def test_from_signed_confirmed(self): """ This test checks the functionality of making a block with the payload from a message. """ meta = self.community.get_meta_message(u"signed_confirm") message = meta.impl( authentication=([self.member, self.member_bank], ), distribution=(self.community.claim_global_time(), ), payload=self.payload, destination=(LoopbackCandidate(), )) block = DatabaseBlock.from_signed_confirm_message(message) self.assertEqual(block.benefactor, message.payload.benefactor) self.assertEqual(block.beneficiary, message.payload.beneficiary) self.assertEqual(DatabaseModel.decode(block.agreement_benefactor), message.payload.agreement_benefactor) self.assertEqual(DatabaseModel.decode(block.agreement_beneficiary), message.payload.agreement_beneficiary) self.assertEqual(block.sequence_number_benefactor, message.payload.sequence_number_benefactor) self.assertEqual(block.sequence_number_beneficiary, message.payload.sequence_number_beneficiary) self.assertEqual(block.previous_hash_benefactor, message.payload.previous_hash_benefactor) self.assertEqual(block.previous_hash_beneficiary, message.payload.previous_hash_beneficiary) self.assertEqual(block.insert_time, message.payload.insert_time)
def test_signed_model_no_save(self): """ Test if signing an unsaved model raises an error. """ model = DatabaseModel() with self.assertRaises(RuntimeError): model.sign(self.api)
def test_model_equal(self): """ Test if identical models have the same hash and are eveluated as equal """ model1 = DatabaseModel() model2 = DatabaseModel() #self.assertEqual(hash(model1), hash(model2)) self.assertEqual(model1, model2)
def test_put_success(self): self.backend.clear() self.backend.post('test', self.block1.id, self.block1.encode()) self.assertEqual( DatabaseModel.decode(self.backend.get('test', self.block1.id)), self.block1) self.assertTrue( self.backend.put('test', self.block1.id, self.block2.encode())) self.assertEqual( DatabaseModel.decode(self.backend.get('test', self.block1.id)), self.block2)
def test_model_unequal(self): """ Test if different models have different hashes and are evaluated as unequal """ model1 = DatabaseModel() model2 = DatabaseModel() # Change the models by saving one and giving it an id model2.post_or_put(self.db) self.assertNotEqual(hash(model1), hash(model2)) self.assertNotEqual(model1, model2)
def test_post_or_put_time(self): model = DatabaseModel() # Save the model, sign it, then save the signed version. model.post_or_put(self.db) model.sign(self.api) model.post_or_put(self.db) original_sign_time = model.time_signed # get a copy model_copy = self.db.get('database_model', model.id) self.assertEqual(original_sign_time, model_copy.time_signed) model_copy.sign(self.api) new_sign_time = model.time_signed model_copy.post_or_put(self.db) model_new_copy = self.db.get('database_model', model.id) self.assertEqual(new_sign_time, model_new_copy.time_signed) # Now we check that older models arent saved. model_new_copy._time_signed = 0 model_new_copy.post_or_put(self.db, check_time=True) model_last_copy = self.db.get('database_model', model.id) self.assertEqual(new_sign_time, model_last_copy.time_signed)
def get_all(self, _type): try: items = self.backend.get_all(_type) if items: return [DatabaseModel.decode(t) for t in items] except KeyError: return None
def test_generate_id_on_clash(self, encode_patch): encode_patch.return_value = True model = DatabaseModel() self.database.post(model.type, model) model2 = DatabaseModel() unique_id = 'unique_id' model2.generate_id = Mock() model2.generate_id.side_effect = [model.id, unique_id] self.database.post(model2.type, model2) self.assertEqual(model2.id, unique_id) self.assertEqual(model2.generate_id.call_count, 2)
def test_on_loan_request_reject(self): """ Test a bank rejecting a users loan_request bank --> user """ # Save the user-side initial data which is a pending loan request. self.loan_request.status[self.bank.id] = STATUS.PENDING self.user.loan_request_ids.append(self.loan_request.id) self.user.post_or_put(self.api.db) self.assertIn(self.loan_request.id, self.user.loan_request_ids) # Deep copy the loan request loan_request_bank = DatabaseModel.decode(self.loan_request.encode()) loan_request_bank.status[self.bank.id] = STATUS.REJECTED # Make the payload payload = FakePayload() payload.request = APIMessage.LOAN_REQUEST_REJECT payload.models = { self.loan_request.type: loan_request_bank, self.user.type: self.bank } self.community.on_loan_request_reject(payload) # Now let's pull the loan request from the user database self.assertTrue(self.isModelInDB(self.api, loan_request_bank)) loan_request = self.api.db.get(loan_request_bank.type, loan_request_bank.id) self.assertEqual(loan_request.status[self.bank.id], STATUS.REJECTED) self.assertNotIn(self.loan_request.id, self.user.loan_request_ids)
def test_signed_model(self): """ Test is models can be signed, and if the signature is read as valid """ model = DatabaseModel() model.post_or_put(self.db) pre_hash = model.generate_sha1_hash() # Sign the model model.sign(self.api) post_hash = model.generate_sha1_hash() self.assertEqual(pre_hash, post_hash) self.assertEqual(model.signer, self.db.backend.get_option('user_key_pub')) self.assertTrue(DatabaseModel.signature_valid(model))
def _decode_signed_confirm(self, placeholder, offset, data): try: offset, payload = decode(data, offset) except ValueError: raise DropPacket("Unable to decode the SignedConfirm-payload") if not isinstance(payload, tuple): raise DropPacket("Invalid payload type") # benefactor, 0 # beneficiary, 1 # agreement_benefactor_encoded, 2 # agreement_beneficiary_encoded, 3 # sequence_number_benefactor, 4 # sequence_number_beneficiary, 5 # previous_hash_benefactor, 6 # previous_hash_beneficiary, 7 # signature_benefactor, 8 # signature_beneficiary, 9 # insert_time 10 if not isinstance(payload[0], str): raise DropPacket("Invalid 'benefactor' type") if not isinstance(payload[1], str): raise DropPacket("Invalid 'beneficiary' type") #TODO: Do the rest. agreement_benefactor = DatabaseModel.decode(payload[2]) agreement_beneficiary = DatabaseModel.decode(payload[3]) return offset, placeholder.meta.payload.implement( payload[0], payload[1], agreement_benefactor, agreement_beneficiary, payload[4], payload[5], payload[6], payload[7], payload[8], payload[9], payload[10], )
def test_signed_model_detect_tamper(self): """ Test is models can be signed, and if the signature is read as valid """ model = DatabaseModel() model.post_or_put(self.db) pre_hash = model.generate_sha1_hash() # Sign the model model.sign(self.api) #Tamper with the model model._id = 'different' post_hash = model.generate_sha1_hash() self.assertNotEqual(pre_hash, post_hash) self.assertEqual(model.signer, self.db.backend.get_option('user_key_pub')) self.assertFalse(DatabaseModel.signature_valid(model))
def setUp(self): self.backend = PersistentBackend('.') # Create some data self.block1 = DatabaseModel('1') self.block2 = DatabaseModel('2') self.block3 = DatabaseModel('3')
def _decode_model(self, placeholder, offset, data): try: offset, payload = decode(data, offset) except ValueError: raise DropPacket("Unable to decode the model payload") if not isinstance(payload, tuple): raise DropPacket("Invalid payload type") fields, encoded_models = payload if not isinstance(fields, list): raise DropPacket("Invalid 'fields' type") if not isinstance(encoded_models, dict): raise DropPacket("Invalid 'models' type") decoded_models = dict() for field in fields: decoded_models[field] = DatabaseModel.decode(encoded_models[field]) return offset, placeholder.meta.payload.implement( fields, decoded_models)
def test_get(self): self.backend.clear() self.backend.post('test', self.block1.id, self.block1.encode()) self.backend.post('test', self.block2.id, self.block2.encode()) self.backend.post('test', self.block3.id, self.block3.encode()) with self.assertRaises(IndexError): self.backend.post('test2', self.block1.id, self.block1.encode()) self.assertEqual(DatabaseModel.decode(self.backend.get('test', '1')), self.block1) self.assertEqual( DatabaseModel.decode(self.backend.get('test', self.block2.id)), self.block2) self.assertNotEqual( DatabaseModel.decode(self.backend.get('test', '1')), DatabaseModel.decode(self.backend.get('test', '2'))) with self.assertRaises(IndexError): self.assertEqual( DatabaseModel.decode(self.backend.get('test', '1')), DatabaseModel.decode(self.backend.get('test2', '1')))
class PersistentBackendTestSuite(unittest.TestCase): def setUp(self): self.backend = PersistentBackend('.') # Create some data self.block1 = DatabaseModel('1') self.block2 = DatabaseModel('2') self.block3 = DatabaseModel('3') def tearDown(self): self.backend.close() def test_clear(self): self.backend.clear() self.backend.post('test', self.block1.id, self.block1) self.backend.clear() with self.assertRaises(IndexError): self.backend.get('test', self.block1.id) def test_post(self): self.backend.clear() self.backend.post('test', self.block1.id, self.block1.encode()) self.assertEqual( self.block1, DatabaseModel.decode(self.backend.get('test', self.block1.id))) def test_get(self): self.backend.clear() self.backend.post('test', self.block1.id, self.block1.encode()) self.backend.post('test', self.block2.id, self.block2.encode()) self.backend.post('test', self.block3.id, self.block3.encode()) with self.assertRaises(IndexError): self.backend.post('test2', self.block1.id, self.block1.encode()) self.assertEqual(DatabaseModel.decode(self.backend.get('test', '1')), self.block1) self.assertEqual( DatabaseModel.decode(self.backend.get('test', self.block2.id)), self.block2) self.assertNotEqual( DatabaseModel.decode(self.backend.get('test', '1')), DatabaseModel.decode(self.backend.get('test', '2'))) with self.assertRaises(IndexError): self.assertEqual( DatabaseModel.decode(self.backend.get('test', '1')), DatabaseModel.decode(self.backend.get('test2', '1'))) def test_get_error(self): self.backend.clear() with self.assertRaises(IndexError): self.backend.get('test', 1) def test_put_fail(self): self.backend.clear() self.assertFalse(self.backend.put('test', '1', self.block1)) def test_put_success(self): self.backend.clear() self.backend.post('test', self.block1.id, self.block1.encode()) self.assertEqual( DatabaseModel.decode(self.backend.get('test', self.block1.id)), self.block1) self.assertTrue( self.backend.put('test', self.block1.id, self.block2.encode())) self.assertEqual( DatabaseModel.decode(self.backend.get('test', self.block1.id)), self.block2) def test_delete(self): self.backend.clear() self.backend.post('test', self.block1.id, self.block1) self.backend.delete(self.block1) self.assertFalse(self.backend.exists('test', self.block1.id)) def test_get_all(self): self.backend.clear() self.backend.post('test', self.block1.id, self.block1.encode()) self.backend.post('test', self.block2.id, self.block2.encode()) self.backend.post('boe', self.block3.id, self.block3.encode()) all_tests = self.backend.get_all('test') self.assertIsInstance(all_tests, list) self.assertIn(self.block1.encode(), all_tests) self.assertIn(self.block2.encode(), all_tests) self.assertNotIn(self.block3.encode(), all_tests)
def test_post(self): self.backend.clear() self.backend.post('test', self.block1.id, self.block1.encode()) self.assertEqual( self.block1, DatabaseModel.decode(self.backend.get('test', self.block1.id)))
def setUp(self): self.database = MarketDatabase(PersistentBackend('.')) self.database.backend.clear() # Some database models self.model1 = DatabaseModel() self.model2 = DatabaseModel()
def setUp(self): self.database = MarketDatabase(MemoryBackend()) # Some database models self.model1 = DatabaseModel() self.model2 = DatabaseModel()
def get(self, _type, _id): try: return DatabaseModel.decode(self._backend.get(_type, _id)) except IndexError: return None