package com.workshare.msnos.usvc.api.routing; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.util.ArrayList; import java.util.List; import org.junit.Test; import org.mockito.Mockito; import com.workshare.msnos.core.geo.Location; import com.workshare.msnos.core.geo.Location.Place; import com.workshare.msnos.usvc.Microservice; import com.workshare.msnos.usvc.api.routing.strategies.LocationBasedStrategy; public class LocationBasedStrategyTest { private static final Location EUROPE = new Location(continent("EU"), null, null, null); private static final Location ITALY = new Location(continent("EU"), country("IT"), null, null); private static final Location PARIS = new Location(continent("EU"), country("FR"), region("RS"), city("PA")); private static final Location MILAN = new Location(continent("EU"), country("IT"), region("LO"), city("MI")); private static final Location TURIN = new Location(continent("EU"), country("IT"), region("PI"), city("TO")); private static final Location ASTI = new Location(continent("EU"), country("IT"), region("PI"), city("AT")); private static final Location CUNEO = new Location(continent("EU"), country("IT"), region("PI"), city("CN")); private static final Location ASIA = new Location(continent("AS"), null, null, null); private static final Location KONG = new Location(continent("AS"), country("HK"), region("HK"), city("HK")); @Test public void shouldSelectAllWhenNothingInTheSameContinent() { Microservice micro = Mockito.mock(Microservice.class); when(micro.getLocation()).thenReturn(ASIA); List<ApiEndpoint> endpoints = makeEndpoints(PARIS, MILAN, TURIN, CUNEO); List<ApiEndpoint> result = new LocationBasedStrategy().select(micro, endpoints); assertEquals(result, endpoints); } @Test public void shouldSelectSameContinent() { Microservice micro = Mockito.mock(Microservice.class); when(micro.getLocation()).thenReturn(EUROPE); List<ApiEndpoint> endpoints = makeEndpoints(PARIS, MILAN, KONG, ASIA); List<ApiEndpoint> result = new LocationBasedStrategy().select(micro, endpoints); assertEquals(2, result.size()); assertResultContainsLocation(result, PARIS); assertResultContainsLocation(result, MILAN); } @Test public void shouldSelectSameCountry() { Microservice micro = Mockito.mock(Microservice.class); when(micro.getLocation()).thenReturn(ITALY); List<ApiEndpoint> endpoints = makeEndpoints(PARIS, MILAN, TURIN, ASTI, CUNEO, KONG, ASIA); List<ApiEndpoint> result = new LocationBasedStrategy().select(micro, endpoints); assertEquals(4, result.size()); assertResultContainsLocation(result, CUNEO); assertResultContainsLocation(result, ASTI); assertResultContainsLocation(result, TURIN); assertResultContainsLocation(result, MILAN); } @Test public void shouldSelectSameRegion() { Microservice micro = Mockito.mock(Microservice.class); when(micro.getLocation()).thenReturn(TURIN); List<ApiEndpoint> endpoints = makeEndpoints(PARIS, MILAN, ASTI, CUNEO, KONG, ASIA); List<ApiEndpoint> result = new LocationBasedStrategy().select(micro, endpoints); assertEquals(2, result.size()); assertResultContainsLocation(result, CUNEO); assertResultContainsLocation(result, ASTI); } @Test public void shouldSelectSameCity() { Microservice micro = Mockito.mock(Microservice.class); when(micro.getLocation()).thenReturn(TURIN); List<ApiEndpoint> endpoints = makeEndpoints(PARIS, MILAN, ASTI, CUNEO, KONG, ASIA, TURIN); List<ApiEndpoint> result = new LocationBasedStrategy().select(micro, endpoints); assertEquals(1, result.size()); assertResultContainsLocation(result, TURIN); } @Test public void shouldSelectAllIfTargetHasNoLocation() { Microservice micro = Mockito.mock(Microservice.class); when(micro.getLocation()).thenReturn(null); List<ApiEndpoint> endpoints = makeEndpoints(PARIS, MILAN, TURIN, CUNEO); List<ApiEndpoint> result = new LocationBasedStrategy().select(micro, endpoints); assertEquals(result, endpoints); } @Test public void shouldSelectAllIfTargetHasLocationUnknown() { Microservice micro = Mockito.mock(Microservice.class); when(micro.getLocation()).thenReturn(Location.UNKNOWN); List<ApiEndpoint> endpoints = makeEndpoints(PARIS, MILAN, TURIN, CUNEO); List<ApiEndpoint> result = new LocationBasedStrategy().select(micro, endpoints); assertEquals(result, endpoints); } private void assertResultContainsLocation(List<ApiEndpoint> result, final Location location) { boolean found = false; for (ApiEndpoint api : result) { if (api.location().equals(location)) { found = true; break; } } assertTrue("Location "+location+" expected but not found", found); } private List<ApiEndpoint> makeEndpoints(Location... locations) { List<ApiEndpoint> result = new ArrayList<ApiEndpoint>(); for (Location location : locations) { ApiEndpoint endpoint = mock(ApiEndpoint.class); when(endpoint.location()).thenReturn(location); result.add(endpoint); } return result; } private static Place continent(String code) { return new Place(Place.Type.CONTINENT, code, code); } private static Place country(String code) { return new Place(Place.Type.COUNTRY, code, code); } private static Place region(String code) { return new Place(Place.Type.REGION, code, code); } private static Place city(String code) { return new Place(Place.Type.CITY, code, code); } }