|
1 import unittest |
|
2 |
|
3 import os, sys, os.path, time |
|
4 from tempfile import mkdtemp |
|
5 from shutil import rmtree |
|
6 import mozunit |
|
7 from mozprocess import processhandler |
|
8 |
|
9 from nsinstall import nsinstall |
|
10 import nsinstall as nsinstall_module |
|
11 NSINSTALL_PATH = nsinstall_module.__file__ |
|
12 |
|
13 # Run the non-ASCII tests on (a) Windows, or (b) any platform with |
|
14 # sys.stdin.encoding set to UTF-8 |
|
15 import codecs |
|
16 RUN_NON_ASCII_TESTS = (sys.platform == "win32" or |
|
17 (sys.stdin.encoding is not None and |
|
18 codecs.lookup(sys.stdin.encoding) == codecs.lookup("utf-8"))) |
|
19 |
|
20 class TestNsinstall(unittest.TestCase): |
|
21 """ |
|
22 Unit tests for nsinstall.py |
|
23 """ |
|
24 def setUp(self): |
|
25 self.tmpdir = mkdtemp() |
|
26 |
|
27 def tearDown(self): |
|
28 # Unicode strings means non-ASCII children can be deleted properly on |
|
29 # Windows |
|
30 if sys.stdin.encoding is None: |
|
31 tmpdir = unicode(self.tmpdir) |
|
32 else: |
|
33 tmpdir = unicode(self.tmpdir, sys.stdin.encoding) |
|
34 rmtree(tmpdir) |
|
35 |
|
36 # utility methods for tests |
|
37 def touch(self, file, dir=None): |
|
38 if dir is None: |
|
39 dir = self.tmpdir |
|
40 f = os.path.join(dir, file) |
|
41 open(f, 'w').close() |
|
42 return f |
|
43 |
|
44 def mkdirs(self, dir): |
|
45 d = os.path.join(self.tmpdir, dir) |
|
46 os.makedirs(d) |
|
47 return d |
|
48 |
|
49 def test_nsinstall_D(self): |
|
50 "Test nsinstall -D <dir>" |
|
51 testdir = os.path.join(self.tmpdir, "test") |
|
52 self.assertEqual(nsinstall(["-D", testdir]), 0) |
|
53 self.assert_(os.path.isdir(testdir)) |
|
54 |
|
55 def test_nsinstall_basic(self): |
|
56 "Test nsinstall <file> <dir>" |
|
57 testfile = self.touch("testfile") |
|
58 testdir = self.mkdirs("testdir") |
|
59 self.assertEqual(nsinstall([testfile, testdir]), 0) |
|
60 self.assert_(os.path.isfile(os.path.join(testdir, "testfile"))) |
|
61 |
|
62 def test_nsinstall_basic_recursive(self): |
|
63 "Test nsinstall <dir> <dest dir>" |
|
64 sourcedir = self.mkdirs("sourcedir") |
|
65 self.touch("testfile", sourcedir) |
|
66 Xfile = self.touch("Xfile", sourcedir) |
|
67 copieddir = self.mkdirs("sourcedir/copieddir") |
|
68 self.touch("testfile2", copieddir) |
|
69 Xdir = self.mkdirs("sourcedir/Xdir") |
|
70 self.touch("testfile3", Xdir) |
|
71 |
|
72 destdir = self.mkdirs("destdir") |
|
73 |
|
74 self.assertEqual(nsinstall([sourcedir, destdir, |
|
75 '-X', Xfile, |
|
76 '-X', Xdir]), 0) |
|
77 |
|
78 testdir = os.path.join(destdir, "sourcedir") |
|
79 self.assert_(os.path.isdir(testdir)) |
|
80 self.assert_(os.path.isfile(os.path.join(testdir, "testfile"))) |
|
81 self.assert_(not os.path.exists(os.path.join(testdir, "Xfile"))) |
|
82 self.assert_(os.path.isdir(os.path.join(testdir, "copieddir"))) |
|
83 self.assert_(os.path.isfile(os.path.join(testdir, "copieddir", "testfile2"))) |
|
84 self.assert_(not os.path.exists(os.path.join(testdir, "Xdir"))) |
|
85 |
|
86 def test_nsinstall_multiple(self): |
|
87 "Test nsinstall <three files> <dest dir>" |
|
88 testfiles = [self.touch("testfile1"), |
|
89 self.touch("testfile2"), |
|
90 self.touch("testfile3")] |
|
91 testdir = self.mkdirs("testdir") |
|
92 self.assertEqual(nsinstall(testfiles + [testdir]), 0) |
|
93 for f in testfiles: |
|
94 self.assert_(os.path.isfile(os.path.join(testdir, |
|
95 os.path.basename(f)))) |
|
96 |
|
97 def test_nsinstall_dir_exists(self): |
|
98 "Test nsinstall <dir> <dest dir>, where <dest dir>/<dir> already exists" |
|
99 srcdir = self.mkdirs("test") |
|
100 destdir = self.mkdirs("testdir/test") |
|
101 self.assertEqual(nsinstall([srcdir, os.path.dirname(destdir)]), 0) |
|
102 self.assert_(os.path.isdir(destdir)) |
|
103 |
|
104 def test_nsinstall_t(self): |
|
105 "Test that nsinstall -t works (preserve timestamp)" |
|
106 testfile = self.touch("testfile") |
|
107 testdir = self.mkdirs("testdir") |
|
108 # set mtime to now - 30 seconds |
|
109 t = int(time.time()) - 30 |
|
110 os.utime(testfile, (t, t)) |
|
111 self.assertEqual(nsinstall(["-t", testfile, testdir]), 0) |
|
112 destfile = os.path.join(testdir, "testfile") |
|
113 self.assert_(os.path.isfile(destfile)) |
|
114 self.assertEqual(os.stat(testfile).st_mtime, |
|
115 os.stat(destfile).st_mtime) |
|
116 |
|
117 if sys.platform != "win32": |
|
118 # can't run this test on windows, don't have real file modes there |
|
119 def test_nsinstall_m(self): |
|
120 "Test that nsinstall -m works (set mode)" |
|
121 testfile = self.touch("testfile") |
|
122 mode = 0600 |
|
123 os.chmod(testfile, mode) |
|
124 testdir = self.mkdirs("testdir") |
|
125 self.assertEqual(nsinstall(["-m", "{0:04o}" |
|
126 .format(mode), testfile, testdir]), 0) |
|
127 destfile = os.path.join(testdir, "testfile") |
|
128 self.assert_(os.path.isfile(destfile)) |
|
129 self.assertEqual(os.stat(testfile).st_mode, |
|
130 os.stat(destfile).st_mode) |
|
131 |
|
132 def test_nsinstall_d(self): |
|
133 "Test that nsinstall -d works (create directories in target)" |
|
134 # -d makes no sense to me, but ok! |
|
135 testfile = self.touch("testfile") |
|
136 testdir = self.mkdirs("testdir") |
|
137 destdir = os.path.join(testdir, "subdir") |
|
138 self.assertEqual(nsinstall(["-d", testfile, destdir]), 0) |
|
139 self.assert_(os.path.isdir(os.path.join(destdir, "testfile"))) |
|
140 |
|
141 if RUN_NON_ASCII_TESTS: |
|
142 def test_nsinstall_non_ascii(self): |
|
143 "Test that nsinstall handles non-ASCII files" |
|
144 filename = u"\u2325\u3452\u2415\u5081" |
|
145 testfile = self.touch(filename) |
|
146 testdir = self.mkdirs(u"\u4241\u1D04\u1414") |
|
147 self.assertEqual(nsinstall([testfile.encode("utf-8"), |
|
148 testdir.encode("utf-8")]), 0) |
|
149 |
|
150 destfile = os.path.join(testdir, filename) |
|
151 self.assert_(os.path.isfile(destfile)) |
|
152 |
|
153 def test_nsinstall_non_ascii_subprocess(self): |
|
154 "Test that nsinstall as a subprocess handles non-ASCII files" |
|
155 filename = u"\u2325\u3452\u2415\u5081" |
|
156 testfile = self.touch(filename) |
|
157 testdir = self.mkdirs(u"\u4241\u1D04\u1414") |
|
158 # We don't use subprocess because it can't handle Unicode on |
|
159 # Windows <http://bugs.python.org/issue1759845>. mozprocess calls |
|
160 # CreateProcessW directly so it's perfect. |
|
161 p = processhandler.ProcessHandlerMixin([sys.executable, |
|
162 NSINSTALL_PATH, |
|
163 testfile, testdir]) |
|
164 p.run() |
|
165 rv = p.waitForFinish() |
|
166 |
|
167 self.assertEqual(rv, 0) |
|
168 destfile = os.path.join(testdir, filename) |
|
169 self.assert_(os.path.isfile(destfile)) |
|
170 |
|
171 #TODO: implement -R, -l, -L and test them! |
|
172 |
|
173 if __name__ == '__main__': |
|
174 mozunit.main() |