1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/addon-sdk/source/python-lib/cuddlefish/tests/test_linker.py Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,231 @@ 1.4 +# This Source Code Form is subject to the terms of the Mozilla Public 1.5 +# License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 +# file, You can obtain one at http://mozilla.org/MPL/2.0/. 1.7 + 1.8 +import os.path 1.9 +import shutil 1.10 +import zipfile 1.11 +from StringIO import StringIO 1.12 +import simplejson as json 1.13 +import unittest 1.14 +import cuddlefish 1.15 +from cuddlefish import packaging, manifest 1.16 + 1.17 +def up(path, generations=1): 1.18 + for i in range(generations): 1.19 + path = os.path.dirname(path) 1.20 + return path 1.21 + 1.22 +ROOT = up(os.path.abspath(__file__), 4) 1.23 +def get_linker_files_dir(name): 1.24 + return os.path.join(up(os.path.abspath(__file__)), "linker-files", name) 1.25 + 1.26 +class Basic(unittest.TestCase): 1.27 + def get_pkg(self, name): 1.28 + d = get_linker_files_dir(name) 1.29 + return packaging.get_config_in_dir(d) 1.30 + 1.31 + def test_deps(self): 1.32 + target_cfg = self.get_pkg("one") 1.33 + pkg_cfg = packaging.build_config(ROOT, target_cfg) 1.34 + deps = packaging.get_deps_for_targets(pkg_cfg, ["one"]) 1.35 + self.failUnlessEqual(deps, ["one"]) 1.36 + deps = packaging.get_deps_for_targets(pkg_cfg, 1.37 + [target_cfg.name, "addon-sdk"]) 1.38 + self.failUnlessEqual(deps, ["addon-sdk", "one"]) 1.39 + 1.40 + def test_manifest(self): 1.41 + target_cfg = self.get_pkg("one") 1.42 + pkg_cfg = packaging.build_config(ROOT, target_cfg) 1.43 + deps = packaging.get_deps_for_targets(pkg_cfg, 1.44 + [target_cfg.name, "addon-sdk"]) 1.45 + self.failUnlessEqual(deps, ["addon-sdk", "one"]) 1.46 + # target_cfg.dependencies is not provided, so we'll search through 1.47 + # all known packages (everything in 'deps'). 1.48 + m = manifest.build_manifest(target_cfg, pkg_cfg, deps, scan_tests=False) 1.49 + m = m.get_harness_options_manifest(False) 1.50 + 1.51 + def assertReqIs(modname, reqname, path): 1.52 + reqs = m["one/%s" % modname]["requirements"] 1.53 + self.failUnlessEqual(reqs[reqname], path) 1.54 + assertReqIs("main", "sdk/panel", "sdk/panel") 1.55 + assertReqIs("main", "two.js", "one/two") 1.56 + assertReqIs("main", "./two", "one/two") 1.57 + assertReqIs("main", "sdk/tabs.js", "sdk/tabs") 1.58 + assertReqIs("main", "./subdir/three", "one/subdir/three") 1.59 + assertReqIs("two", "main", "one/main") 1.60 + assertReqIs("subdir/three", "../main", "one/main") 1.61 + 1.62 + target_cfg.dependencies = [] 1.63 + # now, because .dependencies *is* provided, we won't search 'deps', 1.64 + # so we'll get a link error 1.65 + self.assertRaises(manifest.ModuleNotFoundError, 1.66 + manifest.build_manifest, 1.67 + target_cfg, pkg_cfg, deps, scan_tests=False) 1.68 + 1.69 + def test_main_in_deps(self): 1.70 + target_cfg = self.get_pkg("three") 1.71 + package_path = [get_linker_files_dir("three-deps")] 1.72 + pkg_cfg = packaging.build_config(ROOT, target_cfg, 1.73 + packagepath=package_path) 1.74 + deps = packaging.get_deps_for_targets(pkg_cfg, 1.75 + [target_cfg.name, "addon-sdk"]) 1.76 + self.failUnlessEqual(deps, ["addon-sdk", "three"]) 1.77 + m = manifest.build_manifest(target_cfg, pkg_cfg, deps, scan_tests=False) 1.78 + m = m.get_harness_options_manifest(False) 1.79 + def assertReqIs(modname, reqname, path): 1.80 + reqs = m["three/%s" % modname]["requirements"] 1.81 + self.failUnlessEqual(reqs[reqname], path) 1.82 + assertReqIs("main", "three-a", "three-a/main") 1.83 + assertReqIs("main", "three-b", "three-b/main") 1.84 + assertReqIs("main", "three-c", "three-c/main") 1.85 + 1.86 + def test_relative_main_in_top(self): 1.87 + target_cfg = self.get_pkg("five") 1.88 + package_path = [] 1.89 + pkg_cfg = packaging.build_config(ROOT, target_cfg, 1.90 + packagepath=package_path) 1.91 + deps = packaging.get_deps_for_targets(pkg_cfg, 1.92 + [target_cfg.name, "addon-sdk"]) 1.93 + self.failUnlessEqual(deps, ["addon-sdk", "five"]) 1.94 + # all we care about is that this next call doesn't raise an exception 1.95 + m = manifest.build_manifest(target_cfg, pkg_cfg, deps, scan_tests=False) 1.96 + m = m.get_harness_options_manifest(False) 1.97 + reqs = m["five/main"]["requirements"] 1.98 + self.failUnlessEqual(reqs, {}); 1.99 + 1.100 + def test_unreachable_relative_main_in_top(self): 1.101 + target_cfg = self.get_pkg("six") 1.102 + package_path = [] 1.103 + pkg_cfg = packaging.build_config(ROOT, target_cfg, 1.104 + packagepath=package_path) 1.105 + deps = packaging.get_deps_for_targets(pkg_cfg, 1.106 + [target_cfg.name, "addon-sdk"]) 1.107 + self.failUnlessEqual(deps, ["addon-sdk", "six"]) 1.108 + self.assertRaises(manifest.UnreachablePrefixError, 1.109 + manifest.build_manifest, 1.110 + target_cfg, pkg_cfg, deps, scan_tests=False) 1.111 + 1.112 + def test_unreachable_in_deps(self): 1.113 + target_cfg = self.get_pkg("four") 1.114 + package_path = [get_linker_files_dir("four-deps")] 1.115 + pkg_cfg = packaging.build_config(ROOT, target_cfg, 1.116 + packagepath=package_path) 1.117 + deps = packaging.get_deps_for_targets(pkg_cfg, 1.118 + [target_cfg.name, "addon-sdk"]) 1.119 + self.failUnlessEqual(deps, ["addon-sdk", "four"]) 1.120 + self.assertRaises(manifest.UnreachablePrefixError, 1.121 + manifest.build_manifest, 1.122 + target_cfg, pkg_cfg, deps, scan_tests=False) 1.123 + 1.124 +class Contents(unittest.TestCase): 1.125 + 1.126 + def run_in_subdir(self, dirname, f, *args, **kwargs): 1.127 + top = os.path.abspath(os.getcwd()) 1.128 + basedir = os.path.abspath(os.path.join(".test_tmp",self.id(),dirname)) 1.129 + if os.path.isdir(basedir): 1.130 + assert basedir.startswith(top) 1.131 + shutil.rmtree(basedir) 1.132 + os.makedirs(basedir) 1.133 + try: 1.134 + os.chdir(basedir) 1.135 + return f(basedir, *args, **kwargs) 1.136 + finally: 1.137 + os.chdir(top) 1.138 + 1.139 + def assertIn(self, what, inside_what): 1.140 + self.failUnless(what in inside_what, inside_what) 1.141 + 1.142 + def test_jetpackID(self): 1.143 + # this uses "id": "jid7", to which a @jetpack should be appended 1.144 + seven = get_linker_files_dir("seven") 1.145 + def _test(basedir): 1.146 + stdout = StringIO() 1.147 + shutil.copytree(seven, "seven") 1.148 + os.chdir("seven") 1.149 + try: 1.150 + # regrettably, run() always finishes with sys.exit() 1.151 + cuddlefish.run(["xpi", "--no-strip-xpi"], 1.152 + stdout=stdout) 1.153 + except SystemExit, e: 1.154 + self.failUnlessEqual(e.args[0], 0) 1.155 + zf = zipfile.ZipFile("seven.xpi", "r") 1.156 + hopts = json.loads(zf.read("harness-options.json")) 1.157 + self.failUnlessEqual(hopts["jetpackID"], "jid7@jetpack") 1.158 + self.run_in_subdir("x", _test) 1.159 + 1.160 + def test_jetpackID_suffix(self): 1.161 + # this uses "id": "jid1@jetpack", so no suffix should be appended 1.162 + one = get_linker_files_dir("one") 1.163 + def _test(basedir): 1.164 + stdout = StringIO() 1.165 + shutil.copytree(one, "one") 1.166 + os.chdir("one") 1.167 + try: 1.168 + # regrettably, run() always finishes with sys.exit() 1.169 + cuddlefish.run(["xpi", "--no-strip-xpi"], 1.170 + stdout=stdout) 1.171 + except SystemExit, e: 1.172 + self.failUnlessEqual(e.args[0], 0) 1.173 + zf = zipfile.ZipFile("one.xpi", "r") 1.174 + hopts = json.loads(zf.read("harness-options.json")) 1.175 + self.failUnlessEqual(hopts["jetpackID"], "jid1@jetpack") 1.176 + self.run_in_subdir("x", _test) 1.177 + 1.178 + def test_strip_default(self): 1.179 + seven = get_linker_files_dir("seven") 1.180 + # now run 'cfx xpi' in that directory, except put the generated .xpi 1.181 + # elsewhere 1.182 + def _test(basedir): 1.183 + stdout = StringIO() 1.184 + shutil.copytree(seven, "seven") 1.185 + os.chdir("seven") 1.186 + try: 1.187 + # regrettably, run() always finishes with sys.exit() 1.188 + cuddlefish.run(["xpi"], # --strip-xpi is now the default 1.189 + stdout=stdout) 1.190 + except SystemExit, e: 1.191 + self.failUnlessEqual(e.args[0], 0) 1.192 + zf = zipfile.ZipFile("seven.xpi", "r") 1.193 + names = zf.namelist() 1.194 + # problem found in bug 664840 was that an addon 1.195 + # without an explicit tests/ directory would copy all files from 1.196 + # the package into a bogus JID-PKGNAME-tests/ directory, so check 1.197 + # for that 1.198 + testfiles = [fn for fn in names if "seven/tests" in fn] 1.199 + self.failUnlessEqual([], testfiles) 1.200 + # another problem was that data files were being stripped from 1.201 + # the XPI. Note that data/ is only supposed to be included if a 1.202 + # module that actually gets used does a require("self") . 1.203 + self.assertIn("resources/seven/data/text.data", 1.204 + names) 1.205 + self.failIf("seven/lib/unused.js" 1.206 + in names, names) 1.207 + self.run_in_subdir("x", _test) 1.208 + 1.209 + def test_no_strip(self): 1.210 + seven = get_linker_files_dir("seven") 1.211 + def _test(basedir): 1.212 + stdout = StringIO() 1.213 + shutil.copytree(seven, "seven") 1.214 + os.chdir("seven") 1.215 + try: 1.216 + # regrettably, run() always finishes with sys.exit() 1.217 + cuddlefish.run(["xpi", "--no-strip-xpi"], 1.218 + stdout=stdout) 1.219 + except SystemExit, e: 1.220 + self.failUnlessEqual(e.args[0], 0) 1.221 + zf = zipfile.ZipFile("seven.xpi", "r") 1.222 + names = zf.namelist() 1.223 + self.assertIn("resources/addon-sdk/lib/sdk/loader/cuddlefish.js", names) 1.224 + testfiles = [fn for fn in names if "seven/tests" in fn] 1.225 + self.failUnlessEqual([], testfiles) 1.226 + self.assertIn("resources/seven/data/text.data", 1.227 + names) 1.228 + self.failUnless("resources/seven/lib/unused.js" 1.229 + in names, names) 1.230 + self.run_in_subdir("x", _test) 1.231 + 1.232 + 1.233 +if __name__ == '__main__': 1.234 + unittest.main()