/*
* Copyright 2009-2016 Weibo, Inc.
*
* 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 com.weibo.api.motan.cluster.loadbalance;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.junit.Assert;
import org.junit.Test;
import com.weibo.api.motan.mock.MockReferer;
import com.weibo.api.motan.rpc.Referer;
/**
* @author maijunsheng
* @version 创建时间:2013-6-14
*
*/
@SuppressWarnings({"unchecked", "rawtypes"})
public class ActiveWeightLoadBalanceTest {
private int lowActive = 1;
private int smallSize = 5;
private int largeSize = 15;
private int testLoop = 100;
@Test
public void testSelect() {
for (int i = 0; i < testLoop; i++) {
allAvailableCluster(smallSize);
allAvailableCluster(largeSize);
partOfUnAvailableCluster(smallSize, 1);
partOfUnAvailableCluster(smallSize, smallSize / 2);
partOfUnAvailableCluster(smallSize, smallSize - 1);
partOfUnAvailableCluster(largeSize, 1);
partOfUnAvailableCluster(largeSize, largeSize / 2);
partOfUnAvailableCluster(largeSize, largeSize - 1);
allUnAvailableCluster(smallSize);
allUnAvailableCluster(largeSize);
}
}
private void allAvailableCluster(int refererSize) {
ActiveWeightLoadBalance balance = createBalance(refererSize, 0);
Referer referer = balance.select(null);
Assert.assertNotNull(referer);
if (refererSize <= ActiveWeightLoadBalance.MAX_REFERER_COUNT) {
Assert.assertEquals(referer.activeRefererCount(), lowActive);
} else {
Assert.assertTrue(refererSize - ActiveWeightLoadBalance.MAX_REFERER_COUNT + 1 >= referer.activeRefererCount());
}
List<Referer> referersHolder = new ArrayList<Referer>();
balance.selectToHolder(null, referersHolder);
if (refererSize <= ActiveWeightLoadBalance.MAX_REFERER_COUNT) {
Assert.assertEquals(referersHolder.size(), refererSize);
check(referersHolder);
} else {
Assert.assertEquals(referersHolder.size(), ActiveWeightLoadBalance.MAX_REFERER_COUNT);
check(referersHolder);
}
}
private void partOfUnAvailableCluster(int refererSize, int unAvailableSize) {
if (refererSize <= unAvailableSize) {
throw new RuntimeException("refereSize: " + refererSize + " unAvailableSize: " + unAvailableSize);
}
ActiveWeightLoadBalance balance = createBalance(refererSize, unAvailableSize);
Referer referer = balance.select(null);
Assert.assertNotNull(referer);
Assert.assertTrue(referer.isAvailable());
int availableSize = (refererSize - unAvailableSize);
if (availableSize <= ActiveWeightLoadBalance.MAX_REFERER_COUNT) {
Assert.assertTrue(referer.activeRefererCount() - lowActive - unAvailableSize <= 0);
} else {
Assert.assertTrue(refererSize - ActiveWeightLoadBalance.MAX_REFERER_COUNT + unAvailableSize +1 >= referer.activeRefererCount());
}
List<Referer> referersHolder = new ArrayList<Referer>();
balance.selectToHolder(null, referersHolder);
if (availableSize <= ActiveWeightLoadBalance.MAX_REFERER_COUNT) {
Assert.assertEquals(referersHolder.size(), availableSize);
check(referersHolder);
} else {
Assert.assertEquals(referersHolder.size(), ActiveWeightLoadBalance.MAX_REFERER_COUNT);
check(referersHolder);
}
}
private static void check(List<Referer> referersHolder) {
int prefix = 0;
for (Referer aReferersHolder : referersHolder) {
Assert.assertTrue(aReferersHolder.isAvailable());
Assert.assertTrue(aReferersHolder.activeRefererCount() > prefix);
prefix = aReferersHolder.activeRefererCount();
}
}
private void allUnAvailableCluster(int refererSize) {
ActiveWeightLoadBalance balance = createBalance(refererSize, refererSize);
try {
balance.select(null);
Assert.assertTrue(false);
} catch (Exception e) {
// 应该有异常抛出
Assert.assertTrue(true);
}
try {
List<Referer> referersHolder = new ArrayList<Referer>();
balance.selectToHolder(null, referersHolder);
Assert.assertTrue(false);
} catch (Exception e) {
// 应该有异常抛出
Assert.assertTrue(true);
}
}
private ActiveWeightLoadBalance createBalance(int refererSize, int unAvailableSize) {
List<MockReferer> referers = new ArrayList<MockReferer>();
for (int i = 0; i < refererSize; i++) {
MockReferer referer = new MockReferer();
referer.active = lowActive + i;
referers.add(referer);
}
Collections.shuffle(referers);
for (int i = 0; i < unAvailableSize; i++) {
referers.get(i).available = false;
}
ActiveWeightLoadBalance balance = new ActiveWeightLoadBalance();
balance.onRefresh(referers);
return balance;
}
public static void main(String[] args) {
List<MockReferer> referers = new ArrayList<MockReferer>();
for (int i = 0; i < 20; i++) {
MockReferer referer = new MockReferer();
referer.active = 1 + i;
referers.add(referer);
}
for (int j = 0; j < 20; j++) {
List<Referer> copy = new ArrayList<Referer>(referers);
Collections.shuffle(copy);
String buffer = "[";
for (Referer referer : copy) {
buffer += referer.activeRefererCount() + ",";
}
Collections.sort(copy, new ActiveWeightLoadBalance.LowActivePriorityComparator());
int prefix = -1;
for (Referer aCopy : copy) {
if (aCopy.activeRefererCount() <= prefix) {
throw new RuntimeException("bug bug bug");
}
prefix = aCopy.activeRefererCount();
}
}
}
}