Skip to content

Commit c84841c

Browse files
authored
Merge branch 'main' into fix/cloud-tasks-tests
2 parents 40d999a + 93f3522 commit c84841c

4 files changed

Lines changed: 84 additions & 42 deletions

File tree

security-center/snippets/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"node": ">=16.0.0"
1010
},
1111
"scripts": {
12-
"test": "c8 mocha -p -j 2 --recursive --timeout 6000000 system-test/"
12+
"test": "c8 mocha --recursive --timeout 6000000 system-test/"
1313
},
1414
"license": "Apache-2.0",
1515
"dependencies": {

security-center/snippets/system-test/management_api/securityHealthAnalyticsCustomModule.test.js

Lines changed: 54 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ const customModuleDisplayName =
3333
describe('security health analytics custom module', async () => {
3434
let data;
3535
const sharedModuleIds = [];
36+
const client = new SecurityCenterManagementClient();
3637

3738
before(async () => {
38-
const client = new SecurityCenterManagementClient();
3939
const EnablementState =
4040
protos.google.cloud.securitycentermanagement.v1
4141
.SecurityHealthAnalyticsCustomModule.EnablementState;
@@ -44,7 +44,8 @@ describe('security health analytics custom module', async () => {
4444
const parent = `organizations/${organizationId}/locations/${locationId}`;
4545
const name = `organizations/${organizationId}/locations/${locationId}/securityHealthAnalyticsCustomModules/custom_module`;
4646
const expr = {
47-
expression: `has(resource.rotationPeriod) && (resource.rotationPeriod > duration('2592000s'))`,
47+
expression:
48+
"has(resource.rotationPeriod) && (resource.rotationPeriod > duration('2592000s'))",
4849
};
4950
const resourceSelector = {
5051
resourceTypes: ['cloudkms.googleapis.com/CryptoKey'],
@@ -63,36 +64,59 @@ describe('security health analytics custom module', async () => {
6364
customConfig: customConfig,
6465
};
6566

66-
try {
67-
await new Promise(resolve => setTimeout(resolve, 3000));
68-
const [createResponse] =
69-
await client.createSecurityHealthAnalyticsCustomModule({
70-
parent: parent,
71-
securityHealthAnalyticsCustomModule:
72-
securityHealthAnalyticsCustomModule,
73-
});
74-
// extracts the custom module ID from the full name
75-
const customModuleId = createResponse.name.split('/').pop();
76-
data = {
77-
orgId: organizationId,
78-
customModuleId: customModuleId,
79-
customModuleName: createResponse.displayName,
80-
};
81-
console.log(
82-
'SecurityHealthAnalyticsCustomModule created : %j',
83-
createResponse
84-
);
85-
} catch (error) {
86-
console.error(
87-
'Error creating SecurityHealthAnalyticsCustomModule:',
88-
error
67+
let createResponse;
68+
const maxAttempts = 5;
69+
let attempt = 0;
70+
while (attempt < maxAttempts) {
71+
try {
72+
await new Promise(resolve => setTimeout(resolve, 3000));
73+
const [createSecurityResponse] =
74+
await client.createSecurityHealthAnalyticsCustomModule({
75+
parent: parent,
76+
securityHealthAnalyticsCustomModule:
77+
securityHealthAnalyticsCustomModule,
78+
});
79+
createResponse = createSecurityResponse;
80+
break;
81+
} catch (error) {
82+
if (error.code === 10) {
83+
attempt++;
84+
console.log(
85+
`Concurrent modification detected. Retrying creation (attempt ${attempt}/${maxAttempts})...`
86+
);
87+
await new Promise(resolve =>
88+
setTimeout(resolve, Math.pow(2, attempt) * 1000)
89+
);
90+
} else {
91+
console.error(
92+
'Fatal error creating SecurityHealthAnalyticsCustomModule:',
93+
error
94+
);
95+
throw error;
96+
}
97+
}
98+
}
99+
100+
if (!createResponse) {
101+
throw new Error(
102+
`Timeout: Failed to create custom module after ${maxAttempts} attempts due to concurrent modifications.`
89103
);
90104
}
105+
106+
// extracts the custom module ID from the full name
107+
const customModuleId = createResponse.name.split('/').pop();
108+
data = {
109+
orgId: organizationId,
110+
customModuleId: customModuleId,
111+
customModuleName: createResponse.displayName,
112+
};
113+
console.log(
114+
'SecurityHealthAnalyticsCustomModule created : %j',
115+
createResponse
116+
);
91117
});
92118

93119
after(async () => {
94-
const client = new SecurityCenterManagementClient();
95-
96120
if (sharedModuleIds.length > 0) {
97121
for (const moduleId of sharedModuleIds) {
98122
const name = `organizations/${organizationId}/locations/${locationId}/securityHealthAnalyticsCustomModules/${moduleId}`;
@@ -112,9 +136,11 @@ describe('security health analytics custom module', async () => {
112136
}
113137
}
114138
}
139+
await client.close();
115140
});
116141

117-
it('create security health analytics custom module', done => {
142+
it('create security health analytics custom module', function (done) {
143+
this.retries(3);
118144
const output = exec(
119145
`node management_api/createSecurityHealthAnalyticsCustomModule.js ${data.orgId} ${data.customModuleName} ${locationId}`
120146
);

security-center/snippets/system-test/v2/muterule.test.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,15 @@ describe('Client with mute rule V2', async () => {
4646
},
4747
};
4848

49-
const [muteConfigResponse] = await client
50-
.createMuteConfig(createMuteRuleRequest)
51-
.catch(error => console.error(error));
49+
let muteConfigResponse;
50+
try {
51+
[muteConfigResponse] = await client.createMuteConfig(
52+
createMuteRuleRequest
53+
);
54+
} catch (error) {
55+
console.error('API Error during createMuteConfig:', error);
56+
throw error;
57+
}
5258

5359
const muteConfigId = muteConfigResponse.name.split('/')[5];
5460

security-center/snippets/system-test/v2/notifications.test.js

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,16 @@ describe('Client with Notifications v2', async () => {
4040
let data;
4141

4242
before(async () => {
43-
const configId = 'notif-config-test-node-create-' + uuidv1();
44-
topicName = 'notifications-sample-topic';
43+
const uuidSuffix = uuidv1();
44+
const configId = 'notif-config-test-node-create-' + uuidSuffix;
45+
topicName = 'notifications-sample-topic' + uuidSuffix;
4546
parent = `projects/${projectId}/locations/${location}`;
4647
pubsubTopic = `projects/${projectId}/topics/${topicName}`;
4748

4849
client = new SecurityCenterClient();
4950

5051
pubSubClient = new PubSub();
51-
// A previous test failure can result the topic hanging around
52-
try {
53-
await pubSubClient.topic(topicName).delete();
54-
} catch {
55-
// Ignore if the topic doesn't already exist
56-
}
52+
5753
await pubSubClient.createTopic(topicName);
5854

5955
const notificationConfig = {
@@ -80,10 +76,24 @@ describe('Client with Notifications v2', async () => {
8076
});
8177

8278
after(async () => {
79+
// Delete notification config to prevent resource leaks
80+
if (data && data.notificationName) {
81+
try {
82+
await client.deleteNotificationConfig({
83+
name: data.notificationName,
84+
});
85+
} catch (error) {
86+
console.warn(
87+
`Could not delete Notification Config: ${data.notificationName}`,
88+
error
89+
);
90+
}
91+
}
92+
// Delete topic during cleanup
8393
try {
8494
await pubSubClient.topic(topicName).delete();
85-
} catch {
86-
// Ignore if the topic doesn't exist
95+
} catch (error) {
96+
console.warn(`Could not delete PubSub topic: ${topicName}`, error);
8797
}
8898
});
8999

0 commit comments

Comments
 (0)