You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficcontrol.apache.org by el...@apache.org on 2018/06/14 17:31:29 UTC
[trafficcontrol] 02/05: Implement Traffic Router unit tests for
geo-steering
This is an automated email from the ASF dual-hosted git repository.
elsloo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficcontrol.git
commit ea97ee6202d9d02ee51d87dbbbb5475c6f4b8a5e
Author: Rawlin Peters <ra...@comcast.com>
AuthorDate: Tue Mar 20 16:52:00 2018 -0600
Implement Traffic Router unit tests for geo-steering
---
.../core/ds/SteeringGeolocationComparator.java | 4 +-
.../traffic_router/core/ds/SteeringRegistry.java | 1 +
.../traffic_router/core/ds/SteeringTarget.java | 4 +
.../traffic_router/core/router/TrafficRouter.java | 8 +-
.../core/ds/SteeringGeolocationComparatorTest.java | 151 +++++++++++++++++++++
.../core/router/GeoSortSteeringResultsTest.java | 134 ++++++++++++++++++
6 files changed, 296 insertions(+), 6 deletions(-)
diff --git a/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/ds/SteeringGeolocationComparator.java b/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/ds/SteeringGeolocationComparator.java
index 5436dae..2dbe8d1 100644
--- a/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/ds/SteeringGeolocationComparator.java
+++ b/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/ds/SteeringGeolocationComparator.java
@@ -19,7 +19,6 @@ import java.util.Comparator;
import com.comcast.cdn.traffic_control.traffic_router.geolocation.Geolocation;
-// TODO: add unit tests for this class
public class SteeringGeolocationComparator implements Comparator<SteeringResult> {
private final Geolocation clientLocation;
@@ -29,6 +28,7 @@ public class SteeringGeolocationComparator implements Comparator<SteeringResult>
}
@Override
+ @SuppressWarnings({"PMD.CyclomaticComplexity"})
public int compare(final SteeringResult result1, final SteeringResult result2) {
final Geolocation originGeo1 = result1.getSteeringTarget().getGeolocation();
final Geolocation originGeo2 = result2.getSteeringTarget().getGeolocation();
@@ -63,7 +63,7 @@ public class SteeringGeolocationComparator implements Comparator<SteeringResult>
// different cache and origin locations, prefer shortest total distance
if (totalDistance1 != totalDistance2) {
- // TODO: if the difference is smaller than a certain threshold, still prefer the closer edge even though distance is greater?
+ // TODO: if the difference is smaller than a certain threshold/ratio, still prefer the closer edge even though distance is greater?
return Double.compare(totalDistance1, totalDistance2);
}
diff --git a/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/ds/SteeringRegistry.java b/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/ds/SteeringRegistry.java
index 2bf197b..0b9437a 100644
--- a/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/ds/SteeringRegistry.java
+++ b/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/ds/SteeringRegistry.java
@@ -33,6 +33,7 @@ public class SteeringRegistry {
private final Map<String, Steering> registry = new HashMap<String, Steering>();
private final ObjectMapper objectMapper = new ObjectMapper(new JsonFactory());
+ @SuppressWarnings({"PMD.CyclomaticComplexity", "PMD.AvoidDuplicateLiterals"})
public void update(final String json) {
Map<String, List<Steering>> m;
try {
diff --git a/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/ds/SteeringTarget.java b/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/ds/SteeringTarget.java
index d1a38df..c054ccd 100644
--- a/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/ds/SteeringTarget.java
+++ b/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/ds/SteeringTarget.java
@@ -102,6 +102,10 @@ public class SteeringTarget extends DefaultHashable {
return geolocation;
}
+ public void setGeolocation(final Geolocation geolocation) {
+ this.geolocation = geolocation;
+ }
+
@Override
@SuppressWarnings("PMD")
public boolean equals(Object o) {
diff --git a/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/router/TrafficRouter.java b/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/router/TrafficRouter.java
index 5f49865..c67455c 100644
--- a/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/router/TrafficRouter.java
+++ b/traffic_router/core/src/main/java/com/comcast/cdn/traffic_control/traffic_router/core/router/TrafficRouter.java
@@ -617,6 +617,7 @@ public class TrafficRouter {
return routeResult;
}
+ @SuppressWarnings({"PMD.NPathComplexity"})
private List<SteeringResult> getSteeringResults(final HTTPRequest request, final Track track, final DeliveryService entryDeliveryService) {
if (isTlsMismatch(request, entryDeliveryService)) {
@@ -633,7 +634,7 @@ public class TrafficRouter {
return null;
}
- List<SteeringResult> toBeRemoved = new ArrayList<>();
+ final List<SteeringResult> toBeRemoved = new ArrayList<>();
for (final SteeringResult steeringResult : steeringResults) {
final DeliveryService ds = steeringResult.getDeliveryService();
if (isTlsMismatch(request, ds)) {
@@ -851,7 +852,7 @@ public class TrafficRouter {
return steeringRegistry.get(deliveryService.getId()).isClientSteering();
}
- private Geolocation getClientLocationByCoverageZoneOrGeo(final String clientIP, final DeliveryService deliveryService) {
+ protected Geolocation getClientLocationByCoverageZoneOrGeo(final String clientIP, final DeliveryService deliveryService) {
Geolocation clientLocation;
final NetworkNode networkNode = getNetworkNode(clientIP);
if (networkNode != null && networkNode.getGeolocation() != null) {
@@ -866,8 +867,7 @@ public class TrafficRouter {
return deliveryService.supportLocation(clientLocation);
}
- // TODO: add unit test for this method
- private void geoSortSteeringResults(final List<SteeringResult> steeringResults, final String clientIP, final DeliveryService deliveryService) {
+ protected void geoSortSteeringResults(final List<SteeringResult> steeringResults, final String clientIP, final DeliveryService deliveryService) {
if (clientIP == null || clientIP.isEmpty()
|| steeringResults.stream().allMatch(t -> t.getSteeringTarget().getGeolocation() == null)) {
return;
diff --git a/traffic_router/core/src/test/java/com/comcast/cdn/traffic_control/traffic_router/core/ds/SteeringGeolocationComparatorTest.java b/traffic_router/core/src/test/java/com/comcast/cdn/traffic_control/traffic_router/core/ds/SteeringGeolocationComparatorTest.java
new file mode 100644
index 0000000..ed72081
--- /dev/null
+++ b/traffic_router/core/src/test/java/com/comcast/cdn/traffic_control/traffic_router/core/ds/SteeringGeolocationComparatorTest.java
@@ -0,0 +1,151 @@
+/*
+ *
+ * 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.comcast.cdn.traffic_control.traffic_router.core.ds;
+
+import com.comcast.cdn.traffic_control.traffic_router.core.cache.Cache;
+import com.comcast.cdn.traffic_control.traffic_router.geolocation.Geolocation;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class SteeringGeolocationComparatorTest {
+ /*
+ This test class assumes some knowledge of United States geography. For reference,
+ here are the rough distances looking at a map from left to right:
+
+ Seattle <--- 1300 mi ---> Denver <--- 2000 mi ---> Boston
+
+ */
+
+ private Geolocation seattleGeolocation;
+ private Geolocation denverGeolocation;
+ private Geolocation bostonGeolocation;
+
+ private Cache seattleCache;
+ private Cache denverCache;
+ private Cache bostonCache;
+
+ private SteeringTarget seattleTarget;
+ private SteeringTarget seattleTarget2;
+ private SteeringTarget denverTarget;
+ private SteeringTarget bostonTarget;
+
+ private SteeringResult seattleResult;
+ private SteeringResult seattleResult2;
+ private SteeringResult denverResult;
+ private SteeringResult bostonResult;
+
+ private SteeringGeolocationComparator seattleComparator;
+ private SteeringGeolocationComparator denverComparator;
+ private SteeringGeolocationComparator bostonComparator;
+
+ @Before
+ public void before() {
+ seattleGeolocation = new Geolocation(47.0, -122.0);
+ denverGeolocation = new Geolocation(39.0, -104.0);
+ bostonGeolocation = new Geolocation(42.0, -71.0);
+
+ seattleCache = new Cache("seattle-id", "seattle-hash-id", 1, seattleGeolocation);
+ denverCache = new Cache("denver-id", "denver-hash-id", 1, denverGeolocation);
+ bostonCache = new Cache("boston-id", "boston-hash-id", 1, bostonGeolocation);
+
+ seattleTarget = new SteeringTarget();
+ seattleTarget.setGeolocation(seattleGeolocation);
+ seattleResult = new SteeringResult(seattleTarget, null);
+ seattleResult.setCache(seattleCache);
+
+ seattleTarget2 = new SteeringTarget();
+ seattleTarget2.setGeolocation(seattleGeolocation);
+ seattleResult2 = new SteeringResult(seattleTarget2, null);
+ seattleResult2.setCache(seattleCache);
+
+ denverTarget = new SteeringTarget();
+ denverTarget.setGeolocation(denverGeolocation);
+ denverResult = new SteeringResult(denverTarget, null);
+ denverResult.setCache(denverCache);
+
+ bostonTarget = new SteeringTarget();
+ bostonTarget.setGeolocation(bostonGeolocation);
+ bostonResult = new SteeringResult(bostonTarget, null);
+ bostonResult.setCache(bostonCache);
+
+ seattleComparator = new SteeringGeolocationComparator(seattleGeolocation);
+ denverComparator = new SteeringGeolocationComparator(denverGeolocation);
+ bostonComparator = new SteeringGeolocationComparator(bostonGeolocation);
+
+ }
+
+ @Test
+ public void testLeftNullOriginGeo() {
+ seattleResult.getSteeringTarget().setGeolocation(null);
+ assertEquals(1, seattleComparator.compare(seattleResult, bostonResult));
+ }
+
+ @Test
+ public void testRightNullOriginGeo() {
+ denverResult.getSteeringTarget().setGeolocation(null);
+ assertEquals(-1, seattleComparator.compare(seattleResult, denverResult));
+ }
+
+ @Test
+ public void testBothNullOriginGeo() {
+ seattleResult.getSteeringTarget().setGeolocation(null);
+ denverResult.getSteeringTarget().setGeolocation(null);
+ assertEquals(0, seattleComparator.compare(seattleResult, denverResult));
+ }
+
+ @Test
+ public void testSameCacheAndOriginGeo() {
+ assertEquals(0, seattleComparator.compare(seattleResult, seattleResult));
+ }
+
+ @Test
+ public void testSameCacheAndOriginGeoWithGeoOrder() {
+ seattleTarget.setGeoOrder(1);
+ seattleTarget2.setGeoOrder(2);
+ assertEquals(-1, seattleComparator.compare(seattleResult, seattleResult2));
+ assertEquals(1, seattleComparator.compare(seattleResult2, seattleResult));
+ seattleTarget.setGeoOrder(2);
+ assertEquals(0, seattleComparator.compare(seattleResult, seattleResult2));
+ }
+
+ @Test
+ public void testDifferentCacheAndOriginGeo() {
+ assertEquals(-1, seattleComparator.compare(seattleResult, denverResult));
+ assertEquals(-1, seattleComparator.compare(denverResult, bostonResult));
+ assertEquals(1, seattleComparator.compare(bostonResult, seattleResult));
+ }
+
+ @Test
+ public void testCacheGeoDifferentFromOriginGeo() {
+ seattleResult.setCache(denverCache);
+ // seattle -> denver -> seattle || seattle -> denver
+ assertEquals(1, seattleComparator.compare(seattleResult, denverResult));
+ // denver -> seattle || denver
+ assertEquals(1, denverComparator.compare(seattleResult, denverResult));
+ // boston -> denver -> seattle || boston -> denver
+ assertEquals(1, bostonComparator.compare(seattleResult, denverResult));
+ // seattle -> denver -> seattle || seattle -> boston
+ assertEquals(-1, seattleComparator.compare(seattleResult, bostonResult));
+ seattleResult.setCache(bostonCache);
+ bostonResult.setCache(denverCache);
+ // seattle -> boston -> seattle || seattle -> denver -> boston
+ assertEquals(1, seattleComparator.compare(seattleResult, bostonResult));
+ }
+
+}
diff --git a/traffic_router/core/src/test/java/com/comcast/cdn/traffic_control/traffic_router/core/router/GeoSortSteeringResultsTest.java b/traffic_router/core/src/test/java/com/comcast/cdn/traffic_control/traffic_router/core/router/GeoSortSteeringResultsTest.java
new file mode 100644
index 0000000..81d3ed0
--- /dev/null
+++ b/traffic_router/core/src/test/java/com/comcast/cdn/traffic_control/traffic_router/core/router/GeoSortSteeringResultsTest.java
@@ -0,0 +1,134 @@
+/*
+ *
+ * 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.comcast.cdn.traffic_control.traffic_router.core.router;
+
+import com.comcast.cdn.traffic_control.traffic_router.core.cache.Cache;
+import com.comcast.cdn.traffic_control.traffic_router.core.ds.DeliveryService;
+import com.comcast.cdn.traffic_control.traffic_router.core.ds.SteeringResult;
+import com.comcast.cdn.traffic_control.traffic_router.core.ds.SteeringTarget;
+import com.comcast.cdn.traffic_control.traffic_router.geolocation.Geolocation;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyListOf;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.doCallRealMethod;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({Collections.class})
+public class GeoSortSteeringResultsTest {
+
+ private TrafficRouter trafficRouter;
+ private List<SteeringResult> steeringResults;
+ private Geolocation clientLocation;
+ private DeliveryService deliveryService;
+
+ @Before
+ public void before() {
+ trafficRouter = mock(TrafficRouter.class);
+ steeringResults = new ArrayList<>();
+ clientLocation = new Geolocation(47.0, -122.0);
+ deliveryService = mock(DeliveryService.class);
+ doCallRealMethod().when(trafficRouter).geoSortSteeringResults(anyListOf(SteeringResult.class), anyString(), any(DeliveryService.class));
+ when(trafficRouter.getClientLocationByCoverageZoneOrGeo(anyString(), any(DeliveryService.class))).thenReturn(clientLocation);
+ }
+
+ @Test
+ public void testNullClientIP() {
+ trafficRouter.geoSortSteeringResults(steeringResults, null, deliveryService);
+ verify(trafficRouter, never()).getClientLocationByCoverageZoneOrGeo(null, deliveryService);
+ }
+
+ @Test
+ public void testEmptyClientIP() {
+ trafficRouter.geoSortSteeringResults(steeringResults, "", deliveryService);
+ verify(trafficRouter, never()).getClientLocationByCoverageZoneOrGeo("", deliveryService);
+ }
+
+ @Test
+ public void testNoSteeringTargetsHaveGeolocations() {
+ steeringResults.add(new SteeringResult(new SteeringTarget(), deliveryService));
+ trafficRouter.geoSortSteeringResults(steeringResults, "::1", deliveryService);
+ verify(trafficRouter, never()).getClientLocationByCoverageZoneOrGeo("::1", deliveryService);
+ }
+
+ @Test
+ public void testClientGeolocationIsNull() {
+ SteeringTarget steeringTarget = new SteeringTarget();
+ steeringTarget.setGeolocation(clientLocation);
+ steeringResults.add(new SteeringResult(steeringTarget, deliveryService));
+ clientLocation = null;
+ PowerMockito.mockStatic(Collections.class);
+
+ trafficRouter.geoSortSteeringResults(steeringResults, "::1", deliveryService);
+
+ PowerMockito.verifyStatic(never());
+ }
+
+ @Test
+ public void testGeoSortingMixedWithNonGeoTargets() {
+ Cache cache = new Cache("fake-id", "fake-hash-id",1, clientLocation);
+ SteeringTarget target;
+
+ target = new SteeringTarget();
+ target.setOrder(-1);
+ SteeringResult resultNoGeoNegativeOrder = new SteeringResult(target, deliveryService);
+ resultNoGeoNegativeOrder.setCache(cache);
+ steeringResults.add(resultNoGeoNegativeOrder);
+
+ target = new SteeringTarget();
+ target.setOrder(1);
+ SteeringResult resultNoGeoPositiveOrder = new SteeringResult(target, deliveryService);
+ resultNoGeoPositiveOrder.setCache(cache);
+ steeringResults.add(resultNoGeoPositiveOrder);
+
+ target = new SteeringTarget();
+ target.setOrder(0);
+ SteeringResult resultNoGeoZeroOrder = new SteeringResult(target, deliveryService);
+ resultNoGeoZeroOrder.setCache(cache);
+ steeringResults.add(resultNoGeoZeroOrder);
+
+ target = new SteeringTarget();
+ target.setGeolocation(clientLocation);
+ target.setOrder(0);
+ SteeringResult resultGeo = new SteeringResult(target, deliveryService);
+ resultGeo.setCache(cache);
+ steeringResults.add(resultGeo);
+
+ trafficRouter.geoSortSteeringResults(steeringResults, "::1", deliveryService);
+
+ assertEquals(resultNoGeoNegativeOrder, steeringResults.get(0));
+ assertEquals(resultGeo, steeringResults.get(1));
+ assertEquals(resultNoGeoZeroOrder, steeringResults.get(2));
+ assertEquals(resultNoGeoPositiveOrder, steeringResults.get(3));
+ }
+
+}
--
To stop receiving notification emails like this one, please contact
elsloo@apache.org.