refs/packed-backend.c: add trace2 counters for jump list
The previous commit added low-level tests to ensure that the packed-refs iterator did not enumerate excluded sections of the refspace. However, there was no guarantee that these sections weren't being visited, only that they were being suppressed from the output. To harden these tests, add a trace2 counter which tracks the number of regions skipped by the packed-refs iterator, and assert on its value. Suggested-by: Derrick Stolee <derrickstolee@github.com> Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Taylor Blau committed
Jul 10, 2023 at 17:12 UTC
c489f47a649da8984a2240032e1d819e9a80ea2a
4 files changed
+49
-19
refs/packed-backend.c
+2
@@ -12,6 +12,7 @@
12
#include "../chdir-notify.h"
13
#include "../wrapper.h"
14
#include "../write-or-die.h"
15
+#include "../trace2.h"
16
17
enum mmap_strategy {
18
/*
@@ -845,6 +846,7 @@ static int next_record(struct packed_ref_iterator *iter)
846
iter->jump_cur++;
847
if (iter->pos < curr->end) {
848
iter->pos = curr->end;
849
+ trace2_counter_add(TRACE2_COUNTER_ID_PACKED_REFS_JUMPS, 1);
850
/* jumps are coalesced, so only one jump is necessary */
851
break;
852
}
t/t1419-exclude-refs.sh
+40
-19
@@ -9,7 +9,8 @@ TEST_PASSES_SANITIZE_LEAK=true
9
. ./test-lib.sh
10
11
for_each_ref__exclude () {
12
- test-tool ref-store main for-each-ref--exclude "$@" >actual.raw
12
+ GIT_TRACE2_PERF=1 test-tool ref-store main \
13
+ for-each-ref--exclude "$@" >actual.raw
14
cut -d ' ' -f 2 actual.raw
15
}
16
@@ -17,6 +18,17 @@ for_each_ref () {
18
git for-each-ref --format='%(refname)' "$@"
19
}
20
21
+assert_jumps () {
22
+ local nr="$1"
23
+ local trace="$2"
24
+
25
+ grep -q "name:jumps_made value:$nr$" $trace
26
+}
27
+
28
+assert_no_jumps () {
29
+ ! assert_jumps ".*" "$1"
30
+}
31
+
32
test_expect_success 'setup' '
33
test_commit --no-tag base &&
34
base="$(git rev-parse HEAD)" &&
@@ -35,67 +47,76 @@ test_expect_success 'setup' '
47
'
48
49
test_expect_success 'excluded region in middle' '
38
- for_each_ref__exclude refs/heads refs/heads/foo >actual &&
50
+ for_each_ref__exclude refs/heads refs/heads/foo >actual 2>perf &&
51
for_each_ref refs/heads/bar refs/heads/baz refs/heads/quux >expect &&
52
41
- test_cmp expect actual
53
+ test_cmp expect actual &&
54
+ assert_jumps 1 perf
55
'
56
57
test_expect_success 'excluded region at beginning' '
45
- for_each_ref__exclude refs/heads refs/heads/bar >actual &&
58
+ for_each_ref__exclude refs/heads refs/heads/bar >actual 2>perf &&
59
for_each_ref refs/heads/baz refs/heads/foo refs/heads/quux >expect &&
60
48
- test_cmp expect actual
61
+ test_cmp expect actual &&
62
+ assert_jumps 1 perf
63
'
64
65
test_expect_success 'excluded region at end' '
52
- for_each_ref__exclude refs/heads refs/heads/quux >actual &&
66
+ for_each_ref__exclude refs/heads refs/heads/quux >actual 2>perf &&
67
for_each_ref refs/heads/foo refs/heads/bar refs/heads/baz >expect &&
68
55
- test_cmp expect actual
69
+ test_cmp expect actual &&
70
+ assert_jumps 1 perf
71
'
72
73
test_expect_success 'disjoint excluded regions' '
59
- for_each_ref__exclude refs/heads refs/heads/bar refs/heads/quux >actual &&
74
+ for_each_ref__exclude refs/heads refs/heads/bar refs/heads/quux >actual 2>perf &&
75
for_each_ref refs/heads/baz refs/heads/foo >expect &&
76
62
- test_cmp expect actual
77
+ test_cmp expect actual &&
78
+ assert_jumps 2 perf
79
'
80
81
test_expect_success 'adjacent, non-overlapping excluded regions' '
66
- for_each_ref__exclude refs/heads refs/heads/bar refs/heads/baz >actual &&
82
+ for_each_ref__exclude refs/heads refs/heads/bar refs/heads/baz >actual 2>perf &&
83
for_each_ref refs/heads/foo refs/heads/quux >expect &&
84
69
- test_cmp expect actual
85
+ test_cmp expect actual &&
86
+ assert_jumps 1 perf
87
'
88
89
test_expect_success 'overlapping excluded regions' '
73
- for_each_ref__exclude refs/heads refs/heads/ba refs/heads/baz >actual &&
90
+ for_each_ref__exclude refs/heads refs/heads/ba refs/heads/baz >actual 2>perf &&
91
for_each_ref refs/heads/foo refs/heads/quux >expect &&
92
76
- test_cmp expect actual
93
+ test_cmp expect actual &&
94
+ assert_jumps 1 perf
95
'
96
97
test_expect_success 'several overlapping excluded regions' '
98
for_each_ref__exclude refs/heads \
81
- refs/heads/bar refs/heads/baz refs/heads/foo >actual &&
99
+ refs/heads/bar refs/heads/baz refs/heads/foo >actual 2>perf &&
100
for_each_ref refs/heads/quux >expect &&
101
84
- test_cmp expect actual
102
+ test_cmp expect actual &&
103
+ assert_jumps 1 perf
104
'
105
106
test_expect_success 'non-matching excluded section' '
88
- for_each_ref__exclude refs/heads refs/heads/does/not/exist >actual &&
107
+ for_each_ref__exclude refs/heads refs/heads/does/not/exist >actual 2>perf &&
108
for_each_ref >expect &&
109
91
- test_cmp expect actual
110
+ test_cmp expect actual &&
111
+ assert_no_jumps perf
112
'
113
114
test_expect_success 'meta-characters are discarded' '
95
- for_each_ref__exclude refs/heads "refs/heads/ba*" >actual &&
115
+ for_each_ref__exclude refs/heads "refs/heads/ba*" >actual 2>perf &&
116
for_each_ref >expect &&
117
98
- test_cmp expect actual
118
+ test_cmp expect actual &&
119
+ assert_no_jumps perf
120
'
121
122
test_done
trace2.h
+2
@@ -551,6 +551,8 @@ enum trace2_counter_id {
551
TRACE2_COUNTER_ID_TEST1 = 0, /* emits summary event only */
552
TRACE2_COUNTER_ID_TEST2, /* emits summary and thread events */
553
554
+ TRACE2_COUNTER_ID_PACKED_REFS_JUMPS, /* counts number of jumps */
555
+
556
/* Add additional counter definitions before here. */
557
TRACE2_NUMBER_OF_COUNTERS
558
};
trace2/tr2_ctr.c
+5
@@ -27,6 +27,11 @@ static struct tr2_counter_metadata tr2_counter_metadata[TRACE2_NUMBER_OF_COUNTER
27
.name = "test2",
28
.want_per_thread_events = 1,
29
},
30
+ [TRACE2_COUNTER_ID_PACKED_REFS_JUMPS] = {
31
+ .category = "packed-refs",
32
+ .name = "jumps_made",
33
+ .want_per_thread_events = 0,
34
+ },
35
36
/* Add additional metadata before here. */
37
};