-
Notifications
You must be signed in to change notification settings - Fork 5
Background Jobs Stage 3-4 #234
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: bg-jobs
Are you sure you want to change the base?
Changes from all commits
9516b3e
6a7bae5
dd0c5ae
9a57b1f
83fdd6a
d87fb88
88d8591
26931dd
527e659
befb7ea
b4990fa
fad4be6
075b012
9ce8f96
0775229
126048c
60568df
ae4f6b6
c2f129e
54215f7
00efa63
1973026
a01ec1a
261d3f7
df913a8
761986e
cd57560
03cbfda
5d89b5b
21336ff
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| package internal | ||
|
|
||
| import ( | ||
| "github.com/codecrafters-io/shell-tester/internal/logged_shell_asserter" | ||
| "github.com/codecrafters-io/shell-tester/internal/shell_executable" | ||
| "github.com/codecrafters-io/shell-tester/internal/test_cases" | ||
| "github.com/codecrafters-io/tester-utils/test_case_harness" | ||
| ) | ||
|
|
||
| func testBG3(stageHarness *test_case_harness.TestCaseHarness) error { | ||
| logger := stageHarness.Logger | ||
| shell := shell_executable.NewShellExecutable(stageHarness) | ||
| asserter := logged_shell_asserter.NewLoggedShellAsserter(shell) | ||
|
|
||
| if err := asserter.StartShellAndAssertPrompt(true); err != nil { | ||
| return err | ||
| } | ||
|
|
||
| // Launch a program in the background | ||
| backgroundLaunchCommand := "sleep 100" | ||
| backgroundLaunchTestCase := test_cases.BackgroundCommandResponseTestCase{ | ||
| Command: backgroundLaunchCommand, | ||
| SuccessMessage: "✓ Output includes job number with PID", | ||
| ExpectedJobNumber: 1, | ||
| } | ||
|
|
||
| if err := backgroundLaunchTestCase.Run(asserter, shell, logger); err != nil { | ||
| return err | ||
| } | ||
|
|
||
| // Assert the job output | ||
| jobsTestCase := test_cases.JobsBuiltinResponseTestCase{ | ||
| ExpectedOutputEntries: []test_cases.JobsBuiltinOutputEntry{{ | ||
| JobNumber: 1, | ||
| Status: "Running", | ||
| LaunchCommand: backgroundLaunchCommand, | ||
| Marker: test_cases.CurrentJob, | ||
| }}, | ||
| SuccessMessage: "✓ 1 entry matches the running job", | ||
| } | ||
|
|
||
| if err := jobsTestCase.Run(asserter, shell, logger); err != nil { | ||
| return err | ||
| } | ||
|
|
||
| return logAndQuit(asserter, nil) | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| package internal | ||
|
|
||
| import ( | ||
| "fmt" | ||
|
|
||
| "github.com/codecrafters-io/shell-tester/internal/logged_shell_asserter" | ||
| "github.com/codecrafters-io/shell-tester/internal/shell_executable" | ||
| "github.com/codecrafters-io/shell-tester/internal/test_cases" | ||
| "github.com/codecrafters-io/tester-utils/logger" | ||
| "github.com/codecrafters-io/tester-utils/test_case_harness" | ||
| "github.com/dustin/go-humanize/english" | ||
| ) | ||
|
|
||
| func testBG4(stageHarness *test_case_harness.TestCaseHarness) error { | ||
| logger := stageHarness.Logger | ||
| shell := shell_executable.NewShellExecutable(stageHarness) | ||
| asserter := logged_shell_asserter.NewLoggedShellAsserter(shell) | ||
|
|
||
| if err := asserter.StartShellAndAssertPrompt(true); err != nil { | ||
| return err | ||
| } | ||
|
|
||
| commands := []string{"sleep 100", "sleep 200", "sleep 300"} | ||
|
|
||
| if err := launchBgCommandAndAssertJobs(asserter, shell, logger, commands); err != nil { | ||
| return err | ||
| } | ||
|
|
||
| return logAndQuit(asserter, nil) | ||
| } | ||
|
|
||
| // launchBgCommandAndAssertJobs launches the given bgCommands one by one | ||
| // with a 'jobs' call after each launch | ||
| func launchBgCommandAndAssertJobs(asserter *logged_shell_asserter.LoggedShellAsserter, shell *shell_executable.ShellExecutable, logger *logger.Logger, bgCommands []string) error { | ||
| type jobInfo struct { | ||
| JobNumber int | ||
| Command string | ||
| } | ||
|
|
||
| var jobs []jobInfo | ||
|
|
||
| for i, bgCommand := range bgCommands { | ||
| backgroundLaunchTestCase := test_cases.BackgroundCommandResponseTestCase{ | ||
| Command: bgCommand, | ||
| SuccessMessage: "✓ Output includes job number with PID", | ||
| ExpectedJobNumber: i + 1, | ||
| } | ||
|
|
||
| if err := backgroundLaunchTestCase.Run(asserter, shell, logger); err != nil { | ||
| return err | ||
| } | ||
|
|
||
| jobs = append(jobs, jobInfo{JobNumber: i + 1, Command: bgCommand}) | ||
|
|
||
| jobsOutputEntries := make([]test_cases.JobsBuiltinOutputEntry, 0, len(jobs)) | ||
|
|
||
| for i, job := range jobs { | ||
| // Default marker is unmarked | ||
| marker := test_cases.UnmarkedJob | ||
|
|
||
| // If the job was recently launched, it is the 'Current' job | ||
| if i == len(jobs)-1 { | ||
| marker = test_cases.CurrentJob | ||
| // If the job was launched previously, it is the 'Previous' job | ||
| } else if i == len(jobs)-2 { | ||
| marker = test_cases.PreviousJob | ||
| } | ||
|
|
||
| jobsOutputEntries = append(jobsOutputEntries, test_cases.JobsBuiltinOutputEntry{ | ||
| JobNumber: job.JobNumber, | ||
| Status: "Running", | ||
| LaunchCommand: job.Command, | ||
| Marker: marker, | ||
| }) | ||
| } | ||
|
|
||
| jobsTestCase := test_cases.JobsBuiltinResponseTestCase{ | ||
| ExpectedOutputEntries: jobsOutputEntries, | ||
| SuccessMessage: fmt.Sprintf( | ||
| "✓ %s match the running %s", | ||
| english.Plural(len(jobsOutputEntries), "entry", "entries"), | ||
| english.PluralWord(len(jobsOutputEntries), "job", "jobs"), | ||
| ), | ||
cursor[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| if err := jobsTestCase.Run(asserter, shell, logger); err != nil { | ||
| return err | ||
| } | ||
| } | ||
| return nil | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| Debug = true | ||
|
|
||
| [33m[tester::#DK5] [0m[94mRunning tests for Stage #DK5 (dk5)[0m | ||
| [33m[tester::#DK5] [0m[94mRunning ./your_program.sh[0m | ||
| [33m[your-program] [0m[0m$ sleep 100 &[0m | ||
| [33m[your-program] [0m[0m[1] 2518[0m | ||
| [33m[tester::#DK5] [0m[92m✓ Output includes job number with PID[0m | ||
| [33m[your-program] [0m[0m$ jobs[0m | ||
| [33m[your-program] [0m[0m[1]- Running sleep 100 &[0m | ||
| [33m[tester::#DK5] [0m[91m^ Line does not match expected value.[0m | ||
| [33m[tester::#DK5] [0m[91m[32mExpected:[0m "[1]+ Running sleep 100 &"[0m | ||
| [33m[tester::#DK5] [0m[91m[31mReceived:[0m "[1]- Running sleep 100 &"[0m | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is fine for now, but I can imagine a lot of confusion stemming from the usage of spaces here - if the user users a single space between each but has another mistake, it might look like we're complaining about spaces when we're complaining about something else. Can't think of a neat way to solve this, but I think one way would be to use LLMs. We could expose this via the stage harness and find a mechanism to do restricted prompts (i.e. we have some guarantees over what kind of output they can emit). Then we could generate error messages like "missing space between - and Running"
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Noted - Adding this to linear. |
||
| [33m[your-program] [0m[0m$ [0m | ||
| [33m[tester::#DK5] [0m[91mAssertion failed.[0m | ||
| [33m[tester::#DK5] [0m[91mTest failed[0m | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| Debug = true | ||
|
|
||
| [33m[tester::#DK5] [0m[94mRunning tests for Stage #DK5 (dk5)[0m | ||
| [33m[tester::#DK5] [0m[94mRunning ./your_program.sh[0m | ||
| [33m[your-program] [0m[0m$ sleep 100 &[0m | ||
| [33m[your-program] [0m[0m[1] 2318[0m | ||
| [33m[tester::#DK5] [0m[92m✓ Output includes job number with PID[0m | ||
| [33m[your-program] [0m[0m$ jobs[0m | ||
| [33m[your-program] [0m[0m[1]+Running sleep 100 &[0m | ||
| [33m[tester::#DK5] [0m[91m^ Line does not match expected value.[0m | ||
| [33m[tester::#DK5] [0m[91m[32mExpected:[0m "[1]+ Running sleep 100 &"[0m | ||
| [33m[tester::#DK5] [0m[91m[31mReceived:[0m "[1]+Running sleep 100 &"[0m | ||
| [33m[your-program] [0m[0m$ [0m | ||
| [33m[tester::#DK5] [0m[91mAssertion failed.[0m | ||
| [33m[tester::#DK5] [0m[91mTest failed[0m |
Uh oh!
There was an error while loading. Please reload this page.