Merge lp:~kyrofa/click/bugfix_1479001 into lp:click

Proposed by Kyle Fazzari
Status: Superseded
Proposed branch: lp:~kyrofa/click/bugfix_1479001
Merge into: lp:click
Diff against target: 118 lines (+88/-2)
2 files modified
click/tests/test_database.py (+68/-0)
lib/click/database.vala (+20/-2)
To merge this branch: bzr merge lp:~kyrofa/click/bugfix_1479001
Reviewer Review Type Date Requested Status
Alejandro J. Cura Pending
dobey Pending
click hackers Pending
Review via email: mp+273469@code.launchpad.net

This proposal has been superseded by a proposal from 2015-10-06.

Commit message

Garbage collect old user registrations.

Description of the change

Garbage collect old user registrations.

This should fix bug #1479001, but introduces the following known regression:

Users can only register old versions of an app between reboots-- the system hooks (which are run on boot) will update old registrations to be pointing to the newest version of an app in any database. This is fixable but requires comparing timestamps of the registrations to the app, which is a more in-depth change.

To post a comment you must log in.
lp:~kyrofa/click/bugfix_1479001 updated
582. By Kyle Fazzari

Garbage collect old user registrations.

583. By Kyle Fazzari

Move version comparisons to dpkg --compare-versions.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'click/tests/test_database.py'
2--- click/tests/test_database.py 2014-09-29 11:40:56 +0000
3+++ click/tests/test_database.py 2015-10-05 20:44:54 +0000
4@@ -412,6 +412,74 @@
5 self.db.gc()
6 self.assertTrue(os.path.exists(a_path))
7
8+ # Test that bug #1479001 is fixed. Uses the following scenario:
9+ #
10+ # - Two databases: db1 and db2.
11+ # - One package, "test-package":
12+ # - Versions 1 and 3 installed in db1
13+ # - Version 2 installed in db2
14+ # - User has a registration in db2 for version 2, where the registration
15+ # timestamp precedes the installation of version 3.
16+ #
17+ # In this case, bug #1479001 expects that the user's registration would
18+ # be updated to 3, since it was installed after the user registered for
19+ # 2, which implies that the user would like the update to 3.
20+ def test_gc_fixes_old_user_registrations(self):
21+ with self.run_in_subprocess("getpwnam") as (enter, preloads):
22+ enter()
23+
24+ # Setup the system hook
25+ preloads["getpwnam"].side_effect = (
26+ lambda name: self.make_pointer(Passwd(pw_dir=b"/foo")))
27+
28+ # Setup both databases
29+ db1 = os.path.join(self.temp_dir, "db1")
30+ db2 = os.path.join(self.temp_dir, "db2")
31+ db = Click.DB()
32+ db.add(db1)
33+ db.add(db2)
34+
35+ # Prepare common manifest for the packages
36+ manifest = {"hooks": {"test-app": {"test": "foo"}}}
37+
38+ # Setup versions 1.0 and 3.0 of package in db1
39+ version1 = os.path.join(db1, "test-package", "1.0")
40+ with mkfile(os.path.join(version1, ".click", "info",
41+ "test-package.manifest")) as f:
42+ json.dump(manifest, f)
43+
44+ version3 = os.path.join(db1, "test-package", "3.0")
45+ with mkfile(os.path.join(version3, ".click", "info",
46+ "test-package.manifest")) as f:
47+ json.dump(manifest, f)
48+
49+ # Setup version 0.2 of package in db2
50+ version2 = os.path.join(db2, "test-package", "2.0")
51+ with mkfile(os.path.join(version2, ".click", "info",
52+ "test-package.manifest")) as f:
53+ json.dump(manifest, f)
54+
55+ # Setup the user registration for 2.0 in db2.
56+ registrationPath = os.path.join(
57+ db2, ".click", "users", "foo", "test-package")
58+ os.makedirs(os.path.dirname(registrationPath))
59+ os.symlink(version2, registrationPath)
60+
61+ # Run the garbage collection to update the registrations.
62+ db.gc()
63+
64+ # Verify that the user still has a registration for the package,
65+ # and that it's now registered for version 3.0.
66+ self.assertTrue(os.path.lexists(registrationPath))
67+ self.assertEqual(version3, os.readlink(registrationPath))
68+
69+ user_db = Click.User.for_user(db, "foo")
70+ try:
71+ version = user_db.get_version("test-package")
72+ self.assertEqual("3.0", version)
73+ except:
74+ self.fail("No user registration for 'test-package'")
75+
76 def _make_ownership_test(self):
77 path = os.path.join(self.temp_dir, "a", "1.0")
78 touch(os.path.join(path, ".click", "info", "a.manifest"))
79
80=== modified file 'lib/click/database.vala'
81--- lib/click/database.vala 2014-09-29 11:40:56 +0000
82+++ lib/click/database.vala 2015-10-05 20:44:54 +0000
83@@ -430,6 +430,24 @@
84 public void
85 gc () throws Error
86 {
87+ // Clean up user registrations-- registering for an old version of the
88+ // package is no longer allowed.
89+ foreach (var package in master_db.get_packages(true)) {
90+ var users_db = new Users (master_db);
91+ foreach (var name in users_db.get_user_names ()) {
92+ var user_db = users_db.get_user (name);
93+ try {
94+ string registered_version = user_db.get_version (package.package);
95+ // Update the user's registered version if necessary.
96+ if (registered_version < package.version) {
97+ user_db.set_version (package.package, package.version);
98+ }
99+ } catch (UserError e) {
100+ // User isn't registered for this app. Skip it.
101+ }
102+ }
103+ }
104+
105 var users_db = new Users (master_db);
106 var user_reg = new Gee.HashMultiMap<string, string> ();
107 foreach (var user_name in users_db.get_user_names ()) {
108@@ -625,8 +643,8 @@
109 *
110 * The directory where changes should be written.
111 */
112- public string overlay
113- {
114+ public string overlay
115+ {
116 get {
117 if (db.size == 0)
118 return "";

Subscribers

People subscribed via source and target branches

to all changes: