| 1 | module main |
| 2 | |
| 3 | import os |
| 4 | import time |
| 5 | import os.cmdline |
| 6 | |
| 7 | enum Target { |
| 8 | both |
| 9 | stderr |
| 10 | stdout |
| 11 | alternate |
| 12 | } |
| 13 | |
| 14 | fn s2target(s string) Target { |
| 15 | return match s { |
| 16 | 'both' { Target.both } |
| 17 | 'stderr' { Target.stderr } |
| 18 | 'alternate' { Target.alternate } |
| 19 | else { Target.stdout } |
| 20 | } |
| 21 | } |
| 22 | |
| 23 | struct Context { |
| 24 | mut: |
| 25 | timeout_ms int |
| 26 | period_ms int |
| 27 | exitcode int |
| 28 | target Target |
| 29 | omode Target |
| 30 | is_verbose bool |
| 31 | show_wd bool |
| 32 | show_env bool |
| 33 | } |
| 34 | |
| 35 | fn (mut ctx Context) println(s string) { |
| 36 | if ctx.target == .alternate { |
| 37 | ctx.omode = if ctx.omode == .stderr { Target.stdout } else { Target.stderr } |
| 38 | } |
| 39 | if ctx.target in [.both, .stdout] || ctx.omode == .stdout { |
| 40 | println('stdout, ${s}') |
| 41 | } |
| 42 | if ctx.target in [.both, .stderr] || ctx.omode == .stderr { |
| 43 | eprintln('stderr, ${s}') |
| 44 | } |
| 45 | } |
| 46 | |
| 47 | fn do_timeout(c &Context) { |
| 48 | mut ctx := unsafe { c } |
| 49 | time.sleep(ctx.timeout_ms * time.millisecond) |
| 50 | exit(ctx.exitcode) |
| 51 | } |
| 52 | |
| 53 | fn main() { |
| 54 | unbuffer_stdout() |
| 55 | mut ctx := Context{} |
| 56 | args := os.args[1..] |
| 57 | if '-h' in args || '--help' in args { |
| 58 | println("Usage: |
| 59 | test_os_process [-v] [-h] [-target stderr/stdout/both/alternate] [-show_wd] [-show_env] [-exitcode 0] [-timeout_ms 200] [-period_ms 50] |
| 60 | Prints lines periodically (-period_ms), to stdout/stderr (-target). |
| 61 | After a while (-timeout_ms), exit with (-exitcode). |
| 62 | This program is useful for platform independent testing |
| 63 | of child process/standard input/output control. |
| 64 | It is used in V's `os` module tests. |
| 65 | ") |
| 66 | return |
| 67 | } |
| 68 | ctx.is_verbose = '-v' in args |
| 69 | ctx.show_wd = '-show_wd' in args |
| 70 | ctx.show_env = '-show_env' in args |
| 71 | ctx.target = s2target(cmdline.option(args, '-target', 'both')) |
| 72 | ctx.exitcode = cmdline.option(args, '-exitcode', '0').int() |
| 73 | ctx.timeout_ms = cmdline.option(args, '-timeout_ms', '200').int() |
| 74 | ctx.period_ms = cmdline.option(args, '-period_ms', '50').int() |
| 75 | if ctx.target == .alternate { |
| 76 | ctx.omode = .stdout |
| 77 | } |
| 78 | if ctx.is_verbose { |
| 79 | eprintln('> args: ${args} | context: ${ctx}') |
| 80 | } |
| 81 | if ctx.show_wd { |
| 82 | ctx.println('WORK_DIR=${os.getwd()}') |
| 83 | } |
| 84 | if ctx.show_env { |
| 85 | all := os.environ() |
| 86 | for k, v in all { |
| 87 | ctx.println('${k}=${v}') |
| 88 | } |
| 89 | } |
| 90 | spawn do_timeout(&ctx) |
| 91 | ctx.println('start') |
| 92 | for i := 1; true; i++ { |
| 93 | ctx.println('${i}') |
| 94 | time.sleep(ctx.period_ms * time.millisecond) |
| 95 | } |
| 96 | ctx.println('done') |
| 97 | time.sleep(100 * time.second) |
| 98 | } |
| 99 | |