1 # Copyright 2013 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 import sys 6 7 import module as mojom 8 import pack 9 import test_support 10 11 12 EXPECT_EQ = test_support.EXPECT_EQ 13 EXPECT_TRUE = test_support.EXPECT_TRUE 14 RunTest = test_support.RunTest 15 16 17 def TestOrdinalOrder(): 18 errors = 0 19 struct = mojom.Struct('test') 20 struct.AddField('testfield1', mojom.INT32, 2) 21 struct.AddField('testfield2', mojom.INT32, 1) 22 ps = pack.PackedStruct(struct) 23 24 errors += EXPECT_EQ(2, len(ps.packed_fields)) 25 errors += EXPECT_EQ('testfield2', ps.packed_fields[0].field.name) 26 errors += EXPECT_EQ('testfield1', ps.packed_fields[1].field.name) 27 28 return errors 29 30 def TestZeroFields(): 31 errors = 0 32 struct = mojom.Struct('test') 33 ps = pack.PackedStruct(struct) 34 errors += EXPECT_EQ(0, len(ps.packed_fields)) 35 return errors 36 37 38 def TestOneField(): 39 errors = 0 40 struct = mojom.Struct('test') 41 struct.AddField('testfield1', mojom.INT8) 42 ps = pack.PackedStruct(struct) 43 errors += EXPECT_EQ(1, len(ps.packed_fields)) 44 return errors 45 46 # Pass three tuples. 47 # |kinds| is a sequence of mojom.Kinds that specify the fields that are to 48 # be created. 49 # |fields| is the expected order of the resulting fields, with the integer 50 # "1" first. 51 # |offsets| is the expected order of offsets, with the integer "0" first. 52 def TestSequence(kinds, fields, offsets): 53 errors = 0 54 struct = mojom.Struct('test') 55 index = 1 56 for kind in kinds: 57 struct.AddField("%d" % index, kind) 58 index += 1 59 ps = pack.PackedStruct(struct) 60 num_fields = len(ps.packed_fields) 61 errors += EXPECT_EQ(len(kinds), num_fields) 62 for i in xrange(num_fields): 63 EXPECT_EQ("%d" % fields[i], ps.packed_fields[i].field.name) 64 EXPECT_EQ(offsets[i], ps.packed_fields[i].offset) 65 66 return errors 67 68 69 def TestPaddingPackedInOrder(): 70 return TestSequence( 71 (mojom.INT8, mojom.UINT8, mojom.INT32), 72 (1, 2, 3), 73 (0, 1, 4)) 74 75 76 def TestPaddingPackedOutOfOrder(): 77 return TestSequence( 78 (mojom.INT8, mojom.INT32, mojom.UINT8), 79 (1, 3, 2), 80 (0, 1, 4)) 81 82 83 def TestPaddingPackedOverflow(): 84 kinds = (mojom.INT8, mojom.INT32, mojom.INT16, mojom.INT8, mojom.INT8) 85 # 2 bytes should be packed together first, followed by short, then by int. 86 fields = (1, 4, 3, 2, 5) 87 offsets = (0, 1, 2, 4, 8) 88 return TestSequence(kinds, fields, offsets) 89 90 91 def TestAllTypes(): 92 struct = mojom.Struct('test') 93 array = mojom.Array() 94 return TestSequence( 95 (mojom.BOOL, mojom.INT8, mojom.STRING, mojom.UINT8, 96 mojom.INT16, mojom.DOUBLE, mojom.UINT16, 97 mojom.INT32, mojom.UINT32, mojom.INT64, 98 mojom.FLOAT, mojom.STRING, mojom.HANDLE, 99 mojom.UINT64, mojom.Struct('test'), mojom.Array()), 100 (1, 2, 4, 5, 7, 3, 6, 8, 9, 10, 11, 13, 12, 14, 15, 16, 17), 101 (0, 1, 2, 4, 6, 8, 16, 24, 28, 32, 40, 44, 48, 56, 64, 72, 80)) 102 103 104 def TestPaddingPackedOutOfOrderByOrdinal(): 105 errors = 0 106 struct = mojom.Struct('test') 107 struct.AddField('testfield1', mojom.INT8) 108 struct.AddField('testfield3', mojom.UINT8, 3) 109 struct.AddField('testfield2', mojom.INT32, 2) 110 ps = pack.PackedStruct(struct) 111 errors += EXPECT_EQ(3, len(ps.packed_fields)) 112 113 # Second byte should be packed in behind first, altering order. 114 errors += EXPECT_EQ('testfield1', ps.packed_fields[0].field.name) 115 errors += EXPECT_EQ('testfield3', ps.packed_fields[1].field.name) 116 errors += EXPECT_EQ('testfield2', ps.packed_fields[2].field.name) 117 118 # Second byte should be packed with first. 119 errors += EXPECT_EQ(0, ps.packed_fields[0].offset) 120 errors += EXPECT_EQ(1, ps.packed_fields[1].offset) 121 errors += EXPECT_EQ(4, ps.packed_fields[2].offset) 122 123 return errors 124 125 126 def TestBools(): 127 errors = 0 128 struct = mojom.Struct('test') 129 struct.AddField('bit0', mojom.BOOL) 130 struct.AddField('bit1', mojom.BOOL) 131 struct.AddField('int', mojom.INT32) 132 struct.AddField('bit2', mojom.BOOL) 133 struct.AddField('bit3', mojom.BOOL) 134 struct.AddField('bit4', mojom.BOOL) 135 struct.AddField('bit5', mojom.BOOL) 136 struct.AddField('bit6', mojom.BOOL) 137 struct.AddField('bit7', mojom.BOOL) 138 struct.AddField('bit8', mojom.BOOL) 139 ps = pack.PackedStruct(struct) 140 errors += EXPECT_EQ(10, len(ps.packed_fields)) 141 142 # First 8 bits packed together. 143 for i in xrange(8): 144 pf = ps.packed_fields[i] 145 errors += EXPECT_EQ(0, pf.offset) 146 errors += EXPECT_EQ("bit%d" % i, pf.field.name) 147 errors += EXPECT_EQ(i, pf.bit) 148 149 # Ninth bit goes into second byte. 150 errors += EXPECT_EQ("bit8", ps.packed_fields[8].field.name) 151 errors += EXPECT_EQ(1, ps.packed_fields[8].offset) 152 errors += EXPECT_EQ(0, ps.packed_fields[8].bit) 153 154 # int comes last. 155 errors += EXPECT_EQ("int", ps.packed_fields[9].field.name) 156 errors += EXPECT_EQ(4, ps.packed_fields[9].offset) 157 158 return errors 159 160 161 def Main(args): 162 errors = 0 163 errors += RunTest(TestZeroFields) 164 errors += RunTest(TestOneField) 165 errors += RunTest(TestPaddingPackedInOrder) 166 errors += RunTest(TestPaddingPackedOutOfOrder) 167 errors += RunTest(TestPaddingPackedOverflow) 168 errors += RunTest(TestAllTypes) 169 errors += RunTest(TestPaddingPackedOutOfOrderByOrdinal) 170 errors += RunTest(TestBools) 171 172 return errors 173 174 175 if __name__ == '__main__': 176 sys.exit(Main(sys.argv[1:])) 177