-
Notifications
You must be signed in to change notification settings - Fork 7
ci(apm): preload PoC basic testing improvements #2554
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,22 +1,32 @@ | ||
| use crate::common::config::{DEBUG_LOGGING_CONFIG, update_config, write_agent_local_config}; | ||
| use crate::common::file::write; | ||
| use crate::common::on_drop::CleanUp; | ||
| use crate::common::test::{TestResult, retry_panic}; | ||
| use crate::common::{InstallationArgs, RecipeData}; | ||
| use crate::{ | ||
| linux::{ | ||
| self, | ||
| install::{install_agent_control_from_recipe, tear_down_test}, | ||
| bash::exec_bash_command | ||
| }, | ||
| use crate::linux::{ | ||
| self, | ||
| bash::exec_bash_command, | ||
| install::{install_agent_control_from_recipe, tear_down_test}, | ||
| }; | ||
| use std::time::Duration; | ||
| use tracing::{debug, info}; | ||
|
|
||
| /// Directory where Agent Control loads dynamic (custom) agent type definitions. | ||
| const DYNAMIC_AGENT_TYPES_DIR: &str = "/etc/newrelic-agent-control/dynamic-agent-types"; | ||
|
|
||
| /// Expected package installation directory for the preload agent. | ||
| fn preload_package_dir() -> String { | ||
| format!( | ||
| "{}/packages/nr-preload/stored_packages/preload-agent", | ||
| linux::AGENT_CONTROL_DATA_DIR | ||
| ) | ||
| } | ||
|
|
||
| pub fn test_installation_with_preload_agent(args: InstallationArgs) { | ||
| let preload_version = args | ||
| .preload_version | ||
| .clone() | ||
| .expect("--preload-agent-version is required for this scenario"); | ||
|
|
||
| let staging = matches!(args.nr_region.to_lowercase().as_str(), "staging"); | ||
| .expect("--preload-version is required for this scenario"); | ||
|
|
||
| let recipe_data = RecipeData { | ||
| args, | ||
|
|
@@ -35,6 +45,40 @@ pub fn test_installation_with_preload_agent(args: InstallationArgs) { | |
|
|
||
| let preload_agent_id = "nr-preload"; | ||
|
|
||
| info!("Writing custom preload agent type definition"); | ||
| let custom_agent_type_path = format!("{DYNAMIC_AGENT_TYPES_DIR}/preload.yaml"); | ||
| let custom_agent_type = r#"namespace: newrelic | ||
| name: com.newrelic.preload | ||
| version: 0.1.0 | ||
| variables: | ||
| linux: | ||
| oci: | ||
| repository: | ||
| description: "Package repository name" | ||
| type: string | ||
| required: false | ||
| default: newrelic/preload-agent-artifacts | ||
| variants: | ||
| ac_config_field: "oci_repository_urls" | ||
| values: ["newrelic/preload-agent-artifacts"] | ||
| version: | ||
| description: "Agent version" | ||
| type: string | ||
| required: true | ||
| deployment: | ||
| linux: | ||
| packages: | ||
| preload-agent: | ||
| download: | ||
| oci: | ||
| repository: ${{nr-var:oci.repository}} | ||
| version: ${{nr-var:version}} | ||
| public_key_url: https://publickeys.newrelic.com/g/agent-control-oci/global/nrpreloadagent/jwks.json | ||
| "#; | ||
| exec_bash_command(&format!("mkdir -p {DYNAMIC_AGENT_TYPES_DIR}")) | ||
| .unwrap_or_else(|err| panic!("Failed to create dynamic agent types directory: {err}")); | ||
| write(&custom_agent_type_path, custom_agent_type); | ||
|
|
||
| info!("Setup Agent Control config"); | ||
| update_config( | ||
| linux::DEFAULT_AC_CONFIG_PATH, | ||
|
|
@@ -51,35 +95,47 @@ agents: | |
|
|
||
| write_agent_local_config( | ||
| &linux::local_config_path(preload_agent_id), | ||
| // Correct Config? | ||
| format! {r#" | ||
| fleet_id: alphanumeric_id # needed anymore? | ||
| apm_language: java | ||
| agent_version: 8.13.0 | ||
| application_names: | ||
| - my-app | ||
| - functions | ||
| - lib | ||
| - bin | ||
| new_relic_license_key: '{{{{NEW_RELIC_LICENSE_KEY}}}}' | ||
| staging: {staging} | ||
| version: {preload_version}"#}, | ||
| version: {preload_version}"#}, | ||
| ); | ||
|
|
||
| linux::service::restart_service(linux::SERVICE_NAME); | ||
|
|
||
| // ToDo update with actual path | ||
| let ld_preload_path = "path_to_ld_preload"; | ||
| let install_command = format!(r#"echo "{ld_preload_path}" >> /ec/ld.so.preload"#); | ||
| let output = exec_bash_command(&install_command) | ||
| .unwrap_or_else(|err| panic!("Editing /ec/ld.so.preload failed: {err}")); | ||
| debug!("echo output:\n{output}"); | ||
| info!("Waiting for preload OCI package to be downloaded and extracted"); | ||
| let package_dir = preload_package_dir(); | ||
| let retries = 60; | ||
| retry_panic( | ||
| retries, | ||
| Duration::from_secs(10), | ||
| "preload package download assertion", | ||
| || assert_preload_package_downloaded(&package_dir), | ||
| ); | ||
|
|
||
| linux::service::restart_service(linux::SERVICE_NAME); | ||
| info!("Searching for shared library inside extracted package"); | ||
| let find_so_command = format!(r#"find {package_dir} -type f -name "*.so" | head -n 1"#); | ||
| let so_path = exec_bash_command(&find_so_command) | ||
| .unwrap_or_else(|err| panic!("Failed to find shared library in package: {err}")); | ||
| let so_path = so_path.lines().last().unwrap_or("").trim().to_string(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also from Claude; 🔴 Bug: so_path extraction picks up the wrapper text, not the actual path test/e2e-runner/src/linux/scenarios/preload_agent.rs:115-122: let so_path = exec_bash_command(&find_so_command)...; exec_bash_command (test/e2e-runner/src/linux/bash.rs:22) does not return raw stdout — it returns a wrapped, multi-line string: The Stderr: line is always last, so so_path ends up as "Stderr:" (or empty after the colon depending on trim). The if so_path.is_empty() guard does not catch this, and the next step appends Stderr: to Fix options (pick one):
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changed the strategy used here: fec0466 |
||
| if so_path.is_empty() { | ||
| panic!("No .so file found in extracted preload package at {package_dir}"); | ||
| } | ||
| info!("Found shared library: {so_path}"); | ||
|
|
||
| let ls_command = format!("ls {ld_preload_path}"); | ||
| let output = exec_bash_command(&ls_command) | ||
| .unwrap_or_else(|err| panic!("Installation failed: {err}")); | ||
| debug!("ls output:\n{output}"); | ||
| info!("Installing shared library into /etc/ld.so.preload"); | ||
| let install_command = format!(r#"echo "{so_path}" >> /etc/ld.so.preload"#); | ||
| let output = exec_bash_command(&install_command) | ||
| .unwrap_or_else(|err| panic!("Editing /etc/ld.so.preload failed: {err}")); | ||
| debug!("Install output:\n{output}"); | ||
|
|
||
| info!("Test completed successfully"); | ||
| } | ||
|
|
||
| fn assert_preload_package_downloaded(package_dir: &str) -> TestResult<()> { | ||
| let output = exec_bash_command(&format!("ls -d {package_dir}"))?; | ||
| if output.contains("No such file") || output.contains("cannot access") { | ||
| return Err(format!("Preload package directory not found yet at {package_dir}").into()); | ||
| } | ||
| let listing = exec_bash_command(&format!("ls -la {package_dir}"))?; | ||
| debug!("Package listing:\n{listing}"); | ||
| Ok(()) | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Claude found this issue:
🔴 Bug: ${{ ... }} won't be substituted by Agent Control
test/e2e-runner/src/linux/scenarios/preload_agent.rs:50-77 — the YAML is a plain r#"..."# raw string, not a format! template, so the doubled braces are not escapes — they end up literally in the file:
repository: ${{nr-var:oci.repository}}
version: ${{nr-var:version}}
Compare with agent-control/tests/on_host/scenarios/oci_auth.rs:43-54, where ${{...}} is inside format!(...) and correctly resolves to ${...}. AC's template engine expects the single-brace form
(${nr-var:version}), so the inlined agent type will fail to resolve version and the OCI download won't get a valid tag.
Fix: use single braces (${nr-var:...}) since this is a raw string, or wrap the literal in format! if you want to keep the doubled form for visual consistency with the other tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed e91cd32