mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-28 18:24:01 +00:00
testament: generic N-fold batching: windows CI 37mn=>16m (#14823)
* testament: run CI faster thanks to batching * move ta_in, tstdin into existing tosproc * move ta_out,tafalse,texitcode,tstderr into existing tosproc * joinable osproc * move tstdout into existing tosproc * spec: batchable; fix tests * fixup
This commit is contained in:
@@ -5,9 +5,10 @@ joinable: false
|
||||
#[
|
||||
joinable: false
|
||||
because it'd need cleanup up stdout
|
||||
]#
|
||||
|
||||
import stdtest/[specialpaths, unittest_light]
|
||||
see also: tests/osproc/*.nim; consider merging those into a single test here
|
||||
(easier to factor and test more things as a single self contained test)
|
||||
]#
|
||||
|
||||
when defined(case_testfile): # compiled test file for child process
|
||||
from posix import exitnow
|
||||
@@ -51,22 +52,58 @@ when defined(case_testfile): # compiled test file for child process
|
||||
echo args[1]
|
||||
main()
|
||||
|
||||
else:
|
||||
elif defined(case_testfile2):
|
||||
import strutils
|
||||
let x = stdin.readLine()
|
||||
echo x.parseInt + 5
|
||||
|
||||
elif defined(case_testfile3):
|
||||
echo "start ta_out"
|
||||
stdout.writeLine("to stdout")
|
||||
stdout.flushFile()
|
||||
stdout.writeLine("to stdout")
|
||||
stdout.flushFile()
|
||||
|
||||
stderr.writeLine("to stderr")
|
||||
stderr.flushFile()
|
||||
stderr.writeLine("to stderr")
|
||||
stderr.flushFile()
|
||||
|
||||
stdout.writeLine("to stdout")
|
||||
stdout.flushFile()
|
||||
stdout.writeLine("to stdout")
|
||||
stdout.flushFile()
|
||||
echo "end ta_out"
|
||||
|
||||
elif defined(case_testfile4):
|
||||
import system # we could remove that
|
||||
quit(QuitFailure)
|
||||
|
||||
else: # main driver
|
||||
import stdtest/[specialpaths, unittest_light]
|
||||
import os, osproc, strutils
|
||||
const nim = getCurrentCompilerExe()
|
||||
const sourcePath = currentSourcePath()
|
||||
let dir = getCurrentDir() / "tests" / "osproc"
|
||||
|
||||
template deferScoped(cleanup, body) =
|
||||
# pending https://github.com/nim-lang/RFCs/issues/236#issuecomment-646855314
|
||||
# xxx move to std/sugar or (preferably) some low level module
|
||||
try: body
|
||||
finally: cleanup
|
||||
|
||||
# we're testing `execShellCmd` so don't rely on it to compile test file
|
||||
# note: this should be exported in posix.nim
|
||||
proc c_system(cmd: cstring): cint {.importc: "system", header: "<stdlib.h>".}
|
||||
|
||||
proc compileNimProg(opt: string, name: string): string =
|
||||
result = buildDir / name.addFileExt(ExeExt)
|
||||
let cmd = "$# c -o:$# --hints:off $# $#" % [nim.quoteShell, result.quoteShell, opt, sourcePath.quoteShell]
|
||||
doAssert c_system(cmd) == 0, $cmd
|
||||
doAssert result.fileExists
|
||||
|
||||
block execShellCmdTest:
|
||||
## first, compile child program
|
||||
const sourcePath = currentSourcePath()
|
||||
let output = buildDir / "D20190111T024543".addFileExt(ExeExt)
|
||||
let cmd = "$# c -o:$# -d:release -d:case_testfile $#" % [nim, output,
|
||||
sourcePath]
|
||||
# we're testing `execShellCmd` so don't rely on it to compile test file
|
||||
# note: this should be exported in posix.nim
|
||||
proc c_system(cmd: cstring): cint {.importc: "system",
|
||||
header: "<stdlib.h>".}
|
||||
assertEquals c_system(cmd), 0
|
||||
let output = compileNimProg("-d:release -d:case_testfile", "D20190111T024543")
|
||||
|
||||
## use it
|
||||
template runTest(arg: string, expected: int) =
|
||||
@@ -79,7 +116,7 @@ else:
|
||||
runTest("quit_139", 139)
|
||||
|
||||
block execProcessTest:
|
||||
let dir = parentDir(currentSourcePath())
|
||||
let dir = sourcePath.parentDir
|
||||
let (_, err) = execCmdEx(nim & " c " & quoteShell(dir / "osproctest.nim"))
|
||||
doAssert err == 0
|
||||
let exePath = dir / addFileExt("osproctest", ExeExt)
|
||||
@@ -101,6 +138,7 @@ else:
|
||||
discard
|
||||
|
||||
import std/streams
|
||||
|
||||
block: # test for startProcess (more tests needed)
|
||||
# bugfix: windows stdin.close was a noop and led to blocking reads
|
||||
proc startProcessTest(command: string, options: set[ProcessOption] = {
|
||||
@@ -126,6 +164,56 @@ else:
|
||||
var result = startProcessTest("nim r --hints:off -", options = {}, input = "echo 3*4")
|
||||
doAssert result == ("12\n", 0)
|
||||
|
||||
block: # startProcess stdin (replaces old test `tstdin` + `ta_in`)
|
||||
let output = compileNimProg("-d:case_testfile2", "D20200626T215919")
|
||||
var p = startProcess(output, dir) # dir not needed though
|
||||
p.inputStream.write("5\n")
|
||||
p.inputStream.flush()
|
||||
var line = ""
|
||||
var s: seq[string]
|
||||
while p.outputStream.readLine(line.TaintedString):
|
||||
s.add line
|
||||
doAssert s == @["10"]
|
||||
|
||||
block:
|
||||
let output = compileNimProg("-d:case_testfile3", "D20200626T221233")
|
||||
var x = newStringOfCap(120)
|
||||
block: # startProcess stdout poStdErrToStdOut (replaces old test `tstdout` + `ta_out`)
|
||||
var p = startProcess(output, dir, options={poStdErrToStdOut})
|
||||
deferScoped: p.close()
|
||||
do:
|
||||
var sout: seq[string]
|
||||
while p.outputStream.readLine(x.TaintedString): sout.add x
|
||||
doAssert sout == @["start ta_out", "to stdout", "to stdout", "to stderr", "to stderr", "to stdout", "to stdout", "end ta_out"]
|
||||
block: # startProcess stderr (replaces old test `tstderr` + `ta_out`)
|
||||
var p = startProcess(output, dir, options={})
|
||||
deferScoped: p.close()
|
||||
do:
|
||||
var serr, sout: seq[string]
|
||||
while p.errorStream.readLine(x.TaintedString): serr.add x
|
||||
while p.outputStream.readLine(x.TaintedString): sout.add x
|
||||
doAssert serr == @["to stderr", "to stderr"]
|
||||
doAssert sout == @["start ta_out", "to stdout", "to stdout", "to stdout", "to stdout", "end ta_out"]
|
||||
|
||||
block: # startProcess exit code (replaces old test `texitcode` + `tafalse`)
|
||||
let output = compileNimProg("-d:case_testfile4", "D20200626T224758")
|
||||
var p = startProcess(output, dir)
|
||||
doAssert waitForExit(p) == QuitFailure
|
||||
p = startProcess(output, dir)
|
||||
var running = true
|
||||
while running:
|
||||
# xxx: avoid busyloop?
|
||||
running = running(p)
|
||||
doAssert waitForExit(p) == QuitFailure
|
||||
|
||||
# make sure that first call to running() after process exit returns false
|
||||
p = startProcess(output, dir)
|
||||
for j in 0..<30: # refs #13449
|
||||
os.sleep(50)
|
||||
if not running(p): break
|
||||
doAssert not running(p)
|
||||
doAssert waitForExit(p) == QuitFailure # avoid zombies
|
||||
|
||||
import std/strtabs
|
||||
block execProcessTest:
|
||||
var result = execCmdEx("nim r --hints:off -", options = {}, input = "echo 3*4")
|
||||
|
||||
Reference in New Issue
Block a user