github.com/jiasir/docker@v1.3.3-0.20170609024000-252e610103e7/registry/resumable/resumablerequestreader_test.go (about)

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