tests: move t0009-prio-queue.sh to the new unit testing framework

t/t0009-prio-queue.sh along with t/helper/test-prio-queue.c unit tests Git's implementation of a priority queue. Migrate the test over to the new unit testing framework to simplify debugging and reduce test run-time. Refactor the required logic and add a new test case in addition to porting over the original ones in shell. Signed-off-by: Chandra Pratap <chandrapratap3519@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Chandra Pratap committed Jan 21, 2024 at 19:28 UTC 808b77e5d47094ac8178b08d4c20e4893485bfca
6 files changed +99 -120
Makefile
+1 -1
@@ -828,7 +828,6 @@ TEST_BUILTINS_OBJS += test-partial-clone.o
828 TEST_BUILTINS_OBJS += test-path-utils.o
829 TEST_BUILTINS_OBJS += test-pcre2-config.o
830 TEST_BUILTINS_OBJS += test-pkt-line.o
831 -TEST_BUILTINS_OBJS += test-prio-queue.o
831 TEST_BUILTINS_OBJS += test-proc-receive.o
832 TEST_BUILTINS_OBJS += test-progress.o
833 TEST_BUILTINS_OBJS += test-reach.o
@@ -1342,6 +1341,7 @@ THIRD_PARTY_SOURCES += sha1dc/%
1341 UNIT_TEST_PROGRAMS += t-basic
1342 UNIT_TEST_PROGRAMS += t-mem-pool
1343 UNIT_TEST_PROGRAMS += t-strbuf
1344 +UNIT_TEST_PROGRAMS += t-prio-queue
1345 UNIT_TEST_PROGS = $(patsubst %,$(UNIT_TEST_BIN)/%$X,$(UNIT_TEST_PROGRAMS))
1346 UNIT_TEST_OBJS = $(patsubst %,$(UNIT_TEST_DIR)/%.o,$(UNIT_TEST_PROGRAMS))
1347 UNIT_TEST_OBJS += $(UNIT_TEST_DIR)/test-lib.o
t/helper/test-prio-queue.c deleted
-51
@@ -1,51 +0,0 @@
1 -#include "test-tool.h"
2 -#include "prio-queue.h"
3 -
4 -static int intcmp(const void *va, const void *vb, void *data UNUSED)
5 -{
6 - const int *a = va, *b = vb;
7 - return *a - *b;
8 -}
9 -
10 -static void show(int *v)
11 -{
12 - if (!v)
13 - printf("NULL\n");
14 - else
15 - printf("%d\n", *v);
16 - free(v);
17 -}
18 -
19 -int cmd__prio_queue(int argc UNUSED, const char **argv)
20 -{
21 - struct prio_queue pq = { intcmp };
22 -
23 - while (*++argv) {
24 - if (!strcmp(*argv, "get")) {
25 - void *peek = prio_queue_peek(&pq);
26 - void *get = prio_queue_get(&pq);
27 - if (peek != get)
28 - BUG("peek and get results do not match");
29 - show(get);
30 - } else if (!strcmp(*argv, "dump")) {
31 - void *peek;
32 - void *get;
33 - while ((peek = prio_queue_peek(&pq))) {
34 - get = prio_queue_get(&pq);
35 - if (peek != get)
36 - BUG("peek and get results do not match");
37 - show(get);
38 - }
39 - } else if (!strcmp(*argv, "stack")) {
40 - pq.compare = NULL;
41 - } else {
42 - int *v = xmalloc(sizeof(*v));
43 - *v = atoi(*argv);
44 - prio_queue_put(&pq, v);
45 - }
46 - }
47 -
48 - clear_prio_queue(&pq);
49 -
50 - return 0;
51 -}
t/helper/test-tool.c
-1
@@ -56,7 +56,6 @@ static struct test_cmd cmds[] = {
56 { "path-utils", cmd__path_utils },
57 { "pcre2-config", cmd__pcre2_config },
58 { "pkt-line", cmd__pkt_line },
59 - { "prio-queue", cmd__prio_queue },
59 { "proc-receive", cmd__proc_receive },
60 { "progress", cmd__progress },
61 { "reach", cmd__reach },
t/helper/test-tool.h
-1
@@ -49,7 +49,6 @@ int cmd__partial_clone(int argc, const char **argv);
49 int cmd__path_utils(int argc, const char **argv);
50 int cmd__pcre2_config(int argc, const char **argv);
51 int cmd__pkt_line(int argc, const char **argv);
52 -int cmd__prio_queue(int argc, const char **argv);
52 int cmd__proc_receive(int argc, const char **argv);
53 int cmd__progress(int argc, const char **argv);
54 int cmd__reach(int argc, const char **argv);
t/t0009-prio-queue.sh deleted
-66
@@ -1,66 +0,0 @@
1 -#!/bin/sh
2 -
3 -test_description='basic tests for priority queue implementation'
4 -
5 -TEST_PASSES_SANITIZE_LEAK=true
6 -. ./test-lib.sh
7 -
8 -cat >expect <<'EOF'
9 -1
10 -2
11 -3
12 -4
13 -5
14 -5
15 -6
16 -7
17 -8
18 -9
19 -10
20 -EOF
21 -test_expect_success 'basic ordering' '
22 - test-tool prio-queue 2 6 3 10 9 5 7 4 5 8 1 dump >actual &&
23 - test_cmp expect actual
24 -'
25 -
26 -cat >expect <<'EOF'
27 -2
28 -3
29 -4
30 -1
31 -5
32 -6
33 -EOF
34 -test_expect_success 'mixed put and get' '
35 - test-tool prio-queue 6 2 4 get 5 3 get get 1 dump >actual &&
36 - test_cmp expect actual
37 -'
38 -
39 -cat >expect <<'EOF'
40 -1
41 -2
42 -NULL
43 -1
44 -2
45 -NULL
46 -EOF
47 -test_expect_success 'notice empty queue' '
48 - test-tool prio-queue 1 2 get get get 1 2 get get get >actual &&
49 - test_cmp expect actual
50 -'
51 -
52 -cat >expect <<'EOF'
53 -3
54 -2
55 -6
56 -4
57 -5
58 -1
59 -8
60 -EOF
61 -test_expect_success 'stack order' '
62 - test-tool prio-queue stack 8 1 5 4 6 2 3 dump >actual &&
63 - test_cmp expect actual
64 -'
65 -
66 -test_done
t/unit-tests/t-prio-queue.c new
+98
@@ -0,0 +1,98 @@
1 +#include "test-lib.h"
2 +#include "prio-queue.h"
3 +
4 +static int intcmp(const void *va, const void *vb, void *data UNUSED)
5 +{
6 + const int *a = va, *b = vb;
7 + return *a - *b;
8 +}
9 +
10 +
11 +#define MISSING -1
12 +#define DUMP -2
13 +#define STACK -3
14 +#define GET -4
15 +#define REVERSE -5
16 +
17 +static int show(int *v)
18 +{
19 + return v ? *v : MISSING;
20 +}
21 +
22 +static void test_prio_queue(int *input, int *result, size_t input_size)
23 +{
24 + struct prio_queue pq = { intcmp };
25 +
26 + for (int i = 0, j = 0; i < input_size; i++) {
27 + void *peek, *get;
28 + switch(input[i]) {
29 + case GET:
30 + peek = prio_queue_peek(&pq);
31 + get = prio_queue_get(&pq);
32 + if (!check(peek == get))
33 + return;
34 + if(!check_int(result[j++], ==, show(get)))
35 + test_msg("failed at result[] index %d", j-1);
36 + break;
37 + case DUMP:
38 + while ((peek = prio_queue_peek(&pq))) {
39 + get = prio_queue_get(&pq);
40 + if (!check(peek == get))
41 + return;
42 + if(!check_int(result[j++], ==, show(get)))
43 + test_msg("failed at result[] index %d", j-1);
44 + }
45 + break;
46 + case STACK:
47 + pq.compare = NULL;
48 + break;
49 + case REVERSE:
50 + prio_queue_reverse(&pq);
51 + break;
52 + default:
53 + prio_queue_put(&pq, &input[i]);
54 + break;
55 + }
56 + }
57 + clear_prio_queue(&pq);
58 +}
59 +
60 +#define BASIC_INPUT 2, 6, 3, 10, 9, 5, 7, 4, 5, 8, 1, DUMP
61 +#define BASIC_RESULT 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10
62 +
63 +#define MIXED_PUT_GET_INPUT 6, 2, 4, GET, 5, 3, GET, GET, 1, DUMP
64 +#define MIXED_PUT_GET_RESULT 2, 3, 4, 1, 5, 6
65 +
66 +#define EMPTY_QUEUE_INPUT 1, 2, GET, GET, GET, 1, 2, GET, GET, GET
67 +#define EMPTY_QUEUE_RESULT 1, 2, MISSING, 1, 2, MISSING
68 +
69 +#define STACK_INPUT STACK, 8, 1, 5, 4, 6, 2, 3, DUMP
70 +#define STACK_RESULT 3, 2, 6, 4, 5, 1, 8
71 +
72 +#define REVERSE_STACK_INPUT STACK, 1, 2, 3, 4, 5, 6, REVERSE, DUMP
73 +#define REVERSE_STACK_RESULT 1, 2, 3, 4, 5, 6
74 +
75 +#define TEST_INPUT(INPUT, RESULT, name) \
76 + static void test_##name(void) \
77 +{ \
78 + int input[] = {INPUT}; \
79 + int result[] = {RESULT}; \
80 + test_prio_queue(input, result, ARRAY_SIZE(input)); \
81 +}
82 +
83 +TEST_INPUT(BASIC_INPUT, BASIC_RESULT, basic)
84 +TEST_INPUT(MIXED_PUT_GET_INPUT, MIXED_PUT_GET_RESULT, mixed)
85 +TEST_INPUT(EMPTY_QUEUE_INPUT, EMPTY_QUEUE_RESULT, empty)
86 +TEST_INPUT(STACK_INPUT, STACK_RESULT, stack)
87 +TEST_INPUT(REVERSE_STACK_INPUT, REVERSE_STACK_RESULT, reverse)
88 +
89 +int cmd_main(int argc, const char **argv)
90 +{
91 + TEST(test_basic(), "prio-queue works for basic input");
92 + TEST(test_mixed(), "prio-queue works for mixed put & get commands");
93 + TEST(test_empty(), "prio-queue works when queue is empty");
94 + TEST(test_stack(), "prio-queue works when used as a LIFO stack");
95 + TEST(test_reverse(), "prio-queue works when LIFO stack is reversed");
96 +
97 + return test_done();
98 +}