Skip to content

Commit d170a73

Browse files
committed
tests: add unit test for hexagonrpc function
The hexagonrpc function is getting very complex and deserves its own unit test. Add a unit test for the hexagonrpc function. Signed-off-by: Richard Acayan <[email protected]>
1 parent 849e099 commit d170a73

File tree

2 files changed

+180
-0
lines changed

2 files changed

+180
-0
lines changed

tests/meson.build

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,13 @@ test_hexagonfs = executable('test_hexagonfs',
2424
include_directories : include,
2525
)
2626

27+
test_hexagonrpc = executable('test_hexagonrpc',
28+
'test_hexagonrpc.c',
29+
'../libhexagonrpc/hexagonrpc.c',
30+
c_args : cflags,
31+
include_directories : include,
32+
)
33+
2734
test('iobuffer', test_iobuffer)
2835
test('hexagonfs', test_hexagonfs, args : [sample_file])
36+
test('hexagonrpc', test_hexagonrpc)

tests/test_hexagonrpc.c

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
/*
2+
* FastRPC reverse tunnel - tests for virtual filesystem
3+
*
4+
* Copyright (C) 2025 HexagonRPC Contributors
5+
*
6+
* This file is part of HexagonRPC.
7+
*
8+
* HexagonRPC is free software: you can redistribute it and/or modify
9+
* it under the terms of the GNU General Public License as published by
10+
* the Free Software Foundation, either version 3 of the License, or
11+
* (at your option) any later version.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* GNU General Public License for more details.
17+
*
18+
* You should have received a copy of the GNU General Public License
19+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
20+
*/
21+
22+
#define _DEFAULT_SOURCE
23+
24+
#include <libhexagonrpc/hexagonrpc.h>
25+
#include <misc/fastrpc.h>
26+
#include <stdarg.h>
27+
#include <stdint.h>
28+
#include <stdio.h>
29+
#include <string.h>
30+
#include <sys/ioctl.h>
31+
#include <sys/syscall.h>
32+
#include <unistd.h>
33+
34+
struct expected_invoke_arg {
35+
size_t len;
36+
const void *ptr;
37+
};
38+
39+
static const struct expected_invoke_arg *expected = NULL;
40+
static uint32_t expected_sc = 0;
41+
42+
static const uint32_t no_args_sc = REMOTE_SCALARS_MAKE(0, 0, 0);
43+
44+
static const struct hrpc_method_def_interp4 no_args_def = {
45+
.msg_id = 0,
46+
.n_args = 0,
47+
.args = NULL,
48+
.n_inner_types = 0,
49+
.inner_types = NULL,
50+
};
51+
52+
static const char scalar_arg_exp0[] = {
53+
0x67, 0x45, 0x23, 0x01,
54+
0x02, 0x00, 0x00, 0x00,
55+
0x00, 0x00, 0x00, 0x00,
56+
};
57+
58+
static const char scalar_arg_exp1[] = {
59+
'h', 'i',
60+
};
61+
62+
static const struct expected_invoke_arg scalar_arg_exp[] = {
63+
{
64+
.len = sizeof(scalar_arg_exp0),
65+
.ptr = scalar_arg_exp0,
66+
},
67+
{
68+
.len = sizeof(scalar_arg_exp1),
69+
.ptr = scalar_arg_exp1,
70+
},
71+
{
72+
.len = 0,
73+
.ptr = NULL,
74+
},
75+
};
76+
77+
static const uint32_t scalar_arg_sc = REMOTE_SCALARS_MAKE(0, 3, 0);
78+
79+
static const struct hrpc_arg_def_interp4 scalar_arg_args[] = {
80+
{ HRPC_ARG_WORD, sizeof(uint32_t) },
81+
{ HRPC_ARG_BLOB_SEQ, sizeof(char) },
82+
{ HRPC_ARG_BLOB_SEQ, sizeof(char) },
83+
};
84+
85+
static const struct hrpc_method_def_interp4 scalar_arg_def = {
86+
.msg_id = 0,
87+
.n_args = HRPC_ARRAY_SIZE(scalar_arg_args),
88+
.args = scalar_arg_args,
89+
.n_inner_types = 0,
90+
.inner_types = NULL,
91+
};
92+
93+
int ioctl(int fd, unsigned long int op, ...)
94+
{
95+
struct fastrpc_invoke *invoke;
96+
struct fastrpc_invoke_args *args;
97+
size_t i, n_inbufs, n_outbufs;
98+
void *data;
99+
va_list list;
100+
101+
va_start(list, op);
102+
data = va_arg(list, void *);
103+
va_end(list);
104+
105+
if (op != FASTRPC_IOCTL_INVOKE) {
106+
return syscall(SYS_ioctl, fd, op, data);
107+
} else {
108+
invoke = data;
109+
110+
if (fd != -1)
111+
return -1;
112+
113+
if (invoke->handle != 0)
114+
return -1;
115+
116+
if (invoke->sc != expected_sc)
117+
return -1;
118+
119+
n_inbufs = REMOTE_SCALARS_INBUFS(invoke->sc);
120+
n_outbufs = REMOTE_SCALARS_OUTBUFS(invoke->sc);
121+
args = (struct fastrpc_invoke_args *) invoke->args;
122+
123+
for (i = 0; i < n_inbufs; i++) {
124+
if (args[i].fd != -1 || args[i].attr != 0)
125+
return -1;
126+
127+
if (args[i].length != expected[i].len)
128+
return -1;
129+
130+
if (memcmp((void *) args[i].ptr,
131+
expected[i].ptr,
132+
args[i].length))
133+
return -1;
134+
}
135+
136+
for (i = n_inbufs; i < n_inbufs + n_outbufs; i++) {
137+
if (args[i].fd != -1 || args[i].attr != 0)
138+
return -1;
139+
140+
if (args[i].length < expected[i].len)
141+
return -1;
142+
143+
memcpy((void *) args[i].ptr,
144+
expected[i].ptr,
145+
args[i].length);
146+
}
147+
148+
return 0;
149+
}
150+
}
151+
152+
int main(void)
153+
{
154+
int ret, fd = -1;
155+
uint32_t hdl = 0;
156+
157+
expected_sc = no_args_sc;
158+
expected = NULL;
159+
ret = hexagonrpc(&no_args_def, fd, hdl);
160+
if (ret)
161+
return 1;
162+
163+
expected_sc = scalar_arg_sc;
164+
expected = scalar_arg_exp;
165+
ret = hexagonrpc(&scalar_arg_def, fd, hdl,
166+
(uint32_t) 0x01234567,
167+
(uint32_t) 2, (const void *) "hi");
168+
if (ret)
169+
return 1;
170+
171+
return 0;
172+
}

0 commit comments

Comments
 (0)