blob: 5e51dc9fddd487cf1476dcd5fae417e185191427 [file] [log] [blame]
#include "Config.h"
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include "Bootstrap.h"
#include "Str.h"
#include "Thread.h"
#include "Exception.h"
#include "AssertException.h"
/**
* Exception unity tests
*/
#define THREADS 200
Exception_T A= {"AException"};
Exception_T B= {"BException"};
Exception_T C= {"CException"};
Exception_T D= {"DException"};
void throwA() {
THROW(A, NULL);
}
void throwB() {
THROW(B, NULL);
}
void throwC() {
THROW(C, "A cause");
}
void throwD() {
THROW(D, "A cause");
}
void indirectA() {
throwA();
}
/* Throw and catch exceptions and check that we got the expected exception.
* If the exception stack is corrupt somehow this should be detected
*/
void *thread(void *args) {
TRY
THROW(A, "A cause");
assert(false); // Should not be reached
CATCH(A)
// Ok
ELSE
assert(false); // Should not be reached
END_TRY;
TRY
THROW(B, "A cause");
assert(false); // Should not be reached
CATCH(B)
// Ok
ELSE
assert(false); // Should not be reached
END_TRY;
TRY
THROW(D, NULL);
assert(false); // Should not be reached
CATCH(D)
// Ok
ELSE
assert(false); // Should not be reached
END_TRY;
TRY
THROW(C, NULL);
assert(false); // Should not be reached
CATCH(C)
// Ok
ELSE
assert(false); // Should not be reached
END_TRY;
TRY
THROW(A, NULL);
assert(false); // Should not be reached
CATCH(A)
// Ok
ELSE
assert(false); // Should not be reached
END_TRY;
TRY
throwA();
throwB();
throwC();
throwD();
CATCH(A)
// Ok
CATCH(B)
assert(false); // Should not be reached
CATCH(C)
assert(false); // Should not be reached
CATCH(D)
assert(false); // Should not be reached
END_TRY;
TRY
indirectA();
CATCH(A)
// Ok
ELSE
assert(false); // Should not be reached
END_TRY;
TRY
THROW(B, NULL);
assert(false); // Should not be reached
CATCH(B)
// Ok
ELSE
assert(false); // Should not be reached
END_TRY;
TRY
THROW(B, NULL);
assert(false); // Should not be reached
CATCH(B)
// Ok
ELSE
assert(false); // Should not be reached
END_TRY;
TRY
THROW(B, NULL);
assert(false); // Should not be reached
CATCH(B)
// Ok
ELSE
assert(false); // Should not be reached
END_TRY;
TRY
THROW(B, "A cause %s", "and another cause");
assert(false); // Should not be reached
CATCH(B)
// Ok
ELSE
assert(false); // Should not be reached
END_TRY;
TRY
THROW(A, NULL);
assert(false); // Should not be reached
CATCH(A)
// Ok
ELSE
assert(false); // Should not be reached
END_TRY;
TRY
THROW(B, NULL);
assert(false); // Should not be reached
CATCH(B)
// Ok
ELSE
assert(false); // Should not be reached
END_TRY;
TRY
THROW(D, NULL);
assert(false); // Should not be reached
CATCH(D)
// Ok
ELSE
assert(false); // Should not be reached
END_TRY;
TRY
RETURN (NULL);
assert(false); // Should not be reached
CATCH(A)
assert(false); // Should not be reached
END_TRY;
return NULL;
}
int main(void) {
Bootstrap(); // Need to initialize library
printf("============> Start Exeption Tests\n\n");
printf("=> Test1: TRY-CATCH\n");
{
TRY
THROW(A, "A cause");
assert(false); // Should not be reached
CATCH(A)
printf("\tResult: Ok\n");
END_TRY;
}
printf("=> Test1: OK\n\n");
printf("=> Test2: TRY-CATCH indirect throw\n");
{
TRY
indirectA();
assert(false); // Should not be reached
CATCH(A)
printf("\tResult: Ok\n");
END_TRY;
}
printf("=> Test2: OK\n\n");
printf("=> Test3: TRY-ELSE\n");
{
TRY
THROW(B, NULL);
assert(false); // Should not be reached
ELSE
printf("\tResult: Ok\n");
END_TRY;
}
printf("=> Test3: OK\n\n");
printf("=> Test4: TRY-CATCH-ELSE\n");
{
TRY
throwB();
assert(false); // Should not be reached
CATCH(A)
assert(false); // Should not be reached
ELSE
printf("\tResult: Ok\n");
END_TRY;
}
printf("=> Test4: OK\n\n");
printf("=> Test5: TRY-FINALLY\n");
{
int i= 0;
TRY
i++;
FINALLY
printf("\tResult: ok\n");
assert(i==1);
END_TRY;
}
printf("=> Test5: OK\n\n");
printf("=> Test6: TRY-CATCH-FINALLY\n");
{
volatile int i = 0;
TRY
i++;
THROW(C, "A cause");
CATCH(C)
i++;
FINALLY
printf("\tResult: ok\n");
assert(i == 2);
END_TRY;
}
printf("=> Test6: OK\n\n");
printf("=> Test7: CATCH NumberFormatException\n");
{
TRY
Str_parseInt("not a number");
assert(false); // Should not be reached
CATCH(NumberFormatException)
printf("\tResult: ok got NumberFormatException\n");
END_TRY;
}
printf("=> Test7: OK\n\n");
printf("=> Test8: CATCH AssertException\n");
{
TRY
assert(false); // Throws AssertException
printf("Test8 failed\n");
exit(1);
CATCH(AssertException)
printf("\tResult: ok got AssertException\n");
END_TRY;
}
printf("=> Test8: OK\n\n");
printf("=> Test9: Nested TRY-CATCH\n");
{
TRY
TRY
THROW(B, "A cause");
THROW(A, "Another cause");
assert(false); // Should not be reached
CATCH(A)
assert(false); // Should not be reached
END_TRY;
CATCH(B)
printf("\tResult: ok\n");
END_TRY;
}
printf("=> Test9: OK\n\n");
printf("=> Test10: RETHROW\n");
{
TRY
TRY
THROW(A, "A cause %s", "and a cause");
assert(false); // Should not be reached
CATCH(A)
RETHROW;
END_TRY;
CATCH(A)
printf("\tResult: ok got Exception\n");
END_TRY;
}
printf("=> Test10: OK\n\n");
printf("=> Test11: No exception thrown\n");
{
TRY
int i= 0; i++;
ELSE
assert(false); // Should not be reached
END_TRY;
}
printf("=> Test11: OK\n\n");
printf("=> Test12: Exception message append\n");
{
TRY
TRY
THROW(AssertException, "Original reason");
exit(0); // Should not be reached
CATCH(AssertException)
THROW(AssertException, "%s - Appended reason", Exception_frame.message);
END_TRY;
CATCH(AssertException)
printf("\tResult: Got '%s' with reason: %s\n", AssertException.name, Exception_frame.message);
assert(Str_startsWith(Exception_frame.message, "Original"));
END_TRY;
}
printf("=> Test12: OK\n\n");
printf("=> Test13: FINALLY rethrows exception\n");
{
TRY
{
TRY
{
THROW(AssertException, "A reason");
exit(0); // Should not be reached
}
FINALLY
END_TRY;
exit(0); // Should not be reached
}
CATCH(AssertException)
{
printf("\tResult: Got '%s' thrown from FINALLY\n", AssertException.name);
}
END_TRY;
}
printf("=> Test13: OK\n\n");
printf("=> Test14: Test thread-safeness\n");
{
int i;
Thread_T threads[THREADS];
for (i= 0; i < THREADS; i++) {
Thread_create(threads[i], thread, NULL);
}
for (i= 0; i<THREADS; i++)
Thread_join(threads[i]);
}
printf("=> Test14: OK\n\n");
printf("============> Exception Tests: OK\n\n");
return 0;
}