Skip to content

Commit

Permalink
[nodejs] add nodejs docker_ssi test app
Browse files Browse the repository at this point in the history
  • Loading branch information
brettlangdon committed Nov 22, 2024
1 parent 8031afc commit bc5d067
Show file tree
Hide file tree
Showing 11 changed files with 141 additions and 10 deletions.
13 changes: 12 additions & 1 deletion lib-injection/build/docker/nodejs/sample-app/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ process.on('SIGTERM', (signal) => {
process.exit(0);
});

function crashme(req, res) {
setTimeout(() => {
process.kill(process.pid, 'SIGSEGV');

res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end(`Crashing process ${process.pid}`);
}, 2000); // Add a delay before crashing otherwise the telemetry forwarder leaves a zombie behind
}

function forkAndCrash(req, res) {
const child = fork('child.js');

Expand Down Expand Up @@ -105,7 +114,9 @@ function getZombies(req, res) {
}

require('http').createServer((req, res) => {
if (req.url === '/fork_and_crash') {
if (req.url === '/crashme') {
crashme(req, res);
} else if (req.url === '/fork_and_crash') {
forkAndCrash(req, res);
} else if (req.url === '/child_pids') {
getChildPids(req, res);
Expand Down
5 changes: 4 additions & 1 deletion tests/docker_ssi/test_docker_ssi.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from urllib.parse import urlparse

from utils import scenarios, features, context, irrelevant, bug, interfaces, missing_feature
from utils import scenarios, features, context, irrelevant, bug, interfaces
from utils import weblog
from utils.tools import logger, get_rid_from_request

Expand Down Expand Up @@ -34,6 +34,7 @@ def setup_install_supported_runtime(self):
@bug(condition=context.library == "python", reason="INPLAT-11")
@irrelevant(context.library == "java" and context.installed_language_runtime < "1.8.0_0")
@irrelevant(context.library == "php" and context.installed_language_runtime < "7.0")
@irrelevant(context.library == "nodejs" and context.installed_language_runtime < "16.0")
def test_install_supported_runtime(self):
logger.info(f"Testing Docker SSI installation on supported lang runtime: {context.scenario.library.library}")
assert self.r.status_code == 200, f"Failed to get response from {context.scenario.weblog_url}"
Expand Down Expand Up @@ -69,6 +70,7 @@ def test_install_weblog_running(self):
@irrelevant(context.library == "java" and context.installed_language_runtime < "1.8.0_0")
@irrelevant(context.library == "php" and context.installed_language_runtime < "7.0")
@irrelevant(context.library == "python" and context.installed_language_runtime < "3.7.0")
@irrelevant(context.library == "nodejs" and context.installed_language_runtime < "16.0")
def test_telemetry(self):
# There is telemetry data about the auto instrumentation injector. We only validate there is data
telemetry_autoinject_data = interfaces.test_agent.get_telemetry_for_autoinject()
Expand All @@ -95,6 +97,7 @@ def test_telemetry(self):
@irrelevant(context.library == "php" and context.installed_language_runtime >= "7.0")
@bug(condition=context.library == "python" and context.installed_language_runtime < "3.7.0", reason="INPLAT-181")
@irrelevant(context.library == "python" and context.installed_language_runtime >= "3.7.0")
@irrelevant(context.library == "nodejs" and context.installed_language_runtime >= "16.0")
def test_telemetry_abort(self):
# There is telemetry data about the auto instrumentation injector. We only validate there is data
telemetry_autoinject_data = interfaces.test_agent.get_telemetry_for_autoinject()
Expand Down
3 changes: 2 additions & 1 deletion tests/docker_ssi/test_docker_ssi_crash.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ def setup_crash(self):
self.r = TestDockerSSICrash._r

@features.ssi_crashtracking
@bug(condition=context.library != "python", reason="INPLAT-11")
@bug(condition=context.library not in ("python", "nodejs"), reason="INPLAT-11")
@irrelevant(context.library == "python" and context.installed_language_runtime < "3.7.0")
@irrelevant(context.library == "nodejs" and context.installed_language_runtime < "16.0")
def test_crash(self):
"""Validate that a crash report is generated when the application crashes"""
logger.info(f"Testing Docker SSI crash tracking: {context.scenario.library.library}")
Expand Down
10 changes: 7 additions & 3 deletions utils/_context/_scenarios/docker_ssi.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,10 @@ def __init__(
self.should_push_base_images = False
self._weblog_docker_image = None

@property
def dd_lang(self) -> str:
return "js" if self._library == "nodejs" else self._library

def configure(self):
self.docker_tag = self.get_base_docker_tag()
self._docker_registry_tag = f"ghcr.io/datadog/system-tests/ssi_installer_{self.docker_tag}:latest"
Expand Down Expand Up @@ -288,7 +292,7 @@ def build_lang_deps_image(self):
nocache=self._force_build or self.should_push_base_images,
buildargs={
"ARCH": self._arch,
"DD_LANG": self._library,
"DD_LANG": self.dd_lang,
"RUNTIME_VERSIONS": self._installable_runtime,
"BASE_IMAGE": self._base_image,
},
Expand Down Expand Up @@ -342,7 +346,7 @@ def build_weblog_image(self, ssi_installer_docker_tag):
platform=self._arch,
nocache=self._force_build or self.should_push_base_images,
tag=self.ssi_all_docker_tag,
buildargs={"DD_LANG": self._library, "BASE_IMAGE": ssi_installer_docker_tag},
buildargs={"DD_LANG": self.dd_lang, "BASE_IMAGE": ssi_installer_docker_tag},
)
self.print_docker_build_logs(self.ssi_all_docker_tag, build_logs)
logger.stdout(
Expand Down Expand Up @@ -372,7 +376,7 @@ def tested_components(self):
Return json with the data"""
logger.info("Weblog extract tested components")
result = get_docker_client().containers.run(
image=self._weblog_docker_image, command=f"/tested_components.sh {self._library}", remove=True
image=self._weblog_docker_image, command=f"/tested_components.sh {self.dd_lang}", remove=True
)
logger.info(f"Testes components: {result.decode('utf-8')}")
return json.loads(result.decode("utf-8").replace("'", '"'))
Expand Down
35 changes: 35 additions & 0 deletions utils/build/ssi/base/js_install_runtimes.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/bin/bash

export NODEJS_VERSION=$1

if [ -f /etc/debian_version ] || [ "$DISTRIBUTION" = "Debian" ] || [ "$DISTRIBUTION" = "Ubuntu" ]; then
OS="Debian"
elif [ -f /etc/redhat-release ] || [ "$DISTRIBUTION" = "RedHat" ] || [ "$DISTRIBUTION" = "CentOS" ] || [ "$DISTRIBUTION" = "Amazon" ] || [ "$DISTRIBUTION" = "Rocky" ] || [ "$DISTRIBUTION" = "AlmaLinux" ]; then
OS="RedHat"
elif [ -f /etc/system-release ] || [ "$DISTRIBUTION" = "Amazon" ]; then
OS="RedHat"
elif [ -f /etc/Eos-release ] || [ "$DISTRIBUTION" = "Arista" ]; then
OS="RedHat"
elif [ -f /etc/SuSE-release ] || [ "$DISTRIBUTION" = "SUSE" ] || [ "$DISTRIBUTION" = "openSUSE" ]; then
OS="SUSE"
elif [ -f /etc/alpine-release ]; then
OS="Alpine"
fi

if [ "$OS" = "Debian" ]; then
apt-get update
ln -fs /usr/share/zoneinfo/America/New_York /etc/localtime
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends git curl
elif [ "$OS" = "RedHat" ]; then
yum install -y git curl
else
echo "Unknown OS"
exit 1
fi

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
nvm install ${NODEJS_VERSION}
nvm alias default ${NODEJS_VERSION}
node --version
5 changes: 5 additions & 0 deletions utils/build/ssi/base/tested_components.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ elif [ "$DD_LANG" == "php" ]; then
runtime_version=$(php -v | grep -oP 'PHP \K[0-9]+\.[0-9]+\.[0-9]+')
elif [ "$DD_LANG" == "python" ]; then
runtime_version=$(python --version | grep -oP 'Python \K[0-9]+\.[0-9]+\.[0-9]+')
elif [ "$DD_LANG" == "js" ]; then
export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"

runtime_version=$(node --version | tr -d 'v')
fi

if [ -f /etc/debian_version ] || [ "$DISTRIBUTION" = "Debian" ] || [ "$DISTRIBUTION" = "Ubuntu" ]; then
Expand Down
2 changes: 1 addition & 1 deletion utils/build/ssi/build_local.sh
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ do
if [ -z "$WEBLOG_VARIANT" ] || [ "$WEBLOG_VARIANT" = "$weblog" ]; then
if [ -z "$ARCH" ] || [ "$ARCH" = "$arch" ]; then
echo "Runing test scenario for weblog [${weblog}], base_image [${base_image}], arch [${arch}], installable_runtime [${installable_runtime}], extra_args: [${extra_args}]"
./run.sh DOCKER_SSI --ssi-weblog "$weblog" --ssi-library "$TEST_LIBRARY" --ssi-base-image "$base_image" --ssi-arch "$arch" --ssi-installable-runtime "$installable_runtime" "$extra_args"
./run.sh DOCKER_SSI --ssi-weblog="$weblog" --ssi-library="$TEST_LIBRARY" --ssi-base-image="$base_image" --ssi-arch="$arch" --ssi-installable-runtime="$installable_runtime" "$extra_args"
fi
fi

Expand Down
12 changes: 12 additions & 0 deletions utils/build/ssi/nodejs/js-app.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
ARG BASE_IMAGE

FROM ${BASE_IMAGE}
WORKDIR /app
COPY lib-injection/build/docker/nodejs/sample-app/ .
ENV HOME /root
EXPOSE 18080

# We need pid 1 to be bash and to properly configure nvm
# doing this via `RUN` doesn't seem to work
COPY utils/build/ssi/nodejs/run.sh /app/
CMD /app/run.sh
6 changes: 6 additions & 0 deletions utils/build/ssi/nodejs/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"

node index.js
55 changes: 53 additions & 2 deletions utils/docker_ssi/docker_ssi_definitions.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,35 @@ def get_version_id(version):
raise ValueError(f"Python version {version} not supported")


class JSRuntimeInstallableVersions:
"""Node.js runtime versions that can be installed automatically"""

JS12 = RuntimeInstallableVersion("JS12", "12")
JS14 = RuntimeInstallableVersion("JS14", "14")
JS16 = RuntimeInstallableVersion("JS16", "16")
JS18 = RuntimeInstallableVersion("JS18", "18")
JS20 = RuntimeInstallableVersion("JS20", "20")
JS22 = RuntimeInstallableVersion("JS22", "22")

@staticmethod
def get_all_versions():
return [
JSRuntimeInstallableVersions.JS12,
JSRuntimeInstallableVersions.JS14,
JSRuntimeInstallableVersions.JS18,
JSRuntimeInstallableVersions.JS18,
JSRuntimeInstallableVersions.JS20,
JSRuntimeInstallableVersions.JS22,
]

@staticmethod
def get_version_id(version):
for version_check in JSRuntimeInstallableVersions.get_all_versions():
if version_check.version == version:
return version_check.version_id
raise ValueError(f"Node.js version {version} not supported")


# HERE ADD YOUR WEBLOG DEFINITION: SUPPORTED IMAGES AND INSTALABLE RUNTIME VERSIONS
# Maybe a weblog app contains preinstalled language runtime, in this case we define the weblog without runtime version
JETTY_APP = WeblogDescriptor(
Expand Down Expand Up @@ -204,9 +233,31 @@ def get_version_id(version):
[
SupportedImages().UBUNTU_22_ARM64.with_allowed_runtime_versions(
PythonRuntimeInstallableVersions.get_all_versions()
)
),
],
)

JS_APP = WeblogDescriptor(
"js-app",
"nodejs",
[
SupportedImages().UBUNTU_22_AMD64.with_allowed_runtime_versions(
JSRuntimeInstallableVersions.get_all_versions()
),
SupportedImages().UBUNTU_22_ARM64.with_allowed_runtime_versions(
JSRuntimeInstallableVersions.get_all_versions()
),
],
)

# HERE ADD YOUR WEBLOG DEFINITION TO THE LIST
ALL_WEBLOGS = [JETTY_APP, TOMCAT_APP, JAVA7_APP, WEBSPHERE_APP, JBOSS_APP, PHP_APP, PY_APP]
ALL_WEBLOGS = [
JETTY_APP,
TOMCAT_APP,
JAVA7_APP,
WEBSPHERE_APP,
JBOSS_APP,
PHP_APP,
PY_APP,
JS_APP,
]
5 changes: 4 additions & 1 deletion utils/docker_ssi/docker_ssi_matrix_utils.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
from utils.docker_ssi.docker_ssi_definitions import (
JavaRuntimeInstallableVersions,
JSRuntimeInstallableVersions,
PHPRuntimeInstallableVersions,
PythonRuntimeInstallableVersions,
)


def resolve_runtime_version(library, runtime):
""" For installable runtimes, get the version identifier. ie JAVA_11 """
"""For installable runtimes, get the version identifier. ie JAVA_11"""
if library == "java":
return JavaRuntimeInstallableVersions.get_version_id(runtime)
elif library == "php":
return PHPRuntimeInstallableVersions.get_version_id(runtime)
elif library == "python":
return PythonRuntimeInstallableVersions.get_version_id(runtime)
elif library == "nodejs":
return JSRuntimeInstallableVersions.get_version_id(runtime)

raise ValueError(f"Library {library} not supported")

0 comments on commit bc5d067

Please sign in to comment.