You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2021/10/15 08:32:05 UTC

[skywalking] branch master updated: Replace e2e cases to e2e-v2: Python (#7932)

This is an automated email from the ASF dual-hosted git repository.

wusheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking.git


The following commit(s) were added to refs/heads/master by this push:
     new d73c51a  Replace e2e cases to e2e-v2: Python (#7932)
d73c51a is described below

commit d73c51a4ddb3fd30274909904b906fc48e535f8f
Author: wankai123 <wa...@foxmail.com>
AuthorDate: Fri Oct 15 16:31:35 2021 +0800

    Replace e2e cases to e2e-v2: Python (#7932)
---
 .github/workflows/e2e.python.yaml                  |   4 +-
 CHANGES.md                                         |  22 ++-
 test/e2e-v2/cases/go/e2e.yaml                      |   7 +-
 test/e2e-v2/cases/php/e2e.yaml                     |   7 +-
 .../{script/env => cases/python/Dockerfile.python} |  20 ++-
 test/e2e-v2/cases/python/consumer.py               |  57 ++++++
 test/e2e-v2/cases/python/docker-compose.yml        | 180 +++++++++++++++++++
 test/e2e-v2/cases/python/e2e.yaml                  | 143 +++++++++++++++
 .../expected/dependency-instance-consumer-py.yml   |  41 +++++
 .../dependency-instance-provider-py-kafka.yml      |  41 +++++
 .../expected/dependency-instance-provider-py.yml   |  41 +++++
 .../expected/dependency-services-consumer-py.yml   |  60 +++++++
 .../expected/dependency-services-provider-py.yml}  |  29 ++-
 .../python/expected/metrics-has-value.yml}         |  11 +-
 .../expected/service-endpoint-consumer-java.yml}   |  11 +-
 .../expected/service-endpoint-consumer-py.yml}     |  11 +-
 .../service-endpoint-provider-py-kafka.yml}        |  11 +-
 .../expected/service-endpoint-provider-py.yml}     |  11 +-
 .../expected/service-instance-consumer-java.yml    |  40 +++++
 .../expected/service-instance-consumer-py.yml      |  28 +++
 .../service-instance-provider-py-kafka.yml         |  28 +++
 .../expected/service-instance-provider-py.yml      |  28 +++
 .../env => cases/python/expected/service.yml}      |  21 ++-
 .../cases/python/expected/trace-test-detail.yml    | 195 +++++++++++++++++++++
 .../python/expected/traces-list-consumer-java.yml} |  19 +-
 .../python/expected/traces-list-consumer-py.yml}   |  19 +-
 .../expected/traces-list-provider-py-kafka.yml}    |  19 +-
 .../python/expected/traces-list-provider-py.yml}   |  19 +-
 test/e2e-v2/cases/python/provider-kafka.py         |  47 +++++
 test/e2e-v2/cases/python/provider.py               |  46 +++++
 test/e2e-v2/script/env                             |   1 +
 31 files changed, 1121 insertions(+), 96 deletions(-)

diff --git a/.github/workflows/e2e.python.yaml b/.github/workflows/e2e.python.yaml
index 152bc46..5f84484 100644
--- a/.github/workflows/e2e.python.yaml
+++ b/.github/workflows/e2e.python.yaml
@@ -45,6 +45,6 @@ jobs:
         uses: ./.github/actions/skip
       - name: Run E2E Test
         if: env.SKIP_CI != 'true'
-        uses: ./.github/actions/e2e-test
+        uses: ./.github/actions/infra-e2e-test
         with:
-          test_class: org.apache.skywalking.e2e.PythonE2E
+          config-file: python/e2e.yaml
diff --git a/CHANGES.md b/CHANGES.md
index acae23e..e28e3e8 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -6,18 +6,26 @@ Release Notes.
 ------------------
 #### Project
 
-* replace log e2e cases to e2e-v2.
-
+* Replace e2e cases to e2e-v2: 
+  - Simple: JDK, Auth, SSL, mTLS
+  - Lua Nginx
+  - SelfObservability
+  - Gateway
+  - Meter
+  - Nodejs
+  - PHP
+  - VM: Prometheus Node Exporter, Zabbix
+  - go2sky
+  - log
+  - Python
+  
 #### OAP Server
 
 * Add component definition for `Jackson`.
 * Fix that zipkin-receiver plugin is not packaged into dist.
-* Replace e2e cases to e2e-v2: Lua Nginx/SelfObservability.
 * Upgrade Armeria to 1.12, upgrade OpenSearch test version to 1.1.0.
 * Add component definition for `Apache-Kylin`.
 * Enhance `get` generation mechanism of OAL engine, support map type of source's field.
-* Replace e2e cases to e2e-v2: Gateway.
-* Replace e2e cases to e2e-v2: Meter.
 * Add `tag`(Map) into All, Service, ServiceInstance and Endpoint sources.
 * Fix `funcParamExpression` and `literalExpression` can't be used in the same aggregation function.
 * Support cast statement in the OAL core engine.
@@ -29,13 +37,9 @@ Release Notes.
   attribute expression.
 * Refactor the OAL compiler context to improve readability.
 * Fix wrong generated codes of `hashCode` and `remoteHashCode` methods for numeric fields.
-* Replace e2e cases to e2e-v2: Nodejs.
 * Support `!= null` in OAL engine.
 * Add `Message Queue Consuming Count` metric for MQ consuming service and endpoint.
 * Add `Message Queue Avg Consuming Latency` metric for MQ consuming service and endpoint.
-* Replace e2e cases to e2e-v2: PHP.
-* Replace VM e2e cases to e2e-v2: Prometheus Node Exporter, Zabbix.
-* Replace e2e cases to e2e-v2: go2sky.
 
 #### UI
 
diff --git a/test/e2e-v2/cases/go/e2e.yaml b/test/e2e-v2/cases/go/e2e.yaml
index 31c931b..57a10fe 100644
--- a/test/e2e-v2/cases/go/e2e.yaml
+++ b/test/e2e-v2/cases/go/e2e.yaml
@@ -65,7 +65,7 @@ verify:
     # trace detail
     - query: |
         swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql trace $( \
-          swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql trace ls \
+          swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql trace ls --service-name=e2e-service-consumer\
             | yq e '.traces | select(.[].endpointnames[0]=="POST:/correlation") | .[0].traceids[0]' -
         )
       expected: expected/trace-correlation-detail.yml
@@ -109,3 +109,8 @@ verify:
           swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql instance list --service-name=go2sky | yq e '.[0].name' - ) \
            --service-name=go2sky --dest-instance-name=provider1 --dest-service-name=e2e-service-provider |yq e 'to_entries' -
       expected: expected/metrics-has-value.yml
+    - query: |
+        swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=service_instance_relation_server_cpm --instance-name=$( \
+          swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql instance list --service-name=go2sky | yq e '.[0].name' - ) \
+           --service-name=go2sky --dest-instance-name=provider1 --dest-service-name=e2e-service-provider |yq e 'to_entries' -
+      expected: expected/metrics-has-value.yml
diff --git a/test/e2e-v2/cases/php/e2e.yaml b/test/e2e-v2/cases/php/e2e.yaml
index c487a69..db7edc2 100644
--- a/test/e2e-v2/cases/php/e2e.yaml
+++ b/test/e2e-v2/cases/php/e2e.yaml
@@ -64,7 +64,7 @@ verify:
     # trace detail
     - query: |
         swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql trace $( \
-          swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql trace ls \
+          swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql trace ls --service-name=php\
             | yq e '.traces | select(.[].endpointnames[0]=="/php/info") | .[0].traceids[0]' -
         )
       expected: expected/trace-info-detail.yml
