Skip to content

Commit

Permalink
nose plugin to capture glance service logs
Browse files Browse the repository at this point in the history
Adding custom nose plugin to capture entire glance service logs
for failed tests.

Disabled by default, enable by setting:

  $ NOSE_GLANCELOGCAPTURE=true ; ./run_tests.sh

Change-Id: I8a3bd9529ec6adb8b98804e0ddc266a7ea8eca08
  • Loading branch information
Eoghan Glynn committed Mar 16, 2012
1 parent e1fae1d commit 2145c24
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 1 deletion.
19 changes: 19 additions & 0 deletions glance/tests/functional/__init__.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -395,6 +395,7 @@ def setUp(self):
self.registry_server.pid_file, self.registry_server.pid_file,
self.scrubber_daemon.pid_file] self.scrubber_daemon.pid_file]
self.files_to_destroy = [] self.files_to_destroy = []
self.log_files = []


def tearDown(self): def tearDown(self):
if not self.disabled: if not self.disabled:
Expand Down Expand Up @@ -485,6 +486,8 @@ def start_server(self,


self.assertTrue(re.search("Starting glance-[a-z]+ with", out)) self.assertTrue(re.search("Starting glance-[a-z]+ with", out))


self.log_files.append(server.log_file)

self.wait_for_servers([server.bind_port], expect_launch) self.wait_for_servers([server.bind_port], expect_launch)


def start_servers(self, **kwargs): def start_servers(self, **kwargs):
Expand All @@ -500,13 +503,17 @@ def start_servers(self, **kwargs):
# Start up the API and default registry server # Start up the API and default registry server
exitcode, out, err = self.api_server.start(**kwargs) exitcode, out, err = self.api_server.start(**kwargs)


self.log_files.append(self.api_server.log_file)

self.assertEqual(0, exitcode, self.assertEqual(0, exitcode,
"Failed to spin up the API server. " "Failed to spin up the API server. "
"Got: %s" % err) "Got: %s" % err)
self.assertTrue("Starting glance-api with" in out) self.assertTrue("Starting glance-api with" in out)


exitcode, out, err = self.registry_server.start(**kwargs) exitcode, out, err = self.registry_server.start(**kwargs)


self.log_files.append(self.registry_server.log_file)

self.assertEqual(0, exitcode, self.assertEqual(0, exitcode,
"Failed to spin up the Registry server. " "Failed to spin up the Registry server. "
"Got: %s" % err) "Got: %s" % err)
Expand Down Expand Up @@ -619,3 +626,15 @@ def copy_data_file(self, file_name, dst_dir):
shutil.copy(src_file_name, dst_dir) shutil.copy(src_file_name, dst_dir)
dst_file_name = os.path.join(dst_dir, file_name) dst_file_name = os.path.join(dst_dir, file_name)
return dst_file_name return dst_file_name

def dump_logs(self):
dump = ''
for log in self.log_files:
dump += '\nContent of %s:\n\n' % log
if os.path.exists(log):
f = open(log, 'r')
for line in f:
dump += line
else:
dump += '<empty>'
return dump
60 changes: 60 additions & 0 deletions glance/tests/logcapture.py
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,60 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4

# Copyright 2012 Red Hat, Inc
# All Rights Reserved.
#
# 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.

"""
Custom nose plugin to capture the entire glance service logs for failed tests.
"""

from glance.tests import functional

from nose.plugins.base import Plugin
from nose.util import ln, safe_str


class GlanceLogCapture(Plugin):
enabled = False
env_opt = 'NOSE_GLANCELOGCAPTURE'
name = 'glance-logcapture'

def options(self, parser, env):
parser.add_option(
"--glance-logcapture",
action="store_true",
default=env.get(self.env_opt),
dest="glance_logcapture",
help="Enable glance log capture plugin [NOSE_GLANCELOGCAPTURE]")

def configure(self, options, conf):
self.enabled = options.glance_logcapture

def formatFailure(self, test, err):
return self.formatError(test, err)

def formatError(self, test, err):
if self.enabled:
ec, ev, tb = err
err = (ec, self._dump_logs(ev, test), tb)
return err

def _dump_logs(self, ev, test):
ret = ev
if isinstance(test.test, functional.FunctionalTest):
ret = '\n'.join([safe_str(ev),
ln('>> begin captured glance logging <<')] +
[test.test.dump_logs()] +
[ln('>> end captured glance logging <<')])
return ret
5 changes: 4 additions & 1 deletion run_tests.py
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@


gettext.install('glance', unicode=1) gettext.install('glance', unicode=1)


from glance.tests import logcapture

from nose import config from nose import config
from nose import result from nose import result
from nose import core from nose import core
Expand Down Expand Up @@ -290,4 +292,5 @@ def _makeResult(self):
runner = GlanceTestRunner(stream=c.stream, runner = GlanceTestRunner(stream=c.stream,
verbosity=c.verbosity, verbosity=c.verbosity,
config=c) config=c)
sys.exit(not core.run(config=c, testRunner=runner)) sys.exit(not core.run(config=c, testRunner=runner,
addplugins=[logcapture.GlanceLogCapture()]))

0 comments on commit 2145c24

Please sign in to comment.