diff --git a/.github/workflows/build-verification.yml b/.github/workflows/build-verification.yml deleted file mode 100644 index 58b79b6..0000000 --- a/.github/workflows/build-verification.yml +++ /dev/null @@ -1,158 +0,0 @@ -name: Build Verification - -# 简单的编译验证工作流 - -# 触发条件 -on: - push: - branches: [ main, develop ] - pull_request: - branches: [ main, develop ] - -# 任务 -jobs: - build-verification: - name: Build and Basic Test - runs-on: ubuntu-latest - - steps: - # 检出代码,克隆代码库 - - name: Checkout Repository - uses: actions/checkout@v4 - with: - submodules: 'recursive' # 检出子模块 - - # 安装构建依赖 - - name: Install Build Dependencies - run: | - sudo apt-get update - sudo apt-get install -y \ - build-essential \ - cmake \ - libsqlite3-dev \ - libssl-dev \ - libgtest-dev \ - libgmock-dev \ - pkg-config \ - libboost-all-dev - - # 配置和构建项目 - - name: Configure and Build - run: | - echo "🔧 Configuring CMake..." - mkdir -p build - cd build - cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_VERBOSE_MAKEFILE=ON - - echo "🏗️ Building project..." - make -j$(nproc) - - echo "✅ Build completed successfully!" - - # 验证可执行文件 - - name: Verify Executables - run: | - cd build - - echo "📋 Checking generated executables..." - ls -la - - # 检查主程序 - if [ -x "./SwiftChat" ]; then - echo "✅ Main executable found: SwiftChat" - file ./SwiftChat - else - echo "❌ Main executable not found!" - exit 1 - fi - - # 检查测试程序 - echo "📋 Checking test executables..." - cd tests - test_count=0 - for test in test_*; do - if [ -x "$test" ]; then - echo "✅ Test found: $test" - test_count=$((test_count + 1)) - fi - done - - if [ $test_count -eq 0 ]; then - echo "⚠️ No test executables found" - else - echo "✅ Found $test_count test executables" - fi - - # 运行基本测试 - - name: Run Basic Tests - run: | - cd build/tests - - echo "🧪 Running basic tests..." - failed_tests=0 - total_tests=0 - - for test in test_*; do - if [ -x "$test" ]; then - total_tests=$((total_tests + 1)) - echo "Running $test..." - - if timeout 30s ./"$test"; then - echo "✅ $test: PASSED" - else - echo "❌ $test: FAILED" - failed_tests=$((failed_tests + 1)) - fi - fi - done - - echo "📊 Test Summary:" - echo " Total tests: $total_tests" - echo " Passed: $((total_tests - failed_tests))" - echo " Failed: $failed_tests" - - if [ $failed_tests -gt 0 ]; then - echo "❌ Some tests failed!" - exit 1 - else - echo "✅ All tests passed!" - fi - - # 运行快速功能测试 - - name: Quick Functionality Test - run: | - cd build - - echo "🚀 Testing main program startup..." - # 使用超时来测试程序是否能正常启动 - if timeout 5s ./SwiftChat --help 2>/dev/null; then - echo "✅ Main program '--help' command executed successfully" - else - echo "❌ Main program '--help' command failed to execute" - exit 1 - fi - - echo "✅ Basic functionality test completed" - - # 生成构建摘要 - - name: Build Summary - if: always() - run: | - echo "## 🏗️ Build Verification Summary" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "- **Repository**: ${{ github.repository }}" >> $GITHUB_STEP_SUMMARY - echo "- **Branch**: ${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY - echo "- **Commit**: ${{ github.sha }}" >> $GITHUB_STEP_SUMMARY - echo "- **Build Status**: ${{ job.status }}" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - echo "### 📋 Build Information" >> $GITHUB_STEP_SUMMARY - echo "- Compiler: GCC (Ubuntu)" >> $GITHUB_STEP_SUMMARY - echo "- Build Type: Debug" >> $GITHUB_STEP_SUMMARY - echo "- C++ Standard: C++17" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - - if [[ "${{ job.status }}" == "success" ]]; then - echo "✅ **Build verification completed successfully!**" >> $GITHUB_STEP_SUMMARY - else - echo "❌ **Build verification failed. Please check the logs above.**" >> $GITHUB_STEP_SUMMARY - fi diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..ed01ddf --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,181 @@ +name: CI Workflow +description: This workflow builds the project, runs tests, performs static and dynamic analysis + +on: + push: + branches: [ main, develop ] + pull_request: + branches: [ main, develop ] + +jobs: + # ==================================================================== + # 任务1: 编译项目并上传产物 + # ==================================================================== + build: + name: Build Project + runs-on: ubuntu-latest + + steps: + # 检出代码 + - name: Checkout Repository + uses: actions/checkout@v4 + with: + submodules: 'recursive' + + # 安装构建依赖 + - name: Install Build Dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + build-essential \ + cmake \ + libsqlite3-dev \ + libssl-dev \ + libgtest-dev \ + libgmock-dev \ + pkg-config \ + libboost-all-dev + + # 配置和构建项目 (使用 Debug 类型并带 -g 标志,以便后续分析) + - name: Configure and Build + run: | + mkdir -p build + cd build + cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="-g" -DCMAKE_C_FLAGS="-g" + make -j$(nproc) + + # 上传编译产物 + - name: Upload Build Artifacts + uses: actions/upload-artifact@v4 + with: + name: build-artifacts + path: build/ + + # ==================================================================== + # 任务2: 运行单元测试和功能测试 + # 依赖于 'build' 任务的成功 + # ==================================================================== + test: + name: Run Tests + runs-on: ubuntu-latest + needs: build # 依赖于 build 任务 + + steps: + # 下载编译产物 + - name: Download Build Artifacts + uses: actions/download-artifact@v4 + with: + name: build-artifacts + path: build/ + + # 运行基本测试 + - name: Run Basic Tests + run: | + cd build/tests + failed_tests=0 + total_tests=0 + for test in test_*; do + if [ -x "$test" ]; then + total_tests=$((total_tests + 1)) + echo "Running $test..." + if timeout 30s ./"$test"; then + echo "✅ $test: PASSED" + else + echo "❌ $test: FAILED" + failed_tests=$((failed_tests + 1)) + fi + fi + done + if [ $failed_tests -gt 0 ]; then + echo "❌ $failed_tests out of $total_tests tests failed!" + exit 1 + else + echo "✅ All $total_tests tests passed!" + fi + + # ==================================================================== + # 任务3: 静态代码分析 (Cppcheck) + # 这个任务不依赖构建,可以和 build 并行运行 + # ==================================================================== + static-analysis: + name: Static Analysis (Cppcheck) + runs-on: ubuntu-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + with: + submodules: 'recursive' + + - name: Install Cppcheck + run: sudo apt-get update && sudo apt-get install -y cppcheck + + - name: Run Cppcheck + run: | + cppcheck --enable=all --std=c++17 --error-exitcode=1 \ + --suppress=missingIncludeSystem --suppress=missingInclude \ + --suppress=unusedFunction --inconclusive \ + src/ 2> cppcheck_report.txt + continue-on-error: true + + - name: Check and Upload Cppcheck Report + id: cppcheck + run: | + if grep -E "(error|warning)" cppcheck_report.txt; then + echo "Cppcheck found issues. See the report." + echo "CPPCHECK_EXIT_CODE=1" >> $GITHUB_ENV + else + echo "No critical Cppcheck issues found." + echo "CPPCHECK_EXIT_CODE=0" >> $GITHUB_ENV + fi + + - name: Upload Report on Failure + if: env.CPPCHECK_EXIT_CODE == '1' + uses: actions/upload-artifact@v4 + with: + name: cppcheck-report + path: cppcheck_report.txt + + - name: Fail workflow on issues + if: env.CPPCHECK_EXIT_CODE == '1' + run: exit 1 + + # ==================================================================== + # 任务4: 动态内存分析 (Valgrind) + # 依赖于 'build' 任务的成功 + # ==================================================================== + memory-check: + name: Memory Check (Valgrind) + runs-on: ubuntu-latest + needs: build # 依赖于 build 任务 + + steps: + - name: Install Valgrind + run: sudo apt-get update && sudo apt-get install -y valgrind + + - name: Download Build Artifacts + uses: actions/download-artifact@v4 + with: + name: build-artifacts + path: build/ + + - name: Run Valgrind on Tests + run: | + cd build/tests + valgrind_failed=0 + for test in test_*; do + if [ -x "$test" ]; then + echo "Running Valgrind on $test..." + valgrind --leak-check=full --error-exitcode=1 ./"$test" + if [ $? -ne 0 ]; then + echo "❌ Valgrind found issues in $test" + valgrind_failed=1 + else + echo "✅ Valgrind check passed for $test" + fi + fi + done + if [ $valgrind_failed -ne 0 ]; then + echo "Valgrind detected memory issues." + exit 1 + fi \ No newline at end of file diff --git a/src/db/database_manager.cpp b/src/db/database_manager.cpp index 29d4f2a..9e6ec4c 100644 --- a/src/db/database_manager.cpp +++ b/src/db/database_manager.cpp @@ -1,10 +1,7 @@ #include "database_manager.hpp" -DatabaseManager::DatabaseManager(const std::string &db_path) +DatabaseManager::DatabaseManager(const std::string &db_path):db_conn_(std::make_unique(db_path)) { - // 创建数据库连接 - db_conn_ = std::make_unique(db_path); - if (db_conn_->isConnected()) { // 创建各个仓库 diff --git a/src/service/message_service.cpp b/src/service/message_service.cpp index 6714c03..edff69f 100644 --- a/src/service/message_service.cpp +++ b/src/service/message_service.cpp @@ -112,10 +112,14 @@ http::HttpResponse MessageService::getMessages(const http::HttpRequest &request) // 将 Message 对象转换为 JSON json message_json_array = json::array(); - for (const auto& message : messages) - { - message_json_array.push_back(message.toJson()); - } + std::transform( + messages.begin(), + messages.end(), + std::back_inserter(message_json_array), + [](const auto &message) { + return message.toJson(); + } + ); json response_data = { {"success", true}, diff --git a/src/websocket/websocket_server.cpp b/src/websocket/websocket_server.cpp index e73ff88..ebb3eef 100644 --- a/src/websocket/websocket_server.cpp +++ b/src/websocket/websocket_server.cpp @@ -226,15 +226,15 @@ void WebSocketServer::on_message(connection_hdl hdl, websocket_server::message_p return; } - std::string user_id = *verified_user_id; + std::string verified_id = *verified_user_id; { // 进入临界区 std::lock_guard lock(connection_mutex_); // 检查用户是否已有连接 - auto old_connection_it = user_connections_.find(user_id); + auto old_connection_it = user_connections_.find(verified_id); if (old_connection_it != user_connections_.end()) { - LOG_INFO << "User " << user_id << " already has a connection. Closing old connection."; + LOG_INFO << "User " << verified_id << " already has a connection. Closing old connection."; // 获取旧连接句柄 // 向旧连接发送通知 json reason = { @@ -247,7 +247,7 @@ void WebSocketServer::on_message(connection_hdl hdl, websocket_server::message_p } catch (const std::exception &e) { - LOG_ERROR << "Error closing old connection for user " << user_id << ": " << e.what(); + LOG_ERROR << "Error closing old connection for user " << verified_id << ": " << e.what(); } // 关闭旧连接 @@ -256,15 +256,15 @@ void WebSocketServer::on_message(connection_hdl hdl, websocket_server::message_p connection_users_.erase(old_connection_it->second); } // 认证通过,保存连接和用户ID映射 - user_connections_[user_id] = hdl; - connection_users_[hdl] = user_id; + user_connections_[verified_id] = hdl; + connection_users_[hdl] = verified_id; } - LOG_INFO << "WebSocket connection authenticated for user: " << user_id; + LOG_INFO << "WebSocket connection authenticated for user: " << verified_id; json response = { {"success", true}, {"message", "WebSocket authentication successful"}, - {"data", {{"user_id", user_id}, {"status", "connected"}}}}; + {"data", {{"verified_id", verified_id}, {"status", "connected"}}}}; server_.send(hdl, response.dump(), websocketpp::frame::opcode::text); } else