2 * Copyright (c) 2015 Brocade Communications Systems, Inc. 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.datastore;
10 import static org.junit.Assert.assertEquals;
11 import static org.opendaylight.controller.cluster.datastore.DatastoreContext.DEFAULT_HEARTBEAT_INTERVAL_IN_MILLIS;
12 import static org.opendaylight.controller.cluster.datastore.DatastoreContext.DEFAULT_OPERATION_TIMEOUT_IN_MS;
13 import static org.opendaylight.controller.cluster.datastore.DatastoreContext.DEFAULT_SHARD_INITIALIZATION_TIMEOUT;
14 import static org.opendaylight.controller.cluster.datastore.DatastoreContext.DEFAULT_SHARD_SNAPSHOT_DATA_THRESHOLD_PERCENTAGE;
15 import static org.opendaylight.controller.cluster.datastore.DatastoreContext.DEFAULT_SHARD_TRANSACTION_IDLE_TIMEOUT;
16 import static org.opendaylight.controller.cluster.datastore.DatastoreContext.DEFAULT_SHARD_TX_COMMIT_TIMEOUT_IN_SECONDS;
18 import java.util.HashMap;
19 import java.util.Hashtable;
21 import org.junit.Test;
22 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
23 import org.opendaylight.controller.md.sal.dom.store.impl.InMemoryDOMDataStoreConfigProperties;
26 * Unit tests for DatastoreContextIntrospector.
28 * @author Thomas Pantelis
30 public class DatastoreContextIntrospectorTest {
33 public void testUpdate() {
34 DatastoreContext context = DatastoreContext.newBuilder()
35 .logicalStoreType(LogicalDatastoreType.OPERATIONAL).build();
36 final DatastoreContextIntrospector introspector = new DatastoreContextIntrospector(context);
38 final Map<String, Object> properties = new HashMap<>();
39 properties.put("shard-transaction-idle-timeout-in-minutes", "31");
40 properties.put("operation-timeout-in-seconds", "26");
41 properties.put("shard-transaction-commit-timeout-in-seconds", "100");
42 properties.put("shard-journal-recovery-log-batch-size", "199");
43 properties.put("shard-snapshot-batch-count", "212");
44 properties.put("shard-heartbeat-interval-in-millis", "101");
45 properties.put("shard-transaction-commit-queue-capacity", "567");
46 properties.put("shard-initialization-timeout-in-seconds", "82");
47 properties.put("shard-leader-election-timeout-in-seconds", "66");
48 properties.put("shard-isolated-leader-check-interval-in-millis", "123");
49 properties.put("shard-snapshot-data-threshold-percentage", "100");
50 properties.put("shard-election-timeout-factor", "21");
51 properties.put("shard-batched-modification-count", "901");
52 properties.put("transactionCreationInitialRateLimit", "200");
53 properties.put("MaxShardDataChangeExecutorPoolSize", "41");
54 properties.put("Max-Shard-Data-Change Executor-Queue Size", "1111");
55 properties.put(" max shard data change listener queue size", "2222");
56 properties.put("mAx-shaRd-data-STORE-executor-quEUe-size", "3333");
57 properties.put("persistent", "false");
59 boolean updated = introspector.update(properties);
60 assertEquals("updated", true, updated);
61 context = introspector.getContext();
63 assertEquals(31, context.getShardTransactionIdleTimeout().toMinutes());
64 assertEquals(26000, context.getOperationTimeoutInMillis());
65 assertEquals(100, context.getShardTransactionCommitTimeoutInSeconds());
66 assertEquals(199, context.getShardRaftConfig().getJournalRecoveryLogBatchSize());
67 assertEquals(212, context.getShardRaftConfig().getSnapshotBatchCount());
68 assertEquals(101, context.getShardRaftConfig().getHeartBeatInterval().length());
69 assertEquals(567, context.getShardTransactionCommitQueueCapacity());
70 assertEquals(82, context.getShardInitializationTimeout().duration().toSeconds());
71 assertEquals(66, context.getShardLeaderElectionTimeout().duration().toSeconds());
72 assertEquals(123, context.getShardRaftConfig().getIsolatedCheckIntervalInMillis());
73 assertEquals(100, context.getShardRaftConfig().getSnapshotDataThresholdPercentage());
74 assertEquals(21, context.getShardRaftConfig().getElectionTimeoutFactor());
75 assertEquals(901, context.getShardBatchedModificationCount());
76 assertEquals(200, context.getTransactionCreationInitialRateLimit());
77 assertEquals(41, context.getDataStoreProperties().getMaxDataChangeExecutorPoolSize());
78 assertEquals(1111, context.getDataStoreProperties().getMaxDataChangeExecutorQueueSize());
79 assertEquals(2222, context.getDataStoreProperties().getMaxDataChangeListenerQueueSize());
80 assertEquals(3333, context.getDataStoreProperties().getMaxDataStoreExecutorQueueSize());
81 assertEquals(false, context.isPersistent());
83 properties.put("shard-transaction-idle-timeout-in-minutes", "32");
84 properties.put("operation-timeout-in-seconds", "27");
85 properties.put("shard-heartbeat-interval-in-millis", "102");
86 properties.put("shard-election-timeout-factor", "22");
87 properties.put("max-shard-data-change-executor-pool-size", "42");
88 properties.put("max-shard-data-store-executor-queue-size", "4444");
89 properties.put("persistent", "true");
91 updated = introspector.update(properties);
92 assertEquals("updated", true, updated);
93 context = introspector.getContext();
95 assertEquals(32, context.getShardTransactionIdleTimeout().toMinutes());
96 assertEquals(27000, context.getOperationTimeoutInMillis());
97 assertEquals(100, context.getShardTransactionCommitTimeoutInSeconds());
98 assertEquals(199, context.getShardRaftConfig().getJournalRecoveryLogBatchSize());
99 assertEquals(212, context.getShardRaftConfig().getSnapshotBatchCount());
100 assertEquals(102, context.getShardRaftConfig().getHeartBeatInterval().length());
101 assertEquals(567, context.getShardTransactionCommitQueueCapacity());
102 assertEquals(82, context.getShardInitializationTimeout().duration().toSeconds());
103 assertEquals(66, context.getShardLeaderElectionTimeout().duration().toSeconds());
104 assertEquals(123, context.getShardRaftConfig().getIsolatedCheckIntervalInMillis());
105 assertEquals(100, context.getShardRaftConfig().getSnapshotDataThresholdPercentage());
106 assertEquals(22, context.getShardRaftConfig().getElectionTimeoutFactor());
107 assertEquals(200, context.getTransactionCreationInitialRateLimit());
108 assertEquals(42, context.getDataStoreProperties().getMaxDataChangeExecutorPoolSize());
109 assertEquals(1111, context.getDataStoreProperties().getMaxDataChangeExecutorQueueSize());
110 assertEquals(2222, context.getDataStoreProperties().getMaxDataChangeListenerQueueSize());
111 assertEquals(4444, context.getDataStoreProperties().getMaxDataStoreExecutorQueueSize());
112 assertEquals(true, context.isPersistent());
114 updated = introspector.update(null);
115 assertEquals("updated", false, updated);
117 updated = introspector.update(new Hashtable<>());
118 assertEquals("updated", false, updated);
123 public void testUpdateWithInvalidValues() {
124 DatastoreContext context = DatastoreContext.newBuilder()
125 .logicalStoreType(LogicalDatastoreType.OPERATIONAL).build();
126 final DatastoreContextIntrospector introspector = new DatastoreContextIntrospector(context);
128 final Map<String, Object> properties = new HashMap<>();
129 properties.put("shard-transaction-idle-timeout-in-minutes", "0"); // bad - must be > 0
130 properties.put("shard-journal-recovery-log-batch-size", "199");
131 properties.put("shard-transaction-commit-timeout-in-seconds", "bogus"); // bad - NaN
132 properties.put("shard-snapshot-batch-count", "212"); // good
133 properties.put("operation-timeout-in-seconds", "4"); // bad - must be >= 5
134 properties.put("shard-heartbeat-interval-in-millis", "99"); // bad - must be >= 100
135 properties.put("shard-transaction-commit-queue-capacity", "567"); // good
136 properties.put("shard-snapshot-data-threshold-percentage", "101"); // bad - must be 0-100
137 properties.put("shard-initialization-timeout-in-seconds", "-1"); // bad - must be > 0
138 properties.put("max-shard-data-change-executor-pool-size", "bogus"); // bad - NaN
139 properties.put("unknownProperty", "1"); // bad - invalid property name
141 final boolean updated = introspector.update(properties);
142 assertEquals("updated", true, updated);
143 context = introspector.getContext();
145 assertEquals(DEFAULT_SHARD_TRANSACTION_IDLE_TIMEOUT, context.getShardTransactionIdleTimeout());
146 assertEquals(199, context.getShardRaftConfig().getJournalRecoveryLogBatchSize());
147 assertEquals(DEFAULT_SHARD_TX_COMMIT_TIMEOUT_IN_SECONDS, context.getShardTransactionCommitTimeoutInSeconds());
148 assertEquals(212, context.getShardRaftConfig().getSnapshotBatchCount());
149 assertEquals(DEFAULT_OPERATION_TIMEOUT_IN_MS, context.getOperationTimeoutInMillis());
150 assertEquals(DEFAULT_HEARTBEAT_INTERVAL_IN_MILLIS,
151 context.getShardRaftConfig().getHeartBeatInterval().length());
152 assertEquals(567, context.getShardTransactionCommitQueueCapacity());
153 assertEquals(DEFAULT_SHARD_SNAPSHOT_DATA_THRESHOLD_PERCENTAGE,
154 context.getShardRaftConfig().getSnapshotDataThresholdPercentage());
155 assertEquals(DEFAULT_SHARD_INITIALIZATION_TIMEOUT, context.getShardInitializationTimeout());
156 assertEquals(InMemoryDOMDataStoreConfigProperties.DEFAULT_MAX_DATA_CHANGE_EXECUTOR_POOL_SIZE,
157 context.getDataStoreProperties().getMaxDataChangeExecutorPoolSize());
161 public void testUpdateWithDatastoreTypeSpecificProperties() {
162 final Map<String, Object> properties = new HashMap<>();
163 properties.put("shard-transaction-idle-timeout-in-minutes", "22"); // global setting
164 properties.put("operational.shard-transaction-idle-timeout-in-minutes", "33"); // operational override
165 properties.put("config.shard-transaction-idle-timeout-in-minutes", "44"); // config override
167 properties.put("max-shard-data-change-executor-pool-size", "222"); // global setting
168 properties.put("operational.max-shard-data-change-executor-pool-size", "333"); // operational override
169 properties.put("config.max-shard-data-change-executor-pool-size", "444"); // config override
171 properties.put("persistent", "false"); // global setting
172 properties.put("operational.Persistent", "true"); // operational override
174 DatastoreContext operContext = DatastoreContext.newBuilder()
175 .logicalStoreType(LogicalDatastoreType.OPERATIONAL).build();
176 final DatastoreContextIntrospector operIntrospector = new DatastoreContextIntrospector(operContext);
177 boolean updated = operIntrospector.update(properties);
178 assertEquals("updated", true, updated);
179 operContext = operIntrospector.getContext();
181 assertEquals(33, operContext.getShardTransactionIdleTimeout().toMinutes());
182 assertEquals(true, operContext.isPersistent());
183 assertEquals(333, operContext.getDataStoreProperties().getMaxDataChangeExecutorPoolSize());
185 DatastoreContext configContext = DatastoreContext.newBuilder()
186 .logicalStoreType(LogicalDatastoreType.CONFIGURATION).build();
187 final DatastoreContextIntrospector configIntrospector = new DatastoreContextIntrospector(configContext);
188 updated = configIntrospector.update(properties);
189 assertEquals("updated", true, updated);
190 configContext = configIntrospector.getContext();
192 assertEquals(44, configContext.getShardTransactionIdleTimeout().toMinutes());
193 assertEquals(false, configContext.isPersistent());
194 assertEquals(444, configContext.getDataStoreProperties().getMaxDataChangeExecutorPoolSize());
198 public void testGetDatastoreContextForShard() {
199 final Map<String, Object> properties = new HashMap<>();
200 properties.put("shard-transaction-idle-timeout-in-minutes", "22"); // global setting
201 properties.put("operational.shard-transaction-idle-timeout-in-minutes", "33"); // operational override
202 properties.put("config.shard-transaction-idle-timeout-in-minutes", "44"); // config override
203 properties.put("topology.shard-transaction-idle-timeout-in-minutes", "55"); // global shard override
205 DatastoreContext operContext = DatastoreContext.newBuilder()
206 .logicalStoreType(LogicalDatastoreType.OPERATIONAL).build();
207 final DatastoreContextIntrospector operIntrospector = new DatastoreContextIntrospector(operContext);
209 DatastoreContext shardContext = operIntrospector.newContextFactory().getShardDatastoreContext("topology");
210 assertEquals(10, shardContext.getShardTransactionIdleTimeout().toMinutes());
212 operIntrospector.update(properties);
213 operContext = operIntrospector.getContext();
214 assertEquals(33, operContext.getShardTransactionIdleTimeout().toMinutes());
216 shardContext = operIntrospector.newContextFactory().getShardDatastoreContext("topology");
217 assertEquals(55, shardContext.getShardTransactionIdleTimeout().toMinutes());
219 DatastoreContext configContext = DatastoreContext.newBuilder()
220 .logicalStoreType(LogicalDatastoreType.CONFIGURATION).build();
221 final DatastoreContextIntrospector configIntrospector = new DatastoreContextIntrospector(configContext);
222 configIntrospector.update(properties);
223 configContext = configIntrospector.getContext();
224 assertEquals(44, configContext.getShardTransactionIdleTimeout().toMinutes());
226 shardContext = configIntrospector.newContextFactory().getShardDatastoreContext("topology");
227 assertEquals(55, shardContext.getShardTransactionIdleTimeout().toMinutes());
229 // operational shard override
230 properties.put("operational.topology.shard-transaction-idle-timeout-in-minutes", "66");
231 // config shard override
232 properties.put("config.topology.shard-transaction-idle-timeout-in-minutes", "77");
234 operIntrospector.update(properties);
235 shardContext = operIntrospector.newContextFactory().getShardDatastoreContext("topology");
236 assertEquals(66, shardContext.getShardTransactionIdleTimeout().toMinutes());
238 configIntrospector.update(properties);
239 shardContext = configIntrospector.newContextFactory().getShardDatastoreContext("topology");
240 assertEquals(77, shardContext.getShardTransactionIdleTimeout().toMinutes());
242 shardContext = configIntrospector.newContextFactory().getShardDatastoreContext("default");
243 assertEquals(44, shardContext.getShardTransactionIdleTimeout().toMinutes());