gitea源码

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. // Copyright 2021 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package integration
  4. import (
  5. "bytes"
  6. "fmt"
  7. "io"
  8. "net/http"
  9. "testing"
  10. "code.gitea.io/gitea/models/packages"
  11. "code.gitea.io/gitea/models/unittest"
  12. user_model "code.gitea.io/gitea/models/user"
  13. "code.gitea.io/gitea/modules/setting"
  14. "code.gitea.io/gitea/modules/test"
  15. "code.gitea.io/gitea/tests"
  16. "github.com/stretchr/testify/assert"
  17. )
  18. func TestPackageGeneric(t *testing.T) {
  19. defer tests.PrepareTestEnv(t)()
  20. user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
  21. packageName := "te-st_pac.kage"
  22. packageVersion := "1.0.3-te st"
  23. filename := "fi-le_na.me"
  24. content := []byte{1, 2, 3}
  25. url := fmt.Sprintf("/api/packages/%s/generic/%s/%s", user.Name, packageName, packageVersion)
  26. t.Run("Upload", func(t *testing.T) {
  27. defer tests.PrintCurrentTest(t)()
  28. req := NewRequestWithBody(t, "PUT", url+"/"+filename, bytes.NewReader(content)).
  29. AddBasicAuth(user.Name)
  30. MakeRequest(t, req, http.StatusCreated)
  31. pvs, err := packages.GetVersionsByPackageType(t.Context(), user.ID, packages.TypeGeneric)
  32. assert.NoError(t, err)
  33. assert.Len(t, pvs, 1)
  34. pd, err := packages.GetPackageDescriptor(t.Context(), pvs[0])
  35. assert.NoError(t, err)
  36. assert.Nil(t, pd.Metadata)
  37. assert.Equal(t, packageName, pd.Package.Name)
  38. assert.Equal(t, packageVersion, pd.Version.Version)
  39. pfs, err := packages.GetFilesByVersionID(t.Context(), pvs[0].ID)
  40. assert.NoError(t, err)
  41. assert.Len(t, pfs, 1)
  42. assert.Equal(t, filename, pfs[0].Name)
  43. assert.True(t, pfs[0].IsLead)
  44. pb, err := packages.GetBlobByID(t.Context(), pfs[0].BlobID)
  45. assert.NoError(t, err)
  46. assert.Equal(t, int64(len(content)), pb.Size)
  47. t.Run("Exists", func(t *testing.T) {
  48. defer tests.PrintCurrentTest(t)()
  49. req := NewRequestWithBody(t, "PUT", url+"/"+filename, bytes.NewReader(content)).
  50. AddBasicAuth(user.Name)
  51. MakeRequest(t, req, http.StatusConflict)
  52. })
  53. t.Run("Additional", func(t *testing.T) {
  54. defer tests.PrintCurrentTest(t)()
  55. req := NewRequestWithBody(t, "PUT", url+"/dummy.bin", bytes.NewReader(content)).
  56. AddBasicAuth(user.Name)
  57. MakeRequest(t, req, http.StatusCreated)
  58. // Check deduplication
  59. pfs, err := packages.GetFilesByVersionID(t.Context(), pvs[0].ID)
  60. assert.NoError(t, err)
  61. assert.Len(t, pfs, 2)
  62. assert.Equal(t, pfs[0].BlobID, pfs[1].BlobID)
  63. })
  64. t.Run("InvalidParameter", func(t *testing.T) {
  65. defer tests.PrintCurrentTest(t)()
  66. req := NewRequestWithBody(t, "PUT", fmt.Sprintf("/api/packages/%s/generic/%s/%s/%s", user.Name, "invalid package name", packageVersion, filename), bytes.NewReader(content)).
  67. AddBasicAuth(user.Name)
  68. MakeRequest(t, req, http.StatusBadRequest)
  69. req = NewRequestWithBody(t, "PUT", fmt.Sprintf("/api/packages/%s/generic/%s/%s/%s", user.Name, packageName, "%20test ", filename), bytes.NewReader(content)).
  70. AddBasicAuth(user.Name)
  71. MakeRequest(t, req, http.StatusBadRequest)
  72. req = NewRequestWithBody(t, "PUT", fmt.Sprintf("/api/packages/%s/generic/%s/%s/%s", user.Name, packageName, packageVersion, "inva|id.name"), bytes.NewReader(content)).
  73. AddBasicAuth(user.Name)
  74. MakeRequest(t, req, http.StatusBadRequest)
  75. })
  76. })
  77. t.Run("Download", func(t *testing.T) {
  78. defer tests.PrintCurrentTest(t)()
  79. checkDownloadCount := func(count int64) {
  80. pvs, err := packages.GetVersionsByPackageType(t.Context(), user.ID, packages.TypeGeneric)
  81. assert.NoError(t, err)
  82. assert.Len(t, pvs, 1)
  83. assert.Equal(t, count, pvs[0].DownloadCount)
  84. }
  85. checkDownloadCount(0)
  86. req := NewRequest(t, "GET", url+"/"+filename)
  87. resp := MakeRequest(t, req, http.StatusOK)
  88. assert.Equal(t, content, resp.Body.Bytes())
  89. checkDownloadCount(1)
  90. req = NewRequest(t, "GET", url+"/dummy.bin")
  91. MakeRequest(t, req, http.StatusOK)
  92. checkDownloadCount(2)
  93. t.Run("NotExists", func(t *testing.T) {
  94. defer tests.PrintCurrentTest(t)()
  95. req := NewRequest(t, "GET", url+"/not.found")
  96. MakeRequest(t, req, http.StatusNotFound)
  97. })
  98. t.Run("RequireSignInView", func(t *testing.T) {
  99. defer tests.PrintCurrentTest(t)()
  100. defer test.MockVariableValue(&setting.Service.RequireSignInViewStrict, true)()
  101. req = NewRequest(t, "GET", url+"/dummy.bin")
  102. MakeRequest(t, req, http.StatusUnauthorized)
  103. })
  104. t.Run("ServeDirect", func(t *testing.T) {
  105. defer tests.PrintCurrentTest(t)()
  106. if setting.Packages.Storage.Type == setting.MinioStorageType {
  107. defer test.MockVariableValue(&setting.Packages.Storage.MinioConfig.ServeDirect, true)()
  108. } else if setting.Packages.Storage.Type == setting.AzureBlobStorageType {
  109. defer test.MockVariableValue(&setting.Packages.Storage.AzureBlobConfig.ServeDirect, true)()
  110. } else {
  111. t.Skip("Test skipped for non-Minio-storage and non-AzureBlob-storage.")
  112. }
  113. req = NewRequest(t, "HEAD", url+"/"+filename)
  114. resp = MakeRequest(t, req, http.StatusSeeOther)
  115. location := resp.Header().Get("Location")
  116. assert.NotEmpty(t, location)
  117. checkDownloadCount(2)
  118. req = NewRequest(t, "GET", url+"/"+filename)
  119. resp = MakeRequest(t, req, http.StatusSeeOther)
  120. checkDownloadCount(3)
  121. location = resp.Header().Get("Location")
  122. assert.NotEmpty(t, location)
  123. resp2, err := (&http.Client{}).Get(location)
  124. assert.NoError(t, err)
  125. assert.Equal(t, http.StatusOK, resp2.StatusCode, location)
  126. body, err := io.ReadAll(resp2.Body)
  127. assert.NoError(t, err)
  128. assert.Equal(t, content, body)
  129. checkDownloadCount(3)
  130. })
  131. })
  132. t.Run("Delete", func(t *testing.T) {
  133. defer tests.PrintCurrentTest(t)()
  134. t.Run("File", func(t *testing.T) {
  135. defer tests.PrintCurrentTest(t)()
  136. req := NewRequest(t, "DELETE", url+"/"+filename)
  137. MakeRequest(t, req, http.StatusUnauthorized)
  138. req = NewRequest(t, "DELETE", url+"/"+filename).
  139. AddBasicAuth(user.Name)
  140. MakeRequest(t, req, http.StatusNoContent)
  141. req = NewRequest(t, "GET", url+"/"+filename)
  142. MakeRequest(t, req, http.StatusNotFound)
  143. req = NewRequest(t, "DELETE", url+"/"+filename).
  144. AddBasicAuth(user.Name)
  145. MakeRequest(t, req, http.StatusNotFound)
  146. pvs, err := packages.GetVersionsByPackageType(t.Context(), user.ID, packages.TypeGeneric)
  147. assert.NoError(t, err)
  148. assert.Len(t, pvs, 1)
  149. t.Run("RemovesVersion", func(t *testing.T) {
  150. defer tests.PrintCurrentTest(t)()
  151. req = NewRequest(t, "DELETE", url+"/dummy.bin").
  152. AddBasicAuth(user.Name)
  153. MakeRequest(t, req, http.StatusNoContent)
  154. pvs, err := packages.GetVersionsByPackageType(t.Context(), user.ID, packages.TypeGeneric)
  155. assert.NoError(t, err)
  156. assert.Empty(t, pvs)
  157. })
  158. })
  159. t.Run("Version", func(t *testing.T) {
  160. defer tests.PrintCurrentTest(t)()
  161. req := NewRequestWithBody(t, "PUT", url+"/"+filename, bytes.NewReader(content)).
  162. AddBasicAuth(user.Name)
  163. MakeRequest(t, req, http.StatusCreated)
  164. req = NewRequest(t, "DELETE", url)
  165. MakeRequest(t, req, http.StatusUnauthorized)
  166. req = NewRequest(t, "DELETE", url).
  167. AddBasicAuth(user.Name)
  168. MakeRequest(t, req, http.StatusNoContent)
  169. pvs, err := packages.GetVersionsByPackageType(t.Context(), user.ID, packages.TypeGeneric)
  170. assert.NoError(t, err)
  171. assert.Empty(t, pvs)
  172. req = NewRequest(t, "GET", url+"/"+filename)
  173. MakeRequest(t, req, http.StatusNotFound)
  174. req = NewRequest(t, "DELETE", url).
  175. AddBasicAuth(user.Name)
  176. MakeRequest(t, req, http.StatusNotFound)
  177. })
  178. })
  179. }