def _expected_saved_state(
     self, args, read_only, empty_file, extra_vars, root_dir):
   expected = {
     u'OS': unicode(sys.platform),
     u'algo': u'sha-1',
     u'child_isolated_files': [],
     u'command': [],
     u'config_variables': {
       u'OS': u'mac',
       u'chromeos': 0,
     },
     u'extra_variables': {
       u'EXECUTABLE_SUFFIX': u'.exe' if sys.platform == 'win32' else u'',
     },
     u'files': self._gen_files(read_only, empty_file, True),
     u'isolate_file': file_path.safe_relpath(
         file_path.get_native_path_case(unicode(self.filename())),
         unicode(os.path.dirname(self.isolated))),
     u'path_variables': {},
     u'relative_cwd': unicode(RELATIVE_CWD[self.case()]),
     u'root_dir': unicode(root_dir or os.path.dirname(self.filename())),
     u'version': unicode(isolate.SavedState.EXPECTED_VERSION),
   }
   if args:
     expected[u'command'] = [u'python'] + [unicode(x) for x in args]
   expected['extra_variables'].update(extra_vars or {})
   with open(self.saved_state(), 'r') as f:
     self.assertEqual(expected, json.load(f))
Esempio n. 2
0
 def _expected_saved_state(self, args, read_only, empty_file, extra_vars,
                           root_dir):
     expected = {
         u'OS':
         unicode(sys.platform),
         u'algo':
         u'sha-1',
         u'child_isolated_files': [],
         u'command': [],
         u'config_variables': {
             u'OS': u'mac',
             u'chromeos': 0,
         },
         u'extra_variables': {
             u'EXECUTABLE_SUFFIX':
             u'.exe' if sys.platform == 'win32' else u'',
         },
         u'files':
         self._gen_files(read_only, empty_file, True),
         u'isolate_file':
         file_path.safe_relpath(
             file_path.get_native_path_case(unicode(self.filename())),
             unicode(os.path.dirname(self.isolated))),
         u'path_variables': {},
         u'relative_cwd':
         unicode(RELATIVE_CWD[self.case()]),
         u'root_dir':
         unicode(root_dir or os.path.dirname(self.filename())),
         u'version':
         unicode(isolate.SavedState.EXPECTED_VERSION),
     }
 def _expected_saved_state(self, args, read_only, empty_file, root_dir):
     expected = {
         u'OS':
         six.text_type(sys.platform),
         u'algo':
         u'sha-1',
         u'child_isolated_files': [],
         u'command': [],
         u'config_variables': {
             u'OS': u'mac',
             u'chromeos': 0,
         },
         u'files':
         self._gen_files(read_only, empty_file),
         u'isolate_file':
         file_path.safe_relpath(
             file_path.get_native_path_case(six.ensure_text(
                 self.filename())),
             six.text_type(os.path.dirname(self.isolated))),
         u'path_variables': {},
         u'relative_cwd':
         six.text_type(RELATIVE_CWD[self.case()]),
         u'root_dir':
         six.text_type(root_dir or os.path.dirname(self.filename())),
         u'version':
         six.text_type(isolate.SavedState.EXPECTED_VERSION),
     }
 def _expected_saved_state(self, args, read_only, empty_file, extra_vars):
   flavor = isolate.get_flavor()
   chromeos_value = int(flavor == 'linux')
   expected = {
     u'algo': u'sha-1',
     u'child_isolated_files': [],
     u'command': [],
     u'config_variables': {
       u'OS': unicode(flavor),
       u'chromeos': chromeos_value,
     },
     u'extra_variables': {
       u'EXECUTABLE_SUFFIX': u'.exe' if flavor == 'win' else u'',
     },
     u'files': self._gen_files(read_only, empty_file, True),
     u'isolate_file': file_path.safe_relpath(
         file_path.get_native_path_case(unicode(self.filename())),
         unicode(os.path.dirname(self.isolated))),
     u'relative_cwd': unicode(RELATIVE_CWD[self.case()]),
     u'path_variables': {},
     u'version': unicode(isolate.isolateserver.ISOLATED_FILE_VERSION),
   }
   if args:
     expected[u'command'] = [u'python'] + [unicode(x) for x in args]
   expected['extra_variables'].update(extra_vars or {})
   self.assertEqual(expected, json.load(open(self.saved_state(), 'r')))
Esempio n. 5
0
  def test_subdir(self):
    # The resulting .isolated file will be missing ../../isolate.py. It is
    # because this file is outside the --subdir parameter.
    isolate_file = os.path.join(
        ROOT_DIR, 'tests', 'isolate', 'touch_root.isolate')
    options = self._get_option(isolate_file)
    chromeos_value = int(isolate.get_flavor() == 'linux')
    options.config_variables['chromeos'] = chromeos_value
    complete_state = isolate.load_complete_state(
        options, self.cwd, os.path.join('tests', 'isolate'), False)
    actual_isolated = complete_state.saved_state.to_isolated()
    actual_saved_state = complete_state.saved_state.flatten()

    expected_isolated =  {
      'algo': 'sha-1',
      'command': ['python', 'touch_root.py'],
      'files': {
        os.path.join(u'tests', 'isolate', 'touch_root.py'): {
          'm': 488,
          'h': hash_file('tests', 'isolate', 'touch_root.py'),
          's': _size('tests', 'isolate', 'touch_root.py'),
        },
      },
      'os': isolate.get_flavor(),
      'relative_cwd': os.path.join(u'tests', 'isolate'),
      'version': isolate.isolateserver.ISOLATED_FILE_VERSION,
    }
    self._cleanup_isolated(expected_isolated)
    self.assertEqual(expected_isolated, actual_isolated)

    expected_saved_state = {
      'algo': 'sha-1',
      'child_isolated_files': [],
      'command': ['python', 'touch_root.py'],
      'config_variables': {
        'OS': isolate.get_flavor(),
        'chromeos': chromeos_value,
      },
      'extra_variables': {
        'foo': 'bar',
      },
      'files': {
        os.path.join(u'tests', 'isolate', 'touch_root.py'): {
          'm': 488,
          'h': hash_file('tests', 'isolate', 'touch_root.py'),
          's': _size('tests', 'isolate', 'touch_root.py'),
        },
      },
      'isolate_file': file_path.safe_relpath(
          file_path.get_native_path_case(isolate_file),
          os.path.dirname(options.isolated)),
      'relative_cwd': os.path.join(u'tests', 'isolate'),
      'path_variables': {},
      'version': isolate.isolateserver.ISOLATED_FILE_VERSION,
    }
    self._cleanup_isolated(expected_saved_state)
    self._cleanup_saved_state(actual_saved_state)
    self.assertEqual(expected_saved_state, actual_saved_state)
