~andrewjbeach/juju-ci-tools/make-local-patcher

« back to all changes in this revision

Viewing changes to tests/test_download_juju.py

  • Committer: John George
  • Date: 2015-01-14 22:03:47 UTC
  • mto: This revision was merged to the branch mainline in revision 798.
  • Revision ID: john.george@canonical.com-20150114220347-e8q5wezs1qg9a00u
Added support for setting the juju path, series and agent_url.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
from argparse import Namespace
2
 
import errno
3
 
import hashlib
4
 
import os
5
 
import socket
6
 
import sys
7
 
from unittest import TestCase
8
 
 
9
 
from mock import patch, call
10
 
 
11
 
from download_juju import (
12
 
    _download,
13
 
    download_files,
14
 
    download_candidate_juju,
15
 
    download_released_juju,
16
 
    get_md5,
17
 
    mkdir_p,
18
 
    parse_args,
19
 
    s3_download_files,
20
 
    select_build
21
 
)
22
 
from tests import parse_error
23
 
from utility import temp_dir
24
 
 
25
 
 
26
 
class SelectBuild(TestCase):
27
 
 
28
 
    def test_select_build(self):
29
 
        builds = [
30
 
            'j/p/r/build-win-client/build-829/c/juju-setup-1.25-alpha1.exe']
31
 
        build = select_build(builds)
32
 
        self.assertEqual(
33
 
            build, 's3://juju-qa-data/j/p/r/build-win-client/build-829')
34
 
 
35
 
    def test_select_builds(self):
36
 
        builds = [
37
 
            'j/p/r/build-win-client/build-829/c/juju-setup-1.25-alpha1.exe',
38
 
            'j/p/r/build-win-client/build-1000/c/juju-setup-1.25-alpha1.exe',
39
 
            'j/p/v/build-win-client/build-2000/c/juju-setup-1.25-alpha1.exe',
40
 
            'j/p/r/build-win-client/build-999/c/juju-setup-1.25-alpha1.exe',
41
 
        ]
42
 
        build = select_build(builds)
43
 
        self.assertEqual(
44
 
            build, 's3://juju-qa-data/j/p/v/build-win-client/build-2000')
45
 
 
46
 
 
47
 
class TestGetMD5(TestCase):
48
 
 
49
 
    def test_get_md5_empty(self):
50
 
        with temp_dir() as d:
51
 
            filename = os.path.join(d, "afile")
52
 
            open(filename, "w").close()
53
 
            expected_md5 = hashlib.md5("").hexdigest()
54
 
            self.assertEqual(expected_md5, get_md5(filename))
55
 
 
56
 
    def test_get_md5_size(self):
57
 
        with temp_dir() as d:
58
 
            filename = os.path.join(d, "afile")
59
 
            contents = "some string longer\nthan the size passed\n"
60
 
            with open(filename, "w") as f:
61
 
                f.write(contents)
62
 
            expected_md5 = hashlib.md5(contents).hexdigest()
63
 
            self.assertEqual(expected_md5, get_md5(filename, size=4))
64
 
 
65
 
 
66
 
class TestMkdir(TestCase):
67
 
 
68
 
    def test_mkdir_p(self):
69
 
        with temp_dir() as d:
70
 
            path = os.path.join(d, 'a/b/c')
71
 
            mkdir_p(path)
72
 
            self.assertTrue(os.path.isdir(path))
73
 
 
74
 
 
75
 
class TestParseArgs(TestCase):
76
 
 
77
 
    def test_parse_args(self):
78
 
        with parse_error(self) as stderr:
79
 
            parse_args([])
80
 
        self.assertRegexpMatches(stderr.getvalue(), 'error: too few arguments')
81
 
        self.assertEqual(
82
 
            parse_args(['/cred/path']),
83
 
            Namespace(credential_path='/cred/path', platform=sys.platform,
84
 
                      released=False, revision=None, verbose=0))
85
 
        self.assertEqual(
86
 
            parse_args(['/cred/path', '-r']),
87
 
            Namespace(credential_path='/cred/path', platform=sys.platform,
88
 
                      released=True, revision=None, verbose=0))
