Skip to content

Commit 671feb5

Browse files
committed
FW-1087: provide wirefilter.h C header file and add ffi-ctests crate
This new crate is here to provide a set of C based tests that will serve two purposes: * Provide some examples how to use the FFI bindings * Test that those bindings are actually working as intended Internally, it relies on ffi-ctests/ctests/tests.c file which contains tests written in C and that is compiled at cargo configuration time through the use of a build.rs file. This produces a wirefilter_ffi_ctests.so shared library that is later used in the ffi-ctests/ctests/src/lib.rs file to call the different tests functions. All of this is done in order to try to integrate somehow properly with cargo test.
1 parent c449e9c commit 671feb5

File tree

9 files changed

+478
-0
lines changed

9 files changed

+478
-0
lines changed

Cargo.lock

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
members = [
33
"engine",
44
"ffi",
5+
"ffi-ctests",
56
"wasm",
67
]
78

ffi-ctests/Cargo.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[package]
2+
authors = ["Elie ROUDNINSKI <[email protected]>"]
3+
name = "wirefilter-ffi-ctests"
4+
version = "0.1.0"
5+
description = "C based tests for FFI bindings of the Wirefilter engine"
6+
publish = false
7+
8+
[dependencies]
9+
10+
[build-dependencies]
11+
cmake = "0.1"
12+
wirefilter-ffi = {"path"= "../ffi"}

ffi-ctests/build.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
extern crate cmake;
2+
3+
fn main() {
4+
let dst = cmake::build("ctests");
5+
6+
println!("cargo:rustc-link-search=native={}/lib", dst.display());
7+
println!("cargo:rustc-link-lib=dylib=wirefilter_ffi_ctests");
8+
}

ffi-ctests/ctests/CMakeLists.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
cmake_minimum_required(VERSION 3.2)
2+
project(wirefilter-ffi-ctests)
3+
4+
include_directories($ENV{CARGO_MANIFEST_DIR}/../ffi/include)
5+
link_directories($ENV{OUT_DIR}/../../../deps)
6+
7+
add_library(wirefilter_ffi_ctests SHARED tests.c)
8+
target_link_libraries(wirefilter_ffi_ctests wirefilter_ffi)
9+
10+
install(
11+
TARGETS wirefilter_ffi_ctests
12+
LIBRARY DESTINATION lib
13+
)