Esempio n. 6
0
  def test_subdir(self):
    # The resulting .isolated file will be missing ../../isolate.py. It is
    # because this file is outside the --subdir parameter.
    isolate_file = os.path.join(
        ROOT_DIR, 'tests', 'isolate', 'touch_root.isolate')
    options = self._get_option(isolate_file)
    complete_state = isolate.load_complete_state(
        options, self.cwd, os.path.join('tests', 'isolate'), False)
    actual_isolated = complete_state.saved_state.to_isolated()
    actual_saved_state = complete_state.saved_state.flatten()

    expected_isolated =  {
      'algo': 'sha-1',
      'command': ['python', 'touch_root.py'],
      'files': {
        os.path.join(u'tests', 'isolate', 'touch_root.py'): {
          'm': 488,
          'h': hash_file('tests', 'isolate', 'touch_root.py'),
          's': _size('tests', 'isolate', 'touch_root.py'),
        },
      },
      'relative_cwd': os.path.join(u'tests', 'isolate'),
      'version': isolate.isolateserver.ISOLATED_FILE_VERSION,
    }
    self._cleanup_isolated(expected_isolated)
    self.assertEqual(expected_isolated, actual_isolated)

    expected_saved_state = {
      'OS': sys.platform,
      'algo': 'sha-1',
      'child_isolated_files': [],
      'command': ['python', 'touch_root.py'],
      'config_variables': {
        'OS': 'linux',
        'chromeos': 1,
      },
      'extra_variables': {
        'foo': 'bar',
      },
      'files': {
        os.path.join(u'tests', 'isolate', 'touch_root.py'): {
          'm': 488,
          'h': hash_file('tests', 'isolate', 'touch_root.py'),
          's': _size('tests', 'isolate', 'touch_root.py'),
        },
      },
      'isolate_file': file_path.safe_relpath(
          file_path.get_native_path_case(isolate_file),
          os.path.dirname(options.isolated)),
      'path_variables': {},
      'relative_cwd': os.path.join(u'tests', 'isolate'),
      'root_dir': file_path.get_native_path_case(ROOT_DIR),
      'version': isolate.SavedState.EXPECTED_VERSION,
    }
    self._cleanup_isolated(expected_saved_state)
    self._cleanup_saved_state(actual_saved_state)
    self.assertEqual(expected_saved_state, actual_saved_state)
Esempio n. 7
0
 def _check_merge(self, filename):
   filepath = file_path.get_native_path_case(
           os.path.join(unicode(ROOT_DIR), 'tests', 'isolate', filename))
   expected = 'Updating %s\n' % file_path.safe_relpath(filepath, self.tempdir)
   with open(filepath, 'rb') as f:
     old_content = f.read()
   out = self._execute('merge', filename, [], True) or ''
   self.assertEqual(expected, out)
   with open(filepath, 'rb') as f:
     new_content = f.read()
   self.assertEqual(old_content, new_content)
Esempio n. 8
0
 def _check_merge(self, filename):
     filepath = file_path.get_native_path_case(
         os.path.join(unicode(ROOT_DIR), 'tests', 'isolate', filename))
     expected = 'Updating %s\n' % file_path.safe_relpath(
         filepath, self.tempdir)
     with open(filepath, 'rb') as f:
         old_content = f.read()
     out = self._execute('merge', filename, [], True) or ''
     self.assertEqual(expected, out)
     with open(filepath, 'rb') as f:
         new_content = f.read()
     self.assertEqual(old_content, new_content)
Esempio n. 9
0
  def update(self, isolate_file, path_variables):
    """Updates the saved state with new data to keep GYP variables and internal
    reference to the original .isolate file.
    """
    assert os.path.isabs(isolate_file)
    # Convert back to a relative path. On Windows, if the isolate and
    # isolated files are on different drives, isolate_file will stay an absolute
    # path.
    isolate_file = file_path.safe_relpath(isolate_file, self.isolated_basedir)

    # The same .isolate file should always be used to generate the .isolated and
    # .isolated.state.
    assert isolate_file == self.isolate_file or not self.isolate_file, (
        isolate_file, self.isolate_file)
    self.isolate_file = isolate_file
    self.path_variables.update(path_variables)
Esempio n. 10
0
    def update(self, isolate_file, path_variables, extra_variables):
        """Updates the saved state with new data to keep GYP variables and internal
    reference to the original .isolate file.
    """
        assert os.path.isabs(isolate_file)
        # Convert back to a relative path. On Windows, if the isolate and
        # isolated files are on different drives, isolate_file will stay an absolute
        # path.
        isolate_file = file_path.safe_relpath(isolate_file, self.isolated_basedir)

        # The same .isolate file should always be used to generate the .isolated and
        # .isolated.state.
        assert isolate_file == self.isolate_file or not self.isolate_file, (isolate_file, self.isolate_file)
        self.extra_variables.update(extra_variables)
        self.isolate_file = isolate_file
        self.path_variables.update(path_variables)
  def test_load_stale_isolated(self):
    isolate_file = os.path.join(
        ROOT_DIR, 'tests', 'isolate', 'touch_root.isolate')

    # Data to be loaded in the .isolated file. Do not create a .state file.
    input_data = {
      'command': ['python'],
      'files': {
        'foo': {
          "m": 416,
          "h": "invalid",
          "s": 538,
          "t": 1335146921,
        },
        os.path.join('tests', 'isolate', 'touch_root.py'): {
          "m": 488,
          "h": "invalid",
          "s": 538,
          "t": 1335146921,
        },
      },
    }
    options = self._get_option(isolate_file)
    tools.write_json(options.isolated, input_data, False)

    # A CompleteState object contains two parts:
    # - Result instance stored in complete_state.isolated, corresponding to the
    #   .isolated file, is what is read by run_test_from_archive.py.
    # - SavedState instance stored in compelte_state.saved_state,
    #   corresponding to the .state file, which is simply to aid the developer
    #   when re-running the same command multiple times and contain
    #   discardable information.
    complete_state = isolate.load_complete_state(options, self.cwd, None, False)
    actual_isolated = complete_state.saved_state.to_isolated()
    actual_saved_state = complete_state.saved_state.flatten()

    expected_isolated = {
      'algo': 'sha-1',
      'command': ['python', 'touch_root.py'],
      'files': {
        os.path.join(u'tests', 'isolate', 'touch_root.py'): {
          'm': 488,
          'h': hash_file('tests', 'isolate', 'touch_root.py'),
          's': _size('tests', 'isolate', 'touch_root.py'),
        },
        u'isolate.py': {
          'm': 488,
          'h': hash_file('isolate.py'),
          's': _size('isolate.py'),
        },
      },
      'relative_cwd': os.path.join(u'tests', 'isolate'),
      'version': isolate.isolateserver.ISOLATED_FILE_VERSION,
    }
    self._cleanup_isolated(expected_isolated)
    self.assertEqual(expected_isolated, actual_isolated)

    expected_saved_state = {
      'OS': sys.platform,
      'algo': 'sha-1',
      'child_isolated_files': [],
      'command': ['python', 'touch_root.py'],
      'config_variables': {
        'OS': 'linux',
        'chromeos': options.config_variables['chromeos'],
      },
      'extra_variables': {
        'foo': 'bar',
      },
      'files': {
        os.path.join(u'tests', 'isolate', 'touch_root.py'): {
          'm': 488,
          'h': hash_file('tests', 'isolate', 'touch_root.py'),
          's': _size('tests', 'isolate', 'touch_root.py'),
        },
        u'isolate.py': {
          'm': 488,
          'h': hash_file('isolate.py'),
          's': _size('isolate.py'),
        },
      },
      'isolate_file': file_path.safe_relpath(
          file_path.get_native_path_case(isolate_file),
          os.path.dirname(options.isolated)),
      'path_variables': {},
      'relative_cwd': os.path.join(u'tests', 'isolate'),
      'root_dir': file_path.get_native_path_case(ROOT_DIR),
      'version': isolate.SavedState.EXPECTED_VERSION,
    }
    self._cleanup_isolated(expected_saved_state)
    self._cleanup_saved_state(actual_saved_state)
    self.assertEqual(expected_saved_state, actual_saved_state)
