1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3 /* Fluent Bit
4 * ==========
5 * Copyright (C) 2015-2016 Treasure Data Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
20 #include <fluent-bit.h>
21 #include <pthread.h>
22 #include <stdlib.h>
23 #include <unistd.h>
24 #include "flb_tests_runtime.h"
25
26
27 int64_t result_time;
set_result(int64_t v)28 static inline int64_t set_result(int64_t v)
29 {
30 int64_t old = __sync_lock_test_and_set(&result_time, v);
31 return old;
32 }
33
get_result(void)34 static inline int64_t get_result(void)
35 {
36 int64_t old = __sync_fetch_and_add(&result_time, 0);
37
38 return old;
39 }
40
time_in_ms()41 static inline int64_t time_in_ms()
42 {
43 int ms;
44 struct timespec s;
45 TEST_CHECK(clock_gettime(CLOCK_MONOTONIC, &s) == 0);
46 ms = s.tv_nsec / 1.0e6;
47 if (ms >= 1000) {
48 ms = 0;
49 }
50 return 1000 * s.tv_sec + ms;
51 }
52
callback_test(void * data,size_t size,void * cb_data)53 int callback_test(void* data, size_t size, void* cb_data)
54 {
55 if (size > 0) {
56 flb_info("[test] flush triggered");
57 flb_lib_free(data);
58 set_result(time_in_ms()); /* success */
59 }
60 return 0;
61 }
62
do_test(char * system,...)63 void do_test(char *system, ...)
64 {
65 int64_t ret;
66 flb_ctx_t *ctx = NULL;
67 int in_ffd;
68 int out_ffd;
69 va_list va;
70 char *key;
71 char *value;
72
73 struct flb_lib_out_cb cb;
74 cb.cb = callback_test;
75 cb.data = NULL;
76
77 /* initialize */
78 set_result(0);
79
80 ctx = flb_create();
81
82 in_ffd = flb_input(ctx, (char *) system, NULL);
83 TEST_CHECK(in_ffd >= 0);
84 TEST_CHECK(flb_input_set(ctx, in_ffd, "tag", "test", NULL) == 0);
85
86 va_start(va, system);
87 while ((key = va_arg(va, char *))) {
88 value = va_arg(va, char *);
89 TEST_CHECK(value != NULL);
90 TEST_CHECK(flb_input_set(ctx, in_ffd, key, value, NULL) == 0);
91 }
92 va_end(va);
93
94 out_ffd = flb_output(ctx, (char *) "lib", &cb);
95 TEST_CHECK(out_ffd >= 0);
96 TEST_CHECK(flb_output_set(ctx, out_ffd, "match", "test", NULL) == 0);
97
98 TEST_CHECK(flb_service_set(ctx, "Flush", "0.5",
99 "Grace", "1",
100 NULL) == 0);
101
102 /* The following test tries to check if an input plugin generates
103 * data in a timely manner.
104 *
105 * 0 1 2 3 4 (sec)
106 * |--F--F--F--C--F--F--F--C--|
107 *
108 * F ... Flush (0.5 sec interval)
109 * C ... Condition checks
110 *
111 * Since CI servers can be sometimes very slow, we wait slightly a
112 * little more before checking the condition.
113 */
114
115 /* Start test */
116 TEST_CHECK(flb_start(ctx) == 0);
117
118 /* 2 sec passed. It must have flushed */
119 sleep(2);
120 flb_info("[test] check status 1");
121 ret = get_result();
122 TEST_CHECK(ret > 0);
123
124 /* 4 sec passed. It must have flushed */
125 sleep(2);
126 flb_info("[test] check status 2");
127 ret = get_result();
128 TEST_CHECK(ret > 0);
129
130 flb_stop(ctx);
131 flb_destroy(ctx);
132 }
133
flb_test_in_disk_flush()134 void flb_test_in_disk_flush()
135 {
136 do_test("disk",
137 "interval_sec", "0",
138 "interval_nsec", "500000000",
139 NULL);
140 }
flb_test_in_proc_flush()141 void flb_test_in_proc_flush()
142 {
143 do_test("proc",
144 "interval_sec", "0",
145 "interval_nsec", "500000000",
146 "proc_name", "flb_test_in_proc",
147 "alert", "true",
148 "mem", "on",
149 "fd", "on",
150 NULL);
151 }
flb_test_in_head_flush()152 void flb_test_in_head_flush()
153 {
154 do_test("head",
155 "interval_sec", "0",
156 "interval_nsec", "500000000",
157 "File", "/dev/urandom",
158 NULL);
159 }
flb_test_in_cpu_flush()160 void flb_test_in_cpu_flush()
161 {
162 do_test("cpu", NULL);
163 }
flb_test_in_random_flush()164 void flb_test_in_random_flush()
165 {
166 do_test("random", NULL);
167 }
flb_test_in_dummy_flush()168 void flb_test_in_dummy_flush()
169 {
170 do_test("dummy", NULL);
171 }
flb_test_in_mem_flush()172 void flb_test_in_mem_flush()
173 {
174 do_test("mem", NULL);
175 }
176
177 #ifdef in_proc
flb_test_in_proc_absent_process(void)178 void flb_test_in_proc_absent_process(void)
179 {
180 int ret;
181 flb_ctx_t *ctx = NULL;
182 int in_ffd;
183 int out_ffd;
184
185 struct flb_lib_out_cb cb;
186 cb.cb = callback_test;
187 cb.data = NULL;
188
189 ctx = flb_create();
190
191 in_ffd = flb_input(ctx, (char *) "proc", NULL);
192 TEST_CHECK(in_ffd >= 0);
193 flb_input_set(ctx, in_ffd, "tag", "test",
194 "interval_sec", "1", "proc_name", "",
195 "alert", "true", "mem", "on", "fd", "on", NULL);
196
197 out_ffd = flb_output(ctx, (char *) "lib", &cb);
198 TEST_CHECK(out_ffd >= 0);
199 flb_output_set(ctx, out_ffd, "match", "test", NULL);
200
201 flb_service_set(ctx, "Flush", "2", "Grace", "1", NULL);
202
203 ret = flb_start(ctx);
204 TEST_CHECK(ret == 0); // error occurs but return value is true
205
206 flb_stop(ctx);
207 flb_destroy(ctx);
208 }
209 #endif
210
211 /* Test list */
212 TEST_LIST = {
213 #ifdef in_disk
214 {"disk_flush", flb_test_in_disk_flush},
215 #endif
216 #ifdef in_proc
217 {"proc_flush", flb_test_in_proc_flush},
218 {"proc_absent_process", flb_test_in_proc_absent_process},
219 #endif
220 #ifdef in_head
221 {"head_flush", flb_test_in_head_flush},
222 #endif
223 #ifdef in_cpu
224 {"cpu_flush", flb_test_in_cpu_flush},
225 #endif
226 #ifdef in_random
227 {"random_flush", flb_test_in_random_flush},
228 #endif
229 #ifdef in_dummy
230 {"dummy_flush", flb_test_in_dummy_flush},
231 #endif
232 #ifdef in_mem
233 {"mem_flush", flb_test_in_mem_flush},
234 #endif
235 {NULL, NULL}
236 };
237
238