From 5eefe9f206c4077c352ae2c8a939b9f19e53973e Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Wed, 24 Jan 2024 17:41:46 -0500 Subject: [PATCH 1/4] ready for review --- src/mongo_logger.ts | 23 +++++++++++--- ...mmand_logging_and_monitoring.prose.test.ts | 12 +++---- test/unit/mongo_logger.test.ts | 31 ++++++++++++++++--- 3 files changed, 51 insertions(+), 15 deletions(-) diff --git a/src/mongo_logger.ts b/src/mongo_logger.ts index 6ffcee304a5..aaf8d91e4c8 100644 --- a/src/mongo_logger.ts +++ b/src/mongo_logger.ts @@ -420,10 +420,25 @@ export function stringifyWithMaxLen( ): string { let strToTruncate = ''; - try { - strToTruncate = typeof value !== 'function' ? EJSON.stringify(value, options) : value.name; - } catch (e) { - strToTruncate = `Extended JSON serialization failed with: ${e.message}`; + if (typeof value === 'string') { + strToTruncate = value; + } else if (typeof value === 'function') { + strToTruncate = value.toString(); + } else { + strToTruncate = EJSON.stringify(value, options); + } + + // handle truncation that occurs in the middle of multi-byte codepoints + if ( + maxDocumentLength !== 0 && + strToTruncate.length > maxDocumentLength && + strToTruncate.charCodeAt(maxDocumentLength - 1) !== + strToTruncate.codePointAt(maxDocumentLength - 1) + ) { + maxDocumentLength--; + if (maxDocumentLength === 0) { + return ''; + } } return maxDocumentLength !== 0 && strToTruncate.length > maxDocumentLength diff --git a/test/integration/command-logging-and-monitoring/command_logging_and_monitoring.prose.test.ts b/test/integration/command-logging-and-monitoring/command_logging_and_monitoring.prose.test.ts index b6a841b26e3..22857a6cc38 100644 --- a/test/integration/command-logging-and-monitoring/command_logging_and_monitoring.prose.test.ts +++ b/test/integration/command-logging-and-monitoring/command_logging_and_monitoring.prose.test.ts @@ -156,7 +156,7 @@ describe('Command Logging and Monitoring Prose Tests', function () { }); }); - context.skip('Truncation with multi-byte codepoints', function () { + context('Truncation with multi-byte codepoints', function () { /* A specific test case is not provided here due to the allowed variations in truncation logic as well as varying extended JSON whitespace usage. @@ -216,12 +216,12 @@ describe('Command Logging and Monitoring Prose Tests', function () { ); // multi-byte codepoint in middle of truncated string - expect(insertManyCommandStarted?.command.charCodeAt(maxDocLength - 1)).to.equal( - firstByteChar - ); - expect(insertManyCommandStarted?.command.charCodeAt(maxDocLength - 1)).to.equal( + expect(insertManyCommandStarted?.command.charCodeAt(maxDocLength - 2)).to.equal( secondByteChar ); + expect(insertManyCommandStarted?.command.charCodeAt(maxDocLength - 3)).to.equal( + firstByteChar + ); const insertManyCommandSucceeded = writable.buffer[1]; expect(insertManyCommandSucceeded?.message).to.equal('Command succeeded'); @@ -230,5 +230,5 @@ describe('Command Logging and Monitoring Prose Tests', function () { maxDocLength + ELLIPSES_LENGTH ); }); - }).skipReason = 'todo(NODE-5839)'; + }); }); diff --git a/test/unit/mongo_logger.test.ts b/test/unit/mongo_logger.test.ts index 7a6e1b2da9b..eb32c38e517 100644 --- a/test/unit/mongo_logger.test.ts +++ b/test/unit/mongo_logger.test.ts @@ -1268,14 +1268,36 @@ describe('class MongoLogger', async function () { context('when maxDocumentLength is non-zero', function () { context('when document has length greater than maxDocumentLength', function () { - it('truncates ejson string to length of maxDocumentLength + 3', function () { - expect(stringifyWithMaxLen(largeDoc, DEFAULT_MAX_DOCUMENT_LENGTH)).to.have.lengthOf( - DEFAULT_MAX_DOCUMENT_LENGTH + 3 - ); + context('when truncation does not occur mid-multibyte codepoint', function () { + it('truncates ejson string to length of maxDocumentLength + 3', function () { + expect(stringifyWithMaxLen(largeDoc, DEFAULT_MAX_DOCUMENT_LENGTH)).to.have.lengthOf( + DEFAULT_MAX_DOCUMENT_LENGTH + 3 + ); + }); }); + it('ends with "..."', function () { expect(stringifyWithMaxLen(largeDoc, DEFAULT_MAX_DOCUMENT_LENGTH)).to.match(/^.*\.\.\.$/); }); + + context('when truncation occurs mid-multibyte codepoint', function () { + const multiByteCodePoint = '\ud83d\ude0d'; // heart eyes emoji + context('when maxDocumentLength = 1 but greater than 0', function () { + it('should return an empty string', function () { + expect(stringifyWithMaxLen(multiByteCodePoint, 1, { relaxed: true })).to.equal(''); + }); + }); + + context('when maxDocumentLength > 1', function () { + it('should round down maxDocLength to previous codepoint', function () { + const randomString = `random ${multiByteCodePoint}random random${multiByteCodePoint}${multiByteCodePoint}`; + const randomStringMinusACodePoint = `random ${multiByteCodePoint}random random${multiByteCodePoint}`; + expect( + stringifyWithMaxLen(randomString, randomString.length - 1, { relaxed: true }) + ).to.equal(`${randomStringMinusACodePoint}...`); + }); + }); + }); }); context('when document has length less than or equal to maxDocumentLength', function () { @@ -1289,7 +1311,6 @@ describe('class MongoLogger', async function () { /^.*\.\.\./ ); }); - it('produces valid relaxed EJSON', function () { expect(() => { EJSON.parse(stringifyWithMaxLen(smallDoc, DEFAULT_MAX_DOCUMENT_LENGTH)); From 99dfafa9e3517d304a2d5fdb936df79d2c3af7e0 Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Thu, 25 Jan 2024 11:10:37 -0500 Subject: [PATCH 2/4] anna's suggestion --- test/unit/mongo_logger.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/mongo_logger.test.ts b/test/unit/mongo_logger.test.ts index eb32c38e517..0d60cf4d076 100644 --- a/test/unit/mongo_logger.test.ts +++ b/test/unit/mongo_logger.test.ts @@ -1290,8 +1290,8 @@ describe('class MongoLogger', async function () { context('when maxDocumentLength > 1', function () { it('should round down maxDocLength to previous codepoint', function () { - const randomString = `random ${multiByteCodePoint}random random${multiByteCodePoint}${multiByteCodePoint}`; const randomStringMinusACodePoint = `random ${multiByteCodePoint}random random${multiByteCodePoint}`; + const randomString = `${randomStringMinusACodePoint}${multiByteCodePoint}`; expect( stringifyWithMaxLen(randomString, randomString.length - 1, { relaxed: true }) ).to.equal(`${randomStringMinusACodePoint}...`); From d39f0e490a898d452ced32128d960c42345cfbef Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Thu, 25 Jan 2024 16:47:30 -0500 Subject: [PATCH 3/4] try catch to help with rebase: --- src/mongo_logger.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/mongo_logger.ts b/src/mongo_logger.ts index aaf8d91e4c8..744a5a4d27d 100644 --- a/src/mongo_logger.ts +++ b/src/mongo_logger.ts @@ -425,7 +425,11 @@ export function stringifyWithMaxLen( } else if (typeof value === 'function') { strToTruncate = value.toString(); } else { - strToTruncate = EJSON.stringify(value, options); + try { + strToTruncate = EJSON.stringify(value, options); + } catch (e) { + strToTruncate = `Extended JSON serialization failed with: ${e.message}`; + } } // handle truncation that occurs in the middle of multi-byte codepoints From 5f9a1fff58b5b11288a2ffbd2753f6e5824bff74 Mon Sep 17 00:00:00 2001 From: Aditi Khare Date: Fri, 26 Jan 2024 10:15:20 -0500 Subject: [PATCH 4/4] rebase fix --- src/mongo_logger.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mongo_logger.ts b/src/mongo_logger.ts index 744a5a4d27d..57864c4c4ef 100644 --- a/src/mongo_logger.ts +++ b/src/mongo_logger.ts @@ -423,7 +423,7 @@ export function stringifyWithMaxLen( if (typeof value === 'string') { strToTruncate = value; } else if (typeof value === 'function') { - strToTruncate = value.toString(); + strToTruncate = value.name; } else { try { strToTruncate = EJSON.stringify(value, options);