Verify original database commitments before releasing restored IndeeHub
This commit is contained in:
@@ -121,4 +121,27 @@ class MaintenanceTests(unittest.TestCase):
|
||||
with self.assertRaisesRegex(RuntimeError,'business work'):c.legacy_api_idle()
|
||||
counts['other_active_transactions']=0;c.legacy_api_idle()
|
||||
self.assertEqual(c.record['legacy_api_empty_state'],counts)
|
||||
def test_rollback_compatibility_binds_operation_preserves_rows_and_allows_only_empty_additions(self):
|
||||
import copy
|
||||
table={'schema':{'columns':['original']},'rows':0,'rows_sha256':'a'*64}
|
||||
before={'operation_id':self.operation,'tables':{'migrations':copy.deepcopy(table),'contents':copy.deepcopy(table)},'migrations':[{'id':1,'timestamp':1,'name':'Original1'}]}
|
||||
after=copy.deepcopy(before)
|
||||
self.assertEqual(module.verify_database_compatibility(before,after)['original_tables'],2)
|
||||
names=list(module.ADDITIVE_MIGRATIONS)
|
||||
after['migrations'] += [{'id':i+2,'timestamp':module.ADDITIVE_MIGRATIONS[name],'name':name} for i,name in enumerate(names)]
|
||||
after['tables']['migrations']['rows']=4;after['tables']['migrations']['rows_sha256']='b'*64
|
||||
for name in module.ADDITIVE_TABLES:after['tables'][name]=copy.deepcopy(table)
|
||||
self.assertEqual(len(module.verify_database_compatibility(before,after)['new_empty_tables']),5)
|
||||
for mutate in [lambda d:d.update(operation_id=str(uuid.uuid4())),lambda d:d['tables']['contents'].update(rows_sha256='c'*64),lambda d:d['tables']['contents']['schema'].update(columns=['changed']),lambda d:d['tables']['archipelago_publications'].update(rows=1),lambda d:d['migrations'][0].update(name='Altered'),lambda d:d['migrations'][-1].update(name='Unreviewed'),lambda d:d['tables'].update(unreviewed=copy.deepcopy(table))]:
|
||||
damaged=copy.deepcopy(after);mutate(damaged)
|
||||
with self.assertRaisesRegex(RuntimeError,'Data compatibility'):module.verify_database_compatibility(before,damaged)
|
||||
def test_verified_rollback_records_operation_proof_before_releasing_fence(self):
|
||||
c=self.controller;table={'schema':{},'rows':0,'rows_sha256':'a'*64};baseline={'operation_id':self.operation,'tables':{'migrations':table},'migrations':[]}
|
||||
c.record={'operation_id':self.operation,'phase':'Recovering','database_before':baseline};c.save()
|
||||
c.fence.parent.mkdir(parents=True);c.fence.write_text(self.operation)
|
||||
module.atomic(c.data/'update-transactions'/'supervised'/(self.operation+'.json'),{'phase':'Restored','target_startup_began':True})
|
||||
c.database_commitments=lambda:baseline
|
||||
self.assertEqual(c.release('restored')['state'],'released')
|
||||
self.assertEqual(c.record['recovery_data_verification']['operation_id'],self.operation)
|
||||
self.assertEqual(c.record['recovery_data_verification']['before_sha256'],c.record['recovery_data_verification']['after_sha256'])
|
||||
if __name__=='__main__':unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user