@@ -110,3 +110,8 @@ verify:
           swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql instance list --service-name=php | yq e '.[0].name' - ) \
            --service-name=php --dest-instance-name=provider1 --dest-service-name=e2e-service-provider |yq e 'to_entries' -
       expected: expected/metrics-has-value.yml
+    - query: |
+        swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=service_instance_relation_server_cpm --instance-name=$( \
+          swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql instance list --service-name=php | yq e '.[0].name' - ) \
+           --service-name=php --dest-instance-name=provider1 --dest-service-name=e2e-service-provider |yq e 'to_entries' -
+      expected: expected/metrics-has-value.yml
diff --git a/test/e2e-v2/script/env b/test/e2e-v2/cases/python/Dockerfile.python
similarity index 67%
copy from test/e2e-v2/script/env
copy to test/e2e-v2/cases/python/Dockerfile.python
index 6f9f924..ab11acf 100644
--- a/test/e2e-v2/script/env
+++ b/test/e2e-v2/cases/python/Dockerfile.python
@@ -13,10 +13,18 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-SW_AGENT_JAVA_COMMIT=3997f0256056788bd054ee37e4603c11c0fd6756
-SW_AGENT_SATELLITE_COMMIT=1f3c08a5af19f8522f2a40d9339c45fa816bfe07
-SW_AGENT_NGINX_LUA_COMMIT=c3cee4841798a147d83b96a10914d4ac0e11d0aa
-SW_AGENT_NODEJS_COMMIT=e755659c7f308d3b5589619778c8360308cb14f8
-SW_AGENT_GO_COMMIT=4af380c2db6243106b0fc650b6003ce3b3eb82a0
+FROM python:3.7
+ARG SW_AGENT_PYTHON_COMMIT
 
