package edu.brown.hstore; import org.voltdb.catalog.Procedure; import edu.brown.BaseTestCase; import edu.brown.benchmark.tm1.procedures.UpdateLocation; import edu.brown.hstore.Hstoreservice.WorkFragment; import edu.brown.hstore.conf.HStoreConf; import edu.brown.hstore.internal.InternalMessage; import edu.brown.hstore.internal.StartTxnMessage; import edu.brown.hstore.internal.UtilityWorkMessage; import edu.brown.hstore.internal.WorkFragmentMessage; import edu.brown.hstore.txns.LocalTransaction; import edu.brown.utils.PartitionSet; import edu.brown.utils.ProjectType; public class TestPartitionMessageQueue extends BaseTestCase { private static final int NUM_PARTITIONS = 5; private static final int BASE_PARTITION = 1; private static long NEXT_TXN_ID = 1; private final PartitionMessageQueue queue = new PartitionMessageQueue(); private MockHStoreSite hstore_site; private Procedure catalog_proc; private LocalTransaction ts0; private LocalTransaction ts1; private final WorkFragment mockFragment = null; private StartTxnMessage startMsg; private WorkFragmentMessage workMsg; private UtilityWorkMessage utilMsg; @Override protected void setUp() throws Exception { super.setUp(ProjectType.TM1); this.addPartitions(NUM_PARTITIONS); this.hstore_site = new MockHStoreSite(0, catalogContext, HStoreConf.singleton()); this.catalog_proc = this.getProcedure(UpdateLocation.class); this.ts0 = new LocalTransaction(this.hstore_site); this.ts0.testInit(NEXT_TXN_ID++, BASE_PARTITION, null, catalogContext.getAllPartitionIds(), catalog_proc); this.ts1 = new LocalTransaction(this.hstore_site); this.ts1.testInit(NEXT_TXN_ID++, BASE_PARTITION, null, new PartitionSet(BASE_PARTITION), catalog_proc); // Initialize some messages that we can use this.utilMsg = new UtilityWorkMessage(); this.startMsg = new StartTxnMessage(ts1); this.workMsg = new WorkFragmentMessage(ts1, mockFragment); } private void checkOutputOrder(InternalMessage target, InternalMessage messages[]) { boolean ret; InternalMessage next = null; // First try them one by one for (InternalMessage m : messages) { this.queue.clear(); ret = this.queue.add(m); assertTrue(ret); assertEquals(m, this.queue.peek()); // We should always get back the finish ret = this.queue.add(target); System.err.println(this.queue); assertTrue(ret); assertEquals(target, this.queue.peek()); next = this.queue.poll(); assertEquals(target, next); // And our first guy is still there! assertEquals(m, this.queue.peek()); } // FOR // Now add them all at once, just to make sure that always get the // target message back first this.queue.clear(); for (InternalMessage m : messages) { ret = this.queue.add(m); assertTrue(ret); } // FOR ret = this.queue.add(target); assertTrue(ret); assertEquals(target, this.queue.peek()); next = this.queue.poll(); assertEquals(target, next); } /** * testWorkBeforeOthers */ public void testWorkBeforeOthers() throws Exception { InternalMessage messages[] = { utilMsg, startMsg }; this.checkOutputOrder(workMsg, messages); } /** * testTransactionIdOrder */ public void testTransactionIdOrder() throws Exception { StartTxnMessage start0 = new StartTxnMessage(ts1); StartTxnMessage start1 = new StartTxnMessage(ts0); assert(start1.getTransactionId() < start0.getTransactionId()); // We'll add the our messages and make sure that we get the one with the // smaller txnId back first boolean ret; ret = this.queue.add(start0); assertTrue(ret); ret = this.queue.add(start1); assertTrue(ret); assertEquals(start1, this.queue.peek()); InternalMessage next = this.queue.poll(); assertEquals(start1, next); next = this.queue.poll(); assertEquals(start0, next); } }