Skip to content

Commit 448873b

Browse files
committed
tests: iio_attr_gencode with fixes
Replaced sprintf with snprintf to prevent buffer overflows Added NULL checks for attr_name, dev_name, ch_name Fixed indentation to tabs from spaces Removed function declaration from top and moved TEST_FUNCTION definition below helper functions Updated function names in order to match the other tests naming Added pointer validation with TEST_ASSERT_PTR_NOT_NULL The tests cover: C and Python code generation for all attribute types, except buffer Builds and runs C code If some attributes can't be found we skip them and display while in debug There is one other thing left to cover: Buffer attributes Should be implemented when a when a final buffer API is established Signed-off-by: Marius Lucacel <marius.lucacel@analog.com>
1 parent bd3e1d0 commit 448873b

File tree

1 file changed

+172
-162
lines changed

1 file changed

+172
-162
lines changed

tests/api/test_iio_attr_gencode.c

Lines changed: 172 additions & 162 deletions
Original file line numberDiff line numberDiff line change
@@ -15,204 +15,214 @@
1515
#include <sys/stat.h>
1616
#include <unistd.h>
1717

18-
19-
static void test_code_generation(const char *test_name, const char *iio_args, const char *file_base);
20-
static void test_code_building(const char *test_name, const char *file_base);
2118
static struct iio_context *test_ctx = NULL;
2219

2320
static void setup_test_context(void)
2421
{
25-
if (!test_ctx) {
26-
test_ctx = create_test_context("TESTS_API_URI", "local:", NULL);
27-
if (iio_err(test_ctx)) {
28-
test_ctx = NULL;
29-
}
30-
}
22+
if (!test_ctx) {
23+
test_ctx = create_test_context("TESTS_API_URI", "local:", NULL);
24+
if (iio_err(test_ctx)) {
25+
test_ctx = NULL;
26+
}
27+
}
3128
}
3229

3330
static const char* get_test_uri(void)
3431
{
35-
if (!test_ctx) return "local:";
36-
const struct iio_attr *uri_attr = iio_context_find_attr(test_ctx, "uri");
37-
return uri_attr ? iio_attr_get_static_value(uri_attr) : "local:";
32+
if (!test_ctx) return "local:";
33+
const struct iio_attr *uri_attr = iio_context_find_attr(test_ctx, "uri");
34+
return uri_attr ? iio_attr_get_static_value(uri_attr) : "local:";
3835
}
3936

4037
static void cleanup_test_context(void)
4138
{
42-
if (test_ctx && !iio_err(test_ctx)) {
43-
iio_context_destroy(test_ctx);
44-
test_ctx = NULL;
45-
}
39+
if (test_ctx && !iio_err(test_ctx)) {
40+
iio_context_destroy(test_ctx);
41+
test_ctx = NULL;
42+
}
4643
}
4744

4845
static void cleanup_generated_files(void)
4946
{
50-
system("rm -rf generated_files/");
47+
system("rm -rf generated_files/");
5148
}
5249

5350
static int create_generated_files_dir(void)
5451
{
55-
struct stat st = {0};
56-
if (stat("generated_files", &st) == -1) {
57-
if (mkdir("generated_files", 0755) != 0) {
58-
DEBUG_PRINT(" ERROR: Failed to create directory 'generated_files'\n");
59-
return -1;
60-
}
61-
}
62-
return 0;
52+
struct stat st = {0};
53+
if (stat("generated_files", &st) == -1) {
54+
if (mkdir("generated_files", 0755) != 0) {
55+
DEBUG_PRINT(" ERROR: Failed to create directory 'generated_files'\n");
56+
return -1;
57+
}
58+
}
59+
return 0;
6360
}
6461

