From d4767fae8e0b3890187312ae9c7fe6c3805ce30c Mon Sep 17 00:00:00 2001 From: konard Date: Tue, 9 Sep 2025 22:32:33 +0300 Subject: [PATCH 1/3] Initial commit with task details for issue #22 Adding CLAUDE.md with task information for AI processing. This file will be removed when the task is complete. Issue: https://github.com/link-foundation/command-stream/issues/22 --- CLAUDE.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..91e4846 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,5 @@ +Issue to solve: https://github.com/link-foundation/command-stream/issues/22 +Your prepared branch: issue-22-51ab60ad +Your prepared working directory: /tmp/gh-issue-solver-1757446346826 + +Proceed. \ No newline at end of file From 6be0a4de1a9aa0854bb3017ba04121c7bae53bdc Mon Sep 17 00:00:00 2001 From: konard Date: Tue, 9 Sep 2025 22:32:49 +0300 Subject: [PATCH 2/3] Remove CLAUDE.md - PR created successfully --- CLAUDE.md | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index 91e4846..0000000 --- a/CLAUDE.md +++ /dev/null @@ -1,5 +0,0 @@ -Issue to solve: https://github.com/link-foundation/command-stream/issues/22 -Your prepared branch: issue-22-51ab60ad -Your prepared working directory: /tmp/gh-issue-solver-1757446346826 - -Proceed. \ No newline at end of file From 5d15cbca6bc0564109ca2639b0b64ab8e9b101bf Mon Sep 17 00:00:00 2001 From: konard Date: Tue, 9 Sep 2025 22:37:03 +0300 Subject: [PATCH 3/3] Add comprehensive parallel sleep commands test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Implements test for issue #22 that validates the ability to execute 2-3 commands with sleep inside in parallel. The test suite includes: - 2 parallel sleep commands with timing validation - 3 parallel sleep commands with timing validation - Mixed duration sleep commands executed in parallel - Parallel commands with output verification - Individual execution context verification for parallel commands All tests verify that commands execute truly in parallel (not sequentially) by measuring execution time and ensuring it matches the longest sleep duration rather than the sum of all sleep durations. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- tests/parallel-sleep.test.mjs | 147 ++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 tests/parallel-sleep.test.mjs diff --git a/tests/parallel-sleep.test.mjs b/tests/parallel-sleep.test.mjs new file mode 100644 index 0000000..a02cac9 --- /dev/null +++ b/tests/parallel-sleep.test.mjs @@ -0,0 +1,147 @@ +import { test, expect, describe, beforeEach, afterEach } from 'bun:test'; +import './test-helper.mjs'; // Automatically sets up beforeEach/afterEach cleanup +import { $, shell, disableVirtualCommands } from '../src/$.mjs'; + +// Reset shell settings before each test to prevent interference +beforeEach(() => { + shell.errexit(false); + shell.verbose(false); + shell.xtrace(false); + shell.pipefail(false); + shell.nounset(false); + // Disable virtual commands for these tests to ensure system command behavior + disableVirtualCommands(); +}); + +// Reset shell settings after each test to prevent interference with other test files +afterEach(() => { + shell.errexit(false); + shell.verbose(false); + shell.xtrace(false); + shell.pipefail(false); + shell.nounset(false); +}); + +describe('Parallel Sleep Commands Execution', () => { + test('should execute 2 sleep commands in parallel', async () => { + const startTime = Date.now(); + + // Start 2 parallel sleep commands with 0.5 second delay each + const promises = [ + $`sleep 0.5`, + $`sleep 0.5` + ]; + + const results = await Promise.all(promises); + const endTime = Date.now(); + const duration = endTime - startTime; + + // Both commands should complete successfully + expect(results[0].code).toBe(0); + expect(results[1].code).toBe(0); + + // Total duration should be closer to 0.5s (parallel) than 1.0s (sequential) + // Allow some tolerance for system overhead + expect(duration).toBeLessThan(800); // Should be much less than 800ms if truly parallel + expect(duration).toBeGreaterThan(400); // Should be at least 400ms since sleep is 0.5s + }); + + test('should execute 3 sleep commands in parallel', async () => { + const startTime = Date.now(); + + // Start 3 parallel sleep commands with 0.3 second delay each + const promises = [ + $`sleep 0.3`, + $`sleep 0.3`, + $`sleep 0.3` + ]; + + const results = await Promise.all(promises); + const endTime = Date.now(); + const duration = endTime - startTime; + + // All commands should complete successfully + expect(results[0].code).toBe(0); + expect(results[1].code).toBe(0); + expect(results[2].code).toBe(0); + + // Total duration should be closer to 0.3s (parallel) than 0.9s (sequential) + // Allow some tolerance for system overhead + expect(duration).toBeLessThan(600); // Should be much less than 600ms if truly parallel + expect(duration).toBeGreaterThan(250); // Should be at least 250ms since sleep is 0.3s + }); + + test('should execute mixed duration sleep commands in parallel', async () => { + const startTime = Date.now(); + + // Start 3 parallel sleep commands with different durations + const promises = [ + $`sleep 0.2`, + $`sleep 0.4`, + $`sleep 0.3` + ]; + + const results = await Promise.all(promises); + const endTime = Date.now(); + const duration = endTime - startTime; + + // All commands should complete successfully + expect(results[0].code).toBe(0); + expect(results[1].code).toBe(0); + expect(results[2].code).toBe(0); + + // Total duration should be determined by the longest sleep (0.4s), not the sum (0.9s) + // Allow some tolerance for system overhead + expect(duration).toBeLessThan(650); // Should be much less than 650ms if truly parallel + expect(duration).toBeGreaterThan(350); // Should be at least 350ms since longest sleep is 0.4s + }); + + test('should handle parallel sleep commands with output verification', async () => { + const startTime = Date.now(); + + // Start 2 parallel sleep commands that also produce output + const promises = [ + $`sh -c 'echo "command1 start"; sleep 0.2; echo "command1 end"'`, + $`sh -c 'echo "command2 start"; sleep 0.3; echo "command2 end"'` + ]; + + const results = await Promise.all(promises); + const endTime = Date.now(); + const duration = endTime - startTime; + + // Both commands should complete successfully + expect(results[0].code).toBe(0); + expect(results[1].code).toBe(0); + + // Verify output content + expect(results[0].stdout.trim()).toContain('command1 start'); + expect(results[0].stdout.trim()).toContain('command1 end'); + expect(results[1].stdout.trim()).toContain('command2 start'); + expect(results[1].stdout.trim()).toContain('command2 end'); + + // Duration should be closer to max(0.2s, 0.3s) = 0.3s, not sum = 0.5s + expect(duration).toBeLessThan(550); // Should be much less than 550ms if truly parallel + expect(duration).toBeGreaterThan(250); // Should be at least 250ms since longest sleep is 0.3s + }); + + test('should maintain individual command execution context in parallel', async () => { + // Test that each parallel command maintains its own execution environment + const commands = [ + $`sh -c 'VAR="value1"; sleep 0.1; echo "Command 1: $VAR"'`, + $`sh -c 'VAR="value2"; sleep 0.1; echo "Command 2: $VAR"'`, + $`sh -c 'VAR="value3"; sleep 0.1; echo "Command 3: $VAR"'` + ]; + + const results = await Promise.all(commands); + + // All commands should succeed + results.forEach(result => { + expect(result.code).toBe(0); + }); + + // Each should have its own variable value + expect(results[0].stdout.trim()).toBe('Command 1: value1'); + expect(results[1].stdout.trim()).toBe('Command 2: value2'); + expect(results[2].stdout.trim()).toBe('Command 3: value3'); + }); +}); \ No newline at end of file