2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2018 AT&T Intellectual Property. All rights
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
22 package org.onap.ccsdk.sli.plugins.grtoolkit;
23 import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
24 import static com.github.tomakehurst.wiremock.client.WireMock.get;
25 import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
26 import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
27 import static org.junit.Assert.assertEquals;
28 import static org.junit.Assert.fail;
29 import static org.mockito.Mockito.mock;
30 import static org.mockito.Mockito.spy;
31 import static org.mockito.Mockito.when;
32 import com.github.tomakehurst.wiremock.junit.WireMockRule;
33 import com.google.common.util.concurrent.ListenableFuture;
34 import java.io.IOException;
35 import java.lang.reflect.InvocationTargetException;
36 import java.lang.reflect.Method;
37 import java.nio.file.Files;
38 import java.nio.file.Paths;
39 import java.sql.SQLException;
40 import java.util.ArrayList;
41 import java.util.Arrays;
42 import java.util.Properties;
43 import java.util.concurrent.ExecutionException;
44 import java.util.stream.Collectors;
45 import java.util.stream.Stream;
46 import org.junit.Before;
47 import org.junit.Rule;
48 import org.junit.Test;
49 import org.onap.ccsdk.sli.core.dblib.DBLibConnection;
50 import org.onap.ccsdk.sli.core.dblib.DbLibService;
51 import org.onap.ccsdk.sli.plugins.grtoolkit.data.ClusterActor;
52 import org.opendaylight.controller.cluster.access.concepts.MemberName;
53 import org.opendaylight.controller.cluster.datastore.DistributedDataStoreInterface;
54 import org.opendaylight.controller.cluster.datastore.utils.ActorUtils;
55 import org.opendaylight.mdsal.binding.api.DataBroker;
56 import org.opendaylight.mdsal.binding.api.NotificationPublishService;
57 import org.opendaylight.mdsal.binding.api.RpcProviderService;
58 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.plugins.gr.toolkit.rev180926.AdminHealthOutput;
59 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.plugins.gr.toolkit.rev180926.ClusterHealthOutput;
60 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.plugins.gr.toolkit.rev180926.DatabaseHealthOutput;
61 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.plugins.gr.toolkit.rev180926.FailoverOutput;
62 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.plugins.gr.toolkit.rev180926.HaltAkkaTrafficInputBuilder;
63 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.plugins.gr.toolkit.rev180926.HaltAkkaTrafficOutput;
64 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.plugins.gr.toolkit.rev180926.ResumeAkkaTrafficInputBuilder;
65 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.plugins.gr.toolkit.rev180926.ResumeAkkaTrafficOutput;
66 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.plugins.gr.toolkit.rev180926.SiteHealthOutput;
67 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.plugins.gr.toolkit.rev180926.SiteIdentifierOutput;
68 import org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.plugins.gr.toolkit.rev180926.resume.akka.traffic.input.NodeInfoBuilder;
69 import org.opendaylight.yangtools.yang.common.RpcResult;
71 public class GrToolkitProviderTest {
72 GrToolkitProvider provider;
73 GrToolkitProvider providerSpy;
74 DataBroker dataBroker;
75 NotificationPublishService notificationProviderService;
76 RpcProviderService rpcProviderRegistry;
77 DistributedDataStoreInterface configDatastore;
78 DbLibService dbLibService;
79 DBLibConnection connection;
80 Properties properties;
83 public WireMockRule wireMockRule = new WireMockRule(9999);
87 dataBroker = mock(DataBroker.class);
88 notificationProviderService = mock(NotificationPublishService.class);
89 rpcProviderRegistry = mock(RpcProviderService.class);
90 configDatastore = mock(DistributedDataStoreInterface.class);
91 dbLibService = mock(DbLibService.class);
92 connection = mock(DBLibConnection.class);
94 ActorUtils actorContext = mock(ActorUtils.class);
95 MemberName memberName = MemberName.forName("Test");
97 when(actorContext.getCurrentMemberName()).thenReturn(memberName);
98 when(configDatastore.getActorUtils()).thenReturn(actorContext);
101 when(connection.isReadOnly()).thenReturn(false);
102 when(connection.isClosed()).thenReturn(false);
103 when(dbLibService.isActive()).thenReturn(true);
104 when(dbLibService.getConnection()).thenReturn(connection);
105 } catch(SQLException e) {
109 provider = new GrToolkitProvider(dataBroker, notificationProviderService,
110 rpcProviderRegistry, configDatastore, dbLibService);
111 providerSpy = spy(provider);
116 public void closeTest() {
119 } catch(Exception e) {
120 // Exception expected
125 public void onDataTreeChangedTest() {
126 provider.onDataTreeChanged(new ArrayList());
127 // onDataTreeChanged is an empty stub
130 private void stubController() {
131 String clusterBody = null;
132 String shardManagerBody = null;
133 String shardDefaultBody = null;
134 String shardOperationalBody = null;
135 try(Stream<String> stream = Files.lines(Paths.get("src/test/resources/three/cluster.json"))) {
136 clusterBody = stream.collect(Collectors.joining());
137 } catch(IOException e) {
140 try(Stream<String> stream = Files.lines(Paths.get("src/test/resources/three/shard-manager.json"))) {
141 shardManagerBody = stream.collect(Collectors.joining());
142 } catch(IOException e) {
145 try(Stream<String> stream = Files.lines(Paths.get("src/test/resources/three/default-config.json"))) {
146 shardDefaultBody = stream.collect(Collectors.joining());
147 } catch(IOException e) {
150 try(Stream<String> stream = Files.lines(Paths.get("src/test/resources/three/default-operational.json"))) {
151 shardOperationalBody = stream.collect(Collectors.joining());
152 } catch(IOException e) {
156 if(clusterBody == null || shardManagerBody == null || shardDefaultBody == null || shardOperationalBody == null) {
159 stubFor(get(urlEqualTo("/adm/healthcheck")).willReturn(aResponse().withStatus(200)));
160 stubFor(get(urlEqualTo("/jolokia/read/akka:type=Cluster")).willReturn(aResponse().withStatus(200).withBody(clusterBody)));
161 stubFor(get(urlEqualTo("/jolokia/read/org.opendaylight.controller:Category=ShardManager,name=shard-manager-config,type=DistributedConfigDatastore")).inScenario("testing").willReturn(aResponse().withStatus(200).withBody(shardManagerBody)).willSetStateTo("next"));
162 stubFor(get(urlEqualTo("/jolokia/read/org.opendaylight.controller:Category=Shards,name=member-1-shard-default-config,type=DistributedConfigDatastore")).inScenario("testing").willReturn(aResponse().withStatus(200).withBody(shardDefaultBody)).willSetStateTo("next"));
163 stubFor(get(urlEqualTo("/jolokia/read/org.opendaylight.controller:Category=Shards,name=member-1-shard-default-operational,type=DistributedOperationalDatastore")).willReturn(aResponse().withStatus(200).withBody(shardOperationalBody)));
167 public void clusterHealthTest() {
168 ListenableFuture<RpcResult<ClusterHealthOutput>> result = provider.clusterHealth(null);
170 assertEquals("0", result.get().getResult().getStatus());
171 } catch(InterruptedException | ExecutionException e) {
177 public void siteHealthTest() {
178 ListenableFuture<RpcResult<SiteHealthOutput>> result = provider.siteHealth(null);
180 assertEquals("200", result.get().getResult().getStatus());
181 } catch(InterruptedException | ExecutionException e) {
187 public void databaseHealthTest() {
188 ListenableFuture<RpcResult<DatabaseHealthOutput>> result = provider.databaseHealth(null);
190 assertEquals("200", result.get().getResult().getStatus());
191 } catch(InterruptedException | ExecutionException e) {
197 public void databaseHealthWhenROTest() {
199 when(connection.isReadOnly()).thenReturn(true);
200 } catch(SQLException e) {
203 ListenableFuture<RpcResult<DatabaseHealthOutput>> result = provider.databaseHealth(null);
205 assertEquals("500", result.get().getResult().getStatus());
206 } catch(InterruptedException | ExecutionException e) {
212 public void databaseHealthWhenExceptionTest() {
214 when(connection.isReadOnly()).thenThrow(new SQLException());
215 } catch(SQLException e) {
218 ListenableFuture<RpcResult<DatabaseHealthOutput>> result = provider.databaseHealth(null);
220 assertEquals("500", result.get().getResult().getStatus());
221 } catch(InterruptedException | ExecutionException e) {
227 public void adminHealthTest() {
228 ListenableFuture<RpcResult<AdminHealthOutput>> result = provider.adminHealth(null);
230 assertEquals("200", result.get().getResult().getStatus());
231 } catch(InterruptedException | ExecutionException e) {
237 public void siteIdentifierTest() {
238 ListenableFuture<RpcResult<SiteIdentifierOutput>> result = provider.siteIdentifier(null);
240 assertEquals("200", result.get().getResult().getStatus());
241 } catch(InterruptedException | ExecutionException e) {
247 public void failoverTest() {
248 ListenableFuture<RpcResult<FailoverOutput>> result = provider.failover(null);
250 assertEquals("400", result.get().getResult().getStatus());
251 } catch(InterruptedException | ExecutionException e) {
257 public void haltTrafficTest() {
258 HaltAkkaTrafficInputBuilder builder = new HaltAkkaTrafficInputBuilder();
259 builder.setNodeInfo(Arrays.asList(
260 new org.opendaylight.yang.gen.v1.org.onap.ccsdk.sli.plugins.gr.toolkit.rev180926.halt.akka.traffic.
261 input.NodeInfoBuilder().build()));
262 ListenableFuture<RpcResult<HaltAkkaTrafficOutput>> result = provider.haltAkkaTraffic(builder.build());
264 assertEquals("200", result.get().getResult().getStatus());
265 } catch (InterruptedException | ExecutionException e) {
271 public void resumeTrafficTest() {
272 ResumeAkkaTrafficInputBuilder builder = new ResumeAkkaTrafficInputBuilder();
273 builder.setNodeInfo(Arrays.asList(new NodeInfoBuilder().build()));
274 ListenableFuture<RpcResult<ResumeAkkaTrafficOutput>> result = provider.resumeAkkaTraffic(builder.build());
276 assertEquals("200", result.get().getResult().getStatus());
277 } catch(InterruptedException | ExecutionException e) {
283 public void executeCommandTest() {
285 Method method = provider.getClass().getDeclaredMethod("executeCommand", String.class);
286 method.setAccessible(true);
287 method.invoke(provider, "ls");
288 } catch(NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
294 public void isolateSiteFromClusterTest() {
296 ClusterActor actor = new ClusterActor();
297 actor.setNode("some-node");
298 actor.setAkkaPort("2550");
299 ArrayList<ClusterActor> activeList = new ArrayList<>();
300 activeList.add(actor);
301 ArrayList<ClusterActor> standbyList = new ArrayList<>();
302 standbyList.add(actor);
303 Method method = provider.getClass().getDeclaredMethod("isolateSiteFromCluster", ArrayList.class, ArrayList.class, String.class);
304 method.setAccessible(true);
305 method.invoke(provider, activeList, standbyList, "80");
306 } catch(NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
312 public void downUnreachableNodesTest() {
314 ClusterActor actor = new ClusterActor();
315 actor.setNode("some-node");
316 actor.setAkkaPort("2550");
317 ArrayList<ClusterActor> activeList = new ArrayList<>();
318 activeList.add(actor);
319 ArrayList<ClusterActor> standbyList = new ArrayList<>();
320 standbyList.add(actor);
321 Method method = provider.getClass().getDeclaredMethod("downUnreachableNodes", ArrayList.class, ArrayList.class, String.class);
322 method.setAccessible(true);
323 method.invoke(provider, activeList, standbyList, "80");
324 } catch(NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
330 public void backupMdSalTest() {
332 ClusterActor actor = new ClusterActor();
333 actor.setNode("some-Node");
334 actor.setAkkaPort("2550");
335 ArrayList<ClusterActor> activeList = new ArrayList<>();
336 activeList.add(actor);
337 Method method = provider.getClass().getDeclaredMethod("backupMdSal", ArrayList.class, String.class);
338 method.setAccessible(true);
339 method.invoke(provider, activeList, "80");
340 } catch(NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {