diff options
author | Jon Marius Venstad <jonmv@users.noreply.github.com> | 2022-08-09 16:40:43 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-09 16:40:43 +0200 |
commit | fd1b5165a160af4494da6d1cb3e34f60e6037360 (patch) | |
tree | 75dd251aa0475787a5a5e86144b4b92273e874d0 | |
parent | 9d1b7d6dfd69c6c15786d7b24a1a8136be7d0484 (diff) | |
parent | 10cd4474cc18b5daa6804d8eff0a081fb84329f5 (diff) |
Merge pull request #23614 from vespa-engine/jonmv/test-runtime-conditions
Add conditions for enabling/disabling tests based on region/instance
5 files changed, 237 insertions, 0 deletions
diff --git a/tenant-cd-api/abi-spec.json b/tenant-cd-api/abi-spec.json index 11ec9f73be2..f072d9de169 100644 --- a/tenant-cd-api/abi-spec.json +++ b/tenant-cd-api/abi-spec.json @@ -15,6 +15,70 @@ ], "fields": [] }, + "ai.vespa.hosted.cd.DisabledInInstances": { + "superClass": "java.lang.Object", + "interfaces": [ + "java.lang.annotation.Annotation" + ], + "attributes": [ + "public", + "interface", + "abstract", + "annotation" + ], + "methods": [ + "public abstract java.lang.String[] value()" + ], + "fields": [] + }, + "ai.vespa.hosted.cd.DisabledInRegions": { + "superClass": "java.lang.Object", + "interfaces": [ + "java.lang.annotation.Annotation" + ], + "attributes": [ + "public", + "interface", + "abstract", + "annotation" + ], + "methods": [ + "public abstract java.lang.String[] value()" + ], + "fields": [] + }, + "ai.vespa.hosted.cd.EnabledInInstances": { + "superClass": "java.lang.Object", + "interfaces": [ + "java.lang.annotation.Annotation" + ], + "attributes": [ + "public", + "interface", + "abstract", + "annotation" + ], + "methods": [ + "public abstract java.lang.String[] value()" + ], + "fields": [] + }, + "ai.vespa.hosted.cd.EnabledInRegions": { + "superClass": "java.lang.Object", + "interfaces": [ + "java.lang.annotation.Annotation" + ], + "attributes": [ + "public", + "interface", + "abstract", + "annotation" + ], + "methods": [ + "public abstract java.lang.String[] value()" + ], + "fields": [] + }, "ai.vespa.hosted.cd.Endpoint": { "superClass": "java.lang.Object", "interfaces": [], diff --git a/tenant-cd-api/src/main/java/ai/vespa/hosted/cd/DisabledInInstances.java b/tenant-cd-api/src/main/java/ai/vespa/hosted/cd/DisabledInInstances.java new file mode 100644 index 00000000000..4a14509459a --- /dev/null +++ b/tenant-cd-api/src/main/java/ai/vespa/hosted/cd/DisabledInInstances.java @@ -0,0 +1,43 @@ +package ai.vespa.hosted.cd; + +import org.junit.jupiter.api.extension.ConditionEvaluationResult; +import org.junit.jupiter.api.extension.ExecutionCondition; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.platform.commons.util.AnnotationUtils; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.util.List; +import java.util.Optional; + +/** + * @author jonmv + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.TYPE, ElementType.ANNOTATION_TYPE}) +@ExtendWith(DisabledInInstancesCondition.class) +public @interface DisabledInInstances { + + /** One or more instances that this should be disabled in. */ + String[] value(); + +} + +class DisabledInInstancesCondition implements ExecutionCondition { + + @Override + public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) { + Optional<DisabledInInstances> annotation = AnnotationUtils.findAnnotation(context.getElement(), DisabledInInstances.class); + if (annotation.isEmpty()) + return ConditionEvaluationResult.enabled(DisabledInInstances.class.getSimpleName() + " is not present"); + + List<String> disablingInstances = List.of(annotation.get().value()); + String thisInstance = TestRuntime.get().application().instance(); + String reason = "Disabled in: %s. Current instance: %s.".formatted(disablingInstances.isEmpty() ? "no instances" : "instances " + String.join(", ", disablingInstances), thisInstance); + return disablingInstances.contains(thisInstance) ? ConditionEvaluationResult.disabled(reason) : ConditionEvaluationResult.enabled(reason); + } + +}
\ No newline at end of file diff --git a/tenant-cd-api/src/main/java/ai/vespa/hosted/cd/DisabledInRegions.java b/tenant-cd-api/src/main/java/ai/vespa/hosted/cd/DisabledInRegions.java new file mode 100644 index 00000000000..aeb6a001726 --- /dev/null +++ b/tenant-cd-api/src/main/java/ai/vespa/hosted/cd/DisabledInRegions.java @@ -0,0 +1,44 @@ +package ai.vespa.hosted.cd; + +import org.junit.jupiter.api.extension.ConditionEvaluationResult; +import org.junit.jupiter.api.extension.ExecutionCondition; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.platform.commons.util.AnnotationUtils; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.util.List; +import java.util.Optional; +import java.util.function.Function; + +/** + * @author jonmv + */ +@Target({ElementType.METHOD, ElementType.TYPE, ElementType.ANNOTATION_TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@ExtendWith(DisabledInRegionsCondition.class) +public @interface DisabledInRegions { + + /** One or more regions that this should be disabled in. */ + String[] value(); + +} + +class DisabledInRegionsCondition implements ExecutionCondition { + + @Override + public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) { + Optional<DisabledInRegions> annotation = AnnotationUtils.findAnnotation(context.getElement(), DisabledInRegions.class); + if (annotation.isEmpty()) + return ConditionEvaluationResult.enabled(DisabledInRegions.class.getSimpleName() + " is not present"); + + List<String> disablingRegions = List.of(annotation.get().value()); + String thisRegion = TestRuntime.get().application().instance(); + String reason = "Disabled in: %s. Current region: %s.".formatted(disablingRegions.isEmpty() ? "no regions" : "regions " + String.join(", ", disablingRegions), thisRegion); + return disablingRegions.contains(thisRegion) ? ConditionEvaluationResult.disabled(reason) : ConditionEvaluationResult.enabled(reason); + } + +}
\ No newline at end of file diff --git a/tenant-cd-api/src/main/java/ai/vespa/hosted/cd/EnabledInInstances.java b/tenant-cd-api/src/main/java/ai/vespa/hosted/cd/EnabledInInstances.java new file mode 100644 index 00000000000..dfe22dacb11 --- /dev/null +++ b/tenant-cd-api/src/main/java/ai/vespa/hosted/cd/EnabledInInstances.java @@ -0,0 +1,43 @@ +package ai.vespa.hosted.cd; + +import org.junit.jupiter.api.extension.ConditionEvaluationResult; +import org.junit.jupiter.api.extension.ExecutionCondition; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.platform.commons.util.AnnotationUtils; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.util.List; +import java.util.Optional; + +/** + * @author jonmv + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.TYPE, ElementType.ANNOTATION_TYPE}) +@ExtendWith(EnabledInInstancesCondition.class) +public @interface EnabledInInstances { + + /** One or more instances that this should be enabled in. */ + String[] value(); + +} + +class EnabledInInstancesCondition implements ExecutionCondition { + + @Override + public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) { + Optional<EnabledInInstances> annotation = AnnotationUtils.findAnnotation(context.getElement(), EnabledInInstances.class); + if (annotation.isEmpty()) + return ConditionEvaluationResult.enabled(EnabledInInstances.class.getSimpleName() + " is not present"); + + List<String> enablingInstances = List.of(annotation.get().value()); + String thisInstance = TestRuntime.get().application().instance(); + String reason = "Enabled in: %s. Current instance: %s.".formatted(enablingInstances.isEmpty() ? "no instances" : "instances " + String.join(", ", enablingInstances), thisInstance); + return enablingInstances.contains(thisInstance) ? ConditionEvaluationResult.enabled(reason) : ConditionEvaluationResult.disabled(reason); + } + +}
\ No newline at end of file diff --git a/tenant-cd-api/src/main/java/ai/vespa/hosted/cd/EnabledInRegions.java b/tenant-cd-api/src/main/java/ai/vespa/hosted/cd/EnabledInRegions.java new file mode 100644 index 00000000000..db2e5ac5f95 --- /dev/null +++ b/tenant-cd-api/src/main/java/ai/vespa/hosted/cd/EnabledInRegions.java @@ -0,0 +1,43 @@ +package ai.vespa.hosted.cd; + +import org.junit.jupiter.api.extension.ConditionEvaluationResult; +import org.junit.jupiter.api.extension.ExecutionCondition; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.platform.commons.util.AnnotationUtils; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.util.List; +import java.util.Optional; + +/** + * @author jonmv + */ +@Target({ElementType.METHOD, ElementType.TYPE, ElementType.ANNOTATION_TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@ExtendWith(EnabledInRegionsCondition.class) +public @interface EnabledInRegions { + + /** One or more regions that this should be enabled in. */ + String[] value(); + +} + +class EnabledInRegionsCondition implements ExecutionCondition { + + @Override + public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) { + Optional<EnabledInRegions> annotation = AnnotationUtils.findAnnotation(context.getElement(), EnabledInRegions.class); + if (annotation.isEmpty()) + return ConditionEvaluationResult.enabled(EnabledInRegions.class.getSimpleName() + " is not present"); + + List<String> enablingRegions = List.of(annotation.get().value()); + String thisRegion = TestRuntime.get().application().instance(); + String reason = "Enabled in: %s. Current region: %s.".formatted(enablingRegions.isEmpty() ? "no regions" : "regions " + String.join(", ", enablingRegions), thisRegion); + return enablingRegions.contains(thisRegion) ? ConditionEvaluationResult.enabled(reason) : ConditionEvaluationResult.disabled(reason); + } + +}
\ No newline at end of file |