-SW_CTL_COMMIT=b90255132f916f53eb90955cc8a6445b03a4bec3
+WORKDIR /app
+
+RUN git clone https://github.com/apache/skywalking-python.git $(pwd)
+
+RUN git reset --hard ${SW_AGENT_PYTHON_COMMIT} && git submodule update --init
+
+RUN make setup install
+RUN python3 -m pip install kafka-python
+
+ADD ./consumer.py /consumer.py
+ADD ./provider.py /provider.py
+ADD ./provider-kafka.py /provider-kafka.py
diff --git a/test/e2e-v2/cases/python/consumer.py b/test/e2e-v2/cases/python/consumer.py
new file mode 100644
index 0000000..9640559
--- /dev/null
+++ b/test/e2e-v2/cases/python/consumer.py
@@ -0,0 +1,57 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 urllib.parse
+from urllib import request
+
+from skywalking import agent, config
+
+if __name__ == '__main__':
+    config.service_name = 'consumer-py'
+    config.logging_level = 'DEBUG'
+    config.protocol = 'http'
+    config.collector_address = 'http://oap:12800'
+    agent.start()
+
+    import socketserver
+    from http.server import BaseHTTPRequestHandler
+
+    class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
+        def do_POST(self):
+            self.send_response(200)
+            self.send_header('Content-Type', 'application/json; charset=utf-8')
+            self.end_headers()
+
+            data = '{"name": "whatever"}'.encode('utf8')
+            req = request.Request('http://medium-java:9092/users')
+            req.add_header('Content-Type', 'application/json; charset=utf-8')
+            req.add_header('Content-Length', str(len(data)))
+            with request.urlopen(req, data):
+                self.wfile.write(data)
+
+            req2 = request.Request("http://provider-py-kafka:9089/users")
+            req2.add_header('Content-Type', 'application/json; charset=utf-8')
+            req2.add_header('Content-Length', str(len(data)))
+            with request.urlopen(req2, data):
+                self.wfile.write(data)
+
+    PORT = 9090
+    Handler = SimpleHTTPRequestHandler
+
+    with socketserver.TCPServer(("", PORT), Handler) as httpd:
+        print("serving at port", PORT)
+        httpd.serve_forever()
diff --git a/test/e2e-v2/cases/python/docker-compose.yml b/test/e2e-v2/cases/python/docker-compose.yml
new file mode 100644
index 0000000..7d5c54f
--- /dev/null
+++ b/test/e2e-v2/cases/python/docker-compose.yml
@@ -0,0 +1,180 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+version: '2.1'
+
+services:
+  zookeeper:
+    image: zookeeper:3.4
+    hostname: zookeeper
+    expose:
+      - 2181
+    networks:
+      - e2e
+    environment:
+      - ALLOW_ANONYMOUS_LOGIN=yes
+    healthcheck:
+      test: ["CMD", "sh", "-c", "nc -nz 127.0.0.1 2181"]
+      interval: 5s
+      timeout: 60s
+      retries: 120
+
+  broker-a:
+    image: bitnami/kafka:2.4.1
+    hostname: broker-a
+    expose:
+      - 9092
+    networks:
+      - e2e
+    environment:
+      - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
+      - KAFKA_BROKER_ID=10
+      - ALLOW_PLAINTEXT_LISTENER=yes
+    depends_on:
+      zookeeper:
+        condition: service_healthy
+    healthcheck:
+      test: ["CMD", "kafka-topics.sh", "--list", "--zookeeper", "zookeeper:2181"]
+      interval: 5s
+      timeout: 60s
+      retries: 120
+
+  broker-b:
+    image: bitnami/kafka:2.4.1
+    hostname: broker-b
+    expose:
+      - 9092
+    networks:
+      - e2e
+    environment:
+      - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
+      - KAFKA_BROKER_ID=24
+      - ALLOW_PLAINTEXT_LISTENER=yes
+    depends_on:
+      zookeeper:
+        condition: service_healthy
+    healthcheck:
+      test: ["CMD", "kafka-topics.sh", "--list", "--zookeeper", "zookeeper:2181"]
+      interval: 5s
+      timeout: 60s
+      retries: 120
+
+  oap:
+    extends:
+      file: ../../script/docker-compose/base-compose.yml
+      service: oap
+    environment:
+      SW_KAFKA_FETCHER: default
+      SW_KAFKA_FETCHER_SERVERS: broker-a:9092,broker-b:9092
+      SW_KAFKA_FETCHER_PARTITIONS: 2
+      SW_KAFKA_FETCHER_PARTITIONS_FACTOR: 1
+    depends_on:
+      broker-a:
+        condition: service_healthy
+      broker-b:
+        condition: service_healthy
+    ports:
+    - 12800
+
+  provider-py:
+    build:
+      context: .
+      dockerfile: Dockerfile.python
+      args:
+        - SW_AGENT_PYTHON_COMMIT=${SW_AGENT_PYTHON_COMMIT}
+    networks:
+      - e2e
+    expose:
+      - 9091
+    environment:
+      SW_AGENT_COLLECTOR_BACKEND_SERVICES: oap:11800
+      SW_AGENT_INSTANCE: provider-py-instance
+    depends_on:
+      oap:
+        condition: service_healthy
+    healthcheck:
+      test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/9091"]
+      interval: 5s
+      timeout: 60s
+      retries: 120
+    entrypoint: ['python3', '/provider.py']
+
+  medium-java:
+    extends:
+      file: ../../script/docker-compose/base-compose.yml
+      service: consumer
+    environment:
+      PROVIDER_URL: http://provider-py:9091
+    depends_on:
+      oap:
+        condition: service_healthy
+      provider-py:
+        condition: service_healthy
+
+  provider-py-kafka:
+    build:
+      context: .
+      dockerfile: Dockerfile.python
+      args:
+        - SW_AGENT_PYTHON_COMMIT=${SW_AGENT_PYTHON_COMMIT}
+    networks:
+      - e2e
+    expose:
+      - 9089
+    environment:
+      SW_AGENT_COLLECTOR_BACKEND_SERVICES: oap:11800
+      SW_AGENT_INSTANCE: provider-py-kafka-instance
+      SW_KAFKA_REPORTER_BOOTSTRAP_SERVERS: broker-a:9092,broker-b:9092
+    depends_on:
+      oap:
+        condition: service_healthy
+    healthcheck:
+      test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/9089"]
+      interval: 5s
+      timeout: 60s
+      retries: 120
+    entrypoint: ['python3', '/provider-kafka.py']
+
+
+  consumer-py:
+    build:
+      context: .
+      dockerfile: Dockerfile.python
+      args:
+        - SW_AGENT_PYTHON_COMMIT=${SW_AGENT_PYTHON_COMMIT}
+    networks:
+      - e2e
+    ports:
+      - 9090
+    environment:
+      SW_AGENT_COLLECTOR_BACKEND_SERVICES: oap:11800
+      PROVIDER_URL: http://medium-java:9092/users
+      SW_AGENT_INSTANCE: consumer-py-instance
+    depends_on:
+      oap:
+        condition: service_healthy
+      medium-java:
+        condition: service_healthy
+      provider-py-kafka:
+        condition: service_healthy
+    healthcheck:
+      test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/9090"]
+      interval: 5s
+      timeout: 60s
+      retries: 120
+    entrypoint: ['python3', '/consumer.py']
+
+networks:
+  e2e:
diff --git a/test/e2e-v2/cases/python/e2e.yaml b/test/e2e-v2/cases/python/e2e.yaml
new file mode 100644
index 0000000..c0f3e63
--- /dev/null
+++ b/test/e2e-v2/cases/python/e2e.yaml
@@ -0,0 +1,143 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+# This file is used to show how to write configuration files and can be used to test.
+
+setup:
+  env: compose
+  file: docker-compose.yml
+  timeout: 1200
+  init-system-environment: ../../script/env
+  steps:
+    - name: install yq
+      command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh yq
+    - name: install swctl
+      command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh swctl
+    - name: install etcdctl
+      command: bash test/e2e-v2/script/prepare/setup-e2e-shell/install.sh etcdctl
+
+trigger:
+  action: http
+  interval: 3s
+  times: 10
+  url: http://${consumer-py_host}:${consumer-py_9090}/test
+  method: POST
+
+verify:
+  # verify with retry strategy
+  retry:
+    # max retry count
+    count: 20
+    # the interval between two retries, in millisecond.
+    interval: 3s
+  cases:
+    # service list
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql service ls
+      expected: expected/service.yml
+    # service instance list
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql instance list --service-name=provider-py
+      expected: expected/service-instance-provider-py.yml
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql instance list --service-name=consumer-py
+      expected: expected/service-instance-consumer-py.yml
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql instance list --service-name=provider-py-kafka
+      expected: expected/service-instance-provider-py-kafka.yml
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql instance list --service-name=e2e-service-consumer
+      expected: expected/service-instance-consumer-java.yml
+    # service endpoint
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql endpoint list --keyword=test --service-name=consumer-py
+      expected: expected/service-endpoint-consumer-py.yml
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql endpoint list --keyword=users --service-name=e2e-service-consumer
+      expected: expected/service-endpoint-consumer-java.yml
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql endpoint list --keyword=users --service-name=provider-py
+      expected: expected/service-endpoint-provider-py.yml
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql endpoint list --keyword=users --service-name=provider-py-kafka
+      expected: expected/service-endpoint-provider-py-kafka.yml
+    # trace segment list
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql trace ls --service-name=consumer-py
+      expected: expected/traces-list-consumer-py.yml
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql trace ls --service-name=provider-py
+      expected: expected/traces-list-provider-py.yml
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql trace ls --service-name=provider-py-kafka
+      expected: expected/traces-list-provider-py-kafka.yml
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql trace ls --service-name=e2e-service-consumer
+      expected: expected/traces-list-consumer-java.yml
+    # trace detail
+    - query: |
+        swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql trace $( \
+          swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql trace ls --service-name=consumer-py\
+            | yq e '.traces | select(.[].endpointnames[0]=="/test") | .[0].traceids[0]' -
+        )
+      expected: expected/trace-test-detail.yml
+    # dependency service
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql dependency service --service-name=consumer-py
+      expected: expected/dependency-services-consumer-py.yml
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql dependency service --service-name=provider-py
+      expected: expected/dependency-services-provider-py.yml
+    # dependency instance
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql dependency instance --service-name=consumer-py --dest-service-name=e2e-service-consumer
+      expected: expected/dependency-instance-consumer-py.yml
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql dependency instance --service-name=e2e-service-consumer --dest-service-name=provider-py
+      expected: expected/dependency-instance-provider-py.yml
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql dependency instance --service-name=consumer-py --dest-service-name=provider-py-kafka
+      expected: expected/dependency-instance-provider-py-kafka.yml
+    # service metrics
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=service_sla --service-name=consumer-py |yq e 'to_entries' -
+      expected: expected/metrics-has-value.yml
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=service_cpm --service-name=consumer-py |yq e 'to_entries' -
+      expected: expected/metrics-has-value.yml
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=service_resp_time --service-name=consumer-py |yq e 'to_entries' -
+      expected: expected/metrics-has-value.yml
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=service_apdex --service-name=consumer-py |yq e 'to_entries' -
+      expected: expected/metrics-has-value.yml
+    # service instance metrics
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=service_instance_resp_time --instance-name=consumer1 --service-name=e2e-service-consumer |yq e 'to_entries' -
+      expected: expected/metrics-has-value.yml
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=service_instance_cpm --instance-name=consumer1 --service-name=e2e-service-consumer |yq e 'to_entries' -
+      expected: expected/metrics-has-value.yml
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=service_instance_sla --instance-name=consumer1 --service-name=e2e-service-consumer |yq e 'to_entries' -
+      expected: expected/metrics-has-value.yml
+    # service endpoint metrics
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=endpoint_cpm --endpoint-name=/users --service-name=provider-py |yq e 'to_entries' -
+      expected: expected/metrics-has-value.yml
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=endpoint_avg --endpoint-name=/users --service-name=provider-py |yq e 'to_entries' -
+      expected: expected/metrics-has-value.yml
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=endpoint_sla --endpoint-name=/users --service-name=provider-py |yq e 'to_entries' -
+      expected: expected/metrics-has-value.yml
+    # service relation metrics
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=service_relation_client_cpm  --service-name=consumer-py --dest-service-name=e2e-service-consumer |yq e 'to_entries' -
+      expected: expected/metrics-has-value.yml
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=service_relation_server_cpm  --service-name=consumer-py --dest-service-name=e2e-service-consumer |yq e 'to_entries' -
+      expected: expected/metrics-has-value.yml
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=service_relation_client_cpm  --service-name=consumer-py --dest-service-name=provider-py-kafka |yq e 'to_entries' -
+      expected: expected/metrics-has-value.yml
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=service_relation_server_cpm  --service-name=consumer-py --dest-service-name=provider-py-kafka |yq e 'to_entries' -
+      expected: expected/metrics-has-value.yml
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=service_relation_client_cpm  --service-name=e2e-service-consumer --dest-service-name=provider-py |yq e 'to_entries' -
+      expected: expected/metrics-has-value.yml
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=service_relation_server_cpm  --service-name=e2e-service-consumer --dest-service-name=provider-py |yq e 'to_entries' -
+      expected: expected/metrics-has-value.yml
+    # service instance relation metrics
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=service_instance_relation_client_cpm  --instance-name=consumer-py-instance  --service-name=consumer-py --dest-instance-name=consumer1 --dest-service-name=e2e-service-consumer |yq e 'to_entries' -
+      expected: expected/metrics-has-value.yml
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=service_instance_relation_server_cpm  --instance-name=consumer-py-instance  --service-name=consumer-py --dest-instance-name=consumer1 --dest-service-name=e2e-service-consumer |yq e 'to_entries' -
+      expected: expected/metrics-has-value.yml
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=service_instance_relation_client_cpm  --instance-name=consumer-py-instance  --service-name=consumer-py --dest-instance-name=provider-py-kafka-instance --dest-service-name=provider-py-kafka |yq e 'to_entries' -
+      expected: expected/metrics-has-value.yml
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=service_instance_relation_server_cpm  --instance-name=consumer-py-instance  --service-name=consumer-py --dest-instance-name=provider-py-kafka-instance --dest-service-name=provider-py-kafka |yq e 'to_entries' -
+      expected: expected/metrics-has-value.yml
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=service_instance_relation_client_cpm  --instance-name=consumer1 --service-name=e2e-service-consumer --dest-instance-name=provider-py-instance --dest-service-name=provider-py |yq e 'to_entries' -
+      expected: expected/metrics-has-value.yml
+    - query: swctl --display yaml --base-url=http://${oap_host}:${oap_12800}/graphql metrics linear --name=service_instance_relation_server_cpm  --instance-name=consumer1 --service-name=e2e-service-consumer --dest-instance-name=provider-py-instance --dest-service-name=provider-py |yq e 'to_entries' -
+      expected: expected/metrics-has-value.yml
diff --git a/test/e2e-v2/cases/python/expected/dependency-instance-consumer-py.yml b/test/e2e-v2/cases/python/expected/dependency-instance-consumer-py.yml
new file mode 100644
index 0000000..3116872
--- /dev/null
+++ b/test/e2e-v2/cases/python/expected/dependency-instance-consumer-py.yml
@@ -0,0 +1,41 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+nodes:
+{{- contains .nodes }}
+- id: {{ b64enc "e2e-service-consumer" }}.1_{{ b64enc "consumer1" }}
+  name: consumer1
+  serviceid: {{ b64enc "e2e-service-consumer" }}.1
+  servicename: e2e-service-consumer
+  type: Tomcat
+  isreal: true
+- id: {{ b64enc "consumer-py" }}.1_{{ b64enc "consumer-py-instance" }}
+  name: consumer-py-instance
+  serviceid: {{ b64enc "consumer-py" }}.1
+  servicename: consumer-py
+  type: ""
+  isreal: true
+{{- end }}
+calls:
+{{- contains .calls }}
+  - source: {{ b64enc "consumer-py" }}.1_{{ b64enc "consumer-py-instance" }}
+    sourcecomponents: []
+    target: {{ b64enc "e2e-service-consumer" }}.1_{{ b64enc "consumer1" }}
+    targetcomponents: []
+    id: {{ b64enc "consumer-py" }}.1_{{ b64enc "consumer-py-instance" }}-{{ b64enc "e2e-service-consumer" }}.1_{{ b64enc "consumer1" }}
+    detectpoints:
+      - CLIENT
+      - SERVER
+{{- end }}
diff --git a/test/e2e-v2/cases/python/expected/dependency-instance-provider-py-kafka.yml b/test/e2e-v2/cases/python/expected/dependency-instance-provider-py-kafka.yml
new file mode 100644
index 0000000..4f2ae32
--- /dev/null
+++ b/test/e2e-v2/cases/python/expected/dependency-instance-provider-py-kafka.yml
@@ -0,0 +1,41 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+nodes:
+{{- contains .nodes }}
+- id: {{ b64enc "provider-py-kafka" }}.1_{{ b64enc "provider-py-kafka-instance" }}
+  name: provider-py-kafka-instance
+  serviceid: {{ b64enc "provider-py-kafka" }}.1
+  servicename: provider-py-kafka
+  type: Python
+  isreal: true
+- id: {{ b64enc "consumer-py" }}.1_{{ b64enc "consumer-py-instance" }}
+  name: consumer-py-instance
+  serviceid: {{ b64enc "consumer-py" }}.1
+  servicename: consumer-py
+  type: ""
+  isreal: true
+{{- end }}
+calls:
+{{- contains .calls }}
+  - source: {{ b64enc "consumer-py" }}.1_{{ b64enc "consumer-py-instance" }}
+    sourcecomponents: []
+    target: {{ b64enc "provider-py-kafka" }}.1_{{ b64enc "provider-py-kafka-instance" }}
+    targetcomponents: []
+    id: {{ b64enc "consumer-py" }}.1_{{ b64enc "consumer-py-instance" }}-{{ b64enc "provider-py-kafka" }}.1_{{ b64enc "provider-py-kafka-instance" }}
+    detectpoints:
+      - CLIENT
+      - SERVER
+{{- end }}
diff --git a/test/e2e-v2/cases/python/expected/dependency-instance-provider-py.yml b/test/e2e-v2/cases/python/expected/dependency-instance-provider-py.yml
new file mode 100644
index 0000000..34eb6ec
--- /dev/null
+++ b/test/e2e-v2/cases/python/expected/dependency-instance-provider-py.yml
@@ -0,0 +1,41 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+nodes:
+{{- contains .nodes }}
+- id: {{ b64enc "e2e-service-consumer" }}.1_{{ b64enc "consumer1" }}
+  name: consumer1
+  serviceid: {{ b64enc "e2e-service-consumer" }}.1
+  servicename: e2e-service-consumer
+  type: ""
+  isreal: true
+- id: {{ b64enc "provider-py" }}.1_{{ b64enc "provider-py-instance" }}
+  name: provider-py-instance
+  serviceid: {{ b64enc "provider-py" }}.1
+  servicename: provider-py
+  type: Python
+  isreal: true
+{{- end }}
+calls:
+{{- contains .calls }}
+  - source: {{ b64enc "e2e-service-consumer" }}.1_{{ b64enc "consumer1" }}
+    sourcecomponents: []
+    target: {{ b64enc "provider-py" }}.1_{{ b64enc "provider-py-instance" }}
+    targetcomponents: []
+    id: {{ b64enc "e2e-service-consumer" }}.1_{{ b64enc "consumer1" }}-{{ b64enc "provider-py" }}.1_{{ b64enc "provider-py-instance" }}
+    detectpoints:
+      - CLIENT
+      - SERVER
+{{- end }}
diff --git a/test/e2e-v2/cases/python/expected/dependency-services-consumer-py.yml b/test/e2e-v2/cases/python/expected/dependency-services-consumer-py.yml
new file mode 100644
index 0000000..24e1323
--- /dev/null
+++ b/test/e2e-v2/cases/python/expected/dependency-services-consumer-py.yml
@@ -0,0 +1,60 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+nodes:
+{{- contains .nodes }}
+- id: {{ b64enc "User"}}.0
+  name: User
+  type: USER
+  isreal: false
+- id: {{ b64enc "e2e-service-consumer"}}.1
+  name: e2e-service-consumer
+  type: Tomcat
+  isreal: true
+- id: {{ b64enc "consumer-py" }}.1
+  name: consumer-py
+  type: Python
+  isreal: true
+- id: {{ b64enc "provider-py-kafka" }}.1
+  name: provider-py-kafka
+  type: Python
+  isreal: true
+{{- end }}
+calls:
+{{- contains .calls }}
+- source: {{ b64enc "User"}}.0
+  sourcecomponents: []
+  target: {{ b64enc "consumer-py"}}.1
+  targetcomponents: []
+  id: {{ b64enc "User"}}.0-{{ b64enc "consumer-py"}}.1
+  detectpoints:
+    - SERVER
+- source: {{ b64enc "consumer-py" }}.1
+  sourcecomponents: []
+  target: {{ b64enc "e2e-service-consumer"}}.1
+  targetcomponents: []
+  id: {{ b64enc "consumer-py" }}.1-{{ b64enc "e2e-service-consumer"}}.1
+  detectpoints:
+    - CLIENT
+    - SERVER
+- source: {{ b64enc "consumer-py" }}.1
+  sourcecomponents: []
+  target: {{ b64enc "provider-py-kafka"}}.1
+  targetcomponents: []
+  id: {{ b64enc "consumer-py" }}.1-{{ b64enc "provider-py-kafka"}}.1
+  detectpoints:
+    - CLIENT
+    - SERVER
+{{- end }}
diff --git a/test/e2e-v2/script/env b/test/e2e-v2/cases/python/expected/dependency-services-provider-py.yml
similarity index 60%
copy from test/e2e-v2/script/env
copy to test/e2e-v2/cases/python/expected/dependency-services-provider-py.yml
index 6f9f924..7b55e05 100644
--- a/test/e2e-v2/script/env
+++ b/test/e2e-v2/cases/python/expected/dependency-services-provider-py.yml
@@ -13,10 +13,25 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-SW_AGENT_JAVA_COMMIT=3997f0256056788bd054ee37e4603c11c0fd6756
-SW_AGENT_SATELLITE_COMMIT=1f3c08a5af19f8522f2a40d9339c45fa816bfe07
-SW_AGENT_NGINX_LUA_COMMIT=c3cee4841798a147d83b96a10914d4ac0e11d0aa
-SW_AGENT_NODEJS_COMMIT=e755659c7f308d3b5589619778c8360308cb14f8
-SW_AGENT_GO_COMMIT=4af380c2db6243106b0fc650b6003ce3b3eb82a0
-
-SW_CTL_COMMIT=b90255132f916f53eb90955cc8a6445b03a4bec3
+nodes:
+{{- contains .nodes }}
+- id: {{ b64enc "e2e-service-consumer"}}.1
+  name: e2e-service-consumer
+  type: Tomcat
+  isreal: true
+- id: {{ b64enc "provider-py" }}.1
+  name: provider-py
+  type: Python
+  isreal: true
+{{- end }}
+calls:
+{{- contains .calls }}
+- source: {{ b64enc "e2e-service-consumer" }}.1
+  sourcecomponents: []
+  target: {{ b64enc "provider-py"}}.1
+  targetcomponents: []
+  id: {{ b64enc "e2e-service-consumer" }}.1-{{ b64enc "provider-py"}}.1
+  detectpoints:
+    - CLIENT
+    - SERVER
+{{- end }}
diff --git a/test/e2e-v2/script/env b/test/e2e-v2/cases/python/expected/metrics-has-value.yml
similarity index 67%
copy from test/e2e-v2/script/env
copy to test/e2e-v2/cases/python/expected/metrics-has-value.yml
index 6f9f924..5359e6d 100644
--- a/test/e2e-v2/script/env
+++ b/test/e2e-v2/cases/python/expected/metrics-has-value.yml
@@ -13,10 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-SW_AGENT_JAVA_COMMIT=3997f0256056788bd054ee37e4603c11c0fd6756
-SW_AGENT_SATELLITE_COMMIT=1f3c08a5af19f8522f2a40d9339c45fa816bfe07
-SW_AGENT_NGINX_LUA_COMMIT=c3cee4841798a147d83b96a10914d4ac0e11d0aa
-SW_AGENT_NODEJS_COMMIT=e755659c7f308d3b5589619778c8360308cb14f8
-SW_AGENT_GO_COMMIT=4af380c2db6243106b0fc650b6003ce3b3eb82a0
-
-SW_CTL_COMMIT=b90255132f916f53eb90955cc8a6445b03a4bec3
+{{- contains . }}
+- key: {{ notEmpty .key }}
+  value: {{ ge .value 1 }}
+{{- end }}
diff --git a/test/e2e-v2/script/env b/test/e2e-v2/cases/python/expected/service-endpoint-consumer-java.yml
similarity index 67%
copy from test/e2e-v2/script/env
copy to test/e2e-v2/cases/python/expected/service-endpoint-consumer-java.yml
index 6f9f924..cedf79a 100644
--- a/test/e2e-v2/script/env
+++ b/test/e2e-v2/cases/python/expected/service-endpoint-consumer-java.yml
@@ -13,10 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-SW_AGENT_JAVA_COMMIT=3997f0256056788bd054ee37e4603c11c0fd6756
-SW_AGENT_SATELLITE_COMMIT=1f3c08a5af19f8522f2a40d9339c45fa816bfe07
-SW_AGENT_NGINX_LUA_COMMIT=c3cee4841798a147d83b96a10914d4ac0e11d0aa
-SW_AGENT_NODEJS_COMMIT=e755659c7f308d3b5589619778c8360308cb14f8
-SW_AGENT_GO_COMMIT=4af380c2db6243106b0fc650b6003ce3b3eb82a0
-
-SW_CTL_COMMIT=b90255132f916f53eb90955cc8a6445b03a4bec3
+{{- contains . }}
+- id: {{ b64enc "e2e-service-consumer" }}.1_{{ b64enc "POST:/users" }}
+  name: POST:/users
+{{- end}}
diff --git a/test/e2e-v2/script/env b/test/e2e-v2/cases/python/expected/service-endpoint-consumer-py.yml
similarity index 67%
copy from test/e2e-v2/script/env
copy to test/e2e-v2/cases/python/expected/service-endpoint-consumer-py.yml
index 6f9f924..0e1a744 100644
--- a/test/e2e-v2/script/env
+++ b/test/e2e-v2/cases/python/expected/service-endpoint-consumer-py.yml
@@ -13,10 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-SW_AGENT_JAVA_COMMIT=3997f0256056788bd054ee37e4603c11c0fd6756
-SW_AGENT_SATELLITE_COMMIT=1f3c08a5af19f8522f2a40d9339c45fa816bfe07
-SW_AGENT_NGINX_LUA_COMMIT=c3cee4841798a147d83b96a10914d4ac0e11d0aa
-SW_AGENT_NODEJS_COMMIT=e755659c7f308d3b5589619778c8360308cb14f8
-SW_AGENT_GO_COMMIT=4af380c2db6243106b0fc650b6003ce3b3eb82a0
-
-SW_CTL_COMMIT=b90255132f916f53eb90955cc8a6445b03a4bec3
+{{- contains . }}
+- id: {{ b64enc "consumer-py" }}.1_{{ b64enc "/test" }}
+  name: /test
+{{- end}}
diff --git a/test/e2e-v2/script/env b/test/e2e-v2/cases/python/expected/service-endpoint-provider-py-kafka.yml
similarity index 67%
copy from test/e2e-v2/script/env
copy to test/e2e-v2/cases/python/expected/service-endpoint-provider-py-kafka.yml
index 6f9f924..408a063 100644
--- a/test/e2e-v2/script/env
+++ b/test/e2e-v2/cases/python/expected/service-endpoint-provider-py-kafka.yml
@@ -13,10 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-SW_AGENT_JAVA_COMMIT=3997f0256056788bd054ee37e4603c11c0fd6756
-SW_AGENT_SATELLITE_COMMIT=1f3c08a5af19f8522f2a40d9339c45fa816bfe07
-SW_AGENT_NGINX_LUA_COMMIT=c3cee4841798a147d83b96a10914d4ac0e11d0aa
-SW_AGENT_NODEJS_COMMIT=e755659c7f308d3b5589619778c8360308cb14f8
-SW_AGENT_GO_COMMIT=4af380c2db6243106b0fc650b6003ce3b3eb82a0
-
-SW_CTL_COMMIT=b90255132f916f53eb90955cc8a6445b03a4bec3
+{{- contains . }}
+- id: {{ b64enc "provider-py-kafka" }}.1_{{ b64enc "/users" }}
+  name: /users
+{{- end}}
diff --git a/test/e2e-v2/script/env b/test/e2e-v2/cases/python/expected/service-endpoint-provider-py.yml
similarity index 67%
copy from test/e2e-v2/script/env
copy to test/e2e-v2/cases/python/expected/service-endpoint-provider-py.yml
index 6f9f924..2ce230d 100644
--- a/test/e2e-v2/script/env
+++ b/test/e2e-v2/cases/python/expected/service-endpoint-provider-py.yml
@@ -13,10 +13,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-SW_AGENT_JAVA_COMMIT=3997f0256056788bd054ee37e4603c11c0fd6756
-SW_AGENT_SATELLITE_COMMIT=1f3c08a5af19f8522f2a40d9339c45fa816bfe07
-SW_AGENT_NGINX_LUA_COMMIT=c3cee4841798a147d83b96a10914d4ac0e11d0aa
-SW_AGENT_NODEJS_COMMIT=e755659c7f308d3b5589619778c8360308cb14f8
-SW_AGENT_GO_COMMIT=4af380c2db6243106b0fc650b6003ce3b3eb82a0
-
-SW_CTL_COMMIT=b90255132f916f53eb90955cc8a6445b03a4bec3
+{{- contains . }}
+- id: {{ b64enc "provider-py" }}.1_{{ b64enc "/users" }}
+  name: /users
+{{- end}}
diff --git a/test/e2e-v2/cases/python/expected/service-instance-consumer-java.yml b/test/e2e-v2/cases/python/expected/service-instance-consumer-java.yml
new file mode 100644
index 0000000..7d1d199
--- /dev/null
+++ b/test/e2e-v2/cases/python/expected/service-instance-consumer-java.yml
@@ -0,0 +1,40 @@
+# Licensed to Apache Software Foundation (ASF) under one or more contributor
+# license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright
+# ownership. Apache Software Foundation (ASF) licenses this file to you 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.
+
+{{- contains . }}
+- id: {{ b64enc "e2e-service-consumer" }}.1_{{ b64enc "consumer1" }}
+  name: consumer1
+  attributes:
+  {{- contains .attributes }}
+  - name: OS Name
+    value: Linux
+  - name: hostname
+    value: {{ notEmpty .value }}
+  - name: Process No.
+    value: "1"
+  - name: Start Time
+    value: {{ notEmpty .value }}
+  - name: JVM Arguments
+    value: '{{ notEmpty .value }}'
+  - name: Jar Dependencies
+    value: '{{ notEmpty .value }}'
+  - name: ipv4s
+    value: {{ notEmpty .value }}
+  {{- end}}
+  language: JAVA
+  instanceuuid: {{ b64enc "e2e-service-consumer" }}.1_{{ b64enc "consumer1" }}
+{{- end}}
diff --git a/test/e2e-v2/cases/python/expected/service-instance-consumer-py.yml b/test/e2e-v2/cases/python/expected/service-instance-consumer-py.yml
new file mode 100644
index 0000000..937a69a
--- /dev/null
+++ b/test/e2e-v2/cases/python/expected/service-instance-consumer-py.yml
@@ -0,0 +1,28 @@
+# Licensed to Apache Software Foundation (ASF) under one or more contributor
+# license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright
+# ownership. Apache Software Foundation (ASF) licenses this file to you 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. shadow
+
+{{- contains .}}
+- id: {{ b64enc "consumer-py" }}.1_{{ b64enc "consumer-py-instance" }}
+  name: consumer-py-instance
+  attributes:
+  {{- contains .attributes }}
+  - name: ipv4s
+    value: ""
+  {{- end}}
+  language: UNKNOWN
+  instanceuuid: {{ b64enc "consumer-py" }}.1_{{ b64enc "consumer-py-instance" }}
+{{- end}}
diff --git a/test/e2e-v2/cases/python/expected/service-instance-provider-py-kafka.yml b/test/e2e-v2/cases/python/expected/service-instance-provider-py-kafka.yml
new file mode 100644
index 0000000..ee7870c
--- /dev/null
+++ b/test/e2e-v2/cases/python/expected/service-instance-provider-py-kafka.yml
@@ -0,0 +1,28 @@
+# Licensed to Apache Software Foundation (ASF) under one or more contributor
+# license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright
+# ownership. Apache Software Foundation (ASF) licenses this file to you 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. shadow
+
+{{- contains .}}
+- id: {{ b64enc "provider-py-kafka" }}.1_{{ b64enc "provider-py-kafka-instance" }}
+  name: provider-py-kafka-instance
+  attributes:
+  {{- contains .attributes }}
+  - name: ipv4s
+    value: ""
+  {{- end}}
+  language: UNKNOWN
+  instanceuuid: {{ b64enc "provider-py-kafka" }}.1_{{ b64enc "provider-py-kafka-instance" }}
+{{- end}}
diff --git a/test/e2e-v2/cases/python/expected/service-instance-provider-py.yml b/test/e2e-v2/cases/python/expected/service-instance-provider-py.yml
new file mode 100644
index 0000000..53c2518
--- /dev/null
+++ b/test/e2e-v2/cases/python/expected/service-instance-provider-py.yml
@@ -0,0 +1,28 @@
+# Licensed to Apache Software Foundation (ASF) under one or more contributor
+# license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright
+# ownership. Apache Software Foundation (ASF) licenses this file to you 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. shadow
+
+{{- contains .}}
+- id: {{ b64enc "provider-py" }}.1_{{ b64enc "provider-py-instance" }}
+  name: provider-py-instance
+  attributes:
+  {{- contains .attributes }}
+  - name: ipv4s
+    value: ""
+  {{- end}}
+  language: UNKNOWN
+  instanceuuid: {{ b64enc "provider-py" }}.1_{{ b64enc "provider-py-instance" }}
+{{- end}}
diff --git a/test/e2e-v2/script/env b/test/e2e-v2/cases/python/expected/service.yml
similarity index 67%
copy from test/e2e-v2/script/env
copy to test/e2e-v2/cases/python/expected/service.yml
index 6f9f924..23c736d 100644
--- a/test/e2e-v2/script/env
+++ b/test/e2e-v2/cases/python/expected/service.yml
@@ -13,10 +13,17 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-SW_AGENT_JAVA_COMMIT=3997f0256056788bd054ee37e4603c11c0fd6756
-SW_AGENT_SATELLITE_COMMIT=1f3c08a5af19f8522f2a40d9339c45fa816bfe07
-SW_AGENT_NGINX_LUA_COMMIT=c3cee4841798a147d83b96a10914d4ac0e11d0aa
-SW_AGENT_NODEJS_COMMIT=e755659c7f308d3b5589619778c8360308cb14f8
-SW_AGENT_GO_COMMIT=4af380c2db6243106b0fc650b6003ce3b3eb82a0
-
-SW_CTL_COMMIT=b90255132f916f53eb90955cc8a6445b03a4bec3
+{{- contains . }}
+- id: {{ b64enc "provider-py" }}.1
+  name: provider-py
+  group: ""
+- id: {{ b64enc "e2e-service-consumer" }}.1
+  name: e2e-service-consumer
+  group: ""
+- id: {{ b64enc "consumer-py" }}.1
+  name: consumer-py
+  group: ""
+- id: {{ b64enc "provider-py-kafka" }}.1
+  name: provider-py-kafka
+  group: ""
+{{- end }}
diff --git a/test/e2e-v2/cases/python/expected/trace-test-detail.yml b/test/e2e-v2/cases/python/expected/trace-test-detail.yml
new file mode 100644
index 0000000..55bdf90
--- /dev/null
+++ b/test/e2e-v2/cases/python/expected/trace-test-detail.yml
@@ -0,0 +1,195 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+spans:
+  {{- contains .spans }}
+  - traceid: {{ notEmpty .traceid }}
+    segmentid: {{ notEmpty .segmentid }}
+    spanid: {{ .spanid }}
+    parentspanid: {{ .parentspanid }}
+    refs: []
+    servicecode: consumer-py
+    serviceinstancename: consumer-py-instance
+    starttime: {{ gt .starttime 0 }}
+    endtime: {{ gt .endtime 0 }}
+    endpointname: /test
+    type: Entry
+    peer: {{ notEmpty .peer }}
+    component: Python
+    iserror: false
+    layer: Http
+    tags:
+      {{- contains .tags }}
+      - key: http.method
+        value: POST
+      {{- end }}
+    logs: []
+  - traceid: {{ notEmpty .traceid }}
+    segmentid: {{ notEmpty .segmentid }}
+    spanid: {{ .spanid }}
+    parentspanid: {{ .parentspanid }}
+    refs: []
+    servicecode: consumer-py
+    serviceinstancename: consumer-py-instance
+    starttime: {{ gt .starttime 0 }}
+    endtime: {{ gt .endtime 0 }}
+    endpointname: /users
+    type: Exit
+    peer: medium-java:9092
+    component: Python
+    iserror: false
+    layer: Http
+    tags:
+      {{- contains .tags }}
+      - key: http.method
+        value: POST
+      - key: url
+        value: http://medium-java:9092/users
+      - key: status.code
+        value: "200"
+      {{- end }}
+    logs: []
+  - traceid: {{ notEmpty .traceid }}
+    segmentid: {{ notEmpty .segmentid }}
+    spanid: {{ .spanid }}
+    parentspanid: {{ .parentspanid }}
+    refs:
+      {{- contains .refs }}
+      - traceid: {{ notEmpty .traceid }}
+        parentsegmentid: {{ .parentsegmentid }}
+        parentspanid: {{ .parentspanid }}
+        type: CROSS_PROCESS
+      {{- end }}
+    servicecode: e2e-service-consumer
+    serviceinstancename: consumer1
+    starttime: {{ gt .starttime 0 }}
+    endtime: {{ gt .endtime 0 }}
+    endpointname: POST:/users
+    type: Entry
+    peer: ""
+    component: Tomcat
+    iserror: false
+    layer: Http
+    tags:
+      {{- contains .tags }}
+      - key: url
+        value: http://medium-java:9092/users
+      - key: http.method
+        value: POST
+      {{- end }}
+    logs: []
+  - traceid: {{ notEmpty .traceid }}
+    segmentid: {{ notEmpty .segmentid }}
+    spanid: {{ .spanid }}
+    parentspanid: {{ .parentspanid }}
+    refs: []
+    servicecode: e2e-service-consumer
+    serviceinstancename: consumer1
+    starttime: {{ gt .starttime 0 }}
+    endtime: {{ gt .endtime 0 }}
+    endpointname: /users
+    type: Exit
+    peer: provider-py:9091
+    component: SpringRestTemplate
+    iserror: false
+    layer: Http
+    tags:
+      {{- contains .tags }}
+      - key: url
+        value: http://provider-py:9091/users
+      - key: http.method
+        value: POST
+      {{- end }}
+    logs: []
+  - traceid: {{ notEmpty .traceid }}
+    segmentid: {{ notEmpty .segmentid }}
+    spanid: {{ .spanid }}
+    parentspanid: {{ .parentspanid }}
+    refs:
+      {{- contains .refs }}
+      - traceid: {{ notEmpty .traceid }}
+        parentsegmentid: {{ .parentsegmentid }}
+        parentspanid: {{ .parentspanid }}
+        type: CROSS_PROCESS
+      {{- end }}
+    servicecode: provider-py
+    serviceinstancename: provider-py-instance
+    starttime: {{ gt .starttime 0 }}
+    endtime: {{ gt .endtime 0 }}
+    endpointname: /users
+    type: Entry
+    peer: {{ notEmpty .peer }}
+    component: Python
+    iserror: false
+    layer: Http
+    tags:
+      {{- contains .tags }}
+      - key: http.method
+        value: POST
+      {{- end }}
+    logs: []
+  - traceid: {{ notEmpty .traceid }}
+    segmentid: {{ notEmpty .segmentid }}
+    spanid: {{ .spanid }}
+    parentspanid: {{ .parentspanid }}
+    refs: []
+    servicecode: consumer-py
+    serviceinstancename: consumer-py-instance
+    starttime: {{ gt .starttime 0 }}
+    endtime: {{ gt .endtime 0 }}
+    endpointname: /users
+    type: Exit
+    peer: provider-py-kafka:9089
+    component: Python
+    iserror: false
+    layer: Http
+    tags:
+      {{- contains .tags }}
+      - key: http.method
+        value: POST
+      - key: url
+        value: http://provider-py-kafka:9089/users
+      - key: status.code
+        value: "200"
+      {{- end }}
+    logs: []
+  - traceid: {{ notEmpty .traceid }}
+    segmentid: {{ notEmpty .segmentid }}
+    spanid: {{ .spanid }}
+    parentspanid: {{ .parentspanid }}
+    refs:
+      {{- contains .refs }}
+      - traceid: {{ notEmpty .traceid }}
+        parentsegmentid: {{ .parentsegmentid }}
+        parentspanid: {{ .parentspanid }}
+        type: CROSS_PROCESS
+      {{- end }}
+    servicecode: provider-py-kafka
+    serviceinstancename: provider-py-kafka-instance
+    starttime: {{ gt .starttime 0 }}
+    endtime: {{ gt .endtime 0 }}
+    endpointname: /users
+    type: Entry
+    peer: {{ notEmpty .peer }}
+    component: Python
+    iserror: false
+    layer: Http
+    tags:
+      {{- contains .tags }}
+      - key: http.method
+        value: POST
+      {{- end }}
+    logs: []
+  {{- end }}
diff --git a/test/e2e-v2/script/env b/test/e2e-v2/cases/python/expected/traces-list-consumer-java.yml
similarity index 67%
copy from test/e2e-v2/script/env
copy to test/e2e-v2/cases/python/expected/traces-list-consumer-java.yml
index 6f9f924..1864c1a 100644
--- a/test/e2e-v2/script/env
+++ b/test/e2e-v2/cases/python/expected/traces-list-consumer-java.yml
@@ -13,10 +13,15 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-SW_AGENT_JAVA_COMMIT=3997f0256056788bd054ee37e4603c11c0fd6756
-SW_AGENT_SATELLITE_COMMIT=1f3c08a5af19f8522f2a40d9339c45fa816bfe07
-SW_AGENT_NGINX_LUA_COMMIT=c3cee4841798a147d83b96a10914d4ac0e11d0aa
-SW_AGENT_NODEJS_COMMIT=e755659c7f308d3b5589619778c8360308cb14f8
-SW_AGENT_GO_COMMIT=4af380c2db6243106b0fc650b6003ce3b3eb82a0
-
-SW_CTL_COMMIT=b90255132f916f53eb90955cc8a6445b03a4bec3
+traces:
+{{- contains .traces }}
+- segmentid: {{ notEmpty .segmentid }}
+  endpointnames:
+    - POST:/users
+  duration: {{ ge .duration 0 }}
+  start: "{{ notEmpty .start}}"
+  iserror: false
+  traceids:
+    - {{ (index .traceids 0) }}
+{{- end }}
+total: {{ gt .total 0 }}
diff --git a/test/e2e-v2/script/env b/test/e2e-v2/cases/python/expected/traces-list-consumer-py.yml
similarity index 67%
copy from test/e2e-v2/script/env
copy to test/e2e-v2/cases/python/expected/traces-list-consumer-py.yml
index 6f9f924..f3b624f 100644
--- a/test/e2e-v2/script/env
+++ b/test/e2e-v2/cases/python/expected/traces-list-consumer-py.yml
@@ -13,10 +13,15 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-SW_AGENT_JAVA_COMMIT=3997f0256056788bd054ee37e4603c11c0fd6756
-SW_AGENT_SATELLITE_COMMIT=1f3c08a5af19f8522f2a40d9339c45fa816bfe07
-SW_AGENT_NGINX_LUA_COMMIT=c3cee4841798a147d83b96a10914d4ac0e11d0aa
-SW_AGENT_NODEJS_COMMIT=e755659c7f308d3b5589619778c8360308cb14f8
-SW_AGENT_GO_COMMIT=4af380c2db6243106b0fc650b6003ce3b3eb82a0
-
-SW_CTL_COMMIT=b90255132f916f53eb90955cc8a6445b03a4bec3
+traces:
+{{- contains .traces }}
+- segmentid: {{ notEmpty .segmentid }}
+  endpointnames:
+    - /test
+  duration: {{ ge .duration 0 }}
+  start: "{{ notEmpty .start}}"
+  iserror: false
+  traceids:
+    - {{ (index .traceids 0) }}
+{{- end }}
+total: {{ gt .total 0 }}
diff --git a/test/e2e-v2/script/env b/test/e2e-v2/cases/python/expected/traces-list-provider-py-kafka.yml
similarity index 67%
copy from test/e2e-v2/script/env
copy to test/e2e-v2/cases/python/expected/traces-list-provider-py-kafka.yml
index 6f9f924..2e5d158 100644
--- a/test/e2e-v2/script/env
+++ b/test/e2e-v2/cases/python/expected/traces-list-provider-py-kafka.yml
@@ -13,10 +13,15 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-SW_AGENT_JAVA_COMMIT=3997f0256056788bd054ee37e4603c11c0fd6756
-SW_AGENT_SATELLITE_COMMIT=1f3c08a5af19f8522f2a40d9339c45fa816bfe07
-SW_AGENT_NGINX_LUA_COMMIT=c3cee4841798a147d83b96a10914d4ac0e11d0aa
-SW_AGENT_NODEJS_COMMIT=e755659c7f308d3b5589619778c8360308cb14f8
-SW_AGENT_GO_COMMIT=4af380c2db6243106b0fc650b6003ce3b3eb82a0
-
-SW_CTL_COMMIT=b90255132f916f53eb90955cc8a6445b03a4bec3
+traces:
+{{- contains .traces }}
+- segmentid: {{ notEmpty .segmentid }}
+  endpointnames:
+    - /users
+  duration: {{ ge .duration 0 }}
+  start: "{{ notEmpty .start}}"
+  iserror: false
+  traceids:
+    - {{ (index .traceids 0) }}
+{{- end }}
+total: {{ gt .total 0 }}
diff --git a/test/e2e-v2/script/env b/test/e2e-v2/cases/python/expected/traces-list-provider-py.yml
similarity index 67%
copy from test/e2e-v2/script/env
copy to test/e2e-v2/cases/python/expected/traces-list-provider-py.yml
index 6f9f924..2e5d158 100644
--- a/test/e2e-v2/script/env
+++ b/test/e2e-v2/cases/python/expected/traces-list-provider-py.yml
@@ -13,10 +13,15 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-SW_AGENT_JAVA_COMMIT=3997f0256056788bd054ee37e4603c11c0fd6756
-SW_AGENT_SATELLITE_COMMIT=1f3c08a5af19f8522f2a40d9339c45fa816bfe07
-SW_AGENT_NGINX_LUA_COMMIT=c3cee4841798a147d83b96a10914d4ac0e11d0aa
-SW_AGENT_NODEJS_COMMIT=e755659c7f308d3b5589619778c8360308cb14f8
-SW_AGENT_GO_COMMIT=4af380c2db6243106b0fc650b6003ce3b3eb82a0
-
-SW_CTL_COMMIT=b90255132f916f53eb90955cc8a6445b03a4bec3
+traces:
+{{- contains .traces }}
+- segmentid: {{ notEmpty .segmentid }}
+  endpointnames:
+    - /users
+  duration: {{ ge .duration 0 }}
+  start: "{{ notEmpty .start}}"
+  iserror: false
+  traceids:
+    - {{ (index .traceids 0) }}
+{{- end }}
+total: {{ gt .total 0 }}
diff --git a/test/e2e-v2/cases/python/provider-kafka.py b/test/e2e-v2/cases/python/provider-kafka.py
new file mode 100644
index 0000000..96a5390
--- /dev/null
+++ b/test/e2e-v2/cases/python/provider-kafka.py
@@ -0,0 +1,47 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 time
+
+from urllib import request
+
+from skywalking import agent, config
+
+if __name__ == '__main__':
+    config.service_name = 'provider-py-kafka'
+    config.logging_level = 'DEBUG'
+    config.protocol = "kafka"
+    agent.start()
+
+    import socketserver
+    from http.server import BaseHTTPRequestHandler
+
+    class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
+
+        def do_POST(self):
+            time.sleep(0.15)
+            self.send_response(200)
+            self.send_header('Content-Type', 'application/json')
+            self.end_headers()
+            self.wfile.write('{"name": "whatever"}'.encode('ascii'))
+
+    PORT = 9089
+    Handler = SimpleHTTPRequestHandler
+
+    with socketserver.TCPServer(("", PORT), Handler) as httpd:
+        print("serving at port", PORT)
+        httpd.serve_forever()
diff --git a/test/e2e-v2/cases/python/provider.py b/test/e2e-v2/cases/python/provider.py
new file mode 100644
index 0000000..ff0ee5b
--- /dev/null
+++ b/test/e2e-v2/cases/python/provider.py
@@ -0,0 +1,46 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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 time
+
+from urllib import request
+
+from skywalking import agent, config
+
+if __name__ == '__main__':
+    config.service_name = 'provider-py'
+    config.logging_level = 'DEBUG'
+    agent.start()
+
+    import socketserver
+    from http.server import BaseHTTPRequestHandler
+
+    class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
+
+        def do_POST(self):
+            time.sleep(0.5)
+            self.send_response(200)
+            self.send_header('Content-Type', 'application/json')
+            self.end_headers()
+            self.wfile.write('{"name": "whatever"}'.encode('ascii'))
+
+    PORT = 9091
+    Handler = SimpleHTTPRequestHandler
+
+    with socketserver.TCPServer(("", PORT), Handler) as httpd:
+        print("serving at port", PORT)
+        httpd.serve_forever()
diff --git a/test/e2e-v2/script/env b/test/e2e-v2/script/env
index 6f9f924..3f33578 100644
--- a/test/e2e-v2/script/env
+++ b/test/e2e-v2/script/env
@@ -18,5 +18,6 @@ SW_AGENT_SATELLITE_COMMIT=1f3c08a5af19f8522f2a40d9339c45fa816bfe07
 SW_AGENT_NGINX_LUA_COMMIT=c3cee4841798a147d83b96a10914d4ac0e11d0aa
 SW_AGENT_NODEJS_COMMIT=e755659c7f308d3b5589619778c8360308cb14f8
 SW_AGENT_GO_COMMIT=4af380c2db6243106b0fc650b6003ce3b3eb82a0
+SW_AGENT_PYTHON_COMMIT=50388c55428d742d73d9733278f04173585de80d
 
 SW_CTL_COMMIT=b90255132f916f53eb90955cc8a6445b03a4bec3