/*
* Copyright 2015-2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* 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.
*/
package org.hawkular.inventory.impl.tinkerpop.spi;
import java.util.Iterator;
import java.util.concurrent.CountDownLatch;
import java.util.function.Consumer;
import java.util.function.Function;
import org.apache.tinkerpop.gremlin.process.computer.GraphComputer;
import org.apache.tinkerpop.gremlin.structure.Edge;
import org.apache.tinkerpop.gremlin.structure.Graph;
import org.apache.tinkerpop.gremlin.structure.Transaction;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.hawkular.inventory.api.Configuration;
import org.junit.Assert;
import org.junit.Test;
/**
* @author Lukas Krejci
* @since 0.17.2
*/
public class GraphProviderTest {
@Test
public void testConcurrentTransactionsAllowed() throws Exception {
//lock the commits of the 2 concurrent threads on this latch to ensure that we
//truly do have 2 concurrent transactions on a single graph
final CountDownLatch startLatch = new CountDownLatch(2);
final CountDownLatch finishLatch = new CountDownLatch(1);
boolean[] statuses = new boolean[2];
GraphProvider gp = new DummyGraphProvider();
Graph g = gp.instantiateGraph(null);
Consumer<Integer> payload = (idx) -> {
gp.startTransaction(g);
startLatch.countDown();
try {
finishLatch.await();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IllegalStateException("The test graph should not be forcefully interrupted during test.");
}
gp.commit(g);
statuses[idx] = true;
};
Thread t1 = new Thread(() -> payload.accept(0));
Thread t2 = new Thread(() -> payload.accept(1));
t1.start();
t2.start();
startLatch.await();
finishLatch.countDown();
t1.join();
t2.join();
Assert.assertTrue(statuses[0]);
Assert.assertTrue(statuses[1]);
}
@Test(expected = IllegalStateException.class)
public void testNestedTransactionsDisallowed() throws Exception {
GraphProvider gp = new DummyGraphProvider();
Graph g = gp.instantiateGraph(null);
gp.startTransaction(g);
gp.startTransaction(g);
}
private static class DummyGraphProvider implements GraphProvider {
@Override public boolean isPreferringBigTransactions() {
return false;
}
@Override public boolean needsDraining() {
return false;
}
@Override public boolean isUniqueIndexSupported() {
return false;
}
@Override public Graph instantiateGraph(Configuration configuration) {
return new DummyGraph();
}
@Override public void ensureIndices(Graph graph, IndexSpec... indexSpecs) {
}
}
private static class DummyGraph implements Graph {
@Override public Vertex addVertex(Object... keyValues) {
return null;
}
@Override public <C extends GraphComputer> C compute(Class<C> graphComputerClass)
throws IllegalArgumentException {
return null;
}
@Override public GraphComputer compute() throws IllegalArgumentException {
return null;
}
@Override public Iterator<Vertex> vertices(Object... vertexIds) {
return null;
}
@Override public Iterator<Edge> edges(Object... edgeIds) {
return null;
}
@Override public Transaction tx() {
return new DummyTx();
}
@Override public void close() throws Exception {
}
@Override public Variables variables() {
return null;
}
@Override public org.apache.commons.configuration.Configuration configuration() {
return null;
}
}
private static class DummyTx implements Transaction {
@Override public void open() {
}
@Override public void commit() {
}
@Override public void rollback() {
}
@Override public <R> Workload<R> submit(Function<Graph, R> work) {
return null;
}
@Override public <G extends Graph> G createThreadedTx() {
return null;
}
@Override public boolean isOpen() {
return false;
}
@Override public void readWrite() {
}
@Override public void close() {
}
@Override public Transaction onReadWrite(Consumer<Transaction> consumer) {
return null;
}
@Override public Transaction onClose(Consumer<Transaction> consumer) {
return null;
}
@Override public void addTransactionListener(Consumer<Status> listener) {
}
@Override public void removeTransactionListener(Consumer<Status> listener) {
}
@Override public void clearTransactionListeners() {
}
}
}