Package org.apache.marmotta.kiwi.test

Source Code of org.apache.marmotta.kiwi.test.RepositoryTest

/*
* 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.marmotta.kiwi.test;

import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.marmotta.commons.sesame.repository.ResourceUtils;
import org.apache.marmotta.kiwi.config.KiWiConfiguration;
import org.apache.marmotta.kiwi.sail.KiWiStore;
import org.apache.marmotta.kiwi.test.junit.KiWiDatabaseRunner;
import org.hamcrest.CoreMatchers;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.openrdf.model.*;
import org.openrdf.query.MalformedQueryException;
import org.openrdf.query.QueryLanguage;
import org.openrdf.query.Update;
import org.openrdf.query.UpdateExecutionException;
import org.openrdf.repository.Repository;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.RepositoryException;
import org.openrdf.repository.sail.SailRepository;
import org.openrdf.rio.RDFFormat;
import org.openrdf.rio.RDFParseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import info.aduna.iteration.Iterations;

import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.ConcurrentModificationException;
import java.util.List;

import static org.hamcrest.CoreMatchers.hasItems;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.Matchers.*;
import static org.junit.Assume.assumeThat;

/**
* Test the Sesame repository functionality backed by the KiWi triple store.
*
* @author Sebastian Schaffert (sschaffert@apache.org)
*/
@RunWith(KiWiDatabaseRunner.class)
public class RepositoryTest {

    private static Logger log = LoggerFactory.getLogger(RepositoryTest.class);

    private Repository repository;

    private KiWiStore store;

    private final KiWiConfiguration kiwiConfiguration;

    public RepositoryTest(KiWiConfiguration kiwiConfiguration) {
        this.kiwiConfiguration = kiwiConfiguration;

    }

    @Before
    public void initDatabase() throws RepositoryException {
        store = new KiWiStore(kiwiConfiguration);
        store.setDropTablesOnShutdown(true);
        repository = new SailRepository(store);
        repository.initialize();
    }

    @After
    public void dropDatabase() throws RepositoryException, SQLException {
        repository.shutDown();
    }


    /**
     * Test importing data; the test will load a small sample RDF file and check whether the expected resources are
     * present.
     *
     * @throws RepositoryException
     * @throws RDFParseException
     * @throws IOException
     */
    @Test
    public void testImport() throws RepositoryException, RDFParseException, IOException {
        long start, end;

        start = System.currentTimeMillis();
        // load demo data
        InputStream rdfXML = this.getClass().getResourceAsStream("demo-data.foaf");
        assumeThat("Could not load test-data: demo-data.foaf", rdfXML, notNullValue(InputStream.class));

        RepositoryConnection connectionRDF = repository.getConnection();
        try {
            connectionRDF.add(rdfXML, "http://localhost/foaf/", RDFFormat.RDFXML);
            connectionRDF.commit();
        } finally {
            connectionRDF.close();
        }
        end = System.currentTimeMillis();

        log.info("IMPORT: {} ms", end-start);

        start = System.currentTimeMillis();
        // get another connection and check if demo data is available
        RepositoryConnection connection = repository.getConnection();

        List<String> resources = ImmutableList.copyOf(
                Iterables.transform(
                        ResourceUtils.listResources(connection),
                        new Function<Resource, String>() {
                            @Override
                            public String apply(Resource input) {
                                return input.stringValue();
                            }
                        }
                )
        );

        // test if the result has the expected size
        //FIXME: this test is no longer valid, because resource existance is not bound to use as subject
        //Assert.assertEquals(4, resources.size());

        // test if the result contains all resources that have been used as subject
        Assert.assertThat(resources, hasItems(
                "http://localhost:8080/LMF/resource/hans_meier",
                "http://localhost:8080/LMF/resource/sepp_huber",
                "http://localhost:8080/LMF/resource/anna_schmidt"
        ));
        connection.commit();
        connection.close();

        end = System.currentTimeMillis();

        log.info("QUERY EVALUATION: {} ms", end-start);
    }

