tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

md5_check_test.py (6765B)


      1 #!/usr/bin/env python3
      2 # Copyright 2013 The Chromium Authors
      3 # Use of this source code is governed by a BSD-style license that can be
      4 # found in the LICENSE file.
      5 
      6 import fnmatch
      7 import os
      8 import sys
      9 import tempfile
     10 import unittest
     11 import zipfile
     12 
     13 sys.path.insert(
     14    0, os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir)))
     15 from util import md5_check
     16 
     17 
     18 def _WriteZipFile(path, entries):
     19  with zipfile.ZipFile(path, 'w') as zip_file:
     20    for subpath, data in entries:
     21      zip_file.writestr(subpath, data)
     22 
     23 
     24 class TestMd5Check(unittest.TestCase):
     25  def setUp(self):
     26    self.called = False
     27    self.changes = None
     28 
     29  def testCallAndRecordIfStale(self):
     30    input_strings = ['string1', 'string2']
     31    input_file1 = tempfile.NamedTemporaryFile(suffix='.txt')
     32    input_file2 = tempfile.NamedTemporaryFile(suffix='.zip')
     33    file1_contents = b'input file 1'
     34    input_file1.write(file1_contents)
     35    input_file1.flush()
     36    # Test out empty zip file to start.
     37    _WriteZipFile(input_file2.name, [])
     38    input_files = [input_file1.name, input_file2.name]
     39    zip_paths = [os.path.relpath(input_file2.name)]
     40 
     41    record_path = tempfile.NamedTemporaryFile(suffix='.stamp')
     42 
     43    def CheckCallAndRecord(should_call,
     44                           message,
     45                           force=False,
     46                           outputs_specified=False,
     47                           outputs_missing=False,
     48                           expected_changes=None,
     49                           added_or_modified_only=None,
     50                           track_subentries=False):
     51      output_paths = None
     52      if outputs_specified:
     53        output_file1 = tempfile.NamedTemporaryFile()
     54        if outputs_missing:
     55          output_file1.close()  # Gets deleted on close().
     56        output_paths = [output_file1.name]
     57 
     58      self.called = False
     59      self.changes = None
     60      if expected_changes or added_or_modified_only is not None:
     61        def MarkCalled(changes):
     62          self.called = True
     63          self.changes = changes
     64      else:
     65        def MarkCalled():
     66          self.called = True
     67 
     68      md5_check.CallAndRecordIfStale(
     69          MarkCalled,
     70          record_path=record_path.name,
     71          input_paths=input_files,
     72          input_strings=input_strings,
     73          output_paths=output_paths,
     74          force=force,
     75          pass_changes=(expected_changes or added_or_modified_only) is not None,
     76          track_subpaths_allowlist=zip_paths if track_subentries else None)
     77      self.assertEqual(should_call, self.called, message)
     78      if expected_changes:
     79        description = self.changes.DescribeDifference()
     80        self.assertTrue(fnmatch.fnmatch(description, expected_changes),
     81                        'Expected %s to match %s' % (
     82                        repr(description), repr(expected_changes)))
     83      if should_call and added_or_modified_only is not None:
     84        self.assertEqual(added_or_modified_only,
     85                         self.changes.AddedOrModifiedOnly())
     86 
     87    CheckCallAndRecord(True, 'should call when record doesn\'t exist',
     88                       expected_changes='Previous stamp file not found.',
     89                       added_or_modified_only=False)
     90    CheckCallAndRecord(False, 'should not call when nothing changed')
     91    input_files = input_files[::-1]
     92    CheckCallAndRecord(False, 'reordering of inputs shouldn\'t trigger call')
     93 
     94    CheckCallAndRecord(False, 'should not call when nothing changed #2',
     95                       outputs_specified=True, outputs_missing=False)
     96    CheckCallAndRecord(True, 'should call when output missing',
     97                       outputs_specified=True, outputs_missing=True,
     98                       expected_changes='Outputs do not exist:*',
     99                       added_or_modified_only=False)
    100    CheckCallAndRecord(True, force=True, message='should call when forced',
    101                       expected_changes='force=True',
    102                       added_or_modified_only=False)
    103 
    104    input_file1.write(b'some more input')
    105    input_file1.flush()
    106    CheckCallAndRecord(True,
    107                       'changed input file should trigger call',
    108                       expected_changes='*Modified: %s' %
    109                       os.path.relpath(input_file1.name),
    110                       added_or_modified_only=True)
    111 
    112    input_files = input_files[:1]
    113    CheckCallAndRecord(True,
    114                       'removing file should trigger call',
    115                       expected_changes='*Removed: %s' %
    116                       os.path.relpath(input_file1.name),
    117                       added_or_modified_only=False)
    118 
    119    input_files.append(input_file1.name)
    120    CheckCallAndRecord(True,
    121                       'added input file should trigger call',
    122                       expected_changes='*Added: %s' %
    123                       os.path.relpath(input_file1.name),
    124                       added_or_modified_only=True)
    125 
    126    input_strings[0] = input_strings[0] + ' a bit longer'
    127    CheckCallAndRecord(True, 'changed input string should trigger call',
    128                       expected_changes='*Input strings changed*',
    129                       added_or_modified_only=False)
    130 
    131    input_strings = input_strings[::-1]
    132    CheckCallAndRecord(True, 'reordering of string inputs should trigger call',
    133                       expected_changes='*Input strings changed*')
    134 
    135    input_strings = input_strings[:1]
    136    CheckCallAndRecord(True, 'removing a string should trigger call')
    137 
    138    input_strings.append('a brand new string')
    139    CheckCallAndRecord(
    140        True,
    141        'added input string should trigger call',
    142        added_or_modified_only=False)
    143 
    144    _WriteZipFile(input_file2.name, [('path/1.txt', '1')])
    145    CheckCallAndRecord(True,
    146                       'added subpath should trigger call',
    147                       expected_changes='*Modified: %s*Subpath added: %s' %
    148                       (os.path.relpath(input_file2.name), 'path/1.txt'),
    149                       added_or_modified_only=True,
    150                       track_subentries=True)
    151    _WriteZipFile(input_file2.name, [('path/1.txt', '2')])
    152    CheckCallAndRecord(True,
    153                       'changed subpath should trigger call',
    154                       expected_changes='*Modified: %s*Subpath modified: %s' %
    155                       (os.path.relpath(input_file2.name), 'path/1.txt'),
    156                       added_or_modified_only=True,
    157                       track_subentries=True)
    158 
    159    _WriteZipFile(input_file2.name, [])
    160    CheckCallAndRecord(True,
    161                       'removed subpath should trigger call',
    162                       expected_changes='*Modified: %s*Subpath removed: %s' %
    163                       (os.path.relpath(input_file2.name), 'path/1.txt'),
    164                       added_or_modified_only=False)
    165 
    166 
    167 if __name__ == '__main__':
    168  unittest.main()