blob: 78127eead4930fe3803d5464b36156b4efd65708 [file] [log] [blame]
/*
* Copyright 2017-present Open Networking Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.onosproject.upgrade.impl;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.junit.Test;
import org.onlab.packet.IpAddress;
import org.onosproject.cluster.ClusterEvent;
import org.onosproject.cluster.ClusterServiceAdapter;
import org.onosproject.cluster.ControllerNode;
import org.onosproject.cluster.DefaultControllerNode;
import org.onosproject.cluster.Member;
import org.onosproject.cluster.MembershipGroup;
import org.onosproject.cluster.MembershipServiceAdapter;
import org.onosproject.cluster.NodeId;
import org.onosproject.core.Version;
import org.onosproject.core.VersionServiceAdapter;
import org.onosproject.store.service.AsyncAtomicValue;
import org.onosproject.store.service.AsyncAtomicValueAdapter;
import org.onosproject.store.service.AtomicValue;
import org.onosproject.store.service.AtomicValueAdapter;
import org.onosproject.store.service.AtomicValueBuilder;
import org.onosproject.store.service.CoordinationServiceAdapter;
import org.onosproject.upgrade.Upgrade;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
* Upgrade manager test.
*/
public class UpgradeManagerTest {
/**
* Creates a new upgrade manager to test.
*
* @param version the local node version
* @param state the initial upgrade state
* @param versions a list of controller node versions
* @return the activated upgrade manager
*/
@SuppressWarnings("unchecked")
private UpgradeManager createUpgradeManager(Version version, Upgrade state, List<Version> versions) {
UpgradeManager upgradeManager = new UpgradeManager();
upgradeManager.membershipService = new MembershipServiceAdapter() {
@Override
public MembershipGroup getLocalGroup() {
return getGroups()
.stream()
.filter(group -> group.version().equals(version))
.findFirst()
.get();
}
@Override
public Collection<MembershipGroup> getGroups() {
AtomicInteger nodeCounter = new AtomicInteger();
Map<Version, Set<Member>> groups = Maps.newHashMap();
versions.stream().forEach(version -> {
groups.computeIfAbsent(version, k -> Sets.newHashSet())
.add(new Member(NodeId.nodeId(String.valueOf(nodeCounter.getAndIncrement())), version));
});
return Maps.transformEntries(groups, MembershipGroup::new).values();
}
};
upgradeManager.clusterService = new ClusterServiceAdapter() {
@Override
public Set<ControllerNode> getNodes() {
AtomicInteger nodeCounter = new AtomicInteger();
return versions.stream()
.map(v -> {
int nodeId = nodeCounter.getAndIncrement();
return new DefaultControllerNode(
NodeId.nodeId(String.valueOf(nodeId)),
IpAddress.valueOf("127.0.0.1"),
nodeId);
})
.collect(Collectors.toSet());
}
@Override
public ControllerNode getNode(NodeId nodeId) {
return getNodes()
.stream()
.filter(node -> node.id().equals(nodeId))
.findFirst()
.orElse(null);
}
@Override
public Version getVersion(NodeId nodeId) {
return versions.get(Integer.parseInt(nodeId.id()));
}
};
upgradeManager.versionService = new VersionServiceAdapter() {
@Override
public Version version() {
return version;
}
};
upgradeManager.coordinationService = new CoordinationServiceAdapter() {
@Override
public <V> AtomicValueBuilder<V> atomicValueBuilder() {
return new AtomicValueBuilder<V>() {
@Override
public AsyncAtomicValue<V> build() {
return new AsyncAtomicValueAdapter() {
@Override
public AtomicValue asAtomicValue() {
return new AtomicValueAdapter() {
private Object value = state;
@Override
public void set(Object value) {
this.value = value;
}
@Override
public Object get() {
return value;
}
@Override
public boolean compareAndSet(Object expect, Object update) {
if ((value == null && expect == null)
|| (value != null && value.equals(expect))) {
value = update;
return true;
}
return false;
}
};
}
};
}
};
}
};
upgradeManager.activate();
return upgradeManager;
}
@Test
public void testFailedCommit() throws Exception {
UpgradeManager upgradeManager = createUpgradeManager(
Version.version("1.0.0"),
new Upgrade(Version.version("1.0.0"), Version.version("1.0.0"), Upgrade.Status.INACTIVE),
Arrays.asList(Version.version("1.0.0"), Version.version("1.0.0"), Version.version("1.0.1")));
assertEquals(Upgrade.Status.INACTIVE, upgradeManager.getState().status());
assertTrue(upgradeManager.isLocalActive());
assertFalse(upgradeManager.isLocalUpgraded());
upgradeManager.initialize();
assertEquals(Upgrade.Status.INITIALIZED, upgradeManager.getState().status());
assertEquals(Version.version("1.0.0"), upgradeManager.getState().source());
assertEquals(Version.version("1.0.0"), upgradeManager.getState().target());
assertEquals(Version.version("1.0.0"), upgradeManager.getVersion());
assertTrue(upgradeManager.isLocalActive());
assertFalse(upgradeManager.isLocalUpgraded());
upgradeManager.upgrade();
assertEquals(Upgrade.Status.UPGRADED, upgradeManager.getState().status());
try {
upgradeManager.commit();
fail();
} catch (IllegalStateException e) {
}
}
@Test
public void testSuccessfulCommit() throws Exception {
UpgradeManager upgradeManager = createUpgradeManager(
Version.version("1.0.1"),
new Upgrade(Version.version("1.0.0"), Version.version("1.0.1"), Upgrade.Status.UPGRADED),
Arrays.asList(Version.version("1.0.1"), Version.version("1.0.1"), Version.version("1.0.1")));
assertEquals(Upgrade.Status.UPGRADED, upgradeManager.getState().status());
assertTrue(upgradeManager.isLocalActive());
assertTrue(upgradeManager.isLocalUpgraded());
upgradeManager.commit();
assertEquals(Upgrade.Status.INACTIVE, upgradeManager.getState().status());
}
@Test
public void testFailedReset() throws Exception {
UpgradeManager upgradeManager = createUpgradeManager(
Version.version("1.0.0"),
new Upgrade(Version.version("1.0.0"), Version.version("1.0.1"), Upgrade.Status.INITIALIZED),
Arrays.asList(Version.version("1.0.0"), Version.version("1.0.0"), Version.version("1.0.1")));
assertEquals(Upgrade.Status.INITIALIZED, upgradeManager.getState().status());
assertEquals(Version.version("1.0.0"), upgradeManager.getState().source());
assertEquals(Version.version("1.0.1"), upgradeManager.getState().target());
assertEquals(Version.version("1.0.0"), upgradeManager.getVersion());
assertTrue(upgradeManager.isLocalActive());
assertFalse(upgradeManager.isLocalUpgraded());
upgradeManager.upgrade();
assertEquals(Upgrade.Status.UPGRADED, upgradeManager.getState().status());
assertEquals(Version.version("1.0.1"), upgradeManager.getVersion());
upgradeManager.rollback();
assertEquals(Upgrade.Status.ROLLED_BACK, upgradeManager.getState().status());
try {
upgradeManager.reset();
fail();
} catch (IllegalStateException e) {
}
}
@Test
public void testSuccessfulResetFromInitialized() throws Exception {
UpgradeManager upgradeManager = createUpgradeManager(
Version.version("1.0.0"),
new Upgrade(Version.version("1.0.0"), Version.version("1.0.0"), Upgrade.Status.INITIALIZED),
Arrays.asList(Version.version("1.0.0"), Version.version("1.0.0"), Version.version("1.0.0")));
assertEquals(Upgrade.Status.INITIALIZED, upgradeManager.getState().status());
assertTrue(upgradeManager.isLocalActive());
assertFalse(upgradeManager.isLocalUpgraded());
upgradeManager.reset();
assertEquals(Upgrade.Status.INACTIVE, upgradeManager.getState().status());
}
@Test
public void testSuccessfulResetFromRolledBack() throws Exception {
UpgradeManager upgradeManager = createUpgradeManager(
Version.version("1.0.0"),
new Upgrade(Version.version("1.0.0"), Version.version("1.0.1"), Upgrade.Status.ROLLED_BACK),
Arrays.asList(Version.version("1.0.0"), Version.version("1.0.0"), Version.version("1.0.0")));
assertEquals(Upgrade.Status.ROLLED_BACK, upgradeManager.getState().status());
assertTrue(upgradeManager.isLocalActive());
assertFalse(upgradeManager.isLocalUpgraded());
upgradeManager.reset();
assertEquals(Upgrade.Status.INACTIVE, upgradeManager.getState().status());
}
@Test
public void testCrashRollback() throws Exception {
UpgradeManager upgradeManager = createUpgradeManager(
Version.version("1.0.0"),
new Upgrade(Version.version("1.0.0"), Version.version("1.0.1"), Upgrade.Status.UPGRADED),
Arrays.asList(Version.version("1.0.0"), Version.version("1.0.0"), Version.version("1.0.1")));
assertFalse(upgradeManager.isLocalActive());
upgradeManager.handleClusterEvent(new ClusterEvent(
ClusterEvent.Type.INSTANCE_DEACTIVATED,
upgradeManager.clusterService.getNode(NodeId.nodeId("2"))));
assertEquals(Upgrade.Status.ROLLED_BACK, upgradeManager.getState().status());
assertTrue(upgradeManager.isLocalActive());
assertFalse(upgradeManager.isLocalUpgraded());
}
}