Esempio n. 12
0
def load_complete_state(options, cwd, subdir, skip_update):
    """Loads a CompleteState.

  This includes data from .isolate and .isolated.state files. Never reads the
  .isolated file.

  Arguments:
    options: Options instance generated with process_isolate_options. For either
             options.isolate and options.isolated, if the value is set, it is an
             absolute path.
    cwd: base directory to be used when loading the .isolate file.
    subdir: optional argument to only process file in the subdirectory, relative
            to CompleteState.root_dir.
    skip_update: Skip trying to load the .isolate file and processing the
                 dependencies. It is useful when not needed, like when tracing.
  """
    assert not options.isolate or os.path.isabs(options.isolate)
    assert not options.isolated or os.path.isabs(options.isolated)
    cwd = file_path.get_native_path_case(unicode(cwd))
    if options.isolated:
        # Load the previous state if it was present. Namely, "foo.isolated.state".
        # Note: this call doesn't load the .isolate file.
        complete_state = CompleteState.load_files(options.isolated)
    else:
        # Constructs a dummy object that cannot be saved. Useful for temporary
        # commands like 'run'. There is no directory containing a .isolated file so
        # specify the current working directory as a valid directory.
        complete_state = CompleteState(None, SavedState(os.getcwd()))

    if not options.isolate:
        if not complete_state.saved_state.isolate_file:
            if not skip_update:
                raise ExecutionError("A .isolate file is required.")
            isolate = None
        else:
            isolate = complete_state.saved_state.isolate_filepath
    else:
        isolate = options.isolate
        if complete_state.saved_state.isolate_file:
            rel_isolate = file_path.safe_relpath(options.isolate, complete_state.saved_state.isolated_basedir)
            if rel_isolate != complete_state.saved_state.isolate_file:
                # This happens if the .isolate file was moved for example. In this case,
                # discard the saved state.
                logging.warning(
                    "--isolated %s != %s as saved in %s. Discarding saved state",
                    rel_isolate,
                    complete_state.saved_state.isolate_file,
                    isolatedfile_to_state(options.isolated),
                )
                complete_state = CompleteState(
                    options.isolated, SavedState(complete_state.saved_state.isolated_basedir)
                )

    if not skip_update:
        # Then load the .isolate and expands directories.
        complete_state.load_isolate(
            cwd,
            isolate,
            options.path_variables,
            options.config_variables,
            options.extra_variables,
            options.blacklist,
            options.ignore_broken_items,
        )

    # Regenerate complete_state.saved_state.files.
    if subdir:
        subdir = unicode(subdir)
        # This is tricky here. If it is a path, take it from the root_dir. If
        # it is a variable, it must be keyed from the directory containing the
        # .isolate file. So translate all variables first.
        translated_path_variables = dict(
            (k, os.path.normpath(os.path.join(complete_state.saved_state.relative_cwd, v)))
            for k, v in complete_state.saved_state.path_variables.iteritems()
        )
        subdir = isolate_format.eval_variables(subdir, translated_path_variables)
        subdir = subdir.replace("/", os.path.sep)

    if not skip_update:
        complete_state.files_to_metadata(subdir)
    return complete_state
