blob: e0271646ed475cb8ed4f88fc5243b69830c7941e [file] [log] [blame]
Alice Wang9d4df702023-05-25 14:14:12 +00001/*
2 * Copyright (C) 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//! Integration tests of the library libfdt.
18
Jaewan Kima041d4b2023-11-10 13:38:11 +090019use core::ffi::CStr;
Jaewan Kimf163d762023-11-01 13:12:50 +090020use libfdt::{Fdt, FdtError, FdtNodeMut, Phandle};
Jaewan Kime6363422024-01-19 14:00:00 +090021use std::collections::HashSet;
Pierre-Clément Tosi180a7c22023-11-07 09:54:39 +000022use std::ffi::CString;
Alice Wang9d4df702023-05-25 14:14:12 +000023use std::fs;
24use std::ops::Range;
25
Alice Wang2422bdc2023-06-12 08:37:55 +000026const TEST_TREE_WITH_ONE_MEMORY_RANGE_PATH: &str = "data/test_tree_one_memory_range.dtb";
27const TEST_TREE_WITH_MULTIPLE_MEMORY_RANGES_PATH: &str =
28 "data/test_tree_multiple_memory_ranges.dtb";
29const TEST_TREE_WITH_EMPTY_MEMORY_RANGE_PATH: &str = "data/test_tree_empty_memory_range.dtb";
30const TEST_TREE_WITH_NO_MEMORY_NODE_PATH: &str = "data/test_tree_no_memory_node.dtb";
Jaewan Kim17ba7a32023-10-19 13:25:15 +090031const TEST_TREE_PHANDLE_PATH: &str = "data/test_tree_phandle.dtb";
Alice Wang9d4df702023-05-25 14:14:12 +000032
33#[test]
Alice Wang2422bdc2023-06-12 08:37:55 +000034fn retrieving_memory_from_fdt_with_one_memory_range_succeeds() {
35 let data = fs::read(TEST_TREE_WITH_ONE_MEMORY_RANGE_PATH).unwrap();
Alice Wang9d4df702023-05-25 14:14:12 +000036 let fdt = Fdt::from_slice(&data).unwrap();
37
38 const EXPECTED_FIRST_MEMORY_RANGE: Range<usize> = 0..256;
Alice Wang2422bdc2023-06-12 08:37:55 +000039 let mut memory = fdt.memory().unwrap();
Alice Wang9d4df702023-05-25 14:14:12 +000040 assert_eq!(memory.next(), Some(EXPECTED_FIRST_MEMORY_RANGE));
Pierre-Clément Tosi504b4302023-10-30 12:22:50 +000041 assert_eq!(memory.next(), None);
Alice Wang2422bdc2023-06-12 08:37:55 +000042 assert_eq!(fdt.first_memory_range(), Ok(EXPECTED_FIRST_MEMORY_RANGE));
43}
44
45#[test]
46fn retrieving_memory_from_fdt_with_multiple_memory_ranges_succeeds() {
47 let data = fs::read(TEST_TREE_WITH_MULTIPLE_MEMORY_RANGES_PATH).unwrap();
48 let fdt = Fdt::from_slice(&data).unwrap();
49
50 const EXPECTED_FIRST_MEMORY_RANGE: Range<usize> = 0..256;
51 const EXPECTED_SECOND_MEMORY_RANGE: Range<usize> = 512..1024;
52 let mut memory = fdt.memory().unwrap();
53 assert_eq!(memory.next(), Some(EXPECTED_FIRST_MEMORY_RANGE));
54 assert_eq!(memory.next(), Some(EXPECTED_SECOND_MEMORY_RANGE));
Pierre-Clément Tosi504b4302023-10-30 12:22:50 +000055 assert_eq!(memory.next(), None);
Alice Wang2422bdc2023-06-12 08:37:55 +000056 assert_eq!(fdt.first_memory_range(), Ok(EXPECTED_FIRST_MEMORY_RANGE));
57}
58
59#[test]
60fn retrieving_first_memory_from_fdt_with_empty_memory_range_fails() {
61 let data = fs::read(TEST_TREE_WITH_EMPTY_MEMORY_RANGE_PATH).unwrap();
62 let fdt = Fdt::from_slice(&data).unwrap();
63
64 let mut memory = fdt.memory().unwrap();
Pierre-Clément Tosi504b4302023-10-30 12:22:50 +000065 assert_eq!(memory.next(), None);
Alice Wang2422bdc2023-06-12 08:37:55 +000066 assert_eq!(fdt.first_memory_range(), Err(FdtError::NotFound));
67}
68
69#[test]
70fn retrieving_memory_from_fdt_with_no_memory_node_fails() {
71 let data = fs::read(TEST_TREE_WITH_NO_MEMORY_NODE_PATH).unwrap();
72 let fdt = Fdt::from_slice(&data).unwrap();
73
74 assert_eq!(fdt.memory().unwrap_err(), FdtError::NotFound);
75 assert_eq!(fdt.first_memory_range(), Err(FdtError::NotFound));
Alice Wang9d4df702023-05-25 14:14:12 +000076}
Jaewan Kimaa638702023-09-19 13:34:01 +090077
78#[test]
79fn node_name() {
80 let data = fs::read(TEST_TREE_WITH_NO_MEMORY_NODE_PATH).unwrap();
81 let fdt = Fdt::from_slice(&data).unwrap();
82
Pierre-Clément Tosi244efea2024-02-16 14:48:14 +000083 let root = fdt.root();
Alan Stokesf46a17c2025-01-05 15:50:18 +000084 assert_eq!(root.name(), Ok(c""));
Jaewan Kimaa638702023-09-19 13:34:01 +090085
86 let chosen = fdt.chosen().unwrap().unwrap();
Alan Stokesf46a17c2025-01-05 15:50:18 +000087 assert_eq!(chosen.name(), Ok(c"chosen"));
Jaewan Kimaa638702023-09-19 13:34:01 +090088
Alan Stokesf46a17c2025-01-05 15:50:18 +000089 let nested_node_path = c"/cpus/PowerPC,970@0";
Jaewan Kimaa638702023-09-19 13:34:01 +090090 let nested_node = fdt.node(nested_node_path).unwrap().unwrap();
Alan Stokesf46a17c2025-01-05 15:50:18 +000091 assert_eq!(nested_node.name(), Ok(c"PowerPC,970@0"));
Jaewan Kimaa638702023-09-19 13:34:01 +090092}
Jaewan Kimbc828d72023-09-19 15:52:08 +090093
94#[test]
95fn node_subnodes() {
96 let data = fs::read(TEST_TREE_WITH_NO_MEMORY_NODE_PATH).unwrap();
97 let fdt = Fdt::from_slice(&data).unwrap();
Pierre-Clément Tosi244efea2024-02-16 14:48:14 +000098 let root = fdt.root();
Alan Stokesf46a17c2025-01-05 15:50:18 +000099 let expected = [Ok(c"cpus"), Ok(c"randomnode"), Ok(c"chosen")];
Jaewan Kimbc828d72023-09-19 15:52:08 +0900100
Jaewan Kima041d4b2023-11-10 13:38:11 +0900101 let root_subnodes = root.subnodes().unwrap();
102 let subnode_names: Vec<_> = root_subnodes.map(|node| node.name()).collect();
103 assert_eq!(subnode_names, expected);
Jaewan Kimbc828d72023-09-19 15:52:08 +0900104}
Jaewan Kim72d10902023-10-12 21:59:26 +0900105
106#[test]
107fn node_properties() {
108 let data = fs::read(TEST_TREE_WITH_NO_MEMORY_NODE_PATH).unwrap();
109 let fdt = Fdt::from_slice(&data).unwrap();
Pierre-Clément Tosi244efea2024-02-16 14:48:14 +0000110 let root = fdt.root();
Jaewan Kim72d10902023-10-12 21:59:26 +0900111 let one_be = 0x1_u32.to_be_bytes();
Jaewan Kima041d4b2023-11-10 13:38:11 +0900112 type Result<T> = core::result::Result<T, FdtError>;
113 let expected: Vec<(Result<&CStr>, Result<&[u8]>)> = vec![
Alan Stokesf46a17c2025-01-05 15:50:18 +0000114 (Ok(c"model"), Ok(b"MyBoardName\0".as_ref())),
115 (Ok(c"compatible"), Ok(b"MyBoardName\0MyBoardFamilyName\0".as_ref())),
116 (Ok(c"#address-cells"), Ok(&one_be)),
117 (Ok(c"#size-cells"), Ok(&one_be)),
118 (Ok(c"empty_prop"), Ok(&[])),
Jaewan Kim72d10902023-10-12 21:59:26 +0900119 ];
120
Pierre-Clément Tosi504b4302023-10-30 12:22:50 +0000121 let properties = root.properties().unwrap();
Jaewan Kima041d4b2023-11-10 13:38:11 +0900122 let subnode_properties: Vec<_> = properties.map(|prop| (prop.name(), prop.value())).collect();
123
124 assert_eq!(subnode_properties, expected);
Jaewan Kim72d10902023-10-12 21:59:26 +0900125}
Jaewan Kim5b057772023-10-19 01:02:17 +0900126
127#[test]
128fn node_supernode_at_depth() {
129 let data = fs::read(TEST_TREE_WITH_NO_MEMORY_NODE_PATH).unwrap();
130 let fdt = Fdt::from_slice(&data).unwrap();
Alan Stokesf46a17c2025-01-05 15:50:18 +0000131 let node = fdt.node(c"/cpus/PowerPC,970@1").unwrap().unwrap();
132 let expected = vec![Ok(c""), Ok(c"cpus"), Ok(c"PowerPC,970@1")];
Jaewan Kim5b057772023-10-19 01:02:17 +0900133
Jaewan Kima041d4b2023-11-10 13:38:11 +0900134 let mut supernode_names = vec![];
135 let mut depth = 0;
136 while let Ok(supernode) = node.supernode_at_depth(depth) {
137 supernode_names.push(supernode.name());
138 depth += 1;
Jaewan Kim5b057772023-10-19 01:02:17 +0900139 }
Jaewan Kima041d4b2023-11-10 13:38:11 +0900140
141 assert_eq!(supernode_names, expected);
Jaewan Kim5b057772023-10-19 01:02:17 +0900142}
Jaewan Kim17ba7a32023-10-19 13:25:15 +0900143
144#[test]
145fn phandle_new() {
Pierre-Clément Tosieba27792023-10-30 12:04:12 +0000146 let valid_phandles = [
147 u32::from(Phandle::MIN),
148 u32::from(Phandle::MIN).checked_add(1).unwrap(),
149 0x55,
150 u32::from(Phandle::MAX).checked_sub(1).unwrap(),
151 u32::from(Phandle::MAX),
152 ];
Jaewan Kim17ba7a32023-10-19 13:25:15 +0900153
Pierre-Clément Tosieba27792023-10-30 12:04:12 +0000154 for value in valid_phandles {
155 let phandle = Phandle::new(value).unwrap();
156
157 assert_eq!(value.try_into(), Ok(phandle));
158 assert_eq!(u32::from(phandle), value);
159 }
160
161 let bad_phandles = [
162 u32::from(Phandle::MIN).checked_sub(1).unwrap(),
163 u32::from(Phandle::MAX).checked_add(1).unwrap(),
164 ];
165
166 for value in bad_phandles {
167 assert_eq!(Phandle::new(value), None);
168 assert_eq!(Phandle::try_from(value), Err(FdtError::BadPhandle));
169 }
Jaewan Kim17ba7a32023-10-19 13:25:15 +0900170}
171
172#[test]
173fn max_phandle() {
174 let data = fs::read(TEST_TREE_PHANDLE_PATH).unwrap();
175 let fdt = Fdt::from_slice(&data).unwrap();
Pierre-Clément Tosi504b4302023-10-30 12:22:50 +0000176 let phandle = Phandle::new(0xFF).unwrap();
Jaewan Kim17ba7a32023-10-19 13:25:15 +0900177
Pierre-Clément Tosi504b4302023-10-30 12:22:50 +0000178 assert_eq!(fdt.max_phandle(), Ok(phandle));
Jaewan Kim17ba7a32023-10-19 13:25:15 +0900179}
180
181#[test]
182fn node_with_phandle() {
183 let data = fs::read(TEST_TREE_PHANDLE_PATH).unwrap();
184 let fdt = Fdt::from_slice(&data).unwrap();
185
186 // Test linux,phandle
Pierre-Clément Tosi504b4302023-10-30 12:22:50 +0000187 let phandle = Phandle::new(0xFF).unwrap();
188 let node = fdt.node_with_phandle(phandle).unwrap().unwrap();
Alan Stokesf46a17c2025-01-05 15:50:18 +0000189 assert_eq!(node.name(), Ok(c"node_zz"));
Jaewan Kim17ba7a32023-10-19 13:25:15 +0900190
191 // Test phandle
Pierre-Clément Tosi504b4302023-10-30 12:22:50 +0000192 let phandle = Phandle::new(0x22).unwrap();
193 let node = fdt.node_with_phandle(phandle).unwrap().unwrap();
Alan Stokesf46a17c2025-01-05 15:50:18 +0000194 assert_eq!(node.name(), Ok(c"node_abc"));
Jaewan Kim17ba7a32023-10-19 13:25:15 +0900195}
Jaewan Kim4ae0e712023-10-19 14:16:17 +0900196
197#[test]
Jaewan Kimc63246d2023-11-09 15:41:01 +0900198fn node_mut_with_phandle() {
199 let mut data = fs::read(TEST_TREE_PHANDLE_PATH).unwrap();
200 let fdt = Fdt::from_mut_slice(&mut data).unwrap();
201
202 // Test linux,phandle
203 let phandle = Phandle::new(0xFF).unwrap();
204 let node: FdtNodeMut = fdt.node_mut_with_phandle(phandle).unwrap().unwrap();
Alan Stokesf46a17c2025-01-05 15:50:18 +0000205 assert_eq!(node.as_node().name(), Ok(c"node_zz"));
Jaewan Kimc63246d2023-11-09 15:41:01 +0900206
207 // Test phandle
208 let phandle = Phandle::new(0x22).unwrap();
209 let node: FdtNodeMut = fdt.node_mut_with_phandle(phandle).unwrap().unwrap();
Alan Stokesf46a17c2025-01-05 15:50:18 +0000210 assert_eq!(node.as_node().name(), Ok(c"node_abc"));
Jaewan Kimc63246d2023-11-09 15:41:01 +0900211}
212
213#[test]
Jaewan Kimf34f4b82023-11-03 19:38:38 +0900214fn node_get_phandle() {
215 let data = fs::read(TEST_TREE_PHANDLE_PATH).unwrap();
216 let fdt = Fdt::from_slice(&data).unwrap();
217
218 // Test linux,phandle
Alan Stokesf46a17c2025-01-05 15:50:18 +0000219 let node = fdt.node(c"/node_z/node_zz").unwrap().unwrap();
Jaewan Kimf34f4b82023-11-03 19:38:38 +0900220 assert_eq!(node.get_phandle(), Ok(Phandle::new(0xFF)));
221
222 // Test phandle
Alan Stokesf46a17c2025-01-05 15:50:18 +0000223 let node = fdt.node(c"/node_a/node_ab/node_abc").unwrap().unwrap();
Jaewan Kimf34f4b82023-11-03 19:38:38 +0900224 assert_eq!(node.get_phandle(), Ok(Phandle::new(0x22)));
225
226 // Test no phandle
Alan Stokesf46a17c2025-01-05 15:50:18 +0000227 let node = fdt.node(c"/node_b").unwrap().unwrap();
Jaewan Kimf34f4b82023-11-03 19:38:38 +0900228 assert_eq!(node.get_phandle(), Ok(None));
229}
230
231#[test]
Jaewan Kim4ae0e712023-10-19 14:16:17 +0900232fn node_nop() {
233 let mut data = fs::read(TEST_TREE_PHANDLE_PATH).unwrap();
234 let fdt = Fdt::from_mut_slice(&mut data).unwrap();
Pierre-Clément Tosi504b4302023-10-30 12:22:50 +0000235 let phandle = Phandle::new(0xFF).unwrap();
Alan Stokesf46a17c2025-01-05 15:50:18 +0000236 let path = c"/node_z/node_zz";
Jaewan Kim4ae0e712023-10-19 14:16:17 +0900237
Pierre-Clément Tosi504b4302023-10-30 12:22:50 +0000238 fdt.node_with_phandle(phandle).unwrap().unwrap();
239 let node = fdt.node_mut(path).unwrap().unwrap();
Jaewan Kim4ae0e712023-10-19 14:16:17 +0900240
241 node.nop().unwrap();
242
Pierre-Clément Tosi504b4302023-10-30 12:22:50 +0000243 assert_eq!(fdt.node_with_phandle(phandle), Ok(None));
244 assert_eq!(fdt.node(path), Ok(None));
Jaewan Kim4ae0e712023-10-19 14:16:17 +0900245
246 fdt.unpack().unwrap();
247 fdt.pack().unwrap();
248
Pierre-Clément Tosi504b4302023-10-30 12:22:50 +0000249 assert_eq!(fdt.node_with_phandle(phandle), Ok(None));
250 assert_eq!(fdt.node(path), Ok(None));
Jaewan Kim4ae0e712023-10-19 14:16:17 +0900251}
Jaewan Kim5ab13582023-10-20 20:56:27 +0900252
253#[test]
254fn node_add_subnode_with_namelen() {
255 let mut data = fs::read(TEST_TREE_PHANDLE_PATH).unwrap();
256 data.resize(data.len() * 2, 0_u8);
257
258 let fdt = Fdt::from_mut_slice(&mut data).unwrap();
259 fdt.unpack().unwrap();
260
Alan Stokesf46a17c2025-01-05 15:50:18 +0000261 let node_path = c"/node_z/node_zz";
262 let subnode_name = c"123456789";
Jaewan Kim5ab13582023-10-20 20:56:27 +0900263
264 for len in 0..subnode_name.to_bytes().len() {
Jaewan Kim52026012023-12-13 13:49:28 +0900265 let name = &subnode_name.to_bytes()[0..len];
266 let node = fdt.node(node_path).unwrap().unwrap();
267 assert_eq!(Ok(None), node.subnode_with_name_bytes(name));
Jaewan Kim5ab13582023-10-20 20:56:27 +0900268
Pierre-Clément Tosia3c4ec32024-02-15 20:05:15 +0000269 let node = fdt.node_mut(node_path).unwrap().unwrap();
270 let _ = node.add_subnode_with_namelen(subnode_name, len).unwrap();
Jaewan Kim5ab13582023-10-20 20:56:27 +0900271
Jaewan Kim52026012023-12-13 13:49:28 +0900272 let node = fdt.node(node_path).unwrap().unwrap();
273 assert_ne!(Ok(None), node.subnode_with_name_bytes(name));
Jaewan Kim5ab13582023-10-20 20:56:27 +0900274 }
275
276 let node_path = node_path.to_str().unwrap();
277 for len in 1..subnode_name.to_bytes().len() {
278 let name = String::from_utf8(subnode_name.to_bytes()[..len].to_vec()).unwrap();
279 let path = CString::new(format!("{node_path}/{name}")).unwrap();
Pierre-Clément Tosi504b4302023-10-30 12:22:50 +0000280 let name = CString::new(name).unwrap();
Jaewan Kim5ab13582023-10-20 20:56:27 +0900281 let subnode = fdt.node(&path).unwrap().unwrap();
Pierre-Clément Tosi504b4302023-10-30 12:22:50 +0000282 assert_eq!(subnode.name(), Ok(name.as_c_str()));
Jaewan Kim5ab13582023-10-20 20:56:27 +0900283 }
284}
Jaewan Kimf163d762023-11-01 13:12:50 +0900285
286#[test]
Jaewan Kim52026012023-12-13 13:49:28 +0900287fn node_subnode() {
288 let data = fs::read(TEST_TREE_PHANDLE_PATH).unwrap();
289 let fdt = Fdt::from_slice(&data).unwrap();
290
Alan Stokesf46a17c2025-01-05 15:50:18 +0000291 let name = c"node_a";
Pierre-Clément Tosi244efea2024-02-16 14:48:14 +0000292 let root = fdt.root();
Jaewan Kim52026012023-12-13 13:49:28 +0900293 let node = root.subnode(name).unwrap();
294 assert_ne!(None, node);
295 let node = node.unwrap();
296
297 assert_eq!(Ok(name), node.name());
298}
299
300#[test]
301fn node_subnode_with_name_bytes() {
302 let data = fs::read(TEST_TREE_PHANDLE_PATH).unwrap();
303 let fdt = Fdt::from_slice(&data).unwrap();
304
305 let name = b"node_aaaaa";
Pierre-Clément Tosi244efea2024-02-16 14:48:14 +0000306 let root = fdt.root();
Jaewan Kim52026012023-12-13 13:49:28 +0900307 let node = root.subnode_with_name_bytes(&name[0..6]).unwrap();
308 assert_ne!(None, node);
309 let node = node.unwrap();
310
Alan Stokesf46a17c2025-01-05 15:50:18 +0000311 assert_eq!(Ok(c"node_a"), node.name());
Jaewan Kim52026012023-12-13 13:49:28 +0900312}
313
314#[test]
315fn node_subnode_borrow_checker() {
316 let data = fs::read(TEST_TREE_PHANDLE_PATH).unwrap();
317 let fdt = Fdt::from_slice(&data).unwrap();
318
Alan Stokesf46a17c2025-01-05 15:50:18 +0000319 let name = c"node_a";
Jaewan Kim52026012023-12-13 13:49:28 +0900320 let node = {
Pierre-Clément Tosi244efea2024-02-16 14:48:14 +0000321 let root = fdt.root();
Jaewan Kim52026012023-12-13 13:49:28 +0900322 root.subnode(name).unwrap().unwrap()
323 };
324
325 assert_eq!(Ok(name), node.name());
326}
327
328#[test]
Jaewan Kimf163d762023-11-01 13:12:50 +0900329fn fdt_symbols() {
330 let mut data = fs::read(TEST_TREE_PHANDLE_PATH).unwrap();
331 let fdt = Fdt::from_mut_slice(&mut data).unwrap();
332
333 let symbols = fdt.symbols().unwrap().unwrap();
Alan Stokesf46a17c2025-01-05 15:50:18 +0000334 assert_eq!(symbols.name(), Ok(c"__symbols__"));
Jaewan Kimf163d762023-11-01 13:12:50 +0900335
336 // Validates type.
337 let _symbols: FdtNodeMut = fdt.symbols_mut().unwrap().unwrap();
338}
Jaewan Kimf72f4f22023-11-03 19:21:34 +0900339
340#[test]
341fn node_mut_as_node() {
342 let mut data = fs::read(TEST_TREE_WITH_ONE_MEMORY_RANGE_PATH).unwrap();
343 let fdt = Fdt::from_mut_slice(&mut data).unwrap();
344
Alan Stokesf46a17c2025-01-05 15:50:18 +0000345 let mut memory = fdt.node_mut(c"/memory").unwrap().unwrap();
Jaewan Kimf72f4f22023-11-03 19:21:34 +0900346 {
347 let memory = memory.as_node();
Alan Stokesf46a17c2025-01-05 15:50:18 +0000348 assert_eq!(memory.name(), Ok(c"memory"));
Jaewan Kimf72f4f22023-11-03 19:21:34 +0900349 }
350
351 // Just check whether borrow checker doesn't complain this.
Alan Stokesf46a17c2025-01-05 15:50:18 +0000352 memory.setprop_inplace(c"device_type", b"MEMORY\0").unwrap();
Jaewan Kimf72f4f22023-11-03 19:21:34 +0900353}
Jaewan Kimc9e14112023-12-04 17:05:27 +0900354
355#[test]
356fn node_descendants() {
357 let mut data = fs::read(TEST_TREE_PHANDLE_PATH).unwrap();
358 let fdt = Fdt::from_mut_slice(&mut data).unwrap();
359
Alan Stokesf46a17c2025-01-05 15:50:18 +0000360 let node_z = fdt.node(c"/node_z").unwrap().unwrap();
Jaewan Kimc9e14112023-12-04 17:05:27 +0900361 let descendants: Vec<_> =
362 node_z.descendants().map(|(node, depth)| (node.name().unwrap(), depth)).collect();
363
364 assert_eq!(
365 descendants,
Alan Stokesf46a17c2025-01-05 15:50:18 +0000366 vec![(c"node_za", 1), (c"node_zb", 1), (c"node_zz", 1), (c"node_zzz", 2)]
Jaewan Kimc9e14112023-12-04 17:05:27 +0900367 );
368}
Jaewan Kim5f1a6032023-12-18 15:17:58 +0900369
370#[test]
371fn node_mut_delete_and_next_subnode() {
372 let mut data = fs::read(TEST_TREE_PHANDLE_PATH).unwrap();
373 let fdt = Fdt::from_mut_slice(&mut data).unwrap();
374
Pierre-Clément Tosi244efea2024-02-16 14:48:14 +0000375 let root = fdt.root_mut();
Jaewan Kim5f1a6032023-12-18 15:17:58 +0900376 let mut subnode_iter = root.first_subnode().unwrap();
377
378 while let Some(subnode) = subnode_iter {
Alan Stokesf46a17c2025-01-05 15:50:18 +0000379 if subnode.as_node().name() == Ok(c"node_z") {
Jaewan Kim5f1a6032023-12-18 15:17:58 +0900380 subnode_iter = subnode.delete_and_next_subnode().unwrap();
381 } else {
382 subnode_iter = subnode.next_subnode().unwrap();
383 }
384 }
385
Pierre-Clément Tosi244efea2024-02-16 14:48:14 +0000386 let root = fdt.root();
Alan Stokesf46a17c2025-01-05 15:50:18 +0000387 let expected_names = vec![Ok(c"node_a"), Ok(c"node_b"), Ok(c"node_c"), Ok(c"__symbols__")];
Jaewan Kim5f1a6032023-12-18 15:17:58 +0900388 let subnode_names: Vec<_> = root.subnodes().unwrap().map(|node| node.name()).collect();
389
390 assert_eq!(expected_names, subnode_names);
391}
Jaewan Kim28a13ea2024-01-04 09:22:40 +0900392
393#[test]
394fn node_mut_delete_and_next_node() {
395 let mut data = fs::read(TEST_TREE_PHANDLE_PATH).unwrap();
396 let fdt = Fdt::from_mut_slice(&mut data).unwrap();
397
398 let expected_nodes = vec![
Alan Stokesf46a17c2025-01-05 15:50:18 +0000399 (Ok(c"node_b"), 1),
400 (Ok(c"node_c"), 1),
401 (Ok(c"node_z"), 1),
402 (Ok(c"node_za"), 2),
403 (Ok(c"node_zb"), 2),
404 (Ok(c"__symbols__"), 1),
Jaewan Kim28a13ea2024-01-04 09:22:40 +0900405 ];
406
407 let mut expected_nodes_iter = expected_nodes.iter();
Pierre-Clément Tosi244efea2024-02-16 14:48:14 +0000408 let mut iter = fdt.root_mut().next_node(0).unwrap();
Jaewan Kim28a13ea2024-01-04 09:22:40 +0900409 while let Some((node, depth)) = iter {
410 let node_name = node.as_node().name();
Alan Stokesf46a17c2025-01-05 15:50:18 +0000411 if node_name == Ok(c"node_a") || node_name == Ok(c"node_zz") {
Jaewan Kim28a13ea2024-01-04 09:22:40 +0900412 iter = node.delete_and_next_node(depth).unwrap();
413 } else {
414 // Note: Checking name here is easier than collecting names and assert_eq!(),
415 // because we can't keep name references while iterating with FdtNodeMut.
416 let expected_node = expected_nodes_iter.next();
417 assert_eq!(expected_node, Some(&(node_name, depth)));
418 iter = node.next_node(depth).unwrap();
419 }
420 }
421 assert_eq!(None, expected_nodes_iter.next());
422
Pierre-Clément Tosi244efea2024-02-16 14:48:14 +0000423 let root = fdt.root();
Jaewan Kim28a13ea2024-01-04 09:22:40 +0900424 let all_descendants: Vec<_> =
425 root.descendants().map(|(node, depth)| (node.name(), depth)).collect();
426 assert_eq!(expected_nodes, all_descendants);
427}
Jaewan Kim1eab7232024-01-04 09:46:16 +0900428
429#[test]
Jaewan Kima5bc8922024-02-20 01:15:37 +0900430fn node_mut_delete_and_next_node_with_last_node() {
431 let mut data = fs::read(TEST_TREE_WITH_EMPTY_MEMORY_RANGE_PATH).unwrap();
432 let fdt = Fdt::from_mut_slice(&mut data).unwrap();
433
Pierre-Clément Tosi244efea2024-02-16 14:48:14 +0000434 let mut iter = fdt.root_mut().next_node(0).unwrap();
Jaewan Kima5bc8922024-02-20 01:15:37 +0900435 while let Some((node, depth)) = iter {
436 iter = node.delete_and_next_node(depth).unwrap();
437 }
438
Pierre-Clément Tosi244efea2024-02-16 14:48:14 +0000439 let root = fdt.root();
Jaewan Kima5bc8922024-02-20 01:15:37 +0900440 let all_descendants: Vec<_> =
441 root.descendants().map(|(node, depth)| (node.name(), depth)).collect();
442 assert!(all_descendants.is_empty(), "{all_descendants:?}");
443}
444
445#[test]
Jaewan Kim1eab7232024-01-04 09:46:16 +0900446#[ignore] // Borrow checker test. Compilation success is sufficient.
447fn node_name_lifetime() {
448 let data = fs::read(TEST_TREE_PHANDLE_PATH).unwrap();
449 let fdt = Fdt::from_slice(&data).unwrap();
450
451 let name = {
Pierre-Clément Tosi244efea2024-02-16 14:48:14 +0000452 let root = fdt.root();
Jaewan Kim1eab7232024-01-04 09:46:16 +0900453 root.name()
454 // Make root to be dropped
455 };
Alan Stokesf46a17c2025-01-05 15:50:18 +0000456 assert_eq!(Ok(c""), name);
Jaewan Kim1eab7232024-01-04 09:46:16 +0900457}
458
459#[test]
Jaewan Kime6363422024-01-19 14:00:00 +0900460fn node_mut_add_subnodes() {
461 let mut data = vec![0_u8; 1000];
462 let fdt = Fdt::create_empty_tree(&mut data).unwrap();
463
Pierre-Clément Tosi244efea2024-02-16 14:48:14 +0000464 let root = fdt.root_mut();
Alan Stokesf46a17c2025-01-05 15:50:18 +0000465 let names = [c"a", c"b"];
Jaewan Kime6363422024-01-19 14:00:00 +0900466 root.add_subnodes(&names).unwrap();
467
468 let expected: HashSet<_> = names.into_iter().collect();
Pierre-Clément Tosi244efea2024-02-16 14:48:14 +0000469 let subnodes = fdt.root().subnodes().unwrap();
Jaewan Kime6363422024-01-19 14:00:00 +0900470 let names: HashSet<_> = subnodes.map(|node| node.name().unwrap()).collect();
471
472 assert_eq!(expected, names);
473}
474
475#[test]
Jaewan Kim1eab7232024-01-04 09:46:16 +0900476#[ignore] // Borrow checker test. Compilation success is sufficient.
477fn node_subnode_lifetime() {
478 let data = fs::read(TEST_TREE_PHANDLE_PATH).unwrap();
479 let fdt = Fdt::from_slice(&data).unwrap();
480
481 let name = {
482 let node_a = {
Pierre-Clément Tosi244efea2024-02-16 14:48:14 +0000483 let root = fdt.root();
Alan Stokesf46a17c2025-01-05 15:50:18 +0000484 root.subnode(c"node_a").unwrap()
Jaewan Kim1eab7232024-01-04 09:46:16 +0900485 // Make root to be dropped
486 };
487 assert_ne!(None, node_a);
488 node_a.unwrap().name()
489 // Make node_a to be dropped
490 };
Alan Stokesf46a17c2025-01-05 15:50:18 +0000491 assert_eq!(Ok(c"node_a"), name);
Jaewan Kim1eab7232024-01-04 09:46:16 +0900492}
493
494#[test]
495#[ignore] // Borrow checker test. Compilation success is sufficient.
Jaewan Kim4a34b0d2024-01-19 13:17:47 +0900496fn node_subnodess_lifetime() {
497 let data = fs::read(TEST_TREE_PHANDLE_PATH).unwrap();
498 let fdt = Fdt::from_slice(&data).unwrap();
499
500 let first_subnode_name = {
501 let first_subnode = {
502 let mut subnodes_iter = {
Pierre-Clément Tosi244efea2024-02-16 14:48:14 +0000503 let root = fdt.root();
Jaewan Kim4a34b0d2024-01-19 13:17:47 +0900504 root.subnodes().unwrap()
505 // Make root to be dropped
506 };
507 subnodes_iter.next().unwrap()
508 // Make subnodess_iter to be dropped
509 };
510 first_subnode.name()
511 // Make first_subnode to be dropped
512 };
Alan Stokesf46a17c2025-01-05 15:50:18 +0000513 assert_eq!(Ok(c"node_a"), first_subnode_name);
Jaewan Kim4a34b0d2024-01-19 13:17:47 +0900514}
515
516#[test]
517#[ignore] // Borrow checker test. Compilation success is sufficient.
Jaewan Kim1eab7232024-01-04 09:46:16 +0900518fn node_descendants_lifetime() {
519 let data = fs::read(TEST_TREE_PHANDLE_PATH).unwrap();
520 let fdt = Fdt::from_slice(&data).unwrap();
521
522 let first_descendant_name = {
523 let (first_descendant, _) = {
524 let mut descendants_iter = {
Pierre-Clément Tosi244efea2024-02-16 14:48:14 +0000525 let root = fdt.root();
Jaewan Kim1eab7232024-01-04 09:46:16 +0900526 root.descendants()
527 // Make root to be dropped
528 };
529 descendants_iter.next().unwrap()
530 // Make descendants_iter to be dropped
531 };
532 first_descendant.name()
533 // Make first_descendant to be dropped
534 };
Alan Stokesf46a17c2025-01-05 15:50:18 +0000535 assert_eq!(Ok(c"node_a"), first_descendant_name);
Jaewan Kim1eab7232024-01-04 09:46:16 +0900536}