You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

git_test.go 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. // Copyright 2017 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. "crypto/rand"
  7. "fmt"
  8. "io/ioutil"
  9. "net/http"
  10. "net/url"
  11. "os"
  12. "path"
  13. "path/filepath"
  14. "testing"
  15. "time"
  16. "code.gitea.io/gitea/models"
  17. "code.gitea.io/gitea/modules/git"
  18. "github.com/stretchr/testify/assert"
  19. )
  20. const (
  21. littleSize = 1024 //1ko
  22. bigSize = 128 * 1024 * 1024 //128Mo
  23. )
  24. func TestGit(t *testing.T) {
  25. onGiteaRun(t, testGit)
  26. }
  27. func testGit(t *testing.T, u *url.URL) {
  28. username := "user2"
  29. baseAPITestContext := NewAPITestContext(t, username, "repo1")
  30. u.Path = baseAPITestContext.GitPath()
  31. t.Run("HTTP", func(t *testing.T) {
  32. PrintCurrentTest(t)
  33. httpContext := baseAPITestContext
  34. httpContext.Reponame = "repo-tmp-17"
  35. dstPath, err := ioutil.TempDir("", httpContext.Reponame)
  36. var little, big, littleLFS, bigLFS string
  37. assert.NoError(t, err)
  38. defer os.RemoveAll(dstPath)
  39. t.Run("Standard", func(t *testing.T) {
  40. PrintCurrentTest(t)
  41. ensureAnonymousClone(t, u)
  42. t.Run("CreateRepo", doAPICreateRepository(httpContext, false))
  43. u.Path = httpContext.GitPath()
  44. u.User = url.UserPassword(username, userPassword)
  45. t.Run("Clone", doGitClone(dstPath, u))
  46. t.Run("PushCommit", func(t *testing.T) {
  47. PrintCurrentTest(t)
  48. t.Run("Little", func(t *testing.T) {
  49. PrintCurrentTest(t)
  50. little = commitAndPush(t, littleSize, dstPath)
  51. })
  52. t.Run("Big", func(t *testing.T) {
  53. PrintCurrentTest(t)
  54. big = commitAndPush(t, bigSize, dstPath)
  55. })
  56. })
  57. })
  58. t.Run("LFS", func(t *testing.T) {
  59. PrintCurrentTest(t)
  60. t.Run("PushCommit", func(t *testing.T) {
  61. PrintCurrentTest(t)
  62. //Setup git LFS
  63. _, err = git.NewCommand("lfs").AddArguments("install").RunInDir(dstPath)
  64. assert.NoError(t, err)
  65. _, err = git.NewCommand("lfs").AddArguments("track", "data-file-*").RunInDir(dstPath)
  66. assert.NoError(t, err)
  67. err = git.AddChanges(dstPath, false, ".gitattributes")
  68. assert.NoError(t, err)
  69. t.Run("Little", func(t *testing.T) {
  70. PrintCurrentTest(t)
  71. littleLFS = commitAndPush(t, littleSize, dstPath)
  72. })
  73. t.Run("Big", func(t *testing.T) {
  74. PrintCurrentTest(t)
  75. bigLFS = commitAndPush(t, bigSize, dstPath)
  76. })
  77. })
  78. t.Run("Locks", func(t *testing.T) {
  79. PrintCurrentTest(t)
  80. lockTest(t, u.String(), dstPath)
  81. })
  82. })
  83. t.Run("Raw", func(t *testing.T) {
  84. PrintCurrentTest(t)
  85. session := loginUser(t, "user2")
  86. // Request raw paths
  87. req := NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/raw/branch/master/", little))
  88. resp := session.MakeRequest(t, req, http.StatusOK)
  89. assert.Equal(t, littleSize, resp.Body.Len())
  90. req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/raw/branch/master/", big))
  91. nilResp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
  92. assert.Equal(t, bigSize, nilResp.Length)
  93. req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/raw/branch/master/", littleLFS))
  94. resp = session.MakeRequest(t, req, http.StatusOK)
  95. assert.NotEqual(t, littleSize, resp.Body.Len())
  96. assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier)
  97. req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/raw/branch/master/", bigLFS))
  98. resp = session.MakeRequest(t, req, http.StatusOK)
  99. assert.NotEqual(t, bigSize, resp.Body.Len())
  100. assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier)
  101. })
  102. t.Run("Media", func(t *testing.T) {
  103. PrintCurrentTest(t)
  104. session := loginUser(t, "user2")
  105. // Request media paths
  106. req := NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/media/branch/master/", little))
  107. resp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
  108. assert.Equal(t, littleSize, resp.Length)
  109. req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/media/branch/master/", big))
  110. resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
  111. assert.Equal(t, bigSize, resp.Length)
  112. req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/media/branch/master/", littleLFS))
  113. resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
  114. assert.Equal(t, littleSize, resp.Length)
  115. req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-17/media/branch/master/", bigLFS))
  116. resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
  117. assert.Equal(t, bigSize, resp.Length)
  118. })
  119. })
  120. t.Run("SSH", func(t *testing.T) {
  121. PrintCurrentTest(t)
  122. sshContext := baseAPITestContext
  123. sshContext.Reponame = "repo-tmp-18"
  124. keyname := "my-testing-key"
  125. //Setup key the user ssh key
  126. withKeyFile(t, keyname, func(keyFile string) {
  127. t.Run("CreateUserKey", doAPICreateUserKey(sshContext, "test-key", keyFile))
  128. PrintCurrentTest(t)
  129. //Setup remote link
  130. sshURL := createSSHUrl(sshContext.GitPath(), u)
  131. //Setup clone folder
  132. dstPath, err := ioutil.TempDir("", sshContext.Reponame)
  133. assert.NoError(t, err)
  134. defer os.RemoveAll(dstPath)
  135. var little, big, littleLFS, bigLFS string
  136. t.Run("Standard", func(t *testing.T) {
  137. PrintCurrentTest(t)
  138. t.Run("CreateRepo", doAPICreateRepository(sshContext, false))
  139. //TODO get url from api
  140. t.Run("Clone", doGitClone(dstPath, sshURL))
  141. //time.Sleep(5 * time.Minute)
  142. t.Run("PushCommit", func(t *testing.T) {
  143. PrintCurrentTest(t)
  144. t.Run("Little", func(t *testing.T) {
  145. PrintCurrentTest(t)
  146. little = commitAndPush(t, littleSize, dstPath)
  147. })
  148. t.Run("Big", func(t *testing.T) {
  149. PrintCurrentTest(t)
  150. big = commitAndPush(t, bigSize, dstPath)
  151. })
  152. })
  153. })
  154. t.Run("LFS", func(t *testing.T) {
  155. PrintCurrentTest(t)
  156. t.Run("PushCommit", func(t *testing.T) {
  157. PrintCurrentTest(t)
  158. //Setup git LFS
  159. _, err = git.NewCommand("lfs").AddArguments("install").RunInDir(dstPath)
  160. assert.NoError(t, err)
  161. _, err = git.NewCommand("lfs").AddArguments("track", "data-file-*").RunInDir(dstPath)
  162. assert.NoError(t, err)
  163. err = git.AddChanges(dstPath, false, ".gitattributes")
  164. assert.NoError(t, err)
  165. t.Run("Little", func(t *testing.T) {
  166. PrintCurrentTest(t)
  167. littleLFS = commitAndPush(t, littleSize, dstPath)
  168. })
  169. t.Run("Big", func(t *testing.T) {
  170. PrintCurrentTest(t)
  171. bigLFS = commitAndPush(t, bigSize, dstPath)
  172. })
  173. })
  174. t.Run("Locks", func(t *testing.T) {
  175. PrintCurrentTest(t)
  176. lockTest(t, u.String(), dstPath)
  177. })
  178. })
  179. t.Run("Raw", func(t *testing.T) {
  180. PrintCurrentTest(t)
  181. session := loginUser(t, "user2")
  182. // Request raw paths
  183. req := NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/raw/branch/master/", little))
  184. resp := session.MakeRequest(t, req, http.StatusOK)
  185. assert.Equal(t, littleSize, resp.Body.Len())
  186. req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/raw/branch/master/", big))
  187. resp = session.MakeRequest(t, req, http.StatusOK)
  188. assert.Equal(t, bigSize, resp.Body.Len())
  189. req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/raw/branch/master/", littleLFS))
  190. resp = session.MakeRequest(t, req, http.StatusOK)
  191. assert.NotEqual(t, littleSize, resp.Body.Len())
  192. assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier)
  193. req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/raw/branch/master/", bigLFS))
  194. resp = session.MakeRequest(t, req, http.StatusOK)
  195. assert.NotEqual(t, bigSize, resp.Body.Len())
  196. assert.Contains(t, resp.Body.String(), models.LFSMetaFileIdentifier)
  197. })
  198. t.Run("Media", func(t *testing.T) {
  199. PrintCurrentTest(t)
  200. session := loginUser(t, "user2")
  201. // Request media paths
  202. req := NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/media/branch/master/", little))
  203. resp := session.MakeRequest(t, req, http.StatusOK)
  204. assert.Equal(t, littleSize, resp.Body.Len())
  205. req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/media/branch/master/", big))
  206. resp = session.MakeRequest(t, req, http.StatusOK)
  207. assert.Equal(t, bigSize, resp.Body.Len())
  208. req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/media/branch/master/", littleLFS))
  209. resp = session.MakeRequest(t, req, http.StatusOK)
  210. assert.Equal(t, littleSize, resp.Body.Len())
  211. req = NewRequest(t, "GET", path.Join("/user2/repo-tmp-18/media/branch/master/", bigLFS))
  212. resp = session.MakeRequest(t, req, http.StatusOK)
  213. assert.Equal(t, bigSize, resp.Body.Len())
  214. })
  215. })
  216. })
  217. }
  218. func ensureAnonymousClone(t *testing.T, u *url.URL) {
  219. dstLocalPath, err := ioutil.TempDir("", "repo1")
  220. assert.NoError(t, err)
  221. defer os.RemoveAll(dstLocalPath)
  222. t.Run("CloneAnonymous", doGitClone(dstLocalPath, u))
  223. }
  224. func lockTest(t *testing.T, remote, repoPath string) {
  225. _, err := git.NewCommand("remote").AddArguments("set-url", "origin", remote).RunInDir(repoPath) //TODO add test ssh git-lfs-creds
  226. assert.NoError(t, err)
  227. _, err = git.NewCommand("lfs").AddArguments("locks").RunInDir(repoPath)
  228. assert.NoError(t, err)
  229. _, err = git.NewCommand("lfs").AddArguments("lock", "README.md").RunInDir(repoPath)
  230. assert.NoError(t, err)
  231. _, err = git.NewCommand("lfs").AddArguments("locks").RunInDir(repoPath)
  232. assert.NoError(t, err)
  233. _, err = git.NewCommand("lfs").AddArguments("unlock", "README.md").RunInDir(repoPath)
  234. assert.NoError(t, err)
  235. }
  236. func commitAndPush(t *testing.T, size int, repoPath string) string {
  237. name, err := generateCommitWithNewData(size, repoPath, "user2@example.com", "User Two")
  238. assert.NoError(t, err)
  239. _, err = git.NewCommand("push").RunInDir(repoPath) //Push
  240. assert.NoError(t, err)
  241. return name
  242. }
  243. func generateCommitWithNewData(size int, repoPath, email, fullName string) (string, error) {
  244. //Generate random file
  245. data := make([]byte, size)
  246. _, err := rand.Read(data)
  247. if err != nil {
  248. return "", err
  249. }
  250. tmpFile, err := ioutil.TempFile(repoPath, "data-file-")
  251. if err != nil {
  252. return "", err
  253. }
  254. defer tmpFile.Close()
  255. _, err = tmpFile.Write(data)
  256. if err != nil {
  257. return "", err
  258. }
  259. //Commit
  260. err = git.AddChanges(repoPath, false, filepath.Base(tmpFile.Name()))
  261. if err != nil {
  262. return "", err
  263. }
  264. err = git.CommitChanges(repoPath, git.CommitChangesOptions{
  265. Committer: &git.Signature{
  266. Email: email,
  267. Name: fullName,
  268. When: time.Now(),
  269. },
  270. Author: &git.Signature{
  271. Email: email,
  272. Name: fullName,
  273. When: time.Now(),
  274. },
  275. Message: fmt.Sprintf("Testing commit @ %v", time.Now()),
  276. })
  277. return filepath.Base(tmpFile.Name()), err
  278. }