    // TODO: test delete, test query,

    /**
     * Test setting, retrieving and updating namespaces through the repository API
     * @throws RepositoryException
     */
    @Test
    @SuppressWarnings("unchecked")
    public void testNamespaces() throws RepositoryException {
        RepositoryConnection connection = repository.getConnection();

        connection.begin();
        connection.setNamespace("ns1","http://localhost/ns1/");
        connection.setNamespace("ns2","http://localhost/ns2/");

        connection.commit();

        Assert.assertEquals("http://localhost/ns1/", connection.getNamespace("ns1"));
        Assert.assertEquals("http://localhost/ns2/", connection.getNamespace("ns2"));
        Assert.assertEquals(2, Iterations.asList(connection.getNamespaces()).size());
        Assert.assertThat(
                Iterations.asList(connection.getNamespaces()),
                CoreMatchers.<Namespace>hasItems(
                        hasProperty("name", is("http://localhost/ns1/")),
                        hasProperty("name", is("http://localhost/ns2/"))
                )
        );

        // update ns1 to a different URL
        connection.begin();
        connection.setNamespace("ns1","http://localhost/ns3/");
        connection.commit();

        Assert.assertEquals("http://localhost/ns3/", connection.getNamespace("ns1"));
        Assert.assertThat(
                Iterations.asList(connection.getNamespaces()),
                CoreMatchers.<Namespace>hasItems(
                        hasProperty("name", is("http://localhost/ns3/")),
                        hasProperty("name", is("http://localhost/ns2/"))
                )
        );


        // remove ns2
        connection.begin();
        connection.removeNamespace("ns2");
        connection.commit();

        connection.begin();
        Assert.assertEquals(1, Iterations.asList(connection.getNamespaces()).size());


        connection.commit();
        connection.close();

    }


    @Test
    public void testDeleteTriple() throws RepositoryException, RDFParseException, IOException {
        // load demo data
        InputStream rdfXML = this.getClass().getResourceAsStream("demo-data.foaf");
        assumeThat("Could not load test-data: demo-data.foaf", rdfXML, notNullValue(InputStream.class));

        RepositoryConnection connectionRDF = repository.getConnection();
        try {
            connectionRDF.add(rdfXML, "http://localhost/foaf/", RDFFormat.RDFXML);
            connectionRDF.commit();
        } finally {
            connectionRDF.close();
        }
        // get another connection and check if demo data is available
        RepositoryConnection connection = repository.getConnection();

        try {
            connection.begin();
            List<String> resources = ImmutableList.copyOf(
                    Iterables.transform(
                            ResourceUtils.listResources(connection),
                            new Function<Resource, String>() {
                                @Override
                                public String apply(Resource input) {
                                    return input.stringValue();
                                }
                            }
                    )
            );

            // test if the result has the expected size
            // FIXME: MARMOTTA-39 (no xsd:string, so one resource is "missing")
            // Assert.assertEquals(31, resources.size());
            Assert.assertEquals(30, resources.size());

            // test if the result contains all resources that have been used as subject
            Assert.assertThat(resources, hasItems(
                    "http://localhost:8080/LMF/resource/hans_meier",
                    "http://localhost:8080/LMF/resource/sepp_huber",
                    "http://localhost:8080/LMF/resource/anna_schmidt"
            ));
            long oldsize = connection.size();
            connection.commit();


            // remove a resource and all its triples
            connection.begin();
            ResourceUtils.removeResource(connection, connection.getValueFactory().createURI("http://localhost:8080/LMF/resource/hans_meier"));
            connection.commit();

            connection.begin();
            long newsize = connection.size();

            // new size should be less, since we removed some triples
            Assert.assertThat(newsize, lessThan(oldsize));

            // the resource hans_meier should not be contained in the list of resources
            List<String> resources2 = ImmutableList.copyOf(
                    Iterables.transform(
                            ResourceUtils.listSubjects(connection),
                            new Function<Resource, String>() {
                                @Override
                                public String apply(Resource input) {
                                    return input.stringValue();
                                }
                            }
                    )
            );

            // test if the result has the expected size
            //Assert.assertEquals(3, resources2.size());

            // test if the result does not contain the removed resource
            Assert.assertThat(resources2, not(hasItem(
                    "http://localhost:8080/LMF/resource/hans_meier"
            )));
        } finally {
            connection.commit();
            connection.close();
        }
    }


