This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / spindle / engines / microvm / upload_cache_proxy_test.go
3.9 kB 130 lines
1//go:build linux 2 3package microvm 4 5import ( 6 "io" 7 "log/slog" 8 "net/http" 9 "net/http/httptest" 10 "net/url" 11 "strings" 12 "testing" 13) 14 15func TestUploadProxyRewritesHostAndAuth(t *testing.T) { 16 var upstreamHost string 17 upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { 18 if req.Host != upstreamHost { 19 t.Errorf("host: got %q, want %q", req.Host, upstreamHost) 20 } 21 if req.URL.Path != "/sub/abc.narinfo" { 22 t.Errorf("path: got %q, want /sub/abc.narinfo", req.URL.Path) 23 } 24 if user, pass, ok := req.BasicAuth(); !ok || user != "dawn" || pass != "woof" { 25 t.Errorf("basic auth: got %q/%q/%v, want dawn/hunter2/true", user, pass, ok) 26 } 27 _, _ = io.WriteString(w, "ok") 28 })) 29 defer upstream.Close() 30 upstreamHost = strings.TrimPrefix(upstream.URL, "http://") 31 32 target, err := url.Parse("http://dawn:woof@" + upstreamHost + "/sub/") 33 if err != nil { 34 t.Fatal(err) 35 } 36 37 req := httptest.NewRequest(http.MethodPut, "http://127.0.0.1:10501/abc.narinfo", strings.NewReader("narinfo")) 38 req.Host = "127.0.0.1:10501" 39 rec := httptest.NewRecorder() 40 uploadProxyHandler(target, nil, slog.Default()).ServeHTTP(rec, req) 41 42 if rec.Code != http.StatusOK { 43 t.Fatalf("status: got %d, want 200; body=%q", rec.Code, rec.Body.String()) 44 } 45} 46 47func mustParseURL(t *testing.T, raw string) *url.URL { 48 t.Helper() 49 u, err := url.Parse(raw) 50 if err != nil { 51 t.Fatalf("parse %q: %v", raw, err) 52 } 53 return u 54} 55 56func TestUploadProxySkipsNarinfoAvailableUpstream(t *testing.T) { 57 var uploadHits int 58 target := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { 59 uploadHits++ 60 w.WriteHeader(http.StatusNotFound) 61 })) 62 defer target.Close() 63 64 upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { 65 if req.URL.Path != "/abc.narinfo" { 66 t.Errorf("upstream path: got %q, want /abc.narinfo", req.URL.Path) 67 } 68 _, _ = io.WriteString(w, "StorePath: /nix/store/abc\n") 69 })) 70 defer upstream.Close() 71 72 handler := uploadProxyHandler( 73 mustParseURL(t, target.URL), 74 []CacheUpstream{{url: mustParseURL(t, upstream.URL)}}, 75 slog.Default(), 76 ) 77 78 req := httptest.NewRequest(http.MethodGet, "http://127.0.0.1:10501/abc.narinfo", nil) 79 rec := httptest.NewRecorder() 80 handler.ServeHTTP(rec, req) 81 82 if rec.Code != http.StatusOK { 83 t.Fatalf("status: got %d, want 200 (so nix treats the path as present and skips upload)", rec.Code) 84 } 85 if !strings.Contains(rec.Body.String(), "StorePath: /nix/store/abc") { 86 t.Fatalf("body: got %q, want the upstream narinfo body", rec.Body.String()) 87 } 88} 89 90func TestUploadProxyUploadsNarinfoNobodyHas(t *testing.T) { 91 target := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { 92 w.WriteHeader(http.StatusNotFound) 93 })) 94 defer target.Close() 95 upstream := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { 96 w.WriteHeader(http.StatusNotFound) 97 })) 98 defer upstream.Close() 99 100 handler := uploadProxyHandler( 101 mustParseURL(t, target.URL), 102 []CacheUpstream{{url: mustParseURL(t, upstream.URL)}}, 103 slog.Default(), 104 ) 105 106 req := httptest.NewRequest(http.MethodGet, "http://127.0.0.1:10501/abc.narinfo", nil) 107 rec := httptest.NewRecorder() 108 handler.ServeHTTP(rec, req) 109 110 if rec.Code != http.StatusNotFound { 111 t.Fatalf("status: got %d, want 404 (so nix uploads the path)", rec.Code) 112 } 113} 114 115func TestUploadProxySkipsNarinfoAlreadyOnTarget(t *testing.T) { 116 target := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { 117 _, _ = io.WriteString(w, "StorePath: /nix/store/abc\n") 118 })) 119 defer target.Close() 120 121 handler := uploadProxyHandler(mustParseURL(t, target.URL), nil, slog.Default()) 122 123 req := httptest.NewRequest(http.MethodGet, "http://127.0.0.1:10501/abc.narinfo", nil) 124 rec := httptest.NewRecorder() 125 handler.ServeHTTP(rec, req) 126 127 if rec.Code != http.StatusOK { 128 t.Fatalf("status: got %d, want 200", rec.Code) 129 } 130}