##// END OF EJS Templates
test: add a push race case where raced push created a new named branch...
marmoute -
r32633:b01bfa5a default
parent child Browse files
Show More
@@ -1,386 +1,503 b''
1 1 ============================================================================================
2 2 Test cases where there are race condition between two clients pushing to the same repository
3 3 ============================================================================================
4 4
5 5 This file tests cases where two clients push to a server at the same time. The
6 6 "raced" client is done preparing it push bundle when the "racing" client
7 7 perform its push. The "raced" client starts its actual push after the "racing"
8 8 client push is fully complete.
9 9
10 10 A set of extension and shell functions ensures this scheduling.
11 11
12 12 $ cat >> delaypush.py << EOF
13 13 > """small extension orchestrate push race
14 14 >
15 15 > Client with the extensions will create a file when ready and get stuck until
16 16 > a file is created."""
17 17 >
18 18 > import atexit
19 19 > import errno
20 20 > import os
21 21 > import time
22 22 >
23 23 > from mercurial import (
24 24 > exchange,
25 25 > extensions,
26 26 > )
27 27 >
28 28 > def delaypush(orig, pushop):
29 29 > # notify we are done preparing
30 30 > readypath = pushop.repo.ui.config('delaypush', 'ready-path', None)
31 31 > if readypath is not None:
32 32 > with open(readypath, 'w') as r:
33 33 > r.write('foo')
34 34 > pushop.repo.ui.status('wrote ready: %s\n' % readypath)
35 35 > # now wait for the other process to be done
36 36 > watchpath = pushop.repo.ui.config('delaypush', 'release-path', None)
37 37 > if watchpath is not None:
38 38 > pushop.repo.ui.status('waiting on: %s\n' % watchpath)
39 39 > limit = 100
40 40 > while 0 < limit and not os.path.exists(watchpath):
41 41 > limit -= 1
42 42 > time.sleep(0.1)
43 43 > if limit <= 0:
44 44 > repo.ui.warn('exiting without watchfile: %s' % watchpath)
45 45 > else:
46 46 > # delete the file at the end of the push
47 47 > def delete():
48 48 > try:
49 49 > os.unlink(watchpath)
50 50 > except OSError as exc:
51 51 > if exc.errno != errno.ENOENT:
52 52 > raise
53 53 > atexit.register(delete)
54 54 > return orig(pushop)
55 55 >
56 56 > def uisetup(ui):
57 57 > extensions.wrapfunction(exchange, '_pushbundle2', delaypush)
58 58 > EOF
59 59
60 60 $ waiton () {
61 61 > # wait for a file to be created (then delete it)
62 62 > count=100
63 63 > while [ ! -f $1 ] ;
64 64 > do
65 65 > sleep 0.1;
66 66 > count=`expr $count - 1`;
67 67 > if [ $count -lt 0 ];
68 68 > then
69 69 > break
70 70 > fi;
71 71 > done
72 72 > [ -f $1 ] || echo "ready file still missing: $1"
73 73 > rm -f $1
74 74 > }
75 75
76 76 $ release () {
77 77 > # create a file and wait for it be deleted
78 78 > count=100
79 79 > touch $1
80 80 > while [ -f $1 ] ;
81 81 > do
82 82 > sleep 0.1;
83 83 > count=`expr $count - 1`;
84 84 > if [ $count -lt 0 ];
85 85 > then
86 86 > break
87 87 > fi;
88 88 > done
89 89 > [ ! -f $1 ] || echo "delay file still exist: $1"
90 90 > }
91 91
92 92 $ cat >> $HGRCPATH << EOF
93 93 > [ui]
94 94 > ssh = python "$TESTDIR/dummyssh"
95 95 > # simplify output
96 96 > logtemplate = {node|short} {desc} ({branch})
97 97 > [alias]
98 98 > graph = log -G --rev 'sort(all(), "topo")'
99 99 > EOF
100 100
101 101 Setup
102 102 -----
103 103
104 104 create a repo with one root
105 105
106 106 $ hg init server
107 107 $ cd server
108 108 $ echo root > root
109 109 $ hg ci -Am "C-ROOT"
110 110 adding root
111 111 $ cd ..
112 112
113 113 clone it in two clients
114 114
115 115 $ hg clone ssh://user@dummy/server client-racy
116 116 requesting all changes
117 117 adding changesets
118 118 adding manifests
119 119 adding file changes
120 120 added 1 changesets with 1 changes to 1 files
121 121 updating to branch default
122 122 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
123 123 $ hg clone ssh://user@dummy/server client-other
124 124 requesting all changes
125 125 adding changesets
126 126 adding manifests
127 127 adding file changes
128 128 added 1 changesets with 1 changes to 1 files
129 129 updating to branch default
130 130 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
131 131
132 132 setup one to allow race on push
133 133
134 134 $ cat >> client-racy/.hg/hgrc << EOF
135 135 > [extensions]
136 136 > delaypush = $TESTTMP/delaypush.py
137 137 > [delaypush]
138 138 > ready-path = $TESTTMP/readyfile
139 139 > release-path = $TESTTMP/watchfile
140 140 > EOF
141 141
142 142 Simple race, both try to push to the server at the same time
143 143 ------------------------------------------------------------
144 144
145 145 Both try to replace the same head
146 146
147 147 # a
148 148 # | b
149 149 # |/
150 150 # *
151 151
152 152 Creating changesets
153 153
154 154 $ echo b > client-other/a
155 155 $ hg -R client-other/ add client-other/a
156 156 $ hg -R client-other/ commit -m "C-A"
157 157 $ echo b > client-racy/b
158 158 $ hg -R client-racy/ add client-racy/b
159 159 $ hg -R client-racy/ commit -m "C-B"
160 160
161 161 Pushing
162 162
163 163 $ hg -R client-racy push -r 'tip' > ./push-log 2>&1 &
164 164
165 165 $ waiton $TESTTMP/readyfile
166 166
167 167 $ hg -R client-other push -r 'tip'
168 168 pushing to ssh://user@dummy/server
169 169 searching for changes
170 170 remote: adding changesets
171 171 remote: adding manifests
172 172 remote: adding file changes
173 173 remote: added 1 changesets with 1 changes to 1 files
174 174
175 175 $ release $TESTTMP/watchfile
176 176
177 177 Check the result of the push
178 178
179 179 $ cat ./push-log
180 180 pushing to ssh://user@dummy/server
181 181 searching for changes
182 182 wrote ready: $TESTTMP/readyfile
183 183 waiting on: $TESTTMP/watchfile
184 184 abort: push failed:
185 185 'repository changed while pushing - please try again'
186 186
187 187 $ hg -R server graph
188 188 o 98217d5a1659 C-A (default)
189 189 |
190 190 @ 842e2fac6304 C-ROOT (default)
191 191
192 192
193 193 Pushing on two different heads
194 194 ------------------------------
195 195
196 196 Both try to replace a different head
197 197
198 198 # a b
199 199 # | |
200 200 # * *
201 201 # |/
202 202 # *
203 203
204 204 (resync-all)
205 205
206 206 $ hg -R ./server pull ./client-racy
207 207 pulling from ./client-racy
208 208 searching for changes
209 209 adding changesets
210 210 adding manifests
211 211 adding file changes
212 212 added 1 changesets with 1 changes to 1 files (+1 heads)
213 213 (run 'hg heads' to see heads, 'hg merge' to merge)
214 214 $ hg -R ./client-other pull
215 215 pulling from ssh://user@dummy/server
216 216 searching for changes
217 217 adding changesets
218 218 adding manifests
219 219 adding file changes
220 220 added 1 changesets with 1 changes to 1 files (+1 heads)
221 221 (run 'hg heads' to see heads, 'hg merge' to merge)
222 222 $ hg -R ./client-racy pull
223 223 pulling from ssh://user@dummy/server
224 224 searching for changes
225 225 adding changesets
226 226 adding manifests
227 227 adding file changes
228 228 added 1 changesets with 1 changes to 1 files (+1 heads)
229 229 (run 'hg heads' to see heads, 'hg merge' to merge)
230 230
231 231 $ hg -R server graph
232 232 o a9149a1428e2 C-B (default)
233 233 |
234 234 | o 98217d5a1659 C-A (default)
235 235 |/
236 236 @ 842e2fac6304 C-ROOT (default)
237 237
238 238
239 239 Creating changesets
240 240
241 241 $ echo aa >> client-other/a
242 242 $ hg -R client-other/ commit -m "C-C"
243 243 $ echo bb >> client-racy/b
244 244 $ hg -R client-racy/ commit -m "C-D"
245 245
246 246 Pushing
247 247
248 248 $ hg -R client-racy push -r 'tip' > ./push-log 2>&1 &
249 249
250 250 $ waiton $TESTTMP/readyfile
251 251
252 252 $ hg -R client-other push -r 'tip'
253 253 pushing to ssh://user@dummy/server
254 254 searching for changes
255 255 remote: adding changesets
256 256 remote: adding manifests
257 257 remote: adding file changes
258 258 remote: added 1 changesets with 1 changes to 1 files
259 259
260 260 $ release $TESTTMP/watchfile
261 261
262 262 Check the result of the push
263 263
264 264 $ cat ./push-log
265 265 pushing to ssh://user@dummy/server
266 266 searching for changes
267 267 wrote ready: $TESTTMP/readyfile
268 268 waiting on: $TESTTMP/watchfile
269 269 abort: push failed:
270 270 'repository changed while pushing - please try again'
271 271
272 272 $ hg -R server graph
273 273 o 51c544a58128 C-C (default)
274 274 |
275 275 o 98217d5a1659 C-A (default)
276 276 |
277 277 | o a9149a1428e2 C-B (default)
278 278 |/
279 279 @ 842e2fac6304 C-ROOT (default)
280 280
281 281 Pushing while someone creates a new head
282 282 -----------------------------------------
283 283
284 284 Pushing a new changeset while someone creates a new branch.
285 285
286 286 # a (raced)
287 287 # |
288 288 # * b
289 289 # |/
290 290 # *
291 291
292 292 (resync-all)
293 293
294 294 $ hg -R ./server pull ./client-racy
295 295 pulling from ./client-racy
296 296 searching for changes
297 297 adding changesets
298 298 adding manifests
299 299 adding file changes
300 300 added 1 changesets with 1 changes to 1 files
301 301 (run 'hg update' to get a working copy)
302 302 $ hg -R ./client-other pull
303 303 pulling from ssh://user@dummy/server
304 304 searching for changes
305 305 adding changesets
306 306 adding manifests
307 307 adding file changes
308 308 added 1 changesets with 1 changes to 1 files
309 309 (run 'hg update' to get a working copy)
310 310 $ hg -R ./client-racy pull
311 311 pulling from ssh://user@dummy/server
312 312 searching for changes
313 313 adding changesets
314 314 adding manifests
315 315 adding file changes
316 316 added 1 changesets with 1 changes to 1 files
317 317 (run 'hg update' to get a working copy)
318 318
319 319 $ hg -R server graph
320 320 o 59e76faf78bd C-D (default)
321 321 |
322 322 o a9149a1428e2 C-B (default)
323 323 |
324 324 | o 51c544a58128 C-C (default)
325 325 | |
326 326 | o 98217d5a1659 C-A (default)
327 327 |/
328 328 @ 842e2fac6304 C-ROOT (default)
329 329
330 330
331 331 Creating changesets
332 332
333 333 (new head)
334 334
335 335 $ hg -R client-other/ up 'desc("C-A")'
336 336 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
337 337 $ echo aaa >> client-other/a
338 338 $ hg -R client-other/ commit -m "C-E"
339 339 created new head
340 340
341 341 (children of existing head)
342 342
343 343 $ hg -R client-racy/ up 'desc("C-C")'
344 344 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
345 345 $ echo bbb >> client-racy/a
346 346 $ hg -R client-racy/ commit -m "C-F"
347 347
348 348 Pushing
349 349
350 350 $ hg -R client-racy push -r 'tip' > ./push-log 2>&1 &
351 351
352 352 $ waiton $TESTTMP/readyfile
353 353
354 354 $ hg -R client-other push -fr 'tip'
355 355 pushing to ssh://user@dummy/server
356 356 searching for changes
357 357 remote: adding changesets
358 358 remote: adding manifests
359 359 remote: adding file changes
360 360 remote: added 1 changesets with 1 changes to 1 files (+1 heads)
361 361
362 362 $ release $TESTTMP/watchfile
363 363
364 364 Check the result of the push
365 365
366 366 $ cat ./push-log
367 367 pushing to ssh://user@dummy/server
368 368 searching for changes
369 369 wrote ready: $TESTTMP/readyfile
370 370 waiting on: $TESTTMP/watchfile
371 371 abort: push failed:
372 372 'repository changed while pushing - please try again'
373 373
374 374 $ hg -R server graph
375 375 o d603e2c0cdd7 C-E (default)
376 376 |
377 377 | o 51c544a58128 C-C (default)
378 378 |/
379 379 o 98217d5a1659 C-A (default)
380 380 |
381 381 | o 59e76faf78bd C-D (default)
382 382 | |
383 383 | o a9149a1428e2 C-B (default)
384 384 |/
385 385 @ 842e2fac6304 C-ROOT (default)
386 386
387
388 Pushing touching different named branch (same topo): new branch raced
389 ---------------------------------------------------------------------
390
391 Pushing two children on the same head, one is a different named branch
392
393 # a (raced, branch-a)
394 # |
395 # | b (default branch)
396 # |/
397 # *
398
399 (resync-all)
400
401 $ hg -R ./server pull ./client-racy
402 pulling from ./client-racy
403 searching for changes
404 adding changesets
405 adding manifests
406 adding file changes
407 added 1 changesets with 1 changes to 1 files
408 (run 'hg update' to get a working copy)
409 $ hg -R ./client-other pull
410 pulling from ssh://user@dummy/server
411 searching for changes
412 adding changesets
413 adding manifests
414 adding file changes
415 added 1 changesets with 1 changes to 1 files
416 (run 'hg update' to get a working copy)
417 $ hg -R ./client-racy pull
418 pulling from ssh://user@dummy/server
419 searching for changes
420 adding changesets
421 adding manifests
422 adding file changes
423 added 1 changesets with 1 changes to 1 files (+1 heads)
424 (run 'hg heads .' to see heads, 'hg merge' to merge)
425
426 $ hg -R server graph
427 o d9e379a8c432 C-F (default)
428 |
429 o 51c544a58128 C-C (default)
430 |
431 | o d603e2c0cdd7 C-E (default)
432 |/
433 o 98217d5a1659 C-A (default)
434 |
435 | o 59e76faf78bd C-D (default)
436 | |
437 | o a9149a1428e2 C-B (default)
438 |/
439 @ 842e2fac6304 C-ROOT (default)
440
441
442 Creating changesets
443
444 (update existing head)
445
446 $ hg -R client-other/ up 'desc("C-F")'
447 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
448 $ echo aaa >> client-other/a
449 $ hg -R client-other/ commit -m "C-G"
450
451 (new named branch from that existing head)
452
453 $ hg -R client-racy/ up 'desc("C-F")'
454 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
455 $ echo bbb >> client-racy/a
456 $ hg -R client-racy/ branch my-first-test-branch
457 marked working directory as branch my-first-test-branch
458 (branches are permanent and global, did you want a bookmark?)
459 $ hg -R client-racy/ commit -m "C-H"
460
461 Pushing
462
463 $ hg -R client-racy push -r 'tip' --new-branch > ./push-log 2>&1 &
464
465 $ waiton $TESTTMP/readyfile
466
467 $ hg -R client-other push -fr 'tip'
468 pushing to ssh://user@dummy/server
469 searching for changes
470 remote: adding changesets
471 remote: adding manifests
472 remote: adding file changes
473 remote: added 1 changesets with 1 changes to 1 files
474
475 $ release $TESTTMP/watchfile
476
477 Check the result of the push
478
479 $ cat ./push-log
480 pushing to ssh://user@dummy/server
481 searching for changes
482 wrote ready: $TESTTMP/readyfile
483 waiting on: $TESTTMP/watchfile
484 abort: push failed:
485 'repository changed while pushing - please try again'
486
487 $ hg -R server graph
488 o 75d69cba5402 C-G (default)
489 |
490 o d9e379a8c432 C-F (default)
491 |
492 o 51c544a58128 C-C (default)
493 |
494 | o d603e2c0cdd7 C-E (default)
495 |/
496 o 98217d5a1659 C-A (default)
497 |
498 | o 59e76faf78bd C-D (default)
499 | |
500 | o a9149a1428e2 C-B (default)
501 |/
502 @ 842e2fac6304 C-ROOT (default)
503
General Comments 0
You need to be logged in to leave comments. Login now