1 /*
2  * Copyright (c) 2024 Fabian Blatz <fabianblatz@gmail.com>
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <string.h>
8 
9 #include <zephyr/drivers/stepper.h>
10 #include <zephyr/drivers/stepper/stepper_fake.h>
11 #include <zephyr/fff.h>
12 #include <zephyr/shell/shell.h>
13 #include <zephyr/shell/shell_dummy.h>
14 #include <zephyr/ztest.h>
15 #include <zephyr/sys/util.h>
16 
17 #define FAKE_STEPPER_NAME DEVICE_DT_NAME(DT_NODELABEL(fake_stepper))
18 
19 /* Global variables */
20 static const struct device *const fake_stepper_dev = DEVICE_DT_GET(DT_NODELABEL(fake_stepper));
21 
22 DEFINE_FFF_GLOBALS;
23 
24 #define ASSERT_STEPPER_FUNC_CALLED(stepper_fake_func, retval)                                      \
25 	zassert_ok(retval, "failed to execute shell command (err %d)", retval);                    \
26 	zassert_equal(stepper_fake_func.call_count, 1,                                             \
27 		      STRINGIFY(stepper_fake_func) " function not called");                        \
28 	zassert_equal(stepper_fake_func.arg0_val, fake_stepper_dev, "wrong device pointer")
29 
stepper_shell_setup(void)30 static void *stepper_shell_setup(void)
31 {
32 	const struct shell *sh = shell_backend_dummy_get_ptr();
33 
34 	/* Wait for the initialization of the shell dummy backend. */
35 	WAIT_FOR(shell_ready(sh), 20000, k_msleep(1));
36 	zassert_true(shell_ready(sh), "timed out waiting for dummy shell backend");
37 
38 	return NULL;
39 }
40 
41 ZTEST_SUITE(stepper_shell, NULL, stepper_shell_setup, NULL, NULL, NULL);
42 
ZTEST(stepper_shell,test_stepper_enable)43 ZTEST(stepper_shell, test_stepper_enable)
44 {
45 	const struct shell *sh = shell_backend_dummy_get_ptr();
46 	int err = shell_execute_cmd(sh, "stepper enable " FAKE_STEPPER_NAME " on");
47 
48 	ASSERT_STEPPER_FUNC_CALLED(fake_stepper_enable_fake, err);
49 	zassert_equal(fake_stepper_enable_fake.arg1_val, true, "wrong enable value");
50 
51 	RESET_FAKE(fake_stepper_enable);
52 
53 	err = shell_execute_cmd(sh, "stepper enable " FAKE_STEPPER_NAME " off");
54 	ASSERT_STEPPER_FUNC_CALLED(fake_stepper_enable_fake, err);
55 	zassert_equal(fake_stepper_enable_fake.arg1_val, false, "wrong enable value");
56 }
57 
ZTEST(stepper_shell,test_stepper_move_by)58 ZTEST(stepper_shell, test_stepper_move_by)
59 {
60 	const struct shell *sh = shell_backend_dummy_get_ptr();
61 	int err = shell_execute_cmd(sh, "stepper move_by " FAKE_STEPPER_NAME " 1000");
62 
63 	ASSERT_STEPPER_FUNC_CALLED(fake_stepper_move_by_fake, err);
64 	zassert_equal(fake_stepper_move_by_fake.arg1_val, 1000, "wrong microsteps value");
65 }
66 
ZTEST(stepper_shell,test_stepper_set_max_velocity)67 ZTEST(stepper_shell, test_stepper_set_max_velocity)
68 {
69 	const struct shell *sh = shell_backend_dummy_get_ptr();
70 	int err = shell_execute_cmd(sh, "stepper set_max_velocity " FAKE_STEPPER_NAME " 200");
71 
72 	ASSERT_STEPPER_FUNC_CALLED(fake_stepper_set_max_velocity_fake, err);
73 	zassert_equal(fake_stepper_set_max_velocity_fake.arg1_val, 200, "wrong velocity value");
74 }
75 
ZTEST(stepper_shell,test_stepper_set_micro_step_res)76 ZTEST(stepper_shell, test_stepper_set_micro_step_res)
77 {
78 	const struct shell *sh = shell_backend_dummy_get_ptr();
79 	int err = shell_execute_cmd(sh, "stepper set_micro_step_res " FAKE_STEPPER_NAME " 64");
80 
81 	ASSERT_STEPPER_FUNC_CALLED(fake_stepper_set_micro_step_res_fake, err);
82 	zassert_equal(fake_stepper_set_micro_step_res_fake.arg1_val, 64,
83 		      "wrong micro steps resolution value");
84 }
85 
ZTEST(stepper_shell,test_stepper_set_micro_step_res_invalid_value)86 ZTEST(stepper_shell, test_stepper_set_micro_step_res_invalid_value)
87 {
88 	const struct shell *sh = shell_backend_dummy_get_ptr();
89 	int err = shell_execute_cmd(sh, "stepper set_micro_step_res " FAKE_STEPPER_NAME " 111");
90 
91 	zassert_not_equal(err, 0, " executed set_micro_step_res with invalid micro steps value");
92 }
93 
ZTEST(stepper_shell,test_stepper_get_micro_step_res)94 ZTEST(stepper_shell, test_stepper_get_micro_step_res)
95 {
96 	const struct shell *sh = shell_backend_dummy_get_ptr();
97 	int err = shell_execute_cmd(sh, "stepper get_micro_step_res " FAKE_STEPPER_NAME);
98 
99 	ASSERT_STEPPER_FUNC_CALLED(fake_stepper_get_micro_step_res_fake, err);
100 }
101 
ZTEST(stepper_shell,test_stepper_set_reference_position)102 ZTEST(stepper_shell, test_stepper_set_reference_position)
103 {
104 	const struct shell *sh = shell_backend_dummy_get_ptr();
105 	int err = shell_execute_cmd(sh, "stepper set_reference_position " FAKE_STEPPER_NAME " 100");
106 
107 	ASSERT_STEPPER_FUNC_CALLED(fake_stepper_set_reference_position_fake, err);
108 	zassert_equal(fake_stepper_set_reference_position_fake.arg1_val, 100,
109 		      "wrong actual position value");
110 }
111 
ZTEST(stepper_shell,test_stepper_get_actual_position)112 ZTEST(stepper_shell, test_stepper_get_actual_position)
113 {
114 	const struct shell *sh = shell_backend_dummy_get_ptr();
115 	int err = shell_execute_cmd(sh, "stepper get_actual_position " FAKE_STEPPER_NAME);
116 
117 	ASSERT_STEPPER_FUNC_CALLED(fake_stepper_get_actual_position_fake, err);
118 }
119 
ZTEST(stepper_shell,test_stepper_move_to)120 ZTEST(stepper_shell, test_stepper_move_to)
121 {
122 	const struct shell *sh = shell_backend_dummy_get_ptr();
123 	int err = shell_execute_cmd(sh, "stepper move_to " FAKE_STEPPER_NAME " 200");
124 
125 	ASSERT_STEPPER_FUNC_CALLED(fake_stepper_move_to_fake, err);
126 	zassert_equal(fake_stepper_move_to_fake.arg1_val, 200,
127 		      "wrong target position value");
128 }
129 
ZTEST(stepper_shell,test_stepper_run)130 ZTEST(stepper_shell, test_stepper_run)
131 {
132 	const struct shell *sh = shell_backend_dummy_get_ptr();
133 	int err = shell_execute_cmd(sh, "stepper run " FAKE_STEPPER_NAME " positive 200");
134 
135 	ASSERT_STEPPER_FUNC_CALLED(fake_stepper_run_fake, err);
136 	zassert_equal(fake_stepper_run_fake.arg1_val, STEPPER_DIRECTION_POSITIVE,
137 		      "wrong direction value");
138 	zassert_equal(fake_stepper_run_fake.arg2_val, 200, "wrong velocity value");
139 }
140 
ZTEST(stepper_shell,test_stepper_run_invalid_direction)141 ZTEST(stepper_shell, test_stepper_run_invalid_direction)
142 {
143 	const struct shell *sh = shell_backend_dummy_get_ptr();
144 	int err = shell_execute_cmd(sh, "stepper run " FAKE_STEPPER_NAME " foo 200");
145 
146 	zassert_not_equal(err, 0, " executed run with invalid direction value");
147 }
148 
ZTEST(stepper_shell,test_stepper_info)149 ZTEST(stepper_shell, test_stepper_info)
150 {
151 	const struct shell *sh = shell_backend_dummy_get_ptr();
152 	int err = shell_execute_cmd(sh, "stepper info " FAKE_STEPPER_NAME);
153 
154 	zassert_ok(err, "failed to execute shell command (err %d)", err);
155 
156 	zassert_equal(fake_stepper_is_moving_fake.call_count, 1, "is_moving function not called");
157 	zassert_equal(fake_stepper_get_actual_position_fake.call_count, 1,
158 		      "get_actual_position function not called");
159 	zassert_equal(fake_stepper_get_micro_step_res_fake.call_count, 1,
160 		      "get_micro_step_res function not called");
161 }
162