Esempio n. 13
0
def load_complete_state(options, cwd, subdir, skip_update):
    """Loads a CompleteState.

  This includes data from .isolate and .isolated.state files. Never reads the
  .isolated file.

  Arguments:
    options: Options instance generated with process_isolate_options. For either
             options.isolate and options.isolated, if the value is set, it is an
             absolute path.
    cwd: base directory to be used when loading the .isolate file.
    subdir: optional argument to only process file in the subdirectory, relative
            to CompleteState.root_dir.
    skip_update: Skip trying to load the .isolate file and processing the
                 dependencies. It is useful when not needed, like when tracing.
  """
    assert not options.isolate or os.path.isabs(options.isolate)
    assert not options.isolated or os.path.isabs(options.isolated)
    cwd = file_path.get_native_path_case(unicode(cwd))
    if options.isolated:
        # Load the previous state if it was present. Namely, "foo.isolated.state".
        # Note: this call doesn't load the .isolate file.
        complete_state = CompleteState.load_files(options.isolated)
    else:
        # Constructs a dummy object that cannot be saved. Useful for temporary
        # commands like 'run'. There is no directory containing a .isolated file so
        # specify the current working directory as a valid directory.
        complete_state = CompleteState(None, SavedState(os.getcwd()))

    if not options.isolate:
        if not complete_state.saved_state.isolate_file:
            if not skip_update:
                raise ExecutionError('A .isolate file is required.')
            isolate = None
        else:
            isolate = complete_state.saved_state.isolate_filepath
    else:
        isolate = options.isolate
        if complete_state.saved_state.isolate_file:
            rel_isolate = file_path.safe_relpath(
                options.isolate, complete_state.saved_state.isolated_basedir)
            if rel_isolate != complete_state.saved_state.isolate_file:
                # This happens if the .isolate file was moved for example. In this case,
                # discard the saved state.
                logging.warning(
                    '--isolated %s != %s as saved in %s. Discarding saved state',
                    rel_isolate, complete_state.saved_state.isolate_file,
                    isolatedfile_to_state(options.isolated))
                complete_state = CompleteState(
                    options.isolated,
                    SavedState(complete_state.saved_state.isolated_basedir))

    if not skip_update:
        # Then load the .isolate and expands directories.
        complete_state.load_isolate(cwd, isolate, options.path_variables,
                                    options.config_variables,
                                    options.extra_variables, options.blacklist,
                                    options.ignore_broken_items,
                                    options.collapse_symlinks)

    # Regenerate complete_state.saved_state.files.
    if subdir:
        subdir = unicode(subdir)
        # This is tricky here. If it is a path, take it from the root_dir. If
        # it is a variable, it must be keyed from the directory containing the
        # .isolate file. So translate all variables first.
        translated_path_variables = dict(
            (k,
             os.path.normpath(
                 os.path.join(complete_state.saved_state.relative_cwd, v)))
            for k, v in complete_state.saved_state.path_variables.iteritems())
        subdir = isolate_format.eval_variables(subdir,
                                               translated_path_variables)
        subdir = subdir.replace('/', os.path.sep)

    if not skip_update:
        complete_state.files_to_metadata(subdir, options.collapse_symlinks)
    return complete_state
  def test_root_dir_because_of_variable(self):
    # Ensures that load_isolate() works even when path variables have deep root
    # dirs. The end result is similar to touch_root.isolate, except that
    # no_run.isolate doesn't reference '..' at all.
    #
    # A real world example would be PRODUCT_DIR=../../out/Release but nothing in
    # this directory is mapped.
    #
    # Imagine base/base_unittests.isolate would not map anything in
    # PRODUCT_DIR. In that case, the automatically determined root dir is
    # src/base, since nothing outside this directory is mapped.
    isolate_file = os.path.join(
        ROOT_DIR, 'tests', 'isolate', 'no_run.isolate')
    options = self._get_option(isolate_file)
    # Any directory outside ROOT_DIR/tests/isolate.
    options.path_variables['PRODUCT_DIR'] = os.path.join('third_party')
    complete_state = isolate.load_complete_state(options, ROOT_DIR, None, False)
    actual_isolated = complete_state.saved_state.to_isolated()
    actual_saved_state = complete_state.saved_state.flatten()

    expected_isolated = {
      'algo': 'sha-1',
      'files': {
        os.path.join(u'tests', 'isolate', 'files1', 'subdir', '42.txt'): {
          'm': 416,
          'h': hash_file('tests', 'isolate', 'files1', 'subdir', '42.txt'),
          's': _size('tests', 'isolate', 'files1', 'subdir', '42.txt'),
        },
        os.path.join(u'tests', 'isolate', 'files1', 'test_file1.txt'): {
          'm': 416,
          'h': hash_file('tests', 'isolate', 'files1', 'test_file1.txt'),
          's': _size('tests', 'isolate', 'files1', 'test_file1.txt'),
        },
        os.path.join(u'tests', 'isolate', 'files1', 'test_file2.txt'): {
          'm': 416,
          'h': hash_file('tests', 'isolate', 'files1', 'test_file2.txt'),
          's': _size('tests', 'isolate', 'files1', 'test_file2.txt'),
        },
        os.path.join(u'tests', 'isolate', 'no_run.isolate'): {
          'm': 416,
          'h': hash_file('tests', 'isolate', 'no_run.isolate'),
          's': _size('tests', 'isolate', 'no_run.isolate'),
        },
      },
      'relative_cwd': os.path.join(u'tests', 'isolate'),
      'version': isolate.isolateserver.ISOLATED_FILE_VERSION,
    }
    self._cleanup_isolated(expected_isolated)
    self.assertEqual(expected_isolated, actual_isolated)

    expected_saved_state = {
      'OS': sys.platform,
      'algo': 'sha-1',
      'child_isolated_files': [],
      'command': [],
      'config_variables': {
        'OS': 'linux',
        'chromeos': 1,
      },
      'extra_variables': {
        'foo': 'bar',
      },
      'files': {
        os.path.join(u'tests', 'isolate', 'files1', 'subdir', '42.txt'): {
          'm': 416,
          'h': hash_file('tests', 'isolate', 'files1', 'subdir', '42.txt'),
          's': _size('tests', 'isolate', 'files1', 'subdir', '42.txt'),
        },
        os.path.join(u'tests', 'isolate', 'files1', 'test_file1.txt'): {
          'm': 416,
          'h': hash_file('tests', 'isolate', 'files1', 'test_file1.txt'),
          's': _size('tests', 'isolate', 'files1', 'test_file1.txt'),
        },
        os.path.join(u'tests', 'isolate', 'files1', 'test_file2.txt'): {
          'm': 416,
          'h': hash_file('tests', 'isolate', 'files1', 'test_file2.txt'),
          's': _size('tests', 'isolate', 'files1', 'test_file2.txt'),
        },
        os.path.join(u'tests', 'isolate', 'no_run.isolate'): {
          'm': 416,
          'h': hash_file('tests', 'isolate', 'no_run.isolate'),
          's': _size('tests', 'isolate', 'no_run.isolate'),
        },
      },
      'isolate_file': file_path.safe_relpath(
          file_path.get_native_path_case(isolate_file),
          os.path.dirname(options.isolated)),
      'path_variables': {
        'PRODUCT_DIR': os.path.join(u'..', '..', 'third_party'),
      },
      'relative_cwd': os.path.join(u'tests', 'isolate'),
      'root_dir': file_path.get_native_path_case(ROOT_DIR),
      'version': isolate.SavedState.EXPECTED_VERSION,
    }
    self._cleanup_isolated(expected_saved_state)
    self._cleanup_saved_state(actual_saved_state)
    self.assertEqual(expected_saved_state, actual_saved_state)
    self.assertEqual([], os.listdir(self.directory))
  def test_chromium_split(self):
    # Create an .isolate file and a tree of random stuff.
    isolate_file = os.path.join(
        ROOT_DIR, 'tests', 'isolate', 'split.isolate')
    options = self._get_option(isolate_file)
    options.path_variables = {
      'DEPTH': '.',
      'PRODUCT_DIR': os.path.join('files1'),
    }
    options.config_variables = {
      'OS': 'linux',
    }
    complete_state = isolate.load_complete_state(
        options, os.path.join(ROOT_DIR, 'tests', 'isolate'), None, False)
    # By saving the files, it forces splitting the data up.
    complete_state.save_files()

    actual_isolated_master = tools.read_json(
        os.path.join(self.directory, 'foo.isolated'))
    expected_isolated_master = {
      u'algo': u'sha-1',
      u'command': [u'python', u'split.py'],
      u'files': {
        u'split.py': {
          u'm': 488,
          u'h': unicode(hash_file('tests', 'isolate', 'split.py')),
          u's': _size('tests', 'isolate', 'split.py'),
        },
      },
      u'includes': [
        unicode(hash_file(os.path.join(self.directory, 'foo.0.isolated'))),
        unicode(hash_file(os.path.join(self.directory, 'foo.1.isolated'))),
      ],
      u'relative_cwd': u'.',
      u'version': unicode(isolate.isolateserver.ISOLATED_FILE_VERSION),
    }
    self._cleanup_isolated(expected_isolated_master)
    self.assertEqual(expected_isolated_master, actual_isolated_master)

    actual_isolated_0 = tools.read_json(
        os.path.join(self.directory, 'foo.0.isolated'))
    expected_isolated_0 = {
      u'algo': u'sha-1',
      u'files': {
        os.path.join(u'test', 'data', 'foo.txt'): {
          u'm': 416,
          u'h': unicode(
              hash_file('tests', 'isolate', 'test', 'data', 'foo.txt')),
          u's': _size('tests', 'isolate', 'test', 'data', 'foo.txt'),
        },
      },
      u'version': unicode(isolate.isolateserver.ISOLATED_FILE_VERSION),
    }
    self._cleanup_isolated(expected_isolated_0)
    self.assertEqual(expected_isolated_0, actual_isolated_0)

    actual_isolated_1 = tools.read_json(
        os.path.join(self.directory, 'foo.1.isolated'))
    expected_isolated_1 = {
      u'algo': u'sha-1',
      u'files': {
        os.path.join(u'files1', 'subdir', '42.txt'): {
          u'm': 416,
          u'h': unicode(
              hash_file('tests', 'isolate', 'files1', 'subdir', '42.txt')),
          u's': _size('tests', 'isolate', 'files1', 'subdir', '42.txt'),
        },
      },
      u'version': unicode(isolate.isolateserver.ISOLATED_FILE_VERSION),
    }
    self._cleanup_isolated(expected_isolated_1)
    self.assertEqual(expected_isolated_1, actual_isolated_1)

    actual_saved_state = tools.read_json(
        isolate.isolatedfile_to_state(options.isolated))
    isolated_base = unicode(os.path.basename(options.isolated))
    expected_saved_state = {
      u'OS': unicode(sys.platform),
      u'algo': u'sha-1',
      u'child_isolated_files': [
        isolated_base[:-len('.isolated')] + '.0.isolated',
        isolated_base[:-len('.isolated')] + '.1.isolated',
      ],
      u'command': [u'python', u'split.py'],
      u'config_variables': {
        u'OS': u'linux',
      },
      u'extra_variables': {
        u'foo': u'bar',
      },
      u'files': {
        os.path.join(u'files1', 'subdir', '42.txt'): {
          u'm': 416,
          u'h': unicode(
              hash_file('tests', 'isolate', 'files1', 'subdir', '42.txt')),
          u's': _size('tests', 'isolate', 'files1', 'subdir', '42.txt'),
        },
        u'split.py': {
          u'm': 488,
          u'h': unicode(hash_file('tests', 'isolate', 'split.py')),
          u's': _size('tests', 'isolate', 'split.py'),
        },
        os.path.join(u'test', 'data', 'foo.txt'): {
          u'm': 416,
          u'h': unicode(
              hash_file('tests', 'isolate', 'test', 'data', 'foo.txt')),
          u's': _size('tests', 'isolate', 'test', 'data', 'foo.txt'),
        },
      },
      u'isolate_file': file_path.safe_relpath(
          file_path.get_native_path_case(isolate_file),
          unicode(os.path.dirname(options.isolated))),
      u'path_variables': {
        u'DEPTH': u'.',
        u'PRODUCT_DIR': u'files1',
      },
      u'relative_cwd': u'.',
      u'root_dir': file_path.get_native_path_case(
          os.path.dirname(isolate_file)),
      u'version': unicode(isolate.SavedState.EXPECTED_VERSION),
    }
    self._cleanup_isolated(expected_saved_state)
    self._cleanup_saved_state(actual_saved_state)
    self.assertEqual(expected_saved_state, actual_saved_state)
    self.assertEqual(
        [
          'foo.0.isolated', 'foo.1.isolated',
          'foo.isolated', 'foo.isolated.state',
        ],
        sorted(os.listdir(self.directory)))
  def test_subdir_variable(self):
    # the resulting .isolated file will be missing ../../isolate.py. it is
    # because this file is outside the --subdir parameter.
    isolate_file = os.path.join(
        ROOT_DIR, 'tests', 'isolate', 'touch_root.isolate')
    options = self._get_option(isolate_file)
    # Path variables are keyed on the directory containing the .isolate file.
    options.path_variables['TEST_ISOLATE'] = '.'
    # Note that options.isolated is in self.directory, which is a temporary
    # directory.
    complete_state = isolate.load_complete_state(
        options, os.path.join(ROOT_DIR, 'tests', 'isolate'),
        '<(TEST_ISOLATE)', False)
    actual_isolated = complete_state.saved_state.to_isolated()
    actual_saved_state = complete_state.saved_state.flatten()

    expected_isolated =  {
      'algo': 'sha-1',
      'command': ['python', 'touch_root.py'],
      'files': {
        os.path.join('tests', 'isolate', 'touch_root.py'): {
          'm': 488,
          'h': hash_file('tests', 'isolate', 'touch_root.py'),
          's': _size('tests', 'isolate', 'touch_root.py'),
        },
      },
      'relative_cwd': os.path.join(u'tests', 'isolate'),
      'version': isolate.isolateserver.ISOLATED_FILE_VERSION,
    }
    self._cleanup_isolated(expected_isolated)
    self.assertEqual(expected_isolated, actual_isolated)

    # It is important to note:
    # - the root directory is ROOT_DIR.
    # - relative_cwd is tests/isolate.
    # - TEST_ISOLATE is based of relative_cwd, so it represents tests/isolate.
    # - anything outside TEST_ISOLATE was not included in the 'files' section.
    expected_saved_state = {
      'OS': sys.platform,
      'algo': 'sha-1',
      'child_isolated_files': [],
      'command': ['python', 'touch_root.py'],
      'config_variables': {
        'OS': 'linux',
        'chromeos': 1,
      },
      'extra_variables': {
        'foo': 'bar',
      },
      'files': {
        os.path.join(u'tests', 'isolate', 'touch_root.py'): {
          'm': 488,
          'h': hash_file('tests', 'isolate', 'touch_root.py'),
          's': _size('tests', 'isolate', 'touch_root.py'),
        },
      },
      'isolate_file': file_path.safe_relpath(
          file_path.get_native_path_case(isolate_file),
          os.path.dirname(options.isolated)),
      'path_variables': {
        'TEST_ISOLATE': '.',
      },
      'relative_cwd': os.path.join(u'tests', 'isolate'),
      'root_dir': file_path.get_native_path_case(ROOT_DIR),
      'version': isolate.SavedState.EXPECTED_VERSION,
    }
    self._cleanup_isolated(expected_saved_state)
    self._cleanup_saved_state(actual_saved_state)
    self.assertEqual(expected_saved_state, actual_saved_state)
  def test_variable(self):
    isolate_file = os.path.join(
        ROOT_DIR, 'tests', 'isolate', 'touch_root.isolate')
    options = self._get_option(isolate_file)
    options.path_variables['PRODUCT_DIR'] = os.path.join('tests', 'isolate')
    complete_state = isolate.load_complete_state(options, ROOT_DIR, None, False)
    actual_isolated = complete_state.saved_state.to_isolated()
    actual_saved_state = complete_state.saved_state.flatten()

    expected_isolated =  {
      'algo': 'sha-1',
      'command': ['python', 'touch_root.py'],
      'files': {
        u'isolate.py': {
          'm': 488,
          'h': hash_file('isolate.py'),
          's': _size('isolate.py'),
        },
        os.path.join(u'tests', 'isolate', 'touch_root.py'): {
          'm': 488,
          'h': hash_file('tests', 'isolate', 'touch_root.py'),
          's': _size('tests', 'isolate', 'touch_root.py'),
        },
      },
      'relative_cwd': os.path.join(u'tests', 'isolate'),
      'version': isolate.isolateserver.ISOLATED_FILE_VERSION,
    }
    self._cleanup_isolated(expected_isolated)
    self.assertEqual(expected_isolated, actual_isolated)

    expected_saved_state = {
      'OS': sys.platform,
      'algo': 'sha-1',
      'child_isolated_files': [],
      'command': ['python', 'touch_root.py'],
      'config_variables': {
        'OS': 'linux',
        'chromeos': 1,
      },
      'extra_variables': {
        'foo': 'bar',
      },
      'files': {
        u'isolate.py': {
          'm': 488,
          'h': hash_file('isolate.py'),
          's': _size('isolate.py'),
        },
        os.path.join(u'tests', 'isolate', 'touch_root.py'): {
          'm': 488,
          'h': hash_file('tests', 'isolate', 'touch_root.py'),
          's': _size('tests', 'isolate', 'touch_root.py'),
        },
      },
      'isolate_file': file_path.safe_relpath(
          file_path.get_native_path_case(isolate_file),
          os.path.dirname(options.isolated)),
      'path_variables': {
        'PRODUCT_DIR': '.',
      },
      'relative_cwd': os.path.join(u'tests', 'isolate'),
      'root_dir': file_path.get_native_path_case(ROOT_DIR),
      'version': isolate.SavedState.EXPECTED_VERSION,
    }
    self._cleanup_isolated(expected_saved_state)
    self._cleanup_saved_state(actual_saved_state)
    self.assertEqual(expected_saved_state, actual_saved_state)
    self.assertEqual([], os.listdir(self.directory))
