From 9ea834dc6928f31bc1b5a48dc1615318c1ca061f Mon Sep 17 00:00:00 2001
From: j553liu <1007388420@qq.com>
Date: Sat, 16 Mar 2024 15:42:52 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BA=91=E6=B5=8B=E5=B7=A5=E5=85=B7=E5=88=86?=
=?UTF-8?q?=E6=9E=90=E6=A8=A1=E5=9D=97?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
component/CloudTest/pom.xml | 260 ++++++
.../cloudtest/CompatibleTestApplication.java | 33 +
.../common/config/TaskPoolConfig.java | 59 ++
.../common/exception/BaseException.java | 24 +
.../exception/ClamAvSizeLimitException.java | 24 +
.../common/exception/SshErrorException.java | 24 +
.../typehandler/AbstractListTypeHandler.java | 82 ++
.../common/typehandler/CryptoTypeHandler.java | 69 ++
.../typehandler/JacksonTypeHandler.java | 100 +++
.../controller/LabEnvController.java | 72 ++
.../cloudtest/dao/CloudDevUseRecordDao.java | 40 +
.../cloudtest/dao/CloudLabTestTaskDao.java | 116 +++
.../cloudtest/dao/PerformanceServiceDao.java | 52 ++
.../cloudtest/entity/CloudLabTestTask.java | 282 +++++++
.../openlab/cloudtest/entity/LabTestReq.java | 47 ++
.../openlab/cloudtest/entity/MqsMessage.java | 184 ++++
.../cloudtest/entity/PerformanceService.java | 24 +
.../cloudtest/entity/ScriptResultConfig.java | 21 +
.../cloudtest/entity/SystemParams.java | 82 ++
.../openlab/cloudtest/entity/TaskDelay.java | 56 ++
.../cloudtest/entity/TestCaseResult.java | 67 ++
.../cloudtest/entity/TestCaseResultCount.java | 41 +
.../CompatibilityFilesParser.java | 31 +
.../CompatibilityTestResult.java | 40 +
.../ParseFunctionTestLog.java | 231 +++++
.../ParseInfoLog.java | 219 +++++
.../ParseSafetyFiles.java | 141 ++++
.../impl/AbsParseCompatibilityFiles.java | 103 +++
.../impl/AbsParsePerformanceFiles.java | 92 ++
.../impl/ParseClamLog.java | 152 ++++
.../impl/ParseCpuComFiles.java | 155 ++++
.../impl/ParseCpuPerFiles.java | 179 ++++
.../impl/ParseCveCheckFiles.java | 113 +++
.../impl/ParseDiskComFiles.java | 213 +++++
.../impl/ParseDiskPerFiles.java | 213 +++++
.../impl/ParseMemComFiles.java | 168 ++++
.../impl/ParseMemPerFiles.java | 171 ++++
.../impl/ParseNetComFiles.java | 251 ++++++
.../impl/ParseNetPerFiles.java | 262 ++++++
.../impl/ParseSoftwareLog.java | 181 ++++
.../cloudtest/service/DevkitService.java | 147 ++++
.../cloudtest/service/LabEnvService.java | 642 ++++++++++++++
.../cloudtest/service/TarFileService.java | 387 +++++++++
.../service/TaskDelayMapService.java | 174 ++++
.../ic/openlab/cloudtest/util/AESUtil.java | 245 ++++++
.../openlab/cloudtest/util/ApiCenterUtil.java | 117 +++
.../ic/openlab/cloudtest/util/Constants.java | 789 ++++++++++++++++++
.../cloudtest/util/DgCodeServerClient.java | 36 +
.../ic/openlab/cloudtest/util/FileUtil.java | 54 ++
.../ic/openlab/cloudtest/util/MQSUtil.java | 43 +
.../ic/openlab/cloudtest/util/NormalResp.java | 63 ++
.../ic/openlab/cloudtest/util/PBKDF2Util.java | 67 ++
.../cloudtest/util/PerformanceApiClient.java | 53 ++
.../ic/openlab/cloudtest/util/RandomUtil.java | 31 +
.../cloudtest/util/TeeCodeServerClient.java | 36 +
.../ic/openlab/cloudtest/util/ToolUtil.java | 88 ++
.../cloudtest/util/fastdfs/FastDfsClient.java | 47 ++
.../cloudtest/util/sshclient/SFTPUtil.java | 103 +++
.../cloudtest/util/sshclient/SSHUtil.java | 123 +++
.../src/main/resources/application.yml | 30 +
.../src/main/resources/fastjson.properties | 1 +
.../src/main/resources/key/EXTRUBjR/NmsaKOHM | 1 +
.../src/main/resources/key/STZQZzfs/PIeavG3r | 1 +
.../src/main/resources/key/SW7HH3Up/59X8ARQZ | 1 +
.../src/main/resources/logback-spring.xml | 53 ++
.../mapper/CloudDevUseRecordMapper.xml | 26 +
.../mapper/CloudLabTestTaskMapper.xml | 266 ++++++
.../mapper/PerformanceServiceMapper.xml | 37 +
68 files changed, 8335 insertions(+)
create mode 100644 component/CloudTest/pom.xml
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/CompatibleTestApplication.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/common/config/TaskPoolConfig.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/common/exception/BaseException.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/common/exception/ClamAvSizeLimitException.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/common/exception/SshErrorException.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/common/typehandler/AbstractListTypeHandler.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/common/typehandler/CryptoTypeHandler.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/common/typehandler/JacksonTypeHandler.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/controller/LabEnvController.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/dao/CloudDevUseRecordDao.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/dao/CloudLabTestTaskDao.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/dao/PerformanceServiceDao.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/CloudLabTestTask.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/LabTestReq.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/MqsMessage.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/PerformanceService.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/ScriptResultConfig.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/SystemParams.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/TaskDelay.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/TestCaseResult.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/TestCaseResultCount.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/CompatibilityFilesParser.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/CompatibilityTestResult.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/ParseFunctionTestLog.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/ParseInfoLog.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/ParseSafetyFiles.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/AbsParseCompatibilityFiles.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/AbsParsePerformanceFiles.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseClamLog.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseCpuComFiles.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseCpuPerFiles.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseCveCheckFiles.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseDiskComFiles.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseDiskPerFiles.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseMemComFiles.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseMemPerFiles.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseNetComFiles.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseNetPerFiles.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseSoftwareLog.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/service/DevkitService.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/service/LabEnvService.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/service/TarFileService.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/service/TaskDelayMapService.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/util/AESUtil.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/util/ApiCenterUtil.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/util/Constants.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/util/DgCodeServerClient.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/util/FileUtil.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/util/MQSUtil.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/util/NormalResp.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/util/PBKDF2Util.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/util/PerformanceApiClient.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/util/RandomUtil.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/util/TeeCodeServerClient.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/util/ToolUtil.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/util/fastdfs/FastDfsClient.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/util/sshclient/SFTPUtil.java
create mode 100644 component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/util/sshclient/SSHUtil.java
create mode 100644 component/CloudTest/src/main/resources/application.yml
create mode 100644 component/CloudTest/src/main/resources/fastjson.properties
create mode 100644 component/CloudTest/src/main/resources/key/EXTRUBjR/NmsaKOHM
create mode 100644 component/CloudTest/src/main/resources/key/STZQZzfs/PIeavG3r
create mode 100644 component/CloudTest/src/main/resources/key/SW7HH3Up/59X8ARQZ
create mode 100644 component/CloudTest/src/main/resources/logback-spring.xml
create mode 100644 component/CloudTest/src/main/resources/mapper/CloudDevUseRecordMapper.xml
create mode 100644 component/CloudTest/src/main/resources/mapper/CloudLabTestTaskMapper.xml
create mode 100644 component/CloudTest/src/main/resources/mapper/PerformanceServiceMapper.xml
diff --git a/component/CloudTest/pom.xml b/component/CloudTest/pom.xml
new file mode 100644
index 0000000..f9929bf
--- /dev/null
+++ b/component/CloudTest/pom.xml
@@ -0,0 +1,260 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 2.7.15
+
+
+ com.huawei
+ cloudTest
+ 1.0.0
+ cloudTest
+ Demo project for Spring Boot
+
+ 1.8
+ 2021.0.3
+ 4.1.100.Final
+
+
+
+ com.mikesamuel
+ json-sanitizer
+ 1.2.3
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.apache.commons
+ commons-lang3
+ 3.12.0
+
+
+ org.apache.commons
+ commons-compress
+ 1.23.0
+
+
+ commons-io
+ commons-io
+ 2.11.0
+
+
+ commons-fileupload
+ commons-fileupload
+ 1.5
+
+
+ org.apache.httpcomponents
+ httpclient
+ 4.5.13
+
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+ 2.2.2
+
+
+
+ org.mariadb.jdbc
+ mariadb-java-client
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ junit
+ junit
+ test
+
+
+ com.alibaba
+ fastjson
+ 1.2.83
+
+
+ org.projectlombok
+ lombok
+
+
+ org.springframework.boot
+ spring-boot-starter-data-redis
+
+
+ io.netty
+ netty-buffer
+
+
+ io.netty
+ netty-codec
+
+
+ io.netty
+ netty-common
+
+
+ io.netty
+ netty-handler
+
+
+ io.netty
+ netty-resolver
+
+
+ io.netty
+ netty-transport
+
+
+ io.netty
+ netty-transport-native-unix-common
+
+
+
+
+ io.netty
+ netty-buffer
+ ${netty.version}
+
+
+ io.netty
+ netty-codec
+ ${netty.version}
+
+
+ io.netty
+ netty-common
+ ${netty.version}
+
+
+ io.netty
+ netty-handler
+ ${netty.version}
+
+
+ io.netty
+ netty-resolver
+ ${netty.version}
+
+
+ io.netty
+ netty-transport
+ ${netty.version}
+
+
+ io.netty
+ netty-transport-native-unix-common
+ ${netty.version}
+
+
+
+
+ org.apache.sshd
+ sshd-core
+ 2.10.0
+
+
+ com.jcraft
+ jsch
+ 0.1.54
+
+
+ org.springframework.cloud
+ spring-cloud-starter-openfeign
+ 4.0.3
+
+
+ org.bouncycastle
+ bcpkix-jdk15on
+
+
+ org.springframework.security
+ spring-security-crypto
+
+
+
+
+ com.github.tobato
+ fastdfs-client
+ 1.27.2
+
+
+ commons-beanutils
+ commons-beanutils
+
+
+
+
+ commons-beanutils
+ commons-beanutils
+ 1.9.4
+
+
+
+
+
+ org.yaml
+ snakeyaml
+ 1.32
+
+
+
+ xyz.capybara
+ clamav-client
+ 2.1.2
+
+
+
+
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-dependencies
+ ${spring-cloud.version}
+ pom
+ import
+
+
+
+
+
+ cloudTest
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+ 3.1.2
+
+
+ copy-dependencies
+ compile
+
+ copy-dependencies
+
+
+ ${project.build.directory}/${project.build.finalName}/WEB-INF/lib
+
+ system
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ 2.7.15
+
+
+
+
+
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/CompatibleTestApplication.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/CompatibleTestApplication.java
new file mode 100644
index 0000000..331e92c
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/CompatibleTestApplication.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+/**
+ * CompatibleTestApplication
+ *
+ * @author kongcaizhi
+ * @since 2021-12-15
+ */
+@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
+@EnableAsync
+@EnableScheduling
+@EnableFeignClients
+public class CompatibleTestApplication {
+ /**
+ * main
+ *
+ * @param args params
+ */
+ public static void main(String[] args) {
+ SpringApplication.run(CompatibleTestApplication.class, args);
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/common/config/TaskPoolConfig.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/common/config/TaskPoolConfig.java
new file mode 100644
index 0000000..45eb966
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/common/config/TaskPoolConfig.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.common.config;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.annotation.AsyncConfigurer;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.util.concurrent.Executor;
+
+/**
+ * TaskPoolConfig
+ *
+ * @author kongcaizhi
+ * @since 2022-10-19
+ */
+@Configuration
+@EnableAsync
+@Slf4j
+public class TaskPoolConfig implements AsyncConfigurer {
+ @Override
+ @Bean(name = "asyncExecutor", destroyMethod = "shutdown")
+ public Executor getAsyncExecutor() {
+ ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+
+ // 核心线程数
+ executor.setCorePoolSize(100);
+
+ // 最大线程数,默认 40000
+ executor.setMaxPoolSize(300);
+
+ // 线程池队列最大线程数,默认80000
+ executor.setQueueCapacity(1000);
+
+ // 线程池线程最大空闲时间(秒)
+ executor.setKeepAliveSeconds(300);
+ executor.setThreadNamePrefix("async-task-");
+ executor.initialize();
+ return executor;
+ }
+
+ @Override
+ public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
+ return (throwable, method, objects) ->
+ log.error(
+ "An exception occurred during asynchronous task execution, message {}, method {}, params {}",
+ throwable.getLocalizedMessage(),
+ method,
+ objects
+ );
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/common/exception/BaseException.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/common/exception/BaseException.java
new file mode 100644
index 0000000..755b5ff
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/common/exception/BaseException.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.common.exception;
+
+/**
+ * BaseException
+ *
+ * @author kongcaizhi
+ * @since 2021-10-19
+ */
+public class BaseException extends RuntimeException {
+ private static final long serialVersionUID = 120492404095565805L;
+
+ /**
+ * BaseException
+ *
+ * @param message message
+ */
+ public BaseException(String message) {
+ super(message);
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/common/exception/ClamAvSizeLimitException.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/common/exception/ClamAvSizeLimitException.java
new file mode 100644
index 0000000..c0f310f
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/common/exception/ClamAvSizeLimitException.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.common.exception;
+
+/**
+ * ClamAVSizeLimitException
+ *
+ * @author kongcaizhi
+ * @since 2021-10-19
+ */
+public class ClamAvSizeLimitException extends RuntimeException {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Construction function
+ *
+ * @param msg message
+ */
+ public ClamAvSizeLimitException(String msg) {
+ super(msg);
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/common/exception/SshErrorException.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/common/exception/SshErrorException.java
new file mode 100644
index 0000000..b011a75
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/common/exception/SshErrorException.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.common.exception;
+
+/**
+ * ClamAVSizeLimitException
+ *
+ * @author kongcaizhi
+ * @since 2021-10-19
+ */
+public class SshErrorException extends Exception {
+ private static final long serialVersionUID = 116717817166294456L;
+
+ /**
+ * SshErrorException
+ *
+ * @param message message
+ */
+ public SshErrorException(String message) {
+ super(message);
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/common/typehandler/AbstractListTypeHandler.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/common/typehandler/AbstractListTypeHandler.java
new file mode 100644
index 0000000..4ad6d09
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/common/typehandler/AbstractListTypeHandler.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.common.typehandler;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.type.CollectionType;
+import com.google.json.JsonSanitizer;
+
+import lombok.SneakyThrows;
+
+import org.apache.ibatis.type.BaseTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.MappedJdbcTypes;
+import org.apache.ibatis.type.MappedTypes;
+import org.springframework.util.StringUtils;
+
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.List;
+
+/**
+ * AbstractListTypeHandler
+ *
+ * @author kongcaizhi
+ * @since 2021-11-19
+ */
+@MappedTypes(List.class)
+@MappedJdbcTypes(JdbcType.VARCHAR)
+public abstract class AbstractListTypeHandler extends BaseTypeHandler {
+ /**
+ * objectMapper
+ */
+ protected ObjectMapper objectMapper = new ObjectMapper();
+
+ /**
+ * javaType
+ */
+ protected CollectionType javaType;
+
+ @SneakyThrows
+ @Override
+ public void setNonNullParameter(PreparedStatement ps, int i, List list, JdbcType jdbcType) throws SQLException {
+ ps.setString(i, objectMapper.writeValueAsString(list));
+ }
+
+ @SneakyThrows
+ @Override
+ public List> getNullableResult(ResultSet rs, String columnName) throws SQLException {
+ String json = rs.getString(columnName);
+ List> list = null;
+ if (!StringUtils.hasLength(json)) {
+ list = objectMapper.readValue(JsonSanitizer.sanitize(json), javaType);
+ }
+ return list;
+ }
+
+ @SneakyThrows
+ @Override
+ public List> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
+ String json = rs.getString(rs.getString(columnIndex));
+ List> list = null;
+ if (!StringUtils.hasLength(json)) {
+ list = objectMapper.readValue(JsonSanitizer.sanitize(json), javaType);
+ }
+ return list;
+ }
+
+ @SneakyThrows
+ @Override
+ public List> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
+ String json = cs.getString(columnIndex);
+ List> list = null;
+ if (!StringUtils.hasLength(json)) {
+ list = objectMapper.readValue(JsonSanitizer.sanitize(json), javaType);
+ }
+ return list;
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/common/typehandler/CryptoTypeHandler.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/common/typehandler/CryptoTypeHandler.java
new file mode 100644
index 0000000..fb2b2b6
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/common/typehandler/CryptoTypeHandler.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.common.typehandler;
+
+import com.huawei.ic.openlab.cloudtest.common.exception.BaseException;
+import com.huawei.ic.openlab.cloudtest.util.AESUtil;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.ibatis.type.BaseTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.MappedJdbcTypes;
+
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * CryptoTypeHandler
+ *
+ * @author kongcaizhi
+ * @since 2021-11-19
+ */
+@Slf4j
+@MappedJdbcTypes(JdbcType.VARCHAR)
+public class CryptoTypeHandler extends BaseTypeHandler {
+ private static final Integer PASSWORD_LENGTH_WITHOUT_ENCRYPT = 50;
+
+ @Override
+ public void setNonNullParameter(PreparedStatement preparedStatement, int i, String s, JdbcType jdbcType)
+ throws SQLException {
+ preparedStatement.setString(i, doEncrypt(s));
+ }
+
+ @Override
+ public String getNullableResult(ResultSet resultSet, String s) throws SQLException {
+ return doDecruypt(resultSet.getString(s));
+ }
+
+ @Override
+ public String getNullableResult(ResultSet resultSet, int i) throws SQLException {
+ return doDecruypt(resultSet.getString(i));
+ }
+
+ @Override
+ public String getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
+ return doDecruypt(callableStatement.getString(i));
+ }
+
+ private String doEncrypt(String password) {
+ return AESUtil.gcmEncrypt(password, AESUtil.CRYPTO.getAesDefaultKey(), AESUtil.CRYPTO.getAesDefaultAad());
+ }
+
+ private String doDecruypt(String password) {
+ if (!isEncrypt(password)) {
+ throw new BaseException("password decruypt failed");
+ }
+ return AESUtil.gcmDecrypt(password, AESUtil.CRYPTO.getAesDefaultKey());
+ }
+
+ private boolean isEncrypt(String password) {
+ return (StringUtils.isNotEmpty(password) && password.length() > PASSWORD_LENGTH_WITHOUT_ENCRYPT)
+ ? true : false;
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/common/typehandler/JacksonTypeHandler.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/common/typehandler/JacksonTypeHandler.java
new file mode 100644
index 0000000..5fe1e0e
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/common/typehandler/JacksonTypeHandler.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.common.typehandler;
+
+import com.huawei.ic.openlab.cloudtest.common.exception.BaseException;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.apache.ibatis.exceptions.PersistenceException;
+import org.apache.ibatis.type.BaseTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.MappedJdbcTypes;
+
+import java.io.IOException;
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * JacksonTypeHandler
+ *
+ * @author kongcaizhi
+ * @since 2021-11-19
+ */
+@Slf4j
+@MappedJdbcTypes(JdbcType.VARCHAR)
+public class JacksonTypeHandler extends BaseTypeHandler {
+ private static final ObjectMapper OBJECT_MAPPER;
+
+ static {
+ OBJECT_MAPPER = new ObjectMapper();
+ OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ }
+
+ private final Class type;
+
+ /**
+ * JacksonTypeHandler
+ *
+ * @param type Class
+ */
+ public JacksonTypeHandler(Class type) {
+ if (log.isTraceEnabled()) {
+ log.trace("JacksonTypeHandler ({})", type);
+ }
+ if (type == null) {
+ throw new PersistenceException("Type argument cannot be null");
+ }
+ this.type = type;
+ }
+
+ private T parse(String json) {
+ T object = null;
+ try {
+ if (!(json == null || json.length() == 0)) {
+ object = OBJECT_MAPPER.readValue(json, type);
+ }
+ return object;
+ } catch (IOException e) {
+ log.error(e.getMessage(), e);
+ throw new BaseException(e.getMessage());
+ }
+ }
+
+ private String toJsonString(T obj) {
+ try {
+ return OBJECT_MAPPER.writeValueAsString(obj);
+ } catch (JsonProcessingException e) {
+ log.error(e.getMessage(), e);
+ throw new BaseException(e.getMessage());
+ }
+ }
+
+ @Override
+ public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
+ ps.setString(i, toJsonString(parameter));
+ }
+
+ @Override
+ public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
+ return parse(rs.getString(columnName));
+ }
+
+ @Override
+ public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
+ return parse(rs.getString(columnIndex));
+ }
+
+ @Override
+ public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
+ return parse(cs.getString(columnIndex));
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/controller/LabEnvController.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/controller/LabEnvController.java
new file mode 100644
index 0000000..5991761
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/controller/LabEnvController.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.controller;
+
+import com.huawei.ic.openlab.cloudtest.common.exception.BaseException;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.CompatibilityTestResult;
+import com.huawei.ic.openlab.cloudtest.service.LabEnvService;
+import com.huawei.ic.openlab.cloudtest.service.TarFileService;
+import com.huawei.ic.openlab.cloudtest.util.Constants;
+import com.huawei.ic.openlab.cloudtest.util.NormalResp;
+
+import lombok.extern.slf4j.Slf4j;
+
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RequestPart;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * 实验室环境测试控制器类
+ *
+ * @author kongcaizhi
+ * @since 2021-12-15
+ */
+@Slf4j
+@RestController
+@RequestMapping(value = "/api/v1", produces = MediaType.APPLICATION_JSON_VALUE)
+public class LabEnvController {
+ private final TarFileService tarFileService;
+ private final LabEnvService labEnvService;
+
+
+ /**
+ * LabEnvController
+ * @param tarFileService labEnvService
+ * @param service LabEnvService
+ */
+ @Autowired
+ public LabEnvController(TarFileService tarFileService, LabEnvService labEnvService) {
+ this.tarFileService = tarFileService;
+ this.labEnvService = labEnvService;
+ }
+
+ /**
+ * 测试远程实验室连接是否正常
+ *
+ * @param ip ip
+ * @param port port
+ * @param userName username
+ * @param passWord password
+ * @return response string
+ */
+ @GetMapping(value = "/report")
+ public String setTestFile(@RequestParam(value = "file") String file, @RequestParam(value = "savePath") String savePath) throws IOException {
+ if (!Objects.requireNonNull(file).matches("^.*\\.tar.gz$")) {
+ throw new BaseException("文件后缀错误");
+ }
+ labEnvService.resultJson(file, savePath);
+ return "success";
+ }
+}
\ No newline at end of file
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/dao/CloudDevUseRecordDao.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/dao/CloudDevUseRecordDao.java
new file mode 100644
index 0000000..e44bd19
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/dao/CloudDevUseRecordDao.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.dao;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Repository;
+
+/**
+ * 云开发平台访问记录
+ *
+ * @since 2023-01-16
+ * @author kongcaizhi
+ */
+
+public interface CloudDevUseRecordDao {
+ /**
+ * Get record by taskId
+ *
+ * @param taskDeviceId task id
+ * @param kpToken kp token
+ * @return response string
+ */
+ String getRecordById(@Param("taskDeviceId") String taskDeviceId,
+ @Param("kpToken") String kpToken);
+
+ /**
+ * insert record
+ *
+ * @param requestTime requestTime
+ * @param taskDeviceId taskDeviceId
+ * @param kpToken KP TOKEN
+ * @return RESPONSE STRING
+ */
+ int insertRecord(@Param("requestTime") String requestTime,
+ @Param("taskDeviceId") String taskDeviceId,
+ @Param("kpToken") String kpToken);
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/dao/CloudLabTestTaskDao.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/dao/CloudLabTestTaskDao.java
new file mode 100644
index 0000000..a398515
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/dao/CloudLabTestTaskDao.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.dao;
+
+import com.huawei.ic.openlab.cloudtest.entity.CloudLabTestTask;
+import com.huawei.ic.openlab.cloudtest.entity.LabTestReq;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * CloudLabTestTaskDao
+ *
+ * @author kongcaizhi
+ * @since 2021-12-15
+ */
+
+public interface CloudLabTestTaskDao {
+ /**
+ * get Test Task
+ *
+ * @param projectId projectId
+ * @return CloudLabTestTask
+ */
+ CloudLabTestTask getTestTask(@Param("projectId") String projectId);
+
+ /**
+ * get Ongoing Task
+ *
+ * @param data LabTestReq
+ * @return Task
+ */
+ List getOngoingTask(@Param("data") LabTestReq data);
+
+ /**
+ * set Test Task
+ *
+ * @param projectId projectId
+ * @param data data
+ */
+ void setTestTask(@Param("projectId") String projectId,
+ @Param("data") CloudLabTestTask data);
+
+ /**
+ * update Project Status
+ *
+ * @param projectId projectId
+ * @param status status
+ * @param startTime start Time
+ * @param finishTime finish Time
+ * @param statusDesc status Desc
+ * @return update num
+ */
+ int updateProjectStatus(@Param("projectId") String projectId,
+ @Param("status") Integer status,
+ @Param("startTime") String startTime,
+ @Param("finishTime") String finishTime,
+ @Param("statusDesc") String statusDesc);
+
+ /**
+ * update Upload File
+ *
+ * @param projectId projectId
+ * @param userId userId
+ * @param column column
+ * @param data data
+ * @param ip ip
+ * @return update num
+ */
+ int updateUploadFile(@Param("projectId") String projectId,
+ @Param("userId") String userId,
+ @Param("column") String column,
+ @Param("data") CloudLabTestTask.UploadFile data,
+ @Param("ip") String ip);
+
+ /**
+ * update Step Status
+ *
+ * @param data data
+ * @param testBeginTime test Begin Time
+ * @param projectId projectId
+ * @return update num
+ */
+ int updateStepStatus(@Param("data") CloudLabTestTask.StepStatus data,
+ @Param("testBeginTime") CloudLabTestTask.TestBeginTime testBeginTime,
+ @Param("projectId") String projectId);
+
+ /**
+ * update With Exception File
+ *
+ * @param data CloudLabTestTask
+ * @return update num
+ */
+ int updateWithExceptionFile(@Param("data") CloudLabTestTask data);
+
+ /**
+ * update Compatibility Result
+ *
+ * @param data CloudLabTestTask
+ * @return update num
+ */
+ int updateCompatibilityResult(@Param("data") CloudLabTestTask data);
+
+ /**
+ * update Performance Result
+ *
+ * @param data CloudLabTestTask
+ * @return update num
+ */
+ int updatePerformanceResult(@Param("data") CloudLabTestTask data);
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/dao/PerformanceServiceDao.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/dao/PerformanceServiceDao.java
new file mode 100644
index 0000000..a54979c
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/dao/PerformanceServiceDao.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.dao;
+
+import com.huawei.ic.openlab.cloudtest.entity.PerformanceService;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * PerformanceServiceDao
+ *
+ * @author kongcaizhi
+ * @since 2021-12-15
+ */
+
+public interface PerformanceServiceDao {
+ /**
+ * Get Performance service
+ *
+ * @return get record
+ */
+ List getPerformanceService();
+
+ /**
+ * Get Idle Service
+ *
+ * @return get record
+ */
+ PerformanceService getIdleService();
+
+ /**
+ * add task
+ *
+ * @param serviceIp service ip
+ * @return add record
+ */
+ int addTask(@Param("serviceIp") String serviceIp);
+
+ /**
+ * Subtract task
+ *
+ * @param serviceIp service IP
+ * @return record
+ */
+ int subtractTask(@Param("serviceIp") String serviceIp);
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/CloudLabTestTask.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/CloudLabTestTask.java
new file mode 100644
index 0000000..351a793
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/CloudLabTestTask.java
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.entity;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.List;
+
+/**
+ * 远程实验室测试实体类
+ *
+ * @author kongcaizhi
+ * @since 2021-11-11
+ */
+@Data
+public class CloudLabTestTask {
+ private String projectId;
+ private String userId;
+ private String serverIp;
+ private int serverPort;
+ private String serverUser;
+ private String serverPassword;
+
+ private int projectStatus = 0;
+ private String statusDesc;
+
+ private String requestTime;
+ private String startTime;
+ private String finishTime;
+
+ @JsonProperty(value = "compatibilityTest")
+ private boolean isCompatibilityTest;
+ @JsonProperty(value = "reliabilityTest")
+ private boolean isReliabilityTest;
+ @JsonProperty(value = "securityTest")
+ private boolean isSecurityTest;
+ @JsonProperty(value = "functionTest")
+ private boolean isFunctionTest;
+ @JsonProperty(value = "performanceTest")
+ private boolean isPerformanceTest;
+
+ private StepStatus stepStatus;
+ private String currentStatus;
+ private UploadFile functionFile;
+ private UploadFile performanceFile;
+ private UploadFile resultFile;
+ private TestCaseSummary testSummary;
+ private List testDetail;
+ private ScriptResultConfig scriptResultConfig;
+ private String performanceService;
+ private TestBeginTime testBeginTime;
+ private String taskLanguage;
+
+ /**
+ * StepStatus
+ *
+ * @author kongcaizhi
+ * @since 2021-11-11
+ */
+ @AllArgsConstructor
+ @NoArgsConstructor
+ @Data
+ public static class StepStatus {
+ private String step1Code;
+ private String step1Time;
+ private UploadFile step1File;
+ private String step2Code;
+ private String step2Time;
+ private UploadFile step2File;
+ private String step3Code;
+ private String step3Time;
+ private UploadFile step3File;
+ private String step4Code;
+ private String step4Time;
+ private UploadFile step4File;
+ private String step5Code;
+ private String step5Time;
+ private UploadFile step5File;
+ private String step6Code;
+ private String step6Time;
+ private UploadFile step6File;
+ private String step7Code;
+ private String step7Time;
+ private UploadFile step7File;
+ private String step8Code;
+ private String step8Time;
+ private UploadFile step8File;
+ private String step9Code;
+ private String step9Time;
+ private UploadFile step9File;
+ private String step10Code;
+ private String step10Time;
+ private UploadFile step10File;
+ private String functionCode;
+ private String functionTime;
+ private UploadFile functionFile;
+ private String performanceCode;
+ private String performanceTime;
+ private UploadFile performanceFile;
+
+ /**
+ * set Step1
+ *
+ * @param resultCode resultCode
+ * @param timeString timeString
+ */
+ public void setStep1(String resultCode, String timeString) {
+ this.setStep1Code(resultCode);
+ this.setStep1Time(timeString);
+ }
+
+ /**
+ * set Step2
+ *
+ * @param resultCode resultCode
+ * @param timeString timeString
+ */
+ public void setStep2(String resultCode, String timeString) {
+ this.setStep2Code(resultCode);
+ this.setStep2Time(timeString);
+ }
+
+ /**
+ * set Step3
+ *
+ * @param resultCode resultCode
+ * @param timeString timeString
+ */
+ public void setStep3(String resultCode, String timeString) {
+ if (StringUtils.isNoneEmpty(this.getStep3Code())) {
+ this.setStep3Code(this.getStep3Code() + ";" + resultCode);
+ } else {
+ this.setStep3Code(resultCode);
+ }
+ this.setStep3Time(timeString);
+ }
+
+ /**
+ * set Step4
+ *
+ * @param resultCode resultCode
+ * @param timeString timeString
+ */
+ public void setStep4(String resultCode, String timeString) {
+ this.setStep4Code(resultCode);
+ this.setStep4Time(timeString);
+ }
+
+ /**
+ * set Step5
+ *
+ * @param resultCode resultCode
+ * @param timeString timeString
+ */
+ public void setStep5(String resultCode, String timeString) {
+ this.setStep5Code(resultCode);
+ this.setStep5Time(timeString);
+ }
+
+ /**
+ * set Step6
+ *
+ * @param resultCode resultCode
+ * @param timeString timeString
+ */
+ public void setStep6(String resultCode, String timeString) {
+ this.setStep6Code(resultCode);
+ this.setStep6Time(timeString);
+ }
+
+ /**
+ * set Step7
+ *
+ * @param resultCode resultCode
+ * @param timeString timeString
+ */
+ public void setStep7(String resultCode, String timeString) {
+ this.setStep7Code(resultCode);
+ this.setStep7Time(timeString);
+ }
+
+ /**
+ * set Step8
+ *
+ * @param resultCode resultCode
+ * @param timeString timeString
+ */
+ public void setStep8(String resultCode, String timeString) {
+ this.setStep8Code(resultCode);
+ this.setStep8Time(timeString);
+ }
+
+ /**
+ * set Step9
+ *
+ * @param resultCode resultCode
+ * @param timeString timeString
+ */
+ public void setStep9(String resultCode, String timeString) {
+ this.setStep9Code(resultCode);
+ this.setStep9Time(timeString);
+ }
+
+ /**
+ * set Step10
+ *
+ * @param resultCode resultCode
+ * @param timeString timeString
+ */
+ public void setStep10(String resultCode, String timeString) {
+ this.setStep10Code(resultCode);
+ this.setStep10Time(timeString);
+ }
+ }
+
+ /**
+ * UploadFile
+ *
+ * @author kongcaizhi
+ * @since 2021-11-11
+ */
+ @AllArgsConstructor
+ @NoArgsConstructor
+ @Data
+ public static class UploadFile {
+ private String fileDesc;
+ private String fileStatus;
+ private String fileId;
+ private String fileName;
+ private String filePath;
+ }
+
+ /**
+ * TestBeginTime
+ *
+ * @author kongcaizhi
+ * @since 2021-11-11
+ */
+ @AllArgsConstructor
+ @NoArgsConstructor
+ @Data
+ public static class TestBeginTime {
+ private String compatibilityTime;
+ private String reliabilityTime;
+ private String securityTime;
+ private String functionTime;
+ private String performanceTime;
+ }
+
+ /**
+ * TestCaseSummary
+ *
+ * @author kongcaizhi
+ * @since 2021-11-11
+ */
+ @AllArgsConstructor
+ @NoArgsConstructor
+ @Data
+ public static class TestCaseSummary {
+ private TestCaseResultCount function;
+ private TestCaseResultCount performance;
+ private TestCaseResultCount security;
+ private TestCaseResultCount compatibility;
+ private TestCaseResultCount reliability;
+
+ public TestCaseSummary(TestCaseResultCount function, TestCaseResultCount security,
+ TestCaseResultCount compatibility, TestCaseResultCount reliability) {
+ this.function = function;
+ this.security = security;
+ this.compatibility = compatibility;
+ this.reliability = reliability;
+ }
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/LabTestReq.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/LabTestReq.java
new file mode 100644
index 0000000..a149413
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/LabTestReq.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.entity;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import lombok.Data;
+
+/**
+ * 网站请求蓝区兼容性测试实体类
+ *
+ * @author kongcaizhi
+ * @since 2021-10-30
+ */
+@Data
+public class LabTestReq {
+ private String projectId;
+ private String userId;
+
+ private String serverIp;
+ private int serverPort;
+ private String serverUser;
+ private String serverPassword;
+
+ @JsonProperty(value = "compatibilityTest")
+ private boolean isCompatibilityTest;
+ @JsonProperty(value = "reliabilityTest")
+ private boolean isReliabilityTest;
+ @JsonProperty(value = "securityTest")
+ private boolean isSecurityTest;
+ @JsonProperty(value = "functionTest")
+ private boolean isFunctionTest;
+ @JsonProperty(value = "performance")
+ private boolean isPerformanceTest;
+
+ private String deployDir;
+ private String applicationNames;
+ private String startAppCommands;
+ private String stopAppCommands;
+
+ private int webPort;
+
+ @JsonProperty(value = "language", defaultValue = "CN")
+ private String taskLanguage;
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/MqsMessage.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/MqsMessage.java
new file mode 100644
index 0000000..35020a7
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/MqsMessage.java
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.entity;
+
+import com.huawei.ic.openlab.cloudtest.util.Constants;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+/**
+ * MQSMessage
+ *
+ * @author kongcaizhi
+ * @since 2021-10-30
+ */
+@Data
+public class MqsMessage {
+ private String projectId;
+ private String userId;
+ private String serverIp;
+ private String status;
+ private String statusDesc;
+ private String statusTime;
+ private MessageDetail detail;
+ private MessageResult testResult;
+
+ /**
+ * MessageDetail
+ *
+ * @author kongcaizhi
+ * @since 2021-10-30
+ */
+ @AllArgsConstructor
+ @NoArgsConstructor
+ @Data
+ public static class MessageDetail {
+ private String step;
+ private String stepStatus;
+ private String exceptionType;
+ private String exceptionDesc;
+ private String exceptionFileName;
+ private String resultFileName;
+ private String fileStatus;
+
+ /**
+ * DEPENDENCY_INSTALL_SUCCESS
+ */
+ public void setDependencyInstallSuccess() {
+ this.setStep(Constants.DEPENDENCY_INSTALL_DESC);
+ this.setStepStatus(Constants.TEST_FINISHED_CN);
+ }
+
+ /**
+ * APP_START_SUCCESS
+ */
+ public void setAppStartSuccess() {
+ this.setStep(Constants.DEPENDENCY_INSTALL_DESC);
+ this.setStepStatus(Constants.TEST_FINISHED_CN);
+ }
+
+ /**
+ * APP_STOP_SUCCESS
+ *
+ * @param isCompatibilityTest isCompatibilityTest
+ * @param isReliabilityTest isReliabilityTest
+ * @param isSecurityTest isSecurityTest
+ */
+ public void setAppStopSuccess(boolean isCompatibilityTest, boolean isReliabilityTest, boolean isSecurityTest) {
+ this.setStep(Constants.APP_STOP_DESC);
+ this.setStepStatus(Constants.TEST_FINISHED_CN);
+ if (isCompatibilityTest) {
+ this.setStep(Constants.COMPATIBILITY_TEST_DESC);
+ this.setStepStatus(Constants.TEST_PROCESSING);
+ }
+ if (isReliabilityTest) {
+ this.setStep(Constants.RELIABILITY_TEST_DESC);
+ this.setStepStatus(Constants.TEST_PROCESSING);
+ }
+ if (isSecurityTest) {
+ this.setStep(Constants.SECURITY_TEST_DESC);
+ this.setStepStatus(Constants.TEST_PROCESSING);
+ }
+ }
+
+ /**
+ * COM_START_SUCCESS
+ *
+ * @param isReliabilityTest isReliabilityTest
+ * @param isSecurityTest isSecurityTest
+ */
+ public void setComStartSuccess(boolean isReliabilityTest, boolean isSecurityTest) {
+ this.setStep(Constants.COMPATIBILITY_TEST_DESC);
+ this.setStepStatus(Constants.TEST_PROCESSING);
+ if (isReliabilityTest) {
+ this.setStep(Constants.RELIABILITY_TEST_DESC);
+ this.setStepStatus(Constants.TEST_PROCESSING);
+ }
+ if (isSecurityTest) {
+ this.setStep(Constants.SECURITY_TEST_DESC);
+ this.setStepStatus(Constants.TEST_PROCESSING);
+ }
+ }
+
+ /**
+ * PORT_TEST_SUCCESS
+ */
+ public void setPortTestSuccess() {
+ this.setStep(Constants.DEPENDENCY_INSTALL_DESC);
+ this.setStepStatus(Constants.TEST_FINISHED_CN);
+ }
+
+ /**
+ * VIRUS_SCAN_SUCCESS
+ *
+ * @param isCompatibilityTest isCompatibilityTest
+ * @param isReliabilityTest isReliabilityTest
+ */
+ public void setVirusScanSuccess(boolean isCompatibilityTest, boolean isReliabilityTest) {
+ this.setStep(Constants.SECURITY_TEST_DESC);
+ this.setStepStatus(Constants.TEST_PROCESSING);
+ if (isCompatibilityTest) {
+ this.setStep(Constants.COMPATIBILITY_TEST_DESC);
+ this.setStepStatus(Constants.TEST_PROCESSING);
+ }
+ if (isReliabilityTest) {
+ this.setStep(Constants.RELIABILITY_TEST_DESC);
+ this.setStepStatus(Constants.TEST_PROCESSING);
+ }
+ }
+
+ /**
+ * VULNERABLE_SCAN_SUCCESS
+ *
+ * @param isCompatibilityTest isCompatibilityTest
+ * @param isReliabilityTest isReliabilityTest
+ */
+ public void setVulnerableScanSuccess(boolean isCompatibilityTest, boolean isReliabilityTest) {
+ this.setStep(Constants.SECURITY_TEST_DESC);
+ this.setStepStatus(Constants.TEST_FINISHED_CN);
+ if (isCompatibilityTest) {
+ this.setStep(Constants.COMPATIBILITY_TEST_DESC);
+ this.setStepStatus(Constants.TEST_PROCESSING);
+ }
+ if (isReliabilityTest) {
+ this.setStep(Constants.RELIABILITY_TEST_DESC);
+ this.setStepStatus(Constants.TEST_PROCESSING);
+ }
+ }
+
+ /**
+ * EXCEPTION_TEST_FINISH
+ *
+ * @param isCompatibilityTest isCompatibilityTest
+ */
+ public void setExceptionTestFinish(boolean isCompatibilityTest) {
+ this.setStep(Constants.RELIABILITY_TEST_DESC);
+ this.setStepStatus(Constants.TEST_FINISHED_CN);
+ if (isCompatibilityTest) {
+ this.setStep(Constants.COMPATIBILITY_TEST_DESC);
+ this.setStepStatus(Constants.TEST_PROCESSING);
+ }
+ }
+ }
+
+ /**
+ * MessageResult
+ *
+ * @author kongcaizhi
+ * @since 2021-10-30
+ */
+ @AllArgsConstructor
+ @NoArgsConstructor
+ @Data
+ public static class MessageResult {
+ private CloudLabTestTask.TestCaseSummary testSummary;
+ private List testDetail;
+ private ScriptResultConfig scriptResultConfig;
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/PerformanceService.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/PerformanceService.java
new file mode 100644
index 0000000..c5d1602
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/PerformanceService.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.entity;
+
+import lombok.Data;
+
+/**
+ * PerformanceService
+ *
+ * @author kongcaizhi
+ * @since 2021-10-30
+ */
+@Data
+public class PerformanceService {
+ private String id;
+ private String deviceId;
+ private String serviceIp;
+ private String loginAccount;
+ private String loginPassword;
+ private String status;
+ private int taskNum;
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/ScriptResultConfig.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/ScriptResultConfig.java
new file mode 100644
index 0000000..7ff6688
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/ScriptResultConfig.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.entity;
+
+import lombok.Data;
+
+/**
+ * ScriptResultConfig
+ *
+ * @author kongcaizhi
+ * @since 2021-10-30
+ */
+@Data
+public class ScriptResultConfig {
+ private String applicationNames;
+ private String startAppCommands;
+ private String stopAppCommands;
+ private String osVersion;
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/SystemParams.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/SystemParams.java
new file mode 100644
index 0000000..51f8b82
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/SystemParams.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.entity;
+
+import lombok.Data;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+/**
+ * SystemParams
+ *
+ * @author kongcaizhi
+ * @since 2021-10-30
+ */
+@Component
+@Data
+public class SystemParams {
+ @Value("${scriptConfigCn}")
+ private String scriptConfigCn;
+
+ @Value("${scriptConfigEn}")
+ private String scriptConfigEn;
+
+ @Value("${tempDir}")
+ private String tempDir;
+
+ @Value("${deployIp}")
+ private String deployIP;
+
+ @Value("${uploadFileDir}")
+ private String uploadFileDir;
+
+ @Value("${appId}")
+ private String appId;
+
+ @Value("${appKey}")
+ private String appKey;
+
+ @Value("${mqsTopic}")
+ private String mqsTopic;
+
+ @Value("${mqsUrl}")
+ private String mqsUrl;
+
+ @Value("${clamdIp}")
+ private String clamdIp;
+
+ @Value("${clamdPort}")
+ private int clamdPort;
+
+ @Value("${performanceTestUrl}")
+ private String performanceTestUrl;
+
+
+ @Value("${appIdUat}")
+ private String appIdUat;
+
+ @Value("${appKeyUat}")
+ private String appKeyUat;
+
+ @Value("${mqsTopicUat}")
+ private String mqsTopicUat;
+
+ @Value("${mqsUrlUat}")
+ private String mqsUrlUat;
+
+ @Value("${kunpengServiceUrl}")
+ private String kunpengServiceUrl;
+
+ /**
+ * get Script Config
+ *
+ * @param language language
+ * @return Config
+ */
+ public String getScriptConfig(String language) {
+ return "CN".equals(language) ? scriptConfigCn : scriptConfigEn;
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/TaskDelay.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/TaskDelay.java
new file mode 100644
index 0000000..8ed1261
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/TaskDelay.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.entity;
+
+import com.huawei.ic.openlab.cloudtest.util.Constants;
+import com.huawei.ic.openlab.cloudtest.util.ToolUtil;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * TaskDelay
+ *
+ * @author kongcaizhi
+ * @since 2021-10-30
+ */
+@Data
+@Slf4j
+@AllArgsConstructor
+@NoArgsConstructor
+public class TaskDelay {
+ private static final long PERFORMANCE_DELAY = 60 * 60 * 1000L;
+ private static final long DELAY = 60 * 60 * 1000L;
+
+ private String projectId;
+ private Long startTime;
+ private Long updateTime;
+ private String currentStatus;
+
+ /**
+ * 更新任务状态
+ *
+ * @param currentStatus currentStatus
+ */
+ public void updateCurrentStatus(String currentStatus) {
+ this.updateTime = ToolUtil.getMillionSeconds();
+ this.currentStatus = currentStatus;
+ }
+
+ /**
+ * 判断任务是否过期
+ *
+ * @return isExpired
+ */
+ public boolean isExpired() {
+ if (Constants.PERFORMANCE_TESTING.equals(currentStatus)) {
+ return (ToolUtil.getMillionSeconds() - this.updateTime) > PERFORMANCE_DELAY;
+ } else {
+ return (ToolUtil.getMillionSeconds() - this.updateTime) > DELAY;
+ }
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/TestCaseResult.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/TestCaseResult.java
new file mode 100644
index 0000000..e488989
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/TestCaseResult.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.entity;
+
+import com.huawei.ic.openlab.cloudtest.util.Constants;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+
+import lombok.Data;
+
+import org.springframework.util.StringUtils;
+
+import java.util.List;
+
+/**
+ * TaskDelay
+ *
+ * @author kongcaizhi
+ * @since 2021-10-30
+ */
+@Data
+public class TestCaseResult {
+ private String id;
+ private String result;
+ private String evidence;
+ private String reason;
+
+ /**
+ * transferResult
+ *
+ * @return String
+ */
+ public String transferResult() {
+ if (Constants.TEST_PASSED.equals(result)) {
+ return "通过";
+ } else {
+ return "不通过";
+ }
+ }
+
+ /**
+ * transferEvidence
+ *
+ * @return String
+ */
+ public String transferEvidence() {
+ JSONArray array = JSON.parseArray(evidence);
+ List list = array.toJavaList(String.class);
+ return String.join("", list);
+ }
+
+ /**
+ * transferReason
+ *
+ * @return String
+ */
+ public String transferReason() {
+ if (StringUtils.hasLength(reason)) {
+ return ",原因为:" + reason;
+ } else {
+ return "";
+ }
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/TestCaseResultCount.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/TestCaseResultCount.java
new file mode 100644
index 0000000..1f3a984
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/TestCaseResultCount.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.entity;
+
+import com.huawei.ic.openlab.cloudtest.util.Constants;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * TestCaseResultCount
+ *
+ * @author kongcaizhi
+ * @since 2021-10-30
+ */
+@AllArgsConstructor
+@NoArgsConstructor
+@Data
+public class TestCaseResultCount {
+ private int total = 0;
+ private int passed = 0;
+ private int failed = 0;
+ private String startTime;
+
+ /**
+ * add result
+ *
+ * @param result result
+ */
+ public void add(String result) {
+ if (Constants.TEST_PASSED.equals(result)) {
+ passed += 1;
+ } else {
+ failed += 1;
+ }
+ total += 1;
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/CompatibilityFilesParser.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/CompatibilityFilesParser.java
new file mode 100644
index 0000000..d4884e1
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/CompatibilityFilesParser.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis;
+
+import java.io.IOException;
+
+/**
+ * CompatibilityFilesParser
+ *
+ * @author kongcaizhi
+ * @since 2021-12-15
+ */
+public interface CompatibilityFilesParser {
+ /**
+ * Get result
+ *
+ * @return CompatibilityTestResult
+ * @throws IOException exception
+ */
+ CompatibilityTestResult getResult() throws IOException;
+
+ /**
+ * parseFiles
+ *
+ * @return CompatibilityTestResult
+ * @throws IOException exception
+ */
+ CompatibilityTestResult parseFiles() throws IOException;
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/CompatibilityTestResult.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/CompatibilityTestResult.java
new file mode 100644
index 0000000..56776b8
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/CompatibilityTestResult.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis;
+
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * CompatibilityTestResult
+ *
+ * @author kongcaizhi
+ * @since 2021-12-15
+ */
+@Data
+public class CompatibilityTestResult {
+ private String id;
+ private String result;
+ private List evidence = new ArrayList<>();
+ private List evidenceEn = new ArrayList<>();
+ private String reason;
+ private String reasonEn;
+ private String osVersion;
+ private List applicationNames;
+ private List startAppCommands;
+ private List stopAppCommands;
+ private List deployDir;
+
+ /**
+ * CompatibilityTestResult
+ *
+ * @param testName test Name
+ */
+ public CompatibilityTestResult(String testName) {
+ this.id = testName;
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/ParseFunctionTestLog.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/ParseFunctionTestLog.java
new file mode 100644
index 0000000..715878d
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/ParseFunctionTestLog.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis;
+
+import com.huawei.ic.openlab.cloudtest.common.exception.BaseException;
+import com.huawei.ic.openlab.cloudtest.util.Constants;
+
+import com.alibaba.fastjson.JSONObject;
+
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * ParseFunctionTestLog
+ *
+ * @author kongcaizhi
+ * @since 2021-12-15
+ */
+@Slf4j
+public class ParseFunctionTestLog {
+ private static final Pattern RUN_PATTERN = Pattern.compile(Constants.PYTEST_RUN_PATTERN);
+ private static final Pattern SUCCESS_PATTERN = Pattern.compile(Constants.PYTEST_SUCCESS_PATTERN);
+ private static final Pattern FAIL_PATTERN = Pattern.compile(Constants.PYTEST_FAILED_PATTERN);
+ private static final Pattern SHELL_TEST_PATTERN = Pattern.compile(Constants.SHELL_UNIT_TEST_PATTERN);
+ private static final Pattern SHELL_RUN_PATTERN = Pattern.compile(Constants.SHELL_UNIT_RUN_PATTERN);
+ private static final Pattern SHELL_FAIL_PATTERN = Pattern.compile(Constants.SHELL_UNIT_FAILED_PATTERN);
+
+ private final byte[] shellBytes;
+ private final byte[] pytestBytes;
+
+ /**
+ * constructin function
+ *
+ * @param shellBytes shellBytes
+ * @param pytestBytes pytestBytes
+ */
+ public ParseFunctionTestLog(byte[] shellBytes, byte[] pytestBytes) {
+ this.shellBytes = shellBytes;
+ this.pytestBytes = pytestBytes;
+ }
+
+ /**
+ * get Shell Result
+ *
+ * @return CompatibilityTestResult
+ * @throws IOException IOException
+ */
+ public CompatibilityTestResult getShellResult() {
+ Map resultMap = new HashMap<>();
+ resultMap.put(Constants.TEST_FAILED, 0);
+ resultMap.put(Constants.TEST_PASSED, 0);
+
+ List evidenceList = matches(resultMap);
+ CompatibilityTestResult testResult = new CompatibilityTestResult("Function_Test");
+ testResult.setEvidence(evidenceList);
+ testResult.setReason(JSONObject.toJSONString(resultMap));
+ return testResult;
+ }
+
+ private List matches(Map resultMap) {
+ List evidenceList = new ArrayList<>();
+ try (InputStream inputStream = new ByteArrayInputStream(shellBytes);
+ BufferedReader reader = new BufferedReader(
+ new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
+ String line;
+ int totalTest = 0;
+ while ((line = reader.readLine()) != null) {
+ match(line, evidenceList, resultMap, totalTest);
+ }
+ } catch (IOException e) {
+ throw new BaseException(e.getMessage());
+ }
+ return evidenceList;
+ }
+
+ private void match(String line, List evidenceList, Map resultMap,
+ int totalTest) {
+ int failTest;
+ int total = totalTest;
+ Matcher testMatch = SHELL_TEST_PATTERN.matcher(line);
+ if (testMatch.find()) {
+ evidenceList.add(line.replace(System.lineSeparator(), ""));
+ }
+ Matcher matcher = SHELL_RUN_PATTERN.matcher(line);
+ if (matcher.find()) {
+ evidenceList.add(line.replace(System.lineSeparator(), ""));
+ try {
+ total = Integer.parseInt(matcher.group(1).trim());
+ } catch (NumberFormatException ex) {
+ total = 0;
+ }
+ }
+ if (line.matches("^\\\u001B\\[1;32mOK\\\u001B\\[0m")) {
+ evidenceList.add(line.replace(System.lineSeparator(), ""));
+ resultMap.put(Constants.TEST_PASSED, total + resultMap.get(Constants.TEST_PASSED));
+ total = 0;
+ }
+ Matcher failedMatcher = SHELL_FAIL_PATTERN.matcher(line);
+ if (failedMatcher.find()) {
+ evidenceList.add(line.replace(System.lineSeparator(), ""));
+ try {
+ failTest = Integer.parseInt(failedMatcher.group(1).trim());
+ } catch (NumberFormatException ex) {
+ failTest = 0;
+ }
+ if (failTest > total) {
+ failTest = total;
+ }
+ resultMap.put(Constants.TEST_FAILED, failTest + resultMap.get(Constants.TEST_FAILED));
+ if (total != 0) {
+ resultMap.put(Constants.TEST_PASSED,
+ total - failTest + resultMap.get(Constants.TEST_PASSED));
+ }
+ }
+ }
+
+ private CompatibilityTestResult getPytestResult() {
+ List evidenceList = new ArrayList<>();
+ Map resultMap = new HashMap<>();
+ resultMap.put(Constants.TEST_FAILED, 0);
+ resultMap.put(Constants.TEST_PASSED, 0);
+
+ try (InputStream inputStream = new ByteArrayInputStream(pytestBytes);
+ BufferedReader reader = new BufferedReader(
+ new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
+ String line;
+ while ((line = reader.readLine()) != null) {
+ matcher(line, evidenceList, resultMap);
+ }
+ } catch (IOException e) {
+ throw new BaseException(e.getMessage());
+ }
+ CompatibilityTestResult testResult = new CompatibilityTestResult("Function_Test");
+ testResult.setReason(JSONObject.toJSONString(resultMap));
+ testResult.setEvidence(evidenceList);
+ return testResult;
+ }
+
+ private void matcher(String line, List evidenceList, Map resultMap) {
+ Matcher runMatcher = RUN_PATTERN.matcher(line);
+ if (runMatcher.find()) {
+ evidenceList.add(line.replace(System.lineSeparator(), ""));
+ }
+ Matcher matcher = SUCCESS_PATTERN.matcher(line);
+ if (matcher.find()) {
+ evidenceList.add(line.replace(System.lineSeparator(), ""));
+ try {
+ resultMap.put(Constants.TEST_PASSED,
+ Integer.parseInt(matcher.group(1).trim()) + resultMap.get(Constants.TEST_PASSED));
+ } catch (NumberFormatException ex) {
+ log.error("Error in parsing Python test results {}", line);
+ }
+ }
+ Matcher failedMatcher = FAIL_PATTERN.matcher(line);
+ if (failedMatcher.find()) {
+ evidenceList.add(line.replace(System.lineSeparator(), ""));
+ try {
+ resultMap.put(Constants.TEST_PASSED,
+ Integer.parseInt(failedMatcher.group(2).trim())
+ + resultMap.get(Constants.TEST_PASSED));
+ resultMap.put(Constants.TEST_FAILED,
+ Integer.parseInt(failedMatcher.group(1).trim())
+ + resultMap.get(Constants.TEST_FAILED));
+ } catch (NumberFormatException ex) {
+ log.error("Error in parsing Python test results {}", line);
+ }
+ }
+ }
+
+ /**
+ * parseFunctionTestLog
+ *
+ * @return CompatibilityTestResult
+ */
+ public CompatibilityTestResult parseFunctionTestLog() {
+ Map resultMap = new HashMap<>();
+ List evidenceList = new ArrayList<>();
+ CompatibilityTestResult testResult = new CompatibilityTestResult("Function_Test");
+ try {
+ if (shellBytes.length != 0) {
+ CompatibilityTestResult shellResult = getShellResult();
+ if (shellResult.getEvidence() != null && shellResult.getEvidence().size() > 0) {
+ evidenceList.addAll(shellResult.getEvidence());
+ }
+ if (shellResult.getReason() != null) {
+ JSONObject jsonObject = JSONObject.parseObject(shellResult.getReason());
+ resultMap.put(Constants.TEST_FAILED, jsonObject.getIntValue(Constants.TEST_FAILED));
+ resultMap.put(Constants.TEST_PASSED, jsonObject.getIntValue(Constants.TEST_PASSED));
+ }
+ }
+ if (pytestBytes.length != 0) {
+ CompatibilityTestResult pytestResult = getPytestResult();
+ if (pytestResult.getEvidence() != null && pytestResult.getEvidence().size() > 0) {
+ evidenceList.addAll(pytestResult.getEvidence());
+ }
+ if (pytestResult.getReason() != null) {
+ JSONObject jsonObject = JSONObject.parseObject(pytestResult.getReason());
+ resultMap.put(Constants.TEST_FAILED, resultMap.getOrDefault(Constants.TEST_FAILED, 0)
+ + jsonObject.getIntValue(Constants.TEST_FAILED));
+ resultMap.put(Constants.TEST_PASSED, resultMap.getOrDefault(Constants.TEST_PASSED, 0)
+ + jsonObject.getIntValue(Constants.TEST_PASSED));
+ }
+ }
+ testResult.setResult(Constants.TEST_PASSED);
+ testResult.setReason(JSONObject.toJSONString(resultMap));
+ testResult.setEvidence(evidenceList);
+ if (pytestBytes.length == 0 & shellBytes.length == 0) {
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason("没有功能测试文件");
+ }
+ } catch (BaseException e) {
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason("功能测试文件解析出错");
+ }
+ return testResult;
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/ParseInfoLog.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/ParseInfoLog.java
new file mode 100644
index 0000000..6a3e6a7
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/ParseInfoLog.java
@@ -0,0 +1,219 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis;
+
+import com.huawei.ic.openlab.cloudtest.util.Constants;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * ParseInfoLog
+ *
+ * @author kongcaizhi
+ * @since 2021-12-15
+ */
+@Slf4j
+public class ParseInfoLog {
+ private final byte[] infoLogBytes;
+ private String osVersion;
+
+ /**
+ * construction function
+ *
+ * @param infoLogBytes info log bytes
+ * @param osVersion os version
+ */
+ public ParseInfoLog(byte[] infoLogBytes, String osVersion) {
+ this.infoLogBytes = infoLogBytes;
+ this.osVersion = osVersion;
+ }
+
+ private Map initMap() {
+ Map resultMap = new HashMap<>();
+ resultMap.put(Constants.CompatibilityTestName.APPLICATION_START.getTestName(),
+ new CompatibilityTestResult(Constants.CompatibilityTestName.APPLICATION_START.getTestName()));
+ resultMap.put(Constants.CompatibilityTestName.APPLICATION_STOP.getTestName(),
+ new CompatibilityTestResult(Constants.CompatibilityTestName.APPLICATION_STOP.getTestName()));
+ resultMap.put(Constants.CompatibilityTestName.EXCEPTION_KILL.getTestName(),
+ new CompatibilityTestResult(Constants.CompatibilityTestName.EXCEPTION_KILL.getTestName()));
+ return resultMap;
+ }
+
+ /**
+ * parse info log
+ *
+ * @return Map
+ */
+ public Map parseInfoLog() {
+ Map resultMap = initMap();
+ if (infoLogBytes.length == 0) {
+ for (Map.Entry entry : resultMap.entrySet()) {
+ CompatibilityTestResult testResult = entry.getValue();
+ testResult.setResult(Constants.INFO_TEST_CASE_RESULT_MAP.get("FILE_NOT_EXIT").getTestResult());
+ testResult.setReason(Constants.INFO_TEST_CASE_RESULT_MAP.get("FILE_NOT_EXIT").getTestReason());
+ testResult.setReasonEn(Constants.INFO_TEST_CASE_RESULT_MAP.get("FILE_NOT_EXIT").getTestReasonEn());
+ entry.setValue(testResult);
+ }
+ return resultMap;
+ }
+ try {
+ resultMap = readInfoLog();
+ } catch (IllegalStateException | IOException ex) {
+ log.error("Exception in parsing info.log ", ex);
+ for (Map.Entry entry : resultMap.entrySet()) {
+ CompatibilityTestResult testResult = entry.getValue();
+ testResult.setResult(Constants.INFO_TEST_CASE_RESULT_MAP.get("READ_ERROR").getTestResult());
+ testResult.setReason(Constants.INFO_TEST_CASE_RESULT_MAP.get("READ_ERROR").getTestReason());
+ testResult.setReasonEn(Constants.INFO_TEST_CASE_RESULT_MAP.get("READ_ERROR").getTestReasonEn());
+ entry.setValue(testResult);
+ }
+ } catch (Exception ex) {
+ log.error("Exception in uncompressing info.log ", ex);
+ for (Map.Entry entry : resultMap.entrySet()) {
+ CompatibilityTestResult testResult = entry.getValue();
+ testResult.setResult(Constants.INFO_TEST_CASE_RESULT_MAP.get("UNZIP_ERROR").getTestResult());
+ testResult.setReason(Constants.INFO_TEST_CASE_RESULT_MAP.get("UNZIP_ERROR").getTestReason());
+ testResult.setReasonEn(Constants.INFO_TEST_CASE_RESULT_MAP.get("UNZIP_ERROR").getTestReasonEn());
+ entry.setValue(testResult);
+ }
+ }
+ return resultMap;
+ }
+
+ /**
+ * get os version
+ *
+ * @return os version
+ */
+ public String getOsVersion() {
+ return osVersion;
+ }
+
+ /**
+ * 读取Info日志
+ *
+ * @return map
+ * @throws IOException exception
+ */
+ private Map readInfoLog() throws IOException {
+ Map> evidenceMap = new HashMap<>();
+
+ try (InputStream inputStream = new ByteArrayInputStream(infoLogBytes);
+ BufferedReader reader = new BufferedReader(
+ new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
+ List beginTestIndex = new ArrayList<>();
+ String line;
+ int count = 0;
+ reader.mark(infoLogBytes.length + 1);
+ while ((line = reader.readLine()) != null) {
+ count++;
+ if (StringUtils.contains(line, Constants.START_TEST_STRING) || StringUtils.contains(line,
+ Constants.START_TEST_STRING_EN)) {
+ beginTestIndex.add(count);
+ }
+ }
+ int lastBeginTest = Collections.max(beginTestIndex);
+ reader.reset();
+
+ for (int i = 0; i <= lastBeginTest; i++) {
+ reader.readLine();
+ }
+
+ StringBuilder stringBuilder = new StringBuilder(16);
+ while ((line = reader.readLine()) != null) {
+ stringBuilder.append(line).append(System.lineSeparator());
+ }
+
+ Matcher osMatcher = Pattern.compile(Constants.OS_PATTERN_CN).matcher(stringBuilder.toString());
+ if (osMatcher.find()) {
+ osVersion = osMatcher.group(3);
+ }
+ for (Map.Entry entry : Constants.LOG_WHITE_RULES.entrySet()) {
+ Pattern pattern = entry.getValue();
+ Matcher matcher = pattern.matcher(stringBuilder.toString());
+ if (matcher.find()) {
+ List evidenceList = evidenceMap.getOrDefault(entry.getKey(), new ArrayList<>());
+ evidenceList.add(matcher.group(0).replace(System.lineSeparator(), ""));
+ evidenceMap.put(entry.getKey(), evidenceList);
+ }
+ }
+ }
+ return getResultMap(evidenceMap);
+ }
+
+ /**
+ * 根据日志解析内容,返回用例结果.
+ *
+ * @param evidenceMap map
+ * @return map
+ */
+ private Map getResultMap(Map> evidenceMap) {
+ CompatibilityTestResult startTest =
+ new CompatibilityTestResult(Constants.CompatibilityTestName.APPLICATION_START.getTestName());
+ CompatibilityTestResult stopTest =
+ new CompatibilityTestResult(Constants.CompatibilityTestName.APPLICATION_STOP.getTestName());
+ CompatibilityTestResult exceptionTest =
+ new CompatibilityTestResult(Constants.CompatibilityTestName.EXCEPTION_KILL.getTestName());
+ startTest.setOsVersion(getOsVersion());
+
+ if (evidenceMap.size() > 0) {
+ for (Map.Entry> entry : evidenceMap.entrySet()) {
+ if (entry.getKey().contains("START_APP")) {
+ startTest.setResult(Constants.INFO_TEST_CASE_RESULT_MAP.get(entry.getKey()).getTestResult());
+ startTest.setReason(Constants.INFO_TEST_CASE_RESULT_MAP.get(entry.getKey()).getTestReason());
+ startTest.setReasonEn(Constants.INFO_TEST_CASE_RESULT_MAP.get(entry.getKey()).getTestReasonEn());
+ startTest.setEvidence(entry.getValue());
+ startTest.setEvidenceEn(entry.getValue());
+ }
+ if (entry.getKey().contains("RELIABLE_TEST")) {
+ exceptionTest.setResult(Constants.INFO_TEST_CASE_RESULT_MAP.get(entry.getKey()).getTestResult());
+ exceptionTest.setReason(Constants.INFO_TEST_CASE_RESULT_MAP.get(entry.getKey()).getTestReason());
+ exceptionTest.setReasonEn(
+ Constants.INFO_TEST_CASE_RESULT_MAP.get(entry.getKey()).getTestReasonEn());
+ exceptionTest.setEvidence(entry.getValue());
+ exceptionTest.setEvidenceEn(entry.getValue());
+ }
+ if (entry.getKey().contains("STOP_APP")) {
+ stopTest.setResult(Constants.INFO_TEST_CASE_RESULT_MAP.get(entry.getKey()).getTestResult());
+ stopTest.setReason(Constants.INFO_TEST_CASE_RESULT_MAP.get(entry.getKey()).getTestReason());
+ stopTest.setReasonEn(Constants.INFO_TEST_CASE_RESULT_MAP.get(entry.getKey()).getTestReasonEn());
+ stopTest.setEvidence(entry.getValue());
+ stopTest.setEvidenceEn(entry.getValue());
+ }
+ }
+ } else {
+ startTest.setResult(Constants.INFO_TEST_CASE_RESULT_MAP.get("NO_START_APP").getTestResult());
+ startTest.setReason(Constants.INFO_TEST_CASE_RESULT_MAP.get("NO_START_APP").getTestReason());
+ startTest.setReasonEn(Constants.INFO_TEST_CASE_RESULT_MAP.get("NO_START_APP").getTestReasonEn());
+ stopTest.setResult(Constants.INFO_TEST_CASE_RESULT_MAP.get("NO_STOP_APP").getTestResult());
+ stopTest.setReason(Constants.INFO_TEST_CASE_RESULT_MAP.get("NO_STOP_APP").getTestReason());
+ stopTest.setReasonEn(Constants.INFO_TEST_CASE_RESULT_MAP.get("NO_STOP_APP").getTestReasonEn());
+ exceptionTest.setResult(Constants.INFO_TEST_CASE_RESULT_MAP.get("NO_RELIABLE_TEST").getTestResult());
+ exceptionTest.setReason(Constants.INFO_TEST_CASE_RESULT_MAP.get("NO_RELIABLE_TEST").getTestReason());
+ exceptionTest.setReasonEn(Constants.INFO_TEST_CASE_RESULT_MAP.get("NO_RELIABLE_TEST").getTestReasonEn());
+ }
+ Map resultMap = new HashMap<>();
+ resultMap.put(Constants.CompatibilityTestName.APPLICATION_START.getTestName(), startTest);
+ resultMap.put(Constants.CompatibilityTestName.APPLICATION_STOP.getTestName(), stopTest);
+ resultMap.put(Constants.CompatibilityTestName.EXCEPTION_KILL.getTestName(), exceptionTest);
+ return resultMap;
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/ParseSafetyFiles.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/ParseSafetyFiles.java
new file mode 100644
index 0000000..74f7f62
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/ParseSafetyFiles.java
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis;
+
+import com.huawei.ic.openlab.cloudtest.common.exception.BaseException;
+import com.huawei.ic.openlab.cloudtest.util.Constants;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+/**
+ * ParseSafetyFiles
+ *
+ * @author kongcaizhi
+ * @since 2021-12-15
+ */
+@Slf4j
+public class ParseSafetyFiles {
+ private final byte[] protocolBytes;
+ private final byte[] udpBytes;
+ private final byte[] tcpBytes;
+
+ /**
+ * construction function
+ *
+ * @param protocolBytes bytes
+ * @param udpBytes udp bytes
+ * @param tcpBytes tcp bytes
+ */
+ public ParseSafetyFiles(byte[] protocolBytes, byte[] udpBytes, byte[] tcpBytes) {
+ this.protocolBytes = protocolBytes;
+ this.udpBytes = udpBytes;
+ this.tcpBytes = tcpBytes;
+ }
+
+ /**
+ * get average
+ *
+ * @param fileBytes file bytes
+ * @return average list
+ * @throws IOException exception
+ */
+ public List getAverage(byte[] fileBytes) throws IOException {
+ List averageList = new ArrayList<>();
+ try (InputStream beginInput = new ByteArrayInputStream(fileBytes);
+ BufferedReader beginReader = new BufferedReader(
+ new InputStreamReader(beginInput, StandardCharsets.UTF_8))) {
+ String line;
+ while ((line = beginReader.readLine()) != null) {
+ if (!StringUtils.startsWith(line, "#")
+ || StringUtils.containsIgnoreCase(line, "# Ports scanned")) {
+ averageList.add(line.trim());
+ }
+ }
+ }
+ return averageList;
+ }
+
+ /**
+ * read safety file
+ *
+ * @return CompatibilityTestResult
+ * @throws IOException exception
+ */
+ public CompatibilityTestResult readSafetyFile() throws IOException {
+ if (protocolBytes.length == 0 || udpBytes.length == 0 || tcpBytes.length == 0) {
+ throw new BaseException("端口扫描文件缺失");
+ }
+ List protocolList = getAverage(protocolBytes);
+ List tcpList = getAverage(tcpBytes);
+ List udpList = getAverage(udpBytes);
+
+ CompatibilityTestResult testResult =
+ new CompatibilityTestResult(Constants.CompatibilityTestName.SECURITY_PORT.getTestName());
+ if (protocolList.size() > 0 && tcpList.size() > 0 && udpList.size() > 0) {
+ testResult.setResult(Constants.TEST_PASSED);
+ List evidenceList = new ArrayList<>();
+ List evidenceEnList = new ArrayList<>();
+ evidenceList.add(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_LIST.get(5), "PROTOCOL"));
+ evidenceList.addAll(protocolList);
+ evidenceList.add(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_LIST.get(5), "UDP"));
+ evidenceList.addAll(udpList);
+ evidenceList.add(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_LIST.get(5), "TCP"));
+ evidenceList.addAll(tcpList);
+ testResult.setEvidence(evidenceList);
+ evidenceEnList.add(String.format(Locale.ROOT,
+ Constants.COMPATIBILITY_DESC_EN_LIST.get(5), "PROTOCOL"));
+ evidenceEnList.addAll(protocolList);
+ evidenceEnList.add(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_EN_LIST.get(5), "UDP"));
+ evidenceEnList.addAll(udpList);
+ evidenceEnList.add(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_EN_LIST.get(5), "TCP"));
+ evidenceEnList.addAll(tcpList);
+ testResult.setEvidenceEn(evidenceEnList);
+ } else {
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(Constants.SAFETY_FILE_LOSS);
+ testResult.setReasonEn(Constants.SAFETY_FILE_LOSS_EN);
+ }
+ return testResult;
+ }
+
+ /**
+ * parseSafetyFile
+ *
+ * @return CompatibilityTestResult
+ */
+ public CompatibilityTestResult parseSafetyFile() {
+ CompatibilityTestResult testResult =
+ new CompatibilityTestResult(Constants.CompatibilityTestName.SECURITY_PORT.getTestName());
+ try {
+ testResult = readSafetyFile();
+ } catch (BaseException ex) {
+ log.error("Missing security file", ex.getMessage());
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(Constants.SAFETY_FILE_LOSS);
+ testResult.setReasonEn(Constants.SAFETY_FILE_LOSS_EN);
+ } catch (NumberFormatException | IOException ex) {
+ log.error("Security file parsing error", ex);
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(String.format(Locale.ROOT,
+ Constants.COMPATIBILITY_DESC_LIST.get(2), "安全测试"));
+ testResult.setReasonEn(String.format(Locale.ROOT,
+ Constants.COMPATIBILITY_DESC_EN_LIST.get(2), "security "
+ + "test"));
+ }
+ return testResult;
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/AbsParseCompatibilityFiles.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/AbsParseCompatibilityFiles.java
new file mode 100644
index 0000000..2b4aaf3
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/AbsParseCompatibilityFiles.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.impl;
+
+import com.huawei.ic.openlab.cloudtest.common.exception.BaseException;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.CompatibilityTestResult;
+import com.huawei.ic.openlab.cloudtest.util.Constants;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * AbsParseCompatibilityFiles
+ *
+ * @author kongcaizhi
+ * @since 2021-12-15
+ */
+abstract class AbsParseCompatibilityFiles {
+ private final Map beginByteMap;
+ private final Map endByteMap;
+
+ /**
+ * AbsParseCompatibilityFiles init
+ *
+ * @param beginByteMap beginByteMap
+ * @param endByteMap endByteMap
+ */
+ protected AbsParseCompatibilityFiles(Map beginByteMap, Map endByteMap) {
+ this.beginByteMap = beginByteMap;
+ this.endByteMap = endByteMap;
+ }
+
+ /**
+ * read File
+ *
+ * @param beginBytes beginBytes
+ * @param endBytes endBytes
+ * @return CompatibilityTestResult
+ * @throws IOException Exception
+ */
+ abstract CompatibilityTestResult readFile(byte[] beginBytes, byte[] endBytes) throws IOException;
+
+ /**
+ * Get average rate
+ *
+ * @param fileBytes file bytes
+ * @return average list
+ * @throws IOException exception
+ */
+ abstract List getAverage(byte[] fileBytes) throws IOException;
+
+ /**
+ * Get Result
+ *
+ * @param testName Test name
+ * @param fileType file type
+ * @param fileTypeEn file type in English
+ * @param descIndex description index
+ * @return CompatibilityTestResult
+ * @throws IOException exception
+ */
+ public CompatibilityTestResult getResult(String testName, String fileType, String fileTypeEn, int descIndex)
+ throws IOException {
+ if (beginByteMap == null || beginByteMap.size() == 0) {
+ throw new BaseException(String.format(Locale.ROOT, "解析空载测试%s文件缺失", fileType));
+ }
+ if (endByteMap == null || endByteMap.size() == 0) {
+ throw new BaseException(String.format(Locale.ROOT, "解析空载测试%s文件缺失", fileType));
+ }
+ List clusterResult = new ArrayList<>();
+ List beginFileNames = beginByteMap.keySet().stream().filter(s -> StringUtils.endsWith(s, ".log"))
+ .collect(Collectors.toList());
+ List endFileNames = endByteMap.keySet().stream().filter(s -> StringUtils.endsWith(s, ".log"))
+ .collect(Collectors.toList());
+
+ if (beginFileNames.size() > 0 && endFileNames.size() > 0) {
+ clusterResult.add(readFile(beginByteMap.get(beginFileNames.get(0)), endByteMap.get(endFileNames.get(0))));
+ }
+
+ if (clusterResult.size() > 0) {
+ if (clusterResult.stream().anyMatch(s -> StringUtils.contains(s.getResult(), Constants.TEST_FAILED))) {
+ return clusterResult.stream().filter(s -> StringUtils.contains(s.getResult(), Constants.TEST_FAILED))
+ .collect(Collectors.toList()).get(0);
+ } else {
+ return clusterResult.get(0);
+ }
+ }
+ CompatibilityTestResult testResult = new CompatibilityTestResult(testName);
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_LIST.get(descIndex), fileType));
+ testResult.setReasonEn(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_EN_LIST.get(descIndex),
+ fileTypeEn));
+ return testResult;
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/AbsParsePerformanceFiles.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/AbsParsePerformanceFiles.java
new file mode 100644
index 0000000..35be92e
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/AbsParsePerformanceFiles.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.impl;
+
+import com.huawei.ic.openlab.cloudtest.common.exception.BaseException;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.CompatibilityTestResult;
+import com.huawei.ic.openlab.cloudtest.util.Constants;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * AbsParsePerformanceFiles
+ *
+ * @author kongcaizhi
+ * @since 2021-12-15
+ */
+abstract class AbsParsePerformanceFiles {
+ private final Map inputByteMap;
+
+ /**
+ * Construction function
+ *
+ * @param inputByteMap map
+ */
+ public AbsParsePerformanceFiles(Map inputByteMap) {
+ this.inputByteMap = inputByteMap;
+ }
+
+ /**
+ * Get result
+ *
+ * @param testName testName
+ * @param fileType file Type
+ * @param fileTypeEn file type in English
+ * @param descIndex description index
+ * @return CompatibilityTestResult object
+ * @throws IOException IOException
+ */
+ public CompatibilityTestResult getResult(String testName, String fileType, String fileTypeEn, int descIndex)
+ throws IOException {
+ CompatibilityTestResult testResult = new CompatibilityTestResult(testName);
+ if (inputByteMap == null || inputByteMap.size() == 0) {
+ throw new BaseException(String.format(Locale.ROOT, "解析压力测试%s文件缺失", fileType));
+ }
+ List beginFileNames = inputByteMap.keySet().stream().filter(s -> StringUtils.endsWith(s, ".log"))
+ .collect(Collectors.toList());
+ if (beginFileNames.size() > 0) {
+ return readFile(inputByteMap.get(beginFileNames.get(0)));
+ }
+
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(String.format(Locale.ROOT, Constants.PERFORMANCE_DESC_LIST.get(descIndex), fileType));
+ testResult.setReasonEn(String.format(Locale.ROOT, Constants.PERFORMANCE_DESC_EN_LIST.get(descIndex),
+ fileTypeEn));
+ return testResult;
+ }
+
+ /**
+ * read file
+ *
+ * @param fileBytes file bytes
+ * @return CompatibilityTestResult
+ * @throws IOException Exception
+ */
+ abstract CompatibilityTestResult readFile(byte[] fileBytes) throws IOException;
+
+ /**
+ * Get Idle list
+ *
+ * @param fileBytes FILE BYTES
+ * @return IDLE List
+ * @throws IOException exception
+ */
+ abstract List getIdleList(byte[] fileBytes) throws IOException;
+
+ /**
+ * GET idle map
+ *
+ * @param fileBytes fileBytes
+ * @return idle map
+ * @throws IOException exception
+ */
+ abstract Map>> getIdleMap(byte[] fileBytes) throws IOException;
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseClamLog.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseClamLog.java
new file mode 100644
index 0000000..f823c8b
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseClamLog.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.impl;
+
+import com.huawei.ic.openlab.cloudtest.common.exception.BaseException;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.CompatibilityFilesParser;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.CompatibilityTestResult;
+import com.huawei.ic.openlab.cloudtest.util.Constants;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.util.CollectionUtils;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+/**
+ * AbsParsePerformanceFiles
+ *
+ * @author kongcaizhi
+ * @since 2021-12-15
+ */
+@Slf4j
+public class ParseClamLog implements CompatibilityFilesParser {
+ private static final String RESULT_DESC = "result";
+ private static final String EVIDENCE_DESC = "evidence";
+
+ private final Map inputByteMap;
+
+ /**
+ * Construction function
+ *
+ * @param inputByteMap map
+ */
+ public ParseClamLog(Map inputByteMap) {
+ this.inputByteMap = inputByteMap;
+ }
+
+ @Override
+ public CompatibilityTestResult getResult() throws IOException {
+ CompatibilityTestResult testResult = new CompatibilityTestResult(
+ Constants.CompatibilityTestName.SECURITY_VIRUS.getTestName());
+ if (inputByteMap == null || inputByteMap.size() == 0) {
+ throw new BaseException("病毒扫描文件缺失");
+ }
+ List beginFileNames = inputByteMap.keySet().stream().filter(s -> StringUtils.contains(s,
+ "clam.log"))
+ .collect(Collectors.toList());
+ if (beginFileNames.size() > 0) {
+ return readVirusScanFile(inputByteMap.get(beginFileNames.get(0)));
+ }
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(Constants.SAFETY_FILE_LOSS);
+ testResult.setReasonEn(Constants.SAFETY_FILE_LOSS_EN);
+ return testResult;
+ }
+
+ private Map> getScanResult(BufferedReader reader) throws IOException {
+ String result = null;
+ List evidenceList = new ArrayList<>();
+ String line;
+ while ((line = reader.readLine()) != null) {
+ String lineTrim = line.trim();
+ evidenceList.add(lineTrim);
+ if (lineTrim.isEmpty()) {
+ break;
+ }
+ Pattern pattern = Pattern.compile(Constants.CLAM_RESULT_PATTERN);
+ Matcher matcher = pattern.matcher(line);
+ if (matcher.find()) {
+ result = matcher.group(1).trim();
+ }
+ }
+ Map> resultMap = new HashMap<>();
+ resultMap.put(RESULT_DESC, Collections.singletonList(result));
+ resultMap.put(EVIDENCE_DESC, evidenceList);
+ return resultMap;
+ }
+
+ /**
+ * Read virus scan file
+ *
+ * @param clamFileBytes clam file bytes
+ * @return CompatibilityTestResult
+ * @throws IOException exception
+ */
+ public CompatibilityTestResult readVirusScanFile(byte[] clamFileBytes) throws IOException {
+ if (clamFileBytes.length == 0) {
+ throw new BaseException("病毒扫描文件的内容为空");
+ }
+
+ Map> resultMap = new HashMap<>();
+ try (InputStream inputStream = new ByteArrayInputStream(clamFileBytes);
+ BufferedReader bufferedReader = new BufferedReader(
+ new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
+ String line;
+ while ((line = bufferedReader.readLine()) != null) {
+ if (StringUtils.containsIgnoreCase(line, "SCAN SUMMARY")) {
+ resultMap = getScanResult(bufferedReader);
+ }
+ }
+ }
+
+ CompatibilityTestResult testResult = new CompatibilityTestResult(
+ Constants.CompatibilityTestName.SECURITY_VIRUS.getTestName());
+ if (resultMap.containsKey(RESULT_DESC) && !CollectionUtils.isEmpty(resultMap.get(RESULT_DESC))) {
+ if (StringUtils.equals(resultMap.get(RESULT_DESC).get(0), "0")) {
+ testResult.setResult(Constants.TEST_PASSED);
+ } else {
+ testResult.setResult(Constants.TEST_FAILED);
+ }
+ if (resultMap.containsKey(EVIDENCE_DESC) && resultMap.get(EVIDENCE_DESC) != null) {
+ testResult.setEvidence(resultMap.get(EVIDENCE_DESC));
+ testResult.setEvidenceEn(resultMap.get(EVIDENCE_DESC));
+ }
+ } else {
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(Constants.SAFETY_FILE_LOSS);
+ testResult.setReasonEn(Constants.SAFETY_FILE_LOSS_EN);
+ }
+ return testResult;
+ }
+
+ @Override
+ public CompatibilityTestResult parseFiles() {
+ CompatibilityTestResult testResult =
+ new CompatibilityTestResult(Constants.CompatibilityTestName.SECURITY_VIRUS.getTestName());
+ try {
+ testResult = getResult();
+ } catch (IOException ex) {
+ log.error("Exception occur in parsing virus file", ex);
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(Constants.SAFETY_FILE_LOSS);
+ }
+ return testResult;
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseCpuComFiles.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseCpuComFiles.java
new file mode 100644
index 0000000..129b1f0
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseCpuComFiles.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.impl;
+
+import com.huawei.ic.openlab.cloudtest.common.exception.BaseException;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.CompatibilityFilesParser;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.CompatibilityTestResult;
+import com.huawei.ic.openlab.cloudtest.util.Constants;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.math.BigDecimal;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * ParseCpuComFiles
+ *
+ * @author kongcaizhi
+ * @since 2021-12-15
+ */
+@Slf4j
+public class ParseCpuComFiles implements CompatibilityFilesParser {
+ private static final String CPU_DESC = "CPU";
+
+ private final ParseCompatibilityFilesImpl parseCompatibilityFiles;
+
+ /**
+ * ParseCpuComFiles
+ *
+ * @param beginCpuByteMap beginCpuByteMap
+ * @param endCpuByteMap endCpuByteMap
+ */
+ public ParseCpuComFiles(Map beginCpuByteMap, Map endCpuByteMap) {
+ this.parseCompatibilityFiles = new ParseCompatibilityFilesImpl(beginCpuByteMap, endCpuByteMap);
+ }
+
+ @Override
+ public CompatibilityTestResult getResult() throws IOException {
+ return parseCompatibilityFiles.getResult(Constants.CompatibilityTestName.IDLE_CPU.getTestName(),
+ CPU_DESC, CPU_DESC, 2);
+ }
+
+ @Override
+ public CompatibilityTestResult parseFiles() {
+ CompatibilityTestResult testResult = new CompatibilityTestResult(
+ Constants.CompatibilityTestName.IDLE_CPU.getTestName());
+ try {
+ testResult = getResult();
+ } catch (BaseException ex) {
+ log.error("Missing idle test cpu file ", ex.getMessage());
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_LIST.get(3), CPU_DESC));
+ testResult.setReasonEn(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_EN_LIST.get(3), CPU_DESC));
+ } catch (NumberFormatException | IOException ex) {
+ log.error("Exception in parsing idle test cpu file ", ex);
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_LIST.get(2), CPU_DESC));
+ testResult.setReasonEn(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_EN_LIST.get(2), CPU_DESC));
+ }
+ return testResult;
+ }
+
+ private static class ParseCompatibilityFilesImpl extends AbsParseCompatibilityFiles {
+ /**
+ * ParseCompatibilityFilesImpl
+ *
+ * @param beginByteMap beginByteMap
+ * @param endByteMap endByteMap
+ */
+ protected ParseCompatibilityFilesImpl(Map beginByteMap, Map endByteMap) {
+ super(beginByteMap, endByteMap);
+ }
+
+ @Override
+ CompatibilityTestResult readFile(byte[] beginBytes, byte[] endBytes) throws IOException {
+ if (beginBytes.length == 0 || endBytes.length == 0) {
+ throw new BaseException("解析空载测试CPU文件缺失");
+ }
+ CompatibilityTestResult testResult = new CompatibilityTestResult(
+ Constants.CompatibilityTestName.IDLE_CPU.getTestName());
+ List beginAverageList = getAverage(beginBytes);
+ List endAverageList = getAverage(endBytes);
+ double cpuMaxUsedIdle;
+ if (beginAverageList.size() > 0 && endAverageList.size() > 0) {
+ cpuMaxUsedIdle =
+ new BigDecimal(beginAverageList.get(0))
+ .subtract(new BigDecimal(endAverageList.get(0))).abs().doubleValue();
+ if (cpuMaxUsedIdle <= 1.0) {
+ testResult.setResult(Constants.TEST_PASSED);
+ List evidence = Arrays.asList(beginAverageList.get(1), endAverageList.get(1),
+ String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_LIST.get(1), CPU_DESC,
+ cpuMaxUsedIdle, "小于"));
+ List evidenceEn = Arrays.asList(beginAverageList.get(1), endAverageList.get(1),
+ String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_EN_LIST.get(1),
+ CPU_DESC, cpuMaxUsedIdle, "less"));
+ testResult.setEvidence(evidence);
+ testResult.setEvidenceEn(evidenceEn);
+ } else {
+ testResult.setResult(Constants.TEST_FAILED);
+ List evidence = Arrays.asList(beginAverageList.get(1), endAverageList.get(1),
+ String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_LIST.get(1), CPU_DESC,
+ cpuMaxUsedIdle, "大于"));
+ testResult.setEvidence(evidence);
+ testResult.setReason(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_LIST.get(1),
+ CPU_DESC, cpuMaxUsedIdle, "大于"));
+ List evidenceEn = Arrays.asList(beginAverageList.get(1), endAverageList.get(1),
+ String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_EN_LIST.get(1),
+ CPU_DESC, cpuMaxUsedIdle, "greater"));
+ testResult.setEvidenceEn(evidenceEn);
+ testResult.setReasonEn(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_EN_LIST.get(1),
+ CPU_DESC, cpuMaxUsedIdle, "greater"));
+ }
+ } else {
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_LIST.get(2), CPU_DESC));
+ testResult.setReasonEn(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_EN_LIST.get(2),
+ CPU_DESC));
+ }
+ return testResult;
+ }
+
+ @Override
+ List getAverage(byte[] fileBytes) throws IOException {
+ List averageList = new ArrayList<>();
+ try (InputStream beginInput = new ByteArrayInputStream(fileBytes);
+ BufferedReader beginReader = new BufferedReader(
+ new InputStreamReader(beginInput, StandardCharsets.UTF_8))) {
+ String line;
+
+ while ((line = beginReader.readLine()) != null) {
+ if (StringUtils.containsIgnoreCase(line, "平均时间")
+ || StringUtils.startsWithIgnoreCase(line, "Average")) {
+ averageList.add(line.substring(line.length() - 8).trim());
+ averageList.add(line.replace(System.lineSeparator(), ""));
+ }
+ }
+ }
+ return averageList;
+ }
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseCpuPerFiles.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseCpuPerFiles.java
new file mode 100644
index 0000000..3ceb5cf
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseCpuPerFiles.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.impl;
+
+import com.huawei.ic.openlab.cloudtest.common.exception.BaseException;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.CompatibilityFilesParser;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.CompatibilityTestResult;
+import com.huawei.ic.openlab.cloudtest.util.Constants;
+
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.math.BigDecimal;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+/**
+ * ParseCpuPerFiles
+ *
+ * @author kongcaizhi
+ * @since 2021-12-15
+ */
+@Slf4j
+public class ParseCpuPerFiles implements CompatibilityFilesParser {
+ private static final String CPU_DESC = "CPU";
+
+ private final ParsePerformanceFilesImpl parsePerformanceFiles;
+
+ /**
+ * construction function
+ *
+ * @param inputByteMap map
+ */
+ public ParseCpuPerFiles(Map inputByteMap) {
+ this.parsePerformanceFiles = new ParsePerformanceFilesImpl(inputByteMap);
+ }
+
+ @Override
+ public CompatibilityTestResult getResult() throws IOException {
+ return parsePerformanceFiles.getResult(Constants.CompatibilityTestName.PRESSURE_CPU.getTestName(),
+ CPU_DESC, CPU_DESC, 2);
+ }
+
+ @Override
+ public CompatibilityTestResult parseFiles() {
+ CompatibilityTestResult testResult = new CompatibilityTestResult(
+ Constants.CompatibilityTestName.PRESSURE_CPU.getTestName());
+ try {
+ testResult = getResult();
+ } catch (BaseException ex) {
+ log.error("Missing pressure test CPU file ", ex);
+ testResult.setResult(Constants.TEST_SKIPPED);
+ testResult.setReason(String.format(Locale.ROOT,
+ Constants.PERFORMANCE_DESC_LIST.get(3), CPU_DESC));
+ testResult.setReasonEn(String.format(Locale.ROOT,
+ Constants.PERFORMANCE_DESC_EN_LIST.get(3), CPU_DESC));
+ } catch (NumberFormatException | IOException ex) {
+ log.error("Exception in parsing pressure test CPU file ", ex);
+
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(String.format(Locale.ROOT,
+ Constants.PERFORMANCE_DESC_LIST.get(2), CPU_DESC));
+ testResult.setReasonEn(String.format(Locale.ROOT,
+ Constants.PERFORMANCE_DESC_EN_LIST.get(2), CPU_DESC));
+ }
+ return testResult;
+ }
+
+ private static class ParsePerformanceFilesImpl extends AbsParsePerformanceFiles {
+ private final Pattern idlePattern = Pattern.compile(
+ "\\d{2}(:|时)\\d{2}(:|分)\\d{2}(秒|\\s(PM|AM|HKT|))\\s+all\\s+");
+
+ /**
+ * ParsePerformanceFilesImpl
+ *
+ * @param inputByteMap inputByteMap
+ */
+ public ParsePerformanceFilesImpl(Map inputByteMap) {
+ super(inputByteMap);
+ }
+
+ @Override
+ CompatibilityTestResult readFile(byte[] fileBytes) throws IOException {
+ if (fileBytes.length == 0) {
+ throw new BaseException("解析压力测试CPU文件缺失");
+ }
+ CompatibilityTestResult testResult = new CompatibilityTestResult(
+ Constants.CompatibilityTestName.PRESSURE_CPU.getTestName());
+ List idleList = getIdleList(fileBytes);
+ if (idleList.size() > 0) {
+ List evidence = new ArrayList<>(idleList.subList(1, idleList.size()));
+ List evidenceEn = new ArrayList<>(idleList.subList(1, idleList.size()));
+ if (Double.parseDouble(idleList.get(0)) <= 5.0d) {
+ testResult.setResult(Constants.TEST_PASSED);
+ evidence.add(String.format(Locale.ROOT,
+ Constants.PERFORMANCE_DESC_LIST.get(0), CPU_DESC,
+ Double.parseDouble(idleList.get(0)), "小于"));
+ evidenceEn.add(String.format(Locale.ROOT,
+ Constants.PERFORMANCE_DESC_EN_LIST.get(0), CPU_DESC,
+ Double.parseDouble(idleList.get(0)), "less"));
+ } else {
+ testResult.setResult(Constants.TEST_FAILED);
+ evidence.add(String.format(Locale.ROOT,
+ Constants.PERFORMANCE_DESC_LIST.get(0), CPU_DESC,
+ Double.parseDouble(idleList.get(0)), "大于"));
+ evidenceEn.add(String.format(Locale.ROOT,
+ Constants.PERFORMANCE_DESC_EN_LIST.get(0), CPU_DESC,
+ Double.parseDouble(idleList.get(0)), "greater"));
+ testResult.setReason(String.format(Locale.ROOT,
+ Constants.PERFORMANCE_DESC_LIST.get(0), CPU_DESC,
+ Double.parseDouble(idleList.get(0)), "大于")
+ + Constants.PERFORMANCE_DESC_LIST.get(1));
+ testResult.setReasonEn(String.format(Locale.ROOT,
+ Constants.PERFORMANCE_DESC_EN_LIST.get(0),
+ CPU_DESC,
+ Double.parseDouble(idleList.get(0)), "greater")
+ + Constants.PERFORMANCE_DESC_EN_LIST.get(1));
+ }
+ testResult.setEvidence(evidence);
+ } else {
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(String.format(Locale.ROOT,
+ Constants.PERFORMANCE_DESC_LIST.get(2), CPU_DESC));
+ testResult.setReasonEn(String.format(Locale.ROOT,
+ Constants.PERFORMANCE_DESC_EN_LIST.get(2), CPU_DESC));
+ }
+ return testResult;
+ }
+
+ @Override
+ List getIdleList(byte[] fileBytes) throws IOException {
+ Double maxIdle = 0.0d;
+ String maxEvidence = null;
+ Double minIdle = 100.0d;
+ String minEvidence = null;
+ try (InputStream beginInput = new ByteArrayInputStream(fileBytes);
+ BufferedReader beginReader = new BufferedReader(
+ new InputStreamReader(beginInput, StandardCharsets.UTF_8))) {
+ String line;
+ while ((line = beginReader.readLine()) != null && idlePattern.matcher(line).find()) {
+ String idle = line.substring(line.length() - 8).trim();
+ if (maxIdle <= Double.parseDouble(idle)) {
+ maxIdle = Double.parseDouble(idle);
+ maxEvidence = line;
+ }
+ if (minIdle >= Double.parseDouble(idle)) {
+ minIdle = Double.parseDouble(idle);
+ minEvidence = line;
+ }
+ }
+ }
+
+ List idleList = new ArrayList<>();
+ if (maxEvidence != null) {
+ idleList.add(String.format(Locale.ROOT, "%.2f", new BigDecimal(maxIdle.toString())
+ .subtract(new BigDecimal(minIdle.toString())).abs().doubleValue()));
+ idleList.add(maxEvidence);
+ idleList.add(minEvidence);
+ }
+ return idleList;
+ }
+
+ @Override
+ Map>> getIdleMap(byte[] fileBytes) {
+ return new HashMap<>();
+ }
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseCveCheckFiles.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseCveCheckFiles.java
new file mode 100644
index 0000000..5cff564
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseCveCheckFiles.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.impl;
+
+import com.huawei.ic.openlab.cloudtest.common.exception.BaseException;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.CompatibilityFilesParser;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.CompatibilityTestResult;
+import com.huawei.ic.openlab.cloudtest.util.Constants;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * ParseCveCheckFiles
+ *
+ * @author kongcaizhi
+ * @since 2021-12-15
+ */
+@Slf4j
+public class ParseCveCheckFiles implements CompatibilityFilesParser {
+ private final Map inputByteMap;
+
+ /**
+ * construction function
+ *
+ * @param inputByteMap map
+ */
+ public ParseCveCheckFiles(Map inputByteMap) {
+ this.inputByteMap = inputByteMap;
+ }
+
+ @Override
+ public CompatibilityTestResult getResult() throws IOException {
+ CompatibilityTestResult testResult = new CompatibilityTestResult(
+ Constants.CompatibilityTestName.SECURITY_VULNERABLE.getTestName());
+ if (inputByteMap == null || inputByteMap.size() == 0) {
+ throw new BaseException("漏洞扫描文件缺失");
+ }
+ List beginFileNames = inputByteMap.keySet().stream().filter(s -> StringUtils.contains(s,
+ "cvecheck-result.json"))
+ .collect(Collectors.toList());
+ if (beginFileNames.size() > 0) {
+ return readVirusScanFile(inputByteMap.get(beginFileNames.get(0)));
+ }
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(Constants.SAFETY_FILE_LOSS);
+ testResult.setReasonEn(Constants.SAFETY_FILE_LOSS_EN);
+ return testResult;
+ }
+
+ /**
+ * readVirusScanFile
+ *
+ * @param cveFileBytes cveFileBytes
+ * @return CompatibilityTestResult
+ * @throws IOException IOException
+ */
+ public CompatibilityTestResult readVirusScanFile(byte[] cveFileBytes) throws IOException {
+ if (cveFileBytes.length == 0) {
+ throw new BaseException("漏洞扫描文件缺失");
+ }
+ String line;
+ StringBuilder stringBuilder = new StringBuilder(16);
+ try (InputStream inputStream = new ByteArrayInputStream(cveFileBytes);
+ BufferedReader reader = new BufferedReader(
+ new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
+ while ((line = reader.readLine()) != null) {
+ stringBuilder.append(line);
+ }
+ }
+ CompatibilityTestResult testResult = new CompatibilityTestResult(
+ Constants.CompatibilityTestName.SECURITY_VULNERABLE.getTestName());
+ if (stringBuilder.toString().matches("(\\[\\])+")) {
+ testResult.setResult(Constants.TEST_PASSED);
+ } else {
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setEvidence(Collections.singletonList(stringBuilder.toString()));
+ testResult.setEvidenceEn(Collections.singletonList(stringBuilder.toString()));
+ testResult.setReason(stringBuilder.toString());
+ testResult.setReasonEn(stringBuilder.toString());
+ }
+ return testResult;
+ }
+
+ @Override
+ public CompatibilityTestResult parseFiles() throws IOException {
+ CompatibilityTestResult testResult = new CompatibilityTestResult(
+ Constants.CompatibilityTestName.SECURITY_VULNERABLE.getTestName());
+ try {
+ testResult = getResult();
+ } catch (NumberFormatException | IOException ex) {
+ log.error("Exception in parsing cve check file ", ex);
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(Constants.SAFETY_FILE_LOSS);
+ testResult.setReasonEn(Constants.SAFETY_FILE_LOSS_EN);
+ }
+ return testResult;
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseDiskComFiles.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseDiskComFiles.java
new file mode 100644
index 0000000..2aa2d92
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseDiskComFiles.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.impl;
+
+import com.huawei.ic.openlab.cloudtest.common.exception.BaseException;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.CompatibilityFilesParser;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.CompatibilityTestResult;
+import com.huawei.ic.openlab.cloudtest.util.Constants;
+
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.math.BigDecimal;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import org.apache.commons.lang3.StringUtils;
+/**
+ * ParseDiskComFiles
+ *
+ * @author kongcaizhi
+ * @since 2021-12-15
+ */
+@Slf4j
+public class ParseDiskComFiles implements CompatibilityFilesParser {
+ private static final String DRIVE_CN = "硬盘";
+ private static final String DRIVE_EN = "drive";
+
+ private final ParseCompatibilityFilesImpl parseCompatibilityFiles;
+
+ /**
+ * ParseDiskComFiles
+ *
+ * @param beginDiskByteMap beginDiskByteMap
+ * @param endDiskByteMap endDiskByteMap
+ */
+ public ParseDiskComFiles(Map beginDiskByteMap, Map endDiskByteMap) {
+ this.parseCompatibilityFiles = new ParseCompatibilityFilesImpl(beginDiskByteMap, endDiskByteMap);
+ }
+
+ @Override
+ public CompatibilityTestResult getResult() throws IOException {
+ return parseCompatibilityFiles.getResult(Constants.CompatibilityTestName.IDLE_DISK.getTestName(),
+ DRIVE_CN, DRIVE_EN, 2);
+ }
+
+ @Override
+ public CompatibilityTestResult parseFiles() {
+ CompatibilityTestResult testResult = new CompatibilityTestResult(
+ Constants.CompatibilityTestName.IDLE_DISK.getTestName());
+ try {
+ testResult = getResult();
+ } catch (BaseException ex) {
+ log.error("Missing idle test disk file ", ex.getMessage());
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_LIST.get(3), DRIVE_CN));
+ testResult.setReasonEn(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_EN_LIST.get(3), DRIVE_EN));
+ } catch (NumberFormatException | IOException ex) {
+ log.error("Exception in parsing idle test disk file ", ex);
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_LIST.get(2), DRIVE_CN));
+ testResult.setReasonEn(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_EN_LIST.get(2), DRIVE_EN));
+ }
+ return testResult;
+ }
+
+ private static class ParseCompatibilityFilesImpl extends AbsParseCompatibilityFiles {
+ private final Pattern averagePattern = Pattern.compile("(平均时间|Average):");
+
+ /**
+ * ParseCompatibilityFilesImpl
+ *
+ * @param beginByteMap beginByteMap
+ * @param endByteMap endByteMap
+ */
+ protected ParseCompatibilityFilesImpl(Map beginByteMap, Map endByteMap) {
+ super(beginByteMap, endByteMap);
+ }
+
+ @Override
+ CompatibilityTestResult readFile(byte[] beginBytes, byte[] endBytes) throws IOException {
+ if (beginBytes.length == 0 || endBytes.length == 0) {
+ throw new BaseException("解析空载测试硬盘文件缺失");
+ }
+
+ Map> beginAverageMap = getAverageMap(beginBytes);
+ Map> endAverageMap = getAverageMap(endBytes);
+
+ double diskMaxUsedIdle = 0.0d;
+ String maxDiskName = null;
+ double diskIdle = 0.0d;
+ if (beginAverageMap.size() > 0 && endAverageMap.size() > 0) {
+ for (Map.Entry> entry : beginAverageMap.entrySet()) {
+ if (!endAverageMap.containsKey(entry.getKey())) {
+ continue;
+ }
+ diskIdle = new BigDecimal(beginAverageMap.get(entry.getKey()).get(0))
+ .subtract(new BigDecimal(endAverageMap.get(entry.getKey()).get(0)))
+ .abs().doubleValue();
+ if (diskMaxUsedIdle <= diskIdle) {
+ maxDiskName = entry.getKey();
+ diskMaxUsedIdle = diskIdle;
+ }
+ }
+ }
+ return getTestResult(maxDiskName, diskMaxUsedIdle, beginAverageMap, endAverageMap);
+ }
+
+ private CompatibilityTestResult getTestResult(String maxDiskName, double diskMaxUsedIdle,
+ Map> beginAverageMap, Map> endAverageMap) {
+ CompatibilityTestResult testResult = new CompatibilityTestResult(
+ Constants.CompatibilityTestName.IDLE_DISK.getTestName());
+ List evidence;
+ List evidenceEn;
+ if (maxDiskName != null) {
+ if (diskMaxUsedIdle <= 1.0) {
+ testResult.setResult(Constants.TEST_PASSED);
+ evidence = Arrays.asList(beginAverageMap.get(maxDiskName).get(1),
+ endAverageMap.get(maxDiskName).get(1),
+ String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_LIST.get(1), DRIVE_CN,
+ diskMaxUsedIdle, "小于"));
+ evidenceEn = Arrays.asList(beginAverageMap.get(maxDiskName).get(1),
+ endAverageMap.get(maxDiskName).get(1),
+ String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_EN_LIST.get(1),
+ DRIVE_EN, diskMaxUsedIdle, "less"));
+ } else {
+ testResult.setResult(Constants.TEST_FAILED);
+ evidence = Arrays.asList(beginAverageMap.get(maxDiskName).get(1),
+ endAverageMap.get(maxDiskName).get(1),
+ String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_LIST.get(1),
+ DRIVE_CN, diskMaxUsedIdle, "大于"));
+ evidenceEn = Arrays.asList(beginAverageMap.get(maxDiskName).get(1),
+ endAverageMap.get(maxDiskName).get(1),
+ String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_EN_LIST.get(1),
+ DRIVE_EN, diskMaxUsedIdle, "greater"));
+ }
+ testResult.setEvidence(evidence);
+ testResult.setEvidenceEn(evidenceEn);
+ } else {
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_LIST.get(2), DRIVE_CN));
+ testResult.setReasonEn(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_EN_LIST.get(2),
+ DRIVE_EN));
+ }
+ return testResult;
+ }
+
+ @Override
+ List getAverage(byte[] fileBytes) {
+ return new ArrayList<>();
+ }
+
+ /**
+ * Get average map
+ *
+ * @param cpuBytes cpu bytes
+ * @return average map
+ * @throws IOException exception
+ */
+ public Map> getAverageMap(byte[] cpuBytes) throws IOException {
+ String line = null;
+ Map> averageMap = new HashMap<>();
+ Map indexMap = new HashMap<>();
+ try (InputStream beginInput = new ByteArrayInputStream(cpuBytes);
+ BufferedReader beginReader = new BufferedReader(
+ new InputStreamReader(beginInput, StandardCharsets.UTF_8))) {
+ boolean flag = true;
+ while ((line = beginReader.readLine()) != null) {
+ if (!StringUtils.containsIgnoreCase(line, "DEV") && averagePattern.matcher(line).find()) {
+ String[] split = line.split("\\s+");
+ String idle = split[indexMap.get("%util")];
+ String diskName = split[indexMap.get("DEV")];
+ List averageList = new ArrayList<>();
+ averageList.add(idle);
+ averageList.add(line.replace("\n", ""));
+ averageMap.put(diskName, averageList);
+ } else if (flag && StringUtils.containsIgnoreCase(line, "DEV")
+ && averagePattern.matcher(line).find() ){
+ indexMap = getIndexMap(line);
+ flag = false;
+ }
+ }
+ }
+ return averageMap;
+ }
+
+ private static Map getIndexMap(String line) {
+ Map indexMap = new HashMap<>();
+ String[] split =line.split("\\s+");
+ for (int i = 0; i < split.length; i++) {
+ if (split[i].equals("DEV")) {
+ indexMap.put("DEV", i);
+ } else if (split[i].equals("%util")) {
+ indexMap.put("%util", i);
+ }
+ }
+ return indexMap;
+ }
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseDiskPerFiles.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseDiskPerFiles.java
new file mode 100644
index 0000000..2049a77
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseDiskPerFiles.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.impl;
+
+import com.huawei.ic.openlab.cloudtest.common.exception.BaseException;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.CompatibilityFilesParser;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.CompatibilityTestResult;
+import com.huawei.ic.openlab.cloudtest.util.Constants;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.math.BigDecimal;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+/**
+ * ParseDiskPerFiles
+ *
+ * @author kongcaizhi
+ * @since 2021-12-15
+ */
+@Slf4j
+public class ParseDiskPerFiles implements CompatibilityFilesParser {
+ private static final String DRIVE_CN = "硬盘";
+ private static final String DRIVE_EN = "drive";
+
+ private final ParsePerformanceFilesImpl parsePerformanceFiles;
+
+ /**
+ * construction function
+ *
+ * @param inputByteMap MAP
+ */
+ public ParseDiskPerFiles(Map inputByteMap) {
+ this.parsePerformanceFiles = new ParsePerformanceFilesImpl(inputByteMap);
+ }
+
+ @Override
+ public CompatibilityTestResult getResult() throws IOException {
+ return parsePerformanceFiles.getResult(Constants.CompatibilityTestName.PRESSURE_DISK.getTestName(),
+ DRIVE_CN, DRIVE_EN, 2);
+ }
+
+ @Override
+ public CompatibilityTestResult parseFiles() {
+ CompatibilityTestResult testResult = new CompatibilityTestResult(
+ Constants.CompatibilityTestName.PRESSURE_DISK.getTestName());
+ try {
+ testResult = getResult();
+ } catch (BaseException ex) {
+ log.error("Missing pressure test disk file ", ex.getMessage());
+ testResult.setResult(Constants.TEST_SKIPPED);
+ testResult.setReason(String.format(Locale.ROOT, Constants.PERFORMANCE_DESC_LIST.get(3), DRIVE_CN));
+ testResult.setReasonEn(String.format(Locale.ROOT, Constants.PERFORMANCE_DESC_EN_LIST.get(3), DRIVE_EN));
+ } catch (NumberFormatException | IOException ex) {
+ log.error("Exception occur in parsing pressure test disk file ", ex);
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(String.format(Locale.ROOT, Constants.PERFORMANCE_DESC_LIST.get(2), DRIVE_CN));
+ testResult.setReasonEn(String.format(Locale.ROOT, Constants.PERFORMANCE_DESC_EN_LIST.get(2), DRIVE_EN));
+ }
+ return testResult;
+ }
+
+ private static class ParsePerformanceFilesImpl extends AbsParsePerformanceFiles {
+ private final Pattern idlePattern = Pattern.compile(
+ "\\d{2}(:|时)\\d{2}(:|分)\\d{2}(秒|\\s(PM|AM|HKT|))\\s+");
+
+ /**
+ * ParsePerformanceFilesImpl
+ *
+ * @param inputByteMap inputByteMap
+ */
+ public ParsePerformanceFilesImpl(Map inputByteMap) {
+ super(inputByteMap);
+ }
+
+ @Override
+ CompatibilityTestResult readFile(byte[] fileBytes) throws IOException {
+ if (fileBytes.length == 0) {
+ throw new BaseException("解析压力测试硬盘文件缺失");
+ }
+ CompatibilityTestResult testResult = new CompatibilityTestResult(
+ Constants.CompatibilityTestName.PRESSURE_DISK.getTestName());
+ Map>> idleMap = getIdleMap(fileBytes);
+ if (idleMap.size() > 0) {
+ Double maxGap = 0.00d;
+ String maxDiskName = null;
+ String diskMax = null;
+ String diskMin = null;
+ for (Map.Entry>> entry : idleMap.entrySet()) {
+ List idleList = entry.getValue().get("idle");
+ double diskMaxGap = idleList.stream().mapToDouble(Double::parseDouble).max().orElse(0.00d);
+ double diskMinGap = idleList.stream().mapToDouble(Double::parseDouble).min().orElse(0.00d);
+ Double gap = new BigDecimal(String.valueOf(diskMaxGap))
+ .subtract(new BigDecimal(String.valueOf(diskMinGap))).abs().doubleValue();
+ if (maxGap <= gap) {
+ maxGap = gap;
+ maxDiskName = entry.getKey();
+ diskMax = String.format(Locale.ROOT, "%.2f", diskMaxGap);
+ diskMin = String.format(Locale.ROOT, "%.2f", diskMinGap);
+ }
+ }
+ testResult = getTestResult(maxDiskName, maxGap, idleMap, diskMax, diskMin);
+ } else {
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(String.format(Locale.ROOT,
+ Constants.COMPATIBILITY_DESC_LIST.get(2), DRIVE_CN));
+ testResult.setReasonEn(String.format(Locale.ROOT,
+ Constants.PERFORMANCE_DESC_EN_LIST.get(2), DRIVE_EN));
+ }
+ return testResult;
+ }
+
+ private CompatibilityTestResult getTestResult(String maxDiskName, Double maxGap,
+ Map>> idleMap,
+ String diskMax, String diskMin) {
+ CompatibilityTestResult testResult = new CompatibilityTestResult(
+ Constants.CompatibilityTestName.PRESSURE_DISK.getTestName());
+ List evidenceList = idleMap.get(maxDiskName).get("evidence");
+ List evidence = new ArrayList<>();
+ evidence.add(evidenceList.stream().filter(
+ s -> StringUtils.containsIgnoreCase(s, diskMax)).limit(1)
+ .collect(Collectors.joining()));
+ evidence.add(evidenceList.stream().filter(
+ s -> StringUtils.containsIgnoreCase(s, diskMin)).limit(1)
+ .collect(Collectors.joining()));
+ List evidenceEn = new ArrayList<>(evidence);
+ if (maxGap <= 5.0) {
+ testResult.setResult(Constants.TEST_PASSED);
+ evidence.add(String.format(Locale.ROOT,
+ Constants.PERFORMANCE_DESC_LIST.get(0), DRIVE_CN, maxGap,
+ "小于"));
+ evidenceEn.add(String.format(Locale.ROOT,
+ Constants.PERFORMANCE_DESC_EN_LIST.get(0), DRIVE_EN, maxGap, "less"));
+ } else {
+ testResult.setResult(Constants.TEST_FAILED);
+ evidence.add(String.format(Locale.ROOT, Constants.PERFORMANCE_DESC_LIST.get(0),
+ DRIVE_CN, maxGap, "大于"));
+ evidenceEn.add(String.format(Locale.ROOT, Constants.PERFORMANCE_DESC_EN_LIST.get(0),
+ DRIVE_EN, maxGap, "greater"));
+ testResult.setReason(String.format(Locale.ROOT, Constants.PERFORMANCE_DESC_LIST.get(0),
+ DRIVE_CN, maxGap, "大于"));
+ testResult.setReasonEn(String.format(Locale.ROOT, Constants.PERFORMANCE_DESC_EN_LIST.get(0),
+ DRIVE_EN, maxGap, "greater"));
+ }
+ testResult.setEvidence(evidence);
+ testResult.setEvidenceEn(evidenceEn);
+ return testResult;
+ }
+
+ @Override
+ List getIdleList(byte[] fileBytes) {
+ return new ArrayList<>();
+ }
+
+ @Override
+ Map>> getIdleMap(byte[] fileBytes) throws IOException {
+ String line = null;
+ Map>> averageMap = new HashMap<>();
+ Map indexMap = new HashMap<>();
+ try (InputStream beginInput = new ByteArrayInputStream(fileBytes);
+ BufferedReader beginReader = new BufferedReader(new InputStreamReader(beginInput,
+ StandardCharsets.UTF_8))) {
+ boolean flag = true;
+
+ while ((line = beginReader.readLine()) != null) {
+ if (!StringUtils.containsIgnoreCase(line, "DEV") && idlePattern.matcher(line).find()) {
+ String[] split = line.split("\\s+");
+
+ String idle = split[indexMap.get("%util")];
+
+ String diskName = split[indexMap.get("DEV")];
+ Map> diskMap = averageMap.computeIfAbsent(diskName, e -> new HashMap<>());
+ diskMap.computeIfAbsent("idle", e -> new ArrayList<>()).add(idle);
+ diskMap.computeIfAbsent("evidence", e -> new ArrayList<>()).add(line);
+ } else if (flag && StringUtils.containsIgnoreCase(line, "DEV")) {
+ indexMap = getIndexMap(line);
+ flag = false;
+ }
+ }
+ }
+ return averageMap;
+ }
+
+ private Map getIndexMap(String line) {
+ Map indexMap = new HashMap<>();
+ String[] split = line.split("\\s+");
+ for (int i =0; i < split.length; i++) {
+ if (split[i].equals("DEV")) {
+ indexMap.put("DEV", i);
+ } else if (split[i].equals("%util")) {
+ indexMap.put("%util", i);
+ }
+ }
+ return indexMap;
+ }
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseMemComFiles.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseMemComFiles.java
new file mode 100644
index 0000000..aa500d3
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseMemComFiles.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.impl;
+
+import com.huawei.ic.openlab.cloudtest.common.exception.BaseException;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.CompatibilityFilesParser;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.CompatibilityTestResult;
+import com.huawei.ic.openlab.cloudtest.util.Constants;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.math.BigDecimal;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * ParseMemComFiles
+ *
+ * @author kongcaizhi
+ * @since 2021-12-15
+ */
+@Slf4j
+public class ParseMemComFiles implements CompatibilityFilesParser {
+ private static final String MEMORY_CN = "内存";
+ private static final String MEMORY_EN = "memory";
+ private static final Pattern PATTERN = Pattern.compile("\\d+\\.\\d+");
+
+ private final ParseCompatibilityFilesImpl parseCompatibilityFiles;
+
+ /**
+ * ParseMemComFiles
+ *
+ * @param beginMemByteMap beginMemByteMap
+ * @param endMemByteMap endMemByteMap
+ */
+ public ParseMemComFiles(Map beginMemByteMap, Map endMemByteMap) {
+ this.parseCompatibilityFiles = new ParseCompatibilityFilesImpl(beginMemByteMap, endMemByteMap);
+ }
+
+ @Override
+ public CompatibilityTestResult getResult() throws IOException {
+ return parseCompatibilityFiles.getResult(Constants.CompatibilityTestName.IDLE_MEM.getTestName(), MEMORY_CN,
+ MEMORY_EN, 3);
+ }
+
+ @Override
+ public CompatibilityTestResult parseFiles() {
+ CompatibilityTestResult testResult =
+ new CompatibilityTestResult(Constants.CompatibilityTestName.IDLE_MEM.getTestName());
+ try {
+ testResult = getResult();
+ } catch (BaseException ex) {
+ log.error("Missing idle test memory file ", ex.getMessage());
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_LIST.get(3), MEMORY_CN));
+ testResult.setReasonEn(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_EN_LIST.get(3), MEMORY_EN));
+ } catch (NumberFormatException | IOException ex) {
+ log.error("Exception occur in parsing idle test memory file ", ex);
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_LIST.get(2), MEMORY_CN));
+ testResult.setReasonEn(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_EN_LIST.get(2), MEMORY_EN));
+ }
+ return testResult;
+ }
+
+ private static class ParseCompatibilityFilesImpl extends AbsParseCompatibilityFiles {
+ /**
+ * ParseCompatibilityFilesImpl
+ *
+ * @param beginByteMap beginByteMap
+ * @param endByteMap endByteMap
+ */
+ protected ParseCompatibilityFilesImpl(Map beginByteMap, Map endByteMap) {
+ super(beginByteMap, endByteMap);
+ }
+
+ @Override
+ CompatibilityTestResult readFile(byte[] beginBytes, byte[] endBytes) throws IOException {
+ if (beginBytes.length == 0 || endBytes.length == 0) {
+ throw new BaseException("解析空载测试内存文件缺失");
+ }
+ CompatibilityTestResult testResult =
+ new CompatibilityTestResult(Constants.CompatibilityTestName.IDLE_MEM.getTestName());
+ List beginAverageList = getAverage(beginBytes);
+ List endAverageList = getAverage(endBytes);
+ double memMaxUsedIdle = 0.0d;
+ List evidence;
+ List evidenceEn;
+ if (beginAverageList.size() > 0 && endAverageList.size() > 0) {
+ memMaxUsedIdle = new BigDecimal(beginAverageList.get(0))
+ .subtract(new BigDecimal(endAverageList.get(0)))
+ .abs().doubleValue();
+ if (memMaxUsedIdle <= 1.0) {
+ testResult.setResult(Constants.TEST_PASSED);
+ evidence = Arrays.asList(beginAverageList.get(1), endAverageList.get(1),
+ String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_LIST.get(1), MEMORY_CN,
+ memMaxUsedIdle, "小于"));
+ evidenceEn = Arrays.asList(beginAverageList.get(1), endAverageList.get(1),
+ String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_EN_LIST.get(1), MEMORY_EN,
+ memMaxUsedIdle, "less"));
+ } else {
+ testResult.setResult(Constants.TEST_FAILED);
+ evidence = Arrays.asList(beginAverageList.get(1), endAverageList.get(1),
+ String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_LIST.get(1), MEMORY_CN,
+ memMaxUsedIdle, "大于"));
+ evidenceEn = Arrays.asList(beginAverageList.get(1), endAverageList.get(1),
+ String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_EN_LIST.get(1), MEMORY_EN,
+ memMaxUsedIdle, "greater"));
+ testResult.setReason(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_LIST.get(1),
+ MEMORY_CN, memMaxUsedIdle, "大于"));
+ testResult.setReasonEn(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_EN_LIST.get(1),
+ MEMORY_EN, memMaxUsedIdle, "greater"));
+ }
+ testResult.setEvidence(evidence);
+ testResult.setEvidenceEn(evidenceEn);
+ } else {
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_LIST.get(2), MEMORY_CN));
+ testResult.setReasonEn(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_EN_LIST.get(2),
+ MEMORY_EN));
+ }
+ return testResult;
+ }
+
+ @Override
+ List getAverage(byte[] fileBytes) {
+ try (InputStream beginInput = new ByteArrayInputStream(fileBytes);
+ BufferedReader br = new BufferedReader(
+ new InputStreamReader(beginInput, StandardCharsets.UTF_8))) {
+ String line;
+ List averageList = new ArrayList<>();
+ while ((line = br.readLine()) != null) {
+ average(line, averageList);
+ }
+ return averageList;
+ } catch (IOException e) {
+ throw new BaseException(e.getMessage());
+ }
+ }
+
+ private void average(String line, List averageList) {
+ if (StringUtils.containsIgnoreCase(line, "平均时间")
+ || StringUtils.startsWithIgnoreCase(line,
+ "Average")) {
+ Matcher matcher = PATTERN.matcher(line);
+ if (matcher.find()) {
+ averageList.add(matcher.group());
+ averageList.add(line.replace(System.lineSeparator(), ""));
+ }
+ }
+ }
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseMemPerFiles.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseMemPerFiles.java
new file mode 100644
index 0000000..d377d4e
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseMemPerFiles.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.impl;
+
+import com.huawei.ic.openlab.cloudtest.common.exception.BaseException;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.CompatibilityFilesParser;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.CompatibilityTestResult;
+import com.huawei.ic.openlab.cloudtest.util.Constants;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.math.BigDecimal;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * ParseMemPerFiles
+ *
+ * @author kongcaizhi
+ * @since 2021-12-15
+ */
+@Slf4j
+public class ParseMemPerFiles implements CompatibilityFilesParser {
+ private static final String MEMORY_CN = "内存";
+ private static final String MEMORY_EN = "memory";
+
+ private final ParsePerformanceFilesImpl parsePerformanceFiles;
+
+ /**
+ * construction file
+ *
+ * @param inputByteMap map
+ */
+ public ParseMemPerFiles(Map inputByteMap) {
+ this.parsePerformanceFiles = new ParsePerformanceFilesImpl(inputByteMap);
+ }
+
+ @Override
+ public CompatibilityTestResult getResult() throws IOException {
+ return parsePerformanceFiles.getResult(Constants.CompatibilityTestName.PRESSURE_MEM.getTestName(), MEMORY_CN,
+ MEMORY_EN, 2);
+ }
+
+ @Override
+ public CompatibilityTestResult parseFiles() {
+ CompatibilityTestResult testResult =
+ new CompatibilityTestResult(Constants.CompatibilityTestName.PRESSURE_MEM.getTestName());
+ try {
+ testResult = getResult();
+ } catch (BaseException ex) {
+ log.error("Missing pressure test memory file ", ex.getMessage());
+ testResult.setResult(Constants.TEST_SKIPPED);
+ testResult.setReason(String.format(Locale.ROOT, Constants.PERFORMANCE_DESC_LIST.get(3), MEMORY_CN));
+ testResult.setReasonEn(String.format(Locale.ROOT, Constants.PERFORMANCE_DESC_EN_LIST.get(3), MEMORY_EN));
+ } catch (NumberFormatException | IOException ex) {
+ log.error("Exception in parsing pressure test memory file ", ex);
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(String.format(Locale.ROOT, Constants.PERFORMANCE_DESC_LIST.get(2), MEMORY_CN));
+ testResult.setReasonEn(String.format(Locale.ROOT, Constants.PERFORMANCE_DESC_EN_LIST.get(2), MEMORY_EN));
+ }
+ return testResult;
+ }
+
+ private static class ParsePerformanceFilesImpl extends AbsParsePerformanceFiles {
+ private final Pattern idlePattern = Pattern.compile("\\d{2}(:|时)\\d{2}(:|分)\\d{2}(秒|\\s(PM|AM|HKT|))\\s+");
+ private final Pattern pattern = Pattern.compile("\\d+\\.\\d+");
+
+ /**
+ * inputByteMap
+ *
+ * @param inputByteMap inputByteMap
+ */
+ public ParsePerformanceFilesImpl(Map inputByteMap) {
+ super(inputByteMap);
+ }
+
+ @Override
+ CompatibilityTestResult readFile(byte[] fileBytes) throws IOException {
+ if (fileBytes.length == 0) {
+ throw new BaseException("解析压力测试硬盘文件缺失");
+ }
+ CompatibilityTestResult testResult = new CompatibilityTestResult(
+ Constants.CompatibilityTestName.PRESSURE_MEM.getTestName());
+ List idleList = getIdleList(fileBytes);
+ if (idleList.size() > 0) {
+ List evidence = new ArrayList<>(idleList.subList(1, idleList.size()));
+ List evidenceEn = new ArrayList<>(idleList.subList(1, idleList.size()));
+ if (Double.parseDouble(idleList.get(0)) <= 5.0d) {
+ testResult.setResult(Constants.TEST_PASSED);
+ evidence.add(String.format(Locale.ROOT,
+ Constants.PERFORMANCE_DESC_LIST.get(0), MEMORY_CN,
+ Double.parseDouble(idleList.get(0)), "小于"));
+ evidenceEn.add(String.format(Locale.ROOT,
+ Constants.PERFORMANCE_DESC_EN_LIST.get(0), MEMORY_EN,
+ Double.parseDouble(idleList.get(0)), "less"));
+ } else {
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(String.format(Locale.ROOT,
+ Constants.PERFORMANCE_DESC_LIST.get(0), MEMORY_CN,
+ Double.parseDouble(idleList.get(0)), "大于"));
+ testResult.setReasonEn(String.format(Locale.ROOT, Constants.PERFORMANCE_DESC_EN_LIST.get(0),
+ MEMORY_EN,
+ Double.parseDouble(idleList.get(0)), "greater"));
+ evidence.add(testResult.getReason());
+ evidenceEn.add(testResult.getReasonEn());
+ }
+ testResult.setEvidence(evidence);
+ testResult.setEvidenceEn(evidenceEn);
+ } else {
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(String.format(Locale.ROOT, Constants.PERFORMANCE_DESC_LIST.get(2), MEMORY_CN));
+ testResult.setReasonEn(String.format(Locale.ROOT, Constants.PERFORMANCE_DESC_EN_LIST.get(2),
+ MEMORY_EN));
+ }
+ return testResult;
+ }
+
+ @Override
+ List getIdleList(byte[] fileBytes) throws IOException {
+ Double maxIdle = 0.0d;
+ String maxEvidence = null;
+ Double minIdle = 100.0d;
+ String minEvidence = null;
+ try (InputStream beginInput = new ByteArrayInputStream(fileBytes);
+ BufferedReader beginReader = new BufferedReader(
+ new InputStreamReader(beginInput, StandardCharsets.UTF_8))) {
+ String line;
+ while ((line = beginReader.readLine()) != null) {
+ Matcher matcher = pattern.matcher(line);
+ if (!StringUtils.containsAnyIgnoreCase(line, "kbmemfree")
+ && idlePattern.matcher(line).find() && matcher.find()) {
+ Double idleDouble = Double.parseDouble(matcher.group().trim());
+ maxEvidence = maxIdle <= idleDouble ? line : maxEvidence;
+ maxIdle = Math.max(idleDouble, maxIdle);
+ minIdle = Math.min(idleDouble, minIdle);
+ minEvidence = minIdle >= idleDouble ? line : minEvidence;
+ }
+ }
+ }
+
+ List idleList = new ArrayList<>();
+ if (maxEvidence != null) {
+ idleList.add(String.format(Locale.ROOT, "%.2f", new BigDecimal(String.valueOf(maxIdle))
+ .subtract(new BigDecimal(String.valueOf(maxIdle))).abs().doubleValue()));
+ idleList.add(maxEvidence);
+ idleList.add(minEvidence);
+ }
+ return idleList;
+ }
+
+ @Override
+ Map>> getIdleMap(byte[] fileBytes) {
+ return new HashMap<>();
+ }
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseNetComFiles.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseNetComFiles.java
new file mode 100644
index 0000000..cb09b8f
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseNetComFiles.java
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.impl;
+
+import com.huawei.ic.openlab.cloudtest.common.exception.BaseException;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.CompatibilityFilesParser;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.CompatibilityTestResult;
+import com.huawei.ic.openlab.cloudtest.util.Constants;
+
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.math.BigDecimal;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * ParseNetComFiles
+ *
+ * @author kongcaizhi
+ * @since 2021-12-15
+ */
+@Slf4j
+public class ParseNetComFiles implements CompatibilityFilesParser {
+ private static final String NIC_CN = "网卡";
+ private static final String NIC_EN = "NIC";
+
+ private final ParseCompatibilityFilesImpl parseCompatibilityFiles;
+
+ /**
+ * construction function
+ *
+ * @param beginNetByteMap beginNetByteMap
+ * @param endNetByteMap endNetByteMap
+ */
+ public ParseNetComFiles(Map beginNetByteMap, Map endNetByteMap) {
+ this.parseCompatibilityFiles = new ParseCompatibilityFilesImpl(beginNetByteMap, endNetByteMap);
+ }
+
+ @Override
+ public CompatibilityTestResult getResult() throws IOException {
+ return parseCompatibilityFiles.getResult(Constants.CompatibilityTestName.IDLE_NET.getTestName(),
+ NIC_CN, NIC_EN, 2);
+ }
+
+ @Override
+ public CompatibilityTestResult parseFiles() {
+ CompatibilityTestResult testResult = new CompatibilityTestResult(
+ Constants.CompatibilityTestName.IDLE_NET.getTestName());
+ try {
+ testResult = getResult();
+ } catch (BaseException ex) {
+ log.error("Missing idle test net file ", ex.getMessage());
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_LIST.get(3), NIC_CN));
+ testResult.setReasonEn(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_EN_LIST.get(3), NIC_EN));
+ } catch (NumberFormatException | IOException ex) {
+ log.error("Exception in parsing idle test net file ", ex);
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_LIST.get(2), NIC_CN));
+ testResult.setReasonEn(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_EN_LIST.get(2), NIC_EN));
+ }
+ return testResult;
+ }
+
+ private static class ParseCompatibilityFilesImpl extends AbsParseCompatibilityFiles {
+ private final Pattern averagePattern = Pattern.compile("(平均时间|Average):\\s*(?!IFACE|lo)\\w.*");
+ private final Pattern pattern = Pattern.compile("\\d+\\.\\d+");
+
+ /**
+ * ParseCompatibilityFilesImpl
+ *
+ * @param beginByteMap beginByteMap
+ * @param endByteMap endByteMap
+ */
+ protected ParseCompatibilityFilesImpl(Map beginByteMap, Map endByteMap) {
+ super(beginByteMap, endByteMap);
+ }
+
+ @Override
+ CompatibilityTestResult readFile(byte[] beginBytes, byte[] endBytes) throws IOException {
+ if (beginBytes.length == 0 || endBytes.length == 0) {
+ throw new BaseException("解析空载测试网卡文件缺失");
+ }
+ CompatibilityTestResult testResult = new CompatibilityTestResult(
+ Constants.CompatibilityTestName.IDLE_NET.getTestName());
+ Map> beginAverageMap = getAverageMap(beginBytes);
+ Map> endAverageMap = getAverageMap(endBytes);
+
+ if (beginAverageMap.size() > 0 && endAverageMap.size() > 0) {
+ createTestResult(testResult, beginAverageMap, endAverageMap);
+ } else {
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(String.format(Locale.ROOT,
+ Constants.COMPATIBILITY_DESC_LIST.get(2), NIC_CN));
+ testResult.setReasonEn(String.format(Locale.ROOT,
+ Constants.COMPATIBILITY_DESC_EN_LIST.get(2), NIC_EN));
+ }
+ return testResult;
+ }
+
+ private void createTestResult(CompatibilityTestResult testResult, Map> beginAverageMap,
+ Map> endAverageMap) {
+ Double rxkbIdle;
+ Double txkbIdle;
+ Double maxRxkbIdle = 0.0d;
+ Double maxTxkbIdle = 0.0d;
+ String rxkbNetName = null;
+ String txkbNetName = null;
+ BigDecimal num = new BigDecimal(8).divide(new BigDecimal(1000 * 1024));
+ for (Map.Entry> entry : beginAverageMap.entrySet()) {
+ if (!endAverageMap.containsKey(entry.getKey())) {
+ continue;
+ }
+ rxkbIdle = new BigDecimal(beginAverageMap.get(entry.getKey()).get(0))
+ .subtract(new BigDecimal(endAverageMap.get(entry.getKey()).get(0)))
+ .abs().multiply(num).doubleValue();
+ txkbIdle = new BigDecimal(beginAverageMap.get(entry.getKey()).get(1))
+ .subtract(new BigDecimal(endAverageMap.get(entry.getKey()).get(1)))
+ .abs().multiply(num).doubleValue();
+ if (rxkbIdle >= maxRxkbIdle) {
+ maxRxkbIdle = rxkbIdle;
+ rxkbNetName = entry.getKey();
+ }
+ if (txkbIdle >= maxTxkbIdle) {
+ maxTxkbIdle = txkbIdle;
+ txkbNetName = entry.getKey();
+ }
+ }
+ List evidence = new ArrayList<>();
+ evidence.add(beginAverageMap.get(rxkbNetName).get(2));
+ evidence.add(endAverageMap.get(rxkbNetName).get(2));
+ List evidenceEn = new ArrayList<>(evidence);
+
+ int[] kbpass = {0, 0};
+ checkMaxRxkbIdle(maxRxkbIdle, kbpass, evidence, evidenceEn);
+ evidence.add(beginAverageMap.get(txkbNetName).get(2));
+ evidence.add(endAverageMap.get(txkbNetName).get(2));
+ evidenceEn.add(beginAverageMap.get(txkbNetName).get(2));
+ evidenceEn.add(endAverageMap.get(txkbNetName).get(2));
+ checkMaxTxkbIdle(maxTxkbIdle, kbpass, evidence, evidenceEn);
+
+ testResult.setEvidence(evidence);
+ testResult.setEvidenceEn(evidenceEn);
+ setTestResult(maxRxkbIdle, maxTxkbIdle, kbpass, testResult);
+ }
+
+ private void checkMaxRxkbIdle(Double maxRxkbIdle, int[] kbpass, List evidence,
+ List evidenceEn) {
+ Double maxRxkb = new BigDecimal(maxRxkbIdle.toString()).multiply(new BigDecimal(100)).doubleValue();
+ if (maxRxkbIdle <= 0.01) {
+ kbpass[0] = 1;
+ evidence.add(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_LIST.get(6),
+ "接收", maxRxkb, "小于"));
+ evidenceEn.add(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_EN_LIST.get(6),
+ "received", maxRxkb, "less"));
+ } else {
+ evidence.add(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_LIST.get(6),
+ "接收", maxRxkb, "大于"));
+ evidenceEn.add(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_EN_LIST.get(6),
+ "received", maxRxkb, "greater"));
+ }
+ }
+
+ private void checkMaxTxkbIdle(Double maxTxkbIdle, int[] kbpass, List evidence,
+ List evidenceEn) {
+ Double maxTxkb = new BigDecimal(maxTxkbIdle.toString()).multiply(new BigDecimal(100)).doubleValue();
+ if (maxTxkbIdle < 0.01) {
+ kbpass[1] = 1;
+ evidence.add(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_LIST.get(6), "发送",
+ maxTxkb, "小于"));
+ evidenceEn.add(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_EN_LIST.get(6), "sent",
+ maxTxkb, "less"));
+ } else {
+ evidence.add(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_LIST.get(6), "发送",
+ maxTxkb, "大于"));
+ evidenceEn.add(String.format(Locale.ROOT, Constants.COMPATIBILITY_DESC_EN_LIST.get(6), "sent",
+ maxTxkb, "greater"));
+ }
+ }
+
+ private void setTestResult(Double maxRxkbIdle, Double maxTxkbIdle, int[] kbpass,
+ CompatibilityTestResult testResult) {
+ if (kbpass[0] == 1 && kbpass[1] == 1) {
+ testResult.setResult(Constants.TEST_PASSED);
+ } else {
+ double maxRxkb = new BigDecimal(maxRxkbIdle.toString()).multiply(new BigDecimal(100)).doubleValue();
+ double maxTxkb = new BigDecimal(maxTxkbIdle.toString()).multiply(new BigDecimal(100)).doubleValue();
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(String.format(Locale.ROOT,
+ Constants.COMPATIBILITY_DESC_LIST.get(7), "发送",
+ maxTxkb) + String.format(Locale.ROOT,
+ Constants.COMPATIBILITY_DESC_LIST.get(7), "接收",
+ maxRxkb));
+ testResult.setReasonEn(String.format(Locale.ROOT,
+ Constants.COMPATIBILITY_DESC_EN_LIST.get(7),
+ "sent", maxTxkb) + String.format(Locale.ROOT,
+ Constants.COMPATIBILITY_DESC_LIST.get(7), "received",
+ maxRxkb));
+ }
+ }
+
+ @Override
+ List getAverage(byte[] fileBytes) {
+ return new ArrayList<>();
+ }
+
+ /**
+ * get Average Map
+ *
+ * @param fileBytes fileBytes
+ * @return Map
+ * @throws IOException IOException
+ */
+ public Map> getAverageMap(byte[] fileBytes) throws IOException {
+ Map> averageMap = new HashMap<>();
+ try (InputStream beginInput = new ByteArrayInputStream(fileBytes);
+ BufferedReader beginReader = new BufferedReader(
+ new InputStreamReader(beginInput, StandardCharsets.UTF_8))) {
+ String line;
+
+ while ((line = beginReader.readLine()) != null) {
+ if (!averagePattern.matcher(line).find()) {
+ continue;
+ }
+ Matcher matcher = pattern.matcher(line);
+ String netName = line.substring(13).trim().split(" ")[0];
+ List matchList = new ArrayList<>();
+ while (matcher.find()) {
+ matchList.add(matcher.group().trim());
+ }
+ averageMap.put(netName, Arrays.asList(matchList.get(2), matchList.get(3), line));
+ }
+ }
+ return averageMap;
+ }
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseNetPerFiles.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseNetPerFiles.java
new file mode 100644
index 0000000..6120491
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseNetPerFiles.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.impl;
+
+import com.huawei.ic.openlab.cloudtest.common.exception.BaseException;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.CompatibilityFilesParser;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.CompatibilityTestResult;
+import com.huawei.ic.openlab.cloudtest.util.Constants;
+
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.math.BigDecimal;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+/**
+ * ParseNetPerFiles
+ *
+ * @author kongcaizhi
+ * @since 2021-12-15
+ */
+@Slf4j
+public class ParseNetPerFiles implements CompatibilityFilesParser {
+ private static final String NIC_CN = "网卡";
+ private static final String NIC_EN = "NIC";
+
+ private final ParsePerformanceFilesImpl parsePerformanceFiles;
+
+ /**
+ * construction function
+ *
+ * @param inputByteMap map
+ */
+ public ParseNetPerFiles(Map inputByteMap) {
+ this.parsePerformanceFiles = new ParsePerformanceFilesImpl(inputByteMap);
+ }
+
+ @Override
+ public CompatibilityTestResult getResult() throws IOException {
+ return parsePerformanceFiles.getResult(Constants.CompatibilityTestName.PRESSURE_NET.getTestName(), NIC_CN,
+ NIC_EN, 2);
+ }
+
+ @Override
+ public CompatibilityTestResult parseFiles() throws IOException {
+ CompatibilityTestResult testResult =
+ new CompatibilityTestResult(Constants.CompatibilityTestName.PRESSURE_NET.getTestName());
+ try {
+ testResult = getResult();
+ } catch (BaseException ex) {
+ log.error("Missing pressure test net file ", ex.getMessage());
+ testResult.setResult(Constants.TEST_SKIPPED);
+ testResult.setReason(String.format(Locale.ROOT, Constants.PERFORMANCE_DESC_LIST.get(3), NIC_CN));
+ testResult.setReasonEn(String.format(Locale.ROOT, Constants.PERFORMANCE_DESC_EN_LIST.get(3), NIC_EN));
+ } catch (NumberFormatException | IOException ex) {
+ log.error("Exception in parsing idle test net file ", ex);
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(String.format(Locale.ROOT, Constants.PERFORMANCE_DESC_LIST.get(2), NIC_CN));
+ testResult.setReasonEn(String.format(Locale.ROOT, Constants.PERFORMANCE_DESC_EN_LIST.get(2), NIC_EN));
+ }
+ return testResult;
+ }
+
+ @Data
+ private static class XxkbRate {
+ double maxXxkbRate = 0.00d;
+ String maxXxkbDiskName = null;
+ String netXxkbMax = null;
+ String netXxkbMin = null;
+ double netXxkbRate = 0.0d;
+ }
+
+ private static class ParsePerformanceFilesImpl extends AbsParsePerformanceFiles {
+ private final Pattern idlePattern = Pattern.compile("\\d{2}(:|时)\\d{2}(:|分)\\d{2}(秒|\\s(PM|AM|HKT|))\\s+");
+ private final Pattern pattern = Pattern.compile("\\d+\\.\\d+");
+
+ public ParsePerformanceFilesImpl(Map inputByteMap) {
+ super(inputByteMap);
+ }
+
+ @Override
+ CompatibilityTestResult readFile(byte[] fileBytes) throws IOException {
+ if (fileBytes.length == 0) {
+ throw new BaseException("解析压力测试硬盘文件缺失");
+ }
+ CompatibilityTestResult testResult =
+ new CompatibilityTestResult(Constants.CompatibilityTestName.PRESSURE_NET.getTestName());
+ Map>> netIdleMap = getIdleMap(fileBytes);
+ if (netIdleMap.size() > 0) {
+ XxkbRate rxkbRate = new XxkbRate();
+ XxkbRate txkbRate = new XxkbRate();
+ for (Map.Entry>> entry : netIdleMap.entrySet()) {
+ if (entry.getValue().get("rxkb").size() < 4 || entry.getValue().get("txkb").size() < 4) {
+ continue;
+ }
+
+ List rxkbDoubleList = entry.getValue().get("rxkb").stream()
+ .map(Double::parseDouble).collect(Collectors.toList());
+ calculateXxkbRate(rxkbDoubleList, entry.getKey(), rxkbRate);
+
+ List txkbDoubleList = entry.getValue().get("txkb")
+ .stream().map(Double::parseDouble).collect(Collectors.toList());
+
+ calculateXxkbRate(txkbDoubleList, entry.getKey(), txkbRate);
+ }
+ testResult = getTestCaseResult(rxkbRate, txkbRate, netIdleMap);
+ } else {
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(String.format(Locale.ROOT, Constants.PERFORMANCE_DESC_LIST.get(2), NIC_CN));
+ testResult.setReasonEn(String.format(Locale.ROOT, Constants.PERFORMANCE_DESC_EN_LIST.get(2), NIC_EN));
+ }
+ return testResult;
+ }
+
+ private void calculateXxkbRate(List rxkbDoubleList, String key, XxkbRate rate) {
+ Double maxRxkb = Collections.max(rxkbDoubleList);
+ rxkbDoubleList.remove(maxRxkb);
+ Double minRxkb = Collections.min(rxkbDoubleList);
+ rxkbDoubleList.remove(minRxkb);
+ double rxkbAvg = rxkbDoubleList.stream().mapToDouble(Double::valueOf).average().orElse(0.00);
+ if (Math.round(rxkbAvg) > 0) {
+ BigDecimal num = new BigDecimal(8).divide(new BigDecimal(1000 * 1024));
+ rate.setNetXxkbRate(BigDecimal.valueOf(Collections.max(rxkbDoubleList))
+ .subtract(new BigDecimal(String.valueOf(rxkbAvg))).abs().multiply(num).doubleValue());
+ } else {
+ rate.setNetXxkbRate(0.0);
+ }
+ if (rate.getMaxXxkbRate() <= rate.getNetXxkbRate()) {
+ rate.setMaxXxkbDiskName(key);
+ rate.setMaxXxkbRate(rate.getNetXxkbRate());
+ rate.setNetXxkbMax(String.format(Locale.ROOT, "%.2f", Collections.max(rxkbDoubleList)));
+ rate.setNetXxkbMin(String.format(Locale.ROOT, "%.2f", Collections.min(rxkbDoubleList)));
+ }
+ }
+
+ private CompatibilityTestResult getTestCaseResult(XxkbRate rxkb, XxkbRate txkb,
+ Map>> netIdleMap) {
+ int[] kbPass = {0, 0};
+ if (rxkb.getMaxXxkbRate() <= 0.05) {
+ kbPass[0] = 1;
+ }
+ if (txkb.getMaxXxkbRate() <= 0.05) {
+ kbPass[1] = 1;
+ }
+
+ List evidence = evidenceInit(rxkb, txkb, netIdleMap);
+ List evidenceEn = new ArrayList<>(evidence);
+ Double maxRxkb = new BigDecimal(String.valueOf(rxkb.getMaxXxkbRate()))
+ .multiply(new BigDecimal(100)).doubleValue();
+ Double maxTxkb = new BigDecimal(String.valueOf(txkb.getMaxXxkbRate()))
+ .multiply(new BigDecimal(100)).doubleValue();
+ CompatibilityTestResult testResult =
+ new CompatibilityTestResult(Constants.CompatibilityTestName.PRESSURE_NET.getTestName());
+ if (kbPass[0] == 1 && kbPass[1] == 1) {
+ testResult.setResult(Constants.TEST_PASSED);
+ evidence.add(String.format(Locale.ROOT, Constants.PERFORMANCE_DESC_LIST.get(4), "接收",
+ maxRxkb) + String.format(Locale.ROOT,
+ Constants.PERFORMANCE_DESC_LIST.get(5), "发送",
+ maxTxkb, "小于"));
+ evidenceEn.add(String.format(Locale.ROOT,
+ Constants.PERFORMANCE_DESC_EN_LIST.get(4), "received",
+ maxRxkb) + String.format(Locale.ROOT,
+ Constants.PERFORMANCE_DESC_EN_LIST.get(5), "sent",
+ maxTxkb, "less"));
+ } else {
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(String.format(Locale.ROOT,
+ Constants.PERFORMANCE_DESC_LIST.get(4), "接收",
+ maxRxkb) + String.format(Locale.ROOT,
+ Constants.PERFORMANCE_DESC_LIST.get(5), "发送",
+ maxTxkb, "大于"));
+ testResult.setReasonEn(String.format(Locale.ROOT, Constants.PERFORMANCE_DESC_EN_LIST.get(4),
+ "received", maxRxkb) + String.format(Locale.ROOT,
+ Constants.PERFORMANCE_DESC_EN_LIST.get(5), "sent",
+ maxTxkb, "greater"));
+ evidence.add(testResult.getResult());
+ evidenceEn.add(testResult.getReasonEn());
+ }
+ testResult.setEvidence(evidence);
+ testResult.setEvidenceEn(evidenceEn);
+ return testResult;
+ }
+
+ private List evidenceInit(XxkbRate rxkb, XxkbRate txkb,
+ Map>> netIdleMap) {
+ List rxkbEvidenceList = netIdleMap.get(rxkb.getMaxXxkbDiskName()).get("evidence");
+ List txkbEvidenceList = netIdleMap.get(txkb.getMaxXxkbDiskName()).get("evidence");
+
+ List evidence = new ArrayList<>();
+ String finalNetRxkbMax = rxkb.getNetXxkbMax();
+ evidence.add(rxkbEvidenceList.stream().filter(s -> StringUtils.containsIgnoreCase(s, finalNetRxkbMax))
+ .limit(1).collect(Collectors.joining()));
+ String finalNetRxkbMin = rxkb.getNetXxkbMin();
+ evidence.add(rxkbEvidenceList.stream().filter(s -> StringUtils.containsIgnoreCase(s, finalNetRxkbMin))
+ .limit(1).collect(Collectors.joining()));
+ String finalNetTxkbMax = txkb.getNetXxkbMax();
+ evidence.add(txkbEvidenceList.stream().filter(s -> StringUtils.containsIgnoreCase(s, finalNetTxkbMax))
+ .limit(1).collect(Collectors.joining()));
+ String finalNetTxkbMin = txkb.getNetXxkbMin();
+ evidence.add(txkbEvidenceList.stream().filter(s -> StringUtils.containsIgnoreCase(s, finalNetTxkbMin))
+ .limit(1).collect(Collectors.joining()));
+ return evidence;
+ }
+
+ @Override
+ List getIdleList(byte[] fileBytes) throws IOException {
+ return new ArrayList<>();
+ }
+
+ @Override
+ Map>> getIdleMap(byte[] fileBytes) throws IOException {
+ Map>> averageMap = new HashMap<>();
+ try (InputStream beginInput = new ByteArrayInputStream(fileBytes);
+ BufferedReader beginReader = new BufferedReader(
+ new InputStreamReader(beginInput, StandardCharsets.UTF_8))) {
+ String line;
+
+ while ((line = beginReader.readLine()) != null
+ && !StringUtils.containsIgnoreCase(line, "IFACE")
+ && !StringUtils.containsIgnoreCase(line, "lo")
+ && idlePattern.matcher(line).find()) {
+ Matcher matcher = pattern.matcher(line);
+ String netName = line.substring(13).trim().split(" ")[0];
+ List matchList = new ArrayList<>();
+ while (matcher.find()) {
+ matchList.add(matcher.group().trim());
+ }
+ Map> netMap = averageMap.getOrDefault(netName, new HashMap<>());
+ List rxkbList = netMap.getOrDefault("rxkb", new ArrayList<>());
+ rxkbList.add(matchList.get(2));
+ List txkbList = netMap.getOrDefault("txkb", new ArrayList<>());
+ txkbList.add(matchList.get(3));
+ List evidenceList = netMap.getOrDefault("evidence", new ArrayList<>());
+ evidenceList.add(line);
+ netMap.put("rxkb", rxkbList);
+ netMap.put("txkb", txkbList);
+ netMap.put("evidence", evidenceList);
+ averageMap.put(netName, netMap);
+ }
+ }
+ return averageMap;
+ }
+ }
+}
\ No newline at end of file
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseSoftwareLog.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseSoftwareLog.java
new file mode 100644
index 0000000..75c35cb
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/entity/compatibilityfileanalysis/impl/ParseSoftwareLog.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.impl;
+
+import com.huawei.ic.openlab.cloudtest.common.exception.BaseException;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.CompatibilityFilesParser;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.CompatibilityTestResult;
+import com.huawei.ic.openlab.cloudtest.util.Constants;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * ParseNetPerFiles
+ *
+ * @author kongcaizhi
+ * @since 2021-12-15
+ */
+@Slf4j
+public class ParseSoftwareLog implements CompatibilityFilesParser {
+ private final byte[] configBytes;
+ private final byte[] productNameBytes;
+
+ /**
+ * construction function
+ *
+ * @param configBytes config bytes
+ * @param productNameBytes product name bytes
+ */
+ public ParseSoftwareLog(byte[] configBytes, byte[] productNameBytes) {
+ this.configBytes = configBytes;
+ this.productNameBytes = productNameBytes;
+ }
+
+ private Map> parseConfig() {
+ Map> configMap = new HashMap<>();
+ if (configBytes.length == 0) {
+ return configMap;
+ }
+
+ String line;
+ Pattern appPattern = Pattern.compile(Constants.APPLICATION_NAMES);
+ Pattern startPattern = Pattern.compile(Constants.START_APP_COMMANDS);
+ Pattern stopPattern = Pattern.compile(Constants.STOP_APP_COMMANDS);
+ try (InputStream input = new ByteArrayInputStream(configBytes);
+ BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8))) {
+ while ((line = reader.readLine()) != null) {
+ Matcher appMatcher = appPattern.matcher(line);
+ if (appMatcher.find()) {
+ List applicationNamesList = Arrays.asList(appMatcher.group(1).split(","));
+ configMap.put("applicationNames", applicationNamesList);
+ }
+
+ Matcher startMatcher = startPattern.matcher(line);
+ if (startMatcher.find()) {
+ List startAppCommandsList = Arrays.asList(startMatcher.group(1).split(","));
+ configMap.put("startAppCommands", startAppCommandsList);
+ }
+
+ Matcher stopMatcher = stopPattern.matcher(line);
+ if (stopMatcher.find()) {
+ List stopAppCommandsList = Arrays.asList(stopMatcher.group(1).split(","));
+ configMap.put("stopAppCommands", stopAppCommandsList);
+ }
+ }
+ } catch (IllegalStateException | IOException ex) {
+ log.error("Error reading configuration file for compatibility testing tool", ex);
+ }
+ return configMap;
+ }
+
+ @Override
+ public CompatibilityTestResult getResult() throws IOException {
+ CompatibilityTestResult testResult = new CompatibilityTestResult(
+ Constants.CompatibilityTestName.SOFTWARE_NAME.getTestName());
+ if (this.productNameBytes.length == 0) {
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(Constants.SOFTWARE_COMPARE_DESC_LIST.get(3));
+ return testResult;
+ }
+ Map> configMap = parseConfig();
+ if (configMap.size() == 0 || configMap.get("applicationNames").size() == 0) {
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(Constants.SOFTWARE_COMPARE_DESC_LIST.get(2));
+ } else {
+ testResult.setApplicationNames(configMap.get("applicationNames"));
+ testResult.setStartAppCommands(configMap.get("startAppCommands"));
+ testResult.setStopAppCommands(configMap.get("stopAppCommands"));
+ }
+
+ getApplicationNames(configMap, testResult, this.productNameBytes);
+ return testResult;
+ }
+
+ private void getApplicationNames(Map> configMap, CompatibilityTestResult testResult,
+ byte[] productNameBytes) {
+ try (InputStream inputStream = new ByteArrayInputStream(productNameBytes);
+ BufferedReader reader = new BufferedReader(
+ new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
+ String line;
+ Map appCountMap = new HashMap<>();
+ while ((line = reader.readLine()) != null) {
+ getApplicationName(line, configMap, testResult, appCountMap);
+ }
+ for (Map.Entry entry : appCountMap.entrySet()) {
+ if (appCountMap.get(entry.getKey()) == 0) {
+ testResult.setResult(Constants.TEST_FAILED);
+ List evidenceList = testResult.getEvidence();
+ evidenceList.add(String.format(Locale.ROOT,
+ Constants.SOFTWARE_COMPARE_DESC_LIST.get(0), entry.getKey()));
+ testResult.setEvidence(evidenceList);
+ evidenceList = testResult.getEvidenceEn();
+ evidenceList.add(String.format(Locale.ROOT,
+ Constants.SOFTWARE_COMPARE_DESC_EN_LIST.get(0), entry.getKey()));
+ testResult.setEvidenceEn(evidenceList);
+ }
+ }
+ if (Constants.TEST_FAILED.equals(testResult.getResult())) {
+ testResult.setReason(String.format(Locale.ROOT,
+ Constants.SOFTWARE_COMPARE_DESC_LIST.get(1), configMap.get("applicationNames").toString()));
+ testResult.setReasonEn(String.format(Locale.ROOT,
+ Constants.SOFTWARE_COMPARE_DESC_EN_LIST.get(1), configMap.get("applicationNames").toString()));
+ } else {
+ testResult.setResult(Constants.TEST_PASSED);
+ }
+ } catch (IOException e) {
+ throw new BaseException(e.getMessage());
+ }
+ }
+
+ private void getApplicationName(String line, Map> configMap,
+ CompatibilityTestResult testResult, Map appCountMap) {
+ int userLength = line.split(" ")[0].length();
+ String lineSplit = line.substring(userLength);
+
+ for (String app : configMap.get("applicationNames")) {
+ if (StringUtils.startsWithIgnoreCase(lineSplit, app)) {
+ appCountMap.put(app, appCountMap.getOrDefault(app, 0) + 1);
+ List evidenceList = testResult.getEvidence() == null ? new ArrayList<>()
+ : testResult.getEvidence();
+ evidenceList.add(line.replace(System.lineSeparator(), ""));
+ testResult.setEvidence(evidenceList);
+ testResult.setEvidenceEn(evidenceList);
+ }
+ }
+ }
+
+ @Override
+ public CompatibilityTestResult parseFiles() {
+ CompatibilityTestResult testResult = new CompatibilityTestResult(
+ Constants.CompatibilityTestName.SOFTWARE_NAME.getTestName());
+ try {
+ testResult = getResult();
+ } catch (IllegalStateException | IOException ex) {
+ log.error("Error parsing configuration file and software process stack information of compatibility "
+ + "testing tool", ex);
+ testResult.setResult(Constants.TEST_FAILED);
+ testResult.setReason(Constants.SOFTWARE_COMPARE_DESC_LIST.get(4));
+ testResult.setReasonEn(Constants.SOFTWARE_COMPARE_DESC_EN_LIST.get(4));
+ }
+ return testResult;
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/service/DevkitService.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/service/DevkitService.java
new file mode 100644
index 0000000..51ef42d
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/service/DevkitService.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.service;
+
+import com.huawei.ic.openlab.cloudtest.entity.SystemParams;
+import com.huawei.ic.openlab.cloudtest.util.ApiCenterUtil;
+import com.huawei.ic.openlab.cloudtest.util.DgCodeServerClient;
+import com.huawei.ic.openlab.cloudtest.util.TeeCodeServerClient;
+
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import java.util.concurrent.TimeUnit;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * devkit环境申请service
+ *
+ * @author kongcaizhi
+ * @since 2022-10-19
+ */
+@Slf4j
+public class DevkitService {
+ private final TeeCodeServerClient client;
+ private final DgCodeServerClient dgCodeServerClient;
+ private final SystemParams systemParams;
+
+ @Autowired
+ private RedisTemplate redisTemplate;
+
+ /**
+ * construction function
+ *
+ * @param client client
+ * @param dgCodeServerClient dgCodeServer client
+ * @param systemParams system parameter
+ */
+ public DevkitService(TeeCodeServerClient client, DgCodeServerClient dgCodeServerClient,
+ SystemParams systemParams) {
+ this.client = client;
+ this.dgCodeServerClient = dgCodeServerClient;
+ this.systemParams = systemParams;
+ }
+
+ /**
+ * 往redis 增加 device-id
+ *
+ * @param server 服务器信息
+ */
+ public void addTaskDeviceId(DevkitServer server) {
+ client.addTaskDeviceId(server.getTaskDeviceId(), server.getInternalIp());
+ dgCodeServerClient.addTaskDeviceId(server.getTaskDeviceId(), server.getInternalIp());
+ if (Boolean.TRUE.equals(redisTemplate.hasKey(server.getTaskDeviceId()))) {
+ redisTemplate.opsForValue().setIfAbsent(server.getTaskDeviceId(), server.getInternalIp());
+ } else {
+ redisTemplate.opsForValue().append(server.getTaskDeviceId(), server.getInternalIp());
+ }
+ }
+
+ /**
+ * 往redis 删除device-id
+ *
+ * @param taskDeviceId device-id
+ * @return boolean
+ */
+ public boolean deleteTaskDeviceId(String taskDeviceId) {
+ client.deleteTaskDeviceId(taskDeviceId);
+ dgCodeServerClient.deleteTaskDeviceId(taskDeviceId);
+ return Boolean.TRUE.equals(redisTemplate.delete(taskDeviceId));
+ }
+
+ /**
+ * 向API网关验证token是否有效
+ *
+ * @return validate
+ */
+ public boolean validateToken() {
+ RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
+ HttpServletRequest request = requestAttributes instanceof ServletRequestAttributes
+ ? ((ServletRequestAttributes) requestAttributes).getRequest() : null;
+
+ if (request == null) {
+ return false;
+ }
+
+ String token = request.getHeader("KP-TOKEN");
+ String taskDeviceId = request.getHeader("TASK-DEVICE-ID");
+
+ if (StringUtils.isEmpty(token)) {
+ log.error("token is empty");
+ return false;
+ }
+
+ if (StringUtils.isEmpty(taskDeviceId)) {
+ log.error("taskDeviceId is empty");
+ return false;
+ }
+ return validateToken(token, taskDeviceId);
+ }
+
+ /**
+ * 检查redis是否有token, 如果有,返回为真,如果没有请求apigw判断.如果apigw返回为真,则保存在redis中,设置超时时间为1分钟.
+ *
+ * @param token token
+ * @param taskDeviceId taskDeviceId
+ * @return true|false
+ */
+ private boolean validateToken(String token, String taskDeviceId) {
+ String key = token + "-" + taskDeviceId;
+
+ if (Boolean.TRUE.equals(redisTemplate.hasKey(key))) {
+ return true;
+ } else {
+ boolean isValidated = ApiCenterUtil.validateToken(systemParams, token, taskDeviceId);
+ if (isValidated) {
+ redisTemplate.opsForValue().set(key, "token", 5, TimeUnit.MINUTES);
+ log.info("Add token to redis return{}",
+ redisTemplate.expire(key, 5, TimeUnit.MINUTES));
+ }
+ return isValidated;
+ }
+ }
+
+ /**
+ * DevkitServer
+ *
+ * @author kongcaizhi
+ * @since 2022-10-19
+ */
+ @Data
+ public static class DevkitServer {
+ private String taskDeviceId;
+ private String agentId;
+ private String internalIp;
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/service/LabEnvService.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/service/LabEnvService.java
new file mode 100644
index 0000000..1eba0aa
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/service/LabEnvService.java
@@ -0,0 +1,642 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.service;
+
+import com.alibaba.fastjson.JSONArray;
+import com.huawei.ic.openlab.cloudtest.common.exception.BaseException;
+import com.huawei.ic.openlab.cloudtest.common.exception.SshErrorException;
+import com.huawei.ic.openlab.cloudtest.entity.CloudLabTestTask;
+import com.huawei.ic.openlab.cloudtest.entity.LabTestReq;
+import com.huawei.ic.openlab.cloudtest.entity.MqsMessage;
+import com.huawei.ic.openlab.cloudtest.entity.ScriptResultConfig;
+import com.huawei.ic.openlab.cloudtest.entity.SystemParams;
+import com.huawei.ic.openlab.cloudtest.entity.TestCaseResult;
+import com.huawei.ic.openlab.cloudtest.entity.TestCaseResultCount;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.CompatibilityTestResult;
+import com.huawei.ic.openlab.cloudtest.util.Constants;
+import com.huawei.ic.openlab.cloudtest.util.FileUtil;
+import com.huawei.ic.openlab.cloudtest.util.NormalResp;
+import com.huawei.ic.openlab.cloudtest.util.PerformanceApiClient;
+import com.huawei.ic.openlab.cloudtest.util.RandomUtil;
+import com.huawei.ic.openlab.cloudtest.util.ToolUtil;
+import com.huawei.ic.openlab.cloudtest.util.fastdfs.FastDfsClient;
+import com.huawei.ic.openlab.cloudtest.util.sshclient.SFTPUtil;
+import com.huawei.ic.openlab.cloudtest.util.sshclient.SSHUtil;
+
+import com.alibaba.fastjson.JSONObject;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.SftpException;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.io.IOUtils;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.DigestUtils;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.*;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * LabEnvService
+ *
+ * @author kongcaizhi
+ * @since 2021-10-19
+ */
+@Service
+@Slf4j
+public class LabEnvService {
+ @Autowired
+ private SystemParams systemParams;
+ @Autowired
+ private TarFileService fileService;
+ @Autowired
+ private PerformanceApiClient performanceApiClient;
+ @Autowired
+ private FastDfsClient fastDfsClient;
+
+ /**
+ * getLabConnectTest
+ *
+ * @param ip ip
+ * @param port port
+ * @param userName userName
+ * @param passWord password
+ * @return boolean
+ */
+ public boolean getLabConnectTest(String ip, int port, String userName, String passWord) {
+ return SSHUtil.sshConnectTest(ip, port, userName, passWord);
+ }
+
+ /**
+ * validatedZipFileSize
+ *
+ * @param fileInputStream fileInputStream
+ * @param language language
+ * @throws IOException exception
+ */
+ public void validatedZipFileSize(InputStream fileInputStream, String language) throws IOException {
+ fileService.validatedZipFileSize(fileInputStream, language);
+ }
+
+ /**
+ * validatedTarZipFile
+ *
+ * @param fileInputStream fileInputStream
+ * @throws IOException exception
+ */
+ public void validatedTarZipFile(InputStream fileInputStream) throws IOException {
+ fileService.validatedTarGzFileSize(fileInputStream);
+ }
+
+
+ /**
+ * testPreparation
+ *
+ * @param testReq testReq
+ * @throws SshErrorException SshErrorException
+ * @throws FileNotFoundException FileNotFoundException
+ */
+ public void testPreparation(LabTestReq testReq) throws SshErrorException, FileNotFoundException {
+ List commandList = new ArrayList<>();
+ commandList.add("mkdir -p /home/compatibility_testing; mkdir -p /home/function_testing");
+ String wgetCom = "cd /home/compatibility_testing; wget http://%s:8080/download/compatibility_testing.tar.gz";
+ commandList.add(String.format(Locale.ROOT, wgetCom, systemParams.getDeployIP()));
+ commandList.add("cd /home/compatibility_testing; tar -xvzf compatibility_testing.tar.gz");
+ String wgetFun = "cd /home/function_testing; wget http://%s:8080/download/shunit2-master.zip";
+ commandList.add(String.format(Locale.ROOT, wgetFun, systemParams.getDeployIP()));
+ commandList.add("cd /home/function_testing; unzip -o -q shunit2-master.zip");
+ SSHUtil.sshExecCmd(testReq.getServerIp(), testReq.getServerPort(), testReq.getServerUser(),
+ testReq.getServerPassword(), commandList);
+ }
+
+ /**
+ * 修改配置文件,并上传到实验室环境
+ *
+ * @param testReq testReq
+ * @throws IOException IOException
+ * @throws JSchException JSchException
+ * @throws SftpException SftpException
+ */
+ private void setConfigFile(LabTestReq testReq) throws IOException, JSchException, SftpException {
+ String configContent = readConfigFile(testReq);
+ String configFileName = writeConfigFile(configContent);
+ ToolUtil.validPath(configFileName);
+ File configFile = new File(configFileName);
+ try (InputStream in = Files.newInputStream(configFile.toPath())) {
+ String targetPath = String.format(Locale.ROOT, "/home/compatibility_testing/compatibility_testing/%s"
+ + "/compatibility_testing.conf", "CN".equals(testReq.getTaskLanguage()) ? "Chinese" : "English");
+ SFTPUtil.uploadFile(testReq, targetPath, in);
+ }
+ log.info("Delete configure file {},result {}", configFileName, configFile.delete());
+ }
+
+ private String readConfigFile(LabTestReq testReq) {
+ StringBuilder res = new StringBuilder(16);
+ try (BufferedReader reader = new BufferedReader(
+ new FileReader(systemParams.getScriptConfig(testReq.getTaskLanguage())))) {
+ String line;
+ while ((line = reader.readLine()) != null) {
+ if (StringUtils.startsWithIgnoreCase(line, "application_names=")) {
+ line = line + testReq.getApplicationNames();
+ }
+ if (StringUtils.startsWithIgnoreCase(line, "start_app_commands=")) {
+ line = line + testReq.getStartAppCommands();
+ }
+ if (StringUtils.startsWithIgnoreCase(line, "stop_app_commands=")) {
+ line = line + testReq.getStopAppCommands();
+ }
+ if (StringUtils.startsWithIgnoreCase(line, "application_install_dir=")) {
+ line = line + testReq.getDeployDir();
+ }
+ res.append(line).append(System.lineSeparator());
+ }
+ } catch (FileNotFoundException ex) {
+ log.error(ex.getLocalizedMessage());
+ throw new BaseException("配置文件不存在");
+ } catch (IOException e) {
+ log.error(e.getLocalizedMessage(), e);
+ }
+ return res.toString();
+ }
+
+ private String writeConfigFile(String content) {
+ SecureRandom random = RandomUtil.getRandom();
+ int ends = random.nextInt(99);
+ String fileName = ToolUtil.getTimeStr() + String.format(Locale.ROOT, "%02d", ends);
+ fileName = systemParams.getTempDir() + File.separator + fileName;
+ try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) {
+ writer.write(content);
+ writer.flush();
+ } catch (IOException e) {
+ log.error(e.getLocalizedMessage(), e);
+ }
+ return fileName;
+ }
+
+ private void setStep(String step, String resultCode, String timeString, CloudLabTestTask.StepStatus stepStatus) {
+ switch (step) {
+ case "01":
+ stepStatus.setStep1(resultCode, timeString);
+ break;
+ case "02":
+ stepStatus.setStep2(resultCode, timeString);
+ break;
+ case "03":
+ stepStatus.setStep3(resultCode, timeString);
+ break;
+ case "04":
+ stepStatus.setStep4(resultCode, timeString);
+ break;
+ case "05":
+ stepStatus.setStep5(resultCode, timeString);
+ break;
+ case "06":
+ stepStatus.setStep6(resultCode, timeString);
+ break;
+ case "07":
+ stepStatus.setStep7(resultCode, timeString);
+ break;
+ case "08":
+ stepStatus.setStep8(resultCode, timeString);
+ break;
+ case "09":
+ stepStatus.setStep9(resultCode, timeString);
+ break;
+ default:
+ stepStatus.setStep10(resultCode, timeString);
+ break;
+ }
+ }
+
+ private void setTestTime(String step, String timeString, CloudLabTestTask.TestBeginTime testBeginTime,
+ boolean isFunctionTest) {
+ if ("05".equals(step)) {
+ testBeginTime.setCompatibilityTime(timeString);
+ testBeginTime.setSecurityTime(timeString);
+ testBeginTime.setReliabilityTime(timeString);
+ testBeginTime.setFunctionTime(timeString);
+ } else if ("06".equals(step)) {
+ testBeginTime.setCompatibilityTime(timeString);
+ testBeginTime.setReliabilityTime(timeString);
+ } else if ("08".equals(step)) {
+ testBeginTime.setCompatibilityTime(timeString);
+ } else if ("09".equals(step) && isFunctionTest) {
+ testBeginTime.setFunctionTime(timeString);
+ } else {
+ log.info("not contrast");
+ }
+ }
+
+ /**
+ * 组装测试进度推送MQS 消息
+ *
+ * @param task task
+ * @param resultCode resultCode
+ * @param timeString timeString
+ * @return MqsMessage object
+ */
+ private MqsMessage getProgressMessage(CloudLabTestTask task, String resultCode, String timeString) {
+ MqsMessage message = new MqsMessage();
+ message.setProjectId(task.getProjectId());
+ message.setUserId(task.getUserId());
+ message.setServerIp(task.getServerIp());
+ message.setStatusTime(timeString);
+ message.setStatus(Constants.MQS_STATUS_ONGOING);
+ message.setStatusDesc("");
+
+ MqsMessage.MessageDetail detail = setDetail(task, resultCode);
+ message.setDetail(detail);
+ return message;
+ }
+
+ private MqsMessage.MessageDetail setDetail(CloudLabTestTask task, String resultCode) {
+ MqsMessage.MessageDetail detail = new MqsMessage.MessageDetail();
+ switch (Objects.requireNonNull(Constants.CompatibilityTestStep.fromStepIndex(resultCode))) {
+ case DEPENDENCY_INSTALL_SUCCESS:
+ detail.setDependencyInstallSuccess();
+ break;
+ case APP_START_SUCCESS:
+ detail.setAppStartSuccess();
+ break;
+ case APP_STOP_SUCCESS:
+ detail.setAppStopSuccess(task.isCompatibilityTest(),
+ task.isReliabilityTest(), task.isSecurityTest());
+ break;
+ case COMPATIBILITY_TEST_SUCCESS:
+ case COM_START_SUCCESS:
+ detail.setComStartSuccess(task.isReliabilityTest(), task.isSecurityTest());
+ if ((task.isCompatibilityTest() || task.isReliabilityTest())
+ && !task.isSecurityTest() && task.getPerformanceFile() != null) {
+ setPerformanceTest(task, true);
+ }
+ break;
+ case PORT_TEST_SUCCESS:
+ detail.setPortTestSuccess();
+ break;
+ case VIRUS_SCAN_SUCCESS:
+ detail.setVirusScanSuccess(task.isCompatibilityTest(), task.isReliabilityTest());
+ if ((task.isCompatibilityTest() || task.isReliabilityTest()) && task.getPerformanceFile() != null) {
+ setPerformanceTest(task, true);
+ }
+ break;
+ case VULNERABLE_SCAN_SUCCESS:
+ detail.setVulnerableScanSuccess(task.isCompatibilityTest(), task.isReliabilityTest());
+ break;
+ case EXCEPTION_TEST_FINISH:
+ detail.setExceptionTestFinish(task.isCompatibilityTest());
+ break;
+ case COMPATIBILITY_TEST_FINISH:
+ detail.setStep(Constants.COMPATIBILITY_TEST_DESC);
+ detail.setStepStatus(Constants.TEST_FINISHED_CN);
+ break;
+ case FUN_TEST_FILE_EXIST_ERROR:
+ case FUN_TEST_FILE_DIR_ERROR:
+ case FUN_TEST_PYTEST_ERROR:
+ detail.setStep(Constants.FUNCTION_TEST_DESC);
+ detail.setStepStatus(Constants.TEST_FAILURE_CN);
+ break;
+ default:
+ break;
+ }
+ return detail;
+ }
+
+ private void sendExceptionMessage(CloudLabTestTask task, String timeString, MqsMessage.MessageDetail detail) {
+ MqsMessage message = new MqsMessage();
+ message.setProjectId(task.getProjectId());
+ message.setUserId(task.getUserId());
+ message.setServerIp(task.getServerIp());
+ message.setStatusTime(timeString);
+ message.setStatus(Constants.MQS_STATUS_EXCEPTION);
+ message.setStatusDesc(detail.getExceptionType());
+ message.setDetail(detail);
+ }
+
+ private void ransfer2json(List input_info, String path) {
+ String jsonArray = JSONArray.toJSONString(input_info);
+ byte[] temp_result = jsonArray.getBytes(StandardCharsets.UTF_8);
+ try(FileOutputStream fos=new FileOutputStream(new File(path));
+ ByteArrayInputStream bais = new ByteArrayInputStream(temp_result)){
+ IOUtils.copy(bais, fos);
+ } catch (FileNotFoundException e) {
+ throw new RuntimeException(e);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void resultJson(String multipartFile, String savePath) {
+ List testCaseResultList = null;
+ List results = fileService.compatibilityResultAnalysis(multipartFile);
+ if (results.size() != 0){
+ testCaseResultList = analyseCompatibilityTestResult(results, "CN");
+ } else {
+ throw new BaseException("解析兼容性测试工具输出日志异常");
+ }
+ ransfer2json(testCaseResultList, savePath);
+ }
+
+ private String resultFileAnalysis(CloudLabTestTask task, MultipartFile multipartFile, String resultCode,
+ String fileStatus, String timeString) {
+ List temp = null;
+ CloudLabTestTask.StepStatus stepStatus = task.getStepStatus();
+ if (stepStatus == null) {
+ stepStatus = new CloudLabTestTask.StepStatus();
+ }
+ stepStatus.setStep10Code(resultCode);
+ stepStatus.setStep10Time(timeString);
+ stepStatus.setStep10File(getFileFromRequest(multipartFile, "兼容性测试工具输出日志", fileStatus));
+ if (!task.isPerformanceTest() || (task.getPerformanceFile() == null
+ && Constants.RELIABILITY_START_APP_FAIL_CODE.equals(stepStatus.getStep9Code()))) {
+ task.setProjectStatus(Constants.CLOUD_LAB_TEST_FINISH);
+ task.setFinishTime(timeString);
+
+ task.setProjectStatus(Constants.CLOUD_LAB_TEST_FINISH);
+ } else {
+ stepStatus.setPerformanceTime(timeString);
+ }
+ if (multipartFile != null) {
+ task.setResultFile(stepStatus.getStep10File());
+ List results = fileService.compatibilityResultAnalysis(multipartFile.getOriginalFilename());
+ if (results.size() != 0) {
+ temp = analyseCompatibilityTestResult(results, "CN");
+ } else {
+ task.setStatusDesc("解析兼容性测试工具输出日志异常");
+ task.setProjectStatus(Constants.CLOUD_LAB_TEST_EXCEPTION);
+ }
+ } else {
+ task.setStatusDesc("兼容性测试工具输出日志," + fileStatus);
+ task.setProjectStatus(Constants.CLOUD_LAB_TEST_EXCEPTION);
+ }
+
+ task.setStepStatus(stepStatus);
+
+ return NormalResp.ok();
+ }
+
+ private void setPerformanceTest(CloudLabTestTask task, boolean isTimeLimited) {
+ try {
+ String fileName = task.getPerformanceFile().getFilePath();
+ MultipartFile multipartFile = FileUtil.fileToMultipartFile(fileName);
+ String result = performanceApiClient.setPerformanceTest(createURI(task.getPerformanceService()),
+ task.getProjectId(), task.getServerIp(), isTimeLimited, multipartFile);
+ log.info("Task {} request {} return from performance test {}", task.getProjectId(),
+ task.getPerformanceService(), result);
+ } catch (URISyntaxException ex) {
+ log.error("Failed to request performance test {}", ex.getLocalizedMessage());
+ }
+ }
+
+ /**
+ * 往MQS发送性能测试中状态
+ *
+ * @param task task
+ * @param timeString timeString
+ */
+ private void sendPerformanceMQS(CloudLabTestTask task, String timeString) {
+ MqsMessage message = new MqsMessage();
+ message.setProjectId(task.getProjectId());
+ message.setUserId(task.getUserId());
+ message.setServerIp(task.getServerIp());
+ message.setStatusTime(timeString);
+ message.setStatus(Constants.MQS_STATUS_ONGOING);
+ message.setStatusDesc("");
+ MqsMessage.MessageDetail detail = new MqsMessage.MessageDetail();
+ detail.setStep(Constants.PERFORMANCE_TEST_DESC);
+ detail.setStepStatus(Constants.TEST_PROCESSING);
+ message.setDetail(detail);
+ }
+
+ /**
+ * 往MQS发送分析结果
+ *
+ * @param task task
+ * @param timeString time string
+ */
+ private void sentResultMQSMessage(CloudLabTestTask task, String timeString) {
+ MqsMessage message = new MqsMessage();
+ message.setProjectId(task.getProjectId());
+ message.setUserId(task.getUserId());
+ message.setServerIp(task.getServerIp());
+ message.setStatusTime(timeString);
+ message.setStatus(Constants.MQS_STATUS_FINISH);
+ MqsMessage.MessageDetail detail = new MqsMessage.MessageDetail();
+ detail.setResultFileName(task.getResultFile().getFileName());
+ detail.setFileStatus(Constants.TEST_NORMAL_CN);
+ message.setDetail(detail);
+ MqsMessage.MessageResult result = new MqsMessage.MessageResult();
+ result.setScriptResultConfig(task.getScriptResultConfig());
+ result.setTestDetail(task.getTestDetail());
+ result.setTestSummary(task.getTestSummary());
+ message.setTestResult(result);
+
+ }
+
+ /**
+ * 上传的文件,存储到服务器,返回路径
+ *
+ * @param multipartFile multipartFile
+ * @param type type
+ * @param fileStatus fileStatus
+ * @return 路径
+ */
+ private CloudLabTestTask.UploadFile getFileFromRequest(MultipartFile multipartFile, String type,
+ String fileStatus) {
+ CloudLabTestTask.UploadFile uploadFile = new CloudLabTestTask.UploadFile();
+ uploadFile.setFileDesc(type);
+ uploadFile.setFileStatus(fileStatus);
+ if (multipartFile == null) {
+ return uploadFile;
+ }
+ try {
+ SecureRandom random = RandomUtil.getRandom();
+ String fileName = random.getAlgorithm() + "-"
+ + DigestUtils.md5DigestAsHex(multipartFile.getInputStream())
+ + multipartFile.getOriginalFilename().substring(
+ multipartFile.getOriginalFilename().lastIndexOf("."));
+ String dirName = systemParams.getUploadFileDir() + File.separator
+ + ToolUtil.getDateStr() + File.separator + fileName;
+ ToolUtil.validPath(dirName);
+ File file = new File(dirName);
+ FileUtils.copyToFile(multipartFile.getInputStream(), file);
+ uploadFile.setFileId(DigestUtils.md5DigestAsHex(multipartFile.getInputStream()));
+ uploadFile.setFileName(fileName);
+ uploadFile.setFilePath(dirName);
+ } catch (IOException ex) {
+ log.error(ex.getLocalizedMessage(), ex);
+ uploadFile.setFileStatus(Constants.UPLOAD_FILE_STATUS_EXCEPTION);
+ }
+ return uploadFile;
+ }
+
+ private List analyseCompatibilityTestResult(List results, String lan) {
+ ScriptResultConfig config = new ScriptResultConfig();
+ TestCaseResultCount functionCount = new TestCaseResultCount();
+ TestCaseResultCount compatibilityCount = new TestCaseResultCount();
+ TestCaseResultCount reliabilityCount = new TestCaseResultCount();
+ TestCaseResultCount securityCount = new TestCaseResultCount();
+ List testCaseResults = new ArrayList<>();
+
+ for (CompatibilityTestResult item : results) {
+ ready(item, config);
+ if (StringUtils.isNoneEmpty(item.getId()) && item.getId().startsWith(
+ "Compatibility")) {
+ compatibilityCount.add(item.getResult());
+ testCaseResults.add(getTestCaseResult(item, lan));
+ } else if (StringUtils.isNoneEmpty(item.getId()) && item.getId().startsWith(
+ "Reliability")) {
+ reliabilityCount.add(item.getResult());
+ testCaseResults.add(getTestCaseResult(item, lan));
+ } else if (StringUtils.isNoneEmpty(item.getId()) && item.getId().startsWith(
+ "Security")) {
+ securityCount.add(item.getResult());
+ testCaseResults.add(getTestCaseResult(item, lan));
+ } else {
+ log.info("not contrast");
+ }
+ }
+ CloudLabTestTask.TestCaseSummary testCaseSummary = new CloudLabTestTask.TestCaseSummary(compatibilityCount,
+ reliabilityCount, securityCount, functionCount);
+
+ return testCaseResults;
+ }
+
+ private void ready(CompatibilityTestResult item, ScriptResultConfig config) {
+ if (StringUtils.isNoneEmpty(item.getId()) && StringUtils.equals(item.getId(),
+ Constants.CompatibilityTestName.APPLICATION_START.getTestName())) {
+ config.setOsVersion(item.getOsVersion());
+ } else if (StringUtils.isNoneEmpty(item.getId()) && StringUtils.equals(item.getId(),
+ Constants.CompatibilityTestName.SOFTWARE_NAME.getTestName())) {
+ config.setApplicationNames(item.getApplicationNames() != null ? String.join(",",
+ item.getApplicationNames()) : "");
+ config.setStartAppCommands(item.getStartAppCommands() != null ? String.join(",",
+ item.getStartAppCommands()) : "");
+ config.setStopAppCommands(item.getStopAppCommands() != null ? String.join(",",
+ item.getStopAppCommands()) : "");
+ } else {
+ log.info("not contrast");
+ }
+ }
+
+ private TestCaseResult createTestCaseResult(CloudLabTestTask.UploadFile performanceFile, String taskLanguage) {
+ TestCaseResult testCaseResult = new TestCaseResult();
+ testCaseResult.setId(Constants.PERFORMANCE_TEST_ID);
+ testCaseResult.setResult(Constants.TEST_FAILED);
+ if (performanceFile == null) {
+ testCaseResult.setReason(Constants.PERFORMANCE_FILE_MISSING_MAP.get(taskLanguage));
+ } else {
+ testCaseResult.setReason(Constants.APP_START_UP_FAILURE_DESC_MAP.get(taskLanguage));
+ }
+ return testCaseResult;
+ }
+
+ private void setFunctionCount(CompatibilityTestResult item, TestCaseResultCount functionCount,
+ CloudLabTestTask.StepStatus status, CloudLabTestTask.TestBeginTime testBeginTime) {
+ if (Constants.TEST_PASSED.equals(item.getResult())) {
+ JSONObject jsonObject = JSONObject.parseObject(item.getReason());
+ functionCount.setPassed(jsonObject.getIntValue(Constants.TEST_PASSED));
+ functionCount.setFailed(jsonObject.getIntValue(Constants.TEST_FAILED));
+ functionCount.setTotal(jsonObject.getIntValue(Constants.TEST_PASSED)
+ + jsonObject.getIntValue(Constants.TEST_FAILED));
+ }
+ if (Constants.RELIABILITY_START_APP_FAIL_CODE.equals(status.getStep9Code())) {
+ functionCount.setPassed(0);
+ functionCount.setFailed(0);
+ functionCount.setTotal(0);
+ }
+ functionCount.setStartTime(testBeginTime.getFunctionTime());
+ }
+
+ private TestCaseResult getTestCaseResult(CompatibilityTestResult testResult, String language) {
+ TestCaseResult testCaseResult = new TestCaseResult();
+ testCaseResult.setId(testResult.getId());
+ testCaseResult.setResult(testResult.getResult());
+ testCaseResult.setReason("CN".equals(language) ? testResult.getReason() : testResult.getReasonEn());
+ testCaseResult.setEvidence(String.join(",", "CN".equals(language)
+ ? testResult.getEvidence() : testResult.getEvidenceEn()));
+ return testCaseResult;
+ }
+
+ /**
+ * 上传功能测试文件到远程实验室
+ *
+ * @param task task
+ * @param uploadFile upload file
+ */
+ private void setRemoteFunctionFile(CloudLabTestTask task, CloudLabTestTask.UploadFile uploadFile) {
+ ToolUtil.validPath(uploadFile.getFilePath());
+ try (InputStream in = new FileInputStream(uploadFile.getFilePath())) {
+ SFTPUtil.uploadFile(task, "/home/function_testing/function_testing.zip", in);
+ } catch (JSchException | SftpException | IOException ex) {
+ log.error("Failed to upload task {} function file {} to remote lab {},{}", task.getProjectId(),
+ uploadFile.getFilePath(), task.getServerIp(), ex.getLocalizedMessage());
+ }
+ }
+
+ private boolean stopCompatibilityTesting(CloudLabTestTask task) {
+ List commandList = new ArrayList<>();
+ commandList.add("pid=$(pgrep -f sh\\ compatibility_testing.sh|head -1);sub_pids=$(pgrep -P ${pid});for "
+ + "subpid" + " " + "in ${sub_pids};do kill -9 \"${subpid}\" ;done;kill -9 \"${pid}\" ");
+ try {
+ SSHUtil.sshExecCmd(task.getServerIp(), task.getServerPort(), task.getServerUser(),
+ task.getServerPassword(), commandList);
+
+ return true;
+ } catch (SshErrorException ex) {
+ log.error("Failed to execute task {},{}", task.getProjectId(), ex.getLocalizedMessage());
+ return false;
+ }
+ }
+
+ private boolean stopPerformanceTesting(CloudLabTestTask task) {
+ try {
+ String result = performanceApiClient.stopPerformanceTest(createURI(task.getPerformanceService()),
+ task.getProjectId());
+ log.info("Task {} request {} stop performance test, return {}", task.getProjectId(),
+ task.getPerformanceService(), result);
+ JSONObject resultJson = JSONObject.parseObject(result);
+ return resultJson.containsKey("code") && "0000".equals(resultJson.getString("code"));
+ } catch (URISyntaxException ex) {
+ log.error("Failed to stop performance test {}", ex.getLocalizedMessage());
+ return false;
+ }
+ }
+
+ /**
+ * upload file
+ *
+ * @param file file
+ * @return response
+ */
+ public String uploadFile(MultipartFile file) {
+ String fileId = null;
+ try {
+ fileId = fastDfsClient.uploadFile(file);
+ } catch (IOException ex) {
+ log.error(ex.getLocalizedMessage());
+ }
+ return fileId;
+ }
+
+ private URI createURI(String param) throws URISyntaxException {
+ ToolUtil.checkParameter(param);
+ return new URI(String.format(Locale.ROOT,
+ systemParams.getPerformanceTestUrl(), param));
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/service/TarFileService.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/service/TarFileService.java
new file mode 100644
index 0000000..95e1d89
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/service/TarFileService.java
@@ -0,0 +1,387 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.service;
+
+import com.huawei.ic.openlab.cloudtest.entity.CloudLabTestTask;
+import com.huawei.ic.openlab.cloudtest.entity.SystemParams;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.CompatibilityTestResult;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.ParseFunctionTestLog;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.ParseInfoLog;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.ParseSafetyFiles;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.impl.ParseClamLog;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.impl.ParseCpuComFiles;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.impl.ParseCpuPerFiles;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.impl.ParseCveCheckFiles;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.impl.ParseDiskComFiles;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.impl.ParseDiskPerFiles;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.impl.ParseMemComFiles;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.impl.ParseMemPerFiles;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.impl.ParseNetComFiles;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.impl.ParseNetPerFiles;
+import com.huawei.ic.openlab.cloudtest.entity.compatibilityfileanalysis.impl.ParseSoftwareLog;
+import com.huawei.ic.openlab.cloudtest.util.Constants;
+import com.huawei.ic.openlab.cloudtest.util.ToolUtil;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
+import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
+import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
+import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.zip.ZipInputStream;
+
+/**
+ * TarFileService
+ *
+ * @author kongcaizhi
+ * @since 2021-10-19
+ */
+@Service
+@Slf4j
+public class TarFileService {
+ /**
+ * BUFFER
+ */
+ public static final int BUFFER = 512;
+
+ /**
+ * TOOBIG
+ */
+ public static final int TOOBIG = 0X64000000;
+
+ private final SystemParams systemParams;
+
+ /**
+ * TarFileService
+ *
+ * @param systemParams system Params
+ */
+ public TarFileService(SystemParams systemParams) {
+ this.systemParams = systemParams;
+ }
+
+ /**
+ * validatedTarGzFileSize
+ *
+ * @param fileInputStream input stream
+ * @throws IOException exception
+ */
+ public void validatedTarGzFileSize(InputStream fileInputStream) throws IOException {
+ long total = 0L;
+ try (ZipInputStream zis = new ZipInputStream(new BufferedInputStream(fileInputStream))) {
+ while (zis.getNextEntry() != null) {
+ total = getTarTotalSize(total, zis);
+ if (total > TOOBIG) {
+ throw new IllegalStateException(Constants.TAR_FILE_TOO_BIG);
+ }
+ }
+ }
+ }
+
+ private long getTarTotalSize(long total, ZipInputStream zis) throws IOException {
+ int count;
+ byte[] data = new byte[BUFFER];
+ long sum = total;
+ while ((count = zis.read(data, 0, BUFFER)) != -1) {
+ sum += count;
+ if (sum > TOOBIG) {
+ break;
+ }
+ }
+ return sum;
+ }
+
+ /**
+ * validatedZipFileSize
+ *
+ * @param fileInputStream input stream
+ * @param language language
+ * @throws IOException exception
+ */
+ public void validatedZipFileSize(InputStream fileInputStream, String language) throws IOException {
+ long total = 0L;
+ try (ZipArchiveInputStream zis = new ZipArchiveInputStream(new BufferedInputStream(fileInputStream))) {
+ while (zis.getNextEntry() != null) {
+ total = getZipTotalSize(total, zis);
+ if (total > TOOBIG) {
+ throw new IllegalStateException(
+ Constants.TAR_FILE_TOO_BIG_MAP.getOrDefault(language, "CN"));
+ }
+ }
+ }
+ }
+
+ private long getZipTotalSize(long total, ZipArchiveInputStream zis) throws IOException {
+ int count;
+ byte[] data = new byte[BUFFER];
+ long sum = total;
+ while ((count = zis.read(data, 0, BUFFER)) != -1) {
+ sum += count;
+ if (sum > TOOBIG) {
+ break;
+ }
+ }
+ return sum;
+ }
+
+ /**
+ * 应用启动、停止、异常测试用例
+ *
+ * @param filePath file path
+ * @param testResultList test result list
+ * @throws IOException exception
+ */
+ private void getTestCaseFromInfoLog(String filePath, List testResultList)
+ throws IOException {
+ byte[] infoLogFile = readSpecificFile(filePath, Constants.CompatibilityTarFile.INFO_LOG.getFileName());
+ ParseInfoLog parseInfoLog = new ParseInfoLog(infoLogFile, "");
+ Map infoResultMap = parseInfoLog.parseInfoLog();
+ for (Map.Entry entry : infoResultMap.entrySet()) {
+ testResultList.add(entry.getValue());
+ }
+ }
+
+ /**
+ * 软件识别用例
+ *
+ * @param filePath file path
+ * @param testResultList test result list
+ * @throws IOException exception
+ */
+ private void getTestCaseFromProductName(String filePath, List testResultList)
+ throws IOException {
+ byte[] configFile = readSpecificFile(filePath, Constants.CompatibilityTarFile.CONFIGURE_INFO.getFileName());
+ byte[] processFile = readSpecificFile(filePath, Constants.CompatibilityTarFile.PRODUCT_NAME.getFileName());
+ ParseSoftwareLog softwareLog = new ParseSoftwareLog(configFile, processFile);
+ CompatibilityTestResult softwareResult = softwareLog.parseFiles();
+ testResultList.add(softwareResult);
+ }
+
+ /**
+ * 空载测试用例
+ *
+ * @param filePath filePath
+ * @param testResultList testResultList
+ * @throws IOException IOException
+ */
+ private void getTestCaseFromIdleFile(String filePath, List testResultList)
+ throws IOException {
+ // 空载测试CPU 用例
+ Map beginCpuComFile = getSpecificFile(filePath,
+ Constants.CompatibilityTarFile.COMPATIBILITY_CPU_0.getFileName());
+ Map endCpuComFile = getSpecificFile(filePath,
+ Constants.CompatibilityTarFile.COMPATIBILITY_CPU_1.getFileName());
+ CompatibilityTestResult cpuComResult = new ParseCpuComFiles(beginCpuComFile, endCpuComFile).parseFiles();
+ testResultList.add(cpuComResult);
+
+ // 空载测试内存用例
+ Map beginMemComFile = getSpecificFile(filePath,
+ Constants.CompatibilityTarFile.COMPATIBILITY_MEM_0.getFileName());
+ Map endMemComFile = getSpecificFile(filePath,
+ Constants.CompatibilityTarFile.COMPATIBILITY_MEM_1.getFileName());
+ CompatibilityTestResult memComResult = new ParseMemComFiles(beginMemComFile, endMemComFile).parseFiles();
+ testResultList.add(memComResult);
+
+ Map beginDiskComFile = getSpecificFile(filePath,
+ Constants.CompatibilityTarFile.COMPATIBILITY_DISK_0.getFileName());
+ Map endDiskComFile = getSpecificFile(filePath,
+ Constants.CompatibilityTarFile.COMPATIBILITY_DISK_1.getFileName());
+ CompatibilityTestResult diskComResult = new ParseDiskComFiles(beginDiskComFile, endDiskComFile).parseFiles();
+ testResultList.add(diskComResult);
+
+ Map beginNetComFile = getSpecificFile(filePath,
+ Constants.CompatibilityTarFile.COMPATIBILITY_NET_0.getFileName());
+ Map endNetComFile = getSpecificFile(filePath,
+ Constants.CompatibilityTarFile.COMPATIBILITY_NET_1.getFileName());
+ CompatibilityTestResult diskNetResult = new ParseNetComFiles(beginNetComFile, endNetComFile).parseFiles();
+ testResultList.add(diskNetResult);
+ }
+
+ /**
+ * 压力测试用例
+ *
+ * @param filePath filePath
+ * @param testResultList testResultList
+ * @throws IOException exception
+ */
+ private void getTestCaseFromPressureFile(String filePath, List testResultList)
+ throws IOException {
+ Map cpuPerFile = getSpecificFile(filePath,
+ Constants.CompatibilityTarFile.PERFORMANCE_CPU.getFileName());
+ CompatibilityTestResult cpuPerTestResult = new ParseCpuPerFiles(cpuPerFile).parseFiles();
+ testResultList.add(cpuPerTestResult);
+ Map memPerFile = getSpecificFile(filePath,
+ Constants.CompatibilityTarFile.PERFORMANCE_MEM.getFileName());
+ CompatibilityTestResult memPerTestResult = new ParseMemPerFiles(memPerFile).parseFiles();
+ testResultList.add(memPerTestResult);
+
+ Map diskPerFile = getSpecificFile(filePath,
+ Constants.CompatibilityTarFile.PERFORMANCE_DISK.getFileName());
+ CompatibilityTestResult diskPerTestResult = new ParseDiskPerFiles(diskPerFile).parseFiles();
+ testResultList.add(diskPerTestResult);
+ Map netPerFile = getSpecificFile(filePath,
+ Constants.CompatibilityTarFile.PERFORMANCE_NET.getFileName());
+ CompatibilityTestResult netPerTestResult = new ParseNetPerFiles(netPerFile).parseFiles();
+ testResultList.add(netPerTestResult);
+ }
+
+ private void getTestCaseFromSafeFile(List fileList, String filePath,
+ List testResultList) throws IOException {
+ // 端口扫描
+ byte[] protocolFile = new byte[0];
+ byte[] updFile = new byte[0];
+ byte[] tcpFile = new byte[0];
+
+ for (String tarFileName : fileList) {
+ if (StringUtils.endsWith(tarFileName, "gnmap")
+ && StringUtils.containsIgnoreCase(tarFileName, "PROTOCOL")) {
+ protocolFile = readSpecificFile(filePath, tarFileName);
+ } else if (StringUtils.endsWith(tarFileName, "gnmap")
+ && StringUtils.containsIgnoreCase(tarFileName, "UDP"
+ )) {
+ updFile = readSpecificFile(filePath, tarFileName);
+ } else if (StringUtils.endsWith(tarFileName, "gnmap")
+ && StringUtils.containsIgnoreCase(tarFileName, "TCP"
+ )) {
+ tcpFile = readSpecificFile(filePath, tarFileName);
+ } else {
+ log.info("not contrast");
+ }
+ }
+ testResultList.add(new ParseSafetyFiles(protocolFile, updFile, tcpFile).parseSafetyFile());
+ }
+
+ /**
+ * compatibility Result Analysis
+ *
+ * @param task task
+ * @param multipartFile multipartFile
+ * @return CompatibilityTestResult list
+ */
+ public List compatibilityResultAnalysis(String multipartFile) {
+
+ String logPath = multipartFile;
+ File file = FileUtils.getFile(logPath);
+ List testResultList = new ArrayList<>();
+ try {
+ List fileList = getTarFileList(logPath);
+ getTestCaseFromInfoLog(logPath, testResultList);
+
+ // 硬件识别用例
+ CompatibilityTestResult testResult =
+ new CompatibilityTestResult(Constants.CompatibilityTestName.HARDWARE_SERVER.getTestName());
+ testResult.setResult(Constants.TEST_PASSED);
+ testResult.setReason(Constants.HCS_DESC);
+ testResultList.add(testResult);
+
+ getTestCaseFromProductName(logPath, testResultList);
+ getTestCaseFromIdleFile(logPath, testResultList);
+ getTestCaseFromPressureFile(logPath, testResultList);
+ getTestCaseFromSafeFile(fileList, logPath, testResultList);
+
+ // 功能测试
+ byte[] shellBytes = readSpecificFile(logPath,
+ Constants.CompatibilityTarFile.FUNCTION_SHELL_UNIT.getFileName());
+ byte[] pytestBytes = readSpecificFile(logPath,
+ Constants.CompatibilityTarFile.FUNCTION_PY_TEST.getFileName());
+ testResultList.add(new ParseFunctionTestLog(shellBytes, pytestBytes).parseFunctionTestLog());
+ } catch (IOException ex) {
+ log.error("Error parsing tar file", ex);
+ }
+ return testResultList;
+ }
+
+ /**
+ * get tar file list
+ *
+ * @param tarGzFile tar file
+ * @return file list
+ * @throws IOException exception
+ */
+ public List getTarFileList(String tarGzFile) throws IOException {
+ ToolUtil.validPath(tarGzFile);
+ List fileList = new ArrayList<>();
+ try (FileInputStream fin = new FileInputStream(tarGzFile);
+ BufferedInputStream in = new BufferedInputStream(fin);
+ GzipCompressorInputStream gzip = new GzipCompressorInputStream(in);
+ TarArchiveInputStream tarIn = new TarArchiveInputStream(gzip)) {
+ TarArchiveEntry entry;
+ while ((entry = (TarArchiveEntry) tarIn.getNextEntry()) != null) {
+ fileList.add(entry.getName());
+ }
+ }
+ return fileList;
+ }
+
+ /**
+ * get specific file
+ *
+ * @param tarGzFile tar file
+ * @param fileName file name
+ * @return file map
+ * @throws IOException exception
+ */
+ public Map getSpecificFile(String tarGzFile, String fileName) throws IOException {
+ ToolUtil.validPath(tarGzFile);
+ Map fileMap = new HashMap<>();
+ try (FileInputStream fin = new FileInputStream(tarGzFile);
+ BufferedInputStream in = new BufferedInputStream(fin);
+ GzipCompressorInputStream gzip = new GzipCompressorInputStream(in);
+ TarArchiveInputStream tarIn = new TarArchiveInputStream(gzip)) {
+ TarArchiveEntry entry;
+
+ while ((entry = (TarArchiveEntry) tarIn.getNextEntry()) != null) {
+ if (StringUtils.startsWithIgnoreCase(entry.getName(), fileName)) {
+ byte[] fileBytes = new byte[(int) entry.getSize()];
+ tarIn.read(fileBytes);
+ fileMap.put(entry.getName(), fileBytes);
+ }
+ }
+ }
+ return fileMap;
+ }
+
+ /**
+ * read specific file
+ *
+ * @param tarGzFile tar file
+ * @param fileName file name
+ * @return byte []
+ * @throws IOException exception
+ */
+ public byte[] readSpecificFile(String tarGzFile, String fileName) throws IOException {
+ ToolUtil.validPath(tarGzFile);
+ byte[] fileBytes = new byte[0];
+ try (FileInputStream fin = new FileInputStream(tarGzFile);
+ BufferedInputStream in = new BufferedInputStream(fin);
+ GzipCompressorInputStream gzip = new GzipCompressorInputStream(in);
+ TarArchiveInputStream tarIn = new TarArchiveInputStream(gzip)) {
+ TarArchiveEntry entry;
+ while ((entry = (TarArchiveEntry) tarIn.getNextEntry()) != null) {
+ if (StringUtils.startsWithIgnoreCase(entry.getName(), fileName)) {
+ fileBytes = new byte[(int) entry.getSize()];
+ tarIn.read(fileBytes);
+ }
+ }
+ }
+ return fileBytes;
+ }
+}
\ No newline at end of file
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/service/TaskDelayMapService.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/service/TaskDelayMapService.java
new file mode 100644
index 0000000..e59911c
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/service/TaskDelayMapService.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.service;
+
+import com.huawei.ic.openlab.cloudtest.common.exception.SshErrorException;
+import com.huawei.ic.openlab.cloudtest.dao.CloudLabTestTaskDao;
+import com.huawei.ic.openlab.cloudtest.entity.CloudLabTestTask;
+import com.huawei.ic.openlab.cloudtest.entity.MqsMessage;
+import com.huawei.ic.openlab.cloudtest.entity.SystemParams;
+import com.huawei.ic.openlab.cloudtest.entity.TaskDelay;
+import com.huawei.ic.openlab.cloudtest.util.Constants;
+import com.huawei.ic.openlab.cloudtest.util.ToolUtil;
+import com.huawei.ic.openlab.cloudtest.util.sshclient.SSHUtil;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * TaskDelayMapService
+ *
+ * @author kongcaizhi
+ * @since 2021-10-19
+ */
+@Slf4j
+public class TaskDelayMapService {
+ private final Map taskMap = new HashMap<>();
+ private final CloudLabTestTaskDao dao;
+ private final SystemParams systemParams;
+
+ /**
+ * construction function
+ *
+ * @param dao dao
+ * @param systemParams system parameter
+ */
+ public TaskDelayMapService(CloudLabTestTaskDao dao, SystemParams systemParams) {
+ this.dao = dao;
+ this.systemParams = systemParams;
+ }
+
+ /**
+ * add task
+ *
+ * @param projectId project id
+ * @param currentStatus status
+ */
+ public void addTask(String projectId, String currentStatus) {
+ TaskDelay taskDelay;
+ if (taskMap.containsKey(projectId)) {
+ taskDelay = taskMap.get(projectId);
+ taskDelay.updateCurrentStatus(currentStatus);
+ } else {
+ taskDelay = new TaskDelay(projectId, ToolUtil.getMillionSeconds(), ToolUtil.getMillionSeconds(),
+ currentStatus);
+ }
+ taskMap.put(projectId, taskDelay);
+ }
+
+ /**
+ * update task
+ *
+ * @param projectId project id
+ * @param currentStatus current status
+ * @return boolean
+ */
+ public boolean updateTask(String projectId, String currentStatus) {
+ if (taskMap.containsKey(projectId)) {
+ TaskDelay taskDelay = taskMap.get(projectId);
+ taskDelay.updateCurrentStatus(currentStatus);
+ taskMap.put(projectId, taskDelay);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * get task status
+ *
+ * @param projectId project id
+ * @return status
+ */
+ public String getTaskStatus(String projectId) {
+ if (taskMap.containsKey(projectId)) {
+ taskMap.get(projectId);
+ return taskMap.get(projectId).getCurrentStatus();
+ }
+ return StringUtils.EMPTY;
+ }
+
+ /**
+ * remove task
+ *
+ * @param projectId project id
+ * @return remove task
+ */
+ public boolean removeTask(String projectId) {
+ if (taskMap.containsKey(projectId)) {
+ taskMap.remove(projectId);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * expire task
+ *
+ */
+ @Scheduled(cron = "0 0/5 * * * ?")
+ public void expireTask() {
+ TaskDelay task;
+ Iterator> iterator = taskMap.entrySet().iterator();
+ while (iterator.hasNext()) {
+ Map.Entry entry = iterator.next();
+ task = entry.getValue();
+ if (task.isExpired()) {
+ iterator.remove();
+ CloudLabTestTask testTask = dao.getTestTask(task.getProjectId());
+ testTask.setProjectStatus(Constants.CLOUD_LAB_TEST_EXCEPTION);
+ testTask.setStatusDesc(Constants.TASK_EXPIRE_ESC_MAP.get(testTask.getTaskLanguage()));
+ testTask.setFinishTime(ToolUtil.getStandardTime());
+ dao.updateProjectStatus(testTask.getProjectId(), testTask.getProjectStatus(), "",
+ testTask.getFinishTime(), testTask.getStatusDesc());
+ sendExceptionMessage(testTask);
+
+ // 删除服务器上的测试文件
+ deleteTestFile(testTask);
+ log.error("Task {} status {}: wait for 60 minutes without any change in status, abnormal testing task",
+ task.getProjectId(), task.getCurrentStatus());
+ }
+ }
+ }
+
+ private void sendExceptionMessage(CloudLabTestTask task) {
+ MqsMessage message = new MqsMessage();
+ message.setProjectId(task.getProjectId());
+ message.setUserId(task.getUserId());
+ message.setServerIp(task.getServerIp());
+ message.setStatusTime(task.getFinishTime());
+ message.setStatus(Constants.MQS_STATUS_EXCEPTION);
+ message.setStatusDesc(task.getStatusDesc());
+ }
+
+ /**
+ * delete test file
+ *
+ * @param task task
+ */
+ public void deleteTestFile(CloudLabTestTask task) {
+ try {
+ List commandList = new ArrayList<>();
+ commandList.add("cd /home/compatibility_testing;find . -name \"*.sh\"| xargs rm -rf ; "
+ + "rm -rf compatibility_testing.tar.gz;");
+ commandList.add("cd /home/function_testing; rm -rf shunit2-master.zip shunit2-master;");
+
+ SSHUtil.sshExecCmd(task.getServerIp(), task.getServerPort(), task.getServerUser(),
+ task.getServerPassword(), commandList);
+ } catch (SshErrorException ex) {
+ log.error("task {} in server {} failed in delete {}", task.getProjectId(), task.getServerIp(),
+ ex.getLocalizedMessage());
+ }
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/util/AESUtil.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/util/AESUtil.java
new file mode 100644
index 0000000..a8ffc08
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/util/AESUtil.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.util;
+
+import com.huawei.ic.openlab.cloudtest.common.exception.BaseException;
+
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Component;
+
+import java.nio.charset.StandardCharsets;
+import java.security.GeneralSecurityException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.util.Locale;
+import java.util.Optional;
+
+import javax.annotation.PostConstruct;
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.GCMParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ * AESUtil
+ *
+ * @author liuchunwang
+ * @since 2023-07-21
+ */
+@Slf4j
+@Component
+public class AESUtil {
+ /**
+ * CRYPTO
+ */
+ public static final Crypto CRYPTO = new Crypto();
+
+ private static final int PRIVATE_KEY_LENGTH = 256;
+ private static final int GCM_IV_LENGTH = 12;
+ private static final int GCM_TAG_LENGTH = 16;
+
+ private final Environment environment;
+
+ /**
+ * AESUtil
+ *
+ * @param environment env
+ */
+ public AESUtil(Environment environment) {
+ this.environment = environment;
+ }
+
+ /**
+ * Crypto
+ *
+ * @author liuchunwang
+ * @since 2023-07-21
+ */
+ @Data
+ public static class Crypto {
+ private String aesCipherMode;
+ private String aesDefaultKey;
+ private String aesDefaultAad;
+ }
+
+ @PostConstruct
+ private void initCrypto() {
+ CRYPTO.aesCipherMode = environment.getRequiredProperty("crypto.aes-cipher-mode");
+ CRYPTO.aesDefaultKey = environment.getRequiredProperty("crypto.aes-default-key");
+ CRYPTO.aesDefaultAad = environment.getRequiredProperty("crypto.aes-default-aad");
+ }
+
+ /**
+ * get PrivateKey
+ *
+ * @return PrivateKey
+ */
+ public static byte[] getPrivateKey() {
+ KeyGenerator keygen = null;
+ try {
+ keygen = KeyGenerator.getInstance("AES");
+ } catch (NoSuchAlgorithmException e) {
+ log.error(e.getMessage(), e);
+ }
+
+ if (keygen != null) {
+ keygen.init(AESUtil.PRIVATE_KEY_LENGTH);
+ return keygen.generateKey().getEncoded();
+ }
+ return new byte[0];
+ }
+
+ /**
+ * gcmEncrypt
+ *
+ * @param input input
+ * @param key key
+ * @param aadStr aadStr
+ * @return String
+ */
+ public static String gcmEncrypt(String input, String key, String aadStr) {
+ byte[] data = input.getBytes(StandardCharsets.UTF_8);
+ byte[] privateKey = hex2byte(key);
+ byte[] iv = genRandomBytes();
+ int tagLength = GCM_TAG_LENGTH;
+ byte[] aad = StringUtils.isBlank(aadStr) ? null : aadStr.getBytes(StandardCharsets.UTF_8);
+ byte[] cipherData = Optional.ofNullable(gcmEncrypt(data, privateKey, iv, tagLength, aad))
+ .orElseThrow(() -> new BaseException("Parsing exceptions"));
+
+ byte[] ivLengthByteArray = int2ByteArray(iv.length);
+ byte[] tagLengthByteArray = int2ByteArray(tagLength);
+ int aadLength = aad == null ? 0 : aad.length;
+ byte[] addLengthByteArray = int2ByteArray(aadLength);
+
+ byte[] result = new byte[12 + iv.length + aadLength + cipherData.length];
+ System.arraycopy(ivLengthByteArray, 0, result, 0, 4);
+ System.arraycopy(tagLengthByteArray, 0, result, 4, 4);
+ System.arraycopy(addLengthByteArray, 0, result, 8, 4);
+ System.arraycopy(iv, 0, result, 12, iv.length);
+ if (aad != null) {
+ System.arraycopy(aad, 0, result, 12 + iv.length, aadLength);
+ }
+ System.arraycopy(cipherData, 0, result, 12 + iv.length + aadLength, cipherData.length);
+ return byte2Hex(result);
+ }
+
+ /**
+ * gcmDecrypt
+ *
+ * @param input input
+ * @param key key
+ * @return String
+ */
+ public static String gcmDecrypt(String input, String key) {
+ byte[] data = hex2byte(input);
+ byte[] paramLength = new byte[4];
+
+ System.arraycopy(data, 0, paramLength, 0, 4);
+ int ivLength = byteArray2Int(paramLength);
+ byte[] iv = new byte[ivLength];
+ System.arraycopy(data, 12, iv, 0, ivLength);
+ System.arraycopy(data, 4, paramLength, 0, 4);
+ int tagLength = byteArray2Int(paramLength);
+ System.arraycopy(data, 8, paramLength, 0, 4);
+
+ int aadLength = byteArray2Int(paramLength);
+ byte[] aad = aadLength == 0 ? null : new byte[aadLength];
+ if (aad != null) {
+ System.arraycopy(data, 12 + ivLength, aad, 0, aadLength);
+ }
+
+ byte[] cipherData = new byte[data.length - ivLength - aadLength - 12];
+ System.arraycopy(data, 12 + ivLength + aadLength, cipherData, 0, cipherData.length);
+
+ byte[] privateKey = hex2byte(key);
+ return new String(gcmDecrypt(cipherData, privateKey, iv, tagLength, aad));
+ }
+
+ private static byte[] gcmEncrypt(byte[] data, byte[] privateKey, byte[] iv, int tagLength, byte[] aad) {
+ try {
+ Cipher cipher = cipher(privateKey, iv, tagLength, Cipher.ENCRYPT_MODE);
+ return handle(data, cipher, aad);
+ } catch (GeneralSecurityException e) {
+ throw new BaseException("Parsing exceptions");
+ }
+ }
+
+ private static byte[] gcmDecrypt(byte[] data, byte[] privateKey, byte[] iv, int tagLength, byte[] aad) {
+ try {
+ Cipher cipher = cipher(privateKey, iv, tagLength, Cipher.DECRYPT_MODE);
+ return handle(data, cipher, aad);
+ } catch (GeneralSecurityException e) {
+ throw new BaseException("Parsing exceptions");
+ }
+ }
+
+ private static Cipher cipher(byte[] privateKey, byte[] iv, int tagLength, int mode)
+ throws GeneralSecurityException {
+ Cipher cipher = Cipher.getInstance(CRYPTO.aesCipherMode);
+ SecretKey secretKey = new SecretKeySpec(privateKey, "AES");
+ GCMParameterSpec parameterSpec = new GCMParameterSpec(tagLength * Byte.SIZE, iv);
+ cipher.init(mode, secretKey, parameterSpec);
+ return cipher;
+ }
+
+ private static byte[] handle(byte[] data, Cipher cipher, byte[] aad) throws GeneralSecurityException {
+ if (aad != null) {
+ cipher.updateAAD(aad);
+ }
+ return cipher.doFinal(data);
+ }
+
+ private static byte[] genRandomBytes() {
+ byte[] result = new byte[AESUtil.GCM_IV_LENGTH];
+ SecureRandom rand = RandomUtil.getRandom();
+ rand.nextBytes(result);
+ return result;
+ }
+
+ private static byte[] int2ByteArray(int i) {
+ byte[] result = new byte[4];
+ result[0] = (byte) ((i >> 24) & 0xFF);
+ result[1] = (byte) ((i >> 16) & 0xFF);
+ result[2] = (byte) ((i >> 8) & 0xFF);
+ result[3] = (byte) (i & 0xFF);
+ return result;
+ }
+
+ private static int byteArray2Int(byte[] bytes) {
+ int result = 0;
+ for (int i = 0; i < 4; i++) {
+ int shift = (3 - i) * 8;
+ result += (bytes[i] & 0xFF) << shift;
+ }
+ return result;
+ }
+
+ private static String byte2Hex(byte[] bytes) {
+ StringBuilder sb = new StringBuilder(16);
+ for (byte b : bytes) {
+ String hex = Integer.toHexString(b & 0xFF);
+ if (hex.length() < 2) {
+ sb.append(0);
+ }
+ sb.append(hex.toUpperCase(Locale.US));
+ }
+ return sb.toString();
+ }
+
+ private static byte[] hex2byte(String hexString) {
+ byte[] bytes = new byte[hexString.length() / 2];
+ for (int i = 0; i < hexString.length(); i += 2) {
+ bytes[i / 2] =
+ (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
+ + Character.digit(hexString.charAt(i + 1), 16));
+ }
+ return bytes;
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/util/ApiCenterUtil.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/util/ApiCenterUtil.java
new file mode 100644
index 0000000..637885b
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/util/ApiCenterUtil.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.util;
+
+import com.huawei.ic.openlab.cloudtest.entity.SystemParams;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.conn.ssl.TrustStrategy;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
+import org.springframework.web.client.RestClientException;
+import org.springframework.web.client.RestTemplate;
+import org.springframework.web.util.UriComponentsBuilder;
+
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.X509Certificate;
+import java.util.Objects;
+
+import javax.net.ssl.SSLContext;
+
+/**
+ * API网关的接口工具类
+ *
+ * @author kongcaizhi
+ * @since 2022-10-24
+ */
+@Slf4j
+public class ApiCenterUtil {
+ private static final String VALIDATED_TOKEN_SUCCESS_CODE = "200";
+
+ private static HttpHeaders getBasicHttpHeaders(SystemParams systemParams) {
+ HttpHeaders headers = new HttpHeaders();
+ headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
+ headers.add("X-HW-ID", systemParams.getAppId());
+ headers.add("X-HW-APPKEY", systemParams.getAppKey());
+ return headers;
+ }
+
+ private static RestTemplate restTemplate() throws KeyStoreException, NoSuchAlgorithmException,
+ KeyManagementException {
+ TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
+ SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom()
+ .loadTrustMaterial(null, acceptingTrustStrategy)
+ .build();
+ SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);
+ CloseableHttpClient httpClient = HttpClients.custom()
+ .setSSLSocketFactory(csf)
+ .build();
+
+ HttpComponentsClientHttpRequestFactory requestFactory =
+ new HttpComponentsClientHttpRequestFactory();
+ requestFactory.setHttpClient(httpClient);
+
+ return new RestTemplate(requestFactory);
+ }
+
+ /**
+ * 向API网关验证token是否有效
+ *
+ * @param systemParams 系统参数
+ * @param token token
+ * @param taskDeviceId taskDeviceId
+ * @return boolean 是否有效
+ */
+ public static boolean validateToken(SystemParams systemParams, String token, String taskDeviceId) {
+ // 添加请求头
+ HttpEntity request = new HttpEntity<>(null, getBasicHttpHeaders(systemParams));
+
+ // 发送GET请求
+ try {
+ UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(systemParams.getKunpengServiceUrl())
+ .queryParam("sessionId", token)
+ .queryParam("token", taskDeviceId)
+ .queryParam("tag", 1);
+ String requestUrl = builder.build().encode().toUriString();
+ ResponseEntity response = restTemplate().exchange(requestUrl, HttpMethod.GET, request,
+ ValidatedResp.class);
+
+ log.info("request apiwg check token return{}", JSONObject.toJSONString(response.getBody()));
+ if (response.getStatusCode().is2xxSuccessful() && response.hasBody()
+ && VALIDATED_TOKEN_SUCCESS_CODE.equals(Objects.requireNonNull(response.getBody()).getCode())) {
+ return true;
+ } else {
+ return false;
+ }
+ } catch (KeyStoreException | NoSuchAlgorithmException | KeyManagementException | RestClientException ex) {
+ log.error("request apiwg check taskDeviceId {} exception {}", taskDeviceId,
+ ex.getLocalizedMessage());
+ return false;
+ }
+ }
+
+ @Data
+ private static class ValidatedResp {
+ private String code;
+ private String msg;
+ private String data;
+ @JsonProperty("success")
+ private Boolean isSuccess;
+ }
+}
diff --git a/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/util/Constants.java b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/util/Constants.java
new file mode 100644
index 0000000..5ca52e6
--- /dev/null
+++ b/component/CloudTest/src/main/java/com/huawei/ic/openlab/cloudtest/util/Constants.java
@@ -0,0 +1,789 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
+ */
+
+package com.huawei.ic.openlab.cloudtest.util;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+/**
+ * Constants
+ *
+ * @author kongcaizhi
+ * @since 2022-10-24
+ */
+public final class Constants {
+ /**
+ * TEST_PASSED
+ */
+ public static final String TEST_PASSED = "passed";
+
+ /**
+ * TEST_FAILED
+ */
+ public static final String TEST_FAILED = "failed";
+
+ /**
+ * TEST_SKIPPED
+ */
+ public static final String TEST_SKIPPED = "skipped";
+
+ /**
+ * CLOUD_LAB_TEST_SUBMIT
+ */
+ public static final Integer CLOUD_LAB_TEST_SUBMIT = 0;
+
+ /**
+ * CLOUD_LAB_TEST_START
+ */
+ public static final Integer CLOUD_LAB_TEST_START = 1;
+
+ /**
+ * CLOUD_LAB_TEST_FINISH
+ */
+ public static final Integer CLOUD_LAB_TEST_FINISH = 2;
+
+ /**
+ * CLOUD_LAB_TEST_EXCEPTION
+ */
+ public static final Integer CLOUD_LAB_TEST_EXCEPTION = 3;
+
+ /**
+ * CLOUD_LAB_TEST_HALT
+ */
+ public static final Integer CLOUD_LAB_TEST_HALT = 4;
+
+ /**
+ * TAR_FILE_TOO_BIG
+ */
+ public static final String TAR_FILE_TOO_BIG = "上传的文件解压后不能超过100M,请重新上传.";
+
+ /**
+ * FILE_TOO_BIG
+ */
+ public static final String FILE_TOO_BIG = "上传的文件不能超过100M,请重新上传.";
+
+ /**
+ * CONNECT_EXCEPTION_DESC
+ */
+ public static final String CONNECT_EXCEPTION_DESC = "连接异常,请检查登录密码.";
+
+ /**
+ * TASK_DUPLICATE
+ */
+ public static final String TASK_DUPLICATE = "%s服务器正在测试中,请勿重复提交.";
+
+ /**
+ * TEMPLATE_DECOMPRESSION_ERROR
+ */
+ public static final String TEMPLATE_DECOMPRESSION_ERROR = "请下载模板,根据模板修改,上传修改后的压缩文件";
+
+ /**
+ * FILE_FAILED_VIRUS_SCAN
+ */
+ public static final String FILE_FAILED_VIRUS_SCAN = "文件没有通过病毒扫描,请重新上传";
+
+ /**
+ * 正常
+ */
+ public static final String UPLOAD_FILE_STATUS_NORMAL = "00";
+
+ /**
+ * 已删除
+ */
+ public static final String UPLOAD_FILE_STATUS_DELETE = "01";
+
+ /**
+ * 安全检查不通过
+ */
+ public static final String UPLOAD_FILE_STATUS_SCAN_FAIL = "02";
+
+ /**
+ * 文件太大
+ */
+ public static final String UPLOAD_FILE_STATUS_TOO_BIG = "03";
+
+ /**
+ * 文件异常
+ */
+ public static final String UPLOAD_FILE_STATUS_EXCEPTION = "04";
+
+ /**
+ * 安全测试文件缺失或者读取失败
+ */
+ public static final String SAFETY_FILE_LOSS = "安全测试文件缺失或者读取失败";
+
+ /**
+ * SAFETY_FILE_LOSS_EN
+ */
+ public static final String SAFETY_FILE_LOSS_EN = "The security test file is missing or cannot be read";
+
+ /**
+ * HCS_DESC
+ */
+ public static final String HCS_DESC = "硬件包含鲲鹏芯片,符合要求";
+
+ /**
+ * PERFORMANCE_TEST_ID
+ */
+ public static final String PERFORMANCE_TEST_ID = "Performance_Test_1";
+
+ /**
+ * TASK_DOES_NOT_EXIST
+ */
+ public static final String TASK_DOES_NOT_EXIST = "任务不存在";
+
+ /**
+ * TASK_HAS_FINISHED
+ */
+ public static final String TASK_HAS_FINISHED = "测试已结束";
+
+ /**
+ * FAILED_TO_STOP_TASK
+ */
+ public static final String FAILED_TO_STOP_TASK = "停止测试任务失败";
+
+ /**
+ * PERFORMANCE_TESTING
+ */
+ public static final String PERFORMANCE_TESTING = "性能测试中";
+
+ /**
+ * START_TEST_STRING
+ */
+ public static final String START_TEST_STRING = "自动化测试采集工具开始执行";
+
+ /**
+ * START_TEST_STRING_EN
+ */
+ public static final String START_TEST_STRING_EN = "The automatic test tool starts to run.";
+
+ /**
+ * DEPENDENCY_INSTALL_FAILURE_DESC
+ */
+ public static final String DEPENDENCY_INSTALL_FAILURE_DESC = "依赖软件安装失败";
+
+ /**
+ * MQS_STATUS_ONGOING
+ */
+ public static final String MQS_STATUS_ONGOING = "ongoing";
+
+ /**
+ * MQS_STATUS_FINISH
+ */
+ public static final String MQS_STATUS_FINISH = "finished";
+
+ /**
+ * MQS_STATUS_EXCEPTION
+ */
+ public static final String MQS_STATUS_EXCEPTION = "exception";
+
+ /**
+ * 依赖软件安装
+ */
+ public static final String DEPENDENCY_INSTALL_DESC = "0-1";
+
+ /**
+ * 应用软件启动
+ */
+ public static final String APP_START_DESC = "0-2";
+
+ /**
+ * 应用软件停止
+ */
+ public static final String APP_STOP_DESC = "0-3";
+
+ /**
+ * 安全测试
+ */
+ public static final String SECURITY_TEST_DESC = "1";
+
+ /**
+ * 可靠性测试
+ */
+ public static final String RELIABILITY_TEST_DESC = "2";
+
+ /**
+ * 兼容性测试
+ */
+ public static final String COMPATIBILITY_TEST_DESC = "3";
+
+ /**
+ * 功能测试
+ */
+ public static final String FUNCTION_TEST_DESC = "4";
+
+ /**
+ * 性能测试
+ */
+ public static final String PERFORMANCE_TEST_DESC = "5";
+
+ /**
+ * 测试状态-中
+ */
+ public static final String TEST_PROCESSING = "0";
+
+ /**
+ * 测试状态-完成
+ */
+ public static final String TEST_FINISHED_CN = "1";
+
+ /**
+ * 测试状态-失败
+ */
+ public static final String TEST_FAILURE_CN = "2";
+
+ /**
+ * 测试状态-异常
+ */
+ public static final String TEST_EXCEPTION_CN = "异常";
+
+ /**
+ * T测试状态-正常
+ */
+ public static final String TEST_NORMAL_CN = "正常";
+
+ /**
+ * RELIABILITY_START_APP_FAIL_CODE
+ */
+ public static final String RELIABILITY_START_APP_FAIL_CODE = "0911";
+
+ /**
+ * OS_PATTERN_CN
+ */
+ public static final String OS_PATTERN_CN = "#\\d{4}-\\d{2}-\\d{2}\\s+(20|21|22|23|[0-1]\\d)"
+ + ":[0-5]\\d:[0-5]\\d#info#1#(当前的操作系统版本是|The current OS version is)(.*)(.|.)";
+
+ /**
+ * APPLICATION_NAMES
+ */
+ public static final String APPLICATION_NAMES = "^application_names=(.+)";
+
+ /**
+ * START_APP_COMMANDS
+ */
+ public static final String START_APP_COMMANDS = "^start_app_commands=(.+)";
+
+ /**
+ * STOP_APP_COMMANDS
+ */
+ public static final String STOP_APP_COMMANDS = "^stop_app_commands=(.+)";
+
+ /**
+ * CLAM_RESULT_PATTERN
+ */
+ public static final String CLAM_RESULT_PATTERN = "Infected files: (.+)";
+
+ /**
+ * 功能测试内存 SHELL_UNIT_RUN_PATTERN
+ */
+ public static final String SHELL_UNIT_RUN_PATTERN = "^Ran \\\u001B\\[1;36m(.*)\\\u001B\\[0m test";
+
+ /**
+ * 功能测试内存 SHELL_UNIT_TEST_PATTERN
+ */
+ public static final String SHELL_UNIT_TEST_PATTERN = "^-+ Test file name : (.*).sh -+";
+
+ /**
+ * 功能测试内存 SHELL_UNIT_FAILED_PATTERN
+ */
+ public static final String SHELL_UNIT_FAILED_PATTERN = "^\\\u001B\\[1;31mFAILED\\\u001B\\[0m \\(\\\u001B\\[1;"
+ + "31mfailures=(.*)\\\u001B\\[0m\\)";
+
+ /**
+ * PYTEST_SUCCESS_PATTERN
+ */
+ public static final String PYTEST_SUCCESS_PATTERN = "^=+ (.*) passed in .* =+";
+
+ /**
+ * PYTEST_RUN_PATTERN
+ */
+ public static final String PYTEST_RUN_PATTERN = "^-+ Test file name : (.*).py -+";
+
+ /**
+ * PYTEST_FAILED_PATTERN
+ */
+ public static final String PYTEST_FAILED_PATTERN = "^=+ (.*) failed, (.*) passed in .*=+";
+
+ /**
+ * APP_PACKAGE_TEST_TOPIC
+ */
+ public static final String APP_PACKAGE_TEST_TOPIC = "App_Package_Test";
+
+ /**
+ * SECURITY_SCAN_TAG
+ */
+ public static final String SECURITY_SCAN_TAG = "Security_Scan";
+
+ /**
+ * INFO_TEST_CASE_RESULT_MAP
+ */
+ public static final Map INFO_TEST_CASE_RESULT_MAP =
+ Collections.unmodifiableMap(new HashMap() {
+ {
+ put("FAILED_TO_START_APP", new InfoTestCaseResult(
+ TEST_FAILED, "软件启动失败.", "Failed to start the software."));
+ put("SUCCESS_TO_START_APP", new InfoTestCaseResult(
+ TEST_PASSED, "", ""));
+ put("FAILED_TO_RELIABLE_TEST", new InfoTestCaseResult(
+ TEST_FAILED, "强制杀死进程,启动失败,异常测试失败.",
+ "After the process was forcibly killed,"
+ + " the process failed to be restarted, and exception test failed."));
+ put("SUCCESS_TO_RELIABLE_TEST", new InfoTestCaseResult(
+ TEST_PASSED, "", ""));
+ put("FAILED_TO_STOP_APP", new InfoTestCaseResult(
+ TEST_FAILED, "软件停止失败.", "Failed to stop the software."));
+ put("SUCCESS_TO_STOP_APP", new InfoTestCaseResult(
+ TEST_PASSED, "", ""));
+ put("FILE_NOT_EXIT", new InfoTestCaseResult(
+ TEST_FAILED, "测试结果中没有兼容性测试工具的日志文件.",
+ "The compressed file package does not contain"
+ + " the log file of the compatibility test tool."));
+ put("NO_START_APP", new InfoTestCaseResult(TEST_FAILED, "没有执行软件启动.",
+ "You have no started the software."));
+ put("NO_STOP_APP", new InfoTestCaseResult(TEST_FAILED, "没有执行软件停止.",
+ "You have no stop the software."));
+ put("NO_RELIABLE_TEST", new InfoTestCaseResult(TEST_FAILED, "没有执行可靠性测试.",
+ "You have no conducted the reliability test."));
+ put("UNZIP_ERROR", new InfoTestCaseResult(TEST_FAILED, "测试结果解压错误.",
+ "An error occurred when decompressing the log file "
+ + "of the test tool from the uploaded file package."));
+ put("READ_ERROR", new InfoTestCaseResult(TEST_FAILED, "测试结果读取错误.",
+ "An error occurred when reading the log file"
+ + " of the test tool from the uploaded file package."));
+ }
+ });
+
+ /**
+ * SOFTWARE_COMPARE_DESC_LIST
+ */
+ public static final List SOFTWARE_COMPARE_DESC_LIST = Collections.unmodifiableList(
+ Arrays.asList("未匹配到相应软件:%s", "兼容性测试配置文件填写的应用软件为:%s",
+ "兼容性测试配置文件应用软件名称为空", "没有找到进程快照文件", "解析配置文件和软件进程栈信息出错"));
+
+ /**
+ * SOFTWARE_COMPARE_DESC_EN_LIST
+ */
+ public static final List SOFTWARE_COMPARE_DESC_EN_LIST = Collections.unmodifiableList(
+ Arrays.asList(
+ "No matching software %s found.", "The application software recorded in the compatibility test "
+ + "configuration file is %s",
+ "The name of the application software in the compatibility test configuration file is %s.",
+ "Cannot find the process snapshot file in the uploaded file package.",
+ "An error occurred when reading the process snapshot file in the uploaded file package."));
+
+ /**
+ * COMPATIBILITY_DESC_LIST
+ */
+ public static final List COMPATIBILITY_DESC_LIST = Collections.unmodifiableList(
+ Arrays.asList(
+ "被测试软件启动前采集%1$s资源利用率与被测试软件停止后%1$s利用率之间的波动为%2$,.2f %%.",
+ "被测试软件启动前采集%1$s资源利用率与被测试软件停止后%1$s利用率之间的波动为%2$,.2f %%,%3$s 1.00 %% .",
+ "被测试软件启动前采集%1$s资源利用率与被测试软件停止后%1$s资源利用率文件解析出错.",
+ "被测试软件启动前采集%1$s资源利用率与被测试软件停止后%1$s资源利用率文件缺失.",
+ "根据端口扫描的结果,结合软件端口矩阵,合适是否存在未知端口,并澄清原因.", "%s协议扫描结果如下:",
+ "被测试软件启动前采集的网卡资源%1$s数据与被测软件停止后采集网卡资源%1$s数据之间的波动为%2$,"
+ + ".2f %%,%s测试前波动的1.00%%.",
+ "被测试软件启动前采集的网卡资源%1$s数据与被测软件停止后采集网卡资源%1$s数据之间的波动为%2$,.2f %%."));
+
+ /**
+ * COMPATIBILITY_DESC_EN_LIST
+ */
+ public static final List COMPATIBILITY_DESC_EN_LIST = Collections.unmodifiableList(
+ Arrays.asList(
+ "The change rate of the %s usage collected before the tested software was started "
+ + "and after the target software was stopped is %.2f %%.",
+ "The change rate of the %s usage collected before the tested software was started "
+ + "and after the target software was stopped is %.2f %%, which is %s than 1.00%%.",
+ "An error occurred when parsing the resource files related to %s,"
+ + "before the tested software was started and after the software was stopped.",
+ "An error occurred when reading the resource files related to %s,"
+ + "before the tested software was started and after the software was stopped.",
+ "Check whether unknown ports are opened according to the port scanning "
+ + "result and the tested software port matrix, and locate the cause.",
+ "The scanning result of the %s protocols is as follows:",
+ "The data %s by the NIC fluctuates by %.2f %% before the tested software was "
+ + "started and after the tested software was stopped,"
+ + " which is%s than 1.00%% before the test.",
+ "The data %s by the NIC fluctuates by %.2f %% before the tested software was "
+ + "started and after the software was stopped."
+ ));
+
+ /**
+ * PERFORMANCE_DESC_LIST
+ */
+ public static final List PERFORMANCE_DESC_LIST = Collections.unmodifiableList(
+ Arrays.asList(
+ "压力测试期间%s 资源波动值为%.2f %%,%s 5.00%%.", "后续可结合实际业务澄清波动合理性",
+ "压力测试期间%s 资源文件读取出错.", "压力测试期间%s 资源文件缺失.",
+ "压力测试期间网卡%s数据波动是%.2f %%.", "压力测试期间网卡%s数据波动是%.2f %%,%s 5.00%%."
+ ));
+
+ /**
+ * PERFORMANCE_DESC_EN_LIST
+ */
+ public static final List