text: /**
   * Test that verifies FTDC works in mongos.
   * @tags: [requires_sharding]
   */
  load('jstests/libs/ftdc.js');
  
  (function() {
      'use strict';
      let testPath1 = MongoRunner.toRealPath('ftdc_setdir1');
      let testPath2 = MongoRunner.toRealPath('ftdc_setdir2');
      let testPath3 = MongoRunner.toRealPath('ftdc_setdir3');
      // SERVER-30394: Use a directory relative to the current working directory.
      let testPath4 = 'ftdc_setdir4/';
      let testLog3 = testPath3 + "mongos_ftdc.log";
      let testLog4 = testPath4 + "mongos_ftdc.log";
  
      // Make the log file directory for mongos.
      mkdir(testPath3);
      mkdir(testPath4);
  
      // Startup 3 mongos:
      // 1. Normal MongoS with no log file to verify FTDC can be startup at runtime with a path.
      // 2. MongoS with explict diagnosticDataCollectionDirectoryPath setParameter at startup.
      // 3. MongoS with log file to verify automatic FTDC path computation works.
      let st = new ShardingTest({
          shards: 1,
          mongos: {
              s0: {verbose: 0},
              s1: {setParameter: {diagnosticDataCollectionDirectoryPath: testPath2}},
              s2: {logpath: testLog3},
              s3: {logpath: testLog4}
          }
      });
  
      let admin1 = st.s0.getDB('admin');
      let admin2 = st.s1.getDB('admin');
      let admin3 = st.s2.getDB('admin');
      let admin4 = st.s3.getDB('admin');
  
      function setParam(admin, obj) {
          var ret = admin.runCommand(Object.extend({setParameter: 1}, obj));
          return ret;
      }
  
      function getParam(admin, field) {
          var q = {getParameter: 1};
          q[field] = 1;
  
          var ret = admin.runCommand(q);
          assert.commandWorked(ret);
          return ret[field];
      }
  
      // Verify FTDC can be started at runtime.
      function verifyFTDCDisabledOnStartup() {
          jsTestLog("Running verifyFTDCDisabledOnStartup");
          verifyCommonFTDCParameters(admin1, false);
  
          // 1. Try to enable and fail
          assert.commandFailed(setParam(admin1, {"diagnosticDataCollectionEnabled": 1}));
  
          // 2. Set path and succeed
          assert.commandWorked(
              setParam(admin1, {"diagnosticDataCollectionDirectoryPath": testPath1}));
  
          // 3. Set path again and fail
          assert.commandFailed(
              setParam(admin1, {"diagnosticDataCollectionDirectoryPath": testPath1}));
  
          // 4. Enable successfully
          assert.commandWorked(setParam(admin1, {"diagnosticDataCollectionEnabled": 1}));
  
          // 5. Validate getDiagnosticData returns FTDC data now
          jsTestLog("Verifying FTDC getDiagnosticData");
          verifyGetDiagnosticData(admin1);
      }
  
      // Verify FTDC is already running if there was a path set at startup.
      function verifyFTDCStartsWithPath() {
          jsTestLog("Running verifyFTDCStartsWithPath");
          verifyCommonFTDCParameters(admin2, true);
  
          // 1. Set path fail
          assert.commandFailed(
              setParam(admin2, {"diagnosticDataCollectionDirectoryPath": testPath2}));
  
          // 2. Enable successfully
          assert.commandWorked(setParam(admin2, {"diagnosticDataCollectionEnabled": 1}));
  
          // 3. Validate getDiagnosticData returns FTDC data now
          jsTestLog("Verifying FTDC getDiagnosticData");
          verifyGetDiagnosticData(admin2);
      }
  
      function normpath(path) {
          // On Windows, strip the drive path because MongoRunner.toRealPath() returns a Unix Path
          // while FTDC returns a Windows path.
          return path.replace(/\\/g, "/").replace(/\w:/, "");
      }
  
      // Verify FTDC is already running if there was a path set at startup.
      function verifyFTDCStartsWithLogFile() {
          jsTestLog("Running verifyFTDCStartsWithLogFile");
          verifyCommonFTDCParameters(admin3, true);
  
          // 1. Verify that path is computed correctly.
          let computedPath = getParam(admin3, "diagnosticDataCollectionDirectoryPath");
          assert.eq(normpath(computedPath), normpath(testPath3 + "mongos_ftdc.diagnostic.data"));
  
          // 2. Set path fail
          assert.commandFailed(
              setParam(admin3, {"diagnosticDataCollectionDirectoryPath": testPath3}));
  
          // 3. Enable successfully
          assert.commandWorked(setParam(admin3, {"diagnosticDataCollectionEnabled": 1}));
  
          // 4. Validate getDiagnosticData returns FTDC data now
          jsTestLog("Verifying FTDC getDiagnosticData");
          verifyGetDiagnosticData(admin3);
      }
  
      // Verify FTDC is already running if there is a relative log file path.
      function verifyFTDCStartsWithRelativeLogFile() {
          jsTestLog("Running verifyFTDCStartsWithRelativeLogFile");
          verifyCommonFTDCParameters(admin4, true);
  
          // Skip verification of diagnosticDataCollectionDirectoryPath because it relies on comparing
          // cwd vs dbPath.
  
          // 1. Enable successfully
          assert.commandWorked(setParam(admin4, {"diagnosticDataCollectionEnabled": 1}));
  
          // 2. Validate getDiagnosticData returns FTDC data now
          jsTestLog("Verifying FTDC getDiagnosticData");
          verifyGetDiagnosticData(admin4);
      }
  
      verifyFTDCDisabledOnStartup();
      verifyFTDCStartsWithPath();
      verifyFTDCStartsWithLogFile();
      verifyFTDCStartsWithRelativeLogFile();
  
      st.stop();
  })();
  