def run(argv): parser = OptionParser("%prog pkgdir [options] {PACKAGE-NAME|PATH}") parser.add_option( "--root", metavar="PATH", help="look for additional packages in PATH") parser.add_option( "--user", metavar="USER", help="look up PACKAGE-NAME for USER (if you have permission; " "default: current user)") options, args = parser.parse_args(argv) if len(args) < 1: parser.error("need package name") try: if "/" in args[0]: print(Click.find_package_directory(args[0])) else: db = Click.DB() db.read(db_dir=None) if options.root is not None: db.add(options.root) package_name = args[0] registry = Click.User.for_user(db, name=options.user) print(registry.get_path(package_name)) except Exception as e: print(e, file=sys.stderr) return 1 return 0
def test_find_package_directory(self): info = os.path.join(self.temp_dir, ".click", "info") path = os.path.join(self.temp_dir, "file") Click.ensuredir(info) touch(path) pkgdir = Click.find_package_directory(path) self.assertEqual(self.temp_dir, pkgdir)
def _create_mock_framework_dir(self, frameworks_dir=None): if frameworks_dir is None: frameworks_dir = os.path.join(self.temp_dir, "frameworks") patcher = mock.patch('click_package.paths.frameworks_dir', frameworks_dir) patcher.start() self.addCleanup(patcher.stop) Click.ensuredir(frameworks_dir) return frameworks_dir
def test_get_frameworks_ignores_other_files(self): with self.run_in_subprocess("click_get_frameworks_dir") as (enter, preloads): enter() frameworks_dir = os.path.join(self.temp_dir, "frameworks") Click.ensuredir(frameworks_dir) touch(os.path.join(frameworks_dir, "file")) preloads["click_get_frameworks_dir"].side_effect = ( lambda: self.make_string(frameworks_dir)) self.assertEqual([], Click.Framework.get_frameworks())
def test_get_frameworks_ignores_unopenable_files(self): with self.run_in_subprocess("click_get_frameworks_dir") as (enter, preloads): enter() frameworks_dir = os.path.join(self.temp_dir, "frameworks") Click.ensuredir(frameworks_dir) os.symlink("nonexistent", os.path.join(frameworks_dir, "foo.framework")) preloads["click_get_frameworks_dir"].side_effect = ( lambda: self.make_string(frameworks_dir)) self.assertEqual([], Click.Framework.get_frameworks())
def _setup_frameworks(self, preloads, frameworks_dir=None, frameworks={}): if frameworks_dir is None: frameworks_dir = os.path.join(self.temp_dir, "frameworks") Click.ensuredir(frameworks_dir) for framework_name in frameworks: framework_path = os.path.join(frameworks_dir, "%s.framework" % framework_name) with open(framework_path, "w") as framework: for key, value in frameworks[framework_name].items(): print("%s: %s" % (key, value), file=framework) preloads["click_get_frameworks_dir"].side_effect = ( lambda: self.make_string(frameworks_dir))
def mkfile_utf8(path, mode="w"): Click.ensuredir(os.path.dirname(path)) if sys.version < "3": import codecs with codecs.open(path, mode, "UTF-8") as f: yield f else: # io.open is available from Python 2.6, but we only use it with # Python 3 because it raises exceptions when passed bytes. import io with io.open(path, mode, encoding="UTF-8") as f: yield f
def test_multiple_architectures(self, mock_dpkg_architecture, mock_package_install_hooks): with self.run_in_subprocess("click_get_frameworks_dir") as (enter, preloads): enter() mock_dpkg_architecture.return_value = "armhf" path = self.make_fake_package( control_fields={ "Package": "test-package", "Version": "1.1", "Architecture": "multi", "Maintainer": "Foo Bar <*****@*****.**>", "Description": "test", "Click-Version": "0.2", }, manifest={ "name": "test-package", "version": "1.1", "framework": "ubuntu-sdk-13.10", "architecture": ["armhf", "i386"], }, control_scripts={"preinst": static_preinst}) root = os.path.join(self.temp_dir, "root") db = Click.DB() db.add(root) installer = ClickInstaller(db) self._setup_frameworks(preloads, frameworks=["ubuntu-sdk-13.10"]) with mock_quiet_subprocess_call(): installer.install(path) self.assertTrue( os.path.exists(os.path.join(root, "test-package", "current")))
def setUp(self): super(TestClickSingleDB, self).setUp() self.use_temp_dir() self.master_db = Click.DB() self.master_db.add(self.temp_dir) self.db = self.master_db.get(self.master_db.props.size - 1) self.spawn_calls = []
def test_packages_all(self): with open(os.path.join(self.temp_dir, "a.conf"), "w") as a: print("[Click Database]", file=a) print("root = %s" % os.path.join(self.temp_dir, "a"), file=a) with open(os.path.join(self.temp_dir, "b.conf"), "w") as b: print("[Click Database]", file=b) print("root = %s" % os.path.join(self.temp_dir, "b"), file=b) db = Click.DB() db.read(db_dir=self.temp_dir) self.assertEqual([], list(db.get_packages(all_versions=True))) os.makedirs(os.path.join(self.temp_dir, "a", "pkg1", "1.0")) os.symlink("1.0", os.path.join(self.temp_dir, "a", "pkg1", "current")) os.makedirs(os.path.join(self.temp_dir, "b", "pkg1", "1.1")) os.symlink("1.1", os.path.join(self.temp_dir, "b", "pkg1", "current")) os.makedirs(os.path.join(self.temp_dir, "b", "pkg2", "0.1")) os.symlink("0.1", os.path.join(self.temp_dir, "b", "pkg2", "current")) self.assertEqual([ ("pkg1", "1.1", os.path.join(self.temp_dir, "b", "pkg1", "1.1"), True), ("pkg2", "0.1", os.path.join(self.temp_dir, "b", "pkg2", "0.1"), True), ("pkg1", "1.0", os.path.join(self.temp_dir, "a", "pkg1", "1.0"), False), ], self._installed_packages_tuplify( db.get_packages(all_versions=True)))
def setUp(self): super(TestClickInstaller, self).setUp() self.use_temp_dir() self.db = Click.DB() self.db.add(self.temp_dir) # mock signature checks during the tests self.debsig_patcher = mock.patch("click_package.install.DebsigVerify") self.debsig_patcher.start()
def get_installed_version_and_directory(self): db = Click.DB() db.read() package_name = 'com.ubuntu.reminders' registry = Click.User.for_user(db, name=os.environ.get('USER')) version = registry.get_version(package_name) directory = registry.get_path(package_name) return version, directory
def test_gc_fixes_old_user_registrations(self): with self.run_in_subprocess("getpwnam") as (enter, preloads): enter() # Setup the system hook preloads["getpwnam"].side_effect = ( lambda name: self.make_pointer(Passwd(pw_dir=b"/foo"))) # Setup both databases db1 = os.path.join(self.temp_dir, "db1") db2 = os.path.join(self.temp_dir, "db2") db = Click.DB() db.add(db1) db.add(db2) # Prepare common manifest for the packages manifest = {"hooks": {"test-app": {"test": "foo"}}} # Setup versions 1.0 and 3.0 of package in db1 version1 = os.path.join(db1, "test-package", "1.0") with mkfile( os.path.join(version1, ".click", "info", "test-package.manifest")) as f: json.dump(manifest, f) version3 = os.path.join(db1, "test-package", "3.0") with mkfile( os.path.join(version3, ".click", "info", "test-package.manifest")) as f: json.dump(manifest, f) # Setup version 0.2 of package in db2 version2 = os.path.join(db2, "test-package", "2.0") with mkfile( os.path.join(version2, ".click", "info", "test-package.manifest")) as f: json.dump(manifest, f) # Setup the user registration for 2.0 in db2. registrationPath = os.path.join(db2, ".click", "users", "foo", "test-package") os.makedirs(os.path.dirname(registrationPath)) os.symlink(version2, registrationPath) # Run the garbage collection to update the registrations. db.gc() # Verify that the user still has a registration for the package, # and that it's now registered for version 3.0. self.assertTrue(os.path.lexists(registrationPath)) self.assertEqual(version3, os.readlink(registrationPath)) user_db = Click.User.for_user(db, "foo") try: version = user_db.get_version("test-package") self.assertEqual("3.0", version) except: self.fail("No user registration for 'test-package'")
def test_upgrade(self, mock_package_install_hooks): with self.run_in_subprocess("click_get_frameworks_dir") as (enter, preloads): enter() os.environ["TEST_QUIET"] = "1" path = self.make_fake_package( control_fields={ "Package": "test-package", "Version": "1.1", "Architecture": "all", "Maintainer": "Foo Bar <*****@*****.**>", "Description": "test", "Click-Version": "0.2", }, manifest={ "name": "test-package", "version": "1.1", "framework": "ubuntu-sdk-13.10", }, control_scripts={"preinst": static_preinst}, data_files={"foo": None}) root = os.path.join(self.temp_dir, "root") package_dir = os.path.join(root, "test-package") inst_dir = os.path.join(package_dir, "current") os.makedirs(os.path.join(package_dir, "1.0")) os.symlink("1.0", inst_dir) db = Click.DB() db.add(root) installer = ClickInstaller(db) self._setup_frameworks(preloads, frameworks=["ubuntu-sdk-13.10"]) with mock_quiet_subprocess_call(): installer.install(path) self.assertCountEqual([".click", "test-package"], os.listdir(root)) self.assertCountEqual(["1.1", "current"], os.listdir(package_dir)) self.assertTrue(os.path.islink(inst_dir)) self.assertEqual("1.1", os.readlink(inst_dir)) self.assertCountEqual([".click", "foo"], os.listdir(inst_dir)) status_path = os.path.join(inst_dir, ".click", "status") with open(status_path) as status_file: # .readlines() avoids the need for a python-apt backport to # Ubuntu 12.04 LTS. status = list(Deb822.iter_paragraphs(status_file.readlines())) self.assertEqual(1, len(status)) self.assertEqual( { "Package": "test-package", "Status": "install ok installed", "Version": "1.1", "Architecture": "all", "Maintainer": "Foo Bar <*****@*****.**>", "Description": "test", "Click-Version": "0.2", }, status[0]) mock_package_install_hooks.assert_called_once_with(db, "test-package", "1.0", "1.1", user_name=None)
def read_hooks_for(path, package, app_name): try: directory = Click.find_package_directory(path) manifest_path = os.path.join(directory, ".click", "info", "%s.manifest" % package) with io.open(manifest_path, encoding="UTF-8") as manifest: return json.load(manifest).get("hooks", {}).get(app_name, {}) except Exception: return {}
def test_no_db_conf_errors(self): db = Click.DB() self.assertRaisesDatabaseError(Click.DatabaseError.INVALID, db.get, 0) self.assertEqual(db.props.overlay, "") self.assertRaisesDatabaseError(Click.DatabaseError.INVALID, db.maybe_remove, "something", "1.0") self.assertRaisesDatabaseError(Click.DatabaseError.INVALID, db.gc) self.assertRaisesDatabaseError(Click.DatabaseError.INVALID, db.ensure_ownership)
def test_overlay(self): with open(os.path.join(self.temp_dir, "00_custom.conf"), "w") as f: print("[Click Database]", file=f) print("root = /custom", file=f) with open(os.path.join(self.temp_dir, "99_default.conf"), "w") as f: print("[Click Database]", file=f) print("root = /opt/click.ubuntu.com", file=f) db = Click.DB() db.read(db_dir=self.temp_dir) self.assertEqual("/opt/click.ubuntu.com", db.props.overlay)
def list_packages(options): db = Click.DB() db.read(db_dir=None) if options.root is not None: db.add(options.root) if options.all: return json_array_to_python(db.get_manifests(all_versions=True)) else: registry = Click.User.for_user(db, name=options.user) return json_array_to_python(registry.get_manifests())
def setUp(self): super(UserDataRemovalTestCase, self).setUp() self.use_temp_dir() self.db = Click.DB() self.db.add(self.temp_dir) # add app self.appname = "some-app" self.registry = Click.User.for_user(self.db, "user") os.makedirs(self.registry.get_overlay_db()) path = os.path.join(self.registry.get_overlay_db(), self.appname) os.symlink("/1.0", path)
def write_desktop_file(target_path, source_path, profile): Click.ensuredir(os.path.dirname(target_path)) with io.open(source_path, encoding="UTF-8") as source, \ io.open(target_path, "w", encoding="UTF-8") as target: source_dir = Click.find_package_directory(source_path) written_comment = False seen_path = False for line in source: if not line.rstrip("\n") or line.startswith("#"): # Comment target.write(line) elif line.startswith("["): # Group header target.write(line) if not written_comment: print(COMMENT, file=target) elif "=" not in line: # Who knows? target.write(line) else: key, value = line.split("=", 1) key = key.strip() value = value.strip() if key == "Exec": target.write("%s=aa-exec-click -p %s -- %s\n" % (key, quote_for_desktop_exec(profile), value)) elif key == "Path": target.write("%s=%s\n" % (key, source_dir)) seen_path = True elif key == "Icon": icon_path = os.path.join(source_dir, value) if os.path.exists(icon_path): target.write("%s=%s\n" % (key, icon_path)) else: target.write("%s=%s\n" % (key, value)) else: target.write("%s=%s\n" % (key, value)) if not seen_path: target.write("Path=%s\n" % source_dir)
def test_read_configuration(self): with open(os.path.join(self.temp_dir, "a.conf"), "w") as a: print("[Click Database]", file=a) print("root = /a", file=a) with open(os.path.join(self.temp_dir, "b.conf"), "w") as b: print("[Click Database]", file=b) print("root = /b", file=b) db = Click.DB() db.read(db_dir=self.temp_dir) db.add("/c") self.assertEqual(3, db.props.size) self.assertEqual(["/a", "/b", "/c"], [db.get(i).props.root for i in range(db.props.size)])
def run(argv): parser = OptionParser( dedent("""\ %prog install [options] PACKAGE-FILE This is a low-level tool; to install a package as an ordinary user you should generally use "pkcon install-local PACKAGE-FILE" instead.""")) parser.add_option("--root", metavar="PATH", help="install packages underneath PATH") parser.add_option("--force-missing-framework", action="store_true", default=False, help="install despite missing system framework") parser.add_option("--user", metavar="USER", help="register package for USER") parser.add_option("--all-users", default=False, action="store_true", help="register package for all users") parser.add_option("--allow-unauthenticated", default=False, action="store_true", help="allow installing packages with no signatures") parser.add_option("--verbose", default=False, action="store_true", help="be more verbose on install") options, args = parser.parse_args(argv) if len(args) < 1: parser.error("need package file name") db = Click.DB() db.read(db_dir=None) if options.root is not None: db.add(options.root) package_path = args[0] installer = ClickInstaller( db=db, force_missing_framework=options.force_missing_framework, allow_unauthenticated=options.allow_unauthenticated) try: installer.install(package_path, user=options.user, all_users=options.all_users, quiet=not options.verbose) except ClickInstallerError as e: print("Cannot install %s: %s" % (package_path, e), file=sys.stderr) return 1 return 0
def test_audit_no_signature(self): if not Click.find_on_path("debsig-verify"): self.skipTest("this test needs debsig-verify") path = self.make_fake_package(control_fields={"Click-Version": "0.4"}, manifest={ "name": "test-package", "version": "1.0", "framework": "", }) self.debsig_patcher.stop() self.assertRaisesRegex(ClickInstallerAuditError, "Signature verification error", ClickInstaller(self.db).audit, path) self.debsig_patcher.start()
def run(argv): parser = OptionParser("%prog build [options] DIRECTORY") parser.add_option( "-m", "--manifest", metavar="PATH", default="manifest.json", help="read package manifest from PATH (default: manifest.json)") parser.add_option( "--no-validate", action="store_false", default=True, dest="validate", help="Don't run click-reviewers-tools check on resulting .click") parser.add_option( "-I", "--ignore", metavar="file-pattern", action='append', default=[], help="Ignore the given pattern when building the package") options, args = parser.parse_args(argv) if len(args) < 1: parser.error("need directory") directory = args[0] if not os.path.isdir(directory): parser.error('directory "%s" does not exist' % directory) if os.path.isdir(os.path.join(directory, options.manifest)): options.manifest = os.path.join(options.manifest, "manifest.json") if not os.path.exists(os.path.join(directory, options.manifest)): parser.error( 'directory "%s" does not contain manifest file "%s"' % (directory, options.manifest)) builder = ClickBuilder() builder.add_file(directory, "./") for ignore in options.ignore: builder.add_ignore_pattern(ignore) try: path = builder.build(".", manifest_path=options.manifest) except ClickBuildError as e: print(e, file=sys.stderr) return 1 if options.validate and Click.find_on_path('click-review'): print("Now executing: click-review %s" % path) try: subprocess.check_call(['click-review', path]) except subprocess.CalledProcessError: # qtcreator-plugin-ubuntu relies on return code 0 # to establish if a .click package has been built # at all. # # If we want to distinguish between # - click build failed # - click build succeeded, but validation failed # both tools will have to learn this at the same # time. pass print("Successfully built package in '%s'." % path) return 0
def make_fake_package(self, control_fields=None, manifest=None, control_scripts=None, data_files=None): """Build a fake package with given contents.""" control_fields = {} if control_fields is None else control_fields control_scripts = {} if control_scripts is None else control_scripts data_files = {} if data_files is None else data_files data_dir = os.path.join(self.temp_dir, "fake-package") control_dir = os.path.join(self.temp_dir, "DEBIAN") with mkfile(os.path.join(control_dir, "control")) as control: for key, value in control_fields.items(): print('%s: %s' % (key.title(), value), file=control) print(file=control) if manifest is not None: with mkfile(os.path.join(control_dir, "manifest")) as f: json.dump(manifest, f) print(file=f) for name, contents in control_scripts.items(): with mkfile(os.path.join(control_dir, name)) as script: script.write(contents) Click.ensuredir(data_dir) for name, path in data_files.items(): Click.ensuredir(os.path.dirname(os.path.join(data_dir, name))) if path is None: touch(os.path.join(data_dir, name)) elif os.path.isdir(path): shutil.copytree(path, os.path.join(data_dir, name)) else: shutil.copy2(path, os.path.join(data_dir, name)) package_path = '%s.click' % data_dir ClickBuilder()._pack(self.temp_dir, control_dir, data_dir, package_path) return package_path
def get_manifest(options, arg): if "/" not in arg: db = Click.DB() db.read(db_dir=None) if options.root is not None: db.add(options.root) registry = Click.User.for_user(db, name=options.user) if registry.has_package_name(arg): return json_object_to_python(registry.get_manifest(arg)) try: with closing(DebFile(filename=arg)) as package: with package.control.get_file("manifest", encoding="UTF-8") as manifest_file: return _load_manifest(manifest_file) except Exception: pkgdir = Click.find_package_directory(arg) manifest_path = glob.glob( os.path.join(pkgdir, ".click", "info", "*.manifest")) if len(manifest_path) > 1: raise Exception("Multiple manifest files found in '%s'" % (manifest_path)) with open(manifest_path[0]) as f: return _load_manifest(f)
def test_manifests_all(self): with open(os.path.join(self.temp_dir, "a.conf"), "w") as a: print("[Click Database]", file=a) print("root = %s" % os.path.join(self.temp_dir, "a"), file=a) with open(os.path.join(self.temp_dir, "b.conf"), "w") as b: print("[Click Database]", file=b) print("root = %s" % os.path.join(self.temp_dir, "b"), file=b) db = Click.DB() db.read(db_dir=self.temp_dir) self.assertEqual([], json_array_to_python( db.get_manifests(all_versions=True))) self.assertEqual([], json.loads( db.get_manifests_as_string(all_versions=True))) a_pkg1_manifest_path = os.path.join(self.temp_dir, "a", "pkg1", "1.0", ".click", "info", "pkg1.manifest") a_pkg1_manifest_obj = {"name": "pkg1", "version": "1.0"} with mkfile(a_pkg1_manifest_path) as a_pkg1_manifest: json.dump(a_pkg1_manifest_obj, a_pkg1_manifest) os.symlink("1.0", os.path.join(self.temp_dir, "a", "pkg1", "current")) b_pkg1_manifest_path = os.path.join(self.temp_dir, "b", "pkg1", "1.1", ".click", "info", "pkg1.manifest") b_pkg1_manifest_obj = {"name": "pkg1", "version": "1.1"} with mkfile(b_pkg1_manifest_path) as b_pkg1_manifest: json.dump(b_pkg1_manifest_obj, b_pkg1_manifest) os.symlink("1.1", os.path.join(self.temp_dir, "b", "pkg1", "current")) b_pkg2_manifest_path = os.path.join(self.temp_dir, "b", "pkg2", "0.1", ".click", "info", "pkg2.manifest") b_pkg2_manifest_obj = {"name": "pkg2", "version": "0.1"} with mkfile(b_pkg2_manifest_path) as b_pkg2_manifest: json.dump(b_pkg2_manifest_obj, b_pkg2_manifest) os.symlink("0.1", os.path.join(self.temp_dir, "b", "pkg2", "current")) a_pkg1_manifest_obj["_directory"] = os.path.join( self.temp_dir, "a", "pkg1", "1.0") a_pkg1_manifest_obj["_removable"] = 0 b_pkg1_manifest_obj["_directory"] = os.path.join( self.temp_dir, "b", "pkg1", "1.1") b_pkg1_manifest_obj["_removable"] = 1 b_pkg2_manifest_obj["_directory"] = os.path.join( self.temp_dir, "b", "pkg2", "0.1") b_pkg2_manifest_obj["_removable"] = 1 self.assertEqual( [b_pkg1_manifest_obj, b_pkg2_manifest_obj, a_pkg1_manifest_obj], json_array_to_python(db.get_manifests(all_versions=True))) self.assertEqual( [b_pkg1_manifest_obj, b_pkg2_manifest_obj, a_pkg1_manifest_obj], json.loads(db.get_manifests_as_string(all_versions=True)))
def test_has_package_version(self): with open(os.path.join(self.temp_dir, "a.conf"), "w") as a: print("[Click Database]", file=a) print("root = %s" % os.path.join(self.temp_dir, "a"), file=a) with open(os.path.join(self.temp_dir, "b.conf"), "w") as b: print("[Click Database]", file=b) print("root = %s" % os.path.join(self.temp_dir, "b"), file=b) db = Click.DB() db.read(db_dir=self.temp_dir) self.assertFalse(db.has_package_version("pkg", "1.0")) os.makedirs(os.path.join(self.temp_dir, "a", "pkg", "1.0")) self.assertTrue(db.has_package_version("pkg", "1.0")) self.assertFalse(db.has_package_version("pkg", "1.1")) os.makedirs(os.path.join(self.temp_dir, "b", "pkg", "1.0")) self.assertTrue(db.has_package_version("pkg", "1.0")) os.makedirs(os.path.join(self.temp_dir, "b", "pkg", "1.1")) self.assertTrue(db.has_package_version("pkg", "1.1"))
def test_reinstall_preinstalled(self): # Attempting to reinstall a preinstalled version shouldn't actually # reinstall it in an overlay database (which would cause # irreconcilable confusion about the correct target for system hook # symlinks), but should instead simply update the user registration. path = self.make_fake_package( control_fields={ "Package": "test-package", "Version": "1.1", "Architecture": "all", "Maintainer": "Foo Bar <*****@*****.**>", "Description": "test", "Click-Version": "0.4", }, manifest={ "name": "test-package", "version": "1.1", "framework": "ubuntu-sdk-13.10", }, control_scripts={"preinst": static_preinst}) underlay = os.path.join(self.temp_dir, "underlay") overlay = os.path.join(self.temp_dir, "overlay") db = Click.DB() db.add(underlay) installer = ClickInstaller(db, True) with mock_quiet_subprocess_call(): installer.install(path, all_users=True) underlay_unpacked = os.path.join(underlay, "test-package", "1.1") self.assertTrue(os.path.exists(underlay_unpacked)) all_link = os.path.join(underlay, ".click", "users", "@all", "test-package") self.assertTrue(os.path.islink(all_link)) self.assertEqual(underlay_unpacked, os.readlink(all_link)) db.add(overlay) registry = Click.User.for_user(db, "test-user") registry.remove("test-package") user_link = os.path.join(overlay, ".click", "users", "test-user", "test-package") self.assertTrue(os.path.islink(user_link)) self.assertEqual("@hidden", os.readlink(user_link)) installer = ClickInstaller(db, True) with mock_quiet_subprocess_call(): installer.install(path, user="******") overlay_unpacked = os.path.join(overlay, "test-package", "1.1") self.assertFalse(os.path.exists(overlay_unpacked)) self.assertEqual("1.1", registry.get_version("test-package"))
def test_world_readable(self, mock_package_install_hooks): with self.run_in_subprocess("click_get_frameworks_dir") as (enter, preloads): enter() owner_only_file = os.path.join(self.temp_dir, "owner-only-file") touch(owner_only_file) os.chmod(owner_only_file, stat.S_IRUSR | stat.S_IWUSR) owner_only_dir = os.path.join(self.temp_dir, "owner-only-dir") os.mkdir(owner_only_dir, stat.S_IRWXU) path = self.make_fake_package( control_fields={ "Package": "test-package", "Version": "1.1", "Architecture": "all", "Maintainer": "Foo Bar <*****@*****.**>", "Description": "test", "Click-Version": "0.2", }, manifest={ "name": "test-package", "version": "1.1", "framework": "ubuntu-sdk-13.10", }, control_scripts={"preinst": static_preinst}, data_files={ "world-readable-file": owner_only_file, "world-readable-dir": owner_only_dir, }) root = os.path.join(self.temp_dir, "root") db = Click.DB() db.add(root) installer = ClickInstaller(db) self._setup_frameworks(preloads, frameworks=["ubuntu-sdk-13.10"]) with mock_quiet_subprocess_call(): installer.install(path) inst_dir = os.path.join(root, "test-package", "current") self.assertEqual( stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH, self._get_mode(os.path.join(inst_dir, "world-readable-file"))) self.assertEqual( stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH, self._get_mode(os.path.join(inst_dir, "world-readable-dir")))