選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

lfs_getobject_test.go 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. // Copyright 2019 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package integrations
  5. import (
  6. "archive/zip"
  7. "bytes"
  8. "io/ioutil"
  9. "net/http"
  10. "net/http/httptest"
  11. "testing"
  12. "code.gitea.io/gitea/models"
  13. "code.gitea.io/gitea/modules/lfs"
  14. "code.gitea.io/gitea/modules/setting"
  15. "code.gitea.io/gitea/routers/routes"
  16. gzipp "github.com/klauspost/compress/gzip"
  17. "github.com/stretchr/testify/assert"
  18. )
  19. var lfsID = int64(20000)
  20. func storeObjectInRepo(t *testing.T, repositoryID int64, content *[]byte) string {
  21. pointer, err := lfs.GeneratePointer(bytes.NewReader(*content))
  22. assert.NoError(t, err)
  23. var lfsMetaObject *models.LFSMetaObject
  24. if setting.Database.UsePostgreSQL {
  25. lfsMetaObject = &models.LFSMetaObject{ID: lfsID, Pointer: pointer, RepositoryID: repositoryID}
  26. } else {
  27. lfsMetaObject = &models.LFSMetaObject{Pointer: pointer, RepositoryID: repositoryID}
  28. }
  29. lfsID++
  30. lfsMetaObject, err = models.NewLFSMetaObject(lfsMetaObject)
  31. assert.NoError(t, err)
  32. contentStore := lfs.NewContentStore()
  33. exist, err := contentStore.Exists(pointer)
  34. assert.NoError(t, err)
  35. if !exist {
  36. err := contentStore.Put(pointer, bytes.NewReader(*content))
  37. assert.NoError(t, err)
  38. }
  39. return pointer.Oid
  40. }
  41. func storeAndGetLfs(t *testing.T, content *[]byte, extraHeader *http.Header, expectedStatus int) *httptest.ResponseRecorder {
  42. repo, err := models.GetRepositoryByOwnerAndName("user2", "repo1")
  43. assert.NoError(t, err)
  44. oid := storeObjectInRepo(t, repo.ID, content)
  45. defer repo.RemoveLFSMetaObjectByOid(oid)
  46. session := loginUser(t, "user2")
  47. // Request OID
  48. req := NewRequest(t, "GET", "/user2/repo1.git/info/lfs/objects/"+oid+"/test")
  49. req.Header.Set("Accept-Encoding", "gzip")
  50. if extraHeader != nil {
  51. for key, values := range *extraHeader {
  52. for _, value := range values {
  53. req.Header.Add(key, value)
  54. }
  55. }
  56. }
  57. resp := session.MakeRequest(t, req, expectedStatus)
  58. return resp
  59. }
  60. func checkResponseTestContentEncoding(t *testing.T, content *[]byte, resp *httptest.ResponseRecorder, expectGzip bool) {
  61. contentEncoding := resp.Header().Get("Content-Encoding")
  62. if !expectGzip || !setting.EnableGzip {
  63. assert.NotContains(t, contentEncoding, "gzip")
  64. result := resp.Body.Bytes()
  65. assert.Equal(t, *content, result)
  66. } else {
  67. assert.Contains(t, contentEncoding, "gzip")
  68. gzippReader, err := gzipp.NewReader(resp.Body)
  69. assert.NoError(t, err)
  70. result, err := ioutil.ReadAll(gzippReader)
  71. assert.NoError(t, err)
  72. assert.Equal(t, *content, result)
  73. }
  74. }
  75. func TestGetLFSSmall(t *testing.T) {
  76. defer prepareTestEnv(t)()
  77. setting.CheckLFSVersion()
  78. if !setting.LFS.StartServer {
  79. t.Skip()
  80. return
  81. }
  82. content := []byte("A very small file\n")
  83. resp := storeAndGetLfs(t, &content, nil, http.StatusOK)
  84. checkResponseTestContentEncoding(t, &content, resp, false)
  85. }
  86. func TestGetLFSLarge(t *testing.T) {
  87. defer prepareTestEnv(t)()
  88. setting.CheckLFSVersion()
  89. if !setting.LFS.StartServer {
  90. t.Skip()
  91. return
  92. }
  93. content := make([]byte, routes.GzipMinSize*10)
  94. for i := range content {
  95. content[i] = byte(i % 256)
  96. }
  97. resp := storeAndGetLfs(t, &content, nil, http.StatusOK)
  98. checkResponseTestContentEncoding(t, &content, resp, true)
  99. }
  100. func TestGetLFSGzip(t *testing.T) {
  101. defer prepareTestEnv(t)()
  102. setting.CheckLFSVersion()
  103. if !setting.LFS.StartServer {
  104. t.Skip()
  105. return
  106. }
  107. b := make([]byte, routes.GzipMinSize*10)
  108. for i := range b {
  109. b[i] = byte(i % 256)
  110. }
  111. outputBuffer := bytes.NewBuffer([]byte{})
  112. gzippWriter := gzipp.NewWriter(outputBuffer)
  113. gzippWriter.Write(b)
  114. gzippWriter.Close()
  115. content := outputBuffer.Bytes()
  116. resp := storeAndGetLfs(t, &content, nil, http.StatusOK)
  117. checkResponseTestContentEncoding(t, &content, resp, false)
  118. }
  119. func TestGetLFSZip(t *testing.T) {
  120. defer prepareTestEnv(t)()
  121. setting.CheckLFSVersion()
  122. if !setting.LFS.StartServer {
  123. t.Skip()
  124. return
  125. }
  126. b := make([]byte, routes.GzipMinSize*10)
  127. for i := range b {
  128. b[i] = byte(i % 256)
  129. }
  130. outputBuffer := bytes.NewBuffer([]byte{})
  131. zipWriter := zip.NewWriter(outputBuffer)
  132. fileWriter, err := zipWriter.Create("default")
  133. assert.NoError(t, err)
  134. fileWriter.Write(b)
  135. zipWriter.Close()
  136. content := outputBuffer.Bytes()
  137. resp := storeAndGetLfs(t, &content, nil, http.StatusOK)
  138. checkResponseTestContentEncoding(t, &content, resp, false)
  139. }
  140. func TestGetLFSRangeNo(t *testing.T) {
  141. defer prepareTestEnv(t)()
  142. setting.CheckLFSVersion()
  143. if !setting.LFS.StartServer {
  144. t.Skip()
  145. return
  146. }
  147. content := []byte("123456789\n")
  148. resp := storeAndGetLfs(t, &content, nil, http.StatusOK)
  149. assert.Equal(t, content, resp.Body.Bytes())
  150. }
  151. func TestGetLFSRange(t *testing.T) {
  152. defer prepareTestEnv(t)()
  153. setting.CheckLFSVersion()
  154. if !setting.LFS.StartServer {
  155. t.Skip()
  156. return
  157. }
  158. content := []byte("123456789\n")
  159. tests := []struct {
  160. in string
  161. out string
  162. status int
  163. }{
  164. {"bytes=0-0", "1", http.StatusPartialContent},
  165. {"bytes=0-1", "12", http.StatusPartialContent},
  166. {"bytes=1-1", "2", http.StatusPartialContent},
  167. {"bytes=1-3", "234", http.StatusPartialContent},
  168. {"bytes=1-", "23456789\n", http.StatusPartialContent},
  169. // end-range smaller than start-range is ignored
  170. {"bytes=1-0", "23456789\n", http.StatusPartialContent},
  171. {"bytes=0-10", "123456789\n", http.StatusPartialContent},
  172. // end-range bigger than length-1 is ignored
  173. {"bytes=0-11", "123456789\n", http.StatusPartialContent},
  174. {"bytes=11-", "Requested Range Not Satisfiable", http.StatusRequestedRangeNotSatisfiable},
  175. // incorrect header value cause whole header to be ignored
  176. {"bytes=-", "123456789\n", http.StatusOK},
  177. {"foobar", "123456789\n", http.StatusOK},
  178. }
  179. for _, tt := range tests {
  180. t.Run(tt.in, func(t *testing.T) {
  181. h := http.Header{
  182. "Range": []string{tt.in},
  183. }
  184. resp := storeAndGetLfs(t, &content, &h, tt.status)
  185. assert.Equal(t, tt.out, resp.Body.String())
  186. })
  187. }
  188. }