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 import imp 6 import os.path 7 import sys 8 import unittest 9 10 11 def _GetDirAbove(dirname): 12 """Returns the directory "above" this file containing |dirname| (which must 13 also be "above" this file).""" 14 path = os.path.abspath(__file__) 15 while True: 16 path, tail = os.path.split(path) 17 assert tail 18 if tail == dirname: 19 return path 20 21 22 try: 23 imp.find_module("mojom") 24 except ImportError: 25 sys.path.append(os.path.join(_GetDirAbove("pylib"), "pylib")) 26 from mojom.generate import pack 27 from mojom.generate import module as mojom 28 29 30 # TODO(yzshen): Move tests in pack_tests.py here. 31 class PackTest(unittest.TestCase): 32 def _CheckPackSequence(self, kinds, fields, offsets): 33 """Checks the pack order and offsets of a sequence of mojom.Kinds. 34 35 Args: 36 kinds: A sequence of mojom.Kinds that specify the fields that are to be 37 created. 38 fields: The expected order of the resulting fields, with the integer "1" 39 first. 40 offsets: The expected order of offsets, with the integer "0" first. 41 """ 42 struct = mojom.Struct('test') 43 index = 1 44 for kind in kinds: 45 struct.AddField('%d' % index, kind) 46 index += 1 47 ps = pack.PackedStruct(struct) 48 num_fields = len(ps.packed_fields) 49 self.assertEquals(len(kinds), num_fields) 50 for i in xrange(num_fields): 51 self.assertEquals('%d' % fields[i], ps.packed_fields[i].field.name) 52 self.assertEquals(offsets[i], ps.packed_fields[i].offset) 53 54 def testMinVersion(self): 55 """Tests that |min_version| is properly set for packed fields.""" 56 struct = mojom.Struct('test') 57 struct.AddField('field_2', mojom.BOOL, 2) 58 struct.AddField('field_0', mojom.INT32, 0) 59 struct.AddField('field_1', mojom.INT64, 1) 60 ps = pack.PackedStruct(struct) 61 62 self.assertEquals('field_0', ps.packed_fields[0].field.name) 63 self.assertEquals('field_2', ps.packed_fields[1].field.name) 64 self.assertEquals('field_1', ps.packed_fields[2].field.name) 65 66 self.assertEquals(0, ps.packed_fields[0].min_version) 67 self.assertEquals(0, ps.packed_fields[1].min_version) 68 self.assertEquals(0, ps.packed_fields[2].min_version) 69 70 struct.fields[0].attributes = {'MinVersion': 1} 71 ps = pack.PackedStruct(struct) 72 73 self.assertEquals(0, ps.packed_fields[0].min_version) 74 self.assertEquals(1, ps.packed_fields[1].min_version) 75 self.assertEquals(0, ps.packed_fields[2].min_version) 76 77 def testGetVersionInfoEmptyStruct(self): 78 """Tests that pack.GetVersionInfo() never returns an empty list, even for 79 empty structs. 80 """ 81 struct = mojom.Struct('test') 82 ps = pack.PackedStruct(struct) 83 84 versions = pack.GetVersionInfo(ps) 85 self.assertEquals(1, len(versions)) 86 self.assertEquals(0, versions[0].version) 87 self.assertEquals(0, versions[0].num_fields) 88 self.assertEquals(8, versions[0].num_bytes) 89 90 def testGetVersionInfoComplexOrder(self): 91 """Tests pack.GetVersionInfo() using a struct whose definition order, 92 ordinal order and pack order for fields are all different. 93 """ 94 struct = mojom.Struct('test') 95 struct.AddField('field_3', mojom.BOOL, ordinal=3, 96 attributes={'MinVersion': 3}) 97 struct.AddField('field_0', mojom.INT32, ordinal=0) 98 struct.AddField('field_1', mojom.INT64, ordinal=1, 99 attributes={'MinVersion': 2}) 100 struct.AddField('field_2', mojom.INT64, ordinal=2, 101 attributes={'MinVersion': 3}) 102 ps = pack.PackedStruct(struct) 103 104 versions = pack.GetVersionInfo(ps) 105 self.assertEquals(3, len(versions)) 106 107 self.assertEquals(0, versions[0].version) 108 self.assertEquals(1, versions[0].num_fields) 109 self.assertEquals(16, versions[0].num_bytes) 110 111 self.assertEquals(2, versions[1].version) 112 self.assertEquals(2, versions[1].num_fields) 113 self.assertEquals(24, versions[1].num_bytes) 114 115 self.assertEquals(3, versions[2].version) 116 self.assertEquals(4, versions[2].num_fields) 117 self.assertEquals(32, versions[2].num_bytes) 118 119 def testInterfaceAlignment(self): 120 """Tests that interfaces are aligned on 4-byte boundaries, although the size 121 of an interface is 8 bytes. 122 """ 123 kinds = (mojom.INT32, mojom.Interface('test_interface')) 124 fields = (1, 2) 125 offsets = (0, 4) 126 self._CheckPackSequence(kinds, fields, offsets) 127 128 def testAssociatedInterfaceAlignment(self): 129 """Tests that associated interfaces are aligned on 4-byte boundaries, 130 although the size of an associated interface is 8 bytes. 131 """ 132 kinds = (mojom.INT32, 133 mojom.AssociatedInterface(mojom.Interface('test_interface'))) 134 fields = (1, 2) 135 offsets = (0, 4) 136 self._CheckPackSequence(kinds, fields, offsets) 137