Fix CloudShell terminal hanging for Mongo and Cassandra shells due to missing updateTerminalData method (#2199)

This commit is contained in:
BChoudhury-ms 2025-08-14 01:32:27 +05:30 committed by GitHub
parent 3afd74a957
commit 012d043c78
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 52 additions and 16 deletions

View File

@ -33,6 +33,7 @@ jest.mock("../../../../UserContext", () => ({
})); }));
jest.mock("../Utils/CommonUtils", () => ({ jest.mock("../Utils/CommonUtils", () => ({
...jest.requireActual("../Utils/CommonUtils"),
getHostFromUrl: jest.fn().mockReturnValue("test-mongo.documents.azure.com"), getHostFromUrl: jest.fn().mockReturnValue("test-mongo.documents.azure.com"),
})); }));
@ -124,7 +125,10 @@ describe("MongoShellHandler", () => {
describe("getTerminalSuppressedData", () => { describe("getTerminalSuppressedData", () => {
it("should return the correct warning message", () => { it("should return the correct warning message", () => {
expect(mongoShellHandler.getTerminalSuppressedData()).toEqual(["Warning: Non-Genuine MongoDB Detected"]); expect(mongoShellHandler.getTerminalSuppressedData()).toEqual([
"Warning: Non-Genuine MongoDB Detected",
"Telemetry is now disabled.",
]);
}); });
}); });
}); });

View File

@ -1,10 +1,11 @@
import { userContext } from "../../../../UserContext"; import { userContext } from "../../../../UserContext";
import { getHostFromUrl } from "../Utils/CommonUtils"; import { filterAndCleanTerminalOutput, getHostFromUrl, getMongoShellRemoveInfoText } from "../Utils/CommonUtils";
import { AbstractShellHandler, DISABLE_TELEMETRY_COMMAND } from "./AbstractShellHandler"; import { AbstractShellHandler, DISABLE_TELEMETRY_COMMAND } from "./AbstractShellHandler";
export class MongoShellHandler extends AbstractShellHandler { export class MongoShellHandler extends AbstractShellHandler {
private _key: string; private _key: string;
private _endpoint: string | undefined; private _endpoint: string | undefined;
private _removeInfoText: string[] = getMongoShellRemoveInfoText();
constructor(private key: string) { constructor(private key: string) {
super(); super();
this._key = key; this._key = key;
@ -44,6 +45,10 @@ export class MongoShellHandler extends AbstractShellHandler {
} }
public getTerminalSuppressedData(): string[] { public getTerminalSuppressedData(): string[] {
return ["Warning: Non-Genuine MongoDB Detected"]; return ["Warning: Non-Genuine MongoDB Detected", "Telemetry is now disabled."];
}
updateTerminalData(data: string): string {
return filterAndCleanTerminalOutput(data, this._removeInfoText);
} }
} }

View File

@ -1,13 +1,10 @@
import { userContext } from "../../../../UserContext"; import { userContext } from "../../../../UserContext";
import { filterAndCleanTerminalOutput, getMongoShellRemoveInfoText } from "../Utils/CommonUtils";
import { AbstractShellHandler, DISABLE_TELEMETRY_COMMAND } from "./AbstractShellHandler"; import { AbstractShellHandler, DISABLE_TELEMETRY_COMMAND } from "./AbstractShellHandler";
export class VCoreMongoShellHandler extends AbstractShellHandler { export class VCoreMongoShellHandler extends AbstractShellHandler {
private _endpoint: string | undefined; private _endpoint: string | undefined;
private _textFilterRules: string[] = [ private _removeInfoText: string[] = getMongoShellRemoveInfoText();
"For mongosh info see: https://www.mongodb.com/docs/mongodb-shell/",
"disableTelemetry() command",
"https://www.mongodb.com/legal/privacy-policy",
];
constructor() { constructor() {
super(); super();
@ -38,12 +35,7 @@ export class VCoreMongoShellHandler extends AbstractShellHandler {
return ["Warning: Non-Genuine MongoDB Detected", "Telemetry is now disabled."]; return ["Warning: Non-Genuine MongoDB Detected", "Telemetry is now disabled."];
} }
updateTerminalData(content: string): string { updateTerminalData(data: string): string {
const updatedContent = content return filterAndCleanTerminalOutput(data, this._removeInfoText);
.split("\n")
.filter((line) => !this._textFilterRules.some((part) => line.includes(part)))
.filter((line, idx, arr) => (arr.length > 3 && idx <= arr.length - 3 ? !["", "\r"].includes(line) : true)) // Filter out empty lines and carriage returns, but keep the last 3 lines if they exist
.join("\n");
return updatedContent;
} }
} }

View File

@ -135,7 +135,11 @@ export class AttachAddon implements ITerminalAddon {
} }
if (this._allowTerminalWrite) { if (this._allowTerminalWrite) {
const updatedData = this._shellHandler?.updateTerminalData(data) ?? data; const updatedData =
typeof this._shellHandler?.updateTerminalData === "function"
? this._shellHandler.updateTerminalData(data)
: data;
const suppressedData = this._shellHandler?.getTerminalSuppressedData(); const suppressedData = this._shellHandler?.getTerminalSuppressedData();
const shouldNotWrite = suppressedData.filter(Boolean).some((item) => updatedData.includes(item)); const shouldNotWrite = suppressedData.filter(Boolean).some((item) => updatedData.includes(item));

View File

@ -50,3 +50,34 @@ export const getShellNameForDisplay = (terminalKind: TerminalKind): string => {
return ""; return "";
} }
}; };
/**
* Get MongoDB shell information text that should be removed from terminal output
*/
export const getMongoShellRemoveInfoText = (): string[] => {
return [
"For mongosh info see: https://www.mongodb.com/docs/mongodb-shell/",
"disableTelemetry() command",
"https://www.mongodb.com/legal/privacy-policy",
];
};
export const filterAndCleanTerminalOutput = (data: string, removeInfoText: string[]): string => {
if (!data || removeInfoText.length === 0) {
return data;
}
const lines = data.split("\n");
const filteredLines: string[] = [];
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
const shouldRemove = removeInfoText.some((text) => line.includes(text));
if (!shouldRemove) {
filteredLines.push(line);
}
}
return filteredLines.join("\n").replace(/((\r\n)|\n|\r){2,}/g, "\r\n");
};