hinoka@chromium.org | 7a79054 | 2014-12-10 02:04:39 +0000 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | # Copyright 2014 The Chromium Authors. All rights reserved. |
| 3 | # Use of this source code is governed by a BSD-style license that can be |
| 4 | # found in the LICENSE file. |
| 5 | |
| 6 | """Test gsutil.py.""" |
| 7 | |
| 8 | |
| 9 | import __builtin__ |
hinoka@chromium.org | 7a79054 | 2014-12-10 02:04:39 +0000 | [diff] [blame] | 10 | import base64 |
hinoka@chromium.org | 5e879a4 | 2015-01-24 00:55:46 +0000 | [diff] [blame] | 11 | import hashlib |
hinoka@chromium.org | 7a79054 | 2014-12-10 02:04:39 +0000 | [diff] [blame] | 12 | import json |
| 13 | import os |
hinoka@chromium.org | 5e879a4 | 2015-01-24 00:55:46 +0000 | [diff] [blame] | 14 | import shutil |
| 15 | import subprocess |
| 16 | import sys |
| 17 | import tempfile |
| 18 | import unittest |
primiano@chromium.org | df35176 | 2014-12-18 11:12:34 +0000 | [diff] [blame] | 19 | import urllib2 |
hinoka@chromium.org | 5e879a4 | 2015-01-24 00:55:46 +0000 | [diff] [blame] | 20 | import zipfile |
hinoka@chromium.org | 7a79054 | 2014-12-10 02:04:39 +0000 | [diff] [blame] | 21 | |
| 22 | |
| 23 | # Add depot_tools to path |
| 24 | THIS_DIR = os.path.dirname(os.path.abspath(__file__)) |
| 25 | DEPOT_TOOLS_DIR = os.path.dirname(THIS_DIR) |
| 26 | sys.path.append(DEPOT_TOOLS_DIR) |
| 27 | |
| 28 | import gsutil |
| 29 | |
| 30 | |
| 31 | class TestError(Exception): |
| 32 | pass |
| 33 | |
| 34 | |
| 35 | class Buffer(object): |
| 36 | def __init__(self, data=None): |
| 37 | self.data = data or '' |
| 38 | |
| 39 | def write(self, buf): |
| 40 | self.data += buf |
| 41 | |
| 42 | def read(self, amount=None): |
| 43 | if not amount: |
| 44 | amount = len(self.data) |
| 45 | result = self.data[:amount] |
| 46 | self.data = self.data[amount:] |
| 47 | return result |
| 48 | |
| 49 | |
| 50 | class FakeCall(object): |
| 51 | def __init__(self): |
| 52 | self.expectations = [] |
| 53 | |
| 54 | def add_expectation(self, *args, **kwargs): |
| 55 | returns = kwargs.pop('_returns', None) |
| 56 | self.expectations.append((args, kwargs, returns)) |
| 57 | |
| 58 | def __call__(self, *args, **kwargs): |
| 59 | if not self.expectations: |
| 60 | raise TestError('Got unexpected\n%s\n%s' % (args, kwargs)) |
| 61 | exp_args, exp_kwargs, exp_returns = self.expectations.pop(0) |
| 62 | if args != exp_args or kwargs != exp_kwargs: |
| 63 | message = 'Expected:\n args: %s\n kwargs: %s\n' % (exp_args, exp_kwargs) |
| 64 | message += 'Got:\n args: %s\n kwargs: %s\n' % (args, kwargs) |
| 65 | raise TestError(message) |
hinoka@chromium.org | 7a79054 | 2014-12-10 02:04:39 +0000 | [diff] [blame] | 66 | return exp_returns |
| 67 | |
| 68 | |
| 69 | class GsutilUnitTests(unittest.TestCase): |
| 70 | def setUp(self): |
| 71 | self.fake = FakeCall() |
| 72 | self.tempdir = tempfile.mkdtemp() |
primiano@chromium.org | df35176 | 2014-12-18 11:12:34 +0000 | [diff] [blame] | 73 | self.old_urlopen = getattr(urllib2, 'urlopen') |
hinoka@chromium.org | 5e879a4 | 2015-01-24 00:55:46 +0000 | [diff] [blame] | 74 | self.old_call = getattr(subprocess, 'call') |
primiano@chromium.org | df35176 | 2014-12-18 11:12:34 +0000 | [diff] [blame] | 75 | setattr(urllib2, 'urlopen', self.fake) |
hinoka@chromium.org | 5e879a4 | 2015-01-24 00:55:46 +0000 | [diff] [blame] | 76 | setattr(subprocess, 'call', self.fake) |
hinoka@chromium.org | 7a79054 | 2014-12-10 02:04:39 +0000 | [diff] [blame] | 77 | |
| 78 | def tearDown(self): |
| 79 | self.assertEqual(self.fake.expectations, []) |
| 80 | shutil.rmtree(self.tempdir) |
primiano@chromium.org | df35176 | 2014-12-18 11:12:34 +0000 | [diff] [blame] | 81 | setattr(urllib2, 'urlopen', self.old_urlopen) |
hinoka@chromium.org | 5e879a4 | 2015-01-24 00:55:46 +0000 | [diff] [blame] | 82 | setattr(subprocess, 'call', self.old_call) |
hinoka@chromium.org | 7a79054 | 2014-12-10 02:04:39 +0000 | [diff] [blame] | 83 | |
| 84 | def test_download_gsutil(self): |
| 85 | version = '4.2' |
| 86 | filename = 'gsutil_%s.zip' % version |
| 87 | full_filename = os.path.join(self.tempdir, filename) |
| 88 | fake_file = 'This is gsutil.zip' |
| 89 | fake_file2 = 'This is other gsutil.zip' |
| 90 | url = '%s%s' % (gsutil.GSUTIL_URL, filename) |
| 91 | self.fake.add_expectation(url, _returns=Buffer(fake_file)) |
| 92 | |
| 93 | self.assertEquals( |
| 94 | gsutil.download_gsutil(version, self.tempdir), full_filename) |
| 95 | with open(full_filename, 'r') as f: |
| 96 | self.assertEquals(fake_file, f.read()) |
| 97 | |
| 98 | metadata_url = gsutil.API_URL + filename |
| 99 | md5_calc = hashlib.md5() |
| 100 | md5_calc.update(fake_file) |
| 101 | b64_md5 = base64.b64encode(md5_calc.hexdigest()) |
| 102 | self.fake.add_expectation(metadata_url, _returns=Buffer(json.dumps({ |
| 103 | 'md5Hash': b64_md5 |
| 104 | }))) |
| 105 | self.assertEquals( |
| 106 | gsutil.download_gsutil(version, self.tempdir), full_filename) |
| 107 | with open(full_filename, 'r') as f: |
| 108 | self.assertEquals(fake_file, f.read()) |
| 109 | self.assertEquals(self.fake.expectations, []) |
| 110 | |
| 111 | self.fake.add_expectation(metadata_url, _returns=Buffer(json.dumps({ |
| 112 | 'md5Hash': base64.b64encode('aaaaaaa') # Bad MD5 |
| 113 | }))) |
| 114 | self.fake.add_expectation(url, _returns=Buffer(fake_file2)) |
| 115 | self.assertEquals( |
| 116 | gsutil.download_gsutil(version, self.tempdir), full_filename) |
| 117 | with open(full_filename, 'r') as f: |
| 118 | self.assertEquals(fake_file2, f.read()) |
| 119 | self.assertEquals(self.fake.expectations, []) |
| 120 | |
| 121 | def test_ensure_gsutil_full(self): |
| 122 | version = '4.2' |
| 123 | gsutil_dir = os.path.join(self.tempdir, 'gsutil_%s' % version, 'gsutil') |
| 124 | gsutil_bin = os.path.join(gsutil_dir, 'gsutil') |
Ryan Tseng | 83fd81f | 2017-10-23 11:13:48 -0700 | [diff] [blame] | 125 | gsutil_flag = os.path.join(gsutil_dir, 'install.flag') |
hinoka@chromium.org | 7a79054 | 2014-12-10 02:04:39 +0000 | [diff] [blame] | 126 | os.makedirs(gsutil_dir) |
| 127 | |
hinoka@chromium.org | 7a79054 | 2014-12-10 02:04:39 +0000 | [diff] [blame] | 128 | zip_filename = 'gsutil_%s.zip' % version |
| 129 | url = '%s%s' % (gsutil.GSUTIL_URL, zip_filename) |
| 130 | _, tempzip = tempfile.mkstemp() |
| 131 | fake_gsutil = 'Fake gsutil' |
| 132 | with zipfile.ZipFile(tempzip, 'w') as zf: |
| 133 | zf.writestr('gsutil/gsutil', fake_gsutil) |
| 134 | with open(tempzip, 'rb') as f: |
| 135 | self.fake.add_expectation(url, _returns=Buffer(f.read())) |
hinoka@chromium.org | 7a79054 | 2014-12-10 02:04:39 +0000 | [diff] [blame] | 136 | |
Ryan Tseng | 83fd81f | 2017-10-23 11:13:48 -0700 | [diff] [blame] | 137 | # This should write the gsutil_bin with 'Fake gsutil' |
| 138 | gsutil.ensure_gsutil(version, self.tempdir, False) |
hinoka@chromium.org | 7a79054 | 2014-12-10 02:04:39 +0000 | [diff] [blame] | 139 | self.assertTrue(os.path.exists(gsutil_bin)) |
| 140 | with open(gsutil_bin, 'r') as f: |
| 141 | self.assertEquals(f.read(), fake_gsutil) |
Ryan Tseng | 83fd81f | 2017-10-23 11:13:48 -0700 | [diff] [blame] | 142 | self.assertTrue(os.path.exists(gsutil_flag)) |
hinoka@chromium.org | 7a79054 | 2014-12-10 02:04:39 +0000 | [diff] [blame] | 143 | self.assertEquals(self.fake.expectations, []) |
| 144 | |
| 145 | def test_ensure_gsutil_short(self): |
| 146 | version = '4.2' |
| 147 | gsutil_dir = os.path.join(self.tempdir, 'gsutil_%s' % version, 'gsutil') |
| 148 | gsutil_bin = os.path.join(gsutil_dir, 'gsutil') |
Ryan Tseng | 83fd81f | 2017-10-23 11:13:48 -0700 | [diff] [blame] | 149 | gsutil_flag = os.path.join(gsutil_dir, 'install.flag') |
hinoka@chromium.org | 7a79054 | 2014-12-10 02:04:39 +0000 | [diff] [blame] | 150 | os.makedirs(gsutil_dir) |
| 151 | |
hinoka@chromium.org | 7a79054 | 2014-12-10 02:04:39 +0000 | [diff] [blame] | 152 | with open(gsutil_bin, 'w') as f: |
| 153 | f.write('Foobar') |
Ryan Tseng | 83fd81f | 2017-10-23 11:13:48 -0700 | [diff] [blame] | 154 | with open(gsutil_flag, 'w') as f: |
| 155 | f.write('Barbaz') |
hinoka@chromium.org | 7a79054 | 2014-12-10 02:04:39 +0000 | [diff] [blame] | 156 | self.assertEquals( |
dnj@chromium.org | 605d81d | 2015-09-18 22:33:53 +0000 | [diff] [blame] | 157 | gsutil.ensure_gsutil(version, self.tempdir, False), gsutil_bin) |
hinoka@chromium.org | 7a79054 | 2014-12-10 02:04:39 +0000 | [diff] [blame] | 158 | |
| 159 | if __name__ == '__main__': |
| 160 | unittest.main() |