Esempio n. 18
0
  def test_subdir_variable(self):
    # the resulting .isolated file will be missing ../../isolate.py. it is
    # because this file is outside the --subdir parameter.
    isolate_file = os.path.join(
        ROOT_DIR, 'tests', 'isolate', 'touch_root.isolate')
    options = self._get_option(isolate_file)
    # Path variables are keyed on the directory containing the .isolate file.
    options.path_variables['TEST_ISOLATE'] = '.'
    # Note that options.isolated is in self.directory, which is a temporary
    # directory.
    complete_state = isolate.load_complete_state(
        options, os.path.join(ROOT_DIR, 'tests', 'isolate'),
        '<(TEST_ISOLATE)', False)
    actual_isolated = complete_state.saved_state.to_isolated()
    actual_saved_state = complete_state.saved_state.flatten()

    expected_isolated =  {
      'algo': 'sha-1',
      'command': ['python', 'touch_root.py'],
      'files': {
        os.path.join('tests', 'isolate', 'touch_root.py'): {
          'm': 488,
          'h': hash_file('tests', 'isolate', 'touch_root.py'),
          's': _size('tests', 'isolate', 'touch_root.py'),
        },
      },
      'relative_cwd': os.path.join(u'tests', 'isolate'),
      'version': isolate.isolateserver.ISOLATED_FILE_VERSION,
    }
    self._cleanup_isolated(expected_isolated)
    self.assertEqual(expected_isolated, actual_isolated)

    # It is important to note:
    # - the root directory is ROOT_DIR.
    # - relative_cwd is tests/isolate.
    # - TEST_ISOLATE is based of relative_cwd, so it represents tests/isolate.
    # - anything outside TEST_ISOLATE was not included in the 'files' section.
    expected_saved_state = {
      'OS': sys.platform,
      'algo': 'sha-1',
      'child_isolated_files': [],
      'command': ['python', 'touch_root.py'],
      'config_variables': {
        'OS': 'linux',
        'chromeos': 1,
      },
      'extra_variables': {
        'foo': 'bar',
      },
      'files': {
        os.path.join(u'tests', 'isolate', 'touch_root.py'): {
          'm': 488,
          'h': hash_file('tests', 'isolate', 'touch_root.py'),
          's': _size('tests', 'isolate', 'touch_root.py'),
        },
      },
      'isolate_file': file_path.safe_relpath(
          file_path.get_native_path_case(isolate_file),
          os.path.dirname(options.isolated)),
      'path_variables': {
        'TEST_ISOLATE': '.',
      },
      'relative_cwd': os.path.join(u'tests', 'isolate'),
      'root_dir': file_path.get_native_path_case(ROOT_DIR),
      'version': isolate.SavedState.EXPECTED_VERSION,
    }
    self._cleanup_isolated(expected_saved_state)
    self._cleanup_saved_state(actual_saved_state)
    self.assertEqual(expected_saved_state, actual_saved_state)
