github.com/mgoltzsche/ctnr@v0.7.1-alpha/pkg/fs/source/sourceurl_test.go (about) 1 package source 2 3 import ( 4 "fmt" 5 "net" 6 "net/http" 7 "net/url" 8 "os" 9 "strings" 10 "testing" 11 12 "github.com/mgoltzsche/ctnr/pkg/fs" 13 "github.com/mgoltzsche/ctnr/pkg/fs/testutils" 14 "github.com/mgoltzsche/ctnr/pkg/idutils" 15 "github.com/stretchr/testify/assert" 16 "github.com/stretchr/testify/require" 17 ) 18 19 func TestSourceURL(t *testing.T) { 20 listener, url := mockHttpResource(t) 21 defer listener.Close() 22 writerMock := testutils.NewWriterMock(t, fs.AttrsAll) 23 var mode os.FileMode = 0600 24 usr := idutils.UserIds{1, 33} 25 mockCache := mockedHttpCache{map[string]*HttpHeaders{}} 26 testee := NewSourceURL(url, &mockCache, usr) 27 28 a := testee.Attrs() 29 if a.NodeType != fs.TypeFile { 30 t.Errorf("Attrs(): type != TypeFile but %q", a.NodeType) 31 t.FailNow() 32 } 33 if a.Mode != mode { 34 t.Errorf("Attrs(): mode %s != %s", a.Mode, mode) 35 } 36 37 // Test derived attrs 38 wa, err := testee.DeriveAttrs() 39 require.NoError(t, err) 40 if wa.URL != url.String() { 41 t.Errorf("URL %q != %q", url, wa.URL) 42 } 43 if wa.Hash != "" { 44 t.Errorf("hash != '' but %q", wa.Hash) 45 } 46 if wa.HTTPInfo == "" { 47 t.Errorf("http cache info == ''") 48 } 49 etag1 := wa.HTTPInfo 50 testee = NewSourceURL(url, &mockCache, usr) 51 wa, err = testee.DeriveAttrs() 52 require.NoError(t, err) 53 etag2 := wa.HTTPInfo 54 if etag1 != etag2 { 55 t.Error("http info != http info") 56 } 57 58 // Test write 59 testee.Write("/file", "", writerMock, nil) 60 actual := strings.Join(writerMock.Written, "\n") 61 expected := "/file type=file usr=1:33 mode=600 size=13 url=" + url.String() + " http=etag:mocked+%3D+etag1,time:Fri%2C+21+Sep+2018+20%3A52%3A35+GMT" 62 assert.Equal(t, expected, actual) 63 } 64 65 func mockHttpResource(t *testing.T) (net.Listener, *url.URL) { 66 reqCount := 0 67 http.HandleFunc("/file", func(w http.ResponseWriter, r *http.Request) { 68 reqCount++ 69 etag := r.Header.Get("If-None-Match") 70 w.Header().Set("Last-Modified", "Fri, 21 Sep 2018 20:52:35 GMT") 71 if etag == "" { 72 w.Header().Set("ETag", fmt.Sprintf("mocked = etag%d", reqCount)) 73 w.WriteHeader(http.StatusOK) 74 } else { 75 w.Header().Set("ETag", etag) 76 w.WriteHeader(http.StatusNotModified) 77 } 78 fmt.Fprintf(w, "servercontent") 79 }) 80 listener, err := net.Listen("tcp", ":0") 81 require.NoError(t, err) 82 go http.Serve(listener, nil) 83 url, err := url.Parse(fmt.Sprintf("http://127.0.0.1:%d/file", listener.Addr().(*net.TCPAddr).Port)) 84 require.NoError(t, err) 85 return listener, url 86 } 87 88 type mockedHttpCache struct { 89 entries map[string]*HttpHeaders 90 } 91 92 func (c *mockedHttpCache) GetHttpHeaders(url string) (*HttpHeaders, error) { 93 return c.entries[url], nil 94 } 95 func (c *mockedHttpCache) PutHttpHeaders(url string, attrs *HttpHeaders) error { 96 c.entries[url] = attrs 97 return nil 98 }