diff --git a/tests/unit/tests/eviction/lru.c/lru_iter.c b/tests/unit/tests/eviction/lru.c/lru_iter.c
new file mode 100644
index 0000000..8d97492
--- /dev/null
+++ b/tests/unit/tests/eviction/lru.c/lru_iter.c
@@ -0,0 +1,481 @@
+/*
+ * src/eviction/lru.c
+ * lru_iter_next
+ *
+ * INSERT HERE LIST OF FUNCTIONS YOU WANT TO LEAVE
+ * ONE FUNCTION PER LINE
+ * lru_iter_init
+ * _lru_next_evp
+ * _lru_evp_is_empty
+ * _lru_evp_set_empty
+ * _lru_evp_all_empty
+ * ocf_rotate_right
+ *
+ */
+
+#undef static
+
+#undef inline
+
+
+#include
+#include
+#include
+#include
+#include "print_desc.h"
+
+#include "eviction.h"
+#include "lru.h"
+#include "ops.h"
+#include "../utils/utils_cleaner.h"
+#include "../utils/utils_cache_line.h"
+#include "../concurrency/ocf_concurrency.h"
+#include "../mngt/ocf_mngt_common.h"
+#include "../engine/engine_zero.h"
+#include "../ocf_request.h"
+
+#include "eviction/lru.c/lru_iter_generated_wraps.c"
+
+//#define DEBUG
+
+ocf_cache_line_t test_cases[10 * OCF_NUM_EVICTION_LISTS][OCF_NUM_EVICTION_LISTS][20];
+unsigned num_cases = 20;
+
+void write_test_case_description(void)
+{
+ unsigned i, j, l;
+ unsigned test_case = 0;
+
+ // case 0 - all lists empty
+ for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++) {
+ test_cases[0][i][test_case] = -1;
+ }
+
+ // case 1 - all lists with single element
+ test_case++;
+ for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++) {
+ test_cases[0][i][test_case] = 10 * i;
+ test_cases[1][i][test_case] = -1;
+ }
+
+ // case 2 - all lists have between 1 and 5 elements, increasingly
+ test_case++;
+ for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++) {
+ unsigned num_elements = 1 + i / (OCF_NUM_EVICTION_LISTS / 4);
+
+ for (j = 0; j < num_elements; j++)
+ test_cases[j][i][test_case] = 10 * i + j;
+ test_cases[j][i][test_case] = -1;
+ }
+
+ // case 3 - all lists have between 1 and 5 elements, modulo index
+ test_case++;
+ for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++) {
+ unsigned num_elements = 1 + (i % 5);
+
+ for (j = 0; j < num_elements; j++)
+ test_cases[j][i][test_case] = 10 * i + j;
+ test_cases[j][i][test_case] = -1;
+ }
+
+ // case 4 - all lists have between 0 and 4 elements, increasingly
+ test_case++;
+ for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++) {
+ unsigned num_elements = i / (OCF_NUM_EVICTION_LISTS / 4);
+
+ for (j = 0; j < num_elements; j++)
+ test_cases[j][i][test_case] = 10 * i + j;
+ test_cases[j][i][test_case] = -1;
+ }
+
+ // case 5 - all lists have between 0 and 4 elements, modulo index
+ test_case++;
+ for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++) {
+ unsigned num_elements = (i % 5);
+
+ for (j = 0; j < num_elements; j++)
+ test_cases[j][i][test_case] = 10 * i + j;
+ test_cases[j][i][test_case] = -1;
+ }
+
+ // case 6 - list length increasing by 1 from 0
+ test_case++;
+ for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++) {
+ unsigned num_elements = i;
+
+ for (j = 0; j < num_elements; j++)
+ test_cases[j][i][test_case] = OCF_NUM_EVICTION_LISTS * i + j;
+ test_cases[j][i][test_case] = -1;
+ }
+
+ // case 7 - list length increasing by 1 from 1
+ test_case++;
+ for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++) {
+ unsigned num_elements = i + 1;
+
+ for (j = 0; j < num_elements; j++)
+ test_cases[j][i][test_case] = 2 * OCF_NUM_EVICTION_LISTS * i + j;
+ test_cases[j][i][test_case] = -1;
+ }
+
+ // case 8 - list length increasing by 4 from 0
+ test_case++;
+ for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++) {
+ unsigned num_elements = 4 * i;
+
+ for (j = 0; j < num_elements; j++)
+ test_cases[j][i][test_case] = 4 * OCF_NUM_EVICTION_LISTS * i + j;
+ test_cases[j][i][test_case] = -1;
+ }
+
+ // case 9 - list length increasing by 4 from 1
+ test_case++;
+ for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++) {
+ unsigned num_elements = 4 * i + 1;
+
+ for (j = 0; j < num_elements; j++)
+ test_cases[j][i][test_case] = 5 * OCF_NUM_EVICTION_LISTS * i + j;
+ test_cases[j][i][test_case] = -1;
+ }
+
+ // cases 10-19: cases 0-9 rotated right by 4
+ l = test_case;
+ test_case++;
+ while(test_case < 2 * (l + 1)) {
+ unsigned matching_case = test_case - l - 1;
+
+ for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++) {
+ unsigned curr_list = (i + 4) % OCF_NUM_EVICTION_LISTS;
+ j = 0;
+ while(test_cases[j][i][matching_case] != -1) {
+ test_cases[j][curr_list][test_case] =
+ test_cases[j][i][matching_case];
+ j++;
+ }
+ test_cases[j][curr_list][test_case] = -1;
+ }
+ test_case++;
+ }
+
+#ifdef DEBUG
+ for (test_case = 0; test_case < num_cases; test_case++) {
+ print_message("test case no %d\n", test_case);
+ for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++) {
+ print_message("list %02u: ", i);
+ j = 0;
+ while (test_cases[j][i][test_case] != -1) {
+ print_message("%u ", test_cases[j][i][test_case]);
+ j++;
+ }
+ print_message("\n");
+ }
+ print_message("========\n\n");
+ }
+#endif
+}
+
+unsigned current_case;
+
+struct ocf_lru_list list;
+
+struct ocf_lru_list *__wrap_evp_lru_get_list(struct ocf_user_part *part,
+ uint32_t evp, bool clean)
+{
+ unsigned i = 0;
+
+ while (test_cases[i][evp][current_case] != -1)
+ i++;
+
+ if (i == 0) {
+ list.head = -1;
+ list.tail = -1;
+ list.num_nodes = 0;
+ } else {
+ list.head = test_cases[0][evp][current_case];
+ list.tail = test_cases[i - 1][evp][current_case];
+ list.num_nodes = i;
+ }
+
+ return &list;
+}
+
+inline struct ocf_lru_list *__wrap_evp_get_cline_list(ocf_cache_t cache,
+ ocf_cache_line_t cline)
+{
+ return __wrap_evp_lru_get_list(NULL, cline % OCF_NUM_EVICTION_LISTS, true);
+}
+
+
+union eviction_policy_meta policy;
+
+union eviction_policy_meta *__wrap_ocf_metadata_get_eviction_policy(
+ struct ocf_cache *cache, ocf_cache_line_t line)
+{
+ unsigned i, j;
+
+ for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++)
+ {
+ j = 0;
+
+ while (test_cases[j][i][current_case] != -1) {
+ if (test_cases[j][i][current_case] == line) {
+ if (j == 0) {
+ policy.lru.prev = -1;
+ } else {
+ policy.lru.prev =
+ test_cases[j - 1][i][current_case];
+ }
+
+ policy.lru.next = test_cases[j + 1][i][current_case];
+#ifdef DEBUG
+ print_message("[%u] next %u prev %u\n",
+ line, policy.lru.next,
+ policy.lru.prev);
+#endif
+ return &policy;
+ }
+ j++;
+ }
+
+ }
+
+ print_message("use case %d cache line %d not found\n",
+ current_case, line);
+ assert(false);
+}
+
+
+static void _lru_run_test(unsigned test_case)
+{
+ unsigned start_pos;
+ current_case = test_case;
+
+ for (start_pos = 0; start_pos < OCF_NUM_EVICTION_LISTS; start_pos++)
+ {
+ struct ocf_lru_iter iter;
+ ocf_cache_line_t cache_line, expected_cache_line;
+ unsigned curr_evp = start_pos;
+ unsigned pos[OCF_NUM_EVICTION_LISTS];
+ unsigned i;
+
+ for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++)
+ {
+ pos[i] = -1;
+ while(test_cases[pos[i] + 1][i][test_case] != -1)
+ pos[i]++;
+ }
+
+ lru_iter_init(&iter, NULL, NULL, start_pos, false);
+
+ do {
+ /* get cacheline from iterator */
+ cache_line = lru_iter_next(&iter);
+
+ /* check what is expected to be returned from iterator */
+ if (pos[curr_evp] == -1) {
+ i = 1;
+ while (i < OCF_NUM_EVICTION_LISTS &&
+ pos[(curr_evp + i) % OCF_NUM_EVICTION_LISTS]
+ == -1) {
+ i++;
+ }
+ if (i == OCF_NUM_EVICTION_LISTS) {
+ /* reached end of lists */
+ expected_cache_line = -1;
+ } else {
+ curr_evp = (curr_evp + i) % OCF_NUM_EVICTION_LISTS;
+ expected_cache_line = test_cases[pos[curr_evp]]
+ [curr_evp][test_case];
+ pos[curr_evp]--;
+ }
+ } else {
+ expected_cache_line = test_cases[pos[curr_evp]]
+ [curr_evp][test_case];
+ pos[curr_evp]--;
+ }
+
+ assert_int_equal(cache_line, expected_cache_line);
+
+ curr_evp = (curr_evp + 1) % OCF_NUM_EVICTION_LISTS;
+ } while (cache_line != -1);
+
+ /* make sure all cachelines are visited */
+ for (i = 0; i < OCF_NUM_EVICTION_LISTS; i++)
+ {
+ assert_int_equal((unsigned)-1, pos[i]);
+ }
+ }
+}
+
+static void lru_iter_next_test00(void **state)
+{
+ print_test_description("lru iter test case 00\n");
+ _lru_run_test(0);
+ return;
+}
+
+static void lru_iter_next_test01(void **state)
+{
+ print_test_description("lru iter test case 01\n");
+ _lru_run_test(1);
+ return;
+}
+
+static void lru_iter_next_test02(void **state)
+{
+ print_test_description("lru iter test case 02\n");
+ _lru_run_test(2);
+ return;
+}
+
+static void lru_iter_next_test03(void **state)
+{
+ print_test_description("lru iter test case 03\n");
+ _lru_run_test(3);
+ return;
+}
+
+static void lru_iter_next_test04(void **state)
+{
+ print_test_description("lru iter test case 04\n");
+ _lru_run_test(4);
+ return;
+}
+
+static void lru_iter_next_test05(void **state)
+{
+
+ print_test_description("lru iter test case 05\n");
+ _lru_run_test(5);
+ return;
+}
+
+static void lru_iter_next_test06(void **state)
+{
+ print_test_description("lru iter test case 06\n");
+ _lru_run_test(6);
+ return;
+}
+
+static void lru_iter_next_test07(void **state)
+{
+ print_test_description("lru iter test case 07\n");
+ _lru_run_test(7);
+ return;
+}
+
+static void lru_iter_next_test08(void **state)
+{
+ print_test_description("lru iter test case 08\n");
+ _lru_run_test(8);
+ return;
+}
+
+static void lru_iter_next_test09(void **state)
+{
+ print_test_description("lru iter test case 09\n");
+ _lru_run_test(9);
+ return;
+}
+
+static void lru_iter_next_test10(void **state)
+{
+ print_test_description("lru iter test case 00\n");
+ _lru_run_test(10);
+ return;
+}
+
+static void lru_iter_next_test11(void **state)
+{
+ print_test_description("lru iter test case 11\n");
+ _lru_run_test(11);
+ return;
+}
+
+static void lru_iter_next_test12(void **state)
+{
+ print_test_description("lru iter test case 12\n");
+ _lru_run_test(12);
+ return;
+}
+
+static void lru_iter_next_test13(void **state)
+{
+ print_test_description("lru iter test case 13\n");
+ _lru_run_test(13);
+ return;
+}
+
+static void lru_iter_next_test14(void **state)
+{
+ print_test_description("lru iter test case 14\n");
+ _lru_run_test(14);
+ return;
+}
+
+static void lru_iter_next_test15(void **state)
+{
+ print_test_description("lru iter test case 15\n");
+ _lru_run_test(15);
+ return;
+}
+
+static void lru_iter_next_test16(void **state)
+{
+ print_test_description("lru iter test case 16\n");
+ _lru_run_test(16);
+ return;
+}
+
+static void lru_iter_next_test17(void **state)
+{
+ print_test_description("lru iter test case 17\n");
+ _lru_run_test(17);
+ return;
+}
+
+static void lru_iter_next_test18(void **state)
+{
+ print_test_description("lru iter test case 18\n");
+ _lru_run_test(18);
+ return;
+}
+
+static void lru_iter_next_test19(void **state)
+{
+ print_test_description("lru iter test case 19\n");
+ _lru_run_test(19);
+ return;
+}
+
+int main(void)
+{
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test(lru_iter_next_test00),
+ cmocka_unit_test(lru_iter_next_test01),
+ cmocka_unit_test(lru_iter_next_test02),
+ cmocka_unit_test(lru_iter_next_test03),
+ cmocka_unit_test(lru_iter_next_test04),
+ cmocka_unit_test(lru_iter_next_test05),
+ cmocka_unit_test(lru_iter_next_test06),
+ cmocka_unit_test(lru_iter_next_test07),
+ cmocka_unit_test(lru_iter_next_test08),
+ cmocka_unit_test(lru_iter_next_test09),
+ cmocka_unit_test(lru_iter_next_test10),
+ cmocka_unit_test(lru_iter_next_test11),
+ cmocka_unit_test(lru_iter_next_test12),
+ cmocka_unit_test(lru_iter_next_test13),
+ cmocka_unit_test(lru_iter_next_test14),
+ cmocka_unit_test(lru_iter_next_test15),
+ cmocka_unit_test(lru_iter_next_test16),
+ cmocka_unit_test(lru_iter_next_test17),
+ cmocka_unit_test(lru_iter_next_test18),
+ cmocka_unit_test(lru_iter_next_test19)
+ };
+
+ print_message("Unit test for lru_iter_next\n");
+
+ write_test_case_description();
+
+ return cmocka_run_group_tests(tests, NULL, NULL);
+}