Author: [email protected]
Date: Thu May 5 09:53:07 2011
New Revision: 1096
Log:
[AMDATUCASSANDRA-36] Added unit test to reproduce the consistency issue for the
Hector PM and Thrift PM. The Thrift PM unit test has been disabled, as it will
fail.
Added:
trunk/amdatu-cassandra/cassandra-persistencemanager/src/test/java/org/amdatu/cassandra/persistencemanager/EventualConsistencyHectorTest.java
trunk/amdatu-cassandra/cassandra-persistencemanager/src/test/java/org/amdatu/cassandra/persistencemanager/EventualConsistencyThriftTest.java
trunk/amdatu-cassandra/cassandra-persistencemanager/src/test/java/org/amdatu/cassandra/persistencemanager/UnitTestBase.java
Modified:
trunk/amdatu-cassandra/cassandra-persistencemanager/src/test/java/org/amdatu/cassandra/persistencemanager/PersistenceManagerTest.java
Added:
trunk/amdatu-cassandra/cassandra-persistencemanager/src/test/java/org/amdatu/cassandra/persistencemanager/EventualConsistencyHectorTest.java
==============================================================================
--- (empty file)
+++
trunk/amdatu-cassandra/cassandra-persistencemanager/src/test/java/org/amdatu/cassandra/persistencemanager/EventualConsistencyHectorTest.java
Thu May 5 09:53:07 2011
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2010, 2011 The Amdatu Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.amdatu.cassandra.persistencemanager;
+
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+public class EventualConsistencyHectorTest extends UnitTestBase {
+ private static final org.apache.log4j.Logger LOG =
org.apache.log4j.Logger.getLogger(EventualConsistencyHectorTest.class);
+
+ private static final String TEST_CF = "ECHT_ColumnFamily";
+ private static final String TEST_COLUMN_STRING = "ECHT_ColumnString";
+ private static final String TEST_COLUMN_BYTES = "ECHT_ColumnBytes";
+ private static final String DEFAULT_CHARSET = "UTF-8";
+
+ protected void setup() throws Exception {
+ super.setup();
+ m_daemon.addColumnFamily(TEST_KEYSPACE_HECTOR, TEST_CF, "Standard",
"BytesType", null);
+ }
+
+ @Test
+ public void testAll() throws Exception {
+ LOG.info("Starting unit tests");
+ setup();
+
+ // The test consists of writing value i into column c and then reading
the value from column c.
+ // We expect that the value read from c is always the same as the
value written to c just before
+ // reading it, however, in Cassandra this appears not to be the case.
+ long before = System.currentTimeMillis();
+ for (int i=0; i<1000; i++) {
+ int randomNumber = new Double(Math.floor(10000 *
Math.random())).intValue();
+ String writeValue = "amdatutest-" + randomNumber;
+
+ m_hectorPM.setValue(TEST_CF, "row", null, TEST_COLUMN_STRING,
writeValue);
+ String readValue = m_hectorPM.getValue(TEST_CF, "row", null,
TEST_COLUMN_STRING, String.class);
+ Assert.assertEquals(writeValue, readValue);
+
+ m_hectorPM.setValue(TEST_CF, "row", null, TEST_COLUMN_BYTES,
writeValue.getBytes(DEFAULT_CHARSET));
+ byte[] bReadValue = m_hectorPM.getValue(TEST_CF, "row", null,
TEST_COLUMN_BYTES, byte[].class);
+ Assert.assertEquals(writeValue, new String(bReadValue,
DEFAULT_CHARSET));
+ }
+ long after = System.currentTimeMillis();
+
+ LOG.info("Unit tests finished in " + (after-before) + " milliseconds");
+ }
+}
Added:
trunk/amdatu-cassandra/cassandra-persistencemanager/src/test/java/org/amdatu/cassandra/persistencemanager/EventualConsistencyThriftTest.java
==============================================================================
--- (empty file)
+++
trunk/amdatu-cassandra/cassandra-persistencemanager/src/test/java/org/amdatu/cassandra/persistencemanager/EventualConsistencyThriftTest.java
Thu May 5 09:53:07 2011
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2010, 2011 The Amdatu Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.amdatu.cassandra.persistencemanager;
+
+import junit.framework.Assert;
+
+public class EventualConsistencyThriftTest extends UnitTestBase {
+ private static final org.apache.log4j.Logger LOG =
org.apache.log4j.Logger.getLogger(EventualConsistencyHectorTest.class);
+
+ private static final String TEST_CF = "ECTT_uperColumnFamily";
+ private static final String TEST_SUPER_COLUMN = "ECTT_SuperColumn";
+ private static final String TEST_COLUMN_STRING = "ECTT_ColumnString";
+ private static final String TEST_COLUMN_BYTES = "ECTT_ColumnBytes";
+ private static final String DEFAULT_CHARSET = "UTF-8";
+
+ protected void setup() throws Exception {
+ super.setup();
+ m_daemon.addColumnFamily(TEST_KEYSPACE_THRIFT, TEST_CF, "Super",
"BytesType", "BytesType");
+ }
+
+ // NB: This test is disabled, as it was created to verify that using the
Thrift PM this code snippet
+ // fails while it works fine using the Hector PM.
+ // @Test
+ public void testAll() throws Exception {
+ LOG.info("Starting unit tests");
+ setup();
+
+ // The test consists of writing value i into column c and then reading
the value from column c.
+ // We expect that the value read from c is always the same as the
value written to c just before
+ // reading it, however, in Cassandra this appears not to be the case.
+ long before = System.currentTimeMillis();
+ for (int i=0; i<1000; i++) {
+ int randomNumber = new Double(Math.floor(10000 *
Math.random())).intValue();
+ String writeValue = "amdatutest-" + randomNumber;
+
+ m_thriftPM.setStringValue(TEST_CF, "row", TEST_SUPER_COLUMN,
TEST_COLUMN_STRING, writeValue);
+ String readValue = m_thriftPM.getStringValue(TEST_CF, "row",
TEST_SUPER_COLUMN, TEST_COLUMN_STRING);
+ Assert.assertEquals(writeValue, readValue);
+
+ m_thriftPM.setValue(TEST_CF, "row", TEST_SUPER_COLUMN,
TEST_COLUMN_BYTES, writeValue.getBytes(DEFAULT_CHARSET));
+ byte[] bReadValue = m_thriftPM.getValue(TEST_CF, "row",
TEST_SUPER_COLUMN, TEST_COLUMN_BYTES);
+ Assert.assertEquals(writeValue, new String(bReadValue,
DEFAULT_CHARSET));
+ }
+ long after = System.currentTimeMillis();
+
+ LOG.info("Unit tests finished in " + (after-before) + " milliseconds");
+ }
+}
Modified:
trunk/amdatu-cassandra/cassandra-persistencemanager/src/test/java/org/amdatu/cassandra/persistencemanager/PersistenceManagerTest.java
==============================================================================
---
trunk/amdatu-cassandra/cassandra-persistencemanager/src/test/java/org/amdatu/cassandra/persistencemanager/PersistenceManagerTest.java
(original)
+++
trunk/amdatu-cassandra/cassandra-persistencemanager/src/test/java/org/amdatu/cassandra/persistencemanager/PersistenceManagerTest.java
Thu May 5 09:53:07 2011
@@ -15,92 +15,43 @@
*/
package org.amdatu.cassandra.persistencemanager;
-import java.io.IOException;
-import java.io.Serializable;
-import java.io.UnsupportedEncodingException;
-import java.net.URISyntaxException;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Iterator;
-import java.util.List;
-import java.util.UUID;
-
-import me.prettyprint.hector.api.beans.HColumn;
-import me.prettyprint.hector.api.beans.HSuperColumn;
-import me.prettyprint.hector.api.beans.Row;
-import me.prettyprint.hector.api.beans.SuperRow;
-
-import org.amdatu.cassandra.application.CassandraConfigurationService;
-import
org.amdatu.cassandra.persistencemanager.mock.CassandraConfigurationServiceMock;
-import org.amdatu.cassandra.persistencemanager.mock.CassandraDaemonMock;
-import org.amdatu.cassandra.persistencemanager.mock.LogServiceMock;
-import
org.amdatu.cassandra.persistencemanager.service.HectorCassandraPersistenceManagerImpl;
-import
org.amdatu.cassandra.persistencemanager.service.ThriftCassandraPersistenceManagerImpl;
-import org.apache.cassandra.thrift.InvalidRequestException;
-import org.apache.cassandra.thrift.NotFoundException;
-import org.apache.thrift.TException;
-import org.junit.Assert;
-import org.junit.Test;
+import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.UUID;
+
+import me.prettyprint.hector.api.beans.HColumn;
+import me.prettyprint.hector.api.beans.HSuperColumn;
+import me.prettyprint.hector.api.beans.Row;
+import me.prettyprint.hector.api.beans.SuperRow;
+
+import org.junit.Assert;
+import org.junit.Test;
@SuppressWarnings("deprecation")
-public class PersistenceManagerTest {
+public class PersistenceManagerTest extends UnitTestBase {
private static final org.apache.log4j.Logger LOG =
org.apache.log4j.Logger.getLogger(PersistenceManagerTest.class);
- private static final String TEST_KEYSPACE_HECTOR =
"PMUnitTestHectorKeyspace";
- private static final String TEST_KEYSPACE_THRIFT =
"PMUnitTestThriftKeyspace";
private static final String TEST_SUPER_CF = "PMUnitTestSuperColumnFamily";
private static final String TEST_STANDARD_CF =
"PMUnitTestStandardColumnFamily";
private static final String TEST_SUPERCOLUMN = "PMUnitTestSuperColumn";
private static final String TEST_COLUMN = "PMUnitTestColumn";
- private CassandraDaemonMock m_daemon;
- private HectorCassandraPersistenceManagerImpl m_hectorPM;
- private ThriftCassandraPersistenceManagerImpl m_thriftPM;
-
- private void startDaemon() throws InvalidRequestException, TException,
URISyntaxException, NotFoundException,
- InterruptedException, IOException {
- // Start a new Cassandra daemon
- CassandraConfigurationService config = new
CassandraConfigurationServiceMock();
- m_daemon = new CassandraDaemonMock();
- m_daemon.init();
-
- Thread startThread = m_daemon.new
CassandraDaemonStartThread(m_daemon.getDaemon());
- startThread.setDaemon(true);
- startThread.start();
- startThread.join();
-
- // Setup Hector and Thrift persistence managers
- m_hectorPM = new HectorCassandraPersistenceManagerImpl();
- m_hectorPM.setDaemonService(m_daemon);
- m_hectorPM.setConfigurationService(config);
- m_hectorPM.setLogService(new LogServiceMock());
- m_hectorPM.setKeyspace(TEST_KEYSPACE_HECTOR);
- m_thriftPM = new ThriftCassandraPersistenceManagerImpl();
- m_thriftPM.setDaemonService(m_daemon);
- m_thriftPM.setConfigurationService(config);
- m_thriftPM.setLogService(new LogServiceMock());
- m_thriftPM.setKeyspace(TEST_KEYSPACE_THRIFT);
-
- // Create a test keyspace
- m_daemon.addKeyspace(TEST_KEYSPACE_HECTOR);
- m_daemon.addKeyspace(TEST_KEYSPACE_THRIFT);
+ protected void setup() throws Exception {
+ super.setup();
m_daemon.addColumnFamily(TEST_KEYSPACE_HECTOR, TEST_SUPER_CF, "Super",
"BytesType", "BytesType");
m_daemon.addColumnFamily(TEST_KEYSPACE_THRIFT, TEST_SUPER_CF, "Super",
"BytesType", "BytesType");
m_daemon.addColumnFamily(TEST_KEYSPACE_HECTOR, TEST_STANDARD_CF,
"Standard", "BytesType", null);
m_daemon.addColumnFamily(TEST_KEYSPACE_THRIFT, TEST_STANDARD_CF,
"Standard", "BytesType", null);
}
-
- /**
- * We run all tests in a single execution since Cassandra does not support
shutdown. So when a second
- * test will be executed and a new daemon is spawned, it may fail to
startup as the previous daemon
- * is still running (on the same hostname/port).
- *
- * @throws Exception
- */
+
@Test
- public void testAll() throws Exception {
+ public void run() throws Exception {
LOG.info("Starting unit tests");
- startDaemon();
+ setup();
// Remove all rows first
deleteAllRows(TEST_SUPER_CF);
Added:
trunk/amdatu-cassandra/cassandra-persistencemanager/src/test/java/org/amdatu/cassandra/persistencemanager/UnitTestBase.java
==============================================================================
--- (empty file)
+++
trunk/amdatu-cassandra/cassandra-persistencemanager/src/test/java/org/amdatu/cassandra/persistencemanager/UnitTestBase.java
Thu May 5 09:53:07 2011
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2010, 2011 The Amdatu Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.amdatu.cassandra.persistencemanager;
+
+import org.amdatu.cassandra.application.CassandraConfigurationService;
+import
org.amdatu.cassandra.persistencemanager.mock.CassandraConfigurationServiceMock;
+import org.amdatu.cassandra.persistencemanager.mock.CassandraDaemonMock;
+import org.amdatu.cassandra.persistencemanager.mock.LogServiceMock;
+import
org.amdatu.cassandra.persistencemanager.service.HectorCassandraPersistenceManagerImpl;
+import
org.amdatu.cassandra.persistencemanager.service.ThriftCassandraPersistenceManagerImpl;
+
+/**
+ * An important disadvantage of the Cassandra daemon is that is does not
support in-VM shutdown. It will
+ * only properly shutdown when the VM shuts down (as it is implemented by VM
shutdown hooks).
+ * So when a second unit test will be executed, it is executed in the same VM
and so the previous
+ * Cassandra daemon will still be running, preventing the capability to spawn
a new daemon in that very
+ * same VM. As a result, running multiple unit tests would fail.
+ * For that reason, we define a base class that creates the daemon and
persistence managers and stores
+ * them in static references, such that they will be reused by all unit tests
executed in this VM.
+ *
+ * @throws Exception
+ */
+@SuppressWarnings("deprecation")
+public class UnitTestBase {
+ private static boolean INITIALIZED = false;
+
+ public static final String TEST_KEYSPACE_HECTOR =
"PMUnitTestHectorKeyspace";
+ public static final String TEST_KEYSPACE_THRIFT =
"PMUnitTestThriftKeyspace";
+
+ protected static CassandraDaemonMock m_daemon;
+ protected static HectorCassandraPersistenceManagerImpl m_hectorPM;
+ protected static ThriftCassandraPersistenceManagerImpl m_thriftPM;
+
+ protected void setup() throws Exception {
+ if (!INITIALIZED) {
+ INITIALIZED = true;
+
+ // Start a new Cassandra daemon
+ CassandraConfigurationService config = new
CassandraConfigurationServiceMock();
+ m_daemon = new CassandraDaemonMock();
+ m_daemon.init();
+
+ Thread startThread = m_daemon.new
CassandraDaemonStartThread(m_daemon.getDaemon());
+ startThread.setDaemon(true);
+ startThread.start();
+ startThread.join();
+
+ m_daemon.addKeyspace(TEST_KEYSPACE_HECTOR);
+ m_daemon.addKeyspace(TEST_KEYSPACE_THRIFT);
+
+ // Setup Hector and Thrift persistence managers
+ m_thriftPM = new ThriftCassandraPersistenceManagerImpl();
+ m_thriftPM.setDaemonService(m_daemon);
+ m_thriftPM.setConfigurationService(config);
+ m_thriftPM.setLogService(new LogServiceMock());
+ m_thriftPM.setKeyspace(TEST_KEYSPACE_THRIFT);
+
+ m_hectorPM = new HectorCassandraPersistenceManagerImpl();
+ m_hectorPM.setDaemonService(m_daemon);
+ m_hectorPM.setConfigurationService(config);
+ m_hectorPM.setLogService(new LogServiceMock());
+ m_hectorPM.setKeyspace(TEST_KEYSPACE_HECTOR);
+ }
+ }
+}
_______________________________________________
Amdatu-commits mailing list
[email protected]
http://lists.amdatu.org/mailman/listinfo/amdatu-commits