    /**
     * Test a repeated addition of the same triple, because this is a special case in the database.
     */
    @Test
    public void testRepeatedAdd() throws RepositoryException, IOException, RDFParseException {
        // load demo data
        InputStream rdfXML = this.getClass().getResourceAsStream("srfg-ontology.rdf");
        assumeThat("Could not load test-data: srfg-ontology.rdf", rdfXML, notNullValue(InputStream.class));

        long oldsize, newsize;
        List<Statement> oldTriples, newTriples;

        RepositoryConnection connectionRDF = repository.getConnection();
        try {
            connectionRDF.begin();
            connectionRDF.add(rdfXML, "http://localhost/srfg/", RDFFormat.RDFXML);
            connectionRDF.commit();

            oldTriples = Iterations.asList(connectionRDF.getStatements(null,null,null,true));
            oldsize = connectionRDF.size();
        } finally {
            connectionRDF.close();
        }


        // get another connection and add the same data again
        rdfXML = this.getClass().getResourceAsStream("srfg-ontology.rdf");
        RepositoryConnection connection = repository.getConnection();

        try {
            connection.begin();
            connection.add(rdfXML, "http://localhost/srfg/", RDFFormat.RDFXML);
            connection.commit();

            newTriples = Iterations.asList(connection.getStatements(null,null,null,true));
            newsize = connection.size();
        } finally {
            connection.commit();
            connection.close();
        }

        Assert.assertEquals(oldTriples,newTriples);
        Assert.assertEquals(oldsize,newsize);
    }


    /**
     * Test adding-deleting-adding a triple
     *
     * @throws Exception
     */
    @Test
    public void testRepeatedAddRemove() throws Exception {
        String value = RandomStringUtils.randomAlphanumeric(8);

        URI subject = repository.getValueFactory().createURI("http://localhost/resource/" + RandomStringUtils.randomAlphanumeric(8));
        URI predicate = repository.getValueFactory().createURI("http://localhost/resource/" + RandomStringUtils.randomAlphanumeric(8));
        Literal object1 = repository.getValueFactory().createLiteral(value);

        RepositoryConnection connection1 = repository.getConnection();
        try {
            connection1.add(subject,predicate,object1);
            connection1.commit();

            Assert.assertTrue(connection1.hasStatement(subject,predicate,object1,true));

            connection1.commit();
        } finally {
            connection1.close();
        }

        Literal object2 = repository.getValueFactory().createLiteral(value);
        RepositoryConnection connection2 = repository.getConnection();
        try {
            Assert.assertTrue(connection2.hasStatement(subject,predicate,object2,true));

            connection2.remove(subject,predicate,object2);
            connection2.commit();

            Assert.assertFalse(connection2.hasStatement(subject,predicate,object2,true));

            connection2.commit();
        } finally {
            connection2.close();
        }

        Literal object3 = repository.getValueFactory().createLiteral(value);
        RepositoryConnection connection3 = repository.getConnection();
        try {
            Assert.assertFalse(connection3.hasStatement(subject,predicate,object3,true));

            connection3.add(subject,predicate,object3);
            connection3.commit();

            Assert.assertTrue(connection3.hasStatement(subject,predicate,object3,true));

            connection3.commit();
        } finally {
            connection3.close();
        }

        Literal object4 = repository.getValueFactory().createLiteral(value);
        RepositoryConnection connection4 = repository.getConnection();
        try {
            Assert.assertTrue(connection4.hasStatement(subject,predicate,object4,true));

            connection4.commit();
        } finally {
            connection4.close();
        }


    }

