set up e2e (#4)

* set up e2e

Co-authored-by: zhang-wei <pknfe@outlook.com>
diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml
new file mode 100644
index 0000000..9c07faa
--- /dev/null
+++ b/.github/workflows/e2e.yaml
@@ -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.
+
+name: E2E
+
+on:
+  pull_request:
+  push:
+    branches: 
+      - master
+    tags:
+      - 'v*'
+
+jobs:
+  agent:
+    runs-on: ubuntu-18.04
+    timeout-minutes: 180
+    strategy:
+      fail-fast: true
+    steps:
+      - uses: actions/checkout@v1
+        with:
+          submodules: true
+      - uses: actions/setup-java@v1
+        with:
+          java-version: 8
+      - uses: aahmed-se/setup-maven@v3
+        with:
+          maven-version: 3.6.1
+      - 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: Compile & Install Test Codes
+        run: |
+          mvn -f ./test/e2e/validator/pom.xml clean verify
diff --git a/test/e2e/validator/docker/conf.d/nginx.conf b/test/e2e/validator/docker/conf.d/nginx.conf
new file mode 100644
index 0000000..da2e81b
--- /dev/null
+++ b/test/e2e/validator/docker/conf.d/nginx.conf
@@ -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.
+
+# This nginx.conf is designed and written for local dev environments
+# It will use the blocking startup mode and console logging
+worker_processes  1;
+daemon off;
+error_log /dev/stdout error;
+
+events {
+    worker_connections 1024;
+}
+http {
+    lua_package_path "/skywalking-nginx-lua/lib/skywalking/?.lua;;";
+    # Buffer represents the register inform and the queue of the finished segment
+    lua_shared_dict tracing_buffer 100m;
+
+    # Init is the timer setter and keeper
+    # Setup an infinite loop timer to do register and trace report.
+    init_worker_by_lua_block {
+        local metadata_buffer = ngx.shared.tracing_buffer
+
+        metadata_buffer:set('serviceName', 'User_Service_Name')
+        -- Instance means the number of Nginx deloyment, does not mean the worker instances
+        metadata_buffer:set('serviceInstanceName', 'User_Service_Instance_Name')
+
+        require("client"):startBackendTimer("http://127.0.0.1:8080")
+    }
+    log_format sw_trace escape=json "$uri $request_body";
+
+    server {
+        listen 8080;
+
+        # This is for local dev only, please do not add this in any production env.
+        lua_code_cache off;
+
+        location /ingress {
+            default_type text/html;
+
+            rewrite_by_lua_block {
+                require("tracer"):startBackendTimer()
+            }
+
+            proxy_pass http://127.0.0.1:8080/tier2/lb;
+
+            body_filter_by_lua_block {
+                require("tracer"):finish()
+            }
+
+            log_by_lua_block {
+                require("tracer"):prepareForReport()
+            }
+        }
+
+        location /tier2/lb {
+            default_type text/html;
+
+            rewrite_by_lua_block {
+                require("tracer"):startBackendTimer()
+            }
+
+            proxy_pass http://127.0.0.1:8080/backend;
+
+            body_filter_by_lua_block {
+                require("tracer"):finish()
+            }
+
+            log_by_lua_block {
+                require("tracer"):prepareForReport()
+            }
+        }
+
+        # ------------------------------------------------------
+        # -- Mock backend business service as the upsteeam
+        # ------------------------------------------------------
+        location /backend {
+            default_type text/html;
+            content_by_lua_block {
+                ngx.say("<p>Backend service for testing only.</p>")
+                ngx.say("<p>Backend sw6 received headers: " .. ngx.req.get_headers()["sw6"] .. "</p>")
+            }
+        }
+
+
+        # ------------------------------------------------------
+        # -- Mock OAP server to provide register and trace collection
+        # ------------------------------------------------------
+        location /v2/service/register {
+            default_type text/html;
+            lua_need_request_body on;
+            access_log /var/log/nginx/trace.log sw_trace;
+
+            content_by_lua_block {
+                local cjson = require('cjson')
+
+                ngx.log(ngx.DEBUG, 'Service register request = ', ngx.req.get_body_data())
+                local param = cjson.decode(ngx.req.get_body_data())
+
+                local registeredInfo = {}
+                registeredInfo[1] = {key=param.services[1].serviceName, value=1}
+                ngx.say(cjson.encode(registeredInfo))
+            }
+        }
+
+        location /v2/instance/register {
+            default_type text/html;
+	        access_log /var/log/nginx/trace.log sw_trace;
+            lua_need_request_body on;
+
+            content_by_lua_block {
+                local cjson = require('cjson')
+                ngx.log(ngx.DEBUG, 'Service instance register request = ', ngx.req.get_body_data())
+                local param = cjson.decode(ngx.req.get_body_data())
+
+                local registeredInfo = {}
+
+                registeredInfo[1] = {key=param.instances[1].instanceUUID, value=1}
+                ngx.say(cjson.encode(registeredInfo))
+            }
+        }
+
+        location /v2/instance/heartbeat {
+            default_type text/html;
+            lua_need_request_body on;
+            access_log /var/log/nginx/trace.log sw_trace;
+
+            content_by_lua_block {
+                local cjson = require('cjson')
+                --ngx.log(ngx.DEBUG, 'Service instance ping request = ', ngx.req.get_body_data())
+            }
+        }
+
+        location /v2/segments {
+            default_type text/html;
+            lua_need_request_body on;
+            access_log /var/log/nginx/trace.log sw_trace;
+
+            content_by_lua_block {
+                local cjson = require('cjson')
+                ngx.log(ngx.DEBUG, 'Received segment = ', ngx.req.get_body_data())
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/test/e2e/validator/pom.xml b/test/e2e/validator/pom.xml
new file mode 100644
index 0000000..868b886
--- /dev/null
+++ b/test/e2e/validator/pom.xml
@@ -0,0 +1,268 @@
+<?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</groupId>
+    <artifactId>validator</artifactId>
+    <version>0.0.1</version>
+    <packaging>jar</packaging>
+
+    <name>skywalking-validator-tools</name>
+    <url>http://maven.apache.org</url>
+
+    <properties>
+        <java.version>1.8</java.version>
+
+        <junit.version>4.11</junit.version>
+        <gson.version>2.8.5</gson.version>
+        <slf4j.version>1.7.25</slf4j.version>
+        <log4j.version>2.9.0</log4j.version>
+        <guava.version>28.1-jre</guava.version>
+        <snakeyaml.version>1.18</snakeyaml.version>
+        <gson.version>2.8.6</gson.version>
+        <lombok.version>1.18.10</lombok.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.4.13</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>
+        <docker-maven-plugin.version>0.30.0</docker-maven-plugin.version>
+        <surefire.version>3.0.0-M4</surefire.version>
+
+        <skipSurefire>false</skipSurefire>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>${junit.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.freemarker</groupId>
+            <artifactId>freemarker</artifactId>
+            <version>2.3.23</version>
+        </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>
+
+    <build>
+        <finalName>skywalking-validator-tools</finalName>
+        <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>**/*IT.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>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>
+            </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>io.fabric8</groupId>
+                <artifactId>docker-maven-plugin</artifactId>
+                <configuration>
+                    <containerNamePattern>%a-%t-%i</containerNamePattern>
+                    <images>
+                        <image>
+                            <name>openresty/openresty</name>
+                            <alias>openresty-with-skywalking</alias>
+                            <run>
+                                <ports>
+                                    <port>+nginx.host:nginx.port:8080</port>
+                                </ports>
+                                <volumes>
+                                    <bind>
+                                        <volume>${project.build.testOutputDirectory}/logs:/var/log/nginx</volume>
+                                        <volume>${project.basedir}/docker/conf.d:/var/nginx/conf.d</volume>
+                                        <volume>
+                                            ${project.basedir}/../../../lib/skywalking:/skywalking-nginx-lua/lib/skywalking
+                                        </volume>
+                                    </bind>
+                                </volumes>
+                                <wait>
+                                    <http>
+                                        <url>
+                                            http://${docker.host.address}:${nginx.port}
+                                        </url>
+                                    </http>
+                                    <time>30000</time>
+                                </wait>
+                                <cmd>/usr/bin/openresty -c /var/nginx/conf.d/nginx.conf</cmd>
+                            </run>
+                        </image>
+                    </images>
+                </configuration>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>${surefire.version}</version>
+                <configuration>
+                    <skip>${skipSurefire}</skip>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-failsafe-plugin</artifactId>
+                <version>${maven-failsafe-plugin.version}</version>
+                <configuration>
+                    <systemPropertyVariables>
+                        <ping.url>
+                            http://${nginx.host}:${nginx.port}/ingress
+                        </ping.url>
+                    </systemPropertyVariables>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>verify</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/ApplicationAssert.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/ApplicationAssert.java
new file mode 100644
index 0000000..c59bd6c
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/ApplicationAssert.java
@@ -0,0 +1,53 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor;
+
+import java.util.List;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.RegistryApplicationNotFoundException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.RegistryApplicationSizeNotEqualsException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.ValueAssertFailedException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.entity.RegistryApplication;
+
+public class ApplicationAssert {
+    public static void assertEquals(List<RegistryApplication> expected, List<RegistryApplication> actual) {
+
+        if (expected == null) {
+            return;
+        }
+
+        for (RegistryApplication application : expected) {
+            RegistryApplication actualApplication = getMatchApplication(actual, application);
+            try {
+                ExpressParser.parse(application.expressValue())
+                             .assertValue("registry application", actualApplication.expressValue());
+            } catch (ValueAssertFailedException e) {
+                throw new RegistryApplicationSizeNotEqualsException(application.applicationCode(), e);
+            }
+        }
+    }
+
+    private static RegistryApplication getMatchApplication(List<RegistryApplication> actual,
+        RegistryApplication application) {
+        for (RegistryApplication registryApplication : actual) {
+            if (registryApplication.applicationCode().equals(application.applicationCode())) {
+                return registryApplication;
+            }
+        }
+        throw new RegistryApplicationNotFoundException(application.applicationCode());
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/DataAssert.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/DataAssert.java
new file mode 100644
index 0000000..59a4124
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/DataAssert.java
@@ -0,0 +1,35 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor;
+
+import com.google.gson.GsonBuilder;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.skywalking.plugin.test.agent.tool.validator.entity.Data;
+
+public class DataAssert {
+    private static Logger logger = LogManager.getLogger(DataAssert.class);
+
+    public static void assertEquals(Data excepted, Data actual) {
+        logger.info("excepted data:\n{}", new GsonBuilder().setPrettyPrinting().create().toJson(excepted));
+        logger.info("actual data:\n{}", new GsonBuilder().setPrettyPrinting().create().toJson(actual));
+        RegistryItemsAssert.assertEquals(excepted.registryItems(), actual.registryItems());
+        SegmentItemsAssert.assertEquals(excepted.segmentItems(), actual.segmentItems());
+        logger.info("{} assert successful.", "segment items");
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/ExpressParser.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/ExpressParser.java
new file mode 100644
index 0000000..84ff2d0
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/ExpressParser.java
@@ -0,0 +1,63 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.element.ElementAssertor;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.element.EqualsAssertor;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.element.GreatThanAssertor;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.element.GreetEqualAssertor;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.element.NoopAssertor;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.element.NotEqualsAssertor;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.element.NotNullAssertor;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.element.NullAssertor;
+
+public class ExpressParser {
+    public static ElementAssertor parse(String express) {
+        if (express == null) {
+            return new NoopAssertor();
+        }
+
+        String expressTrim = express.trim();
+        if (expressTrim.equals("not null")) {
+            return new NotNullAssertor();
+        }
+
+        if (expressTrim.equals("null")) {
+            return new NullAssertor();
+        }
+
+        String[] expressSegment = expressTrim.split(" ");
+        if (expressSegment.length == 1) {
+            return new EqualsAssertor(expressSegment[0]);
+        } else if (expressSegment.length == 2) {
+            String exceptedValue = expressSegment[1];
+            switch (expressSegment[0].trim()) {
+                case "nq":
+                    return new NotEqualsAssertor(exceptedValue);
+                case "eq":
+                    return new EqualsAssertor(exceptedValue);
+                case "gt":
+                    return new GreatThanAssertor(exceptedValue);
+                case "ge":
+                    return new GreetEqualAssertor(exceptedValue);
+            }
+        }
+
+        return new EqualsAssertor(express);
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/InstanceAssert.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/InstanceAssert.java
new file mode 100644
index 0000000..c4af5e6
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/InstanceAssert.java
@@ -0,0 +1,53 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor;
+
+import java.util.List;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.RegistryInstanceOfApplicationNotFoundException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.RegistryInstanceSizeNotEqualsException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.ValueAssertFailedException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.entity.RegistryInstance;
+
+public class InstanceAssert {
+    public static void assertEquals(List<RegistryInstance> expected, List<RegistryInstance> actual) {
+
+        if (expected == null) {
+            return;
+        }
+
+        for (RegistryInstance instance : expected) {
+            RegistryInstance actualInstance = getMatchApplication(actual, instance);
+            try {
+                ExpressParser.parse(actualInstance.expressValue())
+                             .assertValue(String.format("The registry instance of %s", instance.applicationCode()), actualInstance
+                                 .expressValue());
+            } catch (ValueAssertFailedException e) {
+                throw new RegistryInstanceSizeNotEqualsException(instance.applicationCode(), e);
+            }
+        }
+    }
+
+    private static RegistryInstance getMatchApplication(List<RegistryInstance> actual, RegistryInstance application) {
+        for (RegistryInstance registryApplication : actual) {
+            if (registryApplication.applicationCode().equals(application.applicationCode())) {
+                return registryApplication;
+            }
+        }
+        throw new RegistryInstanceOfApplicationNotFoundException(application.applicationCode());
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/OperationNameAssert.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/OperationNameAssert.java
new file mode 100644
index 0000000..91974cb
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/OperationNameAssert.java
@@ -0,0 +1,62 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor;
+
+import java.util.List;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.ActualRegistryOperationNameEmptyException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.RegistryOperationNameNotFoundException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.RegistryOperationNamesOfApplicationNotFoundException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.entity.RegistryOperationName;
+
+public class OperationNameAssert {
+    public static void assertEquals(List<RegistryOperationName> expected, List<RegistryOperationName> actual) {
+        if (expected == null) {
+            return;
+        }
+
+        for (RegistryOperationName operationName : expected) {
+            RegistryOperationName actualOperationName = findActualRegistryOperationName(actual, operationName);
+            assertOperationEquals(actualOperationName.serviceName(), operationName.operationName(), actualOperationName
+                .operationName());
+        }
+    }
+
+    private static void assertOperationEquals(String applicationCode, List<String> expectedOperationName,
+        List<String> actualOperationName) {
+        for (String operationName : expectedOperationName) {
+            if (!actualOperationName.contains(operationName)) {
+                throw new RegistryOperationNameNotFoundException(applicationCode, operationName);
+            }
+        }
+    }
+
+    private static RegistryOperationName findActualRegistryOperationName(List<RegistryOperationName> actual,
+        RegistryOperationName registryOperationName) {
+        if (actual == null) {
+            throw new ActualRegistryOperationNameEmptyException(registryOperationName);
+        }
+
+        for (RegistryOperationName operationName : actual) {
+            if (operationName.serviceName().equals(registryOperationName.serviceName())) {
+                return operationName;
+            }
+        }
+
+        throw new RegistryOperationNamesOfApplicationNotFoundException(registryOperationName);
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/ParentSegmentIdExpressParser.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/ParentSegmentIdExpressParser.java
new file mode 100644
index 0000000..0284e95
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/ParentSegmentIdExpressParser.java
@@ -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.
+ */
+
+package org.apache.skywalking.plugin.test.agent.tool.validator.assertor;
+
+import java.util.List;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.ParentSegmentNotFoundException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.entity.SegmentItem;
+
+public class ParentSegmentIdExpressParser {
+    public static String parse(String express, List<SegmentItem> actual) {
+        if (!express.trim().startsWith("${") && !express.trim().endsWith("}")) {
+            return express;
+        }
+
+        String parentSegmentExpress = express.trim().substring(2, express.trim().length() - 1);
+
+        int startIndexOfIndex = parentSegmentExpress.indexOf("[");
+        String applicationCode = parentSegmentExpress.substring(0, startIndexOfIndex);
+        int endIndexOfIndex = parentSegmentExpress.indexOf("]", startIndexOfIndex);
+        int expectedSize = Integer.parseInt(parentSegmentExpress.substring(startIndexOfIndex + 1, endIndexOfIndex));
+        for (SegmentItem segmentItem : actual) {
+            if (segmentItem.serviceName().equals(applicationCode)) {
+                if (segmentItem.segments().size() <= expectedSize) {
+                    throw new ParentSegmentNotFoundException(parentSegmentExpress);
+                }
+
+                return segmentItem.segments().get(expectedSize).segmentId();
+            }
+        }
+        return express;
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/RegistryItemsAssert.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/RegistryItemsAssert.java
new file mode 100644
index 0000000..5c5e791
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/RegistryItemsAssert.java
@@ -0,0 +1,35 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.skywalking.plugin.test.agent.tool.validator.entity.RegistryItems;
+
+public class RegistryItemsAssert {
+    private static Logger logger = LogManager.getLogger(RegistryItemsAssert.class);
+
+    public static void assertEquals(RegistryItems excepted, RegistryItems actual) {
+        ApplicationAssert.assertEquals(excepted.applications(), actual.applications());
+        logger.info("{} assert successful.", "registry applications");
+        InstanceAssert.assertEquals(excepted.instances(), actual.instances());
+        logger.info("{} assert successful.", "registry instances");
+        OperationNameAssert.assertEquals(excepted.operationNames(), actual.operationNames());
+        logger.info("{} assert successful.", "registry operation name");
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/SegmentAssert.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/SegmentAssert.java
new file mode 100644
index 0000000..1c50b58
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/SegmentAssert.java
@@ -0,0 +1,224 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.ActualSegmentRefIsEmptyException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.KeyValueNotEqualsException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.LogEventKeyNotEqualsException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.LogEventSizeNotEqualsException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.LogEventValueNotEqualsException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.LogSizeNotEqualsException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.RefSizeNotEqualsException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.SegmentNotFoundException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.SegmentRefAssertFailedException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.SegmentRefNotFoundException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.SpanAssertFailedException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.SpanSizeNotEqualsException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.TagKeyNotEqualsException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.TagSizeNotEqualsException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.TagValueNotEqualsException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.ValueAssertFailedException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.entity.KeyValuePair;
+import org.apache.skywalking.plugin.test.agent.tool.validator.entity.LogEvent;
+import org.apache.skywalking.plugin.test.agent.tool.validator.entity.Segment;
+import org.apache.skywalking.plugin.test.agent.tool.validator.entity.SegmentItem;
+import org.apache.skywalking.plugin.test.agent.tool.validator.entity.SegmentRef;
+import org.apache.skywalking.plugin.test.agent.tool.validator.entity.Span;
+import org.apache.skywalking.plugin.test.agent.tool.validator.exception.AssertFailedException;
+
+public class SegmentAssert {
+    public static void assertEquals(SegmentItem expected, SegmentItem actual) {
+        if (expected.segments() == null) {
+            return;
+        }
+
+        for (Segment segment : expected.segments()) {
+            Segment actualSegment = findSegment(actual, segment);
+            segment.setSegmentId(actualSegment.segmentId());
+        }
+    }
+
+    private static Segment findSegment(SegmentItem actual, Segment expectedSegment) {
+        List<SegmentPredictionFailedCause> exceptions = new ArrayList<>();
+        for (Segment actualSegment : actual.segments()) {
+            try {
+                if (spansEquals(expectedSegment.spans(), actualSegment.spans())) {
+                    return actualSegment;
+                }
+            } catch (SpanSizeNotEqualsException e) {
+            } catch (SpanAssertFailedException e) {
+                exceptions.add(new SegmentPredictionFailedCause(e, actualSegment));
+            }
+        }
+
+        throw new SegmentNotFoundException(expectedSegment, exceptions);
+    }
+
+    private static boolean spansEquals(List<Span> excepted, List<Span> actual) {
+        if (excepted == null) {
+            return true;
+        }
+
+        if (actual == null || excepted.size() != actual.size()) {
+            throw new SpanSizeNotEqualsException(excepted.size(), (actual != null) ? actual.size() : 0);
+        }
+
+        int equalSpans = 0;
+        for (int index = 0; index < excepted.size(); index++, equalSpans++) {
+            Span exceptedSpan = excepted.get(index);
+            Span actualSpan = actual.get(index);
+            try {
+                spanEquals(exceptedSpan, actualSpan);
+            } catch (AssertFailedException e) {
+                throw new SpanAssertFailedException(e, exceptedSpan, actualSpan);
+            }
+        }
+
+        return true;
+    }
+
+    private static void spanEquals(Span excepted, Span actualSpan) {
+        ExpressParser.parse(excepted.operationName()).assertValue("operation name", actualSpan.operationName());
+        ExpressParser.parse(excepted.componentId()).assertValue("component id", actualSpan.componentId());
+        ExpressParser.parse(excepted.componentName()).assertValue("component name", actualSpan.componentName());
+        ExpressParser.parse(excepted.startTime()).assertValue("start time", actualSpan.startTime());
+        ExpressParser.parse(excepted.endTime()).assertValue("end time", actualSpan.endTime());
+        ExpressParser.parse(excepted.parentSpanId()).assertValue("parent span id", actualSpan.parentSpanId());
+        ExpressParser.parse(excepted.spanId()).assertValue("span id", actualSpan.spanId());
+        ExpressParser.parse(excepted.operationId()).assertValue("operation id", actualSpan.operationId());
+        ExpressParser.parse(excepted.peer()).assertValue("peer", actualSpan.peer());
+        ExpressParser.parse(excepted.spanLayer()).assertValue("span layer", actualSpan.spanLayer());
+        ExpressParser.parse(excepted.peerId()).assertValue("peer id", actualSpan.peerId());
+        ExpressParser.parse(excepted.error()).assertValue("is error", actualSpan.error());
+        ExpressParser.parse(excepted.spanType()).assertValue("span type", actualSpan.spanType());
+        tagsEquals(excepted.tags(), actualSpan.tags());
+        logsEquals(excepted.logs(), actualSpan.logs());
+        refEquals(excepted.refs(), actualSpan.refs());
+        excepted.setActualRefs(actualSpan.refs());
+
+    }
+
+    private static void refEquals(List<SegmentRef> excepted, List<SegmentRef> actual) {
+        if (excepted == null) {
+            return;
+        }
+
+        if (actual == null) {
+            throw new ActualSegmentRefIsEmptyException(excepted.size());
+        }
+
+        if (excepted.size() != actual.size()) {
+            throw new RefSizeNotEqualsException(excepted.size(), actual.size());
+        }
+
+        for (SegmentRef ref : excepted) {
+            findSegmentRef(actual, ref);
+        }
+    }
+
+    private static void tagsEquals(List<KeyValuePair> excepted, List<KeyValuePair> actual) {
+        if (excepted.size() != actual.size()) {
+            throw new TagSizeNotEqualsException(excepted.size(), actual.size());
+        }
+
+        for (int index = 0; index < excepted.size(); index++) {
+            tagEquals(excepted.get(index), actual.get(index));
+        }
+    }
+
+    private static void logsEquals(List<LogEvent> excepted, List<LogEvent> actual) {
+        if (excepted.size() != actual.size()) {
+            throw new LogSizeNotEqualsException(excepted.size(), actual.size());
+        }
+
+        for (int index = 0; index < excepted.size(); index++) {
+            logEventEquals(excepted.get(index), actual.get(index));
+        }
+
+    }
+
+    private static void logEventEquals(LogEvent exceptedEvent, LogEvent actualEvent) {
+        List<KeyValuePair> exceptedKey = exceptedEvent.events();
+        List<KeyValuePair> actualKey = actualEvent.events();
+
+        if (exceptedKey.size() != actualKey.size()) {
+            throw new LogEventSizeNotEqualsException(exceptedKey.size(), actualKey.size());
+        }
+
+        for (int index = 0; index < exceptedKey.size(); index++) {
+            logEventPairEquals(exceptedKey.get(index), actualKey.get(index));
+        }
+    }
+
+    private static void keyValuePairEquals(KeyValuePair excepted, KeyValuePair actual) {
+        if (!excepted.key().equals(actual.key())) {
+            throw new KeyValueNotEqualsException();
+        }
+
+        ExpressParser.parse(excepted.value()).assertValue("", actual.value());
+    }
+
+    private static void logEventPairEquals(KeyValuePair excepted, KeyValuePair actual) {
+        try {
+            keyValuePairEquals(excepted, actual);
+        } catch (KeyValueNotEqualsException e) {
+            throw new LogEventKeyNotEqualsException(excepted.key(), actual.key());
+        } catch (ValueAssertFailedException e) {
+            throw new LogEventValueNotEqualsException(excepted.key(), excepted.value(), actual.value());
+        }
+    }
+
+    private static void tagEquals(KeyValuePair excepted, KeyValuePair actual) {
+        try {
+            keyValuePairEquals(excepted, actual);
+        } catch (KeyValueNotEqualsException e) {
+            throw new TagKeyNotEqualsException(excepted.key(), actual.key());
+        } catch (ValueAssertFailedException e) {
+            throw new TagValueNotEqualsException(excepted.key(), excepted.value(), actual.value());
+        }
+    }
+
+    private static SegmentRef findSegmentRef(List<SegmentRef> actual, SegmentRef expected) {
+        List<SegmentRefAssertFailedCause> causes = new ArrayList<>();
+        for (SegmentRef segmentRef : actual) {
+            try {
+                if (simpleSegmentRefEquals(expected, segmentRef)) {
+                    return segmentRef;
+                }
+            } catch (SegmentRefAssertFailedException e) {
+                causes.add(new SegmentRefAssertFailedCause(e, segmentRef));
+            }
+        }
+        throw new SegmentRefNotFoundException(expected, causes);
+    }
+
+    private static boolean simpleSegmentRefEquals(SegmentRef expected, SegmentRef actual) {
+        try {
+            ExpressParser.parse(expected.entryEndpointName())
+                         .assertValue("entry service name", actual.entryEndpointName());
+            ExpressParser.parse(expected.parentEndpointName())
+                         .assertValue("parent service name", actual.parentEndpointName());
+            ExpressParser.parse(expected.refType()).assertValue("ref type", actual.refType());
+            return true;
+        } catch (ValueAssertFailedException e) {
+            throw new SegmentRefAssertFailedException(e, expected, actual);
+        }
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/SegmentItemsAssert.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/SegmentItemsAssert.java
new file mode 100644
index 0000000..e834ff6
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/SegmentItemsAssert.java
@@ -0,0 +1,102 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor;
+
+import java.util.List;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.ActualSegmentItemEmptyException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.SegmentItemNotFoundException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.SegmentSizeNotEqualsException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.ValueAssertFailedException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.entity.Segment;
+import org.apache.skywalking.plugin.test.agent.tool.validator.entity.SegmentItem;
+import org.apache.skywalking.plugin.test.agent.tool.validator.entity.SegmentRef;
+import org.apache.skywalking.plugin.test.agent.tool.validator.entity.Span;
+
+public class SegmentItemsAssert {
+    private static Logger logger = LogManager.getLogger(SegmentItemsAssert.class);
+
+    public static void assertEquals(List<SegmentItem> expected, List<SegmentItem> actual) {
+        if (expected == null) {
+            logger.info("ignore segment items. because expected segment item is null.");
+            return;
+        }
+
+        for (SegmentItem item : expected) {
+            SegmentItem actualSegmentItem = findSegmentItem(actual, item);
+            try {
+                assertSegmentSize(item.segmentSize(), actualSegmentItem.segmentSize());
+            } catch (ValueAssertFailedException e) {
+                throw new SegmentSizeNotEqualsException(item.serviceName(), item.segmentSize(), actualSegmentItem.segmentSize());
+            }
+            SegmentAssert.assertEquals(item, actualSegmentItem);
+        }
+
+        for (SegmentItem item : expected) {
+            if (item.segments() == null) {
+                continue;
+            }
+
+            for (Segment segment : item.segments()) {
+                convertParentSegmentId(segment, expected);
+
+                for (Span span : segment.spans()) {
+                    if (span.refs() == null || span.refs().size() == 0) {
+                        continue;
+                    }
+                    SegmentRefAssert.assertEquals(span.refs(), span.actualRefs());
+                }
+            }
+        }
+    }
+
+    private static void convertParentSegmentId(Segment segment, List<SegmentItem> actual) {
+        for (Span span : segment.spans()) {
+            if (span.refs() == null || span.refs().size() == 0) {
+                continue;
+            }
+
+            for (SegmentRef ref : span.refs()) {
+                String actualParentSegmentId = ParentSegmentIdExpressParser.parse(ref.parentTraceSegmentId(), actual);
+                ref.parentTraceSegmentId(actualParentSegmentId);
+            }
+        }
+    }
+
+    private static void assertSegmentSize(String expected, String actual) {
+        if (expected == null) {
+            return;
+        }
+        ExpressParser.parse(expected).assertValue("segment size", actual);
+    }
+
+    private static SegmentItem findSegmentItem(List<SegmentItem> actual, SegmentItem expected) {
+        if (actual == null) {
+            throw new ActualSegmentItemEmptyException(expected);
+        }
+
+        for (SegmentItem segmentItem : actual) {
+            if (expected.serviceName().equals(segmentItem.serviceName())) {
+                return segmentItem;
+            }
+        }
+
+        throw new SegmentItemNotFoundException(expected.serviceName());
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/SegmentPredictionFailedCause.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/SegmentPredictionFailedCause.java
new file mode 100644
index 0000000..9fa3efd
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/SegmentPredictionFailedCause.java
@@ -0,0 +1,39 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.SpanAssertFailedException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.entity.Segment;
+
+public class SegmentPredictionFailedCause {
+    private final Segment actualSegment;
+    private final SpanAssertFailedException spanAssertFailedCause;
+
+    public SegmentPredictionFailedCause(SpanAssertFailedException spanAssertFailedCause, Segment actualSegment) {
+        this.spanAssertFailedCause = spanAssertFailedCause;
+        this.actualSegment = actualSegment;
+    }
+
+    public Segment getActualSegment() {
+        return actualSegment;
+    }
+
+    public SpanAssertFailedException getSpanAssertFailedCause() {
+        return spanAssertFailedCause;
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/SegmentRefAssert.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/SegmentRefAssert.java
new file mode 100644
index 0000000..7e6b2d6
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/SegmentRefAssert.java
@@ -0,0 +1,83 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.SegmentRefAssertFailedException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.SegmentRefNotFoundException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.SegmentRefSizeNotEqualsException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.ValueAssertFailedException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.entity.SegmentRef;
+
+public class SegmentRefAssert {
+
+    public static void assertEquals(List<SegmentRef> excepted, List<SegmentRef> actual) {
+        if (excepted == null) {
+            return;
+        }
+
+        if (actual == null || excepted.size() != actual.size()) {
+            throw new SegmentRefSizeNotEqualsException(excepted.size(), actual.size());
+        }
+
+        for (SegmentRef ref : excepted) {
+            findSegmentRef(actual, ref);
+        }
+    }
+
+    private static SegmentRef findSegmentRef(List<SegmentRef> actual, SegmentRef expected) {
+        List<SegmentRefAssertFailedCause> causes = new ArrayList<>();
+        for (SegmentRef segmentRef : actual) {
+            try {
+                if (segmentRefEquals(expected, segmentRef)) {
+                    return segmentRef;
+                }
+            } catch (SegmentRefAssertFailedException e) {
+                causes.add(new SegmentRefAssertFailedCause(e, segmentRef));
+            }
+        }
+        throw new SegmentRefNotFoundException(expected, causes);
+    }
+
+    private static boolean segmentRefEquals(SegmentRef expected, SegmentRef actual) {
+        try {
+            ExpressParser.parse(expected.entryEndpointName())
+                         .assertValue("entry endpoint name", actual.entryEndpointName());
+            ExpressParser.parse(expected.networkAddress()).assertValue("network address", actual.networkAddress());
+            ExpressParser.parse(expected.parentTraceSegmentId())
+                         .assertValue("parent segment id", actual.parentTraceSegmentId());
+            ExpressParser.parse(expected.parentSpanId()).assertValue("span id", actual.parentSpanId());
+            ExpressParser.parse(expected.entryEndpointId()).assertValue("entry endpoint id", actual.entryEndpointId());
+            ExpressParser.parse(expected.networkAddressId())
+                         .assertValue("network address id", actual.networkAddressId());
+            ExpressParser.parse(expected.parentServiceInstanceId())
+                         .assertValue("parent application instance id", actual.parentServiceInstanceId());
+            ExpressParser.parse(expected.parentEndpointId())
+                         .assertValue("parent endpoint id", actual.parentEndpointId());
+            ExpressParser.parse(expected.parentEndpointName())
+                         .assertValue("parent endpoint name", actual.parentEndpointName());
+            ExpressParser.parse(expected.refType()).assertValue("ref type", actual.refType());
+            ExpressParser.parse(expected.entryServiceInstanceId())
+                         .assertValue("entry application instance id", actual.entryServiceInstanceId());
+            return true;
+        } catch (ValueAssertFailedException e) {
+            throw new SegmentRefAssertFailedException(e, expected, actual);
+        }
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/SegmentRefAssertFailedCause.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/SegmentRefAssertFailedCause.java
new file mode 100644
index 0000000..571a4c8
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/SegmentRefAssertFailedCause.java
@@ -0,0 +1,39 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.SegmentRefAssertFailedException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.entity.SegmentRef;
+
+public class SegmentRefAssertFailedCause {
+    private final SegmentRefAssertFailedException failedCause;
+    private final SegmentRef actual;
+
+    public SegmentRefAssertFailedCause(SegmentRefAssertFailedException failedCause, SegmentRef actual) {
+        this.failedCause = failedCause;
+        this.actual = actual;
+    }
+
+    public SegmentRefAssertFailedException getFailedCause() {
+        return failedCause;
+    }
+
+    public SegmentRef getActual() {
+        return actual;
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/element/ElementAssertor.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/element/ElementAssertor.java
new file mode 100644
index 0000000..452fe8f
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/element/ElementAssertor.java
@@ -0,0 +1,31 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.element;
+
+public abstract class ElementAssertor {
+
+    public ElementAssertor(String exceptedValue) {
+        if (exceptedValue != null) {
+            this.exceptedValue = exceptedValue.trim();
+        }
+    }
+
+    protected String exceptedValue;
+
+    public abstract void assertValue(String desc, String actualValue);
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/element/EqualsAssertor.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/element/EqualsAssertor.java
new file mode 100644
index 0000000..c7cd568
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/element/EqualsAssertor.java
@@ -0,0 +1,34 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.element;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.ValueAssertFailedException;
+
+public class EqualsAssertor extends ElementAssertor {
+
+    public EqualsAssertor(String exceptedValue) {
+        super(exceptedValue);
+    }
+
+    @Override
+    public void assertValue(String desc, String actualValue) {
+        if (!exceptedValue.equals(actualValue)) {
+            throw new ValueAssertFailedException(desc, exceptedValue, actualValue);
+        }
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/element/GreatThanAssertor.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/element/GreatThanAssertor.java
new file mode 100644
index 0000000..ca2fecd
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/element/GreatThanAssertor.java
@@ -0,0 +1,34 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.element;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.ValueAssertFailedException;
+
+public class GreatThanAssertor extends ElementAssertor {
+
+    public GreatThanAssertor(String exceptedValue) {
+        super(exceptedValue);
+    }
+
+    @Override
+    public void assertValue(String desc, String actualValue) {
+        if (Long.parseLong(actualValue) <= Long.parseLong(exceptedValue)) {
+            throw new ValueAssertFailedException(desc, " gt " + exceptedValue, actualValue);
+        }
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/element/GreetEqualAssertor.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/element/GreetEqualAssertor.java
new file mode 100644
index 0000000..8c97fd6
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/element/GreetEqualAssertor.java
@@ -0,0 +1,34 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.element;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.ValueAssertFailedException;
+
+public class GreetEqualAssertor extends ElementAssertor {
+    public GreetEqualAssertor(String exceptedValue) {
+        super(exceptedValue);
+    }
+
+    @Override
+    public void assertValue(String desc, String actualValue) {
+        if (Long.parseLong(actualValue) < Long.parseLong(exceptedValue)) {
+            throw new ValueAssertFailedException(desc, " ge " + exceptedValue, actualValue);
+        }
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/element/NoopAssertor.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/element/NoopAssertor.java
new file mode 100644
index 0000000..bcec8f6
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/element/NoopAssertor.java
@@ -0,0 +1,29 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.element;
+
+public class NoopAssertor extends ElementAssertor {
+    public NoopAssertor() {
+        super(null);
+    }
+
+    @Override
+    public void assertValue(String desc, String actualValue) {
+
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/element/NotEqualsAssertor.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/element/NotEqualsAssertor.java
new file mode 100644
index 0000000..9f85d76
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/element/NotEqualsAssertor.java
@@ -0,0 +1,34 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.element;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.ValueAssertFailedException;
+
+public class NotEqualsAssertor extends ElementAssertor {
+
+    public NotEqualsAssertor(String exceptedValue) {
+        super(exceptedValue);
+    }
+
+    @Override
+    public void assertValue(String desc, String actualValue) {
+        if (exceptedValue.equals(actualValue.trim())) {
+            throw new ValueAssertFailedException(desc, " not eq " + exceptedValue, actualValue);
+        }
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/element/NotNullAssertor.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/element/NotNullAssertor.java
new file mode 100644
index 0000000..dcc5f2d
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/element/NotNullAssertor.java
@@ -0,0 +1,33 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.element;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.ValueAssertFailedException;
+
+public class NotNullAssertor extends ElementAssertor {
+    public NotNullAssertor() {
+        super(null);
+    }
+
+    @Override
+    public void assertValue(String desc, String actualValue) {
+        if (actualValue == null) {
+            throw new ValueAssertFailedException(desc, "not null", actualValue);
+        }
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/element/NullAssertor.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/element/NullAssertor.java
new file mode 100644
index 0000000..b30c3fa
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/element/NullAssertor.java
@@ -0,0 +1,33 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.element;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.ValueAssertFailedException;
+
+public class NullAssertor extends ElementAssertor {
+    public NullAssertor() {
+        super(null);
+    }
+
+    @Override
+    public void assertValue(String desc, String actualValue) {
+        if (actualValue != null && actualValue.length() > 0) {
+            throw new ValueAssertFailedException(desc, "null", actualValue);
+        }
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/ActualRegistryOperationNameEmptyException.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/ActualRegistryOperationNameEmptyException.java
new file mode 100644
index 0000000..6600b63
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/ActualRegistryOperationNameEmptyException.java
@@ -0,0 +1,36 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.exception;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.entity.RegistryOperationName;
+import org.apache.skywalking.plugin.test.agent.tool.validator.exception.AssertFailedException;
+
+public class ActualRegistryOperationNameEmptyException extends AssertFailedException {
+
+    private final RegistryOperationName registryOperationName;
+
+    public ActualRegistryOperationNameEmptyException(RegistryOperationName registryOperationName) {
+        this.registryOperationName = registryOperationName;
+    }
+
+    @Override
+    public String getCauseMessage() {
+        return String.format("ActualRegistryOperationNameEmptyException\nexpected:%s\nactual:%s\n", registryOperationName
+            .operationName(), "Empty");
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/ActualSegmentItemEmptyException.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/ActualSegmentItemEmptyException.java
new file mode 100644
index 0000000..4ce4c53
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/ActualSegmentItemEmptyException.java
@@ -0,0 +1,35 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.exception;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.entity.SegmentItem;
+import org.apache.skywalking.plugin.test.agent.tool.validator.exception.AssertFailedException;
+
+public class ActualSegmentItemEmptyException extends AssertFailedException {
+
+    private final SegmentItem expected;
+
+    public ActualSegmentItemEmptyException(SegmentItem expected) {
+        this.expected = expected;
+    }
+
+    @Override
+    public String getCauseMessage() {
+        return String.format("ActualSegmentItemEmptyException\nexpected: %s\nactual: %s", expected, "Empty");
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/ActualSegmentRefIsEmptyException.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/ActualSegmentRefIsEmptyException.java
new file mode 100644
index 0000000..23a5566
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/ActualSegmentRefIsEmptyException.java
@@ -0,0 +1,33 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.exception;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.exception.AssertFailedException;
+
+public class ActualSegmentRefIsEmptyException extends AssertFailedException {
+    private final int expectedSize;
+
+    public ActualSegmentRefIsEmptyException(int expectedSize) {
+        this.expectedSize = expectedSize;
+    }
+
+    @Override
+    public String getCauseMessage() {
+        return String.format("ActualSegmentRefIsEmptyException\nexpected: %d\nactual: %s\n", expectedSize, "Not found");
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/KeyValueNotEqualsException.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/KeyValueNotEqualsException.java
new file mode 100644
index 0000000..e3eb65f
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/KeyValueNotEqualsException.java
@@ -0,0 +1,21 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.exception;
+
+public class KeyValueNotEqualsException extends RuntimeException {
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/LogEventKeyNotEqualsException.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/LogEventKeyNotEqualsException.java
new file mode 100644
index 0000000..c649c96
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/LogEventKeyNotEqualsException.java
@@ -0,0 +1,35 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.exception;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.exception.AssertFailedException;
+
+public class LogEventKeyNotEqualsException extends AssertFailedException {
+    private final String expected;
+    private final String actual;
+
+    public LogEventKeyNotEqualsException(String expected, String actual) {
+        this.expected = expected;
+        this.actual = actual;
+    }
+
+    @Override
+    public String getCauseMessage() {
+        return String.format("[log event key]: expected=>{%s}, actual=>{%s}\n", expected, actual);
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/LogEventSizeNotEqualsException.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/LogEventSizeNotEqualsException.java
new file mode 100644
index 0000000..e79bb89
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/LogEventSizeNotEqualsException.java
@@ -0,0 +1,35 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.exception;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.exception.AssertFailedException;
+
+public class LogEventSizeNotEqualsException extends AssertFailedException {
+    private final int expected;
+    private final int actual;
+
+    public LogEventSizeNotEqualsException(int expected, int actual) {
+        this.expected = expected;
+        this.actual = actual;
+    }
+
+    @Override
+    public String getCauseMessage() {
+        return String.format("[log event size]: expected=>{%d}, actual=>{%d}\n", expected, actual);
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/LogEventValueNotEqualsException.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/LogEventValueNotEqualsException.java
new file mode 100644
index 0000000..407b27c
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/LogEventValueNotEqualsException.java
@@ -0,0 +1,37 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.exception;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.exception.AssertFailedException;
+
+public class LogEventValueNotEqualsException extends AssertFailedException {
+    private final String eventKey;
+    private final String expected;
+    private final String actual;
+
+    public LogEventValueNotEqualsException(String eventKey, String expected, String actual) {
+        this.eventKey = eventKey;
+        this.expected = expected;
+        this.actual = actual;
+    }
+
+    @Override
+    public String getCauseMessage() {
+        return String.format("[log(%s} value]: expected=>{%s}, actual=>{%s}\n", eventKey, expected, actual);
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/LogSizeNotEqualsException.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/LogSizeNotEqualsException.java
new file mode 100644
index 0000000..73f1573
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/LogSizeNotEqualsException.java
@@ -0,0 +1,35 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.exception;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.exception.AssertFailedException;
+
+public class LogSizeNotEqualsException extends AssertFailedException {
+    private final int expected;
+    private final int actual;
+
+    public LogSizeNotEqualsException(int expected, int actual) {
+        this.expected = expected;
+        this.actual = actual;
+    }
+
+    @Override
+    public String getCauseMessage() {
+        return String.format("[log size]: expected=>{%d}, actual=>{%d}", expected, actual);
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/ParentSegmentNotFoundException.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/ParentSegmentNotFoundException.java
new file mode 100644
index 0000000..dc59c13
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/ParentSegmentNotFoundException.java
@@ -0,0 +1,34 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.exception;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.exception.AssertFailedException;
+
+public class ParentSegmentNotFoundException extends AssertFailedException {
+
+    private final String express;
+
+    public ParentSegmentNotFoundException(String express) {
+        this.express = express;
+    }
+
+    @Override
+    public String getCauseMessage() {
+        return String.format("ParentSegmentNotFoundException\nexpected: %s\nactual: %s\n", express, "NOT FOUND");
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/RefSizeNotEqualsException.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/RefSizeNotEqualsException.java
new file mode 100644
index 0000000..c7a2c7b
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/RefSizeNotEqualsException.java
@@ -0,0 +1,36 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.exception;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.exception.AssertFailedException;
+
+public class RefSizeNotEqualsException extends AssertFailedException {
+
+    private final int expected;
+    private final int actual;
+
+    public RefSizeNotEqualsException(int expected, int actual) {
+        this.expected = expected;
+        this.actual = actual;
+    }
+
+    @Override
+    public String getCauseMessage() {
+        return String.format("[segment ref size]: expected=>{%s}, actual=>{%s}", expected, actual);
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/RegistryApplicationNotFoundException.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/RegistryApplicationNotFoundException.java
new file mode 100644
index 0000000..449207c
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/RegistryApplicationNotFoundException.java
@@ -0,0 +1,33 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.exception;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.exception.AssertFailedException;
+
+public class RegistryApplicationNotFoundException extends AssertFailedException {
+    private final String applicationCode;
+
+    public RegistryApplicationNotFoundException(String applicationCode) {
+        this.applicationCode = applicationCode;
+    }
+
+    @Override
+    public String getCauseMessage() {
+        return String.format("RegistryApplicationNotFoundException\nexpected: %s\nactual: %s\n", applicationCode, "Not Found");
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/RegistryApplicationSizeNotEqualsException.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/RegistryApplicationSizeNotEqualsException.java
new file mode 100644
index 0000000..b6e17ee
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/RegistryApplicationSizeNotEqualsException.java
@@ -0,0 +1,36 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.exception;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.exception.AssertFailedException;
+
+public class RegistryApplicationSizeNotEqualsException extends AssertFailedException {
+    private final String applicationCode;
+    private final ValueAssertFailedException cause;
+
+    public RegistryApplicationSizeNotEqualsException(String applicationCode, ValueAssertFailedException cause) {
+        this.applicationCode = applicationCode;
+        this.cause = cause;
+    }
+
+    @Override
+    public String getCauseMessage() {
+        return String.format("RegistryApplicationSizeNotEqualsException: %s\nexpected: %s\nactual: %s\n", applicationCode, cause
+            .getExpected(), cause.getActual());
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/RegistryInstanceOfApplicationNotFoundException.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/RegistryInstanceOfApplicationNotFoundException.java
new file mode 100644
index 0000000..ba41bd1
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/RegistryInstanceOfApplicationNotFoundException.java
@@ -0,0 +1,34 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.exception;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.exception.AssertFailedException;
+
+public class RegistryInstanceOfApplicationNotFoundException extends AssertFailedException {
+
+    private final String applicationCode;
+
+    public RegistryInstanceOfApplicationNotFoundException(String applicationCode) {
+        this.applicationCode = applicationCode;
+    }
+
+    @Override
+    public String getCauseMessage() {
+        return String.format("RegistryInstanceOfApplicationNotFoundException\nexpected: Instances of Service(%s)" + "\nactual: %s\n", applicationCode, "NOT FOUND");
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/RegistryInstanceSizeNotEqualsException.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/RegistryInstanceSizeNotEqualsException.java
new file mode 100644
index 0000000..283e72a
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/RegistryInstanceSizeNotEqualsException.java
@@ -0,0 +1,37 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.exception;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.exception.AssertFailedException;
+
+public class RegistryInstanceSizeNotEqualsException extends AssertFailedException {
+
+    private final String applicationCode;
+    private final ValueAssertFailedException cause;
+
+    public RegistryInstanceSizeNotEqualsException(String applicationCode, ValueAssertFailedException cause) {
+        this.applicationCode = applicationCode;
+        this.cause = cause;
+    }
+
+    @Override
+    public String getCauseMessage() {
+        return String.format("RegistryInstanceSizeNotEqualsException %s\nexpected: %s\nactual: %s\n", applicationCode, cause
+            .getExpected(), cause.getActual());
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/RegistryOperationNameNotFoundException.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/RegistryOperationNameNotFoundException.java
new file mode 100644
index 0000000..1cf2ec7
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/RegistryOperationNameNotFoundException.java
@@ -0,0 +1,35 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.exception;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.exception.AssertFailedException;
+
+public class RegistryOperationNameNotFoundException extends AssertFailedException {
+    private final String applicationCode;
+    private final String operationName;
+
+    public RegistryOperationNameNotFoundException(String applicationCode, String operationName) {
+        this.applicationCode = applicationCode;
+        this.operationName = operationName;
+    }
+
+    @Override
+    public String getCauseMessage() {
+        return String.format("RegistryOperationNameNotFoundException %s\nexpected: %s\nactual: %s\n", applicationCode, operationName, "NOT FOUND");
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/RegistryOperationNamesOfApplicationNotFoundException.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/RegistryOperationNamesOfApplicationNotFoundException.java
new file mode 100644
index 0000000..c416841
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/RegistryOperationNamesOfApplicationNotFoundException.java
@@ -0,0 +1,35 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.exception;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.entity.RegistryOperationName;
+import org.apache.skywalking.plugin.test.agent.tool.validator.exception.AssertFailedException;
+
+public class RegistryOperationNamesOfApplicationNotFoundException extends AssertFailedException {
+    private final RegistryOperationName applicationCode;
+
+    public RegistryOperationNamesOfApplicationNotFoundException(RegistryOperationName applicationCode) {
+        this.applicationCode = applicationCode;
+    }
+
+    @Override
+    public String getCauseMessage() {
+        return String.format("RegistryOperationNamesOfApplicationNotFoundException %s\nexpected: %s\nactual: %s\n", applicationCode
+            .serviceName(), applicationCode.operationName(), "NOT FOUND");
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/SegmentItemNotFoundException.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/SegmentItemNotFoundException.java
new file mode 100644
index 0000000..038fd41
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/SegmentItemNotFoundException.java
@@ -0,0 +1,33 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.exception;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.exception.AssertFailedException;
+
+public class SegmentItemNotFoundException extends AssertFailedException {
+    private final String applicationCode;
+
+    public SegmentItemNotFoundException(String applicationCode) {
+        this.applicationCode = applicationCode;
+    }
+
+    @Override
+    public String getCauseMessage() {
+        return String.format("SegmentItemNotFoundException\nexpected: %s\nactual: %s", applicationCode, "Not Found");
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/SegmentNotFoundException.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/SegmentNotFoundException.java
new file mode 100644
index 0000000..28ba9db
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/SegmentNotFoundException.java
@@ -0,0 +1,56 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.exception;
+
+import java.util.List;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.SegmentPredictionFailedCause;
+import org.apache.skywalking.plugin.test.agent.tool.validator.entity.Segment;
+import org.apache.skywalking.plugin.test.agent.tool.validator.entity.Span;
+import org.apache.skywalking.plugin.test.agent.tool.validator.exception.AssertFailedException;
+
+public class SegmentNotFoundException extends AssertFailedException {
+    private final Segment expectedSegment;
+    private final List<SegmentPredictionFailedCause> failedCauses;
+
+    public SegmentNotFoundException(Segment expectedSegment, List<SegmentPredictionFailedCause> failedCauses) {
+        this.expectedSegment = expectedSegment;
+        this.failedCauses = failedCauses;
+    }
+
+    @Override
+    public String getCauseMessage() {
+        StringBuilder expectedMessage = new StringBuilder("\n  Segment:\n");
+        for (Span span : expectedSegment.spans()) {
+            expectedMessage.append(String.format("  - span[%s, %s] %s\n", span.parentSpanId(), span.spanId(), span.operationName()));
+        }
+
+        StringBuilder causeMessage = new StringBuilder();
+        for (SegmentPredictionFailedCause cause : failedCauses) {
+            Segment actualSegment = cause.getActualSegment();
+            Span actualSpan = cause.getSpanAssertFailedCause().getActualSpan();
+            Span expectedSpan = cause.getSpanAssertFailedCause().getExceptedSpan();
+
+            causeMessage.append(String.format("\n  Segment[%s] e\n  expected:\tSpan[%s, %s] %s\n  " + "actual:" + "\tspan[%s, %s] %s\n  reason:\t%s\n", actualSegment
+                .segmentId(), expectedSpan.parentSpanId(), expectedSpan.spanId(), expectedSpan.operationName(), actualSpan
+                .parentSpanId(), actualSpan.spanId(), actualSpan.operationName(), cause.getSpanAssertFailedCause()
+                                                                                       .getCauseMessage()));
+        }
+
+        return String.format("SegmentNotFoundException:\nexpected: %s\nactual: %s\n", expectedMessage, causeMessage);
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/SegmentRefAssertFailedException.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/SegmentRefAssertFailedException.java
new file mode 100644
index 0000000..f616190
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/SegmentRefAssertFailedException.java
@@ -0,0 +1,38 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.exception;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.entity.SegmentRef;
+import org.apache.skywalking.plugin.test.agent.tool.validator.exception.AssertFailedException;
+
+public class SegmentRefAssertFailedException extends AssertFailedException {
+    private final ValueAssertFailedException e;
+    private final SegmentRef expected;
+    private final SegmentRef actual;
+
+    public SegmentRefAssertFailedException(ValueAssertFailedException e, SegmentRef expected, SegmentRef actual) {
+        this.e = e;
+        this.expected = expected;
+        this.actual = actual;
+    }
+
+    @Override
+    public String getCauseMessage() {
+        return e.getCauseMessage();
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/SegmentRefNotFoundException.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/SegmentRefNotFoundException.java
new file mode 100644
index 0000000..49f4e1f
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/SegmentRefNotFoundException.java
@@ -0,0 +1,56 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.exception;
+
+import java.util.List;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.SegmentRefAssertFailedCause;
+import org.apache.skywalking.plugin.test.agent.tool.validator.entity.SegmentRef;
+import org.apache.skywalking.plugin.test.agent.tool.validator.exception.AssertFailedException;
+
+public class SegmentRefNotFoundException extends AssertFailedException {
+    private final SegmentRef expected;
+    private final List<SegmentRefAssertFailedCause> causes;
+
+    public SegmentRefNotFoundException(SegmentRef expected, List<SegmentRefAssertFailedCause> causes) {
+        this.expected = expected;
+        this.causes = causes;
+    }
+
+    @Override
+    public String getCauseMessage() {
+
+        StringBuilder actualMessage = new StringBuilder();
+        for (SegmentRefAssertFailedCause cause : causes) {
+            SegmentRef actual = cause.getActual();
+            String reason = cause.getFailedCause().getCauseMessage();
+
+            StringBuilder actualSegmentRef = new StringBuilder(String.format("\nSegmentRef:\t%s\n", reason));
+            actualSegmentRef.append(String.format(" - entryServiceName:\t\t%s\n", actual.entryEndpointName()))
+                            .append(String.format(" - networkAddress:\t\t\t%s\n", actual.networkAddress()))
+                            .append(String.format(" - parentServiceName:\t\t%s\n", actual.parentEndpointName()))
+                            .append(String.format(" - parentSpanId:\t\t\t%s\n", actual.parentSpanId()))
+                            .append(String.format(" - parentTraceSegmentId:\t%s\n", actual.parentTraceSegmentId()))
+                            .append(String.format(" - refType:\t\t\t\t\t%s", actual.refType()))
+                            .toString();
+
+            actualMessage.append(String.format("%s\n", actualSegmentRef));
+        }
+
+        return String.format("SegmentRefNotFoundException\nexpected: %s\nactual: %s\n", expected, actualMessage);
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/SegmentRefSizeNotEqualsException.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/SegmentRefSizeNotEqualsException.java
new file mode 100644
index 0000000..fa57496
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/SegmentRefSizeNotEqualsException.java
@@ -0,0 +1,35 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.exception;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.exception.AssertFailedException;
+
+public class SegmentRefSizeNotEqualsException extends AssertFailedException {
+    private final int expected;
+    private final int actual;
+
+    public SegmentRefSizeNotEqualsException(int expected, int actual) {
+        this.expected = expected;
+        this.actual = actual;
+    }
+
+    @Override
+    public String getCauseMessage() {
+        return String.format("SegmentRefSizeNotEqualsException\nexpected:\t%s\nactual:\t%s\n", expected, actual);
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/SegmentSizeNotEqualsException.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/SegmentSizeNotEqualsException.java
new file mode 100644
index 0000000..6ec8e56
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/SegmentSizeNotEqualsException.java
@@ -0,0 +1,37 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.exception;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.exception.AssertFailedException;
+
+public class SegmentSizeNotEqualsException extends AssertFailedException {
+    private final String applicationCode;
+    private final String expected;
+    private final String actual;
+
+    public SegmentSizeNotEqualsException(String applicationCode, String expected, String actual) {
+        this.applicationCode = applicationCode;
+        this.expected = expected;
+        this.actual = actual;
+    }
+
+    @Override
+    public String getCauseMessage() {
+        return String.format("SegmentSizeNotEqualsException:\t%s\nexpected:\t%s\nactual:\t\t%s\n", applicationCode, expected, actual);
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/SpanAssertFailedException.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/SpanAssertFailedException.java
new file mode 100644
index 0000000..e5ae437
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/SpanAssertFailedException.java
@@ -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.
+ */
+
+package org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.entity.Span;
+import org.apache.skywalking.plugin.test.agent.tool.validator.exception.AssertFailedException;
+
+public class SpanAssertFailedException extends AssertFailedException {
+    private final AssertFailedException failedCause;
+    private final Span exceptedSpan;
+    private final Span actualSpan;
+
+    public SpanAssertFailedException(AssertFailedException failedCause, Span exceptedSpan, Span actualSpan) {
+        this.failedCause = failedCause;
+        this.exceptedSpan = exceptedSpan;
+        this.actualSpan = actualSpan;
+    }
+
+    public Span getExceptedSpan() {
+        return exceptedSpan;
+    }
+
+    public Span getActualSpan() {
+        return actualSpan;
+    }
+
+    @Override
+    public String getCauseMessage() {
+        return failedCause.getCauseMessage();
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/SpanSizeNotEqualsException.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/SpanSizeNotEqualsException.java
new file mode 100644
index 0000000..702ab45
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/SpanSizeNotEqualsException.java
@@ -0,0 +1,36 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.exception;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.exception.AssertFailedException;
+
+public class SpanSizeNotEqualsException extends AssertFailedException {
+
+    private final int expected;
+    private final int actual;
+
+    public SpanSizeNotEqualsException(int expected, int actual) {
+        this.expected = expected;
+        this.actual = actual;
+    }
+
+    @Override
+    public String getCauseMessage() {
+        return String.format("[span size]: expected=>{%s}, actual=>{%s}\n", expected, actual);
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/TagKeyNotEqualsException.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/TagKeyNotEqualsException.java
new file mode 100644
index 0000000..8eef92d
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/TagKeyNotEqualsException.java
@@ -0,0 +1,35 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.exception;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.exception.AssertFailedException;
+
+public class TagKeyNotEqualsException extends AssertFailedException {
+    private final String expected;
+    private final String actual;
+
+    public TagKeyNotEqualsException(String expected, String actual) {
+        this.expected = expected;
+        this.actual = actual;
+    }
+
+    @Override
+    public String getCauseMessage() {
+        return String.format("[tag key]: expected=>{%s}, actual=>{%s}\n", expected, actual);
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/TagSizeNotEqualsException.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/TagSizeNotEqualsException.java
new file mode 100644
index 0000000..b09e6bf
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/TagSizeNotEqualsException.java
@@ -0,0 +1,35 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.exception;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.exception.AssertFailedException;
+
+public class TagSizeNotEqualsException extends AssertFailedException {
+    private final int expected;
+    private final int actual;
+
+    public TagSizeNotEqualsException(int expected, int actual) {
+        this.expected = expected;
+        this.actual = actual;
+    }
+
+    @Override
+    public String getCauseMessage() {
+        return String.format("[tag size]: expected=>{%s}, actual=>{%s}\n", expected, actual);
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/TagValueNotEqualsException.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/TagValueNotEqualsException.java
new file mode 100644
index 0000000..6c8d41f
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/TagValueNotEqualsException.java
@@ -0,0 +1,37 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.exception;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.exception.AssertFailedException;
+
+public class TagValueNotEqualsException extends AssertFailedException {
+    private final String tagKey;
+    private final String expected;
+    private final String actual;
+
+    public TagValueNotEqualsException(String tagKey, String expected, String actual) {
+        this.tagKey = tagKey;
+        this.expected = expected;
+        this.actual = actual;
+    }
+
+    @Override
+    public String getCauseMessage() {
+        return String.format("[tag(%s) value]: expected=>{}, actual=>{%s}\n", tagKey, expected, actual);
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/TypeUndefinedException.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/TypeUndefinedException.java
new file mode 100644
index 0000000..aef9b1a
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/TypeUndefinedException.java
@@ -0,0 +1,27 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.exception;
+
+public class TypeUndefinedException extends Exception {
+
+    public TypeUndefinedException(String message) {
+        super(message);
+    }
+
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/ValueAssertFailedException.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/ValueAssertFailedException.java
new file mode 100644
index 0000000..7f7d120
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/assertor/exception/ValueAssertFailedException.java
@@ -0,0 +1,49 @@
+/*
+ * 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.plugin.test.agent.tool.validator.assertor.exception;
+
+import org.apache.skywalking.plugin.test.agent.tool.validator.exception.AssertFailedException;
+
+public class ValueAssertFailedException extends AssertFailedException {
+    private final String desc;
+    private final String expected;
+    private final String actual;
+
+    public ValueAssertFailedException(String desc, String expected, String actual) {
+        this.desc = desc;
+        this.expected = expected;
+        this.actual = actual;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public String getExpected() {
+        return expected;
+    }
+
+    public String getActual() {
+        return actual;
+    }
+
+    @Override
+    public String getCauseMessage() {
+        return String.format("[%s]: expected=>{%s}, actual=>{%s}", desc, expected, actual);
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/Data.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/Data.java
new file mode 100644
index 0000000..fa45668
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/Data.java
@@ -0,0 +1,76 @@
+/*
+ * 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.plugin.test.agent.tool.validator.entity;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.List;
+import org.apache.skywalking.plugin.test.agent.tool.validator.exception.IllegalDataFileException;
+import org.yaml.snakeyaml.TypeDescription;
+import org.yaml.snakeyaml.Yaml;
+import org.yaml.snakeyaml.constructor.Constructor;
+import org.yaml.snakeyaml.representer.Representer;
+
+public interface Data {
+    RegistryItems registryItems();
+
+    List<SegmentItem> segmentItems();
+
+    class Loader {
+        public static Data loadData(String fileName, File file) {
+            try {
+                return loadData(new FileInputStream(file));
+            } catch (Exception e) {
+                throw new IllegalDataFileException(fileName);
+            }
+        }
+
+        public static Data loadData(InputStream inputStream) {
+            Constructor constructor = new Constructor(DataForRead.class);
+            TypeDescription configDescription = new TypeDescription(DataForRead.class);
+            configDescription.putListPropertyType("data", DataForRead.class);
+
+            Representer representer = new Representer();
+            representer.getPropertyUtils().setSkipMissingProperties(true);
+            Yaml yaml = new Yaml(constructor, representer);
+            Data result = yaml.loadAs(inputStream, DataForRead.class);
+            if (result == null) {
+                throw new RuntimeException();
+            } else {
+                return result;
+            }
+        }
+
+        public static Data loadData(String data) {
+            Constructor constructor = new Constructor(DataForRead.class);
+            TypeDescription configDescription = new TypeDescription(DataForRead.class);
+            configDescription.putListPropertyType("data", DataForRead.class);
+
+            Representer representer = new Representer();
+            representer.getPropertyUtils().setSkipMissingProperties(true);
+            Yaml yaml = new Yaml(constructor, representer);
+            Data result = yaml.loadAs(data, DataForRead.class);
+            if (result == null) {
+                throw new RuntimeException();
+            } else {
+                return result;
+            }
+        }
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/DataForRead.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/DataForRead.java
new file mode 100644
index 0000000..c206f9f
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/DataForRead.java
@@ -0,0 +1,42 @@
+/*
+ * 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.plugin.test.agent.tool.validator.entity;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@lombok.Data
+public class DataForRead implements Data {
+    private RegistryItemsForRead registryItems;
+    private List<SegmentItemForRead> segmentItems;
+
+    @Override
+    public RegistryItemsForRead registryItems() {
+        return registryItems;
+    }
+
+    @Override
+    public List<SegmentItem> segmentItems() {
+        if (this.segmentItems == null) {
+            return null;
+        }
+
+        return new ArrayList<>(this.segmentItems);
+    }
+
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/KeyValuePair.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/KeyValuePair.java
new file mode 100644
index 0000000..8032baa
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/KeyValuePair.java
@@ -0,0 +1,44 @@
+/*
+ * 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.plugin.test.agent.tool.validator.entity;
+
+public interface KeyValuePair {
+    String key();
+
+    String value();
+
+    class Impl implements KeyValuePair {
+        private String key;
+        private String value;
+
+        public Impl(String key, String value) {
+            this.key = key;
+            this.value = value;
+        }
+
+        @Override
+        public String key() {
+            return key;
+        }
+
+        @Override
+        public String value() {
+            return value;
+        }
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/LogEvent.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/LogEvent.java
new file mode 100644
index 0000000..f4158f7
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/LogEvent.java
@@ -0,0 +1,42 @@
+/*
+ * 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.plugin.test.agent.tool.validator.entity;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public interface LogEvent {
+    List<KeyValuePair> events();
+
+    class Impl implements LogEvent {
+        private List<KeyValuePair> keyValuePairs;
+
+        Impl() {
+            keyValuePairs = new ArrayList<>();
+        }
+
+        void add(String key, String value) {
+            keyValuePairs.add(new KeyValuePair.Impl(key, value));
+        }
+
+        @Override
+        public List<KeyValuePair> events() {
+            return keyValuePairs;
+        }
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/RegistryApplication.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/RegistryApplication.java
new file mode 100644
index 0000000..760fa70
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/RegistryApplication.java
@@ -0,0 +1,44 @@
+/*
+ * 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.plugin.test.agent.tool.validator.entity;
+
+public interface RegistryApplication {
+    String applicationCode();
+
+    String expressValue();
+
+    class Impl implements RegistryApplication {
+        private String applicationCode;
+        private String express;
+
+        Impl(String code, String express) {
+            this.applicationCode = code;
+            this.express = express;
+        }
+
+        @Override
+        public String applicationCode() {
+            return applicationCode;
+        }
+
+        @Override
+        public String expressValue() {
+            return express;
+        }
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/RegistryInstance.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/RegistryInstance.java
new file mode 100644
index 0000000..766fdf0
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/RegistryInstance.java
@@ -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.
+ */
+
+package org.apache.skywalking.plugin.test.agent.tool.validator.entity;
+
+public interface RegistryInstance {
+
+    String applicationCode();
+
+    String expressValue();
+
+    class Impl implements RegistryInstance {
+
+        private final String code;
+        private final String express;
+
+        Impl(String code, String express) {
+            this.code = code;
+            this.express = express;
+        }
+
+        @Override
+        public String applicationCode() {
+            return code;
+        }
+
+        @Override
+        public String expressValue() {
+            return express;
+        }
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/RegistryItems.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/RegistryItems.java
new file mode 100644
index 0000000..279f41a
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/RegistryItems.java
@@ -0,0 +1,28 @@
+/*
+ * 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.plugin.test.agent.tool.validator.entity;
+
+import java.util.List;
+
+public interface RegistryItems {
+    List<RegistryApplication> applications();
+
+    List<RegistryInstance> instances();
+
+    List<RegistryOperationName> operationNames();
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/RegistryItemsForRead.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/RegistryItemsForRead.java
new file mode 100644
index 0000000..071a1af
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/RegistryItemsForRead.java
@@ -0,0 +1,75 @@
+/*
+ * 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.plugin.test.agent.tool.validator.entity;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import lombok.Data;
+
+@Data
+public class RegistryItemsForRead implements RegistryItems {
+    private List<Map<String, String>> applications;
+    private List<Map<String, String>> instances;
+    private List<Map<String, List<String>>> operationNames;
+
+    @Override
+    public List<RegistryApplication> applications() {
+        if (this.applications == null) {
+            return null;
+        }
+
+        List<RegistryApplication> registryApplications = new ArrayList<>();
+        for (Map<String, String> registryApplication : applications) {
+            String applicationCode = new ArrayList<String>(registryApplication.keySet()).get(0);
+            String express = String.valueOf(registryApplication.get(applicationCode));
+            registryApplications.add(new RegistryApplication.Impl(applicationCode, express));
+        }
+        return registryApplications;
+    }
+
+    @Override
+    public List<RegistryInstance> instances() {
+        if (this.instances == null) {
+            return null;
+        }
+
+        List<RegistryInstance> registryInstances = new ArrayList<>();
+        instances.forEach((registryInstance) -> {
+            String applicationCode = new ArrayList<String>(registryInstance.keySet()).get(0);
+            String express = String.valueOf(registryInstance.get(applicationCode));
+            registryInstances.add(new RegistryInstance.Impl(applicationCode, express));
+        });
+        return registryInstances;
+    }
+
+    @Override
+    public List<RegistryOperationName> operationNames() {
+        if (this.operationNames == null) {
+            return null;
+        }
+
+        List<RegistryOperationName> registryOperationNames = new ArrayList<>();
+        operationNames.forEach((registryInstance) -> {
+            String applicationCode = new ArrayList<String>(registryInstance.keySet()).get(0);
+            List<String> express = registryInstance.get(applicationCode);
+            registryOperationNames.add(new RegistryOperationName.Impl(applicationCode, express));
+        });
+        return registryOperationNames;
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/RegistryOperationName.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/RegistryOperationName.java
new file mode 100644
index 0000000..bcff123
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/RegistryOperationName.java
@@ -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.
+ */
+
+package org.apache.skywalking.plugin.test.agent.tool.validator.entity;
+
+import java.util.List;
+
+public interface RegistryOperationName {
+    String serviceName();
+
+    List<String> operationName();
+
+    class Impl implements RegistryOperationName {
+        private final String code;
+        private final List<String> express;
+
+        Impl(String code, List<String> express) {
+            this.code = code;
+            this.express = express;
+        }
+
+        @Override
+        public String serviceName() {
+            return code;
+        }
+
+        @Override
+        public List<String> operationName() {
+            return express;
+        }
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/Segment.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/Segment.java
new file mode 100644
index 0000000..6f42e22
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/Segment.java
@@ -0,0 +1,28 @@
+/*
+ * 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.plugin.test.agent.tool.validator.entity;
+
+import java.util.List;
+
+public interface Segment {
+    String segmentId();
+
+    List<Span> spans();
+
+    void setSegmentId(String segmentId);
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/SegmentForRead.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/SegmentForRead.java
new file mode 100644
index 0000000..36e5fdc
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/SegmentForRead.java
@@ -0,0 +1,378 @@
+/*
+ * 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.plugin.test.agent.tool.validator.entity;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import lombok.Data;
+
+public class SegmentForRead implements Segment {
+    private String segmentId;
+    private List<SpanForRead> spans;
+
+    @Override
+    public String segmentId() {
+        return segmentId;
+    }
+
+    @Override
+    public List<Span> spans() {
+        if (spans == null) {
+            return null;
+        }
+        return new ArrayList<>(spans);
+    }
+
+    @Data
+    public static class SegmentRefForRead implements SegmentRef {
+        private String parentEndpointId;
+        private String parentEndpoint;
+        private String networkAddressId;
+        private String entryEndpointId;
+        private String refType;
+        private String parentSpanId;
+        private String parentTraceSegmentId;
+        private String parentServiceInstanceId;
+        private String networkAddress;
+        private String entryEndpoint;
+        private String entryServiceInstanceId;
+
+        public SegmentRefForRead() {
+        }
+
+        public SegmentRefForRead(Map<String, Object> ref) {
+            this.networkAddress = ref.get("networkAddress").toString();
+            this.entryEndpoint = ref.get("entryEndpoint").toString();
+            this.parentEndpoint = ref.get("parentEndpoint").toString();
+            this.parentTraceSegmentId = ref.get("parentTraceSegmentId").toString();
+            this.entryServiceInstanceId = ref.get("entryServiceInstanceId").toString();
+            this.refType = ref.get("refType") == null ? null : ref.get("refType").toString();
+            this.parentSpanId = ref.get("parentSpanId") == null ? null : ref.get("parentSpanId").toString();
+            this.entryEndpointId = ref.get("entryEndpointId") == null ? null : ref.get("entryEndpointId").toString();
+            this.parentEndpointId = ref.get("parentEndpointId") == null ? null : ref.get("parentEndpointId").toString();
+            this.networkAddressId = ref.get("networkAddressId") == null ? null : ref.get("networkAddressId").toString();
+            this.parentServiceInstanceId = ref.get("parentServiceInstanceId") == null ? null : ref.get("parentServiceInstanceId")
+                                                                                                  .toString();
+        }
+
+        @Override
+        public String parentEndpointId() {
+            return parentEndpointId;
+        }
+
+        @Override
+        public String parentEndpointName() {
+            return parentEndpoint;
+        }
+
+        @Override
+        public String networkAddressId() {
+            return networkAddressId;
+        }
+
+        @Override
+        public String entryEndpointId() {
+            return entryEndpointId;
+        }
+
+        @Override
+        public String refType() {
+            return refType;
+        }
+
+        @Override
+        public String parentSpanId() {
+            return parentSpanId;
+        }
+
+        @Override
+        public String parentTraceSegmentId() {
+            return parentTraceSegmentId;
+        }
+
+        @Override
+        public String parentServiceInstanceId() {
+            return parentServiceInstanceId;
+        }
+
+        @Override
+        public String networkAddress() {
+            return networkAddress;
+        }
+
+        @Override
+        public String entryEndpointName() {
+            return entryEndpoint;
+        }
+
+        @Override
+        public void parentTraceSegmentId(String parentTraceSegmentId) {
+            this.parentTraceSegmentId = parentTraceSegmentId;
+        }
+
+        @Override
+        public String entryServiceInstanceId() {
+            return entryServiceInstanceId;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder actualSegmentRef = new StringBuilder("\nSegmentRef:\n");
+            return actualSegmentRef.append(String.format(" - entryServiceName:\t\t%s\n", entryEndpointName()))
+                                   .append(String.format(" - networkAddress:\t\t\t%s\n", networkAddress()))
+                                   .append(String.format(" - parentServiceName:\t\t%s\n", parentEndpointName()))
+                                   .append(String.format(" - parentSpanId:\t\t\t%s\n", parentSpanId()))
+                                   .append(String.format(" - parentTraceSegmentId:\t%s\n", parentTraceSegmentId()))
+                                   .append(String.format(" - refType:\t\t\t\t\t%s", refType()))
+                                   .toString();
+        }
+    }
+
+    public static class SpanForRead implements Span {
+        private String operationName;
+        private String operationId;
+        private String parentSpanId;
+        private String spanId;
+        private String spanLayer;
+        private List<Map<String, String>> tags;
+        private List<Map<String, List<Map<String, String>>>> logs;
+        private List<Map<String, Object>> refs;
+        private List<SegmentRef> formatedRefs;
+        private List<SegmentRef> actualRefs;
+        private String startTime;
+        private String endTime;
+        private String componentId;
+        private String componentName;
+        private String isError;
+        private String spanType;
+        private String peer;
+        private String peerId;
+
+        public void setOperationName(String operationName) {
+            this.operationName = operationName;
+        }
+
+        public void setOperationId(String operationId) {
+            this.operationId = operationId;
+        }
+
+        public void setParentSpanId(String parentSpanId) {
+            this.parentSpanId = parentSpanId;
+        }
+
+        public void setSpanId(String spanId) {
+            this.spanId = spanId;
+        }
+
+        public void setSpanLayer(String spanLayer) {
+            this.spanLayer = spanLayer;
+        }
+
+        public void setTags(List<Map<String, String>> tags) {
+            this.tags = tags;
+        }
+
+        public void setLogs(List<Map<String, List<Map<String, String>>>> logs) {
+            this.logs = logs;
+        }
+
+        public void setStartTime(String startTime) {
+            this.startTime = startTime;
+        }
+
+        public void setEndTime(String endTime) {
+            this.endTime = endTime;
+        }
+
+        public void setComponentId(String componentId) {
+            this.componentId = componentId;
+        }
+
+        public void setComponentName(String componentName) {
+            this.componentName = componentName;
+        }
+
+        public void setError(String error) {
+            isError = error;
+        }
+
+        public void setSpanType(String spanType) {
+            this.spanType = spanType;
+        }
+
+        public void setPeer(String peer) {
+            this.peer = peer;
+        }
+
+        public void setPeerId(String peerId) {
+            this.peerId = peerId;
+        }
+
+        public void setRefs(List<Map<String, Object>> refs) {
+            this.refs = refs;
+        }
+
+        @Override
+        public String operationName() {
+            return operationName;
+        }
+
+        @Override
+        public String operationId() {
+            return operationId;
+        }
+
+        @Override
+        public String parentSpanId() {
+            return parentSpanId;
+        }
+
+        @Override
+        public String spanId() {
+            return spanId;
+        }
+
+        @Override
+        public String spanLayer() {
+            return spanLayer;
+        }
+
+        @Override
+        public List<KeyValuePair> tags() {
+            if (tags == null) {
+                return new ArrayList<>();
+            }
+            List<KeyValuePair> result = new ArrayList<>();
+            for (Map<String, String> tag : tags) {
+                result.add(new KeyValuePair.Impl(tag.get("key"), tag.get("value")));
+            }
+            return result;
+        }
+
+        @Override
+        public List<LogEvent> logs() {
+            if (logs == null) {
+                return new ArrayList<>();
+            }
+            List<LogEvent> result = new ArrayList<>();
+            for (Map<String, List<Map<String, String>>> log : logs) {
+                List<Map<String, String>> events = log.get("logEvent");
+                LogEvent.Impl logEvent = new LogEvent.Impl();
+                for (Map<String, String> event : events) {
+                    logEvent.add(event.get("key"), event.get("value"));
+                }
+                result.add(logEvent);
+            }
+
+            return result;
+        }
+
+        @Override
+        public String startTime() {
+            return startTime;
+        }
+
+        @Override
+        public String endTime() {
+            return endTime;
+        }
+
+        @Override
+        public String componentId() {
+            return componentId;
+        }
+
+        @Override
+        public String componentName() {
+            return componentName;
+        }
+
+        @Override
+        public String error() {
+            return isError;
+        }
+
+        @Override
+        public String spanType() {
+            return spanType;
+        }
+
+        @Override
+        public String peer() {
+            return peer;
+        }
+
+        @Override
+        public String peerId() {
+            return peerId;
+        }
+
+        @Override
+        public List<SegmentRef> refs() {
+            if (formatedRefs == null && refs != null) {
+                List<SegmentRef> segmentRefs = new ArrayList<>();
+                for (Map<String, Object> ref : refs) {
+                    segmentRefs.add(new SegmentRefForRead(ref));
+                }
+
+                this.formatedRefs = segmentRefs;
+            }
+            return formatedRefs;
+        }
+
+        @Override
+        public void setActualRefs(List<SegmentRef> refs) {
+            this.actualRefs = refs;
+        }
+
+        @Override
+        public List<SegmentRef> actualRefs() {
+            return actualRefs;
+        }
+    }
+
+    public static class LogEventForRead {
+        private List<Map<String, String>> logEvent;
+
+        public List<Map<String, String>> getLogEvent() {
+            return logEvent;
+        }
+
+        public void setLogEvent(List<Map<String, String>> logEvent) {
+            this.logEvent = logEvent;
+        }
+    }
+
+    public String getSegmentId() {
+        return segmentId;
+    }
+
+    public List<SpanForRead> getSpans() {
+        return spans;
+    }
+
+    @Override
+    public void setSegmentId(String segmentId) {
+        this.segmentId = segmentId;
+    }
+
+    public void setSpans(List<SpanForRead> spans) {
+        this.spans = spans;
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/SegmentItem.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/SegmentItem.java
new file mode 100644
index 0000000..7b0bc67
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/SegmentItem.java
@@ -0,0 +1,28 @@
+/*
+ * 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.plugin.test.agent.tool.validator.entity;
+
+import java.util.List;
+
+public interface SegmentItem {
+    String serviceName();
+
+    String segmentSize();
+
+    List<Segment> segments();
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/SegmentItemForRead.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/SegmentItemForRead.java
new file mode 100644
index 0000000..ab4b3c6
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/SegmentItemForRead.java
@@ -0,0 +1,54 @@
+/*
+ * 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.plugin.test.agent.tool.validator.entity;
+
+import java.util.ArrayList;
+import java.util.List;
+import lombok.Data;
+
+@Data
+public class SegmentItemForRead implements SegmentItem {
+    private String serviceName;
+    private String segmentSize;
+    private List<SegmentForRead> segments;
+
+    @Override
+    public String serviceName() {
+        return serviceName;
+    }
+
+    @Override
+    public String segmentSize() {
+        return segmentSize;
+    }
+
+    @Override
+    public List<Segment> segments() {
+        if (segments == null) {
+            return null;
+        }
+        return new ArrayList<>(segments);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder message = new StringBuilder(String.format("\nSegment Item[%s]", serviceName));
+        message.append(String.format(" - segment size:\t\t%s\n", segmentSize));
+        return message.toString();
+    }
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/SegmentRef.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/SegmentRef.java
new file mode 100644
index 0000000..77cf0b7
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/SegmentRef.java
@@ -0,0 +1,45 @@
+/*
+ * 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.plugin.test.agent.tool.validator.entity;
+
+public interface SegmentRef {
+
+    String parentEndpointId();
+
+    String parentEndpointName();
+
+    String networkAddressId();
+
+    String entryEndpointId();
+
+    String refType();
+
+    String parentSpanId();
+
+    String parentTraceSegmentId();
+
+    String parentServiceInstanceId();
+
+    String networkAddress();
+
+    String entryEndpointName();
+
+    void parentTraceSegmentId(String parentTraceSegmentId);
+
+    String entryServiceInstanceId();
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/Span.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/Span.java
new file mode 100644
index 0000000..ea1bc99
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/entity/Span.java
@@ -0,0 +1,58 @@
+/*
+ * 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.plugin.test.agent.tool.validator.entity;
+
+import java.util.List;
+
+public interface Span {
+    String operationName();
+
+    String operationId();
+
+    String parentSpanId();
+
+    String spanId();
+
+    String spanLayer();
+
+    List<KeyValuePair> tags();
+
+    List<LogEvent> logs();
+
+    String startTime();
+
+    String endTime();
+
+    String componentId();
+
+    String componentName();
+
+    String error();
+
+    String spanType();
+
+    String peer();
+
+    String peerId();
+
+    List<SegmentRef> refs();
+
+    void setActualRefs(List<SegmentRef> refs);
+
+    List<SegmentRef> actualRefs();
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/exception/AssertFailedException.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/exception/AssertFailedException.java
new file mode 100644
index 0000000..902c346
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/exception/AssertFailedException.java
@@ -0,0 +1,29 @@
+/*
+ * 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.plugin.test.agent.tool.validator.exception;
+
+public abstract class AssertFailedException extends RuntimeException {
+    protected AssertFailedException(String message) {
+        super(message);
+    }
+
+    protected AssertFailedException() {
+    }
+
+    public abstract String getCauseMessage();
+}
diff --git a/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/exception/IllegalDataFileException.java b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/exception/IllegalDataFileException.java
new file mode 100644
index 0000000..a80fa67
--- /dev/null
+++ b/test/e2e/validator/src/main/java/org/apache/skywalking/plugin/test/agent/tool/validator/exception/IllegalDataFileException.java
@@ -0,0 +1,31 @@
+/*
+ * 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.plugin.test.agent.tool.validator.exception;
+
+public class IllegalDataFileException extends AssertFailedException {
+    private final String fileName;
+
+    public IllegalDataFileException(String fileName) {
+        this.fileName = fileName;
+    }
+
+    @Override
+    public String getCauseMessage() {
+        return String.format("IllegalDataFileException %s ", fileName);
+    }
+}
diff --git a/test/e2e/validator/src/main/resources/log4j2.xml b/test/e2e/validator/src/main/resources/log4j2.xml
new file mode 100644
index 0000000..342bd6d
--- /dev/null
+++ b/test/e2e/validator/src/main/resources/log4j2.xml
@@ -0,0 +1,37 @@
+<?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.
+  ~
+  -->
+<Configuration status="INFO">
+    <Appenders>
+        <Console name="console_out" target="SYSTEM_OUT">
+            <ThresholdFilter level="INFO"/>
+            <PatternLayout charset="UTF-8" pattern="[%d{yyyy-MM-dd HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
+        </Console>
+
+        <Console name="console_err" target="SYSTEM_ERR">
+            <ThresholdFilter level="ERROR"/>
+            <PatternLayout charset="UTF-8" pattern="[%d{yyyy-MM-dd HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
+        </Console>
+    </Appenders>
+    <Loggers>
+        <Root level="INFO">
+            <AppenderRef ref="console_err"/>
+            <AppenderRef ref="console_out"/>
+        </Root>
+    </Loggers>
+</Configuration>
\ No newline at end of file
diff --git a/test/e2e/validator/src/test/java/org/apache/skywalking/plugin/test/validator/validator/assertor/DataAssertIT.java b/test/e2e/validator/src/test/java/org/apache/skywalking/plugin/test/validator/validator/assertor/DataAssertIT.java
new file mode 100644
index 0000000..4b7377c
--- /dev/null
+++ b/test/e2e/validator/src/test/java/org/apache/skywalking/plugin/test/validator/validator/assertor/DataAssertIT.java
@@ -0,0 +1,114 @@
+/*
+ * 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.plugin.test.validator.validator.assertor;
+
+import com.google.common.io.ByteStreams;
+import com.google.gson.Gson;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParser;
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.nio.file.Files;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.DataAssert;
+import org.apache.skywalking.plugin.test.agent.tool.validator.assertor.exception.TypeUndefinedException;
+import org.apache.skywalking.plugin.test.agent.tool.validator.entity.Data;
+import org.apache.skywalking.plugin.test.agent.tool.validator.entity.DataForRead;
+import org.junit.Test;
+import org.yaml.snakeyaml.Yaml;
+
+@Slf4j
+public class DataAssertIT {
+    private static final Gson gson = new Gson();
+
+    @Test
+    public void testAssertFunction() throws InterruptedException, IOException, TypeUndefinedException {
+        TimeUnit.SECONDS.sleep(10L); // wait for agent registry
+
+        URLConnection connection = new URL(System.getProperty("ping.url")).openConnection();
+        connection.connect();
+        log.info("Http Response: {}", new String(ByteStreams.toByteArray(connection.getInputStream())));
+
+        TimeUnit.SECONDS.sleep(6L);
+
+        for (int times = 0; times < 30; times++) { // retry 30 times, that will spend 60s in the worst case.
+            final DataCollector collector = new DataCollector();
+            URL url = DataAssertIT.class.getResource("/logs/trace.log");
+            List<String> lines = Files.readAllLines(new File(url.getFile()).toPath());
+            log.info("lines : {}", lines.size());
+
+            for (int i = 0; i < lines.size() - 1; i++) {
+                String[] pair = lines.get(i).split(" ", 2);
+
+                JsonElement element = new JsonParser().parse(pair[1].replaceAll("\\\\", "").trim());
+                switch (pair[0]) {
+                    case Type.HEART_BEAT:
+                        break;
+                    case Type.SERVICE_REGISTER: {
+                        element.getAsJsonObject().get("services").getAsJsonArray().forEach(e -> {
+                            collector.serviceRegistry(e.getAsJsonObject().get("serviceName").getAsString());
+                        });
+                        break;
+                    }
+                    case Type.INSTANCE_REGISTER: {
+                        JsonArray instances = element.getAsJsonObject().getAsJsonArray("instances");
+                        instances.forEach(el -> {
+                            collector.instanceRegistry(el.getAsJsonObject().get("serviceId").getAsInt());
+                        });
+                        break;
+                    }
+                    case Type.SEGMENTS: {
+                        collector.addSegmentItem(element);
+                        break;
+                    }
+                    default: {
+                        throw new TypeUndefinedException("Type " + pair[0] + " undefined.");
+                    }
+                }
+            }
+
+            try {
+                if (!collector.hasSegments()) {
+                    throw new NullPointerException();
+                }
+
+                DataAssert.assertEquals(
+                    Data.Loader.loadData(DataCollector.class.getResourceAsStream("/expectedData.yaml")),
+                    Data.Loader.loadData(gson.toJson(collector.collect()))
+                );
+                return;
+            } catch (Exception e) {
+                TimeUnit.SECONDS.sleep(2L);
+                log.error(e.getMessage(), e);
+            }
+        }
+    }
+
+    static interface Type {
+        String HEART_BEAT = "/v2/instance/heartbeat";
+        String SEGMENTS = "/v2/segments";
+        String INSTANCE_REGISTER = "/v2/instance/register";
+        String SERVICE_REGISTER = "/v2/service/register";
+    }
+
+}
\ No newline at end of file
diff --git a/test/e2e/validator/src/test/java/org/apache/skywalking/plugin/test/validator/validator/assertor/DataCollector.java b/test/e2e/validator/src/test/java/org/apache/skywalking/plugin/test/validator/validator/assertor/DataCollector.java
new file mode 100644
index 0000000..7eb2669
--- /dev/null
+++ b/test/e2e/validator/src/test/java/org/apache/skywalking/plugin/test/validator/validator/assertor/DataCollector.java
@@ -0,0 +1,167 @@
+/*
+ * 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.plugin.test.validator.validator.assertor;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.skywalking.plugin.test.validator.validator.assertor.entity.ExpectedDataEntity;
+import org.apache.skywalking.plugin.test.validator.validator.assertor.entity.RegistryItemsEntity;
+
+@Slf4j
+public class DataCollector {
+    // For SegmentItems
+    private Map<String, List<JsonObject>> serviceAndSegments = Maps.newHashMap();
+
+    // For RegistryItems
+    private final Map<String, Integer> instanceMap = Maps.newHashMap();
+    private final Map<Integer, String> serviceMap = Maps.newHashMap();
+    private Map<String, List<String>> serviceAndOperations = Maps.newHashMap();
+    private int serviceIdGenerator = 0;
+
+    public DataCollector serviceRegistry(String serviceName) {
+        if (!serviceMap.containsValue(serviceName)) {
+            serviceMap.put(++serviceIdGenerator, serviceName);
+        }
+        return this;
+    }
+
+    public DataCollector instanceRegistry(int serviceId) {
+        String serviceName = serviceMap.get(serviceId);
+        instanceMap.put(serviceName, instanceMap.getOrDefault(serviceName, 0) + 1);
+        return this;
+    }
+
+    public DataCollector addSegmentItem(JsonElement element) {
+        final JsonElement spans = element.getAsJsonObject().get("spans");
+        if (spans.getAsJsonArray().size() == 0) {
+            return this;
+        }
+
+        try {
+            JsonObject segment = new JsonObject();
+            segment.addProperty("segmentId", "1.159.00000000000000000");
+            segment.add("spans", spans);
+
+            final int serviceId = element.getAsJsonObject().get("serviceId").getAsInt();
+            final String serviceName = serviceMap.get(serviceId);
+
+            spans.getAsJsonArray().forEach(span -> {
+                JsonObject jsonObject = span.getAsJsonObject();
+
+                // extract operation name
+                List<String> operations = serviceAndOperations.getOrDefault(serviceName, Lists.newArrayList());
+                operations.add(jsonObject.get("operationName").getAsString());
+                serviceAndOperations.put(serviceName, operations);
+
+                // remove unless properties
+                JsonElement refs = jsonObject.get("refs");
+                if (refs != null) {
+                    if (refs.isJsonObject()) {
+                        jsonObject.remove("refs");
+                    } else {
+                        refs.getAsJsonArray().forEach(el -> {
+                            el.getAsJsonObject().addProperty("parentTraceSegmentId", "parentTraceSegmentId");
+                        });
+                    }
+                }
+                JsonElement logs = jsonObject.get("logs");
+                if (logs != null) {
+                    if (logs.isJsonObject()) {
+                        jsonObject.remove("logs");
+                    }
+                }
+                JsonElement tags = jsonObject.get("tags");
+                if (tags != null) {
+                    if (tags.isJsonObject()) {
+                        jsonObject.remove("tags");
+                    }
+                }
+            });
+
+            List<JsonObject> segments = serviceAndSegments.getOrDefault(serviceName, Lists.newArrayList());
+            segments.add(segment);
+
+            serviceAndSegments.put(serviceName, segments);
+        } catch (Exception e) {
+            log.error(element.toString(), e);
+        }
+        return this;
+    }
+
+    public boolean hasSegments() {
+        return !serviceAndOperations.isEmpty();
+    }
+
+    public ExpectedDataEntity collect() {
+        RegistryItemsEntity registryItems = new RegistryItemsEntity();
+        registryItems.setInstances(getInstances());
+        registryItems.setApplications(getApplications());
+        registryItems.setOperationNames(getOperationNames());
+
+        ExpectedDataEntity entity = new ExpectedDataEntity();
+        entity.setRegistryItems(registryItems);
+        entity.setSegmentItems(getSegmentItems());
+        return entity;
+    }
+
+    private List<JsonObject> getSegmentItems() {
+        return serviceAndSegments.entrySet().stream().map(e -> {
+            JsonObject item = new JsonObject();
+            item.addProperty("serviceName", e.getKey());
+            item.addProperty("segmentSize", e.getValue().size());
+
+            List<JsonObject> values = e.getValue();
+            JsonArray elements = new JsonArray();
+            values.forEach(elements::add);
+            item.add("segments", elements);
+            return item;
+        }).collect(Collectors.toList());
+    }
+
+    private List<Map<String, List<String>>> getOperationNames() {
+        return serviceAndOperations.entrySet().stream().map(e -> {
+            Map<String, List<String>> instance = Maps.newHashMap();
+            instance.put(e.getKey(), e.getValue());
+            return instance;
+        }).collect(Collectors.toList());
+    }
+
+    private List<Map<String, Integer>> getInstances() {
+        return instanceMap.entrySet().stream().map(entry -> {
+            Map<String, Integer> instance = Maps.newHashMap();
+            instance.put(entry.getKey(), entry.getValue());
+            return instance;
+        }).collect(Collectors.toList());
+    }
+
+    private List<Map<String, Integer>> getApplications() {
+        return serviceMap.entrySet().stream().map(entry -> {
+            Map<String, Integer> instance = Maps.newHashMap();
+            instance.put(entry.getValue(), entry.getKey() + 1);
+            return instance;
+        }).collect(Collectors.toList());
+    }
+}
diff --git a/test/e2e/validator/src/test/java/org/apache/skywalking/plugin/test/validator/validator/assertor/entity/ExpectedDataEntity.java b/test/e2e/validator/src/test/java/org/apache/skywalking/plugin/test/validator/validator/assertor/entity/ExpectedDataEntity.java
new file mode 100644
index 0000000..c01a559
--- /dev/null
+++ b/test/e2e/validator/src/test/java/org/apache/skywalking/plugin/test/validator/validator/assertor/entity/ExpectedDataEntity.java
@@ -0,0 +1,29 @@
+/*
+ * 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.plugin.test.validator.validator.assertor.entity;
+
+import com.google.gson.JsonObject;
+import java.util.List;
+import lombok.Data;
+
+@Data
+public class ExpectedDataEntity {
+    private RegistryItemsEntity registryItems;
+    private List<JsonObject> segmentItems;
+}
diff --git a/test/e2e/validator/src/test/java/org/apache/skywalking/plugin/test/validator/validator/assertor/entity/RegistryItemsEntity.java b/test/e2e/validator/src/test/java/org/apache/skywalking/plugin/test/validator/validator/assertor/entity/RegistryItemsEntity.java
new file mode 100644
index 0000000..aeb3948
--- /dev/null
+++ b/test/e2e/validator/src/test/java/org/apache/skywalking/plugin/test/validator/validator/assertor/entity/RegistryItemsEntity.java
@@ -0,0 +1,30 @@
+/*
+ * 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.plugin.test.validator.validator.assertor.entity;
+
+import java.util.List;
+import java.util.Map;
+import lombok.Data;
+
+@Data
+public class RegistryItemsEntity {
+    private List<Map<String, Integer>> applications;
+    private List<Map<String, Integer>> instances;
+    private List<Map<String, List<String>>> operationNames;
+}
diff --git a/test/e2e/validator/src/test/resources/expectedData.yaml b/test/e2e/validator/src/test/resources/expectedData.yaml
new file mode 100644
index 0000000..96e6de0
--- /dev/null
+++ b/test/e2e/validator/src/test/resources/expectedData.yaml
@@ -0,0 +1,63 @@
+registryItems:
+  applications:
+    - {'User_Service_Name': 2}
+  instances:
+    - {'User_Service_Name': 1}
+  operationNames:
+    - User_Service_Name: [/tier2/lb, /tier2/lb, /ingress, /ingress]
+segmentItems:
+  - serviceName: User_Service_Name
+    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: 'User_Service_Name-nginx:upstream_ip:port'
+            spanLayer: HTTP
+          - operationName: /tier2/lb
+            startTime: gt 0
+            tags:
+              - {key: http.method, value: GET}
+              - {key: http.params, value: 'http://127.0.0.1/tier2/lb'}
+            endTime: gt 0
+            spanType: Entry
+            spanId: 0
+            isError: false
+            parentSpanId: -1
+            componentId: 6000
+            refs:
+              - {parentEndpointId: 0, entryEndpointId: 0, parentServiceInstanceId: 1, parentEndpoint: /ingress, parentTraceSegmentId: parentTraceSegmentId,
+                 networkAddress: '#User_Service_Name-nginx:upstream_ip:port', parentSpanId: 1,
+                 entryServiceInstanceId: 1, networkAddressId: 0, entryEndpoint: /ingress}
+            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: 'User_Service_Name-nginx:upstream_ip:port'
+            spanLayer: HTTP
+          - operationName: /ingress
+            startTime: gt 0
+            tags:
+              - {key: http.method, value: GET}
+              - {key: http.params, value: 'not null'}
+            endTime: gt 0
+            spanType: Entry
+            spanId: 0
+            parentSpanId: -1
+            isError: false
+            spanLayer: HTTP
+            componentId: 6000
\ No newline at end of file