1#!/usr/bin/python 2# 3# Copyright 2016 The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17import unittest 18 19import cstruct 20 21 22# These aren't constants, they're classes. So, pylint: disable=invalid-name 23TestStructA = cstruct.Struct("TestStructA", "=BI", "byte1 int2") 24TestStructB = cstruct.Struct("TestStructB", "=BI", "byte1 int2") 25 26 27class CstructTest(unittest.TestCase): 28 29 def CheckEquals(self, a, b): 30 self.assertEquals(a, b) 31 self.assertEquals(b, a) 32 assert a == b 33 assert b == a 34 assert not (a != b) # pylint: disable=g-comparison-negation,superfluous-parens 35 assert not (b != a) # pylint: disable=g-comparison-negation,superfluous-parens 36 37 def CheckNotEquals(self, a, b): 38 self.assertNotEquals(a, b) 39 self.assertNotEquals(b, a) 40 assert a != b 41 assert b != a 42 assert not (a == b) # pylint: disable=g-comparison-negation,superfluous-parens 43 assert not (b == a) # pylint: disable=g-comparison-negation,superfluous-parens 44 45 def testEqAndNe(self): 46 a1 = TestStructA((1, 2)) 47 a2 = TestStructA((2, 3)) 48 a3 = TestStructA((1, 2)) 49 b = TestStructB((1, 2)) 50 self.CheckNotEquals(a1, b) 51 self.CheckNotEquals(a2, b) 52 self.CheckNotEquals(a1, a2) 53 self.CheckNotEquals(a2, a3) 54 for i in [a1, a2, a3, b]: 55 self.CheckEquals(i, i) 56 self.CheckEquals(a1, a3) 57 58 def testNestedStructs(self): 59 Nested = cstruct.Struct("Nested", "!HSSi", 60 "word1 nest2 nest3 int4", 61 [TestStructA, TestStructB]) 62 DoubleNested = cstruct.Struct("DoubleNested", "SSB", 63 "nest1 nest2 byte3", 64 [TestStructA, Nested]) 65 d = DoubleNested((TestStructA((1, 2)), 66 Nested((5, TestStructA((3, 4)), TestStructB((7, 8)), 9)), 67 6)) 68 69 expectedlen = (len(TestStructA) + 70 2 + len(TestStructA) + len(TestStructB) + 4 + 71 1) 72 self.assertEquals(expectedlen, len(DoubleNested)) 73 74 self.assertEquals(7, d.nest2.nest3.byte1) 75 76 d.byte3 = 252 77 d.nest2.word1 = 33214 78 n = d.nest2 79 n.int4 = -55 80 t = n.nest3 81 t.int2 = 33627591 82 83 self.assertEquals(33627591, d.nest2.nest3.int2) 84 85 expected = ( 86 "DoubleNested(nest1=TestStructA(byte1=1, int2=2)," 87 " nest2=Nested(word1=33214, nest2=TestStructA(byte1=3, int2=4)," 88 " nest3=TestStructB(byte1=7, int2=33627591), int4=-55), byte3=252)") 89 self.assertEquals(expected, str(d)) 90 expected = ("01" "02000000" 91 "81be" "03" "04000000" 92 "07" "c71d0102" "ffffffc9" "fc").decode("hex") 93 self.assertEquals(expected, d.Pack()) 94 unpacked = DoubleNested(expected) 95 self.CheckEquals(unpacked, d) 96 97 def testNullTerminatedStrings(self): 98 TestStruct = cstruct.Struct("TestStruct", "B16si16AH", 99 "byte1 string2 int3 ascii4 word5") 100 nullstr = "hello" + (16 - len("hello")) * "\x00" 101 102 t = TestStruct((2, nullstr, 12345, nullstr, 33210)) 103 expected = ("TestStruct(byte1=2, string2=68656c6c6f0000000000000000000000," 104 " int3=12345, ascii4=hello, word5=33210)") 105 self.assertEquals(expected, str(t)) 106 107 embeddednull = "hello\x00visible123" 108 t = TestStruct((2, embeddednull, 12345, embeddednull, 33210)) 109 expected = ("TestStruct(byte1=2, string2=68656c6c6f0076697369626c65313233," 110 " int3=12345, ascii4=hello\x00visible123, word5=33210)") 111 self.assertEquals(expected, str(t)) 112 113 114if __name__ == "__main__": 115 unittest.main() 116