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