Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/cloudflare/internal/test/workflows/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,5 @@ load("//:build/wd_test.bzl", "wd_test")

wd_test(
src = "workflows-api-test.wd-test",
args = ["--experimental"],
data = glob(["*.js"]),
)
138 changes: 0 additions & 138 deletions src/cloudflare/internal/test/workflows/workflows-api-rpc-test.js

This file was deleted.

70 changes: 50 additions & 20 deletions src/cloudflare/internal/test/workflows/workflows-api-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@

import * as assert from 'node:assert';

// Every test is its own export: `workerd test` runs the `test()` handler of each entrypoint, so
// extra methods hung off a single exported object would silently never run.

// Introspection goes over `env.mock.fetch()` rather than JSRPC on purpose: `env.mock` is an
// ordinary service binding, so its RPC wildcard stays gated at this worker's compatibility date.
async function getLastRestartBody(env, id) {
const res = await env.mock.fetch('http://placeholder/last-restart', {
method: 'POST',
Expand All @@ -12,7 +17,7 @@ async function getLastRestartBody(env, id) {
return (await res.json()).result;
}

export const tests = {
export const workflowsApi = {
async test(_, env) {
{
// Test create instance
Expand Down Expand Up @@ -45,27 +50,14 @@ export const tests = {
assert.deepStrictEqual(instances[1].id, 'bar');
}

{
const instance = await env.workflow.get('status-http');
const status = await instance.status();
assert.deepStrictEqual(status.status, 'running');
assert.strictEqual(status.transport, 'http');
}

{
// Test delete hits the /delete endpoint without throwing.
const instance = await env.workflow.get('delete-http');
await instance.delete();
}

{
const result = await env.workflow.deleteBatch([
'delete-http-1',
'delete-1',
'missing-delete',
'delete-http-1',
'delete-1',
]);
assert.deepStrictEqual(result, {
deleted: [{ id: 'delete-http-1' }, { id: 'delete-http-1' }],
deleted: [{ id: 'delete-1' }, { id: 'delete-1' }],
errors: [
{
id: 'missing-delete',
Expand All @@ -76,6 +68,25 @@ export const tests = {
});
}

{
const instance = await env.workflow.get('inst');
await instance.pause();
await instance.resume();
await instance.terminate();
await instance.delete();
await instance.sendEvent({
type: 'my-event',
payload: { hello: 'world' },
});
}

{
const instance = await env.workflow.get('status-1');
const status = await instance.status();
assert.deepStrictEqual(status.status, 'running');
assert.strictEqual(status.output, 'status-1');
}

{
for (const method of ['get', 'create', 'createBatch', 'deleteBatch']) {
assert.strictEqual(typeof env.workflow[method], 'function');
Expand All @@ -101,27 +112,46 @@ export const tests = {
assert.strictEqual(typeof fromGet[method], 'function');
}
}

{
// The binding keeps its ungated inner fetcher inaccessible to user code.
// Instances returned by the binding omit the fetcher too.
assert.strictEqual(env.workflow.fetcher, undefined);
assert.strictEqual((await env.workflow.get('d')).fetcher, undefined);
}

{
await assert.rejects(env.workflow.get('throw'), {
message: 'workflow instance not found',
});
}
},
};

async testRestartNoOptions(_, env) {
export const restartNoOptions = {
async test(_, env) {
const instance = await env.workflow.get('restart-basic');
await instance.restart();

const body = await getLastRestartBody(env, 'restart-basic');
assert.deepStrictEqual(body.id, 'restart-basic');
assert.strictEqual(body.from, undefined);
},
};

async testRestartFromStepNameOnly(_, env) {
export const restartFromStepNameOnly = {
async test(_, env) {
const instance = await env.workflow.get('restart-step');
await instance.restart({ from: { name: 'fetch data' } });

const body = await getLastRestartBody(env, 'restart-step');
assert.deepStrictEqual(body.id, 'restart-step');
assert.deepStrictEqual(body.from, { name: 'fetch data' });
},
};

async testRestartFromStepAllOptions(_, env) {
export const restartFromStepAllOptions = {
async test(_, env) {
const instance = await env.workflow.get('restart-full');
await instance.restart({
from: { name: 'process item', count: 3, type: 'do' },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using Workerd = import "/workerd/workerd.capnp";

# No `rpc` or `experimental` flag here on purpose. wd_test runs the default variant at compatibility
# date 2000-01-01, so this covers the binding working while `fetcher_rpc` is off.

const unitTests :Workerd.Config = (
services = [
( name = "workflows-api-test",
Expand All @@ -26,35 +29,9 @@ const unitTests :Workerd.Config = (
],
)
),
( name = "workflows-api-rpc-test",
worker = (
modules = [
(name = "worker", esModule = embed "workflows-api-rpc-test.js")
],
compatibilityFlags = ["nodejs_compat", "workflows_bindings_rpc",
"experimental", "service_binding_extra_handlers",
"rpc"],
bindings = [
(
name = "workflow",
wrapped = (
moduleName = "cloudflare-internal:workflows-api",
innerBindings = [(
name = "fetcher",
service = "workflows-mock"
)],
)
),
(
name = "mock",
service = "workflows-mock"
)
],
)
),
( name = "workflows-mock",
worker = (
compatibilityFlags = ["experimental", "nodejs_compat"],
compatibilityFlags = ["nodejs_compat"],
modules = [
(name = "worker", esModule = embed "workflows-mock.js")
],
Expand Down
Loading
Loading