Skip to content

test: add Kotlin verification smoke test#3513

Open
hej090224 wants to merge 1 commit into
operator-framework:mainfrom
hej090224:feature/2967-kotlin-verification
Open

test: add Kotlin verification smoke test#3513
hej090224 wants to merge 1 commit into
operator-framework:mainfrom
hej090224:feature/2967-kotlin-verification

Conversation

@hej090224

Copy link
Copy Markdown

Closes #2967

What this does

Adds a Kotlin-based smoke test to operator-framework-core verifying that JOSDK behaves correctly when a DependentResource is implemented in Kotlin.

Kotlin has no concept of checked vs. unchecked exceptions, so Kotlin code can throw a plain Exception from an overridden method (e.g. DependentResource#reconcile) without declaring it — even though the Java-declared method signature doesn't include throws Exception. Before #2965, NodeExecutor only caught RuntimeException, so such an exception thrown from Kotlin would silently bypass the workflow's error handling and not trigger a retry.

The new test (KotlinCheckedExceptionDependentResourceTest.kt):

  • Defines a Kotlin DependentResource whose reconcile throws a custom checked Exception.
  • Runs it through the real Workflow/WorkflowReconcileExecutor/NodeExecutor (no mocked cluster needed).
  • Asserts the exception is captured in WorkflowReconcileResult#getErroredDependents() and that throwAggregateExceptionIfErrorsPresent() throws AggregatedOperatorException, confirming a retry would be triggered.

I verified this test actually exercises the fix: temporarily reverting NodeExecutor's catch (Exception e) back to catch (RuntimeException e) (the pre-#2965 behavior) makes the test fail, since the checked exception is then silently swallowed and getErroredDependents() stays empty.

Build changes

  • Adds kotlin-maven-plugin (test scope only, 2.4.10) to operator-framework-core/pom.xml, compiling sources under src/test/kotlin. No other module is affected, and no Kotlin dependency is added to the main/runtime classpath.

Relation to #2965

#2965 fixed NodeExecutor, AbstractWorkflowExecutor, and PollingEventSource to catch Exception instead of RuntimeException (with // Exception is required because of Kotlin comments already in place), and opened #2967 as a follow-up to add tests validating this behavior with actual Kotlin code. I also grepped the codebase for any remaining catch (RuntimeException in main sources and found none left to fix.

I scoped this PR to a unit-test-level smoke test (no real Kubernetes cluster required) so it's fast and fully verifiable in CI; a full Kotlin-based *IT.java-style integration test against LocallyRunOperatorExtension could be a good follow-up if maintainers want broader coverage.

Test plan

Adds a Maven-compiled Kotlin test source set to operator-framework-core
and a smoke test verifying that a checked (non-RuntimeException) Exception
thrown from a Kotlin DependentResource is properly caught and reported by
the workflow executor, so that retries are triggered as expected.

Kotlin does not have checked exceptions, so Kotlin code can throw a
checked Exception from an overridden method without declaring it, even
though the Java DependentResource#reconcile signature does not declare
`throws Exception`. Before operator-framework#2965 this exception would not have been
caught by NodeExecutor, since it only handled RuntimeException, silently
swallowing the error and preventing retries.

Closes operator-framework#2967
Copilot AI review requested due to automatic review settings July 25, 2026 16:58
@openshift-ci
openshift-ci Bot requested review from csviri and metacosm July 25, 2026 16:58

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Kotlin-based test coverage to ensure the workflow executor correctly captures non-RuntimeException failures thrown from Kotlin-implemented DependentResources, preventing silent bypass of retry/error aggregation logic.

Changes:

  • Introduces a Kotlin smoke test that throws a checked Exception from DependentResource.reconcile and asserts it is surfaced via erroredDependents and aggregated exceptions.
  • Updates operator-framework-core build to compile src/test/kotlin via kotlin-maven-plugin and adds Kotlin stdlib as a test-scoped dependency.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
operator-framework-core/src/test/kotlin/io/javaoperatorsdk/operator/processing/dependent/workflow/KotlinCheckedExceptionDependentResourceTest.kt Adds Kotlin smoke test validating workflow error capture/aggregation for checked exceptions thrown from Kotlin dependents
operator-framework-core/pom.xml Adds Kotlin test compilation support and Kotlin stdlib dependency (test scope) to enable the new Kotlin test

Comment on lines +72 to +87
`when`(context.managedWorkflowAndDependentResourceContext())
.thenReturn(mock(ManagedWorkflowAndDependentResourceContext::class.java))
`when`(context.workflowExecutorService).thenReturn(Executors.newCachedThreadPool())
@Suppress("UNCHECKED_CAST")
`when`(context.eventSourceRetriever())
.thenReturn(mock(EventSourceRetriever::class.java) as EventSourceRetriever<TestCustomResource>)

val result = workflow.reconcile(TestCustomResource(), context)

// the checked exception was caught by the workflow executor, not left uncaught, so it is
// reported as an error for the dependent resource, which is what allows JOSDK to retry the
// reconciliation.
assertThat(result.erroredDependents).containsOnlyKeys(dependentResource)
assertThat(result.erroredDependents[dependentResource]).isInstanceOf(CheckedException::class.java)
assertThrows<AggregatedOperatorException> { result.throwAggregateExceptionIfErrorsPresent() }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Verifying JOSDK with Kotlin

2 participants