...

Source file src/github.com/docker/distribution/registry/client/blob_writer_test.go

Documentation: github.com/docker/distribution/registry/client

     1  package client
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"net/http"
     7  	"testing"
     8  
     9  	"github.com/docker/distribution"
    10  	"github.com/docker/distribution/registry/api/errcode"
    11  	v2 "github.com/docker/distribution/registry/api/v2"
    12  	"github.com/docker/distribution/testutil"
    13  )
    14  
    15  // Test implements distribution.BlobWriter
    16  var _ distribution.BlobWriter = &httpBlobUpload{}
    17  
    18  func TestUploadReadFrom(t *testing.T) {
    19  	_, b := newRandomBlob(64)
    20  	repo := "test/upload/readfrom"
    21  	locationPath := fmt.Sprintf("/v2/%s/uploads/testid", repo)
    22  
    23  	m := testutil.RequestResponseMap([]testutil.RequestResponseMapping{
    24  		{
    25  			Request: testutil.Request{
    26  				Method: "GET",
    27  				Route:  "/v2/",
    28  			},
    29  			Response: testutil.Response{
    30  				StatusCode: http.StatusOK,
    31  				Headers: http.Header(map[string][]string{
    32  					"Docker-Distribution-API-Version": {"registry/2.0"},
    33  				}),
    34  			},
    35  		},
    36  		// Test Valid case
    37  		{
    38  			Request: testutil.Request{
    39  				Method: "PATCH",
    40  				Route:  locationPath,
    41  				Body:   b,
    42  			},
    43  			Response: testutil.Response{
    44  				StatusCode: http.StatusAccepted,
    45  				Headers: http.Header(map[string][]string{
    46  					"Docker-Upload-UUID": {"46603072-7a1b-4b41-98f9-fd8a7da89f9b"},
    47  					"Location":           {locationPath},
    48  					"Range":              {"0-63"},
    49  				}),
    50  			},
    51  		},
    52  		// Test invalid range
    53  		{
    54  			Request: testutil.Request{
    55  				Method: "PATCH",
    56  				Route:  locationPath,
    57  				Body:   b,
    58  			},
    59  			Response: testutil.Response{
    60  				StatusCode: http.StatusAccepted,
    61  				Headers: http.Header(map[string][]string{
    62  					"Docker-Upload-UUID": {"46603072-7a1b-4b41-98f9-fd8a7da89f9b"},
    63  					"Location":           {locationPath},
    64  					"Range":              {""},
    65  				}),
    66  			},
    67  		},
    68  		// Test 404
    69  		{
    70  			Request: testutil.Request{
    71  				Method: "PATCH",
    72  				Route:  locationPath,
    73  				Body:   b,
    74  			},
    75  			Response: testutil.Response{
    76  				StatusCode: http.StatusNotFound,
    77  			},
    78  		},
    79  		// Test 400 valid json
    80  		{
    81  			Request: testutil.Request{
    82  				Method: "PATCH",
    83  				Route:  locationPath,
    84  				Body:   b,
    85  			},
    86  			Response: testutil.Response{
    87  				StatusCode: http.StatusBadRequest,
    88  				Headers:    http.Header{"Content-Type": []string{"application/json; charset=utf-8"}},
    89  				Body: []byte(`
    90  					{ "errors":
    91  						[
    92  							{
    93  								"code": "BLOB_UPLOAD_INVALID",
    94  								"message": "blob upload invalid",
    95  								"detail": "more detail"
    96  							}
    97  						]
    98  					} `),
    99  			},
   100  		},
   101  		// Test 400 invalid json
   102  		{
   103  			Request: testutil.Request{
   104  				Method: "PATCH",
   105  				Route:  locationPath,
   106  				Body:   b,
   107  			},
   108  			Response: testutil.Response{
   109  				StatusCode: http.StatusBadRequest,
   110  				Headers:    http.Header{"Content-Type": []string{"application/json"}},
   111  				Body:       []byte("something bad happened"),
   112  			},
   113  		},
   114  		// Test 500
   115  		{
   116  			Request: testutil.Request{
   117  				Method: "PATCH",
   118  				Route:  locationPath,
   119  				Body:   b,
   120  			},
   121  			Response: testutil.Response{
   122  				StatusCode: http.StatusInternalServerError,
   123  			},
   124  		},
   125  	})
   126  
   127  	e, c := testServer(m)
   128  	defer c()
   129  
   130  	blobUpload := &httpBlobUpload{
   131  		client: &http.Client{},
   132  	}
   133  
   134  	// Valid case
   135  	blobUpload.location = e + locationPath
   136  	n, err := blobUpload.ReadFrom(bytes.NewReader(b))
   137  	if err != nil {
   138  		t.Fatalf("Error calling ReadFrom: %s", err)
   139  	}
   140  	if n != 64 {
   141  		t.Fatalf("Wrong length returned from ReadFrom: %d, expected 64", n)
   142  	}
   143  
   144  	// Bad range
   145  	blobUpload.location = e + locationPath
   146  	_, err = blobUpload.ReadFrom(bytes.NewReader(b))
   147  	if err == nil {
   148  		t.Fatalf("Expected error when bad range received")
   149  	}
   150  
   151  	// 404
   152  	blobUpload.location = e + locationPath
   153  	_, err = blobUpload.ReadFrom(bytes.NewReader(b))
   154  	if err == nil {
   155  		t.Fatalf("Expected error when not found")
   156  	}
   157  	if err != distribution.ErrBlobUploadUnknown {
   158  		t.Fatalf("Wrong error thrown: %s, expected %s", err, distribution.ErrBlobUploadUnknown)
   159  	}
   160  
   161  	// 400 valid json
   162  	blobUpload.location = e + locationPath
   163  	_, err = blobUpload.ReadFrom(bytes.NewReader(b))
   164  	if err == nil {
   165  		t.Fatalf("Expected error when not found")
   166  	}
   167  	if uploadErr, ok := err.(errcode.Errors); !ok {
   168  		t.Fatalf("Wrong error type %T: %s", err, err)
   169  	} else if len(uploadErr) != 1 {
   170  		t.Fatalf("Unexpected number of errors: %d, expected 1", len(uploadErr))
   171  	} else {
   172  		v2Err, ok := uploadErr[0].(errcode.Error)
   173  		if !ok {
   174  			t.Fatalf("Not an 'Error' type: %#v", uploadErr[0])
   175  		}
   176  		if v2Err.Code != v2.ErrorCodeBlobUploadInvalid {
   177  			t.Fatalf("Unexpected error code: %s, expected %d", v2Err.Code.String(), v2.ErrorCodeBlobUploadInvalid)
   178  		}
   179  		if expected := "blob upload invalid"; v2Err.Message != expected {
   180  			t.Fatalf("Unexpected error message: %q, expected %q", v2Err.Message, expected)
   181  		}
   182  		if expected := "more detail"; v2Err.Detail.(string) != expected {
   183  			t.Fatalf("Unexpected error message: %q, expected %q", v2Err.Detail.(string), expected)
   184  		}
   185  	}
   186  
   187  	// 400 invalid json
   188  	blobUpload.location = e + locationPath
   189  	_, err = blobUpload.ReadFrom(bytes.NewReader(b))
   190  	if err == nil {
   191  		t.Fatalf("Expected error when not found")
   192  	}
   193  	if uploadErr, ok := err.(*UnexpectedHTTPResponseError); !ok {
   194  		t.Fatalf("Wrong error type %T: %s", err, err)
   195  	} else {
   196  		respStr := string(uploadErr.Response)
   197  		if expected := "something bad happened"; respStr != expected {
   198  			t.Fatalf("Unexpected response string: %s, expected: %s", respStr, expected)
   199  		}
   200  	}
   201  
   202  	// 500
   203  	blobUpload.location = e + locationPath
   204  	_, err = blobUpload.ReadFrom(bytes.NewReader(b))
   205  	if err == nil {
   206  		t.Fatalf("Expected error when not found")
   207  	}
   208  	if uploadErr, ok := err.(*UnexpectedHTTPStatusError); !ok {
   209  		t.Fatalf("Wrong error type %T: %s", err, err)
   210  	} else if expected := "500 " + http.StatusText(http.StatusInternalServerError); uploadErr.Status != expected {
   211  		t.Fatalf("Unexpected response status: %s, expected %s", uploadErr.Status, expected)
   212  	}
   213  }
   214  

View as plain text