diff options
Diffstat (limited to 'src/test')
18 files changed, 3804 insertions, 0 deletions
diff --git a/src/test/java/org/openecomp/aai/champ/concurrency/ConcurrencyTest.java b/src/test/java/org/openecomp/aai/champ/concurrency/ConcurrencyTest.java new file mode 100644 index 0000000..a9a6b75 --- /dev/null +++ b/src/test/java/org/openecomp/aai/champ/concurrency/ConcurrencyTest.java @@ -0,0 +1,72 @@ +/** + * ============LICENSE_START========================================== + * org.onap.aai + * =================================================================== + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * =================================================================== + * 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. + * ============LICENSE_END============================================ + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.openecomp.aai.champ.concurrency; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +import org.junit.Test; +import org.openecomp.aai.champ.ChampAPI; +import org.openecomp.aai.champ.ChampGraph; +import org.openecomp.aai.champ.core.ChampObjectTest; +import org.openecomp.aai.champ.core.ChampRelationshipTest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ConcurrencyTest { + + private static final Logger LOGGER = LoggerFactory.getLogger(ConcurrencyTest.class); + + @Test + public void runConcurrentTest() { + for (ChampGraph.Type apiType : ChampGraph.Type.values()) { + final ChampAPI api = ChampAPI.Factory.newInstance(apiType); + runConcurrencyTest(api); + api.shutdown(); + } + } + + private void runConcurrencyTest(ChampAPI api) { + final int numThreads = 10; + final ExecutorService es = Executors.newFixedThreadPool(numThreads); + + for (int i = 0; i < numThreads * 2; i++) { + es.submit(new Runnable() { + @Override + public void run() { + final ChampGraph graph = api.getGraph(ConcurrencyTest.class.getSimpleName()); + ChampObjectTest.testChampObjectCrud(graph); + ChampRelationshipTest.testChampRelationshipCrud(graph); + } + }); + } + + try { + es.shutdown(); + es.awaitTermination(60, TimeUnit.SECONDS); + } catch (InterruptedException e) { + LOGGER.warn("Interrupted while waiting for concurrency test to finish", e); + return; + } + } +} diff --git a/src/test/java/org/openecomp/aai/champ/core/BaseChampAPITest.java b/src/test/java/org/openecomp/aai/champ/core/BaseChampAPITest.java new file mode 100644 index 0000000..7d374c3 --- /dev/null +++ b/src/test/java/org/openecomp/aai/champ/core/BaseChampAPITest.java @@ -0,0 +1,50 @@ +/** + * ============LICENSE_START========================================== + * org.onap.aai + * =================================================================== + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * =================================================================== + * 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. + * ============LICENSE_END============================================ + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.openecomp.aai.champ.core; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class BaseChampAPITest { + + private static final Logger LOGGER = LoggerFactory.getLogger(BaseChampAPITest.class); + + protected static void cleanUp(String graphName) { + LOGGER.warn("cleanUp is disabled for unit tests - you can enable it by commenting out the code below this log message, please don't commit it though"); + + /* + LOGGER.debug("Cleaning up graph {}", graphName); + + try { + final TitanGraph graph = TitanFactory.build() + .set("storage.backend", "cassandra") + .set("storage.hostname", "localhost") + .set("storage.cassandra.keyspace", graphName) + .open(); + graph.close(); + TitanCleanup.clear(graph); + } catch (IllegalArgumentException e) { + LOGGER.warn("Could not clean up graph - unable to instantiate"); + } + */ + } +} diff --git a/src/test/java/org/openecomp/aai/champ/core/ChampAPITest.java b/src/test/java/org/openecomp/aai/champ/core/ChampAPITest.java new file mode 100644 index 0000000..7cd259e --- /dev/null +++ b/src/test/java/org/openecomp/aai/champ/core/ChampAPITest.java @@ -0,0 +1,239 @@ +/** + * ============LICENSE_START========================================== + * org.onap.aai + * =================================================================== + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * =================================================================== + * 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. + * ============LICENSE_END============================================ + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.openecomp.aai.champ.core; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.openecomp.aai.champ.ChampAPI; +import org.openecomp.aai.champ.ChampGraph; +import org.openecomp.aai.champ.model.ChampObjectConstraint; +import org.openecomp.aai.champ.model.ChampRelationshipConstraint; + +public class ChampAPITest { + + @Test + public void testChampAPIInstantiation() { + + for (ChampGraph.Type type : ChampGraph.Type.values()) { + + final ChampAPI api = ChampAPI.Factory.newInstance(type); + + assertTrue(type == ChampGraph.Type.valueOf(type.name())); + assertTrue(api.getType() == type); + + api.getGraph("foo"); + api.shutdown(); + + try { + api.getGraph("foo"); + throw new AssertionError("Able to call getGraph(String name) after shutdown()"); + } catch (IllegalStateException e) { + //Expected + } + } + } + + @Test + public void testChampGraphInstantiation() throws Exception { + for (ChampGraph.Type type : ChampGraph.Type.values()) { + final ChampGraph graph = ChampGraph.Factory.newInstance(type, "foo"); + + graph.shutdown(); + + try { + graph.deleteObject(null); + throw new AssertionError("Able to call API method after shutdown was initiated"); + } catch (IllegalStateException e) { + //Expected + } + + try { + graph.deleteObjectIndex(null); + throw new AssertionError("Able to call API method after shutdown was initiated"); + } catch (IllegalStateException e) { + //Expected + } + + try { + graph.deletePartition(null); + throw new AssertionError("Able to call API method after shutdown was initiated"); + } catch (IllegalStateException e) { + //Expected + } + + try { + graph.deleteRelationship(null); + throw new AssertionError("Able to call API method after shutdown was initiated"); + } catch (IllegalStateException e) { + //Expected + } + + try { + graph.deleteRelationshipIndex(null); + throw new AssertionError("Able to call API method after shutdown was initiated"); + } catch (IllegalStateException e) { + //Expected + } + + try { + graph.deleteSchema(); + throw new AssertionError("Able to call API method after shutdown was initiated"); + } catch (IllegalStateException e) { + //Expected + } + + try { + graph.queryObjects(null); + throw new AssertionError("Able to call API method after shutdown was initiated"); + } catch (IllegalStateException e) { + //Expected + } + + try { + graph.queryRelationships(null); + throw new AssertionError("Able to call API method after shutdown was initiated"); + } catch (IllegalStateException e) { + //Expected + } + + try { + graph.retrieveObject(null); + throw new AssertionError("Able to call API method after shutdown was initiated"); + } catch (IllegalStateException e) { + //Expected + } + + try { + graph.retrieveObjectIndex(null); + throw new AssertionError("Able to call API method after shutdown was initiated"); + } catch (IllegalStateException e) { + //Expected + } + + try { + graph.retrieveObjectIndices(); + throw new AssertionError("Able to call API method after shutdown was initiated"); + } catch (IllegalStateException e) { + //Expected + } + + try { + graph.retrieveRelationship(null); + throw new AssertionError("Able to call API method after shutdown was initiated"); + } catch (IllegalStateException e) { + //Expected + } + + try { + graph.retrieveRelationshipIndex(null); + throw new AssertionError("Able to call API method after shutdown was initiated"); + } catch (IllegalStateException e) { + //Expected + } + + try { + graph.retrieveRelationshipIndices(); + throw new AssertionError("Able to call API method after shutdown was initiated"); + } catch (IllegalStateException e) { + //Expected + } + + try { + graph.retrieveRelationships(null); + throw new AssertionError("Able to call API method after shutdown was initiated"); + } catch (IllegalStateException e) { + //Expected + } + + try { + graph.retrieveSchema(); + throw new AssertionError("Able to call API method after shutdown was initiated"); + } catch (IllegalStateException e) { + //Expected + } + + try { + graph.storeObject(null); + throw new AssertionError("Able to call API method after shutdown was initiated"); + } catch (IllegalStateException e) { + //Expected + } + + try { + graph.storeObjectIndex(null); + throw new AssertionError("Able to call API method after shutdown was initiated"); + } catch (IllegalStateException e) { + //Expected + } + + try { + graph.storePartition(null); + throw new AssertionError("Able to call API method after shutdown was initiated"); + } catch (IllegalStateException e) { + //Expected + } + + try { + graph.storeRelationship(null); + throw new AssertionError("Able to call API method after shutdown was initiated"); + } catch (IllegalStateException e) { + //Expected + } + + try { + graph.storeRelationshipIndex(null); + throw new AssertionError("Able to call API method after shutdown was initiated"); + } catch (IllegalStateException e) { + //Expected + } + + try { + graph.storeSchema(null); + throw new AssertionError("Able to call API method after shutdown was initiated"); + } catch (IllegalStateException e) { + //Expected + } + + try { + graph.updateSchema(new ChampObjectConstraint.Builder("").build()); + throw new AssertionError("Able to call API method after shutdown was initiated"); + } catch (IllegalStateException e) { + //Expected + } + + try { + graph.updateSchema(new ChampRelationshipConstraint.Builder("").build()); + throw new AssertionError("Able to call API method after shutdown was initiated"); + } catch (IllegalStateException e) { + //Expected + } + + try { + graph.shutdown(); + throw new AssertionError("Able to call API method after shutdown was initiated"); + } catch (IllegalStateException e) { + //Expected + } + } + } +} diff --git a/src/test/java/org/openecomp/aai/champ/core/ChampElementTest.java b/src/test/java/org/openecomp/aai/champ/core/ChampElementTest.java new file mode 100644 index 0000000..4d34f8a --- /dev/null +++ b/src/test/java/org/openecomp/aai/champ/core/ChampElementTest.java @@ -0,0 +1,62 @@ +/** + * ============LICENSE_START========================================== + * org.onap.aai + * =================================================================== + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * =================================================================== + * 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. + * ============LICENSE_END============================================ + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.openecomp.aai.champ.core; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.openecomp.aai.champ.model.ChampElement; +import org.openecomp.aai.champ.model.ChampObject; +import org.openecomp.aai.champ.model.ChampRelationship; + +public class ChampElementTest { + + @Test + public void testChampElement() { + final ChampElement fooElement = new ChampObject.Builder("foo").build(); + + assertTrue(fooElement.isObject()); + assertTrue(!fooElement.isRelationship()); + assertTrue(fooElement.asObject() instanceof ChampObject); + + try { + fooElement.asRelationship(); + throw new AssertionError("Failed to throw exception when calling asRelationship() on a ChampObject"); + } catch (UnsupportedOperationException e) { + //Expected + } + + final ChampElement barElement = new ChampObject.Builder("bar").build(); + final ChampElement usesElement = new ChampRelationship.Builder(fooElement.asObject(), barElement.asObject(), "uses").build(); + + assertTrue(usesElement.isRelationship()); + assertTrue(!usesElement.isObject()); + assertTrue(usesElement.asRelationship() instanceof ChampRelationship); + + try { + usesElement.asObject(); + throw new AssertionError("Failed to throw exception when calling asObject() on a ChampRelationship"); + } catch (UnsupportedOperationException e) { + //Expected + } + } +} diff --git a/src/test/java/org/openecomp/aai/champ/core/ChampFieldTest.java b/src/test/java/org/openecomp/aai/champ/core/ChampFieldTest.java new file mode 100644 index 0000000..f852d9d --- /dev/null +++ b/src/test/java/org/openecomp/aai/champ/core/ChampFieldTest.java @@ -0,0 +1,53 @@ +/** + * ============LICENSE_START========================================== + * org.onap.aai + * =================================================================== + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * =================================================================== + * 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. + * ============LICENSE_END============================================ + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.openecomp.aai.champ.core; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.openecomp.aai.champ.model.ChampField; + +public class ChampFieldTest { + + @Test + public void testChampField() { + final ChampField a = new ChampField.Builder("a") + .type(ChampField.Type.STRING) + .build(); + + final ChampField aEquivalent = new ChampField.Builder("a") + .build(); + + final ChampField b = new ChampField.Builder("b") + .build(); + + assertTrue(a.equals(aEquivalent)); + assertTrue(!a.equals(new Object())); + assertTrue(!a.equals(b)); + + assertTrue(a.compareTo(aEquivalent) == 0); + assertTrue(a.compareTo(b) != 0); + + assertTrue(a.toString().equals(aEquivalent.toString())); + assertTrue(!a.toString().equals(b.toString())); + } +} diff --git a/src/test/java/org/openecomp/aai/champ/core/ChampObjectIndexTest.java b/src/test/java/org/openecomp/aai/champ/core/ChampObjectIndexTest.java new file mode 100644 index 0000000..6f71664 --- /dev/null +++ b/src/test/java/org/openecomp/aai/champ/core/ChampObjectIndexTest.java @@ -0,0 +1,142 @@ +/** + * ============LICENSE_START========================================== + * org.onap.aai + * =================================================================== + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * =================================================================== + * 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. + * ============LICENSE_END============================================ + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.openecomp.aai.champ.core; + +import static org.junit.Assert.assertTrue; + +import java.util.Collection; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.junit.Test; +import org.openecomp.aai.champ.ChampAPI; +import org.openecomp.aai.champ.ChampGraph; +import org.openecomp.aai.champ.exceptions.ChampIndexNotExistsException; +import org.openecomp.aai.champ.model.ChampObjectIndex; + +public class ChampObjectIndexTest extends BaseChampAPITest { + @Test + public void runTest() { + for (ChampGraph.Type apiType : ChampGraph.Type.values()) { + final ChampAPI api = ChampAPI.Factory.newInstance(apiType); + final String graphName = api.getClass().getSimpleName(); + + switch (apiType) { + case IN_MEMORY: + break; + case TITAN: + cleanUp(graphName); + break; + default: + break; + } + + ChampObjectIndexTest.testChampObjectIndexCrud(api.getGraph(graphName)); + + api.shutdown(); + } + } + + private static void testChampObjectIndexCrud(ChampGraph graph) { + + final ChampObjectIndex objectIndex = ChampObjectIndex.create() + .ofName("fooObjectIndex") + .onType("foo") + .forField("propertyName") + .build(); + + testChampObjectIndexStorage(graph, objectIndex); + testChampObjectIndexDelete(graph, objectIndex); + } + + private static void testChampObjectIndexDelete(ChampGraph graph, ChampObjectIndex objectIndex) { + + if (!graph.capabilities().canDeleteObjectIndices()) { + try { + graph.deleteObjectIndex("someindex"); + throw new AssertionError("Graph claims it does not support object index delete, but failed to throw UnsupportedOperationException"); + } catch (UnsupportedOperationException e) { + } catch (ChampIndexNotExistsException e) { + throw new AssertionError("Graph claims it does not support object index delete, but failed to throw UnsupportedOperationException"); + } + } else { + try { + graph.deleteObjectIndex(objectIndex.getName()); + + final Optional<ChampObjectIndex> retrievedObjectIndex = graph.retrieveObjectIndex(objectIndex.getName()); + + if (retrievedObjectIndex.isPresent()) throw new AssertionError("Retrieved object index after deleting it"); + + final Stream<ChampObjectIndex> retrievedObjectIndices = graph.retrieveObjectIndices(); + final Collection<ChampObjectIndex> allObjectIndices = retrievedObjectIndices.collect(Collectors.toList()); + + if (allObjectIndices.contains(objectIndex)) throw new AssertionError("Retrieve all indices contained index previously deleted"); + if (allObjectIndices.size() != 0) throw new AssertionError("Wrong number of indices returned by retrieve all indices"); + + } catch (ChampIndexNotExistsException e) { + throw new AssertionError(e); + } + + try { + graph.deleteObjectIndex(objectIndex.getName()); + throw new AssertionError("Failed to throw exception on non-existent object index"); + } catch (ChampIndexNotExistsException e) { + //Expected + } + } + } + + private static void testChampObjectIndexStorage(ChampGraph graph, ChampObjectIndex objectIndex) { + + graph.storeObjectIndex(objectIndex); + graph.storeObjectIndex(objectIndex); //Test storing an already existing object index + + assertTrue(!graph.retrieveRelationshipIndex(objectIndex.getName()).isPresent()); //Make sure this wasn't stored as an object index + + final Optional<ChampObjectIndex> retrieveObjectIndex = graph.retrieveObjectIndex(objectIndex.getName()); + + if (!retrieveObjectIndex.isPresent()) throw new AssertionError("Failed to retrieve object index after storing it"); + if (!objectIndex.equals(retrieveObjectIndex.get())) throw new AssertionError("Non-equal object index returned from API after storing it"); + + final Stream<ChampObjectIndex> retrievedObjectIndices = graph.retrieveObjectIndices(); + final Collection<ChampObjectIndex> allObjectIndices = retrievedObjectIndices.collect(Collectors.toList()); + + if (!allObjectIndices.contains(objectIndex)) throw new AssertionError("Retrieve all indices did not contained index previously stored"); + if (allObjectIndices.size() != 1) throw new AssertionError("Wrong number of indices returned by retrieve all indices"); + + assertTrue(!graph.retrieveObjectIndex("nonExistentIndexName").isPresent()); + } + + @Test + public void testFluentRelationshipCreation() { + final ChampObjectIndex objectIndex = ChampObjectIndex.create() + .ofName("fooNameIndex") + .onType("foo") + .forField("name") + .build(); + + assertTrue(objectIndex.getName().equals("fooNameIndex")); + assertTrue(objectIndex.getType().equals("foo")); + assertTrue(objectIndex.getField().getName().equals("name")); + } +} diff --git a/src/test/java/org/openecomp/aai/champ/core/ChampObjectTest.java b/src/test/java/org/openecomp/aai/champ/core/ChampObjectTest.java new file mode 100644 index 0000000..f149243 --- /dev/null +++ b/src/test/java/org/openecomp/aai/champ/core/ChampObjectTest.java @@ -0,0 +1,331 @@ +/** + * ============LICENSE_START========================================== + * org.onap.aai + * =================================================================== + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * =================================================================== + * 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. + * ============LICENSE_END============================================ + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.openecomp.aai.champ.core; + +import static org.junit.Assert.assertTrue; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.junit.Test; +import org.openecomp.aai.champ.ChampAPI; +import org.openecomp.aai.champ.ChampGraph; +import org.openecomp.aai.champ.exceptions.ChampMarshallingException; +import org.openecomp.aai.champ.exceptions.ChampObjectNotExistsException; +import org.openecomp.aai.champ.exceptions.ChampSchemaViolationException; +import org.openecomp.aai.champ.exceptions.ChampUnmarshallingException; +import org.openecomp.aai.champ.model.ChampCardinality; +import org.openecomp.aai.champ.model.ChampField; +import org.openecomp.aai.champ.model.ChampObject; +import org.openecomp.aai.champ.model.ChampSchema; + +public class ChampObjectTest extends BaseChampAPITest { + + @Test + public void testHashCode() { + final ChampObject foo1 = ChampObject.create() + .ofType("foo") + .withoutKey() + .withProperty("property", "value") + .withProperty("prop", 1) + .build(); + + final ChampObject foo2 = ChampObject.create() + .ofType("foo") + .withoutKey() + .withProperty("property", "value") + .withProperty("prop", 1) + .build(); + + final ChampObject foo1Copy = ChampObject.create() + .from(foo1) + .withoutKey() + .build(); + + final ChampObject foo2Copy = ChampObject.create() + .from(foo2) + .withoutKey() + .build(); + + assertTrue(foo1.hashCode() == foo2.hashCode()); + assertTrue(foo1.hashCode() == foo1.hashCode()); + assertTrue(foo2.hashCode() == foo2.hashCode()); + assertTrue(foo1.hashCode() == foo1Copy.hashCode()); + assertTrue(foo2.hashCode() == foo2Copy.hashCode()); + + assertTrue(Collections.singleton(foo1).contains(foo1)); + assertTrue(Collections.singleton(foo1).contains(foo1Copy)); + } + + @Test + public void runTest() { + for (ChampGraph.Type apiType : ChampGraph.Type.values()) { + final String graphName = ChampObjectTest.class.getSimpleName(); + switch (apiType) { + case TITAN: + cleanUp(graphName); + break; + default: + break; + } + + final ChampAPI api = ChampAPI.Factory.newInstance(apiType); + ChampObjectTest.testChampObjectCrud(api.getGraph(graphName)); + testChampObjectReservedProperties(api.getGraph(graphName)); + api.shutdown(); + } + } + + public static void testChampObjectCrud(ChampGraph graph) { + final ChampObject bookooObject = ChampObject.create() + .ofType("foo") + .withoutKey() + .withProperty("property1", "value1") + .withProperty("integer", 1) + .withProperty("long", 1L) + .withProperty("double", 1.2) + .withProperty("float", 2.3F) + .withProperty("string", "foo") + .withProperty("boolean", true) + .withProperty("list", Collections.singletonList("list")) + .withProperty("set", Collections.singleton("set")) + .build(); + + final ChampObject storedBookooObject; + + try { + + graph.storeSchema(ChampSchema.create() + .withObjectConstraint() + .onType("foo") + .withPropertyConstraint() + .onField("list") + .ofType(ChampField.Type.STRING) + .cardinality(ChampCardinality.LIST) + .optional() + .build() + .withPropertyConstraint() + .onField("set") + .ofType(ChampField.Type.STRING) + .cardinality(ChampCardinality.SET) + .optional() + .build() + .build() + .build()); + + storedBookooObject = graph.storeObject(bookooObject); + + assertTrue(storedBookooObject.getProperty("property1").get().equals("value1")); + assertTrue(storedBookooObject.getProperty("integer").get().equals(1)); + assertTrue(storedBookooObject.getProperty("long").get().equals(1L)); + assertTrue(storedBookooObject.getProperty("double").get().equals(1.2)); + assertTrue(storedBookooObject.getProperty("float").get().equals(2.3F)); + assertTrue(storedBookooObject.getProperty("string").get().equals("foo")); + assertTrue(storedBookooObject.getProperty("boolean").get().equals(true)); + assertTrue(storedBookooObject.getProperty("list").get().equals(Collections.singletonList("list"))); + assertTrue(storedBookooObject.getProperty("set").get().equals(Collections.singleton("set"))); + + final Optional<ChampObject> retrievedBookooObject = graph.retrieveObject(storedBookooObject.getKey().get()); + final Stream<ChampObject> emptyStream = graph.queryObjects(new HashMap<String, Object> () {{ + put(ChampObject.ReservedPropertyKeys.CHAMP_OBJECT_TYPE.toString(), "foo"); + put("long", 2L); + }}); + + assertTrue(emptyStream.limit(1).count() == 0); + + final Stream<ChampObject> oneStream = graph.queryObjects(new HashMap<String, Object> () {{ + put(ChampObject.ReservedPropertyKeys.CHAMP_OBJECT_TYPE.toString(), "foo"); + put("long", 1L); + }}); + final List<ChampObject> oneObject = oneStream.limit(2).collect(Collectors.toList()); + assertTrue(oneObject.size() == 1); + assertTrue(oneObject.get(0).equals(storedBookooObject)); + + final List<ChampObject> queryByKey = graph.queryObjects(Collections.singletonMap(ChampObject.ReservedPropertyKeys.CHAMP_OBJECT_KEY.toString(), storedBookooObject.getKey().get())) + .limit(2) + .collect(Collectors.toList()); + + assertTrue(queryByKey.size() == 1); + assertTrue(queryByKey.get(0).equals(storedBookooObject)); + + if (!retrievedBookooObject.isPresent()) throw new AssertionError("Failed to retrieve stored object " + bookooObject); + if (!storedBookooObject.equals(retrievedBookooObject.get())) throw new AssertionError("Retrieved object does not equal stored object"); + + final ChampObject updatedBookoo = graph.storeObject(ChampObject.create() + .from(storedBookooObject) + .withKey(storedBookooObject.getKey().get()) + .withProperty("long", 2L) + .build()); + + final Optional<ChampObject> retrievedUpdBookooObject = graph.retrieveObject(updatedBookoo.getKey().get()); + + assertTrue(updatedBookoo.getProperty("property1").get().equals("value1")); + assertTrue(updatedBookoo.getProperty("integer").get().equals(1)); + assertTrue(updatedBookoo.getProperty("long").get().equals(2L)); + assertTrue(updatedBookoo.getProperty("double").get().equals(1.2)); + assertTrue(updatedBookoo.getProperty("float").get().equals(2.3F)); + assertTrue(updatedBookoo.getProperty("string").get().equals("foo")); + assertTrue(updatedBookoo.getProperty("boolean").get().equals(true)); + assertTrue(updatedBookoo.getProperty("list").get().equals(Collections.singletonList("list"))); + assertTrue(updatedBookoo.getProperty("set").get().equals(Collections.singleton("set"))); + + if (!retrievedUpdBookooObject.isPresent()) throw new AssertionError("Failed to retrieve stored object " + bookooObject); + if (!updatedBookoo.equals(retrievedUpdBookooObject.get())) throw new AssertionError("Retrieved object does not equal stored object"); + + //validate the replaceObject method + final ChampObject replacedBookoo = graph.replaceObject(ChampObject.create() + .ofType("foo") + .withKey(storedBookooObject.getKey().get()) + .withProperty("property1", "value2") + .withProperty("list", Collections.singletonList("list")) + .withProperty("set", Collections.singleton("set")) + .build()); + + final Optional<ChampObject> retrievedReplacedBookooObject = graph.retrieveObject(replacedBookoo.getKey().get()); + + assertTrue(replacedBookoo.getProperties().size()==3); + assertTrue(replacedBookoo.getProperty("property1").get().equals("value2")); + assertTrue(replacedBookoo.getProperty("list").get().equals(Collections.singletonList("list"))); + assertTrue(replacedBookoo.getProperty("set").get().equals(Collections.singleton("set"))); + + + if (!retrievedReplacedBookooObject.isPresent()) throw new AssertionError("Failed to retrieve stored object " + replacedBookoo); + if (!replacedBookoo.equals(retrievedReplacedBookooObject.get())) throw new AssertionError("Retrieved object does not equal stored object"); + + + + + + graph.deleteObject(storedBookooObject.getKey().get()); + if (graph.retrieveObject(storedBookooObject.getKey().get()).isPresent()) throw new AssertionError("Object not successfully deleted"); + + assertTrue(graph.queryObjects(Collections.emptyMap()).count() == 0); + assertTrue(graph.queryRelationships(Collections.emptyMap()).count() == 0); + } catch (ChampSchemaViolationException e) { + throw new AssertionError("Schema mismatch while storing object", e); + } catch (ChampMarshallingException e) { + throw new AssertionError("Marshalling exception while storing object", e); + } catch (ChampUnmarshallingException e) { + throw new AssertionError("Unmarshalling exception while retrieving object", e); + }catch (ChampObjectNotExistsException e) { + throw new AssertionError("Missing object on delete/update", e); + } + + try { + graph.deleteObject(storedBookooObject.getKey().get()); + throw new AssertionError("Delete succeeded when it should have failed"); + } catch (ChampObjectNotExistsException e) { + //Expected + } + + try { + graph.storeObject(ChampObject.create() + .ofType("foo") + .withKey("non-existent object key") + .build()); + throw new AssertionError("Expected ChampObjectNotExistsException but object was successfully stored"); + } catch (ChampObjectNotExistsException e) { + //Expected + } catch (ChampMarshallingException e) { + throw new AssertionError(e); + } catch (ChampSchemaViolationException e) { + throw new AssertionError(e); + } + + try { + // validate the replaceObject method when Object key is not passed + graph.replaceObject( + ChampObject.create().ofType("foo").withoutKey().withProperty("property1", "value2").build()); + } catch (ChampObjectNotExistsException e) { + // Expected + } catch (ChampMarshallingException e) { + throw new AssertionError(e); + } catch (ChampSchemaViolationException e) { + throw new AssertionError(e); + } + + } + + public void testChampObjectReservedProperties(ChampGraph graph) { + + for (ChampObject.ReservedPropertyKeys key : ChampObject.ReservedPropertyKeys.values()) { + try { + ChampObject.create() + .ofType(ChampObject.ReservedTypes.ANY.toString()) + .withoutKey() + .withProperty(key.toString(), "") + .build(); + throw new AssertionError("Allowed reserved property key to be used during object creation"); + } catch (IllegalArgumentException e) { + //Expected + } + } + } + + @Test + public void testFluentObjectCreation() { + final Object value1 = new Object(); + final String value2 = "value2"; + final float value3 = 0.0f; + + final ChampObject champObject1 = ChampObject.create() + .ofType("foo") + .withoutKey() + .withProperty("key1", value1) + .withProperty("key2", value2) + .withProperty("key3", value3) + .build(); + + assertTrue(champObject1.getKey().equals(Optional.empty())); + assertTrue(champObject1.getKey().isPresent() == false); + assertTrue(champObject1.getType().equals("foo")); + assertTrue(champObject1.getProperty("key1").get() instanceof Object); + assertTrue(champObject1.getProperty("key1").get().equals(value1)); + assertTrue(champObject1.getProperty("key2").get() instanceof String); + assertTrue(champObject1.getProperty("key2").get().equals(value2)); + assertTrue(champObject1.getProperty("key3").get() instanceof Float); + assertTrue(champObject1.getProperty("key3").get().equals(value3)); + + final ChampObject champObject2 = ChampObject.create() + .ofType("foo") + .withKey(1) + .withProperty("key1", value1) + .withProperty("key2", value2) + .withProperty("key3", value3) + .build(); + + assertTrue(champObject2.getType().equals("foo")); + assertTrue(champObject2.getKey().isPresent() == true); + assertTrue(champObject2.getKey().get() instanceof Integer); + assertTrue(champObject2.getKey().get().equals(1)); + assertTrue(champObject2.getProperty("key1").get() instanceof Object); + assertTrue(champObject2.getProperty("key1").get().equals(value1)); + assertTrue(champObject2.getProperty("key2").get() instanceof String); + assertTrue(champObject2.getProperty("key2").get().equals(value2)); + assertTrue(champObject2.getProperty("key3").get() instanceof Float); + assertTrue(champObject2.getProperty("key3").get().equals(value3)); + } +} diff --git a/src/test/java/org/openecomp/aai/champ/core/ChampPartitionTest.java b/src/test/java/org/openecomp/aai/champ/core/ChampPartitionTest.java new file mode 100644 index 0000000..c8671bb --- /dev/null +++ b/src/test/java/org/openecomp/aai/champ/core/ChampPartitionTest.java @@ -0,0 +1,195 @@ +/** + * ============LICENSE_START========================================== + * org.onap.aai + * =================================================================== + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * =================================================================== + * 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. + * ============LICENSE_END============================================ + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.openecomp.aai.champ.core; + +import static org.junit.Assert.assertTrue; + +import java.util.Collections; +import java.util.Optional; + +import org.junit.Test; +import org.openecomp.aai.champ.ChampAPI; +import org.openecomp.aai.champ.ChampGraph; +import org.openecomp.aai.champ.exceptions.ChampMarshallingException; +import org.openecomp.aai.champ.exceptions.ChampObjectNotExistsException; +import org.openecomp.aai.champ.exceptions.ChampRelationshipNotExistsException; +import org.openecomp.aai.champ.exceptions.ChampSchemaViolationException; +import org.openecomp.aai.champ.exceptions.ChampUnmarshallingException; +import org.openecomp.aai.champ.model.ChampObject; +import org.openecomp.aai.champ.model.ChampPartition; +import org.openecomp.aai.champ.model.ChampRelationship; + +public class ChampPartitionTest extends BaseChampAPITest { + + @Test + public void runTests() { + for (ChampGraph.Type apiType : ChampGraph.Type.values()) { + final ChampAPI api = ChampAPI.Factory.newInstance(apiType); + final String graphName = ChampPartitionTest.class.getSimpleName(); + + switch (apiType) { + case IN_MEMORY: + break; + case TITAN: + cleanUp(graphName); + break; + default: + break; + } + + ChampPartitionTest.testChampPartitionCrud(api.getGraph(graphName)); + api.shutdown(); + } + } + + @Test + public void testHashCode() { + + final ChampObject foo = ChampObject.create() + .ofType("foo") + .withoutKey() + .build(); + final ChampObject bar = ChampObject.create() + .ofType("bar") + .withoutKey() + .build(); + final ChampRelationship baz = ChampRelationship.create() + .ofType("baz") + .withoutKey() + .withSource() + .from(foo) + .build() + .withTarget() + .from(bar) + .build() + .build(); + + final ChampPartition partition = ChampPartition.create() + .withObject(foo) + .withObject(bar) + .withRelationship(baz) + .build(); + + assertTrue(partition.getChampObjects().contains(foo)); + assertTrue(partition.getChampObjects().contains(bar)); + assertTrue(partition.getChampRelationships().contains(baz)); + } + + @Test + public void testBuilder() { + final ChampObject foo = new ChampObject.Builder("foo").build(); + final ChampObject bar = new ChampObject.Builder("bar").build(); + final ChampRelationship uses = new ChampRelationship.Builder(foo, bar, "uses") + .build(); + final ChampPartition a = new ChampPartition.Builder() + .object(foo) + .objects(Collections.singleton(bar)) + .relationship(uses) + .relationships(Collections.singleton(uses)) + .build(); + assertTrue(a.getChampObjects().size() == 2); + assertTrue(a.getChampObjects().contains(foo)); + assertTrue(a.getChampObjects().contains(bar)); + + assertTrue(a.getChampRelationships().size() == 1); + assertTrue(a.getChampRelationships().contains(uses)); + } + + public static void testChampPartitionCrud(ChampGraph graph) { + + final ChampObject foo = ChampObject.create() + .ofType("foo") + .withoutKey() + .withProperty("prop1", "value1") + .build(); + final ChampObject bar = ChampObject.create() + .ofType("bar") + .withoutKey() + .withProperty("prop2", "value2") + .build(); + + final ChampRelationship baz = ChampRelationship.create() + .ofType("baz") + .withoutKey() + .withSource() + .from(foo) + .build() + .withTarget() + .from(bar) + .build() + .withProperty("prop3", "value3") + .build(); + + final ChampPartition partition = ChampPartition.create() + .withObject(foo) + .withObject(bar) + .withRelationship(baz) + .build(); + + assertTrue(partition.getIncidentRelationships(foo).contains(baz)); + assertTrue(partition.getIncidentRelationships(bar).contains(baz)); + assertTrue(partition.getIncidentRelationshipsByType(foo).get("baz").contains(baz)); + + try { + final ChampPartition storedPartition = graph.storePartition(partition); + + ChampPartitionTest.retrievePartitionElements(graph, storedPartition, true); + + graph.deletePartition(storedPartition); + + ChampPartitionTest.retrievePartitionElements(graph, storedPartition, false); + + } catch (ChampMarshallingException e) { + throw new AssertionError(e); + } catch (ChampObjectNotExistsException e) { + throw new AssertionError(e); + } catch (ChampSchemaViolationException e) { + throw new AssertionError(e); + } catch (ChampRelationshipNotExistsException e) { + throw new AssertionError(e); + } + } + + private static void retrievePartitionElements(ChampGraph graph, ChampPartition partition, boolean expectFound) { + for (ChampObject object : partition.getChampObjects()) { + try { + final Optional<ChampObject> retrievedObject = graph.retrieveObject(object.getKey().get()); + + if (!expectFound && retrievedObject.isPresent()) throw new AssertionError("Expected object to not be found, but it was found"); + if (expectFound && !retrievedObject.isPresent()) throw new AssertionError("Expected object to be found, but it was not found"); + } catch (ChampUnmarshallingException e) { + throw new AssertionError(e); + } + } + + for (ChampRelationship relationship : partition.getChampRelationships()) { + try { + final Optional<ChampRelationship> retrievedRelationship = graph.retrieveRelationship(relationship.getKey().get()); + + if (!expectFound && retrievedRelationship.isPresent()) throw new AssertionError("Expected relationship to not be found, but it was found"); + if (expectFound && !retrievedRelationship.isPresent()) throw new AssertionError("Expected relationship to be found, but it was not found"); + } catch (ChampUnmarshallingException e) { + throw new AssertionError(e); + } + } + } +} diff --git a/src/test/java/org/openecomp/aai/champ/core/ChampPropertyConstraintTest.java b/src/test/java/org/openecomp/aai/champ/core/ChampPropertyConstraintTest.java new file mode 100644 index 0000000..8ee45f4 --- /dev/null +++ b/src/test/java/org/openecomp/aai/champ/core/ChampPropertyConstraintTest.java @@ -0,0 +1,57 @@ +/** + * ============LICENSE_START========================================== + * org.onap.aai + * =================================================================== + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * =================================================================== + * 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. + * ============LICENSE_END============================================ + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.openecomp.aai.champ.core; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.openecomp.aai.champ.model.ChampCardinality; +import org.openecomp.aai.champ.model.ChampField; +import org.openecomp.aai.champ.model.ChampPropertyConstraint; + +public class ChampPropertyConstraintTest { + + @Test + public void testChampPropertyConstraint() { + final ChampField z = new ChampField.Builder("z").build(); + final ChampField y = new ChampField.Builder("y").build(); + + final ChampPropertyConstraint a = new ChampPropertyConstraint.Builder(z) + .cardinality(ChampCardinality.SINGLE) + .required(false) + .build(); + final ChampPropertyConstraint aEquivalent = new ChampPropertyConstraint.Builder(z) + .build(); + + final ChampPropertyConstraint b = new ChampPropertyConstraint.Builder(y) + .build(); + assertTrue(a.equals(aEquivalent)); + assertTrue(!a.equals(b)); + assertTrue(!a.equals(new Object())); + + assertTrue(a.toString().equals(aEquivalent.toString())); + assertTrue(!a.toString().equals(b.toString())); + + assertTrue(a.compareTo(aEquivalent) == 0); + assertTrue(a.compareTo(b) != 0); + } +} diff --git a/src/test/java/org/openecomp/aai/champ/core/ChampRelationshipIndexTest.java b/src/test/java/org/openecomp/aai/champ/core/ChampRelationshipIndexTest.java new file mode 100644 index 0000000..a611df7 --- /dev/null +++ b/src/test/java/org/openecomp/aai/champ/core/ChampRelationshipIndexTest.java @@ -0,0 +1,175 @@ +/** + * ============LICENSE_START========================================== + * org.onap.aai + * =================================================================== + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * =================================================================== + * 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. + * ============LICENSE_END============================================ + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.openecomp.aai.champ.core; + +import static org.junit.Assert.assertTrue; + +import java.util.Collection; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.junit.Test; +import org.openecomp.aai.champ.ChampAPI; +import org.openecomp.aai.champ.ChampGraph; +import org.openecomp.aai.champ.exceptions.ChampIndexNotExistsException; +import org.openecomp.aai.champ.exceptions.ChampMarshallingException; +import org.openecomp.aai.champ.exceptions.ChampObjectNotExistsException; +import org.openecomp.aai.champ.exceptions.ChampRelationshipNotExistsException; +import org.openecomp.aai.champ.exceptions.ChampSchemaViolationException; +import org.openecomp.aai.champ.exceptions.ChampUnmarshallingException; +import org.openecomp.aai.champ.model.ChampField; +import org.openecomp.aai.champ.model.ChampRelationship; +import org.openecomp.aai.champ.model.ChampRelationshipIndex; + +public class ChampRelationshipIndexTest extends BaseChampAPITest { + + @Test + public void runTest() { + for (ChampGraph.Type apiType : ChampGraph.Type.values()) { + final String graphName = ChampRelationshipIndexTest.class.getSimpleName(); + + switch (apiType) { + case IN_MEMORY: + break; + case TITAN: + cleanUp(graphName); + break; + default: + break; + } + + final ChampAPI api = ChampAPI.Factory.newInstance(apiType); + testChampRelationshipIndexCrud(api.getGraph(graphName)); + api.shutdown(); + } + } + + private void testChampRelationshipIndexCrud(ChampGraph graph) { + + final ChampField relationshipField = new ChampField.Builder("propertyName").build(); + final ChampRelationshipIndex relationshipIndex = new ChampRelationshipIndex.Builder("fooEdgeIndex", "foo", relationshipField).build(); + + //Test on an empty graph + testChampRelationshipIndexStorage(graph, relationshipIndex); + testChampRelationshipIndexDelete(graph, relationshipIndex); + + //Test with existing data in graph + try { + graph.storeRelationship(ChampRelationship.create() + .ofType("uses") + .withoutKey() + .withSource() + .ofType("foo") + .withoutKey() + .build() + .withTarget() + .ofType("bar") + .withoutKey() + .build() + .build()); + testChampRelationshipIndexStorage(graph, relationshipIndex); + testChampRelationshipIndexDelete(graph, relationshipIndex); + } catch (ChampMarshallingException e) { + throw new AssertionError(e); + } catch (ChampSchemaViolationException e) { + throw new AssertionError(e); + } catch (ChampObjectNotExistsException e) { + throw new AssertionError(e); + } catch (ChampRelationshipNotExistsException e) { + throw new AssertionError(e); + } catch (ChampUnmarshallingException e) { + throw new AssertionError(e); + } + } + + private void testChampRelationshipIndexDelete(ChampGraph graph, ChampRelationshipIndex relationshipIndex) { + + if (!graph.capabilities().canDeleteRelationshipIndices()) { + try { + graph.deleteRelationshipIndex("someindex"); + throw new AssertionError("Graph claims it doesn't support relationship index delete, but it failed to throw UnsupportedOperationException"); + } catch (UnsupportedOperationException e) { + //Expected + } catch (ChampIndexNotExistsException e) { + throw new AssertionError("Graph claims it doesn't support relationship index delete, but it failed to throw UnsupportedOperationException"); + } + } else { + try { + graph.deleteRelationshipIndex(relationshipIndex.getName()); + + final Optional<ChampRelationshipIndex> retrieveRelationshipIndex = graph.retrieveRelationshipIndex(relationshipIndex.getName()); + + if (retrieveRelationshipIndex.isPresent()) throw new AssertionError("Retrieve relationship index after deleting it"); + + final Stream<ChampRelationshipIndex> relationshipIndices = graph.retrieveRelationshipIndices(); + final Collection<ChampRelationshipIndex> allRelationshipIndices = relationshipIndices.collect(Collectors.toList()); + + if (allRelationshipIndices.contains(relationshipIndex)) throw new AssertionError("Retrieve all relationship indices contains previously deleted index"); + if (allRelationshipIndices.size() != 0) throw new AssertionError("Wrong number of relationship indices returned by retrieve all indices"); + } catch (ChampIndexNotExistsException e) { + throw new AssertionError(e); + } + + try { + graph.deleteRelationshipIndex(relationshipIndex.getName()); + throw new AssertionError("Failed to throw exception on non-existent object index"); + } catch (ChampIndexNotExistsException e) { + //Expected + } + } + } + + private void testChampRelationshipIndexStorage(ChampGraph graph, ChampRelationshipIndex relationshipIndex) { + + graph.storeRelationshipIndex(relationshipIndex); + graph.storeRelationshipIndex(relationshipIndex); //Test storing duplicate relationship index + + assertTrue(!graph.retrieveObjectIndex(relationshipIndex.getName()).isPresent()); //Make sure this wasn't stored as an object index + + final Optional<ChampRelationshipIndex> retrieveRelationshipIndex = graph.retrieveRelationshipIndex(relationshipIndex.getName()); + + if (!retrieveRelationshipIndex.isPresent()) throw new AssertionError("Failed to retrieve relationship index after storing it"); + if (!relationshipIndex.equals(retrieveRelationshipIndex.get())) throw new AssertionError("Non-equal relationship index returned from API after storing it"); + + final Stream<ChampRelationshipIndex> relationshipIndices = graph.retrieveRelationshipIndices(); + final Collection<ChampRelationshipIndex> allRelationshipIndices = relationshipIndices.collect(Collectors.toList()); + + if (!allRelationshipIndices.contains(relationshipIndex)) throw new AssertionError("Retrieve all relationship indices did not return previously stored relationship index"); + if (allRelationshipIndices.size() != 1) throw new AssertionError("Wrong number of relationship indices returned by retrieve all indices"); + + assertTrue(!graph.retrieveRelationshipIndex("nonExistentIndexName").isPresent()); + } + + @Test + public void testFluentRelationshipIndexCreation() { + final ChampRelationshipIndex relationshipIndex = ChampRelationshipIndex.create() + .ofName("fooNameIndex") + .onType("foo") + .forField("name") + .build(); + + assertTrue(relationshipIndex.getName().equals("fooNameIndex")); + assertTrue(relationshipIndex.getType().equals("foo")); + assertTrue(relationshipIndex.getField().getName().equals("name")); + } +} diff --git a/src/test/java/org/openecomp/aai/champ/core/ChampRelationshipTest.java b/src/test/java/org/openecomp/aai/champ/core/ChampRelationshipTest.java new file mode 100644 index 0000000..cf025d6 --- /dev/null +++ b/src/test/java/org/openecomp/aai/champ/core/ChampRelationshipTest.java @@ -0,0 +1,261 @@ +/** + * ============LICENSE_START========================================== + * org.onap.aai + * =================================================================== + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * =================================================================== + * 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. + * ============LICENSE_END============================================ + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.openecomp.aai.champ.core; + +import static org.junit.Assert.assertTrue; + +import java.util.Collections; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.junit.Test; +import org.openecomp.aai.champ.ChampAPI; +import org.openecomp.aai.champ.ChampGraph; +import org.openecomp.aai.champ.exceptions.ChampMarshallingException; +import org.openecomp.aai.champ.exceptions.ChampObjectNotExistsException; +import org.openecomp.aai.champ.exceptions.ChampRelationshipNotExistsException; +import org.openecomp.aai.champ.exceptions.ChampSchemaViolationException; +import org.openecomp.aai.champ.exceptions.ChampUnmarshallingException; +import org.openecomp.aai.champ.model.ChampObject; +import org.openecomp.aai.champ.model.ChampRelationship; +import org.openecomp.aai.champ.model.ChampRelationship.ReservedPropertyKeys; +import org.openecomp.aai.champ.model.ChampRelationship.ReservedTypes; + +public class ChampRelationshipTest extends BaseChampAPITest { + + @Test + public void runTest() { + for (ChampGraph.Type apiType : ChampGraph.Type.values()) { + final String graphName = ChampRelationshipTest.class.getSimpleName(); + + switch (apiType) { + case IN_MEMORY: + break; + case TITAN: + cleanUp(graphName); + break; + default: + break; + } + + final ChampAPI api = ChampAPI.Factory.newInstance(apiType); + ChampRelationshipTest.testChampRelationshipCrud(api.getGraph(graphName)); + api.shutdown(); + } + } + + public static void testChampRelationshipCrud(ChampGraph graph) { + final ChampObject source = ChampObject.create() + .ofType("foo") + .withoutKey() + .withProperty("property1", "value1") + .build(); + + final ChampObject target = ChampObject.create() + .ofType("foo") + .withoutKey() + .build(); + + try { + final ChampObject storedSource = graph.storeObject(source); + final ChampObject storedTarget = graph.storeObject(target); + + final ChampRelationship relationship = new ChampRelationship.Builder(storedSource, storedTarget, "relationship") + .property("property-1", "value-1") + .property("property-2", 3) + .build(); + + final ChampRelationship storedRelationship = graph.storeRelationship(relationship); + final Optional<ChampRelationship> retrievedRelationship = graph.retrieveRelationship(storedRelationship.getKey().get()); + + if (!retrievedRelationship.isPresent()) throw new AssertionError("Failed to retrieve stored relationship " + storedRelationship); + if (!storedRelationship.equals(retrievedRelationship.get())) throw new AssertionError("Retrieved relationship does not equal stored object"); + + assertTrue(retrievedRelationship.get().getProperty("property-1").get().equals("value-1")); + assertTrue(retrievedRelationship.get().getProperty("property-2").get().equals(3)); + + if (!graph.retrieveRelationships(storedRelationship.getSource()).collect(Collectors.toList()).contains(storedRelationship)) + throw new AssertionError("Failed to retrieve relationships for source object"); + + final ChampRelationship updatedRelationship = ChampRelationship.create() + .from(retrievedRelationship.get()) + .withKey(retrievedRelationship.get().getKey().get()) + .withProperty("property-2", 4) + .build(); + + final ChampRelationship storedUpdRel = graph.storeRelationship(updatedRelationship); + final Optional<ChampRelationship> retrievedUpdRel = graph.retrieveRelationship(storedUpdRel.getKey().get()); + + assertTrue(retrievedUpdRel.isPresent()); + assertTrue(retrievedUpdRel.get().equals(storedUpdRel)); + assertTrue(retrievedUpdRel.get().getProperty("property-1").get().equals("value-1")); + assertTrue(retrievedUpdRel.get().getProperty("property-2").get().equals(4)); + + + // validate the replaceRelationship method + final ChampRelationship replacedRelationship = new ChampRelationship.Builder(storedSource, storedTarget, "relationship") + .key(retrievedRelationship.get().getKey().get()) + .property("property-2", 4) + .build(); + + final ChampRelationship replacedRel = graph.replaceRelationship(replacedRelationship); + final Optional<ChampRelationship> retrievedReplacedRel = graph + .retrieveRelationship(replacedRel.getKey().get()); + + assertTrue(replacedRel.getProperties().size()==1); + assertTrue(replacedRel.getProperty("property-2").get().equals(4)); + + assertTrue(retrievedReplacedRel.get().getProperties().size()==1); + assertTrue(retrievedReplacedRel.get().getProperty("property-2").get().equals(4)); + + if (!retrievedReplacedRel.isPresent()) throw new AssertionError("Failed to retrieve stored relationship " + replacedRel); + if (!replacedRel.equals(retrievedReplacedRel.get())) throw new AssertionError("Retrieved relationship does not equal stored object"); + + + graph.deleteRelationship(retrievedRelationship.get()); + + if (graph.retrieveRelationship(relationship.getKey()).isPresent()) throw new AssertionError("Relationship not successfully deleted"); + + try { + graph.deleteRelationship(retrievedRelationship.get()); + throw new AssertionError("Failed to throw exception for missing relationship"); + } catch (ChampRelationshipNotExistsException e) { + //Expected + } + + assertTrue(graph.queryRelationships(Collections.emptyMap()).count() == 0); + assertTrue(graph.queryObjects(Collections.emptyMap()).count() == 2); + } catch (ChampSchemaViolationException e) { + throw new AssertionError("Schema mismatch while storing object", e); + } catch (ChampMarshallingException e) { + throw new AssertionError("Marshalling exception while storing object", e); + } catch (ChampUnmarshallingException e) { + throw new AssertionError("Unmarshalling exception while retrieving relationship", e); + } catch (ChampRelationshipNotExistsException e) { + throw new AssertionError("Attempted to delete non-existent relationship", e); + } catch (ChampObjectNotExistsException e) { + throw new AssertionError("Object does not exist after storing it", e); + } + + try { + graph.retrieveRelationships(ChampObject.create().ofType("").withoutKey().build()); + throw new AssertionError("Failed to handle missing object while retrieving relationships"); + } catch (ChampUnmarshallingException e) { + throw new AssertionError(e); + } catch (ChampObjectNotExistsException e) { + //Expected + } + //Negative test cases for replace relationship + + try{ + graph.replaceRelationship(new ChampRelationship.Builder(ChampObject.create() + .ofType("foo") + .withoutKey() + .build(), ChampObject.create() + .ofType("foo") + .withoutKey() + .build(), "relationship") + .key("1234") + .property("property-2", 4) + .build()); + } + catch (ChampUnmarshallingException e) { + throw new AssertionError(e); + } catch (ChampMarshallingException e) { + throw new AssertionError(e); + } catch (ChampSchemaViolationException e) { + throw new AssertionError(e); + } catch (ChampRelationshipNotExistsException e) { + throw new AssertionError(e); + } catch(IllegalArgumentException e){ + //expected + } + + try{ + graph.replaceRelationship(new ChampRelationship.Builder(ChampObject.create() + .ofType("foo") + .withKey("123") + .build(), ChampObject.create() + .ofType("foo") + .withKey("456") + .build(), "relationship") + .property("property-2", 4) + .build()); + } + catch (ChampUnmarshallingException e) { + throw new AssertionError(e); + } catch (ChampMarshallingException e) { + throw new AssertionError(e); + } catch (ChampSchemaViolationException e) { + throw new AssertionError(e); + } catch (ChampRelationshipNotExistsException e) { + //expected + } catch(IllegalArgumentException e){ + throw new AssertionError(e); + } + + + } + + @Test + public void testFluentRelationshipCreation() { + final Object value1 = new Object(); + final String value2 = "value2"; + final float value3 = 0.0f; + + final ChampRelationship champRelationship = ChampRelationship.create() + .ofType("foo") + .withoutKey() + .withSource() + .ofType("bar") + .withoutKey() + .build() + .withTarget() + .ofType("baz") + .withKey(1) + .build() + .withProperty("key1", value1) + .withProperty("key2", value2) + .withProperty("key3", value3) + .build(); + + assertTrue(champRelationship.getKey().equals(Optional.empty())); + assertTrue(champRelationship.getType().equals("foo")); + assertTrue(champRelationship.getProperty("key1").get() instanceof Object); + assertTrue(champRelationship.getProperty("key1").get().equals(value1)); + assertTrue(champRelationship.getProperty("key2").get() instanceof String); + assertTrue(champRelationship.getProperty("key2").get().equals(value2)); + assertTrue(champRelationship.getProperty("key3").get() instanceof Float); + assertTrue(champRelationship.getProperty("key3").get().equals(value3)); + } + + @Test + public void testChampRelationshipEnums() { + for (ReservedPropertyKeys key : ChampRelationship.ReservedPropertyKeys.values()) { + assertTrue(ChampRelationship.ReservedPropertyKeys.valueOf(key.name()) == key); + } + + for (ReservedTypes type : ChampRelationship.ReservedTypes.values()) { + assertTrue(ChampRelationship.ReservedTypes.valueOf(type.name()) == type); + } + } +} diff --git a/src/test/java/org/openecomp/aai/champ/core/ChampSchemaTest.java b/src/test/java/org/openecomp/aai/champ/core/ChampSchemaTest.java new file mode 100644 index 0000000..e3f099e --- /dev/null +++ b/src/test/java/org/openecomp/aai/champ/core/ChampSchemaTest.java @@ -0,0 +1,761 @@ +/** + * ============LICENSE_START========================================== + * org.onap.aai + * =================================================================== + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * =================================================================== + * 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. + * ============LICENSE_END============================================ + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.openecomp.aai.champ.core; + +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.Set; + +import org.junit.Test; +import org.openecomp.aai.champ.ChampAPI; +import org.openecomp.aai.champ.ChampGraph; +import org.openecomp.aai.champ.exceptions.ChampMarshallingException; +import org.openecomp.aai.champ.exceptions.ChampObjectNotExistsException; +import org.openecomp.aai.champ.exceptions.ChampSchemaViolationException; +import org.openecomp.aai.champ.model.ChampConnectionConstraint; +import org.openecomp.aai.champ.model.ChampConnectionMultiplicity; +import org.openecomp.aai.champ.model.ChampField; +import org.openecomp.aai.champ.model.ChampObject; +import org.openecomp.aai.champ.model.ChampObject.ReservedTypes; +import org.openecomp.aai.champ.model.ChampObjectConstraint; +import org.openecomp.aai.champ.model.ChampPartition; +import org.openecomp.aai.champ.model.ChampPropertyConstraint; +import org.openecomp.aai.champ.model.ChampRelationship; +import org.openecomp.aai.champ.model.ChampRelationshipConstraint; +import org.openecomp.aai.champ.model.ChampSchema; +import org.openecomp.aai.champ.schema.AlwaysValidChampSchemaEnforcer; +import org.openecomp.aai.champ.schema.ChampSchemaEnforcer; +import org.openecomp.aai.champ.schema.DefaultChampSchemaEnforcer; + +import com.fasterxml.jackson.databind.ObjectMapper; + +public class ChampSchemaTest extends BaseChampAPITest { + + @Test + public void runTest() { + for (ChampGraph.Type apiType : ChampGraph.Type.values()) { + final String graphName = ChampSchemaTest.class.getSimpleName(); + + switch (apiType) { + case IN_MEMORY: + break; + case TITAN: + cleanUp(graphName); + break; + default: + break; + } + + final ChampAPI api = ChampAPI.Factory.newInstance(apiType); + + try { + ChampSchemaTest.testChampSchemaCrud(api.getGraph(graphName)); + } catch (Throwable t) { + throw new AssertionError(apiType + " unit test failed", t); + } + + api.shutdown(); + } + } + + public static void testChampSchemaCrud(ChampGraph graph) { + + final ChampSchema schema = ChampSchema.create() + .withObjectConstraint() + .onType("foo") + .withPropertyConstraint() + .onField("property1") + .required() + .build() + .withPropertyConstraint() + .onField("property2") + .optional() + .build() + .build() + .withRelationshipConstraint() + .onType("bar") + .withPropertyConstraint() + .onField("at") + .ofType(ChampField.Type.STRING) + .optional() + .build() + .withConnectionConstraint() + .sourcedFrom("foo") + .targetedToAny() + .build() + .build() + .build(); + + try { + graph.storeSchema(schema); + } catch (ChampSchemaViolationException e) { + throw new AssertionError(e); + } + + final ChampObject emptyFoo = ChampObject.create() + .ofType("foo") + .withoutKey() + .build(); + + try { + graph.storeObject(emptyFoo); + } catch (ChampMarshallingException e1) { + throw new AssertionError(e1); + } catch (ChampSchemaViolationException e1) { + //Expected, since it does not have the required property "property1" + } catch (ChampObjectNotExistsException e) { + throw new AssertionError(e); + } + + final ChampSchema retrievedSchema = graph.retrieveSchema(); + + if (!schema.equals(retrievedSchema)) throw new AssertionError("Retrieved schema is not the same as the schema that was previously stored"); + + try { + graph.updateSchema(new ChampRelationshipConstraint.Builder("bard").build()); + assertTrue(graph.retrieveSchema().getRelationshipConstraint("bard").isPresent()); + + graph.updateSchema(new ChampObjectConstraint.Builder("baz").build()); + assertTrue(graph.retrieveSchema().getObjectConstraint("baz").isPresent()); + } catch (ChampSchemaViolationException e) { + throw new AssertionError(e); + } + + final ChampSchema updatedSchema = graph.retrieveSchema(); + + if (!updatedSchema.getObjectConstraint("baz").isPresent()) throw new AssertionError("Updated schema and retrieved, but retrieved schema did not contain updates"); + if (!updatedSchema.getRelationshipConstraint("bard").isPresent()) throw new AssertionError("Updated schema and retrieved, but retrieved schema did not contain updates"); + + try { + graph.updateSchema(new ChampObjectConstraint.Builder("foo") + .constraint( + new ChampPropertyConstraint.Builder( + new ChampField.Builder("property2") + .build() + ) + .required(false) + .build() + ) + .build()); + + final ChampObject storedEmptyFoo = graph.storeObject(emptyFoo); + + graph.deleteObject(storedEmptyFoo.getKey().get()); + } catch (ChampMarshallingException e) { + throw new AssertionError(e); + } catch (ChampSchemaViolationException e) { + throw new AssertionError(e); + } catch (ChampObjectNotExistsException e) { + throw new AssertionError(e); + } + + graph.deleteSchema(); + assertTrue(graph.retrieveSchema().equals(ChampSchema.emptySchema())); + } + + @Test + public void testChampSchemaFluentApi() { + final ChampSchema schema = ChampSchema.create() + .withObjectConstraint() + .onType("foo") + .withPropertyConstraint() + .onField("bar") + .ofType(ChampField.Type.STRING) + .required() + .build() + .withPropertyConstraint() + .onField("baz") + .ofType(ChampField.Type.BOOLEAN) + .optional() + .build() + .build() + .withRelationshipConstraint() + .onType("eats") + .withPropertyConstraint() + .onField("at") + .ofType(ChampField.Type.STRING) + .required() + .build() + .withPropertyConstraint() + .onField("for") + .optional() + .build() + .withConnectionConstraint() + .sourcedFrom("foo") + .targetedTo("foo") + .withMultiplicity(ChampConnectionMultiplicity.ONE) + .build() + .withConnectionConstraint() + .sourcedFrom("bar") + .targetedTo("bar") + .build() + .build() + .build(); + + assertTrue(schema.getObjectConstraint("foo").get().getType().equals("foo")); + + for (ChampPropertyConstraint propConst : schema.getObjectConstraint("foo").get().getPropertyConstraints()) { + if (propConst.getField().getName().equals("bar")) { + assertTrue(propConst.getField().getJavaType().equals(String.class)); + assertTrue(propConst.isRequired()); + } else if (propConst.getField().getName().equals("baz")) { + assertTrue(propConst.getField().getJavaType().equals(Boolean.class)); + assertTrue(!propConst.isRequired()); + } else { + throw new AssertionError("Unknown property constraint found: " + propConst); + } + } + + assertTrue(schema.getRelationshipConstraint("eats").get().getType().equals("eats")); + + for (ChampPropertyConstraint propConst : schema.getRelationshipConstraint("eats").get().getPropertyConstraints()) { + if (propConst.getField().getName().equals("at")) { + assertTrue(propConst.getField().getJavaType().equals(String.class)); + assertTrue(propConst.isRequired()); + } else if (propConst.getField().getName().equals("for")) { + assertTrue(propConst.getField().getJavaType().equals(String.class)); + assertTrue(!propConst.isRequired()); + } else { + throw new AssertionError("Unknown property constraint found: " + propConst); + } + } + + for (ChampConnectionConstraint connConst : schema.getRelationshipConstraint("eats").get().getConnectionConstraints()) { + if (connConst.getSourceType().equals("foo")) { + assertTrue(connConst.getTargetType().equals("foo")); + assertTrue(connConst.getMultiplicity() == ChampConnectionMultiplicity.ONE); + } else if (connConst.getSourceType().equals("bar")) { + assertTrue(connConst.getTargetType().equals("bar")); + assertTrue(connConst.getMultiplicity() == ChampConnectionMultiplicity.MANY); + } else { + throw new AssertionError("Unknown connection constraint found: " + connConst); + } + } + } + + @Test + public void testDefaultChampSchemaEnforcer() { + + final ChampSchemaEnforcer schemaEnforcer = new DefaultChampSchemaEnforcer(); + final ChampSchema champSchema = ChampSchema.create() + .withObjectConstraint() + .onType("foo") + .withPropertyConstraint() + .onField("bar") + .ofType(ChampField.Type.STRING) + .required() + .build() + .build() + .withRelationshipConstraint() + .onType("makes") + .withPropertyConstraint() + .onField("bar") + .required() + .build() + .withConnectionConstraint() + .sourcedFrom("foo") + .targetedTo("fiz") + .withMultiplicity(ChampConnectionMultiplicity.ONE) + .build() + .build() + .build(); + + try { + schemaEnforcer.validate(ChampObject.create() + .ofType("foo") + .withoutKey() + .withProperty("bar", "true") + .build(), + champSchema.getObjectConstraint("foo").get()); + } catch (ChampSchemaViolationException e) { + throw new AssertionError(e); + } + + try { + schemaEnforcer.validate(ChampObject.create() + .ofType("foo") + .withoutKey() + .build(), + champSchema.getObjectConstraint("foo").get()); + throw new AssertionError("Failed to enforce required property constraint on object"); + } catch (ChampSchemaViolationException e) { + //Expected + } + + try { + schemaEnforcer.validate(ChampObject.create() + .ofType("foo") + .withoutKey() + .withProperty("bar", true) + .build(), + champSchema.getObjectConstraint("foo").get()); + throw new AssertionError("Failed to enforce property type constraint on object"); + } catch (ChampSchemaViolationException e) { + //Expected + } + + try { + schemaEnforcer.validate(ChampRelationship.create() + .ofType("makes") + .withoutKey() + .withSource() + .ofType("foo") + .withoutKey() + .build() + .withTarget() + .ofType("fiz") + .withoutKey() + .build() + .withProperty("bar", "true") + .build(), + champSchema.getRelationshipConstraint("makes").get() + ); + } catch (ChampSchemaViolationException e) { + throw new AssertionError(e); + } + + try { + schemaEnforcer.validate(ChampRelationship.create() + .ofType("makes") + .withoutKey() + .withSource() + .ofType("foo") + .withoutKey() + .build() + .withTarget() + .ofType("fiz") + .withoutKey() + .build() + .build(), + champSchema.getRelationshipConstraint("makes").get() + ); + throw new AssertionError("Failed to enforce required property constraint on relationship"); + } catch (ChampSchemaViolationException e) { + //Expected + } + + try { + schemaEnforcer.validate(ChampPartition.create() + .withObject( + ChampObject.create() + .ofType("foo") + .withoutKey() + .withProperty("bar", "true") + .build() + ) + .withObject( + ChampObject.create() + .ofType("fiz") + .withoutKey() + .build() + ) + .withRelationship( + ChampRelationship.create() + .ofType("makes") + .withoutKey() + .withSource() + .ofType("foo") + .withoutKey() + .withProperty("bar", "true") + .build() + .withTarget() + .ofType("fiz") + .withoutKey() + .build() + .withProperty("bar", "true") + .build() + ) + .withRelationship( + ChampRelationship.create() + .ofType("makes") + .withoutKey() + .withSource() + .ofType("fiz") + .withoutKey() + .build() + .withTarget() + .ofType("foo") + .withoutKey() + .withProperty("bar", "true") + .build() + .withProperty("bar", "true") + .build() + ) + .build(), + champSchema + ); + } catch (ChampSchemaViolationException e) { + throw new AssertionError(e); + } + + try { + schemaEnforcer.validate(ChampPartition.create() + .withObject( + ChampObject.create() + .ofType("foo") + .withoutKey() + .withProperty("bar", "true") + .build() + ) + .withObject( + ChampObject.create() + .ofType("fiz") + .withoutKey() + .build() + ) + .withRelationship( + ChampRelationship.create() + .ofType("makes") + .withoutKey() + .withSource() + .ofType("foo") + .withoutKey() + .withProperty("bar", "true") + .build() + .withTarget() + .ofType("fiz") + .withoutKey() + .build() + .withProperty("bar", "true") + .build() + ) + .withRelationship( + ChampRelationship.create() + .ofType("makes") + .withoutKey() + .withSource() + .ofType("foo") + .withoutKey() + .withProperty("bar", "true") + .build() + .withTarget() + .ofType("fiz") + .withoutKey() + .build() + .withProperty("bar", "true") + .build() + ) + .build(), + champSchema + ); + throw new AssertionError("Failed to enforce connection constraint on relationship type 'makes'"); + } catch (ChampSchemaViolationException e) { + //Expected + } + } + + @Test + public void testAlwaysValidChampSchemaEnforcer() { + + final ChampSchemaEnforcer schemaEnforcer = new AlwaysValidChampSchemaEnforcer(); + + try { + schemaEnforcer.validate(ChampObject.create() + .ofType("foo") + .withoutKey() + .withProperty("bar", true) + .build(), + new ChampObjectConstraint.Builder("foo") + .constraint( + new ChampPropertyConstraint.Builder( + new ChampField.Builder("bar") + .type(ChampField.Type.STRING) + .build() + ) + .required(true) + .build() + ) + .build() + ); + + schemaEnforcer.validate(ChampRelationship.create() + .ofType("foo") + .withoutKey() + .withSource() + .ofType("foo") + .withoutKey() + .build() + .withTarget() + .ofType("fiz") + .withoutKey() + .build() + .withProperty("bar", true) + .build(), + new ChampRelationshipConstraint.Builder("bar") + .constraint( + new ChampPropertyConstraint.Builder( + new ChampField.Builder("bar") + .type(ChampField.Type.STRING) + .build() + ) + .required(true) + .build() + ) + .build() + ); + + schemaEnforcer.validate(ChampPartition.create() + .withObject( + ChampObject.create() + .ofType("foo") + .withoutKey() + .withProperty("bar", true) + .build() + ) + .withObject( + ChampObject.create() + .ofType("fiz") + .withoutKey() + .withProperty("bar", true) + .build() + ) + .withRelationship( + ChampRelationship.create() + .ofType("makes") + .withoutKey() + .withSource() + .ofType("foo") + .withoutKey() + .build() + .withTarget() + .ofType("fiz") + .withoutKey() + .build() + .build() + ) + .withRelationship( + ChampRelationship.create() + .ofType("makes") + .withoutKey() + .withSource() + .ofType("foo") + .withoutKey() + .build() + .withTarget() + .ofType("fiz") + .withoutKey() + .build() + .withProperty("bar", true) + .build() + ) + .build(), + ChampSchema.create() + .withObjectConstraint() + .onType("foo") + .withPropertyConstraint() + .onField("bar") + .required() + .build() + .build() + .withRelationshipConstraint() + .onType("makes") + .withPropertyConstraint() + .onField("bar") + .required() + .build() + .withConnectionConstraint() + .sourcedFrom("foo") + .targetedTo("fiz") + .withMultiplicity(ChampConnectionMultiplicity.ONE) + .build() + .build() + .withRelationshipConstraint() + .onType("uses") + .withConnectionConstraint() + .sourcedFromAny() + .targetedTo("computer") + .build() + .build() + .withRelationshipConstraint() + .onType("destroys") + .withConnectionConstraint() + .sourcedFrom("computer") + .targetedToAny() + .build() + .build() + .build() + + ); + } catch (ChampSchemaViolationException e) { + throw new AssertionError(e); + } + } + + @Test + public void testFluentSchemaApi() { + final ChampSchema schema = ChampSchema.create() + .withObjectConstraint() + .onType("a") + .withPropertyConstraint() + .onField("z") + .ofType(ChampField.Type.STRING) + .optional() + .build() + .build() + .withObjectConstraint() + .onType("b") + .withPropertyConstraint() + .onField("y") + .ofType(ChampField.Type.LONG) + .required() + .build() + .build() + .withRelationshipConstraint() + .onType("one") + .withPropertyConstraint() + .onField("nine") + .ofType(ChampField.Type.INTEGER) + .optional() + .build() + .withConnectionConstraint() + .sourcedFrom("a") + .targetedTo("b") + .withMultiplicity(ChampConnectionMultiplicity.NONE) + .build() + .withConnectionConstraint() + .sourcedFrom("a") + .targetedToAny() + .withMultiplicity(ChampConnectionMultiplicity.ONE) + .build() + .withConnectionConstraint() + .sourcedFromAny() + .targetedTo("b") + .withMultiplicity(ChampConnectionMultiplicity.MANY) + .build() + .withConnectionConstraint() + .sourcedFromAny() + .targetedToAny() + .withMultiplicity(ChampConnectionMultiplicity.MANY) + .build() + .build() + .build(); + + final ChampObjectConstraint aObjConstraint = schema.getObjectConstraint("a").get(); + + assertTrue(aObjConstraint.getType().equals("a")); + + final ChampPropertyConstraint zPropertyConstraint = aObjConstraint.getPropertyConstraint("z").get(); + + assertTrue(zPropertyConstraint.getField().getName().equals("z")); + assertTrue(zPropertyConstraint.getField().getJavaType().equals(String.class)); + assertTrue(!zPropertyConstraint.isRequired()); + + final ChampObjectConstraint bObjConstraint = schema.getObjectConstraint("b").get(); + + assertTrue(bObjConstraint.getType().equals("b")); + + final ChampPropertyConstraint yPropertyConstraint = bObjConstraint.getPropertyConstraint("y").get(); + + assertTrue(yPropertyConstraint.getField().getName().equals("y")); + assertTrue(yPropertyConstraint.getField().getJavaType().equals(Long.class)); + assertTrue(yPropertyConstraint.isRequired()); + + final ChampRelationshipConstraint oneRelConstraint = schema.getRelationshipConstraint("one").get(); + + assertTrue(oneRelConstraint.getType().equals("one")); + + final ChampPropertyConstraint ninePropertyConstraint = oneRelConstraint.getPropertyConstraint("nine").get(); + + assertTrue(ninePropertyConstraint.getField().getName().equals("nine")); + assertTrue(ninePropertyConstraint.getField().getJavaType().equals(Integer.class)); + assertTrue(!ninePropertyConstraint.isRequired()); + + final Set<ChampConnectionConstraint> connectionConstraints = oneRelConstraint.getConnectionConstraints(); + + for (ChampConnectionConstraint cc : connectionConstraints) { + if (cc.getSourceType().equals("a") && cc.getTargetType().equals("b")) { + assertTrue(cc.getMultiplicity() == ChampConnectionMultiplicity.NONE); + } else if (cc.getSourceType().equals(ReservedTypes.ANY.toString()) && cc.getTargetType().equals("b")) { + assertTrue(cc.getMultiplicity() == ChampConnectionMultiplicity.MANY); + } else if (cc.getSourceType().equals(ReservedTypes.ANY.toString()) && cc.getTargetType().equals(ReservedTypes.ANY.toString())) { + assertTrue(cc.getMultiplicity() == ChampConnectionMultiplicity.MANY); + } else if (cc.getSourceType().equals("a") && cc.getTargetType().equals(ReservedTypes.ANY.toString())) { + assertTrue(cc.getMultiplicity() == ChampConnectionMultiplicity.ONE); + } else { + throw new AssertionError("Found unspecified connection constraint " + cc); + } + } + } + + @Test + public void testJacksonObjectMapping() { + final ChampSchema schema = ChampSchema.create() + .withObjectConstraint() + .onType("a") + .withPropertyConstraint() + .onField("z") + .ofType(ChampField.Type.STRING) + .optional() + .build() + .build() + .withObjectConstraint() + .onType("b") + .withPropertyConstraint() + .onField("y") + .ofType(ChampField.Type.LONG) + .required() + .build() + .build() + .withRelationshipConstraint() + .onType("one") + .withPropertyConstraint() + .onField("nine") + .ofType(ChampField.Type.INTEGER) + .optional() + .build() + .withConnectionConstraint() + .sourcedFrom("a") + .targetedTo("b") + .withMultiplicity(ChampConnectionMultiplicity.NONE) + .build() + .withConnectionConstraint() + .sourcedFrom("a") + .targetedToAny() + .withMultiplicity(ChampConnectionMultiplicity.ONE) + .build() + .withConnectionConstraint() + .sourcedFromAny() + .targetedTo("b") + .withMultiplicity(ChampConnectionMultiplicity.MANY) + .build() + .withConnectionConstraint() + .sourcedFromAny() + .targetedToAny() + .withMultiplicity(ChampConnectionMultiplicity.MANY) + .build() + .build() + .build(); + + final ObjectMapper om = new ObjectMapper(); + + try { + final byte[] serialized = om.writeValueAsBytes(schema); + System.out.println(new String(serialized, "UTF-8")); + final ChampSchema deserialized = om.readValue(serialized, ChampSchema.class); + assert schema.equals(deserialized); + } catch (IOException e) { + throw new AssertionError(e); + } + + } +} diff --git a/src/test/java/org/openecomp/aai/champ/event/AbstractLoggingChampGraphTest.java b/src/test/java/org/openecomp/aai/champ/event/AbstractLoggingChampGraphTest.java new file mode 100644 index 0000000..5383d28 --- /dev/null +++ b/src/test/java/org/openecomp/aai/champ/event/AbstractLoggingChampGraphTest.java @@ -0,0 +1,1029 @@ +/** + * ============LICENSE_START========================================== + * org.onap.aai + * =================================================================== + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * =================================================================== + * 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. + * ============LICENSE_END============================================ + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.openecomp.aai.champ.event; + +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.stream.Stream; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.openecomp.aai.champ.ChampCapabilities; +import org.openecomp.aai.champ.exceptions.ChampIndexNotExistsException; +import org.openecomp.aai.champ.exceptions.ChampMarshallingException; +import org.openecomp.aai.champ.exceptions.ChampObjectNotExistsException; +import org.openecomp.aai.champ.exceptions.ChampRelationshipNotExistsException; +import org.openecomp.aai.champ.exceptions.ChampSchemaViolationException; +import org.openecomp.aai.champ.exceptions.ChampUnmarshallingException; +import org.openecomp.aai.champ.model.ChampObject; +import org.openecomp.aai.champ.model.ChampObjectConstraint; +import org.openecomp.aai.champ.model.ChampObjectIndex; +import org.openecomp.aai.champ.model.ChampPartition; +import org.openecomp.aai.champ.model.ChampRelationship; +import org.openecomp.aai.champ.model.ChampRelationshipConstraint; +import org.openecomp.aai.champ.model.ChampRelationshipIndex; +import org.openecomp.aai.champ.model.ChampSchema; +import org.slf4j.Logger; + +import com.att.nsa.cambria.client.CambriaPublisher; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; + + +public class AbstractLoggingChampGraphTest { + + /** Event stream producer stub. */ + private InMemoryPublisher producer; + + /** In memory graph for testing purposes. */ + private TestGraph testGraph; + + + /** + * Perform any setup tasks that need to be done prior to each test. + */ + @Before + public void setup() { + + // Instantiate an event stream producer stub to use in our tests. + producer = new InMemoryPublisher(); + + // Instantiate an 'in-memory' graph for test purposes. + Map<String, Object> graphProperties = new HashMap<String, Object>(); + graphProperties.put("champ.event.stream.hosts", "myeventstreamhost"); + graphProperties.put("champ.event.stream.batch-size", 1); + testGraph = new TestGraph(graphProperties, producer); + } + + + /** + * Perform any cleanup that needs to be done after each test. + */ + @After + public void tearDown() { + + // Close our stubbed producer and graph. + producer.close(); + testGraph.shutdown(); + } + + + /** + * Validates that store/replace/delete operation against vertices result in the expected events + * being published to the event stream. + * + * @throws ChampMarshallingException + * @throws ChampSchemaViolationException + * @throws ChampObjectNotExistsException + * @throws InterruptedException + * @throws JsonParseException + * @throws JsonMappingException + * @throws IOException + */ + @Test + public void vertexOperationsTest() throws ChampMarshallingException, + ChampSchemaViolationException, + ChampObjectNotExistsException, + InterruptedException, + JsonParseException, + JsonMappingException, + IOException { + + // Create a vertex and store it in the graph data store. + ChampObject obj1 = ChampObject.create() + .ofType("foo") + .withKey("123") + .withProperty("p1", "v1") + .withProperty("p2", "v2") + .build(); + testGraph.storeObject(obj1); + + // Retrieve the next event from the event stream and validate that it is what we expect. + String loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS); + assertTrue("Expected STORE event.", loggedEventStr.contains("STORE")); + assertTrue("Entity type for store event was not a vertex.", loggedEventStr.contains("vertex")); + + // Create a new vertex based on the one that we already created. + ChampObject obj2 = ChampObject.create() + .from(obj1) + .withKey("123") + .withProperty("p3", "v3") + .build(); + + // Now, try doing a replace operation. + testGraph.replaceObject(obj2); + + // Retrieve the next event from the event stream and validate that it is what we expect. + loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS); + assertTrue("Expected REPLACE event.", loggedEventStr.contains("REPLACE")); + assertTrue("Entity type for store event was not a vertex.", loggedEventStr.contains("vertex")); + + // Finally, delete the vertex. + testGraph.deleteObject("123"); + + // Retrieve the next event from the event stream and validate that it is what we expect. + loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS); + assertTrue("Expected DELETE event.", loggedEventStr.contains("DELETE")); + assertTrue("Entity type for store event was not a vertex.", loggedEventStr.contains("vertex")); + } + + + /** + * This test validates that performing vertex operations in the case where the data to be + * forwarded to the event stream is unavailable results in no event being generated, but + * does not otherwise create issues. + * + * @throws ChampMarshallingException + * @throws ChampSchemaViolationException + * @throws ChampObjectNotExistsException + * @throws InterruptedException + * @throws JsonParseException + * @throws JsonMappingException + * @throws IOException + */ + @Test + public void vertexOperationsWithNullsTest() throws ChampMarshallingException, + ChampSchemaViolationException, + ChampObjectNotExistsException, + InterruptedException, + JsonParseException, + JsonMappingException, + IOException { + + // Setup our test graph to simulate failures to retrieve data from the graph data store. + testGraph.returnNulls(); + + // Create a vertex and store it in the graph data store. + ChampObject obj1 = ChampObject.create() + .ofType("foo") + .withKey("123") + .withProperty("p1", "v1") + .withProperty("p2", "v2") + .build(); + testGraph.storeObject(obj1); + + // Check our simulated event stream to verify that an event log was produced. + String loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS); + + // Validate that we did not get an event from the stream. + assertNull("Store vertex event should not have been logged to the event stream", loggedEventStr); + + // Create a new vertex based on the one that we already created. + ChampObject obj2 = ChampObject.create() + .from(obj1) + .withKey("123") + .withProperty("p3", "v3") + .build(); + + // Now, try doing a replace operation. + testGraph.replaceObject(obj2); + + // Check our simulated event stream to see if an event log was not produced. + loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS); + + // Validate that we did not get an event from the stream. + assertNull("Store vertex event should not have been logged to the event stream", loggedEventStr); + + // Finally, delete the vertex. + testGraph.deleteObject("123"); + + // Check our simulated event stream to see if an event log was not produced. + loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS); + + // Validate that we did not get an event from the stream. + assertNull("Store vertex event should not have been logged to the event stream", loggedEventStr); + } + + + /** + * Validates that store/replace/delete operation against edges result in the expected events + * being published to the event stream. + * + * @throws ChampMarshallingException + * @throws ChampSchemaViolationException + * @throws ChampObjectNotExistsException + * @throws InterruptedException + * @throws JsonParseException + * @throws JsonMappingException + * @throws IOException + * @throws ChampUnmarshallingException + * @throws ChampRelationshipNotExistsException + */ + @Test + public void edgeOperationsTest() throws ChampMarshallingException, + ChampSchemaViolationException, + ChampObjectNotExistsException, + InterruptedException, + JsonParseException, + JsonMappingException, + IOException, + ChampUnmarshallingException, + ChampRelationshipNotExistsException { + + // Create two vertices to act as the end points of our edge. + ChampObject obj1 = ChampObject.create() + .ofType("foo") + .withKey("123") + .withProperty("p1", "v1") + .withProperty("p2", "v2") + .build(); + + ChampObject obj2 = ChampObject.create() + .ofType("bar") + .withKey("123") + .withProperty("p3", "v3") + .build(); + + // Now, create an edge object and write it to the graph data store. + ChampRelationship rel = new ChampRelationship.Builder(obj1, obj2, "relationship") + .property("property-1", "value-1") + .property("property-2", "value-2") + .build(); + testGraph.storeRelationship(rel); + + // Retrieve the next event from the event stream and validate that it is what we expect. + String loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS); + assertTrue("Expected STORE event.", loggedEventStr.contains("STORE")); + assertTrue("Entity type for store event was not an edge.", loggedEventStr.contains("relationship")); + + // Now, create another edge object based on the one we just wrote, and use it to perform + // a replace operation. + ChampRelationship rel2 = ChampRelationship.create() + .from(rel) + .withKey("123") + .withProperty("property-3", "value-3") + .build(); + testGraph.replaceRelationship(rel2); + + // Retrieve the next event from the event stream and validate that it is what we expect. + loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS); + assertTrue("Expected REPLACE event.", loggedEventStr.contains("REPLACE")); + assertTrue("Entity type for store event was not an edge.", loggedEventStr.contains("relationship")); + + // Finally, delete our edge. + testGraph.deleteRelationship(rel2); + + // Retrieve the next event from the event stream and validate that it is what we expect. + loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS); + assertTrue("Expected DELETE event.", loggedEventStr.contains("DELETE")); + assertTrue("Entity type for store event was not an edge.", loggedEventStr.contains("relationship")); + } + + + /** + * This test validates that performing edge operations in the case where the data to be + * forwarded to the event stream is unavailable results in no event being generated, but + * does not otherwise create issues. + * + * @throws ChampMarshallingException + * @throws ChampSchemaViolationException + * @throws ChampObjectNotExistsException + * @throws InterruptedException + * @throws JsonParseException + * @throws JsonMappingException + * @throws IOException + * @throws ChampUnmarshallingException + * @throws ChampRelationshipNotExistsException + */ + @Test + public void edgeOperationsWithNullsTest() throws ChampMarshallingException, + ChampSchemaViolationException, + ChampObjectNotExistsException, + InterruptedException, + JsonParseException, + JsonMappingException, + IOException, + ChampUnmarshallingException, + ChampRelationshipNotExistsException { + + // Set up our graph to simulate a failure to retrieve some of the data we need to generate + // events. + testGraph.returnNulls(); + + // Create two vertices to act as the endpoints of our edge. + ChampObject obj1 = ChampObject.create() + .ofType("foo") + .withKey("123") + .withProperty("p1", "v1") + .withProperty("p2", "v2") + .build(); + + ChampObject obj2 = ChampObject.create() + .ofType("bar") + .withKey("123") + .withProperty("p3", "v3") + .build(); + + // Now, create an edge object and write it to the graph data store. + ChampRelationship rel = new ChampRelationship.Builder(obj1, obj2, "relationship") + .property("property-1", "value-1") + .property("property-2", "value-2") + .build(); + testGraph.storeRelationship(rel); + + // Check our simulated event stream to see if an event log was produced. + String loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS); + + // Validate that we did not get an event from the stream. + assertNull("Store edge event should not have been logged to the event stream", loggedEventStr); + + // Now, create another edge object based on the one we just wrote, and use it to perform + // a replace operation. + ChampRelationship rel2 = ChampRelationship.create() + .from(rel) + .withKey("123") + .withProperty("property-3", "value-3") + .build(); + testGraph.replaceRelationship(rel2); + + // Check our simulated event stream to see if an event log was produced. + loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS); + + // Validate that we did not get an event from the stream. + assertNull("Store edge event should not have been logged to the event stream", loggedEventStr); + } + + + /** + * Validates that store/replace/delete operation against partitions result in the expected events + * being published to the event stream. + * + * @throws ChampMarshallingException + * @throws ChampSchemaViolationException + * @throws ChampObjectNotExistsException + * @throws InterruptedException + * @throws JsonParseException + * @throws JsonMappingException + * @throws IOException + * @throws ChampUnmarshallingException + * @throws ChampRelationshipNotExistsException + */ + @Test + public void partitionOperationsTest() throws ChampMarshallingException, + ChampSchemaViolationException, + ChampObjectNotExistsException, + InterruptedException, + JsonParseException, + JsonMappingException, + IOException, + ChampUnmarshallingException, + ChampRelationshipNotExistsException { + + // Create the vertices and edge objects that we need to create a partition. + ChampObject obj1 = ChampObject.create() + .ofType("foo") + .withKey("123") + .withProperty("p1", "v1") + .withProperty("p2", "v2") + .build(); + + ChampObject obj2 = ChampObject.create() + .ofType("bar") + .withKey("123") + .withProperty("p3", "v3") + .build(); + + // Now, create an edge object and write it to the graph data store. + ChampRelationship rel = new ChampRelationship.Builder(obj1, obj2, "relationship") + .property("property-1", "value-1") + .property("property-2", "value-2") + .build(); + + // Now, create our partition object and store it in the graph. + ChampPartition partition = ChampPartition.create() + .withObject(obj1) + .withObject(obj2) + .withRelationship(rel) + .build(); + testGraph.storePartition(partition); + + // Retrieve the next event from the event stream and validate that it is what we expect. + String loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS); + assertTrue("Expected STORE event.", loggedEventStr.contains("STORE")); + assertTrue("Entity type for store event was not a partition.", loggedEventStr.contains("partition")); + + // Now, delete our partition. + testGraph.deletePartition(partition); + + // Retrieve the next event from the event stream and validate that it is what we expect. + loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS); + assertTrue("Expected DELETE event.", loggedEventStr.contains("DELETE")); + assertTrue("Entity type for store event was not a partition.", loggedEventStr.contains("partition")); + } + + + /** + * This test validates that performing partition operations in the case where the data to be + * forwarded to the event stream is unavailable results in no event being generated, but + * does not otherwise create issues. + * + * @throws ChampMarshallingException + * @throws ChampSchemaViolationException + * @throws ChampObjectNotExistsException + * @throws InterruptedException + * @throws JsonParseException + * @throws JsonMappingException + * @throws IOException + * @throws ChampUnmarshallingException + * @throws ChampRelationshipNotExistsException + */ + @Test + public void partitionOperationsWithNullsTest() throws ChampMarshallingException, + ChampSchemaViolationException, + ChampObjectNotExistsException, + InterruptedException, + JsonParseException, + JsonMappingException, + IOException, + ChampUnmarshallingException, + ChampRelationshipNotExistsException { + + // Set up our graph to simulate a failure to retrieve some of the data we need to generate + // events. + testGraph.returnNulls(); + + // Create all of the objects we need to create a partition, and store the partition + // in the graph. + ChampObject obj1 = ChampObject.create() + .ofType("foo") + .withKey("123") + .withProperty("p1", "v1") + .withProperty("p2", "v2") + .build(); + + ChampObject obj2 = ChampObject.create() + .ofType("bar") + .withKey("123") + .withProperty("p3", "v3") + .build(); + + ChampRelationship rel = new ChampRelationship.Builder(obj1, obj2, "relationship") + .property("property-1", "value-1") + .property("property-2", "value-2") + .build(); + + ChampPartition partition = ChampPartition.create() + .withObject(obj1) + .withObject(obj2) + .withRelationship(rel) + .build(); + testGraph.storePartition(partition); + + // Check our simulated event stream to see if an an event log was produced. + String loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS); + + // Validate that we did not get an event from the stream. + assertNull("Store partition event should not have been logged to the event stream", loggedEventStr); + } + + + /** + * Validates that store/replace/delete operation against vertex indexes result in the expected + * events being published to the event stream. + * + * @throws ChampMarshallingException + * @throws ChampSchemaViolationException + * @throws ChampObjectNotExistsException + * @throws InterruptedException + * @throws JsonParseException + * @throws JsonMappingException + * @throws IOException + * @throws ChampUnmarshallingException + * @throws ChampRelationshipNotExistsException + * @throws ChampIndexNotExistsException + */ + @Test + public void indexOperationsTest() throws ChampMarshallingException, + ChampSchemaViolationException, + ChampObjectNotExistsException, + InterruptedException, + JsonParseException, + JsonMappingException, + IOException, + ChampUnmarshallingException, + ChampRelationshipNotExistsException, + ChampIndexNotExistsException { + + // Create an index object and store it in the graph. + ChampObjectIndex objIndex = ChampObjectIndex.create() + .ofName("myIndex") + .onType("type") + .forField("myField") + .build(); + testGraph.storeObjectIndex(objIndex); + + // Retrieve the next event from the event stream and validate that it is what we expect. + String loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS); + assertTrue("Expected STORE event.", loggedEventStr.contains("STORE")); + assertTrue("Entity type for store event was not a vertex index.", loggedEventStr.contains("objectIndex")); + + // Now, delete our partition. + testGraph.deleteObjectIndex("myIndex"); + + // Retrieve the next event from the event stream and validate that it is what we expect. + loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS); + assertTrue("Expected DELETE event.", loggedEventStr.contains("DELETE")); + assertTrue("Entity type for store event was not a vertex index.", loggedEventStr.contains("objectIndex")); + } + + /** + * This test validates that performing index operations in the case where the data to be + * forwarded to the event stream is unavailable results in no event being generated, but + * does not otherwise create issues. + * + * @throws ChampMarshallingException + * @throws ChampSchemaViolationException + * @throws ChampObjectNotExistsException + * @throws InterruptedException + * @throws JsonParseException + * @throws JsonMappingException + * @throws IOException + * @throws ChampUnmarshallingException + * @throws ChampRelationshipNotExistsException + * @throws ChampIndexNotExistsException + */ + @Test + public void indexOperationsWithNullsTest() throws ChampMarshallingException, + ChampSchemaViolationException, + ChampObjectNotExistsException, + InterruptedException, + JsonParseException, + JsonMappingException, + IOException, + ChampUnmarshallingException, + ChampRelationshipNotExistsException, + ChampIndexNotExistsException { + + // Set up our graph to simulate a failure to retrieve some of the data we need to generate + // events. + testGraph.returnNulls(); + + // Create an index object and store it in the graph. + ChampObjectIndex objIndex = ChampObjectIndex.create() + .ofName("myIndex") + .onType("type") + .forField("myField") + .build(); + testGraph.storeObjectIndex(objIndex); + + // Check our simulated event stream to see if an an event log was produced. + String loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS); + + // Now, delete our index. + testGraph.deleteObjectIndex("myIndex"); + + // Check our simulated event stream to see if an an event log was produced. + loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS); + + // Validate that we did not get an event from the stream. + assertNull("Delete partition event should not have been logged to the event stream", loggedEventStr); + } + + + /** + * This test validates that performing relationship index operations in the case where + * the data to be forwarded to the event stream is unavailable results in no event being + * generated, but does not otherwise create issues. + * + * @throws ChampMarshallingException + * @throws ChampSchemaViolationException + * @throws ChampObjectNotExistsException + * @throws InterruptedException + * @throws JsonParseException + * @throws JsonMappingException + * @throws IOException + * @throws ChampUnmarshallingException + * @throws ChampRelationshipNotExistsException + * @throws ChampIndexNotExistsException + */ + @Test + public void relationshipIndexOperationsTest() throws ChampMarshallingException, + ChampSchemaViolationException, + ChampObjectNotExistsException, + InterruptedException, + JsonParseException, + JsonMappingException, + IOException, + ChampUnmarshallingException, + ChampRelationshipNotExistsException, + ChampIndexNotExistsException { + + // Create a relationship index object and store it in the graph. + ChampRelationshipIndex relIndex = ChampRelationshipIndex.create() + .ofName("myIndex") + .onType("type") + .forField("myField") + .build(); + testGraph.storeRelationshipIndex(relIndex); + + // Retrieve the next event from the event stream and validate that it is what we expect. + String loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS); + assertTrue("Expected STORE event.", loggedEventStr.contains("STORE")); + assertTrue("Entity type for store event was not a relationship index.", loggedEventStr.contains("relationshipIndex")); + + // Now, delete our partition. + testGraph.deleteRelationshipIndex("myIndex"); + + // Retrieve the next event from the event stream and validate that it is what we expect. + loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS); + assertTrue("Expected DELETE event.", loggedEventStr.contains("DELETE")); + assertTrue("Entity type for store event was not a relationship index.", loggedEventStr.contains("relationshipIndex")); + } + + + /** + * This test validates that performing index operations in the case where the data to be + * forwarded to the event stream is unavailable results in no event being generated, but + * does not otherwise create issues. + * + * @throws ChampMarshallingException + * @throws ChampSchemaViolationException + * @throws ChampObjectNotExistsException + * @throws InterruptedException + * @throws JsonParseException + * @throws JsonMappingException + * @throws IOException + * @throws ChampUnmarshallingException + * @throws ChampRelationshipNotExistsException + * @throws ChampIndexNotExistsException + */ + @Test + public void relationshipIndexOperationsWithNullsTest() throws ChampMarshallingException, + ChampSchemaViolationException, + ChampObjectNotExistsException, + InterruptedException, + JsonParseException, + JsonMappingException, + IOException, + ChampUnmarshallingException, + ChampRelationshipNotExistsException, + ChampIndexNotExistsException { + + // Set up our graph to simulate a failure to retrieve some of the data we need to generate + // events. + testGraph.returnNulls(); + + // Create a relationship index object and store it in the graph. + ChampRelationshipIndex relIndex = ChampRelationshipIndex.create() + .ofName("myIndex") + .onType("type") + .forField("myField") + .build(); + + testGraph.storeRelationshipIndex(relIndex); + + // Check our simulated event stream to see if an an event log was produced. + String loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS); + + // Now, delete our index. + testGraph.deleteRelationshipIndex("myIndex"); + + // Check our simulated event stream to see if an event log was produced. + loggedEventStr = producer.eventStream.poll(5000, TimeUnit.MILLISECONDS); + + // Validate that we did not get an event from the stream. + assertNull("Delete partition event should not have been logged to the event stream", loggedEventStr); + } + + + /** + * This is a simple graph stub that extends our {@link AbstractLoggingChampGraph} class which + * we can use to validate that log events get generated without worrying about having a real + * underlying graph. + */ + private class TestGraph extends AbstractLoggingChampGraph { + + /** If set, this causes simulated retrieve operations to fail. */ + private boolean returnNulls = false; + + + protected TestGraph(Map<String, Object> properties, CambriaPublisher producer) { + super(properties); + + setProducer(producer); + } + + public void returnNulls() { + returnNulls = true; + } + + @Override + public void shutdown() { + if(returnNulls) { + publisherPool = null; + } + super.shutdown(); + } + + @Override + public ChampObject executeStoreObject(ChampObject object) throws ChampMarshallingException, + ChampSchemaViolationException, + ChampObjectNotExistsException { + if(!returnNulls) { + return object; + } else { + return null; + } + } + + @Override + public ChampObject executeReplaceObject(ChampObject object) throws ChampMarshallingException, + ChampSchemaViolationException, + ChampObjectNotExistsException { + if(!returnNulls) { + return object; + } else { + return null; + } + } + + @Override + public Optional<ChampObject> retrieveObject(Object key) throws ChampUnmarshallingException { + + if(!returnNulls) { + return(Optional.of(ChampObject.create() + .ofType("foo") + .withKey(key) + .build())); + } else { + return Optional.empty(); + } + } + + @Override + public void executeDeleteObject(Object key) throws ChampObjectNotExistsException { + + } + + @Override + public Stream<ChampObject> queryObjects(Map<String, Object> queryParams) { + // Not used by any tests. + return null; + } + + @Override + public ChampRelationship executeStoreRelationship(ChampRelationship relationship) + throws ChampUnmarshallingException, + ChampMarshallingException, + ChampObjectNotExistsException, + ChampSchemaViolationException, + ChampRelationshipNotExistsException { + + if(!returnNulls) { + return relationship; + } else { + return null; + } + } + + @Override + public ChampRelationship executeReplaceRelationship(ChampRelationship relationship) + throws ChampUnmarshallingException, + ChampMarshallingException, + ChampSchemaViolationException, + ChampRelationshipNotExistsException { + + if(!returnNulls) { + return relationship; + } else { + return null; + } + } + + @Override + public Optional<ChampRelationship> retrieveRelationship(Object key) throws ChampUnmarshallingException { + // Not used by any tests. + return null; + } + + @Override + public void executeDeleteRelationship(ChampRelationship relationship) throws ChampRelationshipNotExistsException { + // Not used by any tests. + } + + @Override + public Stream<ChampRelationship> retrieveRelationships(ChampObject object) + throws ChampUnmarshallingException, ChampObjectNotExistsException { + + // Not used by any tests. + return null; + } + + @Override + public Stream<ChampRelationship> queryRelationships(Map<String, Object> queryParams) { + + // Not used by any tests. + return null; + } + + @Override + public ChampPartition executeStorePartition(ChampPartition partition) + throws ChampSchemaViolationException, + ChampRelationshipNotExistsException, + ChampMarshallingException, + ChampObjectNotExistsException { + + if(!returnNulls) { + return partition; + } else { + return null; + } + } + + @Override + public void executeDeletePartition(ChampPartition graph) { + // Not used by any tests. + } + + @Override + public void executeStoreObjectIndex(ChampObjectIndex index) { + // Not used by any tests. + } + + @Override + public Optional<ChampObjectIndex> retrieveObjectIndex(String indexName) { + + if(!returnNulls) { + return Optional.of(ChampObjectIndex.create() + .ofName(indexName) + .onType("doesnt matter") + .forField("doesnt matter") + .build()); + } else { + return Optional.empty(); + } + } + + @Override + public Stream<ChampObjectIndex> retrieveObjectIndices() { + // Not used by any tests. + return null; + } + + @Override + public void executeDeleteObjectIndex(String indexName) throws ChampIndexNotExistsException { + // Not used by any tests. + } + + @Override + public void executeStoreRelationshipIndex(ChampRelationshipIndex index) { + // Not used by any tests. + } + + @Override + public Optional<ChampRelationshipIndex> retrieveRelationshipIndex(String indexName) { + if(!returnNulls) { + return Optional.of(ChampRelationshipIndex.create() + .ofName(indexName) + .onType("doesnt matter") + .forField("doesnt matter") + .build()); + } else { + return Optional.empty(); + } + } + + @Override + public Stream<ChampRelationshipIndex> retrieveRelationshipIndices() { + // Not used by any tests. + return null; + } + + @Override + public void executeDeleteRelationshipIndex(String indexName) + throws ChampIndexNotExistsException { + // Not used by any tests. + } + + @Override + public void storeSchema(ChampSchema schema) throws ChampSchemaViolationException { + // Not used by any tests. + } + + @Override + public ChampSchema retrieveSchema() { + // Not used by any tests. + return null; + } + + @Override + public void updateSchema(ChampObjectConstraint objectConstraint) + throws ChampSchemaViolationException { + // Not used by any tests. + } + + @Override + public void updateSchema(ChampRelationshipConstraint schema) + throws ChampSchemaViolationException { + // Not used by any tests. + } + + @Override + public void deleteSchema() { + // Not used by any tests. + } + + @Override + public ChampCapabilities capabilities() { + // Not used by any tests. + return null; + } + } + + private class InMemoryPublisher implements CambriaPublisher { + + public BlockingQueue<String> eventStream = new ArrayBlockingQueue<String>(50); + public BlockingQueue<String> failedMsgs = new ArrayBlockingQueue<String>(10); + + private boolean failMode=false; + + public void enterFailMode() { + failMode=true; + } + + @Override + public void logTo(Logger log) { + // Not used by any tests. + } + + @Override + public void setApiCredentials(String apiKey, String apiSecret) { + // Not used by any tests. + } + + @Override + public void clearApiCredentials() { + // Not used by any tests. + } + + @Override + public void setHttpBasicCredentials(String username, String password) { + // Not used by any tests. + } + + @Override + public void clearHttpBasicCredentials() { + // Not used by any tests. + } + + @Override + public int send(String partition, String msg) throws IOException { + + if(!failMode) { + eventStream.add(msg); + return 0; + } else { + failedMsgs.add(msg); + throw new IOException("nope"); + } + } + + @Override + public int send(message msg) throws IOException { + eventStream.add(msg.toString()); + return 0; + } + + @Override + public int send(Collection<message> msgs) throws IOException { + for(message msg : msgs) { + eventStream.add(msg.toString()); + } + return 0; + } + + @Override + public void close() { + // Not used by any tests. + } + } +} diff --git a/src/test/java/org/openecomp/aai/champ/exceptions/ChampExceptionTest.java b/src/test/java/org/openecomp/aai/champ/exceptions/ChampExceptionTest.java new file mode 100644 index 0000000..3f813f5 --- /dev/null +++ b/src/test/java/org/openecomp/aai/champ/exceptions/ChampExceptionTest.java @@ -0,0 +1,150 @@ +/** + * ============LICENSE_START========================================== + * org.onap.aai + * =================================================================== + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * =================================================================== + * 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. + * ============LICENSE_END============================================ + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.openecomp.aai.champ.exceptions; + +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +public class ChampExceptionTest { + + @Test + public void testChampIndexNotExistsException() { + final ChampIndexNotExistsException e1 = new ChampIndexNotExistsException(); + + assertTrue(e1.getMessage() == null); + + final ChampIndexNotExistsException e2 = new ChampIndexNotExistsException("foo"); + + assertTrue(e2.getMessage().equals("foo")); + + final ChampIndexNotExistsException e3 = new ChampIndexNotExistsException(e2); + + assertTrue(e3.getCause().equals(e2)); + + final ChampIndexNotExistsException e4 = new ChampIndexNotExistsException("foo", e3); + + assertTrue(e4.getMessage().equals("foo")); + assertTrue(e4.getCause().equals(e3)); + } + + @Test + public void testChampMarshallingException() { + final ChampMarshallingException e1 = new ChampMarshallingException(); + + assertTrue(e1.getMessage() == null); + + final ChampMarshallingException e2 = new ChampMarshallingException("foo"); + + assertTrue(e2.getMessage().equals("foo")); + + final ChampIndexNotExistsException e3 = new ChampIndexNotExistsException(e2); + + assertTrue(e3.getCause().equals(e2)); + + final ChampMarshallingException e4 = new ChampMarshallingException("foo", e3); + + assertTrue(e4.getMessage().equals("foo")); + assertTrue(e4.getCause().equals(e3)); + } + + @Test + public void testChampObjectNotExistsException() { + final ChampObjectNotExistsException e1 = new ChampObjectNotExistsException(); + + assertTrue(e1.getMessage() == null); + + final ChampObjectNotExistsException e2 = new ChampObjectNotExistsException("foo"); + + assertTrue(e2.getMessage().equals("foo")); + + final ChampIndexNotExistsException e3 = new ChampIndexNotExistsException(e2); + + assertTrue(e3.getCause().equals(e2)); + + final ChampObjectNotExistsException e4 = new ChampObjectNotExistsException("foo", e3); + + assertTrue(e4.getMessage().equals("foo")); + assertTrue(e4.getCause().equals(e3)); + } + + @Test + public void testChampRelationshipNotExistsException() { + final ChampRelationshipNotExistsException e1 = new ChampRelationshipNotExistsException(); + + assertTrue(e1.getMessage() == null); + + final ChampRelationshipNotExistsException e2 = new ChampRelationshipNotExistsException("foo"); + + assertTrue(e2.getMessage().equals("foo")); + + final ChampIndexNotExistsException e3 = new ChampIndexNotExistsException(e2); + + assertTrue(e3.getCause().equals(e2)); + + final ChampRelationshipNotExistsException e4 = new ChampRelationshipNotExistsException("foo", e3); + + assertTrue(e4.getMessage().equals("foo")); + assertTrue(e4.getCause().equals(e3)); + } + + @Test + public void testChampSchemaViolationException() { + final ChampSchemaViolationException e1 = new ChampSchemaViolationException(); + + assertTrue(e1.getMessage() == null); + + final ChampSchemaViolationException e2 = new ChampSchemaViolationException("foo"); + + assertTrue(e2.getMessage().equals("foo")); + + final ChampIndexNotExistsException e3 = new ChampIndexNotExistsException(e2); + + assertTrue(e3.getCause().equals(e2)); + + final ChampSchemaViolationException e4 = new ChampSchemaViolationException("foo", e3); + + assertTrue(e4.getMessage().equals("foo")); + assertTrue(e4.getCause().equals(e3)); + } + + @Test + public void testChampUnmarshallingException() { + final ChampUnmarshallingException e1 = new ChampUnmarshallingException(); + + assertTrue(e1.getMessage() == null); + + final ChampUnmarshallingException e2 = new ChampUnmarshallingException("foo"); + + assertTrue(e2.getMessage().equals("foo")); + + final ChampIndexNotExistsException e3 = new ChampIndexNotExistsException(e2); + + assertTrue(e3.getCause().equals(e2)); + + final ChampUnmarshallingException e4 = new ChampUnmarshallingException("foo", e3); + + assertTrue(e4.getMessage().equals("foo")); + assertTrue(e4.getCause().equals(e3)); + } + +} diff --git a/src/test/java/org/openecomp/aai/champ/ie/ExportTest.java b/src/test/java/org/openecomp/aai/champ/ie/ExportTest.java new file mode 100644 index 0000000..7ecb3de --- /dev/null +++ b/src/test/java/org/openecomp/aai/champ/ie/ExportTest.java @@ -0,0 +1,42 @@ +/** + * ============LICENSE_START========================================== + * org.onap.aai + * =================================================================== + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * =================================================================== + * 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. + * ============LICENSE_END============================================ + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.openecomp.aai.champ.ie; + +import org.junit.Test; +import org.openecomp.aai.champ.ChampAPI; +import org.openecomp.aai.champ.ChampGraph; + +public class ExportTest { + + @Test + public void testGraphMLExport() { + + final GraphMLImporterExporter ie = new GraphMLImporterExporter(); + final ChampAPI api = ChampAPI.Factory.newInstance(ChampGraph.Type.IN_MEMORY); + + ie.importData(api, getClass().getClassLoader().getResourceAsStream("import-test.graphml")); + + ie.exportData(api.getGraph("unit-test"), System.out); + + api.shutdown(); + } +} diff --git a/src/test/java/org/openecomp/aai/champ/ie/ImportTest.java b/src/test/java/org/openecomp/aai/champ/ie/ImportTest.java new file mode 100644 index 0000000..ba2cbb1 --- /dev/null +++ b/src/test/java/org/openecomp/aai/champ/ie/ImportTest.java @@ -0,0 +1,93 @@ +/** + * ============LICENSE_START========================================== + * org.onap.aai + * =================================================================== + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 Amdocs + * =================================================================== + * 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. + * ============LICENSE_END============================================ + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.openecomp.aai.champ.ie; + +import static org.junit.Assert.assertTrue; + +import java.util.Collections; +import java.util.Optional; + +import org.junit.Test; +import org.openecomp.aai.champ.ChampAPI; +import org.openecomp.aai.champ.ChampGraph; + +public class ImportTest { + + private final String GRAPH_NAME = "unit-test"; + + @Test + public void testGraphMLImport() { + + final GraphMLImporterExporter importer = new GraphMLImporterExporter(); + final ChampAPI api = ChampAPI.Factory.newInstance(ChampGraph.Type.IN_MEMORY); + + importer.importData(api, getClass().getClassLoader().getResourceAsStream("import-test.graphml")); + + final ChampGraph graph = api.getGraph(GRAPH_NAME); + + graph.queryObjects(Collections.emptyMap()).forEach(object -> { + final Optional<String> nameOpt = object.getProperty("name"); + final Optional<Boolean> studentOpt = object.getProperty("student"); + final Optional<Long> worthOpt = object.getProperty("worth"); + final Optional<Integer> ageOpt = object.getProperty("age"); + final Optional<Float> heightOpt = object.getProperty("height"); + final Optional<Double> weightOpt = object.getProperty("weight"); + final Optional<String> favoriteColorOpt = object.getProperty("favoriteColor"); + + final String name = nameOpt.get(); + + if (name.equals("Champ")) { + assertTrue(!studentOpt.isPresent()); + assertTrue(!ageOpt.isPresent()); + assertTrue(!worthOpt.isPresent()); + assertTrue(!heightOpt.isPresent()); + assertTrue(!weightOpt.isPresent()); + assertTrue(favoriteColorOpt.get().equals("green")); + } else if (name.equals("Max")) { + assertTrue(!studentOpt.isPresent()); + assertTrue(!ageOpt.isPresent()); + assertTrue(!worthOpt.isPresent()); + assertTrue(!heightOpt.isPresent()); + assertTrue(!weightOpt.isPresent()); + assertTrue(favoriteColorOpt.get().equals("red")); + } else if (name.equals("Ace")) { + assertTrue(studentOpt.get()); + assertTrue(worthOpt.get().equals(50000L)); + assertTrue(ageOpt.get().equals(21)); + assertTrue(heightOpt.get().equals(72.5f)); + assertTrue(weightOpt.get().equals(180.5d)); + assertTrue(favoriteColorOpt.get().equals("yellow")); + } else if (name.equals("Fido")) { + assertTrue(!studentOpt.isPresent()); + assertTrue(!ageOpt.isPresent()); + assertTrue(!worthOpt.isPresent()); + assertTrue(!heightOpt.isPresent()); + assertTrue(!weightOpt.isPresent()); + assertTrue(favoriteColorOpt.get().equals("blue")); + } else { + throw new AssertionError("Unknown object " + name + " - update unit test"); + } + }); + + api.shutdown(); + } +} diff --git a/src/test/resources/import-test.graphml b/src/test/resources/import-test.graphml new file mode 100755 index 0000000..fd13b6b --- /dev/null +++ b/src/test/resources/import-test.graphml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8"?> +<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" +xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd"> + <key id="d0" for="node" attr.name="student" attr.type="boolean"/> + <key id="d1" for="node" attr.name="worth" attr.type="long"/> + <key id="d2" for="node" attr.name="age" attr.type="int"/> + <key id="d3" for="node" attr.name="height" attr.type="float"/> + <key id="d4" for="node" attr.name="weight" attr.type="double"/> + <key id="d5" for="node" attr.name="favoriteColor" attr.type="string"> + <default>green</default> + </key> + <key id="d6" for="node" attr.name="name" attr.type="string"/> + <key id="d7" for="edge" attr.name="at" attr.type="long"/> + <key id="d8" for="node" attr.name="type" attr.type="string"/> + <key id="d9" for="edge" attr.name="type" attr.type="string"/> + <graph id="unit-test" edgedefault="directed"> + <node id="n0"> + <data key="d0">true</data> + <data key="d1">50000</data> + <data key="d2">21</data> + <data key="d3">72.5</data> + <data key="d4">180.5</data> + <data key="d5">yellow</data> + <data key="d6">Ace</data> + <data key="d8">Dog</data> + </node> + <node id="n1"> + <data key="d6">Champ</data> + <data key="d8">Dog</data> + </node> + <node id="n2"> + <data key="d5">blue</data> + <data key="d6">Fido</data> + <data key="d8">Dog</data> + </node> + <node id="n3"> + <data key="d5">red</data> + <data key="d6">Max</data> + <data key="d8">Dog</data> + </node> + <edge id="e0" source="n0" target="n2"> + <data key="d7">12348234</data> + <data key="d9">Dog</data> + </edge> + <edge id="e3" source="n3" target="n2"> + <data key="d9">Dog</data> + </edge> + </graph> +</graphml>
\ No newline at end of file diff --git a/src/test/resources/logback.xml b/src/test/resources/logback.xml new file mode 100644 index 0000000..72cd644 --- /dev/null +++ b/src/test/resources/logback.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + ============LICENSE_START========================================== + org.onap.aai + =================================================================== + Copyright © 2017 AT&T Intellectual Property. All rights reserved. + Copyright © 2017 Amdocs + =================================================================== + 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. + ============LICENSE_END============================================ + ECOMP is a trademark and service mark of AT&T Intellectual Property. + +--> +<configuration> + + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + <encoder> + <pattern>%d %-5level [%thread] %logger{255}: %msg%n</pattern> + </encoder> + </appender> + + <logger name="com.thinkaurelius.titan" level="OFF"/> + <logger name="com.netflix.astyanax" level="OFF"/> + <logger name="com.datastax" level="ERROR"/> + <logger name="org.apache.hadoop" level="ERROR"/> + <logger name="org.apache.zookeeper" level="ERROR"/> + + <root level="INFO"> + <appender-ref ref="STDOUT" /> + </root> + +</configuration> |