diff options
Diffstat (limited to 'tests/osproc')
-rw-r--r-- | tests/osproc/passenv.nim | 32 | ||||
-rw-r--r-- | tests/osproc/tclose.nim | 24 | ||||
-rw-r--r-- | tests/osproc/texecps.nim | 30 | ||||
-rw-r--r-- | tests/osproc/texitsignal.nim | 39 | ||||
-rw-r--r-- | tests/osproc/tnoexe.nim | 27 | ||||
-rw-r--r-- | tests/osproc/treadlines.nim | 23 | ||||
-rw-r--r-- | tests/osproc/twaitforexit.nim | 38 | ||||
-rw-r--r-- | tests/osproc/tworkingdir.nim | 21 |
8 files changed, 234 insertions, 0 deletions
diff --git a/tests/osproc/passenv.nim b/tests/osproc/passenv.nim new file mode 100644 index 000000000..40b1c3f7c --- /dev/null +++ b/tests/osproc/passenv.nim @@ -0,0 +1,32 @@ +discard """ + file: "passenv.nim" + output: "123" + targets: "c cpp objc" +""" + +import osproc, os, strtabs + +# Checks that the environment is passed correctly in startProcess +# To do that launches a copy of itself with a new environment. + +if paramCount() == 0: + # Parent process + + let env = newStringTable() + env["A"] = "1" + env["B"] = "2" + env["C"] = "3" + + let p = startProcess( + getAppFilename(), + args = @["child"], + env = env, + options = {poStdErrToStdOut, poUsePath, poParentStreams} + ) + + discard p.waitForExit + +else: + # Child process + # should output "123" + echo getEnv("A") & getEnv("B") & getEnv("C") diff --git a/tests/osproc/tclose.nim b/tests/osproc/tclose.nim new file mode 100644 index 000000000..1c99237c7 --- /dev/null +++ b/tests/osproc/tclose.nim @@ -0,0 +1,24 @@ +discard """ + exitcode: 0 +""" + +when defined(linux): + import osproc, os + + proc countFds(): int = + result = 0 + for i in walkDir("/proc/self/fd"): + result += 1 + + let initCount = countFds() + + let p = osproc.startProcess("echo", options={poUsePath}) + doAssert countFds() == initCount + 3 + p.close + doAssert countFds() == initCount + + let p1 = osproc.startProcess("echo", options={poUsePath}) + discard p1.inputStream + doAssert countFds() == initCount + 3 + p.close + doAssert countFds() == initCount diff --git a/tests/osproc/texecps.nim b/tests/osproc/texecps.nim new file mode 100644 index 000000000..b818fe8eb --- /dev/null +++ b/tests/osproc/texecps.nim @@ -0,0 +1,30 @@ +discard """ +joinable: false +""" + +import osproc, streams, strutils, os + +const NumberOfProcesses = 13 + +var gResults {.threadvar.}: seq[string] + +proc execCb(idx: int, p: Process) = + let exitCode = p.peekExitCode + if exitCode < len(gResults): + gResults[exitCode] = p.outputStream.readAll.strip + +when true: + if paramCount() == 0: + gResults = newSeq[string](NumberOfProcesses) + var checks = newSeq[string](NumberOfProcesses) + var commands = newSeq[string](NumberOfProcesses) + for i in 0..len(commands) - 1: + commands[i] = getAppFileName() & " " & $i + checks[i] = $i + let cres = execProcesses(commands, options = {poStdErrToStdOut}, + afterRunEvent = execCb) + doAssert(cres == len(commands) - 1) + doAssert(gResults == checks) + else: + echo paramStr(1) + programResult = parseInt(paramStr(1)) diff --git a/tests/osproc/texitsignal.nim b/tests/osproc/texitsignal.nim new file mode 100644 index 000000000..fbf5068ea --- /dev/null +++ b/tests/osproc/texitsignal.nim @@ -0,0 +1,39 @@ +discard """ + output: '''true +true''' + targets: "c" +""" + +import os, osproc +when not defined(windows): + import posix + +# Checks that the environment is passed correctly in startProcess +# To do that launches a copy of itself with a new environment. + +if paramCount() == 0: + # Parent process + + let p = startProcess( + getAppFilename(), + args = @["child"], + options = {poStdErrToStdOut, poUsePath, poParentStreams} + ) + + echo p.running() + + p.kill() + + when defined(windows): + # windows kill happens using TerminateProcess(h, 0), so we should get a + # 0 here + echo p.waitForExit() == 0 + elif defined(haiku): + # on Haiku, the program main thread receive SIGKILLTHR + echo p.waitForExit() == 128 + SIGKILLTHR + else: + # on posix (non-windows), kill sends SIGKILL + echo p.waitForExit() == 128 + SIGKILL + +else: + sleep(5000) # should get killed before this diff --git a/tests/osproc/tnoexe.nim b/tests/osproc/tnoexe.nim new file mode 100644 index 000000000..19a3cca67 --- /dev/null +++ b/tests/osproc/tnoexe.nim @@ -0,0 +1,27 @@ +discard """ + output: '''true +true''' +""" + +import std/osproc + +const command = "lsaaa -lah" + +try: + let process = startProcess(command, options = {poUsePath}) + discard process.waitForExit() +except OSError as e: + echo e.errorCode != 0 + +# `poEvalCommand`, invokes the system shell to run the specified command +try: + let process = startProcess(command, options = {poUsePath, poEvalCommand}) + # linux + let exitCode = process.waitForExit() + echo exitCode != 0 +except OSError as e: + # Because the implementation of `poEvalCommand` on different platforms is inconsistent, + # Linux will not throw an exception, but Windows will throw an exception + + # windows + echo e.errorCode != 0 diff --git a/tests/osproc/treadlines.nim b/tests/osproc/treadlines.nim new file mode 100644 index 000000000..bb6a7f129 --- /dev/null +++ b/tests/osproc/treadlines.nim @@ -0,0 +1,23 @@ +discard """ + output: ''' +Error: cannot open 'a.nim' +Error: cannot open 'b.nim' +''' + targets: "c" +""" + +import osproc +from std/os import getCurrentCompilerExe + +var ps: seq[Process] # compile & run 2 progs in parallel +const nim = getCurrentCompilerExe() +for prog in ["a", "b"]: + ps.add startProcess(nim, "", + ["r", "--hint:Conf:off", "--hint:Processing:off", prog], + options = {poUsePath, poDaemon, poStdErrToStdOut}) + +for p in ps: + let (lines, exCode) = p.readLines + if exCode != 0: + for line in lines: echo line + p.close diff --git a/tests/osproc/twaitforexit.nim b/tests/osproc/twaitforexit.nim new file mode 100644 index 000000000..535faca63 --- /dev/null +++ b/tests/osproc/twaitforexit.nim @@ -0,0 +1,38 @@ +import std/[osproc, os, times] + +block: # bug #5091 + when defined(linux): + const filename = "false" + var p = startProcess(filename, options = {poStdErrToStdOut, poUsePath}) + os.sleep(1000) # make sure process has exited already + + let atStart = getTime() + const msWait = 2000 + + try: + discard waitForExit(p, msWait) + except OSError: + discard + + # check that we don't have to wait msWait milliseconds + doAssert(getTime() < atStart + milliseconds(msWait)) + +block: # bug #23825 + + # the sleep command might not be available in all Windows installations + + when defined(linux): + + var thr: array[0..99, Thread[int]] + + proc threadFunc(i: int) {.thread.} = + let sleepTime = float(i) / float(thr.len + 1) + doAssert sleepTime < 1.0 + let p = startProcess("sleep", workingDir = "", args = @[$sleepTime], options = {poUsePath, poParentStreams}) + # timeout = 1_000_000 seconds ~= 278 hours ~= 11.5 days + doAssert p.waitForExit(timeout=1_000_000_000) == 0 + + for i in low(thr)..high(thr): + createThread(thr[i], threadFunc, i) + + joinThreads(thr) diff --git a/tests/osproc/tworkingdir.nim b/tests/osproc/tworkingdir.nim new file mode 100644 index 000000000..3a3c1b6ab --- /dev/null +++ b/tests/osproc/tworkingdir.nim @@ -0,0 +1,21 @@ +discard """ + output: "" +""" + +import osproc, os +when defined(windows): + # Windows don't have this issue, so we won't test it. + discard +else: + let dir1 = getCurrentDir() + var process: Process + when defined(android): + process = startProcess("/system/bin/env", "/system/bin", ["true"]) + elif defined(haiku): + process = startProcess("/bin/env", "/bin", ["true"]) + else: + process = startProcess("/usr/bin/env", "/usr/bin", ["true"]) + let dir2 = getCurrentDir() + discard process.waitForExit() + process.close() + doAssert(dir1 == dir2, $dir1 & " != " & $dir2) |