fakegit.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. package fakegit // import "github.com/docker/docker/testutil/fakegit"
  2. import (
  3. "fmt"
  4. "net/http"
  5. "net/http/httptest"
  6. "os"
  7. "os/exec"
  8. "path/filepath"
  9. "testing"
  10. "github.com/docker/docker/testutil/fakecontext"
  11. "github.com/docker/docker/testutil/fakestorage"
  12. )
  13. type gitServer interface {
  14. URL() string
  15. Close() error
  16. }
  17. type localGitServer struct {
  18. *httptest.Server
  19. }
  20. func (r *localGitServer) Close() error {
  21. r.Server.Close()
  22. return nil
  23. }
  24. func (r *localGitServer) URL() string {
  25. return r.Server.URL
  26. }
  27. // FakeGit is a fake git server
  28. type FakeGit struct {
  29. root string
  30. server gitServer
  31. RepoURL string
  32. }
  33. // Close closes the server, implements Closer interface
  34. func (g *FakeGit) Close() {
  35. g.server.Close()
  36. os.RemoveAll(g.root)
  37. }
  38. // New create a fake git server that can be used for git related tests
  39. func New(c testing.TB, name string, files map[string]string, enforceLocalServer bool) *FakeGit {
  40. c.Helper()
  41. ctx := fakecontext.New(c, "", fakecontext.WithFiles(files))
  42. defer ctx.Close()
  43. curdir, err := os.Getwd()
  44. if err != nil {
  45. c.Fatal(err)
  46. }
  47. defer os.Chdir(curdir)
  48. if output, err := exec.Command("git", "init", ctx.Dir).CombinedOutput(); err != nil {
  49. c.Fatalf("error trying to init repo: %s (%s)", err, output)
  50. }
  51. err = os.Chdir(ctx.Dir)
  52. if err != nil {
  53. c.Fatal(err)
  54. }
  55. if output, err := exec.Command("git", "config", "user.name", "Fake User").CombinedOutput(); err != nil {
  56. c.Fatalf("error trying to set 'user.name': %s (%s)", err, output)
  57. }
  58. if output, err := exec.Command("git", "config", "user.email", "fake.user@example.com").CombinedOutput(); err != nil {
  59. c.Fatalf("error trying to set 'user.email': %s (%s)", err, output)
  60. }
  61. if output, err := exec.Command("git", "add", "*").CombinedOutput(); err != nil {
  62. c.Fatalf("error trying to add files to repo: %s (%s)", err, output)
  63. }
  64. if output, err := exec.Command("git", "commit", "-a", "-m", "Initial commit").CombinedOutput(); err != nil {
  65. c.Fatalf("error trying to commit to repo: %s (%s)", err, output)
  66. }
  67. root, err := os.MkdirTemp("", "docker-test-git-repo")
  68. if err != nil {
  69. c.Fatal(err)
  70. }
  71. repoPath := filepath.Join(root, name+".git")
  72. if output, err := exec.Command("git", "clone", "--bare", ctx.Dir, repoPath).CombinedOutput(); err != nil {
  73. os.RemoveAll(root)
  74. c.Fatalf("error trying to clone --bare: %s (%s)", err, output)
  75. }
  76. err = os.Chdir(repoPath)
  77. if err != nil {
  78. os.RemoveAll(root)
  79. c.Fatal(err)
  80. }
  81. if output, err := exec.Command("git", "update-server-info").CombinedOutput(); err != nil {
  82. os.RemoveAll(root)
  83. c.Fatalf("error trying to git update-server-info: %s (%s)", err, output)
  84. }
  85. err = os.Chdir(curdir)
  86. if err != nil {
  87. os.RemoveAll(root)
  88. c.Fatal(err)
  89. }
  90. var server gitServer
  91. if !enforceLocalServer {
  92. // use fakeStorage server, which might be local or remote (at test daemon)
  93. server = fakestorage.New(c, root)
  94. } else {
  95. // always start a local http server on CLI test machine
  96. httpServer := httptest.NewServer(http.FileServer(http.Dir(root)))
  97. server = &localGitServer{httpServer}
  98. }
  99. return &FakeGit{
  100. root: root,
  101. server: server,
  102. RepoURL: fmt.Sprintf("%s/%s.git", server.URL(), name),
  103. }
  104. }