xref: /openbmc/u-boot/test/py/tests/test_bind.py (revision 03dcf17d)
1# SPDX-License-Identifier: GPL-2.0
2# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
3
4import os.path
5import pytest
6import re
7
8def in_tree(response, name, uclass, drv, depth, last_child):
9	lines = [x.strip() for x in response.splitlines()]
10	leaf = ' ' * 4 * depth;
11	if not last_child:
12		leaf = leaf + '\|'
13	else:
14		leaf = leaf + '`'
15	leaf = leaf + '-- ' + name
16	line = ' *{:10.10}  [0-9]*  \[ [ +] \]   {:20.20}  {}$'.format(uclass, drv, leaf)
17	prog = re.compile(line)
18	for l in lines:
19		if prog.match(l):
20			return True
21	return False
22
23
24@pytest.mark.buildconfigspec('cmd_bind')
25def test_bind_unbind_with_node(u_boot_console):
26
27	#bind /bind-test. Device should come up as well as its children
28	response = u_boot_console.run_command('bind  /bind-test generic_simple_bus')
29	assert response == ''
30	tree = u_boot_console.run_command('dm tree')
31	assert in_tree(tree, 'bind-test', 'simple_bus', 'generic_simple_bus', 0, True)
32	assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, False)
33	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, True)
34
35	#Unbind child #1. No error expected and all devices should be there except for bind-test-child1
36	response = u_boot_console.run_command('unbind  /bind-test/bind-test-child1')
37	assert response == ''
38	tree = u_boot_console.run_command('dm tree')
39	assert in_tree(tree, 'bind-test', 'simple_bus', 'generic_simple_bus', 0, True)
40	assert 'bind-test-child1' not in tree
41	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, True)
42
43	#bind child #1. No error expected and all devices should be there
44	response = u_boot_console.run_command('bind  /bind-test/bind-test-child1 phy_sandbox')
45	assert response == ''
46	tree = u_boot_console.run_command('dm tree')
47	assert in_tree(tree, 'bind-test', 'simple_bus', 'generic_simple_bus', 0, True)
48	assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, True)
49	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, False)
50
51	#Unbind child #2. No error expected and all devices should be there except for bind-test-child2
52	response = u_boot_console.run_command('unbind  /bind-test/bind-test-child2')
53	assert response == ''
54	tree = u_boot_console.run_command('dm tree')
55	assert in_tree(tree, 'bind-test', 'simple_bus', 'generic_simple_bus', 0, True)
56	assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, True)
57	assert 'bind-test-child2' not in tree
58
59
60	#Bind child #2. No error expected and all devices should be there
61	response = u_boot_console.run_command('bind /bind-test/bind-test-child2 generic_simple_bus')
62	assert response == ''
63	tree = u_boot_console.run_command('dm tree')
64	assert in_tree(tree, 'bind-test', 'simple_bus', 'generic_simple_bus', 0, True)
65	assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, False)
66	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, True)
67
68	#Unbind parent. No error expected. All devices should be removed and unbound
69	response = u_boot_console.run_command('unbind  /bind-test')
70	assert response == ''
71	tree = u_boot_console.run_command('dm tree')
72	assert 'bind-test' not in tree
73	assert 'bind-test-child1' not in tree
74	assert 'bind-test-child2' not in tree
75
76	#try binding invalid node with valid driver
77	response = u_boot_console.run_command('bind  /not-a-valid-node generic_simple_bus')
78	assert response != ''
79	tree = u_boot_console.run_command('dm tree')
80	assert 'not-a-valid-node' not in tree
81
82	#try binding valid node with invalid driver
83	response = u_boot_console.run_command('bind  /bind-test not_a_driver')
84	assert response != ''
85	tree = u_boot_console.run_command('dm tree')
86	assert 'bind-test' not in tree
87
88	#bind /bind-test. Device should come up as well as its children
89	response = u_boot_console.run_command('bind  /bind-test generic_simple_bus')
90	assert response == ''
91	tree = u_boot_console.run_command('dm tree')
92	assert in_tree(tree, 'bind-test', 'simple_bus', 'generic_simple_bus', 0, True)
93	assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, False)
94	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, True)
95
96	response = u_boot_console.run_command('unbind  /bind-test')
97	assert response == ''
98
99def get_next_line(tree, name):
100	treelines = [x.strip() for x in tree.splitlines() if x.strip()]
101	child_line = ''
102	for idx, line in enumerate(treelines):
103		if ('-- ' + name) in line:
104			try:
105				child_line = treelines[idx+1]
106			except:
107				pass
108			break
109	return child_line
110
111@pytest.mark.buildconfigspec('cmd_bind')
112def test_bind_unbind_with_uclass(u_boot_console):
113	#bind /bind-test
114	response = u_boot_console.run_command('bind  /bind-test generic_simple_bus')
115	assert response == ''
116
117	#make sure bind-test-child2 is there and get its uclass/index pair
118	tree = u_boot_console.run_command('dm tree')
119	child2_line = [x.strip() for x in tree.splitlines() if '-- bind-test-child2' in x]
120	assert len(child2_line) == 1
121
122	child2_uclass = child2_line[0].split()[0]
123	child2_index = int(child2_line[0].split()[1])
124
125	#bind generic_simple_bus as a child of bind-test-child2
126	response = u_boot_console.run_command('bind  {} {} generic_simple_bus'.format(child2_uclass, child2_index, 'generic_simple_bus'))
127
128	#check that the child is there and its uclass/index pair is right
129	tree = u_boot_console.run_command('dm tree')
130
131	child_of_child2_line = get_next_line(tree, 'bind-test-child2')
132	assert child_of_child2_line
133	child_of_child2_index = int(child_of_child2_line.split()[1])
134	assert in_tree(tree, 'generic_simple_bus', 'simple_bus', 'generic_simple_bus', 2, True)
135	assert child_of_child2_index == child2_index + 1
136
137	#unbind the child and check it has been removed
138	response = u_boot_console.run_command('unbind  simple_bus {}'.format(child_of_child2_index))
139	assert response == ''
140	tree = u_boot_console.run_command('dm tree')
141	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, True)
142	assert not in_tree(tree, 'generic_simple_bus', 'simple_bus', 'generic_simple_bus', 2, True)
143	child_of_child2_line = get_next_line(tree, 'bind-test-child2')
144	assert child_of_child2_line == ''
145
146	#bind generic_simple_bus as a child of bind-test-child2
147	response = u_boot_console.run_command('bind  {} {} generic_simple_bus'.format(child2_uclass, child2_index, 'generic_simple_bus'))
148
149	#check that the child is there and its uclass/index pair is right
150	tree = u_boot_console.run_command('dm tree')
151	treelines = [x.strip() for x in tree.splitlines() if x.strip()]
152
153	child_of_child2_line = get_next_line(tree, 'bind-test-child2')
154	assert child_of_child2_line
155	child_of_child2_index = int(child_of_child2_line.split()[1])
156	assert in_tree(tree, 'generic_simple_bus', 'simple_bus', 'generic_simple_bus', 2, True)
157	assert child_of_child2_index == child2_index + 1
158
159	#unbind the child and check it has been removed
160	response = u_boot_console.run_command('unbind  {} {} generic_simple_bus'.format(child2_uclass, child2_index, 'generic_simple_bus'))
161	assert response == ''
162
163	tree = u_boot_console.run_command('dm tree')
164	assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'generic_simple_bus', 1, True)
165
166	child_of_child2_line = get_next_line(tree, 'bind-test-child2')
167	assert child_of_child2_line == ''
168
169	#unbind the child again and check it doesn't change the tree
170	tree_old = u_boot_console.run_command('dm tree')
171	response = u_boot_console.run_command('unbind  {} {} generic_simple_bus'.format(child2_uclass, child2_index, 'generic_simple_bus'))
172	tree_new = u_boot_console.run_command('dm tree')
173
174	assert response == ''
175	assert tree_old == tree_new
176
177	response = u_boot_console.run_command('unbind  /bind-test')
178	assert response == ''
179