Home | History | Annotate | Download | only in tests
      1 #!/usr/bin/env python
      2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
      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 os
      7 import shutil
      8 import subprocess
      9 import sys
     10 import tempfile
     11 import unittest
     12 import zipfile
     13 
     14 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
     15 PARENT_DIR = os.path.dirname(SCRIPT_DIR)
     16 
     17 sys.path.append(PARENT_DIR)
     18 
     19 import oshelpers
     20 
     21 class RunError(subprocess.CalledProcessError):
     22   def __init__(self, retcode, command, output, error_output):
     23     subprocess.CalledProcessError.__init__(self, retcode, command)
     24     self.output = output
     25     self.error_output = error_output
     26 
     27   def __str__(self):
     28     msg = subprocess.CalledProcessError.__str__(self)
     29     msg += '.\nstdout: """%s"""' % (self.output,)
     30     msg += '.\nstderr: """%s"""' % (self.error_output,)
     31     return msg
     32 
     33 
     34 def RunCmd(cmd, args, cwd, env=None):
     35   env = env or os.environ
     36   command = [sys.executable, 'oshelpers.py', cmd] + args
     37   process = subprocess.Popen(stdout=subprocess.PIPE,
     38                              stderr=subprocess.PIPE,
     39                              args=command,
     40                              cwd=cwd,
     41                              env=env)
     42   output, error_output = process.communicate()
     43   retcode = process.returncode
     44 
     45   if retcode:
     46     raise RunError(retcode, command, output, error_output)
     47   return output, error_output
     48 
     49 
     50 class TestZip(unittest.TestCase):
     51   def setUp(self):
     52     # make zipname -> "testFooBar.zip"
     53     self.zipname = self.id().split('.')[-1] + '.zip'
     54     self.zipfile = None
     55     self.tempdir = tempfile.mkdtemp()
     56     shutil.copy(os.path.join(PARENT_DIR, 'oshelpers.py'),
     57         self.tempdir)
     58 
     59   def tearDown(self):
     60     if self.zipfile:
     61       self.zipfile.close()
     62     shutil.rmtree(self.tempdir)
     63 
     64   def GetTempPath(self, basename):
     65     return os.path.join(self.tempdir, basename)
     66 
     67   def MakeFile(self, rel_path, size):
     68     with open(os.path.join(self.tempdir, rel_path), 'wb') as f:
     69       f.write('0' * size)
     70     return rel_path
     71 
     72   def RunZip(self, *args):
     73     return RunCmd('zip', list(args), cwd=self.tempdir)
     74 
     75   def OpenZipFile(self):
     76     self.zipfile = zipfile.ZipFile(self.GetTempPath(self.zipname), 'r')
     77 
     78   def CloseZipFile(self):
     79     self.zipfile.close()
     80     self.zipfile = None
     81 
     82   def GetZipInfo(self, path):
     83     return self.zipfile.getinfo(oshelpers.OSMakeZipPath(path))
     84 
     85   def testNothingToDo(self):
     86     self.assertRaises(subprocess.CalledProcessError, self.RunZip,
     87         self.zipname, 'nonexistent_file')
     88     self.assertFalse(os.path.exists(self.zipname))
     89 
     90   def testAddSomeFiles(self):
     91     file1 = self.MakeFile('file1', 1024)
     92     file2 = self.MakeFile('file2', 3354)
     93     self.RunZip(self.zipname, file1, file2)
     94     self.OpenZipFile()
     95     self.assertEqual(len(self.zipfile.namelist()), 2)
     96     self.assertEqual(self.GetZipInfo(file1).file_size, 1024)
     97     self.assertEqual(self.GetZipInfo(file2).file_size, 3354)
     98     # make sure files are added in order
     99     self.assertEqual(self.zipfile.namelist()[0], file1)
    100 
    101   def testAddFilesWithGlob(self):
    102     self.MakeFile('file1', 1024)
    103     self.MakeFile('file2', 3354)
    104     self.RunZip(self.zipname, 'file*')
    105     self.OpenZipFile()
    106     self.assertEqual(len(self.zipfile.namelist()), 2)
    107 
    108   def testAddDir(self):
    109     os.mkdir(self.GetTempPath('dir1'))
    110     self.RunZip(self.zipname, 'dir1')
    111     self.OpenZipFile()
    112     self.assertEqual(len(self.zipfile.namelist()), 1)
    113     self.assertRaises(KeyError, self.zipfile.getinfo, 'dir1')
    114     self.zipfile.getinfo('dir1/')
    115 
    116   def testAddRecursive(self):
    117     os.mkdir(self.GetTempPath('dir1'))
    118     self.MakeFile(os.path.join('dir1', 'file1'), 256)
    119     os.mkdir(self.GetTempPath(os.path.join('dir1', 'dir2')))
    120     self.MakeFile(os.path.join('dir1', 'dir2', 'file2'), 1234)
    121     self.RunZip(self.zipname, '-r', 'dir1')
    122     self.OpenZipFile()
    123     self.assertEqual(len(self.zipfile.namelist()), 4)
    124 
    125   def testUpdate(self):
    126     file1 = self.MakeFile('file1', 1223)
    127     self.RunZip(self.zipname, file1)
    128     self.OpenZipFile()
    129     self.assertEqual(self.GetZipInfo(file1).file_size, 1223)
    130 
    131     file1 = self.MakeFile('file1', 2334)
    132     self.RunZip(self.zipname, file1)
    133     self.OpenZipFile()
    134     self.assertEqual(len(self.zipfile.namelist()), 1)
    135     self.assertEqual(self.GetZipInfo(file1).file_size, 2334)
    136 
    137   def testUpdateOneFileOutOfMany(self):
    138     file1 = self.MakeFile('file1', 128)
    139     file2 = self.MakeFile('file2', 256)
    140     file3 = self.MakeFile('file3', 512)
    141     file4 = self.MakeFile('file4', 1024)
    142     self.RunZip(self.zipname, file1, file2, file3, file4)
    143     self.OpenZipFile()
    144     self.assertEqual(len(self.zipfile.namelist()), 4)
    145     self.CloseZipFile()
    146 
    147     file3 = self.MakeFile('file3', 768)
    148     self.RunZip(self.zipname, file3)
    149     self.OpenZipFile()
    150     self.assertEqual(len(self.zipfile.namelist()), 4)
    151     self.assertEqual(self.zipfile.namelist()[0], file1)
    152     self.assertEqual(self.GetZipInfo(file1).file_size, 128)
    153     self.assertEqual(self.zipfile.namelist()[1], file2)
    154     self.assertEqual(self.GetZipInfo(file2).file_size, 256)
    155     self.assertEqual(self.zipfile.namelist()[2], file3)
    156     self.assertEqual(self.GetZipInfo(file3).file_size, 768)
    157     self.assertEqual(self.zipfile.namelist()[3], file4)
    158     self.assertEqual(self.GetZipInfo(file4).file_size, 1024)
    159 
    160   def testUpdateSubdirectory(self):
    161     os.mkdir(self.GetTempPath('dir1'))
    162     file1 = self.MakeFile(os.path.join('dir1', 'file1'), 256)
    163     os.mkdir(self.GetTempPath(os.path.join('dir1', 'dir2')))
    164     self.MakeFile(os.path.join('dir1', 'dir2', 'file2'), 1234)
    165     self.RunZip(self.zipname, '-r', 'dir1')
    166     self.OpenZipFile()
    167     self.assertEqual(len(self.zipfile.namelist()), 4)
    168     self.assertEqual(self.GetZipInfo(file1).file_size, 256)
    169     self.CloseZipFile()
    170 
    171     self.MakeFile(file1, 2560)
    172     self.RunZip(self.zipname, file1)
    173     self.OpenZipFile()
    174     self.assertEqual(len(self.zipfile.namelist()), 4)
    175     self.assertEqual(self.GetZipInfo(file1).file_size, 2560)
    176 
    177   def testAppend(self):
    178     file1 = self.MakeFile('file1', 128)
    179     file2 = self.MakeFile('file2', 256)
    180     self.RunZip(self.zipname, file1, file2)
    181     self.OpenZipFile()
    182     self.assertEqual(len(self.zipfile.namelist()), 2)
    183     self.CloseZipFile()
    184 
    185     file3 = self.MakeFile('file3', 768)
    186     self.RunZip(self.zipname, file3)
    187     self.OpenZipFile()
    188     self.assertEqual(len(self.zipfile.namelist()), 3)
    189 
    190 
    191 class TestWhich(unittest.TestCase):
    192   def setUp(self):
    193     self.path_list = []
    194     self.tempdir = tempfile.mkdtemp()
    195     shutil.copy(os.path.join(PARENT_DIR, 'oshelpers.py'),
    196         self.tempdir)
    197 
    198   def tearDown(self):
    199     shutil.rmtree(self.tempdir)
    200 
    201   def Mkdir(self, path):
    202     os.mkdir(os.path.join(self.tempdir, path))
    203 
    204   def MakeExecutableFile(self, *path_components):
    205     path = os.path.join(self.tempdir, *path_components)
    206     if sys.platform == 'win32':
    207       path += '.exe'
    208 
    209     with open(path, 'w') as f:
    210       f.write('')
    211     os.chmod(path, 0755)
    212 
    213     return path
    214 
    215   def RunWhich(self, *args):
    216     paths = os.pathsep.join(os.path.join(self.tempdir, p)
    217                             for p in self.path_list)
    218     env = {'PATH': paths}
    219     return RunCmd('which', list(args), cwd=self.tempdir, env=env)
    220 
    221   def testNothing(self):
    222     self.assertRaises(RunError, self.RunWhich, 'foo')
    223 
    224   def testBasic(self):
    225     self.Mkdir('bin')
    226     bin_cp = self.MakeExecutableFile('bin', 'cp')
    227     cp = os.path.basename(bin_cp)
    228 
    229     self.path_list.append('bin')
    230     output, _ = self.RunWhich(cp)
    231     self.assertTrue(os.path.join(self.tempdir, 'bin', cp) in output)
    232 
    233   def testMulti(self):
    234     self.Mkdir('bin')
    235     bin_cp = self.MakeExecutableFile('bin', 'cp')
    236     bin_ls = self.MakeExecutableFile('bin', 'ls')
    237     cp = os.path.basename(bin_cp)
    238     ls = os.path.basename(bin_ls)
    239 
    240     self.path_list.append('bin')
    241     output, _ = self.RunWhich(cp, ls)
    242     self.assertTrue(os.path.join(self.tempdir, 'bin', cp) in output)
    243     self.assertTrue(os.path.join(self.tempdir, 'bin', ls) in output)
    244 
    245   def testNonPath(self):
    246     self.Mkdir('bin')
    247     bin_cp = self.MakeExecutableFile('bin', 'cp')
    248     cp = os.path.basename(bin_cp)
    249 
    250     # Note, "bin" not added to PATH.
    251     output, _ = self.RunWhich(bin_cp)
    252     self.assertTrue(os.path.join('bin', cp) in output)
    253 
    254 
    255 if __name__ == '__main__':
    256   unittest.main()
    257