Chromium Code Reviews| Index: tools/isolate/run_test_from_archive.py |
| diff --git a/tools/isolate/run_test_from_archive.py b/tools/isolate/run_test_from_archive.py |
| index d8b2bed74fb6859da0ef3f4f7b7860de424ac2fa..e568899929437d72efe520175db308ea379b713a 100755 |
| --- a/tools/isolate/run_test_from_archive.py |
| +++ b/tools/isolate/run_test_from_archive.py |
| @@ -26,6 +26,13 @@ import urllib |
| # Types of action accepted by recreate_tree(). |
| HARDLINK, SYMLINK, COPY = range(1, 4) |
| +RE_IS_SHA1 = re.compile(r'^[a-fA-F0-9]{40}$') |
| + |
| + |
| +class ConfigError(ValueError): |
| + """Generic failure to load a manifest.""" |
| + pass |
| + |
| class MappingError(OSError): |
| """Failed to recreate the tree.""" |
| @@ -172,6 +179,62 @@ def make_temp_dir(prefix, root_dir): |
| return tempfile.mkdtemp(prefix=prefix, dir=base_temp_dir) |
| +def load_manifest(content): |
| + """Verifies the manifest is valid and loads this object with the json data. |
| + """ |
| + data = json.loads(content) |
| + if not isinstance(data, dict): |
| + raise ConfigError('Expected dict, got %r' % data) |
| + |
| + for key, value in data.iteritems(): |
| + if key == 'command': |
| + if not isinstance(value, list): |
| + raise ConfigError('Expected list, got %r' % value) |
| + for subvalue in value: |
| + if not isinstance(subvalue, basestring): |
| + raise ConfigError('Expected string, got %r' % subvalue) |
| + |
| + elif key == 'files': |
| + if not isinstance(value, dict): |
| + raise ConfigError('Expected dict, got %r' % value) |
| + for subkey, subvalue in value.iteritems(): |
| + if not isinstance(subkey, basestring): |
| + raise ConfigError('Expected string, got %r' % subkey) |
| + if not isinstance(subvalue, dict): |
| + raise ConfigError('Expected dict, got %r' % subvalue) |
| + for subsubkey, subsubvalue in subvalue.iteritems(): |
|
M-A Ruel
2012/08/28 20:51:02
The main issue is that it's much easier to make a
|
| + if subsubkey == 'link': |
| + if not isinstance(subsubvalue, basestring): |
| + raise ConfigError('Expected string, got %r' % subsubvalue) |
| + elif subsubkey == 'mode': |
| + if not isinstance(subsubvalue, int): |
| + raise ConfigError('Expected int, got %r' % subsubvalue) |
| + elif subsubkey == 'sha-1': |
| + if not RE_IS_SHA1.match(subsubvalue): |
| + raise ConfigError('Expected sha-1, got %r' % subsubvalue) |
| + elif subsubkey == 'timestamp': |
| + if not isinstance(subsubvalue, int): |
| + raise ConfigError('Expected int, got %r' % subsubvalue) |
| + else: |
| + raise ConfigError('Unknown key %s' % subsubkey) |
| + if bool('sha-1' in subvalue) and bool('link' in subvalue): |
| + raise ConfigError( |
| + 'Did not expect both \'sha-1\' and \'link\', got: %r' % subvalue) |
| + |
| + elif key == 'read_only': |
| + if not isinstance(value, bool): |
| + raise ConfigError('Expected bool, got %r' % value) |
| + |
| + elif key == 'relative_cwd': |
| + if not isinstance(value, basestring): |
| + raise ConfigError('Expected string, got %r' % value) |
| + |
| + else: |
| + raise ConfigError('Unknown key %s' % subkey) |
| + |
| + return data |
| + |
| + |
| def fix_python_path(cmd): |
| """Returns the fixed command line to call the right python executable.""" |
| out = cmd[:] |
| @@ -394,7 +457,7 @@ def run_tha_test(manifest, cache_dir, remote, policies): |
| # A symlink. |
| os.symlink(properties['link'], outfile) |
| else: |
| - raise ValueError('Unexpected entry: %s' % properties) |
| + raise ConfigError('Unexpected entry: %s' % properties) |
| if 'mode' in properties: |
| # It's not set on Windows. |
| os.chmod(outfile, properties['mode']) |
| @@ -483,7 +546,7 @@ def main(): |
| # First calculate the reference to it. |
| options.manifest = '%s/%s' % (options.remote.rstrip('/'), options.hash) |
| try: |
| - manifest = json.load(open_remote(options.manifest)) |
| + manifest = load_manifest(open_remote(options.manifest).read()) |
| except IOError as e: |
| parser.error( |
| 'Failed to read manifest %s; remote:%s; hash:%s; %s' % |
| @@ -497,7 +560,7 @@ def main(): |
| os.path.abspath(options.cache), |
| options.remote, |
| policies) |
| - except MappingError, e: |
| + except (ConfigError, MappingError), e: |
| print >> sys.stderr, str(e) |
| return 1 |