diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/selftest.cpp | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/src/selftest.cpp b/src/selftest.cpp index d649b23..abe1d15 100644 --- a/src/selftest.cpp +++ b/src/selftest.cpp | |||
| @@ -8,6 +8,23 @@ | |||
| 8 | #include "headers_core.h" | 8 | #include "headers_core.h" |
| 9 | #include "selftest.h" | 9 | #include "selftest.h" |
| 10 | 10 | ||
| 11 | // Test results go to the terminal, not to debug.log. | ||
| 12 | // | ||
| 13 | // printf in this tree is OutputDebugStringF, which writes into the data | ||
| 14 | // directory's debug.log and binds that path, once, on its first call. For a | ||
| 15 | // self-test that produced two bad outcomes at the same time. On Windows the | ||
| 16 | // binary is linked -mwindows and has no console, so `make tests` printed the | ||
| 17 | // bip32 results, echoed the self-test command, and then showed nothing at all -- | ||
| 18 | // a failure was still caught, because a non-zero return stops make, but it | ||
| 19 | // arrived with no way to tell which check failed. And because the first line | ||
| 20 | // printed before strSetDataDir was pointed at the temporary directory, every | ||
| 21 | // line landed in the developer's real debug.log: the same file users are asked | ||
| 22 | // to paste into issues. | ||
| 23 | // | ||
| 24 | // Undefining the macro here gives this file the real printf, so results reach | ||
| 25 | // stdout. Nothing else in the tree is affected. | ||
| 26 | #undef printf | ||
| 27 | |||
| 11 | #include <mutex> | 28 | #include <mutex> |
| 12 | #include <stdexcept> | 29 | #include <stdexcept> |
| 13 | #include <thread> | 30 | #include <thread> |
| @@ -163,6 +180,7 @@ static bool Check(bool condition, const char* message) | |||
| 163 | 180 | ||
| 164 | static int RunWalletKeyPoolSelfTest() | 181 | static int RunWalletKeyPoolSelfTest() |
| 165 | { | 182 | { |
| 183 | fflush(stdout); | ||
| 166 | printf("wallet-keypool self-test\n"); | 184 | printf("wallet-keypool self-test\n"); |
| 167 | 185 | ||
| 168 | std::string tmp; | 186 | std::string tmp; |
| @@ -180,6 +198,9 @@ static int RunWalletKeyPoolSelfTest() | |||
| 180 | } | 198 | } |
| 181 | 199 | ||
| 182 | int nFail = 0; | 200 | int nFail = 0; |
| 201 | // Before anything can open the database or resolve the log path: what the | ||
| 202 | // node itself prints during the test belongs in the temporary directory, | ||
| 203 | // and dies with it. The test's own results are on stdout, above. | ||
| 183 | strSetDataDir = tmp; | 204 | strSetDataDir = tmp; |
| 184 | printf(" temp datadir: %s\n", tmp.c_str()); | 205 | printf(" temp datadir: %s\n", tmp.c_str()); |
| 185 | 206 | ||
| @@ -261,11 +282,42 @@ static int RunWalletKeyPoolSelfTest() | |||
| 261 | RemoveTree(tmp); | 282 | RemoveTree(tmp); |
| 262 | printf("%s (%d failure%s)\n", nFail == 0 ? "ALL TESTS PASSED" : "TESTS FAILED", | 283 | printf("%s (%d failure%s)\n", nFail == 0 ? "ALL TESTS PASSED" : "TESTS FAILED", |
| 263 | nFail, nFail == 1 ? "" : "s"); | 284 | nFail, nFail == 1 ? "" : "s"); |
| 285 | fflush(stdout); | ||
| 264 | return nFail == 0 ? 0 : 1; | 286 | return nFail == 0 ? 0 : 1; |
| 265 | } | 287 | } |
| 266 | 288 | ||
| 289 | // A -mwindows binary starts with no console attached, so stdout goes nowhere | ||
| 290 | // even when it was launched from a terminal. Borrow the caller's console for | ||
| 291 | // the duration of the self-test. Nothing to do on Linux, where stdout is | ||
| 292 | // already connected. | ||
| 293 | static void AttachTerminal() | ||
| 294 | { | ||
| 295 | #ifdef _WIN32 | ||
| 296 | // Only when there is nowhere for stdout to go. If the caller redirected it | ||
| 297 | // to a file or a pipe -- which is what `make tests > log` and any CI does -- | ||
| 298 | // that handle is inherited and already works, and reopening it on CONOUT$ | ||
| 299 | // would take the output away from the file and put it on the screen. That | ||
| 300 | // was the first version of this fix, and it broke the one case that | ||
| 301 | // mattered. | ||
| 302 | HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); | ||
| 303 | if (hOut != NULL && hOut != INVALID_HANDLE_VALUE) | ||
| 304 | return; | ||
| 305 | |||
| 306 | if (AttachConsole(ATTACH_PARENT_PROCESS)) | ||
| 307 | { | ||
| 308 | // Return values ignored on purpose: if the reopen fails there is | ||
| 309 | // nowhere left to report it, and the exit status still carries the | ||
| 310 | // result. | ||
| 311 | freopen("CONOUT$", "w", stdout); | ||
| 312 | freopen("CONOUT$", "w", stderr); | ||
| 313 | } | ||
| 314 | #endif | ||
| 315 | } | ||
| 316 | |||
| 267 | int RunSelfTest(const std::string& name) | 317 | int RunSelfTest(const std::string& name) |
| 268 | { | 318 | { |
| 319 | AttachTerminal(); | ||
| 320 | |||
| 269 | if (name == "wallet-keypool") | 321 | if (name == "wallet-keypool") |
| 270 | return RunWalletKeyPoolSelfTest(); | 322 | return RunWalletKeyPoolSelfTest(); |
| 271 | 323 | ||