##// END OF EJS Templates
Some fixes...
Alexandre Leroux -
r1223:767abfa514f1
parent child
Show More
@@ -1,66 +1,66
1 #ifndef SCIQLOP_SQPRANGE_H
1 #ifndef SCIQLOP_SQPRANGE_H
2 #define SCIQLOP_SQPRANGE_H
2 #define SCIQLOP_SQPRANGE_H
3
3
4 #include <QObject>
4 #include <QObject>
5
5
6 #include <QDebug>
6 #include <QDebug>
7
7
8 #include <Common/DateUtils.h>
8 #include <Common/DateUtils.h>
9 #include <Common/MetaTypes.h>
9 #include <Common/MetaTypes.h>
10
10
11 #include <cmath>
11 #include <cmath>
12
12
13 /**
13 /**
14 * @brief The SqpRange struct holds the information of time parameters
14 * @brief The SqpRange struct holds the information of time parameters
15 */
15 */
16 struct SqpRange {
16 struct SqpRange {
17 /// Creates SqpRange from dates and times
17 /// Creates SqpRange from dates and times
18 static SqpRange fromDateTime(const QDate &startDate, const QTime &startTime,
18 static SqpRange fromDateTime(const QDate &startDate, const QTime &startTime,
19 const QDate &endDate, const QTime &endTime)
19 const QDate &endDate, const QTime &endTime)
20 {
20 {
21 return {DateUtils::secondsSinceEpoch(QDateTime{startDate, startTime}),
21 return {DateUtils::secondsSinceEpoch(QDateTime{startDate, startTime, Qt::UTC}),
22 DateUtils::secondsSinceEpoch(QDateTime{endDate, endTime})};
22 DateUtils::secondsSinceEpoch(QDateTime{endDate, endTime, Qt::UTC})};
23 }
23 }
24
24
25 /// Start time (UTC)
25 /// Start time (UTC)
26 double m_TStart;
26 double m_TStart;
27 /// End time (UTC)
27 /// End time (UTC)
28 double m_TEnd;
28 double m_TEnd;
29
29
30 bool contains(const SqpRange &dateTime) const noexcept
30 bool contains(const SqpRange &dateTime) const noexcept
31 {
31 {
32 return (m_TStart <= dateTime.m_TStart && m_TEnd >= dateTime.m_TEnd);
32 return (m_TStart <= dateTime.m_TStart && m_TEnd >= dateTime.m_TEnd);
33 }
33 }
34
34
35 bool intersect(const SqpRange &dateTime) const noexcept
35 bool intersect(const SqpRange &dateTime) const noexcept
36 {
36 {
37 return (m_TEnd >= dateTime.m_TStart && m_TStart <= dateTime.m_TEnd);
37 return (m_TEnd >= dateTime.m_TStart && m_TStart <= dateTime.m_TEnd);
38 }
38 }
39
39
40 bool operator==(const SqpRange &other) const
40 bool operator==(const SqpRange &other) const
41 {
41 {
42 auto equals = [](const auto &v1, const auto &v2) {
42 auto equals = [](const auto &v1, const auto &v2) {
43 return (std::isnan(v1) && std::isnan(v2)) || v1 == v2;
43 return (std::isnan(v1) && std::isnan(v2)) || v1 == v2;
44 };
44 };
45
45
46 return equals(m_TStart, other.m_TStart) && equals(m_TEnd, other.m_TEnd);
46 return equals(m_TStart, other.m_TStart) && equals(m_TEnd, other.m_TEnd);
47 }
47 }
48 bool operator!=(const SqpRange &other) const { return !(*this == other); }
48 bool operator!=(const SqpRange &other) const { return !(*this == other); }
49 };
49 };
50
50
51 const auto INVALID_RANGE
51 const auto INVALID_RANGE
52 = SqpRange{std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN()};
52 = SqpRange{std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN()};
53
53
54 inline QDebug operator<<(QDebug d, SqpRange obj)
54 inline QDebug operator<<(QDebug d, SqpRange obj)
55 {
55 {
56 auto tendDateTimeStart = DateUtils::dateTime(obj.m_TStart);
56 auto tendDateTimeStart = DateUtils::dateTime(obj.m_TStart);
57 auto tendDateTimeEnd = DateUtils::dateTime(obj.m_TEnd);
57 auto tendDateTimeEnd = DateUtils::dateTime(obj.m_TEnd);
58
58
59 d << "ts: " << tendDateTimeStart << " te: " << tendDateTimeEnd;
59 d << "ts: " << tendDateTimeStart << " te: " << tendDateTimeEnd;
60 return d;
60 return d;
61 }
61 }
62
62
63 // Required for using shared_ptr in signals/slots
63 // Required for using shared_ptr in signals/slots
64 SCIQLOP_REGISTER_META_TYPE(SQPRANGE_REGISTRY, SqpRange)
64 SCIQLOP_REGISTER_META_TYPE(SQPRANGE_REGISTRY, SqpRange)
65
65
66 #endif // SCIQLOP_SQPRANGE_H
66 #endif // SCIQLOP_SQPRANGE_H
@@ -1,9 +1,10
1 #include "FuzzingDefs.h"
1 #include "FuzzingDefs.h"
2
2
3 const QString NB_MAX_OPERATIONS_PROPERTY = QStringLiteral("component");
3 const QString NB_MAX_OPERATIONS_PROPERTY = QStringLiteral("component");
4 const QString NB_MAX_VARIABLES_PROPERTY = QStringLiteral("nbMaxVariables");
4 const QString NB_MAX_VARIABLES_PROPERTY = QStringLiteral("nbMaxVariables");
5 const QString AVAILABLE_OPERATIONS_PROPERTY = QStringLiteral("availableOperations");
5 const QString AVAILABLE_OPERATIONS_PROPERTY = QStringLiteral("availableOperations");
6 const QString INITIAL_RANGE_PROPERTY = QStringLiteral("initialRange");
6 const QString MAX_RANGE_PROPERTY = QStringLiteral("maxRange");
7 const QString MAX_RANGE_PROPERTY = QStringLiteral("maxRange");
7 const QString METADATA_POOL_PROPERTY = QStringLiteral("metadataPool");
8 const QString METADATA_POOL_PROPERTY = QStringLiteral("metadataPool");
8 const QString PROVIDER_PROPERTY = QStringLiteral("provider");
9 const QString PROVIDER_PROPERTY = QStringLiteral("provider");
9 const QString OPERATION_DELAY_PROPERTY = QStringLiteral("operationDelay");
10 const QString OPERATION_DELAY_PROPERTY = QStringLiteral("operationDelay");
@@ -1,57 +1,61
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 <QVariantHash>
7 #include <QVariantHash>
8
8
9 #include <memory>
9 #include <memory>
10
10
11 // /////// //
11 // /////// //
12 // Aliases //
12 // Aliases //
13 // /////// //
13 // /////// //
14
14
15 using MetadataPool = std::vector<QVariantHash>;
15 using MetadataPool = std::vector<QVariantHash>;
16 Q_DECLARE_METATYPE(MetadataPool)
16 Q_DECLARE_METATYPE(MetadataPool)
17
17
18 using Properties = QVariantHash;
18 using Properties = QVariantHash;
19
19
20 // ///////// //
20 // ///////// //
21 // Constants //
21 // Constants //
22 // ///////// //
22 // ///////// //
23
23
24 /// Max number of operations to generate
24 /// Max number of operations to generate
25 extern const QString NB_MAX_OPERATIONS_PROPERTY;
25 extern const QString NB_MAX_OPERATIONS_PROPERTY;
26
26
27 /// Max number of variables to manipulate through operations
27 /// Max number of variables to manipulate through operations
28 extern const QString NB_MAX_VARIABLES_PROPERTY;
28 extern const QString NB_MAX_VARIABLES_PROPERTY;
29
29
30 /// Set of operations available for the test
30 /// Set of operations available for the test
31 extern const QString AVAILABLE_OPERATIONS_PROPERTY;
31 extern const QString AVAILABLE_OPERATIONS_PROPERTY;
32
32
33
34 /// Range with which the timecontroller is initialized
35 extern const QString INITIAL_RANGE_PROPERTY;
36
33 /// Max range that an operation can reach
37 /// Max range that an operation can reach
34 extern const QString MAX_RANGE_PROPERTY;
38 extern const QString MAX_RANGE_PROPERTY;
35
39
36 /// Set of metadata that can be associated to a variable
40 /// Set of metadata that can be associated to a variable
37 extern const QString METADATA_POOL_PROPERTY;
41 extern const QString METADATA_POOL_PROPERTY;
38
42
39 /// Provider used to retrieve data
43 /// Provider used to retrieve data
40 extern const QString PROVIDER_PROPERTY;
44 extern const QString PROVIDER_PROPERTY;
41
45
42 /// Time left for an operation to execute
46 /// Time left for an operation to execute
43 extern const QString OPERATION_DELAY_PROPERTY;
47 extern const QString OPERATION_DELAY_PROPERTY;
44
48
45
49
46 // /////// //
50 // /////// //
47 // Structs //
51 // Structs //
48 // /////// //
52 // /////// //
49
53
50 class Variable;
54 class Variable;
51
55
52 struct VariableState {
56 struct VariableState {
53 std::shared_ptr<Variable> m_Variable{nullptr};
57 std::shared_ptr<Variable> m_Variable{nullptr};
54 SqpRange m_Range{INVALID_RANGE};
58 SqpRange m_Range{INVALID_RANGE};
55 };
59 };
56
60
57 #endif // SCIQLOP_FUZZINGDEFS_H
61 #endif // SCIQLOP_FUZZINGDEFS_H
@@ -1,183 +1,186
1 #include "FuzzingOperations.h"
1 #include "FuzzingOperations.h"
2 #include "FuzzingUtils.h"
2 #include "FuzzingUtils.h"
3
3
4 #include <Data/IDataProvider.h>
4 #include <Data/IDataProvider.h>
5
5
6 #include <Variable/Variable.h>
6 #include <Variable/Variable.h>
7 #include <Variable/VariableController.h>
7 #include <Variable/VariableController.h>
8
8
9 #include <QUuid>
9 #include <QUuid>
10
10
11 #include <functional>
11 #include <functional>
12
12
13 Q_LOGGING_CATEGORY(LOG_FuzzingOperations, "FuzzingOperations")
13 Q_LOGGING_CATEGORY(LOG_FuzzingOperations, "FuzzingOperations")
14
14
15 namespace {
15 namespace {
16
16
17 struct CreateOperation : public IFuzzingOperation {
17 struct CreateOperation : public IFuzzingOperation {
18 bool canExecute(const VariableState &variableState) const override
18 bool canExecute(const VariableState &variableState) const override
19 {
19 {
20 // A variable can be created only if it doesn't exist yet
20 // A variable can be created only if it doesn't exist yet
21 return variableState.m_Variable == nullptr;
21 return variableState.m_Variable == nullptr;
22 }
22 }
23
23
24 void execute(VariableState &variableState, VariableController &variableController,
24 void execute(VariableState &variableState, VariableController &variableController,
25 const Properties &properties) const override
25 const Properties &properties) const override
26 {
26 {
27 // Retrieves metadata pool from properties, and choose one of the metadata entries to
27 // Retrieves metadata pool from properties, and choose one of the metadata entries to
28 // associate it with the variable
28 // associate it with the variable
29 auto metaDataPool = properties.value(METADATA_POOL_PROPERTY).value<MetadataPool>();
29 auto metaDataPool = properties.value(METADATA_POOL_PROPERTY).value<MetadataPool>();
30 auto variableMetadata = RandomGenerator::instance().randomChoice(metaDataPool);
30 auto variableMetadata = RandomGenerator::instance().randomChoice(metaDataPool);
31
31
32 // Retrieves provider
32 // Retrieves provider
33 auto variableProvider
33 auto variableProvider
34 = properties.value(PROVIDER_PROPERTY).value<std::shared_ptr<IDataProvider> >();
34 = properties.value(PROVIDER_PROPERTY).value<std::shared_ptr<IDataProvider> >();
35
35
36 auto variableName = QString{"Var_%1"}.arg(QUuid::createUuid().toString());
36 auto variableName = QString{"Var_%1"}.arg(QUuid::createUuid().toString());
37 qCInfo(LOG_FuzzingOperations())
37 qCInfo(LOG_FuzzingOperations()).noquote()
38 << "Creating variable" << variableName << "(metadata:" << variableMetadata << ")";
38 << "Creating variable" << variableName << "(metadata:" << variableMetadata << ")";
39
39
40 auto newVariable
40 auto newVariable
41 = variableController.createVariable(variableName, variableMetadata, variableProvider);
41 = variableController.createVariable(variableName, variableMetadata, variableProvider);
42
43 // Updates variable's state
44 variableState.m_Range = properties.value(INITIAL_RANGE_PROPERTY).value<SqpRange>();
42 std::swap(variableState.m_Variable, newVariable);
45 std::swap(variableState.m_Variable, newVariable);
43 }
46 }
44 };
47 };
45
48
46 /**
49 /**
47 * Defines a move operation through a range.
50 * Defines a move operation through a range.
48 *
51 *
49 * A move operation is determined by three functions:
52 * A move operation is determined by three functions:
50 * - Two 'move' functions, used to indicate in which direction the beginning and the end of a range
53 * - Two 'move' functions, used to indicate in which direction the beginning and the end of a range
51 * are going during the operation. These functions will be:
54 * are going during the operation. These functions will be:
52 * -- {<- / <-} for pan left
55 * -- {<- / <-} for pan left
53 * -- {-> / ->} for pan right
56 * -- {-> / ->} for pan right
54 * -- {-> / <-} for zoom in
57 * -- {-> / <-} for zoom in
55 * -- {<- / ->} for zoom out
58 * -- {<- / ->} for zoom out
56 * - One 'max move' functions, used to compute the max delta at which the operation can move a
59 * - One 'max move' functions, used to compute the max delta at which the operation can move a
57 * range, according to a max range. For exemple, for a range of {1, 5} and a max range of {0, 10},
60 * range, according to a max range. For exemple, for a range of {1, 5} and a max range of {0, 10},
58 * max deltas will be:
61 * max deltas will be:
59 * -- {0, 4} for pan left
62 * -- {0, 4} for pan left
60 * -- {6, 10} for pan right
63 * -- {6, 10} for pan right
61 * -- {3, 3} for zoom in
64 * -- {3, 3} for zoom in
62 * -- {0, 6} for zoom out (same spacing left and right)
65 * -- {0, 6} for zoom out (same spacing left and right)
63 */
66 */
64 struct MoveOperation : public IFuzzingOperation {
67 struct MoveOperation : public IFuzzingOperation {
65 using MoveFunction = std::function<double(double currentValue, double maxValue)>;
68 using MoveFunction = std::function<double(double currentValue, double maxValue)>;
66 using MaxMoveFunction = std::function<double(const SqpRange &range, const SqpRange &maxRange)>;
69 using MaxMoveFunction = std::function<double(const SqpRange &range, const SqpRange &maxRange)>;
67
70
68 explicit MoveOperation(MoveFunction rangeStartMoveFun, MoveFunction rangeEndMoveFun,
71 explicit MoveOperation(MoveFunction rangeStartMoveFun, MoveFunction rangeEndMoveFun,
69 MaxMoveFunction maxMoveFun,
72 MaxMoveFunction maxMoveFun,
70 const QString &label = QStringLiteral("Move operation"))
73 const QString &label = QStringLiteral("Move operation"))
71 : m_RangeStartMoveFun{std::move(rangeStartMoveFun)},
74 : m_RangeStartMoveFun{std::move(rangeStartMoveFun)},
72 m_RangeEndMoveFun{std::move(rangeEndMoveFun)},
75 m_RangeEndMoveFun{std::move(rangeEndMoveFun)},
73 m_MaxMoveFun{std::move(maxMoveFun)},
76 m_MaxMoveFun{std::move(maxMoveFun)},
74 m_Label{label}
77 m_Label{label}
75 {
78 {
76 }
79 }
77
80
78 bool canExecute(const VariableState &variableState) const override
81 bool canExecute(const VariableState &variableState) const override
79 {
82 {
80 return variableState.m_Variable != nullptr;
83 return variableState.m_Variable != nullptr;
81 }
84 }
82
85
83 void execute(VariableState &variableState, VariableController &variableController,
86 void execute(VariableState &variableState, VariableController &variableController,
84 const Properties &properties) const override
87 const Properties &properties) const override
85 {
88 {
86 auto variable = variableState.m_Variable;
89 auto variable = variableState.m_Variable;
87
90
88 // Gets the max range defined
91 // Gets the max range defined
89 auto maxRange = properties.value(MAX_RANGE_PROPERTY, QVariant::fromValue(INVALID_RANGE))
92 auto maxRange = properties.value(MAX_RANGE_PROPERTY, QVariant::fromValue(INVALID_RANGE))
90 .value<SqpRange>();
93 .value<SqpRange>();
91 auto variableRange = variable->range();
94 auto variableRange = variable->range();
92
95
93 if (maxRange == INVALID_RANGE || variableRange.m_TStart < maxRange.m_TStart
96 if (maxRange == INVALID_RANGE || variableRange.m_TStart < maxRange.m_TStart
94 || variableRange.m_TEnd > maxRange.m_TEnd) {
97 || variableRange.m_TEnd > maxRange.m_TEnd) {
95 qCWarning(LOG_FuzzingOperations()) << "Can't execute operation: invalid max range";
98 qCWarning(LOG_FuzzingOperations()) << "Can't execute operation: invalid max range";
96 return;
99 return;
97 }
100 }
98
101
99 // Computes the max delta at which the variable can move, up to the limits of the max range
102 // Computes the max delta at which the variable can move, up to the limits of the max range
100 auto deltaMax = m_MaxMoveFun(variable->range(), maxRange);
103 auto deltaMax = m_MaxMoveFun(variable->range(), maxRange);
101
104
102 // Generates random delta that will be used to move variable
105 // Generates random delta that will be used to move variable
103 auto delta = RandomGenerator::instance().generateDouble(0, deltaMax);
106 auto delta = RandomGenerator::instance().generateDouble(0, deltaMax);
104
107
105 // Moves variable to its new range
108 // Moves variable to its new range
106 auto newVariableRange = SqpRange{m_RangeStartMoveFun(variableRange.m_TStart, delta),
109 auto newVariableRange = SqpRange{m_RangeStartMoveFun(variableRange.m_TStart, delta),
107 m_RangeEndMoveFun(variableRange.m_TEnd, delta)};
110 m_RangeEndMoveFun(variableRange.m_TEnd, delta)};
108 qCInfo(LOG_FuzzingOperations())
111 qCInfo(LOG_FuzzingOperations()).noquote()
109 << "Performing" << m_Label << "on" << variable->name() << "(from" << variableRange
112 << "Performing" << m_Label << "on" << variable->name() << "(from" << variableRange
110 << "to" << newVariableRange << ")...";
113 << "to" << newVariableRange << ")...";
111 variableController.onRequestDataLoading({variable}, newVariableRange, false);
114 variableController.onRequestDataLoading({variable}, newVariableRange, false);
112
115
113 // Updates variable's state
116 // Updates variable's state
114 variableState.m_Range = newVariableRange;
117 variableState.m_Range = newVariableRange;
115 }
118 }
116
119
117 MoveFunction m_RangeStartMoveFun;
120 MoveFunction m_RangeStartMoveFun;
118 MoveFunction m_RangeEndMoveFun;
121 MoveFunction m_RangeEndMoveFun;
119 MaxMoveFunction m_MaxMoveFun;
122 MaxMoveFunction m_MaxMoveFun;
120 QString m_Label;
123 QString m_Label;
121 };
124 };
122
125
123 struct UnknownOperation : public IFuzzingOperation {
126 struct UnknownOperation : public IFuzzingOperation {
124 bool canExecute(const VariableState &variableState) const override
127 bool canExecute(const VariableState &variableState) const override
125 {
128 {
126 Q_UNUSED(variableState);
129 Q_UNUSED(variableState);
127 return false;
130 return false;
128 }
131 }
129
132
130 void execute(VariableState &variableState, VariableController &variableController,
133 void execute(VariableState &variableState, VariableController &variableController,
131 const Properties &properties) const override
134 const Properties &properties) const override
132 {
135 {
133 Q_UNUSED(variableState);
136 Q_UNUSED(variableState);
134 Q_UNUSED(variableController);
137 Q_UNUSED(variableController);
135 Q_UNUSED(properties);
138 Q_UNUSED(properties);
136 // Does nothing
139 // Does nothing
137 }
140 }
138 };
141 };
139
142
140 } // namespace
143 } // namespace
141
144
142 std::unique_ptr<IFuzzingOperation> FuzzingOperationFactory::create(FuzzingOperationType type)
145 std::unique_ptr<IFuzzingOperation> FuzzingOperationFactory::create(FuzzingOperationType type)
143 {
146 {
144 switch (type) {
147 switch (type) {
145 case FuzzingOperationType::CREATE:
148 case FuzzingOperationType::CREATE:
146 return std::make_unique<CreateOperation>();
149 return std::make_unique<CreateOperation>();
147 case FuzzingOperationType::PAN_LEFT:
150 case FuzzingOperationType::PAN_LEFT:
148 return std::make_unique<MoveOperation>(
151 return std::make_unique<MoveOperation>(
149 std::minus<double>(), std::minus<double>(),
152 std::minus<double>(), std::minus<double>(),
150 [](const SqpRange &range, const SqpRange &maxRange) {
153 [](const SqpRange &range, const SqpRange &maxRange) {
151 return range.m_TStart - maxRange.m_TStart;
154 return range.m_TStart - maxRange.m_TStart;
152 },
155 },
153 QStringLiteral("Pan left operation"));
156 QStringLiteral("Pan left operation"));
154 case FuzzingOperationType::PAN_RIGHT:
157 case FuzzingOperationType::PAN_RIGHT:
155 return std::make_unique<MoveOperation>(
158 return std::make_unique<MoveOperation>(
156 std::plus<double>(), std::plus<double>(),
159 std::plus<double>(), std::plus<double>(),
157 [](const SqpRange &range, const SqpRange &maxRange) {
160 [](const SqpRange &range, const SqpRange &maxRange) {
158 return maxRange.m_TEnd - range.m_TEnd;
161 return maxRange.m_TEnd - range.m_TEnd;
159 },
162 },
160 QStringLiteral("Pan right operation"));
163 QStringLiteral("Pan right operation"));
161 case FuzzingOperationType::ZOOM_IN:
164 case FuzzingOperationType::ZOOM_IN:
162 return std::make_unique<MoveOperation>(
165 return std::make_unique<MoveOperation>(
163 std::plus<double>(), std::minus<double>(),
166 std::plus<double>(), std::minus<double>(),
164 [](const SqpRange &range, const SqpRange &maxRange) {
167 [](const SqpRange &range, const SqpRange &maxRange) {
165 Q_UNUSED(maxRange)
168 Q_UNUSED(maxRange)
166 return range.m_TEnd - (range.m_TStart + range.m_TEnd) / 2.;
169 return range.m_TEnd - (range.m_TStart + range.m_TEnd) / 2.;
167 },
170 },
168 QStringLiteral("Zoom in operation"));
171 QStringLiteral("Zoom in operation"));
169 case FuzzingOperationType::ZOOM_OUT:
172 case FuzzingOperationType::ZOOM_OUT:
170 return std::make_unique<MoveOperation>(
173 return std::make_unique<MoveOperation>(
171 std::minus<double>(), std::plus<double>(),
174 std::minus<double>(), std::plus<double>(),
172 [](const SqpRange &range, const SqpRange &maxRange) {
175 [](const SqpRange &range, const SqpRange &maxRange) {
173 return std::min(range.m_TStart - maxRange.m_TStart,
176 return std::min(range.m_TStart - maxRange.m_TStart,
174 maxRange.m_TEnd - range.m_TEnd);
177 maxRange.m_TEnd - range.m_TEnd);
175 },
178 },
176 QStringLiteral("Zoom out operation"));
179 QStringLiteral("Zoom out operation"));
177 default:
180 default:
178 // Default case returns unknown operation
181 // Default case returns unknown operation
179 break;
182 break;
180 }
183 }
181
184
182 return std::make_unique<UnknownOperation>();
185 return std::make_unique<UnknownOperation>();
183 }
186 }
@@ -1,268 +1,269
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
4
5 #include "AmdaProvider.h"
5 #include "AmdaProvider.h"
6
6
7 #include <Network/NetworkController.h>
7 #include <Network/NetworkController.h>
8 #include <SqpApplication.h>
8 #include <SqpApplication.h>
9 #include <Time/TimeController.h>
9 #include <Time/TimeController.h>
10 #include <Variable/Variable.h>
10 #include <Variable/Variable.h>
11 #include <Variable/VariableController.h>
11 #include <Variable/VariableController.h>
12
12
13 #include <QLoggingCategory>
13 #include <QLoggingCategory>
14 #include <QObject>
14 #include <QObject>
15 #include <QtTest>
15 #include <QtTest>
16
16
17 #include <memory>
17 #include <memory>
18
18
19 Q_LOGGING_CATEGORY(LOG_TestAmdaFuzzing, "TestAmdaFuzzing")
19 Q_LOGGING_CATEGORY(LOG_TestAmdaFuzzing, "TestAmdaFuzzing")
20
20
21 namespace {
21 namespace {
22
22
23 // /////// //
23 // /////// //
24 // Aliases //
24 // Aliases //
25 // /////// //
25 // /////// //
26
26
27 using VariableId = int;
27 using VariableId = int;
28 using Weight = double;
28 using Weight = double;
29 using Weights = std::vector<Weight>;
29 using Weights = std::vector<Weight>;
30
30
31 using VariableOperation = std::pair<VariableId, std::shared_ptr<IFuzzingOperation> >;
31 using VariableOperation = std::pair<VariableId, std::shared_ptr<IFuzzingOperation> >;
32 using VariablesOperations = std::vector<VariableOperation>;
32 using VariablesOperations = std::vector<VariableOperation>;
33
33
34 using WeightedOperationsPool = std::map<std::shared_ptr<IFuzzingOperation>, Weight>;
34 using WeightedOperationsPool = std::map<std::shared_ptr<IFuzzingOperation>, Weight>;
35 using VariablesPool = std::map<VariableId, VariableState>;
35 using VariablesPool = std::map<VariableId, VariableState>;
36
36
37 // ///////// //
37 // ///////// //
38 // Constants //
38 // Constants //
39 // ///////// //
39 // ///////// //
40
40
41 // Defaults values used when the associated properties have not been set for the test
41 // Defaults values used when the associated properties have not been set for the test
42 const auto NB_MAX_OPERATIONS_DEFAULT_VALUE = 100;
42 const auto NB_MAX_OPERATIONS_DEFAULT_VALUE = 100;
43 const auto NB_MAX_VARIABLES_DEFAULT_VALUE = 1;
43 const auto NB_MAX_VARIABLES_DEFAULT_VALUE = 1;
44 const auto AVAILABLE_OPERATIONS_DEFAULT_VALUE
44 const auto AVAILABLE_OPERATIONS_DEFAULT_VALUE
45 = QVariant::fromValue(WeightedOperationsTypes{{FuzzingOperationType::CREATE, 1.},
45 = QVariant::fromValue(WeightedOperationsTypes{{FuzzingOperationType::CREATE, 1.},
46 {FuzzingOperationType::PAN_LEFT, 1.},
46 {FuzzingOperationType::PAN_LEFT, 1.},
47 {FuzzingOperationType::PAN_RIGHT, 1.},
47 {FuzzingOperationType::PAN_RIGHT, 1.},
48 {FuzzingOperationType::ZOOM_IN, 1.},
48 {FuzzingOperationType::ZOOM_IN, 1.},
49 {FuzzingOperationType::ZOOM_OUT, 1.}});
49 {FuzzingOperationType::ZOOM_OUT, 1.}});
50
50
51 /// Delay between each operation (in ms)
51 /// Delay between each operation (in ms)
52 const auto OPERATION_DELAY_DEFAULT_VALUE = 3000;
52 const auto OPERATION_DELAY_DEFAULT_VALUE = 3000;
53
53
54 // /////// //
54 // /////// //
55 // Methods //
55 // Methods //
56 // /////// //
56 // /////// //
57
57
58 /// Goes through the variables pool and operations pool to determine the set of {variable/operation}
58 /// Goes through the variables pool and operations pool to determine the set of {variable/operation}
59 /// pairs that are valid (i.e. operation that can be executed on variable)
59 /// pairs that are valid (i.e. operation that can be executed on variable)
60 std::pair<VariablesOperations, Weights>
60 std::pair<VariablesOperations, Weights>
61 availableOperations(const VariablesPool &variablesPool,
61 availableOperations(const VariablesPool &variablesPool,
62 const WeightedOperationsPool &operationsPool)
62 const WeightedOperationsPool &operationsPool)
63 {
63 {
64 VariablesOperations result{};
64 VariablesOperations result{};
65 Weights weights{};
65 Weights weights{};
66
66
67 for (const auto &variablesPoolEntry : variablesPool) {
67 for (const auto &variablesPoolEntry : variablesPool) {
68 auto variableId = variablesPoolEntry.first;
68 auto variableId = variablesPoolEntry.first;
69 const auto &variableState = variablesPoolEntry.second;
69 const auto &variableState = variablesPoolEntry.second;
70
70
71 for (const auto &operationsPoolEntry : operationsPool) {
71 for (const auto &operationsPoolEntry : operationsPool) {
72 auto operation = operationsPoolEntry.first;
72 auto operation = operationsPoolEntry.first;
73 auto weight = operationsPoolEntry.second;
73 auto weight = operationsPoolEntry.second;
74
74
75 // A pair is valid if the current operation can be executed on the current variable
75 // A pair is valid if the current operation can be executed on the current variable
76 if (operation->canExecute(variableState)) {
76 if (operation->canExecute(variableState)) {
77 result.push_back({variableId, operation});
77 result.push_back({variableId, operation});
78 weights.push_back(weight);
78 weights.push_back(weight);
79 }
79 }
80 }
80 }
81 }
81 }
82
82
83 return {result, weights};
83 return {result, weights};
84 }
84 }
85
85
86 WeightedOperationsPool createOperationsPool(const WeightedOperationsTypes &types)
86 WeightedOperationsPool createOperationsPool(const WeightedOperationsTypes &types)
87 {
87 {
88 WeightedOperationsPool result{};
88 WeightedOperationsPool result{};
89
89
90 std::transform(
90 std::transform(
91 types.cbegin(), types.cend(), std::inserter(result, result.end()), [](const auto &type) {
91 types.cbegin(), types.cend(), std::inserter(result, result.end()), [](const auto &type) {
92 return std::make_pair(FuzzingOperationFactory::create(type.first), type.second);
92 return std::make_pair(FuzzingOperationFactory::create(type.first), type.second);
93 });
93 });
94
94
95 return result;
95 return result;
96 }
96 }
97
97
98 /**
98 /**
99 * Class to run random tests
99 * Class to run random tests
100 */
100 */
101 class FuzzingTest {
101 class FuzzingTest {
102 public:
102 public:
103 explicit FuzzingTest(VariableController &variableController, Properties properties)
103 explicit FuzzingTest(VariableController &variableController, Properties properties)
104 : m_VariableController{variableController},
104 : m_VariableController{variableController},
105 m_Properties{std::move(properties)},
105 m_Properties{std::move(properties)},
106 m_VariablesPool{}
106 m_VariablesPool{}
107 {
107 {
108 // Inits variables pool: at init, all variables are null
108 // Inits variables pool: at init, all variables are null
109 for (auto variableId = 0; variableId < nbMaxVariables(); ++variableId) {
109 for (auto variableId = 0; variableId < nbMaxVariables(); ++variableId) {
110 m_VariablesPool[variableId] = VariableState{};
110 m_VariablesPool[variableId] = VariableState{};
111 }
111 }
112 }
112 }
113
113
114 void execute()
114 void execute()
115 {
115 {
116 qCInfo(LOG_TestAmdaFuzzing()) << "Running" << nbMaxOperations() << "operations on"
116 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Running" << nbMaxOperations() << "operations on"
117 << nbMaxVariables() << "variable(s)...";
117 << nbMaxVariables() << "variable(s)...";
118
118
119 auto canExecute = true;
119 auto canExecute = true;
120 for (auto i = 0; i < nbMaxOperations() && canExecute; ++i) {
120 for (auto i = 0; i < nbMaxOperations() && canExecute; ++i) {
121 // Retrieves all operations that can be executed in the current context
121 // Retrieves all operations that can be executed in the current context
122 VariablesOperations variableOperations{};
122 VariablesOperations variableOperations{};
123 Weights weights{};
123 Weights weights{};
124 std::tie(variableOperations, weights)
124 std::tie(variableOperations, weights)
125 = availableOperations(m_VariablesPool, operationsPool());
125 = availableOperations(m_VariablesPool, operationsPool());
126
126
127 canExecute = !variableOperations.empty();
127 canExecute = !variableOperations.empty();
128 if (canExecute) {
128 if (canExecute) {
129 // Of the operations available, chooses a random operation and executes it
129 // Of the operations available, chooses a random operation and executes it
130 auto variableOperation
130 auto variableOperation
131 = RandomGenerator::instance().randomChoice(variableOperations, weights);
131 = RandomGenerator::instance().randomChoice(variableOperations, weights);
132
132
133 auto variableId = variableOperation.first;
133 auto variableId = variableOperation.first;
134 auto &variableState = m_VariablesPool.at(variableId);
134 auto &variableState = m_VariablesPool.at(variableId);
135 auto fuzzingOperation = variableOperation.second;
135 auto fuzzingOperation = variableOperation.second;
136
136
137 fuzzingOperation->execute(variableState, m_VariableController, m_Properties);
137 fuzzingOperation->execute(variableState, m_VariableController, m_Properties);
138 QTest::qWait(operationDelay());
138 QTest::qWait(operationDelay());
139
139
140 }
140 }
141 else {
141 else {
142 qCInfo(LOG_TestAmdaFuzzing())
142 qCInfo(LOG_TestAmdaFuzzing()).noquote()
143 << "No more operations are available, the execution of the test will stop...";
143 << "No more operations are available, the execution of the test will stop...";
144 }
144 }
145 }
145 }
146
146
147 qCInfo(LOG_TestAmdaFuzzing()) << "Execution of the test completed.";
147 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Execution of the test completed.";
148 }
148 }
149
149
150 private:
150 private:
151 int nbMaxOperations() const
151 int nbMaxOperations() const
152 {
152 {
153 static auto result
153 static auto result
154 = m_Properties.value(NB_MAX_OPERATIONS_PROPERTY, NB_MAX_OPERATIONS_DEFAULT_VALUE)
154 = m_Properties.value(NB_MAX_OPERATIONS_PROPERTY, NB_MAX_OPERATIONS_DEFAULT_VALUE)
155 .toInt();
155 .toInt();
156 return result;
156 return result;
157 }
157 }
158
158
159 int nbMaxVariables() const
159 int nbMaxVariables() const
160 {
160 {
161 static auto result
161 static auto result
162 = m_Properties.value(NB_MAX_VARIABLES_PROPERTY, NB_MAX_VARIABLES_DEFAULT_VALUE).toInt();
162 = m_Properties.value(NB_MAX_VARIABLES_PROPERTY, NB_MAX_VARIABLES_DEFAULT_VALUE).toInt();
163 return result;
163 return result;
164 }
164 }
165
165
166 int operationDelay() const
166 int operationDelay() const
167 {
167 {
168 static auto result
168 static auto result
169 = m_Properties.value(OPERATION_DELAY_PROPERTY, OPERATION_DELAY_DEFAULT_VALUE).toInt();
169 = m_Properties.value(OPERATION_DELAY_PROPERTY, OPERATION_DELAY_DEFAULT_VALUE).toInt();
170 return result;
170 return result;
171 }
171 }
172
172
173 WeightedOperationsPool operationsPool() const
173 WeightedOperationsPool operationsPool() const
174 {
174 {
175 static auto result = createOperationsPool(
175 static auto result = createOperationsPool(
176 m_Properties.value(AVAILABLE_OPERATIONS_PROPERTY, AVAILABLE_OPERATIONS_DEFAULT_VALUE)
176 m_Properties.value(AVAILABLE_OPERATIONS_PROPERTY, AVAILABLE_OPERATIONS_DEFAULT_VALUE)
177 .value<WeightedOperationsTypes>());
177 .value<WeightedOperationsTypes>());
178 return result;
178 return result;
179 }
179 }
180
180
181 VariableController &m_VariableController;
181 VariableController &m_VariableController;
182 Properties m_Properties;
182 Properties m_Properties;
183 VariablesPool m_VariablesPool;
183 VariablesPool m_VariablesPool;
184 };
184 };
185
185
186 } // namespace
186 } // namespace
187
187
188 class TestAmdaFuzzing : public QObject {
188 class TestAmdaFuzzing : public QObject {
189 Q_OBJECT
189 Q_OBJECT
190
190
191 private slots:
191 private slots:
192 /// Input data for @sa testFuzzing()
192 /// Input data for @sa testFuzzing()
193 void testFuzzing_data();
193 void testFuzzing_data();
194 void testFuzzing();
194 void testFuzzing();
195 };
195 };
196
196
197 void TestAmdaFuzzing::testFuzzing_data()
197 void TestAmdaFuzzing::testFuzzing_data()
198 {
198 {
199 // ////////////// //
199 // ////////////// //
200 // Test structure //
200 // Test structure //
201 // ////////////// //
201 // ////////////// //
202
202
203 QTest::addColumn<Properties>("properties"); // Properties for random test
203 QTest::addColumn<Properties>("properties"); // Properties for random test
204
204
205 // ////////// //
205 // ////////// //
206 // Test cases //
206 // Test cases //
207 // ////////// //
207 // ////////// //
208
208
209 auto maxRange = SqpRange::fromDateTime({2017, 1, 1}, {0, 0}, {2017, 1, 5}, {0, 0});
209 auto maxRange = SqpRange::fromDateTime({2017, 1, 1}, {0, 0}, {2017, 1, 5}, {0, 0});
210 MetadataPool metadataPool{{{"dataType", "vector"}, {"xml:id", "imf"}}};
210 MetadataPool metadataPool{{{"dataType", "vector"}, {"xml:id", "imf"}}};
211
211
212 // Note: we don't use auto here as we want to pass std::shared_ptr<IDataProvider> as is in the
212 // Note: we don't use auto here as we want to pass std::shared_ptr<IDataProvider> as is in the
213 // QVariant
213 // QVariant
214 std::shared_ptr<IDataProvider> provider = std::make_shared<AmdaProvider>();
214 std::shared_ptr<IDataProvider> provider = std::make_shared<AmdaProvider>();
215
215
216 QTest::newRow("fuzzingTest") << Properties{
216 QTest::newRow("fuzzingTest") << Properties{
217 {MAX_RANGE_PROPERTY, QVariant::fromValue(maxRange)},
217 {MAX_RANGE_PROPERTY, QVariant::fromValue(maxRange)},
218 {METADATA_POOL_PROPERTY, QVariant::fromValue(metadataPool)},
218 {METADATA_POOL_PROPERTY, QVariant::fromValue(metadataPool)},
219 {PROVIDER_PROPERTY, QVariant::fromValue(provider)}};
219 {PROVIDER_PROPERTY, QVariant::fromValue(provider)}};
220 }
220 }
221
221
222 void TestAmdaFuzzing::testFuzzing()
222 void TestAmdaFuzzing::testFuzzing()
223 {
223 {
224 QFETCH(Properties, properties);
224 QFETCH(Properties, properties);
225
225
226 auto &variableController = sqpApp->variableController();
226 auto &variableController = sqpApp->variableController();
227 auto &timeController = sqpApp->timeController();
227 auto &timeController = sqpApp->timeController();
228
228
229 // Generates random initial range (bounded to max range)
229 // Generates random initial range (bounded to max range)
230 auto maxRange = properties.value(MAX_RANGE_PROPERTY, QVariant::fromValue(INVALID_RANGE))
230 auto maxRange = properties.value(MAX_RANGE_PROPERTY, QVariant::fromValue(INVALID_RANGE))
231 .value<SqpRange>();
231 .value<SqpRange>();
232
232
233 QVERIFY(maxRange != INVALID_RANGE);
233 QVERIFY(maxRange != INVALID_RANGE);
234
234
235 auto initialRangeStart
235 auto initialRangeStart
236 = RandomGenerator::instance().generateDouble(maxRange.m_TStart, maxRange.m_TEnd);
236 = RandomGenerator::instance().generateDouble(maxRange.m_TStart, maxRange.m_TEnd);
237 auto initialRangeEnd
237 auto initialRangeEnd
238 = RandomGenerator::instance().generateDouble(maxRange.m_TStart, maxRange.m_TEnd);
238 = RandomGenerator::instance().generateDouble(maxRange.m_TStart, maxRange.m_TEnd);
239 if (initialRangeStart > initialRangeEnd) {
239 if (initialRangeStart > initialRangeEnd) {
240 std::swap(initialRangeStart, initialRangeEnd);
240 std::swap(initialRangeStart, initialRangeEnd);
241 }
241 }
242
242
243 // Sets initial range on time controller
243 // Sets initial range on time controller
244 SqpRange initialRange{initialRangeStart, initialRangeEnd};
244 SqpRange initialRange{initialRangeStart, initialRangeEnd};
245 qCInfo(LOG_TestAmdaFuzzing()) << "Setting initial range to" << initialRange << "...";
245 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Setting initial range to" << initialRange << "...";
246 timeController.onTimeToUpdate(initialRange);
246 timeController.onTimeToUpdate(initialRange);
247 properties.insert(INITIAL_RANGE_PROPERTY, QVariant::fromValue(initialRange));
247
248
248 FuzzingTest test{variableController, properties};
249 FuzzingTest test{variableController, properties};
249 test.execute();
250 test.execute();
250 }
251 }
251
252
252 int main(int argc, char *argv[])
253 int main(int argc, char *argv[])
253 {
254 {
254 QLoggingCategory::setFilterRules(
255 QLoggingCategory::setFilterRules(
255 "*.warning=false\n"
256 "*.warning=false\n"
256 "*.info=false\n"
257 "*.info=false\n"
257 "*.debug=false\n"
258 "*.debug=false\n"
258 "FuzzingOperations.info=true\n"
259 "FuzzingOperations.info=true\n"
259 "TestAmdaFuzzing.info=true\n");
260 "TestAmdaFuzzing.info=true\n");
260
261
261 SqpApplication app{argc, argv};
262 SqpApplication app{argc, argv};
262 app.setAttribute(Qt::AA_Use96Dpi, true);
263 app.setAttribute(Qt::AA_Use96Dpi, true);
263 TestAmdaFuzzing testObject{};
264 TestAmdaFuzzing testObject{};
264 QTEST_SET_MAIN_SOURCE_PATH
265 QTEST_SET_MAIN_SOURCE_PATH
265 return QTest::qExec(&testObject, argc, argv);
266 return QTest::qExec(&testObject, argc, argv);
266 }
267 }
267
268
268 #include "TestAmdaFuzzing.moc"
269 #include "TestAmdaFuzzing.moc"
General Comments 0
You need to be logged in to leave comments. Login now