Merge "Make sure cli CommandFailed prints out stdout and stderr"
diff --git a/tempest/cli/__init__.py b/tempest/cli/__init__.py
index ba94c82..d7b4a16 100644
--- a/tempest/cli/__init__.py
+++ b/tempest/cli/__init__.py
@@ -133,7 +133,7 @@
raise CommandFailed(proc.returncode,
cmd,
result,
- stderr=result_err)
+ result_err)
return result
def assertTableStruct(self, items, field_names):
@@ -148,9 +148,15 @@
% lines[:3]))
-class CommandFailed(subprocess.CalledProcessError):
- # adds output attribute for python2.6
- def __init__(self, returncode, cmd, output, stderr=""):
- super(CommandFailed, self).__init__(returncode, cmd)
- self.output = output
+class CommandFailed(Exception):
+ def __init__(self, returncode, cmd, output, stderr):
+ super(CommandFailed, self).__init__()
+ self.returncode = returncode
+ self.cmd = cmd
+ self.stdout = output
self.stderr = stderr
+
+ def __str__(self):
+ return ("Command '%s' returned non-zero exit status %d.\n"
+ "stdout:\n%s\n"
+ "stderr:\n%s" % (self.cmd, self.returncode, self.stdout, self.stderr))
diff --git a/tempest/cli/simple_read_only/test_cinder.py b/tempest/cli/simple_read_only/test_cinder.py
index 946b89e..9a6b159 100644
--- a/tempest/cli/simple_read_only/test_cinder.py
+++ b/tempest/cli/simple_read_only/test_cinder.py
@@ -15,17 +15,16 @@
import logging
import re
-import subprocess
import testtools
-import tempest.cli
+from tempest import cli
from tempest import config
CONF = config.CONF
LOG = logging.getLogger(__name__)
-class SimpleReadOnlyCinderClientTest(tempest.cli.ClientTestBase):
+class SimpleReadOnlyCinderClientTest(cli.ClientTestBase):
"""Basic, read-only tests for Cinder CLI client.
Checks return values and output of read-only commands.
@@ -41,7 +40,7 @@
super(SimpleReadOnlyCinderClientTest, cls).setUpClass()
def test_cinder_fake_action(self):
- self.assertRaises(subprocess.CalledProcessError,
+ self.assertRaises(cli.CommandFailed,
self.cinder,
'this-does-not-exist')
@@ -66,7 +65,7 @@
'Attached to'])
self.cinder('list', params='--all-tenants 1')
self.cinder('list', params='--all-tenants 0')
- self.assertRaises(subprocess.CalledProcessError,
+ self.assertRaises(cli.CommandFailed,
self.cinder,
'list',
params='--all-tenants bad')
diff --git a/tempest/cli/simple_read_only/test_glance.py b/tempest/cli/simple_read_only/test_glance.py
index 6b3f763..3fb1120 100644
--- a/tempest/cli/simple_read_only/test_glance.py
+++ b/tempest/cli/simple_read_only/test_glance.py
@@ -14,9 +14,8 @@
# under the License.
import re
-import subprocess
-import tempest.cli
+from tempest import cli
from tempest import config
from tempest.openstack.common import log as logging
@@ -25,7 +24,7 @@
LOG = logging.getLogger(__name__)
-class SimpleReadOnlyGlanceClientTest(tempest.cli.ClientTestBase):
+class SimpleReadOnlyGlanceClientTest(cli.ClientTestBase):
"""Basic, read-only tests for Glance CLI client.
Checks return values and output of read-only commands.
@@ -41,7 +40,7 @@
super(SimpleReadOnlyGlanceClientTest, cls).setUpClass()
def test_glance_fake_action(self):
- self.assertRaises(subprocess.CalledProcessError,
+ self.assertRaises(cli.CommandFailed,
self.glance,
'this-does-not-exist')
diff --git a/tempest/cli/simple_read_only/test_keystone.py b/tempest/cli/simple_read_only/test_keystone.py
index dda65c1..f8dcdba 100644
--- a/tempest/cli/simple_read_only/test_keystone.py
+++ b/tempest/cli/simple_read_only/test_keystone.py
@@ -14,9 +14,8 @@
# under the License.
import re
-import subprocess
-import tempest.cli
+from tempest import cli
from tempest import config
from tempest.openstack.common import log as logging
@@ -26,7 +25,7 @@
LOG = logging.getLogger(__name__)
-class SimpleReadOnlyKeystoneClientTest(tempest.cli.ClientTestBase):
+class SimpleReadOnlyKeystoneClientTest(cli.ClientTestBase):
"""Basic, read-only tests for Keystone CLI client.
Checks return values and output of read-only commands.
@@ -35,7 +34,7 @@
"""
def test_admin_fake_action(self):
- self.assertRaises(subprocess.CalledProcessError,
+ self.assertRaises(cli.CommandFailed,
self.keystone,
'this-does-not-exist')
diff --git a/tempest/cli/simple_read_only/test_neutron.py b/tempest/cli/simple_read_only/test_neutron.py
index 49d079e..2643596 100644
--- a/tempest/cli/simple_read_only/test_neutron.py
+++ b/tempest/cli/simple_read_only/test_neutron.py
@@ -14,7 +14,6 @@
# under the License.
import re
-import subprocess
from tempest import cli
from tempest import config
@@ -43,7 +42,7 @@
@test.attr(type='smoke')
def test_neutron_fake_action(self):
- self.assertRaises(subprocess.CalledProcessError,
+ self.assertRaises(cli.CommandFailed,
self.neutron,
'this-does-not-exist')
diff --git a/tempest/cli/simple_read_only/test_nova.py b/tempest/cli/simple_read_only/test_nova.py
index 1c1ddf1..70eb9ef 100644
--- a/tempest/cli/simple_read_only/test_nova.py
+++ b/tempest/cli/simple_read_only/test_nova.py
@@ -13,11 +13,9 @@
# License for the specific language governing permissions and limitations
# under the License.
-import subprocess
-
import testtools
-import tempest.cli
+from tempest import cli
from tempest import config
from tempest.openstack.common import log as logging
import tempest.test
@@ -27,7 +25,7 @@
LOG = logging.getLogger(__name__)
-class SimpleReadOnlyNovaClientTest(tempest.cli.ClientTestBase):
+class SimpleReadOnlyNovaClientTest(cli.ClientTestBase):
"""
This is a first pass at a simple read only python-novaclient test. This
@@ -49,7 +47,7 @@
super(SimpleReadOnlyNovaClientTest, cls).setUpClass()
def test_admin_fake_action(self):
- self.assertRaises(subprocess.CalledProcessError,
+ self.assertRaises(cli.CommandFailed,
self.nova,
'this-does-nova-exist')
@@ -86,11 +84,11 @@
self.nova('endpoints')
def test_admin_flavor_acces_list(self):
- self.assertRaises(subprocess.CalledProcessError,
+ self.assertRaises(cli.CommandFailed,
self.nova,
'flavor-access-list')
# Failed to get access list for public flavor type
- self.assertRaises(subprocess.CalledProcessError,
+ self.assertRaises(cli.CommandFailed,
self.nova,
'flavor-access-list',
params='--flavor m1.tiny')
@@ -127,7 +125,7 @@
self.nova('list')
self.nova('list', params='--all-tenants 1')
self.nova('list', params='--all-tenants 0')
- self.assertRaises(subprocess.CalledProcessError,
+ self.assertRaises(cli.CommandFailed,
self.nova,
'list',
params='--all-tenants bad')
diff --git a/tempest/cli/simple_read_only/test_nova_manage.py b/tempest/cli/simple_read_only/test_nova_manage.py
index f1fee2e..67c19d8 100644
--- a/tempest/cli/simple_read_only/test_nova_manage.py
+++ b/tempest/cli/simple_read_only/test_nova_manage.py
@@ -13,9 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import subprocess
-
-import tempest.cli
+from tempest import cli
from tempest import config
from tempest.openstack.common import log as logging
@@ -24,7 +22,7 @@
LOG = logging.getLogger(__name__)
-class SimpleReadOnlyNovaManageTest(tempest.cli.ClientTestBase):
+class SimpleReadOnlyNovaManageTest(cli.ClientTestBase):
"""
This is a first pass at a simple read only nova-manage test. This
@@ -48,7 +46,7 @@
super(SimpleReadOnlyNovaManageTest, cls).setUpClass()
def test_admin_fake_action(self):
- self.assertRaises(subprocess.CalledProcessError,
+ self.assertRaises(cli.CommandFailed,
self.nova_manage,
'this-does-nova-exist')
diff --git a/tempest/cli/simple_read_only/test_sahara.py b/tempest/cli/simple_read_only/test_sahara.py
index f00dcae..773921a 100644
--- a/tempest/cli/simple_read_only/test_sahara.py
+++ b/tempest/cli/simple_read_only/test_sahara.py
@@ -14,7 +14,6 @@
# limitations under the License.
import logging
import re
-import subprocess
from tempest import cli
from tempest import config
@@ -42,7 +41,7 @@
@test.attr(type='negative')
def test_sahara_fake_action(self):
- self.assertRaises(subprocess.CalledProcessError,
+ self.assertRaises(cli.CommandFailed,
self.sahara,
'this-does-not-exist')
diff --git a/tempest/cli/simple_read_only/test_swift.py b/tempest/cli/simple_read_only/test_swift.py
index 6d6caa7..c778542 100644
--- a/tempest/cli/simple_read_only/test_swift.py
+++ b/tempest/cli/simple_read_only/test_swift.py
@@ -14,15 +14,14 @@
# under the License.
import re
-import subprocess
-import tempest.cli
+from tempest import cli
from tempest import config
CONF = config.CONF
-class SimpleReadOnlySwiftClientTest(tempest.cli.ClientTestBase):
+class SimpleReadOnlySwiftClientTest(cli.ClientTestBase):
"""Basic, read-only tests for Swift CLI client.
Checks return values and output of read-only commands.
@@ -38,7 +37,7 @@
super(SimpleReadOnlySwiftClientTest, cls).setUpClass()
def test_swift_fake_action(self):
- self.assertRaises(subprocess.CalledProcessError,
+ self.assertRaises(cli.CommandFailed,
self.swift,
'this-does-not-exist')
diff --git a/tempest/tests/cli/test_command_failed.py b/tempest/tests/cli/test_command_failed.py
new file mode 100644
index 0000000..c539ac6
--- /dev/null
+++ b/tempest/tests/cli/test_command_failed.py
@@ -0,0 +1,30 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest import cli
+from tempest.tests import base
+
+
+class TestOutputParser(base.TestCase):
+
+ def test_command_failed_exception(self):
+ returncode = 1
+ cmd = "foo"
+ stdout = "output"
+ stderr = "error"
+ try:
+ raise cli.CommandFailed(returncode, cmd, stdout, stderr)
+ except cli.CommandFailed as e:
+ self.assertIn(str(returncode), str(e))
+ self.assertIn(cmd, str(e))
+ self.assertIn(stdout, str(e))
+ self.assertIn(stderr, str(e))