2
from os.path import join
5
from landscape.lib.persist import Persist
6
from landscape.tests.helpers import LandscapeTest
8
from landscape.patch import UpgradeManager
9
from landscape.upgraders import legacy
10
from landscape.package.store import PackageStore
13
class TestUpgraders(LandscapeTest):
15
def test_v8_upgrade_user_data(self):
17
old_user_data = {"users": {
18
1001: {"home-phone": None, "username": "testing", "uid": 1001,
19
"enabled": True, "location": None, "primary-gid": 1001,
20
"work-phone":None, "name": u"Testing"},
21
4: {"home-phone": None, "username":"sync", "uid": 4,
22
"enabled": True, "location": None, "primary-gid": 65534,
23
"work-phone": None, "name": u"sync"}
26
persist.set("users", old_user_data)
27
legacy.index_users_on_names_added(persist)
28
expected_user_data = {
29
"testing": {"home-phone": None, "username": "testing", "uid": 1001,
30
"enabled": True, "location": None, "primary-gid": 1001,
31
"work-phone":None, "name": u"Testing"},
32
"sync": {"home-phone": None, "username":"sync", "uid": 4,
33
"enabled": True, "location": None,
34
"primary-gid": 65534, "work-phone": None,
37
self.assertEquals(persist.get("users")["users"],
40
def test_v8_upgrade_group_data(self):
42
The newer group format uses usernames instead of user ids in the list
43
of members of a group. So we need to translate between them.
45
If a user is found in the list of members, that we can't find by id,
46
then we drop it from the persistent data.
49
# The "scanner" group contains an unknown userid "9", we expect it to
53
1001: {"home-phone": None, "username": "testing",
54
"uid": 1001, "enabled": True, "location": None,
55
"primary-gid": 1001, "work-phone":None,
57
4: {"home-phone": None, "username":"sync", "uid": 4,
58
"enabled": True, "location": None,
60
"work-phone": None, "name": u"sync"}},
62
5: {"gid": 5, "name": "tty", "members": []},
63
104: {"gid": 104,"name": "scanner",
64
"members": [1001, 4, 9]}}
66
persist.set("users", old_user_data)
67
legacy.index_users_on_names_added(persist)
68
expected_group_data = {
69
"tty": {"gid": 5, "name": "tty", "members": []},
70
"scanner": {"gid": 104,"name": "scanner",
71
"members": ["sync", "testing"]},
73
self.assertEquals(persist.get("users")["groups"],
76
def test_v7_move_registration_data(self):
78
Move the registration-related data to the "registration" namespace.
81
persist.set("message-store.secure_id", "SECURE")
82
persist.set("http-ping.insecure-id", "INSECURE")
83
legacy.move_registration_data(persist)
84
self.assertFalse(persist.has("message-store.secure_id"))
85
self.assertFalse(persist.has("http-ping.insecure-id"))
86
self.assertEquals(persist.get("registration.secure-id"), "SECURE")
87
self.assertEquals(persist.get("registration.insecure-id"), "INSECURE")
89
def test_v6_rename_message_queue(self):
91
Rename "message-queue" to "message-store".
94
persist.set("message-store", "DATA")
95
legacy.rename_message_queue(persist)
96
self.assertFalse(persist.has("message-queue"))
97
self.assertEquals(persist.get("message-store"), "DATA")
99
# Shouldn't break or overwrite if nothing to do.
100
legacy.rename_message_queue(persist)
101
self.assertFalse(persist.has("message-queue"))
102
self.assertEquals(persist.get("message-store"), "DATA")
104
def test_v5_update_user_data(self):
106
The v5 upgrader removes 'users' and 'groups' data from the
110
users = persist.root_at("users")
111
users.set("users", ["user data!"])
112
users.set("groups", ["user data!"])
113
legacy.user_change_detection_added(persist)
114
self.assertFalse(users.has("users"))
115
self.assertFalse(users.has("groups"))
117
def test_v4_delete_user_data(self):
119
The v4 upgrader simply removes old-format user data.
122
users = persist.root_at("users")
123
users.set("data", {"fooble": "blatto"})
124
legacy.group_support_added(persist)
125
self.assertFalse(users.has("data"))
127
def test_v3_delete_urgent_exchange(self):
129
message_exchange = persist.root_at("message-exchange")
130
message_exchange.set("urgent-exchange", True)
131
legacy.delete_urgent_exchange(persist)
132
self.assertFalse(message_exchange.has("urgent-exchange"))
134
def test_v2_delete_old_resource_data(self):
136
The upgrader needs to remove old resource data.
139
persist.set("load-average", 1)
140
persist.set("memory-info", 1)
141
persist.set("mount-info", 1)
142
persist.set("processor-info", 1)
143
persist.set("temperature", 1)
144
persist.set("trip-points", 1)
146
legacy.delete_old_resource_data(persist)
148
self.assertEquals(persist.get("load-average"), None)
149
self.assertEquals(persist.get("memory-info"), None)
150
self.assertEquals(persist.get("mount-info"), None)
151
self.assertEquals(persist.get("processor-info"), None)
152
self.assertEquals(persist.get("temperature"), None)
153
self.assertEquals(persist.get("trip-points"), None)
155
def test_v1_delete_user_data(self):
157
users = persist.root_at("users")
158
users.set("data", {"fooble": "blatto"})
159
legacy.delete_user_data(persist)
160
self.assertFalse(users.has("data"))
163
class TestMigration(LandscapeTest):
166
super(TestMigration, self).setUp()
167
self.data_dir = self.make_dir()
168
self.persist_filename = "data.bpickle"
169
self.broker_filename = "broker_data.bpickle"
170
self.monitor_filename = "monitor_data.bpickle"
171
self.sqlite_filename = "hashdb.sqlite"
172
self.hashdb_filename = "hash.db"
173
self.upgrade_manager = UpgradeManager()
174
self.persist = Persist(filename=join(self.data_dir,
175
self.persist_filename))
178
legacy.migrate_data_file(self.data_dir,
179
self.persist_filename,
180
self.broker_filename,
181
self.monitor_filename,
182
self.hashdb_filename,
183
self.sqlite_filename,
184
self.upgrade_manager)
186
def test_migrate_legacy_data_migrates_monitor_data(self):
188
Make sure the migrater migrates monitor data from the old
189
persist file into the monitor persist file.
191
self.persist.set("load-average", {"A" : 1})
192
self.persist.set("memory-info", {"B" : 2})
193
self.persist.set("mount-info", {"C" : 3})
194
self.persist.set("processor-info", {"D" : 4})
195
self.persist.set("temperature", {"E" : 5})
196
self.persist.set("computer-uptime", {"F" : 6})
197
self.persist.set("computer-info", {"G" : 7})
198
self.persist.set("hardware-inventory", {"H" : 8})
199
self.persist.set("users", {"I" : 9})
204
monitor_filename = join(self.data_dir, self.monitor_filename)
205
self.assertTrue(os.path.exists(monitor_filename))
206
monitor_persist = Persist(filename=monitor_filename)
208
self.assertEquals(monitor_persist.get("load-average"), {"A" : 1})
209
self.assertEquals(monitor_persist.get("memory-info"), {"B" : 2})
210
self.assertEquals(monitor_persist.get("mount-info"), {"C" : 3})
211
self.assertEquals(monitor_persist.get("processor-info"), {"D" : 4})
212
self.assertEquals(monitor_persist.get("temperature"), {"E" : 5})
213
self.assertEquals(monitor_persist.get("computer-uptime"), {"F" : 6})
214
self.assertEquals(monitor_persist.get("computer-info"), {"G" : 7})
215
self.assertEquals(monitor_persist.get("hardware-inventory"), {"H" : 8})
216
self.assertEquals(monitor_persist.get("users"), {"I" : 9})
218
def test_migrate_legacy_data_migrates_broker_data(self):
220
Make sure the migrater migrates broker data from the old
221
persist file into the broker persist file.
223
persist = self.persist.root_at("message-store")
224
persist.set("foo", 33)
225
persist = self.persist.root_at("message-exchange")
226
persist.set("bar", 66)
227
persist = self.persist.root_at("registration")
228
persist.set("baz", 99)
231
broker_filename = join(self.data_dir, self.broker_filename)
232
self.assertTrue(os.path.exists(broker_filename))
234
broker_persist = Persist(filename=broker_filename)
235
self.assertEquals(broker_persist.get("message-store.foo"), 33)
236
self.assertEquals(broker_persist.get("message-exchange.bar"), 66)
237
self.assertEquals(broker_persist.get("registration.baz"), 99)
239
def test_migrate_upgrades_existing_persist_first(self):
241
Make sure the migrater first applies all upgrades to the
242
persist before migrating it.
246
self.upgrade_manager.register_upgrader(1, l.append)
248
persist_filename = join(self.data_dir, self.persist_filename)
249
self.assertTrue(os.path.exists(persist_filename))
250
persist = Persist(filename=persist_filename)
251
self.assertEquals(persist.get("system-version"), 1)
252
self.assertEquals(l[0].get("system-version"), 1)
254
def test_migrate_partially_upgraded_persist(self):
255
"""Unapplied patches are applied before migration occurs."""
256
self.persist.set("system-version", 1)
261
self.upgrade_manager.register_upgrader(1, first.append)
262
self.upgrade_manager.register_upgrader(2, second.append)
265
persist_filename = join(self.data_dir, self.persist_filename)
266
self.assertTrue(os.path.exists(persist_filename))
267
persist = Persist(filename=persist_filename)
268
self.assertEquals(first, [])
269
self.assertEquals(second[0].get("system-version"), 2)
271
def test_migrate_creates_new_persist_first(self):
273
Make sure the migrater creates a new persist and marks it as
274
applied with the most recent version if there is no existing
278
self.upgrade_manager.register_upgrader(1, l.append)
279
persist_filename = join(self.data_dir, self.persist_filename)
280
self.assertFalse(os.path.exists(persist_filename))
284
self.assertTrue(os.path.exists(persist_filename))
285
persist = Persist(filename=persist_filename)
286
self.assertEquals(persist.get("system-version"), 1)
288
# the upgrader is never called because the persist is created
289
# fresh and just marked as the most recent version.
290
self.assertEquals(l, [])
292
def test_package_migrates_hash_db_to_sqlite(self):
294
Make sure migrater migrates legacy package hash data to the
295
new sqlite-based package store.
297
hashdb = gdbm.open(join(self.data_dir, self.hashdb_filename), "cs")
298
hashdb["HASH"] = "33"
299
hashdb["33"] = "HASH"
300
self.assertFalse(os.path.exists(join(self.data_dir,
301
self.sqlite_filename)))
305
store = PackageStore(join(self.data_dir, self.sqlite_filename))
306
self.assertEquals(store.get_hash_id("HASH"), 33)
307
self.assertEquals(store.get_id_hash(33), "HASH")
309
def test_package_migrates_package_statistics_to_sqlite(self):
311
Make sure migrater migrates legacy installed, available and
312
available upgrade package data in the persist file to the new
313
sqlite-based package store.
315
hashdb = gdbm.open(join(self.data_dir, self.hashdb_filename), "cs")
316
hashdb["HASH"] = "33"
317
hashdb["33"] = "HASH"
319
self.persist.set("package.installed", [33])
320
self.persist.set("package.available", [34])
321
self.persist.set("package.available_upgrades", [35])
323
self.assertFalse(os.path.exists(join(self.data_dir,
324
self.sqlite_filename)))
327
store = PackageStore(join(self.data_dir, self.sqlite_filename))
328
self.assertEquals(store.get_installed(), [33])
329
self.assertEquals(store.get_available(), [34])
330
self.assertEquals(store.get_available_upgrades(), [35])