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