Blob


1 #!/bin/sh
2 #
3 # Copyright (c) 2019 Stefan Sperling <stsp@openbsd.org>
4 #
5 # Permission to use, copy, modify, and distribute this software for any
6 # purpose with or without fee is hereby granted, provided that the above
7 # copyright notice and this permission notice appear in all copies.
8 #
9 # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 . ./common.sh
19 test_tag_create() {
20 local testroot=`test_init tag_create`
21 local commit_id=`git_show_head $testroot/repo`
22 local tag=1.0.0
23 local tag2=2.0.0
25 # Create a tag based on repository's HEAD reference
26 got tag -m 'test' -r $testroot/repo -c HEAD $tag > $testroot/stdout
27 ret=$?
28 if [ $ret -ne 0 ]; then
29 echo "got ref command failed unexpectedly"
30 test_done "$testroot" "$ret"
31 return 1
32 fi
34 tag_id=`got ref -r $testroot/repo -l \
35 | grep "^refs/tags/$tag" | tr -d ' ' | cut -d: -f2`
36 echo "Created tag $tag_id" > $testroot/stdout.expected
37 cmp -s $testroot/stdout $testroot/stdout.expected
38 ret=$?
39 if [ $ret -ne 0 ]; then
40 diff -u $testroot/stdout.expected $testroot/stdout
41 test_done "$testroot" "$ret"
42 return 1
43 fi
45 # Ensure that Git recognizes the tag Got has created
46 (cd $testroot/repo && git checkout -q $tag)
47 ret=$?
48 if [ $ret -ne 0 ]; then
49 echo "git checkout command failed unexpectedly"
50 test_done "$testroot" "$ret"
51 return 1
52 fi
54 # Ensure Got recognizes the new tag
55 got checkout -c $tag $testroot/repo $testroot/wt >/dev/null
56 ret=$?
57 if [ $ret -ne 0 ]; then
58 echo "got checkout command failed unexpectedly"
59 test_done "$testroot" "$ret"
60 return 1
61 fi
63 # Create a tag based on implied worktree HEAD ref
64 (cd $testroot/wt && got tag -m 'test' $tag2 > $testroot/stdout)
65 ret=$?
66 if [ $ret -ne 0 ]; then
67 test_done "$testroot" "$ret"
68 return 1
69 fi
71 tag_id2=`got ref -r $testroot/repo -l \
72 | grep "^refs/tags/$tag2" | tr -d ' ' | cut -d: -f2`
73 echo "Created tag $tag_id2" > $testroot/stdout.expected
74 cmp -s $testroot/stdout $testroot/stdout.expected
75 ret=$?
76 if [ $ret -ne 0 ]; then
77 diff -u $testroot/stdout.expected $testroot/stdout
78 test_done "$testroot" "$ret"
79 return 1
80 fi
82 (cd $testroot/repo && git checkout -q $tag2)
83 ret=$?
84 if [ $ret -ne 0 ]; then
85 echo "git checkout command failed unexpectedly"
86 test_done "$testroot" "$ret"
87 return 1
88 fi
90 # Attempt to create a tag pointing at a non-commit
91 local tree_id=`git_show_tree $testroot/repo`
92 (cd $testroot/wt && got tag -m 'test' -c $tree_id foobar \
93 2> $testroot/stderr)
94 ret=$?
95 if [ $ret -eq 0 ]; then
96 echo "git tag command succeeded unexpectedly"
97 test_done "$testroot" "1"
98 return 1
99 fi
101 echo "got: commit $tree_id: object not found" \
102 > $testroot/stderr.expected
103 cmp -s $testroot/stderr $testroot/stderr.expected
104 ret=$?
105 if [ $ret -ne 0 ]; then
106 diff -u $testroot/stderr.expected $testroot/stderr
107 test_done "$testroot" "$ret"
108 return 1
109 fi
111 got ref -r $testroot/repo -l > $testroot/stdout
112 echo "HEAD: $commit_id" > $testroot/stdout.expected
113 echo -n "refs/got/worktree/base-" >> $testroot/stdout.expected
114 cat $testroot/wt/.got/uuid | tr -d '\n' >> $testroot/stdout.expected
115 echo ": $commit_id" >> $testroot/stdout.expected
116 echo "refs/heads/master: $commit_id" >> $testroot/stdout.expected
117 echo "refs/tags/$tag: $tag_id" >> $testroot/stdout.expected
118 echo "refs/tags/$tag2: $tag_id2" >> $testroot/stdout.expected
119 cmp -s $testroot/stdout $testroot/stdout.expected
120 ret=$?
121 if [ $ret -ne 0 ]; then
122 diff -u $testroot/stdout.expected $testroot/stdout
123 fi
124 test_done "$testroot" "$ret"
127 test_tag_list() {
128 local testroot=`test_init tag_list`
129 local commit_id=`git_show_head $testroot/repo`
130 local tag=1.0.0
131 local tag2=2.0.0
133 # create tag with Git
134 (cd $testroot/repo && git tag -a -m 'test' $tag)
135 # create tag with Got
136 (cd $testroot/repo && got tag -m 'test' $tag2 > /dev/null)
138 tag_id=`got ref -r $testroot/repo -l \
139 | grep "^refs/tags/$tag" | tr -d ' ' | cut -d: -f2`
140 local tagger_time=`git_show_tagger_time $testroot/repo $tag`
142 local prev_LC_TIME=$LC_TIME
143 export LC_TIME=C
144 d1=`date -u -d "@$tagger_time" +"%a %b %e %X %Y UTC"`
145 LC_TIME="$prev_LC_TIME"
147 tag_id2=`got ref -r $testroot/repo -l \
148 | grep "^refs/tags/$tag2" | tr -d ' ' | cut -d: -f2`
149 local tagger_time2=`git_show_tagger_time $testroot/repo $tag2`
151 prev_LC_TIME="$LC_TIME"
152 export LC_TIME=C
153 d2=`date -u -d "@$tagger_time2" +"%a %b %e %X %Y UTC"`
154 LC_TIME="$prev_LC_TIME"
156 got tag -r $testroot/repo -l > $testroot/stdout
158 echo "-----------------------------------------------" \
159 > $testroot/stdout.expected
160 echo "tag $tag2 $tag_id2" >> $testroot/stdout.expected
161 echo "from: $GOT_AUTHOR" >> $testroot/stdout.expected
162 echo "date: $d2" >> $testroot/stdout.expected
163 echo "object: commit $commit_id" >> $testroot/stdout.expected
164 echo " " >> $testroot/stdout.expected
165 echo " test" >> $testroot/stdout.expected
166 echo " " >> $testroot/stdout.expected
167 echo "-----------------------------------------------" \
168 >> $testroot/stdout.expected
169 echo "tag $tag $tag_id" >> $testroot/stdout.expected
170 echo "from: $GOT_AUTHOR" >> $testroot/stdout.expected
171 echo "date: $d1" >> $testroot/stdout.expected
172 echo "object: commit $commit_id" >> $testroot/stdout.expected
173 echo " " >> $testroot/stdout.expected
174 echo " test" >> $testroot/stdout.expected
175 echo " " >> $testroot/stdout.expected
176 cmp -s $testroot/stdout $testroot/stdout.expected
177 ret=$?
178 if [ $ret -ne 0 ]; then
179 diff -u $testroot/stdout.expected $testroot/stdout
180 test_done "$testroot" "$ret"
181 return 1
182 fi
184 got tag -r $testroot/repo -l $tag > $testroot/stdout
186 echo "-----------------------------------------------" \
187 > $testroot/stdout.expected
188 echo "tag $tag $tag_id" >> $testroot/stdout.expected
189 echo "from: $GOT_AUTHOR" >> $testroot/stdout.expected
190 echo "date: $d1" >> $testroot/stdout.expected
191 echo "object: commit $commit_id" >> $testroot/stdout.expected
192 echo " " >> $testroot/stdout.expected
193 echo " test" >> $testroot/stdout.expected
194 echo " " >> $testroot/stdout.expected
195 cmp -s $testroot/stdout $testroot/stdout.expected
196 ret=$?
197 if [ $ret -ne 0 ]; then
198 diff -u $testroot/stdout.expected $testroot/stdout
199 test_done "$testroot" "$ret"
200 return 1
201 fi
203 got tag -r $testroot/repo -l $tag2 > $testroot/stdout
205 echo "-----------------------------------------------" \
206 > $testroot/stdout.expected
207 echo "tag $tag2 $tag_id2" >> $testroot/stdout.expected
208 echo "from: $GOT_AUTHOR" >> $testroot/stdout.expected
209 echo "date: $d2" >> $testroot/stdout.expected
210 echo "object: commit $commit_id" >> $testroot/stdout.expected
211 echo " " >> $testroot/stdout.expected
212 echo " test" >> $testroot/stdout.expected
213 echo " " >> $testroot/stdout.expected
214 cmp -s $testroot/stdout $testroot/stdout.expected
215 ret=$?
216 if [ $ret -ne 0 ]; then
217 diff -u $testroot/stdout.expected $testroot/stdout
218 fi
219 test_done "$testroot" "$ret"
222 test_tag_list_lightweight() {
223 local testroot=`test_init tag_list_lightweight`
224 local commit_id=`git_show_head $testroot/repo`
225 local tag=1.0.0
226 local tag2=2.0.0
228 # create "lightweight" tag with Git
229 (cd $testroot/repo && git tag $tag)
230 (cd $testroot/repo && git tag $tag2)
232 tag_id=`got ref -r $testroot/repo -l \
233 | grep "^refs/tags/$tag" | tr -d ' ' | cut -d: -f2`
234 local tagger_time=`git_show_author_time $testroot/repo $tag`
235 local prev_LC_TIME=$LC_TIME
236 export LC_TIME=C
237 d1=`date -u -d "@$tagger_time" +"%a %b %e %X %Y UTC"`
238 LC_TIME="$prev_LC_TIME"
239 tag_id2=`got ref -r $testroot/repo -l \
240 | grep "^refs/tags/$tag2" | tr -d ' ' | cut -d: -f2`
241 local tagger_time2=`git_show_author_time $testroot/repo $tag2`
243 export LC_TIME=C
244 d2=`date -u -d "@$tagger_time2" +"%a %b %e %X %Y UTC"`
245 LC_TIME="$prev_LC_TIME"
247 got tag -r $testroot/repo -l > $testroot/stdout
249 echo "-----------------------------------------------" \
250 > $testroot/stdout.expected
251 echo "tag $tag2 $tag_id2" >> $testroot/stdout.expected
252 echo "from: $GOT_AUTHOR" >> $testroot/stdout.expected
253 echo "date: $d2" >> $testroot/stdout.expected
254 echo "object: commit $commit_id" >> $testroot/stdout.expected
255 echo " " >> $testroot/stdout.expected
256 echo " adding the test tree" >> $testroot/stdout.expected
257 echo " " >> $testroot/stdout.expected
258 echo "-----------------------------------------------" \
259 >> $testroot/stdout.expected
260 echo "tag $tag $tag_id" >> $testroot/stdout.expected
261 echo "from: $GOT_AUTHOR" >> $testroot/stdout.expected
262 echo "date: $d1" >> $testroot/stdout.expected
263 echo "object: commit $commit_id" >> $testroot/stdout.expected
264 echo " " >> $testroot/stdout.expected
265 echo " adding the test tree" >> $testroot/stdout.expected
266 echo " " >> $testroot/stdout.expected
267 cmp -s $testroot/stdout $testroot/stdout.expected
268 ret=$?
269 if [ $ret -ne 0 ]; then
270 diff -u $testroot/stdout.expected $testroot/stdout
271 fi
272 test_done "$testroot" "$ret"
275 test_tag_create_ssh_signed() {
276 local testroot=`test_init tag_create`
277 local commit_id=`git_show_head $testroot/repo`
278 local tag=1.0.0
279 local tag2=2.0.0
280 local tag3=3.0.0
282 ssh-keygen -q -N '' -t ed25519 -f $testroot/id_ed25519
283 ret=$?
284 if [ $ret -ne 0 ]; then
285 echo "ssh-keygen failed unexpectedly"
286 test_done "$testroot" "$ret"
287 return 1
288 fi
289 touch $testroot/allowed_signers
290 touch $testroot/revoked_signers
291 echo "allowed_signers \"$testroot/allowed_signers\"" >> \
292 $testroot/repo/.git/got.conf
293 echo "revoked_signers \"$testroot/revoked_signers\"" >> \
294 $testroot/repo/.git/got.conf
296 # Create a signed tag based on repository's HEAD reference
297 got tag -s $testroot/id_ed25519 -m 'test' -r $testroot/repo -c HEAD \
298 $tag > $testroot/stdout
299 ret=$?
300 if [ $ret -ne 0 ]; then
301 echo "got tag command failed unexpectedly"
302 test_done "$testroot" "$ret"
303 return 1
304 fi
306 tag_id=`got ref -r $testroot/repo -l \
307 | grep "^refs/tags/$tag" | tr -d ' ' | cut -d: -f2`
308 echo "Created tag $tag_id" > $testroot/stdout.expected
309 cmp -s $testroot/stdout $testroot/stdout.expected
310 ret=$?
311 if [ $ret -ne 0 ]; then
312 diff -u $testroot/stdout.expected $testroot/stdout
313 test_done "$testroot" "$ret"
314 return 1
315 fi
317 # Ensure validation fails when the key is not allowed
318 echo "signature: Could not verify signature." > \
319 $testroot/stdout.expected
320 VERIFY_STDOUT=$(got tag -r $testroot/repo -V $tag 2> $testroot/stderr)
321 ret=$?
322 echo "$VERIFY_STDOUT" | grep '^signature: ' > $testroot/stdout
323 if [ $ret -eq 0 ]; then
324 diff -u $testroot/stdout.expected $testroot/stdout
325 test_done "$testroot" "1"
326 return 1
327 fi
329 GOOD_SIG='Good "git" signature for flan_hacker@openbsd.org with ED25519 key '
331 # Validate the signature with the key allowed
332 echo -n 'flan_hacker@openbsd.org ' > $testroot/allowed_signers
333 cat $testroot/id_ed25519.pub >> $testroot/allowed_signers
334 GOT_STDOUT=$(got tag -r $testroot/repo -V $tag 2> $testroot/stderr)
335 ret=$?
336 if [ $ret -ne 0 ]; then
337 echo "got tag command failed unexpectedly"
338 diff -u $testroot/stdout.expected $testroot/stdout
339 test_done "$testroot" "$ret"
340 return 1
341 fi
343 if ! echo "$GOT_STDOUT" | grep -q "^signature: $GOOD_SIG"; then
344 echo "got tag command failed to validate signature"
345 test_done "$testroot" "1"
346 return 1
347 fi
349 # Ensure validation fails after revoking the key
350 ssh-keygen -y -f $testroot/id_ed25519 >> $testroot/revoked_signers
351 echo "signature: Could not verify signature." > \
352 $testroot/stdout.expected
353 VERIFY_STDOUT=$(got tag -r $testroot/repo -V $tag 2> $testroot/stderr)
354 ret=$?
355 echo "$VERIFY_STDOUT" | grep '^signature: ' > $testroot/stdout
356 if [ $ret -eq 0 ]; then
357 diff -u $testroot/stdout.expected $testroot/stdout
358 test_done "$testroot" "1"
359 return 1
360 fi
362 # Later tests expect validation to work
363 echo -n > $testroot/revoked_signers
365 # Ensure that Git recognizes and verifies the tag Got has created
366 (cd $testroot/repo && git checkout -q $tag)
367 ret=$?
368 if [ $ret -ne 0 ]; then
369 echo "git checkout command failed unexpectedly"
370 test_done "$testroot" "$ret"
371 return 1
372 fi
373 (cd $testroot/repo && git config --local gpg.ssh.allowedSignersFile \
374 $testroot/allowed_signers)
375 GIT_STDERR=$(cd $testroot/repo && git tag -v $tag 2>&1 1>/dev/null)
376 if ! echo "$GIT_STDERR" | grep -q "^$GOOD_SIG"; then
377 echo "git tag command failed to validate signature"
378 test_done "$testroot" "1"
379 return 1
380 fi
382 # Ensure Got recognizes the new tag
383 got checkout -c $tag $testroot/repo $testroot/wt >/dev/null
384 ret=$?
385 if [ $ret -ne 0 ]; then
386 echo "got checkout command failed unexpectedly"
387 test_done "$testroot" "$ret"
388 return 1
389 fi
391 # Create another signed tag with a SHA1 commit ID
392 got tag -s $testroot/id_ed25519 -m 'test' -r $testroot/repo \
393 -c $commit_id $tag2 > $testroot/stdout
395 # Create another signed tag with key defined in got.conf(5)
396 echo "signer_id \"$testroot/id_ed25519\"" >> \
397 $testroot/repo/.git/got.conf
398 got tag -m 'test' -r $testroot/repo -c HEAD $tag3 > $testroot/stdout
399 ret=$?
400 if [ $ret -ne 0 ]; then
401 echo "got tag command failed unexpectedly"
402 test_done "$testroot" "$ret"
403 return 1
404 fi
406 # got tag -V behaves like got tag -l, but with verification enabled.
407 got tag -l -r $testroot/repo > $testroot/stdout.list
408 got tag -V -r $testroot/repo > $testroot/stdout.verify
409 diff -U0 $testroot/stdout.list $testroot/stdout.verify |
410 sed -e '/^--- /d' -e '/^+++ /d' > $testroot/stdout
411 echo "@@ -5,0 +6 @@" > $testroot/stdout.expected
412 echo -n "+signature: $GOOD_SIG" >> $testroot/stdout.expected
413 ssh-keygen -l -f $testroot/id_ed25519.pub | cut -d' ' -f 2 \
414 >> $testroot/stdout.expected
415 echo "@@ -19,0 +21 @@" >> $testroot/stdout.expected
416 echo -n "+signature: $GOOD_SIG" >> $testroot/stdout.expected
417 ssh-keygen -l -f $testroot/id_ed25519.pub | cut -d' ' -f 2 \
418 >> $testroot/stdout.expected
419 echo "@@ -33,0 +36 @@" >> $testroot/stdout.expected
420 echo -n "+signature: $GOOD_SIG" >> $testroot/stdout.expected
421 ssh-keygen -l -f $testroot/id_ed25519.pub | cut -d' ' -f 2 \
422 >> $testroot/stdout.expected
423 cmp -s $testroot/stdout $testroot/stdout.expected
424 ret=$?
425 if [ $ret -ne 0 ]; then
426 diff -u $testroot/stdout.expected $testroot/stdout
427 fi
428 test_done "$testroot" "$ret"
431 test_tag_create_ssh_signed_missing_key() {
432 local testroot=`test_init tag_create`
433 local commit_id=`git_show_head $testroot/repo`
434 local tag=1.0.0
436 # Fail to create a signed tag due to a missing SSH key
437 got tag -s $testroot/bogus -m 'test' -r $testroot/repo \
438 -c HEAD $tag > $testroot/stdout 2> $testroot/stderr
439 ret=$?
440 if [ $ret -eq 0 ]; then
441 echo "got tag command succeeded unexpectedly"
442 test_done "$testroot" 1
443 return 1
444 fi
446 got ref -r $testroot/repo -l > $testroot/stdout
447 echo "HEAD: refs/heads/master" > $testroot/stdout.expected
448 echo "refs/heads/master: $commit_id" >> $testroot/stdout.expected
449 cmp -s $testroot/stdout $testroot/stdout.expected
450 ret=$?
451 if [ $ret -ne 0 ]; then
452 diff -u $testroot/stdout.expected $testroot/stdout
453 test_done "$testroot" "$ret"
454 return 1
455 fi
456 printf "Couldn't load public key $testroot/bogus: " \
457 >> $testroot/stderr.expected
458 printf "No such file or directory\r\n" >> $testroot/stderr.expected
459 echo "got: unable to sign tag" >> $testroot/stderr.expected
460 cmp -s $testroot/stderr $testroot/stderr.expected
461 ret=$?
462 if [ $ret -ne 0 ]; then
463 diff -u $testroot/stderr.expected $testroot/stderr
464 fi
465 test_done "$testroot" "$ret"
468 test_parseargs "$@"
469 run_test test_tag_create
470 run_test test_tag_list
471 run_test test_tag_list_lightweight
472 run_test test_tag_create_ssh_signed
473 run_test test_tag_create_ssh_signed_missing_key