This is an automated email from the ASF dual-hosted git repository. hasan pushed a commit to branch reunited in repository https://gitbox.apache.org/repos/asf/clerezza.git
commit 209ee5711d04aae1f0a3278f2c6d49f2149a4142 Author: Hasan <[email protected]> AuthorDate: Wed Feb 6 21:38:53 2019 +0100 CLEREZZA-1035: Copy rdf.core.test from rdf module to test.utils --- test.utils/LICENSE | 201 ++++++++ test.utils/pom.xml | 62 +++ .../org/apache/clerezza/test/utils/GraphTest.java | 561 +++++++++++++++++++++ .../apache/clerezza/test/utils/GraphWrapper.java | 120 +++++ .../apache/clerezza/test/utils/LockChecker.java | 40 ++ .../utils/LockableMGraphWrapperForTesting.java | 72 +++ .../test/utils/LockingIteratorForTesting.java | 80 +++ .../apache/clerezza/test/utils/RandomGraph.java | 233 +++++++++ .../apache/clerezza/test/utils/TcProviderTest.java | 479 ++++++++++++++++++ 9 files changed, 1848 insertions(+) diff --git a/test.utils/LICENSE b/test.utils/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/test.utils/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/test.utils/pom.xml b/test.utils/pom.xml new file mode 100644 index 0000000..0b14eae --- /dev/null +++ b/test.utils/pom.xml @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright + ownership. The ASF licenses this file to you under the Apache + License, Version 2.0 (the "License"); you may not use this file + except in compliance with the License. You may obtain a copy of + the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + either express or implied. See the License for the specific + language governing permissions and limitations under the License. +--> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.clerezza</groupId> + <artifactId>clerezza</artifactId> + <version>8-SNAPSHOT</version> + <relativePath/> + </parent> + + <artifactId>test.utils</artifactId> + <packaging>jar</packaging> + <version>8-SNAPSHOT</version> + <name>Clerezza - Test Utilities</name> + <description>Utilities to test Clerezza API and dataset implementations</description> + + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </dependency> + <dependency> + <groupId>org.apache.clerezza</groupId> + <artifactId>api</artifactId> + <version>8-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>org.apache.clerezza</groupId> + <artifactId>api.impl</artifactId> + <version>8-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>org.apache.clerezza</groupId> + <artifactId>dataset</artifactId> + <version>8-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + </dependency> + </dependencies> +</project> \ No newline at end of file diff --git a/test.utils/src/main/java/org/apache/clerezza/test/utils/GraphTest.java b/test.utils/src/main/java/org/apache/clerezza/test/utils/GraphTest.java new file mode 100644 index 0000000..03e8043 --- /dev/null +++ b/test.utils/src/main/java/org/apache/clerezza/test/utils/GraphTest.java @@ -0,0 +1,561 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the License. + */ + +package org.apache.clerezza.test.utils; + +import org.apache.clerezza.api.*; +import org.apache.clerezza.api.impl.TripleImpl; +import org.apache.clerezza.api.impl.literal.PlainLiteralImpl; +import org.apache.clerezza.api.impl.literal.TypedLiteralImpl; +import org.junit.Assert; +import org.junit.Test; + +import java.util.*; + +/** + * A generic abstract test class, implementations overwrite this class, + * providing an implementation of the getEmptyGraph method. + * + * @author reto, szalay, mir, hhn + */ +public abstract class GraphTest { + + private final IRI uriRef1 = + new IRI("http://example.org/ontology#res1"); + private final IRI uriRef2 = + new IRI("http://example.org/ontology#res2"); + private final IRI uriRef3 = + new IRI("http://example.org/ontology#res3"); + private final IRI uriRef4 = + new IRI("http://example.org/ontology#res4"); + private final IRI xmlLiteralType = + new IRI("http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral"); + private Literal literal1 = new PlainLiteralImpl("literal1"); + private Literal literal2 = new PlainLiteralImpl("literal2"); + private BlankNode bnode1 = new BlankNode(); + private BlankNode bnode2 = new BlankNode(); + private Triple trpl1 = new TripleImpl(uriRef2, uriRef2, literal1); + private Triple trpl2 = new TripleImpl(uriRef1, uriRef2, uriRef1); + private Triple trpl3 = new TripleImpl(bnode2, uriRef3, literal2); + private Triple trpl4 = new TripleImpl(uriRef3, uriRef4, literal2); + + /** + * Subclasses implement this method to provide implementation instances of + * Graph. This method may be called an arbitrary amount of time, + * independently whether previously returned Graph are still in use or not. + * + * @return an empty Graph of the implementation to be tested + */ + protected abstract Graph getEmptyGraph(); + + @Test + public void testAddCountAndGetTriples() { + Graph graph = getEmptyGraph(); + Assert.assertEquals(0, graph.size()); + final TripleImpl triple1 = new TripleImpl(uriRef1, uriRef2, uriRef1); + graph.add(triple1); + Assert.assertEquals(1, graph.size()); + Iterator<Triple> tripleIter = graph.filter(uriRef1, uriRef2, uriRef1); + Assert.assertTrue(tripleIter.hasNext()); + Triple tripleGot = tripleIter.next(); + Assert.assertEquals(triple1, tripleGot); + Assert.assertFalse(tripleIter.hasNext()); + BlankNode bnode = new BlankNode() {}; + graph.add(new TripleImpl(bnode, uriRef1, uriRef3)); + graph.add(new TripleImpl(bnode, uriRef1, uriRef4)); + tripleIter = graph.filter(null, uriRef1, null); + Set<BlankNodeOrIRI> subjectInMatchingTriples = new HashSet<BlankNodeOrIRI>(); + Set<RDFTerm> objectsInMatchingTriples = new HashSet<RDFTerm>(); + while (tripleIter.hasNext()) { + Triple triple = tripleIter.next(); + subjectInMatchingTriples.add(triple.getSubject()); + objectsInMatchingTriples.add(triple.getObject()); + } + Assert.assertEquals(1, subjectInMatchingTriples.size()); + Assert.assertEquals(2, objectsInMatchingTriples.size()); + Set<RDFTerm> expectedObjects = new HashSet<RDFTerm>(); + expectedObjects.add(uriRef3); + expectedObjects.add(uriRef4); + Assert.assertEquals(expectedObjects, objectsInMatchingTriples); + graph.add(new TripleImpl(bnode, uriRef4, bnode)); + tripleIter = graph.filter(null, uriRef4, null); + Assert.assertTrue(tripleIter.hasNext()); + Triple retrievedTriple = tripleIter.next(); + Assert.assertFalse(tripleIter.hasNext()); + Assert.assertEquals(retrievedTriple.getSubject(), retrievedTriple.getObject()); + tripleIter = graph.filter(uriRef1, uriRef2, null); + Assert.assertTrue(tripleIter.hasNext()); + retrievedTriple = tripleIter.next(); + Assert.assertFalse(tripleIter.hasNext()); + Assert.assertEquals(retrievedTriple.getSubject(), retrievedTriple.getObject()); + } + + @Test + public void testRemoveAllTriples() { + Graph graph = getEmptyGraph(); + Assert.assertEquals(0, graph.size()); + graph.add(new TripleImpl(uriRef1, uriRef2, uriRef3)); + graph.add(new TripleImpl(uriRef2, uriRef3, uriRef4)); + Assert.assertEquals(2, graph.size()); + graph.clear(); + Assert.assertEquals(0, graph.size()); + } + + @Test + public void testUseTypedLiterals() { + Graph graph = getEmptyGraph(); + Assert.assertEquals(0, graph.size()); + Literal value = new TypedLiteralImpl("<elem>value</elem>",xmlLiteralType); + final TripleImpl triple1 = new TripleImpl(uriRef1, uriRef2, value); + graph.add(triple1); + Iterator<Triple> tripleIter = graph.filter(uriRef1, uriRef2, null); + Assert.assertTrue(tripleIter.hasNext()); + RDFTerm gotValue = tripleIter.next().getObject(); + Assert.assertEquals(value, gotValue); + } + + @Test + public void testUseLanguageLiterals() { + Graph graph = getEmptyGraph(); + Assert.assertEquals(0, graph.size()); + Language language = new Language("it"); + Literal value = new PlainLiteralImpl("<elem>value</elem>",language); + final TripleImpl triple1 = new TripleImpl(uriRef1, uriRef2, value); + graph.add(triple1); + Iterator<Triple> tripleIter = graph.filter(uriRef1, uriRef2, null); + Assert.assertTrue(tripleIter.hasNext()); + RDFTerm gotValue = tripleIter.next().getObject(); + Assert.assertEquals(value, gotValue); + Assert.assertEquals(language, ((Literal)gotValue).getLanguage()); + } + + @Test + public void testRemoveViaIterator() { + Graph graph = getEmptyGraph(); + Assert.assertEquals(0, graph.size()); + final TripleImpl triple1 = new TripleImpl(uriRef1, uriRef2, uriRef1); + graph.add(triple1); + final TripleImpl triple2 = new TripleImpl(uriRef1, uriRef2, uriRef4); + graph.add(triple2); + Assert.assertEquals(2, graph.size()); + Iterator<Triple> iterator = graph.iterator(); + while (iterator.hasNext()) { + iterator.next(); + iterator.remove(); + } + Assert.assertEquals(0, graph.size()); + } + + @Test + public void testGetSize() throws Exception { + Graph graph = getEmptyGraph(); + // The test graph must always be empty after test fixture setup + Assert.assertEquals(0, graph.size()); + } + + + @Test + public void testAddSingleTriple() throws Exception { + Graph graph = getEmptyGraph(); + final Triple triple= createTriple( + "http://example.org/ontology/Person", + "http://example.org/ontology/hasName", + "http://example.org/people/alice"); + Assert.assertEquals(0, graph.size()); + Assert.assertTrue(graph.add(triple)); + Assert.assertEquals(1, graph.size()); + } + + + @Test + public void testAddSameTripleTwice() throws Exception { + Graph graph = getEmptyGraph(); + final Triple triple= createTriple( + "http://example.org/ontology/Person", + "http://example.org/ontology/hasName", + "http://example.org/people/alice"); + Assert.assertEquals(0, graph.size()); + Assert.assertTrue(graph.add(triple)); + Assert.assertFalse(graph.add(triple)); // ImmutableGraph does not change + Assert.assertEquals(1, graph.size()); + } + + + @Test + public void testRemoveSingleTriple() throws Exception { + Graph graph = getEmptyGraph(); + final Triple triple= createTriple( + "http://example.org/ontology/Person", + "http://example.org/ontology/hasName", + "http://example.org/people/alice"); + Assert.assertTrue(graph.add(triple)); + Assert.assertTrue(graph.remove(triple)); + Assert.assertEquals(0, graph.size()); + } + + @Test + public void testRemoveSameTripleTwice() throws Exception { + Graph graph = getEmptyGraph(); + final Triple tripleAlice= createTriple( + "http://example.org/ontology/Person", + "http://example.org/ontology/hasName", + "http://example.org/people/alice"); + final Triple tripleBob= createTriple( + "http://example.org/ontology/Person", + "http://example.org/ontology/hasName", + "http://example.org/people/bob"); + Assert.assertTrue(graph.add(tripleAlice)); + Assert.assertTrue(graph.add(tripleBob)); + Assert.assertTrue(graph.remove(tripleAlice)); + Assert.assertFalse(graph.remove(tripleAlice)); + Assert.assertEquals(1, graph.size()); + } + + @Test + public void testGetSameBlankNode() throws Exception { + Graph graph = getEmptyGraph(); + BlankNode bNode = new BlankNode(); + final IRI HAS_NAME = new IRI("http://example.org/ontology/hasName"); + final PlainLiteralImpl name = new PlainLiteralImpl("http://example.org/people/alice"); + final PlainLiteralImpl name2 = new PlainLiteralImpl("http://example.org/people/bob"); + final Triple tripleAlice = new TripleImpl(bNode, HAS_NAME, name); + final Triple tripleBob = new TripleImpl(bNode, HAS_NAME, name2); + Assert.assertTrue(graph.add(tripleAlice)); + Assert.assertTrue(graph.add(tripleBob)); + Iterator<Triple> result = graph.filter(null, HAS_NAME, name); + Assert.assertEquals(bNode, result.next().getSubject()); + } + + @Test + public void testContainsIfContained() throws Exception { + Graph graph = getEmptyGraph(); + final Triple triple= createTriple( + "http://example.org/ontology/Person", + "http://example.org/ontology/hasName", + "http://example.org/people/alice"); + Assert.assertTrue(graph.add(triple)); + Assert.assertTrue(graph.contains(triple)); + } + + + @Test + public void testContainsIfEmpty() throws Exception { + Graph graph = getEmptyGraph(); + final Triple triple= createTriple( + "http://example.org/ontology/Person", + "http://example.org/ontology/hasName", + "http://example.org/people/alice"); + Assert.assertFalse(graph.contains(triple)); + } + + + @Test + public void testContainsIfNotContained() throws Exception { + Graph graph = getEmptyGraph(); + final Triple tripleAdd= createTriple( + "http://example.org/ontology/Person", + "http://example.org/ontology/hasName", + "http://example.org/people/alice"); + final Triple tripleTest= createTriple( + "http://example.org/ontology/Person", + "http://example.org/ontology/hasName", + "http://example.org/people/bob"); + Assert.assertTrue(graph.add(tripleAdd)); + Assert.assertFalse(graph.contains(tripleTest)); + } + + + @Test + public void testFilterEmptyGraph() throws Exception { + Graph graph = getEmptyGraph(); + Iterator<Triple> i = graph.filter(null, null, null); + Assert.assertFalse(i.hasNext()); + } + + + @Test + public void testFilterSingleEntry() throws Exception { + Graph graph = getEmptyGraph(); + final Triple triple= createTriple( + "http://example.org/ontology/Person", + "http://example.org/ontology/hasName", + "http://example.org/people/alice"); + Assert.assertTrue(graph.add(triple)); + + Iterator<Triple> i = graph.filter(null, null, null); + Collection<Triple> resultSet= toCollection(i); + Assert.assertEquals(1, resultSet.size()); + Assert.assertTrue(resultSet.contains(triple)); + } + + + @Test + public void testFilterByObject() throws Exception { + Graph graph = getEmptyGraph(); + final Triple tripleAlice= createTriple( + "http://example.org/ontology/Person", + "http://example.org/ontology/hasName", + "http://example.org/people/alice"); + final Triple tripleBob= createTriple( + "http://example.org/ontology/Person", + "http://example.org/ontology/hasName", + "http://example.org/people/bob"); + Assert.assertTrue(graph.add(tripleAlice)); + Assert.assertTrue(graph.add(tripleBob)); + + Iterator<Triple> iterator; + Collection<Triple> resultSet; + + // Find bob + iterator = graph.filter(null, null, + new IRI("http://example.org/people/bob")); + resultSet= toCollection(iterator); + Assert.assertEquals(1, resultSet.size()); + Assert.assertTrue(resultSet.contains(tripleBob)); + + // Find alice + iterator = graph.filter(null, null, + new IRI("http://example.org/people/alice")); + resultSet= toCollection(iterator); + Assert.assertEquals(1, resultSet.size()); + Assert.assertTrue(resultSet.contains(tripleAlice)); + + // Find both + iterator = graph.filter(null, null, null); + resultSet= toCollection(iterator); + Assert.assertEquals(2, resultSet.size()); + Assert.assertTrue(resultSet.contains(tripleAlice)); + Assert.assertTrue(resultSet.contains(tripleBob)); + } +/* + @Test + public void graphEventTestAddRemove() { + Graph mGraph = getEmptyGraph(); + TestGraphListener listener = new TestGraphListener(); + mGraph.addGraphListener(listener, new FilterTriple(uriRef1, uriRef2, null)); + mGraph.addGraphListener(listener, new FilterTriple(bnode2, null, literal2)); + mGraph.addGraphListener(listener, new FilterTriple(null, uriRef4, literal2)); + mGraph.add(trpl1); + Assert.assertNull(listener.getEvents()); + mGraph.add(trpl2); + Assert.assertEquals(1, listener.getEvents().size()); + Assert.assertEquals(trpl2, listener.getEvents().get(0).getTriple()); + Assert.assertTrue(listener.getEvents().get(0) instanceof AddEvent); + listener.resetEvents(); + mGraph.remove(trpl2); + Assert.assertEquals(1, listener.getEvents().size()); + Assert.assertEquals(trpl2, listener.getEvents().get(0).getTriple()); + Assert.assertTrue(listener.getEvents().get(0) instanceof RemoveEvent); + listener.resetEvents(); + mGraph.add(trpl3); + Assert.assertEquals(1, listener.getEvents().size()); + Assert.assertEquals(trpl3, listener.getEvents().get(0).getTriple()); + Assert.assertTrue(listener.getEvents().get(0) instanceof AddEvent); + listener.resetEvents(); + mGraph.remove(trpl4); + Assert.assertNull(listener.getEvents()); + } + + @Test + public void graphEventTestAddAllRemoveAll() { + Graph mGraph = getEmptyGraph(); + TestGraphListener listener = new TestGraphListener(); + mGraph.addGraphListener(listener, new FilterTriple(uriRef1, uriRef2, null)); + mGraph.addGraphListener(listener, new FilterTriple(bnode2, null, literal2)); + mGraph.addGraphListener(listener, new FilterTriple(null, uriRef4, literal2)); + Graph triples = new SimpleGraph(); + triples.add(trpl1); + triples.add(trpl2); + triples.add(trpl3); + triples.add(trpl4); + mGraph.addAll(triples); + List<GraphEvent> cumulatedEvents = listener.getCumulatedEvents(); + Set<Triple> cumulatedTriples = getCumulatedTriples(cumulatedEvents); + Assert.assertEquals(3, cumulatedEvents.size()); + Assert.assertTrue(cumulatedEvents.get(0) instanceof AddEvent); + Assert.assertTrue(cumulatedTriples.contains(trpl2)); + Assert.assertTrue(cumulatedTriples.contains(trpl3)); + Assert.assertTrue(cumulatedTriples.contains(trpl4)); + listener.resetCumulatedEvents(); + mGraph.removeAll(triples); + cumulatedEvents = listener.getCumulatedEvents(); + cumulatedTriples = getCumulatedTriples(cumulatedEvents); + Assert.assertEquals(3, cumulatedEvents.size()); + Assert.assertTrue(cumulatedEvents.get(0) instanceof RemoveEvent); + Assert.assertTrue(cumulatedTriples.contains(trpl2)); + Assert.assertTrue(cumulatedTriples.contains(trpl3)); + Assert.assertTrue(cumulatedTriples.contains(trpl4)); + } + + @Test + public void graphEventTestFilterRemove() { + Graph mGraph = getEmptyGraph(); + TestGraphListener listener = new TestGraphListener(); + mGraph.addGraphListener(listener, new FilterTriple(uriRef1, uriRef2, null)); + mGraph.addGraphListener(listener, new FilterTriple(bnode2, null, literal2)); + mGraph.addGraphListener(listener, new FilterTriple(null, uriRef4, literal2)); + mGraph.add(trpl1); + mGraph.add(trpl2); + mGraph.add(trpl3); + mGraph.add(trpl4); + listener.resetCumulatedEvents(); + Iterator<Triple> result = mGraph.filter(null, uriRef2, null); + while (result.hasNext()) { + result.next(); + result.remove(); + } + List<GraphEvent> cumulatedEvents = listener.getCumulatedEvents(); + Assert.assertEquals(1, cumulatedEvents.size()); + Assert.assertTrue(cumulatedEvents.get(0) instanceof RemoveEvent); + Assert.assertEquals(trpl2, listener.getEvents().get(0).getTriple()); + } + + @Test + public void graphEventTestIteratorRemove() { + Graph mGraph = getEmptyGraph(); + TestGraphListener listener = new TestGraphListener(); + mGraph.addGraphListener(listener, new FilterTriple(uriRef1, uriRef2, null)); + mGraph.addGraphListener(listener, new FilterTriple(bnode2, null, literal2)); + mGraph.addGraphListener(listener, new FilterTriple(null, uriRef4, literal2)); + mGraph.add(trpl1); + mGraph.add(trpl2); + mGraph.add(trpl3); + mGraph.add(trpl4); + listener.resetCumulatedEvents(); + Iterator<Triple> result = mGraph.iterator(); + while (result.hasNext()) { + result.next(); + result.remove(); + } + List<GraphEvent> cumulatedEvents = listener.getCumulatedEvents(); + Set<Triple> cumulatedTriples = getCumulatedTriples(cumulatedEvents); + Assert.assertEquals(3, cumulatedEvents.size()); + Assert.assertTrue(cumulatedEvents.get(0) instanceof RemoveEvent); + Assert.assertTrue(cumulatedTriples.contains(trpl2)); + Assert.assertTrue(cumulatedTriples.contains(trpl3)); + Assert.assertTrue(cumulatedTriples.contains(trpl4)); + } + + @Test + public void graphEventTestClear() { + Graph mGraph = getEmptyGraph(); + TestGraphListener listener = new TestGraphListener(); + mGraph.addGraphListener(listener, new FilterTriple(uriRef1, uriRef2, null)); + mGraph.addGraphListener(listener, new FilterTriple(bnode2, null, literal2)); + mGraph.addGraphListener(listener, new FilterTriple(null, uriRef4, literal2)); + mGraph.add(trpl1); + mGraph.add(trpl2); + mGraph.add(trpl3); + mGraph.add(trpl4); + listener.resetCumulatedEvents(); + mGraph.clear(); + List<GraphEvent> cumulatedEvents = listener.getCumulatedEvents(); + Set<Triple> cumulatedTriples = getCumulatedTriples(cumulatedEvents); + Assert.assertEquals(3, cumulatedEvents.size()); + Assert.assertTrue(cumulatedEvents.get(0) instanceof RemoveEvent); + Assert.assertTrue(cumulatedTriples.contains(trpl2)); + Assert.assertTrue(cumulatedTriples.contains(trpl3)); + Assert.assertTrue(cumulatedTriples.contains(trpl4)); + } + + private Set<Triple> getCumulatedTriples(List<GraphEvent> cumulatedEvents) { + Set<Triple> triples = new HashSet<Triple>(); + for(GraphEvent event: cumulatedEvents) { + triples.add(event.getTriple()); + } + return triples; + } + + @Test + public void graphEventTestWithDelay() throws Exception{ + Graph mGraph = getEmptyGraph(); + TestGraphListener listener = new TestGraphListener(); + mGraph.addGraphListener(listener, new FilterTriple(uriRef1, uriRef2, null), + 1000); + + Triple triple0 = new TripleImpl(uriRef2, uriRef2, literal1); + Triple triple1 = new TripleImpl(uriRef1, uriRef2, uriRef1); + Triple triple2 = new TripleImpl(uriRef1, uriRef2, literal1); + Triple triple3 = new TripleImpl(uriRef1, uriRef2, bnode1); + mGraph.add(triple0); + mGraph.add(triple1); + mGraph.add(triple2); + mGraph.add(triple3); + Thread.sleep(1500); + Assert.assertEquals(3, listener.getEvents().size()); + Assert.assertEquals(triple1, listener.getEvents().get(0).getTriple()); + Assert.assertTrue(listener.getEvents().get(0) instanceof AddEvent); + Assert.assertEquals(triple2, listener.getEvents().get(1).getTriple()); + Assert.assertTrue(listener.getEvents().get(0) instanceof AddEvent); + Assert.assertEquals(triple3, listener.getEvents().get(2).getTriple()); + Assert.assertTrue(listener.getEvents().get(0) instanceof AddEvent); + } + + private static class TestGraphListener implements GraphListener { + private List<GraphEvent> events = null; + private List<GraphEvent> cumulatedEvents = new ArrayList<GraphEvent>(); + + @Override + public void graphChanged(List<GraphEvent> events) { + this.events = events; + Iterator<GraphEvent> eventIter = events.iterator(); + while (eventIter.hasNext()) { + GraphEvent graphEvent = eventIter.next(); + this.cumulatedEvents.add(graphEvent); + } + } + + public List<GraphEvent> getEvents() { + return events; + } + + public List<GraphEvent> getCumulatedEvents() { + return cumulatedEvents; + } + + public void resetEvents() { + events = null; + } + + public void resetCumulatedEvents() { + cumulatedEvents = new ArrayList<GraphEvent>(); + } + } +*/ + private Collection<Triple> toCollection(Iterator<Triple> iterator) { + Collection<Triple> result = new ArrayList<Triple>(); + while (iterator.hasNext()) { + result.add(iterator.next()); + } + return result; + } + + /** + * Creates a new <code>Triple</code>. + * @param subject the subject. + * @param predicate the predicate. + * @param object the object. + * @throws IllegalArgumentException If an attribute is <code>null</code>. + */ + private Triple createTriple(String subject, String predicate, + String object) { + return new TripleImpl(new IRI(subject), new IRI(predicate), + new IRI(object)); + } + +} diff --git a/test.utils/src/main/java/org/apache/clerezza/test/utils/GraphWrapper.java b/test.utils/src/main/java/org/apache/clerezza/test/utils/GraphWrapper.java new file mode 100644 index 0000000..e4d52e5 --- /dev/null +++ b/test.utils/src/main/java/org/apache/clerezza/test/utils/GraphWrapper.java @@ -0,0 +1,120 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the License. + */ + +package org.apache.clerezza.test.utils; + +import org.apache.clerezza.api.*; + +import java.util.Collection; +import java.util.Iterator; +import java.util.concurrent.locks.ReadWriteLock; + +/** + * + * @author mir + */ +class GraphWrapper implements Graph { + + protected Graph wrapped; + + public GraphWrapper(Graph tc) { + this.wrapped = tc; + } + + @Override + public Iterator<Triple> filter(BlankNodeOrIRI subject, IRI predicate, RDFTerm object) { + return wrapped.filter(subject, predicate, object); + } + + + @Override + public int size() { + return wrapped.size(); + } + + @Override + public boolean isEmpty() { + return wrapped.isEmpty(); + } + + @Override + public boolean contains(Object o) { + return wrapped.contains(o); + } + + @Override + public Iterator<Triple> iterator() { + return wrapped.iterator(); + } + + @Override + public Object[] toArray() { + return wrapped.toArray(); + } + + @Override + public <T> T[] toArray(T[] a) { + return wrapped.toArray(a); + } + + @Override + public boolean add(Triple e) { + return wrapped.add(e); + } + + @Override + public boolean remove(Object o) { + return wrapped.remove(o); + } + + @Override + public boolean containsAll(Collection<?> c) { + return wrapped.containsAll(c); + } + + @Override + public boolean addAll(Collection<? extends Triple> c) { + return wrapped.addAll(c); + } + + @Override + public boolean removeAll(Collection<?> c) { + return wrapped.removeAll(c); + } + + @Override + public boolean retainAll(Collection<?> c) { + return wrapped.retainAll(c); + } + + @Override + public void clear() { + wrapped.clear(); + } + + @Override + public ImmutableGraph getImmutableGraph() { + return wrapped.getImmutableGraph(); + } + + @Override + public ReadWriteLock getLock() { + return wrapped.getLock(); + } + +} diff --git a/test.utils/src/main/java/org/apache/clerezza/test/utils/LockChecker.java b/test.utils/src/main/java/org/apache/clerezza/test/utils/LockChecker.java new file mode 100644 index 0000000..5fcf8d4 --- /dev/null +++ b/test.utils/src/main/java/org/apache/clerezza/test/utils/LockChecker.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the License. + */ + +package org.apache.clerezza.test.utils; + +import java.util.concurrent.locks.ReentrantReadWriteLock; + +/** + * + * @author mir + */ +class LockChecker { + + public static void checkIfReadLocked(ReentrantReadWriteLock lock) { + if (lock.getReadLockCount() == 0 && !lock.isWriteLockedByCurrentThread()) { + throw new RuntimeException("Neither read- nor write-locked"); + } + } + + public static void checkIfWriteLocked(ReentrantReadWriteLock lock) { + if (!lock.isWriteLockedByCurrentThread()) { + throw new RuntimeException("Not write-locked"); + } + } +} diff --git a/test.utils/src/main/java/org/apache/clerezza/test/utils/LockableMGraphWrapperForTesting.java b/test.utils/src/main/java/org/apache/clerezza/test/utils/LockableMGraphWrapperForTesting.java new file mode 100644 index 0000000..55bdb58 --- /dev/null +++ b/test.utils/src/main/java/org/apache/clerezza/test/utils/LockableMGraphWrapperForTesting.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the License. + */ + +package org.apache.clerezza.test.utils; + +import org.apache.clerezza.api.*; + +import java.util.Iterator; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +/** + * Wrappes an Graph as a LockableGraph. If a method is called that reads + * or modifies the wrapped graph and the appropriate lock is not set, then a + * RuntimeException is thrown. + * + * @author rbn, mir + */ +public class LockableMGraphWrapperForTesting extends GraphWrapper { + + private final ReentrantReadWriteLock lock = (ReentrantReadWriteLock) getLock(); + private final Lock readLock = lock.readLock(); + private final Graph wrapped; + + /** + * Constructs a LocalbleGraph for an Graph. + * + * @param providedGraph a non-lockable mgraph + */ + public LockableMGraphWrapperForTesting(final Graph providedGraph) { + super(providedGraph); + this.wrapped = providedGraph; + } + + @Override + public Iterator<Triple> filter(BlankNodeOrIRI subject, IRI predicate, RDFTerm object) { + LockChecker.checkIfReadLocked(lock); + readLock.lock(); + try { + return new LockingIteratorForTesting(wrapped.filter(subject, predicate, object), lock); + } finally { + readLock.unlock(); + } + } + + @Override + public Iterator<Triple> iterator() { + LockChecker.checkIfReadLocked(lock); + readLock.lock(); + try { + return new LockingIteratorForTesting(wrapped.iterator(), lock); + } finally { + readLock.unlock(); + } + } + +} diff --git a/test.utils/src/main/java/org/apache/clerezza/test/utils/LockingIteratorForTesting.java b/test.utils/src/main/java/org/apache/clerezza/test/utils/LockingIteratorForTesting.java new file mode 100644 index 0000000..3e7b225 --- /dev/null +++ b/test.utils/src/main/java/org/apache/clerezza/test/utils/LockingIteratorForTesting.java @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the License. + */ + +package org.apache.clerezza.test.utils; + +import org.apache.clerezza.api.Triple; + +import java.util.Iterator; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +/** + * Wrapps an iterator<Triple> reading all elements to a cache on construction + * and returning them from that cache. + * @author reto + */ +class LockingIteratorForTesting implements Iterator<Triple> { + + private Iterator<Triple> base; + private Lock readLock; + private Lock writeLock; + private ReentrantReadWriteLock lock; + + public LockingIteratorForTesting(Iterator<Triple> iterator, ReentrantReadWriteLock lock) { + base = iterator; + readLock = lock.readLock(); + writeLock = lock.writeLock(); + this.lock = lock; + } + + @Override + public boolean hasNext() { + LockChecker.checkIfReadLocked(lock); + readLock.lock(); + try { + return base.hasNext(); + } finally { + readLock.unlock(); + } + } + + @Override + public Triple next() { + LockChecker.checkIfReadLocked(lock); + readLock.lock(); + try { + return base.next(); + } finally { + readLock.unlock(); + } + } + + @Override + public void remove() { + LockChecker.checkIfWriteLocked(lock); + writeLock.lock(); + try { + base.remove(); + } finally { + writeLock.unlock(); + } + } + + +} diff --git a/test.utils/src/main/java/org/apache/clerezza/test/utils/RandomGraph.java b/test.utils/src/main/java/org/apache/clerezza/test/utils/RandomGraph.java new file mode 100644 index 0000000..d028594 --- /dev/null +++ b/test.utils/src/main/java/org/apache/clerezza/test/utils/RandomGraph.java @@ -0,0 +1,233 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the License. + */ + +package org.apache.clerezza.test.utils; + +import org.apache.clerezza.api.*; +import org.apache.clerezza.api.impl.TripleImpl; +import org.apache.clerezza.api.impl.literal.PlainLiteralImpl; +import org.apache.commons.lang.RandomStringUtils; + +import java.util.Iterator; +import java.util.UUID; + +/** + * A <code>Graph</code> wrapper that allows growing and shrinking of + * the wrapped mgraph. + * + * @author mir + */ +public class RandomGraph extends GraphWrapper { + + private int interconnectivity = 2; + + public RandomGraph(Graph mGraph, int interconnectivity) { + super(mGraph); + this.interconnectivity = interconnectivity; + } + + /** + * Creates a new random mutual graph. + * + * @param initialSize Determines the initial size of the content graph + * @param interconnectivity Determines the probability of using already existing + * resource when creating a new triple. The probability of using an existing + * resource over creating a new resouce is 1-(1/interconnectivity). + * @param mGraph + */ + public RandomGraph(int initialSize, int interconnectivity, Graph mGraph) { + super(mGraph); + if (interconnectivity <= 0) { + throw new IllegalArgumentException("growth speed and the interconnectivity " + + "value have to be equals or highter one"); + } + this.interconnectivity = interconnectivity; + + setupInitialSize(initialSize); + } + + /** + * Add or removes randomly a triple. + * + * @return the triple that was added or removed. + */ + public Triple evolve() { + Triple triple; + int random = rollDice(2); + if (random == 0 && size() != 0) { + triple = getRandomTriple(); + remove(triple); + } else { + triple = createRandomTriple(); + add(triple); + } + return triple; + } + + /** + * Removes a random triple. + * + * @return the triple that was removed. + */ + public Triple removeRandomTriple() { + Triple randomTriple = getRandomTriple(); + remove(randomTriple); + return randomTriple; + } + + /** + * Adds a random triple. + * + * @return the triple that was added. + */ + public Triple addRandomTriple() { + Triple randomTriple; + do { + randomTriple = createRandomTriple(); + } while(contains(randomTriple)); + + add(randomTriple); + return randomTriple; + } + + private Triple createRandomTriple() { + return new TripleImpl(getSubject(), getPredicate(), getObject()); + } + + private BlankNodeOrIRI getSubject() { + int random = rollDice(interconnectivity); + if (size() == 0) { + random = 0; + } + switch (random) { + case 0: // create new BlankNodeOrIRI + RDFTerm newRDFTerm; + do { + newRDFTerm = createRandomRDFTerm(); + } while (!(newRDFTerm instanceof BlankNodeOrIRI)); + return (BlankNodeOrIRI) newRDFTerm; + default: // get existing BlankNodeOrIRI + RDFTerm existingRDFTerm; + do { + existingRDFTerm = getExistingRDFTerm(); + if (existingRDFTerm == null) { + random = 0; + } + } while (!(existingRDFTerm instanceof BlankNodeOrIRI)); + + return (BlankNodeOrIRI) existingRDFTerm; + } + } + + private IRI getPredicate() { + int random = rollDice(interconnectivity); + if (size() == 0) { + random = 0; + } + switch (random) { + case 0: // create new IRI + return createRandomIRI(); + default: // get existing IRI + RDFTerm existingRDFTerm; + do { + existingRDFTerm = getExistingRDFTerm(); + if (existingRDFTerm == null) { + random = 0; + } + } while (!(existingRDFTerm instanceof IRI)); + return (IRI) existingRDFTerm; + } + } + + private RDFTerm getObject() { + int random = rollDice(interconnectivity); + if (size() == 0) { + random = 0; + } + switch (random) { + case 0: // create new resource + return createRandomRDFTerm(); + default: // get existing resource + RDFTerm existingRDFTerm = getExistingRDFTerm(); + if (existingRDFTerm == null) { + random = 0; + } + return existingRDFTerm; + } + } + + private static int rollDice(int faces) { + return Double.valueOf(Math.random() * faces).intValue(); + } + + private RDFTerm createRandomRDFTerm() { + switch (rollDice(3)) { + case 0: + return new BlankNode(); + case 1: + return createRandomIRI(); + case 2: + return new PlainLiteralImpl(RandomStringUtils.random(rollDice(100) + 1)); + } + throw new RuntimeException("in createRandomRDFTerm()"); + } + + private RDFTerm getExistingRDFTerm() { + Triple triple = getRandomTriple(); + if (triple == null) { + return null; + } + switch (rollDice(3)) { + case 0: + return triple.getSubject(); + case 1: + return triple.getPredicate(); + case 2: + return triple.getObject(); + } + return null; + } + + private IRI createRandomIRI() { + return new IRI("http://" + UUID.randomUUID().toString()); + } + + /** + * Returns a random triple contained in the Graph. + */ + public Triple getRandomTriple() { + int size = this.size(); + if (size == 0) { + return null; + } + Iterator<Triple> triples = iterator(); + while (triples.hasNext()) { + Triple triple = triples.next(); + if (rollDice(this.size()) == 0) { + return triple; + } + } + return getRandomTriple(); + } + + private void setupInitialSize(int initialSize) { + for (int i = 0; i < initialSize; i++) { + addRandomTriple(); + } + } +} diff --git a/test.utils/src/main/java/org/apache/clerezza/test/utils/TcProviderTest.java b/test.utils/src/main/java/org/apache/clerezza/test/utils/TcProviderTest.java new file mode 100644 index 0000000..48ae397 --- /dev/null +++ b/test.utils/src/main/java/org/apache/clerezza/test/utils/TcProviderTest.java @@ -0,0 +1,479 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. See the License for the specific + * language governing permissions and limitations under the License. + */ + +package org.apache.clerezza.test.utils; + +import org.apache.clerezza.api.*; +import org.apache.clerezza.api.impl.TripleImpl; +import org.apache.clerezza.api.impl.graph.SimpleGraph; +import org.apache.clerezza.dataset.EntityAlreadyExistsException; +import org.apache.clerezza.dataset.NoSuchEntityException; +import org.apache.clerezza.dataset.TcProvider; +import org.junit.Test; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import static org.junit.Assert.*; + +/** + * + * @author mir,rbn + */ +public abstract class TcProviderTest { + + protected final IRI uriRefA = generateUri("a"); + protected final IRI uriRefA1 = generateUri("a1"); + protected final IRI uriRefB = generateUri("b"); + protected final IRI uriRefB1 = generateUri("b1"); + protected final IRI uriRefC = generateUri("c"); + + protected final IRI graphIRI = generateUri("myGraph"); + protected final IRI otherGraphIRI = new IRI(graphIRI.getUnicodeString()); + + @Test + public void testCreateImmutableGraph() { + TcProvider simpleTcmProvider = getInstance(); + Graph mGraph = new SimpleGraph(); + mGraph.add(new TripleImpl(uriRefA, uriRefA, uriRefA)); + + ImmutableGraph createdGraph = simpleTcmProvider.createImmutableGraph(uriRefA, mGraph); + + Iterator<Triple> iteratorInput = mGraph.iterator(); + Iterator<Triple> iteratorCreated = createdGraph.iterator(); + assertEquals(iteratorInput.next(), iteratorCreated.next()); + assertFalse(iteratorCreated.hasNext()); + + try { + simpleTcmProvider.createImmutableGraph(uriRefA, mGraph); + assertTrue(false); + } catch (EntityAlreadyExistsException e) { + assertTrue(true); + } + simpleTcmProvider.deleteGraph(uriRefA); + } + + @Test + public void testCreateGraph() { + TcProvider simpleTcmProvider = getInstance(); + Graph mGraph = simpleTcmProvider.createGraph(uriRefA); + assertTrue(mGraph.isEmpty()); + + try { + simpleTcmProvider.createGraph(uriRefA); + assertTrue(false); + } catch (EntityAlreadyExistsException e) { + assertTrue(true); + } + simpleTcmProvider.deleteGraph(uriRefA); + } + + @Test + public void testGetImmutableGraph() { + TcProvider simpleTcmProvider = getInstance(); + // add Graphs + Graph mGraph = new SimpleGraph(); + mGraph.add(new TripleImpl(uriRefA, uriRefA, uriRefA)); + simpleTcmProvider.createImmutableGraph(uriRefA, mGraph); + mGraph = new SimpleGraph(); + mGraph.add(new TripleImpl(uriRefA1, uriRefA1, uriRefA1)); + simpleTcmProvider.createImmutableGraph(uriRefA1, mGraph); + mGraph = new SimpleGraph(); + mGraph.add(new TripleImpl(uriRefB, uriRefB, uriRefB)); + simpleTcmProvider.createImmutableGraph(uriRefB, mGraph); + mGraph = new SimpleGraph(); + mGraph.add(new TripleImpl(uriRefB1, uriRefB1, uriRefB1)); + simpleTcmProvider.createImmutableGraph(uriRefB1, mGraph); + + ImmutableGraph bGraph = simpleTcmProvider.getImmutableGraph(uriRefB); + Iterator<Triple> iterator = bGraph.iterator(); + assertEquals(new TripleImpl(uriRefB, uriRefB, uriRefB), iterator.next()); + assertFalse(iterator.hasNext()); + simpleTcmProvider.deleteGraph(uriRefA); + simpleTcmProvider.deleteGraph(uriRefA1); + simpleTcmProvider.deleteGraph(uriRefB); + simpleTcmProvider.deleteGraph(uriRefB1); + } + + @Test + public void testGetGraph() { + TcProvider simpleTcmProvider = getInstance(); + // add Graphs + Graph mGraph = simpleTcmProvider.createGraph(uriRefA); + mGraph.add(new TripleImpl(uriRefA, uriRefA, uriRefA)); + mGraph = simpleTcmProvider.createGraph(uriRefA1); + mGraph.add(new TripleImpl(uriRefA1, uriRefA1, uriRefA1)); + mGraph = simpleTcmProvider.createGraph(uriRefB); + mGraph.add(new TripleImpl(uriRefB, uriRefB, uriRefA)); + mGraph.add(new TripleImpl(uriRefB, uriRefB, uriRefB)); + mGraph.remove(new TripleImpl(uriRefB, uriRefB, uriRefA)); + assertEquals(1, mGraph.size()); + mGraph = simpleTcmProvider.createGraph(uriRefB1); + mGraph.add(new TripleImpl(uriRefB1, uriRefB1, uriRefB1)); + + Graph bGraph = simpleTcmProvider.getGraph(uriRefB); + Iterator<Triple> iterator = bGraph.iterator(); + assertEquals(new TripleImpl(uriRefB, uriRefB, uriRefB), iterator.next()); + assertFalse(iterator.hasNext()); + simpleTcmProvider.deleteGraph(uriRefA); + simpleTcmProvider.deleteGraph(uriRefA1); + simpleTcmProvider.deleteGraph(uriRefB); + simpleTcmProvider.deleteGraph(uriRefB1); + + } + + @Test + public void testGetTriples() { + TcProvider simpleTcmProvider = getInstance(); + // add Graphs + Graph mGraph = new SimpleGraph(); + mGraph.add(new TripleImpl(uriRefA, uriRefA, uriRefA)); + simpleTcmProvider.createImmutableGraph(uriRefA, mGraph); + mGraph = new SimpleGraph(); + mGraph.add(new TripleImpl(uriRefB, uriRefB, uriRefB)); + simpleTcmProvider.createImmutableGraph(uriRefB, mGraph); + // add Graphs + mGraph = simpleTcmProvider.createGraph(uriRefA1); + mGraph.add(new TripleImpl(uriRefA1, uriRefA1, uriRefA1)); + mGraph = simpleTcmProvider.createGraph(uriRefB1); + mGraph.add(new TripleImpl(uriRefB1, uriRefB1, uriRefB1)); + + // get a ImmutableGraph + Graph tripleCollection = simpleTcmProvider.getGraph(uriRefA); + // get a Graph + Graph tripleCollection2 = simpleTcmProvider.getGraph(uriRefB1); + + Iterator<Triple> iterator = tripleCollection.iterator(); + assertEquals(new TripleImpl(uriRefA, uriRefA, uriRefA), iterator.next()); + assertFalse(iterator.hasNext()); + + iterator = tripleCollection2.iterator(); + assertEquals(new TripleImpl(uriRefB1, uriRefB1, uriRefB1), iterator.next()); + assertFalse(iterator.hasNext()); + simpleTcmProvider.deleteGraph(uriRefA); + simpleTcmProvider.deleteGraph(uriRefA1); + simpleTcmProvider.deleteGraph(uriRefB); + simpleTcmProvider.deleteGraph(uriRefB1); + } + + @Test + public void testDeleteEntity() { + TcProvider simpleTcmProvider = getInstance(); + Graph mGraph = new SimpleGraph(); + mGraph.add(new TripleImpl(uriRefA, uriRefA, uriRefA)); + ImmutableGraph graph = mGraph.getImmutableGraph(); + simpleTcmProvider.createImmutableGraph(uriRefA, graph); + simpleTcmProvider.createImmutableGraph(uriRefC, graph); + + simpleTcmProvider.deleteGraph(uriRefA); + try { + simpleTcmProvider.getGraph(uriRefA); + assertTrue(false); + } catch (NoSuchEntityException e) { + assertTrue(true); + } + + // Check that graph is still available under uriRefC + ImmutableGraph cGraph = simpleTcmProvider.getImmutableGraph(uriRefC); + assertNotNull(cGraph); + simpleTcmProvider.deleteGraph(uriRefC); + } + + /** + * Subclasses implement this method to provide implementation instances of + * <code>TcProvider</code>. The first call within a test method has to + * return a empty TcProvider. Subsequent calls within the test method + * should instantiate a new provider, but load the previously added data from + * its "persistent" store. + * + * @return a TcProvider of the implementation to be tested. + */ + protected abstract TcProvider getInstance(); + +// @Test +// public void testGetNames() { +// Graph mGraph = new SimpleGraph(); +// mGraph.add(new TripleImpl(uriRefB, uriRefB, uriRefB)); +// simpleTcmProvider.createGraph(uriRefB, mGraph.getGraph()); +// +// mGraph = new SimpleGraph(); +// mGraph.add(new TripleImpl(uriRefA, uriRefA, uriRefA)); +// ImmutableGraph graph = mGraph.getGraph(); +// simpleTcmProvider.createGraph(uriRefA, graph); +// simpleTcmProvider.createGraph(uriRefC, graph); +// +// Set<IRI> names = simpleTcmProvider.getNames(graph); +// +// assertTrue(names.contains(uriRefA)); +// assertTrue(names.contains(uriRefC)); +// assertEquals(2, names.size()); +// +// assertFalse(names.contains(uriRefB)); +// } + + @Test + public void testCreateGraphExtended() throws Exception { + + TcProvider provider = getInstance(); + Graph graph = provider.createGraph(graphIRI); + assertNotNull(graph); + //get a new provider and check that graph is there + provider = getInstance(); + graph = provider.getGraph(graphIRI); + assertNotNull(graph); + //check that there is no such graph, but only the mgraph + boolean expThrown = false; + try { + ImmutableGraph g = provider.getImmutableGraph(graphIRI); + } catch(NoSuchEntityException e) { + expThrown = true; + } + + assertTrue(expThrown); + provider.deleteGraph(graphIRI); + } + + @Test + public void testCreateImmutableGraphExtended() throws Exception { + + TcProvider provider = getInstance(); + ImmutableGraph graph = provider.createImmutableGraph(graphIRI, null); + + assertNotNull(graph); + + //get a new provider and check that graph is there + provider = getInstance(); + graph = provider.getImmutableGraph(graphIRI); + assertNotNull(graph); + + //check that there is no such mgraph, but only the graph + boolean expThrown = false; + + try { + Graph g = provider.getMGraph(graphIRI); + } catch(NoSuchEntityException e) { + expThrown = true; + } + + assertTrue(expThrown); + provider.deleteGraph(graphIRI); + } + + @Test + public void testCreateGraphNoDuplicateNames() throws Exception { + + TcProvider provider = getInstance(); + ImmutableGraph graph = provider.createImmutableGraph(graphIRI, null); + assertNotNull(graph); + boolean expThrown = false; + try { + ImmutableGraph other = provider.createImmutableGraph(otherGraphIRI, null); + } catch(EntityAlreadyExistsException eaee) { + expThrown = true; + } + assertTrue(expThrown); + provider.deleteGraph(graphIRI); + } + + @Test + public void testCreateGraphNoDuplicateNames2() throws Exception { + + TcProvider provider = getInstance(); + Graph graph = provider.createGraph(graphIRI); + assertNotNull(graph); + boolean expThrown = false; + try { + Graph other = provider.createGraph(otherGraphIRI); + } catch(EntityAlreadyExistsException eaee) { + expThrown = true; + } + assertTrue(expThrown); + provider.deleteGraph(graphIRI); + } + + @Test + public void testCreateGraphWithInitialCollection() throws Exception { + + Triple t1 = createTestTriple(); + + TcProvider provider = getInstance(); + + ImmutableGraph graph = provider.createImmutableGraph(graphIRI, createTestTripleCollection(t1)); + + assertEquals(1, graph.size()); + assertTrue(graph.contains(t1)); + provider.deleteGraph(graphIRI); + } + + @Test + public void testGraphIsNotMutable() throws Exception { + + Triple t1 = createTestTriple(); + Set<Triple> t = new HashSet<Triple>(); + t.add(t1); + + TcProvider provider = getInstance(); + + ImmutableGraph graph = provider.createImmutableGraph(graphIRI, createTestTripleCollection(t1)); + + boolean expThrown = false; + + try { + graph.add(t1); + } catch(UnsupportedOperationException uoe) { + expThrown = true; + } + + assertTrue(expThrown); + expThrown = false; + + try { + graph.remove(t1); + } catch(UnsupportedOperationException uoe) { + expThrown = true; + } + + assertTrue(expThrown); + expThrown = false; + + try { + graph.addAll(t); + } catch(UnsupportedOperationException uoe) { + expThrown = true; + } + + assertTrue(expThrown); + + expThrown = false; + + try { + graph.clear(); + } catch(UnsupportedOperationException uoe) { + expThrown = true; + } + + assertTrue(expThrown); + + expThrown = false; + + try { + graph.removeAll(t); + } catch(UnsupportedOperationException uoe) { + expThrown = true; + } + + assertTrue(expThrown); + provider.deleteGraph(graphIRI); + } + +// This tests can not pass, because equals in AbstractGraph is not implemented +// yet. +// @Test +// public void testGraphHasName() throws Exception { +// +// TcProvider provider = getInstance(); +// +// Graph triples = createTestTripleCollection(createTestTriple()); +// ImmutableGraph graph = provider.createGraph(graphIRI, triples); +// +// provider = getInstance(); +// Set<IRI> names = provider.getNames(graph); +// assertTrue(names.contains(graphIRI)); +// } +// +// @Test +// public void testCreateSameGraphWithDifferentNames() throws Exception { +// +// Graph triples = createTestTripleCollection(createTestTriple()); +// +// TcProvider provider = getInstance(); +// IRI name1 = new IRI("http://myGraph1"); +// ImmutableGraph graph = provider.createGraph(name1, triples); +// +// IRI name2 = new IRI("http://myGraph2"); +// ImmutableGraph secondGraph = provider.createGraph(name2, triples); +// +// Set<IRI> names = provider.getNames(graph); +// assertNotNull(names); +// assertEquals(2, names.size()); +// } + + @Test + public void testGraphDeletion() throws Exception { + + Graph triples = createTestTripleCollection(createTestTriple()); + + TcProvider provider = getInstance(); + IRI name1 = new IRI("http://myGraph1"); + ImmutableGraph graph = provider.createImmutableGraph(name1, triples); + + IRI name2 = new IRI("http://myGraph2"); + ImmutableGraph secondGraph = provider.createImmutableGraph(name2, triples); + + //if we delete graph with name1, the second graph should still be there + provider.deleteGraph(name1); + + provider = getInstance(); + ImmutableGraph firstGraph = provider.getImmutableGraph(name2); + assertNotNull(firstGraph); + + //check second name is not there + boolean expThrown = false; + + try { + ImmutableGraph g = provider.getImmutableGraph(name1); + } catch(NoSuchEntityException nses) { + expThrown = true; + } + + assertTrue(expThrown); + provider.deleteGraph(name2); + } + + + + @Test + public void testGetTriplesGraph() throws Exception { + TcProvider provider = getInstance(); + + Graph graph = provider.createGraph(graphIRI); + + Graph tc = provider.getGraph(graphIRI); + assertNotNull(tc); + provider.deleteGraph(graphIRI); + } + + private Triple createTestTriple() { + BlankNodeOrIRI subject = new BlankNode() {}; + IRI predicate = new IRI("http://test.com/"); + BlankNodeOrIRI object = new IRI("http://test.com/myObject"); + return new TripleImpl(subject, predicate, object); + } + + private Graph createTestTripleCollection(Triple t) { + Set<Triple> ts = new HashSet<Triple>(); + ts.add(t); + return new SimpleGraph(ts); + } + + protected IRI generateUri(String name) { + return new IRI("http://example.org/" + name); + } + +}
