import httpclient, json, os, osproc, sequtils, strutils, tempfile, unittest, untar from langutils import sameContents import ../testutil import ../../../main/nim/strawbosspkg/configuration import ../../../main/nim/strawbosspkg/private/util let apiBase = "http://localhost:8180/api" let cfgFilePath = "src/test/json/strawboss.config.json" let cfg = loadStrawBossConfig(cfgFilePath) # Util template intended for use to manually review test case. # Inserting into a test case will prevent the test case from cleaning up it's # working files and echo the command to start StrawBoss using that test's # configuration and working files. template keepEnv(): untyped = preserveEnv = true echo "artifacts dir: " & tempArtifactsDir echo "strawboss serve -c " & tempCfgPath suite "strawboss server": # Suite setup: extract test project let testProjTempDir = mkdtemp() let testProjTarFile = newTarFile("src/test/test-project.tar.gz") let testProjName = "test-project" testProjTarFile.extract(testProjTempDir) # per-test setup: spin up a fresh strawboss instance setup: let tempArtifactsDir = mkdtemp() let (_, tempCfgPath) = mkstemp() var preserveEnv = false # copy our test config var newCfg = cfg newCfg.artifactsRepo = tempArtifactsDir # update the repo string for the extracted test project var testProjDef = newCfg.findProject(testProjName) testProjDef.repo = testProjTempDir & "/" & testProjName newCfg.setProject(testProjName, testProjDef) # save the updated config and start the strawboss instance using it writeFile(tempCfgPath, $newCfg) let serverProcess = startProcess("./strawboss", ".", @["serve", "-c", tempCfgPath], loadEnv(), {poUsePath}) # give the server time to spin up sleep(100) teardown: discard newAsyncHttpClient().post(apiBase & "/service/debug/stop") if not preserveEnv: removeDir(tempArtifactsDir) removeFile(tempCfgPath) # give the server time to spin down but kill it after that sleep(100) if serverProcess.running: kill(serverProcess) test "handle missing project configuration": let http = newAuthenticatedHttpClient(apibase, "bob@builder.com", "password") let resp = http.get(apiBase & "/projects/" & cfg.projects[0].name) check resp.status.startsWith("404") test "gives 404 when no versions built": let http = newAuthenticatedHttpClient(apibase, "bob@builder.com", "password") let resp = http.get(apiBase & "/projects/" & testProjName & "/versions") check resp.status.startsWith("404") test "GET /api/project/@projectName/versions": let projArtifactsDir = tempArtifactsDir & "/" & testProjName let expectedVersions = @["alpha", "beta", "1.0.0", "1.0.1"] # Touch configuration files createDir(projArtifactsDir) for v in expectedVersions: var f: File check open(f, projArtifactsDir & "/configuration." & v & ".json", fmWrite) close(f) let http = newAuthenticatedHttpClient(apibase, "bob@builder.com", "password") let resp = http.get(apiBase & "/project/" & testProjName & "/versions") let returnedVersions = parseJson(resp.body).getElems.mapIt(it.getStr) check sameContents(expectedVersions, returnedVersions) test "run a successful build with artifacts": let http = newAuthenticatedHttpClient(apibase, "bob@builder.com", "password") let resp = http.get(apiBase & "/project/" & testProjName & "/step/build/run/0.1.0" check resp.status.startsWith("200") # TODO # check that the project directory has been created in the artifacts repo # check that the run status file has been created in the artifacts repo # check that the run status is not failed # wait for the build to complete # check that the status is "complete" # check that the artifacts we expect are present check false test "run a time-consuming build and check the status via the API" check false # Last-chance catch to kill the server in case some test err'ed and didn't # reach it's teardown handler discard newAsyncHttpClient().post(apiBase & "/service/debug/stop") # Also, delete the extracted test project "source" repo removeDir(testProjTempDir)