X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-distributed-datastore%2Fsrc%2Ftest%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcluster%2Fdatastore%2Fcompat%2FPreBoronTransactionProxyTest.java;h=2ca4bcab4a2db3c2f77ed9faa91c21de29189e3a;hb=6a5a8670a47f8989998390b6bab6718c1a7857b5;hp=4189912d5b4240e106396e621a0055647754a4d5;hpb=11e722671c6dc194761471038a4e3ca5f7fd8970;p=controller.git diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/compat/PreBoronTransactionProxyTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/compat/PreBoronTransactionProxyTest.java index 4189912d5b..2ca4bcab4a 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/compat/PreBoronTransactionProxyTest.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/compat/PreBoronTransactionProxyTest.java @@ -7,42 +7,160 @@ */ package org.opendaylight.controller.cluster.datastore.compat; +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.argThat; import static org.mockito.Matchers.eq; import static org.mockito.Matchers.isA; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.verify; import static org.opendaylight.controller.cluster.datastore.TransactionType.READ_WRITE; import akka.actor.ActorRef; +import akka.actor.ActorSystem; +import akka.actor.Props; +import akka.dispatch.Futures; +import akka.util.Timeout; +import com.google.common.base.Optional; +import java.util.concurrent.TimeUnit; import org.junit.Test; +import org.mockito.ArgumentMatcher; import org.opendaylight.controller.cluster.datastore.AbstractTransactionProxyTest; import org.opendaylight.controller.cluster.datastore.DataStoreVersions; import org.opendaylight.controller.cluster.datastore.TransactionProxy; +import org.opendaylight.controller.cluster.datastore.TransactionType; +import org.opendaylight.controller.cluster.datastore.messages.CreateTransaction; +import org.opendaylight.controller.cluster.datastore.messages.DataExists; +import org.opendaylight.controller.cluster.datastore.messages.ReadData; import org.opendaylight.controller.cluster.datastore.shardstrategy.DefaultShardStrategy; +import org.opendaylight.controller.cluster.raft.utils.DoNothingActor; import org.opendaylight.controller.md.cluster.datastore.model.TestModel; import org.opendaylight.controller.protobuff.messages.transaction.ShardTransactionMessages; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes; /** * TransactionProxy unit tests for backwards compatibility with pre-Boron versions. * * @author Thomas Pantelis */ +@SuppressWarnings("resource") public class PreBoronTransactionProxyTest extends AbstractTransactionProxyTest { + private CreateTransaction eqLegacyCreateTransaction(final TransactionType type) { + ArgumentMatcher matcher = new ArgumentMatcher() { + @Override + public boolean matches(Object argument) { + if(ShardTransactionMessages.CreateTransaction.class.equals(argument.getClass())) { + CreateTransaction obj = CreateTransaction.fromSerializable(argument); + return obj.getTransactionId().startsWith(memberName) && + obj.getTransactionType() == type.ordinal(); + } + + return false; + } + }; + + return argThat(matcher); + } + + private ShardTransactionMessages.CreateTransactionReply legacyCreateTransactionReply(ActorRef actorRef, + int transactionVersion){ + return ShardTransactionMessages.CreateTransactionReply.newBuilder() + .setTransactionActorPath(actorRef.path().toString()) + .setTransactionId("txn-1") + .setMessageVersion(transactionVersion) + .build(); + } + + private ReadData eqLegacySerializedReadData(final YangInstanceIdentifier path) { + ArgumentMatcher matcher = new ArgumentMatcher() { + @Override + public boolean matches(Object argument) { + return ShardTransactionMessages.ReadData.class.equals(argument.getClass()) && + ReadData.fromSerializable(argument).getPath().equals(path); + } + }; + + return argThat(matcher); + } + + private DataExists eqLegacySerializedDataExists() { + ArgumentMatcher matcher = new ArgumentMatcher() { + @Override + public boolean matches(Object argument) { + return ShardTransactionMessages.DataExists.class.equals(argument.getClass()) && + DataExists.fromSerializable(argument).getPath().equals(TestModel.TEST_PATH); + } + }; + + return argThat(matcher); + } + + private ActorRef setupPreBoronActorContextWithInitialCreateTransaction(ActorSystem actorSystem, + TransactionType type) { + ActorRef shardActorRef = setupActorContextWithoutInitialCreateTransaction(actorSystem, + DefaultShardStrategy.DEFAULT_SHARD, DataStoreVersions.LITHIUM_VERSION); + + ActorRef txActorRef; + if(type == TransactionType.WRITE_ONLY) { + txActorRef = shardActorRef; + } else { + txActorRef = actorSystem.actorOf(Props.create(DoNothingActor.class)); + doReturn(actorSystem.actorSelection(txActorRef.path())). + when(mockActorContext).actorSelection(txActorRef.path().toString()); + + doReturn(Futures.successful(legacyCreateTransactionReply(txActorRef, DataStoreVersions.LITHIUM_VERSION))) + .when(mockActorContext).executeOperationAsync(eq(actorSystem.actorSelection(shardActorRef.path())), + eqLegacyCreateTransaction(type), any(Timeout.class)); + } + + return txActorRef; + } + @Test public void testClose() throws Exception{ - ActorRef actorRef = setupActorContextWithInitialCreateTransaction(getSystem(), READ_WRITE, - DataStoreVersions.LITHIUM_VERSION, DefaultShardStrategy.DEFAULT_SHARD); + ActorRef actorRef = setupPreBoronActorContextWithInitialCreateTransaction(getSystem(), READ_WRITE); - doReturn(readDataReply(null)).when(mockActorContext).executeOperationAsync( - eq(actorSelection(actorRef)), eqSerializedReadData()); + expectBatchedModifications(actorRef, 1); TransactionProxy transactionProxy = new TransactionProxy(mockComponentFactory, READ_WRITE); - transactionProxy.read(TestModel.TEST_PATH); + transactionProxy.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME)); transactionProxy.close(); verify(mockActorContext).sendOperationAsync( eq(actorSelection(actorRef)), isA(ShardTransactionMessages.CloseTransaction.class)); } + + @Test + public void testRead() throws Exception{ + ActorRef actorRef = setupPreBoronActorContextWithInitialCreateTransaction(getSystem(), READ_WRITE); + + NormalizedNode expectedNode = ImmutableNodes.containerNode(TestModel.TEST_QNAME); + doReturn(readDataReply(expectedNode)).when(mockActorContext).executeOperationAsync( + eq(actorSelection(actorRef)), eqLegacySerializedReadData(TestModel.TEST_PATH)); + + TransactionProxy transactionProxy = new TransactionProxy(mockComponentFactory, READ_WRITE); + + Optional> readOptional = transactionProxy.read( + TestModel.TEST_PATH).get(5, TimeUnit.SECONDS); + + assertEquals("NormalizedNode isPresent", true, readOptional.isPresent()); + assertEquals("Response NormalizedNode", expectedNode, readOptional.get()); + } + + @Test + public void testExists() throws Exception{ + ActorRef actorRef = setupPreBoronActorContextWithInitialCreateTransaction(getSystem(), READ_WRITE); + + doReturn(dataExistsReply(true)).when(mockActorContext).executeOperationAsync( + eq(actorSelection(actorRef)), eqLegacySerializedDataExists()); + + TransactionProxy transactionProxy = new TransactionProxy(mockComponentFactory, READ_WRITE); + + Boolean exists = transactionProxy.exists(TestModel.TEST_PATH).checkedGet(5, TimeUnit.SECONDS); + assertEquals("Exists response", true, exists); + } }