package com.indeed.proctor.webapp.controllers; import com.google.common.collect.ImmutableMap; import com.indeed.proctor.common.EnvironmentVersion; import com.indeed.proctor.common.model.Allocation; import com.indeed.proctor.common.model.Payload; import com.indeed.proctor.common.model.Range; import com.indeed.proctor.common.model.TestBucket; import com.indeed.proctor.common.model.TestDefinition; import com.indeed.proctor.common.model.TestType; import java.util.Collections; import org.junit.Assert; import org.junit.Test; import java.util.HashMap; import java.util.List; import java.util.ArrayList; public class TestProctorTestDefinitionController { @Test public void testIsValidTestName() { Assert.assertFalse(ProctorTestDefinitionController.isValidTestName("")); Assert.assertTrue(ProctorTestDefinitionController.isValidTestName("a")); Assert.assertTrue(ProctorTestDefinitionController.isValidTestName("A")); Assert.assertTrue(ProctorTestDefinitionController.isValidTestName("_")); Assert.assertFalse(ProctorTestDefinitionController.isValidTestName("0")); Assert.assertFalse(ProctorTestDefinitionController.isValidTestName(".")); Assert.assertTrue(ProctorTestDefinitionController.isValidTestName("_0")); Assert.assertTrue(ProctorTestDefinitionController.isValidTestName("valid_test_Name_10")); Assert.assertFalse(ProctorTestDefinitionController.isValidTestName("inValid#test#name")); } @Test public void testIsValidBucketName() { Assert.assertFalse(ProctorTestDefinitionController.isValidBucketName("")); Assert.assertTrue(ProctorTestDefinitionController.isValidBucketName("valid_bucket_Name")); Assert.assertFalse(ProctorTestDefinitionController.isValidBucketName("0invalid_bucket_Name")); } @Test public void testAllocationOnlyChangeDetection() { { final double[] rangeOne = {.7, .3}; final double[] rangeTwo = {.5, .5}; final TestDefinition testDefinitionOne = createTestDefinition("testbuck:0", rangeOne); final TestDefinition testDefinitionTwo = createTestDefinition("testbuck:0", rangeTwo); Assert.assertTrue(ProctorTestDefinitionController.isAllocationOnlyChange(testDefinitionOne, testDefinitionTwo)); } { // different amounts of buckets final double[] rangeOne = {.7, .3}; final double[] rangeTwo = {.5, .5}; final TestDefinition testDefinitionOne = createTestDefinition("testbuck:0", rangeOne); final TestDefinition testDefinitionTwo = createTestDefinition("testbuck:0,control:1", rangeTwo); Assert.assertFalse(ProctorTestDefinitionController.isAllocationOnlyChange(testDefinitionOne, testDefinitionTwo)); } { // different buckets final double[] rangeOne = {.7, .3}; final double[] rangeTwo = {.5, .5}; final TestDefinition testDefinitionOne = createTestDefinition("testbuck:0,control:2", rangeOne); final TestDefinition testDefinitionTwo = createTestDefinition("testbuck:0,control:1", rangeTwo); Assert.assertFalse(ProctorTestDefinitionController.isAllocationOnlyChange(testDefinitionOne, testDefinitionTwo)); } { //different testtypes final double[] rangeOne = {.7, .3}; final double[] rangeTwo = {.5, .5}; final TestDefinition testDefinitionOne = createTestDefinition("testbuck:0,control:2",TestType.RANDOM, rangeOne); final TestDefinition testDefinitionTwo = createTestDefinition("testbuck:0,control:2",TestType.EMAIL_ADDRESS, rangeTwo); Assert.assertFalse(ProctorTestDefinitionController.isAllocationOnlyChange(testDefinitionOne, testDefinitionTwo)); } { //testing different salts final double[] rangeOne = {.7, .3}; final double[] rangeTwo = {.5, .5}; final TestDefinition testDefinitionOne = createTestDefinition("testbuck:0,control:2",TestType.RANDOM, "salt1",rangeOne); final TestDefinition testDefinitionTwo = createTestDefinition("testbuck:0,control:2",TestType.RANDOM, "salt2", rangeTwo); Assert.assertFalse(ProctorTestDefinitionController.isAllocationOnlyChange(testDefinitionOne, testDefinitionTwo)); } { //testing 0 to greater allocation final double[] rangeOne = {0, 1}; final double[] rangeTwo = {.5, .5}; final TestDefinition testDefinitionOne = createTestDefinition("testbuck:0,control:2", rangeOne); final TestDefinition testDefinitionTwo = createTestDefinition("testbuck:0,control:2", rangeTwo); Assert.assertFalse(ProctorTestDefinitionController.isAllocationOnlyChange(testDefinitionOne, testDefinitionTwo)); } { //testing non 100% to 100% allocation final double[] rangeOne = {.5, .5}; final double[] rangeTwo = {1, 0}; final TestDefinition testDefinitionOne = createTestDefinition("testbuck:0,control:2", rangeOne); final TestDefinition testDefinitionTwo = createTestDefinition("testbuck:0,control:2", rangeTwo); Assert.assertTrue(ProctorTestDefinitionController.isAllocationOnlyChange(testDefinitionOne, testDefinitionTwo)); } { //testing different salts final double[] rangeOne = {.7, .3}; final double[] rangeTwo = {.5, .5}; final TestDefinition testDefinitionOne = createTestDefinition("testbuck:0,control:2",TestType.RANDOM, "salt1",rangeOne); final TestDefinition testDefinitionTwo = createTestDefinition("testbuck:0,control:2",TestType.RANDOM, "salt2", rangeTwo); Assert.assertFalse(ProctorTestDefinitionController.isAllocationOnlyChange(testDefinitionOne, testDefinitionTwo)); } { //testing with payloads final Payload payloadBucket1Test1 = new Payload(); payloadBucket1Test1.setDoubleValue(10.1D); final Payload payloadBucket2Test1 = new Payload(); payloadBucket2Test1.setStringValue("p"); final Payload[] payloadst1 = {payloadBucket1Test1,payloadBucket2Test1}; final Payload payloadBucket1Test2 = new Payload(); payloadBucket1Test2.setDoubleValue(10.1D); final Payload payloadBucket2Test2 = new Payload(); payloadBucket2Test2.setStringValue("p"); final Payload[] payloadst2 = {payloadBucket1Test2,payloadBucket2Test2}; final double[] rangeOne = {.7, .3}; final double[] rangeTwo = {.5, .5}; final TestDefinition testDefinitionOne = createTestDefinition("testbuck:0,control:2",TestType.RANDOM, "salt1", rangeOne,payloadst1); final TestDefinition testDefinitionTwo = createTestDefinition("testbuck:0,control:2",TestType.RANDOM, "salt1", rangeTwo,payloadst2); Assert.assertTrue(ProctorTestDefinitionController.isAllocationOnlyChange(testDefinitionOne, testDefinitionTwo)); } { //testing different payloads final Payload payloadBucket1Test1 = new Payload(); payloadBucket1Test1.setStringValue("p2"); final Payload payloadBucket2Test1 = new Payload(); payloadBucket2Test1.setStringValue("p"); final Payload[] payloadst1 = {payloadBucket1Test1,payloadBucket2Test1}; final Payload payloadBucket1Test2 = new Payload(); payloadBucket1Test2.setDoubleValue(10.1D); final Payload payloadBucket2Test2 = new Payload(); payloadBucket2Test2.setStringValue("p"); final Payload[] payloadst2 = {payloadBucket1Test2,payloadBucket2Test2}; final double[] rangeOne = {.7, .3}; final double[] rangeTwo = {.5, .5}; final TestDefinition testDefinitionOne = createTestDefinition("testbuck:0,control:2",TestType.RANDOM, "salt1",rangeOne,payloadst1); final TestDefinition testDefinitionTwo = createTestDefinition("testbuck:0,control:2",TestType.RANDOM, "salt1", rangeTwo,payloadst2); Assert.assertFalse(ProctorTestDefinitionController.isAllocationOnlyChange(testDefinitionOne, testDefinitionTwo)); } { //testing null payloads final Payload payloadBucket1Test2 = new Payload(); payloadBucket1Test2.setDoubleValue(10.1D); final Payload payloadBucket2Test2 = new Payload(); payloadBucket2Test2.setStringValue("p"); final Payload[] payloadst2 = {payloadBucket1Test2,payloadBucket2Test2}; final double[] rangeOne = {.7, .3}; final double[] rangeTwo = {.5, .5}; final TestDefinition testDefinitionOne = createTestDefinition("testbuck:0,control:2",TestType.RANDOM, "salt1",rangeOne,null); final TestDefinition testDefinitionTwo = createTestDefinition("testbuck:0,control:2",TestType.RANDOM, "salt1", rangeTwo,payloadst2); Assert.assertFalse(ProctorTestDefinitionController.isAllocationOnlyChange(testDefinitionOne, testDefinitionTwo)); } { //testing map payload autopromote equality final Payload payloadBucket1Test2 = new Payload(); HashMap<String, Object> one = new HashMap<String, Object>(); one.put("A", new ArrayList(){{add(1);}}); one.put("B", 2.1); payloadBucket1Test2.setMap(one); final Payload payloadBucket2Test2 = new Payload(); payloadBucket2Test2.setMap(ImmutableMap.<String,Object>of("A", "asdf")); final Payload[] payloadst2 = {payloadBucket1Test2,payloadBucket2Test2}; final Payload payloadBucket1Test1 = new Payload(); HashMap<String, Object> two = new HashMap<String, Object>(); two.put("B", 2.1); two.put("A", new ArrayList(){{add(1);}}); payloadBucket1Test1.setMap(two); final Payload payloadBucket2Test1 = new Payload(); payloadBucket2Test1.setMap(ImmutableMap.<String,Object>of("A", "asdf")); final Payload[] payloadst1 = {payloadBucket1Test1,payloadBucket2Test1}; final double[] rangeOne = {.7, .3}; final double[] rangeTwo = {.5, .5}; final TestDefinition testDefinitionOne = createTestDefinition("testbuck:0,control:2",TestType.RANDOM, "salt1",rangeOne,payloadst1); final TestDefinition testDefinitionTwo = createTestDefinition("testbuck:0,control:2",TestType.RANDOM, "salt1", rangeTwo,payloadst2); testDefinitionTwo.setDescription("updated description"); Assert.assertTrue(ProctorTestDefinitionController.isAllocationOnlyChange(testDefinitionOne, testDefinitionTwo)); } { //testing map payload failed autopromote equality final Payload payloadBucket1Test2 = new Payload(); payloadBucket1Test2.setMap(ImmutableMap.<String,Object>of("A", new ArrayList(){{add("ff");}})); final Payload payloadBucket2Test2 = new Payload(); payloadBucket2Test2.setMap(ImmutableMap.<String,Object>of("A", "asdf")); final Payload[] payloadst2 = {payloadBucket1Test2,payloadBucket2Test2}; final Payload payloadBucket1Test1 = new Payload(); payloadBucket1Test1.setMap(ImmutableMap.<String,Object>of("A", new ArrayList(){{add(1);}})); final Payload payloadBucket2Test1 = new Payload(); payloadBucket2Test1.setMap(ImmutableMap.<String,Object>of("A", "asdf")); final Payload[] payloadst1 = {payloadBucket1Test1,payloadBucket2Test1}; final double[] rangeOne = {.7, .3}; final double[] rangeTwo = {.5, .5}; final TestDefinition testDefinitionOne = createTestDefinition("testbuck:0,control:2",TestType.RANDOM, "salt1",rangeOne,payloadst1); final TestDefinition testDefinitionTwo = createTestDefinition("testbuck:0,control:2",TestType.RANDOM, "salt1", rangeTwo,payloadst2); Assert.assertFalse(ProctorTestDefinitionController.isAllocationOnlyChange(testDefinitionOne, testDefinitionTwo)); } } public TestDefinition createTestDefinition(String bucketsString, double[] ranges) { return createTestDefinition(bucketsString,TestType.RANDOM,"salt",ranges); } public TestDefinition createTestDefinition(String bucketsString, TestType testType, double[] ranges) { return createTestDefinition(bucketsString,testType,"salt",ranges); } public TestDefinition createTestDefinition(String bucketsString, TestType testType, String salt, double[] ranges) { return createTestDefinition(bucketsString,testType,salt,ranges,null); } public TestDefinition createTestDefinition(String bucketsString, TestType testType, String salt, double[] ranges, Payload[] payloads) { final List<Range> rangeList = new ArrayList<Range>(); for (int i = 0; i < ranges.length; i++) { final Range newRange = new Range(i, ranges[i]); rangeList.add(newRange); } String[] buckets = bucketsString.split(","); List<TestBucket> buckList = new ArrayList<TestBucket>(); for (int i = 0; i < buckets.length; i++) { String bucket = buckets[i]; final int colonInd = bucket.indexOf(':'); final TestBucket tempBucket= new TestBucket(bucket.substring(0,colonInd),Integer.parseInt(bucket.substring(colonInd+1)),"description",(payloads==null)?null:payloads[i]); buckList.add(tempBucket); } final Allocation alloc = new Allocation(null, rangeList); final List<Allocation> allocList = new ArrayList<Allocation>(); allocList.add(alloc); return new TestDefinition(EnvironmentVersion.UNKNOWN_REVISION, null, testType, salt, buckList, allocList, Collections.<String, Object>emptyMap(), Collections.<String, Object>emptyMap(), null); } }