mock.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Mocking API for KUnit.
  4. *
  5. * Copyright (C) 2020, Google LLC.
  6. * Author: Brendan Higgins <[email protected]>
  7. */
  8. #include <kunit/mock.h>
  9. static int mock_void_ptr_init(struct kunit *test, struct MOCK(void) *mock_void_ptr)
  10. {
  11. mock_void_ptr->trgt = mock_void_ptr;
  12. return 0;
  13. }
  14. DEFINE_STRUCT_CLASS_MOCK_INIT(void, mock_void_ptr_init);
  15. static bool mock_match_params(struct mock_matcher *matcher,
  16. struct kunit_stream *stream,
  17. const void **params,
  18. int len)
  19. {
  20. struct mock_param_matcher *param_matcher;
  21. bool ret = true, tmp;
  22. int i;
  23. BUG_ON(matcher->num != len);
  24. for (i = 0; i < matcher->num; i++) {
  25. param_matcher = matcher->matchers[i];
  26. kunit_stream_add(stream, "\t");
  27. tmp = param_matcher->match(param_matcher, stream, params[i]);
  28. ret = ret && tmp;
  29. kunit_stream_add(stream, "\n");
  30. }
  31. return ret;
  32. }
  33. static const void *mock_do_expect(struct mock *mock,
  34. const char *method_name,
  35. const void *method_ptr,
  36. const char * const *type_names,
  37. const void **params,
  38. int len);
  39. static void fail_and_flush(struct kunit *test, struct kunit_stream *stream)
  40. {
  41. kunit_set_failure(test);
  42. kunit_stream_commit(stream);
  43. }
  44. void mock_validate_expectations(struct mock *mock)
  45. {
  46. struct mock_expectation *expectation, *expectation_safe;
  47. struct kunit_stream *stream;
  48. struct mock_method *method;
  49. int times_called;
  50. stream = alloc_kunit_stream(mock->test, GFP_KERNEL);
  51. list_for_each_entry(method, &mock->methods, node) {
  52. list_for_each_entry_safe(expectation, expectation_safe,
  53. &method->expectations, node) {
  54. times_called = expectation->times_called;
  55. if (!(expectation->min_calls_expected <= times_called &&
  56. times_called <= expectation->max_calls_expected)
  57. ) {
  58. kunit_stream_add(stream,
  59. "Expectation was not called the specified number of times:\n\t");
  60. kunit_stream_add(stream,
  61. "Function: %s, min calls: %d, max calls: %d, actual calls: %d\n",
  62. method->method_name,
  63. expectation->min_calls_expected,
  64. expectation->max_calls_expected,
  65. times_called);
  66. fail_and_flush(mock->test, stream);
  67. }
  68. list_del(&expectation->node);
  69. }
  70. }
  71. }
  72. static void mock_validate_wrapper(struct kunit_post_condition *condition)
  73. {
  74. struct mock *mock = container_of(condition, struct mock, parent);
  75. mock_validate_expectations(mock);
  76. }
  77. void mock_init_ctrl(struct kunit *test, struct mock *mock)
  78. {
  79. mock->test = test;
  80. INIT_LIST_HEAD(&mock->methods);
  81. mock->do_expect = mock_do_expect;
  82. mock->type = DEFAULT_MOCK_TYPE;
  83. mock->parent.validate = mock_validate_wrapper;
  84. list_add_tail(&mock->parent.node, &test->post_conditions);
  85. }
  86. struct global_mock {
  87. struct mock ctrl;
  88. bool is_initialized;
  89. };
  90. static struct global_mock global_mock = {
  91. .is_initialized = false,
  92. };
  93. static int mock_init_global_mock(struct test_initcall *initcall,
  94. struct kunit *test)
  95. {
  96. BUG_ON(global_mock.is_initialized);
  97. mock_init_ctrl(test, &global_mock.ctrl);
  98. global_mock.is_initialized = true;
  99. return 0;
  100. }
  101. static void mock_exit_global_mock(struct test_initcall *initcall)
  102. {
  103. BUG_ON(!global_mock.is_initialized);
  104. global_mock.ctrl.test = NULL;
  105. global_mock.is_initialized = false;
  106. }
  107. static struct test_initcall global_mock_initcall = {
  108. .init = mock_init_global_mock,
  109. .exit = mock_exit_global_mock,
  110. };
  111. test_register_initcall(global_mock_initcall);
  112. struct mock *mock_get_global_mock(void)
  113. {
  114. BUG_ON(!global_mock.is_initialized);
  115. return &global_mock.ctrl;
  116. }
  117. static struct mock_method *mock_lookup_method(struct mock *mock,
  118. const void *method_ptr)
  119. {
  120. struct mock_method *ret;
  121. list_for_each_entry(ret, &mock->methods, node) {
  122. if (ret->method_ptr == method_ptr)
  123. return ret;
  124. }
  125. return NULL;
  126. }
  127. static struct mock_method *mock_add_method(struct mock *mock,
  128. const char *method_name,
  129. const void *method_ptr)
  130. {
  131. struct mock_method *method;
  132. method = kunit_kzalloc(mock->test, sizeof(*method), GFP_KERNEL);
  133. if (!method)
  134. return NULL;
  135. INIT_LIST_HEAD(&method->expectations);
  136. method->method_name = method_name;
  137. method->method_ptr = method_ptr;
  138. list_add_tail(&method->node, &mock->methods);
  139. return method;
  140. }
  141. static int mock_add_expectation(struct mock *mock,
  142. const char *method_name,
  143. const void *method_ptr,
  144. struct mock_expectation *expectation)
  145. {
  146. struct mock_method *method;
  147. method = mock_lookup_method(mock, method_ptr);
  148. if (!method) {
  149. method = mock_add_method(mock, method_name, method_ptr);
  150. if (!method)
  151. return -ENOMEM;
  152. }
  153. list_add_tail(&expectation->node, &method->expectations);
  154. return 0;
  155. }
  156. struct mock_expectation *mock_add_matcher(struct mock *mock,
  157. const char *method_name,
  158. const void *method_ptr,
  159. struct mock_param_matcher *matchers[],
  160. int len)
  161. {
  162. struct mock_expectation *expectation;
  163. struct mock_matcher *matcher;
  164. int ret;
  165. expectation = kunit_kzalloc(mock->test,
  166. sizeof(*expectation),
  167. GFP_KERNEL);
  168. if (!expectation)
  169. return NULL;
  170. matcher = kunit_kmalloc(mock->test, sizeof(*matcher), GFP_KERNEL);
  171. if (!matcher)
  172. return NULL;
  173. memcpy(&matcher->matchers, matchers, sizeof(*matchers) * len);
  174. matcher->num = len;
  175. expectation->matcher = matcher;
  176. expectation->max_calls_expected = 1;
  177. expectation->min_calls_expected = 1;
  178. INIT_LIST_HEAD(&expectation->prerequisites);
  179. ret = mock_add_expectation(mock, method_name, method_ptr, expectation);
  180. if (ret < 0)
  181. return NULL;
  182. return expectation;
  183. }
  184. int mock_set_default_action(struct mock *mock,
  185. const char *method_name,
  186. const void *method_ptr,
  187. struct mock_action *action)
  188. {
  189. struct mock_method *method;
  190. method = mock_lookup_method(mock, method_ptr);
  191. if (!method) {
  192. method = mock_add_method(mock, method_name, method_ptr);
  193. if (!method)
  194. return -ENOMEM;
  195. }
  196. method->default_action = action;
  197. return 0;
  198. }
  199. static void mock_format_param(struct kunit_stream *stream,
  200. const char *type_name,
  201. const void *param)
  202. {
  203. /*
  204. * Cannot find formatter, so just print the pointer of the
  205. * symbol.
  206. */
  207. kunit_stream_add(stream, "<%pS>", param);
  208. }
  209. static void mock_add_method_declaration_to_stream(
  210. struct kunit_stream *stream,
  211. const char *function_name,
  212. const char * const *type_names,
  213. const void **params,
  214. int len)
  215. {
  216. int i;
  217. kunit_stream_add(stream, "%s(", function_name);
  218. for (i = 0; i < len; i++) {
  219. mock_format_param(stream, type_names[i], params[i]);
  220. if (i < len - 1)
  221. kunit_stream_add(stream, ", ");
  222. }
  223. kunit_stream_add(stream, ")\n");
  224. }
  225. static struct kunit_stream *mock_initialize_failure_message(
  226. struct kunit *test,
  227. const char *function_name,
  228. const char * const *type_names,
  229. const void **params,
  230. int len)
  231. {
  232. struct kunit_stream *stream;
  233. stream = alloc_kunit_stream(test, GFP_KERNEL);
  234. if (!stream)
  235. return NULL;
  236. kunit_stream_add(stream,
  237. "EXPECTATION FAILED: no expectation for call: ");
  238. mock_add_method_declaration_to_stream(stream,
  239. function_name,
  240. type_names,
  241. params,
  242. len);
  243. return stream;
  244. }
  245. static bool mock_is_expectation_retired(struct mock_expectation *expectation)
  246. {
  247. return expectation->retire_on_saturation &&
  248. expectation->times_called ==
  249. expectation->max_calls_expected;
  250. }
  251. static void mock_add_method_expectation_error(struct kunit *test,
  252. struct kunit_stream *stream,
  253. char *message,
  254. struct mock *mock,
  255. struct mock_method *method,
  256. const char * const *type_names,
  257. const void **params,
  258. int len)
  259. {
  260. kunit_stream_clear(stream);
  261. kunit_stream_add(stream, message);
  262. mock_add_method_declaration_to_stream(stream,
  263. method->method_name, type_names, params, len);
  264. }
  265. static bool mock_are_prereqs_satisfied(struct mock_expectation *expectation,
  266. struct kunit_stream *stream)
  267. {
  268. struct mock_expectation_prereq_entry *entry, *entry_safe;
  269. int times_called;
  270. list_for_each_entry_safe(entry, entry_safe,
  271. &expectation->prerequisites, node) {
  272. times_called = entry->expectation->times_called;
  273. if (!(entry->expectation->min_calls_expected <= times_called &&
  274. times_called <= entry->expectation->max_calls_expected)) {
  275. kunit_stream_add(stream,
  276. "Expectation %s matched but prerequisite expectation was not satisfied:\n",
  277. expectation->expectation_name);
  278. kunit_stream_add(stream,
  279. "Expectation: \n\tmin calls: %d, max calls: %d, actual calls: %d",
  280. entry->expectation->min_calls_expected,
  281. entry->expectation->max_calls_expected,
  282. entry->expectation->times_called);
  283. return false;
  284. }
  285. /* Don't need to check satisfied prereq again. */
  286. list_del(&entry->node);
  287. }
  288. return true;
  289. }
  290. /* Assumes that the var args are null terminated. */
  291. int mock_in_sequence(struct kunit *test, struct mock_expectation *first, ...)
  292. {
  293. struct mock_expectation *prereq = first;
  294. struct mock_expectation *curr = NULL;
  295. struct mock_expectation_prereq_entry *entry;
  296. va_list args;
  297. va_start(args, first);
  298. RetireOnSaturation(first);
  299. while ((curr = va_arg(args, struct mock_expectation*))) {
  300. RetireOnSaturation(curr);
  301. entry = kunit_kzalloc(test, sizeof(*entry), GFP_KERNEL);
  302. if (!entry) {
  303. va_end(args);
  304. return -ENOMEM;
  305. }
  306. entry->expectation = prereq;
  307. list_add_tail(&entry->node, &curr->prerequisites);
  308. prereq = curr;
  309. }
  310. va_end(args);
  311. return 0;
  312. }
  313. static inline bool does_mock_expectation_match_call(
  314. struct mock_expectation *expectation,
  315. struct kunit_stream *stream,
  316. const void **params,
  317. int len)
  318. {
  319. return mock_match_params(expectation->matcher, stream, params, len) &&
  320. mock_are_prereqs_satisfied(expectation, stream);
  321. }
  322. static struct mock_expectation *mock_apply_expectations(
  323. struct mock *mock,
  324. struct mock_method *method,
  325. const char * const *type_names,
  326. const void **params,
  327. int len)
  328. {
  329. struct kunit_stream *attempted_matching_stream;
  330. bool expectations_all_saturated = true;
  331. struct kunit *test = mock->test;
  332. struct kunit_stream *stream = alloc_kunit_stream(test, GFP_KERNEL);
  333. struct mock_expectation *ret;
  334. if (list_empty(&method->expectations)) {
  335. mock_add_method_expectation_error(test, stream,
  336. "Method was called with no expectations declared: ",
  337. mock, method, type_names, params, len);
  338. if (is_strict_mock(mock))
  339. fail_and_flush(test, stream);
  340. else if (is_naggy_mock(mock))
  341. kunit_stream_commit(stream);
  342. else
  343. kunit_stream_clear(stream);
  344. return NULL;
  345. }
  346. attempted_matching_stream = mock_initialize_failure_message(
  347. test,
  348. method->method_name,
  349. type_names,
  350. params,
  351. len);
  352. list_for_each_entry(ret, &method->expectations, node) {
  353. if (mock_is_expectation_retired(ret))
  354. continue;
  355. expectations_all_saturated = false;
  356. kunit_stream_add(attempted_matching_stream,
  357. "Tried expectation: %s, but\n",
  358. ret->expectation_name);
  359. if (does_mock_expectation_match_call(ret,
  360. attempted_matching_stream, params, len)) {
  361. /*
  362. * Matcher was found; we won't print, so clean up the
  363. * log.
  364. */
  365. kunit_stream_clear(attempted_matching_stream);
  366. return ret;
  367. }
  368. }
  369. if (expectations_all_saturated && !is_nice_mock(mock)) {
  370. mock_add_method_expectation_error(test, stream,
  371. "Method was called with fully saturated expectations: ",
  372. mock, method, type_names, params, len);
  373. } else {
  374. mock_add_method_expectation_error(test, stream,
  375. "Method called that did not match any expectations: ",
  376. mock, method, type_names, params, len);
  377. kunit_stream_append(stream, attempted_matching_stream);
  378. }
  379. fail_and_flush(test, stream);
  380. kunit_stream_clear(attempted_matching_stream);
  381. return NULL;
  382. }
  383. static const void *mock_do_expect(struct mock *mock,
  384. const char *method_name,
  385. const void *method_ptr,
  386. const char * const *param_types,
  387. const void **params,
  388. int len)
  389. {
  390. struct mock_expectation *expectation;
  391. struct mock_method *method;
  392. struct mock_action *action;
  393. method = mock_lookup_method(mock, method_ptr);
  394. if (!method)
  395. return NULL;
  396. expectation = mock_apply_expectations(mock,
  397. method,
  398. param_types,
  399. params,
  400. len);
  401. if (!expectation) {
  402. action = method->default_action;
  403. } else {
  404. expectation->times_called++;
  405. if (expectation->action)
  406. action = expectation->action;
  407. else
  408. action = method->default_action;
  409. }
  410. if (!action)
  411. return NULL;
  412. return action->do_action(action, params, len);
  413. }