@Test
public void testTransactionSerialization() throws Exception {
// create and initialize a transaction
BabuDBTransaction txn = new BabuDBTransaction();
txn.createDatabase("db1", 5);
txn.createDatabase("db1", 1, new ByteRangeComparator[] { new DefaultByteRangeComparator() });
txn.insertRecord("db1", 3, "hello".getBytes(), "world".getBytes());
txn.deleteRecord("db2", 1, "blub".getBytes());
txn.deleteDatabase("db1");
txn.insertRecord("new-database", 3, "x".getBytes(), "".getBytes());
// check transaction
assertEquals(6, txn.getOperations().size());
assertEquals(Operation.TYPE_CREATE_DB, txn.getOperations().get(0).getType());
assertEquals("db1", txn.getOperations().get(0).getDatabaseName());
assertEquals(2, txn.getOperations().get(0).getParams().length);
assertEquals(Operation.TYPE_CREATE_DB, txn.getOperations().get(1).getType());
assertEquals("db1", txn.getOperations().get(1).getDatabaseName());
assertEquals(2, txn.getOperations().get(1).getParams().length);
assertEquals(Operation.TYPE_GROUP_INSERT, txn.getOperations().get(2).getType());
assertEquals("db1", txn.getOperations().get(2).getDatabaseName());
assertEquals(2, txn.getOperations().get(2).getParams().length);
assertEquals(Operation.TYPE_GROUP_INSERT, txn.getOperations().get(3).getType());
assertEquals("db2", txn.getOperations().get(3).getDatabaseName());
assertEquals(2, txn.getOperations().get(3).getParams().length);
assertEquals(Operation.TYPE_DELETE_DB, txn.getOperations().get(4).getType());
assertEquals("db1", txn.getOperations().get(4).getDatabaseName());
assertNull(txn.getOperations().get(4).getParams());
assertEquals(Operation.TYPE_GROUP_INSERT, txn.getOperations().get(5).getType());
assertEquals("new-database", txn.getOperations().get(5).getDatabaseName());
assertEquals(2, txn.getOperations().get(5).getParams().length);
// test of the aggregate function
byte aggregate = txn.aggregateOperationTypes();
assertTrue(TransactionInternal.containsOperationType(aggregate, Operation.TYPE_CREATE_DB));
assertTrue(TransactionInternal.containsOperationType(aggregate, Operation.TYPE_CREATE_DB));
assertTrue(TransactionInternal.containsOperationType(aggregate, Operation.TYPE_GROUP_INSERT));
assertTrue(TransactionInternal.containsOperationType(aggregate, Operation.TYPE_DELETE_DB));
assertTrue(TransactionInternal.containsOperationType(aggregate, Operation.TYPE_DELETE_DB));
assertFalse(TransactionInternal.containsOperationType(aggregate, Operation.TYPE_CREATE_SNAP));
// serialize transaction to buffer
int size = txn.getSize();
ReusableBuffer buf = BufferPool.allocate(size);
txn.serialize(buf);
assertEquals(buf.position(), size);
// deserialize transaction from buffer
buf.position(0);
TransactionInternal txn2 = TransactionInternal.deserialize(buf);
assertEquals(buf.position(), size);
// compare original transaction with deserialized transaction
assertEquals(txn.getSize(), txn2.getSize());
assertEquals(txn.getOperations().size(), txn2.getOperations().size());
for (int i = 0; i < txn.getOperations().size(); i++) {
Operation op1 = txn.getOperations().get(i);
Operation op2 = txn2.getOperations().get(i);
// count legal parameters
int count = 0;
if (op1.getParams() != null) {