Bug 4564: Implement clustering backup-datastore RPC
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / test / java / org / opendaylight / controller / cluster / datastore / admin / ClusterAdminRpcServiceTest.java
1 /*
2  * Copyright (c) 2015 Brocade Communications Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.controller.cluster.datastore.admin;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertNotNull;
12 import static org.junit.Assert.assertTrue;
13 import akka.actor.ActorRef;
14 import akka.actor.ActorSystem;
15 import akka.actor.Address;
16 import akka.actor.AddressFromURIString;
17 import akka.actor.PoisonPill;
18 import akka.cluster.Cluster;
19 import akka.testkit.JavaTestKit;
20 import com.google.common.collect.ImmutableMap;
21 import com.google.common.collect.Sets;
22 import com.typesafe.config.ConfigFactory;
23 import java.io.File;
24 import java.io.FileInputStream;
25 import java.io.IOException;
26 import java.util.HashSet;
27 import java.util.List;
28 import java.util.Set;
29 import java.util.concurrent.TimeUnit;
30 import java.util.concurrent.TimeoutException;
31 import org.apache.commons.lang3.SerializationUtils;
32 import org.junit.After;
33 import org.junit.AfterClass;
34 import org.junit.BeforeClass;
35 import org.junit.Test;
36 import org.opendaylight.controller.cluster.datastore.DatastoreContext;
37 import org.opendaylight.controller.cluster.datastore.DistributedDataStore;
38 import org.opendaylight.controller.cluster.datastore.IntegrationTestKit;
39 import org.opendaylight.controller.cluster.datastore.messages.DatastoreSnapshot;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.md.sal.cluster.admin.rev151013.BackupDatastoreInputBuilder;
41 import org.opendaylight.yangtools.yang.common.RpcResult;
42
43 /**
44  * Unit tests for ClusterAdminRpcService.
45  *
46  * @author Thomas Pantelis
47  */
48 public class ClusterAdminRpcServiceTest {
49     private static ActorSystem system;
50
51     private final DatastoreContext.Builder datastoreContextBuilder = DatastoreContext.newBuilder();
52
53     private IntegrationTestKit kit;
54     private DistributedDataStore configDataStore;
55     private DistributedDataStore operDataStore;
56     private ClusterAdminRpcService service;
57
58     @BeforeClass
59     public static void setUpClass() throws IOException {
60         system = ActorSystem.create("cluster-test", ConfigFactory.load().getConfig("Member1"));
61         Address member1Address = AddressFromURIString.parse("akka.tcp://cluster-test@127.0.0.1:2558");
62         Cluster.get(system).join(member1Address);
63     }
64
65     @AfterClass
66     public static void tearDownClass() throws IOException {
67         JavaTestKit.shutdownActorSystem(system);
68         system = null;
69     }
70
71     @After
72     public void tearDown() {
73         if(kit != null) {
74             kit.cleanup(configDataStore);
75             kit.cleanup(operDataStore);
76         }
77     }
78
79     private void setup(String testName, String... shardNames) {
80         kit = new IntegrationTestKit(system, datastoreContextBuilder);
81
82         configDataStore = kit.setupDistributedDataStore(testName + "Config", "module-shards-member1.conf",
83                 true, shardNames);
84         operDataStore = kit.setupDistributedDataStore(testName + "Oper", "module-shards-member1.conf",
85                 true, shardNames);
86
87         service = new ClusterAdminRpcService(configDataStore, operDataStore);
88     }
89
90     @Test
91     public void testBackupDatastore() throws Exception {
92         setup("testBackupDatastore", "cars", "people");
93
94         String fileName = "target/testBackupDatastore";
95         new File(fileName).delete();
96
97         RpcResult<Void> rpcResult = service.backupDatastore(new BackupDatastoreInputBuilder().
98                 setFilePath(fileName).build()).get(5, TimeUnit.SECONDS);
99         assertEquals("isSuccessful", true, rpcResult.isSuccessful());
100
101         try(FileInputStream fis = new FileInputStream(fileName)) {
102             List<DatastoreSnapshot> snapshots = SerializationUtils.deserialize(fis);
103             assertEquals("DatastoreSnapshot size", 2, snapshots.size());
104
105             ImmutableMap<String, DatastoreSnapshot> map = ImmutableMap.of(snapshots.get(0).getType(), snapshots.get(0),
106                     snapshots.get(1).getType(), snapshots.get(1));
107             verifyDatastoreSnapshot(configDataStore.getActorContext().getDataStoreType(),
108                     map.get(configDataStore.getActorContext().getDataStoreType()), "cars", "people");
109         } finally {
110             new File(fileName).delete();
111         }
112
113         // Test failure by killing a shard.
114
115         configDataStore.getActorContext().getShardManager().tell(datastoreContextBuilder.
116                 shardInitializationTimeout(200, TimeUnit.MILLISECONDS).build(), ActorRef.noSender());
117
118         ActorRef carsShardActor = configDataStore.getActorContext().findLocalShard("cars").get();
119         kit.watch(carsShardActor);
120         carsShardActor.tell(PoisonPill.getInstance(), ActorRef.noSender());
121         kit.expectTerminated(carsShardActor);
122
123         rpcResult = service.backupDatastore(new BackupDatastoreInputBuilder().setFilePath(fileName).build()).
124                 get(5, TimeUnit.SECONDS);
125         assertEquals("isSuccessful", false, rpcResult.isSuccessful());
126         assertEquals("getErrors", 1, rpcResult.getErrors().size());
127         assertTrue("Expected error cause TimeoutException",
128                 rpcResult.getErrors().iterator().next().getCause() instanceof TimeoutException);
129     }
130
131     private void verifyDatastoreSnapshot(String type, DatastoreSnapshot datastoreSnapshot, String... expShardNames) {
132         assertNotNull("Missing DatastoreSnapshot for type " + type, datastoreSnapshot);
133         Set<String> shardNames = new HashSet<>();
134         for(DatastoreSnapshot.ShardSnapshot s: datastoreSnapshot.getShardSnapshots()) {
135             shardNames.add(s.getName());
136         }
137
138         assertEquals("DatastoreSnapshot shard names", Sets.newHashSet(expShardNames), shardNames);
139     }
140
141     @Test
142     public void testAddShardReplica() {
143         // TODO implement
144     }
145
146     @Test
147     public void testRemoveShardReplica() {
148         // TODO implement
149     }
150
151     @Test
152     public void testAddReplicasForAllShards() {
153         // TODO implement
154     }
155
156     @Test
157     public void testRemoveAllShardReplicas() {
158         // TODO implement
159     }
160
161     @Test
162     public void testConvertMembersToVotingForAllShards() {
163         // TODO implement
164     }
165
166     @Test
167     public void testConvertMembersToNonvotingForAllShards() {
168         // TODO implement
169     }
170 }