Developer documentation - PerttuP/EventTimer GitHub Wiki

Developer documentation

This page describes the EventTimer architecture, implementation details and automated test cases. This document is directed to developers maintaining or developing the software further.

The project consists of multiple qt projects. The top level project EventTimerHub is a qt subdirs project containing all different parts of the project as its subprojects. Direct subprojects for the EventTimerHub project are EventTimer, EventTimerExample and UnitTests.

EventTimer

This section describes the contets of the EventTimer project, located in the EventTimer directory.

Directories and files.

The EventTimer project contains the actual implementation for the EventTimer component. EventTimer's source code files are divided into two directories: inc and src. The inc directory contains header files required to interact with the component. Component user needs to add this directory to his include path. The src directory contains all the implementation files (.cc) and header files for internal implementation. Component user never needs to refer to this directory, or even know anything about it.

In addition to source code files, the EventTimer directory contains the qt project file for the EventTimer subproject, Doxyfile, which can be used to generate html-referece for public classes and interfaces (defined in the inc-directory), and doxygeninfo.hh, which defines the main page for doxygen documentation.

EventTimer architecture

Down below is the UML class diagram of the EventTimer component. The diagram shows all classes and their relations.

As seen in the diagram, EventTimer's public interface consists of one implemented interface (EventTimer), two interfaces to be implemented (EventHandler and Logger), one utility class (Event) and one builder class (EventTimerBuilder). These classes and interfaces are everything the component user needs to know about the implementation. The actual implementation of the EventTimer interface is the EventTimerLogic class, which uses the DatabaseHandler class to implement database transactions. Brief description of each class and interface if given in next section.

Implementation details

This section give brief description of each class present in the class diagram.

