1
from contextlib import nested
5
from tempfile import NamedTemporaryFile
6
from textwrap import dedent
8
from fixtures import EnvironmentVariable
10
import assess_resources_charmstore as arc
11
from utility import JujuAssertionError
18
class TestParseArgs(TestCase):
20
def test_common_args(self):
21
args = arc.parse_args(['/usr/bin/charm', 'credentials_file'])
22
self.assertEqual('/usr/bin/charm', args.charm_bin)
23
self.assertEqual('credentials_file', args.credentials_file)
24
self.assertEqual(logging.INFO, args.verbose)
27
fake_stdout = StringIO.StringIO()
28
with parse_error(self) as fake_stderr:
29
with patch('sys.stdout', fake_stdout):
30
arc.parse_args(['--help'])
31
self.assertEqual('', fake_stderr.getvalue())
32
self.assertNotIn('TODO', fake_stdout.getvalue())
35
class TestMain(TestCase):
40
'/tmp/credentials_file',
44
patch.object(arc, 'configure_logging', autospec=True),
45
patch.object(arc, 'assess_charmstore_resources', autospec=True),
46
) as (mock_cl, mock_cs_assess):
47
with EnvironmentVariable('JUJU_REPOSITORY', ''):
49
mock_cl.assert_called_once_with(logging.DEBUG)
50
mock_cs_assess.assert_called_once_with(
51
'/usr/bin/charm', '/tmp/credentials_file')
54
class TestCharmstoreDetails(TestCase):
56
def test_raises_when_no_details_found(self):
57
with NamedTemporaryFile() as tmp_file:
59
ValueError, arc.get_charmstore_details, tmp_file.name)
61
def test_creates_CharstoreDetails_object(self):
62
cred_details = dedent("""\
63
export STORE_CREDENTIALS="username@canonical.com:securepassword"
64
export STORE_ADMIN="admin:messy-Travis"
65
export STORE_URL="https://www.jujugui.org
67
with NamedTemporaryFile() as tmp_file:
68
tmp_file.write(cred_details)
71
results = arc.get_charmstore_details(tmp_file.name)
72
self.assertEqual(results.email, 'username@canonical.com')
73
self.assertEqual(results.username, 'username')
74
self.assertEqual(results.password, 'securepassword')
75
self.assertEqual(results.api_url, 'https://www.jujugui.org')
77
def test_parse_credentials_file(self):
78
cred_details = dedent("""\
79
export STORE_CREDENTIALS="username.something@canonical.com:password"
80
export STORE_ADMIN="admin:messy-Travis"
81
export STORE_URL="https://www.jujugui.org
83
with NamedTemporaryFile() as tmp_file:
84
tmp_file.write(cred_details)
87
results = arc.parse_credentials_file(tmp_file.name)
88
self.assertEqual(results['email'], 'username.something@canonical.com')
89
self.assertEqual(results['username'], 'username-something')
90
self.assertEqual(results['password'], 'password')
91
self.assertEqual(results['api_url'], 'https://www.jujugui.org')
93
def test_creates_CharstoreDetails_from_envvars(self):
94
email = 'username@canonical.com'
96
password = 'securepassword'
97
api_url = 'https://www.jujugui.org'
99
EnvironmentVariable('CS_EMAIL', email),
100
EnvironmentVariable('CS_USERNAME', username),
101
EnvironmentVariable('CS_PASSWORD', password),
102
EnvironmentVariable('CS_API_URL', api_url)
104
with NamedTemporaryFile() as tmp_file:
105
results = arc.get_charmstore_details(tmp_file.name)
106
self.assertEqual(results.email, email)
107
self.assertEqual(results.username, username)
108
self.assertEqual(results.password, password)
109
self.assertEqual(results.api_url, api_url)
111
def test_creates_CharstoreDetails_envvards_overwrite(self):
112
cred_details = dedent("""\
113
export STORE_CREDENTIALS="username.something@canonical.com:password"
114
export STORE_ADMIN="admin:messy-Travis"
115
export STORE_URL="https://www.jujugui.org
117
email = 'username-env@canonical.com'
118
username = 'username-env'
119
password = 'password-env'
120
api_url = 'https://www.jujugui.org-env'
122
EnvironmentVariable('CS_EMAIL', email),
123
EnvironmentVariable('CS_USERNAME', username),
124
EnvironmentVariable('CS_PASSWORD', password),
125
EnvironmentVariable('CS_API_URL', api_url)
127
with NamedTemporaryFile() as tmp_file:
128
tmp_file.write(cred_details)
130
results = arc.get_charmstore_details(tmp_file.name)
131
self.assertEqual(results.email, email)
132
self.assertEqual(results.username, username)
133
self.assertEqual(results.password, password)
134
self.assertEqual(results.api_url, api_url)
137
class TestSplitLineDetails(TestCase):
139
def test_doesnt_raise_when_no_split_token(self):
140
self.assertEqual('', arc.split_line_details(''))
142
def test_returns_string_free_of_quotes(self):
144
self.assertEqual('', arc.split_line_details(base_string))
146
def test_returns_complete_token_from_config_string(self):
147
base_string = 'something something = test_value'
148
self.assertEqual(' test_value', arc.split_line_details(base_string))
150
def test_ensure_removes_newlines(self):
151
base_string = 'test_value\n'
152
self.assertEqual('test_value', arc.split_line_details(base_string))
155
class TestRunId(TestCase):
156
def test_replaces_characters_in_uuid(self):
157
uuid = 'fbc4863a-3372-11e6-8aa3-0c8bfd6c5d2c'
158
expected = 'fbc4863a337211e68aa30c8bfd6c5d2c'
159
with patch.object(arc, 'uuid1', auto_spec=True, return_value=uuid):
160
self.assertEquals(arc.get_run_id(), expected)
163
class TestRaiseIfContentsDiffer(TestCase):
165
def test_raises_exception_on_mismatch(self):
166
file_contents = 'abc'
167
resource_contents = 'ab'
170
arc.raise_if_contents_differ,
174
def test_no_raise_on_contents_match(self):
175
file_contents = resource_contents = 'ab'
176
arc.raise_if_contents_differ(
177
resource_contents=resource_contents,
178
file_contents=file_contents)
180
def test_exception_message(self):
181
file_contents = 'abc'
182
resource_contents = 'ab'
183
expected_msg = dedent("""\
184
Resource contents mismatch.
188
{r}""".format(f=file_contents, r=resource_contents))
189
with self.assertRaisesRegexp(JujuAssertionError, expected_msg):
190
arc.raise_if_contents_differ(
191
resource_contents=resource_contents,
192
file_contents=file_contents)