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
35 changes: 35 additions & 0 deletions tests/workflow-tengo/src/exec/large-workdir.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Pl } from "@milaboratories/pl-middle-layer";
import { tplTest } from "@platforma-sdk/test";

/*
* End-to-end check for the E2BIG failure on large working directories
* (fixed in Platforma 4.3.2): a command must start and complete when its
* working directory holds more files than the old inline expected-items list
* could carry (~7300 entries).
*
* `exec.run.large_workdir` fills the working directory with 10000 files and
* runs `hello-world` in it. The software has both a binary and a docker
* distribution, so the same test covers the local exec runner and the k8s
* runner.
*
* The message carries a random suffix on purpose: an exec step with a stable
* CID is deduplicated by the backend, and a cached result would never start a
* job at all.
*/
tplTest.concurrent(
"run-in-workdir-with-10k-files",
async ({ helper, expect }) => {
const helloText = `Hello from a workdir with 10000 files (${Math.random()})`;

const result = await helper.renderTemplate(false, "exec.run.large_workdir", ["main"], (tx) => ({
text: tx.createValue(Pl.JsonObject, JSON.stringify(helloText)),
}));
const mainResult = result.computeOutput("main", (a) => a?.getDataAsString());

expect(await mainResult.awaitStableValue()).eq(helloText + "\n");
},
// Building 10000 workdir entries means 10000 value resources plus the map
// that holds them, all in one transaction. That is slow on the backend, so
// the default 15s test timeout is not enough.
300_000,
);
49 changes: 49 additions & 0 deletions tests/workflow-tengo/src/exec/run/large_workdir.tpl.tengo
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* Regression test for the E2BIG failure on large working directories
* (fixed in Platforma 4.3.2).
*
* The k8s runner used to pass the expected-workdir-item list to the job
* inline. Above roughly 7300 entries the argument list got larger than the
* kernel limit, `execve` returned E2BIG and the job failed before the
* container started. The list now goes to the job by path
* (`.pl/expected_items` inside the workdir, see
* `util/k8s/job_params.go: DefaultExpectedItemsFileName` in the backend).
*
* The template fills the working directory with 10000 files, which is
* comfortably above the ~7300 threshold, then runs a command in it. Do not
* lower the count below ~7300: under that number the test passes on the
* buggy runner too and gives no coverage. Every file holds one byte, because
* the item *count* is what matters here, not the payload size.
*/

self := import("@platforma-sdk/workflow-tengo:tpl")
assets := import("@platforma-sdk/workflow-tengo:assets")
exec := import("@platforma-sdk/workflow-tengo:exec")

self.defineOutputs(["main"])

sw := assets.importSoftware("@platforma-open/milaboratories.software-test-utils:hello-world")

// Number of files to put into the working directory.
// Keep it above the ~7300 entries that used to break `execve`.
workdirFileCount := 10000

self.body(func(inputs) {
builder := exec.builder().
cpu(1).ram("50Mi").
software(sw).
arg(inputs.text).
saveStdoutContent()

// `writeFile` is the cheapest way to reach the file count: it needs no
// blob, no upload and no signature, only a small value resource.
for i := 0; i < workdirFileCount; i++ {
builder.writeFile("filler/" + string(i) + ".txt", "x")
}

run := builder.run()

return {
main: run.getStdoutContent()
}
})
Loading