ffi-ctests/ctests/tests.c

Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
#include <stdlib.h>
2+
#include <stdbool.h>
3+
#include <string.h>
4+
5+
#include <wirefilter.h>
6+
7+
#define WIREFILTER_STRING(v, s) {(v).data = (const unsigned char *)(s); (v).length = strlen(s);}
8+
9+
bool test_wirefilter_ffi_01() {
10+
wirefilter_Scheme *scheme = wirefilter_create_scheme();
11+
if(!scheme) {
12+
return false;
13+
}
14+
wirefilter_free_scheme(scheme);
15+
return true;
16+
}
17+
18+
bool test_wirefilter_ffi_02() {
19+
wirefilter_Scheme *scheme = wirefilter_create_scheme();
20+
if(!scheme) {
21+
return false;
22+
}
23+
24+
wirefilter_ExternallyAllocatedStr field;
25+
26+
WIREFILTER_STRING(field, "http.host");
27+
wirefilter_add_type_field_to_scheme(scheme, field, wirefilter_Bytes);
28+
WIREFILTER_STRING(field, "ip.addr");
29+
wirefilter_add_type_field_to_scheme(scheme, field, wirefilter_Ip);
30+
WIREFILTER_STRING(field, "ssl");
31+
wirefilter_add_type_field_to_scheme(scheme, field, wirefilter_Bool);
32+
WIREFILTER_STRING(field, "tcp.port");
33+
wirefilter_add_type_field_to_scheme(scheme, field, wirefilter_Int);
34+
35+
wirefilter_free_scheme(scheme);
36+
return true;
37+
}
38+
39+
bool test_wirefilter_ffi_03() {
40+
wirefilter_Scheme *scheme = wirefilter_create_scheme();
41+
if(!scheme) {
42+
return false;
43+
}
44+
45+
wirefilter_ExternallyAllocatedStr field, filter_str;
46+
47+
WIREFILTER_STRING(field, "http.host");
48+
wirefilter_add_type_field_to_scheme(scheme, field, wirefilter_Bytes);
49+
WIREFILTER_STRING(field, "ip.addr");
50+
wirefilter_add_type_field_to_scheme(scheme, field, wirefilter_Ip);
51+
WIREFILTER_STRING(field, "ssl");
52+
wirefilter_add_type_field_to_scheme(scheme, field, wirefilter_Bool);
53+
WIREFILTER_STRING(field, "tcp.port");
54+
wirefilter_add_type_field_to_scheme(scheme, field, wirefilter_Int);
55+
56+
WIREFILTER_STRING(filter_str, "tcp.port == 80");
57+
wirefilter_ParsingResult result = wirefilter_parse_filter(scheme, filter_str);
58+
59+
if(!result.success) {
60+
return false;
61+
}
62+
63+
if(!result.ok.ast) {
64+
return false;
65+
}
66+
67+
wirefilter_free_parsing_result(result);
68+
69+
wirefilter_free_scheme(scheme);
70+
return true;
71+
}
72+
73+
bool test_wirefilter_ffi_04() {
74+
wirefilter_Scheme *scheme = wirefilter_create_scheme();
75+
if(!scheme) {
76+
return false;
77+
}
78+
79+
wirefilter_ExternallyAllocatedStr field, filter_str;
80+
81+
WIREFILTER_STRING(field, "http.host");
82+
wirefilter_add_type_field_to_scheme(scheme, field, wirefilter_Bytes);
83+
WIREFILTER_STRING(field, "ip.addr");
84+
wirefilter_add_type_field_to_scheme(scheme, field, wirefilter_Ip);
85+
WIREFILTER_STRING(field, "ssl");
86+
wirefilter_add_type_field_to_scheme(scheme, field, wirefilter_Bool);
87+
WIREFILTER_STRING(field, "tcp.port");
88+
wirefilter_add_type_field_to_scheme(scheme, field, wirefilter_Int);
89+
90+
WIREFILTER_STRING(filter_str, "tcp.port == \"wirefilter\"");
91+
wirefilter_ParsingResult result = wirefilter_parse_filter(scheme, filter_str);
92+
93+
if(result.success) {
94+
return false;
95+
}
96+
97+
if(!result.err.msg.data || result.err.msg.length <= 0) {
98+
return false;
99+
}
100+
101+
wirefilter_free_parsing_result(result);
102+
103+
wirefilter_free_scheme(scheme);
104+
return true;
105+
}
106+
107+
bool test_wirefilter_ffi_05() {
108+
wirefilter_Scheme *scheme = wirefilter_create_scheme();
109+
if(!scheme) {
110+
return false;
111+
}
112+
113+
wirefilter_ExternallyAllocatedStr field, filter_str;
114+
115+
WIREFILTER_STRING(field, "http.host");
116+
wirefilter_add_type_field_to_scheme(scheme, field, wirefilter_Bytes);
117+
WIREFILTER_STRING(field, "ip.addr");
118+
wirefilter_add_type_field_to_scheme(scheme, field, wirefilter_Ip);
119+
WIREFILTER_STRING(field, "ssl");
120+
wirefilter_add_type_field_to_scheme(scheme, field, wirefilter_Bool);
121+
WIREFILTER_STRING(field, "tcp.port");
122+
wirefilter_add_type_field_to_scheme(scheme, field, wirefilter_Int);
123+
124+
WIREFILTER_STRING(filter_str, "tcp.port == 80");
125+
wirefilter_ParsingResult result = wirefilter_parse_filter(scheme, filter_str);
126+
127+
if(!result.success) {
128+
return false;
129+
}
130+
131+
if(!result.ok.ast) {
132+
return false;
133+
}
134+
135+
wirefilter_Filter *filter = wirefilter_compile_filter(result.ok.ast);
136+
if(!filter) {
137+
return false;
138+
}
139+
140+
wirefilter_free_compiled_filter(filter);
141+
142+
wirefilter_free_scheme(scheme);
143+
return true;
144+
}
145+
146+
bool test_wirefilter_ffi_06() {
147+
wirefilter_Scheme *scheme = wirefilter_create_scheme();
148+
if(!scheme) {
149+
return false;
150+
}
151+
152+
wirefilter_ExecutionContext *exec_ctx = wirefilter_create_execution_context(scheme);
153+
if(!exec_ctx) {
154+
return false;
155+
}
156+
157+
wirefilter_free_execution_context(exec_ctx);
158+
159+
wirefilter_free_scheme(scheme);
160+
return true;
161+
}
162+
163+
bool test_wirefilter_ffi_07() {
164+
wirefilter_Scheme *scheme = wirefilter_create_scheme();
165+
if(!scheme) {
166+
return false;
167+
}
168+
169+
wirefilter_ExternallyAllocatedStr field;
170+
171+
WIREFILTER_STRING(field, "http.host");
172+
wirefilter_add_type_field_to_scheme(scheme, field, wirefilter_Bytes);
173+
WIREFILTER_STRING(field, "ip.addr");
174+
wirefilter_add_type_field_to_scheme(scheme, field, wirefilter_Ip);
175+
WIREFILTER_STRING(field, "ssl");
176+
wirefilter_add_type_field_to_scheme(scheme, field, wirefilter_Bool);
177+
WIREFILTER_STRING(field, "tcp.port");
178+
wirefilter_add_type_field_to_scheme(scheme, field, wirefilter_Int);
179+
180+
wirefilter_ExecutionContext *exec_ctx = wirefilter_create_execution_context(scheme);
181+
if(!exec_ctx) {
182+
return false;
183+
}
184+
185+
WIREFILTER_STRING(field, "http.host");
186+
wirefilter_ExternallyAllocatedByteArr http_host;
187+
WIREFILTER_STRING(http_host, "www.cloudflare.com")
188+
wirefilter_add_bytes_value_to_execution_context(exec_ctx, field, http_host);
189+
190+
WIREFILTER_STRING(field, "ip.addr");
191+
uint8_t ip_addr[4] = {192, 168, 0, 1};
192+
wirefilter_add_ipv4_value_to_execution_context(exec_ctx, field, ip_addr);
193+
194+
WIREFILTER_STRING(field, "ssl");
195+
wirefilter_add_bool_value_to_execution_context(exec_ctx, field, false);
196+
197+
WIREFILTER_STRING(field, "tcp.port");
198+
wirefilter_add_int_value_to_execution_context(exec_ctx, field, 80);
199+
200+
wirefilter_free_execution_context(exec_ctx);
201+
202+
wirefilter_free_scheme(scheme);
203+
return true;
204+
}
205+
206+
bool test_wirefilter_ffi_08() {
207+
wirefilter_Scheme *scheme = wirefilter_create_scheme();
208+
if(!scheme) {
209+
return false;
210+
}
211+
212+
wirefilter_ExternallyAllocatedStr field;
213+
214+
WIREFILTER_STRING(field, "http.host");
215+
wirefilter_add_type_field_to_scheme(scheme, field, wirefilter_Bytes);
216+
WIREFILTER_STRING(field, "ip.addr");
217+
wirefilter_add_type_field_to_scheme(scheme, field, wirefilter_Ip);
218+
WIREFILTER_STRING(field, "ssl");
219+
wirefilter_add_type_field_to_scheme(scheme, field, wirefilter_Bool);
220+
WIREFILTER_STRING(field, "tcp.port");
221+
wirefilter_add_type_field_to_scheme(scheme, field, wirefilter_Int);
222+
223+
wirefilter_ExternallyAllocatedStr filter_str;
224+
WIREFILTER_STRING(filter_str, "tcp.port == 80");
225+
wirefilter_ParsingResult result = wirefilter_parse_filter(scheme, filter_str);
226+
227+
if(!result.success) {
228+
return false;
229+
}
230+
231+
if(!result.ok.ast) {
232+
return false;
233+
}
234+
235+
wirefilter_Filter *filter = wirefilter_compile_filter(result.ok.ast);
236+
if(!filter) {
237+
return false;
238+
}
239+
240+
wirefilter_ExecutionContext *exec_ctx = wirefilter_create_execution_context(scheme);
241+
if(!exec_ctx) {
242+
return false;
243+
}
244+
245+
WIREFILTER_STRING(field, "http.host");
246+
wirefilter_ExternallyAllocatedByteArr http_host;
247+
WIREFILTER_STRING(http_host, "www.cloudflare.com")
248+
wirefilter_add_bytes_value_to_execution_context(exec_ctx, field, http_host);
249+
250+
WIREFILTER_STRING(field, "ip.addr");
251+
uint8_t ip_addr[4] = {192, 168, 0, 1};
252+
wirefilter_add_ipv4_value_to_execution_context(exec_ctx, field, ip_addr);
253+
254+
WIREFILTER_STRING(field, "ssl");
255+
wirefilter_add_bool_value_to_execution_context(exec_ctx, field, false);
256+
257+
WIREFILTER_STRING(field, "tcp.port");
258+
wirefilter_add_int_value_to_execution_context(exec_ctx, field, 80);
259+
260+
if(!wirefilter_match(filter, exec_ctx)) {
261+
return false;
262+
}
263+
264+
wirefilter_free_execution_context(exec_ctx);
265+
266+
wirefilter_free_compiled_filter(filter);
267+
268+
wirefilter_free_scheme(scheme);
269+
return true;
270+
}

