Merge branch '2019-01-14-master-imports'
[oweals/u-boot.git] / test / py / tests / test_bind.py
1 # SPDX-License-Identifier: GPL-2.0
2 # Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
3
4 import os.path
5 import pytest
6 import re
7
8 def 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')
25 def 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
99 def 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')
112 def 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 == ''