OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # | 2 # |
3 # Copyright 2016 Google Inc. | 3 # Copyright 2016 Google Inc. |
4 # | 4 # |
5 # Use of this source code is governed by a BSD-style license that can be | 5 # Use of this source code is governed by a BSD-style license that can be |
6 # found in the LICENSE file. | 6 # found in the LICENSE file. |
7 | 7 |
8 | 8 |
9 """Tests for asset_utils.""" | 9 """Tests for asset_utils.""" |
10 | 10 |
11 | 11 |
12 import asset_utils | 12 import asset_utils |
13 import os | 13 import os |
14 import shutil | 14 import shutil |
15 import subprocess | 15 import subprocess |
16 import sys | 16 import sys |
17 import tempfile | 17 import tempfile |
18 import unittest | 18 import unittest |
19 import uuid | 19 import uuid |
20 | 20 |
21 | 21 |
22 FILE_DIR = os.path.dirname(os.path.abspath(__file__)) | 22 FILE_DIR = os.path.dirname(os.path.abspath(__file__)) |
23 INFRA_BOTS_DIR = os.path.realpath(os.path.join( | 23 INFRA_BOTS_DIR = os.path.realpath(os.path.join(FILE_DIR, os.pardir)) |
24 FILE_DIR, os.pardir, 'infra', 'bots')) | |
25 sys.path.insert(0, INFRA_BOTS_DIR) | 24 sys.path.insert(0, INFRA_BOTS_DIR) |
26 import test_utils | 25 import test_utils |
27 import utils | 26 import utils |
28 | 27 |
29 | 28 |
| 29 CIPD_DEV_SERVICE_URL = 'https://chrome-infra-packages-dev.appspot.com' |
30 GS_BUCKET = 'skia-infra-testdata' | 30 GS_BUCKET = 'skia-infra-testdata' |
31 | 31 |
32 | 32 |
33 def _fake_prompt(result): | 33 def _fake_prompt(result): |
34 """Make a function that pretends to prompt for input and returns a result.""" | 34 """Make a function that pretends to prompt for input and returns a result.""" |
35 return lambda s: result | 35 return lambda s: result |
36 | 36 |
37 | 37 |
38 def _write_stuff(target_dir): | 38 def _write_stuff(target_dir): |
39 """Write some files and directories into target_dir.""" | 39 """Write some files and directories into target_dir.""" |
40 fw = test_utils.FileWriter(target_dir) | 40 fw = test_utils.FileWriter(target_dir) |
41 fw.mkdir('mydir') | 41 fw.mkdir('mydir') |
42 fw.mkdir('anotherdir', 0666) | 42 fw.mkdir('anotherdir', 0666) |
43 fw.mkdir('dir3', 0600) | 43 fw.mkdir('dir3', 0600) |
44 fw.mkdir('subdir') | 44 fw.mkdir('subdir') |
45 fw.write('a.txt', 0777) | 45 fw.write('a.txt', 0777) |
46 fw.write('b.txt', 0751) | 46 fw.write('b.txt', 0751) |
47 fw.write('c.txt', 0640) | 47 fw.write('c.txt', 0640) |
48 fw.write(os.path.join('subdir', 'd.txt'), 0640) | 48 fw.write(os.path.join('subdir', 'd.txt'), 0640) |
49 | 49 |
50 | 50 |
51 class AssetUtilsTest(unittest.TestCase): | 51 class _LocalStore(object): |
| 52 """Local store used for testing.""" |
| 53 def __init__(self): |
| 54 self.dir = tempfile.mkdtemp() |
| 55 |
| 56 def get_available_versions(self, name): |
| 57 target = os.path.join(self.dir, name) |
| 58 if not os.path.isdir(target): |
| 59 return [] |
| 60 contents = os.listdir(os.path.join(self.dir, name)) |
| 61 return sorted([int(d) for d in contents]) |
| 62 |
| 63 def upload(self, name, version, target_dir): |
| 64 shutil.copytree(target_dir, os.path.join(self.dir, name, str(version))) |
| 65 |
| 66 def download(self, name, version, target_dir): |
| 67 shutil.copytree(os.path.join(self.dir, name, str(version)), target_dir) |
| 68 |
| 69 def delete_contents(self, name): |
| 70 try: |
| 71 shutil.rmtree(self.dir) |
| 72 except OSError: |
| 73 if os.path.exists(self.dir): |
| 74 raise |
| 75 |
| 76 |
| 77 class StoreTest(unittest.TestCase): |
| 78 """Superclass used for testing one of the stores.""" |
| 79 def setUp(self): |
| 80 self.asset_name = str(uuid.uuid4()) |
| 81 |
| 82 def tearDown(self): |
| 83 pass |
| 84 |
| 85 def _test_upload_download(self, store): |
| 86 with utils.tmp_dir(): |
| 87 # Create input files and directories. |
| 88 input_dir = os.path.join(os.getcwd(), 'input') |
| 89 _write_stuff(input_dir) |
| 90 |
| 91 # Upload a version, download it again. |
| 92 store.upload(self.asset_name, 0, input_dir) |
| 93 output_dir = os.path.join(os.getcwd(), 'output') |
| 94 store.download(self.asset_name, 0, output_dir) |
| 95 |
| 96 # Compare. |
| 97 test_utils.compare_trees(self, input_dir, output_dir) |
| 98 |
| 99 def _test_versions(self, store): |
| 100 with utils.tmp_dir(): |
| 101 # Create input files and directories. |
| 102 input_dir = os.path.join(os.getcwd(), 'input') |
| 103 _write_stuff(input_dir) |
| 104 self.assertEqual(store.get_available_versions(self.asset_name), []) |
| 105 store.upload(self.asset_name, 0, input_dir) |
| 106 self.assertEqual(store.get_available_versions(self.asset_name), [0]) |
| 107 store.upload(self.asset_name, 1, input_dir) |
| 108 self.assertEqual(store.get_available_versions(self.asset_name), [0, 1]) |
| 109 store.delete_contents(self.asset_name) |
| 110 self.assertEqual(store.get_available_versions(self.asset_name), []) |
| 111 |
| 112 |
| 113 class LocalStoreTest(StoreTest): |
| 114 """Test the local store.""" |
| 115 def setUp(self): |
| 116 super(LocalStoreTest, self).setUp() |
| 117 self._store = _LocalStore() |
| 118 |
| 119 def tearDown(self): |
| 120 self._store.delete_contents(self.asset_name) |
| 121 super(LocalStoreTest, self).tearDown() |
| 122 |
| 123 def test_upload_download(self): |
| 124 self._test_upload_download(self._store) |
| 125 |
| 126 def test_versions(self): |
| 127 self._test_versions(self._store) |
| 128 |
| 129 |
| 130 class CIPDStoreTest(StoreTest): |
| 131 """Test the CIPD store.""" |
| 132 def setUp(self): |
| 133 super(CIPDStoreTest, self).setUp() |
| 134 self._store = asset_utils.CIPDStore(cipd_url=CIPD_DEV_SERVICE_URL) |
| 135 |
| 136 def tearDown(self): |
| 137 self._store.delete_contents(self.asset_name) |
| 138 super(CIPDStoreTest, self).tearDown() |
| 139 |
| 140 def test_upload_download(self): |
| 141 self._test_upload_download(self._store) |
| 142 |
| 143 def test_versions(self): |
| 144 self._test_versions(self._store) |
| 145 |
| 146 |
| 147 class GSStoreTest(StoreTest): |
| 148 """Test the GS store.""" |
| 149 def setUp(self): |
| 150 super(GSStoreTest, self).setUp() |
| 151 self._store = asset_utils.GSStore(gsutil=None, bucket=GS_BUCKET) |
| 152 |
| 153 def tearDown(self): |
| 154 self._store.delete_contents(self.asset_name) |
| 155 super(GSStoreTest, self).tearDown() |
| 156 |
| 157 def test_upload_download(self): |
| 158 self._test_upload_download(self._store) |
| 159 |
| 160 def test_versions(self): |
| 161 self._test_versions(self._store) |
| 162 |
| 163 |
| 164 class AssetTest(unittest.TestCase): |
| 165 """Test Asset operations using a local store.""" |
52 def setUp(self): | 166 def setUp(self): |
53 self.asset_name = str(uuid.uuid4()) | 167 self.asset_name = str(uuid.uuid4()) |
54 self.old_prompt = asset_utils._prompt | 168 self.old_prompt = asset_utils._prompt |
55 asset_utils._prompt = _fake_prompt('y') | 169 asset_utils._prompt = _fake_prompt('y') |
56 self.a = asset_utils.Asset.add(self.asset_name, gs_bucket=GS_BUCKET) | 170 self._store = _LocalStore() |
| 171 self.a = asset_utils.Asset.add(self.asset_name, self._store) |
57 | 172 |
58 def tearDown(self): | 173 def tearDown(self): |
59 if self.a: | 174 if self.a: |
60 self.a.remove() | 175 self.a.remove(remove_in_store=True) |
61 asset_utils._prompt = self.old_prompt | 176 asset_utils._prompt = self.old_prompt |
62 | 177 |
63 gs_path = 'gs://%s/assets/%s' % (GS_BUCKET, self.asset_name) | 178 gs_path = 'gs://%s/assets/%s' % (GS_BUCKET, self.asset_name) |
64 attempt_delete = True | 179 attempt_delete = True |
65 try: | 180 try: |
66 subprocess.check_call(['gsutil', 'ls', gs_path]) | 181 subprocess.check_call(['gsutil', 'ls', gs_path]) |
67 except subprocess.CalledProcessError: | 182 except subprocess.CalledProcessError: |
68 attempt_delete = False | 183 attempt_delete = False |
69 if attempt_delete: | 184 if attempt_delete: |
70 subprocess.check_call(['gsutil', 'rm', '-rf', gs_path]) | 185 subprocess.check_call(['gsutil', 'rm', '-rf', gs_path]) |
71 | 186 |
72 def test_add_remove(self): | 187 def test_add_remove(self): |
73 # Ensure that we can't create an asset twice. | 188 # Ensure that we can't create an asset twice. |
74 with self.assertRaises(Exception): | 189 with self.assertRaises(Exception): |
75 asset_utils.Asset.add(self.asset_name, gs_bucket=GS_BUCKET) | 190 asset_utils.Asset.add(self.asset_name, self._store) |
76 | 191 |
77 # Ensure that the asset dir exists. | 192 # Ensure that the asset dir exists. |
78 asset_dir = os.path.join(FILE_DIR, self.asset_name) | 193 asset_dir = os.path.join(FILE_DIR, self.asset_name) |
79 self.assertTrue(os.path.isdir(asset_dir)) | 194 self.assertTrue(os.path.isdir(asset_dir)) |
80 | 195 |
81 # Remove the asset, ensure that it's gone. | 196 # Remove the asset, ensure that it's gone. |
82 self.a.remove() | 197 self.a.remove() |
83 self.a = None | 198 self.a = None |
84 self.assertFalse(os.path.exists(asset_dir)) | 199 self.assertFalse(os.path.exists(asset_dir)) |
85 | 200 |
(...skipping 29 matching lines...) Expand all Loading... |
115 | 230 |
116 self.a.upload_new_version(input_dir) | 231 self.a.upload_new_version(input_dir) |
117 | 232 |
118 self.assertEqual(self.a.get_current_version(), 1) | 233 self.assertEqual(self.a.get_current_version(), 1) |
119 self.assertEqual(self.a.get_available_versions(), [0, 1]) | 234 self.assertEqual(self.a.get_available_versions(), [0, 1]) |
120 self.assertEqual(self.a.get_next_version(), 2) | 235 self.assertEqual(self.a.get_next_version(), 2) |
121 | 236 |
122 | 237 |
123 if __name__ == '__main__': | 238 if __name__ == '__main__': |
124 unittest.main() | 239 unittest.main() |
OLD | NEW |