Index: denali.pro =================================================================== diff -u -r56d00a82669a7a2c00ab90109a89dbec8db27527 -rb9c5b0b3afc3b34d4980ecc4f023f498f80dafbc --- denali.pro (.../denali.pro) (revision 56d00a82669a7a2c00ab90109a89dbec8db27527) +++ denali.pro (.../denali.pro) (revision b9c5b0b3afc3b34d4980ecc4f023f498f80dafbc) @@ -120,6 +120,18 @@ unittests/tst_canbus.cpp } +tst_logging { + message(Building with QtTest test case logging) + QT += testlib + DEFINES += UNIT_TEST \ + TEST_CLASS_INCLUDE=\\\"unittests/tst_logging.h\\\" \ + TEST_CLASS_NAME=tst_logging + HEADERS += \ + unittests/tst_logging.h + SOURCES += \ + unittests/tst_logging.cpp +} + # Additional import path used to resolve QML modules in Qt Creator's code model QML_IMPORT_PATH = Index: denali.pro.user =================================================================== diff -u -r561055268da68e24fe91a1148b76bf1785dae14d -rb9c5b0b3afc3b34d4980ecc4f023f498f80dafbc --- denali.pro.user (.../denali.pro.user) (revision 561055268da68e24fe91a1148b76bf1785dae14d) +++ denali.pro.user (.../denali.pro.user) (revision b9c5b0b3afc3b34d4980ecc4f023f498f80dafbc) @@ -1,14 +1,14 @@ - + EnvironmentId {67370740-e20f-4fc6-be45-6652e866a8bf} ProjectExplorer.Project.ActiveTarget - 0 + 1 ProjectExplorer.Project.EditorSettings @@ -65,14 +65,14 @@ ProjectExplorer.Project.Target.0 - Desktop Qt 5.12.5 GCC 64bit - Desktop Qt 5.12.5 GCC 64bit - qt.qt5.5125.gcc_64_kit - 3 + Qt 5.12.5 (iMX8) + Qt 5.12.5 (iMX8) + {5d6458ef-f917-4aef-a092-c77bbe106149} + 0 0 0 - /home/denali/Project/tmp/build/denali-Desktop_Qt_5_12_5_GCC_64bit-Debug + /home/denali/Project/tmp/build/denali-Qt_5_12_5_iMX8-Debug true @@ -83,7 +83,7 @@ false false - true + false true @@ -128,7 +128,7 @@ true - /home/denali/Project/tmp/build/denali-Desktop_Qt_5_12_5_GCC_64bit-Release + /home/denali/Project/tmp/build/denali-Qt_5_12_5_iMX8-Release true @@ -184,7 +184,7 @@ true - /home/denali/Project/tmp/build/denali-Desktop_Qt_5_12_5_GCC_64bit-Profile + /home/denali/Project/tmp/build/denali-Qt_5_12_5_iMX8-Profile true @@ -239,112 +239,58 @@ 0 true - - /home/denali/Project/tmp/build/unittest/tst_canbus + 3 + true - qmake + Check for free disk space - QtProjectManager.QMakeBuildStep - true - CONFIG+=tst_canbus CONFIG+=CodeCoverage - false - true - true + RemoteLinux.CheckForFreeDiskSpaceStep + + + + + / + 5242880 + + true - Make + Kill current application instance - Qt4ProjectManager.MakeStep - - false - LINK=csg++ AR=csar CXX=csg++ CC=csgcc -j4 - - false + RemoteLinux.KillAppStep + + + + + + true - - %{buildDir}/denali - %{buildDir} - Custom Process Step + Deploy files via rsync - ProjectExplorer.ProcessStep + RemoteLinux.RsyncDeployStep + + + + + + + -av + false - - true - -m denali.csmes -t UnitTests denali.csexe - cmcsexeimport - %{buildDir} - Custom Process Step - - ProjectExplorer.ProcessStep - - - true - --csmes=denali.csmes --html=Coverage/index - cmreport - %{buildDir} - Custom Process Step - - ProjectExplorer.ProcessStep - - - true - --csmes=denali.csmes --csv-excel=Coverage/coverage.csv - cmreport - %{buildDir} - Custom Process Step - - ProjectExplorer.ProcessStep - - 6 - Build - - ProjectExplorer.BuildSteps.Build - - - - true - Make - - Qt4ProjectManager.MakeStep - - true - clean - - false - - 1 - Clean - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - PATH=/opt/SquishCoco/bin:/opt/SquishCoco/wrapper/bin:/opt/Qt5.12.5/5.12.5/gcc_64/bin:/usr/bin:/home/denali/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin - - Test - tst_canbus - Qt4ProjectManager.Qt4BuildConfiguration - 2 - true - - 4 - - - 0 + 3 Deploy ProjectExplorer.BuildSteps.Deploy 1 - Deploy Configuration + Deploy to Remote Linux Host - ProjectExplorer.DefaultDeployConfiguration + DeployToGenericLinux 1 @@ -398,36 +344,40 @@ 13 14 - 2 + 1 - denali - - Qt4ProjectManager.Qt4RunConfiguration:/home/denali/Project/application/denali.pro + + denali (on Generic Linux Device (iMX8)) + RemoteLinuxRunConfiguration:/home/denali/Project/application/denali.pro + 1 + + false 3768 false true - true false - true - false + false + true + false - /home/denali/Project/tmp/build/unittest/tst_canbus + + :0 1 ProjectExplorer.Project.Target.1 - Qt 5.12.5 (iMX8) - Qt 5.12.5 (iMX8) - {5d6458ef-f917-4aef-a092-c77bbe106149} - 1 + Desktop Qt 5.12.5 GCC 64bit + Desktop Qt 5.12.5 GCC 64bit + qt.qt5.5125.gcc_64_kit + 0 0 0 - /home/denali/Project/tmp/build/denali-Qt_5_12_5_iMX8-Debug + /home/denali/Project/tmp/build/denali-Desktop_Qt_5_12_5_GCC_64bit-Debug true @@ -438,7 +388,7 @@ false false - false + true true @@ -483,7 +433,7 @@ true - /home/denali/Project/tmp/build/denali-Qt_5_12_5_iMX8-Release + /home/denali/Project/tmp/build/denali-Desktop_Qt_5_12_5_GCC_64bit-Release true @@ -539,7 +489,7 @@ true - /home/denali/Project/tmp/build/denali-Qt_5_12_5_iMX8-Profile + /home/denali/Project/tmp/build/denali-Desktop_Qt_5_12_5_GCC_64bit-Profile true @@ -594,58 +544,206 @@ 0 true - 3 - + + /home/denali/Project/tmp/build/unittest/tst_canbus true - Check for free disk space + qmake - RemoteLinux.CheckForFreeDiskSpaceStep - - - - - / - 5242880 - - + QtProjectManager.QMakeBuildStep + true + CONFIG+=tst_canbus CONFIG+=CodeCoverage + false + true + true true - Kill current application instance + Make - RemoteLinux.KillAppStep - - - - - - + Qt4ProjectManager.MakeStep + + false + LINK=csg++ AR=csar CXX=csg++ CC=csgcc -j4 + + false true - Deploy files via rsync + + %{buildDir}/denali + %{buildDir} + Custom Process Step - RemoteLinux.RsyncDeployStep - - - - - - - -av - false + ProjectExplorer.ProcessStep - 3 + + true + -m denali.csmes -t UnitTests denali.csexe + cmcsexeimport + %{buildDir} + Custom Process Step + + ProjectExplorer.ProcessStep + + + true + --csmes=denali.csmes --html=Coverage/index + cmreport + %{buildDir} + Custom Process Step + + ProjectExplorer.ProcessStep + + + true + --csmes=denali.csmes --csv-excel=Coverage/coverage.csv + cmreport + %{buildDir} + Custom Process Step + + ProjectExplorer.ProcessStep + + 6 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + PATH=/opt/SquishCoco/bin:/opt/SquishCoco/wrapper/bin:/opt/Qt5.12.5/5.12.5/gcc_64/bin:/usr/bin:/home/denali/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin + + Test + tst_canbus + Qt4ProjectManager.Qt4BuildConfiguration + 2 + true + + + /home/denali/Project/tmp/build/unittest/tst_logging + + + true + qmake + + QtProjectManager.QMakeBuildStep + true + CONFIG+=tst_logging CONFIG+=CodeCoverage + false + true + true + + + true + Make + + Qt4ProjectManager.MakeStep + + false + LINK=csg++ AR=csar CXX=csg++ CC=csgcc -j4 + + false + + + true + + %{buildDir}/denali + %{buildDir} + Custom Process Step + + ProjectExplorer.ProcessStep + + + true + -m denali.csmes -t UnitTests denali.csexe + cmcsexeimport + %{buildDir} + Custom Process Step + + ProjectExplorer.ProcessStep + + + true + --csmes=denali.csmes --html=Coverage/index + cmreport + %{buildDir} + Custom Process Step + + ProjectExplorer.ProcessStep + + + true + --csmes=denali.csmes --csv-excel=Coverage/coverage.csv + cmreport + %{buildDir} + Custom Process Step + + ProjectExplorer.ProcessStep + + 6 + Build + + ProjectExplorer.BuildSteps.Build + + + + true + Make + + Qt4ProjectManager.MakeStep + + true + clean + + false + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + PATH=/opt/SquishCoco/bin:/opt/SquishCoco/wrapper/bin:/opt/Qt5.12.5/5.12.5/gcc_64/bin:/usr/bin:/home/denali/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin + + Test + tst_logging + Qt4ProjectManager.Qt4BuildConfiguration + 2 + true + + 5 + + + 0 Deploy ProjectExplorer.BuildSteps.Deploy 1 - Deploy to Remote Linux Host + Deploy Configuration - DeployToGenericLinux + ProjectExplorer.DefaultDeployConfiguration 1 @@ -699,25 +797,21 @@ 13 14 - 1 + 2 - - denali (on Generic Linux Device (iMX8)) - RemoteLinuxRunConfiguration:/home/denali/Project/application/denali.pro - 1 - - false + denali + + Qt4ProjectManager.Qt4RunConfiguration:/home/denali/Project/application/denali.pro 3768 false true + true false - false - true - false + true + false - - :0 + /home/denali/Project/tmp/build/denali-Desktop_Qt_5_12_5_GCC_64bit-Debug 1 Index: main.cpp =================================================================== diff -u -r56d00a82669a7a2c00ab90109a89dbec8db27527 -rb9c5b0b3afc3b34d4980ecc4f023f498f80dafbc --- main.cpp (.../main.cpp) (revision 56d00a82669a7a2c00ab90109a89dbec8db27527) +++ main.cpp (.../main.cpp) (revision b9c5b0b3afc3b34d4980ecc4f023f498f80dafbc) @@ -95,7 +95,7 @@ Threads::registerTypes(); //! - Initializing Logger - _Logger.init(); + _Logger.init(Threads::_Logger_Thread); LOG_EVENT(QObject::tr("Application Started")); Index: sources/applicationcontroller.cpp =================================================================== diff -u -r862dc0590b73c618fac73dce2c976e3526e0404a -rb9c5b0b3afc3b34d4980ecc4f023f498f80dafbc --- sources/applicationcontroller.cpp (.../applicationcontroller.cpp) (revision 862dc0590b73c618fac73dce2c976e3526e0404a) +++ sources/applicationcontroller.cpp (.../applicationcontroller.cpp) (revision b9c5b0b3afc3b34d4980ecc4f023f498f80dafbc) @@ -102,6 +102,9 @@ connect(&_GuiController , SIGNAL(didExportLog()), this , SLOT( onExportLog())); + + connect(&_Logger , SIGNAL(didExport()), + this , SLOT( onExport())); } /*! @@ -203,14 +206,19 @@ */ void ApplicationController::onExportLog() { - Storage::FileHandler fh; - fh.concurrentExportLog(); - //TODO : it needs to change in a way that we can have an actual export finish time and then emit signal. - // this is not accurate. - emit didExportLog(); + _Logger.concurrentExport(); } /*! + * \brief ApplicationController::onExport + * \details the slot which will be called by logger is done exporting. + */ +void ApplicationController::onExport() +{ + emit didExport(); +} + +/*! * \brief ApplicationController::keepAlive * \details This is the message which has to be send over the CANBUS * as an monitor for other nodes on the bus to notify UI is alive Index: sources/applicationcontroller.h =================================================================== diff -u -r56d00a82669a7a2c00ab90109a89dbec8db27527 -rb9c5b0b3afc3b34d4980ecc4f023f498f80dafbc --- sources/applicationcontroller.h (.../applicationcontroller.h) (revision 56d00a82669a7a2c00ab90109a89dbec8db27527) +++ sources/applicationcontroller.h (.../applicationcontroller.h) (revision b9c5b0b3afc3b34d4980ecc4f023f498f80dafbc) @@ -65,6 +65,7 @@ void onUSBDriveRemove(); void onExportLog (); + void onExport (); signals: void didActionReceive (GuiActionType vAction, const QVariantList &vData); // UI <= HD/DG @@ -74,6 +75,6 @@ void didUSBDriveUmount(); void didUSBDriveRemove(); - void didExportLog(); + void didExport (); }; Index: sources/gui/guicontroller.cpp =================================================================== diff -u -r862dc0590b73c618fac73dce2c976e3526e0404a -rb9c5b0b3afc3b34d4980ecc4f023f498f80dafbc --- sources/gui/guicontroller.cpp (.../guicontroller.cpp) (revision 862dc0590b73c618fac73dce2c976e3526e0404a) +++ sources/gui/guicontroller.cpp (.../guicontroller.cpp) (revision b9c5b0b3afc3b34d4980ecc4f023f498f80dafbc) @@ -71,6 +71,10 @@ this , SLOT( onUSBDriveMount ())); connect(&_ApplicationController, SIGNAL(didUSBDriveRemove()), this , SLOT( onUSBDriveRemove())); + + connect(&_ApplicationController, SIGNAL(didExport()), + this , SLOT( onExport())); + } /*! @@ -217,6 +221,16 @@ } /*! + * \brief GuiController::onExport + * \details The slot which will be called to notify the export is done + * by emitting the didExport signal. + */ +void GuiController::onExport() +{ + emit didExport(); +} + +/*! * \brief GuiController::doExportLog * \details emits didExportLog signal to notify other classes (ApplicationController) * , the User requested to export the log. Index: sources/gui/guicontroller.h =================================================================== diff -u -r56d00a82669a7a2c00ab90109a89dbec8db27527 -rb9c5b0b3afc3b34d4980ecc4f023f498f80dafbc --- sources/gui/guicontroller.h (.../guicontroller.h) (revision 56d00a82669a7a2c00ab90109a89dbec8db27527) +++ sources/gui/guicontroller.h (.../guicontroller.h) (revision b9c5b0b3afc3b34d4980ecc4f023f498f80dafbc) @@ -64,6 +64,8 @@ void onUSBDriveMount (); // OS => UI void onUSBDriveRemove(); // OS => UI + void onExport (); // OS => UI + signals: void didActionReceive (GuiActionType vAction, const QVariantList &vData); // UI <= HD/DG void didActionTransmit(GuiActionType vAction, const QVariantList &vData); // UI => HD/DG @@ -73,6 +75,7 @@ void didUSBDriveRemove(); void didExportLog(); + void didExport (); }; } Index: sources/gui/guiview.cpp =================================================================== diff -u -r56d00a82669a7a2c00ab90109a89dbec8db27527 -rb9c5b0b3afc3b34d4980ecc4f023f498f80dafbc --- sources/gui/guiview.cpp (.../guiview.cpp) (revision 56d00a82669a7a2c00ab90109a89dbec8db27527) +++ sources/gui/guiview.cpp (.../guiview.cpp) (revision b9c5b0b3afc3b34d4980ecc4f023f498f80dafbc) @@ -55,6 +55,9 @@ connect(&_GuiController, SIGNAL(didUSBDriveRemove()), this , SLOT( doUSBDriveRemove())); + connect(&_GuiController, SIGNAL(didExport()), + this , SLOT( doExport())); + // From UI : Export Log connect(this , SIGNAL(didExportLog()), &_GuiController, SLOT( doExportLog())); @@ -133,6 +136,16 @@ } /*! + * \brief GuiView::onExport + * \details The slot which will be called to notify the export is done + * by emitting the didExport signal. + */ +void GuiView::doExport() +{ + emit didExport(); +} + +/*! * \brief GuiView::doExportLog * \details emits didExportLog signal to notify other classes (GuiController) * , the User requested to export the log. Index: sources/gui/guiview.h =================================================================== diff -u -rfeb3423b373dc2a2c4267ef9fcb4d924d738423d -rb9c5b0b3afc3b34d4980ecc4f023f498f80dafbc --- sources/gui/guiview.h (.../guiview.h) (revision feb3423b373dc2a2c4267ef9fcb4d924d738423d) +++ sources/gui/guiview.h (.../guiview.h) (revision b9c5b0b3afc3b34d4980ecc4f023f498f80dafbc) @@ -41,6 +41,8 @@ void doUSBDriveMount (); void doUSBDriveRemove(); + void doExport (); + public slots: // is public since will be used in the UI and is in the same thread. void doActionTransmit(GuiActionType vAction, const QVariantList &vData); // UI => HD/DG void doActionTransmit(GuiActionType vAction, const QVariant &vData); // UI => HD/DG @@ -59,5 +61,6 @@ void didUSBDriveRemove(); void didExportLog(); + void didExport (); }; } Index: sources/gui/qml/components/ExportButton.qml =================================================================== diff -u -r5963f00ffd2c557d3ae06a5deea05032a3a3bd68 -rb9c5b0b3afc3b34d4980ecc4f023f498f80dafbc --- sources/gui/qml/components/ExportButton.qml (.../ExportButton.qml) (revision 5963f00ffd2c557d3ae06a5deea05032a3a3bd68) +++ sources/gui/qml/components/ExportButton.qml (.../ExportButton.qml) (revision b9c5b0b3afc3b34d4980ecc4f023f498f80dafbc) @@ -24,12 +24,10 @@ height: width x: width - 10 animated: true - text.text: qsTr("Export") text.font.pixelSize: Fonts.fontPixelButton * 0.75 button.onPressed: { _GuiView.doExportLog() - //animate(true) } Connections { target: _GuiView @@ -43,5 +41,11 @@ onDidUSBDriveMount: { _root.disabled = false } + onDidExportLog: { + _root.disabled = true + } + onDidExport: { + _root.disabled = false + } } } Index: sources/gui/qml/components/USBButton.qml =================================================================== diff -u -r5963f00ffd2c557d3ae06a5deea05032a3a3bd68 -rb9c5b0b3afc3b34d4980ecc4f023f498f80dafbc --- sources/gui/qml/components/USBButton.qml (.../USBButton.qml) (revision 5963f00ffd2c557d3ae06a5deea05032a3a3bd68) +++ sources/gui/qml/components/USBButton.qml (.../USBButton.qml) (revision b9c5b0b3afc3b34d4980ecc4f023f498f80dafbc) @@ -42,5 +42,11 @@ onDidUSBDriveMount: { _root.disabled = false } + onDidExportLog: { + _root.disabled = true + } + onDidExport: { + _root.disabled = false + } } } Index: sources/gui/qml/pages/TreatmentHome.qml =================================================================== diff -u -r5963f00ffd2c557d3ae06a5deea05032a3a3bd68 -rb9c5b0b3afc3b34d4980ecc4f023f498f80dafbc --- sources/gui/qml/pages/TreatmentHome.qml (.../TreatmentHome.qml) (revision 5963f00ffd2c557d3ae06a5deea05032a3a3bd68) +++ sources/gui/qml/pages/TreatmentHome.qml (.../TreatmentHome.qml) (revision b9c5b0b3afc3b34d4980ecc4f023f498f80dafbc) @@ -33,27 +33,6 @@ property alias createTreatmentButton: _createTreatmentRect.button // exported properties - // - - USBButton { - x: 50 - anchors { - top : parent.top - topMargin : (Variables.headerHeight - Variables.logoHeight) / 2 - rightMargin : (Variables.headerHeight - Variables.logoHeight) / 2 - } - } - ExportButton { - x: 150 - width: 150 - height: 50 - anchors { - top : parent.top - topMargin : (Variables.headerHeight - Variables.logoHeight) / 2 - rightMargin : (Variables.headerHeight - Variables.logoHeight) / 2 - } - } - TreatmentStart { id : _treatmentStart onBackPressed: { _treatmentStack.pop() Index: sources/gui/qml/pages/TreatmentStart.qml =================================================================== diff -u -rfeb3423b373dc2a2c4267ef9fcb4d924d738423d -rb9c5b0b3afc3b34d4980ecc4f023f498f80dafbc --- sources/gui/qml/pages/TreatmentStart.qml (.../TreatmentStart.qml) (revision feb3423b373dc2a2c4267ef9fcb4d924d738423d) +++ sources/gui/qml/pages/TreatmentStart.qml (.../TreatmentStart.qml) (revision b9c5b0b3afc3b34d4980ecc4f023f498f80dafbc) @@ -42,6 +42,25 @@ // } //} + USBButton { + x: 200 + anchors { + top : parent.top + topMargin : (Variables.headerHeight - Variables.logoHeight) / 2 + rightMargin : (Variables.headerHeight - Variables.logoHeight) / 2 + } + } + ExportButton { + x: 300 + width: 150 + height: 50 + anchors { + top : parent.top + topMargin : (Variables.headerHeight - Variables.logoHeight) / 2 + rightMargin : (Variables.headerHeight - Variables.logoHeight) / 2 + } + } + Column { id: _BloodFlowColumn width: 150 spacing: 20 Index: sources/storage/filehandler.cpp =================================================================== diff -u -r56d00a82669a7a2c00ab90109a89dbec8db27527 -rb9c5b0b3afc3b34d4980ecc4f023f498f80dafbc --- sources/storage/filehandler.cpp (.../filehandler.cpp) (revision 56d00a82669a7a2c00ab90109a89dbec8db27527) +++ sources/storage/filehandler.cpp (.../filehandler.cpp) (revision b9c5b0b3afc3b34d4980ecc4f023f498f80dafbc) @@ -77,8 +77,7 @@ * \param vDestination - The destination folder * \return Tue on successful execution. * \note This method uses the Linux "cp -r vSource vDestination" command - * Not a Thread-Safe method so made private to be called by export log - * QtConcurrent::run. + * Not a Thread-Safe. * */ int FileHandler::copyFolder(const QString &vSource, const QString &vDestination ) @@ -89,19 +88,3 @@ return QProcess::execute(cp, arguments); } -/*! - * \brief FileHandler::concurrentExportLog - * \details Exports the log files from log folder (Storage::Log_Base_Path_Name_Location) - * into USB drive folder (Storage::USB_Mount_Point) - * \return always returns true for now. - * \note This method uses QtConcurrent run to execute the copyFolder method. - */ -bool FileHandler::concurrentExportLog() -{ - QString mSource = Storage::Log_Base_Path_Name_Location; - QString mDestination = Storage::USB_Mount_Point; - //QFuture future = - QtConcurrent::run(this, &FileHandler::copyFolder, mSource, mDestination); - //return future.result(); - return true; -} Index: sources/storage/filehandler.h =================================================================== diff -u -r56d00a82669a7a2c00ab90109a89dbec8db27527 -rb9c5b0b3afc3b34d4980ecc4f023f498f80dafbc --- sources/storage/filehandler.h (.../filehandler.h) (revision 56d00a82669a7a2c00ab90109a89dbec8db27527) +++ sources/storage/filehandler.h (.../filehandler.h) (revision b9c5b0b3afc3b34d4980ecc4f023f498f80dafbc) @@ -20,15 +20,11 @@ class FileHandler { - -private: - int copyFolder(const QString &vSource, const QString &vDestination); - public: static bool write(const QString &vFileName, const QString &vContent, bool vAppend = true); - static bool read (const QString &vFileName, QString &vContent); + static bool read (const QString &vFileName, QString &vContent); - bool concurrentExportLog (); + static int copyFolder(const QString &vSource, const QString &vDestination); }; } Index: sources/storage/logger.cpp =================================================================== diff -u -r56d00a82669a7a2c00ab90109a89dbec8db27527 -rb9c5b0b3afc3b34d4980ecc4f023f498f80dafbc --- sources/storage/logger.cpp (.../logger.cpp) (revision 56d00a82669a7a2c00ab90109a89dbec8db27527) +++ sources/storage/logger.cpp (.../logger.cpp) (revision b9c5b0b3afc3b34d4980ecc4f023f498f80dafbc) @@ -40,23 +40,45 @@ if ( _init ) return false; _init = true; - // runs in main thread - Q_ASSERT_X(QThread::currentThread() == qApp->thread() , __func__, "The Class initialization must be done in Main Thread" ); - // runs in thread checkLogPath(); initConnections(); + + LOG_EVENT(QObject::tr("%1 Initialized").arg(metaObject()->className())); + return true; } /*! - * \brief Logger::quit - * \details Does nothing for now + * \brief Logger::init + * \details Initialized the Class by calling the init() method first + * And initializes the thread vThread by calling initThread + * on success init(). + * \param vThread - the thread + * \return returns the return value of the init() method */ +bool Logger::init(QThread &vThread) +{ + if ( ! init() ) return false; + initThread(vThread); + return true; +} + +/*! + * \brief Logger quit + * \details quits the class + * Calls quitThread + */ void Logger::quit() { + quitThread(); } +void Logger::onLog(const QString &vContent, LogType vLogType) +{ + log(vContent,vLogType); +} + /*! * \brief Logger::initConnections * \details Initializes the required signal/slot connection between this class and other objects @@ -65,9 +87,45 @@ */ void Logger::initConnections() { + connect(&_exportWatcher, SIGNAL(finished()), + this , SLOT(onExport())); + + connect(this, SIGNAL(didLog(QString,LogType)), + this, SLOT( onLog(QString,LogType))); } /*! + * \brief Logger::initThread + * \details Moves this object into the thread vThread. + * And checks that this method is called from main thread. + * Also connects quitThread to application aboutToQuit. + * \param vThread - the thread + */ +void Logger::initThread(QThread &vThread) +{ + // runs in main thread + Q_ASSERT_X(QThread::currentThread() == qApp->thread() , __func__, "The Class initialization must be done in Main Thread" ); + _thread = &vThread; + _thread->setObjectName(QString("%1_Thread").arg(metaObject()->className())); + connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(quit())); + _thread->start(); + moveToThread(_thread); +} + +/*! + * \brief Logger::quitThread + * \details Moves this object to main thread to be handled by QApplicaiton + * And to be destroyed there. + */ +void Logger::quitThread() +{ + if (! _thread) return; + + // runs in thread + moveToThread(qApp->thread()); +} + +/*! * \brief Logger::checkLogPath * \details Sets the log paths and creates them if didn't exist. */ @@ -105,9 +163,9 @@ bool Logger::setLogPath() { bool ok = true; - ok = ok && setLogPath(LogType::eLogDatum); ok = ok && setLogPath(LogType::eLogEvent); ok = ok && setLogPath(LogType::eLogError); + ok = ok && setLogPath(LogType::eLogDatum); return ok; } @@ -147,34 +205,42 @@ QString mContent; switch (vLogType) { - case eLogDatum: case eLogEvent: case eLogError: + case eLogDatum: break; default: - Q_ASSERT_X(false, "Logger::log", "Incorrect type of logging"); + LOG_ERROR(tr("Incorrect type of logging").arg(vLogType)); } mContent += _logPrefix[vLogType]; mContent += _prefixSeparator; mContent += QTime::currentTime().toString(_timeFormat); mContent += _timeSeparator + vContent; QString fileName = date + _dateSeparator + Log_File_Name; - FileHandler::write(_logPathNames[vLogType] + fileName, mContent + "\r\n", true); + _logFileName = _logPathNames[vLogType] + fileName; + FileHandler::write(_logFileName, mContent + "\r\n", true); if (vLogType == eLogError) { qDebug().noquote() << mContent; } } /*! - * \brief Logger::concurrentLog - * \details The thread safe of calling the log method in a separate thread. - * This method uses the QtConcurrent::run to call the log in separate thread and thread-safe. - * \param vContent - the content to be logged - * \param vLogType - The log type + * \brief Logger::concurrentExport + * \details Exports the log files from log folder (Storage::Log_Base_Path_Name_Location) + * into USB drive folder (Storage::USB_Mount_Point) + * \return always returns true for now. + * \note This method uses QtConcurrent run to execute the FileHandler copyFolder method. */ -void Logger::concurrentLog(const QString &vContent, LogType vLogType) +bool Logger::concurrentExport() { - // QFuture future = - QtConcurrent::run(this,&Logger::log, vContent, vLogType); - // qDebug() << future.result(); + QString mSource = Storage::Log_Base_Path_Name_Location; + QString mDestination = Storage::USB_Mount_Point; + QFuture future = QtConcurrent::run(&FileHandler::copyFolder, mSource, mDestination); + _exportWatcher.setFuture(future); + return true; } + +void Logger::onExport() +{ + emit didExport(); +} Index: sources/storage/logger.h =================================================================== diff -u -r56d00a82669a7a2c00ab90109a89dbec8db27527 -rb9c5b0b3afc3b34d4980ecc4f023f498f80dafbc --- sources/storage/logger.h (.../logger.h) (revision 56d00a82669a7a2c00ab90109a89dbec8db27527) +++ sources/storage/logger.h (.../logger.h) (revision b9c5b0b3afc3b34d4980ecc4f023f498f80dafbc) @@ -16,6 +16,7 @@ // Qt #include #include +#include // Project #include "main.h" @@ -24,10 +25,13 @@ // Define #define _Logger Storage::Logger::I() -#define LOG_DATUM(vCONTENT) Storage::Logger::I().concurrentLog(vCONTENT, Storage::Logger::LogType::eLogDatum) -#define LOG_EVENT(vCONTENT) Storage::Logger::I().concurrentLog(vCONTENT, Storage::Logger::LogType::eLogEvent) -#define LOG_ERROR(vCONTENT) Storage::Logger::I().concurrentLog(vCONTENT, Storage::Logger::LogType::eLogError) +#define LOG_EVENT(vCONTENT) emit Storage::Logger::I().didLog(vCONTENT, Storage::Logger::LogType::eLogEvent) +#define LOG_ERROR(vCONTENT) emit Storage::Logger::I().didLog(vCONTENT, Storage::Logger::LogType::eLogError) +#define LOG_DATUM(vCONTENT) emit Storage::Logger::I().didLog(vCONTENT, Storage::Logger::LogType::eLogDatum) +// forward declarations +class tst_logging; + namespace Storage { /*! @@ -44,25 +48,28 @@ { Q_OBJECT + // friends + friend class ::tst_logging; + public: enum LogType { - eLogDatum, eLogEvent, eLogError, + eLogDatum, }; private: QDir _dir; QHash _logPathNames; QHash _logBasePathNames { - { eLogDatum, "log/event/" }, // "log/datum/" { eLogEvent, "log/event/" }, { eLogError, "log/error/" }, + { eLogDatum, "log/event/" }, // "log/datum/" }; QHash _logPrefix { - { eLogDatum, "Datum" }, { eLogEvent, "Event" }, { eLogError, "Error" }, + { eLogDatum, "Datum" }, }; const char *_dateFormat = "yyyy_MM_dd"; @@ -72,31 +79,51 @@ const char *_dateSeparator = "_" ; const char *_timeSeparator = " , "; - bool _init = false; + QString _logFileName = ""; + + QFutureWatcher _exportWatcher; + + QThread *_thread = nullptr; + bool _init = false; + // Singleton SINGLETON(Logger) -public: +public slots: bool init(); + bool init(QThread &vThread); + +private slots: void quit(); - private: void initConnections(); + void initThread(QThread &vThread); + void quitThread(); + private: -// setting up +// ----- setting up void checkLogPath (); void setLogBasePath (bool vUseApplicationDirPath = false); bool setLogPath (); bool setLogPath (LogType vLogType); +// ----- Export structure public slots: - void concurrentLog (const QString &vContent, LogType vLogType); + bool concurrentExport(); +private slots: + void onExport(); +signals: + void didExport(); +// ----- logging structure +private slots: + void onLog(const QString &vContent, LogType vLogType); private: void log (const QString &vContent, LogType vLogType); - +signals: + void didLog (const QString &vContent, LogType vLogType); }; } Index: sources/threads.cpp =================================================================== diff -u -r56d00a82669a7a2c00ab90109a89dbec8db27527 -rb9c5b0b3afc3b34d4980ecc4f023f498f80dafbc --- sources/threads.cpp (.../threads.cpp) (revision 56d00a82669a7a2c00ab90109a89dbec8db27527) +++ sources/threads.cpp (.../threads.cpp) (revision b9c5b0b3afc3b34d4980ecc4f023f498f80dafbc) @@ -31,6 +31,7 @@ QThread _CanFrame_Thread; QThread _CanMessage_Thread; QThread _USBWatcher_Thread; + QThread _Logger_Thread; QThread _Application_Thread; /*! @@ -75,6 +76,7 @@ quitThread(_CanFrame_Thread ); quitThread(_CanMessage_Thread ); quitThread(_USBWatcher_Thread ); + quitThread(_Logger_Thread ); quitThread(_Application_Thread); } } Index: sources/threads.h =================================================================== diff -u -r56d00a82669a7a2c00ab90109a89dbec8db27527 -rb9c5b0b3afc3b34d4980ecc4f023f498f80dafbc --- sources/threads.h (.../threads.h) (revision 56d00a82669a7a2c00ab90109a89dbec8db27527) +++ sources/threads.h (.../threads.h) (revision b9c5b0b3afc3b34d4980ecc4f023f498f80dafbc) @@ -29,11 +29,11 @@ extern QThread _CanFrame_Thread ; extern QThread _CanMessage_Thread ; extern QThread _USBWatcher_Thread ; + extern QThread _Logger_Thread ; extern QThread _Application_Thread; void registerTypes(); void quitThread (QThread &vThread); void quitThreads(); - } Index: unittests/tst_canbus.cpp =================================================================== diff -u -r56d00a82669a7a2c00ab90109a89dbec8db27527 -rb9c5b0b3afc3b34d4980ecc4f023f498f80dafbc --- unittests/tst_canbus.cpp (.../tst_canbus.cpp) (revision 56d00a82669a7a2c00ab90109a89dbec8db27527) +++ unittests/tst_canbus.cpp (.../tst_canbus.cpp) (revision b9c5b0b3afc3b34d4980ecc4f023f498f80dafbc) @@ -1,6 +1,6 @@ /*! * - * Copyright (c) 2019-2019 Diality Inc. - All Rights Reserved. + * Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. * copyright * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, * IN PART OR IN WHOLE, @@ -93,7 +93,7 @@ { _expected = QByteArray("123456789"); _FrameInterface.transmitFrame(Can_Id::eChlid_HD, _expected); - QCOMPARE(_emited, false); //there is no signal call - Code Coverage only : Error : "Payload can't be larger than 8 bytes" + QVERIFY( ! _emited ); //there is no signal call - Code Coverage only : Error : "Payload can't be larger than 8 bytes" } void tst_canbus::tst_FrameInterface_ActionTransmit_PowerOff_Accepted() @@ -134,7 +134,7 @@ { _expected = ""; _MessageDispatcher.onActionTransmit(Gui::GuiActionType::Unknown, {}); - QCOMPARE(_emited, false); // should not emit the signal due to unknown action + QVERIFY( ! _emited ); // should not emit the signal due to unknown action } void tst_canbus::tst_FrameInterface_FrameReceived_PowerOff() @@ -173,7 +173,7 @@ mPayload = "A5.01.00.01.01.5E.00.00"; mFrame.setPayload(QByteArray::fromHex(mPayload.remove(QLatin1Char('.')).toLatin1())); emit _CanInterface.didFrameReceive(mFrame); - QCOMPARE(_emited, false); // should not be emitted due to not listening channel + QVERIFY( ! _emited ); // should not be emitted due to not listening channel } void tst_canbus::tst_FrameInterface_FrameReceived_Channel_Incorrect() @@ -186,7 +186,7 @@ mPayload = "A5.01.00.01.01.5E.00.00"; mFrame.setPayload(QByteArray::fromHex(mPayload.remove(QLatin1Char('.')).toLatin1())); emit _CanInterface.didFrameReceive(mFrame); - QCOMPARE(_emited, false); // should not be emitted due to not listening channel + QVERIFY( ! _emited ); // should not be emitted due to not listening channel } void tst_canbus::tst_FrameInterface_FrameReceived_CRC_Error() @@ -264,9 +264,54 @@ mFrame.setPayload(QByteArray::fromHex(payload.remove(QLatin1Char('.')).toLatin1())); emit _CanInterface.didFrameReceive(mFrame); } - QCOMPARE(_emited, false); // Should not emit due to - ERROR : "Incorrect data for Message ID (HD) '0x0500'" + QVERIFY( ! _emited ); // Should not emit due to - ERROR : "Incorrect data for Message ID (HD) '0x0500'" } +void tst_canbus::tst_FrameInterface_FrameReceived_LongFrame_AlarmStatus() +{ + _action = Gui::GuiActionType::AlarmStatus; + _data = { 2, 10, 60, 30, + false,true ,false,false, // 0100 + true ,false,false,false, // 1000 + true ,true ,false,false, // 1100 + false,false,false,false, // 0000 + }; + QCanBusFrame mFrame; + mFrame.setFrameId(Can_Id::eChlid_HD_Alarm); + QStringList mPayloadList { + "a5.02.00.12.02.00.00.00" , + "0a.00.00.00.3c.00.00.00" , + "1e.00.00.00.12.03.bb.00" , + }; + for ( QString payload : mPayloadList ) { + mFrame.setPayload(QByteArray::fromHex(payload.remove(QLatin1Char('.')).toLatin1())); + emit _CanInterface.didFrameReceive(mFrame); + } + QVERIFY(_emited); +} + +void tst_canbus::tst_FrameInterface_FrameReceived_LongFrame_AlarmStatus_LessData() +{ + _action = Gui::GuiActionType::AlarmStatus; + _data = { 2, 10, 60, 30, + false,true ,false,false, // 0100 + true ,false,false,false, // 1000 + true ,true ,false,false, // 1100 + false,false,false,false, // 0000 + }; + QCanBusFrame mFrame; + mFrame.setFrameId(Can_Id::eChlid_HD_Alarm); + QStringList mPayloadList { + "a5.02.00.12.02.00.00.00" , + "0a.00.00.00.3c.00.00.00" , + }; + for ( QString payload : mPayloadList ) { + mFrame.setPayload(QByteArray::fromHex(payload.remove(QLatin1Char('.')).toLatin1())); + emit _CanInterface.didFrameReceive(mFrame); + } + QVERIFY( ! _emited ); // Should not emit due to - ERROR : "Incorrect data for Message ID (HD) '0x0200'" +} + void tst_canbus::cleanup() { } Index: unittests/tst_canbus.h =================================================================== diff -u -r561055268da68e24fe91a1148b76bf1785dae14d -rb9c5b0b3afc3b34d4980ecc4f023f498f80dafbc --- unittests/tst_canbus.h (.../tst_canbus.h) (revision 561055268da68e24fe91a1148b76bf1785dae14d) +++ unittests/tst_canbus.h (.../tst_canbus.h) (revision b9c5b0b3afc3b34d4980ecc4f023f498f80dafbc) @@ -1,12 +1,12 @@ /*! * - * Copyright (c) 2019-2019 Diality Inc. - All Rights Reserved. + * Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. * copyright * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, * IN PART OR IN WHOLE, * WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * - * file unittests.h + * file tst_canbus.h * date 11/21/2019 * author Behrouz NematiPour * @@ -53,9 +53,13 @@ void tst_FrameInterface_FrameReceived_CRC_Error(); void tst_FrameInterface_FrameReceived_ShortFrame_Error(); void tst_FrameInterface_FrameReceived_LongFrame_Error(); + void tst_FrameInterface_FrameReceived_LongFrame_BloodFlow(); void tst_FrameInterface_FrameReceived_LongFrame_BloodFlow_LessData(); + void tst_FrameInterface_FrameReceived_LongFrame_AlarmStatus(); + void tst_FrameInterface_FrameReceived_LongFrame_AlarmStatus_LessData(); + void cleanup(); void cleanupTestCase(); }; Index: unittests/tst_logging.cpp =================================================================== diff -u --- unittests/tst_logging.cpp (revision 0) +++ unittests/tst_logging.cpp (revision b9c5b0b3afc3b34d4980ecc4f023f498f80dafbc) @@ -0,0 +1,80 @@ +/*! + * + * Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. + * copyright + * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, + * IN PART OR IN WHOLE, + * WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. + * + * file tst_logging.cpp + * date 01/07/2020 + * author Behrouz NematiPour + * + */ +#include "tst_logging.h" + +// Qt +#include + +// Project +#include "filehandler.h" +#include "logger.h" + +using namespace Storage; + +tst_logging::tst_logging(QObject *parent) : QObject(parent) { } + +// void tst_logging::initTestCase_data() +// { +// } + +void tst_logging::initTestCase() +{ + Threads::registerTypes(); + _Logger._timeFormat = ""; + _Logger.init(); + QString mContent; + FileHandler::read(_Logger._logFileName, mContent); + QCOMPARE(mContent, "Event: , Storage::Logger Initialized\n"); +} + +// void tst_logging::init() +// { +// } + +void tst_logging::cleanup() +{ + QThread::currentThread()->msleep(1000); +} + +void tst_logging::cleanupTestCase() +{ +} + +void tst_logging::logEvent() +{ + LOG_EVENT("1 - Event log has been created"); + QString mContent; + FileHandler::read(_Logger._logFileName, mContent); + QCOMPARE(mContent, "Event: , Storage::Logger Initialized\n" + "Event: , 1 - Event log has been created\n"); +} + +void tst_logging::logError() +{ + LOG_ERROR("2 - Error log has been created"); + QString mContent; + FileHandler::read(_Logger._logFileName, mContent); + QCOMPARE(mContent, "Error: , 2 - Error log has been created\n"); +} + +void tst_logging::logDatum() +{ + LOG_DATUM("3 - Datum log has been created"); + QString mContent; + FileHandler::read(_Logger._logFileName, mContent); + QCOMPARE(mContent, "Event: , Storage::Logger Initialized\n" + "Event: , 1 - Event log has been created\n" + "Datum: , 3 - Datum log has been created\n"); +} + Index: unittests/tst_logging.h =================================================================== diff -u --- unittests/tst_logging.h (revision 0) +++ unittests/tst_logging.h (revision b9c5b0b3afc3b34d4980ecc4f023f498f80dafbc) @@ -0,0 +1,51 @@ +/*! + * + * Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. + * copyright + * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, + * IN PART OR IN WHOLE, + * WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. + * + * file tst_logging.h + * date 01/07/2019 + * author Behrouz NematiPour + * + */ +#pragma once + +#include +#include + +class tst_logging : public QObject +{ + Q_OBJECT + + bool _emited = false ; + QByteArray _expected {} ; + QVariantList _data {} ; + int _action = -1 ; + +public: + explicit tst_logging(QObject *parent = nullptr); + +private slots: + + // void initTestCase_data(); + + // will be called before the first test function is executed. + void initTestCase(); + + // will be called before each test function is executed. + // void init(); + + // will be called after every test function. + void cleanup(); + + // will be called after the last test function was executed. + void cleanupTestCase(); + + void logEvent(); + void logError(); + void logDatum(); +}; +