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

Reply via email to