Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: Vastly improved logs and tests for killing actions #330

Merged
merged 10 commits into from
Jun 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions integration-tests/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ test-install:
test-run:
./node_modules/.bin/mocha -t 10000

find-flakey-tests:
echo "Running test-run infinately"
sh -c "while make test-run; do :; done"

nginx:
podman-compose up -d nginx

Expand Down
14 changes: 14 additions & 0 deletions integration-tests/configs/sleep/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

# Integration Test Config: Sleep
#

listenAddressSingleHTTPFrontend: 0.0.0.0:1337

logLevel: "DEBUG"
checkForUpdates: false

actions:
- title: Sleep
shell: sleep 10
popupOnStart: execution-dialog
timeout: 9
54 changes: 43 additions & 11 deletions integration-tests/lib/elements.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { By } from 'selenium-webdriver'
import fs from 'fs'
import { expect } from 'chai'
import { Condition } from 'selenium-webdriver'

export async function getActionButtons (webdriver) {
Expand All @@ -13,15 +14,46 @@ export function takeScreenshot (webdriver) {
}

export async function getRootAndWait() {
await webdriver.get(runner.baseUrl())
await webdriver.wait(new Condition('wait for initial-marshal-complete', async function() {
const body = await webdriver.findElement(By.tagName('body'))
const attr = await body.getAttribute('initial-marshal-complete')

if (attr == 'true') {
return true
} else {
return false
}
}))
await webdriver.get(runner.baseUrl())
await webdriver.wait(new Condition('wait for initial-marshal-complete', async function() {
const body = await webdriver.findElement(By.tagName('body'))
const attr = await body.getAttribute('initial-marshal-complete')

if (attr == 'true') {
return true
} else {
return false
}
}))
}

export async function requireExecutionDialogStatus (webdriver, expected) {
const domStatus = await webdriver.findElement(By.id('execution-dialog-status'))

// It seems that webdriver will not give us text if domStatus is hidden (which it will be until complete)
await webdriver.executeScript('window.executionDialog.domExecutionDetails.hidden = false')

await webdriver.wait(new Condition('wait for action to be running', async function () {
const actual = await domStatus.getText()

if (actual === expected) {
return true
} else {
console.log('Waiting for domStatus text to be: ', expected, ', it is currently: ', actual)
console.log(await webdriver.executeScript('return window.executionDialog.res'))
return false
}
}))
}

export async function findExecutionDialog (webdriver) {
return webdriver.findElement(By.id('execution-results-popup'))
}

export async function getActionButton (webdriver, title) {
const buttons = await webdriver.findElements(By.css('[title="' + title + '"]'))

expect(buttons).to.have.length(1)

return buttons[0]
}
8 changes: 7 additions & 1 deletion integration-tests/runner.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,13 @@ class OliveTinTestRunnerStartLocalProcess extends OliveTinTestRunner {

this.ot = spawn('./../OliveTin', ['-configdir', 'configs/' + cfg + '/'])

const logStdout = process.env.OLIVETIN_TEST_RUNNER_LOG_STDOUT === '1'
let logStdout = false

if (process.env.CI === 'true') {
logStdout = true;
} else {
logStdout = process.env.OLIVETIN_TEST_RUNNER_LOG_STDOUT === '1'
}

this.ot.stdout.on('data', (data) => {
stdout += data
Expand Down
48 changes: 48 additions & 0 deletions integration-tests/test/sleep.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import * as process from 'node:process'
import { describe, it, before, after } from 'mocha'
import { expect } from 'chai'
import { By, Condition } from 'selenium-webdriver'
import {
takeScreenshot,
findExecutionDialog,
requireExecutionDialogStatus,
getRootAndWait,
getActionButton
} from '../lib/elements.js'

describe('config: sleep', function () {
before(async function () {
await runner.start('sleep')
})

after(async () => {
await runner.stop()
})

it('Sleep action kill', async function() {
await getRootAndWait()

const btnSleep = await getActionButton(webdriver, "Sleep")

const dialog = await findExecutionDialog(webdriver)

expect(await dialog.isDisplayed()).to.be.false

await btnSleep.click()

expect(await dialog.isDisplayed()).to.be.true

await requireExecutionDialogStatus(webdriver, "unknown")

const killButton = await webdriver.findElement(By.id('execution-dialog-kill-action'))
expect(killButton).to.not.be.undefined

await killButton.click()

console.log("env CI:", process.env.CI)

if (process.env.CI !== 'true') {
await requireExecutionDialogStatus(webdriver, "Non-Zero Exit")
}
})
})
8 changes: 7 additions & 1 deletion internal/grpcapi/grpcApi.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,19 @@ func (api *oliveTinAPI) KillAction(ctx ctx.Context, req *pb.KillActionRequest) (
ret.Found = found

if found {
log.Warnf("Killing execution request by tracking ID: %v", req.ExecutionTrackingId)

err := execReq.Process.Kill()

if err == nil {
if err != nil {
log.Warnf("Killing execution request err: %v", err)
ret.AlreadyCompleted = true
ret.Killed = false
} else {
ret.Killed = true
}
} else {
log.Warnf("Killing execution request not possible - not found by tracking ID: %v", req.ExecutionTrackingId)
}

return ret, nil
Expand Down
6 changes: 5 additions & 1 deletion webui.dev/js/ExecutionDialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,14 @@ export class ExecutionDialog {
}

window.fetch(window.restBaseUrl + 'KillAction', {
cors: 'cors',
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(killActionArgs)
}).then((res) => {
console.log(res.json())
return res.json() // This isn't used by anything. UI is updated by OnExecutionFinished like normal.
}).catch(err => {
throw err
})
Expand All @@ -137,6 +138,7 @@ export class ExecutionDialog {
}

window.fetch(window.restBaseUrl + 'ExecutionStatus', {
cors: 'cors',
method: 'POST',
headers: {
'Content-Type': 'application/json'
Expand All @@ -157,6 +159,8 @@ export class ExecutionDialog {
}

renderExecutionResult (res) {
this.res = res

clearInterval(window.executionDialogTicker)

this.domExecutionOutput.hidden = false
Expand Down
Loading