##// END OF EJS Templates
test-commandserver: change way of triggering early crash...
Yuya Nishihara -
r40857:6a75363f default
parent child Browse files
Show More
@@ -1,1096 +1,1105 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 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 $ cat <<'EOF' > ../earlycrasher.py
850 > from mercurial import commandserver, extensions
851 > def _serverequest(orig, ui, repo, conn, createcmdserver):
852 > def createcmdserver(*args, **kwargs):
853 > raise Exception('crash')
854 > return orig(ui, repo, conn, createcmdserver)
855 > def extsetup(ui):
856 > extensions.wrapfunction(commandserver, b'_serverequest', _serverequest)
857 > EOF
849 858 $ cat <<EOF >> .hg/hgrc
850 > [cmdserver]
851 > log = inexistent/path.log
859 > [extensions]
860 > earlycrasher = ../earlycrasher.py
852 861 > EOF
853 862 >>> from hgclient import bprint, check, readchannel, unixserver
854 863 >>> server = unixserver(b'.hg/server.sock', b'.hg/server.log')
855 864 >>> def earlycrash(conn):
856 865 ... while True:
857 866 ... try:
858 867 ... ch, data = readchannel(conn)
859 868 ... for l in data.splitlines(True):
860 869 ... if not l.startswith(b' '):
861 870 ... bprint(b'%c, %r' % (ch, l))
862 871 ... except EOFError:
863 872 ... break
864 873 >>> check(earlycrash, server.connect)
865 874 e, 'Traceback (most recent call last):\n'
866 e, "(IOError|FileNotFoundError): .*" (re)
875 e, 'Exception: crash\n'
867 876 >>> server.shutdown()
868 877
869 878 $ cat .hg/server.log | grep -v '^ '
870 879 listening at .hg/server.sock
871 880 Traceback (most recent call last):
872 (IOError|FileNotFoundError): .* (re)
881 Exception: crash
873 882 killed!
874 883 #endif
875 884 #if no-unix-socket
876 885
877 886 $ hg serve --cmdserver unix -a .hg/server.sock
878 887 abort: unsupported platform
879 888 [255]
880 889
881 890 #endif
882 891
883 892 $ cd ..
884 893
885 894 Test that accessing to invalid changelog cache is avoided at
886 895 subsequent operations even if repo object is reused even after failure
887 896 of transaction (see 0a7610758c42 also)
888 897
889 898 "hg log" after failure of transaction is needed to detect invalid
890 899 cache in repoview: this can't detect by "hg verify" only.
891 900
892 901 Combination of "finalization" and "empty-ness of changelog" (2 x 2 =
893 902 4) are tested, because '00changelog.i' are differently changed in each
894 903 cases.
895 904
896 905 $ cat > $TESTTMP/failafterfinalize.py <<EOF
897 906 > # extension to abort transaction after finalization forcibly
898 907 > from mercurial import commands, error, extensions, lock as lockmod
899 908 > from mercurial import registrar
900 909 > cmdtable = {}
901 910 > command = registrar.command(cmdtable)
902 911 > configtable = {}
903 912 > configitem = registrar.configitem(configtable)
904 913 > configitem(b'failafterfinalize', b'fail',
905 914 > default=None,
906 915 > )
907 916 > def fail(tr):
908 917 > raise error.Abort(b'fail after finalization')
909 918 > def reposetup(ui, repo):
910 919 > class failrepo(repo.__class__):
911 920 > def commitctx(self, ctx, error=False):
912 921 > if self.ui.configbool(b'failafterfinalize', b'fail'):
913 922 > # 'sorted()' by ASCII code on category names causes
914 923 > # invoking 'fail' after finalization of changelog
915 924 > # using "'cl-%i' % id(self)" as category name
916 925 > self.currenttransaction().addfinalize(b'zzzzzzzz', fail)
917 926 > return super(failrepo, self).commitctx(ctx, error)
918 927 > repo.__class__ = failrepo
919 928 > EOF
920 929
921 930 $ hg init repo3
922 931 $ cd repo3
923 932
924 933 $ cat <<EOF >> $HGRCPATH
925 934 > [ui]
926 935 > logtemplate = {rev} {desc|firstline} ({files})\n
927 936 >
928 937 > [extensions]
929 938 > failafterfinalize = $TESTTMP/failafterfinalize.py
930 939 > EOF
931 940
932 941 - test failure with "empty changelog"
933 942
934 943 $ echo foo > foo
935 944 $ hg add foo
936 945
937 946 (failure before finalization)
938 947
939 948 >>> from hgclient import check, readchannel, runcommand
940 949 >>> @check
941 950 ... def abort(server):
942 951 ... readchannel(server)
943 952 ... runcommand(server, [b'commit',
944 953 ... b'--config', b'hooks.pretxncommit=false',
945 954 ... b'-mfoo'])
946 955 ... runcommand(server, [b'log'])
947 956 ... runcommand(server, [b'verify', b'-q'])
948 957 *** runcommand commit --config hooks.pretxncommit=false -mfoo
949 958 transaction abort!
950 959 rollback completed
951 960 abort: pretxncommit hook exited with status 1
952 961 [255]
953 962 *** runcommand log
954 963 *** runcommand verify -q
955 964
956 965 (failure after finalization)
957 966
958 967 >>> from hgclient import check, readchannel, runcommand
959 968 >>> @check
960 969 ... def abort(server):
961 970 ... readchannel(server)
962 971 ... runcommand(server, [b'commit',
963 972 ... b'--config', b'failafterfinalize.fail=true',
964 973 ... b'-mfoo'])
965 974 ... runcommand(server, [b'log'])
966 975 ... runcommand(server, [b'verify', b'-q'])
967 976 *** runcommand commit --config failafterfinalize.fail=true -mfoo
968 977 transaction abort!
969 978 rollback completed
970 979 abort: fail after finalization
971 980 [255]
972 981 *** runcommand log
973 982 *** runcommand verify -q
974 983
975 984 - test failure with "not-empty changelog"
976 985
977 986 $ echo bar > bar
978 987 $ hg add bar
979 988 $ hg commit -mbar bar
980 989
981 990 (failure before finalization)
982 991
983 992 >>> from hgclient import check, readchannel, runcommand
984 993 >>> @check
985 994 ... def abort(server):
986 995 ... readchannel(server)
987 996 ... runcommand(server, [b'commit',
988 997 ... b'--config', b'hooks.pretxncommit=false',
989 998 ... b'-mfoo', b'foo'])
990 999 ... runcommand(server, [b'log'])
991 1000 ... runcommand(server, [b'verify', b'-q'])
992 1001 *** runcommand commit --config hooks.pretxncommit=false -mfoo foo
993 1002 transaction abort!
994 1003 rollback completed
995 1004 abort: pretxncommit hook exited with status 1
996 1005 [255]
997 1006 *** runcommand log
998 1007 0 bar (bar)
999 1008 *** runcommand verify -q
1000 1009
1001 1010 (failure after finalization)
1002 1011
1003 1012 >>> from hgclient import check, readchannel, runcommand
1004 1013 >>> @check
1005 1014 ... def abort(server):
1006 1015 ... readchannel(server)
1007 1016 ... runcommand(server, [b'commit',
1008 1017 ... b'--config', b'failafterfinalize.fail=true',
1009 1018 ... b'-mfoo', b'foo'])
1010 1019 ... runcommand(server, [b'log'])
1011 1020 ... runcommand(server, [b'verify', b'-q'])
1012 1021 *** runcommand commit --config failafterfinalize.fail=true -mfoo foo
1013 1022 transaction abort!
1014 1023 rollback completed
1015 1024 abort: fail after finalization
1016 1025 [255]
1017 1026 *** runcommand log
1018 1027 0 bar (bar)
1019 1028 *** runcommand verify -q
1020 1029
1021 1030 $ cd ..
1022 1031
1023 1032 Test symlink traversal over cached audited paths:
1024 1033 -------------------------------------------------
1025 1034
1026 1035 #if symlink
1027 1036
1028 1037 set up symlink hell
1029 1038
1030 1039 $ mkdir merge-symlink-out
1031 1040 $ hg init merge-symlink
1032 1041 $ cd merge-symlink
1033 1042 $ touch base
1034 1043 $ hg commit -qAm base
1035 1044 $ ln -s ../merge-symlink-out a
1036 1045 $ hg commit -qAm 'symlink a -> ../merge-symlink-out'
1037 1046 $ hg up -q 0
1038 1047 $ mkdir a
1039 1048 $ touch a/poisoned
1040 1049 $ hg commit -qAm 'file a/poisoned'
1041 1050 $ hg log -G -T '{rev}: {desc}\n'
1042 1051 @ 2: file a/poisoned
1043 1052 |
1044 1053 | o 1: symlink a -> ../merge-symlink-out
1045 1054 |/
1046 1055 o 0: base
1047 1056
1048 1057
1049 1058 try trivial merge after update: cache of audited paths should be discarded,
1050 1059 and the merge should fail (issue5628)
1051 1060
1052 1061 $ hg up -q null
1053 1062 >>> from hgclient import check, readchannel, runcommand
1054 1063 >>> @check
1055 1064 ... def merge(server):
1056 1065 ... readchannel(server)
1057 1066 ... # audit a/poisoned as a good path
1058 1067 ... runcommand(server, [b'up', b'-qC', b'2'])
1059 1068 ... runcommand(server, [b'up', b'-qC', b'1'])
1060 1069 ... # here a is a symlink, so a/poisoned is bad
1061 1070 ... runcommand(server, [b'merge', b'2'])
1062 1071 *** runcommand up -qC 2
1063 1072 *** runcommand up -qC 1
1064 1073 *** runcommand merge 2
1065 1074 abort: path 'a/poisoned' traverses symbolic link 'a'
1066 1075 [255]
1067 1076 $ ls ../merge-symlink-out
1068 1077
1069 1078 cache of repo.auditor should be discarded, so matcher would never traverse
1070 1079 symlinks:
1071 1080
1072 1081 $ hg up -qC 0
1073 1082 $ touch ../merge-symlink-out/poisoned
1074 1083 >>> from hgclient import check, readchannel, runcommand
1075 1084 >>> @check
1076 1085 ... def files(server):
1077 1086 ... readchannel(server)
1078 1087 ... runcommand(server, [b'up', b'-qC', b'2'])
1079 1088 ... # audit a/poisoned as a good path
1080 1089 ... runcommand(server, [b'files', b'a/poisoned'])
1081 1090 ... runcommand(server, [b'up', b'-qC', b'0'])
1082 1091 ... runcommand(server, [b'up', b'-qC', b'1'])
1083 1092 ... # here 'a' is a symlink, so a/poisoned should be warned
1084 1093 ... runcommand(server, [b'files', b'a/poisoned'])
1085 1094 *** runcommand up -qC 2
1086 1095 *** runcommand files a/poisoned
1087 1096 a/poisoned
1088 1097 *** runcommand up -qC 0
1089 1098 *** runcommand up -qC 1
1090 1099 *** runcommand files a/poisoned
1091 1100 abort: path 'a/poisoned' traverses symbolic link 'a'
1092 1101 [255]
1093 1102
1094 1103 $ cd ..
1095 1104
1096 1105 #endif
General Comments 0
You need to be logged in to leave comments. Login now