github.com/christopherobin/docker@v1.6.2/registry/v2/errors_test.go (about) 1 package v2 2 3 import ( 4 "encoding/json" 5 "reflect" 6 "testing" 7 ) 8 9 // TestErrorCodes ensures that error code format, mappings and 10 // marshaling/unmarshaling. round trips are stable. 11 func TestErrorCodes(t *testing.T) { 12 for _, desc := range ErrorDescriptors { 13 if desc.Code.String() != desc.Value { 14 t.Fatalf("error code string incorrect: %q != %q", desc.Code.String(), desc.Value) 15 } 16 17 if desc.Code.Message() != desc.Message { 18 t.Fatalf("incorrect message for error code %v: %q != %q", desc.Code, desc.Code.Message(), desc.Message) 19 } 20 21 // Serialize the error code using the json library to ensure that we 22 // get a string and it works round trip. 23 p, err := json.Marshal(desc.Code) 24 25 if err != nil { 26 t.Fatalf("error marshaling error code %v: %v", desc.Code, err) 27 } 28 29 if len(p) <= 0 { 30 t.Fatalf("expected content in marshaled before for error code %v", desc.Code) 31 } 32 33 // First, unmarshal to interface and ensure we have a string. 34 var ecUnspecified interface{} 35 if err := json.Unmarshal(p, &ecUnspecified); err != nil { 36 t.Fatalf("error unmarshaling error code %v: %v", desc.Code, err) 37 } 38 39 if _, ok := ecUnspecified.(string); !ok { 40 t.Fatalf("expected a string for error code %v on unmarshal got a %T", desc.Code, ecUnspecified) 41 } 42 43 // Now, unmarshal with the error code type and ensure they are equal 44 var ecUnmarshaled ErrorCode 45 if err := json.Unmarshal(p, &ecUnmarshaled); err != nil { 46 t.Fatalf("error unmarshaling error code %v: %v", desc.Code, err) 47 } 48 49 if ecUnmarshaled != desc.Code { 50 t.Fatalf("unexpected error code during error code marshal/unmarshal: %v != %v", ecUnmarshaled, desc.Code) 51 } 52 } 53 } 54 55 // TestErrorsManagement does a quick check of the Errors type to ensure that 56 // members are properly pushed and marshaled. 57 func TestErrorsManagement(t *testing.T) { 58 var errs Errors 59 60 errs.Push(ErrorCodeDigestInvalid) 61 errs.Push(ErrorCodeBlobUnknown, 62 map[string]string{"digest": "sometestblobsumdoesntmatter"}) 63 64 p, err := json.Marshal(errs) 65 66 if err != nil { 67 t.Fatalf("error marashaling errors: %v", err) 68 } 69 70 expectedJSON := "{\"errors\":[{\"code\":\"DIGEST_INVALID\",\"message\":\"provided digest did not match uploaded content\"},{\"code\":\"BLOB_UNKNOWN\",\"message\":\"blob unknown to registry\",\"detail\":{\"digest\":\"sometestblobsumdoesntmatter\"}}]}" 71 72 if string(p) != expectedJSON { 73 t.Fatalf("unexpected json: %q != %q", string(p), expectedJSON) 74 } 75 76 errs.Clear() 77 errs.Push(ErrorCodeUnknown) 78 expectedJSON = "{\"errors\":[{\"code\":\"UNKNOWN\",\"message\":\"unknown error\"}]}" 79 p, err = json.Marshal(errs) 80 81 if err != nil { 82 t.Fatalf("error marashaling errors: %v", err) 83 } 84 85 if string(p) != expectedJSON { 86 t.Fatalf("unexpected json: %q != %q", string(p), expectedJSON) 87 } 88 } 89 90 // TestMarshalUnmarshal ensures that api errors can round trip through json 91 // without losing information. 92 func TestMarshalUnmarshal(t *testing.T) { 93 94 var errors Errors 95 96 for _, testcase := range []struct { 97 description string 98 err Error 99 }{ 100 { 101 description: "unknown error", 102 err: Error{ 103 104 Code: ErrorCodeUnknown, 105 Message: ErrorCodeUnknown.Descriptor().Message, 106 }, 107 }, 108 { 109 description: "unknown manifest", 110 err: Error{ 111 Code: ErrorCodeManifestUnknown, 112 Message: ErrorCodeManifestUnknown.Descriptor().Message, 113 }, 114 }, 115 { 116 description: "unknown manifest", 117 err: Error{ 118 Code: ErrorCodeBlobUnknown, 119 Message: ErrorCodeBlobUnknown.Descriptor().Message, 120 Detail: map[string]interface{}{"digest": "asdfqwerqwerqwerqwer"}, 121 }, 122 }, 123 } { 124 fatalf := func(format string, args ...interface{}) { 125 t.Fatalf(testcase.description+": "+format, args...) 126 } 127 128 unexpectedErr := func(err error) { 129 fatalf("unexpected error: %v", err) 130 } 131 132 p, err := json.Marshal(testcase.err) 133 if err != nil { 134 unexpectedErr(err) 135 } 136 137 var unmarshaled Error 138 if err := json.Unmarshal(p, &unmarshaled); err != nil { 139 unexpectedErr(err) 140 } 141 142 if !reflect.DeepEqual(unmarshaled, testcase.err) { 143 fatalf("errors not equal after round trip: %#v != %#v", unmarshaled, testcase.err) 144 } 145 146 // Roll everything up into an error response envelope. 147 errors.PushErr(testcase.err) 148 } 149 150 p, err := json.Marshal(errors) 151 if err != nil { 152 t.Fatalf("unexpected error marshaling error envelope: %v", err) 153 } 154 155 var unmarshaled Errors 156 if err := json.Unmarshal(p, &unmarshaled); err != nil { 157 t.Fatalf("unexpected error unmarshaling error envelope: %v", err) 158 } 159 160 if !reflect.DeepEqual(unmarshaled, errors) { 161 t.Fatalf("errors not equal after round trip: %#v != %#v", unmarshaled, errors) 162 } 163 }