Skip to content

Commit d48b09b

Browse files
packoczalesremta-ext43767
authored andcommitted
feat(permsets): add maxwaittime ENV variable PSG Awaiter
1 parent ac138e4 commit d48b09b

File tree

2 files changed

+185
-11
lines changed

2 files changed

+185
-11
lines changed

src/core/permsets/PermissionSetGroupUpdateAwaiter.ts

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,31 @@ import SFPLogger, { Logger, LoggerLevel } from '@flxbl-io/sfp-logger';
33
import QueryHelper from '../queryHelper/QueryHelper';
44
import { delay } from '../utils/Delay';
55

6-
const psGroupQuery = `SELECT Id,MasterLabel,Status FROM PermissionSetGroup WHERE Status IN ('Updating', 'Outdated')`;
6+
const psGroupQuery = `SELECT Id,MasterLabel,Status FROM PermissionSetGroup WHERE Status = 'Updating'`;
77

88
export default class PermissionSetGroupUpdateAwaiter {
9-
constructor(private connection: Connection, private logger: Logger, private intervalBetweenRepeats = 60000) {}
9+
constructor(
10+
private connection: Connection,
11+
private logger: Logger,
12+
private intervalBetweenRepeats = 30000
13+
) {}
14+
15+
private getMaxWaitingTimeMilliseconds(): number {
16+
const maxWaitingTimeInMinutes = process.env.PSG_AWAITER_TIMEOUT_MINUTES ?? undefined;
17+
if (maxWaitingTimeInMinutes) {
18+
const maxWaitingTimeInMinutesParsed = Number(maxWaitingTimeInMinutes);
19+
if (isNaN(maxWaitingTimeInMinutesParsed) || maxWaitingTimeInMinutesParsed <= 0) {
20+
SFPLogger.log(`PSG_AWAITER_TIMEOUT_MINUTES env variable must be a positive number [${maxWaitingTimeInMinutes}]`, LoggerLevel.ERROR, this.logger);
21+
}
22+
return maxWaitingTimeInMinutesParsed * 60 * 1000; // Convert minutes to milliseconds
23+
}
24+
}
1025

1126
async waitTillAllPermissionSetGroupIsUpdated() {
12-
SFPLogger.log(
13-
`Checking status of permission sets group..`,
14-
LoggerLevel.INFO,
15-
this.logger
16-
);
27+
const maxWaitingTime = this.getMaxWaitingTimeMilliseconds();
28+
29+
SFPLogger.log(`Checking status of permission sets group..`, LoggerLevel.INFO, this.logger);
30+
let totalTimeWaited = 0;
1731
while (true) {
1832
try {
1933
let records = await QueryHelper.query(psGroupQuery, this.connection, false);
@@ -29,6 +43,17 @@ export default class PermissionSetGroupUpdateAwaiter {
2943
this.logger
3044
);
3145
await delay(this.intervalBetweenRepeats);
46+
totalTimeWaited += this.intervalBetweenRepeats;
47+
if (maxWaitingTime && (totalTimeWaited > maxWaitingTime)) {
48+
SFPLogger.log(
49+
`Max waiting time of ${
50+
maxWaitingTime / 1000
51+
} seconds exceeded. Proceeding with deployment`,
52+
LoggerLevel.WARN,
53+
this.logger
54+
);
55+
break;
56+
}
3257
} else {
3358
SFPLogger.log(
3459
`Proceeding with deployment, as no PermissionSetGroups are being updated`,
@@ -44,3 +69,4 @@ export default class PermissionSetGroupUpdateAwaiter {
4469
}
4570
}
4671
}
72+
Lines changed: 152 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,40 @@
11
import { MockTestOrgData, TestContext } from '../../../node_modules/@salesforce/core/lib/testSetup';
22
import { AuthInfo, Connection, OrgConfigProperties } from '@salesforce/core';
3+
import { ConsoleLogger } from '@flxbl-io/sfp-logger';
34
import { AnyJson } from '@salesforce/ts-types';
45
const $$ = new TestContext();
56
import PermissionSetGroupUpdateAwaiter from '../../../src/core/permsets/PermissionSetGroupUpdateAwaiter';
67
import { expect } from '@jest/globals';
78

89
describe('Await till permissionsets groups are updated', () => {
10+
const noUpdatingPsgRecords: AnyJson = {
11+
records: [],
12+
};
13+
const someUpdatingPsgRecords: AnyJson = {
14+
records: [
15+
{
16+
attributes: {
17+
type: 'PermissionSetGroup',
18+
url: '/services/data/v64.0/sobjects/PermissionSetGroup/0PG250000008nhNGAQ',
19+
},
20+
Id: '0PG250000008nhNGAQ',
21+
MasterLabel: 'PSG1',
22+
Status: 'Updating',
23+
},
24+
{
25+
attributes: {
26+
type: 'PermissionSetGroup',
27+
url: '/services/data/v64.0/sobjects/PermissionSetGroup/0PG250000008nnVGAQ',
28+
},
29+
Id: '0PG250000008nnVGAQ',
30+
MasterLabel: 'PSG2',
31+
Status: 'Updating',
32+
},
33+
],
34+
};
35+
36+
jest.spyOn(require('../../../src/core/utils/Delay'), 'delay').mockImplementation(() => Promise.resolve());
37+
938
it('should return if all permsets groups are updated', async () => {
1039
const testData = new MockTestOrgData();
1140

@@ -15,21 +44,140 @@ describe('Await till permissionsets groups are updated', () => {
1544
contents: await testData.getConfig(),
1645
});
1746

18-
let records: AnyJson = {
19-
records: [],
47+
$$.fakeConnectionRequest = (request: AnyJson): Promise<AnyJson> => {
48+
return Promise.resolve(noUpdatingPsgRecords);
49+
};
50+
51+
const connection: Connection = await Connection.create({
52+
authInfo: await AuthInfo.create({ username: testData.username }),
53+
});
54+
55+
let permissionSetGroupUpdateAwaiter: PermissionSetGroupUpdateAwaiter = new PermissionSetGroupUpdateAwaiter(
56+
connection, new ConsoleLogger()
57+
);
58+
await expect(permissionSetGroupUpdateAwaiter.waitTillAllPermissionSetGroupIsUpdated()).resolves.toBeUndefined();
59+
});
60+
61+
it('should return if all permsets groups are updated after waiting for some time', async () => {
62+
const testData = new MockTestOrgData();
63+
64+
await $$.stubConfig({ [OrgConfigProperties.TARGET_ORG]: testData.username });
65+
await $$.stubAuths(testData);
66+
$$.setConfigStubContents('AuthInfoConfig', {
67+
contents: await testData.getConfig(),
68+
});
69+
70+
let tryCount = 0;
71+
$$.fakeConnectionRequest = (request: AnyJson): Promise<AnyJson> => {
72+
if (tryCount === 0) {
73+
tryCount++;
74+
return Promise.resolve(someUpdatingPsgRecords);
75+
}
76+
return Promise.resolve(noUpdatingPsgRecords);
77+
};
78+
79+
const connection: Connection = await Connection.create({
80+
authInfo: await AuthInfo.create({ username: testData.username }),
81+
});
82+
83+
let permissionSetGroupUpdateAwaiter: PermissionSetGroupUpdateAwaiter = new PermissionSetGroupUpdateAwaiter(
84+
connection,
85+
new ConsoleLogger()
86+
);
87+
await expect(permissionSetGroupUpdateAwaiter.waitTillAllPermissionSetGroupIsUpdated()).resolves.toBeUndefined();
88+
});
89+
90+
it('should keep trying until all permsets groups are updated if there is no maximum wait time', async () => {
91+
const testData = new MockTestOrgData();
92+
93+
await $$.stubConfig({ [OrgConfigProperties.TARGET_ORG]: testData.username });
94+
await $$.stubAuths(testData);
95+
$$.setConfigStubContents('AuthInfoConfig', {
96+
contents: await testData.getConfig(),
97+
});
98+
99+
let tryCount = 0;
100+
$$.fakeConnectionRequest = (request: AnyJson): Promise<AnyJson> => {
101+
if (tryCount < 5) {
102+
// 5th try
103+
tryCount++;
104+
return Promise.resolve(someUpdatingPsgRecords);
105+
}
106+
return Promise.resolve(noUpdatingPsgRecords);
20107
};
108+
109+
const connection: Connection = await Connection.create({
110+
authInfo: await AuthInfo.create({ username: testData.username }),
111+
});
112+
113+
let permissionSetGroupUpdateAwaiter: PermissionSetGroupUpdateAwaiter = new PermissionSetGroupUpdateAwaiter(
114+
connection,
115+
new ConsoleLogger()
116+
);
117+
await expect(permissionSetGroupUpdateAwaiter.waitTillAllPermissionSetGroupIsUpdated()).resolves.toBeUndefined();
118+
expect(tryCount).toBe(5);
119+
});
120+
121+
it('should keep trying until until max wait time is reached', async () => {
122+
const testData = new MockTestOrgData();
123+
124+
await $$.stubConfig({ [OrgConfigProperties.TARGET_ORG]: testData.username });
125+
await $$.stubAuths(testData);
126+
$$.setConfigStubContents('AuthInfoConfig', {
127+
contents: await testData.getConfig(),
128+
});
129+
21130
$$.fakeConnectionRequest = (request: AnyJson): Promise<AnyJson> => {
22-
return Promise.resolve(records);
131+
return Promise.resolve(someUpdatingPsgRecords);
23132
};
24133

25134
const connection: Connection = await Connection.create({
26135
authInfo: await AuthInfo.create({ username: testData.username }),
27136
});
28137

138+
process.env.PSG_AWAITER_TIMEOUT_MINUTES = '0.25'; // 15 seconds
29139
let permissionSetGroupUpdateAwaiter: PermissionSetGroupUpdateAwaiter = new PermissionSetGroupUpdateAwaiter(
30140
connection,
31-
null
141+
new ConsoleLogger(),
142+
100, // try every 100ms
32143
);
33144
await expect(permissionSetGroupUpdateAwaiter.waitTillAllPermissionSetGroupIsUpdated()).resolves.toBeUndefined();
34145
});
146+
147+
it('should not reach maximum time if all permsets groups udpated', async () => {
148+
const testData = new MockTestOrgData();
149+
150+
await $$.stubConfig({ [OrgConfigProperties.TARGET_ORG]: testData.username });
151+
await $$.stubAuths(testData);
152+
$$.setConfigStubContents('AuthInfoConfig', {
153+
contents: await testData.getConfig(),
154+
});
155+
156+
let tryCount = 0;
157+
$$.fakeConnectionRequest = (request: AnyJson): Promise<AnyJson> => {
158+
if (tryCount < 3) {
159+
// 3rd try in 300ms
160+
tryCount++;
161+
return Promise.resolve(someUpdatingPsgRecords);
162+
}
163+
return Promise.resolve(noUpdatingPsgRecords);
164+
};
165+
166+
167+
168+
const connection: Connection = await Connection.create({
169+
authInfo: await AuthInfo.create({ username: testData.username }),
170+
});
171+
172+
process.env.PSG_AWAITER_TIMEOUT_MINUTES = '0.5'; // 30 seconds
173+
let permissionSetGroupUpdateAwaiter: PermissionSetGroupUpdateAwaiter = new PermissionSetGroupUpdateAwaiter(
174+
connection,
175+
new ConsoleLogger(),
176+
100, // try every 100ms
177+
);
178+
await expect(permissionSetGroupUpdateAwaiter.waitTillAllPermissionSetGroupIsUpdated()).resolves.toBeUndefined();
179+
expect(tryCount).toBe(3); // 4 tries in total, first and then waiting 3 times
180+
});
35181
});
182+
183+

0 commit comments

Comments
 (0)