CCOR-13193 - run integration(e2e) tests against latest oss conductor + v4 server#151
CCOR-13193 - run integration(e2e) tests against latest oss conductor + v4 server#151chrishagglund-ship-it wants to merge 11 commits into
Conversation
Codecov Report❌ Patch coverage is
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 1 file with indirect coverage changes 🚀 New features to boost your workflow:
|
cb0af8b to
6ec17eb
Compare
4b03a0e to
b88392d
Compare
223cba3 to
268df8e
Compare
nthmost-orkes
left a comment
There was a problem hiding this comment.
Good PR overall. Verified against server source and our capabilities catalog — the onStateChange fix and the OSS CI job are both the right moves. A few things worth discussing:
onStateChange type fix — verified correct, ship as bugfix
Confirmed against WorkflowTask.java:158 in conductor-oss/conductor:
private @Valid Map<String, List<StateChangeEvent>> onStateChange = new HashMap<>();And StateChangeEvent.java has exactly { String type, Map<String, Object> payload } — no StateChangeConfig anywhere on the server side. The old C# type was never correct; no valid server response could have round-tripped through it. +1 for minor/patch bugfix versioning.
OSS CI job
The new integration_tests_oss job is the right approach. One thing: conductoross/conductor:latest will silently break if the server ships something the SDK doesn't handle yet. Consider pinning to a specific version (e.g. conductoross/conductor:3.32.0-rc.9 or the latest stable) so CI failures are deliberate rather than surprise. Even a comment above the image line noting the intended version would help.
Scheduler exclusion — possibly too conservative
Feature!=OSSSchedulerWIP excludes SchedulerTests from the OSS run. We've been building a capabilities catalog for the OSS server, and the scheduler is fully implemented in OSS 3.32.0-rc.9 with complete Flyway migrations for SQLite, MySQL, and PostgreSQL backends. The exclusion may be warranted if the tests use Orkes-specific API paths or auth-gated endpoints, but it's worth a quick check — the OSS scheduler surface should cover the basics that the integration tests exercise.
If the tests fail against OSS because of missing endpoints (e.g. a scheduler search API that only exists in Orkes Enterprise), documenting that in the OSSSchedulerWIP annotation or a comment in the test class would help the next person know why it's excluded.
Missed opportunity while touching WorkflowTask
Since this PR changes WorkflowTask.OnStateChange, it's a natural place to address WorkflowTaskTypeEnum gaps we found in our SDK audit (#161). The enum currently ends at WAITFORWEBHOOK = 30 and is missing NOOP, AGENT, GET_AGENT_CARD, and CANCEL_AGENT. Not a blocker for this PR, but worth a follow-up issue if there isn't one already.
The rest of the changes (EnvironmentVariable model, EnvironmentResourceApi deserialization fix, v4 matrix) look correct. The new tests in EnvironmentAndStateChangeModelTests cover the new type shapes cleanly.
| cat <<'EOF' > docker-compose-oss.yaml | ||
| services: | ||
| conductor-server: | ||
| image: conductoross/conductor:latest |
There was a problem hiding this comment.
Did you mean to use latest here? If a new OSS release drops mid-PR this could break the job for reasons unrelated to the SDK change. Should we pin to a specific version tag (e.g. conductoross/conductor:3.22.0)?
There was a problem hiding this comment.
let's use a org-wide env var to set which version to use, for now i have set that up as latest . I've also added workflow_dispatch option to the action so that a custom oss version could be tested against without changing the org-wide env var value.
| /// Projects a list of environment variables into a name/value dictionary, | ||
| /// skipping any entries that are missing a name or value. | ||
| /// </summary> | ||
| internal static Dictionary<string, string> ToEnvironmentDictionary(List<EnvironmentVariable> variables) |
There was a problem hiding this comment.
ToEnvironmentDictionary is marked internal, but EnvironmentResourceApiUnitTests.cs calls it directly from the test assembly. Without [assembly: InternalsVisibleTo("Tests")] on the main project this will be a compile error. Either add InternalsVisibleTo or make it public static.
There was a problem hiding this comment.
Thanks for flagging this — I looked into it, and I think this one is a false alarm.
The key detail is that InternalsVisibleTo keys off the assembly name, not the namespace. The test's namespace is Tests.Api, but the test assembly is conductor-csharp.test (from Tests/conductor-csharp.test.csproj, which doesn't override <AssemblyName>).
The main project already grants access to exactly that assembly:
<!-- Conductor/conductor-csharp.csproj -->
<ItemGroup>
<InternalsVisibleTo Include="conductor-csharp.test" />
</ItemGroup>Indeed, without this xml InternalsVisibleTo there would be a compile error
| $"Workflow status is {workflow.Status} and status of last task {lastTask.ReferenceTaskName} is {lastTask.Status}"); | ||
|
|
||
| // Mark the WAIT task as completed by calling Task completion API | ||
| var taskResult = new TaskResult |
There was a problem hiding this comment.
taskResult is declared but never passed to anything — UpdateTaskSync is called with individual arguments on the next line. Dead variable; either wire it up or remove it.
| System.Threading.Thread.Sleep(500); | ||
| } | ||
|
|
||
| var final_ = _taskClient.GetTask(taskId); |
There was a problem hiding this comment.
final is not a reserved keyword in C#, so the trailing underscore is unnecessary. Just var final.
| "schemaVersion": 2, | ||
| "restartable": true, | ||
| "workflowStatusListenerEnabled": false, | ||
| "ownerEmail": "viren@orkes.io", |
There was a problem hiding this comment.
Viren has been immortalized in the test fixture. Flattering, but maybe use something like "test@conductoross.io" so future readers don't wonder if he's personally on-call for the C# SDK test suite.
…inst conductor oss
…st that needs it. setup to test against v4 and v5 in gh action
…ng comparison in favor of initial enum string parse and then compare to enum value
8162bf8 to
2303ec0
Compare
In this PR:
regarding the correction of misshapen data structures, it is technically a breaking change, and there is a question then of if this should be bugfix (eg 1.2.1) or major version (2.0.0). I lean towards the "type was impossible/useless" bugfix camp.
Breaking change:
WorkflowTask.OnStateChangemodel corrected to match server contractWhat breaks
Conductor.Client.Models.WorkflowTask.OnStateChangechanges type:Dictionary<string, StateChangeConfig>Dictionary<string, List<StateChangeEvent>>Consequences for callers:
OnStateChangeproperty and theWorkflowTask(...)constructor'sonStateChangeparameter change type (source-breaking at compile time).
StateChangeConfigand theStateChangeEventTypeenum are removed.StateChangeEventmoves from the global namespace intoConductor.Client.Models(callers now need
using Conductor.Client.Models;).This surfaces on any call that sends or receives a
WorkflowDefcontaining tasks withonStateChange, e.g.MetadataResourceApi.UpdateWorkflowDefinitions(...)(
PUT /metadata/workflow) andMetadataResourceApi.Get(...)(GET /metadata/workflow/{name}).Why the old type was wrong
onStateChangeis serialized as part ofWorkflowDefover the metadata REST API. Theauthoritative server model is
Map<String, List<StateChangeEvent>>, where the map key isthe event name (
onStart,onSuccess, …) and eachStateChangeEventis{ type, payload }:conductor/.../common/metadata/workflow/WorkflowTask.java:158(field),StateChangeEvent.java:25-32orkes-conductor/failover/conductor/.../common/metadata/workflow/WorkflowTask.java:158,StateChangeEvent.java:25-32(identical; Orkes reuses the OSS common model)There is no
StateChangeConfigtype anywhere on the server side.So the server wants:
The old C#
StateChangeConfigproduced:That's wrong on both read and write — wrong key (empty string instead of the event name)
and wrong value shape (a wrapper object with
type/eventsinstead of a bare list ofevents). It only ever "worked" because nothing round-tripped it against a server that
enforced the shape. The new
Dictionary<string, List<StateChangeEvent>>is an exact matchto the server model.
So: bug fix, or breaking change?
Both. The type was never correct, so this is fundamentally a bug fix — but because it
changes a public type, it's source-breaking. Flagging for the team to decide how to ship:
correct code could have depended on it), or
The PR author favors minor/patch bugfix 🙂