michael@0: import unittest michael@0: michael@0: import os, sys, os.path, time michael@0: from tempfile import mkdtemp michael@0: from shutil import rmtree michael@0: import mozunit michael@0: from mozprocess import processhandler michael@0: michael@0: from nsinstall import nsinstall michael@0: import nsinstall as nsinstall_module michael@0: NSINSTALL_PATH = nsinstall_module.__file__ michael@0: michael@0: # Run the non-ASCII tests on (a) Windows, or (b) any platform with michael@0: # sys.stdin.encoding set to UTF-8 michael@0: import codecs michael@0: RUN_NON_ASCII_TESTS = (sys.platform == "win32" or michael@0: (sys.stdin.encoding is not None and michael@0: codecs.lookup(sys.stdin.encoding) == codecs.lookup("utf-8"))) michael@0: michael@0: class TestNsinstall(unittest.TestCase): michael@0: """ michael@0: Unit tests for nsinstall.py michael@0: """ michael@0: def setUp(self): michael@0: self.tmpdir = mkdtemp() michael@0: michael@0: def tearDown(self): michael@0: # Unicode strings means non-ASCII children can be deleted properly on michael@0: # Windows michael@0: if sys.stdin.encoding is None: michael@0: tmpdir = unicode(self.tmpdir) michael@0: else: michael@0: tmpdir = unicode(self.tmpdir, sys.stdin.encoding) michael@0: rmtree(tmpdir) michael@0: michael@0: # utility methods for tests michael@0: def touch(self, file, dir=None): michael@0: if dir is None: michael@0: dir = self.tmpdir michael@0: f = os.path.join(dir, file) michael@0: open(f, 'w').close() michael@0: return f michael@0: michael@0: def mkdirs(self, dir): michael@0: d = os.path.join(self.tmpdir, dir) michael@0: os.makedirs(d) michael@0: return d michael@0: michael@0: def test_nsinstall_D(self): michael@0: "Test nsinstall -D " michael@0: testdir = os.path.join(self.tmpdir, "test") michael@0: self.assertEqual(nsinstall(["-D", testdir]), 0) michael@0: self.assert_(os.path.isdir(testdir)) michael@0: michael@0: def test_nsinstall_basic(self): michael@0: "Test nsinstall " michael@0: testfile = self.touch("testfile") michael@0: testdir = self.mkdirs("testdir") michael@0: self.assertEqual(nsinstall([testfile, testdir]), 0) michael@0: self.assert_(os.path.isfile(os.path.join(testdir, "testfile"))) michael@0: michael@0: def test_nsinstall_basic_recursive(self): michael@0: "Test nsinstall " michael@0: sourcedir = self.mkdirs("sourcedir") michael@0: self.touch("testfile", sourcedir) michael@0: Xfile = self.touch("Xfile", sourcedir) michael@0: copieddir = self.mkdirs("sourcedir/copieddir") michael@0: self.touch("testfile2", copieddir) michael@0: Xdir = self.mkdirs("sourcedir/Xdir") michael@0: self.touch("testfile3", Xdir) michael@0: michael@0: destdir = self.mkdirs("destdir") michael@0: michael@0: self.assertEqual(nsinstall([sourcedir, destdir, michael@0: '-X', Xfile, michael@0: '-X', Xdir]), 0) michael@0: michael@0: testdir = os.path.join(destdir, "sourcedir") michael@0: self.assert_(os.path.isdir(testdir)) michael@0: self.assert_(os.path.isfile(os.path.join(testdir, "testfile"))) michael@0: self.assert_(not os.path.exists(os.path.join(testdir, "Xfile"))) michael@0: self.assert_(os.path.isdir(os.path.join(testdir, "copieddir"))) michael@0: self.assert_(os.path.isfile(os.path.join(testdir, "copieddir", "testfile2"))) michael@0: self.assert_(not os.path.exists(os.path.join(testdir, "Xdir"))) michael@0: michael@0: def test_nsinstall_multiple(self): michael@0: "Test nsinstall " michael@0: testfiles = [self.touch("testfile1"), michael@0: self.touch("testfile2"), michael@0: self.touch("testfile3")] michael@0: testdir = self.mkdirs("testdir") michael@0: self.assertEqual(nsinstall(testfiles + [testdir]), 0) michael@0: for f in testfiles: michael@0: self.assert_(os.path.isfile(os.path.join(testdir, michael@0: os.path.basename(f)))) michael@0: michael@0: def test_nsinstall_dir_exists(self): michael@0: "Test nsinstall , where / already exists" michael@0: srcdir = self.mkdirs("test") michael@0: destdir = self.mkdirs("testdir/test") michael@0: self.assertEqual(nsinstall([srcdir, os.path.dirname(destdir)]), 0) michael@0: self.assert_(os.path.isdir(destdir)) michael@0: michael@0: def test_nsinstall_t(self): michael@0: "Test that nsinstall -t works (preserve timestamp)" michael@0: testfile = self.touch("testfile") michael@0: testdir = self.mkdirs("testdir") michael@0: # set mtime to now - 30 seconds michael@0: t = int(time.time()) - 30 michael@0: os.utime(testfile, (t, t)) michael@0: self.assertEqual(nsinstall(["-t", testfile, testdir]), 0) michael@0: destfile = os.path.join(testdir, "testfile") michael@0: self.assert_(os.path.isfile(destfile)) michael@0: self.assertEqual(os.stat(testfile).st_mtime, michael@0: os.stat(destfile).st_mtime) michael@0: michael@0: if sys.platform != "win32": michael@0: # can't run this test on windows, don't have real file modes there michael@0: def test_nsinstall_m(self): michael@0: "Test that nsinstall -m works (set mode)" michael@0: testfile = self.touch("testfile") michael@0: mode = 0600 michael@0: os.chmod(testfile, mode) michael@0: testdir = self.mkdirs("testdir") michael@0: self.assertEqual(nsinstall(["-m", "{0:04o}" michael@0: .format(mode), testfile, testdir]), 0) michael@0: destfile = os.path.join(testdir, "testfile") michael@0: self.assert_(os.path.isfile(destfile)) michael@0: self.assertEqual(os.stat(testfile).st_mode, michael@0: os.stat(destfile).st_mode) michael@0: michael@0: def test_nsinstall_d(self): michael@0: "Test that nsinstall -d works (create directories in target)" michael@0: # -d makes no sense to me, but ok! michael@0: testfile = self.touch("testfile") michael@0: testdir = self.mkdirs("testdir") michael@0: destdir = os.path.join(testdir, "subdir") michael@0: self.assertEqual(nsinstall(["-d", testfile, destdir]), 0) michael@0: self.assert_(os.path.isdir(os.path.join(destdir, "testfile"))) michael@0: michael@0: if RUN_NON_ASCII_TESTS: michael@0: def test_nsinstall_non_ascii(self): michael@0: "Test that nsinstall handles non-ASCII files" michael@0: filename = u"\u2325\u3452\u2415\u5081" michael@0: testfile = self.touch(filename) michael@0: testdir = self.mkdirs(u"\u4241\u1D04\u1414") michael@0: self.assertEqual(nsinstall([testfile.encode("utf-8"), michael@0: testdir.encode("utf-8")]), 0) michael@0: michael@0: destfile = os.path.join(testdir, filename) michael@0: self.assert_(os.path.isfile(destfile)) michael@0: michael@0: def test_nsinstall_non_ascii_subprocess(self): michael@0: "Test that nsinstall as a subprocess handles non-ASCII files" michael@0: filename = u"\u2325\u3452\u2415\u5081" michael@0: testfile = self.touch(filename) michael@0: testdir = self.mkdirs(u"\u4241\u1D04\u1414") michael@0: # We don't use subprocess because it can't handle Unicode on michael@0: # Windows . mozprocess calls michael@0: # CreateProcessW directly so it's perfect. michael@0: p = processhandler.ProcessHandlerMixin([sys.executable, michael@0: NSINSTALL_PATH, michael@0: testfile, testdir]) michael@0: p.run() michael@0: rv = p.waitForFinish() michael@0: michael@0: self.assertEqual(rv, 0) michael@0: destfile = os.path.join(testdir, filename) michael@0: self.assert_(os.path.isfile(destfile)) michael@0: michael@0: #TODO: implement -R, -l, -L and test them! michael@0: michael@0: if __name__ == '__main__': michael@0: mozunit.main()