89
 
        self.assertEqual(
90
 
            parse_args(['/cred/path', '-r', '-c', '2999', '3001']),
91
 
            Namespace(credential_path='/cred/path', platform=sys.platform,
92
 
                      released=True, revision=['2999', '3001'], verbose=0))
93
 
 
94
 
 
95
 
class TestDownloadFiles(TestCase):
96
 
 
97
 
    def test_download(self):
98
 
        content = "hello"
99
 
        key = KeyStub("test", "hello")
100
 
        with temp_dir() as d:
101
 
            dst = os.path.join(d, "test.txt")
102
 
            _download(key, dst)
103
 
            self.assertEqual(content, get_file_content(dst))
104
 
 
105
 
    def test_download_retries(self):
106
 
        def se(e):
107
 
            raise socket.error(errno.ECONNRESET, "reset")
108
 
        key = KeyStub("test", "foo")
109
 
        with temp_dir() as d:
110
 
            dst = os.path.join(d, "test.txt")
111
 
            with patch.object(key, 'get_contents_to_filename', autospec=True,
112
 
                              side_effect=se) as gcf:
113
 
                with self.assertRaises(socket.error):
114
 
                    _download(key, dst)
115
 
        self.assertEqual(gcf.call_count, 3)
116
 
 
117
 
    def test_download_files(self):
118
 
        keys = [KeyStub("test.txt", "foo"), KeyStub("test2.txt", "foo2")]
119
 
        with temp_dir() as dst:
120
 
            downloaded_files = download_files(keys, dst)
121
 
            self.assertItemsEqual(os.listdir(dst), ['test.txt', 'test2.txt'])
122
 
            self.assertEqual("foo", get_file_content('test.txt', dst))
123
 
            self.assertEqual("foo2", get_file_content('test2.txt', dst))
124
 
        self.assertItemsEqual(downloaded_files, ['test.txt', 'test2.txt'])
125
 
 
126
 
    def test_download_files__matching_file_already_exists(self):
127
 
        keys = [KeyStub("test.txt", "foo"), KeyStub("test2.txt", "foo2")]
128
 
        with temp_dir() as dst:
129
 
            set_file_content("test.txt", "foo", dst)
130
 
            downloaded_files = download_files(keys, dst)
131
 
            self.assertItemsEqual(os.listdir(dst), ['test.txt', 'test2.txt'])
132
 
            self.assertEqual("foo", get_file_content('test.txt', dst))
133
 
            self.assertEqual("foo2", get_file_content('test2.txt', dst))
134
 
        self.assertItemsEqual(downloaded_files, ['test2.txt'])
135
 
 
136
 
    def test_download_files__md5_mismatch(self):
137
 
        keys = [KeyStub("test.txt", "foo"), KeyStub("test2.txt", "foo2")]
138
 
        with temp_dir() as dst:
139
 
            set_file_content("test.txt", "not foo", dst)
140
 
            downloaded_files = download_files(keys, dst)
141
 
            self.assertItemsEqual(os.listdir(dst), ['test.txt', 'test2.txt'])
142
 
            self.assertEqual("foo", get_file_content('test.txt', dst))
143
 
            self.assertEqual("foo2", get_file_content('test2.txt', dst))
144
 
        self.assertItemsEqual(downloaded_files, ['test.txt', 'test2.txt'])
145
 
 
146
 
    def test_download_files__overwrite(self):
147
 
        keys = [KeyStub("test.txt", "foo"), KeyStub("test2.txt", "foo2")]
148
 
        with temp_dir() as dst:
149
 
            set_file_content("test.txt", "foo", dst)
150
 
            downloaded_files = download_files(keys, dst, overwrite=True)
151
 
            self.assertItemsEqual(os.listdir(dst), ['test.txt', 'test2.txt'])
152
 
            self.assertEqual("foo", get_file_content('test.txt', dst))
153
 
            self.assertEqual("foo2", get_file_content('test2.txt', dst))
154
 
        self.assertItemsEqual(downloaded_files, ['test.txt', 'test2.txt'])
155
 
 
156
 
    def test_download_files__suffix(self):
