Merge branch 'main' of ssh://github.com/OliveTin/OliveTin

This commit is contained in:
jamesread 2024-08-06 16:35:10 +01:00
commit e183910b88
9 changed files with 82 additions and 30 deletions

View File

@ -5,7 +5,7 @@ endef
compile: daemon-compile-currentenv compile: daemon-compile-currentenv
daemon-compile-currentenv: daemon-compile-currentenv:
go build -o OliveTin github.com/OliveTin/OliveTin/cmd/OliveTin go build github.com/OliveTin/OliveTin/cmd/OliveTin
daemon-compile-armhf: daemon-compile-armhf:
go env -w GOARCH=arm GOARM=6 go env -w GOARCH=arm GOARM=6
@ -31,7 +31,8 @@ daemon-codestyle:
gocritic check ./... gocritic check ./...
daemon-unittests: daemon-unittests:
mkdir -p reports $(call delete-files,reports)
mkdir reports
go test ./... -coverprofile reports/unittests.out go test ./... -coverprofile reports/unittests.out
go tool cover -html=reports/unittests.out -o reports/unittests.html go tool cover -html=reports/unittests.out -o reports/unittests.html

View File

@ -4,7 +4,7 @@ test-install:
npm install --no-fund npm install --no-fund
test-run: test-run:
./node_modules/.bin/mocha -t 10000 npx mocha -t 10000
find-flakey-tests: find-flakey-tests:
echo "Running test-run infinately" echo "Running test-run infinately"

View File

@ -24,12 +24,12 @@ actions:
shell: sleep 5 shell: sleep 5
icon: "&#x1F62A" icon: "&#x1F62A"
- title: date-popup - title: dir-popup
shell: date shell: dir
popupOnStart: execution-dialog-stdout-only popupOnStart: execution-dialog-stdout-only
- title: date-passive - title: cd-passive
shell: date shell: cd
- title: "Run Ansible Playbook" - title: "Run Ansible Playbook"
icon: "&#x1F1E6" icon: "&#x1F1E6"

View File

@ -0,0 +1,16 @@
#
# Integration Test Config: General
#
listenAddressSingleHTTPFrontend: 0.0.0.0:1337
logLevel: "DEBUG"
checkForUpdates: false
prometheus:
enabled: true
defaultGoMetrics: false
actions:
- title: Hello OliveTin
shell: echo "Hello OliveTin"

View File