    /**
     * Test adding-deleting-adding a triple
     *
     * @throws Exception
     */
    @Test
    public void testRepeatedAddRemoveTransaction() throws Exception {
        String value = RandomStringUtils.randomAlphanumeric(8);

        URI subject = repository.getValueFactory().createURI("http://localhost/resource/" + RandomStringUtils.randomAlphanumeric(8));
        URI predicate = repository.getValueFactory().createURI("http://localhost/resource/" + RandomStringUtils.randomAlphanumeric(8));
        Literal object1 = repository.getValueFactory().createLiteral(value);

        RepositoryConnection connection1 = repository.getConnection();
        try {
            connection1.add(subject,predicate,object1);
            connection1.commit();

            Assert.assertTrue(connection1.hasStatement(subject,predicate,object1,true));

            connection1.commit();
        } finally {
            connection1.close();
        }

        Literal object2 = repository.getValueFactory().createLiteral(value);
        Literal object3 = repository.getValueFactory().createLiteral(value);
        RepositoryConnection connection2 = repository.getConnection();
        try {
            Assert.assertTrue(connection2.hasStatement(subject,predicate,object2,true));

            connection2.remove(subject,predicate,object2);
            Assert.assertFalse(connection2.hasStatement(subject,predicate,object2,true));

            connection2.add(subject,predicate,object3);
            Assert.assertTrue(connection2.hasStatement(subject,predicate,object3,true));

            connection2.commit();
        } finally {
            connection2.close();
        }

        Literal object4 = repository.getValueFactory().createLiteral(value);
        RepositoryConnection connection4 = repository.getConnection();
        try {
            Assert.assertTrue(connection4.hasStatement(subject,predicate,object4,true));

            connection4.commit();
        } finally {
            connection4.close();
        }

        // test repeated adding/removing inside the same transaction
        Literal object5 = repository.getValueFactory().createLiteral(RandomStringUtils.randomAlphanumeric(8));
        RepositoryConnection connection5 = repository.getConnection();
        try {
            Assert.assertFalse(connection5.hasStatement(subject, predicate, object5, true));

            connection5.add(subject,predicate,object5);
            Assert.assertTrue(connection5.hasStatement(subject,predicate,object5,true));

            connection5.remove(subject,predicate,object5);
            Assert.assertFalse(connection5.hasStatement(subject,predicate,object5,true));

            connection5.add(subject,predicate,object5);
            Assert.assertTrue(connection5.hasStatement(subject,predicate,object5,true));
            connection5.commit();
        } finally {
            connection5.close();
        }

        RepositoryConnection connection6 = repository.getConnection();
        try {
            Assert.assertTrue(connection6.hasStatement(subject, predicate, object5, true));

            connection6.commit();
        } finally {
            connection6.close();
        }

    }

    @Test
    public void testRepeatedAddRemoveCrossTransaction() throws RepositoryException {
        String value = RandomStringUtils.randomAlphanumeric(8);

        URI subject = repository.getValueFactory().createURI("http://localhost/resource/" + RandomStringUtils.randomAlphanumeric(8));
        URI predicate = repository.getValueFactory().createURI("http://localhost/resource/" + RandomStringUtils.randomAlphanumeric(8));
        Literal object1 = repository.getValueFactory().createLiteral(value);

        RepositoryConnection connection1 = repository.getConnection();
        try {
            connection1.add(subject,predicate,object1);
            connection1.commit();

            Assert.assertTrue(connection1.hasStatement(subject,predicate,object1,true));

            connection1.commit();
        } finally {
            connection1.close();
        }

        RepositoryConnection connection2 = repository.getConnection();
        try {
            connection2.remove(subject, predicate, object1);
            Assert.assertFalse(connection2.hasStatement(subject, predicate, object1, true));

            connection2.add(subject,predicate,object1);
            Assert.assertTrue(connection2.hasStatement(subject, predicate, object1, true));

            connection2.commit();
        } finally {
            connection2.close();
        }

        RepositoryConnection connection3 = repository.getConnection();
        try {
            Assert.assertTrue(connection3.hasStatement(subject, predicate, object1, true));
            connection3.commit();
        } finally {
            connection3.close();
        }
    }

