##// END OF EJS Templates
Adds utility class to get random values
Alexandre Leroux -
r1206:9f9ab053f00b
parent child
Show More
@@ -0,0 +1,25
1 #include "FuzzingUtils.h"
2
3 RandomGenerator &RandomGenerator::instance()
4 {
5 static auto instance = RandomGenerator();
6 return instance;
7 }
8
9 double RandomGenerator::generateDouble(double min, double max)
10 {
11 std::uniform_real_distribution<double> dist{min, max};
12 return dist(m_Mt);
13 }
14
15 int RandomGenerator::generateInt(int min, int max)
16 {
17 std::uniform_int_distribution<int> dist{min, max};
18 return dist(m_Mt);
19 }
20
21 RandomGenerator::RandomGenerator()
22 {
23 std::random_device rd{};
24 m_Mt = std::mt19937{rd()};
25 }
@@ -0,0 +1,41
1 #ifndef SCIQLOP_FUZZINGUTILS_H
2 #define SCIQLOP_FUZZINGUTILS_H
3
4 #include <random>
5
6 /**
7 * Class that proposes random utility methods
8 */
9 class RandomGenerator {
10 public:
11 /// @return the unique instance of the random generator
12 static RandomGenerator &instance();
13
14 /// Generates a random double between [min, max]
15 double generateDouble(double min, double max);
16 /// Generates a random int between [min, max]
17 int generateInt(int min, int max);
18
19 /// Returns a random element among the elements of a container. If the container is empty, returns an element built by default
20 template <typename T, typename ValueType = typename T::value_type>
21 ValueType randomChoice(const T& container);
22
23 private:
24 std::mt19937 m_Mt;
25
26 explicit RandomGenerator();
27 };
28
29 template<typename T, typename ValueType>
30 ValueType RandomGenerator::randomChoice(const T &container)
31 {
32 if(container.empty()){
33 return ValueType{};
34 }
35
36 auto randomIndex = generateInt(0, container.size() - 1);
37 return container.at(randomIndex);
38 }
39
40 #endif // SCIQLOP_FUZZINGUTILS
41
@@ -1,85 +1,87
1
1
2 amdaplugin_moc_headers = [
2 amdaplugin_moc_headers = [
3 'include/AmdaPlugin.h',
3 'include/AmdaPlugin.h',
4 'include/AmdaProvider.h'
4 'include/AmdaProvider.h'
5 ]
5 ]
6
6
7 amdaplugin_sources = [
7 amdaplugin_sources = [
8 'src/AmdaDefs.cpp',
8 'src/AmdaDefs.cpp',
9 'src/AmdaParser.cpp',
9 'src/AmdaParser.cpp',
10 'src/AmdaPlugin.cpp',
10 'src/AmdaPlugin.cpp',
11 'src/AmdaProvider.cpp',
11 'src/AmdaProvider.cpp',
12 'src/AmdaResultParser.cpp',
12 'src/AmdaResultParser.cpp',
13 'src/AmdaResultParserDefs.cpp',
13 'src/AmdaResultParserDefs.cpp',
14 'src/AmdaResultParserHelper.cpp',
14 'src/AmdaResultParserHelper.cpp',
15 'src/AmdaServer.cpp'
15 'src/AmdaServer.cpp'
16 ]
16 ]
17
17
18 amdaplugin_ui_files = []
18 amdaplugin_ui_files = []
19 amdaplugin_resources_files = [
19 amdaplugin_resources_files = [
20 'resources/amdaresources.qrc'
20 'resources/amdaresources.qrc'
21 ]
21 ]
22
22
23 amdaplugin_inc = include_directories(['include', '../../plugin/include'])
23 amdaplugin_inc = include_directories(['include', '../../plugin/include'])
24
24
25 moc_gen = generator(moc,
25 moc_gen = generator(moc,
26 output : 'moc_@BASENAME@.cpp',
26 output : 'moc_@BASENAME@.cpp',
27 arguments : ['@INPUT@',
27 arguments : ['@INPUT@',
28 '-DSCIQLOP_PLUGIN_JSON_FILE_PATH="'+meson.source_root()+'/plugins/amda/resources/amda.json"',
28 '-DSCIQLOP_PLUGIN_JSON_FILE_PATH="'+meson.source_root()+'/plugins/amda/resources/amda.json"',
29 '-I', meson.current_source_dir()+'/include',
29 '-I', meson.current_source_dir()+'/include',
30 '-I', meson.current_source_dir()+'/../../plugin/include',
30 '-I', meson.current_source_dir()+'/../../plugin/include',
31 '-o', '@OUTPUT@'])
31 '-o', '@OUTPUT@'])
32
32
33 rcc_gen = generator(rcc,
33 rcc_gen = generator(rcc,
34 output : 'qrc_@BASENAME@.cpp',
34 output : 'qrc_@BASENAME@.cpp',
35 arguments : ['--name=@BASENAME@"',
35 arguments : ['--name=@BASENAME@"',
36 '--output',
36 '--output',
37 '@OUTPUT@',
37 '@OUTPUT@',
38 '@INPUT@'])
38 '@INPUT@'])
39
39
40 amdaplugin_moc_plugin_files = moc_gen.process(amdaplugin_moc_headers)
40 amdaplugin_moc_plugin_files = moc_gen.process(amdaplugin_moc_headers)
41
41
42 amdaplugin_rcc_plugin_files = rcc_gen.process(amdaplugin_resources_files)
42 amdaplugin_rcc_plugin_files = rcc_gen.process(amdaplugin_resources_files)
43
43
44 #amdaplugin_rcc_plugin_files = qt5.preprocess(
44 #amdaplugin_rcc_plugin_files = qt5.preprocess(
45 # qresources : amdaplugin_resources_files)
45 # qresources : amdaplugin_resources_files)
46
46
47 amdaplugin_moc_files = qt5.preprocess(
47 amdaplugin_moc_files = qt5.preprocess(
48 ui_files : amdaplugin_ui_files)
48 ui_files : amdaplugin_ui_files)
49
49
50 sciqlop_amdaplugin = library('amdaplugin',
50 sciqlop_amdaplugin = library('amdaplugin',
51 amdaplugin_sources,
51 amdaplugin_sources,
52 amdaplugin_moc_files,
52 amdaplugin_moc_files,
53 amdaplugin_rcc_plugin_files,
53 amdaplugin_rcc_plugin_files,
54 amdaplugin_moc_plugin_files,
54 amdaplugin_moc_plugin_files,
55 cpp_args : ['-DAMDA_LIB','-DQT_PLUGIN'],
55 cpp_args : ['-DAMDA_LIB','-DQT_PLUGIN'],
56 include_directories : [amdaplugin_inc],
56 include_directories : [amdaplugin_inc],
57 dependencies : [sciqlop_core, sciqlop_gui],
57 dependencies : [sciqlop_core, sciqlop_gui],
58 install : true
58 install : true
59 )
59 )
60
60
61
61
62 tests = [
62 tests = [
63 [['tests/TestAmdaParser.cpp'],'test_amda_parser','AMDA parser test'],
63 [['tests/TestAmdaParser.cpp'],'test_amda_parser','AMDA parser test'],
64 [['tests/TestAmdaResultParser.cpp'],'test_amda_result_parser','AMDA result parser test'],
64 [['tests/TestAmdaResultParser.cpp'],'test_amda_result_parser','AMDA result parser test'],
65 [['tests/TestAmdaAcquisition.cpp'],'test_amda_acquisition','AMDA Acquisition test'],
65 [['tests/TestAmdaAcquisition.cpp'],'test_amda_acquisition','AMDA Acquisition test'],
66 [['tests/TestAmdaFuzzing.cpp'],'test_amda_fuzzing','AMDA fuzzing test']
66 [['tests/TestAmdaFuzzing.cpp'],'test_amda_fuzzing','AMDA fuzzing test']
67 ]
67 ]
68
68
69 tests_sources = [
69 tests_sources = [
70 'tests/FuzzingDefs.h',
70 'tests/FuzzingDefs.h',
71 'tests/FuzzingDefs.cpp',
71 'tests/FuzzingDefs.cpp',
72 'tests/FuzzingOperations.h',
72 'tests/FuzzingOperations.h',
73 'tests/FuzzingOperations.cpp',
73 'tests/FuzzingOperations.cpp',
74 'tests/FuzzingUtils.h',
75 'tests/FuzzingUtils.cpp'
74 ]
76 ]
75
77
76 foreach unit_test : tests
78 foreach unit_test : tests
77 test_moc_files = qt5.preprocess(moc_sources : unit_test[0])
79 test_moc_files = qt5.preprocess(moc_sources : unit_test[0])
78 test_exe = executable(unit_test[1],unit_test[0] , test_moc_files,
80 test_exe = executable(unit_test[1],unit_test[0] , test_moc_files,
79 link_with : [sciqlop_amdaplugin],
81 link_with : [sciqlop_amdaplugin],
80 include_directories : [amdaplugin_inc],
82 include_directories : [amdaplugin_inc],
81 cpp_args : ['-DAMDA_TESTS_RESOURCES_DIR="'+meson.current_source_dir()+'/tests-resources"'],
83 cpp_args : ['-DAMDA_TESTS_RESOURCES_DIR="'+meson.current_source_dir()+'/tests-resources"'],
82 sources : [tests_sources],
84 sources : [tests_sources],
83 dependencies : [sciqlop_core, sciqlop_gui, qt5test])
85 dependencies : [sciqlop_core, sciqlop_gui, qt5test])
84 test(unit_test[2], test_exe, args: ['-teamcity', '-o', '@0@.teamcity.txt'.format(unit_test[1])], timeout: 3 * 60)
86 test(unit_test[2], test_exe, args: ['-teamcity', '-o', '@0@.teamcity.txt'.format(unit_test[1])], timeout: 3 * 60)
85 endforeach
87 endforeach
@@ -1,207 +1,209
1 #include "FuzzingDefs.h"
1 #include "FuzzingDefs.h"
2 #include "FuzzingOperations.h"
2 #include "FuzzingOperations.h"
3 #include "FuzzingUtils.h"
4
3 #include <Network/NetworkController.h>
5 #include <Network/NetworkController.h>
4 #include <SqpApplication.h>
6 #include <SqpApplication.h>
5 #include <Time/TimeController.h>
7 #include <Time/TimeController.h>
6 #include <Variable/VariableController.h>
8 #include <Variable/VariableController.h>
7
9
8 #include <QLoggingCategory>
10 #include <QLoggingCategory>
9 #include <QObject>
11 #include <QObject>
10 #include <QtTest>
12 #include <QtTest>
11
13
12 #include <memory>
14 #include <memory>
13
15
14 Q_LOGGING_CATEGORY(LOG_TestAmdaFuzzing, "TestAmdaFuzzing")
16 Q_LOGGING_CATEGORY(LOG_TestAmdaFuzzing, "TestAmdaFuzzing")
15
17
16 namespace {
18 namespace {
17
19
18 // /////// //
20 // /////// //
19 // Aliases //
21 // Aliases //
20 // /////// //
22 // /////// //
21
23
22 using VariableId = int;
24 using VariableId = int;
23
25
24 using VariableOperation = std::pair<VariableId, std::shared_ptr<IFuzzingOperation> >;
26 using VariableOperation = std::pair<VariableId, std::shared_ptr<IFuzzingOperation> >;
25 using VariablesOperations = std::vector<VariableOperation>;
27 using VariablesOperations = std::vector<VariableOperation>;
26
28
27 using OperationsPool = std::set<std::shared_ptr<IFuzzingOperation> >;
29 using OperationsPool = std::set<std::shared_ptr<IFuzzingOperation> >;
28 using VariablesPool = std::map<VariableId, std::shared_ptr<Variable> >;
30 using VariablesPool = std::map<VariableId, std::shared_ptr<Variable> >;
29
31
30 // ///////// //
32 // ///////// //
31 // Constants //
33 // Constants //
32 // ///////// //
34 // ///////// //
33
35
34 // Defaults values used when the associated properties have not been set for the test
36 // Defaults values used when the associated properties have not been set for the test
35 const auto NB_MAX_OPERATIONS_DEFAULT_VALUE = 100;
37 const auto NB_MAX_OPERATIONS_DEFAULT_VALUE = 100;
36 const auto NB_MAX_VARIABLES_DEFAULT_VALUE = 1;
38 const auto NB_MAX_VARIABLES_DEFAULT_VALUE = 1;
37 const auto AVAILABLE_OPERATIONS_DEFAULT_VALUE
39 const auto AVAILABLE_OPERATIONS_DEFAULT_VALUE
38 = QVariant::fromValue(OperationsTypes{FuzzingOperationType::CREATE});
40 = QVariant::fromValue(OperationsTypes{FuzzingOperationType::CREATE});
39 // /////// //
41 // /////// //
40 // Methods //
42 // Methods //
41 // /////// //
43 // /////// //
42
44
43 /// Goes through the variables pool and operations pool to determine the set of {variable/operation}
45 /// Goes through the variables pool and operations pool to determine the set of {variable/operation}
44 /// pairs that are valid (i.e. operation that can be executed on variable)
46 /// pairs that are valid (i.e. operation that can be executed on variable)
45 VariablesOperations availableOperations(const VariablesPool &variablesPool,
47 VariablesOperations availableOperations(const VariablesPool &variablesPool,
46 const OperationsPool &operationsPool)
48 const OperationsPool &operationsPool)
47 {
49 {
48 VariablesOperations result{};
50 VariablesOperations result{};
49
51
50 for (const auto &variablesPoolEntry : variablesPool) {
52 for (const auto &variablesPoolEntry : variablesPool) {
51 auto variableId = variablesPoolEntry.first;
53 auto variableId = variablesPoolEntry.first;
52 auto variable = variablesPoolEntry.second;
54 auto variable = variablesPoolEntry.second;
53
55
54 for (const auto &operation : operationsPool) {
56 for (const auto &operation : operationsPool) {
55 // A pair is valid if the current operation can be executed on the current variable
57 // A pair is valid if the current operation can be executed on the current variable
56 if (operation->canExecute(variable)) {
58 if (operation->canExecute(variable)) {
57 result.push_back({variableId, operation});
59 result.push_back({variableId, operation});
58 }
60 }
59 }
61 }
60 }
62 }
61
63
62 return result;
64 return result;
63 }
65 }
64
66
65 OperationsPool createOperationsPool(const OperationsTypes &types)
67 OperationsPool createOperationsPool(const OperationsTypes &types)
66 {
68 {
67 OperationsPool result{};
69 OperationsPool result{};
68
70
69 std::transform(types.cbegin(), types.cend(), std::inserter(result, result.end()),
71 std::transform(types.cbegin(), types.cend(), std::inserter(result, result.end()),
70 [](const auto &type) { return FuzzingOperationFactory::create(type); });
72 [](const auto &type) { return FuzzingOperationFactory::create(type); });
71
73
72 return result;
74 return result;
73 }
75 }
74
76
75 /**
77 /**
76 * Class to run random tests
78 * Class to run random tests
77 */
79 */
78 class FuzzingTest {
80 class FuzzingTest {
79 public:
81 public:
80 explicit FuzzingTest(VariableController &variableController, Properties properties)
82 explicit FuzzingTest(VariableController &variableController, Properties properties)
81 : m_VariableController{variableController},
83 : m_VariableController{variableController},
82 m_Properties{std::move(properties)},
84 m_Properties{std::move(properties)},
83 m_VariablesPool{}
85 m_VariablesPool{}
84 {
86 {
85 // Inits variables pool: at init, all variables are null
87 // Inits variables pool: at init, all variables are null
86 for (auto variableId = 0; variableId < nbMaxVariables(); ++variableId) {
88 for (auto variableId = 0; variableId < nbMaxVariables(); ++variableId) {
87 m_VariablesPool[variableId] = nullptr;
89 m_VariablesPool[variableId] = nullptr;
88 }
90 }
89 }
91 }
90
92
91 void execute()
93 void execute()
92 {
94 {
93 qCInfo(LOG_TestAmdaFuzzing()) << "Running" << nbMaxOperations() << "operations on"
95 qCInfo(LOG_TestAmdaFuzzing()) << "Running" << nbMaxOperations() << "operations on"
94 << nbMaxVariables() << "variables...";
96 << nbMaxVariables() << "variables...";
95
97
96 auto canExecute = true;
98 auto canExecute = true;
97 for (auto i = 0; i < nbMaxOperations() && canExecute; ++i) {
99 for (auto i = 0; i < nbMaxOperations() && canExecute; ++i) {
98 // Retrieves all operations that can be executed in the current context
100 // Retrieves all operations that can be executed in the current context
99 auto variableOperations = availableOperations(m_VariablesPool, operationsPool());
101 auto variableOperations = availableOperations(m_VariablesPool, operationsPool());
100
102
101 canExecute = !variableOperations.empty();
103 canExecute = !variableOperations.empty();
102 if (canExecute) {
104 if (canExecute) {
103 // Of the operations available, chooses a random operation and executes it
105 // Of the operations available, chooses a random operation and executes it
104 auto variableOperation
106 auto variableOperation
105 = /* TODO: gets a random operation */;
107 = RandomGenerator::instance().randomChoice(variableOperations);
106
108
107 auto variableId = variableOperation.first;
109 auto variableId = variableOperation.first;
108 auto variable = m_VariablesPool.at(variableId);
110 auto variable = m_VariablesPool.at(variableId);
109 auto fuzzingOperation = variableOperation.second;
111 auto fuzzingOperation = variableOperation.second;
110
112
111 fuzzingOperation->execute(variable, m_VariableController, m_Properties);
113 fuzzingOperation->execute(variable, m_VariableController, m_Properties);
112
114
113 // Updates variable pool with the new state of the variable after operation
115 // Updates variable pool with the new state of the variable after operation
114 m_VariablesPool[variableId] = variable;
116 m_VariablesPool[variableId] = variable;
115 }
117 }
116 else {
118 else {
117 qCInfo(LOG_TestAmdaFuzzing())
119 qCInfo(LOG_TestAmdaFuzzing())
118 << "No more operations are available, the execution of the test will stop...";
120 << "No more operations are available, the execution of the test will stop...";
119 }
121 }
120 }
122 }
121
123
122 qCInfo(LOG_TestAmdaFuzzing()) << "Execution of the test completed.";
124 qCInfo(LOG_TestAmdaFuzzing()) << "Execution of the test completed.";
123 }
125 }
124
126
125 private:
127 private:
126 int nbMaxOperations() const
128 int nbMaxOperations() const
127 {
129 {
128 static auto result
130 static auto result
129 = m_Properties.value(NB_MAX_OPERATIONS_PROPERTY, NB_MAX_OPERATIONS_DEFAULT_VALUE)
131 = m_Properties.value(NB_MAX_OPERATIONS_PROPERTY, NB_MAX_OPERATIONS_DEFAULT_VALUE)
130 .toInt();
132 .toInt();
131 return result;
133 return result;
132 }
134 }
133
135
134 int nbMaxVariables() const
136 int nbMaxVariables() const
135 {
137 {
136 static auto result
138 static auto result
137 = m_Properties.value(NB_MAX_VARIABLES_PROPERTY, NB_MAX_VARIABLES_DEFAULT_VALUE).toInt();
139 = m_Properties.value(NB_MAX_VARIABLES_PROPERTY, NB_MAX_VARIABLES_DEFAULT_VALUE).toInt();
138 return result;
140 return result;
139 }
141 }
140
142
141 OperationsPool operationsPool() const
143 OperationsPool operationsPool() const
142 {
144 {
143 static auto result = createOperationsPool(
145 static auto result = createOperationsPool(
144 m_Properties.value(AVAILABLE_OPERATIONS_PROPERTY, AVAILABLE_OPERATIONS_DEFAULT_VALUE)
146 m_Properties.value(AVAILABLE_OPERATIONS_PROPERTY, AVAILABLE_OPERATIONS_DEFAULT_VALUE)
145 .value<OperationsTypes>());
147 .value<OperationsTypes>());
146 return result;
148 return result;
147 }
149 }
148
150
149 VariableController &m_VariableController;
151 VariableController &m_VariableController;
150 Properties m_Properties;
152 Properties m_Properties;
151 VariablesPool m_VariablesPool;
153 VariablesPool m_VariablesPool;
152 };
154 };
153
155
154 } // namespace
156 } // namespace
155
157
156 class TestAmdaFuzzing : public QObject {
158 class TestAmdaFuzzing : public QObject {
157 Q_OBJECT
159 Q_OBJECT
158
160
159 private slots:
161 private slots:
160 /// Input data for @sa testFuzzing()
162 /// Input data for @sa testFuzzing()
161 void testFuzzing_data();
163 void testFuzzing_data();
162 void testFuzzing();
164 void testFuzzing();
163 };
165 };
164
166
165 void TestAmdaFuzzing::testFuzzing_data()
167 void TestAmdaFuzzing::testFuzzing_data()
166 {
168 {
167 // ////////////// //
169 // ////////////// //
168 // Test structure //
170 // Test structure //
169 // ////////////// //
171 // ////////////// //
170
172
171 QTest::addColumn<Properties>("properties"); // Properties for random test
173 QTest::addColumn<Properties>("properties"); // Properties for random test
172
174
173 // ////////// //
175 // ////////// //
174 // Test cases //
176 // Test cases //
175 // ////////// //
177 // ////////// //
176
178
177 ///@todo: complete
179 ///@todo: complete
178 }
180 }
179
181
180 void TestAmdaFuzzing::testFuzzing()
182 void TestAmdaFuzzing::testFuzzing()
181 {
183 {
182 QFETCH(Properties, properties);
184 QFETCH(Properties, properties);
183
185
184 auto &variableController = sqpApp->variableController();
186 auto &variableController = sqpApp->variableController();
185 auto &timeController = sqpApp->timeController();
187 auto &timeController = sqpApp->timeController();
186
188
187 FuzzingTest test{variableController, properties};
189 FuzzingTest test{variableController, properties};
188 test.execute();
190 test.execute();
189 }
191 }
190
192
191 int main(int argc, char *argv[])
193 int main(int argc, char *argv[])
192 {
194 {
193 QLoggingCategory::setFilterRules(
195 QLoggingCategory::setFilterRules(
194 "*.warning=false\n"
196 "*.warning=false\n"
195 "*.info=false\n"
197 "*.info=false\n"
196 "*.debug=false\n"
198 "*.debug=false\n"
197 "FuzzingOperations.info=true\n"
199 "FuzzingOperations.info=true\n"
198 "TestAmdaFuzzing.info=true\n");
200 "TestAmdaFuzzing.info=true\n");
199
201
200 SqpApplication app{argc, argv};
202 SqpApplication app{argc, argv};
201 app.setAttribute(Qt::AA_Use96Dpi, true);
203 app.setAttribute(Qt::AA_Use96Dpi, true);
202 TestAmdaFuzzing testObject{};
204 TestAmdaFuzzing testObject{};
203 QTEST_SET_MAIN_SOURCE_PATH
205 QTEST_SET_MAIN_SOURCE_PATH
204 return QTest::qExec(&testObject, argc, argv);
206 return QTest::qExec(&testObject, argc, argv);
205 }
207 }
206
208
207 #include "TestAmdaFuzzing.moc"
209 #include "TestAmdaFuzzing.moc"
General Comments 0
You need to be logged in to leave comments. Login now