scx_test.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Copyright (c) 2023 Meta Platforms, Inc. and affiliates.
  4. * Copyright (c) 2023 Tejun Heo <tj@kernel.org>
  5. * Copyright (c) 2023 David Vernet <dvernet@meta.com>
  6. */
  7. #ifndef __SCX_TEST_H__
  8. #define __SCX_TEST_H__
  9. #include <errno.h>
  10. #include <scx/common.h>
  11. #include <scx/compat.h>
  12. enum scx_test_status {
  13. SCX_TEST_PASS = 0,
  14. SCX_TEST_SKIP,
  15. SCX_TEST_FAIL,
  16. };
  17. #define EXIT_KIND(__ent) __COMPAT_ENUM_OR_ZERO("scx_exit_kind", #__ent)
  18. struct scx_test {
  19. /**
  20. * name - The name of the testcase.
  21. */
  22. const char *name;
  23. /**
  24. * description - A description of your testcase: what it tests and is
  25. * meant to validate.
  26. */
  27. const char *description;
  28. /*
  29. * setup - Setup the test.
  30. * @ctx: A pointer to a context object that will be passed to run and
  31. * cleanup.
  32. *
  33. * An optional callback that allows a testcase to perform setup for its
  34. * run. A test may return SCX_TEST_SKIP to skip the run.
  35. */
  36. enum scx_test_status (*setup)(void **ctx);
  37. /*
  38. * run - Run the test.
  39. * @ctx: Context set in the setup() callback. If @ctx was not set in
  40. * setup(), it is NULL.
  41. *
  42. * The main test. Callers should return one of:
  43. *
  44. * - SCX_TEST_PASS: Test passed
  45. * - SCX_TEST_SKIP: Test should be skipped
  46. * - SCX_TEST_FAIL: Test failed
  47. *
  48. * This callback must be defined.
  49. */
  50. enum scx_test_status (*run)(void *ctx);
  51. /*
  52. * cleanup - Perform cleanup following the test
  53. * @ctx: Context set in the setup() callback. If @ctx was not set in
  54. * setup(), it is NULL.
  55. *
  56. * An optional callback that allows a test to perform cleanup after
  57. * being run. This callback is run even if the run() callback returns
  58. * SCX_TEST_SKIP or SCX_TEST_FAIL. It is not run if setup() returns
  59. * SCX_TEST_SKIP or SCX_TEST_FAIL.
  60. */
  61. void (*cleanup)(void *ctx);
  62. };
  63. void scx_test_register(struct scx_test *test);
  64. #define REGISTER_SCX_TEST(__test) \
  65. __attribute__((constructor)) \
  66. static void ___scxregister##__LINE__(void) \
  67. { \
  68. scx_test_register(__test); \
  69. }
  70. #define SCX_ERR(__fmt, ...) \
  71. do { \
  72. fprintf(stderr, "ERR: %s:%d\n", __FILE__, __LINE__); \
  73. fprintf(stderr, __fmt"\n", ##__VA_ARGS__); \
  74. } while (0)
  75. #define SCX_FAIL(__fmt, ...) \
  76. do { \
  77. SCX_ERR(__fmt, ##__VA_ARGS__); \
  78. return SCX_TEST_FAIL; \
  79. } while (0)
  80. #define SCX_FAIL_IF(__cond, __fmt, ...) \
  81. do { \
  82. if (__cond) \
  83. SCX_FAIL(__fmt, ##__VA_ARGS__); \
  84. } while (0)
  85. #define SCX_GT(_x, _y) SCX_FAIL_IF((_x) <= (_y), "Expected %s > %s (%lu > %lu)", \
  86. #_x, #_y, (u64)(_x), (u64)(_y))
  87. #define SCX_GE(_x, _y) SCX_FAIL_IF((_x) < (_y), "Expected %s >= %s (%lu >= %lu)", \
  88. #_x, #_y, (u64)(_x), (u64)(_y))
  89. #define SCX_LT(_x, _y) SCX_FAIL_IF((_x) >= (_y), "Expected %s < %s (%lu < %lu)", \
  90. #_x, #_y, (u64)(_x), (u64)(_y))
  91. #define SCX_LE(_x, _y) SCX_FAIL_IF((_x) > (_y), "Expected %s <= %s (%lu <= %lu)", \
  92. #_x, #_y, (u64)(_x), (u64)(_y))
  93. #define SCX_EQ(_x, _y) SCX_FAIL_IF((_x) != (_y), "Expected %s == %s (%lu == %lu)", \
  94. #_x, #_y, (u64)(_x), (u64)(_y))
  95. #define SCX_ASSERT(_x) SCX_FAIL_IF(!(_x), "Expected %s to be true (%lu)", \
  96. #_x, (u64)(_x))
  97. #define SCX_ECODE_VAL(__ecode) ({ \
  98. u64 __val = 0; \
  99. bool __found = false; \
  100. \
  101. __found = __COMPAT_read_enum("scx_exit_code", #__ecode, &__val); \
  102. SCX_ASSERT(__found); \
  103. (s64)__val; \
  104. })
  105. #define SCX_KIND_VAL(__kind) ({ \
  106. u64 __val = 0; \
  107. bool __found = false; \
  108. \
  109. __found = __COMPAT_read_enum("scx_exit_kind", #__kind, &__val); \
  110. SCX_ASSERT(__found); \
  111. __val; \
  112. })
  113. #endif // # __SCX_TEST_H__