65-
TEST_FUNCTION(find_and_test_all_attributes)
62+
static void generate_code(const char *test_name, const char *iio_args, const char *file_base)
6663
{
67-
setup_test_context();
64+
if (create_generated_files_dir() != 0) {
65+
return;
66+
}
6867

69-
if ( !test_ctx) {
70-
DEBUG_PRINT(" SKIP: No test context available\n");
68+
const char *uri = get_test_uri();
69+
char cmd[512];
70+
71+
/* Test C generation */
72+
snprintf(cmd, sizeof(cmd), "iio_attr -u %s %s -g generated_files/%s.c", uri, iio_args, file_base);
73+
74+
int c_ret = system(cmd);
75+
TEST_ASSERT_EQ(c_ret, 0, "C generation should succeed");
76+
if (c_ret != 0) {
77+
DEBUG_PRINT(" ERROR: Failed to generate C code for %s\n", test_name);
7178
return;
79+
} else {
80+
DEBUG_PRINT(" INFO: Successfully generated C code for %s at generated_files/%s.c\n", test_name, file_base);
7281
}
7382

74-
bool found_context = false, found_device = false, found_channel = false, found_debug = false;
75-
char args[256];
76-
77-
unsigned int nb_devices = iio_context_get_devices_count(test_ctx);
78-
unsigned int nb_ctx_attrs = iio_context_get_attrs_count(test_ctx);
79-
80-
/*Test context attributes*/
81-
if (nb_ctx_attrs > 0) {
82-
const struct iio_attr *attr = iio_context_get_attr(test_ctx, 0);
83-
const char *attr_name = iio_attr_get_name(attr);
84-
sprintf(args, "-C %s", attr_name);
85-
DEBUG_PRINT(" INFO: Found context attribute: %s\n", attr_name);
86-
found_context = true;
87-
test_code_generation("context", args, "test_context");
88-
test_code_building("context", "test_context");
89-
}
90-
91-
92-
for (unsigned int i = 0; i < nb_devices &&
93-
!(found_context && found_device && found_channel && found_debug); i++) {
94-
struct iio_device *dev = iio_context_get_device(test_ctx, i);
95-
const char *dev_name = iio_device_get_name(dev);
96-
97-
98-
/*Test device attributes*/
99-
unsigned int nb_device_attr = iio_device_get_attrs_count(dev);
100-
if (nb_device_attr > 0 && !found_device) {
101-
const struct iio_attr *attr = iio_device_get_attr(dev, 0);
102-
const char *attr_name = iio_attr_get_name(attr);
103-
DEBUG_PRINT(" INFO: Found device attribute: Device:%s, Attr:%s\n", dev_name, attr_name);
104-
char args[256];
105-
sprintf(args, "-d %s %s", dev_name, attr_name);
106-
found_device = true;
107-
test_code_generation("device", args, "test_device");
108-
test_code_building("device", "test_device");
109-
}
110-
111-
/*Test debug attributes*/
112-
unsigned int nb_debug_attr = iio_device_get_debug_attrs_count(dev);
113-
if (nb_debug_attr > 0 && !found_debug) {
114-
const struct iio_attr *attr = iio_device_get_debug_attr(dev, 0);
115-
const char *attr_name = iio_attr_get_name(attr);
116-
DEBUG_PRINT(" INFO: Found debug attribute: Device:%s, Attr:%s\n", dev_name, attr_name);
117-
char args[256];
118-
sprintf(args, "-D %s %s", dev_name, attr_name);
119-
found_debug = true;
120-
test_code_generation("debug", args, "test_debug");
121-
test_code_building("debug", "test_debug");
122-
}
123-
124-
/*Test channel attributes*/
125-
unsigned int nb_channels = iio_device_get_channels_count(dev);
126-
if (nb_channels > 0 && !found_channel) {
127-
for (unsigned int j = 0; j < nb_channels; j++) {
128-
struct iio_channel *ch = iio_device_get_channel(dev, j);
129-
unsigned int nb_channels_attr = iio_channel_get_attrs_count(ch);
130-
131-
if (nb_channels_attr > 0) {
132-
const char *ch_name = iio_channel_get_name(ch)? iio_channel_get_name(ch) : iio_channel_get_id(ch);
133-
const struct iio_attr *attr = iio_channel_get_attr(ch, 0);
134-
const char *attr_name = iio_attr_get_name(attr);
135-
DEBUG_PRINT(" INFO: Found channel attribute: Device:%s, Channel:%s, Attr:%s\n", dev_name, ch_name, attr_name);
136-
char args[256];
137-
sprintf(args, "-c %s %s %s", dev_name, ch_name, attr_name);
138-
found_channel = true;
139-
test_code_generation("channel", args, "test_channel");
140-
test_code_building("channel", "test_channel");
141-
break;
142-
}
143-
}
144-
}
145-
}
83+
/* Test Python generation */
84+
snprintf(cmd, sizeof(cmd), "iio_attr -u %s %s -g generated_files/%s.py", uri, iio_args, file_base);
85+
int py_ret = system(cmd);
86+
TEST_ASSERT_EQ(py_ret, 0, "Python generation should succeed");
87+
if (py_ret != 0) {
88+
DEBUG_PRINT(" ERROR: Failed to generate Python code for %s\n", test_name);
89+
return;
90+
} else {
91+
DEBUG_PRINT(" INFO: Successfully generated Python code for %s at generated_files/%s.py\n", test_name, file_base);
92+
}
14693
}
14794

148-
static void test_code_generation(const char *test_name, const char *iio_args, const char *file_base)
95+
static void build_and_run_code(const char *test_name, const char *file_base)
14996
{
150-
if (create_generated_files_dir() != 0) {
151-
return;
152-
}
153-
154-
const char *uri = get_test_uri();
155-
char cmd[512];
156-
157-
/*Test C generation*/
158-
snprintf(cmd, sizeof(cmd), "iio_attr -u %s %s -g generated_files/%s.c", uri, iio_args, file_base);
159-
160-
int c_ret = system(cmd);
161-
TEST_ASSERT(c_ret == 0, "C generation should succeed");
162-
if(c_ret != 0) {
163-
DEBUG_PRINT(" ERROR: Failed to generate C code for %s\n", test_name);
164-
return;
165-
} else {
166-
DEBUG_PRINT(" INFO: Successfully generated C code for %s at generated_files/%s.c\n", test_name, file_base);
167-
}
168-
169-
/*Test Python generation*/
170-
snprintf(cmd, sizeof(cmd), "iio_attr -u %s %s -g generated_files/%s.py", uri, iio_args, file_base);
171-
int py_ret = system(cmd);
172-
TEST_ASSERT(py_ret == 0, "Python generation should succeed");
173-
if(py_ret != 0) {
174-
DEBUG_PRINT(" ERROR: Failed to generate Python code for %s\n", test_name);
175-
return;
176-
} else {
177-
DEBUG_PRINT(" INFO: Successfully generated Python code for %s at generated_files/%s.py\n", test_name, file_base);
178-
}
179-
// cleanup_generated_files();
97+
char cmd[512];
98+
99+
/* Test C code building */
100+
snprintf(cmd, sizeof(cmd), "gcc -o generated_files/%s_test generated_files/%s.c -liio", file_base, file_base);
101+
int c_ret = system(cmd);
102+
TEST_ASSERT_EQ(c_ret, 0, "Generated C code should compile");
103+
if (c_ret != 0) {
104+
DEBUG_PRINT(" ERROR: Failed to compile generated C code for %s\n", test_name);
105+
106+
} else {
107+
DEBUG_PRINT(" INFO: Successfully compiled generated C code for %s\n", test_name);
108+
struct stat exe_stat;
109+
110+
snprintf(cmd, sizeof(cmd), "./generated_files/%s_test", file_base);
111+
int run_ret = system(cmd);
112+
TEST_ASSERT_EQ(run_ret, 0, "Generated C test should run successfully");
113+
}
180114
}
181115

182-
static void test_code_building(const char *test_name, const char *file_base)
116+
TEST_FUNCTION(iio_attr_code_generation)
183117
{
184-
char cmd[512];
185-
186-
/*Test C code building*/
187-
snprintf(cmd, sizeof(cmd), "gcc -o generated_files/%s_test generated_files/%s.c -liio", file_base, file_base);
188-
int c_ret = system(cmd);
189-
TEST_ASSERT(c_ret == 0, "Generated C code should compile");
190-
if(c_ret != 0) {
191-
DEBUG_PRINT(" ERROR: Failed to compile generated C code for %s\n", test_name);
192-
} else {
193-
DEBUG_PRINT(" INFO: Successfully compiled generated C code for %s\n", test_name);
194-
snprintf(cmd, sizeof(cmd), "./generated_files/%s_test", file_base);
195-
int run_ret = system(cmd);
196-
TEST_ASSERT(run_ret == 0, "Generated C test should run successfully");
197-
}
198-
199-
/*Test Python code building*/
200-
// snprintf(cmd, sizeof(cmd), "cd generated_files && python3 %s.py", file_base);
201-
// int py_ret = system(cmd);
202-
// TEST_ASSERT(py_ret == 0, "Generated Python code should compile");
203-
// if(py_ret != 0) {
204-
// DEBUG_PRINT(" ERROR: Failed to compile generated Python code for %s\n", test_name);
205-
// } else {
206-
// DEBUG_PRINT(" INFO: Successfully compiled generated Python code for %s\n", test_name);
207-
// }
118+
setup_test_context();
119+
if ( !test_ctx) {
120+
DEBUG_PRINT(" SKIP: No test context available\n");
121+
return;
122+
}
123+
124+
bool found_context = false, found_device = false, found_channel = false, found_debug = false;
125+
char args[256];
126+
127+
unsigned int nb_devices = iio_context_get_devices_count(test_ctx);
128+
unsigned int nb_ctx_attrs = iio_context_get_attrs_count(test_ctx);
129+
130+
/* Test context attributes */
131+
if (nb_ctx_attrs > 0 && !found_context) {
132+
const struct iio_attr *attr = iio_context_get_attr(test_ctx, 0);
133+
if (attr) {
134+
const char *attr_name = iio_attr_get_name(attr);
135+
if (attr_name) {
136+
snprintf(args, sizeof(args), "-C %s", attr_name);
137+
DEBUG_PRINT(" INFO: Found context attribute: %s\n", attr_name);
138+
found_context = true;
139+
generate_code("context", args, "test_context");
140+
build_and_run_code("context", "test_context");
141+
}
142+
}
143+
}
144+
145+
for (unsigned int i = 0; i < nb_devices &&
146+
!(found_context && found_device && found_channel && found_debug); i++) {
147+
struct iio_device *dev = iio_context_get_device(test_ctx, i);
148+
TEST_ASSERT_PTR_NOT_NULL(dev, "Device should exist");
149+
const char *dev_name = iio_device_get_name(dev);
150+
if (!dev_name) dev_name = iio_device_get_id(dev);
151+
if (!dev_name) continue;
152+
153+
154+
/* Test device attributes */
155+
unsigned int nb_device_attr = iio_device_get_attrs_count(dev);
156+
if (nb_device_attr > 0 && !found_device) {
157+
const struct iio_attr *attr = iio_device_get_attr(dev, 0);
158+
if (attr) {
159+
const char *attr_name = iio_attr_get_name(attr);
160+
if (attr_name) {
161+
DEBUG_PRINT(" INFO: Found device attribute: Device:%s, Attr:%s\n", dev_name, attr_name);
162+
snprintf(args, sizeof(args), "-d %s %s", dev_name, attr_name);
163+
found_device = true;
164+
generate_code("device", args, "test_device");
165+
build_and_run_code("device", "test_device");
166+
}
167+
}
168+
}
169+
/* Test debug attributes */
170+
unsigned int nb_debug_attr = iio_device_get_debug_attrs_count(dev);
171+
if (nb_debug_attr > 0 && !found_debug) {
172+
const struct iio_attr *attr = iio_device_get_debug_attr(dev, 0);
173+
if (attr) {
174+
const char *attr_name = iio_attr_get_name(attr);
175+
if (attr_name) {
176+
DEBUG_PRINT(" INFO: Found debug attribute: Device:%s, Attr:%s\n", dev_name, attr_name);
177+
snprintf(args, sizeof(args), "-D %s %s", dev_name, attr_name);
178+
found_debug = true;
179+
generate_code("debug", args, "test_debug");
180+
build_and_run_code("debug", "test_debug");
181+
}
182+
}
183+
}
184+
185+
/* Test channel attributes */
186+
unsigned int nb_channels = iio_device_get_channels_count(dev);
187+
if (nb_channels > 0 && !found_channel) {
188+
for (unsigned int j = 0; j < nb_channels; j++) {
189+
struct iio_channel *ch = iio_device_get_channel(dev, j);
190+
TEST_ASSERT_PTR_NOT_NULL(ch, "Channel should exist");
191+
unsigned int nb_channels_attr = iio_channel_get_attrs_count(ch);
192+
193+
if (nb_channels_attr > 0) {
194+
const char *ch_name = iio_channel_get_name(ch);
195+
if (!ch_name) ch_name = iio_channel_get_id(ch);
196+
if (!ch_name) continue;
197+
198+
const struct iio_attr *attr = iio_channel_get_attr(ch, 0);
199+
if (attr) {
200+
const char *attr_name = iio_attr_get_name(attr);
201+
if (attr_name) {
202+
DEBUG_PRINT(" INFO: Found channel attribute: Device:%s, Channel:%s, Attr:%s\n", dev_name, ch_name, attr_name);
203+
snprintf(args, sizeof(args), "-c %s %s %s", dev_name, ch_name, attr_name);
204+
found_channel = true;
205+
generate_code("channel", args, "test_channel");
206+
build_and_run_code("channel", "test_channel");
207+
break;
208+
}
209+
}
210+
}
211+
}
212+
}
213+
}
208214

215+
if (!found_context || !found_device || !found_channel || !found_debug) {
216+
DEBUG_PRINT(" SKIP: Some attribute types not found - gencode not fully tested\n");
217+
}
209218
}
210219

220+
211221
int main(void)
212222
{
213-
RUN_TEST(find_and_test_all_attributes);
214-
cleanup_test_context();
215-
// cleanup_generated_files();
216-
TEST_SUMMARY();
217-
return 0;
223+
RUN_TEST(iio_attr_code_generation);
224+
cleanup_test_context();
225+
cleanup_generated_files();
226+
TEST_SUMMARY();
227+
return 0;
218228
}

0 commit comments

Comments
 (0)