gitea源码

api_packages_conda_test.go 9.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. // Copyright 2022 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package integration
  4. import (
  5. "archive/tar"
  6. "archive/zip"
  7. "bytes"
  8. "fmt"
  9. "io"
  10. "net/http"
  11. "testing"
  12. "code.gitea.io/gitea/models/packages"
  13. "code.gitea.io/gitea/models/unittest"
  14. user_model "code.gitea.io/gitea/models/user"
  15. conda_module "code.gitea.io/gitea/modules/packages/conda"
  16. "code.gitea.io/gitea/modules/zstd"
  17. "code.gitea.io/gitea/tests"
  18. "github.com/dsnet/compress/bzip2"
  19. "github.com/stretchr/testify/assert"
  20. )
  21. func TestPackageConda(t *testing.T) {
  22. defer tests.PrepareTestEnv(t)()
  23. user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  24. packageName := "test_package"
  25. packageVersion := "1.0.1"
  26. channel := "test-channel"
  27. root := fmt.Sprintf("/api/packages/%s/conda", user.Name)
  28. t.Run("Upload", func(t *testing.T) {
  29. tarContent := func() []byte {
  30. var buf bytes.Buffer
  31. tw := tar.NewWriter(&buf)
  32. content := []byte(`{"name":"` + packageName + `","version":"` + packageVersion + `","subdir":"noarch","build":"xxx"}`)
  33. hdr := &tar.Header{
  34. Name: "info/index.json",
  35. Mode: 0o600,
  36. Size: int64(len(content)),
  37. }
  38. tw.WriteHeader(hdr)
  39. tw.Write(content)
  40. tw.Close()
  41. return buf.Bytes()
  42. }()
  43. t.Run(".tar.bz2", func(t *testing.T) {
  44. defer tests.PrintCurrentTest(t)()
  45. var buf bytes.Buffer
  46. bw, _ := bzip2.NewWriter(&buf, nil)
  47. io.Copy(bw, bytes.NewReader(tarContent))
  48. bw.Close()
  49. filename := fmt.Sprintf("%s-%s.tar.bz2", packageName, packageVersion)
  50. req := NewRequestWithBody(t, "PUT", root+"/"+filename, bytes.NewReader(buf.Bytes()))
  51. MakeRequest(t, req, http.StatusUnauthorized)
  52. req = NewRequestWithBody(t, "PUT", root+"/"+filename, bytes.NewReader(buf.Bytes())).
  53. AddBasicAuth(user.Name)
  54. MakeRequest(t, req, http.StatusCreated)
  55. req = NewRequestWithBody(t, "PUT", root+"/"+filename, bytes.NewReader(buf.Bytes())).
  56. AddBasicAuth(user.Name)
  57. MakeRequest(t, req, http.StatusConflict)
  58. pvs, err := packages.GetVersionsByPackageType(t.Context(), user.ID, packages.TypeConda)
  59. assert.NoError(t, err)
  60. assert.Len(t, pvs, 1)
  61. pd, err := packages.GetPackageDescriptor(t.Context(), pvs[0])
  62. assert.NoError(t, err)
  63. assert.Nil(t, pd.SemVer)
  64. assert.IsType(t, &conda_module.VersionMetadata{}, pd.Metadata)
  65. assert.Equal(t, packageName, pd.Package.Name)
  66. assert.Equal(t, packageVersion, pd.Version.Version)
  67. assert.Empty(t, pd.PackageProperties.GetByName(conda_module.PropertyChannel))
  68. })
  69. t.Run(".conda", func(t *testing.T) {
  70. defer tests.PrintCurrentTest(t)()
  71. var infoBuf bytes.Buffer
  72. zsw, _ := zstd.NewWriter(&infoBuf)
  73. io.Copy(zsw, bytes.NewReader(tarContent))
  74. zsw.Close()
  75. var buf bytes.Buffer
  76. zpw := zip.NewWriter(&buf)
  77. w, _ := zpw.Create("info-x.tar.zst")
  78. w.Write(infoBuf.Bytes())
  79. zpw.Close()
  80. fullName := channel + "/" + packageName
  81. filename := fmt.Sprintf("%s-%s.conda", packageName, packageVersion)
  82. req := NewRequestWithBody(t, "PUT", root+"/"+channel+"/"+filename, bytes.NewReader(buf.Bytes()))
  83. MakeRequest(t, req, http.StatusUnauthorized)
  84. req = NewRequestWithBody(t, "PUT", root+"/"+channel+"/"+filename, bytes.NewReader(buf.Bytes())).
  85. AddBasicAuth(user.Name)
  86. MakeRequest(t, req, http.StatusCreated)
  87. req = NewRequestWithBody(t, "PUT", root+"/"+channel+"/"+filename, bytes.NewReader(buf.Bytes())).
  88. AddBasicAuth(user.Name)
  89. MakeRequest(t, req, http.StatusConflict)
  90. pvs, err := packages.GetVersionsByPackageType(t.Context(), user.ID, packages.TypeConda)
  91. assert.NoError(t, err)
  92. assert.Len(t, pvs, 2)
  93. pds, err := packages.GetPackageDescriptors(t.Context(), pvs)
  94. assert.NoError(t, err)
  95. assert.Condition(t, func() bool {
  96. for _, pd := range pds {
  97. if pd.Package.Name == fullName {
  98. return true
  99. }
  100. }
  101. return false
  102. })
  103. for _, pd := range pds {
  104. if pd.Package.Name == fullName {
  105. assert.Nil(t, pd.SemVer)
  106. assert.IsType(t, &conda_module.VersionMetadata{}, pd.Metadata)
  107. assert.Equal(t, fullName, pd.Package.Name)
  108. assert.Equal(t, packageVersion, pd.Version.Version)
  109. assert.Equal(t, channel, pd.PackageProperties.GetByName(conda_module.PropertyChannel))
  110. }
  111. }
  112. })
  113. })
  114. t.Run("Download", func(t *testing.T) {
  115. t.Run(".tar.bz2", func(t *testing.T) {
  116. defer tests.PrintCurrentTest(t)()
  117. req := NewRequest(t, "GET", fmt.Sprintf("%s/noarch/%s-%s-xxx.tar.bz2", root, packageName, packageVersion))
  118. MakeRequest(t, req, http.StatusOK)
  119. req = NewRequest(t, "GET", fmt.Sprintf("%s/%s/noarch/%s-%s-xxx.tar.bz2", root, channel, packageName, packageVersion))
  120. MakeRequest(t, req, http.StatusNotFound)
  121. })
  122. t.Run(".conda", func(t *testing.T) {
  123. defer tests.PrintCurrentTest(t)()
  124. req := NewRequest(t, "GET", fmt.Sprintf("%s/noarch/%s-%s-xxx.conda", root, packageName, packageVersion))
  125. MakeRequest(t, req, http.StatusNotFound)
  126. req = NewRequest(t, "GET", fmt.Sprintf("%s/%s/noarch/%s-%s-xxx.conda", root, channel, packageName, packageVersion))
  127. MakeRequest(t, req, http.StatusOK)
  128. })
  129. })
  130. t.Run("EnumeratePackages", func(t *testing.T) {
  131. type Info struct {
  132. Subdir string `json:"subdir"`
  133. }
  134. type PackageInfo struct {
  135. Name string `json:"name"`
  136. Version string `json:"version"`
  137. NoArch string `json:"noarch"`
  138. Subdir string `json:"subdir"`
  139. Timestamp int64 `json:"timestamp"`
  140. Build string `json:"build"`
  141. BuildNumber int64 `json:"build_number"`
  142. Dependencies []string `json:"depends"`
  143. License string `json:"license"`
  144. LicenseFamily string `json:"license_family"`
  145. HashMD5 string `json:"md5"`
  146. HashSHA256 string `json:"sha256"`
  147. Size int64 `json:"size"`
  148. }
  149. type RepoData struct {
  150. Info Info `json:"info"`
  151. Packages map[string]*PackageInfo `json:"packages"`
  152. PackagesConda map[string]*PackageInfo `json:"packages.conda"`
  153. Removed map[string]*PackageInfo `json:"removed"`
  154. }
  155. req := NewRequest(t, "GET", root+"/noarch/repodata.json")
  156. resp := MakeRequest(t, req, http.StatusOK)
  157. assert.Equal(t, "application/json", resp.Header().Get("Content-Type"))
  158. req = NewRequest(t, "GET", root+"/noarch/repodata.json.bz2")
  159. resp = MakeRequest(t, req, http.StatusOK)
  160. assert.Equal(t, "application/x-bzip2", resp.Header().Get("Content-Type"))
  161. req = NewRequest(t, "GET", root+"/noarch/current_repodata.json")
  162. resp = MakeRequest(t, req, http.StatusOK)
  163. assert.Equal(t, "application/json", resp.Header().Get("Content-Type"))
  164. req = NewRequest(t, "GET", root+"/noarch/current_repodata.json.bz2")
  165. resp = MakeRequest(t, req, http.StatusOK)
  166. assert.Equal(t, "application/x-bzip2", resp.Header().Get("Content-Type"))
  167. t.Run(".tar.bz2", func(t *testing.T) {
  168. defer tests.PrintCurrentTest(t)()
  169. pv, err := packages.GetVersionByNameAndVersion(t.Context(), user.ID, packages.TypeConda, packageName, packageVersion)
  170. assert.NoError(t, err)
  171. pd, err := packages.GetPackageDescriptor(t.Context(), pv)
  172. assert.NoError(t, err)
  173. req := NewRequest(t, "GET", root+"/noarch/repodata.json")
  174. resp := MakeRequest(t, req, http.StatusOK)
  175. var result RepoData
  176. DecodeJSON(t, resp, &result)
  177. assert.Equal(t, "noarch", result.Info.Subdir)
  178. assert.Empty(t, result.PackagesConda)
  179. assert.Empty(t, result.Removed)
  180. filename := fmt.Sprintf("%s-%s-xxx.tar.bz2", packageName, packageVersion)
  181. assert.Contains(t, result.Packages, filename)
  182. packageInfo := result.Packages[filename]
  183. assert.Equal(t, packageName, packageInfo.Name)
  184. assert.Equal(t, packageVersion, packageInfo.Version)
  185. assert.Equal(t, "noarch", packageInfo.Subdir)
  186. assert.Equal(t, "xxx", packageInfo.Build)
  187. assert.Equal(t, pd.Files[0].Blob.HashMD5, packageInfo.HashMD5)
  188. assert.Equal(t, pd.Files[0].Blob.HashSHA256, packageInfo.HashSHA256)
  189. assert.Equal(t, pd.Files[0].Blob.Size, packageInfo.Size)
  190. })
  191. t.Run(".conda", func(t *testing.T) {
  192. defer tests.PrintCurrentTest(t)()
  193. pv, err := packages.GetVersionByNameAndVersion(t.Context(), user.ID, packages.TypeConda, channel+"/"+packageName, packageVersion)
  194. assert.NoError(t, err)
  195. pd, err := packages.GetPackageDescriptor(t.Context(), pv)
  196. assert.NoError(t, err)
  197. req := NewRequest(t, "GET", fmt.Sprintf("%s/%s/noarch/repodata.json", root, channel))
  198. resp := MakeRequest(t, req, http.StatusOK)
  199. var result RepoData
  200. DecodeJSON(t, resp, &result)
  201. assert.Equal(t, "noarch", result.Info.Subdir)
  202. assert.Empty(t, result.Packages)
  203. assert.Empty(t, result.Removed)
  204. filename := fmt.Sprintf("%s-%s-xxx.conda", packageName, packageVersion)
  205. assert.Contains(t, result.PackagesConda, filename)
  206. packageInfo := result.PackagesConda[filename]
  207. assert.Equal(t, packageName, packageInfo.Name)
  208. assert.Equal(t, packageVersion, packageInfo.Version)
  209. assert.Equal(t, "noarch", packageInfo.Subdir)
  210. assert.Equal(t, "xxx", packageInfo.Build)
  211. assert.Equal(t, pd.Files[0].Blob.HashMD5, packageInfo.HashMD5)
  212. assert.Equal(t, pd.Files[0].Blob.HashSHA256, packageInfo.HashSHA256)
  213. assert.Equal(t, pd.Files[0].Blob.Size, packageInfo.Size)
  214. })
  215. })
  216. }