| /* This Source Code Form is subject to the terms of the Mozilla Public |
| * License, v. 2.0. If a copy of the MPL was not distributed with this |
| * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| /* |
| * testutil.c |
| * |
| * Utility error handling functions |
| * |
| */ |
| |
| #include "testutil.h" |
| |
| /* |
| * static global variable to keep track of total number of errors for |
| * a particular test suite (eg. all the OID tests) |
| */ |
| static int errCount = 0; |
| |
| /* |
| * FUNCTION: startTests |
| * DESCRIPTION: |
| * |
| * Prints standard message for starting the test suite with the name pointed |
| * to by "testName". This function should be called in the beginning of every |
| * test suite. |
| * |
| * PARAMETERS: |
| * "testName" |
| * Address of string representing name of test suite. |
| * THREAD SAFETY: |
| * Not Thread Safe - assumes exclusive access to "errCount" |
| * (see Thread Safety Definitions in Programmer's Guide) |
| * RETURNS: |
| * Returns nothing. |
| */ |
| void |
| startTests(char *testName) |
| { |
| (void)printf("*START OF TESTS FOR %s:\n", testName); |
| errCount = 0; |
| } |
| |
| /* |
| * FUNCTION: endTests |
| * DESCRIPTION: |
| * |
| * Prints standard message for ending the test suite with the name pointed |
| * to by "testName", followed by a success/failure message. This function |
| * should be called at the end of every test suite. |
| * |
| * PARAMETERS: |
| * "testName" |
| * Address of string representing name of test suite. |
| * THREAD SAFETY: |
| * Not Thread Safe - assumes exclusive access to "errCount" |
| * (see Thread Safety Definitions in Programmer's Guide) |
| * RETURNS: |
| * Returns nothing. |
| */ |
| void |
| endTests(char *testName) |
| { |
| char plural = ' '; |
| |
| (void)printf("*END OF TESTS FOR %s: ", testName); |
| if (errCount > 0) { |
| if (errCount > 1) |
| plural = 's'; |
| (void)printf("%d SUBTEST%c FAILED.\n\n", errCount, plural); |
| } else { |
| (void)printf("ALL TESTS COMPLETED SUCCESSFULLY.\n\n"); |
| } |
| } |
| |
| /* |
| * FUNCTION: subTest |
| * DESCRIPTION: |
| * |
| * Prints standard message for starting the subtest with the name pointed to |
| * by "subTestName". This function should be called at the beginning of each |
| * subtest. |
| * |
| * PARAMETERS: |
| * "subTestName" |
| * Address of string representing name of subTest. |
| * THREAD SAFETY: |
| * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
| * RETURNS: |
| * Returns nothing. |
| */ |
| void |
| subTest(char *subTestName) |
| { |
| (void)printf("TESTING: %s ...\n", subTestName); |
| } |
| |
| /* |
| * FUNCTION: testErrorUndo |
| * DESCRIPTION: |
| * |
| * Decrements the global variable "errCount" and prints a test failure |
| * expected message followed by the string pointed to by "msg". This function |
| * should be called when an expected error condition is encountered in the |
| * tests. Calling this function *correct* the previous errCount increment. |
| * It should only be called ONCE per subtest. |
| * |
| * PARAMETERS: |
| * "msg" |
| * Address of text of error message. |
| * THREAD SAFETY: |
| * Not Thread Safe - assumes exclusive access to "errCount" |
| * (see Thread Safety Definitions in Programmer's Guide) |
| * RETURNS: |
| * Returns nothing. |
| */ |
| void |
| testErrorUndo(char *msg) |
| { |
| --errCount; |
| (void)printf("TEST FAILURE *** EXPECTED *** :%s\n", msg); |
| } |
| |
| /* |
| * FUNCTION: testError |
| * DESCRIPTION: |
| * |
| * Increments the global variable "errCount" and prints a standard test |
| * failure message followed by the string pointed to by "msg". This function |
| * should be called when an unexpected error condition is encountered in the |
| * tests. It should only be called ONCE per subtest. |
| * |
| * PARAMETERS: |
| * "msg" |
| * Address of text of error message. |
| * THREAD SAFETY: |
| * Not Thread Safe - assumes exclusive access to "errCount" |
| * (see Thread Safety Definitions in Programmer's Guide) |
| * RETURNS: |
| * Returns nothing. |
| */ |
| void |
| testError(char *msg) |
| { |
| ++errCount; |
| (void)printf("TEST FAILURE: %s\n", msg); |
| } |
| |
| /* |
| * FUNCTION: PKIX_String2ASCII |
| * DESCRIPTION: |
| * |
| * Converts String object pointed to by "string" to its ASCII representation |
| * and returns the converted value. Returns NULL upon failure. |
| * |
| * XXX Might want to use ESCASCII_DEBUG to show control characters, etc. |
| * |
| * PARAMETERS: |
| * "string" |
| * Address of String to be converted to ASCII. Must be non-NULL. |
| * "plContext" |
| * Platform-specific context pointer. |
| * THREAD SAFETY: |
| * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
| * RETURNS: |
| * Returns the ASCII representation of "string" upon success; |
| * NULL upon failure. |
| */ |
| char * |
| PKIX_String2ASCII(PKIX_PL_String *string, void *plContext) |
| { |
| PKIX_UInt32 length; |
| char *asciiString = NULL; |
| PKIX_Error *errorResult; |
| |
| errorResult = PKIX_PL_String_GetEncoded(string, |
| PKIX_ESCASCII, |
| (void **)&asciiString, |
| &length, |
| plContext); |
| |
| if (errorResult) |
| goto cleanup; |
| |
| cleanup: |
| |
| if (errorResult) { |
| return (NULL); |
| } |
| |
| return (asciiString); |
| } |
| |
| /* |
| * FUNCTION: PKIX_Error2ASCII |
| * DESCRIPTION: |
| * |
| * Converts Error pointed to by "error" to its ASCII representation and |
| * returns the converted value. Returns NULL upon failure. |
| * |
| * PARAMETERS: |
| * "error" |
| * Address of Error to be converted to ASCII. Must be non-NULL. |
| * "plContext" |
| * Platform-specific context pointer. |
| * THREAD SAFETY: |
| * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
| * RETURNS: |
| * Returns the ASCII representation of "error" upon success; |
| * NULL upon failure. |
| */ |
| char * |
| PKIX_Error2ASCII(PKIX_Error *error, void *plContext) |
| { |
| PKIX_UInt32 length; |
| char *asciiString = NULL; |
| PKIX_PL_String *pkixString = NULL; |
| PKIX_Error *errorResult = NULL; |
| |
| errorResult = PKIX_PL_Object_ToString((PKIX_PL_Object *)error, &pkixString, plContext); |
| if (errorResult) |
| goto cleanup; |
| |
| errorResult = PKIX_PL_String_GetEncoded(pkixString, |
| PKIX_ESCASCII, |
| (void **)&asciiString, |
| &length, |
| plContext); |
| |
| cleanup: |
| |
| if (pkixString) { |
| if (PKIX_PL_Object_DecRef((PKIX_PL_Object *)pkixString, plContext)) { |
| return (NULL); |
| } |
| } |
| |
| if (errorResult) { |
| return (NULL); |
| } |
| |
| return (asciiString); |
| } |
| |
| /* |
| * FUNCTION: PKIX_Object2ASCII |
| * DESCRIPTION: |
| * |
| * Converts Object pointed to by "object" to its ASCII representation and |
| * returns the converted value. Returns NULL upon failure. |
| * |
| * PARAMETERS: |
| * "object" |
| * Address of Object to be converted to ASCII. Must be non-NULL. |
| * THREAD SAFETY: |
| * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
| * RETURNS: |
| * Returns the ASCII representation of "object" upon success; |
| * NULL upon failure. |
| */ |
| char * |
| PKIX_Object2ASCII(PKIX_PL_Object *object) |
| { |
| PKIX_UInt32 length; |
| char *asciiString = NULL; |
| PKIX_PL_String *pkixString = NULL; |
| PKIX_Error *errorResult = NULL; |
| |
| errorResult = PKIX_PL_Object_ToString(object, &pkixString, NULL); |
| if (errorResult) |
| goto cleanup; |
| |
| errorResult = PKIX_PL_String_GetEncoded(pkixString, PKIX_ESCASCII, (void **)&asciiString, &length, NULL); |
| |
| cleanup: |
| |
| if (pkixString) { |
| if (PKIX_PL_Object_DecRef((PKIX_PL_Object *)pkixString, NULL)) { |
| return (NULL); |
| } |
| } |
| |
| if (errorResult) { |
| return (NULL); |
| } |
| |
| return (asciiString); |
| } |
| |
| /* |
| * FUNCTION: PKIX_Cert2ASCII |
| * DESCRIPTION: |
| * |
| * Converts Cert pointed to by "cert" to its partial ASCII representation and |
| * returns the converted value. Returns NULL upon failure. |
| * |
| * PARAMETERS: |
| * "cert" |
| * Address of Cert to be converted to ASCII. Must be non-NULL. |
| * THREAD SAFETY: |
| * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
| * RETURNS: |
| * Returns the partial ASCII representation of "cert" upon success; |
| * NULL upon failure. |
| */ |
| char * |
| PKIX_Cert2ASCII(PKIX_PL_Cert *cert) |
| { |
| PKIX_PL_X500Name *issuer = NULL; |
| void *issuerAscii = NULL; |
| PKIX_PL_X500Name *subject = NULL; |
| void *subjectAscii = NULL; |
| void *asciiString = NULL; |
| PKIX_Error *errorResult = NULL; |
| PKIX_UInt32 numChars; |
| |
| /* Issuer */ |
| errorResult = PKIX_PL_Cert_GetIssuer(cert, &issuer, NULL); |
| if (errorResult) |
| goto cleanup; |
| |
| issuerAscii = PKIX_Object2ASCII((PKIX_PL_Object *)issuer); |
| |
| /* Subject */ |
| errorResult = PKIX_PL_Cert_GetSubject(cert, &subject, NULL); |
| if (errorResult) |
| goto cleanup; |
| |
| if (subject) { |
| subjectAscii = PKIX_Object2ASCII((PKIX_PL_Object *)subject); |
| } |
| |
| errorResult = PKIX_PL_Malloc(200, &asciiString, NULL); |
| if (errorResult) |
| goto cleanup; |
| |
| numChars = |
| PR_snprintf(asciiString, |
| 200, |
| "Issuer=%s\nSubject=%s\n", |
| issuerAscii, |
| subjectAscii); |
| |
| if (!numChars) |
| goto cleanup; |
| |
| cleanup: |
| |
| if (issuer) { |
| if (PKIX_PL_Object_DecRef((PKIX_PL_Object *)issuer, NULL)) { |
| return (NULL); |
| } |
| } |
| |
| if (subject) { |
| if (PKIX_PL_Object_DecRef((PKIX_PL_Object *)subject, NULL)) { |
| return (NULL); |
| } |
| } |
| |
| if (PKIX_PL_Free((PKIX_PL_Object *)issuerAscii, NULL)) { |
| return (NULL); |
| } |
| |
| if (PKIX_PL_Free((PKIX_PL_Object *)subjectAscii, NULL)) { |
| return (NULL); |
| } |
| |
| if (errorResult) { |
| return (NULL); |
| } |
| |
| return (asciiString); |
| } |
| |
| /* |
| * FUNCTION: testHashcodeHelper |
| * DESCRIPTION: |
| * |
| * Computes the hashcode of the Object pointed to by "goodObject" and the |
| * Object pointed to by "otherObject" and compares them. If the result of the |
| * comparison is not the desired match as specified by "match", an error |
| * message is generated. |
| * |
| * PARAMETERS: |
| * "goodObject" |
| * Address of an object. Must be non-NULL. |
| * "otherObject" |
| * Address of another object. Must be non-NULL. |
| * "match" |
| * Boolean value representing the desired comparison result. |
| * "plContext" |
| * Platform-specific context pointer. |
| * THREAD SAFETY: |
| * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
| * RETURNS: |
| * Returns nothing. |
| */ |
| void |
| testHashcodeHelper( |
| PKIX_PL_Object *goodObject, |
| PKIX_PL_Object *otherObject, |
| PKIX_Boolean match, |
| void *plContext) |
| { |
| |
| PKIX_UInt32 goodHash; |
| PKIX_UInt32 otherHash; |
| PKIX_Boolean cmpResult; |
| PKIX_TEST_STD_VARS(); |
| |
| PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Hashcode((PKIX_PL_Object *)goodObject, &goodHash, plContext)); |
| |
| PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Hashcode((PKIX_PL_Object *)otherObject, &otherHash, plContext)); |
| |
| cmpResult = (goodHash == otherHash); |
| |
| if ((match && !cmpResult) || (!match && cmpResult)) { |
| testError("unexpected mismatch"); |
| (void)printf("Hash1:\t%d\n", goodHash); |
| (void)printf("Hash2:\t%d\n", otherHash); |
| } |
| |
| cleanup: |
| |
| PKIX_TEST_RETURN(); |
| } |
| |
| /* |
| * FUNCTION: testToStringHelper |
| * DESCRIPTION: |
| * |
| * Calls toString on the Object pointed to by "goodObject" and compares the |
| * result to the string pointed to by "expected". If the results are not |
| * equal, an error message is generated. |
| * |
| * PARAMETERS: |
| * "goodObject" |
| * Address of Object. Must be non-NULL. |
| * "expected" |
| * Address of the desired string. |
| * "plContext" |
| * Platform-specific context pointer. |
| * THREAD SAFETY: |
| * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
| * RETURNS: |
| * Returns nothing. |
| */ |
| void |
| testToStringHelper( |
| PKIX_PL_Object *goodObject, |
| char *expected, |
| void *plContext) |
| { |
| PKIX_PL_String *stringRep = NULL; |
| char *actual = NULL; |
| PKIX_TEST_STD_VARS(); |
| |
| PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString(goodObject, &stringRep, plContext)); |
| |
| actual = PKIX_String2ASCII(stringRep, plContext); |
| if (actual == NULL) { |
| pkixTestErrorMsg = "PKIX_String2ASCII Failed"; |
| goto cleanup; |
| } |
| |
| /* |
| * If you are having trouble matching the string, uncomment the |
| * PL_strstr function to figure out what's going on. |
| */ |
| |
| /* |
| if (PL_strstr(actual, expected) == NULL){ |
| testError("PL_strstr failed"); |
| } |
| */ |
| |
| if (PL_strcmp(actual, expected) != 0) { |
| testError("unexpected mismatch"); |
| (void)printf("Actual value:\t%s\n", actual); |
| (void)printf("Expected value:\t%s\n", expected); |
| } |
| |
| cleanup: |
| |
| PKIX_PL_Free(actual, plContext); |
| |
| PKIX_TEST_DECREF_AC(stringRep); |
| |
| PKIX_TEST_RETURN(); |
| } |
| |
| /* |
| * FUNCTION: testEqualsHelper |
| * DESCRIPTION: |
| * |
| * Checks if the Object pointed to by "goodObject" is Equal to the Object |
| * pointed to by "otherObject". If the result of the check is not the desired |
| * match as specified by "match", an error message is generated. |
| * |
| * PARAMETERS: |
| * "goodObject" |
| * Address of an Object. Must be non-NULL. |
| * "otherObject" |
| * Address of another Object. Must be non-NULL. |
| * "match" |
| * Boolean value representing the desired comparison result. |
| * "plContext" |
| * Platform-specific context pointer. |
| * THREAD SAFETY: |
| * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
| * RETURNS: |
| * Returns nothing. |
| */ |
| void |
| testEqualsHelper( |
| PKIX_PL_Object *goodObject, |
| PKIX_PL_Object *otherObject, |
| PKIX_Boolean match, |
| void *plContext) |
| { |
| |
| PKIX_Boolean cmpResult; |
| PKIX_TEST_STD_VARS(); |
| |
| PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals(goodObject, otherObject, &cmpResult, plContext)); |
| |
| if ((match && !cmpResult) || (!match && cmpResult)) { |
| testError("unexpected mismatch"); |
| (void)printf("Actual value:\t%d\n", cmpResult); |
| (void)printf("Expected value:\t%d\n", match); |
| } |
| |
| cleanup: |
| |
| PKIX_TEST_RETURN(); |
| } |
| |
| /* |
| * FUNCTION: testDuplicateHelper |
| * DESCRIPTION: |
| * Checks if the Object pointed to by "object" is equal to its duplicate. |
| * If the result of the check is not equality, an error message is generated. |
| * PARAMETERS: |
| * "object" |
| * Address of Object. Must be non-NULL. |
| * "plContext" |
| * Platform-specific context pointer. |
| * THREAD SAFETY: |
| * Thread Safe (see Thread Safety Definitions in Programmer's Guide) |
| * RETURNS: |
| * Returns nothing. |
| */ |
| void |
| testDuplicateHelper(PKIX_PL_Object *object, void *plContext) |
| { |
| PKIX_PL_Object *newObject = NULL; |
| PKIX_Boolean cmpResult; |
| |
| PKIX_TEST_STD_VARS(); |
| |
| PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Duplicate(object, &newObject, plContext)); |
| |
| PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals(object, newObject, &cmpResult, plContext)); |
| |
| if (!cmpResult) { |
| testError("unexpected mismatch"); |
| (void)printf("Actual value:\t%d\n", cmpResult); |
| (void)printf("Expected value:\t%d\n", PKIX_TRUE); |
| } |
| |
| cleanup: |
| |
| PKIX_TEST_DECREF_AC(newObject); |
| |
| PKIX_TEST_RETURN(); |
| } |