diff --git a/.github/actions/common/backend/action.yml b/.github/actions/common/backend/action.yml index 345552df81..3989658a12 100644 --- a/.github/actions/common/backend/action.yml +++ b/.github/actions/common/backend/action.yml @@ -46,3 +46,12 @@ runs: uses: actions/setup-python@v5 with: python-version: '3.10' + - name: install requests + shell: bash + run: | + pip install requests + - name: download agent + uses: actions/cache@v4 + with: + path: sermant-agent-*/ + key: ${{ runner.os }}-agent-${{ github.run_id }} diff --git a/.github/actions/scenarios/backend/config/action.yml b/.github/actions/scenarios/backend/config/action.yml index cb05d180ea..98f0199dbb 100644 --- a/.github/actions/scenarios/backend/config/action.yml +++ b/.github/actions/scenarios/backend/config/action.yml @@ -3,6 +3,10 @@ description: "Auto test for Backend" runs: using: "composite" steps: + - name: entry + uses: ./.github/actions/common/entry + with: + log-dir: ./logs/backend-config - name: start backend with zookeeper shell: bash env: diff --git a/.github/actions/scenarios/backend/event/memory/action.yml b/.github/actions/scenarios/backend/event/memory/action.yml index 37af0ebca3..4812af9bc9 100644 --- a/.github/actions/scenarios/backend/event/memory/action.yml +++ b/.github/actions/scenarios/backend/event/memory/action.yml @@ -3,18 +3,13 @@ description: "Auto test for Backend" runs: using: "composite" steps: - - name: download agent - uses: actions/cache@v4 - with: - path: sermant-agent-*/ - key: ${{ runner.os }}-agent-${{ github.run_id }} - name: package dubbo 2.6.0 tests shell: bash run: mvn package -Dalibaba.dubbo.version=2.6.0 -DskipTests -P260 --file sermant-integration-tests/dubbo-test/pom.xml - name: entry uses: ./.github/actions/common/entry with: - log-dir: ./logs/backend + log-dir: ./logs/backend-memory - name: start backend with memory shell: bash run: | @@ -39,10 +34,6 @@ runs: shell: bash run: | netstat -nlp | grep :28021 | awk '{print $7}' | awk -F "/" '{print $1}' | xargs kill - - name: install requests - shell: bash - run: | - pip install requests - name: start test shell: bash run: | diff --git a/.github/actions/scenarios/backend/event/redis/action.yml b/.github/actions/scenarios/backend/event/redis/action.yml index d12db858b7..83e5466c62 100644 --- a/.github/actions/scenarios/backend/event/redis/action.yml +++ b/.github/actions/scenarios/backend/event/redis/action.yml @@ -6,7 +6,7 @@ runs: - name: entry uses: ./.github/actions/common/entry with: - log-dir: ./logs/backend + log-dir: ./logs/backend-redis - name: install redis shell: bash run: | diff --git a/.github/actions/scenarios/backend/external-agent/action.yml b/.github/actions/scenarios/backend/external-agent/action.yml new file mode 100644 index 0000000000..a22b6e8625 --- /dev/null +++ b/.github/actions/scenarios/backend/external-agent/action.yml @@ -0,0 +1,235 @@ +name: "Test external agent management" +description: "Auto test for external agent" +runs: + using: "composite" + steps: + - name: entry + uses: ./.github/actions/common/entry + with: + log-dir: ./logs/backend-external-agent + - name: compile AgentLoader + shell: bash + run: | + cp sermant-integration-tests/scripts/AgentLoader.java ./ + javac -classpath ./:${{ env.JAVA_HOME}}/lib/tools.jar AgentLoader.java + - name: download opentelemetry agent + uses: actions/cache@v4 + with: + path: opentelemetry-javaagent.jar + key: ${{ runner.os }}-opentelemetry-javaagent.jar + restore-keys: | + ${{ runner.os }}-opentelemetry-javaagent.jar + - name: start backend with zookeeper + shell: bash + env: + DYNAMIC_CONFIG_SERVERADDRESS: 127.0.0.1:2181 + DYNAMIC_CONFIG_DYNAMICCONFIGTYPE: ZOOKEEPER + DYNAMIC_CONFIG_ENABLE: true + NETTY_PORT: 6894 + SERVER_PORT: 8910 + MAX_EFFECTIVE_TIME: 20000 + run: | + nohup java -jar sermant-agent-${{ env.sermantVersion }}/server/sermant/sermant-backend-${{ env.sermantVersion }}.jar & + sleep 20 + + - name: start application with sermant agent without external agent + shell: bash + env: + dynamic.config.serverAddress: 127.0.0.1:2181 + dynamic.config.dynamicConfigType: ZOOKEEPER + service.meta.project: TestAgentCore + run: | + nohup java -javaagent:sermant-agent-${{ env.sermantVersion }}/agent/sermant-agent.jar \ + -Dserver.port=8915 \ + -Dagent.config.externalAgent.injection=false \ + -Dagent.service.heartbeat.enable=true \ + -Dagent.service.gateway.enable=true \ + -Devent.enable=true \ + -Dgateway.nettyPort=6894 \ + -Dheartbeat.interval=5000 \ + -jar sermant-agent-${{ env.sermantVersion }}/agent/agentcore-test-application-1.0.0-jar-with-dependencies.jar > ${{ env.logDir }}/agentcore-test.log 2>&1 & + - name: waiting for application start + shell: bash + run: | + bash ./sermant-integration-tests/scripts/checkService.sh http://127.0.0.1:8915/ping 120 + - name: test start with sermant agent without external agent + shell: bash + run: | + export TEST_MODE=startWithoutExternalAgent + python -m unittest ./sermant-integration-tests/scripts/test_backend_external_agent.py + - name: stop application + shell: bash + run: | + netstat -nlp | grep :8915 | awk '{print $7}' | awk -F "/" '{print $1}' | xargs kill + sleep 3 + - name: start application with sermant agent and external agent + shell: bash + env: + dynamic.config.serverAddress: 127.0.0.1:2181 + dynamic.config.dynamicConfigType: ZOOKEEPER + service.meta.project: TestAgentCore + run: | + nohup java -javaagent:sermant-agent-${{ env.sermantVersion }}/agent/sermant-agent.jar \ + -Dserver.port=8916 \ + -Dagent.config.externalAgent.injection=true \ + -Dagent.config.externalAgent.name=OTEL \ + -Dagent.config.externalAgent.file=opentelemetry-javaagent.jar \ + -Dagent.service.heartbeat.enable=true \ + -Dagent.service.gateway.enable=true \ + -Devent.enable=true \ + -Dgateway.nettyPort=6894 \ + -Dheartbeat.interval=5000 \ + -jar sermant-agent-${{ env.sermantVersion }}/agent/agentcore-test-application-1.0.0-jar-with-dependencies.jar > ${{ env.logDir }}/agentcore-test.log 2>&1 & + - name: waiting for application start + shell: bash + run: | + bash ./sermant-integration-tests/scripts/checkService.sh http://127.0.0.1:8916/ping 120 + - name: test start with sermant agent and external agent + shell: bash + run: | + export TEST_MODE=startWithExternalAgent + python -m unittest ./sermant-integration-tests/scripts/test_backend_external_agent.py + - name: stop application + shell: bash + run: | + netstat -nlp | grep :8916 | awk '{print $7}' | awk -F "/" '{print $1}' | xargs kill + sleep 3 + - name: start application alone + shell: bash + env: + dynamic.config.serverAddress: 127.0.0.1:2181 + dynamic.config.dynamicConfigType: ZOOKEEPER + service.meta.project: TestAgentCore + run: | + nohup java -Dserver.port=8917 \ + -jar sermant-agent-${{ env.sermantVersion }}/agent/agentcore-test-application-1.0.0-jar-with-dependencies.jar > ${{ env.logDir }}/agentcore-test.log 2>&1 & + - name: waiting for application start + shell: bash + run: | + bash ./sermant-integration-tests/scripts/checkService.sh http://127.0.0.1:8917/ping 120 + sleep 10 + - name: dynamic install external agent + shell: bash + run: java -classpath ./:${{ env.JAVA_HOME}}/lib/tools.jar AgentLoader sermant-agent-${{ env.sermantVersion }}/agent/sermant-agent.jar \ + command=INSTALL-EXTERNAL-AGENT:OTEL,AGENT_FILE=opentelemetry-javaagent.jar,agent.service.heartbeat.enable=true,agent.service.gateway.enable=true,event.enable=true,gateway.nettyPort=6894,heartbeat.interval=5000 + - name: test install external agent by attach in case of sermant agent is not installed + shell: bash + run: | + export TEST_MODE=installByAttach + python -m unittest ./sermant-integration-tests/scripts/test_backend_external_agent.py + - name: stop application + shell: bash + run: | + netstat -nlp | grep :8917 | awk '{print $7}' | awk -F "/" '{print $1}' | xargs kill + sleep 3 + - name: start application with sermant agent without external agent + shell: bash + env: + dynamic.config.serverAddress: 127.0.0.1:2181 + dynamic.config.dynamicConfigType: ZOOKEEPER + service.meta.project: TestAgentCore + run: | + nohup java -javaagent:sermant-agent-${{ env.sermantVersion }}/agent/sermant-agent.jar \ + -Dserver.port=8918 \ + -Dagent.config.externalAgent.injection=false \ + -Dagent.service.heartbeat.enable=true \ + -Dagent.service.gateway.enable=true \ + -Devent.enable=true \ + -Dgateway.nettyPort=6894 \ + -Dheartbeat.interval=5000 \ + -jar sermant-agent-${{ env.sermantVersion }}/agent/agentcore-test-application-1.0.0-jar-with-dependencies.jar > ${{ env.logDir }}/agentcore-test.log 2>&1 & + - name: waiting for application start + shell: bash + run: | + bash ./sermant-integration-tests/scripts/checkService.sh http://127.0.0.1:8918/ping 120 + - name: dynamic install external agent + shell: bash + run: java -classpath ./:${{ env.JAVA_HOME}}/lib/tools.jar AgentLoader sermant-agent-${{ env.sermantVersion }}/agent/sermant-agent.jar \ + command=INSTALL-EXTERNAL-AGENT:OTEL,AGENT_FILE=opentelemetry-javaagent.jar,agent.service.heartbeat.enable=true,agent.service.gateway.enable=true,event.enable=true,gateway.nettyPort=6894 + - name: test install external agent by attach in case of sermant agent is installed + shell: bash + run: | + export TEST_MODE=installByAttach + python -m unittest ./sermant-integration-tests/scripts/test_backend_external_agent.py + - name: stop application + shell: bash + run: | + netstat -nlp | grep :8918 | awk '{print $7}' | awk -F "/" '{print $1}' | xargs kill + sleep 3 + - name: start application alone + shell: bash + env: + dynamic.config.serverAddress: 127.0.0.1:2181 + dynamic.config.dynamicConfigType: ZOOKEEPER + service.meta.project: TestAgentCore + run: | + nohup java -Dserver.port=8919 \ + -jar sermant-agent-${{ env.sermantVersion }}/agent/agentcore-test-application-1.0.0-jar-with-dependencies.jar > ${{ env.logDir }}/agentcore-test.log 2>&1 & + - name: waiting for application start + shell: bash + run: | + bash ./sermant-integration-tests/scripts/checkService.sh http://127.0.0.1:8919/ping 120 + sleep 10 + - name: dynamic install external agent + shell: bash + run: java -classpath ./:${{ env.JAVA_HOME}}/lib/tools.jar AgentLoader sermant-agent-${{ env.sermantVersion }}/agent/sermant-agent.jar \ + agent.config.externalAgent.injection=true,agent.config.externalAgent.name=OTEL,agent.config.externalAgent.file=opentelemetry-javaagent.jar,agent.service.heartbeat.enable=true,agent.service.gateway.enable=true,event.enable=true,gateway.nettyPort=6894,heartbeat.interval=5000 + - name: test install external agent by attach in case of sermant agent is not installalled and has set external agent config + shell: bash + run: | + export TEST_MODE=installByAttach + python -m unittest ./sermant-integration-tests/scripts/test_backend_external_agent.py + - name: stop application + shell: bash + run: | + netstat -nlp | grep :8919 | awk '{print $7}' | awk -F "/" '{print $1}' | xargs kill + sleep 3 + - name: start application with sermant agent without external agent + shell: bash + env: + dynamic.config.serverAddress: 127.0.0.1:2181 + dynamic.config.dynamicConfigType: ZOOKEEPER + service.meta.project: TestAgentCore + run: | + nohup java -javaagent:sermant-agent-${{ env.sermantVersion }}/agent/sermant-agent.jar \ + -Dserver.port=8920 \ + -Dagent.config.externalAgent.injection=false \ + -Dagent.service.heartbeat.enable=true \ + -Dagent.service.gateway.enable=true \ + -Devent.enable=true \ + -Dgateway.nettyPort=6894 \ + -Dheartbeat.interval=5000 \ + -jar sermant-agent-${{ env.sermantVersion }}/agent/agentcore-test-application-1.0.0-jar-with-dependencies.jar > ${{ env.logDir }}/agentcore-test.log 2>&1 & + - name: waiting for application start + shell: bash + run: | + bash ./sermant-integration-tests/scripts/checkService.sh http://127.0.0.1:8920/ping 120 + - name: test install external agent by Sermant Backend + shell: bash + run: | + export TEST_MODE=install + python -m unittest ./sermant-integration-tests/scripts/test_backend_external_agent.py + - name: stop application + shell: bash + run: | + netstat -nlp | grep :8920 | awk '{print $7}' | awk -F "/" '{print $1}' | xargs kill + sleep 3 + - name: stop backend + shell: bash + run: | + netstat -nlp | grep :8910 | awk '{print $7}' | awk -F "/" '{print $1}' | xargs kill + - name: exit + if: always() + uses: ./.github/actions/common/exit + with: + processor-keyword: agentcore|backend + - name: if failure then upload error log + uses: actions/upload-artifact@v4 + if: ${{ failure() || cancelled() }} + with: + name: (${{ github.job }})-backend-logs + path: | + ./*.log + ./logs/** + if-no-files-found: warn + retention-days: 2 diff --git a/.github/actions/scenarios/backend/hot-plugging/action.yml b/.github/actions/scenarios/backend/hot-plugging/action.yml index 810b1c70c4..16c374f78b 100644 --- a/.github/actions/scenarios/backend/hot-plugging/action.yml +++ b/.github/actions/scenarios/backend/hot-plugging/action.yml @@ -1,8 +1,12 @@ -name: "Test the configuration management of Backend" +name: "Test the plugin hot-plugging in Backend" description: "Auto test for Backend" runs: using: "composite" steps: + - name: entry + uses: ./.github/actions/common/entry + with: + log-dir: ./logs/backend-hot-plugging - name: compile AgentLoader shell: bash run: | @@ -27,8 +31,7 @@ runs: service.meta.project: TestAgentCore run: | nohup java -jar \ - sermant-agent-${{ env.sermantVersion }}/agent/agentcore-test-application-1.0.0-jar-with-dependencies.jar > ${{ env.logDir - }}/agentcore-test.log 2>&1 & + sermant-agent-${{ env.sermantVersion }}/agent/agentcore-test-application-1.0.0-jar-with-dependencies.jar > ${{ env.logDir }}/agentcore-test.log 2>&1 & - name: waiting for agentcore services start shell: bash run: | @@ -66,6 +69,14 @@ runs: run: | export TEST_MODE=unInstall python -m unittest ./sermant-integration-tests/scripts/test_backend_hot_plugging.py + - name: stop application + shell: bash + run: | + netstat -nlp | grep :8915 | awk '{print $7}' | awk -F "/" '{print $1}' | xargs kill + - name: stop backend + shell: bash + run: | + netstat -nlp | grep :8910 | awk '{print $7}' | awk -F "/" '{print $1}' | xargs kill - name: exit if: always() uses: ./.github/actions/common/exit diff --git a/.github/workflows/backend_integration_test.yml b/.github/workflows/backend_integration_test.yml index ae6fa98d12..6746b7f28d 100644 --- a/.github/workflows/backend_integration_test.yml +++ b/.github/workflows/backend_integration_test.yml @@ -57,6 +57,17 @@ jobs: run: | export ROOT_PATH=$(pwd) bash ./sermant-integration-tests/scripts/tryDownloadMidware.sh nacos210 + - name: cache opentelemetry agent + uses: actions/cache@v4 + with: + path: opentelemetry-javaagent.jar + key: ${{ runner.os }}-opentelemetry-javaagent.jar + restore-keys: | + ${{ runner.os }}-opentelemetry-javaagent.jar + - name: download opentelemetry agent + run: | + export ROOT_PATH=$(pwd) + bash ./sermant-integration-tests/scripts/tryDownloadMidware.sh otel build-agent-and-cache: name: build agent and cache runs-on: ubuntu-latest @@ -102,3 +113,5 @@ jobs: uses: ./.github/actions/scenarios/backend/config - name: start hot plugging test uses: ./.github/actions/scenarios/backend/hot-plugging + - name: start external agent test + uses: ./.github/actions/scenarios/backend/external-agent diff --git a/sermant-integration-tests/agentcore-test/agentcore-test-application/src/main/java/com/example/sermant/agentcore/test/application/AgentCoreTestApplication.java b/sermant-integration-tests/agentcore-test/agentcore-test-application/src/main/java/com/example/sermant/agentcore/test/application/AgentCoreTestApplication.java index 3a1df759b2..dd98570f4f 100644 --- a/sermant-integration-tests/agentcore-test/agentcore-test-application/src/main/java/com/example/sermant/agentcore/test/application/AgentCoreTestApplication.java +++ b/sermant-integration-tests/agentcore-test/agentcore-test-application/src/main/java/com/example/sermant/agentcore/test/application/AgentCoreTestApplication.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2023-2023 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (C) 2023-2025 Huawei Technologies Co., Ltd. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -41,7 +41,14 @@ public class AgentCoreTestApplication { * @throws IllegalAccessException */ public static void main(String[] args) throws IOException, IllegalAccessException { - HttpServer server = HttpServer.create(new InetSocketAddress(SERVER_PORT), 0); + int actualPort; + String port = System.getProperty("server.port"); + if (port != null && !"".equals(port)) { + actualPort = Integer.parseInt(port); + } else { + actualPort = SERVER_PORT; + } + HttpServer server = HttpServer.create(new InetSocketAddress(actualPort), 0); // 添加URL路由 for (Field field : RouterPath.class.getDeclaredFields()) { diff --git a/sermant-integration-tests/scripts/test_backend_external_agent.py b/sermant-integration-tests/scripts/test_backend_external_agent.py new file mode 100644 index 0000000000..f1551dbeba --- /dev/null +++ b/sermant-integration-tests/scripts/test_backend_external_agent.py @@ -0,0 +1,75 @@ +# +# Copyright (C) 2025-2025 Sermant Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# + +import requests +import time +import unittest +import os + +class TestBackendExternalAgent(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls.mode = os.getenv('TEST_MODE', 'default') + cls.session = requests.session() + + @classmethod + def tearDownClass(cls): + cls.session.close() + + hot_plugging_url = "http://127.0.0.1:8910/sermant/publishHotPluggingConfig" + query_plugin_info_url = "http://127.0.0.1:8910/sermant/getPluginsInfo" + header = {'content-type': 'application/json'} + install_external_agent_param = { + "commandType": "INSTALL-EXTERNAL-AGENT", + "instanceIds": "", + "externalAgentName": "OTEL", + "agentPath": "opentelemetry-javaagent.jar" + } + + def get_health_instances(self): + time.sleep(30) + resp = self.session.get(self.query_plugin_info_url).json() + health_instances = [item for item in resp if item.get('health') is True] + print("Health Instances:", health_instances) + return health_instances + + def assert_otel_installed(self, instance): + self.assertIn("OTEL", instance['externalAgentInfoMap'], "OTEL not found in externalAgentInfoMap") + self.assertEqual("OTEL", instance['externalAgentInfoMap']['OTEL']['name']) + self.assertEqual("2.10.0", instance['externalAgentInfoMap']['OTEL']['version']) + + def test_external_agent_function(self): + health_instances = self.get_health_instances() + + if self.mode == 'startWithoutExternalAgent': + self.assertEqual({}, health_instances[0]['externalAgentInfoMap']) + + elif self.mode == 'startWithExternalAgent': + self.assert_otel_installed(health_instances[0]) + + elif self.mode == 'installByAttach': + self.assert_otel_installed(health_instances[0]) + + elif self.mode == 'installByBackend': + self.install_external_agent_param["instanceIds"] = health_instances[0]['instanceId'] + self.session.post(self.hot_plugging_url, json=self.install_external_agent_param, headers=self.header) + + health_instances = self.get_health_instances() + self.assert_otel_installed(health_instances[0]) + +if __name__ == "__main__": + unittest.main() diff --git a/sermant-integration-tests/scripts/test_backend_hot_plugging.py b/sermant-integration-tests/scripts/test_backend_hot_plugging.py index 9d1e2c4952..3c1c5be323 100644 --- a/sermant-integration-tests/scripts/test_backend_hot_plugging.py +++ b/sermant-integration-tests/scripts/test_backend_hot_plugging.py @@ -74,6 +74,5 @@ def test_hot_plugging_function(self): resp = session.get(self.query_uninstall_result_url).json() self.assertTrue(resp.get('DYNAMIC_UNINSTALL_PLUGIN_INTERCEPTOR_FAILURE')) self.assertFalse(resp.get('DYNAMIC_UNINSTALL_REPEAT_ENHANCE')) - if __name__ == "__main__": unittest.main() diff --git a/sermant-integration-tests/scripts/tryDownloadMidware.sh b/sermant-integration-tests/scripts/tryDownloadMidware.sh index 7bf53c974e..364a959e2c 100644 --- a/sermant-integration-tests/scripts/tryDownloadMidware.sh +++ b/sermant-integration-tests/scripts/tryDownloadMidware.sh @@ -44,6 +44,9 @@ ROCKETMQ_514_FILE_NAME=rocketmq-all-5.1.4-bin-release.zip KAFKA_ADDRESS=https://archive.apache.org/dist/kafka/2.7.0/kafka_2.13-2.7.0.tgz KAFKA_FILE_NAME=kafka_2.13-2.7.0.tgz +OTEL_ADDRESS=https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v2.10.0/opentelemetry-javaagent.jar +OTEL_FILE_NAME=opentelemetry-javaagent.jar + #重试次数 TRY_TIMES=3 @@ -95,6 +98,9 @@ elif [ $midleware == "rocketmq514" ]; then elif [ $midleware == "kafka" ]; then ADDRESS=$KAFKA_ADDRESS FILE_NAME=$KAFKA_FILE_NAME + elif [ $midleware == "otel" ]; then + ADDRESS=$OTEL_ADDRESS + FILE_NAME=$OTEL_FILE_NAME else ADDRESS=$CSE_ADDRESS FILE_NAME=$CSE_FILE_NAME