1# SPDX-License-Identifier: GPL-2.0 2# Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. 3 4""" Test for bind command """ 5 6import re 7import pytest 8 9def in_tree(response, name, uclass, drv, depth, last_child): 10 """A helper function to confirm contents of the device tree """ 11 lines = [x.strip() for x in response.splitlines()] 12 leaf = '' 13 if depth != 0: 14 leaf = ' ' + ' ' * (depth - 1) 15 if not last_child: 16 leaf = leaf + r'\|' 17 else: 18 leaf = leaf + '`' 19 20 leaf = leaf + '-- ' + name 21 line = (r' *{:10.10} *[0-9]* \[ [ +] \] {:20.20} [` |]{}$' 22 .format(uclass, drv, leaf)) 23 prog = re.compile(line) 24 for l in lines: 25 if prog.match(l): 26 return True 27 return False 28 29@pytest.mark.boardspec('sandbox') 30@pytest.mark.buildconfigspec('cmd_bind') 31def test_bind_unbind_with_node(ubman): 32 """Test the bind and unbind commands of a node 33 34 Verify that the dm tree output contains some expected nodes, and then bind 35 and unbind a USB via node device while verifying that the dm tree output 36 matches the expected values at each step. 37 """ 38 tree = ubman.run_command('dm tree') 39 assert in_tree(tree, 'bind-test', 'simple_bus', 'simple_bus', 0, True) 40 assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, False) 41 assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'simple_bus', 1, True) 42 43 #bind usb_ether driver (which has no compatible) to usb@1 node. 44 ##New entry usb_ether should appear in the dm tree 45 response = ubman.run_command('bind /usb@1 usb_ether') 46 assert response == '' 47 tree = ubman.run_command('dm tree') 48 assert in_tree(tree, 'usb@1', 'ethernet', 'usb_ether', 1, True) 49 50 #Unbind child #1. No error expected and all devices should be there except for bind-test-child1 51 response = ubman.run_command('unbind /bind-test/bind-test-child1') 52 assert response == '' 53 tree = ubman.run_command('dm tree') 54 assert in_tree(tree, 'bind-test', 'simple_bus', 'simple_bus', 0, True) 55 assert 'bind-test-child1' not in tree 56 assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'simple_bus', 1, True) 57 58 #bind child #1. No error expected and all devices should be there 59 response = ubman.run_command('bind /bind-test/bind-test-child1 phy_sandbox') 60 assert response == '' 61 tree = ubman.run_command('dm tree') 62 assert in_tree(tree, 'bind-test', 'simple_bus', 'simple_bus', 0, True) 63 assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, True) 64 assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'simple_bus', 1, False) 65 66 #Unbind child #2. No error expected and all devices should be there except for bind-test-child2 67 response = ubman.run_command('unbind /bind-test/bind-test-child2') 68 assert response == '' 69 tree = ubman.run_command('dm tree') 70 assert in_tree(tree, 'bind-test', 'simple_bus', 'simple_bus', 0, True) 71 assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, True) 72 assert 'bind-test-child2' not in tree 73 74 75 #Bind child #2. No error expected and all devices should be there 76 response = ubman.run_command('bind /bind-test/bind-test-child2 simple_bus') 77 assert response == '' 78 tree = ubman.run_command('dm tree') 79 assert in_tree(tree, 'bind-test', 'simple_bus', 'simple_bus', 0, True) 80 assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, False) 81 assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'simple_bus', 1, True) 82 83 #Unbind parent. No error expected. All devices should be removed and unbound 84 response = ubman.run_command('unbind /bind-test') 85 assert response == '' 86 tree = ubman.run_command('dm tree') 87 assert 'bind-test' not in tree 88 assert 'bind-test-child1' not in tree 89 assert 'bind-test-child2' not in tree 90 91 #try binding invalid node with valid driver 92 response = ubman.run_command('bind /not-a-valid-node simple_bus') 93 assert response != '' 94 tree = ubman.run_command('dm tree') 95 assert 'not-a-valid-node' not in tree 96 97 #try binding valid node with invalid driver 98 response = ubman.run_command('bind /bind-test not_a_driver') 99 assert response != '' 100 tree = ubman.run_command('dm tree') 101 assert 'bind-test' not in tree 102 103 #bind /bind-test. Device should come up as well as its children 104 response = ubman.run_command('bind /bind-test simple_bus') 105 assert response == '' 106 tree = ubman.run_command('dm tree') 107 assert in_tree(tree, 'bind-test', 'simple_bus', 'simple_bus', 0, True) 108 assert in_tree(tree, 'bind-test-child1', 'phy', 'phy_sandbox', 1, False) 109 assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'simple_bus', 1, True) 110 111 response = ubman.run_command('unbind /bind-test') 112 assert response == '' 113 114def get_next_line(tree, name): 115 """A helper function to strip content out of dm tree output""" 116 treelines = [x.strip() for x in tree.splitlines() if x.strip()] 117 child_line = '' 118 for idx, line in enumerate(treelines): 119 if '-- ' + name in line: 120 try: 121 child_line = treelines[idx+1] 122 except: 123 pass 124 break 125 return child_line 126 127@pytest.mark.boardspec('sandbox') 128@pytest.mark.buildconfigspec('cmd_bind') 129@pytest.mark.singlethread 130def test_bind_unbind_with_uclass(ubman): 131 """Test the bind and unbind commands of a class 132 133 Bind and unbind the simple_bus class while verifying that the dm tree 134 output matches the expected values at each step. 135 """ 136 #bind /bind-test 137 response = ubman.run_command('bind /bind-test simple_bus') 138 assert response == '' 139 140 #make sure bind-test-child2 is there and get its uclass/index pair 141 tree = ubman.run_command('dm tree') 142 child2_line = [x.strip() for x in tree.splitlines() if '-- bind-test-child2' in x] 143 assert len(child2_line) == 1 144 145 child2_uclass = child2_line[0].split()[0] 146 child2_index = int(child2_line[0].split()[1]) 147 148 #bind simple_bus as a child of bind-test-child2 149 response = ubman.run_command( 150 'bind {} {} simple_bus'.format(child2_uclass, child2_index)) 151 152 #check that the child is there and its uclass/index pair is right 153 tree = ubman.run_command('dm tree') 154 155 child_of_child2_line = get_next_line(tree, 'bind-test-child2') 156 assert child_of_child2_line 157 child_of_child2_index = int(child_of_child2_line.split()[1]) 158 assert in_tree(tree, 'simple_bus', 'simple_bus', 'simple_bus', 2, True) 159 assert child_of_child2_index == child2_index + 1 160 161 #unbind the child and check it has been removed 162 response = ubman.run_command('unbind simple_bus {}'.format(child_of_child2_index)) 163 assert response == '' 164 tree = ubman.run_command('dm tree') 165 assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'simple_bus', 1, True) 166 assert not in_tree(tree, 'simple_bus', 'simple_bus', 'simple_bus', 2, True) 167 child_of_child2_line = get_next_line(tree, 'bind-test-child2') 168 assert child_of_child2_line == '' 169 170 #bind simple_bus as a child of bind-test-child2 171 response = ubman.run_command( 172 'bind {} {} simple_bus'.format(child2_uclass, child2_index)) 173 174 #check that the child is there and its uclass/index pair is right 175 tree = ubman.run_command('dm tree') 176 treelines = [x.strip() for x in tree.splitlines() if x.strip()] 177 178 child_of_child2_line = get_next_line(tree, 'bind-test-child2') 179 assert child_of_child2_line 180 child_of_child2_index = int(child_of_child2_line.split()[1]) 181 assert in_tree(tree, 'simple_bus', 'simple_bus', 'simple_bus', 2, True) 182 assert child_of_child2_index == child2_index + 1 183 184 #unbind the child and check it has been removed 185 response = ubman.run_command( 186 'unbind {} {} simple_bus'.format(child2_uclass, child2_index)) 187 assert response == '' 188 189 tree = ubman.run_command('dm tree') 190 assert in_tree(tree, 'bind-test-child2', 'simple_bus', 'simple_bus', 1, True) 191 192 child_of_child2_line = get_next_line(tree, 'bind-test-child2') 193 assert child_of_child2_line == '' 194 195 #unbind the child again and check it doesn't change the tree 196 tree_old = ubman.run_command('dm tree') 197 response = ubman.run_command( 198 'unbind {} {} simple_bus'.format(child2_uclass, child2_index)) 199 tree_new = ubman.run_command('dm tree') 200 201 assert response == '' 202 assert tree_old == tree_new 203 204 response = ubman.run_command('unbind /bind-test') 205 assert response == '' 206