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