##// END OF EJS Templates
Passes FuzzingState and variable id instead VariableState to the methods of operations
Alexandre Leroux -
r1236:ea04bef9c90c
parent child
Show More
@@ -1,210 +1,206
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(VariableId variableId, const FuzzingState &fuzzingState) 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 fuzzingState.variableState(variableId).m_Variable == nullptr;
22 }
22 }
23
23
24 void execute(VariableState &variableState, VariableController &variableController,
24 void execute(VariableId variableId, FuzzingState &fuzzingState,
25 VariableController &variableController,
25 const Properties &properties) const override
26 const Properties &properties) const override
26 {
27 {
27 // Retrieves metadata pool from properties, and choose one of the metadata entries to
28 // Retrieves metadata pool from properties, and choose one of the metadata entries to
28 // associate it with the variable
29 // associate it with the variable
29 auto metaDataPool = properties.value(METADATA_POOL_PROPERTY).value<MetadataPool>();
30 auto metaDataPool = properties.value(METADATA_POOL_PROPERTY).value<MetadataPool>();
30 auto variableMetadata = RandomGenerator::instance().randomChoice(metaDataPool);
31 auto variableMetadata = RandomGenerator::instance().randomChoice(metaDataPool);
31
32
32 // Retrieves provider
33 // Retrieves provider
33 auto variableProvider
34 auto variableProvider
34 = properties.value(PROVIDER_PROPERTY).value<std::shared_ptr<IDataProvider> >();
35 = properties.value(PROVIDER_PROPERTY).value<std::shared_ptr<IDataProvider> >();
35
36
36 auto variableName = QString{"Var_%1"}.arg(QUuid::createUuid().toString());
37 auto variableName = QString{"Var_%1"}.arg(QUuid::createUuid().toString());
37 qCInfo(LOG_FuzzingOperations()).noquote()
38 qCInfo(LOG_FuzzingOperations()).noquote()
38 << "Creating variable" << variableName << "(metadata:" << variableMetadata << ")...";
39 << "Creating variable" << variableName << "(metadata:" << variableMetadata << ")...";
39
40
40 auto newVariable
41 auto newVariable
41 = variableController.createVariable(variableName, variableMetadata, variableProvider);
42 = variableController.createVariable(variableName, variableMetadata, variableProvider);
42
43
43 // Updates variable's state
44 // Updates variable's state
45 auto &variableState = fuzzingState.variableState(variableId);
44 variableState.m_Range = properties.value(INITIAL_RANGE_PROPERTY).value<SqpRange>();
46 variableState.m_Range = properties.value(INITIAL_RANGE_PROPERTY).value<SqpRange>();
45 std::swap(variableState.m_Variable, newVariable);
47 std::swap(variableState.m_Variable, newVariable);
46 }
48 }
47 };
49 };
48
50
49 struct DeleteOperation : public IFuzzingOperation {
51 struct DeleteOperation : public IFuzzingOperation {
50 bool canExecute(const VariableState &variableState) const override
52 bool canExecute(VariableId variableId, const FuzzingState &fuzzingState) const override
51 {
53 {
52 // A variable can be delete only if it exists
54 // A variable can be delete only if it exists
53 return variableState.m_Variable != nullptr;
55 return fuzzingState.variableState(variableId).m_Variable != nullptr;
54 }
56 }
55
57
56 void execute(VariableState &variableState, VariableController &variableController,
58 void execute(VariableId variableId, FuzzingState &fuzzingState,
57 const Properties &properties) const override
59 VariableController &variableController, const Properties &) const override
58 {
60 {
59 Q_UNUSED(properties);
61 auto &variableState = fuzzingState.variableState(variableId);
60
62
61 qCInfo(LOG_FuzzingOperations()).noquote()
63 qCInfo(LOG_FuzzingOperations()).noquote()
62 << "Deleting variable" << variableState.m_Variable->name() << "...";
64 << "Deleting variable" << variableState.m_Variable->name() << "...";
63 variableController.deleteVariable(variableState.m_Variable);
65 variableController.deleteVariable(variableState.m_Variable);
64
66
65 // Updates variable's state
67 // Updates variable's state
66 variableState.m_Range = INVALID_RANGE;
68 variableState.m_Range = INVALID_RANGE;
67 variableState.m_Variable = nullptr;
69 variableState.m_Variable = nullptr;
68 }
70 }
69 };
71 };
70
72
71 /**
73 /**
72 * Defines a move operation through a range.
74 * Defines a move operation through a range.
73 *
75 *
74 * A move operation is determined by three functions:
76 * A move operation is determined by three functions:
75 * - Two 'move' functions, used to indicate in which direction the beginning and the end of a range
77 * - Two 'move' functions, used to indicate in which direction the beginning and the end of a range
76 * are going during the operation. These functions will be:
78 * are going during the operation. These functions will be:
77 * -- {<- / <-} for pan left
79 * -- {<- / <-} for pan left
78 * -- {-> / ->} for pan right
80 * -- {-> / ->} for pan right
79 * -- {-> / <-} for zoom in
81 * -- {-> / <-} for zoom in
80 * -- {<- / ->} for zoom out
82 * -- {<- / ->} for zoom out
81 * - One 'max move' functions, used to compute the max delta at which the operation can move a
83 * - One 'max move' functions, used to compute the max delta at which the operation can move a
82 * range, according to a max range. For exemple, for a range of {1, 5} and a max range of {0, 10},
84 * range, according to a max range. For exemple, for a range of {1, 5} and a max range of {0, 10},
83 * max deltas will be:
85 * max deltas will be:
84 * -- {0, 4} for pan left
86 * -- {0, 4} for pan left
85 * -- {6, 10} for pan right
87 * -- {6, 10} for pan right
86 * -- {3, 3} for zoom in
88 * -- {3, 3} for zoom in
87 * -- {0, 6} for zoom out (same spacing left and right)
89 * -- {0, 6} for zoom out (same spacing left and right)
88 */
90 */
89 struct MoveOperation : public IFuzzingOperation {
91 struct MoveOperation : public IFuzzingOperation {
90 using MoveFunction = std::function<double(double currentValue, double maxValue)>;
92 using MoveFunction = std::function<double(double currentValue, double maxValue)>;
91 using MaxMoveFunction = std::function<double(const SqpRange &range, const SqpRange &maxRange)>;
93 using MaxMoveFunction = std::function<double(const SqpRange &range, const SqpRange &maxRange)>;
92
94
93 explicit MoveOperation(MoveFunction rangeStartMoveFun, MoveFunction rangeEndMoveFun,
95 explicit MoveOperation(MoveFunction rangeStartMoveFun, MoveFunction rangeEndMoveFun,
94 MaxMoveFunction maxMoveFun,
96 MaxMoveFunction maxMoveFun,
95 const QString &label = QStringLiteral("Move operation"))
97 const QString &label = QStringLiteral("Move operation"))
96 : m_RangeStartMoveFun{std::move(rangeStartMoveFun)},
98 : m_RangeStartMoveFun{std::move(rangeStartMoveFun)},
97 m_RangeEndMoveFun{std::move(rangeEndMoveFun)},
99 m_RangeEndMoveFun{std::move(rangeEndMoveFun)},
98 m_MaxMoveFun{std::move(maxMoveFun)},
100 m_MaxMoveFun{std::move(maxMoveFun)},
99 m_Label{label}
101 m_Label{label}
100 {
102 {
101 }
103 }
102
104
103 bool canExecute(const VariableState &variableState) const override
105 bool canExecute(VariableId variableId, const FuzzingState &fuzzingState) const override
104 {
106 {
105 return variableState.m_Variable != nullptr;
107 return fuzzingState.variableState(variableId).m_Variable != nullptr;
106 }
108 }
107
109
108 void execute(VariableState &variableState, VariableController &variableController,
110 void execute(VariableId variableId, FuzzingState &fuzzingState,
111 VariableController &variableController,
109 const Properties &properties) const override
112 const Properties &properties) const override
110 {
113 {
114 auto &variableState = fuzzingState.variableState(variableId);
111 auto variable = variableState.m_Variable;
115 auto variable = variableState.m_Variable;
112
116
113 // Gets the max range defined
117 // Gets the max range defined
114 auto maxRange = properties.value(MAX_RANGE_PROPERTY, QVariant::fromValue(INVALID_RANGE))
118 auto maxRange = properties.value(MAX_RANGE_PROPERTY, QVariant::fromValue(INVALID_RANGE))
115 .value<SqpRange>();
119 .value<SqpRange>();
116 auto variableRange = variable->range();
120 auto variableRange = variable->range();
117
121
118 if (maxRange == INVALID_RANGE || variableRange.m_TStart < maxRange.m_TStart
122 if (maxRange == INVALID_RANGE || variableRange.m_TStart < maxRange.m_TStart
119 || variableRange.m_TEnd > maxRange.m_TEnd) {
123 || variableRange.m_TEnd > maxRange.m_TEnd) {
120 qCWarning(LOG_FuzzingOperations()) << "Can't execute operation: invalid max range";
124 qCWarning(LOG_FuzzingOperations()) << "Can't execute operation: invalid max range";
121 return;
125 return;
122 }
126 }
123
127
124 // Computes the max delta at which the variable can move, up to the limits of the max range
128 // Computes the max delta at which the variable can move, up to the limits of the max range
125 auto deltaMax = m_MaxMoveFun(variable->range(), maxRange);
129 auto deltaMax = m_MaxMoveFun(variable->range(), maxRange);
126
130
127 // Generates random delta that will be used to move variable
131 // Generates random delta that will be used to move variable
128 auto delta = RandomGenerator::instance().generateDouble(0, deltaMax);
132 auto delta = RandomGenerator::instance().generateDouble(0, deltaMax);
129
133
130 // Moves variable to its new range
134 // Moves variable to its new range
131 auto newVariableRange = SqpRange{m_RangeStartMoveFun(variableRange.m_TStart, delta),
135 auto newVariableRange = SqpRange{m_RangeStartMoveFun(variableRange.m_TStart, delta),
132 m_RangeEndMoveFun(variableRange.m_TEnd, delta)};
136 m_RangeEndMoveFun(variableRange.m_TEnd, delta)};
133 qCInfo(LOG_FuzzingOperations()).noquote()
137 qCInfo(LOG_FuzzingOperations()).noquote()
134 << "Performing" << m_Label << "on" << variable->name() << "(from" << variableRange
138 << "Performing" << m_Label << "on" << variable->name() << "(from" << variableRange
135 << "to" << newVariableRange << ")...";
139 << "to" << newVariableRange << ")...";
136 variableController.onRequestDataLoading({variable}, newVariableRange, false);
140 variableController.onRequestDataLoading({variable}, newVariableRange, false);
137
141
138 // Updates variable's state
142 // Updates variable's state
139 variableState.m_Range = newVariableRange;
143 variableState.m_Range = newVariableRange;
140 }
144 }
141
145
142 MoveFunction m_RangeStartMoveFun;
146 MoveFunction m_RangeStartMoveFun;
143 MoveFunction m_RangeEndMoveFun;
147 MoveFunction m_RangeEndMoveFun;
144 MaxMoveFunction m_MaxMoveFun;
148 MaxMoveFunction m_MaxMoveFun;
145 QString m_Label;
149 QString m_Label;
146 };
150 };
147
151
148 struct UnknownOperation : public IFuzzingOperation {
152 struct UnknownOperation : public IFuzzingOperation {
149 bool canExecute(const VariableState &variableState) const override
153 bool canExecute(VariableId, const FuzzingState &) const override { return false; }
150 {
151 Q_UNUSED(variableState);
152 return false;
153 }
154
154
155 void execute(VariableState &variableState, VariableController &variableController,
155 void execute(VariableId, FuzzingState &, VariableController &,
156 const Properties &properties) const override
156 const Properties &) const override
157 {
157 {
158 Q_UNUSED(variableState);
159 Q_UNUSED(variableController);
160 Q_UNUSED(properties);
161 // Does nothing
162 }
158 }
163 };
159 };
164
160
165 } // namespace
161 } // namespace
166
162
167 std::unique_ptr<IFuzzingOperation> FuzzingOperationFactory::create(FuzzingOperationType type)
163 std::unique_ptr<IFuzzingOperation> FuzzingOperationFactory::create(FuzzingOperationType type)
168 {
164 {
169 switch (type) {
165 switch (type) {
170 case FuzzingOperationType::CREATE:
166 case FuzzingOperationType::CREATE:
171 return std::make_unique<CreateOperation>();
167 return std::make_unique<CreateOperation>();
172 case FuzzingOperationType::DELETE:
168 case FuzzingOperationType::DELETE:
173 return std::make_unique<DeleteOperation>();
169 return std::make_unique<DeleteOperation>();
174 case FuzzingOperationType::PAN_LEFT:
170 case FuzzingOperationType::PAN_LEFT:
175 return std::make_unique<MoveOperation>(
171 return std::make_unique<MoveOperation>(
176 std::minus<double>(), std::minus<double>(),
172 std::minus<double>(), std::minus<double>(),
177 [](const SqpRange &range, const SqpRange &maxRange) {
173 [](const SqpRange &range, const SqpRange &maxRange) {
178 return range.m_TStart - maxRange.m_TStart;
174 return range.m_TStart - maxRange.m_TStart;
179 },
175 },
180 QStringLiteral("Pan left operation"));
176 QStringLiteral("Pan left operation"));
181 case FuzzingOperationType::PAN_RIGHT:
177 case FuzzingOperationType::PAN_RIGHT:
182 return std::make_unique<MoveOperation>(
178 return std::make_unique<MoveOperation>(
183 std::plus<double>(), std::plus<double>(),
179 std::plus<double>(), std::plus<double>(),
184 [](const SqpRange &range, const SqpRange &maxRange) {
180 [](const SqpRange &range, const SqpRange &maxRange) {
185 return maxRange.m_TEnd - range.m_TEnd;
181 return maxRange.m_TEnd - range.m_TEnd;
186 },
182 },
187 QStringLiteral("Pan right operation"));
183 QStringLiteral("Pan right operation"));
188 case FuzzingOperationType::ZOOM_IN:
184 case FuzzingOperationType::ZOOM_IN:
189 return std::make_unique<MoveOperation>(
185 return std::make_unique<MoveOperation>(
190 std::plus<double>(), std::minus<double>(),
186 std::plus<double>(), std::minus<double>(),
191 [](const SqpRange &range, const SqpRange &maxRange) {
187 [](const SqpRange &range, const SqpRange &maxRange) {
192 Q_UNUSED(maxRange)
188 Q_UNUSED(maxRange)
193 return range.m_TEnd - (range.m_TStart + range.m_TEnd) / 2.;
189 return range.m_TEnd - (range.m_TStart + range.m_TEnd) / 2.;
194 },
190 },
195 QStringLiteral("Zoom in operation"));
191 QStringLiteral("Zoom in operation"));
196 case FuzzingOperationType::ZOOM_OUT:
192 case FuzzingOperationType::ZOOM_OUT:
197 return std::make_unique<MoveOperation>(
193 return std::make_unique<MoveOperation>(
198 std::minus<double>(), std::plus<double>(),
194 std::minus<double>(), std::plus<double>(),
199 [](const SqpRange &range, const SqpRange &maxRange) {
195 [](const SqpRange &range, const SqpRange &maxRange) {
200 return std::min(range.m_TStart - maxRange.m_TStart,
196 return std::min(range.m_TStart - maxRange.m_TStart,
201 maxRange.m_TEnd - range.m_TEnd);
197 maxRange.m_TEnd - range.m_TEnd);
202 },
198 },
203 QStringLiteral("Zoom out operation"));
199 QStringLiteral("Zoom out operation"));
204 default:
200 default:
205 // Default case returns unknown operation
201 // Default case returns unknown operation
206 break;
202 break;
207 }
203 }
208
204
209 return std::make_unique<UnknownOperation>();
205 return std::make_unique<UnknownOperation>();
210 }
206 }
@@ -1,48 +1,50
1 #ifndef SCIQLOP_FUZZINGOPERATIONS_H
1 #ifndef SCIQLOP_FUZZINGOPERATIONS_H
2 #define SCIQLOP_FUZZINGOPERATIONS_H
2 #define SCIQLOP_FUZZINGOPERATIONS_H
3
3
4 #include "FuzzingDefs.h"
4 #include "FuzzingDefs.h"
5
5
6 #include <memory>
6 #include <memory>
7 #include <set>
7 #include <set>
8
8
9 #include <QLoggingCategory>
9 #include <QLoggingCategory>
10 #include <QMetaType>
10 #include <QMetaType>
11
11
12 Q_DECLARE_LOGGING_CATEGORY(LOG_FuzzingOperations)
12 Q_DECLARE_LOGGING_CATEGORY(LOG_FuzzingOperations)
13
13
14 class VariableController;
14 class VariableController;
15
15
16 /**
16 /**
17 * Enumeration of types of existing fuzzing operations
17 * Enumeration of types of existing fuzzing operations
18 */
18 */
19 enum class FuzzingOperationType { CREATE, DELETE, PAN_LEFT, PAN_RIGHT, ZOOM_IN, ZOOM_OUT };
19 enum class FuzzingOperationType { CREATE, DELETE, PAN_LEFT, PAN_RIGHT, ZOOM_IN, ZOOM_OUT };
20
20
21 /// Interface that represents an operation that can be executed during a fuzzing test
21 /// Interface that represents an operation that can be executed during a fuzzing test
22 struct IFuzzingOperation {
22 struct IFuzzingOperation {
23 virtual ~IFuzzingOperation() noexcept = default;
23 virtual ~IFuzzingOperation() noexcept = default;
24
24
25 /// Checks if the operation can be executed according to the current variable state passed in
25 /// Checks if the operation can be executed according to the current test's state for the
26 /// parameter
26 /// variable passed in parameter
27 virtual bool canExecute(const VariableState &variableState) const = 0;
27 virtual bool canExecute(VariableId variableId, const FuzzingState &fuzzingState) const = 0;
28 /// Executes the operation on the variable state passed in parameter
28 /// Executes the operation on the variable for which its identifier is passed in parameter
29 /// @param variableState the variable state on which to execute the operation
29 /// @param variableId the variable identifier
30 /// @param fuzzingState the current test's state on which to find the variable and execute the
31 /// operation
30 /// @param variableController the controller associated to the operation
32 /// @param variableController the controller associated to the operation
31 /// @param properties properties that can be used to configure the operation
33 /// @param properties properties that can be used to configure the operation
32 /// @remarks variableState is passed as a reference because, according to the operation, it can
34 /// @remarks fuzzingState is passed as a reference because, according to the operation, it can
33 /// be
35 /// be modified (in/out parameter)
34 /// modified (in/out parameter)
36 virtual void execute(VariableId variableId, FuzzingState &fuzzingState,
35 virtual void execute(VariableState &variableState, VariableController &variableController,
37 VariableController &variableController,
36 const Properties &properties = {}) const = 0;
38 const Properties &properties = {}) const = 0;
37 };
39 };
38
40
39 /// Factory of @sa IFuzzingOperation
41 /// Factory of @sa IFuzzingOperation
40 struct FuzzingOperationFactory {
42 struct FuzzingOperationFactory {
41 /// Creates a fuzzing operation from a type
43 /// Creates a fuzzing operation from a type
42 static std::unique_ptr<IFuzzingOperation> create(FuzzingOperationType type);
44 static std::unique_ptr<IFuzzingOperation> create(FuzzingOperationType type);
43 };
45 };
44
46
45 using WeightedOperationsTypes = std::map<FuzzingOperationType, double>;
47 using WeightedOperationsTypes = std::map<FuzzingOperationType, double>;
46 Q_DECLARE_METATYPE(WeightedOperationsTypes)
48 Q_DECLARE_METATYPE(WeightedOperationsTypes)
47
49
48 #endif // SCIQLOP_FUZZINGOPERATIONS_H
50 #endif // SCIQLOP_FUZZINGOPERATIONS_H
@@ -1,332 +1,328
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 <Network/NetworkController.h>
8 #include <Network/NetworkController.h>
9 #include <Settings/SqpSettingsDefs.h>
9 #include <Settings/SqpSettingsDefs.h>
10 #include <SqpApplication.h>
10 #include <SqpApplication.h>
11 #include <Time/TimeController.h>
11 #include <Time/TimeController.h>
12 #include <Variable/Variable.h>
12 #include <Variable/Variable.h>
13 #include <Variable/VariableController.h>
13 #include <Variable/VariableController.h>
14
14
15 #include <QLoggingCategory>
15 #include <QLoggingCategory>
16 #include <QObject>
16 #include <QObject>
17 #include <QtTest>
17 #include <QtTest>
18
18
19 #include <memory>
19 #include <memory>
20
20
21 Q_LOGGING_CATEGORY(LOG_TestAmdaFuzzing, "TestAmdaFuzzing")
21 Q_LOGGING_CATEGORY(LOG_TestAmdaFuzzing, "TestAmdaFuzzing")
22
22
23 namespace {
23 namespace {
24
24
25 // /////// //
25 // /////// //
26 // Aliases //
26 // Aliases //
27 // /////// //
27 // /////// //
28
28
29 using VariableId = int;
30 using Weight = double;
29 using Weight = double;
31 using Weights = std::vector<Weight>;
30 using Weights = std::vector<Weight>;
32
31
33 using VariableOperation = std::pair<VariableId, std::shared_ptr<IFuzzingOperation> >;
32 using VariableOperation = std::pair<VariableId, std::shared_ptr<IFuzzingOperation> >;
34 using VariablesOperations = std::vector<VariableOperation>;
33 using VariablesOperations = std::vector<VariableOperation>;
35
34
36 using WeightedOperationsPool = std::map<std::shared_ptr<IFuzzingOperation>, Weight>;
35 using WeightedOperationsPool = std::map<std::shared_ptr<IFuzzingOperation>, Weight>;
37 using VariablesPool = std::map<VariableId, VariableState>;
38 using Validators = std::vector<std::shared_ptr<IFuzzingValidator> >;
36 using Validators = std::vector<std::shared_ptr<IFuzzingValidator> >;
39
37
40 // ///////// //
38 // ///////// //
41 // Constants //
39 // Constants //
42 // ///////// //
40 // ///////// //
43
41
44 // Defaults values used when the associated properties have not been set for the test
42 // Defaults values used when the associated properties have not been set for the test
45 const auto NB_MAX_OPERATIONS_DEFAULT_VALUE = 100;
43 const auto NB_MAX_OPERATIONS_DEFAULT_VALUE = 100;
46 const auto NB_MAX_VARIABLES_DEFAULT_VALUE = 1;
44 const auto NB_MAX_VARIABLES_DEFAULT_VALUE = 1;
47 const auto AVAILABLE_OPERATIONS_DEFAULT_VALUE = QVariant::fromValue(WeightedOperationsTypes{
45 const auto AVAILABLE_OPERATIONS_DEFAULT_VALUE = QVariant::fromValue(WeightedOperationsTypes{
48 {FuzzingOperationType::CREATE, 1.},
46 {FuzzingOperationType::CREATE, 1.},
49 {FuzzingOperationType::DELETE, 0.1}, // Delete operation is less frequent
47 {FuzzingOperationType::DELETE, 0.1}, // Delete operation is less frequent
50 {FuzzingOperationType::PAN_LEFT, 1.},
48 {FuzzingOperationType::PAN_LEFT, 1.},
51 {FuzzingOperationType::PAN_RIGHT, 1.},
49 {FuzzingOperationType::PAN_RIGHT, 1.},
52 {FuzzingOperationType::ZOOM_IN, 1.},
50 {FuzzingOperationType::ZOOM_IN, 1.},
53 {FuzzingOperationType::ZOOM_OUT, 1.}});
51 {FuzzingOperationType::ZOOM_OUT, 1.}});
54 const auto CACHE_TOLERANCE_DEFAULT_VALUE = 0.2;
52 const auto CACHE_TOLERANCE_DEFAULT_VALUE = 0.2;
55
53
56 /// Delay between each operation (in ms)
54 /// Delay between each operation (in ms)
57 const auto OPERATION_DELAY_DEFAULT_VALUE = 3000;
55 const auto OPERATION_DELAY_DEFAULT_VALUE = 3000;
58
56
59 /// Validators for the tests (executed in the order in which they're defined)
57 /// Validators for the tests (executed in the order in which they're defined)
60 const auto VALIDATORS_DEFAULT_VALUE = QVariant::fromValue(
58 const auto VALIDATORS_DEFAULT_VALUE = QVariant::fromValue(
61 ValidatorsTypes{{FuzzingValidatorType::RANGE, FuzzingValidatorType::DATA}});
59 ValidatorsTypes{{FuzzingValidatorType::RANGE, FuzzingValidatorType::DATA}});
62
60
63 // /////// //
61 // /////// //
64 // Methods //
62 // Methods //
65 // /////// //
63 // /////// //
66
64
67 /// Goes through the variables pool and operations pool to determine the set of {variable/operation}
65 /// Goes through the variables pool and operations pool to determine the set of {variable/operation}
68 /// pairs that are valid (i.e. operation that can be executed on variable)
66 /// pairs that are valid (i.e. operation that can be executed on variable)
69 std::pair<VariablesOperations, Weights>
67 std::pair<VariablesOperations, Weights>
70 availableOperations(const VariablesPool &variablesPool,
68 availableOperations(const FuzzingState &fuzzingState, const WeightedOperationsPool &operationsPool)
71 const WeightedOperationsPool &operationsPool)
72 {
69 {
73 VariablesOperations result{};
70 VariablesOperations result{};
74 Weights weights{};
71 Weights weights{};
75
72
76 for (const auto &variablesPoolEntry : variablesPool) {
73 for (const auto &variablesPoolEntry : fuzzingState.m_VariablesPool) {
77 auto variableId = variablesPoolEntry.first;
74 auto variableId = variablesPoolEntry.first;
78 const auto &variableState = variablesPoolEntry.second;
79
75
80 for (const auto &operationsPoolEntry : operationsPool) {
76 for (const auto &operationsPoolEntry : operationsPool) {
81 auto operation = operationsPoolEntry.first;
77 auto operation = operationsPoolEntry.first;
82 auto weight = operationsPoolEntry.second;
78 auto weight = operationsPoolEntry.second;
83
79
84 // A pair is valid if the current operation can be executed on the current variable
80 // A pair is valid if the current operation can be executed on the current variable
85 if (operation->canExecute(variableState)) {
81 if (operation->canExecute(variableId, fuzzingState)) {
86 result.push_back({variableId, operation});
82 result.push_back({variableId, operation});
87 weights.push_back(weight);
83 weights.push_back(weight);
88 }
84 }
89 }
85 }
90 }
86 }
91
87
92 return {result, weights};
88 return {result, weights};
93 }
89 }
94
90
95 WeightedOperationsPool createOperationsPool(const WeightedOperationsTypes &types)
91 WeightedOperationsPool createOperationsPool(const WeightedOperationsTypes &types)
96 {
92 {
97 WeightedOperationsPool result{};
93 WeightedOperationsPool result{};
98
94
99 std::transform(
95 std::transform(
100 types.cbegin(), types.cend(), std::inserter(result, result.end()), [](const auto &type) {
96 types.cbegin(), types.cend(), std::inserter(result, result.end()), [](const auto &type) {
101 return std::make_pair(FuzzingOperationFactory::create(type.first), type.second);
97 return std::make_pair(FuzzingOperationFactory::create(type.first), type.second);
102 });
98 });
103
99
104 return result;
100 return result;
105 }
101 }
106
102
107 Validators createValidators(const ValidatorsTypes &types)
103 Validators createValidators(const ValidatorsTypes &types)
108 {
104 {
109 Validators result{};
105 Validators result{};
110
106
111 std::transform(types.cbegin(), types.cend(), std::inserter(result, result.end()),
107 std::transform(types.cbegin(), types.cend(), std::inserter(result, result.end()),
112 [](const auto &type) { return FuzzingValidatorFactory::create(type); });
108 [](const auto &type) { return FuzzingValidatorFactory::create(type); });
113
109
114 return result;
110 return result;
115 }
111 }
116
112
117 /**
113 /**
118 * Validates all the variables' states passed in parameter, according to a set of validators
114 * Validates all the variables' states passed in parameter, according to a set of validators
119 * @param variablesPool the variables' states
115 * @param variablesPool the variables' states
120 * @param validators the validators used for validation
116 * @param validators the validators used for validation
121 */
117 */
122 void validate(const VariablesPool &variablesPool, const Validators &validators)
118 void validate(const VariablesPool &variablesPool, const Validators &validators)
123 {
119 {
124 for (const auto &variablesPoolEntry : variablesPool) {
120 for (const auto &variablesPoolEntry : variablesPool) {
125 auto variableId = variablesPoolEntry.first;
121 auto variableId = variablesPoolEntry.first;
126 const auto &variableState = variablesPoolEntry.second;
122 const auto &variableState = variablesPoolEntry.second;
127
123
128 auto variableMessage = variableState.m_Variable ? variableState.m_Variable->name()
124 auto variableMessage = variableState.m_Variable ? variableState.m_Variable->name()
129 : QStringLiteral("null variable");
125 : QStringLiteral("null variable");
130 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Validating state of variable at index"
126 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Validating state of variable at index"
131 << variableId << "(" << variableMessage << ")...";
127 << variableId << "(" << variableMessage << ")...";
132
128
133 for (const auto &validator : validators) {
129 for (const auto &validator : validators) {
134 validator->validate(VariableState{variableState});
130 validator->validate(VariableState{variableState});
135 }
131 }
136
132
137 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Validation completed.";
133 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Validation completed.";
138 }
134 }
139 }
135 }
140
136
141 /**
137 /**
142 * Class to run random tests
138 * Class to run random tests
143 */
139 */
144 class FuzzingTest {
140 class FuzzingTest {
145 public:
141 public:
146 explicit FuzzingTest(VariableController &variableController, Properties properties)
142 explicit FuzzingTest(VariableController &variableController, Properties properties)
147 : m_VariableController{variableController},
143 : m_VariableController{variableController},
148 m_Properties{std::move(properties)},
144 m_Properties{std::move(properties)},
149 m_VariablesPool{}
145 m_FuzzingState{}
150 {
146 {
151 // Inits variables pool: at init, all variables are null
147 // Inits variables pool: at init, all variables are null
152 for (auto variableId = 0; variableId < nbMaxVariables(); ++variableId) {
148 for (auto variableId = 0; variableId < nbMaxVariables(); ++variableId) {
153 m_VariablesPool[variableId] = VariableState{};
149 m_FuzzingState.m_VariablesPool[variableId] = VariableState{};
154 }
150 }
155 }
151 }
156
152
157 void execute()
153 void execute()
158 {
154 {
159 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Running" << nbMaxOperations() << "operations on"
155 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Running" << nbMaxOperations() << "operations on"
160 << nbMaxVariables() << "variable(s)...";
156 << nbMaxVariables() << "variable(s)...";
161
157
162 auto canExecute = true;
158 auto canExecute = true;
163 for (auto i = 0; i < nbMaxOperations() && canExecute; ++i) {
159 for (auto i = 0; i < nbMaxOperations() && canExecute; ++i) {
164 // Retrieves all operations that can be executed in the current context
160 // Retrieves all operations that can be executed in the current context
165 VariablesOperations variableOperations{};
161 VariablesOperations variableOperations{};
166 Weights weights{};
162 Weights weights{};
167 std::tie(variableOperations, weights)
163 std::tie(variableOperations, weights)
168 = availableOperations(m_VariablesPool, operationsPool());
164 = availableOperations(m_FuzzingState, operationsPool());
169
165
170 canExecute = !variableOperations.empty();
166 canExecute = !variableOperations.empty();
171 if (canExecute) {
167 if (canExecute) {
172 // Of the operations available, chooses a random operation and executes it
168 // Of the operations available, chooses a random operation and executes it
173 auto variableOperation
169 auto variableOperation
174 = RandomGenerator::instance().randomChoice(variableOperations, weights);
170 = RandomGenerator::instance().randomChoice(variableOperations, weights);
175
171
176 auto variableId = variableOperation.first;
172 auto variableId = variableOperation.first;
177 auto &variableState = m_VariablesPool.at(variableId);
178 auto fuzzingOperation = variableOperation.second;
173 auto fuzzingOperation = variableOperation.second;
179
174
180 fuzzingOperation->execute(variableState, m_VariableController, m_Properties);
175 fuzzingOperation->execute(variableId, m_FuzzingState, m_VariableController,
176 m_Properties);
181 QTest::qWait(operationDelay());
177 QTest::qWait(operationDelay());
182
178
183 // Validates variables
179 // Validates variables
184 validate(m_VariablesPool, validators());
180 validate(m_FuzzingState.m_VariablesPool, validators());
185 }
181 }
186 else {
182 else {
187 qCInfo(LOG_TestAmdaFuzzing()).noquote()
183 qCInfo(LOG_TestAmdaFuzzing()).noquote()
188 << "No more operations are available, the execution of the test will stop...";
184 << "No more operations are available, the execution of the test will stop...";
189 }
185 }
190 }
186 }
191
187
192 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Execution of the test completed.";
188 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Execution of the test completed.";
193 }
189 }
194
190
195 private:
191 private:
196 int nbMaxOperations() const
192 int nbMaxOperations() const
197 {
193 {
198 static auto result
194 static auto result
199 = m_Properties.value(NB_MAX_OPERATIONS_PROPERTY, NB_MAX_OPERATIONS_DEFAULT_VALUE)
195 = m_Properties.value(NB_MAX_OPERATIONS_PROPERTY, NB_MAX_OPERATIONS_DEFAULT_VALUE)
200 .toInt();
196 .toInt();
201 return result;
197 return result;
202 }
198 }
203
199
204 int nbMaxVariables() const
200 int nbMaxVariables() const
205 {
201 {
206 static auto result
202 static auto result
207 = m_Properties.value(NB_MAX_VARIABLES_PROPERTY, NB_MAX_VARIABLES_DEFAULT_VALUE).toInt();
203 = m_Properties.value(NB_MAX_VARIABLES_PROPERTY, NB_MAX_VARIABLES_DEFAULT_VALUE).toInt();
208 return result;
204 return result;
209 }
205 }
210
206
211 int operationDelay() const
207 int operationDelay() const
212 {
208 {
213 static auto result
209 static auto result
214 = m_Properties.value(OPERATION_DELAY_PROPERTY, OPERATION_DELAY_DEFAULT_VALUE).toInt();
210 = m_Properties.value(OPERATION_DELAY_PROPERTY, OPERATION_DELAY_DEFAULT_VALUE).toInt();
215 return result;
211 return result;
216 }
212 }
217
213
218 WeightedOperationsPool operationsPool() const
214 WeightedOperationsPool operationsPool() const
219 {
215 {
220 static auto result = createOperationsPool(
216 static auto result = createOperationsPool(
221 m_Properties.value(AVAILABLE_OPERATIONS_PROPERTY, AVAILABLE_OPERATIONS_DEFAULT_VALUE)
217 m_Properties.value(AVAILABLE_OPERATIONS_PROPERTY, AVAILABLE_OPERATIONS_DEFAULT_VALUE)
222 .value<WeightedOperationsTypes>());
218 .value<WeightedOperationsTypes>());
223 return result;
219 return result;
224 }
220 }
225
221
226 Validators validators() const
222 Validators validators() const
227 {
223 {
228 static auto result
224 static auto result
229 = createValidators(m_Properties.value(VALIDATORS_PROPERTY, VALIDATORS_DEFAULT_VALUE)
225 = createValidators(m_Properties.value(VALIDATORS_PROPERTY, VALIDATORS_DEFAULT_VALUE)
230 .value<ValidatorsTypes>());
226 .value<ValidatorsTypes>());
231 return result;
227 return result;
232 }
228 }
233
229
234 VariableController &m_VariableController;
230 VariableController &m_VariableController;
235 Properties m_Properties;
231 Properties m_Properties;
236 VariablesPool m_VariablesPool;
232 FuzzingState m_FuzzingState;
237 };
233 };
238
234
239 } // namespace
235 } // namespace
240
236
241 class TestAmdaFuzzing : public QObject {
237 class TestAmdaFuzzing : public QObject {
242 Q_OBJECT
238 Q_OBJECT
243
239
244 private slots:
240 private slots:
245 /// Input data for @sa testFuzzing()
241 /// Input data for @sa testFuzzing()
246 void testFuzzing_data();
242 void testFuzzing_data();
247 void testFuzzing();
243 void testFuzzing();
248 };
244 };
249
245
250 void TestAmdaFuzzing::testFuzzing_data()
246 void TestAmdaFuzzing::testFuzzing_data()
251 {
247 {
252 // ////////////// //
248 // ////////////// //
253 // Test structure //
249 // Test structure //
254 // ////////////// //
250 // ////////////// //
255
251
256 QTest::addColumn<Properties>("properties"); // Properties for random test
252 QTest::addColumn<Properties>("properties"); // Properties for random test
257
253
258 // ////////// //
254 // ////////// //
259 // Test cases //
255 // Test cases //
260 // ////////// //
256 // ////////// //
261
257
262 auto maxRange = SqpRange::fromDateTime({2017, 1, 1}, {0, 0}, {2017, 1, 5}, {0, 0});
258 auto maxRange = SqpRange::fromDateTime({2017, 1, 1}, {0, 0}, {2017, 1, 5}, {0, 0});
263 MetadataPool metadataPool{{{"dataType", "vector"}, {"xml:id", "imf"}}};
259 MetadataPool metadataPool{{{"dataType", "vector"}, {"xml:id", "imf"}}};
264
260
265 // Note: we don't use auto here as we want to pass std::shared_ptr<IDataProvider> as is in the
261 // Note: we don't use auto here as we want to pass std::shared_ptr<IDataProvider> as is in the
266 // QVariant
262 // QVariant
267 std::shared_ptr<IDataProvider> provider = std::make_shared<AmdaProvider>();
263 std::shared_ptr<IDataProvider> provider = std::make_shared<AmdaProvider>();
268
264
269 QTest::newRow("fuzzingTest") << Properties{
265 QTest::newRow("fuzzingTest") << Properties{
270 {MAX_RANGE_PROPERTY, QVariant::fromValue(maxRange)},
266 {MAX_RANGE_PROPERTY, QVariant::fromValue(maxRange)},
271 {METADATA_POOL_PROPERTY, QVariant::fromValue(metadataPool)},
267 {METADATA_POOL_PROPERTY, QVariant::fromValue(metadataPool)},
272 {PROVIDER_PROPERTY, QVariant::fromValue(provider)}};
268 {PROVIDER_PROPERTY, QVariant::fromValue(provider)}};
273 }
269 }
274
270
275 void TestAmdaFuzzing::testFuzzing()
271 void TestAmdaFuzzing::testFuzzing()
276 {
272 {
277 QFETCH(Properties, properties);
273 QFETCH(Properties, properties);
278
274
279 // Sets cache property
275 // Sets cache property
280 QSettings settings{};
276 QSettings settings{};
281 auto cacheTolerance = properties.value(CACHE_TOLERANCE_PROPERTY, CACHE_TOLERANCE_DEFAULT_VALUE);
277 auto cacheTolerance = properties.value(CACHE_TOLERANCE_PROPERTY, CACHE_TOLERANCE_DEFAULT_VALUE);
282 settings.setValue(GENERAL_TOLERANCE_AT_INIT_KEY, cacheTolerance);
278 settings.setValue(GENERAL_TOLERANCE_AT_INIT_KEY, cacheTolerance);
283 settings.setValue(GENERAL_TOLERANCE_AT_UPDATE_KEY, cacheTolerance);
279 settings.setValue(GENERAL_TOLERANCE_AT_UPDATE_KEY, cacheTolerance);
284
280
285 auto &variableController = sqpApp->variableController();
281 auto &variableController = sqpApp->variableController();
286 auto &timeController = sqpApp->timeController();
282 auto &timeController = sqpApp->timeController();
287
283
288 // Generates random initial range (bounded to max range)
284 // Generates random initial range (bounded to max range)
289 auto maxRange = properties.value(MAX_RANGE_PROPERTY, QVariant::fromValue(INVALID_RANGE))
285 auto maxRange = properties.value(MAX_RANGE_PROPERTY, QVariant::fromValue(INVALID_RANGE))
290 .value<SqpRange>();
286 .value<SqpRange>();
291
287
292 QVERIFY(maxRange != INVALID_RANGE);
288 QVERIFY(maxRange != INVALID_RANGE);
293
289
294 auto initialRangeStart
290 auto initialRangeStart
295 = RandomGenerator::instance().generateDouble(maxRange.m_TStart, maxRange.m_TEnd);
291 = RandomGenerator::instance().generateDouble(maxRange.m_TStart, maxRange.m_TEnd);
296 auto initialRangeEnd
292 auto initialRangeEnd
297 = RandomGenerator::instance().generateDouble(maxRange.m_TStart, maxRange.m_TEnd);
293 = RandomGenerator::instance().generateDouble(maxRange.m_TStart, maxRange.m_TEnd);
298 if (initialRangeStart > initialRangeEnd) {
294 if (initialRangeStart > initialRangeEnd) {
299 std::swap(initialRangeStart, initialRangeEnd);
295 std::swap(initialRangeStart, initialRangeEnd);
300 }
296 }
301
297
302 // Sets initial range on time controller
298 // Sets initial range on time controller
303 SqpRange initialRange{initialRangeStart, initialRangeEnd};
299 SqpRange initialRange{initialRangeStart, initialRangeEnd};
304 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Setting initial range to" << initialRange << "...";
300 qCInfo(LOG_TestAmdaFuzzing()).noquote() << "Setting initial range to" << initialRange << "...";
305 timeController.onTimeToUpdate(initialRange);
301 timeController.onTimeToUpdate(initialRange);
306 properties.insert(INITIAL_RANGE_PROPERTY, QVariant::fromValue(initialRange));
302 properties.insert(INITIAL_RANGE_PROPERTY, QVariant::fromValue(initialRange));
307
303
308 FuzzingTest test{variableController, properties};
304 FuzzingTest test{variableController, properties};
309 test.execute();
305 test.execute();
310 }
306 }
311
307
312 int main(int argc, char *argv[])
308 int main(int argc, char *argv[])
313 {
309 {
314 QLoggingCategory::setFilterRules(
310 QLoggingCategory::setFilterRules(
315 "*.warning=false\n"
311 "*.warning=false\n"
316 "*.info=false\n"
312 "*.info=false\n"
317 "*.debug=false\n"
313 "*.debug=false\n"
318 "FuzzingOperations.info=true\n"
314 "FuzzingOperations.info=true\n"
319 "FuzzingValidators.info=true\n"
315 "FuzzingValidators.info=true\n"
320 "TestAmdaFuzzing.info=true\n");
316 "TestAmdaFuzzing.info=true\n");
321
317
322 SqpApplication app{argc, argv};
318 SqpApplication app{argc, argv};
323 SqpApplication::setOrganizationName("LPP");
319 SqpApplication::setOrganizationName("LPP");
324 SqpApplication::setOrganizationDomain("lpp.fr");
320 SqpApplication::setOrganizationDomain("lpp.fr");
325 SqpApplication::setApplicationName("SciQLop-TestFuzzing");
321 SqpApplication::setApplicationName("SciQLop-TestFuzzing");
326 app.setAttribute(Qt::AA_Use96Dpi, true);
322 app.setAttribute(Qt::AA_Use96Dpi, true);
327 TestAmdaFuzzing testObject{};
323 TestAmdaFuzzing testObject{};
328 QTEST_SET_MAIN_SOURCE_PATH
324 QTEST_SET_MAIN_SOURCE_PATH
329 return QTest::qExec(&testObject, argc, argv);
325 return QTest::qExec(&testObject, argc, argv);
330 }
326 }
331
327
332 #include "TestAmdaFuzzing.moc"
328 #include "TestAmdaFuzzing.moc"
General Comments 0
You need to be logged in to leave comments. Login now