diff options
| author | Brian S. O'Neill <bronee@gmail.com> | 2008-05-05 01:22:37 +0000 | 
|---|---|---|
| committer | Brian S. O'Neill <bronee@gmail.com> | 2008-05-05 01:22:37 +0000 | 
| commit | 8753f3a53002dfdf551e7acc3baeba70c5558578 (patch) | |
| tree | 86b8fce2665048685de460c1df276b40be5593ac /src/test/java/com/amazon/carbonado/repo/map | |
| parent | 7b9f49a10ccb6307324b9353399c176f350cd4a9 (diff) | |
Added transaction test case.
Diffstat (limited to 'src/test/java/com/amazon/carbonado/repo/map')
| -rw-r--r-- | src/test/java/com/amazon/carbonado/repo/map/TestTransaction.java | 561 | 
1 files changed, 561 insertions, 0 deletions
diff --git a/src/test/java/com/amazon/carbonado/repo/map/TestTransaction.java b/src/test/java/com/amazon/carbonado/repo/map/TestTransaction.java new file mode 100644 index 0000000..cbaa431 --- /dev/null +++ b/src/test/java/com/amazon/carbonado/repo/map/TestTransaction.java @@ -0,0 +1,561 @@ +/*
 + * Copyright 2008 Amazon Technologies, Inc. or its affiliates.
 + * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks
 + * of Amazon Technologies, Inc. or its affiliates.  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.
 + */
 +
 +package com.amazon.carbonado.repo.map;
 +
 +import junit.framework.TestCase;
 +import junit.framework.TestSuite;
 +
 +import com.amazon.carbonado.*;
 +
 +import com.amazon.carbonado.stored.StorableTestBasic;
 +
 +/**
 + * 
 + *
 + * @author Brian S O'Neill
 + */
 +public class TestTransaction extends TestCase {
 +    public static void main(String[] args) {
 +        junit.textui.TestRunner.run(suite());
 +    }
 +
 +    public static TestSuite suite() {
 +        return new TestSuite(TestTransaction.class);
 +    }
 +
 +    public TestTransaction(String s) {
 +        super(s);
 +    }
 +
 +    private Repository mRepo;
 +
 +    protected void setUp() throws Exception {
 +        mRepo = MapRepositoryBuilder.newRepository();
 +    }
 +
 +    protected void tearDown() throws Exception {
 +        mRepo = null;
 +    }
 +
 +    public void testSimpleRollback() throws Exception {
 +        Storage<StorableTestBasic> storage = mRepo.storageFor(StorableTestBasic.class);
 +        StorableTestBasic stb;
 +
 +        Transaction txn = mRepo.enterTransaction();
 +        try {
 +            stb = storage.prepare();
 +            stb.setId(1);
 +            stb.setStringProp("hello");
 +            stb.setIntProp(3);
 +            stb.setLongProp(22);
 +            stb.setDoubleProp(234.2);
 +            stb.insert();
 +
 +            StorableTestBasic stb2 = storage.prepare();
 +            stb2.setId(1);
 +            stb2.load();
 +            assertEquals("hello", stb2.getStringProp());
 +        } finally {
 +            txn.exit();
 +        }
 +
 +        assertEquals(0, storage.query().count());
 +
 +        stb.insert();
 +
 +        assertEquals(1, storage.query().count());
 +
 +        txn = mRepo.enterTransaction();
 +        try {
 +            stb = storage.prepare();
 +            stb.setId(1);
 +            stb.setStringProp("world");
 +            stb.update();
 +
 +            StorableTestBasic stb2 = storage.prepare();
 +            stb2.setId(1);
 +            stb2.load();
 +            assertEquals("world", stb2.getStringProp());
 +        } finally {
 +            txn.exit();
 +        }
 +
 +        assertEquals(1, storage.query().count());
 +
 +        stb = storage.prepare();
 +        stb.setId(1);
 +        stb.load();
 +        assertEquals("hello", stb.getStringProp());
 +
 +        txn = mRepo.enterTransaction();
 +        try {
 +            stb = storage.prepare();
 +            stb.setId(1);
 +            stb.delete();
 +
 +            StorableTestBasic stb2 = storage.prepare();
 +            stb2.setId(1);
 +            assertFalse(stb2.tryLoad());
 +        } finally {
 +            txn.exit();
 +        }
 +
 +        assertEquals(1, storage.query().count());
 +
 +        stb = storage.prepare();
 +        stb.setId(1);
 +        stb.load();
 +        assertEquals("hello", stb.getStringProp());
 +
 +        stb.delete();
 +
 +        assertEquals(0, storage.query().count());
 +    }
 +
 +    public void testNestedRollback() throws Exception {
 +        Storage<StorableTestBasic> storage = mRepo.storageFor(StorableTestBasic.class);
 +        StorableTestBasic stb;
 +
 +        Transaction txn = mRepo.enterTransaction();
 +        try {
 +            stb = storage.prepare();
 +            stb.setId(1);
 +            stb.setStringProp("hello");
 +            stb.setIntProp(3);
 +            stb.setLongProp(22);
 +            stb.setDoubleProp(234.2);
 +            stb.insert();
 +
 +            StorableTestBasic stb2 = storage.prepare();
 +            stb2.setId(1);
 +            stb2.load();
 +            assertEquals("hello", stb2.getStringProp());
 +
 +            Transaction txn2 = mRepo.enterTransaction();
 +            try {
 +                stb2.setStringProp("world");
 +                stb2.update();
 +                stb2.load();
 +                assertEquals("world", stb2.getStringProp());
 +            } finally {
 +                txn2.exit();
 +            }
 +
 +            stb2.load();
 +            assertEquals("hello", stb2.getStringProp());
 +        } finally {
 +            txn.exit();
 +        }
 +
 +        assertEquals(0, storage.query().count());
 +
 +        stb.insert();
 +
 +        assertEquals(1, storage.query().count());
 +
 +        txn = mRepo.enterTransaction();
 +        try {
 +            stb = storage.prepare();
 +            stb.setId(1);
 +            stb.setStringProp("world");
 +            stb.update();
 +
 +            StorableTestBasic stb2 = storage.prepare();
 +            stb2.setId(1);
 +            stb2.load();
 +            assertEquals("world", stb2.getStringProp());
 +
 +            Transaction txn2 = mRepo.enterTransaction();
 +            try {
 +                stb2.setStringProp("everybody");
 +                stb2.update();
 +                stb2.load();
 +                assertEquals("everybody", stb2.getStringProp());
 +
 +                StorableTestBasic stb3 = storage.prepare();
 +                stb3.setId(1);
 +                stb3.setStringProp("text");
 +                stb3.setIntProp(33);
 +                stb3.setLongProp(2);
 +                stb3.setDoubleProp(34.2);
 +                assertFalse(stb3.tryInsert());
 +
 +                stb3.setId(2);
 +                stb3.insert();
 +
 +                stb3.load();
 +                assertEquals("text", stb3.getStringProp());
 +            } finally {
 +                txn2.exit();
 +            }
 +
 +            stb2.load();
 +            assertEquals("world", stb2.getStringProp());
 +
 +            StorableTestBasic stb3 = storage.prepare();
 +            stb3.setId(2);
 +            assertFalse(stb3.tryLoad());
 +        } finally {
 +            txn.exit();
 +        }
 +
 +        assertEquals(1, storage.query().count());
 +
 +        stb = storage.prepare();
 +        stb.setId(1);
 +        stb.load();
 +        assertEquals("hello", stb.getStringProp());
 +
 +        txn = mRepo.enterTransaction();
 +        try {
 +            stb = storage.prepare();
 +            stb.setId(1);
 +            stb.delete();
 +
 +            StorableTestBasic stb2 = storage.prepare();
 +            stb2.setId(1);
 +            assertFalse(stb2.tryLoad());
 +
 +            Transaction txn2 = mRepo.enterTransaction();
 +            try {
 +                StorableTestBasic stb3 = storage.prepare();
 +                stb3.setId(1);
 +                stb3.setStringProp("text");
 +                stb3.setIntProp(33);
 +                stb3.setLongProp(2);
 +                stb3.setDoubleProp(34.2);
 +                stb3.insert();
 +
 +                assertTrue(stb3.tryLoad());
 +                assertEquals("text", stb3.getStringProp());
 +            } finally {
 +                txn2.exit();
 +            }
 +
 +            assertFalse(stb2.tryLoad());
 +        } finally {
 +            txn.exit();
 +        }
 +
 +        assertEquals(1, storage.query().count());
 +
 +        stb = storage.prepare();
 +        stb.setId(1);
 +        stb.load();
 +        assertEquals("hello", stb.getStringProp());
 +
 +        stb.delete();
 +
 +        assertEquals(0, storage.query().count());
 +    }
 +
 +    public void testDeadlock() throws Exception {
 +        // This test makes sure that transaction locker is not the current
 +        // thread. Top transactions will deadlock.
 +
 +        Storage<StorableTestBasic> storage = mRepo.storageFor(StorableTestBasic.class);
 +        StorableTestBasic stb;
 +
 +        Transaction txn = mRepo.enterTransaction();
 +        try {
 +            stb = storage.prepare();
 +            stb.setId(1);
 +            stb.setStringProp("hello");
 +            stb.setIntProp(3);
 +            stb.setLongProp(22);
 +            stb.setDoubleProp(234.2);
 +            stb.insert();
 +
 +            Transaction txn2 = mRepo.enterTopTransaction(IsolationLevel.READ_COMMITTED);
 +            try {
 +                stb = storage.prepare();
 +                stb.setId(2);
 +                stb.setStringProp("world");
 +                stb.setIntProp(3);
 +                stb.setLongProp(22);
 +                stb.setDoubleProp(234.2);
 +                try {
 +                    stb.insert();
 +                    fail();
 +                } catch (PersistTimeoutException e) {
 +                }
 +            } finally {
 +                txn2.exit();
 +            }
 +
 +            txn.commit();
 +        } finally {
 +            txn.exit();
 +        }
 +
 +        stb = storage.prepare();
 +        stb.setId(1);
 +        stb.load();
 +        assertEquals("hello", stb.getStringProp());
 +    }
 +
 +    public void testIsolation() throws Exception {
 +        final Storage<StorableTestBasic> storage = mRepo.storageFor(StorableTestBasic.class);
 +        StorableTestBasic stb;
 +
 +        stb = storage.prepare();
 +        stb.setId(1);
 +        stb.setStringProp("hello");
 +        stb.setIntProp(3);
 +        stb.setLongProp(22);
 +        stb.setDoubleProp(234.2);
 +        stb.insert();
 +
 +        Transaction txn = mRepo.enterTransaction(IsolationLevel.READ_COMMITTED);
 +        try {
 +            stb.load();
 +            assertEquals("hello", stb.getStringProp());
 +
 +            Thread t = new Thread() {
 +                public void run() {
 +                    try {
 +                        StorableTestBasic stb = storage.prepare();
 +                        stb.setId(1);
 +                        assertTrue(stb.tryLoad());
 +                        stb.setStringProp("world");
 +                        stb.update();
 +                    } catch (Exception e) {
 +                        e.printStackTrace();
 +                    }
 +                }
 +            };
 +
 +            t.start();
 +            t.join();
 +
 +            // Test that read is not repeatable.
 +            stb.load();
 +            assertEquals("world", stb.getStringProp());
 +
 +            t = new Thread() {
 +                public void run() {
 +                    try {
 +                        Transaction txn = mRepo.enterTransaction();
 +                        try {
 +                            StorableTestBasic stb = storage.prepare();
 +                            stb.setId(1);
 +                            assertTrue(stb.tryLoad());
 +                            stb.setStringProp("world!!!");
 +                            stb.update();
 +                            txn.commit();
 +                        } finally {
 +                            txn.exit();
 +                        }
 +                    } catch (Exception e) {
 +                        e.printStackTrace();
 +                    }
 +                }
 +            };
 +
 +            t.start();
 +            t.join();
 +
 +            // Test that read is still not repeatable.
 +            stb.load();
 +            assertEquals("world!!!", stb.getStringProp());
 +
 +            txn.commit();
 +        } finally {
 +            txn.exit();
 +        }
 +
 +        stb = storage.prepare();
 +        stb.setId(1);
 +        stb.load();
 +        assertEquals("world!!!", stb.getStringProp());
 +
 +        stb.setStringProp("hello");
 +        stb.update();
 +
 +        txn = mRepo.enterTransaction(IsolationLevel.REPEATABLE_READ);
 +        try {
 +            stb.load();
 +            assertEquals("hello", stb.getStringProp());
 +
 +            Thread t = new Thread() {
 +                public void run() {
 +                    try {
 +                        StorableTestBasic stb = storage.prepare();
 +                        stb.setId(1);
 +                        assertTrue(stb.tryLoad());
 +                        stb.setStringProp("world");
 +                        stb.update();
 +                        fail();
 +                    } catch (PersistTimeoutException e) {
 +                        // expected
 +                    } catch (Exception e) {
 +                        e.printStackTrace();
 +                    }
 +                }
 +            };
 +
 +            t.start();
 +            t.join();
 +
 +            // Test that read is repeatable.
 +            stb.load();
 +            assertEquals("hello", stb.getStringProp());
 +
 +            t = new Thread() {
 +                public void run() {
 +                    try {
 +                        Transaction txn = mRepo.enterTransaction();
 +                        try {
 +                            StorableTestBasic stb = storage.prepare();
 +                            stb.setId(1);
 +                            try {
 +                                assertTrue(stb.tryLoad());
 +                                fail();
 +                            } catch (FetchTimeoutException e) {
 +                                // expected
 +                            }
 +                            stb.setStringProp("world!!!");
 +                            stb.update();
 +                            fail();
 +                            txn.commit();
 +                            fail();
 +                        } finally {
 +                            txn.exit();
 +                        }
 +                    } catch (PersistTimeoutException e) {
 +                        // expected
 +                    } catch (Exception e) {
 +                        e.printStackTrace();
 +                    }
 +                }
 +            };
 +
 +            t.start();
 +            t.join();
 +
 +            // Test that read is still repeatable.
 +            stb.load();
 +            assertEquals("hello", stb.getStringProp());
 +
 +            txn.commit();
 +        } finally {
 +            txn.exit();
 +        }
 +    }
 +
 +    public void testForUpdate() throws Exception {
 +        // Tests that "for update" mode prevents deadlock.
 +
 +        final Storage<StorableTestBasic> storage = mRepo.storageFor(StorableTestBasic.class);
 +        StorableTestBasic stb;
 +
 +        stb = storage.prepare();
 +        stb.setId(1);
 +        stb.setStringProp("hello");
 +        stb.setIntProp(3);
 +        stb.setLongProp(22);
 +        stb.setDoubleProp(234.2);
 +        stb.insert();
 +
 +        class Task extends Thread {
 +            private Boolean mLoaded;
 +
 +            public void run() {
 +                try {
 +                    Transaction txn = mRepo.enterTransaction(IsolationLevel.REPEATABLE_READ);
 +                    try {
 +                        StorableTestBasic stb = storage.prepare();
 +                        stb.setId(1);
 +                        assertTrue(stb.tryLoad());
 +                        loaded(true);
 +                        Thread.sleep(1000);
 +                    } finally {
 +                        txn.exit();
 +                    }
 +                } catch (FetchTimeoutException e) {
 +                    // ok
 +                } catch (Exception e) {
 +                    e.printStackTrace();
 +                }
 +                loaded(false);
 +            }
 +
 +            private synchronized void loaded(boolean b) {
 +                if (mLoaded == null) {
 +                    mLoaded = b;
 +                    notify();
 +                }
 +            }
 +
 +            public synchronized boolean waitToLoad() throws InterruptedException {
 +                while (mLoaded == null) {
 +                    wait();
 +                }
 +                return mLoaded;
 +            }
 +        }
 +
 +        Transaction txn = mRepo.enterTransaction();
 +        try {
 +            stb.load();
 +
 +            Task t = new Task();
 +
 +            t.start();
 +            assertTrue(t.waitToLoad());
 +
 +            try {
 +                stb.load();
 +                fail();
 +            } catch (FetchTimeoutException e) {
 +                // expected
 +            }
 +
 +            t.join();
 +        } finally {
 +            txn.exit();
 +        }
 +
 +        txn = mRepo.enterTransaction();
 +        try {
 +            txn.setForUpdate(true);
 +            stb.load();
 +
 +            Task t = new Task();
 +
 +            t.start();
 +            assertFalse(t.waitToLoad());
 +
 +            stb.load();
 +            stb.setStringProp("world");
 +            stb.update();
 +
 +            t.join();
 +
 +            txn.commit();
 +        } finally {
 +            txn.exit();
 +        }
 +
 +        stb = storage.prepare();
 +        stb.setId(1);
 +        stb.load();
 +        assertEquals("world", stb.getStringProp());
 +    }
 +}
  | 
