##// END OF EJS Templates
tests: stabilize test-commandserver.t on Windows...
Matt Harbison -
r40689:6d0fdeda default
parent child Browse files
Show More
@@ -1,1096 +1,1096 b''
1 1 #if windows
2 2 $ PYTHONPATH="$TESTDIR/../contrib;$PYTHONPATH"
3 3 #else
4 4 $ PYTHONPATH="$TESTDIR/../contrib:$PYTHONPATH"
5 5 #endif
6 6 $ export PYTHONPATH
7 7
8 8 typical client does not want echo-back messages, so test without it:
9 9
10 10 $ grep -v '^promptecho ' < $HGRCPATH >> $HGRCPATH.new
11 11 $ mv $HGRCPATH.new $HGRCPATH
12 12
13 13 $ hg init repo
14 14 $ cd repo
15 15
16 16 >>> from __future__ import absolute_import
17 17 >>> import os
18 18 >>> import sys
19 19 >>> from hgclient import bprint, check, readchannel, runcommand
20 20 >>> @check
21 21 ... def hellomessage(server):
22 22 ... ch, data = readchannel(server)
23 23 ... bprint(b'%c, %r' % (ch, data))
24 24 ... # run an arbitrary command to make sure the next thing the server
25 25 ... # sends isn't part of the hello message
26 26 ... runcommand(server, [b'id'])
27 27 o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob)
28 28 *** runcommand id
29 29 000000000000 tip
30 30
31 31 >>> from hgclient import check
32 32 >>> @check
33 33 ... def unknowncommand(server):
34 34 ... server.stdin.write(b'unknowncommand\n')
35 35 abort: unknown command unknowncommand
36 36
37 37 >>> from hgclient import check, readchannel, runcommand
38 38 >>> @check
39 39 ... def checkruncommand(server):
40 40 ... # hello block
41 41 ... readchannel(server)
42 42 ...
43 43 ... # no args
44 44 ... runcommand(server, [])
45 45 ...
46 46 ... # global options
47 47 ... runcommand(server, [b'id', b'--quiet'])
48 48 ...
49 49 ... # make sure global options don't stick through requests
50 50 ... runcommand(server, [b'id'])
51 51 ...
52 52 ... # --config
53 53 ... runcommand(server, [b'id', b'--config', b'ui.quiet=True'])
54 54 ...
55 55 ... # make sure --config doesn't stick
56 56 ... runcommand(server, [b'id'])
57 57 ...
58 58 ... # negative return code should be masked
59 59 ... runcommand(server, [b'id', b'-runknown'])
60 60 *** runcommand
61 61 Mercurial Distributed SCM
62 62
63 63 basic commands:
64 64
65 65 add add the specified files on the next commit
66 66 annotate show changeset information by line for each file
67 67 clone make a copy of an existing repository
68 68 commit commit the specified files or all outstanding changes
69 69 diff diff repository (or selected files)
70 70 export dump the header and diffs for one or more changesets
71 71 forget forget the specified files on the next commit
72 72 init create a new repository in the given directory
73 73 log show revision history of entire repository or files
74 74 merge merge another revision into working directory
75 75 pull pull changes from the specified source
76 76 push push changes to the specified destination
77 77 remove remove the specified files on the next commit
78 78 serve start stand-alone webserver
79 79 status show changed files in the working directory
80 80 summary summarize working directory state
81 81 update update working directory (or switch revisions)
82 82
83 83 (use 'hg help' for the full list of commands or 'hg -v' for details)
84 84 *** runcommand id --quiet
85 85 000000000000
86 86 *** runcommand id
87 87 000000000000 tip
88 88 *** runcommand id --config ui.quiet=True
89 89 000000000000
90 90 *** runcommand id
91 91 000000000000 tip
92 92 *** runcommand id -runknown
93 93 abort: unknown revision 'unknown'!
94 94 [255]
95 95
96 96 >>> from hgclient import bprint, check, readchannel
97 97 >>> @check
98 98 ... def inputeof(server):
99 99 ... readchannel(server)
100 100 ... server.stdin.write(b'runcommand\n')
101 101 ... # close stdin while server is waiting for input
102 102 ... server.stdin.close()
103 103 ...
104 104 ... # server exits with 1 if the pipe closed while reading the command
105 105 ... bprint(b'server exit code =', b'%d' % server.wait())
106 106 server exit code = 1
107 107
108 108 >>> from hgclient import check, readchannel, runcommand, stringio
109 109 >>> @check
110 110 ... def serverinput(server):
111 111 ... readchannel(server)
112 112 ...
113 113 ... patch = b"""
114 114 ... # HG changeset patch
115 115 ... # User test
116 116 ... # Date 0 0
117 117 ... # Node ID c103a3dec114d882c98382d684d8af798d09d857
118 118 ... # Parent 0000000000000000000000000000000000000000
119 119 ... 1
120 120 ...
121 121 ... diff -r 000000000000 -r c103a3dec114 a
122 122 ... --- /dev/null Thu Jan 01 00:00:00 1970 +0000
123 123 ... +++ b/a Thu Jan 01 00:00:00 1970 +0000
124 124 ... @@ -0,0 +1,1 @@
125 125 ... +1
126 126 ... """
127 127 ...
128 128 ... runcommand(server, [b'import', b'-'], input=stringio(patch))
129 129 ... runcommand(server, [b'log'])
130 130 *** runcommand import -
131 131 applying patch from stdin
132 132 *** runcommand log
133 133 changeset: 0:eff892de26ec
134 134 tag: tip
135 135 user: test
136 136 date: Thu Jan 01 00:00:00 1970 +0000
137 137 summary: 1
138 138
139 139
140 140 check strict parsing of early options:
141 141
142 142 >>> import os
143 143 >>> from hgclient import check, readchannel, runcommand
144 144 >>> os.environ['HGPLAIN'] = '+strictflags'
145 145 >>> @check
146 146 ... def cwd(server):
147 147 ... readchannel(server)
148 148 ... runcommand(server, [b'log', b'-b', b'--config=alias.log=!echo pwned',
149 149 ... b'default'])
150 150 *** runcommand log -b --config=alias.log=!echo pwned default
151 151 abort: unknown revision '--config=alias.log=!echo pwned'!
152 152 [255]
153 153
154 154 check that "histedit --commands=-" can read rules from the input channel:
155 155
156 156 >>> from hgclient import check, readchannel, runcommand, stringio
157 157 >>> @check
158 158 ... def serverinput(server):
159 159 ... readchannel(server)
160 160 ... rules = b'pick eff892de26ec\n'
161 161 ... runcommand(server, [b'histedit', b'0', b'--commands=-',
162 162 ... b'--config', b'extensions.histedit='],
163 163 ... input=stringio(rules))
164 164 *** runcommand histedit 0 --commands=- --config extensions.histedit=
165 165
166 166 check that --cwd doesn't persist between requests:
167 167
168 168 $ mkdir foo
169 169 $ touch foo/bar
170 170 >>> from hgclient import check, readchannel, runcommand
171 171 >>> @check
172 172 ... def cwd(server):
173 173 ... readchannel(server)
174 174 ... runcommand(server, [b'--cwd', b'foo', b'st', b'bar'])
175 175 ... runcommand(server, [b'st', b'foo/bar'])
176 176 *** runcommand --cwd foo st bar
177 177 ? bar
178 178 *** runcommand st foo/bar
179 179 ? foo/bar
180 180
181 181 $ rm foo/bar
182 182
183 183
184 184 check that local configs for the cached repo aren't inherited when -R is used:
185 185
186 186 $ cat <<EOF >> .hg/hgrc
187 187 > [ui]
188 188 > foo = bar
189 189 > EOF
190 190
191 191 #if no-extraextensions
192 192
193 193 >>> from hgclient import check, readchannel, runcommand, sep
194 194 >>> @check
195 195 ... def localhgrc(server):
196 196 ... readchannel(server)
197 197 ...
198 198 ... # the cached repo local hgrc contains ui.foo=bar, so showconfig should
199 199 ... # show it
200 200 ... runcommand(server, [b'showconfig'], outfilter=sep)
201 201 ...
202 202 ... # but not for this repo
203 203 ... runcommand(server, [b'init', b'foo'])
204 204 ... runcommand(server, [b'-R', b'foo', b'showconfig', b'ui', b'defaults'])
205 205 *** runcommand showconfig
206 206 bundle.mainreporoot=$TESTTMP/repo
207 207 devel.all-warnings=true
208 208 devel.default-date=0 0
209 209 extensions.fsmonitor= (fsmonitor !)
210 210 largefiles.usercache=$TESTTMP/.cache/largefiles
211 211 lfs.usercache=$TESTTMP/.cache/lfs
212 212 ui.slash=True
213 213 ui.interactive=False
214 214 ui.merge=internal:merge
215 215 ui.mergemarkers=detailed
216 216 ui.foo=bar
217 217 ui.nontty=true
218 218 web.address=localhost
219 219 web\.ipv6=(?:True|False) (re)
220 220 web.server-header=testing stub value
221 221 *** runcommand init foo
222 222 *** runcommand -R foo showconfig ui defaults
223 223 ui.slash=True
224 224 ui.interactive=False
225 225 ui.merge=internal:merge
226 226 ui.mergemarkers=detailed
227 227 ui.nontty=true
228 228 #endif
229 229
230 230 $ rm -R foo
231 231
232 232 #if windows
233 233 $ PYTHONPATH="$TESTTMP/repo;$PYTHONPATH"
234 234 #else
235 235 $ PYTHONPATH="$TESTTMP/repo:$PYTHONPATH"
236 236 #endif
237 237
238 238 $ cat <<EOF > hook.py
239 239 > import sys
240 240 > from hgclient import bprint
241 241 > def hook(**args):
242 242 > bprint(b'hook talking')
243 243 > bprint(b'now try to read something: %r' % sys.stdin.read())
244 244 > EOF
245 245
246 246 >>> from hgclient import check, readchannel, runcommand, stringio
247 247 >>> @check
248 248 ... def hookoutput(server):
249 249 ... readchannel(server)
250 250 ... runcommand(server, [b'--config',
251 251 ... b'hooks.pre-identify=python:hook.hook',
252 252 ... b'id'],
253 253 ... input=stringio(b'some input'))
254 254 *** runcommand --config hooks.pre-identify=python:hook.hook id
255 255 eff892de26ec tip
256 256 hook talking
257 257 now try to read something: ''
258 258
259 259 Clean hook cached version
260 260 $ rm hook.py*
261 261 $ rm -Rf __pycache__
262 262
263 263 $ echo a >> a
264 264 >>> import os
265 265 >>> from hgclient import check, readchannel, runcommand
266 266 >>> @check
267 267 ... def outsidechanges(server):
268 268 ... readchannel(server)
269 269 ... runcommand(server, [b'status'])
270 270 ... os.system('hg ci -Am2')
271 271 ... runcommand(server, [b'tip'])
272 272 ... runcommand(server, [b'status'])
273 273 *** runcommand status
274 274 M a
275 275 *** runcommand tip
276 276 changeset: 1:d3a0a68be6de
277 277 tag: tip
278 278 user: test
279 279 date: Thu Jan 01 00:00:00 1970 +0000
280 280 summary: 2
281 281
282 282 *** runcommand status
283 283
284 284 >>> import os
285 285 >>> from hgclient import bprint, check, readchannel, runcommand
286 286 >>> @check
287 287 ... def bookmarks(server):
288 288 ... readchannel(server)
289 289 ... runcommand(server, [b'bookmarks'])
290 290 ...
291 291 ... # changes .hg/bookmarks
292 292 ... os.system('hg bookmark -i bm1')
293 293 ... os.system('hg bookmark -i bm2')
294 294 ... runcommand(server, [b'bookmarks'])
295 295 ...
296 296 ... # changes .hg/bookmarks.current
297 297 ... os.system('hg upd bm1 -q')
298 298 ... runcommand(server, [b'bookmarks'])
299 299 ...
300 300 ... runcommand(server, [b'bookmarks', b'bm3'])
301 301 ... f = open('a', 'ab')
302 302 ... f.write(b'a\n') and None
303 303 ... f.close()
304 304 ... runcommand(server, [b'commit', b'-Amm'])
305 305 ... runcommand(server, [b'bookmarks'])
306 306 ... bprint(b'')
307 307 *** runcommand bookmarks
308 308 no bookmarks set
309 309 *** runcommand bookmarks
310 310 bm1 1:d3a0a68be6de
311 311 bm2 1:d3a0a68be6de
312 312 *** runcommand bookmarks
313 313 * bm1 1:d3a0a68be6de
314 314 bm2 1:d3a0a68be6de
315 315 *** runcommand bookmarks bm3
316 316 *** runcommand commit -Amm
317 317 *** runcommand bookmarks
318 318 bm1 1:d3a0a68be6de
319 319 bm2 1:d3a0a68be6de
320 320 * bm3 2:aef17e88f5f0
321 321
322 322
323 323 >>> import os
324 324 >>> from hgclient import check, readchannel, runcommand
325 325 >>> @check
326 326 ... def tagscache(server):
327 327 ... readchannel(server)
328 328 ... runcommand(server, [b'id', b'-t', b'-r', b'0'])
329 329 ... os.system('hg tag -r 0 foo')
330 330 ... runcommand(server, [b'id', b'-t', b'-r', b'0'])
331 331 *** runcommand id -t -r 0
332 332
333 333 *** runcommand id -t -r 0
334 334 foo
335 335
336 336 >>> import os
337 337 >>> from hgclient import check, readchannel, runcommand
338 338 >>> @check
339 339 ... def setphase(server):
340 340 ... readchannel(server)
341 341 ... runcommand(server, [b'phase', b'-r', b'.'])
342 342 ... os.system('hg phase -r . -p')
343 343 ... runcommand(server, [b'phase', b'-r', b'.'])
344 344 *** runcommand phase -r .
345 345 3: draft
346 346 *** runcommand phase -r .
347 347 3: public
348 348
349 349 $ echo a >> a
350 350 >>> from hgclient import bprint, check, readchannel, runcommand
351 351 >>> @check
352 352 ... def rollback(server):
353 353 ... readchannel(server)
354 354 ... runcommand(server, [b'phase', b'-r', b'.', b'-p'])
355 355 ... runcommand(server, [b'commit', b'-Am.'])
356 356 ... runcommand(server, [b'rollback'])
357 357 ... runcommand(server, [b'phase', b'-r', b'.'])
358 358 ... bprint(b'')
359 359 *** runcommand phase -r . -p
360 360 no phases changed
361 361 *** runcommand commit -Am.
362 362 *** runcommand rollback
363 363 repository tip rolled back to revision 3 (undo commit)
364 364 working directory now based on revision 3
365 365 *** runcommand phase -r .
366 366 3: public
367 367
368 368
369 369 >>> import os
370 370 >>> from hgclient import check, readchannel, runcommand
371 371 >>> @check
372 372 ... def branch(server):
373 373 ... readchannel(server)
374 374 ... runcommand(server, [b'branch'])
375 375 ... os.system('hg branch foo')
376 376 ... runcommand(server, [b'branch'])
377 377 ... os.system('hg branch default')
378 378 *** runcommand branch
379 379 default
380 380 marked working directory as branch foo
381 381 (branches are permanent and global, did you want a bookmark?)
382 382 *** runcommand branch
383 383 foo
384 384 marked working directory as branch default
385 385 (branches are permanent and global, did you want a bookmark?)
386 386
387 387 $ touch .hgignore
388 388 >>> import os
389 389 >>> from hgclient import bprint, check, readchannel, runcommand
390 390 >>> @check
391 391 ... def hgignore(server):
392 392 ... readchannel(server)
393 393 ... runcommand(server, [b'commit', b'-Am.'])
394 394 ... f = open('ignored-file', 'ab')
395 395 ... f.write(b'') and None
396 396 ... f.close()
397 397 ... f = open('.hgignore', 'ab')
398 398 ... f.write(b'ignored-file')
399 399 ... f.close()
400 400 ... runcommand(server, [b'status', b'-i', b'-u'])
401 401 ... bprint(b'')
402 402 *** runcommand commit -Am.
403 403 adding .hgignore
404 404 *** runcommand status -i -u
405 405 I ignored-file
406 406
407 407
408 408 cache of non-public revisions should be invalidated on repository change
409 409 (issue4855):
410 410
411 411 >>> import os
412 412 >>> from hgclient import bprint, check, readchannel, runcommand
413 413 >>> @check
414 414 ... def phasesetscacheaftercommit(server):
415 415 ... readchannel(server)
416 416 ... # load _phasecache._phaserevs and _phasesets
417 417 ... runcommand(server, [b'log', b'-qr', b'draft()'])
418 418 ... # create draft commits by another process
419 419 ... for i in range(5, 7):
420 420 ... f = open('a', 'ab')
421 421 ... f.seek(0, os.SEEK_END)
422 422 ... f.write(b'a\n') and None
423 423 ... f.close()
424 424 ... os.system('hg commit -Aqm%d' % i)
425 425 ... # new commits should be listed as draft revisions
426 426 ... runcommand(server, [b'log', b'-qr', b'draft()'])
427 427 ... bprint(b'')
428 428 *** runcommand log -qr draft()
429 429 4:7966c8e3734d
430 430 *** runcommand log -qr draft()
431 431 4:7966c8e3734d
432 432 5:41f6602d1c4f
433 433 6:10501e202c35
434 434
435 435
436 436 >>> import os
437 437 >>> from hgclient import bprint, check, readchannel, runcommand
438 438 >>> @check
439 439 ... def phasesetscacheafterstrip(server):
440 440 ... readchannel(server)
441 441 ... # load _phasecache._phaserevs and _phasesets
442 442 ... runcommand(server, [b'log', b'-qr', b'draft()'])
443 443 ... # strip cached revisions by another process
444 444 ... os.system('hg --config extensions.strip= strip -q 5')
445 445 ... # shouldn't abort by "unknown revision '6'"
446 446 ... runcommand(server, [b'log', b'-qr', b'draft()'])
447 447 ... bprint(b'')
448 448 *** runcommand log -qr draft()
449 449 4:7966c8e3734d
450 450 5:41f6602d1c4f
451 451 6:10501e202c35
452 452 *** runcommand log -qr draft()
453 453 4:7966c8e3734d
454 454
455 455
456 456 cache of phase roots should be invalidated on strip (issue3827):
457 457
458 458 >>> import os
459 459 >>> from hgclient import check, readchannel, runcommand, sep
460 460 >>> @check
461 461 ... def phasecacheafterstrip(server):
462 462 ... readchannel(server)
463 463 ...
464 464 ... # create new head, 5:731265503d86
465 465 ... runcommand(server, [b'update', b'-C', b'0'])
466 466 ... f = open('a', 'ab')
467 467 ... f.write(b'a\n') and None
468 468 ... f.close()
469 469 ... runcommand(server, [b'commit', b'-Am.', b'a'])
470 470 ... runcommand(server, [b'log', b'-Gq'])
471 471 ...
472 472 ... # make it public; draft marker moves to 4:7966c8e3734d
473 473 ... runcommand(server, [b'phase', b'-p', b'.'])
474 474 ... # load _phasecache.phaseroots
475 475 ... runcommand(server, [b'phase', b'.'], outfilter=sep)
476 476 ...
477 477 ... # strip 1::4 outside server
478 478 ... os.system('hg -q --config extensions.mq= strip 1')
479 479 ...
480 480 ... # shouldn't raise "7966c8e3734d: no node!"
481 481 ... runcommand(server, [b'branches'])
482 482 *** runcommand update -C 0
483 483 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
484 484 (leaving bookmark bm3)
485 485 *** runcommand commit -Am. a
486 486 created new head
487 487 *** runcommand log -Gq
488 488 @ 5:731265503d86
489 489 |
490 490 | o 4:7966c8e3734d
491 491 | |
492 492 | o 3:b9b85890c400
493 493 | |
494 494 | o 2:aef17e88f5f0
495 495 | |
496 496 | o 1:d3a0a68be6de
497 497 |/
498 498 o 0:eff892de26ec
499 499
500 500 *** runcommand phase -p .
501 501 *** runcommand phase .
502 502 5: public
503 503 *** runcommand branches
504 504 default 1:731265503d86
505 505
506 506 in-memory cache must be reloaded if transaction is aborted. otherwise
507 507 changelog and manifest would have invalid node:
508 508
509 509 $ echo a >> a
510 510 >>> from hgclient import check, readchannel, runcommand
511 511 >>> @check
512 512 ... def txabort(server):
513 513 ... readchannel(server)
514 514 ... runcommand(server, [b'commit', b'--config', b'hooks.pretxncommit=false',
515 515 ... b'-mfoo'])
516 516 ... runcommand(server, [b'verify'])
517 517 *** runcommand commit --config hooks.pretxncommit=false -mfoo
518 518 transaction abort!
519 519 rollback completed
520 520 abort: pretxncommit hook exited with status 1
521 521 [255]
522 522 *** runcommand verify
523 523 checking changesets
524 524 checking manifests
525 525 crosschecking files in changesets and manifests
526 526 checking files
527 527 checked 2 changesets with 2 changes to 1 files
528 528 $ hg revert --no-backup -aq
529 529
530 530 $ cat >> .hg/hgrc << EOF
531 531 > [experimental]
532 532 > evolution.createmarkers=True
533 533 > EOF
534 534
535 535 >>> import os
536 536 >>> from hgclient import check, readchannel, runcommand
537 537 >>> @check
538 538 ... def obsolete(server):
539 539 ... readchannel(server)
540 540 ...
541 541 ... runcommand(server, [b'up', b'null'])
542 542 ... runcommand(server, [b'phase', b'-df', b'tip'])
543 543 ... cmd = 'hg debugobsolete `hg log -r tip --template {node}`'
544 544 ... if os.name == 'nt':
545 545 ... cmd = 'sh -c "%s"' % cmd # run in sh, not cmd.exe
546 546 ... os.system(cmd)
547 547 ... runcommand(server, [b'log', b'--hidden'])
548 548 ... runcommand(server, [b'log'])
549 549 *** runcommand up null
550 550 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
551 551 *** runcommand phase -df tip
552 552 obsoleted 1 changesets
553 553 *** runcommand log --hidden
554 554 changeset: 1:731265503d86
555 555 tag: tip
556 556 user: test
557 557 date: Thu Jan 01 00:00:00 1970 +0000
558 558 obsolete: pruned
559 559 summary: .
560 560
561 561 changeset: 0:eff892de26ec
562 562 bookmark: bm1
563 563 bookmark: bm2
564 564 bookmark: bm3
565 565 user: test
566 566 date: Thu Jan 01 00:00:00 1970 +0000
567 567 summary: 1
568 568
569 569 *** runcommand log
570 570 changeset: 0:eff892de26ec
571 571 bookmark: bm1
572 572 bookmark: bm2
573 573 bookmark: bm3
574 574 tag: tip
575 575 user: test
576 576 date: Thu Jan 01 00:00:00 1970 +0000
577 577 summary: 1
578 578
579 579
580 580 $ cat <<EOF >> .hg/hgrc
581 581 > [extensions]
582 582 > mq =
583 583 > EOF
584 584
585 585 >>> import os
586 586 >>> from hgclient import check, readchannel, runcommand
587 587 >>> @check
588 588 ... def mqoutsidechanges(server):
589 589 ... readchannel(server)
590 590 ...
591 591 ... # load repo.mq
592 592 ... runcommand(server, [b'qapplied'])
593 593 ... os.system('hg qnew 0.diff')
594 594 ... # repo.mq should be invalidated
595 595 ... runcommand(server, [b'qapplied'])
596 596 ...
597 597 ... runcommand(server, [b'qpop', b'--all'])
598 598 ... os.system('hg qqueue --create foo')
599 599 ... # repo.mq should be recreated to point to new queue
600 600 ... runcommand(server, [b'qqueue', b'--active'])
601 601 *** runcommand qapplied
602 602 *** runcommand qapplied
603 603 0.diff
604 604 *** runcommand qpop --all
605 605 popping 0.diff
606 606 patch queue now empty
607 607 *** runcommand qqueue --active
608 608 foo
609 609
610 610 $ cat <<'EOF' > ../dbgui.py
611 611 > import os
612 612 > import sys
613 613 > from mercurial import commands, registrar
614 614 > cmdtable = {}
615 615 > command = registrar.command(cmdtable)
616 616 > @command(b"debuggetpass", norepo=True)
617 617 > def debuggetpass(ui):
618 618 > ui.write(b"%s\n" % ui.getpass())
619 619 > @command(b"debugprompt", norepo=True)
620 620 > def debugprompt(ui):
621 621 > ui.write(b"%s\n" % ui.prompt(b"prompt:"))
622 622 > @command(b"debugpromptchoice", norepo=True)
623 623 > def debugpromptchoice(ui):
624 624 > msg = b"promptchoice (y/n)? $$ &Yes $$ &No"
625 625 > ui.write(b"%d\n" % ui.promptchoice(msg))
626 626 > @command(b"debugreadstdin", norepo=True)
627 627 > def debugreadstdin(ui):
628 628 > ui.write(b"read: %r\n" % sys.stdin.read(1))
629 629 > @command(b"debugwritestdout", norepo=True)
630 630 > def debugwritestdout(ui):
631 631 > os.write(1, b"low-level stdout fd and\n")
632 632 > sys.stdout.write("stdout should be redirected to stderr\n")
633 633 > sys.stdout.flush()
634 634 > EOF
635 635 $ cat <<EOF >> .hg/hgrc
636 636 > [extensions]
637 637 > dbgui = ../dbgui.py
638 638 > EOF
639 639
640 640 >>> from hgclient import check, readchannel, runcommand, stringio
641 641 >>> @check
642 642 ... def getpass(server):
643 643 ... readchannel(server)
644 644 ... runcommand(server, [b'debuggetpass', b'--config',
645 645 ... b'ui.interactive=True'],
646 646 ... input=stringio(b'1234\n'))
647 647 ... runcommand(server, [b'debuggetpass', b'--config',
648 648 ... b'ui.interactive=True'],
649 649 ... input=stringio(b'\n'))
650 650 ... runcommand(server, [b'debuggetpass', b'--config',
651 651 ... b'ui.interactive=True'],
652 652 ... input=stringio(b''))
653 653 ... runcommand(server, [b'debugprompt', b'--config',
654 654 ... b'ui.interactive=True'],
655 655 ... input=stringio(b'5678\n'))
656 656 ... runcommand(server, [b'debugreadstdin'])
657 657 ... runcommand(server, [b'debugwritestdout'])
658 658 *** runcommand debuggetpass --config ui.interactive=True
659 659 password: 1234
660 660 *** runcommand debuggetpass --config ui.interactive=True
661 661 password:
662 662 *** runcommand debuggetpass --config ui.interactive=True
663 663 password: abort: response expected
664 664 [255]
665 665 *** runcommand debugprompt --config ui.interactive=True
666 666 prompt: 5678
667 667 *** runcommand debugreadstdin
668 668 read: ''
669 669 *** runcommand debugwritestdout
670 670 low-level stdout fd and
671 671 stdout should be redirected to stderr
672 672
673 673
674 674 run commandserver in commandserver, which is silly but should work:
675 675
676 676 >>> from hgclient import bprint, check, readchannel, runcommand, stringio
677 677 >>> @check
678 678 ... def nested(server):
679 679 ... bprint(b'%c, %r' % readchannel(server))
680 680 ... class nestedserver(object):
681 681 ... stdin = stringio(b'getencoding\n')
682 682 ... stdout = stringio()
683 683 ... runcommand(server, [b'serve', b'--cmdserver', b'pipe'],
684 684 ... output=nestedserver.stdout, input=nestedserver.stdin)
685 685 ... nestedserver.stdout.seek(0)
686 686 ... bprint(b'%c, %r' % readchannel(nestedserver)) # hello
687 687 ... bprint(b'%c, %r' % readchannel(nestedserver)) # getencoding
688 688 o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob)
689 689 *** runcommand serve --cmdserver pipe
690 690 o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob)
691 691 r, '*' (glob)
692 692
693 693
694 694 start without repository:
695 695
696 696 $ cd ..
697 697
698 698 >>> from hgclient import bprint, check, readchannel, runcommand
699 699 >>> @check
700 700 ... def hellomessage(server):
701 701 ... ch, data = readchannel(server)
702 702 ... bprint(b'%c, %r' % (ch, data))
703 703 ... # run an arbitrary command to make sure the next thing the server
704 704 ... # sends isn't part of the hello message
705 705 ... runcommand(server, [b'id'])
706 706 o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob)
707 707 *** runcommand id
708 708 abort: there is no Mercurial repository here (.hg not found)
709 709 [255]
710 710
711 711 >>> from hgclient import check, readchannel, runcommand
712 712 >>> @check
713 713 ... def startwithoutrepo(server):
714 714 ... readchannel(server)
715 715 ... runcommand(server, [b'init', b'repo2'])
716 716 ... runcommand(server, [b'id', b'-R', b'repo2'])
717 717 *** runcommand init repo2
718 718 *** runcommand id -R repo2
719 719 000000000000 tip
720 720
721 721
722 722 don't fall back to cwd if invalid -R path is specified (issue4805):
723 723
724 724 $ cd repo
725 725 $ hg serve --cmdserver pipe -R ../nonexistent
726 726 abort: repository ../nonexistent not found!
727 727 [255]
728 728 $ cd ..
729 729
730 730
731 731 structured message channel:
732 732
733 733 $ cat <<'EOF' >> repo2/.hg/hgrc
734 734 > [ui]
735 735 > # server --config should precede repository option
736 736 > message-output = stdio
737 737 > EOF
738 738
739 739 >>> from hgclient import bprint, checkwith, readchannel, runcommand
740 740 >>> @checkwith(extraargs=[b'--config', b'ui.message-output=channel',
741 741 ... b'--config', b'cmdserver.message-encodings=foo cbor'])
742 742 ... def verify(server):
743 743 ... _ch, data = readchannel(server)
744 744 ... bprint(data)
745 745 ... runcommand(server, [b'-R', b'repo2', b'verify'])
746 746 capabilities: getencoding runcommand
747 747 encoding: ascii
748 748 message-encoding: cbor
749 749 pid: * (glob)
750 pgid: * (glob)
750 pgid: * (glob) (no-windows !)
751 751 *** runcommand -R repo2 verify
752 752 message: '\xa2DdataTchecking changesets\nDtypeFstatus'
753 753 message: '\xa6Ditem@Cpos\xf6EtopicHcheckingEtotal\xf6DtypeHprogressDunit@'
754 754 message: '\xa2DdataSchecking manifests\nDtypeFstatus'
755 755 message: '\xa6Ditem@Cpos\xf6EtopicHcheckingEtotal\xf6DtypeHprogressDunit@'
756 756 message: '\xa2DdataX0crosschecking files in changesets and manifests\nDtypeFstatus'
757 757 message: '\xa6Ditem@Cpos\xf6EtopicMcrosscheckingEtotal\xf6DtypeHprogressDunit@'
758 758 message: '\xa2DdataOchecking files\nDtypeFstatus'
759 759 message: '\xa6Ditem@Cpos\xf6EtopicHcheckingEtotal\xf6DtypeHprogressDunit@'
760 760 message: '\xa2DdataX/checked 0 changesets with 0 changes to 0 files\nDtypeFstatus'
761 761
762 762 >>> from hgclient import checkwith, readchannel, runcommand, stringio
763 763 >>> @checkwith(extraargs=[b'--config', b'ui.message-output=channel',
764 764 ... b'--config', b'cmdserver.message-encodings=cbor',
765 765 ... b'--config', b'extensions.dbgui=dbgui.py'])
766 766 ... def prompt(server):
767 767 ... readchannel(server)
768 768 ... interactive = [b'--config', b'ui.interactive=True']
769 769 ... runcommand(server, [b'debuggetpass'] + interactive,
770 770 ... input=stringio(b'1234\n'))
771 771 ... runcommand(server, [b'debugprompt'] + interactive,
772 772 ... input=stringio(b'5678\n'))
773 773 ... runcommand(server, [b'debugpromptchoice'] + interactive,
774 774 ... input=stringio(b'n\n'))
775 775 *** runcommand debuggetpass --config ui.interactive=True
776 776 message: '\xa3DdataJpassword: Hpassword\xf5DtypeFprompt'
777 777 1234
778 778 *** runcommand debugprompt --config ui.interactive=True
779 779 message: '\xa3DdataGprompt:GdefaultAyDtypeFprompt'
780 780 5678
781 781 *** runcommand debugpromptchoice --config ui.interactive=True
782 782 message: '\xa4Gchoices\x82\x82AyCYes\x82AnBNoDdataTpromptchoice (y/n)? GdefaultAyDtypeFprompt'
783 783 1
784 784
785 785 bad message encoding:
786 786
787 787 $ hg serve --cmdserver pipe --config ui.message-output=channel
788 788 abort: no supported message encodings:
789 789 [255]
790 790 $ hg serve --cmdserver pipe --config ui.message-output=channel \
791 791 > --config cmdserver.message-encodings='foo bar'
792 792 abort: no supported message encodings: foo bar
793 793 [255]
794 794
795 795 unix domain socket:
796 796
797 797 $ cd repo
798 798 $ hg update -q
799 799
800 800 #if unix-socket unix-permissions
801 801
802 802 >>> from hgclient import bprint, check, readchannel, runcommand, stringio, unixserver
803 803 >>> server = unixserver(b'.hg/server.sock', b'.hg/server.log')
804 804 >>> def hellomessage(conn):
805 805 ... ch, data = readchannel(conn)
806 806 ... bprint(b'%c, %r' % (ch, data))
807 807 ... runcommand(conn, [b'id'])
808 808 >>> check(hellomessage, server.connect)
809 809 o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob)
810 810 *** runcommand id
811 811 eff892de26ec tip bm1/bm2/bm3
812 812 >>> def unknowncommand(conn):
813 813 ... readchannel(conn)
814 814 ... conn.stdin.write(b'unknowncommand\n')
815 815 >>> check(unknowncommand, server.connect) # error sent to server.log
816 816 >>> def serverinput(conn):
817 817 ... readchannel(conn)
818 818 ... patch = b"""
819 819 ... # HG changeset patch
820 820 ... # User test
821 821 ... # Date 0 0
822 822 ... 2
823 823 ...
824 824 ... diff -r eff892de26ec -r 1ed24be7e7a0 a
825 825 ... --- a/a
826 826 ... +++ b/a
827 827 ... @@ -1,1 +1,2 @@
828 828 ... 1
829 829 ... +2
830 830 ... """
831 831 ... runcommand(conn, [b'import', b'-'], input=stringio(patch))
832 832 ... runcommand(conn, [b'log', b'-rtip', b'-q'])
833 833 >>> check(serverinput, server.connect)
834 834 *** runcommand import -
835 835 applying patch from stdin
836 836 *** runcommand log -rtip -q
837 837 2:1ed24be7e7a0
838 838 >>> server.shutdown()
839 839
840 840 $ cat .hg/server.log
841 841 listening at .hg/server.sock
842 842 abort: unknown command unknowncommand
843 843 killed!
844 844 $ rm .hg/server.log
845 845
846 846 if server crashed before hello, traceback will be sent to 'e' channel as
847 847 last ditch:
848 848
849 849 $ cat <<EOF >> .hg/hgrc
850 850 > [cmdserver]
851 851 > log = inexistent/path.log
852 852 > EOF
853 853 >>> from hgclient import bprint, check, readchannel, unixserver
854 854 >>> server = unixserver(b'.hg/server.sock', b'.hg/server.log')
855 855 >>> def earlycrash(conn):
856 856 ... while True:
857 857 ... try:
858 858 ... ch, data = readchannel(conn)
859 859 ... for l in data.splitlines(True):
860 860 ... if not l.startswith(b' '):
861 861 ... bprint(b'%c, %r' % (ch, l))
862 862 ... except EOFError:
863 863 ... break
864 864 >>> check(earlycrash, server.connect)
865 865 e, 'Traceback (most recent call last):\n'
866 866 e, "(IOError|FileNotFoundError): .*" (re)
867 867 >>> server.shutdown()
868 868
869 869 $ cat .hg/server.log | grep -v '^ '
870 870 listening at .hg/server.sock
871 871 Traceback (most recent call last):
872 872 (IOError|FileNotFoundError): .* (re)
873 873 killed!
874 874 #endif
875 875 #if no-unix-socket
876 876
877 877 $ hg serve --cmdserver unix -a .hg/server.sock
878 878 abort: unsupported platform
879 879 [255]
880 880
881 881 #endif
882 882
883 883 $ cd ..
884 884
885 885 Test that accessing to invalid changelog cache is avoided at
886 886 subsequent operations even if repo object is reused even after failure
887 887 of transaction (see 0a7610758c42 also)
888 888
889 889 "hg log" after failure of transaction is needed to detect invalid
890 890 cache in repoview: this can't detect by "hg verify" only.
891 891
892 892 Combination of "finalization" and "empty-ness of changelog" (2 x 2 =
893 893 4) are tested, because '00changelog.i' are differently changed in each
894 894 cases.
895 895
896 896 $ cat > $TESTTMP/failafterfinalize.py <<EOF
897 897 > # extension to abort transaction after finalization forcibly
898 898 > from mercurial import commands, error, extensions, lock as lockmod
899 899 > from mercurial import registrar
900 900 > cmdtable = {}
901 901 > command = registrar.command(cmdtable)
902 902 > configtable = {}
903 903 > configitem = registrar.configitem(configtable)
904 904 > configitem(b'failafterfinalize', b'fail',
905 905 > default=None,
906 906 > )
907 907 > def fail(tr):
908 908 > raise error.Abort(b'fail after finalization')
909 909 > def reposetup(ui, repo):
910 910 > class failrepo(repo.__class__):
911 911 > def commitctx(self, ctx, error=False):
912 912 > if self.ui.configbool(b'failafterfinalize', b'fail'):
913 913 > # 'sorted()' by ASCII code on category names causes
914 914 > # invoking 'fail' after finalization of changelog
915 915 > # using "'cl-%i' % id(self)" as category name
916 916 > self.currenttransaction().addfinalize(b'zzzzzzzz', fail)
917 917 > return super(failrepo, self).commitctx(ctx, error)
918 918 > repo.__class__ = failrepo
919 919 > EOF
920 920
921 921 $ hg init repo3
922 922 $ cd repo3
923 923
924 924 $ cat <<EOF >> $HGRCPATH
925 925 > [ui]
926 926 > logtemplate = {rev} {desc|firstline} ({files})\n
927 927 >
928 928 > [extensions]
929 929 > failafterfinalize = $TESTTMP/failafterfinalize.py
930 930 > EOF
931 931
932 932 - test failure with "empty changelog"
933 933
934 934 $ echo foo > foo
935 935 $ hg add foo
936 936
937 937 (failure before finalization)
938 938
939 939 >>> from hgclient import check, readchannel, runcommand
940 940 >>> @check
941 941 ... def abort(server):
942 942 ... readchannel(server)
943 943 ... runcommand(server, [b'commit',
944 944 ... b'--config', b'hooks.pretxncommit=false',
945 945 ... b'-mfoo'])
946 946 ... runcommand(server, [b'log'])
947 947 ... runcommand(server, [b'verify', b'-q'])
948 948 *** runcommand commit --config hooks.pretxncommit=false -mfoo
949 949 transaction abort!
950 950 rollback completed
951 951 abort: pretxncommit hook exited with status 1
952 952 [255]
953 953 *** runcommand log
954 954 *** runcommand verify -q
955 955
956 956 (failure after finalization)
957 957
958 958 >>> from hgclient import check, readchannel, runcommand
959 959 >>> @check
960 960 ... def abort(server):
961 961 ... readchannel(server)
962 962 ... runcommand(server, [b'commit',
963 963 ... b'--config', b'failafterfinalize.fail=true',
964 964 ... b'-mfoo'])
965 965 ... runcommand(server, [b'log'])
966 966 ... runcommand(server, [b'verify', b'-q'])
967 967 *** runcommand commit --config failafterfinalize.fail=true -mfoo
968 968 transaction abort!
969 969 rollback completed
970 970 abort: fail after finalization
971 971 [255]
972 972 *** runcommand log
973 973 *** runcommand verify -q
974 974
975 975 - test failure with "not-empty changelog"
976 976
977 977 $ echo bar > bar
978 978 $ hg add bar
979 979 $ hg commit -mbar bar
980 980
981 981 (failure before finalization)
982 982
983 983 >>> from hgclient import check, readchannel, runcommand
984 984 >>> @check
985 985 ... def abort(server):
986 986 ... readchannel(server)
987 987 ... runcommand(server, [b'commit',
988 988 ... b'--config', b'hooks.pretxncommit=false',
989 989 ... b'-mfoo', b'foo'])
990 990 ... runcommand(server, [b'log'])
991 991 ... runcommand(server, [b'verify', b'-q'])
992 992 *** runcommand commit --config hooks.pretxncommit=false -mfoo foo
993 993 transaction abort!
994 994 rollback completed
995 995 abort: pretxncommit hook exited with status 1
996 996 [255]
997 997 *** runcommand log
998 998 0 bar (bar)
999 999 *** runcommand verify -q
1000 1000
1001 1001 (failure after finalization)
1002 1002
1003 1003 >>> from hgclient import check, readchannel, runcommand
1004 1004 >>> @check
1005 1005 ... def abort(server):
1006 1006 ... readchannel(server)
1007 1007 ... runcommand(server, [b'commit',
1008 1008 ... b'--config', b'failafterfinalize.fail=true',
1009 1009 ... b'-mfoo', b'foo'])
1010 1010 ... runcommand(server, [b'log'])
1011 1011 ... runcommand(server, [b'verify', b'-q'])
1012 1012 *** runcommand commit --config failafterfinalize.fail=true -mfoo foo
1013 1013 transaction abort!
1014 1014 rollback completed
1015 1015 abort: fail after finalization
1016 1016 [255]
1017 1017 *** runcommand log
1018 1018 0 bar (bar)
1019 1019 *** runcommand verify -q
1020 1020
1021 1021 $ cd ..
1022 1022
1023 1023 Test symlink traversal over cached audited paths:
1024 1024 -------------------------------------------------
1025 1025
1026 1026 #if symlink
1027 1027
1028 1028 set up symlink hell
1029 1029
1030 1030 $ mkdir merge-symlink-out
1031 1031 $ hg init merge-symlink
1032 1032 $ cd merge-symlink
1033 1033 $ touch base
1034 1034 $ hg commit -qAm base
1035 1035 $ ln -s ../merge-symlink-out a
1036 1036 $ hg commit -qAm 'symlink a -> ../merge-symlink-out'
1037 1037 $ hg up -q 0
1038 1038 $ mkdir a
1039 1039 $ touch a/poisoned
1040 1040 $ hg commit -qAm 'file a/poisoned'
1041 1041 $ hg log -G -T '{rev}: {desc}\n'
1042 1042 @ 2: file a/poisoned
1043 1043 |
1044 1044 | o 1: symlink a -> ../merge-symlink-out
1045 1045 |/
1046 1046 o 0: base
1047 1047
1048 1048
1049 1049 try trivial merge after update: cache of audited paths should be discarded,
1050 1050 and the merge should fail (issue5628)
1051 1051
1052 1052 $ hg up -q null
1053 1053 >>> from hgclient import check, readchannel, runcommand
1054 1054 >>> @check
1055 1055 ... def merge(server):
1056 1056 ... readchannel(server)
1057 1057 ... # audit a/poisoned as a good path
1058 1058 ... runcommand(server, [b'up', b'-qC', b'2'])
1059 1059 ... runcommand(server, [b'up', b'-qC', b'1'])
1060 1060 ... # here a is a symlink, so a/poisoned is bad
1061 1061 ... runcommand(server, [b'merge', b'2'])
1062 1062 *** runcommand up -qC 2
1063 1063 *** runcommand up -qC 1
1064 1064 *** runcommand merge 2
1065 1065 abort: path 'a/poisoned' traverses symbolic link 'a'
1066 1066 [255]
1067 1067 $ ls ../merge-symlink-out
1068 1068
1069 1069 cache of repo.auditor should be discarded, so matcher would never traverse
1070 1070 symlinks:
1071 1071
1072 1072 $ hg up -qC 0
1073 1073 $ touch ../merge-symlink-out/poisoned
1074 1074 >>> from hgclient import check, readchannel, runcommand
1075 1075 >>> @check
1076 1076 ... def files(server):
1077 1077 ... readchannel(server)
1078 1078 ... runcommand(server, [b'up', b'-qC', b'2'])
1079 1079 ... # audit a/poisoned as a good path
1080 1080 ... runcommand(server, [b'files', b'a/poisoned'])
1081 1081 ... runcommand(server, [b'up', b'-qC', b'0'])
1082 1082 ... runcommand(server, [b'up', b'-qC', b'1'])
1083 1083 ... # here 'a' is a symlink, so a/poisoned should be warned
1084 1084 ... runcommand(server, [b'files', b'a/poisoned'])
1085 1085 *** runcommand up -qC 2
1086 1086 *** runcommand files a/poisoned
1087 1087 a/poisoned
1088 1088 *** runcommand up -qC 0
1089 1089 *** runcommand up -qC 1
1090 1090 *** runcommand files a/poisoned
1091 1091 abort: path 'a/poisoned' traverses symbolic link 'a'
1092 1092 [255]
1093 1093
1094 1094 $ cd ..
1095 1095
1096 1096 #endif
General Comments 0
You need to be logged in to leave comments. Login now