From ba120205e94bb98085b926c4ea4558b508747293 Mon Sep 17 00:00:00 2001 From: Jeff Cheng <83052155+jeffreyc-splunk@users.noreply.github.com> Date: Fri, 1 Sep 2023 17:05:50 -0400 Subject: [PATCH] Add tests for express instrumentation (#3566) --- .../images/deb/Dockerfile.debian-bullseye | 5 + .../images/deb/Dockerfile.debian-buster | 5 + .../images/deb/Dockerfile.debian-stretch | 5 + .../images/deb/Dockerfile.ubuntu-bionic | 5 + .../images/deb/Dockerfile.ubuntu-focal | 5 + .../images/deb/Dockerfile.ubuntu-jammy | 5 + .../images/deb/Dockerfile.ubuntu-xenial | 5 + .../images/rpm/Dockerfile.amazonlinux-2 | 5 + .../images/rpm/Dockerfile.amazonlinux-2023 | 5 + .../images/rpm/Dockerfile.centos-7 | 5 + .../images/rpm/Dockerfile.centos-8 | 5 + .../images/rpm/Dockerfile.centos-9 | 5 + .../images/rpm/Dockerfile.opensuse-12 | 5 + .../images/rpm/Dockerfile.opensuse-15 | 5 + .../images/rpm/Dockerfile.oraclelinux-7 | 5 + .../images/rpm/Dockerfile.oraclelinux-8 | 5 + .../images/rpm/Dockerfile.oraclelinux-9 | 5 + .../instrumentation/instrumentation_test.py | 301 +++++++++++++----- .../instrumentation/libsplunk-java-test.conf | 4 +- .../instrumentation/libsplunk-node-test.conf | 6 + .../tests/instrumentation/setup-express.sh | 54 ++++ ...stemd-test.conf => systemd-java-test.conf} | 4 +- .../instrumentation/systemd-node-test.conf | 6 + 23 files changed, 377 insertions(+), 83 deletions(-) create mode 100644 internal/buildscripts/packaging/tests/instrumentation/libsplunk-node-test.conf create mode 100644 internal/buildscripts/packaging/tests/instrumentation/setup-express.sh rename internal/buildscripts/packaging/tests/instrumentation/{systemd-test.conf => systemd-java-test.conf} (66%) create mode 100644 internal/buildscripts/packaging/tests/instrumentation/systemd-node-test.conf diff --git a/internal/buildscripts/packaging/tests/instrumentation/images/deb/Dockerfile.debian-bullseye b/internal/buildscripts/packaging/tests/instrumentation/images/deb/Dockerfile.debian-bullseye index 8530d48181..b33257b79a 100644 --- a/internal/buildscripts/packaging/tests/instrumentation/images/deb/Dockerfile.debian-bullseye +++ b/internal/buildscripts/packaging/tests/instrumentation/images/deb/Dockerfile.debian-bullseye @@ -23,6 +23,11 @@ COPY --from=tomcat /opt/java /opt/java COPY instrumentation/setup-tomcat.sh /opt/ RUN bash /opt/setup-tomcat.sh +ARG NODE_VERSION=v16 +ENV NODE_PATH=/opt/express/node_modules +COPY instrumentation/setup-express.sh /opt +RUN bash /opt/setup-express.sh + RUN systemctl set-default multi-user.target ENV init /lib/systemd/systemd diff --git a/internal/buildscripts/packaging/tests/instrumentation/images/deb/Dockerfile.debian-buster b/internal/buildscripts/packaging/tests/instrumentation/images/deb/Dockerfile.debian-buster index 05c8048a59..fbcabe2929 100644 --- a/internal/buildscripts/packaging/tests/instrumentation/images/deb/Dockerfile.debian-buster +++ b/internal/buildscripts/packaging/tests/instrumentation/images/deb/Dockerfile.debian-buster @@ -23,6 +23,11 @@ COPY --from=tomcat /opt/java /opt/java COPY instrumentation/setup-tomcat.sh /opt/ RUN bash /opt/setup-tomcat.sh +ARG NODE_VERSION=v16 +ENV NODE_PATH=/opt/express/node_modules +COPY instrumentation/setup-express.sh /opt +RUN bash /opt/setup-express.sh + RUN systemctl set-default multi-user.target ENV init /lib/systemd/systemd diff --git a/internal/buildscripts/packaging/tests/instrumentation/images/deb/Dockerfile.debian-stretch b/internal/buildscripts/packaging/tests/instrumentation/images/deb/Dockerfile.debian-stretch index f59f75bc35..ddc5fcafb8 100644 --- a/internal/buildscripts/packaging/tests/instrumentation/images/deb/Dockerfile.debian-stretch +++ b/internal/buildscripts/packaging/tests/instrumentation/images/deb/Dockerfile.debian-stretch @@ -26,6 +26,11 @@ COPY --from=tomcat /opt/java /opt/java COPY instrumentation/setup-tomcat.sh /opt/ RUN bash /opt/setup-tomcat.sh +ARG NODE_VERSION=v14 +ENV NODE_PATH=/opt/express/node_modules +COPY instrumentation/setup-express.sh /opt +RUN bash /opt/setup-express.sh + RUN systemctl set-default multi-user.target ENV init /lib/systemd/systemd diff --git a/internal/buildscripts/packaging/tests/instrumentation/images/deb/Dockerfile.ubuntu-bionic b/internal/buildscripts/packaging/tests/instrumentation/images/deb/Dockerfile.ubuntu-bionic index 460acf9d7a..aa28c546bf 100644 --- a/internal/buildscripts/packaging/tests/instrumentation/images/deb/Dockerfile.ubuntu-bionic +++ b/internal/buildscripts/packaging/tests/instrumentation/images/deb/Dockerfile.ubuntu-bionic @@ -23,6 +23,11 @@ COPY --from=tomcat /opt/java /opt/java COPY instrumentation/setup-tomcat.sh /opt/ RUN bash /opt/setup-tomcat.sh +ARG NODE_VERSION=v16 +ENV NODE_PATH=/opt/express/node_modules +COPY instrumentation/setup-express.sh /opt +RUN bash /opt/setup-express.sh + RUN systemctl set-default multi-user.target ENV init /lib/systemd/systemd diff --git a/internal/buildscripts/packaging/tests/instrumentation/images/deb/Dockerfile.ubuntu-focal b/internal/buildscripts/packaging/tests/instrumentation/images/deb/Dockerfile.ubuntu-focal index f817229087..42ff230e64 100644 --- a/internal/buildscripts/packaging/tests/instrumentation/images/deb/Dockerfile.ubuntu-focal +++ b/internal/buildscripts/packaging/tests/instrumentation/images/deb/Dockerfile.ubuntu-focal @@ -23,6 +23,11 @@ COPY --from=tomcat /opt/java /opt/java COPY instrumentation/setup-tomcat.sh /opt/ RUN bash /opt/setup-tomcat.sh +ARG NODE_VERSION=v16 +ENV NODE_PATH=/opt/express/node_modules +COPY instrumentation/setup-express.sh /opt +RUN bash /opt/setup-express.sh + RUN systemctl set-default multi-user.target ENV init /lib/systemd/systemd diff --git a/internal/buildscripts/packaging/tests/instrumentation/images/deb/Dockerfile.ubuntu-jammy b/internal/buildscripts/packaging/tests/instrumentation/images/deb/Dockerfile.ubuntu-jammy index a4fd8f72bc..8025db7dbb 100644 --- a/internal/buildscripts/packaging/tests/instrumentation/images/deb/Dockerfile.ubuntu-jammy +++ b/internal/buildscripts/packaging/tests/instrumentation/images/deb/Dockerfile.ubuntu-jammy @@ -23,6 +23,11 @@ COPY --from=tomcat /opt/java /opt/java COPY instrumentation/setup-tomcat.sh /opt/ RUN bash /opt/setup-tomcat.sh +ARG NODE_VERSION=v16 +ENV NODE_PATH=/opt/express/node_modules +COPY instrumentation/setup-express.sh /opt +RUN bash /opt/setup-express.sh + RUN systemctl set-default multi-user.target ENV init /lib/systemd/systemd diff --git a/internal/buildscripts/packaging/tests/instrumentation/images/deb/Dockerfile.ubuntu-xenial b/internal/buildscripts/packaging/tests/instrumentation/images/deb/Dockerfile.ubuntu-xenial index 8629c6f1a1..b88c42849d 100644 --- a/internal/buildscripts/packaging/tests/instrumentation/images/deb/Dockerfile.ubuntu-xenial +++ b/internal/buildscripts/packaging/tests/instrumentation/images/deb/Dockerfile.ubuntu-xenial @@ -23,6 +23,11 @@ COPY --from=tomcat /opt/java /opt/java COPY instrumentation/setup-tomcat.sh /opt/ RUN bash /opt/setup-tomcat.sh +ARG NODE_VERSION=v16 +ENV NODE_PATH=/opt/express/node_modules +COPY instrumentation/setup-express.sh /opt +RUN bash /opt/setup-express.sh + RUN systemctl set-default multi-user.target ENV init /lib/systemd/systemd diff --git a/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.amazonlinux-2 b/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.amazonlinux-2 index 4d73204d67..cd71cf7bfe 100644 --- a/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.amazonlinux-2 +++ b/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.amazonlinux-2 @@ -22,6 +22,11 @@ COPY --from=tomcat /opt/java /opt/java COPY instrumentation/setup-tomcat.sh /opt/ RUN bash /opt/setup-tomcat.sh +ARG NODE_VERSION=v16 +ENV NODE_PATH=/opt/express/node_modules +COPY instrumentation/setup-express.sh /opt +RUN bash /opt/setup-express.sh + VOLUME [ "/sys/fs/cgroup" ] CMD ["/usr/sbin/init"] diff --git a/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.amazonlinux-2023 b/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.amazonlinux-2023 index b21df31625..1a5fb6e431 100644 --- a/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.amazonlinux-2023 +++ b/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.amazonlinux-2023 @@ -22,6 +22,11 @@ COPY --from=tomcat /opt/java /opt/java COPY instrumentation/setup-tomcat.sh /opt/ RUN bash /opt/setup-tomcat.sh +ARG NODE_VERSION=v16 +ENV NODE_PATH=/opt/express/node_modules +COPY instrumentation/setup-express.sh /opt +RUN bash /opt/setup-express.sh + VOLUME [ "/sys/fs/cgroup" ] CMD ["/usr/sbin/init"] diff --git a/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.centos-7 b/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.centos-7 index ee582c7aef..70a13aee46 100644 --- a/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.centos-7 +++ b/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.centos-7 @@ -23,6 +23,11 @@ COPY --from=tomcat /opt/java /opt/java COPY instrumentation/setup-tomcat.sh /opt/ RUN bash /opt/setup-tomcat.sh +ARG NODE_VERSION=v14 +ENV NODE_PATH=/opt/express/node_modules +COPY instrumentation/setup-express.sh /opt +RUN bash /opt/setup-express.sh + VOLUME [ "/sys/fs/cgroup" ] CMD ["/usr/sbin/init"] diff --git a/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.centos-8 b/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.centos-8 index 8984412744..865908e292 100644 --- a/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.centos-8 +++ b/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.centos-8 @@ -23,6 +23,11 @@ COPY --from=tomcat /opt/java /opt/java COPY instrumentation/setup-tomcat.sh /opt/ RUN bash /opt/setup-tomcat.sh +ARG NODE_VERSION=v16 +ENV NODE_PATH=/opt/express/node_modules +COPY instrumentation/setup-express.sh /opt +RUN bash /opt/setup-express.sh + VOLUME [ "/sys/fs/cgroup" ] CMD ["/usr/sbin/init"] diff --git a/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.centos-9 b/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.centos-9 index b30564af9e..77b48b9cf3 100644 --- a/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.centos-9 +++ b/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.centos-9 @@ -24,6 +24,11 @@ COPY --from=tomcat /opt/java /opt/java COPY instrumentation/setup-tomcat.sh /opt/ RUN bash /opt/setup-tomcat.sh +ARG NODE_VERSION=v16 +ENV NODE_PATH=/opt/express/node_modules +COPY instrumentation/setup-express.sh /opt +RUN bash /opt/setup-express.sh + VOLUME [ "/sys/fs/cgroup" ] CMD ["/usr/sbin/init"] diff --git a/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.opensuse-12 b/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.opensuse-12 index e3e2bf0818..ca995191e2 100644 --- a/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.opensuse-12 +++ b/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.opensuse-12 @@ -24,6 +24,11 @@ COPY --from=tomcat /opt/java /opt/java COPY instrumentation/setup-tomcat.sh /opt/ RUN bash /opt/setup-tomcat.sh +ARG NODE_VERSION=v16 +ENV NODE_PATH=/opt/express/node_modules +COPY instrumentation/setup-express.sh /opt +RUN bash /opt/setup-express.sh + VOLUME [ "/sys/fs/cgroup" ] CMD ["/sbin/init"] diff --git a/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.opensuse-15 b/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.opensuse-15 index ffd5264656..8568d5499d 100644 --- a/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.opensuse-15 +++ b/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.opensuse-15 @@ -22,6 +22,11 @@ COPY --from=tomcat /opt/java /opt/java COPY instrumentation/setup-tomcat.sh /opt/ RUN bash /opt/setup-tomcat.sh +ARG NODE_VERSION=v16 +ENV NODE_PATH=/opt/express/node_modules +COPY instrumentation/setup-express.sh /opt +RUN bash /opt/setup-express.sh + VOLUME [ "/sys/fs/cgroup" ] CMD ["/sbin/init"] diff --git a/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.oraclelinux-7 b/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.oraclelinux-7 index b303c1df36..2c1ddbf18b 100644 --- a/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.oraclelinux-7 +++ b/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.oraclelinux-7 @@ -22,6 +22,11 @@ COPY --from=tomcat /opt/java /opt/java COPY instrumentation/setup-tomcat.sh /opt/ RUN bash /opt/setup-tomcat.sh +ARG NODE_VERSION=v14 +ENV NODE_PATH=/opt/express/node_modules +COPY instrumentation/setup-express.sh /opt +RUN bash /opt/setup-express.sh + VOLUME [ "/sys/fs/cgroup" ] CMD ["/usr/sbin/init"] diff --git a/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.oraclelinux-8 b/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.oraclelinux-8 index 358209afa1..a935096bd8 100644 --- a/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.oraclelinux-8 +++ b/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.oraclelinux-8 @@ -22,6 +22,11 @@ COPY --from=tomcat /opt/java /opt/java COPY instrumentation/setup-tomcat.sh /opt/ RUN bash /opt/setup-tomcat.sh +ARG NODE_VERSION=v16 +ENV NODE_PATH=/opt/express/node_modules +COPY instrumentation/setup-express.sh /opt +RUN bash /opt/setup-express.sh + VOLUME [ "/sys/fs/cgroup" ] CMD ["/usr/sbin/init"] diff --git a/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.oraclelinux-9 b/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.oraclelinux-9 index c2ab85152d..4de6b7c6c2 100644 --- a/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.oraclelinux-9 +++ b/internal/buildscripts/packaging/tests/instrumentation/images/rpm/Dockerfile.oraclelinux-9 @@ -22,6 +22,11 @@ COPY --from=tomcat /opt/java /opt/java COPY instrumentation/setup-tomcat.sh /opt/ RUN bash /opt/setup-tomcat.sh +ARG NODE_VERSION=v16 +ENV NODE_PATH=/opt/express/node_modules +COPY instrumentation/setup-express.sh /opt +RUN bash /opt/setup-express.sh + VOLUME [ "/sys/fs/cgroup" ] CMD ["/usr/sbin/init"] diff --git a/internal/buildscripts/packaging/tests/instrumentation/instrumentation_test.py b/internal/buildscripts/packaging/tests/instrumentation/instrumentation_test.py index 701f6e7dbf..c7de14909a 100644 --- a/internal/buildscripts/packaging/tests/instrumentation/instrumentation_test.py +++ b/internal/buildscripts/packaging/tests/instrumentation/instrumentation_test.py @@ -41,19 +41,23 @@ OTELCOL_BIN_DIR = REPO_DIR / "bin" INSTALLER_PATH = REPO_DIR / "internal" / "buildscripts" / "packaging" / "installer" / "install.sh" COLLECTOR_CONFIG_PATH = TESTS_DIR / "instrumentation" / "config.yaml" -JAVA_AGENT_PATH = "/usr/lib/splunk-instrumentation/splunk-otel-javaagent.jar" -NODE_AGENT_PATH = "/usr/lib/splunk-instrumentation/splunk-otel-js.tgz" PKG_NAME = "splunk-otel-auto-instrumentation" LIBSPLUNK_PATH = "/usr/lib/splunk-instrumentation/libsplunk.so" +PRELOAD_PATH = "/etc/ld.so.preload" +SYSTEMD_CONF_DIR = "/usr/lib/systemd/system.conf.d" + +JAVA_AGENT_PATH = "/usr/lib/splunk-instrumentation/splunk-otel-javaagent.jar" JAVA_CONFIG_PATH = "/etc/splunk/zeroconfig_java.conf" CUSTOM_JAVA_CONFIG_PATH = TESTS_DIR / "instrumentation" / "libsplunk-java-test.conf" -NODE_CONFIG_PATH = "/etc/splunk/zeroconfig_node.conf" SAMPLE_JAVA_SYSTEMD_CONF_PATH = "/usr/lib/splunk-instrumentation/examples/systemd/00-splunk-otel-javaagent.conf" +CUSTOM_JAVA_SYSTEMD_CONF_PATH = TESTS_DIR / "instrumentation" / "systemd-java-test.conf" + +NODE_AGENT_PATH = "/usr/lib/splunk-instrumentation/splunk-otel-js.tgz" +NODE_CONFIG_PATH = "/etc/splunk/zeroconfig_node.conf" +CUSTOM_NODE_CONFIG_PATH = TESTS_DIR / "instrumentation" / "libsplunk-node-test.conf" SAMPLE_NODE_SYSTEMD_CONF_PATH = "/usr/lib/splunk-instrumentation/examples/systemd/00-splunk-otel-js.conf" -CUSTOM_SYSTEMD_CONF_PATH = TESTS_DIR / "instrumentation" / "systemd-test.conf" -SYSTEMD_CONF_DIR = "/usr/lib/systemd/system.conf.d" -PRELOAD_PATH = "/etc/ld.so.preload" +CUSTOM_NODE_SYSTEMD_CONF_PATH = TESTS_DIR / "instrumentation" / "systemd-node-test.conf" INSTALLED_FILES = [ JAVA_AGENT_PATH, @@ -65,6 +69,19 @@ SAMPLE_NODE_SYSTEMD_CONF_PATH, ] +TOMCAT_PIDFILE = "/usr/local/tomcat/temp/tomcat.pid" +TOMCAT_ENV = { + "JAVA_HOME": "/opt/java/openjdk", + "CATALINA_PID": TOMCAT_PIDFILE, + "CATALINA_HOME": "/usr/local/tomcat", + "CATALINA_BASE": "/usr/local/tomcat", + "CATALINA_OPTS": "-Xms512M -Xmx1024M -server -XX:+UseParallelGC", + "JAVA_OPTS": "-Djava.awt.headless=true", +} + +EXPRESS_PIDFILE = "/opt/express/express.pid" + + def get_dockerfile(distro): if distro in DEB_DISTROS: return IMAGES_DIR / "deb" / f"Dockerfile.{distro}" @@ -117,69 +134,87 @@ def verify_preload(container, line, exists=True): assert not match, f"'{line}' found in {PRELOAD_PATH}" -def verify_tomcat_instrumentation(container, otelcol_path, test_case, source, attributes=[]): - if source == "systemd": - if otelcol_path is None: - container.restart() - wait_for_container_cmd(container, "systemctl show-environment", timeout=30) - wait_for_container_cmd(container, "systemctl status splunk-otel-collector", timeout=30) - # get the output stream for the collector from journald - stream = container.exec_run("journalctl -u splunk-otel-collector -f", stream=True).output - else: - run_container_cmd(container, f"mkdir -p {SYSTEMD_CONF_DIR}") - run_container_cmd(container, f"cp {SAMPLE_JAVA_SYSTEMD_CONF_PATH} {SYSTEMD_CONF_DIR}/") - if test_case == "custom": - copy_file_into_container(container, CUSTOM_SYSTEMD_CONF_PATH, - f"{SYSTEMD_CONF_DIR}/99-systemd-test.conf") - container.restart() - wait_for_container_cmd(container, "systemctl show-environment", timeout=30) - # start the collector and get the output stream - stream = container.exec_run(f"{otelcol_path} --config=/test/config.yaml", stream=True).output - print("Starting the tomcat systemd service ...") - run_container_cmd(container, "systemctl start tomcat") +def start_app(container, app, systemd, timeout=300): + if systemd: + print(f"Starting the {app} systemd service ...") + run_container_cmd(container, f"systemctl start {app}") else: - if otelcol_path is None: - wait_for_container_cmd(container, "systemctl status splunk-otel-collector", timeout=30) - # get the output stream for the collector from journald - stream = container.exec_run("journalctl -u splunk-otel-collector -f", stream=True).output - else: - run_container_cmd(container, - "sh -c 'echo /usr/lib/splunk-instrumentation/libsplunk.so > /etc/ld.so.preload'") - if test_case == "custom": - # overwrite the default instrumentation.conf with the custom one for testing - copy_file_into_container(container, CUSTOM_JAVA_CONFIG_PATH, JAVA_CONFIG_PATH) - # start the collector and get the output stream - stream = container.exec_run(f"{otelcol_path} --config=/test/config.yaml", stream=True).output - print("Starting tomcat from a shell ...") - tomcat_env = { - "JAVA_HOME": "/opt/java/openjdk", - "CATALINA_PID": "/usr/local/tomcat/temp/tomcat.pid", - "CATALINA_HOME": "/usr/local/tomcat", - "CATALINA_BASE": "/usr/local/tomcat", - "CATALINA_OPTS": "-Xms512M -Xmx1024M -server -XX:+UseParallelGC", - "JAVA_OPTS": "-Djava.awt.headless=true", - } - run_container_cmd(container, "bash -c /usr/local/tomcat/bin/startup.sh", env=tomcat_env) - - print("Waiting for http://127.0.0.1:8080/sample ...") - wait_for_container_cmd(container, "curl -sSL http://127.0.0.1:8080/sample", timeout=300) + print(f"Starting {app} from a shell ...") + if app == "tomcat": + run_container_cmd(container, "bash -c /usr/local/tomcat/bin/startup.sh", env=TOMCAT_ENV) + elif app == "express": + run_container_cmd(container, f"bash -l -c 'node /opt/express/app.js & echo $! > {EXPRESS_PIDFILE}'") + + if app == "tomcat": + print("Waiting for http://127.0.0.1:8080/sample ...") + wait_for_container_cmd(container, "curl -sSL http://127.0.0.1:8080/sample", timeout=timeout) + elif app == "express": + print("Waiting for http://127.0.0.1:3000 ...") + wait_for_container_cmd(container, "curl -sSL http://127.0.0.1:3000", timeout=timeout) + + +def stop_app(container, app): + run_container_cmd(container, f"systemctl stop {app}") + + pidfile = TOMCAT_PIDFILE if app == "tomcat" else EXPRESS_PIDFILE + if container_file_exists(container, pidfile): + if app == "tomcat": + run_container_cmd(container, "bash -c /usr/local/tomcat/bin/shutdown.sh", env=TOMCAT_ENV) + elif app == "express": + run_container_cmd(container, f"bash -c 'kill -TERM `cat {pidfile}`'") + run_container_cmd(container, f"rm -f {pidfile}") + + +def verify_attributes(stream, attributes, timeout=300): + found = {} + for key, value in attributes.items(): + found[key] = False if value else True - # check the collector output stream for attributes start_time = time.time() for output in TimeoutIterator(stream, timeout=10, sentinel=None): if output: output = output.decode("utf-8").rstrip() print(output) - for attr in attributes: - if attr["found"]: + for key, value in attributes.items(): + if found[key]: continue - if re.search(f"{attr['key']}: {attr['value']}", output, re.MULTILINE): - attr["found"] = True - if False not in [ attr["found"] for attr in attributes ] or ((time.time() - start_time) > 300): + if re.search(f"{key}: {value}", output, re.MULTILINE): + found[key] = True + if False not in found.values() or ((time.time() - start_time) > timeout): break - for attr in attributes: - assert attr["found"], f"timed out waiting for '{attr['key']}: {attr['value']}'" + for key, value in attributes.items(): + assert found[key], f"timed out waiting for '{key}: {value}'" + + +def verify_app_instrumentation(container, app, method, attributes, otelcol_path=None): + systemd = True if method == "systemd" else False + + if systemd and container_file_exists(container, "/etc/ld.so.preload"): + run_container_cmd(container, "rm -f /etc/ld.so.preload") + + try: + stop_app(container, app) + except AssertionError: + pass + + container.restart() + wait_for_container_cmd(container, "systemctl show-environment", timeout=30) + + if otelcol_path is None: + # start the collector systemd service + run_container_cmd(container, "systemctl start splunk-otel-collector") + wait_for_container_cmd(container, "systemctl status splunk-otel-collector", timeout=30) + # get the output stream for the collector from journald + stream = container.exec_run("journalctl -u splunk-otel-collector -f", stream=True).output + else: + # start the collector from the shell and get the output stream + stream = container.exec_run(f"{otelcol_path} --config=/test/config.yaml", stream=True).output + + start_app(container, app, systemd) + + # check the collector output stream for attributes + verify_attributes(stream, attributes) @pytest.mark.parametrize( @@ -188,15 +223,14 @@ def verify_tomcat_instrumentation(container, otelcol_path, test_case, source, at + [pytest.param(distro, marks=pytest.mark.rpm) for distro in RPM_DISTROS], ) @pytest.mark.parametrize("arch", ["amd64", "arm64"]) -@pytest.mark.parametrize("test_case", ["default", "custom"]) -@pytest.mark.parametrize("source", ["systemd", "libsplunk"]) -def test_tomcat_instrumentation(distro, arch, test_case, source): +def test_tomcat_instrumentation(distro, arch): if distro == "opensuse-12" and arch == "arm64": pytest.skip("opensuse-12 arm64 no longer supported") otelcol_bin = f"otelcol_linux_{arch}" otelcol_bin_path = OTELCOL_BIN_DIR / otelcol_bin assert os.path.isfile(otelcol_bin_path), f"{otelcol_bin_path} not found!" + otelcol = f"/test/{otelcol_bin}" pkg_path = get_package(distro, PKG_NAME, arch) assert pkg_path, f"{PKG_NAME} package not found" @@ -210,24 +244,133 @@ def test_tomcat_instrumentation(distro, arch, test_case, source): install_package(container, distro, f"/test/{pkg_base}") - if test_case == "default": - # service name auto-generated by java agent - service_name = r"Str\(Hello, World Application\)" - environment = None - profiling = None + for method in ["systemd", "libsplunk"]: + # attributes from default config + attributes = { + r"telemetry\.sdk\.language": r"Str\(java\)", + r"service\.name": r"Str\(Hello, World Application\)", # auto-generated for the sample app + } + + if method == "systemd": + # install the sample drop-in file to enable the agent + run_container_cmd(container, f"mkdir -p {SYSTEMD_CONF_DIR}") + run_container_cmd(container, f"cp -f {SAMPLE_JAVA_SYSTEMD_CONF_PATH} {SYSTEMD_CONF_DIR}/") + else: + # add libsplunk.so to /etc/ld.so.preload + run_container_cmd(container, f"sh -c 'echo {LIBSPLUNK_PATH} > /etc/ld.so.preload'") + + # verify default config + verify_app_instrumentation(container, "tomcat", method, attributes, otelcol_path=otelcol) + + # attributes from custom config + attributes = { + r"telemetry\.sdk\.language": r"Str\(java\)", + r"service\.name": rf"Str\(service_name_from_{method}_java\)", + r"deployment\.environment": rf"Str\(deployment_environment_from_{method}_java\)", + r"com\.splunk\.sourcetype": r"Str\(otel\.profiling\)", + } + + if method == "systemd": + # install the custom drop-in file to configure the agent + copy_file_into_container(container, CUSTOM_JAVA_SYSTEMD_CONF_PATH, f"{SYSTEMD_CONF_DIR}/test.conf") + else: + # overwrite the default libsplunk config with the custom one for testing + copy_file_into_container(container, CUSTOM_JAVA_CONFIG_PATH, JAVA_CONFIG_PATH) + + # verify custom config + verify_app_instrumentation(container, "tomcat", method, attributes, otelcol_path=otelcol) + + +@pytest.mark.parametrize( + "distro", + [pytest.param(distro, marks=pytest.mark.deb) for distro in DEB_DISTROS] + + [pytest.param(distro, marks=pytest.mark.rpm) for distro in RPM_DISTROS], + ) +@pytest.mark.parametrize("arch", ["amd64", "arm64"]) +def test_express_instrumentation(distro, arch): + if distro == "opensuse-12" and arch == "arm64": + pytest.skip("opensuse-12 arm64 no longer supported") + + otelcol_bin = f"otelcol_linux_{arch}" + otelcol_bin_path = OTELCOL_BIN_DIR / otelcol_bin + assert os.path.isfile(otelcol_bin_path), f"{otelcol_bin_path} not found!" + otelcol = f"/test/{otelcol_bin}" + + pkg_path = get_package(distro, PKG_NAME, arch) + assert pkg_path, f"{PKG_NAME} package not found" + pkg_base = os.path.basename(pkg_path) + + # minimum supported node version required for profiling + node_version = "v16" + + if distro in ("centos-7", "oraclelinux-7"): + # g++ for these distros is too old to install splunk-otel-js with node v16: + # g++: error: unrecognized command line option '-std=gnu++14' + # use the minimum supported node version without profiling instead + node_version = "v14" + elif distro in ("debian-stretch", "ubuntu-xenial"): + # these distros only provide python 3.5, but node v16 requires python 3.6+ + # use the minimum supported node version without profiling instead + node_version = "v14" + + buildargs = {"NODE_VERSION": node_version} + with run_distro_container(distro, dockerfile=get_dockerfile(distro), arch=arch, buildargs=buildargs) as container: + copy_file_into_container(container, COLLECTOR_CONFIG_PATH, "/test/config.yaml") + copy_file_into_container(container, pkg_path, f"/test/{pkg_base}") + copy_file_into_container(container, otelcol_bin_path, otelcol) + run_container_cmd(container, f"chmod a+x /test/{otelcol_bin}") + + install_package(container, distro, f"/test/{pkg_base}") + + # install dependencies for splunk-otel-js + if "opensuse" in distro: + run_container_cmd(container, "zypper -n install -t pattern devel_basis") + run_container_cmd(container, "zypper -n install -t pattern devel_C_C++") + run_container_cmd(container, "zypper -n install python3") + elif distro in RPM_DISTROS: + run_container_cmd(container, "yum groupinstall -y 'Development Tools'") + run_container_cmd(container, "yum install -y python3") else: - service_name = rf"Str\(service_name_from_{source}\)" - environment = rf"Str\(deployment_environment_from_{source}\)" - profiling = r"Str\(otel\.profiling\)" - - attributes = [ - {"key": r"telemetry\.sdk\.language", "value": r"Str\(java\)", "found": False}, - {"key": r"service\.name", "value": service_name, "found": False}, - {"key": r"deployment\.environment", "value": environment, "found": False if environment else True}, - {"key": r"com\.splunk\.sourcetype", "value": profiling, "found": False if profiling else True}, - ] - - verify_tomcat_instrumentation(container, f"/test/{otelcol_bin}", test_case, source, attributes) + run_container_cmd(container, "apt-get install -y build-essential python3") + + # install splunk-otel-js + run_container_cmd(container, f"bash -l -c 'npm install --prefix /opt/express {NODE_AGENT_PATH}'") + + for method in ["systemd", "libsplunk"]: + # attributes from default config + attributes = { + r"telemetry\.sdk\.language": r"Str\(nodejs\)", + r"service\.name": r"Str\(unnamed-node-service\)", # auto-generated for the sample app + } + + if method == "systemd": + # install the sample drop-in file to enable the agent + run_container_cmd(container, f"mkdir -p {SYSTEMD_CONF_DIR}") + run_container_cmd(container, f"cp -f {SAMPLE_NODE_SYSTEMD_CONF_PATH} {SYSTEMD_CONF_DIR}/") + else: + # add libsplunk.so to /etc/ld.so.preload + run_container_cmd(container, f"sh -c 'echo {LIBSPLUNK_PATH} > /etc/ld.so.preload'") + + # verify default config + verify_app_instrumentation(container, "express", method, attributes, otelcol_path=otelcol) + + # attributes from custom config + attributes = { + r"telemetry\.sdk\.language": r"Str\(nodejs\)", + r"service\.name": rf"Str\(service_name_from_{method}_node\)", + r"deployment\.environment": rf"Str\(deployment_environment_from_{method}_node\)", + r"com\.splunk\.sourcetype": None if node_version == "v14" else r"Str\(otel\.profiling\)", + } + + if method == "systemd": + # install the custom drop-in file to configure the agent + copy_file_into_container(container, CUSTOM_NODE_SYSTEMD_CONF_PATH, f"{SYSTEMD_CONF_DIR}/test.conf") + else: + # overwrite the default libsplunk config with the custom one for testing + copy_file_into_container(container, CUSTOM_NODE_CONFIG_PATH, NODE_CONFIG_PATH) + + # verify custom config + verify_app_instrumentation(container, "express", method, attributes, otelcol_path=otelcol) @pytest.mark.parametrize( diff --git a/internal/buildscripts/packaging/tests/instrumentation/libsplunk-java-test.conf b/internal/buildscripts/packaging/tests/instrumentation/libsplunk-java-test.conf index c8bf9a693d..9c21dca1ef 100644 --- a/internal/buildscripts/packaging/tests/instrumentation/libsplunk-java-test.conf +++ b/internal/buildscripts/packaging/tests/instrumentation/libsplunk-java-test.conf @@ -1,6 +1,6 @@ JAVA_TOOL_OPTIONS=-javaagent:/usr/lib/splunk-instrumentation/splunk-otel-javaagent.jar -OTEL_RESOURCE_ATTRIBUTES=deployment.environment=deployment_environment_from_libsplunk -OTEL_SERVICE_NAME=service_name_from_libsplunk +OTEL_RESOURCE_ATTRIBUTES=deployment.environment=deployment_environment_from_libsplunk_java +OTEL_SERVICE_NAME=service_name_from_libsplunk_java SPLUNK_METRICS_ENABLED=true SPLUNK_PROFILER_ENABLED=true SPLUNK_PROFILER_MEMORY_ENABLED=true diff --git a/internal/buildscripts/packaging/tests/instrumentation/libsplunk-node-test.conf b/internal/buildscripts/packaging/tests/instrumentation/libsplunk-node-test.conf new file mode 100644 index 0000000000..b14d37e74c --- /dev/null +++ b/internal/buildscripts/packaging/tests/instrumentation/libsplunk-node-test.conf @@ -0,0 +1,6 @@ +NODE_OPTIONS=-r @splunk/otel/instrument +OTEL_RESOURCE_ATTRIBUTES=deployment.environment=deployment_environment_from_libsplunk_node +OTEL_SERVICE_NAME=service_name_from_libsplunk_node +SPLUNK_METRICS_ENABLED=true +SPLUNK_PROFILER_ENABLED=true +SPLUNK_PROFILER_MEMORY_ENABLED=true diff --git a/internal/buildscripts/packaging/tests/instrumentation/setup-express.sh b/internal/buildscripts/packaging/tests/instrumentation/setup-express.sh new file mode 100644 index 0000000000..28f8f18079 --- /dev/null +++ b/internal/buildscripts/packaging/tests/instrumentation/setup-express.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +set -euo pipefail + +EXPRESS_HOME="/opt/express" +useradd -r -m -U -d $EXPRESS_HOME -s /bin/false express + +NVM_HOME="/opt/nvm" +mkdir -p $NVM_HOME +HOME=$NVM_HOME bash -c 'curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash' +NVM_DIR="$NVM_HOME/.nvm" +[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" + +nvm install --default ${NODE_VERSION:-v16} + +echo "PATH=\$PATH:${NVM_BIN}" >> /etc/profile + +npm install --prefix $EXPRESS_HOME express + +cat < ${EXPRESS_HOME}/app.js +var express = require('express'); +var app = express(); + +app.get('/', function (req, res) { + res.send('Hello World'); +}) + +var server = app.listen(3000, function () { + var host = server.address().address + var port = server.address().port + + console.log("Example app listening at http://%s:%s", host, port) +}) +EOH + +chown express:express ${EXPRESS_HOME}/app.js + +mkdir -p /etc/systemd/system +cat < /etc/systemd/system/express.service +[Unit] +After=network.target + +[Service] +Type=simple +User=express +Group=express +Environment=NODE_PATH=${EXPRESS_HOME}/node_modules +ExecStart=${NVM_BIN}/node ${EXPRESS_HOME}/app.js +ExecStop=/bin/kill -TERM \$MAINPID +Restart=on-failure + +[Install] +WantedBy=multi-user.target +EOH diff --git a/internal/buildscripts/packaging/tests/instrumentation/systemd-test.conf b/internal/buildscripts/packaging/tests/instrumentation/systemd-java-test.conf similarity index 66% rename from internal/buildscripts/packaging/tests/instrumentation/systemd-test.conf rename to internal/buildscripts/packaging/tests/instrumentation/systemd-java-test.conf index 8738416f1f..b5a431265e 100644 --- a/internal/buildscripts/packaging/tests/instrumentation/systemd-test.conf +++ b/internal/buildscripts/packaging/tests/instrumentation/systemd-java-test.conf @@ -1,6 +1,6 @@ [Manager] -DefaultEnvironment="OTEL_SERVICE_NAME=service_name_from_systemd" -DefaultEnvironment="OTEL_RESOURCE_ATTRIBUTES=deployment.environment=deployment_environment_from_systemd" +DefaultEnvironment="OTEL_SERVICE_NAME=service_name_from_systemd_java" +DefaultEnvironment="OTEL_RESOURCE_ATTRIBUTES=deployment.environment=deployment_environment_from_systemd_java" DefaultEnvironment="SPLUNK_METRICS_ENABLED=true" DefaultEnvironment="SPLUNK_PROFILER_ENABLED=true" DefaultEnvironment="SPLUNK_PROFILER_MEMORY_ENABLED=true" diff --git a/internal/buildscripts/packaging/tests/instrumentation/systemd-node-test.conf b/internal/buildscripts/packaging/tests/instrumentation/systemd-node-test.conf new file mode 100644 index 0000000000..32ab46c5e8 --- /dev/null +++ b/internal/buildscripts/packaging/tests/instrumentation/systemd-node-test.conf @@ -0,0 +1,6 @@ +[Manager] +DefaultEnvironment="OTEL_SERVICE_NAME=service_name_from_systemd_node" +DefaultEnvironment="OTEL_RESOURCE_ATTRIBUTES=deployment.environment=deployment_environment_from_systemd_node" +DefaultEnvironment="SPLUNK_METRICS_ENABLED=true" +DefaultEnvironment="SPLUNK_PROFILER_ENABLED=true" +DefaultEnvironment="SPLUNK_PROFILER_MEMORY_ENABLED=true"