45
47
from canonical.launchpad.database.openidconsumer import OpenIDConsumerNonce
48
from canonical.launchpad.interfaces.account import AccountStatus
46
49
from canonical.launchpad.interfaces.emailaddress import EmailAddressStatus
47
50
from canonical.launchpad.interfaces.lpstorm import IMasterStore
48
51
from canonical.launchpad.scripts.tests import run_script
392
397
def test_OAuthNoncePruner(self):
393
398
now = datetime.now(UTC)
395
now - timedelta(days=2), # Garbage
396
now - timedelta(days=1) - timedelta(seconds=60), # Garbage
397
now - timedelta(days=1) + timedelta(seconds=60), # Not garbage
400
now - timedelta(days=2), # Garbage
401
now - timedelta(days=1) - timedelta(seconds=60), # Garbage
402
now - timedelta(days=1) + timedelta(seconds=60), # Not garbage
400
405
LaunchpadZopelessLayer.switchDbUser('testadmin')
401
406
store = IMasterStore(OAuthNonce)
406
411
for timestamp in timestamps:
407
412
store.add(OAuthNonce(
408
413
access_token=OAuthAccessToken.get(1),
409
request_timestamp = timestamp,
410
nonce = str(timestamp)))
414
request_timestamp=timestamp,
415
nonce=str(timestamp)))
411
416
transaction.commit()
413
418
# Make sure we have 4 nonces now.
414
419
self.failUnlessEqual(store.find(OAuthNonce).count(), 4)
416
self.runHourly(maximum_chunk_size=60) # 1 minute maximum chunk size
421
self.runHourly(maximum_chunk_size=60) # 1 minute maximum chunk size
418
423
store = IMasterStore(OAuthNonce)
436
441
DAYS = 24 * HOURS
438
now - 2 * DAYS, # Garbage
439
now - 1 * DAYS - 1 * MINUTES, # Garbage
440
now - 1 * DAYS + 1 * MINUTES, # Not garbage
443
now - 2 * DAYS, # Garbage
444
now - 1 * DAYS - 1 * MINUTES, # Garbage
445
now - 1 * DAYS + 1 * MINUTES, # Not garbage
443
448
LaunchpadZopelessLayer.switchDbUser('testadmin')
456
461
self.failUnlessEqual(store.find(OpenIDConsumerNonce).count(), 4)
458
463
# Run the garbage collector.
459
self.runHourly(maximum_chunk_size=60) # 1 minute maximum chunks.
464
self.runHourly(maximum_chunk_size=60) # 1 minute maximum chunks.
461
466
store = IMasterStore(OpenIDConsumerNonce)
466
471
# And none of them are older than 1 day
467
472
earliest = store.find(Min(OpenIDConsumerNonce.timestamp)).one()
468
self.failUnless(earliest >= now - 24*60*60, 'Still have old nonces')
474
earliest >= now - 24 * 60 * 60, 'Still have old nonces')
470
476
def test_CodeImportResultPruner(self):
471
477
now = datetime.now(UTC)
493
499
new_code_import_result(now - timedelta(days=60))
494
500
for i in range(results_to_keep_count - 1):
495
new_code_import_result(now - timedelta(days=19+i))
501
new_code_import_result(now - timedelta(days=19 + i))
497
503
# Run the garbage collector
565
571
store.execute("""
566
572
INSERT INTO %s (server_url, handle, issued, lifetime)
567
573
VALUES (%s, %s, %d, %d)
568
""" % (table_name, str(delta), str(delta), now-10, delta))
574
""" % (table_name, str(delta), str(delta), now - 10, delta))
569
575
transaction.commit()
571
577
# Ensure that we created at least one expirable row (using the
779
785
BugNotification.date_emailed < THIRTY_DAYS_AGO).count(),
788
def _test_AnswerContactPruner(self, status, interval, expected_count=0):
789
# Garbo should remove answer contacts for accounts with given 'status'
790
# which was set more than 'interval' days ago.
791
LaunchpadZopelessLayer.switchDbUser('testadmin')
792
store = IMasterStore(AnswerContact)
794
person = self.factory.makePerson()
795
person.addLanguage(getUtility(ILanguageSet)['en'])
796
question = self.factory.makeQuestion()
797
with person_logged_in(question.owner):
798
question.target.addAnswerContact(person, person)
799
Store.of(question).flush()
803
AnswerContact.person == person.id).count(),
806
account = person.account
807
account.status = status
808
# We flush because a trigger sets the date_status_set and we need to
809
# modify it ourselves.
810
Store.of(account).flush()
811
if interval is not None:
812
account.date_status_set = interval
816
LaunchpadZopelessLayer.switchDbUser('testadmin')
820
AnswerContact.person == person.id).count(),
823
def test_AnswerContactPruner_deactivated_accounts(self):
824
# Answer contacts with an account deactivated at least one day ago
826
self._test_AnswerContactPruner(AccountStatus.DEACTIVATED, ONE_DAY_AGO)
828
def test_AnswerContactPruner_suspended_accounts(self):
829
# Answer contacts with an account suspended at least seven days ago
831
self._test_AnswerContactPruner(
832
AccountStatus.SUSPENDED, SEVEN_DAYS_AGO)
834
def test_AnswerContactPruner_doesnt_prune_recently_changed_accounts(self):
835
# Answer contacts which are suspended or deactivated inside the
836
# minimum time interval are not pruned.
837
self._test_AnswerContactPruner(
838
AccountStatus.DEACTIVATED, None, expected_count=1)
839
self._test_AnswerContactPruner(
840
AccountStatus.SUSPENDED, ONE_DAY_AGO, expected_count=1)
782
842
def test_BranchJobPruner(self):
783
843
# Garbo should remove jobs completed over 30 days ago.
784
844
LaunchpadZopelessLayer.switchDbUser('testadmin')
902
962
store = IMasterStore(BugMessage)
903
unmigrated = store.find(BugMessage, BugMessage.ownerID==None).count
963
unmigrated = store.find(BugMessage, BugMessage.ownerID == None).count
904
964
self.assertNotEqual(0, unmigrated())
906
966
self.assertEqual(0, unmigrated())