github.com/davecgh/go-xdr@v0.0.0-20161123171359-e6a2ba005892/xdr/decode_test.go (about) 1 /* 2 * Copyright (c) 2012-2014 Dave Collins <dave@davec.name> 3 * 4 * Permission to use, copy, modify, and distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 package xdr 18 19 import ( 20 "fmt" 21 "math" 22 "reflect" 23 "testing" 24 "time" 25 ) 26 27 // subTest is used to allow testing of the Unmarshal function into struct fields 28 // which are structs themselves. 29 type subTest struct { 30 A string 31 B uint8 32 } 33 34 // allTypesTest is used to allow testing of the Unmarshal function into struct 35 // fields of all supported types. 36 type allTypesTest struct { 37 A int8 38 B uint8 39 C int16 40 D uint16 41 E int32 42 F uint32 43 G int64 44 H uint64 45 I bool 46 J float32 47 K float64 48 L string 49 M []byte 50 N [3]byte 51 O []int16 52 P [2]subTest 53 Q subTest 54 R map[string]uint32 55 S time.Time 56 } 57 58 // TestUnmarshal executes all of the tests described by unmarshalTests. 59 func TestUnmarshal(t *testing.T) { 60 // structTestIn is input data for the big struct test of all supported 61 // types. 62 structTestIn := []byte{ 63 0x00, 0x00, 0x00, 0x7F, // A 64 0x00, 0x00, 0x00, 0xFF, // B 65 0x00, 0x00, 0x7F, 0xFF, // C 66 0x00, 0x00, 0xFF, 0xFF, // D 67 0x7F, 0xFF, 0xFF, 0xFF, // E 68 0xFF, 0xFF, 0xFF, 0xFF, // F 69 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // G 70 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // H 71 0x00, 0x00, 0x00, 0x01, // I 72 0x40, 0x48, 0xF5, 0xC3, // J 73 0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18, // K 74 0x00, 0x00, 0x00, 0x03, 0x78, 0x64, 0x72, 0x00, // L 75 0x00, 0x00, 0x00, 0x04, 0x01, 0x02, 0x03, 0x04, // M 76 0x01, 0x02, 0x03, 0x00, // N 77 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 78 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, // O 79 0x00, 0x00, 0x00, 0x03, 0x6F, 0x6E, 0x65, 0x00, // P[0].A 80 0x00, 0x00, 0x00, 0x01, // P[0].B 81 0x00, 0x00, 0x00, 0x03, 0x74, 0x77, 0x6F, 0x00, // P[1].A 82 0x00, 0x00, 0x00, 0x02, // P[1].B 83 0x00, 0x00, 0x00, 0x03, 0x62, 0x61, 0x72, 0x00, // Q.A 84 0x00, 0x00, 0x00, 0x03, // Q.B 85 0x00, 0x00, 0x00, 0x02, // R length 86 0x00, 0x00, 0x00, 0x04, 0x6D, 0x61, 0x70, 0x31, // R key map1 87 0x00, 0x00, 0x00, 0x01, // R value map1 88 0x00, 0x00, 0x00, 0x04, 0x6D, 0x61, 0x70, 0x32, // R key map2 89 0x00, 0x00, 0x00, 0x02, // R value map2 90 0x00, 0x00, 0x00, 0x14, 0x32, 0x30, 0x31, 0x34, 91 0x2d, 0x30, 0x34, 0x2d, 0x30, 0x34, 0x54, 0x30, 92 0x33, 0x3a, 0x32, 0x34, 0x3a, 0x34, 0x38, 0x5a, // S 93 } 94 95 // structTestWant is the expected output after unmarshalling 96 // structTestIn. 97 structTestWant := allTypesTest{ 98 127, // A 99 255, // B 100 32767, // C 101 65535, // D 102 2147483647, // E 103 4294967295, // F 104 9223372036854775807, // G 105 18446744073709551615, // H 106 true, // I 107 3.14, // J 108 3.141592653589793, // K 109 "xdr", // L 110 []byte{1, 2, 3, 4}, // M 111 [3]byte{1, 2, 3}, // N 112 []int16{512, 1024, 2048}, // O 113 [2]subTest{{"one", 1}, {"two", 2}}, // P 114 subTest{"bar", 3}, // Q 115 map[string]uint32{"map1": 1, "map2": 2}, // R 116 time.Unix(1396581888, 0).UTC(), // S 117 } 118 119 tests := []struct { 120 in []byte 121 want interface{} 122 err error 123 }{ 124 // int8 - XDR Integer 125 {[]byte{0x00, 0x00, 0x00, 0x00}, int8(0), nil}, 126 {[]byte{0x00, 0x00, 0x00, 0x40}, int8(64), nil}, 127 {[]byte{0x00, 0x00, 0x00, 0x7F}, int8(127), nil}, 128 {[]byte{0xFF, 0xFF, 0xFF, 0xFF}, int8(-1), nil}, 129 {[]byte{0xFF, 0xFF, 0xFF, 0x80}, int8(-128), nil}, 130 // Expected Failures -- 128, -129 overflow int8 131 {[]byte{0x00, 0x00, 0x00, 0x80}, int8(0), &UnmarshalError{ErrorCode: ErrOverflow}}, 132 {[]byte{0xFF, 0xFF, 0xFF, 0x7F}, int8(0), &UnmarshalError{ErrorCode: ErrOverflow}}, 133 134 // uint8 - XDR Unsigned Integer 135 {[]byte{0x00, 0x00, 0x00, 0x00}, uint8(0), nil}, 136 {[]byte{0x00, 0x00, 0x00, 0x40}, uint8(64), nil}, 137 {[]byte{0x00, 0x00, 0x00, 0xFF}, uint8(255), nil}, 138 // Expected Failures -- 256, -1 overflow uint8 139 {[]byte{0x00, 0x00, 0x01, 0x00}, uint8(0), &UnmarshalError{ErrorCode: ErrOverflow}}, 140 {[]byte{0xFF, 0xFF, 0xFF, 0xFF}, uint8(0), &UnmarshalError{ErrorCode: ErrOverflow}}, 141 142 // int16 - XDR Integer 143 {[]byte{0x00, 0x00, 0x00, 0x00}, int16(0), nil}, 144 {[]byte{0x00, 0x00, 0x04, 0x00}, int16(1024), nil}, 145 {[]byte{0x00, 0x00, 0x7F, 0xFF}, int16(32767), nil}, 146 {[]byte{0xFF, 0xFF, 0xFF, 0xFF}, int16(-1), nil}, 147 {[]byte{0xFF, 0xFF, 0x80, 0x00}, int16(-32768), nil}, 148 // Expected Failures -- 32768, -32769 overflow int16 149 {[]byte{0x00, 0x00, 0x80, 0x00}, int16(0), &UnmarshalError{ErrorCode: ErrOverflow}}, 150 {[]byte{0xFF, 0xFF, 0x7F, 0xFF}, int16(0), &UnmarshalError{ErrorCode: ErrOverflow}}, 151 152 // uint16 - XDR Unsigned Integer 153 {[]byte{0x00, 0x00, 0x00, 0x00}, uint16(0), nil}, 154 {[]byte{0x00, 0x00, 0x04, 0x00}, uint16(1024), nil}, 155 {[]byte{0x00, 0x00, 0xFF, 0xFF}, uint16(65535), nil}, 156 // Expected Failures -- 65536, -1 overflow uint16 157 {[]byte{0x00, 0x01, 0x00, 0x00}, uint16(0), &UnmarshalError{ErrorCode: ErrOverflow}}, 158 {[]byte{0xFF, 0xFF, 0xFF, 0xFF}, uint16(0), &UnmarshalError{ErrorCode: ErrOverflow}}, 159 160 // int32 - XDR Integer 161 {[]byte{0x00, 0x00, 0x00, 0x00}, int32(0), nil}, 162 {[]byte{0x00, 0x04, 0x00, 0x00}, int32(262144), nil}, 163 {[]byte{0x7F, 0xFF, 0xFF, 0xFF}, int32(2147483647), nil}, 164 {[]byte{0xFF, 0xFF, 0xFF, 0xFF}, int32(-1), nil}, 165 {[]byte{0x80, 0x00, 0x00, 0x00}, int32(-2147483648), nil}, 166 167 // uint32 - XDR Unsigned Integer 168 {[]byte{0x00, 0x00, 0x00, 0x00}, uint32(0), nil}, 169 {[]byte{0x00, 0x04, 0x00, 0x00}, uint32(262144), nil}, 170 {[]byte{0xFF, 0xFF, 0xFF, 0xFF}, uint32(4294967295), nil}, 171 172 // int64 - XDR Hyper Integer 173 {[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, int64(0), nil}, 174 {[]byte{0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}, int64(1 << 34), nil}, 175 {[]byte{0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00}, int64(1 << 42), nil}, 176 {[]byte{0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, int64(9223372036854775807), nil}, 177 {[]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, int64(-1), nil}, 178 {[]byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, int64(-9223372036854775808), nil}, 179 180 // uint64 - XDR Unsigned Hyper Integer 181 {[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, uint64(0), nil}, 182 {[]byte{0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}, uint64(1 << 34), nil}, 183 {[]byte{0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00}, uint64(1 << 42), nil}, 184 {[]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, uint64(18446744073709551615), nil}, 185 {[]byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, uint64(9223372036854775808), nil}, 186 187 // bool - XDR Integer 188 {[]byte{0x00, 0x00, 0x00, 0x00}, false, nil}, 189 {[]byte{0x00, 0x00, 0x00, 0x01}, true, nil}, 190 // Expected Failures -- only 0 or 1 is a valid bool 191 {[]byte{0x01, 0x00, 0x00, 0x00}, true, &UnmarshalError{ErrorCode: ErrBadEnumValue}}, 192 {[]byte{0x00, 0x00, 0x40, 0x00}, true, &UnmarshalError{ErrorCode: ErrBadEnumValue}}, 193 194 // float32 - XDR Floating-Point 195 {[]byte{0x00, 0x00, 0x00, 0x00}, float32(0), nil}, 196 {[]byte{0x40, 0x48, 0xF5, 0xC3}, float32(3.14), nil}, 197 {[]byte{0x49, 0x96, 0xB4, 0x38}, float32(1234567.0), nil}, 198 {[]byte{0xFF, 0x80, 0x00, 0x00}, float32(math.Inf(-1)), nil}, 199 {[]byte{0x7F, 0x80, 0x00, 0x00}, float32(math.Inf(0)), nil}, 200 201 // float64 - XDR Double-precision Floating-Point 202 {[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, float64(0), nil}, 203 {[]byte{0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18}, float64(3.141592653589793), nil}, 204 {[]byte{0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, float64(math.Inf(-1)), nil}, 205 {[]byte{0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, float64(math.Inf(0)), nil}, 206 207 // string - XDR String 208 {[]byte{0x00, 0x00, 0x00, 0x00}, "", nil}, 209 {[]byte{0x00, 0x00, 0x00, 0x03, 0x78, 0x64, 0x72, 0x00}, "xdr", nil}, 210 {[]byte{0x00, 0x00, 0x00, 0x06, 0xCF, 0x84, 0x3D, 0x32, 0xCF, 0x80, 0x00, 0x00}, "τ=2π", nil}, 211 // Expected Failure -- String len 255 larger than available bytes 212 {[]byte{0x00, 0x00, 0x00, 0xFF}, "", &UnmarshalError{ErrorCode: ErrUnexpectedEnd}}, 213 214 // []byte - XDR Variable Opaque 215 {[]byte{0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00}, []byte{0x01}, nil}, 216 {[]byte{0x00, 0x00, 0x00, 0x03, 0x01, 0x02, 0x03, 0x00}, []byte{0x01, 0x02, 0x03}, nil}, 217 // Expected Failure -- 255 bytes of opaque data larger than available bytes 218 {[]byte{0x00, 0x00, 0x00, 0xFF}, []byte{}, &UnmarshalError{ErrorCode: ErrUnexpectedEnd}}, 219 220 // [#]byte - XDR Fixed Opaque 221 {[]byte{0x01, 0x00, 0x00, 0x00}, [1]byte{0x01}, nil}, 222 {[]byte{0x01, 0x02, 0x00, 0x00}, [2]byte{0x01, 0x02}, nil}, 223 {[]byte{0x01, 0x02, 0x03, 0x00}, [3]byte{0x01, 0x02, 0x03}, nil}, 224 {[]byte{0x01, 0x02, 0x03, 0x04}, [4]byte{0x01, 0x02, 0x03, 0x04}, nil}, 225 {[]byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x00, 0x00}, [5]byte{0x01, 0x02, 0x03, 0x04, 0x05}, nil}, 226 // Expected Failure -- fixed opaque data not padded 227 {[]byte{0x01}, [1]byte{}, &UnmarshalError{ErrorCode: ErrUnexpectedEnd}}, 228 229 // []<type> - XDR Variable-Length Array 230 {[]byte{0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00}, 231 []int16{512, 1024, 2048}, nil}, 232 {[]byte{0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00}, []bool{true, false}, nil}, 233 // Expected Failure -- 2 entries in array - not enough bytes 234 {[]byte{0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01}, []bool{}, &UnmarshalError{ErrorCode: ErrUnexpectedEnd}}, 235 236 // [#]<type> - XDR Fixed-Length Array 237 {[]byte{0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00}, [2]uint32{512, 1024}, nil}, 238 {[]byte{0x00, 0x00, 0x02, 0x00}, [2]uint32{}, &UnmarshalError{ErrorCode: ErrUnexpectedEnd}}, 239 240 // map[string]uint32 241 {[]byte{0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x6D, 0x61, 0x70, 0x31, 0x00, 0x00, 0x00, 0x01}, 242 map[string]uint32{"map1": 1}, nil}, 243 // Expected Failure -- 1 map element - not enough bytes 244 {[]byte{0x00, 0x00, 0x00, 0x01}, map[string]uint32{}, &UnmarshalError{ErrorCode: ErrUnexpectedEnd}}, 245 246 // time.Time - XDR String per RFC3339 247 {[]byte{ 248 0x00, 0x00, 0x00, 0x14, 0x32, 0x30, 0x31, 0x34, 249 0x2d, 0x30, 0x34, 0x2d, 0x30, 0x34, 0x54, 0x30, 250 0x33, 0x3a, 0x32, 0x34, 0x3a, 0x34, 0x38, 0x5a, 251 }, time.Unix(1396581888, 0).UTC(), nil}, 252 253 // struct - XDR Structure -- test struct contains all supported types 254 {structTestIn, structTestWant, nil}, 255 } 256 257 for i, test := range tests { 258 // Create a new pointer to the appropriate type 259 want := reflect.New(reflect.TypeOf(test.want)).Interface() 260 rest, err := Unmarshal(test.in, want) 261 if reflect.TypeOf(err) != reflect.TypeOf(test.err) { 262 t.Errorf("Unmarshal #%d failed to detect error - got: %v <%T> want: %T", 263 i, err, err, test.err) 264 continue 265 } 266 if rerr, ok := err.(*UnmarshalError); ok { 267 if terr, ok := test.err.(*UnmarshalError); ok { 268 if rerr.ErrorCode != terr.ErrorCode { 269 t.Errorf("Unmarshal #%d failed to detect error code - got: %v want: %v", 270 i, rerr.ErrorCode, terr.ErrorCode) 271 continue 272 } 273 // Got expected error. Move on to the next test. 274 continue 275 } 276 } 277 278 if len(rest) != 0 { 279 t.Errorf("Unmarshal #%d len got: %v want: %v\n", i, len(rest), 0) 280 continue 281 } 282 wantElem := reflect.Indirect(reflect.ValueOf(want)).Interface() 283 if !reflect.DeepEqual(wantElem, test.want) { 284 t.Errorf("Unmarshal #%d got: %v want: %v\n", i, wantElem, test.want) 285 continue 286 } 287 } 288 } 289 290 // decodeFunc is used to identify which public function of the Decoder object 291 // a test applies to. 292 type decodeFunc int 293 294 const ( 295 fDecodeBool decodeFunc = iota 296 fDecodeDouble 297 fDecodeEnum 298 fDecodeFixedOpaque 299 fDecodeFloat 300 fDecodeHyper 301 fDecodeInt 302 fDecodeOpaque 303 fDecodeString 304 fDecodeUhyper 305 fDecodeUint 306 ) 307 308 // Map of decodeFunc values to names for pretty printing. 309 var decodeFuncStrings = map[decodeFunc]string{ 310 fDecodeBool: "DecodeBool", 311 fDecodeDouble: "DecodeDouble", 312 fDecodeEnum: "DecodeEnum", 313 fDecodeFixedOpaque: "DecodeFixedOpaque", 314 fDecodeFloat: "DecodeFloat", 315 fDecodeHyper: "DecodeHyper", 316 fDecodeInt: "DecodeInt", 317 fDecodeOpaque: "DecodeOpaque", 318 fDecodeString: "DecodeString", 319 fDecodeUhyper: "DecodeUhyper", 320 fDecodeUint: "DecodeUint", 321 } 322 323 func (f decodeFunc) String() string { 324 if s := decodeFuncStrings[f]; s != "" { 325 return s 326 } 327 return fmt.Sprintf("Unknown decodeFunc (%d)", f) 328 } 329 330 // TestDecoder executes all of the tests described by decodeTests. 331 func TestDecoder(t *testing.T) { 332 tests := []struct { 333 f decodeFunc 334 in []byte 335 want interface{} 336 err error 337 }{ 338 // Bool 339 {fDecodeBool, []byte{0x00, 0x00, 0x00, 0x00}, false, nil}, 340 {fDecodeBool, []byte{0x00, 0x00, 0x00, 0x01}, true, nil}, 341 // Expected Failures -- only 0 or 1 is a valid bool 342 {fDecodeBool, []byte{0x01, 0x00, 0x00, 0x00}, true, &UnmarshalError{ErrorCode: ErrBadEnumValue}}, 343 {fDecodeBool, []byte{0x00, 0x00, 0x40, 0x00}, true, &UnmarshalError{ErrorCode: ErrBadEnumValue}}, 344 345 // Double 346 {fDecodeDouble, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, float64(0), nil}, 347 {fDecodeDouble, []byte{0x40, 0x09, 0x21, 0xfb, 0x54, 0x44, 0x2d, 0x18}, float64(3.141592653589793), nil}, 348 {fDecodeDouble, []byte{0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, float64(math.Inf(-1)), nil}, 349 {fDecodeDouble, []byte{0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, float64(math.Inf(0)), nil}, 350 351 // Enum 352 {fDecodeEnum, []byte{0x00, 0x00, 0x00, 0x00}, int32(0), nil}, 353 {fDecodeEnum, []byte{0x00, 0x00, 0x00, 0x01}, int32(1), nil}, 354 {fDecodeEnum, []byte{0x00, 0x00, 0x00, 0x02}, nil, &UnmarshalError{ErrorCode: ErrBadEnumValue}}, 355 {fDecodeEnum, []byte{0x12, 0x34, 0x56, 0x78}, nil, &UnmarshalError{ErrorCode: ErrBadEnumValue}}, 356 357 // FixedOpaque 358 {fDecodeFixedOpaque, []byte{0x01, 0x00, 0x00, 0x00}, []byte{0x01}, nil}, 359 {fDecodeFixedOpaque, []byte{0x01, 0x02, 0x00, 0x00}, []byte{0x01, 0x02}, nil}, 360 {fDecodeFixedOpaque, []byte{0x01, 0x02, 0x03, 0x00}, []byte{0x01, 0x02, 0x03}, nil}, 361 {fDecodeFixedOpaque, []byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}, nil}, 362 {fDecodeFixedOpaque, []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x00, 0x00}, []byte{0x01, 0x02, 0x03, 0x04, 0x05}, nil}, 363 // Expected Failure -- fixed opaque data not padded 364 {fDecodeFixedOpaque, []byte{0x01}, []byte{0x00}, &UnmarshalError{ErrorCode: ErrUnexpectedEnd}}, 365 366 // Float 367 {fDecodeFloat, []byte{0x00, 0x00, 0x00, 0x00}, float32(0), nil}, 368 {fDecodeFloat, []byte{0x40, 0x48, 0xF5, 0xC3}, float32(3.14), nil}, 369 {fDecodeFloat, []byte{0x49, 0x96, 0xB4, 0x38}, float32(1234567.0), nil}, 370 {fDecodeFloat, []byte{0xFF, 0x80, 0x00, 0x00}, float32(math.Inf(-1)), nil}, 371 {fDecodeFloat, []byte{0x7F, 0x80, 0x00, 0x00}, float32(math.Inf(0)), nil}, 372 373 // Hyper 374 {fDecodeHyper, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, int64(0), nil}, 375 {fDecodeHyper, []byte{0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}, int64(1 << 34), nil}, 376 {fDecodeHyper, []byte{0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00}, int64(1 << 42), nil}, 377 {fDecodeHyper, []byte{0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, int64(9223372036854775807), nil}, 378 {fDecodeHyper, []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, int64(-1), nil}, 379 {fDecodeHyper, []byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, int64(-9223372036854775808), nil}, 380 381 // Int 382 {fDecodeInt, []byte{0x00, 0x00, 0x00, 0x00}, int32(0), nil}, 383 {fDecodeInt, []byte{0x00, 0x04, 0x00, 0x00}, int32(262144), nil}, 384 {fDecodeInt, []byte{0x7F, 0xFF, 0xFF, 0xFF}, int32(2147483647), nil}, 385 {fDecodeInt, []byte{0xFF, 0xFF, 0xFF, 0xFF}, int32(-1), nil}, 386 {fDecodeInt, []byte{0x80, 0x00, 0x00, 0x00}, int32(-2147483648), nil}, 387 388 // Opaque 389 {fDecodeOpaque, []byte{0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00}, []byte{0x01}, nil}, 390 {fDecodeOpaque, []byte{0x00, 0x00, 0x00, 0x03, 0x01, 0x02, 0x03, 0x00}, []byte{0x01, 0x02, 0x03}, nil}, 391 // Expected Failure -- 255 bytes of opaque data larger than available bytes 392 {fDecodeOpaque, []byte{0x00, 0x00, 0x00, 0xFF}, []byte{}, &UnmarshalError{ErrorCode: ErrUnexpectedEnd}}, 393 394 // String 395 {fDecodeString, []byte{0x00, 0x00, 0x00, 0x00}, "", nil}, 396 {fDecodeString, []byte{0x00, 0x00, 0x00, 0x03, 0x78, 0x64, 0x72, 0x00}, "xdr", nil}, 397 {fDecodeString, []byte{0x00, 0x00, 0x00, 0x06, 0xCF, 0x84, 0x3D, 0x32, 0xCF, 0x80, 0x00, 0x00}, "τ=2π", nil}, 398 // Expected Failure -- String len 255 larger than available bytes 399 {fDecodeString, []byte{0x00, 0x00, 0x00, 0xFF}, "", &UnmarshalError{ErrorCode: ErrUnexpectedEnd}}, 400 401 // Uhyper 402 {fDecodeUhyper, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, uint64(0), nil}, 403 {fDecodeUhyper, []byte{0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00}, uint64(1 << 34), nil}, 404 {fDecodeUhyper, []byte{0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00}, uint64(1 << 42), nil}, 405 {fDecodeUhyper, []byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, uint64(18446744073709551615), nil}, 406 {fDecodeUhyper, []byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, uint64(9223372036854775808), nil}, 407 408 // Uint 409 {fDecodeUint, []byte{0x00, 0x00, 0x00, 0x00}, uint32(0), nil}, 410 {fDecodeUint, []byte{0x00, 0x04, 0x00, 0x00}, uint32(262144), nil}, 411 {fDecodeUint, []byte{0xFF, 0xFF, 0xFF, 0xFF}, uint32(4294967295), nil}, 412 } 413 414 validEnums := make(map[int32]bool) 415 validEnums[0] = true 416 validEnums[1] = true 417 418 var rv interface{} 419 var err error 420 421 for i, test := range tests { 422 err = nil 423 dec := NewDecoder(test.in) 424 switch test.f { 425 case fDecodeBool: 426 rv, err = dec.DecodeBool() 427 case fDecodeDouble: 428 rv, err = dec.DecodeDouble() 429 case fDecodeEnum: 430 rv, err = dec.DecodeEnum(validEnums) 431 case fDecodeFixedOpaque: 432 want := test.want.([]byte) 433 rv, err = dec.DecodeFixedOpaque(int32(len(want))) 434 case fDecodeFloat: 435 rv, err = dec.DecodeFloat() 436 case fDecodeHyper: 437 rv, err = dec.DecodeHyper() 438 case fDecodeInt: 439 rv, err = dec.DecodeInt() 440 case fDecodeOpaque: 441 rv, err = dec.DecodeOpaque() 442 case fDecodeString: 443 rv, err = dec.DecodeString() 444 case fDecodeUhyper: 445 rv, err = dec.DecodeUhyper() 446 case fDecodeUint: 447 rv, err = dec.DecodeUint() 448 default: 449 t.Errorf("%v #%d unrecognized function", test.f, i) 450 continue 451 } 452 if reflect.TypeOf(err) != reflect.TypeOf(test.err) { 453 t.Errorf("%v #%d failed to detect error - got: %v <%T> want: %T", 454 test.f, i, err, err, test.err) 455 continue 456 } 457 if rerr, ok := err.(*UnmarshalError); ok { 458 if terr, ok := test.err.(*UnmarshalError); ok { 459 if rerr.ErrorCode != terr.ErrorCode { 460 t.Errorf("%v #%d failed to detect error code - got: %v want: %v", 461 test.f, i, rerr.ErrorCode, terr.ErrorCode) 462 continue 463 } 464 // Got expected error. Move on to the next test. 465 continue 466 } 467 } 468 469 if !reflect.DeepEqual(rv, test.want) { 470 t.Errorf("%v #%d got: %v want: %v\n", test.f, i, rv, test.want) 471 continue 472 } 473 } 474 }