Introducing the concept of flagging an automation as 'in test' which means it can run with triggers and everything as it normally would in development.
This commit is contained in:
parent
84cdec5907
commit
3eeb7c27b8
|
@ -13,6 +13,7 @@ exports.Databases = {
|
|||
DEBOUNCE: "debounce",
|
||||
SESSIONS: "session",
|
||||
USER_CACHE: "users",
|
||||
FLAGS: "flags",
|
||||
}
|
||||
|
||||
exports.SEPARATOR = SEPARATOR
|
||||
|
|
|
@ -7,6 +7,7 @@ const {
|
|||
checkForWebhooks,
|
||||
updateTestHistory,
|
||||
} = require("../../automations/utils")
|
||||
const { setTestFlag, clearTestFlag } = require("../../utilities/redis")
|
||||
|
||||
/*************************
|
||||
* *
|
||||
|
@ -163,6 +164,7 @@ exports.test = async function (ctx) {
|
|||
const appId = ctx.appId
|
||||
const db = new CouchDB(appId)
|
||||
let automation = await db.get(ctx.params.id)
|
||||
await setTestFlag(automation._id)
|
||||
const response = await triggers.externalTrigger(
|
||||
automation,
|
||||
{
|
||||
|
@ -176,5 +178,6 @@ exports.test = async function (ctx) {
|
|||
...ctx.request.body,
|
||||
occurredAt: new Date().toISOString(),
|
||||
})
|
||||
await clearTestFlag(automation._id)
|
||||
ctx.body = response
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ const {
|
|||
checkBuilderEndpoint,
|
||||
getAllTableRows,
|
||||
clearAllAutomations,
|
||||
triggerAutomation,
|
||||
testAutomation,
|
||||
} = require("./utilities/TestFunctions")
|
||||
const setup = require("./utilities")
|
||||
const { basicAutomation } = setup.structures
|
||||
|
@ -160,14 +160,13 @@ describe("/automations", () => {
|
|||
automation.definition.steps[0].inputs.row.tableId = table._id
|
||||
automation = await config.createAutomation(automation)
|
||||
await setup.delay(500)
|
||||
const res = await triggerAutomation(config, automation)
|
||||
const res = await testAutomation(config, automation)
|
||||
// this looks a bit mad but we don't actually have a way to wait for a response from the automation to
|
||||
// know that it has finished all of its actions - this is currently the best way
|
||||
// also when this runs in CI it is very temper-mental so for now trying to make run stable by repeating until it works
|
||||
// TODO: update when workflow logs are a thing
|
||||
for (let tries = 0; tries < MAX_RETRIES; tries++) {
|
||||
expect(res.body.message).toEqual(`Automation ${automation._id} has been triggered.`)
|
||||
expect(res.body.automation.name).toEqual(automation.name)
|
||||
expect(res.body).toBeDefined()
|
||||
await setup.delay(500)
|
||||
let elements = await getAllTableRows(config)
|
||||
// don't test it unless there are values to test
|
||||
|
|
|
@ -102,19 +102,15 @@ exports.getDB = config => {
|
|||
return new CouchDB(config.getAppId())
|
||||
}
|
||||
|
||||
exports.triggerAutomation = async (config, automation) => {
|
||||
return await config.request
|
||||
.post(`/api/automations/${automation._id}/trigger`)
|
||||
.send({ name: "Test", description: "TEST" })
|
||||
.set(config.defaultHeaders())
|
||||
.expect("Content-Type", /json/)
|
||||
.expect(200)
|
||||
}
|
||||
|
||||
exports.testAutomation = async (config, automation) => {
|
||||
return await config.request
|
||||
.post(`/api/automations/${automation._id}/test`)
|
||||
.send({ name: "Test", description: "TEST" })
|
||||
.send({
|
||||
row: {
|
||||
name: "Test",
|
||||
description: "TEST",
|
||||
},
|
||||
})
|
||||
.set(config.defaultHeaders())
|
||||
.expect("Content-Type", /json/)
|
||||
.expect(200)
|
||||
|
|
|
@ -7,6 +7,7 @@ const { isDevAppID } = require("../db/utils")
|
|||
// need this to call directly, so we can get a response
|
||||
const { processEvent } = require("./utils")
|
||||
const { queue } = require("./bullboard")
|
||||
const { checkTestFlag } = require("../utilities/redis")
|
||||
|
||||
const TRIGGER_DEFINITIONS = definitions
|
||||
|
||||
|
@ -14,11 +15,7 @@ async function queueRelevantRowAutomations(event, eventType) {
|
|||
if (event.appId == null) {
|
||||
throw `No appId specified for ${eventType} - check event emitters.`
|
||||
}
|
||||
// don't queue events which are for dev apps, only way to test automations is
|
||||
// running tests on them
|
||||
if (isDevAppID(event.appId)) {
|
||||
return
|
||||
}
|
||||
|
||||
const db = new CouchDB(event.appId)
|
||||
let automations = await db.allDocs(
|
||||
getAutomationParams(null, { include_docs: true })
|
||||
|
@ -33,6 +30,12 @@ async function queueRelevantRowAutomations(event, eventType) {
|
|||
})
|
||||
|
||||
for (let automation of automations) {
|
||||
// don't queue events which are for dev apps, only way to test automations is
|
||||
// running tests on them
|
||||
// in production the test flag will never be checked due to lazy evaluation (first always false)
|
||||
if (isDevAppID(event.appId) && !(await checkTestFlag(automation._id))) {
|
||||
return
|
||||
}
|
||||
let automationDef = automation.definition
|
||||
let automationTrigger = automationDef ? automationDef.trigger : {}
|
||||
if (
|
||||
|
|
|
@ -2,20 +2,24 @@ const { Client, utils } = require("@budibase/auth/redis")
|
|||
const { getGlobalIDFromUserMetadataID } = require("../db/utils")
|
||||
|
||||
const APP_DEV_LOCK_SECONDS = 600
|
||||
let devAppClient, debounceClient
|
||||
const AUTOMATION_TEST_FLAG_SECONDS = 60
|
||||
let devAppClient, debounceClient, flagClient
|
||||
|
||||
// we init this as we want to keep the connection open all the time
|
||||
// reduces the performance hit
|
||||
exports.init = async () => {
|
||||
devAppClient = new Client(utils.Databases.DEV_LOCKS)
|
||||
debounceClient = new Client(utils.Databases.DEBOUNCE)
|
||||
flagClient = new Client(utils.Databases.FLAGS)
|
||||
await devAppClient.init()
|
||||
await debounceClient.init()
|
||||
await flagClient.init()
|
||||
}
|
||||
|
||||
exports.shutdown = async () => {
|
||||
if (devAppClient) await devAppClient.finish()
|
||||
if (debounceClient) await debounceClient.finish()
|
||||
if (flagClient) await flagClient.finish()
|
||||
}
|
||||
|
||||
exports.doesUserHaveLock = async (devAppId, user) => {
|
||||
|
@ -67,3 +71,16 @@ exports.checkDebounce = async id => {
|
|||
exports.setDebounce = async (id, seconds) => {
|
||||
await debounceClient.store(id, "debouncing", seconds)
|
||||
}
|
||||
|
||||
exports.setTestFlag = async id => {
|
||||
await flagClient.store(id, { testing: true }, AUTOMATION_TEST_FLAG_SECONDS)
|
||||
}
|
||||
|
||||
exports.checkTestFlag = async id => {
|
||||
const flag = await flagClient.get(id)
|
||||
return !!(flag && flag.testing)
|
||||
}
|
||||
|
||||
exports.clearTestFlag = async id => {
|
||||
await devAppClient.delete(id)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue