1 1.1 skrll # SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause) 2 1.1 skrll # pylibfdt - Tests for Flat Device Tree manipulation in Python 3 1.1 skrll # Copyright (C) 2017 Google, Inc. 4 1.1 skrll # Written by Simon Glass <sjg (at] chromium.org> 5 1.1 skrll # 6 1.1 skrll 7 1.1 skrll import struct 8 1.1 skrll import sys 9 1.1 skrll import types 10 1.1 skrll import unittest 11 1.1 skrll 12 1.1 skrll sys.path.insert(0, '../pylibfdt') 13 1.1 skrll import libfdt 14 1.1 skrll from libfdt import Fdt, FdtSw, FdtException, QUIET_NOTFOUND, QUIET_ALL 15 1.1 skrll 16 1.1 skrll TEST_ADDR_1H = 0xdeadbeef 17 1.1 skrll TEST_ADDR_1L = 0x00000000 18 1.1 skrll TEST_ADDR_1 = (TEST_ADDR_1H << 32) | TEST_ADDR_1L 19 1.1 skrll TEST_ADDR_1 = 0x8000000000000000 20 1.1 skrll TEST_SIZE_1H = 0x00000000 21 1.1 skrll TEST_SIZE_1L = 0x00100000 22 1.1 skrll TEST_SIZE_1 = (TEST_SIZE_1H << 32) | TEST_SIZE_1L 23 1.1 skrll TEST_ADDR_2H = 0 24 1.1 skrll TEST_ADDR_2L = 123456789 25 1.1 skrll TEST_ADDR_2 = (TEST_ADDR_2H << 32) | TEST_ADDR_2L 26 1.1 skrll TEST_SIZE_2H = 0 27 1.1 skrll TEST_SIZE_2L = 0o10000 28 1.1 skrll TEST_SIZE_2 = (TEST_SIZE_2H << 32) | TEST_SIZE_2L 29 1.1 skrll 30 1.1 skrll TEST_VALUE_1 = 0xdeadbeef 31 1.1 skrll TEST_VALUE_2 = 123456789 32 1.1 skrll 33 1.1 skrll TEST_VALUE64_1H = 0xdeadbeef 34 1.1 skrll TEST_VALUE64_1L = 0x01abcdef 35 1.1 skrll TEST_VALUE64_1 = (TEST_VALUE64_1H << 32) | TEST_VALUE64_1L 36 1.1 skrll 37 1.1 skrll PHANDLE_1 = 0x2000 38 1.1 skrll PHANDLE_2 = 0x2001 39 1.1 skrll 40 1.1 skrll TEST_BYTES_1 = b'hello world' 41 1.1 skrll 42 1.1 skrll TEST_STRING_1 = 'hello world' 43 1.1 skrll TEST_STRING_2 = 'hi world' 44 1.1 skrll TEST_STRING_3 = u'unicode \u01d3' 45 1.1 skrll 46 1.1 skrll 47 1.1 skrll def get_err(err_code): 48 1.1 skrll """Convert an error code into an error message 49 1.1 skrll 50 1.1 skrll Args: 51 1.1 skrll err_code: Error code value (FDT_ERR_...) 52 1.1 skrll 53 1.1 skrll Returns: 54 1.1 skrll String error code 55 1.1 skrll """ 56 1.1 skrll return 'pylibfdt error %d: %s' % (-err_code, libfdt.strerror(-err_code)) 57 1.1 skrll 58 1.1 skrll def _ReadFdt(fname): 59 1.1 skrll """Read a device tree file into an Fdt object, ready for use 60 1.1 skrll 61 1.1 skrll Args: 62 1.1 skrll fname: Filename to read from 63 1.1 skrll 64 1.1 skrll Returns: 65 1.1 skrll Fdt bytearray suitable for passing to libfdt functions 66 1.1 skrll """ 67 1.1 skrll return libfdt.Fdt(open(fname, mode='rb').read()) 68 1.1 skrll 69 1.1 skrll class PyLibfdtBasicTests(unittest.TestCase): 70 1.1 skrll """Test class for basic pylibfdt access functions 71 1.1 skrll 72 1.1 skrll Properties: 73 1.1 skrll fdt: Device tree file used for testing 74 1.1 skrll """ 75 1.1 skrll 76 1.1 skrll def setUp(self): 77 1.1 skrll """Read in the device tree we use for testing""" 78 1.1 skrll self.fdt = _ReadFdt('test_tree1.dtb') 79 1.1 skrll self.fdt2 = _ReadFdt('test_props.dtb') 80 1.1 skrll self.fdt3 = _ReadFdt('aliases.dtb') 81 1.1 skrll 82 1.1 skrll def GetPropList(self, node_path): 83 1.1 skrll """Read a list of properties from a node 84 1.1 skrll 85 1.1 skrll Args: 86 1.1 skrll node_path: Full path to node, e.g. '/subnode@1/subsubnode' 87 1.1 skrll 88 1.1 skrll Returns: 89 1.1 skrll List of property names for that node, e.g. ['compatible', 'reg'] 90 1.1 skrll """ 91 1.1 skrll prop_list = [] 92 1.1 skrll node = self.fdt.path_offset(node_path) 93 1.1 skrll poffset = self.fdt.first_property_offset(node, QUIET_NOTFOUND) 94 1.1 skrll while poffset > 0: 95 1.1 skrll prop = self.fdt.get_property_by_offset(poffset) 96 1.1 skrll prop_list.append(prop.name) 97 1.1 skrll poffset = self.fdt.next_property_offset(poffset, QUIET_NOTFOUND) 98 1.1 skrll return prop_list 99 1.1 skrll 100 1.1 skrll def GetSubnodes(self, node_path): 101 1.1 skrll """Read a list of subnodes from a node 102 1.1 skrll 103 1.1 skrll Args: 104 1.1 skrll node_path: Full path to node, e.g. '/subnode@1/subsubnode' 105 1.1 skrll 106 1.1 skrll Returns: 107 1.1 skrll List of subnode names for that node, e.g. ['subsubnode', 'ss1'] 108 1.1 skrll """ 109 1.1 skrll subnode_list = [] 110 1.1 skrll node = self.fdt.path_offset(node_path) 111 1.1 skrll offset = self.fdt.first_subnode(node, QUIET_NOTFOUND) 112 1.1 skrll while offset > 0: 113 1.1 skrll name = self.fdt.get_name(offset) 114 1.1 skrll subnode_list.append(name) 115 1.1 skrll offset = self.fdt.next_subnode(offset, QUIET_NOTFOUND) 116 1.1 skrll return subnode_list 117 1.1 skrll 118 1.1 skrll def testImport(self): 119 1.1 skrll """Check that we can import the library correctly""" 120 1.1 skrll self.assertEquals(type(libfdt), types.ModuleType) 121 1.1 skrll 122 1.1 skrll def testBadFdt(self): 123 1.1 skrll """Check that a filename provided accidentally is not accepted""" 124 1.1 skrll with self.assertRaises(FdtException) as e: 125 1.1 skrll fdt = libfdt.Fdt(b'a string') 126 1.1 skrll self.assertEquals(e.exception.err, -libfdt.BADMAGIC) 127 1.1 skrll 128 1.1 skrll def testSubnodeOffset(self): 129 1.1 skrll """check that we can locate a subnode by name""" 130 1.1 skrll node1 = self.fdt.path_offset('/subnode@1') 131 1.1 skrll self.assertEquals(self.fdt.subnode_offset(0, 'subnode@1'), node1) 132 1.1 skrll 133 1.1 skrll with self.assertRaises(FdtException) as e: 134 1.1 skrll self.fdt.subnode_offset(0, 'missing') 135 1.1 skrll self.assertEquals(e.exception.err, -libfdt.NOTFOUND) 136 1.1 skrll 137 1.1 skrll node2 = self.fdt.path_offset('/subnode@1/subsubnode') 138 1.1 skrll self.assertEquals(self.fdt.subnode_offset(node1, 'subsubnode'), node2) 139 1.1 skrll 140 1.1 skrll def testPathOffset(self): 141 1.1 skrll """Check that we can find the offset of a node""" 142 1.1 skrll self.assertEquals(self.fdt.path_offset('/'), 0) 143 1.1 skrll self.assertTrue(self.fdt.path_offset('/subnode@1') > 0) 144 1.1 skrll with self.assertRaises(FdtException) as e: 145 1.1 skrll self.fdt.path_offset('/wibble') 146 1.1 skrll self.assertEquals(e.exception.err, -libfdt.NOTFOUND) 147 1.1 skrll self.assertEquals(self.fdt.path_offset('/wibble', QUIET_NOTFOUND), 148 1.1 skrll -libfdt.NOTFOUND) 149 1.1 skrll 150 1.1 skrll def testPropertyOffset(self): 151 1.1 skrll """Walk through all the properties in the root node""" 152 1.1 skrll offset = self.fdt.first_property_offset(0) 153 1.1 skrll self.assertTrue(offset > 0) 154 1.1 skrll for i in range(5): 155 1.1 skrll next_offset = self.fdt.next_property_offset(offset) 156 1.1 skrll self.assertTrue(next_offset > offset) 157 1.1 skrll offset = next_offset 158 1.1 skrll self.assertEquals(self.fdt.next_property_offset(offset, QUIET_NOTFOUND), 159 1.1 skrll -libfdt.NOTFOUND) 160 1.1 skrll 161 1.1 skrll def testPropertyOffsetExceptions(self): 162 1.1 skrll """Check that exceptions are raised as expected""" 163 1.1 skrll with self.assertRaises(FdtException) as e: 164 1.1 skrll self.fdt.first_property_offset(107) 165 1.1 skrll self.assertEquals(e.exception.err, -libfdt.BADOFFSET) 166 1.1 skrll 167 1.1 skrll # Quieten the NOTFOUND exception and check that a BADOFFSET 168 1.1 skrll # exception is still raised. 169 1.1 skrll with self.assertRaises(FdtException) as e: 170 1.1 skrll self.fdt.first_property_offset(107, QUIET_NOTFOUND) 171 1.1 skrll self.assertEquals(e.exception.err, -libfdt.BADOFFSET) 172 1.1 skrll with self.assertRaises(FdtException) as e: 173 1.1 skrll self.fdt.next_property_offset(107, QUIET_NOTFOUND) 174 1.1 skrll self.assertEquals(e.exception.err, -libfdt.BADOFFSET) 175 1.1 skrll 176 1.1 skrll # Check that NOTFOUND can be quietened. 177 1.1 skrll node = self.fdt.path_offset('/subnode@1/ss1') 178 1.1 skrll self.assertEquals(self.fdt.first_property_offset(node, QUIET_NOTFOUND), 179 1.1 skrll -libfdt.NOTFOUND) 180 1.1 skrll with self.assertRaises(FdtException) as e: 181 1.1 skrll self.fdt.first_property_offset(node) 182 1.1 skrll self.assertEquals(e.exception.err, -libfdt.NOTFOUND) 183 1.1 skrll 184 1.1 skrll def testGetName(self): 185 1.1 skrll """Check that we can get the name of a node""" 186 1.1 skrll self.assertEquals(self.fdt.get_name(0), '') 187 1.1 skrll node = self.fdt.path_offset('/subnode@1/subsubnode') 188 1.1 skrll self.assertEquals(self.fdt.get_name(node), 'subsubnode') 189 1.1 skrll 190 1.1 skrll with self.assertRaises(FdtException) as e: 191 1.1 skrll self.fdt.get_name(-2) 192 1.1 skrll self.assertEquals(e.exception.err, -libfdt.BADOFFSET) 193 1.1 skrll 194 1.1 skrll def testGetPropertyByOffset(self): 195 1.1 skrll """Check that we can read the name and contents of a property""" 196 1.1 skrll root = 0 197 1.1 skrll poffset = self.fdt.first_property_offset(root) 198 1.1 skrll prop = self.fdt.get_property_by_offset(poffset) 199 1.1 skrll self.assertEquals(prop.name, 'compatible') 200 1.1 skrll self.assertEquals(prop, b'test_tree1\0') 201 1.1 skrll 202 1.1 skrll with self.assertRaises(FdtException) as e: 203 1.1 skrll self.fdt.get_property_by_offset(-2) 204 1.1 skrll self.assertEquals(e.exception.err, -libfdt.BADOFFSET) 205 1.1 skrll self.assertEquals( 206 1.1 skrll -libfdt.BADOFFSET, 207 1.1 skrll self.fdt.get_property_by_offset(-2, [libfdt.BADOFFSET])) 208 1.1 skrll 209 1.1 skrll def testGetProp(self): 210 1.1 skrll """Check that we can read the contents of a property by name""" 211 1.1 skrll root = self.fdt.path_offset('/') 212 1.1 skrll value = self.fdt.getprop(root, "compatible") 213 1.1 skrll self.assertEquals(value, b'test_tree1\0') 214 1.1 skrll self.assertEquals(-libfdt.NOTFOUND, self.fdt.getprop(root, 'missing', 215 1.1 skrll QUIET_NOTFOUND)) 216 1.1 skrll 217 1.1 skrll with self.assertRaises(FdtException) as e: 218 1.1 skrll self.fdt.getprop(root, 'missing') 219 1.1 skrll self.assertEquals(e.exception.err, -libfdt.NOTFOUND) 220 1.1 skrll 221 1.1 skrll node = self.fdt.path_offset('/subnode@1/subsubnode') 222 1.1 skrll value = self.fdt.getprop(node, "compatible") 223 1.1 skrll self.assertEquals(value, b'subsubnode1\0subsubnode\0') 224 1.1 skrll 225 1.1 skrll def testStrError(self): 226 1.1 skrll """Check that we can get an error string""" 227 1.1 skrll self.assertEquals(libfdt.strerror(-libfdt.NOTFOUND), 228 1.1 skrll 'FDT_ERR_NOTFOUND') 229 1.1 skrll 230 1.1 skrll def testNextNodeOffset(self): 231 1.1 skrll """Check that we can walk through nodes""" 232 1.1 skrll node_list = [] 233 1.1 skrll node = 0 234 1.1 skrll depth = 0 235 1.1 skrll while depth >= 0: 236 1.1 skrll node_list.append([depth, self.fdt.get_name(node)]) 237 1.1 skrll node, depth = self.fdt.next_node(node, depth, (libfdt.BADOFFSET,)) 238 1.1 skrll self.assertEquals(node_list, [ 239 1.1 skrll [0, ''], 240 1.1 skrll [1, 'subnode@1'], 241 1.1 skrll [2, 'subsubnode'], 242 1.1 skrll [2, 'ss1'], 243 1.1 skrll [1, 'subnode@2'], 244 1.1 skrll [2, 'subsubnode@0'], 245 1.1 skrll [2, 'ss2'], 246 1.1 skrll ]) 247 1.1 skrll 248 1.1 skrll def testFirstNextSubnodeOffset(self): 249 1.1 skrll """Check that we can walk through subnodes""" 250 1.1 skrll node_list = [] 251 1.1 skrll node = self.fdt.first_subnode(0, QUIET_NOTFOUND) 252 1.1 skrll while node >= 0: 253 1.1 skrll node_list.append(self.fdt.get_name(node)) 254 1.1 skrll node = self.fdt.next_subnode(node, QUIET_NOTFOUND) 255 1.1 skrll self.assertEquals(node_list, ['subnode@1', 'subnode@2']) 256 1.1 skrll 257 1.1 skrll def testFirstNextSubnodeOffsetExceptions(self): 258 1.1 skrll """Check except handling for first/next subnode functions""" 259 1.1 skrll node = self.fdt.path_offset('/subnode@1/subsubnode', QUIET_NOTFOUND) 260 1.1 skrll self.assertEquals(self.fdt.first_subnode(node, QUIET_NOTFOUND), 261 1.1 skrll -libfdt.NOTFOUND) 262 1.1 skrll with self.assertRaises(FdtException) as e: 263 1.1 skrll self.fdt.first_subnode(node) 264 1.1 skrll self.assertEquals(e.exception.err, -libfdt.NOTFOUND) 265 1.1 skrll 266 1.1 skrll node = self.fdt.path_offset('/subnode@1/ss1', QUIET_NOTFOUND) 267 1.1 skrll self.assertEquals(self.fdt.next_subnode(node, QUIET_NOTFOUND), 268 1.1 skrll -libfdt.NOTFOUND) 269 1.1 skrll with self.assertRaises(FdtException) as e: 270 1.1 skrll self.fdt.next_subnode(node) 271 1.1 skrll self.assertEquals(e.exception.err, -libfdt.NOTFOUND) 272 1.1 skrll 273 1.1 skrll def testDeleteProperty(self): 274 1.1 skrll """Test that we can delete a property""" 275 1.1 skrll node_name = '/subnode@1' 276 1.1 skrll self.assertEquals(self.GetPropList(node_name), 277 1.1 skrll ['compatible', 'reg', 'prop-int']) 278 1.1 skrll node = self.fdt.path_offset('/%s' % node_name) 279 1.1 skrll self.assertEquals(self.fdt.delprop(node, 'reg'), 0) 280 1.1 skrll self.assertEquals(self.GetPropList(node_name), 281 1.1 skrll ['compatible', 'prop-int']) 282 1.1 skrll 283 1.1 skrll def testHeader(self): 284 1.1 skrll """Test that we can access the header values""" 285 1.1 skrll self.assertEquals(self.fdt.magic(), 0xd00dfeed) 286 1.1 skrll self.assertEquals(self.fdt.totalsize(), len(self.fdt._fdt)) 287 1.1 skrll self.assertEquals(self.fdt.off_dt_struct(), 88) 288 1.1 skrll self.assertEquals(self.fdt.off_dt_strings(), 652) 289 1.1 skrll self.assertEquals(self.fdt.off_mem_rsvmap(), 40) 290 1.1 skrll self.assertEquals(self.fdt.version(), 17) 291 1.1 skrll self.assertEquals(self.fdt.last_comp_version(), 16) 292 1.1 skrll self.assertEquals(self.fdt.boot_cpuid_phys(), 0) 293 1.1 skrll self.assertEquals(self.fdt.size_dt_strings(), 105) 294 1.1 skrll self.assertEquals(self.fdt.size_dt_struct(), 564) 295 1.1 skrll 296 1.1 skrll def testPack(self): 297 1.1 skrll """Test that we can pack the tree after deleting something""" 298 1.1 skrll orig_size = self.fdt.totalsize() 299 1.1 skrll node = self.fdt.path_offset('/subnode@2', QUIET_NOTFOUND) 300 1.1 skrll self.assertEquals(self.fdt.delprop(node, 'prop-int'), 0) 301 1.1 skrll self.assertEquals(orig_size, self.fdt.totalsize()) 302 1.1 skrll self.assertEquals(self.fdt.pack(), 0) 303 1.1 skrll self.assertTrue(self.fdt.totalsize() < orig_size) 304 1.1 skrll self.assertEquals(self.fdt.totalsize(), len(self.fdt.as_bytearray())) 305 1.1 skrll 306 1.1 skrll def testBadPropertyOffset(self): 307 1.1 skrll """Test that bad property offsets are detected""" 308 1.1 skrll with self.assertRaises(FdtException) as e: 309 1.1 skrll self.fdt.get_property_by_offset(13) 310 1.1 skrll self.assertEquals(e.exception.err, -libfdt.BADOFFSET) 311 1.1 skrll with self.assertRaises(FdtException) as e: 312 1.1 skrll self.fdt.first_property_offset(3) 313 1.1 skrll self.assertEquals(e.exception.err, -libfdt.BADOFFSET) 314 1.1 skrll with self.assertRaises(FdtException) as e: 315 1.1 skrll self.fdt.next_property_offset(3) 316 1.1 skrll self.assertEquals(e.exception.err, -libfdt.BADOFFSET) 317 1.1 skrll 318 1.1 skrll def testBadPathOffset(self): 319 1.1 skrll """Test that bad path names are detected""" 320 1.1 skrll with self.assertRaisesRegexp(FdtException, get_err(libfdt.BADPATH)): 321 1.1 skrll self.fdt.path_offset('not-present') 322 1.1 skrll 323 1.1 skrll def testQuietAll(self): 324 1.1 skrll """Check that exceptions can be masked by QUIET_ALL""" 325 1.1 skrll self.assertEquals(-libfdt.NOTFOUND, 326 1.1 skrll self.fdt.path_offset('/missing', QUIET_ALL)) 327 1.1 skrll self.assertEquals(-libfdt.BADOFFSET, 328 1.1 skrll self.fdt.get_property_by_offset(13, QUIET_ALL)) 329 1.1 skrll self.assertEquals(-libfdt.BADPATH, 330 1.1 skrll self.fdt.path_offset('missing', QUIET_ALL)) 331 1.1 skrll 332 1.1 skrll def testIntegers(self): 333 1.1 skrll """Check that integers can be passed and returned""" 334 1.1 skrll self.assertEquals(0, libfdt.fdt_get_phandle(self.fdt._fdt, 0)) 335 1.1 skrll node2 = self.fdt.path_offset('/subnode@2') 336 1.1 skrll self.assertEquals(0x2000, libfdt.fdt_get_phandle(self.fdt._fdt, node2)) 337 1.1 skrll 338 1.1 skrll def testGetPhandle(self): 339 1.1 skrll """Test for the get_phandle() method""" 340 1.1 skrll self.assertEquals(0, self.fdt.get_phandle(0)) 341 1.1 skrll node2 = self.fdt.path_offset('/subnode@2') 342 1.1 skrll self.assertEquals(0x2000, self.fdt.get_phandle(node2)) 343 1.1 skrll 344 1.1 skrll def testGetAlias(self): 345 1.1 skrll """Test for the get_alias() method""" 346 1.1 skrll self.assertEquals("/subnode@1", self.fdt3.get_alias('s1')) 347 1.1 skrll self.assertEquals("/subnode@1/subsubnode", self.fdt3.get_alias('ss1')) 348 1.1 skrll self.assertEquals("/subnode@1/subsubnode/subsubsubnode", self.fdt3.get_alias('sss1')) 349 1.1 skrll 350 1.1 skrll def testParentOffset(self): 351 1.1 skrll """Test for the parent_offset() method""" 352 1.1 skrll self.assertEquals(-libfdt.NOTFOUND, 353 1.1 skrll self.fdt.parent_offset(0, QUIET_NOTFOUND)) 354 1.1 skrll with self.assertRaises(FdtException) as e: 355 1.1 skrll self.fdt.parent_offset(0) 356 1.1 skrll self.assertEquals(e.exception.err, -libfdt.NOTFOUND) 357 1.1 skrll 358 1.1 skrll node1 = self.fdt.path_offset('/subnode@2') 359 1.1 skrll self.assertEquals(0, self.fdt.parent_offset(node1)) 360 1.1 skrll node2 = self.fdt.path_offset('/subnode@2/subsubnode@0') 361 1.1 skrll self.assertEquals(node1, self.fdt.parent_offset(node2)) 362 1.1 skrll 363 1.1 skrll def testNodeOffsetByPhandle(self): 364 1.1 skrll """Test for the node_offset_by_phandle() method""" 365 1.1 skrll self.assertEquals(-libfdt.NOTFOUND, 366 1.1 skrll self.fdt.node_offset_by_phandle(1, QUIET_NOTFOUND)) 367 1.1 skrll node1 = self.fdt.path_offset('/subnode@2') 368 1.1 skrll self.assertEquals(node1, self.fdt.node_offset_by_phandle(0x2000)) 369 1.1 skrll node2 = self.fdt.path_offset('/subnode@2/subsubnode@0') 370 1.1 skrll self.assertEquals(node2, self.fdt.node_offset_by_phandle(0x2001)) 371 1.1 skrll 372 1.1 skrll def get_prop(self, name): 373 1.1 skrll return self.fdt2.getprop(0, name) 374 1.1 skrll 375 1.1 skrll def testGetIntProperties(self): 376 1.1 skrll """Test that we can access properties as integers""" 377 1.1 skrll self.assertEquals(0xdeadbeef, self.get_prop("prop-hex32").as_uint32()) 378 1.1 skrll self.assertEquals(123, self.get_prop("prop-uint32").as_uint32()) 379 1.1 skrll self.assertEquals(-2, self.get_prop("prop-int32").as_int32()) 380 1.1 skrll self.assertEquals(9223372036854775807, 381 1.1 skrll self.get_prop("prop-uint64").as_uint64()) 382 1.1 skrll self.assertEquals(-2, self.get_prop("prop-int64").as_int64()) 383 1.1 skrll 384 1.1 skrll def testReserveMap(self): 385 1.1 skrll """Test that we can access the memory reserve map""" 386 1.1 skrll self.assertEquals(2, self.fdt.num_mem_rsv()) 387 1.1 skrll self.assertEquals([ 0xdeadbeef00000000, 0x100000], 388 1.1 skrll self.fdt.get_mem_rsv(0)) 389 1.1 skrll self.assertEquals([123456789, 0o10000], self.fdt.get_mem_rsv(1)) 390 1.1 skrll 391 1.1 skrll def testEmpty(self): 392 1.1 skrll """Test that we can create an empty tree""" 393 1.1 skrll self.assertEquals(-libfdt.NOSPACE, 394 1.1 skrll Fdt.create_empty_tree(1, (libfdt.NOSPACE,))) 395 1.1 skrll fdt = Fdt.create_empty_tree(128) 396 1.1 skrll self.assertEquals(128, fdt.totalsize()) 397 1.1 skrll 398 1.1 skrll def testOpenInto(self): 399 1.1 skrll """Test that we can resize a tree""" 400 1.1 skrll fdt = Fdt.create_empty_tree(128) 401 1.1 skrll self.assertEquals(128, fdt.totalsize()) 402 1.1 skrll fdt.resize(256) 403 1.1 skrll self.assertEquals(256, fdt.totalsize()) 404 1.1 skrll fdt.pack() 405 1.1 skrll self.assertTrue(fdt.totalsize() < 128) 406 1.1 skrll 407 1.1 skrll def testSetProp(self): 408 1.1 skrll """Test that we can update and create properties""" 409 1.1 skrll node = self.fdt.path_offset('/subnode@1') 410 1.1 skrll self.fdt.setprop(node, 'compatible', TEST_BYTES_1) 411 1.1 skrll self.assertEquals(TEST_BYTES_1, self.fdt.getprop(node, 'compatible')) 412 1.1 skrll 413 1.1 skrll # Check that this property is missing, and that we don't have space to 414 1.1 skrll # add it 415 1.1 skrll self.assertEquals(-libfdt.NOTFOUND, 416 1.1 skrll self.fdt.getprop(node, 'missing', QUIET_NOTFOUND)) 417 1.1 skrll self.assertEquals(-libfdt.NOSPACE, 418 1.1 skrll self.fdt.setprop(node, 'missing', TEST_BYTES_1, 419 1.1 skrll quiet=(libfdt.NOSPACE,))) 420 1.1 skrll 421 1.1 skrll # Expand the device tree so we now have room 422 1.1 skrll self.fdt.resize(self.fdt.totalsize() + 50) 423 1.1 skrll self.fdt.setprop(node, 'missing', TEST_BYTES_1) 424 1.1 skrll self.assertEquals(TEST_BYTES_1, self.fdt.getprop(node, 'missing')) 425 1.1 skrll 426 1.1 skrll def testSetPropU32(self): 427 1.1 skrll """Test that we can update and create integer properties""" 428 1.1 skrll node = 0 429 1.1 skrll prop = 'prop-int' 430 1.1 skrll self.fdt.setprop_u32(node, prop, TEST_VALUE_1) 431 1.1 skrll self.assertEquals(struct.pack('>I', TEST_VALUE_1), 432 1.1 skrll self.fdt.getprop(node, prop)) 433 1.1 skrll 434 1.1 skrll def testSetPropU64(self): 435 1.1 skrll """Test that we can update and create integer properties""" 436 1.1 skrll node = 0 437 1.1 skrll prop = 'prop-int64' 438 1.1 skrll self.fdt.setprop_u64(node, prop, TEST_VALUE64_1) 439 1.1 skrll self.assertEquals(struct.pack('>Q', TEST_VALUE64_1), 440 1.1 skrll self.fdt.getprop(node, prop)) 441 1.1 skrll 442 1.1 skrll def testSetPropStr(self): 443 1.1 skrll """Test that we can set a property to a particular string""" 444 1.1 skrll node = 0 445 1.1 skrll prop = 'prop-str' 446 1.1 skrll self.assertEquals(TEST_STRING_1, self.fdt.getprop(node, prop).as_str()) 447 1.1 skrll self.fdt.setprop_str(node, prop, TEST_STRING_2) 448 1.1 skrll self.assertEquals(TEST_STRING_2, self.fdt.getprop(node, prop).as_str()) 449 1.1 skrll with self.assertRaises(ValueError) as e: 450 1.1 skrll self.fdt.getprop(node, 'prop-int').as_str() 451 1.1 skrll self.assertIn('lacks nul termination', str(e.exception)) 452 1.1 skrll 453 1.1 skrll node2 = self.fdt.path_offset('/subnode@1/subsubnode') 454 1.1 skrll with self.assertRaises(ValueError) as e: 455 1.1 skrll self.fdt.getprop(node2, 'compatible').as_str() 456 1.1 skrll self.assertIn('embedded nul', str(e.exception)) 457 1.1 skrll 458 1.1 skrll # Expand the device tree so we now have room 459 1.1 skrll self.fdt.resize(self.fdt.totalsize() + 50) 460 1.1 skrll prop = 'prop-unicode' 461 1.1 skrll self.fdt.setprop_str(node, prop, TEST_STRING_3) 462 1.1 skrll self.assertEquals(TEST_STRING_3, 463 1.1 skrll self.fdt.getprop(node, prop).as_str()) 464 1.1 skrll 465 1.1 skrll def testSetName(self): 466 1.1 skrll """Test that we can update a node name""" 467 1.1 skrll node = self.fdt.path_offset('/subnode@1') 468 1.1 skrll old_val = self.fdt.get_name(node) 469 1.1 skrll self.fdt.set_name(node, 'test') 470 1.1 skrll self.assertEquals('test', self.fdt.get_name(node)) 471 1.1 skrll 472 1.1 skrll with self.assertRaises(ValueError) as e: 473 1.1 skrll self.fdt.set_name(node, 'some\0name') 474 1.1 skrll self.assertIn('embedded nul', str(e.exception)) 475 1.1 skrll 476 1.1 skrll with self.assertRaises(ValueError) as e: 477 1.1 skrll self.fdt.set_name(node, 'name\0') 478 1.1 skrll self.assertIn('embedded nul', str(e.exception)) 479 1.1 skrll 480 1.1 skrll def testAddDeleteNodes(self): 481 1.1 skrll """Test that we can add and delete nodes""" 482 1.1 skrll node_name = '/subnode@1' 483 1.1 skrll self.assertEquals(self.GetSubnodes(node_name), ['subsubnode', 'ss1']) 484 1.1 skrll node = self.fdt.path_offset('%s/subsubnode' % node_name) 485 1.1 skrll self.assertEquals(self.fdt.del_node(node, 'subsubnode'), 0) 486 1.1 skrll self.assertEquals(self.GetSubnodes(node_name), ['ss1']) 487 1.1 skrll 488 1.1 skrll node = self.fdt.path_offset(node_name) 489 1.1 skrll offset = self.fdt.add_subnode(node, 'more') 490 1.1 skrll self.assertTrue(offset > 0) 491 1.1 skrll self.assertEquals(self.GetSubnodes(node_name), ['more', 'ss1']) 492 1.1 skrll 493 1.1 skrll 494 1.1 skrll class PyLibfdtSwTests(unittest.TestCase): 495 1.1 skrll """Test class for pylibfdt sequential-write DT creation 496 1.1 skrll """ 497 1.1 skrll def assertOk(self, err_code): 498 1.1 skrll self.assertEquals(0, err_code) 499 1.1 skrll 500 1.1 skrll def testCreate(self): 501 1.1 skrll # First check the minimum size and also the FdtSw() constructor 502 1.1 skrll with self.assertRaisesRegexp(FdtException, get_err(libfdt.NOSPACE)): 503 1.1 skrll self.assertEquals(-libfdt.NOSPACE, FdtSw(3)) 504 1.1 skrll 505 1.1 skrll sw = FdtSw() 506 1.1 skrll sw.add_reservemap_entry(TEST_ADDR_1, TEST_SIZE_1) 507 1.1 skrll sw.add_reservemap_entry(TEST_ADDR_2, TEST_SIZE_2) 508 1.1 skrll sw.finish_reservemap() 509 1.1 skrll 510 1.1 skrll sw.begin_node('') 511 1.1 skrll sw.property_string('compatible', 'test_tree1') 512 1.1 skrll sw.property_u32('prop-int', TEST_VALUE_1) 513 1.1 skrll 514 1.1 skrll sw.property_u32('prop-int', TEST_VALUE_1) 515 1.1 skrll sw.property_u64('prop-int64', TEST_VALUE64_1) 516 1.1 skrll sw.property_string('prop-str', TEST_STRING_1) 517 1.1 skrll sw.property_u32('#address-cells', 1) 518 1.1 skrll sw.property_u32('#size-cells', 0) 519 1.1 skrll 520 1.1 skrll sw.begin_node('subnode@1') 521 1.1 skrll sw.property_string('compatible', 'subnode1') 522 1.1 skrll sw.property_u32('reg', 1) 523 1.1 skrll sw.property_cell('prop-int', TEST_VALUE_1) 524 1.1 skrll sw.begin_node('subsubnode') 525 1.1 skrll sw.property('compatible', 'subsubnode1\0subsubnode') 526 1.1 skrll sw.property_cell('prop-int', TEST_VALUE_1) 527 1.1 skrll sw.end_node() 528 1.1 skrll sw.begin_node('ss1') 529 1.1 skrll sw.end_node() 530 1.1 skrll sw.end_node() 531 1.1 skrll 532 1.1 skrll for i in range(2, 11): 533 1.1 skrll with sw.add_node('subnode@%d' % i): 534 1.1 skrll sw.property_u32('reg', 2) 535 1.1 skrll sw.property_cell('linux,phandle', PHANDLE_1) 536 1.1 skrll sw.property_cell('prop-int', TEST_VALUE_2) 537 1.1 skrll sw.property_u32('#address-cells', 1) 538 1.1 skrll sw.property_u32('#size-cells', 0) 539 1.1 skrll with sw.add_node('subsubnode@0'): 540 1.1 skrll sw.property_u32('reg', 0) 541 1.1 skrll sw.property_cell('phandle', PHANDLE_2) 542 1.1 skrll sw.property('compatible', 'subsubnode2\0subsubnode') 543 1.1 skrll sw.property_cell('prop-int', TEST_VALUE_2) 544 1.1 skrll with sw.add_node('ss2'): 545 1.1 skrll pass 546 1.1 skrll sw.end_node() 547 1.1 skrll 548 1.1 skrll fdt = sw.as_fdt() 549 1.1 skrll self.assertEqual(2, fdt.num_mem_rsv()) 550 1.1 skrll self.assertEqual([TEST_ADDR_1, TEST_SIZE_1], fdt.get_mem_rsv(0)) 551 1.1 skrll 552 1.1 skrll # Make sure we can add a few more things 553 1.1 skrll with sw.add_node('another'): 554 1.1 skrll sw.property_u32('reg', 3) 555 1.1 skrll 556 1.1 skrll # Make sure we can read from the tree too 557 1.1 skrll node = sw.path_offset('/subnode@1') 558 1.1 skrll self.assertEqual(b'subnode1\0', sw.getprop(node, 'compatible')) 559 1.1 skrll 560 1.1 skrll # Make sure we did at least two resizes 561 1.1 skrll self.assertTrue(len(fdt.as_bytearray()) > FdtSw.INC_SIZE * 2) 562 1.1 skrll 563 1.1 skrll 564 1.1 skrll class PyLibfdtRoTests(unittest.TestCase): 565 1.1 skrll """Test class for read-only pylibfdt access functions 566 1.1 skrll 567 1.1 skrll This just tests a few simple cases. Most of the tests are in 568 1.1 skrll PyLibfdtBasicTests. 569 1.1 skrll 570 1.1 skrll Properties: 571 1.1 skrll fdt: Device tree file used for testing 572 1.1 skrll """ 573 1.1 skrll 574 1.1 skrll def setUp(self): 575 1.1 skrll """Read in the device tree we use for testing""" 576 1.1 skrll self.fdt = libfdt.FdtRo(open('test_tree1.dtb', mode='rb').read()) 577 1.1 skrll 578 1.1 skrll def testAccess(self): 579 1.1 skrll """Basic sanity check for the FdtRo class""" 580 1.1 skrll node = self.fdt.path_offset('/subnode@1') 581 1.1 skrll self.assertEqual(b'subnode1\0', 582 1.1 skrll self.fdt.getprop(node, 'compatible')) 583 1.1 skrll node = self.fdt.first_subnode(node) 584 1.1 skrll self.assertEqual(b'this is a placeholder string\0string2\0', 585 1.1 skrll self.fdt.getprop(node, 'placeholder')) 586 1.1 skrll 587 1.1 skrll 588 1.1 skrll if __name__ == "__main__": 589 1.1 skrll unittest.main() 590