The Event class: This class represents a single event that can be scheduled with the EventTimer. Event has six attributes: name (QString, identifies event), timestamp (QString, represents the first time of occurence in format 'yyyy-MM-dd hh:mm:ss:zzz'), type (STATIC or DYNAMIC. Static events are preserved in the database while dynamic events are cleared every time EventTimer's start method is called), interval (unsigned, represents time between repeated events in milliseconds), repeats (unsigned, represents remaining repeat times after next occurence) and id (unsigned, unique for each event addded to the EventTimer). The Event class provides methods to read, modify and validate these attributes. Generate doxygen documentation or see the header file for more detailed description.

The EventTimer interface: This interface allows user to interact with the component once it has been instantiated. The interface allows adding elements to the schedule, remove them, check their state, check next upcoming events and clear the EventTimer from dynamic or all events. Generate doxygen documentation or see the header file for more detailed description.

The EventTimerBuilder class: This class is responsible for instantiating the EventTimer, hiding the actual implementation from the user. EventTimerBuilder creates both the DatabaseHandler object and the EventTimerLogic object using it. This class also defines type for storing EventTimer configuration parameters. Generate doxygen documentation or see the header file for more detailed description.

The EventHandler interface. Component user implements this interface, and injects it to the EventTimer before starting it. The interface allows EventTimer to notify user on occuring events. EventHandler's notify-method is called from EventTimer every time events occur, passing the occured event to the handler. Generate doxygen documentation or see the header file for more detailed description.

The Logger interface: Component user may implement this interface and inject it to the EventTimer at any time. The logger is sent log messages about significant events in the EventTimer, such as modifications and failures in the database. If no implementation is provided, no log messages are generated. Generate doxygen documentation or see the header file for more detailed description.

The DatabaseHandler class: This class is responsible for implementing all database transactions required by the EventTimerLogic class. Transactions consist of initializing database, adding, removing updating and quering events. Database transactions are implemented using database driver independent QtSql module. The rationale for this is to make it possible to use database of user's choice to store events. See the header file for more detailed description.

The EventTimerLogic class: This is the actual implementation of the EventTimer interface. This class is responsible for passing database operations to DatabaseHandler, checking for occuring events and notifying user on occured events. The class also may send log information to user if Logger implementation is provided. See the header file for more detailed description.

EventTimerExample

This subproject, located in the EventTimerExample directory, contains a simple example program on how to instantiate and use the EventTimer component. Purpose of this program is to help users getting started but also to test complete, precompiled EventTimer in practice.

The EventTimerExample project consists of two files: EventTimerExample.pro and main.cc. The program source code is written in main.cc, and linking with EventTimer is done in the project file. Running the example program requires The EventTimer project to be compiled first, and sqlite to be installed in the system.

UnitTests

The UnitTests project is a qt subdirs project that contains all automated tests for EventTimer classes. There are four subprojects: EventTest, DatabaseHandlerTest, DatabaseHandlerBenchmark and EventTimerLogicTest.

EventTest

The EventTest project is a qt unit test project that implements unit tests for the EventTimerNS::Event class (implementation). Tests are implemented using the QTest test framework. All test cases are defined in tst_eventtest.cc. The unit tests consist of following test cases:

  1. constructorTest. This test case tests Event constructor with several different parameters. This method also tests the id and setId methods. This is a data driven test, and test data (construction parameters) are fetched from the constructorTest_data() QTest data method.

  2. isValidTest. This test case tests the Event's isValid method with different combinations of attributes. This test case also tests the setter and getter methods for each event attribute. This is a data driven test, and test data (attribute values) are fetched from the isValidTest_data() data function.

  3. copyTest. Tests the copy-method. This is a data driven test, and test data (construction parameters are fetched from the copyTest_data() data function, which reuses test data from construcrorTest.

DatabaseHandlerTest

The DatabaseHandlerTest project is a qt unit test project that implements unit tests for the EventTimerNS::DatabaseHandler class (implementation), which is part of EventTimer's internal implementation. All test cases are defined in tst_databasehandlertest.cc. All test cases are implemented as data driven tests using QTest test framework. All test cases use the same test data, which defines different test configurations for the DatabaseHandler object.

All tests are performed using only local SQLite database without authentication. This is because I'm personally interested using the component only with this setup. Since database handling is implemented using QtSql module, all other supported database types are expected to work as well. Tests for other database configurations can be implemented simply adding new rows to the test data, defined in the addEventsTest data function. All the other test cases reuse this data funtion.

The DatabaseHandlerTest consists of following test cases:

  1. unknownDbTypeTest. This test case tests instantiating DatabaseHandler(DBH) using an unsupported database type. This should cause instantiated DBH having invalid state.

  2. invalidTableNameTest. This test case tests instantiating DBH using illegal SQL identifier as table name. Like previously, this should cause instantiated DBH having invalid state.

  3. getEventNotFound. This test case tests the DBH's getEvent method with id-parameter that is not found in the database. Result should be a returned event with unassigned id, while DBH's errorString remains empty.

  4. addEventsTest. This test case tests adding events into database. Results are verified using DBH's getEvent method.

  5. removeEventsTest. This test case tests removing events from the database. Results are verified using DBH's getEvent method.

  6. clearDynamicEvents. This test case tests DBH's clearDynamic method, which is supposed to remove all events of dynamic type.

  7. updateEventTest. Tests DBH's updateEvent method.

  8. checkOccuredTest. Tests DBH's checkOccured method.

  9. nextEventsTest. Tests DBH's nextEvents method.

  10. addRemoveTest. Tests adding and removing events sequently.

  11. addUpdateTest. Tests adding and updating events sequently.

  12. twoHandlersDifferentTablesTest. Tests adding and removing events using two DBH instances using different tables in the same database simuntaniously. The purpose of this test is to make sure that two DBHs handling different tables in same database at the same time do not interfere with each other.

DBH's clear all and getEvent do not have their own test cases. However, these methods are used in other test cases, and since all these test cases pass, we can safely say that these methods work as intended.

DatabaseHandlerBenchmark

DatabaseHandlerBenchmark is a qt unit test project that implements performance tests for the DatabaseHandler class, functionally tested in the DatabaseHandlerTest project. Benchmarking is implemented using benchmarking utilities in QTest test framework. All tests are implemented in tst_databasehandlerbenchmark.cc

The performance tests consist of following test cases:

  1. constructorBenchmark. Performace test for DatabaseHandler constructor.

  2. addEventBenchmark. Performace test for adding event in an empty database.

  3. updateSingleBenchmark. Performance test for updating lonely event in the database.

  4. getEventSingle. Performance test for getting lonely event in the database.

  5. nextEventsBenchmark. Performance test for getting small amount (3) next events in relatively small database (20 events)

  6. addUpdateRemoveSingleEvent. Performance test for sequential addition, updating and removal of a lonely event in the database.

  7. addThousandEvents. Performance test for adding 1000 events in the database.

  8. updateThousandEvents. Performance test for updating 1000 different events in the database.

  9. getThousandEvent. Performance test for getting 1000 different events in the database.

  10. get500ExpiredEvents. Performance test for getting list of 500 expired events from database of 1000 events.

  11. oneNextEventsFromThousandEvents. Performance test for getting the next event from database of 1001 events.

  12. thousandNextEvents. Performance test for getting 1000 next events from database of 1002 events.

  13. clear500DynamicEvents. Performance tests for clearing 500 next events from database of 1002 events.

  14. clear500Events. Performance tests for clearing 500 remaining events.

  15. removeThousand events. Performance test for removing 1000 events one by one from database having originally 1000 events.

EventTimerLogicTest

EventTimerLogicTest project is a qt unit test project testing the EventTimerLogic class (implementation), which is concrete implementation for the EventTimerNS::EventTimer interface. These testes are integration tests, since EventTimerLogic is composed of DatabaseHandler, which have been tested seperately in DatabaseHandlerTest and DatabaseHandlerBenchmark projects.

EventTimerLogicTest consist of following test cases:

  1. invalidBuilderTest. Test instantiating EventTimerLogic (ETL) with invaldid configuration parameters. This should lead to an invalid ETL.

  2. validBuilderTest. Test instantiating ETL with valid configuration parameters. This should lead to a valid ETL.

  3. addEventTest. Test adding events for ETL.

  4. removeEvent. Test removing events from ETL.

  5. nextEventsTest. Test ETL's nextEvents methods.

  6. clearDynamicTest. Test ETL's clearDynamic method.

  7. clearAllTest. Test ETL's clearAll method.

  8. startClearsDynamicAndExpiredEventsTest. Verify that the ETL's start method clears dynamic and expired events.

  9. startNotifyPolicyTest. Test ETL's start method with optional NOTIFY parameter.