X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-distributed-datastore%2Fsrc%2Ftest%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcluster%2Fdatastore%2FTransactionProxyTest.java;h=a5625637f4b5720d2d8084dcd415ab94b31a0c7a;hp=8909e1d3127fe7e49e986470f95d4a04533cf206;hb=482caffb6cc503ab1d156109a5dba8c2fe675f3d;hpb=233db109dea38ed45ca3c48eba04f302e38a9139 diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/TransactionProxyTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/TransactionProxyTest.java index 8909e1d312..a5625637f4 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/TransactionProxyTest.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/TransactionProxyTest.java @@ -1,3 +1,11 @@ +/* + * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + package org.opendaylight.controller.cluster.datastore; import static org.junit.Assert.assertEquals; @@ -19,6 +27,7 @@ import akka.actor.ActorSelection; import akka.actor.ActorSystem; import akka.actor.Props; import akka.dispatch.Futures; +import akka.util.Timeout; import com.google.common.base.Optional; import com.google.common.collect.Sets; import com.google.common.util.concurrent.CheckedFuture; @@ -34,6 +43,7 @@ import org.junit.Assert; import org.junit.Test; import org.mockito.InOrder; import org.mockito.Mockito; +import org.opendaylight.controller.cluster.datastore.config.Configuration; import org.opendaylight.controller.cluster.datastore.exceptions.NoShardLeaderException; import org.opendaylight.controller.cluster.datastore.exceptions.NotInitializedException; import org.opendaylight.controller.cluster.datastore.exceptions.PrimaryNotFoundException; @@ -47,8 +57,8 @@ import org.opendaylight.controller.cluster.datastore.modification.DeleteModifica import org.opendaylight.controller.cluster.datastore.modification.MergeModification; import org.opendaylight.controller.cluster.datastore.modification.WriteModification; import org.opendaylight.controller.cluster.datastore.shardstrategy.DefaultShardStrategy; -import org.opendaylight.controller.cluster.datastore.utils.DoNothingActor; import org.opendaylight.controller.cluster.datastore.utils.NormalizedNodeAggregatorTest; +import org.opendaylight.controller.cluster.raft.utils.DoNothingActor; import org.opendaylight.controller.md.cluster.datastore.model.CarsModel; import org.opendaylight.controller.md.cluster.datastore.model.SchemaContextHelper; import org.opendaylight.controller.md.cluster.datastore.model.TestModel; @@ -138,7 +148,7 @@ public class TransactionProxyTest extends AbstractTransactionProxyTest { } doReturn(Futures.failed(exToThrow)).when(mockActorContext).executeOperationAsync( - any(ActorSelection.class), any()); + any(ActorSelection.class), any(), any(Timeout.class)); TransactionProxy transactionProxy = new TransactionProxy(mockComponentFactory, READ_ONLY); @@ -216,7 +226,8 @@ public class TransactionProxyTest extends AbstractTransactionProxyTest { when(mockActorContext).findPrimaryShardAsync(eq(DefaultShardStrategy.DEFAULT_SHARD)); doReturn(Futures.successful(new Object())).when(mockActorContext).executeOperationAsync( - eq(getSystem().actorSelection(actorRef.path())), eqCreateTransaction(memberName, READ_ONLY)); + eq(getSystem().actorSelection(actorRef.path())), eqCreateTransaction(memberName, READ_ONLY), + any(Timeout.class)); TransactionProxy transactionProxy = new TransactionProxy(mockComponentFactory, READ_ONLY); @@ -334,7 +345,7 @@ public class TransactionProxyTest extends AbstractTransactionProxyTest { Promise createTxPromise = akka.dispatch.Futures.promise(); doReturn(createTxPromise).when(mockActorContext).executeOperationAsync( eq(getSystem().actorSelection(actorRef.path())), - eqCreateTransaction(memberName, READ_WRITE)); + eqCreateTransaction(memberName, READ_WRITE), any(Timeout.class)); doReturn(readSerializedDataReply(null)).when(mockActorContext).executeOperationAsync( eq(actorSelection(actorRef)), eqSerializedReadData()); @@ -798,20 +809,30 @@ public class TransactionProxyTest extends AbstractTransactionProxyTest { throttleOperation(operation, 1, true); } + private void throttleOperation(TransactionProxyOperation operation, int outstandingOpsLimit, boolean shardFound){ + throttleOperation(operation, outstandingOpsLimit, shardFound, TimeUnit.MILLISECONDS.toNanos( + mockActorContext.getDatastoreContext().getOperationTimeoutInMillis())); + } + private PrimaryShardInfo newPrimaryShardInfo(ActorRef actorRef){ - return new PrimaryShardInfo(getSystem().actorSelection(actorRef.path()), Optional.absent()); + return new PrimaryShardInfo(getSystem().actorSelection(actorRef.path()), DataStoreVersions.CURRENT_VERSION, + Optional.absent()); } private PrimaryShardInfo newPrimaryShardInfo(ActorRef actorRef, Optional dataTreeOptional){ - return new PrimaryShardInfo(getSystem().actorSelection(actorRef.path()), dataTreeOptional); + return new PrimaryShardInfo(getSystem().actorSelection(actorRef.path()), DataStoreVersions.CURRENT_VERSION, + dataTreeOptional); } - private void throttleOperation(TransactionProxyOperation operation, int outstandingOpsLimit, boolean shardFound){ + private void throttleOperation(TransactionProxyOperation operation, int outstandingOpsLimit, boolean shardFound, long expectedCompletionTime){ ActorSystem actorSystem = getSystem(); ActorRef shardActorRef = actorSystem.actorOf(Props.create(DoNothingActor.class)); - doReturn(outstandingOpsLimit).when(mockActorContext).getTransactionOutstandingOperationLimit(); + // Note that we setting batchedModificationCount to one less than what we need because in TransactionProxy + // we now allow one extra permit to be allowed for ready + doReturn(dataStoreContextBuilder.operationTimeoutInSeconds(2). + shardBatchedModificationCount(outstandingOpsLimit-1).build()).when(mockActorContext).getDatastoreContext(); doReturn(actorSystem.actorSelection(shardActorRef.path())). when(mockActorContext).actorSelection(shardActorRef.path().toString()); @@ -819,19 +840,19 @@ public class TransactionProxyTest extends AbstractTransactionProxyTest { if(shardFound) { doReturn(Futures.successful(newPrimaryShardInfo(shardActorRef))). when(mockActorContext).findPrimaryShardAsync(eq(DefaultShardStrategy.DEFAULT_SHARD)); + doReturn(Futures.successful(newPrimaryShardInfo(shardActorRef))). + when(mockActorContext).findPrimaryShardAsync(eq("cars")); + } else { doReturn(Futures.failed(new Exception("not found"))) .when(mockActorContext).findPrimaryShardAsync(eq(DefaultShardStrategy.DEFAULT_SHARD)); } String actorPath = "akka.tcp://system@127.0.0.1:2550/user/tx-actor"; - CreateTransactionReply createTransactionReply = CreateTransactionReply.newBuilder(). - setTransactionId("txn-1").setTransactionActorPath(actorPath). - setMessageVersion(DataStoreVersions.CURRENT_VERSION).build(); - doReturn(Futures.successful(createTransactionReply)).when(mockActorContext). - executeOperationAsync(eq(actorSystem.actorSelection(shardActorRef.path())), - eqCreateTransaction(memberName, READ_WRITE)); + doReturn(incompleteFuture()).when(mockActorContext). + executeOperationAsync(eq(actorSystem.actorSelection(shardActorRef.path())), + eqCreateTransaction(memberName, READ_WRITE), any(Timeout.class)); doReturn(true).when(mockActorContext).isPathLocal(actorPath); @@ -843,9 +864,9 @@ public class TransactionProxyTest extends AbstractTransactionProxyTest { long end = System.nanoTime(); - long expected = TimeUnit.SECONDS.toNanos(mockActorContext.getDatastoreContext().getOperationTimeoutInSeconds()); Assert.assertTrue(String.format("Expected elapsed time: %s. Actual: %s", - expected, (end-start)), (end - start) > expected); + expectedCompletionTime, (end-start)), + ((end - start) > expectedCompletionTime) && ((end - start) < expectedCompletionTime*2)); } @@ -857,8 +878,6 @@ public class TransactionProxyTest extends AbstractTransactionProxyTest { ActorSystem actorSystem = getSystem(); ActorRef shardActorRef = actorSystem.actorOf(Props.create(DoNothingActor.class)); - doReturn(1).when(mockActorContext).getTransactionOutstandingOperationLimit(); - doReturn(actorSystem.actorSelection(shardActorRef.path())). when(mockActorContext).actorSelection(shardActorRef.path().toString()); @@ -880,7 +899,7 @@ public class TransactionProxyTest extends AbstractTransactionProxyTest { doReturn(Futures.successful(createTransactionReply)).when(mockActorContext). executeOperationAsync(eq(actorSystem.actorSelection(shardActorRef.path())), - eqCreateTransaction(memberName, READ_WRITE)); + eqCreateTransaction(memberName, READ_WRITE), any(Timeout.class)); doReturn(true).when(mockActorContext).isPathLocal(anyString()); @@ -892,7 +911,7 @@ public class TransactionProxyTest extends AbstractTransactionProxyTest { long end = System.nanoTime(); - long expected = TimeUnit.SECONDS.toNanos(mockActorContext.getDatastoreContext().getOperationTimeoutInSeconds()); + long expected = TimeUnit.MILLISECONDS.toNanos(mockActorContext.getDatastoreContext().getOperationTimeoutInMillis()); Assert.assertTrue(String.format("Expected elapsed time: %s. Actual: %s", expected, (end-start)), (end - start) <= expected); } @@ -901,8 +920,6 @@ public class TransactionProxyTest extends AbstractTransactionProxyTest { ActorSystem actorSystem = getSystem(); ActorRef shardActorRef = actorSystem.actorOf(Props.create(DoNothingActor.class)); - doReturn(1).when(mockActorContext).getTransactionOutstandingOperationLimit(); - doReturn(actorSystem.actorSelection(shardActorRef.path())). when(mockActorContext).actorSelection(shardActorRef.path().toString()); @@ -917,12 +934,12 @@ public class TransactionProxyTest extends AbstractTransactionProxyTest { long end = System.nanoTime(); - long expected = TimeUnit.SECONDS.toNanos(mockActorContext.getDatastoreContext().getOperationTimeoutInSeconds()); + long expected = TimeUnit.MILLISECONDS.toNanos(mockActorContext.getDatastoreContext().getOperationTimeoutInMillis()); Assert.assertTrue(String.format("Expected elapsed time: %s. Actual: %s", expected, (end-start)), (end - start) <= expected); } - private Optional createDataTree(){ + private static Optional createDataTree(){ DataTree dataTree = mock(DataTree.class); Optional dataTreeOptional = Optional.of(dataTree); DataTreeSnapshot dataTreeSnapshot = mock(DataTreeSnapshot.class); @@ -934,7 +951,7 @@ public class TransactionProxyTest extends AbstractTransactionProxyTest { return dataTreeOptional; } - private Optional createDataTree(NormalizedNode readResponse){ + private static Optional createDataTree(NormalizedNode readResponse){ DataTree dataTree = mock(DataTree.class); Optional dataTreeOptional = Optional.of(dataTree); DataTreeSnapshot dataTreeSnapshot = mock(DataTreeSnapshot.class); @@ -950,7 +967,6 @@ public class TransactionProxyTest extends AbstractTransactionProxyTest { @Test public void testWriteCompletionForLocalShard(){ - dataStoreContextBuilder.shardBatchedModificationCount(1); completeOperationLocal(new TransactionProxyOperation() { @Override public void run(TransactionProxy transactionProxy) { @@ -966,7 +982,6 @@ public class TransactionProxyTest extends AbstractTransactionProxyTest { @Test public void testWriteThrottlingWhenShardFound(){ - dataStoreContextBuilder.shardBatchedModificationCount(1); throttleOperation(new TransactionProxyOperation() { @Override public void run(TransactionProxy transactionProxy) { @@ -984,7 +999,6 @@ public class TransactionProxyTest extends AbstractTransactionProxyTest { @Test public void testWriteThrottlingWhenShardNotFound(){ // Confirm that there is no throttling when the Shard is not found - dataStoreContextBuilder.shardBatchedModificationCount(1); completeOperation(new TransactionProxyOperation() { @Override public void run(TransactionProxy transactionProxy) { @@ -1003,7 +1017,6 @@ public class TransactionProxyTest extends AbstractTransactionProxyTest { @Test public void testWriteCompletion(){ - dataStoreContextBuilder.shardBatchedModificationCount(1); completeOperation(new TransactionProxyOperation() { @Override public void run(TransactionProxy transactionProxy) { @@ -1020,7 +1033,6 @@ public class TransactionProxyTest extends AbstractTransactionProxyTest { @Test public void testMergeThrottlingWhenShardFound(){ - dataStoreContextBuilder.shardBatchedModificationCount(1); throttleOperation(new TransactionProxyOperation() { @Override public void run(TransactionProxy transactionProxy) { @@ -1037,7 +1049,6 @@ public class TransactionProxyTest extends AbstractTransactionProxyTest { @Test public void testMergeThrottlingWhenShardNotFound(){ - dataStoreContextBuilder.shardBatchedModificationCount(1); completeOperation(new TransactionProxyOperation() { @Override public void run(TransactionProxy transactionProxy) { @@ -1054,7 +1065,6 @@ public class TransactionProxyTest extends AbstractTransactionProxyTest { @Test public void testMergeCompletion(){ - dataStoreContextBuilder.shardBatchedModificationCount(1); completeOperation(new TransactionProxyOperation() { @Override public void run(TransactionProxy transactionProxy) { @@ -1072,7 +1082,6 @@ public class TransactionProxyTest extends AbstractTransactionProxyTest { @Test public void testMergeCompletionForLocalShard(){ - dataStoreContextBuilder.shardBatchedModificationCount(1); completeOperationLocal(new TransactionProxyOperation() { @Override public void run(TransactionProxy transactionProxy) { @@ -1120,7 +1129,6 @@ public class TransactionProxyTest extends AbstractTransactionProxyTest { @Test public void testDeleteCompletionForLocalShard(){ - dataStoreContextBuilder.shardBatchedModificationCount(1); completeOperationLocal(new TransactionProxyOperation() { @Override public void run(TransactionProxy transactionProxy) { @@ -1135,7 +1143,6 @@ public class TransactionProxyTest extends AbstractTransactionProxyTest { @Test public void testDeleteCompletion(){ - dataStoreContextBuilder.shardBatchedModificationCount(1); completeOperation(new TransactionProxyOperation() { @Override public void run(TransactionProxy transactionProxy) { @@ -1312,9 +1319,6 @@ public class TransactionProxyTest extends AbstractTransactionProxyTest { expectBatchedModifications(1); - doReturn(incompleteFuture()).when(mockActorContext).executeOperationAsync( - any(ActorSelection.class), any(ReadyTransaction.class)); - transactionProxy.write(TestModel.TEST_PATH, nodeToWrite); transactionProxy.ready(); @@ -1324,7 +1328,6 @@ public class TransactionProxyTest extends AbstractTransactionProxyTest { @Test public void testReadyThrottlingWithTwoTransactionContexts(){ - throttleOperation(new TransactionProxyOperation() { @Override public void run(TransactionProxy transactionProxy) { @@ -1338,11 +1341,13 @@ public class TransactionProxyTest extends AbstractTransactionProxyTest { transactionProxy.write(TestModel.TEST_PATH, nodeToWrite); - transactionProxy.write(TestModel.TEST_PATH, carsNode); + // Trying to write to Cars will cause another transaction context to get created + transactionProxy.write(CarsModel.BASE_PATH, carsNode); + // Now ready should block for both transaction contexts transactionProxy.ready(); } - }, 2, true); + }, 1, true, TimeUnit.MILLISECONDS.toNanos(mockActorContext.getDatastoreContext().getOperationTimeoutInMillis()) * 2); } private void testModificationOperationBatching(TransactionType type) throws Exception { @@ -1524,8 +1529,6 @@ public class TransactionProxyTest extends AbstractTransactionProxyTest { doReturn(memberName).when(mockActorContext).getCurrentMemberName(); - doReturn(10).when(mockActorContext).getTransactionOutstandingOperationLimit(); - doReturn(getSystem().dispatchers().defaultGlobalDispatcher()).when(mockActorContext).getClientDispatcher(); TransactionProxy transactionProxy = new TransactionProxy(mockComponentFactory, READ_ONLY); @@ -1576,7 +1579,7 @@ public class TransactionProxyTest extends AbstractTransactionProxyTest { doReturn(Futures.successful(createTransactionReply(txActorRef, DataStoreVersions.CURRENT_VERSION))).when(mockActorContext). executeOperationAsync(eq(actorSystem.actorSelection(shardActorRef.path())), - eqCreateTransaction(memberName, TransactionType.READ_ONLY)); + eqCreateTransaction(memberName, TransactionType.READ_ONLY), any(Timeout.class)); doReturn(readSerializedDataReply(expectedNode)).when(mockActorContext).executeOperationAsync( eq(actorSelection(txActorRef)), eqSerializedReadData(YangInstanceIdentifier.builder().build()));