diff --git a/doc/api_samples/os-coverage/coverage-reset-post-req.json b/doc/api_samples/os-coverage/coverage-reset-post-req.json new file mode 100644 index 000000000000..e5a22bb2b4f2 --- /dev/null +++ b/doc/api_samples/os-coverage/coverage-reset-post-req.json @@ -0,0 +1,4 @@ +{ + "reset" : { + } +} diff --git a/doc/api_samples/os-coverage/coverage-reset-post-req.xml b/doc/api_samples/os-coverage/coverage-reset-post-req.xml new file mode 100644 index 000000000000..b7971ad27920 --- /dev/null +++ b/doc/api_samples/os-coverage/coverage-reset-post-req.xml @@ -0,0 +1,2 @@ + + diff --git a/nova/api/openstack/compute/contrib/coverage_ext.py b/nova/api/openstack/compute/contrib/coverage_ext.py index ad30987fff75..b8a1681d05ac 100644 --- a/nova/api/openstack/compute/contrib/coverage_ext.py +++ b/nova/api/openstack/compute/contrib/coverage_ext.py @@ -259,18 +259,41 @@ class CoverageController(object): output.close() return {'path': path} + def _reset_coverage_telnet(self, tn): + tn.write("coverInst.erase()\n") + tn.write("print 'finished'\n") + tn.expect([re.compile('finished')]) + + def _reset_coverage(self, req): + # Reopen telnet connections if they are closed. + for service in self.services: + if not service['telnet'].get_socket(): + service['telnet'].open(service['host'], service['port']) + + # Stop coverage if it is started. + try: + self._stop_coverage(req) + except exc.HTTPNotFound: + pass + + for service in self.services: + self._reset_coverage_telnet(service['telnet']) + service['telnet'].close() + self.coverInst.erase() + def action(self, req, body): _actions = { 'start': self._start_coverage, 'stop': self._stop_coverage, 'report': self._report_coverage, + 'reset': self._reset_coverage, } authorize(req.environ['nova.context']) if not self.coverInst: msg = _("Python coverage module is not installed.") raise exc.HTTPServiceUnavailable(explanation=msg) for action, data in body.iteritems(): - if action == 'stop': + if action == 'stop' or action == 'reset': return _actions[action](req) elif action == 'report' or action == 'start': return _actions[action](req, body) diff --git a/nova/tests/api/openstack/compute/contrib/test_coverage_ext.py b/nova/tests/api/openstack/compute/contrib/test_coverage_ext.py index 6d66f8d743b3..cd4229ddd4ed 100644 --- a/nova/tests/api/openstack/compute/contrib/test_coverage_ext.py +++ b/nova/tests/api/openstack/compute/contrib/test_coverage_ext.py @@ -56,6 +56,9 @@ class FakeCoverage(object): def xml_report(self, outfile): pass + def erase(self): + pass + class CoverageExtensionTest(test.TestCase): @@ -202,3 +205,25 @@ class CoverageExtensionTest(test.TestCase): res = req.get_response(fakes.wsgi_app( fake_auth_context=self.admin_context)) self.assertEqual(res.status_int, 404) + + def test_reset_coverage_action_while_coverage_running(self): + self.stubs.Set(coverage_ext.CoverageController, + '_check_coverage', fake_check_coverage) + body = {'reset': {}} + req = webob.Request.blank('/v2/fake/os-coverage/action') + req.method = "POST" + req.body = jsonutils.dumps(body) + req.headers["content-type"] = "application/json" + res = req.get_response(fakes.wsgi_app( + fake_auth_context=self.admin_context)) + self.assertEqual(res.status_int, 200) + + def test_reset_coverage_action_while_coverage_stopped(self): + body = {'reset': {}} + req = webob.Request.blank('/v2/fake/os-coverage/action') + req.method = "POST" + req.body = jsonutils.dumps(body) + req.headers["content-type"] = "application/json" + res = req.get_response(fakes.wsgi_app( + fake_auth_context=self.admin_context)) + self.assertEqual(res.status_int, 200)