blob: 79fecefac4aeee6673b4464fb931c6a9e84be00b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#!/bin/sh

# The snapshot page hands a branch back as an archive. One function below
# registers the same checks for every tar based format, and each format
# needs the same compressor cgit pipes through on the server, so one missing
# tool skips that format on both grounds at once. zip follows at the end,
# since unzip shares no flags with the rest.

test_description='Verify snapshot'
. ./setup.sh

# Registers the checks for one tar based format. Takes the archive suffix,
# the content type the response must carry, the compressor to unpack with and
# the name of the prerequisite guarding the checks.
test_tar_snapshot() {
	ext=$1
	type=$2
	tool=$3
	prereq=$4

	if command -v "$tool" >/dev/null 2>&1
	then
		test_set_prereq $prereq
	else
		say "Skipping $ext validation tests: $tool not found"
	fi

	test_expect_success $prereq "get foo/snapshot/master.$ext" "
		cgit_url 'foo/snapshot/master.$ext' >tmp
	"

	test_expect_success $prereq "check $ext response headers" "
		head -n 1 tmp | grep 'Status: 200 OK' &&
		head -n 2 tmp | grep 'Content-Type: $type' &&
		head -n 3 tmp | grep 'Content-Disposition: inline; filename=.master.$ext.'
	"

	test_expect_success $prereq "verify $ext format" "
		strip_headers <tmp >master.$ext &&
		'$tool' -t 'master.$ext'
	"

	test_expect_success $prereq "untar $ext and verify the content" "
		rm -rf master &&
		'$tool' -dc 'master.$ext' | tar -xf - &&
		ls master/ >output &&
		test_line_count = 5 output &&
		grep '^5\$' master/file-5 &&
		test_line_count = 1 master/file-5
	"
}

# The uncompressed tar comes straight out of git's archive writer, so tar
# itself both proves the format and unpacks it.
test_expect_success 'get foo/snapshot/master.tar' '
	cgit_url "foo/snapshot/master.tar" >tmp
'

test_expect_success 'check tar response headers' '
	head -n 1 tmp | grep "Status: 200 OK" &&
	head -n 2 tmp | grep "Content-Type: application/x-tar" &&
	head -n 3 tmp | grep "Content-Disposition: inline; filename=.master.tar."
'

test_expect_success 'untar and verify the content' '
	strip_headers <tmp >master.tar &&
	rm -rf master &&
	tar -xf master.tar &&
	ls master/ >output &&
	test_line_count = 5 output &&
	grep "^5$" master/file-5 &&
	test_line_count = 1 master/file-5
'

test_tar_snapshot tar.gz  application/gzip  gzip  GZIP
test_tar_snapshot tar.bz2 application/x-bzip2 bzip2 BZIP2
test_tar_snapshot tar.lz  application/x-lzip  lzip  LZIP
test_tar_snapshot tar.xz  application/x-xz    xz    XZ
test_tar_snapshot tar.zst application/zstd  zstd  ZSTD

if command -v unzip >/dev/null 2>&1
then
	test_set_prereq UNZIP
else
	say 'Skipping zip validation tests: unzip not found'
fi

test_expect_success 'get foo/snapshot/master.zip' '
	cgit_url "foo/snapshot/master.zip" >tmp
'

test_expect_success 'check zip response headers' '
	head -n 1 tmp | grep "Status: 200 OK" &&
	head -n 2 tmp | grep "Content-Type: application/zip" &&
	head -n 3 tmp | grep "Content-Disposition: inline; filename=.master.zip."
'

test_expect_success 'strip off the header lines' '
	strip_headers <tmp >master.zip
'

test_expect_success UNZIP 'verify zip format' '
	unzip -t master.zip
'

test_expect_success UNZIP 'unzip and verify the content' '
	rm -rf master &&
	unzip master.zip &&
	ls master/ >output &&
	test_line_count = 5 output &&
	grep "^5$" master/file-5 &&
	test_line_count = 1 master/file-5
'

# A tag named v1.0 sheds its v in the snapshot name unless dropping it would
# merge two tags. The first tag below stays a loose ref on purpose, because on
# a case-insensitive filesystem a ref lookup for V1.0 finds the loose v1.0
# file, and deciding by lookups called every fresh tag ambiguous and kept its
# v until git happened to pack the refs.
test_expect_success 'set up a repo with a versioned tag' '
	mkrepo repos/vtags 2 &&
	git -C repos/vtags update-ref refs/tags/v1.0 HEAD &&
	{
		echo "virtual-root=/" &&
		echo "cache-size=0" &&
		echo "snapshots=tar.gz" &&
		echo "repo.url=vtags" &&
		echo "repo.path=$PWD/repos/vtags/.git"
	} >vtagsrc
'

test_expect_success 'a loose v tag still sheds its v in the snapshot name' '
	CGIT_CONFIG="$PWD/vtagsrc" QUERY_STRING="url=vtags/refs/" cgit >tmp &&
	grep "vtags-1.0.tar.gz" tmp &&
	! grep "vtags-v1.0.tar.gz" tmp
'

# The second tag goes in only after the first is packed, since two loose files
# differing in case alone cannot coexist on a case-insensitive filesystem.
test_expect_success 'a real case collision keeps the v on both tags' '
	git -C repos/vtags pack-refs --all &&
	git -C repos/vtags update-ref refs/tags/V1.0 HEAD~1 &&
	CGIT_CONFIG="$PWD/vtagsrc" QUERY_STRING="url=vtags/refs/" cgit >tmp &&
	grep "vtags-v1.0.tar.gz" tmp &&
	grep "vtags-V1.0.tar.gz" tmp &&
	! grep "vtags-1.0.tar.gz" tmp
'

test_done