Skip to content

Commit 88c2bc7

Browse files
amulyakashyap09Amulya Kashyap
andauthored
ACNA-3231 | E2e tests failure (#821)
* failed e2e tests fix * e2e test failures fix * PR comments fixed * fixed PR comments * ticket ACNA-3240 : commented out code * e2e test failures fix * tested for standalone scenario * removed non-required token check function && fixed the undeploy no-login/standalone case * added lint * removed unused code * removed commented code --------- Co-authored-by: Amulya Kashyap <amulyak@adobe.com>
1 parent fff2504 commit 88c2bc7

8 files changed

Lines changed: 213 additions & 67 deletions

File tree

src/commands/app/deploy.js

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class Deploy extends BuildCommand {
6464
const lfConfig = lf.getLocalConfigWithSecrets()
6565
if (lfConfig.isDefined()) {
6666
await lf.updateServerConfig(lfConfig)
67-
spinner.succeed(chalk.green(`Log forwarding is set to '${lfConfig.getDestination()}'`))
67+
spinner.succeed(chalk.green(`\nLog forwarding is set to '${lfConfig.getDestination()}'`))
6868
} else {
6969
if (flags.verbose) {
7070
spinner.info(chalk.dim('Log forwarding is not updated: no configuration is provided'))
@@ -93,14 +93,6 @@ class Deploy extends BuildCommand {
9393
}
9494
}
9595

96-
// 3. send deploy log event
97-
const logEvent = getAuditLogEvent(flags, aioConfig.project, 'AB_APP_DEPLOY')
98-
if (logEvent) {
99-
await sendAuditLogs(cliDetails.accessToken, logEvent, cliDetails.env)
100-
} else {
101-
this.log(chalk.red(chalk.bold('Warning: No valid config data found to send audit log event for deployment.')))
102-
}
103-
10496
// 4. deploy actions and web assets for each extension
10597
// Possible improvements:
10698
// - parallelize
@@ -112,9 +104,14 @@ class Deploy extends BuildCommand {
112104
if (v.app.hasFrontend && flags['web-assets']) {
113105
const opItems = getFilesCountWithExtension(v.web.distProd)
114106
const assetDeployedLogEvent = getAuditLogEvent(flags, aioConfig.project, 'AB_APP_ASSETS_DEPLOYED')
115-
if (assetDeployedLogEvent) {
107+
if (assetDeployedLogEvent && cliDetails?.accessToken) {
116108
assetDeployedLogEvent.data.opItems = opItems
117-
await sendAuditLogs(cliDetails.accessToken, assetDeployedLogEvent, cliDetails.env)
109+
try {
110+
// only send logs in case of web-assets deployment
111+
await sendAuditLogs(cliDetails.accessToken, assetDeployedLogEvent, cliDetails.env)
112+
} catch (error) {
113+
this.warn('Error: Audit Log Service Error: Failed to send audit log event for deployment.')
114+
}
118115
}
119116
}
120117
}

src/commands/app/undeploy.js

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,21 @@ class Undeploy extends BaseCommand {
2727
const { flags } = await this.parse(Undeploy)
2828

2929
const undeployConfigs = await this.getAppExtConfigs(flags)
30+
31+
// 1. undeploy actions and web assets for each extension
32+
const keys = Object.keys(undeployConfigs)
33+
const values = Object.values(undeployConfigs)
34+
35+
// if it is standalone app, unpublish it without token
36+
const isStandaloneApp = (keys.length === 1 && keys[0] === 'application')
37+
flags.unpublish = flags.unpublish && !isStandaloneApp
38+
3039
let libConsoleCLI
3140
if (flags.unpublish) {
3241
// force login at beginning (if required)
3342
libConsoleCLI = await this.getLibConsoleCLI()
3443
}
3544

36-
// 1. undeploy actions and web assets for each extension
37-
const keys = Object.keys(undeployConfigs)
38-
const values = Object.values(undeployConfigs)
39-
4045
if (
4146
(!flags.unpublish && !flags['web-assets'] && !flags.actions)
4247
) {
@@ -46,28 +51,25 @@ class Undeploy extends BaseCommand {
4651
const spinner = ora()
4752
try {
4853
const aioConfig = (await this.getFullConfig()).aio
49-
const cliDetails = await getCliInfo()
50-
const logEvent = getAuditLogEvent(flags, aioConfig.project, 'AB_APP_UNDEPLOY')
51-
52-
// 1.1. send audit log event for successful undeploy
53-
if (logEvent) {
54-
await sendAuditLogs(cliDetails.accessToken, logEvent, cliDetails.env)
55-
} else {
56-
this.log(chalk.red(chalk.bold('Warning: No valid config data found to send audit log event for deployment.')))
57-
}
54+
const cliDetails = await getCliInfo(flags.unpublish)
5855

5956
for (let i = 0; i < keys.length; ++i) {
6057
const k = keys[i]
6158
const v = values[i]
6259
await this.undeployOneExt(k, v, flags, spinner)
6360
const assetUndeployLogEvent = getAuditLogEvent(flags, aioConfig.project, 'AB_APP_ASSETS_UNDEPLOYED')
64-
if (assetUndeployLogEvent) {
65-
await sendAuditLogs(cliDetails.accessToken, assetUndeployLogEvent, cliDetails.env)
61+
// send logs for case of web-assets undeployment
62+
if (assetUndeployLogEvent && cliDetails?.accessToken) {
63+
try {
64+
await sendAuditLogs(cliDetails.accessToken, assetUndeployLogEvent, cliDetails.env)
65+
} catch (error) {
66+
this.warn('Warning: Audit Log Service Error: Failed to send audit log event for un-deployment.')
67+
}
6668
}
6769
}
6870

6971
// 1.2. unpublish extension manifest
70-
if (flags.unpublish && !(keys.length === 1 && keys[0] === 'application')) {
72+
if (flags.unpublish) {
7173
const payload = await this.unpublishExtensionPoints(libConsoleCLI, undeployConfigs, aioConfig, flags['force-unpublish'])
7274
this.log(chalk.blue(chalk.bold(`New Extension Point(s) in Workspace '${aioConfig.project.workspace.name}': '${Object.keys(payload.endpoints)}'`)))
7375
} else {

src/lib/app-helper.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ async function runScript (command, dir, cmdArgs = []) {
155155
aioLogger.debug(`Killing ${command} event hook long-running process (pid: ${pid})`)
156156
process.kill(pid, 'SIGTERM')
157157
} catch (_) {
158-
// do nothing if pid not found
158+
// do nothing if pid not found
159159
}
160160
})
161161
}

src/lib/audit-logger.js

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,16 @@ const fetch = require('node-fetch')
1212
const fs = require('fs')
1313
const path = require('path')
1414
const chalk = require('chalk')
15-
const { getCliEnv, PROD_ENV } = require('@adobe/aio-lib-env')
16-
const aioLogger = require('@adobe/aio-lib-core-logging')('@adobe/aio-cli-plugin-app:lib-audit-logger', { provider: 'debug' })
1715

1816
const OPERATIONS = {
1917
AB_APP_DEPLOY: 'ab_app_deploy',
2018
AB_APP_UNDEPLOY: 'ab_app_undeploy',
21-
AB_APP_TEST: 'ab_app_test', // todo : remove after testing
19+
AB_APP_TEST: 'ab_app_test',
2220
AB_APP_ASSETS_DEPLOYED: 'ab_app_assets_deployed',
2321
AB_APP_ASSETS_UNDEPLOYED: 'ab_app_assets_undeployed'
2422
}
2523

26-
const AUDIT_SERVICE_ENPOINTS = {
24+
const AUDIT_SERVICE_ENDPOINTS = {
2725
stage: 'https://adp-auditlog-service-stage.adobeioruntime.net/api/v1/web/audit-log-api/event-post',
2826
prod: 'https://adp-auditlog-service-prod.adobeioruntime.net/api/v1/web/audit-log-api/event-post'
2927
}
@@ -35,12 +33,7 @@ const AUDIT_SERVICE_ENPOINTS = {
3533
* @param {string} env valid env stage|prod
3634
*/
3735
async function sendAuditLogs (accessToken, logEvent, env = 'prod') {
38-
// TODO: this is blocked by the audit service only being available in stage
39-
// remove this check once the service is available in prod
40-
if (env !== 'stage') {
41-
return
42-
}
43-
const url = AUDIT_SERVICE_ENPOINTS[env]
36+
const url = AUDIT_SERVICE_ENDPOINTS[env] ?? AUDIT_SERVICE_ENDPOINTS.prod
4437
const payload = {
4538
event: logEvent
4639
}
@@ -67,11 +60,6 @@ async function sendAuditLogs (accessToken, logEvent, env = 'prod') {
6760
* @returns {object} logEvent
6861
*/
6962
function getAuditLogEvent (flags, project, event) {
70-
if (getCliEnv() === PROD_ENV) {
71-
aioLogger.debug('Audit logging is currently disabled in production environment')
72-
return null
73-
}
74-
7563
let logEvent, logStrMsg
7664
if (project && project.org && project.workspace) {
7765
if (event === 'AB_APP_DEPLOY') {
@@ -151,6 +139,6 @@ function getFilesCountWithExtension (directory) {
151139
module.exports = {
152140
sendAuditLogs,
153141
getAuditLogEvent,
154-
AUDIT_SERVICE_ENPOINTS,
142+
AUDIT_SERVICE_ENDPOINTS,
155143
getFilesCountWithExtension
156144
}

test/commands/app/deploy.test.js

Lines changed: 87 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ test('flags', async () => {
217217
expect(typeof TheCommand.flags.action).toBe('object')
218218
expect(TheCommand.flags.action.char).toBe('a')
219219
expect(typeof TheCommand.flags.action.description).toBe('string')
220-
expect(JSON.stringify(TheCommand.flags.action.exclusive)).toStrictEqual(JSON.stringify(['extension', { name: 'publish', when: () => {} }]))
220+
expect(JSON.stringify(TheCommand.flags.action.exclusive)).toStrictEqual(JSON.stringify(['extension', { name: 'publish', when: () => { } }]))
221221

222222
expect(typeof TheCommand.flags['web-assets']).toBe('object')
223223
expect(typeof TheCommand.flags['web-assets'].description).toBe('string')
@@ -1324,11 +1324,11 @@ describe('run', () => {
13241324
expect(command.error).toHaveBeenCalledTimes(0)
13251325
expect(mockRuntimeLib.deployActions).toHaveBeenCalledTimes(1)
13261326
expect(mockWebLib.deployWeb).toHaveBeenCalledTimes(1)
1327-
expect(auditLogger.sendAuditLogs.mock.calls.length).toBeLessThanOrEqual(2)
1327+
expect(auditLogger.sendAuditLogs).toHaveBeenCalledTimes(1)
13281328
expect(auditLogger.sendAuditLogs).toHaveBeenCalledWith(mockToken, expect.objectContaining({ orgId: mockOrg, projectId: mockProject, workspaceId: mockWorkspaceId, workspaceName: mockWorkspaceName }), mockEnv)
13291329
})
13301330

1331-
test('Do not send audit logs for successful app deploy', async () => {
1331+
test('Do not send audit logs for successful app deploy, if no logevent is present', async () => {
13321332
const mockToken = 'mocktoken'
13331333
const mockEnv = 'stage'
13341334
const mockOrg = 'mockorg'
@@ -1362,6 +1362,43 @@ describe('run', () => {
13621362
expect(command.error).toHaveBeenCalledTimes(0)
13631363
expect(mockRuntimeLib.deployActions).toHaveBeenCalledTimes(1)
13641364
expect(mockWebLib.deployWeb).toHaveBeenCalledTimes(1)
1365+
expect(auditLogger.sendAuditLogs).toHaveBeenCalledTimes(0)
1366+
})
1367+
1368+
test('Do not send audit logs for successful app deploy, if case of no token', async () => {
1369+
const mockToken = null
1370+
const mockEnv = 'stage'
1371+
const mockOrg = 'mockorg'
1372+
const mockProject = 'mockproject'
1373+
const mockWorkspaceId = 'mockworkspaceid'
1374+
const mockWorkspaceName = 'mockworkspacename'
1375+
1376+
helpers.getCliInfo.mockResolvedValueOnce({
1377+
accessToken: mockToken,
1378+
env: mockEnv
1379+
})
1380+
1381+
command.getFullConfig = jest.fn().mockReturnValue({
1382+
aio: {
1383+
project: {
1384+
id: mockProject,
1385+
org: {
1386+
id: mockOrg
1387+
},
1388+
workspace: {
1389+
id: mockWorkspaceId,
1390+
name: mockWorkspaceName
1391+
}
1392+
}
1393+
}
1394+
})
1395+
command.getAppExtConfigs.mockResolvedValueOnce(createAppConfig(command.appConfig))
1396+
1397+
await command.run()
1398+
expect(command.error).toHaveBeenCalledTimes(0)
1399+
expect(mockRuntimeLib.deployActions).toHaveBeenCalledTimes(1)
1400+
expect(mockWebLib.deployWeb).toHaveBeenCalledTimes(1)
1401+
expect(auditLogger.sendAuditLogs).toHaveBeenCalledTimes(0)
13651402
})
13661403

13671404
test('Send audit logs for successful app deploy + web assets', async () => {
@@ -1403,4 +1440,51 @@ describe('run', () => {
14031440
expect(auditLogger.getFilesCountWithExtension).toHaveBeenCalledTimes(2)
14041441
expect(auditLogger.sendAuditLogs).toHaveBeenCalledWith(mockToken, expect.objectContaining({ orgId: mockOrg, projectId: mockProject, workspaceId: mockWorkspaceId, workspaceName: mockWorkspaceName }), mockEnv)
14051442
})
1443+
1444+
test('Should deploy successfully even if Audit log service is unavailable', async () => {
1445+
const mockToken = 'mocktoken'
1446+
const mockEnv = 'stage'
1447+
const mockOrg = 'mockorg'
1448+
const mockProject = 'mockproject'
1449+
const mockWorkspaceId = 'mockworkspaceid'
1450+
const mockWorkspaceName = 'mockworkspacename'
1451+
helpers.getCliInfo.mockResolvedValueOnce({
1452+
accessToken: mockToken,
1453+
env: mockEnv
1454+
})
1455+
command.getFullConfig = jest.fn().mockReturnValue({
1456+
aio: {
1457+
project: {
1458+
id: mockProject,
1459+
org: {
1460+
id: mockOrg
1461+
},
1462+
workspace: {
1463+
id: mockWorkspaceId,
1464+
name: mockWorkspaceName
1465+
}
1466+
}
1467+
}
1468+
})
1469+
1470+
auditLogger.sendAuditLogs.mockRejectedValue({
1471+
message: 'Internal Server Error',
1472+
status: 500
1473+
})
1474+
1475+
command.getAppExtConfigs.mockResolvedValueOnce(createAppConfig(command.appConfig))
1476+
1477+
await command.run()
1478+
expect(command.log).toHaveBeenCalledWith(
1479+
expect.stringContaining('skipping publish phase...')
1480+
)
1481+
1482+
expect(command.log).toHaveBeenCalledWith(
1483+
expect.stringContaining('Successful deployment 🏄')
1484+
)
1485+
expect(auditLogger.sendAuditLogs).toHaveBeenCalledTimes(1)
1486+
expect(command.error).toHaveBeenCalledTimes(0)
1487+
expect(mockRuntimeLib.deployActions).toHaveBeenCalledTimes(1)
1488+
expect(mockWebLib.deployWeb).toHaveBeenCalledTimes(1)
1489+
})
14061490
})

test/commands/app/undeploy.test.js

Lines changed: 72 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,10 @@ describe('run', () => {
143143
command.error = jest.fn()
144144
command.log = jest.fn()
145145
command.appConfig = mockConfigData
146-
command.config = { runCommand: jest.fn(), runHook: jest.fn() }
146+
command.config = {
147+
runCommand: jest.fn(),
148+
runHook: jest.fn()
149+
}
147150
command.getLibConsoleCLI = jest.fn(() => mockLibConsoleCLI)
148151
command.getAppExtConfigs = jest.fn()
149152
command.getFullConfig = jest.fn().mockReturnValue({
@@ -189,7 +192,8 @@ describe('run', () => {
189192

190193
command.argv = ['--no-actions', '--no-web-assets']
191194
await command.run()
192-
expect(command.error).toHaveBeenCalledTimes(0)
195+
expect(command.error).toHaveBeenCalledTimes(1)
196+
expect(command.error).toHaveBeenCalledWith('Nothing to be done 🚫')
193197
expect(mockRuntimeLib.undeployActions).toHaveBeenCalledTimes(0)
194198
expect(mockWebLib.undeployWeb).toHaveBeenCalledTimes(0)
195199

@@ -496,11 +500,41 @@ describe('run', () => {
496500
expect(command.error).toHaveBeenCalledTimes(0)
497501
expect(mockRuntimeLib.undeployActions).toHaveBeenCalledTimes(1)
498502
expect(mockWebLib.undeployWeb).toHaveBeenCalledTimes(1)
499-
expect(auditLogger.sendAuditLogs.mock.calls.length).toBeGreaterThan(1)
503+
expect(auditLogger.sendAuditLogs.mock.calls.length).toBe(1)
500504
expect(auditLogger.sendAuditLogs).toHaveBeenCalledWith(mockToken, expect.objectContaining({ orgId: mockOrg, projectId: mockProject, workspaceId: mockWorkspaceId, workspaceName: mockWorkspaceName }), mockEnv)
501505
})
502506

503-
test('Do not Send audit logs for successful app undeploy', async () => {
507+
test('Do not Send audit logs for successful app undeploy if case of no-token', async () => {
508+
const mockOrg = 'mockorg'
509+
const mockProject = 'mockproject'
510+
const mockWorkspaceId = 'mockworkspaceid'
511+
const mockWorkspaceName = 'mockworkspacename'
512+
513+
command.getFullConfig = jest.fn().mockReturnValue({
514+
aio: {
515+
project: {
516+
id: mockProject,
517+
org: {
518+
id: mockOrg
519+
},
520+
workspace: {
521+
id: mockWorkspaceId,
522+
name: mockWorkspaceName
523+
}
524+
}
525+
}
526+
})
527+
command.getAppExtConfigs.mockResolvedValueOnce(createAppConfig(command.appConfig))
528+
helpers.getCliInfo.mockImplementationOnce(() => null)
529+
530+
await command.run()
531+
expect(command.error).toHaveBeenCalledTimes(0)
532+
expect(mockRuntimeLib.undeployActions).toHaveBeenCalledTimes(1)
533+
expect(mockWebLib.undeployWeb).toHaveBeenCalledTimes(1)
534+
expect(auditLogger.sendAuditLogs.mock.calls.length).toBe(0)
535+
})
536+
537+
test('Do not Send audit logs for successful app undeploy, if no logevent is present', async () => {
504538
const mockOrg = 'mockorg'
505539
const mockProject = 'mockproject'
506540
const mockWorkspaceId = 'mockworkspaceid'
@@ -529,6 +563,39 @@ describe('run', () => {
529563
expect(mockRuntimeLib.undeployActions).toHaveBeenCalledTimes(1)
530564
expect(mockWebLib.undeployWeb).toHaveBeenCalledTimes(1)
531565
expect(auditLogger.sendAuditLogs.mock.calls.length).toBe(0)
532-
expect(command.log).toHaveBeenCalledWith(expect.stringMatching(/Warning: No valid config data found to send audit log event for deployment/))
566+
})
567+
568+
test('Should app undeploy successfully even if Audit Log Service is not available', async () => {
569+
const mockOrg = 'mockorg'
570+
const mockProject = 'mockproject'
571+
const mockWorkspaceId = 'mockworkspaceid'
572+
const mockWorkspaceName = 'mockworkspacename'
573+
574+
command.getFullConfig = jest.fn().mockReturnValue({
575+
aio: {
576+
project: {
577+
id: mockProject,
578+
org: {
579+
id: mockOrg
580+
},
581+
workspace: {
582+
id: mockWorkspaceId,
583+
name: mockWorkspaceName
584+
}
585+
}
586+
}
587+
})
588+
command.getAppExtConfigs.mockResolvedValueOnce(createAppConfig(command.appConfig))
589+
590+
auditLogger.sendAuditLogs.mockRejectedValue({
591+
message: 'Internal Server Error',
592+
status: 500
593+
})
594+
595+
await command.run()
596+
expect(command.error).toHaveBeenCalledTimes(0)
597+
expect(mockRuntimeLib.undeployActions).toHaveBeenCalledTimes(1)
598+
expect(mockWebLib.undeployWeb).toHaveBeenCalledTimes(1)
599+
expect(auditLogger.sendAuditLogs).toHaveBeenCalledTimes(1)
533600
})
534601
})

0 commit comments

Comments
 (0)