PX4 Firmware
PX4 Autopilot Software http://px4.io
test_parameters.cpp
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * Copyright (C) 2012-2019 PX4 Development Team. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * 3. Neither the name PX4 nor the names of its contributors may be
16  * used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
26  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  *
32  ****************************************************************************/
33 
34 /**
35  * @file test_parameters.cpp
36  * Tests related to the parameter system.
37  */
38 
39 #include <unit_test.h>
40 
41 #include <px4_platform_common/defines.h>
42 #include <lib/parameters/param.h>
43 
44 #include <errno.h>
45 #include <fcntl.h>
46 #include <unistd.h>
47 #include <math.h>
48 
49 class ParameterTest : public UnitTest
50 {
51 public:
52  virtual bool run_tests();
53 
55  {
56  p0 = param_find("TEST_RC_X");
57  p1 = param_find("TEST_RC2_X");
58  p2 = param_find("TEST_1");
59  p3 = param_find("TEST_2");
60  p4 = param_find("TEST_3");
61  }
62 
63 private:
64 
70 
71  bool _assert_parameter_int_value(param_t param, int32_t expected);
72  bool _assert_parameter_float_value(param_t param, float expected);
73 
74  bool _set_all_int_parameters_to(int32_t value);
75 
76  // tests on the test parameters (TEST_RC_X, TEST_RC2_X, TEST_1, TEST_2, TEST_3)
77  bool SimpleFind();
78  bool ResetAll();
79  bool ResetAllExcludesOne();
80  bool ResetAllExcludesTwo();
83  bool exportImport();
84 
85  // tests on system parameters
86  // WARNING, can potentially trash your system
87  bool exportImportAll();
88 };
89 
91 {
92  int32_t value;
93  int result = param_get(param, &value);
94  ut_compare("param_get did not return parameter", 0, result);
95  ut_compare("value for param doesn't match default value", expected, value);
96 
97  return true;
98 }
99 
101 {
102  float value;
103  int result = param_get(param, &value);
104  ut_compare("param_get did not return parameter", 0, result);
105  ut_compare_float("value for param doesn't match default value", expected, value, 0.001);
106 
107  return true;
108 }
109 
111 {
112  param_set(p0, &value);
113  param_set(p1, &value);
114  param_set(p2, &value);
115  param_set(p3, &value);
116 
117  bool ret = false;
118 
119  ret = ret || _assert_parameter_int_value(p0, value);
120  ret = ret || _assert_parameter_int_value(p1, value);
121  ret = ret || _assert_parameter_int_value(p2, value);
122  ret = ret || _assert_parameter_int_value(p3, value);
123 
124  return ret;
125 }
126 
128 {
129  param_t param = param_find("TEST_2");
130 
131  ut_assert_true(PARAM_INVALID != param);
132 
133  int32_t value;
134  int result = param_get(param, &value);
135 
136  ut_compare("param_get did not return parameter", 0, result);
137  ut_compare("value of returned parameter does not match", 4, value);
138 
139  return true;
140 }
141 
143 {
145 
146  param_reset_all();
147 
148  bool ret = false;
149 
150  ret = ret || _assert_parameter_int_value(p0, 8);
151  ret = ret || _assert_parameter_int_value(p1, 16);
152  ret = ret || _assert_parameter_int_value(p2, 2);
153  ret = ret || _assert_parameter_int_value(p3, 4);
154 
155  return ret;
156 }
157 
159 {
161 
162  const char *excludes[] = {"TEST_RC_X"};
163  param_reset_excludes(excludes, 1);
164 
165  bool ret = false;
166 
167  ret = ret || _assert_parameter_int_value(p0, 50);
168  ret = ret || _assert_parameter_int_value(p1, 16);
169  ret = ret || _assert_parameter_int_value(p2, 2);
170  ret = ret || _assert_parameter_int_value(p3, 4);
171 
172  return ret;
173 }
174 
176 {
178 
179  const char *excludes[] = {"TEST_RC_X", "TEST_1"};
180  param_reset_excludes(excludes, 2);
181 
182  bool ret = false;
183 
184  ret = ret || _assert_parameter_int_value(p0, 50);
185  ret = ret || _assert_parameter_int_value(p1, 16);
186  ret = ret || _assert_parameter_int_value(p2, 50);
187  ret = ret || _assert_parameter_int_value(p3, 4);
188 
189  return ret;
190 }
191 
193 {
195 
196  const char *excludes[] = {"TEST_RC_X", "TEST_1"};
197  param_reset_excludes(excludes, 1);
198 
199  bool ret = false;
200 
201  ret = ret || _assert_parameter_int_value(p0, 50);
202  ret = ret || _assert_parameter_int_value(p1, 16);
203  ret = ret || _assert_parameter_int_value(p2, 2);
204  ret = ret || _assert_parameter_int_value(p3, 4);
205 
206  return ret;
207 }
208 
210 {
212 
213  const char *excludes[] = {"TEST_RC*"};
214  param_reset_excludes(excludes, 1);
215 
216  bool ret = false;
217 
218  ret = ret || _assert_parameter_int_value(p0, 50);
219  ret = ret || _assert_parameter_int_value(p1, 50);
220  ret = ret || _assert_parameter_int_value(p2, 2);
221  ret = ret || _assert_parameter_int_value(p3, 4);
222 
223  return ret;
224 }
225 
227 {
228  static constexpr float MAGIC_FLOAT_VAL = 0.314159f;
229 
230  bool ret = true;
231 
232  param_t test_params[] = {p0, p1, p2, p3, p4};
233 
234  // set all params to corresponding param_t value
235  for (auto p : test_params) {
236  if (param_type(p) == PARAM_TYPE_INT32) {
237  const int32_t set_val = p;
238 
239  if (param_set_no_notification(p, &set_val) != PX4_OK) {
240  PX4_ERR("param_set_no_notification failed for: %d", p);
241  ut_assert("param_set_no_notification failed", false);
242  }
243 
244  int32_t get_val = 0;
245 
246  if (param_get(p, &get_val) != PX4_OK) {
247  PX4_ERR("param_get failed for: %d", p);
248  ut_assert("param_set_no_notification failed", false);
249  }
250 
251  ut_compare("value for param doesn't match default value", p, get_val);
252  }
253 
254  if (param_type(p) == PARAM_TYPE_FLOAT) {
255  const float set_val = (float)p + MAGIC_FLOAT_VAL;
256 
257  if (param_set_no_notification(p, &set_val) != PX4_OK) {
258  PX4_ERR("param_set_no_notification failed for: %d", p);
259  ut_assert("param_set_no_notification failed", false);
260  }
261 
262  float get_val = 0.0f;
263 
264  if (param_get(p, &get_val) != PX4_OK) {
265  PX4_ERR("param_get failed for: %d", p);
266  ut_assert("param_set_no_notification failed", false);
267  }
268 
269  ut_compare("value for param doesn't match default value", p, (float)p + MAGIC_FLOAT_VAL);
270  }
271  }
272 
273  // save
274  if (param_save_default() != PX4_OK) {
275  PX4_ERR("param_save_default failed");
276  return false;
277  }
278 
279  // zero all params and verify, but don't save
280  for (auto p : test_params) {
281  if (param_type(p) == PARAM_TYPE_INT32) {
282  const int32_t set_val = 0;
283 
284  if (param_set_no_notification(p, &set_val) != PX4_OK) {
285  PX4_ERR("param_set_no_notification failed for: %d", p);
286  ut_assert("param_set_no_notification failed", false);
287  }
288 
289  int32_t get_val = -1;
290 
291  if (param_get(p, &get_val) != PX4_OK) {
292  PX4_ERR("param_get failed for: %d", p);
293  ut_assert("param_set_no_notification failed", false);
294  }
295 
296  ut_compare("value for param doesn't match default value", set_val, get_val);
297  }
298 
299  if (param_type(p) == PARAM_TYPE_FLOAT) {
300  const float set_val = 0.0f;
301 
302  if (param_set_no_notification(p, &set_val) != PX4_OK) {
303  PX4_ERR("param_set_no_notification failed for: %d", p);
304  ut_assert("param_set_no_notification failed", false);
305  }
306 
307  float get_val = -1.0f;
308 
309  if (param_get(p, &get_val) != PX4_OK) {
310  PX4_ERR("param_get failed for: %d", p);
311  ut_assert("param_set_no_notification failed", false);
312  }
313 
314  ut_compare_float("value for param doesn't match default value", set_val, get_val, 0.001f);
315  }
316  }
317 
318  // load saved params
319  if (param_load_default() != PX4_OK) {
320  PX4_ERR("param_save_default failed");
321  ret = true;
322  }
323 
324  // check every param
325  for (auto p : test_params) {
326  if (param_type(p) == PARAM_TYPE_INT32) {
327 
328  int32_t get_val = 0.0f;
329 
330  if (param_get(p, &get_val) != PX4_OK) {
331  PX4_ERR("param_get failed for: %d", p);
332  ut_assert("param_set_no_notification failed", false);
333  }
334 
335  ut_compare("value for param doesn't match default value", p, get_val);
336  }
337 
338  if (param_type(p) == PARAM_TYPE_FLOAT) {
339  float get_val = 0.0f;
340 
341  if (param_get(p, &get_val) != PX4_OK) {
342  PX4_ERR("param_get failed for: %d", p);
343  ut_assert("param_set_no_notification failed", false);
344  }
345 
346  ut_compare_float("value for param doesn't match default value", p, (float)p + MAGIC_FLOAT_VAL, 0.001f);
347  }
348  }
349 
350  return ret;
351 }
352 
354 {
355  static constexpr float MAGIC_FLOAT_VAL = 0.217828f;
356 
357  // backup current parameters
358  const char *param_file_name = PX4_STORAGEDIR "/param_backup";
359  int fd = open(param_file_name, O_WRONLY | O_CREAT, PX4_O_MODE_666);
360 
361  if (fd < 0) {
362  PX4_ERR("open '%s' failed (%i)", param_file_name, errno);
363  return false;
364  }
365 
366  int result = param_export(fd, false);
367 
368  if (result != PX4_OK) {
369  PX4_ERR("param_export failed");
370  close(fd);
371  return false;
372  }
373 
374  close(fd);
375 
376  bool ret = true;
377 
378  int N = param_count();
379 
380  // set all params to corresponding param_t value
381  for (unsigned i = 0; i < N; i++) {
382 
383  param_t p = param_for_index(i);
384 
385  if (p == PARAM_INVALID) {
386  PX4_ERR("param invalid: %d(%d)", p, i);
387  break;
388  }
389 
390  if (param_type(p) == PARAM_TYPE_INT32) {
391  const int32_t set_val = p;
392 
393  if (param_set_no_notification(p, &set_val) != PX4_OK) {
394  PX4_ERR("param_set_no_notification failed for: %d", p);
395  ut_assert("param_set_no_notification failed", false);
396  }
397 
398  int32_t get_val = 0;
399 
400  if (param_get(p, &get_val) != PX4_OK) {
401  PX4_ERR("param_get failed for: %d", p);
402  ut_assert("param_set_no_notification failed", false);
403  }
404 
405  ut_compare("value for param doesn't match default value", p, get_val);
406  }
407 
408  if (param_type(p) == PARAM_TYPE_FLOAT) {
409  const float set_val = (float)p + MAGIC_FLOAT_VAL;
410 
411  if (param_set_no_notification(p, &set_val) != PX4_OK) {
412  PX4_ERR("param_set_no_notification failed for: %d", p);
413  ut_assert("param_set_no_notification failed", false);
414  }
415 
416  float get_val = 0.0f;
417 
418  if (param_get(p, &get_val) != PX4_OK) {
419  PX4_ERR("param_get failed for: %d", p);
420  ut_assert("param_set_no_notification failed", false);
421  }
422 
423  ut_compare("value for param doesn't match default value", p, (float)p + MAGIC_FLOAT_VAL);
424  }
425  }
426 
427  // save
428  if (param_save_default() != PX4_OK) {
429  PX4_ERR("param_save_default failed");
430  return false;
431  }
432 
433  // zero all params and verify, but don't save
434  for (unsigned i = 0; i < N; i++) {
435  param_t p = param_for_index(i);
436 
437  if (param_type(p) == PARAM_TYPE_INT32) {
438 
439  const int32_t set_val = 0;
440 
441  if (param_set_no_notification(p, &set_val) != PX4_OK) {
442  PX4_ERR("param set failed: %d", p);
443  ut_assert("param_set_no_notification failed", false);
444  }
445 
446  int32_t get_val = -1;
447 
448  if (param_get(p, &get_val) != PX4_OK) {
449  PX4_ERR("param_get failed for: %d", p);
450  ut_assert("param_set_no_notification failed", false);
451  }
452 
453  ut_compare("value for param doesn't match default value", set_val, get_val);
454  }
455 
456  if (param_type(p) == PARAM_TYPE_FLOAT) {
457  float set_val = 0.0f;
458 
459  if (param_set_no_notification(p, &set_val) != PX4_OK) {
460  PX4_ERR("param set failed: %d", p);
461  ut_assert("param_set_no_notification failed", false);
462  }
463 
464  float get_val = -1.0f;
465 
466  if (param_get(p, &get_val) != PX4_OK) {
467  PX4_ERR("param_get failed for: %d", p);
468  ut_assert("param_set_no_notification failed", false);
469  }
470 
471  ut_compare("value for param doesn't match default value", set_val, get_val);
472  }
473  }
474 
475  // load saved params
476  if (param_load_default() != PX4_OK) {
477  PX4_ERR("param_save_default failed");
478  ret = true;
479  }
480 
481  // check every param
482  for (unsigned i = 0; i < N; i++) {
483  param_t p = param_for_index(i);
484 
485  if (param_type(p) == PARAM_TYPE_INT32) {
486 
487  int32_t get_val = 0;
488 
489  if (param_get(p, &get_val) != PX4_OK) {
490  PX4_ERR("param_get failed for: %d", p);
491  ut_assert("param_set_no_notification failed", false);
492  }
493 
494  ut_compare("value for param doesn't match default value", p, get_val);
495  }
496 
497  if (param_type(p) == PARAM_TYPE_FLOAT) {
498  float get_val = 0.0f;
499 
500  if (param_get(p, &get_val) != PX4_OK) {
501  PX4_ERR("param_get failed for: %d", p);
502  ut_assert("param_set_no_notification failed", false);
503  }
504 
505  ut_compare("value for param doesn't match default value", p, (float)p + MAGIC_FLOAT_VAL);
506  }
507  }
508 
509  param_reset_all();
510 
511  // restore original params
512  fd = open(param_file_name, O_RDONLY);
513 
514  if (fd < 0) {
515  PX4_ERR("open '%s' failed (%i)", param_file_name, errno);
516  return false;
517  }
518 
519  result = param_import(fd);
520  close(fd);
521 
522  if (result < 0) {
523  PX4_ERR("importing from '%s' failed (%i)", param_file_name, result);
524  return false;
525  }
526 
527  // save
528  if (param_save_default() != PX4_OK) {
529  PX4_ERR("param_save_default failed");
530  return false;
531  }
532 
533  return ret;
534 }
535 
537 {
538  param_control_autosave(false);
539 
548 
549  // WARNING, can potentially trash your system
550 #ifdef __PX4_POSIX
552 #endif /* __PX4_POSIX */
553 
555 
556  return (_tests_failed == 0);
557 }
558 
#define PARAM_INVALID
Handle returned when a parameter cannot be found.
Definition: param.h:103
bool _assert_parameter_int_value(param_t param, int32_t expected)
__EXPORT int param_import(int fd)
Import parameters from a file, discarding any unrecognized parameters.
#define PARAM_TYPE_INT32
Parameter types.
Definition: param.h:60
#define ut_declare_test_c(test_function, test_class)
Definition: unit_test.h:40
bool ResetAllExcludesOne()
__EXPORT int param_get(param_t param, void *val)
Copy the value of a parameter.
Definition: parameters.cpp:589
__EXPORT int param_set_no_notification(param_t param, const void *val)
Set the value of a parameter, but do not notify the system about the change.
Definition: parameters.cpp:820
bool _assert_parameter_float_value(param_t param, float expected)
__EXPORT int param_set(param_t param, const void *val)
Set the value of a parameter.
Definition: parameters.cpp:814
__EXPORT param_t param_for_index(unsigned index)
Look up a parameter by index.
Definition: parameters.cpp:408
Base class to be used for unit tests.
Definition: unit_test.h:54
__EXPORT unsigned param_count(void)
Return the total number of parameters.
Definition: parameters.cpp:382
bool ResetAllExcludesTwo()
Global flash based parameter store.
int _tests_failed
The number of unit tests which failed.
Definition: unit_test.h:206
__EXPORT void param_reset_excludes(const char *excludes[], int num_excludes)
Reset all parameters to their default values except for excluded parameters.
Definition: parameters.cpp:916
__EXPORT int param_export(int fd, bool only_unsaved)
Export changed parameters to a file.
#define ut_assert(message, test)
Used to assert a value within a unit test.
Definition: unit_test.h:113
Vector< float, 6 > f(float t, const Matrix< float, 6, 1 > &, const Matrix< float, 3, 1 > &)
Definition: integration.cpp:8
__EXPORT param_type_t param_type(param_t param)
Obtain the type of a parameter.
Definition: parameters.cpp:519
__EXPORT int param_save_default(void)
Save parameters to the default file.
Definition: parameters.cpp:974
#define ut_assert_true(test)
To assert specifically to true.
Definition: unit_test.h:127
virtual bool run_tests()
Override to run your unit tests.
int fd
Definition: dataman.cpp:146
__EXPORT param_t param_find(const char *name)
Look up a parameter by name.
Definition: parameters.cpp:370
#define PARAM_TYPE_FLOAT
Definition: param.h:61
bool ResetAllExcludesBoundaryCheck()
__EXPORT void param_control_autosave(bool enable)
Enable/disable the param autosaving.
Definition: parameters.cpp:687
__EXPORT void param_reset_all(void)
Reset all parameters to their default values.
Definition: parameters.cpp:910
#define ut_compare(message, v1, v2)
Used to compare two integer values within a unit test.
Definition: unit_test.h:150
#define ut_run_test(test)
Runs a single unit test.
Definition: unit_test.h:96
#define ut_compare_float(message, v1, v2, precision)
Used to compare two float values within a unit test.
Definition: unit_test.h:164
int test_parameters(int argc, char *argv[])
bool ResetAllExcludesWildcard()
__EXPORT int param_load_default(void)
Load parameters from the default parameter file.
bool _set_all_int_parameters_to(int32_t value)
uint32_t param_t
Parameter handle.
Definition: param.h:98