Skip to content
Merged
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
69 changes: 69 additions & 0 deletions tests/integration/features/build/resources-parallel.docker.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/**
* Integration tests for PARALLEL resource building with real Docker.
*
* Uses the microservices example (base component + api/worker/gateway that
* depend on base:image) to prove the scheduler's dependency barrier holds
* against concurrent `docker build`s.
*/
import { runCommand } from '@oclif/test';
import { execa } from 'execa';
import { describe, expect, test } from 'vitest';

import { useExampleWithDocker } from '../../helpers.js';

async function imageExists(
projectName: string,
componentName: string,
): Promise<boolean> {
const { stdout } = await execa('docker', [
'images',
'--filter',
`label=emb/project=${projectName}`,
'--format',
'{{.Repository}}:{{.Tag}}',
]);
return stdout.includes(`${projectName}/${componentName}`);
}

describe('Build - resources (parallel)', () => {
useExampleWithDocker('microservices');

test('honours the dependency barrier under -j (base built before its dependents)', async () => {
// Clean daemon (beforeAll ran `clean --force`): base:image does not exist
// yet, so api/worker's real `FROM microservices/base` would fail if the
// scheduler let them start before base finished. Both depend on base — a
// green build proves base was built first, then both ran concurrently.
const { error } = await runCommand(
'resources build api:image worker:image -j 4',
);

expect(error).toBeUndefined();
expect(await imageExists('microservices', 'base')).toBe(true);
expect(await imageExists('microservices', 'api')).toBe(true);
expect(await imageExists('microservices', 'worker')).toBe(true);
});

test('accepts -j auto', async () => {
const { error } = await runCommand('resources build api:image -j auto');

expect(error).toBeUndefined();
expect(await imageExists('microservices', 'api')).toBe(true);
});

test('-j 1 builds a dependent chain serially', async () => {
const { error } = await runCommand('resources build gateway:image -j 1');

expect(error).toBeUndefined();
expect(await imageExists('microservices', 'gateway')).toBe(true);
});

test('--force rebuilds under -j', async () => {
await runCommand('resources build gateway:image -j 4');
const { error } = await runCommand(
'resources build gateway:image -j 4 --force',
);

expect(error).toBeUndefined();
expect(await imageExists('microservices', 'gateway')).toBe(true);
});
});
3 changes: 3 additions & 0 deletions vitest.workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ export default defineWorkspace([
},
// Longer timeout for Docker operations
testTimeout: 120_000,
// `clean --force` (image removal) in setup/teardown can exceed the
// default 10s hook timeout.
hookTimeout: 120_000,
},
},
{
Expand Down
Loading