A dynamic tracer for Linux

unittest.h 1.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. #ifndef _UNITTEST_H
  2. #define _UNITTEST_H
  3. #include <stdio.h>
  4. struct unittest {
  5. const char *name;
  6. int (*fn)(void *ctx);
  7. };
  8. #define UNITTEST(_fn) __attribute__((section("unittests"))) \
  9. static struct unittest _fn ## _desc = { \
  10. .name = #_fn, \
  11. .fn = _fn, \
  12. }
  13. extern struct unittest __start_unittests;
  14. extern struct unittest __stop_unittests;
  15. #define unittest_foreach(_t) \
  16. for ((_t) = &__start_unittests; (_t) < &__stop_unittests; (_t)++)
  17. struct unittest_ctx {
  18. int keep_going:1;
  19. int verbose:1;
  20. void *ctx;
  21. };
  22. static inline int unittests_run(struct unittest_ctx *ctx)
  23. {
  24. struct unittest *t;
  25. int err, ret = 0;
  26. unittest_foreach(t) {
  27. if (ctx->verbose) {
  28. printf("%-40s\t", t->name);
  29. fflush(stdout);
  30. }
  31. err = t->fn(ctx->ctx);
  32. if (!err) {
  33. if (ctx->verbose)
  34. printf("pass\n");
  35. continue;
  36. }
  37. if (!ctx->verbose) {
  38. printf("%-40s\t", t->name);
  39. fflush(stdout);
  40. }
  41. printf("\n%40s\tFAIL\n", "");
  42. if (!ctx->keep_going)
  43. return err;
  44. else if (!ret)
  45. ret = err;
  46. }
  47. return ret;
  48. }
  49. #define unittest_eq(_a, _b) if ((_a) != (_b)) { \
  50. printf("\n\t%s == %s (%lld != %lld)", \
  51. #_a, #_b, (long long)(_a), (long long)(_b)); \
  52. return -1; \
  53. }
  54. #endif /* _UNITTEST_H */