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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
|
<!-- -*- markdown -*- -->
Test library for Gitano
=======================
When running tests under yarn, for each scenario, we are provided with a
temporary working directory called `$DATADIR` which is a fresh directory for
each scenario being run. Within that base, we can set up any number of fake
SSH keys, a fake Gitano instance, fake users, and use them to make clones, do
pushes etc. Nearly all of the implementations rely on a tool in the testing
directory called `gitano-test-tool` the path to which is available as `$GTT`.
For ease of testing, the fake user who gets to "own" the Gitano instance will
be called `testinstance` and the keyset which they get to use in order to
access the repository will be called `adminkey`. This is important when it
comes to cloning, pushing, etc.
General instance management
---------------------------
IMPLEMENTS GIVEN a standard instance
$GTT createunixuser testinstance
$GTT createsshkey testinstance adminkey
$GTT createsshkey testinstance bypasskey
$GTT setupstandard testinstance adminkey bypasskey
if [ "$GTT_PROTO" = http ]; then
printf "%s" admin | GTT_PROTO=ssh $GTT runcommand \
testinstance adminkey as admin passwd \
>> "$DATADIR/stdout" 2>> "$DATADIR/stderr"
printf "%s" gitano-bypass | GTT_PROTO=ssh $GTT runcommand \
testinstance bypasskey as gitano-bypass passwd \
>> "$DATADIR/stdout" 2>> "$DATADIR/stderr"
fi
IMPLEMENTS FINALLY the instance is torn down
$GTT teardownstandard
Managing the fake unix users
----------------------------
The `gitano-test-tool` utility helps us manage fake UNIX users and give them
SSH keys. Sometimes it's helpful to be able to work with these...
IMPLEMENTS GIVEN a unix user called ([a-z][a-z0-9]*)
$GTT createunixuser "$MATCH_1"
IMPLEMENTS GIVEN ([a-z][a-z0-9]*) has keys called ([a-z][a-z0-9]*)
$GTT createsshkey "$MATCH_1" "$MATCH_2"
IMPLEMENTS WHEN ([a-z][a-z0-9]*) uses their ssh public key called ([a-z][a-z0-9]*) as stdin
cp "$DATADIR/user-home-$MATCH_1/.ssh/$MATCH_2.pub" "$DATADIR/stdin"
A lot of tests need a user which isn't `gitano-admin` to work with, this GIVEN
rolls up the creation of a unix user, allocation of an SSH key, and creation
of the user inside Gitano.
IMPLEMENTS GIVEN ([a-z][a-z0-9]*),? using ([a-z][a-z0-9_-]*),? adds a new user ([a-z][a-z0-9_-]*), with a key called ([a-z][a-z0-9_-]*)
$GTT createunixuser "$MATCH_3"
$GTT createsshkey "$MATCH_3" "$MATCH_4"
$GTT runcommand "$MATCH_1" "$MATCH_2" \
user add "$MATCH_3" "$MATCH_3"@testinstance "$MATCH_3's real name" > "$DATADIR/stdout" 2> "$DATADIR/stderr"
$GTT runcommand "$MATCH_1" "$MATCH_2" \
as "$MATCH_3" sshkey add default < \
"$($GTT pubkeyfilename "$MATCH_3" "$MATCH_4")" >> "$DATADIR/stdout" 2>> "$DATADIR/stderr"
if [ "$GTT_PROTO" = http ]; then
printf "%s" "$MATCH_3" | GTT_PROTO=ssh $GTT runcommand \
"$MATCH_1" "$MATCH_2" as "$MATCH_3" passwd \
>> "$DATADIR/stdout" 2>> "$DATADIR/stderr"
fi
Repository access
-----------------
IMPLEMENTS WHEN ([a-z][a-z0-9]*),? using ([a-z][a-z0-9]*),? clones ([^ ]+) as ([^ ]+)( with depth (\d+))?
$GTT clone "$MATCH_1" "$MATCH_2" "$MATCH_3" "$MATCH_4" ${MATCH_5:+ --no-local --depth="$MATCH_6"} \
>"$DATADIR/stdout" 2>"$DATADIR/stderr"
IMPLEMENTS WHEN ([a-z][a-z0-9]*),? using ([a-z][a-z0-9]*),? (expecting failure,? )?pushes ([^ ]+) to ([^ ]+)
if $GTT push "$MATCH_1" "$MATCH_2" "$MATCH_4" "$MATCH_5" \
>"$DATADIR/stdout" 2>"$DATADIR/stderr"; then
test "$MATCH_3" = ""
fi
IMPLEMENTS WHEN ([a-z][a-z0-9]*),? using ([a-z][a-z0-9]*),? (expecting failure,? )?destroys ([^ ]+) using the (.+) token
if $GTT runcommand "$MATCH_1" "$MATCH_2" \
destroy "$MATCH_4" "$(cat "$DATADIR/saved-tokens/$MATCH_5")" \
>"$DATADIR/stdout" 2>"$DATADIR/stderr"; then
test "$MATCH_3" = ""
fi
Server-side repository checking for behind-the-scenes work
----------------------------------------------------------
IMPLEMENTS THEN server-side ([^ ]+) file ([^ ]+) contains (.+)
cd "$($GTT serverlocation "$MATCH_1")"
grep -q "$MATCH_3" "$MATCH_2"
IMPLEMENTS THEN server-side ([^ ]+) file ([^ ]+) exists
cd "$($GTT serverlocation "$MATCH_1")"
test -e "$MATCH_2"
IMPLEMENTS THEN server-side ([^ ]+) has identical refs to ([^ ]+)
bash -c 'diff -u <(git ls-remote -ht "$($GTT serverlocation "$MATCH_1")" | sort -k2) <(git ls-remote -ht "$($GTT serverlocation "$MATCH_2")" | sort -k2)'
IMPLEMENTS THEN server-side ([^ ]+) has no missing objects
cd "$($GTT serverlocation "$MATCH_1")".git
git fsck
Clone manipulation
------------------
IMPLEMENTS THEN ([a-z][a-z0-9]*) has a clone of ([^ ]+)
$GTT cloneexists "$MATCH_1" "$MATCH_2"
IMPLEMENTS WHEN git pull happens in ([a-z][a-z0-9]*) ([^ ]+)
cd "$($GTT clonelocation "$MATCH_1" "$MATCH_2")"
git pull
IMPLEMENTS THEN ([a-z][a-z0-9]*) ([^ ]+) has a file called (.+)
cd "$($GTT clonelocation "$MATCH_1" "$MATCH_2")"
test -r "$MATCH_3"
IMPLEMENTS THEN ([a-z][a-z0-9]*) ([^ ]+) has no file called (.+)
set -x
cd "$($GTT clonelocation "$MATCH_1" "$MATCH_2")"
if test -r "$MATCH_3"; then false; else true; fi
IMPLEMENTS WHEN ([a-z][a-z0-9]*) ([a-z][a-z0-9]*) uses git archive to extract the tree of ([a-z][a-z0-9-]*) ([a-z][a-z0-9]*) to ([a-z][a-z0-9]*)
mkdir -p "$DATADIR/$MATCH_5"
$GTT gitarchive "$MATCH_1" "$MATCH_2" "$MATCH_3" "$MATCH_4" | tar -C "$DATADIR/$MATCH_5" -x
rsync manipulation
------------------
IMPLEMENTS ASSUMING rsync is possible
test "x$GTT_PROTO" = "xssh"
IMPLEMENTS WHEN ([a-z][a-z0-9]*) ([a-z][a-z0-9]*) rsync'?s (.*) to (.*)
rsync -I --rsh="$GTT rsh \"$MATCH_1\" \"$MATCH_2\"" "$DATADIR/$MATCH_3" "dummy:$MATCH_4/$MATCH_3"
IMPLEMENTS WHEN ([a-z][a-z0-9]*) ([a-z][a-z0-9]*) rsync'?s (.*) from (.*)
rsync -I --rsh="$GTT rsh \"$MATCH_1\" \"$MATCH_2\"" "dummy:$MATCH_4/$MATCH_3" "$DATADIR/$MATCH_3"
Admin repo manipulation
-----------------------
IMPLEMENTS WHEN ([a-z][a-z0-9]*),? using ([a-z][a-z0-9]*),? adds user ([a-z][a-z0-9]*),? using ([a-z][a-z0-9]*) ([a-z][a-z0-9]*)
$GTT runcommand "$MATCH_1" "$MATCH_2" \
user add "$MATCH_3" "$MATCH_3"@testinstance "$MATCH_3's real name" > "$DATADIR/stdout" 2> "$DATADIR/stderr"
$GTT runcommand "$MATCH_1" "$MATCH_2" \
as "$MATCH_3" sshkey add default < \
"$($GTT pubkeyfilename "$MATCH_4" "$MATCH_5")" >> "$DATADIR/stdout" 2>> "$DATADIR/stderr"
if [ "$GTT_PROTO" = http ]; then
printf "%s" "$MATCH_3" | GTT_PROTO=ssh $GTT runcommand \
"$MATCH_1" "$MATCH_2" as "$MATCH_3" passwd \
>> "$DATADIR/stdout" 2>> "$DATADIR/stderr"
fi
IMPLEMENTS WHEN ([a-z][a-z0-9]*),? using ([a-z][a-z0-9]*),? deletes user ([a-z][a-z0-9]*)
TOKEN="$($GTT runcommand "$MATCH_1" "$MATCH_2" user del "$MATCH_3" 2>&1 | $GTT findtoken)"
$GTT runcommand "$MATCH_1" "$MATCH_2" user del "$MATCH_3" $TOKEN
IMPLEMENTS GIVEN ([a-z][a-z0-9]*),? using ([a-z][a-z0-9]*),? has patched gitano-admin with (the reverse of )?([^ ]+)
$GTT clone "$MATCH_1" "$MATCH_2" gitano-admin.git tmp-adminpatch \
>"$DATADIR/stdout" 2>"$DATADIR/stderr"
if test "$MATCH_3" = ""; then
$GTT rungit "$MATCH_1" tmp-adminpatch apply -v --cached - <"testing/admin-patches/$MATCH_4" \
>>"$DATADIR/stdout" 2>>"$DATADIR/stderr"
else
$GTT rungit "$MATCH_1" tmp-adminpatch apply -v --cached --reverse - <"testing/admin-patches/$MATCH_4" \
>>"$DATADIR/stdout" 2>>"$DATADIR/stderr"
fi
$GTT rungit "$MATCH_1" tmp-adminpatch diff --cached \
>>"$DATADIR/stdout" 2>>"$DATADIR/stderr"
$GTT rungit "$MATCH_1" tmp-adminpatch commit --allow-empty -m "Apply $MATCH_4 rules change" \
>>"$DATADIR/stdout" 2>>"$DATADIR/stderr"
$GTT rungit "$MATCH_1" tmp-adminpatch show HEAD \
>>"$DATADIR/stdout" 2>>"$DATADIR/stderr"
$GTT push "$MATCH_1" "$MATCH_2" tmp-adminpatch gitano-admin.git \
>>"$DATADIR/stdout" 2>>"$DATADIR/stderr"
rm -r "$($GTT clonelocation "$MATCH_1" tmp-adminpatch)" \
>>"$DATADIR/stdout" 2>>"$DATADIR/stderr"
IMPLEMENTS WHEN ([a-z][a-z0-9]*),? using ([a-z][a-z0-9]*),? (expecting failure,? )?pushes an empty commit in ([^ ]+)
$GTT rungit "$MATCH_1" "$MATCH_4" commit --allow-empty -m "Make an empty commit"
if $GTT push "$MATCH_1" "$MATCH_2" "$MATCH_4" "$MATCH_4".git > "$DATADIR/stdout" 2>"$DATADIR/stderr"; then
test "$MATCH_3" = ""
fi
IMPLEMENTS WHEN ([a-z][a-z0-9]*) (applies|reverts) ([^ ]+) in ([^ ]+)
if test "$MATCH_2" = "applies"; then
$GTT rungit "$MATCH_1" "$MATCH_4" apply --cached - <"testing/content-patches/$MATCH_3" \
>"$DATADIR/stdout" 2>"$DATADIR/stderr"
else
$GTT rungit "$MATCH_1" "$MATCH_4" apply --cached --reverse - <"testing/content-patches/$MATCH_3" \
>"$DATADIR/stdout" 2>"$DATADIR/stderr"
fi
$GTT rungit "$MATCH_1" "$MATCH_4" commit --allow-empty -m "Apply $MATCH_3 content change" \
>>"$DATADIR/stdout" 2>>"$DATADIR/stderr"
Specific commands
-----------------
IMPLEMENTS GIVEN ([a-z][a-z0-9]*) ([a-z][a-z0-9]*) has copied ([^ ]+) to ([^ ]+)
$GTT runcommand "$MATCH_1" "$MATCH_2" copy "$MATCH_3" "$MATCH_4"
IMPLEMENTS GIVEN ([a-z][a-z0-9]*) ([a-z][a-z0-9]*) has set the owner of ([^ ]+) to ([a-z][a-z0-9]*)
$GTT runcommand "$MATCH_1" "$MATCH_2" config "$MATCH_3" set project.owner "$MATCH_4"
IMPLEMENTS WHEN ([a-z][a-z0-9]*) ([a-z][a-z0-9]*) restores the latest deletion to (.+)
$GTT runcommand "$MATCH_1" "$MATCH_2" graveyard list >"$DATADIR/stdout" 2>"$DATADIR/stderr"
reponame="$(head -n1 "$DATADIR/stdout" | cut -d' ' -f2)"
$GTT runcommand "$MATCH_1" "$MATCH_2" graveyard restore "$reponame" "$MATCH_3"
IMPLEMENTS WHEN ([a-z][a-z0-9]*) ([a-z][a-z0-9]*) purges the latest deletion
$GTT runcommand "$MATCH_1" "$MATCH_2" graveyard list >"$DATADIR/stdout" 2>"$DATADIR/stderr"
reponame="$(head -n1 "$DATADIR/stderr" | cut -d' ' -f2)"
$GTT runcommand "$MATCH_1" "$MATCH_2" graveyard purge "$reponame"
Generic utility methods
-----------------------
IMPLEMENTS WHEN ([a-z][a-z0-9]*) ([a-z][a-z0-9]*) runs ?(.*)
if ! test -e "$DATADIR/stdin"; then touch "$DATADIR/stdin"; fi
$GTT runcommand "$MATCH_1" "$MATCH_2" $MATCH_3 < "$DATADIR/stdin" > "$DATADIR/stdout" 2> "$DATADIR/stderr"
rm -f "$DATADIR/stdin"
IMPLEMENTS WHEN ([a-z][a-z0-9]*) ([a-z][a-z0-9]*),? expecting failure,? runs ?(.*)
if ! test -e "$DATADIR/stdin"; then touch "$DATADIR/stdin"; fi
if $GTT runcommand "$MATCH_1" "$MATCH_2" $MATCH_3 > "$DATADIR/stdout" 2> "$DATADIR/stderr"; then
false
fi
rm -f "$DATADIR/stdin"
IMPLEMENTS GIVEN ([^ ]+) contains (.+)
printf %s "$MATCH_2" >"$DATADIR/$MATCH_1"
IMPLEMENTS THEN ([^ ]+) contains (.+)
grep -q "$MATCH_2" "$DATADIR/$MATCH_1"
IMPLEMENTS THEN the output contains (.+)
grep -q "$MATCH_1" "$DATADIR/stdout" "$DATADIR/stderr"
IMPLEMENTS THEN ([^ ]+) does not contain (.+)
if grep -q "$MATCH_2" "$DATADIR/$MATCH_1"; then false; else true; fi
IMPLEMENTS THEN the output does not contain (.+)
if grep -q "$MATCH_1" "$DATADIR/stdout" "$DATADIR/stderr"; then false; else true; fi
IMPLEMENTS THEN ([^ ]+) is empty
if grep -q . "$DATADIR/$MATCH_1"; then false; fi
IMPLEMENTS THEN ([^ ]+) is not empty
grep -q . "$DATADIR/$MATCH_1"
IMPLEMENTS THEN the output is empty
if grep -q . "$DATADIR/stdout" "$DATADIR/stderr"; then false; else true; fi
IMPLEMENTS THEN the output is not empty
grep -q . "$DATADIR/stdout" "$DATADIR/stderr"
IMPLEMENTS GIVEN the token is saved as (.+)
mkdir -p "$DATADIR/saved-tokens"
cat "$DATADIR/stdout" "$DATADIR/stderr" | $GTT findtoken >"$DATADIR/saved-tokens/$MATCH_1"
IMPLEMENTS THEN failure ensues
cd "$DATADIR"
echo "FIND:"
find .
echo "KEYS:"
cat user-home-testinstance/.ssh/authorized_keys
echo "OUT":
if test -r stdout; then cat stdout; fi
echo "ERR":
if test -r stderr; then cat stderr; fi
echo "LASTPROG:"
cat last-program
/bin/false
IMPLEMENTS ASSUMING gitano is being accessed over ([^ ]+)
test "$GTT_PROTO" = "$MATCH_1"
GPG Keyring related helpers
---------------------------
Since the test suite runs with a `GNUPG_HOME` set up for us which the test tool
can access, these implementations use that `GNUPG_HOME` rather than one inside
`DATADIR`.
IMPLEMENTS GIVEN gpg key ([0-9A-Fa-f]+) on stdin
$GTT gpg --armor --export "$MATCH_1" > "$DATADIR/stdin"
|