Skip to content

Commit e69f0e6

Browse files
committed
Add mocks and suggested unit test sequence.
1 parent 32226d8 commit e69f0e6

File tree

6 files changed

+183
-30
lines changed

6 files changed

+183
-30
lines changed

Makefile

+4-3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ THE_PROGRAM = do_toggle
88
TARGET_SYSTEM ?= ${DEFAULT_SYSTEM}
99
ifeq (rpi, ${TARGET_SYSTEM})
1010
MAKE_TARGET = deploy
11+
DEPLOY_COMMAND ?= scp ${THE_PROGRAM} pet-piercer.local:
1112
EXT_TREES_ROOT ?= ${HOME}/Documents/trees
1213
NETBSDSRCDIR ?= ${EXT_TREES_ROOT}/netbsd-src
1314
CROSS_ROOT ?= ${EXT_TREES_ROOT}/rpi
@@ -48,12 +49,12 @@ clean:
4849
${SILENT}rm -rf *.dSYM *.gcda *.gcno *.gcov
4950

5051
deploy: ${THE_PROGRAM}
51-
${SILENT}scp ${THE_PROGRAM} pet-piercer.local:
52+
${SILENT}${DEPLOY_COMMAND}
5253

5354
.PHONY: all check clean deploy
5455

55-
${THE_TESTS}: ${THE_PROGRAM} .has_check ${THE_LIBRARY} check_toggle.c check_toggle_acceptance.c check_toggle_unit.c
56-
${SILENT}${CC} ${CFLAGS} ${CHECK_CFLAGS} -o ${THE_TESTS} check_toggle_acceptance.c check_toggle_unit.c check_toggle.c ${CHECK_LIBS} ${TEST_LIBS} ${THE_LIBRARY}
56+
${THE_TESTS}: ${THE_PROGRAM} .has_check ${THE_LIBRARY} check_toggle.c acceptance.c unit.c
57+
${SILENT}${CC} ${CFLAGS} ${CHECK_CFLAGS} -o ${THE_TESTS} acceptance.c unit.c check_toggle.c ${CHECK_LIBS} ${TEST_LIBS} ${THE_LIBRARY}
5758

5859
${THE_LIBRARY}: led.h led.c syscalls.h ${TARGET_SYSTEM}_syscalls.h ${TARGET_SYSTEM}_syscalls.c
5960
${SILENT}${CC} ${CFLAGS} -c led.c

check_toggle_acceptance.c renamed to acceptance.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22

33
#include "led.h"
44

