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