test_helpers.h 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #ifndef _TEST_HELPERS
  2. #define _TEST_HELPERS
  3. #include <errno.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <unistd.h>
  8. // Throws errors on a well-defined API error values.
  9. //
  10. // Only use with API functions that sets the errno variable.
  11. // Do not pass functions as the status or condition arguments, they might be
  12. // evaluated multiple times.
  13. //
  14. // Usage example:
  15. //
  16. // > Upon successful completion, fclose() returns 0.
  17. // > Otherwise, it returns EOF and sets errno to indicate the error.
  18. //
  19. // int status = fclose(fp);
  20. // ERROR_IF(fclose, status, == EOF);
  21. //
  22. // Use it only for checking the API error values.
  23. // Do not use it for checking the correctness of the results. If you need to
  24. // do that, print the values to the standard output and use the expected outputs
  25. // directory.
  26. //
  27. // For example:
  28. //
  29. // int c = fgetc(f); // !!! DO NOT USE THIS WAY !!!
  30. // ERROR_IF(fgetc, c, != 'H'); // !!! DO NOT USE THIS WAY !!!
  31. //
  32. // Correct usage:
  33. //
  34. // int c = fgetc(f); // OK
  35. // ERROR_IF(fgetc, c, == EOF); // OK
  36. // printf("result: %c\n", c); // OK
  37. //
  38. #define ERROR_IF(func, status, condition) { \
  39. if (status condition) { \
  40. fprintf(stderr, "%s:%s:%d: '%s' failed: %s (%d)\n", \
  41. __FILE__, __func__, __LINE__, #func, strerror(errno), errno); \
  42. _exit(EXIT_FAILURE); \
  43. } \
  44. }
  45. // Throws errors on API return values not defined by the standards.
  46. //
  47. // Do not pass functions as the status or condition arguments, they might be
  48. // evaluated multiple times.
  49. //
  50. // Use it only for detecting return values that should have never been returned
  51. // in any case by the API functions.
  52. //
  53. // Usage example:
  54. //
  55. // > The fgetc() function obtains the next byte as an unsigned char
  56. // > converted to an int.
  57. //
  58. // int c = fgetc(f);
  59. // UNEXP_IF(fgetc, c, < 0);
  60. // UNEXP_IF(fgetc, c, > 255);
  61. //
  62. #define UNEXP_IF(func, status, condition) { \
  63. if (status condition) { \
  64. fprintf(stderr, "%s:%s:%d: '%s' returned a non-standard value: ", \
  65. __FILE__, __func__, __LINE__, #func); \
  66. fprintf(stderr, _Generic((status), \
  67. char *: "char*(%p) = \"%1$s\"", \
  68. void *: "void*(%p)", \
  69. default: "%i" \
  70. ), status); \
  71. fprintf(stderr, "\n"); \
  72. _exit(EXIT_FAILURE); \
  73. } \
  74. }
  75. // A convenience macro to show where the test fail.
  76. #define exit(code) { \
  77. if (code != EXIT_SUCCESS) { \
  78. fprintf(stderr, "%s:%s:%d: Test failed with exit(%s)\n", \
  79. __FILE__, __func__, __LINE__, #code); \
  80. } \
  81. _exit(code); \
  82. }
  83. #endif /* _TEST_HELPERS */