kfifo_kunit.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * KUnit test for the generic kernel FIFO implementation.
  4. *
  5. * Copyright (C) 2024 Diego Vieira <diego.daniel.professional@gmail.com>
  6. */
  7. #include <kunit/test.h>
  8. #include <linux/kfifo.h>
  9. #define KFIFO_SIZE 32
  10. #define N_ELEMENTS 5
  11. static void kfifo_test_reset_should_clear_the_fifo(struct kunit *test)
  12. {
  13. DEFINE_KFIFO(my_fifo, u8, KFIFO_SIZE);
  14. kfifo_put(&my_fifo, 1);
  15. kfifo_put(&my_fifo, 2);
  16. kfifo_put(&my_fifo, 3);
  17. KUNIT_EXPECT_EQ(test, kfifo_len(&my_fifo), 3);
  18. kfifo_reset(&my_fifo);
  19. KUNIT_EXPECT_EQ(test, kfifo_len(&my_fifo), 0);
  20. KUNIT_EXPECT_TRUE(test, kfifo_is_empty(&my_fifo));
  21. }
  22. static void kfifo_test_define_should_define_an_empty_fifo(struct kunit *test)
  23. {
  24. DEFINE_KFIFO(my_fifo, u8, KFIFO_SIZE);
  25. KUNIT_EXPECT_TRUE(test, kfifo_initialized(&my_fifo));
  26. KUNIT_EXPECT_TRUE(test, kfifo_is_empty(&my_fifo));
  27. KUNIT_EXPECT_EQ(test, kfifo_len(&my_fifo), 0);
  28. }
  29. static void kfifo_test_len_should_ret_n_of_stored_elements(struct kunit *test)
  30. {
  31. u8 buffer1[N_ELEMENTS];
  32. for (int i = 0; i < N_ELEMENTS; i++)
  33. buffer1[i] = i + 1;
  34. DEFINE_KFIFO(my_fifo, u8, KFIFO_SIZE);
  35. KUNIT_EXPECT_EQ(test, kfifo_len(&my_fifo), 0);
  36. kfifo_in(&my_fifo, buffer1, N_ELEMENTS);
  37. KUNIT_EXPECT_EQ(test, kfifo_len(&my_fifo), N_ELEMENTS);
  38. kfifo_in(&my_fifo, buffer1, N_ELEMENTS);
  39. KUNIT_EXPECT_EQ(test, kfifo_len(&my_fifo), N_ELEMENTS * 2);
  40. kfifo_reset(&my_fifo);
  41. KUNIT_EXPECT_EQ(test, kfifo_len(&my_fifo), 0);
  42. }
  43. static void kfifo_test_put_should_insert_and_get_should_pop(struct kunit *test)
  44. {
  45. u8 out_data = 0;
  46. int processed_elements;
  47. u8 elements[] = { 3, 5, 11 };
  48. DEFINE_KFIFO(my_fifo, u8, KFIFO_SIZE);
  49. // If the fifo is empty, get returns 0
  50. processed_elements = kfifo_get(&my_fifo, &out_data);
  51. KUNIT_EXPECT_EQ(test, processed_elements, 0);
  52. KUNIT_EXPECT_EQ(test, out_data, 0);
  53. for (int i = 0; i < 3; i++)
  54. kfifo_put(&my_fifo, elements[i]);
  55. for (int i = 0; i < 3; i++) {
  56. processed_elements = kfifo_get(&my_fifo, &out_data);
  57. KUNIT_EXPECT_EQ(test, processed_elements, 1);
  58. KUNIT_EXPECT_EQ(test, out_data, elements[i]);
  59. }
  60. }
  61. static void kfifo_test_in_should_insert_multiple_elements(struct kunit *test)
  62. {
  63. u8 in_buffer[] = { 11, 25, 65 };
  64. u8 out_data;
  65. int processed_elements;
  66. DEFINE_KFIFO(my_fifo, u8, KFIFO_SIZE);
  67. kfifo_in(&my_fifo, in_buffer, 3);
  68. for (int i = 0; i < 3; i++) {
  69. processed_elements = kfifo_get(&my_fifo, &out_data);
  70. KUNIT_EXPECT_EQ(test, processed_elements, 1);
  71. KUNIT_EXPECT_EQ(test, out_data, in_buffer[i]);
  72. }
  73. }
  74. static void kfifo_test_out_should_pop_multiple_elements(struct kunit *test)
  75. {
  76. u8 in_buffer[] = { 11, 25, 65 };
  77. u8 out_buffer[3];
  78. int copied_elements;
  79. DEFINE_KFIFO(my_fifo, u8, KFIFO_SIZE);
  80. for (int i = 0; i < 3; i++)
  81. kfifo_put(&my_fifo, in_buffer[i]);
  82. copied_elements = kfifo_out(&my_fifo, out_buffer, 3);
  83. KUNIT_EXPECT_EQ(test, copied_elements, 3);
  84. for (int i = 0; i < 3; i++)
  85. KUNIT_EXPECT_EQ(test, out_buffer[i], in_buffer[i]);
  86. KUNIT_EXPECT_TRUE(test, kfifo_is_empty(&my_fifo));
  87. }
  88. static void kfifo_test_dec_init_should_define_an_empty_fifo(struct kunit *test)
  89. {
  90. DECLARE_KFIFO(my_fifo, u8, KFIFO_SIZE);
  91. INIT_KFIFO(my_fifo);
  92. // my_fifo is a struct with an inplace buffer
  93. KUNIT_EXPECT_FALSE(test, __is_kfifo_ptr(&my_fifo));
  94. KUNIT_EXPECT_TRUE(test, kfifo_initialized(&my_fifo));
  95. }
  96. static void kfifo_test_define_should_equal_declare_init(struct kunit *test)
  97. {
  98. // declare a variable my_fifo of type struct kfifo of u8
  99. DECLARE_KFIFO(my_fifo1, u8, KFIFO_SIZE);
  100. // initialize the my_fifo variable
  101. INIT_KFIFO(my_fifo1);
  102. // DEFINE_KFIFO declares the variable with the initial value
  103. // essentially the same as calling DECLARE_KFIFO and INIT_KFIFO
  104. DEFINE_KFIFO(my_fifo2, u8, KFIFO_SIZE);
  105. // my_fifo1 and my_fifo2 have the same size
  106. KUNIT_EXPECT_EQ(test, sizeof(my_fifo1), sizeof(my_fifo2));
  107. KUNIT_EXPECT_EQ(test, kfifo_initialized(&my_fifo1),
  108. kfifo_initialized(&my_fifo2));
  109. KUNIT_EXPECT_EQ(test, kfifo_is_empty(&my_fifo1),
  110. kfifo_is_empty(&my_fifo2));
  111. }
  112. static void kfifo_test_alloc_should_initiliaze_a_ptr_fifo(struct kunit *test)
  113. {
  114. int ret;
  115. DECLARE_KFIFO_PTR(my_fifo, u8);
  116. INIT_KFIFO(my_fifo);
  117. // kfifo_initialized returns false signaling the buffer pointer is NULL
  118. KUNIT_EXPECT_FALSE(test, kfifo_initialized(&my_fifo));
  119. // kfifo_alloc allocates the buffer
  120. ret = kfifo_alloc(&my_fifo, KFIFO_SIZE, GFP_KERNEL);
  121. KUNIT_EXPECT_EQ_MSG(test, ret, 0, "Memory allocation should succeed");
  122. KUNIT_EXPECT_TRUE(test, kfifo_initialized(&my_fifo));
  123. // kfifo_free frees the buffer
  124. kfifo_free(&my_fifo);
  125. }
  126. static void kfifo_test_peek_should_not_remove_elements(struct kunit *test)
  127. {
  128. u8 out_data;
  129. int processed_elements;
  130. DEFINE_KFIFO(my_fifo, u8, KFIFO_SIZE);
  131. // If the fifo is empty, peek returns 0
  132. processed_elements = kfifo_peek(&my_fifo, &out_data);
  133. KUNIT_EXPECT_EQ(test, processed_elements, 0);
  134. kfifo_put(&my_fifo, 3);
  135. kfifo_put(&my_fifo, 5);
  136. kfifo_put(&my_fifo, 11);
  137. KUNIT_EXPECT_EQ(test, kfifo_len(&my_fifo), 3);
  138. processed_elements = kfifo_peek(&my_fifo, &out_data);
  139. KUNIT_EXPECT_EQ(test, processed_elements, 1);
  140. KUNIT_EXPECT_EQ(test, out_data, 3);
  141. KUNIT_EXPECT_EQ(test, kfifo_len(&my_fifo), 3);
  142. // Using peek doesn't remove the element
  143. // so the read element and the fifo length
  144. // remains the same
  145. processed_elements = kfifo_peek(&my_fifo, &out_data);
  146. KUNIT_EXPECT_EQ(test, processed_elements, 1);
  147. KUNIT_EXPECT_EQ(test, out_data, 3);
  148. KUNIT_EXPECT_EQ(test, kfifo_len(&my_fifo), 3);
  149. }
  150. static struct kunit_case kfifo_test_cases[] = {
  151. KUNIT_CASE(kfifo_test_reset_should_clear_the_fifo),
  152. KUNIT_CASE(kfifo_test_define_should_define_an_empty_fifo),
  153. KUNIT_CASE(kfifo_test_len_should_ret_n_of_stored_elements),
  154. KUNIT_CASE(kfifo_test_put_should_insert_and_get_should_pop),
  155. KUNIT_CASE(kfifo_test_in_should_insert_multiple_elements),
  156. KUNIT_CASE(kfifo_test_out_should_pop_multiple_elements),
  157. KUNIT_CASE(kfifo_test_dec_init_should_define_an_empty_fifo),
  158. KUNIT_CASE(kfifo_test_define_should_equal_declare_init),
  159. KUNIT_CASE(kfifo_test_alloc_should_initiliaze_a_ptr_fifo),
  160. KUNIT_CASE(kfifo_test_peek_should_not_remove_elements),
  161. {},
  162. };
  163. static struct kunit_suite kfifo_test_module = {
  164. .name = "kfifo",
  165. .test_cases = kfifo_test_cases,
  166. };
  167. kunit_test_suites(&kfifo_test_module);
  168. MODULE_LICENSE("GPL");
  169. MODULE_AUTHOR("Diego Vieira <diego.daniel.professional@gmail.com>");
  170. MODULE_DESCRIPTION("KUnit test for the kernel FIFO");