Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[identity] Use esm4mocha, re-enable IBC test, remove unnecessary stub #28580

Merged
merged 8 commits into from
Feb 15, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 7 additions & 22 deletions common/config/rush/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 8 additions & 1 deletion common/tools/dev-tool/src/commands/run/testNodeJSInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,21 @@ export const commandInfo = makeCommandInfo(
default: false,
description: "whether to run with test-proxy",
},
"no-esm": {
shortName: "nesm",
kind: "boolean",
maorleger marked this conversation as resolved.
Show resolved Hide resolved
default: false,
description: "whether to skip loading the esm package",
},
},
);

export default leafCommand(commandInfo, async (options) => {
console.log(options);
const reporterArgs =
"--reporter ../../../common/tools/mocha-multi-reporter.js --reporter-option output=test-results.xml";
const defaultMochaArgs = `${
(await isModuleProject())
options["no-esm"] === true || (await isModuleProject())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking to use an option to toggle between the two workarounds, for example with --no-esm=true and if it is not module project, we would have "--loader=../../../esm4mocha.mjs -r source-map-support/register" so we don't have to pass the loader option in the package's NPM script.

? "-r source-map-support/register.js"
: "-r ../../../common/tools/esm-workaround -r esm -r source-map-support/register"
} ${reporterArgs} --full-trace`;
Expand Down
8 changes: 5 additions & 3 deletions common/tools/esm4mocha.mjs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

import { readFile, stat, constants } from "node:fs/promises";
import { constants, readFile, stat } from "node:fs/promises";
import { dirname, join } from "node:path";
import { fileURLToPath } from "url";

import { Project } from "./dev-tool/node_modules/ts-morph/dist/ts-morph.js";
import { fileURLToPath } from "url";

// if modules are loaded from dist-esm/ treat them as ESM
export async function resolve(specifier, context, defaultResolve) {
Expand Down Expand Up @@ -32,7 +33,8 @@ export async function load(url, context, defaultLoad) {
};
}
const { source } = await defaultLoad(url, context, defaultLoad);
return { format: context.format, source, shortCircuit: true };
const format = context.format ?? "builtin";
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

node:fs/promises wasn't importing correctly for me. I was thinking it's fine to default to builtin? Alternatively I can also do something like:

const format = context.format
if (format === undefined && url.startsWith("node:")) format = "builtin"

Or if anyone has a better suggestion, I am not too familiar with loader logic

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interesting! My changes are barely minimum to get many packages test running. I am sure there are cases that aren't handled properly. If buildin works we will use it!

return { format, source, shortCircuit: true };
}

async function updateSpecifierValueIfRelative(declaration, base) {
Expand Down
2 changes: 1 addition & 1 deletion sdk/communication/communication-identity/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@
"@azure/dev-tool": "^1.0.0",
"@azure/eslint-plugin-azure-sdk": "^3.0.0",
"@azure/identity": "^4.0.1",
"@azure/msal-node": "^1.3.0",
"@azure/msal-node": "^2.5.1",
"@azure/test-utils": "^1.0.0",
"@microsoft/api-extractor": "^7.31.1",
"@types/chai": "^4.1.6",
Expand Down
2 changes: 1 addition & 1 deletion sdk/identity/identity/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"format": "dev-tool run vendored prettier --write --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"samples-dev/**/*.ts\" \"*.{js,json}\"",
"check-format": "dev-tool run vendored prettier --list-different --config ../../../.prettierrc.json --ignore-path ../../../.prettierignore \"src/**/*.ts\" \"test/**/*.ts\" \"samples-dev/**/*.ts\" \"*.{js,json}\"",
"integration-test:browser": "echo skipped",
"integration-test:node": "dev-tool run test:node-js-input -- --timeout 180000 'dist-esm/test/public/node/*.spec.js' 'dist-esm/test/internal/node/*.spec.js'",
"integration-test:node": "dev-tool run test:node-js-input --no-esm=true -- --loader=../../../common/tools/esm4mocha.mjs --timeout 180000 'dist-esm/test/public/node/*.spec.js' 'dist-esm/test/internal/node/*.spec.js'",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

identity's integration tests use the recordings as well, for <reasons>, so we need the test proxy running. Easiest way is to keep using dev-tool commands

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I was going to add an option then switch most of our packages over to use that. Eventually also would like to make using the loader default behavior. --no-esm doesn't sound like a great name but I haven't got a better one either.

Copy link
Member Author

@maorleger maorleger Feb 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking maybe something like "loader" with a default of esm?

Then, you could omit it for existing behavior or pass --loader=esm4mocha for the new mocha loader. Maybe that would be nicer? I'll push that up shortly because I also don't love "no-esm" - let me know how that looks once I push the changes up!

Once we are comfortable we can make the default value esm4mocha and everyone will just get it

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel that --loader= may be confusing, sounding like you could pass any strings there but they get ignored. How about --use-esm-workaround=false with default value of true? I think there are only a handful packages that doesn't work immediately now with the esm4mocha loader. Once I switch majority over, I can make the default value false then added ``--use-esm-workaround=true` to those a few packages.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah good point and I agree with loader being confusing... let me push up a change with your suggestion and we can see if that reads better 👍

"integration-test": "npm run integration-test:node && npm run integration-test:browser",
"lint:fix": "eslint package.json api-extractor.json src test --ext .ts --fix --fix-type [problem,suggestion]",
"lint": "eslint package.json api-extractor.json src test --ext .ts",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ describe("ClientAssertionCredential (internal)", function () {
await credential.getToken("https://vault.azure.net/.default");
} catch (e: any) {
// We're ignoring errors since our main goal here is to ensure that we send the correct parameters to MSAL.
console.log("error", e);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adds noise, if we're ignoring it let's ignore it

}

assert.equal(getTokenSilentSpy.callCount, 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ describe("ClientCertificateCredential (internal)", function () {
});

it("throws when given a file that doesn't contain a PEM-formatted certificate", async function (this: Context) {
const fullPath = path.resolve(__dirname, "../src/index.ts");
const fullPath = path.resolve("./clientCertificateCredential.spec.ts");
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

__dirname is not supported, but it doesn't actually matter what file we send as long as it's not a proper cert

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah __dirname is blocking some packages' test too. There's recommendation of const __dirname=path.dirname(url.fileURLToPath(import.meta.url) but import.meta.url requires "module" of "ES2020", which is at odds with our module of commonjs for test:node-ts-input :(

const credential = new ClientCertificateCredential("tenant", "client", {
certificatePath: fullPath,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
/* eslint-disable @typescript-eslint/no-non-null-asserted-optional-chain */
/* eslint-disable @typescript-eslint/no-namespace */

import { MsalTestCleanup, msalNodeTestSetup } from "../../node/msalNodeTestSetup";
import { Recorder, env } from "@azure-tools/test-recorder";
import { Context } from "mocha";
import {
InteractiveBrowserCredential,
InteractiveBrowserCredentialNodeOptions,
} from "../../../src";
import { MsalTestCleanup, msalNodeTestSetup } from "../../node/msalNodeTestSetup";
import { Recorder, env } from "@azure-tools/test-recorder";

import { Context } from "mocha";
import Sinon from "sinon";
import { assert } from "chai";
import http from "http";
Expand Down Expand Up @@ -46,9 +46,7 @@ describe("InteractiveBrowserCredential (internal)", function () {

const scope = "https://vault.azure.net/.default";

// TODO: re-enable this when we resolve the esm incompatibility issues
// https://github.com/Azure/azure-sdk-for-js/issues/28373
it.skip("Throws an expected error if no browser is available", async function (this: Context) {
it("Throws an expected error if no browser is available", async function (this: Context) {
// The SinonStub type does not include this second parameter to throws().
const testErrorMessage = "No browsers available on this test.";
(sandbox.stub(interactiveBrowserMockable, "open") as any).throws(
Expand Down
10 changes: 5 additions & 5 deletions sdk/identity/identity/test/node/msalNodeTestSetup.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import * as util from "../../src/msal/utils";

import {
AuthenticationResult,
ConfidentialClientApplication,
Expand Down Expand Up @@ -46,9 +44,6 @@ export async function msalNodeTestSetup(

const sandbox = createSandbox();

const stub = sandbox.stub(util, "randomUUID");
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just a better world to live in, no weird wrapping and no concerns with immutable modules

stub.returns(playbackValues.correlationId);

if (testContextOrStubbedToken instanceof Test || testContextOrStubbedToken === undefined) {
const testContext = testContextOrStubbedToken;

Expand Down Expand Up @@ -132,6 +127,11 @@ export async function msalNodeTestSetup(
target: `x-client-VER=[a-zA-Z0-9.-]+`,
value: `x-client-VER=identity-client-version`,
},
{
regex: true,
target: `client-request-id=[a-zA-Z0-9-]+`,
value: `client-request-id=${playbackValues.correlationId}`,
},
],
bodyKeySanitizers: [
{
Expand Down
3 changes: 2 additions & 1 deletion sdk/identity/identity/test/public/node/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
// Licensed under the MIT license.

import * as fs from "fs";
import * as jwt from "jsonwebtoken";
import * as net from "net";
import * as tls from "tls";

import jwt from "jsonwebtoken";
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be the default export to work

import ms from "ms";
import { randomUUID } from "@azure/core-util";

Expand Down
Loading