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