1 /* This file is part of the hkl library.
3 * The hkl library is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, either version 3 of the License, or
6 * (at your option) any later version.
8 * The hkl library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with the hkl library. If not, see <http://www.gnu.org/licenses/>.
16 * Copyright (C) 2003-2014 Synchrotron SOLEIL
17 * L'Orme des Merisiers Saint-Aubin
18 * BP 48 91192 GIF-sur-YVETTE CEDEX
20 * Authors: Picca Frédéric-Emmanuel <picca@synchrotron-soleil.fr>
25 #include <tap/basic.h>
26 #include <tap/hkl-tap.h>
31 typedef int (* test_func
) (HklEngine
*engine
, HklEngineList
*engine_list
, unsigned int n
);
33 static int __test(unsigned int nb_iter
, test_func f
, int foreach_mode
)
35 HklFactory
**factories
;
37 HklGeometry
*geometry
= NULL
;
38 HklDetector
*detector
= hkl_detector_factory_new(HKL_DETECTOR_TYPE_0D
);
39 HklSample
*sample
= hkl_sample_new("test");
40 HklEngineList
*engines
;
44 factories
= hkl_factory_get_all(&n
);
45 for(i
=0; i
<n
&& TRUE
== res
; i
++){
48 geometry
= hkl_factory_create_new_geometry(factories
[i
]);
49 engines
= hkl_factory_create_new_engine_list(factories
[i
]);
50 hkl_engine_list_init(engines
, geometry
, detector
, sample
);
51 darray_foreach(engine
, *hkl_engine_list_engines_get(engines
)){
52 const darray_string
*modes
= hkl_engine_modes_names_get(*engine
);
54 darray_foreach(mode
, *modes
){
55 res
&= DIAG(hkl_engine_current_mode_set(*engine
, *mode
, NULL
));
56 for(j
=0; j
<nb_iter
; ++j
){
57 res
&= DIAG(f(*engine
, engines
, nb_iter
));
59 diag("failed at factory: \"%s\" engine: \"%s\" mode: \"%s\"",
60 hkl_geometry_name_get(geometry
),
61 hkl_engine_name_get(*engine
), *mode
);
69 for(j
=0; j
<nb_iter
; ++j
){
70 res
&= DIAG(f(*engine
, engines
, nb_iter
));
78 hkl_geometry_free(geometry
);
79 hkl_engine_list_free(engines
);
81 hkl_detector_free(detector
);
82 hkl_sample_free(sample
);
87 #define TEST(_nb_iter, _f) __test(_nb_iter, _f, 0)
88 #define TEST_FOREACH_MODE(_nb_iter, _f) __test(_nb_iter, _f, 1)
90 static void factories(void)
94 HklEngineList
*engines
;
95 HklFactory
**factories
;
97 factories
= hkl_factory_get_all(&n
);
99 engines
= hkl_factory_create_new_engine_list(factories
[i
]);
100 hkl_engine_list_free(engines
);
103 ok(res
== TRUE
, "factories");
106 static int _get(HklEngine
*engine
, HklEngineList
*engine_list
, unsigned int n
)
111 HklGeometry
*geometry
= hkl_engine_list_geometry_get(engine_list
);
112 const darray_string
*pseudo_axes
= hkl_engine_pseudo_axes_names_get(engine
);
113 const size_t n_pseudo_axes
= darray_size(*pseudo_axes
);
114 double targets
[n_pseudo_axes
];
115 double currents
[n_pseudo_axes
];
117 /* randomize the geometry */
118 hkl_geometry_randomize(geometry
);
120 /* randomize the pseudoAxes values */
121 hkl_tap_engine_pseudo_axes_randomize(engine
,
122 targets
, n_pseudo_axes
,
125 /* randomize the parameters */
126 hkl_tap_engine_parameters_randomize(engine
);
128 /* pseudo -> geometry */
129 if(HKL_ENGINE_CAPABILITIES_INITIALIZABLE
& hkl_engine_capabilities_get(engine
))
130 res
&= DIAG(hkl_engine_initialized_set(engine
, TRUE
, NULL
));
131 res
&= DIAG(hkl_engine_pseudo_axes_values_get(engine
, currents
, n_pseudo_axes
,
132 HKL_UNIT_DEFAULT
, NULL
));
134 /* idem with error management */
136 res
&= DIAG(hkl_engine_pseudo_axes_values_get(engine
, currents
, n_pseudo_axes
,
137 HKL_UNIT_DEFAULT
, &error
));
138 res
&= DIAG(NULL
== error
);
139 for(i
=0; i
<n_pseudo_axes
; ++i
)
140 res
&= DIAG(targets
[i
] != currents
[i
]); /* TODO this test is almost true, need a real check */
147 ok(TRUE
== TEST_FOREACH_MODE(1, _get
), __func__
);
150 static int _set(HklEngine
*engine
, HklEngineList
*engine_list
, unsigned int n
)
153 GError
*error
= NULL
;
156 HklGeometry
*geometry
= hkl_engine_list_geometry_get(engine_list
);
157 const darray_string
*pseudo_axes
= hkl_engine_pseudo_axes_names_get(engine
);
158 const size_t n_pseudo_axes
= darray_size(*pseudo_axes
);
159 double targets
[n_pseudo_axes
];
160 double currents
[n_pseudo_axes
];
162 /* randomize the geometry */
163 hkl_geometry_randomize(geometry
);
165 /* for now skip the eulerians check */
166 if(!strcmp(hkl_engine_current_mode_get(engine
), "eulerians"))
170 HklParameter
**pseudo_axis
;
171 HklGeometryList
*solutions
;
173 /* randomize the pseudoAxes values */
174 hkl_tap_engine_pseudo_axes_randomize(engine
,
175 targets
, n_pseudo_axes
,
178 /* randomize the parameters */
179 hkl_tap_engine_parameters_randomize(engine
);
181 /* pseudo -> geometry */
182 res
&= DIAG(hkl_engine_initialized_set(engine
, TRUE
, &error
));
184 /* geometry -> pseudo */
185 solutions
= hkl_engine_pseudo_axes_values_set(engine
,
186 targets
, n_pseudo_axes
,
187 HKL_UNIT_DEFAULT
, &error
);
189 const HklGeometryListItem
*item
;
191 HKL_GEOMETRY_LIST_FOREACH(item
, solutions
){
192 hkl_geometry_set(geometry
,
193 hkl_geometry_list_item_geometry_get(item
));
195 res
&= DIAG(hkl_engine_pseudo_axes_values_get(engine
, currents
, n_pseudo_axes
, HKL_UNIT_DEFAULT
, &error
));
196 for(j
=0; j
<n_pseudo_axes
; ++j
)
197 res
&= DIAG(fabs(targets
[j
] - currents
[j
]) < HKL_EPSILON
);
200 res
&= DIAG(error
!= NULL
);
201 g_clear_error(&error
);
205 fprintf(stderr
, " unreachable : %d/%d", unreachable
, i
);
207 fprintf(stderr
, " ko");
208 /* print the hkl internals if the test failed */
209 fprintf(stderr
, "\n expected : ");
210 for(uint j
=0; j
<n_pseudo_axes
; ++j
)
211 fprintf(stderr
, " %f", targets
[j
]);
212 fprintf(stderr
, " obtained : ");
213 for(uint j
=0; j
<n_pseudo_axes
; ++j
)
214 fprintf(stderr
, " %f", currents
[j
]);
215 hkl_engine_fprintf(stderr
, engine
);
218 fprintf(stderr
, " ok");
226 static void set(int nb_iter
)
228 ok(TRUE
== TEST_FOREACH_MODE(nb_iter
, _set
), __func__
);
232 static int _pseudo_axis_get(HklEngine
*engine
, HklEngineList
*engine_list
, unsigned int n
)
234 static const char *bad
= "_bad_name_";
235 const darray_string
*pseudo_axes_names
= hkl_engine_pseudo_axes_names_get(engine
);
236 const char **pseudo_axis_name
;
237 const HklParameter
*pseudo_axis
;
241 darray_foreach(pseudo_axis_name
, *pseudo_axes_names
){
242 pseudo_axis
= hkl_engine_pseudo_axis_get(engine
, *pseudo_axis_name
, NULL
);
243 res
&= DIAG(NULL
!= pseudo_axis
);
246 pseudo_axis
= hkl_engine_pseudo_axis_get(engine
, *pseudo_axis_name
, &error
);
247 res
&= DIAG(NULL
!= pseudo_axis
);
248 res
&= DIAG(NULL
== error
);
252 pseudo_axis
= hkl_engine_pseudo_axis_get(engine
, bad
, NULL
);
253 res
&= DIAG(NULL
== pseudo_axis
);
256 pseudo_axis
= hkl_engine_pseudo_axis_get(engine
, bad
, &error
);
257 res
&= DIAG(NULL
== pseudo_axis
);
258 res
&= DIAG(error
!= NULL
);
259 g_clear_error(&error
);
264 static void pseudo_axis_get(void)
266 ok(TRUE
== TEST(1, _pseudo_axis_get
), __func__
);
269 static int _capabilities(HklEngine
*engine
, HklEngineList
*engine_list
, unsigned int n
)
272 const unsigned long capabilities
= hkl_engine_capabilities_get(engine
);
274 /* all motors must have the read/write capabilities */
275 res
&= DIAG((capabilities
& HKL_ENGINE_CAPABILITIES_READABLE
) != 0);
276 res
&= DIAG((capabilities
& HKL_ENGINE_CAPABILITIES_WRITABLE
) != 0);
278 /* all psi engines must be initialisable */
279 if(!strcmp("psi", hkl_engine_name_get(engine
)))
280 res
&= DIAG((capabilities
& HKL_ENGINE_CAPABILITIES_INITIALIZABLE
) != 0);
285 static void capabilities(void)
287 ok(TRUE
== TEST_FOREACH_MODE(1, _capabilities
), __func__
);
290 static int _initialized(HklEngine
*engine
, HklEngineList
*engine_list
, unsigned int n
)
293 GError
*error
= NULL
;
294 const unsigned long capabilities
= hkl_engine_capabilities_get(engine
);
296 if(HKL_ENGINE_CAPABILITIES_INITIALIZABLE
& capabilities
){
299 res
&= DIAG(TRUE
== hkl_engine_initialized_set(engine
, FALSE
, NULL
));
300 res
&= DIAG(FALSE
== hkl_engine_initialized_get(engine
));
301 tmp
= hkl_engine_initialized_set(engine
, TRUE
, NULL
);
302 res
&= DIAG(tmp
== hkl_engine_initialized_get(engine
));
304 res
&= DIAG(TRUE
== hkl_engine_initialized_set(engine
, FALSE
, &error
));
305 res
&= DIAG(FALSE
== hkl_engine_initialized_get(engine
));
306 res
&= DIAG(NULL
== error
);
307 tmp
= hkl_engine_initialized_set(engine
, TRUE
, &error
);
308 res
&= DIAG(tmp
== hkl_engine_initialized_get(engine
));
310 res
&= DIAG(NULL
== error
);
312 res
&= DIAG(NULL
!= error
);
313 g_clear_error(&error
);
316 /* non-initializable engine should not produce an error */
317 res
&= DIAG(TRUE
== hkl_engine_initialized_get(engine
));
318 res
&= DIAG(TRUE
== hkl_engine_initialized_set(engine
, TRUE
, NULL
));
319 res
&= DIAG(TRUE
== hkl_engine_initialized_get(engine
));
320 res
&= DIAG(TRUE
== hkl_engine_initialized_set(engine
, FALSE
, NULL
));
321 res
&= DIAG(TRUE
== hkl_engine_initialized_get(engine
));
323 res
&= DIAG(TRUE
== hkl_engine_initialized_set(engine
, TRUE
, &error
));
324 res
&= DIAG(TRUE
== hkl_engine_initialized_get(engine
));
325 res
&= DIAG(NULL
== error
);
326 res
&= DIAG(TRUE
== hkl_engine_initialized_set(engine
, FALSE
, &error
));
327 res
&= DIAG(TRUE
== hkl_engine_initialized_get(engine
));
328 res
&= DIAG(NULL
== error
);
334 static void initialized(void)
336 ok(TRUE
== TEST_FOREACH_MODE(1, _initialized
), __func__
);
339 HKLAPI
int hkl_engine_initialized_set(HklEngine
*self
, int initialized
,
340 GError
**error
) HKL_ARG_NONNULL(1) HKL_WARN_UNUSED_RESULT
;
342 static int _modes(HklEngine
*engine
, HklEngineList
*engine_list
, unsigned int n
)
344 static const char *bad
= "__bad_mode_name__";
347 const darray_string
*modes
;
349 const char *current_mode
;
350 GError
*error
= NULL
;
352 modes
= hkl_engine_modes_names_get(engine
);
354 /* check that the current mode is available in the mode list. */
355 current_mode
= hkl_engine_current_mode_get(engine
);
357 darray_foreach(mode
, *modes
){
358 if(!strcmp(current_mode
, *mode
))
361 res
&= DIAG(TRUE
== ok
);
363 /* check that all modes can be set */
364 darray_foreach(mode
, *modes
){
365 res
&= DIAG(TRUE
== hkl_engine_current_mode_set(engine
, *mode
, NULL
));
367 res
&= DIAG(TRUE
== hkl_engine_current_mode_set(engine
, *mode
, &error
));
368 res
&= DIAG(NULL
== error
);
371 /* check for bad mode name */
372 res
&= DIAG(FALSE
== hkl_engine_current_mode_set(engine
, bad
, NULL
));
374 res
&= DIAG(FALSE
== hkl_engine_current_mode_set(engine
, bad
, &error
));
375 res
&= DIAG(NULL
!= error
);
376 g_clear_error(&error
);
381 static void modes(void)
383 ok(TRUE
== TEST(1, _modes
), __func__
);
386 static int _check_axes(const darray_string
*axes
, const darray_string
*refs
)
392 darray_foreach(axis
, *axes
){
393 darray_foreach(ref
, *refs
){
394 if(!strcmp(*axis
, *ref
))
404 static int _axes_names(HklEngine
*engine
, HklEngineList
*engine_list
, unsigned int n
)
407 HklGeometry
*geometry
;
408 const darray_string
*all_axes
;
409 const darray_string
*axes_r
;
410 const darray_string
*axes_w
;
412 geometry
= hkl_engine_list_geometry_get(engine_list
);
413 all_axes
= hkl_geometry_axes_names_get(geometry
);
415 /* check consistency of the engines, all axes should be in the
416 * list of the geometry axes */
417 axes_r
= hkl_engine_axes_names_get(engine
,
418 HKL_ENGINE_AXES_NAMES_GET_READ
);
420 axes_w
= hkl_engine_axes_names_get(engine
,
421 HKL_ENGINE_AXES_NAMES_GET_WRITE
);
423 res
&= DIAG(axes_r
!= NULL
);
424 res
&= DIAG(axes_w
!= NULL
);
425 res
&= DIAG(_check_axes(axes_r
, all_axes
));
426 res
&= DIAG(_check_axes(axes_w
, all_axes
));
429 static void axes_names(void)
431 ok(TRUE
== TEST_FOREACH_MODE(1, _axes_names
), __func__
);
436 static int _parameters(HklEngine
*engine
, HklEngineList
*engine_list
, unsigned int n
)
438 static const char *bad
= "__bad_parameer_name__";
440 GError
*error
= NULL
;
441 const char **parameter
;
442 const darray_string
*parameters
= hkl_engine_parameters_names_get(engine
);
443 const HklParameter
*param
;
444 int n_values
= darray_size(*parameters
);
445 double values
[n_values
];
447 /* can not get a bad parameter */
448 param
= hkl_engine_parameter_get(engine
, bad
, NULL
);
449 res
&= DIAG(NULL
== param
);
451 param
= hkl_engine_parameter_get(engine
, bad
, &error
);
452 res
&= DIAG(NULL
== param
);
453 res
&= DIAG(NULL
!= error
);
454 g_clear_error(&error
);
456 /* it is possible to get and set all the parameters */
457 darray_foreach(parameter
, *parameters
){
459 param
= hkl_engine_parameter_get(engine
, *parameter
, NULL
);
460 res
&= DIAG(NULL
!= param
);
462 param
= hkl_engine_parameter_get(engine
, *parameter
, &error
);
463 res
&= DIAG(NULL
!= param
);
464 res
&= DIAG(NULL
== error
);
467 res
&= DIAG(TRUE
== hkl_engine_parameter_set(engine
, *parameter
, param
, NULL
));
468 res
&= DIAG(TRUE
== hkl_engine_parameter_set(engine
, *parameter
, param
, &error
));
469 res
&= DIAG(NULL
== error
);
471 res
&= DIAG(FALSE
== hkl_engine_parameter_set(engine
, bad
, param
, &error
));
472 res
&= DIAG(NULL
!= error
);
473 g_clear_error(&error
);
476 hkl_engine_parameters_values_get(engine
, values
, n_values
, HKL_UNIT_USER
);
478 res
&= DIAG(TRUE
== hkl_engine_parameters_values_set(engine
, values
, n_values
, HKL_UNIT_DEFAULT
, NULL
));
479 res
&= DIAG(TRUE
== hkl_engine_parameters_values_set(engine
, values
, n_values
, HKL_UNIT_DEFAULT
, &error
));
480 res
&= DIAG(NULL
== error
);
482 res
&= DIAG(TRUE
== hkl_engine_parameters_values_set(engine
, values
, n_values
, HKL_UNIT_USER
, NULL
));
483 res
&= DIAG(TRUE
== hkl_engine_parameters_values_set(engine
, values
, n_values
, HKL_UNIT_USER
, &error
));
484 res
&= DIAG(NULL
== error
);
489 static void parameters(void)
491 ok(TRUE
== TEST_FOREACH_MODE(1, _parameters
), __func__
);
495 int main(int argc
, char** argv
)