Source code
Revision control
Copy as Markdown
Other Tools
/* 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
/*
* 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();
}