gitea源码

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. // Copyright 2022 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package integration
  4. import (
  5. "archive/tar"
  6. "bytes"
  7. "compress/gzip"
  8. "fmt"
  9. "net/http"
  10. "testing"
  11. "time"
  12. "code.gitea.io/gitea/models/packages"
  13. "code.gitea.io/gitea/models/unittest"
  14. user_model "code.gitea.io/gitea/models/user"
  15. helm_module "code.gitea.io/gitea/modules/packages/helm"
  16. "code.gitea.io/gitea/modules/setting"
  17. "code.gitea.io/gitea/tests"
  18. "github.com/stretchr/testify/assert"
  19. "gopkg.in/yaml.v3"
  20. )
  21. func TestPackageHelm(t *testing.T) {
  22. defer tests.PrepareTestEnv(t)()
  23. user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  24. packageName := "test-chart"
  25. packageVersion := "1.0.3"
  26. packageAuthor := "KN4CK3R"
  27. packageDescription := "Gitea Test Package"
  28. filename := fmt.Sprintf("%s-%s.tgz", packageName, packageVersion)
  29. chartContent := `apiVersion: v2
  30. description: ` + packageDescription + `
  31. name: ` + packageName + `
  32. type: application
  33. version: ` + packageVersion + `
  34. maintainers:
  35. - name: ` + packageAuthor + `
  36. dependencies:
  37. - name: dep1
  38. repository: https://example.com/
  39. version: 1.0.0`
  40. var buf bytes.Buffer
  41. zw := gzip.NewWriter(&buf)
  42. archive := tar.NewWriter(zw)
  43. archive.WriteHeader(&tar.Header{
  44. Name: packageName + "/Chart.yaml",
  45. Mode: 0o600,
  46. Size: int64(len(chartContent)),
  47. })
  48. archive.Write([]byte(chartContent))
  49. archive.Close()
  50. zw.Close()
  51. content := buf.Bytes()
  52. url := fmt.Sprintf("/api/packages/%s/helm", user.Name)
  53. t.Run("Upload", func(t *testing.T) {
  54. defer tests.PrintCurrentTest(t)()
  55. uploadURL := url + "/api/charts"
  56. req := NewRequestWithBody(t, "POST", uploadURL, bytes.NewReader(content)).
  57. AddBasicAuth(user.Name)
  58. MakeRequest(t, req, http.StatusCreated)
  59. pvs, err := packages.GetVersionsByPackageType(t.Context(), user.ID, packages.TypeHelm)
  60. assert.NoError(t, err)
  61. assert.Len(t, pvs, 1)
  62. pd, err := packages.GetPackageDescriptor(t.Context(), pvs[0])
  63. assert.NoError(t, err)
  64. assert.NotNil(t, pd.SemVer)
  65. assert.IsType(t, &helm_module.Metadata{}, pd.Metadata)
  66. assert.Equal(t, packageName, pd.Package.Name)
  67. assert.Equal(t, packageVersion, pd.Version.Version)
  68. pfs, err := packages.GetFilesByVersionID(t.Context(), pvs[0].ID)
  69. assert.NoError(t, err)
  70. assert.Len(t, pfs, 1)
  71. assert.Equal(t, filename, pfs[0].Name)
  72. assert.True(t, pfs[0].IsLead)
  73. pb, err := packages.GetBlobByID(t.Context(), pfs[0].BlobID)
  74. assert.NoError(t, err)
  75. assert.Equal(t, int64(len(content)), pb.Size)
  76. req = NewRequestWithBody(t, "POST", uploadURL, bytes.NewReader(content)).
  77. AddBasicAuth(user.Name)
  78. MakeRequest(t, req, http.StatusCreated)
  79. })
  80. t.Run("Download", func(t *testing.T) {
  81. defer tests.PrintCurrentTest(t)()
  82. checkDownloadCount := func(count int64) {
  83. pvs, err := packages.GetVersionsByPackageType(t.Context(), user.ID, packages.TypeHelm)
  84. assert.NoError(t, err)
  85. assert.Len(t, pvs, 1)
  86. assert.Equal(t, count, pvs[0].DownloadCount)
  87. }
  88. checkDownloadCount(0)
  89. req := NewRequest(t, "GET", fmt.Sprintf("%s/%s", url, filename)).
  90. AddBasicAuth(user.Name)
  91. resp := MakeRequest(t, req, http.StatusOK)
  92. assert.Equal(t, content, resp.Body.Bytes())
  93. checkDownloadCount(1)
  94. })
  95. t.Run("Index", func(t *testing.T) {
  96. defer tests.PrintCurrentTest(t)()
  97. req := NewRequest(t, "GET", url+"/index.yaml").
  98. AddBasicAuth(user.Name)
  99. resp := MakeRequest(t, req, http.StatusOK)
  100. type ChartVersion struct {
  101. helm_module.Metadata `yaml:",inline"`
  102. URLs []string `yaml:"urls"`
  103. Created time.Time `yaml:"created,omitempty"`
  104. Removed bool `yaml:"removed,omitempty"`
  105. Digest string `yaml:"digest,omitempty"`
  106. }
  107. type ServerInfo struct {
  108. ContextPath string `yaml:"contextPath,omitempty"`
  109. }
  110. type Index struct {
  111. APIVersion string `yaml:"apiVersion"`
  112. Entries map[string][]*ChartVersion `yaml:"entries"`
  113. Generated time.Time `yaml:"generated,omitempty"`
  114. ServerInfo *ServerInfo `yaml:"serverInfo,omitempty"`
  115. }
  116. var result Index
  117. assert.NoError(t, yaml.NewDecoder(resp.Body).Decode(&result))
  118. assert.NotEmpty(t, result.Entries)
  119. assert.Contains(t, result.Entries, packageName)
  120. cvs := result.Entries[packageName]
  121. assert.Len(t, cvs, 1)
  122. cv := cvs[0]
  123. assert.Equal(t, packageName, cv.Name)
  124. assert.Equal(t, packageVersion, cv.Version)
  125. assert.Equal(t, packageDescription, cv.Description)
  126. assert.Len(t, cv.Maintainers, 1)
  127. assert.Equal(t, packageAuthor, cv.Maintainers[0].Name)
  128. assert.Len(t, cv.Dependencies, 1)
  129. assert.ElementsMatch(t, []string{fmt.Sprintf("%s%s/%s", setting.AppURL, url[1:], filename)}, cv.URLs)
  130. assert.Equal(t, url, result.ServerInfo.ContextPath)
  131. })
  132. }