This commit is contained in:
fit2-zhao 2020-12-16 13:02:13 +08:00
commit 00415e6084
14 changed files with 93 additions and 1631 deletions

View File

@ -1,45 +0,0 @@
FROM alpine:latest
LABEL maintainer="support@fit2cloud.com"
ENV JMETER_VERSION "5.3"
ENV KAFKA_BACKEND_LISTENER_VERSION "1.0.4"
#定义时区参数
ENV TZ=Asia/Shanghai
RUN apk update && \
apk upgrade && \
apk add --update openjdk8 wget tar bash && \
wget https://mirrors.tuna.tsinghua.edu.cn/apache/jmeter/binaries/apache-jmeter-${JMETER_VERSION}.tgz && \
wget https://jmeter-plugins.org/files/packages/jpgc-casutg-2.9.zip && \
wget https://jmeter-plugins.org/files/packages/jpgc-tst-2.5.zip && \
wget https://github.com/metersphere/jmeter-backend-listener-kafka/releases/download/v${KAFKA_BACKEND_LISTENER_VERSION}/jmeter.backendlistener.kafka-${KAFKA_BACKEND_LISTENER_VERSION}.jar && \
wget https://github.com/metersphere/jmeter-plugins-for-apache-dubbo/releases/download/2.7.7/jmeter-plugins-dubbo-2.7.7-jar-with-dependencies.jar && \
wget -q "http://search.maven.org/remotecontent?filepath=mysql/mysql-connector-java/5.1.49/mysql-connector-java-5.1.49.jar" -O mysql-connector-java.jar && \
wget -q "http://search.maven.org/remotecontent?filepath=com/oracle/database/jdbc/ojdbc8/19.7.0.0/ojdbc8-19.7.0.0.jar" -O ojdbc8.jar && \
wget -q "http://search.maven.org/remotecontent?filepath=org/postgresql/postgresql/42.2.14/postgresql-42.2.14.jar" -O postgresql.jar && \
wget -q "http://search.maven.org/remotecontent?filepath=com/microsoft/sqlserver/mssql-jdbc/7.4.1.jre8/mssql-jdbc-7.4.1.jre8.jar" -O mssql-jdbc.jar && \
mkdir -p /opt/jmeter && \
tar -zxf apache-jmeter-${JMETER_VERSION}.tgz -C /opt/jmeter/ --strip-components=1 && \
unzip -o jpgc-casutg-2.9.zip -d /tmp/ && mv /tmp/lib/ext/jmeter-plugins-casutg-2.9.jar /opt/jmeter/lib/ext && \
unzip -o jpgc-tst-2.5.zip -d /tmp/ && mv /tmp/lib/ext/jmeter-plugins-tst-2.5.jar /opt/jmeter/lib/ext && \
mv jmeter.backendlistener.kafka-${KAFKA_BACKEND_LISTENER_VERSION}.jar /opt/jmeter/lib/ext && \
mv jmeter-plugins-dubbo-2.7.7-jar-with-dependencies.jar /opt/jmeter/lib/ext && \
mv mysql-connector-java.jar /opt/jmeter/lib/ext && \
mv ojdbc8.jar /opt/jmeter/lib/ext && \
mv postgresql.jar /opt/jmeter/lib/ext && \
mv mssql-jdbc.jar /opt/jmeter/lib/ext && \
rm -rf apache-jmeter-${JMETER_VERSION}.tgz && \
rm -rf jpgc-casutg-2.9.zip && \
rm -rf jpgc-tst-2.5.zip && \
rm -rf jmeter.backendlistener.kafka-${KAFKA_BACKEND_LISTENER_VERSION}.jar && \
rm -rf jmeter-plugins-dubbo-2.7.7-jar-with-dependencies.jar && \
rm -rf /var/cache/apk/* && \
wget -O /usr/bin/tpl https://github.com/schneidexe/tpl/releases/download/v0.5.0/tpl-linux-amd64 && \
chmod +x /usr/bin/tpl && \
ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo "$TZ" > /etc/timezone
ENV JMETER_HOME /opt/jmeter
ENV PATH $PATH:$JMETER_HOME/bin:/usr/lib/jvm/java-1.8-openjdk/bin
ADD log4j2.xml $JMETER_HOME/bin/log4j2.xml
ADD jmeter.properties $JMETER_HOME/bin/jmeter.properties

File diff suppressed because it is too large Load Diff

View File

@ -1,116 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<Configuration status="WARN" packages="org.apache.jmeter.gui.logging">
<Appenders>
<File name="jmeter-log" fileName="${sys:jmeter.logfile:-jmeter.log}" append="false">
<PatternLayout>
<pattern>%d %p %c{1.}: %m%n</pattern>
</PatternLayout>
</File>
<GuiLogEvent name="gui-log-event">
<PatternLayout>
<pattern>%d %p %c{1.}: %m%n</pattern>
</PatternLayout>
</GuiLogEvent>
<Kafka name="Kafka" topic="${env:LOG_TOPIC}">
<PatternLayout pattern="${env:REPORT_ID} ${env:RESOURCE_ID} %date %message"/>
<Property name="bootstrap.servers">${env:BOOTSTRAP_SERVERS}</Property>
</Kafka>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="jmeter-log" />
<AppenderRef ref="gui-log-event" />
<AppenderRef ref="Kafka" />
</Root>
<Logger name="org.apache.kafka" level="INFO" />
<Logger name="org.apache.jmeter.junit" level="debug" />
<!--
<Logger name="org.apache.jmeter.control" level="debug" />
<Logger name="org.apache.jmeter.testbeans" level="debug" />
<Logger name="org.apache.jmeter.engine" level="debug" />
<Logger name="org.apache.jmeter.threads" level="debug" />
<Logger name="org.apache.jmeter.gui" level="warn" />
<Logger name="org.apache.jmeter.testelement" level="debug" />
<Logger name="org.apache.jmeter.util" level="warn" />
<Logger name="org.apache.jmeter.protocol.http" level="debug" />
-->
<!-- # For CookieManager, AuthManager etc: -->
<!--
<Logger name="org.apache.jmeter.protocol.http.control" level="debug" />
<Logger name="org.apache.jmeter.protocol.ftp" level="warn" />
<Logger name="org.apache.jmeter.protocol.jdbc" level="debug" />
<Logger name="org.apache.jmeter.protocol.java" level="warn" />
<Logger name="org.apache.jmeter.testelements.property" level="debug" />
-->
<Logger name="org.apache.jorphan" level="info" />
<!--
# Apache HttpClient logging examples
-->
<!-- # Enable header wire + context logging - Best for Debugging -->
<!--
<Logger name="org.apache.http" level="debug" />
<Logger name="org.apache.http.wire" level="error" />
-->
<!-- # Enable full wire + context logging -->
<!-- <Logger name="org.apache.http" level="debug" /> -->
<!-- # Enable context logging for connection management -->
<!-- <Logger name="org.apache.http.impl.conn" level="debug" /> -->
<!-- # Enable context logging for connection management / request execution -->
<!--
<Logger name="org.apache.http.impl.conn" level="debug" />
<Logger name="org.apache.http.impl.client" level="debug" />
<Logger name="org.apache.http.client" level="debug" />
-->
<!--
# Reporting logging configuration examples
-->
<!-- # If you want to debug reporting, uncomment this line -->
<!-- <Logger name="org.apache.jmeter.report" level="debug" /> -->
<!--
# More user specific logging configuration examples.
-->
<!-- <Logger name="org.apache.jorphan.reflect" level="debug" /> -->
<!--
# Warning: Enabling the next debug line causes javax.net.ssl.SSLException: Received fatal alert: unexpected_message
for certain sites when used with the default HTTP Sampler
-->
<!--
<Logger name="org.apache.jmeter.util.HttpSSLProtocolSocketFactory" level="debug" />
<Logger name="org.apache.jmeter.util.JsseSSLManager" level="debug" />
-->
<!--
# Enable Proxy request debug
-->
<!-- <Logger name="org.apache.jmeter.protocol.http.proxy.HttpRequestHdr" level="debug" /> -->
</Loggers>
</Configuration>

View File

@ -1,14 +0,0 @@
FROM registry.fit2cloud.com/metersphere/jmeter-base:0.0.1
LABEL maintainer="support@fit2cloud.com"
EXPOSE 60000
ENV SSL_DISABLED true
ENV TESTS_DIR /test
ADD run-test.sh /run-test.sh
RUN chmod +x /run-test.sh \
&& mkdir /test \
&& mkdir /jmeter-log
WORKDIR /jmeter-log/
ENTRYPOINT /run-test.sh

View File

@ -1,3 +0,0 @@
for file in ${TESTS_DIR}/*.jmx; do
jmeter -n -t ${file} -Jserver.rmi.ssl.disable=${SSL_DISABLED}
done

View File

@ -83,8 +83,7 @@
}], }],
}, },
} }
} },
,
methods: { methods: {
saveScenario(saveAs) { saveScenario(saveAs) {
this.$refs['scenarioForm'].validate((valid) => { this.$refs['scenarioForm'].validate((valid) => {
@ -95,7 +94,7 @@
this.visible = false; this.visible = false;
if (saveAs) { if (saveAs) {
this.scenarioForm.request = JSON.stringify(this.scenarioForm.request); this.scenarioForm.request = JSON.stringify(this.scenarioForm.request);
this.$emit('saveAsEdit', this.httpForm); this.$emit('saveAsEdit', this.scenarioForm);
} else { } else {
this.$emit('refresh'); this.$emit('refresh');
} }
@ -109,7 +108,8 @@
this.scenarioForm.projectId = getCurrentProjectID(); this.scenarioForm.projectId = getCurrentProjectID();
this.scenarioForm.id = getUUID().substring(0, 8); this.scenarioForm.id = getUUID().substring(0, 8);
this.scenarioForm.protocol = this.currentProtocol; this.scenarioForm.protocol = this.currentProtocol;
if (this.currentModule != null && this.currentModule != "newId") {
if (this.currentModule && this.currentModule.id != "root") {
this.scenarioForm.modulePath = this.currentModule.method !== undefined ? this.currentModule.method : null; this.scenarioForm.modulePath = this.currentModule.method !== undefined ? this.currentModule.method : null;
this.scenarioForm.apiScenarioModuleId = this.currentModule.id; this.scenarioForm.apiScenarioModuleId = this.currentModule.id;
} }

View File

@ -57,7 +57,7 @@
}, },
projectId: "", projectId: "",
data: [], data: [],
currentModule: {}, currentModule: undefined,
} }
}, },
mounted() { mounted() {

View File

@ -59,7 +59,7 @@
import MsDialogFooter from "../../../../common/components/MsDialogFooter"; import MsDialogFooter from "../../../../common/components/MsDialogFooter";
import {WORKSPACE_ID} from '../../../../../../common/js/constants'; import {WORKSPACE_ID} from '../../../../../../common/js/constants';
import {REQ_METHOD} from "../../model/JsonData"; import {REQ_METHOD} from "../../model/JsonData";
import {getCurrentProjectID, getCurrentUser, getUUID} from "../../../../../../common/js/utils"; import {getCurrentProjectID, getCurrentUser} from "../../../../../../common/js/utils";
import {createComponent, Request} from "../jmeter/components"; import {createComponent, Request} from "../jmeter/components";
export default { export default {

View File

@ -1,25 +1,10 @@
<template> <template>
<div id="menu-bar" v-if="isRouterAlive"> <div id="menu-bar" v-if="isRouterAlive">
<el-row type="flex"> <el-row type="flex">
<project-change :project-name="currentProject"/>
<el-col :span="14"> <el-col :span="14">
<el-menu class="header-menu" :unique-opened="true" mode="horizontal" router :default-active='$route.path'> <el-menu class="header-menu" :unique-opened="true" mode="horizontal" router :default-active='$route.path'>
<el-submenu :class="{'deactivation':!isProjectActivation}"
v-permission="['test_manager','test_user','test_viewer']" index="3">
<template v-slot:title>
<span style="display: inline-block;width: 150px;white-space:nowrap; overflow:hidden; text-overflow:ellipsis;" :title="currentProject">
{{ $t('commons.project') }}: {{currentProject}}
</span>
</template>
<search-list ref="projectRecent" :options="projectRecent" :current-project.sync="currentProject"/>
<el-divider class="menu-divider"/>
<el-menu-item :index="'/setting/project/create'">
<font-awesome-icon :icon="['fa', 'plus']"/>
<span style="padding-left: 7px;">{{ $t("project.create") }}</span>
</el-menu-item>
<ms-show-all :index="'/setting/project/all'"/>
</el-submenu>
<el-menu-item :index="'/api/home'"> <el-menu-item :index="'/api/home'">
{{ $t("i18n.home") }} {{ $t("i18n.home") }}
</el-menu-item> </el-menu-item>
@ -75,10 +60,11 @@ import MsCreateButton from "../../common/head/CreateButton";
import MsCreateTest from "../../common/head/CreateTest"; import MsCreateTest from "../../common/head/CreateTest";
import {ApiEvent, LIST_CHANGE} from "@/business/components/common/head/ListEvent"; import {ApiEvent, LIST_CHANGE} from "@/business/components/common/head/ListEvent";
import SearchList from "@/business/components/common/head/SearchList"; import SearchList from "@/business/components/common/head/SearchList";
import ProjectChange from "@/business/components/common/head/ProjectSwitch";
export default { export default {
name: "MsApiHeaderMenus", name: "MsApiHeaderMenus",
components: {SearchList, MsCreateTest, MsCreateButton, MsShowAll, MsRecentList}, components: {SearchList, MsCreateTest, MsCreateButton, MsShowAll, MsRecentList, ProjectChange},
data() { data() {
return { return {
projectRecent: { projectRecent: {
@ -123,11 +109,11 @@ export default {
methods: { methods: {
registerEvents() { registerEvents() {
ApiEvent.$on(LIST_CHANGE, () => { ApiEvent.$on(LIST_CHANGE, () => {
// todo refs // // todo refs
if (!this.$refs.projectRecent) { // if (!this.$refs.projectRecent) {
return; // return;
} // }
this.$refs.projectRecent.recent(); // this.$refs.projectRecent.recent();
this.$refs.testRecent.recent(); this.$refs.testRecent.recent();
this.$refs.reportRecent.recent(); this.$refs.reportRecent.recent();
}); });

View File

@ -1,28 +0,0 @@
<template>
<span>
<el-submenu index="10">
<template v-slot:title>操作</template>
<el-input
placeholder="请输入内容"
prefix-icon="el-icon-search"
v-model="input2">
</el-input>
</el-submenu>
</span>
</template>
<script>
export default {
name: "ProjectMenu",
data() {
return {
input2: '1'
}
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,52 @@
<template>
<el-menu class="header-menu" :unique-opened="true" mode="horizontal" default-active="1">
<!-- 不激活项目路由-->
<el-menu-item index="1" v-show="false">Placeholder</el-menu-item>
<el-submenu v-permission="['test_manager','test_user','test_viewer']" index="2" popper-class="submenu">
<template v-slot:title>
<span class="project-name" :title="currentProject">
{{ $t('commons.project') }}: {{currentProject}}
</span>
</template>
<search-list :current-project.sync="currentProject"/>
<el-divider/>
<el-menu-item :index="'/setting/project/create'">
<font-awesome-icon :icon="['fa', 'plus']"/>
<span style="padding-left: 7px;">{{ $t("project.create") }}</span>
</el-menu-item>
<ms-show-all :index="'/setting/project/all'"/>
</el-submenu>
</el-menu>
</template>
<script>
import SearchList from "@/business/components/common/head/SearchList";
import MsShowAll from "@/business/components/common/head/ShowAll";
export default {
name: "ProjectSwitch",
props: {
projectName: String
},
components: {SearchList, MsShowAll},
data() {
return {
currentProject: this.projectName
}
}
}
</script>
<style scoped>
.project-name {
display: inline-block;
width: 130px;
white-space:nowrap;
overflow:hidden;
text-overflow:ellipsis;
}
.el-divider--horizontal {
margin: 0;
}
</style>

View File

@ -1,5 +1,5 @@
<template> <template>
<div v-loading="result.loading" class="search-list"> <div v-loading="result.loading">
<el-input placeholder="搜索项目" <el-input placeholder="搜索项目"
prefix-icon="el-icon-search" prefix-icon="el-icon-search"
v-model="searchString" v-model="searchString"
@ -135,7 +135,7 @@ export default {
.title { .title {
display: inline-block; display: inline-block;
padding-left: 20px; padding-left: 15px;
max-width: 200px; max-width: 200px;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;

View File

@ -1,25 +1,9 @@
<template> <template>
<div id="menu-bar"> <div id="menu-bar">
<el-row type="flex"> <el-row type="flex">
<el-col :span="10"> <project-change :project-name="currentProject"/>
<el-col :span="12">
<el-menu class="header-menu" :unique-opened="true" mode="horizontal" router :default-active='$route.path'> <el-menu class="header-menu" :unique-opened="true" mode="horizontal" router :default-active='$route.path'>
<el-submenu v-permission="['test_manager','test_user','test_viewer']"
index="3" popper-class="submenu">
<template v-slot:title>
<span style="display: inline-block;width: 150px;white-space:nowrap; overflow:hidden; text-overflow:ellipsis;" :title="currentProject">
{{ $t('commons.project') }}: {{currentProject}}
</span>
</template>
<search-list ref="projectRecent" :options="projectRecent" :current-project.sync="currentProject"/>
<el-divider/>
<el-menu-item :index="'/setting/project/create'">
<font-awesome-icon :icon="['fa', 'plus']"/>
<span style="padding-left: 7px;">{{ $t("project.create") }}</span>
</el-menu-item>
<ms-show-all :index="'/setting/project/all'"/>
</el-submenu>
<el-menu-item :index="'/performance/home'"> <el-menu-item :index="'/performance/home'">
{{ $t("i18n.home") }} {{ $t("i18n.home") }}
</el-menu-item> </el-menu-item>
@ -61,10 +45,12 @@ import MsCreateButton from "../../common/head/CreateButton";
import MsShowAll from "../../common/head/ShowAll"; import MsShowAll from "../../common/head/ShowAll";
import {LIST_CHANGE, PerformanceEvent} from "@/business/components/common/head/ListEvent"; import {LIST_CHANGE, PerformanceEvent} from "@/business/components/common/head/ListEvent";
import SearchList from "@/business/components/common/head/SearchList"; import SearchList from "@/business/components/common/head/SearchList";
import ProjectChange from "@/business/components/common/head/ProjectSwitch";
export default { export default {
name: "PerformanceHeaderMenus", name: "PerformanceHeaderMenus",
components: { components: {
ProjectChange,
SearchList, SearchList,
MsCreateButton, MsCreateButton,
MsShowAll, MsShowAll,
@ -108,11 +94,11 @@ export default {
methods: { methods: {
registerEvents() { registerEvents() {
PerformanceEvent.$on(LIST_CHANGE, () => { PerformanceEvent.$on(LIST_CHANGE, () => {
// todo refs // // todo refs
if (!this.$refs.projectRecent) { // if (!this.$refs.projectRecent) {
return; // return;
} // }
this.$refs.projectRecent.recent(); // this.$refs.projectRecent.recent();
this.$refs.testRecent.recent(); this.$refs.testRecent.recent();
this.$refs.reportRecent.recent(); this.$refs.reportRecent.recent();
}); });

View File

@ -2,25 +2,10 @@
<div id="menu-bar" v-if="isRouterAlive"> <div id="menu-bar" v-if="isRouterAlive">
<el-row type="flex"> <el-row type="flex">
<el-col :span="16"> <project-change :project-name="currentProject"/>
<el-col :span="14">
<el-menu class="header-menu" :unique-opened="true" mode="horizontal" router <el-menu class="header-menu" :unique-opened="true" mode="horizontal" router
:default-active='$route.path'> :default-active='$route.path'>
<el-submenu :class="{'deactivation':!isProjectActivation}"
v-permission="['test_manager','test_user','test_viewer']" index="3" popper-class="submenu">
<template v-slot:title>
<span style="display: inline-block;width: 150px;white-space:nowrap; overflow:hidden; text-overflow:ellipsis;" :title="currentProject">
{{ $t('commons.project') }}: {{currentProject}}
</span>
</template>
<search-list ref="projectRecent" :options="projectRecent" :current-project.sync="currentProject"/>
<el-divider/>
<el-menu-item :index="'/setting/project/create'">
<font-awesome-icon :icon="['fa', 'plus']"/>
<span style="padding-left: 7px;">{{ $t("project.create") }}</span>
</el-menu-item>
<ms-show-all :index="'/setting/project/all'"/>
</el-submenu>
<el-menu-item :index="'/track/home'"> <el-menu-item :index="'/track/home'">
{{ $t("i18n.home") }} {{ $t("i18n.home") }}
</el-menu-item> </el-menu-item>
@ -70,10 +55,11 @@ import MsRecentList from "../../common/head/RecentList";
import MsCreateButton from "../../common/head/CreateButton"; import MsCreateButton from "../../common/head/CreateButton";
import {LIST_CHANGE, TrackEvent} from "@/business/components/common/head/ListEvent"; import {LIST_CHANGE, TrackEvent} from "@/business/components/common/head/ListEvent";
import SearchList from "@/business/components/common/head/SearchList"; import SearchList from "@/business/components/common/head/SearchList";
import ProjectChange from "@/business/components/common/head/ProjectSwitch";
export default { export default {
name: "TrackHeaderMenus", name: "TrackHeaderMenus",
components: {SearchList, MsShowAll, MsRecentList, MsCreateButton}, components: {ProjectChange, SearchList, MsShowAll, MsRecentList, MsCreateButton},
data() { data() {
return { return {
testPlanViewPath: '', testPlanViewPath: '',
@ -163,11 +149,11 @@ export default {
}, },
registerEvents() { registerEvents() {
TrackEvent.$on(LIST_CHANGE, () => { TrackEvent.$on(LIST_CHANGE, () => {
// todo refs // // todo refs
if (!this.$refs.projectRecent) { // if (!this.$refs.projectRecent) {
return; // return;
} // }
this.$refs.projectRecent.recent(); // this.$refs.projectRecent.recent();
this.$refs.planRecent.recent(); this.$refs.planRecent.recent();
this.$refs.caseRecent.recent(); this.$refs.caseRecent.recent();
}); });
@ -199,4 +185,11 @@ export default {
border-bottom: white !important; border-bottom: white !important;
} }
/*.project-change {*/
/* height: 40px;*/
/* line-height: 40px;*/
/* color: inherit;*/
/* margin-left: 20px;*/
/*}*/
</style> </style>