pack_tests.py revision 0529e5d033099cbfc42635f6f6183833b09dff6e
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
5import sys
6
7import module as mojom
8import pack
9import test_support
10
11
12EXPECT_EQ = test_support.EXPECT_EQ
13EXPECT_TRUE = test_support.EXPECT_TRUE
14RunTest = test_support.RunTest
15
16
17def 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
30def 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
38def 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.
52def 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
69def TestPaddingPackedInOrder():
70  return TestSequence(
71      (mojom.INT8, mojom.UINT8, mojom.INT32),
72      (1, 2, 3),
73      (0, 1, 4))
74
75
76def TestPaddingPackedOutOfOrder():
77  return TestSequence(
78      (mojom.INT8, mojom.INT32, mojom.UINT8),
79      (1, 3, 2),
80      (0, 1, 4))
81
82
83def 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
91def 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
104def 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
126def 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
161def 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
175if __name__ == '__main__':
176  sys.exit(Main(sys.argv[1:]))
177