Esempio n. 19
0
  def test_variable(self):
    isolate_file = os.path.join(
        ROOT_DIR, 'tests', 'isolate', 'touch_root.isolate')
    options = self._get_option(isolate_file)
    options.path_variables['PRODUCT_DIR'] = os.path.join('tests', 'isolate')
    complete_state = isolate.load_complete_state(options, ROOT_DIR, None, False)
    actual_isolated = complete_state.saved_state.to_isolated()
    actual_saved_state = complete_state.saved_state.flatten()

    expected_isolated =  {
      'algo': 'sha-1',
      'command': ['python', 'touch_root.py'],
      'files': {
        u'isolate.py': {
          'm': 488,
          'h': hash_file('isolate.py'),
          's': _size('isolate.py'),
        },
        os.path.join(u'tests', 'isolate', 'touch_root.py'): {
          'm': 488,
          'h': hash_file('tests', 'isolate', 'touch_root.py'),
          's': _size('tests', 'isolate', 'touch_root.py'),
        },
      },
      'relative_cwd': os.path.join(u'tests', 'isolate'),
      'version': isolate.isolateserver.ISOLATED_FILE_VERSION,
    }
    self._cleanup_isolated(expected_isolated)
    self.assertEqual(expected_isolated, actual_isolated)

    expected_saved_state = {
      'OS': sys.platform,
      'algo': 'sha-1',
      'child_isolated_files': [],
      'command': ['python', 'touch_root.py'],
      'config_variables': {
        'OS': 'linux',
        'chromeos': 1,
      },
      'extra_variables': {
        'foo': 'bar',
      },
      'files': {
        u'isolate.py': {
          'm': 488,
          'h': hash_file('isolate.py'),
          's': _size('isolate.py'),
        },
        os.path.join(u'tests', 'isolate', 'touch_root.py'): {
          'm': 488,
          'h': hash_file('tests', 'isolate', 'touch_root.py'),
          's': _size('tests', 'isolate', 'touch_root.py'),
        },
      },
      'isolate_file': file_path.safe_relpath(
          file_path.get_native_path_case(isolate_file),
          os.path.dirname(options.isolated)),
      'path_variables': {
        'PRODUCT_DIR': '.',
      },
      'relative_cwd': os.path.join(u'tests', 'isolate'),
      'root_dir': file_path.get_native_path_case(ROOT_DIR),
      'version': isolate.SavedState.EXPECTED_VERSION,
    }
    self._cleanup_isolated(expected_saved_state)
    self._cleanup_saved_state(actual_saved_state)
    self.assertEqual(expected_saved_state, actual_saved_state)
    self.assertEqual([], os.listdir(self.directory))
