SERVER-112107: Accept and validate startTime and endTime (#42352)

GitOrigin-RevId: 72e660e02b1e9114724e1d96fe03465f8f626d26
This commit is contained in:
James H 2025-10-22 21:44:48 +01:00 committed by MongoDB Bot
parent 42620e46f3
commit 6aeadcba8a
3 changed files with 88 additions and 0 deletions

View File

@ -216,3 +216,64 @@ function runTest(client, restartCommand) {
removeFile(dirB);
}
}
// Ensure startTrafficRecording validates startTime and endTime
{
const path = MongoRunner.toRealDir("$dataDir/traffic_recording/");
let recordingDir = path + "/recordings/";
removeFile(recordingDir);
mkdir(recordingDir);
let m = MongoRunner.runMongod({auth: "", setParameter: {trafficRecordingDirectory: path, enableTestCommands: 1}});
let db = m.getDB("admin");
db.createUser({user: "admin", pwd: "pass", roles: jsTest.adminUserRoles});
db.auth("admin", "pass");
const nowPlusDays = (days) => {
const now = new Date();
const milliseconds = days * 24 * 60 * 60 * 1000;
return new Date(now.getTime() + milliseconds);
};
// No start or end time - allowed.
assert.commandWorked(db.runCommand({"startTrafficRecording": 1, "destination": "recordings"}));
assert.commandWorked(db.runCommand({"stopTrafficRecording": 1}));
// start time < 1 day in the future, end time > start time && end time < 10 days in the future -
// allowed.
assert.commandWorked(
db.runCommand({
"startTrafficRecording": 1,
"destination": "recordings",
startTime: nowPlusDays(0.5),
endTime: nowPlusDays(2),
}),
);
// Cancelling early is permitted.
assert.commandWorked(db.runCommand({"stopTrafficRecording": 1}));
const expectFailure = (params) => {
assert.commandFailedWithCode(
db.runCommand({"startTrafficRecording": 1, "destination": "recordings", ...params}),
ErrorCodes.BadValue,
);
};
// Only start.
expectFailure({startTime: nowPlusDays(0.5)});
// Only end.
expectFailure({endTime: nowPlusDays(2)});
// Starts too late.
expectFailure({startTime: nowPlusDays(1.5), endTime: nowPlusDays(2)});
// Ends too late.
expectFailure({startTime: nowPlusDays(0.5), endTime: nowPlusDays(20)});
// Both.
expectFailure({startTime: nowPlusDays(1.5), endTime: nowPlusDays(20)});
MongoRunner.stopMongod(m, null, {user: "admin", pwd: "pass"});
removeFile(recordingDir);
}

View File

@ -52,6 +52,7 @@
#include "mongo/stdx/thread.h"
#include "mongo/util/assert_util.h"
#include "mongo/util/decorable.h"
#include "mongo/util/duration.h"
#include "mongo/util/net/hostandport.h"
#include "mongo/util/producer_consumer_queue.h"
#include "mongo/util/tick_source.h"
@ -300,6 +301,24 @@ std::shared_ptr<TrafficRecorder::Recording> TrafficRecorder::_makeRecording(
}
void TrafficRecorder::start(const StartTrafficRecording& options, ServiceContext* svcCtx) {
uassert(ErrorCodes::BadValue,
"startTime and endTime should both be provided, or neither",
options.getStartTime().has_value() == options.getEndTime().has_value());
if (options.getStartTime().has_value()) {
auto start = *options.getStartTime();
auto end = *options.getEndTime();
uassert(ErrorCodes::BadValue,
"startTime should be in the future, and less than 1 day into the future",
start > Date_t::now() && start < (Date_t::now() + Days(1)));
uassert(ErrorCodes::BadValue,
"endTime should be after startTime, and less than 10 days into the future",
end > start && end < (Date_t::now() + Days(10)));
}
_prepare(options, svcCtx);
_start(svcCtx);
}

View File

@ -92,6 +92,14 @@ commands:
description: "max additional memory the recording is allowed to use"
default: 134217728
type: numBytes
startTime:
description: "Future time to start the recording"
optional: true
type: date
endTime:
description: "Future time to halt the recording"
optional: true
type: date
stopTrafficRecording:
description: "stop recording Command"