Tests for repository machinery
Tests Package and bundle creation, dependency traversal, corresponding shell commands. Change-Id: I93d2984243a6e89efb901a0510c61ae9fb0cf210
This commit is contained in:
parent
2a4454467f
commit
21504e6ad4
|
@ -1,86 +0,0 @@
|
|||
# Copyright (c) 2015 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 StringIO
|
||||
import tempfile
|
||||
|
||||
import mock
|
||||
import requests
|
||||
import testtools
|
||||
|
||||
from muranoclient.common import utils
|
||||
|
||||
|
||||
class UtilsTest(testtools.TestCase):
|
||||
|
||||
def test_file_object_from_file(self):
|
||||
f_obj = tempfile.NamedTemporaryFile(delete=True)
|
||||
new_f_obj = utils.File(f_obj).open()
|
||||
self.assertTrue(hasattr(new_f_obj, 'read'))
|
||||
|
||||
new_f_obj = utils.File(f_obj.name).open()
|
||||
self.assertTrue(hasattr(new_f_obj, 'read'))
|
||||
|
||||
def test_file_object_file_fails(self):
|
||||
f_obj = utils.File('')
|
||||
self.assertRaises(ValueError, f_obj.open)
|
||||
|
||||
def test_file_object_url_fails(self):
|
||||
resp = requests.Response()
|
||||
resp.status_code = 400
|
||||
resp.raw = StringIO.StringIO("123")
|
||||
|
||||
with mock.patch(
|
||||
'requests.get',
|
||||
mock.Mock(side_effect=lambda k, *args, **kwargs: resp)):
|
||||
f = utils.File("http://127.0.0.1")
|
||||
self.assertRaises(ValueError, f.open)
|
||||
|
||||
def test_file_object_url(self):
|
||||
resp = requests.Response()
|
||||
resp.raw = StringIO.StringIO("123")
|
||||
resp.status_code = 200
|
||||
with mock.patch(
|
||||
'requests.get',
|
||||
mock.Mock(side_effect=lambda k, *args, **kwargs: resp)):
|
||||
new_f_obj = utils.File('http://127.0.0.1/').open()
|
||||
self.assertTrue(hasattr(new_f_obj, 'read'))
|
||||
|
||||
def test_file_object_repo_fails(self):
|
||||
|
||||
resp = requests.Response()
|
||||
resp.raw = StringIO.StringIO("123")
|
||||
resp.status_code = 400
|
||||
with mock.patch(
|
||||
'requests.get',
|
||||
mock.Mock(side_effect=lambda k, *args, **kwargs: resp)):
|
||||
self.assertRaises(
|
||||
ValueError, utils.Package.from_file,
|
||||
utils.to_url('foo.bar.baz', base_url='http://127.0.0.1'))
|
||||
|
||||
def test_no_repo_url_fails(self):
|
||||
self.assertRaises(ValueError, utils.to_url,
|
||||
'foo.bar.baz', base_url='')
|
||||
|
||||
def test_file_object_repo(self):
|
||||
resp = requests.Response()
|
||||
resp.raw = StringIO.StringIO("123")
|
||||
resp.status_code = 200
|
||||
with mock.patch(
|
||||
'requests.get',
|
||||
mock.Mock(side_effect=lambda k, *args, **kwargs: resp)):
|
||||
new_f_obj = utils.Package.from_file(utils.to_url(
|
||||
'foo.bar.baz', base_url='http://')).file()
|
||||
self.assertTrue(hasattr(new_f_obj, 'read'))
|
|
@ -12,15 +12,18 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import StringIO
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
import fixtures
|
||||
import mock
|
||||
import requests
|
||||
import requests_mock
|
||||
import six
|
||||
from testtools import matchers
|
||||
|
||||
|
@ -28,8 +31,11 @@ from muranoclient.common import utils
|
|||
from muranoclient.openstack.common.apiclient import exceptions
|
||||
import muranoclient.shell
|
||||
from muranoclient.tests import base
|
||||
from muranoclient.tests import test_utils
|
||||
from muranoclient.v1 import shell as v1_shell
|
||||
|
||||
make_pkg = test_utils.make_pkg
|
||||
|
||||
FIXTURE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__),
|
||||
'fixture_data'))
|
||||
# RESULT_PACKAGE = os.path.join(FIXTURE_DIR, 'test-app.zip')
|
||||
|
@ -47,8 +53,10 @@ FAKE_ENV2 = {'OS_USERNAME': 'username',
|
|||
|
||||
class TestArgs(object):
|
||||
version = ''
|
||||
murano_repo_url = ''
|
||||
murano_repo_url = 'http://127.0.0.1'
|
||||
exists_action = ''
|
||||
is_public = False
|
||||
categories = []
|
||||
|
||||
|
||||
class ShellTest(base.TestCaseShell):
|
||||
|
@ -70,6 +78,17 @@ class ShellTest(base.TestCaseShell):
|
|||
'muranoclient.common.http.HTTPClient.get_proxy_url',
|
||||
mock.MagicMock))
|
||||
|
||||
# To prevent log descriptors from being closed during
|
||||
# shell tests set a custom StreamHandler
|
||||
self.logger = logging.getLogger()
|
||||
self.logger.level = logging.DEBUG
|
||||
self.stream_handler = logging.StreamHandler(sys.stdout)
|
||||
self.logger.addHandler(self.stream_handler)
|
||||
|
||||
def tearDown(self):
|
||||
super(ShellTest, self).tearDown()
|
||||
self.logger.removeHandler(self.stream_handler)
|
||||
|
||||
def shell(self, argstr, exitcodes=(0,)):
|
||||
orig = sys.stdout
|
||||
orig_stderr = sys.stderr
|
||||
|
@ -265,8 +284,6 @@ class ShellTest(base.TestCaseShell):
|
|||
|
||||
|
||||
class ShellPackagesOperations(ShellTest):
|
||||
def tearDown(self):
|
||||
super(ShellPackagesOperations, self).tearDown()
|
||||
|
||||
def test_create_hot_based_package(self):
|
||||
self.useFixture(fixtures.MonkeyPatch(
|
||||
|
@ -299,9 +316,8 @@ class ShellPackagesOperations(ShellTest):
|
|||
"Application package "
|
||||
"is available at {0}".format(RESULT_PACKAGE))
|
||||
|
||||
@mock.patch('muranoclient.common.utils.Package.images')
|
||||
def test_package_import(self, mock_images):
|
||||
mock_images.return_value = []
|
||||
@mock.patch('muranoclient.common.utils.Package.from_file')
|
||||
def test_package_import(self, from_file):
|
||||
args = TestArgs()
|
||||
with tempfile.NamedTemporaryFile() as f:
|
||||
RESULT_PACKAGE = f.name
|
||||
|
@ -309,82 +325,59 @@ class ShellPackagesOperations(ShellTest):
|
|||
args.categories = ['Cat1', 'Cat2 with space']
|
||||
args.is_public = True
|
||||
|
||||
result = {RESULT_PACKAGE: utils.Package.from_file(
|
||||
StringIO.StringIO("123"))}
|
||||
with mock.patch(
|
||||
'muranoclient.common.utils.Package.manifest') as man_mock:
|
||||
man_mock.__getitem__.side_effect = [args.filename]
|
||||
with mock.patch(
|
||||
'muranoclient.common.utils.Package.requirements',
|
||||
mock.Mock(side_effect=lambda *args, **kw: result)):
|
||||
v1_shell.do_package_import(self.client, args)
|
||||
pkg = make_pkg({'FullName': RESULT_PACKAGE})
|
||||
from_file.return_value = utils.Package(utils.File(pkg))
|
||||
|
||||
self.client.packages.create.assert_called_once_with(
|
||||
{'categories': ['Cat1', 'Cat2 with space'], 'is_public': True},
|
||||
{RESULT_PACKAGE: mock.ANY},
|
||||
)
|
||||
v1_shell.do_package_import(self.client, args)
|
||||
|
||||
@mock.patch('muranoclient.common.utils.Package.images')
|
||||
def test_package_import_no_categories(self, mock_images):
|
||||
mock_images.return_value = []
|
||||
self.client.packages.create.assert_called_once_with({
|
||||
'categories': ['Cat1', 'Cat2 with space'],
|
||||
'is_public': True
|
||||
}, {RESULT_PACKAGE: mock.ANY},)
|
||||
|
||||
@mock.patch('muranoclient.common.utils.Package.from_file')
|
||||
def test_package_import_no_categories(self, from_file):
|
||||
args = TestArgs()
|
||||
|
||||
with tempfile.NamedTemporaryFile() as f:
|
||||
RESULT_PACKAGE = f.name
|
||||
pkg = make_pkg({'FullName': RESULT_PACKAGE})
|
||||
from_file.return_value = utils.Package(utils.File(pkg))
|
||||
|
||||
args.filename = RESULT_PACKAGE
|
||||
args.categories = None
|
||||
args.is_public = False
|
||||
|
||||
result = {RESULT_PACKAGE: utils.Package.from_file(
|
||||
StringIO.StringIO("123"))}
|
||||
|
||||
with mock.patch(
|
||||
'muranoclient.common.utils.Package.manifest') as man_mock:
|
||||
man_mock.__getitem__.side_effect = [args.filename]
|
||||
with mock.patch(
|
||||
'muranoclient.common.utils.Package.requirements',
|
||||
mock.Mock(side_effect=lambda *args, **kw: result)):
|
||||
v1_shell.do_package_import(self.client, args)
|
||||
v1_shell.do_package_import(self.client, args)
|
||||
|
||||
self.client.packages.create.assert_called_once_with(
|
||||
{'is_public': False},
|
||||
{RESULT_PACKAGE: mock.ANY},
|
||||
)
|
||||
|
||||
@mock.patch('muranoclient.common.utils.Package.images')
|
||||
def test_package_import_url(self, mock_images):
|
||||
mock_images.return_value = []
|
||||
@requests_mock.mock()
|
||||
@mock.patch('muranoclient.common.utils.Package.from_file')
|
||||
def test_package_import_url(self, rm, from_file):
|
||||
args = TestArgs()
|
||||
|
||||
args.filename = "http://127.0.0.1/test_package.zip"
|
||||
args.categories = None
|
||||
args.is_public = False
|
||||
|
||||
resp = requests.Response()
|
||||
resp.status_code = 200
|
||||
resp.raw = StringIO.StringIO("123")
|
||||
result = {args.filename: utils.Package.from_file(
|
||||
StringIO.StringIO("123"))}
|
||||
with mock.patch(
|
||||
'muranoclient.common.utils.Package.manifest') as man_mock:
|
||||
man_mock.__getitem__.side_effect = [args.filename]
|
||||
with mock.patch(
|
||||
'requests.get',
|
||||
mock.Mock(side_effect=lambda k, *args, **kw: resp)):
|
||||
with mock.patch(
|
||||
'muranoclient.common.utils.Package.requirements',
|
||||
mock.Mock(side_effect=lambda *args, **kw: result)):
|
||||
pkg = make_pkg({'FullName': 'test_package'})
|
||||
from_file.return_value = utils.Package(utils.File(pkg))
|
||||
|
||||
v1_shell.do_package_import(self.client, args)
|
||||
rm.get(args.filename, body=make_pkg({'FullName': 'test_package'}))
|
||||
|
||||
v1_shell.do_package_import(self.client, args)
|
||||
|
||||
self.client.packages.create.assert_called_once_with(
|
||||
{'is_public': False},
|
||||
{args.filename: mock.ANY},
|
||||
{'test_package': mock.ANY},
|
||||
)
|
||||
|
||||
@mock.patch('muranoclient.common.utils.Package.images')
|
||||
def test_package_import_by_name(self, mock_images):
|
||||
mock_images.return_value = []
|
||||
@requests_mock.mock()
|
||||
@mock.patch('muranoclient.common.utils.Package.from_file')
|
||||
def test_package_import_by_name(self, rm, from_file):
|
||||
args = TestArgs()
|
||||
|
||||
args.filename = "io.test.apps.test_application"
|
||||
|
@ -392,25 +385,182 @@ class ShellPackagesOperations(ShellTest):
|
|||
args.is_public = False
|
||||
args.murano_repo_url = "http://127.0.0.1"
|
||||
|
||||
resp = requests.Response()
|
||||
resp.status_code = 200
|
||||
resp.raw = StringIO.StringIO("123")
|
||||
result = {args.filename: utils.Package.from_file(
|
||||
StringIO.StringIO("123"))}
|
||||
with mock.patch(
|
||||
'muranoclient.common.utils.Package.manifest') as man_mock:
|
||||
man_mock.__getitem__.side_effect = [args.filename]
|
||||
with mock.patch(
|
||||
'requests.get',
|
||||
mock.Mock(side_effect=lambda k, *args, **kw: resp)):
|
||||
with mock.patch(
|
||||
'muranoclient.common.utils.Package.requirements',
|
||||
mock.Mock(side_effect=lambda *args, **kw: result)):
|
||||
pkg = make_pkg({'FullName': args.filename})
|
||||
from_file.return_value = utils.Package(utils.File(pkg))
|
||||
|
||||
v1_shell.do_package_import(self.client, args)
|
||||
rm.get(args.murano_repo_url + '/apps/' + args.filename + '.zip',
|
||||
body=make_pkg({'FullName': 'first_app'}))
|
||||
|
||||
v1_shell.do_package_import(self.client, args)
|
||||
|
||||
self.assertTrue(self.client.packages.create.called)
|
||||
self.client.packages.create.assert_called_once_with(
|
||||
{'is_public': False},
|
||||
{args.filename: mock.ANY},
|
||||
)
|
||||
|
||||
@requests_mock.mock()
|
||||
def test_import_bundle_by_name(self, m):
|
||||
"""Asserts bundle import calls packages create once for each pkg."""
|
||||
pkg1 = make_pkg({'FullName': 'first_app'})
|
||||
pkg2 = make_pkg({'FullName': 'second_app'})
|
||||
|
||||
m.get(TestArgs.murano_repo_url + '/apps/first_app.zip', body=pkg1)
|
||||
m.get(TestArgs.murano_repo_url + '/apps/second_app.1.0.zip',
|
||||
body=pkg2)
|
||||
s = StringIO.StringIO()
|
||||
bundle_contents = {'Packages': [
|
||||
{'Name': 'first_app'},
|
||||
{'Name': 'second_app', 'Version': '1.0'}
|
||||
]}
|
||||
json.dump(bundle_contents, s)
|
||||
s.seek(0)
|
||||
|
||||
m.get(TestArgs.murano_repo_url + '/bundles/test_bundle.bundle',
|
||||
body=s)
|
||||
|
||||
args = TestArgs()
|
||||
args.filename = "test_bundle"
|
||||
|
||||
v1_shell.do_bundle_import(self.client, args)
|
||||
|
||||
self.client.packages.create.assert_has_calls(
|
||||
[
|
||||
mock.call({'is_public': False}, {'first_app': mock.ANY}),
|
||||
mock.call({'is_public': False}, {'second_app': mock.ANY}),
|
||||
], any_order=True,
|
||||
)
|
||||
|
||||
@requests_mock.mock()
|
||||
def test_import_bundle_dependencies(self, m):
|
||||
"""Asserts bundle import calls packages create once for each pkg,
|
||||
including dependencies.
|
||||
"""
|
||||
pkg1 = make_pkg(
|
||||
{'FullName': 'first_app', 'Require': {'second_app': '1.0'}, })
|
||||
pkg2 = make_pkg({'FullName': 'second_app'})
|
||||
|
||||
m.get(TestArgs.murano_repo_url + '/apps/first_app.zip', body=pkg1)
|
||||
m.get(TestArgs.murano_repo_url + '/apps/second_app.1.0.zip',
|
||||
body=pkg2)
|
||||
s = StringIO.StringIO()
|
||||
|
||||
# bundle only contains 1st package
|
||||
bundle_contents = {'Packages': [
|
||||
{'Name': 'first_app'},
|
||||
]}
|
||||
json.dump(bundle_contents, s)
|
||||
s.seek(0)
|
||||
|
||||
m.get(TestArgs.murano_repo_url + '/bundles/test_bundle.bundle',
|
||||
body=s)
|
||||
|
||||
args = TestArgs()
|
||||
args.filename = "test_bundle"
|
||||
|
||||
v1_shell.do_bundle_import(self.client, args)
|
||||
|
||||
self.client.packages.create.assert_has_calls(
|
||||
[
|
||||
mock.call({'is_public': False}, {'first_app': mock.ANY}),
|
||||
mock.call({'is_public': False}, {'second_app': mock.ANY}),
|
||||
], any_order=True,
|
||||
)
|
||||
|
||||
@requests_mock.mock()
|
||||
def test_import_bundle_by_url(self, m):
|
||||
"""Asserts bundle import calls packages create once for each pkg."""
|
||||
pkg1 = make_pkg({'FullName': 'first_app'})
|
||||
pkg2 = make_pkg({'FullName': 'second_app'})
|
||||
|
||||
m.get(TestArgs.murano_repo_url + '/apps/first_app.zip', body=pkg1)
|
||||
m.get(TestArgs.murano_repo_url + '/apps/second_app.1.0.zip',
|
||||
body=pkg2)
|
||||
s = StringIO.StringIO()
|
||||
bundle_contents = {'Packages': [
|
||||
{'Name': 'first_app'},
|
||||
{'Name': 'second_app', 'Version': '1.0'}
|
||||
]}
|
||||
json.dump(bundle_contents, s)
|
||||
s.seek(0)
|
||||
|
||||
url = 'http://127.0.0.2/test_bundle.bundle'
|
||||
m.get(url, body=s)
|
||||
|
||||
args = TestArgs()
|
||||
args.filename = url
|
||||
|
||||
v1_shell.do_bundle_import(self.client, args)
|
||||
|
||||
self.client.packages.create.assert_has_calls(
|
||||
[
|
||||
mock.call({'is_public': False}, {'first_app': mock.ANY}),
|
||||
mock.call({'is_public': False}, {'second_app': mock.ANY}),
|
||||
], any_order=True,
|
||||
)
|
||||
|
||||
@requests_mock.mock()
|
||||
def test_import_bundle_wrong_url(self, m):
|
||||
url = 'http://127.0.0.2/test_bundle.bundle'
|
||||
m.get(url, status_code=404)
|
||||
|
||||
args = TestArgs()
|
||||
args.filename = url
|
||||
|
||||
self.assertRaises(ValueError, v1_shell.do_bundle_import,
|
||||
self.client, args)
|
||||
self.assertFalse(self.client.packages.create.called)
|
||||
|
||||
@requests_mock.mock()
|
||||
def test_import_bundle_no_bundle(self, m):
|
||||
url = 'http://127.0.0.1/bundles/test_bundle.bundle'
|
||||
m.get(url, status_code=404)
|
||||
|
||||
args = TestArgs()
|
||||
args.filename = "test_bundle"
|
||||
|
||||
self.assertRaises(ValueError, v1_shell.do_bundle_import,
|
||||
self.client, args)
|
||||
self.assertFalse(self.client.packages.create.called)
|
||||
|
||||
@requests_mock.mock()
|
||||
def test_import_local_bundle(self, m):
|
||||
"""Asserts local bundles are first searched locally."""
|
||||
tmp_dir = tempfile.mkdtemp()
|
||||
bundle_file = os.path.join(tmp_dir, 'bundle.bundle')
|
||||
with open(os.path.join(tmp_dir, 'bundle.bundle'), 'w') as f:
|
||||
|
||||
bundle_contents = {'Packages': [
|
||||
{'Name': 'first_app'},
|
||||
{'Name': 'second_app', 'Version': '1.0'}
|
||||
]}
|
||||
json.dump(bundle_contents, f)
|
||||
|
||||
pkg1 = make_pkg({'FullName': 'first_app',
|
||||
'Require': {'third_app': None}})
|
||||
pkg2 = make_pkg({'FullName': 'second_app'})
|
||||
pkg3 = make_pkg({'FullName': 'third_app'})
|
||||
with open(os.path.join(tmp_dir, 'first_app'), 'w') as f:
|
||||
f.write(pkg1.read())
|
||||
with open(os.path.join(tmp_dir, 'third_app'), 'w') as f:
|
||||
f.write(pkg3.read())
|
||||
|
||||
m.get(TestArgs.murano_repo_url + '/apps/first_app.zip',
|
||||
status_code=404)
|
||||
m.get(TestArgs.murano_repo_url + '/apps/second_app.1.0.zip',
|
||||
body=pkg2)
|
||||
m.get(TestArgs.murano_repo_url + '/apps/third_app.zip',
|
||||
status_code=404)
|
||||
|
||||
args = TestArgs()
|
||||
args.filename = bundle_file
|
||||
v1_shell.do_bundle_import(self.client, args)
|
||||
|
||||
self.client.packages.create.assert_has_calls(
|
||||
[
|
||||
mock.call({'is_public': False}, {'first_app': mock.ANY}),
|
||||
mock.call({'is_public': False}, {'second_app': mock.ANY}),
|
||||
mock.call({'is_public': False}, {'third_app': mock.ANY}),
|
||||
], any_order=True,
|
||||
)
|
||||
shutil.rmtree(tmp_dir)
|
||||
|
|
|
@ -0,0 +1,270 @@
|
|||
# Copyright (c) 2015 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 json
|
||||
import os.path
|
||||
import StringIO
|
||||
import tempfile
|
||||
import zipfile
|
||||
|
||||
import mock
|
||||
import requests
|
||||
import requests_mock
|
||||
import testtools
|
||||
import yaml
|
||||
|
||||
|
||||
from muranoclient.common import utils
|
||||
|
||||
|
||||
class FileTest(testtools.TestCase):
|
||||
|
||||
def test_file_object_from_file(self):
|
||||
f_obj = tempfile.NamedTemporaryFile(delete=True)
|
||||
new_f_obj = utils.File(f_obj).open()
|
||||
self.assertTrue(hasattr(new_f_obj, 'read'))
|
||||
|
||||
new_f_obj = utils.File(f_obj.name).open()
|
||||
self.assertTrue(hasattr(new_f_obj, 'read'))
|
||||
|
||||
def test_file_object_file_fails(self):
|
||||
f_obj = utils.File('')
|
||||
self.assertRaises(ValueError, f_obj.open)
|
||||
|
||||
def test_file_object_url_fails(self):
|
||||
resp = requests.Response()
|
||||
resp.status_code = 400
|
||||
resp.raw = StringIO.StringIO("123")
|
||||
|
||||
with mock.patch(
|
||||
'requests.get',
|
||||
mock.Mock(side_effect=lambda k, *args, **kwargs: resp)):
|
||||
f = utils.File("http://127.0.0.1")
|
||||
self.assertRaises(ValueError, f.open)
|
||||
|
||||
def test_file_object_url(self):
|
||||
resp = requests.Response()
|
||||
resp.raw = StringIO.StringIO("123")
|
||||
resp.status_code = 200
|
||||
with mock.patch(
|
||||
'requests.get',
|
||||
mock.Mock(side_effect=lambda k, *args, **kwargs: resp)):
|
||||
new_f_obj = utils.File('http://127.0.0.1/').open()
|
||||
self.assertTrue(hasattr(new_f_obj, 'read'))
|
||||
|
||||
|
||||
def make_pkg(manifest_override, image_dicts=None):
|
||||
manifest = {
|
||||
'Author': '',
|
||||
'Classes': {'foo': 'foo.yaml'},
|
||||
'Description': '',
|
||||
'Format': 1.0,
|
||||
'FullName': '',
|
||||
'Name': 'Apache HTTP Server',
|
||||
'Type': 'Application'}
|
||||
manifest.update(manifest_override)
|
||||
file_obj = StringIO.StringIO()
|
||||
zfile = zipfile.ZipFile(file_obj, "a")
|
||||
zfile.writestr('manifest.yaml', yaml.dump(manifest))
|
||||
if image_dicts:
|
||||
images_list = []
|
||||
default_image_spec = {
|
||||
'ContainerFormat': 'bare',
|
||||
'DiskFormat': 'qcow2',
|
||||
'Hash': 'd41d8cd98f00b204e9800998ecf8427e',
|
||||
'Name': '',
|
||||
}
|
||||
for image_dict in image_dicts:
|
||||
image_spec = default_image_spec.copy()
|
||||
image_spec.update(image_dict)
|
||||
images_list.append(image_spec)
|
||||
images = {'Images': images_list, }
|
||||
zfile.writestr('images.lst', yaml.dump(images))
|
||||
zfile.close()
|
||||
file_obj.seek(0)
|
||||
return file_obj
|
||||
|
||||
|
||||
class PackageTest(testtools.TestCase):
|
||||
base_url = "http://127.0.0.1"
|
||||
|
||||
@requests_mock.mock()
|
||||
def test_from_location_local_file(self, m):
|
||||
temp = tempfile.NamedTemporaryFile()
|
||||
pkg = make_pkg({'FullName': 'single_app'})
|
||||
|
||||
temp.write(pkg.read())
|
||||
temp.flush()
|
||||
path, name = os.path.split(temp.name)
|
||||
|
||||
# ensure we do not go to base url
|
||||
m.get(self.base_url + '/apps/{0}.zip'.format(name), status_code=404)
|
||||
|
||||
self.assertEqual('single_app', utils.Package.from_location(
|
||||
name=name, base_url=self.base_url,
|
||||
path=path,
|
||||
).manifest['FullName'])
|
||||
|
||||
@requests_mock.mock()
|
||||
def test_from_location_url(self, m):
|
||||
"""Test that url overrides name specification."""
|
||||
|
||||
pkg = make_pkg({'FullName': 'single_app'})
|
||||
m.get('http://127.0.0.2/apps/single_app.zip', body=pkg)
|
||||
m.get(self.base_url + '/apps/single_app.zip', status_code=404)
|
||||
|
||||
self.assertEqual('single_app', utils.Package.from_location(
|
||||
name='single_app', base_url=self.base_url,
|
||||
url="http://127.0.0.2/apps/single_app.zip",
|
||||
).manifest['FullName'])
|
||||
|
||||
@requests_mock.mock()
|
||||
def test_from_location(self, m):
|
||||
"""Test from location url requesting mechanism."""
|
||||
pkg = make_pkg({'FullName': 'single_app'})
|
||||
pkg_ver = make_pkg({'FullName': 'single_app'})
|
||||
m.get(self.base_url + '/apps/single_app.zip', body=pkg)
|
||||
m.get(self.base_url + '/apps/single_app.1.0.zip', body=pkg_ver)
|
||||
m.get(self.base_url + '/apps/single_app.2.0.zip', status_code=404)
|
||||
|
||||
self.assertEqual('single_app', utils.Package.from_location(
|
||||
name='single_app', base_url=self.base_url).manifest['FullName'])
|
||||
|
||||
self.assertEqual('single_app', utils.Package.from_location(
|
||||
name='single_app',
|
||||
version='1.0',
|
||||
base_url=self.base_url).manifest['FullName'])
|
||||
self.assertRaises(
|
||||
ValueError,
|
||||
utils.Package.from_location,
|
||||
name='single_app',
|
||||
version='2.0',
|
||||
base_url=self.base_url)
|
||||
|
||||
def test_no_requirements(self):
|
||||
pkg = make_pkg({'FullName': 'single_app'})
|
||||
app = utils.Package.fromFile(pkg)
|
||||
reqs = app.requirements(base_url=self.base_url)
|
||||
self.assertEqual(reqs, {'single_app': app})
|
||||
|
||||
@requests_mock.mock()
|
||||
def test_requirements(self, m):
|
||||
"""Test that dependencies are parsed correctly."""
|
||||
|
||||
pkg3 = make_pkg({'FullName': 'dep_of_dep'})
|
||||
pkg2 = make_pkg({'FullName': 'dep_app', 'Require': {
|
||||
'dep_of_dep': "1.0"}, })
|
||||
pkg1 = make_pkg({'FullName': 'main_app', 'Require': {
|
||||
'dep_app': None}, })
|
||||
|
||||
m.get(self.base_url + '/apps/main_app.zip', body=pkg1)
|
||||
m.get(self.base_url + '/apps/dep_app.zip', body=pkg2)
|
||||
m.get(self.base_url + '/apps/dep_of_dep.1.0.zip', body=pkg3)
|
||||
app = utils.Package.fromFile(pkg1)
|
||||
reqs = app.requirements(base_url=self.base_url)
|
||||
|
||||
self.assertEqual(
|
||||
reqs,
|
||||
{'main_app': app, 'dep_app': mock.ANY, 'dep_of_dep': mock.ANY})
|
||||
|
||||
@requests_mock.mock()
|
||||
def test_cyclic_requirements(self, m):
|
||||
"""Test that a cyclic dependency would be handled correctly."""
|
||||
pkg3 = make_pkg({'FullName': 'dep_of_dep', 'Require': {
|
||||
'main_app': None, 'dep_app': None}, })
|
||||
pkg2 = make_pkg({'FullName': 'dep_app', 'Require': {
|
||||
'dep_of_dep': None, 'main_app': None}, })
|
||||
pkg1 = make_pkg({'FullName': 'main_app', 'Require': {
|
||||
'dep_app': None, 'dep_of_dep': None}, })
|
||||
|
||||
m.get(self.base_url + '/apps/main_app.zip', body=pkg1)
|
||||
m.get(self.base_url + '/apps/dep_app.zip', body=pkg2)
|
||||
m.get(self.base_url + '/apps/dep_of_dep.zip', body=pkg3)
|
||||
app = utils.Package.fromFile(pkg1)
|
||||
reqs = app.requirements(base_url=self.base_url)
|
||||
|
||||
self.assertEqual(
|
||||
reqs,
|
||||
{'main_app': app, 'dep_app': mock.ANY, 'dep_of_dep': mock.ANY})
|
||||
|
||||
def test_images(self):
|
||||
pkg = make_pkg({})
|
||||
app = utils.Package.fromFile(pkg)
|
||||
self.assertEqual([], app.images())
|
||||
|
||||
pkg = make_pkg(
|
||||
{}, [{'Name': 'test.qcow2'}, {'Name': 'test2.qcow2'}])
|
||||
app = utils.Package.fromFile(pkg)
|
||||
self.assertEqual(
|
||||
set(['test.qcow2', 'test2.qcow2']),
|
||||
set([img['Name'] for img in app.images()]))
|
||||
|
||||
def test_file_object_repo_fails(self):
|
||||
resp = requests.Response()
|
||||
resp.raw = StringIO.StringIO("123")
|
||||
resp.status_code = 400
|
||||
with mock.patch(
|
||||
'requests.get',
|
||||
mock.Mock(side_effect=lambda k, *args, **kwargs: resp)):
|
||||
self.assertRaises(
|
||||
ValueError, utils.Package.from_location,
|
||||
name='foo.bar.baz', base_url='http://127.0.0.1')
|
||||
|
||||
def test_no_repo_url_fails(self):
|
||||
self.assertRaises(ValueError, utils.Package.from_location,
|
||||
name='foo.bar.baz', base_url='')
|
||||
|
||||
def test_file_object_repo(self):
|
||||
resp = requests.Response()
|
||||
resp.raw = StringIO.StringIO("123")
|
||||
resp.status_code = 200
|
||||
with mock.patch(
|
||||
'requests.get',
|
||||
mock.Mock(side_effect=lambda k, *args, **kwargs: resp)):
|
||||
new_f_obj = utils.Package.from_location(
|
||||
name='foo.bar.baz', base_url='http://127.0.0.1').file()
|
||||
self.assertTrue(hasattr(new_f_obj, 'read'))
|
||||
|
||||
|
||||
class BundleTest(testtools.TestCase):
|
||||
base_url = "http://127.0.0.1"
|
||||
|
||||
@requests_mock.mock()
|
||||
def test_packages(self, m):
|
||||
s = StringIO.StringIO()
|
||||
bundle_contents = {'Packages': [
|
||||
{'Name': 'first_app'},
|
||||
{'Name': 'second_app', 'Version': '1.0'}
|
||||
]}
|
||||
json.dump(bundle_contents, s)
|
||||
s.seek(0)
|
||||
bundle = utils.Bundle.from_file(s)
|
||||
self.assertEqual(
|
||||
set([p['Name'] for p in bundle.package_specs()]),
|
||||
set(['first_app', 'second_app']),
|
||||
)
|
||||
|
||||
# setup packages
|
||||
pkg1 = make_pkg({'FullName': 'first_app'})
|
||||
pkg2 = make_pkg({'FullName': 'second_app'})
|
||||
|
||||
m.get(self.base_url + '/apps/first_app.zip', body=pkg1)
|
||||
m.get(self.base_url + '/apps/second_app.1.0.zip', body=pkg2)
|
||||
self.assertEqual(
|
||||
set([p.manifest['FullName']
|
||||
for p in
|
||||
bundle.packages(base_url=self.base_url)]),
|
||||
set(['first_app', 'second_app'])
|
||||
)
|
|
@ -7,6 +7,7 @@ coverage>=3.6
|
|||
discover
|
||||
fixtures>=0.3.14
|
||||
mock>=1.0
|
||||
requests-mock>=0.6.0 # Apache-2.0
|
||||
tempest-lib>=0.4.0
|
||||
testrepository>=0.0.18
|
||||
testscenarios>=0.4
|
||||
|
|
Loading…
Reference in New Issue