summary refs log tree commit diff stats
path: root/testament/azure.nim
diff options
context:
space:
mode:
authorLeorize <leorize+oss@disroot.org>2019-10-03 17:36:07 +0200
committernarimiran <narimiran@disroot.org>2019-10-03 18:36:07 +0200
commitacebcd7899bf497588b509bf0524368cf7323240 (patch)
treefe449a89e66ac1400ee029f2ecbf14d145133065 /testament/azure.nim
parent880df4de625a7ae09da0a5b4b681ab4b49a98dbd (diff)
downloadNim-acebcd7899bf497588b509bf0524368cf7323240.tar.gz
testament: add azure integration
Diffstat (limited to 'testament/azure.nim')
-rw-r--r--testament/azure.nim95
1 files changed, 95 insertions, 0 deletions
diff --git a/testament/azure.nim b/testament/azure.nim
new file mode 100644
index 000000000..7299af480
--- /dev/null
+++ b/testament/azure.nim
@@ -0,0 +1,95 @@
+#
+#
+#              The Nim Tester
+#        (c) Copyright 2019 Leorize
+#
+#    Look at license.txt for more info.
+#    All rights reserved.
+
+import base64, json, httpclient, os, strutils
+import specs
+
+const
+  ApiRuns = "/_apis/test/runs"
+  ApiVersion = "?api-version=5.0"
+  ApiResults = ApiRuns & "/$1/results"
+
+var runId* = -1
+
+proc getAzureEnv(env: string): string =
+  # Conversion rule at:
+  # https://docs.microsoft.com/en-us/azure/devops/pipelines/process/variables#set-variables-in-pipeline
+  env.toUpperAscii().replace('.', '_').getEnv
+
+proc invokeRest(httpMethod: HttpMethod; api: string; body = ""): Response =
+  let http = newHttpClient()
+  defer: close http
+  result = http.request(getAzureEnv("System.TeamFoundationCollectionUri") &
+                        getAzureEnv("System.TeamProjectId") & api & ApiVersion,
+                        httpMethod,
+                        $body,
+                        newHttpHeaders {
+                          "Accept": "application/json",
+                          "Authorization": "Basic " & encode(':' & getAzureEnv("System.AccessToken")),
+                          "Content-Type": "application/json"
+                        })
+  if not result.code.is2xx:
+    raise newException(HttpRequestError, "Server returned: " & result.body)
+
+proc finish*() {.noconv.} =
+  if not isAzure or runId < 0:
+    return
+
+  try:
+    discard invokeRest(HttpPatch,
+                       ApiRuns & "/" & $runId,
+                       $ %* { "state": "Completed" })
+  except:
+    stderr.writeLine "##vso[task.logissue type=warning;]Unable to finalize Azure backend"
+    stderr.writeLine getCurrentExceptionMsg()
+
+  runId = -1
+
+# TODO: Only obtain a run id if tests are run
+# NOTE: We can't delete test runs with Azure's access token
+proc start*() =
+  if not isAzure:
+    return
+  try:
+    if runId < 0:
+      runId = invokeRest(HttpPost,
+                         ApiRuns,
+                         $ %* {
+                           "automated": true,
+                           "build": { "id": getAzureEnv("Build.BuildId") },
+                           "buildPlatform": hostCPU,
+                           "controller": "nim-testament",
+                           "name": getAzureEnv("Agent.JobName")
+                         }).body.parseJson["id"].getInt(-1)
+  except:
+    stderr.writeLine "##vso[task.logissue type=warning;]Unable to initialize Azure backend"
+    stderr.writeLine getCurrentExceptionMsg()
+
+proc addTestResult*(name, category: string; durationInMs: int; errorMsg: string;
+                    outcome: TResultEnum) =
+  if not isAzure or runId < 0:
+    return
+  let outcome = case outcome
+                of reSuccess: "Passed"
+                of reDisabled, reJoined: "NotExecuted"
+                else: "Failed"
+  try:
+    discard invokeRest(HttpPost,
+                       ApiResults % [$runId],
+                       $ %* [{
+                         "automatedTestName": name,
+                         "automatedTestStorage": category,
+                         "durationInMs": durationInMs,
+                         "errorMessage": errorMsg,
+                         "outcome": outcome,
+                         "testCaseTitle": name
+                       }])
+  except:
+    stderr.writeLine "##vso[task.logissue type=warning;]Unable to log test case: ",
+                     name, ", outcome: ", outcome
+    stderr.writeLine getCurrentExceptionMsg()