aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Vanbesien <tvanbesi@proton.me>2026-02-19 00:01:18 +0100
committerThomas Vanbesien <tvanbesi@proton.me>2026-02-19 00:01:18 +0100
commitf3648fefe040152bb1676d651ebf7d836cb8ac9e (patch)
treea656270416167c3a15e61f937c27093a7fb05bf0
parent965db7e3243aecb02f7f57b4fe8dabe9ad50a697 (diff)
downloadBobinkCOpcUa-f3648fefe040152bb1676d651ebf7d836cb8ac9e.tar.gz
BobinkCOpcUa-f3648fefe040152bb1676d651ebf7d836cb8ac9e.zip
Refactor: reduce duplication and tighten helpers
- Remove redundant applicationUri log in print_application_description - Use UA_SECURITY_POLICY_NONE_URI macro instead of hardcoded string - Extract _s_register_with_lds / _s_deregister_from_lds helpers - Rename signal handler param 'sign' to 'sig' for consistency - Add INT_MIN/INT_MAX bounds check to config_require_int - Extract shared test helpers into tests/test_helpers.sh
-rw-r--r--src/common.c7
-rw-r--r--src/config.c3
-rw-r--r--src/server_register.c86
-rwxr-xr-xtests/run_cert_bootstrap_test.sh39
-rwxr-xr-xtests/run_download_cert_test.sh37
-rwxr-xr-xtests/run_test.sh40
-rw-r--r--tests/test_helpers.sh56
7 files changed, 115 insertions, 153 deletions
diff --git a/src/common.c b/src/common.c
index 234f925..8f141d7 100644
--- a/src/common.c
+++ b/src/common.c
@@ -366,10 +366,6 @@ print_application_description (const UA_ApplicationDescription *description,
(int)description->applicationName.text.length,
description->applicationName.text.data);
UA_LOG_INFO (UA_Log_Stdout, UA_LOGCATEGORY_APPLICATION,
- " Application URI: %.*s",
- (int)description->applicationUri.length,
- description->applicationUri.data);
- UA_LOG_INFO (UA_Log_Stdout, UA_LOGCATEGORY_APPLICATION,
" Product URI: %.*s", (int)description->productUri.length,
description->productUri.data);
UA_LOG_INFO (UA_Log_Stdout, UA_LOGCATEGORY_APPLICATION, " Type: %s", type);
@@ -507,8 +503,7 @@ create_unsecure_client_config (UA_ClientConfig *cc,
cc->securityMode = UA_MESSAGESECURITYMODE_NONE;
UA_String_clear (&cc->securityPolicyUri);
- cc->securityPolicyUri = UA_String_fromChars (
- "http://opcfoundation.org/UA/SecurityPolicy#None");
+ UA_String_copy (&UA_SECURITY_POLICY_NONE_URI, &cc->securityPolicyUri);
if (auth && auth->mode == AUTH_USER)
UA_ClientConfig_setAuthenticationUsername (cc, auth->user.username,
diff --git a/src/config.c b/src/config.c
index 5f4d67a..2cee9d3 100644
--- a/src/config.c
+++ b/src/config.c
@@ -7,6 +7,7 @@
#include <open62541/plugin/log_stdout.h>
+#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -192,7 +193,7 @@ config_require_int (const config *cfg, const char *key, const char *program)
char *endptr;
long num = strtol (val, &endptr, 10);
- if (*endptr != '\0')
+ if (*endptr != '\0' || num < INT_MIN || num > INT_MAX)
{
UA_LOG_FATAL (UA_Log_Stdout, UA_LOGCATEGORY_USERLAND,
"%s: config key '%s' is not a valid integer: '%s'",
diff --git a/src/server_register.c b/src/server_register.c
index de333a5..b675e2f 100644
--- a/src/server_register.c
+++ b/src/server_register.c
@@ -24,7 +24,7 @@
volatile UA_Boolean g_running = true;
static void
-_s_stop_handler (int sign)
+_s_stop_handler (int sig)
{
g_running = false;
}
@@ -66,6 +66,40 @@ _s_make_lds_client_config (UA_ClientConfig *cc, const lds_client_params *p)
return UA_STATUSCODE_GOOD;
}
+/**
+ * Creates a fresh client config and registers with the LDS.
+ */
+static UA_StatusCode
+_s_register_with_lds (UA_Server *server, const lds_client_params *p,
+ const char *endpoint)
+{
+ UA_ClientConfig cc;
+ UA_StatusCode rv = _s_make_lds_client_config (&cc, p);
+ if (rv != UA_STATUSCODE_GOOD)
+ return rv;
+ UA_String url = UA_STRING_ALLOC (endpoint);
+ rv = UA_Server_registerDiscovery (server, &cc, url, UA_STRING_NULL);
+ UA_String_clear (&url);
+ return rv;
+}
+
+/**
+ * Creates a fresh client config and deregisters from the LDS.
+ */
+static UA_StatusCode
+_s_deregister_from_lds (UA_Server *server, const lds_client_params *p,
+ const char *endpoint)
+{
+ UA_ClientConfig cc;
+ UA_StatusCode rv = _s_make_lds_client_config (&cc, p);
+ if (rv != UA_STATUSCODE_GOOD)
+ return rv;
+ UA_String url = UA_STRING_ALLOC (endpoint);
+ rv = UA_Server_deregisterDiscovery (server, &cc, url);
+ UA_String_clear (&url);
+ return rv;
+}
+
/* ========================================================================
* Main
* ======================================================================== */
@@ -175,20 +209,7 @@ main (int argc, char **argv)
can periodically re-register with the LDS between iterations. */
UA_Server_run_startup (server);
- /* UA_Server_registerDiscovery consumes (clears) the client config,
- so _s_make_lds_client_config builds a fresh one for every call. */
- UA_ClientConfig client_config;
- retval = _s_make_lds_client_config (&client_config, &lds_params);
- if (retval != UA_STATUSCODE_GOOD)
- {
- UA_Server_run_shutdown (server);
- goto cleanup;
- }
-
- UA_String discovery_url = UA_STRING_ALLOC (discovery_endpoint);
- retval = UA_Server_registerDiscovery (server, &client_config, discovery_url,
- UA_STRING_NULL);
- UA_String_clear (&discovery_url);
+ retval = _s_register_with_lds (server, &lds_params, discovery_endpoint);
if (retval != UA_STATUSCODE_GOOD)
UA_LOG_WARNING (UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
"Initial register failed: %s",
@@ -205,36 +226,23 @@ main (int argc, char **argv)
time_t now = time (NULL);
if (now - last_register >= register_interval)
{
- retval = _s_make_lds_client_config (&client_config, &lds_params);
- if (retval == UA_STATUSCODE_GOOD)
- {
- UA_String rereg_url = UA_STRING_ALLOC (discovery_endpoint);
- retval = UA_Server_registerDiscovery (server, &client_config,
- rereg_url, UA_STRING_NULL);
- UA_String_clear (&rereg_url);
- if (retval != UA_STATUSCODE_GOOD)
- UA_LOG_WARNING (UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
- "Re-register failed: %s",
- UA_StatusCode_name (retval));
- }
+ retval
+ = _s_register_with_lds (server, &lds_params, discovery_endpoint);
+ if (retval != UA_STATUSCODE_GOOD)
+ UA_LOG_WARNING (UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
+ "Re-register failed: %s",
+ UA_StatusCode_name (retval));
last_register = now;
}
}
/* Deregister from the LDS before shutting down so the LDS removes
our entry immediately rather than waiting for the cleanup timeout. */
- retval = _s_make_lds_client_config (&client_config, &lds_params);
- if (retval == UA_STATUSCODE_GOOD)
- {
- UA_String dereg_url = UA_STRING_ALLOC (discovery_endpoint);
- retval
- = UA_Server_deregisterDiscovery (server, &client_config, dereg_url);
- UA_String_clear (&dereg_url);
- if (retval != UA_STATUSCODE_GOOD)
- UA_LOG_ERROR (UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
- "Could not unregister from discovery server: %s",
- UA_StatusCode_name (retval));
- }
+ retval = _s_deregister_from_lds (server, &lds_params, discovery_endpoint);
+ if (retval != UA_STATUSCODE_GOOD)
+ UA_LOG_ERROR (UA_Log_Stdout, UA_LOGCATEGORY_SERVER,
+ "Could not unregister from discovery server: %s",
+ UA_StatusCode_name (retval));
UA_Server_run_shutdown (server);
rc = EXIT_SUCCESS;
diff --git a/tests/run_cert_bootstrap_test.sh b/tests/run_cert_bootstrap_test.sh
index 681a4aa..d0f4a3e 100755
--- a/tests/run_cert_bootstrap_test.sh
+++ b/tests/run_cert_bootstrap_test.sh
@@ -15,6 +15,8 @@
# ---------------------------------------------------------------
set -uo pipefail
+source "$(dirname "$0")/test_helpers.sh"
+
CONFIG_DIR="${1:?Usage: $0 <config_dir>}"
LDS_PORT=14840
@@ -23,7 +25,6 @@ LDS_PID=""
SR_PID=""
TMPFILE=""
DOWNLOADED_CERT=""
-FAILURES=0
# ── cleanup ────────────────────────────────────────────────────
cleanup() {
@@ -35,44 +36,10 @@ cleanup() {
}
trap cleanup EXIT
-# ── helpers ────────────────────────────────────────────────────
-wait_for_port() {
- local port="$1" pid="$2" label="$3" i=0
- while [ $i -lt 50 ]; do
- if ! kill -0 "$pid" 2>/dev/null; then
- echo "FAIL: $label exited prematurely"
- exit 1
- fi
- if ss -tlnp 2>/dev/null | grep -q ":${port} "; then
- return 0
- fi
- sleep 0.1
- i=$((i + 1))
- done
- echo "FAIL: $label did not listen on port $port within 5 s"
- exit 1
-}
-
-check() {
- local label="$1" result="$2"
- if [ "$result" -eq 0 ]; then
- echo "PASS: $label"
- else
- echo "FAIL: $label"
- FAILURES=$((FAILURES + 1))
- fi
-}
-
# ── idempotency guard ─────────────────────────────────────────
rm -f "$CONFIG_DIR/certs/trust_client/ServerRegister_cert.der"
-# ── port check ─────────────────────────────────────────────────
-for port in $LDS_PORT $SR_PORT; do
- if ss -tlnp 2>/dev/null | grep -q ":${port} "; then
- echo "FAIL: port $port is already in use"
- exit 1
- fi
-done
+assert_ports_free "$LDS_PORT" "$SR_PORT"
# ── start LDS ──────────────────────────────────────────────────
build/bobink_opcua_discovery_server "$CONFIG_DIR/server_lds.conf" >/dev/null 2>&1 &
diff --git a/tests/run_download_cert_test.sh b/tests/run_download_cert_test.sh
index 3631c56..7dd7dfd 100755
--- a/tests/run_download_cert_test.sh
+++ b/tests/run_download_cert_test.sh
@@ -12,13 +12,14 @@
# ---------------------------------------------------------------
set -uo pipefail
+source "$(dirname "$0")/test_helpers.sh"
+
CONFIG_DIR="${1:?Usage: $0 <config_dir>}"
LDS_PORT=14840
LDS_PID=""
TMPFILE=""
DOWNLOADED_CERT=""
-FAILURES=0
# ── cleanup ────────────────────────────────────────────────────
cleanup() {
@@ -28,39 +29,7 @@ cleanup() {
}
trap cleanup EXIT
-# ── helpers ────────────────────────────────────────────────────
-wait_for_port() {
- local port="$1" pid="$2" label="$3" i=0
- while [ $i -lt 50 ]; do
- if ! kill -0 "$pid" 2>/dev/null; then
- echo "FAIL: $label exited prematurely"
- exit 1
- fi
- if ss -tlnp 2>/dev/null | grep -q ":${port} "; then
- return 0
- fi
- sleep 0.1
- i=$((i + 1))
- done
- echo "FAIL: $label did not listen on port $port within 5 s"
- exit 1
-}
-
-check() {
- local label="$1" result="$2"
- if [ "$result" -eq 0 ]; then
- echo "PASS: $label"
- else
- echo "FAIL: $label"
- FAILURES=$((FAILURES + 1))
- fi
-}
-
-# ── port check ─────────────────────────────────────────────────
-if ss -tlnp 2>/dev/null | grep -q ":${LDS_PORT} "; then
- echo "FAIL: port $LDS_PORT is already in use"
- exit 1
-fi
+assert_ports_free "$LDS_PORT"
# ── start LDS ──────────────────────────────────────────────────
build/bobink_opcua_discovery_server "$CONFIG_DIR/server_lds.conf" >/dev/null 2>&1 &
diff --git a/tests/run_test.sh b/tests/run_test.sh
index 6d17958..8f6c21b 100755
--- a/tests/run_test.sh
+++ b/tests/run_test.sh
@@ -18,6 +18,8 @@ set -uo pipefail
# NOTE: we intentionally omit "set -e" so that every check runs
# even if the client itself returns non-zero.
+source "$(dirname "$0")/test_helpers.sh"
+
CONFIG_DIR="${1:?Usage: $0 <config_dir> <expected_policy>}"
EXPECTED_POLICY="${2:?Usage: $0 <config_dir> <expected_policy>}"
@@ -26,7 +28,6 @@ SR_PORT=14841
LDS_PID=""
SR_PID=""
TMPFILE=""
-FAILURES=0
# ── cleanup ────────────────────────────────────────────────────
cleanup() {
@@ -36,31 +37,7 @@ cleanup() {
}
trap cleanup EXIT
-# ── helpers ────────────────────────────────────────────────────
-wait_for_port() {
- local port="$1" pid="$2" label="$3" i=0
- while [ $i -lt 50 ]; do
- if ! kill -0 "$pid" 2>/dev/null; then
- echo "FAIL: $label exited prematurely"
- exit 1
- fi
- if ss -tlnp 2>/dev/null | grep -q ":${port} "; then
- return 0
- fi
- sleep 0.1
- i=$((i + 1))
- done
- echo "FAIL: $label did not listen on port $port within 5 s"
- exit 1
-}
-
-# ── port check ─────────────────────────────────────────────────
-for port in $LDS_PORT $SR_PORT; do
- if ss -tlnp 2>/dev/null | grep -q ":${port} "; then
- echo "FAIL: port $port is already in use"
- exit 1
- fi
-done
+assert_ports_free "$LDS_PORT" "$SR_PORT"
# ── start LDS ──────────────────────────────────────────────────
build/bobink_opcua_discovery_server "$CONFIG_DIR/server_lds.conf" >/dev/null 2>&1 &
@@ -72,17 +49,6 @@ build/bobink_opcua_server "$CONFIG_DIR/server_register.conf" "$CONFIG_DIR/server
SR_PID=$!
wait_for_port "$SR_PORT" "$SR_PID" "bobink_opcua_server"
-# ── validation helper ─────────────────────────────────────────
-check() {
- local label="$1" result="$2"
- if [ "$result" -eq 0 ]; then
- echo "PASS: $label"
- else
- echo "FAIL: $label"
- FAILURES=$((FAILURES + 1))
- fi
-}
-
# ── FindServers ───────────────────────────────────────────────
TMPFILE=$(mktemp)
build/client "$CONFIG_DIR/client.conf" find-servers "opc.tcp://localhost:$LDS_PORT" >"$TMPFILE" 2>&1
diff --git a/tests/test_helpers.sh b/tests/test_helpers.sh
new file mode 100644
index 0000000..a9d420c
--- /dev/null
+++ b/tests/test_helpers.sh
@@ -0,0 +1,56 @@
+#!/usr/bin/env bash
+# ---------------------------------------------------------------
+# Shared helpers for OPC UA discovery integration tests.
+#
+# Source this file from test scripts:
+# source "$(dirname "$0")/test_helpers.sh"
+# ---------------------------------------------------------------
+
+FAILURES=0
+
+# Waits up to 5 seconds for a process to listen on a TCP port.
+# Exits immediately if the process dies before the port opens.
+#
+# wait_for_port <port> <pid> <label>
+wait_for_port() {
+ local port="$1" pid="$2" label="$3" i=0
+ while [ $i -lt 50 ]; do
+ if ! kill -0 "$pid" 2>/dev/null; then
+ echo "FAIL: $label exited prematurely"
+ exit 1
+ fi
+ if ss -tlnp 2>/dev/null | grep -q ":${port} "; then
+ return 0
+ fi
+ sleep 0.1
+ i=$((i + 1))
+ done
+ echo "FAIL: $label did not listen on port $port within 5 s"
+ exit 1
+}
+
+# Records a PASS/FAIL result. Increments FAILURES on failure.
+#
+# check <label> <exit-code>
+check() {
+ local label="$1" result="$2"
+ if [ "$result" -eq 0 ]; then
+ echo "PASS: $label"
+ else
+ echo "FAIL: $label"
+ FAILURES=$((FAILURES + 1))
+ fi
+}
+
+# Asserts that the given TCP ports are not already in use.
+# Exits immediately if any port is occupied.
+#
+# assert_ports_free <port> [port...]
+assert_ports_free() {
+ for port in "$@"; do
+ if ss -tlnp 2>/dev/null | grep -q ":${port} "; then
+ echo "FAIL: port $port is already in use"
+ exit 1
+ fi
+ done
+}