diff options
Diffstat (limited to 'jstests/watchdog/lib/charybdefs_lib.js')
-rw-r--r-- | jstests/watchdog/lib/charybdefs_lib.js | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/jstests/watchdog/lib/charybdefs_lib.js b/jstests/watchdog/lib/charybdefs_lib.js new file mode 100644 index 00000000000..f80246426d8 --- /dev/null +++ b/jstests/watchdog/lib/charybdefs_lib.js @@ -0,0 +1,127 @@ +// Exit code that the watchdog uses on exit +const EXIT_WATCHDOG = 61; + +/** + * Control the Charybdefs file system for Fault Injectiong testing + * + * @param {string} test_name unique name for test directories + */ +function CharybdefsControl(test_name) { + 'use strict'; + + const python = "/opt/mongodbtoolchain/v3/bin/python3"; + let control_py = "/data/charybdefs/mongo/control.py"; + + // Use the minimum watchdog period + const wd_period_sec = 60; + + // Since the watchdog can take up to (2 x period) to detect failures, stall the write for that + // amount of time plus a small buffer of time to account for thread scheduling, etc. + const fs_delay_sec = wd_period_sec * 2 + 5; + + const mount_point = MongoRunner.toRealPath(test_name + '_mnt'); + const backing_path = MongoRunner.toRealPath(test_name + '_backing'); + + this._runControl = function(cmd, ...args) { + let cmd_args = [python, control_py, cmd]; + cmd_args = cmd_args.concat(args); + let ret = run.apply(null, cmd_args); + assert.eq(ret, 0); + }; + + /** + * Get the path of the mounted Charybdefs file system. + * + * @return {string} mount point + */ + this.getMountPath = function() { + return mount_point; + }; + + /** + * Get the Watchdog Period. + * + * @return {number} number of sections + */ + this.getWatchdogPeriodSeconds = function() { + return wd_period_sec; + }; + + /** + * Start the Charybdefs filesystem. + */ + this.start = function() { + this.cleanup(); + + this._runControl("start", + "--fuse_mount=" + mount_point, + "--backing_path=" + backing_path, + "--log_file=foo_fs.log"); + print("Charybdefs sucessfully started."); + }; + + // Get the current check generation + function _getGeneration(admin) { + const result = admin.runCommand({"serverStatus": 1}); + + assert.commandWorked(result); + + return result.watchdog.checkGeneration; + } + + /** + * Wait for the watchdog to run some checks first. + * + * @param {object} MongoDB connection to admin database + */ + this.waitForWatchdogToStart = function(admin) { + print("Waiting for MongoDB watchdog to checks run twice."); + assert.soon(function() { + return _getGeneration(admin) > 2; + }, "Watchdog did not start running", 5 * wd_period_sec * 1000); + }; + + /** + * Inject delay on write, and wait to MongoDB to get hung. + * + * @param {string} file_name - file name to inject fault on + */ + this.addWriteDelayFaultAndWait = function(file_name) { + // Convert seconds to microseconds for charybdefs + const delay_us = fs_delay_sec * 1000000; + this.addFault("write_buf", file_name, delay_us); + + // Wait for watchdog to stop + print("Waiting for MongoDB to hang."); + sleep(fs_delay_sec * 1000); + + }; + + /** + * Add a fault to inject. + * + * @param {string} method - name of fuse method to inject fault for + * @param {string} file_name - file name to inject fault on + * @param {number} delay_us - optional delay in microseconds to wait + */ + this.addFault = function(method, file_name, delay_us) { + + this._runControl("set_fault", + "--methods=" + method, + "--errno=5", + "--probability=100000", + "--regexp=.*" + file_name, + "--delay_us=" + delay_us); + }; + + /** + * Shutdown and clean up the Charybdefs filesystem. + */ + this.cleanup = function() { + this._runControl("stop_all", "--fuse_mount=" + mount_point); + + // Delete any remaining files + resetDbpath(mount_point); + resetDbpath(backing_path); + }; +} |