github.com/flavio/docker@v0.1.3-0.20170117145210-f63d1a6eec47/pkg/httputils/resumablerequestreader_test.go (about)

     1  package httputils
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"io/ioutil"
     7  	"net/http"
     8  	"net/http/httptest"
     9  	"strings"
    10  	"testing"
    11  	"time"
    12  )
    13  
    14  func TestResumableRequestHeaderSimpleErrors(t *testing.T) {
    15  	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    16  		fmt.Fprintln(w, "Hello, world !")
    17  	}))
    18  	defer ts.Close()
    19  
    20  	client := &http.Client{}
    21  
    22  	var req *http.Request
    23  	req, err := http.NewRequest("GET", ts.URL, nil)
    24  	if err != nil {
    25  		t.Fatal(err)
    26  	}
    27  
    28  	expectedError := "client and request can't be nil\n"
    29  	resreq := &resumableRequestReader{}
    30  	_, err = resreq.Read([]byte{})
    31  	if err == nil || err.Error() != expectedError {
    32  		t.Fatalf("Expected an error with '%s', got %v.", expectedError, err)
    33  	}
    34  
    35  	resreq = &resumableRequestReader{
    36  		client:    client,
    37  		request:   req,
    38  		totalSize: -1,
    39  	}
    40  	expectedError = "failed to auto detect content length"
    41  	_, err = resreq.Read([]byte{})
    42  	if err == nil || err.Error() != expectedError {
    43  		t.Fatalf("Expected an error with '%s', got %v.", expectedError, err)
    44  	}
    45  
    46  }
    47  
    48  // Not too much failures, bails out after some wait
    49  func TestResumableRequestHeaderNotTooMuchFailures(t *testing.T) {
    50  	client := &http.Client{}
    51  
    52  	var badReq *http.Request
    53  	badReq, err := http.NewRequest("GET", "I'm not an url", nil)
    54  	if err != nil {
    55  		t.Fatal(err)
    56  	}
    57  
    58  	resreq := &resumableRequestReader{
    59  		client:       client,
    60  		request:      badReq,
    61  		failures:     0,
    62  		maxFailures:  2,
    63  		waitDuration: 10 * time.Millisecond,
    64  	}
    65  	read, err := resreq.Read([]byte{})
    66  	if err != nil || read != 0 {
    67  		t.Fatalf("Expected no error and no byte read, got err:%v, read:%v.", err, read)
    68  	}
    69  }
    70  
    71  // Too much failures, returns the error
    72  func TestResumableRequestHeaderTooMuchFailures(t *testing.T) {
    73  	client := &http.Client{}
    74  
    75  	var badReq *http.Request
    76  	badReq, err := http.NewRequest("GET", "I'm not an url", nil)
    77  	if err != nil {
    78  		t.Fatal(err)
    79  	}
    80  
    81  	resreq := &resumableRequestReader{
    82  		client:      client,
    83  		request:     badReq,
    84  		failures:    0,
    85  		maxFailures: 1,
    86  	}
    87  	defer resreq.Close()
    88  
    89  	expectedError := `Get I%27m%20not%20an%20url: unsupported protocol scheme ""`
    90  	read, err := resreq.Read([]byte{})
    91  	if err == nil || err.Error() != expectedError || read != 0 {
    92  		t.Fatalf("Expected the error '%s', got err:%v, read:%v.", expectedError, err, read)
    93  	}
    94  }
    95  
    96  type errorReaderCloser struct{}
    97  
    98  func (errorReaderCloser) Close() error { return nil }
    99  
   100  func (errorReaderCloser) Read(p []byte) (n int, err error) {
   101  	return 0, fmt.Errorf("An error occurred")
   102  }
   103  
   104  // If an unknown error is encountered, return 0, nil and log it
   105  func TestResumableRequestReaderWithReadError(t *testing.T) {
   106  	var req *http.Request
   107  	req, err := http.NewRequest("GET", "", nil)
   108  	if err != nil {
   109  		t.Fatal(err)
   110  	}
   111  
   112  	client := &http.Client{}
   113  
   114  	response := &http.Response{
   115  		Status:        "500 Internal Server",
   116  		StatusCode:    500,
   117  		ContentLength: 0,
   118  		Close:         true,
   119  		Body:          errorReaderCloser{},
   120  	}
   121  
   122  	resreq := &resumableRequestReader{
   123  		client:          client,
   124  		request:         req,
   125  		currentResponse: response,
   126  		lastRange:       1,
   127  		totalSize:       1,
   128  	}
   129  	defer resreq.Close()
   130  
   131  	buf := make([]byte, 1)
   132  	read, err := resreq.Read(buf)
   133  	if err != nil {
   134  		t.Fatal(err)
   135  	}
   136  
   137  	if read != 0 {
   138  		t.Fatalf("Expected to have read nothing, but read %v", read)
   139  	}
   140  }
   141  
   142  func TestResumableRequestReaderWithEOFWith416Response(t *testing.T) {
   143  	var req *http.Request
   144  	req, err := http.NewRequest("GET", "", nil)
   145  	if err != nil {
   146  		t.Fatal(err)
   147  	}
   148  
   149  	client := &http.Client{}
   150  
   151  	response := &http.Response{
   152  		Status:        "416 Requested Range Not Satisfiable",
   153  		StatusCode:    416,
   154  		ContentLength: 0,
   155  		Close:         true,
   156  		Body:          ioutil.NopCloser(strings.NewReader("")),
   157  	}
   158  
   159  	resreq := &resumableRequestReader{
   160  		client:          client,
   161  		request:         req,
   162  		currentResponse: response,
   163  		lastRange:       1,
   164  		totalSize:       1,
   165  	}
   166  	defer resreq.Close()
   167  
   168  	buf := make([]byte, 1)
   169  	_, err = resreq.Read(buf)
   170  	if err == nil || err != io.EOF {
   171  		t.Fatalf("Expected an io.EOF error, got %v", err)
   172  	}
   173  }
   174  
   175  func TestResumableRequestReaderWithServerDoesntSupportByteRanges(t *testing.T) {
   176  	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   177  		if r.Header.Get("Range") == "" {
   178  			t.Fatalf("Expected a Range HTTP header, got nothing")
   179  		}
   180  	}))
   181  	defer ts.Close()
   182  
   183  	var req *http.Request
   184  	req, err := http.NewRequest("GET", ts.URL, nil)
   185  	if err != nil {
   186  		t.Fatal(err)
   187  	}
   188  
   189  	client := &http.Client{}
   190  
   191  	resreq := &resumableRequestReader{
   192  		client:    client,
   193  		request:   req,
   194  		lastRange: 1,
   195  	}
   196  	defer resreq.Close()
   197  
   198  	expectedError := "the server doesn't support byte ranges"
   199  	buf := make([]byte, 2)
   200  	_, err = resreq.Read(buf)
   201  	if err == nil || err.Error() != expectedError {
   202  		t.Fatalf("Expected an error '%s', got %v", expectedError, err)
   203  	}
   204  }
   205  
   206  func TestResumableRequestReaderWithZeroTotalSize(t *testing.T) {
   207  
   208  	srvtxt := "some response text data"
   209  
   210  	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   211  		fmt.Fprintln(w, srvtxt)
   212  	}))
   213  	defer ts.Close()
   214  
   215  	var req *http.Request
   216  	req, err := http.NewRequest("GET", ts.URL, nil)
   217  	if err != nil {
   218  		t.Fatal(err)
   219  	}
   220  
   221  	client := &http.Client{}
   222  	retries := uint32(5)
   223  
   224  	resreq := ResumableRequestReader(client, req, retries, 0)
   225  	defer resreq.Close()
   226  
   227  	data, err := ioutil.ReadAll(resreq)
   228  	if err != nil {
   229  		t.Fatal(err)
   230  	}
   231  
   232  	resstr := strings.TrimSuffix(string(data), "\n")
   233  
   234  	if resstr != srvtxt {
   235  		t.Error("resstr != srvtxt")
   236  	}
   237  }
   238  
   239  func TestResumableRequestReader(t *testing.T) {
   240  
   241  	srvtxt := "some response text data"
   242  
   243  	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   244  		fmt.Fprintln(w, srvtxt)
   245  	}))
   246  	defer ts.Close()
   247  
   248  	var req *http.Request
   249  	req, err := http.NewRequest("GET", ts.URL, nil)
   250  	if err != nil {
   251  		t.Fatal(err)
   252  	}
   253  
   254  	client := &http.Client{}
   255  	retries := uint32(5)
   256  	imgSize := int64(len(srvtxt))
   257  
   258  	resreq := ResumableRequestReader(client, req, retries, imgSize)
   259  	defer resreq.Close()
   260  
   261  	data, err := ioutil.ReadAll(resreq)
   262  	if err != nil {
   263  		t.Fatal(err)
   264  	}
   265  
   266  	resstr := strings.TrimSuffix(string(data), "\n")
   267  
   268  	if resstr != srvtxt {
   269  		t.Error("resstr != srvtxt")
   270  	}
   271  }
   272  
   273  func TestResumableRequestReaderWithInitialResponse(t *testing.T) {
   274  
   275  	srvtxt := "some response text data"
   276  
   277  	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   278  		fmt.Fprintln(w, srvtxt)
   279  	}))
   280  	defer ts.Close()
   281  
   282  	var req *http.Request
   283  	req, err := http.NewRequest("GET", ts.URL, nil)
   284  	if err != nil {
   285  		t.Fatal(err)
   286  	}
   287  
   288  	client := &http.Client{}
   289  	retries := uint32(5)
   290  	imgSize := int64(len(srvtxt))
   291  
   292  	res, err := client.Do(req)
   293  	if err != nil {
   294  		t.Fatal(err)
   295  	}
   296  
   297  	resreq := ResumableRequestReaderWithInitialResponse(client, req, retries, imgSize, res)
   298  	defer resreq.Close()
   299  
   300  	data, err := ioutil.ReadAll(resreq)
   301  	if err != nil {
   302  		t.Fatal(err)
   303  	}
   304  
   305  	resstr := strings.TrimSuffix(string(data), "\n")
   306  
   307  	if resstr != srvtxt {
   308  		t.Error("resstr != srvtxt")
   309  	}
   310  }