def test_put_operation_2(self): with self.assertRaisesRegex(Operation.ChainError, "previous_operation_rev does not exist"): self.operation[2] = Operation(OperationRev.from_id( sha256(b'wrong hash').digest()), self.operation[2].address, self.operation[2].owners) sign_object(self.public_keys[0], self.private_keys[0], self.operation[1]) self.operation[2] = Operation._construct_with_uuid(OperationRev.from_obj(self.operation[1]), self.operation[2].uuid, self.operation[2].address, self.operation[2].owners) sign_object(self.public_keys[1], self.private_keys[1], self.operation[2]) with self.assertRaisesRegex(Operation.UUIDError, "UUID mismatch"): self.operation[2].put() self.operation[2] = Operation._construct_with_uuid(OperationRev(), self.operation[2].uuid, self.operation[2].address, self.operation[2].owners) sign_object(self.public_keys[1], self.private_keys[1], self.operation[2]) self.operation[2].put() with self.assertRaisesRegex(Operation.DuplicationError, "object id already in the database"): self.operation[2].put()
def get_from_queue_cb(future): op = future.result() try: Operation.get(op.id) except Operation.DoesNotExist: ops.append(op) clean_queue()
def test_3_get_and_remove(self): sign_object(self.public_key, self.private_key, self.operations[0]) self.operations[1] = Operation(OperationRev.from_obj(self.operations[0]), self.operations[1].address, self.operations[1].owners) for op in self.operations: sign_object(self.public_key, self.private_key, op) op.put() for op in self.operations: new_op = Operation.get(op.id) self.assertEqual(new_op.id, op.id) self.assertCountEqual(Operation.get_ids_list(), [op.id for op in self.operations]) self.operations[1].remove() self.operations[0].remove() self.assertCountEqual(Operation.get_ids_list(), [self.operations[2].id]) self.operations[2].remove() for op in self.operations: with self.assertRaises(Operation.DoesNotExist): op.remove() self.assertEqual(Operation.get_ids_list(), [])
def test_put_operation0_and_copy(self): sign_object(self.public_keys[0], self.private_keys[0], self.operation[0]) self.operation[0].put() copied_op = Operation(self.operation[0].previous_operation_rev, self.operation[0].address, self.operation[0].owners) sign_object(self.public_keys[1], self.private_keys[1], copied_op) with self.assertRaisesRegex(Operation.VerifyError, "trying to create a minting operation for an existing uuid"): copied_op.put()
def test_sign_operation(self): op = Operation(OperationRev(), 'http://example.com/', [PublicKey.from_signing_key(SigningKey.generate())]) user = User.new_keys() with self.assertRaisesRegex(Operation.VerifyError, "object is not signed"): op.verify() user.sign_object(op) self.assertTrue(op.verify()) self.assertEqual(op.public_key, user._public_key)
def test_owners(self): self.operation = Operation(self.operation.previous_operation_rev, self.operation.address, [self.public_key, self.public_key]) sign_object(self.public_key, self.private_key, self.operation) with self.assertRaisesRegex(Operation.VerifyError, "duplicated owners"): self.operation.verify() self.operation = Operation(self.operation.previous_operation_rev, self.operation.address, []) sign_object(self.public_key, self.private_key, self.operation) self.assertTrue(self.operation.verify())
def setUp(self): self.private_key = SigningKey.generate(curve=NIST256p) self.public_key = PublicKey.from_signing_key(self.private_key) self.operation = Operation(OperationRev(), 'http://example.com/', [self.public_key]) sign_object(self.public_key, self.private_key, self.operation)
def test_put_operation1(self): sign_object(self.public_keys[0], self.private_keys[0], self.operation[0]) self.operation[0].put() self.operation[1] = Operation._construct_with_uuid(OperationRev(), self.operation[0].uuid, self.operation[1].address, self.operation[1].owners) sign_object(self.public_keys[0], self.private_keys[0], self.operation[1]) with self.assertRaisesRegex(Operation.UUIDError, "UUID of the minting operation does not fulfill the requirements"): self.operation[1].put() self.operation[1] = Operation(OperationRev.from_obj(self.operation[0]), self.operation[1].address, self.operation[1].owners) sign_object(self.public_keys[0], self.private_keys[0], self.operation[1]) with self.assertRaises(Operation.OwnershipError): self.operation[1].put() sign_object(self.public_keys[1], self.private_keys[1], self.operation[1]) self.operation[1].put()
def test_from_raw(self): new_operation = Operation.from_raw(self.operation.raw()) self.assertIsInstance(new_operation, Operation) for attr in ('previous_operation_rev', 'uuid', 'address', 'signature'): self.assertEqual(getattr(new_operation, attr), getattr(self.operation, attr)) self.assertEqual(new_operation.owners_der, self.operation.owners_der) self.assertEqual(new_operation.public_key.der, self.operation.public_key.der)
def test_mangled_raw(self): raw = self.operation.raw() with self.assertRaisesRegex(RawFormatError, "raw input too short"): Operation.from_raw(raw[:-1]) with self.assertRaisesRegex(RawFormatError, "raw input too long"): Operation.from_raw(raw + b'\x00') with self.assertRaisesRegex(Operation.VerifyError, "wrong signature"): mangled_raw = bytearray(raw) mangled_raw[-1] = 0 Operation.from_raw(mangled_raw).verify() with self.assertRaisesRegex(Operation.VerifyError, "wrong object id"): Operation.from_raw(raw).verify_id(b'wrong hash') # wrong hash length with self.assertRaisesRegex(Operation.VerifyError, "wrong object id"): Operation.from_raw(raw).verify_id(sha256(b'wrong hash').digest()) # different hash
def test_no_database(self): with self.assertRaisesRegex(pmpi.database.Database.InitialisationError, "initialise database first"): Operation.get_ids_list() with self.assertRaisesRegex(pmpi.database.Database.InitialisationError, "initialise database first"): Operation.get(sha256(b'something').digest()) operation = Operation(OperationRev(), 'http://example.com/', []) sk = SigningKey.generate() sign_object(PublicKey.from_signing_key(sk), sk, operation) with self.assertRaisesRegex(pmpi.database.Database.InitialisationError, "initialise database first"): operation.put(BlockRev()) with self.assertRaisesRegex(pmpi.database.Database.InitialisationError, "initialise database first"): operation.remove(BlockRev())
def test_2_operation(self): sign_object(self.public_keys[1], self.private_keys[1], self.operation[0]) self.operation[1] = Operation(OperationRev.from_obj(self.operation[0]), 'http://new.example.com/', [self.public_keys[2]]) sign_object(self.public_keys[2], self.private_keys[2], self.operation[1]) self.operation[2] = Operation._construct_with_uuid(OperationRev.from_obj(self.operation[1]), uuid4(), 'http://new2.example.com', []) with self.assertRaisesRegex(Operation.UUIDError, "UUID mismatch"): sign_object(self.public_keys[2], self.private_keys[2], self.operation[2]) self.operation[2].verify() self.operation[2] = Operation(OperationRev.from_obj(self.operation[1]), 'http://new2.example.com', []) sign_object(self.public_keys[2], self.private_keys[2], self.operation[2]) self.operation[2].verify()
def test_2_put(self): sign_object(self.public_key, self.private_key, self.operations[0]) self.operations[0].put() with self.assertRaisesRegex(Operation.DuplicationError, "object id already in the database"): self.operations[0].put() self.operations[1] = Operation(OperationRev.from_obj(self.operations[0]), self.operations[1].address, self.operations[1].owners) sign_object(self.public_key, self.private_key, self.operations[1]) self.operations[1].put() sign_object(self.public_key, self.private_key, self.operations[2]) self.operations[2].put() revision_id_list = Operation.get_ids_list() self.assertEqual(len(revision_id_list), 3) self.assertCountEqual(revision_id_list, [op.id for op in self.operations])
def process_operation(self, raw_operation): op = Operation.from_raw(raw_operation) future = asyncio.ensure_future(operation_queue.put(op)) future.add_done_callback(self.new_block)
def test_0_empty(self): self.assertEqual(len(Operation.get_ids_list()), 0)
def test_1_get_from_empty(self): with self.assertRaises(Operation.DoesNotExist): sign_object(self.public_key, self.private_key, self.operations[0]) Operation.get(self.operations[0].id)
class TestSingleOperation(TestCase): def setUp(self): self.private_key = SigningKey.generate(curve=NIST256p) self.public_key = PublicKey.from_signing_key(self.private_key) self.operation = Operation(OperationRev(), 'http://example.com/', [self.public_key]) sign_object(self.public_key, self.private_key, self.operation) def test_fields(self): self.assertEqual(self.operation.previous_operation_rev, OperationRev()) self.assertEqual(self.operation.address, 'http://example.com/') self.assertEqual(self.operation.owners, (self.public_key,)) self.assertEqual(self.operation.public_key, self.public_key) # noinspection PyPropertyAccess def test_immutable(self): with self.assertRaisesRegex(AttributeError, "can't set attribute"): self.operation.previous_operation_rev = OperationRev() with self.assertRaisesRegex(AttributeError, "can't set attribute"): self.operation.uuid = uuid4() with self.assertRaisesRegex(AttributeError, "can't set attribute"): self.operation.address = 'http://changed.com/' with self.assertRaisesRegex(AttributeError, "can't set attribute"): self.operation.owners = [] def test_unsigned_raw(self): unsigned_raw = self.operation.unsigned_raw() self.assertIsInstance(unsigned_raw, bytes) self.assertEqual(unsigned_raw[:36], b'\x00\x00\x00\x01' + b'\x00' * 32) self.assertEqual(len(unsigned_raw), 4 + 32 + 16 + 4 + len('http://example.com/') + 4 + 4 + len(self.public_key.der)) def test_raw(self): raw = self.operation.raw() unsigned_raw = self.operation.unsigned_raw() self.assertIsInstance(raw, bytes) self.assertEqual(raw[:len(unsigned_raw)], self.operation.unsigned_raw()) self.assertEqual(len(raw), len(unsigned_raw) + 4 + len(self.public_key.der) + 4 + len(self.operation.signature)) def test_from_raw(self): new_operation = Operation.from_raw(self.operation.raw()) self.assertIsInstance(new_operation, Operation) for attr in ('previous_operation_rev', 'uuid', 'address', 'signature'): self.assertEqual(getattr(new_operation, attr), getattr(self.operation, attr)) self.assertEqual(new_operation.owners_der, self.operation.owners_der) self.assertEqual(new_operation.public_key.der, self.operation.public_key.der) def test_verify(self): self.assertTrue(self.operation.verify()) def test_mangled_raw(self): raw = self.operation.raw() with self.assertRaisesRegex(RawFormatError, "raw input too short"): Operation.from_raw(raw[:-1]) with self.assertRaisesRegex(RawFormatError, "raw input too long"): Operation.from_raw(raw + b'\x00') with self.assertRaisesRegex(Operation.VerifyError, "wrong signature"): mangled_raw = bytearray(raw) mangled_raw[-1] = 0 Operation.from_raw(mangled_raw).verify() with self.assertRaisesRegex(Operation.VerifyError, "wrong object id"): Operation.from_raw(raw).verify_id(b'wrong hash') # wrong hash length with self.assertRaisesRegex(Operation.VerifyError, "wrong object id"): Operation.from_raw(raw).verify_id(sha256(b'wrong hash').digest()) # different hash def test_owners(self): self.operation = Operation(self.operation.previous_operation_rev, self.operation.address, [self.public_key, self.public_key]) sign_object(self.public_key, self.private_key, self.operation) with self.assertRaisesRegex(Operation.VerifyError, "duplicated owners"): self.operation.verify() self.operation = Operation(self.operation.previous_operation_rev, self.operation.address, []) sign_object(self.public_key, self.private_key, self.operation) self.assertTrue(self.operation.verify())