157
 
        keys = [KeyStub("test.txt", "foo"), KeyStub("test2.tar", "foo2")]
158
 
        with temp_dir() as dst:
159
 
            downloaded_files = download_files(keys, dst, suffix=".tar")
160
 
            self.assertItemsEqual(os.listdir(dst), ['test2.tar'])
161
 
            self.assertEqual("foo2", get_file_content('test2.tar', dst))
162
 
        self.assertItemsEqual(downloaded_files, ['test2.tar'])
163
 
 
164
 
    def test_download_files__dst_dir_none(self):
165
 
        keys = [KeyStub("test.txt", "foo"), KeyStub("test2.txt", "foo2")]
166
 
        with patch('download_juju._download', autospec=True) as dj:
167
 
            download_files(keys)
168
 
        self.assertFalse(dj.called)
169
 
 
170
 
    def test_s3_download_files(self):
171
 
        with temp_dir() as dst:
172
 
            with patch('download_juju.s3_auth_with_rc', autospec=True) as ds:
173
 
                with patch(
174
 
                        'download_juju.download_files', autospec=True) as dd:
175
 
                    s3_download_files('s3://foo/path', '/cred/path', dst)
176
 
            ds.assert_called_once_with('/cred/path')
177
 
            dd.assert_called_once_with(
178
 
                ds.return_value.get_bucket.return_value.list.return_value,
179
 
                dst, False, None)
180
 
 
181
 
    def test_download_released_juju(self):
182
 
        with patch('download_juju.s3_download_files', autospec=True) as dd:
183
 
            download_released_juju(
184
 
                Namespace(platform='win32', credential_path='/tmp'))
185
 
        s3path = 's3://juju-qa-data/client-archive/win/'
186
 
        dst = os.path.join(os.environ['HOME'], 'old-juju', 'win')
187
 
        dd.assert_called_once_with(s3path, credential_path='/tmp', dst_dir=dst)
188
 
 
189
 
    def test_download_candidate_juju(self):
190
 
        with patch('download_juju.s3_download_files', autospec=True) as ds:
191
 
            with patch('download_juju.select_build', autospec=True) as db:
192
 
                download_candidate_juju(
193
 
                    Namespace(platform='darwin', credential_path='/tmp',
194
 
                              revision=['11', '33']))
195
 
        dst = os.path.join(os.environ['HOME'], 'candidate', 'osx')
196
 
        self.assertEqual(ds.call_count, 4)
197
 
        exp = 's3://juju-qa-data/juju-ci/products/version-{}/build-{}-client/'
198
 
        calls = [
199
 
            call(exp.format('11', 'osx'), credential_path='/tmp',
200
 
                 suffix='.tar.gz'),
201
 
            call(db.return_value, credential_path='/tmp', suffix='.tar.gz',
202
 
                 dst_dir=dst),
203
 
            call(exp.format('33', 'osx'), credential_path='/tmp',
204
 
                 suffix='.tar.gz'),
205
 
            call(db.return_value, credential_path='/tmp', suffix='.tar.gz',
206
 
                 dst_dir=dst),
207
 
            ]
208
 
        self.assertEqual(ds.call_args_list, calls)
209
 
        self.assertEqual(db.call_count, 2)
210
 
 
211
 
 
212
 
class KeyStub():
213
 
 
214
 
    def __init__(self, name, content=""):
215
 
        self.name = name
216
 
        self.etag = '"{}"'.format(hashlib.md5(content).hexdigest())
217
 
        self.content = content
218
 
 
219
 
    def get_contents_to_filename(self, filename):
220
 
        with open(filename, "wb") as f:
221
 
            f.write(self.content)
222
 
 
223
 
 
224
 
def set_file_content(filename, content, dst_dir=None):
225
 
    dst_path = os.path.join(dst_dir, filename) if dst_dir else filename
226
 
    with open(dst_path, "wb") as f:
227
 
        f.write(content)
228
 
 
229
 
 
230
 
def get_file_content(filename, dst_dir=None):
231
 
    dst_path = os.path.join(dst_dir, filename) if dst_dir else filename
232
 
    with open(dst_path) as f:
233
 
        return f.read()