BOROSOFTWAREAll work →
scantool/diag_test.c 216 lines
1/*
2 * freediag - Vehicle Diagnostic Utility
3 *
4 *
5 * Copyright (C) 2017 fenugrec
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 *************************************************************************
22 *
23 * Diag library test harness
24 * This is a stand-alone program !
25 * Designed to exercise code paths not easy to test through the .ini-based testsuite.
26 */
27
28#include <signal.h>
29#include <stdlib.h>
30#include <string.h>
31
32#include "diag.h"
33#include "diag_err.h"
34#include "diag_os.h"
35#include "diag_l0.h"
36#include "diag_l1.h"
37#include "diag_l2.h"
38
39struct test_item {
40 const char *name;
41 bool (*testfunc)(void);
42};
43
44bool test_dupmsg(void);
45bool test_periodic(void);
46
47static struct test_item test_list[] = {
48 {"msg duplication", test_dupmsg},
49 {"periodic timers", test_periodic}
50};
51
52bool test_dupmsg(void) {
53 struct diag_msg *msg0, *msg1, *msg2;
54 struct diag_msg *newchain;
55
56 msg0 = diag_allocmsg(1);
57 msg1 = diag_allocmsg(1);
58 msg2 = diag_allocmsg(1);
59
60 if (!msg0 || !msg1 || !msg2) {
61 printf("alloc err\n");
62 return 0;
63 }
64
65 msg0->next = msg1;
66 msg1->next = msg2;
67 msg1->rxtime = 1;
68 msg2->rxtime = 2;
69
70 newchain = diag_dupmsg(msg0);
71
72 if ((newchain->rxtime != 0) ||
73 (newchain->next->rxtime != 1) ||
74 (newchain->next->next->rxtime != 2)) {
75 printf("chain data / order mismatch\n");
76 return 0;
77 }
78 diag_freemsg(msg0);
79 diag_freemsg(newchain);
80 return 1;
81}
82
83/********** construct a dummy L0 driver */
84int d0_init(void) {
85 return 0;
86}
87int d0_new(struct diag_l0_device *dl0d) {
88 (void) dl0d;
89 return 0;
90}
91struct cfgi *d0_getcfg(struct diag_l0_device *dl0d) {
92 (void) dl0d;
93 return NULL;
94}
95void d0_del(struct diag_l0_device *dl0d) {
96 (void) dl0d;
97}
98int d0_open(struct diag_l0_device *dl0d, int l1_proto) {
99 (void) dl0d;
100 (void) l1_proto;
101 return 0;
102}
103void d0_close(struct diag_l0_device *dl0d) {
104 (void) dl0d;
105}
106uint32_t d0_getflags(struct diag_l0_device *dl0d) {
107 (void) dl0d;
108 return 0;
109}
110int d0_recv(struct diag_l0_device *dl0d, void *data, size_t len, unsigned int timeout) {
111 (void) dl0d;
112 (void) data;
113 (void) len;
114 (void) timeout;
115 return 0;
116}
117int d0_send(struct diag_l0_device *dl0d, const void *data, size_t len) {
118 (void) dl0d;
119 (void) data;
120 (void) len;
121 return 0;
122}
123int d0_ioctl(struct diag_l0_device *dl0d, unsigned cmd, void *data) {
124 (void) dl0d;
125 (void) cmd;
126 (void) data;
127 return 0;
128}
129
130static struct diag_l0 dummy_dl0 = {
131 .longname = "dummy L0",
132 .shortname = "dummy L0",
133 .l1proto_mask = -1, //support everything
134 .init = d0_init,
135 ._new = d0_new,
136 ._getcfg = d0_getcfg,
137 ._del = d0_del,
138 ._open = d0_open,
139 ._close = d0_close,
140 ._getflags = d0_getflags,
141 ._recv = d0_recv,
142 ._send = d0_send,
143 ._ioctl = d0_ioctl
144};
145
146#define TEST_PERIODIC_DURATION 800 //in ms
147/** periodic callback test
148 * Start an L2, let the periodic timer run a few times, then stop
149 */
150bool test_periodic(void) {
151 struct diag_l0_device dl0d = {
152 .dl0 = &dummy_dl0
153 };
154 struct diag_l2_conn *dl2c;
155 unsigned long ts;
156
157 if (diag_l2_open(&dl0d, DIAG_L1_RAW)) {
158 printf("dl2open err\n");
159 return 0;
160 }
161
162 ts = diag_os_getms() + TEST_PERIODIC_DURATION; //anticipated endtime
163
164 dl2c = diag_l2_StartCommunications(&dl0d, DIAG_L2_PROT_TEST, 0, 0, 0, 0);
165 if (dl2c == NULL) {
166 printf("startcomm err\n");
167 diag_l2_close(&dl0d);
168 return 0;
169 }
170 dl2c->tinterval = 0; //force timer expiry on every timer callback
171 while (diag_os_getms() < ts) {}
172
173 diag_l2_StopCommunications(dl2c);
174 diag_l2_close(&dl0d);
175 return 1;
176}
177
178/** ret 1 if success */
179static bool run_tests(void) {
180 bool rv = 1;
181 unsigned i;
182
183 for (i=0; i < ARRAY_SIZE(test_list); i++) {
184 printf("Testing %s:\t", test_list[i].name);
185 if (!test_list[i].testfunc()) {
186 rv = 0;
187 printf("failed\n");
188 } else {
189 printf("ok\n");
190 }
191 }
192
193 return rv;
194}
195
196
197int main(int argc, char **argv) {
198 bool rv;
199 (void) argc;
200 (void) argv;
201
202 if (diag_init()) {
203 printf("error in initialization\n");
204 return 0;
205 }
206
207 rv = run_tests();
208
209 (void) diag_end();
210
211 if (!rv) {
212 return -1;
213 }
214 return 0;
215}
216