xref: /openbmc/u-boot/test/py/tests/test_env.py (revision ba10b852)
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
80ste = None
81@pytest.fixture(scope='function')
82def state_test_env(u_boot_console):
83    """pytest fixture to provide a StateTestEnv object to tests."""
84
85    global ste
86    if not ste:
87        ste = StateTestEnv(u_boot_console)
88    return ste
89
90def unset_var(state_test_env, var):
91    """Unset an environment variable.
92
93    This both executes a U-Boot shell command and updates a StateTestEnv
94    object.
95
96    Args:
97        state_test_env: The StateTestEnv object to update.
98        var: The variable name to unset.
99
100    Returns:
101        Nothing.
102    """
103
104    state_test_env.u_boot_console.run_command('setenv %s' % var)
105    if var in state_test_env.env:
106        del state_test_env.env[var]
107
108def set_var(state_test_env, var, value):
109    """Set an environment variable.
110
111    This both executes a U-Boot shell command and updates a StateTestEnv
112    object.
113
114    Args:
115        state_test_env: The StateTestEnv object to update.
116        var: The variable name to set.
117        value: The value to set the variable to.
118
119    Returns:
120        Nothing.
121    """
122
123    state_test_env.u_boot_console.run_command('setenv %s "%s"' % (var, value))
124    state_test_env.env[var] = value
125
126def validate_empty(state_test_env, var):
127    """Validate that a variable is not set, using U-Boot shell commands.
128
129    Args:
130        var: The variable name to test.
131
132    Returns:
133        Nothing.
134    """
135
136    response = state_test_env.u_boot_console.run_command('echo $%s' % var)
137    assert response == ''
138
139def validate_set(state_test_env, var, value):
140    """Validate that a variable is set, using U-Boot shell commands.
141
142    Args:
143        var: The variable name to test.
144        value: The value the variable is expected to have.
145
146    Returns:
147        Nothing.
148    """
149
150    # echo does not preserve leading, internal, or trailing whitespace in the
151    # value. printenv does, and hence allows more complete testing.
152    response = state_test_env.u_boot_console.run_command('printenv %s' % var)
153    assert response == ('%s=%s' % (var, value))
154
155def test_env_echo_exists(state_test_env):
156    """Test echoing a variable that exists."""
157
158    var = state_test_env.get_existent_var()
159    value = state_test_env.env[var]
160    validate_set(state_test_env, var, value)
161
162def test_env_echo_non_existent(state_test_env):
163    """Test echoing a variable that doesn't exist."""
164
165    var = state_test_env.set_var
166    validate_empty(state_test_env, var)
167
168def test_env_printenv_non_existent(state_test_env):
169    """Test printenv error message for non-existant variables."""
170
171    var = state_test_env.set_var
172    c = state_test_env.u_boot_console
173    with c.disable_check('error_notification'):
174        response = c.run_command('printenv %s' % var)
175    assert(response == '## Error: "%s" not defined' % var)
176
177def test_env_unset_non_existent(state_test_env):
178    """Test unsetting a nonexistent variable."""
179
180    var = state_test_env.get_non_existent_var()
181    unset_var(state_test_env, var)
182    validate_empty(state_test_env, var)
183
184def test_env_set_non_existent(state_test_env):
185    """Test set a non-existant variable."""
186
187    var = state_test_env.set_var
188    value = 'foo'
189    set_var(state_test_env, var, value)
190    validate_set(state_test_env, var, value)
191
192def test_env_set_existing(state_test_env):
193    """Test setting an existant variable."""
194
195    var = state_test_env.set_var
196    value = 'bar'
197    set_var(state_test_env, var, value)
198    validate_set(state_test_env, var, value)
199
200def test_env_unset_existing(state_test_env):
201    """Test unsetting a variable."""
202
203    var = state_test_env.set_var
204    unset_var(state_test_env, var)
205    validate_empty(state_test_env, var)
206
207def test_env_expansion_spaces(state_test_env):
208    """Test expanding a variable that contains a space in its value."""
209
210    var_space = None
211    var_test = None
212    try:
213        var_space = state_test_env.get_non_existent_var()
214        set_var(state_test_env, var_space, ' ')
215
216        var_test = state_test_env.get_non_existent_var()
217        value = ' 1${%(var_space)s}${%(var_space)s} 2 ' % locals()
218        set_var(state_test_env, var_test, value)
219        value = ' 1   2 '
220        validate_set(state_test_env, var_test, value)
221    finally:
222        if var_space:
223            unset_var(state_test_env, var_space)
224        if var_test:
225            unset_var(state_test_env, var_test)
226