219
224
deferred = self.reporter.handle_tasks()
220
225
return deferred.addCallback(got_result)
227
def test_fetch_hash_id_db(self):
229
# Assume package_hash_id_url is set
230
self.config.data_path = self.makeDir()
231
self.config.package_hash_id_url = "http://fake.url/path/"
232
os.makedirs(os.path.join(self.config.data_path, "package", "hash-id"))
233
hash_id_db_filename = os.path.join(self.config.data_path, "package",
234
"hash-id", "uuid_codename_arch")
236
# Fake uuid, codename and arch
237
message_store = self.broker_service.message_store
238
message_store.set_server_uuid("uuid")
239
command_mock = self.mocker.replace("landscape.lib.command.run_command")
240
command_mock("lsb_release -cs")
241
self.mocker.result("codename")
242
self.facade.set_arch("arch")
244
# Let's say fetch_async is successful
245
hash_id_db_url = self.config.package_hash_id_url + "uuid_codename_arch"
246
fetch_async_mock = self.mocker.replace("landscape.lib.fetch.fetch_async")
247
fetch_async_mock(hash_id_db_url)
248
fetch_async_result = Deferred()
249
fetch_async_result.callback("hash-ids")
250
self.mocker.result(fetch_async_result)
252
# The download should be properly logged
253
logging_mock = self.mocker.replace("logging.info")
254
logging_mock("Downloaded hash=>id database from %s" % hash_id_db_url)
255
self.mocker.result(None)
257
# We don't have our hash=>id database yet
258
self.assertFalse(os.path.exists(hash_id_db_filename))
262
result = self.reporter.fetch_hash_id_db()
265
def callback(ignored):
266
self.assertTrue(os.path.exists(hash_id_db_filename))
267
self.assertEquals(open(hash_id_db_filename).read(), "hash-ids")
268
result.addCallback(callback)
272
def test_fetch_hash_id_db_does_not_download_twice(self):
274
# Let's say that the hash=>id database is already there
275
self.config.package_hash_id_url = "http://fake.url/path/"
276
self.config.data_path = self.makeDir()
277
os.makedirs(os.path.join(self.config.data_path, "package", "hash-id"))
278
hash_id_db_filename = os.path.join(self.config.data_path, "package",
279
"hash-id", "uuid_codename_arch")
280
open(hash_id_db_filename, "w").write("test")
282
# Fake uuid, codename and arch
283
message_store = self.broker_service.message_store
284
message_store.set_server_uuid("uuid")
285
command_mock = self.mocker.replace("landscape.lib.command.run_command")
286
command_mock("lsb_release -cs")
287
self.mocker.result("codename")
288
self.facade.set_arch("arch")
290
# Intercept any call to fetch_async
291
fetch_async_mock = self.mocker.replace("landscape.lib.fetch.fetch_async")
292
fetch_async_mock(ANY)
296
result = self.reporter.fetch_hash_id_db()
298
def callback(ignored):
299
# Check that fetch_async hasn't been called
300
self.assertRaises(AssertionError, self.mocker.verify)
303
# The hash=>id database is still there
304
self.assertEquals(open(hash_id_db_filename).read(), "test")
306
result.addCallback(callback)
310
def test_fetch_hash_id_db_undetermined_server_uuid(self):
312
If the server-uuid can't be determined for some reason, no download
313
should be attempted and the failure should be properly logged.
315
message_store = self.broker_service.message_store
316
message_store.set_server_uuid(None)
318
logging_mock = self.mocker.replace("logging.warning")
319
logging_mock("Couldn't determine which hash=>id database to use: "
320
"server UUID not available")
321
self.mocker.result(None)
324
result = self.reporter.fetch_hash_id_db()
327
def test_fetch_hash_id_db_undetermined_codename(self):
330
message_store = self.broker_service.message_store
331
message_store.set_server_uuid("uuid")
333
# Undetermined codename
334
command_mock = self.mocker.replace("landscape.lib.command.run_command")
335
command_mock("lsb_release -cs")
336
command_error = CommandError("lsb_release -cs", 1, "error")
337
self.mocker.throw(command_error)
339
# The failure should be properly logged
340
logging_mock = self.mocker.replace("logging.warning")
341
logging_mock("Couldn't determine which hash=>id database to use: %s" %
343
self.mocker.result(None)
347
result = self.reporter.fetch_hash_id_db()
351
def test_fetch_hash_id_db_undetermined_arch(self):
353
# Fake uuid and codename
354
message_store = self.broker_service.message_store
355
message_store.set_server_uuid("uuid")
356
command_mock = self.mocker.replace("landscape.lib.command.run_command")
357
command_mock("lsb_release -cs")
358
self.mocker.result("codename")
361
self.facade.set_arch(None)
363
# The failure should be properly logged
364
logging_mock = self.mocker.replace("logging.warning")
365
logging_mock("Couldn't determine which hash=>id database to use: "\
366
"unknown dpkg architecture")
367
self.mocker.result(None)
371
result = self.reporter.fetch_hash_id_db()
375
def test_fetch_hash_id_db_with_default_url(self):
377
# Let's say package_hash_id_url is not set but url is
378
self.config.data_path = self.makeDir()
379
self.config.package_hash_id_url = None
380
self.config.url = "http://fake.url/path/message-system/"
381
os.makedirs(os.path.join(self.config.data_path, "package", "hash-id"))
382
hash_id_db_filename = os.path.join(self.config.data_path, "package",
383
"hash-id", "uuid_codename_arch")
385
# Fake uuid, codename and arch
386
message_store = self.broker_service.message_store
387
message_store.set_server_uuid("uuid")
388
command_mock = self.mocker.replace("landscape.lib.command.run_command")
389
command_mock("lsb_release -cs")
390
self.mocker.result("codename")
391
self.facade.set_arch("arch")
393
# Check fetch_async is called with the default url
394
hash_id_db_url = "http://fake.url/path/hash-id-databases/" \
396
fetch_async_mock = self.mocker.replace("landscape.lib.fetch.fetch_async")
397
fetch_async_mock(hash_id_db_url)
398
fetch_async_result = Deferred()
399
fetch_async_result.callback("hash-ids")
400
self.mocker.result(fetch_async_result)
404
result = self.reporter.fetch_hash_id_db()
407
def callback(ignored):
408
self.assertTrue(os.path.exists(hash_id_db_filename))
409
self.assertEquals(open(hash_id_db_filename).read(), "hash-ids")
410
result.addCallback(callback)
413
def test_fetch_hash_id_db_with_download_error(self):
415
# Assume package_hash_id_url is set
416
self.config.data_path = self.makeDir()
417
self.config.package_hash_id_url = "http://fake.url/path/"
419
# Fake uuid, codename and arch
420
message_store = self.broker_service.message_store
421
message_store.set_server_uuid("uuid")
422
command_mock = self.mocker.replace("landscape.lib.command.run_command")
423
command_mock("lsb_release -cs")
424
self.mocker.result("codename")
425
self.facade.set_arch("arch")
427
# Let's say fetch_async fails
428
hash_id_db_url = self.config.package_hash_id_url + "uuid_codename_arch"
429
fetch_async_mock = self.mocker.replace("landscape.lib.fetch.fetch_async")
430
fetch_async_mock(hash_id_db_url)
431
fetch_async_result = Deferred()
432
fetch_async_result.errback(FetchError("fetch error"))
433
self.mocker.result(fetch_async_result)
435
# The failure should be properly logged
436
logging_mock = self.mocker.replace("logging.warning")
437
logging_mock("Couldn't download hash=>id database: fetch error")
438
self.mocker.result(None)
442
result = self.reporter.fetch_hash_id_db()
444
# We shouldn't have any hash=>id database
445
def callback(ignored):
446
hash_id_db_filename = os.path.join(self.config.data_path, "package",
447
"hash-id", "uuid_codename_arch")
448
self.assertEquals(os.path.exists(hash_id_db_filename), False)
449
result.addCallback(callback)
453
def test_fetch_hash_id_db_with_undetermined_url(self):
455
# We don't know where to fetch the hash=>id database from
456
self.config.url = None
457
self.config.package_hash_id_url = None
459
# Fake uuid, codename and arch
460
message_store = self.broker_service.message_store
461
message_store.set_server_uuid("uuid")
462
command_mock = self.mocker.replace("landscape.lib.command.run_command")
463
command_mock("lsb_release -cs")
464
self.mocker.result("codename")
465
self.facade.set_arch("arch")
467
# The failure should be properly logged
468
logging_mock = self.mocker.replace("logging.warning")
469
logging_mock("Can't determine the hash=>id database url")
470
self.mocker.result(None)
475
result = self.reporter.fetch_hash_id_db()
477
# We shouldn't have any hash=>id database
478
def callback(ignored):
479
hash_id_db_filename = os.path.join(self.config.data_path, "package",
480
"hash-id", "uuid_codename_arch")
481
self.assertEquals(os.path.exists(hash_id_db_filename), False)
482
result.addCallback(callback)
486
def test_run_smart_update(self):
488
The L{PackageReporter.run_smart_update} method should run smart-update
489
with the proper arguments.
491
self.reporter.smart_update_filename = self.makeFile(
492
"#!/bin/sh\necho -n $@")
493
os.chmod(self.reporter.smart_update_filename, 0755)
494
logging_mock = self.mocker.replace("logging.debug")
495
logging_mock("'%s' exited with status 0 (out='--after %d', err=''" % (
496
self.reporter.smart_update_filename,
497
self.reporter.smart_update_interval))
499
deferred = Deferred()
504
logging.warning = raiseme
505
result = self.reporter.run_smart_update()
506
def callback((out, err, code)):
507
interval = self.reporter.smart_update_interval
508
self.assertEquals(out, "--after %d" % interval)
509
self.assertEquals(err, "")
510
self.assertEquals(code, 0)
511
result.addCallback(callback)
512
result.chainDeferred(deferred)
514
reactor.callWhenRunning(do_test)
517
def test_run_smart_update_warns_about_failures(self):
519
The L{PackageReporter.run_smart_update} method should log a warning
520
in case smart-update terminates with a non-zero exit code other than 1.
522
self.reporter.smart_update_filename = self.makeFile(
523
"#!/bin/sh\necho -n error >&2\necho -n output\nexit 2")
524
os.chmod(self.reporter.smart_update_filename, 0755)
525
logging_mock = self.mocker.replace("logging.warning")
526
logging_mock("'%s' exited with status 2"
527
" (error)" % self.reporter.smart_update_filename)
529
deferred = Deferred()
532
result = self.reporter.run_smart_update()
533
def callback((out, err, code)):
534
interval = self.reporter.smart_update_interval
535
self.assertEquals(out, "output")
536
self.assertEquals(err, "error")
537
self.assertEquals(code, 2)
538
result.addCallback(callback)
539
result.chainDeferred(deferred)
541
reactor.callWhenRunning(do_test)
544
def test_run_smart_update_warns_exit_code_1_and_non_empty_stderr(self):
546
The L{PackageReporter.run_smart_update} method should log a warning
547
in case smart-update terminates with exit code 1 and non empty stderr.
549
self.reporter.smart_update_filename = self.makeFile(
550
"#!/bin/sh\necho -n \"error \" >&2\nexit 1")
551
os.chmod(self.reporter.smart_update_filename, 0755)
552
logging_mock = self.mocker.replace("logging.warning")
553
logging_mock("'%s' exited with status 1"
554
" (error )" % self.reporter.smart_update_filename)
556
deferred = Deferred()
558
result = self.reporter.run_smart_update()
559
def callback((out, err, code)):
560
interval = self.reporter.smart_update_interval
561
self.assertEquals(out, "")
562
self.assertEquals(err, "error ")
563
self.assertEquals(code, 1)
564
result.addCallback(callback)
565
result.chainDeferred(deferred)
567
reactor.callWhenRunning(do_test)
570
def test_run_smart_update_ignores_exit_code_1_and_empty_output(self):
572
The L{PackageReporter.run_smart_update} method should not log anything
573
in case smart-update terminates with exit code 1 and output containing
574
only a newline character.
576
self.reporter.smart_update_filename = self.makeFile(
577
"#!/bin/sh\necho\nexit 1")
578
os.chmod(self.reporter.smart_update_filename, 0755)
579
deferred = Deferred()
583
logging.warning = raiseme
584
result = self.reporter.run_smart_update()
585
def callback((out, err, code)):
586
interval = self.reporter.smart_update_interval
587
self.assertEquals(out, "\n")
588
self.assertEquals(err, "")
589
self.assertEquals(code, 1)
590
result.addCallback(callback)
591
result.chainDeferred(deferred)
593
reactor.callWhenRunning(do_test)
222
596
def test_remove_expired_hash_id_request(self):
223
597
request = self.store.add_hash_id_request(["hash1"])
224
598
request.message_id = 9999