diff --git a/.github/workflows/documentations.yml b/.github/workflows/documentations.yml deleted file mode 100644 index 411ca625..00000000 --- a/.github/workflows/documentations.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: Generate Documentation - -on: - push: - branches: - - dev - -jobs: - generate-docs: - name: Generate Documentation - runs-on: ubuntu-latest - - steps: - # Checkout do código - - name: Checkout Code - uses: actions/checkout@v3 - - # Instalar Doxygen - - name: Install Doxygen - run: | - sudo apt-get update - sudo apt-get install -y doxygen graphviz - - - name: Create docs directory if it does not exist - run: mkdir -p docs - - # Gerar documentação - - name: Generate Documentation - run: doxygen Doxyfile - - # Fazer upload da documentação para o branch gh-pages - - name: Deploy Documentation to GitHub Pages - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.PAT_TOKEN }} - publish_dir: . - force_orphan: true \ No newline at end of file diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 32c74333..18d425d2 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -15,7 +15,7 @@ jobs: - name: Install Dependencies run: | sudo apt-get update - sudo apt-get install -y g++ cmake qtbase5-dev qtbase5-private-dev libqt5widgets5 libqt5gui5 xvfb + sudo apt-get install -y doxygen graphviz lcov g++ cmake qtbase5-dev qtbase5-private-dev libqt5widgets5 libqt5gui5 xvfb git clone -b 5.15 https://code.qt.io/qt/qtmqtt.git ./qtmqtt cd qtmqtt qmake @@ -34,3 +34,45 @@ jobs: cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTS=ON -DUSE_SANITIZER=ON .. make xvfb-run -a ./digital_cluster_test + lcov --capture --directory . --output-file coverage.info --ignore-errors mismatch,unused + lcov --remove coverage.info '*/build/*' '*/test/*' '/usr/*' --output-file coverage.info + genhtml coverage.info --output-directory coverage_report + + - name: Create docs directory if it does not exist + run: mkdir -p docs + + # Gerar documentação + - name: Generate Documentation + run: doxygen Doxyfile + + - name: Upload Coverage Report + uses: actions/upload-artifact@v4 + with: + name: coverage-report + path: digital_cluster/build/coverage_report/ + # retention-days: 7 + + - name: Upload Doxygen Documentation + uses: actions/upload-artifact@v4 + with: + name: doxygen-docs + path: docs # Adjust to your Doxygen output directory + # retention-days: 7 + + - name: Move coverage report into docs + run: | + mkdir -p docs/coverage + cp -r digital_cluster/build/coverage_report/* docs/coverage/ + + - name: Deploy to GitHub Pages + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.PAT_TOKEN }} + publish_dir: docs + # destination_dir: ./ + force_orphan: true + # user_name: github-actions + # user_email: github-actions@github.com + # keep_files: true + # exclude_assets: '**/*.md' + diff --git a/README.md b/README.md index c24c0def..ca40304e 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,10 @@ For more on our **CAN Communication, Arduino and Speed Sensor**, visit our [Ardu To view a more detailed and structured documentation, click on [Doxygen Docs](https://seame-pt.github.io/DistributedEmbeddedSystems/). +## Test Coverage Report + +To view our test coverage report access: [Test Coverage Report](https://seame-pt.github.io/DistributedEmbeddedSystems/coverage/index.html) + ### [DES Project 1 - PiRacer Assembly](https://github.com/SEA-ME/DES_PiRacer-Assembly) -### [DES Project 2 - Instrument Cluster](https://github.com/SEA-ME/DES_Instrument-Cluster) \ No newline at end of file +### [DES Project 2 - Instrument Cluster](https://github.com/SEA-ME/DES_Instrument-Cluster) diff --git a/digital_cluster/CMakeLists.txt b/digital_cluster/CMakeLists.txt index c96f34c5..f7a2162b 100644 --- a/digital_cluster/CMakeLists.txt +++ b/digital_cluster/CMakeLists.txt @@ -15,8 +15,13 @@ option(BUILD_TESTS "Build test targets" OFF) set(CMAKE_COLOR_MAKEFILE ON) find_package(QT NAMES Qt5 REQUIRED COMPONENTS Widgets Mqtt Test) +find_library(PTHREAD_LIBRARY NAMES pthread) find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets Mqtt Test) include_directories(${CMAKE_SOURCE_DIR}) +# Enable coverage flags +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage -g -O0") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --coverage -g -O0") +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage") option(USE_SANITIZER "Enable sanitizer" OFF) @@ -26,11 +31,11 @@ if(USE_SANITIZER) # set(SANITIZER_FLAGS -fsanitize=thread) # Uncomment this line if you want ThreadSanitizer instead: endif() -include(FetchContent) #because of gmock i have to include gtest globally +include(FetchContent) FetchContent_Declare( googletest - URL https://github.com/google/googletest/archive/release-1.12.1.zip - DOWNLOAD_EXTRACT_TIMESTAMP TRUE + GIT_REPOSITORY https://github.com/google/googletest.git + GIT_TAG release-1.12.1 # Stable release ) FetchContent_MakeAvailable(googletest) @@ -42,6 +47,11 @@ if(BUILD_TESTS) ${HEADERS} ${TESTS} ) + set_source_files_properties(${SOURCES} PROPERTIES COMPILE_FLAGS "--coverage") + set_source_files_properties(${SOURCES} PROPERTIES LINK_FLAGS "--coverage") + # Explicitly disable coverage for test files and moc files + set_source_files_properties(${TESTS} PROPERTIES COMPILE_FLAGS "-fno-profile-arcs -fno-test-coverage") + set_source_files_properties(digital_cluster_test_autogen/mocs_compilation.cpp PROPERTIES COMPILE_FLAGS "-fno-profile-arcs -fno-test-coverage") target_link_libraries(digital_cluster_test gmock gtest diff --git a/digital_cluster/automate_env.sh b/digital_cluster/automate_env.sh index c84354af..2071e73c 100755 --- a/digital_cluster/automate_env.sh +++ b/digital_cluster/automate_env.sh @@ -7,8 +7,8 @@ cd build && cmake -DCMAKE_BUILD_TYPE=Debug .. && make # export QT_WAYLAND_DISABLE_TABLET=1 # export QT_WAYLAND_DISABLE_CLIPBOARD=1 # export QT_QPA_PLATFORM=xcb -# LD_PRELOAD=/lib/x86_64-linux-gnu/libpthread.so.0 -# valgrind +LD_PRELOAD=/lib/x86_64-linux-gnu/libpthread.so.0 ./digital_cluster # export QT_LOGGING_RULES="qt5.*=true;qt5.wayland=true" # GSETTINGS_BACKEND=memory QT_WAYLAND_DISABLE_KEYBOARD=1 -valgrind --leak-check=full --track-origins=yes ./digital_cluster \ No newline at end of file +# valgrind --leak-check=full --track-origins=yes + \ No newline at end of file diff --git a/digital_cluster/automate_test.sh b/digital_cluster/automate_test.sh index 08d73ec0..7ed6cc46 100755 --- a/digital_cluster/automate_test.sh +++ b/digital_cluster/automate_test.sh @@ -6,10 +6,14 @@ set -e cd build cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTS=ON .. # -DUSE_SANITIZER=ON make -# LD_PRELOAD=/lib/x86_64-linux-gnu/libpthread.so.0 ctest -V -R DigitalClusterTest -N +LD_PRELOAD=/lib/x86_64-linux-gnu/libpthread.so.0 ./digital_cluster_test # gdb --args ./digital_cluster_test -# valgrind -valgrind ./digital_cluster_test + +lcov --capture --directory . --output-file coverage.info +lcov --remove coverage.info '*/build/*' '*/test/*' '/usr/*' '*/googletest/*' --output-file coverage.info +genhtml coverage.info --output-directory coverage_report +xdg-open coverage_report/index.html + #/lib/x86_64-linux-gnu/libasan.so.8 # valgrind --leak-check=full ./digital_cluster_test # valgrind --leak-check=full ctest -V --rerun-failed --output-on-failure \ No newline at end of file diff --git a/digital_cluster/coverage.info b/digital_cluster/coverage.info new file mode 100644 index 00000000..e69de29b diff --git a/digital_cluster/include/object.h b/digital_cluster/include/object.h index c1ed3439..dfee682c 100644 --- a/digital_cluster/include/object.h +++ b/digital_cluster/include/object.h @@ -10,7 +10,7 @@ class Object : public Lane { private: QWidget *popup = nullptr; - std::vector objects; + int object; QString digital_path; public: @@ -18,8 +18,8 @@ class Object : public Lane { ~Object(); // void showObjectPopup(); void setting_pens(int i, QPainter *painter); - std::vector get_object(); - void set_object(std::string str); + int get_object(); + void set_object(int i); protected: void paintEvent(QPaintEvent *) override; diff --git a/digital_cluster/src/lane.cpp b/digital_cluster/src/lane.cpp index 5e363786..8c2e854e 100644 --- a/digital_cluster/src/lane.cpp +++ b/digital_cluster/src/lane.cpp @@ -12,7 +12,6 @@ Lane::Lane(QWidget *parent) : QWidget(parent), lane(1) digital_path = QDir::cleanPath(digital_path); pixmap = QPixmap(digital_path); pixmap = pixmap.scaled(this->width() * 0.4, height() * 0.7, Qt::KeepAspectRatio, Qt::SmoothTransformation); - animationTimer = new QTimer(this); connect(animationTimer, &QTimer::timeout, this, [this]() { m_leftDashOffset = int(m_leftDashOffset + 1) % 30; diff --git a/digital_cluster/src/mainwindow.cpp b/digital_cluster/src/mainwindow.cpp index 36e46d32..88da4806 100644 --- a/digital_cluster/src/mainwindow.cpp +++ b/digital_cluster/src/mainwindow.cpp @@ -10,7 +10,7 @@ MainWindow::MainWindow(QWidget *parent) QHBoxLayout* layout = new QHBoxLayout(); layout->addWidget(left_dial, 1, Qt::AlignTop | Qt::AlignLeft); - center_dial = new Object(this); + center_dial = new Lane(this); QVBoxLayout* centerLayout = new QVBoxLayout(); centerLayout->addWidget(center_dial, 0, Qt::AlignCenter); layout->addLayout(centerLayout, 1); diff --git a/digital_cluster/src/object.cpp b/digital_cluster/src/object.cpp index 60978164..40247746 100644 --- a/digital_cluster/src/object.cpp +++ b/digital_cluster/src/object.cpp @@ -1,11 +1,11 @@ #include "object.h" -Object::Object(QWidget *parent) : Lane(parent) +Object::Object(QWidget *parent) { // QString path = QCoreApplication::applicationDirPath(); // digital_path = QDir(path).filePath("../fonts_icon/warning1.png"); // digital_path = QDir::cleanPath(digital_path); - set_object("11,1,11"); + set_object(1); } // void Object::showObjectPopup() @@ -47,76 +47,90 @@ Object::Object(QWidget *parent) : Lane(parent) // } // } -void Object::setting_pens(int i, QPainter *painter) -{ - QColor rectColor = (objects[i] > 10) ? Qt::darkRed : Qt::darkGray; - // std::cout << "Object " << i << ": " << objects[i] << std::endl; - // std::cout << "Color: " << rectColor.red() << std::endl; - QPen rectPen(rectColor, 5); - QBrush rectBrush(rectColor, Qt::SolidPattern); - painter->setPen(rectPen); - painter->setBrush(rectBrush); - // painter.setOpacity(1.0); -} +// void Object::setting_pens(int i, QPainter *painter) +// { +// QColor rectColor = (objects[i] > 10) ? Qt::darkRed : Qt::darkGray; +// // std::cout << "Object " << i << ": " << objects[i] << std::endl; +// // std::cout << "Color: " << rectColor.red() << std::endl; +// QPen rectPen(rectColor, 5); +// QBrush rectBrush(rectColor, Qt::SolidPattern); +// painter->setPen(rectPen); +// painter->setBrush(rectBrush); +// // painter.setOpacity(1.0); +// } void Object::paintEvent(QPaintEvent *event) { - Lane::paintEvent(event); - QPainter painter(this); - painter.setRenderHint(QPainter::Antialiasing); - int BottomLeft = width() * 0.35; - int BottomRight = width() * 0.65; - int TopLeft = width() * 0.4; - int TopRight = width() * 0.6; - - int rectWidth = 9; - int margin = 10; - int centerX = (width() - rectWidth) / 2; - - if (objects[0] != 0) - { - setting_pens(0, &painter); - painter.drawLine(QPoint(BottomLeft, height() * 0.15), QPoint(TopLeft - margin, height() * 0.1)); - } - if (objects[1] != 0) - { - setting_pens(1, &painter); - painter.drawLine(QPoint(centerX, height() * 0.05), QPoint((width() + rectWidth) / 2, height() * 0.05)); - } - if (objects[2] != 0) - { - setting_pens(2, &painter); - painter.drawLine(QPoint(BottomRight, height() * 0.15), QPoint(TopRight + margin, height() * 0.1)); - } +// Lane::paintEvent(event); +// QPainter painter(this); +// painter.setRenderHint(QPainter::Antialiasing); +// int BottomLeft = width() * 0.35; +// int BottomRight = width() * 0.65; +// int TopLeft = width() * 0.4; +// int TopRight = width() * 0.6; + +// int rectWidth = 9; +// int margin = 10; +// int centerX = (width() - rectWidth) / 2; + +// if (objects[0] != 0) +// { +// setting_pens(0, &painter); +// painter.drawLine(QPoint(BottomLeft, height() * 0.15), QPoint(TopLeft - margin, height() * 0.1)); +// } +// if (objects[1] != 0) +// { +// setting_pens(1, &painter); +// painter.drawLine(QPoint(centerX, height() * 0.05), QPoint((width() + rectWidth) / 2, height() * 0.05)); +// } +// if (objects[2] != 0) +// { +// setting_pens(2, &painter); +// painter.drawLine(QPoint(BottomRight, height() * 0.15), QPoint(TopRight + margin, height() * 0.1)); +// } } //parsing -void Object::set_object(std::string str) +void Object::set_object(int i) { - std::vector temp(3, 0); - int j = -1; - for (int i = 0; i < str.size(); i++) - { - if (str[i] == ',' || i == str.size() - 1) - { - int n = i; - while (n - 1 >= 0 && str[n - 1] != ',') - n--; - if (i == str.size() - 1) - i++; - temp[++j] = std::stoi(str.substr(n, i - n)); - } - } - if (objects == temp) + if (object == i or (i != 1 && i != 2)) return; - objects = temp; + object = i; + std::cout << "Object: " << object << std::endl; + // objects.clear(); + // objects.resize(3, 0); + // objects[0] = i % 10; // left + // objects[1] = (i / 10) % 10; // center + // objects[2] = (i / 100) % 10; // right // std::cout << "Object: " << objects[0] << " " << objects[1] << " " << objects[2] << std::endl; - update(); + // update(); } -std::vector Object::get_object() +// // std::vector temp(3, 0); +// // int j = -1; +// // for (int i = 0; i < str.size(); i++) +// // { +// // if (str[i] == ',' || i == str.size() - 1) +// // { +// // int n = i; +// // while (n - 1 >= 0 && str[n - 1] != ',') +// // n--; +// // if (i == str.size() - 1) +// // i++; +// // temp[++j] = std::stoi(str.substr(n, i - n)); +// // } +// // } + +// // if (objects == temp) +// // return; +// // objects = temp; +// // std::cout << "Object: " << objects[0] << " " << objects[1] << " " << objects[2] << std::endl; +// update(); + + +int Object::get_object() { - return objects; + return object; } Object::~Object()