Skip to content

Commit 54c6689

Browse files
authored
[Identity] Different approach for testing the Arc feature, instead of mock-fs (Azure#15571)
Recently we found an issue on our CI build for Node 16.3.0, which boiled down to one unit test specific to Identity: Azure#15547 After some investigation, it is clear that Node 16.3.0 has some incompatibility with mock-fs: tschaub/mock-fs#332 In the mean time, to add this test again, we can simply create a file, point to it and delete it at the end. This should work in all versions of Node, and it means one less dev-dependency for us.
1 parent e40ae59 commit 54c6689

File tree

2 files changed

+58
-56
lines changed

2 files changed

+58
-56
lines changed

sdk/identity/identity/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@
126126
"util": "^0.12.1",
127127
"sinon": "^9.0.2",
128128
"@types/sinon": "^9.0.4",
129-
"mock-fs": "^4.10.4",
130129
"typedoc": "0.15.2"
131130
}
132131
}

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

Lines changed: 58 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,16 @@ import { MockAuthHttpClient, MockAuthHttpClientOptions, assertRejects } from "..
1313
import { OAuthErrorResponse } from "../../../src/client/errors";
1414
import Sinon from "sinon";
1515
import { imdsMsiRetryConfig } from "../../../src/credentials/managedIdentityCredential/imdsMsi";
16+
import { mkdtempSync, rmdirSync, unlinkSync, writeFileSync } from "fs";
17+
import { join } from "path";
18+
import { tmpdir } from "os";
1619

1720
interface AuthRequestDetails {
1821
requests: WebResource[];
1922
token: AccessToken | null;
2023
}
2124

2225
describe("ManagedIdentityCredential", function() {
23-
// There are no types available for this dependency, at least at the time this test file was written.
24-
// eslint-disable-next-line @typescript-eslint/no-require-imports
25-
const mockFs = require("mock-fs");
2626
let envCopy: string = "";
2727
let sandbox: Sinon.SinonSandbox;
2828
let clock: Sinon.SinonFakeTimers;
@@ -42,7 +42,6 @@ describe("ManagedIdentityCredential", function() {
4242
});
4343
});
4444
afterEach(() => {
45-
mockFs.restore();
4645
const env = JSON.parse(envCopy);
4746
process.env.IDENTITY_ENDPOINT = env.IDENTITY_ENDPOINT;
4847
process.env.IDENTITY_HEADER = env.IDENTITY_HEADER;
@@ -338,71 +337,75 @@ describe("ManagedIdentityCredential", function() {
338337
}
339338
});
340339

341-
// This fails on ubuntu1804_16x_node on Node version 16.3.0
342-
it.skip("sends an authorization request correctly in an Azure Arc environment", async () => {
340+
it("sends an authorization request correctly in an Azure Arc environment", async function() {
343341
// Trigger Azure Arc behavior by setting environment variables
344342

345343
process.env.IMDS_ENDPOINT = "https://endpoint";
346344
process.env.IDENTITY_ENDPOINT = "https://endpoint";
347345

348-
const filePath = "path/to/file";
346+
// eslint-disable-next-line @typescript-eslint/no-invalid-this
347+
const testTitle = this.test?.title || `test-Date.time()`;
348+
const tempDir = mkdtempSync(join(tmpdir(), testTitle));
349+
const tempFile = join(tempDir, testTitle);
349350
const key = "challenge key";
350-
351-
mockFs({
352-
[`${filePath}`]: key
353-
});
354-
355-
const authDetails = await getMsiTokenAuthRequest(["https://service/.default"], undefined, {
356-
authResponse: [
357-
{
358-
status: 401,
359-
headers: new HttpHeaders({
360-
"www-authenticate": `we don't pay much attention about this format=${filePath}`
361-
})
362-
},
363-
{
364-
status: 200,
365-
parsedBody: {
366-
token: "token",
367-
expires_in: 1
351+
writeFileSync(tempFile, key, { encoding: "utf8" });
352+
353+
try {
354+
const authDetails = await getMsiTokenAuthRequest(["https://service/.default"], undefined, {
355+
authResponse: [
356+
{
357+
status: 401,
358+
headers: new HttpHeaders({
359+
"www-authenticate": `we don't pay much attention about this format=${tempFile}`
360+
})
361+
},
362+
{
363+
status: 200,
364+
parsedBody: {
365+
token: "token",
366+
expires_in: 1
367+
}
368368
}
369-
}
370-
]
371-
});
372-
373-
// File request
374-
const validationRequest = authDetails.requests[0];
375-
assert.ok(validationRequest.query, "No query string parameters on request");
369+
]
370+
});
376371

377-
assert.equal(validationRequest.method, "GET");
378-
assert.equal(decodeURIComponent(validationRequest.query!["resource"]), "https://service");
372+
// File request
373+
const validationRequest = authDetails.requests[0];
374+
assert.ok(validationRequest.query, "No query string parameters on request");
379375

380-
assert.ok(
381-
validationRequest.url.startsWith(process.env.IDENTITY_ENDPOINT),
382-
"URL does not start with expected host and path"
383-
);
376+
assert.equal(validationRequest.method, "GET");
377+
assert.equal(decodeURIComponent(validationRequest.query!["resource"]), "https://service");
384378

385-
// Authorization request, which comes after getting the file path, for now at least.
386-
const authRequest = authDetails.requests[1];
387-
assert.ok(authRequest.query, "No query string parameters on request");
379+
assert.ok(
380+
validationRequest.url.startsWith(process.env.IDENTITY_ENDPOINT),
381+
"URL does not start with expected host and path"
382+
);
388383

389-
assert.equal(authRequest.method, "GET");
390-
assert.equal(decodeURIComponent(authRequest.query!["resource"]), "https://service");
384+
// Authorization request, which comes after getting the file path, for now at least.
385+
const authRequest = authDetails.requests[1];
386+
assert.ok(authRequest.query, "No query string parameters on request");
391387

392-
assert.ok(
393-
authRequest.url.startsWith(process.env.IDENTITY_ENDPOINT),
394-
"URL does not start with expected host and path"
395-
);
388+
assert.equal(authRequest.method, "GET");
389+
assert.equal(decodeURIComponent(authRequest.query!["resource"]), "https://service");
396390

397-
assert.equal(authRequest.headers.get("Authorization"), `Basic ${key}`);
398-
if (authDetails.token) {
399-
// We use Date.now underneath.
400-
assert.equal(
401-
Math.floor(authDetails.token.expiresOnTimestamp / 1000000),
402-
Math.floor(Date.now() / 1000000)
391+
assert.ok(
392+
authRequest.url.startsWith(process.env.IDENTITY_ENDPOINT),
393+
"URL does not start with expected host and path"
403394
);
404-
} else {
405-
assert.fail("No token was returned!");
395+
396+
assert.equal(authRequest.headers.get("Authorization"), `Basic ${key}`);
397+
if (authDetails.token) {
398+
// We use Date.now underneath.
399+
assert.equal(
400+
Math.floor(authDetails.token.expiresOnTimestamp / 1000000),
401+
Math.floor(Date.now() / 1000000)
402+
);
403+
} else {
404+
assert.fail("No token was returned!");
405+
}
406+
} finally {
407+
unlinkSync(tempFile);
408+
rmdirSync(tempDir);
406409
}
407410
});
408411

0 commit comments

Comments
 (0)