oshelpers_test.py revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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
6import os
7import shutil
8import subprocess
9import sys
10import tempfile
11import unittest
12import zipfile
13
14SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
15PARENT_DIR = os.path.dirname(SCRIPT_DIR)
16
17sys.path.append(PARENT_DIR)
18
19import oshelpers
20
21class 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
34def 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
50class 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
86  def testNothingToDo(self):
87    self.assertRaises(subprocess.CalledProcessError, self.RunZip,
88        self.zipname, 'nonexistent_file')
89    self.assertFalse(os.path.exists(self.zipname))
90
91  def testAddSomeFiles(self):
92    file1 = self.MakeFile('file1', 1024)
93    file2 = self.MakeFile('file2', 3354)
94    self.RunZip(self.zipname, file1, file2)
95    self.OpenZipFile()
96    self.assertEqual(len(self.zipfile.namelist()), 2)
97    self.assertEqual(self.GetZipInfo(file1).file_size, 1024)
98    self.assertEqual(self.GetZipInfo(file2).file_size, 3354)
99    # make sure files are added in order
100    self.assertEqual(self.zipfile.namelist()[0], file1)
101
102  def testAddFilesWithGlob(self):
103    self.MakeFile('file1', 1024)
104    self.MakeFile('file2', 3354)
105    self.RunZip(self.zipname, 'file*')
106    self.OpenZipFile()
107    self.assertEqual(len(self.zipfile.namelist()), 2)
108
109  def testAddDir(self):
110    os.mkdir(self.GetTempPath('dir1'))
111    self.RunZip(self.zipname, 'dir1')
112    self.OpenZipFile()
113    self.assertEqual(len(self.zipfile.namelist()), 1)
114    self.assertRaises(KeyError, self.zipfile.getinfo, 'dir1')
115    self.zipfile.getinfo('dir1/')
116
117  def testAddRecursive(self):
118    os.mkdir(self.GetTempPath('dir1'))
119    self.MakeFile(os.path.join('dir1', 'file1'), 256)
120    os.mkdir(self.GetTempPath(os.path.join('dir1', 'dir2')))
121    self.MakeFile(os.path.join('dir1', 'dir2', 'file2'), 1234)
122    self.RunZip(self.zipname, '-r', 'dir1')
123    self.OpenZipFile()
124    self.assertEqual(len(self.zipfile.namelist()), 4)
125
126  def testUpdate(self):
127    file1 = self.MakeFile('file1', 1223)
128    self.RunZip(self.zipname, file1)
129    self.OpenZipFile()
130    self.assertEqual(self.GetZipInfo(file1).file_size, 1223)
131
132    file1 = self.MakeFile('file1', 2334)
133    self.RunZip(self.zipname, file1)
134    self.OpenZipFile()
135    self.assertEqual(len(self.zipfile.namelist()), 1)
136    self.assertEqual(self.GetZipInfo(file1).file_size, 2334)
137
138  def testUpdateOneFileOutOfMany(self):
139    file1 = self.MakeFile('file1', 128)
140    file2 = self.MakeFile('file2', 256)
141    file3 = self.MakeFile('file3', 512)
142    file4 = self.MakeFile('file4', 1024)
143    self.RunZip(self.zipname, file1, file2, file3, file4)
144    self.OpenZipFile()
145    self.assertEqual(len(self.zipfile.namelist()), 4)
146    self.CloseZipFile()
147
148    file3 = self.MakeFile('file3', 768)
149    self.RunZip(self.zipname, file3)
150    self.OpenZipFile()
151    self.assertEqual(len(self.zipfile.namelist()), 4)
152    self.assertEqual(self.zipfile.namelist()[0], file1)
153    self.assertEqual(self.GetZipInfo(file1).file_size, 128)
154    self.assertEqual(self.zipfile.namelist()[1], file2)
155    self.assertEqual(self.GetZipInfo(file2).file_size, 256)
156    self.assertEqual(self.zipfile.namelist()[2], file3)
157    self.assertEqual(self.GetZipInfo(file3).file_size, 768)
158    self.assertEqual(self.zipfile.namelist()[3], file4)
159    self.assertEqual(self.GetZipInfo(file4).file_size, 1024)
160
161  def testUpdateSubdirectory(self):
162    os.mkdir(self.GetTempPath('dir1'))
163    file1 = self.MakeFile(os.path.join('dir1', 'file1'), 256)
164    os.mkdir(self.GetTempPath(os.path.join('dir1', 'dir2')))
165    self.MakeFile(os.path.join('dir1', 'dir2', 'file2'), 1234)
166    self.RunZip(self.zipname, '-r', 'dir1')
167    self.OpenZipFile()
168    self.assertEqual(len(self.zipfile.namelist()), 4)
169    self.assertEqual(self.GetZipInfo(file1).file_size, 256)
170    self.CloseZipFile()
171
172    self.MakeFile(file1, 2560)
173    self.RunZip(self.zipname, file1)
174    self.OpenZipFile()
175    self.assertEqual(len(self.zipfile.namelist()), 4)
176    self.assertEqual(self.GetZipInfo(file1).file_size, 2560)
177
178  def testAppend(self):
179    file1 = self.MakeFile('file1', 128)
180    file2 = self.MakeFile('file2', 256)
181    self.RunZip(self.zipname, file1, file2)
182    self.OpenZipFile()
183    self.assertEqual(len(self.zipfile.namelist()), 2)
184    self.CloseZipFile()
185
186    file3 = self.MakeFile('file3', 768)
187    self.RunZip(self.zipname, file3)
188    self.OpenZipFile()
189    self.assertEqual(len(self.zipfile.namelist()), 3)
190
191
192class TestWhich(unittest.TestCase):
193  def setUp(self):
194    self.path_list = []
195    self.tempdir = tempfile.mkdtemp()
196    shutil.copy(os.path.join(PARENT_DIR, 'oshelpers.py'),
197        self.tempdir)
198
199  def tearDown(self):
200    shutil.rmtree(self.tempdir)
201
202  def Mkdir(self, path):
203    os.mkdir(os.path.join(self.tempdir, path))
204
205  def MakeExecutableFile(self, *path_components):
206    path = os.path.join(self.tempdir, *path_components)
207    if sys.platform == 'win32':
208      path += '.exe'
209
210    with open(path, 'w') as f:
211      f.write('')
212    os.chmod(path, 0755)
213
214    return path
215
216  def RunWhich(self, *args):
217    paths = os.pathsep.join(os.path.join(self.tempdir, p)
218                            for p in self.path_list)
219    env = {'PATH': paths}
220    return RunCmd('which', list(args), cwd=self.tempdir, env=env)
221
222  def testNothing(self):
223    self.assertRaises(RunError, self.RunWhich, 'foo')
224
225  def testBasic(self):
226    self.Mkdir('bin')
227    bin_cp = self.MakeExecutableFile('bin', 'cp')
228    cp = os.path.basename(bin_cp)
229
230    self.path_list.append('bin')
231    output, _ = self.RunWhich(cp)
232    self.assertTrue(os.path.join(self.tempdir, 'bin', cp) in output)
233
234  def testMulti(self):
235    self.Mkdir('bin')
236    bin_cp = self.MakeExecutableFile('bin', 'cp')
237    bin_ls = self.MakeExecutableFile('bin', 'ls')
238    cp = os.path.basename(bin_cp)
239    ls = os.path.basename(bin_ls)
240
241    self.path_list.append('bin')
242    output, _ = self.RunWhich(cp, ls)
243    self.assertTrue(os.path.join(self.tempdir, 'bin', cp) in output)
244    self.assertTrue(os.path.join(self.tempdir, 'bin', ls) in output)
245
246  def testNonPath(self):
247    self.Mkdir('bin')
248    bin_cp = self.MakeExecutableFile('bin', 'cp')
249    cp = os.path.basename(bin_cp)
250
251    # Note, "bin" not added to PATH.
252    output, _ = self.RunWhich(bin_cp)
253    self.assertTrue(os.path.join('bin', cp) in output)
254
255
256if __name__ == '__main__':
257  unittest.main()
258