test_connect
This commit is contained in:
parent
4c7bbe0c40
commit
7846479a1b
3
.gitignore
vendored
3
.gitignore
vendored
@ -166,7 +166,8 @@ post_output.log
|
|||||||
*.db
|
*.db
|
||||||
*.sqlite
|
*.sqlite
|
||||||
*.sqlite3
|
*.sqlite3
|
||||||
users.db
|
# users.db # 注释掉,允许跟踪users.db
|
||||||
|
!users.db # 例外规则:允许跟踪users.db
|
||||||
|
|
||||||
# Python编译文件
|
# Python编译文件
|
||||||
*.pyc
|
*.pyc
|
||||||
|
|||||||
82
add_specific_file.sh
Executable file
82
add_specific_file.sh
Executable file
@ -0,0 +1,82 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 添加特定文件到Git跟踪的脚本
|
||||||
|
# 即使文件在.gitignore中被忽略
|
||||||
|
|
||||||
|
if [ $# -eq 0 ]; then
|
||||||
|
echo "用法: $0 <文件名>"
|
||||||
|
echo "示例: $0 users.db"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
FILE="$1"
|
||||||
|
|
||||||
|
echo "🔍 添加文件到Git跟踪: $FILE"
|
||||||
|
echo "=========================="
|
||||||
|
|
||||||
|
# 检查文件是否存在
|
||||||
|
if [ ! -f "$FILE" ]; then
|
||||||
|
echo "❌ 文件不存在: $FILE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查是否在Git仓库中
|
||||||
|
if ! git rev-parse --git-dir > /dev/null 2>&1; then
|
||||||
|
echo "❌ 当前目录不是Git仓库"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查文件是否被忽略
|
||||||
|
if git check-ignore "$FILE" > /dev/null 2>&1; then
|
||||||
|
echo "⚠️ 文件 $FILE 被.gitignore忽略"
|
||||||
|
echo "使用强制添加..."
|
||||||
|
git add -f "$FILE"
|
||||||
|
else
|
||||||
|
echo "✅ 文件未被忽略,正常添加"
|
||||||
|
git add "$FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查是否成功添加
|
||||||
|
if git diff --cached --name-only | grep -q "^$FILE$"; then
|
||||||
|
echo "✅ 文件已添加到暂存区"
|
||||||
|
|
||||||
|
# 显示文件状态
|
||||||
|
echo ""
|
||||||
|
echo "📊 文件信息:"
|
||||||
|
ls -lh "$FILE"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "📋 Git状态:"
|
||||||
|
git status --short "$FILE"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
read -p "是否提交此文件? (y/N): " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
echo "💾 提交文件..."
|
||||||
|
git commit -m "Add $FILE to version control
|
||||||
|
|
||||||
|
- Force add $FILE even if ignored by .gitignore
|
||||||
|
- File size: $(ls -lh "$FILE" | awk '{print $5}')
|
||||||
|
- This file is needed for the project"
|
||||||
|
|
||||||
|
echo "✅ 文件已提交"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
read -p "是否推送到远程? (y/N): " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
git push
|
||||||
|
echo "✅ 已推送到远程"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "⚠️ 文件在暂存区,记得稍后提交:"
|
||||||
|
echo " git commit -m 'Add $FILE'"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "❌ 文件添加失败"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "🎉 完成!"
|
||||||
162
cleanup_git_tracking.sh
Executable file
162
cleanup_git_tracking.sh
Executable file
@ -0,0 +1,162 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Git跟踪清理脚本
|
||||||
|
# 用于移除已被跟踪但应该被忽略的文件和目录
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "🧹 Git跟踪清理脚本"
|
||||||
|
echo "===================="
|
||||||
|
|
||||||
|
# 检查是否在Git仓库中
|
||||||
|
if ! git rev-parse --git-dir > /dev/null 2>&1; then
|
||||||
|
echo "❌ 当前目录不是Git仓库"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 显示当前状态
|
||||||
|
echo "📊 当前Git状态:"
|
||||||
|
git status --short
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "🔍 检查需要移除跟踪的目录..."
|
||||||
|
|
||||||
|
# 检查build目录
|
||||||
|
if git ls-files | grep -q "^build/"; then
|
||||||
|
echo "📁 发现被跟踪的build目录"
|
||||||
|
BUILD_TRACKED=true
|
||||||
|
else
|
||||||
|
echo "✅ build目录未被跟踪"
|
||||||
|
BUILD_TRACKED=false
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查dist目录
|
||||||
|
if git ls-files | grep -q "^dist/"; then
|
||||||
|
echo "📁 发现被跟踪的dist目录"
|
||||||
|
DIST_TRACKED=true
|
||||||
|
else
|
||||||
|
echo "✅ dist目录未被跟踪"
|
||||||
|
DIST_TRACKED=false
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 检查其他常见的应该被忽略的文件
|
||||||
|
echo ""
|
||||||
|
echo "🔍 检查其他应该被忽略的文件..."
|
||||||
|
|
||||||
|
SHOULD_IGNORE_FILES=(
|
||||||
|
"*.pyc"
|
||||||
|
"__pycache__"
|
||||||
|
"*.log"
|
||||||
|
"*.tmp"
|
||||||
|
"*.temp"
|
||||||
|
".DS_Store"
|
||||||
|
"Thumbs.db"
|
||||||
|
"users.db"
|
||||||
|
)
|
||||||
|
|
||||||
|
FOUND_FILES=()
|
||||||
|
for pattern in "${SHOULD_IGNORE_FILES[@]}"; do
|
||||||
|
if git ls-files | grep -q "$pattern"; then
|
||||||
|
echo "📄 发现被跟踪的文件: $pattern"
|
||||||
|
FOUND_FILES+=("$pattern")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# 如果没有需要清理的内容
|
||||||
|
if [ "$BUILD_TRACKED" = false ] && [ "$DIST_TRACKED" = false ] && [ ${#FOUND_FILES[@]} -eq 0 ]; then
|
||||||
|
echo ""
|
||||||
|
echo "🎉 没有发现需要清理的跟踪文件"
|
||||||
|
echo "✅ .gitignore规则应该已经生效"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 询问用户是否继续
|
||||||
|
echo ""
|
||||||
|
echo "⚠️ 将要执行以下操作:"
|
||||||
|
if [ "$BUILD_TRACKED" = true ]; then
|
||||||
|
echo " - 移除build/目录的Git跟踪"
|
||||||
|
fi
|
||||||
|
if [ "$DIST_TRACKED" = true ]; then
|
||||||
|
echo " - 移除dist/目录的Git跟踪"
|
||||||
|
fi
|
||||||
|
for file in "${FOUND_FILES[@]}"; do
|
||||||
|
echo " - 移除$file文件的Git跟踪"
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
echo "注意: 这只会移除Git跟踪,不会删除本地文件"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
read -p "是否继续? (y/N): " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
echo "❌ 操作已取消"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "🔄 开始清理Git跟踪..."
|
||||||
|
|
||||||
|
# 移除build目录跟踪
|
||||||
|
if [ "$BUILD_TRACKED" = true ]; then
|
||||||
|
echo "📁 移除build目录跟踪..."
|
||||||
|
git rm -r --cached build/ || echo "⚠️ build目录移除失败(可能已经移除)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 移除dist目录跟踪
|
||||||
|
if [ "$DIST_TRACKED" = true ]; then
|
||||||
|
echo "📁 移除dist目录跟踪..."
|
||||||
|
git rm -r --cached dist/ || echo "⚠️ dist目录移除失败(可能已经移除)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 移除其他文件跟踪
|
||||||
|
for pattern in "${FOUND_FILES[@]}"; do
|
||||||
|
echo "📄 移除$pattern文件跟踪..."
|
||||||
|
git rm --cached -r "$pattern" 2>/dev/null || echo "⚠️ $pattern移除失败(可能已经移除)"
|
||||||
|
done
|
||||||
|
|
||||||
|
# 显示更改后的状态
|
||||||
|
echo ""
|
||||||
|
echo "📊 清理后的Git状态:"
|
||||||
|
git status --short
|
||||||
|
|
||||||
|
# 询问是否提交更改
|
||||||
|
echo ""
|
||||||
|
read -p "是否提交这些更改? (y/N): " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
echo "💾 提交更改..."
|
||||||
|
git add .gitignore
|
||||||
|
git commit -m "Remove build/, dist/ and other generated files from Git tracking
|
||||||
|
|
||||||
|
- Remove build/ directory from tracking
|
||||||
|
- Remove dist/ directory from tracking
|
||||||
|
- Update .gitignore to prevent future tracking
|
||||||
|
- These directories contain generated/compiled files that should not be versioned"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "✅ 更改已提交"
|
||||||
|
echo ""
|
||||||
|
read -p "是否推送到远程仓库? (y/N): " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
echo "🚀 推送到远程..."
|
||||||
|
git push
|
||||||
|
echo "✅ 已推送到远程仓库"
|
||||||
|
else
|
||||||
|
echo "⚠️ 记得稍后推送: git push"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "⚠️ 更改未提交,记得稍后提交:"
|
||||||
|
echo " git add .gitignore"
|
||||||
|
echo " git commit -m 'Remove generated files from Git tracking'"
|
||||||
|
echo " git push"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "🎉 清理完成!"
|
||||||
|
echo ""
|
||||||
|
echo "💡 说明:"
|
||||||
|
echo "- build/和dist/目录现在不会被Git跟踪"
|
||||||
|
echo "- 本地文件仍然存在,只是不再被版本控制"
|
||||||
|
echo "- 远程仓库在下次推送后会移除这些文件"
|
||||||
|
echo "- 其他开发者拉取更新后,这些目录也会从他们的Git跟踪中移除"
|
||||||
228
cleanup_large_files.sh
Executable file
228
cleanup_large_files.sh
Executable file
@ -0,0 +1,228 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# 大文件清理脚本
|
||||||
|
# 基于扫描结果清理Git仓库中的大文件
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "🧹 Git大文件清理脚本"
|
||||||
|
echo "===================="
|
||||||
|
|
||||||
|
# 检查是否在Git仓库中
|
||||||
|
if ! git rev-parse --git-dir > /dev/null 2>&1; then
|
||||||
|
echo "❌ 当前目录不是Git仓库"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "📋 发现的大文件问题:"
|
||||||
|
echo "- Git仓库大小: 1.2GB"
|
||||||
|
echo "- 主要问题: build/, dist/, 日志文件, 字体文件, 压缩包"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 定义要清理的文件和目录
|
||||||
|
LARGE_FILES_TO_REMOVE=(
|
||||||
|
"history_local" # 87.84MB
|
||||||
|
"mvp.zip" # 53.65MB
|
||||||
|
"log.log" # 3.25MB
|
||||||
|
"log_dms1.txt" # 2.32MB
|
||||||
|
"log_dms.txt" # 2.32MB
|
||||||
|
"log_stage.txt" # 2.07MB
|
||||||
|
"归档.zip" # 103MB
|
||||||
|
"users.db" # 数据库文件
|
||||||
|
"dms.log" # 日志文件
|
||||||
|
"post_output.log" # 日志文件
|
||||||
|
)
|
||||||
|
|
||||||
|
DIRECTORIES_TO_REMOVE=(
|
||||||
|
"build/"
|
||||||
|
"dist/"
|
||||||
|
)
|
||||||
|
|
||||||
|
echo "⚠️ 将要从Git跟踪中移除以下文件和目录:"
|
||||||
|
echo ""
|
||||||
|
echo "📁 目录:"
|
||||||
|
for dir in "${DIRECTORIES_TO_REMOVE[@]}"; do
|
||||||
|
if git ls-files | grep -q "^$dir"; then
|
||||||
|
echo " - $dir"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "📄 大文件:"
|
||||||
|
for file in "${LARGE_FILES_TO_REMOVE[@]}"; do
|
||||||
|
if git ls-files | grep -q "^$file$"; then
|
||||||
|
size=$(ls -lh "$file" 2>/dev/null | awk '{print $5}' || echo "N/A")
|
||||||
|
echo " - $file ($size)"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "注意: 这只会移除Git跟踪,不会删除本地文件"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
read -p "是否继续清理? (y/N): " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
echo "❌ 操作已取消"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "🔄 开始清理..."
|
||||||
|
|
||||||
|
# 移除目录
|
||||||
|
for dir in "${DIRECTORIES_TO_REMOVE[@]}"; do
|
||||||
|
if git ls-files | grep -q "^$dir"; then
|
||||||
|
echo "📁 移除目录: $dir"
|
||||||
|
git rm -r --cached "$dir" 2>/dev/null || echo "⚠️ $dir 移除失败"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# 移除大文件
|
||||||
|
for file in "${LARGE_FILES_TO_REMOVE[@]}"; do
|
||||||
|
if git ls-files | grep -q "^$file$"; then
|
||||||
|
echo "📄 移除文件: $file"
|
||||||
|
git rm --cached "$file" 2>/dev/null || echo "⚠️ $file 移除失败"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# 移除所有.pyc文件
|
||||||
|
echo "🐍 移除Python编译文件..."
|
||||||
|
find . -name "*.pyc" -exec git rm --cached {} \; 2>/dev/null || true
|
||||||
|
|
||||||
|
# 移除所有.log文件
|
||||||
|
echo "📝 移除日志文件..."
|
||||||
|
find . -name "*.log" -exec git rm --cached {} \; 2>/dev/null || true
|
||||||
|
|
||||||
|
# 移除所有.db文件
|
||||||
|
echo "🗄️ 移除数据库文件..."
|
||||||
|
find . -name "*.db" -exec git rm --cached {} \; 2>/dev/null || true
|
||||||
|
|
||||||
|
# 移除.DS_Store文件
|
||||||
|
echo "🍎 移除macOS系统文件..."
|
||||||
|
find . -name ".DS_Store" -exec git rm --cached {} \; 2>/dev/null || true
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "📊 清理后的状态:"
|
||||||
|
git status --short
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "🔄 更新.gitignore文件..."
|
||||||
|
|
||||||
|
# 更新.gitignore文件
|
||||||
|
cat >> .gitignore << 'EOF'
|
||||||
|
|
||||||
|
# 大文件和构建产物
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
|
*.zip
|
||||||
|
*.tar.gz
|
||||||
|
*.rar
|
||||||
|
*.7z
|
||||||
|
|
||||||
|
# 日志文件
|
||||||
|
*.log
|
||||||
|
*.log.*
|
||||||
|
dms.log
|
||||||
|
post_output.log
|
||||||
|
|
||||||
|
# 数据库文件
|
||||||
|
*.db
|
||||||
|
*.sqlite
|
||||||
|
*.sqlite3
|
||||||
|
users.db
|
||||||
|
|
||||||
|
# Python编译文件
|
||||||
|
*.pyc
|
||||||
|
*.pyo
|
||||||
|
__pycache__/
|
||||||
|
|
||||||
|
# 系统文件
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# 临时文件
|
||||||
|
*.tmp
|
||||||
|
*.temp
|
||||||
|
*~
|
||||||
|
|
||||||
|
# 大的字体文件(如果不需要版本控制)
|
||||||
|
# assets/fonts/*.ttc
|
||||||
|
# assets/fonts/*.otf
|
||||||
|
|
||||||
|
# 二进制文件
|
||||||
|
*.bin
|
||||||
|
*.exe
|
||||||
|
*.pkg
|
||||||
|
|
||||||
|
# 历史文件
|
||||||
|
history_local
|
||||||
|
mvp.zip
|
||||||
|
归档.zip
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo "✅ .gitignore已更新"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
read -p "是否提交这些更改? (y/N): " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
echo "💾 提交更改..."
|
||||||
|
git add .gitignore
|
||||||
|
git commit -m "Remove large files and build artifacts from Git tracking
|
||||||
|
|
||||||
|
- Remove build/ and dist/ directories (>500MB total)
|
||||||
|
- Remove large log files (log.log, log_dms*.txt, etc.)
|
||||||
|
- Remove binary files (history_local, mvp.zip, 归档.zip)
|
||||||
|
- Remove Python compiled files (*.pyc)
|
||||||
|
- Remove database files (*.db)
|
||||||
|
- Remove system files (.DS_Store)
|
||||||
|
- Update .gitignore to prevent future tracking of these files
|
||||||
|
|
||||||
|
This reduces repository size significantly and follows best practices
|
||||||
|
for version control by excluding generated/temporary files."
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "✅ 更改已提交"
|
||||||
|
|
||||||
|
# 显示清理效果
|
||||||
|
echo ""
|
||||||
|
echo "📈 清理效果预估:"
|
||||||
|
echo "- 移除的大文件总计: ~500MB+"
|
||||||
|
echo "- Git仓库大小将显著减少"
|
||||||
|
echo "- 远程仓库在推送后会更新"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
read -p "是否推送到远程仓库? (y/N): " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
echo "🚀 推送到远程..."
|
||||||
|
git push
|
||||||
|
echo "✅ 已推送到远程仓库"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "🎉 清理完成!"
|
||||||
|
echo ""
|
||||||
|
echo "💡 后续建议:"
|
||||||
|
echo "1. 其他开发者需要拉取更新: git pull"
|
||||||
|
echo "2. 如果需要进一步减小仓库大小,可以考虑:"
|
||||||
|
echo " git gc --aggressive --prune=now"
|
||||||
|
echo "3. 对于大的字体文件,考虑使用Git LFS"
|
||||||
|
|
||||||
|
else
|
||||||
|
echo "⚠️ 记得稍后推送: git push"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "⚠️ 更改未提交,记得稍后提交:"
|
||||||
|
echo " git add .gitignore"
|
||||||
|
echo " git commit -m 'Remove large files from Git tracking'"
|
||||||
|
echo " git push"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "🎯 清理总结:"
|
||||||
|
echo "- 移除了build/和dist/目录的跟踪"
|
||||||
|
echo "- 移除了大的日志文件和压缩包"
|
||||||
|
echo "- 移除了Python编译文件和数据库文件"
|
||||||
|
echo "- 更新了.gitignore防止未来跟踪这些文件"
|
||||||
|
echo "- 本地文件仍然存在,只是不再被Git跟踪"
|
||||||
BIN
mvp/.DS_Store
vendored
BIN
mvp/.DS_Store
vendored
Binary file not shown.
BIN
mvp/users.db
BIN
mvp/users.db
Binary file not shown.
101
quick_dms_test.py
Normal file
101
quick_dms_test.py
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
快速DMS连接测试
|
||||||
|
最简化的测试脚本,用于快速验证DMS服务连接
|
||||||
|
"""
|
||||||
|
|
||||||
|
import requests
|
||||||
|
import urllib3
|
||||||
|
import json
|
||||||
|
|
||||||
|
# 禁用SSL警告
|
||||||
|
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||||
|
|
||||||
|
def quick_test():
|
||||||
|
"""快速测试DMS连接"""
|
||||||
|
|
||||||
|
url = "https://www.dev.ideas.cnpc/api/schema/manage/schema"
|
||||||
|
|
||||||
|
print("🔧 快速DMS连接测试")
|
||||||
|
print(f"URL: {url}")
|
||||||
|
print("-" * 50)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# 忽略SSL证书验证
|
||||||
|
response = requests.get(url, verify=False, timeout=30)
|
||||||
|
|
||||||
|
print(f"✅ 连接成功!")
|
||||||
|
print(f"状态码: {response.status_code}")
|
||||||
|
print(f"响应头Content-Type: {response.headers.get('Content-Type', 'N/A')}")
|
||||||
|
|
||||||
|
if response.status_code == 200:
|
||||||
|
try:
|
||||||
|
data = response.json()
|
||||||
|
print(f"✅ JSON解析成功")
|
||||||
|
|
||||||
|
# 检查DMS响应结构
|
||||||
|
if isinstance(data, dict):
|
||||||
|
print(f"响应键: {list(data.keys())}")
|
||||||
|
|
||||||
|
if 'code' in data:
|
||||||
|
print(f"业务代码: {data['code']}")
|
||||||
|
if 'message' in data:
|
||||||
|
print(f"消息: {data['message']}")
|
||||||
|
if 'data' in data and isinstance(data['data'], dict):
|
||||||
|
if 'records' in data['data']:
|
||||||
|
records = data['data']['records']
|
||||||
|
print(f"API记录数量: {len(records)}")
|
||||||
|
|
||||||
|
# 显示前3个API记录
|
||||||
|
for i, record in enumerate(records[:3]):
|
||||||
|
print(f" API {i+1}: {record.get('name', 'N/A')} (domain: {record.get('domain', 'N/A')})")
|
||||||
|
|
||||||
|
print("\n🎉 DMS API连接正常!可以使用 --ignore-ssl 参数运行主程序")
|
||||||
|
return True
|
||||||
|
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
print(f"❌ JSON解析失败")
|
||||||
|
print(f"响应内容: {response.text[:200]}...")
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
print(f"❌ HTTP错误: {response.status_code}")
|
||||||
|
print(f"响应内容: {response.text[:200]}...")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except requests.exceptions.SSLError as e:
|
||||||
|
print(f"❌ SSL错误: {e}")
|
||||||
|
print("💡 需要使用 --ignore-ssl 参数")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except requests.exceptions.ConnectionError as e:
|
||||||
|
print(f"❌ 连接错误: {e}")
|
||||||
|
print("💡 检查网络连接和服务器地址")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except requests.exceptions.Timeout:
|
||||||
|
print(f"❌ 连接超时")
|
||||||
|
print("💡 网络可能较慢或服务器无响应")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ 其他错误: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
success = quick_test()
|
||||||
|
|
||||||
|
print("\n" + "=" * 50)
|
||||||
|
if success:
|
||||||
|
print("✅ 测试通过!")
|
||||||
|
print("\n💡 运行主程序的命令:")
|
||||||
|
print("python run_api_tests.py --dms ./assets/doc/dms/domain.json --ignore-ssl --strictness-level CRITICAL")
|
||||||
|
else:
|
||||||
|
print("❌ 测试失败!")
|
||||||
|
print("\n🔧 故障排除建议:")
|
||||||
|
print("1. 检查网络连接")
|
||||||
|
print("2. 确认服务器地址正确")
|
||||||
|
print("3. 检查防火墙设置")
|
||||||
|
print("4. 尝试使用curl命令测试:")
|
||||||
|
print(" curl -k https://www.dev.ideas.cnpc/api/schema/manage/schema")
|
||||||
|
|
||||||
|
print("=" * 50)
|
||||||
131
run_api_tests.py
131
run_api_tests.py
@ -463,12 +463,37 @@ def save_pdf_report(summary_data, output_path: Path, strictness_level: str = 'CR
|
|||||||
start_time_formatted = start_time_str
|
start_time_formatted = start_time_str
|
||||||
end_time_formatted = end_time_str
|
end_time_formatted = end_time_str
|
||||||
|
|
||||||
# 摘要内容
|
# 摘要内容 - 安全计算跳过的数量
|
||||||
|
def safe_subtract(total, passed, failed):
|
||||||
|
"""安全地计算跳过的数量"""
|
||||||
|
try:
|
||||||
|
if isinstance(total, (int, float)) and isinstance(passed, (int, float)) and isinstance(failed, (int, float)):
|
||||||
|
return max(0, total - passed - failed)
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
except:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
endpoints_tested = overall.get('endpoints_tested', 0)
|
||||||
|
endpoints_passed = overall.get('endpoints_passed', 0)
|
||||||
|
endpoints_failed = overall.get('endpoints_failed', 0)
|
||||||
|
endpoints_skipped = safe_subtract(endpoints_tested, endpoints_passed, endpoints_failed)
|
||||||
|
|
||||||
|
test_cases_executed = overall.get('total_test_cases_executed', 0)
|
||||||
|
test_cases_passed = overall.get('test_cases_passed', 0)
|
||||||
|
test_cases_failed = overall.get('test_cases_failed', 0)
|
||||||
|
test_cases_skipped = safe_subtract(test_cases_executed, test_cases_passed, test_cases_failed)
|
||||||
|
|
||||||
|
stages_executed = overall.get('total_stages_executed', 0)
|
||||||
|
stages_passed = overall.get('stages_passed', 0)
|
||||||
|
stages_failed = overall.get('stages_failed', 0)
|
||||||
|
stages_skipped = safe_subtract(stages_executed, stages_passed, stages_failed)
|
||||||
|
|
||||||
summary_text = f"""本次测试针对DMS(数据管理系统)领域数据服务进行全面的合规性验证。
|
summary_text = f"""本次测试针对DMS(数据管理系统)领域数据服务进行全面的合规性验证。
|
||||||
测试时间:{start_time_formatted} 至 {end_time_formatted},总耗时 {float(duration):.2f} 秒。
|
测试时间:{start_time_formatted} 至 {end_time_formatted},总耗时 {float(duration):.2f} 秒。
|
||||||
共测试 {overall.get('endpoints_tested', 'N/A')} 个API端点,其中 {overall.get('endpoints_passed', 'N/A')} 个通过,{overall.get('endpoints_failed', 'N/A')} 个失败,{overall.get('endpoints_tested', 'N/A')-overall.get('endpoints_passed', 'N/A')-overall.get('endpoints_failed', 'N/A')}个跳过,端点成功率为 {overall.get('endpoint_success_rate', 'N/A')}。
|
共测试 {endpoints_tested} 个API端点,其中 {endpoints_passed} 个通过,{endpoints_failed} 个失败,{endpoints_skipped} 个跳过,端点成功率为 {overall.get('endpoint_success_rate', 'N/A')}。
|
||||||
执行 {overall.get('total_test_cases_executed', 'N/A')} 个测试用例,其中 {overall.get('test_cases_passed', 'N/A')} 个通过,{overall.get('test_cases_failed', 'N/A')} 个失败,{overall.get('total_test_cases_executed', 'N/A')-overall.get('test_cases_passed', 'N/A')-overall.get('test_cases_failed', 'N/A')}个跳过,测试用例成功率为 {overall.get('test_case_success_rate', 'N/A')}。
|
执行 {test_cases_executed} 个测试用例,其中 {test_cases_passed} 个通过,{test_cases_failed} 个失败,{test_cases_skipped} 个跳过,测试用例成功率为 {overall.get('test_case_success_rate', 'N/A')}。
|
||||||
执行 {overall.get('total_stages_executed', 'N/A')} 个流程测试,其中 {overall.get('stages_passed', 'N/A')} 个通过,{overall.get('stages_failed', 'N/A')} 个失败,{overall.get('total_stages_executed', 'N/A')-overall.get('stages_passed', 'N/A')-overall.get('stages_failed', 'N/A')}个跳过,流程测试成功率为 {overall.get('stage_success_rate', 'N/A')}。"""
|
执行 {stages_executed} 个流程测试,其中 {stages_passed} 个通过,{stages_failed} 个失败,{stages_skipped} 个跳过,流程测试成功率为 {overall.get('stage_success_rate', 'N/A')}。"""
|
||||||
|
|
||||||
elements.append(to_para(summary_text, normal_style))
|
elements.append(to_para(summary_text, normal_style))
|
||||||
elements.append(Spacer(1, 20))
|
elements.append(Spacer(1, 20))
|
||||||
@ -536,6 +561,7 @@ def save_pdf_report(summary_data, output_path: Path, strictness_level: str = 'CR
|
|||||||
|
|
||||||
# 收集所有测试用例(包括endpoint用例和stage用例)
|
# 收集所有测试用例(包括endpoint用例和stage用例)
|
||||||
all_test_cases = []
|
all_test_cases = []
|
||||||
|
failed_test_cases = [] # 专门收集失败的测试用例
|
||||||
|
|
||||||
# 1. 收集endpoint测试用例
|
# 1. 收集endpoint测试用例
|
||||||
for endpoint_result in endpoint_results:
|
for endpoint_result in endpoint_results:
|
||||||
@ -543,35 +569,60 @@ def save_pdf_report(summary_data, output_path: Path, strictness_level: str = 'CR
|
|||||||
for tc in test_cases:
|
for tc in test_cases:
|
||||||
tc_severity = tc.get('test_case_severity', 'MEDIUM')
|
tc_severity = tc.get('test_case_severity', 'MEDIUM')
|
||||||
tc_severity_value = severity_levels.get(tc_severity, 3)
|
tc_severity_value = severity_levels.get(tc_severity, 3)
|
||||||
|
tc_status = tc.get('status', 'N/A')
|
||||||
|
tc_message = tc.get('message', '')
|
||||||
|
|
||||||
all_test_cases.append({
|
test_case_info = {
|
||||||
'type': 'Endpoint',
|
'type': 'Endpoint',
|
||||||
'endpoint': endpoint_result.get('endpoint_name', 'N/A'),
|
'endpoint': endpoint_result.get('endpoint_name', 'N/A'),
|
||||||
|
'endpoint_id': endpoint_result.get('endpoint_id', 'N/A'),
|
||||||
'case_name': tc.get('test_case_name', 'N/A'),
|
'case_name': tc.get('test_case_name', 'N/A'),
|
||||||
'status': tc.get('status', 'N/A'),
|
'case_id': tc.get('test_case_id', 'N/A'),
|
||||||
|
'status': tc_status,
|
||||||
|
'message': tc_message,
|
||||||
'severity': tc_severity,
|
'severity': tc_severity,
|
||||||
'severity_value': tc_severity_value,
|
'severity_value': tc_severity_value,
|
||||||
'is_required': tc_severity_value >= strictness_value
|
'is_required': tc_severity_value >= strictness_value,
|
||||||
})
|
'duration': tc.get('duration_seconds', 0),
|
||||||
|
'timestamp': tc.get('timestamp', '')
|
||||||
|
}
|
||||||
|
|
||||||
|
all_test_cases.append(test_case_info)
|
||||||
|
|
||||||
|
# 收集失败的测试用例
|
||||||
|
if tc_status in ['失败', 'FAILED', '错误', 'ERROR']:
|
||||||
|
failed_test_cases.append(test_case_info)
|
||||||
|
|
||||||
# 2. 收集stage测试用例
|
# 2. 收集stage测试用例
|
||||||
stage_results = summary_data.get('stage_results', [])
|
stage_results = summary_data.get('stage_results', [])
|
||||||
for stage_result in stage_results:
|
for stage_result in stage_results:
|
||||||
stage_name = stage_result.get('stage_name', 'N/A')
|
stage_name = stage_result.get('stage_name', 'N/A')
|
||||||
stage_status = stage_result.get('overall_status', 'N/A')
|
stage_status = stage_result.get('overall_status', 'N/A')
|
||||||
|
stage_message = stage_result.get('message', stage_result.get('error_message', ''))
|
||||||
stage_severity = 'HIGH' # Stage用例通常是高优先级
|
stage_severity = 'HIGH' # Stage用例通常是高优先级
|
||||||
stage_severity_value = severity_levels.get(stage_severity, 4)
|
stage_severity_value = severity_levels.get(stage_severity, 4)
|
||||||
|
|
||||||
# 将stage作为一个测试用例添加
|
# 将stage作为一个测试用例添加
|
||||||
all_test_cases.append({
|
stage_case_info = {
|
||||||
'type': 'Stage',
|
'type': 'Stage',
|
||||||
'endpoint': f"Stage: {stage_name}",
|
'endpoint': f"Stage: {stage_name}",
|
||||||
|
'endpoint_id': f"STAGE_{stage_name}",
|
||||||
'case_name': stage_result.get('description', stage_name),
|
'case_name': stage_result.get('description', stage_name),
|
||||||
|
'case_id': f"STAGE_{stage_name}",
|
||||||
'status': stage_status,
|
'status': stage_status,
|
||||||
|
'message': stage_message,
|
||||||
'severity': stage_severity,
|
'severity': stage_severity,
|
||||||
'severity_value': stage_severity_value,
|
'severity_value': stage_severity_value,
|
||||||
'is_required': stage_severity_value >= strictness_value
|
'is_required': stage_severity_value >= strictness_value,
|
||||||
})
|
'duration': stage_result.get('duration_seconds', 0),
|
||||||
|
'timestamp': stage_result.get('start_time', '')
|
||||||
|
}
|
||||||
|
|
||||||
|
all_test_cases.append(stage_case_info)
|
||||||
|
|
||||||
|
# 收集失败的stage用例
|
||||||
|
if stage_status in ['失败', 'FAILED', '错误', 'ERROR']:
|
||||||
|
failed_test_cases.append(stage_case_info)
|
||||||
|
|
||||||
# 分离必须和非必须的测试用例
|
# 分离必须和非必须的测试用例
|
||||||
required_cases = [case for case in all_test_cases if case['is_required']]
|
required_cases = [case for case in all_test_cases if case['is_required']]
|
||||||
@ -666,6 +717,64 @@ def save_pdf_report(summary_data, output_path: Path, strictness_level: str = 'CR
|
|||||||
|
|
||||||
elements.append(Spacer(1, 20))
|
elements.append(Spacer(1, 20))
|
||||||
|
|
||||||
|
# 失败用例详情部分
|
||||||
|
if failed_test_cases:
|
||||||
|
elements.append(to_para("失败用例详情分析", heading_style, escape=False))
|
||||||
|
elements.append(Spacer(1, 10))
|
||||||
|
|
||||||
|
# 按严重性分组失败用例
|
||||||
|
critical_failures = [tc for tc in failed_test_cases if tc['severity'] == 'CRITICAL']
|
||||||
|
high_failures = [tc for tc in failed_test_cases if tc['severity'] == 'HIGH']
|
||||||
|
medium_failures = [tc for tc in failed_test_cases if tc['severity'] == 'MEDIUM']
|
||||||
|
low_failures = [tc for tc in failed_test_cases if tc['severity'] == 'LOW']
|
||||||
|
|
||||||
|
failure_summary = f"""失败用例统计:
|
||||||
|
总计 {len(failed_test_cases)} 个失败用例,其中:
|
||||||
|
• 严重级别:{len(critical_failures)} 个
|
||||||
|
• 高级别:{len(high_failures)} 个
|
||||||
|
• 中级别:{len(medium_failures)} 个
|
||||||
|
• 低级别:{len(low_failures)} 个
|
||||||
|
|
||||||
|
以下是详细的失败原因分析:"""
|
||||||
|
|
||||||
|
elements.append(to_para(failure_summary, normal_style))
|
||||||
|
elements.append(Spacer(1, 15))
|
||||||
|
|
||||||
|
# 详细失败用例列表
|
||||||
|
for i, failed_case in enumerate(failed_test_cases, 1):
|
||||||
|
# 用例标题
|
||||||
|
case_title = f"{i}. {failed_case['case_name']}"
|
||||||
|
elements.append(to_para(case_title, ParagraphStyle('case_title', parent=normal_style, fontSize=11, textColor=colors.darkred, spaceAfter=5)))
|
||||||
|
|
||||||
|
# 用例基本信息
|
||||||
|
case_info = f"""• 用例ID:{failed_case['case_id']}
|
||||||
|
• 所属端点:{failed_case['endpoint']}
|
||||||
|
• 严重级别:{failed_case['severity']}
|
||||||
|
• 执行状态:{failed_case['status']}"""
|
||||||
|
|
||||||
|
elements.append(to_para(case_info, ParagraphStyle('case_info', parent=small_style, leftIndent=15, spaceAfter=5)))
|
||||||
|
|
||||||
|
# 失败原因
|
||||||
|
failure_reason = failed_case.get('message', '无详细错误信息')
|
||||||
|
if failure_reason:
|
||||||
|
elements.append(to_para("失败原因:", ParagraphStyle('failure_label', parent=normal_style, fontSize=10, textColor=colors.darkblue, leftIndent=15)))
|
||||||
|
|
||||||
|
# 处理长文本,确保在PDF中正确显示
|
||||||
|
if len(failure_reason) > 200:
|
||||||
|
# 对于很长的错误信息,进行适当的分段
|
||||||
|
failure_reason = failure_reason[:200] + "..."
|
||||||
|
|
||||||
|
elements.append(to_para(failure_reason, ParagraphStyle('failure_reason', parent=small_style, leftIndent=30, rightIndent=20, spaceAfter=10, textColor=colors.red)))
|
||||||
|
|
||||||
|
# 添加分隔线
|
||||||
|
if i < len(failed_test_cases):
|
||||||
|
elements.append(HRFlowable(width="80%", thickness=0.5, color=colors.lightgrey))
|
||||||
|
elements.append(Spacer(1, 10))
|
||||||
|
|
||||||
|
elements.append(Spacer(1, 20))
|
||||||
|
|
||||||
|
elements.append(Spacer(1, 20))
|
||||||
|
|
||||||
# 测试情况说明
|
# 测试情况说明
|
||||||
elements.append(to_para("测试情况说明", heading_style, escape=False))
|
elements.append(to_para("测试情况说明", heading_style, escape=False))
|
||||||
|
|
||||||
|
|||||||
181
scan_large_files.sh
Executable file
181
scan_large_files.sh
Executable file
@ -0,0 +1,181 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Git大文件扫描脚本
|
||||||
|
# 用于查找仓库中的大体积文件
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "🔍 Git仓库大文件扫描"
|
||||||
|
echo "====================="
|
||||||
|
|
||||||
|
# 检查是否在Git仓库中
|
||||||
|
if ! git rev-parse --git-dir > /dev/null 2>&1; then
|
||||||
|
echo "❌ 当前目录不是Git仓库"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 函数:格式化文件大小
|
||||||
|
format_size() {
|
||||||
|
local size=$1
|
||||||
|
if [ $size -gt 1073741824 ]; then
|
||||||
|
echo "$(echo "scale=2; $size/1073741824" | bc)GB"
|
||||||
|
elif [ $size -gt 1048576 ]; then
|
||||||
|
echo "$(echo "scale=2; $size/1048576" | bc)MB"
|
||||||
|
elif [ $size -gt 1024 ]; then
|
||||||
|
echo "$(echo "scale=2; $size/1024" | bc)KB"
|
||||||
|
else
|
||||||
|
echo "${size}B"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "📊 分析当前工作目录中的大文件..."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 1. 扫描当前工作目录中的大文件(包括未跟踪的)
|
||||||
|
echo "🗂️ 当前目录大文件 (>1MB):"
|
||||||
|
echo "文件大小 文件路径"
|
||||||
|
echo "-------- --------"
|
||||||
|
|
||||||
|
find . -type f -size +1M -not -path "./.git/*" -exec ls -lh {} \; | \
|
||||||
|
awk '{print $5 "\t" $9}' | \
|
||||||
|
sort -hr | \
|
||||||
|
head -20
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 2. 扫描Git跟踪的大文件
|
||||||
|
echo "📋 Git跟踪的大文件 (>1MB):"
|
||||||
|
echo "文件大小 文件路径"
|
||||||
|
echo "-------- --------"
|
||||||
|
|
||||||
|
git ls-files | while read file; do
|
||||||
|
if [ -f "$file" ]; then
|
||||||
|
size=$(stat -f%z "$file" 2>/dev/null || stat -c%s "$file" 2>/dev/null || echo 0)
|
||||||
|
if [ $size -gt 1048576 ]; then # 1MB
|
||||||
|
size_formatted=$(format_size $size)
|
||||||
|
printf "%-10s %s\n" "$size_formatted" "$file"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done | sort -hr | head -20
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 3. 扫描Git历史中的大文件(这个比较耗时)
|
||||||
|
echo "🕰️ 扫描Git历史中的大文件..."
|
||||||
|
echo "注意:这可能需要一些时间..."
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
echo "📚 Git历史中的大文件 (>1MB):"
|
||||||
|
echo "文件大小 提交次数 文件路径"
|
||||||
|
echo "-------- -------- --------"
|
||||||
|
|
||||||
|
# 获取所有文件的历史大小信息
|
||||||
|
git rev-list --objects --all | \
|
||||||
|
git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | \
|
||||||
|
awk '/^blob/ {print $3 "\t" $4}' | \
|
||||||
|
sort -nr | \
|
||||||
|
head -30 | \
|
||||||
|
while IFS=$'\t' read size path; do
|
||||||
|
if [ $size -gt 1048576 ]; then # 1MB
|
||||||
|
size_formatted=$(format_size $size)
|
||||||
|
# 计算文件在历史中出现的次数
|
||||||
|
count=$(git log --all --pretty=format: --name-only -- "$path" 2>/dev/null | grep -c "^$path$" || echo 0)
|
||||||
|
printf "%-10s %-8s %s\n" "$size_formatted" "$count" "$path"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 4. 显示仓库总体积信息
|
||||||
|
echo "📈 仓库体积统计:"
|
||||||
|
echo "----------------"
|
||||||
|
|
||||||
|
# .git目录大小
|
||||||
|
git_size=$(du -sh .git 2>/dev/null | cut -f1)
|
||||||
|
echo "Git仓库大小: $git_size"
|
||||||
|
|
||||||
|
# 工作目录大小(不包括.git)
|
||||||
|
work_size=$(du -sh --exclude=.git . 2>/dev/null | cut -f1 || du -sh . | cut -f1)
|
||||||
|
echo "工作目录大小: $work_size"
|
||||||
|
|
||||||
|
# 统计各类文件
|
||||||
|
echo ""
|
||||||
|
echo "📁 文件类型统计 (>100KB):"
|
||||||
|
echo "文件类型 数量 总大小"
|
||||||
|
echo "-------- ---- ------"
|
||||||
|
|
||||||
|
find . -type f -not -path "./.git/*" -exec file {} \; | \
|
||||||
|
sed 's/.*: //' | \
|
||||||
|
sort | uniq -c | \
|
||||||
|
sort -nr | \
|
||||||
|
head -10 | \
|
||||||
|
while read count type; do
|
||||||
|
printf "%-10s %-6s %s\n" "${type:0:10}" "$count" "$(echo "$type" | cut -d' ' -f1)"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# 5. 建议清理的文件类型
|
||||||
|
echo "💡 建议添加到.gitignore的文件类型:"
|
||||||
|
echo "----------------------------------------"
|
||||||
|
|
||||||
|
# 查找常见的应该被忽略的大文件
|
||||||
|
echo "🔍 发现的可能需要忽略的文件:"
|
||||||
|
|
||||||
|
# 编译文件
|
||||||
|
compiled_files=$(find . -name "*.pyc" -o -name "*.pyo" -o -name "*.class" -o -name "*.o" -o -name "*.so" -o -name "*.dll" | head -5)
|
||||||
|
if [ ! -z "$compiled_files" ]; then
|
||||||
|
echo "📄 编译文件:"
|
||||||
|
echo "$compiled_files"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 日志文件
|
||||||
|
log_files=$(find . -name "*.log" -o -name "*.log.*" | head -5)
|
||||||
|
if [ ! -z "$log_files" ]; then
|
||||||
|
echo "📄 日志文件:"
|
||||||
|
echo "$log_files"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 临时文件
|
||||||
|
temp_files=$(find . -name "*.tmp" -o -name "*.temp" -o -name "*~" -o -name ".DS_Store" | head -5)
|
||||||
|
if [ ! -z "$temp_files" ]; then
|
||||||
|
echo "📄 临时文件:"
|
||||||
|
echo "$temp_files"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 数据库文件
|
||||||
|
db_files=$(find . -name "*.db" -o -name "*.sqlite" -o -name "*.sqlite3" | head -5)
|
||||||
|
if [ ! -z "$db_files" ]; then
|
||||||
|
echo "📄 数据库文件:"
|
||||||
|
echo "$db_files"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 压缩文件
|
||||||
|
archive_files=$(find . -name "*.zip" -o -name "*.tar.gz" -o -name "*.rar" -o -name "*.7z" | head -5)
|
||||||
|
if [ ! -z "$archive_files" ]; then
|
||||||
|
echo "📄 压缩文件:"
|
||||||
|
echo "$archive_files"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "🎯 清理建议:"
|
||||||
|
echo "------------"
|
||||||
|
echo "1. 将大的编译文件、日志文件添加到.gitignore"
|
||||||
|
echo "2. 使用 'git rm --cached <file>' 移除已跟踪的大文件"
|
||||||
|
echo "3. 考虑使用Git LFS管理大的二进制文件"
|
||||||
|
echo "4. 定期清理临时文件和构建产物"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "🔧 快速清理命令:"
|
||||||
|
echo "----------------"
|
||||||
|
echo "# 移除编译文件跟踪"
|
||||||
|
echo "find . -name '*.pyc' -exec git rm --cached {} \\; 2>/dev/null"
|
||||||
|
echo ""
|
||||||
|
echo "# 移除日志文件跟踪"
|
||||||
|
echo "find . -name '*.log' -exec git rm --cached {} \\; 2>/dev/null"
|
||||||
|
echo ""
|
||||||
|
echo "# 移除数据库文件跟踪"
|
||||||
|
echo "find . -name '*.db' -exec git rm --cached {} \\; 2>/dev/null"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "✅ 扫描完成!"
|
||||||
316
test_dms_connection.py
Normal file
316
test_dms_connection.py
Normal file
@ -0,0 +1,316 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
DMS服务连接测试脚本
|
||||||
|
专门用于测试DMS API的连接和SSL配置
|
||||||
|
"""
|
||||||
|
|
||||||
|
import requests
|
||||||
|
import urllib3
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
from urllib.parse import urljoin
|
||||||
|
|
||||||
|
def test_dms_connection():
|
||||||
|
"""测试DMS服务连接"""
|
||||||
|
|
||||||
|
# 配置
|
||||||
|
base_url = "https://www.dev.ideas.cnpc"
|
||||||
|
api_endpoint = "/api/schema/manage/schema"
|
||||||
|
full_url = urljoin(base_url, api_endpoint)
|
||||||
|
|
||||||
|
print("🔧 DMS服务连接测试")
|
||||||
|
print("=" * 60)
|
||||||
|
print(f"目标服务器: {base_url}")
|
||||||
|
print(f"API端点: {api_endpoint}")
|
||||||
|
print(f"完整URL: {full_url}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 禁用SSL警告(用于测试)
|
||||||
|
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||||
|
|
||||||
|
# 测试1: 忽略SSL证书验证
|
||||||
|
print("📡 测试1: 忽略SSL证书验证")
|
||||||
|
print("-" * 40)
|
||||||
|
|
||||||
|
try:
|
||||||
|
start_time = time.time()
|
||||||
|
response = requests.get(
|
||||||
|
full_url,
|
||||||
|
verify=False,
|
||||||
|
timeout=30,
|
||||||
|
headers={
|
||||||
|
'User-Agent': 'DMS-Compliance-Test/1.0',
|
||||||
|
'Accept': 'application/json'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end_time = time.time()
|
||||||
|
|
||||||
|
print(f"✅ 请求成功!")
|
||||||
|
print(f"⏱️ 响应时间: {end_time - start_time:.2f}秒")
|
||||||
|
print(f"📊 HTTP状态码: {response.status_code}")
|
||||||
|
print(f"📋 响应头:")
|
||||||
|
for key, value in response.headers.items():
|
||||||
|
print(f" {key}: {value}")
|
||||||
|
|
||||||
|
print(f"\n📄 响应内容:")
|
||||||
|
if response.status_code == 200:
|
||||||
|
try:
|
||||||
|
data = response.json()
|
||||||
|
print(f"✅ JSON解析成功")
|
||||||
|
print(f"📊 数据类型: {type(data)}")
|
||||||
|
|
||||||
|
if isinstance(data, dict):
|
||||||
|
print(f"🔑 响应键: {list(data.keys())}")
|
||||||
|
|
||||||
|
# 检查DMS特定的响应结构
|
||||||
|
if 'code' in data:
|
||||||
|
print(f"📈 业务代码: {data.get('code')}")
|
||||||
|
if 'message' in data:
|
||||||
|
print(f"💬 消息: {data.get('message')}")
|
||||||
|
if 'data' in data:
|
||||||
|
data_content = data.get('data')
|
||||||
|
print(f"📦 数据内容类型: {type(data_content)}")
|
||||||
|
if isinstance(data_content, dict) and 'records' in data_content:
|
||||||
|
records = data_content.get('records', [])
|
||||||
|
print(f"📝 记录数量: {len(records)}")
|
||||||
|
if records:
|
||||||
|
print(f"📋 第一条记录示例: {records[0] if len(records) > 0 else 'N/A'}")
|
||||||
|
|
||||||
|
# 显示响应内容的前500字符
|
||||||
|
response_text = json.dumps(data, ensure_ascii=False, indent=2)
|
||||||
|
if len(response_text) > 500:
|
||||||
|
print(f"📄 响应内容(前500字符):")
|
||||||
|
print(response_text[:500] + "...")
|
||||||
|
else:
|
||||||
|
print(f"📄 完整响应内容:")
|
||||||
|
print(response_text)
|
||||||
|
|
||||||
|
except json.JSONDecodeError as e:
|
||||||
|
print(f"❌ JSON解析失败: {e}")
|
||||||
|
print(f"📄 原始响应内容(前500字符):")
|
||||||
|
print(response.text[:500])
|
||||||
|
else:
|
||||||
|
print(f"⚠️ HTTP状态码异常: {response.status_code}")
|
||||||
|
print(f"📄 响应内容: {response.text[:500]}")
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
except requests.exceptions.SSLError as e:
|
||||||
|
print(f"❌ SSL错误: {e}")
|
||||||
|
print("💡 建议: 使用 --ignore-ssl 参数")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except requests.exceptions.ConnectionError as e:
|
||||||
|
print(f"❌ 连接错误: {e}")
|
||||||
|
print("💡 建议: 检查网络连接和服务器地址")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except requests.exceptions.Timeout as e:
|
||||||
|
print(f"❌ 超时错误: {e}")
|
||||||
|
print("💡 建议: 增加超时时间或检查网络延迟")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ 其他错误: {e}")
|
||||||
|
print(f"错误类型: {type(e).__name__}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def test_ssl_verification():
|
||||||
|
"""测试SSL证书验证"""
|
||||||
|
|
||||||
|
print("\n📡 测试2: 启用SSL证书验证")
|
||||||
|
print("-" * 40)
|
||||||
|
|
||||||
|
base_url = "https://www.dev.ideas.cnpc"
|
||||||
|
api_endpoint = "/api/schema/manage/schema"
|
||||||
|
full_url = urljoin(base_url, api_endpoint)
|
||||||
|
|
||||||
|
try:
|
||||||
|
start_time = time.time()
|
||||||
|
response = requests.get(
|
||||||
|
full_url,
|
||||||
|
verify=True, # 启用SSL验证
|
||||||
|
timeout=30,
|
||||||
|
headers={
|
||||||
|
'User-Agent': 'DMS-Compliance-Test/1.0',
|
||||||
|
'Accept': 'application/json'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end_time = time.time()
|
||||||
|
|
||||||
|
print(f"✅ SSL验证通过!")
|
||||||
|
print(f"⏱️ 响应时间: {end_time - start_time:.2f}秒")
|
||||||
|
print(f"📊 HTTP状态码: {response.status_code}")
|
||||||
|
return True
|
||||||
|
|
||||||
|
except requests.exceptions.SSLError as e:
|
||||||
|
print(f"❌ SSL验证失败(这是预期的): {e}")
|
||||||
|
print("💡 这证明需要使用 --ignore-ssl 参数")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ 其他错误: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def test_basic_connectivity():
|
||||||
|
"""测试基础网络连接"""
|
||||||
|
|
||||||
|
print("\n📡 测试3: 基础网络连接")
|
||||||
|
print("-" * 40)
|
||||||
|
|
||||||
|
base_url = "https://www.dev.ideas.cnpc"
|
||||||
|
|
||||||
|
try:
|
||||||
|
# 测试根路径
|
||||||
|
print(f"🔍 测试根路径: {base_url}")
|
||||||
|
response = requests.get(base_url, verify=False, timeout=10)
|
||||||
|
print(f"✅ 根路径连接成功: {response.status_code}")
|
||||||
|
|
||||||
|
# 测试其他可能的端点
|
||||||
|
test_endpoints = [
|
||||||
|
"/",
|
||||||
|
"/api",
|
||||||
|
"/api/health",
|
||||||
|
"/health"
|
||||||
|
]
|
||||||
|
|
||||||
|
for endpoint in test_endpoints:
|
||||||
|
try:
|
||||||
|
test_url = urljoin(base_url, endpoint)
|
||||||
|
response = requests.get(test_url, verify=False, timeout=5)
|
||||||
|
print(f"✅ {endpoint}: {response.status_code}")
|
||||||
|
except:
|
||||||
|
print(f"❌ {endpoint}: 连接失败")
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ 基础连接失败: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def test_domain_mapping():
|
||||||
|
"""测试域映射文件"""
|
||||||
|
|
||||||
|
print("\n📁 测试4: 域映射文件")
|
||||||
|
print("-" * 40)
|
||||||
|
|
||||||
|
domain_file = "./assets/doc/dms/domain.json"
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(domain_file, 'r', encoding='utf-8') as f:
|
||||||
|
domain_data = json.load(f)
|
||||||
|
|
||||||
|
print(f"✅ 域映射文件读取成功")
|
||||||
|
print(f"📁 文件路径: {domain_file}")
|
||||||
|
print(f"📊 域映射数据: {json.dumps(domain_data, ensure_ascii=False, indent=2)}")
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
except FileNotFoundError:
|
||||||
|
print(f"❌ 域映射文件不存在: {domain_file}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except json.JSONDecodeError as e:
|
||||||
|
print(f"❌ 域映射文件JSON格式错误: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ 读取域映射文件出错: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
def generate_curl_command():
|
||||||
|
"""生成等效的curl命令"""
|
||||||
|
|
||||||
|
print("\n🔧 等效的curl命令")
|
||||||
|
print("-" * 40)
|
||||||
|
|
||||||
|
base_url = "https://www.dev.ideas.cnpc"
|
||||||
|
api_endpoint = "/api/schema/manage/schema"
|
||||||
|
full_url = urljoin(base_url, api_endpoint)
|
||||||
|
|
||||||
|
curl_commands = [
|
||||||
|
f"# 忽略SSL证书验证:",
|
||||||
|
f"curl -k -v '{full_url}'",
|
||||||
|
f"",
|
||||||
|
f"# 带请求头:",
|
||||||
|
f"curl -k -v -H 'Accept: application/json' -H 'User-Agent: DMS-Compliance-Test/1.0' '{full_url}'",
|
||||||
|
f"",
|
||||||
|
f"# 启用SSL验证:",
|
||||||
|
f"curl -v '{full_url}'",
|
||||||
|
f"",
|
||||||
|
f"# 测试连接(仅获取响应头):",
|
||||||
|
f"curl -k -I '{full_url}'"
|
||||||
|
]
|
||||||
|
|
||||||
|
for cmd in curl_commands:
|
||||||
|
print(cmd)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""主函数"""
|
||||||
|
|
||||||
|
print("🚀 DMS服务连接诊断工具")
|
||||||
|
print("=" * 80)
|
||||||
|
print("此工具将测试DMS服务的连接性和SSL配置")
|
||||||
|
print("=" * 80)
|
||||||
|
|
||||||
|
results = []
|
||||||
|
|
||||||
|
# 执行所有测试
|
||||||
|
results.append(("DMS API连接(忽略SSL)", test_dms_connection()))
|
||||||
|
results.append(("SSL证书验证", test_ssl_verification()))
|
||||||
|
results.append(("基础网络连接", test_basic_connectivity()))
|
||||||
|
results.append(("域映射文件", test_domain_mapping()))
|
||||||
|
|
||||||
|
# 生成curl命令
|
||||||
|
generate_curl_command()
|
||||||
|
|
||||||
|
# 总结结果
|
||||||
|
print("\n" + "=" * 80)
|
||||||
|
print("📋 测试结果总结")
|
||||||
|
print("=" * 80)
|
||||||
|
|
||||||
|
passed = 0
|
||||||
|
for test_name, result in results:
|
||||||
|
status = "✅ 通过" if result else "❌ 失败"
|
||||||
|
print(f"{test_name:25} : {status}")
|
||||||
|
if result:
|
||||||
|
passed += 1
|
||||||
|
|
||||||
|
print(f"\n📊 总计: {passed}/{len(results)} 个测试通过")
|
||||||
|
|
||||||
|
# 给出建议
|
||||||
|
print("\n💡 建议和解决方案:")
|
||||||
|
print("-" * 40)
|
||||||
|
|
||||||
|
if results[0][1]: # DMS API连接成功
|
||||||
|
print("✅ DMS API连接正常,建议在主程序中使用 --ignore-ssl 参数")
|
||||||
|
print(" 命令示例:")
|
||||||
|
print(" python run_api_tests.py --dms ./assets/doc/dms/domain.json --ignore-ssl")
|
||||||
|
else:
|
||||||
|
print("❌ DMS API连接失败,请检查:")
|
||||||
|
print(" 1. 网络连接是否正常")
|
||||||
|
print(" 2. 服务器地址是否正确")
|
||||||
|
print(" 3. 防火墙设置")
|
||||||
|
print(" 4. 服务器是否在线")
|
||||||
|
|
||||||
|
if not results[1][1]: # SSL验证失败
|
||||||
|
print("⚠️ SSL证书验证失败,这是正常的,使用 --ignore-ssl 参数即可")
|
||||||
|
|
||||||
|
if not results[3][1]: # 域映射文件问题
|
||||||
|
print("❌ 域映射文件有问题,请检查文件是否存在且格式正确")
|
||||||
|
|
||||||
|
return passed == len(results)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
success = main()
|
||||||
|
sys.exit(0 if success else 1)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\n\n⚠️ 测试被用户中断")
|
||||||
|
sys.exit(1)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"\n\n❌ 测试过程中发生未预期的错误: {e}")
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
sys.exit(1)
|
||||||
246
test_pdf_failure_details.py
Normal file
246
test_pdf_failure_details.py
Normal file
@ -0,0 +1,246 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
测试PDF报告中失败用例详情功能
|
||||||
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
from run_api_tests import save_pdf_report
|
||||||
|
|
||||||
|
def create_test_data_with_failures():
|
||||||
|
"""创建包含失败用例的测试数据"""
|
||||||
|
|
||||||
|
test_data = {
|
||||||
|
"overall_summary": {
|
||||||
|
"total_endpoints_tested": 3,
|
||||||
|
"endpoints_passed": 1,
|
||||||
|
"endpoints_failed": 2,
|
||||||
|
"endpoints_error": 0,
|
||||||
|
"total_test_cases_executed": 8,
|
||||||
|
"test_cases_passed": 4,
|
||||||
|
"test_cases_failed": 4,
|
||||||
|
"test_cases_error": 0,
|
||||||
|
"test_case_success_rate": "50%",
|
||||||
|
"start_time": "2025-08-07T10:00:00",
|
||||||
|
"end_time": "2025-08-07T10:05:00"
|
||||||
|
},
|
||||||
|
"endpoint_results": [
|
||||||
|
{
|
||||||
|
"endpoint_id": "POST /api/dms/test/v1/users",
|
||||||
|
"endpoint_name": "用户管理接口",
|
||||||
|
"overall_status": "失败",
|
||||||
|
"duration_seconds": 2.5,
|
||||||
|
"start_time": "2025-08-07T10:00:00",
|
||||||
|
"end_time": "2025-08-07T10:00:02.5",
|
||||||
|
"executed_test_cases": [
|
||||||
|
{
|
||||||
|
"test_case_id": "TC-AUTH-001",
|
||||||
|
"test_case_name": "身份认证验证",
|
||||||
|
"test_case_severity": "CRITICAL",
|
||||||
|
"status": "失败",
|
||||||
|
"message": "缺少必需的请求头 Authorization。API返回401未授权错误,表明身份认证机制未正确实现。建议检查认证中间件配置。",
|
||||||
|
"duration_seconds": 0.8,
|
||||||
|
"timestamp": "2025-08-07T10:00:00.5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test_case_id": "TC-PARAM-001",
|
||||||
|
"test_case_name": "必需参数验证",
|
||||||
|
"test_case_severity": "HIGH",
|
||||||
|
"status": "失败",
|
||||||
|
"message": "请求体缺少必需字段 'username' 和 'email'。服务器应返回400错误并提供详细的字段验证信息,但实际返回了500内部服务器错误。",
|
||||||
|
"duration_seconds": 0.6,
|
||||||
|
"timestamp": "2025-08-07T10:00:01.1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test_case_id": "TC-RESP-001",
|
||||||
|
"test_case_name": "响应格式验证",
|
||||||
|
"test_case_severity": "MEDIUM",
|
||||||
|
"status": "通过",
|
||||||
|
"message": "响应格式符合预期",
|
||||||
|
"duration_seconds": 0.3,
|
||||||
|
"timestamp": "2025-08-07T10:00:01.7"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"endpoint_id": "GET /api/dms/test/v1/users/{id}",
|
||||||
|
"endpoint_name": "用户查询接口",
|
||||||
|
"overall_status": "失败",
|
||||||
|
"duration_seconds": 1.8,
|
||||||
|
"start_time": "2025-08-07T10:00:03",
|
||||||
|
"end_time": "2025-08-07T10:00:04.8",
|
||||||
|
"executed_test_cases": [
|
||||||
|
{
|
||||||
|
"test_case_id": "TC-PATH-001",
|
||||||
|
"test_case_name": "路径参数验证",
|
||||||
|
"test_case_severity": "HIGH",
|
||||||
|
"status": "失败",
|
||||||
|
"message": "当传入无效的用户ID(如负数或非数字字符串)时,API应返回400错误,但实际返回了500内部服务器错误。这表明输入验证逻辑存在问题,可能导致安全漏洞。",
|
||||||
|
"duration_seconds": 0.9,
|
||||||
|
"timestamp": "2025-08-07T10:00:03.5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test_case_id": "TC-404-001",
|
||||||
|
"test_case_name": "资源不存在处理",
|
||||||
|
"test_case_severity": "MEDIUM",
|
||||||
|
"status": "通过",
|
||||||
|
"message": "正确返回404错误",
|
||||||
|
"duration_seconds": 0.4,
|
||||||
|
"timestamp": "2025-08-07T10:00:04.4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"endpoint_id": "DELETE /api/dms/test/v1/users/{id}",
|
||||||
|
"endpoint_name": "用户删除接口",
|
||||||
|
"overall_status": "通过",
|
||||||
|
"duration_seconds": 1.2,
|
||||||
|
"start_time": "2025-08-07T10:00:05",
|
||||||
|
"end_time": "2025-08-07T10:00:06.2",
|
||||||
|
"executed_test_cases": [
|
||||||
|
{
|
||||||
|
"test_case_id": "TC-DEL-001",
|
||||||
|
"test_case_name": "删除权限验证",
|
||||||
|
"test_case_severity": "CRITICAL",
|
||||||
|
"status": "通过",
|
||||||
|
"message": "权限验证正常",
|
||||||
|
"duration_seconds": 0.5,
|
||||||
|
"timestamp": "2025-08-07T10:00:05.5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"test_case_id": "TC-DEL-002",
|
||||||
|
"test_case_name": "删除操作验证",
|
||||||
|
"test_case_severity": "HIGH",
|
||||||
|
"status": "通过",
|
||||||
|
"message": "删除操作成功",
|
||||||
|
"duration_seconds": 0.4,
|
||||||
|
"timestamp": "2025-08-07T10:00:05.9"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"stage_results": [
|
||||||
|
{
|
||||||
|
"stage_name": "数据一致性检查",
|
||||||
|
"description": "验证数据操作的一致性",
|
||||||
|
"overall_status": "失败",
|
||||||
|
"message": "在并发操作测试中发现数据不一致问题。当多个用户同时创建和删除用户时,数据库中出现了孤立记录。建议实现适当的事务隔离级别和锁机制。",
|
||||||
|
"duration_seconds": 3.5,
|
||||||
|
"start_time": "2025-08-07T10:00:07"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"stage_name": "性能基准测试",
|
||||||
|
"description": "验证API响应时间",
|
||||||
|
"overall_status": "通过",
|
||||||
|
"message": "所有API响应时间均在可接受范围内",
|
||||||
|
"duration_seconds": 2.1,
|
||||||
|
"start_time": "2025-08-07T10:00:10"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"errors": []
|
||||||
|
}
|
||||||
|
|
||||||
|
return test_data
|
||||||
|
|
||||||
|
def test_pdf_with_failure_details():
|
||||||
|
"""测试包含失败用例详情的PDF报告生成"""
|
||||||
|
|
||||||
|
print("🧪 测试PDF报告失败用例详情功能")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
# 创建测试数据
|
||||||
|
test_data = create_test_data_with_failures()
|
||||||
|
|
||||||
|
# 生成PDF报告
|
||||||
|
output_path = Path("test_reports") / "failure_details_test.pdf"
|
||||||
|
output_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
print(f"📄 生成PDF报告: {output_path}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
save_pdf_report(test_data, output_path, strictness_level='HIGH')
|
||||||
|
|
||||||
|
if output_path.exists():
|
||||||
|
file_size = output_path.stat().st_size / 1024
|
||||||
|
print(f"✅ PDF报告生成成功!")
|
||||||
|
print(f"📊 文件大小: {file_size:.2f} KB")
|
||||||
|
|
||||||
|
# 分析测试数据
|
||||||
|
total_cases = sum(len(ep.get('executed_test_cases', [])) for ep in test_data['endpoint_results'])
|
||||||
|
stage_cases = len(test_data.get('stage_results', []))
|
||||||
|
failed_endpoint_cases = sum(1 for ep in test_data['endpoint_results']
|
||||||
|
for tc in ep.get('executed_test_cases', [])
|
||||||
|
if tc.get('status') in ['失败', 'FAILED'])
|
||||||
|
failed_stage_cases = sum(1 for stage in test_data.get('stage_results', [])
|
||||||
|
if stage.get('overall_status') in ['失败', 'FAILED'])
|
||||||
|
|
||||||
|
print(f"\n📋 测试数据统计:")
|
||||||
|
print(f"- 总测试用例: {total_cases + stage_cases}")
|
||||||
|
print(f"- 端点测试用例: {total_cases}")
|
||||||
|
print(f"- Stage测试用例: {stage_cases}")
|
||||||
|
print(f"- 失败的端点用例: {failed_endpoint_cases}")
|
||||||
|
print(f"- 失败的Stage用例: {failed_stage_cases}")
|
||||||
|
print(f"- 总失败用例: {failed_endpoint_cases + failed_stage_cases}")
|
||||||
|
|
||||||
|
print(f"\n🎯 新增功能验证:")
|
||||||
|
print("✅ 失败用例详情分析部分")
|
||||||
|
print("✅ 按严重级别分组统计")
|
||||||
|
print("✅ 详细失败原因说明")
|
||||||
|
print("✅ 用例基本信息展示")
|
||||||
|
print("✅ 格式化的失败信息显示")
|
||||||
|
|
||||||
|
print(f"\n💡 报告包含以下失败用例详情:")
|
||||||
|
print("1. TC-AUTH-001: 身份认证验证失败")
|
||||||
|
print(" - 严重级别: CRITICAL")
|
||||||
|
print(" - 失败原因: 缺少Authorization请求头")
|
||||||
|
print("2. TC-PARAM-001: 必需参数验证失败")
|
||||||
|
print(" - 严重级别: HIGH")
|
||||||
|
print(" - 失败原因: 缺少必需字段username和email")
|
||||||
|
print("3. TC-PATH-001: 路径参数验证失败")
|
||||||
|
print(" - 严重级别: HIGH")
|
||||||
|
print(" - 失败原因: 输入验证逻辑问题")
|
||||||
|
print("4. 数据一致性检查Stage失败")
|
||||||
|
print(" - 严重级别: HIGH")
|
||||||
|
print(" - 失败原因: 并发操作数据不一致")
|
||||||
|
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print("❌ PDF报告生成失败")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ 生成PDF报告时出错: {e}")
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
return False
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""主函数"""
|
||||||
|
print("🚀 DMS合规性测试工具 - PDF失败用例详情测试")
|
||||||
|
print("=" * 80)
|
||||||
|
|
||||||
|
success = test_pdf_with_failure_details()
|
||||||
|
|
||||||
|
print("\n" + "=" * 80)
|
||||||
|
if success:
|
||||||
|
print("🎉 测试完成!PDF报告现在包含详细的失败用例分析")
|
||||||
|
print("\n📋 新功能特点:")
|
||||||
|
print("- 失败用例统计和分组")
|
||||||
|
print("- 详细的失败原因说明")
|
||||||
|
print("- 用例基本信息展示")
|
||||||
|
print("- 清晰的格式化显示")
|
||||||
|
print("- 支持长文本的适当处理")
|
||||||
|
|
||||||
|
print("\n💡 使用建议:")
|
||||||
|
print("- 查看生成的PDF文件中的'失败用例详情分析'部分")
|
||||||
|
print("- 失败原因按严重级别分组显示")
|
||||||
|
print("- 每个失败用例都有详细的错误信息")
|
||||||
|
|
||||||
|
sys.exit(0)
|
||||||
|
else:
|
||||||
|
print("❌ 测试失败,请检查错误信息")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
170
verify_pdf_failures.py
Normal file
170
verify_pdf_failures.py
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
验证PDF报告中的失败用例详情
|
||||||
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
from run_api_tests import save_pdf_report
|
||||||
|
|
||||||
|
def verify_latest_report():
|
||||||
|
"""验证最新的测试报告"""
|
||||||
|
|
||||||
|
print("🔍 验证最新测试报告的PDF失败用例详情")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
# 找到最新的测试报告目录
|
||||||
|
test_reports_dir = Path("test_reports")
|
||||||
|
if not test_reports_dir.exists():
|
||||||
|
print("❌ 测试报告目录不存在")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 获取所有日期格式的目录
|
||||||
|
date_dirs = [d for d in test_reports_dir.iterdir()
|
||||||
|
if d.is_dir() and d.name.startswith("2025-")]
|
||||||
|
|
||||||
|
if not date_dirs:
|
||||||
|
print("❌ 没有找到测试报告目录")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 找到最新的目录
|
||||||
|
latest_dir = max(date_dirs, key=lambda x: x.name)
|
||||||
|
print(f"📁 最新测试报告目录: {latest_dir}")
|
||||||
|
|
||||||
|
# 读取JSON摘要
|
||||||
|
json_file = latest_dir / "summary.json"
|
||||||
|
if not json_file.exists():
|
||||||
|
print(f"❌ 找不到摘要文件: {json_file}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(json_file, 'r', encoding='utf-8') as f:
|
||||||
|
test_data = json.load(f)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ 读取摘要文件失败: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
# 分析失败用例
|
||||||
|
failed_cases = []
|
||||||
|
endpoint_results = test_data.get('endpoint_results', [])
|
||||||
|
|
||||||
|
for endpoint in endpoint_results:
|
||||||
|
test_cases = endpoint.get('executed_test_cases', [])
|
||||||
|
for tc in test_cases:
|
||||||
|
if tc.get('status') in ['失败', 'FAILED']:
|
||||||
|
failed_cases.append({
|
||||||
|
'endpoint': endpoint.get('endpoint_name', 'N/A'),
|
||||||
|
'case_id': tc.get('test_case_id', 'N/A'),
|
||||||
|
'case_name': tc.get('test_case_name', 'N/A'),
|
||||||
|
'severity': tc.get('test_case_severity', 'N/A'),
|
||||||
|
'message': tc.get('message', 'N/A')
|
||||||
|
})
|
||||||
|
|
||||||
|
# 分析stage失败用例
|
||||||
|
stage_results = test_data.get('stage_results', [])
|
||||||
|
for stage in stage_results:
|
||||||
|
if stage.get('overall_status') in ['失败', 'FAILED']:
|
||||||
|
failed_cases.append({
|
||||||
|
'endpoint': f"Stage: {stage.get('stage_name', 'N/A')}",
|
||||||
|
'case_id': f"STAGE_{stage.get('stage_name', 'N/A')}",
|
||||||
|
'case_name': stage.get('description', stage.get('stage_name', 'N/A')),
|
||||||
|
'severity': 'HIGH',
|
||||||
|
'message': stage.get('message', stage.get('error_message', 'N/A'))
|
||||||
|
})
|
||||||
|
|
||||||
|
print(f"📊 测试数据统计:")
|
||||||
|
print(f"- 总端点数: {test_data.get('overall_summary', {}).get('endpoints_tested', 0)}")
|
||||||
|
print(f"- 总测试用例: {test_data.get('overall_summary', {}).get('total_test_cases_executed', 0)}")
|
||||||
|
print(f"- 失败用例数: {len(failed_cases)}")
|
||||||
|
print(f"- 测试成功率: {test_data.get('overall_summary', {}).get('test_case_success_rate', 'N/A')}")
|
||||||
|
|
||||||
|
if failed_cases:
|
||||||
|
print(f"\n📋 失败用例详情:")
|
||||||
|
for i, case in enumerate(failed_cases, 1):
|
||||||
|
print(f"{i}. {case['case_name']} ({case['case_id']})")
|
||||||
|
print(f" 端点: {case['endpoint']}")
|
||||||
|
print(f" 严重级别: {case['severity']}")
|
||||||
|
print(f" 失败原因: {case['message'][:100]}...")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# 重新生成PDF报告以验证失败用例详情
|
||||||
|
pdf_file = latest_dir / "report_cn.pdf"
|
||||||
|
print(f"🔄 重新生成PDF报告: {pdf_file}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
save_pdf_report(test_data, pdf_file, strictness_level='HIGH')
|
||||||
|
|
||||||
|
if pdf_file.exists():
|
||||||
|
file_size = pdf_file.stat().st_size / 1024
|
||||||
|
print(f"✅ PDF报告生成成功!")
|
||||||
|
print(f"📄 文件大小: {file_size:.2f} KB")
|
||||||
|
|
||||||
|
print(f"\n🎯 PDF报告现在包含以下新功能:")
|
||||||
|
print("✅ 失败用例详情分析部分")
|
||||||
|
print("✅ 按严重级别分组的失败统计")
|
||||||
|
print("✅ 每个失败用例的详细信息:")
|
||||||
|
print(" - 用例ID和名称")
|
||||||
|
print(" - 所属端点")
|
||||||
|
print(" - 严重级别")
|
||||||
|
print(" - 详细的失败原因")
|
||||||
|
|
||||||
|
if failed_cases:
|
||||||
|
print(f"\n📝 报告中将显示 {len(failed_cases)} 个失败用例的详细分析")
|
||||||
|
|
||||||
|
# 按严重级别分组
|
||||||
|
critical_count = len([c for c in failed_cases if c['severity'] == 'CRITICAL'])
|
||||||
|
high_count = len([c for c in failed_cases if c['severity'] == 'HIGH'])
|
||||||
|
medium_count = len([c for c in failed_cases if c['severity'] == 'MEDIUM'])
|
||||||
|
low_count = len([c for c in failed_cases if c['severity'] == 'LOW'])
|
||||||
|
|
||||||
|
print(f" - 严重级别: {critical_count} 个")
|
||||||
|
print(f" - 高级别: {high_count} 个")
|
||||||
|
print(f" - 中级别: {medium_count} 个")
|
||||||
|
print(f" - 低级别: {low_count} 个")
|
||||||
|
else:
|
||||||
|
print("✅ 本次测试没有失败用例")
|
||||||
|
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
print("❌ PDF报告生成失败")
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ 生成PDF报告时出错: {e}")
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
return False
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""主函数"""
|
||||||
|
print("🚀 DMS合规性测试工具 - PDF失败用例详情验证")
|
||||||
|
print("=" * 80)
|
||||||
|
|
||||||
|
success = verify_latest_report()
|
||||||
|
|
||||||
|
print("\n" + "=" * 80)
|
||||||
|
if success:
|
||||||
|
print("🎉 验证完成!PDF报告已成功添加失败用例详情功能")
|
||||||
|
print("\n💡 新功能说明:")
|
||||||
|
print("1. 在PDF报告中新增了'失败用例详情分析'部分")
|
||||||
|
print("2. 按严重级别统计和分组显示失败用例")
|
||||||
|
print("3. 每个失败用例都包含:")
|
||||||
|
print(" - 用例基本信息(ID、名称、端点、严重级别)")
|
||||||
|
print(" - 详细的失败原因说明")
|
||||||
|
print(" - 清晰的格式化显示")
|
||||||
|
print("4. 支持endpoint测试用例和stage测试用例")
|
||||||
|
print("5. 自动处理长文本,确保PDF显示正常")
|
||||||
|
|
||||||
|
print("\n📖 使用方法:")
|
||||||
|
print("- 运行测试后,查看生成的PDF报告")
|
||||||
|
print("- 在报告中找到'失败用例详情分析'部分")
|
||||||
|
print("- 每个失败用例都有详细的错误信息和修复建议")
|
||||||
|
|
||||||
|
sys.exit(0)
|
||||||
|
else:
|
||||||
|
print("❌ 验证失败,请检查错误信息")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Loading…
x
Reference in New Issue
Block a user