summaryrefslogtreecommitdiff
path: root/utils/ipc/mojo/public/tools/mojom/mojom/generate/pack_unittest.py
diff options
context:
space:
mode:
Diffstat (limited to 'utils/ipc/mojo/public/tools/mojom/mojom/generate/pack_unittest.py')
-rw-r--r--utils/ipc/mojo/public/tools/mojom/mojom/generate/pack_unittest.py225
1 files changed, 225 insertions, 0 deletions
diff --git a/utils/ipc/mojo/public/tools/mojom/mojom/generate/pack_unittest.py b/utils/ipc/mojo/public/tools/mojom/mojom/generate/pack_unittest.py
new file mode 100644
index 00000000..98c705ad
--- /dev/null
+++ b/utils/ipc/mojo/public/tools/mojom/mojom/generate/pack_unittest.py
@@ -0,0 +1,225 @@
+# Copyright 2013 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import sys
+import unittest
+
+from mojom.generate import module as mojom
+from mojom.generate import pack
+
+
+class PackTest(unittest.TestCase):
+ def testOrdinalOrder(self):
+ struct = mojom.Struct('test')
+ struct.AddField('testfield1', mojom.INT32, 2)
+ struct.AddField('testfield2', mojom.INT32, 1)
+ ps = pack.PackedStruct(struct)
+
+ self.assertEqual(2, len(ps.packed_fields))
+ self.assertEqual('testfield2', ps.packed_fields[0].field.mojom_name)
+ self.assertEqual('testfield1', ps.packed_fields[1].field.mojom_name)
+
+ def testZeroFields(self):
+ struct = mojom.Struct('test')
+ ps = pack.PackedStruct(struct)
+ self.assertEqual(0, len(ps.packed_fields))
+
+ def testOneField(self):
+ struct = mojom.Struct('test')
+ struct.AddField('testfield1', mojom.INT8)
+ ps = pack.PackedStruct(struct)
+ self.assertEqual(1, len(ps.packed_fields))
+
+ def _CheckPackSequence(self, kinds, fields, offsets):
+ """Checks the pack order and offsets of a sequence of mojom.Kinds.
+
+ Args:
+ kinds: A sequence of mojom.Kinds that specify the fields that are to be
+ created.
+ fields: The expected order of the resulting fields, with the integer "1"
+ first.
+ offsets: The expected order of offsets, with the integer "0" first.
+ """
+ struct = mojom.Struct('test')
+ index = 1
+ for kind in kinds:
+ struct.AddField('%d' % index, kind)
+ index += 1
+ ps = pack.PackedStruct(struct)
+ num_fields = len(ps.packed_fields)
+ self.assertEqual(len(kinds), num_fields)
+ for i in range(num_fields):
+ self.assertEqual('%d' % fields[i], ps.packed_fields[i].field.mojom_name)
+ self.assertEqual(offsets[i], ps.packed_fields[i].offset)
+
+ def testPaddingPackedInOrder(self):
+ return self._CheckPackSequence((mojom.INT8, mojom.UINT8, mojom.INT32),
+ (1, 2, 3), (0, 1, 4))
+
+ def testPaddingPackedOutOfOrder(self):
+ return self._CheckPackSequence((mojom.INT8, mojom.INT32, mojom.UINT8),
+ (1, 3, 2), (0, 1, 4))
+
+ def testPaddingPackedOverflow(self):
+ kinds = (mojom.INT8, mojom.INT32, mojom.INT16, mojom.INT8, mojom.INT8)
+ # 2 bytes should be packed together first, followed by short, then by int.
+ fields = (1, 4, 3, 2, 5)
+ offsets = (0, 1, 2, 4, 8)
+ return self._CheckPackSequence(kinds, fields, offsets)
+
+ def testNullableTypes(self):
+ kinds = (mojom.STRING.MakeNullableKind(), mojom.HANDLE.MakeNullableKind(),
+ mojom.Struct('test_struct').MakeNullableKind(),
+ mojom.DCPIPE.MakeNullableKind(), mojom.Array().MakeNullableKind(),
+ mojom.DPPIPE.MakeNullableKind(),
+ mojom.Array(length=5).MakeNullableKind(),
+ mojom.MSGPIPE.MakeNullableKind(),
+ mojom.Interface('test_interface').MakeNullableKind(),
+ mojom.SHAREDBUFFER.MakeNullableKind(),
+ mojom.InterfaceRequest().MakeNullableKind())
+ fields = (1, 2, 4, 3, 5, 6, 8, 7, 9, 10, 11)
+ offsets = (0, 8, 12, 16, 24, 32, 36, 40, 48, 56, 60)
+ return self._CheckPackSequence(kinds, fields, offsets)
+
+ def testAllTypes(self):
+ return self._CheckPackSequence(
+ (mojom.BOOL, mojom.INT8, mojom.STRING, mojom.UINT8, mojom.INT16,
+ mojom.DOUBLE, mojom.UINT16, mojom.INT32, mojom.UINT32, mojom.INT64,
+ mojom.FLOAT, mojom.STRING, mojom.HANDLE, mojom.UINT64,
+ mojom.Struct('test'), mojom.Array(), mojom.STRING.MakeNullableKind()),
+ (1, 2, 4, 5, 7, 3, 6, 8, 9, 10, 11, 13, 12, 14, 15, 16, 17, 18),
+ (0, 1, 2, 4, 6, 8, 16, 24, 28, 32, 40, 44, 48, 56, 64, 72, 80, 88))
+
+ def testPaddingPackedOutOfOrderByOrdinal(self):
+ struct = mojom.Struct('test')
+ struct.AddField('testfield1', mojom.INT8)
+ struct.AddField('testfield3', mojom.UINT8, 3)
+ struct.AddField('testfield2', mojom.INT32, 2)
+ ps = pack.PackedStruct(struct)
+ self.assertEqual(3, len(ps.packed_fields))
+
+ # Second byte should be packed in behind first, altering order.
+ self.assertEqual('testfield1', ps.packed_fields[0].field.mojom_name)
+ self.assertEqual('testfield3', ps.packed_fields[1].field.mojom_name)
+ self.assertEqual('testfield2', ps.packed_fields[2].field.mojom_name)
+
+ # Second byte should be packed with first.
+ self.assertEqual(0, ps.packed_fields[0].offset)
+ self.assertEqual(1, ps.packed_fields[1].offset)
+ self.assertEqual(4, ps.packed_fields[2].offset)
+
+ def testBools(self):
+ struct = mojom.Struct('test')
+ struct.AddField('bit0', mojom.BOOL)
+ struct.AddField('bit1', mojom.BOOL)
+ struct.AddField('int', mojom.INT32)
+ struct.AddField('bit2', mojom.BOOL)
+ struct.AddField('bit3', mojom.BOOL)
+ struct.AddField('bit4', mojom.BOOL)
+ struct.AddField('bit5', mojom.BOOL)
+ struct.AddField('bit6', mojom.BOOL)
+ struct.AddField('bit7', mojom.BOOL)
+ struct.AddField('bit8', mojom.BOOL)
+ ps = pack.PackedStruct(struct)
+ self.assertEqual(10, len(ps.packed_fields))
+
+ # First 8 bits packed together.
+ for i in range(8):
+ pf = ps.packed_fields[i]
+ self.assertEqual(0, pf.offset)
+ self.assertEqual("bit%d" % i, pf.field.mojom_name)
+ self.assertEqual(i, pf.bit)
+
+ # Ninth bit goes into second byte.
+ self.assertEqual("bit8", ps.packed_fields[8].field.mojom_name)
+ self.assertEqual(1, ps.packed_fields[8].offset)
+ self.assertEqual(0, ps.packed_fields[8].bit)
+
+ # int comes last.
+ self.assertEqual("int", ps.packed_fields[9].field.mojom_name)
+ self.assertEqual(4, ps.packed_fields[9].offset)
+
+ def testMinVersion(self):
+ """Tests that |min_version| is properly set for packed fields."""
+ struct = mojom.Struct('test')
+ struct.AddField('field_2', mojom.BOOL, 2)
+ struct.AddField('field_0', mojom.INT32, 0)
+ struct.AddField('field_1', mojom.INT64, 1)
+ ps = pack.PackedStruct(struct)
+
+ self.assertEqual('field_0', ps.packed_fields[0].field.mojom_name)
+ self.assertEqual('field_2', ps.packed_fields[1].field.mojom_name)
+ self.assertEqual('field_1', ps.packed_fields[2].field.mojom_name)
+
+ self.assertEqual(0, ps.packed_fields[0].min_version)
+ self.assertEqual(0, ps.packed_fields[1].min_version)
+ self.assertEqual(0, ps.packed_fields[2].min_version)
+
+ struct.fields[0].attributes = {'MinVersion': 1}
+ ps = pack.PackedStruct(struct)
+
+ self.assertEqual(0, ps.packed_fields[0].min_version)
+ self.assertEqual(1, ps.packed_fields[1].min_version)
+ self.assertEqual(0, ps.packed_fields[2].min_version)
+
+ def testGetVersionInfoEmptyStruct(self):
+ """Tests that pack.GetVersionInfo() never returns an empty list, even for
+ empty structs.
+ """
+ struct = mojom.Struct('test')
+ ps = pack.PackedStruct(struct)
+
+ versions = pack.GetVersionInfo(ps)
+ self.assertEqual(1, len(versions))
+ self.assertEqual(0, versions[0].version)
+ self.assertEqual(0, versions[0].num_fields)
+ self.assertEqual(8, versions[0].num_bytes)
+
+ def testGetVersionInfoComplexOrder(self):
+ """Tests pack.GetVersionInfo() using a struct whose definition order,
+ ordinal order and pack order for fields are all different.
+ """
+ struct = mojom.Struct('test')
+ struct.AddField(
+ 'field_3', mojom.BOOL, ordinal=3, attributes={'MinVersion': 3})
+ struct.AddField('field_0', mojom.INT32, ordinal=0)
+ struct.AddField(
+ 'field_1', mojom.INT64, ordinal=1, attributes={'MinVersion': 2})
+ struct.AddField(
+ 'field_2', mojom.INT64, ordinal=2, attributes={'MinVersion': 3})
+ ps = pack.PackedStruct(struct)
+
+ versions = pack.GetVersionInfo(ps)
+ self.assertEqual(3, len(versions))
+
+ self.assertEqual(0, versions[0].version)
+ self.assertEqual(1, versions[0].num_fields)
+ self.assertEqual(16, versions[0].num_bytes)
+
+ self.assertEqual(2, versions[1].version)
+ self.assertEqual(2, versions[1].num_fields)
+ self.assertEqual(24, versions[1].num_bytes)
+
+ self.assertEqual(3, versions[2].version)
+ self.assertEqual(4, versions[2].num_fields)
+ self.assertEqual(32, versions[2].num_bytes)
+
+ def testInterfaceAlignment(self):
+ """Tests that interfaces are aligned on 4-byte boundaries, although the size
+ of an interface is 8 bytes.
+ """
+ kinds = (mojom.INT32, mojom.Interface('test_interface'))
+ fields = (1, 2)
+ offsets = (0, 4)
+ self._CheckPackSequence(kinds, fields, offsets)
+
+ def testAssociatedInterfaceAlignment(self):
+ """Tests that associated interfaces are aligned on 4-byte boundaries,
+ although the size of an associated interface is 8 bytes.
+ """
+ kinds = (mojom.INT32,
+ mojom.AssociatedInterface(mojom.Interface('test_interface')))
+ fields = (1, 2)
+ offsets = (0, 4)
+ self._CheckPackSequence(kinds, fields, offsets)