blob: 4df9d4685ce735153ca4786ffe9d56ef10997b15 [file] [log] [blame]
Jordan Halterman980a8c12017-09-22 18:01:19 -07001/*
2 * Copyright 2017-present Open Networking Foundation
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 */
16package org.onosproject.upgrade.impl;
17
18import java.util.Arrays;
Jordan Halterman28183ee2017-10-17 17:29:10 -070019import java.util.Collection;
Jordan Halterman980a8c12017-09-22 18:01:19 -070020import java.util.List;
Jordan Halterman28183ee2017-10-17 17:29:10 -070021import java.util.Map;
Jordan Halterman980a8c12017-09-22 18:01:19 -070022import java.util.Set;
23import java.util.concurrent.atomic.AtomicInteger;
24import java.util.stream.Collectors;
25
Jordan Halterman28183ee2017-10-17 17:29:10 -070026import com.google.common.collect.Maps;
27import com.google.common.collect.Sets;
Jordan Halterman980a8c12017-09-22 18:01:19 -070028import org.junit.Test;
29import org.onlab.packet.IpAddress;
Jordan Halterman5ca07932017-10-07 13:28:22 -070030import org.onosproject.cluster.ClusterEvent;
Jordan Halterman28183ee2017-10-17 17:29:10 -070031import org.onosproject.cluster.ClusterServiceAdapter;
Jordan Halterman980a8c12017-09-22 18:01:19 -070032import org.onosproject.cluster.ControllerNode;
33import org.onosproject.cluster.DefaultControllerNode;
Jordan Halterman28183ee2017-10-17 17:29:10 -070034import org.onosproject.cluster.Member;
35import org.onosproject.cluster.MembershipGroup;
36import org.onosproject.cluster.MembershipServiceAdapter;
Jordan Halterman980a8c12017-09-22 18:01:19 -070037import org.onosproject.cluster.NodeId;
Jordan Halterman07f052b2017-10-08 14:22:41 -070038import org.onosproject.common.event.impl.TestEventDispatcher;
Jordan Halterman980a8c12017-09-22 18:01:19 -070039import org.onosproject.core.Version;
40import org.onosproject.core.VersionServiceAdapter;
41import org.onosproject.store.service.AsyncAtomicValue;
42import org.onosproject.store.service.AsyncAtomicValueAdapter;
43import org.onosproject.store.service.AtomicValue;
44import org.onosproject.store.service.AtomicValueAdapter;
45import org.onosproject.store.service.AtomicValueBuilder;
46import org.onosproject.store.service.CoordinationServiceAdapter;
47import org.onosproject.upgrade.Upgrade;
48
49import static org.junit.Assert.assertEquals;
50import static org.junit.Assert.assertFalse;
51import static org.junit.Assert.assertTrue;
52import static org.junit.Assert.fail;
Jordan Halterman07f052b2017-10-08 14:22:41 -070053import static org.onosproject.net.NetTestTools.injectEventDispatcher;
Jordan Halterman980a8c12017-09-22 18:01:19 -070054
55/**
56 * Upgrade manager test.
57 */
58public class UpgradeManagerTest {
59
60 /**
61 * Creates a new upgrade manager to test.
62 *
63 * @param version the local node version
64 * @param state the initial upgrade state
65 * @param versions a list of controller node versions
66 * @return the activated upgrade manager
67 */
68 @SuppressWarnings("unchecked")
69 private UpgradeManager createUpgradeManager(Version version, Upgrade state, List<Version> versions) {
70 UpgradeManager upgradeManager = new UpgradeManager();
Jordan Halterman07f052b2017-10-08 14:22:41 -070071 injectEventDispatcher(upgradeManager, new TestEventDispatcher());
Jordan Halterman28183ee2017-10-17 17:29:10 -070072 upgradeManager.membershipService = new MembershipServiceAdapter() {
73 @Override
74 public MembershipGroup getLocalGroup() {
75 return getGroups()
76 .stream()
77 .filter(group -> group.version().equals(version))
78 .findFirst()
79 .get();
80 }
81
82 @Override
83 public Collection<MembershipGroup> getGroups() {
84 AtomicInteger nodeCounter = new AtomicInteger();
85 Map<Version, Set<Member>> groups = Maps.newHashMap();
86 versions.stream().forEach(version -> {
87 groups.computeIfAbsent(version, k -> Sets.newHashSet())
88 .add(new Member(NodeId.nodeId(String.valueOf(nodeCounter.getAndIncrement())), version));
89 });
90 return Maps.transformEntries(groups, MembershipGroup::new).values();
91 }
92 };
93
94 upgradeManager.clusterService = new ClusterServiceAdapter() {
Jordan Halterman980a8c12017-09-22 18:01:19 -070095 @Override
96 public Set<ControllerNode> getNodes() {
97 AtomicInteger nodeCounter = new AtomicInteger();
98 return versions.stream()
99 .map(v -> {
100 int nodeId = nodeCounter.getAndIncrement();
101 return new DefaultControllerNode(
102 NodeId.nodeId(String.valueOf(nodeId)),
103 IpAddress.valueOf("127.0.0.1"),
104 nodeId);
105 })
106 .collect(Collectors.toSet());
107 }
108
109 @Override
Jordan Halterman5ca07932017-10-07 13:28:22 -0700110 public ControllerNode getNode(NodeId nodeId) {
111 return getNodes()
112 .stream()
113 .filter(node -> node.id().equals(nodeId))
114 .findFirst()
115 .orElse(null);
116 }
117
118 @Override
Jordan Halterman980a8c12017-09-22 18:01:19 -0700119 public Version getVersion(NodeId nodeId) {
120 return versions.get(Integer.parseInt(nodeId.id()));
121 }
122 };
123
124 upgradeManager.versionService = new VersionServiceAdapter() {
125 @Override
126 public Version version() {
127 return version;
128 }
129 };
130
131 upgradeManager.coordinationService = new CoordinationServiceAdapter() {
132 @Override
133 public <V> AtomicValueBuilder<V> atomicValueBuilder() {
134 return new AtomicValueBuilder<V>() {
135 @Override
136 public AsyncAtomicValue<V> build() {
137 return new AsyncAtomicValueAdapter() {
138 @Override
139 public AtomicValue asAtomicValue() {
140 return new AtomicValueAdapter() {
141 private Object value = state;
142
143 @Override
144 public void set(Object value) {
145 this.value = value;
146 }
147
148 @Override
149 public Object get() {
150 return value;
151 }
152
153 @Override
154 public boolean compareAndSet(Object expect, Object update) {
155 if ((value == null && expect == null)
156 || (value != null && value.equals(expect))) {
157 value = update;
158 return true;
159 }
160 return false;
161 }
162 };
163 }
164 };
165 }
166 };
167 }
168 };
169
170 upgradeManager.activate();
171 return upgradeManager;
172 }
173
174 @Test
175 public void testFailedCommit() throws Exception {
176 UpgradeManager upgradeManager = createUpgradeManager(
177 Version.version("1.0.0"),
178 new Upgrade(Version.version("1.0.0"), Version.version("1.0.0"), Upgrade.Status.INACTIVE),
179 Arrays.asList(Version.version("1.0.0"), Version.version("1.0.0"), Version.version("1.0.1")));
180
181 assertEquals(Upgrade.Status.INACTIVE, upgradeManager.getState().status());
182 assertTrue(upgradeManager.isLocalActive());
183 assertFalse(upgradeManager.isLocalUpgraded());
184
185 upgradeManager.initialize();
186
187 assertEquals(Upgrade.Status.INITIALIZED, upgradeManager.getState().status());
188 assertEquals(Version.version("1.0.0"), upgradeManager.getState().source());
189 assertEquals(Version.version("1.0.0"), upgradeManager.getState().target());
190 assertEquals(Version.version("1.0.0"), upgradeManager.getVersion());
191 assertTrue(upgradeManager.isLocalActive());
192 assertFalse(upgradeManager.isLocalUpgraded());
193
194 upgradeManager.upgrade();
195 assertEquals(Upgrade.Status.UPGRADED, upgradeManager.getState().status());
196
197 try {
198 upgradeManager.commit();
199 fail();
200 } catch (IllegalStateException e) {
201 }
202 }
203
204 @Test
205 public void testSuccessfulCommit() throws Exception {
206 UpgradeManager upgradeManager = createUpgradeManager(
207 Version.version("1.0.1"),
208 new Upgrade(Version.version("1.0.0"), Version.version("1.0.1"), Upgrade.Status.UPGRADED),
209 Arrays.asList(Version.version("1.0.1"), Version.version("1.0.1"), Version.version("1.0.1")));
210
211 assertEquals(Upgrade.Status.UPGRADED, upgradeManager.getState().status());
212 assertTrue(upgradeManager.isLocalActive());
213 assertTrue(upgradeManager.isLocalUpgraded());
214
215 upgradeManager.commit();
216 assertEquals(Upgrade.Status.INACTIVE, upgradeManager.getState().status());
217 }
218
219 @Test
220 public void testFailedReset() throws Exception {
221 UpgradeManager upgradeManager = createUpgradeManager(
222 Version.version("1.0.0"),
223 new Upgrade(Version.version("1.0.0"), Version.version("1.0.1"), Upgrade.Status.INITIALIZED),
224 Arrays.asList(Version.version("1.0.0"), Version.version("1.0.0"), Version.version("1.0.1")));
225
226 assertEquals(Upgrade.Status.INITIALIZED, upgradeManager.getState().status());
227 assertEquals(Version.version("1.0.0"), upgradeManager.getState().source());
228 assertEquals(Version.version("1.0.1"), upgradeManager.getState().target());
229 assertEquals(Version.version("1.0.0"), upgradeManager.getVersion());
230 assertTrue(upgradeManager.isLocalActive());
231 assertFalse(upgradeManager.isLocalUpgraded());
232
233 upgradeManager.upgrade();
234 assertEquals(Upgrade.Status.UPGRADED, upgradeManager.getState().status());
235 assertEquals(Version.version("1.0.1"), upgradeManager.getVersion());
236
237 upgradeManager.rollback();
238 assertEquals(Upgrade.Status.ROLLED_BACK, upgradeManager.getState().status());
239
240 try {
241 upgradeManager.reset();
242 fail();
243 } catch (IllegalStateException e) {
244 }
245 }
246
247 @Test
248 public void testSuccessfulResetFromInitialized() throws Exception {
249 UpgradeManager upgradeManager = createUpgradeManager(
250 Version.version("1.0.0"),
251 new Upgrade(Version.version("1.0.0"), Version.version("1.0.0"), Upgrade.Status.INITIALIZED),
252 Arrays.asList(Version.version("1.0.0"), Version.version("1.0.0"), Version.version("1.0.0")));
253
254 assertEquals(Upgrade.Status.INITIALIZED, upgradeManager.getState().status());
255 assertTrue(upgradeManager.isLocalActive());
256 assertFalse(upgradeManager.isLocalUpgraded());
257
258 upgradeManager.reset();
259 assertEquals(Upgrade.Status.INACTIVE, upgradeManager.getState().status());
260 }
261
262 @Test
263 public void testSuccessfulResetFromRolledBack() throws Exception {
264 UpgradeManager upgradeManager = createUpgradeManager(
265 Version.version("1.0.0"),
266 new Upgrade(Version.version("1.0.0"), Version.version("1.0.1"), Upgrade.Status.ROLLED_BACK),
267 Arrays.asList(Version.version("1.0.0"), Version.version("1.0.0"), Version.version("1.0.0")));
268
269 assertEquals(Upgrade.Status.ROLLED_BACK, upgradeManager.getState().status());
270 assertTrue(upgradeManager.isLocalActive());
271 assertFalse(upgradeManager.isLocalUpgraded());
272
273 upgradeManager.reset();
274 assertEquals(Upgrade.Status.INACTIVE, upgradeManager.getState().status());
275 }
276
Jordan Halterman5ca07932017-10-07 13:28:22 -0700277 @Test
278 public void testCrashRollback() throws Exception {
279 UpgradeManager upgradeManager = createUpgradeManager(
280 Version.version("1.0.0"),
281 new Upgrade(Version.version("1.0.0"), Version.version("1.0.1"), Upgrade.Status.UPGRADED),
282 Arrays.asList(Version.version("1.0.0"), Version.version("1.0.0"), Version.version("1.0.1")));
283
284 assertFalse(upgradeManager.isLocalActive());
285
286 upgradeManager.handleClusterEvent(new ClusterEvent(
287 ClusterEvent.Type.INSTANCE_DEACTIVATED,
288 upgradeManager.clusterService.getNode(NodeId.nodeId("2"))));
289
290 assertEquals(Upgrade.Status.ROLLED_BACK, upgradeManager.getState().status());
291 assertTrue(upgradeManager.isLocalActive());
292 assertFalse(upgradeManager.isLocalUpgraded());
293 }
294
Jordan Halterman980a8c12017-09-22 18:01:19 -0700295}