From a101a34c7fddb91b232a9919d8831d9466e594ab Mon Sep 17 00:00:00 2001 From: Quinn Klassen Date: Thu, 16 Jan 2025 15:39:51 -0800 Subject: [PATCH 1/2] Make sure GetVersion never yields --- .../io/temporal/internal/common/SdkFlag.java | 4 + .../replay/ReplayWorkflowContext.java | 2 +- .../replay/ReplayWorkflowContextImpl.java | 2 +- .../statemachines/VersionStateMachine.java | 4 +- .../statemachines/WorkflowStateMachines.java | 4 +- .../internal/sync/SyncWorkflowContext.java | 25 +- ...ltVersionNotSupportedDuringReplayTest.java | 4 + .../GetVersionMultithreadingRemoveTest.java | 97 +++++++ ...GetVersionMultithreadingRemoveHistory.json | 257 ++++++++++++++++++ .../sync/DummySyncWorkflowContext.java | 2 +- 10 files changed, 392 insertions(+), 9 deletions(-) create mode 100644 temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionMultithreadingRemoveTest.java create mode 100644 temporal-sdk/src/test/resources/testGetVersionMultithreadingRemoveHistory.json diff --git a/temporal-sdk/src/main/java/io/temporal/internal/common/SdkFlag.java b/temporal-sdk/src/main/java/io/temporal/internal/common/SdkFlag.java index 658b44e0d..68533ac80 100644 --- a/temporal-sdk/src/main/java/io/temporal/internal/common/SdkFlag.java +++ b/temporal-sdk/src/main/java/io/temporal/internal/common/SdkFlag.java @@ -30,6 +30,10 @@ public enum SdkFlag { * Changes behavior of GetVersion to not yield if no previous call existed in history. */ SKIP_YIELD_ON_DEFAULT_VERSION(1), + /* + * Changes behavior of GetVersion to never yield. + */ + SKIP_YIELD_ON_VERSION(2), UNKNOWN(Integer.MAX_VALUE); private final int value; diff --git a/temporal-sdk/src/main/java/io/temporal/internal/replay/ReplayWorkflowContext.java b/temporal-sdk/src/main/java/io/temporal/internal/replay/ReplayWorkflowContext.java index 377b6b7c7..8c219d42d 100644 --- a/temporal-sdk/src/main/java/io/temporal/internal/replay/ReplayWorkflowContext.java +++ b/temporal-sdk/src/main/java/io/temporal/internal/replay/ReplayWorkflowContext.java @@ -284,7 +284,7 @@ void mutableSideEffect( * @param callback used to return version * @return True if the identifier is not present in history */ - boolean getVersion( + Integer getVersion( String changeId, int minSupported, int maxSupported, diff --git a/temporal-sdk/src/main/java/io/temporal/internal/replay/ReplayWorkflowContextImpl.java b/temporal-sdk/src/main/java/io/temporal/internal/replay/ReplayWorkflowContextImpl.java index 4a3e81b23..3556d1700 100644 --- a/temporal-sdk/src/main/java/io/temporal/internal/replay/ReplayWorkflowContextImpl.java +++ b/temporal-sdk/src/main/java/io/temporal/internal/replay/ReplayWorkflowContextImpl.java @@ -324,7 +324,7 @@ public void mutableSideEffect( } @Override - public boolean getVersion( + public Integer getVersion( String changeId, int minSupported, int maxSupported, diff --git a/temporal-sdk/src/main/java/io/temporal/internal/statemachines/VersionStateMachine.java b/temporal-sdk/src/main/java/io/temporal/internal/statemachines/VersionStateMachine.java index 12de236fd..93aee5832 100644 --- a/temporal-sdk/src/main/java/io/temporal/internal/statemachines/VersionStateMachine.java +++ b/temporal-sdk/src/main/java/io/temporal/internal/statemachines/VersionStateMachine.java @@ -379,7 +379,7 @@ private VersionStateMachine( * @param callback used to return version * @return True if the identifier is not present in history */ - public boolean getVersion( + public Integer getVersion( int minSupported, int maxSupported, Functions.Proc2 callback) { InvocationStateMachine ism = new InvocationStateMachine(minSupported, maxSupported, callback); ism.explicitEvent(ExplicitEvent.CHECK_EXECUTION_STATE); @@ -390,7 +390,7 @@ public boolean getVersion( // This means either this version marker did not exist in the original execution or // the version marker did exist, but was in an earlier WFT. If the version marker was in a // previous WFT then the version field should have a value. - return !(ism.getState() == VersionStateMachine.State.SKIPPED_REPLAYING && version == null); + return version == null ? preloadedVersion : version; } public void handleNonMatchingEvent(HistoryEvent event) { diff --git a/temporal-sdk/src/main/java/io/temporal/internal/statemachines/WorkflowStateMachines.java b/temporal-sdk/src/main/java/io/temporal/internal/statemachines/WorkflowStateMachines.java index 260e3acf3..1be219f88 100644 --- a/temporal-sdk/src/main/java/io/temporal/internal/statemachines/WorkflowStateMachines.java +++ b/temporal-sdk/src/main/java/io/temporal/internal/statemachines/WorkflowStateMachines.java @@ -60,7 +60,7 @@ enum HandleEventStatus { /** Initial set of SDK flags that will be set on all new workflow executions. */ private static final List initialFlags = Collections.unmodifiableList( - Collections.singletonList(SdkFlag.SKIP_YIELD_ON_DEFAULT_VERSION)); + Arrays.asList(SdkFlag.SKIP_YIELD_ON_DEFAULT_VERSION, SdkFlag.SKIP_YIELD_ON_VERSION)); /** * EventId of the WorkflowTaskStarted event of the Workflow Task that was picked up by a worker @@ -1074,7 +1074,7 @@ public void mutableSideEffect( stateMachineSink); } - public boolean getVersion( + public Integer getVersion( String changeId, int minSupported, int maxSupported, diff --git a/temporal-sdk/src/main/java/io/temporal/internal/sync/SyncWorkflowContext.java b/temporal-sdk/src/main/java/io/temporal/internal/sync/SyncWorkflowContext.java index dc5906b9d..4115f1747 100644 --- a/temporal-sdk/src/main/java/io/temporal/internal/sync/SyncWorkflowContext.java +++ b/temporal-sdk/src/main/java/io/temporal/internal/sync/SyncWorkflowContext.java @@ -1119,7 +1119,7 @@ private R mutableSideEffectImpl( @Override public int getVersion(String changeId, int minSupported, int maxSupported) { CompletablePromise result = Workflow.newPromise(); - boolean markerExists = + Integer versionToUse = replayContext.getVersion( changeId, minSupported, @@ -1140,12 +1140,33 @@ public int getVersion(String changeId, int minSupported, int maxSupported) { * because it can lead to non-deterministic scheduling. * */ if (replayContext.isReplaying() - && !markerExists + && versionToUse == null && replayContext.tryUseSdkFlag(SdkFlag.SKIP_YIELD_ON_DEFAULT_VERSION) && minSupported == DEFAULT_VERSION) { return DEFAULT_VERSION; } + /* + * Previously the SDK would yield on the getVersion call to the scheduler. This is not ideal because it can lead to non-deterministic + * scheduling if the getVersion call was removed. + * */ + if (replayContext.tryUseSdkFlag(SdkFlag.SKIP_YIELD_ON_VERSION)) { + // This can happen if we are replaying a workflow and encounter a getVersion call that did not + // exist on the original execution. + // and the range does not include the default version. + if (versionToUse == null) { + versionToUse = DEFAULT_VERSION; + } + if (versionToUse < minSupported || versionToUse > maxSupported) { + throw new UnsupportedVersion( + new UnsupportedVersion.UnsupportedVersionException( + String.format( + "Version %d of changeId %s is not supported. Supported v is between %d and %d.", + versionToUse, changeId, minSupported, maxSupported))); + } + return versionToUse; + } + // Legacy behavior if SKIP_YIELD_ON_VERSION is not set try { return result.get(); } catch (UnsupportedVersion.UnsupportedVersionException ex) { diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/DefaultVersionNotSupportedDuringReplayTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/DefaultVersionNotSupportedDuringReplayTest.java index 6ce933651..e0fe26d71 100644 --- a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/DefaultVersionNotSupportedDuringReplayTest.java +++ b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/DefaultVersionNotSupportedDuringReplayTest.java @@ -28,6 +28,7 @@ import io.temporal.workflow.shared.TestWorkflows.TestWorkflowReturnString; import io.temporal.workflow.unsafe.WorkflowUnsafe; import java.time.Duration; +import org.junit.Assert; import org.junit.Rule; import org.junit.Test; @@ -64,6 +65,9 @@ public String execute() { try { Workflow.getVersion("test_change", 2, 3); } catch (UnsupportedVersion e) { + Assert.assertEquals( + "Version -1 of changeId test_change is not supported. Supported v is between 2 and 3.", + e.getMessage()); unsupportedVersionExceptionThrown.signal(); throw e; } diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionMultithreadingRemoveTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionMultithreadingRemoveTest.java new file mode 100644 index 000000000..79c26ff66 --- /dev/null +++ b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionMultithreadingRemoveTest.java @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2022 Temporal Technologies, Inc. All Rights Reserved. + * + * Copyright (C) 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Modifications copyright (C) 2017 Uber Technologies, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this material except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.temporal.workflow.versionTests; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import io.temporal.testing.WorkflowReplayer; +import io.temporal.testing.internal.SDKTestOptions; +import io.temporal.testing.internal.SDKTestWorkflowRule; +import io.temporal.worker.WorkerOptions; +import io.temporal.workflow.Async; +import io.temporal.workflow.Workflow; +import io.temporal.workflow.shared.TestActivities; +import io.temporal.workflow.shared.TestWorkflows; +import io.temporal.workflow.unsafe.WorkflowUnsafe; +import java.time.Duration; +import org.junit.Rule; +import org.junit.Test; + +public class GetVersionMultithreadingRemoveTest { + + private static boolean hasReplayed; + + @Rule + public SDKTestWorkflowRule testWorkflowRule = + SDKTestWorkflowRule.newBuilder() + .setWorkflowTypes(TestGetVersionWorkflowImpl.class) + .setActivityImplementations(new TestActivities.TestActivitiesImpl()) + .setUseExternalService(true) + // Forcing a replay. Full history arrived from a normal queue causing a replay. + .setWorkerOptions( + WorkerOptions.newBuilder() + .setStickyQueueScheduleToStartTimeout(Duration.ZERO) + .build()) + .build(); + + @Test + public void testGetVersionMultithreadingRemoval() { + TestWorkflows.TestWorkflow1 workflowStub = + testWorkflowRule.newWorkflowStubTimeoutOptions(TestWorkflows.TestWorkflow1.class); + String result = workflowStub.execute(testWorkflowRule.getTaskQueue()); + assertTrue(hasReplayed); + assertEquals("activity1", result); + } + + @Test + public void testGetVersionMultithreadingRemovalReplay() throws Exception { + WorkflowReplayer.replayWorkflowExecutionFromResource( + "testGetVersionMultithreadingRemoveHistory.json", TestGetVersionWorkflowImpl.class); + } + + public static class TestGetVersionWorkflowImpl implements TestWorkflows.TestWorkflow1 { + + @Override + public String execute(String taskQueue) { + TestActivities.VariousTestActivities testActivities = + Workflow.newActivityStub( + TestActivities.VariousTestActivities.class, + SDKTestOptions.newActivityOptionsForTaskQueue(taskQueue)); + + Async.procedure( + () -> { + Workflow.sleep(1000); + }); + + // Test removing a version check in replaying code with an additional thread running. + if (!WorkflowUnsafe.isReplaying()) { + int version = Workflow.getVersion("changeId", 1, 2); + assertEquals(version, 2); + } else { + hasReplayed = true; + } + String result = + "activity" + testActivities.activity1(1); // This is executed in non-replay mode. + return result; + } + } +} diff --git a/temporal-sdk/src/test/resources/testGetVersionMultithreadingRemoveHistory.json b/temporal-sdk/src/test/resources/testGetVersionMultithreadingRemoveHistory.json new file mode 100644 index 000000000..399df05e3 --- /dev/null +++ b/temporal-sdk/src/test/resources/testGetVersionMultithreadingRemoveHistory.json @@ -0,0 +1,257 @@ +{ + "events": [ + { + "eventId": "1", + "eventTime": "2025-01-16T18:40:18.888021135Z", + "eventType": "EVENT_TYPE_WORKFLOW_EXECUTION_STARTED", + "taskId": "1053133", + "workflowExecutionStartedEventAttributes": { + "workflowType": { + "name": "TestWorkflow1" + }, + "taskQueue": { + "name": "WorkflowTest-testGetVersionMultithreadingRemoval-95ece4de-215c-4933-a089-6c06cbda4f68", + "kind": "TASK_QUEUE_KIND_NORMAL" + }, + "input": { + "payloads": [ + { + "metadata": { + "encoding": "anNvbi9wbGFpbg==" + }, + "data": "IldvcmtmbG93VGVzdC10ZXN0R2V0VmVyc2lvbk11bHRpdGhyZWFkaW5nUmVtb3ZhbC05NWVjZTRkZS0yMTVjLTQ5MzMtYTA4OS02YzA2Y2JkYTRmNjgi" + } + ] + }, + "workflowExecutionTimeout": "0s", + "workflowRunTimeout": "200s", + "workflowTaskTimeout": "5s", + "originalExecutionRunId": "71e7563e-b565-4008-81f4-482871f2304a", + "identity": "96988@Quinn-Klassens-MacBook-Pro.local", + "firstExecutionRunId": "71e7563e-b565-4008-81f4-482871f2304a", + "attempt": 1, + "firstWorkflowTaskBackoff": "0s", + "header": {}, + "workflowId": "8ad4d0a9-caef-43e3-b0b2-d5cf94b1af1e" + } + }, + { + "eventId": "2", + "eventTime": "2025-01-16T18:40:18.888143343Z", + "eventType": "EVENT_TYPE_WORKFLOW_TASK_SCHEDULED", + "taskId": "1053134", + "workflowTaskScheduledEventAttributes": { + "taskQueue": { + "name": "WorkflowTest-testGetVersionMultithreadingRemoval-95ece4de-215c-4933-a089-6c06cbda4f68", + "kind": "TASK_QUEUE_KIND_NORMAL" + }, + "startToCloseTimeout": "5s", + "attempt": 1 + } + }, + { + "eventId": "3", + "eventTime": "2025-01-16T18:40:18.895798427Z", + "eventType": "EVENT_TYPE_WORKFLOW_TASK_STARTED", + "taskId": "1053140", + "workflowTaskStartedEventAttributes": { + "scheduledEventId": "2", + "identity": "96988@Quinn-Klassens-MacBook-Pro.local", + "requestId": "274ce0c8-e4c4-4bbd-957c-27027bb13770", + "historySizeBytes": "552" + } + }, + { + "eventId": "4", + "eventTime": "2025-01-16T18:40:19.016492760Z", + "eventType": "EVENT_TYPE_WORKFLOW_TASK_COMPLETED", + "taskId": "1053144", + "workflowTaskCompletedEventAttributes": { + "scheduledEventId": "2", + "startedEventId": "3", + "identity": "96988@Quinn-Klassens-MacBook-Pro.local", + "workerVersion": {}, + "sdkMetadata": { + "langUsedFlags": [ + 1, + 2 + ] + }, + "meteringMetadata": {} + } + }, + { + "eventId": "5", + "eventTime": "2025-01-16T18:40:19.016582260Z", + "eventType": "EVENT_TYPE_MARKER_RECORDED", + "taskId": "1053145", + "markerRecordedEventAttributes": { + "markerName": "Version", + "details": { + "changeId": { + "payloads": [ + { + "metadata": { + "encoding": "anNvbi9wbGFpbg==" + }, + "data": "ImNoYW5nZUlkIg==" + } + ] + }, + "version": { + "payloads": [ + { + "metadata": { + "encoding": "anNvbi9wbGFpbg==" + }, + "data": "Mg==" + } + ] + } + }, + "workflowTaskCompletedEventId": "4" + } + }, + { + "eventId": "6", + "eventTime": "2025-01-16T18:40:19.016612093Z", + "eventType": "EVENT_TYPE_ACTIVITY_TASK_SCHEDULED", + "taskId": "1053146", + "activityTaskScheduledEventAttributes": { + "activityId": "53d70bb8-4c9b-32b9-a35f-11cfecf8df1f", + "activityType": { + "name": "customActivity1" + }, + "taskQueue": { + "name": "WorkflowTest-testGetVersionMultithreadingRemoval-95ece4de-215c-4933-a089-6c06cbda4f68", + "kind": "TASK_QUEUE_KIND_NORMAL" + }, + "header": {}, + "input": { + "payloads": [ + { + "metadata": { + "encoding": "anNvbi9wbGFpbg==" + }, + "data": "MQ==" + } + ] + }, + "scheduleToCloseTimeout": "5s", + "scheduleToStartTimeout": "5s", + "startToCloseTimeout": "5s", + "heartbeatTimeout": "5s", + "workflowTaskCompletedEventId": "4", + "retryPolicy": { + "initialInterval": "1s", + "backoffCoefficient": 2, + "maximumInterval": "100s" + }, + "useWorkflowBuildId": true + } + }, + { + "eventId": "7", + "eventTime": "2025-01-16T18:40:19.016639260Z", + "eventType": "EVENT_TYPE_TIMER_STARTED", + "taskId": "1053147", + "timerStartedEventAttributes": { + "timerId": "6edcca54-ba94-3990-8f03-d505555caa13", + "startToFireTimeout": "1s", + "workflowTaskCompletedEventId": "4" + } + }, + { + "eventId": "8", + "eventTime": "2025-01-16T18:40:19.022781468Z", + "eventType": "EVENT_TYPE_ACTIVITY_TASK_STARTED", + "taskId": "1053155", + "activityTaskStartedEventAttributes": { + "scheduledEventId": "6", + "identity": "96988@Quinn-Klassens-MacBook-Pro.local", + "requestId": "df9283ca-9d8a-4f0f-a1f8-42ca506b7615", + "attempt": 1, + "workerVersion": {} + } + }, + { + "eventId": "9", + "eventTime": "2025-01-16T18:40:19.034605677Z", + "eventType": "EVENT_TYPE_ACTIVITY_TASK_COMPLETED", + "taskId": "1053156", + "activityTaskCompletedEventAttributes": { + "result": { + "payloads": [ + { + "metadata": { + "encoding": "anNvbi9wbGFpbg==" + }, + "data": "MQ==" + } + ] + }, + "scheduledEventId": "6", + "startedEventId": "8", + "identity": "96988@Quinn-Klassens-MacBook-Pro.local" + } + }, + { + "eventId": "10", + "eventTime": "2025-01-16T18:40:19.034610718Z", + "eventType": "EVENT_TYPE_WORKFLOW_TASK_SCHEDULED", + "taskId": "1053157", + "workflowTaskScheduledEventAttributes": { + "taskQueue": { + "name": "WorkflowTest-testGetVersionMultithreadingRemoval-95ece4de-215c-4933-a089-6c06cbda4f68", + "kind": "TASK_QUEUE_KIND_NORMAL" + }, + "startToCloseTimeout": "5s", + "attempt": 1 + } + }, + { + "eventId": "11", + "eventTime": "2025-01-16T18:40:19.037768302Z", + "eventType": "EVENT_TYPE_WORKFLOW_TASK_STARTED", + "taskId": "1053160", + "workflowTaskStartedEventAttributes": { + "scheduledEventId": "10", + "identity": "96988@Quinn-Klassens-MacBook-Pro.local", + "requestId": "23e778fd-4050-4c83-8c0e-f0e85ccede7c", + "historySizeBytes": "1522" + } + }, + { + "eventId": "12", + "eventTime": "2025-01-16T18:40:19.054224677Z", + "eventType": "EVENT_TYPE_WORKFLOW_TASK_COMPLETED", + "taskId": "1053164", + "workflowTaskCompletedEventAttributes": { + "scheduledEventId": "10", + "startedEventId": "11", + "identity": "96988@Quinn-Klassens-MacBook-Pro.local", + "workerVersion": {}, + "meteringMetadata": {} + } + }, + { + "eventId": "13", + "eventTime": "2025-01-16T18:40:19.054246177Z", + "eventType": "EVENT_TYPE_WORKFLOW_EXECUTION_COMPLETED", + "taskId": "1053165", + "workflowExecutionCompletedEventAttributes": { + "result": { + "payloads": [ + { + "metadata": { + "encoding": "anNvbi9wbGFpbg==" + }, + "data": "ImFjdGl2aXR5MSI=" + } + ] + }, + "workflowTaskCompletedEventId": "12" + } + } + ] +} \ No newline at end of file diff --git a/temporal-testing/src/main/java/io/temporal/internal/sync/DummySyncWorkflowContext.java b/temporal-testing/src/main/java/io/temporal/internal/sync/DummySyncWorkflowContext.java index 653db1a15..40cec05d0 100644 --- a/temporal-testing/src/main/java/io/temporal/internal/sync/DummySyncWorkflowContext.java +++ b/temporal-testing/src/main/java/io/temporal/internal/sync/DummySyncWorkflowContext.java @@ -288,7 +288,7 @@ public boolean isReplaying() { } @Override - public boolean getVersion( + public Integer getVersion( String changeId, int minSupported, int maxSupported, From fef88d3aab48c162b212e0fc585932ed777ad45c Mon Sep 17 00:00:00 2001 From: Quinn Klassen Date: Fri, 17 Jan 2025 15:19:42 -0800 Subject: [PATCH 2/2] Add SDK flag to fix multithreaded GetVersion call --- .../io/temporal/internal/common/SdkFlags.java | 11 +++++ .../replay/ReplayWorkflowContext.java | 5 ++ .../replay/ReplayWorkflowContextImpl.java | 5 ++ .../statemachines/WorkflowStateMachines.java | 13 +++-- .../internal/sync/SyncWorkflowContext.java | 9 ++-- .../versionTests/BaseVersionTest.java | 49 +++++++++++++++++++ ...ltVersionNotSupportedDuringReplayTest.java | 2 +- .../GetVersionAddNewBeforeTest.java | 2 +- ...eCancellationInMainWorkflowMethodTest.java | 2 +- .../GetVersionAfterScopeCancellationTest.java | 2 +- .../versionTests/GetVersionAndTimerTest.java | 2 +- .../GetVersionDefaultInSignalTest.java | 2 +- .../GetVersionInSignalOnReplayTest.java | 2 +- .../versionTests/GetVersionInSignalTest.java | 2 +- .../GetVersionMultipleCallsDefaultTest.java | 2 +- .../GetVersionMultipleCallsTest.java | 2 +- .../GetVersionMultithreadingRemoveTest.java | 10 ++-- .../GetVersionMultithreadingTest.java | 2 +- .../GetVersionOutOfOrderFailTest.java | 3 ++ .../GetVersionRemovalBeforeMarkerTest.java | 2 +- .../GetVersionRemovedBeforeTest.java | 2 +- .../GetVersionRemovedInReplayTest.java | 2 +- .../GetVersionSameIdOnReplayTest.java | 2 +- .../versionTests/GetVersionSameIdTest.java | 2 +- .../workflow/versionTests/GetVersionTest.java | 2 +- .../GetVersionWithoutCommandEventTest.java | 2 +- .../GetVersionWorkflowRemoveTest.java | 2 +- ...tVersionWorkflowReplaceCompletelyTest.java | 2 +- ...ersionWorkflowReplaceGetVersionIdTest.java | 2 +- ...tedWithConflictingRangesExecutionTest.java | 2 +- .../sync/DummySyncWorkflowContext.java | 5 ++ 31 files changed, 121 insertions(+), 33 deletions(-) create mode 100644 temporal-sdk/src/test/java/io/temporal/workflow/versionTests/BaseVersionTest.java diff --git a/temporal-sdk/src/main/java/io/temporal/internal/common/SdkFlags.java b/temporal-sdk/src/main/java/io/temporal/internal/common/SdkFlags.java index c61d5a748..3cff3201e 100644 --- a/temporal-sdk/src/main/java/io/temporal/internal/common/SdkFlags.java +++ b/temporal-sdk/src/main/java/io/temporal/internal/common/SdkFlags.java @@ -68,6 +68,17 @@ public boolean tryUseSdkFlag(SdkFlag flag) { } } + /** + * @return True if this flag is set. + */ + public boolean checkSdkFlag(SdkFlag flag) { + if (!supportSdkMetadata) { + return false; + } + + return sdkFlags.contains(flag); + } + /** * @return All flags set since the last call to takeNewSdkFlags. */ diff --git a/temporal-sdk/src/main/java/io/temporal/internal/replay/ReplayWorkflowContext.java b/temporal-sdk/src/main/java/io/temporal/internal/replay/ReplayWorkflowContext.java index 8c219d42d..039755cc5 100644 --- a/temporal-sdk/src/main/java/io/temporal/internal/replay/ReplayWorkflowContext.java +++ b/temporal-sdk/src/main/java/io/temporal/internal/replay/ReplayWorkflowContext.java @@ -417,6 +417,11 @@ Integer getVersion( */ boolean tryUseSdkFlag(SdkFlag flag); + /** + * @return true if this flag is currently set. + */ + boolean checkSdkFlag(SdkFlag flag); + /** * @return The Build ID of the worker which executed the current Workflow Task. May be empty the * task was completed by a worker without a Build ID. If this worker is the one executing this diff --git a/temporal-sdk/src/main/java/io/temporal/internal/replay/ReplayWorkflowContextImpl.java b/temporal-sdk/src/main/java/io/temporal/internal/replay/ReplayWorkflowContextImpl.java index 3556d1700..dd302aa3b 100644 --- a/temporal-sdk/src/main/java/io/temporal/internal/replay/ReplayWorkflowContextImpl.java +++ b/temporal-sdk/src/main/java/io/temporal/internal/replay/ReplayWorkflowContextImpl.java @@ -260,6 +260,11 @@ public boolean tryUseSdkFlag(SdkFlag flag) { return workflowStateMachines.tryUseSdkFlag(flag); } + @Override + public boolean checkSdkFlag(SdkFlag flag) { + return workflowStateMachines.checkSdkFlag(flag); + } + @Override public Optional getCurrentBuildId() { String curTaskBID = workflowStateMachines.getCurrentTaskBuildId(); diff --git a/temporal-sdk/src/main/java/io/temporal/internal/statemachines/WorkflowStateMachines.java b/temporal-sdk/src/main/java/io/temporal/internal/statemachines/WorkflowStateMachines.java index 1be219f88..5742bfecb 100644 --- a/temporal-sdk/src/main/java/io/temporal/internal/statemachines/WorkflowStateMachines.java +++ b/temporal-sdk/src/main/java/io/temporal/internal/statemachines/WorkflowStateMachines.java @@ -58,9 +58,9 @@ enum HandleEventStatus { } /** Initial set of SDK flags that will be set on all new workflow executions. */ - private static final List initialFlags = - Collections.unmodifiableList( - Arrays.asList(SdkFlag.SKIP_YIELD_ON_DEFAULT_VERSION, SdkFlag.SKIP_YIELD_ON_VERSION)); + @VisibleForTesting + public static List initialFlags = + Collections.unmodifiableList(Arrays.asList(SdkFlag.SKIP_YIELD_ON_DEFAULT_VERSION)); /** * EventId of the WorkflowTaskStarted event of the Workflow Task that was picked up by a worker @@ -661,6 +661,13 @@ public boolean tryUseSdkFlag(SdkFlag flag) { return flags.tryUseSdkFlag(flag); } + /** + * @return True if the SDK flag is set in the workflow execution + */ + public boolean checkSdkFlag(SdkFlag flag) { + return flags.checkSdkFlag(flag); + } + /** * @return Set of all new flags set since the last call */ diff --git a/temporal-sdk/src/main/java/io/temporal/internal/sync/SyncWorkflowContext.java b/temporal-sdk/src/main/java/io/temporal/internal/sync/SyncWorkflowContext.java index 4115f1747..c15679702 100644 --- a/temporal-sdk/src/main/java/io/temporal/internal/sync/SyncWorkflowContext.java +++ b/temporal-sdk/src/main/java/io/temporal/internal/sync/SyncWorkflowContext.java @@ -1150,10 +1150,9 @@ public int getVersion(String changeId, int minSupported, int maxSupported) { * Previously the SDK would yield on the getVersion call to the scheduler. This is not ideal because it can lead to non-deterministic * scheduling if the getVersion call was removed. * */ - if (replayContext.tryUseSdkFlag(SdkFlag.SKIP_YIELD_ON_VERSION)) { + if (replayContext.checkSdkFlag(SdkFlag.SKIP_YIELD_ON_VERSION)) { // This can happen if we are replaying a workflow and encounter a getVersion call that did not - // exist on the original execution. - // and the range does not include the default version. + // exist on the original execution and the range does not include the default version. if (versionToUse == null) { versionToUse = DEFAULT_VERSION; } @@ -1166,7 +1165,9 @@ public int getVersion(String changeId, int minSupported, int maxSupported) { } return versionToUse; } - // Legacy behavior if SKIP_YIELD_ON_VERSION is not set + // Legacy behavior if SKIP_YIELD_ON_VERSION is not set. This means this thread will yield on the + // getVersion call. + // while it waits for the result. try { return result.get(); } catch (UnsupportedVersion.UnsupportedVersionException ex) { diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/BaseVersionTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/BaseVersionTest.java new file mode 100644 index 000000000..9e56f83fd --- /dev/null +++ b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/BaseVersionTest.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2022 Temporal Technologies, Inc. All Rights Reserved. + * + * Copyright (C) 2012-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Modifications copyright (C) 2017 Uber Technologies, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this material except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.temporal.workflow.versionTests; + +import io.temporal.internal.common.SdkFlag; +import io.temporal.internal.statemachines.WorkflowStateMachines; +import java.util.Arrays; +import java.util.Collections; +import org.junit.Before; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +@RunWith(Parameterized.class) +public abstract class BaseVersionTest { + + @Parameterized.Parameter public static boolean setVersioningFlag; + + @Parameterized.Parameters() + public static Object[] data() { + return new Object[][] {{true}, {false}}; + } + + @Before + public void setup() { + if (setVersioningFlag) { + WorkflowStateMachines.initialFlags = + Collections.unmodifiableList( + Arrays.asList(SdkFlag.SKIP_YIELD_ON_DEFAULT_VERSION, SdkFlag.SKIP_YIELD_ON_VERSION)); + } + } +} diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/DefaultVersionNotSupportedDuringReplayTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/DefaultVersionNotSupportedDuringReplayTest.java index e0fe26d71..c631fdae1 100644 --- a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/DefaultVersionNotSupportedDuringReplayTest.java +++ b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/DefaultVersionNotSupportedDuringReplayTest.java @@ -37,7 +37,7 @@ * replayed on a code version that doesn't support the {@link * io.temporal.workflow.Workflow#DEFAULT_VERSION} anymore */ -public class DefaultVersionNotSupportedDuringReplayTest { +public class DefaultVersionNotSupportedDuringReplayTest extends BaseVersionTest { private static final Signal unsupportedVersionExceptionThrown = new Signal(); diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionAddNewBeforeTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionAddNewBeforeTest.java index c4a726012..9fc08ee2f 100644 --- a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionAddNewBeforeTest.java +++ b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionAddNewBeforeTest.java @@ -34,7 +34,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class GetVersionAddNewBeforeTest { +public class GetVersionAddNewBeforeTest extends BaseVersionTest { private static final Logger log = LoggerFactory.getLogger(GetVersionAddNewBeforeTest.class); private static int versionFoo; diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionAfterScopeCancellationInMainWorkflowMethodTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionAfterScopeCancellationInMainWorkflowMethodTest.java index 0f616271a..727fcda3d 100644 --- a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionAfterScopeCancellationInMainWorkflowMethodTest.java +++ b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionAfterScopeCancellationInMainWorkflowMethodTest.java @@ -35,7 +35,7 @@ /** This test reproduces a clash in cancellation scopes with getVersion described here: */ @Issue("https://github.com/temporalio/sdk-java/issues/648") -public class GetVersionAfterScopeCancellationInMainWorkflowMethodTest { +public class GetVersionAfterScopeCancellationInMainWorkflowMethodTest extends BaseVersionTest { @Rule public SDKTestWorkflowRule testWorkflowRule = diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionAfterScopeCancellationTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionAfterScopeCancellationTest.java index 0c78b66a2..86bc46d12 100644 --- a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionAfterScopeCancellationTest.java +++ b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionAfterScopeCancellationTest.java @@ -42,7 +42,7 @@ * io.temporal.internal.statemachines.VersionStateMachineTest#testRecordAfterCommandCancellation} */ @Issue("https://github.com/temporalio/sdk-java/issues/615") -public class GetVersionAfterScopeCancellationTest { +public class GetVersionAfterScopeCancellationTest extends BaseVersionTest { @Rule public SDKTestWorkflowRule testWorkflowRule = diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionAndTimerTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionAndTimerTest.java index 23f5155ce..82bbffd88 100644 --- a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionAndTimerTest.java +++ b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionAndTimerTest.java @@ -33,7 +33,7 @@ import org.junit.Rule; import org.junit.Test; -public class GetVersionAndTimerTest { +public class GetVersionAndTimerTest extends BaseVersionTest { @Rule public SDKTestWorkflowRule testWorkflowRuleWithoutVersion = diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionDefaultInSignalTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionDefaultInSignalTest.java index 0cfecde86..de1e5b425 100644 --- a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionDefaultInSignalTest.java +++ b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionDefaultInSignalTest.java @@ -35,7 +35,7 @@ import org.junit.Rule; import org.junit.Test; -public class GetVersionDefaultInSignalTest { +public class GetVersionDefaultInSignalTest extends BaseVersionTest { @Rule public SDKTestWorkflowRule testWorkflowRule = diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionInSignalOnReplayTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionInSignalOnReplayTest.java index 7bba4825f..cabb00fe5 100644 --- a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionInSignalOnReplayTest.java +++ b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionInSignalOnReplayTest.java @@ -38,7 +38,7 @@ import org.junit.Rule; import org.junit.Test; -public class GetVersionInSignalOnReplayTest { +public class GetVersionInSignalOnReplayTest extends BaseVersionTest { public static boolean hasReplayedSignal; @Rule diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionInSignalTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionInSignalTest.java index 3812d7490..e23fb5754 100644 --- a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionInSignalTest.java +++ b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionInSignalTest.java @@ -32,7 +32,7 @@ import org.junit.Rule; import org.junit.Test; -public class GetVersionInSignalTest { +public class GetVersionInSignalTest extends BaseVersionTest { @Rule public SDKTestWorkflowRule testWorkflowRule = diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionMultipleCallsDefaultTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionMultipleCallsDefaultTest.java index fd8d36c71..82a7eed88 100644 --- a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionMultipleCallsDefaultTest.java +++ b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionMultipleCallsDefaultTest.java @@ -35,7 +35,7 @@ import org.junit.Rule; import org.junit.Test; -public class GetVersionMultipleCallsDefaultTest { +public class GetVersionMultipleCallsDefaultTest extends BaseVersionTest { @Rule public SDKTestWorkflowRule testWorkflowRule = SDKTestWorkflowRule.newBuilder() diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionMultipleCallsTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionMultipleCallsTest.java index a999d644a..5ae6b0842 100644 --- a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionMultipleCallsTest.java +++ b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionMultipleCallsTest.java @@ -34,7 +34,7 @@ import org.junit.Rule; import org.junit.Test; -public class GetVersionMultipleCallsTest { +public class GetVersionMultipleCallsTest extends BaseVersionTest { @Rule public SDKTestWorkflowRule testWorkflowRule = SDKTestWorkflowRule.newBuilder() diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionMultithreadingRemoveTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionMultithreadingRemoveTest.java index 79c26ff66..18e3dedc1 100644 --- a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionMultithreadingRemoveTest.java +++ b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionMultithreadingRemoveTest.java @@ -20,9 +20,10 @@ package io.temporal.workflow.versionTests; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; +import static org.junit.Assume.assumeTrue; +import io.temporal.internal.Issue; import io.temporal.testing.WorkflowReplayer; import io.temporal.testing.internal.SDKTestOptions; import io.temporal.testing.internal.SDKTestWorkflowRule; @@ -36,7 +37,8 @@ import org.junit.Rule; import org.junit.Test; -public class GetVersionMultithreadingRemoveTest { +@Issue("https://github.com/temporalio/sdk-java/issues/2307") +public class GetVersionMultithreadingRemoveTest extends BaseVersionTest { private static boolean hasReplayed; @@ -45,7 +47,6 @@ public class GetVersionMultithreadingRemoveTest { SDKTestWorkflowRule.newBuilder() .setWorkflowTypes(TestGetVersionWorkflowImpl.class) .setActivityImplementations(new TestActivities.TestActivitiesImpl()) - .setUseExternalService(true) // Forcing a replay. Full history arrived from a normal queue causing a replay. .setWorkerOptions( WorkerOptions.newBuilder() @@ -55,6 +56,7 @@ public class GetVersionMultithreadingRemoveTest { @Test public void testGetVersionMultithreadingRemoval() { + assumeTrue("This test only passes if SKIP_YIELD_ON_VERSION is enabled", setVersioningFlag); TestWorkflows.TestWorkflow1 workflowStub = testWorkflowRule.newWorkflowStubTimeoutOptions(TestWorkflows.TestWorkflow1.class); String result = workflowStub.execute(testWorkflowRule.getTaskQueue()); diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionMultithreadingTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionMultithreadingTest.java index fe487fda2..7afc852e6 100644 --- a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionMultithreadingTest.java +++ b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionMultithreadingTest.java @@ -37,7 +37,7 @@ import org.junit.Rule; import org.junit.Test; -public class GetVersionMultithreadingTest { +public class GetVersionMultithreadingTest extends BaseVersionTest { private static boolean hasReplayed; diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionOutOfOrderFailTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionOutOfOrderFailTest.java index 0243a6eb2..4add95f51 100644 --- a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionOutOfOrderFailTest.java +++ b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionOutOfOrderFailTest.java @@ -75,6 +75,9 @@ public void testGetVersionOutOfOrderFail() { assertEquals( NonDeterministicException.class.getName(), ((ApplicationFailure) e.getCause().getCause().getCause()).getType()); + assertEquals( + "[TMPRL1100] getVersion call before the existing version marker event. The most probable cause is retroactive addition of a getVersion call with an existing 'changeId'", + ((ApplicationFailure) e.getCause().getCause().getCause()).getOriginalMessage()); } @Test diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionRemovalBeforeMarkerTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionRemovalBeforeMarkerTest.java index 943698561..bbc866bf6 100644 --- a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionRemovalBeforeMarkerTest.java +++ b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionRemovalBeforeMarkerTest.java @@ -34,7 +34,7 @@ import org.junit.Rule; import org.junit.Test; -public class GetVersionRemovalBeforeMarkerTest { +public class GetVersionRemovalBeforeMarkerTest extends BaseVersionTest { private static boolean hasReplayed; @Rule diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionRemovedBeforeTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionRemovedBeforeTest.java index 5681bde46..79476d81c 100644 --- a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionRemovedBeforeTest.java +++ b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionRemovedBeforeTest.java @@ -36,7 +36,7 @@ import org.junit.Rule; import org.junit.Test; -public class GetVersionRemovedBeforeTest { +public class GetVersionRemovedBeforeTest extends BaseVersionTest { private static boolean hasReplayed; diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionRemovedInReplayTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionRemovedInReplayTest.java index e84d8e299..090a96c04 100644 --- a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionRemovedInReplayTest.java +++ b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionRemovedInReplayTest.java @@ -37,7 +37,7 @@ import org.junit.Rule; import org.junit.Test; -public class GetVersionRemovedInReplayTest { +public class GetVersionRemovedInReplayTest extends BaseVersionTest { public static boolean hasReplayed; diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionSameIdOnReplayTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionSameIdOnReplayTest.java index a4a115e1b..ed19cba2b 100644 --- a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionSameIdOnReplayTest.java +++ b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionSameIdOnReplayTest.java @@ -36,7 +36,7 @@ import org.junit.Rule; import org.junit.Test; -public class GetVersionSameIdOnReplayTest { +public class GetVersionSameIdOnReplayTest extends BaseVersionTest { private static boolean hasReplayed; diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionSameIdTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionSameIdTest.java index 378d47fde..5e7471d75 100644 --- a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionSameIdTest.java +++ b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionSameIdTest.java @@ -33,7 +33,7 @@ import org.junit.Rule; import org.junit.Test; -public class GetVersionSameIdTest { +public class GetVersionSameIdTest extends BaseVersionTest { private static boolean hasReplayed; diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionTest.java index e59464faa..addf65365 100644 --- a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionTest.java +++ b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionTest.java @@ -37,7 +37,7 @@ import org.junit.Rule; import org.junit.Test; -public class GetVersionTest { +public class GetVersionTest extends BaseVersionTest { private static boolean hasReplayed; diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionWithoutCommandEventTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionWithoutCommandEventTest.java index 06113d619..1699029c1 100644 --- a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionWithoutCommandEventTest.java +++ b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionWithoutCommandEventTest.java @@ -34,7 +34,7 @@ import org.junit.Rule; import org.junit.Test; -public class GetVersionWithoutCommandEventTest { +public class GetVersionWithoutCommandEventTest extends BaseVersionTest { private static CompletableFuture executionStarted = new CompletableFuture<>(); diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionWorkflowRemoveTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionWorkflowRemoveTest.java index ee2760b70..c681b305d 100644 --- a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionWorkflowRemoveTest.java +++ b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionWorkflowRemoveTest.java @@ -36,7 +36,7 @@ import org.junit.Rule; import org.junit.Test; -public class GetVersionWorkflowRemoveTest { +public class GetVersionWorkflowRemoveTest extends BaseVersionTest { private static boolean hasReplayed; diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionWorkflowReplaceCompletelyTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionWorkflowReplaceCompletelyTest.java index ac2e64a6f..df92d6ba2 100644 --- a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionWorkflowReplaceCompletelyTest.java +++ b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionWorkflowReplaceCompletelyTest.java @@ -34,7 +34,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class GetVersionWorkflowReplaceCompletelyTest { +public class GetVersionWorkflowReplaceCompletelyTest extends BaseVersionTest { private static final Logger log = LoggerFactory.getLogger(GetVersionWorkflowReplaceCompletelyTest.class); diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionWorkflowReplaceGetVersionIdTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionWorkflowReplaceGetVersionIdTest.java index 9c21233b1..2234b3a73 100644 --- a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionWorkflowReplaceGetVersionIdTest.java +++ b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/GetVersionWorkflowReplaceGetVersionIdTest.java @@ -34,7 +34,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class GetVersionWorkflowReplaceGetVersionIdTest { +public class GetVersionWorkflowReplaceGetVersionIdTest extends BaseVersionTest { private static final Logger log = LoggerFactory.getLogger(GetVersionWorkflowReplaceGetVersionIdTest.class); diff --git a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/VersionNotSupportedWithConflictingRangesExecutionTest.java b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/VersionNotSupportedWithConflictingRangesExecutionTest.java index 896019aeb..cd7eecf2b 100644 --- a/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/VersionNotSupportedWithConflictingRangesExecutionTest.java +++ b/temporal-sdk/src/test/java/io/temporal/workflow/versionTests/VersionNotSupportedWithConflictingRangesExecutionTest.java @@ -42,7 +42,7 @@ * Verifies a situation with a workflow having two getVersion calls.These calls have version ranges * that are incompatible with each other. */ -public class VersionNotSupportedWithConflictingRangesExecutionTest { +public class VersionNotSupportedWithConflictingRangesExecutionTest extends BaseVersionTest { private static boolean hasReplayed; diff --git a/temporal-testing/src/main/java/io/temporal/internal/sync/DummySyncWorkflowContext.java b/temporal-testing/src/main/java/io/temporal/internal/sync/DummySyncWorkflowContext.java index 40cec05d0..6baca1c77 100644 --- a/temporal-testing/src/main/java/io/temporal/internal/sync/DummySyncWorkflowContext.java +++ b/temporal-testing/src/main/java/io/temporal/internal/sync/DummySyncWorkflowContext.java @@ -331,6 +331,11 @@ public boolean tryUseSdkFlag(SdkFlag flag) { return false; } + @Override + public boolean checkSdkFlag(SdkFlag flag) { + return false; + } + @Override public Optional getCurrentBuildId() { return Optional.empty();