ffi-ctests/src/lib.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#[test]
2+
fn test() {
3+
#[link(name = "wirefilter_ffi_ctests")]
4+
extern "C" {
5+
fn test_wirefilter_ffi_01() -> bool;
6+
fn test_wirefilter_ffi_02() -> bool;
7+
fn test_wirefilter_ffi_03() -> bool;
8+
fn test_wirefilter_ffi_04() -> bool;
9+
fn test_wirefilter_ffi_05() -> bool;
10+
fn test_wirefilter_ffi_06() -> bool;
11+
fn test_wirefilter_ffi_07() -> bool;
12+
fn test_wirefilter_ffi_08() -> bool;
13+
}
14+
15+
assert!(unsafe { test_wirefilter_ffi_01() });
16+
17+
assert!(unsafe { test_wirefilter_ffi_02() });
18+
19+
assert!(unsafe { test_wirefilter_ffi_03() });
20+
21+
assert!(unsafe { test_wirefilter_ffi_04() });
22+
23+
assert!(unsafe { test_wirefilter_ffi_05() });
24+
25+
assert!(unsafe { test_wirefilter_ffi_06() });
26+
27+
assert!(unsafe { test_wirefilter_ffi_07() });
28+
29+
assert!(unsafe { test_wirefilter_ffi_08() });
30+
}

0 commit comments

Comments
 (0)