github.com/adevinta/lava@v0.7.2/internal/gitserver/gitserver_test.go (about)

     1  // Copyright 2023 Adevinta
     2  
     3  package gitserver
     4  
     5  import (
     6  	"flag"
     7  	"fmt"
     8  	"log/slog"
     9  	"net"
    10  	"net/http"
    11  	"os"
    12  	"path/filepath"
    13  	"testing"
    14  
    15  	"github.com/jroimartin/clilog"
    16  
    17  	"github.com/adevinta/lava/internal/gitserver/gittest"
    18  )
    19  
    20  func TestMain(m *testing.M) {
    21  	flag.Parse()
    22  
    23  	level := slog.LevelError
    24  	if testing.Verbose() {
    25  		level = slog.LevelDebug
    26  	}
    27  
    28  	h := clilog.NewCLIHandler(os.Stderr, &clilog.HandlerOptions{Level: level})
    29  	slog.SetDefault(slog.New(h))
    30  
    31  	os.Exit(m.Run())
    32  }
    33  
    34  func TestServer_AddRepository(t *testing.T) {
    35  	// Not parallel: uses global test hook.
    36  	defer func() { testHookServerServe = nil }()
    37  
    38  	tmpPath, err := gittest.ExtractTemp(filepath.Join("testdata", "testrepo.tar"))
    39  	if err != nil {
    40  		t.Fatalf("unable to create a repository: %v", err)
    41  	}
    42  	defer os.RemoveAll(tmpPath)
    43  
    44  	gs, err := New()
    45  	if err != nil {
    46  		t.Fatalf("unable to create a server: %v", err)
    47  	}
    48  	defer gs.Close()
    49  
    50  	lnc := make(chan net.Listener)
    51  	testHookServerServe = func(gs *Server, ln net.Listener) {
    52  		lnc <- ln
    53  	}
    54  
    55  	go gs.ListenAndServe("127.0.0.1:0") //nolint:errcheck
    56  
    57  	ln := <-lnc
    58  
    59  	repoName, err := gs.AddRepository(tmpPath)
    60  	if err != nil {
    61  		t.Fatalf("unable to add a repository: %v", err)
    62  	}
    63  
    64  	repoPath, err := gittest.CloneTemp(fmt.Sprintf("http://%v/%s", ln.Addr(), repoName))
    65  	if err != nil {
    66  		t.Fatalf("unable to clone the repo %s: %v", repoName, err)
    67  	}
    68  	defer os.RemoveAll(repoPath)
    69  
    70  	if _, err := os.Stat(filepath.Join(repoPath, "foo.txt")); err != nil {
    71  		t.Fatalf("unexpected error: %v", err)
    72  	}
    73  }
    74  
    75  func TestServer_AddRepository_no_repo(t *testing.T) {
    76  	tmpPath, err := os.MkdirTemp("", "")
    77  	if err != nil {
    78  		t.Fatalf("unable to create a temporary dir")
    79  	}
    80  	defer os.RemoveAll(tmpPath)
    81  
    82  	gs, err := New()
    83  	if err != nil {
    84  		t.Fatalf("unable to create a server: %v", err)
    85  	}
    86  	defer gs.Close() //nolint:staticcheck
    87  
    88  	if _, err = gs.AddRepository(tmpPath); err == nil {
    89  		t.Fatal("expected error adding repository")
    90  	}
    91  }
    92  
    93  func TestServer_AddRepository_invalid_dir(t *testing.T) {
    94  	gs, err := New()
    95  	if err != nil {
    96  		t.Fatalf("unable to create a server: %v", err)
    97  	}
    98  	defer gs.Close() //nolint:staticcheck
    99  
   100  	if _, err = gs.AddRepository("/fakedir"); err == nil {
   101  		t.Fatal("expected error adding repository")
   102  	}
   103  }
   104  
   105  func TestServer_AddRepository_invalid_dir_2(t *testing.T) {
   106  	tmpPath, err := os.MkdirTemp("", "")
   107  	if err != nil {
   108  		t.Fatalf("unable to create a temporary dir")
   109  	}
   110  	defer os.RemoveAll(tmpPath)
   111  
   112  	gs := &Server{
   113  		basePath: "testdata/fakedir",
   114  		repos:    make(map[string]string),
   115  		httpsrv:  &http.Server{Handler: newSmartServer(tmpPath)},
   116  	}
   117  	defer gs.Close() //nolint:staticcheck
   118  
   119  	if _, err = gs.AddRepository(tmpPath); err == nil {
   120  		t.Fatal("expected error adding repository")
   121  	}
   122  }
   123  
   124  func TestServer_AddRepository_do_not_cache_error(t *testing.T) {
   125  	gs, err := New()
   126  	if err != nil {
   127  		t.Fatalf("unable to create a server: %v", err)
   128  	}
   129  	defer gs.Close() //nolint:staticcheck
   130  
   131  	if _, err = gs.AddRepository("/fakedir"); err == nil {
   132  		t.Fatal("expected error adding repository")
   133  	}
   134  
   135  	if _, err = gs.AddRepository("/fakedir"); err == nil {
   136  		t.Fatal("expected error adding repository")
   137  	}
   138  }
   139  
   140  func TestServer_AddRepository_already_added(t *testing.T) {
   141  	tmpPath, err := gittest.ExtractTemp(filepath.Join("testdata", "testrepo.tar"))
   142  	if err != nil {
   143  		t.Fatalf("unable to create a repository: %v", err)
   144  	}
   145  	defer os.RemoveAll(tmpPath)
   146  
   147  	gs, err := New()
   148  	if err != nil {
   149  		t.Fatalf("unable to create a server: %v", err)
   150  	}
   151  	defer gs.Close()
   152  
   153  	repoName, err := gs.AddRepository(tmpPath)
   154  	if err != nil {
   155  		t.Fatalf("unable to add a repository: %v", err)
   156  	}
   157  	repoName2, err := gs.AddRepository(tmpPath)
   158  	if err != nil {
   159  		t.Fatalf("unable to add a repository: %v", err)
   160  	}
   161  
   162  	if repoName != repoName2 {
   163  		t.Fatalf("%s should be the same as %s", repoName, repoName2)
   164  	}
   165  }
   166  
   167  func TestServer_AddPath(t *testing.T) {
   168  	// Not parallel: uses global test hook.
   169  	defer func() { testHookServerServe = nil }()
   170  
   171  	gs, err := New()
   172  	if err != nil {
   173  		t.Fatalf("unable to create a server: %v", err)
   174  	}
   175  	defer gs.Close()
   176  
   177  	lnc := make(chan net.Listener)
   178  	testHookServerServe = func(gs *Server, ln net.Listener) {
   179  		lnc <- ln
   180  	}
   181  
   182  	go gs.ListenAndServe("127.0.0.1:0") //nolint:errcheck
   183  
   184  	ln := <-lnc
   185  
   186  	repoName, err := gs.AddPath("testdata/dir")
   187  	if err != nil {
   188  		t.Fatalf("unable to add a path: %v", err)
   189  	}
   190  
   191  	repoPath, err := gittest.CloneTemp(fmt.Sprintf("http://%v/%s", ln.Addr(), repoName))
   192  	if err != nil {
   193  		t.Fatalf("unable to clone the repo %s: %v", repoName, err)
   194  	}
   195  	defer os.RemoveAll(repoPath)
   196  
   197  	if _, err := os.Stat(filepath.Join(repoPath, "foo.txt")); err != nil {
   198  		t.Fatalf("unexpected error: %v", err)
   199  	}
   200  }
   201  
   202  func TestServer_AddPath_file(t *testing.T) {
   203  	// Not parallel: uses global test hook.
   204  	defer func() { testHookServerServe = nil }()
   205  
   206  	gs, err := New()
   207  	if err != nil {
   208  		t.Fatalf("unable to create a server: %v", err)
   209  	}
   210  	defer gs.Close()
   211  
   212  	lnc := make(chan net.Listener)
   213  	testHookServerServe = func(gs *Server, ln net.Listener) {
   214  		lnc <- ln
   215  	}
   216  
   217  	go gs.ListenAndServe("127.0.0.1:0") //nolint:errcheck
   218  
   219  	ln := <-lnc
   220  
   221  	repoName, err := gs.AddPath("testdata/dir/foo.txt")
   222  	if err != nil {
   223  		t.Fatalf("unable to add a path: %v", err)
   224  	}
   225  
   226  	repoPath, err := gittest.CloneTemp(fmt.Sprintf("http://%v/%s", ln.Addr(), repoName))
   227  	if err != nil {
   228  		t.Fatalf("unable to clone the repo %s: %v", repoName, err)
   229  	}
   230  	defer os.RemoveAll(repoPath)
   231  
   232  	if _, err := os.Stat(filepath.Join(repoPath, "foo.txt")); err != nil {
   233  		t.Fatalf("unexpected error: %v", err)
   234  	}
   235  }
   236  
   237  func TestServer_AddPath_symlink(t *testing.T) {
   238  	// Not parallel: uses global test hook.
   239  	defer func() { testHookServerServe = nil }()
   240  
   241  	gs, err := New()
   242  	if err != nil {
   243  		t.Fatalf("unable to create a server: %v", err)
   244  	}
   245  	defer gs.Close()
   246  
   247  	lnc := make(chan net.Listener)
   248  	testHookServerServe = func(gs *Server, ln net.Listener) {
   249  		lnc <- ln
   250  	}
   251  
   252  	go gs.ListenAndServe("127.0.0.1:0") //nolint:errcheck
   253  
   254  	ln := <-lnc
   255  
   256  	repoName, err := gs.AddPath("testdata/symlink")
   257  	if err != nil {
   258  		t.Fatalf("unable to add a path: %v", err)
   259  	}
   260  
   261  	repoPath, err := gittest.CloneTemp(fmt.Sprintf("http://%v/%s", ln.Addr(), repoName))
   262  	if err != nil {
   263  		t.Fatalf("unable to clone the repo %s: %v", repoName, err)
   264  	}
   265  	defer os.RemoveAll(repoPath)
   266  
   267  	if _, err := os.Stat(filepath.Join(repoPath, "bar.txt")); err != nil {
   268  		t.Fatalf("unexpected error: %v", err)
   269  	}
   270  }
   271  
   272  func TestServer_AddPath_repo(t *testing.T) {
   273  	// Not parallel: uses global test hook.
   274  	defer func() { testHookServerServe = nil }()
   275  
   276  	tmpPath, err := gittest.ExtractTemp(filepath.Join("testdata", "testrepo.tar"))
   277  	if err != nil {
   278  		t.Fatalf("unable to create a repository: %v", err)
   279  	}
   280  	defer os.RemoveAll(tmpPath)
   281  
   282  	gs, err := New()
   283  	if err != nil {
   284  		t.Fatalf("unable to create a server: %v", err)
   285  	}
   286  	defer gs.Close()
   287  
   288  	lnc := make(chan net.Listener)
   289  	testHookServerServe = func(gs *Server, ln net.Listener) {
   290  		lnc <- ln
   291  	}
   292  
   293  	go gs.ListenAndServe("127.0.0.1:0") //nolint:errcheck
   294  
   295  	ln := <-lnc
   296  
   297  	repoName, err := gs.AddPath(tmpPath)
   298  	if err != nil {
   299  		t.Fatalf("unable to add a path: %v", err)
   300  	}
   301  
   302  	repoPath, err := gittest.CloneTemp(fmt.Sprintf("http://%v/%s", ln.Addr(), repoName))
   303  	if err != nil {
   304  		t.Fatalf("unable to clone the repo %s: %v", repoName, err)
   305  	}
   306  	defer os.RemoveAll(repoPath)
   307  
   308  	if _, err := os.Stat(filepath.Join(repoPath, "foo.txt")); err != nil {
   309  		t.Fatalf("unexpected error: %v", err)
   310  	}
   311  }
   312  
   313  func TestServer_AddPath_invalid_path(t *testing.T) {
   314  	gs, err := New()
   315  	if err != nil {
   316  		t.Fatalf("unable to create a server: %v", err)
   317  	}
   318  	defer gs.Close() //nolint:staticcheck
   319  
   320  	if _, err = gs.AddPath("/fakedir"); err == nil {
   321  		t.Fatal("expected error adding path")
   322  	}
   323  }
   324  
   325  func TestServer_AddPath_do_not_cache_error(t *testing.T) {
   326  	gs, err := New()
   327  	if err != nil {
   328  		t.Fatalf("unable to create a server: %v", err)
   329  	}
   330  	defer gs.Close() //nolint:staticcheck
   331  
   332  	if _, err = gs.AddPath("/fakedir"); err == nil {
   333  		t.Fatal("expected error adding path")
   334  	}
   335  
   336  	if _, err = gs.AddPath("/fakedir"); err == nil {
   337  		t.Fatal("expected error adding path")
   338  	}
   339  }
   340  
   341  func TestServer_AddPath_already_added(t *testing.T) {
   342  	gs, err := New()
   343  	if err != nil {
   344  		t.Fatalf("unable to create a server: %v", err)
   345  	}
   346  	defer gs.Close()
   347  
   348  	repoName, err := gs.AddPath("testdata/dir")
   349  	if err != nil {
   350  		t.Fatalf("unable to add a path: %v", err)
   351  	}
   352  
   353  	repoName2, err := gs.AddPath("testdata/dir")
   354  	if err != nil {
   355  		t.Fatalf("unable to add a path: %v", err)
   356  	}
   357  
   358  	if repoName != repoName2 {
   359  		t.Fatalf("%s should be the same as %s", repoName, repoName2)
   360  	}
   361  }