GitOps for k8s
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.

repo_test.go 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. package gittest
  2. import (
  3. "io/ioutil"
  4. "os"
  5. "path/filepath"
  6. "reflect"
  7. "sync"
  8. "testing"
  9. "time"
  10. "context"
  11. "github.com/fluxcd/flux/cluster/kubernetes/testfiles"
  12. "github.com/fluxcd/flux/git"
  13. "github.com/fluxcd/flux/gpg/gpgtest"
  14. )
  15. type Note struct {
  16. Comment string
  17. }
  18. func TestCommit(t *testing.T) {
  19. config := TestConfig
  20. config.SkipMessage = " **SKIP**"
  21. syncTag := "syncity"
  22. checkout, repo, cleanup := CheckoutWithConfig(t, config, syncTag)
  23. defer cleanup()
  24. for file, _ := range testfiles.Files {
  25. dirs := checkout.AbsolutePaths()
  26. path := filepath.Join(dirs[0], file)
  27. if err := ioutil.WriteFile(path, []byte("FIRST CHANGE"), 0666); err != nil {
  28. t.Fatal(err)
  29. }
  30. break
  31. }
  32. ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
  33. defer cancel()
  34. commitAction := git.CommitAction{Message: "Changed file"}
  35. if err := checkout.CommitAndPush(ctx, commitAction, nil, false); err != nil {
  36. t.Fatal(err)
  37. }
  38. err := repo.Refresh(ctx)
  39. if err != nil {
  40. t.Error(err)
  41. }
  42. commits, err := repo.CommitsBefore(ctx, "HEAD")
  43. if err != nil {
  44. t.Fatal(err)
  45. }
  46. if len(commits) < 1 {
  47. t.Fatal("expected at least one commit")
  48. }
  49. if msg := commits[0].Message; msg != commitAction.Message+config.SkipMessage {
  50. t.Errorf(`expected commit message to be:
  51. %s
  52. but it was
  53. %s
  54. `, commitAction.Message+config.SkipMessage, msg)
  55. }
  56. }
  57. func TestSignedCommit(t *testing.T) {
  58. gpgHome, signingKey, gpgCleanup := gpgtest.GPGKey(t)
  59. defer gpgCleanup()
  60. config := TestConfig
  61. config.SigningKey = signingKey
  62. syncTag := "syncsync"
  63. os.Setenv("GNUPGHOME", gpgHome)
  64. defer os.Unsetenv("GNUPGHOME")
  65. checkout, repo, cleanup := CheckoutWithConfig(t, config, syncTag)
  66. defer cleanup()
  67. for file, _ := range testfiles.Files {
  68. dirs := checkout.AbsolutePaths()
  69. path := filepath.Join(dirs[0], file)
  70. if err := ioutil.WriteFile(path, []byte("FIRST CHANGE"), 0666); err != nil {
  71. t.Fatal(err)
  72. }
  73. break
  74. }
  75. ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
  76. defer cancel()
  77. commitAction := git.CommitAction{Message: "Changed file"}
  78. if err := checkout.CommitAndPush(ctx, commitAction, nil, false); err != nil {
  79. t.Fatal(err)
  80. }
  81. err := repo.Refresh(ctx)
  82. if err != nil {
  83. t.Error(err)
  84. }
  85. commits, err := repo.CommitsBefore(ctx, "HEAD")
  86. if err != nil {
  87. t.Fatal(err)
  88. }
  89. if len(commits) < 1 {
  90. t.Fatal("expected at least one commit")
  91. }
  92. expectedKey := signingKey[len(signingKey)-16:]
  93. foundKey := commits[0].Signature.Key[len(commits[0].Signature.Key)-16:]
  94. if expectedKey != foundKey {
  95. t.Errorf(`expected commit signing key to be:
  96. %s
  97. but it was
  98. %s
  99. `, expectedKey, foundKey)
  100. }
  101. }
  102. func TestSignedTag(t *testing.T) {
  103. gpgHome, signingKey, gpgCleanup := gpgtest.GPGKey(t)
  104. defer gpgCleanup()
  105. config := TestConfig
  106. config.SigningKey = signingKey
  107. syncTag := "sync-test"
  108. os.Setenv("GNUPGHOME", gpgHome)
  109. defer os.Unsetenv("GNUPGHOME")
  110. checkout, repo, cleanup := CheckoutWithConfig(t, config, syncTag)
  111. defer cleanup()
  112. ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
  113. defer cancel()
  114. tagAction := git.TagAction{Revision: "HEAD", Message: "Sync pointer", Tag: syncTag}
  115. if err := checkout.MoveTagAndPush(ctx, tagAction); err != nil {
  116. t.Fatal(err)
  117. }
  118. if err := repo.Refresh(ctx); err != nil {
  119. t.Error(err)
  120. }
  121. _, err := repo.VerifyTag(ctx, syncTag)
  122. if err != nil {
  123. t.Fatal(err)
  124. }
  125. }
  126. func TestCheckout(t *testing.T) {
  127. repo, cleanup := Repo(t)
  128. defer cleanup()
  129. sd, sg := make(chan struct{}), &sync.WaitGroup{}
  130. if err := repo.Ready(context.Background()); err != nil {
  131. t.Fatal(err)
  132. }
  133. ctx := context.Background()
  134. params := git.Config{
  135. Branch: "master",
  136. UserName: "example",
  137. UserEmail: "example@example.com",
  138. NotesRef: "fluxtest",
  139. }
  140. checkout, err := repo.Clone(ctx, params)
  141. if err != nil {
  142. t.Fatal(err)
  143. }
  144. defer checkout.Clean()
  145. // We don't expect any notes in the clone, yet. Make sure we get
  146. // no note, rather than an error.
  147. head, err := checkout.HeadRevision(ctx)
  148. if err != nil {
  149. t.Fatal(err)
  150. }
  151. var note Note
  152. ok, err := repo.GetNote(ctx, head, params.NotesRef, &note)
  153. if err != nil {
  154. t.Error(err)
  155. }
  156. if ok {
  157. t.Errorf("Expected no note on head revision; got %#v", note)
  158. }
  159. changedFile := ""
  160. dirs := checkout.AbsolutePaths()
  161. for file, _ := range testfiles.Files {
  162. path := filepath.Join(dirs[0], file)
  163. if err := ioutil.WriteFile(path, []byte("FIRST CHANGE"), 0666); err != nil {
  164. t.Fatal(err)
  165. }
  166. changedFile = file
  167. break
  168. }
  169. commitAction := git.CommitAction{Author: "", Message: "Changed file"}
  170. if err := checkout.CommitAndPush(ctx, commitAction, nil, false); err != nil {
  171. t.Fatal(err)
  172. }
  173. path := filepath.Join(dirs[0], changedFile)
  174. if err := ioutil.WriteFile(path, []byte("SECOND CHANGE"), 0666); err != nil {
  175. t.Fatal(err)
  176. }
  177. // An example note with some of the fields filled in, so we can test
  178. // serialization a bit.
  179. expectedNote := Note{
  180. Comment: "Expected comment",
  181. }
  182. commitAction = git.CommitAction{Author: "", Message: "Changed file again"}
  183. if err := checkout.CommitAndPush(ctx, commitAction, &expectedNote, false); err != nil {
  184. t.Fatal(err)
  185. }
  186. check := func(c *git.Checkout) {
  187. contents, err := ioutil.ReadFile(filepath.Join(dirs[0], changedFile))
  188. if err != nil {
  189. t.Fatal(err)
  190. }
  191. if string(contents) != "SECOND CHANGE" {
  192. t.Error("contents in checkout are not what we committed")
  193. }
  194. rev, err := c.HeadRevision(ctx)
  195. if err != nil {
  196. t.Fatal(err)
  197. }
  198. var note Note
  199. ok, err := repo.GetNote(ctx, rev, params.NotesRef, &note)
  200. if !ok {
  201. t.Error("note not found")
  202. }
  203. if err != nil {
  204. t.Error(err)
  205. }
  206. if !reflect.DeepEqual(note, expectedNote) {
  207. t.Errorf("note is not what we supplied when committing: %#v", note)
  208. }
  209. }
  210. // Do we see the changes if we make another working checkout?
  211. if err := repo.Refresh(ctx); err != nil {
  212. t.Error(err)
  213. }
  214. another, err := repo.Clone(ctx, params)
  215. if err != nil {
  216. t.Fatal(err)
  217. }
  218. defer another.Clean()
  219. check(another)
  220. close(sd)
  221. sg.Wait()
  222. }