mirror of
https://gitee.com/mao-peng/MangoTestingPlatform.git
synced 2025-12-06 11:59:15 +08:00
增加了对minio的配置
This commit is contained in:
@@ -3,17 +3,21 @@ uiautomator2==3.2.5
|
||||
pywinauto==0.6.8
|
||||
uiautodev==0.5.0
|
||||
locust==2.27.0
|
||||
|
||||
mangokit==1.3.3
|
||||
mangoui==3.0.14
|
||||
|
||||
websockets==10.4
|
||||
websocket-client==1.5.1
|
||||
|
||||
assertpy==1.1
|
||||
deepdiff==8.0.1
|
||||
adbutils==2.7.0
|
||||
gevent==24.2.1
|
||||
|
||||
pyinstaller==6.11.1
|
||||
retrying==1.3.4
|
||||
Pympler==1.0.1
|
||||
psutil==5.9.5
|
||||
|
||||
adbutils==2.7.0
|
||||
gevent==24.2.1
|
||||
deepdiff==8.0.1
|
||||
|
||||
|
||||
@@ -13,26 +13,26 @@ from src.exceptions import ERROR_MSG_0007, ToolsError
|
||||
from src.network.http.http_base import HttpBase
|
||||
from src.tools import project_dir
|
||||
from src.tools.log_collector import log
|
||||
|
||||
from src.settings.settings import IS_MINIO
|
||||
|
||||
class HttpClientApi(HttpBase):
|
||||
@classmethod
|
||||
def download_file(cls, file_name):
|
||||
response = requests.get(urljoin(cls.get_host(), f'files/{file_name}'), cls.headers)
|
||||
file_path = project_dir.upload()
|
||||
try:
|
||||
with open(fr'{file_path}\{file_name}', 'wb') as f:
|
||||
f.write(response.content)
|
||||
except FileNotFoundError:
|
||||
raise ToolsError(*ERROR_MSG_0007)
|
||||
if IS_MINIO:
|
||||
pass
|
||||
else:
|
||||
response = requests.get(urljoin(cls.get_host(), f'test_file/{file_name}'), cls.headers)
|
||||
file_path = project_dir.upload()
|
||||
try:
|
||||
with open(fr'{file_path}\{file_name}', 'wb') as f:
|
||||
f.write(response.content)
|
||||
except FileNotFoundError:
|
||||
raise ToolsError(*ERROR_MSG_0007)
|
||||
|
||||
@classmethod
|
||||
def upload_file(cls, project_product_id: int, file_path: str, file_name: str):
|
||||
file_size = os.path.getsize(file_path)
|
||||
def upload_file(cls, file_path: str, file_name: str):
|
||||
data = {
|
||||
'type': ClientTypeEnum.ACTUATOR.value,
|
||||
'project_product_id': project_product_id,
|
||||
'price': file_size,
|
||||
'name': file_name
|
||||
}
|
||||
files = [
|
||||
|
||||
@@ -46,7 +46,7 @@ class TestFilePage(TableParent):
|
||||
file_size = os.path.getsize(file_name)
|
||||
file_name_only = os.path.basename(file_name)
|
||||
files = [
|
||||
('file', (file_name_only, open(file_name, 'rb'), 'application/octet-stream')) # 根据文件类型设置 MIME 类型
|
||||
('test_file', (file_name_only, open(file_name, 'rb'), 'application/octet-stream')) # 根据文件类型设置 MIME 类型
|
||||
]
|
||||
response = self.post({
|
||||
'type': 0,
|
||||
|
||||
@@ -23,19 +23,10 @@ table_column = [
|
||||
'name': 'ID',
|
||||
'width': 7
|
||||
},
|
||||
{
|
||||
'key': 'project',
|
||||
'name': '项目名称',
|
||||
'width': 100
|
||||
},
|
||||
|
||||
{
|
||||
'key': 'name',
|
||||
'name': '文件名称',
|
||||
'width': 150
|
||||
},
|
||||
{
|
||||
'key': 'file',
|
||||
'name': '文件地址',
|
||||
},
|
||||
{
|
||||
'key': 'ope',
|
||||
|
||||
@@ -6,6 +6,7 @@ import traceback
|
||||
|
||||
from mangokit import MangoKitError
|
||||
from playwright._impl._errors import TargetClosedError, Error, TimeoutError
|
||||
|
||||
from src.enums.tools_enum import StatusEnum
|
||||
from src.enums.ui_enum import ElementOperationEnum, DriveTypeEnum
|
||||
from src.exceptions import *
|
||||
@@ -13,7 +14,6 @@ from src.models.ui_model import ElementResultModel, ElementModel
|
||||
from src.network import HTTP
|
||||
from src.services.ui.bases.android import AndroidDriver
|
||||
from src.services.ui.bases.web import WebDevice
|
||||
from src.settings import settings
|
||||
from src.tools import project_dir
|
||||
from src.tools.decorator.memory import async_memory
|
||||
from src.tools.log_collector import log
|
||||
@@ -280,4 +280,4 @@ class ElementOperation(WebDevice, AndroidDriver):
|
||||
pass
|
||||
case _:
|
||||
log.error('自动化类型不存在,请联系管理员检查!')
|
||||
HTTP.not_auth.upload_file(self.project_product_id, file_path, file_name)
|
||||
HTTP.not_auth.upload_file(file_path, file_name)
|
||||
|
||||
@@ -4,31 +4,28 @@ from mango_ui import AppConfig, MenusModel
|
||||
|
||||
from src.tools import project_dir
|
||||
|
||||
# ****************************************** DEBUG ****************************************** #
|
||||
IS_DEBUG = False
|
||||
|
||||
# ************************************** 是否弹出首页弹窗 ************************************** #
|
||||
IS_WINDOW = True
|
||||
|
||||
# ***************************************** 内存阈值 ***************************************** #
|
||||
|
||||
MEMORY_THRESHOLD = 100 # 控制内存高于多少就不可以执行用例,防止崩溃
|
||||
LOOP_MIX = 10 # 最大检查内存次数
|
||||
|
||||
# ************************************* 找不到元素循环次数 ************************************* #
|
||||
|
||||
FAILED_RETRY_TIME = 10 # 秒
|
||||
RETRY_WAITING_TIME = 0.2 # 每隔多少秒重新一次
|
||||
|
||||
# **************************************** 下面不用管 **************************************** #
|
||||
|
||||
IP = None
|
||||
PORT = None
|
||||
USERNAME = None
|
||||
PASSWORD = None
|
||||
|
||||
with open(project_dir.resource_path('src/settings/settings.json'), "r", encoding='utf-8') as f:
|
||||
STYLE = AppConfig(**json.loads(f.read()))
|
||||
|
||||
with open(project_dir.resource_path('src/settings/menus.json'), "r", encoding='utf-8') as f:
|
||||
MENUS = MenusModel(**json.loads(f.read()))
|
||||
# **************************************** 上面不用管 **************************************** #
|
||||
|
||||
# ****************************************** DEBUG ****************************************** #
|
||||
IS_DEBUG = False
|
||||
# ************************************** 是否弹出首页弹窗 ************************************** #
|
||||
IS_WINDOW = True
|
||||
# ************************************* 找不到元素循环次数 ************************************* #
|
||||
FAILED_RETRY_TIME = 10 # 秒
|
||||
RETRY_WAITING_TIME = 0.2 # 每隔多少秒重新一次
|
||||
# **************************************** 文件资源路径 **************************************** #
|
||||
IS_MINIO = False
|
||||
FILE_PATH = IP # 配置IP则代表你没有minio,如果有minio则配置mini的IP和端口
|
||||
# ***************************************** 内存阈值 ***************************************** #
|
||||
# 现在没有用到这个配置
|
||||
MEMORY_THRESHOLD = 100 # 控制内存高于多少就不可以执行用例,防止崩溃
|
||||
LOOP_MIX = 10 # 最大检查内存次数
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,6 +1,5 @@
|
||||
.git
|
||||
__pycache__
|
||||
*.pyc
|
||||
*.pyo
|
||||
*.pyd
|
||||
.venv
|
||||
|
||||
4
MangoServer/.gitignore
vendored
4
MangoServer/.gitignore
vendored
@@ -4,6 +4,6 @@
|
||||
*.log
|
||||
.logs/*
|
||||
logs/
|
||||
files/
|
||||
db.sqlite3
|
||||
test_file/
|
||||
failed_screenshot/
|
||||
PyAutoTest/settings/database.json
|
||||
@@ -81,5 +81,8 @@ class AutoSystemConfig(AppConfig):
|
||||
self.system_task.start()
|
||||
|
||||
def shutdown(self):
|
||||
self.consumer_thread.stop()
|
||||
self.system_task.join()
|
||||
try:
|
||||
self.consumer_thread.stop()
|
||||
self.system_task.join()
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
# Generated by Django 4.1.5 on 2025-01-15 12:51
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('auto_system', '0002_tasksdetails_command_alter_tasksdetails_case_id'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='filedata',
|
||||
name='file',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='filedata',
|
||||
name='price',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='filedata',
|
||||
name='project',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='filedata',
|
||||
name='failed_screenshot',
|
||||
field=models.ImageField(null=True, upload_to='failed_screenshot/', verbose_name='失败截图'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='filedata',
|
||||
name='test_file',
|
||||
field=models.FileField(null=True, upload_to='test_file/', verbose_name='文件'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='filedata',
|
||||
name='name',
|
||||
field=models.CharField(max_length=255, unique=True, verbose_name='文件名称'),
|
||||
),
|
||||
]
|
||||
@@ -23,8 +23,6 @@ class Project(models.Model):
|
||||
def delete(self, *args, **kwargs):
|
||||
if ProjectProduct.objects.filter(project=self).exists():
|
||||
raise ToolsError(300, "有关联数据,请先删除绑定的产品后再删除!")
|
||||
if FileData.objects.filter(project=self).exists():
|
||||
raise ToolsError(300, "有关联数据,请先删除绑定的测试文件后再删除!")
|
||||
super().delete(*args, **kwargs)
|
||||
|
||||
|
||||
@@ -156,17 +154,14 @@ class Database(models.Model):
|
||||
ordering = ['-id']
|
||||
|
||||
|
||||
|
||||
|
||||
class FileData(models.Model):
|
||||
""" 文件表 """
|
||||
create_time = models.DateTimeField(verbose_name="创建时间", auto_now_add=True)
|
||||
update_time = models.DateTimeField(verbose_name="修改时间", auto_now=True)
|
||||
project = models.ForeignKey(to=Project, to_field="id", on_delete=models.SET_NULL, null=True)
|
||||
type = models.SmallIntegerField(verbose_name="类型")
|
||||
name = models.CharField(verbose_name="文件名称", max_length=64)
|
||||
price = models.DecimalField(verbose_name="文件大小", max_digits=10, decimal_places=2)
|
||||
file = models.FileField(verbose_name='文件', upload_to='files/')
|
||||
name = models.CharField(verbose_name="文件名称", max_length=255, unique=True)
|
||||
test_file = models.FileField(verbose_name='文件', upload_to='test_file/', null=True)
|
||||
failed_screenshot = models.ImageField(verbose_name='失败截图', upload_to='failed_screenshot/', null=True)
|
||||
|
||||
class Meta:
|
||||
db_table = 'file_data'
|
||||
|
||||
@@ -21,6 +21,15 @@ elif DJANGO_ENV == SystemEnvEnum.MASTER.value:
|
||||
else:
|
||||
raise Exception(
|
||||
'你选择的环境不在系统默认的环境中,无法启动!!!如果你有能力修改代码请自行解决,如果没有能力请使用master即可')
|
||||
if DEBUG:
|
||||
DEFAULT_FILE_STORAGE = 'django.core.files.storage.FileSystemStorage'
|
||||
MINIO_STORAGE_ENDPOINT = None
|
||||
MINIO_STORAGE_ACCESS_KEY = None
|
||||
MINIO_STORAGE_SECRET_KEY = None
|
||||
else:
|
||||
DEFAULT_FILE_STORAGE = 'minio_storage.storage.MinioMediaStorage'
|
||||
|
||||
|
||||
nuw_dir()
|
||||
|
||||
USE_TZ = False
|
||||
@@ -45,9 +54,8 @@ INSTALLED_APPS = [
|
||||
'rest_framework', # 前后端分离
|
||||
'corsheaders', # 跨域
|
||||
'channels', # 验证
|
||||
# 'storages',
|
||||
'minio_storage',
|
||||
]
|
||||
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
|
||||
|
||||
MIDDLEWARE = [
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
|
||||
@@ -16,33 +16,22 @@ MYSQL_PASSWORD = 'mP123456&'
|
||||
MYSQL_IP = '127.0.0.1'
|
||||
|
||||
# ************************ DEBUG配置 ************************ #
|
||||
DEBUG = False
|
||||
DEBUG = True
|
||||
|
||||
# ************************ REDIS配置 ************************ #
|
||||
|
||||
REDIS = False
|
||||
# ************************ Minio配置 ************************ #
|
||||
IS_MINIO = True
|
||||
MINIO_IP = '127.0.0.1'
|
||||
MINIO_PORT = 9000
|
||||
|
||||
MINIO_STORAGE_ENDPOINT = 'localhost:9000'
|
||||
MINIO_STORAGE_ACCESS_KEY = 'HpApeT5FMen6nKyjCyep'
|
||||
MINIO_STORAGE_SECRET_KEY = 'uPh0fLlWnRFHnPOEgsGFhFm0tx8wvcFfb0Os2xPt'
|
||||
MINIO_STORAGE_USE_HTTPS = False # 如果使用 HTTPS,设置为 True
|
||||
MINIO_STORAGE_MEDIA_BUCKET_NAME = 'mango_file' # 桶名称
|
||||
MINIO_STORAGE_AUTO_CREATE_MEDIA_BUCKET = True # 桶不存在时自动创建
|
||||
|
||||
# ************************ 是否允许删除 ************************ #
|
||||
IS_DELETE = True
|
||||
|
||||
# settings.py
|
||||
|
||||
# 使用 django-storages 的 S3 后端
|
||||
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
|
||||
|
||||
# MinIO 配置
|
||||
AWS_ACCESS_KEY_ID = 'kGio1ain4dleEQwymPl5' # MinIO 的 Access Key
|
||||
AWS_SECRET_ACCESS_KEY = 'lc5YVRRl3ShbPKzDgCPGQnJjxKpKnmEuW2tz9scq' # MinIO 的 Secret Key
|
||||
AWS_STORAGE_BUCKET_NAME = 'mango' # MinIO 存储桶名称
|
||||
AWS_S3_ENDPOINT_URL = 'http://127.0.0.1:9000' # MinIO 服务器的地址
|
||||
AWS_S3_USE_SSL = False # 如果 MinIO 使用 HTTP 而不是 HTTPS,设置为 False
|
||||
AWS_S3_FILE_OVERWRITE = True # 如果不想覆盖同名文件,设置为 False
|
||||
|
||||
# **************** 个人配置,开源用户忽略这部分代码 **************** #
|
||||
# file_name = 'PyAutoTest/settings/database.json'
|
||||
# if os.path.exists(file_name):
|
||||
|
||||
@@ -21,6 +21,13 @@ DEBUG = True
|
||||
# ************************ REDIS配置 ************************ #
|
||||
|
||||
REDIS = False
|
||||
# ************************ Minio配置 ************************ #
|
||||
MINIO_STORAGE_ENDPOINT = 'localhost:9000'
|
||||
MINIO_STORAGE_ACCESS_KEY = 'HpApeT5FMen6nKyjCyep'
|
||||
MINIO_STORAGE_SECRET_KEY = 'uPh0fLlWnRFHnPOEgsGFhFm0tx8wvcFfb0Os2xPt'
|
||||
MINIO_STORAGE_USE_HTTPS = False # 如果使用 HTTPS,设置为 True
|
||||
MINIO_STORAGE_MEDIA_BUCKET_NAME = 'mango' # 桶名称
|
||||
MINIO_STORAGE_AUTO_CREATE_MEDIA_BUCKET = True # 桶不存在时自动创建
|
||||
|
||||
# ************************ 是否允许删除 ************************ #
|
||||
IS_DELETE = True
|
||||
|
||||
@@ -17,11 +17,18 @@ MYSQL_IP = 'db'
|
||||
MYSQL_PORT = 3306
|
||||
|
||||
# ************************ DEBUG配置 ************************ #
|
||||
DEBUG = True
|
||||
DEBUG = False
|
||||
|
||||
# ************************ REDIS配置 ************************ #
|
||||
|
||||
REDIS = False
|
||||
# ************************ Minio配置 ************************ #
|
||||
MINIO_STORAGE_ENDPOINT = 'localhost:9000'
|
||||
MINIO_STORAGE_ACCESS_KEY = 'HpApeT5FMen6nKyjCyep'
|
||||
MINIO_STORAGE_SECRET_KEY = 'uPh0fLlWnRFHnPOEgsGFhFm0tx8wvcFfb0Os2xPt'
|
||||
MINIO_STORAGE_USE_HTTPS = False # 如果使用 HTTPS,设置为 True
|
||||
MINIO_STORAGE_MEDIA_BUCKET_NAME = 'mango' # 桶名称
|
||||
MINIO_STORAGE_AUTO_CREATE_MEDIA_BUCKET = True # 桶不存在时自动创建
|
||||
|
||||
# ************************ 是否允许删除 ************************ #
|
||||
IS_DELETE = False
|
||||
|
||||
@@ -18,14 +18,13 @@ def ensure_path_sep(path: str) -> str:
|
||||
|
||||
|
||||
def nuw_dir():
|
||||
files = ensure_path_sep('/files')
|
||||
if not os.path.exists(files):
|
||||
os.makedirs(files)
|
||||
file = ['auto_api', 'auto_perf', 'auto_system', 'auto_ui', 'auto_user']
|
||||
for i in ['/logs', '/test_file', '/failed_screenshot', '/upload_template']:
|
||||
file = ensure_path_sep(i)
|
||||
if not os.path.exists(file):
|
||||
os.makedirs(file)
|
||||
|
||||
logs_dir = ensure_path_sep('/logs')
|
||||
if not os.path.exists(logs_dir):
|
||||
os.makedirs(logs_dir)
|
||||
for i in file:
|
||||
for i in ['auto_api', 'auto_perf', 'auto_system', 'auto_ui', 'auto_user']:
|
||||
subdirectory = os.path.join(logs_dir, i)
|
||||
if not os.path.exists(subdirectory):
|
||||
os.makedirs(subdirectory)
|
||||
|
||||
Binary file not shown.
@@ -2,4 +2,5 @@ BUILD_PATH=/
|
||||
VITE_APP_ENV='dev'
|
||||
VITE_APP_BASE_URL = 'http://127.0.0.1:8000'
|
||||
VITE_APP_SOCKET_URL = 'ws://127.0.0.1:8000/web/socket?'
|
||||
VITE_IS_INDEX_WINDOW = 'false'
|
||||
VITE_APP_MINIO_URL = 'ws://127.0.0.1:9000/mango_file'
|
||||
VITE_IS_INDEX_WINDOW = 'true'
|
||||
@@ -2,6 +2,7 @@ import Axios, { AxiosResponse } from 'axios'
|
||||
import qs from 'qs'
|
||||
|
||||
export const baseURL = import.meta.env.VITE_APP_BASE_URL
|
||||
export const minioURL = import.meta.env.VITE_APP_MINIO_URL
|
||||
export const webSocketURL = import.meta.env.VITE_APP_SOCKET_URL
|
||||
|
||||
export const CONTENT_TYPE = 'Content-Type'
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
<a-modal v-model:visible="visible" @ok="handleOk" @cancel="handleCancel">
|
||||
<template #title> 扫描二维码加群 </template>
|
||||
<a-space>
|
||||
<img alt="作者微信" :src="baseURL + '/files/author.jpg'" />
|
||||
<img alt="交流群" :src="baseURL + '/files/group.jpg'" />
|
||||
<img alt="作者微信" :src="minioURL + '/test_file/author.jpg'" />
|
||||
<img alt="交流群" :src="minioURL + '/test_file/group.jpg'" />
|
||||
</a-space>
|
||||
</a-modal>
|
||||
</template>
|
||||
@@ -40,7 +40,7 @@
|
||||
import useUserStore from '@/store/modules/user'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { websocket } from '@/utils/socket'
|
||||
import { baseURL, webSocketURL } from '@/api/axios.config'
|
||||
import {baseURL, minioURL, webSocketURL} from '@/api/axios.config'
|
||||
import { SERVER } from '@/setting'
|
||||
|
||||
const userStore = useUserStore()
|
||||
|
||||
@@ -2,21 +2,12 @@ import { useTable, useTableColumn } from '@/hooks/table'
|
||||
const table = useTable()
|
||||
export const tableColumns = useTableColumn([
|
||||
table.indexColumn,
|
||||
{
|
||||
title: '项目名称',
|
||||
key: 'project',
|
||||
dataIndex: 'project',
|
||||
},
|
||||
|
||||
{
|
||||
title: '文件名称',
|
||||
key: 'name',
|
||||
dataIndex: 'name',
|
||||
},
|
||||
{
|
||||
title: '文件地址',
|
||||
key: 'file',
|
||||
dataIndex: 'file',
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'actions',
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
</div>
|
||||
<a-upload @before-upload="beforeUpload" :show-file-list="false" />
|
||||
</a-space>
|
||||
<span> 注意:上传文件时必须要选择项目后才能进行上传 </span>
|
||||
|
||||
<a-tabs />
|
||||
<a-table
|
||||
@@ -32,9 +31,6 @@
|
||||
<template v-if="item.key === 'index'" :class="record" #cell="{ record }">
|
||||
{{ record.id }}
|
||||
</template>
|
||||
<template v-else-if="item.key === 'project'" #cell="{ record }">
|
||||
{{ record.project?.name }}
|
||||
</template>
|
||||
<template v-else-if="item.key === 'actions'" #cell="{ record }">
|
||||
<a-button
|
||||
type="text"
|
||||
|
||||
Reference in New Issue
Block a user