Esempio n. 20
0
  def test_load_stale_isolated(self):
    isolate_file = os.path.join(
        ROOT_DIR, 'tests', 'isolate', 'touch_root.isolate')

    # Data to be loaded in the .isolated file. Do not create a .state file.
    input_data = {
      'command': ['python'],
      'files': {
        'foo': {
          "m": 416,
          "h": "invalid",
          "s": 538,
          "t": 1335146921,
        },
        os.path.join('tests', 'isolate', 'touch_root.py'): {
          "m": 488,
          "h": "invalid",
          "s": 538,
          "t": 1335146921,
        },
      },
    }
    options = self._get_option(isolate_file)
    tools.write_json(options.isolated, input_data, False)

    # A CompleteState object contains two parts:
    # - Result instance stored in complete_state.isolated, corresponding to the
    #   .isolated file, is what is read by run_test_from_archive.py.
    # - SavedState instance stored in compelte_state.saved_state,
    #   corresponding to the .state file, which is simply to aid the developer
    #   when re-running the same command multiple times and contain
    #   discardable information.
    complete_state = isolate.load_complete_state(options, self.cwd, None, False)
    actual_isolated = complete_state.saved_state.to_isolated()
    actual_saved_state = complete_state.saved_state.flatten()

    expected_isolated = {
      'algo': 'sha-1',
      'command': ['python', 'touch_root.py'],
      'files': {
        os.path.join(u'tests', 'isolate', 'touch_root.py'): {
          'm': 488,
          'h': hash_file('tests', 'isolate', 'touch_root.py'),
          's': _size('tests', 'isolate', 'touch_root.py'),
        },
        u'isolate.py': {
          'm': 488,
          'h': hash_file('isolate.py'),
          's': _size('isolate.py'),
        },
      },
      'relative_cwd': os.path.join(u'tests', 'isolate'),
      'version': isolate.isolateserver.ISOLATED_FILE_VERSION,
    }
    self._cleanup_isolated(expected_isolated)
    self.assertEqual(expected_isolated, actual_isolated)

    expected_saved_state = {
      'OS': sys.platform,
      'algo': 'sha-1',
      'child_isolated_files': [],
      'command': ['python', 'touch_root.py'],
      'config_variables': {
        'OS': 'linux',
        'chromeos': options.config_variables['chromeos'],
      },
      'extra_variables': {
        'foo': 'bar',
      },
      'files': {
        os.path.join(u'tests', 'isolate', 'touch_root.py'): {
          'm': 488,
          'h': hash_file('tests', 'isolate', 'touch_root.py'),
          's': _size('tests', 'isolate', 'touch_root.py'),
        },
        u'isolate.py': {
          'm': 488,
          'h': hash_file('isolate.py'),
          's': _size('isolate.py'),
        },
      },
      'isolate_file': file_path.safe_relpath(
          file_path.get_native_path_case(isolate_file),
          os.path.dirname(options.isolated)),
      'path_variables': {},
      'relative_cwd': os.path.join(u'tests', 'isolate'),
      'root_dir': file_path.get_native_path_case(ROOT_DIR),
      'version': isolate.SavedState.EXPECTED_VERSION,
    }
    self._cleanup_isolated(expected_saved_state)
    self._cleanup_saved_state(actual_saved_state)
    self.assertEqual(expected_saved_state, actual_saved_state)
Esempio n. 21
0
  def test_root_dir_because_of_variable(self):
    # Ensures that load_isolate() works even when path variables have deep root
    # dirs. The end result is similar to touch_root.isolate, except that
    # no_run.isolate doesn't reference '..' at all.
    #
    # A real world example would be PRODUCT_DIR=../../out/Release but nothing in
    # this directory is mapped.
    #
    # Imagine base/base_unittests.isolate would not map anything in
    # PRODUCT_DIR. In that case, the automatically determined root dir is
    # src/base, since nothing outside this directory is mapped.
    isolate_file = os.path.join(
        ROOT_DIR, 'tests', 'isolate', 'no_run.isolate')
    options = self._get_option(isolate_file)
    # Any directory outside ROOT_DIR/tests/isolate.
    options.path_variables['PRODUCT_DIR'] = os.path.join('third_party')
    complete_state = isolate.load_complete_state(options, ROOT_DIR, None, False)
    actual_isolated = complete_state.saved_state.to_isolated()
    actual_saved_state = complete_state.saved_state.flatten()

    expected_isolated = {
      'algo': 'sha-1',
      'files': {
        os.path.join(u'tests', 'isolate', 'files1', 'subdir', '42.txt'): {
          'm': 416,
          'h': hash_file('tests', 'isolate', 'files1', 'subdir', '42.txt'),
          's': _size('tests', 'isolate', 'files1', 'subdir', '42.txt'),
        },
        os.path.join(u'tests', 'isolate', 'files1', 'test_file1.txt'): {
          'm': 416,
          'h': hash_file('tests', 'isolate', 'files1', 'test_file1.txt'),
          's': _size('tests', 'isolate', 'files1', 'test_file1.txt'),
        },
        os.path.join(u'tests', 'isolate', 'files1', 'test_file2.txt'): {
          'm': 416,
          'h': hash_file('tests', 'isolate', 'files1', 'test_file2.txt'),
          's': _size('tests', 'isolate', 'files1', 'test_file2.txt'),
        },
        os.path.join(u'tests', 'isolate', 'no_run.isolate'): {
          'm': 416,
          'h': hash_file('tests', 'isolate', 'no_run.isolate'),
          's': _size('tests', 'isolate', 'no_run.isolate'),
        },
      },
      'relative_cwd': os.path.join(u'tests', 'isolate'),
      'version': isolate.isolateserver.ISOLATED_FILE_VERSION,
    }
    self._cleanup_isolated(expected_isolated)
    self.assertEqual(expected_isolated, actual_isolated)

    expected_saved_state = {
      'OS': sys.platform,
      'algo': 'sha-1',
      'child_isolated_files': [],
      'command': [],
      'config_variables': {
        'OS': 'linux',
        'chromeos': 1,
      },
      'extra_variables': {
        'foo': 'bar',
      },
      'files': {
        os.path.join(u'tests', 'isolate', 'files1', 'subdir', '42.txt'): {
          'm': 416,
          'h': hash_file('tests', 'isolate', 'files1', 'subdir', '42.txt'),
          's': _size('tests', 'isolate', 'files1', 'subdir', '42.txt'),
        },
        os.path.join(u'tests', 'isolate', 'files1', 'test_file1.txt'): {
          'm': 416,
          'h': hash_file('tests', 'isolate', 'files1', 'test_file1.txt'),
          's': _size('tests', 'isolate', 'files1', 'test_file1.txt'),
        },
        os.path.join(u'tests', 'isolate', 'files1', 'test_file2.txt'): {
          'm': 416,
          'h': hash_file('tests', 'isolate', 'files1', 'test_file2.txt'),
          's': _size('tests', 'isolate', 'files1', 'test_file2.txt'),
        },
        os.path.join(u'tests', 'isolate', 'no_run.isolate'): {
          'm': 416,
          'h': hash_file('tests', 'isolate', 'no_run.isolate'),
          's': _size('tests', 'isolate', 'no_run.isolate'),
        },
      },
      'isolate_file': file_path.safe_relpath(
          file_path.get_native_path_case(isolate_file),
          os.path.dirname(options.isolated)),
      'path_variables': {
        'PRODUCT_DIR': os.path.join(u'..', '..', 'third_party'),
      },
      'relative_cwd': os.path.join(u'tests', 'isolate'),
      'root_dir': file_path.get_native_path_case(ROOT_DIR),
      'version': isolate.SavedState.EXPECTED_VERSION,
    }
    self._cleanup_isolated(expected_saved_state)
    self._cleanup_saved_state(actual_saved_state)
    self.assertEqual(expected_saved_state, actual_saved_state)
    self.assertEqual([], os.listdir(self.directory))
