root/src/modules/test_abort.c

Revision f91ddca09660d8415b1bcdd88b20946e82b0ef62, 6.7 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 3 years ago)

propagate the cause for causal checks into all of the calls

  • Property mode set to 100644
Line 
1 /*
2  * Copyright (c) 2007-2010, OmniTI Computer Consulting, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *     * Redistributions of source code must retain the above copyright
10  *       notice, this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above
12  *       copyright notice, this list of conditions and the following
13  *       disclaimer in the documentation and/or other materials provided
14  *       with the distribution.
15  *     * Neither the name OmniTI Computer Consulting, Inc. nor the names
16  *       of its contributors may be used to endorse or promote products
17  *       derived from this software without specific prior written
18  *       permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 #include "noit_defines.h"
34
35 #include <stdio.h>
36 #include <unistd.h>
37 #include <errno.h>
38 #include <assert.h>
39 #include <math.h>
40
41 #include "noit_module.h"
42 #include "noit_check.h"
43 #include "noit_check_tools.h"
44 #include "utils/noit_log.h"
45 #include "utils/noit_hash.h"
46
47 #ifndef BOOLOID
48 #define BOOLOID                  16
49 #endif
50 #ifndef INT2OID
51 #define INT2OID                  21
52 #endif
53 #ifndef INT4OID
54 #define INT4OID                  23
55 #endif
56 #ifndef INT8OID
57 #define INT8OID                  20
58 #endif
59 #ifndef FLOAT4OID
60 #define FLOAT4OID                700
61 #endif
62 #ifndef FLOAT8OID
63 #define FLOAT8OID                701
64 #endif
65 #ifndef NUMERICOID
66 #define NUMERICOID               1700
67 #endif
68
69 typedef struct {
70   noit_module_t *self;
71   noit_check_t *check;
72   int rv;
73   int timed_out;
74   double timeout;
75   int method;
76   int ignore_signals;
77 } test_abort_check_info_t;
78
79 static noit_log_stream_t nlerr = NULL;
80 static noit_log_stream_t nldeb = NULL;
81
82 static void test_abort_cleanup(noit_module_t *self, noit_check_t *check) {
83   test_abort_check_info_t *ci = check->closure;
84   if(ci) {
85     memset(ci, 0, sizeof(*ci));
86   }
87 }
88
89 static int test_abort_drive_session(eventer_t e, int mask, void *closure,
90                                   struct timeval *passed_now) {
91   struct timespec rqtp;
92   struct timeval target_time, now, diff;
93   double i, r;
94   test_abort_check_info_t *ci = closure;
95   noit_check_t *check = ci->check;
96
97   if(mask & (EVENTER_READ | EVENTER_WRITE)) {
98     /* this case is impossible from the eventer.  It is called as
99      * such on the synchronous completion of the event.
100      */
101     stats_t current;
102     noit_check_stats_clear(&current);
103     current.available = NP_AVAILABLE;
104     current.state = ci->timed_out ? NP_BAD : NP_GOOD;
105     noitL(nlerr, "test_abort: EVENTER_READ | EVENTER_WRITE\n");
106     noit_check_set_stats(ci->self, check, &current);
107     check->flags &= ~NP_RUNNING;
108     return 0;
109   }
110   switch(mask) {
111     case EVENTER_ASYNCH_WORK:
112       noitL(nlerr, "test_abort: EVENTER_ASYNCH_WORK\n");
113       r = modf(ci->timeout, &i);
114       ci->timed_out = 1;
115      
116       if(ci->ignore_signals) { /* compuational loop */
117         double trash = 1.0;
118         gettimeofday(&now, NULL);
119         diff.tv_sec = (int)i;
120         diff.tv_usec = (int)(r * 1000000.0);
121         add_timeval(now, diff, &target_time);
122
123         do {
124           for(i=0; i<100000; i++) {
125             trash += drand48();
126             trash = log(trash);
127             trash += 1.1;
128             trash = exp(trash);
129           }
130           gettimeofday(&now, NULL);
131           sub_timeval(target_time, now, &diff);
132         } while(diff.tv_sec >= 0 && diff.tv_usec >= 0);
133       }
134       else {
135         rqtp.tv_sec = (int)i;
136         rqtp.tv_nsec = (int)(r * 1000000000.0);
137         nanosleep(&rqtp,NULL);
138       }
139       noitL(nlerr, "test_abort: EVENTER_ASYNCH_WORK (done)\n");
140       ci->timed_out = 0;
141       return 0;
142       break;
143     case EVENTER_ASYNCH_CLEANUP:
144       /* This sets us up for a completion call. */
145       noitL(nlerr, "test_abort: EVENTER_ASYNCH_CLEANUP\n");
146       e->mask = EVENTER_READ | EVENTER_WRITE;
147       break;
148     default:
149       abort();
150   }
151   return 0;
152 }
153
154 static int test_abort_initiate(noit_module_t *self, noit_check_t *check,
155                                noit_check_t *cause) {
156   test_abort_check_info_t *ci = check->closure;
157   struct timeval __now;
158   const char *v;
159
160   noitL(nlerr, "test_abort_initiate\n");
161   /* We cannot be running */
162   assert(!(check->flags & NP_RUNNING));
163   check->flags |= NP_RUNNING;
164
165   ci->self = self;
166   ci->check = check;
167   ci->timeout = 30;
168   if(noit_hash_retr_str(check->config, "sleep", strlen("sleep"), &v)) {
169     ci->timeout = atof(v);
170   }
171   ci->ignore_signals = 0;
172   if(noit_hash_retr_str(check->config, "ignore_signals", strlen("ignore_signals"), &v)) {
173     if(!strcmp(v, "true")) ci->ignore_signals = 1;
174   }
175   ci->timed_out = 1;
176
177   ci->method = 0;
178   if(noit_hash_retr_str(check->config, "method", strlen("method"), &v)) {
179     if(!strcmp(v, "evil")) ci->method = EVENTER_EVIL_BRUTAL;
180     else if(!strcmp(v, "deferred")) ci->method = EVENTER_CANCEL_DEFERRED;
181     else if(!strcmp(v, "asynch")) ci->method = EVENTER_CANCEL_ASYNCH;
182   }
183   memcpy(&check->last_fire_time, &__now, sizeof(__now));
184
185   /* Register a handler for the worker */
186   noit_check_run_full_asynch_opts(check, test_abort_drive_session, ci->method);
187   return 0;
188 }
189
190 static int test_abort_initiate_check(noit_module_t *self, noit_check_t *check,
191                                    int once, noit_check_t *cause) {
192   if(!check->closure) check->closure = calloc(1, sizeof(test_abort_check_info_t));
193   INITIATE_CHECK(test_abort_initiate, self, check, cause);
194   return 0;
195 }
196
197 static int test_abort_onload(noit_image_t *self) {
198   nlerr = noit_log_stream_find("error/test_abort");
199   nldeb = noit_log_stream_find("debug/test_abort");
200   if(!nlerr) nlerr = noit_stderr;
201   if(!nldeb) nldeb = noit_debug;
202
203   eventer_name_callback("http/test_abort_drive_session", test_abort_drive_session);
204   return 0;
205 }
206
207 noit_module_t test_abort = {
208   {
209     NOIT_MODULE_MAGIC,
210     NOIT_MODULE_ABI_VERSION,
211     "test_abort",
212     "test_abort internal tool for eventer testing",
213     "",
214     test_abort_onload
215   },
216   NULL,
217   NULL,
218   test_abort_initiate_check,
219   test_abort_cleanup
220 };
221
Note: See TracBrowser for help on using the browser.