import hashlib
import json
import logging
+import optparse
import os
import shutil
+import subprocess
import sys
import tempfile
-import unittest
ROOT_DIR = unicode(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
sys.path.insert(0, ROOT_DIR)
sys.path.insert(0, os.path.join(ROOT_DIR, 'third_party'))
from depot_tools import auto_stub
+import auth
import isolate
+import isolate_format
import isolated_format
+import isolateserver
from utils import file_path
from utils import tools
-
+import test_utils
ALGO = hashlib.sha1
class IsolateBase(auto_stub.TestCase):
def setUp(self):
super(IsolateBase, self).setUp()
- self.mock(isolate.auth, 'ensure_logged_in', lambda _: None)
+ self.mock(auth, 'ensure_logged_in', lambda _: None)
self.old_cwd = os.getcwd()
self.cwd = tempfile.mkdtemp(prefix='isolate_')
# Everything should work even from another directory.
def tearDown(self):
try:
os.chdir(self.old_cwd)
- isolate.run_isolated.rmtree(self.cwd)
+ file_path.rmtree(self.cwd)
finally:
super(IsolateBase, self).tearDown()
self.assertEqual(expected, saved_state.flatten())
def test_variable_arg(self):
- parser = isolate.OptionParserIsolate()
- parser.require_isolated = False
+ parser = optparse.OptionParser()
+ isolate.add_isolate_options(parser)
+ options, args = parser.parse_args(
+ ['--config-variable', 'Foo', 'bar',
+ '--path-variable', 'Baz=sub=string',
+ '--extra-variable', 'biz', 'b uz=a'])
+ isolate.process_isolate_options(parser, options, require_isolated=False)
+
expected_path = {
'Baz': 'sub=string',
}
'biz': 'b uz=a',
'EXECUTABLE_SUFFIX': '.exe' if sys.platform == 'win32' else '',
}
-
- options, args = parser.parse_args(
- ['--config-variable', 'Foo', 'bar',
- '--path-variable', 'Baz=sub=string',
- '--extra-variable', 'biz', 'b uz=a'])
self.assertEqual(expected_path, options.path_variables)
self.assertEqual(expected_config, options.config_variables)
self.assertEqual(expected_extra, options.extra_variables)
self.assertEqual([], args)
def test_variable_arg_fail(self):
- parser = isolate.OptionParserIsolate()
+ parser = optparse.OptionParser()
+ isolate.add_isolate_options(parser)
self.mock(sys, 'stderr', cStringIO.StringIO())
with self.assertRaises(SystemExit):
parser.parse_args(['--config-variable', 'Foo'])
- def test_blacklist(self):
+ def test_blacklist_default(self):
ok = [
'.git2',
'.pyc',
'foo.pyc',
'bar.swp',
]
- blacklist = tools.gen_blacklist(isolate.isolateserver.DEFAULT_BLACKLIST)
+ blacklist = tools.gen_blacklist(isolateserver.DEFAULT_BLACKLIST)
for i in ok:
self.assertFalse(blacklist(i), i)
for i in blocked:
self.assertTrue(blacklist(i), i)
- def test_blacklist_chromium(self):
+ def test_blacklist_custom(self):
ok = [
'.run_test_cases',
'testserver.log2',
'testserver.log',
os.path.join('foo', 'testserver.log'),
]
- blacklist = tools.gen_blacklist(isolate.isolateserver.DEFAULT_BLACKLIST)
+ blacklist = tools.gen_blacklist([r'^.+\.run_test_cases$', r'^.+\.log$'])
for i in ok:
self.assertFalse(blacklist(i), i)
for i in blocked:
self.assertTrue(blacklist(i), i)
+ def test_read_only(self):
+ isolate_file = os.path.join(self.cwd, 'fake.isolate')
+ isolate_content = {
+ 'variables': {
+ 'read_only': 0,
+ },
+ }
+ tools.write_json(isolate_file, isolate_content, False)
+ expected = {
+ 'algo': 'sha-1',
+ 'files': {},
+ 'read_only': 0,
+ 'relative_cwd': '.',
+ 'version': isolated_format.ISOLATED_FILE_VERSION,
+ }
+ complete_state = isolate.CompleteState(None, isolate.SavedState(self.cwd))
+ complete_state.load_isolate(
+ unicode(self.cwd), unicode(isolate_file), {}, {}, {}, None, False)
+ self.assertEqual(expected, complete_state.saved_state.to_isolated())
+
class IsolateLoad(IsolateBase):
def setUp(self):
def tearDown(self):
try:
- isolate.run_isolated.rmtree(self.directory)
+ file_path.rmtree(self.directory)
finally:
super(IsolateLoad, self).tearDown()
isolated = os.path.join(self.directory, 'foo.isolated')
outdir = os.path.join(self.directory, 'outdir')
isolate = isolate_file
+ blacklist = list(isolateserver.DEFAULT_BLACKLIST)
path_variables = {}
config_variables = {
'OS': 'linux',
's': _size('isolate.py'),
},
},
+ 'read_only': 1,
'relative_cwd': os.path.join(u'tests', 'isolate'),
'version': isolated_format.ISOLATED_FILE_VERSION,
}
's': _size('tests', 'isolate', 'touch_root.py'),
},
},
+ 'read_only': 1,
'relative_cwd': os.path.join(u'tests', 'isolate'),
'version': isolated_format.ISOLATED_FILE_VERSION,
}
's': _size('tests', 'isolate', 'touch_root.py'),
},
},
+ 'read_only': 1,
'relative_cwd': os.path.join(u'tests', 'isolate'),
'version': isolated_format.ISOLATED_FILE_VERSION,
}
's': _size('tests', 'isolate', 'touch_root.py'),
},
},
+ 'read_only': 1,
'relative_cwd': os.path.join(u'tests', 'isolate'),
'version': isolated_format.ISOLATED_FILE_VERSION,
}
's': _size('tests', 'isolate', 'no_run.isolate'),
},
},
+ 'read_only': 1,
'relative_cwd': os.path.join(u'tests', 'isolate'),
'version': isolated_format.ISOLATED_FILE_VERSION,
}
unicode(hash_file(os.path.join(self.directory, 'foo.0.isolated'))),
unicode(hash_file(os.path.join(self.directory, 'foo.1.isolated'))),
],
+ u'read_only': 1,
u'relative_cwd': u'.',
u'version': unicode(isolated_format.ISOLATED_FILE_VERSION),
}
'command': [
'foo', 'linux',
],
- 'isolate_dependency_tracked': [
+ 'files': [
'file_linux',
],
},
}],
['OS=="mac" or OS=="win"', {
'variables': {
- 'isolate_dependency_tracked': [
+ 'files': [
'file_non_linux',
],
},
'command': [
'foo', 'linux_or_mac',
],
- 'isolate_dependency_tracked': [
+ 'files': [
'other/file',
],
},
'conditions': [
['OS=="amiga"', {
'variables': {
- 'isolate_dependency_tracked': [
+ 'files': [
'file_amiga',
],
},
'command': [
'foo', 'mac',
],
- 'isolate_dependency_tracked': [
+ 'files': [
'file_mac',
],
},
isolated = os.path.join(isolated_dir, u'foo.isolated')
with open(os.path.join(isolate_dir_1, 'isolate1.isolate'), 'wb') as f:
- isolate.isolate_format.pretty_print(isolate1, f)
+ isolate_format.pretty_print(isolate1, f)
with open(os.path.join(isolate_dir_3_2, 'isolate2.isolate'), 'wb') as f:
- isolate.isolate_format.pretty_print(isolate2, f)
+ isolate_format.pretty_print(isolate2, f)
root_isolate = os.path.join(isolate_dir_3, 'isolate3.isolate')
with open(root_isolate, 'wb') as f:
- isolate.isolate_format.pretty_print(isolate3, f)
+ isolate_format.pretty_print(isolate3, f)
# Make all the touched files.
mapping = {1: isolate_dir_1, 2: isolate_dir_3_2, 3: isolate_dir_3}
config = {
'OS': config_os,
}
- c.load_isolate(unicode(self.cwd), root_isolate, {}, config, {}, False)
+ c.load_isolate(
+ unicode(self.cwd), root_isolate, {}, config, {}, None, False)
# Note that load_isolate() doesn't retrieve the meta data about each file.
expected = {
'algo': 'sha-1',
'command': command,
'files': {unicode(f):{} for f in expected_files},
+ 'read_only': 1,
'relative_cwd': relative_cwd,
'version': isolated_format.ISOLATED_FILE_VERSION,
}
'command': [
'foo', 'linux', '<(PATH)', '<(EXTRA)',
],
- 'isolate_dependency_tracked': [
+ 'files': [
'<(PATH)/file_linux',
],
},
}],
['OS=="mac" or OS=="win"', {
'variables': {
- 'isolate_dependency_tracked': [
+ 'files': [
'<(PATH)/file_non_linux',
],
},
'command': [
'foo', 'linux_or_mac', '<(PATH)', '<(EXTRA)',
],
- 'isolate_dependency_tracked': [
+ 'files': [
'<(PATH)/other/file',
],
},
'conditions': [
['OS=="amiga"', {
'variables': {
- 'isolate_dependency_tracked': [
+ 'files': [
'<(PATH)/file_amiga',
],
},
'command': [
'foo', 'mac', '<(PATH)', '<(EXTRA)',
],
- 'isolate_dependency_tracked': [
+ 'files': [
'<(PATH)/file_mac',
],
},
isolated = os.path.join(isolated_dir, u'foo.isolated')
with open(os.path.join(isolate_dir_1, 'isolate1.isolate'), 'wb') as f:
- isolate.isolate_format.pretty_print(isolate1, f)
+ isolate_format.pretty_print(isolate1, f)
with open(os.path.join(isolate_dir_3_2, 'isolate2.isolate'), 'wb') as f:
- isolate.isolate_format.pretty_print(isolate2, f)
+ isolate_format.pretty_print(isolate2, f)
root_isolate = os.path.join(isolate_dir_3, 'isolate3.isolate')
with open(root_isolate, 'wb') as f:
- isolate.isolate_format.pretty_print(isolate3, f)
+ isolate_format.pretty_print(isolate3, f)
# Make all the touched files.
path_dir = os.path.join(cwd, 'path')
'EXTRA': 'indeed',
}
c.load_isolate(
- unicode(cwd), root_isolate, paths, config, extra, False)
+ unicode(cwd), root_isolate, paths, config, extra, None, False)
# Note that load_isolate() doesn't retrieve the meta data about each file.
expected = {
'algo': 'sha-1',
unicode(os.path.join(cwd_name, config_os, 'path', f)): {}
for f in expected_files
},
+ 'read_only': 1,
'relative_cwd': relative_cwd,
'version': isolated_format.ISOLATED_FILE_VERSION,
}
def test_CMDarchive(self):
actual = []
- self.mock(
- isolate.isolateserver, 'upload_tree',
- lambda **kwargs: actual.append(kwargs))
- isolate_file = os.path.join(self.cwd, 'x.isolate')
- isolated_file = os.path.join(self.cwd, 'x.isolated')
+ def mocked_upload_tree(base_url, infiles, namespace):
+ # |infiles| may be a generator of pair, materialize it into a list.
+ actual.append({
+ 'base_url': base_url,
+ 'infiles': dict(infiles),
+ 'namespace': namespace,
+ })
+ self.mock(isolateserver, 'upload_tree', mocked_upload_tree)
+
+ def join(*path):
+ return os.path.join(self.cwd, *path)
+
+ isolate_file = join('x.isolate')
+ isolated_file = join('x.isolated')
with open(isolate_file, 'wb') as f:
f.write(
'# Foo\n'
' \'conditions\':['
' [\'OS=="dendy"\', {'
' \'variables\': {'
- ' \'isolate_dependency_tracked\': [\'foo\'],'
+ ' \'files\': [\'foo\'],'
' },'
' }],'
' ],'
'}')
- with open(os.path.join(self.cwd, 'foo'), 'wb') as f:
+ with open(join('foo'), 'wb') as f:
f.write('fooo')
self.mock(sys, 'stdout', cStringIO.StringIO())
'--isolate-server', 'http://localhost:1',
'--config-variable', 'OS', 'dendy',
]
- self.assertEqual(0, isolate.CMDarchive(isolate.OptionParserIsolate(), cmd))
+ self.assertEqual(0, isolate.CMDarchive(optparse.OptionParser(), cmd))
+ expected = [
+ {
+ 'base_url': 'http://localhost:1',
+ 'infiles': {
+ join(isolated_file): {
+ 'priority': '0',
+ },
+ join('foo'): {
+ 'h': '520d41b29f891bbaccf31d9fcfa72e82ea20fcf0',
+ 's': 4,
+ },
+ },
+ 'namespace': 'default-gzip',
+ },
+ ]
+ # These always change.
+ actual[0]['infiles'][join(isolated_file)].pop('h')
+ actual[0]['infiles'][join(isolated_file)].pop('s')
+ actual[0]['infiles'][join('foo')].pop('m')
+ actual[0]['infiles'][join('foo')].pop('t')
+ self.assertEqual(expected, actual)
+
+ def test_CMDbatcharchive(self):
+ # Same as test_CMDarchive but via code path that parses *.gen.json files.
+ actual = []
+
+ def mocked_upload_tree(base_url, infiles, namespace):
+ # |infiles| may be a generator of pair, materialize it into a list.
+ actual.append({
+ 'base_url': base_url,
+ 'infiles': dict(infiles),
+ 'namespace': namespace,
+ })
+ self.mock(isolateserver, 'upload_tree', mocked_upload_tree)
+
+ def join(*path):
+ return os.path.join(self.cwd, *path)
+
+ # First isolate: x.isolate.
+ isolate_file_x = join('x.isolate')
+ isolated_file_x = join('x.isolated')
+ with open(isolate_file_x, 'wb') as f:
+ f.write(
+ '# Foo\n'
+ '{'
+ ' \'conditions\':['
+ ' [\'OS=="dendy"\', {'
+ ' \'variables\': {'
+ ' \'files\': [\'foo\'],'
+ ' },'
+ ' }],'
+ ' ],'
+ '}')
+ with open(join('foo'), 'wb') as f:
+ f.write('fooo')
+ with open(join('x.isolated.gen.json'), 'wb') as f:
+ json.dump({
+ 'args': [
+ '-i', isolate_file_x,
+ '-s', isolated_file_x,
+ '--config-variable', 'OS', 'dendy',
+ ],
+ 'dir': self.cwd,
+ 'version': 1,
+ }, f)
+
+ # Second isolate: y.isolate.
+ isolate_file_y = join('y.isolate')
+ isolated_file_y = join('y.isolated')
+ with open(isolate_file_y, 'wb') as f:
+ f.write(
+ '# Foo\n'
+ '{'
+ ' \'conditions\':['
+ ' [\'OS=="dendy"\', {'
+ ' \'variables\': {'
+ ' \'files\': [\'bar\'],'
+ ' },'
+ ' }],'
+ ' ],'
+ '}')
+ with open(join('bar'), 'wb') as f:
+ f.write('barr')
+ with open(join('y.isolated.gen.json'), 'wb') as f:
+ json.dump({
+ 'args': [
+ '-i', isolate_file_y,
+ '-s', isolated_file_y,
+ '--config-variable', 'OS', 'dendy',
+ ],
+ 'dir': self.cwd,
+ 'version': 1,
+ }, f)
+
+ self.mock(sys, 'stdout', cStringIO.StringIO())
+ cmd = [
+ '--isolate-server', 'http://localhost:1',
+ '--dump-json', 'json_output.json',
+ join('x.isolated.gen.json'),
+ join('y.isolated.gen.json'),
+ ]
+ self.assertEqual(
+ 0, isolate.CMDbatcharchive(tools.OptionParserWithLogging(), cmd))
expected = [
{
'base_url': 'http://localhost:1',
- 'indir': self.cwd,
'infiles': {
- isolated_file: {
+ join(isolated_file_x): {
'priority': '0',
},
- u'foo': {
+ join('foo'): {
'h': '520d41b29f891bbaccf31d9fcfa72e82ea20fcf0',
's': 4,
},
+ join(isolated_file_y): {
+ 'priority': '0',
+ },
+ join('bar'): {
+ 'h': 'e918b3a3f9597e3cfdc62ce20ecf5756191cb3ec',
+ 's': 4,
+ },
},
'namespace': 'default-gzip',
},
]
# These always change.
- actual[0]['infiles'][isolated_file].pop('h')
- actual[0]['infiles'][isolated_file].pop('s')
- actual[0]['infiles']['foo'].pop('m')
- actual[0]['infiles']['foo'].pop('t')
+ actual[0]['infiles'][join(isolated_file_x)].pop('h')
+ actual[0]['infiles'][join(isolated_file_x)].pop('s')
+ actual[0]['infiles'][join('foo')].pop('m')
+ actual[0]['infiles'][join('foo')].pop('t')
+ actual[0]['infiles'][join(isolated_file_y)].pop('h')
+ actual[0]['infiles'][join(isolated_file_y)].pop('s')
+ actual[0]['infiles'][join('bar')].pop('m')
+ actual[0]['infiles'][join('bar')].pop('t')
self.assertEqual(expected, actual)
+ expected_json = {
+ 'x': isolated_format.hash_file('x.isolated', ALGO),
+ 'y': isolated_format.hash_file('y.isolated', ALGO),
+ }
+ self.assertEqual(expected_json, tools.read_json('json_output.json'))
+
def test_CMDcheck_empty(self):
isolate_file = os.path.join(self.cwd, 'x.isolate')
isolated_file = os.path.join(self.cwd, 'x.isolated')
self.mock(sys, 'stdout', cStringIO.StringIO())
cmd = ['-i', isolate_file, '-s', isolated_file]
- isolate.CMDcheck(isolate.OptionParserIsolate(), cmd)
+ isolate.CMDcheck(optparse.OptionParser(), cmd)
def test_CMDcheck_stale_version(self):
isolate_file = os.path.join(self.cwd, 'x.isolate')
'-s', isolated_file,
'--config-variable', 'OS=dendy',
]
- self.assertEqual(0, isolate.CMDcheck(isolate.OptionParserIsolate(), cmd))
+ self.assertEqual(0, isolate.CMDcheck(optparse.OptionParser(), cmd))
with open(isolate_file, 'rb') as f:
actual = f.read()
actual_isolated = f.read()
expected_isolated = (
'{"algo":"sha-1","command":["foo"],"files":{},'
- '"relative_cwd":".","version":"%s"}'
+ '"read_only":1,"relative_cwd":".","version":"%s"}'
) % isolated_format.ISOLATED_FILE_VERSION
self.assertEqual(expected_isolated, actual_isolated)
isolated_data = json.loads(actual_isolated)
with open(isolated_file + '.state', 'wb') as f:
isolated_state_data['version'] = '100.42'
json.dump(isolated_state_data, f)
- self.assertEqual(0, isolate.CMDcheck(isolate.OptionParserIsolate(), cmd))
+ self.assertEqual(0, isolate.CMDcheck(optparse.OptionParser(), cmd))
# Now edit the .isolated file to break the version number and make
# sure it doesn't crash.
with open(isolated_file, 'wb') as f:
isolated_data['version'] = '100.42'
json.dump(isolated_data, f)
- self.assertEqual(0, isolate.CMDcheck(isolate.OptionParserIsolate(), cmd))
+ self.assertEqual(0, isolate.CMDcheck(optparse.OptionParser(), cmd))
# Make sure the files were regenerated.
with open(isolated_file, 'rb') as f:
' [\'OS=="dendy"\', {'
' \'variables\': {'
' \'command\': [\'foo\'],'
- ' \'isolate_dependency_tracked\': [\'foo\'],'
+ ' \'files\': [\'foo\'],'
' },'
' }],'
' ],'
f.write('yeah')
self.mock(sys, 'stdout', cStringIO.StringIO())
- self.assertEqual(0, isolate.CMDcheck(isolate.OptionParserIsolate(), cmd))
+ self.assertEqual(0, isolate.CMDcheck(optparse.OptionParser(), cmd))
# Now add a new config variable.
with open(isolate_file, 'wb') as f:
' [\'OS=="dendy"\', {'
' \'variables\': {'
' \'command\': [\'foo\'],'
- ' \'isolate_dependency_tracked\': [\'foo\'],'
+ ' \'files\': [\'foo\'],'
' },'
' }],'
' [\'foo=="baz"\', {'
' \'variables\': {'
- ' \'isolate_dependency_tracked\': [\'bar\'],'
+ ' \'files\': [\'bar\'],'
' },'
' }],'
' ],'
self.assertEqual(
0,
isolate.CMDcheck(
- isolate.OptionParserIsolate(),
- cmd + ['--config-variable', 'foo=bar']))
+ optparse.OptionParser(), cmd + ['--config-variable', 'foo=bar']))
def test_CMDcheck_isolate_copied(self):
# Note that moving the .isolate file is a different code path, this is about
cmd = ['-i', x_isolate_file, '-s', isolated_file]
with open(x_isolate_file, 'wb') as f:
f.write('{}')
- self.assertEqual(0, isolate.CMDcheck(isolate.OptionParserIsolate(), cmd))
+ self.assertEqual(0, isolate.CMDcheck(optparse.OptionParser(), cmd))
self.assertTrue(os.path.isfile(isolated_file + '.state'))
with open(isolated_file + '.state', 'rb') as f:
self.assertEqual(json.load(f)['isolate_file'], 'x.isolate')
y_isolate_file = os.path.join(self.cwd, 'Y.isolate')
shutil.copyfile(x_isolate_file, y_isolate_file)
cmd = ['-i', y_isolate_file, '-s', isolated_file]
- self.assertEqual(0, isolate.CMDcheck(isolate.OptionParserIsolate(), cmd))
+ self.assertEqual(0, isolate.CMDcheck(optparse.OptionParser(), cmd))
with open(isolated_file + '.state', 'rb') as f:
self.assertEqual(json.load(f)['isolate_file'], 'Y.isolate')
- def test_CMDrewrite(self):
- isolate_file = os.path.join(self.cwd, 'x.isolate')
- data = (
- '# Foo',
- '{',
- '}',
- )
- with open(isolate_file, 'wb') as f:
- f.write('\n'.join(data))
-
- self.mock(sys, 'stdout', cStringIO.StringIO())
- cmd = ['-i', isolate_file]
- self.assertEqual(0, isolate.CMDrewrite(isolate.OptionParserIsolate(), cmd))
- with open(isolate_file, 'rb') as f:
- actual = f.read()
-
- expected = "# Foo\n{\n 'conditions': [\n ],\n}\n"
- self.assertEqual(expected, actual)
-
def test_CMDrun_extra_args(self):
cmd = [
'run',
'--', 'extra_args',
]
self.mock(isolate, 'load_complete_state', self.load_complete_state)
- self.mock(isolate.subprocess, 'call', lambda *_, **_kwargs: 0)
- self.assertEqual(0, isolate.CMDrun(isolate.OptionParserIsolate(), cmd))
+ self.mock(subprocess, 'call', lambda *_, **_kwargs: 0)
+ self.assertEqual(0, isolate.CMDrun(optparse.OptionParser(), cmd))
def test_CMDrun_no_isolated(self):
isolate_file = os.path.join(self.cwd, 'x.isolate')
self.assertEqual([sys.executable, '-c', "print('hi')", 'run'], cmd)
self.assertTrue(os.path.isdir(cwd))
return 0
- self.mock(isolate.subprocess, 'call', expect_call)
+ self.mock(subprocess, 'call', expect_call)
cmd = ['run', '--isolate', isolate_file]
- self.assertEqual(0, isolate.CMDrun(isolate.OptionParserIsolate(), cmd))
+ self.assertEqual(0, isolate.CMDrun(optparse.OptionParser(), cmd))
def clear_env_vars():
if __name__ == '__main__':
- logging.basicConfig(
- level=logging.DEBUG if '-v' in sys.argv else logging.ERROR,
- format='%(levelname)5s %(filename)15s(%(lineno)3d): %(message)s')
- if '-v' in sys.argv:
- unittest.TestCase.maxDiff = None
clear_env_vars()
- unittest.main()
+ test_utils.main()