@ -25,6 +25,10 @@ class OliveTinTestRunner {
baseUrl() { baseUrl() {
return this.BASE_URL return this.BASE_URL
} }
metricsUrl() {
return new URL('metrics', this.baseUrl());
}
} }
class OliveTinTestRunnerStartLocalProcess extends OliveTinTestRunner { class OliveTinTestRunnerStartLocalProcess extends OliveTinTestRunner {

View File

@ -44,42 +44,42 @@ describe('config: general', function () {
expect(buttons).to.have.length(8) expect(buttons).to.have.length(8)
}) })
it('Start date action (popup)', async function() { it('Start dir action (popup)', async function () {
await getRootAndWait() await getRootAndWait()
const buttons = await webdriver.findElements(By.css('[title="date-popup"]')) const buttons = await webdriver.findElements(By.css('[title="dir-popup"]'))
expect(buttons).to.have.length(1) expect(buttons).to.have.length(1)
const buttonDate = buttons[0] const buttonCMD = buttons[0]
expect(buttonDate).to.not.be.null expect(buttonCMD).to.not.be.null
buttonDate.click() buttonCMD.click()
const dialog = await webdriver.findElement(By.id('execution-results-popup')) const dialog = await webdriver.findElement(By.id('execution-results-popup'))
expect(await dialog.isDisplayed()).to.be.true expect(await dialog.isDisplayed()).to.be.true
const title = await webdriver.findElement(By.id('execution-dialog-title')) const title = await webdriver.findElement(By.id('execution-dialog-title'))
expect(await title.getAttribute('innerText')).to.be.equal('date-popup') expect(await webdriver.wait(until.elementTextIs(title, 'dir-popup'), 2000))
const dialogErr = await webdriver.findElement(By.id('big-error')) const dialogErr = await webdriver.findElement(By.id('big-error'))
expect(dialogErr).to.not.be.null expect(dialogErr).to.not.be.null
expect(await dialogErr.isDisplayed()).to.be.false expect(await dialogErr.isDisplayed()).to.be.false
}) })
it('Start date action (passive)', async function() { it('Start cd action (passive)', async function () {
await getRootAndWait() await getRootAndWait()
const buttons = await webdriver.findElements(By.css('[title="date-passive"]')) const buttons = await webdriver.findElements(By.css('[title="cd-passive"]'))
expect(buttons).to.have.length(1) expect(buttons).to.have.length(1)
const buttonDate = buttons[0] const buttonCMD = buttons[0]
expect(buttonDate).to.not.be.null expect(buttonCMD).to.not.be.null
buttonDate.click() buttonCMD.click()
const dialog = await webdriver.findElement(By.id('execution-results-popup')) const dialog = await webdriver.findElement(By.id('execution-results-popup'))
expect(await dialog.isDisplayed()).to.be.false expect(await dialog.isDisplayed()).to.be.false

View File

@ -0,0 +1,33 @@
import { describe, it, before, after } from 'mocha'
import { expect } from 'chai'
import { By } from 'selenium-webdriver'
let metrics = [
{'name': 'olivetin_actions_requested_count', 'type': 'counter', 'desc': 'The actions requested count'},
{'name': 'olivetin_config_action_count', 'type': 'gauge', 'desc': 'The number of actions in the config file'},
{'name': 'olivetin_config_reloaded_count', 'type': 'counter', 'desc': 'The number of times the config has been reloaded'},
{'name': 'olivetin_sv_count', 'type': 'gauge', 'desc': 'The number entries in the sv map'},
]
describe('config: prometheus', function () {
before(async function () {
await runner.start('prometheus')
})
after(async () => {
await runner.stop()
})
it('Metrics are available with correct types', async () => {
webdriver.get(runner.metricsUrl())
const prometheusOutput = await webdriver.findElement(By.tagName('pre')).getText()
expect(prometheusOutput).to.not.be.null
metrics.forEach(({name, type, desc}) => {
const metaLines = `# HELP ${name} ${desc}\n`
+ `# TYPE ${name} ${type}\n`
expect(prometheusOutput).to.match(new RegExp(metaLines))
})
})
})

View File

@ -4,9 +4,10 @@ import (
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/client_golang/prometheus/promauto"
log "github.com/sirupsen/logrus"
"os" "os"
"path" "path/filepath"
log "github.com/sirupsen/logrus"
"github.com/spf13/viper" "github.com/spf13/viper"
) )
@ -14,7 +15,7 @@ import (
var ( var (
metricConfigActionCount = promauto.NewGauge(prometheus.GaugeOpts{ metricConfigActionCount = promauto.NewGauge(prometheus.GaugeOpts{
Name: "olivetin_config_action_count", Name: "olivetin_config_action_count",
Help: "Then number of actions in the config file", Help: "The number of actions in the config file",
}) })
metricConfigReloadedCount = promauto.NewCounter(prometheus.CounterOpts{ metricConfigReloadedCount = promauto.NewCounter(prometheus.CounterOpts{
@ -38,7 +39,7 @@ func Reload(cfg *Config) {
metricConfigReloadedCount.Inc() metricConfigReloadedCount.Inc()
metricConfigActionCount.Set(float64(len(cfg.Actions))) metricConfigActionCount.Set(float64(len(cfg.Actions)))
cfg.SetDir(path.Dir(viper.ConfigFileUsed())) cfg.SetDir(filepath.Dir(viper.ConfigFileUsed()))
cfg.Sanitize() cfg.Sanitize()
for _, l := range listeners { for _, l := range listeners {

View File

@ -22,7 +22,7 @@ import (
) )
var ( var (
metricActionsRequested = promauto.NewGauge(prometheus.GaugeOpts{ metricActionsRequested = promauto.NewCounter(prometheus.CounterOpts{
Name: "olivetin_actions_requested_count", Name: "olivetin_actions_requested_count",
Help: "The actions requested count", Help: "The actions requested count",
}) })
@ -135,11 +135,6 @@ func (e *Executor) AddListener(m listener) {
// ExecRequest processes an ExecutionRequest // ExecRequest processes an ExecutionRequest
func (e *Executor) ExecRequest(req *ExecutionRequest) (*sync.WaitGroup, string) { func (e *Executor) ExecRequest(req *ExecutionRequest) (*sync.WaitGroup, string) {
req.executor = e req.executor = e
// req.UUID is now set by the client, so that they can track the request
// from start to finish. This means that a malicious client could send
// duplicate UUIDs (or just random strings), but this is the only way.
req.logEntry = &InternalLogEntry{ req.logEntry = &InternalLogEntry{
DatetimeStarted: time.Now(), DatetimeStarted: time.Now(),
ExecutionTrackingID: req.TrackingID, ExecutionTrackingID: req.TrackingID,
@ -152,12 +147,14 @@ func (e *Executor) ExecRequest(req *ExecutionRequest) (*sync.WaitGroup, string)
ActionIcon: "💩", ActionIcon: "💩",
} }
_, foundLog := e.Logs[req.TrackingID] _, isDuplicate := e.Logs[req.TrackingID]
if foundLog || req.TrackingID == "" { if isDuplicate || req.TrackingID == "" {
req.TrackingID = uuid.NewString() req.TrackingID = uuid.NewString()
} }
log.Tracef("executor.ExecRequest(): %v", req)
e.Logs[req.TrackingID] = req.logEntry e.Logs[req.TrackingID] = req.logEntry
wg := new(sync.WaitGroup) wg := new(sync.WaitGroup)