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  }