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