@platformatic/watt-extra 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +87 -0
- package/app.js +124 -0
- package/cli.js +141 -0
- package/clients/compliance/compliance-types.d.ts +887 -0
- package/clients/compliance/compliance.mjs +1049 -0
- package/clients/compliance/compliance.openapi.json +6127 -0
- package/clients/control-plane/control-plane-types.d.ts +2696 -0
- package/clients/control-plane/control-plane.mjs +3051 -0
- package/clients/control-plane/control-plane.openapi.json +13693 -0
- package/clients/cron/cron-types.d.ts +1479 -0
- package/clients/cron/cron.mjs +872 -0
- package/clients/cron/cron.openapi.json +9330 -0
- package/compliance/index.js +21 -0
- package/compliance/rules/dependencies.js +76 -0
- package/compliance/rules/utils.js +12 -0
- package/eslint.config.js +11 -0
- package/help/start.txt +12 -0
- package/help/watt-extra.txt +12 -0
- package/index.js +45 -0
- package/lib/banner.js +22 -0
- package/lib/errors.js +34 -0
- package/lib/utils.js +34 -0
- package/lib/wattpro.js +580 -0
- package/package.json +50 -0
- package/plugins/alerts.js +115 -0
- package/plugins/auth.js +89 -0
- package/plugins/compliancy.js +70 -0
- package/plugins/env.js +58 -0
- package/plugins/flamegraphs.js +100 -0
- package/plugins/init.js +70 -0
- package/plugins/metadata.js +84 -0
- package/plugins/scheduler.js +48 -0
- package/plugins/update.js +128 -0
- package/renovate.json +6 -0
- package/test/alerts.test.js +607 -0
- package/test/auth.test.js +128 -0
- package/test/auto-cache.test.js +401 -0
- package/test/cli.test.js +75 -0
- package/test/compliancy.test.js +87 -0
- package/test/fixtures/runtime-domains/alpha/package.json +5 -0
- package/test/fixtures/runtime-domains/alpha/platformatic.json +6 -0
- package/test/fixtures/runtime-domains/alpha/plugin.js +16 -0
- package/test/fixtures/runtime-domains/beta/package.json +5 -0
- package/test/fixtures/runtime-domains/beta/platformatic.json +6 -0
- package/test/fixtures/runtime-domains/beta/plugin.js +7 -0
- package/test/fixtures/runtime-domains/composer/package.json +5 -0
- package/test/fixtures/runtime-domains/composer/platformatic.json +19 -0
- package/test/fixtures/runtime-domains/package.json +1 -0
- package/test/fixtures/runtime-domains/platformatic.json +27 -0
- package/test/fixtures/runtime-health/package.json +20 -0
- package/test/fixtures/runtime-health/platformatic.json +16 -0
- package/test/fixtures/runtime-health/services/service-1/package.json +17 -0
- package/test/fixtures/runtime-health/services/service-1/platformatic.json +16 -0
- package/test/fixtures/runtime-health/services/service-1/plugins/example.js +6 -0
- package/test/fixtures/runtime-health/services/service-1/routes/root.cjs +8 -0
- package/test/fixtures/runtime-health/services/service-2/package.json +17 -0
- package/test/fixtures/runtime-health/services/service-2/platformatic.json +16 -0
- package/test/fixtures/runtime-health/services/service-2/plugins/example.js +6 -0
- package/test/fixtures/runtime-health/services/service-2/routes/root.cjs +8 -0
- package/test/fixtures/runtime-next/package.json +5 -0
- package/test/fixtures/runtime-next/platformatic.json +9 -0
- package/test/fixtures/runtime-next/web/next/next.config.js +2 -0
- package/test/fixtures/runtime-next/web/next/package.json +7 -0
- package/test/fixtures/runtime-next/web/next/platformatic.json +9 -0
- package/test/fixtures/runtime-next/web/next/src/app/direct/route.js +3 -0
- package/test/fixtures/runtime-next/web/next/src/app/layout.jsx +7 -0
- package/test/fixtures/runtime-next/web/next/src/app/page.jsx +3 -0
- package/test/fixtures/runtime-scheduler/main/package.json +5 -0
- package/test/fixtures/runtime-scheduler/main/platformatic.json +9 -0
- package/test/fixtures/runtime-scheduler/main/routes/root.cjs +11 -0
- package/test/fixtures/runtime-scheduler/package.json +1 -0
- package/test/fixtures/runtime-scheduler/platformatic.json +27 -0
- package/test/fixtures/runtime-service/main/package.json +5 -0
- package/test/fixtures/runtime-service/main/platformatic.json +12 -0
- package/test/fixtures/runtime-service/main/routes/root.cjs +11 -0
- package/test/fixtures/runtime-service/package.json +1 -0
- package/test/fixtures/runtime-service/platformatic.json +19 -0
- package/test/fixtures/service-1/package.json +7 -0
- package/test/fixtures/service-1/platformatic.json +18 -0
- package/test/fixtures/service-1/routes/root.cjs +48 -0
- package/test/fixtures/service-2/platformatic.json +21 -0
- package/test/fixtures/service-2/routes/root.cjs +5 -0
- package/test/fixtures/service-3/package.json +5 -0
- package/test/fixtures/service-3/platformatic.json +21 -0
- package/test/fixtures/service-3/routes/root.cjs +8 -0
- package/test/health.test.js +44 -0
- package/test/helper.js +274 -0
- package/test/init.test.js +243 -0
- package/test/patch-config.test.js +434 -0
- package/test/scheduler.test.js +71 -0
- package/test/send-to-icc-retry.test.js +138 -0
- package/test/shared-context.test.js +82 -0
- package/test/spawn.test.js +110 -0
- package/test/trigger-flamegraphs.test.js +226 -0
- package/test/update.test.js +519 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import assert from 'node:assert'
|
|
2
|
+
import { test } from 'node:test'
|
|
3
|
+
import { join, dirname } from 'node:path'
|
|
4
|
+
import { fileURLToPath } from 'node:url'
|
|
5
|
+
|
|
6
|
+
import { randomUUID } from 'node:crypto'
|
|
7
|
+
import { setTimeout as sleep } from 'node:timers/promises'
|
|
8
|
+
import { request } from 'undici'
|
|
9
|
+
import {
|
|
10
|
+
startICC,
|
|
11
|
+
installDeps,
|
|
12
|
+
setUpEnvironment,
|
|
13
|
+
createJwtToken
|
|
14
|
+
} from './helper.js'
|
|
15
|
+
import { start } from '../index.js'
|
|
16
|
+
|
|
17
|
+
const __filename = fileURLToPath(import.meta.url)
|
|
18
|
+
const __dirname = dirname(__filename)
|
|
19
|
+
|
|
20
|
+
test('should propagete a jwt token via runtime shared context', async (t) => {
|
|
21
|
+
const applicationName = 'test-app'
|
|
22
|
+
const applicationId = randomUUID()
|
|
23
|
+
const applicationPath = join(__dirname, 'fixtures', 'runtime-domains')
|
|
24
|
+
|
|
25
|
+
await installDeps(t, applicationPath, ['@platformatic/composer'])
|
|
26
|
+
|
|
27
|
+
const expiresIn = 10
|
|
28
|
+
const jwt = createJwtToken(expiresIn)
|
|
29
|
+
|
|
30
|
+
setUpEnvironment({
|
|
31
|
+
PLT_APP_NAME: applicationName,
|
|
32
|
+
PLT_APP_DIR: applicationPath,
|
|
33
|
+
PLT_ICC_URL: 'http://127.0.0.1:3000',
|
|
34
|
+
PLT_TEST_TOKEN: jwt,
|
|
35
|
+
PLT_JWT_EXPIRATION_OFFSET_SEC: 1
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
const icc = await startICC(t, {
|
|
39
|
+
applicationId,
|
|
40
|
+
applicationName
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
const app = await start()
|
|
44
|
+
|
|
45
|
+
let newToken = null
|
|
46
|
+
setTimeout(() => {
|
|
47
|
+
newToken = createJwtToken(expiresIn)
|
|
48
|
+
process.env.PLT_TEST_TOKEN = newToken
|
|
49
|
+
}, expiresIn * 1000)
|
|
50
|
+
|
|
51
|
+
t.after(async () => {
|
|
52
|
+
await app.close()
|
|
53
|
+
await icc.close()
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
{
|
|
57
|
+
const { statusCode, body } = await request('http://127.0.0.1:3042/1/shared-context')
|
|
58
|
+
assert.strictEqual(statusCode, 200)
|
|
59
|
+
|
|
60
|
+
const sharedContext = await body.json()
|
|
61
|
+
|
|
62
|
+
const { iccAuthHeaders } = sharedContext
|
|
63
|
+
const { authorization } = iccAuthHeaders
|
|
64
|
+
assert.strictEqual(authorization, `Bearer ${jwt}`)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Wait for the token to expire
|
|
68
|
+
await sleep(expiresIn * 1000 + 1000)
|
|
69
|
+
|
|
70
|
+
{
|
|
71
|
+
const { statusCode, body } = await request('http://127.0.0.1:3042/1/shared-context')
|
|
72
|
+
assert.strictEqual(statusCode, 200)
|
|
73
|
+
|
|
74
|
+
const sharedContext = await body.json()
|
|
75
|
+
|
|
76
|
+
const { iccAuthHeaders } = sharedContext
|
|
77
|
+
const { authorization } = iccAuthHeaders
|
|
78
|
+
assert.strictEqual(authorization, `Bearer ${newToken}`)
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
assert.notStrictEqual(jwt, newToken)
|
|
82
|
+
})
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import assert from 'node:assert'
|
|
2
|
+
import { test } from 'node:test'
|
|
3
|
+
import { hostname } from 'node:os'
|
|
4
|
+
import { randomUUID } from 'node:crypto'
|
|
5
|
+
import { request } from 'undici'
|
|
6
|
+
import { join, dirname } from 'node:path'
|
|
7
|
+
import { fileURLToPath } from 'node:url'
|
|
8
|
+
import { createRequire } from 'node:module'
|
|
9
|
+
import { setTimeout as sleep } from 'node:timers/promises'
|
|
10
|
+
import { setUpEnvironment, startICC } from './helper.js'
|
|
11
|
+
import { start } from '../index.js'
|
|
12
|
+
|
|
13
|
+
const __filename = fileURLToPath(import.meta.url)
|
|
14
|
+
const __dirname = dirname(__filename)
|
|
15
|
+
|
|
16
|
+
const require = createRequire(import.meta.url)
|
|
17
|
+
const platformaticVersion = require('@platformatic/runtime/package.json').version
|
|
18
|
+
|
|
19
|
+
test('should spawn a service app sending the state', async (t) => {
|
|
20
|
+
const applicationName = 'test-app'
|
|
21
|
+
const applicationId = randomUUID()
|
|
22
|
+
const applicationPath = join(__dirname, 'fixtures', 'service-1')
|
|
23
|
+
|
|
24
|
+
const applicationStates = []
|
|
25
|
+
|
|
26
|
+
const icc = await startICC(t, {
|
|
27
|
+
applicationId,
|
|
28
|
+
applicationName,
|
|
29
|
+
saveApplicationInstanceState: (state) => {
|
|
30
|
+
applicationStates.push(state)
|
|
31
|
+
},
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
process.env.PLT_TEST_APP_1_URL = 'http://test-app-1:3042'
|
|
35
|
+
t.after(() => {
|
|
36
|
+
delete process.env.PLT_TEST_APP_1_URL
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
setUpEnvironment({
|
|
40
|
+
PLT_APP_NAME: applicationName,
|
|
41
|
+
PLT_APP_DIR: applicationPath,
|
|
42
|
+
PLT_ICC_URL: 'http://127.0.0.1:3000',
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
const app = await start()
|
|
46
|
+
|
|
47
|
+
t.after(async () => {
|
|
48
|
+
await app.close()
|
|
49
|
+
await icc.close()
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
{
|
|
53
|
+
const { statusCode, body } = await request('http://127.0.0.1:3042/example')
|
|
54
|
+
assert.strictEqual(statusCode, 200)
|
|
55
|
+
|
|
56
|
+
const data = await body.json()
|
|
57
|
+
assert.deepStrictEqual(data, { hello: 'world' })
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
assert.strictEqual(applicationStates.length, 1)
|
|
61
|
+
const [state] = applicationStates
|
|
62
|
+
assert.strictEqual(state.instanceId, hostname())
|
|
63
|
+
assert.deepStrictEqual(state.state.applications.length, 1)
|
|
64
|
+
assert.strictEqual(
|
|
65
|
+
state.state.metadata.platformaticVersion,
|
|
66
|
+
platformaticVersion
|
|
67
|
+
)
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
test('should not fail on worker error', async (t) => {
|
|
71
|
+
const applicationName = 'test-app'
|
|
72
|
+
const applicationId = randomUUID()
|
|
73
|
+
const applicationPath = join(__dirname, 'fixtures', 'service-3')
|
|
74
|
+
|
|
75
|
+
const icc = await startICC(t, {
|
|
76
|
+
applicationId,
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
setUpEnvironment({
|
|
80
|
+
PLT_APP_NAME: applicationName,
|
|
81
|
+
PLT_APP_DIR: applicationPath,
|
|
82
|
+
PLT_ICC_URL: 'http://127.0.0.1:3000',
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
const app = await start()
|
|
86
|
+
|
|
87
|
+
t.after(async () => {
|
|
88
|
+
await app.close()
|
|
89
|
+
await icc.close()
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
{
|
|
93
|
+
const { statusCode, body } = await request('http://127.0.0.1:3042/example')
|
|
94
|
+
assert.strictEqual(statusCode, 200)
|
|
95
|
+
|
|
96
|
+
const data = await body.json()
|
|
97
|
+
assert.deepStrictEqual(data, { hello: 'world' })
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Await for runtime to crash and restart
|
|
101
|
+
await sleep(4000)
|
|
102
|
+
|
|
103
|
+
{
|
|
104
|
+
const { statusCode, body } = await request('http://127.0.0.1:3042/example')
|
|
105
|
+
assert.strictEqual(statusCode, 200)
|
|
106
|
+
|
|
107
|
+
const data = await body.json()
|
|
108
|
+
assert.deepStrictEqual(data, { hello: 'world' })
|
|
109
|
+
}
|
|
110
|
+
})
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { test } from 'node:test'
|
|
2
|
+
import { equal } from 'node:assert'
|
|
3
|
+
import { once } from 'node:events'
|
|
4
|
+
import { setTimeout as sleep } from 'node:timers/promises'
|
|
5
|
+
import { WebSocketServer } from 'ws'
|
|
6
|
+
import { setUpEnvironment } from './helper.js'
|
|
7
|
+
import updatePlugin from '../plugins/update.js'
|
|
8
|
+
import flamegraphsPlugin from '../plugins/flamegraphs.js'
|
|
9
|
+
|
|
10
|
+
function setupMockIccServer (wss, receivedMessages, validateAuth = false) {
|
|
11
|
+
let ws = null
|
|
12
|
+
|
|
13
|
+
const waitForClientSubscription = once(wss, 'connection').then(
|
|
14
|
+
([socket, req]) => {
|
|
15
|
+
ws = socket
|
|
16
|
+
|
|
17
|
+
if (validateAuth) {
|
|
18
|
+
equal(req.headers.authorization, 'Bearer test-token')
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return new Promise((resolve) => {
|
|
22
|
+
socket.on('message', (data) => {
|
|
23
|
+
const message = JSON.parse(data.toString())
|
|
24
|
+
receivedMessages.push(message)
|
|
25
|
+
|
|
26
|
+
if (message.command === 'subscribe' && message.topic === '/config') {
|
|
27
|
+
socket.send(JSON.stringify({ command: 'ack' }))
|
|
28
|
+
resolve()
|
|
29
|
+
}
|
|
30
|
+
})
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
return { waitForClientSubscription, getWs: () => ws }
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function createMockApp (port, includeScalerUrl = true) {
|
|
39
|
+
const mockWattPro = {
|
|
40
|
+
runtime: {
|
|
41
|
+
getApplications: () => ({
|
|
42
|
+
applications: [{ id: 'service-1' }, { id: 'service-2' }],
|
|
43
|
+
}),
|
|
44
|
+
},
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const app = {
|
|
48
|
+
log: {
|
|
49
|
+
info: () => {},
|
|
50
|
+
error: () => {},
|
|
51
|
+
warn: () => {},
|
|
52
|
+
debug: () => {},
|
|
53
|
+
},
|
|
54
|
+
instanceConfig: {
|
|
55
|
+
applicationId: 'test-application-id',
|
|
56
|
+
},
|
|
57
|
+
instanceId: 'test-pod-123',
|
|
58
|
+
getAuthorizationHeader: async () => {
|
|
59
|
+
return { Authorization: 'Bearer test-token' }
|
|
60
|
+
},
|
|
61
|
+
env: {
|
|
62
|
+
PLT_APP_NAME: 'test-app',
|
|
63
|
+
PLT_APP_DIR: '/path/to/app',
|
|
64
|
+
PLT_ICC_URL: `http://localhost:${port}`,
|
|
65
|
+
PLT_DISABLE_FLAMEGRAPHS: false,
|
|
66
|
+
PLT_FLAMEGRAPHS_INTERVAL_SEC: 1
|
|
67
|
+
},
|
|
68
|
+
wattpro: mockWattPro,
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (includeScalerUrl) {
|
|
72
|
+
app.instanceConfig.iccServices = {
|
|
73
|
+
scaler: {
|
|
74
|
+
url: `http://localhost:${port}/scaler`,
|
|
75
|
+
},
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return app
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const port = 14000
|
|
83
|
+
|
|
84
|
+
test('should handle trigger-flamegraph command and upload flamegraphs from services', async (t) => {
|
|
85
|
+
setUpEnvironment()
|
|
86
|
+
|
|
87
|
+
const receivedMessages = []
|
|
88
|
+
const getFlamegraphReqs = []
|
|
89
|
+
let uploadResolve
|
|
90
|
+
const allUploadsComplete = new Promise((resolve) => {
|
|
91
|
+
uploadResolve = resolve
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
const wss = new WebSocketServer({ port })
|
|
95
|
+
t.after(async () => wss.close())
|
|
96
|
+
|
|
97
|
+
const { waitForClientSubscription, getWs } = setupMockIccServer(
|
|
98
|
+
wss,
|
|
99
|
+
receivedMessages,
|
|
100
|
+
true
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
const app = createMockApp(port)
|
|
104
|
+
|
|
105
|
+
app.wattpro.runtime.sendCommandToApplication = async (
|
|
106
|
+
serviceId,
|
|
107
|
+
command
|
|
108
|
+
) => {
|
|
109
|
+
if (command === 'getLastProfile') {
|
|
110
|
+
getFlamegraphReqs.push({ serviceId })
|
|
111
|
+
if (getFlamegraphReqs.length === 2) {
|
|
112
|
+
uploadResolve()
|
|
113
|
+
}
|
|
114
|
+
return { success: true }
|
|
115
|
+
}
|
|
116
|
+
return { success: false }
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
await updatePlugin(app)
|
|
120
|
+
await flamegraphsPlugin(app)
|
|
121
|
+
|
|
122
|
+
await app.connectToUpdates()
|
|
123
|
+
await app.setupFlamegraphs()
|
|
124
|
+
|
|
125
|
+
await waitForClientSubscription
|
|
126
|
+
|
|
127
|
+
const triggerFlamegraphMessage = {
|
|
128
|
+
command: 'trigger-flamegraph',
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
getWs().send(JSON.stringify(triggerFlamegraphMessage))
|
|
132
|
+
|
|
133
|
+
await allUploadsComplete
|
|
134
|
+
|
|
135
|
+
equal(getFlamegraphReqs.length, 2)
|
|
136
|
+
|
|
137
|
+
const service1Req = getFlamegraphReqs.find(
|
|
138
|
+
(f) => f.serviceId === 'service-1'
|
|
139
|
+
)
|
|
140
|
+
const service2Req = getFlamegraphReqs.find(
|
|
141
|
+
(f) => f.serviceId === 'service-2'
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
equal(service1Req.serviceId, 'service-1')
|
|
145
|
+
equal(service2Req.serviceId, 'service-2')
|
|
146
|
+
|
|
147
|
+
await app.closeUpdates()
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
test('should handle trigger-flamegraph when no runtime is available', async (t) => {
|
|
151
|
+
setUpEnvironment()
|
|
152
|
+
|
|
153
|
+
const receivedMessages = []
|
|
154
|
+
|
|
155
|
+
const wss = new WebSocketServer({ port: port + 1 })
|
|
156
|
+
t.after(async () => wss.close())
|
|
157
|
+
|
|
158
|
+
const { waitForClientSubscription, getWs } = setupMockIccServer(
|
|
159
|
+
wss,
|
|
160
|
+
receivedMessages,
|
|
161
|
+
false
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
const app = createMockApp(port + 1)
|
|
165
|
+
app.wattpro.runtime = null
|
|
166
|
+
|
|
167
|
+
await updatePlugin(app)
|
|
168
|
+
await app.connectToUpdates()
|
|
169
|
+
await waitForClientSubscription
|
|
170
|
+
|
|
171
|
+
const triggerFlamegraphMessage = {
|
|
172
|
+
command: 'trigger-flamegraph',
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
getWs().send(JSON.stringify(triggerFlamegraphMessage))
|
|
176
|
+
|
|
177
|
+
await sleep(100)
|
|
178
|
+
|
|
179
|
+
await app.closeUpdates()
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
test('should handle trigger-flamegraph when flamegraph upload fails', async (t) => {
|
|
183
|
+
setUpEnvironment()
|
|
184
|
+
|
|
185
|
+
const receivedMessages = []
|
|
186
|
+
|
|
187
|
+
const wss = new WebSocketServer({ port: port + 2 })
|
|
188
|
+
t.after(async () => wss.close())
|
|
189
|
+
|
|
190
|
+
const { waitForClientSubscription, getWs } = setupMockIccServer(
|
|
191
|
+
wss,
|
|
192
|
+
receivedMessages,
|
|
193
|
+
false
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
const app = createMockApp(port + 2)
|
|
197
|
+
|
|
198
|
+
app.wattpro.runtime.sendCommandToApplication = async (
|
|
199
|
+
serviceId,
|
|
200
|
+
command,
|
|
201
|
+
options
|
|
202
|
+
) => {
|
|
203
|
+
if (command === 'sendFlamegraph' && options.url && options.headers) {
|
|
204
|
+
throw new Error('Flamegraph upload failed')
|
|
205
|
+
}
|
|
206
|
+
return { success: false }
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
await updatePlugin(app)
|
|
210
|
+
await flamegraphsPlugin(app)
|
|
211
|
+
|
|
212
|
+
await app.connectToUpdates()
|
|
213
|
+
await app.setupFlamegraphs()
|
|
214
|
+
|
|
215
|
+
await waitForClientSubscription
|
|
216
|
+
|
|
217
|
+
const triggerFlamegraphMessage = {
|
|
218
|
+
command: 'trigger-flamegraph',
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
getWs().send(JSON.stringify(triggerFlamegraphMessage))
|
|
222
|
+
|
|
223
|
+
await sleep(100)
|
|
224
|
+
|
|
225
|
+
await app.closeUpdates()
|
|
226
|
+
})
|