From 73fd84e1ec09135ab48b6a5e50a3df40672b6832 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Fu=C3=9Fberger?= Date: Fri, 24 Apr 2026 15:23:08 +0200 Subject: [PATCH 01/26] Provide new configuration interfaces --- .../expected_output/new_lm_config.json | 398 ++++ .../expected_output/new_lm_config.json | 86 + .../expected_output/new_lm_config.json | 31 + .../expected_output/new_lm_config.json | 238 +++ .../expected_output/new_lm_config.json | 472 +++++ src/launch_manager_daemon/config/BUILD | 63 + .../config/include/config.hpp | 192 ++ .../config/include/config_loader.hpp | 52 + .../include/flatbuffer_config_loader.hpp | 35 + .../config/src/config.cpp | 81 + .../config/src/flatbuffer_config_loader.cpp | 514 ++++++ .../src/flatbuffer_config_loader_UT.cpp | 987 ++++++++++ .../config/src/new_lm_flatcfg.fbs | 191 ++ .../config/src/new_lm_flatcfg_generated.h | 1605 +++++++++++++++++ 14 files changed, 4945 insertions(+) create mode 100644 scripts/config_mapping/tests/basic_test/expected_output/new_lm_config.json create mode 100644 scripts/config_mapping/tests/empty_health_config_test/expected_output/new_lm_config.json create mode 100644 scripts/config_mapping/tests/empty_lm_config_test/expected_output/new_lm_config.json create mode 100644 scripts/config_mapping/tests/health_config_test/expected_output/new_lm_config.json create mode 100644 scripts/config_mapping/tests/lm_config_test/expected_output/new_lm_config.json create mode 100644 src/launch_manager_daemon/config/include/config.hpp create mode 100644 src/launch_manager_daemon/config/include/config_loader.hpp create mode 100644 src/launch_manager_daemon/config/include/flatbuffer_config_loader.hpp create mode 100644 src/launch_manager_daemon/config/src/config.cpp create mode 100644 src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp create mode 100644 src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp create mode 100644 src/launch_manager_daemon/config/src/new_lm_flatcfg.fbs create mode 100644 src/launch_manager_daemon/config/src/new_lm_flatcfg_generated.h diff --git a/scripts/config_mapping/tests/basic_test/expected_output/new_lm_config.json b/scripts/config_mapping/tests/basic_test/expected_output/new_lm_config.json new file mode 100644 index 000000000..3801364ce --- /dev/null +++ b/scripts/config_mapping/tests/basic_test/expected_output/new_lm_config.json @@ -0,0 +1,398 @@ +{ + "schema_version": 1, + "components": [ + { + "name": "setup_filesystem_sh", + "description": "Script to mount partitions at the right directories", + "component_properties": { + "binary_name": "bin/setup_filesystem.sh", + "application_profile": { + "application_type": "Native", + "is_self_terminating": true, + "alive_supervision": { + "reporting_cycle": 0.5, + "failed_cycles_tolerance": 2, + "min_indications": 1, + "max_indications": 3 + } + }, + "depends_on": [], + "process_arguments": [ + "-a", + "-b" + ], + "ready_condition": { + "process_state": "Terminated" + } + }, + "deployment_config": { + "ready_timeout": 0.5, + "shutdown_timeout": 0.5, + "environmental_variables": [ + { + "key": "LD_LIBRARY_PATH", + "value": "/opt/lib" + }, + { + "key": "GLOBAL_ENV_VAR", + "value": "abc" + }, + { + "key": "EMPTY_GLOBAL_ENV_VAR", + "value": "" + } + ], + "bin_dir": "/opt/scripts", + "working_dir": "/tmp", + "ready_recovery_action_type": "RestartAction", + "ready_recovery_action": { + "number_of_attempts": 1, + "delay_before_restart": 0.5 + }, + "recovery_action_type": "SwitchRunTargetAction", + "recovery_action": { + "run_target": "Off" + }, + "sandbox": { + "uid": 1000, + "gid": 1000, + "supplementary_group_ids": [ + 500, + 600, + 700 + ], + "security_policy": "policy_name", + "scheduling_policy": "SCHED_OTHER", + "scheduling_priority": 0, + "max_memory_usage": 1024, + "max_cpu_usage": 75 + } + } + }, + { + "name": "dlt-daemon", + "description": "Logging application", + "component_properties": { + "binary_name": "dltd", + "application_profile": { + "application_type": "Native", + "is_self_terminating": false, + "alive_supervision": { + "reporting_cycle": 0.5, + "failed_cycles_tolerance": 2, + "min_indications": 1, + "max_indications": 3 + } + }, + "depends_on": [ + "setup_filesystem_sh" + ], + "process_arguments": [ + "-a", + "-b", + "--xyz" + ], + "ready_condition": { + "process_state": "Running" + } + }, + "deployment_config": { + "ready_timeout": 0.5, + "shutdown_timeout": 0.5, + "environmental_variables": [ + { + "key": "LD_LIBRARY_PATH", + "value": "/opt/lib" + }, + { + "key": "GLOBAL_ENV_VAR", + "value": "abc" + }, + { + "key": "EMPTY_GLOBAL_ENV_VAR", + "value": "" + } + ], + "bin_dir": "/opt/apps/dlt-daemon", + "working_dir": "/tmp", + "ready_recovery_action_type": "RestartAction", + "ready_recovery_action": { + "number_of_attempts": 1, + "delay_before_restart": 0.5 + }, + "recovery_action_type": "SwitchRunTargetAction", + "recovery_action": { + "run_target": "Off" + }, + "sandbox": { + "uid": 1000, + "gid": 1000, + "supplementary_group_ids": [ + 500, + 600, + 700 + ], + "security_policy": "policy_name", + "scheduling_policy": "SCHED_OTHER", + "scheduling_priority": 0, + "max_memory_usage": 1024, + "max_cpu_usage": 75 + } + } + }, + { + "name": "someip-daemon", + "description": "SOME/IP application", + "component_properties": { + "binary_name": "someipd", + "application_profile": { + "application_type": "Reporting_And_Supervised", + "is_self_terminating": false, + "alive_supervision": { + "reporting_cycle": 0.5, + "failed_cycles_tolerance": 2, + "min_indications": 1, + "max_indications": 3 + } + }, + "depends_on": [], + "process_arguments": [ + "-a", + "-b", + "--xyz" + ], + "ready_condition": { + "process_state": "Running" + } + }, + "deployment_config": { + "ready_timeout": 0.5, + "shutdown_timeout": 0.5, + "environmental_variables": [ + { + "key": "LD_LIBRARY_PATH", + "value": "/opt/lib" + }, + { + "key": "GLOBAL_ENV_VAR", + "value": "abc" + }, + { + "key": "EMPTY_GLOBAL_ENV_VAR", + "value": "" + } + ], + "bin_dir": "/opt/apps/someip", + "working_dir": "/tmp", + "ready_recovery_action_type": "RestartAction", + "ready_recovery_action": { + "number_of_attempts": 1, + "delay_before_restart": 0.5 + }, + "recovery_action_type": "SwitchRunTargetAction", + "recovery_action": { + "run_target": "Off" + }, + "sandbox": { + "uid": 1000, + "gid": 1000, + "supplementary_group_ids": [ + 500, + 600, + 700 + ], + "security_policy": "policy_name", + "scheduling_policy": "SCHED_OTHER", + "scheduling_priority": 0, + "max_memory_usage": 1024, + "max_cpu_usage": 75 + } + } + }, + { + "name": "test_app1", + "description": "Simple test application", + "component_properties": { + "binary_name": "test_app1", + "application_profile": { + "application_type": "Reporting_And_Supervised", + "is_self_terminating": false, + "alive_supervision": { + "reporting_cycle": 0.5, + "failed_cycles_tolerance": 2, + "min_indications": 1, + "max_indications": 3 + } + }, + "depends_on": [ + "dlt-daemon", + "someip-daemon" + ], + "process_arguments": [ + "-a", + "-b", + "--xyz" + ], + "ready_condition": { + "process_state": "Running" + } + }, + "deployment_config": { + "ready_timeout": 0.5, + "shutdown_timeout": 0.5, + "environmental_variables": [ + { + "key": "LD_LIBRARY_PATH", + "value": "/opt/lib" + }, + { + "key": "GLOBAL_ENV_VAR", + "value": "abc" + }, + { + "key": "EMPTY_GLOBAL_ENV_VAR", + "value": "" + } + ], + "bin_dir": "/opt/apps/test_app1", + "working_dir": "/tmp", + "ready_recovery_action_type": "RestartAction", + "ready_recovery_action": { + "number_of_attempts": 1, + "delay_before_restart": 0.5 + }, + "recovery_action_type": "SwitchRunTargetAction", + "recovery_action": { + "run_target": "Off" + }, + "sandbox": { + "uid": 1000, + "gid": 1000, + "supplementary_group_ids": [ + 500, + 600, + 700 + ], + "security_policy": "policy_name", + "scheduling_policy": "SCHED_OTHER", + "scheduling_priority": 0, + "max_memory_usage": 1024, + "max_cpu_usage": 75 + } + } + }, + { + "name": "state_manager", + "description": "Application that manages life cycle of the ECU", + "component_properties": { + "binary_name": "sm", + "application_profile": { + "application_type": "State_Manager", + "is_self_terminating": false, + "alive_supervision": { + "reporting_cycle": 0.5, + "failed_cycles_tolerance": 2, + "min_indications": 1, + "max_indications": 3 + } + }, + "depends_on": [ + "setup_filesystem_sh" + ], + "process_arguments": [ + "-a", + "-b", + "--xyz" + ], + "ready_condition": { + "process_state": "Running" + } + }, + "deployment_config": { + "ready_timeout": 0.5, + "shutdown_timeout": 0.5, + "environmental_variables": [ + { + "key": "LD_LIBRARY_PATH", + "value": "/opt/lib" + }, + { + "key": "GLOBAL_ENV_VAR", + "value": "abc" + }, + { + "key": "EMPTY_GLOBAL_ENV_VAR", + "value": "" + } + ], + "bin_dir": "/opt/apps/state_manager", + "working_dir": "/tmp", + "ready_recovery_action_type": "RestartAction", + "ready_recovery_action": { + "number_of_attempts": 1, + "delay_before_restart": 0.5 + }, + "recovery_action_type": "SwitchRunTargetAction", + "recovery_action": { + "run_target": "Off" + }, + "sandbox": { + "uid": 1000, + "gid": 1000, + "supplementary_group_ids": [ + 500, + 600, + 700 + ], + "security_policy": "policy_name", + "scheduling_policy": "SCHED_OTHER", + "scheduling_priority": 0, + "max_memory_usage": 1024, + "max_cpu_usage": 75 + } + } + } + ], + "run_targets": [ + { + "name": "Startup", + "description": "Minimal functionality of the system", + "depends_on": [ + "state_manager" + ], + "transition_timeout": 5, + "recovery_action_type": "SwitchRunTargetAction", + "recovery_action": { + "run_target": "fallback_run_target" + } + }, + { + "name": "Full", + "description": "Everything running", + "depends_on": [ + "test_app1", + "Startup" + ], + "transition_timeout": 5, + "recovery_action_type": "SwitchRunTargetAction", + "recovery_action": { + "run_target": "fallback_run_target" + } + } + ], + "initial_run_target": "Startup", + "fallback_run_target": { + "description": "Switching off everything", + "depends_on": [], + "transition_timeout": 1.5 + }, + "alive_supervision": { + "evaluation_cycle": 0.5 + }, + "watchdog": { + "device_file_path": "/dev/watchdog", + "max_timeout": 2, + "deactivate_on_shutdown": true, + "require_magic_close": false + } +} \ No newline at end of file diff --git a/scripts/config_mapping/tests/empty_health_config_test/expected_output/new_lm_config.json b/scripts/config_mapping/tests/empty_health_config_test/expected_output/new_lm_config.json new file mode 100644 index 000000000..d54cd0c6f --- /dev/null +++ b/scripts/config_mapping/tests/empty_health_config_test/expected_output/new_lm_config.json @@ -0,0 +1,86 @@ +{ + "schema_version": 1, + "components": [ + { + "name": "non_supervised_comp", + "description": "Non-supervised component", + "component_properties": { + "binary_name": "bin/comp", + "application_profile": { + "application_type": "Native", + "is_self_terminating": true, + "alive_supervision": { + "reporting_cycle": 0.5, + "failed_cycles_tolerance": 2, + "min_indications": 1, + "max_indications": 3 + } + }, + "depends_on": [], + "process_arguments": [], + "ready_condition": { + "process_state": "Terminated" + } + }, + "deployment_config": { + "ready_timeout": 0.5, + "shutdown_timeout": 0.5, + "environmental_variables": [], + "bin_dir": "/opt/scripts", + "working_dir": "/tmp", + "ready_recovery_action_type": "RestartAction", + "ready_recovery_action": { + "number_of_attempts": 0, + "delay_before_restart": 0 + }, + "recovery_action_type": "SwitchRunTargetAction", + "recovery_action": { + "run_target": "fallback_run_target" + }, + "sandbox": { + "uid": 3, + "gid": 1000, + "supplementary_group_ids": [], + "security_policy": "", + "scheduling_policy": "SCHED_OTHER", + "scheduling_priority": 0 + } + } + } + ], + "run_targets": [ + { + "name": "Startup", + "description": "Minimal functionality of the system", + "depends_on": [ + "non_supervised_comp" + ], + "transition_timeout": 3, + "recovery_action_type": "SwitchRunTargetAction", + "recovery_action": { + "run_target": "fallback_run_target" + } + }, + { + "name": "Full", + "description": "Everything running", + "depends_on": [ + "non_supervised_comp" + ], + "transition_timeout": 5, + "recovery_action_type": "SwitchRunTargetAction", + "recovery_action": { + "run_target": "fallback_run_target" + } + } + ], + "initial_run_target": "Startup", + "fallback_run_target": { + "description": "Switching off everything", + "depends_on": [], + "transition_timeout": 1.5 + }, + "alive_supervision": { + "evaluation_cycle": 0.123 + } +} \ No newline at end of file diff --git a/scripts/config_mapping/tests/empty_lm_config_test/expected_output/new_lm_config.json b/scripts/config_mapping/tests/empty_lm_config_test/expected_output/new_lm_config.json new file mode 100644 index 000000000..ebf074a29 --- /dev/null +++ b/scripts/config_mapping/tests/empty_lm_config_test/expected_output/new_lm_config.json @@ -0,0 +1,31 @@ +{ + "schema_version": 1, + "components": [], + "run_targets": [ + { + "name": "Startup", + "description": "Empty", + "depends_on": [], + "transition_timeout": 5, + "recovery_action_type": "SwitchRunTargetAction", + "recovery_action": { + "run_target": "fallback_run_target" + } + } + ], + "initial_run_target": "Startup", + "fallback_run_target": { + "description": "Switching off everything", + "depends_on": [], + "transition_timeout": 1.5 + }, + "alive_supervision": { + "evaluation_cycle": 0.5 + }, + "watchdog": { + "device_file_path": "/dev/watchdog", + "max_timeout": 2, + "deactivate_on_shutdown": true, + "require_magic_close": false + } +} \ No newline at end of file diff --git a/scripts/config_mapping/tests/health_config_test/expected_output/new_lm_config.json b/scripts/config_mapping/tests/health_config_test/expected_output/new_lm_config.json new file mode 100644 index 000000000..3525c3663 --- /dev/null +++ b/scripts/config_mapping/tests/health_config_test/expected_output/new_lm_config.json @@ -0,0 +1,238 @@ +{ + "schema_version": 1, + "components": [ + { + "name": "non_supervised_comp", + "description": "Non-supervised component", + "component_properties": { + "binary_name": "bin/comp", + "application_profile": { + "application_type": "Native", + "is_self_terminating": true, + "alive_supervision": { + "reporting_cycle": 0.5, + "failed_cycles_tolerance": 2, + "min_indications": 1, + "max_indications": 3 + } + }, + "depends_on": [], + "process_arguments": [], + "ready_condition": { + "process_state": "Terminated" + } + }, + "deployment_config": { + "ready_timeout": 0.5, + "shutdown_timeout": 0.5, + "environmental_variables": [], + "bin_dir": "/opt/scripts", + "working_dir": "/tmp", + "ready_recovery_action_type": "RestartAction", + "ready_recovery_action": { + "number_of_attempts": 0, + "delay_before_restart": 0 + }, + "recovery_action_type": "SwitchRunTargetAction", + "recovery_action": { + "run_target": "fallback_run_target" + }, + "sandbox": { + "uid": 3, + "gid": 1000, + "supplementary_group_ids": [], + "security_policy": "", + "scheduling_policy": "SCHED_OTHER", + "scheduling_priority": 0 + } + } + }, + { + "name": "state_manager", + "description": "StateManager with min_indications set to 0", + "component_properties": { + "binary_name": "sm", + "application_profile": { + "application_type": "State_Manager", + "is_self_terminating": false, + "alive_supervision": { + "reporting_cycle": 0.1, + "failed_cycles_tolerance": 0, + "min_indications": 0, + "max_indications": 2 + } + }, + "depends_on": [], + "process_arguments": [], + "ready_condition": { + "process_state": "Running" + } + }, + "deployment_config": { + "ready_timeout": 0.5, + "shutdown_timeout": 0.5, + "environmental_variables": [], + "bin_dir": "/opt/apps/state_manager", + "working_dir": "/tmp", + "ready_recovery_action_type": "RestartAction", + "ready_recovery_action": { + "number_of_attempts": 0, + "delay_before_restart": 0 + }, + "recovery_action_type": "SwitchRunTargetAction", + "recovery_action": { + "run_target": "fallback_run_target" + }, + "sandbox": { + "uid": 4, + "gid": 1000, + "supplementary_group_ids": [], + "security_policy": "", + "scheduling_policy": "SCHED_OTHER", + "scheduling_priority": 0 + } + } + }, + { + "name": "reporting_supervised_component", + "description": "Component reporting Running state and supervised", + "component_properties": { + "binary_name": "bin/comp", + "application_profile": { + "application_type": "Reporting_And_Supervised", + "is_self_terminating": true, + "alive_supervision": { + "reporting_cycle": 0.5, + "failed_cycles_tolerance": 2, + "min_indications": 1, + "max_indications": 3 + } + }, + "depends_on": [], + "process_arguments": [ + "-a", + "-b" + ], + "ready_condition": { + "process_state": "Running" + } + }, + "deployment_config": { + "ready_timeout": 0.5, + "shutdown_timeout": 0.5, + "environmental_variables": [], + "bin_dir": "/opt/scripts", + "working_dir": "/tmp", + "ready_recovery_action_type": "RestartAction", + "ready_recovery_action": { + "number_of_attempts": 0, + "delay_before_restart": 0 + }, + "recovery_action_type": "SwitchRunTargetAction", + "recovery_action": { + "run_target": "fallback_run_target" + }, + "sandbox": { + "uid": 5, + "gid": 1000, + "supplementary_group_ids": [], + "security_policy": "", + "scheduling_policy": "SCHED_OTHER", + "scheduling_priority": 0 + } + } + }, + { + "name": "reporting_supervised_component_with_no_max_indications", + "description": "Component reporting Running state and supervised with max_indications=0", + "component_properties": { + "binary_name": "bin/comp", + "application_profile": { + "application_type": "Reporting_And_Supervised", + "is_self_terminating": true, + "alive_supervision": { + "reporting_cycle": 0.5, + "failed_cycles_tolerance": 2, + "min_indications": 1, + "max_indications": 0 + } + }, + "depends_on": [], + "process_arguments": [ + "-a", + "-b" + ], + "ready_condition": { + "process_state": "Running" + } + }, + "deployment_config": { + "ready_timeout": 0.5, + "shutdown_timeout": 0.5, + "environmental_variables": [], + "bin_dir": "/opt/scripts", + "working_dir": "/tmp", + "ready_recovery_action_type": "RestartAction", + "ready_recovery_action": { + "number_of_attempts": 0, + "delay_before_restart": 0 + }, + "recovery_action_type": "SwitchRunTargetAction", + "recovery_action": { + "run_target": "fallback_run_target" + }, + "sandbox": { + "uid": 5, + "gid": 1000, + "supplementary_group_ids": [], + "security_policy": "", + "scheduling_policy": "SCHED_OTHER", + "scheduling_priority": 0 + } + } + } + ], + "run_targets": [ + { + "name": "Startup", + "description": "Minimal functionality of the system", + "depends_on": [ + "state_manager" + ], + "transition_timeout": 3, + "recovery_action_type": "SwitchRunTargetAction", + "recovery_action": { + "run_target": "fallback_run_target" + } + }, + { + "name": "Full", + "description": "Everything running", + "depends_on": [ + "reporting_supervised_component", + "reporting_supervised_component_with_no_max_indications", + "Startup" + ], + "transition_timeout": 5, + "recovery_action_type": "SwitchRunTargetAction", + "recovery_action": { + "run_target": "fallback_run_target" + } + } + ], + "initial_run_target": "Startup", + "fallback_run_target": { + "description": "Switching off everything", + "depends_on": [], + "transition_timeout": 1.5 + }, + "alive_supervision": { + "evaluation_cycle": 0.123 + }, + "watchdog": { + "device_file_path": "/dev/watchdog", + "max_timeout": 2, + "deactivate_on_shutdown": true, + "require_magic_close": false + } +} \ No newline at end of file diff --git a/scripts/config_mapping/tests/lm_config_test/expected_output/new_lm_config.json b/scripts/config_mapping/tests/lm_config_test/expected_output/new_lm_config.json new file mode 100644 index 000000000..6b5f3e808 --- /dev/null +++ b/scripts/config_mapping/tests/lm_config_test/expected_output/new_lm_config.json @@ -0,0 +1,472 @@ +{ + "schema_version": 1, + "components": [ + { + "name": "test_app2", + "description": "Another simple test application", + "component_properties": { + "binary_name": "test_app2", + "application_profile": { + "application_type": "Reporting_And_Supervised", + "is_self_terminating": false, + "alive_supervision": { + "reporting_cycle": 0.5, + "failed_cycles_tolerance": 2, + "min_indications": 1, + "max_indications": 3 + } + }, + "depends_on": [], + "process_arguments": [ + "-a", + "-b", + "--xyz" + ], + "ready_condition": { + "process_state": "Running" + } + }, + "deployment_config": { + "ready_timeout": 0.5, + "shutdown_timeout": 0.5, + "environmental_variables": [ + { + "key": "LD_LIBRARY_PATH", + "value": "/opt/lib" + }, + { + "key": "GLOBAL_ENV_VAR", + "value": "overridden_value" + }, + { + "key": "EMPTY_GLOBAL_ENV_VAR", + "value": "" + }, + { + "key": "APP_SPECIFIC_ENV_VAR", + "value": "def" + } + ], + "bin_dir": "/opt/apps/test_app2", + "working_dir": "/tmp", + "ready_recovery_action_type": "RestartAction", + "ready_recovery_action": { + "number_of_attempts": 1, + "delay_before_restart": 0.5 + }, + "recovery_action_type": "SwitchRunTargetAction", + "recovery_action": { + "run_target": "fallback_run_target" + }, + "sandbox": { + "uid": 2000, + "gid": 2000, + "supplementary_group_ids": [ + 800, + 900 + ], + "security_policy": "policy_name_2", + "scheduling_policy": "SCHED_FIFO", + "scheduling_priority": 99, + "max_memory_usage": 2048, + "max_cpu_usage": 50 + } + } + }, + { + "name": "setup_filesystem_sh", + "description": "Script to mount partitions at the right directories", + "component_properties": { + "binary_name": "bin/setup_filesystem.sh", + "application_profile": { + "application_type": "Native", + "is_self_terminating": true, + "alive_supervision": { + "reporting_cycle": 0.5, + "failed_cycles_tolerance": 2, + "min_indications": 1, + "max_indications": 3 + } + }, + "depends_on": [ + "test_app2" + ], + "process_arguments": [ + "-a", + "-b" + ], + "ready_condition": { + "process_state": "Terminated" + } + }, + "deployment_config": { + "ready_timeout": 0.5, + "shutdown_timeout": 0.5, + "environmental_variables": [ + { + "key": "LD_LIBRARY_PATH", + "value": "/opt/lib" + }, + { + "key": "GLOBAL_ENV_VAR", + "value": "abc" + }, + { + "key": "EMPTY_GLOBAL_ENV_VAR", + "value": "" + } + ], + "bin_dir": "/opt/scripts", + "working_dir": "/tmp", + "ready_recovery_action_type": "RestartAction", + "ready_recovery_action": { + "number_of_attempts": 1, + "delay_before_restart": 0.5 + }, + "recovery_action_type": "SwitchRunTargetAction", + "recovery_action": { + "run_target": "fallback_run_target" + }, + "sandbox": { + "uid": 1000, + "gid": 1000, + "supplementary_group_ids": [ + 500, + 600, + 700 + ], + "security_policy": "policy_name", + "scheduling_policy": "SCHED_OTHER", + "scheduling_priority": 0, + "max_memory_usage": 1024, + "max_cpu_usage": 75 + } + } + }, + { + "name": "dlt-daemon", + "description": "Logging application", + "component_properties": { + "binary_name": "dltd", + "application_profile": { + "application_type": "Native", + "is_self_terminating": false, + "alive_supervision": { + "reporting_cycle": 0.5, + "failed_cycles_tolerance": 2, + "min_indications": 1, + "max_indications": 3 + } + }, + "depends_on": [ + "setup_filesystem_sh" + ], + "process_arguments": [ + "-a", + "-b", + "--xyz" + ], + "ready_condition": { + "process_state": "Running" + } + }, + "deployment_config": { + "ready_timeout": 0.5, + "shutdown_timeout": 0.5, + "environmental_variables": [ + { + "key": "LD_LIBRARY_PATH", + "value": "/opt/lib" + }, + { + "key": "GLOBAL_ENV_VAR", + "value": "abc" + }, + { + "key": "EMPTY_GLOBAL_ENV_VAR", + "value": "" + } + ], + "bin_dir": "/opt/apps/dlt-daemon", + "working_dir": "/tmp", + "ready_recovery_action_type": "RestartAction", + "ready_recovery_action": { + "number_of_attempts": 1, + "delay_before_restart": 0.5 + }, + "recovery_action_type": "SwitchRunTargetAction", + "recovery_action": { + "run_target": "fallback_run_target" + }, + "sandbox": { + "uid": 1000, + "gid": 1000, + "supplementary_group_ids": [ + 500, + 600, + 700 + ], + "security_policy": "policy_name", + "scheduling_policy": "SCHED_OTHER", + "scheduling_priority": 0, + "max_memory_usage": 1024, + "max_cpu_usage": 75 + } + } + }, + { + "name": "someip-daemon", + "description": "SOME/IP application", + "component_properties": { + "binary_name": "someipd", + "application_profile": { + "application_type": "Reporting_And_Supervised", + "is_self_terminating": false, + "alive_supervision": { + "reporting_cycle": 0.5, + "failed_cycles_tolerance": 2, + "min_indications": 1, + "max_indications": 3 + } + }, + "depends_on": [], + "process_arguments": [ + "-a", + "-b", + "--xyz" + ], + "ready_condition": { + "process_state": "Running" + } + }, + "deployment_config": { + "ready_timeout": 0.5, + "shutdown_timeout": 0.5, + "environmental_variables": [ + { + "key": "LD_LIBRARY_PATH", + "value": "/opt/lib" + }, + { + "key": "GLOBAL_ENV_VAR", + "value": "abc" + }, + { + "key": "EMPTY_GLOBAL_ENV_VAR", + "value": "" + } + ], + "bin_dir": "/opt/apps/someip", + "working_dir": "/tmp", + "ready_recovery_action_type": "RestartAction", + "ready_recovery_action": { + "number_of_attempts": 1, + "delay_before_restart": 0.5 + }, + "recovery_action_type": "SwitchRunTargetAction", + "recovery_action": { + "run_target": "fallback_run_target" + }, + "sandbox": { + "uid": 1000, + "gid": 1000, + "supplementary_group_ids": [ + 500, + 600, + 700 + ], + "security_policy": "policy_name", + "scheduling_policy": "SCHED_OTHER", + "scheduling_priority": 0, + "max_memory_usage": 1024, + "max_cpu_usage": 75 + } + } + }, + { + "name": "test_app1", + "description": "Simple test application", + "component_properties": { + "binary_name": "test_app1", + "application_profile": { + "application_type": "Reporting_And_Supervised", + "is_self_terminating": false, + "alive_supervision": { + "reporting_cycle": 0.5, + "failed_cycles_tolerance": 2, + "min_indications": 1, + "max_indications": 3 + } + }, + "depends_on": [ + "dlt-daemon", + "someip-daemon" + ], + "process_arguments": [ + "-a", + "-b", + "--xyz" + ], + "ready_condition": { + "process_state": "Running" + } + }, + "deployment_config": { + "ready_timeout": 0.5, + "shutdown_timeout": 0.5, + "environmental_variables": [ + { + "key": "LD_LIBRARY_PATH", + "value": "/opt/lib" + }, + { + "key": "GLOBAL_ENV_VAR", + "value": "abc" + }, + { + "key": "EMPTY_GLOBAL_ENV_VAR", + "value": "" + } + ], + "bin_dir": "/opt/apps/test_app1", + "working_dir": "/tmp", + "ready_recovery_action_type": "RestartAction", + "ready_recovery_action": { + "number_of_attempts": 1, + "delay_before_restart": 0.5 + }, + "recovery_action_type": "SwitchRunTargetAction", + "recovery_action": { + "run_target": "fallback_run_target" + }, + "sandbox": { + "uid": 1000, + "gid": 1000, + "supplementary_group_ids": [ + 500, + 600, + 700 + ], + "security_policy": "policy_name", + "scheduling_policy": "SCHED_OTHER", + "scheduling_priority": 0, + "max_memory_usage": 1024, + "max_cpu_usage": 75 + } + } + }, + { + "name": "state_manager", + "description": "Application that manages life cycle of the ECU", + "component_properties": { + "binary_name": "sm", + "application_profile": { + "application_type": "State_Manager", + "is_self_terminating": false, + "alive_supervision": { + "reporting_cycle": 0.5, + "failed_cycles_tolerance": 2, + "min_indications": 1, + "max_indications": 3 + } + }, + "depends_on": [ + "setup_filesystem_sh" + ], + "process_arguments": [ + "-a", + "-b", + "--xyz" + ], + "ready_condition": { + "process_state": "Running" + } + }, + "deployment_config": { + "ready_timeout": 0.5, + "shutdown_timeout": 0.5, + "environmental_variables": [ + { + "key": "LD_LIBRARY_PATH", + "value": "/opt/lib" + }, + { + "key": "GLOBAL_ENV_VAR", + "value": "abc" + }, + { + "key": "EMPTY_GLOBAL_ENV_VAR", + "value": "" + } + ], + "bin_dir": "/opt/apps/state_manager", + "working_dir": "/tmp", + "ready_recovery_action_type": "RestartAction", + "ready_recovery_action": { + "number_of_attempts": 1, + "delay_before_restart": 0.5 + }, + "recovery_action_type": "SwitchRunTargetAction", + "recovery_action": { + "run_target": "fallback_run_target" + }, + "sandbox": { + "uid": 1000, + "gid": 1000, + "supplementary_group_ids": [ + 500, + 600, + 700 + ], + "security_policy": "policy_name", + "scheduling_policy": "SCHED_OTHER", + "scheduling_priority": 0, + "max_memory_usage": 1024, + "max_cpu_usage": 75 + } + } + } + ], + "run_targets": [ + { + "name": "Startup", + "description": "Minimal functionality of the system", + "depends_on": [ + "state_manager" + ], + "transition_timeout": 5, + "recovery_action_type": "SwitchRunTargetAction", + "recovery_action": { + "run_target": "fallback_run_target" + } + }, + { + "name": "Full", + "description": "Everything running", + "depends_on": [ + "test_app1", + "Startup" + ], + "transition_timeout": 5, + "recovery_action_type": "SwitchRunTargetAction", + "recovery_action": { + "run_target": "fallback_run_target" + } + } + ], + "initial_run_target": "Startup", + "fallback_run_target": { + "description": "Switching off everything", + "depends_on": [], + "transition_timeout": 1.5 + }, + "alive_supervision": { + "evaluation_cycle": 0.5 + }, + "watchdog": { + "device_file_path": "/dev/watchdog", + "max_timeout": 2, + "deactivate_on_shutdown": true, + "require_magic_close": false + } +} \ No newline at end of file diff --git a/src/launch_manager_daemon/config/BUILD b/src/launch_manager_daemon/config/BUILD index 67f38aa85..e64f9383f 100644 --- a/src/launch_manager_daemon/config/BUILD +++ b/src/launch_manager_daemon/config/BUILD @@ -14,3 +14,66 @@ exports_files([ "lm_flatcfg.fbs", "lm_flatcfg_generated.h", ]) + +filegroup( + name = "new_lm_flatcfg_fbs", + srcs = ["src/new_lm_flatcfg.fbs"], + visibility = ["//visibility:public"], +) + +cc_library( + name = "config", + srcs = ["src/config.cpp"], + hdrs = ["include/config.hpp"], + includes = ["include"], + visibility = ["//src:__subpackages__"], +) + +cc_library( + name = "config_loader", + hdrs = ["include/config_loader.hpp"], + includes = ["include"], + visibility = ["//src:__subpackages__"], + deps = [ + ":config", + "@score_baselibs//score/filesystem", + "@score_baselibs//score/result", + ], +) + +cc_library( + name = "flatbuffer_config_loader", + srcs = [ + "src/flatbuffer_config_loader.cpp", + "src/new_lm_flatcfg_generated.h", + ], + hdrs = ["include/flatbuffer_config_loader.hpp"], + includes = [ + "include", + "src", + ], + visibility = ["//src:__subpackages__"], + deps = [ + ":config_loader", + "@flatbuffers", + "@score_baselibs//score/os:fcntl", + "@score_baselibs//score/os:stat", + "@score_baselibs//score/os:unistd", + ], +) + +cc_test( + name = "flatbuffer_config_loader_UT", + srcs = ["src/flatbuffer_config_loader_UT.cpp"], + visibility = ["//tests:__subpackages__"], + deps = [ + ":flatbuffer_config_loader", + "@flatbuffers", + "@googletest//:gtest_main", + "@score_baselibs//score/os:object_seam", + "@score_baselibs//score/os/mocklib:fcntl_mock", + "@score_baselibs//score/os/mocklib:stat_mock", + "@score_baselibs//score/os/mocklib:unistd_mock", + ], +) + diff --git a/src/launch_manager_daemon/config/include/config.hpp b/src/launch_manager_daemon/config/include/config.hpp new file mode 100644 index 000000000..99ed3b89e --- /dev/null +++ b/src/launch_manager_daemon/config/include/config.hpp @@ -0,0 +1,192 @@ +// ******************************************************************************* +// Copyright (c) 2026 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache License Version 2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: Apache-2.0 +// ******************************************************************************* + +#ifndef CONFIG_HPP +#define CONFIG_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace score::launch_manager::config { + +enum class ApplicationType : uint8_t { + Native = 0, + Reporting = 1, + ReportingAndSupervised = 2, + StateManager = 3 +}; + +enum class ProcessState : uint8_t { + Running = 0, + Terminated = 1 +}; + +struct ComponentAliveSupervision { + uint32_t reporting_cycle_ms{}; + uint32_t failed_cycles_tolerance{}; + uint32_t min_indications{}; + uint32_t max_indications{}; +}; + +struct ApplicationProfile { + ApplicationType application_type{ApplicationType::Native}; + bool is_self_terminating{}; + std::optional alive_supervision; +}; + +struct ReadyCondition { + ProcessState process_state{ProcessState::Running}; +}; + +struct ComponentProperties { + std::string binary_name; + ApplicationProfile application_profile; + std::vector depends_on; + std::vector process_arguments; + ReadyCondition ready_condition; +}; + +struct RestartAction { + uint32_t number_of_attempts{}; + uint32_t delay_before_restart_ms{}; +}; + +struct SwitchRunTargetAction { + std::string run_target; +}; + +using RecoveryAction = std::variant; + +struct Sandbox { + uint32_t uid{}; + uint32_t gid{}; + std::vector supplementary_group_ids; + std::optional security_policy; + std::string scheduling_policy; + int32_t scheduling_priority{}; + std::optional max_memory_usage; + std::optional max_cpu_usage; +}; + +struct DeploymentConfig { + uint32_t ready_timeout_ms{}; + uint32_t shutdown_timeout_ms{}; + std::unordered_map environmental_variables; + std::string bin_dir; + std::string working_dir; + std::optional ready_recovery_action; + std::optional recovery_action; + std::optional sandbox; +}; + +struct ComponentConfig { + std::string name; + std::string description; + ComponentProperties component_properties; + DeploymentConfig deployment_config; +}; + +struct RunTargetConfig { + std::string name; + std::string description; + std::vector depends_on; + uint32_t transition_timeout_ms{}; + std::optional recovery_action; +}; + +struct FallbackRunTargetConfig { + std::string description; + std::vector depends_on; + uint32_t transition_timeout_ms{}; +}; + +struct AliveSupervisionConfig { + uint32_t evaluation_cycle_ms{}; +}; + +struct WatchdogConfig { + std::string device_file_path; + uint32_t max_timeout_ms{}; + bool deactivate_on_shutdown{}; + bool require_magic_close{}; +}; + +class Config { + public: + Config(const Config&) = delete; + Config& operator=(const Config&) = delete; + Config(Config&&) = default; + Config& operator=(Config&&) = default; + + class Builder { + public: + Builder& setComponents(std::vector components); + Builder& setRunTargets(std::vector run_targets); + Builder& setInitialRunTarget(std::string initial_run_target); + Builder& setFallbackRunTarget(FallbackRunTargetConfig fallback); + Builder& setAliveSupervision(AliveSupervisionConfig alive_supervision); + Builder& setWatchdog(WatchdogConfig watchdog); + + Config build(); + + private: + std::string initial_run_target_; + std::vector components_; + std::vector run_targets_; + std::optional fallback_run_target_; + std::optional alive_supervision_; + std::optional watchdog_; + }; + + // Read access + const std::vector& components() const { return components_; } + const std::vector& run_targets() const { return run_targets_; } + std::string_view initial_run_target() const { return initial_run_target_; } + const std::optional& fallback_run_target() const { return fallback_run_target_; } + const std::optional& alive_supervision() const { return alive_supervision_; } + const std::optional& watchdog() const { return watchdog_; } + + // Ownership transfer — source is left in a moved-from state after the call + std::vector take_components() { return std::move(components_); } + std::vector take_run_targets() { return std::move(run_targets_); } + std::string take_initial_run_target() { return std::move(initial_run_target_); } + std::optional take_fallback_run_target() { return std::move(fallback_run_target_); } + std::optional take_alive_supervision() { return std::move(alive_supervision_); } + std::optional take_watchdog() { return std::move(watchdog_); } + + private: + friend class Builder; + + Config(std::vector components, + std::vector run_targets, + std::string initial_run_target, + std::optional fallback_run_target, + std::optional alive_supervision, + std::optional watchdog); + + std::vector components_; + std::vector run_targets_; + std::string initial_run_target_; + std::optional fallback_run_target_; + std::optional alive_supervision_; + std::optional watchdog_; +}; + +} // namespace score::launch_manager::config + +#endif diff --git a/src/launch_manager_daemon/config/include/config_loader.hpp b/src/launch_manager_daemon/config/include/config_loader.hpp new file mode 100644 index 000000000..451b13fdb --- /dev/null +++ b/src/launch_manager_daemon/config/include/config_loader.hpp @@ -0,0 +1,52 @@ +// ******************************************************************************* +// Copyright (c) 2026 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache License Version 2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: Apache-2.0 +// ******************************************************************************* + +#ifndef CONFIG_LOADER_HPP +#define CONFIG_LOADER_HPP + +#include "config.hpp" + +#include "score/filesystem/path.h" + +#include +#include + +namespace score::launch_manager::config { + +/// @brief Abstract interface for loading Launch Manager configuration from a file. +/// +/// Decouples the configuration consumer from the serialization format (e.g., JSON, FlatBuffers). +/// A concrete implementation parses the file and returns a format-independent @ref Config object. +class IConfigLoader { + public: + /// @brief Error codes returned when configuration loading fails. + enum class Error : std::uint32_t + { + FileNotFound, ///< The configuration file does not exist at the given path. + InsufficientPermission, ///< The process lacks read permissions for the file. + InvalidFormat, ///< The file contents could not be parsed (malformed or missing required fields). + UnsupportedVersion, ///< The file uses a configuration schema version not supported by this loader. + GeneralError ///< Any other failure not covered by the above codes. + }; + + virtual ~IConfigLoader() = default; + + /// @brief Loads and parses the configuration file at @p path. + /// @param path Filesystem path to the configuration file. + /// @return A @ref Config object on success, or an @ref Error on failure. + virtual score::cpp::expected load(const score::filesystem::Path& path) = 0; +}; + +} // namespace score::launch_manager::config + +#endif diff --git a/src/launch_manager_daemon/config/include/flatbuffer_config_loader.hpp b/src/launch_manager_daemon/config/include/flatbuffer_config_loader.hpp new file mode 100644 index 000000000..b528dd117 --- /dev/null +++ b/src/launch_manager_daemon/config/include/flatbuffer_config_loader.hpp @@ -0,0 +1,35 @@ +// ******************************************************************************* +// Copyright (c) 2026 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache License Version 2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: Apache-2.0 +// ******************************************************************************* + +#ifndef FLATBUFFER_CONFIG_LOADER_HPP +#define FLATBUFFER_CONFIG_LOADER_HPP + +#include "config_loader.hpp" + +#include +#include + +namespace score::launch_manager::config { + +class FlatbufferConfigLoader : public IConfigLoader { + public: + score::cpp::expected load(const score::filesystem::Path& path) override; + + private: + score::cpp::expected, Error> readFile(const score::filesystem::Path& path); + score::cpp::expected parseBuffer(const std::vector& buffer); +}; + +} // namespace score::launch_manager::config + +#endif // FLATBUFFER_CONFIG_LOADER_HPP diff --git a/src/launch_manager_daemon/config/src/config.cpp b/src/launch_manager_daemon/config/src/config.cpp new file mode 100644 index 000000000..e67d262ce --- /dev/null +++ b/src/launch_manager_daemon/config/src/config.cpp @@ -0,0 +1,81 @@ +// ******************************************************************************* +// Copyright (c) 2026 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache License Version 2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: Apache-2.0 +// ******************************************************************************* + +#include "config.hpp" + +#include + +namespace score::launch_manager::config { + +Config::Config(std::vector components, + std::vector run_targets, + std::string initial_run_target, + std::optional fallback_run_target, + std::optional alive_supervision, + std::optional watchdog) + : components_{std::move(components)}, + run_targets_{std::move(run_targets)}, + initial_run_target_{std::move(initial_run_target)}, + fallback_run_target_{std::move(fallback_run_target)}, + alive_supervision_{std::move(alive_supervision)}, + watchdog_{std::move(watchdog)} +{ +} + +Config::Builder& Config::Builder::setComponents(std::vector components) +{ + components_ = std::move(components); + return *this; +} + +Config::Builder& Config::Builder::setRunTargets(std::vector run_targets) +{ + run_targets_ = std::move(run_targets); + return *this; +} + +Config::Builder& Config::Builder::setInitialRunTarget(std::string initial_run_target) +{ + initial_run_target_ = std::move(initial_run_target); + return *this; +} + +Config::Builder& Config::Builder::setFallbackRunTarget(FallbackRunTargetConfig fallback) +{ + fallback_run_target_ = std::move(fallback); + return *this; +} + +Config::Builder& Config::Builder::setAliveSupervision(AliveSupervisionConfig alive_supervision) +{ + alive_supervision_ = std::move(alive_supervision); + return *this; +} + +Config::Builder& Config::Builder::setWatchdog(WatchdogConfig watchdog) +{ + watchdog_ = std::move(watchdog); + return *this; +} + +Config Config::Builder::build() +{ + return Config(std::move(components_), + std::move(run_targets_), + std::move(initial_run_target_), + std::move(fallback_run_target_), + std::move(alive_supervision_), + std::move(watchdog_)); +} + +} // namespace score::launch_manager::config diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp new file mode 100644 index 000000000..5ca87db25 --- /dev/null +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp @@ -0,0 +1,514 @@ +// ******************************************************************************* +// Copyright (c) 2026 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache License Version 2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: Apache-2.0 +// ******************************************************************************* + +#include "flatbuffer_config_loader.hpp" +#include "new_lm_flatcfg_generated.h" + +#include "score/os/errno.h" +#include "score/os/fcntl.h" +#include "score/os/stat.h" +#include "score/os/unistd.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace score::launch_manager::config { + +namespace fb = score::launch_manager::config::fb; + +namespace { + +constexpr int32_t kExpectedSchemaVersion = 1; +constexpr double kSecondsToMilliseconds = 1000.0; + +uint32_t secondsToMs(double seconds) +{ + return static_cast(seconds * kSecondsToMilliseconds); +} + +// --- Enum conversion helpers --- + +ApplicationType convertApplicationType(fb::ApplicationType fb_type) +{ + switch (fb_type) + { + case fb::ApplicationType_Reporting: + return ApplicationType::Reporting; + case fb::ApplicationType_Reporting_And_Supervised: + return ApplicationType::ReportingAndSupervised; + case fb::ApplicationType_State_Manager: + return ApplicationType::StateManager; + case fb::ApplicationType_Native: + default: + return ApplicationType::Native; + } +} + +ProcessState convertProcessState(fb::ProcessState fb_state) +{ + switch (fb_state) + { + case fb::ProcessState_Terminated: + return ProcessState::Terminated; + case fb::ProcessState_Running: + default: + return ProcessState::Running; + } +} + +// --- String/vector helpers --- + +std::string safeString(const ::flatbuffers::String* s) +{ + return s ? s->str() : std::string{}; +} + +std::vector convertStringVector( + const ::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>* vec) +{ + std::vector result; + if (vec != nullptr) + { + result.reserve(vec->size()); + for (const auto* s : *vec) + { + result.emplace_back(s ? s->str() : std::string{}); + } + } + return result; +} + +std::vector convertUint32Vector(const ::flatbuffers::Vector* vec) +{ + std::vector result; + if (vec != nullptr) + { + result.reserve(vec->size()); + for (const auto val : *vec) + { + result.emplace_back(val); + } + } + return result; +} + +std::unordered_map convertEnvironmentalVariables( + const ::flatbuffers::Vector<::flatbuffers::Offset>* vec) +{ + std::unordered_map result; + if (vec != nullptr) + { + result.reserve(vec->size()); + for (const auto* ev : *vec) + { + if (ev != nullptr && ev->key() != nullptr) + { + result.emplace(ev->key()->str(), safeString(ev->value())); + } + } + } + return result; +} + +// --- Recovery action conversion --- + +std::optional convertRecoveryAction(fb::RecoveryAction type, const void* action) +{ + switch (type) + { + case fb::RecoveryAction_RestartAction: + { + const auto* ra = static_cast(action); + if (ra == nullptr) + { + return std::nullopt; + } + return RestartAction{ra->number_of_attempts(), secondsToMs(ra->delay_before_restart())}; + } + case fb::RecoveryAction_SwitchRunTargetAction: + { + const auto* sa = static_cast(action); + if (sa == nullptr) + { + return std::nullopt; + } + return SwitchRunTargetAction{safeString(sa->run_target())}; + } + default: + return std::nullopt; + } +} + +// --- Struct conversion helpers --- + +ComponentAliveSupervision convertComponentAliveSupervision(const fb::ComponentAliveSupervision* fb_cas) +{ + ComponentAliveSupervision result{}; + if (fb_cas != nullptr) + { + result.reporting_cycle_ms = secondsToMs(fb_cas->reporting_cycle()); + result.failed_cycles_tolerance = fb_cas->failed_cycles_tolerance(); + result.min_indications = fb_cas->min_indications().value_or(0U); + result.max_indications = fb_cas->max_indications().value_or(0U); + } + return result; +} + +ApplicationProfile convertApplicationProfile(const fb::ApplicationProfile* fb_ap) +{ + ApplicationProfile result{}; + if (fb_ap != nullptr) + { + result.application_type = convertApplicationType(fb_ap->application_type()); + result.is_self_terminating = fb_ap->is_self_terminating(); + if (fb_ap->alive_supervision() != nullptr) + { + result.alive_supervision = convertComponentAliveSupervision(fb_ap->alive_supervision()); + } + } + return result; +} + +ReadyCondition convertReadyCondition(const fb::ReadyCondition* fb_rc) +{ + ReadyCondition result{ProcessState::Running}; + if (fb_rc != nullptr) + { + const auto opt = fb_rc->process_state(); + if (opt.has_value()) + { + result.process_state = convertProcessState(*opt); + } + } + return result; +} + +ComponentProperties convertComponentProperties(const fb::ComponentProperties* fb_cp) +{ + ComponentProperties result{}; + if (fb_cp != nullptr) + { + result.binary_name = safeString(fb_cp->binary_name()); + result.application_profile = convertApplicationProfile(fb_cp->application_profile()); + result.depends_on = convertStringVector(fb_cp->depends_on()); + result.process_arguments = convertStringVector(fb_cp->process_arguments()); + result.ready_condition = convertReadyCondition(fb_cp->ready_condition()); + } + return result; +} + +std::optional convertSandbox(const fb::Sandbox* fb_sb) +{ + if (fb_sb == nullptr) + { + return std::nullopt; + } + Sandbox result{}; + result.uid = fb_sb->uid(); + result.gid = fb_sb->gid(); + result.supplementary_group_ids = convertUint32Vector(fb_sb->supplementary_group_ids()); + result.security_policy = + fb_sb->security_policy() != nullptr ? std::optional{fb_sb->security_policy()->str()} + : std::nullopt; + result.scheduling_policy = safeString(fb_sb->scheduling_policy()); + result.scheduling_priority = fb_sb->scheduling_priority().value_or(0); + result.max_memory_usage = fb_sb->max_memory_usage().has_value() + ? std::optional{*fb_sb->max_memory_usage()} + : std::nullopt; + result.max_cpu_usage = + fb_sb->max_cpu_usage().has_value() ? std::optional{*fb_sb->max_cpu_usage()} : std::nullopt; + return result; +} + +DeploymentConfig convertDeploymentConfig(const fb::DeploymentConfig* fb_dc) +{ + DeploymentConfig result{}; + if (fb_dc != nullptr) + { + result.ready_timeout_ms = secondsToMs(fb_dc->ready_timeout()); + result.shutdown_timeout_ms = secondsToMs(fb_dc->shutdown_timeout()); + result.environmental_variables = convertEnvironmentalVariables(fb_dc->environmental_variables()); + result.bin_dir = safeString(fb_dc->bin_dir()); + result.working_dir = safeString(fb_dc->working_dir()); + result.ready_recovery_action = + convertRecoveryAction(fb_dc->ready_recovery_action_type(), fb_dc->ready_recovery_action()); + result.recovery_action = convertRecoveryAction(fb_dc->recovery_action_type(), fb_dc->recovery_action()); + result.sandbox = convertSandbox(fb_dc->sandbox()); + } + return result; +} + +ComponentConfig convertComponent(const fb::Component* fb_comp) +{ + ComponentConfig result{}; + if (fb_comp != nullptr) + { + result.name = safeString(fb_comp->name()); + result.description = safeString(fb_comp->description()); + result.component_properties = convertComponentProperties(fb_comp->component_properties()); + result.deployment_config = convertDeploymentConfig(fb_comp->deployment_config()); + } + return result; +} + +RunTargetConfig convertRunTarget(const fb::RunTarget* fb_rt) +{ + RunTargetConfig result{}; + if (fb_rt != nullptr) + { + result.name = safeString(fb_rt->name()); + result.description = safeString(fb_rt->description()); + result.depends_on = convertStringVector(fb_rt->depends_on()); + result.transition_timeout_ms = secondsToMs(fb_rt->transition_timeout()); + result.recovery_action = convertRecoveryAction(fb_rt->recovery_action_type(), fb_rt->recovery_action()); + } + return result; +} + +FallbackRunTargetConfig convertFallbackRunTarget(const fb::FallbackRunTarget* fb_frt) +{ + FallbackRunTargetConfig result{}; + if (fb_frt != nullptr) + { + result.description = safeString(fb_frt->description()); + result.depends_on = convertStringVector(fb_frt->depends_on()); + result.transition_timeout_ms = secondsToMs(fb_frt->transition_timeout()); + } + return result; +} + +std::optional convertAliveSupervision(const fb::AliveSupervision* fb_as) +{ + if (fb_as == nullptr) + { + return std::nullopt; + } + return AliveSupervisionConfig{secondsToMs(fb_as->evaluation_cycle())}; +} + +std::optional convertWatchdog(const fb::Watchdog* fb_wd) +{ + if (fb_wd == nullptr) + { + return std::nullopt; + } + WatchdogConfig result{}; + result.device_file_path = safeString(fb_wd->device_file_path()); + result.max_timeout_ms = secondsToMs(fb_wd->max_timeout()); + result.deactivate_on_shutdown = fb_wd->deactivate_on_shutdown().has_value() ? *fb_wd->deactivate_on_shutdown() : false; + result.require_magic_close = fb_wd->require_magic_close().has_value() ? *fb_wd->require_magic_close() : false; + return result; +} + +// --- File I/O error mapping --- + +IConfigLoader::Error mapOsError(const score::os::Error& error) +{ + if (error == score::os::Error::Code::kNoSuchFileOrDirectory) + { + return IConfigLoader::Error::FileNotFound; + } + if (error == score::os::Error::Code::kPermissionDenied) + { + return IConfigLoader::Error::InsufficientPermission; + } + return IConfigLoader::Error::GeneralError; +} + +} // anonymous namespace + +// --- Public interface --- + +score::cpp::expected FlatbufferConfigLoader::load(const score::filesystem::Path& path) +{ + auto buffer_result = readFile(path); + if (!buffer_result.has_value()) + { + return score::cpp::make_unexpected(buffer_result.error()); + } + return parseBuffer(buffer_result.value()); +} + +// --- File loading using OS abstractions --- + +score::cpp::expected, IConfigLoader::Error> FlatbufferConfigLoader::readFile( + const score::filesystem::Path& path) +{ + auto& fcntl = score::os::Fcntl::instance(); + auto& stat = score::os::Stat::instance(); + auto& unistd = score::os::Unistd::instance(); + + const auto fd_result = fcntl.open(path.CStr(), score::os::Fcntl::Open::kReadOnly); + if (!fd_result.has_value()) + { + return score::cpp::make_unexpected(mapOsError(fd_result.error())); + } + const std::int32_t file_desc = fd_result.value(); + + auto close_fd = [&unistd, file_desc](const IConfigLoader::Error* prior_error) + -> score::cpp::expected, IConfigLoader::Error> { + unistd.close(file_desc); + if (prior_error != nullptr) + { + return score::cpp::make_unexpected(*prior_error); + } + return score::cpp::make_unexpected(IConfigLoader::Error::GeneralError); + }; + + score::os::StatBuffer stat_buf{}; + const auto stat_result = stat.fstat(file_desc, stat_buf); + if (!stat_result.has_value()) + { + auto err = IConfigLoader::Error::GeneralError; + return close_fd(&err); + } + + if (stat_buf.st_size <= 0) + { + auto err = IConfigLoader::Error::InvalidFormat; + return close_fd(&err); + } + + const auto file_size = static_cast(stat_buf.st_size); + std::vector buffer; + try + { + buffer.resize(file_size); + } + catch (const std::bad_alloc&) + { + auto err = IConfigLoader::Error::GeneralError; + return close_fd(&err); + } + + std::size_t total_bytes_read = 0U; + while (total_bytes_read < file_size) + { + const auto read_result = unistd.read( + file_desc, + std::next(buffer.data(), static_cast(total_bytes_read)), + file_size - total_bytes_read); + if (!read_result.has_value()) + { + if (read_result.error() == score::os::Error::Code::kOperationWasInterruptedBySignal) + { + continue; + } + auto err = IConfigLoader::Error::GeneralError; + return close_fd(&err); + } + + const auto bytes_read = read_result.value(); + if (bytes_read == 0) + { + auto err = IConfigLoader::Error::GeneralError; + return close_fd(&err); + } + + total_bytes_read += static_cast(bytes_read); + } + + const auto close_result = unistd.close(file_desc); + if (!close_result.has_value()) + { + return score::cpp::make_unexpected(IConfigLoader::Error::GeneralError); + } + + return buffer; +} + +// --- FlatBuffer parsing and conversion --- + +score::cpp::expected FlatbufferConfigLoader::parseBuffer( + const std::vector& buffer) +{ + ::flatbuffers::Verifier verifier(buffer.data(), buffer.size()); + if (!fb::VerifyLaunchManagerConfigBuffer(verifier)) + { + return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); + } + + const auto* config = fb::GetLaunchManagerConfig(buffer.data()); + if (config == nullptr) + { + return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); + } + + if (config->schema_version() != kExpectedSchemaVersion) + { + return score::cpp::make_unexpected(IConfigLoader::Error::UnsupportedVersion); + } + + if (config->initial_run_target() == nullptr) + { + return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); + } + + Config::Builder builder; + builder.setInitialRunTarget(config->initial_run_target()->str()); + + if (config->components() != nullptr) + { + std::vector components; + components.reserve(config->components()->size()); + for (const auto* comp : *config->components()) + { + if (comp != nullptr) + { + components.emplace_back(convertComponent(comp)); + } + } + builder.setComponents(std::move(components)); + } + + if (config->run_targets() != nullptr) + { + std::vector run_targets; + run_targets.reserve(config->run_targets()->size()); + for (const auto* rt : *config->run_targets()) + { + if (rt != nullptr) + { + run_targets.emplace_back(convertRunTarget(rt)); + } + } + builder.setRunTargets(std::move(run_targets)); + } + + if (config->fallback_run_target() != nullptr) + { + builder.setFallbackRunTarget(convertFallbackRunTarget(config->fallback_run_target())); + } + + auto alive_sup = convertAliveSupervision(config->alive_supervision()); + if (alive_sup.has_value()) + { + builder.setAliveSupervision(std::move(*alive_sup)); + } + + auto wd = convertWatchdog(config->watchdog()); + if (wd.has_value()) + { + builder.setWatchdog(std::move(*wd)); + } + + return builder.build(); +} + +} // namespace score::launch_manager::config diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp new file mode 100644 index 000000000..9871fafb5 --- /dev/null +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp @@ -0,0 +1,987 @@ +// ******************************************************************************* +// Copyright (c) 2026 Contributors to the Eclipse Foundation +// +// See the NOTICE file(s) distributed with this work for additional +// information regarding copyright ownership. +// +// This program and the accompanying materials are made available under the +// terms of the Apache License Version 2.0 which is available at +// https://www.apache.org/licenses/LICENSE-2.0 +// +// SPDX-License-Identifier: Apache-2.0 +// ******************************************************************************* + +#include "flatbuffer_config_loader.hpp" +#include "new_lm_flatcfg_generated.h" + +#include "score/filesystem/path.h" +#include "score/os/ObjectSeam.h" +#include "score/os/mocklib/fcntl_mock.h" +#include "score/os/mocklib/stat_mock.h" +#include "score/os/mocklib/unistdmock.h" + +#include +#include + +#include +#include +#include + +namespace score::launch_manager::config { +namespace { + +namespace fb = score::launch_manager::config::fb; + +using ::testing::_; +using ::testing::DoAll; +using ::testing::Eq; +using ::testing::Invoke; +using ::testing::IsFalse; +using ::testing::IsTrue; +using ::testing::NiceMock; +using ::testing::Return; + +constexpr std::int32_t kTestFd = 42; +const score::filesystem::Path kTestPath{"/tmp/test_config.bin"}; + +std::vector finishBuffer(::flatbuffers::FlatBufferBuilder& fbb, + ::flatbuffers::Offset root) +{ + fb::FinishLaunchManagerConfigBuffer(fbb, root); + const auto* buf = fbb.GetBufferPointer(); + return {buf, buf + fbb.GetSize()}; +} + +class FlatbufferConfigLoaderTest : public ::testing::Test { + protected: + void SetUp() override + { + RecordProperty("TestType", "interface-test"); + RecordProperty("DerivationTechnique", "explorative-testing "); + } + + void setUpSuccessfulFileRead(const std::vector& content) + { + ON_CALL(*fcntl_mock_, open(_, _)) + .WillByDefault(Return(score::cpp::expected{kTestFd})); + + ON_CALL(*stat_mock_, fstat(kTestFd, _)) + .WillByDefault( + DoAll(Invoke([size = static_cast(content.size())](std::int32_t, + score::os::StatBuffer& buf) { + buf.st_size = size; + }), + Return(score::cpp::expected_blank{}))); + + ON_CALL(*unistd_mock_, read(kTestFd, _, _)) + .WillByDefault( + Invoke([&content](std::int32_t, void* buf, std::size_t count) + -> score::cpp::expected { + const auto bytes = std::min(count, content.size()); + std::memcpy(buf, content.data(), bytes); + return static_cast(bytes); + })); + + ON_CALL(*unistd_mock_, close(kTestFd)) + .WillByDefault(Return(score::cpp::expected_blank{})); + } + + std::vector buildMinimalConfig(int32_t schema_version = 1, + const char* initial_run_target = "Startup") + { + ::flatbuffers::FlatBufferBuilder fbb; + auto irt = fbb.CreateString(initial_run_target); + auto fallback = fb::CreateFallbackRunTarget(fbb); + auto alive_sup = fb::CreateAliveSupervision(fbb); + auto config = fb::CreateLaunchManagerConfig( + fbb, schema_version, 0 /*components*/, 0 /*run_targets*/, irt, fallback, alive_sup); + return finishBuffer(fbb, config); + } + + score::os::MockGuard> fcntl_mock_; + score::os::MockGuard> stat_mock_; + score::os::MockGuard> unistd_mock_; + FlatbufferConfigLoader loader_; +}; + +// ============================================================================ +// Happy path tests +// ============================================================================ + +TEST_F(FlatbufferConfigLoaderTest, LoadMinimalConfig) +{ + RecordProperty("Description", "Loads a minimal config with only required fields."); + + // GIVEN + auto buffer = buildMinimalConfig(1, "Startup"); + setUpSuccessfulFileRead(buffer); + + // WHEN + auto result = loader_.load(kTestPath); + + // THEN + ASSERT_THAT(result.has_value(), IsTrue()); + EXPECT_THAT(result->initial_run_target(), Eq("Startup")); + EXPECT_THAT(result->components().empty(), IsTrue()); + EXPECT_THAT(result->run_targets().empty(), IsTrue()); + EXPECT_THAT(result->fallback_run_target().has_value(), IsTrue()); + EXPECT_THAT(result->alive_supervision().has_value(), IsTrue()); + EXPECT_THAT(result->watchdog().has_value(), IsFalse()); +} + +TEST_F(FlatbufferConfigLoaderTest, LoadSingleComponent) +{ + RecordProperty("Description", "Loads a config with one fully-populated component."); + + // GIVEN + ::flatbuffers::FlatBufferBuilder fbb; + + auto alive_sup = fb::CreateComponentAliveSupervision(fbb, + 0.5 /*reporting_cycle*/, 2 /*failed_cycles_tolerance*/, 1 /*min_indications*/, 3 /*max_indications*/); + auto app_profile = + fb::CreateApplicationProfile(fbb, fb::ApplicationType_Reporting_And_Supervised, true /*is_self_terminating*/, alive_sup); + auto bin_name = fbb.CreateString("my_binary"); + auto dep = fbb.CreateString("other_comp"); + auto deps_vec = fbb.CreateVector(std::vector<::flatbuffers::Offset<::flatbuffers::String>>{dep}); + auto arg = fbb.CreateString("--verbose"); + auto args_vec = fbb.CreateVector(std::vector<::flatbuffers::Offset<::flatbuffers::String>>{arg}); + auto ready_cond = fb::CreateReadyCondition(fbb, fb::ProcessState_Running); + auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile, deps_vec, args_vec, ready_cond); + + auto bin_dir = fbb.CreateString("/opt/bin"); + auto work_dir = fbb.CreateString("/tmp"); + auto deploy = fb::CreateDeploymentConfig(fbb, + 1.5 /*ready_timeout*/, 2.5 /*shutdown_timeout*/, 0 /*environmental_variables*/, bin_dir, work_dir); + + auto comp_name = fbb.CreateString("TestComponent"); + auto comp_desc = fbb.CreateString("A test component"); + auto component = fb::CreateComponent(fbb, comp_name, comp_desc, comp_props, deploy); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{component}); + + auto fallback = fb::CreateFallbackRunTarget(fbb); + auto global_alive_sup = fb::CreateAliveSupervision(fbb); + auto irt = fbb.CreateString("Startup"); + auto config = fb::CreateLaunchManagerConfig(fbb, + 1 /*schema_version*/, comps, 0 /*run_targets*/, irt, fallback, global_alive_sup); + auto buffer = finishBuffer(fbb, config); + setUpSuccessfulFileRead(buffer); + + // WHEN + auto result = loader_.load(kTestPath); + + // THEN + ASSERT_THAT(result.has_value(), IsTrue()); + ASSERT_THAT(result->components().size(), Eq(1U)); + + const auto& comp = result->components()[0]; + EXPECT_THAT(comp.name, Eq("TestComponent")); + EXPECT_THAT(comp.description, Eq("A test component")); + EXPECT_THAT(comp.component_properties.binary_name, Eq("my_binary")); + EXPECT_THAT(comp.component_properties.application_profile.application_type, Eq(ApplicationType::ReportingAndSupervised)); + EXPECT_THAT(comp.component_properties.application_profile.is_self_terminating, IsTrue()); + ASSERT_THAT(comp.component_properties.application_profile.alive_supervision.has_value(), IsTrue()); + EXPECT_THAT(comp.component_properties.application_profile.alive_supervision->reporting_cycle_ms, Eq(500U)); + EXPECT_THAT(comp.component_properties.application_profile.alive_supervision->failed_cycles_tolerance, Eq(2U)); + EXPECT_THAT(comp.component_properties.application_profile.alive_supervision->min_indications, Eq(1U)); + EXPECT_THAT(comp.component_properties.application_profile.alive_supervision->max_indications, Eq(3U)); + ASSERT_THAT(comp.component_properties.depends_on.size(), Eq(1U)); + EXPECT_THAT(comp.component_properties.depends_on[0], Eq("other_comp")); + ASSERT_THAT(comp.component_properties.process_arguments.size(), Eq(1U)); + EXPECT_THAT(comp.component_properties.process_arguments[0], Eq("--verbose")); + EXPECT_THAT(comp.component_properties.ready_condition.process_state, Eq(ProcessState::Running)); + EXPECT_THAT(comp.deployment_config.ready_timeout_ms, Eq(1500U)); + EXPECT_THAT(comp.deployment_config.shutdown_timeout_ms, Eq(2500U)); + EXPECT_THAT(comp.deployment_config.bin_dir, Eq("/opt/bin")); + EXPECT_THAT(comp.deployment_config.working_dir, Eq("/tmp")); +} + +TEST_F(FlatbufferConfigLoaderTest, LoadRunTargets) +{ + RecordProperty("Description", "Loads run targets with dependencies and transition timeout."); + + // GIVEN + ::flatbuffers::FlatBufferBuilder fbb; + + auto switch_target = fbb.CreateString("SafeState"); + auto switch_action = fb::CreateSwitchRunTargetAction(fbb, switch_target); + auto rt_name = fbb.CreateString("Startup"); + auto rt_desc = fbb.CreateString("Initial state"); + auto rt_dep = fbb.CreateString("component_a"); + auto rt_deps = fbb.CreateVector(std::vector<::flatbuffers::Offset<::flatbuffers::String>>{rt_dep}); + auto rt = fb::CreateRunTarget(fbb, rt_name, rt_desc, rt_deps, 5.0 /*transition_timeout*/, + fb::RecoveryAction_SwitchRunTargetAction, switch_action.Union()); + auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{rt}); + + auto fallback = fb::CreateFallbackRunTarget(fbb); + auto alive_sup = fb::CreateAliveSupervision(fbb); + auto irt = fbb.CreateString("Startup"); + auto config = fb::CreateLaunchManagerConfig(fbb, + 1 /*schema_version*/, 0 /*components*/, rts, irt, fallback, alive_sup); + auto buffer = finishBuffer(fbb, config); + setUpSuccessfulFileRead(buffer); + + // WHEN + auto result = loader_.load(kTestPath); + + // THEN + ASSERT_THAT(result.has_value(), IsTrue()); + ASSERT_THAT(result->run_targets().size(), Eq(1U)); + + const auto& target = result->run_targets()[0]; + EXPECT_THAT(target.name, Eq("Startup")); + EXPECT_THAT(target.description, Eq("Initial state")); + ASSERT_THAT(target.depends_on.size(), Eq(1U)); + EXPECT_THAT(target.depends_on[0], Eq("component_a")); + EXPECT_THAT(target.transition_timeout_ms, Eq(5000U)); + ASSERT_THAT(target.recovery_action.has_value(), IsTrue()); + ASSERT_THAT(std::holds_alternative(target.recovery_action.value()), IsTrue()); + EXPECT_THAT(std::get(target.recovery_action.value()).run_target, Eq("SafeState")); +} + +TEST_F(FlatbufferConfigLoaderTest, LoadFallbackRunTarget) +{ + RecordProperty("Description", "Loads fallback run target with all fields."); + + // GIVEN + ::flatbuffers::FlatBufferBuilder fbb; + + auto fb_desc = fbb.CreateString("Fallback state"); + auto fb_dep = fbb.CreateString("critical_comp"); + auto fb_deps = fbb.CreateVector(std::vector<::flatbuffers::Offset<::flatbuffers::String>>{fb_dep}); + auto fallback = fb::CreateFallbackRunTarget(fbb, fb_desc, fb_deps, 10.0 /*transition_timeout*/); + + auto alive_sup = fb::CreateAliveSupervision(fbb); + auto irt = fbb.CreateString("Startup"); + auto config = fb::CreateLaunchManagerConfig(fbb, + 1 /*schema_version*/, 0 /*components*/, 0 /*run_targets*/, irt, fallback, alive_sup); + auto buffer = finishBuffer(fbb, config); + setUpSuccessfulFileRead(buffer); + + // WHEN + auto result = loader_.load(kTestPath); + + // THEN + ASSERT_THAT(result.has_value(), IsTrue()); + ASSERT_THAT(result->fallback_run_target().has_value(), IsTrue()); + + const auto& fb = result->fallback_run_target().value(); + EXPECT_THAT(fb.description, Eq("Fallback state")); + ASSERT_THAT(fb.depends_on.size(), Eq(1U)); + EXPECT_THAT(fb.depends_on[0], Eq("critical_comp")); + EXPECT_THAT(fb.transition_timeout_ms, Eq(10000U)); +} + +TEST_F(FlatbufferConfigLoaderTest, LoadAliveSupervision) +{ + RecordProperty("Description", "Loads global alive supervision config."); + + // GIVEN + ::flatbuffers::FlatBufferBuilder fbb; + + auto alive_sup = fb::CreateAliveSupervision(fbb, 0.25 /*evaluation_cycle*/); + auto fallback = fb::CreateFallbackRunTarget(fbb); + + auto irt = fbb.CreateString("Startup"); + auto config = fb::CreateLaunchManagerConfig(fbb, + 1 /*schema_version*/, 0 /*components*/, 0 /*run_targets*/, irt, fallback, alive_sup); + auto buffer = finishBuffer(fbb, config); + setUpSuccessfulFileRead(buffer); + + // WHEN + auto result = loader_.load(kTestPath); + + // THEN + ASSERT_THAT(result.has_value(), IsTrue()); + ASSERT_THAT(result->alive_supervision().has_value(), IsTrue()); + EXPECT_THAT(result->alive_supervision()->evaluation_cycle_ms, Eq(250U)); +} + +TEST_F(FlatbufferConfigLoaderTest, LoadWatchdog) +{ + RecordProperty("Description", "Loads watchdog config with all fields."); + + // GIVEN + ::flatbuffers::FlatBufferBuilder fbb; + + auto dev_path = fbb.CreateString("/dev/watchdog0"); + auto watchdog = fb::CreateWatchdog(fbb, dev_path, + 30.0 /*max_timeout*/, true /*deactivate_on_shutdown*/, false /*require_magic_close*/); + + auto fallback = fb::CreateFallbackRunTarget(fbb); + auto alive_sup = fb::CreateAliveSupervision(fbb); + auto irt = fbb.CreateString("Startup"); + auto config = fb::CreateLaunchManagerConfig(fbb, + 1 /*schema_version*/, 0 /*components*/, 0 /*run_targets*/, irt, fallback, alive_sup, watchdog); + auto buffer = finishBuffer(fbb, config); + setUpSuccessfulFileRead(buffer); + + // WHEN + auto result = loader_.load(kTestPath); + + // THEN + ASSERT_THAT(result.has_value(), IsTrue()); + ASSERT_THAT(result->watchdog().has_value(), IsTrue()); + + const auto& wd = result->watchdog().value(); + EXPECT_THAT(wd.device_file_path, Eq("/dev/watchdog0")); + EXPECT_THAT(wd.max_timeout_ms, Eq(30000U)); + EXPECT_THAT(wd.deactivate_on_shutdown, IsTrue()); + EXPECT_THAT(wd.require_magic_close, IsFalse()); +} + +TEST_F(FlatbufferConfigLoaderTest, LoadRestartRecoveryAction) +{ + RecordProperty("Description", "Recovery action variant holds RestartAction with correct fields."); + + // GIVEN + ::flatbuffers::FlatBufferBuilder fbb; + + auto restart = fb::CreateRestartAction(fbb, 3 /*number_of_attempts*/, 1.5 /*delay_before_restart*/); + auto rt_name = fbb.CreateString("Startup"); + auto rt = fb::CreateRunTarget( + fbb, rt_name, 0 /*description*/, 0 /*depends_on*/, 0.0 /*transition_timeout*/, + fb::RecoveryAction_RestartAction, restart.Union()); + auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{rt}); + + auto fallback = fb::CreateFallbackRunTarget(fbb); + auto alive_sup = fb::CreateAliveSupervision(fbb); + auto irt = fbb.CreateString("Startup"); + auto config = fb::CreateLaunchManagerConfig(fbb, + 1 /*schema_version*/, 0 /*components*/, rts, irt, fallback, alive_sup); + auto buffer = finishBuffer(fbb, config); + setUpSuccessfulFileRead(buffer); + + // WHEN + auto result = loader_.load(kTestPath); + + // THEN + ASSERT_THAT(result.has_value(), IsTrue()); + ASSERT_THAT(result->run_targets().size(), Eq(1U)); + ASSERT_THAT(result->run_targets()[0].recovery_action.has_value(), IsTrue()); + + const auto& action = result->run_targets()[0].recovery_action.value(); + ASSERT_THAT(std::holds_alternative(action), IsTrue()); + + const auto& ra = std::get(action); + EXPECT_THAT(ra.number_of_attempts, Eq(3U)); + EXPECT_THAT(ra.delay_before_restart_ms, Eq(1500U)); +} + +TEST_F(FlatbufferConfigLoaderTest, LoadSwitchRunTargetAction) +{ + RecordProperty("Description", "Recovery action variant holds SwitchRunTargetAction."); + + // GIVEN + ::flatbuffers::FlatBufferBuilder fbb; + + auto target_name = fbb.CreateString("Fallback"); + auto switch_action = fb::CreateSwitchRunTargetAction(fbb, target_name); + auto rt_name = fbb.CreateString("Startup"); + auto rt = fb::CreateRunTarget( + fbb, rt_name, 0 /*description*/, 0 /*depends_on*/, 0.0 /*transition_timeout*/, + fb::RecoveryAction_SwitchRunTargetAction, switch_action.Union()); + auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{rt}); + + auto fallback = fb::CreateFallbackRunTarget(fbb); + auto alive_sup = fb::CreateAliveSupervision(fbb); + auto irt = fbb.CreateString("Startup"); + auto config = fb::CreateLaunchManagerConfig(fbb, + 1 /*schema_version*/, 0 /*components*/, rts, irt, fallback, alive_sup); + auto buffer = finishBuffer(fbb, config); + setUpSuccessfulFileRead(buffer); + + // WHEN + auto result = loader_.load(kTestPath); + + // THEN + ASSERT_THAT(result.has_value(), IsTrue()); + ASSERT_THAT(result->run_targets()[0].recovery_action.has_value(), IsTrue()); + + const auto& action = result->run_targets()[0].recovery_action.value(); + ASSERT_THAT(std::holds_alternative(action), IsTrue()); + EXPECT_THAT(std::get(action).run_target, Eq("Fallback")); +} + +TEST_F(FlatbufferConfigLoaderTest, LoadSandbox) +{ + RecordProperty("Description", "Loads sandbox config including optional fields."); + + // GIVEN + ::flatbuffers::FlatBufferBuilder fbb; + + auto sec_policy = fbb.CreateString("strict"); + auto sched_policy = fbb.CreateString("SCHED_FIFO"); + auto supp_gids = fbb.CreateVector(std::vector{100, 200}); + auto sandbox = fb::CreateSandbox(fbb, + 1000 /*uid*/, 1000 /*gid*/, supp_gids, sec_policy, sched_policy, + 50 /*scheduling_priority*/, 4096 /*max_memory_usage*/, 80 /*max_cpu_usage*/); + + auto sb_bin_name = fbb.CreateString("sandboxed_bin"); + auto sb_app_profile = fb::CreateApplicationProfile(fbb); + auto sb_ready_cond = fb::CreateReadyCondition(fbb); + auto sb_comp_props = fb::CreateComponentProperties(fbb, sb_bin_name, sb_app_profile, + 0 /*depends_on*/, 0 /*process_arguments*/, sb_ready_cond); + + auto bin_dir = fbb.CreateString("/opt"); + auto work_dir = fbb.CreateString("/tmp"); + auto deploy = fb::CreateDeploymentConfig(fbb, + 0.5 /*ready_timeout*/, 0.5 /*shutdown_timeout*/, 0 /*environmental_variables*/, bin_dir, work_dir, + fb::RecoveryAction_NONE, 0 /*ready_recovery_action*/, + fb::RecoveryAction_NONE, 0 /*recovery_action*/, sandbox); + + auto comp_name = fbb.CreateString("sandboxed_comp"); + auto component = fb::CreateComponent(fbb, comp_name, 0 /*description*/, sb_comp_props, deploy); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{component}); + + auto fallback = fb::CreateFallbackRunTarget(fbb); + auto alive_sup = fb::CreateAliveSupervision(fbb); + auto irt = fbb.CreateString("Startup"); + auto config = fb::CreateLaunchManagerConfig(fbb, + 1 /*schema_version*/, comps, 0 /*run_targets*/, irt, fallback, alive_sup); + auto buffer = finishBuffer(fbb, config); + setUpSuccessfulFileRead(buffer); + + // WHEN + auto result = loader_.load(kTestPath); + + // THEN + ASSERT_THAT(result.has_value(), IsTrue()); + ASSERT_THAT(result->components().size(), Eq(1U)); + ASSERT_THAT(result->components()[0].deployment_config.sandbox.has_value(), IsTrue()); + + const auto& sb = result->components()[0].deployment_config.sandbox.value(); + EXPECT_THAT(sb.uid, Eq(1000U)); + EXPECT_THAT(sb.gid, Eq(1000U)); + EXPECT_THAT(sb.supplementary_group_ids, Eq(std::vector{100, 200})); + ASSERT_THAT(sb.security_policy.has_value(), IsTrue()); + EXPECT_THAT(sb.security_policy.value(), Eq("strict")); + EXPECT_THAT(sb.scheduling_policy, Eq("SCHED_FIFO")); + EXPECT_THAT(sb.scheduling_priority, Eq(50)); + ASSERT_THAT(sb.max_memory_usage.has_value(), IsTrue()); + EXPECT_THAT(sb.max_memory_usage.value(), Eq(4096U)); + ASSERT_THAT(sb.max_cpu_usage.has_value(), IsTrue()); + EXPECT_THAT(sb.max_cpu_usage.value(), Eq(80U)); +} + +TEST_F(FlatbufferConfigLoaderTest, LoadComponentAliveSupervision) +{ + RecordProperty("Description", "Per-component alive supervision is mapped correctly."); + + // GIVEN + ::flatbuffers::FlatBufferBuilder fbb; + + auto comp_alive_sup = fb::CreateComponentAliveSupervision(fbb, + 1.0 /*reporting_cycle*/, 3 /*failed_cycles_tolerance*/, 2 /*min_indications*/, 5 /*max_indications*/); + auto app_profile = fb::CreateApplicationProfile(fbb, + fb::ApplicationType_Reporting_And_Supervised, false /*is_self_terminating*/, comp_alive_sup); + auto bin_name = fbb.CreateString("supervised_bin"); + auto ready_cond = fb::CreateReadyCondition(fbb); + auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile, + 0 /*depends_on*/, 0 /*process_arguments*/, ready_cond); + + auto bin_dir = fbb.CreateString("/opt"); + auto deploy = fb::CreateDeploymentConfig(fbb, + 0.0 /*ready_timeout*/, 0.0 /*shutdown_timeout*/, 0 /*environmental_variables*/, bin_dir); + + auto comp_name = fbb.CreateString("supervised_comp"); + auto component = fb::CreateComponent(fbb, comp_name, 0 /*description*/, comp_props, deploy); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{component}); + + auto fallback = fb::CreateFallbackRunTarget(fbb); + auto alive_sup = fb::CreateAliveSupervision(fbb); + auto irt = fbb.CreateString("Startup"); + auto config = fb::CreateLaunchManagerConfig(fbb, + 1 /*schema_version*/, comps, 0 /*run_targets*/, irt, fallback, alive_sup); + auto buffer = finishBuffer(fbb, config); + setUpSuccessfulFileRead(buffer); + + // WHEN + auto result = loader_.load(kTestPath); + + // THEN + ASSERT_THAT(result.has_value(), IsTrue()); + const auto& as = result->components()[0].component_properties.application_profile.alive_supervision; + ASSERT_THAT(as.has_value(), IsTrue()); + EXPECT_THAT(as->reporting_cycle_ms, Eq(1000U)); + EXPECT_THAT(as->failed_cycles_tolerance, Eq(3U)); + EXPECT_THAT(as->min_indications, Eq(2U)); + EXPECT_THAT(as->max_indications, Eq(5U)); +} + +TEST_F(FlatbufferConfigLoaderTest, LoadEnvironmentalVariables) +{ + RecordProperty("Description", "Environmental variables vector is mapped to unordered_map."); + + // GIVEN + ::flatbuffers::FlatBufferBuilder fbb; + + auto k1 = fbb.CreateString("PATH"); + auto v1 = fbb.CreateString("/usr/bin"); + auto ev1 = fb::CreateEnvironmentalVariable(fbb, k1, v1); + auto k2 = fbb.CreateString("HOME"); + auto v2 = fbb.CreateString("/root"); + auto ev2 = fb::CreateEnvironmentalVariable(fbb, k2, v2); + auto env_vars = fbb.CreateVector(std::vector<::flatbuffers::Offset>{ev1, ev2}); + + auto env_bin_name = fbb.CreateString("env_bin"); + auto env_app_profile = fb::CreateApplicationProfile(fbb); + auto env_ready_cond = fb::CreateReadyCondition(fbb); + auto env_comp_props = fb::CreateComponentProperties(fbb, env_bin_name, env_app_profile, + 0 /*depends_on*/, 0 /*process_arguments*/, env_ready_cond); + + auto bin_dir = fbb.CreateString("/opt"); + auto work_dir = fbb.CreateString("/tmp"); + auto deploy = fb::CreateDeploymentConfig(fbb, + 0.5 /*ready_timeout*/, 0.5 /*shutdown_timeout*/, env_vars, bin_dir, work_dir); + + auto comp_name = fbb.CreateString("env_comp"); + auto component = fb::CreateComponent(fbb, comp_name, 0 /*description*/, env_comp_props, deploy); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{component}); + + auto fallback = fb::CreateFallbackRunTarget(fbb); + auto alive_sup = fb::CreateAliveSupervision(fbb); + auto irt = fbb.CreateString("Startup"); + auto config = fb::CreateLaunchManagerConfig(fbb, + 1 /*schema_version*/, comps, 0 /*run_targets*/, irt, fallback, alive_sup); + auto buffer = finishBuffer(fbb, config); + setUpSuccessfulFileRead(buffer); + + // WHEN + auto result = loader_.load(kTestPath); + + // THEN + ASSERT_THAT(result.has_value(), IsTrue()); + const auto& env = result->components()[0].deployment_config.environmental_variables; + EXPECT_THAT(env.size(), Eq(2U)); + EXPECT_THAT(env.at("PATH"), Eq("/usr/bin")); + EXPECT_THAT(env.at("HOME"), Eq("/root")); +} + +TEST_F(FlatbufferConfigLoaderTest, LoadMultipleComponents) +{ + RecordProperty("Description", "Multiple components are all present and in order."); + + // GIVEN + ::flatbuffers::FlatBufferBuilder fbb; + + auto make_component = [&fbb](const char* name) { + auto comp_name = fbb.CreateString(name); + auto bin_name = fbb.CreateString(name); + auto app_profile = fb::CreateApplicationProfile(fbb); + auto ready_cond = fb::CreateReadyCondition(fbb); + auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile, + 0 /*depends_on*/, 0 /*process_arguments*/, ready_cond); + auto bin_dir = fbb.CreateString("/opt"); + auto deploy = fb::CreateDeploymentConfig(fbb, + 0.0 /*ready_timeout*/, 0.0 /*shutdown_timeout*/, 0 /*environmental_variables*/, bin_dir); + return fb::CreateComponent(fbb, comp_name, 0 /*description*/, comp_props, deploy); + }; + + auto comp_a = make_component("CompA"); + auto comp_b = make_component("CompB"); + auto comp_c = make_component("CompC"); + auto comps = fbb.CreateVector( + std::vector<::flatbuffers::Offset>{comp_a, comp_b, comp_c}); + + auto fallback = fb::CreateFallbackRunTarget(fbb); + auto alive_sup = fb::CreateAliveSupervision(fbb); + auto irt = fbb.CreateString("Startup"); + auto config = fb::CreateLaunchManagerConfig(fbb, + 1 /*schema_version*/, comps, 0 /*run_targets*/, irt, fallback, alive_sup); + auto buffer = finishBuffer(fbb, config); + setUpSuccessfulFileRead(buffer); + + // WHEN + auto result = loader_.load(kTestPath); + + // THEN + ASSERT_THAT(result.has_value(), IsTrue()); + ASSERT_THAT(result->components().size(), Eq(3U)); + EXPECT_THAT(result->components()[0].name, Eq("CompA")); + EXPECT_THAT(result->components()[1].name, Eq("CompB")); + EXPECT_THAT(result->components()[2].name, Eq("CompC")); +} + +// ============================================================================ +// Optional / required field tests +// ============================================================================ + +TEST_F(FlatbufferConfigLoaderTest, MissingRequiredFallbackReturnsInvalidFormat) +{ + RecordProperty("Description", "When the required fallback_run_target is absent, returns InvalidFormat."); + + // GIVEN + ::flatbuffers::FlatBufferBuilder fbb; + auto irt = fbb.CreateString("Startup"); + auto alive_sup = fb::CreateAliveSupervision(fbb); + auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, 0 /*components*/, 0 /*run_targets*/, irt, + 0 /*fallback_run_target*/, alive_sup); + auto buffer = finishBuffer(fbb, config); + setUpSuccessfulFileRead(buffer); + + // WHEN + auto result = loader_.load(kTestPath); + + // THEN + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); +} + +TEST_F(FlatbufferConfigLoaderTest, MissingRequiredAliveSupervisionReturnsInvalidFormat) +{ + RecordProperty("Description", "When the required alive_supervision is absent, returns InvalidFormat."); + + // GIVEN + ::flatbuffers::FlatBufferBuilder fbb; + auto irt = fbb.CreateString("Startup"); + auto fallback = fb::CreateFallbackRunTarget(fbb); + auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, 0 /*components*/, 0 /*run_targets*/, irt, + fallback, 0 /*alive_supervision*/); + auto buffer = finishBuffer(fbb, config); + setUpSuccessfulFileRead(buffer); + + // WHEN + auto result = loader_.load(kTestPath); + + // THEN + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); +} + +TEST_F(FlatbufferConfigLoaderTest, OptionalWatchdogAbsent) +{ + RecordProperty("Description", "When no watchdog is present, it is nullopt."); + + // GIVEN + auto buffer = buildMinimalConfig(); + setUpSuccessfulFileRead(buffer); + + // WHEN + auto result = loader_.load(kTestPath); + + // THEN + ASSERT_THAT(result.has_value(), IsTrue()); + EXPECT_THAT(result->watchdog().has_value(), IsFalse()); +} + +TEST_F(FlatbufferConfigLoaderTest, OptionalSandboxAbsent) +{ + RecordProperty("Description", "When no sandbox is present on a component, it is nullopt."); + + // GIVEN + ::flatbuffers::FlatBufferBuilder fbb; + + auto ns_bin_name = fbb.CreateString("no_sandbox_bin"); + auto ns_app_profile = fb::CreateApplicationProfile(fbb); + auto ns_ready_cond = fb::CreateReadyCondition(fbb); + auto ns_comp_props = fb::CreateComponentProperties(fbb, ns_bin_name, ns_app_profile, + 0 /*depends_on*/, 0 /*process_arguments*/, ns_ready_cond); + + auto bin_dir = fbb.CreateString("/opt"); + auto work_dir = fbb.CreateString("/tmp"); + auto deploy = fb::CreateDeploymentConfig(fbb, + 0.5 /*ready_timeout*/, 0.5 /*shutdown_timeout*/, 0 /*environmental_variables*/, bin_dir, work_dir); + + auto comp_name = fbb.CreateString("no_sandbox"); + auto component = fb::CreateComponent(fbb, comp_name, 0 /*description*/, ns_comp_props, deploy); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{component}); + + auto fallback = fb::CreateFallbackRunTarget(fbb); + auto alive_sup = fb::CreateAliveSupervision(fbb); + auto irt = fbb.CreateString("Startup"); + auto config = fb::CreateLaunchManagerConfig(fbb, + 1 /*schema_version*/, comps, 0 /*run_targets*/, irt, fallback, alive_sup); + auto buffer = finishBuffer(fbb, config); + setUpSuccessfulFileRead(buffer); + + // WHEN + auto result = loader_.load(kTestPath); + + // THEN + ASSERT_THAT(result.has_value(), IsTrue()); + EXPECT_THAT(result->components()[0].deployment_config.sandbox.has_value(), IsFalse()); +} + +TEST_F(FlatbufferConfigLoaderTest, MissingRequiredRecoveryActionReturnsInvalidFormat) +{ + RecordProperty("Description", "When the required recovery_action is absent on a RunTarget, returns InvalidFormat."); + + // GIVEN + ::flatbuffers::FlatBufferBuilder fbb; + + auto rt_name = fbb.CreateString("Startup"); + auto rt = fb::CreateRunTarget(fbb, rt_name); + auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{rt}); + + auto fallback = fb::CreateFallbackRunTarget(fbb); + auto alive_sup = fb::CreateAliveSupervision(fbb); + auto irt = fbb.CreateString("Startup"); + auto config = fb::CreateLaunchManagerConfig(fbb, + 1 /*schema_version*/, 0 /*components*/, rts, irt, fallback, alive_sup); + auto buffer = finishBuffer(fbb, config); + setUpSuccessfulFileRead(buffer); + + // WHEN + auto result = loader_.load(kTestPath); + + // THEN + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); +} + +// ============================================================================ +// Enum mapping tests +// ============================================================================ + +TEST_F(FlatbufferConfigLoaderTest, MapNativeApplicationType) +{ + RecordProperty("Description", "ApplicationType_Native maps to ApplicationType::Native."); + + // GIVEN + ::flatbuffers::FlatBufferBuilder fbb; + + auto app_profile = fb::CreateApplicationProfile(fbb, fb::ApplicationType_Native); + auto bin_name = fbb.CreateString("native_bin"); + auto ready_cond = fb::CreateReadyCondition(fbb); + auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile, + 0 /*depends_on*/, 0 /*process_arguments*/, ready_cond); + auto bin_dir = fbb.CreateString("/opt"); + auto deploy = fb::CreateDeploymentConfig(fbb, + 0.0 /*ready_timeout*/, 0.0 /*shutdown_timeout*/, 0 /*environmental_variables*/, bin_dir); + auto comp_name = fbb.CreateString("native_comp"); + auto component = fb::CreateComponent(fbb, comp_name, 0 /*description*/, comp_props, deploy); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{component}); + + auto fallback = fb::CreateFallbackRunTarget(fbb); + auto alive_sup = fb::CreateAliveSupervision(fbb); + auto irt = fbb.CreateString("Startup"); + auto config = fb::CreateLaunchManagerConfig(fbb, + 1 /*schema_version*/, comps, 0 /*run_targets*/, irt, fallback, alive_sup); + auto buffer = finishBuffer(fbb, config); + setUpSuccessfulFileRead(buffer); + + // WHEN + auto result = loader_.load(kTestPath); + + // THEN + ASSERT_THAT(result.has_value(), IsTrue()); + EXPECT_THAT(result->components()[0].component_properties.application_profile.application_type, + Eq(ApplicationType::Native)); +} + +TEST_F(FlatbufferConfigLoaderTest, MapReportingAndSupervisedType) +{ + RecordProperty("Description", + "ApplicationType_Reporting_And_Supervised maps to ApplicationType::ReportingAndSupervised."); + + // GIVEN + ::flatbuffers::FlatBufferBuilder fbb; + + auto app_profile = fb::CreateApplicationProfile(fbb, fb::ApplicationType_Reporting_And_Supervised); + auto bin_name = fbb.CreateString("supervised_bin"); + auto ready_cond = fb::CreateReadyCondition(fbb); + auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile, + 0 /*depends_on*/, 0 /*process_arguments*/, ready_cond); + auto bin_dir = fbb.CreateString("/opt"); + auto deploy = fb::CreateDeploymentConfig(fbb, + 0.0 /*ready_timeout*/, 0.0 /*shutdown_timeout*/, 0 /*environmental_variables*/, bin_dir); + auto comp_name = fbb.CreateString("supervised_comp"); + auto component = fb::CreateComponent(fbb, comp_name, 0 /*description*/, comp_props, deploy); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{component}); + + auto fallback = fb::CreateFallbackRunTarget(fbb); + auto alive_sup = fb::CreateAliveSupervision(fbb); + auto irt = fbb.CreateString("Startup"); + auto config = fb::CreateLaunchManagerConfig(fbb, + 1 /*schema_version*/, comps, 0 /*run_targets*/, irt, fallback, alive_sup); + auto buffer = finishBuffer(fbb, config); + setUpSuccessfulFileRead(buffer); + + // WHEN + auto result = loader_.load(kTestPath); + + // THEN + ASSERT_THAT(result.has_value(), IsTrue()); + EXPECT_THAT(result->components()[0].component_properties.application_profile.application_type, + Eq(ApplicationType::ReportingAndSupervised)); +} + +TEST_F(FlatbufferConfigLoaderTest, MapTerminatedProcessState) +{ + RecordProperty("Description", "ProcessState_Terminated maps to ProcessState::Terminated."); + + // GIVEN + ::flatbuffers::FlatBufferBuilder fbb; + + auto app_profile = fb::CreateApplicationProfile(fbb); + auto ready_cond = fb::CreateReadyCondition(fbb, fb::ProcessState_Terminated); + auto bin_name = fbb.CreateString("term_bin"); + auto comp_props = fb::CreateComponentProperties(fbb, + bin_name, app_profile, 0 /*depends_on*/, 0 /*process_arguments*/, ready_cond); + auto bin_dir = fbb.CreateString("/opt"); + auto deploy = fb::CreateDeploymentConfig(fbb, + 0.0 /*ready_timeout*/, 0.0 /*shutdown_timeout*/, 0 /*environmental_variables*/, bin_dir); + auto comp_name = fbb.CreateString("term_comp"); + auto component = fb::CreateComponent(fbb, comp_name, 0 /*description*/, comp_props, deploy); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{component}); + + auto fallback = fb::CreateFallbackRunTarget(fbb); + auto alive_sup = fb::CreateAliveSupervision(fbb); + auto irt = fbb.CreateString("Startup"); + auto config = fb::CreateLaunchManagerConfig(fbb, + 1 /*schema_version*/, comps, 0 /*run_targets*/, irt, fallback, alive_sup); + auto buffer = finishBuffer(fbb, config); + setUpSuccessfulFileRead(buffer); + + // WHEN + auto result = loader_.load(kTestPath); + + // THEN + ASSERT_THAT(result.has_value(), IsTrue()); + EXPECT_THAT(result->components()[0].component_properties.ready_condition.process_state, + Eq(ProcessState::Terminated)); +} + +// ============================================================================ +// Error path tests +// ============================================================================ + +TEST_F(FlatbufferConfigLoaderTest, FileOpenFailsReturnsFileNotFound) +{ + RecordProperty("Description", "When file open fails with ENOENT, returns FileNotFound error."); + + // GIVEN + const auto open_error = score::os::Error::createFromErrno(ENOENT); + EXPECT_CALL(*fcntl_mock_, open(_, _)) + .WillOnce(Return(score::cpp::make_unexpected(open_error))); + + // WHEN + auto result = loader_.load(kTestPath); + + // THEN + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::FileNotFound)); +} + +TEST_F(FlatbufferConfigLoaderTest, FileOpenFailsWithPermissionDeniedReturnsInsufficientPermission) +{ + RecordProperty("Description", "When file open fails with EACCES, returns InsufficientPermission error."); + + // GIVEN + const auto open_error = score::os::Error::createFromErrno(EACCES); + EXPECT_CALL(*fcntl_mock_, open(_, _)) + .WillOnce(Return(score::cpp::make_unexpected(open_error))); + + // WHEN + auto result = loader_.load(kTestPath); + + // THEN + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InsufficientPermission)); +} + +TEST_F(FlatbufferConfigLoaderTest, FstatFailsReturnsGeneralError) +{ + RecordProperty("Description", "When fstat fails, returns GeneralError."); + + // GIVEN + ON_CALL(*fcntl_mock_, open(_, _)) + .WillByDefault(Return(score::cpp::expected{kTestFd})); + + const auto stat_error = score::os::Error::createFromErrno(EBADF); + EXPECT_CALL(*stat_mock_, fstat(kTestFd, _)) + .WillOnce(Return(score::cpp::make_unexpected(stat_error))); + + ON_CALL(*unistd_mock_, close(_)) + .WillByDefault(Return(score::cpp::expected_blank{})); + + // WHEN + auto result = loader_.load(kTestPath); + + // THEN + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::GeneralError)); +} + +TEST_F(FlatbufferConfigLoaderTest, ReadFailsReturnsGeneralError) +{ + RecordProperty("Description", "When read fails, returns GeneralError."); + + // GIVEN + ON_CALL(*fcntl_mock_, open(_, _)) + .WillByDefault(Return(score::cpp::expected{kTestFd})); + + ON_CALL(*stat_mock_, fstat(kTestFd, _)) + .WillByDefault( + DoAll(Invoke([](std::int32_t, score::os::StatBuffer& buf) { buf.st_size = 100; }), + Return(score::cpp::expected_blank{}))); + + const auto read_error = score::os::Error::createFromErrno(EIO); + EXPECT_CALL(*unistd_mock_, read(kTestFd, _, _)) + .WillOnce(Return(score::cpp::make_unexpected(read_error))); + + ON_CALL(*unistd_mock_, close(_)) + .WillByDefault(Return(score::cpp::expected_blank{})); + + // WHEN + auto result = loader_.load(kTestPath); + + // THEN + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::GeneralError)); +} + +TEST_F(FlatbufferConfigLoaderTest, CorruptedBufferReturnsInvalidFormat) +{ + RecordProperty("Description", "Corrupted binary data returns InvalidFormat error."); + + // GIVEN + std::vector garbage = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01, 0x02, 0x03}; + setUpSuccessfulFileRead(garbage); + + // WHEN + auto result = loader_.load(kTestPath); + + // THEN + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); +} + +TEST_F(FlatbufferConfigLoaderTest, MissingInitialRunTargetReturnsInvalidFormat) +{ + RecordProperty("Description", "A valid FlatBuffer with null initial_run_target returns InvalidFormat."); + + // GIVEN + ::flatbuffers::FlatBufferBuilder fbb; + auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/); + fb::FinishLaunchManagerConfigBuffer(fbb, config); + const auto* buf = fbb.GetBufferPointer(); + std::vector buffer(buf, buf + fbb.GetSize()); + setUpSuccessfulFileRead(buffer); + + // WHEN + auto result = loader_.load(kTestPath); + + // THEN + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); +} + +TEST_F(FlatbufferConfigLoaderTest, WrongSchemaVersionReturnsUnsupportedVersion) +{ + RecordProperty("Description", "A config with an unexpected schema_version returns UnsupportedVersion."); + + // GIVEN + auto buffer = buildMinimalConfig(99, "Startup"); + setUpSuccessfulFileRead(buffer); + + // WHEN + auto result = loader_.load(kTestPath); + + // THEN + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::UnsupportedVersion)); +} + +} // namespace +} // namespace score::launch_manager::config diff --git a/src/launch_manager_daemon/config/src/new_lm_flatcfg.fbs b/src/launch_manager_daemon/config/src/new_lm_flatcfg.fbs new file mode 100644 index 000000000..56148ef1a --- /dev/null +++ b/src/launch_manager_daemon/config/src/new_lm_flatcfg.fbs @@ -0,0 +1,191 @@ +// FlatBuffers schema for S-CORE Launch Manager configuration. +// Equivalent to launch_manager.schema.json + +namespace score.launch_manager.config.fb; + +// Specifies the level of integration between the component and the Launch Manager. +enum ApplicationType : byte { + Native = 0, + Reporting = 1, + Reporting_And_Supervised = 2, + State_Manager = 3 +} + +// Specifies the required state of the component's POSIX process. +enum ProcessState : byte { + Running = 0, + Terminated = 1 +} + +// Defines the configuration parameters used for alive monitoring of a component. +table ComponentAliveSupervision { + // Duration in seconds of the time interval used to verify alive notifications. + reporting_cycle:double; + // Maximum number of consecutive reporting cycle failures before recovery is triggered. + failed_cycles_tolerance:uint32; + // Minimum number of checkpoints that must be reported within each reporting_cycle. + min_indications:uint32 = null; + // Maximum number of checkpoints that may be reported within each reporting_cycle. + max_indications:uint32 = null; +} + +// Defines the application profile that specifies the runtime behavior and capabilities of a component. +table ApplicationProfile { + application_type:ApplicationType; + // Whether the component terminates automatically once its tasks are completed. + is_self_terminating:bool; + alive_supervision:ComponentAliveSupervision; +} + +// Defines the conditions that determine when the component enters the ready state. +table ReadyCondition { + process_state:ProcessState = null; +} + +// Defines essential characteristics of a software component. +table ComponentProperties { + // Relative path of the executable inside bin_dir. + binary_name:string (required); + application_profile:ApplicationProfile (required); + // Names of components that must reach ready state before this component starts. + depends_on:[string]; + // Ordered list of command-line arguments passed to the component at startup. + process_arguments:[string]; + ready_condition:ReadyCondition (required); +} + +// Recovery action that restarts the POSIX process associated with a component. +table RestartAction { + // Maximum number of restart attempts before recovery is considered failed. + number_of_attempts:uint32; + // Delay in seconds before initiating a restart attempt. + delay_before_restart:double; +} + +// Recovery action that switches to a specified Run Target. +table SwitchRunTargetAction { + // Name of the Run Target to switch to. + run_target:string (required); +} + +// Specifies recovery actions to execute when an error or failure occurs. +// Exactly one variant is set. Maps to the JSON schema's oneOf constraint. +union RecoveryAction { RestartAction, SwitchRunTargetAction } + +// A key-value pair representing an environment variable. +table EnvironmentalVariable { + key:string (required); + value:string (required); +} + +// Defines sandbox configuration parameters that isolate and constrain component execution. +table Sandbox { + // POSIX user ID (UID) under which the component executes. + uid:uint32; + // Primary POSIX group ID (GID) under which the component executes. + gid:uint32; + // Supplementary POSIX group IDs assigned to the component. + supplementary_group_ids:[uint32]; + // Security policy or confinement profile name (e.g., SELinux or AppArmor profile). + security_policy:string; + // Scheduling policy for the component's initial thread (e.g., SCHED_FIFO, SCHED_RR, SCHED_OTHER). + scheduling_policy:string; + // Scheduling priority for the component's initial thread. + scheduling_priority:int32 = null; + // Maximum memory in bytes the component is permitted to use. + max_memory_usage:uint64 = null; + // Maximum CPU usage as a percentage of total CPU capacity. + max_cpu_usage:uint32 = null; +} + +// Deployment configuration for a component. +table DeploymentConfig { + // Maximum time in seconds for the component to reach its ready state. + ready_timeout:double; + // Maximum time in seconds for the component to terminate after SIGTERM. + shutdown_timeout:double; + // Environment variables passed to the component at startup. + environmental_variables:[EnvironmentalVariable]; + // Absolute path to the directory where the component is installed. + bin_dir:string (required); + // Working directory for the component during execution. + working_dir:string; + // Recovery action when the component fails to reach ready state. + // Must be RestartAction per the JSON schema constraint. + ready_recovery_action:RecoveryAction; + // Recovery action when the component malfunctions after reaching ready state. + // Must be SwitchRunTargetAction per the JSON schema constraint. + recovery_action:RecoveryAction; + sandbox:Sandbox; +} + +// Configuration for a Run Target representing an operational mode of the system. +table RunTarget { + // Unique Run Target identifier. + name:string (required); + // Human-readable description of the Run Target. + description:string; + // Names of components and Run Targets that must be activated with this Run Target. + depends_on:[string]; + // Time limit in seconds for the Run Target transition. + transition_timeout:double; + // Recovery action when a component in this Run Target fails. + // Must be SwitchRunTargetAction per the JSON schema constraint. + recovery_action:RecoveryAction (required); +} + +// An individual component entry with its identifier. +table Component { + // Unique component identifier. + name:string (required); + // Human-readable description of the component's purpose. + description:string; + component_properties:ComponentProperties (required); + deployment_config:DeploymentConfig (required); +} + +// Global alive supervision configuration. +table AliveSupervision { + // Length in seconds of the time window used to assess alive supervision reports. + evaluation_cycle:double; +} + +// External watchdog device configuration. +table Watchdog { + // Path to the external watchdog device file (e.g., /dev/watchdog). + device_file_path:string (required); + // Maximum timeout in seconds configured on the external watchdog. + max_timeout:double; + // Whether the watchdog is deactivated during shutdown. + deactivate_on_shutdown:bool = null; + // Whether the magic close sequence is performed on intentional shutdown. + require_magic_close:bool = null; +} + +// Fallback Run Target activated when all recovery attempts are exhausted. +// Does not include a recovery_action. +table FallbackRunTarget { + // Human-readable description of the fallback Run Target. + description:string; + // Names of components and Run Targets that must be activated. + depends_on:[string]; + // Time limit in seconds for the Run Target transition. + transition_timeout:double; +} + +// Root configuration table for the S-CORE Launch Manager. +table LaunchManagerConfig { + // Schema version number. + schema_version:int32; + // Software components managed by the Launch Manager. + components:[Component]; + // Run Targets representing different operational modes. + run_targets:[RunTarget]; + // Name of the initial Run Target activated during startup. + initial_run_target:string (required); + fallback_run_target:FallbackRunTarget (required); + alive_supervision:AliveSupervision (required); + watchdog:Watchdog; +} + +root_type LaunchManagerConfig; diff --git a/src/launch_manager_daemon/config/src/new_lm_flatcfg_generated.h b/src/launch_manager_daemon/config/src/new_lm_flatcfg_generated.h new file mode 100644 index 000000000..30c84cf6b --- /dev/null +++ b/src/launch_manager_daemon/config/src/new_lm_flatcfg_generated.h @@ -0,0 +1,1605 @@ +// automatically generated by the FlatBuffers compiler, do not modify + + +#ifndef FLATBUFFERS_GENERATED_NEWLMFLATCFG_SCORE_LAUNCH_MANAGER_CONFIG_FB_H_ +#define FLATBUFFERS_GENERATED_NEWLMFLATCFG_SCORE_LAUNCH_MANAGER_CONFIG_FB_H_ + +#include "flatbuffers/flatbuffers.h" + +// Ensure the included flatbuffers.h is the same version as when this file was +// generated, otherwise it may not be compatible. +static_assert(FLATBUFFERS_VERSION_MAJOR == 25 && + FLATBUFFERS_VERSION_MINOR == 9 && + FLATBUFFERS_VERSION_REVISION == 23, + "Non-compatible flatbuffers version included"); + +namespace score { +namespace launch_manager { +namespace config { +namespace fb { + +struct ComponentAliveSupervision; +struct ComponentAliveSupervisionBuilder; + +struct ApplicationProfile; +struct ApplicationProfileBuilder; + +struct ReadyCondition; +struct ReadyConditionBuilder; + +struct ComponentProperties; +struct ComponentPropertiesBuilder; + +struct RestartAction; +struct RestartActionBuilder; + +struct SwitchRunTargetAction; +struct SwitchRunTargetActionBuilder; + +struct EnvironmentalVariable; +struct EnvironmentalVariableBuilder; + +struct Sandbox; +struct SandboxBuilder; + +struct DeploymentConfig; +struct DeploymentConfigBuilder; + +struct RunTarget; +struct RunTargetBuilder; + +struct Component; +struct ComponentBuilder; + +struct AliveSupervision; +struct AliveSupervisionBuilder; + +struct Watchdog; +struct WatchdogBuilder; + +struct FallbackRunTarget; +struct FallbackRunTargetBuilder; + +struct LaunchManagerConfig; +struct LaunchManagerConfigBuilder; + +enum ApplicationType : int8_t { + ApplicationType_Native = 0, + ApplicationType_Reporting = 1, + ApplicationType_Reporting_And_Supervised = 2, + ApplicationType_State_Manager = 3, + ApplicationType_MIN = ApplicationType_Native, + ApplicationType_MAX = ApplicationType_State_Manager +}; + +inline const ApplicationType (&EnumValuesApplicationType())[4] { + static const ApplicationType values[] = { + ApplicationType_Native, + ApplicationType_Reporting, + ApplicationType_Reporting_And_Supervised, + ApplicationType_State_Manager + }; + return values; +} + +inline const char * const *EnumNamesApplicationType() { + static const char * const names[5] = { + "Native", + "Reporting", + "Reporting_And_Supervised", + "State_Manager", + nullptr + }; + return names; +} + +inline const char *EnumNameApplicationType(ApplicationType e) { + if (::flatbuffers::IsOutRange(e, ApplicationType_Native, ApplicationType_State_Manager)) return ""; + const size_t index = static_cast(e); + return EnumNamesApplicationType()[index]; +} + +enum ProcessState : int8_t { + ProcessState_Running = 0, + ProcessState_Terminated = 1, + ProcessState_MIN = ProcessState_Running, + ProcessState_MAX = ProcessState_Terminated +}; + +inline const ProcessState (&EnumValuesProcessState())[2] { + static const ProcessState values[] = { + ProcessState_Running, + ProcessState_Terminated + }; + return values; +} + +inline const char * const *EnumNamesProcessState() { + static const char * const names[3] = { + "Running", + "Terminated", + nullptr + }; + return names; +} + +inline const char *EnumNameProcessState(ProcessState e) { + if (::flatbuffers::IsOutRange(e, ProcessState_Running, ProcessState_Terminated)) return ""; + const size_t index = static_cast(e); + return EnumNamesProcessState()[index]; +} + +enum RecoveryAction : uint8_t { + RecoveryAction_NONE = 0, + RecoveryAction_RestartAction = 1, + RecoveryAction_SwitchRunTargetAction = 2, + RecoveryAction_MIN = RecoveryAction_NONE, + RecoveryAction_MAX = RecoveryAction_SwitchRunTargetAction +}; + +inline const RecoveryAction (&EnumValuesRecoveryAction())[3] { + static const RecoveryAction values[] = { + RecoveryAction_NONE, + RecoveryAction_RestartAction, + RecoveryAction_SwitchRunTargetAction + }; + return values; +} + +inline const char * const *EnumNamesRecoveryAction() { + static const char * const names[4] = { + "NONE", + "RestartAction", + "SwitchRunTargetAction", + nullptr + }; + return names; +} + +inline const char *EnumNameRecoveryAction(RecoveryAction e) { + if (::flatbuffers::IsOutRange(e, RecoveryAction_NONE, RecoveryAction_SwitchRunTargetAction)) return ""; + const size_t index = static_cast(e); + return EnumNamesRecoveryAction()[index]; +} + +template struct RecoveryActionTraits { + static const RecoveryAction enum_value = RecoveryAction_NONE; +}; + +template<> struct RecoveryActionTraits { + static const RecoveryAction enum_value = RecoveryAction_RestartAction; +}; + +template<> struct RecoveryActionTraits { + static const RecoveryAction enum_value = RecoveryAction_SwitchRunTargetAction; +}; + +bool VerifyRecoveryAction(::flatbuffers::Verifier &verifier, const void *obj, RecoveryAction type); +bool VerifyRecoveryActionVector(::flatbuffers::Verifier &verifier, const ::flatbuffers::Vector<::flatbuffers::Offset> *values, const ::flatbuffers::Vector *types); + +struct ComponentAliveSupervision FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef ComponentAliveSupervisionBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_REPORTING_CYCLE = 4, + VT_FAILED_CYCLES_TOLERANCE = 6, + VT_MIN_INDICATIONS = 8, + VT_MAX_INDICATIONS = 10 + }; + double reporting_cycle() const { + return GetField(VT_REPORTING_CYCLE, 0.0); + } + uint32_t failed_cycles_tolerance() const { + return GetField(VT_FAILED_CYCLES_TOLERANCE, 0); + } + ::flatbuffers::Optional min_indications() const { + return GetOptional(VT_MIN_INDICATIONS); + } + ::flatbuffers::Optional max_indications() const { + return GetOptional(VT_MAX_INDICATIONS); + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_REPORTING_CYCLE, 8) && + VerifyField(verifier, VT_FAILED_CYCLES_TOLERANCE, 4) && + VerifyField(verifier, VT_MIN_INDICATIONS, 4) && + VerifyField(verifier, VT_MAX_INDICATIONS, 4) && + verifier.EndTable(); + } +}; + +struct ComponentAliveSupervisionBuilder { + typedef ComponentAliveSupervision Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_reporting_cycle(double reporting_cycle) { + fbb_.AddElement(ComponentAliveSupervision::VT_REPORTING_CYCLE, reporting_cycle, 0.0); + } + void add_failed_cycles_tolerance(uint32_t failed_cycles_tolerance) { + fbb_.AddElement(ComponentAliveSupervision::VT_FAILED_CYCLES_TOLERANCE, failed_cycles_tolerance, 0); + } + void add_min_indications(uint32_t min_indications) { + fbb_.AddElement(ComponentAliveSupervision::VT_MIN_INDICATIONS, min_indications); + } + void add_max_indications(uint32_t max_indications) { + fbb_.AddElement(ComponentAliveSupervision::VT_MAX_INDICATIONS, max_indications); + } + explicit ComponentAliveSupervisionBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateComponentAliveSupervision( + ::flatbuffers::FlatBufferBuilder &_fbb, + double reporting_cycle = 0.0, + uint32_t failed_cycles_tolerance = 0, + ::flatbuffers::Optional min_indications = ::flatbuffers::nullopt, + ::flatbuffers::Optional max_indications = ::flatbuffers::nullopt) { + ComponentAliveSupervisionBuilder builder_(_fbb); + builder_.add_reporting_cycle(reporting_cycle); + if(max_indications) { builder_.add_max_indications(*max_indications); } + if(min_indications) { builder_.add_min_indications(*min_indications); } + builder_.add_failed_cycles_tolerance(failed_cycles_tolerance); + return builder_.Finish(); +} + +struct ApplicationProfile FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef ApplicationProfileBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_APPLICATION_TYPE = 4, + VT_IS_SELF_TERMINATING = 6, + VT_ALIVE_SUPERVISION = 8 + }; + score::launch_manager::config::fb::ApplicationType application_type() const { + return static_cast(GetField(VT_APPLICATION_TYPE, 0)); + } + bool is_self_terminating() const { + return GetField(VT_IS_SELF_TERMINATING, 0) != 0; + } + const score::launch_manager::config::fb::ComponentAliveSupervision *alive_supervision() const { + return GetPointer(VT_ALIVE_SUPERVISION); + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_APPLICATION_TYPE, 1) && + VerifyField(verifier, VT_IS_SELF_TERMINATING, 1) && + VerifyOffset(verifier, VT_ALIVE_SUPERVISION) && + verifier.VerifyTable(alive_supervision()) && + verifier.EndTable(); + } +}; + +struct ApplicationProfileBuilder { + typedef ApplicationProfile Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_application_type(score::launch_manager::config::fb::ApplicationType application_type) { + fbb_.AddElement(ApplicationProfile::VT_APPLICATION_TYPE, static_cast(application_type), 0); + } + void add_is_self_terminating(bool is_self_terminating) { + fbb_.AddElement(ApplicationProfile::VT_IS_SELF_TERMINATING, static_cast(is_self_terminating), 0); + } + void add_alive_supervision(::flatbuffers::Offset alive_supervision) { + fbb_.AddOffset(ApplicationProfile::VT_ALIVE_SUPERVISION, alive_supervision); + } + explicit ApplicationProfileBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateApplicationProfile( + ::flatbuffers::FlatBufferBuilder &_fbb, + score::launch_manager::config::fb::ApplicationType application_type = score::launch_manager::config::fb::ApplicationType_Native, + bool is_self_terminating = false, + ::flatbuffers::Offset alive_supervision = 0) { + ApplicationProfileBuilder builder_(_fbb); + builder_.add_alive_supervision(alive_supervision); + builder_.add_is_self_terminating(is_self_terminating); + builder_.add_application_type(application_type); + return builder_.Finish(); +} + +struct ReadyCondition FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef ReadyConditionBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_PROCESS_STATE = 4 + }; + ::flatbuffers::Optional process_state() const { + return GetOptional(VT_PROCESS_STATE); + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_PROCESS_STATE, 1) && + verifier.EndTable(); + } +}; + +struct ReadyConditionBuilder { + typedef ReadyCondition Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_process_state(score::launch_manager::config::fb::ProcessState process_state) { + fbb_.AddElement(ReadyCondition::VT_PROCESS_STATE, static_cast(process_state)); + } + explicit ReadyConditionBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateReadyCondition( + ::flatbuffers::FlatBufferBuilder &_fbb, + ::flatbuffers::Optional process_state = ::flatbuffers::nullopt) { + ReadyConditionBuilder builder_(_fbb); + if(process_state) { builder_.add_process_state(*process_state); } + return builder_.Finish(); +} + +struct ComponentProperties FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef ComponentPropertiesBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_BINARY_NAME = 4, + VT_APPLICATION_PROFILE = 6, + VT_DEPENDS_ON = 8, + VT_PROCESS_ARGUMENTS = 10, + VT_READY_CONDITION = 12 + }; + const ::flatbuffers::String *binary_name() const { + return GetPointer(VT_BINARY_NAME); + } + const score::launch_manager::config::fb::ApplicationProfile *application_profile() const { + return GetPointer(VT_APPLICATION_PROFILE); + } + const ::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>> *depends_on() const { + return GetPointer> *>(VT_DEPENDS_ON); + } + const ::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>> *process_arguments() const { + return GetPointer> *>(VT_PROCESS_ARGUMENTS); + } + const score::launch_manager::config::fb::ReadyCondition *ready_condition() const { + return GetPointer(VT_READY_CONDITION); + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffsetRequired(verifier, VT_BINARY_NAME) && + verifier.VerifyString(binary_name()) && + VerifyOffsetRequired(verifier, VT_APPLICATION_PROFILE) && + verifier.VerifyTable(application_profile()) && + VerifyOffset(verifier, VT_DEPENDS_ON) && + verifier.VerifyVector(depends_on()) && + verifier.VerifyVectorOfStrings(depends_on()) && + VerifyOffset(verifier, VT_PROCESS_ARGUMENTS) && + verifier.VerifyVector(process_arguments()) && + verifier.VerifyVectorOfStrings(process_arguments()) && + VerifyOffsetRequired(verifier, VT_READY_CONDITION) && + verifier.VerifyTable(ready_condition()) && + verifier.EndTable(); + } +}; + +struct ComponentPropertiesBuilder { + typedef ComponentProperties Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_binary_name(::flatbuffers::Offset<::flatbuffers::String> binary_name) { + fbb_.AddOffset(ComponentProperties::VT_BINARY_NAME, binary_name); + } + void add_application_profile(::flatbuffers::Offset application_profile) { + fbb_.AddOffset(ComponentProperties::VT_APPLICATION_PROFILE, application_profile); + } + void add_depends_on(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>> depends_on) { + fbb_.AddOffset(ComponentProperties::VT_DEPENDS_ON, depends_on); + } + void add_process_arguments(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>> process_arguments) { + fbb_.AddOffset(ComponentProperties::VT_PROCESS_ARGUMENTS, process_arguments); + } + void add_ready_condition(::flatbuffers::Offset ready_condition) { + fbb_.AddOffset(ComponentProperties::VT_READY_CONDITION, ready_condition); + } + explicit ComponentPropertiesBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + fbb_.Required(o, ComponentProperties::VT_BINARY_NAME); + fbb_.Required(o, ComponentProperties::VT_APPLICATION_PROFILE); + fbb_.Required(o, ComponentProperties::VT_READY_CONDITION); + return o; + } +}; + +inline ::flatbuffers::Offset CreateComponentProperties( + ::flatbuffers::FlatBufferBuilder &_fbb, + ::flatbuffers::Offset<::flatbuffers::String> binary_name = 0, + ::flatbuffers::Offset application_profile = 0, + ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>> depends_on = 0, + ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>> process_arguments = 0, + ::flatbuffers::Offset ready_condition = 0) { + ComponentPropertiesBuilder builder_(_fbb); + builder_.add_ready_condition(ready_condition); + builder_.add_process_arguments(process_arguments); + builder_.add_depends_on(depends_on); + builder_.add_application_profile(application_profile); + builder_.add_binary_name(binary_name); + return builder_.Finish(); +} + +inline ::flatbuffers::Offset CreateComponentPropertiesDirect( + ::flatbuffers::FlatBufferBuilder &_fbb, + const char *binary_name = nullptr, + ::flatbuffers::Offset application_profile = 0, + const std::vector<::flatbuffers::Offset<::flatbuffers::String>> *depends_on = nullptr, + const std::vector<::flatbuffers::Offset<::flatbuffers::String>> *process_arguments = nullptr, + ::flatbuffers::Offset ready_condition = 0) { + auto binary_name__ = binary_name ? _fbb.CreateString(binary_name) : 0; + auto depends_on__ = depends_on ? _fbb.CreateVector<::flatbuffers::Offset<::flatbuffers::String>>(*depends_on) : 0; + auto process_arguments__ = process_arguments ? _fbb.CreateVector<::flatbuffers::Offset<::flatbuffers::String>>(*process_arguments) : 0; + return score::launch_manager::config::fb::CreateComponentProperties( + _fbb, + binary_name__, + application_profile, + depends_on__, + process_arguments__, + ready_condition); +} + +struct RestartAction FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef RestartActionBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_NUMBER_OF_ATTEMPTS = 4, + VT_DELAY_BEFORE_RESTART = 6 + }; + uint32_t number_of_attempts() const { + return GetField(VT_NUMBER_OF_ATTEMPTS, 0); + } + double delay_before_restart() const { + return GetField(VT_DELAY_BEFORE_RESTART, 0.0); + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_NUMBER_OF_ATTEMPTS, 4) && + VerifyField(verifier, VT_DELAY_BEFORE_RESTART, 8) && + verifier.EndTable(); + } +}; + +struct RestartActionBuilder { + typedef RestartAction Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_number_of_attempts(uint32_t number_of_attempts) { + fbb_.AddElement(RestartAction::VT_NUMBER_OF_ATTEMPTS, number_of_attempts, 0); + } + void add_delay_before_restart(double delay_before_restart) { + fbb_.AddElement(RestartAction::VT_DELAY_BEFORE_RESTART, delay_before_restart, 0.0); + } + explicit RestartActionBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateRestartAction( + ::flatbuffers::FlatBufferBuilder &_fbb, + uint32_t number_of_attempts = 0, + double delay_before_restart = 0.0) { + RestartActionBuilder builder_(_fbb); + builder_.add_delay_before_restart(delay_before_restart); + builder_.add_number_of_attempts(number_of_attempts); + return builder_.Finish(); +} + +struct SwitchRunTargetAction FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef SwitchRunTargetActionBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_RUN_TARGET = 4 + }; + const ::flatbuffers::String *run_target() const { + return GetPointer(VT_RUN_TARGET); + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffsetRequired(verifier, VT_RUN_TARGET) && + verifier.VerifyString(run_target()) && + verifier.EndTable(); + } +}; + +struct SwitchRunTargetActionBuilder { + typedef SwitchRunTargetAction Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_run_target(::flatbuffers::Offset<::flatbuffers::String> run_target) { + fbb_.AddOffset(SwitchRunTargetAction::VT_RUN_TARGET, run_target); + } + explicit SwitchRunTargetActionBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + fbb_.Required(o, SwitchRunTargetAction::VT_RUN_TARGET); + return o; + } +}; + +inline ::flatbuffers::Offset CreateSwitchRunTargetAction( + ::flatbuffers::FlatBufferBuilder &_fbb, + ::flatbuffers::Offset<::flatbuffers::String> run_target = 0) { + SwitchRunTargetActionBuilder builder_(_fbb); + builder_.add_run_target(run_target); + return builder_.Finish(); +} + +inline ::flatbuffers::Offset CreateSwitchRunTargetActionDirect( + ::flatbuffers::FlatBufferBuilder &_fbb, + const char *run_target = nullptr) { + auto run_target__ = run_target ? _fbb.CreateString(run_target) : 0; + return score::launch_manager::config::fb::CreateSwitchRunTargetAction( + _fbb, + run_target__); +} + +struct EnvironmentalVariable FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef EnvironmentalVariableBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_KEY = 4, + VT_VALUE = 6 + }; + const ::flatbuffers::String *key() const { + return GetPointer(VT_KEY); + } + const ::flatbuffers::String *value() const { + return GetPointer(VT_VALUE); + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffsetRequired(verifier, VT_KEY) && + verifier.VerifyString(key()) && + VerifyOffsetRequired(verifier, VT_VALUE) && + verifier.VerifyString(value()) && + verifier.EndTable(); + } +}; + +struct EnvironmentalVariableBuilder { + typedef EnvironmentalVariable Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_key(::flatbuffers::Offset<::flatbuffers::String> key) { + fbb_.AddOffset(EnvironmentalVariable::VT_KEY, key); + } + void add_value(::flatbuffers::Offset<::flatbuffers::String> value) { + fbb_.AddOffset(EnvironmentalVariable::VT_VALUE, value); + } + explicit EnvironmentalVariableBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + fbb_.Required(o, EnvironmentalVariable::VT_KEY); + fbb_.Required(o, EnvironmentalVariable::VT_VALUE); + return o; + } +}; + +inline ::flatbuffers::Offset CreateEnvironmentalVariable( + ::flatbuffers::FlatBufferBuilder &_fbb, + ::flatbuffers::Offset<::flatbuffers::String> key = 0, + ::flatbuffers::Offset<::flatbuffers::String> value = 0) { + EnvironmentalVariableBuilder builder_(_fbb); + builder_.add_value(value); + builder_.add_key(key); + return builder_.Finish(); +} + +inline ::flatbuffers::Offset CreateEnvironmentalVariableDirect( + ::flatbuffers::FlatBufferBuilder &_fbb, + const char *key = nullptr, + const char *value = nullptr) { + auto key__ = key ? _fbb.CreateString(key) : 0; + auto value__ = value ? _fbb.CreateString(value) : 0; + return score::launch_manager::config::fb::CreateEnvironmentalVariable( + _fbb, + key__, + value__); +} + +struct Sandbox FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef SandboxBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_UID = 4, + VT_GID = 6, + VT_SUPPLEMENTARY_GROUP_IDS = 8, + VT_SECURITY_POLICY = 10, + VT_SCHEDULING_POLICY = 12, + VT_SCHEDULING_PRIORITY = 14, + VT_MAX_MEMORY_USAGE = 16, + VT_MAX_CPU_USAGE = 18 + }; + uint32_t uid() const { + return GetField(VT_UID, 0); + } + uint32_t gid() const { + return GetField(VT_GID, 0); + } + const ::flatbuffers::Vector *supplementary_group_ids() const { + return GetPointer *>(VT_SUPPLEMENTARY_GROUP_IDS); + } + const ::flatbuffers::String *security_policy() const { + return GetPointer(VT_SECURITY_POLICY); + } + const ::flatbuffers::String *scheduling_policy() const { + return GetPointer(VT_SCHEDULING_POLICY); + } + ::flatbuffers::Optional scheduling_priority() const { + return GetOptional(VT_SCHEDULING_PRIORITY); + } + ::flatbuffers::Optional max_memory_usage() const { + return GetOptional(VT_MAX_MEMORY_USAGE); + } + ::flatbuffers::Optional max_cpu_usage() const { + return GetOptional(VT_MAX_CPU_USAGE); + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_UID, 4) && + VerifyField(verifier, VT_GID, 4) && + VerifyOffset(verifier, VT_SUPPLEMENTARY_GROUP_IDS) && + verifier.VerifyVector(supplementary_group_ids()) && + VerifyOffset(verifier, VT_SECURITY_POLICY) && + verifier.VerifyString(security_policy()) && + VerifyOffset(verifier, VT_SCHEDULING_POLICY) && + verifier.VerifyString(scheduling_policy()) && + VerifyField(verifier, VT_SCHEDULING_PRIORITY, 4) && + VerifyField(verifier, VT_MAX_MEMORY_USAGE, 8) && + VerifyField(verifier, VT_MAX_CPU_USAGE, 4) && + verifier.EndTable(); + } +}; + +struct SandboxBuilder { + typedef Sandbox Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_uid(uint32_t uid) { + fbb_.AddElement(Sandbox::VT_UID, uid, 0); + } + void add_gid(uint32_t gid) { + fbb_.AddElement(Sandbox::VT_GID, gid, 0); + } + void add_supplementary_group_ids(::flatbuffers::Offset<::flatbuffers::Vector> supplementary_group_ids) { + fbb_.AddOffset(Sandbox::VT_SUPPLEMENTARY_GROUP_IDS, supplementary_group_ids); + } + void add_security_policy(::flatbuffers::Offset<::flatbuffers::String> security_policy) { + fbb_.AddOffset(Sandbox::VT_SECURITY_POLICY, security_policy); + } + void add_scheduling_policy(::flatbuffers::Offset<::flatbuffers::String> scheduling_policy) { + fbb_.AddOffset(Sandbox::VT_SCHEDULING_POLICY, scheduling_policy); + } + void add_scheduling_priority(int32_t scheduling_priority) { + fbb_.AddElement(Sandbox::VT_SCHEDULING_PRIORITY, scheduling_priority); + } + void add_max_memory_usage(uint64_t max_memory_usage) { + fbb_.AddElement(Sandbox::VT_MAX_MEMORY_USAGE, max_memory_usage); + } + void add_max_cpu_usage(uint32_t max_cpu_usage) { + fbb_.AddElement(Sandbox::VT_MAX_CPU_USAGE, max_cpu_usage); + } + explicit SandboxBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateSandbox( + ::flatbuffers::FlatBufferBuilder &_fbb, + uint32_t uid = 0, + uint32_t gid = 0, + ::flatbuffers::Offset<::flatbuffers::Vector> supplementary_group_ids = 0, + ::flatbuffers::Offset<::flatbuffers::String> security_policy = 0, + ::flatbuffers::Offset<::flatbuffers::String> scheduling_policy = 0, + ::flatbuffers::Optional scheduling_priority = ::flatbuffers::nullopt, + ::flatbuffers::Optional max_memory_usage = ::flatbuffers::nullopt, + ::flatbuffers::Optional max_cpu_usage = ::flatbuffers::nullopt) { + SandboxBuilder builder_(_fbb); + if(max_memory_usage) { builder_.add_max_memory_usage(*max_memory_usage); } + if(max_cpu_usage) { builder_.add_max_cpu_usage(*max_cpu_usage); } + if(scheduling_priority) { builder_.add_scheduling_priority(*scheduling_priority); } + builder_.add_scheduling_policy(scheduling_policy); + builder_.add_security_policy(security_policy); + builder_.add_supplementary_group_ids(supplementary_group_ids); + builder_.add_gid(gid); + builder_.add_uid(uid); + return builder_.Finish(); +} + +inline ::flatbuffers::Offset CreateSandboxDirect( + ::flatbuffers::FlatBufferBuilder &_fbb, + uint32_t uid = 0, + uint32_t gid = 0, + const std::vector *supplementary_group_ids = nullptr, + const char *security_policy = nullptr, + const char *scheduling_policy = nullptr, + ::flatbuffers::Optional scheduling_priority = ::flatbuffers::nullopt, + ::flatbuffers::Optional max_memory_usage = ::flatbuffers::nullopt, + ::flatbuffers::Optional max_cpu_usage = ::flatbuffers::nullopt) { + auto supplementary_group_ids__ = supplementary_group_ids ? _fbb.CreateVector(*supplementary_group_ids) : 0; + auto security_policy__ = security_policy ? _fbb.CreateString(security_policy) : 0; + auto scheduling_policy__ = scheduling_policy ? _fbb.CreateString(scheduling_policy) : 0; + return score::launch_manager::config::fb::CreateSandbox( + _fbb, + uid, + gid, + supplementary_group_ids__, + security_policy__, + scheduling_policy__, + scheduling_priority, + max_memory_usage, + max_cpu_usage); +} + +struct DeploymentConfig FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef DeploymentConfigBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_READY_TIMEOUT = 4, + VT_SHUTDOWN_TIMEOUT = 6, + VT_ENVIRONMENTAL_VARIABLES = 8, + VT_BIN_DIR = 10, + VT_WORKING_DIR = 12, + VT_READY_RECOVERY_ACTION_TYPE = 14, + VT_READY_RECOVERY_ACTION = 16, + VT_RECOVERY_ACTION_TYPE = 18, + VT_RECOVERY_ACTION = 20, + VT_SANDBOX = 22 + }; + double ready_timeout() const { + return GetField(VT_READY_TIMEOUT, 0.0); + } + double shutdown_timeout() const { + return GetField(VT_SHUTDOWN_TIMEOUT, 0.0); + } + const ::flatbuffers::Vector<::flatbuffers::Offset> *environmental_variables() const { + return GetPointer> *>(VT_ENVIRONMENTAL_VARIABLES); + } + const ::flatbuffers::String *bin_dir() const { + return GetPointer(VT_BIN_DIR); + } + const ::flatbuffers::String *working_dir() const { + return GetPointer(VT_WORKING_DIR); + } + score::launch_manager::config::fb::RecoveryAction ready_recovery_action_type() const { + return static_cast(GetField(VT_READY_RECOVERY_ACTION_TYPE, 0)); + } + const void *ready_recovery_action() const { + return GetPointer(VT_READY_RECOVERY_ACTION); + } + template const T *ready_recovery_action_as() const; + const score::launch_manager::config::fb::RestartAction *ready_recovery_action_as_RestartAction() const { + return ready_recovery_action_type() == score::launch_manager::config::fb::RecoveryAction_RestartAction ? static_cast(ready_recovery_action()) : nullptr; + } + const score::launch_manager::config::fb::SwitchRunTargetAction *ready_recovery_action_as_SwitchRunTargetAction() const { + return ready_recovery_action_type() == score::launch_manager::config::fb::RecoveryAction_SwitchRunTargetAction ? static_cast(ready_recovery_action()) : nullptr; + } + score::launch_manager::config::fb::RecoveryAction recovery_action_type() const { + return static_cast(GetField(VT_RECOVERY_ACTION_TYPE, 0)); + } + const void *recovery_action() const { + return GetPointer(VT_RECOVERY_ACTION); + } + template const T *recovery_action_as() const; + const score::launch_manager::config::fb::RestartAction *recovery_action_as_RestartAction() const { + return recovery_action_type() == score::launch_manager::config::fb::RecoveryAction_RestartAction ? static_cast(recovery_action()) : nullptr; + } + const score::launch_manager::config::fb::SwitchRunTargetAction *recovery_action_as_SwitchRunTargetAction() const { + return recovery_action_type() == score::launch_manager::config::fb::RecoveryAction_SwitchRunTargetAction ? static_cast(recovery_action()) : nullptr; + } + const score::launch_manager::config::fb::Sandbox *sandbox() const { + return GetPointer(VT_SANDBOX); + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_READY_TIMEOUT, 8) && + VerifyField(verifier, VT_SHUTDOWN_TIMEOUT, 8) && + VerifyOffset(verifier, VT_ENVIRONMENTAL_VARIABLES) && + verifier.VerifyVector(environmental_variables()) && + verifier.VerifyVectorOfTables(environmental_variables()) && + VerifyOffsetRequired(verifier, VT_BIN_DIR) && + verifier.VerifyString(bin_dir()) && + VerifyOffset(verifier, VT_WORKING_DIR) && + verifier.VerifyString(working_dir()) && + VerifyField(verifier, VT_READY_RECOVERY_ACTION_TYPE, 1) && + VerifyOffset(verifier, VT_READY_RECOVERY_ACTION) && + VerifyRecoveryAction(verifier, ready_recovery_action(), ready_recovery_action_type()) && + VerifyField(verifier, VT_RECOVERY_ACTION_TYPE, 1) && + VerifyOffset(verifier, VT_RECOVERY_ACTION) && + VerifyRecoveryAction(verifier, recovery_action(), recovery_action_type()) && + VerifyOffset(verifier, VT_SANDBOX) && + verifier.VerifyTable(sandbox()) && + verifier.EndTable(); + } +}; + +template<> inline const score::launch_manager::config::fb::RestartAction *DeploymentConfig::ready_recovery_action_as() const { + return ready_recovery_action_as_RestartAction(); +} + +template<> inline const score::launch_manager::config::fb::SwitchRunTargetAction *DeploymentConfig::ready_recovery_action_as() const { + return ready_recovery_action_as_SwitchRunTargetAction(); +} + +template<> inline const score::launch_manager::config::fb::RestartAction *DeploymentConfig::recovery_action_as() const { + return recovery_action_as_RestartAction(); +} + +template<> inline const score::launch_manager::config::fb::SwitchRunTargetAction *DeploymentConfig::recovery_action_as() const { + return recovery_action_as_SwitchRunTargetAction(); +} + +struct DeploymentConfigBuilder { + typedef DeploymentConfig Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_ready_timeout(double ready_timeout) { + fbb_.AddElement(DeploymentConfig::VT_READY_TIMEOUT, ready_timeout, 0.0); + } + void add_shutdown_timeout(double shutdown_timeout) { + fbb_.AddElement(DeploymentConfig::VT_SHUTDOWN_TIMEOUT, shutdown_timeout, 0.0); + } + void add_environmental_variables(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> environmental_variables) { + fbb_.AddOffset(DeploymentConfig::VT_ENVIRONMENTAL_VARIABLES, environmental_variables); + } + void add_bin_dir(::flatbuffers::Offset<::flatbuffers::String> bin_dir) { + fbb_.AddOffset(DeploymentConfig::VT_BIN_DIR, bin_dir); + } + void add_working_dir(::flatbuffers::Offset<::flatbuffers::String> working_dir) { + fbb_.AddOffset(DeploymentConfig::VT_WORKING_DIR, working_dir); + } + void add_ready_recovery_action_type(score::launch_manager::config::fb::RecoveryAction ready_recovery_action_type) { + fbb_.AddElement(DeploymentConfig::VT_READY_RECOVERY_ACTION_TYPE, static_cast(ready_recovery_action_type), 0); + } + void add_ready_recovery_action(::flatbuffers::Offset ready_recovery_action) { + fbb_.AddOffset(DeploymentConfig::VT_READY_RECOVERY_ACTION, ready_recovery_action); + } + void add_recovery_action_type(score::launch_manager::config::fb::RecoveryAction recovery_action_type) { + fbb_.AddElement(DeploymentConfig::VT_RECOVERY_ACTION_TYPE, static_cast(recovery_action_type), 0); + } + void add_recovery_action(::flatbuffers::Offset recovery_action) { + fbb_.AddOffset(DeploymentConfig::VT_RECOVERY_ACTION, recovery_action); + } + void add_sandbox(::flatbuffers::Offset sandbox) { + fbb_.AddOffset(DeploymentConfig::VT_SANDBOX, sandbox); + } + explicit DeploymentConfigBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + fbb_.Required(o, DeploymentConfig::VT_BIN_DIR); + return o; + } +}; + +inline ::flatbuffers::Offset CreateDeploymentConfig( + ::flatbuffers::FlatBufferBuilder &_fbb, + double ready_timeout = 0.0, + double shutdown_timeout = 0.0, + ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> environmental_variables = 0, + ::flatbuffers::Offset<::flatbuffers::String> bin_dir = 0, + ::flatbuffers::Offset<::flatbuffers::String> working_dir = 0, + score::launch_manager::config::fb::RecoveryAction ready_recovery_action_type = score::launch_manager::config::fb::RecoveryAction_NONE, + ::flatbuffers::Offset ready_recovery_action = 0, + score::launch_manager::config::fb::RecoveryAction recovery_action_type = score::launch_manager::config::fb::RecoveryAction_NONE, + ::flatbuffers::Offset recovery_action = 0, + ::flatbuffers::Offset sandbox = 0) { + DeploymentConfigBuilder builder_(_fbb); + builder_.add_shutdown_timeout(shutdown_timeout); + builder_.add_ready_timeout(ready_timeout); + builder_.add_sandbox(sandbox); + builder_.add_recovery_action(recovery_action); + builder_.add_ready_recovery_action(ready_recovery_action); + builder_.add_working_dir(working_dir); + builder_.add_bin_dir(bin_dir); + builder_.add_environmental_variables(environmental_variables); + builder_.add_recovery_action_type(recovery_action_type); + builder_.add_ready_recovery_action_type(ready_recovery_action_type); + return builder_.Finish(); +} + +inline ::flatbuffers::Offset CreateDeploymentConfigDirect( + ::flatbuffers::FlatBufferBuilder &_fbb, + double ready_timeout = 0.0, + double shutdown_timeout = 0.0, + const std::vector<::flatbuffers::Offset> *environmental_variables = nullptr, + const char *bin_dir = nullptr, + const char *working_dir = nullptr, + score::launch_manager::config::fb::RecoveryAction ready_recovery_action_type = score::launch_manager::config::fb::RecoveryAction_NONE, + ::flatbuffers::Offset ready_recovery_action = 0, + score::launch_manager::config::fb::RecoveryAction recovery_action_type = score::launch_manager::config::fb::RecoveryAction_NONE, + ::flatbuffers::Offset recovery_action = 0, + ::flatbuffers::Offset sandbox = 0) { + auto environmental_variables__ = environmental_variables ? _fbb.CreateVector<::flatbuffers::Offset>(*environmental_variables) : 0; + auto bin_dir__ = bin_dir ? _fbb.CreateString(bin_dir) : 0; + auto working_dir__ = working_dir ? _fbb.CreateString(working_dir) : 0; + return score::launch_manager::config::fb::CreateDeploymentConfig( + _fbb, + ready_timeout, + shutdown_timeout, + environmental_variables__, + bin_dir__, + working_dir__, + ready_recovery_action_type, + ready_recovery_action, + recovery_action_type, + recovery_action, + sandbox); +} + +struct RunTarget FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef RunTargetBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_NAME = 4, + VT_DESCRIPTION = 6, + VT_DEPENDS_ON = 8, + VT_TRANSITION_TIMEOUT = 10, + VT_RECOVERY_ACTION_TYPE = 12, + VT_RECOVERY_ACTION = 14 + }; + const ::flatbuffers::String *name() const { + return GetPointer(VT_NAME); + } + const ::flatbuffers::String *description() const { + return GetPointer(VT_DESCRIPTION); + } + const ::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>> *depends_on() const { + return GetPointer> *>(VT_DEPENDS_ON); + } + double transition_timeout() const { + return GetField(VT_TRANSITION_TIMEOUT, 0.0); + } + score::launch_manager::config::fb::RecoveryAction recovery_action_type() const { + return static_cast(GetField(VT_RECOVERY_ACTION_TYPE, 0)); + } + const void *recovery_action() const { + return GetPointer(VT_RECOVERY_ACTION); + } + template const T *recovery_action_as() const; + const score::launch_manager::config::fb::RestartAction *recovery_action_as_RestartAction() const { + return recovery_action_type() == score::launch_manager::config::fb::RecoveryAction_RestartAction ? static_cast(recovery_action()) : nullptr; + } + const score::launch_manager::config::fb::SwitchRunTargetAction *recovery_action_as_SwitchRunTargetAction() const { + return recovery_action_type() == score::launch_manager::config::fb::RecoveryAction_SwitchRunTargetAction ? static_cast(recovery_action()) : nullptr; + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffsetRequired(verifier, VT_NAME) && + verifier.VerifyString(name()) && + VerifyOffset(verifier, VT_DESCRIPTION) && + verifier.VerifyString(description()) && + VerifyOffset(verifier, VT_DEPENDS_ON) && + verifier.VerifyVector(depends_on()) && + verifier.VerifyVectorOfStrings(depends_on()) && + VerifyField(verifier, VT_TRANSITION_TIMEOUT, 8) && + VerifyField(verifier, VT_RECOVERY_ACTION_TYPE, 1) && + VerifyOffsetRequired(verifier, VT_RECOVERY_ACTION) && + VerifyRecoveryAction(verifier, recovery_action(), recovery_action_type()) && + verifier.EndTable(); + } +}; + +template<> inline const score::launch_manager::config::fb::RestartAction *RunTarget::recovery_action_as() const { + return recovery_action_as_RestartAction(); +} + +template<> inline const score::launch_manager::config::fb::SwitchRunTargetAction *RunTarget::recovery_action_as() const { + return recovery_action_as_SwitchRunTargetAction(); +} + +struct RunTargetBuilder { + typedef RunTarget Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_name(::flatbuffers::Offset<::flatbuffers::String> name) { + fbb_.AddOffset(RunTarget::VT_NAME, name); + } + void add_description(::flatbuffers::Offset<::flatbuffers::String> description) { + fbb_.AddOffset(RunTarget::VT_DESCRIPTION, description); + } + void add_depends_on(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>> depends_on) { + fbb_.AddOffset(RunTarget::VT_DEPENDS_ON, depends_on); + } + void add_transition_timeout(double transition_timeout) { + fbb_.AddElement(RunTarget::VT_TRANSITION_TIMEOUT, transition_timeout, 0.0); + } + void add_recovery_action_type(score::launch_manager::config::fb::RecoveryAction recovery_action_type) { + fbb_.AddElement(RunTarget::VT_RECOVERY_ACTION_TYPE, static_cast(recovery_action_type), 0); + } + void add_recovery_action(::flatbuffers::Offset recovery_action) { + fbb_.AddOffset(RunTarget::VT_RECOVERY_ACTION, recovery_action); + } + explicit RunTargetBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + fbb_.Required(o, RunTarget::VT_NAME); + fbb_.Required(o, RunTarget::VT_RECOVERY_ACTION); + return o; + } +}; + +inline ::flatbuffers::Offset CreateRunTarget( + ::flatbuffers::FlatBufferBuilder &_fbb, + ::flatbuffers::Offset<::flatbuffers::String> name = 0, + ::flatbuffers::Offset<::flatbuffers::String> description = 0, + ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>> depends_on = 0, + double transition_timeout = 0.0, + score::launch_manager::config::fb::RecoveryAction recovery_action_type = score::launch_manager::config::fb::RecoveryAction_NONE, + ::flatbuffers::Offset recovery_action = 0) { + RunTargetBuilder builder_(_fbb); + builder_.add_transition_timeout(transition_timeout); + builder_.add_recovery_action(recovery_action); + builder_.add_depends_on(depends_on); + builder_.add_description(description); + builder_.add_name(name); + builder_.add_recovery_action_type(recovery_action_type); + return builder_.Finish(); +} + +inline ::flatbuffers::Offset CreateRunTargetDirect( + ::flatbuffers::FlatBufferBuilder &_fbb, + const char *name = nullptr, + const char *description = nullptr, + const std::vector<::flatbuffers::Offset<::flatbuffers::String>> *depends_on = nullptr, + double transition_timeout = 0.0, + score::launch_manager::config::fb::RecoveryAction recovery_action_type = score::launch_manager::config::fb::RecoveryAction_NONE, + ::flatbuffers::Offset recovery_action = 0) { + auto name__ = name ? _fbb.CreateString(name) : 0; + auto description__ = description ? _fbb.CreateString(description) : 0; + auto depends_on__ = depends_on ? _fbb.CreateVector<::flatbuffers::Offset<::flatbuffers::String>>(*depends_on) : 0; + return score::launch_manager::config::fb::CreateRunTarget( + _fbb, + name__, + description__, + depends_on__, + transition_timeout, + recovery_action_type, + recovery_action); +} + +struct Component FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef ComponentBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_NAME = 4, + VT_DESCRIPTION = 6, + VT_COMPONENT_PROPERTIES = 8, + VT_DEPLOYMENT_CONFIG = 10 + }; + const ::flatbuffers::String *name() const { + return GetPointer(VT_NAME); + } + const ::flatbuffers::String *description() const { + return GetPointer(VT_DESCRIPTION); + } + const score::launch_manager::config::fb::ComponentProperties *component_properties() const { + return GetPointer(VT_COMPONENT_PROPERTIES); + } + const score::launch_manager::config::fb::DeploymentConfig *deployment_config() const { + return GetPointer(VT_DEPLOYMENT_CONFIG); + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffsetRequired(verifier, VT_NAME) && + verifier.VerifyString(name()) && + VerifyOffset(verifier, VT_DESCRIPTION) && + verifier.VerifyString(description()) && + VerifyOffsetRequired(verifier, VT_COMPONENT_PROPERTIES) && + verifier.VerifyTable(component_properties()) && + VerifyOffsetRequired(verifier, VT_DEPLOYMENT_CONFIG) && + verifier.VerifyTable(deployment_config()) && + verifier.EndTable(); + } +}; + +struct ComponentBuilder { + typedef Component Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_name(::flatbuffers::Offset<::flatbuffers::String> name) { + fbb_.AddOffset(Component::VT_NAME, name); + } + void add_description(::flatbuffers::Offset<::flatbuffers::String> description) { + fbb_.AddOffset(Component::VT_DESCRIPTION, description); + } + void add_component_properties(::flatbuffers::Offset component_properties) { + fbb_.AddOffset(Component::VT_COMPONENT_PROPERTIES, component_properties); + } + void add_deployment_config(::flatbuffers::Offset deployment_config) { + fbb_.AddOffset(Component::VT_DEPLOYMENT_CONFIG, deployment_config); + } + explicit ComponentBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + fbb_.Required(o, Component::VT_NAME); + fbb_.Required(o, Component::VT_COMPONENT_PROPERTIES); + fbb_.Required(o, Component::VT_DEPLOYMENT_CONFIG); + return o; + } +}; + +inline ::flatbuffers::Offset CreateComponent( + ::flatbuffers::FlatBufferBuilder &_fbb, + ::flatbuffers::Offset<::flatbuffers::String> name = 0, + ::flatbuffers::Offset<::flatbuffers::String> description = 0, + ::flatbuffers::Offset component_properties = 0, + ::flatbuffers::Offset deployment_config = 0) { + ComponentBuilder builder_(_fbb); + builder_.add_deployment_config(deployment_config); + builder_.add_component_properties(component_properties); + builder_.add_description(description); + builder_.add_name(name); + return builder_.Finish(); +} + +inline ::flatbuffers::Offset CreateComponentDirect( + ::flatbuffers::FlatBufferBuilder &_fbb, + const char *name = nullptr, + const char *description = nullptr, + ::flatbuffers::Offset component_properties = 0, + ::flatbuffers::Offset deployment_config = 0) { + auto name__ = name ? _fbb.CreateString(name) : 0; + auto description__ = description ? _fbb.CreateString(description) : 0; + return score::launch_manager::config::fb::CreateComponent( + _fbb, + name__, + description__, + component_properties, + deployment_config); +} + +struct AliveSupervision FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef AliveSupervisionBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_EVALUATION_CYCLE = 4 + }; + double evaluation_cycle() const { + return GetField(VT_EVALUATION_CYCLE, 0.0); + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_EVALUATION_CYCLE, 8) && + verifier.EndTable(); + } +}; + +struct AliveSupervisionBuilder { + typedef AliveSupervision Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_evaluation_cycle(double evaluation_cycle) { + fbb_.AddElement(AliveSupervision::VT_EVALUATION_CYCLE, evaluation_cycle, 0.0); + } + explicit AliveSupervisionBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateAliveSupervision( + ::flatbuffers::FlatBufferBuilder &_fbb, + double evaluation_cycle = 0.0) { + AliveSupervisionBuilder builder_(_fbb); + builder_.add_evaluation_cycle(evaluation_cycle); + return builder_.Finish(); +} + +struct Watchdog FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef WatchdogBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_DEVICE_FILE_PATH = 4, + VT_MAX_TIMEOUT = 6, + VT_DEACTIVATE_ON_SHUTDOWN = 8, + VT_REQUIRE_MAGIC_CLOSE = 10 + }; + const ::flatbuffers::String *device_file_path() const { + return GetPointer(VT_DEVICE_FILE_PATH); + } + double max_timeout() const { + return GetField(VT_MAX_TIMEOUT, 0.0); + } + ::flatbuffers::Optional deactivate_on_shutdown() const { + return GetOptional(VT_DEACTIVATE_ON_SHUTDOWN); + } + ::flatbuffers::Optional require_magic_close() const { + return GetOptional(VT_REQUIRE_MAGIC_CLOSE); + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffsetRequired(verifier, VT_DEVICE_FILE_PATH) && + verifier.VerifyString(device_file_path()) && + VerifyField(verifier, VT_MAX_TIMEOUT, 8) && + VerifyField(verifier, VT_DEACTIVATE_ON_SHUTDOWN, 1) && + VerifyField(verifier, VT_REQUIRE_MAGIC_CLOSE, 1) && + verifier.EndTable(); + } +}; + +struct WatchdogBuilder { + typedef Watchdog Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_device_file_path(::flatbuffers::Offset<::flatbuffers::String> device_file_path) { + fbb_.AddOffset(Watchdog::VT_DEVICE_FILE_PATH, device_file_path); + } + void add_max_timeout(double max_timeout) { + fbb_.AddElement(Watchdog::VT_MAX_TIMEOUT, max_timeout, 0.0); + } + void add_deactivate_on_shutdown(bool deactivate_on_shutdown) { + fbb_.AddElement(Watchdog::VT_DEACTIVATE_ON_SHUTDOWN, static_cast(deactivate_on_shutdown)); + } + void add_require_magic_close(bool require_magic_close) { + fbb_.AddElement(Watchdog::VT_REQUIRE_MAGIC_CLOSE, static_cast(require_magic_close)); + } + explicit WatchdogBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + fbb_.Required(o, Watchdog::VT_DEVICE_FILE_PATH); + return o; + } +}; + +inline ::flatbuffers::Offset CreateWatchdog( + ::flatbuffers::FlatBufferBuilder &_fbb, + ::flatbuffers::Offset<::flatbuffers::String> device_file_path = 0, + double max_timeout = 0.0, + ::flatbuffers::Optional deactivate_on_shutdown = ::flatbuffers::nullopt, + ::flatbuffers::Optional require_magic_close = ::flatbuffers::nullopt) { + WatchdogBuilder builder_(_fbb); + builder_.add_max_timeout(max_timeout); + builder_.add_device_file_path(device_file_path); + if(require_magic_close) { builder_.add_require_magic_close(*require_magic_close); } + if(deactivate_on_shutdown) { builder_.add_deactivate_on_shutdown(*deactivate_on_shutdown); } + return builder_.Finish(); +} + +inline ::flatbuffers::Offset CreateWatchdogDirect( + ::flatbuffers::FlatBufferBuilder &_fbb, + const char *device_file_path = nullptr, + double max_timeout = 0.0, + ::flatbuffers::Optional deactivate_on_shutdown = ::flatbuffers::nullopt, + ::flatbuffers::Optional require_magic_close = ::flatbuffers::nullopt) { + auto device_file_path__ = device_file_path ? _fbb.CreateString(device_file_path) : 0; + return score::launch_manager::config::fb::CreateWatchdog( + _fbb, + device_file_path__, + max_timeout, + deactivate_on_shutdown, + require_magic_close); +} + +struct FallbackRunTarget FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef FallbackRunTargetBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_DESCRIPTION = 4, + VT_DEPENDS_ON = 6, + VT_TRANSITION_TIMEOUT = 8 + }; + const ::flatbuffers::String *description() const { + return GetPointer(VT_DESCRIPTION); + } + const ::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>> *depends_on() const { + return GetPointer> *>(VT_DEPENDS_ON); + } + double transition_timeout() const { + return GetField(VT_TRANSITION_TIMEOUT, 0.0); + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_DESCRIPTION) && + verifier.VerifyString(description()) && + VerifyOffset(verifier, VT_DEPENDS_ON) && + verifier.VerifyVector(depends_on()) && + verifier.VerifyVectorOfStrings(depends_on()) && + VerifyField(verifier, VT_TRANSITION_TIMEOUT, 8) && + verifier.EndTable(); + } +}; + +struct FallbackRunTargetBuilder { + typedef FallbackRunTarget Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_description(::flatbuffers::Offset<::flatbuffers::String> description) { + fbb_.AddOffset(FallbackRunTarget::VT_DESCRIPTION, description); + } + void add_depends_on(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>> depends_on) { + fbb_.AddOffset(FallbackRunTarget::VT_DEPENDS_ON, depends_on); + } + void add_transition_timeout(double transition_timeout) { + fbb_.AddElement(FallbackRunTarget::VT_TRANSITION_TIMEOUT, transition_timeout, 0.0); + } + explicit FallbackRunTargetBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateFallbackRunTarget( + ::flatbuffers::FlatBufferBuilder &_fbb, + ::flatbuffers::Offset<::flatbuffers::String> description = 0, + ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>> depends_on = 0, + double transition_timeout = 0.0) { + FallbackRunTargetBuilder builder_(_fbb); + builder_.add_transition_timeout(transition_timeout); + builder_.add_depends_on(depends_on); + builder_.add_description(description); + return builder_.Finish(); +} + +inline ::flatbuffers::Offset CreateFallbackRunTargetDirect( + ::flatbuffers::FlatBufferBuilder &_fbb, + const char *description = nullptr, + const std::vector<::flatbuffers::Offset<::flatbuffers::String>> *depends_on = nullptr, + double transition_timeout = 0.0) { + auto description__ = description ? _fbb.CreateString(description) : 0; + auto depends_on__ = depends_on ? _fbb.CreateVector<::flatbuffers::Offset<::flatbuffers::String>>(*depends_on) : 0; + return score::launch_manager::config::fb::CreateFallbackRunTarget( + _fbb, + description__, + depends_on__, + transition_timeout); +} + +struct LaunchManagerConfig FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef LaunchManagerConfigBuilder Builder; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_SCHEMA_VERSION = 4, + VT_COMPONENTS = 6, + VT_RUN_TARGETS = 8, + VT_INITIAL_RUN_TARGET = 10, + VT_FALLBACK_RUN_TARGET = 12, + VT_ALIVE_SUPERVISION = 14, + VT_WATCHDOG = 16 + }; + int32_t schema_version() const { + return GetField(VT_SCHEMA_VERSION, 0); + } + const ::flatbuffers::Vector<::flatbuffers::Offset> *components() const { + return GetPointer> *>(VT_COMPONENTS); + } + const ::flatbuffers::Vector<::flatbuffers::Offset> *run_targets() const { + return GetPointer> *>(VT_RUN_TARGETS); + } + const ::flatbuffers::String *initial_run_target() const { + return GetPointer(VT_INITIAL_RUN_TARGET); + } + const score::launch_manager::config::fb::FallbackRunTarget *fallback_run_target() const { + return GetPointer(VT_FALLBACK_RUN_TARGET); + } + const score::launch_manager::config::fb::AliveSupervision *alive_supervision() const { + return GetPointer(VT_ALIVE_SUPERVISION); + } + const score::launch_manager::config::fb::Watchdog *watchdog() const { + return GetPointer(VT_WATCHDOG); + } + bool Verify(::flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_SCHEMA_VERSION, 4) && + VerifyOffset(verifier, VT_COMPONENTS) && + verifier.VerifyVector(components()) && + verifier.VerifyVectorOfTables(components()) && + VerifyOffset(verifier, VT_RUN_TARGETS) && + verifier.VerifyVector(run_targets()) && + verifier.VerifyVectorOfTables(run_targets()) && + VerifyOffsetRequired(verifier, VT_INITIAL_RUN_TARGET) && + verifier.VerifyString(initial_run_target()) && + VerifyOffsetRequired(verifier, VT_FALLBACK_RUN_TARGET) && + verifier.VerifyTable(fallback_run_target()) && + VerifyOffsetRequired(verifier, VT_ALIVE_SUPERVISION) && + verifier.VerifyTable(alive_supervision()) && + VerifyOffset(verifier, VT_WATCHDOG) && + verifier.VerifyTable(watchdog()) && + verifier.EndTable(); + } +}; + +struct LaunchManagerConfigBuilder { + typedef LaunchManagerConfig Table; + ::flatbuffers::FlatBufferBuilder &fbb_; + ::flatbuffers::uoffset_t start_; + void add_schema_version(int32_t schema_version) { + fbb_.AddElement(LaunchManagerConfig::VT_SCHEMA_VERSION, schema_version, 0); + } + void add_components(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> components) { + fbb_.AddOffset(LaunchManagerConfig::VT_COMPONENTS, components); + } + void add_run_targets(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> run_targets) { + fbb_.AddOffset(LaunchManagerConfig::VT_RUN_TARGETS, run_targets); + } + void add_initial_run_target(::flatbuffers::Offset<::flatbuffers::String> initial_run_target) { + fbb_.AddOffset(LaunchManagerConfig::VT_INITIAL_RUN_TARGET, initial_run_target); + } + void add_fallback_run_target(::flatbuffers::Offset fallback_run_target) { + fbb_.AddOffset(LaunchManagerConfig::VT_FALLBACK_RUN_TARGET, fallback_run_target); + } + void add_alive_supervision(::flatbuffers::Offset alive_supervision) { + fbb_.AddOffset(LaunchManagerConfig::VT_ALIVE_SUPERVISION, alive_supervision); + } + void add_watchdog(::flatbuffers::Offset watchdog) { + fbb_.AddOffset(LaunchManagerConfig::VT_WATCHDOG, watchdog); + } + explicit LaunchManagerConfigBuilder(::flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + fbb_.Required(o, LaunchManagerConfig::VT_INITIAL_RUN_TARGET); + fbb_.Required(o, LaunchManagerConfig::VT_FALLBACK_RUN_TARGET); + fbb_.Required(o, LaunchManagerConfig::VT_ALIVE_SUPERVISION); + return o; + } +}; + +inline ::flatbuffers::Offset CreateLaunchManagerConfig( + ::flatbuffers::FlatBufferBuilder &_fbb, + int32_t schema_version = 0, + ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> components = 0, + ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> run_targets = 0, + ::flatbuffers::Offset<::flatbuffers::String> initial_run_target = 0, + ::flatbuffers::Offset fallback_run_target = 0, + ::flatbuffers::Offset alive_supervision = 0, + ::flatbuffers::Offset watchdog = 0) { + LaunchManagerConfigBuilder builder_(_fbb); + builder_.add_watchdog(watchdog); + builder_.add_alive_supervision(alive_supervision); + builder_.add_fallback_run_target(fallback_run_target); + builder_.add_initial_run_target(initial_run_target); + builder_.add_run_targets(run_targets); + builder_.add_components(components); + builder_.add_schema_version(schema_version); + return builder_.Finish(); +} + +inline ::flatbuffers::Offset CreateLaunchManagerConfigDirect( + ::flatbuffers::FlatBufferBuilder &_fbb, + int32_t schema_version = 0, + const std::vector<::flatbuffers::Offset> *components = nullptr, + const std::vector<::flatbuffers::Offset> *run_targets = nullptr, + const char *initial_run_target = nullptr, + ::flatbuffers::Offset fallback_run_target = 0, + ::flatbuffers::Offset alive_supervision = 0, + ::flatbuffers::Offset watchdog = 0) { + auto components__ = components ? _fbb.CreateVector<::flatbuffers::Offset>(*components) : 0; + auto run_targets__ = run_targets ? _fbb.CreateVector<::flatbuffers::Offset>(*run_targets) : 0; + auto initial_run_target__ = initial_run_target ? _fbb.CreateString(initial_run_target) : 0; + return score::launch_manager::config::fb::CreateLaunchManagerConfig( + _fbb, + schema_version, + components__, + run_targets__, + initial_run_target__, + fallback_run_target, + alive_supervision, + watchdog); +} + +inline bool VerifyRecoveryAction(::flatbuffers::Verifier &verifier, const void *obj, RecoveryAction type) { + switch (type) { + case RecoveryAction_NONE: { + return true; + } + case RecoveryAction_RestartAction: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + case RecoveryAction_SwitchRunTargetAction: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } + default: return true; + } +} + +inline bool VerifyRecoveryActionVector(::flatbuffers::Verifier &verifier, const ::flatbuffers::Vector<::flatbuffers::Offset> *values, const ::flatbuffers::Vector *types) { + if (!values || !types) return !values && !types; + if (values->size() != types->size()) return false; + for (::flatbuffers::uoffset_t i = 0; i < values->size(); ++i) { + if (!VerifyRecoveryAction( + verifier, values->Get(i), types->GetEnum(i))) { + return false; + } + } + return true; +} + +inline const score::launch_manager::config::fb::LaunchManagerConfig *GetLaunchManagerConfig(const void *buf) { + return ::flatbuffers::GetRoot(buf); +} + +inline const score::launch_manager::config::fb::LaunchManagerConfig *GetSizePrefixedLaunchManagerConfig(const void *buf) { + return ::flatbuffers::GetSizePrefixedRoot(buf); +} + +inline bool VerifyLaunchManagerConfigBuffer( + ::flatbuffers::Verifier &verifier) { + return verifier.VerifyBuffer(nullptr); +} + +inline bool VerifySizePrefixedLaunchManagerConfigBuffer( + ::flatbuffers::Verifier &verifier) { + return verifier.VerifySizePrefixedBuffer(nullptr); +} + +inline void FinishLaunchManagerConfigBuffer( + ::flatbuffers::FlatBufferBuilder &fbb, + ::flatbuffers::Offset root) { + fbb.Finish(root); +} + +inline void FinishSizePrefixedLaunchManagerConfigBuffer( + ::flatbuffers::FlatBufferBuilder &fbb, + ::flatbuffers::Offset root) { + fbb.FinishSizePrefixed(root); +} + +} // namespace fb +} // namespace config +} // namespace launch_manager +} // namespace score + +#endif // FLATBUFFERS_GENERATED_NEWLMFLATCFG_SCORE_LAUNCH_MANAGER_CONFIG_FB_H_ From 164b832b7c25bcfed00a79764648c1b8f3be1fd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Fu=C3=9Fberger?= Date: Mon, 18 May 2026 16:09:59 +0200 Subject: [PATCH 02/26] Upgrade baselibs & flatbuffer version --- MODULE.bazel | 9 ++- MODULE.bazel.lock | 50 +++---------- .../config/lm_flatcfg_generated.h | 56 +++++++-------- .../config/src/new_lm_flatcfg_generated.h | 71 ++++++++++++------- .../config/hm_flatcfg_generated.h | 71 ++++++++++--------- .../config/hmcore_flatcfg_generated.h | 35 ++++----- 6 files changed, 144 insertions(+), 148 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index b6cd10238..a8cec0078 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -25,7 +25,7 @@ bazel_dep(name = "rules_oci", version = "2.3.0") bazel_dep(name = "aspect_rules_lint", version = "2.0.0") bazel_dep(name = "buildifier_prebuilt", version = "8.2.0.2") bazel_dep(name = "platforms", version = "1.0.0") -bazel_dep(name = "flatbuffers", version = "25.9.23") +bazel_dep(name = "flatbuffers", version = "25.12.19") bazel_dep(name = "download_utils", version = "1.2.2") bazel_dep(name = "googletest", version = "1.17.0.bcr.2") @@ -133,6 +133,13 @@ use_repo(oci, "debian-test-runtime", "debian-test-runtime_linux_amd64") bazel_dep(name = "score_baselibs_rust", version = "0.1.2") bazel_dep(name = "score_baselibs", version = "0.2.6") +# Temporarily overwrite baselibs to use the new flatbuffer config loader until there is a new release +git_override( + module_name = "score_baselibs", + commit = "498a4b256c9073602140243d30c33b106e279f75", + remote = "https://github.com/eclipse-score/baselibs.git", +) + # Hedron's Compile Commands Extractor for Bazel # https://github.com/hedronvision/bazel-compile-commands-extractor diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 6f3fcf108..3583d88fd 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -173,8 +173,9 @@ "https://bcr.bazel.build/modules/download_utils/1.2.2/source.json": "c88be2bc48c98371d35665b805f307a647c98c83327345c918d9088822d77928", "https://bcr.bazel.build/modules/envoy_api/0.0.0-20241214-918efc9/MODULE.bazel": "24e05f6f52f37be63a795192848555a2c8c855e7814dbc1ed419fb04a7005464", "https://bcr.bazel.build/modules/envoy_api/0.0.0-20241214-918efc9/source.json": "212043ab69d87f7a04aa4f627f725b540cff5e145a3a31a9403d8b6ec2e920c9", + "https://bcr.bazel.build/modules/flatbuffers/25.12.19/MODULE.bazel": "fe3a7f7811f43264f68136ad99e64384d70b2a25245e09ab800c4bb83171da25", + "https://bcr.bazel.build/modules/flatbuffers/25.12.19/source.json": "ea0204be7a79de9141cee5fa436e58a14e88b39b5b59227b21efa0394474ebea", "https://bcr.bazel.build/modules/flatbuffers/25.9.23/MODULE.bazel": "32753ba60bf3bacfe7737c0f3e8e3e55624b19af5d398c485580d57492d145d8", - "https://bcr.bazel.build/modules/flatbuffers/25.9.23/source.json": "a2116f0017f6896353fd3abf65ef2b89b0a257e8a87f395c5000f53934829f31", "https://bcr.bazel.build/modules/gawk/5.3.2.bcr.1/MODULE.bazel": "cdf8cbe5ee750db04b78878c9633cc76e80dcf4416cbe982ac3a9222f80713c8", "https://bcr.bazel.build/modules/gawk/5.3.2.bcr.1/source.json": "fa7b512dfcb5eafd90ce3959cf42a2a6fe96144ebbb4b3b3928054895f2afac2", "https://bcr.bazel.build/modules/gazelle/0.27.0/MODULE.bazel": "3446abd608295de6d90b4a8a118ed64a9ce11dcb3dda2dc3290a22056bd20996", @@ -227,6 +228,8 @@ "https://bcr.bazel.build/modules/opencensus-cpp/0.0.0-20230502-50eb5de/source.json": "f50efc07822f5425bd1d3e40e977484f9c0142463052717d40ec85cd6744243e", "https://bcr.bazel.build/modules/opencensus-proto/0.4.1/MODULE.bazel": "4a2e8b4d0b544002502474d611a5a183aa282251e14f6a01afe841c0c1b10372", "https://bcr.bazel.build/modules/opencensus-proto/0.4.1/source.json": "a7d956700a85b833c43fc61455c0e111ab75bab40768ed17a206ee18a2bbe38f", + "https://bcr.bazel.build/modules/openssl/3.5.5.bcr.4/MODULE.bazel": "b3f35b53c6c73bd3a7c8efbf9b7e79e92566d189e64d313aede69f608ac6dd77", + "https://bcr.bazel.build/modules/openssl/3.5.5.bcr.4/source.json": "662d68be9227e60ef65fed83c6820564bda4af0efe6a40dc62dd9aee288fe9cf", "https://bcr.bazel.build/modules/opentelemetry-cpp/1.14.2/MODULE.bazel": "089a5613c2a159c7dfde098dabfc61e966889c7d6a81a98422a84c51535ed17d", "https://bcr.bazel.build/modules/opentelemetry-cpp/1.16.0/MODULE.bazel": "b7379a140f538cea3f749179a2d481ed81942cc6f7b05a6113723eb34ac3b3e7", "https://bcr.bazel.build/modules/opentelemetry-cpp/1.16.0/source.json": "da0cf667713b1e48d7f8912b100b4e0a8284c8a95717af5eb8c830d699e61cf5", @@ -309,7 +312,6 @@ "https://bcr.bazel.build/modules/rules_cc/0.1.4/MODULE.bazel": "bb03a452a7527ac25a7518fb86a946ef63df860b9657d8323a0c50f8504fb0b9", "https://bcr.bazel.build/modules/rules_cc/0.1.5/MODULE.bazel": "88dfc9361e8b5ae1008ac38f7cdfd45ad738e4fa676a3ad67d19204f045a1fd8", "https://bcr.bazel.build/modules/rules_cc/0.2.14/MODULE.bazel": "353c99ed148887ee89c54a17d4100ae7e7e436593d104b668476019023b58df8", - "https://bcr.bazel.build/modules/rules_cc/0.2.16/MODULE.bazel": "9242fa89f950c6ef7702801ab53922e99c69b02310c39fb6e62b2bd30df2a1d4", "https://bcr.bazel.build/modules/rules_cc/0.2.17/MODULE.bazel": "1849602c86cb60da8613d2de887f9566a6d354a6df6d7009f9d04a14402f9a84", "https://bcr.bazel.build/modules/rules_cc/0.2.17/source.json": "3832f45d145354049137c0090df04629d9c2b5493dc5c2bf46f1834040133a07", "https://bcr.bazel.build/modules/rules_cc/0.2.4/MODULE.bazel": "1ff1223dfd24f3ecf8f028446d4a27608aa43c3f41e346d22838a4223980b8cc", @@ -384,6 +386,8 @@ "https://bcr.bazel.build/modules/rules_nodejs/6.5.2/source.json": "6a6ca0940914d55c550d1417cad13a56c9900e23f651a762d8ccc5a64adcf661", "https://bcr.bazel.build/modules/rules_oci/2.3.0/MODULE.bazel": "49075197960c924c0a4d759b7c765c3d00a41d2fdd4a943b42823c1d016ab4ec", "https://bcr.bazel.build/modules/rules_oci/2.3.0/source.json": "47710c28446211b5e61a24015a4669c50c6862d5f91e6bdbc710de8d750cf613", + "https://bcr.bazel.build/modules/rules_perl/1.1.0/MODULE.bazel": "22138e75bb8f1ee6c21f609b90d2c24b0c9b796ccf55cc04c1c9190b699f7e9d", + "https://bcr.bazel.build/modules/rules_perl/1.1.0/source.json": "896fe7707a38c5b229c6f5fa77134209874c4d57fecda5f756c1f23e4d25aae2", "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", "https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff", "https://bcr.bazel.build/modules/rules_pkg/1.1.0/MODULE.bazel": "9db8031e71b6ef32d1846106e10dd0ee2deac042bd9a2de22b4761b0c3036453", @@ -599,6 +603,7 @@ "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/download_utils/1.0.1/MODULE.bazel": "not found", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/download_utils/1.2.2/MODULE.bazel": "not found", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/envoy_api/0.0.0-20241214-918efc9/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/flatbuffers/25.12.19/MODULE.bazel": "not found", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/flatbuffers/25.9.23/MODULE.bazel": "not found", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/gawk/5.3.2.bcr.1/MODULE.bazel": "not found", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/gazelle/0.27.0/MODULE.bazel": "not found", @@ -637,6 +642,7 @@ "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/nlohmann_json/3.6.1/MODULE.bazel": "not found", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/opencensus-cpp/0.0.0-20230502-50eb5de/MODULE.bazel": "not found", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/opencensus-proto/0.4.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/openssl/3.5.5.bcr.4/MODULE.bazel": "not found", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/opentelemetry-cpp/1.14.2/MODULE.bazel": "not found", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/opentelemetry-cpp/1.16.0/MODULE.bazel": "not found", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/opentelemetry-proto/1.1.0/MODULE.bazel": "not found", @@ -705,7 +711,6 @@ "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.1.4/MODULE.bazel": "not found", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.1.5/MODULE.bazel": "not found", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.2.14/MODULE.bazel": "not found", - "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.2.16/MODULE.bazel": "not found", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.2.17/MODULE.bazel": "not found", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.2.4/MODULE.bazel": "not found", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_cc/0.2.8/MODULE.bazel": "not found", @@ -768,6 +773,7 @@ "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_nodejs/6.3.3/MODULE.bazel": "not found", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_nodejs/6.5.2/MODULE.bazel": "not found", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_oci/2.3.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_perl/1.1.0/MODULE.bazel": "not found", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_pkg/0.7.0/MODULE.bazel": "not found", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_pkg/1.0.1/MODULE.bazel": "not found", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_pkg/1.1.0/MODULE.bazel": "not found", @@ -814,8 +820,6 @@ "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_swift/1.16.0/MODULE.bazel": "not found", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_swift/1.18.0/MODULE.bazel": "not found", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_swift/2.1.1/MODULE.bazel": "not found", - "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_baselibs/0.2.6/MODULE.bazel": "36db2ffb07d1b4cc91f44ffbdb17cab834baef0fb3173c5e9b6885868fdc420c", - "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_baselibs/0.2.6/source.json": "a8bb7e82abe9d4de6301e4a28252e51323d4a758fe0b8e74ac9fd8c3ea625c3f", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_baselibs_rust/0.1.2/MODULE.bazel": "8a07e1c62986e941a6e182e39c9cd08391849eed55c2f4dbb02d72ef6f524346", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_baselibs_rust/0.1.2/source.json": "5d920b55b98cf3d87da75d5a3ab1915709867fda14991ef2843c5e7c33aa0391", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_bazel_cpp_toolchains/0.2.2/MODULE.bazel": "343a1892b1d5c616e0b4cbecfb5e548fa69328d22bb4fd5862bdd3cfa902142b", @@ -1343,40 +1347,6 @@ ] } }, - "@@aspect_rules_ts+//ts:extensions.bzl%ext": { - "general": { - "bzlTransitiveDigest": "MTYrHsOSgiQcK2kWLEJXgQN+rPXhhAOe+aJ7E65JPKE=", - "usagesDigest": "caXVbnxEUN71ZxydJbg6pZ8NaFPVDbNp12wS9TMC824=", - "recordedFileInputs": {}, - "recordedDirentsInputs": {}, - "envVariables": {}, - "generatedRepoSpecs": { - "npm_typescript": { - "repoRuleId": "@@aspect_rules_ts+//ts/private:npm_repositories.bzl%http_archive_version", - "attributes": { - "bzlmod": true, - "version": "5.8.3", - "integrity": "", - "build_file": "@@aspect_rules_ts+//ts:BUILD.typescript", - "build_file_substitutions": { - "bazel_worker_version": "5.4.2", - "google_protobuf_version": "3.20.1" - }, - "urls": [ - "https://registry.npmjs.org/typescript/-/typescript-{}.tgz" - ] - } - } - }, - "recordedRepoMappingEntries": [ - [ - "aspect_rules_ts+", - "bazel_tools", - "bazel_tools" - ] - ] - } - }, "@@aspect_tools_telemetry+//:extension.bzl%telemetry": { "general": { "bzlTransitiveDigest": "gA7tPEdJXhskzPIEUxjX9IdDrM6+WjfbgXJ8Ez47umk=", @@ -2289,7 +2259,7 @@ "@@rules_nodejs+//nodejs:extensions.bzl%node": { "general": { "bzlTransitiveDigest": "FmfMiNXAxRoLWw3NloQbssosE1egrSvzirbQnso7j7E=", - "usagesDigest": "xQt2gTXxeHPqo+xDPEb0l8bxaCWaMbfvKRJcHvysWMI=", + "usagesDigest": "RmjWGl+udnOtLbA4SVIYVixOYhc+YyN36MKAPAhLDWw=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, diff --git a/src/launch_manager_daemon/config/lm_flatcfg_generated.h b/src/launch_manager_daemon/config/lm_flatcfg_generated.h index f82a2547f..6c7fbac3b 100644 --- a/src/launch_manager_daemon/config/lm_flatcfg_generated.h +++ b/src/launch_manager_daemon/config/lm_flatcfg_generated.h @@ -1,15 +1,3 @@ -/******************************************************************************** - * Copyright (c) 2025 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0 - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ // automatically generated by the FlatBuffers compiler, do not modify @@ -21,8 +9,8 @@ // Ensure the included flatbuffers.h is the same version as when this file was // generated, otherwise it may not be compatible. static_assert(FLATBUFFERS_VERSION_MAJOR == 25 && - FLATBUFFERS_VERSION_MINOR == 9 && - FLATBUFFERS_VERSION_REVISION == 23, + FLATBUFFERS_VERSION_MINOR == 12 && + FLATBUFFERS_VERSION_REVISION == 19, "Non-compatible flatbuffers version included"); namespace LMFlatBuffer { @@ -137,7 +125,8 @@ struct LMEcuCfg FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { const ::flatbuffers::Vector<::flatbuffers::Offset> *Process() const { return GetPointer> *>(VT_PROCESS); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_VERSIONMAJOR, 4) && VerifyField(verifier, VT_VERSIONMINOR, 4) && @@ -232,7 +221,8 @@ struct ModeGroup FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { const ::flatbuffers::Vector<::flatbuffers::Offset> *modeDeclaration() const { return GetPointer> *>(VT_MODEDECLARATION); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_IDENTIFIER) && verifier.VerifyString(identifier()) && @@ -324,7 +314,8 @@ struct ModeDeclaration FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { const ::flatbuffers::String *identifier() const { return GetPointer(VT_IDENTIFIER); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_IDENTIFIER) && verifier.VerifyString(identifier()) && @@ -415,7 +406,8 @@ struct Process FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { const ::flatbuffers::Vector<::flatbuffers::Offset> *sgids() const { return GetPointer> *>(VT_SGIDS); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_IDENTIFIER) && verifier.VerifyString(identifier()) && @@ -604,7 +596,8 @@ struct ProcessStartupConfig FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Tab uint64_t memoryUsage() const { return GetField(VT_MEMORYUSAGE, 0); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_IDENTIFIER) && verifier.VerifyString(identifier()) && @@ -765,7 +758,8 @@ struct ProcessGroupStateDependency FLATBUFFERS_FINAL_CLASS : private ::flatbuffe const ::flatbuffers::String *stateName() const { return GetPointer(VT_STATENAME); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_STATEMACHINE_NAME) && verifier.VerifyString(stateMachine_name()) && @@ -830,7 +824,8 @@ struct ProcessExecutionDependency FLATBUFFERS_FINAL_CLASS : private ::flatbuffer const ::flatbuffers::String *targetProcess_identifier() const { return GetPointer(VT_TARGETPROCESS_IDENTIFIER); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_STATENAME) && verifier.VerifyString(stateName()) && @@ -895,7 +890,8 @@ struct EnvironmentVariable FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Tabl const ::flatbuffers::String *value() const { return GetPointer(VT_VALUE); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_KEY) && verifier.VerifyString(key()) && @@ -956,7 +952,8 @@ struct ProcessArgument FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { const ::flatbuffers::String *argument() const { return GetPointer(VT_ARGUMENT); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_ARGUMENT) && verifier.VerifyString(argument()) && @@ -1007,7 +1004,8 @@ struct ProcessSgid FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { uint32_t sgid() const { return GetField(VT_SGID, 0); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_SGID, 4) && verifier.EndTable(); @@ -1062,14 +1060,16 @@ inline bool SizePrefixedLMEcuCfgBufferHasIdentifier(const void *buf) { buf, LMEcuCfgIdentifier(), true); } +template inline bool VerifyLMEcuCfgBuffer( - ::flatbuffers::Verifier &verifier) { - return verifier.VerifyBuffer(LMEcuCfgIdentifier()); + ::flatbuffers::VerifierTemplate &verifier) { + return verifier.template VerifyBuffer(LMEcuCfgIdentifier()); } +template inline bool VerifySizePrefixedLMEcuCfgBuffer( - ::flatbuffers::Verifier &verifier) { - return verifier.VerifySizePrefixedBuffer(LMEcuCfgIdentifier()); + ::flatbuffers::VerifierTemplate &verifier) { + return verifier.template VerifySizePrefixedBuffer(LMEcuCfgIdentifier()); } inline const char *LMEcuCfgExtension() { diff --git a/src/launch_manager_daemon/config/src/new_lm_flatcfg_generated.h b/src/launch_manager_daemon/config/src/new_lm_flatcfg_generated.h index 30c84cf6b..ff1f4bf4a 100644 --- a/src/launch_manager_daemon/config/src/new_lm_flatcfg_generated.h +++ b/src/launch_manager_daemon/config/src/new_lm_flatcfg_generated.h @@ -9,8 +9,8 @@ // Ensure the included flatbuffers.h is the same version as when this file was // generated, otherwise it may not be compatible. static_assert(FLATBUFFERS_VERSION_MAJOR == 25 && - FLATBUFFERS_VERSION_MINOR == 9 && - FLATBUFFERS_VERSION_REVISION == 23, + FLATBUFFERS_VERSION_MINOR == 12 && + FLATBUFFERS_VERSION_REVISION == 19, "Non-compatible flatbuffers version included"); namespace score { @@ -174,8 +174,10 @@ template<> struct RecoveryActionTraits> *values, const ::flatbuffers::Vector *types); +template +bool VerifyRecoveryAction(::flatbuffers::VerifierTemplate &verifier, const void *obj, RecoveryAction type); +template +bool VerifyRecoveryActionVector(::flatbuffers::VerifierTemplate &verifier, const ::flatbuffers::Vector<::flatbuffers::Offset> *values, const ::flatbuffers::Vector *types); struct ComponentAliveSupervision FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { typedef ComponentAliveSupervisionBuilder Builder; @@ -197,7 +199,8 @@ struct ComponentAliveSupervision FLATBUFFERS_FINAL_CLASS : private ::flatbuffers ::flatbuffers::Optional max_indications() const { return GetOptional(VT_MAX_INDICATIONS); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_REPORTING_CYCLE, 8) && VerifyField(verifier, VT_FAILED_CYCLES_TOLERANCE, 4) && @@ -264,7 +267,8 @@ struct ApplicationProfile FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table const score::launch_manager::config::fb::ComponentAliveSupervision *alive_supervision() const { return GetPointer(VT_ALIVE_SUPERVISION); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_APPLICATION_TYPE, 1) && VerifyField(verifier, VT_IS_SELF_TERMINATING, 1) && @@ -318,7 +322,8 @@ struct ReadyCondition FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { ::flatbuffers::Optional process_state() const { return GetOptional(VT_PROCESS_STATE); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_PROCESS_STATE, 1) && verifier.EndTable(); @@ -375,7 +380,8 @@ struct ComponentProperties FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Tabl const score::launch_manager::config::fb::ReadyCondition *ready_condition() const { return GetPointer(VT_READY_CONDITION); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyOffsetRequired(verifier, VT_BINARY_NAME) && verifier.VerifyString(binary_name()) && @@ -473,7 +479,8 @@ struct RestartAction FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { double delay_before_restart() const { return GetField(VT_DELAY_BEFORE_RESTART, 0.0); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_NUMBER_OF_ATTEMPTS, 4) && VerifyField(verifier, VT_DELAY_BEFORE_RESTART, 8) && @@ -520,7 +527,8 @@ struct SwitchRunTargetAction FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Ta const ::flatbuffers::String *run_target() const { return GetPointer(VT_RUN_TARGET); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyOffsetRequired(verifier, VT_RUN_TARGET) && verifier.VerifyString(run_target()) && @@ -576,7 +584,8 @@ struct EnvironmentalVariable FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Ta const ::flatbuffers::String *value() const { return GetPointer(VT_VALUE); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyOffsetRequired(verifier, VT_KEY) && verifier.VerifyString(key()) && @@ -667,7 +676,8 @@ struct Sandbox FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { ::flatbuffers::Optional max_cpu_usage() const { return GetOptional(VT_MAX_CPU_USAGE); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_UID, 4) && VerifyField(verifier, VT_GID, 4) && @@ -828,7 +838,8 @@ struct DeploymentConfig FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { const score::launch_manager::config::fb::Sandbox *sandbox() const { return GetPointer(VT_SANDBOX); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_READY_TIMEOUT, 8) && VerifyField(verifier, VT_SHUTDOWN_TIMEOUT, 8) && @@ -1003,7 +1014,8 @@ struct RunTarget FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { const score::launch_manager::config::fb::SwitchRunTargetAction *recovery_action_as_SwitchRunTargetAction() const { return recovery_action_type() == score::launch_manager::config::fb::RecoveryAction_SwitchRunTargetAction ? static_cast(recovery_action()) : nullptr; } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyOffsetRequired(verifier, VT_NAME) && verifier.VerifyString(name()) && @@ -1122,7 +1134,8 @@ struct Component FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { const score::launch_manager::config::fb::DeploymentConfig *deployment_config() const { return GetPointer(VT_DEPLOYMENT_CONFIG); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyOffsetRequired(verifier, VT_NAME) && verifier.VerifyString(name()) && @@ -1204,7 +1217,8 @@ struct AliveSupervision FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { double evaluation_cycle() const { return GetField(VT_EVALUATION_CYCLE, 0.0); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_EVALUATION_CYCLE, 8) && verifier.EndTable(); @@ -1257,7 +1271,8 @@ struct Watchdog FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { ::flatbuffers::Optional require_magic_close() const { return GetOptional(VT_REQUIRE_MAGIC_CLOSE); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyOffsetRequired(verifier, VT_DEVICE_FILE_PATH) && verifier.VerifyString(device_file_path()) && @@ -1341,7 +1356,8 @@ struct FallbackRunTarget FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table double transition_timeout() const { return GetField(VT_TRANSITION_TIMEOUT, 0.0); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_DESCRIPTION) && verifier.VerifyString(description()) && @@ -1435,7 +1451,8 @@ struct LaunchManagerConfig FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Tabl const score::launch_manager::config::fb::Watchdog *watchdog() const { return GetPointer(VT_WATCHDOG); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_SCHEMA_VERSION, 4) && VerifyOffset(verifier, VT_COMPONENTS) && @@ -1538,7 +1555,8 @@ inline ::flatbuffers::Offset CreateLaunchManagerConfigDirec watchdog); } -inline bool VerifyRecoveryAction(::flatbuffers::Verifier &verifier, const void *obj, RecoveryAction type) { +template +inline bool VerifyRecoveryAction(::flatbuffers::VerifierTemplate &verifier, const void *obj, RecoveryAction type) { switch (type) { case RecoveryAction_NONE: { return true; @@ -1555,7 +1573,8 @@ inline bool VerifyRecoveryAction(::flatbuffers::Verifier &verifier, const void * } } -inline bool VerifyRecoveryActionVector(::flatbuffers::Verifier &verifier, const ::flatbuffers::Vector<::flatbuffers::Offset> *values, const ::flatbuffers::Vector *types) { +template +inline bool VerifyRecoveryActionVector(::flatbuffers::VerifierTemplate &verifier, const ::flatbuffers::Vector<::flatbuffers::Offset> *values, const ::flatbuffers::Vector *types) { if (!values || !types) return !values && !types; if (values->size() != types->size()) return false; for (::flatbuffers::uoffset_t i = 0; i < values->size(); ++i) { @@ -1575,14 +1594,16 @@ inline const score::launch_manager::config::fb::LaunchManagerConfig *GetSizePref return ::flatbuffers::GetSizePrefixedRoot(buf); } +template inline bool VerifyLaunchManagerConfigBuffer( - ::flatbuffers::Verifier &verifier) { - return verifier.VerifyBuffer(nullptr); + ::flatbuffers::VerifierTemplate &verifier) { + return verifier.template VerifyBuffer(nullptr); } +template inline bool VerifySizePrefixedLaunchManagerConfigBuffer( - ::flatbuffers::Verifier &verifier) { - return verifier.VerifySizePrefixedBuffer(nullptr); + ::flatbuffers::VerifierTemplate &verifier) { + return verifier.template VerifySizePrefixedBuffer(nullptr); } inline void FinishLaunchManagerConfigBuffer( diff --git a/src/launch_manager_daemon/health_monitor_lib/config/hm_flatcfg_generated.h b/src/launch_manager_daemon/health_monitor_lib/config/hm_flatcfg_generated.h index fab01f69b..11c90e45b 100644 --- a/src/launch_manager_daemon/health_monitor_lib/config/hm_flatcfg_generated.h +++ b/src/launch_manager_daemon/health_monitor_lib/config/hm_flatcfg_generated.h @@ -1,15 +1,3 @@ -/******************************************************************************** - * Copyright (c) 2026 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0 - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ // automatically generated by the FlatBuffers compiler, do not modify @@ -21,8 +9,8 @@ // Ensure the included flatbuffers.h is the same version as when this file was // generated, otherwise it may not be compatible. static_assert(FLATBUFFERS_VERSION_MAJOR == 25 && - FLATBUFFERS_VERSION_MINOR == 9 && - FLATBUFFERS_VERSION_REVISION == 23, + FLATBUFFERS_VERSION_MINOR == 12 && + FLATBUFFERS_VERSION_REVISION == 19, "Non-compatible flatbuffers version included"); namespace HMFlatBuffer { @@ -145,7 +133,8 @@ struct HMEcuCfg FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { const ::flatbuffers::Vector<::flatbuffers::Offset> *hmRecoveryNotification() const { return GetPointer> *>(VT_HMRECOVERYNOTIFICATION); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_VERSIONMAJOR, 4) && VerifyField(verifier, VT_VERSIONMINOR, 4) && @@ -299,7 +288,8 @@ struct Process FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { const ::flatbuffers::Vector<::flatbuffers::Offset> *processExecutionErrors() const { return GetPointer> *>(VT_PROCESSEXECUTIONERRORS); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_SHORTNAME) && verifier.VerifyString(shortName()) && @@ -398,7 +388,8 @@ struct HmProcessExecutionError FLATBUFFERS_FINAL_CLASS : private ::flatbuffers:: uint32_t processExecutionError() const { return GetField(VT_PROCESSEXECUTIONERROR, 0); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_PROCESSEXECUTIONERROR, 4) && verifier.EndTable(); @@ -439,7 +430,8 @@ struct HmRefProcessGroupStates FLATBUFFERS_FINAL_CLASS : private ::flatbuffers:: const ::flatbuffers::String *identifier() const { return GetPointer(VT_IDENTIFIER); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_IDENTIFIER) && verifier.VerifyString(identifier()) && @@ -490,7 +482,8 @@ struct HmRefProcess FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { uint32_t index() const { return GetField(VT_INDEX, 0); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_INDEX, 4) && verifier.EndTable(); @@ -551,7 +544,8 @@ struct HmMonitorInterface FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table int32_t permittedUid() const { return GetField(VT_PERMITTEDUID, 0); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_INSTANCESPECIFIER) && verifier.VerifyString(instanceSpecifier()) && @@ -656,7 +650,8 @@ struct HmSupervisionCheckpoint FLATBUFFERS_FINAL_CLASS : private ::flatbuffers:: uint32_t refInterfaceIndex() const { return GetField(VT_REFINTERFACEINDEX, 0); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_SHORTNAME) && verifier.VerifyString(shortName()) && @@ -735,7 +730,8 @@ struct HmCheckpointTransition FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::T const HMFlatBuffer::HmSupervisionCheckpoint *infoTarget() const { return GetPointer(VT_INFOTARGET); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_REFSOURCECPINDEX, 4) && VerifyField(verifier, VT_REFTARGETCPINDEX, 4) && @@ -832,7 +828,8 @@ struct HmAliveSupervision FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table const ::flatbuffers::Vector<::flatbuffers::Offset> *refProcessGroupStates() const { return GetPointer> *>(VT_REFPROCESSGROUPSTATES); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_RULECONTEXTKEY) && verifier.VerifyString(ruleContextKey()) && @@ -966,7 +963,8 @@ struct HmLocalSupervision FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table const ::flatbuffers::Vector<::flatbuffers::Offset> *hmRefAliveSupervision() const { return GetPointer> *>(VT_HMREFALIVESUPERVISION); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_RULECONTEXTKEY) && verifier.VerifyString(ruleContextKey()) && @@ -1042,7 +1040,8 @@ struct HmRefAliveSupervision FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Ta uint32_t refAliveSupervisionIdx() const { return GetField(VT_REFALIVESUPERVISIONIDX, 0); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_RULECONTEXTKEY, 4) && VerifyField(verifier, VT_REFALIVESUPERVISIONIDX, 4) && @@ -1105,7 +1104,8 @@ struct HmGlobalSupervision FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Tabl const ::flatbuffers::Vector<::flatbuffers::Offset> *refProcessGroupStates() const { return GetPointer> *>(VT_REFPROCESSGROUPSTATES); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_RULECONTEXTKEY) && verifier.VerifyString(ruleContextKey()) && @@ -1197,7 +1197,8 @@ struct HmGlobalSupervisionLocalRef FLATBUFFERS_FINAL_CLASS : private ::flatbuffe uint32_t refLocalSupervisionIndex() const { return GetField(VT_REFLOCALSUPERVISIONINDEX, 0); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_REFLOCALSUPERVISIONINDEX, 4) && verifier.EndTable(); @@ -1242,7 +1243,8 @@ struct HmRefProcessGroupStatesGlobal FLATBUFFERS_FINAL_CLASS : private ::flatbuf double expiredSupervisionTolerance() const { return GetField(VT_EXPIREDSUPERVISIONTOLERANCE, 0.0); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_IDENTIFIER) && verifier.VerifyString(identifier()) && @@ -1313,7 +1315,8 @@ struct RecoveryNotification FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Tab bool shouldFireWatchdog() const { return GetField(VT_SHOULDFIREWATCHDOG, 0) != 0; } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyOffsetRequired(verifier, VT_SHORTNAME) && verifier.VerifyString(shortName()) && @@ -1405,14 +1408,16 @@ inline bool SizePrefixedHMEcuCfgBufferHasIdentifier(const void *buf) { buf, HMEcuCfgIdentifier(), true); } +template inline bool VerifyHMEcuCfgBuffer( - ::flatbuffers::Verifier &verifier) { - return verifier.VerifyBuffer(HMEcuCfgIdentifier()); + ::flatbuffers::VerifierTemplate &verifier) { + return verifier.template VerifyBuffer(HMEcuCfgIdentifier()); } +template inline bool VerifySizePrefixedHMEcuCfgBuffer( - ::flatbuffers::Verifier &verifier) { - return verifier.VerifySizePrefixedBuffer(HMEcuCfgIdentifier()); + ::flatbuffers::VerifierTemplate &verifier) { + return verifier.template VerifySizePrefixedBuffer(HMEcuCfgIdentifier()); } inline const char *HMEcuCfgExtension() { diff --git a/src/launch_manager_daemon/health_monitor_lib/config/hmcore_flatcfg_generated.h b/src/launch_manager_daemon/health_monitor_lib/config/hmcore_flatcfg_generated.h index 4d3fb96d6..b4fa6ed72 100644 --- a/src/launch_manager_daemon/health_monitor_lib/config/hmcore_flatcfg_generated.h +++ b/src/launch_manager_daemon/health_monitor_lib/config/hmcore_flatcfg_generated.h @@ -1,15 +1,3 @@ -/******************************************************************************** - * Copyright (c) 2026 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0 - * - * SPDX-License-Identifier: Apache-2.0 - ********************************************************************************/ // automatically generated by the FlatBuffers compiler, do not modify @@ -21,8 +9,8 @@ // Ensure the included flatbuffers.h is the same version as when this file was // generated, otherwise it may not be compatible. static_assert(FLATBUFFERS_VERSION_MAJOR == 25 && - FLATBUFFERS_VERSION_MINOR == 9 && - FLATBUFFERS_VERSION_REVISION == 23, + FLATBUFFERS_VERSION_MINOR == 12 && + FLATBUFFERS_VERSION_REVISION == 19, "Non-compatible flatbuffers version included"); namespace HMCOREFlatBuffer { @@ -56,7 +44,8 @@ struct HMCOREEcuCfg FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { const ::flatbuffers::Vector<::flatbuffers::Offset> *config() const { return GetPointer> *>(VT_CONFIG); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_VERSIONMAJOR, 4) && VerifyField(verifier, VT_VERSIONMINOR, 4) && @@ -159,7 +148,8 @@ struct Watchdog FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { bool hasValueRequireMagicClose() const { return GetField(VT_HASVALUEREQUIREMAGICCLOSE, 0) != 0; } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_SHORTNAME) && verifier.VerifyString(shortName()) && @@ -276,7 +266,8 @@ struct HmConfig FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { uint16_t bufferSizeGlobalSupervision() const { return GetField(VT_BUFFERSIZEGLOBALSUPERVISION, 0); } - bool Verify(::flatbuffers::Verifier &verifier) const { + template + bool Verify(::flatbuffers::VerifierTemplate &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_PERIODICITY, 4) && VerifyField(verifier, VT_BUFFERSIZEMONITOR, 2) && @@ -355,14 +346,16 @@ inline bool SizePrefixedHMCOREEcuCfgBufferHasIdentifier(const void *buf) { buf, HMCOREEcuCfgIdentifier(), true); } +template inline bool VerifyHMCOREEcuCfgBuffer( - ::flatbuffers::Verifier &verifier) { - return verifier.VerifyBuffer(HMCOREEcuCfgIdentifier()); + ::flatbuffers::VerifierTemplate &verifier) { + return verifier.template VerifyBuffer(HMCOREEcuCfgIdentifier()); } +template inline bool VerifySizePrefixedHMCOREEcuCfgBuffer( - ::flatbuffers::Verifier &verifier) { - return verifier.VerifySizePrefixedBuffer(HMCOREEcuCfgIdentifier()); + ::flatbuffers::VerifierTemplate &verifier) { + return verifier.template VerifySizePrefixedBuffer(HMCOREEcuCfgIdentifier()); } inline const char *HMCOREEcuCfgExtension() { From 2325ae754829fb155723539681b7564be26f8cac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Fu=C3=9Fberger?= Date: Mon, 18 May 2026 16:26:35 +0200 Subject: [PATCH 03/26] Use baselibs flatbuffer helper --- src/launch_manager_daemon/config/BUILD | 8 +- .../include/flatbuffer_config_loader.hpp | 31 ++- .../config/src/flatbuffer_config_loader.cpp | 131 +--------- .../src/flatbuffer_config_loader_UT.cpp | 240 +++--------------- 4 files changed, 80 insertions(+), 330 deletions(-) diff --git a/src/launch_manager_daemon/config/BUILD b/src/launch_manager_daemon/config/BUILD index e64f9383f..42c1d72d9 100644 --- a/src/launch_manager_daemon/config/BUILD +++ b/src/launch_manager_daemon/config/BUILD @@ -56,9 +56,7 @@ cc_library( deps = [ ":config_loader", "@flatbuffers", - "@score_baselibs//score/os:fcntl", - "@score_baselibs//score/os:stat", - "@score_baselibs//score/os:unistd", + "@score_baselibs//score/flatbuffers:flatbufferutils", ], ) @@ -70,10 +68,6 @@ cc_test( ":flatbuffer_config_loader", "@flatbuffers", "@googletest//:gtest_main", - "@score_baselibs//score/os:object_seam", - "@score_baselibs//score/os/mocklib:fcntl_mock", - "@score_baselibs//score/os/mocklib:stat_mock", - "@score_baselibs//score/os/mocklib:unistd_mock", ], ) diff --git a/src/launch_manager_daemon/config/include/flatbuffer_config_loader.hpp b/src/launch_manager_daemon/config/include/flatbuffer_config_loader.hpp index b528dd117..8a38f40e6 100644 --- a/src/launch_manager_daemon/config/include/flatbuffer_config_loader.hpp +++ b/src/launch_manager_daemon/config/include/flatbuffer_config_loader.hpp @@ -16,18 +16,39 @@ #include "config_loader.hpp" +#include "score/flatbuffers/load_buffer.hpp" + #include #include namespace score::launch_manager::config { +namespace details { + +score::cpp::expected parseFlatbuffer(const std::vector& buffer); +IConfigLoader::Error mapOsError(const score::os::Error& error); + +} // namespace details + +struct DefaultBufferLoader { + static score::os::Result> load(const score::filesystem::Path& path) + { + return score::flatbuffers::LoadBuffer(path); + } +}; + +template class FlatbufferConfigLoader : public IConfigLoader { public: - score::cpp::expected load(const score::filesystem::Path& path) override; - - private: - score::cpp::expected, Error> readFile(const score::filesystem::Path& path); - score::cpp::expected parseBuffer(const std::vector& buffer); + score::cpp::expected load(const score::filesystem::Path& path) override + { + auto buffer_result = BufferLoaderT::load(path); + if (!buffer_result.has_value()) + { + return score::cpp::make_unexpected(details::mapOsError(buffer_result.error())); + } + return details::parseFlatbuffer(buffer_result.value()); + } }; } // namespace score::launch_manager::config diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp index 5ca87db25..54731f85c 100644 --- a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp @@ -15,15 +15,8 @@ #include "new_lm_flatcfg_generated.h" #include "score/os/errno.h" -#include "score/os/fcntl.h" -#include "score/os/stat.h" -#include "score/os/unistd.h" -#include -#include #include -#include -#include #include #include #include @@ -316,6 +309,10 @@ std::optional convertWatchdog(const fb::Watchdog* fb_wd) return result; } +} // anonymous namespace + +namespace details { + // --- File I/O error mapping --- IConfigLoader::Error mapOsError(const score::os::Error& error) @@ -331,112 +328,9 @@ IConfigLoader::Error mapOsError(const score::os::Error& error) return IConfigLoader::Error::GeneralError; } -} // anonymous namespace - -// --- Public interface --- - -score::cpp::expected FlatbufferConfigLoader::load(const score::filesystem::Path& path) -{ - auto buffer_result = readFile(path); - if (!buffer_result.has_value()) - { - return score::cpp::make_unexpected(buffer_result.error()); - } - return parseBuffer(buffer_result.value()); -} - -// --- File loading using OS abstractions --- - -score::cpp::expected, IConfigLoader::Error> FlatbufferConfigLoader::readFile( - const score::filesystem::Path& path) -{ - auto& fcntl = score::os::Fcntl::instance(); - auto& stat = score::os::Stat::instance(); - auto& unistd = score::os::Unistd::instance(); - - const auto fd_result = fcntl.open(path.CStr(), score::os::Fcntl::Open::kReadOnly); - if (!fd_result.has_value()) - { - return score::cpp::make_unexpected(mapOsError(fd_result.error())); - } - const std::int32_t file_desc = fd_result.value(); - - auto close_fd = [&unistd, file_desc](const IConfigLoader::Error* prior_error) - -> score::cpp::expected, IConfigLoader::Error> { - unistd.close(file_desc); - if (prior_error != nullptr) - { - return score::cpp::make_unexpected(*prior_error); - } - return score::cpp::make_unexpected(IConfigLoader::Error::GeneralError); - }; - - score::os::StatBuffer stat_buf{}; - const auto stat_result = stat.fstat(file_desc, stat_buf); - if (!stat_result.has_value()) - { - auto err = IConfigLoader::Error::GeneralError; - return close_fd(&err); - } - - if (stat_buf.st_size <= 0) - { - auto err = IConfigLoader::Error::InvalidFormat; - return close_fd(&err); - } - - const auto file_size = static_cast(stat_buf.st_size); - std::vector buffer; - try - { - buffer.resize(file_size); - } - catch (const std::bad_alloc&) - { - auto err = IConfigLoader::Error::GeneralError; - return close_fd(&err); - } - - std::size_t total_bytes_read = 0U; - while (total_bytes_read < file_size) - { - const auto read_result = unistd.read( - file_desc, - std::next(buffer.data(), static_cast(total_bytes_read)), - file_size - total_bytes_read); - if (!read_result.has_value()) - { - if (read_result.error() == score::os::Error::Code::kOperationWasInterruptedBySignal) - { - continue; - } - auto err = IConfigLoader::Error::GeneralError; - return close_fd(&err); - } - - const auto bytes_read = read_result.value(); - if (bytes_read == 0) - { - auto err = IConfigLoader::Error::GeneralError; - return close_fd(&err); - } - - total_bytes_read += static_cast(bytes_read); - } - - const auto close_result = unistd.close(file_desc); - if (!close_result.has_value()) - { - return score::cpp::make_unexpected(IConfigLoader::Error::GeneralError); - } - - return buffer; -} - // --- FlatBuffer parsing and conversion --- -score::cpp::expected FlatbufferConfigLoader::parseBuffer( - const std::vector& buffer) +score::cpp::expected parseFlatbuffer(const std::vector& buffer) { ::flatbuffers::Verifier verifier(buffer.data(), buffer.size()); if (!fb::VerifyLaunchManagerConfigBuffer(verifier)) @@ -455,12 +349,9 @@ score::cpp::expected FlatbufferConfigLoader::parse return score::cpp::make_unexpected(IConfigLoader::Error::UnsupportedVersion); } - if (config->initial_run_target() == nullptr) - { - return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); - } - Config::Builder builder; + + // initial_run_target is a required field, guaranteed non-null by the schema and verifier. builder.setInitialRunTarget(config->initial_run_target()->str()); if (config->components() != nullptr) @@ -491,11 +382,10 @@ score::cpp::expected FlatbufferConfigLoader::parse builder.setRunTargets(std::move(run_targets)); } - if (config->fallback_run_target() != nullptr) - { - builder.setFallbackRunTarget(convertFallbackRunTarget(config->fallback_run_target())); - } + // fallback_run_target is a required field, guaranteed non-null by the schema and verifier. + builder.setFallbackRunTarget(convertFallbackRunTarget(config->fallback_run_target())); + // alive_supervision is a required field, guaranteed non-null by the schema and verifier. auto alive_sup = convertAliveSupervision(config->alive_supervision()); if (alive_sup.has_value()) { @@ -511,4 +401,5 @@ score::cpp::expected FlatbufferConfigLoader::parse return builder.build(); } +} // namespace details } // namespace score::launch_manager::config diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp index 9871fafb5..76e92e94f 100644 --- a/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp @@ -15,16 +15,13 @@ #include "new_lm_flatcfg_generated.h" #include "score/filesystem/path.h" -#include "score/os/ObjectSeam.h" -#include "score/os/mocklib/fcntl_mock.h" -#include "score/os/mocklib/stat_mock.h" -#include "score/os/mocklib/unistdmock.h" +#include "score/os/errno.h" #include #include +#include #include -#include #include namespace score::launch_manager::config { @@ -32,16 +29,10 @@ namespace { namespace fb = score::launch_manager::config::fb; -using ::testing::_; -using ::testing::DoAll; using ::testing::Eq; -using ::testing::Invoke; using ::testing::IsFalse; using ::testing::IsTrue; -using ::testing::NiceMock; -using ::testing::Return; -constexpr std::int32_t kTestFd = 42; const score::filesystem::Path kTestPath{"/tmp/test_config.bin"}; std::vector finishBuffer(::flatbuffers::FlatBufferBuilder& fbb, @@ -52,38 +43,23 @@ std::vector finishBuffer(::flatbuffers::FlatBufferBuilder& fbb, return {buf, buf + fbb.GetSize()}; } +struct MockBufferLoader { + static score::os::Result> load(const score::filesystem::Path&) + { + return result_; + } + static score::os::Result> result_; +}; + +score::os::Result> MockBufferLoader::result_{std::vector{}}; + class FlatbufferConfigLoaderTest : public ::testing::Test { protected: void SetUp() override { RecordProperty("TestType", "interface-test"); RecordProperty("DerivationTechnique", "explorative-testing "); - } - - void setUpSuccessfulFileRead(const std::vector& content) - { - ON_CALL(*fcntl_mock_, open(_, _)) - .WillByDefault(Return(score::cpp::expected{kTestFd})); - - ON_CALL(*stat_mock_, fstat(kTestFd, _)) - .WillByDefault( - DoAll(Invoke([size = static_cast(content.size())](std::int32_t, - score::os::StatBuffer& buf) { - buf.st_size = size; - }), - Return(score::cpp::expected_blank{}))); - - ON_CALL(*unistd_mock_, read(kTestFd, _, _)) - .WillByDefault( - Invoke([&content](std::int32_t, void* buf, std::size_t count) - -> score::cpp::expected { - const auto bytes = std::min(count, content.size()); - std::memcpy(buf, content.data(), bytes); - return static_cast(bytes); - })); - - ON_CALL(*unistd_mock_, close(kTestFd)) - .WillByDefault(Return(score::cpp::expected_blank{})); + MockBufferLoader::result_ = std::vector{}; } std::vector buildMinimalConfig(int32_t schema_version = 1, @@ -98,10 +74,7 @@ class FlatbufferConfigLoaderTest : public ::testing::Test { return finishBuffer(fbb, config); } - score::os::MockGuard> fcntl_mock_; - score::os::MockGuard> stat_mock_; - score::os::MockGuard> unistd_mock_; - FlatbufferConfigLoader loader_; + FlatbufferConfigLoader loader_; }; // ============================================================================ @@ -114,7 +87,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadMinimalConfig) // GIVEN auto buffer = buildMinimalConfig(1, "Startup"); - setUpSuccessfulFileRead(buffer); + MockBufferLoader::result_ = buffer; // WHEN auto result = loader_.load(kTestPath); @@ -164,7 +137,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadSingleComponent) auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, comps, 0 /*run_targets*/, irt, fallback, global_alive_sup); auto buffer = finishBuffer(fbb, config); - setUpSuccessfulFileRead(buffer); + MockBufferLoader::result_ = buffer; // WHEN auto result = loader_.load(kTestPath); @@ -218,7 +191,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadRunTargets) auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, 0 /*components*/, rts, irt, fallback, alive_sup); auto buffer = finishBuffer(fbb, config); - setUpSuccessfulFileRead(buffer); + MockBufferLoader::result_ = buffer; // WHEN auto result = loader_.load(kTestPath); @@ -255,7 +228,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadFallbackRunTarget) auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, 0 /*components*/, 0 /*run_targets*/, irt, fallback, alive_sup); auto buffer = finishBuffer(fbb, config); - setUpSuccessfulFileRead(buffer); + MockBufferLoader::result_ = buffer; // WHEN auto result = loader_.load(kTestPath); @@ -285,7 +258,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadAliveSupervision) auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, 0 /*components*/, 0 /*run_targets*/, irt, fallback, alive_sup); auto buffer = finishBuffer(fbb, config); - setUpSuccessfulFileRead(buffer); + MockBufferLoader::result_ = buffer; // WHEN auto result = loader_.load(kTestPath); @@ -313,7 +286,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadWatchdog) auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, 0 /*components*/, 0 /*run_targets*/, irt, fallback, alive_sup, watchdog); auto buffer = finishBuffer(fbb, config); - setUpSuccessfulFileRead(buffer); + MockBufferLoader::result_ = buffer; // WHEN auto result = loader_.load(kTestPath); @@ -349,7 +322,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadRestartRecoveryAction) auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, 0 /*components*/, rts, irt, fallback, alive_sup); auto buffer = finishBuffer(fbb, config); - setUpSuccessfulFileRead(buffer); + MockBufferLoader::result_ = buffer; // WHEN auto result = loader_.load(kTestPath); @@ -388,7 +361,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadSwitchRunTargetAction) auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, 0 /*components*/, rts, irt, fallback, alive_sup); auto buffer = finishBuffer(fbb, config); - setUpSuccessfulFileRead(buffer); + MockBufferLoader::result_ = buffer; // WHEN auto result = loader_.load(kTestPath); @@ -439,7 +412,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadSandbox) auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, comps, 0 /*run_targets*/, irt, fallback, alive_sup); auto buffer = finishBuffer(fbb, config); - setUpSuccessfulFileRead(buffer); + MockBufferLoader::result_ = buffer; // WHEN auto result = loader_.load(kTestPath); @@ -493,7 +466,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadComponentAliveSupervision) auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, comps, 0 /*run_targets*/, irt, fallback, alive_sup); auto buffer = finishBuffer(fbb, config); - setUpSuccessfulFileRead(buffer); + MockBufferLoader::result_ = buffer; // WHEN auto result = loader_.load(kTestPath); @@ -544,7 +517,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadEnvironmentalVariables) auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, comps, 0 /*run_targets*/, irt, fallback, alive_sup); auto buffer = finishBuffer(fbb, config); - setUpSuccessfulFileRead(buffer); + MockBufferLoader::result_ = buffer; // WHEN auto result = loader_.load(kTestPath); @@ -589,7 +562,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadMultipleComponents) auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, comps, 0 /*run_targets*/, irt, fallback, alive_sup); auto buffer = finishBuffer(fbb, config); - setUpSuccessfulFileRead(buffer); + MockBufferLoader::result_ = buffer; // WHEN auto result = loader_.load(kTestPath); @@ -606,55 +579,13 @@ TEST_F(FlatbufferConfigLoaderTest, LoadMultipleComponents) // Optional / required field tests // ============================================================================ -TEST_F(FlatbufferConfigLoaderTest, MissingRequiredFallbackReturnsInvalidFormat) -{ - RecordProperty("Description", "When the required fallback_run_target is absent, returns InvalidFormat."); - - // GIVEN - ::flatbuffers::FlatBufferBuilder fbb; - auto irt = fbb.CreateString("Startup"); - auto alive_sup = fb::CreateAliveSupervision(fbb); - auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, 0 /*components*/, 0 /*run_targets*/, irt, - 0 /*fallback_run_target*/, alive_sup); - auto buffer = finishBuffer(fbb, config); - setUpSuccessfulFileRead(buffer); - - // WHEN - auto result = loader_.load(kTestPath); - - // THEN - ASSERT_THAT(result.has_value(), IsFalse()); - EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); -} - -TEST_F(FlatbufferConfigLoaderTest, MissingRequiredAliveSupervisionReturnsInvalidFormat) -{ - RecordProperty("Description", "When the required alive_supervision is absent, returns InvalidFormat."); - - // GIVEN - ::flatbuffers::FlatBufferBuilder fbb; - auto irt = fbb.CreateString("Startup"); - auto fallback = fb::CreateFallbackRunTarget(fbb); - auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, 0 /*components*/, 0 /*run_targets*/, irt, - fallback, 0 /*alive_supervision*/); - auto buffer = finishBuffer(fbb, config); - setUpSuccessfulFileRead(buffer); - - // WHEN - auto result = loader_.load(kTestPath); - - // THEN - ASSERT_THAT(result.has_value(), IsFalse()); - EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); -} - TEST_F(FlatbufferConfigLoaderTest, OptionalWatchdogAbsent) { RecordProperty("Description", "When no watchdog is present, it is nullopt."); // GIVEN auto buffer = buildMinimalConfig(); - setUpSuccessfulFileRead(buffer); + MockBufferLoader::result_ = buffer; // WHEN auto result = loader_.load(kTestPath); @@ -692,7 +623,7 @@ TEST_F(FlatbufferConfigLoaderTest, OptionalSandboxAbsent) auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, comps, 0 /*run_targets*/, irt, fallback, alive_sup); auto buffer = finishBuffer(fbb, config); - setUpSuccessfulFileRead(buffer); + MockBufferLoader::result_ = buffer; // WHEN auto result = loader_.load(kTestPath); @@ -702,33 +633,6 @@ TEST_F(FlatbufferConfigLoaderTest, OptionalSandboxAbsent) EXPECT_THAT(result->components()[0].deployment_config.sandbox.has_value(), IsFalse()); } -TEST_F(FlatbufferConfigLoaderTest, MissingRequiredRecoveryActionReturnsInvalidFormat) -{ - RecordProperty("Description", "When the required recovery_action is absent on a RunTarget, returns InvalidFormat."); - - // GIVEN - ::flatbuffers::FlatBufferBuilder fbb; - - auto rt_name = fbb.CreateString("Startup"); - auto rt = fb::CreateRunTarget(fbb, rt_name); - auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{rt}); - - auto fallback = fb::CreateFallbackRunTarget(fbb); - auto alive_sup = fb::CreateAliveSupervision(fbb); - auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, - 1 /*schema_version*/, 0 /*components*/, rts, irt, fallback, alive_sup); - auto buffer = finishBuffer(fbb, config); - setUpSuccessfulFileRead(buffer); - - // WHEN - auto result = loader_.load(kTestPath); - - // THEN - ASSERT_THAT(result.has_value(), IsFalse()); - EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); -} - // ============================================================================ // Enum mapping tests // ============================================================================ @@ -758,7 +662,7 @@ TEST_F(FlatbufferConfigLoaderTest, MapNativeApplicationType) auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, comps, 0 /*run_targets*/, irt, fallback, alive_sup); auto buffer = finishBuffer(fbb, config); - setUpSuccessfulFileRead(buffer); + MockBufferLoader::result_ = buffer; // WHEN auto result = loader_.load(kTestPath); @@ -795,7 +699,7 @@ TEST_F(FlatbufferConfigLoaderTest, MapReportingAndSupervisedType) auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, comps, 0 /*run_targets*/, irt, fallback, alive_sup); auto buffer = finishBuffer(fbb, config); - setUpSuccessfulFileRead(buffer); + MockBufferLoader::result_ = buffer; // WHEN auto result = loader_.load(kTestPath); @@ -831,7 +735,7 @@ TEST_F(FlatbufferConfigLoaderTest, MapTerminatedProcessState) auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, comps, 0 /*run_targets*/, irt, fallback, alive_sup); auto buffer = finishBuffer(fbb, config); - setUpSuccessfulFileRead(buffer); + MockBufferLoader::result_ = buffer; // WHEN auto result = loader_.load(kTestPath); @@ -846,14 +750,12 @@ TEST_F(FlatbufferConfigLoaderTest, MapTerminatedProcessState) // Error path tests // ============================================================================ -TEST_F(FlatbufferConfigLoaderTest, FileOpenFailsReturnsFileNotFound) +TEST_F(FlatbufferConfigLoaderTest, LoadBufferFailsWithNoSuchFileReturnsFileNotFound) { - RecordProperty("Description", "When file open fails with ENOENT, returns FileNotFound error."); + RecordProperty("Description", "When LoadBuffer fails with ENOENT, returns FileNotFound error."); // GIVEN - const auto open_error = score::os::Error::createFromErrno(ENOENT); - EXPECT_CALL(*fcntl_mock_, open(_, _)) - .WillOnce(Return(score::cpp::make_unexpected(open_error))); + MockBufferLoader::result_ = score::cpp::make_unexpected(score::os::Error::createFromErrno(ENOENT)); // WHEN auto result = loader_.load(kTestPath); @@ -863,14 +765,12 @@ TEST_F(FlatbufferConfigLoaderTest, FileOpenFailsReturnsFileNotFound) EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::FileNotFound)); } -TEST_F(FlatbufferConfigLoaderTest, FileOpenFailsWithPermissionDeniedReturnsInsufficientPermission) +TEST_F(FlatbufferConfigLoaderTest, LoadBufferFailsWithPermissionDeniedReturnsInsufficientPermission) { - RecordProperty("Description", "When file open fails with EACCES, returns InsufficientPermission error."); + RecordProperty("Description", "When LoadBuffer fails with EACCES, returns InsufficientPermission error."); // GIVEN - const auto open_error = score::os::Error::createFromErrno(EACCES); - EXPECT_CALL(*fcntl_mock_, open(_, _)) - .WillOnce(Return(score::cpp::make_unexpected(open_error))); + MockBufferLoader::result_ = score::cpp::make_unexpected(score::os::Error::createFromErrno(EACCES)); // WHEN auto result = loader_.load(kTestPath); @@ -880,48 +780,12 @@ TEST_F(FlatbufferConfigLoaderTest, FileOpenFailsWithPermissionDeniedReturnsInsuf EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InsufficientPermission)); } -TEST_F(FlatbufferConfigLoaderTest, FstatFailsReturnsGeneralError) +TEST_F(FlatbufferConfigLoaderTest, LoadBufferFailsWithGenericErrorReturnsGeneralError) { - RecordProperty("Description", "When fstat fails, returns GeneralError."); + RecordProperty("Description", "When LoadBuffer fails with a generic OS error, returns GeneralError."); // GIVEN - ON_CALL(*fcntl_mock_, open(_, _)) - .WillByDefault(Return(score::cpp::expected{kTestFd})); - - const auto stat_error = score::os::Error::createFromErrno(EBADF); - EXPECT_CALL(*stat_mock_, fstat(kTestFd, _)) - .WillOnce(Return(score::cpp::make_unexpected(stat_error))); - - ON_CALL(*unistd_mock_, close(_)) - .WillByDefault(Return(score::cpp::expected_blank{})); - - // WHEN - auto result = loader_.load(kTestPath); - - // THEN - ASSERT_THAT(result.has_value(), IsFalse()); - EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::GeneralError)); -} - -TEST_F(FlatbufferConfigLoaderTest, ReadFailsReturnsGeneralError) -{ - RecordProperty("Description", "When read fails, returns GeneralError."); - - // GIVEN - ON_CALL(*fcntl_mock_, open(_, _)) - .WillByDefault(Return(score::cpp::expected{kTestFd})); - - ON_CALL(*stat_mock_, fstat(kTestFd, _)) - .WillByDefault( - DoAll(Invoke([](std::int32_t, score::os::StatBuffer& buf) { buf.st_size = 100; }), - Return(score::cpp::expected_blank{}))); - - const auto read_error = score::os::Error::createFromErrno(EIO); - EXPECT_CALL(*unistd_mock_, read(kTestFd, _, _)) - .WillOnce(Return(score::cpp::make_unexpected(read_error))); - - ON_CALL(*unistd_mock_, close(_)) - .WillByDefault(Return(score::cpp::expected_blank{})); + MockBufferLoader::result_ = score::cpp::make_unexpected(score::os::Error::createFromErrno(EIO)); // WHEN auto result = loader_.load(kTestPath); @@ -937,27 +801,7 @@ TEST_F(FlatbufferConfigLoaderTest, CorruptedBufferReturnsInvalidFormat) // GIVEN std::vector garbage = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01, 0x02, 0x03}; - setUpSuccessfulFileRead(garbage); - - // WHEN - auto result = loader_.load(kTestPath); - - // THEN - ASSERT_THAT(result.has_value(), IsFalse()); - EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); -} - -TEST_F(FlatbufferConfigLoaderTest, MissingInitialRunTargetReturnsInvalidFormat) -{ - RecordProperty("Description", "A valid FlatBuffer with null initial_run_target returns InvalidFormat."); - - // GIVEN - ::flatbuffers::FlatBufferBuilder fbb; - auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/); - fb::FinishLaunchManagerConfigBuffer(fbb, config); - const auto* buf = fbb.GetBufferPointer(); - std::vector buffer(buf, buf + fbb.GetSize()); - setUpSuccessfulFileRead(buffer); + MockBufferLoader::result_ = garbage; // WHEN auto result = loader_.load(kTestPath); @@ -973,7 +817,7 @@ TEST_F(FlatbufferConfigLoaderTest, WrongSchemaVersionReturnsUnsupportedVersion) // GIVEN auto buffer = buildMinimalConfig(99, "Startup"); - setUpSuccessfulFileRead(buffer); + MockBufferLoader::result_ = buffer; // WHEN auto result = loader_.load(kTestPath); From 509005492afef15c068e4303360c9ac36130c1f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Fu=C3=9Fberger?= Date: Tue, 19 May 2026 07:04:57 +0200 Subject: [PATCH 04/26] Config refactoring --- .../config/include/config.hpp | 2 +- .../config/src/flatbuffer_config_loader.cpp | 12 +- .../src/flatbuffer_config_loader_UT.cpp | 426 ++++++------------ .../config/src/new_lm_flatcfg.fbs | 4 +- .../config/src/new_lm_flatcfg_generated.h | 47 +- 5 files changed, 150 insertions(+), 341 deletions(-) diff --git a/src/launch_manager_daemon/config/include/config.hpp b/src/launch_manager_daemon/config/include/config.hpp index 99ed3b89e..b48cdfe25 100644 --- a/src/launch_manager_daemon/config/include/config.hpp +++ b/src/launch_manager_daemon/config/include/config.hpp @@ -89,7 +89,7 @@ struct DeploymentConfig { std::unordered_map environmental_variables; std::string bin_dir; std::string working_dir; - std::optional ready_recovery_action; + std::optional ready_recovery_action; std::optional recovery_action; std::optional sandbox; }; diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp index 54731f85c..fc692b113 100644 --- a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp @@ -121,6 +121,15 @@ std::unordered_map convertEnvironmentalVariables( // --- Recovery action conversion --- +std::optional convertRestartAction(const fb::RestartAction* ra) +{ + if (ra == nullptr) + { + return std::nullopt; + } + return RestartAction{ra->number_of_attempts(), secondsToMs(ra->delay_before_restart())}; +} + std::optional convertRecoveryAction(fb::RecoveryAction type, const void* action) { switch (type) @@ -239,8 +248,7 @@ DeploymentConfig convertDeploymentConfig(const fb::DeploymentConfig* fb_dc) result.environmental_variables = convertEnvironmentalVariables(fb_dc->environmental_variables()); result.bin_dir = safeString(fb_dc->bin_dir()); result.working_dir = safeString(fb_dc->working_dir()); - result.ready_recovery_action = - convertRecoveryAction(fb_dc->ready_recovery_action_type(), fb_dc->ready_recovery_action()); + result.ready_recovery_action = convertRestartAction(fb_dc->ready_recovery_action()); result.recovery_action = convertRecoveryAction(fb_dc->recovery_action_type(), fb_dc->recovery_action()); result.sandbox = convertSandbox(fb_dc->sandbox()); } diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp index 76e92e94f..735b5ea00 100644 --- a/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp @@ -43,6 +43,66 @@ std::vector finishBuffer(::flatbuffers::FlatBufferBuilder& fbb, return {buf, buf + fbb.GetSize()}; } +// ============================================================================ +// Helper functions to reduce test boilerplate +// ============================================================================ + +::flatbuffers::Offset buildDefaultComponentProperties( + ::flatbuffers::FlatBufferBuilder& fbb) +{ + auto bin_name = fbb.CreateString("default_bin"); + auto app_profile = fb::CreateApplicationProfile(fbb); + auto ready_cond = fb::CreateReadyCondition(fbb); + return fb::CreateComponentProperties(fbb, bin_name, app_profile, 0, 0, ready_cond); +} + +::flatbuffers::Offset buildDefaultDeploymentConfig( + ::flatbuffers::FlatBufferBuilder& fbb) +{ + auto bin_dir = fbb.CreateString("/opt"); + return fb::CreateDeploymentConfig(fbb, 0.0, 0.0, 0, bin_dir); +} + +::flatbuffers::Offset buildDefaultComponent( + ::flatbuffers::FlatBufferBuilder& fbb, + const char* name, + ::flatbuffers::Offset comp_props = 0, + ::flatbuffers::Offset deploy = 0) +{ + if (comp_props.IsNull()) { + comp_props = buildDefaultComponentProperties(fbb); + } + if (deploy.IsNull()) { + deploy = buildDefaultDeploymentConfig(fbb); + } + auto comp_name = fbb.CreateString(name); + return fb::CreateComponent(fbb, comp_name, 0, comp_props, deploy); +} + +std::vector buildConfigWithComponents( + ::flatbuffers::FlatBufferBuilder& fbb, + ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> comps) +{ + auto fallback = fb::CreateFallbackRunTarget(fbb); + auto alive_sup = fb::CreateAliveSupervision(fbb); + auto irt = fbb.CreateString("Startup"); + auto config = fb::CreateLaunchManagerConfig(fbb, 1, comps, 0, irt, fallback, alive_sup); + return finishBuffer(fbb, config); +} + +std::vector buildConfigWithRunTargets( + ::flatbuffers::FlatBufferBuilder& fbb, + ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> rts) +{ + auto fallback = fb::CreateFallbackRunTarget(fbb); + auto alive_sup = fb::CreateAliveSupervision(fbb); + auto irt = fbb.CreateString("Startup"); + auto config = fb::CreateLaunchManagerConfig(fbb, 1, 0, rts, irt, fallback, alive_sup); + return finishBuffer(fbb, config); +} + +// ============================================================================ + struct MockBufferLoader { static score::os::Result> load(const score::filesystem::Path&) { @@ -70,10 +130,16 @@ class FlatbufferConfigLoaderTest : public ::testing::Test { auto fallback = fb::CreateFallbackRunTarget(fbb); auto alive_sup = fb::CreateAliveSupervision(fbb); auto config = fb::CreateLaunchManagerConfig( - fbb, schema_version, 0 /*components*/, 0 /*run_targets*/, irt, fallback, alive_sup); + fbb, schema_version, 0, 0, irt, fallback, alive_sup); return finishBuffer(fbb, config); } + score::cpp::expected loadBuffer(const std::vector& buffer) + { + MockBufferLoader::result_ = buffer; + return loader_.load(kTestPath); + } + FlatbufferConfigLoader loader_; }; @@ -85,14 +151,8 @@ TEST_F(FlatbufferConfigLoaderTest, LoadMinimalConfig) { RecordProperty("Description", "Loads a minimal config with only required fields."); - // GIVEN - auto buffer = buildMinimalConfig(1, "Startup"); - MockBufferLoader::result_ = buffer; + auto result = loadBuffer(buildMinimalConfig(1, "Startup")); - // WHEN - auto result = loader_.load(kTestPath); - - // THEN ASSERT_THAT(result.has_value(), IsTrue()); EXPECT_THAT(result->initial_run_target(), Eq("Startup")); EXPECT_THAT(result->components().empty(), IsTrue()); @@ -106,7 +166,6 @@ TEST_F(FlatbufferConfigLoaderTest, LoadSingleComponent) { RecordProperty("Description", "Loads a config with one fully-populated component."); - // GIVEN ::flatbuffers::FlatBufferBuilder fbb; auto alive_sup = fb::CreateComponentAliveSupervision(fbb, @@ -131,18 +190,8 @@ TEST_F(FlatbufferConfigLoaderTest, LoadSingleComponent) auto component = fb::CreateComponent(fbb, comp_name, comp_desc, comp_props, deploy); auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{component}); - auto fallback = fb::CreateFallbackRunTarget(fbb); - auto global_alive_sup = fb::CreateAliveSupervision(fbb); - auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, - 1 /*schema_version*/, comps, 0 /*run_targets*/, irt, fallback, global_alive_sup); - auto buffer = finishBuffer(fbb, config); - MockBufferLoader::result_ = buffer; + auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); - // WHEN - auto result = loader_.load(kTestPath); - - // THEN ASSERT_THAT(result.has_value(), IsTrue()); ASSERT_THAT(result->components().size(), Eq(1U)); @@ -172,7 +221,6 @@ TEST_F(FlatbufferConfigLoaderTest, LoadRunTargets) { RecordProperty("Description", "Loads run targets with dependencies and transition timeout."); - // GIVEN ::flatbuffers::FlatBufferBuilder fbb; auto switch_target = fbb.CreateString("SafeState"); @@ -185,18 +233,8 @@ TEST_F(FlatbufferConfigLoaderTest, LoadRunTargets) fb::RecoveryAction_SwitchRunTargetAction, switch_action.Union()); auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{rt}); - auto fallback = fb::CreateFallbackRunTarget(fbb); - auto alive_sup = fb::CreateAliveSupervision(fbb); - auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, - 1 /*schema_version*/, 0 /*components*/, rts, irt, fallback, alive_sup); - auto buffer = finishBuffer(fbb, config); - MockBufferLoader::result_ = buffer; + auto result = loadBuffer(buildConfigWithRunTargets(fbb, rts)); - // WHEN - auto result = loader_.load(kTestPath); - - // THEN ASSERT_THAT(result.has_value(), IsTrue()); ASSERT_THAT(result->run_targets().size(), Eq(1U)); @@ -215,7 +253,6 @@ TEST_F(FlatbufferConfigLoaderTest, LoadFallbackRunTarget) { RecordProperty("Description", "Loads fallback run target with all fields."); - // GIVEN ::flatbuffers::FlatBufferBuilder fbb; auto fb_desc = fbb.CreateString("Fallback state"); @@ -225,15 +262,10 @@ TEST_F(FlatbufferConfigLoaderTest, LoadFallbackRunTarget) auto alive_sup = fb::CreateAliveSupervision(fbb); auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, - 1 /*schema_version*/, 0 /*components*/, 0 /*run_targets*/, irt, fallback, alive_sup); - auto buffer = finishBuffer(fbb, config); - MockBufferLoader::result_ = buffer; + auto config = fb::CreateLaunchManagerConfig(fbb, 1, 0, 0, irt, fallback, alive_sup); - // WHEN - auto result = loader_.load(kTestPath); + auto result = loadBuffer(finishBuffer(fbb, config)); - // THEN ASSERT_THAT(result.has_value(), IsTrue()); ASSERT_THAT(result->fallback_run_target().has_value(), IsTrue()); @@ -248,22 +280,15 @@ TEST_F(FlatbufferConfigLoaderTest, LoadAliveSupervision) { RecordProperty("Description", "Loads global alive supervision config."); - // GIVEN ::flatbuffers::FlatBufferBuilder fbb; auto alive_sup = fb::CreateAliveSupervision(fbb, 0.25 /*evaluation_cycle*/); auto fallback = fb::CreateFallbackRunTarget(fbb); - auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, - 1 /*schema_version*/, 0 /*components*/, 0 /*run_targets*/, irt, fallback, alive_sup); - auto buffer = finishBuffer(fbb, config); - MockBufferLoader::result_ = buffer; + auto config = fb::CreateLaunchManagerConfig(fbb, 1, 0, 0, irt, fallback, alive_sup); - // WHEN - auto result = loader_.load(kTestPath); + auto result = loadBuffer(finishBuffer(fbb, config)); - // THEN ASSERT_THAT(result.has_value(), IsTrue()); ASSERT_THAT(result->alive_supervision().has_value(), IsTrue()); EXPECT_THAT(result->alive_supervision()->evaluation_cycle_ms, Eq(250U)); @@ -273,7 +298,6 @@ TEST_F(FlatbufferConfigLoaderTest, LoadWatchdog) { RecordProperty("Description", "Loads watchdog config with all fields."); - // GIVEN ::flatbuffers::FlatBufferBuilder fbb; auto dev_path = fbb.CreateString("/dev/watchdog0"); @@ -283,15 +307,10 @@ TEST_F(FlatbufferConfigLoaderTest, LoadWatchdog) auto fallback = fb::CreateFallbackRunTarget(fbb); auto alive_sup = fb::CreateAliveSupervision(fbb); auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, - 1 /*schema_version*/, 0 /*components*/, 0 /*run_targets*/, irt, fallback, alive_sup, watchdog); - auto buffer = finishBuffer(fbb, config); - MockBufferLoader::result_ = buffer; + auto config = fb::CreateLaunchManagerConfig(fbb, 1, 0, 0, irt, fallback, alive_sup, watchdog); - // WHEN - auto result = loader_.load(kTestPath); + auto result = loadBuffer(finishBuffer(fbb, config)); - // THEN ASSERT_THAT(result.has_value(), IsTrue()); ASSERT_THAT(result->watchdog().has_value(), IsTrue()); @@ -304,38 +323,27 @@ TEST_F(FlatbufferConfigLoaderTest, LoadWatchdog) TEST_F(FlatbufferConfigLoaderTest, LoadRestartRecoveryAction) { - RecordProperty("Description", "Recovery action variant holds RestartAction with correct fields."); + RecordProperty("Description", "Recovery action variant holds RestartAction with correct fields on a component."); - // GIVEN ::flatbuffers::FlatBufferBuilder fbb; auto restart = fb::CreateRestartAction(fbb, 3 /*number_of_attempts*/, 1.5 /*delay_before_restart*/); - auto rt_name = fbb.CreateString("Startup"); - auto rt = fb::CreateRunTarget( - fbb, rt_name, 0 /*description*/, 0 /*depends_on*/, 0.0 /*transition_timeout*/, - fb::RecoveryAction_RestartAction, restart.Union()); - auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{rt}); + auto bin_dir = fbb.CreateString("/opt"); + auto deploy = fb::CreateDeploymentConfig(fbb, + 0.0, 0.0, 0 /*environmental_variables*/, bin_dir, 0 /*working_dir*/, + restart); - auto fallback = fb::CreateFallbackRunTarget(fbb); - auto alive_sup = fb::CreateAliveSupervision(fbb); - auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, - 1 /*schema_version*/, 0 /*components*/, rts, irt, fallback, alive_sup); - auto buffer = finishBuffer(fbb, config); - MockBufferLoader::result_ = buffer; + auto comp = buildDefaultComponent(fbb, "restart_comp", + buildDefaultComponentProperties(fbb), deploy); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); - // WHEN - auto result = loader_.load(kTestPath); + auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); - // THEN ASSERT_THAT(result.has_value(), IsTrue()); - ASSERT_THAT(result->run_targets().size(), Eq(1U)); - ASSERT_THAT(result->run_targets()[0].recovery_action.has_value(), IsTrue()); - - const auto& action = result->run_targets()[0].recovery_action.value(); - ASSERT_THAT(std::holds_alternative(action), IsTrue()); + ASSERT_THAT(result->components().size(), Eq(1U)); + ASSERT_THAT(result->components()[0].deployment_config.ready_recovery_action.has_value(), IsTrue()); - const auto& ra = std::get(action); + const auto& ra = result->components()[0].deployment_config.ready_recovery_action.value(); EXPECT_THAT(ra.number_of_attempts, Eq(3U)); EXPECT_THAT(ra.delay_before_restart_ms, Eq(1500U)); } @@ -344,29 +352,18 @@ TEST_F(FlatbufferConfigLoaderTest, LoadSwitchRunTargetAction) { RecordProperty("Description", "Recovery action variant holds SwitchRunTargetAction."); - // GIVEN ::flatbuffers::FlatBufferBuilder fbb; auto target_name = fbb.CreateString("Fallback"); auto switch_action = fb::CreateSwitchRunTargetAction(fbb, target_name); auto rt_name = fbb.CreateString("Startup"); auto rt = fb::CreateRunTarget( - fbb, rt_name, 0 /*description*/, 0 /*depends_on*/, 0.0 /*transition_timeout*/, + fbb, rt_name, 0, 0, 0.0, fb::RecoveryAction_SwitchRunTargetAction, switch_action.Union()); auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{rt}); - auto fallback = fb::CreateFallbackRunTarget(fbb); - auto alive_sup = fb::CreateAliveSupervision(fbb); - auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, - 1 /*schema_version*/, 0 /*components*/, rts, irt, fallback, alive_sup); - auto buffer = finishBuffer(fbb, config); - MockBufferLoader::result_ = buffer; - - // WHEN - auto result = loader_.load(kTestPath); + auto result = loadBuffer(buildConfigWithRunTargets(fbb, rts)); - // THEN ASSERT_THAT(result.has_value(), IsTrue()); ASSERT_THAT(result->run_targets()[0].recovery_action.has_value(), IsTrue()); @@ -379,7 +376,6 @@ TEST_F(FlatbufferConfigLoaderTest, LoadSandbox) { RecordProperty("Description", "Loads sandbox config including optional fields."); - // GIVEN ::flatbuffers::FlatBufferBuilder fbb; auto sec_policy = fbb.CreateString("strict"); @@ -389,35 +385,19 @@ TEST_F(FlatbufferConfigLoaderTest, LoadSandbox) 1000 /*uid*/, 1000 /*gid*/, supp_gids, sec_policy, sched_policy, 50 /*scheduling_priority*/, 4096 /*max_memory_usage*/, 80 /*max_cpu_usage*/); - auto sb_bin_name = fbb.CreateString("sandboxed_bin"); - auto sb_app_profile = fb::CreateApplicationProfile(fbb); - auto sb_ready_cond = fb::CreateReadyCondition(fbb); - auto sb_comp_props = fb::CreateComponentProperties(fbb, sb_bin_name, sb_app_profile, - 0 /*depends_on*/, 0 /*process_arguments*/, sb_ready_cond); - auto bin_dir = fbb.CreateString("/opt"); auto work_dir = fbb.CreateString("/tmp"); auto deploy = fb::CreateDeploymentConfig(fbb, - 0.5 /*ready_timeout*/, 0.5 /*shutdown_timeout*/, 0 /*environmental_variables*/, bin_dir, work_dir, - fb::RecoveryAction_NONE, 0 /*ready_recovery_action*/, + 0.5, 0.5, 0 /*environmental_variables*/, bin_dir, work_dir, + 0 /*ready_recovery_action*/, fb::RecoveryAction_NONE, 0 /*recovery_action*/, sandbox); - auto comp_name = fbb.CreateString("sandboxed_comp"); - auto component = fb::CreateComponent(fbb, comp_name, 0 /*description*/, sb_comp_props, deploy); - auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{component}); + auto comp = buildDefaultComponent(fbb, "sandboxed_comp", + buildDefaultComponentProperties(fbb), deploy); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); - auto fallback = fb::CreateFallbackRunTarget(fbb); - auto alive_sup = fb::CreateAliveSupervision(fbb); - auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, - 1 /*schema_version*/, comps, 0 /*run_targets*/, irt, fallback, alive_sup); - auto buffer = finishBuffer(fbb, config); - MockBufferLoader::result_ = buffer; - - // WHEN - auto result = loader_.load(kTestPath); + auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); - // THEN ASSERT_THAT(result.has_value(), IsTrue()); ASSERT_THAT(result->components().size(), Eq(1U)); ASSERT_THAT(result->components()[0].deployment_config.sandbox.has_value(), IsTrue()); @@ -440,7 +420,6 @@ TEST_F(FlatbufferConfigLoaderTest, LoadComponentAliveSupervision) { RecordProperty("Description", "Per-component alive supervision is mapped correctly."); - // GIVEN ::flatbuffers::FlatBufferBuilder fbb; auto comp_alive_sup = fb::CreateComponentAliveSupervision(fbb, @@ -449,29 +428,13 @@ TEST_F(FlatbufferConfigLoaderTest, LoadComponentAliveSupervision) fb::ApplicationType_Reporting_And_Supervised, false /*is_self_terminating*/, comp_alive_sup); auto bin_name = fbb.CreateString("supervised_bin"); auto ready_cond = fb::CreateReadyCondition(fbb); - auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile, - 0 /*depends_on*/, 0 /*process_arguments*/, ready_cond); + auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile, 0, 0, ready_cond); - auto bin_dir = fbb.CreateString("/opt"); - auto deploy = fb::CreateDeploymentConfig(fbb, - 0.0 /*ready_timeout*/, 0.0 /*shutdown_timeout*/, 0 /*environmental_variables*/, bin_dir); - - auto comp_name = fbb.CreateString("supervised_comp"); - auto component = fb::CreateComponent(fbb, comp_name, 0 /*description*/, comp_props, deploy); - auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{component}); - - auto fallback = fb::CreateFallbackRunTarget(fbb); - auto alive_sup = fb::CreateAliveSupervision(fbb); - auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, - 1 /*schema_version*/, comps, 0 /*run_targets*/, irt, fallback, alive_sup); - auto buffer = finishBuffer(fbb, config); - MockBufferLoader::result_ = buffer; + auto comp = buildDefaultComponent(fbb, "supervised_comp", comp_props); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); - // WHEN - auto result = loader_.load(kTestPath); + auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); - // THEN ASSERT_THAT(result.has_value(), IsTrue()); const auto& as = result->components()[0].component_properties.application_profile.alive_supervision; ASSERT_THAT(as.has_value(), IsTrue()); @@ -485,7 +448,6 @@ TEST_F(FlatbufferConfigLoaderTest, LoadEnvironmentalVariables) { RecordProperty("Description", "Environmental variables vector is mapped to unordered_map."); - // GIVEN ::flatbuffers::FlatBufferBuilder fbb; auto k1 = fbb.CreateString("PATH"); @@ -496,33 +458,17 @@ TEST_F(FlatbufferConfigLoaderTest, LoadEnvironmentalVariables) auto ev2 = fb::CreateEnvironmentalVariable(fbb, k2, v2); auto env_vars = fbb.CreateVector(std::vector<::flatbuffers::Offset>{ev1, ev2}); - auto env_bin_name = fbb.CreateString("env_bin"); - auto env_app_profile = fb::CreateApplicationProfile(fbb); - auto env_ready_cond = fb::CreateReadyCondition(fbb); - auto env_comp_props = fb::CreateComponentProperties(fbb, env_bin_name, env_app_profile, - 0 /*depends_on*/, 0 /*process_arguments*/, env_ready_cond); - auto bin_dir = fbb.CreateString("/opt"); auto work_dir = fbb.CreateString("/tmp"); auto deploy = fb::CreateDeploymentConfig(fbb, - 0.5 /*ready_timeout*/, 0.5 /*shutdown_timeout*/, env_vars, bin_dir, work_dir); + 0.5, 0.5, env_vars, bin_dir, work_dir); - auto comp_name = fbb.CreateString("env_comp"); - auto component = fb::CreateComponent(fbb, comp_name, 0 /*description*/, env_comp_props, deploy); - auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{component}); + auto comp = buildDefaultComponent(fbb, "env_comp", + buildDefaultComponentProperties(fbb), deploy); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); - auto fallback = fb::CreateFallbackRunTarget(fbb); - auto alive_sup = fb::CreateAliveSupervision(fbb); - auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, - 1 /*schema_version*/, comps, 0 /*run_targets*/, irt, fallback, alive_sup); - auto buffer = finishBuffer(fbb, config); - MockBufferLoader::result_ = buffer; + auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); - // WHEN - auto result = loader_.load(kTestPath); - - // THEN ASSERT_THAT(result.has_value(), IsTrue()); const auto& env = result->components()[0].deployment_config.environmental_variables; EXPECT_THAT(env.size(), Eq(2U)); @@ -534,40 +480,16 @@ TEST_F(FlatbufferConfigLoaderTest, LoadMultipleComponents) { RecordProperty("Description", "Multiple components are all present and in order."); - // GIVEN ::flatbuffers::FlatBufferBuilder fbb; - auto make_component = [&fbb](const char* name) { - auto comp_name = fbb.CreateString(name); - auto bin_name = fbb.CreateString(name); - auto app_profile = fb::CreateApplicationProfile(fbb); - auto ready_cond = fb::CreateReadyCondition(fbb); - auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile, - 0 /*depends_on*/, 0 /*process_arguments*/, ready_cond); - auto bin_dir = fbb.CreateString("/opt"); - auto deploy = fb::CreateDeploymentConfig(fbb, - 0.0 /*ready_timeout*/, 0.0 /*shutdown_timeout*/, 0 /*environmental_variables*/, bin_dir); - return fb::CreateComponent(fbb, comp_name, 0 /*description*/, comp_props, deploy); - }; - - auto comp_a = make_component("CompA"); - auto comp_b = make_component("CompB"); - auto comp_c = make_component("CompC"); + auto comp_a = buildDefaultComponent(fbb, "CompA"); + auto comp_b = buildDefaultComponent(fbb, "CompB"); + auto comp_c = buildDefaultComponent(fbb, "CompC"); auto comps = fbb.CreateVector( std::vector<::flatbuffers::Offset>{comp_a, comp_b, comp_c}); - auto fallback = fb::CreateFallbackRunTarget(fbb); - auto alive_sup = fb::CreateAliveSupervision(fbb); - auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, - 1 /*schema_version*/, comps, 0 /*run_targets*/, irt, fallback, alive_sup); - auto buffer = finishBuffer(fbb, config); - MockBufferLoader::result_ = buffer; - - // WHEN - auto result = loader_.load(kTestPath); + auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); - // THEN ASSERT_THAT(result.has_value(), IsTrue()); ASSERT_THAT(result->components().size(), Eq(3U)); EXPECT_THAT(result->components()[0].name, Eq("CompA")); @@ -583,14 +505,8 @@ TEST_F(FlatbufferConfigLoaderTest, OptionalWatchdogAbsent) { RecordProperty("Description", "When no watchdog is present, it is nullopt."); - // GIVEN - auto buffer = buildMinimalConfig(); - MockBufferLoader::result_ = buffer; - - // WHEN - auto result = loader_.load(kTestPath); + auto result = loadBuffer(buildMinimalConfig()); - // THEN ASSERT_THAT(result.has_value(), IsTrue()); EXPECT_THAT(result->watchdog().has_value(), IsFalse()); } @@ -599,36 +515,13 @@ TEST_F(FlatbufferConfigLoaderTest, OptionalSandboxAbsent) { RecordProperty("Description", "When no sandbox is present on a component, it is nullopt."); - // GIVEN ::flatbuffers::FlatBufferBuilder fbb; - auto ns_bin_name = fbb.CreateString("no_sandbox_bin"); - auto ns_app_profile = fb::CreateApplicationProfile(fbb); - auto ns_ready_cond = fb::CreateReadyCondition(fbb); - auto ns_comp_props = fb::CreateComponentProperties(fbb, ns_bin_name, ns_app_profile, - 0 /*depends_on*/, 0 /*process_arguments*/, ns_ready_cond); + auto comp = buildDefaultComponent(fbb, "no_sandbox"); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); - auto bin_dir = fbb.CreateString("/opt"); - auto work_dir = fbb.CreateString("/tmp"); - auto deploy = fb::CreateDeploymentConfig(fbb, - 0.5 /*ready_timeout*/, 0.5 /*shutdown_timeout*/, 0 /*environmental_variables*/, bin_dir, work_dir); + auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); - auto comp_name = fbb.CreateString("no_sandbox"); - auto component = fb::CreateComponent(fbb, comp_name, 0 /*description*/, ns_comp_props, deploy); - auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{component}); - - auto fallback = fb::CreateFallbackRunTarget(fbb); - auto alive_sup = fb::CreateAliveSupervision(fbb); - auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, - 1 /*schema_version*/, comps, 0 /*run_targets*/, irt, fallback, alive_sup); - auto buffer = finishBuffer(fbb, config); - MockBufferLoader::result_ = buffer; - - // WHEN - auto result = loader_.load(kTestPath); - - // THEN ASSERT_THAT(result.has_value(), IsTrue()); EXPECT_THAT(result->components()[0].deployment_config.sandbox.has_value(), IsFalse()); } @@ -641,33 +534,18 @@ TEST_F(FlatbufferConfigLoaderTest, MapNativeApplicationType) { RecordProperty("Description", "ApplicationType_Native maps to ApplicationType::Native."); - // GIVEN ::flatbuffers::FlatBufferBuilder fbb; auto app_profile = fb::CreateApplicationProfile(fbb, fb::ApplicationType_Native); auto bin_name = fbb.CreateString("native_bin"); auto ready_cond = fb::CreateReadyCondition(fbb); - auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile, - 0 /*depends_on*/, 0 /*process_arguments*/, ready_cond); - auto bin_dir = fbb.CreateString("/opt"); - auto deploy = fb::CreateDeploymentConfig(fbb, - 0.0 /*ready_timeout*/, 0.0 /*shutdown_timeout*/, 0 /*environmental_variables*/, bin_dir); - auto comp_name = fbb.CreateString("native_comp"); - auto component = fb::CreateComponent(fbb, comp_name, 0 /*description*/, comp_props, deploy); - auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{component}); + auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile, 0, 0, ready_cond); - auto fallback = fb::CreateFallbackRunTarget(fbb); - auto alive_sup = fb::CreateAliveSupervision(fbb); - auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, - 1 /*schema_version*/, comps, 0 /*run_targets*/, irt, fallback, alive_sup); - auto buffer = finishBuffer(fbb, config); - MockBufferLoader::result_ = buffer; + auto comp = buildDefaultComponent(fbb, "native_comp", comp_props); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); - // WHEN - auto result = loader_.load(kTestPath); + auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); - // THEN ASSERT_THAT(result.has_value(), IsTrue()); EXPECT_THAT(result->components()[0].component_properties.application_profile.application_type, Eq(ApplicationType::Native)); @@ -678,33 +556,18 @@ TEST_F(FlatbufferConfigLoaderTest, MapReportingAndSupervisedType) RecordProperty("Description", "ApplicationType_Reporting_And_Supervised maps to ApplicationType::ReportingAndSupervised."); - // GIVEN ::flatbuffers::FlatBufferBuilder fbb; auto app_profile = fb::CreateApplicationProfile(fbb, fb::ApplicationType_Reporting_And_Supervised); auto bin_name = fbb.CreateString("supervised_bin"); auto ready_cond = fb::CreateReadyCondition(fbb); - auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile, - 0 /*depends_on*/, 0 /*process_arguments*/, ready_cond); - auto bin_dir = fbb.CreateString("/opt"); - auto deploy = fb::CreateDeploymentConfig(fbb, - 0.0 /*ready_timeout*/, 0.0 /*shutdown_timeout*/, 0 /*environmental_variables*/, bin_dir); - auto comp_name = fbb.CreateString("supervised_comp"); - auto component = fb::CreateComponent(fbb, comp_name, 0 /*description*/, comp_props, deploy); - auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{component}); + auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile, 0, 0, ready_cond); - auto fallback = fb::CreateFallbackRunTarget(fbb); - auto alive_sup = fb::CreateAliveSupervision(fbb); - auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, - 1 /*schema_version*/, comps, 0 /*run_targets*/, irt, fallback, alive_sup); - auto buffer = finishBuffer(fbb, config); - MockBufferLoader::result_ = buffer; + auto comp = buildDefaultComponent(fbb, "supervised_comp", comp_props); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); - // WHEN - auto result = loader_.load(kTestPath); + auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); - // THEN ASSERT_THAT(result.has_value(), IsTrue()); EXPECT_THAT(result->components()[0].component_properties.application_profile.application_type, Eq(ApplicationType::ReportingAndSupervised)); @@ -714,33 +577,19 @@ TEST_F(FlatbufferConfigLoaderTest, MapTerminatedProcessState) { RecordProperty("Description", "ProcessState_Terminated maps to ProcessState::Terminated."); - // GIVEN ::flatbuffers::FlatBufferBuilder fbb; auto app_profile = fb::CreateApplicationProfile(fbb); auto ready_cond = fb::CreateReadyCondition(fbb, fb::ProcessState_Terminated); auto bin_name = fbb.CreateString("term_bin"); auto comp_props = fb::CreateComponentProperties(fbb, - bin_name, app_profile, 0 /*depends_on*/, 0 /*process_arguments*/, ready_cond); - auto bin_dir = fbb.CreateString("/opt"); - auto deploy = fb::CreateDeploymentConfig(fbb, - 0.0 /*ready_timeout*/, 0.0 /*shutdown_timeout*/, 0 /*environmental_variables*/, bin_dir); - auto comp_name = fbb.CreateString("term_comp"); - auto component = fb::CreateComponent(fbb, comp_name, 0 /*description*/, comp_props, deploy); - auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{component}); + bin_name, app_profile, 0, 0, ready_cond); - auto fallback = fb::CreateFallbackRunTarget(fbb); - auto alive_sup = fb::CreateAliveSupervision(fbb); - auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, - 1 /*schema_version*/, comps, 0 /*run_targets*/, irt, fallback, alive_sup); - auto buffer = finishBuffer(fbb, config); - MockBufferLoader::result_ = buffer; + auto comp = buildDefaultComponent(fbb, "term_comp", comp_props); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); - // WHEN - auto result = loader_.load(kTestPath); + auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); - // THEN ASSERT_THAT(result.has_value(), IsTrue()); EXPECT_THAT(result->components()[0].component_properties.ready_condition.process_state, Eq(ProcessState::Terminated)); @@ -754,13 +603,10 @@ TEST_F(FlatbufferConfigLoaderTest, LoadBufferFailsWithNoSuchFileReturnsFileNotFo { RecordProperty("Description", "When LoadBuffer fails with ENOENT, returns FileNotFound error."); - // GIVEN MockBufferLoader::result_ = score::cpp::make_unexpected(score::os::Error::createFromErrno(ENOENT)); - // WHEN auto result = loader_.load(kTestPath); - // THEN ASSERT_THAT(result.has_value(), IsFalse()); EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::FileNotFound)); } @@ -769,13 +615,10 @@ TEST_F(FlatbufferConfigLoaderTest, LoadBufferFailsWithPermissionDeniedReturnsIns { RecordProperty("Description", "When LoadBuffer fails with EACCES, returns InsufficientPermission error."); - // GIVEN MockBufferLoader::result_ = score::cpp::make_unexpected(score::os::Error::createFromErrno(EACCES)); - // WHEN auto result = loader_.load(kTestPath); - // THEN ASSERT_THAT(result.has_value(), IsFalse()); EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InsufficientPermission)); } @@ -784,13 +627,10 @@ TEST_F(FlatbufferConfigLoaderTest, LoadBufferFailsWithGenericErrorReturnsGeneral { RecordProperty("Description", "When LoadBuffer fails with a generic OS error, returns GeneralError."); - // GIVEN MockBufferLoader::result_ = score::cpp::make_unexpected(score::os::Error::createFromErrno(EIO)); - // WHEN auto result = loader_.load(kTestPath); - // THEN ASSERT_THAT(result.has_value(), IsFalse()); EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::GeneralError)); } @@ -799,14 +639,8 @@ TEST_F(FlatbufferConfigLoaderTest, CorruptedBufferReturnsInvalidFormat) { RecordProperty("Description", "Corrupted binary data returns InvalidFormat error."); - // GIVEN - std::vector garbage = {0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01, 0x02, 0x03}; - MockBufferLoader::result_ = garbage; + auto result = loadBuffer({0xDE, 0xAD, 0xBE, 0xEF, 0x00, 0x01, 0x02, 0x03}); - // WHEN - auto result = loader_.load(kTestPath); - - // THEN ASSERT_THAT(result.has_value(), IsFalse()); EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); } @@ -815,14 +649,8 @@ TEST_F(FlatbufferConfigLoaderTest, WrongSchemaVersionReturnsUnsupportedVersion) { RecordProperty("Description", "A config with an unexpected schema_version returns UnsupportedVersion."); - // GIVEN - auto buffer = buildMinimalConfig(99, "Startup"); - MockBufferLoader::result_ = buffer; - - // WHEN - auto result = loader_.load(kTestPath); + auto result = loadBuffer(buildMinimalConfig(99, "Startup")); - // THEN ASSERT_THAT(result.has_value(), IsFalse()); EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::UnsupportedVersion)); } diff --git a/src/launch_manager_daemon/config/src/new_lm_flatcfg.fbs b/src/launch_manager_daemon/config/src/new_lm_flatcfg.fbs index 56148ef1a..4d3713826 100644 --- a/src/launch_manager_daemon/config/src/new_lm_flatcfg.fbs +++ b/src/launch_manager_daemon/config/src/new_lm_flatcfg.fbs @@ -111,8 +111,8 @@ table DeploymentConfig { // Working directory for the component during execution. working_dir:string; // Recovery action when the component fails to reach ready state. - // Must be RestartAction per the JSON schema constraint. - ready_recovery_action:RecoveryAction; + // Can only be a RestartAction per the JSON schema constraint. + ready_recovery_action:RestartAction; // Recovery action when the component malfunctions after reaching ready state. // Must be SwitchRunTargetAction per the JSON schema constraint. recovery_action:RecoveryAction; diff --git a/src/launch_manager_daemon/config/src/new_lm_flatcfg_generated.h b/src/launch_manager_daemon/config/src/new_lm_flatcfg_generated.h index ff1f4bf4a..71cc56ca3 100644 --- a/src/launch_manager_daemon/config/src/new_lm_flatcfg_generated.h +++ b/src/launch_manager_daemon/config/src/new_lm_flatcfg_generated.h @@ -788,11 +788,10 @@ struct DeploymentConfig FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { VT_ENVIRONMENTAL_VARIABLES = 8, VT_BIN_DIR = 10, VT_WORKING_DIR = 12, - VT_READY_RECOVERY_ACTION_TYPE = 14, - VT_READY_RECOVERY_ACTION = 16, - VT_RECOVERY_ACTION_TYPE = 18, - VT_RECOVERY_ACTION = 20, - VT_SANDBOX = 22 + VT_READY_RECOVERY_ACTION = 14, + VT_RECOVERY_ACTION_TYPE = 16, + VT_RECOVERY_ACTION = 18, + VT_SANDBOX = 20 }; double ready_timeout() const { return GetField(VT_READY_TIMEOUT, 0.0); @@ -809,18 +808,8 @@ struct DeploymentConfig FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { const ::flatbuffers::String *working_dir() const { return GetPointer(VT_WORKING_DIR); } - score::launch_manager::config::fb::RecoveryAction ready_recovery_action_type() const { - return static_cast(GetField(VT_READY_RECOVERY_ACTION_TYPE, 0)); - } - const void *ready_recovery_action() const { - return GetPointer(VT_READY_RECOVERY_ACTION); - } - template const T *ready_recovery_action_as() const; - const score::launch_manager::config::fb::RestartAction *ready_recovery_action_as_RestartAction() const { - return ready_recovery_action_type() == score::launch_manager::config::fb::RecoveryAction_RestartAction ? static_cast(ready_recovery_action()) : nullptr; - } - const score::launch_manager::config::fb::SwitchRunTargetAction *ready_recovery_action_as_SwitchRunTargetAction() const { - return ready_recovery_action_type() == score::launch_manager::config::fb::RecoveryAction_SwitchRunTargetAction ? static_cast(ready_recovery_action()) : nullptr; + const score::launch_manager::config::fb::RestartAction *ready_recovery_action() const { + return GetPointer(VT_READY_RECOVERY_ACTION); } score::launch_manager::config::fb::RecoveryAction recovery_action_type() const { return static_cast(GetField(VT_RECOVERY_ACTION_TYPE, 0)); @@ -850,9 +839,8 @@ struct DeploymentConfig FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { verifier.VerifyString(bin_dir()) && VerifyOffset(verifier, VT_WORKING_DIR) && verifier.VerifyString(working_dir()) && - VerifyField(verifier, VT_READY_RECOVERY_ACTION_TYPE, 1) && VerifyOffset(verifier, VT_READY_RECOVERY_ACTION) && - VerifyRecoveryAction(verifier, ready_recovery_action(), ready_recovery_action_type()) && + verifier.VerifyTable(ready_recovery_action()) && VerifyField(verifier, VT_RECOVERY_ACTION_TYPE, 1) && VerifyOffset(verifier, VT_RECOVERY_ACTION) && VerifyRecoveryAction(verifier, recovery_action(), recovery_action_type()) && @@ -862,14 +850,6 @@ struct DeploymentConfig FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { } }; -template<> inline const score::launch_manager::config::fb::RestartAction *DeploymentConfig::ready_recovery_action_as() const { - return ready_recovery_action_as_RestartAction(); -} - -template<> inline const score::launch_manager::config::fb::SwitchRunTargetAction *DeploymentConfig::ready_recovery_action_as() const { - return ready_recovery_action_as_SwitchRunTargetAction(); -} - template<> inline const score::launch_manager::config::fb::RestartAction *DeploymentConfig::recovery_action_as() const { return recovery_action_as_RestartAction(); } @@ -897,10 +877,7 @@ struct DeploymentConfigBuilder { void add_working_dir(::flatbuffers::Offset<::flatbuffers::String> working_dir) { fbb_.AddOffset(DeploymentConfig::VT_WORKING_DIR, working_dir); } - void add_ready_recovery_action_type(score::launch_manager::config::fb::RecoveryAction ready_recovery_action_type) { - fbb_.AddElement(DeploymentConfig::VT_READY_RECOVERY_ACTION_TYPE, static_cast(ready_recovery_action_type), 0); - } - void add_ready_recovery_action(::flatbuffers::Offset ready_recovery_action) { + void add_ready_recovery_action(::flatbuffers::Offset ready_recovery_action) { fbb_.AddOffset(DeploymentConfig::VT_READY_RECOVERY_ACTION, ready_recovery_action); } void add_recovery_action_type(score::launch_manager::config::fb::RecoveryAction recovery_action_type) { @@ -931,8 +908,7 @@ inline ::flatbuffers::Offset CreateDeploymentConfig( ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> environmental_variables = 0, ::flatbuffers::Offset<::flatbuffers::String> bin_dir = 0, ::flatbuffers::Offset<::flatbuffers::String> working_dir = 0, - score::launch_manager::config::fb::RecoveryAction ready_recovery_action_type = score::launch_manager::config::fb::RecoveryAction_NONE, - ::flatbuffers::Offset ready_recovery_action = 0, + ::flatbuffers::Offset ready_recovery_action = 0, score::launch_manager::config::fb::RecoveryAction recovery_action_type = score::launch_manager::config::fb::RecoveryAction_NONE, ::flatbuffers::Offset recovery_action = 0, ::flatbuffers::Offset sandbox = 0) { @@ -946,7 +922,6 @@ inline ::flatbuffers::Offset CreateDeploymentConfig( builder_.add_bin_dir(bin_dir); builder_.add_environmental_variables(environmental_variables); builder_.add_recovery_action_type(recovery_action_type); - builder_.add_ready_recovery_action_type(ready_recovery_action_type); return builder_.Finish(); } @@ -957,8 +932,7 @@ inline ::flatbuffers::Offset CreateDeploymentConfigDirect( const std::vector<::flatbuffers::Offset> *environmental_variables = nullptr, const char *bin_dir = nullptr, const char *working_dir = nullptr, - score::launch_manager::config::fb::RecoveryAction ready_recovery_action_type = score::launch_manager::config::fb::RecoveryAction_NONE, - ::flatbuffers::Offset ready_recovery_action = 0, + ::flatbuffers::Offset ready_recovery_action = 0, score::launch_manager::config::fb::RecoveryAction recovery_action_type = score::launch_manager::config::fb::RecoveryAction_NONE, ::flatbuffers::Offset recovery_action = 0, ::flatbuffers::Offset sandbox = 0) { @@ -972,7 +946,6 @@ inline ::flatbuffers::Offset CreateDeploymentConfigDirect( environmental_variables__, bin_dir__, working_dir__, - ready_recovery_action_type, ready_recovery_action, recovery_action_type, recovery_action, From d73fa632ae37ef6937e04ae82b26ec1092736a0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Fu=C3=9Fberger?= Date: Tue, 19 May 2026 07:10:18 +0200 Subject: [PATCH 05/26] Use bazel rule to generate fb file --- src/launch_manager_daemon/config/BUILD | 12 +- .../config/src/flatbuffer_config_loader.cpp | 16 +- .../src/flatbuffer_config_loader_UT.cpp | 18 +- .../config/src/new_lm_flatcfg_generated.h | 1599 ----------------- 4 files changed, 28 insertions(+), 1617 deletions(-) delete mode 100644 src/launch_manager_daemon/config/src/new_lm_flatcfg_generated.h diff --git a/src/launch_manager_daemon/config/BUILD b/src/launch_manager_daemon/config/BUILD index 42c1d72d9..04c076566 100644 --- a/src/launch_manager_daemon/config/BUILD +++ b/src/launch_manager_daemon/config/BUILD @@ -10,6 +10,9 @@ # # SPDX-License-Identifier: Apache-2.0 # ******************************************************************************* + +load("@score_baselibs//score/flatbuffers/bazel:codegen.bzl", "generate_cpp") + exports_files([ "lm_flatcfg.fbs", "lm_flatcfg_generated.h", @@ -21,6 +24,12 @@ filegroup( visibility = ["//visibility:public"], ) +generate_cpp( + name = "new_lm_flatcfg_generated", + output = "new_lm_flatcfg_generated.h", + schema = "src/new_lm_flatcfg.fbs", +) + cc_library( name = "config", srcs = ["src/config.cpp"], @@ -45,10 +54,11 @@ cc_library( name = "flatbuffer_config_loader", srcs = [ "src/flatbuffer_config_loader.cpp", - "src/new_lm_flatcfg_generated.h", + ":new_lm_flatcfg_generated", ], hdrs = ["include/flatbuffer_config_loader.hpp"], includes = [ + ".", "include", "src", ], diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp index fc692b113..c89cbb790 100644 --- a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp @@ -41,13 +41,13 @@ ApplicationType convertApplicationType(fb::ApplicationType fb_type) { switch (fb_type) { - case fb::ApplicationType_Reporting: + case fb::ApplicationType::Reporting: return ApplicationType::Reporting; - case fb::ApplicationType_Reporting_And_Supervised: + case fb::ApplicationType::Reporting_And_Supervised: return ApplicationType::ReportingAndSupervised; - case fb::ApplicationType_State_Manager: + case fb::ApplicationType::State_Manager: return ApplicationType::StateManager; - case fb::ApplicationType_Native: + case fb::ApplicationType::Native: default: return ApplicationType::Native; } @@ -57,9 +57,9 @@ ProcessState convertProcessState(fb::ProcessState fb_state) { switch (fb_state) { - case fb::ProcessState_Terminated: + case fb::ProcessState::Terminated: return ProcessState::Terminated; - case fb::ProcessState_Running: + case fb::ProcessState::Running: default: return ProcessState::Running; } @@ -134,7 +134,7 @@ std::optional convertRecoveryAction(fb::RecoveryAction type, con { switch (type) { - case fb::RecoveryAction_RestartAction: + case fb::RecoveryAction::RestartAction: { const auto* ra = static_cast(action); if (ra == nullptr) @@ -143,7 +143,7 @@ std::optional convertRecoveryAction(fb::RecoveryAction type, con } return RestartAction{ra->number_of_attempts(), secondsToMs(ra->delay_before_restart())}; } - case fb::RecoveryAction_SwitchRunTargetAction: + case fb::RecoveryAction::SwitchRunTargetAction: { const auto* sa = static_cast(action); if (sa == nullptr) diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp index 735b5ea00..73fbb8a7e 100644 --- a/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp @@ -171,13 +171,13 @@ TEST_F(FlatbufferConfigLoaderTest, LoadSingleComponent) auto alive_sup = fb::CreateComponentAliveSupervision(fbb, 0.5 /*reporting_cycle*/, 2 /*failed_cycles_tolerance*/, 1 /*min_indications*/, 3 /*max_indications*/); auto app_profile = - fb::CreateApplicationProfile(fbb, fb::ApplicationType_Reporting_And_Supervised, true /*is_self_terminating*/, alive_sup); + fb::CreateApplicationProfile(fbb, fb::ApplicationType::Reporting_And_Supervised, true /*is_self_terminating*/, alive_sup); auto bin_name = fbb.CreateString("my_binary"); auto dep = fbb.CreateString("other_comp"); auto deps_vec = fbb.CreateVector(std::vector<::flatbuffers::Offset<::flatbuffers::String>>{dep}); auto arg = fbb.CreateString("--verbose"); auto args_vec = fbb.CreateVector(std::vector<::flatbuffers::Offset<::flatbuffers::String>>{arg}); - auto ready_cond = fb::CreateReadyCondition(fbb, fb::ProcessState_Running); + auto ready_cond = fb::CreateReadyCondition(fbb, fb::ProcessState::Running); auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile, deps_vec, args_vec, ready_cond); auto bin_dir = fbb.CreateString("/opt/bin"); @@ -230,7 +230,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadRunTargets) auto rt_dep = fbb.CreateString("component_a"); auto rt_deps = fbb.CreateVector(std::vector<::flatbuffers::Offset<::flatbuffers::String>>{rt_dep}); auto rt = fb::CreateRunTarget(fbb, rt_name, rt_desc, rt_deps, 5.0 /*transition_timeout*/, - fb::RecoveryAction_SwitchRunTargetAction, switch_action.Union()); + fb::RecoveryAction::SwitchRunTargetAction, switch_action.Union()); auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{rt}); auto result = loadBuffer(buildConfigWithRunTargets(fbb, rts)); @@ -359,7 +359,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadSwitchRunTargetAction) auto rt_name = fbb.CreateString("Startup"); auto rt = fb::CreateRunTarget( fbb, rt_name, 0, 0, 0.0, - fb::RecoveryAction_SwitchRunTargetAction, switch_action.Union()); + fb::RecoveryAction::SwitchRunTargetAction, switch_action.Union()); auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{rt}); auto result = loadBuffer(buildConfigWithRunTargets(fbb, rts)); @@ -390,7 +390,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadSandbox) auto deploy = fb::CreateDeploymentConfig(fbb, 0.5, 0.5, 0 /*environmental_variables*/, bin_dir, work_dir, 0 /*ready_recovery_action*/, - fb::RecoveryAction_NONE, 0 /*recovery_action*/, sandbox); + fb::RecoveryAction::NONE, 0 /*recovery_action*/, sandbox); auto comp = buildDefaultComponent(fbb, "sandboxed_comp", buildDefaultComponentProperties(fbb), deploy); @@ -425,7 +425,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadComponentAliveSupervision) auto comp_alive_sup = fb::CreateComponentAliveSupervision(fbb, 1.0 /*reporting_cycle*/, 3 /*failed_cycles_tolerance*/, 2 /*min_indications*/, 5 /*max_indications*/); auto app_profile = fb::CreateApplicationProfile(fbb, - fb::ApplicationType_Reporting_And_Supervised, false /*is_self_terminating*/, comp_alive_sup); + fb::ApplicationType::Reporting_And_Supervised, false /*is_self_terminating*/, comp_alive_sup); auto bin_name = fbb.CreateString("supervised_bin"); auto ready_cond = fb::CreateReadyCondition(fbb); auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile, 0, 0, ready_cond); @@ -536,7 +536,7 @@ TEST_F(FlatbufferConfigLoaderTest, MapNativeApplicationType) ::flatbuffers::FlatBufferBuilder fbb; - auto app_profile = fb::CreateApplicationProfile(fbb, fb::ApplicationType_Native); + auto app_profile = fb::CreateApplicationProfile(fbb, fb::ApplicationType::Native); auto bin_name = fbb.CreateString("native_bin"); auto ready_cond = fb::CreateReadyCondition(fbb); auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile, 0, 0, ready_cond); @@ -558,7 +558,7 @@ TEST_F(FlatbufferConfigLoaderTest, MapReportingAndSupervisedType) ::flatbuffers::FlatBufferBuilder fbb; - auto app_profile = fb::CreateApplicationProfile(fbb, fb::ApplicationType_Reporting_And_Supervised); + auto app_profile = fb::CreateApplicationProfile(fbb, fb::ApplicationType::Reporting_And_Supervised); auto bin_name = fbb.CreateString("supervised_bin"); auto ready_cond = fb::CreateReadyCondition(fbb); auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile, 0, 0, ready_cond); @@ -580,7 +580,7 @@ TEST_F(FlatbufferConfigLoaderTest, MapTerminatedProcessState) ::flatbuffers::FlatBufferBuilder fbb; auto app_profile = fb::CreateApplicationProfile(fbb); - auto ready_cond = fb::CreateReadyCondition(fbb, fb::ProcessState_Terminated); + auto ready_cond = fb::CreateReadyCondition(fbb, fb::ProcessState::Terminated); auto bin_name = fbb.CreateString("term_bin"); auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile, 0, 0, ready_cond); diff --git a/src/launch_manager_daemon/config/src/new_lm_flatcfg_generated.h b/src/launch_manager_daemon/config/src/new_lm_flatcfg_generated.h deleted file mode 100644 index 71cc56ca3..000000000 --- a/src/launch_manager_daemon/config/src/new_lm_flatcfg_generated.h +++ /dev/null @@ -1,1599 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify - - -#ifndef FLATBUFFERS_GENERATED_NEWLMFLATCFG_SCORE_LAUNCH_MANAGER_CONFIG_FB_H_ -#define FLATBUFFERS_GENERATED_NEWLMFLATCFG_SCORE_LAUNCH_MANAGER_CONFIG_FB_H_ - -#include "flatbuffers/flatbuffers.h" - -// Ensure the included flatbuffers.h is the same version as when this file was -// generated, otherwise it may not be compatible. -static_assert(FLATBUFFERS_VERSION_MAJOR == 25 && - FLATBUFFERS_VERSION_MINOR == 12 && - FLATBUFFERS_VERSION_REVISION == 19, - "Non-compatible flatbuffers version included"); - -namespace score { -namespace launch_manager { -namespace config { -namespace fb { - -struct ComponentAliveSupervision; -struct ComponentAliveSupervisionBuilder; - -struct ApplicationProfile; -struct ApplicationProfileBuilder; - -struct ReadyCondition; -struct ReadyConditionBuilder; - -struct ComponentProperties; -struct ComponentPropertiesBuilder; - -struct RestartAction; -struct RestartActionBuilder; - -struct SwitchRunTargetAction; -struct SwitchRunTargetActionBuilder; - -struct EnvironmentalVariable; -struct EnvironmentalVariableBuilder; - -struct Sandbox; -struct SandboxBuilder; - -struct DeploymentConfig; -struct DeploymentConfigBuilder; - -struct RunTarget; -struct RunTargetBuilder; - -struct Component; -struct ComponentBuilder; - -struct AliveSupervision; -struct AliveSupervisionBuilder; - -struct Watchdog; -struct WatchdogBuilder; - -struct FallbackRunTarget; -struct FallbackRunTargetBuilder; - -struct LaunchManagerConfig; -struct LaunchManagerConfigBuilder; - -enum ApplicationType : int8_t { - ApplicationType_Native = 0, - ApplicationType_Reporting = 1, - ApplicationType_Reporting_And_Supervised = 2, - ApplicationType_State_Manager = 3, - ApplicationType_MIN = ApplicationType_Native, - ApplicationType_MAX = ApplicationType_State_Manager -}; - -inline const ApplicationType (&EnumValuesApplicationType())[4] { - static const ApplicationType values[] = { - ApplicationType_Native, - ApplicationType_Reporting, - ApplicationType_Reporting_And_Supervised, - ApplicationType_State_Manager - }; - return values; -} - -inline const char * const *EnumNamesApplicationType() { - static const char * const names[5] = { - "Native", - "Reporting", - "Reporting_And_Supervised", - "State_Manager", - nullptr - }; - return names; -} - -inline const char *EnumNameApplicationType(ApplicationType e) { - if (::flatbuffers::IsOutRange(e, ApplicationType_Native, ApplicationType_State_Manager)) return ""; - const size_t index = static_cast(e); - return EnumNamesApplicationType()[index]; -} - -enum ProcessState : int8_t { - ProcessState_Running = 0, - ProcessState_Terminated = 1, - ProcessState_MIN = ProcessState_Running, - ProcessState_MAX = ProcessState_Terminated -}; - -inline const ProcessState (&EnumValuesProcessState())[2] { - static const ProcessState values[] = { - ProcessState_Running, - ProcessState_Terminated - }; - return values; -} - -inline const char * const *EnumNamesProcessState() { - static const char * const names[3] = { - "Running", - "Terminated", - nullptr - }; - return names; -} - -inline const char *EnumNameProcessState(ProcessState e) { - if (::flatbuffers::IsOutRange(e, ProcessState_Running, ProcessState_Terminated)) return ""; - const size_t index = static_cast(e); - return EnumNamesProcessState()[index]; -} - -enum RecoveryAction : uint8_t { - RecoveryAction_NONE = 0, - RecoveryAction_RestartAction = 1, - RecoveryAction_SwitchRunTargetAction = 2, - RecoveryAction_MIN = RecoveryAction_NONE, - RecoveryAction_MAX = RecoveryAction_SwitchRunTargetAction -}; - -inline const RecoveryAction (&EnumValuesRecoveryAction())[3] { - static const RecoveryAction values[] = { - RecoveryAction_NONE, - RecoveryAction_RestartAction, - RecoveryAction_SwitchRunTargetAction - }; - return values; -} - -inline const char * const *EnumNamesRecoveryAction() { - static const char * const names[4] = { - "NONE", - "RestartAction", - "SwitchRunTargetAction", - nullptr - }; - return names; -} - -inline const char *EnumNameRecoveryAction(RecoveryAction e) { - if (::flatbuffers::IsOutRange(e, RecoveryAction_NONE, RecoveryAction_SwitchRunTargetAction)) return ""; - const size_t index = static_cast(e); - return EnumNamesRecoveryAction()[index]; -} - -template struct RecoveryActionTraits { - static const RecoveryAction enum_value = RecoveryAction_NONE; -}; - -template<> struct RecoveryActionTraits { - static const RecoveryAction enum_value = RecoveryAction_RestartAction; -}; - -template<> struct RecoveryActionTraits { - static const RecoveryAction enum_value = RecoveryAction_SwitchRunTargetAction; -}; - -template -bool VerifyRecoveryAction(::flatbuffers::VerifierTemplate &verifier, const void *obj, RecoveryAction type); -template -bool VerifyRecoveryActionVector(::flatbuffers::VerifierTemplate &verifier, const ::flatbuffers::Vector<::flatbuffers::Offset> *values, const ::flatbuffers::Vector *types); - -struct ComponentAliveSupervision FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef ComponentAliveSupervisionBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_REPORTING_CYCLE = 4, - VT_FAILED_CYCLES_TOLERANCE = 6, - VT_MIN_INDICATIONS = 8, - VT_MAX_INDICATIONS = 10 - }; - double reporting_cycle() const { - return GetField(VT_REPORTING_CYCLE, 0.0); - } - uint32_t failed_cycles_tolerance() const { - return GetField(VT_FAILED_CYCLES_TOLERANCE, 0); - } - ::flatbuffers::Optional min_indications() const { - return GetOptional(VT_MIN_INDICATIONS); - } - ::flatbuffers::Optional max_indications() const { - return GetOptional(VT_MAX_INDICATIONS); - } - template - bool Verify(::flatbuffers::VerifierTemplate &verifier) const { - return VerifyTableStart(verifier) && - VerifyField(verifier, VT_REPORTING_CYCLE, 8) && - VerifyField(verifier, VT_FAILED_CYCLES_TOLERANCE, 4) && - VerifyField(verifier, VT_MIN_INDICATIONS, 4) && - VerifyField(verifier, VT_MAX_INDICATIONS, 4) && - verifier.EndTable(); - } -}; - -struct ComponentAliveSupervisionBuilder { - typedef ComponentAliveSupervision Table; - ::flatbuffers::FlatBufferBuilder &fbb_; - ::flatbuffers::uoffset_t start_; - void add_reporting_cycle(double reporting_cycle) { - fbb_.AddElement(ComponentAliveSupervision::VT_REPORTING_CYCLE, reporting_cycle, 0.0); - } - void add_failed_cycles_tolerance(uint32_t failed_cycles_tolerance) { - fbb_.AddElement(ComponentAliveSupervision::VT_FAILED_CYCLES_TOLERANCE, failed_cycles_tolerance, 0); - } - void add_min_indications(uint32_t min_indications) { - fbb_.AddElement(ComponentAliveSupervision::VT_MIN_INDICATIONS, min_indications); - } - void add_max_indications(uint32_t max_indications) { - fbb_.AddElement(ComponentAliveSupervision::VT_MAX_INDICATIONS, max_indications); - } - explicit ComponentAliveSupervisionBuilder(::flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - ::flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); - return o; - } -}; - -inline ::flatbuffers::Offset CreateComponentAliveSupervision( - ::flatbuffers::FlatBufferBuilder &_fbb, - double reporting_cycle = 0.0, - uint32_t failed_cycles_tolerance = 0, - ::flatbuffers::Optional min_indications = ::flatbuffers::nullopt, - ::flatbuffers::Optional max_indications = ::flatbuffers::nullopt) { - ComponentAliveSupervisionBuilder builder_(_fbb); - builder_.add_reporting_cycle(reporting_cycle); - if(max_indications) { builder_.add_max_indications(*max_indications); } - if(min_indications) { builder_.add_min_indications(*min_indications); } - builder_.add_failed_cycles_tolerance(failed_cycles_tolerance); - return builder_.Finish(); -} - -struct ApplicationProfile FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef ApplicationProfileBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_APPLICATION_TYPE = 4, - VT_IS_SELF_TERMINATING = 6, - VT_ALIVE_SUPERVISION = 8 - }; - score::launch_manager::config::fb::ApplicationType application_type() const { - return static_cast(GetField(VT_APPLICATION_TYPE, 0)); - } - bool is_self_terminating() const { - return GetField(VT_IS_SELF_TERMINATING, 0) != 0; - } - const score::launch_manager::config::fb::ComponentAliveSupervision *alive_supervision() const { - return GetPointer(VT_ALIVE_SUPERVISION); - } - template - bool Verify(::flatbuffers::VerifierTemplate &verifier) const { - return VerifyTableStart(verifier) && - VerifyField(verifier, VT_APPLICATION_TYPE, 1) && - VerifyField(verifier, VT_IS_SELF_TERMINATING, 1) && - VerifyOffset(verifier, VT_ALIVE_SUPERVISION) && - verifier.VerifyTable(alive_supervision()) && - verifier.EndTable(); - } -}; - -struct ApplicationProfileBuilder { - typedef ApplicationProfile Table; - ::flatbuffers::FlatBufferBuilder &fbb_; - ::flatbuffers::uoffset_t start_; - void add_application_type(score::launch_manager::config::fb::ApplicationType application_type) { - fbb_.AddElement(ApplicationProfile::VT_APPLICATION_TYPE, static_cast(application_type), 0); - } - void add_is_self_terminating(bool is_self_terminating) { - fbb_.AddElement(ApplicationProfile::VT_IS_SELF_TERMINATING, static_cast(is_self_terminating), 0); - } - void add_alive_supervision(::flatbuffers::Offset alive_supervision) { - fbb_.AddOffset(ApplicationProfile::VT_ALIVE_SUPERVISION, alive_supervision); - } - explicit ApplicationProfileBuilder(::flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - ::flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); - return o; - } -}; - -inline ::flatbuffers::Offset CreateApplicationProfile( - ::flatbuffers::FlatBufferBuilder &_fbb, - score::launch_manager::config::fb::ApplicationType application_type = score::launch_manager::config::fb::ApplicationType_Native, - bool is_self_terminating = false, - ::flatbuffers::Offset alive_supervision = 0) { - ApplicationProfileBuilder builder_(_fbb); - builder_.add_alive_supervision(alive_supervision); - builder_.add_is_self_terminating(is_self_terminating); - builder_.add_application_type(application_type); - return builder_.Finish(); -} - -struct ReadyCondition FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef ReadyConditionBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_PROCESS_STATE = 4 - }; - ::flatbuffers::Optional process_state() const { - return GetOptional(VT_PROCESS_STATE); - } - template - bool Verify(::flatbuffers::VerifierTemplate &verifier) const { - return VerifyTableStart(verifier) && - VerifyField(verifier, VT_PROCESS_STATE, 1) && - verifier.EndTable(); - } -}; - -struct ReadyConditionBuilder { - typedef ReadyCondition Table; - ::flatbuffers::FlatBufferBuilder &fbb_; - ::flatbuffers::uoffset_t start_; - void add_process_state(score::launch_manager::config::fb::ProcessState process_state) { - fbb_.AddElement(ReadyCondition::VT_PROCESS_STATE, static_cast(process_state)); - } - explicit ReadyConditionBuilder(::flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - ::flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); - return o; - } -}; - -inline ::flatbuffers::Offset CreateReadyCondition( - ::flatbuffers::FlatBufferBuilder &_fbb, - ::flatbuffers::Optional process_state = ::flatbuffers::nullopt) { - ReadyConditionBuilder builder_(_fbb); - if(process_state) { builder_.add_process_state(*process_state); } - return builder_.Finish(); -} - -struct ComponentProperties FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef ComponentPropertiesBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_BINARY_NAME = 4, - VT_APPLICATION_PROFILE = 6, - VT_DEPENDS_ON = 8, - VT_PROCESS_ARGUMENTS = 10, - VT_READY_CONDITION = 12 - }; - const ::flatbuffers::String *binary_name() const { - return GetPointer(VT_BINARY_NAME); - } - const score::launch_manager::config::fb::ApplicationProfile *application_profile() const { - return GetPointer(VT_APPLICATION_PROFILE); - } - const ::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>> *depends_on() const { - return GetPointer> *>(VT_DEPENDS_ON); - } - const ::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>> *process_arguments() const { - return GetPointer> *>(VT_PROCESS_ARGUMENTS); - } - const score::launch_manager::config::fb::ReadyCondition *ready_condition() const { - return GetPointer(VT_READY_CONDITION); - } - template - bool Verify(::flatbuffers::VerifierTemplate &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffsetRequired(verifier, VT_BINARY_NAME) && - verifier.VerifyString(binary_name()) && - VerifyOffsetRequired(verifier, VT_APPLICATION_PROFILE) && - verifier.VerifyTable(application_profile()) && - VerifyOffset(verifier, VT_DEPENDS_ON) && - verifier.VerifyVector(depends_on()) && - verifier.VerifyVectorOfStrings(depends_on()) && - VerifyOffset(verifier, VT_PROCESS_ARGUMENTS) && - verifier.VerifyVector(process_arguments()) && - verifier.VerifyVectorOfStrings(process_arguments()) && - VerifyOffsetRequired(verifier, VT_READY_CONDITION) && - verifier.VerifyTable(ready_condition()) && - verifier.EndTable(); - } -}; - -struct ComponentPropertiesBuilder { - typedef ComponentProperties Table; - ::flatbuffers::FlatBufferBuilder &fbb_; - ::flatbuffers::uoffset_t start_; - void add_binary_name(::flatbuffers::Offset<::flatbuffers::String> binary_name) { - fbb_.AddOffset(ComponentProperties::VT_BINARY_NAME, binary_name); - } - void add_application_profile(::flatbuffers::Offset application_profile) { - fbb_.AddOffset(ComponentProperties::VT_APPLICATION_PROFILE, application_profile); - } - void add_depends_on(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>> depends_on) { - fbb_.AddOffset(ComponentProperties::VT_DEPENDS_ON, depends_on); - } - void add_process_arguments(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>> process_arguments) { - fbb_.AddOffset(ComponentProperties::VT_PROCESS_ARGUMENTS, process_arguments); - } - void add_ready_condition(::flatbuffers::Offset ready_condition) { - fbb_.AddOffset(ComponentProperties::VT_READY_CONDITION, ready_condition); - } - explicit ComponentPropertiesBuilder(::flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - ::flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); - fbb_.Required(o, ComponentProperties::VT_BINARY_NAME); - fbb_.Required(o, ComponentProperties::VT_APPLICATION_PROFILE); - fbb_.Required(o, ComponentProperties::VT_READY_CONDITION); - return o; - } -}; - -inline ::flatbuffers::Offset CreateComponentProperties( - ::flatbuffers::FlatBufferBuilder &_fbb, - ::flatbuffers::Offset<::flatbuffers::String> binary_name = 0, - ::flatbuffers::Offset application_profile = 0, - ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>> depends_on = 0, - ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>> process_arguments = 0, - ::flatbuffers::Offset ready_condition = 0) { - ComponentPropertiesBuilder builder_(_fbb); - builder_.add_ready_condition(ready_condition); - builder_.add_process_arguments(process_arguments); - builder_.add_depends_on(depends_on); - builder_.add_application_profile(application_profile); - builder_.add_binary_name(binary_name); - return builder_.Finish(); -} - -inline ::flatbuffers::Offset CreateComponentPropertiesDirect( - ::flatbuffers::FlatBufferBuilder &_fbb, - const char *binary_name = nullptr, - ::flatbuffers::Offset application_profile = 0, - const std::vector<::flatbuffers::Offset<::flatbuffers::String>> *depends_on = nullptr, - const std::vector<::flatbuffers::Offset<::flatbuffers::String>> *process_arguments = nullptr, - ::flatbuffers::Offset ready_condition = 0) { - auto binary_name__ = binary_name ? _fbb.CreateString(binary_name) : 0; - auto depends_on__ = depends_on ? _fbb.CreateVector<::flatbuffers::Offset<::flatbuffers::String>>(*depends_on) : 0; - auto process_arguments__ = process_arguments ? _fbb.CreateVector<::flatbuffers::Offset<::flatbuffers::String>>(*process_arguments) : 0; - return score::launch_manager::config::fb::CreateComponentProperties( - _fbb, - binary_name__, - application_profile, - depends_on__, - process_arguments__, - ready_condition); -} - -struct RestartAction FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef RestartActionBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_NUMBER_OF_ATTEMPTS = 4, - VT_DELAY_BEFORE_RESTART = 6 - }; - uint32_t number_of_attempts() const { - return GetField(VT_NUMBER_OF_ATTEMPTS, 0); - } - double delay_before_restart() const { - return GetField(VT_DELAY_BEFORE_RESTART, 0.0); - } - template - bool Verify(::flatbuffers::VerifierTemplate &verifier) const { - return VerifyTableStart(verifier) && - VerifyField(verifier, VT_NUMBER_OF_ATTEMPTS, 4) && - VerifyField(verifier, VT_DELAY_BEFORE_RESTART, 8) && - verifier.EndTable(); - } -}; - -struct RestartActionBuilder { - typedef RestartAction Table; - ::flatbuffers::FlatBufferBuilder &fbb_; - ::flatbuffers::uoffset_t start_; - void add_number_of_attempts(uint32_t number_of_attempts) { - fbb_.AddElement(RestartAction::VT_NUMBER_OF_ATTEMPTS, number_of_attempts, 0); - } - void add_delay_before_restart(double delay_before_restart) { - fbb_.AddElement(RestartAction::VT_DELAY_BEFORE_RESTART, delay_before_restart, 0.0); - } - explicit RestartActionBuilder(::flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - ::flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); - return o; - } -}; - -inline ::flatbuffers::Offset CreateRestartAction( - ::flatbuffers::FlatBufferBuilder &_fbb, - uint32_t number_of_attempts = 0, - double delay_before_restart = 0.0) { - RestartActionBuilder builder_(_fbb); - builder_.add_delay_before_restart(delay_before_restart); - builder_.add_number_of_attempts(number_of_attempts); - return builder_.Finish(); -} - -struct SwitchRunTargetAction FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef SwitchRunTargetActionBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_RUN_TARGET = 4 - }; - const ::flatbuffers::String *run_target() const { - return GetPointer(VT_RUN_TARGET); - } - template - bool Verify(::flatbuffers::VerifierTemplate &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffsetRequired(verifier, VT_RUN_TARGET) && - verifier.VerifyString(run_target()) && - verifier.EndTable(); - } -}; - -struct SwitchRunTargetActionBuilder { - typedef SwitchRunTargetAction Table; - ::flatbuffers::FlatBufferBuilder &fbb_; - ::flatbuffers::uoffset_t start_; - void add_run_target(::flatbuffers::Offset<::flatbuffers::String> run_target) { - fbb_.AddOffset(SwitchRunTargetAction::VT_RUN_TARGET, run_target); - } - explicit SwitchRunTargetActionBuilder(::flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - ::flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); - fbb_.Required(o, SwitchRunTargetAction::VT_RUN_TARGET); - return o; - } -}; - -inline ::flatbuffers::Offset CreateSwitchRunTargetAction( - ::flatbuffers::FlatBufferBuilder &_fbb, - ::flatbuffers::Offset<::flatbuffers::String> run_target = 0) { - SwitchRunTargetActionBuilder builder_(_fbb); - builder_.add_run_target(run_target); - return builder_.Finish(); -} - -inline ::flatbuffers::Offset CreateSwitchRunTargetActionDirect( - ::flatbuffers::FlatBufferBuilder &_fbb, - const char *run_target = nullptr) { - auto run_target__ = run_target ? _fbb.CreateString(run_target) : 0; - return score::launch_manager::config::fb::CreateSwitchRunTargetAction( - _fbb, - run_target__); -} - -struct EnvironmentalVariable FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef EnvironmentalVariableBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_KEY = 4, - VT_VALUE = 6 - }; - const ::flatbuffers::String *key() const { - return GetPointer(VT_KEY); - } - const ::flatbuffers::String *value() const { - return GetPointer(VT_VALUE); - } - template - bool Verify(::flatbuffers::VerifierTemplate &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffsetRequired(verifier, VT_KEY) && - verifier.VerifyString(key()) && - VerifyOffsetRequired(verifier, VT_VALUE) && - verifier.VerifyString(value()) && - verifier.EndTable(); - } -}; - -struct EnvironmentalVariableBuilder { - typedef EnvironmentalVariable Table; - ::flatbuffers::FlatBufferBuilder &fbb_; - ::flatbuffers::uoffset_t start_; - void add_key(::flatbuffers::Offset<::flatbuffers::String> key) { - fbb_.AddOffset(EnvironmentalVariable::VT_KEY, key); - } - void add_value(::flatbuffers::Offset<::flatbuffers::String> value) { - fbb_.AddOffset(EnvironmentalVariable::VT_VALUE, value); - } - explicit EnvironmentalVariableBuilder(::flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - ::flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); - fbb_.Required(o, EnvironmentalVariable::VT_KEY); - fbb_.Required(o, EnvironmentalVariable::VT_VALUE); - return o; - } -}; - -inline ::flatbuffers::Offset CreateEnvironmentalVariable( - ::flatbuffers::FlatBufferBuilder &_fbb, - ::flatbuffers::Offset<::flatbuffers::String> key = 0, - ::flatbuffers::Offset<::flatbuffers::String> value = 0) { - EnvironmentalVariableBuilder builder_(_fbb); - builder_.add_value(value); - builder_.add_key(key); - return builder_.Finish(); -} - -inline ::flatbuffers::Offset CreateEnvironmentalVariableDirect( - ::flatbuffers::FlatBufferBuilder &_fbb, - const char *key = nullptr, - const char *value = nullptr) { - auto key__ = key ? _fbb.CreateString(key) : 0; - auto value__ = value ? _fbb.CreateString(value) : 0; - return score::launch_manager::config::fb::CreateEnvironmentalVariable( - _fbb, - key__, - value__); -} - -struct Sandbox FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef SandboxBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_UID = 4, - VT_GID = 6, - VT_SUPPLEMENTARY_GROUP_IDS = 8, - VT_SECURITY_POLICY = 10, - VT_SCHEDULING_POLICY = 12, - VT_SCHEDULING_PRIORITY = 14, - VT_MAX_MEMORY_USAGE = 16, - VT_MAX_CPU_USAGE = 18 - }; - uint32_t uid() const { - return GetField(VT_UID, 0); - } - uint32_t gid() const { - return GetField(VT_GID, 0); - } - const ::flatbuffers::Vector *supplementary_group_ids() const { - return GetPointer *>(VT_SUPPLEMENTARY_GROUP_IDS); - } - const ::flatbuffers::String *security_policy() const { - return GetPointer(VT_SECURITY_POLICY); - } - const ::flatbuffers::String *scheduling_policy() const { - return GetPointer(VT_SCHEDULING_POLICY); - } - ::flatbuffers::Optional scheduling_priority() const { - return GetOptional(VT_SCHEDULING_PRIORITY); - } - ::flatbuffers::Optional max_memory_usage() const { - return GetOptional(VT_MAX_MEMORY_USAGE); - } - ::flatbuffers::Optional max_cpu_usage() const { - return GetOptional(VT_MAX_CPU_USAGE); - } - template - bool Verify(::flatbuffers::VerifierTemplate &verifier) const { - return VerifyTableStart(verifier) && - VerifyField(verifier, VT_UID, 4) && - VerifyField(verifier, VT_GID, 4) && - VerifyOffset(verifier, VT_SUPPLEMENTARY_GROUP_IDS) && - verifier.VerifyVector(supplementary_group_ids()) && - VerifyOffset(verifier, VT_SECURITY_POLICY) && - verifier.VerifyString(security_policy()) && - VerifyOffset(verifier, VT_SCHEDULING_POLICY) && - verifier.VerifyString(scheduling_policy()) && - VerifyField(verifier, VT_SCHEDULING_PRIORITY, 4) && - VerifyField(verifier, VT_MAX_MEMORY_USAGE, 8) && - VerifyField(verifier, VT_MAX_CPU_USAGE, 4) && - verifier.EndTable(); - } -}; - -struct SandboxBuilder { - typedef Sandbox Table; - ::flatbuffers::FlatBufferBuilder &fbb_; - ::flatbuffers::uoffset_t start_; - void add_uid(uint32_t uid) { - fbb_.AddElement(Sandbox::VT_UID, uid, 0); - } - void add_gid(uint32_t gid) { - fbb_.AddElement(Sandbox::VT_GID, gid, 0); - } - void add_supplementary_group_ids(::flatbuffers::Offset<::flatbuffers::Vector> supplementary_group_ids) { - fbb_.AddOffset(Sandbox::VT_SUPPLEMENTARY_GROUP_IDS, supplementary_group_ids); - } - void add_security_policy(::flatbuffers::Offset<::flatbuffers::String> security_policy) { - fbb_.AddOffset(Sandbox::VT_SECURITY_POLICY, security_policy); - } - void add_scheduling_policy(::flatbuffers::Offset<::flatbuffers::String> scheduling_policy) { - fbb_.AddOffset(Sandbox::VT_SCHEDULING_POLICY, scheduling_policy); - } - void add_scheduling_priority(int32_t scheduling_priority) { - fbb_.AddElement(Sandbox::VT_SCHEDULING_PRIORITY, scheduling_priority); - } - void add_max_memory_usage(uint64_t max_memory_usage) { - fbb_.AddElement(Sandbox::VT_MAX_MEMORY_USAGE, max_memory_usage); - } - void add_max_cpu_usage(uint32_t max_cpu_usage) { - fbb_.AddElement(Sandbox::VT_MAX_CPU_USAGE, max_cpu_usage); - } - explicit SandboxBuilder(::flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - ::flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); - return o; - } -}; - -inline ::flatbuffers::Offset CreateSandbox( - ::flatbuffers::FlatBufferBuilder &_fbb, - uint32_t uid = 0, - uint32_t gid = 0, - ::flatbuffers::Offset<::flatbuffers::Vector> supplementary_group_ids = 0, - ::flatbuffers::Offset<::flatbuffers::String> security_policy = 0, - ::flatbuffers::Offset<::flatbuffers::String> scheduling_policy = 0, - ::flatbuffers::Optional scheduling_priority = ::flatbuffers::nullopt, - ::flatbuffers::Optional max_memory_usage = ::flatbuffers::nullopt, - ::flatbuffers::Optional max_cpu_usage = ::flatbuffers::nullopt) { - SandboxBuilder builder_(_fbb); - if(max_memory_usage) { builder_.add_max_memory_usage(*max_memory_usage); } - if(max_cpu_usage) { builder_.add_max_cpu_usage(*max_cpu_usage); } - if(scheduling_priority) { builder_.add_scheduling_priority(*scheduling_priority); } - builder_.add_scheduling_policy(scheduling_policy); - builder_.add_security_policy(security_policy); - builder_.add_supplementary_group_ids(supplementary_group_ids); - builder_.add_gid(gid); - builder_.add_uid(uid); - return builder_.Finish(); -} - -inline ::flatbuffers::Offset CreateSandboxDirect( - ::flatbuffers::FlatBufferBuilder &_fbb, - uint32_t uid = 0, - uint32_t gid = 0, - const std::vector *supplementary_group_ids = nullptr, - const char *security_policy = nullptr, - const char *scheduling_policy = nullptr, - ::flatbuffers::Optional scheduling_priority = ::flatbuffers::nullopt, - ::flatbuffers::Optional max_memory_usage = ::flatbuffers::nullopt, - ::flatbuffers::Optional max_cpu_usage = ::flatbuffers::nullopt) { - auto supplementary_group_ids__ = supplementary_group_ids ? _fbb.CreateVector(*supplementary_group_ids) : 0; - auto security_policy__ = security_policy ? _fbb.CreateString(security_policy) : 0; - auto scheduling_policy__ = scheduling_policy ? _fbb.CreateString(scheduling_policy) : 0; - return score::launch_manager::config::fb::CreateSandbox( - _fbb, - uid, - gid, - supplementary_group_ids__, - security_policy__, - scheduling_policy__, - scheduling_priority, - max_memory_usage, - max_cpu_usage); -} - -struct DeploymentConfig FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef DeploymentConfigBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_READY_TIMEOUT = 4, - VT_SHUTDOWN_TIMEOUT = 6, - VT_ENVIRONMENTAL_VARIABLES = 8, - VT_BIN_DIR = 10, - VT_WORKING_DIR = 12, - VT_READY_RECOVERY_ACTION = 14, - VT_RECOVERY_ACTION_TYPE = 16, - VT_RECOVERY_ACTION = 18, - VT_SANDBOX = 20 - }; - double ready_timeout() const { - return GetField(VT_READY_TIMEOUT, 0.0); - } - double shutdown_timeout() const { - return GetField(VT_SHUTDOWN_TIMEOUT, 0.0); - } - const ::flatbuffers::Vector<::flatbuffers::Offset> *environmental_variables() const { - return GetPointer> *>(VT_ENVIRONMENTAL_VARIABLES); - } - const ::flatbuffers::String *bin_dir() const { - return GetPointer(VT_BIN_DIR); - } - const ::flatbuffers::String *working_dir() const { - return GetPointer(VT_WORKING_DIR); - } - const score::launch_manager::config::fb::RestartAction *ready_recovery_action() const { - return GetPointer(VT_READY_RECOVERY_ACTION); - } - score::launch_manager::config::fb::RecoveryAction recovery_action_type() const { - return static_cast(GetField(VT_RECOVERY_ACTION_TYPE, 0)); - } - const void *recovery_action() const { - return GetPointer(VT_RECOVERY_ACTION); - } - template const T *recovery_action_as() const; - const score::launch_manager::config::fb::RestartAction *recovery_action_as_RestartAction() const { - return recovery_action_type() == score::launch_manager::config::fb::RecoveryAction_RestartAction ? static_cast(recovery_action()) : nullptr; - } - const score::launch_manager::config::fb::SwitchRunTargetAction *recovery_action_as_SwitchRunTargetAction() const { - return recovery_action_type() == score::launch_manager::config::fb::RecoveryAction_SwitchRunTargetAction ? static_cast(recovery_action()) : nullptr; - } - const score::launch_manager::config::fb::Sandbox *sandbox() const { - return GetPointer(VT_SANDBOX); - } - template - bool Verify(::flatbuffers::VerifierTemplate &verifier) const { - return VerifyTableStart(verifier) && - VerifyField(verifier, VT_READY_TIMEOUT, 8) && - VerifyField(verifier, VT_SHUTDOWN_TIMEOUT, 8) && - VerifyOffset(verifier, VT_ENVIRONMENTAL_VARIABLES) && - verifier.VerifyVector(environmental_variables()) && - verifier.VerifyVectorOfTables(environmental_variables()) && - VerifyOffsetRequired(verifier, VT_BIN_DIR) && - verifier.VerifyString(bin_dir()) && - VerifyOffset(verifier, VT_WORKING_DIR) && - verifier.VerifyString(working_dir()) && - VerifyOffset(verifier, VT_READY_RECOVERY_ACTION) && - verifier.VerifyTable(ready_recovery_action()) && - VerifyField(verifier, VT_RECOVERY_ACTION_TYPE, 1) && - VerifyOffset(verifier, VT_RECOVERY_ACTION) && - VerifyRecoveryAction(verifier, recovery_action(), recovery_action_type()) && - VerifyOffset(verifier, VT_SANDBOX) && - verifier.VerifyTable(sandbox()) && - verifier.EndTable(); - } -}; - -template<> inline const score::launch_manager::config::fb::RestartAction *DeploymentConfig::recovery_action_as() const { - return recovery_action_as_RestartAction(); -} - -template<> inline const score::launch_manager::config::fb::SwitchRunTargetAction *DeploymentConfig::recovery_action_as() const { - return recovery_action_as_SwitchRunTargetAction(); -} - -struct DeploymentConfigBuilder { - typedef DeploymentConfig Table; - ::flatbuffers::FlatBufferBuilder &fbb_; - ::flatbuffers::uoffset_t start_; - void add_ready_timeout(double ready_timeout) { - fbb_.AddElement(DeploymentConfig::VT_READY_TIMEOUT, ready_timeout, 0.0); - } - void add_shutdown_timeout(double shutdown_timeout) { - fbb_.AddElement(DeploymentConfig::VT_SHUTDOWN_TIMEOUT, shutdown_timeout, 0.0); - } - void add_environmental_variables(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> environmental_variables) { - fbb_.AddOffset(DeploymentConfig::VT_ENVIRONMENTAL_VARIABLES, environmental_variables); - } - void add_bin_dir(::flatbuffers::Offset<::flatbuffers::String> bin_dir) { - fbb_.AddOffset(DeploymentConfig::VT_BIN_DIR, bin_dir); - } - void add_working_dir(::flatbuffers::Offset<::flatbuffers::String> working_dir) { - fbb_.AddOffset(DeploymentConfig::VT_WORKING_DIR, working_dir); - } - void add_ready_recovery_action(::flatbuffers::Offset ready_recovery_action) { - fbb_.AddOffset(DeploymentConfig::VT_READY_RECOVERY_ACTION, ready_recovery_action); - } - void add_recovery_action_type(score::launch_manager::config::fb::RecoveryAction recovery_action_type) { - fbb_.AddElement(DeploymentConfig::VT_RECOVERY_ACTION_TYPE, static_cast(recovery_action_type), 0); - } - void add_recovery_action(::flatbuffers::Offset recovery_action) { - fbb_.AddOffset(DeploymentConfig::VT_RECOVERY_ACTION, recovery_action); - } - void add_sandbox(::flatbuffers::Offset sandbox) { - fbb_.AddOffset(DeploymentConfig::VT_SANDBOX, sandbox); - } - explicit DeploymentConfigBuilder(::flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - ::flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); - fbb_.Required(o, DeploymentConfig::VT_BIN_DIR); - return o; - } -}; - -inline ::flatbuffers::Offset CreateDeploymentConfig( - ::flatbuffers::FlatBufferBuilder &_fbb, - double ready_timeout = 0.0, - double shutdown_timeout = 0.0, - ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> environmental_variables = 0, - ::flatbuffers::Offset<::flatbuffers::String> bin_dir = 0, - ::flatbuffers::Offset<::flatbuffers::String> working_dir = 0, - ::flatbuffers::Offset ready_recovery_action = 0, - score::launch_manager::config::fb::RecoveryAction recovery_action_type = score::launch_manager::config::fb::RecoveryAction_NONE, - ::flatbuffers::Offset recovery_action = 0, - ::flatbuffers::Offset sandbox = 0) { - DeploymentConfigBuilder builder_(_fbb); - builder_.add_shutdown_timeout(shutdown_timeout); - builder_.add_ready_timeout(ready_timeout); - builder_.add_sandbox(sandbox); - builder_.add_recovery_action(recovery_action); - builder_.add_ready_recovery_action(ready_recovery_action); - builder_.add_working_dir(working_dir); - builder_.add_bin_dir(bin_dir); - builder_.add_environmental_variables(environmental_variables); - builder_.add_recovery_action_type(recovery_action_type); - return builder_.Finish(); -} - -inline ::flatbuffers::Offset CreateDeploymentConfigDirect( - ::flatbuffers::FlatBufferBuilder &_fbb, - double ready_timeout = 0.0, - double shutdown_timeout = 0.0, - const std::vector<::flatbuffers::Offset> *environmental_variables = nullptr, - const char *bin_dir = nullptr, - const char *working_dir = nullptr, - ::flatbuffers::Offset ready_recovery_action = 0, - score::launch_manager::config::fb::RecoveryAction recovery_action_type = score::launch_manager::config::fb::RecoveryAction_NONE, - ::flatbuffers::Offset recovery_action = 0, - ::flatbuffers::Offset sandbox = 0) { - auto environmental_variables__ = environmental_variables ? _fbb.CreateVector<::flatbuffers::Offset>(*environmental_variables) : 0; - auto bin_dir__ = bin_dir ? _fbb.CreateString(bin_dir) : 0; - auto working_dir__ = working_dir ? _fbb.CreateString(working_dir) : 0; - return score::launch_manager::config::fb::CreateDeploymentConfig( - _fbb, - ready_timeout, - shutdown_timeout, - environmental_variables__, - bin_dir__, - working_dir__, - ready_recovery_action, - recovery_action_type, - recovery_action, - sandbox); -} - -struct RunTarget FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef RunTargetBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_NAME = 4, - VT_DESCRIPTION = 6, - VT_DEPENDS_ON = 8, - VT_TRANSITION_TIMEOUT = 10, - VT_RECOVERY_ACTION_TYPE = 12, - VT_RECOVERY_ACTION = 14 - }; - const ::flatbuffers::String *name() const { - return GetPointer(VT_NAME); - } - const ::flatbuffers::String *description() const { - return GetPointer(VT_DESCRIPTION); - } - const ::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>> *depends_on() const { - return GetPointer> *>(VT_DEPENDS_ON); - } - double transition_timeout() const { - return GetField(VT_TRANSITION_TIMEOUT, 0.0); - } - score::launch_manager::config::fb::RecoveryAction recovery_action_type() const { - return static_cast(GetField(VT_RECOVERY_ACTION_TYPE, 0)); - } - const void *recovery_action() const { - return GetPointer(VT_RECOVERY_ACTION); - } - template const T *recovery_action_as() const; - const score::launch_manager::config::fb::RestartAction *recovery_action_as_RestartAction() const { - return recovery_action_type() == score::launch_manager::config::fb::RecoveryAction_RestartAction ? static_cast(recovery_action()) : nullptr; - } - const score::launch_manager::config::fb::SwitchRunTargetAction *recovery_action_as_SwitchRunTargetAction() const { - return recovery_action_type() == score::launch_manager::config::fb::RecoveryAction_SwitchRunTargetAction ? static_cast(recovery_action()) : nullptr; - } - template - bool Verify(::flatbuffers::VerifierTemplate &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffsetRequired(verifier, VT_NAME) && - verifier.VerifyString(name()) && - VerifyOffset(verifier, VT_DESCRIPTION) && - verifier.VerifyString(description()) && - VerifyOffset(verifier, VT_DEPENDS_ON) && - verifier.VerifyVector(depends_on()) && - verifier.VerifyVectorOfStrings(depends_on()) && - VerifyField(verifier, VT_TRANSITION_TIMEOUT, 8) && - VerifyField(verifier, VT_RECOVERY_ACTION_TYPE, 1) && - VerifyOffsetRequired(verifier, VT_RECOVERY_ACTION) && - VerifyRecoveryAction(verifier, recovery_action(), recovery_action_type()) && - verifier.EndTable(); - } -}; - -template<> inline const score::launch_manager::config::fb::RestartAction *RunTarget::recovery_action_as() const { - return recovery_action_as_RestartAction(); -} - -template<> inline const score::launch_manager::config::fb::SwitchRunTargetAction *RunTarget::recovery_action_as() const { - return recovery_action_as_SwitchRunTargetAction(); -} - -struct RunTargetBuilder { - typedef RunTarget Table; - ::flatbuffers::FlatBufferBuilder &fbb_; - ::flatbuffers::uoffset_t start_; - void add_name(::flatbuffers::Offset<::flatbuffers::String> name) { - fbb_.AddOffset(RunTarget::VT_NAME, name); - } - void add_description(::flatbuffers::Offset<::flatbuffers::String> description) { - fbb_.AddOffset(RunTarget::VT_DESCRIPTION, description); - } - void add_depends_on(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>> depends_on) { - fbb_.AddOffset(RunTarget::VT_DEPENDS_ON, depends_on); - } - void add_transition_timeout(double transition_timeout) { - fbb_.AddElement(RunTarget::VT_TRANSITION_TIMEOUT, transition_timeout, 0.0); - } - void add_recovery_action_type(score::launch_manager::config::fb::RecoveryAction recovery_action_type) { - fbb_.AddElement(RunTarget::VT_RECOVERY_ACTION_TYPE, static_cast(recovery_action_type), 0); - } - void add_recovery_action(::flatbuffers::Offset recovery_action) { - fbb_.AddOffset(RunTarget::VT_RECOVERY_ACTION, recovery_action); - } - explicit RunTargetBuilder(::flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - ::flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); - fbb_.Required(o, RunTarget::VT_NAME); - fbb_.Required(o, RunTarget::VT_RECOVERY_ACTION); - return o; - } -}; - -inline ::flatbuffers::Offset CreateRunTarget( - ::flatbuffers::FlatBufferBuilder &_fbb, - ::flatbuffers::Offset<::flatbuffers::String> name = 0, - ::flatbuffers::Offset<::flatbuffers::String> description = 0, - ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>> depends_on = 0, - double transition_timeout = 0.0, - score::launch_manager::config::fb::RecoveryAction recovery_action_type = score::launch_manager::config::fb::RecoveryAction_NONE, - ::flatbuffers::Offset recovery_action = 0) { - RunTargetBuilder builder_(_fbb); - builder_.add_transition_timeout(transition_timeout); - builder_.add_recovery_action(recovery_action); - builder_.add_depends_on(depends_on); - builder_.add_description(description); - builder_.add_name(name); - builder_.add_recovery_action_type(recovery_action_type); - return builder_.Finish(); -} - -inline ::flatbuffers::Offset CreateRunTargetDirect( - ::flatbuffers::FlatBufferBuilder &_fbb, - const char *name = nullptr, - const char *description = nullptr, - const std::vector<::flatbuffers::Offset<::flatbuffers::String>> *depends_on = nullptr, - double transition_timeout = 0.0, - score::launch_manager::config::fb::RecoveryAction recovery_action_type = score::launch_manager::config::fb::RecoveryAction_NONE, - ::flatbuffers::Offset recovery_action = 0) { - auto name__ = name ? _fbb.CreateString(name) : 0; - auto description__ = description ? _fbb.CreateString(description) : 0; - auto depends_on__ = depends_on ? _fbb.CreateVector<::flatbuffers::Offset<::flatbuffers::String>>(*depends_on) : 0; - return score::launch_manager::config::fb::CreateRunTarget( - _fbb, - name__, - description__, - depends_on__, - transition_timeout, - recovery_action_type, - recovery_action); -} - -struct Component FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef ComponentBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_NAME = 4, - VT_DESCRIPTION = 6, - VT_COMPONENT_PROPERTIES = 8, - VT_DEPLOYMENT_CONFIG = 10 - }; - const ::flatbuffers::String *name() const { - return GetPointer(VT_NAME); - } - const ::flatbuffers::String *description() const { - return GetPointer(VT_DESCRIPTION); - } - const score::launch_manager::config::fb::ComponentProperties *component_properties() const { - return GetPointer(VT_COMPONENT_PROPERTIES); - } - const score::launch_manager::config::fb::DeploymentConfig *deployment_config() const { - return GetPointer(VT_DEPLOYMENT_CONFIG); - } - template - bool Verify(::flatbuffers::VerifierTemplate &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffsetRequired(verifier, VT_NAME) && - verifier.VerifyString(name()) && - VerifyOffset(verifier, VT_DESCRIPTION) && - verifier.VerifyString(description()) && - VerifyOffsetRequired(verifier, VT_COMPONENT_PROPERTIES) && - verifier.VerifyTable(component_properties()) && - VerifyOffsetRequired(verifier, VT_DEPLOYMENT_CONFIG) && - verifier.VerifyTable(deployment_config()) && - verifier.EndTable(); - } -}; - -struct ComponentBuilder { - typedef Component Table; - ::flatbuffers::FlatBufferBuilder &fbb_; - ::flatbuffers::uoffset_t start_; - void add_name(::flatbuffers::Offset<::flatbuffers::String> name) { - fbb_.AddOffset(Component::VT_NAME, name); - } - void add_description(::flatbuffers::Offset<::flatbuffers::String> description) { - fbb_.AddOffset(Component::VT_DESCRIPTION, description); - } - void add_component_properties(::flatbuffers::Offset component_properties) { - fbb_.AddOffset(Component::VT_COMPONENT_PROPERTIES, component_properties); - } - void add_deployment_config(::flatbuffers::Offset deployment_config) { - fbb_.AddOffset(Component::VT_DEPLOYMENT_CONFIG, deployment_config); - } - explicit ComponentBuilder(::flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - ::flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); - fbb_.Required(o, Component::VT_NAME); - fbb_.Required(o, Component::VT_COMPONENT_PROPERTIES); - fbb_.Required(o, Component::VT_DEPLOYMENT_CONFIG); - return o; - } -}; - -inline ::flatbuffers::Offset CreateComponent( - ::flatbuffers::FlatBufferBuilder &_fbb, - ::flatbuffers::Offset<::flatbuffers::String> name = 0, - ::flatbuffers::Offset<::flatbuffers::String> description = 0, - ::flatbuffers::Offset component_properties = 0, - ::flatbuffers::Offset deployment_config = 0) { - ComponentBuilder builder_(_fbb); - builder_.add_deployment_config(deployment_config); - builder_.add_component_properties(component_properties); - builder_.add_description(description); - builder_.add_name(name); - return builder_.Finish(); -} - -inline ::flatbuffers::Offset CreateComponentDirect( - ::flatbuffers::FlatBufferBuilder &_fbb, - const char *name = nullptr, - const char *description = nullptr, - ::flatbuffers::Offset component_properties = 0, - ::flatbuffers::Offset deployment_config = 0) { - auto name__ = name ? _fbb.CreateString(name) : 0; - auto description__ = description ? _fbb.CreateString(description) : 0; - return score::launch_manager::config::fb::CreateComponent( - _fbb, - name__, - description__, - component_properties, - deployment_config); -} - -struct AliveSupervision FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef AliveSupervisionBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_EVALUATION_CYCLE = 4 - }; - double evaluation_cycle() const { - return GetField(VT_EVALUATION_CYCLE, 0.0); - } - template - bool Verify(::flatbuffers::VerifierTemplate &verifier) const { - return VerifyTableStart(verifier) && - VerifyField(verifier, VT_EVALUATION_CYCLE, 8) && - verifier.EndTable(); - } -}; - -struct AliveSupervisionBuilder { - typedef AliveSupervision Table; - ::flatbuffers::FlatBufferBuilder &fbb_; - ::flatbuffers::uoffset_t start_; - void add_evaluation_cycle(double evaluation_cycle) { - fbb_.AddElement(AliveSupervision::VT_EVALUATION_CYCLE, evaluation_cycle, 0.0); - } - explicit AliveSupervisionBuilder(::flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - ::flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); - return o; - } -}; - -inline ::flatbuffers::Offset CreateAliveSupervision( - ::flatbuffers::FlatBufferBuilder &_fbb, - double evaluation_cycle = 0.0) { - AliveSupervisionBuilder builder_(_fbb); - builder_.add_evaluation_cycle(evaluation_cycle); - return builder_.Finish(); -} - -struct Watchdog FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef WatchdogBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_DEVICE_FILE_PATH = 4, - VT_MAX_TIMEOUT = 6, - VT_DEACTIVATE_ON_SHUTDOWN = 8, - VT_REQUIRE_MAGIC_CLOSE = 10 - }; - const ::flatbuffers::String *device_file_path() const { - return GetPointer(VT_DEVICE_FILE_PATH); - } - double max_timeout() const { - return GetField(VT_MAX_TIMEOUT, 0.0); - } - ::flatbuffers::Optional deactivate_on_shutdown() const { - return GetOptional(VT_DEACTIVATE_ON_SHUTDOWN); - } - ::flatbuffers::Optional require_magic_close() const { - return GetOptional(VT_REQUIRE_MAGIC_CLOSE); - } - template - bool Verify(::flatbuffers::VerifierTemplate &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffsetRequired(verifier, VT_DEVICE_FILE_PATH) && - verifier.VerifyString(device_file_path()) && - VerifyField(verifier, VT_MAX_TIMEOUT, 8) && - VerifyField(verifier, VT_DEACTIVATE_ON_SHUTDOWN, 1) && - VerifyField(verifier, VT_REQUIRE_MAGIC_CLOSE, 1) && - verifier.EndTable(); - } -}; - -struct WatchdogBuilder { - typedef Watchdog Table; - ::flatbuffers::FlatBufferBuilder &fbb_; - ::flatbuffers::uoffset_t start_; - void add_device_file_path(::flatbuffers::Offset<::flatbuffers::String> device_file_path) { - fbb_.AddOffset(Watchdog::VT_DEVICE_FILE_PATH, device_file_path); - } - void add_max_timeout(double max_timeout) { - fbb_.AddElement(Watchdog::VT_MAX_TIMEOUT, max_timeout, 0.0); - } - void add_deactivate_on_shutdown(bool deactivate_on_shutdown) { - fbb_.AddElement(Watchdog::VT_DEACTIVATE_ON_SHUTDOWN, static_cast(deactivate_on_shutdown)); - } - void add_require_magic_close(bool require_magic_close) { - fbb_.AddElement(Watchdog::VT_REQUIRE_MAGIC_CLOSE, static_cast(require_magic_close)); - } - explicit WatchdogBuilder(::flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - ::flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); - fbb_.Required(o, Watchdog::VT_DEVICE_FILE_PATH); - return o; - } -}; - -inline ::flatbuffers::Offset CreateWatchdog( - ::flatbuffers::FlatBufferBuilder &_fbb, - ::flatbuffers::Offset<::flatbuffers::String> device_file_path = 0, - double max_timeout = 0.0, - ::flatbuffers::Optional deactivate_on_shutdown = ::flatbuffers::nullopt, - ::flatbuffers::Optional require_magic_close = ::flatbuffers::nullopt) { - WatchdogBuilder builder_(_fbb); - builder_.add_max_timeout(max_timeout); - builder_.add_device_file_path(device_file_path); - if(require_magic_close) { builder_.add_require_magic_close(*require_magic_close); } - if(deactivate_on_shutdown) { builder_.add_deactivate_on_shutdown(*deactivate_on_shutdown); } - return builder_.Finish(); -} - -inline ::flatbuffers::Offset CreateWatchdogDirect( - ::flatbuffers::FlatBufferBuilder &_fbb, - const char *device_file_path = nullptr, - double max_timeout = 0.0, - ::flatbuffers::Optional deactivate_on_shutdown = ::flatbuffers::nullopt, - ::flatbuffers::Optional require_magic_close = ::flatbuffers::nullopt) { - auto device_file_path__ = device_file_path ? _fbb.CreateString(device_file_path) : 0; - return score::launch_manager::config::fb::CreateWatchdog( - _fbb, - device_file_path__, - max_timeout, - deactivate_on_shutdown, - require_magic_close); -} - -struct FallbackRunTarget FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef FallbackRunTargetBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_DESCRIPTION = 4, - VT_DEPENDS_ON = 6, - VT_TRANSITION_TIMEOUT = 8 - }; - const ::flatbuffers::String *description() const { - return GetPointer(VT_DESCRIPTION); - } - const ::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>> *depends_on() const { - return GetPointer> *>(VT_DEPENDS_ON); - } - double transition_timeout() const { - return GetField(VT_TRANSITION_TIMEOUT, 0.0); - } - template - bool Verify(::flatbuffers::VerifierTemplate &verifier) const { - return VerifyTableStart(verifier) && - VerifyOffset(verifier, VT_DESCRIPTION) && - verifier.VerifyString(description()) && - VerifyOffset(verifier, VT_DEPENDS_ON) && - verifier.VerifyVector(depends_on()) && - verifier.VerifyVectorOfStrings(depends_on()) && - VerifyField(verifier, VT_TRANSITION_TIMEOUT, 8) && - verifier.EndTable(); - } -}; - -struct FallbackRunTargetBuilder { - typedef FallbackRunTarget Table; - ::flatbuffers::FlatBufferBuilder &fbb_; - ::flatbuffers::uoffset_t start_; - void add_description(::flatbuffers::Offset<::flatbuffers::String> description) { - fbb_.AddOffset(FallbackRunTarget::VT_DESCRIPTION, description); - } - void add_depends_on(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>> depends_on) { - fbb_.AddOffset(FallbackRunTarget::VT_DEPENDS_ON, depends_on); - } - void add_transition_timeout(double transition_timeout) { - fbb_.AddElement(FallbackRunTarget::VT_TRANSITION_TIMEOUT, transition_timeout, 0.0); - } - explicit FallbackRunTargetBuilder(::flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - ::flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); - return o; - } -}; - -inline ::flatbuffers::Offset CreateFallbackRunTarget( - ::flatbuffers::FlatBufferBuilder &_fbb, - ::flatbuffers::Offset<::flatbuffers::String> description = 0, - ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>> depends_on = 0, - double transition_timeout = 0.0) { - FallbackRunTargetBuilder builder_(_fbb); - builder_.add_transition_timeout(transition_timeout); - builder_.add_depends_on(depends_on); - builder_.add_description(description); - return builder_.Finish(); -} - -inline ::flatbuffers::Offset CreateFallbackRunTargetDirect( - ::flatbuffers::FlatBufferBuilder &_fbb, - const char *description = nullptr, - const std::vector<::flatbuffers::Offset<::flatbuffers::String>> *depends_on = nullptr, - double transition_timeout = 0.0) { - auto description__ = description ? _fbb.CreateString(description) : 0; - auto depends_on__ = depends_on ? _fbb.CreateVector<::flatbuffers::Offset<::flatbuffers::String>>(*depends_on) : 0; - return score::launch_manager::config::fb::CreateFallbackRunTarget( - _fbb, - description__, - depends_on__, - transition_timeout); -} - -struct LaunchManagerConfig FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef LaunchManagerConfigBuilder Builder; - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_SCHEMA_VERSION = 4, - VT_COMPONENTS = 6, - VT_RUN_TARGETS = 8, - VT_INITIAL_RUN_TARGET = 10, - VT_FALLBACK_RUN_TARGET = 12, - VT_ALIVE_SUPERVISION = 14, - VT_WATCHDOG = 16 - }; - int32_t schema_version() const { - return GetField(VT_SCHEMA_VERSION, 0); - } - const ::flatbuffers::Vector<::flatbuffers::Offset> *components() const { - return GetPointer> *>(VT_COMPONENTS); - } - const ::flatbuffers::Vector<::flatbuffers::Offset> *run_targets() const { - return GetPointer> *>(VT_RUN_TARGETS); - } - const ::flatbuffers::String *initial_run_target() const { - return GetPointer(VT_INITIAL_RUN_TARGET); - } - const score::launch_manager::config::fb::FallbackRunTarget *fallback_run_target() const { - return GetPointer(VT_FALLBACK_RUN_TARGET); - } - const score::launch_manager::config::fb::AliveSupervision *alive_supervision() const { - return GetPointer(VT_ALIVE_SUPERVISION); - } - const score::launch_manager::config::fb::Watchdog *watchdog() const { - return GetPointer(VT_WATCHDOG); - } - template - bool Verify(::flatbuffers::VerifierTemplate &verifier) const { - return VerifyTableStart(verifier) && - VerifyField(verifier, VT_SCHEMA_VERSION, 4) && - VerifyOffset(verifier, VT_COMPONENTS) && - verifier.VerifyVector(components()) && - verifier.VerifyVectorOfTables(components()) && - VerifyOffset(verifier, VT_RUN_TARGETS) && - verifier.VerifyVector(run_targets()) && - verifier.VerifyVectorOfTables(run_targets()) && - VerifyOffsetRequired(verifier, VT_INITIAL_RUN_TARGET) && - verifier.VerifyString(initial_run_target()) && - VerifyOffsetRequired(verifier, VT_FALLBACK_RUN_TARGET) && - verifier.VerifyTable(fallback_run_target()) && - VerifyOffsetRequired(verifier, VT_ALIVE_SUPERVISION) && - verifier.VerifyTable(alive_supervision()) && - VerifyOffset(verifier, VT_WATCHDOG) && - verifier.VerifyTable(watchdog()) && - verifier.EndTable(); - } -}; - -struct LaunchManagerConfigBuilder { - typedef LaunchManagerConfig Table; - ::flatbuffers::FlatBufferBuilder &fbb_; - ::flatbuffers::uoffset_t start_; - void add_schema_version(int32_t schema_version) { - fbb_.AddElement(LaunchManagerConfig::VT_SCHEMA_VERSION, schema_version, 0); - } - void add_components(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> components) { - fbb_.AddOffset(LaunchManagerConfig::VT_COMPONENTS, components); - } - void add_run_targets(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> run_targets) { - fbb_.AddOffset(LaunchManagerConfig::VT_RUN_TARGETS, run_targets); - } - void add_initial_run_target(::flatbuffers::Offset<::flatbuffers::String> initial_run_target) { - fbb_.AddOffset(LaunchManagerConfig::VT_INITIAL_RUN_TARGET, initial_run_target); - } - void add_fallback_run_target(::flatbuffers::Offset fallback_run_target) { - fbb_.AddOffset(LaunchManagerConfig::VT_FALLBACK_RUN_TARGET, fallback_run_target); - } - void add_alive_supervision(::flatbuffers::Offset alive_supervision) { - fbb_.AddOffset(LaunchManagerConfig::VT_ALIVE_SUPERVISION, alive_supervision); - } - void add_watchdog(::flatbuffers::Offset watchdog) { - fbb_.AddOffset(LaunchManagerConfig::VT_WATCHDOG, watchdog); - } - explicit LaunchManagerConfigBuilder(::flatbuffers::FlatBufferBuilder &_fbb) - : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - ::flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); - fbb_.Required(o, LaunchManagerConfig::VT_INITIAL_RUN_TARGET); - fbb_.Required(o, LaunchManagerConfig::VT_FALLBACK_RUN_TARGET); - fbb_.Required(o, LaunchManagerConfig::VT_ALIVE_SUPERVISION); - return o; - } -}; - -inline ::flatbuffers::Offset CreateLaunchManagerConfig( - ::flatbuffers::FlatBufferBuilder &_fbb, - int32_t schema_version = 0, - ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> components = 0, - ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> run_targets = 0, - ::flatbuffers::Offset<::flatbuffers::String> initial_run_target = 0, - ::flatbuffers::Offset fallback_run_target = 0, - ::flatbuffers::Offset alive_supervision = 0, - ::flatbuffers::Offset watchdog = 0) { - LaunchManagerConfigBuilder builder_(_fbb); - builder_.add_watchdog(watchdog); - builder_.add_alive_supervision(alive_supervision); - builder_.add_fallback_run_target(fallback_run_target); - builder_.add_initial_run_target(initial_run_target); - builder_.add_run_targets(run_targets); - builder_.add_components(components); - builder_.add_schema_version(schema_version); - return builder_.Finish(); -} - -inline ::flatbuffers::Offset CreateLaunchManagerConfigDirect( - ::flatbuffers::FlatBufferBuilder &_fbb, - int32_t schema_version = 0, - const std::vector<::flatbuffers::Offset> *components = nullptr, - const std::vector<::flatbuffers::Offset> *run_targets = nullptr, - const char *initial_run_target = nullptr, - ::flatbuffers::Offset fallback_run_target = 0, - ::flatbuffers::Offset alive_supervision = 0, - ::flatbuffers::Offset watchdog = 0) { - auto components__ = components ? _fbb.CreateVector<::flatbuffers::Offset>(*components) : 0; - auto run_targets__ = run_targets ? _fbb.CreateVector<::flatbuffers::Offset>(*run_targets) : 0; - auto initial_run_target__ = initial_run_target ? _fbb.CreateString(initial_run_target) : 0; - return score::launch_manager::config::fb::CreateLaunchManagerConfig( - _fbb, - schema_version, - components__, - run_targets__, - initial_run_target__, - fallback_run_target, - alive_supervision, - watchdog); -} - -template -inline bool VerifyRecoveryAction(::flatbuffers::VerifierTemplate &verifier, const void *obj, RecoveryAction type) { - switch (type) { - case RecoveryAction_NONE: { - return true; - } - case RecoveryAction_RestartAction: { - auto ptr = reinterpret_cast(obj); - return verifier.VerifyTable(ptr); - } - case RecoveryAction_SwitchRunTargetAction: { - auto ptr = reinterpret_cast(obj); - return verifier.VerifyTable(ptr); - } - default: return true; - } -} - -template -inline bool VerifyRecoveryActionVector(::flatbuffers::VerifierTemplate &verifier, const ::flatbuffers::Vector<::flatbuffers::Offset> *values, const ::flatbuffers::Vector *types) { - if (!values || !types) return !values && !types; - if (values->size() != types->size()) return false; - for (::flatbuffers::uoffset_t i = 0; i < values->size(); ++i) { - if (!VerifyRecoveryAction( - verifier, values->Get(i), types->GetEnum(i))) { - return false; - } - } - return true; -} - -inline const score::launch_manager::config::fb::LaunchManagerConfig *GetLaunchManagerConfig(const void *buf) { - return ::flatbuffers::GetRoot(buf); -} - -inline const score::launch_manager::config::fb::LaunchManagerConfig *GetSizePrefixedLaunchManagerConfig(const void *buf) { - return ::flatbuffers::GetSizePrefixedRoot(buf); -} - -template -inline bool VerifyLaunchManagerConfigBuffer( - ::flatbuffers::VerifierTemplate &verifier) { - return verifier.template VerifyBuffer(nullptr); -} - -template -inline bool VerifySizePrefixedLaunchManagerConfigBuffer( - ::flatbuffers::VerifierTemplate &verifier) { - return verifier.template VerifySizePrefixedBuffer(nullptr); -} - -inline void FinishLaunchManagerConfigBuffer( - ::flatbuffers::FlatBufferBuilder &fbb, - ::flatbuffers::Offset root) { - fbb.Finish(root); -} - -inline void FinishSizePrefixedLaunchManagerConfigBuffer( - ::flatbuffers::FlatBufferBuilder &fbb, - ::flatbuffers::Offset root) { - fbb.FinishSizePrefixed(root); -} - -} // namespace fb -} // namespace config -} // namespace launch_manager -} // namespace score - -#endif // FLATBUFFERS_GENERATED_NEWLMFLATCFG_SCORE_LAUNCH_MANAGER_CONFIG_FB_H_ From dcaa534b1847b477d3fcf3b6676e6563baa1ddeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Fu=C3=9Fberger?= Date: Tue, 19 May 2026 07:31:40 +0200 Subject: [PATCH 06/26] Extend documentation --- .../config/include/config.hpp | 5 +++++ .../config/include/flatbuffer_config_loader.hpp | 14 +++++++++++++- .../config/src/flatbuffer_config_loader_UT.cpp | 2 +- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/launch_manager_daemon/config/include/config.hpp b/src/launch_manager_daemon/config/include/config.hpp index b48cdfe25..c39f90bff 100644 --- a/src/launch_manager_daemon/config/include/config.hpp +++ b/src/launch_manager_daemon/config/include/config.hpp @@ -126,6 +126,11 @@ struct WatchdogConfig { bool require_magic_close{}; }; +/// @brief Move-only value object holding the parsed launch-manager configuration. +/// +/// Loaded once by an IConfigLoader, then individual parts are moved out via +/// the `take_*()` accessors to transfer ownership to dedicated domain objects +/// (e.g. ComponentConfig to Component). class Config { public: Config(const Config&) = delete; diff --git a/src/launch_manager_daemon/config/include/flatbuffer_config_loader.hpp b/src/launch_manager_daemon/config/include/flatbuffer_config_loader.hpp index 8a38f40e6..3c884d30f 100644 --- a/src/launch_manager_daemon/config/include/flatbuffer_config_loader.hpp +++ b/src/launch_manager_daemon/config/include/flatbuffer_config_loader.hpp @@ -23,6 +23,7 @@ namespace score::launch_manager::config { +/// @brief Internal helpers for FlatBuffer config parsing. namespace details { score::cpp::expected parseFlatbuffer(const std::vector& buffer); @@ -30,6 +31,11 @@ IConfigLoader::Error mapOsError(const score::os::Error& error); } // namespace details +/// @brief Default buffer loader that delegates to score::flatbuffers::LoadBuffer. +/// +/// Exists as a named type so that FlatbufferConfigLoaderImpl can be parameterized on the +/// buffer-loading strategy. In production the default is used; in tests a mock +/// loader can be substituted without virtual dispatch overhead. struct DefaultBufferLoader { static score::os::Result> load(const score::filesystem::Path& path) { @@ -37,8 +43,11 @@ struct DefaultBufferLoader { } }; +/// @brief IConfigLoader implementation that reads a FlatBuffer binary file. +/// @tparam BufferLoaderT Policy type providing a static `load(path)` method. +/// Defaults to DefaultBufferLoader; replace with a mock for testing. template -class FlatbufferConfigLoader : public IConfigLoader { +class FlatbufferConfigLoaderImpl : public IConfigLoader { public: score::cpp::expected load(const score::filesystem::Path& path) override { @@ -51,6 +60,9 @@ class FlatbufferConfigLoader : public IConfigLoader { } }; +/// @brief Production-ready alias using the default buffer loader. +using FlatbufferConfigLoader = FlatbufferConfigLoaderImpl<>; + } // namespace score::launch_manager::config #endif // FLATBUFFER_CONFIG_LOADER_HPP diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp index 73fbb8a7e..1aa26c036 100644 --- a/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp @@ -140,7 +140,7 @@ class FlatbufferConfigLoaderTest : public ::testing::Test { return loader_.load(kTestPath); } - FlatbufferConfigLoader loader_; + FlatbufferConfigLoaderImpl loader_; }; // ============================================================================ From 5203bbcb4f009920aafd545e39868ead314193ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Fu=C3=9Fberger?= Date: Tue, 19 May 2026 07:37:24 +0200 Subject: [PATCH 07/26] Narrow RecoveryAction options --- .../config/include/config.hpp | 8 ++--- .../config/src/flatbuffer_config_loader.cpp | 30 ++++--------------- .../src/flatbuffer_config_loader_UT.cpp | 16 ++++------ .../config/src/new_lm_flatcfg.fbs | 10 ++----- 4 files changed, 16 insertions(+), 48 deletions(-) diff --git a/src/launch_manager_daemon/config/include/config.hpp b/src/launch_manager_daemon/config/include/config.hpp index c39f90bff..79223b25b 100644 --- a/src/launch_manager_daemon/config/include/config.hpp +++ b/src/launch_manager_daemon/config/include/config.hpp @@ -19,7 +19,6 @@ #include #include #include -#include #include namespace score::launch_manager::config { @@ -70,8 +69,6 @@ struct SwitchRunTargetAction { std::string run_target; }; -using RecoveryAction = std::variant; - struct Sandbox { uint32_t uid{}; uint32_t gid{}; @@ -90,7 +87,8 @@ struct DeploymentConfig { std::string bin_dir; std::string working_dir; std::optional ready_recovery_action; - std::optional recovery_action; + // Currently only SwitchRunTargetAction is supported here, RestartAction to be added in the future + std::optional recovery_action; std::optional sandbox; }; @@ -106,7 +104,7 @@ struct RunTargetConfig { std::string description; std::vector depends_on; uint32_t transition_timeout_ms{}; - std::optional recovery_action; + std::optional recovery_action; }; struct FallbackRunTargetConfig { diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp index c89cbb790..a74cd4aa4 100644 --- a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp @@ -130,31 +130,13 @@ std::optional convertRestartAction(const fb::RestartAction* ra) return RestartAction{ra->number_of_attempts(), secondsToMs(ra->delay_before_restart())}; } -std::optional convertRecoveryAction(fb::RecoveryAction type, const void* action) +std::optional convertSwitchRunTargetAction(const fb::SwitchRunTargetAction* sa) { - switch (type) + if (sa == nullptr) { - case fb::RecoveryAction::RestartAction: - { - const auto* ra = static_cast(action); - if (ra == nullptr) - { - return std::nullopt; - } - return RestartAction{ra->number_of_attempts(), secondsToMs(ra->delay_before_restart())}; - } - case fb::RecoveryAction::SwitchRunTargetAction: - { - const auto* sa = static_cast(action); - if (sa == nullptr) - { - return std::nullopt; - } - return SwitchRunTargetAction{safeString(sa->run_target())}; - } - default: - return std::nullopt; + return std::nullopt; } + return SwitchRunTargetAction{safeString(sa->run_target())}; } // --- Struct conversion helpers --- @@ -249,7 +231,7 @@ DeploymentConfig convertDeploymentConfig(const fb::DeploymentConfig* fb_dc) result.bin_dir = safeString(fb_dc->bin_dir()); result.working_dir = safeString(fb_dc->working_dir()); result.ready_recovery_action = convertRestartAction(fb_dc->ready_recovery_action()); - result.recovery_action = convertRecoveryAction(fb_dc->recovery_action_type(), fb_dc->recovery_action()); + result.recovery_action = convertSwitchRunTargetAction(fb_dc->recovery_action()); result.sandbox = convertSandbox(fb_dc->sandbox()); } return result; @@ -277,7 +259,7 @@ RunTargetConfig convertRunTarget(const fb::RunTarget* fb_rt) result.description = safeString(fb_rt->description()); result.depends_on = convertStringVector(fb_rt->depends_on()); result.transition_timeout_ms = secondsToMs(fb_rt->transition_timeout()); - result.recovery_action = convertRecoveryAction(fb_rt->recovery_action_type(), fb_rt->recovery_action()); + result.recovery_action = convertSwitchRunTargetAction(fb_rt->recovery_action()); } return result; } diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp index 1aa26c036..e1aa2b9c8 100644 --- a/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp @@ -229,8 +229,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadRunTargets) auto rt_desc = fbb.CreateString("Initial state"); auto rt_dep = fbb.CreateString("component_a"); auto rt_deps = fbb.CreateVector(std::vector<::flatbuffers::Offset<::flatbuffers::String>>{rt_dep}); - auto rt = fb::CreateRunTarget(fbb, rt_name, rt_desc, rt_deps, 5.0 /*transition_timeout*/, - fb::RecoveryAction::SwitchRunTargetAction, switch_action.Union()); + auto rt = fb::CreateRunTarget(fbb, rt_name, rt_desc, rt_deps, 5.0 /*transition_timeout*/, switch_action); auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{rt}); auto result = loadBuffer(buildConfigWithRunTargets(fbb, rts)); @@ -245,8 +244,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadRunTargets) EXPECT_THAT(target.depends_on[0], Eq("component_a")); EXPECT_THAT(target.transition_timeout_ms, Eq(5000U)); ASSERT_THAT(target.recovery_action.has_value(), IsTrue()); - ASSERT_THAT(std::holds_alternative(target.recovery_action.value()), IsTrue()); - EXPECT_THAT(std::get(target.recovery_action.value()).run_target, Eq("SafeState")); + EXPECT_THAT(target.recovery_action->run_target, Eq("SafeState")); } TEST_F(FlatbufferConfigLoaderTest, LoadFallbackRunTarget) @@ -357,9 +355,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadSwitchRunTargetAction) auto target_name = fbb.CreateString("Fallback"); auto switch_action = fb::CreateSwitchRunTargetAction(fbb, target_name); auto rt_name = fbb.CreateString("Startup"); - auto rt = fb::CreateRunTarget( - fbb, rt_name, 0, 0, 0.0, - fb::RecoveryAction::SwitchRunTargetAction, switch_action.Union()); + auto rt = fb::CreateRunTarget(fbb, rt_name, 0, 0, 0.0, switch_action); auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{rt}); auto result = loadBuffer(buildConfigWithRunTargets(fbb, rts)); @@ -367,9 +363,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadSwitchRunTargetAction) ASSERT_THAT(result.has_value(), IsTrue()); ASSERT_THAT(result->run_targets()[0].recovery_action.has_value(), IsTrue()); - const auto& action = result->run_targets()[0].recovery_action.value(); - ASSERT_THAT(std::holds_alternative(action), IsTrue()); - EXPECT_THAT(std::get(action).run_target, Eq("Fallback")); + EXPECT_THAT(result->run_targets()[0].recovery_action->run_target, Eq("Fallback")); } TEST_F(FlatbufferConfigLoaderTest, LoadSandbox) @@ -390,7 +384,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadSandbox) auto deploy = fb::CreateDeploymentConfig(fbb, 0.5, 0.5, 0 /*environmental_variables*/, bin_dir, work_dir, 0 /*ready_recovery_action*/, - fb::RecoveryAction::NONE, 0 /*recovery_action*/, sandbox); + 0 /*recovery_action*/, sandbox); auto comp = buildDefaultComponent(fbb, "sandboxed_comp", buildDefaultComponentProperties(fbb), deploy); diff --git a/src/launch_manager_daemon/config/src/new_lm_flatcfg.fbs b/src/launch_manager_daemon/config/src/new_lm_flatcfg.fbs index 4d3713826..b488ece3a 100644 --- a/src/launch_manager_daemon/config/src/new_lm_flatcfg.fbs +++ b/src/launch_manager_daemon/config/src/new_lm_flatcfg.fbs @@ -68,10 +68,6 @@ table SwitchRunTargetAction { run_target:string (required); } -// Specifies recovery actions to execute when an error or failure occurs. -// Exactly one variant is set. Maps to the JSON schema's oneOf constraint. -union RecoveryAction { RestartAction, SwitchRunTargetAction } - // A key-value pair representing an environment variable. table EnvironmentalVariable { key:string (required); @@ -114,8 +110,7 @@ table DeploymentConfig { // Can only be a RestartAction per the JSON schema constraint. ready_recovery_action:RestartAction; // Recovery action when the component malfunctions after reaching ready state. - // Must be SwitchRunTargetAction per the JSON schema constraint. - recovery_action:RecoveryAction; + recovery_action:SwitchRunTargetAction; sandbox:Sandbox; } @@ -130,8 +125,7 @@ table RunTarget { // Time limit in seconds for the Run Target transition. transition_timeout:double; // Recovery action when a component in this Run Target fails. - // Must be SwitchRunTargetAction per the JSON schema constraint. - recovery_action:RecoveryAction (required); + recovery_action:SwitchRunTargetAction (required); } // An individual component entry with its identifier. From c9367b130e603e9902e4c226a323006ec6465ab1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Fu=C3=9Fberger?= Date: Tue, 19 May 2026 10:24:51 +0200 Subject: [PATCH 08/26] Remove optional from required fields --- .../config_schema/launch_manager.schema.json | 4 +- .../config/include/config.hpp | 26 ++++++---- .../config/src/config.cpp | 4 +- .../config/src/flatbuffer_config_loader.cpp | 17 +++--- .../src/flatbuffer_config_loader_UT.cpp | 52 ++++++++----------- 5 files changed, 51 insertions(+), 52 deletions(-) diff --git a/src/launch_manager_daemon/config/config_schema/launch_manager.schema.json b/src/launch_manager_daemon/config/config_schema/launch_manager.schema.json index 371630d73..a0f8d6527 100644 --- a/src/launch_manager_daemon/config/config_schema/launch_manager.schema.json +++ b/src/launch_manager_daemon/config/config_schema/launch_manager.schema.json @@ -95,7 +95,9 @@ "additionalProperties": false } }, - "required": [], + "required": [ + "recovery_action" + ], "additionalProperties": false }, "recovery_action": { diff --git a/src/launch_manager_daemon/config/include/config.hpp b/src/launch_manager_daemon/config/include/config.hpp index 79223b25b..0a973089a 100644 --- a/src/launch_manager_daemon/config/include/config.hpp +++ b/src/launch_manager_daemon/config/include/config.hpp @@ -104,7 +104,7 @@ struct RunTargetConfig { std::string description; std::vector depends_on; uint32_t transition_timeout_ms{}; - std::optional recovery_action; + SwitchRunTargetAction recovery_action; }; struct FallbackRunTargetConfig { @@ -129,6 +129,10 @@ struct WatchdogConfig { /// Loaded once by an IConfigLoader, then individual parts are moved out via /// the `take_*()` accessors to transfer ownership to dedicated domain objects /// (e.g. ComponentConfig to Component). +/// +/// @note As of now, everything is expected in a single config file. +/// Even though some fields appear as optional in the json schema, they are only optional if the configuration would be split across multiple files. +/// As only a single file is supported, the single config will contain all fields. class Config { public: Config(const Config&) = delete; @@ -151,8 +155,8 @@ class Config { std::string initial_run_target_; std::vector components_; std::vector run_targets_; - std::optional fallback_run_target_; - std::optional alive_supervision_; + FallbackRunTargetConfig fallback_run_target_; + AliveSupervisionConfig alive_supervision_; std::optional watchdog_; }; @@ -160,16 +164,16 @@ class Config { const std::vector& components() const { return components_; } const std::vector& run_targets() const { return run_targets_; } std::string_view initial_run_target() const { return initial_run_target_; } - const std::optional& fallback_run_target() const { return fallback_run_target_; } - const std::optional& alive_supervision() const { return alive_supervision_; } + const FallbackRunTargetConfig& fallback_run_target() const { return fallback_run_target_; } + const AliveSupervisionConfig& alive_supervision() const { return alive_supervision_; } const std::optional& watchdog() const { return watchdog_; } // Ownership transfer — source is left in a moved-from state after the call std::vector take_components() { return std::move(components_); } std::vector take_run_targets() { return std::move(run_targets_); } std::string take_initial_run_target() { return std::move(initial_run_target_); } - std::optional take_fallback_run_target() { return std::move(fallback_run_target_); } - std::optional take_alive_supervision() { return std::move(alive_supervision_); } + FallbackRunTargetConfig take_fallback_run_target() { return std::move(fallback_run_target_); } + AliveSupervisionConfig take_alive_supervision() { return std::move(alive_supervision_); } std::optional take_watchdog() { return std::move(watchdog_); } private: @@ -178,15 +182,15 @@ class Config { Config(std::vector components, std::vector run_targets, std::string initial_run_target, - std::optional fallback_run_target, - std::optional alive_supervision, + FallbackRunTargetConfig fallback_run_target, + AliveSupervisionConfig alive_supervision, std::optional watchdog); std::vector components_; std::vector run_targets_; std::string initial_run_target_; - std::optional fallback_run_target_; - std::optional alive_supervision_; + FallbackRunTargetConfig fallback_run_target_; + AliveSupervisionConfig alive_supervision_; std::optional watchdog_; }; diff --git a/src/launch_manager_daemon/config/src/config.cpp b/src/launch_manager_daemon/config/src/config.cpp index e67d262ce..f179522c9 100644 --- a/src/launch_manager_daemon/config/src/config.cpp +++ b/src/launch_manager_daemon/config/src/config.cpp @@ -20,8 +20,8 @@ namespace score::launch_manager::config { Config::Config(std::vector components, std::vector run_targets, std::string initial_run_target, - std::optional fallback_run_target, - std::optional alive_supervision, + FallbackRunTargetConfig fallback_run_target, + AliveSupervisionConfig alive_supervision, std::optional watchdog) : components_{std::move(components)}, run_targets_{std::move(run_targets)}, diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp index a74cd4aa4..88b22043a 100644 --- a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp @@ -139,6 +139,11 @@ std::optional convertSwitchRunTargetAction(const fb::Swit return SwitchRunTargetAction{safeString(sa->run_target())}; } +SwitchRunTargetAction convertRequiredSwitchRunTargetAction(const fb::SwitchRunTargetAction* sa) +{ + return convertSwitchRunTargetAction(sa).value(); +} + // --- Struct conversion helpers --- ComponentAliveSupervision convertComponentAliveSupervision(const fb::ComponentAliveSupervision* fb_cas) @@ -259,7 +264,7 @@ RunTargetConfig convertRunTarget(const fb::RunTarget* fb_rt) result.description = safeString(fb_rt->description()); result.depends_on = convertStringVector(fb_rt->depends_on()); result.transition_timeout_ms = secondsToMs(fb_rt->transition_timeout()); - result.recovery_action = convertSwitchRunTargetAction(fb_rt->recovery_action()); + result.recovery_action = convertRequiredSwitchRunTargetAction(fb_rt->recovery_action()); } return result; } @@ -276,11 +281,11 @@ FallbackRunTargetConfig convertFallbackRunTarget(const fb::FallbackRunTarget* fb return result; } -std::optional convertAliveSupervision(const fb::AliveSupervision* fb_as) +AliveSupervisionConfig convertAliveSupervision(const fb::AliveSupervision* fb_as) { if (fb_as == nullptr) { - return std::nullopt; + return AliveSupervisionConfig{}; } return AliveSupervisionConfig{secondsToMs(fb_as->evaluation_cycle())}; } @@ -376,11 +381,7 @@ score::cpp::expected parseFlatbuffer(const std::ve builder.setFallbackRunTarget(convertFallbackRunTarget(config->fallback_run_target())); // alive_supervision is a required field, guaranteed non-null by the schema and verifier. - auto alive_sup = convertAliveSupervision(config->alive_supervision()); - if (alive_sup.has_value()) - { - builder.setAliveSupervision(std::move(*alive_sup)); - } + builder.setAliveSupervision(convertAliveSupervision(config->alive_supervision())); auto wd = convertWatchdog(config->watchdog()); if (wd.has_value()) diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp index e1aa2b9c8..f1cad8ecf 100644 --- a/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp @@ -53,14 +53,14 @@ ::flatbuffers::Offset buildDefaultComponentProperties( auto bin_name = fbb.CreateString("default_bin"); auto app_profile = fb::CreateApplicationProfile(fbb); auto ready_cond = fb::CreateReadyCondition(fbb); - return fb::CreateComponentProperties(fbb, bin_name, app_profile, 0, 0, ready_cond); + return fb::CreateComponentProperties(fbb, bin_name, app_profile, 0 /*depends_on*/, 0 /*process_arguments*/, ready_cond); } ::flatbuffers::Offset buildDefaultDeploymentConfig( ::flatbuffers::FlatBufferBuilder& fbb) { auto bin_dir = fbb.CreateString("/opt"); - return fb::CreateDeploymentConfig(fbb, 0.0, 0.0, 0, bin_dir); + return fb::CreateDeploymentConfig(fbb, 0.0 /*ready_timeout*/, 0.0 /*shutdown_timeout*/, 0 /*environmental_variables*/, bin_dir); } ::flatbuffers::Offset buildDefaultComponent( @@ -76,7 +76,7 @@ ::flatbuffers::Offset buildDefaultComponent( deploy = buildDefaultDeploymentConfig(fbb); } auto comp_name = fbb.CreateString(name); - return fb::CreateComponent(fbb, comp_name, 0, comp_props, deploy); + return fb::CreateComponent(fbb, comp_name, 0 /*description*/, comp_props, deploy); } std::vector buildConfigWithComponents( @@ -86,7 +86,7 @@ std::vector buildConfigWithComponents( auto fallback = fb::CreateFallbackRunTarget(fbb); auto alive_sup = fb::CreateAliveSupervision(fbb); auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, 1, comps, 0, irt, fallback, alive_sup); + auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, comps, 0 /*run_targets*/, irt, fallback, alive_sup); return finishBuffer(fbb, config); } @@ -97,7 +97,7 @@ std::vector buildConfigWithRunTargets( auto fallback = fb::CreateFallbackRunTarget(fbb); auto alive_sup = fb::CreateAliveSupervision(fbb); auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, 1, 0, rts, irt, fallback, alive_sup); + auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, 0 /*components*/, rts, irt, fallback, alive_sup); return finishBuffer(fbb, config); } @@ -118,7 +118,7 @@ class FlatbufferConfigLoaderTest : public ::testing::Test { void SetUp() override { RecordProperty("TestType", "interface-test"); - RecordProperty("DerivationTechnique", "explorative-testing "); + RecordProperty("DerivationTechnique", "explorative-testing"); MockBufferLoader::result_ = std::vector{}; } @@ -130,7 +130,7 @@ class FlatbufferConfigLoaderTest : public ::testing::Test { auto fallback = fb::CreateFallbackRunTarget(fbb); auto alive_sup = fb::CreateAliveSupervision(fbb); auto config = fb::CreateLaunchManagerConfig( - fbb, schema_version, 0, 0, irt, fallback, alive_sup); + fbb, schema_version, 0 /*components*/, 0 /*run_targets*/, irt, fallback, alive_sup); return finishBuffer(fbb, config); } @@ -157,8 +157,6 @@ TEST_F(FlatbufferConfigLoaderTest, LoadMinimalConfig) EXPECT_THAT(result->initial_run_target(), Eq("Startup")); EXPECT_THAT(result->components().empty(), IsTrue()); EXPECT_THAT(result->run_targets().empty(), IsTrue()); - EXPECT_THAT(result->fallback_run_target().has_value(), IsTrue()); - EXPECT_THAT(result->alive_supervision().has_value(), IsTrue()); EXPECT_THAT(result->watchdog().has_value(), IsFalse()); } @@ -243,8 +241,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadRunTargets) ASSERT_THAT(target.depends_on.size(), Eq(1U)); EXPECT_THAT(target.depends_on[0], Eq("component_a")); EXPECT_THAT(target.transition_timeout_ms, Eq(5000U)); - ASSERT_THAT(target.recovery_action.has_value(), IsTrue()); - EXPECT_THAT(target.recovery_action->run_target, Eq("SafeState")); + EXPECT_THAT(target.recovery_action.run_target, Eq("SafeState")); } TEST_F(FlatbufferConfigLoaderTest, LoadFallbackRunTarget) @@ -260,14 +257,12 @@ TEST_F(FlatbufferConfigLoaderTest, LoadFallbackRunTarget) auto alive_sup = fb::CreateAliveSupervision(fbb); auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, 1, 0, 0, irt, fallback, alive_sup); + auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, 0 /*components*/, 0 /*run_targets*/, irt, fallback, alive_sup); auto result = loadBuffer(finishBuffer(fbb, config)); ASSERT_THAT(result.has_value(), IsTrue()); - ASSERT_THAT(result->fallback_run_target().has_value(), IsTrue()); - - const auto& fb = result->fallback_run_target().value(); + const auto& fb = result->fallback_run_target(); EXPECT_THAT(fb.description, Eq("Fallback state")); ASSERT_THAT(fb.depends_on.size(), Eq(1U)); EXPECT_THAT(fb.depends_on[0], Eq("critical_comp")); @@ -283,13 +278,12 @@ TEST_F(FlatbufferConfigLoaderTest, LoadAliveSupervision) auto alive_sup = fb::CreateAliveSupervision(fbb, 0.25 /*evaluation_cycle*/); auto fallback = fb::CreateFallbackRunTarget(fbb); auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, 1, 0, 0, irt, fallback, alive_sup); + auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, 0 /*components*/, 0 /*run_targets*/, irt, fallback, alive_sup); auto result = loadBuffer(finishBuffer(fbb, config)); ASSERT_THAT(result.has_value(), IsTrue()); - ASSERT_THAT(result->alive_supervision().has_value(), IsTrue()); - EXPECT_THAT(result->alive_supervision()->evaluation_cycle_ms, Eq(250U)); + EXPECT_THAT(result->alive_supervision().evaluation_cycle_ms, Eq(250U)); } TEST_F(FlatbufferConfigLoaderTest, LoadWatchdog) @@ -305,7 +299,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadWatchdog) auto fallback = fb::CreateFallbackRunTarget(fbb); auto alive_sup = fb::CreateAliveSupervision(fbb); auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, 1, 0, 0, irt, fallback, alive_sup, watchdog); + auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, 0 /*components*/, 0 /*run_targets*/, irt, fallback, alive_sup, watchdog); auto result = loadBuffer(finishBuffer(fbb, config)); @@ -328,7 +322,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadRestartRecoveryAction) auto restart = fb::CreateRestartAction(fbb, 3 /*number_of_attempts*/, 1.5 /*delay_before_restart*/); auto bin_dir = fbb.CreateString("/opt"); auto deploy = fb::CreateDeploymentConfig(fbb, - 0.0, 0.0, 0 /*environmental_variables*/, bin_dir, 0 /*working_dir*/, + 0.0 /*ready_timeout*/, 0.0 /*shutdown_timeout*/, 0 /*environmental_variables*/, bin_dir, 0 /*working_dir*/, restart); auto comp = buildDefaultComponent(fbb, "restart_comp", @@ -355,15 +349,13 @@ TEST_F(FlatbufferConfigLoaderTest, LoadSwitchRunTargetAction) auto target_name = fbb.CreateString("Fallback"); auto switch_action = fb::CreateSwitchRunTargetAction(fbb, target_name); auto rt_name = fbb.CreateString("Startup"); - auto rt = fb::CreateRunTarget(fbb, rt_name, 0, 0, 0.0, switch_action); + auto rt = fb::CreateRunTarget(fbb, rt_name, 0 /*description*/, 0 /*depends_on*/, 0.0 /*transition_timeout*/, switch_action); auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{rt}); auto result = loadBuffer(buildConfigWithRunTargets(fbb, rts)); ASSERT_THAT(result.has_value(), IsTrue()); - ASSERT_THAT(result->run_targets()[0].recovery_action.has_value(), IsTrue()); - - EXPECT_THAT(result->run_targets()[0].recovery_action->run_target, Eq("Fallback")); + EXPECT_THAT(result->run_targets()[0].recovery_action.run_target, Eq("Fallback")); } TEST_F(FlatbufferConfigLoaderTest, LoadSandbox) @@ -382,7 +374,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadSandbox) auto bin_dir = fbb.CreateString("/opt"); auto work_dir = fbb.CreateString("/tmp"); auto deploy = fb::CreateDeploymentConfig(fbb, - 0.5, 0.5, 0 /*environmental_variables*/, bin_dir, work_dir, + 0.5 /*ready_timeout*/, 0.5 /*shutdown_timeout*/, 0 /*environmental_variables*/, bin_dir, work_dir, 0 /*ready_recovery_action*/, 0 /*recovery_action*/, sandbox); @@ -422,7 +414,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadComponentAliveSupervision) fb::ApplicationType::Reporting_And_Supervised, false /*is_self_terminating*/, comp_alive_sup); auto bin_name = fbb.CreateString("supervised_bin"); auto ready_cond = fb::CreateReadyCondition(fbb); - auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile, 0, 0, ready_cond); + auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile, 0 /*depends_on*/, 0 /*process_arguments*/, ready_cond); auto comp = buildDefaultComponent(fbb, "supervised_comp", comp_props); auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); @@ -455,7 +447,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadEnvironmentalVariables) auto bin_dir = fbb.CreateString("/opt"); auto work_dir = fbb.CreateString("/tmp"); auto deploy = fb::CreateDeploymentConfig(fbb, - 0.5, 0.5, env_vars, bin_dir, work_dir); + 0.5 /*ready_timeout*/, 0.5 /*shutdown_timeout*/, env_vars, bin_dir, work_dir); auto comp = buildDefaultComponent(fbb, "env_comp", buildDefaultComponentProperties(fbb), deploy); @@ -533,7 +525,7 @@ TEST_F(FlatbufferConfigLoaderTest, MapNativeApplicationType) auto app_profile = fb::CreateApplicationProfile(fbb, fb::ApplicationType::Native); auto bin_name = fbb.CreateString("native_bin"); auto ready_cond = fb::CreateReadyCondition(fbb); - auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile, 0, 0, ready_cond); + auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile, 0 /*depends_on*/, 0 /*process_arguments*/, ready_cond); auto comp = buildDefaultComponent(fbb, "native_comp", comp_props); auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); @@ -555,7 +547,7 @@ TEST_F(FlatbufferConfigLoaderTest, MapReportingAndSupervisedType) auto app_profile = fb::CreateApplicationProfile(fbb, fb::ApplicationType::Reporting_And_Supervised); auto bin_name = fbb.CreateString("supervised_bin"); auto ready_cond = fb::CreateReadyCondition(fbb); - auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile, 0, 0, ready_cond); + auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile, 0 /*depends_on*/, 0 /*process_arguments*/, ready_cond); auto comp = buildDefaultComponent(fbb, "supervised_comp", comp_props); auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); @@ -577,7 +569,7 @@ TEST_F(FlatbufferConfigLoaderTest, MapTerminatedProcessState) auto ready_cond = fb::CreateReadyCondition(fbb, fb::ProcessState::Terminated); auto bin_name = fbb.CreateString("term_bin"); auto comp_props = fb::CreateComponentProperties(fbb, - bin_name, app_profile, 0, 0, ready_cond); + bin_name, app_profile, 0 /*depends_on*/, 0 /*process_arguments*/, ready_cond); auto comp = buildDefaultComponent(fbb, "term_comp", comp_props); auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); From fb24424857741555c3df20ce8426ccfa7fc5d9e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Fu=C3=9Fberger?= Date: Tue, 19 May 2026 12:56:05 +0200 Subject: [PATCH 09/26] Remove unrelated test output --- .../expected_output/new_lm_config.json | 398 --------------- .../expected_output/new_lm_config.json | 86 ---- .../expected_output/new_lm_config.json | 31 -- .../expected_output/new_lm_config.json | 238 --------- .../expected_output/new_lm_config.json | 472 ------------------ .../config_schema/launch_manager.schema.json | 4 +- 6 files changed, 1 insertion(+), 1228 deletions(-) delete mode 100644 scripts/config_mapping/tests/basic_test/expected_output/new_lm_config.json delete mode 100644 scripts/config_mapping/tests/empty_health_config_test/expected_output/new_lm_config.json delete mode 100644 scripts/config_mapping/tests/empty_lm_config_test/expected_output/new_lm_config.json delete mode 100644 scripts/config_mapping/tests/health_config_test/expected_output/new_lm_config.json delete mode 100644 scripts/config_mapping/tests/lm_config_test/expected_output/new_lm_config.json diff --git a/scripts/config_mapping/tests/basic_test/expected_output/new_lm_config.json b/scripts/config_mapping/tests/basic_test/expected_output/new_lm_config.json deleted file mode 100644 index 3801364ce..000000000 --- a/scripts/config_mapping/tests/basic_test/expected_output/new_lm_config.json +++ /dev/null @@ -1,398 +0,0 @@ -{ - "schema_version": 1, - "components": [ - { - "name": "setup_filesystem_sh", - "description": "Script to mount partitions at the right directories", - "component_properties": { - "binary_name": "bin/setup_filesystem.sh", - "application_profile": { - "application_type": "Native", - "is_self_terminating": true, - "alive_supervision": { - "reporting_cycle": 0.5, - "failed_cycles_tolerance": 2, - "min_indications": 1, - "max_indications": 3 - } - }, - "depends_on": [], - "process_arguments": [ - "-a", - "-b" - ], - "ready_condition": { - "process_state": "Terminated" - } - }, - "deployment_config": { - "ready_timeout": 0.5, - "shutdown_timeout": 0.5, - "environmental_variables": [ - { - "key": "LD_LIBRARY_PATH", - "value": "/opt/lib" - }, - { - "key": "GLOBAL_ENV_VAR", - "value": "abc" - }, - { - "key": "EMPTY_GLOBAL_ENV_VAR", - "value": "" - } - ], - "bin_dir": "/opt/scripts", - "working_dir": "/tmp", - "ready_recovery_action_type": "RestartAction", - "ready_recovery_action": { - "number_of_attempts": 1, - "delay_before_restart": 0.5 - }, - "recovery_action_type": "SwitchRunTargetAction", - "recovery_action": { - "run_target": "Off" - }, - "sandbox": { - "uid": 1000, - "gid": 1000, - "supplementary_group_ids": [ - 500, - 600, - 700 - ], - "security_policy": "policy_name", - "scheduling_policy": "SCHED_OTHER", - "scheduling_priority": 0, - "max_memory_usage": 1024, - "max_cpu_usage": 75 - } - } - }, - { - "name": "dlt-daemon", - "description": "Logging application", - "component_properties": { - "binary_name": "dltd", - "application_profile": { - "application_type": "Native", - "is_self_terminating": false, - "alive_supervision": { - "reporting_cycle": 0.5, - "failed_cycles_tolerance": 2, - "min_indications": 1, - "max_indications": 3 - } - }, - "depends_on": [ - "setup_filesystem_sh" - ], - "process_arguments": [ - "-a", - "-b", - "--xyz" - ], - "ready_condition": { - "process_state": "Running" - } - }, - "deployment_config": { - "ready_timeout": 0.5, - "shutdown_timeout": 0.5, - "environmental_variables": [ - { - "key": "LD_LIBRARY_PATH", - "value": "/opt/lib" - }, - { - "key": "GLOBAL_ENV_VAR", - "value": "abc" - }, - { - "key": "EMPTY_GLOBAL_ENV_VAR", - "value": "" - } - ], - "bin_dir": "/opt/apps/dlt-daemon", - "working_dir": "/tmp", - "ready_recovery_action_type": "RestartAction", - "ready_recovery_action": { - "number_of_attempts": 1, - "delay_before_restart": 0.5 - }, - "recovery_action_type": "SwitchRunTargetAction", - "recovery_action": { - "run_target": "Off" - }, - "sandbox": { - "uid": 1000, - "gid": 1000, - "supplementary_group_ids": [ - 500, - 600, - 700 - ], - "security_policy": "policy_name", - "scheduling_policy": "SCHED_OTHER", - "scheduling_priority": 0, - "max_memory_usage": 1024, - "max_cpu_usage": 75 - } - } - }, - { - "name": "someip-daemon", - "description": "SOME/IP application", - "component_properties": { - "binary_name": "someipd", - "application_profile": { - "application_type": "Reporting_And_Supervised", - "is_self_terminating": false, - "alive_supervision": { - "reporting_cycle": 0.5, - "failed_cycles_tolerance": 2, - "min_indications": 1, - "max_indications": 3 - } - }, - "depends_on": [], - "process_arguments": [ - "-a", - "-b", - "--xyz" - ], - "ready_condition": { - "process_state": "Running" - } - }, - "deployment_config": { - "ready_timeout": 0.5, - "shutdown_timeout": 0.5, - "environmental_variables": [ - { - "key": "LD_LIBRARY_PATH", - "value": "/opt/lib" - }, - { - "key": "GLOBAL_ENV_VAR", - "value": "abc" - }, - { - "key": "EMPTY_GLOBAL_ENV_VAR", - "value": "" - } - ], - "bin_dir": "/opt/apps/someip", - "working_dir": "/tmp", - "ready_recovery_action_type": "RestartAction", - "ready_recovery_action": { - "number_of_attempts": 1, - "delay_before_restart": 0.5 - }, - "recovery_action_type": "SwitchRunTargetAction", - "recovery_action": { - "run_target": "Off" - }, - "sandbox": { - "uid": 1000, - "gid": 1000, - "supplementary_group_ids": [ - 500, - 600, - 700 - ], - "security_policy": "policy_name", - "scheduling_policy": "SCHED_OTHER", - "scheduling_priority": 0, - "max_memory_usage": 1024, - "max_cpu_usage": 75 - } - } - }, - { - "name": "test_app1", - "description": "Simple test application", - "component_properties": { - "binary_name": "test_app1", - "application_profile": { - "application_type": "Reporting_And_Supervised", - "is_self_terminating": false, - "alive_supervision": { - "reporting_cycle": 0.5, - "failed_cycles_tolerance": 2, - "min_indications": 1, - "max_indications": 3 - } - }, - "depends_on": [ - "dlt-daemon", - "someip-daemon" - ], - "process_arguments": [ - "-a", - "-b", - "--xyz" - ], - "ready_condition": { - "process_state": "Running" - } - }, - "deployment_config": { - "ready_timeout": 0.5, - "shutdown_timeout": 0.5, - "environmental_variables": [ - { - "key": "LD_LIBRARY_PATH", - "value": "/opt/lib" - }, - { - "key": "GLOBAL_ENV_VAR", - "value": "abc" - }, - { - "key": "EMPTY_GLOBAL_ENV_VAR", - "value": "" - } - ], - "bin_dir": "/opt/apps/test_app1", - "working_dir": "/tmp", - "ready_recovery_action_type": "RestartAction", - "ready_recovery_action": { - "number_of_attempts": 1, - "delay_before_restart": 0.5 - }, - "recovery_action_type": "SwitchRunTargetAction", - "recovery_action": { - "run_target": "Off" - }, - "sandbox": { - "uid": 1000, - "gid": 1000, - "supplementary_group_ids": [ - 500, - 600, - 700 - ], - "security_policy": "policy_name", - "scheduling_policy": "SCHED_OTHER", - "scheduling_priority": 0, - "max_memory_usage": 1024, - "max_cpu_usage": 75 - } - } - }, - { - "name": "state_manager", - "description": "Application that manages life cycle of the ECU", - "component_properties": { - "binary_name": "sm", - "application_profile": { - "application_type": "State_Manager", - "is_self_terminating": false, - "alive_supervision": { - "reporting_cycle": 0.5, - "failed_cycles_tolerance": 2, - "min_indications": 1, - "max_indications": 3 - } - }, - "depends_on": [ - "setup_filesystem_sh" - ], - "process_arguments": [ - "-a", - "-b", - "--xyz" - ], - "ready_condition": { - "process_state": "Running" - } - }, - "deployment_config": { - "ready_timeout": 0.5, - "shutdown_timeout": 0.5, - "environmental_variables": [ - { - "key": "LD_LIBRARY_PATH", - "value": "/opt/lib" - }, - { - "key": "GLOBAL_ENV_VAR", - "value": "abc" - }, - { - "key": "EMPTY_GLOBAL_ENV_VAR", - "value": "" - } - ], - "bin_dir": "/opt/apps/state_manager", - "working_dir": "/tmp", - "ready_recovery_action_type": "RestartAction", - "ready_recovery_action": { - "number_of_attempts": 1, - "delay_before_restart": 0.5 - }, - "recovery_action_type": "SwitchRunTargetAction", - "recovery_action": { - "run_target": "Off" - }, - "sandbox": { - "uid": 1000, - "gid": 1000, - "supplementary_group_ids": [ - 500, - 600, - 700 - ], - "security_policy": "policy_name", - "scheduling_policy": "SCHED_OTHER", - "scheduling_priority": 0, - "max_memory_usage": 1024, - "max_cpu_usage": 75 - } - } - } - ], - "run_targets": [ - { - "name": "Startup", - "description": "Minimal functionality of the system", - "depends_on": [ - "state_manager" - ], - "transition_timeout": 5, - "recovery_action_type": "SwitchRunTargetAction", - "recovery_action": { - "run_target": "fallback_run_target" - } - }, - { - "name": "Full", - "description": "Everything running", - "depends_on": [ - "test_app1", - "Startup" - ], - "transition_timeout": 5, - "recovery_action_type": "SwitchRunTargetAction", - "recovery_action": { - "run_target": "fallback_run_target" - } - } - ], - "initial_run_target": "Startup", - "fallback_run_target": { - "description": "Switching off everything", - "depends_on": [], - "transition_timeout": 1.5 - }, - "alive_supervision": { - "evaluation_cycle": 0.5 - }, - "watchdog": { - "device_file_path": "/dev/watchdog", - "max_timeout": 2, - "deactivate_on_shutdown": true, - "require_magic_close": false - } -} \ No newline at end of file diff --git a/scripts/config_mapping/tests/empty_health_config_test/expected_output/new_lm_config.json b/scripts/config_mapping/tests/empty_health_config_test/expected_output/new_lm_config.json deleted file mode 100644 index d54cd0c6f..000000000 --- a/scripts/config_mapping/tests/empty_health_config_test/expected_output/new_lm_config.json +++ /dev/null @@ -1,86 +0,0 @@ -{ - "schema_version": 1, - "components": [ - { - "name": "non_supervised_comp", - "description": "Non-supervised component", - "component_properties": { - "binary_name": "bin/comp", - "application_profile": { - "application_type": "Native", - "is_self_terminating": true, - "alive_supervision": { - "reporting_cycle": 0.5, - "failed_cycles_tolerance": 2, - "min_indications": 1, - "max_indications": 3 - } - }, - "depends_on": [], - "process_arguments": [], - "ready_condition": { - "process_state": "Terminated" - } - }, - "deployment_config": { - "ready_timeout": 0.5, - "shutdown_timeout": 0.5, - "environmental_variables": [], - "bin_dir": "/opt/scripts", - "working_dir": "/tmp", - "ready_recovery_action_type": "RestartAction", - "ready_recovery_action": { - "number_of_attempts": 0, - "delay_before_restart": 0 - }, - "recovery_action_type": "SwitchRunTargetAction", - "recovery_action": { - "run_target": "fallback_run_target" - }, - "sandbox": { - "uid": 3, - "gid": 1000, - "supplementary_group_ids": [], - "security_policy": "", - "scheduling_policy": "SCHED_OTHER", - "scheduling_priority": 0 - } - } - } - ], - "run_targets": [ - { - "name": "Startup", - "description": "Minimal functionality of the system", - "depends_on": [ - "non_supervised_comp" - ], - "transition_timeout": 3, - "recovery_action_type": "SwitchRunTargetAction", - "recovery_action": { - "run_target": "fallback_run_target" - } - }, - { - "name": "Full", - "description": "Everything running", - "depends_on": [ - "non_supervised_comp" - ], - "transition_timeout": 5, - "recovery_action_type": "SwitchRunTargetAction", - "recovery_action": { - "run_target": "fallback_run_target" - } - } - ], - "initial_run_target": "Startup", - "fallback_run_target": { - "description": "Switching off everything", - "depends_on": [], - "transition_timeout": 1.5 - }, - "alive_supervision": { - "evaluation_cycle": 0.123 - } -} \ No newline at end of file diff --git a/scripts/config_mapping/tests/empty_lm_config_test/expected_output/new_lm_config.json b/scripts/config_mapping/tests/empty_lm_config_test/expected_output/new_lm_config.json deleted file mode 100644 index ebf074a29..000000000 --- a/scripts/config_mapping/tests/empty_lm_config_test/expected_output/new_lm_config.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "schema_version": 1, - "components": [], - "run_targets": [ - { - "name": "Startup", - "description": "Empty", - "depends_on": [], - "transition_timeout": 5, - "recovery_action_type": "SwitchRunTargetAction", - "recovery_action": { - "run_target": "fallback_run_target" - } - } - ], - "initial_run_target": "Startup", - "fallback_run_target": { - "description": "Switching off everything", - "depends_on": [], - "transition_timeout": 1.5 - }, - "alive_supervision": { - "evaluation_cycle": 0.5 - }, - "watchdog": { - "device_file_path": "/dev/watchdog", - "max_timeout": 2, - "deactivate_on_shutdown": true, - "require_magic_close": false - } -} \ No newline at end of file diff --git a/scripts/config_mapping/tests/health_config_test/expected_output/new_lm_config.json b/scripts/config_mapping/tests/health_config_test/expected_output/new_lm_config.json deleted file mode 100644 index 3525c3663..000000000 --- a/scripts/config_mapping/tests/health_config_test/expected_output/new_lm_config.json +++ /dev/null @@ -1,238 +0,0 @@ -{ - "schema_version": 1, - "components": [ - { - "name": "non_supervised_comp", - "description": "Non-supervised component", - "component_properties": { - "binary_name": "bin/comp", - "application_profile": { - "application_type": "Native", - "is_self_terminating": true, - "alive_supervision": { - "reporting_cycle": 0.5, - "failed_cycles_tolerance": 2, - "min_indications": 1, - "max_indications": 3 - } - }, - "depends_on": [], - "process_arguments": [], - "ready_condition": { - "process_state": "Terminated" - } - }, - "deployment_config": { - "ready_timeout": 0.5, - "shutdown_timeout": 0.5, - "environmental_variables": [], - "bin_dir": "/opt/scripts", - "working_dir": "/tmp", - "ready_recovery_action_type": "RestartAction", - "ready_recovery_action": { - "number_of_attempts": 0, - "delay_before_restart": 0 - }, - "recovery_action_type": "SwitchRunTargetAction", - "recovery_action": { - "run_target": "fallback_run_target" - }, - "sandbox": { - "uid": 3, - "gid": 1000, - "supplementary_group_ids": [], - "security_policy": "", - "scheduling_policy": "SCHED_OTHER", - "scheduling_priority": 0 - } - } - }, - { - "name": "state_manager", - "description": "StateManager with min_indications set to 0", - "component_properties": { - "binary_name": "sm", - "application_profile": { - "application_type": "State_Manager", - "is_self_terminating": false, - "alive_supervision": { - "reporting_cycle": 0.1, - "failed_cycles_tolerance": 0, - "min_indications": 0, - "max_indications": 2 - } - }, - "depends_on": [], - "process_arguments": [], - "ready_condition": { - "process_state": "Running" - } - }, - "deployment_config": { - "ready_timeout": 0.5, - "shutdown_timeout": 0.5, - "environmental_variables": [], - "bin_dir": "/opt/apps/state_manager", - "working_dir": "/tmp", - "ready_recovery_action_type": "RestartAction", - "ready_recovery_action": { - "number_of_attempts": 0, - "delay_before_restart": 0 - }, - "recovery_action_type": "SwitchRunTargetAction", - "recovery_action": { - "run_target": "fallback_run_target" - }, - "sandbox": { - "uid": 4, - "gid": 1000, - "supplementary_group_ids": [], - "security_policy": "", - "scheduling_policy": "SCHED_OTHER", - "scheduling_priority": 0 - } - } - }, - { - "name": "reporting_supervised_component", - "description": "Component reporting Running state and supervised", - "component_properties": { - "binary_name": "bin/comp", - "application_profile": { - "application_type": "Reporting_And_Supervised", - "is_self_terminating": true, - "alive_supervision": { - "reporting_cycle": 0.5, - "failed_cycles_tolerance": 2, - "min_indications": 1, - "max_indications": 3 - } - }, - "depends_on": [], - "process_arguments": [ - "-a", - "-b" - ], - "ready_condition": { - "process_state": "Running" - } - }, - "deployment_config": { - "ready_timeout": 0.5, - "shutdown_timeout": 0.5, - "environmental_variables": [], - "bin_dir": "/opt/scripts", - "working_dir": "/tmp", - "ready_recovery_action_type": "RestartAction", - "ready_recovery_action": { - "number_of_attempts": 0, - "delay_before_restart": 0 - }, - "recovery_action_type": "SwitchRunTargetAction", - "recovery_action": { - "run_target": "fallback_run_target" - }, - "sandbox": { - "uid": 5, - "gid": 1000, - "supplementary_group_ids": [], - "security_policy": "", - "scheduling_policy": "SCHED_OTHER", - "scheduling_priority": 0 - } - } - }, - { - "name": "reporting_supervised_component_with_no_max_indications", - "description": "Component reporting Running state and supervised with max_indications=0", - "component_properties": { - "binary_name": "bin/comp", - "application_profile": { - "application_type": "Reporting_And_Supervised", - "is_self_terminating": true, - "alive_supervision": { - "reporting_cycle": 0.5, - "failed_cycles_tolerance": 2, - "min_indications": 1, - "max_indications": 0 - } - }, - "depends_on": [], - "process_arguments": [ - "-a", - "-b" - ], - "ready_condition": { - "process_state": "Running" - } - }, - "deployment_config": { - "ready_timeout": 0.5, - "shutdown_timeout": 0.5, - "environmental_variables": [], - "bin_dir": "/opt/scripts", - "working_dir": "/tmp", - "ready_recovery_action_type": "RestartAction", - "ready_recovery_action": { - "number_of_attempts": 0, - "delay_before_restart": 0 - }, - "recovery_action_type": "SwitchRunTargetAction", - "recovery_action": { - "run_target": "fallback_run_target" - }, - "sandbox": { - "uid": 5, - "gid": 1000, - "supplementary_group_ids": [], - "security_policy": "", - "scheduling_policy": "SCHED_OTHER", - "scheduling_priority": 0 - } - } - } - ], - "run_targets": [ - { - "name": "Startup", - "description": "Minimal functionality of the system", - "depends_on": [ - "state_manager" - ], - "transition_timeout": 3, - "recovery_action_type": "SwitchRunTargetAction", - "recovery_action": { - "run_target": "fallback_run_target" - } - }, - { - "name": "Full", - "description": "Everything running", - "depends_on": [ - "reporting_supervised_component", - "reporting_supervised_component_with_no_max_indications", - "Startup" - ], - "transition_timeout": 5, - "recovery_action_type": "SwitchRunTargetAction", - "recovery_action": { - "run_target": "fallback_run_target" - } - } - ], - "initial_run_target": "Startup", - "fallback_run_target": { - "description": "Switching off everything", - "depends_on": [], - "transition_timeout": 1.5 - }, - "alive_supervision": { - "evaluation_cycle": 0.123 - }, - "watchdog": { - "device_file_path": "/dev/watchdog", - "max_timeout": 2, - "deactivate_on_shutdown": true, - "require_magic_close": false - } -} \ No newline at end of file diff --git a/scripts/config_mapping/tests/lm_config_test/expected_output/new_lm_config.json b/scripts/config_mapping/tests/lm_config_test/expected_output/new_lm_config.json deleted file mode 100644 index 6b5f3e808..000000000 --- a/scripts/config_mapping/tests/lm_config_test/expected_output/new_lm_config.json +++ /dev/null @@ -1,472 +0,0 @@ -{ - "schema_version": 1, - "components": [ - { - "name": "test_app2", - "description": "Another simple test application", - "component_properties": { - "binary_name": "test_app2", - "application_profile": { - "application_type": "Reporting_And_Supervised", - "is_self_terminating": false, - "alive_supervision": { - "reporting_cycle": 0.5, - "failed_cycles_tolerance": 2, - "min_indications": 1, - "max_indications": 3 - } - }, - "depends_on": [], - "process_arguments": [ - "-a", - "-b", - "--xyz" - ], - "ready_condition": { - "process_state": "Running" - } - }, - "deployment_config": { - "ready_timeout": 0.5, - "shutdown_timeout": 0.5, - "environmental_variables": [ - { - "key": "LD_LIBRARY_PATH", - "value": "/opt/lib" - }, - { - "key": "GLOBAL_ENV_VAR", - "value": "overridden_value" - }, - { - "key": "EMPTY_GLOBAL_ENV_VAR", - "value": "" - }, - { - "key": "APP_SPECIFIC_ENV_VAR", - "value": "def" - } - ], - "bin_dir": "/opt/apps/test_app2", - "working_dir": "/tmp", - "ready_recovery_action_type": "RestartAction", - "ready_recovery_action": { - "number_of_attempts": 1, - "delay_before_restart": 0.5 - }, - "recovery_action_type": "SwitchRunTargetAction", - "recovery_action": { - "run_target": "fallback_run_target" - }, - "sandbox": { - "uid": 2000, - "gid": 2000, - "supplementary_group_ids": [ - 800, - 900 - ], - "security_policy": "policy_name_2", - "scheduling_policy": "SCHED_FIFO", - "scheduling_priority": 99, - "max_memory_usage": 2048, - "max_cpu_usage": 50 - } - } - }, - { - "name": "setup_filesystem_sh", - "description": "Script to mount partitions at the right directories", - "component_properties": { - "binary_name": "bin/setup_filesystem.sh", - "application_profile": { - "application_type": "Native", - "is_self_terminating": true, - "alive_supervision": { - "reporting_cycle": 0.5, - "failed_cycles_tolerance": 2, - "min_indications": 1, - "max_indications": 3 - } - }, - "depends_on": [ - "test_app2" - ], - "process_arguments": [ - "-a", - "-b" - ], - "ready_condition": { - "process_state": "Terminated" - } - }, - "deployment_config": { - "ready_timeout": 0.5, - "shutdown_timeout": 0.5, - "environmental_variables": [ - { - "key": "LD_LIBRARY_PATH", - "value": "/opt/lib" - }, - { - "key": "GLOBAL_ENV_VAR", - "value": "abc" - }, - { - "key": "EMPTY_GLOBAL_ENV_VAR", - "value": "" - } - ], - "bin_dir": "/opt/scripts", - "working_dir": "/tmp", - "ready_recovery_action_type": "RestartAction", - "ready_recovery_action": { - "number_of_attempts": 1, - "delay_before_restart": 0.5 - }, - "recovery_action_type": "SwitchRunTargetAction", - "recovery_action": { - "run_target": "fallback_run_target" - }, - "sandbox": { - "uid": 1000, - "gid": 1000, - "supplementary_group_ids": [ - 500, - 600, - 700 - ], - "security_policy": "policy_name", - "scheduling_policy": "SCHED_OTHER", - "scheduling_priority": 0, - "max_memory_usage": 1024, - "max_cpu_usage": 75 - } - } - }, - { - "name": "dlt-daemon", - "description": "Logging application", - "component_properties": { - "binary_name": "dltd", - "application_profile": { - "application_type": "Native", - "is_self_terminating": false, - "alive_supervision": { - "reporting_cycle": 0.5, - "failed_cycles_tolerance": 2, - "min_indications": 1, - "max_indications": 3 - } - }, - "depends_on": [ - "setup_filesystem_sh" - ], - "process_arguments": [ - "-a", - "-b", - "--xyz" - ], - "ready_condition": { - "process_state": "Running" - } - }, - "deployment_config": { - "ready_timeout": 0.5, - "shutdown_timeout": 0.5, - "environmental_variables": [ - { - "key": "LD_LIBRARY_PATH", - "value": "/opt/lib" - }, - { - "key": "GLOBAL_ENV_VAR", - "value": "abc" - }, - { - "key": "EMPTY_GLOBAL_ENV_VAR", - "value": "" - } - ], - "bin_dir": "/opt/apps/dlt-daemon", - "working_dir": "/tmp", - "ready_recovery_action_type": "RestartAction", - "ready_recovery_action": { - "number_of_attempts": 1, - "delay_before_restart": 0.5 - }, - "recovery_action_type": "SwitchRunTargetAction", - "recovery_action": { - "run_target": "fallback_run_target" - }, - "sandbox": { - "uid": 1000, - "gid": 1000, - "supplementary_group_ids": [ - 500, - 600, - 700 - ], - "security_policy": "policy_name", - "scheduling_policy": "SCHED_OTHER", - "scheduling_priority": 0, - "max_memory_usage": 1024, - "max_cpu_usage": 75 - } - } - }, - { - "name": "someip-daemon", - "description": "SOME/IP application", - "component_properties": { - "binary_name": "someipd", - "application_profile": { - "application_type": "Reporting_And_Supervised", - "is_self_terminating": false, - "alive_supervision": { - "reporting_cycle": 0.5, - "failed_cycles_tolerance": 2, - "min_indications": 1, - "max_indications": 3 - } - }, - "depends_on": [], - "process_arguments": [ - "-a", - "-b", - "--xyz" - ], - "ready_condition": { - "process_state": "Running" - } - }, - "deployment_config": { - "ready_timeout": 0.5, - "shutdown_timeout": 0.5, - "environmental_variables": [ - { - "key": "LD_LIBRARY_PATH", - "value": "/opt/lib" - }, - { - "key": "GLOBAL_ENV_VAR", - "value": "abc" - }, - { - "key": "EMPTY_GLOBAL_ENV_VAR", - "value": "" - } - ], - "bin_dir": "/opt/apps/someip", - "working_dir": "/tmp", - "ready_recovery_action_type": "RestartAction", - "ready_recovery_action": { - "number_of_attempts": 1, - "delay_before_restart": 0.5 - }, - "recovery_action_type": "SwitchRunTargetAction", - "recovery_action": { - "run_target": "fallback_run_target" - }, - "sandbox": { - "uid": 1000, - "gid": 1000, - "supplementary_group_ids": [ - 500, - 600, - 700 - ], - "security_policy": "policy_name", - "scheduling_policy": "SCHED_OTHER", - "scheduling_priority": 0, - "max_memory_usage": 1024, - "max_cpu_usage": 75 - } - } - }, - { - "name": "test_app1", - "description": "Simple test application", - "component_properties": { - "binary_name": "test_app1", - "application_profile": { - "application_type": "Reporting_And_Supervised", - "is_self_terminating": false, - "alive_supervision": { - "reporting_cycle": 0.5, - "failed_cycles_tolerance": 2, - "min_indications": 1, - "max_indications": 3 - } - }, - "depends_on": [ - "dlt-daemon", - "someip-daemon" - ], - "process_arguments": [ - "-a", - "-b", - "--xyz" - ], - "ready_condition": { - "process_state": "Running" - } - }, - "deployment_config": { - "ready_timeout": 0.5, - "shutdown_timeout": 0.5, - "environmental_variables": [ - { - "key": "LD_LIBRARY_PATH", - "value": "/opt/lib" - }, - { - "key": "GLOBAL_ENV_VAR", - "value": "abc" - }, - { - "key": "EMPTY_GLOBAL_ENV_VAR", - "value": "" - } - ], - "bin_dir": "/opt/apps/test_app1", - "working_dir": "/tmp", - "ready_recovery_action_type": "RestartAction", - "ready_recovery_action": { - "number_of_attempts": 1, - "delay_before_restart": 0.5 - }, - "recovery_action_type": "SwitchRunTargetAction", - "recovery_action": { - "run_target": "fallback_run_target" - }, - "sandbox": { - "uid": 1000, - "gid": 1000, - "supplementary_group_ids": [ - 500, - 600, - 700 - ], - "security_policy": "policy_name", - "scheduling_policy": "SCHED_OTHER", - "scheduling_priority": 0, - "max_memory_usage": 1024, - "max_cpu_usage": 75 - } - } - }, - { - "name": "state_manager", - "description": "Application that manages life cycle of the ECU", - "component_properties": { - "binary_name": "sm", - "application_profile": { - "application_type": "State_Manager", - "is_self_terminating": false, - "alive_supervision": { - "reporting_cycle": 0.5, - "failed_cycles_tolerance": 2, - "min_indications": 1, - "max_indications": 3 - } - }, - "depends_on": [ - "setup_filesystem_sh" - ], - "process_arguments": [ - "-a", - "-b", - "--xyz" - ], - "ready_condition": { - "process_state": "Running" - } - }, - "deployment_config": { - "ready_timeout": 0.5, - "shutdown_timeout": 0.5, - "environmental_variables": [ - { - "key": "LD_LIBRARY_PATH", - "value": "/opt/lib" - }, - { - "key": "GLOBAL_ENV_VAR", - "value": "abc" - }, - { - "key": "EMPTY_GLOBAL_ENV_VAR", - "value": "" - } - ], - "bin_dir": "/opt/apps/state_manager", - "working_dir": "/tmp", - "ready_recovery_action_type": "RestartAction", - "ready_recovery_action": { - "number_of_attempts": 1, - "delay_before_restart": 0.5 - }, - "recovery_action_type": "SwitchRunTargetAction", - "recovery_action": { - "run_target": "fallback_run_target" - }, - "sandbox": { - "uid": 1000, - "gid": 1000, - "supplementary_group_ids": [ - 500, - 600, - 700 - ], - "security_policy": "policy_name", - "scheduling_policy": "SCHED_OTHER", - "scheduling_priority": 0, - "max_memory_usage": 1024, - "max_cpu_usage": 75 - } - } - } - ], - "run_targets": [ - { - "name": "Startup", - "description": "Minimal functionality of the system", - "depends_on": [ - "state_manager" - ], - "transition_timeout": 5, - "recovery_action_type": "SwitchRunTargetAction", - "recovery_action": { - "run_target": "fallback_run_target" - } - }, - { - "name": "Full", - "description": "Everything running", - "depends_on": [ - "test_app1", - "Startup" - ], - "transition_timeout": 5, - "recovery_action_type": "SwitchRunTargetAction", - "recovery_action": { - "run_target": "fallback_run_target" - } - } - ], - "initial_run_target": "Startup", - "fallback_run_target": { - "description": "Switching off everything", - "depends_on": [], - "transition_timeout": 1.5 - }, - "alive_supervision": { - "evaluation_cycle": 0.5 - }, - "watchdog": { - "device_file_path": "/dev/watchdog", - "max_timeout": 2, - "deactivate_on_shutdown": true, - "require_magic_close": false - } -} \ No newline at end of file diff --git a/src/launch_manager_daemon/config/config_schema/launch_manager.schema.json b/src/launch_manager_daemon/config/config_schema/launch_manager.schema.json index a0f8d6527..371630d73 100644 --- a/src/launch_manager_daemon/config/config_schema/launch_manager.schema.json +++ b/src/launch_manager_daemon/config/config_schema/launch_manager.schema.json @@ -95,9 +95,7 @@ "additionalProperties": false } }, - "required": [ - "recovery_action" - ], + "required": [], "additionalProperties": false }, "recovery_action": { From b5f777f0550b975660494d5d8ea6b949494e24a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Fu=C3=9Fberger?= Date: Tue, 19 May 2026 13:02:01 +0200 Subject: [PATCH 10/26] Run formater on new code --- MODULE.bazel | 2 +- src/launch_manager_daemon/config/BUILD | 1 - .../config/include/config.hpp | 143 ++++++++++----- .../config/include/config_loader.hpp | 43 ++--- .../include/flatbuffer_config_loader.hpp | 37 ++-- .../config/lm_flatcfg_generated.h | 12 ++ .../config/src/config.cpp | 28 +-- .../config/src/flatbuffer_config_loader.cpp | 48 ++--- .../src/flatbuffer_config_loader_UT.cpp | 165 ++++++++++-------- .../config/hm_flatcfg_generated.h | 12 ++ .../config/hmcore_flatcfg_generated.h | 12 ++ 11 files changed, 311 insertions(+), 192 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index a8cec0078..1b7d4fb7b 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -133,6 +133,7 @@ use_repo(oci, "debian-test-runtime", "debian-test-runtime_linux_amd64") bazel_dep(name = "score_baselibs_rust", version = "0.1.2") bazel_dep(name = "score_baselibs", version = "0.2.6") + # Temporarily overwrite baselibs to use the new flatbuffer config loader until there is a new release git_override( module_name = "score_baselibs", @@ -140,7 +141,6 @@ git_override( remote = "https://github.com/eclipse-score/baselibs.git", ) - # Hedron's Compile Commands Extractor for Bazel # https://github.com/hedronvision/bazel-compile-commands-extractor bazel_dep(name = "hedron_compile_commands", dev_dependency = True) diff --git a/src/launch_manager_daemon/config/BUILD b/src/launch_manager_daemon/config/BUILD index 04c076566..39d3a2f2f 100644 --- a/src/launch_manager_daemon/config/BUILD +++ b/src/launch_manager_daemon/config/BUILD @@ -80,4 +80,3 @@ cc_test( "@googletest//:gtest_main", ], ) - diff --git a/src/launch_manager_daemon/config/include/config.hpp b/src/launch_manager_daemon/config/include/config.hpp index 0a973089a..5b3160703 100644 --- a/src/launch_manager_daemon/config/include/config.hpp +++ b/src/launch_manager_daemon/config/include/config.hpp @@ -1,16 +1,15 @@ -// ******************************************************************************* -// Copyright (c) 2026 Contributors to the Eclipse Foundation -// -// See the NOTICE file(s) distributed with this work for additional -// information regarding copyright ownership. -// -// This program and the accompanying materials are made available under the -// terms of the Apache License Version 2.0 which is available at -// https://www.apache.org/licenses/LICENSE-2.0 -// -// SPDX-License-Identifier: Apache-2.0 -// ******************************************************************************* - +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ #ifndef CONFIG_HPP #define CONFIG_HPP @@ -21,38 +20,45 @@ #include #include -namespace score::launch_manager::config { +namespace score::launch_manager::config +{ -enum class ApplicationType : uint8_t { +enum class ApplicationType : uint8_t +{ Native = 0, Reporting = 1, ReportingAndSupervised = 2, StateManager = 3 }; -enum class ProcessState : uint8_t { +enum class ProcessState : uint8_t +{ Running = 0, Terminated = 1 }; -struct ComponentAliveSupervision { +struct ComponentAliveSupervision +{ uint32_t reporting_cycle_ms{}; uint32_t failed_cycles_tolerance{}; uint32_t min_indications{}; uint32_t max_indications{}; }; -struct ApplicationProfile { +struct ApplicationProfile +{ ApplicationType application_type{ApplicationType::Native}; bool is_self_terminating{}; std::optional alive_supervision; }; -struct ReadyCondition { +struct ReadyCondition +{ ProcessState process_state{ProcessState::Running}; }; -struct ComponentProperties { +struct ComponentProperties +{ std::string binary_name; ApplicationProfile application_profile; std::vector depends_on; @@ -60,16 +66,19 @@ struct ComponentProperties { ReadyCondition ready_condition; }; -struct RestartAction { +struct RestartAction +{ uint32_t number_of_attempts{}; uint32_t delay_before_restart_ms{}; }; -struct SwitchRunTargetAction { +struct SwitchRunTargetAction +{ std::string run_target; }; -struct Sandbox { +struct Sandbox +{ uint32_t uid{}; uint32_t gid{}; std::vector supplementary_group_ids; @@ -80,7 +89,8 @@ struct Sandbox { std::optional max_cpu_usage; }; -struct DeploymentConfig { +struct DeploymentConfig +{ uint32_t ready_timeout_ms{}; uint32_t shutdown_timeout_ms{}; std::unordered_map environmental_variables; @@ -92,14 +102,16 @@ struct DeploymentConfig { std::optional sandbox; }; -struct ComponentConfig { +struct ComponentConfig +{ std::string name; std::string description; ComponentProperties component_properties; DeploymentConfig deployment_config; }; -struct RunTargetConfig { +struct RunTargetConfig +{ std::string name; std::string description; std::vector depends_on; @@ -107,17 +119,20 @@ struct RunTargetConfig { SwitchRunTargetAction recovery_action; }; -struct FallbackRunTargetConfig { +struct FallbackRunTargetConfig +{ std::string description; std::vector depends_on; uint32_t transition_timeout_ms{}; }; -struct AliveSupervisionConfig { +struct AliveSupervisionConfig +{ uint32_t evaluation_cycle_ms{}; }; -struct WatchdogConfig { +struct WatchdogConfig +{ std::string device_file_path; uint32_t max_timeout_ms{}; bool deactivate_on_shutdown{}; @@ -131,16 +146,18 @@ struct WatchdogConfig { /// (e.g. ComponentConfig to Component). /// /// @note As of now, everything is expected in a single config file. -/// Even though some fields appear as optional in the json schema, they are only optional if the configuration would be split across multiple files. -/// As only a single file is supported, the single config will contain all fields. -class Config { +/// Even though some fields appear as optional in the json schema, they are only optional if the configuration would be +/// split across multiple files. As only a single file is supported, the single config will contain all fields. +class Config +{ public: Config(const Config&) = delete; Config& operator=(const Config&) = delete; Config(Config&&) = default; Config& operator=(Config&&) = default; - class Builder { + class Builder + { public: Builder& setComponents(std::vector components); Builder& setRunTargets(std::vector run_targets); @@ -161,20 +178,56 @@ class Config { }; // Read access - const std::vector& components() const { return components_; } - const std::vector& run_targets() const { return run_targets_; } - std::string_view initial_run_target() const { return initial_run_target_; } - const FallbackRunTargetConfig& fallback_run_target() const { return fallback_run_target_; } - const AliveSupervisionConfig& alive_supervision() const { return alive_supervision_; } - const std::optional& watchdog() const { return watchdog_; } + const std::vector& components() const + { + return components_; + } + const std::vector& run_targets() const + { + return run_targets_; + } + std::string_view initial_run_target() const + { + return initial_run_target_; + } + const FallbackRunTargetConfig& fallback_run_target() const + { + return fallback_run_target_; + } + const AliveSupervisionConfig& alive_supervision() const + { + return alive_supervision_; + } + const std::optional& watchdog() const + { + return watchdog_; + } // Ownership transfer — source is left in a moved-from state after the call - std::vector take_components() { return std::move(components_); } - std::vector take_run_targets() { return std::move(run_targets_); } - std::string take_initial_run_target() { return std::move(initial_run_target_); } - FallbackRunTargetConfig take_fallback_run_target() { return std::move(fallback_run_target_); } - AliveSupervisionConfig take_alive_supervision() { return std::move(alive_supervision_); } - std::optional take_watchdog() { return std::move(watchdog_); } + std::vector take_components() + { + return std::move(components_); + } + std::vector take_run_targets() + { + return std::move(run_targets_); + } + std::string take_initial_run_target() + { + return std::move(initial_run_target_); + } + FallbackRunTargetConfig take_fallback_run_target() + { + return std::move(fallback_run_target_); + } + AliveSupervisionConfig take_alive_supervision() + { + return std::move(alive_supervision_); + } + std::optional take_watchdog() + { + return std::move(watchdog_); + } private: friend class Builder; diff --git a/src/launch_manager_daemon/config/include/config_loader.hpp b/src/launch_manager_daemon/config/include/config_loader.hpp index 451b13fdb..2eae7a38d 100644 --- a/src/launch_manager_daemon/config/include/config_loader.hpp +++ b/src/launch_manager_daemon/config/include/config_loader.hpp @@ -1,16 +1,15 @@ -// ******************************************************************************* -// Copyright (c) 2026 Contributors to the Eclipse Foundation -// -// See the NOTICE file(s) distributed with this work for additional -// information regarding copyright ownership. -// -// This program and the accompanying materials are made available under the -// terms of the Apache License Version 2.0 which is available at -// https://www.apache.org/licenses/LICENSE-2.0 -// -// SPDX-License-Identifier: Apache-2.0 -// ******************************************************************************* - +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ #ifndef CONFIG_LOADER_HPP #define CONFIG_LOADER_HPP @@ -18,25 +17,27 @@ #include "score/filesystem/path.h" -#include #include +#include -namespace score::launch_manager::config { +namespace score::launch_manager::config +{ /// @brief Abstract interface for loading Launch Manager configuration from a file. /// /// Decouples the configuration consumer from the serialization format (e.g., JSON, FlatBuffers). /// A concrete implementation parses the file and returns a format-independent @ref Config object. -class IConfigLoader { +class IConfigLoader +{ public: /// @brief Error codes returned when configuration loading fails. enum class Error : std::uint32_t { - FileNotFound, ///< The configuration file does not exist at the given path. - InsufficientPermission, ///< The process lacks read permissions for the file. - InvalidFormat, ///< The file contents could not be parsed (malformed or missing required fields). - UnsupportedVersion, ///< The file uses a configuration schema version not supported by this loader. - GeneralError ///< Any other failure not covered by the above codes. + FileNotFound, ///< The configuration file does not exist at the given path. + InsufficientPermission, ///< The process lacks read permissions for the file. + InvalidFormat, ///< The file contents could not be parsed (malformed or missing required fields). + UnsupportedVersion, ///< The file uses a configuration schema version not supported by this loader. + GeneralError ///< Any other failure not covered by the above codes. }; virtual ~IConfigLoader() = default; diff --git a/src/launch_manager_daemon/config/include/flatbuffer_config_loader.hpp b/src/launch_manager_daemon/config/include/flatbuffer_config_loader.hpp index 3c884d30f..f23dfc5e2 100644 --- a/src/launch_manager_daemon/config/include/flatbuffer_config_loader.hpp +++ b/src/launch_manager_daemon/config/include/flatbuffer_config_loader.hpp @@ -1,16 +1,15 @@ -// ******************************************************************************* -// Copyright (c) 2026 Contributors to the Eclipse Foundation -// -// See the NOTICE file(s) distributed with this work for additional -// information regarding copyright ownership. -// -// This program and the accompanying materials are made available under the -// terms of the Apache License Version 2.0 which is available at -// https://www.apache.org/licenses/LICENSE-2.0 -// -// SPDX-License-Identifier: Apache-2.0 -// ******************************************************************************* - +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ #ifndef FLATBUFFER_CONFIG_LOADER_HPP #define FLATBUFFER_CONFIG_LOADER_HPP @@ -21,10 +20,12 @@ #include #include -namespace score::launch_manager::config { +namespace score::launch_manager::config +{ /// @brief Internal helpers for FlatBuffer config parsing. -namespace details { +namespace details +{ score::cpp::expected parseFlatbuffer(const std::vector& buffer); IConfigLoader::Error mapOsError(const score::os::Error& error); @@ -36,7 +37,8 @@ IConfigLoader::Error mapOsError(const score::os::Error& error); /// Exists as a named type so that FlatbufferConfigLoaderImpl can be parameterized on the /// buffer-loading strategy. In production the default is used; in tests a mock /// loader can be substituted without virtual dispatch overhead. -struct DefaultBufferLoader { +struct DefaultBufferLoader +{ static score::os::Result> load(const score::filesystem::Path& path) { return score::flatbuffers::LoadBuffer(path); @@ -47,7 +49,8 @@ struct DefaultBufferLoader { /// @tparam BufferLoaderT Policy type providing a static `load(path)` method. /// Defaults to DefaultBufferLoader; replace with a mock for testing. template -class FlatbufferConfigLoaderImpl : public IConfigLoader { +class FlatbufferConfigLoaderImpl : public IConfigLoader +{ public: score::cpp::expected load(const score::filesystem::Path& path) override { diff --git a/src/launch_manager_daemon/config/lm_flatcfg_generated.h b/src/launch_manager_daemon/config/lm_flatcfg_generated.h index 6c7fbac3b..83ed21465 100644 --- a/src/launch_manager_daemon/config/lm_flatcfg_generated.h +++ b/src/launch_manager_daemon/config/lm_flatcfg_generated.h @@ -1,3 +1,15 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ // automatically generated by the FlatBuffers compiler, do not modify diff --git a/src/launch_manager_daemon/config/src/config.cpp b/src/launch_manager_daemon/config/src/config.cpp index f179522c9..baa7284c0 100644 --- a/src/launch_manager_daemon/config/src/config.cpp +++ b/src/launch_manager_daemon/config/src/config.cpp @@ -1,21 +1,21 @@ -// ******************************************************************************* -// Copyright (c) 2026 Contributors to the Eclipse Foundation -// -// See the NOTICE file(s) distributed with this work for additional -// information regarding copyright ownership. -// -// This program and the accompanying materials are made available under the -// terms of the Apache License Version 2.0 which is available at -// https://www.apache.org/licenses/LICENSE-2.0 -// -// SPDX-License-Identifier: Apache-2.0 -// ******************************************************************************* - +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ #include "config.hpp" #include -namespace score::launch_manager::config { +namespace score::launch_manager::config +{ Config::Config(std::vector components, std::vector run_targets, diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp index 88b22043a..bd2332b01 100644 --- a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp @@ -1,16 +1,15 @@ -// ******************************************************************************* -// Copyright (c) 2026 Contributors to the Eclipse Foundation -// -// See the NOTICE file(s) distributed with this work for additional -// information regarding copyright ownership. -// -// This program and the accompanying materials are made available under the -// terms of the Apache License Version 2.0 which is available at -// https://www.apache.org/licenses/LICENSE-2.0 -// -// SPDX-License-Identifier: Apache-2.0 -// ******************************************************************************* - +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ #include "flatbuffer_config_loader.hpp" #include "new_lm_flatcfg_generated.h" @@ -21,11 +20,13 @@ #include #include -namespace score::launch_manager::config { +namespace score::launch_manager::config +{ namespace fb = score::launch_manager::config::fb; -namespace { +namespace +{ constexpr int32_t kExpectedSchemaVersion = 1; constexpr double kSecondsToMilliseconds = 1000.0; @@ -212,14 +213,13 @@ std::optional convertSandbox(const fb::Sandbox* fb_sb) result.uid = fb_sb->uid(); result.gid = fb_sb->gid(); result.supplementary_group_ids = convertUint32Vector(fb_sb->supplementary_group_ids()); - result.security_policy = - fb_sb->security_policy() != nullptr ? std::optional{fb_sb->security_policy()->str()} - : std::nullopt; + result.security_policy = fb_sb->security_policy() != nullptr + ? std::optional{fb_sb->security_policy()->str()} + : std::nullopt; result.scheduling_policy = safeString(fb_sb->scheduling_policy()); result.scheduling_priority = fb_sb->scheduling_priority().value_or(0); - result.max_memory_usage = fb_sb->max_memory_usage().has_value() - ? std::optional{*fb_sb->max_memory_usage()} - : std::nullopt; + result.max_memory_usage = + fb_sb->max_memory_usage().has_value() ? std::optional{*fb_sb->max_memory_usage()} : std::nullopt; result.max_cpu_usage = fb_sb->max_cpu_usage().has_value() ? std::optional{*fb_sb->max_cpu_usage()} : std::nullopt; return result; @@ -299,14 +299,16 @@ std::optional convertWatchdog(const fb::Watchdog* fb_wd) WatchdogConfig result{}; result.device_file_path = safeString(fb_wd->device_file_path()); result.max_timeout_ms = secondsToMs(fb_wd->max_timeout()); - result.deactivate_on_shutdown = fb_wd->deactivate_on_shutdown().has_value() ? *fb_wd->deactivate_on_shutdown() : false; + result.deactivate_on_shutdown = + fb_wd->deactivate_on_shutdown().has_value() ? *fb_wd->deactivate_on_shutdown() : false; result.require_magic_close = fb_wd->require_magic_close().has_value() ? *fb_wd->require_magic_close() : false; return result; } } // anonymous namespace -namespace details { +namespace details +{ // --- File I/O error mapping --- diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp index f1cad8ecf..61d7b8e11 100644 --- a/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp @@ -1,16 +1,15 @@ -// ******************************************************************************* -// Copyright (c) 2026 Contributors to the Eclipse Foundation -// -// See the NOTICE file(s) distributed with this work for additional -// information regarding copyright ownership. -// -// This program and the accompanying materials are made available under the -// terms of the Apache License Version 2.0 which is available at -// https://www.apache.org/licenses/LICENSE-2.0 -// -// SPDX-License-Identifier: Apache-2.0 -// ******************************************************************************* - +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ #include "flatbuffer_config_loader.hpp" #include "new_lm_flatcfg_generated.h" @@ -24,8 +23,10 @@ #include #include -namespace score::launch_manager::config { -namespace { +namespace score::launch_manager::config +{ +namespace +{ namespace fb = score::launch_manager::config::fb; @@ -47,20 +48,20 @@ std::vector finishBuffer(::flatbuffers::FlatBufferBuilder& fbb, // Helper functions to reduce test boilerplate // ============================================================================ -::flatbuffers::Offset buildDefaultComponentProperties( - ::flatbuffers::FlatBufferBuilder& fbb) +::flatbuffers::Offset buildDefaultComponentProperties(::flatbuffers::FlatBufferBuilder& fbb) { auto bin_name = fbb.CreateString("default_bin"); auto app_profile = fb::CreateApplicationProfile(fbb); auto ready_cond = fb::CreateReadyCondition(fbb); - return fb::CreateComponentProperties(fbb, bin_name, app_profile, 0 /*depends_on*/, 0 /*process_arguments*/, ready_cond); + return fb::CreateComponentProperties( + fbb, bin_name, app_profile, 0 /*depends_on*/, 0 /*process_arguments*/, ready_cond); } -::flatbuffers::Offset buildDefaultDeploymentConfig( - ::flatbuffers::FlatBufferBuilder& fbb) +::flatbuffers::Offset buildDefaultDeploymentConfig(::flatbuffers::FlatBufferBuilder& fbb) { auto bin_dir = fbb.CreateString("/opt"); - return fb::CreateDeploymentConfig(fbb, 0.0 /*ready_timeout*/, 0.0 /*shutdown_timeout*/, 0 /*environmental_variables*/, bin_dir); + return fb::CreateDeploymentConfig( + fbb, 0.0 /*ready_timeout*/, 0.0 /*shutdown_timeout*/, 0 /*environmental_variables*/, bin_dir); } ::flatbuffers::Offset buildDefaultComponent( @@ -69,10 +70,12 @@ ::flatbuffers::Offset buildDefaultComponent( ::flatbuffers::Offset comp_props = 0, ::flatbuffers::Offset deploy = 0) { - if (comp_props.IsNull()) { + if (comp_props.IsNull()) + { comp_props = buildDefaultComponentProperties(fbb); } - if (deploy.IsNull()) { + if (deploy.IsNull()) + { deploy = buildDefaultDeploymentConfig(fbb); } auto comp_name = fbb.CreateString(name); @@ -86,7 +89,8 @@ std::vector buildConfigWithComponents( auto fallback = fb::CreateFallbackRunTarget(fbb); auto alive_sup = fb::CreateAliveSupervision(fbb); auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, comps, 0 /*run_targets*/, irt, fallback, alive_sup); + auto config = + fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, comps, 0 /*run_targets*/, irt, fallback, alive_sup); return finishBuffer(fbb, config); } @@ -97,13 +101,15 @@ std::vector buildConfigWithRunTargets( auto fallback = fb::CreateFallbackRunTarget(fbb); auto alive_sup = fb::CreateAliveSupervision(fbb); auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, 0 /*components*/, rts, irt, fallback, alive_sup); + auto config = + fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, 0 /*components*/, rts, irt, fallback, alive_sup); return finishBuffer(fbb, config); } // ============================================================================ -struct MockBufferLoader { +struct MockBufferLoader +{ static score::os::Result> load(const score::filesystem::Path&) { return result_; @@ -113,7 +119,8 @@ struct MockBufferLoader { score::os::Result> MockBufferLoader::result_{std::vector{}}; -class FlatbufferConfigLoaderTest : public ::testing::Test { +class FlatbufferConfigLoaderTest : public ::testing::Test +{ protected: void SetUp() override { @@ -122,8 +129,7 @@ class FlatbufferConfigLoaderTest : public ::testing::Test { MockBufferLoader::result_ = std::vector{}; } - std::vector buildMinimalConfig(int32_t schema_version = 1, - const char* initial_run_target = "Startup") + std::vector buildMinimalConfig(int32_t schema_version = 1, const char* initial_run_target = "Startup") { ::flatbuffers::FlatBufferBuilder fbb; auto irt = fbb.CreateString(initial_run_target); @@ -166,10 +172,10 @@ TEST_F(FlatbufferConfigLoaderTest, LoadSingleComponent) ::flatbuffers::FlatBufferBuilder fbb; - auto alive_sup = fb::CreateComponentAliveSupervision(fbb, - 0.5 /*reporting_cycle*/, 2 /*failed_cycles_tolerance*/, 1 /*min_indications*/, 3 /*max_indications*/); - auto app_profile = - fb::CreateApplicationProfile(fbb, fb::ApplicationType::Reporting_And_Supervised, true /*is_self_terminating*/, alive_sup); + auto alive_sup = fb::CreateComponentAliveSupervision( + fbb, 0.5 /*reporting_cycle*/, 2 /*failed_cycles_tolerance*/, 1 /*min_indications*/, 3 /*max_indications*/); + auto app_profile = fb::CreateApplicationProfile( + fbb, fb::ApplicationType::Reporting_And_Supervised, true /*is_self_terminating*/, alive_sup); auto bin_name = fbb.CreateString("my_binary"); auto dep = fbb.CreateString("other_comp"); auto deps_vec = fbb.CreateVector(std::vector<::flatbuffers::Offset<::flatbuffers::String>>{dep}); @@ -180,8 +186,8 @@ TEST_F(FlatbufferConfigLoaderTest, LoadSingleComponent) auto bin_dir = fbb.CreateString("/opt/bin"); auto work_dir = fbb.CreateString("/tmp"); - auto deploy = fb::CreateDeploymentConfig(fbb, - 1.5 /*ready_timeout*/, 2.5 /*shutdown_timeout*/, 0 /*environmental_variables*/, bin_dir, work_dir); + auto deploy = fb::CreateDeploymentConfig( + fbb, 1.5 /*ready_timeout*/, 2.5 /*shutdown_timeout*/, 0 /*environmental_variables*/, bin_dir, work_dir); auto comp_name = fbb.CreateString("TestComponent"); auto comp_desc = fbb.CreateString("A test component"); @@ -197,7 +203,8 @@ TEST_F(FlatbufferConfigLoaderTest, LoadSingleComponent) EXPECT_THAT(comp.name, Eq("TestComponent")); EXPECT_THAT(comp.description, Eq("A test component")); EXPECT_THAT(comp.component_properties.binary_name, Eq("my_binary")); - EXPECT_THAT(comp.component_properties.application_profile.application_type, Eq(ApplicationType::ReportingAndSupervised)); + EXPECT_THAT(comp.component_properties.application_profile.application_type, + Eq(ApplicationType::ReportingAndSupervised)); EXPECT_THAT(comp.component_properties.application_profile.is_self_terminating, IsTrue()); ASSERT_THAT(comp.component_properties.application_profile.alive_supervision.has_value(), IsTrue()); EXPECT_THAT(comp.component_properties.application_profile.alive_supervision->reporting_cycle_ms, Eq(500U)); @@ -257,7 +264,8 @@ TEST_F(FlatbufferConfigLoaderTest, LoadFallbackRunTarget) auto alive_sup = fb::CreateAliveSupervision(fbb); auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, 0 /*components*/, 0 /*run_targets*/, irt, fallback, alive_sup); + auto config = fb::CreateLaunchManagerConfig( + fbb, 1 /*schema_version*/, 0 /*components*/, 0 /*run_targets*/, irt, fallback, alive_sup); auto result = loadBuffer(finishBuffer(fbb, config)); @@ -278,7 +286,8 @@ TEST_F(FlatbufferConfigLoaderTest, LoadAliveSupervision) auto alive_sup = fb::CreateAliveSupervision(fbb, 0.25 /*evaluation_cycle*/); auto fallback = fb::CreateFallbackRunTarget(fbb); auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, 0 /*components*/, 0 /*run_targets*/, irt, fallback, alive_sup); + auto config = fb::CreateLaunchManagerConfig( + fbb, 1 /*schema_version*/, 0 /*components*/, 0 /*run_targets*/, irt, fallback, alive_sup); auto result = loadBuffer(finishBuffer(fbb, config)); @@ -293,13 +302,14 @@ TEST_F(FlatbufferConfigLoaderTest, LoadWatchdog) ::flatbuffers::FlatBufferBuilder fbb; auto dev_path = fbb.CreateString("/dev/watchdog0"); - auto watchdog = fb::CreateWatchdog(fbb, dev_path, - 30.0 /*max_timeout*/, true /*deactivate_on_shutdown*/, false /*require_magic_close*/); + auto watchdog = fb::CreateWatchdog( + fbb, dev_path, 30.0 /*max_timeout*/, true /*deactivate_on_shutdown*/, false /*require_magic_close*/); auto fallback = fb::CreateFallbackRunTarget(fbb); auto alive_sup = fb::CreateAliveSupervision(fbb); auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, 0 /*components*/, 0 /*run_targets*/, irt, fallback, alive_sup, watchdog); + auto config = fb::CreateLaunchManagerConfig( + fbb, 1 /*schema_version*/, 0 /*components*/, 0 /*run_targets*/, irt, fallback, alive_sup, watchdog); auto result = loadBuffer(finishBuffer(fbb, config)); @@ -322,11 +332,14 @@ TEST_F(FlatbufferConfigLoaderTest, LoadRestartRecoveryAction) auto restart = fb::CreateRestartAction(fbb, 3 /*number_of_attempts*/, 1.5 /*delay_before_restart*/); auto bin_dir = fbb.CreateString("/opt"); auto deploy = fb::CreateDeploymentConfig(fbb, - 0.0 /*ready_timeout*/, 0.0 /*shutdown_timeout*/, 0 /*environmental_variables*/, bin_dir, 0 /*working_dir*/, - restart); - - auto comp = buildDefaultComponent(fbb, "restart_comp", - buildDefaultComponentProperties(fbb), deploy); + 0.0 /*ready_timeout*/, + 0.0 /*shutdown_timeout*/, + 0 /*environmental_variables*/, + bin_dir, + 0 /*working_dir*/, + restart); + + auto comp = buildDefaultComponent(fbb, "restart_comp", buildDefaultComponentProperties(fbb), deploy); auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); @@ -349,7 +362,8 @@ TEST_F(FlatbufferConfigLoaderTest, LoadSwitchRunTargetAction) auto target_name = fbb.CreateString("Fallback"); auto switch_action = fb::CreateSwitchRunTargetAction(fbb, target_name); auto rt_name = fbb.CreateString("Startup"); - auto rt = fb::CreateRunTarget(fbb, rt_name, 0 /*description*/, 0 /*depends_on*/, 0.0 /*transition_timeout*/, switch_action); + auto rt = fb::CreateRunTarget( + fbb, rt_name, 0 /*description*/, 0 /*depends_on*/, 0.0 /*transition_timeout*/, switch_action); auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{rt}); auto result = loadBuffer(buildConfigWithRunTargets(fbb, rts)); @@ -368,18 +382,28 @@ TEST_F(FlatbufferConfigLoaderTest, LoadSandbox) auto sched_policy = fbb.CreateString("SCHED_FIFO"); auto supp_gids = fbb.CreateVector(std::vector{100, 200}); auto sandbox = fb::CreateSandbox(fbb, - 1000 /*uid*/, 1000 /*gid*/, supp_gids, sec_policy, sched_policy, - 50 /*scheduling_priority*/, 4096 /*max_memory_usage*/, 80 /*max_cpu_usage*/); + 1000 /*uid*/, + 1000 /*gid*/, + supp_gids, + sec_policy, + sched_policy, + 50 /*scheduling_priority*/, + 4096 /*max_memory_usage*/, + 80 /*max_cpu_usage*/); auto bin_dir = fbb.CreateString("/opt"); auto work_dir = fbb.CreateString("/tmp"); auto deploy = fb::CreateDeploymentConfig(fbb, - 0.5 /*ready_timeout*/, 0.5 /*shutdown_timeout*/, 0 /*environmental_variables*/, bin_dir, work_dir, - 0 /*ready_recovery_action*/, - 0 /*recovery_action*/, sandbox); - - auto comp = buildDefaultComponent(fbb, "sandboxed_comp", - buildDefaultComponentProperties(fbb), deploy); + 0.5 /*ready_timeout*/, + 0.5 /*shutdown_timeout*/, + 0 /*environmental_variables*/, + bin_dir, + work_dir, + 0 /*ready_recovery_action*/, + 0 /*recovery_action*/, + sandbox); + + auto comp = buildDefaultComponent(fbb, "sandboxed_comp", buildDefaultComponentProperties(fbb), deploy); auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); @@ -408,13 +432,14 @@ TEST_F(FlatbufferConfigLoaderTest, LoadComponentAliveSupervision) ::flatbuffers::FlatBufferBuilder fbb; - auto comp_alive_sup = fb::CreateComponentAliveSupervision(fbb, - 1.0 /*reporting_cycle*/, 3 /*failed_cycles_tolerance*/, 2 /*min_indications*/, 5 /*max_indications*/); - auto app_profile = fb::CreateApplicationProfile(fbb, - fb::ApplicationType::Reporting_And_Supervised, false /*is_self_terminating*/, comp_alive_sup); + auto comp_alive_sup = fb::CreateComponentAliveSupervision( + fbb, 1.0 /*reporting_cycle*/, 3 /*failed_cycles_tolerance*/, 2 /*min_indications*/, 5 /*max_indications*/); + auto app_profile = fb::CreateApplicationProfile( + fbb, fb::ApplicationType::Reporting_And_Supervised, false /*is_self_terminating*/, comp_alive_sup); auto bin_name = fbb.CreateString("supervised_bin"); auto ready_cond = fb::CreateReadyCondition(fbb); - auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile, 0 /*depends_on*/, 0 /*process_arguments*/, ready_cond); + auto comp_props = fb::CreateComponentProperties( + fbb, bin_name, app_profile, 0 /*depends_on*/, 0 /*process_arguments*/, ready_cond); auto comp = buildDefaultComponent(fbb, "supervised_comp", comp_props); auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); @@ -446,11 +471,10 @@ TEST_F(FlatbufferConfigLoaderTest, LoadEnvironmentalVariables) auto bin_dir = fbb.CreateString("/opt"); auto work_dir = fbb.CreateString("/tmp"); - auto deploy = fb::CreateDeploymentConfig(fbb, - 0.5 /*ready_timeout*/, 0.5 /*shutdown_timeout*/, env_vars, bin_dir, work_dir); + auto deploy = + fb::CreateDeploymentConfig(fbb, 0.5 /*ready_timeout*/, 0.5 /*shutdown_timeout*/, env_vars, bin_dir, work_dir); - auto comp = buildDefaultComponent(fbb, "env_comp", - buildDefaultComponentProperties(fbb), deploy); + auto comp = buildDefaultComponent(fbb, "env_comp", buildDefaultComponentProperties(fbb), deploy); auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); @@ -471,8 +495,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadMultipleComponents) auto comp_a = buildDefaultComponent(fbb, "CompA"); auto comp_b = buildDefaultComponent(fbb, "CompB"); auto comp_c = buildDefaultComponent(fbb, "CompC"); - auto comps = fbb.CreateVector( - std::vector<::flatbuffers::Offset>{comp_a, comp_b, comp_c}); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp_a, comp_b, comp_c}); auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); @@ -525,7 +548,8 @@ TEST_F(FlatbufferConfigLoaderTest, MapNativeApplicationType) auto app_profile = fb::CreateApplicationProfile(fbb, fb::ApplicationType::Native); auto bin_name = fbb.CreateString("native_bin"); auto ready_cond = fb::CreateReadyCondition(fbb); - auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile, 0 /*depends_on*/, 0 /*process_arguments*/, ready_cond); + auto comp_props = fb::CreateComponentProperties( + fbb, bin_name, app_profile, 0 /*depends_on*/, 0 /*process_arguments*/, ready_cond); auto comp = buildDefaultComponent(fbb, "native_comp", comp_props); auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); @@ -547,7 +571,8 @@ TEST_F(FlatbufferConfigLoaderTest, MapReportingAndSupervisedType) auto app_profile = fb::CreateApplicationProfile(fbb, fb::ApplicationType::Reporting_And_Supervised); auto bin_name = fbb.CreateString("supervised_bin"); auto ready_cond = fb::CreateReadyCondition(fbb); - auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile, 0 /*depends_on*/, 0 /*process_arguments*/, ready_cond); + auto comp_props = fb::CreateComponentProperties( + fbb, bin_name, app_profile, 0 /*depends_on*/, 0 /*process_arguments*/, ready_cond); auto comp = buildDefaultComponent(fbb, "supervised_comp", comp_props); auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); @@ -568,8 +593,8 @@ TEST_F(FlatbufferConfigLoaderTest, MapTerminatedProcessState) auto app_profile = fb::CreateApplicationProfile(fbb); auto ready_cond = fb::CreateReadyCondition(fbb, fb::ProcessState::Terminated); auto bin_name = fbb.CreateString("term_bin"); - auto comp_props = fb::CreateComponentProperties(fbb, - bin_name, app_profile, 0 /*depends_on*/, 0 /*process_arguments*/, ready_cond); + auto comp_props = fb::CreateComponentProperties( + fbb, bin_name, app_profile, 0 /*depends_on*/, 0 /*process_arguments*/, ready_cond); auto comp = buildDefaultComponent(fbb, "term_comp", comp_props); auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); diff --git a/src/launch_manager_daemon/health_monitor_lib/config/hm_flatcfg_generated.h b/src/launch_manager_daemon/health_monitor_lib/config/hm_flatcfg_generated.h index 11c90e45b..528648266 100644 --- a/src/launch_manager_daemon/health_monitor_lib/config/hm_flatcfg_generated.h +++ b/src/launch_manager_daemon/health_monitor_lib/config/hm_flatcfg_generated.h @@ -1,3 +1,15 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ // automatically generated by the FlatBuffers compiler, do not modify diff --git a/src/launch_manager_daemon/health_monitor_lib/config/hmcore_flatcfg_generated.h b/src/launch_manager_daemon/health_monitor_lib/config/hmcore_flatcfg_generated.h index b4fa6ed72..8b27af346 100644 --- a/src/launch_manager_daemon/health_monitor_lib/config/hmcore_flatcfg_generated.h +++ b/src/launch_manager_daemon/health_monitor_lib/config/hmcore_flatcfg_generated.h @@ -1,3 +1,15 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ // automatically generated by the FlatBuffers compiler, do not modify From eb8a04453986fc019db9edc50cea3dc6d8588870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Fu=C3=9Fberger?= Date: Thu, 21 May 2026 08:21:50 +0200 Subject: [PATCH 11/26] Change method names to CamelCase --- .../config/include/config.hpp | 22 +++++++++---------- .../src/flatbuffer_config_loader_UT.cpp | 14 ++++++------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/launch_manager_daemon/config/include/config.hpp b/src/launch_manager_daemon/config/include/config.hpp index 5b3160703..a917d489b 100644 --- a/src/launch_manager_daemon/config/include/config.hpp +++ b/src/launch_manager_daemon/config/include/config.hpp @@ -142,7 +142,7 @@ struct WatchdogConfig /// @brief Move-only value object holding the parsed launch-manager configuration. /// /// Loaded once by an IConfigLoader, then individual parts are moved out via -/// the `take_*()` accessors to transfer ownership to dedicated domain objects +/// the `take*()` accessors to transfer ownership to dedicated domain objects /// (e.g. ComponentConfig to Component). /// /// @note As of now, everything is expected in a single config file. @@ -182,19 +182,19 @@ class Config { return components_; } - const std::vector& run_targets() const + const std::vector& runTargets() const { return run_targets_; } - std::string_view initial_run_target() const + std::string_view initialRunTarget() const { return initial_run_target_; } - const FallbackRunTargetConfig& fallback_run_target() const + const FallbackRunTargetConfig& fallbackRunTarget() const { return fallback_run_target_; } - const AliveSupervisionConfig& alive_supervision() const + const AliveSupervisionConfig& aliveSupervision() const { return alive_supervision_; } @@ -204,27 +204,27 @@ class Config } // Ownership transfer — source is left in a moved-from state after the call - std::vector take_components() + std::vector takeComponents() { return std::move(components_); } - std::vector take_run_targets() + std::vector takeRunTargets() { return std::move(run_targets_); } - std::string take_initial_run_target() + std::string takeInitialRunTarget() { return std::move(initial_run_target_); } - FallbackRunTargetConfig take_fallback_run_target() + FallbackRunTargetConfig takeFallbackRunTarget() { return std::move(fallback_run_target_); } - AliveSupervisionConfig take_alive_supervision() + AliveSupervisionConfig takeAliveSupervision() { return std::move(alive_supervision_); } - std::optional take_watchdog() + std::optional takeWatchdog() { return std::move(watchdog_); } diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp index 61d7b8e11..dffc192d2 100644 --- a/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp @@ -160,9 +160,9 @@ TEST_F(FlatbufferConfigLoaderTest, LoadMinimalConfig) auto result = loadBuffer(buildMinimalConfig(1, "Startup")); ASSERT_THAT(result.has_value(), IsTrue()); - EXPECT_THAT(result->initial_run_target(), Eq("Startup")); + EXPECT_THAT(result->initialRunTarget(), Eq("Startup")); EXPECT_THAT(result->components().empty(), IsTrue()); - EXPECT_THAT(result->run_targets().empty(), IsTrue()); + EXPECT_THAT(result->runTargets().empty(), IsTrue()); EXPECT_THAT(result->watchdog().has_value(), IsFalse()); } @@ -240,9 +240,9 @@ TEST_F(FlatbufferConfigLoaderTest, LoadRunTargets) auto result = loadBuffer(buildConfigWithRunTargets(fbb, rts)); ASSERT_THAT(result.has_value(), IsTrue()); - ASSERT_THAT(result->run_targets().size(), Eq(1U)); + ASSERT_THAT(result->runTargets().size(), Eq(1U)); - const auto& target = result->run_targets()[0]; + const auto& target = result->runTargets()[0]; EXPECT_THAT(target.name, Eq("Startup")); EXPECT_THAT(target.description, Eq("Initial state")); ASSERT_THAT(target.depends_on.size(), Eq(1U)); @@ -270,7 +270,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadFallbackRunTarget) auto result = loadBuffer(finishBuffer(fbb, config)); ASSERT_THAT(result.has_value(), IsTrue()); - const auto& fb = result->fallback_run_target(); + const auto& fb = result->fallbackRunTarget(); EXPECT_THAT(fb.description, Eq("Fallback state")); ASSERT_THAT(fb.depends_on.size(), Eq(1U)); EXPECT_THAT(fb.depends_on[0], Eq("critical_comp")); @@ -292,7 +292,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadAliveSupervision) auto result = loadBuffer(finishBuffer(fbb, config)); ASSERT_THAT(result.has_value(), IsTrue()); - EXPECT_THAT(result->alive_supervision().evaluation_cycle_ms, Eq(250U)); + EXPECT_THAT(result->aliveSupervision().evaluation_cycle_ms, Eq(250U)); } TEST_F(FlatbufferConfigLoaderTest, LoadWatchdog) @@ -369,7 +369,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadSwitchRunTargetAction) auto result = loadBuffer(buildConfigWithRunTargets(fbb, rts)); ASSERT_THAT(result.has_value(), IsTrue()); - EXPECT_THAT(result->run_targets()[0].recovery_action.run_target, Eq("Fallback")); + EXPECT_THAT(result->runTargets()[0].recovery_action.run_target, Eq("Fallback")); } TEST_F(FlatbufferConfigLoaderTest, LoadSandbox) From d523966489854093388a8abdb29dd453f1fd6523 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Fu=C3=9Fberger?= Date: Thu, 21 May 2026 08:23:18 +0200 Subject: [PATCH 12/26] Move accessor method impl to cpp file --- .../config/include/config.hpp | 60 ++++--------------- .../config/src/config.cpp | 60 +++++++++++++++++++ 2 files changed, 72 insertions(+), 48 deletions(-) diff --git a/src/launch_manager_daemon/config/include/config.hpp b/src/launch_manager_daemon/config/include/config.hpp index a917d489b..320933d2d 100644 --- a/src/launch_manager_daemon/config/include/config.hpp +++ b/src/launch_manager_daemon/config/include/config.hpp @@ -178,56 +178,20 @@ class Config }; // Read access - const std::vector& components() const - { - return components_; - } - const std::vector& runTargets() const - { - return run_targets_; - } - std::string_view initialRunTarget() const - { - return initial_run_target_; - } - const FallbackRunTargetConfig& fallbackRunTarget() const - { - return fallback_run_target_; - } - const AliveSupervisionConfig& aliveSupervision() const - { - return alive_supervision_; - } - const std::optional& watchdog() const - { - return watchdog_; - } + const std::vector& components() const; + const std::vector& runTargets() const; + std::string_view initialRunTarget() const; + const FallbackRunTargetConfig& fallbackRunTarget() const; + const AliveSupervisionConfig& aliveSupervision() const; + const std::optional& watchdog() const; // Ownership transfer — source is left in a moved-from state after the call - std::vector takeComponents() - { - return std::move(components_); - } - std::vector takeRunTargets() - { - return std::move(run_targets_); - } - std::string takeInitialRunTarget() - { - return std::move(initial_run_target_); - } - FallbackRunTargetConfig takeFallbackRunTarget() - { - return std::move(fallback_run_target_); - } - AliveSupervisionConfig takeAliveSupervision() - { - return std::move(alive_supervision_); - } - std::optional takeWatchdog() - { - return std::move(watchdog_); - } + std::vector takeComponents(); + std::vector takeRunTargets(); + std::string takeInitialRunTarget(); + FallbackRunTargetConfig takeFallbackRunTarget(); + AliveSupervisionConfig takeAliveSupervision(); + std::optional takeWatchdog(); private: friend class Builder; diff --git a/src/launch_manager_daemon/config/src/config.cpp b/src/launch_manager_daemon/config/src/config.cpp index baa7284c0..c81684a77 100644 --- a/src/launch_manager_daemon/config/src/config.cpp +++ b/src/launch_manager_daemon/config/src/config.cpp @@ -78,4 +78,64 @@ Config Config::Builder::build() std::move(watchdog_)); } +const std::vector& Config::components() const +{ + return components_; +} + +const std::vector& Config::runTargets() const +{ + return run_targets_; +} + +std::string_view Config::initialRunTarget() const +{ + return initial_run_target_; +} + +const FallbackRunTargetConfig& Config::fallbackRunTarget() const +{ + return fallback_run_target_; +} + +const AliveSupervisionConfig& Config::aliveSupervision() const +{ + return alive_supervision_; +} + +const std::optional& Config::watchdog() const +{ + return watchdog_; +} + +std::vector Config::takeComponents() +{ + return std::move(components_); +} + +std::vector Config::takeRunTargets() +{ + return std::move(run_targets_); +} + +std::string Config::takeInitialRunTarget() +{ + return std::move(initial_run_target_); +} + +FallbackRunTargetConfig Config::takeFallbackRunTarget() +{ + return std::move(fallback_run_target_); +} + +AliveSupervisionConfig Config::takeAliveSupervision() +{ + return std::move(alive_supervision_); +} + +std::optional Config::takeWatchdog() +{ + return std::move(watchdog_); +} + } // namespace score::launch_manager::config From 24d6e5fafa2582d869a510205b2c9cd2c913bfab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Fu=C3=9Fberger?= Date: Thu, 21 May 2026 08:26:31 +0200 Subject: [PATCH 13/26] Add #endif comments --- src/launch_manager_daemon/config/include/config.hpp | 2 +- src/launch_manager_daemon/config/include/config_loader.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/launch_manager_daemon/config/include/config.hpp b/src/launch_manager_daemon/config/include/config.hpp index 320933d2d..740c928e3 100644 --- a/src/launch_manager_daemon/config/include/config.hpp +++ b/src/launch_manager_daemon/config/include/config.hpp @@ -213,4 +213,4 @@ class Config } // namespace score::launch_manager::config -#endif +#endif // CONFIG_HPP diff --git a/src/launch_manager_daemon/config/include/config_loader.hpp b/src/launch_manager_daemon/config/include/config_loader.hpp index 2eae7a38d..6eafd58c5 100644 --- a/src/launch_manager_daemon/config/include/config_loader.hpp +++ b/src/launch_manager_daemon/config/include/config_loader.hpp @@ -50,4 +50,4 @@ class IConfigLoader } // namespace score::launch_manager::config -#endif +#endif // CONFIG_LOADER_HPP From f70d64bc5b687fc07146a27787dcc7bddb49ea72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Fu=C3=9Fberger?= Date: Thu, 21 May 2026 11:24:44 +0200 Subject: [PATCH 14/26] ConfigBuilder is no longer a nested class --- .../config/include/config.hpp | 46 ++++++++++--------- .../config/src/config.cpp | 14 +++--- .../config/src/flatbuffer_config_loader.cpp | 2 +- 3 files changed, 32 insertions(+), 30 deletions(-) diff --git a/src/launch_manager_daemon/config/include/config.hpp b/src/launch_manager_daemon/config/include/config.hpp index 740c928e3..03ecda6d5 100644 --- a/src/launch_manager_daemon/config/include/config.hpp +++ b/src/launch_manager_daemon/config/include/config.hpp @@ -139,6 +139,8 @@ struct WatchdogConfig bool require_magic_close{}; }; +class ConfigBuilder; + /// @brief Move-only value object holding the parsed launch-manager configuration. /// /// Loaded once by an IConfigLoader, then individual parts are moved out via @@ -156,27 +158,6 @@ class Config Config(Config&&) = default; Config& operator=(Config&&) = default; - class Builder - { - public: - Builder& setComponents(std::vector components); - Builder& setRunTargets(std::vector run_targets); - Builder& setInitialRunTarget(std::string initial_run_target); - Builder& setFallbackRunTarget(FallbackRunTargetConfig fallback); - Builder& setAliveSupervision(AliveSupervisionConfig alive_supervision); - Builder& setWatchdog(WatchdogConfig watchdog); - - Config build(); - - private: - std::string initial_run_target_; - std::vector components_; - std::vector run_targets_; - FallbackRunTargetConfig fallback_run_target_; - AliveSupervisionConfig alive_supervision_; - std::optional watchdog_; - }; - // Read access const std::vector& components() const; const std::vector& runTargets() const; @@ -194,7 +175,7 @@ class Config std::optional takeWatchdog(); private: - friend class Builder; + friend class ConfigBuilder; Config(std::vector components, std::vector run_targets, @@ -211,6 +192,27 @@ class Config std::optional watchdog_; }; +class ConfigBuilder +{ + public: + ConfigBuilder& setComponents(std::vector components); + ConfigBuilder& setRunTargets(std::vector run_targets); + ConfigBuilder& setInitialRunTarget(std::string initial_run_target); + ConfigBuilder& setFallbackRunTarget(FallbackRunTargetConfig fallback); + ConfigBuilder& setAliveSupervision(AliveSupervisionConfig alive_supervision); + ConfigBuilder& setWatchdog(WatchdogConfig watchdog); + + Config build(); + + private: + std::string initial_run_target_; + std::vector components_; + std::vector run_targets_; + FallbackRunTargetConfig fallback_run_target_; + AliveSupervisionConfig alive_supervision_; + std::optional watchdog_; +}; + } // namespace score::launch_manager::config #endif // CONFIG_HPP diff --git a/src/launch_manager_daemon/config/src/config.cpp b/src/launch_manager_daemon/config/src/config.cpp index c81684a77..efcea8cc8 100644 --- a/src/launch_manager_daemon/config/src/config.cpp +++ b/src/launch_manager_daemon/config/src/config.cpp @@ -32,43 +32,43 @@ Config::Config(std::vector components, { } -Config::Builder& Config::Builder::setComponents(std::vector components) +ConfigBuilder& ConfigBuilder::setComponents(std::vector components) { components_ = std::move(components); return *this; } -Config::Builder& Config::Builder::setRunTargets(std::vector run_targets) +ConfigBuilder& ConfigBuilder::setRunTargets(std::vector run_targets) { run_targets_ = std::move(run_targets); return *this; } -Config::Builder& Config::Builder::setInitialRunTarget(std::string initial_run_target) +ConfigBuilder& ConfigBuilder::setInitialRunTarget(std::string initial_run_target) { initial_run_target_ = std::move(initial_run_target); return *this; } -Config::Builder& Config::Builder::setFallbackRunTarget(FallbackRunTargetConfig fallback) +ConfigBuilder& ConfigBuilder::setFallbackRunTarget(FallbackRunTargetConfig fallback) { fallback_run_target_ = std::move(fallback); return *this; } -Config::Builder& Config::Builder::setAliveSupervision(AliveSupervisionConfig alive_supervision) +ConfigBuilder& ConfigBuilder::setAliveSupervision(AliveSupervisionConfig alive_supervision) { alive_supervision_ = std::move(alive_supervision); return *this; } -Config::Builder& Config::Builder::setWatchdog(WatchdogConfig watchdog) +ConfigBuilder& ConfigBuilder::setWatchdog(WatchdogConfig watchdog) { watchdog_ = std::move(watchdog); return *this; } -Config Config::Builder::build() +Config ConfigBuilder::build() { return Config(std::move(components_), std::move(run_targets_), diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp index bd2332b01..e3226e09c 100644 --- a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp @@ -346,7 +346,7 @@ score::cpp::expected parseFlatbuffer(const std::ve return score::cpp::make_unexpected(IConfigLoader::Error::UnsupportedVersion); } - Config::Builder builder; + ConfigBuilder builder; // initial_run_target is a required field, guaranteed non-null by the schema and verifier. builder.setInitialRunTarget(config->initial_run_target()->str()); From 99cdb9c55dfb8bcc73ad2a82a48533c134263976 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Fu=C3=9Fberger?= Date: Thu, 21 May 2026 11:34:06 +0200 Subject: [PATCH 15/26] Add assertions for required fields --- .../config/src/flatbuffer_config_loader.cpp | 37 +++++++++++++------ 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp index e3226e09c..5f354e3c0 100644 --- a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp @@ -15,6 +15,7 @@ #include "score/os/errno.h" +#include #include #include #include @@ -111,9 +112,11 @@ std::unordered_map convertEnvironmentalVariables( result.reserve(vec->size()); for (const auto* ev : *vec) { - if (ev != nullptr && ev->key() != nullptr) + if (ev != nullptr) { - result.emplace(ev->key()->str(), safeString(ev->value())); + assert(ev->key() && "EnvironmentalVariable::key must never be nullptr as it is required in the schema"); + assert(ev->value() && "EnvironmentalVariable::value must never be nullptr as it is required in the schema"); + result.emplace(ev->key()->str(), ev->value()->str()); } } } @@ -137,11 +140,13 @@ std::optional convertSwitchRunTargetAction(const fb::Swit { return std::nullopt; } - return SwitchRunTargetAction{safeString(sa->run_target())}; + assert(sa->run_target() && "SwitchRunTargetAction::run_target must never be nullptr as it is required in the schema"); + return SwitchRunTargetAction{sa->run_target()->str()}; } SwitchRunTargetAction convertRequiredSwitchRunTargetAction(const fb::SwitchRunTargetAction* sa) { + assert(sa && "SwitchRunTargetAction must never be nullptr as it is required in the schema"); return convertSwitchRunTargetAction(sa).value(); } @@ -194,7 +199,10 @@ ComponentProperties convertComponentProperties(const fb::ComponentProperties* fb ComponentProperties result{}; if (fb_cp != nullptr) { - result.binary_name = safeString(fb_cp->binary_name()); + assert(fb_cp->binary_name() && "ComponentProperties::binary_name must never be nullptr as it is required in the schema"); + assert(fb_cp->application_profile() && "ComponentProperties::application_profile must never be nullptr as it is required in the schema"); + assert(fb_cp->ready_condition() && "ComponentProperties::ready_condition must never be nullptr as it is required in the schema"); + result.binary_name = fb_cp->binary_name()->str(); result.application_profile = convertApplicationProfile(fb_cp->application_profile()); result.depends_on = convertStringVector(fb_cp->depends_on()); result.process_arguments = convertStringVector(fb_cp->process_arguments()); @@ -230,10 +238,11 @@ DeploymentConfig convertDeploymentConfig(const fb::DeploymentConfig* fb_dc) DeploymentConfig result{}; if (fb_dc != nullptr) { + assert(fb_dc->bin_dir() && "DeploymentConfig::bin_dir must never be nullptr as it is required in the schema"); result.ready_timeout_ms = secondsToMs(fb_dc->ready_timeout()); result.shutdown_timeout_ms = secondsToMs(fb_dc->shutdown_timeout()); result.environmental_variables = convertEnvironmentalVariables(fb_dc->environmental_variables()); - result.bin_dir = safeString(fb_dc->bin_dir()); + result.bin_dir = fb_dc->bin_dir()->str(); result.working_dir = safeString(fb_dc->working_dir()); result.ready_recovery_action = convertRestartAction(fb_dc->ready_recovery_action()); result.recovery_action = convertSwitchRunTargetAction(fb_dc->recovery_action()); @@ -247,7 +256,10 @@ ComponentConfig convertComponent(const fb::Component* fb_comp) ComponentConfig result{}; if (fb_comp != nullptr) { - result.name = safeString(fb_comp->name()); + assert(fb_comp->name() && "Component::name must never be nullptr as it is required in the schema"); + assert(fb_comp->component_properties() && "Component::component_properties must never be nullptr as it is required in the schema"); + assert(fb_comp->deployment_config() && "Component::deployment_config must never be nullptr as it is required in the schema"); + result.name = fb_comp->name()->str(); result.description = safeString(fb_comp->description()); result.component_properties = convertComponentProperties(fb_comp->component_properties()); result.deployment_config = convertDeploymentConfig(fb_comp->deployment_config()); @@ -260,7 +272,9 @@ RunTargetConfig convertRunTarget(const fb::RunTarget* fb_rt) RunTargetConfig result{}; if (fb_rt != nullptr) { - result.name = safeString(fb_rt->name()); + assert(fb_rt->name() && "RunTarget::name must never be nullptr as it is required in the schema"); + assert(fb_rt->recovery_action() && "RunTarget::recovery_action must never be nullptr as it is required in the schema"); + result.name = fb_rt->name()->str(); result.description = safeString(fb_rt->description()); result.depends_on = convertStringVector(fb_rt->depends_on()); result.transition_timeout_ms = secondsToMs(fb_rt->transition_timeout()); @@ -296,8 +310,9 @@ std::optional convertWatchdog(const fb::Watchdog* fb_wd) { return std::nullopt; } + assert(fb_wd->device_file_path() && "Watchdog::device_file_path must never be nullptr as it is required in the schema"); WatchdogConfig result{}; - result.device_file_path = safeString(fb_wd->device_file_path()); + result.device_file_path = fb_wd->device_file_path()->str(); result.max_timeout_ms = secondsToMs(fb_wd->max_timeout()); result.deactivate_on_shutdown = fb_wd->deactivate_on_shutdown().has_value() ? *fb_wd->deactivate_on_shutdown() : false; @@ -348,7 +363,7 @@ score::cpp::expected parseFlatbuffer(const std::ve ConfigBuilder builder; - // initial_run_target is a required field, guaranteed non-null by the schema and verifier. + assert(config->initial_run_target() && "LaunchManagerConfig::initial_run_target must never be nullptr as it is required in the schema"); builder.setInitialRunTarget(config->initial_run_target()->str()); if (config->components() != nullptr) @@ -379,10 +394,10 @@ score::cpp::expected parseFlatbuffer(const std::ve builder.setRunTargets(std::move(run_targets)); } - // fallback_run_target is a required field, guaranteed non-null by the schema and verifier. + assert(config->fallback_run_target() && "LaunchManagerConfig::fallback_run_target must never be nullptr as it is required in the schema"); builder.setFallbackRunTarget(convertFallbackRunTarget(config->fallback_run_target())); - // alive_supervision is a required field, guaranteed non-null by the schema and verifier. + assert(config->alive_supervision() && "LaunchManagerConfig::alive_supervision must never be nullptr as it is required in the schema"); builder.setAliveSupervision(convertAliveSupervision(config->alive_supervision())); auto wd = convertWatchdog(config->watchdog()); From a1f2860bb959b7f23a7d8a955c410277c72d757a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Fu=C3=9Fberger?= Date: Thu, 21 May 2026 11:37:37 +0200 Subject: [PATCH 16/26] Add assertion for sub-ms precision --- .../config/src/flatbuffer_config_loader.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp index 5f354e3c0..798a94820 100644 --- a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp @@ -34,7 +34,9 @@ constexpr double kSecondsToMilliseconds = 1000.0; uint32_t secondsToMs(double seconds) { - return static_cast(seconds * kSecondsToMilliseconds); + const auto result = static_cast(seconds * kSecondsToMilliseconds); + assert(!(seconds > 0.0 && result == 0U) && "Sub-millisecond precision is not supported: value rounds to 0ms"); + return result; } // --- Enum conversion helpers --- From efe69a05ba19a0f83685c91fb466b1fca022b57e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Fu=C3=9Fberger?= Date: Fri, 22 May 2026 07:30:05 +0200 Subject: [PATCH 17/26] Use uid_t and gid_t types --- src/launch_manager_daemon/config/BUILD | 1 + .../config/include/config.hpp | 7 +- .../config/src/flatbuffer_config_loader.cpp | 68 ++++++++--- .../src/flatbuffer_config_loader_UT.cpp | 107 +++++++++++++++++- 4 files changed, 166 insertions(+), 17 deletions(-) diff --git a/src/launch_manager_daemon/config/BUILD b/src/launch_manager_daemon/config/BUILD index 39d3a2f2f..b5395de8c 100644 --- a/src/launch_manager_daemon/config/BUILD +++ b/src/launch_manager_daemon/config/BUILD @@ -65,6 +65,7 @@ cc_library( visibility = ["//src:__subpackages__"], deps = [ ":config_loader", + "//src/launch_manager_daemon/common:log", "@flatbuffers", "@score_baselibs//score/flatbuffers:flatbufferutils", ], diff --git a/src/launch_manager_daemon/config/include/config.hpp b/src/launch_manager_daemon/config/include/config.hpp index 03ecda6d5..24631dde0 100644 --- a/src/launch_manager_daemon/config/include/config.hpp +++ b/src/launch_manager_daemon/config/include/config.hpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -79,9 +80,9 @@ struct SwitchRunTargetAction struct Sandbox { - uint32_t uid{}; - uint32_t gid{}; - std::vector supplementary_group_ids; + uid_t uid{}; + gid_t gid{}; + std::vector supplementary_group_ids; std::optional security_policy; std::string scheduling_policy; int32_t scheduling_priority{}; diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp index 798a94820..93a297e28 100644 --- a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp @@ -15,9 +15,13 @@ #include "score/os/errno.h" +#include + #include #include +#include #include +#include #include #include @@ -91,15 +95,21 @@ std::vector convertStringVector( return result; } -std::vector convertUint32Vector(const ::flatbuffers::Vector* vec) +score::cpp::expected, IConfigLoader::Error> convertGidVector( + const ::flatbuffers::Vector* vec) { - std::vector result; + std::vector result; if (vec != nullptr) { result.reserve(vec->size()); for (const auto val : *vec) { - result.emplace_back(val); + if (val < std::numeric_limits::min() || val > std::numeric_limits::max()) + { + LM_LOG_ERROR() << "Sandbox supplementary group id " << val << " is out of valid gid_t range [" << std::numeric_limits::min() << "," << std::numeric_limits::max() << "]"; + return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); + } + result.emplace_back(static_cast(val)); } } return result; @@ -213,16 +223,33 @@ ComponentProperties convertComponentProperties(const fb::ComponentProperties* fb return result; } -std::optional convertSandbox(const fb::Sandbox* fb_sb) +score::cpp::expected, IConfigLoader::Error> convertSandbox(const fb::Sandbox* fb_sb) { if (fb_sb == nullptr) { return std::nullopt; } + const auto fb_uid = fb_sb->uid(); + const auto fb_gid = fb_sb->gid(); + if (fb_uid < std::numeric_limits::min() || fb_uid > std::numeric_limits::max()) + { + LM_LOG_ERROR() << "Sandbox uid " << fb_uid << " is out of valid uid_t range [" << std::numeric_limits::min() << "," << std::numeric_limits::max() << "]"; + return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); + } + if (fb_gid < std::numeric_limits::min() || fb_gid > std::numeric_limits::max()) + { + LM_LOG_ERROR() << "Sandbox gid " << fb_gid << " is out of valid gid_t range [" << std::numeric_limits::min() << "," << std::numeric_limits::max() << "]"; + return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); + } Sandbox result{}; - result.uid = fb_sb->uid(); - result.gid = fb_sb->gid(); - result.supplementary_group_ids = convertUint32Vector(fb_sb->supplementary_group_ids()); + result.uid = static_cast(fb_uid); + result.gid = static_cast(fb_gid); + auto supplementary_gids = convertGidVector(fb_sb->supplementary_group_ids()); + if (!supplementary_gids.has_value()) + { + return score::cpp::make_unexpected(supplementary_gids.error()); + } + result.supplementary_group_ids = std::move(*supplementary_gids); result.security_policy = fb_sb->security_policy() != nullptr ? std::optional{fb_sb->security_policy()->str()} : std::nullopt; @@ -232,10 +259,10 @@ std::optional convertSandbox(const fb::Sandbox* fb_sb) fb_sb->max_memory_usage().has_value() ? std::optional{*fb_sb->max_memory_usage()} : std::nullopt; result.max_cpu_usage = fb_sb->max_cpu_usage().has_value() ? std::optional{*fb_sb->max_cpu_usage()} : std::nullopt; - return result; + return std::optional{std::move(result)}; } -DeploymentConfig convertDeploymentConfig(const fb::DeploymentConfig* fb_dc) +score::cpp::expected convertDeploymentConfig(const fb::DeploymentConfig* fb_dc) { DeploymentConfig result{}; if (fb_dc != nullptr) @@ -248,12 +275,17 @@ DeploymentConfig convertDeploymentConfig(const fb::DeploymentConfig* fb_dc) result.working_dir = safeString(fb_dc->working_dir()); result.ready_recovery_action = convertRestartAction(fb_dc->ready_recovery_action()); result.recovery_action = convertSwitchRunTargetAction(fb_dc->recovery_action()); - result.sandbox = convertSandbox(fb_dc->sandbox()); + auto sandbox = convertSandbox(fb_dc->sandbox()); + if (!sandbox.has_value()) + { + return score::cpp::make_unexpected(sandbox.error()); + } + result.sandbox = std::move(*sandbox); } return result; } -ComponentConfig convertComponent(const fb::Component* fb_comp) +score::cpp::expected convertComponent(const fb::Component* fb_comp) { ComponentConfig result{}; if (fb_comp != nullptr) @@ -264,7 +296,12 @@ ComponentConfig convertComponent(const fb::Component* fb_comp) result.name = fb_comp->name()->str(); result.description = safeString(fb_comp->description()); result.component_properties = convertComponentProperties(fb_comp->component_properties()); - result.deployment_config = convertDeploymentConfig(fb_comp->deployment_config()); + auto deployment_config = convertDeploymentConfig(fb_comp->deployment_config()); + if (!deployment_config.has_value()) + { + return score::cpp::make_unexpected(deployment_config.error()); + } + result.deployment_config = std::move(*deployment_config); } return result; } @@ -376,7 +413,12 @@ score::cpp::expected parseFlatbuffer(const std::ve { if (comp != nullptr) { - components.emplace_back(convertComponent(comp)); + auto component = convertComponent(comp); + if (!component.has_value()) + { + return score::cpp::make_unexpected(component.error()); + } + components.emplace_back(std::move(*component)); } } builder.setComponents(std::move(components)); diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp index dffc192d2..ca16b66ee 100644 --- a/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp @@ -21,6 +21,8 @@ #include #include +#include +#include #include namespace score::launch_manager::config @@ -415,7 +417,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadSandbox) const auto& sb = result->components()[0].deployment_config.sandbox.value(); EXPECT_THAT(sb.uid, Eq(1000U)); EXPECT_THAT(sb.gid, Eq(1000U)); - EXPECT_THAT(sb.supplementary_group_ids, Eq(std::vector{100, 200})); + EXPECT_THAT(sb.supplementary_group_ids, Eq(std::vector{100, 200})); ASSERT_THAT(sb.security_policy.has_value(), IsTrue()); EXPECT_THAT(sb.security_policy.value(), Eq("strict")); EXPECT_THAT(sb.scheduling_policy, Eq("SCHED_FIFO")); @@ -666,5 +668,108 @@ TEST_F(FlatbufferConfigLoaderTest, WrongSchemaVersionReturnsUnsupportedVersion) EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::UnsupportedVersion)); } +TEST_F(FlatbufferConfigLoaderTest, SandboxUidOutOfRangeReturnsInvalidFormat) +{ + RecordProperty("Description", "A sandbox uid exceeding uid_t range returns InvalidFormat."); + + if constexpr (std::numeric_limits::max() >= std::numeric_limits::max()) + { + // On Linux, uid_t and gid_t are typically 32-bit unsigned integers, so any uint32_t value is valid. In that case, this test is not applicable. + // On QNX, uid_t and gid_t can be int32_t, so values above INT32_MAX would be invalid. + GTEST_SKIP() << "uid_t range covers all uint32_t values on this platform"; + } + + ::flatbuffers::FlatBufferBuilder fbb; + + auto sandbox = fb::CreateSandbox(fbb, std::numeric_limits::max() /*uid*/, 1000 /*gid*/); + auto bin_dir = fbb.CreateString("/opt"); + auto deploy = fb::CreateDeploymentConfig(fbb, + 0.0 /*ready_timeout*/, + 0.0 /*shutdown_timeout*/, + 0 /*environmental_variables*/, + bin_dir, + 0 /*working_dir*/, + 0 /*ready_recovery_action*/, + 0 /*recovery_action*/, + sandbox); + + auto comp = buildDefaultComponent(fbb, "bad_uid_comp", buildDefaultComponentProperties(fbb), deploy); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); + + auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); + + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); +} + +TEST_F(FlatbufferConfigLoaderTest, SandboxGidOutOfRangeReturnsInvalidFormat) +{ + RecordProperty("Description", "A sandbox gid exceeding gid_t range returns InvalidFormat."); + + if constexpr (std::numeric_limits::max() >= std::numeric_limits::max()) + { + // On Linux, uid_t and gid_t are typically 32-bit unsigned integers, so any uint32_t value is valid. In that case, this test is not applicable. + // On QNX, uid_t and gid_t can be int32_t, so values above INT32_MAX would be invalid. + GTEST_SKIP() << "gid_t range covers all uint32_t values on this platform"; + } + + ::flatbuffers::FlatBufferBuilder fbb; + + auto sandbox = fb::CreateSandbox(fbb, 1000 /*uid*/, std::numeric_limits::max() /*gid*/); + auto bin_dir = fbb.CreateString("/opt"); + auto deploy = fb::CreateDeploymentConfig(fbb, + 0.0 /*ready_timeout*/, + 0.0 /*shutdown_timeout*/, + 0 /*environmental_variables*/, + bin_dir, + 0 /*working_dir*/, + 0 /*ready_recovery_action*/, + 0 /*recovery_action*/, + sandbox); + + auto comp = buildDefaultComponent(fbb, "bad_gid_comp", buildDefaultComponentProperties(fbb), deploy); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); + + auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); + + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); +} + +TEST_F(FlatbufferConfigLoaderTest, SandboxSupplementaryGidOutOfRangeReturnsInvalidFormat) +{ + RecordProperty("Description", "A supplementary group id exceeding gid_t range returns InvalidFormat."); + + if constexpr (std::numeric_limits::max() >= std::numeric_limits::max()) + { + // On Linux, uid_t and gid_t are typically 32-bit unsigned integers, so any uint32_t value is valid. In that case, this test is not applicable. + // On QNX, uid_t and gid_t can be int32_t, so values above INT32_MAX would be invalid. + GTEST_SKIP() << "gid_t range covers all uint32_t values on this platform"; + } + + ::flatbuffers::FlatBufferBuilder fbb; + + auto supp_gids = fbb.CreateVector(std::vector{100, std::numeric_limits::max()}); + auto sandbox = fb::CreateSandbox(fbb, 1000 /*uid*/, 1000 /*gid*/, supp_gids); + auto bin_dir = fbb.CreateString("/opt"); + auto deploy = fb::CreateDeploymentConfig(fbb, + 0.0 /*ready_timeout*/, + 0.0 /*shutdown_timeout*/, + 0 /*environmental_variables*/, + bin_dir, + 0 /*working_dir*/, + 0 /*ready_recovery_action*/, + 0 /*recovery_action*/, + sandbox); + + auto comp = buildDefaultComponent(fbb, "bad_supp_gid_comp", buildDefaultComponentProperties(fbb), deploy); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); + + auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); + + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); +} + } // namespace } // namespace score::launch_manager::config From 5c25b13c5673ee5d3e1a232f70ca6792b6061172 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Fu=C3=9Fberger?= Date: Fri, 22 May 2026 08:20:22 +0200 Subject: [PATCH 18/26] Implement Environment var classes --- src/launch_manager_daemon/config/BUILD | 10 + .../config/include/config.hpp | 46 +++- .../config/src/config.cpp | 90 ++++++ .../config/src/config_UT.cpp | 260 ++++++++++++++++++ .../config/src/flatbuffer_config_loader.cpp | 7 +- .../src/flatbuffer_config_loader_UT.cpp | 18 +- 6 files changed, 421 insertions(+), 10 deletions(-) create mode 100644 src/launch_manager_daemon/config/src/config_UT.cpp diff --git a/src/launch_manager_daemon/config/BUILD b/src/launch_manager_daemon/config/BUILD index b5395de8c..b1b177628 100644 --- a/src/launch_manager_daemon/config/BUILD +++ b/src/launch_manager_daemon/config/BUILD @@ -71,6 +71,16 @@ cc_library( ], ) +cc_test( + name = "config_UT", + srcs = ["src/config_UT.cpp"], + visibility = ["//tests:__subpackages__"], + deps = [ + ":config", + "@googletest//:gtest_main", + ], +) + cc_test( name = "flatbuffer_config_loader_UT", srcs = ["src/flatbuffer_config_loader_UT.cpp"], diff --git a/src/launch_manager_daemon/config/include/config.hpp b/src/launch_manager_daemon/config/include/config.hpp index 24631dde0..53ce3d187 100644 --- a/src/launch_manager_daemon/config/include/config.hpp +++ b/src/launch_manager_daemon/config/include/config.hpp @@ -18,7 +18,6 @@ #include #include #include -#include #include namespace score::launch_manager::config @@ -67,6 +66,49 @@ struct ComponentProperties ReadyCondition ready_condition; }; +class EnvironmentVariable +{ + public: + EnvironmentVariable(std::string_view key, std::string_view value); + + std::string_view key() const; + std::string_view value() const; + const char* c_str() const; + + private: + std::string entry_; + std::size_t key_length_; +}; + +class Environment +{ + public: + using const_iterator = std::vector::const_iterator; + + Environment() = default; + + Environment(const Environment&) = delete; + Environment& operator=(const Environment&) = delete; + Environment(Environment&& other) noexcept; + Environment& operator=(Environment&& other) noexcept; + + ~Environment() = default; + + void reserve(std::size_t count); + void add(std::string_view key, std::string_view value); + + const_iterator begin() const; + const_iterator end() const; + std::size_t size() const; + + char* const* envp() const; + + private: + void rebuildPointers() const; + std::vector entries_; + mutable std::vector pointers_; +}; + struct RestartAction { uint32_t number_of_attempts{}; @@ -94,7 +136,7 @@ struct DeploymentConfig { uint32_t ready_timeout_ms{}; uint32_t shutdown_timeout_ms{}; - std::unordered_map environmental_variables; + Environment environmental_variables; std::string bin_dir; std::string working_dir; std::optional ready_recovery_action; diff --git a/src/launch_manager_daemon/config/src/config.cpp b/src/launch_manager_daemon/config/src/config.cpp index efcea8cc8..90139ea28 100644 --- a/src/launch_manager_daemon/config/src/config.cpp +++ b/src/launch_manager_daemon/config/src/config.cpp @@ -11,12 +11,102 @@ * SPDX-License-Identifier: Apache-2.0 ********************************************************************************/ #include "config.hpp" +#include #include namespace score::launch_manager::config { +// --- EnvironmentVariable --- + +EnvironmentVariable::EnvironmentVariable(std::string_view key, std::string_view value) + : entry_{std::string{key} + "=" + std::string{value}}, key_length_{key.size()} +{ + assert(!key.empty() && "Environment variable key must not be empty"); +} + +std::string_view EnvironmentVariable::key() const +{ + return {entry_.data(), key_length_}; +} + +std::string_view EnvironmentVariable::value() const +{ + return {entry_.data() + key_length_ + 1, entry_.size() - key_length_ - 1}; +} + +const char* EnvironmentVariable::c_str() const +{ + return entry_.c_str(); +} + +// --- Environment --- + +Environment::Environment(Environment&& other) noexcept + : entries_{std::move(other.entries_)} +{ + rebuildPointers(); +} + +Environment& Environment::operator=(Environment&& other) noexcept +{ + if (this != &other) + { + entries_ = std::move(other.entries_); + rebuildPointers(); + } + return *this; +} + +void Environment::reserve(std::size_t count) +{ + entries_.reserve(count); + // +1 for nullptr terminator + pointers_.reserve(count + 1); +} + +void Environment::add(std::string_view key, std::string_view value) +{ + entries_.emplace_back(key, value); +} + +Environment::const_iterator Environment::begin() const +{ + return entries_.begin(); +} + +Environment::const_iterator Environment::end() const +{ + return entries_.end(); +} + +std::size_t Environment::size() const +{ + return entries_.size(); +} + +char* const* Environment::envp() const +{ + rebuildPointers(); + // const_cast is required to convert to the type expected by execve + return const_cast(pointers_.data()); +} + +void Environment::rebuildPointers() const +{ + pointers_.clear(); + // +1 for nullptr terminator + pointers_.reserve(entries_.size() + 1); + for (const auto& e : entries_) + { + pointers_.push_back(e.c_str()); + } + pointers_.push_back(nullptr); +} + +// --- Config --- + Config::Config(std::vector components, std::vector run_targets, std::string initial_run_target, diff --git a/src/launch_manager_daemon/config/src/config_UT.cpp b/src/launch_manager_daemon/config/src/config_UT.cpp new file mode 100644 index 000000000..1f56de344 --- /dev/null +++ b/src/launch_manager_daemon/config/src/config_UT.cpp @@ -0,0 +1,260 @@ +/******************************************************************************** + * Copyright (c) 2026 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0 + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ +#include "config.hpp" + +#include +#include + +#include +#include +#include + +namespace score::launch_manager::config +{ +namespace +{ + +using ::testing::Eq; +using ::testing::IsNull; +using ::testing::NotNull; +using ::testing::StrEq; + +class EnvironmentVariableTest : public ::testing::Test +{ + protected: + void SetUp() override + { + RecordProperty("TestType", "interface-test"); + RecordProperty("DerivationTechnique", "explorative-testing"); + } +}; + +TEST_F(EnvironmentVariableTest, KeyAndValueAreAccessible) +{ + RecordProperty("Description", "Key and value are correctly split from the internal key=value storage."); + + EnvironmentVariable ev{"PATH", "/usr/bin"}; + + EXPECT_THAT(ev.key(), Eq("PATH")); + EXPECT_THAT(ev.value(), Eq("/usr/bin")); +} + +TEST_F(EnvironmentVariableTest, CStrReturnsKeyEqualsValue) +{ + RecordProperty("Description", "c_str() returns the full key=value string."); + + EnvironmentVariable ev{"HOME", "/root"}; + + EXPECT_THAT(ev.c_str(), StrEq("HOME=/root")); +} + +TEST_F(EnvironmentVariableTest, EmptyValue) +{ + RecordProperty("Description", "Empty value is handled correctly."); + + EnvironmentVariable ev{"KEY", ""}; + + EXPECT_THAT(ev.key(), Eq("KEY")); + EXPECT_THAT(ev.value(), Eq("")); + EXPECT_THAT(ev.c_str(), StrEq("KEY=")); +} + +TEST_F(EnvironmentVariableTest, ValueContainingEquals) +{ + RecordProperty("Description", "A value containing '=' is preserved correctly."); + + EnvironmentVariable ev{"OPTS", "a=1,b=2"}; + + EXPECT_THAT(ev.key(), Eq("OPTS")); + EXPECT_THAT(ev.value(), Eq("a=1,b=2")); + EXPECT_THAT(ev.c_str(), StrEq("OPTS=a=1,b=2")); +} + +class EnvironmentTest : public ::testing::Test +{ + protected: + void SetUp() override + { + RecordProperty("TestType", "interface-test"); + RecordProperty("DerivationTechnique", "explorative-testing"); + } +}; + +TEST_F(EnvironmentTest, DefaultConstructedIsEmpty) +{ + RecordProperty("Description", "A default-constructed Environment has size 0 and begin == end."); + + Environment env; + + EXPECT_THAT(env.size(), Eq(0U)); + EXPECT_THAT(env.begin(), Eq(env.end())); +} + +TEST_F(EnvironmentTest, AddIncreasesSize) +{ + RecordProperty("Description", "Adding entries increases size and they are iterable."); + + Environment env; + env.add("A", "1"); + env.add("B", "2"); + + EXPECT_THAT(env.size(), Eq(2U)); + auto it = env.begin(); + EXPECT_THAT(it->key(), Eq("A")); + EXPECT_THAT(it->value(), Eq("1")); + ++it; + EXPECT_THAT(it->key(), Eq("B")); + EXPECT_THAT(it->value(), Eq("2")); + ++it; + EXPECT_THAT(it, Eq(env.end())); +} + +TEST_F(EnvironmentTest, EnvpReturnsNullTerminatedArray) +{ + RecordProperty("Description", "envp() returns a null-terminated array suitable for execve."); + + Environment env; + env.add("KEY", "val"); + + char* const* envp = env.envp(); + + ASSERT_THAT(envp, NotNull()); + EXPECT_THAT(envp[0], StrEq("KEY=val")); + EXPECT_THAT(envp[1], IsNull()); +} + +TEST_F(EnvironmentTest, EnvpWithMultipleEntries) +{ + RecordProperty("Description", "envp() contains all entries in order followed by nullptr."); + + Environment env; + env.add("A", "1"); + env.add("B", "2"); + env.add("C", "3"); + + char* const* envp = env.envp(); + + EXPECT_THAT(envp[0], StrEq("A=1")); + EXPECT_THAT(envp[1], StrEq("B=2")); + EXPECT_THAT(envp[2], StrEq("C=3")); + EXPECT_THAT(envp[3], IsNull()); +} + +TEST_F(EnvironmentTest, ReserveAndAddAvoidReallocation) +{ + RecordProperty("Description", "reserve() followed by add() produces correct entries and envp."); + + Environment env; + env.reserve(3); + env.add("X", "10"); + env.add("Y", "20"); + env.add("Z", "30"); + + EXPECT_THAT(env.size(), Eq(3U)); + + char* const* envp = env.envp(); + EXPECT_THAT(envp[0], StrEq("X=10")); + EXPECT_THAT(envp[1], StrEq("Y=20")); + EXPECT_THAT(envp[2], StrEq("Z=30")); + EXPECT_THAT(envp[3], IsNull()); +} + +TEST_F(EnvironmentTest, MoveConstructorPreservesEntries) +{ + RecordProperty("Description", "Move-constructed Environment has the original entries and valid envp."); + + Environment original; + original.add("FOO", "bar"); + original.add("BAZ", "qux"); + + Environment moved{std::move(original)}; + + EXPECT_THAT(moved.size(), Eq(2U)); + auto it = moved.begin(); + EXPECT_THAT(it->key(), Eq("FOO")); + EXPECT_THAT(it->value(), Eq("bar")); + ++it; + EXPECT_THAT(it->key(), Eq("BAZ")); + EXPECT_THAT(it->value(), Eq("qux")); + + char* const* envp = moved.envp(); + EXPECT_THAT(envp[0], StrEq("FOO=bar")); + EXPECT_THAT(envp[1], StrEq("BAZ=qux")); + EXPECT_THAT(envp[2], IsNull()); +} + +TEST_F(EnvironmentTest, MoveAssignmentPreservesEntries) +{ + RecordProperty("Description", "Move-assigned Environment has the original entries and valid envp."); + + Environment original; + original.add("K", "V"); + + Environment target; + target = std::move(original); + + EXPECT_THAT(target.size(), Eq(1U)); + EXPECT_THAT(target.begin()->key(), Eq("K")); + + char* const* envp = target.envp(); + EXPECT_THAT(envp[0], StrEq("K=V")); + EXPECT_THAT(envp[1], IsNull()); +} + +TEST_F(EnvironmentTest, SsoLengthStringSurvivesReallocation) +{ + RecordProperty("Description", "Short strings within SSO threshold have valid envp after reallocation."); + + Environment env; + for (int i = 0; i < 100; ++i) + { + env.add("K", std::to_string(i)); + } + + char* const* envp = env.envp(); + EXPECT_THAT(envp[0], StrEq("K=0")); + EXPECT_THAT(envp[99], StrEq("K=99")); + EXPECT_THAT(envp[100], IsNull()); +} + +TEST_F(EnvironmentTest, EmptyEnvironmentEnvpIsNullTerminated) +{ + RecordProperty("Description", "envp() on an empty Environment returns a null-terminated array."); + + Environment env; + + char* const* envp = env.envp(); + + ASSERT_THAT(envp, NotNull()); + EXPECT_THAT(envp[0], IsNull()); +} + +TEST_F(EnvironmentTest, RangeBasedForLoopWorks) +{ + RecordProperty("Description", "Environment supports range-based for loop."); + + Environment env; + env.add("A", "1"); + env.add("B", "2"); + + std::size_t count = 0; + for (const auto& ev : env) + { + EXPECT_THAT(ev.c_str(), NotNull()); + ++count; + } + EXPECT_THAT(count, Eq(2U)); +} + +} // namespace +} // namespace score::launch_manager::config diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp index 93a297e28..9976a1447 100644 --- a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp @@ -22,7 +22,6 @@ #include #include #include -#include #include namespace score::launch_manager::config @@ -115,10 +114,10 @@ score::cpp::expected, IConfigLoader::Error> convertGidVector( return result; } -std::unordered_map convertEnvironmentalVariables( +Environment convertEnvironmentalVariables( const ::flatbuffers::Vector<::flatbuffers::Offset>* vec) { - std::unordered_map result; + Environment result; if (vec != nullptr) { result.reserve(vec->size()); @@ -128,7 +127,7 @@ std::unordered_map convertEnvironmentalVariables( { assert(ev->key() && "EnvironmentalVariable::key must never be nullptr as it is required in the schema"); assert(ev->value() && "EnvironmentalVariable::value must never be nullptr as it is required in the schema"); - result.emplace(ev->key()->str(), ev->value()->str()); + result.add(ev->key()->str(), ev->value()->str()); } } } diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp index ca16b66ee..75e9b4889 100644 --- a/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp @@ -34,7 +34,9 @@ namespace fb = score::launch_manager::config::fb; using ::testing::Eq; using ::testing::IsFalse; +using ::testing::IsNull; using ::testing::IsTrue; +using ::testing::StrEq; const score::filesystem::Path kTestPath{"/tmp/test_config.bin"}; @@ -459,7 +461,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadComponentAliveSupervision) TEST_F(FlatbufferConfigLoaderTest, LoadEnvironmentalVariables) { - RecordProperty("Description", "Environmental variables vector is mapped to unordered_map."); + RecordProperty("Description", "Environmental variables are stored as key=value strings."); ::flatbuffers::FlatBufferBuilder fbb; @@ -483,9 +485,17 @@ TEST_F(FlatbufferConfigLoaderTest, LoadEnvironmentalVariables) ASSERT_THAT(result.has_value(), IsTrue()); const auto& env = result->components()[0].deployment_config.environmental_variables; - EXPECT_THAT(env.size(), Eq(2U)); - EXPECT_THAT(env.at("PATH"), Eq("/usr/bin")); - EXPECT_THAT(env.at("HOME"), Eq("/root")); + ASSERT_THAT(env.size(), Eq(2U)); + auto it = env.begin(); + EXPECT_THAT(it->key(), Eq("PATH")); + EXPECT_THAT(it->value(), Eq("/usr/bin")); + ++it; + EXPECT_THAT(it->key(), Eq("HOME")); + EXPECT_THAT(it->value(), Eq("/root")); + ASSERT_THAT(env.size(), Eq(2U)); + EXPECT_THAT(env.envp()[0], StrEq("PATH=/usr/bin")); + EXPECT_THAT(env.envp()[1], StrEq("HOME=/root")); + EXPECT_THAT(env.envp()[2], IsNull()); } TEST_F(FlatbufferConfigLoaderTest, LoadMultipleComponents) From dbfa690c6a1c6388877b1dae9f90f9d9c7365216 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Fu=C3=9Fberger?= Date: Fri, 22 May 2026 12:08:21 +0200 Subject: [PATCH 19/26] Scheduling policy as int --- .../config/include/config.hpp | 2 +- .../config/src/flatbuffer_config_loader.cpp | 24 +++- .../src/flatbuffer_config_loader_UT.cpp | 103 +++++++++++++++++- .../config/src/new_lm_flatcfg.fbs | 11 +- 4 files changed, 133 insertions(+), 7 deletions(-) diff --git a/src/launch_manager_daemon/config/include/config.hpp b/src/launch_manager_daemon/config/include/config.hpp index 53ce3d187..69d13d29f 100644 --- a/src/launch_manager_daemon/config/include/config.hpp +++ b/src/launch_manager_daemon/config/include/config.hpp @@ -126,7 +126,7 @@ struct Sandbox gid_t gid{}; std::vector supplementary_group_ids; std::optional security_policy; - std::string scheduling_policy; + int32_t scheduling_policy; int32_t scheduling_priority{}; std::optional max_memory_usage; std::optional max_cpu_usage; diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp index 9976a1447..390ab9b91 100644 --- a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -72,6 +73,22 @@ ProcessState convertProcessState(fb::ProcessState fb_state) } } +score::cpp::expected convertSchedulingPolicy(fb::SchedulingPolicy policy) +{ + switch (policy) + { + case fb::SchedulingPolicy::OTHER: + return SCHED_OTHER; + case fb::SchedulingPolicy::FIFO: + return SCHED_FIFO; + case fb::SchedulingPolicy::RR: + return SCHED_RR; + default: + LM_LOG_ERROR() << "Unsupported scheduling policy: " << static_cast(policy); + return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); + } +} + // --- String/vector helpers --- std::string safeString(const ::flatbuffers::String* s) @@ -252,7 +269,12 @@ score::cpp::expected, IConfigLoader::Error> convertSandbo result.security_policy = fb_sb->security_policy() != nullptr ? std::optional{fb_sb->security_policy()->str()} : std::nullopt; - result.scheduling_policy = safeString(fb_sb->scheduling_policy()); + auto scheduling_policy = convertSchedulingPolicy(fb_sb->scheduling_policy()); + if (!scheduling_policy.has_value()) + { + return score::cpp::make_unexpected(scheduling_policy.error()); + } + result.scheduling_policy = *scheduling_policy; result.scheduling_priority = fb_sb->scheduling_priority().value_or(0); result.max_memory_usage = fb_sb->max_memory_usage().has_value() ? std::optional{*fb_sb->max_memory_usage()} : std::nullopt; diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp index 75e9b4889..dfa34ca7c 100644 --- a/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -383,14 +384,13 @@ TEST_F(FlatbufferConfigLoaderTest, LoadSandbox) ::flatbuffers::FlatBufferBuilder fbb; auto sec_policy = fbb.CreateString("strict"); - auto sched_policy = fbb.CreateString("SCHED_FIFO"); auto supp_gids = fbb.CreateVector(std::vector{100, 200}); auto sandbox = fb::CreateSandbox(fbb, 1000 /*uid*/, 1000 /*gid*/, supp_gids, sec_policy, - sched_policy, + fb::SchedulingPolicy::FIFO, 50 /*scheduling_priority*/, 4096 /*max_memory_usage*/, 80 /*max_cpu_usage*/); @@ -422,7 +422,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadSandbox) EXPECT_THAT(sb.supplementary_group_ids, Eq(std::vector{100, 200})); ASSERT_THAT(sb.security_policy.has_value(), IsTrue()); EXPECT_THAT(sb.security_policy.value(), Eq("strict")); - EXPECT_THAT(sb.scheduling_policy, Eq("SCHED_FIFO")); + EXPECT_THAT(sb.scheduling_policy, Eq(SCHED_FIFO)); EXPECT_THAT(sb.scheduling_priority, Eq(50)); ASSERT_THAT(sb.max_memory_usage.has_value(), IsTrue()); EXPECT_THAT(sb.max_memory_usage.value(), Eq(4096U)); @@ -781,5 +781,102 @@ TEST_F(FlatbufferConfigLoaderTest, SandboxSupplementaryGidOutOfRangeReturnsInval EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); } +// ============================================================================ +// Parameterized scheduling policy tests +// ============================================================================ + +struct SchedulingPolicyTestParam +{ + fb::SchedulingPolicy fb_policy; + int32_t expected_posix_value; + const char* name; +}; + +class SchedulingPolicyTest : public FlatbufferConfigLoaderTest, + public ::testing::WithParamInterface +{ +}; + +TEST_P(SchedulingPolicyTest, ConvertsToExpectedPosixValue) +{ + RecordProperty("Description", "Scheduling policy enum maps to correct POSIX value."); + + ::flatbuffers::FlatBufferBuilder fbb; + + auto sandbox = fb::CreateSandbox(fbb, + 1000 /*uid*/, + 1000 /*gid*/, + 0 /*supplementary_group_ids*/, + 0 /*security_policy*/, + GetParam().fb_policy); + auto bin_dir = fbb.CreateString("/opt"); + auto deploy = fb::CreateDeploymentConfig(fbb, + 0.0 /*ready_timeout*/, + 0.0 /*shutdown_timeout*/, + 0 /*environmental_variables*/, + bin_dir, + 0 /*working_dir*/, + 0 /*ready_recovery_action*/, + 0 /*recovery_action*/, + sandbox); + + auto comp = buildDefaultComponent(fbb, "sched_comp", buildDefaultComponentProperties(fbb), deploy); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); + + auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); + + ASSERT_THAT(result.has_value(), IsTrue()); + ASSERT_THAT(result->components()[0].deployment_config.sandbox.has_value(), IsTrue()); + EXPECT_THAT(result->components()[0].deployment_config.sandbox->scheduling_policy, + Eq(GetParam().expected_posix_value)); +} + +INSTANTIATE_TEST_SUITE_P(SchedulingPolicies, + SchedulingPolicyTest, + ::testing::Values(SchedulingPolicyTestParam{fb::SchedulingPolicy::FIFO, + SCHED_FIFO, + "SCHED_FIFO"}, + SchedulingPolicyTestParam{fb::SchedulingPolicy::RR, + SCHED_RR, + "SCHED_RR"}, + SchedulingPolicyTestParam{fb::SchedulingPolicy::OTHER, + SCHED_OTHER, + "SCHED_OTHER"}), + [](const ::testing::TestParamInfo& info) { + return info.param.name; + }); + +TEST_F(FlatbufferConfigLoaderTest, UnsupportedSchedulingPolicyReturnsInvalidFormat) +{ + RecordProperty("Description", "An unsupported scheduling policy value returns InvalidFormat."); + + ::flatbuffers::FlatBufferBuilder fbb; + + auto sandbox = fb::CreateSandbox(fbb, + 1000 /*uid*/, + 1000 /*gid*/, + 0 /*supplementary_group_ids*/, + 0 /*security_policy*/, + static_cast(99)); + auto bin_dir = fbb.CreateString("/opt"); + auto deploy = fb::CreateDeploymentConfig(fbb, + 0.0 /*ready_timeout*/, + 0.0 /*shutdown_timeout*/, + 0 /*environmental_variables*/, + bin_dir, + 0 /*working_dir*/, + 0 /*ready_recovery_action*/, + 0 /*recovery_action*/, + sandbox); + + auto comp = buildDefaultComponent(fbb, "bad_sched_comp", buildDefaultComponentProperties(fbb), deploy); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); + + auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); + + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); +} + } // namespace } // namespace score::launch_manager::config diff --git a/src/launch_manager_daemon/config/src/new_lm_flatcfg.fbs b/src/launch_manager_daemon/config/src/new_lm_flatcfg.fbs index b488ece3a..a52ab45a7 100644 --- a/src/launch_manager_daemon/config/src/new_lm_flatcfg.fbs +++ b/src/launch_manager_daemon/config/src/new_lm_flatcfg.fbs @@ -17,6 +17,13 @@ enum ProcessState : byte { Terminated = 1 } +// Scheduling policy for a component's initial thread. +enum SchedulingPolicy : byte { + OTHER = 0, + FIFO = 1, + RR = 2 +} + // Defines the configuration parameters used for alive monitoring of a component. table ComponentAliveSupervision { // Duration in seconds of the time interval used to verify alive notifications. @@ -84,8 +91,8 @@ table Sandbox { supplementary_group_ids:[uint32]; // Security policy or confinement profile name (e.g., SELinux or AppArmor profile). security_policy:string; - // Scheduling policy for the component's initial thread (e.g., SCHED_FIFO, SCHED_RR, SCHED_OTHER). - scheduling_policy:string; + // Scheduling policy for the component's initial thread. + scheduling_policy:SchedulingPolicy; // Scheduling priority for the component's initial thread. scheduling_priority:int32 = null; // Maximum memory in bytes the component is permitted to use. From a6e2b08fd2b7f5ccb5d2f16b3495f9c837277f3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Fu=C3=9Fberger?= Date: Fri, 22 May 2026 14:13:26 +0200 Subject: [PATCH 20/26] Refactor handling of mandatory and optional values --- .../config/include/config.hpp | 8 +- .../config/src/flatbuffer_config_loader.cpp | 269 ++++++-- .../src/flatbuffer_config_loader_UT.cpp | 626 +++++++++++++++--- .../config/src/new_lm_flatcfg.fbs | 115 ++-- 4 files changed, 793 insertions(+), 225 deletions(-) diff --git a/src/launch_manager_daemon/config/include/config.hpp b/src/launch_manager_daemon/config/include/config.hpp index 69d13d29f..c15ec6aec 100644 --- a/src/launch_manager_daemon/config/include/config.hpp +++ b/src/launch_manager_daemon/config/include/config.hpp @@ -41,8 +41,8 @@ struct ComponentAliveSupervision { uint32_t reporting_cycle_ms{}; uint32_t failed_cycles_tolerance{}; - uint32_t min_indications{}; - uint32_t max_indications{}; + std::optional min_indications; + std::optional max_indications; }; struct ApplicationProfile @@ -63,7 +63,7 @@ struct ComponentProperties ApplicationProfile application_profile; std::vector depends_on; std::vector process_arguments; - ReadyCondition ready_condition; + std::optional ready_condition; }; class EnvironmentVariable @@ -142,7 +142,7 @@ struct DeploymentConfig std::optional ready_recovery_action; // Currently only SwitchRunTargetAction is supported here, RestartAction to be added in the future std::optional recovery_action; - std::optional sandbox; + Sandbox sandbox; }; struct ComponentConfig diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp index 390ab9b91..8d18b1392 100644 --- a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp @@ -153,13 +153,25 @@ Environment convertEnvironmentalVariables( // --- Recovery action conversion --- -std::optional convertRestartAction(const fb::RestartAction* ra) +score::cpp::expected, IConfigLoader::Error> convertRestartAction( + const fb::RestartAction* ra) { if (ra == nullptr) { - return std::nullopt; + return std::optional{std::nullopt}; + } + if (!ra->number_of_attempts().has_value()) + { + LM_LOG_ERROR() << "RestartAction::number_of_attempts is required but missing"; + return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); + } + if (!ra->delay_before_restart().has_value()) + { + LM_LOG_ERROR() << "RestartAction::delay_before_restart is required but missing"; + return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); } - return RestartAction{ra->number_of_attempts(), secondsToMs(ra->delay_before_restart())}; + return std::optional{ + RestartAction{*ra->number_of_attempts(), secondsToMs(*ra->delay_before_restart())}}; } std::optional convertSwitchRunTargetAction(const fb::SwitchRunTargetAction* sa) @@ -180,73 +192,125 @@ SwitchRunTargetAction convertRequiredSwitchRunTargetAction(const fb::SwitchRunTa // --- Struct conversion helpers --- -ComponentAliveSupervision convertComponentAliveSupervision(const fb::ComponentAliveSupervision* fb_cas) +score::cpp::expected convertComponentAliveSupervision( + const fb::ComponentAliveSupervision* fb_cas) { ComponentAliveSupervision result{}; if (fb_cas != nullptr) { - result.reporting_cycle_ms = secondsToMs(fb_cas->reporting_cycle()); - result.failed_cycles_tolerance = fb_cas->failed_cycles_tolerance(); - result.min_indications = fb_cas->min_indications().value_or(0U); - result.max_indications = fb_cas->max_indications().value_or(0U); + if (!fb_cas->reporting_cycle().has_value()) + { + LM_LOG_ERROR() << "ComponentAliveSupervision::reporting_cycle is required but missing"; + return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); + } + if (!fb_cas->failed_cycles_tolerance().has_value()) + { + LM_LOG_ERROR() << "ComponentAliveSupervision::failed_cycles_tolerance is required but missing"; + return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); + } + result.reporting_cycle_ms = secondsToMs(*fb_cas->reporting_cycle()); + result.failed_cycles_tolerance = *fb_cas->failed_cycles_tolerance(); + result.min_indications = fb_cas->min_indications().has_value() + ? std::optional{*fb_cas->min_indications()} + : std::nullopt; + result.max_indications = fb_cas->max_indications().has_value() + ? std::optional{*fb_cas->max_indications()} + : std::nullopt; } return result; } -ApplicationProfile convertApplicationProfile(const fb::ApplicationProfile* fb_ap) +score::cpp::expected convertApplicationProfile( + const fb::ApplicationProfile* fb_ap) { ApplicationProfile result{}; if (fb_ap != nullptr) { - result.application_type = convertApplicationType(fb_ap->application_type()); - result.is_self_terminating = fb_ap->is_self_terminating(); + if (!fb_ap->application_type().has_value()) + { + LM_LOG_ERROR() << "ApplicationProfile::application_type is required but missing"; + return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); + } + if (!fb_ap->is_self_terminating().has_value()) + { + LM_LOG_ERROR() << "ApplicationProfile::is_self_terminating is required but missing"; + return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); + } + result.application_type = convertApplicationType(*fb_ap->application_type()); + result.is_self_terminating = *fb_ap->is_self_terminating(); if (fb_ap->alive_supervision() != nullptr) { - result.alive_supervision = convertComponentAliveSupervision(fb_ap->alive_supervision()); + auto alive_sup = convertComponentAliveSupervision(fb_ap->alive_supervision()); + if (!alive_sup.has_value()) + { + return score::cpp::make_unexpected(alive_sup.error()); + } + result.alive_supervision = std::move(*alive_sup); } } return result; } -ReadyCondition convertReadyCondition(const fb::ReadyCondition* fb_rc) +score::cpp::expected convertReadyCondition(const fb::ReadyCondition* fb_rc) { - ReadyCondition result{ProcessState::Running}; + ReadyCondition result{}; if (fb_rc != nullptr) { - const auto opt = fb_rc->process_state(); - if (opt.has_value()) + if (!fb_rc->process_state().has_value()) { - result.process_state = convertProcessState(*opt); + LM_LOG_ERROR() << "ReadyCondition::process_state is required but missing"; + return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); } + result.process_state = convertProcessState(*fb_rc->process_state()); } return result; } -ComponentProperties convertComponentProperties(const fb::ComponentProperties* fb_cp) +score::cpp::expected convertComponentProperties( + const fb::ComponentProperties* fb_cp) { ComponentProperties result{}; if (fb_cp != nullptr) { assert(fb_cp->binary_name() && "ComponentProperties::binary_name must never be nullptr as it is required in the schema"); assert(fb_cp->application_profile() && "ComponentProperties::application_profile must never be nullptr as it is required in the schema"); - assert(fb_cp->ready_condition() && "ComponentProperties::ready_condition must never be nullptr as it is required in the schema"); result.binary_name = fb_cp->binary_name()->str(); - result.application_profile = convertApplicationProfile(fb_cp->application_profile()); + auto app_profile = convertApplicationProfile(fb_cp->application_profile()); + if (!app_profile.has_value()) + { + return score::cpp::make_unexpected(app_profile.error()); + } + result.application_profile = std::move(*app_profile); result.depends_on = convertStringVector(fb_cp->depends_on()); result.process_arguments = convertStringVector(fb_cp->process_arguments()); - result.ready_condition = convertReadyCondition(fb_cp->ready_condition()); + if (fb_cp->ready_condition() != nullptr) + { + auto ready_cond = convertReadyCondition(fb_cp->ready_condition()); + if (!ready_cond.has_value()) + { + return score::cpp::make_unexpected(ready_cond.error()); + } + result.ready_condition = std::move(*ready_cond); + } } return result; } -score::cpp::expected, IConfigLoader::Error> convertSandbox(const fb::Sandbox* fb_sb) +score::cpp::expected convertSandbox(const fb::Sandbox* fb_sb) { - if (fb_sb == nullptr) + assert(fb_sb && "Sandbox must never be nullptr as it is required in the schema"); + if (!fb_sb->uid().has_value()) { - return std::nullopt; + LM_LOG_ERROR() << "Sandbox::uid is required but missing"; + return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); } - const auto fb_uid = fb_sb->uid(); - const auto fb_gid = fb_sb->gid(); + if (!fb_sb->gid().has_value()) + { + LM_LOG_ERROR() << "Sandbox::gid is required but missing"; + return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); + } + const auto fb_uid = *fb_sb->uid(); + const auto fb_gid = *fb_sb->gid(); if (fb_uid < std::numeric_limits::min() || fb_uid > std::numeric_limits::max()) { LM_LOG_ERROR() << "Sandbox uid " << fb_uid << " is out of valid uid_t range [" << std::numeric_limits::min() << "," << std::numeric_limits::max() << "]"; @@ -257,6 +321,21 @@ score::cpp::expected, IConfigLoader::Error> convertSandbo LM_LOG_ERROR() << "Sandbox gid " << fb_gid << " is out of valid gid_t range [" << std::numeric_limits::min() << "," << std::numeric_limits::max() << "]"; return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); } + if (!fb_sb->scheduling_policy().has_value()) + { + LM_LOG_ERROR() << "Sandbox::scheduling_policy is required but missing"; + return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); + } + auto scheduling_policy = convertSchedulingPolicy(*fb_sb->scheduling_policy()); + if (!scheduling_policy.has_value()) + { + return score::cpp::make_unexpected(scheduling_policy.error()); + } + if (!fb_sb->scheduling_priority().has_value()) + { + LM_LOG_ERROR() << "Sandbox::scheduling_priority is required but missing"; + return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); + } Sandbox result{}; result.uid = static_cast(fb_uid); result.gid = static_cast(fb_gid); @@ -269,18 +348,13 @@ score::cpp::expected, IConfigLoader::Error> convertSandbo result.security_policy = fb_sb->security_policy() != nullptr ? std::optional{fb_sb->security_policy()->str()} : std::nullopt; - auto scheduling_policy = convertSchedulingPolicy(fb_sb->scheduling_policy()); - if (!scheduling_policy.has_value()) - { - return score::cpp::make_unexpected(scheduling_policy.error()); - } result.scheduling_policy = *scheduling_policy; - result.scheduling_priority = fb_sb->scheduling_priority().value_or(0); + result.scheduling_priority = *fb_sb->scheduling_priority(); result.max_memory_usage = fb_sb->max_memory_usage().has_value() ? std::optional{*fb_sb->max_memory_usage()} : std::nullopt; result.max_cpu_usage = fb_sb->max_cpu_usage().has_value() ? std::optional{*fb_sb->max_cpu_usage()} : std::nullopt; - return std::optional{std::move(result)}; + return result; } score::cpp::expected convertDeploymentConfig(const fb::DeploymentConfig* fb_dc) @@ -289,12 +363,29 @@ score::cpp::expected convertDeploymentCo if (fb_dc != nullptr) { assert(fb_dc->bin_dir() && "DeploymentConfig::bin_dir must never be nullptr as it is required in the schema"); - result.ready_timeout_ms = secondsToMs(fb_dc->ready_timeout()); - result.shutdown_timeout_ms = secondsToMs(fb_dc->shutdown_timeout()); + assert(fb_dc->working_dir() && "DeploymentConfig::working_dir must never be nullptr as it is required in the schema"); + assert(fb_dc->sandbox() && "DeploymentConfig::sandbox must never be nullptr as it is required in the schema"); + if (!fb_dc->ready_timeout().has_value()) + { + LM_LOG_ERROR() << "DeploymentConfig::ready_timeout is required but missing"; + return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); + } + if (!fb_dc->shutdown_timeout().has_value()) + { + LM_LOG_ERROR() << "DeploymentConfig::shutdown_timeout is required but missing"; + return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); + } + result.ready_timeout_ms = secondsToMs(*fb_dc->ready_timeout()); + result.shutdown_timeout_ms = secondsToMs(*fb_dc->shutdown_timeout()); result.environmental_variables = convertEnvironmentalVariables(fb_dc->environmental_variables()); result.bin_dir = fb_dc->bin_dir()->str(); - result.working_dir = safeString(fb_dc->working_dir()); - result.ready_recovery_action = convertRestartAction(fb_dc->ready_recovery_action()); + result.working_dir = fb_dc->working_dir()->str(); + auto ready_recovery = convertRestartAction(fb_dc->ready_recovery_action()); + if (!ready_recovery.has_value()) + { + return score::cpp::make_unexpected(ready_recovery.error()); + } + result.ready_recovery_action = std::move(*ready_recovery); result.recovery_action = convertSwitchRunTargetAction(fb_dc->recovery_action()); auto sandbox = convertSandbox(fb_dc->sandbox()); if (!sandbox.has_value()) @@ -316,7 +407,12 @@ score::cpp::expected convertComponent(con assert(fb_comp->deployment_config() && "Component::deployment_config must never be nullptr as it is required in the schema"); result.name = fb_comp->name()->str(); result.description = safeString(fb_comp->description()); - result.component_properties = convertComponentProperties(fb_comp->component_properties()); + auto component_properties = convertComponentProperties(fb_comp->component_properties()); + if (!component_properties.has_value()) + { + return score::cpp::make_unexpected(component_properties.error()); + } + result.component_properties = std::move(*component_properties); auto deployment_config = convertDeploymentConfig(fb_comp->deployment_config()); if (!deployment_config.has_value()) { @@ -327,57 +423,88 @@ score::cpp::expected convertComponent(con return result; } -RunTargetConfig convertRunTarget(const fb::RunTarget* fb_rt) +score::cpp::expected convertRunTarget(const fb::RunTarget* fb_rt) { RunTargetConfig result{}; if (fb_rt != nullptr) { assert(fb_rt->name() && "RunTarget::name must never be nullptr as it is required in the schema"); assert(fb_rt->recovery_action() && "RunTarget::recovery_action must never be nullptr as it is required in the schema"); + if (!fb_rt->transition_timeout().has_value()) + { + LM_LOG_ERROR() << "RunTarget::transition_timeout is required but missing"; + return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); + } result.name = fb_rt->name()->str(); result.description = safeString(fb_rt->description()); result.depends_on = convertStringVector(fb_rt->depends_on()); - result.transition_timeout_ms = secondsToMs(fb_rt->transition_timeout()); + result.transition_timeout_ms = secondsToMs(*fb_rt->transition_timeout()); result.recovery_action = convertRequiredSwitchRunTargetAction(fb_rt->recovery_action()); } return result; } -FallbackRunTargetConfig convertFallbackRunTarget(const fb::FallbackRunTarget* fb_frt) +score::cpp::expected convertFallbackRunTarget( + const fb::FallbackRunTarget* fb_frt) { FallbackRunTargetConfig result{}; if (fb_frt != nullptr) { + if (!fb_frt->transition_timeout().has_value()) + { + LM_LOG_ERROR() << "FallbackRunTarget::transition_timeout is required but missing"; + return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); + } result.description = safeString(fb_frt->description()); result.depends_on = convertStringVector(fb_frt->depends_on()); - result.transition_timeout_ms = secondsToMs(fb_frt->transition_timeout()); + result.transition_timeout_ms = secondsToMs(*fb_frt->transition_timeout()); } return result; } -AliveSupervisionConfig convertAliveSupervision(const fb::AliveSupervision* fb_as) +score::cpp::expected convertAliveSupervision( + const fb::AliveSupervision* fb_as) { if (fb_as == nullptr) { return AliveSupervisionConfig{}; } - return AliveSupervisionConfig{secondsToMs(fb_as->evaluation_cycle())}; + if (!fb_as->evaluation_cycle().has_value()) + { + LM_LOG_ERROR() << "AliveSupervision::evaluation_cycle is required but missing"; + return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); + } + return AliveSupervisionConfig{secondsToMs(*fb_as->evaluation_cycle())}; } -std::optional convertWatchdog(const fb::Watchdog* fb_wd) +score::cpp::expected, IConfigLoader::Error> convertWatchdog(const fb::Watchdog* fb_wd) { if (fb_wd == nullptr) { - return std::nullopt; + return std::optional{std::nullopt}; } assert(fb_wd->device_file_path() && "Watchdog::device_file_path must never be nullptr as it is required in the schema"); + if (!fb_wd->max_timeout().has_value()) + { + LM_LOG_ERROR() << "Watchdog::max_timeout is required but missing"; + return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); + } + if (!fb_wd->deactivate_on_shutdown().has_value()) + { + LM_LOG_ERROR() << "Watchdog::deactivate_on_shutdown is required but missing"; + return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); + } + if (!fb_wd->require_magic_close().has_value()) + { + LM_LOG_ERROR() << "Watchdog::require_magic_close is required but missing"; + return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); + } WatchdogConfig result{}; result.device_file_path = fb_wd->device_file_path()->str(); - result.max_timeout_ms = secondsToMs(fb_wd->max_timeout()); - result.deactivate_on_shutdown = - fb_wd->deactivate_on_shutdown().has_value() ? *fb_wd->deactivate_on_shutdown() : false; - result.require_magic_close = fb_wd->require_magic_close().has_value() ? *fb_wd->require_magic_close() : false; - return result; + result.max_timeout_ms = secondsToMs(*fb_wd->max_timeout()); + result.deactivate_on_shutdown = *fb_wd->deactivate_on_shutdown(); + result.require_magic_close = *fb_wd->require_magic_close(); + return std::optional{std::move(result)}; } } // anonymous namespace @@ -416,7 +543,12 @@ score::cpp::expected parseFlatbuffer(const std::ve return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); } - if (config->schema_version() != kExpectedSchemaVersion) + if (!config->schema_version().has_value()) + { + LM_LOG_ERROR() << "LaunchManagerConfig::schema_version is required but missing"; + return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); + } + if (*config->schema_version() != kExpectedSchemaVersion) { return score::cpp::make_unexpected(IConfigLoader::Error::UnsupportedVersion); } @@ -424,9 +556,10 @@ score::cpp::expected parseFlatbuffer(const std::ve ConfigBuilder builder; assert(config->initial_run_target() && "LaunchManagerConfig::initial_run_target must never be nullptr as it is required in the schema"); + assert(config->components() && "LaunchManagerConfig::components must never be nullptr as it is required in the schema"); + assert(config->run_targets() && "LaunchManagerConfig::run_targets must never be nullptr as it is required in the schema"); builder.setInitialRunTarget(config->initial_run_target()->str()); - if (config->components() != nullptr) { std::vector components; components.reserve(config->components()->size()); @@ -445,7 +578,6 @@ score::cpp::expected parseFlatbuffer(const std::ve builder.setComponents(std::move(components)); } - if (config->run_targets() != nullptr) { std::vector run_targets; run_targets.reserve(config->run_targets()->size()); @@ -453,22 +585,41 @@ score::cpp::expected parseFlatbuffer(const std::ve { if (rt != nullptr) { - run_targets.emplace_back(convertRunTarget(rt)); + auto run_target = convertRunTarget(rt); + if (!run_target.has_value()) + { + return score::cpp::make_unexpected(run_target.error()); + } + run_targets.emplace_back(std::move(*run_target)); } } builder.setRunTargets(std::move(run_targets)); } assert(config->fallback_run_target() && "LaunchManagerConfig::fallback_run_target must never be nullptr as it is required in the schema"); - builder.setFallbackRunTarget(convertFallbackRunTarget(config->fallback_run_target())); + auto fallback = convertFallbackRunTarget(config->fallback_run_target()); + if (!fallback.has_value()) + { + return score::cpp::make_unexpected(fallback.error()); + } + builder.setFallbackRunTarget(std::move(*fallback)); assert(config->alive_supervision() && "LaunchManagerConfig::alive_supervision must never be nullptr as it is required in the schema"); - builder.setAliveSupervision(convertAliveSupervision(config->alive_supervision())); + auto alive_sup = convertAliveSupervision(config->alive_supervision()); + if (!alive_sup.has_value()) + { + return score::cpp::make_unexpected(alive_sup.error()); + } + builder.setAliveSupervision(std::move(*alive_sup)); auto wd = convertWatchdog(config->watchdog()); - if (wd.has_value()) + if (!wd.has_value()) + { + return score::cpp::make_unexpected(wd.error()); + } + if (wd->has_value()) { - builder.setWatchdog(std::move(*wd)); + builder.setWatchdog(std::move(**wd)); } return builder.build(); diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp index dfa34ca7c..c82617110 100644 --- a/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp @@ -53,11 +53,22 @@ std::vector finishBuffer(::flatbuffers::FlatBufferBuilder& fbb, // Helper functions to reduce test boilerplate // ============================================================================ +::flatbuffers::Offset buildDefaultSandbox(::flatbuffers::FlatBufferBuilder& fbb) +{ + return fb::CreateSandbox(fbb, + 0 /*uid*/, + 0 /*gid*/, + 0 /*supplementary_group_ids*/, + 0 /*security_policy*/, + fb::SchedulingPolicy::OTHER, + 0 /*scheduling_priority*/); +} + ::flatbuffers::Offset buildDefaultComponentProperties(::flatbuffers::FlatBufferBuilder& fbb) { auto bin_name = fbb.CreateString("default_bin"); - auto app_profile = fb::CreateApplicationProfile(fbb); - auto ready_cond = fb::CreateReadyCondition(fbb); + auto app_profile = fb::CreateApplicationProfile(fbb, fb::ApplicationType::Native, false); + auto ready_cond = fb::CreateReadyCondition(fbb, fb::ProcessState::Running); return fb::CreateComponentProperties( fbb, bin_name, app_profile, 0 /*depends_on*/, 0 /*process_arguments*/, ready_cond); } @@ -65,8 +76,11 @@ ::flatbuffers::Offset buildDefaultComponentProperties(: ::flatbuffers::Offset buildDefaultDeploymentConfig(::flatbuffers::FlatBufferBuilder& fbb) { auto bin_dir = fbb.CreateString("/opt"); + auto work_dir = fbb.CreateString("/tmp"); + auto sandbox = buildDefaultSandbox(fbb); return fb::CreateDeploymentConfig( - fbb, 0.0 /*ready_timeout*/, 0.0 /*shutdown_timeout*/, 0 /*environmental_variables*/, bin_dir); + fbb, 1.0 /*ready_timeout*/, 1.0 /*shutdown_timeout*/, 0 /*environmental_variables*/, + bin_dir, work_dir, 0 /*ready_recovery_action*/, 0 /*recovery_action*/, sandbox); } ::flatbuffers::Offset buildDefaultComponent( @@ -91,11 +105,11 @@ std::vector buildConfigWithComponents( ::flatbuffers::FlatBufferBuilder& fbb, ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> comps) { - auto fallback = fb::CreateFallbackRunTarget(fbb); - auto alive_sup = fb::CreateAliveSupervision(fbb); + auto fallback = fb::CreateFallbackRunTarget(fbb, 0 /*description*/, 0 /*depends_on*/, 1.0 /*transition_timeout*/); + auto alive_sup = fb::CreateAliveSupervision(fbb, 1.0 /*evaluation_cycle*/); + auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); auto irt = fbb.CreateString("Startup"); - auto config = - fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, comps, 0 /*run_targets*/, irt, fallback, alive_sup); + auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, comps, rts, irt, fallback, alive_sup); return finishBuffer(fbb, config); } @@ -103,11 +117,11 @@ std::vector buildConfigWithRunTargets( ::flatbuffers::FlatBufferBuilder& fbb, ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset>> rts) { - auto fallback = fb::CreateFallbackRunTarget(fbb); - auto alive_sup = fb::CreateAliveSupervision(fbb); + auto fallback = fb::CreateFallbackRunTarget(fbb, 0 /*description*/, 0 /*depends_on*/, 1.0 /*transition_timeout*/); + auto alive_sup = fb::CreateAliveSupervision(fbb, 1.0 /*evaluation_cycle*/); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); auto irt = fbb.CreateString("Startup"); - auto config = - fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, 0 /*components*/, rts, irt, fallback, alive_sup); + auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, comps, rts, irt, fallback, alive_sup); return finishBuffer(fbb, config); } @@ -138,10 +152,13 @@ class FlatbufferConfigLoaderTest : public ::testing::Test { ::flatbuffers::FlatBufferBuilder fbb; auto irt = fbb.CreateString(initial_run_target); - auto fallback = fb::CreateFallbackRunTarget(fbb); - auto alive_sup = fb::CreateAliveSupervision(fbb); - auto config = fb::CreateLaunchManagerConfig( - fbb, schema_version, 0 /*components*/, 0 /*run_targets*/, irt, fallback, alive_sup); + auto fallback = + fb::CreateFallbackRunTarget(fbb, 0 /*description*/, 0 /*depends_on*/, 1.0 /*transition_timeout*/); + auto alive_sup = fb::CreateAliveSupervision(fbb, 1.0 /*evaluation_cycle*/); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); + auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); + auto config = + fb::CreateLaunchManagerConfig(fbb, schema_version, comps, rts, irt, fallback, alive_sup); return finishBuffer(fbb, config); } @@ -191,8 +208,10 @@ TEST_F(FlatbufferConfigLoaderTest, LoadSingleComponent) auto bin_dir = fbb.CreateString("/opt/bin"); auto work_dir = fbb.CreateString("/tmp"); + auto sandbox = buildDefaultSandbox(fbb); auto deploy = fb::CreateDeploymentConfig( - fbb, 1.5 /*ready_timeout*/, 2.5 /*shutdown_timeout*/, 0 /*environmental_variables*/, bin_dir, work_dir); + fbb, 1.5 /*ready_timeout*/, 2.5 /*shutdown_timeout*/, 0 /*environmental_variables*/, + bin_dir, work_dir, 0 /*ready_recovery_action*/, 0 /*recovery_action*/, sandbox); auto comp_name = fbb.CreateString("TestComponent"); auto comp_desc = fbb.CreateString("A test component"); @@ -214,13 +233,16 @@ TEST_F(FlatbufferConfigLoaderTest, LoadSingleComponent) ASSERT_THAT(comp.component_properties.application_profile.alive_supervision.has_value(), IsTrue()); EXPECT_THAT(comp.component_properties.application_profile.alive_supervision->reporting_cycle_ms, Eq(500U)); EXPECT_THAT(comp.component_properties.application_profile.alive_supervision->failed_cycles_tolerance, Eq(2U)); - EXPECT_THAT(comp.component_properties.application_profile.alive_supervision->min_indications, Eq(1U)); - EXPECT_THAT(comp.component_properties.application_profile.alive_supervision->max_indications, Eq(3U)); + ASSERT_THAT(comp.component_properties.application_profile.alive_supervision->min_indications.has_value(), IsTrue()); + EXPECT_THAT(*comp.component_properties.application_profile.alive_supervision->min_indications, Eq(1U)); + ASSERT_THAT(comp.component_properties.application_profile.alive_supervision->max_indications.has_value(), IsTrue()); + EXPECT_THAT(*comp.component_properties.application_profile.alive_supervision->max_indications, Eq(3U)); ASSERT_THAT(comp.component_properties.depends_on.size(), Eq(1U)); EXPECT_THAT(comp.component_properties.depends_on[0], Eq("other_comp")); ASSERT_THAT(comp.component_properties.process_arguments.size(), Eq(1U)); EXPECT_THAT(comp.component_properties.process_arguments[0], Eq("--verbose")); - EXPECT_THAT(comp.component_properties.ready_condition.process_state, Eq(ProcessState::Running)); + ASSERT_THAT(comp.component_properties.ready_condition.has_value(), IsTrue()); + EXPECT_THAT(comp.component_properties.ready_condition->process_state, Eq(ProcessState::Running)); EXPECT_THAT(comp.deployment_config.ready_timeout_ms, Eq(1500U)); EXPECT_THAT(comp.deployment_config.shutdown_timeout_ms, Eq(2500U)); EXPECT_THAT(comp.deployment_config.bin_dir, Eq("/opt/bin")); @@ -267,10 +289,11 @@ TEST_F(FlatbufferConfigLoaderTest, LoadFallbackRunTarget) auto fb_deps = fbb.CreateVector(std::vector<::flatbuffers::Offset<::flatbuffers::String>>{fb_dep}); auto fallback = fb::CreateFallbackRunTarget(fbb, fb_desc, fb_deps, 10.0 /*transition_timeout*/); - auto alive_sup = fb::CreateAliveSupervision(fbb); + auto alive_sup = fb::CreateAliveSupervision(fbb, 1.0 /*evaluation_cycle*/); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); + auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig( - fbb, 1 /*schema_version*/, 0 /*components*/, 0 /*run_targets*/, irt, fallback, alive_sup); + auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, comps, rts, irt, fallback, alive_sup); auto result = loadBuffer(finishBuffer(fbb, config)); @@ -289,10 +312,11 @@ TEST_F(FlatbufferConfigLoaderTest, LoadAliveSupervision) ::flatbuffers::FlatBufferBuilder fbb; auto alive_sup = fb::CreateAliveSupervision(fbb, 0.25 /*evaluation_cycle*/); - auto fallback = fb::CreateFallbackRunTarget(fbb); + auto fallback = fb::CreateFallbackRunTarget(fbb, 0 /*description*/, 0 /*depends_on*/, 1.0 /*transition_timeout*/); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); + auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig( - fbb, 1 /*schema_version*/, 0 /*components*/, 0 /*run_targets*/, irt, fallback, alive_sup); + auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, comps, rts, irt, fallback, alive_sup); auto result = loadBuffer(finishBuffer(fbb, config)); @@ -310,11 +334,12 @@ TEST_F(FlatbufferConfigLoaderTest, LoadWatchdog) auto watchdog = fb::CreateWatchdog( fbb, dev_path, 30.0 /*max_timeout*/, true /*deactivate_on_shutdown*/, false /*require_magic_close*/); - auto fallback = fb::CreateFallbackRunTarget(fbb); - auto alive_sup = fb::CreateAliveSupervision(fbb); + auto fallback = fb::CreateFallbackRunTarget(fbb, 0 /*description*/, 0 /*depends_on*/, 1.0 /*transition_timeout*/); + auto alive_sup = fb::CreateAliveSupervision(fbb, 1.0 /*evaluation_cycle*/); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); + auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig( - fbb, 1 /*schema_version*/, 0 /*components*/, 0 /*run_targets*/, irt, fallback, alive_sup, watchdog); + auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, comps, rts, irt, fallback, alive_sup, watchdog); auto result = loadBuffer(finishBuffer(fbb, config)); @@ -336,13 +361,17 @@ TEST_F(FlatbufferConfigLoaderTest, LoadRestartRecoveryAction) auto restart = fb::CreateRestartAction(fbb, 3 /*number_of_attempts*/, 1.5 /*delay_before_restart*/); auto bin_dir = fbb.CreateString("/opt"); + auto work_dir = fbb.CreateString("/tmp"); + auto sandbox = buildDefaultSandbox(fbb); auto deploy = fb::CreateDeploymentConfig(fbb, - 0.0 /*ready_timeout*/, - 0.0 /*shutdown_timeout*/, + 1.0 /*ready_timeout*/, + 1.0 /*shutdown_timeout*/, 0 /*environmental_variables*/, bin_dir, - 0 /*working_dir*/, - restart); + work_dir, + restart, + 0 /*recovery_action*/, + sandbox); auto comp = buildDefaultComponent(fbb, "restart_comp", buildDefaultComponentProperties(fbb), deploy); auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); @@ -368,7 +397,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadSwitchRunTargetAction) auto switch_action = fb::CreateSwitchRunTargetAction(fbb, target_name); auto rt_name = fbb.CreateString("Startup"); auto rt = fb::CreateRunTarget( - fbb, rt_name, 0 /*description*/, 0 /*depends_on*/, 0.0 /*transition_timeout*/, switch_action); + fbb, rt_name, 0 /*description*/, 0 /*depends_on*/, 1.0 /*transition_timeout*/, switch_action); auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{rt}); auto result = loadBuffer(buildConfigWithRunTargets(fbb, rts)); @@ -414,9 +443,8 @@ TEST_F(FlatbufferConfigLoaderTest, LoadSandbox) ASSERT_THAT(result.has_value(), IsTrue()); ASSERT_THAT(result->components().size(), Eq(1U)); - ASSERT_THAT(result->components()[0].deployment_config.sandbox.has_value(), IsTrue()); - const auto& sb = result->components()[0].deployment_config.sandbox.value(); + const auto& sb = result->components()[0].deployment_config.sandbox; EXPECT_THAT(sb.uid, Eq(1000U)); EXPECT_THAT(sb.gid, Eq(1000U)); EXPECT_THAT(sb.supplementary_group_ids, Eq(std::vector{100, 200})); @@ -441,7 +469,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadComponentAliveSupervision) auto app_profile = fb::CreateApplicationProfile( fbb, fb::ApplicationType::Reporting_And_Supervised, false /*is_self_terminating*/, comp_alive_sup); auto bin_name = fbb.CreateString("supervised_bin"); - auto ready_cond = fb::CreateReadyCondition(fbb); + auto ready_cond = fb::CreateReadyCondition(fbb, fb::ProcessState::Running); auto comp_props = fb::CreateComponentProperties( fbb, bin_name, app_profile, 0 /*depends_on*/, 0 /*process_arguments*/, ready_cond); @@ -455,8 +483,10 @@ TEST_F(FlatbufferConfigLoaderTest, LoadComponentAliveSupervision) ASSERT_THAT(as.has_value(), IsTrue()); EXPECT_THAT(as->reporting_cycle_ms, Eq(1000U)); EXPECT_THAT(as->failed_cycles_tolerance, Eq(3U)); - EXPECT_THAT(as->min_indications, Eq(2U)); - EXPECT_THAT(as->max_indications, Eq(5U)); + ASSERT_THAT(as->min_indications.has_value(), IsTrue()); + EXPECT_THAT(*as->min_indications, Eq(2U)); + ASSERT_THAT(as->max_indications.has_value(), IsTrue()); + EXPECT_THAT(*as->max_indications, Eq(5U)); } TEST_F(FlatbufferConfigLoaderTest, LoadEnvironmentalVariables) @@ -475,8 +505,10 @@ TEST_F(FlatbufferConfigLoaderTest, LoadEnvironmentalVariables) auto bin_dir = fbb.CreateString("/opt"); auto work_dir = fbb.CreateString("/tmp"); - auto deploy = - fb::CreateDeploymentConfig(fbb, 0.5 /*ready_timeout*/, 0.5 /*shutdown_timeout*/, env_vars, bin_dir, work_dir); + auto sandbox = buildDefaultSandbox(fbb); + auto deploy = fb::CreateDeploymentConfig( + fbb, 0.5 /*ready_timeout*/, 0.5 /*shutdown_timeout*/, env_vars, + bin_dir, work_dir, 0 /*ready_recovery_action*/, 0 /*recovery_action*/, sandbox); auto comp = buildDefaultComponent(fbb, "env_comp", buildDefaultComponentProperties(fbb), deploy); auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); @@ -532,19 +564,47 @@ TEST_F(FlatbufferConfigLoaderTest, OptionalWatchdogAbsent) EXPECT_THAT(result->watchdog().has_value(), IsFalse()); } -TEST_F(FlatbufferConfigLoaderTest, OptionalSandboxAbsent) +TEST_F(FlatbufferConfigLoaderTest, OptionalReadyConditionAbsent) { - RecordProperty("Description", "When no sandbox is present on a component, it is nullopt."); + RecordProperty("Description", "When no ready_condition is present on a component, it is nullopt."); ::flatbuffers::FlatBufferBuilder fbb; - auto comp = buildDefaultComponent(fbb, "no_sandbox"); + auto bin_name = fbb.CreateString("no_rc_bin"); + auto app_profile = fb::CreateApplicationProfile(fbb, fb::ApplicationType::Native, false); + auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile); + + auto comp = buildDefaultComponent(fbb, "no_rc_comp", comp_props); auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); ASSERT_THAT(result.has_value(), IsTrue()); - EXPECT_THAT(result->components()[0].deployment_config.sandbox.has_value(), IsFalse()); + EXPECT_THAT(result->components()[0].component_properties.ready_condition.has_value(), IsFalse()); +} + +TEST_F(FlatbufferConfigLoaderTest, OptionalAliveSupervisionIndicationsAbsent) +{ + RecordProperty("Description", "When min/max_indications are absent, they are nullopt."); + + ::flatbuffers::FlatBufferBuilder fbb; + + auto comp_alive_sup = fb::CreateComponentAliveSupervision(fbb, 1.0 /*reporting_cycle*/, 3 /*failed_cycles_tolerance*/); + auto app_profile = fb::CreateApplicationProfile(fbb, fb::ApplicationType::Native, false, comp_alive_sup); + auto bin_name = fbb.CreateString("no_ind_bin"); + auto ready_cond = fb::CreateReadyCondition(fbb, fb::ProcessState::Running); + auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile, 0, 0, ready_cond); + + auto comp = buildDefaultComponent(fbb, "no_ind_comp", comp_props); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); + + auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); + + ASSERT_THAT(result.has_value(), IsTrue()); + const auto& as = result->components()[0].component_properties.application_profile.alive_supervision; + ASSERT_THAT(as.has_value(), IsTrue()); + EXPECT_THAT(as->min_indications.has_value(), IsFalse()); + EXPECT_THAT(as->max_indications.has_value(), IsFalse()); } // ============================================================================ @@ -557,9 +617,9 @@ TEST_F(FlatbufferConfigLoaderTest, MapNativeApplicationType) ::flatbuffers::FlatBufferBuilder fbb; - auto app_profile = fb::CreateApplicationProfile(fbb, fb::ApplicationType::Native); + auto app_profile = fb::CreateApplicationProfile(fbb, fb::ApplicationType::Native, false); auto bin_name = fbb.CreateString("native_bin"); - auto ready_cond = fb::CreateReadyCondition(fbb); + auto ready_cond = fb::CreateReadyCondition(fbb, fb::ProcessState::Running); auto comp_props = fb::CreateComponentProperties( fbb, bin_name, app_profile, 0 /*depends_on*/, 0 /*process_arguments*/, ready_cond); @@ -580,9 +640,9 @@ TEST_F(FlatbufferConfigLoaderTest, MapReportingAndSupervisedType) ::flatbuffers::FlatBufferBuilder fbb; - auto app_profile = fb::CreateApplicationProfile(fbb, fb::ApplicationType::Reporting_And_Supervised); + auto app_profile = fb::CreateApplicationProfile(fbb, fb::ApplicationType::Reporting_And_Supervised, false); auto bin_name = fbb.CreateString("supervised_bin"); - auto ready_cond = fb::CreateReadyCondition(fbb); + auto ready_cond = fb::CreateReadyCondition(fbb, fb::ProcessState::Running); auto comp_props = fb::CreateComponentProperties( fbb, bin_name, app_profile, 0 /*depends_on*/, 0 /*process_arguments*/, ready_cond); @@ -602,7 +662,7 @@ TEST_F(FlatbufferConfigLoaderTest, MapTerminatedProcessState) ::flatbuffers::FlatBufferBuilder fbb; - auto app_profile = fb::CreateApplicationProfile(fbb); + auto app_profile = fb::CreateApplicationProfile(fbb, fb::ApplicationType::Native, false); auto ready_cond = fb::CreateReadyCondition(fbb, fb::ProcessState::Terminated); auto bin_name = fbb.CreateString("term_bin"); auto comp_props = fb::CreateComponentProperties( @@ -614,7 +674,8 @@ TEST_F(FlatbufferConfigLoaderTest, MapTerminatedProcessState) auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); ASSERT_THAT(result.has_value(), IsTrue()); - EXPECT_THAT(result->components()[0].component_properties.ready_condition.process_state, + ASSERT_THAT(result->components()[0].component_properties.ready_condition.has_value(), IsTrue()); + EXPECT_THAT(result->components()[0].component_properties.ready_condition->process_state, Eq(ProcessState::Terminated)); } @@ -684,24 +745,21 @@ TEST_F(FlatbufferConfigLoaderTest, SandboxUidOutOfRangeReturnsInvalidFormat) if constexpr (std::numeric_limits::max() >= std::numeric_limits::max()) { - // On Linux, uid_t and gid_t are typically 32-bit unsigned integers, so any uint32_t value is valid. In that case, this test is not applicable. - // On QNX, uid_t and gid_t can be int32_t, so values above INT32_MAX would be invalid. GTEST_SKIP() << "uid_t range covers all uint32_t values on this platform"; } ::flatbuffers::FlatBufferBuilder fbb; - auto sandbox = fb::CreateSandbox(fbb, std::numeric_limits::max() /*uid*/, 1000 /*gid*/); + auto sandbox = fb::CreateSandbox(fbb, + std::numeric_limits::max() /*uid*/, + 1000 /*gid*/, + 0 /*supplementary_group_ids*/, + 0 /*security_policy*/, + fb::SchedulingPolicy::OTHER, + 0 /*scheduling_priority*/); auto bin_dir = fbb.CreateString("/opt"); - auto deploy = fb::CreateDeploymentConfig(fbb, - 0.0 /*ready_timeout*/, - 0.0 /*shutdown_timeout*/, - 0 /*environmental_variables*/, - bin_dir, - 0 /*working_dir*/, - 0 /*ready_recovery_action*/, - 0 /*recovery_action*/, - sandbox); + auto work_dir = fbb.CreateString("/tmp"); + auto deploy = fb::CreateDeploymentConfig(fbb, 1.0, 1.0, 0, bin_dir, work_dir, 0, 0, sandbox); auto comp = buildDefaultComponent(fbb, "bad_uid_comp", buildDefaultComponentProperties(fbb), deploy); auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); @@ -718,24 +776,21 @@ TEST_F(FlatbufferConfigLoaderTest, SandboxGidOutOfRangeReturnsInvalidFormat) if constexpr (std::numeric_limits::max() >= std::numeric_limits::max()) { - // On Linux, uid_t and gid_t are typically 32-bit unsigned integers, so any uint32_t value is valid. In that case, this test is not applicable. - // On QNX, uid_t and gid_t can be int32_t, so values above INT32_MAX would be invalid. GTEST_SKIP() << "gid_t range covers all uint32_t values on this platform"; } ::flatbuffers::FlatBufferBuilder fbb; - auto sandbox = fb::CreateSandbox(fbb, 1000 /*uid*/, std::numeric_limits::max() /*gid*/); + auto sandbox = fb::CreateSandbox(fbb, + 1000 /*uid*/, + std::numeric_limits::max() /*gid*/, + 0 /*supplementary_group_ids*/, + 0 /*security_policy*/, + fb::SchedulingPolicy::OTHER, + 0 /*scheduling_priority*/); auto bin_dir = fbb.CreateString("/opt"); - auto deploy = fb::CreateDeploymentConfig(fbb, - 0.0 /*ready_timeout*/, - 0.0 /*shutdown_timeout*/, - 0 /*environmental_variables*/, - bin_dir, - 0 /*working_dir*/, - 0 /*ready_recovery_action*/, - 0 /*recovery_action*/, - sandbox); + auto work_dir = fbb.CreateString("/tmp"); + auto deploy = fb::CreateDeploymentConfig(fbb, 1.0, 1.0, 0, bin_dir, work_dir, 0, 0, sandbox); auto comp = buildDefaultComponent(fbb, "bad_gid_comp", buildDefaultComponentProperties(fbb), deploy); auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); @@ -752,25 +807,22 @@ TEST_F(FlatbufferConfigLoaderTest, SandboxSupplementaryGidOutOfRangeReturnsInval if constexpr (std::numeric_limits::max() >= std::numeric_limits::max()) { - // On Linux, uid_t and gid_t are typically 32-bit unsigned integers, so any uint32_t value is valid. In that case, this test is not applicable. - // On QNX, uid_t and gid_t can be int32_t, so values above INT32_MAX would be invalid. GTEST_SKIP() << "gid_t range covers all uint32_t values on this platform"; } ::flatbuffers::FlatBufferBuilder fbb; auto supp_gids = fbb.CreateVector(std::vector{100, std::numeric_limits::max()}); - auto sandbox = fb::CreateSandbox(fbb, 1000 /*uid*/, 1000 /*gid*/, supp_gids); + auto sandbox = fb::CreateSandbox(fbb, + 1000 /*uid*/, + 1000 /*gid*/, + supp_gids, + 0 /*security_policy*/, + fb::SchedulingPolicy::OTHER, + 0 /*scheduling_priority*/); auto bin_dir = fbb.CreateString("/opt"); - auto deploy = fb::CreateDeploymentConfig(fbb, - 0.0 /*ready_timeout*/, - 0.0 /*shutdown_timeout*/, - 0 /*environmental_variables*/, - bin_dir, - 0 /*working_dir*/, - 0 /*ready_recovery_action*/, - 0 /*recovery_action*/, - sandbox); + auto work_dir = fbb.CreateString("/tmp"); + auto deploy = fb::CreateDeploymentConfig(fbb, 1.0, 1.0, 0, bin_dir, work_dir, 0, 0, sandbox); auto comp = buildDefaultComponent(fbb, "bad_supp_gid_comp", buildDefaultComponentProperties(fbb), deploy); auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); @@ -781,6 +833,375 @@ TEST_F(FlatbufferConfigLoaderTest, SandboxSupplementaryGidOutOfRangeReturnsInval EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); } +// ============================================================================ +// Missing required field tests +// ============================================================================ + +TEST_F(FlatbufferConfigLoaderTest, MissingSchemaVersionReturnsInvalidFormat) +{ + RecordProperty("Description", "A config without schema_version returns InvalidFormat."); + + ::flatbuffers::FlatBufferBuilder fbb; + auto irt = fbb.CreateString("Startup"); + auto fallback = fb::CreateFallbackRunTarget(fbb, 0, 0, 1.0); + auto alive_sup = fb::CreateAliveSupervision(fbb, 1.0); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); + auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); + auto config = fb::CreateLaunchManagerConfig(fbb, std::nullopt, comps, rts, irt, fallback, alive_sup); + + auto result = loadBuffer(finishBuffer(fbb, config)); + + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); +} + +TEST_F(FlatbufferConfigLoaderTest, MissingEvaluationCycleReturnsInvalidFormat) +{ + RecordProperty("Description", "AliveSupervision without evaluation_cycle returns InvalidFormat."); + + ::flatbuffers::FlatBufferBuilder fbb; + auto irt = fbb.CreateString("Startup"); + auto fallback = fb::CreateFallbackRunTarget(fbb, 0, 0, 1.0); + auto alive_sup = fb::CreateAliveSupervision(fbb); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); + auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); + auto config = fb::CreateLaunchManagerConfig(fbb, 1, comps, rts, irt, fallback, alive_sup); + + auto result = loadBuffer(finishBuffer(fbb, config)); + + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); +} + +TEST_F(FlatbufferConfigLoaderTest, MissingFallbackTransitionTimeoutReturnsInvalidFormat) +{ + RecordProperty("Description", "FallbackRunTarget without transition_timeout returns InvalidFormat."); + + ::flatbuffers::FlatBufferBuilder fbb; + auto irt = fbb.CreateString("Startup"); + auto fallback = fb::CreateFallbackRunTarget(fbb); + auto alive_sup = fb::CreateAliveSupervision(fbb, 1.0); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); + auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); + auto config = fb::CreateLaunchManagerConfig(fbb, 1, comps, rts, irt, fallback, alive_sup); + + auto result = loadBuffer(finishBuffer(fbb, config)); + + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); +} + +TEST_F(FlatbufferConfigLoaderTest, MissingRunTargetTransitionTimeoutReturnsInvalidFormat) +{ + RecordProperty("Description", "RunTarget without transition_timeout returns InvalidFormat."); + + ::flatbuffers::FlatBufferBuilder fbb; + auto switch_target = fbb.CreateString("SafeState"); + auto switch_action = fb::CreateSwitchRunTargetAction(fbb, switch_target); + auto rt_name = fbb.CreateString("Startup"); + auto rt = fb::CreateRunTarget(fbb, rt_name, 0, 0, std::nullopt, switch_action); + auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{rt}); + + auto result = loadBuffer(buildConfigWithRunTargets(fbb, rts)); + + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); +} + +TEST_F(FlatbufferConfigLoaderTest, MissingReadyTimeoutReturnsInvalidFormat) +{ + RecordProperty("Description", "DeploymentConfig without ready_timeout returns InvalidFormat."); + + ::flatbuffers::FlatBufferBuilder fbb; + auto bin_dir = fbb.CreateString("/opt"); + auto work_dir = fbb.CreateString("/tmp"); + auto sandbox = buildDefaultSandbox(fbb); + auto deploy = fb::CreateDeploymentConfig(fbb, std::nullopt, 1.0, 0, bin_dir, work_dir, 0, 0, sandbox); + + auto comp = buildDefaultComponent(fbb, "comp", buildDefaultComponentProperties(fbb), deploy); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); + + auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); + + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); +} + +TEST_F(FlatbufferConfigLoaderTest, MissingShutdownTimeoutReturnsInvalidFormat) +{ + RecordProperty("Description", "DeploymentConfig without shutdown_timeout returns InvalidFormat."); + + ::flatbuffers::FlatBufferBuilder fbb; + auto bin_dir = fbb.CreateString("/opt"); + auto work_dir = fbb.CreateString("/tmp"); + auto sandbox = buildDefaultSandbox(fbb); + auto deploy = fb::CreateDeploymentConfig(fbb, 1.0, std::nullopt, 0, bin_dir, work_dir, 0, 0, sandbox); + + auto comp = buildDefaultComponent(fbb, "comp", buildDefaultComponentProperties(fbb), deploy); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); + + auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); + + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); +} + +TEST_F(FlatbufferConfigLoaderTest, MissingApplicationTypeReturnsInvalidFormat) +{ + RecordProperty("Description", "ApplicationProfile without application_type returns InvalidFormat."); + + ::flatbuffers::FlatBufferBuilder fbb; + auto app_profile = fb::CreateApplicationProfile(fbb, std::nullopt, false); + auto bin_name = fbb.CreateString("bin"); + auto ready_cond = fb::CreateReadyCondition(fbb, fb::ProcessState::Running); + auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile, 0, 0, ready_cond); + + auto comp = buildDefaultComponent(fbb, "comp", comp_props); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); + + auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); + + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); +} + +TEST_F(FlatbufferConfigLoaderTest, MissingIsSelfTerminatingReturnsInvalidFormat) +{ + RecordProperty("Description", "ApplicationProfile without is_self_terminating returns InvalidFormat."); + + ::flatbuffers::FlatBufferBuilder fbb; + auto app_profile = fb::CreateApplicationProfile(fbb, fb::ApplicationType::Native, std::nullopt); + auto bin_name = fbb.CreateString("bin"); + auto ready_cond = fb::CreateReadyCondition(fbb, fb::ProcessState::Running); + auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile, 0, 0, ready_cond); + + auto comp = buildDefaultComponent(fbb, "comp", comp_props); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); + + auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); + + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); +} + +TEST_F(FlatbufferConfigLoaderTest, MissingProcessStateReturnsInvalidFormat) +{ + RecordProperty("Description", "ReadyCondition without process_state returns InvalidFormat."); + + ::flatbuffers::FlatBufferBuilder fbb; + auto app_profile = fb::CreateApplicationProfile(fbb, fb::ApplicationType::Native, false); + auto bin_name = fbb.CreateString("bin"); + auto ready_cond = fb::CreateReadyCondition(fbb); + auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile, 0, 0, ready_cond); + + auto comp = buildDefaultComponent(fbb, "comp", comp_props); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); + + auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); + + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); +} + +TEST_F(FlatbufferConfigLoaderTest, MissingReportingCycleReturnsInvalidFormat) +{ + RecordProperty("Description", "ComponentAliveSupervision without reporting_cycle returns InvalidFormat."); + + ::flatbuffers::FlatBufferBuilder fbb; + auto comp_alive_sup = fb::CreateComponentAliveSupervision(fbb, std::nullopt, 3); + auto app_profile = fb::CreateApplicationProfile(fbb, fb::ApplicationType::Native, false, comp_alive_sup); + auto bin_name = fbb.CreateString("bin"); + auto ready_cond = fb::CreateReadyCondition(fbb, fb::ProcessState::Running); + auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile, 0, 0, ready_cond); + + auto comp = buildDefaultComponent(fbb, "comp", comp_props); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); + + auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); + + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); +} + +TEST_F(FlatbufferConfigLoaderTest, MissingFailedCyclesToleranceReturnsInvalidFormat) +{ + RecordProperty("Description", "ComponentAliveSupervision without failed_cycles_tolerance returns InvalidFormat."); + + ::flatbuffers::FlatBufferBuilder fbb; + auto comp_alive_sup = fb::CreateComponentAliveSupervision(fbb, 1.0, std::nullopt); + auto app_profile = fb::CreateApplicationProfile(fbb, fb::ApplicationType::Native, false, comp_alive_sup); + auto bin_name = fbb.CreateString("bin"); + auto ready_cond = fb::CreateReadyCondition(fbb, fb::ProcessState::Running); + auto comp_props = fb::CreateComponentProperties(fbb, bin_name, app_profile, 0, 0, ready_cond); + + auto comp = buildDefaultComponent(fbb, "comp", comp_props); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); + + auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); + + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); +} + +TEST_F(FlatbufferConfigLoaderTest, MissingRestartActionFieldsReturnsInvalidFormat) +{ + RecordProperty("Description", "RestartAction without required fields returns InvalidFormat."); + + ::flatbuffers::FlatBufferBuilder fbb; + auto restart = fb::CreateRestartAction(fbb); + auto bin_dir = fbb.CreateString("/opt"); + auto work_dir = fbb.CreateString("/tmp"); + auto sandbox = buildDefaultSandbox(fbb); + auto deploy = fb::CreateDeploymentConfig(fbb, 1.0, 1.0, 0, bin_dir, work_dir, restart, 0, sandbox); + + auto comp = buildDefaultComponent(fbb, "comp", buildDefaultComponentProperties(fbb), deploy); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); + + auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); + + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); +} + +TEST_F(FlatbufferConfigLoaderTest, MissingSandboxUidReturnsInvalidFormat) +{ + RecordProperty("Description", "Sandbox without uid returns InvalidFormat."); + + ::flatbuffers::FlatBufferBuilder fbb; + auto sandbox = fb::CreateSandbox(fbb, std::nullopt, 0, 0, 0, fb::SchedulingPolicy::OTHER, 0); + auto bin_dir = fbb.CreateString("/opt"); + auto work_dir = fbb.CreateString("/tmp"); + auto deploy = fb::CreateDeploymentConfig(fbb, 1.0, 1.0, 0, bin_dir, work_dir, 0, 0, sandbox); + + auto comp = buildDefaultComponent(fbb, "comp", buildDefaultComponentProperties(fbb), deploy); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); + + auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); + + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); +} + +TEST_F(FlatbufferConfigLoaderTest, MissingSandboxGidReturnsInvalidFormat) +{ + RecordProperty("Description", "Sandbox without gid returns InvalidFormat."); + + ::flatbuffers::FlatBufferBuilder fbb; + auto sandbox = fb::CreateSandbox(fbb, 0, std::nullopt, 0, 0, fb::SchedulingPolicy::OTHER, 0); + auto bin_dir = fbb.CreateString("/opt"); + auto work_dir = fbb.CreateString("/tmp"); + auto deploy = fb::CreateDeploymentConfig(fbb, 1.0, 1.0, 0, bin_dir, work_dir, 0, 0, sandbox); + + auto comp = buildDefaultComponent(fbb, "comp", buildDefaultComponentProperties(fbb), deploy); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); + + auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); + + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); +} + +TEST_F(FlatbufferConfigLoaderTest, MissingSandboxSchedulingPolicyReturnsInvalidFormat) +{ + RecordProperty("Description", "Sandbox without scheduling_policy returns InvalidFormat."); + + ::flatbuffers::FlatBufferBuilder fbb; + auto sandbox = fb::CreateSandbox(fbb, 0, 0, 0, 0, std::nullopt, 0); + auto bin_dir = fbb.CreateString("/opt"); + auto work_dir = fbb.CreateString("/tmp"); + auto deploy = fb::CreateDeploymentConfig(fbb, 1.0, 1.0, 0, bin_dir, work_dir, 0, 0, sandbox); + + auto comp = buildDefaultComponent(fbb, "comp", buildDefaultComponentProperties(fbb), deploy); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); + + auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); + + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); +} + +TEST_F(FlatbufferConfigLoaderTest, MissingSandboxSchedulingPriorityReturnsInvalidFormat) +{ + RecordProperty("Description", "Sandbox without scheduling_priority returns InvalidFormat."); + + ::flatbuffers::FlatBufferBuilder fbb; + auto sandbox = fb::CreateSandbox(fbb, 0, 0, 0, 0, fb::SchedulingPolicy::OTHER, std::nullopt); + auto bin_dir = fbb.CreateString("/opt"); + auto work_dir = fbb.CreateString("/tmp"); + auto deploy = fb::CreateDeploymentConfig(fbb, 1.0, 1.0, 0, bin_dir, work_dir, 0, 0, sandbox); + + auto comp = buildDefaultComponent(fbb, "comp", buildDefaultComponentProperties(fbb), deploy); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); + + auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); + + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); +} + +TEST_F(FlatbufferConfigLoaderTest, MissingWatchdogMaxTimeoutReturnsInvalidFormat) +{ + RecordProperty("Description", "Watchdog without max_timeout returns InvalidFormat."); + + ::flatbuffers::FlatBufferBuilder fbb; + auto dev_path = fbb.CreateString("/dev/watchdog0"); + auto watchdog = fb::CreateWatchdog(fbb, dev_path, std::nullopt, true, false); + + auto fallback = fb::CreateFallbackRunTarget(fbb, 0, 0, 1.0); + auto alive_sup = fb::CreateAliveSupervision(fbb, 1.0); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); + auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); + auto irt = fbb.CreateString("Startup"); + auto config = fb::CreateLaunchManagerConfig(fbb, 1, comps, rts, irt, fallback, alive_sup, watchdog); + + auto result = loadBuffer(finishBuffer(fbb, config)); + + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); +} + +TEST_F(FlatbufferConfigLoaderTest, MissingWatchdogDeactivateOnShutdownReturnsInvalidFormat) +{ + RecordProperty("Description", "Watchdog without deactivate_on_shutdown returns InvalidFormat."); + + ::flatbuffers::FlatBufferBuilder fbb; + auto dev_path = fbb.CreateString("/dev/watchdog0"); + auto watchdog = fb::CreateWatchdog(fbb, dev_path, 30.0, std::nullopt, false); + + auto fallback = fb::CreateFallbackRunTarget(fbb, 0, 0, 1.0); + auto alive_sup = fb::CreateAliveSupervision(fbb, 1.0); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); + auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); + auto irt = fbb.CreateString("Startup"); + auto config = fb::CreateLaunchManagerConfig(fbb, 1, comps, rts, irt, fallback, alive_sup, watchdog); + + auto result = loadBuffer(finishBuffer(fbb, config)); + + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); +} + +TEST_F(FlatbufferConfigLoaderTest, MissingWatchdogRequireMagicCloseReturnsInvalidFormat) +{ + RecordProperty("Description", "Watchdog without require_magic_close returns InvalidFormat."); + + ::flatbuffers::FlatBufferBuilder fbb; + auto dev_path = fbb.CreateString("/dev/watchdog0"); + auto watchdog = fb::CreateWatchdog(fbb, dev_path, 30.0, true, std::nullopt); + + auto fallback = fb::CreateFallbackRunTarget(fbb, 0, 0, 1.0); + auto alive_sup = fb::CreateAliveSupervision(fbb, 1.0); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); + auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); + auto irt = fbb.CreateString("Startup"); + auto config = fb::CreateLaunchManagerConfig(fbb, 1, comps, rts, irt, fallback, alive_sup, watchdog); + + auto result = loadBuffer(finishBuffer(fbb, config)); + + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); +} + // ============================================================================ // Parameterized scheduling policy tests // ============================================================================ @@ -808,17 +1229,11 @@ TEST_P(SchedulingPolicyTest, ConvertsToExpectedPosixValue) 1000 /*gid*/, 0 /*supplementary_group_ids*/, 0 /*security_policy*/, - GetParam().fb_policy); + GetParam().fb_policy, + 0 /*scheduling_priority*/); auto bin_dir = fbb.CreateString("/opt"); - auto deploy = fb::CreateDeploymentConfig(fbb, - 0.0 /*ready_timeout*/, - 0.0 /*shutdown_timeout*/, - 0 /*environmental_variables*/, - bin_dir, - 0 /*working_dir*/, - 0 /*ready_recovery_action*/, - 0 /*recovery_action*/, - sandbox); + auto work_dir = fbb.CreateString("/tmp"); + auto deploy = fb::CreateDeploymentConfig(fbb, 1.0, 1.0, 0, bin_dir, work_dir, 0, 0, sandbox); auto comp = buildDefaultComponent(fbb, "sched_comp", buildDefaultComponentProperties(fbb), deploy); auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); @@ -826,8 +1241,7 @@ TEST_P(SchedulingPolicyTest, ConvertsToExpectedPosixValue) auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); ASSERT_THAT(result.has_value(), IsTrue()); - ASSERT_THAT(result->components()[0].deployment_config.sandbox.has_value(), IsTrue()); - EXPECT_THAT(result->components()[0].deployment_config.sandbox->scheduling_policy, + EXPECT_THAT(result->components()[0].deployment_config.sandbox.scheduling_policy, Eq(GetParam().expected_posix_value)); } @@ -857,17 +1271,11 @@ TEST_F(FlatbufferConfigLoaderTest, UnsupportedSchedulingPolicyReturnsInvalidForm 1000 /*gid*/, 0 /*supplementary_group_ids*/, 0 /*security_policy*/, - static_cast(99)); + static_cast(99), + 0 /*scheduling_priority*/); auto bin_dir = fbb.CreateString("/opt"); - auto deploy = fb::CreateDeploymentConfig(fbb, - 0.0 /*ready_timeout*/, - 0.0 /*shutdown_timeout*/, - 0 /*environmental_variables*/, - bin_dir, - 0 /*working_dir*/, - 0 /*ready_recovery_action*/, - 0 /*recovery_action*/, - sandbox); + auto work_dir = fbb.CreateString("/tmp"); + auto deploy = fb::CreateDeploymentConfig(fbb, 1.0, 1.0, 0, bin_dir, work_dir, 0, 0, sandbox); auto comp = buildDefaultComponent(fbb, "bad_sched_comp", buildDefaultComponentProperties(fbb), deploy); auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); diff --git a/src/launch_manager_daemon/config/src/new_lm_flatcfg.fbs b/src/launch_manager_daemon/config/src/new_lm_flatcfg.fbs index a52ab45a7..c491d4a10 100644 --- a/src/launch_manager_daemon/config/src/new_lm_flatcfg.fbs +++ b/src/launch_manager_daemon/config/src/new_lm_flatcfg.fbs @@ -1,6 +1,15 @@ // FlatBuffers schema for S-CORE Launch Manager configuration. // Equivalent to launch_manager.schema.json +// All fields are commented as either required or optional +// For non-scalar values: +// - required values are defined with "(required)" keyword in the schema and it is verified by flatbuffer that the value has been configured +// - optional values may be nullptr and are populated in the code as std::optional +// For scalar values: +// - required values are defined with "= null" and it is verified when loading that they have been configured. +// Note: Without "= null", flatbuffer will return a default value and there is no way to know if it has been configured or not +// - optional values are defined with "= null" and they are populated as std::optional in the code + namespace score.launch_manager.config.fb; // Specifies the level of integration between the component and the Launch Manager. @@ -27,46 +36,46 @@ enum SchedulingPolicy : byte { // Defines the configuration parameters used for alive monitoring of a component. table ComponentAliveSupervision { // Duration in seconds of the time interval used to verify alive notifications. - reporting_cycle:double; + reporting_cycle:double = null; // required // Maximum number of consecutive reporting cycle failures before recovery is triggered. - failed_cycles_tolerance:uint32; + failed_cycles_tolerance:uint32 = null; // required // Minimum number of checkpoints that must be reported within each reporting_cycle. - min_indications:uint32 = null; + min_indications:uint32 = null; // optional // Maximum number of checkpoints that may be reported within each reporting_cycle. - max_indications:uint32 = null; + max_indications:uint32 = null; // optional } // Defines the application profile that specifies the runtime behavior and capabilities of a component. table ApplicationProfile { - application_type:ApplicationType; + application_type:ApplicationType = null; // required // Whether the component terminates automatically once its tasks are completed. - is_self_terminating:bool; - alive_supervision:ComponentAliveSupervision; + is_self_terminating:bool = null; // required + alive_supervision:ComponentAliveSupervision; // optional } // Defines the conditions that determine when the component enters the ready state. table ReadyCondition { - process_state:ProcessState = null; + process_state:ProcessState = null; // required } // Defines essential characteristics of a software component. table ComponentProperties { // Relative path of the executable inside bin_dir. - binary_name:string (required); - application_profile:ApplicationProfile (required); + binary_name:string (required); // required + application_profile:ApplicationProfile (required); // required // Names of components that must reach ready state before this component starts. - depends_on:[string]; + depends_on:[string]; // optional // Ordered list of command-line arguments passed to the component at startup. - process_arguments:[string]; - ready_condition:ReadyCondition (required); + process_arguments:[string]; // optional + ready_condition:ReadyCondition; // optional } // Recovery action that restarts the POSIX process associated with a component. table RestartAction { // Maximum number of restart attempts before recovery is considered failed. - number_of_attempts:uint32; + number_of_attempts:uint32 = null; // required // Delay in seconds before initiating a restart attempt. - delay_before_restart:double; + delay_before_restart:double = null; // required } // Recovery action that switches to a specified Run Target. @@ -84,41 +93,41 @@ table EnvironmentalVariable { // Defines sandbox configuration parameters that isolate and constrain component execution. table Sandbox { // POSIX user ID (UID) under which the component executes. - uid:uint32; + uid:uint32 = null; // required // Primary POSIX group ID (GID) under which the component executes. - gid:uint32; + gid:uint32 = null; // required // Supplementary POSIX group IDs assigned to the component. - supplementary_group_ids:[uint32]; + supplementary_group_ids:[uint32]; // optional // Security policy or confinement profile name (e.g., SELinux or AppArmor profile). - security_policy:string; + security_policy:string; // optional // Scheduling policy for the component's initial thread. - scheduling_policy:SchedulingPolicy; + scheduling_policy:SchedulingPolicy = null; // required // Scheduling priority for the component's initial thread. - scheduling_priority:int32 = null; + scheduling_priority:int32 = null; // required // Maximum memory in bytes the component is permitted to use. - max_memory_usage:uint64 = null; + max_memory_usage:uint64 = null; // optional // Maximum CPU usage as a percentage of total CPU capacity. - max_cpu_usage:uint32 = null; + max_cpu_usage:uint32 = null; // optional } // Deployment configuration for a component. table DeploymentConfig { // Maximum time in seconds for the component to reach its ready state. - ready_timeout:double; + ready_timeout:double = null; // required // Maximum time in seconds for the component to terminate after SIGTERM. - shutdown_timeout:double; + shutdown_timeout:double = null; // required // Environment variables passed to the component at startup. - environmental_variables:[EnvironmentalVariable]; + environmental_variables:[EnvironmentalVariable]; // optional // Absolute path to the directory where the component is installed. - bin_dir:string (required); + bin_dir:string (required); // required // Working directory for the component during execution. - working_dir:string; + working_dir:string (required); // required // Recovery action when the component fails to reach ready state. // Can only be a RestartAction per the JSON schema constraint. - ready_recovery_action:RestartAction; + ready_recovery_action:RestartAction; // optional // Recovery action when the component malfunctions after reaching ready state. - recovery_action:SwitchRunTargetAction; - sandbox:Sandbox; + recovery_action:SwitchRunTargetAction; // optional + sandbox:Sandbox (required); // required } // Configuration for a Run Target representing an operational mode of the system. @@ -126,11 +135,11 @@ table RunTarget { // Unique Run Target identifier. name:string (required); // Human-readable description of the Run Target. - description:string; + description:string; // optional // Names of components and Run Targets that must be activated with this Run Target. - depends_on:[string]; + depends_on:[string]; // optional // Time limit in seconds for the Run Target transition. - transition_timeout:double; + transition_timeout:double = null; // required // Recovery action when a component in this Run Target fails. recovery_action:SwitchRunTargetAction (required); } @@ -138,55 +147,55 @@ table RunTarget { // An individual component entry with its identifier. table Component { // Unique component identifier. - name:string (required); + name:string (required); // required // Human-readable description of the component's purpose. - description:string; - component_properties:ComponentProperties (required); - deployment_config:DeploymentConfig (required); + description:string; // optional + component_properties:ComponentProperties (required); // required + deployment_config:DeploymentConfig (required); // required } // Global alive supervision configuration. table AliveSupervision { // Length in seconds of the time window used to assess alive supervision reports. - evaluation_cycle:double; + evaluation_cycle:double = null; // required } // External watchdog device configuration. table Watchdog { // Path to the external watchdog device file (e.g., /dev/watchdog). - device_file_path:string (required); + device_file_path:string (required); // required // Maximum timeout in seconds configured on the external watchdog. - max_timeout:double; + max_timeout:double = null; // required // Whether the watchdog is deactivated during shutdown. - deactivate_on_shutdown:bool = null; + deactivate_on_shutdown:bool = null; // required // Whether the magic close sequence is performed on intentional shutdown. - require_magic_close:bool = null; + require_magic_close:bool = null; // required } // Fallback Run Target activated when all recovery attempts are exhausted. // Does not include a recovery_action. table FallbackRunTarget { // Human-readable description of the fallback Run Target. - description:string; + description:string; // optional // Names of components and Run Targets that must be activated. - depends_on:[string]; + depends_on:[string]; // optional // Time limit in seconds for the Run Target transition. - transition_timeout:double; + transition_timeout:double = null; // required } // Root configuration table for the S-CORE Launch Manager. table LaunchManagerConfig { // Schema version number. - schema_version:int32; + schema_version:int32 = null; // required // Software components managed by the Launch Manager. - components:[Component]; + components:[Component] (required); // required // Run Targets representing different operational modes. - run_targets:[RunTarget]; + run_targets:[RunTarget] (required); // required // Name of the initial Run Target activated during startup. - initial_run_target:string (required); - fallback_run_target:FallbackRunTarget (required); - alive_supervision:AliveSupervision (required); - watchdog:Watchdog; + initial_run_target:string (required); // required + fallback_run_target:FallbackRunTarget (required); // required + alive_supervision:AliveSupervision (required); // required + watchdog:Watchdog; // optional } root_type LaunchManagerConfig; From 4e9dffdf40a8363ce83206d5e301d4f3d2a74945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Fu=C3=9Fberger?= Date: Tue, 26 May 2026 08:09:20 +0200 Subject: [PATCH 21/26] Upgrade to latest baselibs release This removes the baselibs override --- MODULE.bazel | 9 +-------- MODULE.bazel.lock | 2 ++ 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 1b7d4fb7b..bc0a2cb58 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -132,14 +132,7 @@ oci.pull( use_repo(oci, "debian-test-runtime", "debian-test-runtime_linux_amd64") bazel_dep(name = "score_baselibs_rust", version = "0.1.2") -bazel_dep(name = "score_baselibs", version = "0.2.6") - -# Temporarily overwrite baselibs to use the new flatbuffer config loader until there is a new release -git_override( - module_name = "score_baselibs", - commit = "498a4b256c9073602140243d30c33b106e279f75", - remote = "https://github.com/eclipse-score/baselibs.git", -) +bazel_dep(name = "score_baselibs", version = "0.2.8") # Hedron's Compile Commands Extractor for Bazel # https://github.com/hedronvision/bazel-compile-commands-extractor diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 3583d88fd..08cbec6ed 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -820,6 +820,8 @@ "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_swift/1.16.0/MODULE.bazel": "not found", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_swift/1.18.0/MODULE.bazel": "not found", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/rules_swift/2.1.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_baselibs/0.2.8/MODULE.bazel": "167e2cdfea63ef2eb38546d83ceef833671263f9faae6e496e834f86c2427f0d", + "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_baselibs/0.2.8/source.json": "6a649da9895fcdcaa58b0a4de11be04770f3180bb7ff176d3dfcb9bfe72ef0f3", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_baselibs_rust/0.1.2/MODULE.bazel": "8a07e1c62986e941a6e182e39c9cd08391849eed55c2f4dbb02d72ef6f524346", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_baselibs_rust/0.1.2/source.json": "5d920b55b98cf3d87da75d5a3ab1915709867fda14991ef2843c5e7c33aa0391", "https://raw.githubusercontent.com/eclipse-score/bazel_registry/main/modules/score_bazel_cpp_toolchains/0.2.2/MODULE.bazel": "343a1892b1d5c616e0b4cbecfb5e548fa69328d22bb4fd5862bdd3cfa902142b", From dd96262ac9197f78bd5e02ea6bed35c651ae997e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Fu=C3=9Fberger?= Date: Tue, 26 May 2026 08:22:44 +0200 Subject: [PATCH 22/26] Validation of secToMs conversion + more error logs --- .../config/src/flatbuffer_config_loader.cpp | 90 ++++++++++++++++--- .../src/flatbuffer_config_loader_UT.cpp | 63 +++++++++++++ 2 files changed, 142 insertions(+), 11 deletions(-) diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp index 8d18b1392..fe6e95933 100644 --- a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp @@ -36,10 +36,24 @@ namespace constexpr int32_t kExpectedSchemaVersion = 1; constexpr double kSecondsToMilliseconds = 1000.0; -uint32_t secondsToMs(double seconds) +score::cpp::expected secondsToMs(double seconds) { + if (seconds < 0.0) + { + LM_LOG_ERROR() << "Negative time value " << seconds << " seconds is not supported"; + return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); + } + if (seconds * kSecondsToMilliseconds > static_cast(std::numeric_limits::max())) + { + LM_LOG_ERROR() << "Time value " << seconds << " seconds exceeds maximum representable milliseconds"; + return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); + } const auto result = static_cast(seconds * kSecondsToMilliseconds); - assert(!(seconds > 0.0 && result == 0U) && "Sub-millisecond precision is not supported: value rounds to 0ms"); + if (seconds > 0.0 && result == 0U) + { + LM_LOG_ERROR() << "Sub-millisecond time value " << seconds << " seconds rounds to 0ms"; + return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); + } return result; } @@ -170,8 +184,13 @@ score::cpp::expected, IConfigLoader::Error> convert LM_LOG_ERROR() << "RestartAction::delay_before_restart is required but missing"; return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); } - return std::optional{ - RestartAction{*ra->number_of_attempts(), secondsToMs(*ra->delay_before_restart())}}; + auto delay_ms = secondsToMs(*ra->delay_before_restart()); + if (!delay_ms.has_value()) + { + LM_LOG_ERROR() << "Invalid value for RestartAction::delay_before_restart"; + return score::cpp::make_unexpected(delay_ms.error()); + } + return std::optional{RestartAction{*ra->number_of_attempts(), *delay_ms}}; } std::optional convertSwitchRunTargetAction(const fb::SwitchRunTargetAction* sa) @@ -208,7 +227,13 @@ score::cpp::expected convertCom LM_LOG_ERROR() << "ComponentAliveSupervision::failed_cycles_tolerance is required but missing"; return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); } - result.reporting_cycle_ms = secondsToMs(*fb_cas->reporting_cycle()); + auto reporting_cycle_ms = secondsToMs(*fb_cas->reporting_cycle()); + if (!reporting_cycle_ms.has_value()) + { + LM_LOG_ERROR() << "Invalid value for ComponentAliveSupervision::reporting_cycle"; + return score::cpp::make_unexpected(reporting_cycle_ms.error()); + } + result.reporting_cycle_ms = *reporting_cycle_ms; result.failed_cycles_tolerance = *fb_cas->failed_cycles_tolerance(); result.min_indications = fb_cas->min_indications().has_value() ? std::optional{*fb_cas->min_indications()} @@ -375,8 +400,20 @@ score::cpp::expected convertDeploymentCo LM_LOG_ERROR() << "DeploymentConfig::shutdown_timeout is required but missing"; return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); } - result.ready_timeout_ms = secondsToMs(*fb_dc->ready_timeout()); - result.shutdown_timeout_ms = secondsToMs(*fb_dc->shutdown_timeout()); + auto ready_timeout_ms = secondsToMs(*fb_dc->ready_timeout()); + if (!ready_timeout_ms.has_value()) + { + LM_LOG_ERROR() << "Invalid value for DeploymentConfig::ready_timeout"; + return score::cpp::make_unexpected(ready_timeout_ms.error()); + } + auto shutdown_timeout_ms = secondsToMs(*fb_dc->shutdown_timeout()); + if (!shutdown_timeout_ms.has_value()) + { + LM_LOG_ERROR() << "Invalid value for DeploymentConfig::shutdown_timeout"; + return score::cpp::make_unexpected(shutdown_timeout_ms.error()); + } + result.ready_timeout_ms = *ready_timeout_ms; + result.shutdown_timeout_ms = *shutdown_timeout_ms; result.environmental_variables = convertEnvironmentalVariables(fb_dc->environmental_variables()); result.bin_dir = fb_dc->bin_dir()->str(); result.working_dir = fb_dc->working_dir()->str(); @@ -410,12 +447,14 @@ score::cpp::expected convertComponent(con auto component_properties = convertComponentProperties(fb_comp->component_properties()); if (!component_properties.has_value()) { + LM_LOG_ERROR() << "Invalid component_properties for Component '" << result.name << "'"; return score::cpp::make_unexpected(component_properties.error()); } result.component_properties = std::move(*component_properties); auto deployment_config = convertDeploymentConfig(fb_comp->deployment_config()); if (!deployment_config.has_value()) { + LM_LOG_ERROR() << "Invalid deployment_config for Component '" << result.name << "'"; return score::cpp::make_unexpected(deployment_config.error()); } result.deployment_config = std::move(*deployment_config); @@ -438,7 +477,13 @@ score::cpp::expected convertRunTarget(con result.name = fb_rt->name()->str(); result.description = safeString(fb_rt->description()); result.depends_on = convertStringVector(fb_rt->depends_on()); - result.transition_timeout_ms = secondsToMs(*fb_rt->transition_timeout()); + auto transition_timeout_ms = secondsToMs(*fb_rt->transition_timeout()); + if (!transition_timeout_ms.has_value()) + { + LM_LOG_ERROR() << "Invalid value for RunTarget::transition_timeout"; + return score::cpp::make_unexpected(transition_timeout_ms.error()); + } + result.transition_timeout_ms = *transition_timeout_ms; result.recovery_action = convertRequiredSwitchRunTargetAction(fb_rt->recovery_action()); } return result; @@ -457,7 +502,13 @@ score::cpp::expected convertFallb } result.description = safeString(fb_frt->description()); result.depends_on = convertStringVector(fb_frt->depends_on()); - result.transition_timeout_ms = secondsToMs(*fb_frt->transition_timeout()); + auto transition_timeout_ms = secondsToMs(*fb_frt->transition_timeout()); + if (!transition_timeout_ms.has_value()) + { + LM_LOG_ERROR() << "Invalid value for FallbackRunTarget::transition_timeout"; + return score::cpp::make_unexpected(transition_timeout_ms.error()); + } + result.transition_timeout_ms = *transition_timeout_ms; } return result; } @@ -474,7 +525,13 @@ score::cpp::expected convertAliveS LM_LOG_ERROR() << "AliveSupervision::evaluation_cycle is required but missing"; return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); } - return AliveSupervisionConfig{secondsToMs(*fb_as->evaluation_cycle())}; + auto evaluation_cycle_ms = secondsToMs(*fb_as->evaluation_cycle()); + if (!evaluation_cycle_ms.has_value()) + { + LM_LOG_ERROR() << "Invalid value for AliveSupervision::evaluation_cycle"; + return score::cpp::make_unexpected(evaluation_cycle_ms.error()); + } + return AliveSupervisionConfig{*evaluation_cycle_ms}; } score::cpp::expected, IConfigLoader::Error> convertWatchdog(const fb::Watchdog* fb_wd) @@ -501,7 +558,13 @@ score::cpp::expected, IConfigLoader::Error> conver } WatchdogConfig result{}; result.device_file_path = fb_wd->device_file_path()->str(); - result.max_timeout_ms = secondsToMs(*fb_wd->max_timeout()); + auto max_timeout_ms = secondsToMs(*fb_wd->max_timeout()); + if (!max_timeout_ms.has_value()) + { + LM_LOG_ERROR() << "Invalid value for Watchdog::max_timeout"; + return score::cpp::make_unexpected(max_timeout_ms.error()); + } + result.max_timeout_ms = *max_timeout_ms; result.deactivate_on_shutdown = *fb_wd->deactivate_on_shutdown(); result.require_magic_close = *fb_wd->require_magic_close(); return std::optional{std::move(result)}; @@ -570,6 +633,7 @@ score::cpp::expected parseFlatbuffer(const std::ve auto component = convertComponent(comp); if (!component.has_value()) { + LM_LOG_ERROR() << "Failed to load configuration for Component '" << safeString(comp->name()) << "'"; return score::cpp::make_unexpected(component.error()); } components.emplace_back(std::move(*component)); @@ -588,6 +652,7 @@ score::cpp::expected parseFlatbuffer(const std::ve auto run_target = convertRunTarget(rt); if (!run_target.has_value()) { + LM_LOG_ERROR() << "Failed to load configuration for RunTarget '" << safeString(rt->name()) << "'"; return score::cpp::make_unexpected(run_target.error()); } run_targets.emplace_back(std::move(*run_target)); @@ -600,6 +665,7 @@ score::cpp::expected parseFlatbuffer(const std::ve auto fallback = convertFallbackRunTarget(config->fallback_run_target()); if (!fallback.has_value()) { + LM_LOG_ERROR() << "Failed to load configuration for FallbackRunTarget"; return score::cpp::make_unexpected(fallback.error()); } builder.setFallbackRunTarget(std::move(*fallback)); @@ -608,6 +674,7 @@ score::cpp::expected parseFlatbuffer(const std::ve auto alive_sup = convertAliveSupervision(config->alive_supervision()); if (!alive_sup.has_value()) { + LM_LOG_ERROR() << "Failed to load configuration for AliveSupervision"; return score::cpp::make_unexpected(alive_sup.error()); } builder.setAliveSupervision(std::move(*alive_sup)); @@ -615,6 +682,7 @@ score::cpp::expected parseFlatbuffer(const std::ve auto wd = convertWatchdog(config->watchdog()); if (!wd.has_value()) { + LM_LOG_ERROR() << "Failed to load configuration for Watchdog"; return score::cpp::make_unexpected(wd.error()); } if (wd->has_value()) diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp index c82617110..1ae7a7057 100644 --- a/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp @@ -833,6 +833,69 @@ TEST_F(FlatbufferConfigLoaderTest, SandboxSupplementaryGidOutOfRangeReturnsInval EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); } +// ============================================================================ +// Invalid time value tests (secondsToMs validation) +// ============================================================================ + +TEST_F(FlatbufferConfigLoaderTest, NegativeTimeValueReturnsInvalidFormat) +{ + RecordProperty("Description", "A negative time value returns InvalidFormat."); + + ::flatbuffers::FlatBufferBuilder fbb; + auto bin_dir = fbb.CreateString("/opt"); + auto work_dir = fbb.CreateString("/tmp"); + auto sandbox = buildDefaultSandbox(fbb); + auto deploy = fb::CreateDeploymentConfig(fbb, -1.0 /*ready_timeout*/, 1.0, 0, bin_dir, work_dir, 0, 0, sandbox); + + auto comp = buildDefaultComponent(fbb, "comp", buildDefaultComponentProperties(fbb), deploy); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); + + auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); + + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); +} + +TEST_F(FlatbufferConfigLoaderTest, OverflowTimeValueReturnsInvalidFormat) +{ + RecordProperty("Description", "A time value exceeding uint32_t max milliseconds returns InvalidFormat."); + + ::flatbuffers::FlatBufferBuilder fbb; + auto bin_dir = fbb.CreateString("/opt"); + auto work_dir = fbb.CreateString("/tmp"); + auto sandbox = buildDefaultSandbox(fbb); + auto deploy = fb::CreateDeploymentConfig( + fbb, 5000000.0 /*ready_timeout*/, 1.0, 0, bin_dir, work_dir, 0, 0, sandbox); + + auto comp = buildDefaultComponent(fbb, "comp", buildDefaultComponentProperties(fbb), deploy); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); + + auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); + + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); +} + +TEST_F(FlatbufferConfigLoaderTest, SubMillisecondTimeValueReturnsInvalidFormat) +{ + RecordProperty("Description", "A positive time value that rounds to 0ms returns InvalidFormat."); + + ::flatbuffers::FlatBufferBuilder fbb; + auto bin_dir = fbb.CreateString("/opt"); + auto work_dir = fbb.CreateString("/tmp"); + auto sandbox = buildDefaultSandbox(fbb); + auto deploy = fb::CreateDeploymentConfig( + fbb, 0.0001 /*ready_timeout*/, 1.0, 0, bin_dir, work_dir, 0, 0, sandbox); + + auto comp = buildDefaultComponent(fbb, "comp", buildDefaultComponentProperties(fbb), deploy); + auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{comp}); + + auto result = loadBuffer(buildConfigWithComponents(fbb, comps)); + + ASSERT_THAT(result.has_value(), IsFalse()); + EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::InvalidFormat)); +} + // ============================================================================ // Missing required field tests // ============================================================================ From 06d37941a85a70f2a6ab1b4cfb5d12f1e3c47c0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Fu=C3=9Fberger?= Date: Tue, 26 May 2026 15:11:12 +0200 Subject: [PATCH 23/26] Add [[nodiscard]] to config API --- src/launch_manager_daemon/config/include/config_loader.hpp | 4 ++-- .../config/include/flatbuffer_config_loader.hpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/launch_manager_daemon/config/include/config_loader.hpp b/src/launch_manager_daemon/config/include/config_loader.hpp index 6eafd58c5..dd13a0b2e 100644 --- a/src/launch_manager_daemon/config/include/config_loader.hpp +++ b/src/launch_manager_daemon/config/include/config_loader.hpp @@ -31,7 +31,7 @@ class IConfigLoader { public: /// @brief Error codes returned when configuration loading fails. - enum class Error : std::uint32_t + [[nodiscard]] enum class Error : std::uint32_t { FileNotFound, ///< The configuration file does not exist at the given path. InsufficientPermission, ///< The process lacks read permissions for the file. @@ -45,7 +45,7 @@ class IConfigLoader /// @brief Loads and parses the configuration file at @p path. /// @param path Filesystem path to the configuration file. /// @return A @ref Config object on success, or an @ref Error on failure. - virtual score::cpp::expected load(const score::filesystem::Path& path) = 0; + [[nodiscard]] virtual score::cpp::expected load(const score::filesystem::Path& path) = 0; }; } // namespace score::launch_manager::config diff --git a/src/launch_manager_daemon/config/include/flatbuffer_config_loader.hpp b/src/launch_manager_daemon/config/include/flatbuffer_config_loader.hpp index f23dfc5e2..2ecfd43e2 100644 --- a/src/launch_manager_daemon/config/include/flatbuffer_config_loader.hpp +++ b/src/launch_manager_daemon/config/include/flatbuffer_config_loader.hpp @@ -27,8 +27,8 @@ namespace score::launch_manager::config namespace details { -score::cpp::expected parseFlatbuffer(const std::vector& buffer); -IConfigLoader::Error mapOsError(const score::os::Error& error); +[[nodiscard]] score::cpp::expected parseFlatbuffer(const std::vector& buffer); +[[nodiscard]] IConfigLoader::Error mapOsError(const score::os::Error& error); } // namespace details @@ -52,7 +52,7 @@ template class FlatbufferConfigLoaderImpl : public IConfigLoader { public: - score::cpp::expected load(const score::filesystem::Path& path) override + [[nodiscard]] score::cpp::expected load(const score::filesystem::Path& path) override { auto buffer_result = BufferLoaderT::load(path); if (!buffer_result.has_value()) From 81712b346e4e649c32d36bdcebe30c6c6e6a6079 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Fu=C3=9Fberger?= Date: Tue, 26 May 2026 15:20:33 +0200 Subject: [PATCH 24/26] Change namespace of new code --- src/launch_manager_daemon/config/include/config.hpp | 4 ++-- src/launch_manager_daemon/config/include/config_loader.hpp | 4 ++-- .../config/include/flatbuffer_config_loader.hpp | 4 ++-- src/launch_manager_daemon/config/src/config.cpp | 4 ++-- src/launch_manager_daemon/config/src/config_UT.cpp | 4 ++-- .../config/src/flatbuffer_config_loader.cpp | 6 +++--- .../config/src/flatbuffer_config_loader_UT.cpp | 6 +++--- src/launch_manager_daemon/config/src/new_lm_flatcfg.fbs | 2 +- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/launch_manager_daemon/config/include/config.hpp b/src/launch_manager_daemon/config/include/config.hpp index c15ec6aec..2b4b6f4d6 100644 --- a/src/launch_manager_daemon/config/include/config.hpp +++ b/src/launch_manager_daemon/config/include/config.hpp @@ -20,7 +20,7 @@ #include #include -namespace score::launch_manager::config +namespace score::mw::launch_manager::configuration { enum class ApplicationType : uint8_t @@ -256,6 +256,6 @@ class ConfigBuilder std::optional watchdog_; }; -} // namespace score::launch_manager::config +} // namespace score::mw::launch_manager::configuration #endif // CONFIG_HPP diff --git a/src/launch_manager_daemon/config/include/config_loader.hpp b/src/launch_manager_daemon/config/include/config_loader.hpp index dd13a0b2e..b8cb1c202 100644 --- a/src/launch_manager_daemon/config/include/config_loader.hpp +++ b/src/launch_manager_daemon/config/include/config_loader.hpp @@ -20,7 +20,7 @@ #include #include -namespace score::launch_manager::config +namespace score::mw::launch_manager::configuration { /// @brief Abstract interface for loading Launch Manager configuration from a file. @@ -48,6 +48,6 @@ class IConfigLoader [[nodiscard]] virtual score::cpp::expected load(const score::filesystem::Path& path) = 0; }; -} // namespace score::launch_manager::config +} // namespace score::mw::launch_manager::configuration #endif // CONFIG_LOADER_HPP diff --git a/src/launch_manager_daemon/config/include/flatbuffer_config_loader.hpp b/src/launch_manager_daemon/config/include/flatbuffer_config_loader.hpp index 2ecfd43e2..51f615c0a 100644 --- a/src/launch_manager_daemon/config/include/flatbuffer_config_loader.hpp +++ b/src/launch_manager_daemon/config/include/flatbuffer_config_loader.hpp @@ -20,7 +20,7 @@ #include #include -namespace score::launch_manager::config +namespace score::mw::launch_manager::configuration { /// @brief Internal helpers for FlatBuffer config parsing. @@ -66,6 +66,6 @@ class FlatbufferConfigLoaderImpl : public IConfigLoader /// @brief Production-ready alias using the default buffer loader. using FlatbufferConfigLoader = FlatbufferConfigLoaderImpl<>; -} // namespace score::launch_manager::config +} // namespace score::mw::launch_manager::configuration #endif // FLATBUFFER_CONFIG_LOADER_HPP diff --git a/src/launch_manager_daemon/config/src/config.cpp b/src/launch_manager_daemon/config/src/config.cpp index 90139ea28..c026c5e7a 100644 --- a/src/launch_manager_daemon/config/src/config.cpp +++ b/src/launch_manager_daemon/config/src/config.cpp @@ -15,7 +15,7 @@ #include -namespace score::launch_manager::config +namespace score::mw::launch_manager::configuration { // --- EnvironmentVariable --- @@ -228,4 +228,4 @@ std::optional Config::takeWatchdog() return std::move(watchdog_); } -} // namespace score::launch_manager::config +} // namespace score::mw::launch_manager::configuration diff --git a/src/launch_manager_daemon/config/src/config_UT.cpp b/src/launch_manager_daemon/config/src/config_UT.cpp index 1f56de344..5591b12bd 100644 --- a/src/launch_manager_daemon/config/src/config_UT.cpp +++ b/src/launch_manager_daemon/config/src/config_UT.cpp @@ -19,7 +19,7 @@ #include #include -namespace score::launch_manager::config +namespace score::mw::launch_manager::configuration { namespace { @@ -257,4 +257,4 @@ TEST_F(EnvironmentTest, RangeBasedForLoopWorks) } } // namespace -} // namespace score::launch_manager::config +} // namespace score::mw::launch_manager::configuration diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp index fe6e95933..4d17f8022 100644 --- a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp @@ -25,10 +25,10 @@ #include #include -namespace score::launch_manager::config +namespace score::mw::launch_manager::configuration { -namespace fb = score::launch_manager::config::fb; +namespace fb = score::mw::launch_manager::configuration::fb; namespace { @@ -694,4 +694,4 @@ score::cpp::expected parseFlatbuffer(const std::ve } } // namespace details -} // namespace score::launch_manager::config +} // namespace score::mw::launch_manager::configuration diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp index 1ae7a7057..252599b53 100644 --- a/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp @@ -26,12 +26,12 @@ #include #include -namespace score::launch_manager::config +namespace score::mw::launch_manager::configuration { namespace { -namespace fb = score::launch_manager::config::fb; +namespace fb = score::mw::launch_manager::configuration::fb; using ::testing::Eq; using ::testing::IsFalse; @@ -1350,4 +1350,4 @@ TEST_F(FlatbufferConfigLoaderTest, UnsupportedSchedulingPolicyReturnsInvalidForm } } // namespace -} // namespace score::launch_manager::config +} // namespace score::mw::launch_manager::configuration diff --git a/src/launch_manager_daemon/config/src/new_lm_flatcfg.fbs b/src/launch_manager_daemon/config/src/new_lm_flatcfg.fbs index c491d4a10..e2fe8a60b 100644 --- a/src/launch_manager_daemon/config/src/new_lm_flatcfg.fbs +++ b/src/launch_manager_daemon/config/src/new_lm_flatcfg.fbs @@ -10,7 +10,7 @@ // Note: Without "= null", flatbuffer will return a default value and there is no way to know if it has been configured or not // - optional values are defined with "= null" and they are populated as std::optional in the code -namespace score.launch_manager.config.fb; +namespace score.mw.launch_manager.configuration.fb; // Specifies the level of integration between the component and the Launch Manager. enum ApplicationType : byte { From 0e6f0d82ef54831becd5326bea3c1f98c6cfd122 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Fu=C3=9Fberger?= Date: Tue, 26 May 2026 15:32:19 +0200 Subject: [PATCH 25/26] More doxygen documentation --- .../config/include/config.hpp | 37 ++++++++++++++++++- .../config/include/config_loader.hpp | 15 +++++--- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/launch_manager_daemon/config/include/config.hpp b/src/launch_manager_daemon/config/include/config.hpp index 2b4b6f4d6..49810d483 100644 --- a/src/launch_manager_daemon/config/include/config.hpp +++ b/src/launch_manager_daemon/config/include/config.hpp @@ -66,13 +66,18 @@ struct ComponentProperties std::optional ready_condition; }; +/// @brief A single environment variable class EnvironmentVariable { public: + /// @brief Constructs an environment variable from a key and value. EnvironmentVariable(std::string_view key, std::string_view value); + /// @brief Returns the key portion. std::string_view key() const; + /// @brief Returns the value portion. std::string_view value() const; + /// @brief Returns the full "key=value" as a null-terminated C string. const char* c_str() const; private: @@ -80,6 +85,10 @@ class EnvironmentVariable std::size_t key_length_; }; +/// @brief Stores configured environment variables. +/// +/// Provides read access via key/value iteration and a null-terminated pointer array +/// suitable for use with the @c execve system call via @ref envp(). class Environment { public: @@ -94,13 +103,19 @@ class Environment ~Environment() = default; + /// @brief Pre-allocates storage for @p count environment variables. void reserve(std::size_t count); + /// @brief Adds an environment variable with the given key and value. void add(std::string_view key, std::string_view value); + /// @brief Returns an iterator to the first environment variable. const_iterator begin() const; + /// @brief Returns an iterator past the last environment variable. const_iterator end() const; + /// @brief Returns the number of stored environment variables. std::size_t size() const; + /// @brief Returns a null-terminated array of "key=value" C strings for use with @c execve. char* const* envp() const; private: @@ -201,20 +216,30 @@ class Config Config(Config&&) = default; Config& operator=(Config&&) = default; - // Read access + /// @brief Returns the component configurations. const std::vector& components() const; + /// @brief Returns the run target configurations. const std::vector& runTargets() const; + /// @brief Returns the name of the initial run target. std::string_view initialRunTarget() const; + /// @brief Returns the fallback run target configuration. const FallbackRunTargetConfig& fallbackRunTarget() const; + /// @brief Returns the global alive supervision configuration. const AliveSupervisionConfig& aliveSupervision() const; + /// @brief Returns the watchdog configuration, if present. const std::optional& watchdog() const; - // Ownership transfer — source is left in a moved-from state after the call + /// @brief Moves out the component configurations. Source is left in a moved-from state. std::vector takeComponents(); + /// @brief Moves out the run target configurations. Source is left in a moved-from state. std::vector takeRunTargets(); + /// @brief Moves out the initial run target name. Source is left in a moved-from state. std::string takeInitialRunTarget(); + /// @brief Moves out the fallback run target configuration. Source is left in a moved-from state. FallbackRunTargetConfig takeFallbackRunTarget(); + /// @brief Moves out the alive supervision configuration. Source is left in a moved-from state. AliveSupervisionConfig takeAliveSupervision(); + /// @brief Moves out the watchdog configuration. Source is left in a moved-from state. std::optional takeWatchdog(); private: @@ -235,16 +260,24 @@ class Config std::optional watchdog_; }; +/// @brief Builder for constructing a @ref Config instance. class ConfigBuilder { public: + /// @brief Sets the component configurations. ConfigBuilder& setComponents(std::vector components); + /// @brief Sets the run target configurations. ConfigBuilder& setRunTargets(std::vector run_targets); + /// @brief Sets the initial run target name. ConfigBuilder& setInitialRunTarget(std::string initial_run_target); + /// @brief Sets the fallback run target configuration. ConfigBuilder& setFallbackRunTarget(FallbackRunTargetConfig fallback); + /// @brief Sets the global alive supervision configuration. ConfigBuilder& setAliveSupervision(AliveSupervisionConfig alive_supervision); + /// @brief Sets the watchdog configuration. ConfigBuilder& setWatchdog(WatchdogConfig watchdog); + /// @brief Builds and returns the @ref Config object. Config build(); private: diff --git a/src/launch_manager_daemon/config/include/config_loader.hpp b/src/launch_manager_daemon/config/include/config_loader.hpp index b8cb1c202..469444333 100644 --- a/src/launch_manager_daemon/config/include/config_loader.hpp +++ b/src/launch_manager_daemon/config/include/config_loader.hpp @@ -33,11 +33,16 @@ class IConfigLoader /// @brief Error codes returned when configuration loading fails. [[nodiscard]] enum class Error : std::uint32_t { - FileNotFound, ///< The configuration file does not exist at the given path. - InsufficientPermission, ///< The process lacks read permissions for the file. - InvalidFormat, ///< The file contents could not be parsed (malformed or missing required fields). - UnsupportedVersion, ///< The file uses a configuration schema version not supported by this loader. - GeneralError ///< Any other failure not covered by the above codes. + /// @brief The configuration file does not exist at the given path. + FileNotFound, + /// @brief The process lacks read permissions for the file. + InsufficientPermission, + /// @brief The file contents could not be parsed (malformed or missing required fields). + InvalidFormat, + /// @brief The file uses a configuration schema version not supported by this loader. + UnsupportedVersion, + /// @brief Any other failure not covered by the above codes. + GeneralError }; virtual ~IConfigLoader() = default; From 71a4f937a8a0adcdb8a409fef2cf2a60d0354876 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20Fu=C3=9Fberger?= Date: Tue, 26 May 2026 16:26:02 +0200 Subject: [PATCH 26/26] Make kExpectedSchemaVersion a public member --- .../include/score/lcm/control_client.h | 5 ++++ .../include/flatbuffer_config_loader.hpp | 5 +++- .../config/src/flatbuffer_config_loader.cpp | 3 +-- .../src/flatbuffer_config_loader_UT.cpp | 26 +++++++++---------- 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/src/control_client_lib/include/score/lcm/control_client.h b/src/control_client_lib/include/score/lcm/control_client.h index 020ed5f91..4dae87a16 100644 --- a/src/control_client_lib/include/score/lcm/control_client.h +++ b/src/control_client_lib/include/score/lcm/control_client.h @@ -60,6 +60,11 @@ class ControlClient final { /// @returns the new reference ControlClient& operator=(ControlClient&& rval) noexcept; + + void OnRunTargetTransitionFinished(std::function callback) noexcept; + void OnFallbackRunTargetActivated(std::function callback) noexcept; + std::string_view GetCurrentRunTarget() const noexcept; // when does the "current" RunTarget change? Is it when the request is sent, or when the transition is finished? + /// @brief Method to request activation of a specific Run Target. /// /// This method will request Launch Manager to activate a Run Target and return immediately. diff --git a/src/launch_manager_daemon/config/include/flatbuffer_config_loader.hpp b/src/launch_manager_daemon/config/include/flatbuffer_config_loader.hpp index 51f615c0a..3a51ff903 100644 --- a/src/launch_manager_daemon/config/include/flatbuffer_config_loader.hpp +++ b/src/launch_manager_daemon/config/include/flatbuffer_config_loader.hpp @@ -52,6 +52,9 @@ template class FlatbufferConfigLoaderImpl : public IConfigLoader { public: + /// @brief The configuration schema version supported by this loader. + static constexpr int32_t kExpectedSchemaVersion = 1; + [[nodiscard]] score::cpp::expected load(const score::filesystem::Path& path) override { auto buffer_result = BufferLoaderT::load(path); @@ -63,7 +66,7 @@ class FlatbufferConfigLoaderImpl : public IConfigLoader } }; -/// @brief Production-ready alias using the default buffer loader. +/// @brief Alias using the default buffer loader. using FlatbufferConfigLoader = FlatbufferConfigLoaderImpl<>; } // namespace score::mw::launch_manager::configuration diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp index 4d17f8022..907a364e0 100644 --- a/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader.cpp @@ -33,7 +33,6 @@ namespace fb = score::mw::launch_manager::configuration::fb; namespace { -constexpr int32_t kExpectedSchemaVersion = 1; constexpr double kSecondsToMilliseconds = 1000.0; score::cpp::expected secondsToMs(double seconds) @@ -611,7 +610,7 @@ score::cpp::expected parseFlatbuffer(const std::ve LM_LOG_ERROR() << "LaunchManagerConfig::schema_version is required but missing"; return score::cpp::make_unexpected(IConfigLoader::Error::InvalidFormat); } - if (*config->schema_version() != kExpectedSchemaVersion) + if (*config->schema_version() != FlatbufferConfigLoader::kExpectedSchemaVersion) { return score::cpp::make_unexpected(IConfigLoader::Error::UnsupportedVersion); } diff --git a/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp b/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp index 252599b53..6596c6e58 100644 --- a/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp +++ b/src/launch_manager_daemon/config/src/flatbuffer_config_loader_UT.cpp @@ -109,7 +109,7 @@ std::vector buildConfigWithComponents( auto alive_sup = fb::CreateAliveSupervision(fbb, 1.0 /*evaluation_cycle*/); auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, comps, rts, irt, fallback, alive_sup); + auto config = fb::CreateLaunchManagerConfig(fbb, FlatbufferConfigLoader::kExpectedSchemaVersion, comps, rts, irt, fallback, alive_sup); return finishBuffer(fbb, config); } @@ -121,7 +121,7 @@ std::vector buildConfigWithRunTargets( auto alive_sup = fb::CreateAliveSupervision(fbb, 1.0 /*evaluation_cycle*/); auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, comps, rts, irt, fallback, alive_sup); + auto config = fb::CreateLaunchManagerConfig(fbb, FlatbufferConfigLoader::kExpectedSchemaVersion, comps, rts, irt, fallback, alive_sup); return finishBuffer(fbb, config); } @@ -148,7 +148,7 @@ class FlatbufferConfigLoaderTest : public ::testing::Test MockBufferLoader::result_ = std::vector{}; } - std::vector buildMinimalConfig(int32_t schema_version = 1, const char* initial_run_target = "Startup") + std::vector buildMinimalConfig(int32_t schema_version = FlatbufferConfigLoader::kExpectedSchemaVersion, const char* initial_run_target = "Startup") { ::flatbuffers::FlatBufferBuilder fbb; auto irt = fbb.CreateString(initial_run_target); @@ -179,7 +179,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadMinimalConfig) { RecordProperty("Description", "Loads a minimal config with only required fields."); - auto result = loadBuffer(buildMinimalConfig(1, "Startup")); + auto result = loadBuffer(buildMinimalConfig(FlatbufferConfigLoader::kExpectedSchemaVersion, "Startup")); ASSERT_THAT(result.has_value(), IsTrue()); EXPECT_THAT(result->initialRunTarget(), Eq("Startup")); @@ -293,7 +293,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadFallbackRunTarget) auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, comps, rts, irt, fallback, alive_sup); + auto config = fb::CreateLaunchManagerConfig(fbb, FlatbufferConfigLoader::kExpectedSchemaVersion, comps, rts, irt, fallback, alive_sup); auto result = loadBuffer(finishBuffer(fbb, config)); @@ -316,7 +316,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadAliveSupervision) auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, comps, rts, irt, fallback, alive_sup); + auto config = fb::CreateLaunchManagerConfig(fbb, FlatbufferConfigLoader::kExpectedSchemaVersion, comps, rts, irt, fallback, alive_sup); auto result = loadBuffer(finishBuffer(fbb, config)); @@ -339,7 +339,7 @@ TEST_F(FlatbufferConfigLoaderTest, LoadWatchdog) auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, 1 /*schema_version*/, comps, rts, irt, fallback, alive_sup, watchdog); + auto config = fb::CreateLaunchManagerConfig(fbb, FlatbufferConfigLoader::kExpectedSchemaVersion, comps, rts, irt, fallback, alive_sup, watchdog); auto result = loadBuffer(finishBuffer(fbb, config)); @@ -733,7 +733,7 @@ TEST_F(FlatbufferConfigLoaderTest, WrongSchemaVersionReturnsUnsupportedVersion) { RecordProperty("Description", "A config with an unexpected schema_version returns UnsupportedVersion."); - auto result = loadBuffer(buildMinimalConfig(99, "Startup")); + auto result = loadBuffer(buildMinimalConfig(FlatbufferConfigLoader::kExpectedSchemaVersion + 1, "Startup")); ASSERT_THAT(result.has_value(), IsFalse()); EXPECT_THAT(result.error(), Eq(IConfigLoader::Error::UnsupportedVersion)); @@ -928,7 +928,7 @@ TEST_F(FlatbufferConfigLoaderTest, MissingEvaluationCycleReturnsInvalidFormat) auto alive_sup = fb::CreateAliveSupervision(fbb); auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); - auto config = fb::CreateLaunchManagerConfig(fbb, 1, comps, rts, irt, fallback, alive_sup); + auto config = fb::CreateLaunchManagerConfig(fbb, FlatbufferConfigLoader::kExpectedSchemaVersion, comps, rts, irt, fallback, alive_sup); auto result = loadBuffer(finishBuffer(fbb, config)); @@ -946,7 +946,7 @@ TEST_F(FlatbufferConfigLoaderTest, MissingFallbackTransitionTimeoutReturnsInvali auto alive_sup = fb::CreateAliveSupervision(fbb, 1.0); auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); - auto config = fb::CreateLaunchManagerConfig(fbb, 1, comps, rts, irt, fallback, alive_sup); + auto config = fb::CreateLaunchManagerConfig(fbb, FlatbufferConfigLoader::kExpectedSchemaVersion, comps, rts, irt, fallback, alive_sup); auto result = loadBuffer(finishBuffer(fbb, config)); @@ -1215,7 +1215,7 @@ TEST_F(FlatbufferConfigLoaderTest, MissingWatchdogMaxTimeoutReturnsInvalidFormat auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, 1, comps, rts, irt, fallback, alive_sup, watchdog); + auto config = fb::CreateLaunchManagerConfig(fbb, FlatbufferConfigLoader::kExpectedSchemaVersion, comps, rts, irt, fallback, alive_sup, watchdog); auto result = loadBuffer(finishBuffer(fbb, config)); @@ -1236,7 +1236,7 @@ TEST_F(FlatbufferConfigLoaderTest, MissingWatchdogDeactivateOnShutdownReturnsInv auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, 1, comps, rts, irt, fallback, alive_sup, watchdog); + auto config = fb::CreateLaunchManagerConfig(fbb, FlatbufferConfigLoader::kExpectedSchemaVersion, comps, rts, irt, fallback, alive_sup, watchdog); auto result = loadBuffer(finishBuffer(fbb, config)); @@ -1257,7 +1257,7 @@ TEST_F(FlatbufferConfigLoaderTest, MissingWatchdogRequireMagicCloseReturnsInvali auto comps = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); auto rts = fbb.CreateVector(std::vector<::flatbuffers::Offset>{}); auto irt = fbb.CreateString("Startup"); - auto config = fb::CreateLaunchManagerConfig(fbb, 1, comps, rts, irt, fallback, alive_sup, watchdog); + auto config = fb::CreateLaunchManagerConfig(fbb, FlatbufferConfigLoader::kExpectedSchemaVersion, comps, rts, irt, fallback, alive_sup, watchdog); auto result = loadBuffer(finishBuffer(fbb, config));