5-
START_TEST(test_acceptance_nothing) {
6-
ck_assert_int_eq(1, 2);
5+
START_TEST(test_public_interface) {
6+
led_toggle();
77
} END_TEST
88

99
TCase* tcase_acceptance(void) {
1010
TCase *tc = tcase_create("Acceptance Tests");
1111

12-
tcase_add_test(tc, test_acceptance_nothing);
12+
tcase_add_test(tc, test_public_interface);
1313

1414
return tc;
1515
}

check_toggle_unit.c

-24
This file was deleted.

host_syscalls.c

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#include <limits.h>
2+
#include <string.h>
3+
4+
#include "host_syscalls.h"
5+
6+
7+
static struct {
8+
int fake_return_value;
9+
int spy_numcalls;
10+
char spy_path[PATH_MAX];
11+
int spy_oflag;
12+
} mock_open;
13+
14+
void mock_open_fake_return_value(int value) {
15+
mock_open.fake_return_value = value;
16+
}
17+
18+
int mock_open_spy_numcalls() {
19+
return mock_open.spy_numcalls;
20+
}
21+
22+
int mock_open_spy_oflag() {
23+
return mock_open.spy_oflag;
24+
}
25+
26+
const char * mock_open_spy_path() {
27+
return mock_open.spy_path;
28+
}
29+
30+
int open(const char *path, int oflag, ...) {
31+
strcpy(mock_open.spy_path, path);
32+
mock_open.spy_oflag = oflag;
33+
++mock_open.spy_numcalls;
34+
return mock_open.fake_return_value;
35+
}
36+
37+
38+
static struct {
39+
int fake_return_value;
40+
int spy_numcalls;
41+
int spy_fd;
42+
int spy_request;
43+
int spy_pin;
44+
} mock_ioctl;
45+
46+
void mock_ioctl_fake_return_value(int value) {
47+
mock_ioctl.fake_return_value = value;
48+
}
49+
50+
int mock_ioctl_spy_fd() {
51+
return mock_ioctl.spy_fd;
52+
}
53+
54+
int mock_ioctl_spy_numcalls() {
55+
return mock_ioctl.spy_numcalls;
56+
}
57+
58+
int mock_ioctl_spy_request() {
59+
return mock_ioctl.spy_request;
60+
}
61+
62+
int mock_ioctl_spy_pin() {
63+
return mock_ioctl.spy_pin;
64+
}
65+
66+
int ioctl(int fildes, unsigned long request, void *gpio_request) {
67+
(void)fildes;
68+
mock_ioctl.spy_fd = fildes;
69+
mock_ioctl.spy_request = request;
70+
mock_ioctl.spy_pin = ((struct gpio_req *)gpio_request)->gp_pin;
71+
++mock_ioctl.spy_numcalls;
72+
return mock_ioctl.fake_return_value;
73+
}
74+
75+
76+
static struct {
77+
int spy_numcalls;
78+
int spy_fd;
79+
} mock_close;
80+
81+
int mock_close_spy_numcalls() {
82+
return mock_close.spy_numcalls;
83+
}
84+
85+
int mock_close_spy_fd() {
86+
return mock_close.spy_fd;
87+
}
88+
89+
int close(int fildes) {
90+
mock_close.spy_fd = fildes;
91+
++mock_close.spy_numcalls;
92+
return 99;
93+
}
94+
95+
96+
void mock_reset_all() {
97+
memset(&mock_open, 0, sizeof(mock_open));
98+
memset(&mock_ioctl, 0, sizeof(mock_ioctl));
99+
memset(&mock_close, 0, sizeof(mock_close));
100+
}

host_syscalls.h

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
void mock_reset_all(void);
2+
3+
int open(const char *, int, ...);
4+
#define O_WRONLY 77
5+
void mock_open_fake_return_value(int);
6+
int mock_open_spy_numcalls(void);
7+
const char* mock_open_spy_path(void);
8+
int mock_open_spy_oflag(void);
9+
10+
int ioctl(int, unsigned long, void *);
11+
#define GPIOTOGGLE 66
12+
struct gpio_req {
13+
int gp_pin;
14+
};
15+
void mock_ioctl_fake_return_value(int);
16+
int mock_ioctl_spy_numcalls(void);
17+
int mock_ioctl_spy_fd(void);
18+
int mock_ioctl_spy_request(void);
19+
int mock_ioctl_spy_pin(void);
20+
21+
int close(int);
22+
int mock_close_spy_numcalls(void);
23+
int mock_close_spy_fd(void);

unit.c

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#include <check.h>
2+
3+
#include "led.h"
4+
#include "syscalls.h"
5+
6+
START_TEST(it_opens_gpio_device_for_write) {
7+
ck_assert_int_eq(mock_open_spy_numcalls(), 0);
8+
ck_assert_str_eq(mock_open_spy_path(), "");
9+
ck_assert_int_eq(mock_open_spy_oflag(), 0);
10+
11+
led_toggle();
12+
13+
ck_assert_int_eq(mock_open_spy_numcalls(), 1);
14+
ck_assert_str_eq(mock_open_spy_path(), "/dev/gpio0");
15+
ck_assert_int_eq(mock_open_spy_oflag(), O_WRONLY);
16+
} END_TEST
17+
18+
START_TEST(it_stops_if_open_fails) {
19+
} END_TEST
20+
21+
START_TEST(it_calls_ioctl_if_open_succeeds) {
22+
} END_TEST
23+
24+
START_TEST(it_ioctls_gpio_device_to_toggle_our_pin) {
25+
} END_TEST
26+
27+
START_TEST(it_closes_gpio_device_if_ioctl_succeeds) {
28+
} END_TEST
29+
30+
START_TEST(it_closes_gpio_device_if_ioctl_fails) {
31+
} END_TEST
32+
33+
void setup(void) {
34+
mock_reset_all();
35+
}
36+
37+
void teardown(void) {
38+
}
39+
40+
TCase* tcase_unit(void) {
41+
TCase *tc = tcase_create("Unit Tests");
42+
43+
tcase_add_checked_fixture(tc, setup, teardown);
44+
45+
tcase_add_test(tc, it_opens_gpio_device_for_write);
46+
tcase_add_test(tc, it_stops_if_open_fails);
47+
tcase_add_test(tc, it_calls_ioctl_if_open_succeeds);
48+
tcase_add_test(tc, it_ioctls_gpio_device_to_toggle_our_pin);
49+
tcase_add_test(tc, it_closes_gpio_device_if_ioctl_succeeds);
50+
tcase_add_test(tc, it_closes_gpio_device_if_ioctl_fails);
51+
52+
return tc;
53+
}

0 commit comments

Comments
 (0)