package org.springframework.cloud.netflix.eureka.server;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.cloud.netflix.eureka.server.InstanceRegistryTest.TestApplication;
import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceCanceledEvent;
import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceRegisteredEvent;
import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceRenewedEvent;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.EventListener;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.appinfo.LeaseInfo;
import com.netflix.discovery.shared.Application;
import com.netflix.eureka.registry.PeerAwareInstanceRegistry;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.doReturn;
/**
* @author Bartlomiej Slota
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = TestApplication.class,
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
value = {"spring.application.name=eureka", "logging.level.org.springframework."
+ "cloud.netflix.eureka.server.InstanceRegistry=DEBUG"})
public class InstanceRegistryTest {
private static final String APP_NAME = "MY-APP-NAME";
private static final String HOST_NAME = "my-host-name";
private static final String INSTANCE_ID = "my-host-name:8008";
private static final int PORT = 8008;
@SpyBean(PeerAwareInstanceRegistry.class)
private InstanceRegistry instanceRegistry;
@Before
public void setup() {
this.testEvents.applicationEvents.clear();
}
@Autowired
private TestEvents testEvents;
@Test
public void testRegister() throws Exception {
// creating instance info
final LeaseInfo leaseInfo = getLeaseInfo();
final InstanceInfo instanceInfo = getInstanceInfo(APP_NAME, HOST_NAME, INSTANCE_ID, PORT, leaseInfo);
// calling tested method
instanceRegistry.register(instanceInfo, false);
// event of proper type is registered
assertEquals(1, this.testEvents.applicationEvents.size());
assertTrue(this.testEvents.applicationEvents.get(0) instanceof EurekaInstanceRegisteredEvent);
// event details are correct
final EurekaInstanceRegisteredEvent registeredEvent =
(EurekaInstanceRegisteredEvent) (this.testEvents.applicationEvents.get(0));
assertEquals(instanceInfo, registeredEvent.getInstanceInfo());
assertEquals(leaseInfo.getDurationInSecs(), registeredEvent.getLeaseDuration());
assertEquals(instanceRegistry, registeredEvent.getSource());
assertFalse(registeredEvent.isReplication());
}
@Test
public void testDefaultLeaseDurationRegisterEvent() throws Exception {
// creating instance info
final InstanceInfo instanceInfo = getInstanceInfo(APP_NAME, HOST_NAME, INSTANCE_ID, PORT, null);
// calling tested method
instanceRegistry.register(instanceInfo, false);
// instance info duration is set to default
final EurekaInstanceRegisteredEvent registeredEvent =
(EurekaInstanceRegisteredEvent) (this.testEvents.applicationEvents.get(0));
assertEquals(LeaseInfo.DEFAULT_LEASE_DURATION,
registeredEvent.getLeaseDuration());
}
@Test
public void testInternalCancel() throws Exception {
// calling tested method
instanceRegistry.internalCancel(APP_NAME, HOST_NAME, false);
// event of proper type is registered
assertEquals(1, this.testEvents.applicationEvents.size());
assertTrue(this.testEvents.applicationEvents.get(0) instanceof EurekaInstanceCanceledEvent);
// event details are correct
final EurekaInstanceCanceledEvent registeredEvent =
(EurekaInstanceCanceledEvent) (this.testEvents.applicationEvents.get(0));
assertEquals(APP_NAME, registeredEvent.getAppName());
assertEquals(HOST_NAME, registeredEvent.getServerId());
assertEquals(instanceRegistry, registeredEvent.getSource());
assertFalse(registeredEvent.isReplication());
}
@Test
public void testRenew() throws Exception {
//Creating two instances of the app
final InstanceInfo instanceInfo1 = getInstanceInfo(APP_NAME, HOST_NAME, INSTANCE_ID, PORT, null);
final InstanceInfo instanceInfo2 = getInstanceInfo(APP_NAME, HOST_NAME, "my-host-name:8009", 8009, null);
// creating application list with an app having two instances
final Application application = new Application(APP_NAME, Arrays.asList(instanceInfo1, instanceInfo2));
final List<Application> applications = new ArrayList<>();
applications.add(application);
// stubbing applications list
doReturn(applications).when(instanceRegistry).getSortedApplications();
// calling tested method
instanceRegistry.renew(APP_NAME, INSTANCE_ID, false);
instanceRegistry.renew(APP_NAME, "my-host-name:8009", false);
// event of proper type is registered
assertEquals(2, this.testEvents.applicationEvents.size());
assertTrue(this.testEvents.applicationEvents.get(0) instanceof EurekaInstanceRenewedEvent);
assertTrue(this.testEvents.applicationEvents.get(1) instanceof EurekaInstanceRenewedEvent);
// event details are correct
final EurekaInstanceRenewedEvent event1 = (EurekaInstanceRenewedEvent)
(this.testEvents.applicationEvents.get(0));
assertEquals(APP_NAME, event1.getAppName());
assertEquals(INSTANCE_ID, event1.getServerId());
assertEquals(instanceRegistry, event1.getSource());
assertEquals(instanceInfo1, event1.getInstanceInfo());
assertFalse(event1.isReplication());
final EurekaInstanceRenewedEvent event2 = (EurekaInstanceRenewedEvent)
(this.testEvents.applicationEvents.get(1));
assertEquals(instanceInfo2, event2.getInstanceInfo());
}
@Configuration
@EnableAutoConfiguration
@EnableEurekaServer
protected static class TestApplication {
@Bean
public TestEvents testEvents() {
return new TestEvents();
}
public static void main(String[] args) {
new SpringApplicationBuilder(TestApplication.class).run(args);
}
}
protected static class TestEvents {
public final List<ApplicationEvent> applicationEvents = new LinkedList<>();
@EventListener(EurekaInstanceRegisteredEvent.class)
public void onEvent(EurekaInstanceRegisteredEvent event) {
this.applicationEvents.add(event);
}
@EventListener(EurekaInstanceCanceledEvent.class)
public void onEvent(EurekaInstanceCanceledEvent event) {
this.applicationEvents.add(event);
}
@EventListener(EurekaInstanceRenewedEvent.class)
public void onEvent(EurekaInstanceRenewedEvent event) {
this.applicationEvents.add(event);
}
}
private LeaseInfo getLeaseInfo() {
LeaseInfo.Builder leaseBuilder = LeaseInfo.Builder.newBuilder();
leaseBuilder.setRenewalIntervalInSecs(10);
leaseBuilder.setDurationInSecs(15);
return leaseBuilder.build();
}
private InstanceInfo getInstanceInfo(String appName, String hostName,
String instanceId, int port, LeaseInfo leaseInfo) {
InstanceInfo.Builder builder = InstanceInfo.Builder.newBuilder();
builder.setAppName(appName);
builder.setHostName(hostName);
builder.setInstanceId(instanceId);
builder.setPort(port);
builder.setLeaseInfo(leaseInfo);
return builder.build();
}
}