From patchwork Tue Feb 7 22:38:11 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zygmunt Krynicki X-Patchwork-Id: 6695 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 9689D23EB0 for ; Tue, 7 Feb 2012 22:38:15 +0000 (UTC) Received: from mail-iy0-f180.google.com (mail-iy0-f180.google.com [209.85.210.180]) by fiordland.canonical.com (Postfix) with ESMTP id 46E5BA18788 for ; Tue, 7 Feb 2012 22:38:15 +0000 (UTC) Received: by mail-iy0-f180.google.com with SMTP id z7so14490583iab.11 for ; Tue, 07 Feb 2012 14:38:15 -0800 (PST) Received: by 10.42.57.148 with SMTP id d20mr24216374ich.33.1328654293286; Tue, 07 Feb 2012 14:38:13 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.231.169.210 with SMTP id a18cs138476ibz; Tue, 7 Feb 2012 14:38:13 -0800 (PST) Received: by 10.180.86.9 with SMTP id l9mr37105995wiz.15.1328654292226; Tue, 07 Feb 2012 14:38:12 -0800 (PST) Received: from indium.canonical.com (indium.canonical.com. [91.189.90.7]) by mx.google.com with ESMTPS id n44si14284105weq.49.2012.02.07.14.38.11 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 07 Feb 2012 14:38:12 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.7 as permitted sender) client-ip=91.189.90.7; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.7 as permitted sender) smtp.mail=bounces@canonical.com Received: from ackee.canonical.com ([91.189.89.26]) by indium.canonical.com with esmtp (Exim 4.71 #1 (Debian)) id 1Rutfv-0000ch-Mf for ; Tue, 07 Feb 2012 22:38:11 +0000 Received: from ackee.canonical.com (localhost [127.0.0.1]) by ackee.canonical.com (Postfix) with ESMTP id 97134E04F6 for ; Tue, 7 Feb 2012 22:38:11 +0000 (UTC) MIME-Version: 1.0 X-Launchpad-Project: lava-test X-Launchpad-Branch: ~linaro-validation/lava-test/trunk X-Launchpad-Message-Rationale: Subscriber X-Launchpad-Branch-Revision-Number: 112 X-Launchpad-Notification-Type: branch-revision To: Linaro Patch Tracker From: noreply@launchpad.net Subject: [Branch ~linaro-validation/lava-test/trunk] Rev 112: Fix exception handler for RegistryProvider._fill_cache() Message-Id: <20120207223811.13301.1100.launchpad@ackee.canonical.com> Date: Tue, 07 Feb 2012 22:38:11 -0000 Reply-To: noreply@launchpad.net Sender: bounces@canonical.com Errors-To: bounces@canonical.com Precedence: bulk X-Generated-By: Launchpad (canonical.com); Revision="14747"; Instance="launchpad-lazr.conf" X-Launchpad-Hash: ffe8832ce36dbe0d8ac91cc51d31e5cd9bde8fd6 Merge authors: Zygmunt Krynicki (zkrynicki) Related merge proposals: https://code.launchpad.net/~zkrynicki/lava-test/fix-926867/+merge/91689 proposed by: Zygmunt Krynicki (zkrynicki) review: Approve - Paul Larson (pwlars) ------------------------------------------------------------ revno: 112 [merge] committer: Zygmunt Krynicki branch nick: trunk timestamp: Tue 2012-02-07 23:35:15 +0100 message: Fix exception handler for RegistryProvider._fill_cache() removed: .testr.conf added: tests/test_providers.py modified: .bzrignore MANIFEST.in lava_test/core/providers.py setup.py tests/__init__.py --- lp:lava-test https://code.launchpad.net/~linaro-validation/lava-test/trunk You are subscribed to branch lp:lava-test. To unsubscribe from this branch go to https://code.launchpad.net/~linaro-validation/lava-test/trunk/+edit-subscription === modified file '.bzrignore' --- .bzrignore 2011-09-12 09:19:10 +0000 +++ .bzrignore 2012-02-04 20:53:31 +0000 @@ -1,8 +1,7 @@ +*.egg +*.egg-info +*.tmp .idea .testrepository +build dist -lava_test.egg-info -*~ -*.tmp -*.py[co] -build === removed file '.testr.conf' --- .testr.conf 2010-06-14 20:32:28 +0000 +++ .testr.conf 1970-01-01 00:00:00 +0000 @@ -1,3 +0,0 @@ -[DEFAULT] -test_command=PYTHONPATH=. python -m subunit.run $IDLIST -test_id_list_default=tests.test_suite === modified file 'MANIFEST.in' --- MANIFEST.in 2011-09-12 09:19:10 +0000 +++ MANIFEST.in 2012-02-06 15:47:49 +0000 @@ -1,3 +1,2 @@ include COPYING include README -include .testr.conf === modified file 'lava_test/core/providers.py' --- lava_test/core/providers.py 2012-01-18 21:45:51 +0000 +++ lava_test/core/providers.py 2012-02-06 17:51:19 +0000 @@ -172,19 +172,18 @@ if test.test_id in self._cache: raise ValueError("Duplicate test %s declared" % test.test_id) self._cache[test.test_id] = test - except IOError, err: - logging.warning("Failed to load the " + test_url) - if hasattr(e, 'reason'): - logging.warning("WARNING: URL Reason: "+ e.reason) - elif hasattr(e, 'code'): - logging.warning('WARNING: URL Error code: ' + e.code) - else: - logging.exception("WARNING: Unknown IO error", str(err)) - except ValueError, err: - logging.warning('Error found when parsing the' + test_url) - except Exception, err: - logging.warning('Failed to load the' + test_url) - logging.warning("Unknown exception : " + str(err)) + except IOError as exc: + logging.warning( + "Unable to load test definition from %r: %r", test_url, exc) + if hasattr(exc, 'reason'): + logging.warning("Error reason: %r", exc.reason) + elif hasattr(exc, 'code'): + logging.warning('Error code: %r', exc.code) + except Exception as exc: + # This can be a number of things, including URL errors, JSON + # errors and validation errors + logging.warning('Unable to load test definition from %r: %r', + test_url, exc) def __iter__(self): self._fill_cache() === modified file 'setup.py' --- setup.py 2011-09-12 09:19:10 +0000 +++ setup.py 2012-02-06 15:48:33 +0000 @@ -28,7 +28,7 @@ long_description=open("README").read(), packages=find_packages(exclude=['tests']), license="GNU GPLv3", - test_suite='tests.test_suite', + test_suite='unittest2.collector', entry_points=""" [console_scripts] lava-test=lava_test.main:main @@ -60,5 +60,9 @@ setup_requires=[ 'versiontools >= 1.4' ], + tests_require=[ + 'unittest2', + 'mocker >= 1.1', + ], zip_safe=False, include_package_data=True) === modified file 'tests/__init__.py' --- tests/__init__.py 2011-09-12 09:19:10 +0000 +++ tests/__init__.py 2012-02-04 20:50:16 +0000 @@ -12,17 +12,3 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see . - -import unittest - -def test_suite(): - module_names = ['tests.test_lavatest_commands', - 'tests.test_lavatest_test', - 'tests.test_lavatest_testinstaller', - 'tests.test_lavatest_testparser', - 'tests.test_lavatest_testrunner', - 'tests.test_hwprofile', - 'tests.test_swprofile'] - loader = unittest.TestLoader() - suite = loader.loadTestsFromNames(module_names) - return suite === added file 'tests/test_providers.py' --- tests/test_providers.py 1970-01-01 00:00:00 +0000 +++ tests/test_providers.py 2012-02-06 17:51:19 +0000 @@ -0,0 +1,105 @@ +# Copyright (c) 2012 Linaro Limited +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +from mocker import MockerTestCase + +from lava_test.core.providers import RegistryProvider + + +class RegistryProviderTests(MockerTestCase): + + # Helper values used in test methods + _code = 1 + _reason = "reason" + _test_id = 'test1' + _test_id_list = ['test1', 'test2'] + _url = "http://example.org/test.json" + + def _prepare_provider_that_crashes_with_error(self, error): + self.provider = self.mocker.patch( + RegistryProvider({'entries': [self._url]})) + self.expect(self.provider._fill_cache()).passthrough() + self.expect(self.provider._load_remote_test(self._url)).throw(error) + + def _test_fill_cache_response(self): + # Now onto testing: + self.mocker.replay() + # Call _fill_cache() + self.provider._fill_cache() + # the actual tests are validated as mocker expectation + + def test_fill_cache_IOError_handling_with_just_reason(self): + # We want to test resilience to IOError that has a 'reason' attribute + error = IOError() + error.reason = self._reason + self._prepare_provider_that_crashes_with_error(error) + # Now this ought to log a few warning messages + logging = self.mocker.replace("logging", passthrough=False) + logging.warning( + "Unable to load test definition from %r: %r", + self._url, error) + logging.warning("Error reason: %r", self._reason) + self._test_fill_cache_response() + + def test_fill_cache_IOError_handling_with_just_code(self): + # We want to test resilience to IOError that has a 'code' attribute + error = IOError() + error.code = self._code + provider = self._prepare_provider_that_crashes_with_error(error) + # Now this ought to log a few warning messages + logging = self.mocker.replace("logging", passthrough=False) + logging.warning( + "Unable to load test definition from %r: %r", + self._url, error) + logging.warning("Error code: %r", self._code) + self._test_fill_cache_response() + + def test_fill_cache_IOError_handling_without_anything(self): + # We want to test resilience to IOError that has no attributes + error = IOError() + provider = self._prepare_provider_that_crashes_with_error(error) + # Now this ought to log a few warning messages + logging = self.mocker.replace("logging", passthrough=False) + logging.warning( + "Unable to load test definition from %r: %r", + self._url, error) + self._test_fill_cache_response() + + def test_fill_cache_ValueError_handling(self): + # We want to test resilience to ValueError + error = ValueError() + provider = self._prepare_provider_that_crashes_with_error(error) + # Now this ought to log a few warning messages + logging = self.mocker.replace("logging", passthrough=False) + logging.warning( + "Unable to load test definition from %r: %r", + self._url, error) + self._test_fill_cache_response() + + def test_iter_calls_fill_cache(self): + provider = self.mocker.patch(RegistryProvider({})) + self.expect(iter(provider)).passthrough() + self.expect(provider._fill_cache()) + self.expect(provider._cache.iterkeys()).generate(self._test_id_list) + self.mocker.replay() + self.assertSequenceEqual(list(provider), self._test_id_list) + + def test_getitem_calls_fill_cache(self): + provider = self.mocker.patch(RegistryProvider({})) + self.expect(provider[self._test_id]).passthrough() + self.expect(provider._fill_cache()) + self.expect(provider._cache[self._test_id]) + self.mocker.replay() + provider[self._test_id]