1# SPDX-License-Identifier: GPL-2.0 2# Copyright (c) 2015 Stephen Warren 3# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved. 4 5# Test operation of shell commands relating to environment variables. 6 7import pytest 8 9# FIXME: This might be useful for other tests; 10# perhaps refactor it into ConsoleBase or some other state object? 11class StateTestEnv(object): 12 """Container that represents the state of all U-Boot environment variables. 13 This enables quick determination of existant/non-existant variable 14 names. 15 """ 16 17 def __init__(self, u_boot_console): 18 """Initialize a new StateTestEnv object. 19 20 Args: 21 u_boot_console: A U-Boot console. 22 23 Returns: 24 Nothing. 25 """ 26 27 self.u_boot_console = u_boot_console 28 self.get_env() 29 self.set_var = self.get_non_existent_var() 30 31 def get_env(self): 32 """Read all current environment variables from U-Boot. 33 34 Args: 35 None. 36 37 Returns: 38 Nothing. 39 """ 40 41 if self.u_boot_console.config.buildconfig.get( 42 'config_version_variable', 'n') == 'y': 43 with self.u_boot_console.disable_check('main_signon'): 44 response = self.u_boot_console.run_command('printenv') 45 else: 46 response = self.u_boot_console.run_command('printenv') 47 self.env = {} 48 for l in response.splitlines(): 49 if not '=' in l: 50 continue 51 (var, value) = l.strip().split('=', 1) 52 self.env[var] = value 53 54 def get_existent_var(self): 55 """Return the name of an environment variable that exists. 56 57 Args: 58 None. 59 60 Returns: 61 The name of an environment variable. 62 """ 63 64 for var in self.env: 65 return var 66 67 def get_non_existent_var(self): 68 """Return the name of an environment variable that does not exist. 69 70 Args: 71 None. 72 73 Returns: 74 The name of an environment variable. 75 """ 76 77 n = 0 78 while True: 79 var = 'test_env_' + str(n) 80 if var not in self.env: 81 return var 82 n += 1 83 84ste = None 85@pytest.fixture(scope='function') 86def state_test_env(u_boot_console): 87 """pytest fixture to provide a StateTestEnv object to tests.""" 88 89 global ste 90 if not ste: 91 ste = StateTestEnv(u_boot_console) 92 return ste 93 94def unset_var(state_test_env, var): 95 """Unset an environment variable. 96 97 This both executes a U-Boot shell command and updates a StateTestEnv 98 object. 99 100 Args: 101 state_test_env: The StateTestEnv object to update. 102 var: The variable name to unset. 103 104 Returns: 105 Nothing. 106 """ 107 108 state_test_env.u_boot_console.run_command('setenv %s' % var) 109 if var in state_test_env.env: 110 del state_test_env.env[var] 111 112def set_var(state_test_env, var, value): 113 """Set an environment variable. 114 115 This both executes a U-Boot shell command and updates a StateTestEnv 116 object. 117 118 Args: 119 state_test_env: The StateTestEnv object to update. 120 var: The variable name to set. 121 value: The value to set the variable to. 122 123 Returns: 124 Nothing. 125 """ 126 127 bc = state_test_env.u_boot_console.config.buildconfig 128 if bc.get('config_hush_parser', None): 129 quote = '"' 130 else: 131 quote = '' 132 if ' ' in value: 133 pytest.skip('Space in variable value on non-Hush shell') 134 135 state_test_env.u_boot_console.run_command( 136 'setenv %s %s%s%s' % (var, quote, value, quote)) 137 state_test_env.env[var] = value 138 139def validate_empty(state_test_env, var): 140 """Validate that a variable is not set, using U-Boot shell commands. 141 142 Args: 143 var: The variable name to test. 144 145 Returns: 146 Nothing. 147 """ 148 149 response = state_test_env.u_boot_console.run_command('echo $%s' % var) 150 assert response == '' 151 152def validate_set(state_test_env, var, value): 153 """Validate that a variable is set, using U-Boot shell commands. 154 155 Args: 156 var: The variable name to test. 157 value: The value the variable is expected to have. 158 159 Returns: 160 Nothing. 161 """ 162 163 # echo does not preserve leading, internal, or trailing whitespace in the 164 # value. printenv does, and hence allows more complete testing. 165 response = state_test_env.u_boot_console.run_command('printenv %s' % var) 166 assert response == ('%s=%s' % (var, value)) 167 168def test_env_echo_exists(state_test_env): 169 """Test echoing a variable that exists.""" 170 171 var = state_test_env.get_existent_var() 172 value = state_test_env.env[var] 173 validate_set(state_test_env, var, value) 174 175@pytest.mark.buildconfigspec('cmd_echo') 176def test_env_echo_non_existent(state_test_env): 177 """Test echoing a variable that doesn't exist.""" 178 179 var = state_test_env.set_var 180 validate_empty(state_test_env, var) 181 182def test_env_printenv_non_existent(state_test_env): 183 """Test printenv error message for non-existant variables.""" 184 185 var = state_test_env.set_var 186 c = state_test_env.u_boot_console 187 with c.disable_check('error_notification'): 188 response = c.run_command('printenv %s' % var) 189 assert(response == '## Error: "%s" not defined' % var) 190 191@pytest.mark.buildconfigspec('cmd_echo') 192def test_env_unset_non_existent(state_test_env): 193 """Test unsetting a nonexistent variable.""" 194 195 var = state_test_env.get_non_existent_var() 196 unset_var(state_test_env, var) 197 validate_empty(state_test_env, var) 198 199def test_env_set_non_existent(state_test_env): 200 """Test set a non-existant variable.""" 201 202 var = state_test_env.set_var 203 value = 'foo' 204 set_var(state_test_env, var, value) 205 validate_set(state_test_env, var, value) 206 207def test_env_set_existing(state_test_env): 208 """Test setting an existant variable.""" 209 210 var = state_test_env.set_var 211 value = 'bar' 212 set_var(state_test_env, var, value) 213 validate_set(state_test_env, var, value) 214 215@pytest.mark.buildconfigspec('cmd_echo') 216def test_env_unset_existing(state_test_env): 217 """Test unsetting a variable.""" 218 219 var = state_test_env.set_var 220 unset_var(state_test_env, var) 221 validate_empty(state_test_env, var) 222 223def test_env_expansion_spaces(state_test_env): 224 """Test expanding a variable that contains a space in its value.""" 225 226 var_space = None 227 var_test = None 228 try: 229 var_space = state_test_env.get_non_existent_var() 230 set_var(state_test_env, var_space, ' ') 231 232 var_test = state_test_env.get_non_existent_var() 233 value = ' 1${%(var_space)s}${%(var_space)s} 2 ' % locals() 234 set_var(state_test_env, var_test, value) 235 value = ' 1 2 ' 236 validate_set(state_test_env, var_test, value) 237 finally: 238 if var_space: 239 unset_var(state_test_env, var_space) 240 if var_test: 241 unset_var(state_test_env, var_test) 242