...

Source file src/github.com/docker/distribution/registry/api/errcode/errors_test.go

Documentation: github.com/docker/distribution/registry/api/errcode

     1  package errcode
     2  
     3  import (
     4  	"encoding/json"
     5  	"net/http"
     6  	"reflect"
     7  	"strings"
     8  	"testing"
     9  )
    10  
    11  // TestErrorsManagement does a quick check of the Errors type to ensure that
    12  // members are properly pushed and marshaled.
    13  var ErrorCodeTest1 = Register("test.errors", ErrorDescriptor{
    14  	Value:          "TEST1",
    15  	Message:        "test error 1",
    16  	Description:    `Just a test message #1.`,
    17  	HTTPStatusCode: http.StatusInternalServerError,
    18  })
    19  
    20  var ErrorCodeTest2 = Register("test.errors", ErrorDescriptor{
    21  	Value:          "TEST2",
    22  	Message:        "test error 2",
    23  	Description:    `Just a test message #2.`,
    24  	HTTPStatusCode: http.StatusNotFound,
    25  })
    26  
    27  var ErrorCodeTest3 = Register("test.errors", ErrorDescriptor{
    28  	Value:          "TEST3",
    29  	Message:        "Sorry %q isn't valid",
    30  	Description:    `Just a test message #3.`,
    31  	HTTPStatusCode: http.StatusNotFound,
    32  })
    33  
    34  // TestErrorCodes ensures that error code format, mappings and
    35  // marshaling/unmarshaling. round trips are stable.
    36  func TestErrorCodes(t *testing.T) {
    37  	if len(errorCodeToDescriptors) == 0 {
    38  		t.Fatal("errors aren't loaded!")
    39  	}
    40  
    41  	for ec, desc := range errorCodeToDescriptors {
    42  		if ec != desc.Code {
    43  			t.Fatalf("error code in descriptor isn't correct, %q != %q", ec, desc.Code)
    44  		}
    45  
    46  		if idToDescriptors[desc.Value].Code != ec {
    47  			t.Fatalf("error code in idToDesc isn't correct, %q != %q", idToDescriptors[desc.Value].Code, ec)
    48  		}
    49  
    50  		if ec.Message() != desc.Message {
    51  			t.Fatalf("ec.Message doesn't mtach desc.Message: %q != %q", ec.Message(), desc.Message)
    52  		}
    53  
    54  		// Test (de)serializing the ErrorCode
    55  		p, err := json.Marshal(ec)
    56  		if err != nil {
    57  			t.Fatalf("couldn't marshal ec %v: %v", ec, err)
    58  		}
    59  
    60  		if len(p) <= 0 {
    61  			t.Fatalf("expected content in marshaled before for error code %v", ec)
    62  		}
    63  
    64  		// First, unmarshal to interface and ensure we have a string.
    65  		var ecUnspecified interface{}
    66  		if err := json.Unmarshal(p, &ecUnspecified); err != nil {
    67  			t.Fatalf("error unmarshaling error code %v: %v", ec, err)
    68  		}
    69  
    70  		if _, ok := ecUnspecified.(string); !ok {
    71  			t.Fatalf("expected a string for error code %v on unmarshal got a %T", ec, ecUnspecified)
    72  		}
    73  
    74  		// Now, unmarshal with the error code type and ensure they are equal
    75  		var ecUnmarshaled ErrorCode
    76  		if err := json.Unmarshal(p, &ecUnmarshaled); err != nil {
    77  			t.Fatalf("error unmarshaling error code %v: %v", ec, err)
    78  		}
    79  
    80  		if ecUnmarshaled != ec {
    81  			t.Fatalf("unexpected error code during error code marshal/unmarshal: %v != %v", ecUnmarshaled, ec)
    82  		}
    83  
    84  		expectedErrorString := strings.ToLower(strings.Replace(ec.Descriptor().Value, "_", " ", -1))
    85  		if ec.Error() != expectedErrorString {
    86  			t.Fatalf("unexpected return from %v.Error(): %q != %q", ec, ec.Error(), expectedErrorString)
    87  		}
    88  	}
    89  
    90  }
    91  
    92  func TestErrorsManagement(t *testing.T) {
    93  	var errs Errors
    94  
    95  	errs = append(errs, ErrorCodeTest1)
    96  	errs = append(errs, ErrorCodeTest2.WithDetail(
    97  		map[string]interface{}{"digest": "sometestblobsumdoesntmatter"}))
    98  	errs = append(errs, ErrorCodeTest3.WithArgs("BOOGIE"))
    99  	errs = append(errs, ErrorCodeTest3.WithArgs("BOOGIE").WithDetail("data"))
   100  
   101  	p, err := json.Marshal(errs)
   102  
   103  	if err != nil {
   104  		t.Fatalf("error marashaling errors: %v", err)
   105  	}
   106  
   107  	expectedJSON := `{"errors":[` +
   108  		`{"code":"TEST1","message":"test error 1"},` +
   109  		`{"code":"TEST2","message":"test error 2","detail":{"digest":"sometestblobsumdoesntmatter"}},` +
   110  		`{"code":"TEST3","message":"Sorry \"BOOGIE\" isn't valid"},` +
   111  		`{"code":"TEST3","message":"Sorry \"BOOGIE\" isn't valid","detail":"data"}` +
   112  		`]}`
   113  
   114  	if string(p) != expectedJSON {
   115  		t.Fatalf("unexpected json:\ngot:\n%q\n\nexpected:\n%q", string(p), expectedJSON)
   116  	}
   117  
   118  	// Now test the reverse
   119  	var unmarshaled Errors
   120  	if err := json.Unmarshal(p, &unmarshaled); err != nil {
   121  		t.Fatalf("unexpected error unmarshaling error envelope: %v", err)
   122  	}
   123  
   124  	if !reflect.DeepEqual(unmarshaled, errs) {
   125  		t.Fatalf("errors not equal after round trip:\nunmarshaled:\n%#v\n\nerrs:\n%#v", unmarshaled, errs)
   126  	}
   127  
   128  	// Test the arg substitution stuff
   129  	e1 := unmarshaled[3].(Error)
   130  	exp1 := `Sorry "BOOGIE" isn't valid`
   131  	if e1.Message != exp1 {
   132  		t.Fatalf("Wrong msg, got:\n%q\n\nexpected:\n%q", e1.Message, exp1)
   133  	}
   134  
   135  	exp1 = "test3: " + exp1
   136  	if e1.Error() != exp1 {
   137  		t.Fatalf("Error() didn't return the right string, got:%s\nexpected:%s", e1.Error(), exp1)
   138  	}
   139  
   140  	// Test again with a single value this time
   141  	errs = Errors{ErrorCodeUnknown}
   142  	expectedJSON = "{\"errors\":[{\"code\":\"UNKNOWN\",\"message\":\"unknown error\"}]}"
   143  	p, err = json.Marshal(errs)
   144  
   145  	if err != nil {
   146  		t.Fatalf("error marashaling errors: %v", err)
   147  	}
   148  
   149  	if string(p) != expectedJSON {
   150  		t.Fatalf("unexpected json: %q != %q", string(p), expectedJSON)
   151  	}
   152  
   153  	// Now test the reverse
   154  	unmarshaled = nil
   155  	if err := json.Unmarshal(p, &unmarshaled); err != nil {
   156  		t.Fatalf("unexpected error unmarshaling error envelope: %v", err)
   157  	}
   158  
   159  	if !reflect.DeepEqual(unmarshaled, errs) {
   160  		t.Fatalf("errors not equal after round trip:\nunmarshaled:\n%#v\n\nerrs:\n%#v", unmarshaled, errs)
   161  	}
   162  
   163  	// Verify that calling WithArgs() more than once does the right thing.
   164  	// Meaning creates a new Error and uses the ErrorCode Message
   165  	e1 = ErrorCodeTest3.WithArgs("test1")
   166  	e2 := e1.WithArgs("test2")
   167  	if &e1 == &e2 {
   168  		t.Fatalf("args: e2 and e1 should not be the same, but they are")
   169  	}
   170  	if e2.Message != `Sorry "test2" isn't valid` {
   171  		t.Fatalf("e2 had wrong message: %q", e2.Message)
   172  	}
   173  
   174  	// Verify that calling WithDetail() more than once does the right thing.
   175  	// Meaning creates a new Error and overwrites the old detail field
   176  	e1 = ErrorCodeTest3.WithDetail("stuff1")
   177  	e2 = e1.WithDetail("stuff2")
   178  	if &e1 == &e2 {
   179  		t.Fatalf("detail: e2 and e1 should not be the same, but they are")
   180  	}
   181  	if e2.Detail != `stuff2` {
   182  		t.Fatalf("e2 had wrong detail: %q", e2.Detail)
   183  	}
   184  
   185  }
   186  

View as plain text