diff --git a/glareclient/tests/unit/osc/v1/__init__.py b/glareclient/tests/unit/osc/v1/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/glareclient/tests/unit/osc/v1/fakes.py b/glareclient/tests/unit/osc/v1/fakes.py new file mode 100644 index 0000000..d644615 --- /dev/null +++ b/glareclient/tests/unit/osc/v1/fakes.py @@ -0,0 +1,86 @@ +# Copyright 2016 OpenStack Foundation +# 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 sys + + +from glareclient.common import utils as g_utils +import mock +from osc_lib.tests import utils + + +def mock_list(*args, **kwargs): + return [{'id': 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba', + 'name': 'art1', + 'version': '0.0.0', + 'owner': 'f649c77999e449e89627024f71b76603', + 'visibility': 'private', + 'status': 'active'}, + {'id': '48d35c1d-6739-459b-bbda-e4dcba8a684a', + 'name': 'art2', + 'version': '0.0.0', + 'owner': 'f649c77999e449e89627024f71b76603', + 'visibility': 'private', + 'status': 'active'}] + + +def mock_get(*args, **kwargs): + return {'id': 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba', + 'name': 'art1', + 'version': '0.0.0', + 'owner': 'f649c77999e449e89627024f71b76603', + 'visibility': 'private', + 'status': 'active', + 'blob': {'size': 1}, + 'image': {'size': 1}, + 'package': {'size': 1}, + 'template': {'size': 1}, + 'environment': {'size': 1}} + + +def mock_g_servs(*args, **kwargs): + return {'id': 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba', + 'name': 'art1', + 'version': '0.0.0', + 'owner': 'f649c77999e449e89627024f71b76603', + 'visibility': 'private', + 'status': 'active'} + + +def mock_get_data_file(*args, **kwargs): + return 'data' + + +class TestArtifacts(utils.TestCommand): + + def setUp(self): + super(TestArtifacts, self).setUp() + self.app.client_manager.artifact = mock.MagicMock() + self.app.client_manager.artifact.artifacts.list = mock_list + self.app.client_manager.artifact.artifacts.get = mock_get + self.app.client_manager.artifact.artifacts.create = mock_g_servs + self.app.client_manager.artifact.artifacts.update = mock_g_servs + self.app.client_manager.artifact.artifacts.delete = mock_g_servs + self.app.client_manager.artifact.artifacts.active = mock_g_servs + self.app.client_manager.artifact.artifacts.deactivate = mock_g_servs + self.app.client_manager.artifact.artifacts.reactivate = mock_g_servs + self.app.client_manager.artifact.artifacts.publish = mock_g_servs + self.app.client_manager.artifact.blobs.upload_blob = mock_g_servs + self.app.client_manager.artifact.blobs.download_blob = mock_g_servs + g_utils.get_data_file = mock.MagicMock() + g_utils.get_data_file = mock_get_data_file + g_utils.save_blob = mock.MagicMock() + sys.stdout.isatty = mock.MagicMock() + sys.stdout.isatty._mock_return_value = True diff --git a/glareclient/tests/unit/osc/v1/test_artifacts.py b/glareclient/tests/unit/osc/v1/test_artifacts.py new file mode 100644 index 0000000..2146045 --- /dev/null +++ b/glareclient/tests/unit/osc/v1/test_artifacts.py @@ -0,0 +1,345 @@ +# Copyright (c) 2016 Mirantis, Inc. +# +# 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 mock + +import testtools + +from glareclient.osc.v1 import artifacts as osc_art +from glareclient.tests.unit.osc.v1 import fakes +from glareclient.v1 import artifacts as api_art +from osc_lib.tests.utils import ParserException + + +class TestArtifacts(fakes.TestArtifacts): + def setUp(self): + super(TestArtifacts, self).setUp() + self.artifact_mock = \ + self.app.client_manager.artifact.artifacts + self.http = mock.MagicMock() + + +class TestListArtifacts(TestArtifacts): + + def setUp(self): + super(TestListArtifacts, self).setUp() + self.artifact_mock.call.return_value = \ + api_art.Controller(self.http, type_name='sample_artifact') + + # Command to test + self.cmd = osc_art.ListArtifacts(self.app, None) + self.COLUMNS = ['Id', 'Name', 'Version', + 'Owner', 'Visibility', 'Status'] + + def test_artifact_list(self): + arglist = ['sample_artifact'] + verify = [('type_name', 'sample_artifact')] + + parsed_args = self.check_parser(self.cmd, arglist, verify) + + columns, data = self.cmd.take_action(parsed_args) + + # Check that columns are correct + self.assertEqual(self.COLUMNS, columns) + + self.check_parser(self.cmd, arglist, verify) + + def test_artifact_list_with_multifilters(self): + arglist = ['sample_artifact', + '--filter', 'spam:spam', + '--filter', 'maps:maps'] + verify = [('type_name', 'sample_artifact'), + ('filter', ['spam:spam', 'maps:maps'])] + + self.check_parser(self.cmd, arglist, verify) + + def test_artifact_list_with_sort(self): + arglist = ['sample_artifact', '--sort', 'name:asc'] + verify = [('type_name', 'sample_artifact'), + ('sort', 'name:asc')] + + self.check_parser(self.cmd, arglist, verify) + + def test_artifact_list_with_multisort(self): + arglist = ['sample_artifact', + '--sort', 'name:desc', + '--sort', 'name:asc'] + verify = [('type_name', 'sample_artifact'), + ('sort', 'name:asc')] + self.check_parser(self.cmd, arglist, verify) + + def test_artifact_list_page_size(self): + arglist = ['sample_artifact', '--page-size', '1'] + verify = [('type_name', 'sample_artifact'), + ('page_size', '1')] + self.check_parser(self.cmd, arglist, verify) + + def test_artifact_list_limit(self): + arglist = ['sample_artifact', '--limit', '2'] + verify = [('type_name', 'sample_artifact'), + ('limit', '2')] + self.check_parser(self.cmd, arglist, verify) + + def test_artifact_list_multilimit(self): + arglist = ['sample_artifact', '--limit', '2', '--limit', '1'] + verify = [('type_name', 'sample_artifact'), + ('limit', '1')] + self.check_parser(self.cmd, arglist, verify) + + +class TestShowArtifacts(TestArtifacts): + + def setUp(self): + super(TestShowArtifacts, self).setUp() + self.artifact_mock.call.return_value = \ + api_art.Controller(self.http, type_name='sample_artifact') + + # Command to test + self.cmd = osc_art.ShowArtifact(self.app, None) + self.COLUMNS = ('id', 'name', 'owner', + 'status', 'version', 'visibility') + + def test_artifact_show(self): + arglist = ['sample_artifact', 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba'] + verify = [('type_name', 'sample_artifact')] + COLUMNS = ('blob', 'environment', 'id', 'image', 'name', 'owner', + 'package', 'status', 'template', 'version', 'visibility') + + parsed_args = self.check_parser(self.cmd, arglist, verify) + columns, data = self.cmd.take_action(parsed_args) + + # Check that columns are correct + self.assertEqual(COLUMNS, columns) + + def test_artifact_show_without_id(self): + arglist = ['sample_artifact'] + verify = [('type_name', 'sample_artifact')] + + with testtools.ExpectedException(ParserException): + self.check_parser(self.cmd, arglist, verify) + + def test_artifact_show_without_type_id(self): + arglist = ['fc15c365-d4f9-4b8b-a090-d9e230f1f6ba'] + verify = [('type_name', 'sample_artifact')] + + with testtools.ExpectedException(ParserException): + self.check_parser(self.cmd, arglist, verify) + + +class TestCreateArtifacts(TestArtifacts): + + def setUp(self): + super(TestCreateArtifacts, self).setUp() + self.artifact_mock.call.return_value = \ + api_art.Controller(self.http, type_name='sample_artifact') + + # Command to test + self.cmd = osc_art.CreateArtifact(self.app, None) + self.COLUMNS = ('id', 'name', 'owner', + 'status', 'version', 'visibility') + + def test_create_artifact(self): + arglist = ['sample_artifact', 'art', + '--artifact-version', '0.2.4', + '--property', 'blah=10'] + verify = [('type_name', 'sample_artifact'), + ('property', ['blah=10']), + ('artifact_version', '0.2.4')] + parsed_args = self.check_parser(self.cmd, arglist, verify) + columns, data = self.cmd.take_action(parsed_args) + + # Check that columns are correct + self.assertEqual(self.COLUMNS, columns) + + def test_create_artifact_multiproperty(self): + arglist = ['sample_artifact', 'art', + '--artifact-version', '0.2.4', + '--property', 'blah=1', + '--property', 'blag=2'] + verify = [('type_name', 'sample_artifact'), + ('property', ['blah=1', 'blag=2']), + ('artifact_version', '0.2.4')] + self.check_parser(self.cmd, arglist, verify) + + def test_create_artifact_multiversion(self): + arglist = ['sample_artifact', 'art', + '--artifact-version', '0.2.4', + '--artifact-version', '0.2.5'] + verify = [('type_name', 'sample_artifact'), + ('artifact_version', '0.2.5')] + self.check_parser(self.cmd, arglist, verify) + + +class TestUpdateArtifacts(TestArtifacts): + + def setUp(self): + super(TestUpdateArtifacts, self).setUp() + self.artifact_mock.call.return_value = \ + api_art.Controller(self.http, type_name='sample_artifact') + + # Command to test + self.cmd = osc_art.UpdateArtifact(self.app, None) + self.COLUMNS = ('id', 'name', 'owner', + 'status', 'version', 'visibility') + + def test_artifact_update(self): + arglist = ['sample_artifact', + 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba', + '--property', 'blah=1', + '--property', 'blag=2'] + verify = [('type_name', 'sample_artifact'), + ('property', ['blah=1', 'blag=2'])] + parsed_args = self.check_parser(self.cmd, arglist, verify) + columns, data = self.cmd.take_action(parsed_args) + # Check that columns are correct + self.assertEqual(self.COLUMNS, columns) + + def test_artifact_update_bad(self): + arglist = ['sample_artifact', + 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba', + '--property', 'blah', + '--property', 'blah' + ] + verify = [('type_name', 'sample_artifact')] + parsed_args = self.check_parser(self.cmd, arglist, verify) + with testtools.ExpectedException(ValueError): + self.cmd.take_action(parsed_args) + + def test_artifact_update_multiremove_prop(self): + arglist = ['sample_artifact', + 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba', + '--remove-property', 'prop1=1', + '--remove-property', 'prop2=2'] + verify = [('type_name', 'sample_artifact'), + ('remove_property', ['prop1=1', 'prop2=2'])] + parsed_args = self.check_parser(self.cmd, arglist, verify) + columns, data = self.cmd.take_action(parsed_args) + # Check that columns are correct + self.assertEqual(self.COLUMNS, columns) + + +class TestDeleteArtifacts(TestArtifacts): + + def setUp(self): + super(TestDeleteArtifacts, self).setUp() + self.artifact_mock.call.return_value = \ + api_art.Controller(self.http, type_name='sample_artifact') + + # Command to test + self.cmd = osc_art.DeleteArtifact(self.app, None) + self.COLUMNS = ('id', 'name', 'owner', + 'status', 'version', 'visibility') + + def test_artifact_delete(self): + arglist = ['sample_artifact', + 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba'] + verify = [('type_name', 'sample_artifact'), + ('id', 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba')] + parsed_args = self.check_parser(self.cmd, arglist, verify) + columns, data = self.cmd.take_action(parsed_args) + # Check that columns are correct + self.assertEqual(self.COLUMNS, columns) + + +class TestActivateArtifacts(TestArtifacts): + + def setUp(self): + super(TestActivateArtifacts, self).setUp() + self.artifact_mock.call.return_value = \ + api_art.Controller(self.http, type_name='sample_artifact') + + # Command to test + self.cmd = osc_art.ActivateArtifact(self.app, None) + self.COLUMNS = ('id', 'name', 'owner', + 'status', 'version', 'visibility') + + def test_artifact_activate(self): + arglist = ['sample_artifact', + 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba'] + verify = [('type_name', 'sample_artifact'), + ('id', 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba')] + parsed_args = self.check_parser(self.cmd, arglist, verify) + columns, data = self.cmd.take_action(parsed_args) + # Check that columns are correct + self.assertEqual(self.COLUMNS, columns) + + +class TestDeactivateArtifacts(TestArtifacts): + + def setUp(self): + super(TestDeactivateArtifacts, self).setUp() + self.artifact_mock.call.return_value = \ + api_art.Controller(self.http, type_name='sample_artifact') + + # Command to test + self.cmd = osc_art.DeactivateArtifact(self.app, None) + self.COLUMNS = ('id', 'name', 'owner', + 'status', 'version', 'visibility') + + def test_artifact_deactivate(self): + arglist = ['sample_artifact', + 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba'] + verify = [('type_name', 'sample_artifact'), + ('id', 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba')] + parsed_args = self.check_parser(self.cmd, arglist, verify) + columns, data = self.cmd.take_action(parsed_args) + # Check that columns are correct + self.assertEqual(self.COLUMNS, columns) + + +class TestReactivateArtifacts(TestArtifacts): + + def setUp(self): + super(TestReactivateArtifacts, self).setUp() + self.artifact_mock.call.return_value = \ + api_art.Controller(self.http, type_name='sample_artifact') + + # Command to test + self.cmd = osc_art.ReactivateArtifact(self.app, None) + self.COLUMNS = ('id', 'name', 'owner', + 'status', 'version', 'visibility') + + def test_artifact_rectivate(self): + arglist = ['sample_artifact', + 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba'] + verify = [('type_name', 'sample_artifact'), + ('id', 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba')] + parsed_args = self.check_parser(self.cmd, arglist, verify) + columns, data = self.cmd.take_action(parsed_args) + # Check that columns are correct + self.assertEqual(self.COLUMNS, columns) + + +class TestPublishArtifacts(TestArtifacts): + + def setUp(self): + super(TestPublishArtifacts, self).setUp() + self.artifact_mock.call.return_value = \ + api_art.Controller(self.http, type_name='sample_artifact') + + # Command to test + self.cmd = osc_art.PublishArtifact(self.app, None) + self.COLUMNS = ('id', 'name', 'owner', + 'status', 'version', 'visibility') + + def test_publish_delete(self): + arglist = ['sample_artifact', + 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba'] + verify = [('type_name', 'sample_artifact'), + ('id', 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba')] + parsed_args = self.check_parser(self.cmd, arglist, verify) + columns, data = self.cmd.take_action(parsed_args) + # Check that columns are correct + self.assertEqual(self.COLUMNS, columns) diff --git a/glareclient/tests/unit/osc/v1/test_blob.py b/glareclient/tests/unit/osc/v1/test_blob.py new file mode 100644 index 0000000..473428f --- /dev/null +++ b/glareclient/tests/unit/osc/v1/test_blob.py @@ -0,0 +1,183 @@ +# Copyright (c) 2016 Mirantis, Inc. +# +# 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 mock + +from glareclient.osc.v1 import blobs as osc_blob +from glareclient.tests.unit.osc.v1 import fakes +from glareclient.v1 import artifacts as api_art +import testtools + + +class TestBlobs(fakes.TestArtifacts): + def setUp(self): + super(TestBlobs, self).setUp() + self.blob_mock = \ + self.app.client_manager.artifact.blobs + self.http = mock.MagicMock() + + +class TestUploadBlob(TestBlobs): + def setUp(self): + super(TestUploadBlob, self).setUp() + self.blob_mock.call.return_value = \ + api_art.Controller(self.http, type_name='sample_artifact') + + # Command to test + self.cmd = osc_blob.UploadBlob(self.app, None) + + self.COLUMNS = ('blob_property', 'id', 'name', + 'size', 'status', 'version') + + def test_upload_images(self): + exp_data = ('image', 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba', + 'art1', '1B', 'active', '0.0.0') + arglist = ['images', + 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba', + '--blob', '/path/to/file'] + verify = [('type_name', 'images')] + + parsed_args = self.check_parser(self.cmd, arglist, verify) + columns, data = self.cmd.take_action(parsed_args) + self.assertEqual(self.COLUMNS, columns) + self.assertEqual(exp_data, data) + + def test_upload_tosca_template(self): + exp_data = ('template', 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba', + 'art1', '1B', 'active', '0.0.0') + arglist = ['tosca_templates', + 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba', + '--blob', '/path/to/file'] + verify = [('type_name', 'tosca_templates')] + + parsed_args = self.check_parser(self.cmd, arglist, verify) + columns, data = self.cmd.take_action(parsed_args) + self.assertEqual(self.COLUMNS, columns) + self.assertEqual(exp_data, data) + + def test_upload_heat_template(self): + exp_data = ('template', 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba', + 'art1', '1B', 'active', '0.0.0') + arglist = ['heat_templates', + 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba', + '--blob', '/path/to/file'] + verify = [('type_name', 'heat_templates')] + + parsed_args = self.check_parser(self.cmd, arglist, verify) + columns, data = self.cmd.take_action(parsed_args) + self.assertEqual(self.COLUMNS, columns) + self.assertEqual(exp_data, data) + + def test_upload_environment(self): + exp_data = ('environment', 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba', + 'art1', '1B', 'active', '0.0.0') + arglist = ['heat_environments', + 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba', + '--blob', '/path/to/file'] + verify = [('type_name', 'heat_environments')] + + parsed_args = self.check_parser(self.cmd, arglist, verify) + columns, data = self.cmd.take_action(parsed_args) + self.assertEqual(self.COLUMNS, columns) + self.assertEqual(exp_data, data) + + def test_upload_package(self): + exp_data = ('package', 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba', + 'art1', '1B', 'active', '0.0.0') + arglist = ['murano_packages', + 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba', + '--blob', '/path/to/file'] + verify = [('type_name', 'murano_packages')] + + parsed_args = self.check_parser(self.cmd, arglist, verify) + columns, data = self.cmd.take_action(parsed_args) + self.assertEqual(self.COLUMNS, columns) + self.assertEqual(exp_data, data) + + def test_upload_bad(self): + arglist = ['sample_artifact', + 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba', + '--blob', '/path/to/file'] + verify = [('type_name', 'sample_artifact')] + + parsed_args = self.check_parser(self.cmd, arglist, verify) + with testtools.ExpectedException(SystemExit): + self.cmd.take_action(parsed_args) + + def test_upload_blob_with_blob_prop(self): + exp_data = ('blob', 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba', + 'art1', '1B', 'active', '0.0.0') + arglist = ['sample_artifact', + 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba', + '--blob', '/path/to/file', + '--blob-property', 'blob'] + verify = [('type_name', 'sample_artifact')] + + parsed_args = self.check_parser(self.cmd, arglist, verify) + columns, data = self.cmd.take_action(parsed_args) + self.assertEqual(self.COLUMNS, columns) + self.assertEqual(exp_data, data) + + +class TestDownloadBlob(TestBlobs): + def setUp(self): + super(TestDownloadBlob, self).setUp() + self.blob_mock.call.return_value = \ + api_art.Controller(self.http, type_name='sample_artifact') + + # Command to test + self.cmd = osc_blob.DownloadBlob(self.app, None) + + self.COLUMNS = ('blob_property', 'id', 'name', + 'size', 'status', 'version') + + def test_download_exception(self): + arglist = ['images', + 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba', + '--blob-property', 'blob', + '--file', None] + verify = [('type_name', 'images')] + + parsed_args = self.check_parser(self.cmd, arglist, verify) + with testtools.ExpectedException(SystemExit): + self.cmd.take_action(parsed_args) + + def test_download_blob(self): + arglist = ['images', + 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba', + '--blob-property', 'blob', + '--file', '/path/to/file'] + verify = [('type_name', 'images')] + + parsed_args = self.check_parser(self.cmd, arglist, verify) + self.cmd.take_action(parsed_args) + + def test_download_without_blob_property(self): + arglist = ['images', + 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba', + '--file', '/path/to/file'] + verify = [('type_name', 'images')] + + parsed_args = self.check_parser(self.cmd, arglist, verify) + self.cmd.take_action(parsed_args) + + def test_download_progress(self): + arglist = ['images', + 'fc15c365-d4f9-4b8b-a090-d9e230f1f6ba', + '--file', '/path/to/file', + '--progress', 'True'] + verify = [('type_name', 'images')] + + parsed_args = self.check_parser(self.cmd, arglist, verify) + self.cmd.take_action(parsed_args)