Ray Milkey

ONOS-2431 - Unit tests for DistributedNetworkConfigStore

Change-Id: I7a3f6bd5d39c90e7ad2247fb56a14fa29227ad91
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.store.service;
17 +
18 +import java.util.Collection;
19 +import java.util.Map;
20 +import java.util.Set;
21 +import java.util.function.BiFunction;
22 +import java.util.function.Function;
23 +import java.util.function.Predicate;
24 +
25 +/**
26 + * Testing adapter for the consistent map.
27 + */
28 +public class ConsistentMapAdapter<K, V> implements ConsistentMap<K, V> {
29 + @Override
30 + public int size() {
31 + return 0;
32 + }
33 +
34 + @Override
35 + public boolean isEmpty() {
36 + return false;
37 + }
38 +
39 + @Override
40 + public boolean containsKey(K key) {
41 + return false;
42 + }
43 +
44 + @Override
45 + public boolean containsValue(V value) {
46 + return false;
47 + }
48 +
49 + @Override
50 + public Versioned<V> get(K key) {
51 + return null;
52 + }
53 +
54 + @Override
55 + public Versioned<V> computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
56 + return null;
57 + }
58 +
59 + @Override
60 + public Versioned<V> compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
61 + return null;
62 + }
63 +
64 + @Override
65 + public Versioned<V> computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
66 + return null;
67 + }
68 +
69 + @Override
70 + public Versioned<V> computeIf(K key, Predicate<? super V> condition,
71 + BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
72 + return null;
73 + }
74 +
75 + @Override
76 + public Versioned<V> put(K key, V value) {
77 + return null;
78 + }
79 +
80 + @Override
81 + public Versioned<V> putAndGet(K key, V value) {
82 + return null;
83 + }
84 +
85 + @Override
86 + public Versioned<V> remove(K key) {
87 + return null;
88 + }
89 +
90 + @Override
91 + public void clear() {
92 +
93 + }
94 +
95 + @Override
96 + public Set<K> keySet() {
97 + return null;
98 + }
99 +
100 + @Override
101 + public Collection<Versioned<V>> values() {
102 + return null;
103 + }
104 +
105 + @Override
106 + public Set<Map.Entry<K, Versioned<V>>> entrySet() {
107 + return null;
108 + }
109 +
110 + @Override
111 + public Versioned<V> putIfAbsent(K key, V value) {
112 + return null;
113 + }
114 +
115 + @Override
116 + public boolean remove(K key, V value) {
117 + return false;
118 + }
119 +
120 + @Override
121 + public boolean remove(K key, long version) {
122 + return false;
123 + }
124 +
125 + @Override
126 + public boolean replace(K key, V oldValue, V newValue) {
127 + return false;
128 + }
129 +
130 + @Override
131 + public boolean replace(K key, long oldVersion, V newValue) {
132 + return false;
133 + }
134 +
135 + @Override
136 + public void addListener(MapEventListener<K, V> listener) {
137 +
138 + }
139 +
140 + @Override
141 + public void removeListener(MapEventListener<K, V> listener) {
142 +
143 + }
144 +}
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.store.service;
17 +
18 +import java.util.Collection;
19 +import java.util.HashMap;
20 +import java.util.LinkedList;
21 +import java.util.List;
22 +import java.util.Map;
23 +import java.util.Set;
24 +import java.util.function.BiFunction;
25 +import java.util.function.Function;
26 +import java.util.function.Predicate;
27 +import java.util.stream.Collectors;
28 +
29 +import org.onosproject.core.ApplicationId;
30 +import static org.onosproject.store.service.MapEvent.Type;
31 +import static org.onosproject.store.service.MapEvent.Type.*;
32 +
33 +/**
34 + * Test implementation of the consistent map.
35 + */
36 +public final class TestConsistentMap<K, V> extends ConsistentMapAdapter<K, V> {
37 +
38 + private final List<MapEventListener<K, V>> listeners;
39 + private final HashMap<K, V> map;
40 + private final String mapName;
41 +
42 + private TestConsistentMap(String mapName) {
43 + map = new HashMap<>();
44 + listeners = new LinkedList<>();
45 + this.mapName = mapName;
46 + }
47 +
48 + private Versioned<V> version(V v) {
49 + return new Versioned<>(v, 1, System.currentTimeMillis());
50 + }
51 +
52 + /**
53 + * Notify all listeners of an event.
54 + */
55 + private void notifyListeners(String mapName, Type type,
56 + K key, Versioned<V> value) {
57 + MapEvent<K, V> event = new MapEvent<>(mapName, type, key, value);
58 + listeners.forEach(
59 + listener -> listener.event(event)
60 + );
61 + }
62 +
63 + @Override
64 + public int size() {
65 + return map.size();
66 + }
67 +
68 + @Override
69 + public boolean isEmpty() {
70 + return map.isEmpty();
71 + }
72 +
73 + @Override
74 + public boolean containsKey(K key) {
75 + return map.containsKey(key);
76 + }
77 +
78 + @Override
79 + public boolean containsValue(V value) {
80 + return map.containsValue(value);
81 + }
82 +
83 + @Override
84 + public Versioned<V> get(K key) {
85 + return version(map.get(key));
86 + }
87 +
88 + @Override
89 + public Versioned<V> computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
90 + Versioned<V> result = version(map.computeIfAbsent(key, mappingFunction));
91 + notifyListeners(mapName, INSERT, key, result);
92 + return result;
93 + }
94 +
95 + @Override
96 + public Versioned<V> compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
97 + return version(map.compute(key, remappingFunction));
98 + }
99 +
100 + @Override
101 + public Versioned<V> computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
102 + return version(map.computeIfPresent(key, remappingFunction));
103 + }
104 +
105 + @Override
106 + public Versioned<V> computeIf(K key, Predicate<? super V> condition,
107 + BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
108 + return null;
109 + }
110 +
111 + @Override
112 + public Versioned<V> put(K key, V value) {
113 + Versioned<V> result = version(map.put(key, value));
114 + notifyListeners(mapName, INSERT, key, result);
115 + return result;
116 + }
117 +
118 + @Override
119 + public Versioned<V> putAndGet(K key, V value) {
120 + Versioned<V> result = version(map.put(key, value));
121 + notifyListeners(mapName, UPDATE, key, result);
122 + return result;
123 + }
124 +
125 + @Override
126 + public Versioned<V> remove(K key) {
127 + Versioned<V> result = version(map.remove(key));
128 + notifyListeners(mapName, REMOVE, key, result);
129 + return result;
130 + }
131 +
132 + @Override
133 + public void clear() {
134 + map.clear();
135 + }
136 +
137 + @Override
138 + public Set<K> keySet() {
139 + return map.keySet();
140 + }
141 +
142 + @Override
143 + public Collection<Versioned<V>> values() {
144 + return map
145 + .values()
146 + .stream()
147 + .map(this::version)
148 + .collect(Collectors.toList());
149 + }
150 +
151 + @Override
152 + public Set<Map.Entry<K, Versioned<V>>> entrySet() {
153 + return super.entrySet();
154 + }
155 +
156 + @Override
157 + public Versioned<V> putIfAbsent(K key, V value) {
158 + Versioned<V> result = version(map.putIfAbsent(key, value));
159 + if (map.get(key).equals(value)) {
160 + notifyListeners(mapName, INSERT, key, result);
161 + }
162 + return result;
163 + }
164 +
165 + @Override
166 + public boolean remove(K key, V value) {
167 + boolean removed = map.remove(key, value);
168 + if (removed) {
169 + notifyListeners(mapName, REMOVE, key, null);
170 + }
171 + return removed;
172 + }
173 +
174 + @Override
175 + public boolean remove(K key, long version) {
176 + boolean removed = map.remove(key, version);
177 + if (removed) {
178 + notifyListeners(mapName, REMOVE, key, null);
179 + }
180 + return removed;
181 + }
182 +
183 + @Override
184 + public boolean replace(K key, V oldValue, V newValue) {
185 + boolean replaced = map.replace(key, oldValue, newValue);
186 + if (replaced) {
187 + notifyListeners(mapName, REMOVE, key, null);
188 + }
189 + return replaced;
190 + }
191 +
192 + @Override
193 + public boolean replace(K key, long oldVersion, V newValue) {
194 + boolean replaced = map.replace(key, map.get(key), newValue);
195 + if (replaced) {
196 + notifyListeners(mapName, REMOVE, key, null);
197 + }
198 + return replaced;
199 + }
200 +
201 + @Override
202 + public void addListener(MapEventListener<K, V> listener) {
203 + listeners.add(listener);
204 + }
205 +
206 + @Override
207 + public void removeListener(MapEventListener<K, V> listener) {
208 + listeners.remove(listener);
209 + }
210 +
211 + public static Builder builder() {
212 + return new Builder();
213 + }
214 +
215 + public static class Builder<K, V> implements ConsistentMapBuilder<K, V> {
216 + String mapName = "map";
217 +
218 + @Override
219 + public ConsistentMapBuilder<K, V> withName(String mapName) {
220 + this.mapName = mapName;
221 + return this;
222 + }
223 +
224 + @Override
225 + public ConsistentMapBuilder<K, V> withApplicationId(ApplicationId id) {
226 + return this;
227 + }
228 +
229 + @Override
230 + public ConsistentMapBuilder<K, V> withSerializer(Serializer serializer) {
231 + return this;
232 + }
233 +
234 + @Override
235 + public ConsistentMapBuilder<K, V> withPartitionsDisabled() {
236 + return this;
237 + }
238 +
239 + @Override
240 + public ConsistentMapBuilder<K, V> withUpdatesDisabled() {
241 + return this;
242 + }
243 +
244 + @Override
245 + public ConsistentMapBuilder<K, V> withPurgeOnUninstall() {
246 + return this;
247 + }
248 +
249 + @Override
250 + public ConsistentMap<K, V> build() {
251 + return new TestConsistentMap<>(mapName);
252 + }
253 +
254 + @Override
255 + public AsyncConsistentMap<K, V> buildAsyncMap() {
256 + return null;
257 + }
258 +
259 + }
260 +
261 +}
...@@ -25,7 +25,7 @@ public class TestStorageService extends StorageServiceAdapter { ...@@ -25,7 +25,7 @@ public class TestStorageService extends StorageServiceAdapter {
25 25
26 @Override 26 @Override
27 public <K, V> ConsistentMapBuilder<K, V> consistentMapBuilder() { 27 public <K, V> ConsistentMapBuilder<K, V> consistentMapBuilder() {
28 - throw new UnsupportedOperationException("consistentMapBuilder"); 28 + return TestConsistentMap.builder();
29 } 29 }
30 30
31 @Override 31 @Override
......
1 +/*
2 + * Copyright 2015 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.incubator.store.config.impl;
17 +
18 +import org.junit.After;
19 +import org.junit.Before;
20 +import org.junit.Test;
21 +import org.onosproject.incubator.net.config.Config;
22 +import org.onosproject.incubator.net.config.ConfigFactory;
23 +import org.onosproject.incubator.net.config.SubjectFactory;
24 +import org.onosproject.store.service.TestStorageService;
25 +
26 +import com.fasterxml.jackson.databind.ObjectMapper;
27 +
28 +import static org.hamcrest.Matchers.hasSize;
29 +import static org.hamcrest.Matchers.is;
30 +import static org.hamcrest.Matchers.notNullValue;
31 +import static org.hamcrest.Matchers.nullValue;
32 +import static org.junit.Assert.assertThat;
33 +
34 +public class DistributedNetworkConfigStoreTest {
35 + private DistributedNetworkConfigStore configStore;
36 +
37 + /**
38 + * Sets up the config store and the storage service test harness.
39 + */
40 + @Before
41 + public void setUp() {
42 + configStore = new DistributedNetworkConfigStore();
43 + configStore.storageService = new TestStorageService();
44 + configStore.setDelegate(event -> { });
45 + configStore.activate();
46 + }
47 +
48 + /**
49 + * Tears down the config store.
50 + */
51 + @After
52 + public void tearDown() {
53 + configStore.deactivate();
54 + }
55 +
56 + /**
57 + * Config class for testing.
58 + */
59 + public class BasicConfig extends Config<String> { }
60 +
61 + /**
62 + * Config factory class for testing.
63 + */
64 + public class MockConfigFactory extends ConfigFactory<String, BasicConfig> {
65 + protected MockConfigFactory(SubjectFactory<String> subjectFactory,
66 + Class<BasicConfig> configClass, String configKey) {
67 + super(subjectFactory, configClass, configKey);
68 + }
69 + @Override
70 + public BasicConfig createConfig() {
71 + return new BasicConfig();
72 + }
73 + }
74 +
75 + /**
76 + * Tests creation, query and removal of a config.
77 + */
78 + @Test
79 + public void testCreateConfig() {
80 + configStore.addConfigFactory(new MockConfigFactory(null, BasicConfig.class, "config1"));
81 +
82 + configStore.createConfig("config1", BasicConfig.class);
83 + assertThat(configStore.getConfigClasses("config1"), hasSize(1));
84 + assertThat(configStore.getSubjects(String.class, BasicConfig.class), hasSize(1));
85 + assertThat(configStore.getSubjects(String.class), hasSize(1));
86 +
87 + BasicConfig queried = configStore.getConfig("config1", BasicConfig.class);
88 + assertThat(queried, notNullValue());
89 +
90 + configStore.clearConfig("config1", BasicConfig.class);
91 + assertThat(configStore.getConfigClasses("config1"), hasSize(0));
92 + assertThat(configStore.getSubjects(String.class, BasicConfig.class), hasSize(0));
93 + assertThat(configStore.getSubjects(String.class), hasSize(0));
94 +
95 + BasicConfig queriedAfterClear = configStore.getConfig("config1", BasicConfig.class);
96 + assertThat(queriedAfterClear, nullValue());
97 + }
98 +
99 + /**
100 + * Tests creation, query and removal of a factory.
101 + */
102 + @Test
103 + public void testCreateFactory() {
104 + MockConfigFactory mockFactory = new MockConfigFactory(null, BasicConfig.class, "config1");
105 +
106 + assertThat(configStore.getConfigFactory(BasicConfig.class), nullValue());
107 +
108 + configStore.addConfigFactory(mockFactory);
109 + assertThat(configStore.getConfigFactory(BasicConfig.class), is(mockFactory));
110 +
111 + configStore.removeConfigFactory(mockFactory);
112 + assertThat(configStore.getConfigFactory(BasicConfig.class), nullValue());
113 + }
114 +
115 + /**
116 + * Tests applying a config.
117 + */
118 + @Test
119 + public void testApplyConfig() {
120 + configStore.addConfigFactory(new MockConfigFactory(null, BasicConfig.class, "config1"));
121 +
122 + configStore.applyConfig("config1", BasicConfig.class, new ObjectMapper().createObjectNode());
123 + assertThat(configStore.getConfigClasses("config1"), hasSize(1));
124 + assertThat(configStore.getSubjects(String.class, BasicConfig.class), hasSize(1));
125 + assertThat(configStore.getSubjects(String.class), hasSize(1));
126 + }
127 +}