##// END OF EJS Templates
Completes fuzzing test structure by setting initial range for the time controller
Alexandre Leroux -
r1178:324a3ee21c58
parent child
Show More
@@ -1,58 +1,66
1 1 #ifndef SCIQLOP_SQPRANGE_H
2 2 #define SCIQLOP_SQPRANGE_H
3 3
4 4 #include <QObject>
5 5
6 6 #include <QDebug>
7 7
8 8 #include <Common/DateUtils.h>
9 9 #include <Common/MetaTypes.h>
10 10
11 11 #include <cmath>
12 12
13 13 /**
14 14 * @brief The SqpRange struct holds the information of time parameters
15 15 */
16 16 struct SqpRange {
17 /// Creates SqpRange from dates and times
18 static SqpRange fromDateTime(const QDate &startDate, const QTime &startTime,
19 const QDate &endDate, const QTime &endTime)
20 {
21 return {DateUtils::secondsSinceEpoch(QDateTime{startDate, startTime}),
22 DateUtils::secondsSinceEpoch(QDateTime{endDate, endTime})};
23 }
24
17 25 /// Start time (UTC)
18 26 double m_TStart;
19 27 /// End time (UTC)
20 28 double m_TEnd;
21 29
22 30 bool contains(const SqpRange &dateTime) const noexcept
23 31 {
24 32 return (m_TStart <= dateTime.m_TStart && m_TEnd >= dateTime.m_TEnd);
25 33 }
26 34
27 35 bool intersect(const SqpRange &dateTime) const noexcept
28 36 {
29 37 return (m_TEnd >= dateTime.m_TStart && m_TStart <= dateTime.m_TEnd);
30 38 }
31 39
32 40 bool operator==(const SqpRange &other) const
33 41 {
34 42 auto equals = [](const auto &v1, const auto &v2) {
35 43 return (std::isnan(v1) && std::isnan(v2)) || v1 == v2;
36 44 };
37 45
38 46 return equals(m_TStart, other.m_TStart) && equals(m_TEnd, other.m_TEnd);
39 47 }
40 48 bool operator!=(const SqpRange &other) const { return !(*this == other); }
41 49 };
42 50
43 51 const auto INVALID_RANGE
44 52 = SqpRange{std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN()};
45 53
46 54 inline QDebug operator<<(QDebug d, SqpRange obj)
47 55 {
48 56 auto tendDateTimeStart = DateUtils::dateTime(obj.m_TStart);
49 57 auto tendDateTimeEnd = DateUtils::dateTime(obj.m_TEnd);
50 58
51 59 d << "ts: " << tendDateTimeStart << " te: " << tendDateTimeEnd;
52 60 return d;
53 61 }
54 62
55 63 // Required for using shared_ptr in signals/slots
56 64 SCIQLOP_REGISTER_META_TYPE(SQPRANGE_REGISTRY, SqpRange)
57 65
58 66 #endif // SCIQLOP_SQPRANGE_H
@@ -1,7 +1,8
1 1 #include "FuzzingDefs.h"
2 2
3 3 const QString NB_MAX_OPERATIONS_PROPERTY = QStringLiteral("component");
4 4 const QString NB_MAX_VARIABLES_PROPERTY = QStringLiteral("nbMaxVariables");
5 5 const QString AVAILABLE_OPERATIONS_PROPERTY = QStringLiteral("availableOperations");
6 const QString MAX_RANGE_PROPERTY = QStringLiteral("maxRange");
6 7 const QString METADATA_POOL_PROPERTY = QStringLiteral("metadataPool");
7 8 const QString PROVIDER_PROPERTY = QStringLiteral("provider");
@@ -1,35 +1,38
1 1 #ifndef SCIQLOP_FUZZINGDEFS_H
2 2 #define SCIQLOP_FUZZINGDEFS_H
3 3
4 4 #include <QString>
5 5 #include <QVariantHash>
6 6
7 7 // /////// //
8 8 // Aliases //
9 9 // /////// //
10 10
11 11 using MetadataPool = std::vector<QVariantHash>;
12 12 Q_DECLARE_METATYPE(MetadataPool)
13 13
14 14 using Properties = QVariantHash;
15 15
16 16 // ///////// //
17 17 // Constants //
18 18 // ///////// //
19 19
20 20 /// Max number of operations to generate
21 21 extern const QString NB_MAX_OPERATIONS_PROPERTY;
22 22
23 23 /// Max number of variables to manipulate through operations
24 24 extern const QString NB_MAX_VARIABLES_PROPERTY;
25 25
26 26 /// Set of operations available for the test
27 27 extern const QString AVAILABLE_OPERATIONS_PROPERTY;
28 28
29 /// Max range that an operation can reach
30 extern const QString MAX_RANGE_PROPERTY;
31
29 32 /// Set of metadata that can be associated to a variable
30 33 extern const QString METADATA_POOL_PROPERTY;
31 34
32 35 /// Provider used to retrieve data
33 36 extern const QString PROVIDER_PROPERTY;
34 37
35 38 #endif // SCIQLOP_FUZZINGDEFS_H
@@ -1,209 +1,229
1 1 #include "FuzzingDefs.h"
2 2 #include "FuzzingOperations.h"
3 3 #include "FuzzingUtils.h"
4 4
5 5 #include <Network/NetworkController.h>
6 6 #include <SqpApplication.h>
7 7 #include <Time/TimeController.h>
8 8 #include <Variable/VariableController.h>
9 9
10 10 #include <QLoggingCategory>
11 11 #include <QObject>
12 12 #include <QtTest>
13 13
14 14 #include <memory>
15 15
16 16 Q_LOGGING_CATEGORY(LOG_TestAmdaFuzzing, "TestAmdaFuzzing")
17 17
18 18 namespace {
19 19
20 20 // /////// //
21 21 // Aliases //
22 22 // /////// //
23 23
24 24 using VariableId = int;
25 25
26 26 using VariableOperation = std::pair<VariableId, std::shared_ptr<IFuzzingOperation> >;
27 27 using VariablesOperations = std::vector<VariableOperation>;
28 28
29 29 using OperationsPool = std::set<std::shared_ptr<IFuzzingOperation> >;
30 30 using VariablesPool = std::map<VariableId, std::shared_ptr<Variable> >;
31 31
32 32 // ///////// //
33 33 // Constants //
34 34 // ///////// //
35 35
36 36 // Defaults values used when the associated properties have not been set for the test
37 37 const auto NB_MAX_OPERATIONS_DEFAULT_VALUE = 100;
38 38 const auto NB_MAX_VARIABLES_DEFAULT_VALUE = 1;
39 39 const auto AVAILABLE_OPERATIONS_DEFAULT_VALUE
40 40 = QVariant::fromValue(OperationsTypes{FuzzingOperationType::CREATE});
41
41 42 // /////// //
42 43 // Methods //
43 44 // /////// //
44 45
45 46 /// Goes through the variables pool and operations pool to determine the set of {variable/operation}
46 47 /// pairs that are valid (i.e. operation that can be executed on variable)
47 48 VariablesOperations availableOperations(const VariablesPool &variablesPool,
48 49 const OperationsPool &operationsPool)
49 50 {
50 51 VariablesOperations result{};
51 52
52 53 for (const auto &variablesPoolEntry : variablesPool) {
53 54 auto variableId = variablesPoolEntry.first;
54 55 auto variable = variablesPoolEntry.second;
55 56
56 57 for (const auto &operation : operationsPool) {
57 58 // A pair is valid if the current operation can be executed on the current variable
58 59 if (operation->canExecute(variable)) {
59 60 result.push_back({variableId, operation});
60 61 }
61 62 }
62 63 }
63 64
64 65 return result;
65 66 }
66 67
67 68 OperationsPool createOperationsPool(const OperationsTypes &types)
68 69 {
69 70 OperationsPool result{};
70 71
71 72 std::transform(types.cbegin(), types.cend(), std::inserter(result, result.end()),
72 73 [](const auto &type) { return FuzzingOperationFactory::create(type); });
73 74
74 75 return result;
75 76 }
76 77
77 78 /**
78 79 * Class to run random tests
79 80 */
80 81 class FuzzingTest {
81 82 public:
82 83 explicit FuzzingTest(VariableController &variableController, Properties properties)
83 84 : m_VariableController{variableController},
84 85 m_Properties{std::move(properties)},
85 86 m_VariablesPool{}
86 87 {
87 88 // Inits variables pool: at init, all variables are null
88 89 for (auto variableId = 0; variableId < nbMaxVariables(); ++variableId) {
89 90 m_VariablesPool[variableId] = nullptr;
90 91 }
91 92 }
92 93
93 94 void execute()
94 95 {
95 96 qCInfo(LOG_TestAmdaFuzzing()) << "Running" << nbMaxOperations() << "operations on"
96 97 << nbMaxVariables() << "variables...";
97 98
98 99 auto canExecute = true;
99 100 for (auto i = 0; i < nbMaxOperations() && canExecute; ++i) {
100 101 // Retrieves all operations that can be executed in the current context
101 102 auto variableOperations = availableOperations(m_VariablesPool, operationsPool());
102 103
103 104 canExecute = !variableOperations.empty();
104 105 if (canExecute) {
105 106 // Of the operations available, chooses a random operation and executes it
106 107 auto variableOperation
107 108 = RandomGenerator::instance().randomChoice(variableOperations);
108 109
109 110 auto variableId = variableOperation.first;
110 111 auto variable = m_VariablesPool.at(variableId);
111 112 auto fuzzingOperation = variableOperation.second;
112 113
113 114 fuzzingOperation->execute(variable, m_VariableController, m_Properties);
114 115
115 116 // Updates variable pool with the new state of the variable after operation
116 117 m_VariablesPool[variableId] = variable;
117 118 }
118 119 else {
119 120 qCInfo(LOG_TestAmdaFuzzing())
120 121 << "No more operations are available, the execution of the test will stop...";
121 122 }
122 123 }
123 124
124 125 qCInfo(LOG_TestAmdaFuzzing()) << "Execution of the test completed.";
125 126 }
126 127
127 128 private:
128 129 int nbMaxOperations() const
129 130 {
130 131 static auto result
131 132 = m_Properties.value(NB_MAX_OPERATIONS_PROPERTY, NB_MAX_OPERATIONS_DEFAULT_VALUE)
132 133 .toInt();
133 134 return result;
134 135 }
135 136
136 137 int nbMaxVariables() const
137 138 {
138 139 static auto result
139 140 = m_Properties.value(NB_MAX_VARIABLES_PROPERTY, NB_MAX_VARIABLES_DEFAULT_VALUE).toInt();
140 141 return result;
141 142 }
142 143
143 144 OperationsPool operationsPool() const
144 145 {
145 146 static auto result = createOperationsPool(
146 147 m_Properties.value(AVAILABLE_OPERATIONS_PROPERTY, AVAILABLE_OPERATIONS_DEFAULT_VALUE)
147 148 .value<OperationsTypes>());
148 149 return result;
149 150 }
150 151
151 152 VariableController &m_VariableController;
152 153 Properties m_Properties;
153 154 VariablesPool m_VariablesPool;
154 155 };
155 156
156 157 } // namespace
157 158
158 159 class TestAmdaFuzzing : public QObject {
159 160 Q_OBJECT
160 161
161 162 private slots:
162 163 /// Input data for @sa testFuzzing()
163 164 void testFuzzing_data();
164 165 void testFuzzing();
165 166 };
166 167
167 168 void TestAmdaFuzzing::testFuzzing_data()
168 169 {
169 170 // ////////////// //
170 171 // Test structure //
171 172 // ////////////// //
172 173
173 174 QTest::addColumn<Properties>("properties"); // Properties for random test
174 175
175 176 // ////////// //
176 177 // Test cases //
177 178 // ////////// //
178 179
179 180 ///@todo: complete
180 181 }
181 182
182 183 void TestAmdaFuzzing::testFuzzing()
183 184 {
184 185 QFETCH(Properties, properties);
185 186
186 187 auto &variableController = sqpApp->variableController();
187 188 auto &timeController = sqpApp->timeController();
188 189
190 // Generates random initial range (bounded to max range)
191 auto maxRange = properties.value(MAX_RANGE_PROPERTY, QVariant::fromValue(INVALID_RANGE))
192 .value<SqpRange>();
193
194 QVERIFY(maxRange != INVALID_RANGE);
195
196 auto initialRangeStart
197 = RandomGenerator::instance().generateDouble(maxRange.m_TStart, maxRange.m_TEnd);
198 auto initialRangeEnd
199 = RandomGenerator::instance().generateDouble(maxRange.m_TStart, maxRange.m_TEnd);
200 if (initialRangeStart > initialRangeEnd) {
201 std::swap(initialRangeStart, initialRangeEnd);
202 }
203
204 // Sets initial range on time controller
205 SqpRange initialRange{initialRangeStart, initialRangeEnd};
206 qCInfo(LOG_TestAmdaFuzzing()) << "Setting initial range to" << initialRange << "...";
207 timeController.onTimeToUpdate(initialRange);
208
189 209 FuzzingTest test{variableController, properties};
190 210 test.execute();
191 211 }
192 212
193 213 int main(int argc, char *argv[])
194 214 {
195 215 QLoggingCategory::setFilterRules(
196 216 "*.warning=false\n"
197 217 "*.info=false\n"
198 218 "*.debug=false\n"
199 219 "FuzzingOperations.info=true\n"
200 220 "TestAmdaFuzzing.info=true\n");
201 221
202 222 SqpApplication app{argc, argv};
203 223 app.setAttribute(Qt::AA_Use96Dpi, true);
204 224 TestAmdaFuzzing testObject{};
205 225 QTEST_SET_MAIN_SOURCE_PATH
206 226 return QTest::qExec(&testObject, argc, argv);
207 227 }
208 228
209 229 #include "TestAmdaFuzzing.moc"
General Comments 0
You need to be logged in to leave comments. Login now