package pkg_test import ( "crypto/sha512" "encoding/base64" "net/http" "reflect" "testing" "testing/fstest" "hakurei.app/container/check" "hakurei.app/internal/pkg" ) func TestHTTP(t *testing.T) { t.Parallel() const testdata = "\x7f\xe1\x69\xa2\xdd\x63\x96\x26\x83\x79\x61\x8b\xf0\x3f\xd5\x16\x9a\x39\x3a\xdb\xcf\xb1\xbc\x8d\x33\xff\x75\xee\x62\x56\xa9\xf0\x27\xac\x13\x94\x69" testdataChecksum := func() pkg.Checksum { h := sha512.New384() h.Write([]byte(testdata)) return (pkg.Checksum)(h.Sum(nil)) }() testdataChecksumString := base64.URLEncoding.EncodeToString(testdataChecksum[:]) var transport http.Transport client := http.Client{Transport: &transport} transport.RegisterProtocol("file", http.NewFileTransportFS(fstest.MapFS{ "testdata": {Data: []byte(testdata), Mode: 0400}, })) checkWithCache(t, []cacheTestCase{ {"direct", nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) { var got []byte if f, err := c.NewHTTPGet( t.Context(), &client, "file:///testdata", testdataChecksum, ); err != nil { t.Fatalf("NewHTTPGet: error = %v", err) } else if got, err = f.Data(); err != nil { t.Fatalf("Data: error = %v", err) } else if string(got) != testdata { t.Fatalf("Data: %x, want %x", got, testdata) } else if gotIdent := f.ID(); gotIdent != testdataChecksum { t.Fatalf("ID: %x, want %x", gotIdent, testdataChecksum) } // check direct validation wantErrMismatch := &pkg.ChecksumMismatchError{ Got: testdataChecksum, } if f, err := c.NewHTTPGet( t.Context(), &client, "file:///testdata", pkg.Checksum{}, ); err != nil { t.Fatalf("NewHTTPGet: error = %v", err) } else if _, err = f.Data(); !reflect.DeepEqual(err, wantErrMismatch) { t.Fatalf("Data: error = %#v, want %#v", err, wantErrMismatch) } else if gotIdent := f.ID(); gotIdent != (pkg.Checksum{}) { t.Fatalf("ID: %x, want %x", gotIdent, pkg.Checksum{}) } // check direct response error wantErrNotFound := pkg.ResponseStatusError(http.StatusNotFound) if f, err := c.NewHTTPGet( t.Context(), &client, "file:///nonexistent", pkg.Checksum{}, ); err != nil { t.Fatalf("NewHTTPGet: error = %v", err) } else if _, err = f.Data(); !reflect.DeepEqual(err, wantErrNotFound) { t.Fatalf("Data: error = %#v, want %#v", err, wantErrNotFound) } else if gotIdent := f.ID(); gotIdent != (pkg.Checksum{}) { t.Fatalf("ID: %x, want %x", gotIdent, pkg.Checksum{}) } }, pkg.MustDecode("E4vEZKhCcL2gPZ2Tt59FS3lDng-d_2SKa2i5G_RbDfwGn6EemptFaGLPUDiOa94C")}, {"load or store", nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) { f, err := c.NewHTTPGet( t.Context(), &client, "file:///testdata", testdataChecksum, ) if err != nil { t.Fatalf("NewHTTPGet: error = %v", err) } wantPathname := base.Append( "identifier", testdataChecksumString, ) var pathname *check.Absolute if pathname, err = f.Pathname(); err != nil { t.Fatalf("Pathname: error = %v", err) } else if !pathname.Is(wantPathname) { t.Fatalf("Pathname: %q, want %q", pathname, wantPathname) } var checksum pkg.Checksum if checksum, err = f.Hash(); err != nil { t.Fatalf("Hash: error = %v", err) } else if checksum != testdataChecksum { t.Fatalf("Hash: %x, want %x", checksum, testdataChecksum) } var got []byte if got, err = f.Data(); err != nil { t.Fatalf("Data: error = %v", err) } else if string(got) != testdata { t.Fatalf("Data: %x, want %x", got, testdata) } else if gotIdent := f.ID(); gotIdent != testdataChecksum { t.Fatalf("ID: %x, want %x", gotIdent, testdataChecksum) } // check load from cache if f, err = c.NewHTTPGet( t.Context(), &client, "file:///testdata", testdataChecksum, ); err != nil { t.Fatalf("NewHTTPGet: error = %v", err) } else if got, err = f.Data(); err != nil { t.Fatalf("Data: error = %v", err) } else if string(got) != testdata { t.Fatalf("Data: %x, want %x", got, testdata) } else if gotIdent := f.ID(); gotIdent != testdataChecksum { t.Fatalf("ID: %x, want %x", gotIdent, testdataChecksum) } // check error passthrough wantErrNotFound := pkg.ResponseStatusError(http.StatusNotFound) if f, err = c.NewHTTPGet( t.Context(), &client, "file:///nonexistent", pkg.Checksum{}, ); err != nil { t.Fatalf("NewHTTPGet: error = %v", err) } else if _, err = f.Pathname(); !reflect.DeepEqual(err, wantErrNotFound) { t.Fatalf("Pathname: error = %#v, want %#v", err, wantErrNotFound) } else if gotIdent := f.ID(); gotIdent != (pkg.Checksum{}) { t.Fatalf("ID: %x, want %x", gotIdent, pkg.Checksum{}) } }, pkg.MustDecode("4WHaMvRRcCac1uAyXnEklEd2YaNQBj6rXlfMntX9GgYLij3By1znv5QYPGJHYQIH")}, {"store", nil, func(t *testing.T, base *check.Absolute, c *pkg.Cache) { var ( got []byte pathname *check.Absolute checksum pkg.Checksum ) wantPathname := base.Append( "identifier", testdataChecksumString, ) if f, err := c.NewHTTPGet( t.Context(), &client, "file:///testdata", testdataChecksum, ); err != nil { t.Fatalf("NewHTTPGet: error = %v", err) } else if got, err = f.Data(); err != nil { t.Fatalf("Data: error = %v", err) } else if string(got) != testdata { t.Fatalf("Data: %x, want %x", got, testdata) } else if gotIdent := f.ID(); gotIdent != testdataChecksum { t.Fatalf("ID: %x, want %x", gotIdent, testdataChecksum) } else if pathname, err = f.Pathname(); err != nil { t.Fatalf("Pathname: error = %v", err) } else if !pathname.Is(wantPathname) { t.Fatalf("Pathname: %q, want %q", pathname, wantPathname) } else if checksum, err = f.Hash(); err != nil { t.Fatalf("Hash: error = %v", err) } else if checksum != testdataChecksum { t.Fatalf("Hash: %x, want %x", checksum, testdataChecksum) } }, pkg.MustDecode("4WHaMvRRcCac1uAyXnEklEd2YaNQBj6rXlfMntX9GgYLij3By1znv5QYPGJHYQIH")}, }) }