2 * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.controller.cluster.databroker.actors.dds;
10 import static org.mockito.Matchers.any;
11 import static org.mockito.Mockito.doAnswer;
12 import static org.mockito.Mockito.mock;
13 import static org.mockito.Mockito.verify;
14 import static org.opendaylight.controller.cluster.databroker.actors.dds.TestUtils.assertFutureEquals;
16 import akka.testkit.TestProbe;
17 import java.util.function.Consumer;
18 import org.junit.Assert;
19 import org.junit.Test;
20 import org.mockito.ArgumentCaptor;
21 import org.mockito.invocation.InvocationOnMock;
22 import org.mockito.stubbing.Answer;
23 import org.opendaylight.controller.cluster.access.commands.AbortLocalTransactionRequest;
24 import org.opendaylight.controller.cluster.access.commands.CommitLocalTransactionRequest;
25 import org.opendaylight.controller.cluster.access.commands.ExistsTransactionRequest;
26 import org.opendaylight.controller.cluster.access.commands.ExistsTransactionSuccess;
27 import org.opendaylight.controller.cluster.access.commands.ModifyTransactionRequest;
28 import org.opendaylight.controller.cluster.access.commands.PersistenceProtocol;
29 import org.opendaylight.controller.cluster.access.commands.ReadTransactionRequest;
30 import org.opendaylight.controller.cluster.access.commands.ReadTransactionSuccess;
31 import org.opendaylight.controller.cluster.access.commands.TransactionPurgeRequest;
32 import org.opendaylight.controller.cluster.access.commands.TransactionRequest;
33 import org.opendaylight.controller.cluster.access.concepts.Response;
34 import org.opendaylight.yangtools.yang.data.api.schema.tree.CursorAwareDataTreeModification;
35 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModificationCursor;
37 public abstract class LocalProxyTransactionTest<T extends LocalProxyTransaction>
38 extends AbstractProxyTransactionTest<T> {
42 public void testExists() throws Exception {
43 assertFutureEquals(true, transaction.exists(PATH_1));
44 assertFutureEquals(false, transaction.exists(PATH_3));
49 public void testRead() throws Exception {
50 assertFutureEquals(com.google.common.base.Optional.of(DATA_1), transaction.read(PATH_1));
51 assertFutureEquals(com.google.common.base.Optional.absent(), transaction.read(PATH_3));
55 public void testDoAbort() throws Exception {
56 transaction.doAbort();
57 getTester().expectTransactionRequest(AbortLocalTransactionRequest.class);
61 public void testHandleForwardedRemoteReadRequest() throws Exception {
62 final TestProbe probe = createProbe();
63 final ReadTransactionRequest request =
64 new ReadTransactionRequest(TRANSACTION_ID, 0L, probe.ref(), PATH_1, true);
65 final Consumer<Response<?, ?>> callback = createCallbackMock();
66 transaction.handleForwardedRemoteRequest(request, callback);
67 final ArgumentCaptor<Response> captor = ArgumentCaptor.forClass(Response.class);
68 verify(callback).accept(captor.capture());
69 final Response value = captor.getValue();
70 Assert.assertTrue(value instanceof ReadTransactionSuccess);
71 final ReadTransactionSuccess success = (ReadTransactionSuccess) value;
72 Assert.assertTrue(success.getData().isPresent());
73 Assert.assertEquals(DATA_1, success.getData().get());
77 public void testHandleForwardedRemoteExistsRequest() throws Exception {
78 final TestProbe probe = createProbe();
79 final ExistsTransactionRequest request =
80 new ExistsTransactionRequest(TRANSACTION_ID, 0L, probe.ref(), PATH_1, true);
81 final Consumer<Response<?, ?>> callback = createCallbackMock();
82 transaction.handleForwardedRemoteRequest(request, callback);
83 final ArgumentCaptor<Response> captor = ArgumentCaptor.forClass(Response.class);
84 verify(callback).accept(captor.capture());
85 final Response value = captor.getValue();
86 Assert.assertTrue(value instanceof ExistsTransactionSuccess);
87 final ExistsTransactionSuccess success = (ExistsTransactionSuccess) value;
88 Assert.assertTrue(success.getExists());
92 public void testHandleForwardedRemotePurgeRequest() throws Exception {
93 final TestProbe probe = createProbe();
94 final TransactionPurgeRequest request =
95 new TransactionPurgeRequest(TRANSACTION_ID, 0L, probe.ref());
96 testHandleForwardedRemoteRequest(request);
101 public void testForwardToRemoteAbort() throws Exception {
102 final TestProbe probe = createProbe();
103 final AbortLocalTransactionRequest request = new AbortLocalTransactionRequest(TRANSACTION_ID, probe.ref());
104 final ModifyTransactionRequest modifyRequest = testForwardToRemote(request, ModifyTransactionRequest.class);
105 Assert.assertTrue(modifyRequest.getPersistenceProtocol().isPresent());
106 Assert.assertEquals(PersistenceProtocol.ABORT, modifyRequest.getPersistenceProtocol().get());
111 public void testForwardToRemoteCommit() throws Exception {
112 final TestProbe probe = createProbe();
113 final CursorAwareDataTreeModification modification = mock(CursorAwareDataTreeModification.class);
114 final CommitLocalTransactionRequest request =
115 new CommitLocalTransactionRequest(TRANSACTION_ID, 0L, probe.ref(), modification, true);
116 doAnswer(this::applyToCursorAnswer).when(modification).applyToCursor(any());
117 final ModifyTransactionRequest modifyRequest = testForwardToRemote(request, ModifyTransactionRequest.class);
118 verify(modification).applyToCursor(any());
119 Assert.assertTrue(modifyRequest.getPersistenceProtocol().isPresent());
120 Assert.assertEquals(PersistenceProtocol.THREE_PHASE, modifyRequest.getPersistenceProtocol().get());
121 checkModifications(modifyRequest);
125 public void testForwardToLocalAbort() throws Exception {
126 final TestProbe probe = createProbe();
127 final AbortLocalTransactionRequest request = new AbortLocalTransactionRequest(TRANSACTION_ID, probe.ref());
128 testForwardToLocal(request, AbortLocalTransactionRequest.class);
132 public void testForwardToLocalPurge() throws Exception {
133 final TestProbe probe = createProbe();
134 final TransactionPurgeRequest request = new TransactionPurgeRequest(TRANSACTION_ID, 0L, probe.ref());
135 testForwardToLocal(request, TransactionPurgeRequest.class);
138 protected <T extends TransactionRequest> T testForwardToLocal(final TransactionRequest toForward,
139 final Class<T> expectedMessageClass) {
140 final Consumer<Response<?, ?>> callback = createCallbackMock();
141 final TransactionTester<LocalReadWriteProxyTransaction> transactionTester = createLocalProxy();
142 final LocalReadWriteProxyTransaction successor = transactionTester.getTransaction();
143 transaction.forwardToLocal(successor, toForward, callback);
144 return transactionTester.expectTransactionRequest(expectedMessageClass);
148 * To emulate side effect of void method.
149 * {@link CursorAwareDataTreeModification#applyToCursor(DataTreeModificationCursor)}
151 * @param invocation invocation
152 * @return void - always null
154 protected Answer applyToCursorAnswer(final InvocationOnMock invocation) {
155 final DataTreeModificationCursor cursor =
156 invocation.getArgumentAt(0, DataTreeModificationCursor.class);
157 cursor.write(PATH_1.getLastPathArgument(), DATA_1);
158 cursor.merge(PATH_2.getLastPathArgument(), DATA_2);
159 cursor.delete(PATH_3.getLastPathArgument());