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()