You've already forked pgbackrest
							
							
				mirror of
				https://github.com/pgbackrest/pgbackrest.git
				synced 2025-10-30 23:37:45 +02:00 
			
		
		
		
	Allow tests that use ports to run in parallel.
Set the test index in the C unit test code so it can assign port numbers that won't conflict between tests.
This commit is contained in:
		| @@ -389,6 +389,7 @@ sub run | ||||
|                 $strTestC =~ s/\{\[C\_TEST\_PROJECT\_EXE\]\}/$strProjectExePath/g; | ||||
|                 $strTestC =~ s/\{\[C\_TEST\_PATH\]\}/$strTestPathC/g; | ||||
|                 $strTestC =~ s/\{\[C\_TEST\_DATA_PATH\]\}/$self->{strDataPath}/g; | ||||
|                 $strTestC =~ s/\{\[C\_TEST\_IDX\]\}/$self->{iVmIdx}/g; | ||||
|                 $strTestC =~ s/\{\[C\_TEST\_REPO_PATH\]\}/$self->{strBackRestBase}/g; | ||||
|                 $strTestC =~ s/\{\[C\_TEST\_SCALE\]\}/$self->{iScale}/g; | ||||
|  | ||||
|   | ||||
| @@ -186,6 +186,30 @@ testDataPathSet(const char *testDataPath) | ||||
|     FUNCTION_HARNESS_RESULT_VOID(); | ||||
| } | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Get and set test index | ||||
| ***********************************************************************************************************************************/ | ||||
| static unsigned int testIdxData = 0; | ||||
|  | ||||
| unsigned int | ||||
| testIdx(void) | ||||
| { | ||||
|     FUNCTION_HARNESS_VOID(); | ||||
|     FUNCTION_HARNESS_RESULT(UINT, testIdxData); | ||||
| } | ||||
|  | ||||
| void | ||||
| testIdxSet(unsigned int testIdx) | ||||
| { | ||||
|     FUNCTION_HARNESS_BEGIN(); | ||||
|         FUNCTION_HARNESS_PARAM(UINT, testIdx); | ||||
|     FUNCTION_HARNESS_END(); | ||||
|  | ||||
|     testIdxData = testIdx; | ||||
|  | ||||
|     FUNCTION_HARNESS_RESULT_VOID(); | ||||
| } | ||||
|  | ||||
| /*********************************************************************************************************************************** | ||||
| Get and set scale for performance testing | ||||
| ***********************************************************************************************************************************/ | ||||
|   | ||||
| @@ -41,6 +41,10 @@ bool testContainer(void); | ||||
| // Location of the data path were the harness can write data that won't be visible to the test | ||||
| const char *testDataPath(void); | ||||
|  | ||||
| // Get the 0-based index of the test.  Useful for modifying resources like port numbers to avoid conflicts when running tests in | ||||
| // parallel. | ||||
| unsigned int testIdx(void); | ||||
|  | ||||
| // Location of the project exe | ||||
| const char *testProjectExe(void); | ||||
|  | ||||
|   | ||||
| @@ -31,7 +31,7 @@ static SSL *testClientSSL = NULL; | ||||
| Initialize TLS and listen on the specified port for TLS connections | ||||
| ***********************************************************************************************************************************/ | ||||
| void | ||||
| harnessTlsServerInit(int port, const char *serverCert, const char *serverKey) | ||||
| harnessTlsServerInit(unsigned int port, const char *serverCert, const char *serverKey) | ||||
| { | ||||
|     // Add test hosts | ||||
|     if (testContainer()) | ||||
| @@ -92,11 +92,11 @@ void | ||||
| harnessTlsServerInitDefault(void) | ||||
| { | ||||
|     if (testContainer()) | ||||
|         harnessTlsServerInit(TLS_TEST_PORT, TLS_CERT_TEST_CERT, TLS_CERT_TEST_KEY); | ||||
|         harnessTlsServerInit(harnessTlsTestPort(), TLS_CERT_TEST_CERT, TLS_CERT_TEST_KEY); | ||||
|     else | ||||
|     { | ||||
|         harnessTlsServerInit( | ||||
|             TLS_TEST_PORT, | ||||
|             harnessTlsTestPort(), | ||||
|             strPtr(strNewFmt("%s/" TEST_CERTIFICATE_PREFIX ".crt", testRepoPath())), | ||||
|             strPtr(strNewFmt("%s/" TEST_CERTIFICATE_PREFIX ".key", testRepoPath()))); | ||||
|     } | ||||
| @@ -180,3 +180,9 @@ const String *harnessTlsTestHost(void) | ||||
| { | ||||
|     return strNew(testContainer() ? TLS_TEST_HOST : "localhost"); | ||||
| } | ||||
|  | ||||
| /**********************************************************************************************************************************/ | ||||
| unsigned int harnessTlsTestPort(void) | ||||
| { | ||||
|     return 44443 + testIdx(); | ||||
| } | ||||
|   | ||||
| @@ -14,8 +14,6 @@ Path and prefix for test certificates | ||||
| /*********************************************************************************************************************************** | ||||
| Tls test defaults | ||||
| ***********************************************************************************************************************************/ | ||||
| #define TLS_TEST_PORT                                               9443 | ||||
|  | ||||
| #define TLS_CERT_FAKE_PATH                                          "/etc/fake-cert" | ||||
| #define TLS_CERT_TEST_CERT                                          TLS_CERT_FAKE_PATH "/pgbackrest-test.crt" | ||||
| #define TLS_CERT_TEST_KEY                                           TLS_CERT_FAKE_PATH "/pgbackrest-test.key" | ||||
| @@ -23,7 +21,7 @@ Tls test defaults | ||||
| /*********************************************************************************************************************************** | ||||
| Functions | ||||
| ***********************************************************************************************************************************/ | ||||
| void harnessTlsServerInit(int port, const char *serverCert, const char *serverKey); | ||||
| void harnessTlsServerInit(unsigned int port, const char *serverCert, const char *serverKey); | ||||
|  | ||||
| // Initialize TLS with default parameters | ||||
| void harnessTlsServerInitDefault(void); | ||||
| @@ -39,4 +37,7 @@ Getters | ||||
| // Hostname to use for testing -- this will vary based on whether the test is running in a container | ||||
| const String *harnessTlsTestHost(void); | ||||
|  | ||||
| // Port to use for testing.  This will be unique for each test running in parallel to avoid conflicts | ||||
| unsigned int harnessTlsTestPort(void); | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -410,22 +410,24 @@ testRun(void) | ||||
|         httpClientStatLocal = (HttpClientStat){0}; | ||||
|         TEST_RESULT_STR(httpClientStatStr(), NULL, "no stats yet"); | ||||
|  | ||||
|         TEST_ASSIGN(client, httpClientNew(strNew("localhost"), TLS_TEST_PORT, 500, testContainer(), NULL, NULL), "new client"); | ||||
|         TEST_ASSIGN( | ||||
|             client, httpClientNew(strNew("localhost"), harnessTlsTestPort(), 500, testContainer(), NULL, NULL), "new client"); | ||||
|  | ||||
|         TEST_ERROR_FMT( | ||||
|             httpClientRequest(client, strNew("GET"), strNew("/"), NULL, NULL, NULL, false), HostConnectError, | ||||
|             "unable to connect to 'localhost:%d': [111] Connection refused", TLS_TEST_PORT); | ||||
|             "unable to connect to 'localhost:%u': [111] Connection refused", harnessTlsTestPort()); | ||||
|  | ||||
|         // Start http test server | ||||
|         testHttpServer(); | ||||
|  | ||||
|         // Test no output from server | ||||
|         TEST_ASSIGN(client, httpClientNew(harnessTlsTestHost(), TLS_TEST_PORT, 500, testContainer(), NULL, NULL), "new client"); | ||||
|         TEST_ASSIGN( | ||||
|             client, httpClientNew(harnessTlsTestHost(), harnessTlsTestPort(), 500, testContainer(), NULL, NULL), "new client"); | ||||
|         client->timeout = 0; | ||||
|  | ||||
|         TEST_ERROR_FMT( | ||||
|             httpClientRequest(client, strNew("GET"), strNew("/"), NULL, NULL, NULL, false), FileReadError, | ||||
|             "timeout after 500ms waiting for read from '%s:%d'", strPtr(harnessTlsTestHost()), TLS_TEST_PORT); | ||||
|             "timeout after 500ms waiting for read from '%s:%u'", strPtr(harnessTlsTestHost()), harnessTlsTestPort()); | ||||
|  | ||||
|         // Test invalid http version | ||||
|         TEST_ERROR( | ||||
| @@ -576,7 +578,8 @@ testRun(void) | ||||
|         HttpClient *client1 = NULL; | ||||
|         HttpClient *client2 = NULL; | ||||
|  | ||||
|         TEST_ASSIGN(cache, httpClientCacheNew(strNew("localhost"), TLS_TEST_PORT, 500, true, NULL, NULL), "new http client cache"); | ||||
|         TEST_ASSIGN( | ||||
|             cache, httpClientCacheNew(strNew("localhost"), harnessTlsTestPort(), 500, true, NULL, NULL), "new http client cache"); | ||||
|         TEST_ASSIGN(client1, httpClientCacheGet(cache), "get http client"); | ||||
|         TEST_RESULT_PTR(client1, *(HttpClient **)lstGet(cache->clientList, 0), "    check http client"); | ||||
|         TEST_RESULT_PTR(httpClientCacheGet(cache), *(HttpClient **)lstGet(cache->clientList, 0), "    get same http client"); | ||||
|   | ||||
| @@ -16,7 +16,7 @@ testTlsServerAltName(void) | ||||
|     if (fork() == 0) | ||||
|     { | ||||
|         harnessTlsServerInit( | ||||
|             TLS_TEST_PORT, | ||||
|             harnessTlsTestPort(), | ||||
|             strPtr(strNewFmt("%s/" TEST_CERTIFICATE_PREFIX "-alt-name.crt", testRepoPath())), | ||||
|             strPtr(strNewFmt("%s/" TEST_CERTIFICATE_PREFIX ".key", testRepoPath()))); | ||||
|  | ||||
| @@ -121,7 +121,7 @@ testRun(void) | ||||
|     { | ||||
|         TlsClient *client = NULL; | ||||
|  | ||||
|         TEST_ASSIGN(client, tlsClientNew(strNew("99.99.99.99.99"), TLS_TEST_PORT, 0, true, NULL, NULL), "new client"); | ||||
|         TEST_ASSIGN(client, tlsClientNew(strNew("99.99.99.99.99"), harnessTlsTestPort(), 0, true, NULL, NULL), "new client"); | ||||
|  | ||||
|         TEST_RESULT_BOOL(tlsError(client, SSL_ERROR_WANT_READ), true, "continue after want read"); | ||||
|         TEST_RESULT_BOOL(tlsError(client, SSL_ERROR_ZERO_RETURN), false, "check connection closed error"); | ||||
| @@ -135,14 +135,14 @@ testRun(void) | ||||
|  | ||||
|         // Connection errors | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         TEST_ASSIGN(client, tlsClientNew(strNew("99.99.99.99.99"), TLS_TEST_PORT, 0, true, NULL, NULL), "new client"); | ||||
|         TEST_ASSIGN(client, tlsClientNew(strNew("99.99.99.99.99"), harnessTlsTestPort(), 0, true, NULL, NULL), "new client"); | ||||
|         TEST_ERROR( | ||||
|             tlsClientOpen(client), HostConnectError, "unable to get address for '99.99.99.99.99': [-2] Name or service not known"); | ||||
|  | ||||
|         TEST_ASSIGN(client, tlsClientNew(strNew("localhost"), TLS_TEST_PORT, 100, true, NULL, NULL), "new client"); | ||||
|         TEST_ASSIGN(client, tlsClientNew(strNew("localhost"), harnessTlsTestPort(), 100, true, NULL, NULL), "new client"); | ||||
|         TEST_ERROR_FMT( | ||||
|             tlsClientOpen(client), HostConnectError, "unable to connect to 'localhost:%d': [111] Connection refused", | ||||
|             TLS_TEST_PORT); | ||||
|             tlsClientOpen(client), HostConnectError, "unable to connect to 'localhost:%u': [111] Connection refused", | ||||
|             harnessTlsTestPort()); | ||||
|  | ||||
|         // Certificate location and validation errors | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -161,28 +161,29 @@ testRun(void) | ||||
|         testTlsServerAltName(); | ||||
|  | ||||
|         TEST_ERROR( | ||||
|             tlsClientOpen(tlsClientNew(strNew("localhost"), TLS_TEST_PORT, 500, true, strNew("bogus.crt"), strNew("/bogus"))), | ||||
|             tlsClientOpen( | ||||
|                 tlsClientNew(strNew("localhost"), harnessTlsTestPort(), 500, true, strNew("bogus.crt"), strNew("/bogus"))), | ||||
|             CryptoError, "unable to set user-defined CA certificate location: [33558530] No such file or directory"); | ||||
|         TEST_ERROR_FMT( | ||||
|             tlsClientOpen(tlsClientNew(strNew("localhost"), TLS_TEST_PORT, 500, true, NULL, strNew("/bogus"))), | ||||
|             CryptoError, "unable to verify certificate presented by 'localhost:%d': [20] unable to get local issuer certificate", | ||||
|             TLS_TEST_PORT); | ||||
|             tlsClientOpen(tlsClientNew(strNew("localhost"), harnessTlsTestPort(), 500, true, NULL, strNew("/bogus"))), | ||||
|             CryptoError, "unable to verify certificate presented by 'localhost:%u': [20] unable to get local issuer certificate", | ||||
|             harnessTlsTestPort()); | ||||
|  | ||||
|         if (testContainer()) | ||||
|         { | ||||
|             TEST_RESULT_VOID( | ||||
|                 tlsClientOpen( | ||||
|                     tlsClientNew(strNew("test.pgbackrest.org"), TLS_TEST_PORT, 500, true, | ||||
|                     tlsClientNew(strNew("test.pgbackrest.org"), harnessTlsTestPort(), 500, true, | ||||
|                     strNewFmt("%s/" TEST_CERTIFICATE_PREFIX "-ca.crt", testRepoPath()), NULL)), | ||||
|                 "success on valid ca file and match common name"); | ||||
|             TEST_RESULT_VOID( | ||||
|                 tlsClientOpen( | ||||
|                     tlsClientNew(strNew("host.test2.pgbackrest.org"), TLS_TEST_PORT, 500, true, | ||||
|                     tlsClientNew(strNew("host.test2.pgbackrest.org"), harnessTlsTestPort(), 500, true, | ||||
|                     strNewFmt("%s/" TEST_CERTIFICATE_PREFIX "-ca.crt", testRepoPath()), NULL)), | ||||
|                 "success on valid ca file and match alt name"); | ||||
|             TEST_ERROR( | ||||
|                 tlsClientOpen( | ||||
|                     tlsClientNew(strNew("test3.pgbackrest.org"), TLS_TEST_PORT, 500, true, | ||||
|                     tlsClientNew(strNew("test3.pgbackrest.org"), harnessTlsTestPort(), 500, true, | ||||
|                     strNewFmt("%s/" TEST_CERTIFICATE_PREFIX "-ca.crt", testRepoPath()), NULL)), | ||||
|                 CryptoError, | ||||
|                 "unable to find hostname 'test3.pgbackrest.org' in certificate common name or subject alternative names"); | ||||
| @@ -191,13 +192,14 @@ testRun(void) | ||||
|         TEST_ERROR_FMT( | ||||
|             tlsClientOpen( | ||||
|                 tlsClientNew( | ||||
|                     strNew("localhost"), TLS_TEST_PORT, 500, true, strNewFmt("%s/" TEST_CERTIFICATE_PREFIX ".crt", testRepoPath()), | ||||
|                     strNew("localhost"), harnessTlsTestPort(), 500, true, strNewFmt("%s/" TEST_CERTIFICATE_PREFIX ".crt", | ||||
|                     testRepoPath()), | ||||
|                 NULL)), | ||||
|             CryptoError, "unable to verify certificate presented by 'localhost:%d': [20] unable to get local issuer certificate", | ||||
|             TLS_TEST_PORT); | ||||
|             CryptoError, "unable to verify certificate presented by 'localhost:%u': [20] unable to get local issuer certificate", | ||||
|             harnessTlsTestPort()); | ||||
|  | ||||
|         TEST_RESULT_VOID( | ||||
|             tlsClientOpen(tlsClientNew(strNew("localhost"), TLS_TEST_PORT, 500, false, NULL, NULL)), "success on no verify"); | ||||
|             tlsClientOpen(tlsClientNew(strNew("localhost"), harnessTlsTestPort(), 500, false, NULL, NULL)), "success on no verify"); | ||||
|     } | ||||
|     // ***************************************************************************************************************************** | ||||
|     if (testBegin("TlsClient general usage")) | ||||
| @@ -211,7 +213,8 @@ testRun(void) | ||||
|         testTlsServer(); | ||||
|         ioBufferSizeSet(12); | ||||
|  | ||||
|         TEST_ASSIGN(client, tlsClientNew(harnessTlsTestHost(), TLS_TEST_PORT, 500, testContainer(), NULL, NULL), "new client"); | ||||
|         TEST_ASSIGN( | ||||
|             client, tlsClientNew(harnessTlsTestHost(), harnessTlsTestPort(), 500, testContainer(), NULL, NULL), "new client"); | ||||
|         TEST_RESULT_VOID(tlsClientOpen(client), "open client"); | ||||
|  | ||||
|         const Buffer *input = BUFSTRDEF("some protocol info"); | ||||
| @@ -234,7 +237,7 @@ testRun(void) | ||||
|         output = bufNew(12); | ||||
|         TEST_ERROR_FMT( | ||||
|             ioRead(tlsClientIoRead(client), output), FileReadError, | ||||
|             "timeout after 500ms waiting for read from '%s:%d'", strPtr(harnessTlsTestHost()), TLS_TEST_PORT); | ||||
|             "timeout after 500ms waiting for read from '%s:%u'", strPtr(harnessTlsTestHost()), harnessTlsTestPort()); | ||||
|  | ||||
|         // ------------------------------------------------------------------------------------------------------------------------- | ||||
|         input = BUFSTRDEF("more protocol info"); | ||||
|   | ||||
| @@ -510,7 +510,7 @@ testRun(void) | ||||
|     const String *region = strNew("us-east-1"); | ||||
|     const String *endPoint = strNew("s3.amazonaws.com"); | ||||
|     const String *host = harnessTlsTestHost(); | ||||
|     const unsigned int port = TLS_TEST_PORT; | ||||
|     const unsigned int port = harnessTlsTestPort(); | ||||
|     const String *accessKey = strNew("AKIAIOSFODNN7EXAMPLE"); | ||||
|     const String *secretAccessKey = strNew("wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"); | ||||
|     const String *securityToken = strNew( | ||||
|   | ||||
| @@ -32,6 +32,7 @@ The test code is included directly so it can freely interact with the included C | ||||
|  | ||||
| void testContainerSet(bool testContainer); | ||||
| void testDataPathSet(const char *testDataPath); | ||||
| void testIdxSet(unsigned int testIdx); | ||||
| void testScaleSet(uint64_t testScale); | ||||
| void testProjectExeSet(const char *testProjectExe); | ||||
|  | ||||
| @@ -88,6 +89,7 @@ main(int argListSize, const char *argList[]) | ||||
|     testPathSet("{[C_TEST_PATH]}"); | ||||
|     testRepoPathSet("{[C_TEST_REPO_PATH]}"); | ||||
|     testDataPathSet("{[C_TEST_DATA_PATH]}"); | ||||
|     testIdxSet({[C_TEST_IDX]}); | ||||
|     testScaleSet({[C_TEST_SCALE]}); | ||||
|  | ||||
|     // Set default test log level | ||||
|   | ||||
| @@ -201,8 +201,6 @@ eval | ||||
|             processEnd(); | ||||
|  | ||||
|             # Run tests | ||||
|             $strParam .= " --vm-max=2"; | ||||
|  | ||||
|             if ($strVm eq VM_U18) | ||||
|             { | ||||
|                 $strParam .= " --container-only"; | ||||
| @@ -219,7 +217,7 @@ eval | ||||
|  | ||||
|         processBegin(($strVm eq VM_NONE ? "no container" : $strVm) . ' test'); | ||||
|         processExec( | ||||
|             "${strTestExe} --no-gen --vm-host=${strVmHost} --vm=${strVm}${strParam}", | ||||
|             "${strTestExe} --no-gen --vm-host=${strVmHost} --vm-max=2 --vm=${strVm}${strParam}", | ||||
|             {bShowOutputAsync => true, bOutLogOnError => false}); | ||||
|         processEnd(); | ||||
|     } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user