~abentley/juju-ci-tools/client-from-config-4

« back to all changes in this revision

Viewing changes to tests/test_s3ci.py

  • Committer: Aaron Bentley
  • Date: 2015-11-17 14:13:35 UTC
  • mfrom: (1151.2.6 s3-get)
  • Revision ID: aaron.bentley@canonical.com-20151117141335-8thtwtluaum2xn1d
Add a get command to s3ci.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
from argparse import Namespace
2
2
from ConfigParser import NoOptionError
 
3
from contextlib import contextmanager
3
4
import errno
4
5
import os
5
6
from StringIO import StringIO
18
19
    patch,
19
20
    )
20
21
 
21
 
from jujuci import PackageNamer
 
22
from jujuci import (
 
23
    JobNamer,
 
24
    PackageNamer,
 
25
    )
22
26
from jujuconfig import get_juju_home
23
27
from s3ci import (
 
28
    fetch_files,
24
29
    fetch_juju_binary,
 
30
    find_file_keys,
25
31
    find_package_key,
26
32
    get_job_path,
27
33
    get_s3_credentials,
63
69
        args = parse_args(['get-juju-bin', '3275', '-vv'])
64
70
        self.assertEqual(2, args.verbose)
65
71
 
 
72
    def test_get_defaults(self):
 
73
        default_config = os.path.join(get_juju_home(), 'juju-qa.s3cfg')
 
74
        args = parse_args(['get', '3275', 'job-foo', 'files-bar'])
 
75
        self.assertEqual(Namespace(
 
76
            command='get', config=default_config, revision_build=3275,
 
77
            job='job-foo', file_pattern='files-bar', workspace='.', verbose=0),
 
78
            args)
 
79
 
 
80
    def test_get_workspace(self):
 
81
        args = parse_args(['get', '3275', 'job-foo', 'files-bar',
 
82
                           'myworkspace'])
 
83
        self.assertEqual('myworkspace', args.workspace)
 
84
 
 
85
    def test_get_too_few(self):
 
86
        with parse_error(self) as stderr:
 
87
            parse_args(['get', '3275', 'job-foo'])
 
88
        self.assertRegexpMatches(stderr.getvalue(), 'too few arguments$')
 
89
 
 
90
    def test_get_verbosity(self):
 
91
        args = parse_args(['get', '3275', 'job-foo', 'files-bar', '-v'])
 
92
        self.assertEqual(1, args.verbose)
 
93
        args = parse_args(['get', '3275', 'job-foo', 'files-bar', '-vv'])
 
94
        self.assertEqual(2, args.verbose)
 
95
 
66
96
 
67
97
class TestGetS3Credentials(TestCase):
68
98
 
108
138
        self.assertEqual(exc.exception.errno, errno.ENOENT)
109
139
 
110
140
 
 
141
def mock_key(revision_build, job, build, file_path):
 
142
    key = create_autospec(S3Key, instance=True)
 
143
    key.name = '{}/build-{}/{}'.format(
 
144
        get_job_path(revision_build, job), build, file_path)
 
145
    return key
 
146
 
 
147
 
111
148
def mock_package_key(revision_build, build=27, distro_release=None):
112
 
    key = create_autospec(S3Key, instance=True)
113
149
    namer = PackageNamer.factory()
114
150
    if distro_release is not None:
115
151
        namer.distro_release = distro_release
116
152
    package = namer.get_release_package('109.6')
117
 
    key.name = '{}/build-{}/{}'.format(
118
 
        get_job_path(revision_build), build, package)
119
 
    return key
 
153
    job = JobNamer.factory().get_build_binary_job()
 
154
    return mock_key(revision_build, job, build, package)
120
155
 
121
156
 
122
157
def mock_bucket(keys):
123
158
    bucket = create_autospec(Bucket, instance=True)
124
 
    bucket.list.return_value = keys
 
159
 
 
160
    def list_bucket(prefix):
 
161
        return [key for key in keys if key.name.startswith(prefix)]
 
162
 
 
163
    bucket.list.side_effect = list_bucket
125
164
    return bucket
126
165
 
127
166
 
140
179
    def test_find_package_key(self):
141
180
        key = mock_package_key(390)
142
181
        bucket = mock_bucket([key])
 
182
        namer = JobNamer.factory()
 
183
        job = namer.get_build_binary_job()
143
184
        found_key, filename = find_package_key(bucket, 390)
144
 
        bucket.list.assert_called_once_with(get_job_path(390))
 
185
        bucket.list.assert_called_once_with(get_job_path(390, job))
145
186
        self.assertIs(key, found_key)
146
187
        self.assertEqual(filename, get_key_filename(key))
147
188
 
148
189
    def test_selects_latest(self):
149
190
        new_key = mock_package_key(390, build=27)
150
191
        old_key = mock_package_key(390, build=9)
151
 
        bucket = mock_bucket([old_key, new_key, old_key])
 
192
        bucket = FakeBucket([old_key, new_key, old_key])
152
193
        found_key = find_package_key(bucket, 390)[0]
153
194
        self.assertIs(new_key, found_key)
154
195
 
155
196
    def test_wrong_version(self):
156
197
        key = mock_package_key(390, distro_release='01.01')
157
 
        bucket = mock_bucket([key])
 
198
        bucket = FakeBucket([key])
158
199
        with self.assertRaises(PackageNotFound):
159
200
            find_package_key(bucket, 390)
160
201
 
161
202
    def test_wrong_file(self):
162
203
        key = mock_package_key(390)
163
204
        key.name = key.name.replace('juju-core', 'juju-dore')
164
 
        bucket = mock_bucket([key])
 
205
        bucket = FakeBucket([key])
165
206
        with self.assertRaises(PackageNotFound):
166
207
            find_package_key(bucket, 390)
167
208
 
177
218
    def test_fetch_juju_binary(self):
178
219
        key = mock_package_key(275)
179
220
        filename = get_key_filename(key)
180
 
        bucket = mock_bucket([key])
 
221
        bucket = FakeBucket([key])
181
222
 
182
223
        def extract(package, out_dir):
183
224
            os.mkdir(out_dir)
194
235
        self.assertEqual(os.path.join(eb_dir, 'juju'), extracted)
195
236
 
196
237
 
 
238
class TestFetchFiles(StrictTestCase):
 
239
 
 
240
    def setUp(self):
 
241
        use_context(self, patch('utility.get_deb_arch', return_value='amd65',
 
242
                                autospec=True))
 
243
 
 
244
    def test_fetch_files(self):
 
245
        key = mock_key(275, 'job-foo', 27, 'file-pattern')
 
246
        bucket = FakeBucket([key])
 
247
        with temp_dir() as workspace:
 
248
            downloaded = fetch_files(bucket, 275, 'job-foo', 'file-pat+ern',
 
249
                                     workspace)
 
250
        local_file = os.path.join(workspace, 'file-pattern')
 
251
        key.get_contents_to_filename.assert_called_once_with(local_file)
 
252
        key_copy = os.path.join(workspace, local_file)
 
253
        self.assertEqual([key_copy], downloaded)
 
254
 
 
255
 
 
256
class FakeKey:
 
257
 
 
258
    def __init__(self, revision_build, job, build, file_path):
 
259
        job_path = get_job_path(revision_build, job)
 
260
        self.name = '{}/build-{}/{}'.format(job_path, build, file_path)
 
261
 
 
262
 
 
263
class FakeBucket:
 
264
 
 
265
    def __init__(self, keys):
 
266
        self.keys = keys
 
267
 
 
268
    def list(self, prefix):
 
269
        return [key for key in self.keys if key.name.startswith(prefix)]
 
270
 
 
271
 
 
272
class TestFindFileKeys(StrictTestCase):
 
273
 
 
274
    def test_find_file_keys(self):
 
275
        key = FakeKey(275, 'job-foo', 27, 'file-pattern')
 
276
        bucket = FakeBucket([key])
 
277
        filtered = find_file_keys(bucket, 275, 'job-foo', 'file-pat+ern')
 
278
        self.assertEqual([key], filtered)
 
279
 
 
280
    def test_matches_pattern(self):
 
281
        match_key = FakeKey(275, 'job-foo', 27, 'file-pattern')
 
282
        wrong_name = FakeKey(275, 'job-foo', 27, 'file-pat+ern')
 
283
        wrong_job = FakeKey(275, 'job.foo', 27, 'file-pattern')
 
284
        wrong_rb = FakeKey(276, 'job-foo', 27, 'file-pattern')
 
285
        keys = [match_key, wrong_name, wrong_job, wrong_rb]
 
286
        bucket = FakeBucket(keys)
 
287
        filtered = find_file_keys(
 
288
            bucket, 275, 'job-foo', 'file-pat+ern')
 
289
        self.assertEqual([match_key], filtered)
 
290
 
 
291
    def test_uses_latest_build(self):
 
292
        bucket = FakeBucket([FakeKey(275, 'job-foo', 1, 'file-pattern')])
 
293
        filtered = find_file_keys(bucket, 275, 'job-foo', 'file-pat+ern')
 
294
        self.assertEqual([bucket.keys[0]], filtered)
 
295
 
 
296
        bucket.keys.append(FakeKey(275, 'job-foo', 2, 'non-match'))
 
297
        filtered = find_file_keys(bucket, 275, 'job-foo', 'file-pat+ern')
 
298
        self.assertEqual([], filtered)
 
299
 
 
300
        bucket.keys.append(FakeKey(275, 'job-foo', 2, 'file-pattern'))
 
301
        filtered = find_file_keys(bucket, 275, 'job-foo', 'file-pat+ern')
 
302
        self.assertEqual([bucket.keys[2]], filtered)
 
303
 
 
304
    def test_pattern_is_path(self):
 
305
        match_key = FakeKey(275, 'job-foo', 27, 'dir/file')
 
306
        bucket = FakeBucket([match_key])
 
307
        filtered = find_file_keys(bucket, 275, 'job-foo', 'dir/file')
 
308
        self.assertEqual([match_key], filtered)
 
309
 
 
310
 
197
311
class TestMain(StrictTestCase):
198
312
 
 
313
    @contextmanager
 
314
    def temp_credentials(self):
 
315
        with NamedTemporaryFile() as temp_file:
 
316
            temp_file.write(dedent("""\
 
317
                [default]
 
318
                access_key = fake_username
 
319
                secret_key = fake_pass
 
320
                """))
 
321
            temp_file.flush()
 
322
            yield temp_file.name
 
323
 
199
324
    def setUp(self):
200
325
        use_context(self, stdout_guard())
201
326
 
202
 
    def test_main_args(self):
 
327
    def test_main_args_get_juju_bin(self):
203
328
        stdout = StringIO()
204
 
        with NamedTemporaryFile() as temp_file:
205
 
            temp_file.write(dedent("""\
206
 
                [default]
207
 
                access_key = fake_username
208
 
                secret_key = fake_pass
209
 
                """))
210
 
            temp_file.flush()
 
329
        with self.temp_credentials() as config_file:
211
330
            with patch('sys.argv', [
212
331
                    'foo', 'get-juju-bin', '28', 'bar-workspace',
213
 
                    '--config', temp_file.name]):
 
332
                    '--config', config_file]):
