diff --git a/impl/test/src/test/java/io/serverlessworkflow/impl/test/CustomFunctionTest.java b/impl/test/src/test/java/io/serverlessworkflow/impl/test/CustomFunctionTest.java index b659b7af0..f21107a10 100644 --- a/impl/test/src/test/java/io/serverlessworkflow/impl/test/CustomFunctionTest.java +++ b/impl/test/src/test/java/io/serverlessworkflow/impl/test/CustomFunctionTest.java @@ -21,6 +21,7 @@ import io.serverlessworkflow.impl.WorkflowApplication; import io.serverlessworkflow.impl.WorkflowException; +import io.serverlessworkflow.impl.test.junit.DisabledIfPythonUnavailable; import java.io.IOException; import java.util.Map; import org.junit.jupiter.api.AfterAll; @@ -58,6 +59,7 @@ void testCustomFunction() { .isEqualTo(404); } + @DisabledIfPythonUnavailable() @ParameterizedTest @ValueSource( strings = { diff --git a/impl/test/src/test/java/io/serverlessworkflow/impl/test/grpc/GrpcBiDirectionalStreamingTest.java b/impl/test/src/test/java/io/serverlessworkflow/impl/test/grpc/GrpcBiDirectionalStreamingTest.java index aa34497aa..bbde7cf0d 100644 --- a/impl/test/src/test/java/io/serverlessworkflow/impl/test/grpc/GrpcBiDirectionalStreamingTest.java +++ b/impl/test/src/test/java/io/serverlessworkflow/impl/test/grpc/GrpcBiDirectionalStreamingTest.java @@ -23,6 +23,7 @@ import io.serverlessworkflow.impl.WorkflowDefinition; import io.serverlessworkflow.impl.WorkflowModel; import io.serverlessworkflow.impl.test.grpc.handlers.ContributorBiDiStreamingHandler; +import io.serverlessworkflow.impl.test.junit.DisabledIfProtocUnavailable; import java.io.IOException; import java.util.Collection; import java.util.Map; @@ -31,6 +32,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +@DisabledIfProtocUnavailable public class GrpcBiDirectionalStreamingTest { private static final int PORT_FOR_EXAMPLES = 5011; diff --git a/impl/test/src/test/java/io/serverlessworkflow/impl/test/grpc/GrpcClientStreamingTest.java b/impl/test/src/test/java/io/serverlessworkflow/impl/test/grpc/GrpcClientStreamingTest.java index aca9615db..f22c34d5a 100644 --- a/impl/test/src/test/java/io/serverlessworkflow/impl/test/grpc/GrpcClientStreamingTest.java +++ b/impl/test/src/test/java/io/serverlessworkflow/impl/test/grpc/GrpcClientStreamingTest.java @@ -22,6 +22,7 @@ import io.serverlessworkflow.impl.WorkflowApplication; import io.serverlessworkflow.impl.WorkflowDefinition; import io.serverlessworkflow.impl.test.grpc.handlers.ContributorClientStreamingHandler; +import io.serverlessworkflow.impl.test.junit.DisabledIfProtocUnavailable; import java.io.IOException; import java.util.List; import java.util.Map; @@ -30,6 +31,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +@DisabledIfProtocUnavailable public class GrpcClientStreamingTest { private static final int PORT_FOR_EXAMPLES = 5011; diff --git a/impl/test/src/test/java/io/serverlessworkflow/impl/test/grpc/GrpcServerStreamingTest.java b/impl/test/src/test/java/io/serverlessworkflow/impl/test/grpc/GrpcServerStreamingTest.java index 78ac67ca2..5f18ca670 100644 --- a/impl/test/src/test/java/io/serverlessworkflow/impl/test/grpc/GrpcServerStreamingTest.java +++ b/impl/test/src/test/java/io/serverlessworkflow/impl/test/grpc/GrpcServerStreamingTest.java @@ -23,6 +23,7 @@ import io.serverlessworkflow.impl.WorkflowDefinition; import io.serverlessworkflow.impl.WorkflowModel; import io.serverlessworkflow.impl.test.grpc.handlers.ContributorServerStreamingHandler; +import io.serverlessworkflow.impl.test.junit.DisabledIfProtocUnavailable; import java.io.IOException; import java.util.Collection; import java.util.Map; @@ -31,6 +32,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +@DisabledIfProtocUnavailable public class GrpcServerStreamingTest { private static final int PORT_FOR_EXAMPLES = 5011; diff --git a/impl/test/src/test/java/io/serverlessworkflow/impl/test/grpc/GrpcUnaryArgsExprTest.java b/impl/test/src/test/java/io/serverlessworkflow/impl/test/grpc/GrpcUnaryArgsExprTest.java index 59777fb01..594b481e5 100644 --- a/impl/test/src/test/java/io/serverlessworkflow/impl/test/grpc/GrpcUnaryArgsExprTest.java +++ b/impl/test/src/test/java/io/serverlessworkflow/impl/test/grpc/GrpcUnaryArgsExprTest.java @@ -22,6 +22,7 @@ import io.serverlessworkflow.impl.WorkflowApplication; import io.serverlessworkflow.impl.WorkflowDefinition; import io.serverlessworkflow.impl.test.grpc.handlers.ContributorUnaryArgsExprHandler; +import io.serverlessworkflow.impl.test.junit.DisabledIfProtocUnavailable; import java.io.IOException; import java.util.Map; import org.assertj.core.api.Assertions; @@ -29,6 +30,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +@DisabledIfProtocUnavailable public class GrpcUnaryArgsExprTest { private static final int PORT_FOR_EXAMPLES = 5011; diff --git a/impl/test/src/test/java/io/serverlessworkflow/impl/test/grpc/GrpcUnaryTest.java b/impl/test/src/test/java/io/serverlessworkflow/impl/test/grpc/GrpcUnaryTest.java index 6205ff27e..bce72a72e 100644 --- a/impl/test/src/test/java/io/serverlessworkflow/impl/test/grpc/GrpcUnaryTest.java +++ b/impl/test/src/test/java/io/serverlessworkflow/impl/test/grpc/GrpcUnaryTest.java @@ -22,6 +22,7 @@ import io.serverlessworkflow.impl.WorkflowApplication; import io.serverlessworkflow.impl.WorkflowDefinition; import io.serverlessworkflow.impl.test.grpc.handlers.PersonUnaryHandler; +import io.serverlessworkflow.impl.test.junit.DisabledIfProtocUnavailable; import java.io.IOException; import java.util.Map; import org.assertj.core.api.Assertions; @@ -29,6 +30,7 @@ import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +@DisabledIfProtocUnavailable public class GrpcUnaryTest { private static final int PORT_FOR_EXAMPLES = 5011; diff --git a/impl/test/src/test/java/io/serverlessworkflow/impl/test/junit/BinaryCheckUtil.java b/impl/test/src/test/java/io/serverlessworkflow/impl/test/junit/BinaryCheckUtil.java new file mode 100644 index 000000000..47f3f7f95 --- /dev/null +++ b/impl/test/src/test/java/io/serverlessworkflow/impl/test/junit/BinaryCheckUtil.java @@ -0,0 +1,53 @@ +/* + * Copyright 2020-Present The Serverless Workflow Specification Authors + * + * 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 io.serverlessworkflow.impl.test.junit; + +import java.io.IOException; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.TimeUnit; + +public final class BinaryCheckUtil { + + private static final ConcurrentMap BINARY_CHECKS = new ConcurrentHashMap<>(); + + private BinaryCheckUtil() {} + + public static boolean isBinaryAvailable(String... command) { + return BINARY_CHECKS.computeIfAbsent( + String.join(" ", command), + __ -> { + Process process; + try { + process = + new ProcessBuilder(command) + .redirectErrorStream(true) + .redirectOutput(ProcessBuilder.Redirect.DISCARD) + .start(); + } catch (IOException e) { + return false; + } + try { + return process.waitFor(2, TimeUnit.SECONDS) && process.exitValue() == 0; + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return false; + } finally { + process.destroyForcibly(); + } + }); + } +} diff --git a/impl/test/src/test/java/io/serverlessworkflow/impl/test/junit/DisabledIfProtocUnavailable.java b/impl/test/src/test/java/io/serverlessworkflow/impl/test/junit/DisabledIfProtocUnavailable.java new file mode 100644 index 000000000..5b91e3a9d --- /dev/null +++ b/impl/test/src/test/java/io/serverlessworkflow/impl/test/junit/DisabledIfProtocUnavailable.java @@ -0,0 +1,27 @@ +/* + * Copyright 2020-Present The Serverless Workflow Specification Authors + * + * 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 io.serverlessworkflow.impl.test.junit; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.junit.jupiter.api.extension.ExtendWith; + +@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@ExtendWith(ProtocCheckCondition.class) +public @interface DisabledIfProtocUnavailable {} diff --git a/impl/test/src/test/java/io/serverlessworkflow/impl/test/junit/DisabledIfPythonUnavailable.java b/impl/test/src/test/java/io/serverlessworkflow/impl/test/junit/DisabledIfPythonUnavailable.java new file mode 100644 index 000000000..dcaa116e1 --- /dev/null +++ b/impl/test/src/test/java/io/serverlessworkflow/impl/test/junit/DisabledIfPythonUnavailable.java @@ -0,0 +1,27 @@ +/* + * Copyright 2020-Present The Serverless Workflow Specification Authors + * + * 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 io.serverlessworkflow.impl.test.junit; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import org.junit.jupiter.api.extension.ExtendWith; + +@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@ExtendWith(PythonCheckCondition.class) +public @interface DisabledIfPythonUnavailable {} diff --git a/impl/test/src/test/java/io/serverlessworkflow/impl/test/junit/ProtocCheckCondition.java b/impl/test/src/test/java/io/serverlessworkflow/impl/test/junit/ProtocCheckCondition.java new file mode 100644 index 000000000..e4ff9b98d --- /dev/null +++ b/impl/test/src/test/java/io/serverlessworkflow/impl/test/junit/ProtocCheckCondition.java @@ -0,0 +1,53 @@ +/* + * Copyright 2020-Present The Serverless Workflow Specification Authors + * + * 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 io.serverlessworkflow.impl.test.junit; + +import static io.serverlessworkflow.impl.test.junit.BinaryCheckUtil.isBinaryAvailable; + +import com.github.os72.protocjar.Protoc; +import org.junit.jupiter.api.extension.ConditionEvaluationResult; +import org.junit.jupiter.api.extension.ExecutionCondition; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.platform.commons.util.AnnotationUtils; + +public class ProtocCheckCondition implements ExecutionCondition { + + private static boolean protocAvailable = false; + + static { + try { + protocAvailable = Protoc.runProtoc(new String[] {"--version"}) == 0; + } catch (Exception e) { + // ignore + } + if (!protocAvailable) { + protocAvailable = isBinaryAvailable("protoc", "--version"); + } + } + + @Override + public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) { + return AnnotationUtils.findAnnotation(context.getElement(), DisabledIfProtocUnavailable.class) + .map( + annotation -> + protocAvailable + ? ConditionEvaluationResult.enabled( + "Protoc is available for the current platform.") + : ConditionEvaluationResult.disabled( + "Test disabled: Protoc not currently available not found.")) + .orElse(ConditionEvaluationResult.enabled("No @DisabledIfProtocUnavailable found.")); + } +} diff --git a/impl/test/src/test/java/io/serverlessworkflow/impl/test/junit/PythonCheckCondition.java b/impl/test/src/test/java/io/serverlessworkflow/impl/test/junit/PythonCheckCondition.java new file mode 100644 index 000000000..66f789fc6 --- /dev/null +++ b/impl/test/src/test/java/io/serverlessworkflow/impl/test/junit/PythonCheckCondition.java @@ -0,0 +1,37 @@ +/* + * Copyright 2020-Present The Serverless Workflow Specification Authors + * + * 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 io.serverlessworkflow.impl.test.junit; + +import static io.serverlessworkflow.impl.test.junit.BinaryCheckUtil.isBinaryAvailable; + +import org.junit.jupiter.api.extension.ConditionEvaluationResult; +import org.junit.jupiter.api.extension.ExecutionCondition; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.platform.commons.util.AnnotationUtils; + +public class PythonCheckCondition implements ExecutionCondition { + + @Override + public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) { + return AnnotationUtils.findAnnotation(context.getElement(), DisabledIfPythonUnavailable.class) + .map( + annotation -> + isBinaryAvailable("python", "--version") + ? ConditionEvaluationResult.enabled("Python is available.") + : ConditionEvaluationResult.disabled("Test disabled: Python not found.")) + .orElse(ConditionEvaluationResult.enabled("No @DisabledIfBinaryUnavailable found.")); + } +}