You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@asterixdb.apache.org by am...@apache.org on 2018/01/17 18:47:51 UTC

asterixdb git commit: [ASTERIXDB-2204][STO] Add an abstract test case for an IIndexCursor

Repository: asterixdb
Updated Branches:
  refs/heads/master a03ff60a8 -> a49c7cce0


[ASTERIXDB-2204][STO] Add an abstract test case for an IIndexCursor

- user model changes: no
- storage format changes: no
- interface changes: no

details:
- Add a base test for all implementations of IIndexCursor
- The test case includes the following scenarios:
--- testNormalLifeCycle
--- testCreateDestroySucceed
--- testDoubleOpenFails
--- testCloseWithoutOpenFails
--- testDoubleCloseFails
--- testHasNextBeforeOpenFails
--- testHasNextAfterCloseFails
--- testNextBeforeOpenFails
--- testNextAfterCloseFails
--- testDestroyWhileOpenFails
--- testOpenAfterDestroyFails
--- testCloseAfterDestroyFails
--- testNextAfterDestroyFails
--- testHasNextAfterDestroyFails
--- testGetTupleReturnsNullAfterDestroy
- Add a base implementation of the interface that conforms
  to the expected lifecycle and can be extended by
  any cursor implementation.
- The test is run on the base implementation.

Change-Id: I7c32dd560367d84403ffa3d9cb69ff80d715fdc5
Reviewed-on: https://asterix-gerrit.ics.uci.edu/2291
Sonar-Qube: Jenkins <je...@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <je...@fulliautomatix.ics.uci.edu>
Contrib: Jenkins <je...@fulliautomatix.ics.uci.edu>
Integration-Tests: Jenkins <je...@fulliautomatix.ics.uci.edu>
Reviewed-by: Michael Blow <mb...@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/asterixdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/asterixdb/commit/a49c7cce
Tree: http://git-wip-us.apache.org/repos/asf/asterixdb/tree/a49c7cce
Diff: http://git-wip-us.apache.org/repos/asf/asterixdb/diff/a49c7cce

Branch: refs/heads/master
Commit: a49c7cce09f7dfb5d0424d7eeef1b61efa6a9aef
Parents: a03ff60
Author: Abdullah Alamoudi <ba...@gmail.com>
Authored: Tue Jan 16 17:53:23 2018 -0800
Committer: abdullah alamoudi <ba...@gmail.com>
Committed: Wed Jan 17 10:47:36 2018 -0800

----------------------------------------------------------------------
 .../tests/unit/EnforcedIndexCursorTest.java     |  49 ++++
 .../hyracks/tests/unit/IIndexCursorTest.java    | 263 +++++++++++++++++++
 .../storage/common/EnforcedIndexCursor.java     | 111 ++++++++
 3 files changed, 423 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a49c7cce/hyracks-fullstack/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/org/apache/hyracks/tests/unit/EnforcedIndexCursorTest.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/org/apache/hyracks/tests/unit/EnforcedIndexCursorTest.java b/hyracks-fullstack/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/org/apache/hyracks/tests/unit/EnforcedIndexCursorTest.java
