blob: d0fb8b029164ee3d6ed174d535c23339c8d7c537 [file] [log] [blame]
hinoka@chromium.org7a790542014-12-10 02:04:39 +00001#!/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
9import __builtin__
hinoka@chromium.org7a790542014-12-10 02:04:39 +000010import base64
hinoka@chromium.org5e879a42015-01-24 00:55:46 +000011import hashlib
hinoka@chromium.org7a790542014-12-10 02:04:39 +000012import json
13import os
hinoka@chromium.org5e879a42015-01-24 00:55:46 +000014import shutil
15import subprocess
16import sys
17import tempfile
18import unittest
primiano@chromium.orgdf351762014-12-18 11:12:34 +000019import urllib2
hinoka@chromium.org5e879a42015-01-24 00:55:46 +000020import zipfile
hinoka@chromium.org7a790542014-12-10 02:04:39 +000021
22
23# Add depot_tools to path
24THIS_DIR = os.path.dirname(os.path.abspath(__file__))
25DEPOT_TOOLS_DIR = os.path.dirname(THIS_DIR)
26sys.path.append(DEPOT_TOOLS_DIR)
27
28import gsutil
29
30
31class TestError(Exception):
32 pass
33
34
35class 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
50class 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.org7a790542014-12-10 02:04:39 +000066 return exp_returns
67
68
69class GsutilUnitTests(unittest.TestCase):
70 def setUp(self):
71 self.fake = FakeCall()
72 self.tempdir = tempfile.mkdtemp()
primiano@chromium.orgdf351762014-12-18 11:12:34 +000073 self.old_urlopen = getattr(urllib2, 'urlopen')
hinoka@chromium.org5e879a42015-01-24 00:55:46 +000074 self.old_call = getattr(subprocess, 'call')
primiano@chromium.orgdf351762014-12-18 11:12:34 +000075 setattr(urllib2, 'urlopen', self.fake)
hinoka@chromium.org5e879a42015-01-24 00:55:46 +000076 setattr(subprocess, 'call', self.fake)
hinoka@chromium.org7a790542014-12-10 02:04:39 +000077
78 def tearDown(self):
79 self.assertEqual(self.fake.expectations, [])
80 shutil.rmtree(self.tempdir)
primiano@chromium.orgdf351762014-12-18 11:12:34 +000081 setattr(urllib2, 'urlopen', self.old_urlopen)
hinoka@chromium.org5e879a42015-01-24 00:55:46 +000082 setattr(subprocess, 'call', self.old_call)
hinoka@chromium.org7a790542014-12-10 02:04:39 +000083
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 Tseng83fd81f2017-10-23 11:13:48 -0700125 gsutil_flag = os.path.join(gsutil_dir, 'install.flag')
hinoka@chromium.org7a790542014-12-10 02:04:39 +0000126 os.makedirs(gsutil_dir)
127
hinoka@chromium.org7a790542014-12-10 02:04:39 +0000128 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.org7a790542014-12-10 02:04:39 +0000136
Ryan Tseng83fd81f2017-10-23 11:13:48 -0700137 # This should write the gsutil_bin with 'Fake gsutil'
138 gsutil.ensure_gsutil(version, self.tempdir, False)
hinoka@chromium.org7a790542014-12-10 02:04:39 +0000139 self.assertTrue(os.path.exists(gsutil_bin))
140 with open(gsutil_bin, 'r') as f:
141 self.assertEquals(f.read(), fake_gsutil)
Ryan Tseng83fd81f2017-10-23 11:13:48 -0700142 self.assertTrue(os.path.exists(gsutil_flag))
hinoka@chromium.org7a790542014-12-10 02:04:39 +0000143 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 Tseng83fd81f2017-10-23 11:13:48 -0700149 gsutil_flag = os.path.join(gsutil_dir, 'install.flag')
hinoka@chromium.org7a790542014-12-10 02:04:39 +0000150 os.makedirs(gsutil_dir)
151
hinoka@chromium.org7a790542014-12-10 02:04:39 +0000152 with open(gsutil_bin, 'w') as f:
153 f.write('Foobar')
Ryan Tseng83fd81f2017-10-23 11:13:48 -0700154 with open(gsutil_flag, 'w') as f:
155 f.write('Barbaz')
hinoka@chromium.org7a790542014-12-10 02:04:39 +0000156 self.assertEquals(
dnj@chromium.org605d81d2015-09-18 22:33:53 +0000157 gsutil.ensure_gsutil(version, self.tempdir, False), gsutil_bin)
hinoka@chromium.org7a790542014-12-10 02:04:39 +0000158
159if __name__ == '__main__':
160 unittest.main()