test: Added simple filter_chain test
[lumina.git] / test / src / test.c
blobfd608858d863c244cc8e8e72a06e3468ccf1bce4
1 #include <errno.h>
2 #include <stdio.h>
3 #include <memory.h>
4 #include <fcntl.h>
5 #include <ev.h>
7 #include <stdlib.h> /* exit, system */
8 #include <unistd.h>
9 #include <sys/types.h>
10 #include <sys/socket.h>
11 #include <netdb.h>
13 /* setrlimit */
14 #include <sys/time.h>
15 #include <sys/resource.h>
17 #include <assert.h> /* assert */
18 #include "core.h"
19 #include "connect_request.h"
20 #include "request.h"
22 #include "data_item.h"
24 #include "filters/filter_chain.h"
26 #if 0
27 void pump_data(output_item *item) {
28 while(output_remaining(item)) {
29 int ret = output_send(item, 1, FDT_PIPE);
30 if(ret < 0) {
31 perror("Failed to send output...");
32 goto err;
35 output_on_complete(item);
36 goto cleanup;
37 err:
38 output_on_error(item, errno);
39 cleanup:
40 output_release(item);
43 void memory_test() {
44 output_item *mem = new_memory_output_item("TEST VALUE\n", strlen("TEST VALUE\n"), 0);
45 pump_data(mem);
48 output_item *new_file_output_item_byname(const char *name) {
49 int fd = open(name, O_RDONLY);
50 if(fd <= 0) {
51 perror("Failed to open file");
52 return NULL;
54 return new_file_output_item(fd);
57 void file_test() {
58 output_item *file = new_file_output_item_byname("premake.lua");
59 pump_data(file);
62 void event_test() {
63 struct ev_loop *loop = ev_default_loop(0);
64 output_hook *hook = new_output_hook();
65 ev_io watcher;
66 /* SET STDOUT to be non-blocking */
67 int flags;
69 output_item *mem = new_memory_output_item("TEST VALUE\n", strlen("TEST VALUE\n"), 0);
70 output_hook_queue(hook, mem);
71 mem = new_file_output_item_byname("core/src/output_hook.c");
72 output_hook_queue(hook, mem);
74 if(-1 == (flags = fcntl(1, F_GETFL, 0)))
75 flags = 0;
76 fcntl(1, F_SETFL, flags | O_NONBLOCK);
77 ev_io_init(&watcher, output_hook_callback, /* STDOUT */ 1, EV_WRITE);
78 watcher.data = hook;
79 ev_io_start(loop, &watcher);
81 ev_loop(loop, 0);
82 release_output_hook(hook);
83 ev_default_destroy();
84 return;
86 #endif
87 static int bad_count = 0;
88 int connect_err_cb(void *req, int err, void *data) {
89 int error = errno;
90 int fd;
91 bad_count++;
92 printf("ERROR: %i %i %s\n", err, error, strerror(error));
93 fd = ConnectRequest_getFd(req);
94 if(fd > 0)
95 close(fd);
96 free_ConnectRequest(req);
97 return 0;
100 static int success_count = 0;
102 void connect_cb(void *req, void *data) {
103 int fd = ConnectRequest_getFd(req);
104 success_count++;
105 close(fd);
106 free_ConnectRequest(req);
109 int socket_error_cb(void *req, int err, void *data) {
110 int error = errno;
111 int fd;
112 bad_count++;
113 printf("ERROR: %i %i %s\n", err, error, strerror(error));
114 fd = SocketRequest_getFd(req);
115 if(fd > 0 && error != EMFILE && error != ENFILE)
116 close(fd);
117 free(data);
118 free_SocketRequest(req);
119 return 0;
122 struct addrContainer {
123 struct sockaddr *addr;
124 socklen_t addr_len;
127 void socket_cb(void *req, void *data) {
128 HandlerCallback callback = {
129 connect_cb,
130 connect_err_cb,
131 NULL
133 core_t *c = SocketRequest_getCore(req);
134 int fd = SocketRequest_getFd(req);
135 struct addrContainer *addr = data;
136 ConnectRequest *cr = new_ConnectRequest(c, callback, fd, addr->addr, addr->addr_len);
137 ConnectRequest_queue(cr, 10);
138 free(data);
139 free_SocketRequest(req);
142 void connect_handler_test() {
143 core_t *c = new_core();
144 struct addrinfo ai, *aitop = NULL;
145 int i;
146 HandlerCallback callback = {
147 socket_cb,
148 socket_error_cb
150 assert(c);
151 memset(&ai, 0, sizeof(ai));
152 ai.ai_family = AF_INET;
153 ai.ai_socktype = SOCK_STREAM;
154 if(0 != getaddrinfo("localhost", "80", &ai, &aitop)) {
155 perror("getaddrinfo"); exit(-1);
158 struct rlimit lim;
159 getrlimit(RLIMIT_NOFILE, &lim);
160 lim.rlim_cur = 64;
161 setrlimit(RLIMIT_NOFILE, &lim);
164 for(i = 0; i < 1024; i++) {
165 SocketRequest *sr;
166 struct addrContainer *cont = calloc(1, sizeof(struct addrContainer));
167 cont->addr = aitop->ai_addr;
168 cont->addr_len = aitop->ai_addrlen;
169 callback.data = cont;
170 sr = new_SocketRequest(c, callback, PF_INET, SOCK_STREAM, 0);
171 SocketRequest_queue(sr, 0, 0);
173 freeaddrinfo(aitop);
174 ev_loop(c->loop, 0);
175 free_core(c);
176 printf("BAD COUNT: %i\nGOOD COUNT: %i\nTOTAL:%i\n", bad_count, success_count, bad_count + success_count);
178 void data_item_test() {
179 data_item_t *mem = new_memory_item("HELLO", 6);
180 printf("MEMORY_TYPE: %i\n", mem->typeID);
181 free_data_item(mem);
184 void test_filter_action(void *state, filter_activity activity, data_item_t *item, next_filter_action next, void *nextData) {
185 printf("GOT ACTION: %i - DATA: 0x%p\n", activity, item);
186 next(nextData, activity, item);
189 void end_filter_action(void *state, filter_activity activity, data_item_t *item) {
190 printf("DONE: %i - DATA: 0x%p\n", activity, item);
192 void chain_test() {
193 void* chain = new_filter_chain();
194 filter_chain_append(chain, test_filter_action, NULL, NULL);
195 filter_chain_action(chain, 0, NULL, end_filter_action, NULL);
196 free_filter_chain(chain);
198 int main(int argc, const char **argv) {
199 #if 0
200 memory_test();
201 file_test();
202 #endif
203 data_item_test();
204 chain_test();
205 if(argc > 1 && !strcmp(argv[1], "--sock")) {
206 struct addrinfo ai, *aitop;
207 int sock;
208 system("nc -l -p 9876 &");
209 sleep(1);
210 memset(&ai, 0, sizeof(ai));
211 ai.ai_family = AF_INET;
212 ai.ai_socktype = SOCK_STREAM;
213 if(0 != getaddrinfo("localhost", "9876", &ai, &aitop)) {
214 perror("getaddrinfo"); return -1;
216 sock = socket(PF_INET, SOCK_STREAM, 0);
217 if(sock < 0) { perror("Failed to create socket"); return -1; }
218 if(0 > connect(sock, aitop->ai_addr, aitop->ai_addrlen)) {
219 perror("connect");
220 freeaddrinfo(aitop);
221 return -1;
223 freeaddrinfo(aitop);
224 /* Replace stdout w/ the socket */
225 if(0 > dup2(sock, 1)) {
226 perror("dup2"); return -1;
229 #if 0
230 event_test();
231 #endif
232 connect_handler_test();
233 return 0;