meson.build (8589B)
1 # Reverse-proxy integration tests. 2 # 3 # Builds the C upstream (libmicrohttpd), the raw-socket pipelining 4 # client, and — when the toolchains are available — Go and Rust 5 # upstreams, then runs the shell-driven test driver. 6 7 upstream_mhd = executable( 8 'upstream_mhd', 9 'upstream_mhd.c', 10 dependencies: [mhd_dep], 11 include_directories: [incdir, configuration_inc], 12 install: false, 13 ) 14 15 pipeline_client = executable( 16 'pipeline_client', 17 'pipeline_client.c', 18 include_directories: [incdir, configuration_inc], 19 install: false, 20 ) 21 22 early_response_upstream = executable( 23 'early_response_upstream', 24 'early_response_upstream.c', 25 dependencies: [gnunetutil_dep], 26 include_directories: [incdir, configuration_inc], 27 install: false, 28 ) 29 30 # The streaming pair: an origin that serves bodies larger than memory, 31 # at a controlled rate and in framings a conforming server will not 32 # emit, and a client that verifies them as they arrive rather than 33 # storing them. Both generate the body from its offset, so a 200 MiB 34 # case costs no disk on either side. 35 stream_upstream = executable( 36 'stream_upstream', 37 'stream_upstream.c', 38 dependencies: [gnunetutil_dep], 39 include_directories: [incdir, configuration_inc], 40 install: false, 41 ) 42 43 stream_client = executable( 44 'stream_client', 45 'stream_client.c', 46 dependencies: [curl_dep], 47 include_directories: [incdir, configuration_inc], 48 install: false, 49 ) 50 51 # Unit test for the client-address canonicalisation that the access 52 # cookie is keyed on. Links the two backend compilation units it 53 # exercises; the daemon's globals are supplied by the test itself. 54 test_client_address = executable( 55 'test_client_address', 56 [ 57 'test_client_address.c', 58 '../backend/paivana-httpd_helper.c', 59 '../backend/paivana-httpd_cookie.c', 60 ], 61 dependencies: [ 62 talerutil_dep, 63 talermhd_dep, 64 gnunetutil_dep, 65 gcrypt_dep, 66 mhd_dep, 67 json_dep, 68 curl_dep, 69 ], 70 include_directories: [incdir, configuration_inc, paivana_backend_inc], 71 install: false, 72 ) 73 74 test('client_address', test_client_address) 75 76 # Unit test for the Set-Cookie line of the access cookie (Path 77 # encoding, Path grammar, Secure). Links only the cookie compilation 78 # unit; the daemon's globals are supplied by the test itself. 79 test_cookie_header = executable( 80 'test_cookie_header', 81 ['test_cookie_header.c', '../backend/paivana-httpd_cookie.c'], 82 dependencies: [ 83 talerutil_dep, 84 talermhd_dep, 85 gnunetutil_dep, 86 gcrypt_dep, 87 mhd_dep, 88 json_dep, 89 curl_dep, 90 ], 91 include_directories: [incdir, configuration_inc, paivana_backend_inc], 92 install: false, 93 ) 94 95 test('cookie_header', test_cookie_header) 96 97 # Unit test for the access decision the cookie encodes (the time bound, 98 # the three MAC inputs, the four rejection paths) and for the 99 # `paivana_id`. Same shape as the above: only the cookie compilation 100 # unit, with the daemon's globals supplied by the test. 101 test_cookie_access = executable( 102 'test_cookie_access', 103 ['test_cookie_access.c', '../backend/paivana-httpd_cookie.c'], 104 dependencies: [ 105 talerutil_dep, 106 talermhd_dep, 107 gnunetutil_dep, 108 gcrypt_dep, 109 mhd_dep, 110 json_dep, 111 curl_dep, 112 ], 113 include_directories: [incdir, configuration_inc, paivana_backend_inc], 114 install: false, 115 ) 116 117 test('cookie_access', test_cookie_access) 118 119 # Prints base64url vectors as the daemon produces them, for 120 # test_base64url.sh to check paywall.js against. The paivana ID 121 # depends on the two encoders agreeing and nothing else forces them to; 122 # they have already disagreed twice, both times breaking the payment 123 # path. 124 base64url_vectors = executable( 125 'base64url_vectors', 126 'base64url_vectors.c', 127 dependencies: [gnunetutil_dep], 128 include_directories: [incdir, configuration_inc], 129 install: false, 130 ) 131 132 test( 133 'base64url', 134 files('test_base64url.sh'), 135 env: { 136 'SRCDIR': meson.current_source_dir(), 137 'BUILDDIR': meson.current_build_dir(), 138 }, 139 depends: [base64url_vectors], 140 ) 141 142 test_deps = [ 143 upstream_mhd, 144 pipeline_client, 145 early_response_upstream, 146 stream_upstream, 147 stream_client, 148 paivana_httpd_exe, 149 ] 150 151 go_bin = find_program('go', required: false) 152 if go_bin.found() 153 upstream_go = custom_target( 154 'upstream_go', 155 input: 'upstream_go.go', 156 output: 'upstream_go', 157 command: [go_bin, 'build', '-o', '@OUTPUT@', '@INPUT@'], 158 build_by_default: true, 159 ) 160 test_deps += upstream_go 161 endif 162 163 rustc_bin = find_program('rustc', required: false) 164 if rustc_bin.found() 165 upstream_rs = custom_target( 166 'upstream_rs', 167 input: 'upstream_rs.rs', 168 output: 'upstream_rs', 169 command: [rustc_bin, '-O', '-o', '@OUTPUT@', '@INPUT@'], 170 build_by_default: true, 171 ) 172 test_deps += upstream_rs 173 174 # Only benchmark.sh -m paywall uses this, and only to get paivana 175 # past the template fetch it does before it starts serving. Built 176 # here rather than beside it because it needs the same rustc that 177 # `-m paywall' already requires for upstream_rs, so it costs the 178 # benchmark no dependency it did not have. 179 merchant_stub = custom_target( 180 'merchant_stub', 181 input: 'merchant_stub.rs', 182 output: 'merchant_stub', 183 command: [rustc_bin, '-O', '-o', '@OUTPUT@', '@INPUT@'], 184 build_by_default: true, 185 ) 186 test_deps += merchant_stub 187 endif 188 189 # Under `./configure --enable-sanitizers' the whole project is built 190 # instrumented, so these are the same tests with ASan and UBSan under 191 # them rather than extra cases. Two things are needed to keep that 192 # mode usable rather than something everyone turns off again: 193 # 194 # - LSan needs the suppression file, or every run fails on one-time 195 # allocations in libcurl and libgcrypt that are nothing to do with 196 # paivana; 197 # - the large cases have to scale down, since 200 MiB through ASan is 198 # not a test but a coffee break. What those cases exercise is the 199 # pause/resume interleaving, which is a function of the ring size 200 # and not of the total, so a twentieth of the bytes reaches the same 201 # transitions. 202 test_env = {'SRCDIR': meson.current_source_dir(), 'BUILDDIR': meson.current_build_dir(), 'PAIVANA_HTTPD': paivana_httpd_exe.full_path(), 'LSAN_OPTIONS': 'suppressions=' 203 + meson.current_source_dir() / 'lsan.supp'} 204 if get_option('b_sanitize') != 'none' 205 test_env += {'PAIVANA_TEST_SCALE': '20', 'PAIVANA_SANITIZED': '1'} 206 endif 207 208 test( 209 'reverse_proxy', 210 files('test_reverse_proxy.sh'), 211 env: test_env, 212 depends: test_deps, 213 timeout: 600, 214 ) 215 216 # The paywall against a real merchant backend. Skips (77) unless the 217 # GNU Taler stack and PostgreSQL are there, since nothing in a bare 218 # paivana checkout can bring an exchange and a merchant up. Given a 219 # long timeout because it withdraws coins and makes a payment: the 220 # wallet's withdrawal alone is tens of seconds. 221 test( 222 'paywall', 223 files('test_paywall.sh'), 224 env: test_env, 225 depends: test_deps, 226 timeout: 900, 227 ) 228 229 # What the reverse proxy costs: N curl clients at a fixed-size static 230 # page, first straight at upstream_rs and then through paivana in front 231 # of it. Registered with benchmark() rather than test() deliberately -- 232 # `meson test' does not run benchmarks, so this stays out of 233 # `make check', where a timing run would contribute nothing but twenty 234 # seconds and a result that depends on how loaded the machine is. Run 235 # it with `meson test --benchmark proxy_overhead -C build', or call the 236 # script directly for the options (-c clients, -s size, -d seconds). 237 benchmark( 238 'proxy_overhead', 239 files('benchmark.sh'), 240 env: test_env, 241 depends: test_deps, 242 timeout: 300, 243 ) 244 245 # The other half of the same script: what paivana costs when it answers 246 # by itself, i.e. the 402 paywall page an unpaid client is sent to, with 247 # no upstream in the path. A second entry rather than `-m all' on the 248 # one above so that the two skip independently -- this arm needs the 249 # generated paywall template and merchant_stub, and neither should be 250 # able to take the proxy measurement down with it. Its own port base 251 # because these two would otherwise collide if anyone ran the benchmarks 252 # in parallel, which is not meson's default but is one flag away. 253 benchmark( 254 'paywall_page', 255 files('benchmark.sh'), 256 args: ['-m', 'paywall', '-b', '18610'], 257 env: test_env, 258 depends: test_deps, 259 timeout: 300, 260 )