mirror of
https://github.com/logos-storage/logos-storage-nim.git
synced 2026-01-07 16:03:13 +00:00
85 lines
2.7 KiB
Nim
85 lines
2.7 KiB
Nim
import std/os
|
|
import std/strformat
|
|
import pkg/chronos
|
|
import pkg/chronos/asyncproc
|
|
import pkg/codex/logutils
|
|
|
|
{.push raises: [].}
|
|
|
|
proc nextFreePort*(startPort: int): Future[int] {.async: (raises: [CancelledError]).} =
|
|
proc client(server: StreamServer, transp: StreamTransport) {.async: (raises: []).} =
|
|
await transp.closeWait()
|
|
|
|
var port = startPort
|
|
while true:
|
|
trace "checking if port is free", port
|
|
try:
|
|
let host = initTAddress("127.0.0.1", port)
|
|
# We use ReuseAddr here only to be able to reuse the same IP/Port when
|
|
# there's a TIME_WAIT socket. It's useful when running the test multiple
|
|
# times or if a test ran previously using the same port.
|
|
var server = createStreamServer(host, client, {ReuseAddr})
|
|
trace "port is free", port
|
|
await server.closeWait()
|
|
return port
|
|
except TransportOsError:
|
|
trace "port is not free", port
|
|
inc port
|
|
except TransportAddressError:
|
|
raiseAssert "bad address"
|
|
|
|
proc sanitize*(pathSegment: string): string =
|
|
var sanitized = pathSegment
|
|
for invalid in invalidFilenameChars.items:
|
|
sanitized = sanitized.replace(invalid, '_').replace(' ', '_')
|
|
sanitized
|
|
|
|
proc getLogFile*(
|
|
logDir, startTime, suiteName, testName, role: string, index = int.none
|
|
): string {.raises: [IOError, OSError].} =
|
|
let logsDir =
|
|
if logDir == "":
|
|
currentSourcePath.parentDir() / "logs" / sanitize(startTime & "__" & suiteName) /
|
|
sanitize(testName)
|
|
else:
|
|
logDir / sanitize(suiteName) / sanitize(testName)
|
|
|
|
createDir(logsDir)
|
|
|
|
var fn = $role
|
|
if idx =? index:
|
|
fn &= "_" & $idx
|
|
fn &= ".log"
|
|
|
|
let fileName = logsDir / fn
|
|
return fileName
|
|
|
|
proc appendFile*(filename: string, content: string) {.raises: [IOError].} =
|
|
## Opens a file named `filename` for writing. Then writes the
|
|
## `content` completely to the file and closes the file afterwards.
|
|
## Raises an IO exception in case of an error.
|
|
var f: File
|
|
try:
|
|
f = open(filename, fmAppend)
|
|
f.write(content)
|
|
except IOError as e:
|
|
raise newException(IOError, "cannot open and write " & filename & ": " & e.msg)
|
|
finally:
|
|
close(f)
|
|
|
|
when defined(windows):
|
|
proc forceKillProcess*(
|
|
processName, matchingCriteria: string
|
|
): Future[CommandExResponse] {.
|
|
async: (
|
|
raises: [
|
|
AsyncProcessError, AsyncProcessTimeoutError, CancelledError, ValueError,
|
|
OSError,
|
|
]
|
|
)
|
|
.} =
|
|
let path = splitFile(currentSourcePath()).dir / "scripts" / "winkillprocess.sh"
|
|
let cmd = &"{absolutePath(path)} kill {processName} \"{matchingCriteria}\""
|
|
trace "Forcefully killing windows process", processName, matchingCriteria, cmd
|
|
return await execCommandEx(cmd, timeout = 5.seconds)
|