    @Test
    public void testRepeatedAddRemoveSPARQL() throws RepositoryException, MalformedQueryException, UpdateExecutionException {
        String value = RandomStringUtils.randomAlphanumeric(8);

        URI subject = repository.getValueFactory().createURI("http://localhost/resource/" + RandomStringUtils.randomAlphanumeric(8));
        URI predicate = repository.getValueFactory().createURI("http://localhost/resource/" + RandomStringUtils.randomAlphanumeric(8));
        Literal object1 = repository.getValueFactory().createLiteral(value);

        RepositoryConnection connection1 = repository.getConnection();
        try {
            connection1.add(subject,predicate,object1);
            connection1.commit();

            Assert.assertTrue(connection1.hasStatement(subject,predicate,object1,true));

            connection1.commit();
        } finally {
            connection1.close();
        }

        RepositoryConnection connection2 = repository.getConnection();
        try {
            String query = String.format("DELETE { <%s> <%s> ?v } INSERT { <%s> <%s> ?v . } WHERE { <%s> <%s> ?v }", subject.stringValue(), predicate.stringValue(), subject.stringValue(), predicate.stringValue(), subject.stringValue(), predicate.stringValue());

            Update u = connection2.prepareUpdate(QueryLanguage.SPARQL, query);
            u.execute();

            connection2.commit();
        } finally {
            connection2.close();
        }

        RepositoryConnection connection3 = repository.getConnection();
        try {
            Assert.assertTrue(connection3.hasStatement(subject, predicate, object1, true));
            connection3.commit();
        } finally {
            connection3.close();
        }
    }


    /**
     * Test the rollback functionality of the triple store by adding a triple, rolling back, adding the triple again.
     *
     * @throws Exception
     */
    @Test
    public void testRollback() throws Exception {
        String value = RandomStringUtils.randomAlphanumeric(8);

        URI subject = repository.getValueFactory().createURI("http://localhost/resource/" + RandomStringUtils.randomAlphanumeric(8));
        URI predicate = repository.getValueFactory().createURI("http://localhost/resource/" + RandomStringUtils.randomAlphanumeric(8));
        Literal object = repository.getValueFactory().createLiteral(value);

        RepositoryConnection connection1 = repository.getConnection();
        try {
            connection1.begin();
            connection1.add(subject,predicate,object);
            connection1.rollback();

        } finally {
            connection1.close();
        }

        RepositoryConnection connection2 = repository.getConnection();
        try {
            connection2.begin();
            Assert.assertFalse(connection2.hasStatement(subject,predicate,object,true));

            connection2.add(subject,predicate,object);
            connection2.commit();

            Assert.assertTrue(connection2.hasStatement(subject,predicate,object,true));

            connection2.commit();
        } finally {
            connection2.close();
        }

    }

