feat: add etag to slim binaries endpoint (#5750)

This commit is contained in:
Dean Sheather
2023-01-17 12:38:08 -06:00
committed by GitHub
parent c377cd0fa9
commit b19d644162
3 changed files with 227 additions and 63 deletions
+58 -13
View File
@@ -45,7 +45,7 @@ func TestCaching(t *testing.T) {
}
binFS := http.FS(fstest.MapFS{})
srv := httptest.NewServer(site.Handler(rootFS, binFS))
srv := httptest.NewServer(site.Handler(rootFS, binFS, nil))
defer srv.Close()
// Create a context
@@ -105,7 +105,7 @@ func TestServingFiles(t *testing.T) {
}
binFS := http.FS(fstest.MapFS{})
srv := httptest.NewServer(site.Handler(rootFS, binFS))
srv := httptest.NewServer(site.Handler(rootFS, binFS, nil))
defer srv.Close()
// Create a context
@@ -185,10 +185,18 @@ const (
binCoderTarZstd = "bin/coder.tar.zst"
)
var sampleBinSHAs = map[string]string{
"coder-linux-amd64": "55641d5d56bbb8ccf5850fe923bd971b86364604",
}
func sampleBinFS() fstest.MapFS {
sha1File := bytes.NewBuffer(nil)
for name, sha := range sampleBinSHAs {
_, _ = fmt.Fprintf(sha1File, "%s *%s\n", sha, name)
}
return fstest.MapFS{
binCoderSha1: &fstest.MapFile{
Data: []byte("55641d5d56bbb8ccf5850fe923bd971b86364604 *coder-linux-amd64\n"),
Data: sha1File.Bytes(),
},
binCoderTarZstd: &fstest.MapFile{
// echo -n compressed >coder-linux-amd64
@@ -241,9 +249,11 @@ func TestServingBin(t *testing.T) {
delete(sampleBinFSMissingSha256, binCoderSha1)
type req struct {
url string
wantStatus int
wantBody []byte
url string
ifNoneMatch string
wantStatus int
wantBody []byte
wantEtag string
}
tests := []struct {
name string
@@ -255,7 +265,19 @@ func TestServingBin(t *testing.T) {
name: "Extract and serve bin",
fs: sampleBinFS(),
reqs: []req{
{url: "/bin/coder-linux-amd64", wantStatus: http.StatusOK, wantBody: []byte("compressed")},
{
url: "/bin/coder-linux-amd64",
wantStatus: http.StatusOK,
wantBody: []byte("compressed"),
wantEtag: fmt.Sprintf("%q", sampleBinSHAs["coder-linux-amd64"]),
},
// Test ETag support.
{
url: "/bin/coder-linux-amd64",
ifNoneMatch: fmt.Sprintf("%q", sampleBinSHAs["coder-linux-amd64"]),
wantStatus: http.StatusNotModified,
wantEtag: fmt.Sprintf("%q", sampleBinSHAs["coder-linux-amd64"]),
},
{url: "/bin/GITKEEP", wantStatus: http.StatusNotFound},
},
},
@@ -329,14 +351,14 @@ func TestServingBin(t *testing.T) {
t.Parallel()
dest := t.TempDir()
binFS, err := site.ExtractOrReadBinFS(dest, tt.fs)
binFS, binHashes, err := site.ExtractOrReadBinFS(dest, tt.fs)
if !tt.wantErr && err != nil {
require.NoError(t, err, "extract or read failed")
} else if tt.wantErr {
require.Error(t, err, "extraction or read did not fail")
}
srv := httptest.NewServer(site.Handler(rootFS, binFS))
srv := httptest.NewServer(site.Handler(rootFS, binFS, binHashes))
defer srv.Close()
// Create a context
@@ -348,6 +370,10 @@ func TestServingBin(t *testing.T) {
req, err := http.NewRequestWithContext(ctx, "GET", srv.URL+tr.url, nil)
require.NoError(t, err, "http request failed")
if tr.ifNoneMatch != "" {
req.Header.Set("If-None-Match", tr.ifNoneMatch)
}
resp, err := http.DefaultClient.Do(req)
require.NoError(t, err, "http do failed")
defer resp.Body.Close()
@@ -361,6 +387,14 @@ func TestServingBin(t *testing.T) {
if tr.wantBody != nil {
assert.Equal(t, string(tr.wantBody), string(gotBody), "body did not match")
}
if tr.wantStatus == http.StatusNoContent || tr.wantStatus == http.StatusNotModified {
assert.Empty(t, gotBody, "body is not empty")
}
if tr.wantEtag != "" {
assert.NotEmpty(t, resp.Header.Get("ETag"), "etag header is empty")
assert.Equal(t, tr.wantEtag, resp.Header.Get("ETag"), "etag did not match")
}
})
}
})
@@ -374,7 +408,7 @@ func TestExtractOrReadBinFS(t *testing.T) {
siteFS := sampleBinFS()
dest := t.TempDir()
_, err := site.ExtractOrReadBinFS(dest, siteFS)
_, _, err := site.ExtractOrReadBinFS(dest, siteFS)
require.NoError(t, err)
checkModtime := func() map[string]time.Time {
@@ -402,7 +436,7 @@ func TestExtractOrReadBinFS(t *testing.T) {
firstModtimes := checkModtime()
_, err = site.ExtractOrReadBinFS(dest, siteFS)
_, _, err = site.ExtractOrReadBinFS(dest, siteFS)
require.NoError(t, err)
secondModtimes := checkModtime()
@@ -414,7 +448,7 @@ func TestExtractOrReadBinFS(t *testing.T) {
siteFS := sampleBinFS()
dest := t.TempDir()
_, err := site.ExtractOrReadBinFS(dest, siteFS)
_, _, err := site.ExtractOrReadBinFS(dest, siteFS)
require.NoError(t, err)
bin := filepath.Join(dest, "bin", "coder-linux-amd64")
@@ -428,7 +462,7 @@ func TestExtractOrReadBinFS(t *testing.T) {
err = f.Close()
require.NoError(t, err)
_, err = site.ExtractOrReadBinFS(dest, siteFS)
_, _, err = site.ExtractOrReadBinFS(dest, siteFS)
require.NoError(t, err)
f, err = os.Open(bin)
@@ -441,6 +475,17 @@ func TestExtractOrReadBinFS(t *testing.T) {
assert.NotEqual(t, dontWant, got, "file should be overwritten on hash mismatch")
})
t.Run("ParsesHashes", func(t *testing.T) {
t.Parallel()
siteFS := sampleBinFS()
dest := t.TempDir()
_, hashes, err := site.ExtractOrReadBinFS(dest, siteFS)
require.NoError(t, err)
require.Equal(t, sampleBinSHAs, hashes, "hashes did not match")
})
}
func TestRenderStaticErrorPage(t *testing.T) {