abdullah alamoudi has uploaded a new change for review. https://asterix-gerrit.ics.uci.edu/2291
Change subject: [ASTERIXDB-2204][STO] Add an abstract test case for an IIndexCursor ...................................................................... [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 --- A hyracks-fullstack/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/org/apache/hyracks/tests/unit/EnforcedIndexCursorTest.java A hyracks-fullstack/hyracks/hyracks-examples/hyracks-integration-tests/src/test/java/org/apache/hyracks/tests/unit/IIndexCursorTest.java A hyracks-fullstack/hyracks/hyracks-storage-common/src/main/java/org/apache/hyracks/storage/common/EnforcedIndexCursor.java 3 files changed, 423 insertions(+), 0 deletions(-) git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb refs/changes/91/2291/1 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(); + } +} 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(); +} 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; + } +} -- To view, visit https://asterix-gerrit.ics.uci.edu/2291 To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I7c32dd560367d84403ffa3d9cb69ff80d715fdc5 Gerrit-PatchSet: 1 Gerrit-Project: asterixdb Gerrit-Branch: master Gerrit-Owner: abdullah alamoudi <[email protected]>
