##// END OF EJS Templates
Minor fix
Alexandre Leroux -
r1252:072fa3ead1eb
parent child
Show More
@@ -1,265 +1,265
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(VariableId variableId, const FuzzingState &fuzzingState) 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 fuzzingState.variableState(variableId).m_Variable == nullptr;
21 return fuzzingState.variableState(variableId).m_Variable == nullptr;
22 }
22 }
23
23
24 void execute(VariableId variableId, FuzzingState &fuzzingState,
24 void execute(VariableId variableId, FuzzingState &fuzzingState,
25 VariableController &variableController,
25 VariableController &variableController,
26 const Properties &properties) const override
26 const Properties &properties) const override
27 {
27 {
28 // 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
29 // associate it with the variable
29 // associate it with the variable
30 auto metaDataPool = properties.value(METADATA_POOL_PROPERTY).value<MetadataPool>();
30 auto metaDataPool = properties.value(METADATA_POOL_PROPERTY).value<MetadataPool>();
31 auto variableMetadata = RandomGenerator::instance().randomChoice(metaDataPool);
31 auto variableMetadata = RandomGenerator::instance().randomChoice(metaDataPool);
32
32
33 // Retrieves provider
33 // Retrieves provider
34 auto variableProvider
34 auto variableProvider
35 = properties.value(PROVIDER_PROPERTY).value<std::shared_ptr<IDataProvider> >();
35 = properties.value(PROVIDER_PROPERTY).value<std::shared_ptr<IDataProvider> >();
36
36
37 auto variableName = QString{"Var_%1"}.arg(QUuid::createUuid().toString());
37 auto variableName = QString{"Var_%1"}.arg(QUuid::createUuid().toString());
38 qCInfo(LOG_FuzzingOperations()).noquote()
38 qCInfo(LOG_FuzzingOperations()).noquote()
39 << "Creating variable" << variableName << "(metadata:" << variableMetadata << ")...";
39 << "Creating variable" << variableName << "(metadata:" << variableMetadata << ")...";
40
40
41 auto newVariable
41 auto newVariable
42 = variableController.createVariable(variableName, variableMetadata, variableProvider);
42 = variableController.createVariable(variableName, variableMetadata, variableProvider);
43
43
44 // Updates variable's state
44 // Updates variable's state
45 auto &variableState = fuzzingState.variableState(variableId);
45 auto &variableState = fuzzingState.variableState(variableId);
46 variableState.m_Range = properties.value(INITIAL_RANGE_PROPERTY).value<SqpRange>();
46 variableState.m_Range = properties.value(INITIAL_RANGE_PROPERTY).value<SqpRange>();
47 std::swap(variableState.m_Variable, newVariable);
47 std::swap(variableState.m_Variable, newVariable);
48 }
48 }
49 };
49 };
50
50
51 struct DeleteOperation : public IFuzzingOperation {
51 struct DeleteOperation : public IFuzzingOperation {
52 bool canExecute(VariableId variableId, const FuzzingState &fuzzingState) const override
52 bool canExecute(VariableId variableId, const FuzzingState &fuzzingState) const override
53 {
53 {
54 // A variable can be delete only if it exists
54 // A variable can be delete only if it exists
55 return fuzzingState.variableState(variableId).m_Variable != nullptr;
55 return fuzzingState.variableState(variableId).m_Variable != nullptr;
56 }
56 }
57
57
58 void execute(VariableId variableId, FuzzingState &fuzzingState,
58 void execute(VariableId variableId, FuzzingState &fuzzingState,
59 VariableController &variableController, const Properties &) const override
59 VariableController &variableController, const Properties &) const override
60 {
60 {
61 auto &variableState = fuzzingState.variableState(variableId);
61 auto &variableState = fuzzingState.variableState(variableId);
62
62
63 qCInfo(LOG_FuzzingOperations()).noquote()
63 qCInfo(LOG_FuzzingOperations()).noquote()
64 << "Deleting variable" << variableState.m_Variable->name() << "...";
64 << "Deleting variable" << variableState.m_Variable->name() << "...";
65 variableController.deleteVariable(variableState.m_Variable);
65 variableController.deleteVariable(variableState.m_Variable);
66
66
67 // Updates variable's state
67 // Updates variable's state
68 variableState.m_Range = INVALID_RANGE;
68 variableState.m_Range = INVALID_RANGE;
69 variableState.m_Variable = nullptr;
69 variableState.m_Variable = nullptr;
70
70
71 // Desynchronizes the variable if it was in a sync group
71 // Desynchronizes the variable if it was in a sync group
72 auto syncGroupId = fuzzingState.syncGroupId(variableId);
72 auto syncGroupId = fuzzingState.syncGroupId(variableId);
73 fuzzingState.desynchronizeVariable(variableId, syncGroupId);
73 fuzzingState.desynchronizeVariable(variableId, syncGroupId);
74 }
74 }
75 };
75 };
76
76
77 /**
77 /**
78 * Defines a move operation through a range.
78 * Defines a move operation through a range.
79 *
79 *
80 * A move operation is determined by three functions:
80 * A move operation is determined by three functions:
81 * - Two 'move' functions, used to indicate in which direction the beginning and the end of a range
81 * - Two 'move' functions, used to indicate in which direction the beginning and the end of a range
82 * are going during the operation. These functions will be:
82 * are going during the operation. These functions will be:
83 * -- {<- / <-} for pan left
83 * -- {<- / <-} for pan left
84 * -- {-> / ->} for pan right
84 * -- {-> / ->} for pan right
85 * -- {-> / <-} for zoom in
85 * -- {-> / <-} for zoom in
86 * -- {<- / ->} for zoom out
86 * -- {<- / ->} for zoom out
87 * - One 'max move' functions, used to compute the max delta at which the operation can move a
87 * - One 'max move' functions, used to compute the max delta at which the operation can move a
88 * range, according to a max range. For exemple, for a range of {1, 5} and a max range of {0, 10},
88 * range, according to a max range. For exemple, for a range of {1, 5} and a max range of {0, 10},
89 * max deltas will be:
89 * max deltas will be:
90 * -- {0, 4} for pan left
90 * -- {0, 4} for pan left
91 * -- {6, 10} for pan right
91 * -- {6, 10} for pan right
92 * -- {3, 3} for zoom in
92 * -- {3, 3} for zoom in
93 * -- {0, 6} for zoom out (same spacing left and right)
93 * -- {0, 6} for zoom out (same spacing left and right)
94 */
94 */
95 struct MoveOperation : public IFuzzingOperation {
95 struct MoveOperation : public IFuzzingOperation {
96 using MoveFunction = std::function<double(double currentValue, double maxValue)>;
96 using MoveFunction = std::function<double(double currentValue, double maxValue)>;
97 using MaxMoveFunction = std::function<double(const SqpRange &range, const SqpRange &maxRange)>;
97 using MaxMoveFunction = std::function<double(const SqpRange &range, const SqpRange &maxRange)>;
98
98
99 explicit MoveOperation(MoveFunction rangeStartMoveFun, MoveFunction rangeEndMoveFun,
99 explicit MoveOperation(MoveFunction rangeStartMoveFun, MoveFunction rangeEndMoveFun,
100 MaxMoveFunction maxMoveFun,
100 MaxMoveFunction maxMoveFun,
101 const QString &label = QStringLiteral("Move operation"))
101 const QString &label = QStringLiteral("Move operation"))
102 : m_RangeStartMoveFun{std::move(rangeStartMoveFun)},
102 : m_RangeStartMoveFun{std::move(rangeStartMoveFun)},
103 m_RangeEndMoveFun{std::move(rangeEndMoveFun)},
103 m_RangeEndMoveFun{std::move(rangeEndMoveFun)},
104 m_MaxMoveFun{std::move(maxMoveFun)},
104 m_MaxMoveFun{std::move(maxMoveFun)},
105 m_Label{label}
105 m_Label{label}
106 {
106 {
107 }
107 }
108
108
109 bool canExecute(VariableId variableId, const FuzzingState &fuzzingState) const override
109 bool canExecute(VariableId variableId, const FuzzingState &fuzzingState) const override
110 {
110 {
111 return fuzzingState.variableState(variableId).m_Variable != nullptr;
111 return fuzzingState.variableState(variableId).m_Variable != nullptr;
112 }
112 }
113
113
114 void execute(VariableId variableId, FuzzingState &fuzzingState,
114 void execute(VariableId variableId, FuzzingState &fuzzingState,
115 VariableController &variableController,
115 VariableController &variableController,
116 const Properties &properties) const override
116 const Properties &properties) const override
117 {
117 {
118 auto &variableState = fuzzingState.variableState(variableId);
118 auto &variableState = fuzzingState.variableState(variableId);
119 auto variable = variableState.m_Variable;
119 auto variable = variableState.m_Variable;
120
120
121 // Gets the max range defined
121 // Gets the max range defined
122 auto maxRange = properties.value(MAX_RANGE_PROPERTY, QVariant::fromValue(INVALID_RANGE))
122 auto maxRange = properties.value(MAX_RANGE_PROPERTY, QVariant::fromValue(INVALID_RANGE))
123 .value<SqpRange>();
123 .value<SqpRange>();
124 auto variableRange = variable->range();
124 auto variableRange = variableState.m_Range;
125
125
126 if (maxRange == INVALID_RANGE || variableRange.m_TStart < maxRange.m_TStart
126 if (maxRange == INVALID_RANGE || variableRange.m_TStart < maxRange.m_TStart
127 || variableRange.m_TEnd > maxRange.m_TEnd) {
127 || variableRange.m_TEnd > maxRange.m_TEnd) {
128 qCWarning(LOG_FuzzingOperations()) << "Can't execute operation: invalid max range";
128 qCWarning(LOG_FuzzingOperations()) << "Can't execute operation: invalid max range";
129 return;
129 return;
130 }
130 }
131
131
132 // Computes the max delta at which the variable can move, up to the limits of the max range
132 // Computes the max delta at which the variable can move, up to the limits of the max range
133 auto deltaMax = m_MaxMoveFun(variable->range(), maxRange);
133 auto deltaMax = m_MaxMoveFun(variableRange, maxRange);
134
134
135 // Generates random delta that will be used to move variable
135 // Generates random delta that will be used to move variable
136 auto delta = RandomGenerator::instance().generateDouble(0, deltaMax);
136 auto delta = RandomGenerator::instance().generateDouble(0, deltaMax);
137
137
138 // Moves variable to its new range
138 // Moves variable to its new range
139 auto isSynchronized = !fuzzingState.syncGroupId(variableId).isNull();
139 auto isSynchronized = !fuzzingState.syncGroupId(variableId).isNull();
140 auto newVariableRange = SqpRange{m_RangeStartMoveFun(variableRange.m_TStart, delta),
140 auto newVariableRange = SqpRange{m_RangeStartMoveFun(variableRange.m_TStart, delta),
141 m_RangeEndMoveFun(variableRange.m_TEnd, delta)};
141 m_RangeEndMoveFun(variableRange.m_TEnd, delta)};
142 qCInfo(LOG_FuzzingOperations()).noquote()
142 qCInfo(LOG_FuzzingOperations()).noquote()
143 << "Performing" << m_Label << "on" << variable->name() << "(from" << variableRange
143 << "Performing" << m_Label << "on" << variable->name() << "(from" << variableRange
144 << "to" << newVariableRange << ")...";
144 << "to" << newVariableRange << ")...";
145 variableController.onRequestDataLoading({variable}, newVariableRange, isSynchronized);
145 variableController.onRequestDataLoading({variable}, newVariableRange, isSynchronized);
146
146
147 // Updates state
147 // Updates state
148 fuzzingState.updateRanges(variableId, newVariableRange);
148 fuzzingState.updateRanges(variableId, newVariableRange);
149 }
149 }
150
150
151 MoveFunction m_RangeStartMoveFun;
151 MoveFunction m_RangeStartMoveFun;
152 MoveFunction m_RangeEndMoveFun;
152 MoveFunction m_RangeEndMoveFun;
153 MaxMoveFunction m_MaxMoveFun;
153 MaxMoveFunction m_MaxMoveFun;
154 QString m_Label;
154 QString m_Label;
155 };
155 };
156
156
157 struct SynchronizeOperation : public IFuzzingOperation {
157 struct SynchronizeOperation : public IFuzzingOperation {
158 bool canExecute(VariableId variableId, const FuzzingState &fuzzingState) const override
158 bool canExecute(VariableId variableId, const FuzzingState &fuzzingState) const override
159 {
159 {
160 auto variable = fuzzingState.variableState(variableId).m_Variable;
160 auto variable = fuzzingState.variableState(variableId).m_Variable;
161 return variable != nullptr && !fuzzingState.m_SyncGroupsPool.empty()
161 return variable != nullptr && !fuzzingState.m_SyncGroupsPool.empty()
162 && fuzzingState.syncGroupId(variableId).isNull();
162 && fuzzingState.syncGroupId(variableId).isNull();
163 }
163 }
164
164
165 void execute(VariableId variableId, FuzzingState &fuzzingState,
165 void execute(VariableId variableId, FuzzingState &fuzzingState,
166 VariableController &variableController, const Properties &) const override
166 VariableController &variableController, const Properties &) const override
167 {
167 {
168 auto &variableState = fuzzingState.variableState(variableId);
168 auto &variableState = fuzzingState.variableState(variableId);
169
169
170 // Chooses a random synchronization group and adds the variable into sync group
170 // Chooses a random synchronization group and adds the variable into sync group
171 auto syncGroupId = RandomGenerator::instance().randomChoice(fuzzingState.syncGroupsIds());
171 auto syncGroupId = RandomGenerator::instance().randomChoice(fuzzingState.syncGroupsIds());
172 qCInfo(LOG_FuzzingOperations()).noquote()
172 qCInfo(LOG_FuzzingOperations()).noquote()
173 << "Adding" << variableState.m_Variable->name() << "into synchronization group"
173 << "Adding" << variableState.m_Variable->name() << "into synchronization group"
174 << syncGroupId << "...";
174 << syncGroupId << "...";
175 variableController.onAddSynchronized(variableState.m_Variable, syncGroupId);
175 variableController.onAddSynchronized(variableState.m_Variable, syncGroupId);
176
176
177 // Updates state
177 // Updates state
178 fuzzingState.synchronizeVariable(variableId, syncGroupId);
178 fuzzingState.synchronizeVariable(variableId, syncGroupId);
179 }
179 }
180 };
180 };
181
181
182 struct DesynchronizeOperation : public IFuzzingOperation {
182 struct DesynchronizeOperation : public IFuzzingOperation {
183 bool canExecute(VariableId variableId, const FuzzingState &fuzzingState) const override
183 bool canExecute(VariableId variableId, const FuzzingState &fuzzingState) const override
184 {
184 {
185 auto variable = fuzzingState.variableState(variableId).m_Variable;
185 auto variable = fuzzingState.variableState(variableId).m_Variable;
186 return variable != nullptr && !fuzzingState.syncGroupId(variableId).isNull();
186 return variable != nullptr && !fuzzingState.syncGroupId(variableId).isNull();
187 }
187 }
188
188
189 void execute(VariableId variableId, FuzzingState &fuzzingState,
189 void execute(VariableId variableId, FuzzingState &fuzzingState,
190 VariableController &variableController, const Properties &) const override
190 VariableController &variableController, const Properties &) const override
191 {
191 {
192 auto &variableState = fuzzingState.variableState(variableId);
192 auto &variableState = fuzzingState.variableState(variableId);
193
193
194 // Gets the sync group of the variable
194 // Gets the sync group of the variable
195 auto syncGroupId = fuzzingState.syncGroupId(variableId);
195 auto syncGroupId = fuzzingState.syncGroupId(variableId);
196
196
197 qCInfo(LOG_FuzzingOperations()).noquote()
197 qCInfo(LOG_FuzzingOperations()).noquote()
198 << "Removing" << variableState.m_Variable->name() << "from synchronization group"
198 << "Removing" << variableState.m_Variable->name() << "from synchronization group"
199 << syncGroupId << "...";
199 << syncGroupId << "...";
200 variableController.onAddSynchronized(variableState.m_Variable, syncGroupId);
200 variableController.onAddSynchronized(variableState.m_Variable, syncGroupId);
201
201
202 // Updates state
202 // Updates state
203 fuzzingState.desynchronizeVariable(variableId, syncGroupId);
203 fuzzingState.desynchronizeVariable(variableId, syncGroupId);
204 }
204 }
205 };
205 };
206
206
207 struct UnknownOperation : public IFuzzingOperation {
207 struct UnknownOperation : public IFuzzingOperation {
208 bool canExecute(VariableId, const FuzzingState &) const override { return false; }
208 bool canExecute(VariableId, const FuzzingState &) const override { return false; }
209
209
210 void execute(VariableId, FuzzingState &, VariableController &,
210 void execute(VariableId, FuzzingState &, VariableController &,
211 const Properties &) const override
211 const Properties &) const override
212 {
212 {
213 }
213 }
214 };
214 };
215
215
216 } // namespace
216 } // namespace
217
217
218 std::unique_ptr<IFuzzingOperation> FuzzingOperationFactory::create(FuzzingOperationType type)
218 std::unique_ptr<IFuzzingOperation> FuzzingOperationFactory::create(FuzzingOperationType type)
219 {
219 {
220 switch (type) {
220 switch (type) {
221 case FuzzingOperationType::CREATE:
221 case FuzzingOperationType::CREATE:
222 return std::make_unique<CreateOperation>();
222 return std::make_unique<CreateOperation>();
223 case FuzzingOperationType::DELETE:
223 case FuzzingOperationType::DELETE:
224 return std::make_unique<DeleteOperation>();
224 return std::make_unique<DeleteOperation>();
225 case FuzzingOperationType::PAN_LEFT:
225 case FuzzingOperationType::PAN_LEFT:
226 return std::make_unique<MoveOperation>(
226 return std::make_unique<MoveOperation>(
227 std::minus<double>(), std::minus<double>(),
227 std::minus<double>(), std::minus<double>(),
228 [](const SqpRange &range, const SqpRange &maxRange) {
228 [](const SqpRange &range, const SqpRange &maxRange) {
229 return range.m_TStart - maxRange.m_TStart;
229 return range.m_TStart - maxRange.m_TStart;
230 },
230 },
231 QStringLiteral("Pan left operation"));
231 QStringLiteral("Pan left operation"));
232 case FuzzingOperationType::PAN_RIGHT:
232 case FuzzingOperationType::PAN_RIGHT:
233 return std::make_unique<MoveOperation>(
233 return std::make_unique<MoveOperation>(
234 std::plus<double>(), std::plus<double>(),
234 std::plus<double>(), std::plus<double>(),
235 [](const SqpRange &range, const SqpRange &maxRange) {
235 [](const SqpRange &range, const SqpRange &maxRange) {
236 return maxRange.m_TEnd - range.m_TEnd;
236 return maxRange.m_TEnd - range.m_TEnd;
237 },
237 },
238 QStringLiteral("Pan right operation"));
238 QStringLiteral("Pan right operation"));
239 case FuzzingOperationType::ZOOM_IN:
239 case FuzzingOperationType::ZOOM_IN:
240 return std::make_unique<MoveOperation>(
240 return std::make_unique<MoveOperation>(
241 std::plus<double>(), std::minus<double>(),
241 std::plus<double>(), std::minus<double>(),
242 [](const SqpRange &range, const SqpRange &maxRange) {
242 [](const SqpRange &range, const SqpRange &maxRange) {
243 Q_UNUSED(maxRange)
243 Q_UNUSED(maxRange)
244 return range.m_TEnd - (range.m_TStart + range.m_TEnd) / 2.;
244 return range.m_TEnd - (range.m_TStart + range.m_TEnd) / 2.;
245 },
245 },
246 QStringLiteral("Zoom in operation"));
246 QStringLiteral("Zoom in operation"));
247 case FuzzingOperationType::ZOOM_OUT:
247 case FuzzingOperationType::ZOOM_OUT:
248 return std::make_unique<MoveOperation>(
248 return std::make_unique<MoveOperation>(
249 std::minus<double>(), std::plus<double>(),
249 std::minus<double>(), std::plus<double>(),
250 [](const SqpRange &range, const SqpRange &maxRange) {
250 [](const SqpRange &range, const SqpRange &maxRange) {
251 return std::min(range.m_TStart - maxRange.m_TStart,
251 return std::min(range.m_TStart - maxRange.m_TStart,
252 maxRange.m_TEnd - range.m_TEnd);
252 maxRange.m_TEnd - range.m_TEnd);
253 },
253 },
254 QStringLiteral("Zoom out operation"));
254 QStringLiteral("Zoom out operation"));
255 case FuzzingOperationType::SYNCHRONIZE:
255 case FuzzingOperationType::SYNCHRONIZE:
256 return std::make_unique<SynchronizeOperation>();
256 return std::make_unique<SynchronizeOperation>();
257 case FuzzingOperationType::DESYNCHRONIZE:
257 case FuzzingOperationType::DESYNCHRONIZE:
258 return std::make_unique<DesynchronizeOperation>();
258 return std::make_unique<DesynchronizeOperation>();
259 default:
259 default:
260 // Default case returns unknown operation
260 // Default case returns unknown operation
261 break;
261 break;
262 }
262 }
263
263
264 return std::make_unique<UnknownOperation>();
264 return std::make_unique<UnknownOperation>();
265 }
265 }
General Comments 0
You need to be logged in to leave comments. Login now