diff options
Diffstat (limited to 'addon-sdk/source/python-lib/cuddlefish/tests/test_linker.py')
-rwxr-xr-x | addon-sdk/source/python-lib/cuddlefish/tests/test_linker.py | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/addon-sdk/source/python-lib/cuddlefish/tests/test_linker.py b/addon-sdk/source/python-lib/cuddlefish/tests/test_linker.py new file mode 100755 index 000000000..7a6fd12e4 --- /dev/null +++ b/addon-sdk/source/python-lib/cuddlefish/tests/test_linker.py @@ -0,0 +1,247 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +import os.path +import shutil +import zipfile +from StringIO import StringIO +import simplejson as json +import unittest +import cuddlefish +from cuddlefish import packaging, manifest + +def up(path, generations=1): + for i in range(generations): + path = os.path.dirname(path) + return path + +ROOT = up(os.path.abspath(__file__), 4) +def get_linker_files_dir(name): + return os.path.join(up(os.path.abspath(__file__)), "linker-files", name) + +class Basic(unittest.TestCase): + def get_pkg(self, name): + d = get_linker_files_dir(name) + return packaging.get_config_in_dir(d) + + def test_deps(self): + target_cfg = self.get_pkg("one") + pkg_cfg = packaging.build_config(ROOT, target_cfg) + deps = packaging.get_deps_for_targets(pkg_cfg, ["one"]) + self.failUnlessEqual(deps, ["one"]) + deps = packaging.get_deps_for_targets(pkg_cfg, + [target_cfg.name, "addon-sdk"]) + self.failUnlessEqual(deps, ["addon-sdk", "one"]) + + def test_manifest(self): + target_cfg = self.get_pkg("one") + pkg_cfg = packaging.build_config(ROOT, target_cfg) + deps = packaging.get_deps_for_targets(pkg_cfg, + [target_cfg.name, "addon-sdk"]) + self.failUnlessEqual(deps, ["addon-sdk", "one"]) + # target_cfg.dependencies is not provided, so we'll search through + # all known packages (everything in 'deps'). + m = manifest.build_manifest(target_cfg, pkg_cfg, deps, scan_tests=False) + m = m.get_harness_options_manifest(False) + + def assertReqIs(modname, reqname, path): + reqs = m["one/%s" % modname]["requirements"] + self.failUnlessEqual(reqs[reqname], path) + + assertReqIs("main", "sdk/panel", "sdk/panel") + assertReqIs("main", "two.js", "one/two") + assertReqIs("main", "./two", "one/two") + assertReqIs("main", "sdk/tabs.js", "sdk/tabs") + assertReqIs("main", "./subdir/three", "one/subdir/three") + assertReqIs("two", "main", "one/main") + assertReqIs("subdir/three", "../main", "one/main") + + target_cfg.dependencies = [] + + try: + # this should now work, as we ignore missing modules by default + m = manifest.build_manifest(target_cfg, pkg_cfg, deps, scan_tests=False) + m = m.get_harness_options_manifest(False) + + assertReqIs("main", "sdk/panel", "sdk/panel") + # note that with "addon-sdk" dependency present, + # "sdk/tabs.js" mapped to "sdk/tabs", but without, + # we just get the default (identity) mapping + assertReqIs("main", "sdk/tabs.js", "sdk/tabs.js") + except Exception, e: + self.fail("Must not throw from build_manifest() if modules are missing") + + # now, because .dependencies *is* provided, we won't search 'deps', + # and stop_on_missing is True, we'll get a link error + self.assertRaises(manifest.ModuleNotFoundError, + manifest.build_manifest, + target_cfg, pkg_cfg, deps, scan_tests=False, + abort_on_missing=True) + + def test_main_in_deps(self): + target_cfg = self.get_pkg("three") + package_path = [get_linker_files_dir("three-deps")] + pkg_cfg = packaging.build_config(ROOT, target_cfg, + packagepath=package_path) + deps = packaging.get_deps_for_targets(pkg_cfg, + [target_cfg.name, "addon-sdk"]) + self.failUnlessEqual(deps, ["addon-sdk", "three"]) + m = manifest.build_manifest(target_cfg, pkg_cfg, deps, scan_tests=False) + m = m.get_harness_options_manifest(False) + def assertReqIs(modname, reqname, path): + reqs = m["three/%s" % modname]["requirements"] + self.failUnlessEqual(reqs[reqname], path) + assertReqIs("main", "three-a", "three-a/main") + assertReqIs("main", "three-b", "three-b/main") + assertReqIs("main", "three-c", "three-c/main") + + def test_relative_main_in_top(self): + target_cfg = self.get_pkg("five") + package_path = [] + pkg_cfg = packaging.build_config(ROOT, target_cfg, + packagepath=package_path) + deps = packaging.get_deps_for_targets(pkg_cfg, + [target_cfg.name, "addon-sdk"]) + self.failUnlessEqual(deps, ["addon-sdk", "five"]) + # all we care about is that this next call doesn't raise an exception + m = manifest.build_manifest(target_cfg, pkg_cfg, deps, scan_tests=False) + m = m.get_harness_options_manifest(False) + reqs = m["five/main"]["requirements"] + self.failUnlessEqual(reqs, {}); + + def test_unreachable_relative_main_in_top(self): + target_cfg = self.get_pkg("six") + package_path = [] + pkg_cfg = packaging.build_config(ROOT, target_cfg, + packagepath=package_path) + deps = packaging.get_deps_for_targets(pkg_cfg, + [target_cfg.name, "addon-sdk"]) + self.failUnlessEqual(deps, ["addon-sdk", "six"]) + self.assertRaises(manifest.UnreachablePrefixError, + manifest.build_manifest, + target_cfg, pkg_cfg, deps, scan_tests=False) + + def test_unreachable_in_deps(self): + target_cfg = self.get_pkg("four") + package_path = [get_linker_files_dir("four-deps")] + pkg_cfg = packaging.build_config(ROOT, target_cfg, + packagepath=package_path) + deps = packaging.get_deps_for_targets(pkg_cfg, + [target_cfg.name, "addon-sdk"]) + self.failUnlessEqual(deps, ["addon-sdk", "four"]) + self.assertRaises(manifest.UnreachablePrefixError, + manifest.build_manifest, + target_cfg, pkg_cfg, deps, scan_tests=False) + +class Contents(unittest.TestCase): + + def run_in_subdir(self, dirname, f, *args, **kwargs): + top = os.path.abspath(os.getcwd()) + basedir = os.path.abspath(os.path.join(".test_tmp",self.id(),dirname)) + if os.path.isdir(basedir): + assert basedir.startswith(top) + shutil.rmtree(basedir) + os.makedirs(basedir) + try: + os.chdir(basedir) + return f(basedir, *args, **kwargs) + finally: + os.chdir(top) + + def assertIn(self, what, inside_what): + self.failUnless(what in inside_what, inside_what) + + def test_jetpackID(self): + # this uses "id": "jid7", to which a @jetpack should be appended + seven = get_linker_files_dir("seven") + def _test(basedir): + stdout = StringIO() + shutil.copytree(seven, "seven") + os.chdir("seven") + try: + # regrettably, run() always finishes with sys.exit() + cuddlefish.run(["xpi", "--no-strip-xpi"], + stdout=stdout) + except SystemExit, e: + self.failUnlessEqual(e.args[0], 0) + zf = zipfile.ZipFile("seven.xpi", "r") + hopts = json.loads(zf.read("harness-options.json")) + self.failUnlessEqual(hopts["jetpackID"], "jid7@jetpack") + self.run_in_subdir("x", _test) + + def test_jetpackID_suffix(self): + # this uses "id": "jid1@jetpack", so no suffix should be appended + one = get_linker_files_dir("one") + def _test(basedir): + stdout = StringIO() + shutil.copytree(one, "one") + os.chdir("one") + try: + # regrettably, run() always finishes with sys.exit() + cuddlefish.run(["xpi", "--no-strip-xpi"], + stdout=stdout) + except SystemExit, e: + self.failUnlessEqual(e.args[0], 0) + zf = zipfile.ZipFile("one.xpi", "r") + hopts = json.loads(zf.read("harness-options.json")) + self.failUnlessEqual(hopts["jetpackID"], "jid1@jetpack") + self.run_in_subdir("x", _test) + + def test_strip_default(self): + seven = get_linker_files_dir("seven") + # now run 'cfx xpi' in that directory, except put the generated .xpi + # elsewhere + def _test(basedir): + stdout = StringIO() + shutil.copytree(seven, "seven") + os.chdir("seven") + try: + # regrettably, run() always finishes with sys.exit() + cuddlefish.run(["xpi"], # --strip-xpi is now the default + stdout=stdout) + except SystemExit, e: + self.failUnlessEqual(e.args[0], 0) + zf = zipfile.ZipFile("seven.xpi", "r") + names = zf.namelist() + # problem found in bug 664840 was that an addon + # without an explicit tests/ directory would copy all files from + # the package into a bogus JID-PKGNAME-tests/ directory, so check + # for that + testfiles = [fn for fn in names if "seven/tests" in fn] + self.failUnlessEqual([], testfiles) + # another problem was that data files were being stripped from + # the XPI. Note that data/ is only supposed to be included if a + # module that actually gets used does a require("self") . + self.assertIn("resources/seven/data/text.data", + names) + self.failIf("seven/lib/unused.js" + in names, names) + self.run_in_subdir("x", _test) + + def test_no_strip(self): + seven = get_linker_files_dir("seven") + def _test(basedir): + stdout = StringIO() + shutil.copytree(seven, "seven") + os.chdir("seven") + try: + # regrettably, run() always finishes with sys.exit() + cuddlefish.run(["xpi", "--no-strip-xpi"], + stdout=stdout) + except SystemExit, e: + self.failUnlessEqual(e.args[0], 0) + zf = zipfile.ZipFile("seven.xpi", "r") + names = zf.namelist() + self.assertIn("resources/addon-sdk/lib/sdk/loader/cuddlefish.js", names) + testfiles = [fn for fn in names if "seven/tests" in fn] + self.failUnlessEqual([], testfiles) + self.assertIn("resources/seven/data/text.data", + names) + self.failUnless("resources/seven/lib/unused.js" + in names, names) + self.run_in_subdir("x", _test) + + +if __name__ == '__main__': + unittest.main() |