Closed DanielBaldelomar closed 8 years ago
Don't change the prompt then, maybe?
Is your test supposed to change the prompt?
Yes, it is, and when I try to do it, I have the following output:
2016-02-03T10:10:43.928870 [sw1].send_command(hostname CT-TEST) ::
2016-02-03T10:10:44.038668 [sw1].send_command(end) ::
FAILED
================================================================================== FAILURES ===================================================================================
_______________________________________________________________________________ test_cfgdbutil ________________________________________________________________________________
topology = <topology.manager.TopologyManager object at 0x7f2dd03c63c8>, step = <topology.pytest.plugin.StepLogger object at 0x7f2dcf2f4550>
def test_cfgdbutil(topology, step):
sw1 = topology.get('sw1')
assert sw1 is not None
step("### Test cfgdbutils show commands ###")
sw1('configure terminal')
sw1('lldp holdtime 9')
sw1('radius-server host 1.1.1.1')
sw1('end')
sw1('copy running-config startup-config')
output = sw1('show startup-config')
assert "lldp holdtime 9" in output and \
"radius-server host 1.1.1.1" in output, \
"Failed: To fetch startup configuration"
"""
step("### Test to show startup config in json ###")
output = sw1('show startup-config json')
output = output[output.index('{'):]
output = output[:output.rindex('}') + 1]
parsed = json.loads(output)
system = parsed["System"]
radius_servers = system["radius_servers"]
assert "1.1.1.1" in radius_servers,
"Failed: To fetch startup config in json"
"""
step("#### Delete startup config saved in configdb ###")
output = sw1('cfgdbutil delete startup-config', shell='bash')
assert "success" in output, "Failed: Delete startup configuration"
step("### Test copy running to startup config ###")
sw1('configure terminal')
sw1('hostname CT-TEST')
> sw1('end')
../../../test/ops-cfgd/test_cfgdbutil.py:71:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../src/topology/lib/topology/platforms/base.py:211: in __call__
return self.send_command(cmd, shell=shell, silent=silent)
../src/topology/lib/topology/platforms/base.py:339: in send_command
response = self._shells[shell](cmd)
../lib/python3.4/site-packages/topology_docker/shell.py:68: in __call__
self._spawn.expect(self._prompt, timeout=self._timeout)
../lib/python3.4/site-packages/pexpect/spawnbase.py:315: in expect
timeout, searchwindowsize, async)
../lib/python3.4/site-packages/pexpect/spawnbase.py:339: in expect_list
return exp.expect_loop(timeout)
../lib/python3.4/site-packages/pexpect/expect.py:104: in expect_loop
return self.timeout(e)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <pexpect.expect.Expecter object at 0x7f2dcf2a3e80>, err = TIMEOUT('Timeout exceeded.',)
def timeout(self, err=None):
spawn = self.spawn
from . import TIMEOUT
spawn.before = spawn.buffer
spawn.after = TIMEOUT
index = self.searcher.timeout_index
if index >= 0:
spawn.match = TIMEOUT
spawn.match_index = index
return index
else:
spawn.match = None
spawn.match_index = None
msg = str(spawn)
if err is not None:
msg = str(err) + '\n' + msg
> raise TIMEOUT(msg)
E pexpect.exceptions.TIMEOUT: Timeout exceeded.
E <pexpect.pty_spawn.spawn object at 0x7f2dd03c6588>
E command: /usr/bin/docker
E args: ['/usr/bin/docker', 'exec', '-i', '-t', '56f65537d50eb047218731a92ee8270c9b8e17fe95bceb570cf4eea585a0b934', 'vtysh']
E searcher: None
E buffer (last 100 chars): b' end\r\r\nCT-TEST# '
E before (last 100 chars): b' end\r\r\nCT-TEST# '
E after: <class 'pexpect.exceptions.TIMEOUT'>
E match: None
E match_index: None
E exitstatus: None
E flag_eof: False
E pid: 20236
E child_fd: 10
E closed: False
E timeout: 30
E delimiter: <class 'pexpect.exceptions.EOF'>
E logfile: None
E logfile_read: None
E logfile_send: None
E maxread: 2000
E ignorecase: False
E searchwindowsize: None
E delaybeforesend: 0.05
E delayafterclose: 0.1
E delayafterterminate: 0.1
../lib/python3.4/site-packages/pexpect/expect.py:68: TIMEOUT
--------------------------------------------- generated xml file: /users/baldelom/HALON2/openswitch_tests/.tox/py34/tmp/tests.xml ---------------------------------------------
========================================================================== slowest 10 test durations ==========================================================================
37.69s call test/ops-cfgd/test_cfgdbutil.py::test_cfgdbutil
10.28s teardown test/ops-cfgd/test_cfgdbutil.py::test_cfgdbutil
8.06s setup test/ops-cfgd/test_cfgdbutil.py::test_cfgdbutil
================================================================== 12 tests deselected by '-ktest_cfgdbutil' ==================================================================
================================================================== 1 failed, 12 deselected in 56.43 seconds ===================================================================
ERROR: InvocationError: '/users/baldelom/HALON2/openswitch_tests/.tox/py34/bin/py.test --random --durations=10 --junitxml=tests.xml --topology-nml-dir topologies --topology-plot-dir topologies --topology-plot-format svg --topology-platform=docker -k test_cfgdbutil -s -v /users/baldelom/HALON2/openswitch_tests/test'
___________________________________________________________________________________ summary ___________________________________________________________________________________
ERROR: py34: commands failed
Thanks, much better. This issue seems related to a regex that is too restrictive, will investigate.
@ocelotl not very much about the regular expression being too restrictive, more about the unpredictability of the prompt matching, which we have seen as problematic in other OpenSwitch related tests.
We can take into consideration the pexpect
ssh helper pxssh's set_unique_prompt() call.
This call allows to set the prompt of a bash shell to a constant value during the pexpect session. Now, we can emulate that for bash shells, but the problem on the vytsh prompt will remain.
Handling prompt matching in a satisfactory way requires a a deeper change in the framework itself and also support for precise prompt changing in the involved shells. Meanwhile, this can serve as a workaround for this issue:
I tried with this image and found out that after calling hostname a second enter key press is needed for the prompt to be updated:
ocelotl@stallman:~/private/openswitch_tests/test$ docker run --privileged -v /tmp:/tmp -v /dev/log:/dev/log -v /sys/fs/cgroup:/sys/fs/cgroup openswitch:2016010100 /sbin/init
&
[2] 22388
ocelotl@stallman:~/private/openswitch_tests/test$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b0c4d4fd5025 openswitch:2016010100 "/sbin/init" 10 seconds ago Up 10 seconds happy_galileo
5aba68e7302c openswitch:2016010100 "/sbin/init" About a minute ago Up About a minute stupefied_archimedes
ocelotl@stallman:~/private/openswitch_tests/test$ docker exec -t -i b0c4d4fd5025 vtysh
switch# configure terminal
switch(config)# hostname new_hostname
switch(config)#
new_hostname(config)# exit
new_hostname# exit
Considering this, you can use this workaround (notice how the promtp is changhed after calling hostname):
TOPOLOGY = """
[type=openswitch name="OpenSwitch 1" image="openswitch:2016010100"] ops1
"""
def test_hostname(topology):
"""
This is a test case that uses vtysh hostname command.
"""
ops1 = topology.get('ops1')
ops1('configure terminal')
ops1('hostname new_hostname')
ops1._shells['vtysh']._prompt = (
'(^|\n)new_hostname(\\([\\-a-zA-Z0-9]*\\))?#'
)
ops1('exit')
ops1('show vlan 1')
Ok Hurtado, thanks a lot, this fix works fine.
Closing now, then.
When try to execute the following command
The test failed, because I am changing the prompt.