summaryrefslogtreecommitdiffstats
path: root/flags/src/test
diff options
context:
space:
mode:
authorHåkon Hallingstad <hakon@verizonmedia.com>2019-10-22 00:28:22 +0200
committerHåkon Hallingstad <hakon@verizonmedia.com>2019-10-22 00:28:22 +0200
commitc29b374c582c8b112a6e95150e5d4a460dc30464 (patch)
treea9ec0e5bb3a388d6c30199bd3b89b07b1bcb716e /flags/src/test
parentfef3449937c173ef8128b6085829e0bbe3f97ce4 (diff)
Support flag conditions based on Vespa release
Supports a "relational" condition with a new dimension "vespa-version", that can be satisfied with e.g. "predicate": ">= 7.120.5" as long as the condition is evaluated in a JVM that has a Vtag at least high as 7.120.5. The typical use-case for this condition would be: The developer has used the flag to test and verify the feature is ready to roll out globally. The developer can now roll the feature with the next release, and ORCHESTRATED, halting if anything goes wrong like any normal rollout. This also allows one-shot tests of a feature flag in integration tests: Just enable it for an upcoming version with predicate "== 7.x.y".
Diffstat (limited to 'flags/src/test')
-rw-r--r--flags/src/test/java/com/yahoo/vespa/flags/json/ConditionTest.java40
-rw-r--r--flags/src/test/java/com/yahoo/vespa/flags/json/SerializationTest.java12
2 files changed, 45 insertions, 7 deletions
diff --git a/flags/src/test/java/com/yahoo/vespa/flags/json/ConditionTest.java b/flags/src/test/java/com/yahoo/vespa/flags/json/ConditionTest.java
index d19442ae0f0..cf8d06fd312 100644
--- a/flags/src/test/java/com/yahoo/vespa/flags/json/ConditionTest.java
+++ b/flags/src/test/java/com/yahoo/vespa/flags/json/ConditionTest.java
@@ -4,9 +4,10 @@ package com.yahoo.vespa.flags.json;
import com.yahoo.vespa.flags.FetchVector;
import org.junit.Test;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
+import java.util.List;
+import java.util.Optional;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
@@ -17,8 +18,8 @@ public class ConditionTest {
@Test
public void testWhitelist() {
String hostname1 = "host1";
- Condition condition = new Condition(Condition.Type.WHITELIST, FetchVector.Dimension.HOSTNAME,
- Stream.of(hostname1).collect(Collectors.toList()));
+ var params = new Condition.CreateParams(FetchVector.Dimension.HOSTNAME, List.of(hostname1), Optional.empty());
+ Condition condition = new WhitelistCondition(params);
assertFalse(condition.test(new FetchVector()));
assertFalse(condition.test(new FetchVector().with(FetchVector.Dimension.APPLICATION_ID, "foo")));
assertFalse(condition.test(new FetchVector().with(FetchVector.Dimension.HOSTNAME, "bar")));
@@ -28,11 +29,38 @@ public class ConditionTest {
@Test
public void testBlacklist() {
String hostname1 = "host1";
- Condition condition = new Condition(Condition.Type.BLACKLIST, FetchVector.Dimension.HOSTNAME,
- Stream.of(hostname1).collect(Collectors.toList()));
+ var params = new Condition.CreateParams(FetchVector.Dimension.HOSTNAME, List.of(hostname1), Optional.empty());
+ Condition condition = new BlacklistCondition(params);
assertTrue(condition.test(new FetchVector()));
assertTrue(condition.test(new FetchVector().with(FetchVector.Dimension.APPLICATION_ID, "foo")));
assertTrue(condition.test(new FetchVector().with(FetchVector.Dimension.HOSTNAME, "bar")));
assertFalse(condition.test(new FetchVector().with(FetchVector.Dimension.HOSTNAME, hostname1)));
}
+
+ @Test
+ public void testRelational() {
+ verifyVespaVersionFor("<", true, false, false);
+ verifyVespaVersionFor("<=", true, true, false);
+ verifyVespaVersionFor(">", false, false, true);
+ verifyVespaVersionFor(">=", false, true, true);
+
+ // Test with empty fetch vector along vespa version dimension (this should never happen as the
+ // version is always available through Vtag, although Vtag has a dummy version number for e.g.
+ // locally run unit tests that hasn't set the release Vespa version).
+ var params = new Condition.CreateParams(FetchVector.Dimension.VESPA_VERSION, List.of(), Optional.of(">=7.1.2"));
+ Condition condition = RelationalCondition.create(params);
+ assertFalse(condition.test(new FetchVector()));
+ }
+
+ private void verifyVespaVersionFor(String operator, boolean whenLess, boolean whenEqual, boolean whenGreater) {
+ assertEquals(whenLess, vespaVersionCondition("7.2.4", operator + "7.3.4"));
+ assertEquals(whenEqual, vespaVersionCondition("7.3.4", operator + "7.3.4"));
+ assertEquals(whenGreater, vespaVersionCondition("7.4.4", operator + "7.3.4"));
+ }
+
+ private boolean vespaVersionCondition(String vespaVersion, String predicate) {
+ var params = new Condition.CreateParams(FetchVector.Dimension.VESPA_VERSION, List.of(), Optional.of(predicate));
+ Condition condition = RelationalCondition.create(params);
+ return condition.test(new FetchVector().with(FetchVector.Dimension.VESPA_VERSION, vespaVersion));
+ }
}
diff --git a/flags/src/test/java/com/yahoo/vespa/flags/json/SerializationTest.java b/flags/src/test/java/com/yahoo/vespa/flags/json/SerializationTest.java
index b0e4cd0f682..8326b14fcbf 100644
--- a/flags/src/test/java/com/yahoo/vespa/flags/json/SerializationTest.java
+++ b/flags/src/test/java/com/yahoo/vespa/flags/json/SerializationTest.java
@@ -48,6 +48,11 @@ public class SerializationTest {
" \"type\": \"blacklist\",\n" +
" \"dimension\": \"hostname\",\n" +
" \"values\": [ \"h1\" ]\n" +
+ " },\n" +
+ " {\n" +
+ " \"type\": \"relational\",\n" +
+ " \"dimension\": \"vespa-version\",\n" +
+ " \"predicate\": \">=7.3.4\"\n" +
" }\n" +
" ],\n" +
" \"value\": true\n" +
@@ -66,7 +71,7 @@ public class SerializationTest {
assertThat(wireData.id, equalTo("id2"));
// rule
assertThat(wireData.rules.size(), equalTo(1));
- assertThat(wireData.rules.get(0).andConditions.size(), equalTo(2));
+ assertThat(wireData.rules.get(0).andConditions.size(), equalTo(3));
assertThat(wireData.rules.get(0).value.getNodeType(), equalTo(JsonNodeType.BOOLEAN));
assertThat(wireData.rules.get(0).value.asBoolean(), equalTo(true));
// first condition
@@ -79,6 +84,11 @@ public class SerializationTest {
assertThat(blacklistCondition.type, equalTo("blacklist"));
assertThat(blacklistCondition.dimension, equalTo("hostname"));
assertThat(blacklistCondition.values, equalTo(List.of("h1")));
+ // third condition
+ WireCondition relationalCondition = wireData.rules.get(0).andConditions.get(2);
+ assertThat(relationalCondition.type, equalTo("relational"));
+ assertThat(relationalCondition.dimension, equalTo("vespa-version"));
+ assertThat(relationalCondition.predicate, equalTo(">=7.3.4"));
// attributes
assertThat(wireData.defaultFetchVector, notNullValue());