new file mode 100644
index 0000000..8fe689e
--- /dev/null
+++ b/hyracks-fullstack/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/org/apache/hyracks/tests/unit/EnforcedIndexCursorTest.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.hyracks.tests.unit;
+
+import org.apache.hyracks.storage.common.EnforcedIndexCursor;
+import org.apache.hyracks.storage.common.ICursorInitialState;
+import org.apache.hyracks.storage.common.IIndexCursor;
+import org.apache.hyracks.storage.common.ISearchPredicate;
+import org.mockito.Mockito;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class EnforcedIndexCursorTest extends IIndexCursorTest {
+    @Override
+    protected List<ISearchPredicate> createSearchPredicates() {
+        List<ISearchPredicate> predicates = new ArrayList<>();
+        for (int i = 0; i < 10; i++) {
+            predicates.add(Mockito.mock(ISearchPredicate.class));
+        }
+        return predicates;
+    }
+
+    @Override
+    protected ICursorInitialState createCursorInitialState() {
+        return Mockito.mock(ICursorInitialState.class);
+    }
+
+    @Override
+    protected IIndexCursor createCursor() {
+        return new EnforcedIndexCursor();
+    }
+}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a49c7cce/hyracks-fullstack/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/org/apache/hyracks/tests/unit/IIndexCursorTest.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/org/apache/hyracks/tests/unit/IIndexCursorTest.java b/hyracks-fullstack/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/org/apache/hyracks/tests/unit/IIndexCursorTest.java
new file mode 100644
index 0000000..4d0f287
--- /dev/null
+++ b/hyracks-fullstack/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/org/apache/hyracks/tests/unit/IIndexCursorTest.java
@@ -0,0 +1,263 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.hyracks.tests.unit;
+
+import org.apache.hyracks.storage.common.ICursorInitialState;
+import org.apache.hyracks.storage.common.IIndexCursor;
+import org.apache.hyracks.storage.common.ISearchPredicate;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.List;
+
+/**
+ * This is a test class that forms the basis for unit tests of different implementations of the IIndexCursor interface
+ */
+public abstract class IIndexCursorTest {
+    @Test
+    public void testNormalLifeCycle() throws Exception {
+        IIndexCursor cursor = createCursor();
+        ICursorInitialState initialState = createCursorInitialState();
+        List<ISearchPredicate> predicates = createSearchPredicates();
+        for (ISearchPredicate predicate : predicates) {
+            cursor.open(initialState, predicate);
+            while (cursor.hasNext()) {
+                cursor.next();
+            }
+            cursor.close();
+        }
+        cursor.destroy();
+    }
+
+    @Test
+    public void testCreateDestroySucceed() throws Exception {
+        IIndexCursor cursor = createCursor();
+        cursor.destroy();
+    }
+
+    @Test
+    public void testDoubleOpenFails() throws Exception {
+        IIndexCursor cursor = createCursor();
+        ICursorInitialState initialState = createCursorInitialState();
+        List<ISearchPredicate> predicates = createSearchPredicates();
+        cursor.open(initialState, predicates.get(0));
+        boolean expectedExceptionThrown = false;
+        try {
+            cursor.open(initialState, predicates.get(0));
+        } catch (Exception e) {
+            expectedExceptionThrown = true;
+        }
+        cursor.close();
+        cursor.destroy();
+        Assert.assertTrue(expectedExceptionThrown);
+    }
+
+    @Test
+    public void testCloseWithoutOpenFails() throws Exception {
+        IIndexCursor cursor = createCursor();
+        boolean expectedExceptionThrown = false;
+        try {
+            cursor.close();
+        } catch (Exception e) {
+            expectedExceptionThrown = true;
+        }
+        cursor.destroy();
+        Assert.assertTrue(expectedExceptionThrown);
+    }
+
+    @Test
+    public void testDoubleCloseFails() throws Exception {
+        IIndexCursor cursor = createCursor();
+        ICursorInitialState initialState = createCursorInitialState();
+        List<ISearchPredicate> predicates = createSearchPredicates();
+        cursor.open(initialState, predicates.get(0));
+        cursor.close();
+        boolean expectedExceptionThrown = false;
+        try {
+            cursor.close();
+        } catch (Exception e) {
+            expectedExceptionThrown = true;
+        }
+        cursor.destroy();
+        Assert.assertTrue(expectedExceptionThrown);
+    }
+
+    @Test
+    public void testHasNextBeforeOpenFails() throws Exception {
+        IIndexCursor cursor = createCursor();
+        boolean expectedExceptionThrown = false;
+        try {
+            cursor.hasNext();
+        } catch (Exception e) {
+            expectedExceptionThrown = true;
+        }
+        cursor.destroy();
+        Assert.assertTrue(expectedExceptionThrown);
+    }
+
+    @Test
+    public void testHasNextAfterCloseFails() throws Exception {
+        IIndexCursor cursor = createCursor();
+        ICursorInitialState initialState = createCursorInitialState();
+        List<ISearchPredicate> predicates = createSearchPredicates();
+        cursor.open(initialState, predicates.get(0));
+        cursor.close();
+        boolean expectedExceptionThrown = false;
+        try {
+            cursor.hasNext();
+        } catch (Exception e) {
+            expectedExceptionThrown = true;
+        }
+        cursor.destroy();
+        Assert.assertTrue(expectedExceptionThrown);
+    }
+
+    @Test
+    public void testNextBeforeOpenFails() throws Exception {
+        IIndexCursor cursor = createCursor();
+        boolean expectedExceptionThrown = false;
+        try {
+            cursor.next();
+        } catch (Exception e) {
+            expectedExceptionThrown = true;
+        }
+        cursor.destroy();
+        Assert.assertTrue(expectedExceptionThrown);
+    }
+
+    @Test
+    public void testNextAfterCloseFails() throws Exception {
+        IIndexCursor cursor = createCursor();
+        ICursorInitialState initialState = createCursorInitialState();
+        List<ISearchPredicate> predicates = createSearchPredicates();
+        cursor.open(initialState, predicates.get(0));
+        cursor.close();
+        boolean expectedExceptionThrown = false;
+        try {
+            cursor.next();
+        } catch (Exception e) {
+            expectedExceptionThrown = true;
+        }
+        cursor.destroy();
+        Assert.assertTrue(expectedExceptionThrown);
+    }
+
+    @Test
+    public void testDestroyWhileOpenFails() throws Exception {
+        IIndexCursor cursor = createCursor();
+        ICursorInitialState initialState = createCursorInitialState();
+        List<ISearchPredicate> predicates = createSearchPredicates();
+        cursor.open(initialState, predicates.get(0));
+        boolean expectedExceptionThrown = false;
+        try {
+            cursor.destroy();
+        } catch (Exception e) {
+            expectedExceptionThrown = true;
+        }
+        cursor.close();
+        cursor.destroy();
+        Assert.assertTrue(expectedExceptionThrown);
+    }
+
+    @Test
+    public void testOpenAfterDestroyFails() throws Exception {
+        IIndexCursor cursor = createCursor();
+        ICursorInitialState initialState = createCursorInitialState();
+        List<ISearchPredicate> predicates = createSearchPredicates();
+        cursor.open(initialState, predicates.get(0));
+        cursor.close();
+        cursor.destroy();
+        boolean expectedExceptionThrown = false;
+        try {
+            cursor.open(initialState, predicates.get(0));
+        } catch (Exception e) {
+            expectedExceptionThrown = true;
+        }
+        Assert.assertTrue(expectedExceptionThrown);
+    }
+
+    @Test
+    public void testCloseAfterDestroyFails() throws Exception {
+        IIndexCursor cursor = createCursor();
+        ICursorInitialState initialState = createCursorInitialState();
+        List<ISearchPredicate> predicates = createSearchPredicates();
+        cursor.open(initialState, predicates.get(0));
+        cursor.close();
+        cursor.destroy();
+        boolean expectedExceptionThrown = false;
+        try {
+            cursor.close();
+        } catch (Exception e) {
+            expectedExceptionThrown = true;
+        }
+        Assert.assertTrue(expectedExceptionThrown);
+    }
+
+    @Test
+    public void testNextAfterDestroyFails() throws Exception {
+        IIndexCursor cursor = createCursor();
+        ICursorInitialState initialState = createCursorInitialState();
+        List<ISearchPredicate> predicates = createSearchPredicates();
+        cursor.open(initialState, predicates.get(0));
+        cursor.close();
+        cursor.destroy();
+        boolean expectedExceptionThrown = false;
+        try {
+            cursor.next();
+        } catch (Exception e) {
+            expectedExceptionThrown = true;
+        }
+        Assert.assertTrue(expectedExceptionThrown);
+    }
+
+    @Test
+    public void testHasNextAfterDestroyFails() throws Exception {
+        IIndexCursor cursor = createCursor();
+        ICursorInitialState initialState = createCursorInitialState();
+        List<ISearchPredicate> predicates = createSearchPredicates();
+        cursor.open(initialState, predicates.get(0));
+        cursor.close();
+        cursor.destroy();
+        boolean expectedExceptionThrown = false;
+        try {
+            cursor.hasNext();
+        } catch (Exception e) {
+            expectedExceptionThrown = true;
+        }
+        Assert.assertTrue(expectedExceptionThrown);
+    }
+
+    @Test
+    public void testGetTupleReturnsNullAfterDestroy() throws Exception {
+        IIndexCursor cursor = createCursor();
+        ICursorInitialState initialState = createCursorInitialState();
+        List<ISearchPredicate> predicates = createSearchPredicates();
+        cursor.open(initialState, predicates.get(0));
+        cursor.close();
+        cursor.destroy();
+        Assert.assertNull(cursor.getTuple());
+    }
+
+    protected abstract List<ISearchPredicate> createSearchPredicates();
+
+    protected abstract ICursorInitialState createCursorInitialState();
+
+    protected abstract IIndexCursor createCursor();
+}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/a49c7cce/hyracks-fullstack/hyracks/hyracks-storage-common/src/main/java/org/apache/hyracks/storage/common/EnforcedIndexCursor.java
----------------------------------------------------------------------
diff --git a/hyracks-fullstack/hyracks/hyracks-storage-common/src/main/java/org/apache/hyracks/storage/common/EnforcedIndexCursor.java b/hyracks-fullstack/hyracks/hyracks-storage-common/src/main/java/org/apache/hyracks/storage/common/EnforcedIndexCursor.java
new file mode 100644
index 0000000..62a56e6
--- /dev/null
+++ b/hyracks-fullstack/hyracks/hyracks-storage-common/src/main/java/org/apache/hyracks/storage/common/EnforcedIndexCursor.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.hyracks.storage.common;
+
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.dataflow.common.data.accessors.ITupleReference;
+
+public class EnforcedIndexCursor implements IIndexCursor {
+    enum State {
+        CLOSED,
+        OPENED,
+        DESTROYED
+    }
+
+    private State state = State.CLOSED;
+
+    @Override
+    public void open(ICursorInitialState initialState, ISearchPredicate searchPred) throws HyracksDataException {
+        if (state != State.CLOSED) {
+            throw new IllegalStateException("Cannot open a cursor in the state " + state);
+        }
+        doOpen(initialState, searchPred);
+        state = State.OPENED;
+    }
+
+    protected void doOpen(ICursorInitialState initialState, ISearchPredicate searchPred) throws HyracksDataException {
+        // Do nothing
+    }
+
+    @Override
+    public boolean hasNext() throws HyracksDataException {
+        if (state != State.OPENED) {
+            throw new IllegalStateException("Cannot call hasNext() on a cursor in the state " + state);
+        }
+        return doHasNext();
+    }
+
+    protected boolean doHasNext() throws HyracksDataException {
+        return false;
+    }
+
+    @Override
+    public void next() throws HyracksDataException {
+        if (state != State.OPENED) {
+            throw new IllegalStateException("Cannot call next() on a cursor in the state " + state);
+        }
+        doNext();
+    }
+
+    protected void doNext() throws HyracksDataException {
+        // Do nothing
+    }
+
+    @Override
+    public void destroy() throws HyracksDataException {
+        if (state != State.CLOSED) {
+            throw new IllegalStateException("Cannot destroy a cursor in the state " + state);
+        }
+        doDestroy();
+        state = State.DESTROYED;
+    }
+
+    protected void doDestroy() throws HyracksDataException {
+        // Do nothing
+    }
+
+    @Override
+    public void close() throws HyracksDataException {
+        if (state != State.OPENED) {
+            throw new IllegalStateException("Cannot close a cursor in the state " + state);
+        }
+        doClose();
+        state = State.CLOSED;
+    }
+
+    private void doClose() throws HyracksDataException {
+        // Do nothing
+    }
+
+    @Override
+    public ITupleReference getTuple() {
+        return null;
+    }
+
+    @Override
+    public ITupleReference getFilterMinTuple() {
+        return null;
+    }
+
+    @Override
+    public ITupleReference getFilterMaxTuple() {
+        return null;
+    }
+}