OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 package tests |
| 6 |
| 7 import ( |
| 8 "reflect" |
| 9 "testing" |
| 10 |
| 11 "mojo/public/interfaces/bindings/mojom_types" |
| 12 "mojo/public/interfaces/bindings/service_describer" |
| 13 "mojo/public/interfaces/bindings/tests/test_included_unions" |
| 14 "mojo/public/interfaces/bindings/tests/test_unions" |
| 15 test "mojo/public/interfaces/bindings/tests/validation_test_interfaces" |
| 16 ) |
| 17 |
| 18 var test_descriptor map[string]mojom_types.UserDefinedType |
| 19 var test_unions_descriptor map[string]mojom_types.UserDefinedType |
| 20 |
| 21 func init() { |
| 22 test_descriptor = test.GetAllMojomTypeDefinitions() |
| 23 test_unions_descriptor = test_unions.GetAllMojomTypeDefinitions() |
| 24 } |
| 25 |
| 26 // Perform a sanity check where we examine an MojomEnum's contents for correctne
ss. |
| 27 func TestEnumType(t *testing.T) { |
| 28 enumID := test.ID_validation_test_interfaces_BasicEnum__ |
| 29 shortName := "BasicEnum" |
| 30 labelMap := map[string]int32{ |
| 31 "A": 0, |
| 32 "B": 1, |
| 33 "C": 0, |
| 34 "D": -3, |
| 35 "E": 0xA, |
| 36 } |
| 37 |
| 38 // Extract *UserDefinedType from the validation test's Descriptor using
enumID. |
| 39 udt := test_descriptor[enumID] |
| 40 if udt == nil { |
| 41 t.Fatalf("Descriptor did not contain %s", enumID) |
| 42 } |
| 43 |
| 44 // The *UserDefinedType must be a *UserDefinedTypeEnumType. |
| 45 udet, ok := udt.(*mojom_types.UserDefinedTypeEnumType) |
| 46 if !ok { |
| 47 t.Fatalf("*UserDefinedType for %s was not *UserDefinedTypeEnumTy
pe", enumID) |
| 48 } |
| 49 |
| 50 // The UserDefinedTypeEnumType has a MojomEnum inside. |
| 51 me := udet.Value |
| 52 |
| 53 // Check that the generator produced the short name. |
| 54 if me.DeclData == nil || me.DeclData.ShortName == nil { |
| 55 t.Fatalf("Declaration Data's ShortName for %s is missing", enumI
D) |
| 56 } |
| 57 if *me.DeclData.ShortName != shortName { |
| 58 t.Fatalf("Declaration Data's ShortName for %s was not %s", enumI
D, shortName) |
| 59 } |
| 60 |
| 61 // Verify that the number of entries matches the expected ones. |
| 62 if got, expected := len(me.Values), len(labelMap); got != expected { |
| 63 t.Fatalf("MojomEnum for %s had %d labels, but expected %d", enum
ID, got, expected) |
| 64 } |
| 65 |
| 66 // Go through each entry, verify type info and that the enum label match
es the expected one. |
| 67 for _, label := range me.Values { |
| 68 // label is an EnumValue. |
| 69 // Check that the generator produced the field's short name. |
| 70 if label.DeclData == nil || label.DeclData.ShortName == nil { |
| 71 t.Fatalf("Declaration Data's ShortName for %s's label is
missing", enumID) |
| 72 } |
| 73 if _, ok := labelMap[*label.DeclData.ShortName]; !ok { |
| 74 t.Fatalf("Declaration Data's ShortName for %s's label %s
is unknown ", enumID, *label.DeclData.ShortName) |
| 75 } |
| 76 // label's EnumTypeKey must be correct. |
| 77 if label.EnumTypeKey != enumID { |
| 78 t.Fatalf("EnumTypeKey for Enum %s's label %s had wrong i
dentifier %s", enumID, |
| 79 *label.DeclData.ShortName, label.EnumTypeKey) |
| 80 } |
| 81 |
| 82 // Check that the label's IntValue matches the expected one. |
| 83 if expectedOrdinal := labelMap[*label.DeclData.ShortName]; label
.IntValue != expectedOrdinal { |
| 84 t.Fatalf("IntValue for Enum %s's label %s was %d but exp
ected %d", |
| 85 enumID, *label.DeclData.ShortName, label.IntValu
e, expectedOrdinal) |
| 86 } |
| 87 } |
| 88 } |
| 89 |
| 90 // Perform a sanity check where we examine a MojomStruct's contents for correctn
ess. |
| 91 func TestStructType(t *testing.T) { |
| 92 structID := test.ID_validation_test_interfaces_StructE__ |
| 93 shortName := "StructE" |
| 94 fields := map[int]string{ |
| 95 0: "StructD", |
| 96 1: "DataPipeConsumer", |
| 97 } |
| 98 |
| 99 // Extract *UserDefinedType from the validation test's Descriptor using
structID. |
| 100 udt := test_descriptor[structID] |
| 101 if udt == nil { |
| 102 t.Fatalf("Descriptor did not contain %s", structID) |
| 103 } |
| 104 |
| 105 // The *UserDefinedType must be a *UserDefinedTypeStructType. |
| 106 udst, ok := udt.(*mojom_types.UserDefinedTypeStructType) |
| 107 if !ok { |
| 108 t.Fatalf("*UserDefinedType for %s was not *UserDefinedTypeStruct
Type", structID) |
| 109 } |
| 110 |
| 111 // The UserDefinedTypeStructType has a MojomStruct inside. |
| 112 ms := udst.Value |
| 113 |
| 114 // Check that the generator produced the short name. |
| 115 if ms.DeclData == nil || ms.DeclData.ShortName == nil { |
| 116 t.Fatalf("Declaration Data's ShortName for %s is missing", struc
tID) |
| 117 } |
| 118 if *ms.DeclData.ShortName != shortName { |
| 119 t.Fatalf("Declaration Data's ShortName for %s was not %s", struc
tID, shortName) |
| 120 } |
| 121 |
| 122 // Verify that the number of fields matches the expected ones. |
| 123 if got, expected := len(ms.Fields), len(fields); got != expected { |
| 124 t.Fatalf("MojomStruct for %s had %d fields, but expected %d", st
ructID, got, expected) |
| 125 } |
| 126 |
| 127 // Go through each StructField, checking DeclData and the Type of each f
ield. |
| 128 // Note that since ms.Fields is a slice, the "ordinal" is the index. |
| 129 for i, field := range ms.Fields { |
| 130 expectedFieldShortName := fields[i] |
| 131 // Check that the ShortName is correct. |
| 132 if field.DeclData == nil || field.DeclData.ShortName == nil || *
field.DeclData.ShortName != expectedFieldShortName { |
| 133 t.Fatalf("StructField for %s at ordinal %d did not have
ShortName %s", structID, i, expectedFieldShortName) |
| 134 } |
| 135 |
| 136 // Special case each field since we know what's inside. |
| 137 switch i { |
| 138 case 0: |
| 139 ttr, ok := field.Type.(*mojom_types.TypeTypeReference) |
| 140 if !ok { |
| 141 t.Fatalf("StructField %s's field 0 didn't have T
ype *TypeTypeReference", structID) |
| 142 } |
| 143 |
| 144 // TypeTypeReference.Value is a TypeReference |
| 145 expectedReferenceID := test.ID_validation_test_interface
s_StructD__ |
| 146 if *ttr.Value.Identifier != expectedReferenceID { |
| 147 t.Fatalf("TypeReference Identifier got %s, but e
xpected %s", *ttr.Value.Identifier, expectedReferenceID) |
| 148 } |
| 149 if *ttr.Value.TypeKey != expectedReferenceID { |
| 150 t.Fatalf("TypeReference TypeKey got %s, but expe
cted %s", *ttr.Value.TypeKey, expectedReferenceID) |
| 151 } |
| 152 case 1: |
| 153 tht, ok := field.Type.(*mojom_types.TypeHandleType) |
| 154 if !ok { |
| 155 t.Fatalf("StructField %s's field 1 didn't have T
ype *TypeHandleType", structID) |
| 156 } |
| 157 |
| 158 // TypeHandleType.Value is a HandleType |
| 159 if tht.Value.Nullable { |
| 160 t.Fatalf("StructField %s's field 1 should have a
non-nullable TypeHandle", structID) |
| 161 } |
| 162 if tht.Value.Kind != mojom_types.HandleType_Kind_DataPip
eConsumer { |
| 163 t.Fatalf("StructField %s's field 1 has the wrong
kind", structID) |
| 164 } |
| 165 default: |
| 166 t.Fatalf("There should not be a field %d for MojomStruct
%s", i, structID) |
| 167 } |
| 168 } |
| 169 } |
| 170 |
| 171 // Perform a sanity check where we examine a MojomUnion's contents for correctne
ss. |
| 172 func TestUnionType(t *testing.T) { |
| 173 unionID := test.ID_validation_test_interfaces_UnionB__ |
| 174 shortName := "UnionB" |
| 175 fields := map[int]string{ |
| 176 0: "A", |
| 177 1: "B", |
| 178 2: "C", |
| 179 3: "D", |
| 180 } |
| 181 |
| 182 // Extract *UserDefinedType from the validation test's Descriptor using
unionID. |
| 183 udt := test_descriptor[unionID] |
| 184 if udt == nil { |
| 185 t.Fatalf("Descriptor did not contain %s", unionID) |
| 186 } |
| 187 |
| 188 // The *UserDefinedType must be a *UserDefinedTypeUnionType. |
| 189 udut, ok := udt.(*mojom_types.UserDefinedTypeUnionType) |
| 190 if !ok { |
| 191 t.Fatalf("*UserDefinedType for %s was not *UserDefinedTypeUnionT
ype", unionID) |
| 192 } |
| 193 |
| 194 // The UserDefinedTypeUnionType has a MojomUnion inside. |
| 195 mu := udut.Value |
| 196 |
| 197 // Check that the generator produced the short name. |
| 198 if mu.DeclData == nil || mu.DeclData.ShortName == nil { |
| 199 t.Fatalf("Declaration Data's ShortName for %s was missing", unio
nID) |
| 200 } |
| 201 if *mu.DeclData.ShortName != shortName { |
| 202 t.Fatalf("Declaration Data's ShortName for %s was not %s", union
ID, shortName) |
| 203 } |
| 204 |
| 205 // Verify that the number of fields matches the expected ones. |
| 206 if got, expected := len(mu.Fields), len(fields); got != expected { |
| 207 t.Fatalf("MojomUnion for %s had %d fields, but expected %d", uni
onID, got, expected) |
| 208 } |
| 209 |
| 210 // Go through each UnionField, checking DeclData and the Type of each fi
eld. |
| 211 // Note that UnionField's rely on their Tag to determine their ordinal. |
| 212 // It is NOT in definition order, like with MojomStruct's. |
| 213 for _, field := range mu.Fields { |
| 214 ordinal := field.Tag |
| 215 expectedFieldShortName := fields[int(ordinal)] |
| 216 // Check that the ShortName is correct. |
| 217 if field.DeclData == nil || field.DeclData.ShortName == nil || *
field.DeclData.ShortName != expectedFieldShortName { |
| 218 t.Fatalf("UnionField for %s at ordinal %d did not have S
hortName %s", unionID, ordinal, expectedFieldShortName) |
| 219 } |
| 220 |
| 221 // It turns out that regardless of field ordinal, this union has
TypeSimpleType for the type. |
| 222 tst, ok := field.Type.(*mojom_types.TypeSimpleType) |
| 223 if !ok { |
| 224 t.Fatalf("UnionField %s's field %d didn't have Type *Typ
eSimpleType", unionID, ordinal) |
| 225 } |
| 226 |
| 227 // Special case each field since we know what's inside. |
| 228 switch ordinal { |
| 229 case 0: |
| 230 if tst.Value != mojom_types.SimpleType_UinT16 { |
| 231 t.Fatalf("UnionField %s's field %d's Type value
was not SimpleType_UinT16", unionID, ordinal) |
| 232 } |
| 233 case 1: |
| 234 case 3: |
| 235 if tst.Value != mojom_types.SimpleType_UinT32 { |
| 236 t.Fatalf("UnionField %s's field %d's Type value
was not SimpleType_UinT32", unionID, ordinal) |
| 237 } |
| 238 case 2: |
| 239 if tst.Value != mojom_types.SimpleType_UinT64 { |
| 240 t.Fatalf("UnionField %s's field %d's Type value
was not SimpleType_UinT64", unionID, ordinal) |
| 241 } |
| 242 default: |
| 243 t.Fatalf("There should not be a field Tag %d for MojomSt
ruct %s", ordinal, unionID) |
| 244 } |
| 245 } |
| 246 } |
| 247 |
| 248 // Perform a sanity check for a struct that imports a union from another file. |
| 249 // The descriptor should still handle it. |
| 250 func TestStructWithImportType(t *testing.T) { |
| 251 structID := test_unions.ID_test_unions_IncludingStruct__ |
| 252 shortName := "IncludingStruct" |
| 253 fields := map[int]string{ |
| 254 0: "A", |
| 255 } |
| 256 |
| 257 // Extract *UserDefinedType from the validation test's Descriptor using
structID. |
| 258 udt := test_unions_descriptor[structID] |
| 259 if udt == nil { |
| 260 t.Fatalf("Descriptor did not contain %s", structID) |
| 261 } |
| 262 |
| 263 // The *UserDefinedType must be a *UserDefinedTypeStructType. |
| 264 udst, ok := udt.(*mojom_types.UserDefinedTypeStructType) |
| 265 if !ok { |
| 266 t.Fatalf("*UserDefinedType for %s was not *UserDefinedTypeStruct
Type", structID) |
| 267 } |
| 268 |
| 269 // The UserDefinedTypeStructType has a MojomStruct inside. |
| 270 ms := udst.Value |
| 271 |
| 272 // Check that the generator produced the short name. |
| 273 if ms.DeclData == nil || ms.DeclData.ShortName == nil { |
| 274 t.Fatalf("Declaration Data's ShortName for %s is missing", struc
tID) |
| 275 } |
| 276 if *ms.DeclData.ShortName != shortName { |
| 277 t.Fatalf("Declaration Data's ShortName for %s was not %s", struc
tID, shortName) |
| 278 } |
| 279 |
| 280 // Verify that the number of fields matches the expected ones. |
| 281 if got, expected := len(ms.Fields), len(fields); got != expected { |
| 282 t.Fatalf("MojomStruct for %s had %d fields, but expected %d", st
ructID, got, expected) |
| 283 } |
| 284 |
| 285 // Go through each StructField, checking DeclData and the Type of each f
ield. |
| 286 // Note that since ms.Fields is a slice, the "ordinal" is the index. |
| 287 for i, field := range ms.Fields { |
| 288 expectedFieldShortName := fields[i] |
| 289 // Check that the ShortName is correct. |
| 290 if field.DeclData == nil || field.DeclData.ShortName == nil || *
field.DeclData.ShortName != expectedFieldShortName { |
| 291 t.Fatalf("StructField for %s at ordinal %d did not have
ShortName %s", structID, i, expectedFieldShortName) |
| 292 } |
| 293 |
| 294 // Special case each field since we know what's inside. |
| 295 switch i { |
| 296 case 0: |
| 297 ttr, ok := field.Type.(*mojom_types.TypeTypeReference) |
| 298 if !ok { |
| 299 t.Fatalf("StructField %s's field 0 didn't have T
ype *TypeTypeReference", structID) |
| 300 } |
| 301 |
| 302 // TypeTypeReference.Value is a TypeReference, which mus
t have reference equality to the imported unionID. |
| 303 unionIDRef := &test_included_unions.ID_test_included_uni
ons_IncludedUnion__ |
| 304 if ttr.Value.Identifier != unionIDRef { |
| 305 t.Fatalf("TypeReference Identifier got %s, but e
xpected %s", *ttr.Value.Identifier, *unionIDRef) |
| 306 } |
| 307 if ttr.Value.TypeKey != unionIDRef { |
| 308 t.Fatalf("TypeReference TypeKey got %s, but expe
cted %s", *ttr.Value.TypeKey, *unionIDRef) |
| 309 } |
| 310 default: |
| 311 t.Fatalf("There should not be a field %d for MojomStruct
%s", i, structID) |
| 312 } |
| 313 } |
| 314 } |
| 315 |
| 316 // Check that a MojomInterface has the right methods and the right struct defini
tions |
| 317 // for its input and output. Further, its Interface_Request and Interface_Factor
y |
| 318 // must expose a usable ServiceDescription. |
| 319 func TestInterfaceType(t *testing.T) { |
| 320 // interface BoundsCheckTestInterface { |
| 321 // Method0(uint8 param0) => (uint8 param0); |
| 322 // Method1(uint8 param0); |
| 323 // }; |
| 324 |
| 325 interfaceID := test.ID_validation_test_interfaces_BoundsCheckTestInterfa
ce__ |
| 326 shortName := "BoundsCheckTestInterface" |
| 327 methodMap := map[uint32]string{ |
| 328 0: "Method0", |
| 329 1: "Method1", |
| 330 } |
| 331 |
| 332 // Extract *UserDefinedType from the validation test's Descriptor using
interfaceID. |
| 333 udt := test_descriptor[interfaceID] |
| 334 if udt == nil { |
| 335 t.Fatalf("Descriptor did not contain %s", interfaceID) |
| 336 } |
| 337 |
| 338 // The *UserDefinedType must be a *UserDefinedTypeInterfaceType. |
| 339 udit, ok := udt.(*mojom_types.UserDefinedTypeInterfaceType) |
| 340 if !ok { |
| 341 t.Fatalf("*UserDefinedType for %s was not *UserDefinedTypeInterf
aceType", interfaceID) |
| 342 } |
| 343 |
| 344 // The UserDefinedTypeInterfaceType has a MojomInterface inside. |
| 345 mi := udit.Value |
| 346 checkMojomInterface(t, mi, interfaceID, shortName, methodMap) |
| 347 |
| 348 // Now, we must check the ServiceDescription(s) exposed by the autogener
ated |
| 349 // ServiceRequest and ServiceFactory. |
| 350 var bcti_r test.BoundsCheckTestInterface_Request |
| 351 checkServiceDescription(t, bcti_r.ServiceDescription(), interfaceID, sho
rtName, methodMap) |
| 352 |
| 353 var bcti_sf test.BoundsCheckTestInterface_ServiceFactory |
| 354 checkServiceDescription(t, bcti_sf.ServiceDescription(), interfaceID, sh
ortName, methodMap) |
| 355 } |
| 356 |
| 357 func checkServiceDescription(t *testing.T, sd service_describer.ServiceDescripti
on, interfaceID string, shortName string, methodMap map[uint32]string) { |
| 358 // Check out the top level interface. This must pass checkMojomInterface
. |
| 359 mi, err := sd.GetTopLevelInterface() |
| 360 if err != nil { |
| 361 t.Fatalf("Unexpected error %s", err) |
| 362 } |
| 363 checkMojomInterface(t, mi, interfaceID, shortName, methodMap) |
| 364 |
| 365 // Try out sd.GetTypeDefinition. Pass in the interfaceID to see if you c
an get it out. |
| 366 udt, err := sd.GetTypeDefinition(interfaceID) |
| 367 if err != nil { |
| 368 t.Fatalf("Unexpected error %s", err) |
| 369 } |
| 370 if udtit, ok := udt.(*mojom_types.UserDefinedTypeInterfaceType); !ok { |
| 371 t.Fatalf("This type should be a *UserDefinedTypeInterfaceType") |
| 372 } else { |
| 373 checkMojomInterface(t, udtit.Value, interfaceID, shortName, meth
odMap) |
| 374 } |
| 375 |
| 376 // Look at all the type definitions. Reflect-wise, all data inside shoul
d match the imported Descriptor. |
| 377 outDesc, err := sd.GetAllTypeDefinitions() |
| 378 if err != nil { |
| 379 t.Fatalf("Unexpected error %s", err) |
| 380 } |
| 381 if !reflect.DeepEqual(*outDesc, test_descriptor) { |
| 382 t.Fatalf("Descriptions did not match") |
| 383 } |
| 384 } |
| 385 |
| 386 func checkMojomInterface(t *testing.T, mi mojom_types.MojomInterface, interfaceI
D string, shortName string, methodMap map[uint32]string) { |
| 387 // Check that the generator produced the short name. |
| 388 if mi.DeclData == nil || mi.DeclData.ShortName == nil { |
| 389 t.Fatalf("Declaration Data's ShortName for %s was missing", inte
rfaceID) |
| 390 } |
| 391 if *mi.DeclData.ShortName != shortName { |
| 392 t.Fatalf("Declaration Data's ShortName for %s was not %s", inter
faceID, shortName) |
| 393 } |
| 394 |
| 395 // Verify that the number of methods matches the expected ones. |
| 396 if got, expected := len(mi.Methods), len(methodMap); got != expected { |
| 397 t.Fatalf("MojomInterface for %s had %d methods, but expected %d"
, interfaceID, got, expected) |
| 398 } |
| 399 |
| 400 // Go through each MojomMethod, checking DeclData and the Type of each f
ield. |
| 401 // Note that since mi.Methods is a map, the "ordinal" is the key. |
| 402 for ordinal, method := range mi.Methods { |
| 403 expectedMethodShortName := methodMap[ordinal] |
| 404 // Check that the ShortName is correct. |
| 405 if method.DeclData == nil || method.DeclData.ShortName == nil ||
*method.DeclData.ShortName != expectedMethodShortName { |
| 406 t.Fatalf("MojomMethod for %s at ordinal %d did not have
ShortName %s", interfaceID, ordinal, expectedMethodShortName) |
| 407 } |
| 408 |
| 409 // Special case each field since we know what's inside. |
| 410 switch ordinal { |
| 411 case 0: |
| 412 // We expect 0 to be a MojomMethod with both request and
response params. |
| 413 params := method.Parameters |
| 414 if len(params.Fields) != 1 { |
| 415 t.Fatalf("Method0 Request had %d arguments, but
should have had 1", len(params.Fields)) |
| 416 } |
| 417 if tst, ok := params.Fields[0].Type.(*mojom_types.TypeSi
mpleType); !ok { |
| 418 t.Fatalf("Method0 Request param 0's Type should
be a *TypeSimpleType") |
| 419 } else if tst.Value != mojom_types.SimpleType_UinT8 { |
| 420 t.Fatalf("Method0 Request param 0's Type's Value
should be a SimpleType_UinT8") |
| 421 } |
| 422 |
| 423 response := method.ResponseParams |
| 424 if response == nil { |
| 425 t.Fatalf("Method0 Response should not be nil") |
| 426 } |
| 427 if len(response.Fields) != 1 { |
| 428 t.Fatalf("Method0 Response had %d arguments, but
should have had 1", len(response.Fields)) |
| 429 } |
| 430 if tst, ok := response.Fields[0].Type.(*mojom_types.Type
SimpleType); !ok { |
| 431 t.Fatalf("Method0 Response param 0's Type should
be a *TypeSimpleType") |
| 432 } else if tst.Value != mojom_types.SimpleType_UinT8 { |
| 433 t.Fatalf("Method0 Response param 0's Type's Valu
e should be a SimpleType_UinT8") |
| 434 } |
| 435 case 1: |
| 436 // We expect 1 to be a MojomMethod with a request and ni
l response params. |
| 437 params := method.Parameters |
| 438 if len(params.Fields) != 1 { |
| 439 t.Fatalf("Method1 Request had %d arguments, but
should have had 1", len(params.Fields)) |
| 440 } |
| 441 if tst, ok := params.Fields[0].Type.(*mojom_types.TypeSi
mpleType); !ok { |
| 442 t.Fatalf("Method1 Request param 0's Type should
be a *TypeSimpleType") |
| 443 } else if tst.Value != mojom_types.SimpleType_UinT8 { |
| 444 t.Fatalf("Method1 Request param 0's Type's Value
should be a SimpleType_UinT8") |
| 445 } |
| 446 |
| 447 if method.ResponseParams != nil { |
| 448 t.Fatalf("MojomMethod %d had a Response but shou
ld not have", ordinal) |
| 449 } |
| 450 default: |
| 451 t.Fatalf("There should not be a method %d for MojomInter
face %s", ordinal, interfaceID) |
| 452 } |
| 453 } |
| 454 } |
OLD | NEW |