Skip to content

Commit 854d41e

Browse files
Fix flaky workloadIdentityCredentialIdentityBinding test on Windows (#36745)
### Packages impacted by this PR - @azure/identity ### Issues associated with this PR - #33623 ### Describe the problem that is addressed by this PR Test `should use custom token endpoint with CA file configuration` fails intermittently on Windows with `ENOTEMPTY: directory not empty, rmdir`. The "Certificate Validation & Processing" tests used `fs.unlink()` + `fs.rmdir()` for temp directory cleanup, which fails on Windows due to timing issues with file handle releases. Additionally, the inline cleanup approach meant that cleanup would not occur if test assertions failed. ### What are the possible designs available to address the problem? If there are more than one possible design, why was the one in this PR chosen? Two main approaches were implemented: 1. **Replace two-step cleanup pattern**: Changed from `fs.unlink()` + `fs.rmdir()` to `fs.rm(tempDir, { recursive: true, force: true })` for reliable cross-platform directory cleanup. This pattern is already used elsewhere in this test file ("Configuration validation" and "Identity binding feature" sections). 2. **Refactor cleanup to afterEach block**: Moved cleanup logic to an `afterEach` hook to ensure cleanup happens even if test assertions fail. This involved: - Declaring `tempDir` and `tempCaFile` as describe-block-level variables typed as `string | undefined` - Adding error handling in the cleanup to prevent test suite failures from filesystem issues - Resetting variables to `undefined` after cleanup to prevent stale path reuse This combined approach ensures both reliable cleanup on Windows and guaranteed cleanup regardless of test outcome. ### Are there test cases added in this PR? _(If not, why?)_ No new tests needed—this fixes existing test cleanup reliability and robustness. ### Provide a list of related PRs _(if any)_ N/A ### Command used to generate this PR:**_(Applicable only to SDK release request PRs)_ N/A ### Checklists - [x] Added impacted package name to the issue description - [ ] Does this PR needs any fixes in the SDK Generator?** _(If so, create an Issue in the [Autorest/typescript](https://github.com/Azure/autorest.typescript) repository and link it here)_ - [ ] Added a changelog (if necessary) <!-- START COPILOT CODING AGENT SUFFIX --> <details> <summary>Original prompt</summary> > > ---- > > *This section details on the original issue you should resolve* > > <issue_title>[test] [identity] flaky workloadIdentityCredentialIdentityBinding test?</issue_title> > <issue_description>```text > @azure/identity:test:node: [vitest] ⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯ > @azure/identity:test:node: [vitest] > @azure/identity:test:node: [vitest] FAIL test/internal/node/workloadIdentityCredentialIdentityBinding.spec.ts > WorkloadIdentityCredential - Identity Binding Configuration > Identity binding feature > should use custom token endpoint with CA file configuration > @azure/identity:test:node: [vitest] Error: ENOTEMPTY: directory not empty, rmdir 'C:\Users\CLOUDT~1\AppData\Local\Temp\tempDir3YnkHc' > @azure/identity:test:node: [vitest] ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯ > @azure/identity:test:node: [vitest] > @azure/identity:test:node: [vitest] > @azure/identity:test:node: [vitest] Test Files 1 failed | 38 passed | 3 skipped (42) > @azure/identity:test:node: [vitest] Tests 1 failed | 384 passed | 17 skipped (402) > @azure/identity:test:node: [vitest] Start at 19:35:52 > @azure/identity:test:node: [vitest] Duration 27.69s (transform 12.00s, setup 0ms, collect 37.61s, tests 21.64s, environment 14ms, prepare 816ms) > ```</issue_description> > > ## Comments on the Issue (you are @copilot in this section) > > <comments> > <comment_new><author>@jeremymeng</author><body> > https://dev.azure.com/azure-sdk/public/public%20Team/_build/results?buildId=5605868&view=logs&j=3e883751-031e-56f9-9938-d1ed90b686e8&t=209f8deb-5df3-5fcd-d026-4e85ab01a9fe&l=2126</body></comment_new> > </comments> > </details> - Fixes #36735 <!-- START COPILOT CODING AGENT TIPS --> --- ✨ Let Copilot coding agent [set things up for you](https://github.com/Azure/azure-sdk-for-js/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo. --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: minhanh-phan <[email protected]>
1 parent bfe5908 commit 854d41e

File tree

1 file changed

+20
-9
lines changed

1 file changed

+20
-9
lines changed

sdk/identity/identity/test/internal/node/workloadIdentityCredentialIdentityBinding.spec.ts

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,22 @@ describe("WorkloadIdentityCredential - Identity Binding Configuration", function
3737
});
3838

3939
describe("Certificate Validation & Processing", function () {
40+
let tempDir: string | undefined;
41+
let tempCaFile: string | undefined;
42+
43+
afterEach(async function () {
44+
if (tempDir) {
45+
try {
46+
await fs.rm(tempDir, { recursive: true, force: true });
47+
} catch (error) {
48+
// Ignore cleanup errors to prevent test suite failures
49+
} finally {
50+
tempDir = undefined;
51+
tempCaFile = undefined;
52+
}
53+
}
54+
});
55+
4056
it("should throw error for invalid CA certificate data", async function () {
4157
vi.stubEnv("AZURE_KUBERNETES_TOKEN_PROXY", "https://test-proxy.example.com");
4258
vi.stubEnv("AZURE_KUBERNETES_CA_DATA", "invalid-certificate-data");
@@ -52,8 +68,8 @@ describe("WorkloadIdentityCredential - Identity Binding Configuration", function
5268
});
5369
it("should validate CA file changes and cache invalidation", async function () {
5470
const invalidCaContent = "invalid-certificate-data";
55-
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "cert-test-"));
56-
const tempCaFile = path.join(tempDir, "ca.pem");
71+
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "cert-test-"));
72+
tempCaFile = path.join(tempDir, "ca.pem");
5773
// Copy valid certificate initially
5874
await fs.copyFile(TEST_CERT_PATH, tempCaFile);
5975

@@ -100,13 +116,11 @@ describe("WorkloadIdentityCredential - Identity Binding Configuration", function
100116

101117
// Should be a new object reference since cache was invalidated
102118
assert.equal(tlsSettings3.ca, getTestCertificateContent());
103-
await fs.unlink(tempCaFile);
104-
await fs.rmdir(tempDir);
105119
});
106120

107121
it("should handle empty CA file during rotation", async function () {
108-
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "cert-test-"));
109-
const tempCaFile = path.join(tempDir, "ca.pem");
122+
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "cert-test-"));
123+
tempCaFile = path.join(tempDir, "ca.pem");
110124

111125
await fs.copyFile(TEST_CERT_PATH, tempCaFile);
112126

@@ -143,9 +157,6 @@ describe("WorkloadIdentityCredential - Identity Binding Configuration", function
143157
enableAzureProxy: true,
144158
});
145159
}, /CA certificate file is empty/);
146-
147-
await fs.unlink(tempCaFile);
148-
await fs.rmdir(tempDir);
149160
});
150161
});
151162

0 commit comments

Comments
 (0)