##// END OF EJS Templates
Wait for the end of an acquisition to validate an operation (3)...
Alexandre Leroux -
r1215:7541b71e5b78
parent child
Show More
@@ -1,108 +1,109
1 #include "FuzzingDefs.h"
1 #include "FuzzingDefs.h"
2
2
3 const QString ACQUISITION_TIMEOUT_PROPERTY = QStringLiteral("acquisitionTimeout");
3 const QString NB_MAX_OPERATIONS_PROPERTY = QStringLiteral("component");
4 const QString NB_MAX_OPERATIONS_PROPERTY = QStringLiteral("component");
4 const QString NB_MAX_SYNC_GROUPS_PROPERTY = QStringLiteral("nbSyncGroups");
5 const QString NB_MAX_SYNC_GROUPS_PROPERTY = QStringLiteral("nbSyncGroups");
5 const QString NB_MAX_VARIABLES_PROPERTY = QStringLiteral("nbMaxVariables");
6 const QString NB_MAX_VARIABLES_PROPERTY = QStringLiteral("nbMaxVariables");
6 const QString AVAILABLE_OPERATIONS_PROPERTY = QStringLiteral("availableOperations");
7 const QString AVAILABLE_OPERATIONS_PROPERTY = QStringLiteral("availableOperations");
7 const QString CACHE_TOLERANCE_PROPERTY = QStringLiteral("cacheTolerance");
8 const QString CACHE_TOLERANCE_PROPERTY = QStringLiteral("cacheTolerance");
8 const QString INITIAL_RANGE_PROPERTY = QStringLiteral("initialRange");
9 const QString INITIAL_RANGE_PROPERTY = QStringLiteral("initialRange");
9 const QString MAX_RANGE_PROPERTY = QStringLiteral("maxRange");
10 const QString MAX_RANGE_PROPERTY = QStringLiteral("maxRange");
10 const QString METADATA_POOL_PROPERTY = QStringLiteral("metadataPool");
11 const QString METADATA_POOL_PROPERTY = QStringLiteral("metadataPool");
11 const QString PROVIDER_PROPERTY = QStringLiteral("provider");
12 const QString PROVIDER_PROPERTY = QStringLiteral("provider");
12 const QString OPERATION_DELAY_BOUNDS_PROPERTY = QStringLiteral("operationDelays");
13 const QString OPERATION_DELAY_BOUNDS_PROPERTY = QStringLiteral("operationDelays");
13 const QString VALIDATORS_PROPERTY = QStringLiteral("validators");
14 const QString VALIDATORS_PROPERTY = QStringLiteral("validators");
14 const QString VALIDATION_FREQUENCY_BOUNDS_PROPERTY = QStringLiteral("validationFrequencyBounds");
15 const QString VALIDATION_FREQUENCY_BOUNDS_PROPERTY = QStringLiteral("validationFrequencyBounds");
15
16
16 // //////////// //
17 // //////////// //
17 // FuzzingState //
18 // FuzzingState //
18 // //////////// //
19 // //////////// //
19
20
20 const SyncGroup &FuzzingState::syncGroup(SyncGroupId id) const
21 const SyncGroup &FuzzingState::syncGroup(SyncGroupId id) const
21 {
22 {
22 return m_SyncGroupsPool.at(id);
23 return m_SyncGroupsPool.at(id);
23 }
24 }
24
25
25 SyncGroup &FuzzingState::syncGroup(SyncGroupId id)
26 SyncGroup &FuzzingState::syncGroup(SyncGroupId id)
26 {
27 {
27 return m_SyncGroupsPool.at(id);
28 return m_SyncGroupsPool.at(id);
28 }
29 }
29
30
30 const VariableState &FuzzingState::variableState(VariableId id) const
31 const VariableState &FuzzingState::variableState(VariableId id) const
31 {
32 {
32 return m_VariablesPool.at(id);
33 return m_VariablesPool.at(id);
33 }
34 }
34
35
35 VariableState &FuzzingState::variableState(VariableId id)
36 VariableState &FuzzingState::variableState(VariableId id)
36 {
37 {
37 return m_VariablesPool.at(id);
38 return m_VariablesPool.at(id);
38 }
39 }
39
40
40 SyncGroupId FuzzingState::syncGroupId(VariableId variableId) const
41 SyncGroupId FuzzingState::syncGroupId(VariableId variableId) const
41 {
42 {
42 auto end = m_SyncGroupsPool.cend();
43 auto end = m_SyncGroupsPool.cend();
43 auto it
44 auto it
44 = std::find_if(m_SyncGroupsPool.cbegin(), end, [&variableId](const auto &syncGroupEntry) {
45 = std::find_if(m_SyncGroupsPool.cbegin(), end, [&variableId](const auto &syncGroupEntry) {
45 const auto &syncGroup = syncGroupEntry.second;
46 const auto &syncGroup = syncGroupEntry.second;
46 return syncGroup.m_Variables.find(variableId) != syncGroup.m_Variables.end();
47 return syncGroup.m_Variables.find(variableId) != syncGroup.m_Variables.end();
47 });
48 });
48
49
49 return it != end ? it->first : SyncGroupId{};
50 return it != end ? it->first : SyncGroupId{};
50 }
51 }
51
52
52 std::vector<SyncGroupId> FuzzingState::syncGroupsIds() const
53 std::vector<SyncGroupId> FuzzingState::syncGroupsIds() const
53 {
54 {
54 std::vector<SyncGroupId> result{};
55 std::vector<SyncGroupId> result{};
55
56
56 for (const auto &entry : m_SyncGroupsPool) {
57 for (const auto &entry : m_SyncGroupsPool) {
57 result.push_back(entry.first);
58 result.push_back(entry.first);
58 }
59 }
59
60
60 return result;
61 return result;
61 }
62 }
62
63
63 void FuzzingState::synchronizeVariable(VariableId variableId, SyncGroupId syncGroupId)
64 void FuzzingState::synchronizeVariable(VariableId variableId, SyncGroupId syncGroupId)
64 {
65 {
65 if (syncGroupId.isNull()) {
66 if (syncGroupId.isNull()) {
66 return;
67 return;
67 }
68 }
68
69
69 // Registers variable into sync group: if it's the first variable, sets the variable range as
70 // Registers variable into sync group: if it's the first variable, sets the variable range as
70 // the sync group range
71 // the sync group range
71 auto &syncGroup = m_SyncGroupsPool.at(syncGroupId);
72 auto &syncGroup = m_SyncGroupsPool.at(syncGroupId);
72 syncGroup.m_Variables.insert(variableId);
73 syncGroup.m_Variables.insert(variableId);
73 if (syncGroup.m_Variables.size() == 1) {
74 if (syncGroup.m_Variables.size() == 1) {
74 auto &variableState = m_VariablesPool.at(variableId);
75 auto &variableState = m_VariablesPool.at(variableId);
75 syncGroup.m_Range = variableState.m_Range;
76 syncGroup.m_Range = variableState.m_Range;
76 }
77 }
77 }
78 }
78
79
79 void FuzzingState::desynchronizeVariable(VariableId variableId, SyncGroupId syncGroupId)
80 void FuzzingState::desynchronizeVariable(VariableId variableId, SyncGroupId syncGroupId)
80 {
81 {
81 if (syncGroupId.isNull()) {
82 if (syncGroupId.isNull()) {
82 return;
83 return;
83 }
84 }
84
85
85 // Unregisters variable from sync group: if there is no more variable in the group, resets the
86 // Unregisters variable from sync group: if there is no more variable in the group, resets the
86 // range
87 // range
87 auto &syncGroup = m_SyncGroupsPool.at(syncGroupId);
88 auto &syncGroup = m_SyncGroupsPool.at(syncGroupId);
88 syncGroup.m_Variables.erase(variableId);
89 syncGroup.m_Variables.erase(variableId);
89 if (syncGroup.m_Variables.empty()) {
90 if (syncGroup.m_Variables.empty()) {
90 syncGroup.m_Range = INVALID_RANGE;
91 syncGroup.m_Range = INVALID_RANGE;
91 }
92 }
92 }
93 }
93
94
94 void FuzzingState::updateRanges(VariableId variableId, const SqpRange &newRange)
95 void FuzzingState::updateRanges(VariableId variableId, const SqpRange &newRange)
95 {
96 {
96 auto syncGroupId = this->syncGroupId(variableId);
97 auto syncGroupId = this->syncGroupId(variableId);
97
98
98 // Retrieves the variables to update:
99 // Retrieves the variables to update:
99 // - if the variable is synchronized to others, updates all synchronized variables
100 // - if the variable is synchronized to others, updates all synchronized variables
100 // - otherwise, updates only the variable
101 // - otherwise, updates only the variable
101 auto variablesToUpdate = syncGroupId.isNull() ? std::set<VariableId>{variableId}
102 auto variablesToUpdate = syncGroupId.isNull() ? std::set<VariableId>{variableId}
102 : m_SyncGroupsPool.at(syncGroupId).m_Variables;
103 : m_SyncGroupsPool.at(syncGroupId).m_Variables;
103
104
104 // Sets new range
105 // Sets new range
105 for (const auto &variableId : variablesToUpdate) {
106 for (const auto &variableId : variablesToUpdate) {
106 m_VariablesPool.at(variableId).m_Range = newRange;
107 m_VariablesPool.at(variableId).m_Range = newRange;
107 }
108 }
108 }
109 }
@@ -1,125 +1,128
1 #ifndef SCIQLOP_FUZZINGDEFS_H
1 #ifndef SCIQLOP_FUZZINGDEFS_H
2 #define SCIQLOP_FUZZINGDEFS_H
2 #define SCIQLOP_FUZZINGDEFS_H
3
3
4 #include <Data/SqpRange.h>
4 #include <Data/SqpRange.h>
5
5
6 #include <QString>
6 #include <QString>
7 #include <QUuid>
7 #include <QUuid>
8 #include <QVariantHash>
8 #include <QVariantHash>
9
9
10 #include <memory>
10 #include <memory>
11 #include <set>
11 #include <set>
12
12
13 // /////// //
13 // /////// //
14 // Aliases //
14 // Aliases //
15 // /////// //
15 // /////// //
16
16
17 using MetadataPool = std::vector<QVariantHash>;
17 using MetadataPool = std::vector<QVariantHash>;
18 Q_DECLARE_METATYPE(MetadataPool)
18 Q_DECLARE_METATYPE(MetadataPool)
19
19
20 using Properties = QVariantHash;
20 using Properties = QVariantHash;
21
21
22 // ///////// //
22 // ///////// //
23 // Constants //
23 // Constants //
24 // ///////// //
24 // ///////// //
25
25
26 /// Timeout set for data acquisition for an operation (in ms)
27 extern const QString ACQUISITION_TIMEOUT_PROPERTY;
28
26 /// Max number of operations to generate
29 /// Max number of operations to generate
27 extern const QString NB_MAX_OPERATIONS_PROPERTY;
30 extern const QString NB_MAX_OPERATIONS_PROPERTY;
28
31
29 /// Max number of sync groups to create through operations
32 /// Max number of sync groups to create through operations
30 extern const QString NB_MAX_SYNC_GROUPS_PROPERTY;
33 extern const QString NB_MAX_SYNC_GROUPS_PROPERTY;
31
34
32 /// Max number of variables to manipulate through operations
35 /// Max number of variables to manipulate through operations
33 extern const QString NB_MAX_VARIABLES_PROPERTY;
36 extern const QString NB_MAX_VARIABLES_PROPERTY;
34
37
35 /// Set of operations available for the test
38 /// Set of operations available for the test
36 extern const QString AVAILABLE_OPERATIONS_PROPERTY;
39 extern const QString AVAILABLE_OPERATIONS_PROPERTY;
37
40
38 /// Tolerance used for variable's cache (in ratio)
41 /// Tolerance used for variable's cache (in ratio)
39 extern const QString CACHE_TOLERANCE_PROPERTY;
42 extern const QString CACHE_TOLERANCE_PROPERTY;
40
43
41 /// Range with which the timecontroller is initialized
44 /// Range with which the timecontroller is initialized
42 extern const QString INITIAL_RANGE_PROPERTY;
45 extern const QString INITIAL_RANGE_PROPERTY;
43
46
44 /// Max range that an operation can reach
47 /// Max range that an operation can reach
45 extern const QString MAX_RANGE_PROPERTY;
48 extern const QString MAX_RANGE_PROPERTY;
46
49
47 /// Set of metadata that can be associated to a variable
50 /// Set of metadata that can be associated to a variable
48 extern const QString METADATA_POOL_PROPERTY;
51 extern const QString METADATA_POOL_PROPERTY;
49
52
50 /// Provider used to retrieve data
53 /// Provider used to retrieve data
51 extern const QString PROVIDER_PROPERTY;
54 extern const QString PROVIDER_PROPERTY;
52
55
53 /// Min/max times left for an operation to execute
56 /// Min/max times left for an operation to execute
54 extern const QString OPERATION_DELAY_BOUNDS_PROPERTY;
57 extern const QString OPERATION_DELAY_BOUNDS_PROPERTY;
55
58
56 /// Validators used to validate an operation
59 /// Validators used to validate an operation
57 extern const QString VALIDATORS_PROPERTY;
60 extern const QString VALIDATORS_PROPERTY;
58
61
59 /// Min/max number of operations to execute before calling validation of the current test's state
62 /// Min/max number of operations to execute before calling validation of the current test's state
60 extern const QString VALIDATION_FREQUENCY_BOUNDS_PROPERTY;
63 extern const QString VALIDATION_FREQUENCY_BOUNDS_PROPERTY;
61
64
62 // /////// //
65 // /////// //
63 // Structs //
66 // Structs //
64 // /////// //
67 // /////// //
65
68
66 class Variable;
69 class Variable;
67 struct VariableState {
70 struct VariableState {
68 std::shared_ptr<Variable> m_Variable{nullptr};
71 std::shared_ptr<Variable> m_Variable{nullptr};
69 SqpRange m_Range{INVALID_RANGE};
72 SqpRange m_Range{INVALID_RANGE};
70 };
73 };
71
74
72 using VariableId = int;
75 using VariableId = int;
73 using VariablesPool = std::map<VariableId, VariableState>;
76 using VariablesPool = std::map<VariableId, VariableState>;
74
77
75 /**
78 /**
76 * Defines a synchronization group for a fuzzing state. A group reports the variables synchronized
79 * Defines a synchronization group for a fuzzing state. A group reports the variables synchronized
77 * with each other, and the current range of the group (i.e. range of the last synchronized variable
80 * with each other, and the current range of the group (i.e. range of the last synchronized variable
78 * that has been moved)
81 * that has been moved)
79 */
82 */
80 struct SyncGroup {
83 struct SyncGroup {
81 std::set<VariableId> m_Variables{};
84 std::set<VariableId> m_Variables{};
82 SqpRange m_Range{INVALID_RANGE};
85 SqpRange m_Range{INVALID_RANGE};
83 };
86 };
84
87
85 using SyncGroupId = QUuid;
88 using SyncGroupId = QUuid;
86 using SyncGroupsPool = std::map<SyncGroupId, SyncGroup>;
89 using SyncGroupsPool = std::map<SyncGroupId, SyncGroup>;
87
90
88 /**
91 /**
89 * Defines a current state during a fuzzing state. It contains all the variables manipulated during
92 * Defines a current state during a fuzzing state. It contains all the variables manipulated during
90 * the test, as well as the synchronization status of these variables.
93 * the test, as well as the synchronization status of these variables.
91 */
94 */
92 struct FuzzingState {
95 struct FuzzingState {
93 const SyncGroup &syncGroup(SyncGroupId id) const;
96 const SyncGroup &syncGroup(SyncGroupId id) const;
94 SyncGroup &syncGroup(SyncGroupId id);
97 SyncGroup &syncGroup(SyncGroupId id);
95
98
96 const VariableState &variableState(VariableId id) const;
99 const VariableState &variableState(VariableId id) const;
97 VariableState &variableState(VariableId id);
100 VariableState &variableState(VariableId id);
98
101
99 /// @return the identifier of the synchronization group in which the variable passed in
102 /// @return the identifier of the synchronization group in which the variable passed in
100 /// parameter is located. If the variable is not in any group, returns an invalid identifier
103 /// parameter is located. If the variable is not in any group, returns an invalid identifier
101 SyncGroupId syncGroupId(VariableId variableId) const;
104 SyncGroupId syncGroupId(VariableId variableId) const;
102
105
103 /// @return the set of synchronization group identifiers
106 /// @return the set of synchronization group identifiers
104 std::vector<SyncGroupId> syncGroupsIds() const;
107 std::vector<SyncGroupId> syncGroupsIds() const;
105
108
106 /// Updates fuzzing state according to a variable synchronization
109 /// Updates fuzzing state according to a variable synchronization
107 /// @param variableId the variable that is synchronized
110 /// @param variableId the variable that is synchronized
108 /// @param syncGroupId the synchronization group
111 /// @param syncGroupId the synchronization group
109 void synchronizeVariable(VariableId variableId, SyncGroupId syncGroupId);
112 void synchronizeVariable(VariableId variableId, SyncGroupId syncGroupId);
110
113
111 /// Updates fuzzing state according to a variable desynchronization
114 /// Updates fuzzing state according to a variable desynchronization
112 /// @param variableId the variable that is desynchronized
115 /// @param variableId the variable that is desynchronized
113 /// @param syncGroupId the synchronization group from which to remove the variable
116 /// @param syncGroupId the synchronization group from which to remove the variable
114 void desynchronizeVariable(VariableId variableId, SyncGroupId syncGroupId);
117 void desynchronizeVariable(VariableId variableId, SyncGroupId syncGroupId);
115
118
116 /// Updates the range of a variable and all variables to which it is synchronized
119 /// Updates the range of a variable and all variables to which it is synchronized
117 /// @param the variable for which to affect the range
120 /// @param the variable for which to affect the range
118 /// @param the range to affect
121 /// @param the range to affect
119 void updateRanges(VariableId variableId, const SqpRange &newRange);
122 void updateRanges(VariableId variableId, const SqpRange &newRange);
120
123
121 VariablesPool m_VariablesPool;
124 VariablesPool m_VariablesPool;
122 SyncGroupsPool m_SyncGroupsPool;
125 SyncGroupsPool m_SyncGroupsPool;
123 };
126 };
124
127
125 #endif // SCIQLOP_FUZZINGDEFS_H
128 #endif // SCIQLOP_FUZZINGDEFS_H
@@ -1,369 +1,377
1 #include "FuzzingDefs.h"
1 #include "FuzzingDefs.h"
2 #include "FuzzingOperations.h"
2 #include "FuzzingOperations.h"
3 #include "FuzzingUtils.h"
3 #include "FuzzingUtils.h"
4 #include "FuzzingValidators.h"
4 #include "FuzzingValidators.h"
5
5
6 #include "AmdaProvider.h"
6 #include "AmdaProvider.h"
7
7
8 #include <Common/SignalWaiter.h>
8 #include <Common/SignalWaiter.h>
9 #include <Network/NetworkController.h>
9 #include <Network/NetworkController.h>
10 #include <Settings/SqpSettingsDefs.h>
10 #include <Settings/SqpSettingsDefs.h>
11 #include <SqpApplication.h>
11 #include <SqpApplication.h>
12 #include <Time/TimeController.h>
12 #include <Time/TimeController.h>
13 #include <Variable/Variable.h>
13 #include <Variable/Variable.h>
14 #include <Variable/VariableController.h>
14 #include <Variable/VariableController.h>
15
15
16 #include <QLoggingCategory>
16 #include <QLoggingCategory>
17 #include <QObject>
17 #include <QObject>
18 #include <QtTest>
18 #include <QtTest>
19
19
20 #include <memory>
20 #include <memory>
21
21
22 Q_LOGGING_CATEGORY(LOG_TestAmdaFuzzing, "TestAmdaFuzzing")
22 Q_LOGGING_CATEGORY(LOG_TestAmdaFuzzing, "TestAmdaFuzzing")
23
23
24 /**
24 /**
25 * Macro used to generate a getter for a property in @sa FuzzingTest. The macro generates a static
25 * Macro used to generate a getter for a property in @sa FuzzingTest. The macro generates a static
26 * attribute that is initialized by searching in properties the property and use a default value if
26 * attribute that is initialized by searching in properties the property and use a default value if
27 * it's not present. Macro arguments are:
27 * it's not present. Macro arguments are:
28 * - GETTER_NAME : name of the getter
28 * - GETTER_NAME : name of the getter
29 * - PROPERTY_NAME: used to generate constants for property's name ({PROPERTY_NAME}_PROPERTY) and
29 * - PROPERTY_NAME: used to generate constants for property's name ({PROPERTY_NAME}_PROPERTY) and
30 * default value ({PROPERTY_NAME}_DEFAULT_VALUE)
30 * default value ({PROPERTY_NAME}_DEFAULT_VALUE)
31 * - TYPE : return type of the getter
31 * - TYPE : return type of the getter
32 */
32 */
33 // clang-format off
33 // clang-format off
34 #define DECLARE_PROPERTY_GETTER(GETTER_NAME, PROPERTY_NAME, TYPE) \
34 #define DECLARE_PROPERTY_GETTER(GETTER_NAME, PROPERTY_NAME, TYPE) \
35 TYPE GETTER_NAME() const \
35 TYPE GETTER_NAME() const \
36 { \
36 { \
37 static auto result = m_Properties.value(PROPERTY_NAME##_PROPERTY, PROPERTY_NAME##_DEFAULT_VALUE).value<TYPE>(); \
37 static auto result = m_Properties.value(PROPERTY_NAME##_PROPERTY, PROPERTY_NAME##_DEFAULT_VALUE).value<TYPE>(); \
38 return result; \
38 return result; \
39 } \
39 } \
40 // clang-format on
40 // clang-format on
41
41
42 namespace {
42 namespace {
43
43
44 // /////// //
44 // /////// //
45 // Aliases //
45 // Aliases //
46 // /////// //
46 // /////// //
47
47
48 using IntPair = std::pair<int, int>;
48 using IntPair = std::pair<int, int>;
49 using Weight = double;
49 using Weight = double;
50 using Weights = std::vector<Weight>;
50 using Weights = std::vector<Weight>;
51
51
52 using VariableOperation = std::pair<VariableId, std::shared_ptr<IFuzzingOperation> >;
52 using VariableOperation = std::pair<VariableId, std::shared_ptr<IFuzzingOperation> >;
53 using VariablesOperations = std::vector<VariableOperation>;
53 using VariablesOperations = std::vector<VariableOperation>;
54
54
55 using WeightedOperationsPool = std::map<std::shared_ptr<IFuzzingOperation>, Weight>;
55 using WeightedOperationsPool = std::map<std::shared_ptr<IFuzzingOperation>, Weight>;
56 using Validators = std::vector<std::shared_ptr<IFuzzingValidator> >;
56 using Validators = std::vector<std::shared_ptr<IFuzzingValidator> >;
57
57
58 // ///////// //
58 // ///////// //
59 // Constants //
59 // Constants //
60 // ///////// //
60 // ///////// //
61
61
62 // Defaults values used when the associated properties have not been set for the test
62 // Defaults values used when the associated properties have not been set for the test
63 const auto ACQUISITION_TIMEOUT_DEFAULT_VALUE = 30000;
63 const auto NB_MAX_OPERATIONS_DEFAULT_VALUE = 100;
64 const auto NB_MAX_OPERATIONS_DEFAULT_VALUE = 100;
64 const auto NB_MAX_SYNC_GROUPS_DEFAULT_VALUE = 1;
65 const auto NB_MAX_SYNC_GROUPS_DEFAULT_VALUE = 1;
65 const auto NB_MAX_VARIABLES_DEFAULT_VALUE = 1;
66 const auto NB_MAX_VARIABLES_DEFAULT_VALUE = 1;
66 const auto AVAILABLE_OPERATIONS_DEFAULT_VALUE = QVariant::fromValue(WeightedOperationsTypes{
67 const auto AVAILABLE_OPERATIONS_DEFAULT_VALUE = QVariant::fromValue(WeightedOperationsTypes{
67 {FuzzingOperationType::CREATE, 1.},
68 {FuzzingOperationType::CREATE, 1.},
68 {FuzzingOperationType::DELETE, 0.1}, // Delete operation is less frequent
69 {FuzzingOperationType::DELETE, 0.1}, // Delete operation is less frequent
69 {FuzzingOperationType::PAN_LEFT, 1.},
70 {FuzzingOperationType::PAN_LEFT, 1.},
70 {FuzzingOperationType::PAN_RIGHT, 1.},
71 {FuzzingOperationType::PAN_RIGHT, 1.},
71 {FuzzingOperationType::ZOOM_IN, 1.},
72 {FuzzingOperationType::ZOOM_IN, 1.},
72 {FuzzingOperationType::ZOOM_OUT, 1.},
73 {FuzzingOperationType::ZOOM_OUT, 1.},
73 {FuzzingOperationType::SYNCHRONIZE, 0.8},
74 {FuzzingOperationType::SYNCHRONIZE, 0.8},
74 {FuzzingOperationType::DESYNCHRONIZE, 0.4}});
75 {FuzzingOperationType::DESYNCHRONIZE, 0.4}});
75 const auto CACHE_TOLERANCE_DEFAULT_VALUE = 0.2;
76 const auto CACHE_TOLERANCE_DEFAULT_VALUE = 0.2;
76
77
77 /// Min/max delays between each operation (in ms)
78 /// Min/max delays between each operation (in ms)
78 const auto OPERATION_DELAY_BOUNDS_DEFAULT_VALUE = QVariant::fromValue(std::make_pair(100, 3000));
79 const auto OPERATION_DELAY_BOUNDS_DEFAULT_VALUE = QVariant::fromValue(std::make_pair(100, 3000));
79
80
80 /// Validators for the tests (executed in the order in which they're defined)
81 /// Validators for the tests (executed in the order in which they're defined)
81 const auto VALIDATORS_DEFAULT_VALUE = QVariant::fromValue(
82 const auto VALIDATORS_DEFAULT_VALUE = QVariant::fromValue(
82 ValidatorsTypes{{FuzzingValidatorType::RANGE, FuzzingValidatorType::DATA}});
83 ValidatorsTypes{{FuzzingValidatorType::RANGE, FuzzingValidatorType::DATA}});
83
84
84 /// Min/max number of operations to execute before calling validation
85 /// Min/max number of operations to execute before calling validation
85 const auto VALIDATION_FREQUENCY_BOUNDS_DEFAULT_VALUE = QVariant::fromValue(std::make_pair(1, 10));
86 const auto VALIDATION_FREQUENCY_BOUNDS_DEFAULT_VALUE = QVariant::fromValue(std::make_pair(1, 10));
86
87
87 // /////// //
88 // /////// //
88 // Methods //
89 // Methods //
89 // /////// //
90 // /////// //
90
91
91 /// Goes through the variables pool and operations pool to determine the set of {variable/operation}
92 /// Goes through the variables pool and operations pool to determine the set of {variable/operation}
92 /// pairs that are valid (i.e. operation that can be executed on variable)
93 /// pairs that are valid (i.e. operation that can be executed on variable)
93 std::pair<VariablesOperations, Weights>
94 std::pair<VariablesOperations, Weights>
94 availableOperations(const FuzzingState &fuzzingState, const WeightedOperationsPool &operationsPool)
95 availableOperations(const FuzzingState &fuzzingState, const WeightedOperationsPool &operationsPool)
95 {
96 {
96 VariablesOperations result{};
97 VariablesOperations result{};
97 Weights weights{};
98 Weights weights{};
98
99
99 for (const auto &variablesPoolEntry : fuzzingState.m_VariablesPool) {
100 for (const auto &variablesPoolEntry : fuzzingState.m_VariablesPool) {
100 auto variableId = variablesPoolEntry.first;
101 auto variableId = variablesPoolEntry.first;
101
102
102 for (const auto &operationsPoolEntry : operationsPool) {
103 for (const auto &operationsPoolEntry : operationsPool) {
103 auto operation = operationsPoolEntry.first;
104 auto operation = operationsPoolEntry.first;
104 auto weight = operationsPoolEntry.second;
105 auto weight = operationsPoolEntry.second;
105
106
106 // A pair is valid if the current operation can be executed on the current variable
107 // A pair is valid if the current operation can be executed on the current variable
107 if (operation->canExecute(variableId, fuzzingState)) {
108 if (operation->canExecute(variableId, fuzzingState)) {
108 result.push_back({variableId, operation});
109 result.push_back({variableId, operation});
109 weights.push_back(weight);
110 weights.push_back(weight);
110 }
111 }
111 }
112 }
112 }
113 }
113
114
114 return {result, weights};
115 return {result, weights};
115 }
116 }
116
117
117 WeightedOperationsPool createOperationsPool(const WeightedOperationsTypes &types)
118 WeightedOperationsPool createOperationsPool(const WeightedOperationsTypes &types)
118 {
119 {
119 WeightedOperationsPool result{};
120 WeightedOperationsPool result{};
120
121
121 std::transform(
122 std::transform(
122 types.cbegin(), types.cend(), std::inserter(result, result.end()), [](const auto &type) {
123 types.cbegin(), types.cend(), std::inserter(result, result.end()), [](const auto &type) {
123 return std::make_pair(FuzzingOperationFactory::create(type.first), type.second);
124 return std::make_pair(FuzzingOperationFactory::create(type.first), type.second);
124 });
125 });
125
126
126 return result;
127 return result;
127 }
128 }
128
129
129 Validators createValidators(const ValidatorsTypes &types)
130 Validators createValidators(const ValidatorsTypes &types)
130 {
131 {
131 Validators result{};
132 Validators result{};
132
133
133 std::transform(types.cbegin(), types.cend(), std::inserter(result, result.end()),
134 std::transform(types.cbegin(), types.cend(), std::inserter(result, result.end()),
134 [](const auto &type) { return FuzzingValidatorFactory::create(type); });
135 [](const auto &type) { return FuzzingValidatorFactory::create(type); });
135
136
136 return result;
137 return result;
137 }
138 }
138
139
139 /**
140 /**
140 * Validates all the variables' states passed in parameter, according to a set of validators
141 * Validates all the variables' states passed in parameter, according to a set of validators
141 * @param variablesPool the variables' states
142 * @param variablesPool the variables' states
142 * @param validators the validators used for validation
143 * @param validators the validators used for validation
143 */
144 */
144 void validate(const VariablesPool &variablesPool, const Validators &validators)
145 void validate(const VariablesPool &variablesPool, const Validators &validators)
145 {
146 {
146 for (const auto &variablesPoolEntry : variablesPool) {
147 for (const auto &variablesPoolEntry : variablesPool) {
147 auto variableId = variablesPoolEntry.first;
148 auto variableId = variablesPoolEntry.first;
148 const auto &variableState = variablesPoolEntry.second;
149 const auto &variableState = variablesPoolEntry.second;
149
150
150 auto variableMessage = variableState.m_Variable ? variableState.m_Variable->name()
151 auto variableMessage = variableState.m_Variable ? variableState.m_Variable->name()
151 : QStringLiteral("null variable");
152 : QStringLiteral("null variable");
152 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Validating state of variable at index"
153 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Validating state of variable at index"
153 << variableId << "(" << variableMessage << ")...";
154 << variableId << "(" << variableMessage << ")...";
154
155
155 for (const auto &validator : validators) {
156 for (const auto &validator : validators) {
156 validator->validate(VariableState{variableState});
157 validator->validate(VariableState{variableState});
157 }
158 }
158
159
159 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Validation completed.";
160 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Validation completed.";
160 }
161 }
161 }
162 }
162
163
163 /**
164 /**
164 * Class to run random tests
165 * Class to run random tests
165 */
166 */
166 class FuzzingTest {
167 class FuzzingTest {
167 public:
168 public:
168 explicit FuzzingTest(VariableController &variableController, Properties properties)
169 explicit FuzzingTest(VariableController &variableController, Properties properties)
169 : m_VariableController{variableController},
170 : m_VariableController{variableController},
170 m_Properties{std::move(properties)},
171 m_Properties{std::move(properties)},
171 m_FuzzingState{}
172 m_FuzzingState{}
172 {
173 {
173 // Inits variables pool: at init, all variables are null
174 // Inits variables pool: at init, all variables are null
174 for (auto variableId = 0; variableId < nbMaxVariables(); ++variableId) {
175 for (auto variableId = 0; variableId < nbMaxVariables(); ++variableId) {
175 m_FuzzingState.m_VariablesPool[variableId] = VariableState{};
176 m_FuzzingState.m_VariablesPool[variableId] = VariableState{};
176 }
177 }
177
178
178 // Inits sync groups and registers them into the variable controller
179 // Inits sync groups and registers them into the variable controller
179 for (auto i = 0; i < nbMaxSyncGroups(); ++i) {
180 for (auto i = 0; i < nbMaxSyncGroups(); ++i) {
180 auto syncGroupId = SyncGroupId::createUuid();
181 auto syncGroupId = SyncGroupId::createUuid();
181 variableController.onAddSynchronizationGroupId(syncGroupId);
182 variableController.onAddSynchronizationGroupId(syncGroupId);
182 m_FuzzingState.m_SyncGroupsPool[syncGroupId] = SyncGroup{};
183 m_FuzzingState.m_SyncGroupsPool[syncGroupId] = SyncGroup{};
183 }
184 }
184 }
185 }
185
186
186 void execute()
187 void execute()
187 {
188 {
188 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Running" << nbMaxOperations() << "operations on"
189 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Running" << nbMaxOperations() << "operations on"
189 << nbMaxVariables() << "variable(s)...";
190 << nbMaxVariables() << "variable(s)...";
190
191
191
192
192 // Inits the count of the number of operations before the next validation
193 // Inits the count of the number of operations before the next validation
193 int nextValidationCounter = 0;
194 int nextValidationCounter = 0;
194 auto updateValidationCounter = [this, &nextValidationCounter]() {
195 auto updateValidationCounter = [this, &nextValidationCounter]() {
195 nextValidationCounter = RandomGenerator::instance().generateInt(
196 nextValidationCounter = RandomGenerator::instance().generateInt(
196 validationFrequencies().first, validationFrequencies().second);
197 validationFrequencies().first, validationFrequencies().second);
197 qCInfo(LOG_TestAmdaFuzzing()).noquote()
198 qCInfo(LOG_TestAmdaFuzzing()).noquote()
198 << "Next validation in " << nextValidationCounter << "operations...";
199 << "Next validation in " << nextValidationCounter << "operation(s)...";
199 };
200 };
200 updateValidationCounter();
201 updateValidationCounter();
201
202
202 auto canExecute = true;
203 auto canExecute = true;
203 for (auto i = 0; i < nbMaxOperations() && canExecute; ++i) {
204 for (auto i = 0; i < nbMaxOperations() && canExecute; ++i) {
204 // Retrieves all operations that can be executed in the current context
205 // Retrieves all operations that can be executed in the current context
205 VariablesOperations variableOperations{};
206 VariablesOperations variableOperations{};
206 Weights weights{};
207 Weights weights{};
207 std::tie(variableOperations, weights)
208 std::tie(variableOperations, weights)
208 = availableOperations(m_FuzzingState, operationsPool());
209 = availableOperations(m_FuzzingState, operationsPool());
209
210
210 canExecute = !variableOperations.empty();
211 canExecute = !variableOperations.empty();
211 if (canExecute) {
212 if (canExecute) {
212 --nextValidationCounter;
213 --nextValidationCounter;
213
214
214 // Of the operations available, chooses a random operation and executes it
215 // Of the operations available, chooses a random operation and executes it
215 auto variableOperation
216 auto variableOperation
216 = RandomGenerator::instance().randomChoice(variableOperations, weights);
217 = RandomGenerator::instance().randomChoice(variableOperations, weights);
217
218
218 auto variableId = variableOperation.first;
219 auto variableId = variableOperation.first;
219 auto fuzzingOperation = variableOperation.second;
220 auto fuzzingOperation = variableOperation.second;
220
221
222 auto waitAcquisition = nextValidationCounter == 0;
223
221 fuzzingOperation->execute(variableId, m_FuzzingState, m_VariableController,
224 fuzzingOperation->execute(variableId, m_FuzzingState, m_VariableController,
222 m_Properties);
225 m_Properties);
223
226
224 // Delays the next operation with a randomly generated time
227 if (waitAcquisition) {
225 auto delay = RandomGenerator::instance().generateInt(operationDelays().first,
228 qCDebug(LOG_TestAmdaFuzzing()) << "Waiting for acquisition to finish...";
226 operationDelays().second);
229 SignalWaiter{m_VariableController, SIGNAL(acquisitionFinished())}.wait(
227 qCDebug(LOG_TestAmdaFuzzing())
230 acquisitionTimeout());
228 << "Waiting " << delay << "ms before the next operation...";
229 QTest::qWait(delay);
230
231
231 // Validates variables
232 // Validates variables
232 if (nextValidationCounter == 0) {
233 validate(m_FuzzingState.m_VariablesPool, validators());
233 validate(m_FuzzingState.m_VariablesPool, validators());
234 updateValidationCounter();
234 updateValidationCounter();
235 }
235 }
236 else {
237 // Delays the next operation with a randomly generated time
238 auto delay = RandomGenerator::instance().generateInt(operationDelays().first,
239 operationDelays().second);
240 qCDebug(LOG_TestAmdaFuzzing())
241 << "Waiting " << delay << "ms before the next operation...";
242 QTest::qWait(delay);
243 }
236 }
244 }
237 else {
245 else {
238 qCInfo(LOG_TestAmdaFuzzing()).noquote()
246 qCInfo(LOG_TestAmdaFuzzing()).noquote()
239 << "No more operations are available, the execution of the test will stop...";
247 << "No more operations are available, the execution of the test will stop...";
240 }
248 }
241 }
249 }
242
250
243 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Execution of the test completed.";
251 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Execution of the test completed.";
244 }
252 }
245
253
246 private:
254 private:
247
255
248 WeightedOperationsPool operationsPool() const
256 WeightedOperationsPool operationsPool() const
249 {
257 {
250 static auto result = createOperationsPool(
258 static auto result = createOperationsPool(
251 m_Properties.value(AVAILABLE_OPERATIONS_PROPERTY, AVAILABLE_OPERATIONS_DEFAULT_VALUE)
259 m_Properties.value(AVAILABLE_OPERATIONS_PROPERTY, AVAILABLE_OPERATIONS_DEFAULT_VALUE)
252 .value<WeightedOperationsTypes>());
260 .value<WeightedOperationsTypes>());
253 return result;
261 return result;
254 }
262 }
255
263
256 Validators validators() const
264 Validators validators() const
257 {
265 {
258 static auto result
266 static auto result
259 = createValidators(m_Properties.value(VALIDATORS_PROPERTY, VALIDATORS_DEFAULT_VALUE)
267 = createValidators(m_Properties.value(VALIDATORS_PROPERTY, VALIDATORS_DEFAULT_VALUE)
260 .value<ValidatorsTypes>());
268 .value<ValidatorsTypes>());
261 return result;
269 return result;
262 }
270 }
263
271
264 DECLARE_PROPERTY_GETTER(nbMaxOperations, NB_MAX_OPERATIONS, int)
272 DECLARE_PROPERTY_GETTER(nbMaxOperations, NB_MAX_OPERATIONS, int)
265 DECLARE_PROPERTY_GETTER(nbMaxSyncGroups, NB_MAX_SYNC_GROUPS, int)
273 DECLARE_PROPERTY_GETTER(nbMaxSyncGroups, NB_MAX_SYNC_GROUPS, int)
266 DECLARE_PROPERTY_GETTER(nbMaxVariables, NB_MAX_VARIABLES, int)
274 DECLARE_PROPERTY_GETTER(nbMaxVariables, NB_MAX_VARIABLES, int)
267 DECLARE_PROPERTY_GETTER(operationDelays, OPERATION_DELAY_BOUNDS, IntPair)
275 DECLARE_PROPERTY_GETTER(operationDelays, OPERATION_DELAY_BOUNDS, IntPair)
268 DECLARE_PROPERTY_GETTER(validationFrequencies, VALIDATION_FREQUENCY_BOUNDS, IntPair)
276 DECLARE_PROPERTY_GETTER(validationFrequencies, VALIDATION_FREQUENCY_BOUNDS, IntPair)
269 DECLARE_PROPERTY_GETTER(acquisitionTimeout, ACQUISITION_TIMEOUT, int)
277 DECLARE_PROPERTY_GETTER(acquisitionTimeout, ACQUISITION_TIMEOUT, int)
270
278
271 VariableController &m_VariableController;
279 VariableController &m_VariableController;
272 Properties m_Properties;
280 Properties m_Properties;
273 FuzzingState m_FuzzingState;
281 FuzzingState m_FuzzingState;
274 };
282 };
275
283
276 } // namespace
284 } // namespace
277
285
278 class TestAmdaFuzzing : public QObject {
286 class TestAmdaFuzzing : public QObject {
279 Q_OBJECT
287 Q_OBJECT
280
288
281 private slots:
289 private slots:
282 /// Input data for @sa testFuzzing()
290 /// Input data for @sa testFuzzing()
283 void testFuzzing_data();
291 void testFuzzing_data();
284 void testFuzzing();
292 void testFuzzing();
285 };
293 };
286
294
287 void TestAmdaFuzzing::testFuzzing_data()
295 void TestAmdaFuzzing::testFuzzing_data()
288 {
296 {
289 // ////////////// //
297 // ////////////// //
290 // Test structure //
298 // Test structure //
291 // ////////////// //
299 // ////////////// //
292
300
293 QTest::addColumn<Properties>("properties"); // Properties for random test
301 QTest::addColumn<Properties>("properties"); // Properties for random test
294
302
295 // ////////// //
303 // ////////// //
296 // Test cases //
304 // Test cases //
297 // ////////// //
305 // ////////// //
298
306
299 auto maxRange = SqpRange::fromDateTime({2017, 1, 1}, {0, 0}, {2017, 1, 5}, {0, 0});
307 auto maxRange = SqpRange::fromDateTime({2017, 1, 1}, {0, 0}, {2017, 1, 5}, {0, 0});
300 MetadataPool metadataPool{{{"dataType", "vector"}, {"xml:id", "imf"}}};
308 MetadataPool metadataPool{{{"dataType", "vector"}, {"xml:id", "imf"}}};
301
309
302 // Note: we don't use auto here as we want to pass std::shared_ptr<IDataProvider> as is in the
310 // Note: we don't use auto here as we want to pass std::shared_ptr<IDataProvider> as is in the
303 // QVariant
311 // QVariant
304 std::shared_ptr<IDataProvider> provider = std::make_shared<AmdaProvider>();
312 std::shared_ptr<IDataProvider> provider = std::make_shared<AmdaProvider>();
305
313
306 QTest::newRow("fuzzingTest") << Properties{
314 QTest::newRow("fuzzingTest") << Properties{
307 {MAX_RANGE_PROPERTY, QVariant::fromValue(maxRange)},
315 {MAX_RANGE_PROPERTY, QVariant::fromValue(maxRange)},
308 {METADATA_POOL_PROPERTY, QVariant::fromValue(metadataPool)},
316 {METADATA_POOL_PROPERTY, QVariant::fromValue(metadataPool)},
309 {PROVIDER_PROPERTY, QVariant::fromValue(provider)}};
317 {PROVIDER_PROPERTY, QVariant::fromValue(provider)}};
310 }
318 }
311
319
312 void TestAmdaFuzzing::testFuzzing()
320 void TestAmdaFuzzing::testFuzzing()
313 {
321 {
314 QFETCH(Properties, properties);
322 QFETCH(Properties, properties);
315
323
316 // Sets cache property
324 // Sets cache property
317 QSettings settings{};
325 QSettings settings{};
318 auto cacheTolerance = properties.value(CACHE_TOLERANCE_PROPERTY, CACHE_TOLERANCE_DEFAULT_VALUE);
326 auto cacheTolerance = properties.value(CACHE_TOLERANCE_PROPERTY, CACHE_TOLERANCE_DEFAULT_VALUE);
319 settings.setValue(GENERAL_TOLERANCE_AT_INIT_KEY, cacheTolerance);
327 settings.setValue(GENERAL_TOLERANCE_AT_INIT_KEY, cacheTolerance);
320 settings.setValue(GENERAL_TOLERANCE_AT_UPDATE_KEY, cacheTolerance);
328 settings.setValue(GENERAL_TOLERANCE_AT_UPDATE_KEY, cacheTolerance);
321
329
322 auto &variableController = sqpApp->variableController();
330 auto &variableController = sqpApp->variableController();
323 auto &timeController = sqpApp->timeController();
331 auto &timeController = sqpApp->timeController();
324
332
325 // Generates random initial range (bounded to max range)
333 // Generates random initial range (bounded to max range)
326 auto maxRange = properties.value(MAX_RANGE_PROPERTY, QVariant::fromValue(INVALID_RANGE))
334 auto maxRange = properties.value(MAX_RANGE_PROPERTY, QVariant::fromValue(INVALID_RANGE))
327 .value<SqpRange>();
335 .value<SqpRange>();
328
336
329 QVERIFY(maxRange != INVALID_RANGE);
337 QVERIFY(maxRange != INVALID_RANGE);
330
338
331 auto initialRangeStart
339 auto initialRangeStart
332 = RandomGenerator::instance().generateDouble(maxRange.m_TStart, maxRange.m_TEnd);
340 = RandomGenerator::instance().generateDouble(maxRange.m_TStart, maxRange.m_TEnd);
333 auto initialRangeEnd
341 auto initialRangeEnd
334 = RandomGenerator::instance().generateDouble(maxRange.m_TStart, maxRange.m_TEnd);
342 = RandomGenerator::instance().generateDouble(maxRange.m_TStart, maxRange.m_TEnd);
335 if (initialRangeStart > initialRangeEnd) {
343 if (initialRangeStart > initialRangeEnd) {
336 std::swap(initialRangeStart, initialRangeEnd);
344 std::swap(initialRangeStart, initialRangeEnd);
337 }
345 }
338
346
339 // Sets initial range on time controller
347 // Sets initial range on time controller
340 SqpRange initialRange{initialRangeStart, initialRangeEnd};
348 SqpRange initialRange{initialRangeStart, initialRangeEnd};
341 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Setting initial range to" << initialRange << "...";
349 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Setting initial range to" << initialRange << "...";
342 timeController.onTimeToUpdate(initialRange);
350 timeController.onTimeToUpdate(initialRange);
343 properties.insert(INITIAL_RANGE_PROPERTY, QVariant::fromValue(initialRange));
351 properties.insert(INITIAL_RANGE_PROPERTY, QVariant::fromValue(initialRange));
344
352
345 FuzzingTest test{variableController, properties};
353 FuzzingTest test{variableController, properties};
346 test.execute();
354 test.execute();
347 }
355 }
348
356
349 int main(int argc, char *argv[])
357 int main(int argc, char *argv[])
350 {
358 {
351 QLoggingCategory::setFilterRules(
359 QLoggingCategory::setFilterRules(
352 "*.warning=false\n"
360 "*.warning=false\n"
353 "*.info=false\n"
361 "*.info=false\n"
354 "*.debug=false\n"
362 "*.debug=false\n"
355 "FuzzingOperations.info=true\n"
363 "FuzzingOperations.info=true\n"
356 "FuzzingValidators.info=true\n"
364 "FuzzingValidators.info=true\n"
357 "TestAmdaFuzzing.info=true\n");
365 "TestAmdaFuzzing.info=true\n");
358
366
359 SqpApplication app{argc, argv};
367 SqpApplication app{argc, argv};
360 SqpApplication::setOrganizationName("LPP");
368 SqpApplication::setOrganizationName("LPP");
361 SqpApplication::setOrganizationDomain("lpp.fr");
369 SqpApplication::setOrganizationDomain("lpp.fr");
362 SqpApplication::setApplicationName("SciQLop-TestFuzzing");
370 SqpApplication::setApplicationName("SciQLop-TestFuzzing");
363 app.setAttribute(Qt::AA_Use96Dpi, true);
371 app.setAttribute(Qt::AA_Use96Dpi, true);
364 TestAmdaFuzzing testObject{};
372 TestAmdaFuzzing testObject{};
365 QTEST_SET_MAIN_SOURCE_PATH
373 QTEST_SET_MAIN_SOURCE_PATH
366 return QTest::qExec(&testObject, argc, argv);
374 return QTest::qExec(&testObject, argc, argv);
367 }
375 }
368
376
369 #include "TestAmdaFuzzing.moc"
377 #include "TestAmdaFuzzing.moc"
General Comments 0
You need to be logged in to leave comments. Login now