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 }