diff --git a/.gitignore b/.gitignore index 812791c1bb..ce9b613f12 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ run_tests.log guest-agent-files.txt reddwarf.egg* reddwarf/vcsversion.py +*py*.egg diff --git a/reddwarf/db/sqlalchemy/api.py b/reddwarf/db/sqlalchemy/api.py index 393a3614ec..f9e3f592ff 100644 --- a/reddwarf/db/sqlalchemy/api.py +++ b/reddwarf/db/sqlalchemy/api.py @@ -113,18 +113,9 @@ def db_downgrade(options, version, repo_path=None): def db_reset(options, *plugins): drop_db(options) db_sync(options) - db_reset_for_plugins(options, *plugins) configure_db(options) -def db_reset_for_plugins(options, *plugins): - for plugin in plugins: - repo_path = plugin.migrate_repo_path() - if repo_path: - db_sync(options, repo_path=repo_path) - configure_db(options, *plugins) - - def _base_query(cls): return session.get_session().query(cls) diff --git a/reddwarf/tests/__init__.py b/reddwarf/tests/__init__.py index 4fedc93665..ef0194fed1 100644 --- a/reddwarf/tests/__init__.py +++ b/reddwarf/tests/__init__.py @@ -29,6 +29,7 @@ import urlparse import mox from reddwarf.db import db_api +from reddwarf.common import config from reddwarf.common import utils @@ -55,6 +56,9 @@ class BaseTest(unittest.TestCase): self.maxDiff = None self.mock = mox.Mox() + conf, reddwarf_app = config.Config.load_paste_app('reddwarfapp', + {"config_file": test_config_file()}, None) + db_api.configure_db(conf) db_api.clean_db() super(BaseTest, self).setUp() diff --git a/reddwarf/tests/functional/__init__.py b/reddwarf/tests/functional/__init__.py new file mode 100644 index 0000000000..2f61369ecb --- /dev/null +++ b/reddwarf/tests/functional/__init__.py @@ -0,0 +1,65 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 OpenStack LLC. +# 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. + +import os +import subprocess + +from reddwarf import tests +from reddwarf.common import config +from reddwarf.db import db_api + + +def setup(): + options = dict(config_file=tests.test_config_file()) + conf = config.Config.load_paste_config("reddwarf", options, None) + + db_api.db_reset(conf) + + +def execute(cmd, raise_error=True): + """Executes a command in a subprocess. + Returns a tuple of (exitcode, out, err), where out is the string output + from stdout and err is the string output from stderr when + executing the command. + + :param cmd: Command string to execute + :param raise_error: If returncode is not 0 (success), then + raise a RuntimeError? Default: True) + + """ + + env = os.environ.copy() + + # Make sure that we use the programs in the + # current source directory's bin/ directory. + env['PATH'] = tests.reddwarf_bin_path() + ':' + env['PATH'] + process = subprocess.Popen(cmd, + shell=True, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + env=env) + result = process.communicate() + (out, err) = result + exitcode = process.returncode + if process.returncode != 0 and raise_error: + msg = "Command %(cmd)s did not succeed. Returned an exit "\ + "code of %(exitcode)d."\ + "\n\nSTDOUT: %(out)s"\ + "\n\nSTDERR: %(err)s" % locals() + raise RuntimeError(msg) + return exitcode, out, err diff --git a/reddwarf/tests/functional/test_cli.py b/reddwarf/tests/functional/test_cli.py new file mode 100644 index 0000000000..8e8d298717 --- /dev/null +++ b/reddwarf/tests/functional/test_cli.py @@ -0,0 +1,44 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 OpenStack LLC. +# 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. + +import datetime + +import reddwarf +from reddwarf import tests +from reddwarf.common import config +from reddwarf.tests import functional + + +def run_reddwarf_manage(command): + reddwarf_manage = tests.reddwarf_bin_path('reddwarf-manage') + config_file = tests.test_config_file() + return functional.execute("%(reddwarf_manage)s %(command)s " + "--config-file=%(config_file)s" % locals()) + + +class TestDBSyncCLI(tests.BaseTest): + + def test_db_sync_executes(self): + exitcode, out, err = run_reddwarf_manage("db_sync") + self.assertEqual(exitcode, 0) + + +class TestDBUpgradeCLI(tests.BaseTest): + + def test_db_upgrade_executes(self): + exitcode, out, err = run_reddwarf_manage("db_upgrade") + self.assertEqual(exitcode, 0) diff --git a/reddwarf/tests/unit/__init__.py b/reddwarf/tests/unit/__init__.py index 0519dd3ece..c471059726 100644 --- a/reddwarf/tests/unit/__init__.py +++ b/reddwarf/tests/unit/__init__.py @@ -1 +1,76 @@ -__author__ = 'mbasnight' +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2011 OpenStack LLC. +# 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. + +import json +import webtest + +from reddwarf import tests +from reddwarf.common import config +from reddwarf.common import utils +from reddwarf.common import wsgi +from reddwarf.db import db_api + + +def sanitize(data): + serializer = wsgi.JSONDictSerializer() + return json.loads(serializer.serialize(data)) + + +class StubConfig(): + + def __init__(self, **options): + self.options = options + + def __enter__(self): + self.actual_config = config.Config.instance + temp_config = self.actual_config.copy() + temp_config.update(self.options) + config.Config.instance = temp_config + + def __exit__(self, exc_type, exc_value, traceback): + config.Config.instance = self.actual_config + + +class StubTime(object): + + def __init__(self, time): + self.time = time + + def __enter__(self): + self.actual_provider = utils.utcnow + utils.utcnow = lambda: self.time + + def __exit__(self, exc_type, exc_value, traceback): + utils.utcnow = self.actual_provider + + +class TestApp(webtest.TestApp): + + def post_json(self, url, body=None, **kwargs): + kwargs['content_type'] = "application/json" + return self.post(url, json.dumps(body), **kwargs) + + def put_json(self, url, body=None, **kwargs): + kwargs['content_type'] = "application/json" + return self.put(url, json.dumps(body), **kwargs) + + +def setup(): + options = {"config_file": tests.test_config_file()} + conf = config.Config.load_paste_config("reddwarfapp", options, None) + + db_api.db_reset(conf) diff --git a/reddwarf/tests/unit/test_database_service.py b/reddwarf/tests/unit/test_database_service.py new file mode 100644 index 0000000000..7f197ff638 --- /dev/null +++ b/reddwarf/tests/unit/test_database_service.py @@ -0,0 +1,72 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 +# Copyright 2011 OpenStack LLC. +# 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. + +import mox +import logging + +from reddwarf import tests +from reddwarf.common import config +from reddwarf.common import wsgi +from reddwarf.database import models +from reddwarf.database import service +from reddwarf.tests import unit + + +LOG = logging.getLogger(__name__) + + +class ControllerTestBase(tests.BaseTest): + + def setUp(self): + super(ControllerTestBase, self).setUp() + conf, reddwarf_app = config.Config.load_paste_app('reddwarfapp', + {"config_file": tests.test_config_file()}, None) + self.app = unit.TestApp(reddwarf_app) + + +class DummyApp(wsgi.Router): + + def __init__(self, controller): + mapper = routes.Mapper() + mapper.resource("resource", "/resources", + controller=controller.create_resource()) + super(DummyApp, self).__init__(mapper) + + +class TestInstanceController(ControllerTestBase): + + DUMMY_INSTANCE_ID = "123" + + def setUp(self): + self.instances_path = "/tenant/instances" + super(TestInstanceController, self).setUp() + + def test_show(self): + # block = factory_models.IpBlockFactory() + instance = mox.MockAnything() + self.mock.StubOutWithMock(models.Instance, 'data') + models.Instance.data().AndReturn({"id": self.DUMMY_INSTANCE_ID, + "name": "DUMMY_NAME", + "status": "BUILD"}) + self.mock.StubOutWithMock(models.Instance, '__init__') + models.Instance.__init__(context=mox.IgnoreArg(), uuid=mox.IgnoreArg()) + self.mock.ReplayAll() + + response = self.app.get("%s/%s" % (self.instances_path, + self.DUMMY_INSTANCE_ID), + headers={'X-Auth-Token': '123'}) + + self.assertEqual(response.status_int, 201)