Improve DOMRpcRouterTest 40/97140/2
authorRobert Varga <robert.varga@pantheon.tech>
Wed, 11 Aug 2021 12:24:37 +0000 (14:24 +0200)
committerRobert Varga <nite@hq.sk>
Wed, 11 Aug 2021 13:43:27 +0000 (13:43 +0000)
We have a ton of untested functionality, add a few tests to increase
coverage.

Change-Id: I0885a9a2c1b8f5ca5a3b56b6c03ff0c7acd00563
Signed-off-by: Robert Varga <robert.varga@pantheon.tech>
(cherry picked from commit f55130715deea48b49c6f9a95438cb70d7f7a400)

dom/mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker/DOMRpcRouterTest.java
dom/mdsal-dom-broker/src/test/resources/actions.yang [new file with mode: 0644]

index 9c13dbf84e10650ef9a1cf2838199f1c4a918f1f..b9649b0571ed28f3edd9dca3f67c51affa8acc55 100644 (file)
@@ -7,6 +7,9 @@
  */
 package org.opendaylight.mdsal.dom.broker;
 
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
@@ -14,15 +17,60 @@ import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
 import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.RejectedExecutionException;
+import org.junit.BeforeClass;
 import org.junit.Test;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.dom.api.DOMActionImplementation;
+import org.opendaylight.mdsal.dom.api.DOMActionInstance;
+import org.opendaylight.mdsal.dom.api.DOMActionNotAvailableException;
+import org.opendaylight.mdsal.dom.api.DOMActionProviderService;
+import org.opendaylight.mdsal.dom.api.DOMActionResult;
+import org.opendaylight.mdsal.dom.api.DOMActionService;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
 import org.opendaylight.mdsal.dom.api.DOMRpcAvailabilityListener;
 import org.opendaylight.mdsal.dom.api.DOMRpcIdentifier;
 import org.opendaylight.mdsal.dom.api.DOMRpcProviderService;
 import org.opendaylight.mdsal.dom.broker.util.TestModel;
+import org.opendaylight.mdsal.dom.spi.SimpleDOMActionResult;
+import org.opendaylight.yangtools.concepts.ObjectRegistration;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
+import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
+import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
 
 public class DOMRpcRouterTest extends TestUtils {
+    private static final QName FOO = QName.create("actions", "foo");
+    private static final QName BAR = QName.create(FOO, "bar");
+    private static final QName BAZ = QName.create(FOO, "baz");
+    private static final QName INPUT = QName.create(FOO, "input");
+    private static final QName OUTPUT = QName.create(FOO, "output");
+
+    private static final Absolute BAZ_TYPE = Absolute.of(FOO, BAZ);
+    private static final YangInstanceIdentifier BAZ_PATH_BAD = YangInstanceIdentifier.create(
+        new NodeIdentifier(FOO), NodeIdentifierWithPredicates.of(FOO, BAR, "bad"));
+    private static final YangInstanceIdentifier BAZ_PATH_GOOD = YangInstanceIdentifier.create(
+        new NodeIdentifier(FOO), NodeIdentifierWithPredicates.of(FOO, BAR, "good"));
+
+    private static final DOMActionImplementation IMPL =
+        (type, path, input) -> Futures.immediateFuture(new SimpleDOMActionResult(
+            Builders.containerBuilder().withNodeIdentifier(new NodeIdentifier(OUTPUT)).build()));
+
+    private static EffectiveModelContext ACTIONS_CONTEXT;
+
+    @BeforeClass
+    public static void beforeClass() {
+        ACTIONS_CONTEXT = YangParserTestUtils.parseYangResource("/actions.yang");
+    }
 
     @Test
     public void registerRpcImplementation() {
@@ -87,4 +135,48 @@ public class DOMRpcRouterTest extends TestUtils {
         assertThrows(RejectedExecutionException.class, () -> svc.registerRpcImplementation(getTestRpcImplementation(),
             DOMRpcIdentifier.create(TestModel.TEST_QNAME, null)));
     }
+
+    @Test
+    public void testActionInstanceRouting() throws ExecutionException {
+        try (DOMRpcRouter rpcRouter = new DOMRpcRouter()) {
+            rpcRouter.onModelContextUpdated(ACTIONS_CONTEXT);
+
+            final DOMActionProviderService actionProvider = rpcRouter.getActionProviderService();
+            assertNotNull(actionProvider);
+            final DOMActionService actionConsumer = rpcRouter.getActionService();
+            assertNotNull(actionConsumer);
+
+            try (ObjectRegistration<?> reg = actionProvider.registerActionImplementation(IMPL,
+                DOMActionInstance.of(BAZ_TYPE, LogicalDatastoreType.OPERATIONAL, BAZ_PATH_GOOD))) {
+
+                assertAvailable(actionConsumer, BAZ_PATH_GOOD);
+                assertUnavailable(actionConsumer, BAZ_PATH_BAD);
+            }
+
+            assertUnavailable(actionConsumer, BAZ_PATH_BAD);
+            assertUnavailable(actionConsumer, BAZ_PATH_GOOD);
+        }
+    }
+
+    private static void assertAvailable(final DOMActionService actionService, final YangInstanceIdentifier path) {
+        final DOMActionResult result;
+        try {
+            result = Futures.getDone(invokeBaz(actionService, path));
+        } catch (ExecutionException e) {
+            throw new AssertionError("Unexpected invocation failure", e);
+        }
+        assertEquals(List.of(), result.getErrors());
+    }
+
+    private static void assertUnavailable(final DOMActionService actionService, final YangInstanceIdentifier path) {
+        final ListenableFuture<? extends DOMActionResult> future = invokeBaz(actionService, path);
+        final ExecutionException ex = assertThrows(ExecutionException.class, () -> Futures.getDone(future));
+        assertThat(ex.getCause(), instanceOf(DOMActionNotAvailableException.class));
+    }
+
+    private static ListenableFuture<? extends DOMActionResult> invokeBaz(final DOMActionService actionService,
+            final YangInstanceIdentifier path) {
+        return actionService.invokeAction(BAZ_TYPE, new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL, path),
+            Builders.containerBuilder().withNodeIdentifier(new NodeIdentifier(INPUT)).build());
+    }
 }
diff --git a/dom/mdsal-dom-broker/src/test/resources/actions.yang b/dom/mdsal-dom-broker/src/test/resources/actions.yang
new file mode 100644 (file)
index 0000000..654973d
--- /dev/null
@@ -0,0 +1,14 @@
+module actions {
+  yang-version 1.1;
+  namespace actions;
+  prefix actions;
+
+  list foo {
+    key bar;
+    leaf bar {
+      type string;
+    }
+
+    action baz;
+  }
+}