Skip to content

Commit 3918577

Browse files
apollo_integration_tests,apollo_node_config: load integration-test node config via native format
Make the integration-test harness emit a nested native config artifact plus a secrets file and boot the node with --config_format native (two --config_file paths: nested base first, flat secrets second), instead of the legacy preset single-file path. Adds as_native_value/dump_native_config_file alongside the retained preset as_value, a {} secrets file, and node_config_paths() returning [base, secrets]; both spawn_run_node call sites pass the two-file vector. This is the prerequisite that lets the integration suite exercise the native load path before the preset path is torn down. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 6d40587 commit 3918577

4 files changed

Lines changed: 40 additions & 9 deletions

File tree

crates/apollo_integration_tests/src/executable_setup.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use tempfile::{tempdir, TempDir};
1111
use tokio::fs::create_dir_all;
1212

1313
const NODE_CONFIG_CHANGES_FILE_PATH: &str = "node_integration_test_config_changes.json";
14+
const NODE_SECRETS_FILE_PATH: &str = "node_integration_test_secrets.json";
1415

1516
#[derive(Debug, Clone)]
1617
pub struct NodeExecutableId {
@@ -48,8 +49,10 @@ pub struct ExecutableSetup {
4849
pub node_executable_id: NodeExecutableId,
4950
// Client for checking liveness of the sequencer node.
5051
pub monitoring_client: MonitoringClient,
51-
// Path to the node configuration file.
52+
// Path to the nested native base config file (consumed first by the native loader).
5253
pub node_config_path: PathBuf,
54+
// Path to the (empty) secrets file overlaid onto the base by the native loader.
55+
pub node_secrets_path: PathBuf,
5356
// Config.
5457
pub base_app_config: DeploymentBaseAppConfig,
5558
// Handles for the config files, maintained so the files are not deleted. Since
@@ -84,17 +87,29 @@ impl ExecutableSetup {
8487
let monitoring_client = MonitoringClient::new(SocketAddr::new(*ip, *port));
8588

8689
let config_path = node_config_dir.join(NODE_CONFIG_CHANGES_FILE_PATH);
87-
base_app_config.dump_config_file(&config_path);
90+
base_app_config.dump_native_config_file(&config_path);
91+
92+
// The native loader requires a secrets file overlaid onto the base. The harness carries no
93+
// secrets, so emit an empty JSON object.
94+
let secrets_path = node_config_dir.join(NODE_SECRETS_FILE_PATH);
95+
std::fs::write(&secrets_path, "{}").expect("Should be able to write secrets file");
8896

8997
Self {
9098
node_executable_id,
9199
monitoring_client,
92100
base_app_config,
93101
node_config_dir_handle,
94102
node_config_path: config_path,
103+
node_secrets_path: secrets_path,
95104
}
96105
}
97106

107+
/// Config files passed to the native loader, base first then secrets, matching the
108+
/// `[base, secret]` arity expected by `load_native`.
109+
pub(crate) fn node_config_paths(&self) -> Vec<PathBuf> {
110+
vec![self.node_config_path.clone(), self.node_secrets_path.clone()]
111+
}
112+
98113
pub fn modify_config<F>(&mut self, modify_config_fn: F)
99114
where
100115
F: Fn(&mut SequencerNodeConfig),
@@ -115,8 +130,8 @@ impl ExecutableSetup {
115130
self.base_app_config.get_config()
116131
}
117132

118-
/// Creates a config file for the sequencer node for an integration test.
133+
/// Re-emits the native base config file for the sequencer node after a config change.
119134
pub fn dump_config_file_changes(&self) {
120-
self.base_app_config.dump_config_file(&self.node_config_path);
135+
self.base_app_config.dump_native_config_file(&self.node_config_path);
121136
}
122137
}

crates/apollo_integration_tests/src/integration_test_manager.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ impl NodeSetup {
281281
pub fn run_service(&self, service: NodeService) -> AbortOnDropHandle<()> {
282282
let executable_setup = self.get_executable_by_service(service);
283283
spawn_run_node(
284-
vec![executable_setup.node_config_path.clone()],
284+
executable_setup.node_config_paths(),
285285
executable_setup.node_executable_id.clone().into(),
286286
)
287287
}
@@ -294,7 +294,7 @@ impl NodeSetup {
294294
(
295295
*service,
296296
spawn_run_node(
297-
vec![executable.node_config_path.clone()],
297+
executable.node_config_paths(),
298298
executable.node_executable_id.clone().into(),
299299
),
300300
)

crates/apollo_node/src/test_utils/node_runner.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,9 @@ async fn spawn_node_child_process(
9191
info!("Getting the node executable.");
9292
let node_executable = get_node_executable_path();
9393

94-
// Interpret the config files with the legacy flat-preset loader (the node's default), kept
95-
// explicit so this stays a clear switch point if/when tests move to "native" loading.
96-
let config_file_args: Vec<String> = ["--config_format".to_string(), "preset".to_string()]
94+
// Interpret the config files with the native loader: the paths are a nested base config
95+
// followed by a flat secrets file, matching `load_native`'s `[base, secret]` arity.
96+
let config_file_args: Vec<String> = ["--config_format".to_string(), "native".to_string()]
9797
.into_iter()
9898
.chain(node_config_paths.into_iter().flat_map(|path| {
9999
let path_str = path.to_str().expect("Invalid path").to_string();

crates/apollo_node_config/src/config_utils.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,13 @@ impl DeploymentBaseAppConfig {
196196
preset
197197
}
198198

199+
/// Returns the nested config as JSON, matching the `SequencerNodeConfig` field hierarchy.
200+
/// This is the artifact consumed by the `ConfigFormat::Native` loader (as the base config),
201+
/// in contrast to the flat preset produced by `as_value`.
202+
pub fn as_native_value(&self) -> Value {
203+
serde_json::to_value(&self.config).expect("Should be able to serialize config to value")
204+
}
205+
199206
// TODO(Tsabary): unify path types throughout.
200207
pub fn dump_config_file(&self, config_path: &Path) {
201208
let value = self.as_value();
@@ -204,6 +211,15 @@ impl DeploymentBaseAppConfig {
204211
config_path.to_str().expect("Should be able to convert path to string"),
205212
);
206213
}
214+
215+
/// Dumps the nested native base config (see `as_native_value`) to `config_path`.
216+
pub fn dump_native_config_file(&self, config_path: &Path) {
217+
let value = self.as_native_value();
218+
serialize_to_file(
219+
&value,
220+
config_path.to_str().expect("Should be able to convert path to string"),
221+
);
222+
}
207223
}
208224

209225
pub fn load_and_validate_config(

0 commit comments

Comments
 (0)