/*************************************************************************** * Copyright (C) 2011 by H-Store Project * * Brown University * * Massachusetts Institute of Technology * * Yale University * * * * Permission is hereby granted, free of charge, to any person obtaining * * a copy of this software and associated documentation files (the * * "Software"), to deal in the Software without restriction, including * * without limitation the rights to use, copy, modify, merge, publish, * * distribute, sublicense, and/or sell copies of the Software, and to * * permit persons to whom the Software is furnished to do so, subject to * * the following conditions: * * * * The above copyright notice and this permission notice shall be * * included in all copies or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.* * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR * * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * * OTHER DEALINGS IN THE SOFTWARE. * ***************************************************************************/ package edu.brown.hstore.cmdlog; import java.io.File; import java.util.concurrent.atomic.AtomicLong; import org.junit.Test; import org.voltdb.ClientResponseImpl; import org.voltdb.VoltProcedure; import org.voltdb.catalog.Procedure; import org.voltdb.catalog.Site; import edu.brown.BaseTestCase; import edu.brown.benchmark.tm1.procedures.UpdateLocation; import edu.brown.benchmark.tm1.procedures.UpdateSubscriberData; import edu.brown.hstore.HStoreConstants; import edu.brown.hstore.HStoreSite; import edu.brown.hstore.Hstoreservice.Status; import edu.brown.hstore.MockHStoreSite; import edu.brown.hstore.cmdlog.CommandLogReader; import edu.brown.hstore.cmdlog.CommandLogWriter; import edu.brown.hstore.cmdlog.LogEntry; import edu.brown.hstore.conf.HStoreConf; import edu.brown.hstore.txns.LocalTransaction; import edu.brown.utils.CollectionUtil; import edu.brown.utils.FileUtil; import edu.brown.utils.PartitionSet; import edu.brown.utils.ProjectType; /** * @author mkirsch * @author pavlo */ public class TestCommandLogger extends BaseTestCase { static final AtomicLong TXN_ID = new AtomicLong(1000); static final int BASE_PARTITION = 0; @SuppressWarnings("unchecked") static final Class<? extends VoltProcedure>[] TARGET_PROCS = (Class<? extends VoltProcedure>[])new Class<?>[]{ UpdateLocation.class, UpdateSubscriberData.class }; static final Object TARGET_PARAMS[][] = new Object[][]{ { 12345l, "ABCDEF"}, { 666l, 777l, 888l, 999l} }; HStoreSite hstore_site; CommandLogWriter logger; Thread loggerThread; Procedure catalog_procs[]; File outputFile; @Override protected void setUp() throws Exception { super.setUp(ProjectType.TM1); this.catalog_procs = new Procedure[TARGET_PROCS.length]; for (int i = 0; i < this.catalog_procs.length; i++) { this.catalog_procs[i] = this.getProcedure(TARGET_PROCS[i]); } // FOR HStoreConf hstore_conf = HStoreConf.singleton(); hstore_conf.site.commandlog_enable = false; hstore_conf.site.commandlog_timeout = 1000; Site catalog_site = CollectionUtil.first(catalogContext.sites); hstore_site = new MockHStoreSite(catalog_site.getId(), catalogContext, hstore_conf); assert(hstore_site.isLocalPartition(0)); outputFile = FileUtil.getTempFile("log"); logger = new CommandLogWriter(hstore_site, outputFile); loggerThread = new Thread(this.logger); loggerThread.setDaemon(true); loggerThread.start(); } @Override public void tearDown() throws Exception { if (outputFile != null && outputFile.exists()) outputFile.delete(); } @Test public void testWithGroupCommit() throws Exception { // Write out a new txn invocation to the log int num_txns = 1000; long txnId[] = new long[num_txns]; for (int i = 0; i < num_txns; i++) { LocalTransaction ts = new LocalTransaction(hstore_site); txnId[i] = TXN_ID.incrementAndGet(); ts.testInit(txnId[i], BASE_PARTITION, new PartitionSet(BASE_PARTITION), catalog_procs[i % 2], TARGET_PARAMS[i % 2]); ClientResponseImpl cresponse = new ClientResponseImpl(txnId[i], 0l, BASE_PARTITION, Status.OK, HStoreConstants.EMPTY_RESULT, ""); boolean ret = logger.appendToLog(ts, cresponse); assertFalse(ret); } logger.flush(); //This makes sure everything is written to the file logger.shutdown(); // This closes the file // Now read in the file back in and check to see that we have two // entries that have our expected information CommandLogReader reader = new CommandLogReader(outputFile.getAbsolutePath()); int ctr = 0; for (LogEntry entry : reader) { assertNotNull(entry); assertEquals(txnId[ctr], entry.getTransactionId().longValue()); assertEquals(catalog_procs[ctr % 2].getId(), entry.getProcedureId()); Object[] entryParams = entry.getProcedureParams().toArray(); assertEquals(TARGET_PARAMS[ctr % 2].length, entryParams.length); for (int i = 0; i < TARGET_PARAMS[ctr % 2].length; i++) assertEquals(TARGET_PARAMS[ctr % 2][i], entryParams[i]); ctr++; } assertEquals(txnId.length, ctr); } }