Esempio n. 22
0
  def test_chromium_split(self):
    # Create an .isolate file and a tree of random stuff.
    isolate_file = os.path.join(
        ROOT_DIR, 'tests', 'isolate', 'split.isolate')
    options = self._get_option(isolate_file)
    options.path_variables = {
      'DEPTH': '.',
      'PRODUCT_DIR': os.path.join('files1'),
    }
    options.config_variables = {
      'OS': 'linux',
    }
    complete_state = isolate.load_complete_state(
        options, os.path.join(ROOT_DIR, 'tests', 'isolate'), None, False)
    # By saving the files, it forces splitting the data up.
    complete_state.save_files()

    actual_isolated_master = tools.read_json(
        os.path.join(self.directory, 'foo.isolated'))
    expected_isolated_master = {
      u'algo': u'sha-1',
      u'command': [u'python', u'split.py'],
      u'files': {
        u'split.py': {
          u'm': 488,
          u'h': unicode(hash_file('tests', 'isolate', 'split.py')),
          u's': _size('tests', 'isolate', 'split.py'),
        },
      },
      u'includes': [
        unicode(hash_file(os.path.join(self.directory, 'foo.0.isolated'))),
        unicode(hash_file(os.path.join(self.directory, 'foo.1.isolated'))),
      ],
      u'relative_cwd': u'.',
      u'version': unicode(isolate.isolateserver.ISOLATED_FILE_VERSION),
    }
    self._cleanup_isolated(expected_isolated_master)
    self.assertEqual(expected_isolated_master, actual_isolated_master)

    actual_isolated_0 = tools.read_json(
        os.path.join(self.directory, 'foo.0.isolated'))
    expected_isolated_0 = {
      u'algo': u'sha-1',
      u'files': {
        os.path.join(u'test', 'data', 'foo.txt'): {
          u'm': 416,
          u'h': unicode(
              hash_file('tests', 'isolate', 'test', 'data', 'foo.txt')),
          u's': _size('tests', 'isolate', 'test', 'data', 'foo.txt'),
        },
      },
      u'version': unicode(isolate.isolateserver.ISOLATED_FILE_VERSION),
    }
    self._cleanup_isolated(expected_isolated_0)
    self.assertEqual(expected_isolated_0, actual_isolated_0)

    actual_isolated_1 = tools.read_json(
        os.path.join(self.directory, 'foo.1.isolated'))
    expected_isolated_1 = {
      u'algo': u'sha-1',
      u'files': {
        os.path.join(u'files1', 'subdir', '42.txt'): {
          u'm': 416,
          u'h': unicode(
              hash_file('tests', 'isolate', 'files1', 'subdir', '42.txt')),
          u's': _size('tests', 'isolate', 'files1', 'subdir', '42.txt'),
        },
      },
      u'version': unicode(isolate.isolateserver.ISOLATED_FILE_VERSION),
    }
    self._cleanup_isolated(expected_isolated_1)
    self.assertEqual(expected_isolated_1, actual_isolated_1)

    actual_saved_state = tools.read_json(
        isolate.isolatedfile_to_state(options.isolated))
    isolated_base = unicode(os.path.basename(options.isolated))
    expected_saved_state = {
      u'OS': unicode(sys.platform),
      u'algo': u'sha-1',
      u'child_isolated_files': [
        isolated_base[:-len('.isolated')] + '.0.isolated',
        isolated_base[:-len('.isolated')] + '.1.isolated',
      ],
      u'command': [u'python', u'split.py'],
      u'config_variables': {
        u'OS': u'linux',
      },
      u'extra_variables': {
        u'foo': u'bar',
      },
      u'files': {
        os.path.join(u'files1', 'subdir', '42.txt'): {
          u'm': 416,
          u'h': unicode(
              hash_file('tests', 'isolate', 'files1', 'subdir', '42.txt')),
          u's': _size('tests', 'isolate', 'files1', 'subdir', '42.txt'),
        },
        u'split.py': {
          u'm': 488,
          u'h': unicode(hash_file('tests', 'isolate', 'split.py')),
          u's': _size('tests', 'isolate', 'split.py'),
        },
        os.path.join(u'test', 'data', 'foo.txt'): {
          u'm': 416,
          u'h': unicode(
              hash_file('tests', 'isolate', 'test', 'data', 'foo.txt')),
          u's': _size('tests', 'isolate', 'test', 'data', 'foo.txt'),
        },
      },
      u'isolate_file': file_path.safe_relpath(
          file_path.get_native_path_case(isolate_file),
          unicode(os.path.dirname(options.isolated))),
      u'path_variables': {
        u'DEPTH': u'.',
        u'PRODUCT_DIR': u'files1',
      },
      u'relative_cwd': u'.',
      u'root_dir': file_path.get_native_path_case(
          os.path.dirname(isolate_file)),
      u'version': unicode(isolate.SavedState.EXPECTED_VERSION),
    }
    self._cleanup_isolated(expected_saved_state)
    self._cleanup_saved_state(actual_saved_state)
    self.assertEqual(expected_saved_state, actual_saved_state)
    self.assertEqual(
        [
          'foo.0.isolated', 'foo.1.isolated',
          'foo.isolated', 'foo.isolated.state',
        ],
        sorted(os.listdir(self.directory)))