[Nexthop][fboss2-dev] Rewrite fboss2-dev CLI end-to-end tests in C++ with gtest#893
[Nexthop][fboss2-dev] Rewrite fboss2-dev CLI end-to-end tests in C++ with gtest#893benoit-nexthop wants to merge 1 commit into
Conversation
0e2ede9 to
de18a53
Compare
…p class # Summary This PR consolidates the separate CmdConfigInterfaceDescription and CmdConfigInterfaceMtu commands into a unified CmdConfigInterface command that can set multiple interface attributes in a single invocation. ``` # Set description config interface eth1/1/1 description "My port description" # Set MTU config interface eth1/1/1 mtu 9000 # Set both in one command config interface eth1/1/1 description "My port" mtu 9000 # Apply to multiple interfaces config interface eth1/1/1,eth1/2/1 description "Uplink" mtu 1500 ``` Original change by @hillol-nexthop ## Implementation Details 1. **New `InterfaceConfig` class** - Parses CLI tokens to separate port names from attribute key-value pairs - Supports description and mtu attributes (case-insensitive) - Validates attribute names and detects missing values - Wraps `InterfaceList` for port/interface resolution 2. **Updated CmdConfigInterface** - Changed from pass-through command to functional command - Implements `queryClient` to process description and mtu attributes - Sets `port->description()` for description attribute - Sets `interface->mtu()` for mtu attribute with validation 3. **Updated subcommands to use `InterfaceConfig` instead of `InterfaceList`** 4. **Deleted obsolete pairs of `.cpp` / `.h`** 5. **New comprehensive test suite** - 23 tests covering `InterfaceConfig` validation and `CmdConfigInterface::queryClient` functionality - Backward Compatibility - Subcommands like switchport, pfc-config, and queuing-policy continue to work as before # Test Plan **Note:** The e2e test is already implemented in facebook#893 Above mentioned list of new test file, deleted and updated test files. Existing unit and end to end tests pass. # Please enter the commit message for your changes. Lines starting # with '#' will be kept; you may remove them yourself if you want to. # An empty message aborts the commit. # # Author: hillol-nexthop <hillol@nexthop.ai> # Date: Tue Feb 10 18:53:21 2026 +0530 # # On branch fboss2-cli-prototype_part28 # Your branch is up to date with 'fork/fboss2-cli-prototype_part28'. # # Changes to be committed: # modified: cmake/CliFboss2.cmake # modified: cmake/CliFboss2Test.cmake # modified: fboss/cli/fboss2/BUCK # modified: fboss/cli/fboss2/CmdHandlerImplConfig.cpp # modified: fboss/cli/fboss2/CmdListConfig.cpp # modified: fboss/cli/fboss2/CmdSubcommands.cpp # new file: fboss/cli/fboss2/commands/config/interface/CmdConfigInterface.cpp # modified: fboss/cli/fboss2/commands/config/interface/CmdConfigInterface.h # deleted: fboss/cli/fboss2/commands/config/interface/CmdConfigInterfaceDescription.cpp # deleted: fboss/cli/fboss2/commands/config/interface/CmdConfigInterfaceDescription.h # deleted: fboss/cli/fboss2/commands/config/interface/CmdConfigInterfaceMtu.cpp # deleted: fboss/cli/fboss2/commands/config/interface/CmdConfigInterfaceMtu.h # modified: fboss/cli/fboss2/commands/config/interface/CmdConfigInterfaceQueuingPolicy.cpp # modified: fboss/cli/fboss2/commands/config/interface/CmdConfigInterfaceQueuingPolicy.h # modified: fboss/cli/fboss2/commands/config/interface/pfc_config/CmdConfigInterfacePfcConfig.cpp # modified: fboss/cli/fboss2/commands/config/interface/pfc_config/CmdConfigInterfacePfcConfig.h # modified: fboss/cli/fboss2/commands/config/interface/switchport/CmdConfigInterfaceSwitchport.h # modified: fboss/cli/fboss2/commands/config/interface/switchport/access/CmdConfigInterfaceSwitchportAccess.h # modified: fboss/cli/fboss2/commands/config/interface/switchport/access/vlan/CmdConfigInterfaceSwitchportAccessVlan.cpp # modified: fboss/cli/fboss2/commands/config/interface/switchport/access/vlan/CmdConfigInterfaceSwitchportAccessVlan.h # modified: fboss/cli/fboss2/test/BUCK # deleted: fboss/cli/fboss2/test/CmdConfigInterfaceDescriptionTest.cpp # deleted: fboss/cli/fboss2/test/CmdConfigInterfaceMtuTest.cpp # modified: fboss/cli/fboss2/test/CmdConfigInterfaceSwitchportAccessVlanTest.cpp # new file: fboss/cli/fboss2/test/CmdConfigInterfaceTest.cpp # modified: fboss/cli/fboss2/utils/CmdUtilsCommon.h # new file: fboss/cli/fboss2/utils/InterfacesConfig.cpp # new file: fboss/cli/fboss2/utils/InterfacesConfig.h #
…p class # Summary This PR consolidates the separate CmdConfigInterfaceDescription and CmdConfigInterfaceMtu commands into a unified CmdConfigInterface command that can set multiple interface attributes in a single invocation. ``` # Set description config interface eth1/1/1 description "My port description" # Set MTU config interface eth1/1/1 mtu 9000 # Set both in one command config interface eth1/1/1 description "My port" mtu 9000 # Apply to multiple interfaces config interface eth1/1/1,eth1/2/1 description "Uplink" mtu 1500 ``` Original change by @hillol-nexthop ## Implementation Details 1. **New `InterfaceConfig` class** - Parses CLI tokens to separate port names from attribute key-value pairs - Supports description and mtu attributes (case-insensitive) - Validates attribute names and detects missing values - Wraps `InterfaceList` for port/interface resolution 2. **Updated CmdConfigInterface** - Changed from pass-through command to functional command - Implements `queryClient` to process description and mtu attributes - Sets `port->description()` for description attribute - Sets `interface->mtu()` for mtu attribute with validation 3. **Updated subcommands to use `InterfaceConfig` instead of `InterfaceList`** 4. **Deleted obsolete pairs of `.cpp` / `.h`** 5. **New comprehensive test suite** - 23 tests covering `InterfaceConfig` validation and `CmdConfigInterface::queryClient` functionality - Backward Compatibility - Subcommands like switchport, pfc-config, and queuing-policy continue to work as before # Test Plan **Note:** The e2e test is already implemented in facebook#893 Above mentioned list of new test file, deleted and updated test files. Existing unit and end to end tests pass.
joseph5wu
left a comment
There was a problem hiding this comment.
Overall it matches what I would expect an end-to-end CLI test binary should look like.
Although this is the first diff, I can see there're some future improvements on how to write these tests in a more concise way. As most of the tests should follow the below steps:
- pick the subject for your tests. could be an interface, a vlan or a qos
- prepare the exact cli you wants to run and then execute
- call a validation function
- maybe we should also properly check the config version updated or config session infra logic in the test too
- restore the config
Hopefully with more and more tests you're about to add, you can consider what's a best way to make CliTest.cpp more structured and all the commands can reuse more of the code.
What's more, we should also introduce "batch cli" in your end-to-end tests; or cli with different action levels.
| // Force config reload from system config on next access | ||
| configLoaded_ = false; |
There was a problem hiding this comment.
Do we also need to clear commands_ and requiredActions_ like you did for line 639-642 above?
If so, can you make a private resetSession() function to make sure all the necessary variables get reset
There was a problem hiding this comment.
This change wasn't part of this PR. It was part of the PR adding rebase: #832
| #include <fmt/format.h> | ||
| #include <folly/Conv.h> | ||
| #include <folly/Demangle.h> | ||
| #include <folly/ScopeGuard.h> | ||
| #include <folly/Traits.h> | ||
| #include <folly/logging/xlog.h> | ||
| #include <folly/stop_watch.h> | ||
| #include <cstddef> | ||
| #include <cstdint> | ||
| #include <cstring> | ||
| #include <exception> | ||
| #include <future> | ||
| #include <iostream> | ||
| #include <map> | ||
| #include <memory> | ||
| #include <optional> | ||
| #include <queue> | ||
| #include <stdexcept> | ||
| #include <string> | ||
| #include <tuple> | ||
| #include <utility> | ||
| #include <vector> |
There was a problem hiding this comment.
Why suddenly includes so many libraries? Your change in the implementation below doesn't seem to rely on all these libraries
There was a problem hiding this comment.
This is adding already required headers. I generate the includes with clang-include-cleaner.
…p class This PR consolidates the separate CmdConfigInterfaceDescription and CmdConfigInterfaceMtu commands into a unified CmdConfigInterface command that can set multiple interface attributes in a single invocation. ``` config interface eth1/1/1 description "My port description" config interface eth1/1/1 mtu 9000 config interface eth1/1/1 description "My port" mtu 9000 config interface eth1/1/1,eth1/2/1 description "Uplink" mtu 1500 ``` Original change by @hillol-nexthop 1. **New `InterfaceConfig` class** - Parses CLI tokens to separate port names from attribute key-value pairs - Supports description and mtu attributes (case-insensitive) - Validates attribute names and detects missing values - Wraps `InterfaceList` for port/interface resolution 2. **Updated CmdConfigInterface** - Changed from pass-through command to functional command - Implements `queryClient` to process description and mtu attributes - Sets `port->description()` for description attribute - Sets `interface->mtu()` for mtu attribute with validation 3. **Updated subcommands to use `InterfaceConfig` instead of `InterfaceList`** 4. **Deleted obsolete pairs of `.cpp` / `.h`** 5. **New comprehensive test suite** - 23 tests covering `InterfaceConfig` validation and `CmdConfigInterface::queryClient` functionality - Backward Compatibility - Subcommands like switchport, pfc-config, and queuing-policy continue to work as before **Note:** The e2e test is already implemented in facebook#893 Above mentioned list of new test file, deleted and updated test files. Existing unit and end to end tests pass.
| /** | ||
| * Represents a network interface from the output of 'show interface'. | ||
| */ | ||
| struct Interface { |
There was a problem hiding this comment.
Let's put this inside CliTest class so it won't mess up with the real facebook::fboss::Interface
(https://github.com/facebook/fboss/blob/main/fboss/agent/state/Interface.h#L56)
There was a problem hiding this comment.
Done. Also move the CliResult class that was right before it, so that it became CliTest::Result.
| fs::path sessionDir = fs::path(home) / ".fboss2"; | ||
| fs::path sessionConfig = sessionDir / "agent.conf"; | ||
| fs::path sessionMetadata = sessionDir / "cli_metadata.json"; |
There was a problem hiding this comment.
Since we're touching files/folders for the fboss2 config cli, I think we should consider to introduce
something similar to
https://github.com/facebook/fboss/blob/main/fboss/agent/AgentDirectoryUtil.h
for our config related directory to store these static settings
Feel free to use future PR to address this improvement
| * @return MTU value, or -1 if interface not found | ||
| */ | ||
| int getKernelInterfaceMtu(int vlanId) const; | ||
|
|
There was a problem hiding this comment.
Since this function is only needed for the ConfigInterfaceMtuTest.cpp.
we don't have to define this method in the general CliTest.cpp.
We should set the standard that this CliTest.cpp only handles the common utility functions,
any other functions related to specific tests should be handled in their own test classes.
There was a problem hiding this comment.
I put it here because I felt like it was likely to be needed for other tests in the future.
| int cliTestMain(int argc, char** argv) { | ||
| // Initialize gtest first so it consumes --gtest_* flags before folly::init | ||
| ::testing::InitGoogleTest(&argc, argv); | ||
|
|
||
| // Initialize folly singletons before using CLI components | ||
| folly::init(&argc, &argv, /* removeFlags = */ false); | ||
|
|
||
| return RUN_ALL_TESTS(); | ||
| } | ||
|
|
||
| } // namespace facebook::fboss | ||
|
|
||
| #ifdef IS_OSS | ||
| FOLLY_INIT_LOGGING_CONFIG("DBG2; default:async=true"); | ||
| #else | ||
| FOLLY_INIT_LOGGING_CONFIG("fboss=DBG2; default:async=true"); | ||
| #endif | ||
|
|
||
| int main(int argc, char* argv[]) { | ||
| return facebook::fboss::cliTestMain(argc, argv); | ||
| } |
There was a problem hiding this comment.
Let's move the cliTestMain() implementation to the main() directly.
I don't see there's other place needed to call cliTestMain()
| folly::dynamic CliTest::runCliJson(const std::vector<std::string>& args) const { | ||
| auto result = runCli(args); | ||
| if (result.exitCode != 0) { | ||
| throw std::runtime_error( | ||
| fmt::format( | ||
| "CLI command failed with exit code {}: {}", | ||
| result.exitCode, | ||
| result.stderr)); | ||
| } | ||
| if (result.stdout.empty()) { | ||
| return folly::dynamic::object(); | ||
| } | ||
| return folly::parseJson(result.stdout); | ||
| } |
There was a problem hiding this comment.
I am not a big fan of this function, because all the other run cli or command functions are return CliResult while this returns folly::dynamic and throw exception if there's an error.
I'd recommend to remove such function, and always let users call runCli(). And then you just need to provide a function like folly::dynamic toFollyDynamic(const std::string& stdout). This will force your test to do EXPECT_EQ(result.exitCode, 0) first before calling this function to convert the string
There was a problem hiding this comment.
I don't want to have to repeat an EXPECT_EQ() followed by a call to toFollyDynamic() everywhere we run a CLI command. If your concern is with the exception throwing here, can we instead do this:
EXPECT_EQ(result.exitCode, 0) << "CLI command failed: " << result.stderr;
if (result.exitCode != 0 || result.stdout.empty()) {
return folly::dynamic::object();
}| if (result.exitCode != 0) { | ||
| XLOG(WARN) << "Kernel interface " << kernelIntf << " not found"; | ||
| return -1; | ||
| } |
There was a problem hiding this comment.
All FBOSS Interface should be shown in kernel interface.
Let's treat it as an error if such interface doesn't exist
| CLI tests are simpler than hardware tests - they don't need config file | ||
| manipulation, warmboot/coldboot setup, or SAI-specific logging. They just | ||
| run against the already-running agent via Thrift. | ||
| """ | ||
| tests_to_run = self._get_tests_to_run() | ||
| tests_to_run = self._filter_tests(tests_to_run) |
There was a problem hiding this comment.
I'm okay with this diff doesn't properly orchestra all the necessary services to run cli_test.
But ideally, I would like to see run_test.py to properly setup agent, qsfp, fsdb and etc services just like link tests.
There was a problem hiding this comment.
OK, I can do this in a follow up change. Should CliTestRunner mimic what LinkTestRunner does in _setup_coldboot_test() and _setup_warmboot_test() then? If yes maybe it would be better to refactor the code so as to avoid duplication between LinkTestRunner and CliTestRunner. I can send a PR for this if you agree.
| print(f"Running {len(tests_to_run)} CLI end-to-end tests...") | ||
| start_time = datetime.now() | ||
|
|
||
| # Run all tests in a single gtest invocation | ||
| test_filter = ":".join(tests_to_run) | ||
| # Use /tmp for test results since CLI tests may not have write access | ||
| # to the default TESTRESULT_FILE location | ||
| result_file = "/tmp/cli_test_results.xml" | ||
| cmd = [ | ||
| self._get_test_binary_name(), | ||
| f"--gtest_filter={test_filter}", | ||
| f"--gtest_output=xml:{result_file}", | ||
| ] | ||
|
|
||
| print(f"Running command: {' '.join(cmd)}") | ||
|
|
||
| try: | ||
| result = subprocess.run( | ||
| cmd, | ||
| timeout=args.test_run_timeout, | ||
| ) | ||
|
|
||
| end_time = datetime.now() | ||
| delta_time = end_time - start_time | ||
| print(f"Running all tests took {delta_time}") | ||
|
|
||
| if result.returncode != 0: | ||
| sys.exit(result.returncode) | ||
|
|
||
| except subprocess.TimeoutExpired: | ||
| print(f"[ TIMEOUT ] CLI tests timed out after {args.test_run_timeout}s") | ||
| sys.exit(1) | ||
| except Exception as e: | ||
| print(f"[ ERROR ] Failed to run CLI tests: {e}") |
There was a problem hiding this comment.
Now as cli_test as a cpp test binary just like all the other test binaries, can we keep the run logic identical
There was a problem hiding this comment.
Done. I had to override the fruid_path and coldboot args for CliTestRunner in order to disable passing --fruid_path and --setup-for-warmboot as those flags are not supported by the cli_test binary.
de18a53 to
959d4e8
Compare
Summary: **Pre-submission checklist** - [x] I've ran the linters locally and fixed lint errors related to the files I modified in this PR. You can install the linters by running `pip install -r requirements-dev.txt && pre-commit install` - [x] `pre-commit run` Command syntax: ``` fboss2-dev config qos policy <name> map <map-type> <key> <value> ``` Where: - `<name>` is the QoS policy name - `<map-type>` is one of: `tc-to-queue`, `pfc-pri-to-queue`, `tc-to-pg`, `pfc-pri-to-pg` - `<key>` and `<value>` are integers from 0-7 Note: this change is part of a series, the previous one is #867, the next one is #893. Pull Request resolved: #881 Test Plan: New end to end test: ``` ====================================================================== CLI E2E Test: QoS Policy Configuration ====================================================================== [Step 0] Cleaning up any existing test config... Copying system config to session config... Removing QoS policy test configs... Updating metadata for AGENT_RESTART... Committing cleanup... Using CLI from FBOSS_CLI_PATH: ./fboss2-dev [CLI] Running: config session commit [CLI] Completed in 2.77s: config session commit Cleanup complete [Step 1] Configuring QoS policy 'cli_e2e_test_qos_policy'... Configuring trafficClassToQueueId (tc-to-queue)... [CLI] Running: config qos policy cli_e2e_test_qos_policy map tc-to-queue 0 0 [CLI] Completed in 0.08s: config qos policy cli_e2e_test_qos_policy map tc-to-queue 0 0 [CLI] Running: config qos policy cli_e2e_test_qos_policy map tc-to-queue 1 1 [CLI] Completed in 0.06s: config qos policy cli_e2e_test_qos_policy map tc-to-queue 1 1 [CLI] Running: config qos policy cli_e2e_test_qos_policy map tc-to-queue 2 2 [CLI] Completed in 0.07s: config qos policy cli_e2e_test_qos_policy map tc-to-queue 2 2 [CLI] Running: config qos policy cli_e2e_test_qos_policy map tc-to-queue 3 3 [CLI] Completed in 0.07s: config qos policy cli_e2e_test_qos_policy map tc-to-queue 3 3 [CLI] Running: config qos policy cli_e2e_test_qos_policy map tc-to-queue 4 4 [CLI] Completed in 0.07s: config qos policy cli_e2e_test_qos_policy map tc-to-queue 4 4 [CLI] Running: config qos policy cli_e2e_test_qos_policy map tc-to-queue 5 5 [CLI] Completed in 0.07s: config qos policy cli_e2e_test_qos_policy map tc-to-queue 5 5 [CLI] Running: config qos policy cli_e2e_test_qos_policy map tc-to-queue 6 6 [CLI] Completed in 0.07s: config qos policy cli_e2e_test_qos_policy map tc-to-queue 6 6 [CLI] Running: config qos policy cli_e2e_test_qos_policy map tc-to-queue 7 7 [CLI] Completed in 0.06s: config qos policy cli_e2e_test_qos_policy map tc-to-queue 7 7 Configuring pfcPriorityToQueueId (pfc-pri-to-queue)... [CLI] Running: config qos policy cli_e2e_test_qos_policy map pfc-pri-to-queue 0 0 [CLI] Completed in 0.06s: config qos policy cli_e2e_test_qos_policy map pfc-pri-to-queue 0 0 [CLI] Running: config qos policy cli_e2e_test_qos_policy map pfc-pri-to-queue 1 1 [CLI] Completed in 0.06s: config qos policy cli_e2e_test_qos_policy map pfc-pri-to-queue 1 1 [CLI] Running: config qos policy cli_e2e_test_qos_policy map pfc-pri-to-queue 2 2 [CLI] Completed in 0.06s: config qos policy cli_e2e_test_qos_policy map pfc-pri-to-queue 2 2 [CLI] Running: config qos policy cli_e2e_test_qos_policy map pfc-pri-to-queue 3 3 [CLI] Completed in 0.06s: config qos policy cli_e2e_test_qos_policy map pfc-pri-to-queue 3 3 [CLI] Running: config qos policy cli_e2e_test_qos_policy map pfc-pri-to-queue 4 4 [CLI] Completed in 0.06s: config qos policy cli_e2e_test_qos_policy map pfc-pri-to-queue 4 4 [CLI] Running: config qos policy cli_e2e_test_qos_policy map pfc-pri-to-queue 5 5 [CLI] Completed in 0.07s: config qos policy cli_e2e_test_qos_policy map pfc-pri-to-queue 5 5 [CLI] Running: config qos policy cli_e2e_test_qos_policy map pfc-pri-to-queue 6 6 [CLI] Completed in 0.05s: config qos policy cli_e2e_test_qos_policy map pfc-pri-to-queue 6 6 [CLI] Running: config qos policy cli_e2e_test_qos_policy map pfc-pri-to-queue 7 7 [CLI] Completed in 0.06s: config qos policy cli_e2e_test_qos_policy map pfc-pri-to-queue 7 7 Configuring trafficClassToPgId (tc-to-pg)... [CLI] Running: config qos policy cli_e2e_test_qos_policy map tc-to-pg 0 0 [CLI] Completed in 0.06s: config qos policy cli_e2e_test_qos_policy map tc-to-pg 0 0 [CLI] Running: config qos policy cli_e2e_test_qos_policy map tc-to-pg 1 1 [CLI] Completed in 0.06s: config qos policy cli_e2e_test_qos_policy map tc-to-pg 1 1 [CLI] Running: config qos policy cli_e2e_test_qos_policy map tc-to-pg 2 2 [CLI] Completed in 0.07s: config qos policy cli_e2e_test_qos_policy map tc-to-pg 2 2 [CLI] Running: config qos policy cli_e2e_test_qos_policy map tc-to-pg 3 3 [CLI] Completed in 0.06s: config qos policy cli_e2e_test_qos_policy map tc-to-pg 3 3 [CLI] Running: config qos policy cli_e2e_test_qos_policy map tc-to-pg 4 4 [CLI] Completed in 0.07s: config qos policy cli_e2e_test_qos_policy map tc-to-pg 4 4 [CLI] Running: config qos policy cli_e2e_test_qos_policy map tc-to-pg 5 5 [CLI] Completed in 0.07s: config qos policy cli_e2e_test_qos_policy map tc-to-pg 5 5 [CLI] Running: config qos policy cli_e2e_test_qos_policy map tc-to-pg 6 6 [CLI] Completed in 0.06s: config qos policy cli_e2e_test_qos_policy map tc-to-pg 6 6 [CLI] Running: config qos policy cli_e2e_test_qos_policy map tc-to-pg 7 7 [CLI] Completed in 0.07s: config qos policy cli_e2e_test_qos_policy map tc-to-pg 7 7 Configuring pfcPriorityToPgId (pfc-pri-to-pg)... [CLI] Running: config qos policy cli_e2e_test_qos_policy map pfc-pri-to-pg 0 0 [CLI] Completed in 0.07s: config qos policy cli_e2e_test_qos_policy map pfc-pri-to-pg 0 0 [CLI] Running: config qos policy cli_e2e_test_qos_policy map pfc-pri-to-pg 1 1 [CLI] Completed in 0.07s: config qos policy cli_e2e_test_qos_policy map pfc-pri-to-pg 1 1 [CLI] Running: config qos policy cli_e2e_test_qos_policy map pfc-pri-to-pg 2 2 [CLI] Completed in 0.07s: config qos policy cli_e2e_test_qos_policy map pfc-pri-to-pg 2 2 [CLI] Running: config qos policy cli_e2e_test_qos_policy map pfc-pri-to-pg 3 3 [CLI] Completed in 0.07s: config qos policy cli_e2e_test_qos_policy map pfc-pri-to-pg 3 3 [CLI] Running: config qos policy cli_e2e_test_qos_policy map pfc-pri-to-pg 4 4 [CLI] Completed in 0.07s: config qos policy cli_e2e_test_qos_policy map pfc-pri-to-pg 4 4 [CLI] Running: config qos policy cli_e2e_test_qos_policy map pfc-pri-to-pg 5 5 [CLI] Completed in 0.06s: config qos policy cli_e2e_test_qos_policy map pfc-pri-to-pg 5 5 [CLI] Running: config qos policy cli_e2e_test_qos_policy map pfc-pri-to-pg 6 6 [CLI] Completed in 0.06s: config qos policy cli_e2e_test_qos_policy map pfc-pri-to-pg 6 6 [CLI] Running: config qos policy cli_e2e_test_qos_policy map pfc-pri-to-pg 7 7 [CLI] Completed in 0.07s: config qos policy cli_e2e_test_qos_policy map pfc-pri-to-pg 7 7 QoS policy configured [Step 2] Committing configuration... [CLI] Running: config session commit [CLI] Completed in 10.59s: config session commit Configuration committed successfully [Step 3] Verifying configuration... QoS policy 'cli_e2e_test_qos_policy' found trafficClassToQueueId verified pfcPriorityToQueueId verified trafficClassToPgId verified pfcPriorityToPgId verified ====================================================================== TEST PASSED ====================================================================== [Step 4] Cleaning up test config... Copying system config to session config... Removing QoS policy test configs... Updating metadata for AGENT_RESTART... Committing cleanup... [CLI] Running: config session commit [CLI] Completed in 6.50s: config session commit Cleanup complete ``` ## Sample usage ``` admin@fboss101:~/benoit$ ./fboss2-dev config qos policy test-policy map tc-to-queue 0 0 Successfully set QoS policy 'test-policy' trafficClassToQueueId [0] = 0 admin@fboss101:~/benoit$ ./fboss2-dev config qos policy test-policy map pfc-pri-to-queue 3 5 Successfully set QoS policy 'test-policy' pfcPriorityToQueueId [3] = 5 admin@fboss101:~/benoit$ ./fboss2-dev config qos policy test-policy map tc-to-pg 2 2 Successfully set QoS policy 'test-policy' trafficClassToPgId [2] = 2 admin@fboss101:~/benoit$ ./fboss2-dev config qos policy test-policy map pfc-pri-to-pg 7 7 Successfully set QoS policy 'test-policy' pfcPriorityToPgId [7] = 7 admin@fboss101:~/benoit$ ./fboss2-dev config session diff --- current live config +++ session config @@ -5871,7 +5871,28 @@ } ], "proactiveArp": false, - "qosPolicies": [], + "qosPolicies": [ + { + "name": "test-policy", + "qosMap": { + "dscpMaps": [], + "expMaps": [], + "pfcPriorityToPgId": { + "7": 7 + }, + "pfcPriorityToQueueId": { + "3": 5 + }, + "trafficClassToPgId": { + "2": 2 + }, + "trafficClassToQueueId": { + "0": 0 + } + }, + "rules": [] + } + ], "sFlowCollectors": [], "sdkVersion": { "asicSdk": "sdk", ``` Reviewed By: KevinYakar Differential Revision: D97308312 Pulled By: joseph5wu fbshipit-source-id: 3fc4d0be7e504cd044bb71a89acde5867d1308bd
2d4c073 to
daa1b1a
Compare
|
@joseph5wu has imported this pull request. If you are a Meta employee, you can view this in D97513684. |
daa1b1a to
8c1d28c
Compare
|
@benoit-nexthop has updated the pull request. You must reimport the pull request before landing. |
8c1d28c to
6fa5e9e
Compare
|
@benoit-nexthop has updated the pull request. You must reimport the pull request before landing. |
6fa5e9e to
35be84f
Compare
|
@benoit-nexthop has updated the pull request. You must reimport the pull request before landing. |
35be84f to
93b2f56
Compare
|
@benoit-nexthop has updated the pull request. You must reimport the pull request before landing. |
# Summary
This change enables running multiple CLI commands within a single process,
which is required for C++ end-to-end tests. The first two end-to-end tests
that were originally written in Python, along with helper functions, have
been rewritten in C++, and can now run as a self-contained gtest binary,
without depending on the fboss2-dev binary.
Some fixes were necessary to make this work, so the CLI could be re-used
as a library instead of being invoked as a subprocess:
1. Remove the `hasRun` static variable from `CmdHandler`
- Previously, a static `hasRun` flag prevented commands from executing
more than once per process
- Now we wrap callbacks in `CmdSubcommands` to check `get_subcommands().empty()`
to detect leaf commands, eliminating the need for static state
2. Throw exceptions instead of calling `exit(1)` in `CmdHandler`
- `CmdHandler::run()` now rethrows exceptions instead of calling `exit(1)`
- This allows tests to catch errors and verify exit codes
- `Main.cpp` catches exceptions and returns exit code 1
3. Factor out `CLI::App` initialization into `CliAppInit.h`
- Header-only `initApp()` function shared between `Main.cpp` and tests
- Eliminates code duplication for CLI setup
- This couldn't be packaged into a library of its own without going
into circular dependency hell, hence why it's a header-only helper
4. Reset state in `ConfigSession::initializeSession()`
- Clear `ConfigSession` attributes when creating a new session (when
session file doesn't exist)
- Allows re-using the same `ConfigSession` singleton after `commit()`
5. Update state in `ConfigSession::commit()`
- Set `base_` to the new commit SHA after successful commit
- Set `configLoaded_ = false` to force config reload on next access
- Allows re-using the same `ConfigSession` singleton after `commit()`
6. Automatically initialize session in `ConfigSession::loadConfig()`
- If session file doesn't exist (e.g., after commit deleted it),
call `initializeSession()` to create a fresh session
These changes allow the ConfigSession singleton to be properly reused
across multiple CLI command invocations within the same process.
# Test Plan
Added new end-to-end tests in C++ that replace `test_config_interface_mtu.py`
and `test_config_interface_description.py` (the Python scripts will be
removed in a future PR soon).
Sample output (simplified, without timestamps and other noise):
```
[==========] Running 2 tests from 2 test suites.
[----------] 1 test from ConfigInterfaceDescriptionTest
[ RUN ] ConfigInterfaceDescriptionTest.SetAndVerifyDescription
[Step 1] Finding an interface to test...
Using interface: eth1/1/1 (VLAN: 2001)
[Step 2] Getting current description...
Current description: 'CLI_E2E_TEST_DESCRIPTION_ALT'
[Step 3] Setting description to 'CLI_E2E_TEST_DESCRIPTION'...
Description set to 'CLI_E2E_TEST_DESCRIPTION'
[Step 4] Verifying description via 'show interface'...
Verified: Description is 'CLI_E2E_TEST_DESCRIPTION'
[Step 5] Restoring original description ('CLI_E2E_TEST_DESCRIPTION_ALT')...
Restored description to 'CLI_E2E_TEST_DESCRIPTION_ALT'
TEST PASSED
[ OK ] ConfigInterfaceDescriptionTest.SetAndVerifyDescription (412 ms)
[----------] 1 test from ConfigInterfaceMtuTest
[ RUN ] ConfigInterfaceMtuTest.SetAndVerifyMtu
[Step 1] Finding an interface to test...
Using interface: eth1/1/1 (VLAN: 2001)
[Step 2] Getting current MTU...
Current MTU: 9000
[Step 3] Setting MTU to 1500...
MTU set to 1500
[Step 4] Verifying MTU via 'show interface'...
Verified: MTU is 1500
[Step 5] Verifying kernel interface MTU...
Verified: Kernel interface fboss2001 has MTU 1500
[Step 6] Restoring original MTU (9000)...
Restored MTU to 9000
TEST PASSED
[ OK ] ConfigInterfaceMtuTest.SetAndVerifyMtu (384 ms)
[==========] 2 tests from 2 test suites ran. (797 ms total)
[ PASSED ] 2 tests.
```
93b2f56 to
50984b8
Compare
|
@benoit-nexthop has updated the pull request. You must reimport the pull request before landing. |
|
@joseph5wu merged this pull request in 06ff27b. |
…-mode (#896) Summary: **Pre-submission checklist** - [x] I've ran the linters locally and fixed lint errors related to the files I modified in this PR. You can install the linters by running `pip install -r requirements-dev.txt && pre-commit install` - [x] `pre-commit run` Implements two new fboss2-dev CLI commands for switch configuration. ## 1. config vlan <vlanId> port <portId> taggingMode <mode> Configures the VLAN tagging mode for a port within a VLAN. This controls whether packets are tagged or untagged when egressing the port. Where `<mode>` can be: - `tagged` - Packets egress with VLAN tag - `untagged` - Packets egress without VLAN tag This is a hitless configuration change (no agent restart required). ## 2. config l2 learning-mode <mode> Configures the L2 learning mode (`l2LearningMode` in `SwitchSettings`). This controls how the switch learns MAC addresses. Where `<mode>` can be: - `hardware` - MAC learning is performed by the hardware ASIC - `software` - MAC learning is performed by the software agent - `disabled` - MAC learning is disabled Note: Changing L2 learning mode requires an agent restart (not hitless) because the FBOSS agent does not permit changing this setting after initial config application. Note: this change is part of a series, the previous one is #893, the next one is #900. This change was originally developed by manoharan-nexthop Pull Request resolved: #896 Add CLI commands to configure the dscpMaps, expMaps, and pcpMaps attributes of the QosMap object within a QosPolicy. These commands allow configuring bidirectional mappings between codepoint values and internal traffic classes. New CLI commands: - DSCP maps (RFC 2474, values 0-63): - `config qos policy <name> map dscp <value> traffic-class <tc>` - `config qos policy <name> map traffic-class <tc> dscp <value>` - MPLS EXP maps (RFC 3032/5462, values 0-7): - `config qos policy <name> map mpls-exp <value> traffic-class <tc>` - `config qos policy <name> map traffic-class <tc> mpls-exp <value>` - DOT1P/PCP maps (802.1Q, values 0-7): - `config qos policy <name> map dot1p <value> traffic-class <tc>` - `config qos policy <name> map traffic-class <tc> dot1p <value>` The first command in each pair is additive (ingress classification - multiple codepoints can map to the same traffic class), while the second is not additive (egress rewrite - one traffic class maps to one codepoint value). Test Plan: ## Unit tests - **config vlan port taggingMode** (15 test cases): Argument validation, mode conversion, error handling - **config l2 learning-mode** (14 test cases): Argument validation, mode conversion, error handling ## End-to-end tests **config vlan port taggingMode:** ``` ============================================================ CLI E2E Test: config vlan <id> port <port> taggingMode ============================================================ [Step 1] Finding an interface to test... Using CLI from FBOSS_CLI_PATH: /home/admin/manoharan/fboss2-dev [CLI] Running: show interface [CLI] Completed in 0.08s: show interface Using interface: eth1/1/1 (VLAN: 2001) [Step 2] Getting current tagging mode... [CLI] Running: show running-config [CLI] Completed in 0.07s: show running-config Current mode: untagged [Step 3] Setting tagging mode to 'tagged'... [CLI] Running: config vlan 2001 port eth1/1/1 taggingMode tagged [CLI] Completed in 0.08s: config vlan 2001 port eth1/1/1 taggingMode tagged [CLI] Running: config session commit [CLI] Completed in 0.16s: config session commit Tagging mode set to 'tagged' [Step 4] Verifying tagging mode is 'tagged'... [CLI] Running: show running-config [CLI] Completed in 0.06s: show running-config Verified: Tagging mode is 'tagged' [Step 5] Setting tagging mode to 'untagged'... [CLI] Running: config vlan 2001 port eth1/1/1 taggingMode untagged [CLI] Completed in 0.08s: config vlan 2001 port eth1/1/1 taggingMode untagged [CLI] Running: config session commit [CLI] Completed in 0.15s: config session commit Tagging mode set to 'untagged' [Step 6] Verifying tagging mode is 'untagged'... [CLI] Running: show running-config [CLI] Completed in 0.06s: show running-config Verified: Tagging mode is 'untagged' ============================================================ TEST PASSED ============================================================ ``` **config l2 learning-mode:** ``` ============================================================ CLI E2E Test: config l2 learning-mode <mode> ============================================================ [Step 1] Getting current L2 learning mode... Using CLI from FBOSS_CLI_PATH: /home/admin/manoharan/fboss2-dev [CLI] Running: show running-config [CLI] Completed in 0.06s: show running-config Current mode: hardware [Step 2] Setting L2 learning mode to 'software'... [CLI] Running: config l2 learning-mode software [CLI] Completed in 0.07s: config l2 learning-mode software [CLI] Running: config session commit [CLI] Completed in 2.88s: config session commit Waiting for agent to be ready after restart... Sleeping 30s for agent restart... L2 learning mode set to 'software' [Step 3] Verifying L2 learning mode is 'software'... [CLI] Running: show running-config [CLI] Completed in 0.06s: show running-config Verified: L2 learning mode is 'software' [Step 4] Setting L2 learning mode to 'hardware'... [CLI] Running: config l2 learning-mode hardware [CLI] Completed in 0.08s: config l2 learning-mode hardware [CLI] Running: config session commit [CLI] Completed in 3.51s: config session commit Waiting for agent to be ready after restart... Sleeping 30s for agent restart... L2 learning mode set to 'hardware' [Step 5] Verifying L2 learning mode is 'hardware'... [CLI] Running: show running-config [CLI] Completed in 0.06s: show running-config Verified: L2 learning mode is 'hardware' ============================================================ TEST PASSED ============================================================ ``` ## Sample usage CLI: Add DSCP, EXP, and DOT1P map configuration commands New end to end tests: ``` Note: Google Test filter = *ConfigQosPolicyMapTest* [==========] Running 1 test from 1 test suite. [----------] Global test environment set-up. [----------] 1 test from ConfigQosPolicyMapTest [ RUN ] ConfigQosPolicyMapTest.CreateSamplePolicy I0204 18:36:53.719844 63663 CliTest.cpp:35] CliTest::SetUp - starting CLI test I0204 18:36:53.719979 63663 ConfigQosPolicyMapTest.cpp:63] Using test policy name: cli_e2e_test_qos_policy_1770259013719 I0204 18:36:53.719994 63663 ConfigQosPolicyMapTest.cpp:229] ======================================== I0204 18:36:53.719999 63663 ConfigQosPolicyMapTest.cpp:230] ConfigQosPolicyMapTest::CreateSamplePolicy I0204 18:36:53.720004 63663 ConfigQosPolicyMapTest.cpp:231] ======================================== I0204 18:36:53.720008 63663 ConfigQosPolicyMapTest.cpp:242] [Step 1] Configuring DOT1P/PCP maps... I0204 18:36:53.720016 63663 CliTest.cpp:118] Running CLI command: config qos policy cli_e2e_test_qos_policy_1770259013719 map dot1p 0 traffic-class 0 I0204 18:36:53.761480 63663 ConfigQosPolicyMapTest.cpp:102] Command: dot1p 0 traffic-class 0 I0204 18:36:53.761503 63663 ConfigQosPolicyMapTest.cpp:104] stdout: {"localhost":"Successfully set QoS policy 'cli_e2e_test_qos_policy_1770259013719' pcpMaps.fromPcpToTrafficClass [tc=0] = 0"} [... additional map configuration commands ...] I0204 18:36:53.985447 63663 ConfigQosPolicyMapTest.cpp:276] DOT1P maps configured I0204 18:36:53.985452 63663 ConfigQosPolicyMapTest.cpp:279] [Step 2] Configuring traffic-class-to-queue mappings... I0204 18:36:53.985462 63663 CliTest.cpp:118] Running CLI command: config qos policy cli_e2e_test_qos_policy_1770259013719 map tc-to-queue 0 0 I0204 18:36:54.002140 63663 ConfigQosPolicyMapTest.cpp:128] Command: tc-to-queue 0 0 I0204 18:36:54.002164 63663 ConfigQosPolicyMapTest.cpp:129] stdout: {"localhost":"Successfully set QoS policy 'cli_e2e_test_qos_policy_1770259013719' trafficClassToQueueId [0] = 0"} [... additional tc-to-queue commands ...] I0204 18:36:54.091056 63663 ConfigQosPolicyMapTest.cpp:286] TC-to-queue mappings configured I0204 18:36:54.091071 63663 ConfigQosPolicyMapTest.cpp:289] [Step 3] Committing config... I0204 18:36:54.091084 63663 CliTest.cpp:118] Running CLI command: config session commit I0204 18:36:54.316841 63663 ConfigQosPolicyMapTest.cpp:291] Config committed I0204 18:36:54.316868 63663 ConfigQosPolicyMapTest.cpp:294] [Step 4] Verifying config was applied... I0204 18:36:54.326264 63663 ConfigQosPolicyMapTest.cpp:297] Got running config from agent I0204 18:36:54.326306 63663 ConfigQosPolicyMapTest.cpp:303] Found test policy in running config I0204 18:36:54.326319 63663 ConfigQosPolicyMapTest.cpp:314] Verified pcpMaps has 6 entries I0204 18:36:54.326344 63663 ConfigQosPolicyMapTest.cpp:329] All pcpMap entries verified I0204 18:36:54.326363 63663 ConfigQosPolicyMapTest.cpp:347] trafficClassToQueueId verified I0204 18:36:54.326374 63663 ConfigQosPolicyMapTest.cpp:349] TEST PASSED [ OK ] ConfigQosPolicyMapTest.CreateSamplePolicy (607 ms) [----------] 1 test from ConfigQosPolicyMapTest (607 ms total) [----------] Global test environment tear-down [==========] 1 test from 1 test suite ran. (607 ms total) [ PASSED ] 1 test. ``` ## Sample usage ``` [admin@fboss101 ~]$ fboss2-dev config vlan 2001 port eth1/1/1 taggingMode untagged Successfully set tagging mode for port 'eth1/1/1' in VLAN 2001 to 'untagged' [admin@fboss101 ~]$ fboss2-dev config l2 learning-mode software Successfully set L2 learning mode to 'software' [admin@fboss101 ~]$ fboss2-dev config session commit wedge_agent restarted, config committed ``` Reviewed By: KevinYakar Differential Revision: D98023658 Pulled By: joseph5wu fbshipit-source-id: 57b01b9f2a9acbfd3c39622fdf86ae0001b3a7a6
…p class # Summary This PR consolidates the separate CmdConfigInterfaceDescription and CmdConfigInterfaceMtu commands into a unified CmdConfigInterface command that can set multiple interface attributes in a single invocation. ``` # Set description config interface eth1/1/1 description "My port description" # Set MTU config interface eth1/1/1 mtu 9000 # Set both in one command config interface eth1/1/1 description "My port" mtu 9000 # Apply to multiple interfaces config interface eth1/1/1,eth1/2/1 description "Uplink" mtu 1500 ``` Original change by @hillol-nexthop ## Implementation Details 1. **New `InterfaceConfig` class** - Parses CLI tokens to separate port names from attribute key-value pairs - Supports description and mtu attributes (case-insensitive) - Validates attribute names and detects missing values - Wraps `InterfaceList` for port/interface resolution 2. **Updated CmdConfigInterface** - Changed from pass-through command to functional command - Implements `queryClient` to process description and mtu attributes - Sets `port->description()` for description attribute - Sets `interface->mtu()` for mtu attribute with validation 3. **Updated subcommands to use `InterfaceConfig` instead of `InterfaceList`** 4. **Deleted obsolete pairs of `.cpp` / `.h`** 5. **New comprehensive test suite** - 23 tests covering `InterfaceConfig` validation and `CmdConfigInterface::queryClient` functionality - Backward Compatibility - Subcommands like switchport, pfc-config, and queuing-policy continue to work as before # Test Plan **Note:** The e2e test is already implemented in facebook#893 Above mentioned list of new test file, deleted and updated test files. Existing unit and end to end tests pass.
…p class # Summary This PR consolidates the separate CmdConfigInterfaceDescription and CmdConfigInterfaceMtu commands into a unified CmdConfigInterface command that can set multiple interface attributes in a single invocation. ``` # Set description config interface eth1/1/1 description "My port description" # Set MTU config interface eth1/1/1 mtu 9000 # Set both in one command config interface eth1/1/1 description "My port" mtu 9000 # Apply to multiple interfaces config interface eth1/1/1,eth1/2/1 description "Uplink" mtu 1500 ``` Original change by @hillol-nexthop ## Implementation Details 1. **New `InterfaceConfig` class** - Parses CLI tokens to separate port names from attribute key-value pairs - Supports description and mtu attributes (case-insensitive) - Validates attribute names and detects missing values - Wraps `InterfaceList` for port/interface resolution 2. **Updated CmdConfigInterface** - Changed from pass-through command to functional command - Implements `queryClient` to process description and mtu attributes - Sets `port->description()` for description attribute - Sets `interface->mtu()` for mtu attribute with validation 3. **Updated subcommands to use `InterfaceConfig` instead of `InterfaceList`** 4. **Deleted obsolete pairs of `.cpp` / `.h`** 5. **New comprehensive test suite** - 23 tests covering `InterfaceConfig` validation and `CmdConfigInterface::queryClient` functionality - Backward Compatibility - Subcommands like switchport, pfc-config, and queuing-policy continue to work as before # Test Plan **Note:** The e2e test is already implemented in facebook#893 Above mentioned list of new test file, deleted and updated test files. Existing unit and end to end tests pass.
…p class # Summary This PR consolidates the separate CmdConfigInterfaceDescription and CmdConfigInterfaceMtu commands into a unified CmdConfigInterface command that can set multiple interface attributes in a single invocation. ``` # Set description config interface eth1/1/1 description "My port description" # Set MTU config interface eth1/1/1 mtu 9000 # Set both in one command config interface eth1/1/1 description "My port" mtu 9000 # Apply to multiple interfaces config interface eth1/1/1,eth1/2/1 description "Uplink" mtu 1500 ``` Original change by @hillol-nexthop ## Implementation Details 1. **New `InterfaceConfig` class** - Parses CLI tokens to separate port names from attribute key-value pairs - Supports description and mtu attributes (case-insensitive) - Validates attribute names and detects missing values - Wraps `InterfaceList` for port/interface resolution 2. **Updated CmdConfigInterface** - Changed from pass-through command to functional command - Implements `queryClient` to process description and mtu attributes - Sets `port->description()` for description attribute - Sets `interface->mtu()` for mtu attribute with validation 3. **Updated subcommands to use `InterfaceConfig` instead of `InterfaceList`** 4. **Deleted obsolete pairs of `.cpp` / `.h`** 5. **New comprehensive test suite** - 23 tests covering `InterfaceConfig` validation and `CmdConfigInterface::queryClient` functionality - Backward Compatibility - Subcommands like switchport, pfc-config, and queuing-policy continue to work as before # Test Plan **Note:** The e2e test is already implemented in facebook#893 Above mentioned list of new test file, deleted and updated test files. Existing unit and end to end tests pass.
…p class (#919) Summary: **Pre-submission checklist** - [x] I've ran the linters locally and fixed lint errors related to the files I modified in this PR. You can install the linters by running `pip install -r requirements-dev.txt && pre-commit install` - [x] `pre-commit run` This PR consolidates the separate `CmdConfigInterfaceDescription` and `CmdConfigInterfaceMtu` commands into a unified `CmdConfigInterface` command that can set multiple interface attributes in a single invocation. ``` # Set description config interface eth1/1/1 description "My port description" # Set MTU config interface eth1/1/1 mtu 9000 # Set both in one command config interface eth1/1/1 description "My port" mtu 9000 # Apply to multiple interfaces config interface eth1/1/1,eth1/2/1 description "Uplink" mtu 1500 ``` Original change by hillol-nexthop Note: this change is part of a series, the previous one is #900, the next one is #931. ## Implementation Details 1. **New `InterfaceConfig` class** - Parses CLI tokens to separate port names from attribute key-value pairs - Supports description and mtu attributes (case-insensitive) - Validates attribute names and detects missing values - Wraps `InterfaceList` for port/interface resolution 2. **Updated CmdConfigInterface** - Changed from pass-through command to functional command - Implements `queryClient` to process description and mtu attributes - Sets `port->description()` for description attribute - Sets `interface->mtu()` for mtu attribute with validation 3. **Updated subcommands to use `InterfaceConfig` instead of `InterfaceList`** 4. **Deleted obsolete pairs of `.cpp` / `.h`** 5. **New comprehensive test suite** - 23 tests covering `InterfaceConfig` validation and `CmdConfigInterface::queryClient` functionality - Backward Compatibility - Subcommands like switchport, pfc-config, and queuing-policy continue to work as before Pull Request resolved: #919 Test Plan: **Note:** The e2e test is already implemented in #893 Above mentioned list of new test file, deleted and updated test files. Existing unit and end to end tests pass. Reviewed By: KevinYakar Differential Revision: D98340162 Pulled By: joseph5wu fbshipit-source-id: 82d10267ae00fb6e81710f61781f0746d591f836
| if (kernelMtu > 0) { | ||
| EXPECT_EQ(kernelMtu, newMtu) | ||
| << "Kernel MTU is " << kernelMtu << ", expected " << newMtu; | ||
| XLOG(INFO) << " Verified: Kernel interface fboss" << *interface.vlan | ||
| << " has MTU " << kernelMtu; | ||
| } else { | ||
| XLOG(INFO) << " Skipped: Kernel interface fboss" << *interface.vlan | ||
| << " not found"; | ||
| } |
There was a problem hiding this comment.
This part of the change was not merged.
Pre-submission checklist
pip install -r requirements-dev.txt && pre-commit installpre-commit runSummary
This change enables running multiple CLI commands within a single process, which is required for C++ end-to-end tests. The first two end-to-end tests that were originally written in Python, along with helper functions, have been rewritten in C++, and can now run as a self-contained gtest binary, without depending on the fboss2-dev binary.
Some fixes were necessary to make this work, so the CLI could be re-used as a library instead of being invoked as a subprocess:
Remove the
hasRunstatic variable fromCmdHandlerhasRunflag prevented commands from executing more than once per processCmdSubcommandsto checkget_subcommands().empty()to detect leaf commands, eliminating the need for static stateThrow exceptions instead of calling
exit(1)inCmdHandlerCmdHandler::run()now rethrows exceptions instead of callingexit(1)Main.cppcatches exceptions and returns exit code 1Factor out
CLI::Appinitialization intoCliAppInit.hinitApp()function shared betweenMain.cppand testsReset state in
ConfigSession::initializeSession()ConfigSessionattributes when creating a new session (when session file doesn't exist)ConfigSessionsingleton aftercommit()Update state in
ConfigSession::commit()base_to the new commit SHA after successful commitconfigLoaded_ = falseto force config reload on next accessConfigSessionsingleton aftercommit()Automatically initialize session in
ConfigSession::loadConfig()initializeSession()to create a fresh sessionThese changes allow the ConfigSession singleton to be properly reused across multiple CLI command invocations within the same process.
Note: this change is part of a series, the previous one is #881, the next one is #896.
Test Plan
Added new end-to-end tests in C++ that replace
test_config_interface_mtu.pyandtest_config_interface_description.py(the Python scripts will be removed in a future PR soon).Sample output (simplified, without timestamps and other noise):