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