    /**
     * This test is for a strange bug that happens when running SPARQL updates that delete and reinsert a triple in
     * the same transaction. See https://issues.apache.org/jira/browse/MARMOTTA-283
     */
    @Test
    public void testMARMOTTA283() throws RepositoryException, RDFParseException, IOException, MalformedQueryException, UpdateExecutionException {

        InputStream rdfXML = this.getClass().getResourceAsStream("demo-data.foaf");
        assumeThat("Could not load test-data: demo-data.foaf", rdfXML, notNullValue(InputStream.class));

        RepositoryConnection connectionRDF = repository.getConnection();
        try {
            connectionRDF.add(rdfXML, "http://localhost/foaf/", RDFFormat.RDFXML);
            connectionRDF.commit();
        } finally {
            connectionRDF.close();
        }


        String update = "DELETE { ?s ?p ?o } INSERT { <http://localhost:8080/LMF/resource/hans_meier> <http://xmlns.com/foaf/0.1/name> \"Hans Meier\" . <http://localhost:8080/LMF/resource/hans_meier> <http://xmlns.com/foaf/0.1/based_near> <http://dbpedia.org/resource/Traunstein> . <http://localhost:8080/LMF/resource/hans_meier> <http://xmlns.com/foaf/0.1/interest> <http://rdf.freebase.com/ns/en.linux> } WHERE { ?s ?p ?o . FILTER ( ?s = <http://localhost:8080/LMF/resource/hans_meier> ) }";

        RepositoryConnection connectionUpdate = repository.getConnection();
        try {
            Update u = connectionUpdate.prepareUpdate(QueryLanguage.SPARQL, update);
            u.execute();
            connectionUpdate.commit();
        } finally {
            connectionUpdate.close();
        }

        // now there should be two triples
        RepositoryConnection connectionVerify = repository.getConnection();
        try {
            URI hans_meier = repository.getValueFactory().createURI("http://localhost:8080/LMF/resource/hans_meier");
            URI foaf_name  = repository.getValueFactory().createURI("http://xmlns.com/foaf/0.1/name");
            URI foaf_based_near = repository.getValueFactory().createURI("http://xmlns.com/foaf/0.1/based_near");
            URI foaf_interest = repository.getValueFactory().createURI("http://xmlns.com/foaf/0.1/interest");
            URI freebase_linux = repository.getValueFactory().createURI("http://rdf.freebase.com/ns/en.linux");
            URI traunstein = repository.getValueFactory().createURI("http://dbpedia.org/resource/Traunstein");

            Assert.assertTrue(connectionVerify.hasStatement(hans_meier,foaf_name,null, true));
            Assert.assertTrue(connectionVerify.hasStatement(hans_meier,foaf_based_near,traunstein, true));
            Assert.assertTrue(connectionVerify.hasStatement(hans_meier,foaf_interest,freebase_linux, true));

            connectionVerify.commit();
        } finally {
            connectionVerify.close();
        }
    }

