blob: 9098f5fc6521378ff99e4d1a75bd580d91709563 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.apache.servicecomb.loadbalance;
import java.util.ArrayList;
import java.util.List;
import org.apache.servicecomb.core.Endpoint;
import org.apache.servicecomb.core.Invocation;
import org.apache.servicecomb.core.Transport;
import org.apache.servicecomb.foundation.test.scaffolding.config.ArchaiusUtils;
import org.apache.servicecomb.registry.api.registry.MicroserviceInstance;
import org.junit.Test;
import com.netflix.loadbalancer.Server;
import mockit.Deencapsulation;
import mockit.Expectations;
import mockit.Injectable;
import org.junit.jupiter.api.Assertions;
public class TestLoadBalanceCreator {
@Test
public void testLoadBalanceWithRoundRobinRuleAndFilter(@Injectable Invocation invocation,
@Injectable Transport transport) {
// Robin components implementations require getReachableServers & getServerList have the same size, we add a test case for this.
RoundRobinRuleExt rule = new RoundRobinRuleExt();
List<ServiceCombServer> servers = new ArrayList<>();
Endpoint host1 = new Endpoint(transport, "host1");
MicroserviceInstance instance1 = new MicroserviceInstance();
instance1.setInstanceId("instance1");
ServiceCombServer server = new ServiceCombServer(null, host1, instance1);
Endpoint host2 = new Endpoint(transport, "host2");
MicroserviceInstance instance2 = new MicroserviceInstance();
instance2.setInstanceId("instance2");
ServiceCombServer server2 = new ServiceCombServer(null, host2, instance2);
servers.add(server);
servers.add(server2);
LoadBalancer lb = new LoadBalancer(rule, "test");
List<ServerListFilterExt> filters = new ArrayList<>();
filters.add((serverList, invocation1) -> {
List<ServiceCombServer> filteredServers = new ArrayList<>();
for (ServiceCombServer server1 : servers) {
if (server1.getHost().equals("host1")) {
continue;
}
filteredServers.add(server1);
}
return filteredServers;
});
lb.setFilters(filters);
new Expectations() {
{
invocation.getLocalContext(LoadbalanceHandler.CONTEXT_KEY_SERVER_LIST);
result = servers;
}
};
Server s = lb.chooseServer(invocation);
Assertions.assertEquals(server2, s);
s = lb.chooseServer(invocation);
Assertions.assertEquals(server2, s);
s = lb.chooseServer(invocation);
Assertions.assertEquals(server2, s);
}
@Test
public void testLoadBalanceWithRandomRuleAndFilter(@Injectable Invocation invocation,
@Injectable Transport transport) {
// Robin components implementations require getReachableServers & getServerList have the same size, we add a test case for this.
RandomRuleExt rule = new RandomRuleExt();
LoadBalancer lb = new LoadBalancer(rule, "service");
List<ServiceCombServer> servers = new ArrayList<>();
Endpoint host1 = new Endpoint(transport, "host1");
MicroserviceInstance instance1 = new MicroserviceInstance();
instance1.setInstanceId("instance1");
ServiceCombServer server = new ServiceCombServer(null, host1, instance1);
Endpoint host2 = new Endpoint(transport, "host2");
MicroserviceInstance instance2 = new MicroserviceInstance();
instance2.setInstanceId("instance2");
ServiceCombServer server2 = new ServiceCombServer(null, host2, instance2);
servers.add(server);
servers.add(server2);
List<ServerListFilterExt> filters = new ArrayList<>();
filters.add((serverList, invocation1) -> {
List<ServiceCombServer> filteredServers = new ArrayList<>();
for (ServiceCombServer server1 : servers) {
if (server1.getHost().equals("host1")) {
continue;
}
filteredServers.add(server1);
}
return filteredServers;
});
lb.setFilters(filters);
new Expectations() {
{
invocation.getLocalContext(LoadbalanceHandler.CONTEXT_KEY_SERVER_LIST);
result = servers;
}
};
Server s = lb.chooseServer(invocation);
Assertions.assertEquals(server2, s);
s = lb.chooseServer(invocation);
Assertions.assertEquals(server2, s);
s = lb.chooseServer(invocation);
Assertions.assertEquals(server2, s);
}
@Test
public void testLoadBalanceWithWeightedResponseTimeRuleAndFilter(@Injectable Endpoint endpoint1,
@Injectable Endpoint endpoint2, @Injectable Invocation invocation) {
// Robin components implementations require getReachableServers & getServerList have the same size, we add a test case for this.
WeightedResponseTimeRuleExt rule = new WeightedResponseTimeRuleExt();
LoadBalancer lb = new LoadBalancer(rule, "service");
List<ServiceCombServer> servers = new ArrayList<>();
MicroserviceInstance instance1 = new MicroserviceInstance();
instance1.setInstanceId("ii01");
MicroserviceInstance instance2 = new MicroserviceInstance();
instance2.setInstanceId("ii02");
ServiceCombServer server = new ServiceCombServer(null, endpoint1, instance1);
ServiceCombServer server2 = new ServiceCombServer(null, endpoint2, instance2);
new Expectations() {
{
endpoint1.getEndpoint();
result = "host1";
endpoint2.getEndpoint();
result = "host2";
}
};
servers.add(server);
servers.add(server2);
List<ServerListFilterExt> filters = new ArrayList<>();
filters.add((serverList, invocation1) -> {
List<ServiceCombServer> filteredServers = new ArrayList<>();
for (ServiceCombServer server1 : servers) {
if (server1.getHost().equals("host1")) {
continue;
}
filteredServers.add(server1);
}
return filteredServers;
});
lb.setFilters(filters);
new Expectations() {
{
invocation.getLocalContext(LoadbalanceHandler.CONTEXT_KEY_SERVER_LIST);
result = servers;
}
};
Server s = lb.chooseServer(invocation);
Assertions.assertEquals(server2, s);
s = lb.chooseServer(invocation);
Assertions.assertEquals(server2, s);
s = lb.chooseServer(invocation);
Assertions.assertEquals(server2, s);
}
@Test
public void testLoadBalanceWithSessionSticknessRule(@Injectable Invocation invocation,
@Injectable Transport transport) {
SessionStickinessRule rule = new SessionStickinessRule();
LoadBalancer lb = new LoadBalancer(rule, "service");
List<ServiceCombServer> servers = new ArrayList<>();
Endpoint host1 = new Endpoint(transport, "host1");
MicroserviceInstance instance1 = new MicroserviceInstance();
ServiceCombServer server = new ServiceCombServer(null, host1, instance1);
instance1.setInstanceId("instance1");
Endpoint host2 = new Endpoint(transport, "host2");
MicroserviceInstance instance2 = new MicroserviceInstance();
ServiceCombServer server2 = new ServiceCombServer(null, host2, instance2);
instance2.setInstanceId("instance2");
servers.add(server);
servers.add(server2);
lb.setFilters(new ArrayList<>());
new Expectations() {
{
invocation.getLocalContext(LoadbalanceHandler.CONTEXT_KEY_SERVER_LIST);
result = servers;
}
};
Server s = lb.chooseServer(invocation);
Assertions.assertEquals(server, s);
s = lb.chooseServer(invocation);
Assertions.assertEquals(server, s);
long time = Deencapsulation.getField(rule, "lastAccessedTime");
Deencapsulation.setField(rule, "lastAccessedTime", time - 1000 * 300);
ArchaiusUtils.setProperty("cse.loadbalance.service.SessionStickinessRule.sessionTimeoutInSeconds", 9);
s = lb.chooseServer(invocation);
Assertions.assertEquals(server2, s);
ArchaiusUtils.setProperty("cse.loadbalance.service.SessionStickinessRule.successiveFailedTimes", 5);
lb.getLoadBalancerStats().incrementSuccessiveConnectionFailureCount(s);
lb.getLoadBalancerStats().incrementSuccessiveConnectionFailureCount(s);
lb.getLoadBalancerStats().incrementSuccessiveConnectionFailureCount(s);
lb.getLoadBalancerStats().incrementSuccessiveConnectionFailureCount(s);
lb.getLoadBalancerStats().incrementSuccessiveConnectionFailureCount(s);
s = lb.chooseServer(invocation);
Assertions.assertEquals(server, s);
}
}