214
333
                with patch('s3ci.S3Connection', autospec=True) as s3c_mock:
215
334
                    with patch('s3ci.fetch_juju_binary', autospec=True,
216
335
                               return_value='gjb') as gbj_mock:
222
341
        gbj_mock.assert_called_once_with(gb_mock.return_value, 28,
223
342
                                         'bar-workspace')
224
343
        self.assertEqual('gjb\n', stdout.getvalue())
 
344
 
 
345
    def test_main_args_get(self):
 
346
        stdout = StringIO()
 
347
        with self.temp_credentials() as config_file:
 
348
            with patch('sys.argv', [
 
349
                    'foo', 'get', '28', 'foo-job', 'bar-file', 'bar-workspace',
 
350
                    '--config', config_file]):
 
351
                with patch('s3ci.S3Connection', autospec=True) as s3c_mock:
 
352
                    with patch('s3ci.fetch_files', autospec=True,
 
353
                               return_value=['ff', 'gg']) as ff_mock:
 
354
                        with patch('sys.stdout', stdout):
 
355
                            main()
 
356
        s3c_mock.assert_called_once_with('fake_username', 'fake_pass')
 
357
        gb_mock = s3c_mock.return_value.get_bucket
 
358
        gb_mock.assert_called_once_with('juju-qa-data')
 
359
        ff_mock.assert_called_once_with(gb_mock.return_value, 28,
 
360
                                        'foo-job', 'bar-file', 'bar-workspace')
 
361
        self.assertEqual('ff\ngg\n', stdout.getvalue())