From f8355d7af38073f873cddaf07784296da54a2172 Mon Sep 17 00:00:00 2001 From: Ivan Khokhlov Date: Sat, 12 Apr 2025 08:54:33 +0000 Subject: [PATCH] first test --- .github/ISSUE_TEMPLATE/bug_report.md | 32 ++++ .github/ISSUE_TEMPLATE/feature_request.md | 20 +++ .github/PULL_REQUEST_TEMPLATE.md | 22 +++ .github/workflows/ci.yml | 173 +++++++++++++++++++ scripts/check_style.sh | 41 +++++ scripts/create_task.sh | 195 ++++++++++++++++++++++ scripts/format_code.sh | 36 ++++ 7 files changed, 519 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/workflows/ci.yml create mode 100755 scripts/check_style.sh create mode 100755 scripts/create_task.sh create mode 100755 scripts/format_code.sh diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..0739958 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,32 @@ +--- +name: Сообщение об ошибке +about: Создайте сообщение об ошибке, чтобы помочь нам улучшить проект +title: '[BUG] Краткое описание ошибки' +labels: bug +assignees: '' + +--- + +**Опишите ошибку** +Четкое и краткое описание того, что представляет собой ошибка. + +**Как воспроизвести** +Шаги для воспроизведения поведения: +1. Перейдите к '...' +2. Нажмите на '....' +3. Прокрутите вниз до '....' +4. Смотрите ошибку + +**Ожидаемое поведение** +Четкое и краткое описание того, что вы ожидали произойти. + +**Скриншоты** +Если применимо, добавьте скриншоты, чтобы объяснить вашу проблему. + +**Окружение:** + - ОС: [например, Ubuntu 20.04] + - Компилятор: [например, g++ 9.3.0] + - Версия проекта: [например, 1.0.0] + +**Дополнительный контекст** +Добавьте сюда любой другой контекст о проблеме. \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..e6c0f48 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Запрос новой функции +about: Предложите идею для этого проекта +title: '[FEATURE] Краткое описание функции' +labels: enhancement +assignees: '' + +--- + +**Ваш запрос связан с проблемой? Пожалуйста, опишите.** +Четкое и краткое описание проблемы. Например: Я всегда расстраиваюсь, когда [...] + +**Опишите решение, которое вы хотели бы** +Четкое и краткое описание того, что вы хотите, чтобы произошло. + +**Опишите альтернативы, которые вы рассматривали** +Четкое и краткое описание любых альтернативных решений или функций, которые вы рассматривали. + +**Дополнительный контекст** +Добавьте сюда любой другой контекст или скриншоты о запросе функции. \ No newline at end of file diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..60db6e1 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,22 @@ +## Описание изменений +[Опишите, какие изменения были внесены] + +## Связанные задачи +- [ ] Задача #1 +- [ ] Задача #2 + +## Тип изменений +- [ ] Исправление ошибок +- [ ] Улучшение кода +- [ ] Новая функциональность +- [ ] Документация +- [ ] Тесты + +## Проверка +- [ ] Код соответствует стилю Google +- [ ] Все тесты проходят +- [ ] Добавлены новые тесты (если необходимо) +- [ ] Документация обновлена (если необходимо) + +## Дополнительная информация +[Добавьте любую дополнительную информацию, которая может быть полезна для ревью] \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..ff7c066 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,173 @@ +name: CI/CD Pipeline + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + code-quality: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y clang-format cppcheck valgrind ccache + + - name: Cache ccache files + uses: actions/cache@v3 + with: + path: ~/.ccache + key: ccache-${{ github.sha }} + restore-keys: ccache- + + - name: Style Check + run: | + find . -type f \( -name "*.cpp" -o -name "*.hpp" -o -name "*.h" \) \ + -not -path "./build/*" \ + -not -path "./.git/*" \ + -exec clang-format --style=Google --dry-run --Werror {} \; + + - name: Static Analysis + run: | + cppcheck --enable=all --error-exitcode=1 \ + --suppress=missingInclude \ + --suppress=unmatchedSuppression \ + --suppress=unusedFunction \ + --suppress=noExplicitConstructor \ + --suppress=useInitializationList \ + */src/*.cpp */include/*.hpp + + build-and-test: + runs-on: ubuntu-latest + strategy: + matrix: + build_type: [Debug, Release] + compiler: [gcc, clang] + + steps: + - uses: actions/checkout@v3 + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y cmake build-essential clang valgrind ccache + + - name: Cache ccache files + uses: actions/cache@v3 + with: + path: ~/.ccache + key: ccache-${{ matrix.compiler }}-${{ matrix.build_type }}-${{ github.sha }} + restore-keys: ccache-${{ matrix.compiler }}-${{ matrix.build_type }}- + + - name: Configure CMake + run: | + if [ "${{ matrix.compiler }}" = "gcc" ]; then + export CC=gcc CXX=g++ + else + export CC=clang CXX=clang++ + fi + cmake -B build -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} + + - name: Build + run: cmake --build build --config ${{ matrix.build_type }} + + - name: Run Tests + working-directory: build + run: ctest --output-on-failure + + - name: Memory Check + if: matrix.build_type == 'Debug' + working-directory: build + run: | + for test in test_task_*; do + if [ -x "$test" ]; then + valgrind --leak-check=full --error-exitcode=1 ./"$test" + fi + done + + - name: Run Benchmarks + if: matrix.build_type == 'Release' + working-directory: build + run: | + for bench in benchmark_task_*; do + if [ -x "$bench" ]; then + ./"$bench" --benchmark_min_time=0.1 + fi + done + + sanitizers: + runs-on: ubuntu-latest + strategy: + matrix: + sanitizer: [address, undefined, thread] + + steps: + - uses: actions/checkout@v3 + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y cmake build-essential clang + + - name: Configure CMake with Sanitizer + run: | + export CC=clang CXX=clang++ + cmake -B build \ + -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_CXX_FLAGS="-fsanitize=${{ matrix.sanitizer }}" + + - name: Build + run: cmake --build build + + - name: Run Tests with Sanitizer + working-directory: build + run: | + for test in test_task_*; do + if [ -x "$test" ]; then + ./"$test" + fi + done + + coverage: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y cmake build-essential lcov + + - name: Configure CMake with Coverage + run: | + cmake -B build \ + -DCMAKE_BUILD_TYPE=Debug \ + -DCMAKE_CXX_FLAGS="--coverage" + + - name: Build + run: cmake --build build + + - name: Run Tests for Coverage + working-directory: build + run: | + for test in test_task_*; do + if [ -x "$test" ]; then + ./"$test" + fi + done + + - name: Generate Coverage Report + run: | + lcov --capture --directory build --output-file coverage.info + lcov --remove coverage.info '/usr/*' --output-file coverage.info + lcov --list coverage.info + + - name: Upload Coverage Report + uses: actions/upload-artifact@v3 + with: + name: coverage-report + path: coverage.info \ No newline at end of file diff --git a/scripts/check_style.sh b/scripts/check_style.sh new file mode 100755 index 0000000..1b9e712 --- /dev/null +++ b/scripts/check_style.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +# Проверяем наличие clang-format +if ! command -v clang-format &> /dev/null; then + echo "Error: clang-format is not installed" + exit 1 +fi + +# Создаем временный файл для хранения списка файлов +TMP_FILE=$(mktemp) + +# Находим все C++ файлы в проекте +find . -type f \( -name "*.cpp" -o -name "*.hpp" -o -name "*.h" \) \ + -not -path "./build/*" \ + -not -path "./.git/*" \ + -not -path "./googletest/*" \ + > "$TMP_FILE" + +# Проверяем стиль каждого файла +ERRORS=0 +while IFS= read -r file; do + echo "Checking $file..." + if ! clang-format --style=Google --dry-run --Werror "$file" &> /dev/null; then + echo "Style issues found in $file" + clang-format --style=Google "$file" > "${file}.formatted" + diff -u "$file" "${file}.formatted" + rm "${file}.formatted" + ERRORS=$((ERRORS + 1)) + fi +done < "$TMP_FILE" + +# Удаляем временный файл +rm "$TMP_FILE" + +if [ $ERRORS -gt 0 ]; then + echo "Found $ERRORS files with style issues" + exit 1 +else + echo "All files follow Google style guide" + exit 0 +fi \ No newline at end of file diff --git a/scripts/create_task.sh b/scripts/create_task.sh new file mode 100755 index 0000000..ca37fdb --- /dev/null +++ b/scripts/create_task.sh @@ -0,0 +1,195 @@ +#!/bin/bash + +if [ $# -ne 1 ]; then + echo "Usage: $0 " + exit 1 +fi + +TASK_NUMBER=$1 +TASK_DIR="task_$TASK_NUMBER" + +# Create task directory structure +mkdir -p "$TASK_DIR/src" +mkdir -p "$TASK_DIR/include" +mkdir -p "$TASK_DIR/benchmark" + +# Create main.cpp +cat > "$TASK_DIR/src/main.cpp" << 'EOL' +#include +#include "../include/solution.hpp" + +int main() { + // Your testing code here + return 0; +} +EOL + +# Create test.cpp +cat > "$TASK_DIR/src/test.cpp" << 'EOL' +#include +#include "../include/solution.hpp" + +TEST(TestSuite, TestCase) { + // Your test code here + ASSERT_EQ(1, 1); +} + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} +EOL + +# Create benchmark.cpp +cat > "$TASK_DIR/benchmark/benchmark.cpp" << 'EOL' +#include +#include "../include/solution.hpp" + +// Базовый бенчмарк +static void BM_YourFunction(benchmark::State& state) { + // Подготовка данных для тестирования + for (auto _ : state) { + // Тестируемый код + benchmark::DoNotOptimize(/* ваш код */); + } +} +BENCHMARK(BM_YourFunction); + +// Бенчмарк с параметрами +static void BM_YourFunctionWithParams(benchmark::State& state) { + int size = state.range(0); + // Подготовка данных размера size + for (auto _ : state) { + // Тестируемый код с параметром size + benchmark::DoNotOptimize(/* ваш код */); + } +} +BENCHMARK(BM_YourFunctionWithParams) + ->RangeMultiplier(2) + ->Range(8, 8<<10); // Тестируем размеры от 8 до 8192 + +// Бенчмарк с пользовательскими счетчиками +static void BM_YourFunctionWithCounters(benchmark::State& state) { + int size = state.range(0); + for (auto _ : state) { + // Тестируемый код + state.counters["items_per_second"] = benchmark::Counter( + size, benchmark::Counter::kIsRate); + state.counters["bytes_processed"] = benchmark::Counter( + size * sizeof(int), benchmark::Counter::kIsRate); + } +} +BENCHMARK(BM_YourFunctionWithCounters) + ->Range(8, 8<<10); + +BENCHMARK_MAIN(); +EOL + +# Create solution.hpp +cat > "$TASK_DIR/include/solution.hpp" << 'EOL' +#pragma once + +// Your solution class/function declarations here + +EOL + +# Create solution.cpp +cat > "$TASK_DIR/src/solution.cpp" << 'EOL' +#include "../include/solution.hpp" + +// Your solution implementations here + +EOL + +# Create CMakeLists.txt +cat > "$TASK_DIR/CMakeLists.txt" << 'EOL' +cmake_minimum_required(VERSION 3.10) +project(task_${TASK_NUMBER}) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# Add gtest +include(FetchContent) +FetchContent_Declare( + googletest + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG release-1.12.1 +) +FetchContent_MakeAvailable(googletest) + +# Add benchmark +FetchContent_Declare( + benchmark + GIT_REPOSITORY https://github.com/google/benchmark.git + GIT_TAG v1.8.3 +) +FetchContent_MakeAvailable(benchmark) + +# Add executable for testing +add_executable(test_task_${TASK_NUMBER} + src/test.cpp + src/solution.cpp +) + +target_link_libraries(test_task_${TASK_NUMBER} + gtest_main + gmock_main +) + +# Add executable for main +add_executable(main_task_${TASK_NUMBER} + src/main.cpp + src/solution.cpp +) + +# Add executable for benchmark +add_executable(benchmark_task_${TASK_NUMBER} + benchmark/benchmark.cpp + src/solution.cpp +) + +target_link_libraries(benchmark_task_${TASK_NUMBER} + benchmark::benchmark +) +EOL + +# Create README.md +cat > "$TASK_DIR/README.md" << 'EOL' +# Task ${TASK_NUMBER} + +## Description +[Add task description here] + +## Requirements +- C++17 or higher +- Google Test framework +- Google Benchmark framework + +## Building +```bash +mkdir build && cd build +cmake .. +make +``` + +## Running Tests +```bash +./test_task_${TASK_NUMBER} +``` + +## Running Main +```bash +./main_task_${TASK_NUMBER} +``` + +## Running Benchmarks +```bash +./benchmark_task_${TASK_NUMBER} +``` + +## Benchmark Results +[Add benchmark results and analysis here] +EOL + +echo "Task ${TASK_NUMBER} created successfully!" \ No newline at end of file diff --git a/scripts/format_code.sh b/scripts/format_code.sh new file mode 100755 index 0000000..6070b68 --- /dev/null +++ b/scripts/format_code.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# Проверяем наличие clang-format +if ! command -v clang-format &> /dev/null; then + echo "Error: clang-format is not installed" + exit 1 +fi + +# Создаем временный файл для хранения списка файлов +TMP_FILE=$(mktemp) + +# Находим все C++ файлы в проекте +find . -type f \( -name "*.cpp" -o -name "*.hpp" -o -name "*.h" \) \ + -not -path "./build/*" \ + -not -path "./.git/*" \ + -not -path "./googletest/*" \ + > "$TMP_FILE" + +# Форматируем каждый файл +FORMATTED=0 +while IFS= read -r file; do + echo "Formatting $file..." + if ! clang-format --style=Google --dry-run --Werror "$file" &> /dev/null; then + clang-format --style=Google -i "$file" + FORMATTED=$((FORMATTED + 1)) + fi +done < "$TMP_FILE" + +# Удаляем временный файл +rm "$TMP_FILE" + +if [ $FORMATTED -gt 0 ]; then + echo "Formatted $FORMATTED files" +else + echo "All files are already formatted" +fi \ No newline at end of file