Permalink
Browse files

add unit tests, state that recovery is not implemented for serializab…

…ility
  • Loading branch information...
Maysam Yabandeh
Maysam Yabandeh committed May 18, 2012
1 parent 64eca47 commit a129898ce9d5f48e9c0827fd74f49b460405c7f7
@@ -101,7 +101,7 @@ public void addElder(long ts, long tc, RowKey[] wwRows) {
public boolean reincarnateElder(long id) {
boolean itWasFailed;
synchronized (this) {
- assert(eldest == null || eldest.getId() < id);
+ assert(eldest == null || eldest.getId() <= id);
Elder e = new Elder(id);
boolean isStillElder = setofelders.remove(e);
itWasFailed = false;
@@ -226,6 +226,10 @@ public void readComplete(int rc, LedgerHandle lh, Enumeration<LedgerEntry> entri
@Override
public TSOState buildState()
throws LoggerException {
+ //The buildState is not implemented for isolation levels that do not check for write-write conflicts. We can remove this exception throwing, after implementing that.
+ if (!com.yahoo.omid.IsolationLevel.checkForWriteWriteConflicts)
+ throws LoggerException.create(Code.LOGGERDISABLED);
+
try{
CountDownLatch latch = new CountDownLatch(1);
@@ -0,0 +1,216 @@
+/**
+ * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
+ *
+ * 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. See accompanying LICENSE file.
+ */
+
+package com.yahoo.omid;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.HColumnDescriptor;
+import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.client.Delete;
+import org.apache.hadoop.hbase.client.Get;
+import org.apache.hadoop.hbase.client.HBaseAdmin;
+import org.apache.hadoop.hbase.client.Put;
+import org.apache.hadoop.hbase.client.Result;
+import org.apache.hadoop.hbase.client.ResultScanner;
+import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.junit.Test;
+
+import com.yahoo.omid.client.CommitUnsuccessfulException;
+import com.yahoo.omid.client.TransactionManager;
+import com.yahoo.omid.client.TransactionState;
+import com.yahoo.omid.client.TransactionalTable;
+
+public class TestIsolationLevels extends OmidTestBase {
+ private static final Log LOG = LogFactory.getLog(TestIsolationLevels.class);
+
+ @Test
+ public void runTestWriteWriteConflict() throws Exception {
+ TransactionManager tm = new TransactionManager(conf);
+ TransactionalTable tt = new TransactionalTable(conf, TEST_TABLE);
+
+ TransactionState t1 = tm.beginTransaction();
+ LOG.info("Transaction created " + t1);
+
+ TransactionState t2 = tm.beginTransaction();
+ LOG.info("Transaction created" + t2);
+
+ byte[] row = Bytes.toBytes("test-simple");
+ byte[] fam = Bytes.toBytes(TEST_FAMILY);
+ byte[] col = Bytes.toBytes("testdata");
+ byte[] data1 = Bytes.toBytes("testWrite-1");
+ byte[] data2 = Bytes.toBytes("testWrite-2");
+
+ Put p = new Put(row);
+ p.add(fam, col, data1);
+ tt.put(t1, p);
+
+ Put p2 = new Put(row);
+ p2.add(fam, col, data2);
+ tt.put(t2, p2);
+
+ tm.tryCommit(t2);
+
+ boolean aborted = false;
+ try {
+ tm.tryCommit(t1);
+ assertFalse("Transaction commited successfully, despite the check for write-write conflicts", IsolationLevel.checkForWriteWriteConflicts);
+ } catch (CommitUnsuccessfulException e) {
+ aborted = true;
+ assertTrue("Transaction aborted even though check for write-write conflicts is not set", IsolationLevel.checkForWriteWriteConflicts);
+ }
+
+ if (!aborted) {
+ //check the read snapshot property
+ TransactionState tread = tm.beginTransaction();
+ LOG.info("Transaction created" + tread);
+ Get g = new Get(row).setMaxVersions(1);
+ Result r = tt.get(tread, g);
+ boolean isTheLastCommitRead = Bytes.equals(data1, r.getValue(fam, col));
+ assertTrue("The last committed value is not visible.", isTheLastCommitRead);
+ }
+ }
+
+ @Test
+ public void runTestReadWriteConflict() throws Exception {
+ TransactionManager tm = new TransactionManager(conf);
+ TransactionalTable tt = new TransactionalTable(conf, TEST_TABLE);
+
+ TransactionState t1 = tm.beginTransaction();
+ LOG.info("Transaction created " + t1);
+
+ TransactionState t2 = tm.beginTransaction();
+ LOG.info("Transaction created" + t2);
+
+ byte[] row = Bytes.toBytes("test-simple");
+ byte[] row2 = Bytes.toBytes("test-simple2");
+ byte[] fam = Bytes.toBytes(TEST_FAMILY);
+ byte[] col = Bytes.toBytes("testdata");
+ byte[] data1 = Bytes.toBytes("testWrite-1");
+ byte[] data2 = Bytes.toBytes("testWrite-2");
+
+ Put p = new Put(row);
+ p.add(fam, col, data1);
+ tt.put(t1, p);
+
+ //dummy put, to make the transaciton not read-only
+ Put p2 = new Put(row2);
+ p2.add(fam, col, data2);
+ tt.put(t2, p2);
+ Get g = new Get(row).setMaxVersions(1);
+ Result r = tt.get(g);
+ tt.get(t2, g);
+
+ //transaction t1 commit sooner. Since t1 modifies the read set of t2 and commits during t2's lifetime, t2 must abort under read-write conflict checking.
+ tm.tryCommit(t1);
+
+ try {
+ tm.tryCommit(t2);
+ assertFalse("Transaction commited successfully, despite the check for read-write conflicts", IsolationLevel.checkForReadWriteConflicts);
+ } catch (CommitUnsuccessfulException e) {
+ assertTrue("Transaction aborted even though check for read-write conflicts is not set", IsolationLevel.checkForReadWriteConflicts);
+ }
+ }
+
+ @Test
+ public void runTestFakeReadWriteConflict() throws Exception {
+ TransactionManager tm = new TransactionManager(conf);
+ TransactionalTable tt = new TransactionalTable(conf, TEST_TABLE);
+
+ TransactionState t1 = tm.beginTransaction();
+ LOG.info("Transaction created " + t1);
+
+ TransactionState t2 = tm.beginTransaction();
+ LOG.info("Transaction created" + t2);
+
+ byte[] row = Bytes.toBytes("test-simple");
+ byte[] row2 = Bytes.toBytes("test-simple2");
+ byte[] fam = Bytes.toBytes(TEST_FAMILY);
+ byte[] col = Bytes.toBytes("testdata");
+ byte[] data1 = Bytes.toBytes("testWrite-1");
+ byte[] data2 = Bytes.toBytes("testWrite-2");
+
+ Put p = new Put(row);
+ p.add(fam, col, data1);
+ tt.put(t1, p);
+
+ //dummy put, to make the transaciton not read-only
+ Put p2 = new Put(row2);
+ p2.add(fam, col, data2);
+ tt.put(t2, p2);
+ Get g = new Get(row).setMaxVersions(1);
+ tt.get(t2, g);
+
+ //transaction t2 commit sooner. Since t1, which modifies the read set of t2, does not commits during t2's lifetime, t1 does not have to abort under read-write conflict checking.
+ tm.tryCommit(t2);
+
+ boolean aborted = false;
+ try {
+ tm.tryCommit(t1);
+ } catch (CommitUnsuccessfulException e) {
+ aborted = true;
+ }
+ assertTrue("Transaction aborted while there is no conflict", !aborted);
+ }
+
+ @Test
+ public void runTestUpdate() throws Exception {
+ TransactionManager tm = new TransactionManager(conf);
+ TransactionalTable tt = new TransactionalTable(conf, TEST_TABLE);
+
+ TransactionState t1 = tm.beginTransaction();
+ LOG.info("Transaction created " + t1);
+
+ TransactionState t2 = tm.beginTransaction();
+ LOG.info("Transaction created" + t2);
+
+ byte[] row = Bytes.toBytes("test-simple");
+ byte[] fam = Bytes.toBytes(TEST_FAMILY);
+ byte[] col = Bytes.toBytes("testdata");
+ byte[] data1 = Bytes.toBytes("testWrite-1");
+ byte[] data2 = Bytes.toBytes("testWrite-2");
+
+ //Note: the order of get and put would not matter
+ Put p = new Put(row);
+ p.add(fam, col, data1);
+ tt.put(t1, p);
+ Get g = new Get(row).setMaxVersions(1);
+ tt.get(t1, g);
+
+ Put p2 = new Put(row);
+ p2.add(fam, col, data2);
+ tt.put(t2, p2);
+ Get g2 = new Get(row).setMaxVersions(1);
+ tt.get(t2, g2);
+
+ //Since both transaction read and write (update) the row, we should abort under any isolation level
+ tm.tryCommit(t2);
+
+ boolean aborted = false;
+ try {
+ tm.tryCommit(t1);
+ } catch (CommitUnsuccessfulException e) {
+ aborted = true;
+ }
+ assertTrue("Transaction did aborted while there is an update conflict", aborted);
+ }
+
+}
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
+ *
+ * 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. See accompanying LICENSE file.
+ */
+
+package com.yahoo.omid;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.HColumnDescriptor;
+import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.client.Delete;
+import org.apache.hadoop.hbase.client.Get;
+import org.apache.hadoop.hbase.client.HBaseAdmin;
+import org.apache.hadoop.hbase.client.Put;
+import org.apache.hadoop.hbase.client.Result;
+import org.apache.hadoop.hbase.client.ResultScanner;
+import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.junit.Test;
+
+import com.yahoo.omid.client.CommitUnsuccessfulException;
+import com.yahoo.omid.client.TransactionManager;
+import com.yahoo.omid.client.TransactionState;
+import com.yahoo.omid.client.TransactionalTable;
+
+public class TestReadWriteChecking extends TestIsolationLevels {
+ private static final Log LOG = LogFactory.getLog(TestReadWriteChecking.class);
+
+ public TestReadWriteChecking() {
+ IsolationLevel.checkForWriteWriteConflicts = false;
+ IsolationLevel.checkForReadWriteConflicts = true;
+ }
+
+}
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
+ *
+ * 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. See accompanying LICENSE file.
+ */
+
+package com.yahoo.omid;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.HColumnDescriptor;
+import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.client.Delete;
+import org.apache.hadoop.hbase.client.Get;
+import org.apache.hadoop.hbase.client.HBaseAdmin;
+import org.apache.hadoop.hbase.client.Put;
+import org.apache.hadoop.hbase.client.Result;
+import org.apache.hadoop.hbase.client.ResultScanner;
+import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.junit.Test;
+
+import com.yahoo.omid.client.CommitUnsuccessfulException;
+import com.yahoo.omid.client.TransactionManager;
+import com.yahoo.omid.client.TransactionState;
+import com.yahoo.omid.client.TransactionalTable;
+
+public class TestReadWriteWriteWriteChecking extends TestIsolationLevels {
+ private static final Log LOG = LogFactory.getLog(TestReadWriteWriteWriteChecking.class);
+
+ public TestReadWriteWriteWriteChecking() {
+ IsolationLevel.checkForWriteWriteConflicts = true;
+ IsolationLevel.checkForReadWriteConflicts = true;
+ }
+
+}
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2011 Yahoo! Inc. All rights reserved.
+ *
+ * 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. See accompanying LICENSE file.
+ */
+
+package com.yahoo.omid;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.HColumnDescriptor;
+import org.apache.hadoop.hbase.HTableDescriptor;
+import org.apache.hadoop.hbase.client.Delete;
+import org.apache.hadoop.hbase.client.Get;
+import org.apache.hadoop.hbase.client.HBaseAdmin;
+import org.apache.hadoop.hbase.client.Put;
+import org.apache.hadoop.hbase.client.Result;
+import org.apache.hadoop.hbase.client.ResultScanner;
+import org.apache.hadoop.hbase.client.Scan;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.junit.Test;
+
+import com.yahoo.omid.client.CommitUnsuccessfulException;
+import com.yahoo.omid.client.TransactionManager;
+import com.yahoo.omid.client.TransactionState;
+import com.yahoo.omid.client.TransactionalTable;
+
+public class TestWriteWriteChecking extends TestIsolationLevels {
+ private static final Log LOG = LogFactory.getLog(TestWriteWriteChecking.class);
+
+ public TestWriteWriteChecking() {
+ IsolationLevel.checkForWriteWriteConflicts = true;
+ IsolationLevel.checkForReadWriteConflicts = false;
+ }
+
+}

0 comments on commit a129898

Please sign in to comment.