提交 6dd19ac4 编写于 作者: A ainilife

Bug fix

上级 3f9d6fd9
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.dianping.cat</groupId>
<artifactId>abtest-sample</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>abtest-sample Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>com.dianping.cat</groupId>
<artifactId>cat-core</artifactId>
<version>0.5.2.10</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.unidal.framework</groupId>
<artifactId>test-framework</artifactId>
<version>2.0.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>abtest-sample</finalName>
</build>
</project>
package com.dianping.abtest.sample;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.dianping.cat.abtest.ABTest;
import com.dianping.cat.abtest.ABTestId;
import com.dianping.cat.abtest.ABTestManager;
public class ABTestSampleServlet extends HttpServlet {
private static final long serialVersionUID = -6472784609174835547L;
private ABTest m_abtest = ABTestManager.getTest(MyABTestId.CASE1);
@Override
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
if (m_abtest.isGroupA()) {
RequestDispatcher rd = getServletContext().getRequestDispatcher("/index2.jsp");
rd.forward(request, response);
// Cat.logMetric(...);
} else {
RequestDispatcher rd = getServletContext().getRequestDispatcher("/index.jsp");
rd.forward(request, response);
// Cat.logMetric(...);
}
}
public static enum MyABTestId implements ABTestId {
CASE1(0);
private int m_id;
private MyABTestId(int id) {
m_id = id;
}
@Override
public int getValue() {
return m_id;
}
}
}
package com.dianping.abtest.sample;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.unidal.helper.Splitters;
import org.unidal.lookup.util.StringUtils;
import com.dianping.cat.abtest.spi.ABTestContext;
import com.dianping.cat.abtest.spi.ABTestEntity;
import com.dianping.cat.abtest.spi.ABTestGroupStrategy;
public class IPDistributionStrategy implements ABTestGroupStrategy {
public static final String ID = "ip-distribution";
public IPDistributionStrategy(){
System.out.println("new " + ID + " created");
}
@Override
public void apply(ABTestContext ctx) {
ABTestEntity entity = ctx.getEntity();
String config = entity.getGroupStrategyConfiguration();
List<String> ips = Splitters.by(',').trim().split(config);
HttpServletRequest req = ctx.getHttpServletRequest();
String address = getRemoteAddr(req);
for (String ip : ips) {
if (ip.equals(address)) {
ctx.setGroupName("A");
return;
}
}
}
public String getRemoteAddr(HttpServletRequest req) {
String ip = req.getHeader("X-Forwarded-For");
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = req.getHeader("Proxy-Client-IP");
}
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = req.getHeader("WL-Proxy-Client-IP");
}
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = req.getHeader("HTTP_CLIENT_IP");
}
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = req.getHeader("HTTP_X_FORWARDED_FOR");
}
if (StringUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
ip = req.getRemoteAddr();
if(ip.equals("127.0.0.1")){
ip = IPUtils.getFirstNoLoopbackIP4Address();
}
}
return ip;
}
}
package com.dianping.abtest.sample;
/**
* Project: puma-server
*
* File Created at 2012-7-24
* $Id$
*
* Copyright 2010 dianping.com.
* All rights reserved.
*
* This software is the confidential and proprietary information of
* Dianping Company. ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with dianping.com.
*/
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
/**
* @author Leo Liang
*
*/
public final class IPUtils {
private IPUtils() {
}
/**
* 获取第一个no loop address
*
* @return first no loop address, or null if not exists
*/
public static String getFirstNoLoopbackIP4Address() {
Collection<String> allNoLoopbackIP4Addresses = getNoLoopbackIP4Addresses();
if (allNoLoopbackIP4Addresses.isEmpty()) {
return null;
}
return allNoLoopbackIP4Addresses.iterator().next();
}
public static Collection<String> getNoLoopbackIP4Addresses() {
Collection<String> noLoopbackIP4Addresses = new ArrayList<String>();
Collection<InetAddress> allInetAddresses = getAllHostAddress();
for (InetAddress address : allInetAddresses) {
if (!address.isLoopbackAddress() && !address.isSiteLocalAddress()
&& !Inet6Address.class.isInstance(address)) {
noLoopbackIP4Addresses.add(address.getHostAddress());
}
}
if (noLoopbackIP4Addresses.isEmpty()) {
// 降低过滤标准,将site local address纳入结果
for (InetAddress address : allInetAddresses) {
if (!address.isLoopbackAddress() && !Inet6Address.class.isInstance(address)) {
noLoopbackIP4Addresses.add(address.getHostAddress());
}
}
}
return noLoopbackIP4Addresses;
}
public static Collection<InetAddress> getAllHostAddress() {
try {
Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
Collection<InetAddress> addresses = new ArrayList<InetAddress>();
while (networkInterfaces.hasMoreElements()) {
NetworkInterface networkInterface = networkInterfaces.nextElement();
Enumeration<InetAddress> inetAddresses = networkInterface.getInetAddresses();
while (inetAddresses.hasMoreElements()) {
InetAddress inetAddress = inetAddresses.nextElement();
addresses.add(inetAddress);
}
}
return addresses;
} catch (SocketException e) {
throw new RuntimeException(e.getMessage(), e);
}
}
}
\ No newline at end of file
Manifest-Version: 1.0
Class-Path:
Main-Class: com.dianping.cat.Server
<config mode="client" xmlns:xsi="http://www.w3.org/2001/XMLSchema" xsi:noNamespaceSchemaLocation="config.xsd">
<domain id="Cat"/>
</config>
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="config" type="ConfigType" />
<xs:complexType name="ConfigType">
<xs:sequence>
<xs:element name="base-log-dir" type="xs:string" minOccurs="0" maxOccurs="1" />
<xs:element name="servers">
<xs:complexType>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="server" type="ServerType" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element minOccurs="0" maxOccurs="unbounded" name="domain" type="DomainType" />
<xs:element name="bind" type="BindType" minOccurs="0" maxOccurs="1" />
<xs:element name="properties">
<xs:complexType>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="property" type="PropertyType" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="mode" type="xs:string" use="required" />
</xs:complexType>
<xs:complexType name="ServerType">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="ip" type="xs:string" />
<xs:attribute name="port" type="xs:int" default="2280" />
<xs:attribute name="enabled" type="xs:boolean" default="true" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="DomainType">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="id" type="xs:string" />
<xs:attribute name="ip" type="xs:string" />
<xs:attribute name="enabled" type="xs:boolean" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="BindType">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="ip" type="xs:string" />
<xs:attribute name="port" type="xs:string" default="2280" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="PropertyType">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="name" type="xs:string" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:schema>
<web-app>
<display-name>Archetype Created Web Application</display-name>
<listener>
<listener-class>com.dianping.cat.servlet.CatListener</listener-class>
</listener>
<filter>
<filter-name>cat-filter</filter-name>
<filter-class>com.dianping.cat.servlet.CatFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cat-filter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<servlet>
<servlet-name>ABTestSampleServlet</servlet-name>
<servlet-class>com.dianping.abtest.sample.ABTestSampleServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ABTestSampleServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
<html>
<body>
<h2>Hello World!</h2>
</body>
</html>
<html>
<body>
<h2>Congratulation!</h2>
</body>
</html>
package com.dianping.abtest.sample;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.unidal.test.jetty.JettyServer;
@RunWith(JUnit4.class)
public class ABTestServer extends JettyServer {
public static void main(String[] args) throws Exception {
ABTestServer server = new ABTestServer();
System.setProperty("devMode", "true");
server.startServer();
server.startWebApp();
server.stopServer();
}
@Before
public void before() throws Exception {
System.setProperty("devMode", "true");
super.startServer();
}
@Override
protected String getContextPath() {
return "/abtest-sample";
}
@Override
protected int getServerPort() {
return 8081;
}
@Test
public void startWebApp() throws Exception {
// open the page in the default browser
display("/abtest-sample");
waitForAnyKey();
}
}
package com.dianping.abtest.sample;
import java.util.ArrayList;
import java.util.List;
import org.unidal.lookup.configuration.AbstractResourceConfigurator;
import org.unidal.lookup.configuration.Component;
import com.dianping.cat.abtest.spi.ABTestGroupStrategy;
public class ABTestServerConfigurator extends AbstractResourceConfigurator {
@Override
public List<Component> defineComponents() {
List<Component> all = new ArrayList<Component>();
all.add(C(ABTestGroupStrategy.class, IPDistributionStrategy.ID, IPDistributionStrategy.class)
.is(PER_LOOKUP));
return all;
}
@Override
protected Class<?> getTestClass() {
return ABTestServer.class;
}
public static void main(String[] args) {
generatePlexusComponentsXmlFile(new ABTestServerConfigurator());
}
}
<plexus>
<components>
<component>
<role>com.dianping.cat.abtest.spi.ABTestGroupStrategy</role>
<role-hint>ip-distribution</role-hint>
<implementation>com.dianping.abtest.sample.IPDistributionStrategy</implementation>
<instantiation-strategy>per-lookup</instantiation-strategy>
</component>
</components>
</plexus>
......@@ -2,9 +2,11 @@ package com.dianping.cat.abtest;
import javax.servlet.http.HttpServletRequest;
import org.codehaus.plexus.PlexusContainer;
import org.unidal.lookup.ContainerLoader;
import com.dianping.cat.abtest.internal.DefaultABTest;
import com.dianping.cat.abtest.repository.ABTestEntityRepository;
import com.dianping.cat.abtest.spi.internal.ABTestContextManager;
public final class ABTestManager {
......@@ -22,7 +24,13 @@ public final class ABTestManager {
if (s_contextManager == null) {
try {
// it could be time-consuming due to load entities from the repository, i.e. database.
s_contextManager = ContainerLoader.getDefaultContainer().lookup(ABTestContextManager.class);
PlexusContainer container = ContainerLoader.getDefaultContainer();
s_contextManager = container.lookup(ABTestContextManager.class);
ABTestEntityRepository repository = container.lookup(ABTestEntityRepository.class);
repository.start();
} catch (Exception e) {
throw new RuntimeException("Error when initializing ABTestContextManager!", e);
}
......
package com.dianping.cat.abtest.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface UserID {
String[] value();
}
......@@ -5,7 +5,9 @@ import java.util.Map;
import com.dianping.cat.abtest.spi.ABTestEntity;
public interface ABTestEntityRepository {
public Map<Integer, ABTestEntity> getAllEntities();
public Map<Integer, ABTestEntity> getEntities();
public void start();
}
......@@ -5,10 +5,13 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.codehaus.plexus.logging.LogEnabled;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
import org.codehaus.plexus.util.StringUtils;
import org.unidal.helper.Splitters;
import org.unidal.lookup.ContainerHolder;
import org.unidal.lookup.annotation.Inject;
import org.unidal.socket.MessageInboundHandler;
import org.unidal.socket.udp.UdpSocket;
......@@ -20,37 +23,57 @@ import com.dianping.cat.abtest.model.entity.Run;
import com.dianping.cat.abtest.model.transform.BaseVisitor;
import com.dianping.cat.abtest.model.transform.DefaultSaxParser;
import com.dianping.cat.abtest.spi.ABTestEntity;
import com.dianping.cat.abtest.spi.ABTestGroupStrategy;
import com.dianping.cat.configuration.ClientConfigManager;
import com.dianping.cat.message.Heartbeat;
import com.dianping.cat.message.Message;
public class DefaultABTestEntityRepository implements ABTestEntityRepository, Initializable {
public class DefaultABTestEntityRepository extends ContainerHolder implements ABTestEntityRepository, Initializable,
LogEnabled, MessageInboundHandler<ProtocolMessage> {
@Inject
private ClientConfigManager m_configManager;
@Inject
private InetSocketAddress m_address = new InetSocketAddress("228.0.0.3", 2283);
@Inject
private Logger m_logger;
private UdpSocket m_socket;
private String m_domain;
private Map<Integer, ABTestEntity> m_entities = new HashMap<Integer, ABTestEntity>();
private Map<String, ABTestGroupStrategy> m_strategies = new HashMap<String, ABTestGroupStrategy>();
@Override
public Map<Integer, ABTestEntity> getAllEntities() {
public Map<Integer, ABTestEntity> getEntities() {
return m_entities;
}
@Override
public void initialize() throws InitializationException {
m_domain = m_configManager.getFirstDomain().getId();
}
// for test purpose
void setDomain(String domain) {
m_domain = domain;
}
@Override
public void start() {
m_socket = new UdpSocket();
m_socket.setName("ABTest");
m_socket.setCodec(new ProtocolMessageCodec());
m_socket.onMessage(new ProtocolHandler());
m_socket.onMessage(this);
m_socket.listenOn(m_address);
System.out.println("ABTestRepository init...");
ProtocolMessage hi = new ProtocolMessage();
hi.setName(ProtocolNames.HI);
hi.addHeader(ProtocolNames.HEARTBEAT, m_domain);
m_socket.send(hi);
......@@ -66,33 +89,45 @@ public class DefaultABTestEntityRepository implements ABTestEntityRepository, In
m_address = new InetSocketAddress(host, Integer.parseInt(port));
}
class ProtocolHandler implements MessageInboundHandler<ProtocolMessage> {
@Override
public void handle(ProtocolMessage message) {
String name = message.getName();
if (ProtocolNames.HEARTBEAT.equalsIgnoreCase(name)) {
String content = message.getContent();
if (StringUtils.isNotBlank(content)) {
try {
AbtestModel abtest = DefaultSaxParser.parse(content);
ABTestVisitor visitor = new ABTestVisitor();
abtest.accept(visitor);
m_entities = visitor.getEntities();
} catch (Exception e) {
Cat.logError(e);
}
@Override
public void handle(ProtocolMessage message) {
String name = message.getName();
if (ProtocolNames.HEARTBEAT.equalsIgnoreCase(name)) {
Heartbeat h = Cat.newHeartbeat("abtest-heartbeat", message.getName()); // TODO .getFrom()
h.addData(message.toString());
h.setStatus(Message.SUCCESS);
h.complete();
String content = message.getContent();
if (StringUtils.isNotBlank(content)) {
try {
AbtestModel abtest = DefaultSaxParser.parse(content);
ABTestVisitor visitor = new ABTestVisitor(m_domain);
abtest.accept(visitor);
//switch the entities
m_entities = visitor.getEntities();
} catch (Exception e) {
Cat.logError(e);
}
}
} else {
m_logger.warn(String.format("Unknown command(%s) found in %s!", name, message));
}
}
class ABTestVisitor extends BaseVisitor {
private String m_domain;
private Map<Integer, ABTestEntity> m_entities;
public ABTestVisitor() {
public ABTestVisitor(String domain) {
m_domain = domain;
m_entities = new HashMap<Integer, ABTestEntity>();
}
......@@ -101,15 +136,47 @@ public class DefaultABTestEntityRepository implements ABTestEntityRepository, In
for (Run run : _case.getRuns()) {
// filter abtest-entities by domain
if (run.getDomains() != null && run.getDomains().contains(m_domain)) {
ABTestEntity abTestEntity = new ABTestEntity(_case, run);
m_entities.put(abTestEntity.getId(), abTestEntity);
ABTestEntity entity = new ABTestEntity(_case, run);
String strategyKey = String.format("%s+%s+%s", _case.getId(), entity.getGroupStrategyName(),
entity.getGroupStrategyConfiguration());
ABTestGroupStrategy strategy = m_strategies.get(strategyKey);
if (strategy != null) {
entity.setGroupStrategy(strategy);
} else {
try {
strategy = lookup(ABTestGroupStrategy.class, entity.getGroupStrategyName());
entity.setGroupStrategy(strategy);
m_strategies.put(strategyKey, strategy);
} catch (Exception e) {
Cat.logError(e);
ABTestEntity origin = DefaultABTestEntityRepository.this.m_entities.get(_case.getId());
if (origin != null) {
entity = origin;
} else {
entity.setDisabled(true);
}
}
}
m_entities.put(entity.getId(), entity);
}
}
}
public Map<Integer, ABTestEntity> getEntities() {
return m_entities;
}
return m_entities;
}
}
@Override
public void enableLogging(Logger logger) {
m_logger = logger;
}
}
......@@ -100,33 +100,50 @@ public class ABTestEntity {
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((m_groupStrategy == null) ? 0 : m_groupStrategy.hashCode());
result = prime * result + ((m_groupStrategyName == null) ? 0 : m_groupStrategyName.hashCode());
result = prime * result + m_id;
result = prime * result + ((m_run == null) ? 0 : m_run.hashCode());
return result;
}
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((m_groupStrategyName == null) ? 0 : m_groupStrategyName.hashCode());
result = prime * result + m_id;
result = prime * result + ((m_name == null) ? 0 : m_name.hashCode());
result = prime * result + ((m_run == null) ? 0 : m_run.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ABTestEntity other = (ABTestEntity) obj;
if (getId() != other.getId())
return false;
return true;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ABTestEntity other = (ABTestEntity) obj;
if (m_groupStrategyName == null) {
if (other.m_groupStrategyName != null)
return false;
} else if (!m_groupStrategyName.equals(other.m_groupStrategyName))
return false;
if (m_id != other.m_id)
return false;
if (m_name == null) {
if (other.m_name != null)
return false;
} else if (!m_name.equals(other.m_name))
return false;
if (m_run == null) {
if (other.m_run != null)
return false;
} else if (!m_run.equals(other.m_run))
return false;
return true;
}
@Override
public String toString() {
return "ABTestEntity [m_id=" + m_id + ", m_groupStrategyName=" + m_groupStrategyName + ", m_run=" + m_run
+ ", m_groupStrategy=" + m_groupStrategy + "]";
}
public String toString() {
return "ABTestEntity [m_id=" + m_id + ", m_name=" + m_name + ", m_groupStrategyName=" + m_groupStrategyName
+ ", m_run=" + m_run +"]";
}
}
\ No newline at end of file
......@@ -21,14 +21,14 @@ public class DefaultABTestEntityManager extends ContainerHolder implements ABTes
@Override
public ABTestEntity getEntity(ABTestId id) {
ABTestEntity entity = m_repository.getAllEntities().get(id.getValue());
ABTestEntity entity = m_repository.getEntities().get(id.getValue());
if (entity == null) {
entity = new ABTestEntity();
entity.setId(id.getValue());
entity.setDisabled(true);
m_repository.getAllEntities().put(id.getValue(), entity);
m_repository.getEntities().put(id.getValue(), entity);
}
return entity;
......@@ -36,7 +36,7 @@ public class DefaultABTestEntityManager extends ContainerHolder implements ABTes
public List<ABTestEntity> getEntityList() {
List<ABTestEntity> entitiesList = new ArrayList<ABTestEntity>();
for (ABTestEntity entity : m_repository.getAllEntities().values()) {
for (ABTestEntity entity : m_repository.getEntities().values()) {
entitiesList.add(entity);
}
return entitiesList;
......@@ -44,7 +44,7 @@ public class DefaultABTestEntityManager extends ContainerHolder implements ABTes
@Override
public void initialize() throws InitializationException {
for (ABTestEntity entity : m_repository.getAllEntities().values()) {
for (ABTestEntity entity : m_repository.getEntities().values()) {
try {
ABTestGroupStrategy groupStrategy = lookup(ABTestGroupStrategy.class, entity.getGroupStrategyName());
......
package com.dianping.cat.abtest.repository;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import junit.framework.Assert;
import org.junit.Test;
import org.unidal.helper.Splitters;
import org.unidal.lookup.ComponentTestCase;
import com.dianping.cat.abtest.model.entity.AbtestModel;
import com.dianping.cat.abtest.model.entity.Case;
import com.dianping.cat.abtest.model.entity.Run;
import com.dianping.cat.abtest.spi.ABTestEntity;
public class ABTestRepositoryTest extends ComponentTestCase {
private void checkHandler(String expected, String... keys) throws Exception {
DefaultABTestEntityRepository repository = (DefaultABTestEntityRepository) lookup(ABTestEntityRepository.class);
ProtocolMessage message = new ProtocolMessage();
repository.setDomain("domain2");
message.setName("heartbeat");
AbtestModel abtest = new AbtestModel();
for (String key : keys) {
List<String> parts = Splitters.by(':').trim().split(key);
int index = 0;
int id = Integer.parseInt(parts.get(index++));
String name = parts.get(index++);
List<String> domains = Splitters.by(',').noEmptyItem().trim().split(parts.get(index++));
Case _case = new Case(id).setName(name);
_case.getDomains().addAll(domains);
Run run = new Run(id);
run.getDomains().addAll(domains);
_case.addRun(run);
abtest.addCase(_case);
}
message.setContent(abtest.toString());
repository.handle(message);
StringBuilder sb = new StringBuilder(1024);
List<ABTestEntity> values = new ArrayList<ABTestEntity>(repository.getEntities().values());
boolean first = true;
Collections.sort(values, new Comparator<ABTestEntity>() {
@Override
public int compare(ABTestEntity o1, ABTestEntity o2) {
return o1.getName().compareTo(o1.getName());
}
});
for (ABTestEntity entity : values) {
if (first) {
first = false;
} else {
sb.append(',');
}
sb.append(entity.getName());
}
Assert.assertEquals(expected, sb.toString());
}
@Test
public void testHandler() throws Exception {
checkHandler("case2,case3", "1:case1:domain1", "2:case2:domain2", "3:case3:domain2,domain3");
}
}
......@@ -10,7 +10,7 @@ import org.unidal.lookup.ComponentTestCase;
import com.dianping.cat.abtest.spi.ABTestEntity;
public class DefaultABTestEntityManagerTest extends ComponentTestCase {
public class ABTestEntityManagerTest extends ComponentTestCase {
private static final String PATTERN = "yyyy-MM-dd hh:mm:ss";
......
<heartbeat>
<ip>192.168.0.1</ip> <!-- 看看能不能主动获得IP -->
<domain>tuangou</domain>
<whoami>client/server</whoami>
<entities>
<entity id="1001" name="Mock1" start-date="2013-04-10 17:00:00"
end-date="2013-12-30 18:00:00" disabled="false">
<description>This is a mock ABTest for test</description>
<group-strategy name="roundrobin">
<strategy-config>
<users>
<id>1001</id>
<id>1002</id>
<id></id>
</users>
<age>
<begin>20</begin>
<end>40</end>
</age>
<cookies>
<cookie>cityId</cookie>
<cookie>gender</cookie>
<cookie></cookie>
</cookies>
</strategy-config>
</group-strategy>
<domain>Cat</domain>
<domain>TuanGouWeb</domain>
</entity>
</entities>
<configuration><![CDATA[This is the configuration]]></configuration>
</heartbeat>
\ No newline at end of file
<strategy-config>
<users>
<id>1001</id>
<id>1002</id>
<id></id>
</users>
<age>
<begin>20</begin>
<end>40</end>
</age>
<cookies>
<cookie>cityId</cookie>
<cookie>gender</cookie>
<cookie></cookie>
</cookies>
</strategy-config>
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册