Skip to content

Commit

Permalink
[Identity] Different approach for testing the Arc feature, instead of…
Browse files Browse the repository at this point in the history
… mock-fs (#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: #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.
  • Loading branch information
sadasant committed Jun 5, 2021
1 parent e40ae59 commit 54c6689
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 56 deletions.
1 change: 0 additions & 1 deletion sdk/identity/identity/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@
"util": "^0.12.1",
"sinon": "^9.0.2",
"@types/sinon": "^9.0.4",
"mock-fs": "^4.10.4",
"typedoc": "0.15.2"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@ import { MockAuthHttpClient, MockAuthHttpClientOptions, assertRejects } from "..
import { OAuthErrorResponse } from "../../../src/client/errors";
import Sinon from "sinon";
import { imdsMsiRetryConfig } from "../../../src/credentials/managedIdentityCredential/imdsMsi";
import { mkdtempSync, rmdirSync, unlinkSync, writeFileSync } from "fs";
import { join } from "path";
import { tmpdir } from "os";

interface AuthRequestDetails {
requests: WebResource[];
token: AccessToken | null;
}

describe("ManagedIdentityCredential", function() {
// There are no types available for this dependency, at least at the time this test file was written.
// eslint-disable-next-line @typescript-eslint/no-require-imports
const mockFs = require("mock-fs");
let envCopy: string = "";
let sandbox: Sinon.SinonSandbox;
let clock: Sinon.SinonFakeTimers;
Expand All @@ -42,7 +42,6 @@ describe("ManagedIdentityCredential", function() {
});
});
afterEach(() => {
mockFs.restore();
const env = JSON.parse(envCopy);
process.env.IDENTITY_ENDPOINT = env.IDENTITY_ENDPOINT;
process.env.IDENTITY_HEADER = env.IDENTITY_HEADER;
Expand Down Expand Up @@ -338,71 +337,75 @@ describe("ManagedIdentityCredential", function() {
}
});

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

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

const filePath = "path/to/file";
// eslint-disable-next-line @typescript-eslint/no-invalid-this
const testTitle = this.test?.title || `test-Date.time()`;
const tempDir = mkdtempSync(join(tmpdir(), testTitle));
const tempFile = join(tempDir, testTitle);
const key = "challenge key";

mockFs({
[`${filePath}`]: key
});

const authDetails = await getMsiTokenAuthRequest(["https://service/.default"], undefined, {
authResponse: [
{
status: 401,
headers: new HttpHeaders({
"www-authenticate": `we don't pay much attention about this format=${filePath}`
})
},
{
status: 200,
parsedBody: {
token: "token",
expires_in: 1
writeFileSync(tempFile, key, { encoding: "utf8" });

try {
const authDetails = await getMsiTokenAuthRequest(["https://service/.default"], undefined, {
authResponse: [
{
status: 401,
headers: new HttpHeaders({
"www-authenticate": `we don't pay much attention about this format=${tempFile}`
})
},
{
status: 200,
parsedBody: {
token: "token",
expires_in: 1
}
}
}
]
});

// File request
const validationRequest = authDetails.requests[0];
assert.ok(validationRequest.query, "No query string parameters on request");
]
});

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

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

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

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

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

assert.equal(authRequest.headers.get("Authorization"), `Basic ${key}`);
if (authDetails.token) {
// We use Date.now underneath.
assert.equal(
Math.floor(authDetails.token.expiresOnTimestamp / 1000000),
Math.floor(Date.now() / 1000000)
assert.ok(
authRequest.url.startsWith(process.env.IDENTITY_ENDPOINT),
"URL does not start with expected host and path"
);
} else {
assert.fail("No token was returned!");

assert.equal(authRequest.headers.get("Authorization"), `Basic ${key}`);
if (authDetails.token) {
// We use Date.now underneath.
assert.equal(
Math.floor(authDetails.token.expiresOnTimestamp / 1000000),
Math.floor(Date.now() / 1000000)
);
} else {
assert.fail("No token was returned!");
}
} finally {
unlinkSync(tempFile);
rmdirSync(tempDir);
}
});

Expand Down

0 comments on commit 54c6689

Please sign in to comment.