    /**
     * This test is for a strange bug that happens when running SPARQL updates that delete and reinsert a triple in
     * the same transaction. It is similar to #testMARMOTTA283, but simulates the issue in more detail.
     * See https://issues.apache.org/jira/browse/MARMOTTA-283
     */
    @Test
    public void testMARMOTTA283_2() throws RepositoryException, RDFParseException, IOException, MalformedQueryException, UpdateExecutionException {

        //insert quadruples
        String insert =
                "WITH <http://resource.org/video>" +
                "INSERT {" +
                "   <http://resource.org/video> <http://ontology.org#hasFragment> <http://resource.org/fragment1>." +
                "   <http://resource.org/annotation1> <http://ontology.org#hasTarget> <http://resource.org/fragment1>." +
                "   <http://resource.org/annotation1> <http://ontology.org#hasBody> <http://resource.org/subject1>." +
                "   <http://resource.org/fragment1> <http://ontology.org#shows> <http://resource.org/subject1>." +
                "} WHERE {}";

        RepositoryConnection connectionInsert = repository.getConnection();
        try {
            Update u = connectionInsert.prepareUpdate(QueryLanguage.SPARQL, insert);
            u.execute();
            connectionInsert.commit();
        } finally {
            connectionInsert.close();
        }

        //update quadruples
        String update =
                "WITH <http://resource.org/video>" +
                "DELETE { " +
                "   ?annotation ?p ?v." +
                "   ?fragment ?r ?s." +
                "   <http://resource.org/video> <http://ontology.org#hasFragment> ?fragment." +
                "} INSERT {" +
                "   <http://resource.org/video> <http://ontology.org#hasFragment> <http://resource.org/fragment1>." +
                "   <http://resource.org/annotation1> <http://ontology.org#hasTarget> <http://resource.org/fragment1>." +
                "   <http://resource.org/annotation1> <http://ontology.org#hasBody> <http://resource.org/subject1>." +
                "   <http://resource.org/fragment1> <http://ontology.org#shows> <http://resource.org/subject1>." +
                "} WHERE {" +
                "   ?annotation <http://ontology.org#hasTarget> ?fragment." +
                "   ?annotation ?p ?v." +
                "   OPTIONAL {" +
                "       ?fragment ?r ?s" +
                "   }" +
                "   FILTER (?fragment = <http://resource.org/fragment1>)" +
                "} ";

        RepositoryConnection connectionUpdate = repository.getConnection();
        try {
            Update u = connectionUpdate.prepareUpdate(QueryLanguage.SPARQL, update);
            u.execute();
            connectionUpdate.commit();
        } finally {
            connectionUpdate.close();
        }

        //check quadruples
        RepositoryConnection connectionVerify = repository.getConnection();
        try {
            URI video = repository.getValueFactory().createURI("http://resource.org/video");
            URI hasFragment  = repository.getValueFactory().createURI("http://ontology.org#hasFragment");
            URI fragment = repository.getValueFactory().createURI("http://resource.org/fragment1");
            URI annotation = repository.getValueFactory().createURI("http://resource.org/annotation1");
            URI hasTarget = repository.getValueFactory().createURI("http://ontology.org#hasTarget");
            URI hasBody = repository.getValueFactory().createURI("http://ontology.org#hasBody");
            URI subject = repository.getValueFactory().createURI("http://resource.org/subject1");
            URI shows = repository.getValueFactory().createURI("http://ontology.org#shows");

            Assert.assertTrue(connectionVerify.hasStatement(video,hasFragment,fragment,true,video));
            Assert.assertTrue(connectionVerify.hasStatement(annotation,hasTarget,fragment,true,video));
            Assert.assertTrue(connectionVerify.hasStatement(annotation,hasBody,subject,true,video));
            Assert.assertTrue(connectionVerify.hasStatement(fragment,shows,subject,true,video));

            connectionVerify.commit();
        } finally {
            connectionVerify.close();
        }
    }

    /**
     * Test the concurrent connection problem reported in MARMOTTA-236 for facading:
     * - get two parallel connections
     * - add triple in connection 1; should be available in connection 1 and not in connection 2
     * - add same triple in connection 2; should be available in both, connection 1 and connection 2 or
     *   fail-fast by throwing a ConcurrentModificationException
     * @throws Exception
     */
    @Test
    public void testMARMOTTA236() throws Exception {
        RepositoryConnection con1 = repository.getConnection();
        RepositoryConnection con2 = repository.getConnection();

        try {
            URI r1 = repository.getValueFactory().createURI("http://localhost/"+ RandomStringUtils.randomAlphanumeric(8));
            URI r2 = repository.getValueFactory().createURI("http://localhost/"+ RandomStringUtils.randomAlphanumeric(8));
            URI r3 = repository.getValueFactory().createURI("http://localhost/"+ RandomStringUtils.randomAlphanumeric(8));

            con1.begin();
            con1.add(r1,r2,r3);

            Assert.assertTrue(con1.hasStatement(r1,r2,r3,true));

            con2.begin();
            Assert.assertFalse(con2.hasStatement(r1,r2,r3,true));

            con2.add(r1,r2,r3);

            Assert.assertTrue(con2.hasStatement(r1,r2,r3,true));

            con2.rollback();
            con1.commit();
        } catch (ConcurrentModificationException ex) {

        } finally {
            con1.close();
            con2.close();
        }


    }
}
TOP

Related Classes of org.apache.marmotta.kiwi.test.RepositoryTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.