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 2022/04/20 04:46:46 UTC

[skywalking-nginx-lua] branch master updated: improve e2e test (#103)

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-nginx-lua.git


The following commit(s) were added to refs/heads/master by this push:
     new df615f5  improve e2e test (#103)
df615f5 is described below

commit df615f566cb05cec02d800db1421777461d48f19
Author: Daming <zt...@foxmail.com>
AuthorDate: Wed Apr 20 12:46:41 2022 +0800

    improve e2e test (#103)
---
 .github/workflows/e2e.yaml                         |  29 ++-
 test/e2e/{nginx/docker/bin/startup.sh => .env}     |   9 +-
 .github/workflows/e2e.yaml => test/e2e/Dockerfile  |  34 +--
 test/e2e/docker-compose.yml                        | 134 +++++++++++
 .../e2e.yaml => test/e2e/nginx/Dockerfile          |  36 +--
 test/e2e/nginx/{docker => }/conf.d/nginx.conf      |  33 +--
 test/e2e/nginx/pom.xml                             | 121 ----------
 .../apache/skywalking/e2e/DataAssertITCase.java    |  97 --------
 .../e2e/nginx/src/test/resources/expectedData.yaml |  91 -------
 test/e2e/pom.xml                                   | 265 ---------------------
 .../workflows/e2e.yaml => test/e2e/user/Dockerfile |  31 +--
 test/e2e/user/execute_and_validate.sh              |  49 ++++
 test/e2e/user/expectedData.yaml                    | 158 ++++++++++++
 13 files changed, 387 insertions(+), 700 deletions(-)

diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml
index a92f025..10de749 100644
--- a/.github/workflows/e2e.yaml
+++ b/.github/workflows/e2e.yaml
@@ -19,26 +19,29 @@ name: E2E
 on:
   pull_request:
   push:
-    branches: 
+    branches:
       - master
     tags:
       - 'v*'
 
 jobs:
   nginx:
-    runs-on: ubuntu-18.04
-    timeout-minutes: 180
+    runs-on: ubuntu-latest
+    timeout-minutes: 20
     steps:
-      - uses: actions/checkout@v2
-      - name: checkout submodules
-        shell: bash
-        run: |
-          git submodule sync --recursive
-          git -c protocol.version=2 submodule update --init --force --recursive --depth=1
+      - uses: actions/checkout@v3
+        with:
+          submodules: true
       - uses: actions/setup-java@v1
         with:
           java-version: 8
-      - name: Set environment
-        run: export MAVEN_OPTS='-Dmaven.repo.local=~/.m2/repository -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -XX:-UseGCOverheadLimit -Xmx3g'
-      - name: Run Nginx Test
-        run: ./mvnw -f ./test/e2e/pom.xml verify
+      - run: |
+          docker-compose --env-file ./test/e2e/.env -f ./test/e2e/docker-compose.yml run -d user
+          docker wait $(docker ps -qa --filter Name=e2e_user)
+          status="$?"
+          docker-compose -f ./test/e2e/docker-compose.yml logs
+          if [ $status -eq 0 ]; then
+            docker cp "$(docker ps -qa --filter Name=e2e_user):/response" ./response
+            cat ./response
+          fi
+          docker-compose -f ./test/e2e/docker-compose.yml kill
diff --git a/test/e2e/nginx/docker/bin/startup.sh b/test/e2e/.env
similarity index 72%
rename from test/e2e/nginx/docker/bin/startup.sh
rename to test/e2e/.env
index 3fa9a86..f264177 100644
--- a/test/e2e/nginx/docker/bin/startup.sh
+++ b/test/e2e/.env
@@ -1,4 +1,3 @@
-#!/bin/bash
 # 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
@@ -16,9 +15,5 @@
 # specific language governing permissions and limitations
 # under the License.
 
-COLLECTOR=$(grep "skywalking-collector" /etc/hosts |awk -F" " '{print $1}')
-sed -e "s%\${collector}%${COLLECTOR}%g" /var/nginx/conf.d/nginx.conf > /var/run/nginx.conf
-
-luarocks make /skywalking-nginx-lua/rockspec/skywalking-nginx-lua-master-0.rockspec
-
-openresty -c /var/run/nginx.conf
+E2E_SERVICE_VERSION=34a4553e23530e8255efe6f5a0adff9e69555d64
+MOCK_COLLECTOR_VERSION=092c6a3c753684b5a301baf5bcb1965f2dfaf79d
\ No newline at end of file
diff --git a/.github/workflows/e2e.yaml b/test/e2e/Dockerfile
similarity index 50%
copy from .github/workflows/e2e.yaml
copy to test/e2e/Dockerfile
index a92f025..6659e3c 100644
--- a/.github/workflows/e2e.yaml
+++ b/test/e2e/Dockerfile
@@ -14,31 +14,13 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-name: E2E
+ARG E2E_SERVICE_NAME
+ARG E2E_SERVICE_VERSION
 
-on:
-  pull_request:
-  push:
-    branches: 
-      - master
-    tags:
-      - 'v*'
+FROM ghcr.io/apache/skywalking/${E2E_SERVICE_NAME}:${E2E_SERVICE_VERSION}
+FROM apache/skywalking-java-agent:8.10.0-java8
 
-jobs:
-  nginx:
-    runs-on: ubuntu-18.04
-    timeout-minutes: 180
-    steps:
-      - uses: actions/checkout@v2
-      - name: checkout submodules
-        shell: bash
-        run: |
-          git submodule sync --recursive
-          git -c protocol.version=2 submodule update --init --force --recursive --depth=1
-      - uses: actions/setup-java@v1
-        with:
-          java-version: 8
-      - name: Set environment
-        run: export MAVEN_OPTS='-Dmaven.repo.local=~/.m2/repository -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -XX:-UseGCOverheadLimit -Xmx3g'
-      - name: Run Nginx Test
-        run: ./mvnw -f ./test/e2e/pom.xml verify
+COPY --from=0 /app.jar /app.jar
+
+ENV JAVA_TOOL_OPTIONS=-javaagent:/skywalking/agent/skywalking-agent.jar
+CMD ["java", "-jar", "/app.jar"]
diff --git a/test/e2e/docker-compose.yml b/test/e2e/docker-compose.yml
new file mode 100644
index 0000000..c6e0e20
--- /dev/null
+++ b/test/e2e/docker-compose.yml
@@ -0,0 +1,134 @@
+# 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:
+  skywalking-collector:
+    image: ghcr.io/apache/skywalking-agent-test-tool/mock-collector:${MOCK_COLLECTOR_VERSION}
+    expose:
+      - 19876
+      - 12800
+    ports:
+      - 12800:12800
+    restart: on-failure
+    healthcheck:
+      test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/12800"]
+      interval: 5s
+      timeout: 60s
+      retries: 120
+    networks:
+      e2e:
+        ipv4_address: 172.16.238.10
+
+  nginx:
+    build:
+      context: ../../
+      dockerfile: ./test/e2e/nginx/Dockerfile
+    expose:
+      - 8080
+    networks:
+      e2e:
+        ipv4_address: 172.16.238.11
+    depends_on:
+      skywalking-collector:
+        condition: service_healthy
+    healthcheck:
+      test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/8080"]
+      interval: 5s
+      timeout: 60s
+      retries: 120
+
+  provider:
+    build:
+      context: ./
+      args:
+        E2E_SERVICE_NAME: e2e-service-provider
+        E2E_SERVICE_VERSION: ${E2E_SERVICE_VERSION}
+    networks:
+      e2e:
+        ipv4_address: 172.16.238.12
+    expose:
+      - 9090
+    environment:
+      SW_AGENT_COLLECTOR_BACKEND_SERVICES: skywalking-collector:19876
+      SW_LOGGING_OUTPUT: CONSOLE
+      SW_AGENT_NAME: e2e-service-provider
+      SW_AGENT_INSTANCE_NAME: provider1
+    depends_on:
+      skywalking-collector:
+        condition: service_healthy
+    healthcheck:
+      test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/9090"]
+      interval: 5s
+      timeout: 60s
+      retries: 120
+
+  consumer:
+    build:
+      context: ./
+      args:
+        E2E_SERVICE_NAME: e2e-service-consumer
+        E2E_SERVICE_VERSION: ${E2E_SERVICE_VERSION}
+    networks:
+      e2e:
+        ipv4_address: 172.16.238.13
+    expose:
+      - 9092
+    environment:
+      SW_AGENT_COLLECTOR_BACKEND_SERVICES: skywalking-collector:19876
+      SW_LOGGING_OUTPUT: CONSOLE
+      PROVIDER_URL: http://nginx:8080
+      SW_AGENT_NAME: e2e-service-consumer
+      SW_AGENT_INSTANCE_NAME: consumer1
+    depends_on:
+      skywalking-collector:
+        condition: service_healthy
+      nginx:
+        condition: service_healthy
+      provider:
+        condition: service_healthy
+    healthcheck:
+      test: ["CMD", "bash", "-c", "cat < /dev/null > /dev/tcp/127.0.0.1/9092"]
+      interval: 5s
+      timeout: 60s
+      retries: 120
+
+  user:
+    build:
+      context: ./user
+    volumes:
+      - ./user/expectedData.yaml:/expectedData.yaml
+    environment:
+      MAX_RETRY_TIMES: 3
+      SUFFIX_ENTRY: http://nginx:8080/suffix
+      SERVICE_ENTRY: http://consumer:9092/info
+      VALIDATION_ENTRY: http://skywalking-collector:12800/dataValidate
+    networks:
+      e2e:
+        ipv4_address: 172.16.238.14
+    depends_on:
+      consumer:
+        condition: service_healthy
+      skywalking-collector:
+        condition: service_healthy
+
+networks:
+  e2e:
+    driver: bridge
+    ipam:
+      driver: default
+      config:
+        - subnet: 172.16.238.0/24
+          gateway: 172.16.238.1
diff --git a/.github/workflows/e2e.yaml b/test/e2e/nginx/Dockerfile
similarity index 50%
copy from .github/workflows/e2e.yaml
copy to test/e2e/nginx/Dockerfile
index a92f025..8eb4af4 100644
--- a/.github/workflows/e2e.yaml
+++ b/test/e2e/nginx/Dockerfile
@@ -14,31 +14,15 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-name: E2E
+FROM openresty/openresty:1.17.8.2-5-alpine-fat
 
-on:
-  pull_request:
-  push:
-    branches: 
-      - master
-    tags:
-      - 'v*'
+WORKDIR /skywalking-nginx-lua
 
-jobs:
-  nginx:
-    runs-on: ubuntu-18.04
-    timeout-minutes: 180
-    steps:
-      - uses: actions/checkout@v2
-      - name: checkout submodules
-        shell: bash
-        run: |
-          git submodule sync --recursive
-          git -c protocol.version=2 submodule update --init --force --recursive --depth=1
-      - uses: actions/setup-java@v1
-        with:
-          java-version: 8
-      - name: Set environment
-        run: export MAVEN_OPTS='-Dmaven.repo.local=~/.m2/repository -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -XX:-UseGCOverheadLimit -Xmx3g'
-      - name: Run Nginx Test
-        run: ./mvnw -f ./test/e2e/pom.xml verify
+COPY ./lib ./lib
+COPY ./rockspec ./rockspec
+COPY ./Makefile ./Makefile
+COPY ./test/e2e/nginx/conf.d/nginx.conf ./conf.d/nginx.conf
+
+RUN luarocks make rockspec/skywalking-nginx-lua-master-0.rockspec
+
+CMD ["/bin/bash", "-c", "openresty -c /skywalking-nginx-lua/conf.d/nginx.conf"]
diff --git a/test/e2e/nginx/docker/conf.d/nginx.conf b/test/e2e/nginx/conf.d/nginx.conf
similarity index 76%
rename from test/e2e/nginx/docker/conf.d/nginx.conf
rename to test/e2e/nginx/conf.d/nginx.conf
index 483f3f8..9c09238 100644
--- a/test/e2e/nginx/docker/conf.d/nginx.conf
+++ b/test/e2e/nginx/conf.d/nginx.conf
@@ -34,14 +34,14 @@ http {
     init_worker_by_lua_block {
         local metadata_buffer = ngx.shared.tracing_buffer
 
-        metadata_buffer:set('serviceName', 'e2e-test-with-mock-collector')
+        metadata_buffer:set("serviceName", "skywalking-nginx")
         -- Instance means the number of Nginx deployment, does not mean the worker instances
-        metadata_buffer:set('serviceInstanceName', 'e2e-test-with-mock-collector-instanceA')
+        metadata_buffer:set("serviceInstanceName", "e2e")
          -- set ignoreSuffix
         require("skywalking.util").set_ignore_suffix(".jpg,.jpeg,.js,.css,.png,.bmp,.gif,.ico,.mp3,.mp4,.svg")
 
         require("skywalking.util").set_randomseed()
-        require("skywalking.client"):startBackendTimer("http://${collector}:12800")
+        require("skywalking.client"):startBackendTimer("http://172.16.238.10:12800")
 
         -- If there is a bug of this `tablepool` implementation, we can
         -- disable it in this way
@@ -53,14 +53,13 @@ http {
     server {
         listen 8080;
 
-        location /ingress {
+        location /info {
             default_type text/html;
-
             rewrite_by_lua_block {
                 skywalking_tracer:start("e2e-test-with-mock-collector:upstream_ip:port")
             }
 
-            proxy_pass http://127.0.0.1:8080/tier2/lb;
+            proxy_pass http://provider:9090;
 
             body_filter_by_lua_block {
                 skywalking_tracer:finish()
@@ -71,25 +70,7 @@ http {
             }
         }
 
-        location /tier2/lb {
-            default_type text/html;
-
-            rewrite_by_lua_block {
-                skywalking_tracer:start("e2e-test-with-mock-collector:upstream_ip2:port2")
-            }
-
-            proxy_pass http://127.0.0.1:8080/backend;
-
-            body_filter_by_lua_block {
-                skywalking_tracer:finish()
-            }
-
-            log_by_lua_block {
-                skywalking_tracer:prepareForReport()
-            }
-        }
         location /suffix {
-
             default_type text/html;
             content_by_lua_block {
                 ngx.say("<p>Suffix for testing only.</p>")
@@ -107,9 +88,5 @@ http {
                 skywalking_tracer:prepareForReport()
             }
         }
-
-        location /backend {
-            proxy_pass http://${collector}:12800/receiveData;
-        }
     }
 }
diff --git a/test/e2e/nginx/pom.xml b/test/e2e/nginx/pom.xml
deleted file mode 100644
index dbd00af..0000000
--- a/test/e2e/nginx/pom.xml
+++ /dev/null
@@ -1,121 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  ~ 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.
-  ~
-  -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.apache.skywalking.plugin.nginx-lua</groupId>
-        <artifactId>e2e</artifactId>
-        <version>1.0.0</version>
-    </parent>
-
-    <artifactId>nginx</artifactId>
-    <packaging>jar</packaging>
-
-    <properties>
-        <mock-collector.version>092c6a3c753684b5a301baf5bcb1965f2dfaf79d</mock-collector.version>
-    </properties>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>io.fabric8</groupId>
-                <artifactId>docker-maven-plugin</artifactId>
-                <configuration>
-                    <containerNamePattern>%a-%t-%i</containerNamePattern>
-                    <images>
-                        <image>
-                            <name>openresty-with-skywalking</name>
-                            <build>
-                                <from>openresty/openresty:1.17.8.2-5-alpine-fat</from>
-                                <workdir>/skywalking-nginx-lua</workdir>
-                            </build>
-                            <run>
-                                <dependsOn>
-                                    <container>skywalking-collector</container>
-                                </dependsOn>
-                                <ports>
-                                    <port>+nginx.host:nginx.port:8080</port>
-                                </ports>
-                                <volumes>
-                                    <bind>
-                                        <volume>${project.basedir}/docker/conf.d:/var/nginx/conf.d</volume>
-                                        <volume>${project.basedir}/docker/bin:/opt/bin</volume>
-                                        <volume>
-                                            ${project.basedir}/../../../:/skywalking-nginx-lua/
-                                        </volume>
-                                    </bind>
-                                </volumes>
-                                <links>
-                                    <link>skywalking-collector</link>
-                                </links>
-                                <wait>
-                                    <http>
-                                        <url>
-                                            http://${docker.host.address}:${nginx.port}
-                                        </url>
-                                    </http>
-                                    <time>30000</time>
-                                </wait>
-                                <cmd>bash /opt/bin/startup.sh</cmd>
-                            </run>
-                        </image>
-                        <image>
-                            <name>ghcr.io/apache/skywalking-agent-test-tool/mock-collector:${mock-collector.version}</name>
-                            <alias>skywalking-collector</alias>
-                            <run>
-                                <ports>
-                                    <port>+collector.host:collector.port:12800</port>
-                                </ports>
-                                <wait>
-                                    <http>
-                                        <url>http://${docker.host.address}:${collector.port}/receiveData</url>
-                                    </http>
-                                    <time>30000</time>
-                                </wait>
-                            </run>
-                        </image>
-                    </images>
-                </configuration>
-            </plugin>
-
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-failsafe-plugin</artifactId>
-                <version>${maven-failsafe-plugin.version}</version>
-                <configuration>
-                    <systemPropertyVariables>
-                        <service.entry>http://${nginx.host}:${nginx.port}/ingress</service.entry>
-                        <suffix.entry>http://${nginx.host}:${nginx.port}/suffix/suffix.js</suffix.entry>
-                        <validation.entry>http://${collector.host}:${collector.port}/dataValidate</validation.entry>
-                        <healthcheck.entry>http://${collector.host}:${collector.port}/status</healthcheck.entry>
-                    </systemPropertyVariables>
-                </configuration>
-                <executions>
-                    <execution>
-                        <goals>
-                            <goal>verify</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin>
-        </plugins>
-    </build>
-</project>
diff --git a/test/e2e/nginx/src/test/java/org/apache/skywalking/e2e/DataAssertITCase.java b/test/e2e/nginx/src/test/java/org/apache/skywalking/e2e/DataAssertITCase.java
deleted file mode 100644
index ea4fe89..0000000
--- a/test/e2e/nginx/src/test/java/org/apache/skywalking/e2e/DataAssertITCase.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * 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.
- *
- */
-
-package org.apache.skywalking.e2e;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.concurrent.TimeUnit;
-import org.apache.http.client.methods.CloseableHttpResponse;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.entity.InputStreamEntity;
-import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClientBuilder;
-import org.junit.After;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-public class DataAssertITCase {
-    private CloseableHttpClient client = HttpClientBuilder.create().build();
-    private static final int MAX_RETRY_TIMES = 5;
-    private String validationEntry;
-    private String serviceEntry;
-    private String healthCheckEntry;
-    private String suffixEntry;
-    
-    @Before
-    public void setup() throws IOException {
-        serviceEntry = System.getProperty("service.entry");
-        suffixEntry = System.getProperty("suffix.entry");
-        validationEntry = System.getProperty("validation.entry");
-        healthCheckEntry = System.getProperty("healthcheck.entry");
-    }
-
-    @Test(timeout = 180_000)
-    public void verify() throws IOException, InterruptedException {
-        int times = 0;
-
-        do {
-            TimeUnit.SECONDS.sleep(2L); // Wait Nginx Lua Agent available.
-
-            try (CloseableHttpResponse response = client.execute(new HttpGet(healthCheckEntry))) {
-                if (response.getStatusLine().getStatusCode() == 200) {
-                    break;
-                }
-            }
-        } while (++times <= MAX_RETRY_TIMES);
-
-        try (CloseableHttpResponse response = client.execute(new HttpGet(serviceEntry))) {
-            Assert.assertEquals(200, response.getStatusLine().getStatusCode());
-        }
-
-        try (CloseableHttpResponse response = client.execute(new HttpGet(suffixEntry))) {
-            Assert.assertEquals(200, response.getStatusLine().getStatusCode());
-        }
-
-        times = 0;
-        do {
-            TimeUnit.SECONDS.sleep(5L); // Wait Agent reported TraceSegment.
-
-            HttpPost post = new HttpPost(validationEntry);
-            InputStream input = DataAssertITCase.class.getResourceAsStream("/expectedData.yaml");
-            post.setEntity(new InputStreamEntity(input));
-            try (CloseableHttpResponse response = client.execute(post)) {
-                System.out.println(response.getStatusLine().getStatusCode());
-                if (response.getStatusLine().getStatusCode() == 200) {
-                    break;
-                }
-            }
-            post.abort();
-        }
-        while (++times <= MAX_RETRY_TIMES);
-
-        Assert.assertTrue("Test failed.", times <= MAX_RETRY_TIMES);
-    }
-
-    @After
-    public void cleanup() throws IOException {
-        client.close();
-    }
-}
diff --git a/test/e2e/nginx/src/test/resources/expectedData.yaml b/test/e2e/nginx/src/test/resources/expectedData.yaml
deleted file mode 100644
index 3a0eb1d..0000000
--- a/test/e2e/nginx/src/test/resources/expectedData.yaml
+++ /dev/null
@@ -1,91 +0,0 @@
-# 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.
-
-segmentItems:
-  - serviceName: e2e-test-with-mock-collector
-    segmentSize: eq 2
-    segments:
-      - segmentId: not null
-        spans:
-          - operationName: /tier2/lb
-            startTime: gt 0
-            endTime: gt 0
-            spanType: Exit
-            spanId: 1
-            isError: false
-            parentSpanId: 0
-            componentId: 6000
-            peer: 'e2e-test-with-mock-collector:upstream_ip2:port2'
-            spanLayer: Http
-            tags:
-              - key: http.status
-                value: '200'
-          - operationName: /tier2/lb
-            startTime: gt 0
-            tags:
-              - key: http.method
-                value: GET
-              - key: http.params
-                value: 'http://127.0.0.1/tier2/lb'
-              - key: http.status
-                value: '200'
-            endTime: gt 0
-            spanType: Entry
-            spanId: 0
-            isError: false
-            parentSpanId: -1
-            componentId: 6000
-            refs:
-              - parentEndpoint: /ingress
-                parentTraceSegmentId: not null
-                refType: 'CrossProcess'
-                networkAddress: 'e2e-test-with-mock-collector:upstream_ip:port'
-                parentSpanId: 1
-                parentServiceInstance: 'e2e-test-with-mock-collector-instanceA'
-                traceId: not null
-                parentService: 'e2e-test-with-mock-collector'
-            spanLayer: Http
-      - segmentId: not null
-        spans:
-          - operationName: /ingress
-            startTime: gt 0
-            endTime: gt 0
-            spanType: Exit
-            spanId: 1
-            isError: false
-            parentSpanId: 0
-            componentId: 6000
-            peer: 'e2e-test-with-mock-collector:upstream_ip:port'
-            spanLayer: Http
-            tags:
-              - key: http.status
-                value: '200'
-          - operationName: /ingress
-            startTime: gt 0
-            tags:
-              - key: http.method
-                value: GET
-              - key: http.params
-                value: 'not null'
-              - key: http.status
-                value: '200'
-            endTime: gt 0
-            spanType: Entry
-            spanId: 0
-            parentSpanId: -1
-            isError: false
-            spanLayer: Http
-            componentId: 6000
diff --git a/test/e2e/pom.xml b/test/e2e/pom.xml
deleted file mode 100644
index b5d19d9..0000000
--- a/test/e2e/pom.xml
+++ /dev/null
@@ -1,265 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  ~ 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.
-  ~
-  -->
-
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-    <modelVersion>4.0.0</modelVersion>
-
-    <groupId>org.apache.skywalking.plugin.nginx-lua</groupId>
-    <artifactId>e2e</artifactId>
-    <version>1.0.0</version>
-
-    <name>SkyWalking Nginx Lua E2E Tests</name>
-    <packaging>pom</packaging>
-
-    <modules>
-        <module>nginx</module>
-    </modules>
-
-    <properties>
-        <java.version>1.8</java.version>
-
-        <junit.version>4.11</junit.version>
-        <slf4j.version>1.7.25</slf4j.version>
-        <log4j.version>2.9.0</log4j.version>
-        <gson.version>2.8.6</gson.version>
-        <guava.version>28.1-jre</guava.version>
-        <lombok.version>1.18.10</lombok.version>
-        <snakeyaml.version>1.18</snakeyaml.version>
-        <httpclient.version>4.5.6</httpclient.version>
-
-        <maven.compiler.source>${java.version}</maven.compiler.source>
-        <maven.compiler.target>${java.version}</maven.compiler.target>
-
-        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-
-        <maven-compiler-plugin.version>3.8.0</maven-compiler-plugin.version>
-        <docker-maven-plugin.version>0.30.0</docker-maven-plugin.version>
-
-        <maven-failsafe-plugin.version>3.0.0-M4</maven-failsafe-plugin.version>
-        <maven-compiler-plugin.version>3.8.0</maven-compiler-plugin.version>
-        <surefire.version>3.0.0-M4</surefire.version>
-    </properties>
-
-    <dependencyManagement>
-        <dependencies>
-            <dependency>
-                <groupId>junit</groupId>
-                <artifactId>junit</artifactId>
-                <version>${junit.version}</version>
-            </dependency>
-            <dependency>
-                <groupId>org.apache.httpcomponents</groupId>
-                <artifactId>httpclient</artifactId>
-                <version>${httpclient.version}</version>
-            </dependency>
-            <dependency>
-                <groupId>com.google.guava</groupId>
-                <artifactId>guava</artifactId>
-                <version>${guava.version}</version>
-            </dependency>
-            <dependency>
-                <groupId>org.yaml</groupId>
-                <artifactId>snakeyaml</artifactId>
-                <version>${snakeyaml.version}</version>
-            </dependency>
-            <dependency>
-                <groupId>com.google.code.gson</groupId>
-                <artifactId>gson</artifactId>
-                <version>${gson.version}</version>
-            </dependency>
-            <dependency>
-                <groupId>org.projectlombok</groupId>
-                <artifactId>lombok</artifactId>
-                <version>${lombok.version}</version>
-                <scope>provided</scope>
-            </dependency>
-            <dependency>
-                <groupId>org.slf4j</groupId>
-                <artifactId>slf4j-api</artifactId>
-                <version>${slf4j.version}</version>
-            </dependency>
-            <dependency>
-                <groupId>org.slf4j</groupId>
-                <artifactId>log4j-over-slf4j</artifactId>
-                <version>${slf4j.version}</version>
-            </dependency>
-            <dependency>
-                <groupId>org.apache.logging.log4j</groupId>
-                <artifactId>log4j-core</artifactId>
-                <version>${log4j.version}</version>
-            </dependency>
-            <dependency>
-                <groupId>org.apache.logging.log4j</groupId>
-                <artifactId>log4j-slf4j-impl</artifactId>
-                <version>${log4j.version}</version>
-                <exclusions>
-                    <exclusion>
-                        <groupId>org.apache.logging.log4j</groupId>
-                        <artifactId>log4j-core</artifactId>
-                    </exclusion>
-                </exclusions>
-            </dependency>
-        </dependencies>
-    </dependencyManagement>
-
-    <dependencies>
-        <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.httpcomponents</groupId>
-            <artifactId>httpclient</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.google.guava</groupId>
-            <artifactId>guava</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.yaml</groupId>
-            <artifactId>snakeyaml</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>com.google.code.gson</groupId>
-            <artifactId>gson</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.projectlombok</groupId>
-            <artifactId>lombok</artifactId>
-            <scope>provided</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>log4j-over-slf4j</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.logging.log4j</groupId>
-            <artifactId>log4j-core</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.logging.log4j</groupId>
-            <artifactId>log4j-slf4j-impl</artifactId>
-            <version>${log4j.version}</version>
-            <exclusions>
-                <exclusion>
-                    <groupId>org.apache.logging.log4j</groupId>
-                    <artifactId>log4j-core</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-    </dependencies>
-    <build>
-        <pluginManagement>
-            <plugins>
-                <plugin>
-                    <groupId>org.apache.maven.plugins</groupId>
-                    <artifactId>maven-failsafe-plugin</artifactId>
-                    <version>${maven-failsafe-plugin.version}</version>
-                    <dependencies>
-                        <dependency>
-                            <groupId>org.apache.maven.surefire</groupId>
-                            <artifactId>surefire-junit4</artifactId>
-                            <version>${maven-failsafe-plugin.version}</version>
-                        </dependency>
-                    </dependencies>
-                    <executions>
-                        <execution>
-                            <id>integration-test</id>
-                            <goals>
-                                <goal>integration-test</goal>
-                                <goal>verify</goal>
-                            </goals>
-                            <configuration>
-                                <excludes>
-                                    <exclude>none</exclude>
-                                </excludes>
-                                <includes>
-                                    <include>**/*ITCase.java</include>
-                                </includes>
-                            </configuration>
-                        </execution>
-                    </executions>
-                </plugin>
-                <plugin>
-                    <groupId>io.fabric8</groupId>
-                    <artifactId>docker-maven-plugin</artifactId>
-                    <version>${docker-maven-plugin.version}</version>
-                    <configuration>
-                        <sourceMode>all</sourceMode>
-                        <showLogs>true</showLogs>
-                        <logDate>default</logDate>
-                        <imagePullPolicy>IfNotPresent</imagePullPolicy>
-                    </configuration>
-                    <executions>
-                        <execution>
-                            <id>build</id>
-                            <phase>initialize</phase>
-                            <goals>
-                                <goal>build</goal>
-                            </goals>
-                        </execution>
-                        <execution>
-                            <id>start</id>
-                            <phase>pre-integration-test</phase>
-                            <goals>
-                                <goal>start</goal>
-                            </goals>
-                        </execution>
-                        <execution>
-                            <id>stop</id>
-                            <phase>post-integration-test</phase>
-                            <goals>
-                                <goal>stop</goal>
-                            </goals>
-                        </execution>
-                    </executions>
-                </plugin>
-                <plugin>
-                    <groupId>org.apache.maven.plugins</groupId>
-                    <artifactId>maven-surefire-plugin</artifactId>
-                    <version>${surefire.version}</version>
-                </plugin>
-            </plugins>
-        </pluginManagement>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-compiler-plugin</artifactId>
-                <version>${maven-compiler-plugin.version}</version>
-                <configuration>
-                    <source>${java.version}</source>
-                    <target>${java.version}</target>
-                    <encoding>${project.build.sourceEncoding}</encoding>
-                </configuration>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-surefire-plugin</artifactId>
-                <version>${surefire.version}</version>
-            </plugin>
-        </plugins>
-    </build>
-</project>
\ No newline at end of file
diff --git a/.github/workflows/e2e.yaml b/test/e2e/user/Dockerfile
similarity index 50%
copy from .github/workflows/e2e.yaml
copy to test/e2e/user/Dockerfile
index a92f025..91b7dec 100644
--- a/.github/workflows/e2e.yaml
+++ b/test/e2e/user/Dockerfile
@@ -14,31 +14,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-name: E2E
+FROM alpine
 
-on:
-  pull_request:
-  push:
-    branches: 
-      - master
-    tags:
-      - 'v*'
+RUN apk add --no-cache curl
 
-jobs:
-  nginx:
-    runs-on: ubuntu-18.04
-    timeout-minutes: 180
-    steps:
-      - uses: actions/checkout@v2
-      - name: checkout submodules
-        shell: bash
-        run: |
-          git submodule sync --recursive
-          git -c protocol.version=2 submodule update --init --force --recursive --depth=1
-      - uses: actions/setup-java@v1
-        with:
-          java-version: 8
-      - name: Set environment
-        run: export MAVEN_OPTS='-Dmaven.repo.local=~/.m2/repository -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGC -XX:-UseGCOverheadLimit -Xmx3g'
-      - name: Run Nginx Test
-        run: ./mvnw -f ./test/e2e/pom.xml verify
+COPY execute_and_validate.sh /execute_and_validate.sh
+
+CMD ["sh", "/execute_and_validate.sh"]
diff --git a/test/e2e/user/execute_and_validate.sh b/test/e2e/user/execute_and_validate.sh
new file mode 100644
index 0000000..401dc91
--- /dev/null
+++ b/test/e2e/user/execute_and_validate.sh
@@ -0,0 +1,49 @@
+#!/usr/bin/env bash
+
+# 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.
+
+rst=$(curl -X POST -Is ${SERVICE_ENTRY} | head -1 | grep "HTTP/1.1 200")
+if [[ -z "$rst" ]]; then
+  echo "failed to access ${SERVICE_ENTRY}"
+  exit 1
+fi
+echo "access ${SERVICE_ENTRY} success"
+
+rst=$(curl -X GET -Is ${SUFFIX_ENTRY} | head -1 | grep "HTTP/1.1 200")
+if [[ -z "$rst" ]]; then
+  echo "failed to access ${SUFFIX_ENTRY}"
+  exit 1
+fi
+echo "access ${SUFFIX_ENTRY} success"
+
+sleep 5 # Wait Agent reported TraceSegment.
+
+times=0
+while [ $times -lt $MAX_RETRY_TIMES ]; do
+  curl -X POST --data-raw "$(cat /expectedData.yaml)" --dump-header ./header -o /response -s ${VALIDATION_ENTRY}
+  rst=$(head -1 /header | grep "HTTP/1.1 200")
+  if [[ -n "$rst" ]]; then
+    echo "Verification successful"
+    exit 0
+  fi
+
+  sleep 3
+  times=$((times+1))
+done
+
+cat /response
+exit 1
diff --git a/test/e2e/user/expectedData.yaml b/test/e2e/user/expectedData.yaml
new file mode 100644
index 0000000..7d3c505
--- /dev/null
+++ b/test/e2e/user/expectedData.yaml
@@ -0,0 +1,158 @@
+# 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.
+segmentItems:
+- serviceName: e2e-service-consumer
+  segmentSize: ge 1
+  segments:
+  - segmentId: not null
+    spans:
+    - operationName: /info
+      parentSpanId: 0
+      spanId: 1
+      spanLayer: Http
+      startTime: gt 0
+      endTime: gt 0
+      componentId: 13
+      isError: false
+      spanType: Exit
+      peer: nginx:8080
+      skipAnalysis: false
+      tags:
+      - key: url
+        value: 'http://nginx:8080/info'
+      - key: http.method
+        value: POST
+    - operationName: POST:/info
+      parentSpanId: -1
+      spanId: 0
+      spanLayer: Http
+      startTime: gt 0
+      endTime: gt 0
+      componentId: 1
+      isError: false
+      spanType: Entry
+      peer: ''
+      skipAnalysis: false
+      tags:
+      - key: url
+        value: 'http://consumer:9092/info'
+      - key: http.method
+        value: POST
+- serviceName: skywalking-nginx
+  segmentSize: ge 2
+  segments:
+  - segmentId: not null
+    spans:
+    - operationName: /info
+      parentSpanId: 0
+      spanId: 1
+      spanLayer: Http
+      startTime: gt 0
+      endTime: gt 0
+      componentId: 6000
+      isError: false
+      spanType: Exit
+      peer: 'e2e-test-with-mock-collector:upstream_ip:port'
+      skipAnalysis: false
+      tags:
+      - key: http.status
+        value: '200'
+    - operationName: /info
+      parentSpanId: -1
+      spanId: 0
+      spanLayer: Http
+      startTime: gt 0
+      endTime: gt 0
+      componentId: 6000
+      isError: false
+      spanType: Entry
+      peer: ''
+      skipAnalysis: false
+      tags:
+      - key: http.method
+        value: POST
+      - key: http.params
+        value: 'http://nginx/info'
+      - key: http.status
+        value: '200'
+      refs:
+      - parentEndpoint: 'POST:/info'
+        networkAddress: 'nginx:8080'
+        refType: CrossProcess
+        parentSpanId: 1
+        parentTraceSegmentId: not null
+        parentServiceInstance: consumer1
+        parentService: e2e-service-consumer
+        traceId: not null
+  - segmentId: not null
+    spans:
+    - operationName: /suffix
+      parentSpanId: 0
+      spanId: 1
+      spanLayer: Http
+      startTime: gt 0
+      endTime: gt 0
+      componentId: 6000
+      isError: false
+      spanType: Exit
+      peer: 'e2e-test-with-mock-collector:upstream_ip:port'
+      skipAnalysis: false
+    - operationName: /suffix
+      parentSpanId: -1
+      spanId: 0
+      spanLayer: Http
+      startTime: gt 0
+      endTime: gt 0
+      componentId: 6000
+      isError: false
+      spanType: Entry
+      peer: ''
+      skipAnalysis: false
+      tags:
+      - key: http.method
+        value: GET
+      - key: http.params
+        value: 'http://nginx/suffix'
+      - key: http.status
+        value: '200'
+- serviceName: e2e-service-provider
+  segmentSize: gt 1
+  segments:
+  - segmentId: not nul
+    spans:
+    - operationName: POST:/info
+      parentSpanId: -1
+      spanId: 0
+      spanLayer: Http
+      startTime: gt 0
+      endTime: gt 0
+      componentId: 1
+      isError: false
+      spanType: Entry
+      peer: ''
+      skipAnalysis: false
+      tags:
+      - {key: url, value: 'http://provider:9090/info'}
+      - {key: http.method, value: POST}
+      refs:
+      - parentEndpoint: /info
+        networkAddress: 'e2e-test-with-mock-collector:upstream_ip:port'
+        refType: CrossProcess
+        parentSpanId: 1
+        parentTraceSegmentId: not null
+        parentServiceInstance: e2e
+        parentService: skywalking-nginx
+        traceId: not null