diff --git a/buildSrc/src/main/kotlin/com.hedera.fullstack.jpms-modules.gradle.kts b/buildSrc/src/main/kotlin/com.hedera.fullstack.jpms-modules.gradle.kts index 7c11ba55c..ab0cf0d6a 100644 --- a/buildSrc/src/main/kotlin/com.hedera.fullstack.jpms-modules.gradle.kts +++ b/buildSrc/src/main/kotlin/com.hedera.fullstack.jpms-modules.gradle.kts @@ -23,6 +23,8 @@ plugins { javaModuleDependencies { versionsFromConsistentResolution(":fullstack-helm-client") + + moduleNameToGA.put("com.hedera.fullstack.junit.support", "com.hedera.fullstack:fullstack-junit-support") } extraJavaModuleInfo { diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/EnableHashIO.java b/fullstack-base-api/src/main/java/com/hedera/fullstack/base/api/units/StorageUnits.java similarity index 72% rename from fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/EnableHashIO.java rename to fullstack-base-api/src/main/java/com/hedera/fullstack/base/api/units/StorageUnits.java index 1345a586d..923dbc7e4 100644 --- a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/EnableHashIO.java +++ b/fullstack-base-api/src/main/java/com/hedera/fullstack/base/api/units/StorageUnits.java @@ -14,12 +14,14 @@ * limitations under the License. */ -package com.hedera.fullstack.junit.support.annotations; +package com.hedera.fullstack.base.api.units; -import java.lang.annotation.*; - -@Inherited -@Documented -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.TYPE, ElementType.METHOD}) -public @interface EnableHashIO {} +public enum StorageUnits { + BYTES, + KILOBYTES, + MEGABYTES, + GIGABYTES, + TERABYTES, + PETABYTES, + EXABYTES +} diff --git a/fullstack-base-api/src/main/java/module-info.java b/fullstack-base-api/src/main/java/module-info.java index f67c569a9..797375f7c 100644 --- a/fullstack-base-api/src/main/java/module-info.java +++ b/fullstack-base-api/src/main/java/module-info.java @@ -5,5 +5,6 @@ exports com.hedera.fullstack.base.api.reflect; exports com.hedera.fullstack.base.api.resource; exports com.hedera.fullstack.base.api.util; + exports com.hedera.fullstack.base.api.units; exports com.hedera.fullstack.base.api.version; } diff --git a/fullstack-examples/build.gradle.kts b/fullstack-examples/build.gradle.kts index f9776d955..47325bb76 100644 --- a/fullstack-examples/build.gradle.kts +++ b/fullstack-examples/build.gradle.kts @@ -17,3 +17,16 @@ plugins { id("com.hedera.fullstack.conventions") } dependencies { api(platform(project(":fullstack-bom"))) } + +testing { + suites { + @Suppress("UnstableApiUsage", "unused") + val fullStackTest by + registering(JvmTestSuite::class) { + useJUnitJupiter() + dependencies { implementation(project(":fullstack-examples")) } + } + } +} + +tasks.assemble.configure { dependsOn(tasks.named("fullStackTestClasses")) } diff --git a/fullstack-examples/src/fullStackTest/java/com/hedera/fullstack/examples/signing/InvalidStateSignatureTest.java b/fullstack-examples/src/fullStackTest/java/com/hedera/fullstack/examples/signing/InvalidStateSignatureTest.java new file mode 100644 index 000000000..3beacfc9c --- /dev/null +++ b/fullstack-examples/src/fullStackTest/java/com/hedera/fullstack/examples/signing/InvalidStateSignatureTest.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.examples.signing; + +import com.hedera.fullstack.examples.monitors.InvalidStateSignatureMonitor; +import com.hedera.fullstack.examples.monitors.LogErrorMonitor; +import com.hedera.fullstack.examples.monitors.NodeLivenessMonitor; +import com.hedera.fullstack.examples.readiness.NodeActiveReadinessCheck; +import com.hedera.fullstack.examples.validators.NodeStatisticHealthValidator; +import com.hedera.fullstack.junit.support.annotations.application.ApplicationNodes; +import com.hedera.fullstack.junit.support.annotations.application.PlatformApplication; +import com.hedera.fullstack.junit.support.annotations.application.PlatformConfiguration; +import com.hedera.fullstack.junit.support.annotations.core.ConfigurationValue; +import com.hedera.fullstack.junit.support.annotations.core.FullStackSuite; +import com.hedera.fullstack.junit.support.annotations.core.FullStackTest; +import com.hedera.fullstack.junit.support.annotations.core.TestExecutionMode; +import com.hedera.fullstack.junit.support.annotations.flow.MaxTestExecutionTime; +import com.hedera.fullstack.junit.support.annotations.flow.WaitForDuration; +import com.hedera.fullstack.junit.support.annotations.resource.ResourceShape; +import com.hedera.fullstack.junit.support.annotations.validation.Monitors; +import com.hedera.fullstack.junit.support.annotations.validation.ReadinessChecks; +import com.hedera.fullstack.junit.support.annotations.validation.Validators; +import java.util.concurrent.TimeUnit; +import org.junit.jupiter.api.DisplayName; + +@FullStackSuite +@ApplicationNodes(value = 4, shape = @ResourceShape(cpuInMillis = 8_000, memorySize = 8L)) +@PlatformApplication(fileName = "ISSTestingTool.jar") +@ReadinessChecks({NodeActiveReadinessCheck.class}) +@Monitors({NodeLivenessMonitor.class, LogErrorMonitor.class, InvalidStateSignatureMonitor.class}) +@Validators({NodeStatisticHealthValidator.class}) +@PlatformConfiguration({ + @ConfigurationValue(name = "state.dumpStateOnAnyISS", value = "false"), + @ConfigurationValue(name = "state.automatedSelfIssRecovery", value = "true"), + @ConfigurationValue(name = "state.haltOnCatastrophicIss", value = "true"), + @ConfigurationValue(name = "event.preconsensus.enableReplay", value = "false"), + @ConfigurationValue(name = "event.preconsensus.enableStorage", value = "false") +}) +@DisplayName("Invalid State Signature Testing Tool") +class InvalidStateSignatureTest { + + @FullStackTest(mode = TestExecutionMode.TIMED_EXECUTION) + @WaitForDuration(value = 5, unit = TimeUnit.MINUTES) + @MaxTestExecutionTime(value = 15, unit = TimeUnit.MINUTES) + @PlatformConfiguration({ + @ConfigurationValue(name = "issTestingTool.plannedISSs", value = "180:0-1-2-3"), + }) + @DisplayName("ISS-catastrophic-1k-5m") + void catastrophic_1k_5m() {} +} diff --git a/fullstack-examples/src/fullStackTest/java/com/hedera/fullstack/examples/signing/PlatformSignatureVerificationTest.java b/fullstack-examples/src/fullStackTest/java/com/hedera/fullstack/examples/signing/PlatformSignatureVerificationTest.java new file mode 100644 index 000000000..908263afd --- /dev/null +++ b/fullstack-examples/src/fullStackTest/java/com/hedera/fullstack/examples/signing/PlatformSignatureVerificationTest.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.examples.signing; + +import com.hedera.fullstack.base.api.units.StorageUnits; +import com.hedera.fullstack.junit.support.annotations.application.ApplicationNodes; +import com.hedera.fullstack.junit.support.annotations.application.NamedApplicationNode; +import com.hedera.fullstack.junit.support.annotations.application.NamedApplicationNodes; +import com.hedera.fullstack.junit.support.annotations.core.FullStackSuite; +import com.hedera.fullstack.junit.support.annotations.core.FullStackTest; +import com.hedera.fullstack.junit.support.annotations.core.ParameterizedFullStackTest; +import com.hedera.fullstack.junit.support.annotations.flow.MaxTestExecutionTime; +import com.hedera.fullstack.junit.support.annotations.resource.ResourceShape; +import java.util.concurrent.TimeUnit; +import java.util.stream.Stream; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Named; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +@FullStackSuite +public class PlatformSignatureVerificationTest { + + @FullStackTest + void testBasicCase() {} + + @FullStackTest + @ApplicationNodes( + value = 4, + shape = @ResourceShape(cpuInMillis = 10_000, memorySize = 64, memoryUnits = StorageUnits.GIGABYTES)) + @DisplayName("SSTT: Basic Signatures - Mixed Algorithms - 4 Nodes - 10k TPS") + void testBasicSignaturesMixedAlgorithms() {} + + @FullStackTest + @DisplayName("SSTT: Quick Basic Signatures - 2 Nodes - 500 TPS") + @MaxTestExecutionTime(value = 5, unit = TimeUnit.MINUTES) + @NamedApplicationNodes({ + @NamedApplicationNode("node1"), + @NamedApplicationNode(value = "node2", shape = @ResourceShape(cpuInMillis = 2500)) + }) + void testQuickBasicSignatures() {} + + static Stream testScalingBasicSignatures() { + return Stream.of(Arguments.of(Named.of("5k TPS", 5000)), Arguments.of(Named.of("10k TPS", 10000))); + } + + @ParameterizedFullStackTest + @DisplayName("SSTT: Scaling Basic Signatures - 4 Nodes") + @ApplicationNodes(6) + @MethodSource + void testScalingBasicSignatures(int tps) {} +} diff --git a/fullstack-examples/src/fullStackTest/java/com/hedera/fullstack/examples/signing/StatsSigningTest.java b/fullstack-examples/src/fullStackTest/java/com/hedera/fullstack/examples/signing/StatsSigningTest.java new file mode 100644 index 000000000..541269f48 --- /dev/null +++ b/fullstack-examples/src/fullStackTest/java/com/hedera/fullstack/examples/signing/StatsSigningTest.java @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.examples.signing; + +import com.hedera.fullstack.examples.monitors.InvalidStateSignatureMonitor; +import com.hedera.fullstack.examples.monitors.LogErrorMonitor; +import com.hedera.fullstack.examples.monitors.NodeLivenessMonitor; +import com.hedera.fullstack.examples.readiness.NodeActiveReadinessCheck; +import com.hedera.fullstack.examples.validators.NodeStatisticHealthValidator; +import com.hedera.fullstack.junit.support.annotations.application.ApplicationNodes; +import com.hedera.fullstack.junit.support.annotations.application.PlatformApplication; +import com.hedera.fullstack.junit.support.annotations.core.FullStackSuite; +import com.hedera.fullstack.junit.support.annotations.core.FullStackTest; +import com.hedera.fullstack.junit.support.annotations.core.TestExecutionMode; +import com.hedera.fullstack.junit.support.annotations.flow.MaxTestExecutionTime; +import com.hedera.fullstack.junit.support.annotations.flow.WaitForDuration; +import com.hedera.fullstack.junit.support.annotations.resource.ResourceShape; +import com.hedera.fullstack.junit.support.annotations.validation.Monitors; +import com.hedera.fullstack.junit.support.annotations.validation.ReadinessChecks; +import com.hedera.fullstack.junit.support.annotations.validation.Validators; +import org.junit.jupiter.api.DisplayName; + +@FullStackSuite +@DisplayName("Stats Signing Testing Tool") +class StatsSigningTest { + + /** + * Replaces the existing {@code Crypto-Basic-10k-4N} test. + * This test will run the StatsSigningTestingTool.jar at 10k TPS for 20 minutes. + */ + @FullStackTest(mode = TestExecutionMode.TIMED_EXECUTION) + @ApplicationNodes(value = 4, shape = @ResourceShape(cpuInMillis = 32_000)) + @WaitForDuration(value = 20, unit = java.util.concurrent.TimeUnit.MINUTES) + @MaxTestExecutionTime(value = 30, unit = java.util.concurrent.TimeUnit.MINUTES) + @PlatformApplication( + fileName = "StatsSigningTestingTool.jar", + parameters = {"1", "3000", "0", "100", "-1", "10000", "5000"}) + @ReadinessChecks({ + NodeActiveReadinessCheck.class, + }) + @Monitors({NodeLivenessMonitor.class, LogErrorMonitor.class, InvalidStateSignatureMonitor.class}) + @Validators({NodeStatisticHealthValidator.class}) + @DisplayName("Basic 10k TPS - 20 minutes") + void basic() {} +} diff --git a/fullstack-examples/src/fullStackTest/java/module-info.java b/fullstack-examples/src/fullStackTest/java/module-info.java new file mode 100644 index 000000000..afe8cd302 --- /dev/null +++ b/fullstack-examples/src/fullStackTest/java/module-info.java @@ -0,0 +1,11 @@ +module com.hedera.fullstack.examples.fullstacktest { + exports com.hedera.fullstack.examples.signing to + org.junit.platform.commons; + + opens com.hedera.fullstack.examples.signing to + org.junit.platform.commons; + + requires com.hedera.fullstack.examples; + requires com.hedera.fullstack.junit.support; + requires org.junit.jupiter.api; +} diff --git a/fullstack-examples/src/main/java/com/hedera/fullstack/examples/monitors/InvalidStateSignatureMonitor.java b/fullstack-examples/src/main/java/com/hedera/fullstack/examples/monitors/InvalidStateSignatureMonitor.java new file mode 100644 index 000000000..8cbaf9fd9 --- /dev/null +++ b/fullstack-examples/src/main/java/com/hedera/fullstack/examples/monitors/InvalidStateSignatureMonitor.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.examples.monitors; + +import com.hedera.fullstack.monitoring.api.CheckOutcome; +import com.hedera.fullstack.monitoring.api.Monitor; + +public class InvalidStateSignatureMonitor implements Monitor { + @Override + public CheckOutcome check() { + return CheckOutcome.SUCCESS; + } +} diff --git a/fullstack-examples/src/main/java/com/hedera/fullstack/examples/monitors/LogErrorMonitor.java b/fullstack-examples/src/main/java/com/hedera/fullstack/examples/monitors/LogErrorMonitor.java new file mode 100644 index 000000000..7ef6e027e --- /dev/null +++ b/fullstack-examples/src/main/java/com/hedera/fullstack/examples/monitors/LogErrorMonitor.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.examples.monitors; + +import com.hedera.fullstack.monitoring.api.CheckOutcome; +import com.hedera.fullstack.monitoring.api.Monitor; + +public class LogErrorMonitor implements Monitor { + @Override + public CheckOutcome check() { + return CheckOutcome.SUCCESS; + } +} diff --git a/fullstack-examples/src/main/java/com/hedera/fullstack/examples/monitors/NodeLivenessMonitor.java b/fullstack-examples/src/main/java/com/hedera/fullstack/examples/monitors/NodeLivenessMonitor.java new file mode 100644 index 000000000..7d65d03b6 --- /dev/null +++ b/fullstack-examples/src/main/java/com/hedera/fullstack/examples/monitors/NodeLivenessMonitor.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.examples.monitors; + +import com.hedera.fullstack.monitoring.api.CheckOutcome; +import com.hedera.fullstack.monitoring.api.Monitor; + +public class NodeLivenessMonitor implements Monitor { + @Override + public CheckOutcome check() { + return CheckOutcome.SUCCESS; + } +} diff --git a/fullstack-examples/src/main/java/com/hedera/fullstack/examples/readiness/NodeActiveReadinessCheck.java b/fullstack-examples/src/main/java/com/hedera/fullstack/examples/readiness/NodeActiveReadinessCheck.java new file mode 100644 index 000000000..92f120703 --- /dev/null +++ b/fullstack-examples/src/main/java/com/hedera/fullstack/examples/readiness/NodeActiveReadinessCheck.java @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.examples.readiness; + +import com.hedera.fullstack.readiness.api.ReadinessCheck; + +public class NodeActiveReadinessCheck implements ReadinessCheck { + + @Override + public boolean ready() { + return true; + } +} diff --git a/fullstack-examples/src/main/java/com/hedera/fullstack/examples/validators/NodeStatisticHealthValidator.java b/fullstack-examples/src/main/java/com/hedera/fullstack/examples/validators/NodeStatisticHealthValidator.java new file mode 100644 index 000000000..a8c27ac9d --- /dev/null +++ b/fullstack-examples/src/main/java/com/hedera/fullstack/examples/validators/NodeStatisticHealthValidator.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.examples.validators; + +import com.hedera.fullstack.validator.api.ValidationContext; +import com.hedera.fullstack.validator.api.ValidationResult; +import com.hedera.fullstack.validator.api.Validator; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Future; + +public class NodeStatisticHealthValidator implements Validator { + + @Override + public Future validate(ValidationContext context) { + return CompletableFuture.completedFuture(null); + } +} diff --git a/fullstack-examples/src/main/java/module-info.java b/fullstack-examples/src/main/java/module-info.java index e12f75112..da2ebeab9 100644 --- a/fullstack-examples/src/main/java/module-info.java +++ b/fullstack-examples/src/main/java/module-info.java @@ -1 +1,9 @@ -module com.hedera.fullstack.examples {} +module com.hedera.fullstack.examples { + exports com.hedera.fullstack.examples.monitors; + exports com.hedera.fullstack.examples.readiness; + exports com.hedera.fullstack.examples.validators; + + requires com.hedera.fullstack.readiness.api; + requires com.hedera.fullstack.monitoring.api; + requires com.hedera.fullstack.validator.api; +} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/FullStackTestSuite.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/FullStackTestSuite.java deleted file mode 100644 index b19da2f2e..000000000 --- a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/FullStackTestSuite.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2023 Hedera Hashgraph, LLC - * - * 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.hedera.fullstack.junit.support.annotations; - -import com.hedera.fullstack.junit.support.extensions.TestSuiteInitializer; -import java.lang.annotation.*; -import org.junit.jupiter.api.extension.ExtendWith; -import org.junit.jupiter.api.parallel.Execution; -import org.junit.jupiter.api.parallel.ExecutionMode; - -@Inherited -@Documented -@Target({ElementType.TYPE}) -@Retention(RetentionPolicy.RUNTIME) -@Execution(ExecutionMode.SAME_THREAD) -@ExtendWith({TestSuiteInitializer.class}) -public @interface FullStackTestSuite {} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/application/ApplicationNodes.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/application/ApplicationNodes.java new file mode 100644 index 000000000..32fd8f86e --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/application/ApplicationNodes.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.junit.support.annotations.application; + +import com.hedera.fullstack.junit.support.annotations.resource.ResourceShape; +import java.lang.annotation.*; + +/** + * Defines multiple identical application nodes with a resource shape specification, and zero or more tags. This + * annotation is mutually exclusive with the {@link NamedApplicationNode} annotation and must not be used in conjunction + * with each other on the same element. When {@link ApplicationNodes}, {@link NamedApplicationNode}, or any combination + * thereof is defined at the class level and at the test method level, then the annotations declared on the class will + * be ignored and only the annotations declared on the test method will be used. + * + * @see NamedApplicationNode + * @see NamedApplicationNodes + */ +@Inherited +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.METHOD}) +public @interface ApplicationNodes { + /** + * The number of identical application nodes to be created. This value must be greater than or equal to 1. + * + * @return the number of application nodes. + */ + int value(); + + /** + * The description of the physical machine specification on which the application is deployed. Uses the defaults + * as defined in {@link ResourceShape} if not explicitly specified. + * + * @return the resource shape specification. + */ + ResourceShape shape() default @ResourceShape; + + /** + * An optional array of tags to be applied to the application node. The default value is an empty array. + * + * @return an array of tags. + */ + String[] tags() default {}; +} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/application/NamedApplicationNode.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/application/NamedApplicationNode.java new file mode 100644 index 000000000..90c517750 --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/application/NamedApplicationNode.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.junit.support.annotations.application; + +import com.hedera.fullstack.junit.support.annotations.resource.ResourceShape; +import java.lang.annotation.*; + +/** + * Defines a single application node with a name, resource shape specification, and zero or more tags. This annotation + * is mutually exclusive with the {@link ApplicationNodes} annotation and must not be used in conjunction + * with each other on the same element. When {@link ApplicationNodes}, {@link NamedApplicationNode}, or any combination + * thereof is defined at the class level and at the test method level, then the annotations declared on the class will + * be ignored and only the annotations declared on the test method will be used. + * + * @see ApplicationNodes + * @see NamedApplicationNodes + */ +@Inherited +@Documented +@Repeatable(NamedApplicationNodes.class) +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.METHOD}) +public @interface NamedApplicationNode { + /** + * The user specific name or identifier of the application node. This name must be unique within the scope of the + * test suite and test method. If this annotation is declared on a test method, then the name must be unique within + * the scope of the test method. If this annotation is declared on a test class, then the name must be unique within + * the scope of the test class. + *

The user provided name must conform to the DNS label specification as defined in RFC 1035 (summarized below): + *

+ * + * @return the name of the application node. + */ + String value(); + + /** + * The description of the physical machine specification on which the application is deployed. Uses the defaults + * as defined in {@link ResourceShape} if not explicitly specified. + * + * @return the resource shape specification. + */ + ResourceShape shape() default @ResourceShape; + + /** + * An optional array of tags to be applied to the application node. The default value is an empty array. + * + * @return an array of tags. + */ + String[] tags() default {}; +} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/application/NamedApplicationNodes.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/application/NamedApplicationNodes.java new file mode 100644 index 000000000..30d631db2 --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/application/NamedApplicationNodes.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.junit.support.annotations.application; + +import java.lang.annotation.*; + +/** + * A container annotation for {@link NamedApplicationNode}. This annotation allows multiple + * {@link NamedApplicationNode} annotations to be declared on a single element. + *

Please see the documentation for {@link NamedApplicationNode} for more information. + * + * @see NamedApplicationNode + */ +@Inherited +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.METHOD}) +public @interface NamedApplicationNodes { + /** + * The array of {@link NamedApplicationNode} annotations which have been applied to the target element. + * + * @return an array of {@link NamedApplicationNode} annotations. + */ + NamedApplicationNode[] value(); +} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/application/PlatformApplication.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/application/PlatformApplication.java new file mode 100644 index 000000000..c9a075d4a --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/application/PlatformApplication.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.junit.support.annotations.application; + +import java.lang.annotation.*; + +/** + * Configures the Platform application to be executed by a test. This annotation may be applied to a test class or + * test method. If applied to a test class, the configuration will be applied to all test methods in the class. If + * applied to a test method, the configuration will be applied to only that test method. If applied to both a test + * class and a test method, the configuration applied to the test method will override the configuration applied to + * the test class. + */ +@Inherited +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.METHOD}) +public @interface PlatformApplication { + /** + * Specifies the name of the Platform application jar file. The default value is {@code HederaNode.jar}. Only the + * name of the JAR file should be specified, not the path. The JAR file must be located in the {@code data/apps} + * directory of the Platform deployment. + * + *

+ * This value is used to form the {@code } portion of {@code app, , } specification + * for the Platform SDK {@code config.txt} definition. + * + * @return the name of the Platform application jar file. + */ + String fileName() default "HederaNode.jar"; + + /** + * Specifies the parameters to be passed to the Platform application. The default value is an empty array. The + * parameters are passed to the Platform application in the order specified. The values must not contain any commas. + * + *

+ * This value is used to form the {@code } portion of {@code app, , } specification + * for the Platform SDK {@code config.txt} definition. + * + * @return the parameters to be passed to the Platform application. + */ + String[] parameters() default {}; +} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/application/PlatformConfiguration.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/application/PlatformConfiguration.java new file mode 100644 index 000000000..8bec72805 --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/application/PlatformConfiguration.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.junit.support.annotations.application; + +import com.hedera.fullstack.junit.support.annotations.core.ConfigurationValue; +import java.lang.annotation.*; + +/** + * Specifies the configuration values used by the Platform SDK {@code settings.txt} file. This annotation may be applied + * to a test class or to a test method. If applied to a test class, the configuration values are applied to all test + * methods in the class. If applied to a test method, the configuration values are applied only to that test method. If + * applied to both a test class and a test method, the configuration values will be merged with the overlapping values + * specified by the test method taking precedence. These values are always merged with the default values with + * the overlapping values supplied by this annotation taking precedence. + */ +@Inherited +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.METHOD}) +public @interface PlatformConfiguration { + /** + * The configuration values to be applied to the Platform SDK {@code settings.txt} file. + * + * @return an array of configuration values. + */ + ConfigurationValue[] value(); +} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/core/ConfigurationValue.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/core/ConfigurationValue.java new file mode 100644 index 000000000..1920f9986 --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/core/ConfigurationValue.java @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.junit.support.annotations.core; + +import java.lang.annotation.*; + +/** + * Represents a generic configuration value which comprises a key and value pair. This annotation may only be used + * in conjunction with other annotations and may not be directly applied to test classes or methods. + */ +@Inherited +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({}) +public @interface ConfigurationValue { + /** + * The key or name of the configuration value. Depending on the context, the key format may vary. + * + * @return the key or name of the configuration value. + */ + String name(); + + /** + * The value of the specified configuration key/name. Depending on the context, the value format may vary. + * + * @return the value of the specified configuration key/name. + */ + String value(); +} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/core/FullStackSuite.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/core/FullStackSuite.java new file mode 100644 index 000000000..052c05b72 --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/core/FullStackSuite.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.junit.support.annotations.core; + +import com.hedera.fullstack.junit.support.extensions.TestSetupExtension; +import com.hedera.fullstack.junit.support.extensions.TestSuiteConfigurationExtension; +import com.hedera.fullstack.junit.support.extensions.TestSuiteTeardownExtension; +import com.hedera.fullstack.junit.support.extensions.TestTeardownExtension; +import java.lang.annotation.*; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.parallel.Execution; + +/** + * The primary and mandatory annotation which must be applied to all test classes which are to be executed as part of + * a full stack test suite. This annotation is a meta-annotation which provides several JUnit Jupiter extensions. + * These extensions are responsible for setting up and tearing down the test suite, as well as setting up and tearing + * down each individual test. + *

+ * The test provisioning and concurrency model is dictated by a combination consisting of the JUnit built-in + * {@link Execution} annotation, the {@code junit.jupiter.execution.parallel.enabled} property, the + * {@code junit.jupiter.execution.parallel.mode.default} property and the full stack {@link #provisioningModel()} value + * specified by this annotation. + *

+ * Please refer to the documentation of the {@link ProvisioningModel} enumeration for more information. + *

+ * NOTE: Any unit test bearing this annotation should only contain Full Stack driven unit tests. Combining + * regular unit tests with Full Stack based unit tests in a single class is not supported. + * + * @see ProvisioningModel + */ +@Inherited +@Documented +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@ExtendWith({ + TestSuiteConfigurationExtension.class, + TestSuiteTeardownExtension.class, + TestSetupExtension.class, + TestTeardownExtension.class +}) +public @interface FullStackSuite { + /** + * The provisioning model to be used for the test suite. The default value is {@link ProvisioningModel#CLEAN_ENV_PER_TEST}. + * Please see the {@link ProvisioningModel} documentation for more information. + * + * @return the provisioning model to be used for the test suite. + */ + ProvisioningModel provisioningModel() default ProvisioningModel.CLEAN_ENV_PER_TEST; +} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/core/FullStackTest.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/core/FullStackTest.java new file mode 100644 index 000000000..b2d72d9f3 --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/core/FullStackTest.java @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.junit.support.annotations.core; + +import com.hedera.fullstack.junit.support.annotations.flow.WaitForDuration; +import java.lang.annotation.*; +import org.junit.jupiter.api.Test; + +/** + * One of the two primary annotations used to mark a test method to be executed as a full stack test case. The other + * annotation is {@link ParameterizedFullStackTest}. All test methods in a class bearing the {@link FullStackSuite} + * annotation must be annotated with either {@link FullStackTest} or {@link ParameterizedFullStackTest}. + * + * @see FullStackSuite + * @see ParameterizedFullStackTest + */ +@Inherited +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD}) +@Test +public @interface FullStackTest { + /** + * The Full Stack execution mode for the annotated test method. The default value is {@link TestExecutionMode#DEFAULT}. + * + *

+ * Full Stack tests support three modes of execution: + *

+ * + *

+ * The {@link TestExecutionMode#DEFAULT} mode provisions the infrastructure resources, deploys and configures the + * application, waits for readiness checks to pass, starts the monitors, and finally turns over control to the test + * method. + * + *

+ * The {@link TestExecutionMode#TIMED_EXECUTION} mode provisions the infrastructure resources, deploys and + * configures the application, waits for readiness checks to pass, starts the monitors, and then waits for the time + * specified by the {@link WaitForDuration} to elapse before turning over control to the test method. + * + *

+ * The {@link TestExecutionMode#PROVISION_ONLY} mode provisions resources, deploys the application, configures + * the application, and then passes control to the test method. The provision only mode does not start the node + * software and does not run any of the readiness checks or monitors. Additionally, validators are not automatically + * executed when the test method completes or throws an exception. The provision only mode is useful for tests which + * need explicit control over readiness check, monitor, and validator executions. + * + * @return the execution flow used by this test. + * @see TestExecutionMode + */ + TestExecutionMode mode() default TestExecutionMode.DEFAULT; + + /** + * The Full Stack test execution framework for the node software. The default value is + * {@link TestExecutorType#JAVA_DIRECT}. + * + *

+ * Full Stack tests support two execution frameworks: + *

+ * + *

+ * The {@link TestExecutorType#JAVA_DIRECT} framework executes the node software using the {@code ubi8-init-java17} + * docker container image. The {@code ubi8-init-java17} image is built from the {@code ubi8-init} image and + * includes the Java 17 JDK. Tests using this framework are executed directly in the container using the embedded + * Java 17 JDK. Node Management Tools are not available when using this framework and are not used for any of the + * provisioning, configuration, or monitoring operations. + * + *

+ * The {@link TestExecutorType#NODE_MGMT_TOOLS} framework executes the node software using the {@code ubi8-init-dind} + * docker container image. The {@code ubi8-init-dind} image is built from the {@code ubi8-init} image and includes + * the Docker daemon. Tests using this framework are provisioned and executed via the Node Management Tools. + * + * @return the execution framework used by this test. + */ + TestExecutorType executor() default TestExecutorType.JAVA_DIRECT; +} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/core/ParameterizedFullStackTest.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/core/ParameterizedFullStackTest.java new file mode 100644 index 000000000..15dfb5d53 --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/core/ParameterizedFullStackTest.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.junit.support.annotations.core; + +import java.lang.annotation.*; +import org.junit.jupiter.params.ParameterizedTest; + +/** + * One of the two primary annotations used to mark a test method to be executed as a full stack test case. The other + * annotation is {@link FullStackTest}. All test methods in a class bearing the {@link FullStackSuite} + * annotation must be annotated with either {@link FullStackTest} or {@link ParameterizedFullStackTest}. + * + * @see FullStackSuite + * @see FullStackTest + */ +@Inherited +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD}) +@ParameterizedTest +public @interface ParameterizedFullStackTest { + /** + * Please see the documentation for {@link FullStackTest#mode()} for a description of the supported execution flows. + * + * @see FullStackTest#mode() + * @return the execution flow used by this test. + */ + TestExecutionMode mode() default TestExecutionMode.DEFAULT; + + /** + * Please see the documentation for {@link FullStackTest#executor()} for a description of the supported execution + * frameworks. + * + * @see FullStackTest#executor() + * @return the execution framework used by this test. + */ + TestExecutorType executor() default TestExecutorType.JAVA_DIRECT; +} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/core/ProvisioningModel.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/core/ProvisioningModel.java new file mode 100644 index 000000000..0b80fa397 --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/core/ProvisioningModel.java @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.junit.support.annotations.core; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.parallel.ExecutionMode; + +/** + * The provisioning model determines how the test environment is provisioned. These options are mutually exclusive and + * may be set on the {@link FullStackSuite} annotation. + * + * @see FullStackSuite + */ +public enum ProvisioningModel { + /** + * The clean environment per test model will provision a new environment for each test method. This is the default + * behavior. This model works for all levels of JUnit concurrency and guarantees each test method will be executed + * in a clean environment with no side effects from other tests. + */ + CLEAN_ENV_PER_TEST, + /** + * The clean environment per class model will provision a new environment for each test class. This model works for + * the {@link ExecutionMode#SAME_THREAD} concurrency model and guarantees each test class will be executed in a + * new environment provisioned for the test class and will be cleaned between test method executions. This model + * attempts to provide, but does not guarantee a side effect free environment for each test method execution. + */ + CLEAN_ENV_PER_CLASS, + /** + * The shared environment per class model will provision a single environment for all test methods in a test class. + * This model works for all levels of JUnit concurrency. The environment will not be cleaned between test method + * executions and does not guarantee a side effect free environment for each test method execution. Additionally, + * the application will not be stopped between test method executions unless a test method or a user supplied + * {@link AfterEach} method explicitly does so. + */ + SHARED_PER_CLASS +} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/core/TestExecutionMode.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/core/TestExecutionMode.java new file mode 100644 index 000000000..91534f4fd --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/core/TestExecutionMode.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.junit.support.annotations.core; + +import com.hedera.fullstack.junit.support.annotations.flow.WaitForDuration; + +/** + * The test execution mode determines how the test method will be executed. These options are mutually exclusive and + * may be set on the {@link FullStackTest} and {@link ParameterizedFullStackTest} annotations. + * + * @see FullStackSuite + * @see ParameterizedFullStackTest + * @see WaitForDuration + */ +public enum TestExecutionMode { + /** + * The default behavior is to provision resources, start the application, wait for any readiness checks, and + * start any monitors before the test method is executed. + */ + DEFAULT, + + /** + * Timed execution mode will provision resources, start the application, wait for any readiness checks, start any + * monitors, and then wait for the {@link WaitForDuration} to expire before executing the test method. + */ + TIMED_EXECUTION, + + /** + * Provision only mode will stage the resources, but not start the application, monitors, or wait for readiness checks. + * The test method will be executed immediately after the basic resources are provisioned. The provision only mode + * ignores the {@link WaitForDuration} annotation, if present. + */ + PROVISION_ONLY, +} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/core/TestExecutorType.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/core/TestExecutorType.java new file mode 100644 index 000000000..450f26977 --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/core/TestExecutorType.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.junit.support.annotations.core; + +/** + * The test executor type determines how a test is provisioned and executed. These options are mutually exclusive and + * may be set on the {@link FullStackTest} and {@link ParameterizedFullStackTest} annotations. + * + * @see FullStackSuite + * @see ParameterizedFullStackTest + */ +public enum TestExecutorType { + /** + * The Java Direct mode provisions the {@code ubi8-init-java17} base image and runs the test directly on the + * installed JVM without any Node Management Tool based provisioning. This mode is the default and is meant to be + * extremely fast and flexible. + */ + JAVA_DIRECT, + + /** + * The Node Management Tools mode provisions the {@code ubi8-init-dind} base image and runs the test using the + * Node Management Tools provisioning mechanism. This mode is meant to be used for tests that require a more + * realistic environment or depend on network upgrades. This mode is inherently slower and less customizable than + * the Java Direct mode. + */ + NODE_MGMT_TOOLS +} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/flow/MaxTestExecutionTime.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/flow/MaxTestExecutionTime.java new file mode 100644 index 000000000..450bc037d --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/flow/MaxTestExecutionTime.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.junit.support.annotations.flow; + +import java.lang.annotation.*; +import java.util.concurrent.TimeUnit; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; + +/** + * Specifies the maximum time a test is permitted to execute before it is considered to have failed. This time is + * inclusive of all time spent in the test method and in {@link BeforeAll}, {@link BeforeEach}, {@link AfterEach}, and + * {@link AfterAll} methods declared by the test suite. For a parameterized test, the timeout applies separately to each + * invocation of the test method for each unique set of arguments. + *

+ * If this annotation is not present on a test class, then this timeout will individually apply to each test method. + * Specifying this annotation at the class level will not impose a maximum execution time on the test class as a whole. + */ +@Inherited +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.METHOD}) +public @interface MaxTestExecutionTime { + /** + * The maximum number of time units the test is permitted to execute before it is considered to have failed. + * + * @return the maximum number of time units. + */ + int value(); + + /** + * The time unit of the {@link #value()}. Defaults to {@link TimeUnit#SECONDS}. + * + * @return the time unit of the {@link #value()}. + */ + TimeUnit unit() default TimeUnit.SECONDS; +} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/flow/SuppressMonitors.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/flow/SuppressMonitors.java new file mode 100644 index 000000000..c81716607 --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/flow/SuppressMonitors.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.junit.support.annotations.flow; + +import com.hedera.fullstack.monitoring.api.Monitor; +import java.lang.annotation.*; + +/** + * Suppresses the specified monitors for the annotated method. The behavior of this annotation is to suppress the + * monitor, if present, regardless of the inheritance path from which the monitor was applied. + */ +@Inherited +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD}) +public @interface SuppressMonitors { + /** + * An array of monitors to suppress. + * + * @return the array of monitors to be suppressed. + */ + Class[] value(); + + // String[] nodeLabels() default {}; + // + // int[] nodeIndices() default {}; +} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/flow/SuppressReadinessChecks.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/flow/SuppressReadinessChecks.java new file mode 100644 index 000000000..d4b6321ae --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/flow/SuppressReadinessChecks.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.junit.support.annotations.flow; + +import com.hedera.fullstack.readiness.api.ReadinessCheck; +import java.lang.annotation.*; + +/** + * Suppresses the specified readiness checks for the annotated method. The behavior of this annotation is to suppress the + * readiness check, if present, regardless of the inheritance path from which the readiness check was applied. + */ +@Inherited +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD}) +public @interface SuppressReadinessChecks { + /** + * An array of readiness checks to suppress. + * + * @return the array of readiness checks to be suppressed. + */ + Class[] value(); + + // String[] nodeLabels() default {}; + // + // int[] nodeIndices() default {}; +} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/flow/SuppressValidators.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/flow/SuppressValidators.java new file mode 100644 index 000000000..ebc7d3e17 --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/flow/SuppressValidators.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.junit.support.annotations.flow; + +import com.hedera.fullstack.validator.api.Validator; +import java.lang.annotation.*; + +/** + * Suppresses the specified validators for the annotated method. The behavior of this annotation is to suppress the + * validator, if present, regardless of the inheritance path from which the validator was applied. + */ +@Inherited +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD}) +public @interface SuppressValidators { + /** + * An array of validators to suppress. + * + * @return the array of validators to be suppressed. + */ + Class[] value(); + + // String[] nodeLabels() default {}; + // + // int[] nodeIndices() default {}; +} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/flow/WaitForDuration.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/flow/WaitForDuration.java new file mode 100644 index 000000000..f6ebdc61e --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/flow/WaitForDuration.java @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.junit.support.annotations.flow; + +import com.hedera.fullstack.junit.support.annotations.core.FullStackTest; +import com.hedera.fullstack.junit.support.annotations.core.TestExecutionMode; +import java.lang.annotation.*; +import java.util.concurrent.TimeUnit; + +/** + * Instructs the test framework to wait for a specified duration before executing the test body. This only applies + * when the {@link FullStackTest#mode()} is {@link TestExecutionMode#TIMED_EXECUTION}. If the + * {@link FullStackTest#mode()} is set to any other value, then this annotation will be silently ignored. + */ +@Inherited +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD}) +public @interface WaitForDuration { + /** + * The amount of time units for which to wait before executing the test body. + * + * @return the number of time units. + */ + int value(); + + /** + * The time unit of the {@link #value()}. Defaults to {@link TimeUnit#SECONDS}. + * + * @return the time unit of the {@link #value()}. + * @see TimeUnit + */ + TimeUnit unit() default TimeUnit.SECONDS; +} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/resource/HelmChart.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/resource/HelmChart.java new file mode 100644 index 000000000..b9c4dbf95 --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/resource/HelmChart.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.junit.support.annotations.resource; + +import java.lang.annotation.*; + +/** + * Represents a Helm chart identifier in component form (repository, chart, version). + */ +@Inherited +@Documented +@Target({}) +@Retention(RetentionPolicy.RUNTIME) +public @interface HelmChart { + /** + * The Helm repository URL where the chart is located. This is synonymous with the URL used by the Helm CLI + * {@code helm repo add } command syntax. + * + * @return the Helm repository URL where the chart is located. + */ + String repository(); + + /** + * The identifier of the Helm chart. This is synonymous with the name used by the Helm CLI + * {@code helm install } command syntax. + * + * @return the Helm chart identifier. + */ + String chart(); + + /** + * The version of the Helm chart. This must be a valid Semantic Version (SemVer) string as required by the + * Helm Chart v2 specification. + * + * @return the Helm chart semantic version. + */ + String version(); +} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/resource/ResourceShape.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/resource/ResourceShape.java new file mode 100644 index 000000000..88929dd7f --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/resource/ResourceShape.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.junit.support.annotations.resource; + +import com.hedera.fullstack.base.api.units.StorageUnits; +import com.hedera.fullstack.junit.support.annotations.application.ApplicationNodes; +import com.hedera.fullstack.junit.support.annotations.application.NamedApplicationNode; +import java.lang.annotation.*; + +/** + * Describes the resource limits (CPU, Memory, Disk) for a physical machine, K8S pod, or container. This annotation + * must be used as a parameter of another annotation, such as {@link ApplicationNodes} or {@link NamedApplicationNode}. + */ +@Inherited +@Documented +@Target({}) +@Retention(RetentionPolicy.RUNTIME) +public @interface ResourceShape { + /** + * Defines the maximum allowable CPU cores in milli-cores. The milli-cores units are identical to the units used by + * Kubernetes. For example, 1000 milli-cores is equivalent to 1 CPU core or hyper-thread. The default value is 2 CPU + * cores/hyper-threads. + * + * @return the maximum allowable CPU cores in milli-cores. + */ + float cpuInMillis() default 2000f; + + /** + * The maximum memory to be allocated scaled according to the units specified by the {@link #memoryUnits()} property. + * The default value is 16 GB. + * + * @return the maximum memory to be allocated. + */ + long memorySize() default 16L; + + /** + * The units for the {@link #memorySize()} property. The default value is {@link StorageUnits#GIGABYTES}. + * + * @return the units for the {@link #memorySize()} property. + */ + StorageUnits memoryUnits() default StorageUnits.GIGABYTES; + + /** + * The maximum disk size to be allocated scaled according to the units specified by the {@link #diskUnits()} property. + * The default value is 32 GB. + * + * @return the maximum disk size to be allocated. + */ + long diskSize() default 32L; + + /** + * The units for the {@link #diskSize()} property. The default value is {@link StorageUnits#GIGABYTES}. + * + * @return the units for the {@link #diskSize()} property. + */ + StorageUnits diskUnits() default StorageUnits.GIGABYTES; +} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/EnableProxyServer.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/services/EnvoyProxy.java similarity index 76% rename from fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/EnableProxyServer.java rename to fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/services/EnvoyProxy.java index 35f527e25..57b5cce67 100644 --- a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/EnableProxyServer.java +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/services/EnvoyProxy.java @@ -14,12 +14,16 @@ * limitations under the License. */ -package com.hedera.fullstack.junit.support.annotations; +package com.hedera.fullstack.junit.support.annotations.services; import java.lang.annotation.*; +/** + * Indicates that the annotated test class or test method requires one or more Envoy Proxy servers to be deployed and + * running. + */ @Inherited @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) -public @interface EnableProxyServer {} +public @interface EnvoyProxy {} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/ApplicationNodes.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/services/HashIO.java similarity index 72% rename from fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/ApplicationNodes.java rename to fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/services/HashIO.java index 21807d034..b5b56b7a9 100644 --- a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/ApplicationNodes.java +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/services/HashIO.java @@ -14,17 +14,16 @@ * limitations under the License. */ -package com.hedera.fullstack.junit.support.annotations; +package com.hedera.fullstack.junit.support.annotations.services; -import com.hedera.fullstack.junit.support.ApplicationProvisioner; import java.lang.annotation.*; +/** + * Indicates that the annotated test class or test method requires an HashIO server to be deployed and running. This + * annotation also implicitly specifies the {@link MirrorNode} annotation. + */ @Inherited @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) -public @interface ApplicationNodes { - int value(); - - Class provisioner() default ApplicationProvisioner.class; -} +public @interface HashIO {} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/LabeledApplicationNode.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/services/HashScan.java similarity index 69% rename from fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/LabeledApplicationNode.java rename to fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/services/HashScan.java index 8e84942de..9d1a88a0d 100644 --- a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/LabeledApplicationNode.java +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/services/HashScan.java @@ -14,18 +14,16 @@ * limitations under the License. */ -package com.hedera.fullstack.junit.support.annotations; +package com.hedera.fullstack.junit.support.annotations.services; -import com.hedera.fullstack.junit.support.ApplicationProvisioner; import java.lang.annotation.*; +/** + * Indicates that the annotated test class or test method requires a HashScan server (Hedera Mirror Node Explorer) + * to be deployed and running. This annotation also implicitly specifies the {@link MirrorNode} annotation. + */ @Inherited @Documented -@Repeatable(LabeledApplicationNodes.class) @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) -public @interface LabeledApplicationNode { - String value(); - - Class provisioner() default ApplicationProvisioner.class; -} +public @interface HashScan {} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/EnableMirrorNode.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/services/HttpProxy.java similarity index 76% rename from fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/EnableMirrorNode.java rename to fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/services/HttpProxy.java index 3ddb1b411..31c20a4cf 100644 --- a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/EnableMirrorNode.java +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/services/HttpProxy.java @@ -14,12 +14,16 @@ * limitations under the License. */ -package com.hedera.fullstack.junit.support.annotations; +package com.hedera.fullstack.junit.support.annotations.services; import java.lang.annotation.*; +/** + * Indicates that the annotated test class or test method requires one or more HAProxy servers to be deployed and + * running. + */ @Inherited @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) -public @interface EnableMirrorNode {} +public @interface HttpProxy {} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/EnableHashScan.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/services/MirrorNode.java similarity index 77% rename from fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/EnableHashScan.java rename to fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/services/MirrorNode.java index f26c62f26..85aca3a93 100644 --- a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/EnableHashScan.java +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/services/MirrorNode.java @@ -14,12 +14,15 @@ * limitations under the License. */ -package com.hedera.fullstack.junit.support.annotations; +package com.hedera.fullstack.junit.support.annotations.services; import java.lang.annotation.*; +/** + * Indicates that the annotated test class or test method requires a mirror node to be deployed and running. + */ @Inherited @Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) -public @interface EnableHashScan {} +public @interface MirrorNode {} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/validation/Monitors.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/validation/Monitors.java new file mode 100644 index 000000000..443315b6c --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/validation/Monitors.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.junit.support.annotations.validation; + +import com.hedera.fullstack.junit.support.annotations.flow.SuppressMonitors; +import com.hedera.fullstack.monitoring.api.Monitor; +import java.lang.annotation.*; + +/** + * Declares a list of {@link Monitor} implementations which should be executed during the tests. + *

+ * If this annotation is present on a test class, all tests in the class inherit the list of monitors. If this annotation + * is also present on one or more test methods, then the list of monitors declared on the method is appended to the list + * of monitors declared on the class with any duplicates removed. Monitors declared at the class level may be excluded + * on a per monitor and per test basis by using the {@link SuppressMonitors} at the method level. + *

+ * Default monitors will not be used for a test or class if this annotation is present. + */ +@Inherited +@Documented +@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface Monitors { + /** + * The list of {@link Monitor} implementations to be executed during the test. + * + * @return an array of {@link Monitor} implementations. + */ + Class[] value(); +} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/validation/ReadinessChecks.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/validation/ReadinessChecks.java new file mode 100644 index 000000000..cb9f30df9 --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/validation/ReadinessChecks.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.junit.support.annotations.validation; + +import com.hedera.fullstack.junit.support.annotations.flow.SuppressReadinessChecks; +import com.hedera.fullstack.readiness.api.ReadinessCheck; +import java.lang.annotation.*; + +/** + * Declares a list of {@link ReadinessCheck} implementations which should be executed before the test body. + *

+ * If this annotation is present on a test class, all tests in the class inherit the list of readiness checks. If this + * annotation is also present on one or more test methods, then the list of readiness checks declared on the method is + * appended to the list of readiness checks declared on the class with any duplicates removed. Readiness checks declared + * at the class level may be excluded on a per readiness check and per test basis by using the + * {@link SuppressReadinessChecks} at the method level. + *

+ * Default readiness checks will not be used for a test or class if this annotation is present. + */ +@Inherited +@Documented +@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface ReadinessChecks { + /** + * The list of {@link ReadinessCheck} implementations to be executed during the test. + * + * @return an array of {@link ReadinessCheck} implementations. + */ + Class[] value(); +} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/validation/Validators.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/validation/Validators.java new file mode 100644 index 000000000..97c3c6270 --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/validation/Validators.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.junit.support.annotations.validation; + +import com.hedera.fullstack.junit.support.annotations.flow.SuppressValidators; +import com.hedera.fullstack.validator.api.Validator; +import java.lang.annotation.*; + +/** + * Declares a list of {@link Validator} implementations which should be executed after the test body. + *

+ * If this annotation is present on a test class, all tests in the class inherit the list of validators. If this + * annotation is also present on one or more test methods, then the list of validators declared on the method is + * appended to the list of validators declared on the class with any duplicates removed. Monitors declared at the class + * level may be excluded on a per validator and per test basis by using the {@link SuppressValidators} at the method + * level. + *

+ * Default validators will not be used for a test or class if this annotation is present. + */ +@Inherited +@Documented +@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface Validators { + /** + * The list of {@link Validator} implementations to be executed during the test. + * + * @return an array of {@link Validator} implementations. + */ + Class[] value(); +} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/events/application/ApplicationEvent.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/events/application/ApplicationEvent.java new file mode 100644 index 000000000..4eb943c67 --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/events/application/ApplicationEvent.java @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.junit.support.events.application; + +/** + * The base interface for all event types which are related to the application lifecycle. + */ +public interface ApplicationEvent {} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/events/application/BeforeApplicationConfigured.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/events/application/BeforeApplicationConfigured.java new file mode 100644 index 000000000..b2bb8e50a --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/events/application/BeforeApplicationConfigured.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.junit.support.events.application; + +/** + * Defines an extension point for the application lifecycle which is invoked before the application node configuration + * is rendered and deployed to the physical environment. This event is invoked for each node in the application topology. + *

+ * Implementations of this extension point are expected to be idempotent and should only modify the configuration + * supplied as method arguments. Mutating state other than the supplied configuration is not recommended and may lead to + * unexpected results. + *

+ * At the time of extension point invocation, it is guaranteed that the defaults have been applied and any class or + * method level annotations have been applied to the configuration. + */ +public interface BeforeApplicationConfigured extends ApplicationEvent { + + /** + * Invoked before the application node configuration is rendered and deployed to the physical environment. + * + * @param index the index of the node in the application topology. + * @param node the application node. + * @param config the application node configuration. + */ + void beforeApplicationConfigured(int index, Object node, Object config); +} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSuiteInitializer.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSetupExtension.java similarity index 59% rename from fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSuiteInitializer.java rename to fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSetupExtension.java index 8796980d9..4ff797802 100644 --- a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSuiteInitializer.java +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSetupExtension.java @@ -16,21 +16,19 @@ package com.hedera.fullstack.junit.support.extensions; +import org.junit.jupiter.api.extension.BeforeEachCallback; import org.junit.jupiter.api.extension.ExtensionContext; -import org.junit.jupiter.api.extension.TestInstancePostProcessor; /** - * Initializes the test class instance for the test suite. This initializer is responsible for reading the class level - * annotations and setting up the suite configuration. + * Handles the individual test setup, configuration, and resource deployment (if applicable). */ -public class TestSuiteInitializer implements TestInstancePostProcessor { - +public class TestSetupExtension implements BeforeEachCallback { /** + * Callback that is invoked before each test is executed. * - * @param testInstance the instance to post-process; never {@code null} * @param context the current extension context; never {@code null} - * @throws Exception if an error occurs during post-processing + * @throws Exception if an error occurs during callback execution. */ @Override - public void postProcessTestInstance(Object testInstance, ExtensionContext context) throws Exception {} + public void beforeEach(final ExtensionContext context) throws Exception {} } diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSuiteConfigurationExtension.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSuiteConfigurationExtension.java new file mode 100644 index 000000000..4f641c921 --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSuiteConfigurationExtension.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.junit.support.extensions; + +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.TestInstanceFactoryContext; +import org.junit.jupiter.api.extension.TestInstancePostProcessor; +import org.junit.jupiter.api.extension.TestInstancePreConstructCallback; + +/** + * Initializes the test class instance for the test suite. This initializer is responsible for reading the class level + * annotations and setting up the suite configuration. Additionally, the individual test annotations will be read and + * validated. The test suite will not be executed if one or more suite or test level validation failures occur. + */ +public class TestSuiteConfigurationExtension implements TestInstancePreConstructCallback, TestInstancePostProcessor { + + /** + * Callback that is invoked before the test instance is constructed. + * + * @param factoryContext the context for the test instance about to be instantiated; never {@code null} + * @param context the current extension context; never {@code null} + * @throws Exception if an error occurs during callback execution. + */ + @Override + public void preConstructTestInstance( + final TestInstanceFactoryContext factoryContext, final ExtensionContext context) throws Exception {} + + /** + * Callback that is invoked after the test instance has been created and configured. + * + * @param testInstance the instance to post-process; never {@code null} + * @param context the current extension context; never {@code null} + * @throws Exception if an error occurs during post-processing + */ + @Override + public void postProcessTestInstance(final Object testInstance, final ExtensionContext context) throws Exception {} +} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSuiteTeardownExtension.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSuiteTeardownExtension.java new file mode 100644 index 000000000..537067870 --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestSuiteTeardownExtension.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.junit.support.extensions; + +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.TestInstancePreDestroyCallback; + +/** + * Handles the test suite teardown and resource cleanup. + */ +public class TestSuiteTeardownExtension implements TestInstancePreDestroyCallback { + /** + * Callback for processing test instances before they are destroyed. + * + * @param context the current extension context; never {@code null} + * @throws Exception if an error occurs during callback execution. + * @see ExtensionContext#getTestInstance() + * @see ExtensionContext#getRequiredTestInstance() + * @see ExtensionContext#getTestInstances() + * @see ExtensionContext#getRequiredTestInstances() + */ + @Override + public void preDestroyTestInstance(ExtensionContext context) throws Exception {} +} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestTeardownExtension.java b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestTeardownExtension.java new file mode 100644 index 000000000..d4851edb9 --- /dev/null +++ b/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/extensions/TestTeardownExtension.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.junit.support.extensions; + +import org.junit.jupiter.api.extension.AfterEachCallback; +import org.junit.jupiter.api.extension.ExtensionContext; + +/** + * Handles the individual test teardown and resource cleanup. + */ +public class TestTeardownExtension implements AfterEachCallback { + /** + * Callback that is invoked after an individual test and any user-defined teardown methods for that test + * have been executed. + * + * @param context the current extension context; never {@code null} + * @throws Exception if an error occurs during callback execution. + */ + @Override + public void afterEach(final ExtensionContext context) throws Exception {} +} diff --git a/fullstack-junit-support/src/main/java/module-info.java b/fullstack-junit-support/src/main/java/module-info.java index 5440b8e98..8e130a5ed 100644 --- a/fullstack-junit-support/src/main/java/module-info.java +++ b/fullstack-junit-support/src/main/java/module-info.java @@ -1,3 +1,24 @@ module com.hedera.fullstack.junit.support { + // Global Exports + exports com.hedera.fullstack.junit.support.annotations.application; + exports com.hedera.fullstack.junit.support.annotations.core; + exports com.hedera.fullstack.junit.support.annotations.flow; + exports com.hedera.fullstack.junit.support.annotations.resource; + exports com.hedera.fullstack.junit.support.annotations.services; + exports com.hedera.fullstack.junit.support.annotations.validation; + exports com.hedera.fullstack.junit.support.events.application; + + // Targeted Exports + exports com.hedera.fullstack.junit.support.extensions to + org.junit.platform.commons; + + // Transitive Requirements + requires transitive com.hedera.fullstack.base.api; + requires transitive com.hedera.fullstack.validator.api; + requires transitive com.hedera.fullstack.monitoring.api; + requires transitive com.hedera.fullstack.readiness.api; requires transitive org.junit.jupiter.api; + requires transitive org.junit.jupiter.params; + +// Direct Requirements } diff --git a/fullstack-monitoring-api/src/main/java/com/hedera/fullstack/monitoring/api/Dummy.java b/fullstack-monitoring-api/src/main/java/com/hedera/fullstack/monitoring/api/CheckOutcome.java similarity index 87% rename from fullstack-monitoring-api/src/main/java/com/hedera/fullstack/monitoring/api/Dummy.java rename to fullstack-monitoring-api/src/main/java/com/hedera/fullstack/monitoring/api/CheckOutcome.java index 5c396c33f..3de5afe4e 100644 --- a/fullstack-monitoring-api/src/main/java/com/hedera/fullstack/monitoring/api/Dummy.java +++ b/fullstack-monitoring-api/src/main/java/com/hedera/fullstack/monitoring/api/CheckOutcome.java @@ -16,4 +16,10 @@ package com.hedera.fullstack.monitoring.api; -public class Dummy {} +public enum CheckOutcome { + NOT_READY, + WAITING, + SUCCESS, + FAILURE, + SKIPPED +} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/LabeledApplicationNodes.java b/fullstack-monitoring-api/src/main/java/com/hedera/fullstack/monitoring/api/Monitor.java similarity index 67% rename from fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/LabeledApplicationNodes.java rename to fullstack-monitoring-api/src/main/java/com/hedera/fullstack/monitoring/api/Monitor.java index d2e44cf32..a47304b6d 100644 --- a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/annotations/LabeledApplicationNodes.java +++ b/fullstack-monitoring-api/src/main/java/com/hedera/fullstack/monitoring/api/Monitor.java @@ -14,14 +14,18 @@ * limitations under the License. */ -package com.hedera.fullstack.junit.support.annotations; +package com.hedera.fullstack.monitoring.api; -import java.lang.annotation.*; +import java.time.Duration; -@Inherited -@Documented -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.TYPE, ElementType.METHOD}) -public @interface LabeledApplicationNodes { - LabeledApplicationNode[] value(); +@FunctionalInterface +public interface Monitor { + + Duration DEFAULT_CHECK_INTERVAL = Duration.ofSeconds(5); + + CheckOutcome check(); + + default Duration checkInterval() { + return DEFAULT_CHECK_INTERVAL; + } } diff --git a/fullstack-monitoring-api/src/main/java/module-info.java b/fullstack-monitoring-api/src/main/java/module-info.java index 9bb4b7d89..f8671b8d5 100644 --- a/fullstack-monitoring-api/src/main/java/module-info.java +++ b/fullstack-monitoring-api/src/main/java/module-info.java @@ -1 +1,3 @@ -module com.hedera.fullstack.monitoring.api {} +module com.hedera.fullstack.monitoring.api { + exports com.hedera.fullstack.monitoring.api; +} diff --git a/fullstack-examples/src/main/java/com/hedera/fullstack/examples/Dummy.java b/fullstack-readiness-api/build.gradle.kts similarity index 83% rename from fullstack-examples/src/main/java/com/hedera/fullstack/examples/Dummy.java rename to fullstack-readiness-api/build.gradle.kts index 0d1d4770b..37ba083c1 100644 --- a/fullstack-examples/src/main/java/com/hedera/fullstack/examples/Dummy.java +++ b/fullstack-readiness-api/build.gradle.kts @@ -14,6 +14,6 @@ * limitations under the License. */ -package com.hedera.fullstack.examples; +plugins { id("com.hedera.fullstack.conventions") } -public class Dummy {} +dependencies { api(enforcedPlatform(project(":fullstack-bom"))) } diff --git a/fullstack-readiness-api/gradle.properties b/fullstack-readiness-api/gradle.properties new file mode 100644 index 000000000..c733d432a --- /dev/null +++ b/fullstack-readiness-api/gradle.properties @@ -0,0 +1,17 @@ +# +# Copyright (C) 2023 Hedera Hashgraph, LLC +# +# 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. +# + +version=0.1.0-SNAPSHOT diff --git a/fullstack-readiness-api/src/main/java/com/hedera/fullstack/readiness/api/ReadinessCheck.java b/fullstack-readiness-api/src/main/java/com/hedera/fullstack/readiness/api/ReadinessCheck.java new file mode 100644 index 000000000..8b37e9542 --- /dev/null +++ b/fullstack-readiness-api/src/main/java/com/hedera/fullstack/readiness/api/ReadinessCheck.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2023 Hedera Hashgraph, LLC + * + * 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.hedera.fullstack.readiness.api; + +import java.time.Duration; + +@FunctionalInterface +public interface ReadinessCheck { + Duration DEFAULT_CHECK_INTERVAL = Duration.ofSeconds(1); + Duration DEFAULT_CHECK_TIMEOUT = Duration.ofSeconds(60); + + boolean ready(); + + default Duration checkInterval() { + return DEFAULT_CHECK_INTERVAL; + } + + default Duration checkTimeout() { + return DEFAULT_CHECK_TIMEOUT; + } +} diff --git a/fullstack-readiness-api/src/main/java/module-info.java b/fullstack-readiness-api/src/main/java/module-info.java new file mode 100644 index 000000000..0d7dd0791 --- /dev/null +++ b/fullstack-readiness-api/src/main/java/module-info.java @@ -0,0 +1,3 @@ +module com.hedera.fullstack.readiness.api { + exports com.hedera.fullstack.readiness.api; +} diff --git a/fullstack-readiness-api/src/test/java/module-info.java b/fullstack-readiness-api/src/test/java/module-info.java new file mode 100644 index 000000000..d7acc9b06 --- /dev/null +++ b/fullstack-readiness-api/src/test/java/module-info.java @@ -0,0 +1 @@ +module com.hedera.fullstack.readiness.api.test {} diff --git a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/ApplicationProvisioner.java b/fullstack-validator-api/src/main/java/com/hedera/fullstack/validator/api/ValidationOutcome.java similarity index 78% rename from fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/ApplicationProvisioner.java rename to fullstack-validator-api/src/main/java/com/hedera/fullstack/validator/api/ValidationOutcome.java index c10eb8b8f..2ffcd061a 100644 --- a/fullstack-junit-support/src/main/java/com/hedera/fullstack/junit/support/ApplicationProvisioner.java +++ b/fullstack-validator-api/src/main/java/com/hedera/fullstack/validator/api/ValidationOutcome.java @@ -14,9 +14,11 @@ * limitations under the License. */ -package com.hedera.fullstack.junit.support; +package com.hedera.fullstack.validator.api; -public interface ApplicationProvisioner { - - void beforeApplicationConfigured(int index, Object node, Object config); +public enum ValidationOutcome { + PASS, + FAIL, + WARN, + SKIP } diff --git a/fullstack-validator-api/src/main/java/com/hedera/fullstack/validator/api/ValidationResult.java b/fullstack-validator-api/src/main/java/com/hedera/fullstack/validator/api/ValidationResult.java index 0d534aec7..1a8d17f3c 100644 --- a/fullstack-validator-api/src/main/java/com/hedera/fullstack/validator/api/ValidationResult.java +++ b/fullstack-validator-api/src/main/java/com/hedera/fullstack/validator/api/ValidationResult.java @@ -16,7 +16,13 @@ package com.hedera.fullstack.validator.api; +import java.util.List; + /** * */ -public interface ValidationResult {} +public interface ValidationResult { + ValidationOutcome getOutcome(); + + List getDetails(); +} diff --git a/fullstack-validator-api/src/main/java/com/hedera/fullstack/validator/api/Validator.java b/fullstack-validator-api/src/main/java/com/hedera/fullstack/validator/api/Validator.java index 4f42fbcc7..4576cf20e 100644 --- a/fullstack-validator-api/src/main/java/com/hedera/fullstack/validator/api/Validator.java +++ b/fullstack-validator-api/src/main/java/com/hedera/fullstack/validator/api/Validator.java @@ -21,6 +21,7 @@ /** * */ +@FunctionalInterface public interface Validator { /** * diff --git a/fullstack-validator-api/src/main/java/com/hedera/fullstack/validator/api/annotations/ValidateAlways.java b/fullstack-validator-api/src/main/java/com/hedera/fullstack/validator/api/annotations/ValidateAlways.java index 4e014d0c1..60cda0022 100644 --- a/fullstack-validator-api/src/main/java/com/hedera/fullstack/validator/api/annotations/ValidateAlways.java +++ b/fullstack-validator-api/src/main/java/com/hedera/fullstack/validator/api/annotations/ValidateAlways.java @@ -20,7 +20,7 @@ /** * Indicates the annotated {@link com.hedera.fullstack.validator.api.Validator} implementation should always be executed, - * even if the test has already failed. + * even if the test has already failed or if a prior validator reports a failure. */ @Inherited @Documented diff --git a/fullstack-validator-api/src/main/java/com/hedera/fullstack/validator/api/annotations/ValidateOnFailure.java b/fullstack-validator-api/src/main/java/com/hedera/fullstack/validator/api/annotations/ValidateOnFailure.java index b48275795..c1f585fe5 100644 --- a/fullstack-validator-api/src/main/java/com/hedera/fullstack/validator/api/annotations/ValidateOnFailure.java +++ b/fullstack-validator-api/src/main/java/com/hedera/fullstack/validator/api/annotations/ValidateOnFailure.java @@ -20,7 +20,7 @@ /** * Indicates the annotated {@link com.hedera.fullstack.validator.api.Validator} implementation should only be executed - * if the test has failed. + * if the test has failed or if a prior validator has failed. */ @Inherited @Documented diff --git a/fullstack-validator-api/src/main/java/module-info.java b/fullstack-validator-api/src/main/java/module-info.java index bb5cd76fb..571b4ee18 100644 --- a/fullstack-validator-api/src/main/java/module-info.java +++ b/fullstack-validator-api/src/main/java/module-info.java @@ -1 +1,8 @@ -module com.hedera.fullstack.validator.api {} +import com.hedera.fullstack.validator.api.Validator; + +module com.hedera.fullstack.validator.api { + exports com.hedera.fullstack.validator.api; + exports com.hedera.fullstack.validator.api.annotations; + + uses Validator; +} diff --git a/settings.gradle.kts b/settings.gradle.kts index becd69530..45efa5148 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -55,6 +55,8 @@ include(":fullstack-monitoring-api") include(":fullstack-monitoring-core") +include(":fullstack-readiness-api") + include(":fullstack-reporting-api") include(":fullstack-reporting-core")