### Question:
ShardCleaner { @VisibleForTesting void deleteOldCompletedTransactions() { while (!Thread.currentThread().isInterrupted()) { int deleted = dao.deleteOldCompletedTransactions(maxTimestamp(maxCompletedTransactionAge)); if (deleted < CLEANUP_TRANSACTIONS_BATCH_SIZE) { break; } } } @Inject  ShardCleaner(
            DaoSupplier<ShardDao> shardDaoSupplier,
            Ticker ticker,
            NodeManager nodeManager,
            StorageService storageService,
            Optional<BackupStore> backupStore,
            ShardCleanerConfig config);  ShardCleaner(
            DaoSupplier<ShardDao> shardDaoSupplier,
            String currentNode,
            boolean coordinator,
            Ticker ticker,
            StorageService storageService,
            Optional<BackupStore> backupStore,
            Duration maxTransactionAge,
            Duration transactionCleanerInterval,
            Duration localCleanerInterval,
            Duration localCleanTime,
            Duration backupCleanerInterval,
            Duration backupCleanTime,
            int backupDeletionThreads,
            Duration maxCompletedTransactionAge); @PostConstruct void start(); @PreDestroy void shutdown(); @Managed @Nested CounterStat getTransactionJobErrors(); @Managed @Nested CounterStat getBackupJobErrors(); @Managed @Nested CounterStat getLocalJobErrors(); @Managed @Nested CounterStat getBackupShardsQueued(); @Managed @Nested CounterStat getBackupShardsCleaned(); @Managed @Nested CounterStat getLocalShardsCleaned(); @Managed void startBackupCleanup(); @Managed void startLocalCleanup(); @Managed void startLocalCleanupImmediately();  }### Answer:
@Test public void testDeleteOldCompletedTransactions() { TestingDao dao = dbi.onDemand(TestingDao.class); ShardDao shardDao = dbi.onDemand(ShardDao.class); long now = System.currentTimeMillis(); Timestamp yesterdayStart = new Timestamp(now - HOURS.toMillis(27)); Timestamp yesterdayEnd = new Timestamp(now - HOURS.toMillis(26)); Timestamp todayEnd = new Timestamp(now - HOURS.toMillis(1)); long txn1 = dao.insertTransaction(yesterdayStart); long txn2 = dao.insertTransaction(yesterdayStart); long txn3 = dao.insertTransaction(yesterdayStart); long txn4 = dao.insertTransaction(yesterdayStart); long txn5 = dao.insertTransaction(new Timestamp(now)); long txn6 = dao.insertTransaction(new Timestamp(now)); assertEquals(shardDao.finalizeTransaction(txn1, true), 1); assertEquals(shardDao.finalizeTransaction(txn2, false), 1); assertEquals(shardDao.finalizeTransaction(txn3, false), 1); assertEquals(shardDao.finalizeTransaction(txn5, true), 1); assertEquals(shardDao.finalizeTransaction(txn6, false), 1); assertEquals(dao.updateTransactionEndTime(txn1, yesterdayEnd), 1); assertEquals(dao.updateTransactionEndTime(txn2, yesterdayEnd), 1); assertEquals(dao.updateTransactionEndTime(txn3, yesterdayEnd), 1); assertEquals(dao.updateTransactionEndTime(txn5, todayEnd), 1); assertEquals(dao.updateTransactionEndTime(txn6, todayEnd), 1); shardDao.insertCreatedShard(randomUUID(), txn2); shardDao.insertCreatedShard(randomUUID(), txn2); assertQuery("SELECT transaction_id, successful, end_time FROM transactions", row(txn1, true, yesterdayEnd), row(txn2, false, yesterdayEnd), row(txn3, false, yesterdayEnd), row(txn4, null, null), row(txn5, true, todayEnd), row(txn6, false, todayEnd)); cleaner.deleteOldCompletedTransactions(); assertQuery("SELECT transaction_id, successful, end_time FROM transactions", row(txn2, false, yesterdayEnd), row(txn4, null, null), row(txn5, true, todayEnd), row(txn6, false, todayEnd)); }