WIP
[m6w6/libmemcached] / test / setup.cpp
1 #include "mem_config.h"
2 #include "test/conf.h"
3 #include "test/lib/env.hpp"
4 #include "test/lib/random.hpp"
5 #include <cstdlib>
6 #include <cstdio>
7 #include <cstring>
8 #include <csignal>
9 #include <iostream>
10 #include <string>
11 #if HAVE_UNISTD_H
12 # include <unistd.h>
13 #endif
14
15 static void sigchld(int, siginfo_t *si, void *) {
16 switch (si->si_code) {
17 case CLD_EXITED:
18 // expected
19 break;
20 case CLD_KILLED:
21 if (si->si_status == SIGKILL) {
22 // expected
23 break;
24 }
25 [[fallthrough]];
26 case CLD_DUMPED:
27 std::cerr << "Server{pid="
28 << std::to_string(si->si_pid)
29 << "} died: "
30 << strsignal(si->si_status)
31 << std::endl;
32 break;
33 }
34 }
35
36 static inline void setup_signals() {
37 struct sigaction sa;
38 memset(&sa, 0, sizeof(sa));
39 sa.sa_flags = SA_NOCLDSTOP | SA_RESTART | SA_SIGINFO | SA_NODEFER;
40
41 sa.sa_sigaction = sigchld;
42 if (0 > sigaction(SIGCHLD, &sa, nullptr)) {
43 perror("sigaction(CHLD)");
44 }
45 }
46
47 #if HAVE_ASAN
48 // this has to be a macro for putenv() to work
49 # define ASAN_OPTIONS \
50 "check_initialization_order=1," \
51 "replace_str=1," \
52 "replace_intrin=1," \
53 "detect_stack_use_after_return=1," \
54 "alloc_dealloc_mismatch=1," \
55 "new_delete_type_mismatch=1," \
56 "detect_odr_violation=2," \
57 "halt_on_error=0," \
58 "verify_asan_link_order=1," \
59 "abort_on_error=0," \
60 ""
61 # define LSAN_OPTIONS \
62 "suppressions=" SOURCES_ROOT "/test/LeakSanitizer.suppressions," \
63 ""
64
65 static inline void setup_asan(char **argv) {
66 const auto set = getenv("ASAN_OPTIONS");
67
68 if (!set || !*set) {
69 SET_ENV_EX(asan, "ASAN_OPTIONS", ASAN_OPTIONS, 0);
70 execvp(argv[0], argv);
71 perror("exec()");
72 }
73 }
74 static inline void setup_lsan(char **argv) {
75 const auto set = getenv("LSAN_OPTIONS");
76
77 if (!set || !*set) {
78 SET_ENV_EX(lsan, "LSAN_OPTIONS", LSAN_OPTIONS, 0);
79 execvp(argv[0], argv);
80 perror("exec()");
81 }
82 }
83 #else
84 # define setup_asan(a) (void) a
85 # define setup_lsan(a) (void) a
86 #endif
87
88 #if HAVE_TSAN
89 # define TSAN_OPTIONS \
90 "abort_on_error=0," \
91 "halt_on_error=0" \
92 ""
93 static inline void setup_tsan(char **argv) {
94 const auto set = getenv("TSAN_OPTIONS");
95
96 if (!set || !*set) {
97 SET_ENV_EX(tsan, "TSAN_OPTIONS", TSAN_OPTIONS, 0);
98 execvp(argv[0], argv);
99 perror("exec()");
100 }
101 }
102 #else
103 # define setup_tsan(a) (void) a
104 #endif
105
106 #if LIBMEMCACHED_WITH_SASL_SUPPORT
107 static inline void setup_sasl() {
108 SET_ENV_EX(sasl_pwdb, "MEMCACHED_SASL_PWDB", LIBMEMCACHED_WITH_SASL_PWDB, 0);
109 SET_ENV_EX(sasl_conf, "SASL_CONF_PATH", LIBMEMCACHED_WITH_SASL_CONF, 0);
110 }
111 #else
112 # define setup_sasl()
113 #endif
114
115 static inline void setup_random() {
116 random_setup();
117 }
118
119 int setup(int &, char ***argv) {
120 setup_signals();
121 setup_random();
122 setup_asan(*argv);
123 setup_lsan(*argv);
124 setup_tsan(*argv);
125 setup_sasl();
126
127 return 0;
128 }