##// END OF EJS Templates
test-commandserver: clean up quoting and location of dbgui extension...
Yuya Nishihara -
r40627:c49283e7 default
parent child Browse files
Show More
@@ -1,1065 +1,1065 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 $ cat <<EOF > dbgui.py
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 > ui.write(b"%s\\n" % ui.getpass())
618 > ui.write(b"%s\n" % ui.getpass())
619 619 > @command(b"debugprompt", norepo=True)
620 620 > def debugprompt(ui):
621 > ui.write(b"%s\\n" % ui.prompt(b"prompt:"))
621 > ui.write(b"%s\n" % ui.prompt(b"prompt:"))
622 622 > @command(b"debugreadstdin", norepo=True)
623 623 > def debugreadstdin(ui):
624 624 > ui.write(b"read: %r\n" % sys.stdin.read(1))
625 625 > @command(b"debugwritestdout", norepo=True)
626 626 > def debugwritestdout(ui):
627 627 > os.write(1, b"low-level stdout fd and\n")
628 628 > sys.stdout.write("stdout should be redirected to stderr\n")
629 629 > sys.stdout.flush()
630 630 > EOF
631 631 $ cat <<EOF >> .hg/hgrc
632 632 > [extensions]
633 > dbgui = dbgui.py
633 > dbgui = ../dbgui.py
634 634 > EOF
635 635
636 636 >>> from hgclient import check, readchannel, runcommand, stringio
637 637 >>> @check
638 638 ... def getpass(server):
639 639 ... readchannel(server)
640 640 ... runcommand(server, [b'debuggetpass', b'--config',
641 641 ... b'ui.interactive=True'],
642 642 ... input=stringio(b'1234\n'))
643 643 ... runcommand(server, [b'debuggetpass', b'--config',
644 644 ... b'ui.interactive=True'],
645 645 ... input=stringio(b'\n'))
646 646 ... runcommand(server, [b'debuggetpass', b'--config',
647 647 ... b'ui.interactive=True'],
648 648 ... input=stringio(b''))
649 649 ... runcommand(server, [b'debugprompt', b'--config',
650 650 ... b'ui.interactive=True'],
651 651 ... input=stringio(b'5678\n'))
652 652 ... runcommand(server, [b'debugreadstdin'])
653 653 ... runcommand(server, [b'debugwritestdout'])
654 654 *** runcommand debuggetpass --config ui.interactive=True
655 655 password: 1234
656 656 *** runcommand debuggetpass --config ui.interactive=True
657 657 password:
658 658 *** runcommand debuggetpass --config ui.interactive=True
659 659 password: abort: response expected
660 660 [255]
661 661 *** runcommand debugprompt --config ui.interactive=True
662 662 prompt: 5678
663 663 *** runcommand debugreadstdin
664 664 read: ''
665 665 *** runcommand debugwritestdout
666 666 low-level stdout fd and
667 667 stdout should be redirected to stderr
668 668
669 669
670 670 run commandserver in commandserver, which is silly but should work:
671 671
672 672 >>> from hgclient import bprint, check, readchannel, runcommand, stringio
673 673 >>> @check
674 674 ... def nested(server):
675 675 ... bprint(b'%c, %r' % readchannel(server))
676 676 ... class nestedserver(object):
677 677 ... stdin = stringio(b'getencoding\n')
678 678 ... stdout = stringio()
679 679 ... runcommand(server, [b'serve', b'--cmdserver', b'pipe'],
680 680 ... output=nestedserver.stdout, input=nestedserver.stdin)
681 681 ... nestedserver.stdout.seek(0)
682 682 ... bprint(b'%c, %r' % readchannel(nestedserver)) # hello
683 683 ... bprint(b'%c, %r' % readchannel(nestedserver)) # getencoding
684 684 o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob)
685 685 *** runcommand serve --cmdserver pipe
686 686 o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob)
687 687 r, '*' (glob)
688 688
689 689
690 690 start without repository:
691 691
692 692 $ cd ..
693 693
694 694 >>> from hgclient import bprint, check, readchannel, runcommand
695 695 >>> @check
696 696 ... def hellomessage(server):
697 697 ... ch, data = readchannel(server)
698 698 ... bprint(b'%c, %r' % (ch, data))
699 699 ... # run an arbitrary command to make sure the next thing the server
700 700 ... # sends isn't part of the hello message
701 701 ... runcommand(server, [b'id'])
702 702 o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob)
703 703 *** runcommand id
704 704 abort: there is no Mercurial repository here (.hg not found)
705 705 [255]
706 706
707 707 >>> from hgclient import check, readchannel, runcommand
708 708 >>> @check
709 709 ... def startwithoutrepo(server):
710 710 ... readchannel(server)
711 711 ... runcommand(server, [b'init', b'repo2'])
712 712 ... runcommand(server, [b'id', b'-R', b'repo2'])
713 713 *** runcommand init repo2
714 714 *** runcommand id -R repo2
715 715 000000000000 tip
716 716
717 717
718 718 don't fall back to cwd if invalid -R path is specified (issue4805):
719 719
720 720 $ cd repo
721 721 $ hg serve --cmdserver pipe -R ../nonexistent
722 722 abort: repository ../nonexistent not found!
723 723 [255]
724 724 $ cd ..
725 725
726 726
727 727 structured message channel:
728 728
729 729 $ cat <<'EOF' >> repo2/.hg/hgrc
730 730 > [ui]
731 731 > # server --config should precede repository option
732 732 > message-output = stdio
733 733 > EOF
734 734
735 735 >>> from hgclient import bprint, checkwith, readchannel, runcommand
736 736 >>> @checkwith(extraargs=[b'--config', b'ui.message-output=channel',
737 737 ... b'--config', b'cmdserver.message-encodings=foo cbor'])
738 738 ... def verify(server):
739 739 ... _ch, data = readchannel(server)
740 740 ... bprint(data)
741 741 ... runcommand(server, [b'-R', b'repo2', b'verify'])
742 742 capabilities: getencoding runcommand
743 743 encoding: ascii
744 744 message-encoding: cbor
745 745 pid: * (glob)
746 746 pgid: * (glob)
747 747 *** runcommand -R repo2 verify
748 748 message: '\xa2DdataTchecking changesets\nDtypeFstatus'
749 749 message: '\xa2DdataSchecking manifests\nDtypeFstatus'
750 750 message: '\xa2DdataX0crosschecking files in changesets and manifests\nDtypeFstatus'
751 751 message: '\xa2DdataOchecking files\nDtypeFstatus'
752 752 message: '\xa2DdataX/checked 0 changesets with 0 changes to 0 files\nDtypeFstatus'
753 753
754 754 bad message encoding:
755 755
756 756 $ hg serve --cmdserver pipe --config ui.message-output=channel
757 757 abort: no supported message encodings:
758 758 [255]
759 759 $ hg serve --cmdserver pipe --config ui.message-output=channel \
760 760 > --config cmdserver.message-encodings='foo bar'
761 761 abort: no supported message encodings: foo bar
762 762 [255]
763 763
764 764 unix domain socket:
765 765
766 766 $ cd repo
767 767 $ hg update -q
768 768
769 769 #if unix-socket unix-permissions
770 770
771 771 >>> from hgclient import bprint, check, readchannel, runcommand, stringio, unixserver
772 772 >>> server = unixserver(b'.hg/server.sock', b'.hg/server.log')
773 773 >>> def hellomessage(conn):
774 774 ... ch, data = readchannel(conn)
775 775 ... bprint(b'%c, %r' % (ch, data))
776 776 ... runcommand(conn, [b'id'])
777 777 >>> check(hellomessage, server.connect)
778 778 o, 'capabilities: getencoding runcommand\nencoding: *\npid: *' (glob)
779 779 *** runcommand id
780 780 eff892de26ec tip bm1/bm2/bm3
781 781 >>> def unknowncommand(conn):
782 782 ... readchannel(conn)
783 783 ... conn.stdin.write(b'unknowncommand\n')
784 784 >>> check(unknowncommand, server.connect) # error sent to server.log
785 785 >>> def serverinput(conn):
786 786 ... readchannel(conn)
787 787 ... patch = b"""
788 788 ... # HG changeset patch
789 789 ... # User test
790 790 ... # Date 0 0
791 791 ... 2
792 792 ...
793 793 ... diff -r eff892de26ec -r 1ed24be7e7a0 a
794 794 ... --- a/a
795 795 ... +++ b/a
796 796 ... @@ -1,1 +1,2 @@
797 797 ... 1
798 798 ... +2
799 799 ... """
800 800 ... runcommand(conn, [b'import', b'-'], input=stringio(patch))
801 801 ... runcommand(conn, [b'log', b'-rtip', b'-q'])
802 802 >>> check(serverinput, server.connect)
803 803 *** runcommand import -
804 804 applying patch from stdin
805 805 *** runcommand log -rtip -q
806 806 2:1ed24be7e7a0
807 807 >>> server.shutdown()
808 808
809 809 $ cat .hg/server.log
810 810 listening at .hg/server.sock
811 811 abort: unknown command unknowncommand
812 812 killed!
813 813 $ rm .hg/server.log
814 814
815 815 if server crashed before hello, traceback will be sent to 'e' channel as
816 816 last ditch:
817 817
818 818 $ cat <<EOF >> .hg/hgrc
819 819 > [cmdserver]
820 820 > log = inexistent/path.log
821 821 > EOF
822 822 >>> from hgclient import bprint, check, readchannel, unixserver
823 823 >>> server = unixserver(b'.hg/server.sock', b'.hg/server.log')
824 824 >>> def earlycrash(conn):
825 825 ... while True:
826 826 ... try:
827 827 ... ch, data = readchannel(conn)
828 828 ... for l in data.splitlines(True):
829 829 ... if not l.startswith(b' '):
830 830 ... bprint(b'%c, %r' % (ch, l))
831 831 ... except EOFError:
832 832 ... break
833 833 >>> check(earlycrash, server.connect)
834 834 e, 'Traceback (most recent call last):\n'
835 835 e, "(IOError|FileNotFoundError): .*" (re)
836 836 >>> server.shutdown()
837 837
838 838 $ cat .hg/server.log | grep -v '^ '
839 839 listening at .hg/server.sock
840 840 Traceback (most recent call last):
841 841 (IOError|FileNotFoundError): .* (re)
842 842 killed!
843 843 #endif
844 844 #if no-unix-socket
845 845
846 846 $ hg serve --cmdserver unix -a .hg/server.sock
847 847 abort: unsupported platform
848 848 [255]
849 849
850 850 #endif
851 851
852 852 $ cd ..
853 853
854 854 Test that accessing to invalid changelog cache is avoided at
855 855 subsequent operations even if repo object is reused even after failure
856 856 of transaction (see 0a7610758c42 also)
857 857
858 858 "hg log" after failure of transaction is needed to detect invalid
859 859 cache in repoview: this can't detect by "hg verify" only.
860 860
861 861 Combination of "finalization" and "empty-ness of changelog" (2 x 2 =
862 862 4) are tested, because '00changelog.i' are differently changed in each
863 863 cases.
864 864
865 865 $ cat > $TESTTMP/failafterfinalize.py <<EOF
866 866 > # extension to abort transaction after finalization forcibly
867 867 > from mercurial import commands, error, extensions, lock as lockmod
868 868 > from mercurial import registrar
869 869 > cmdtable = {}
870 870 > command = registrar.command(cmdtable)
871 871 > configtable = {}
872 872 > configitem = registrar.configitem(configtable)
873 873 > configitem(b'failafterfinalize', b'fail',
874 874 > default=None,
875 875 > )
876 876 > def fail(tr):
877 877 > raise error.Abort(b'fail after finalization')
878 878 > def reposetup(ui, repo):
879 879 > class failrepo(repo.__class__):
880 880 > def commitctx(self, ctx, error=False):
881 881 > if self.ui.configbool(b'failafterfinalize', b'fail'):
882 882 > # 'sorted()' by ASCII code on category names causes
883 883 > # invoking 'fail' after finalization of changelog
884 884 > # using "'cl-%i' % id(self)" as category name
885 885 > self.currenttransaction().addfinalize(b'zzzzzzzz', fail)
886 886 > return super(failrepo, self).commitctx(ctx, error)
887 887 > repo.__class__ = failrepo
888 888 > EOF
889 889
890 890 $ hg init repo3
891 891 $ cd repo3
892 892
893 893 $ cat <<EOF >> $HGRCPATH
894 894 > [ui]
895 895 > logtemplate = {rev} {desc|firstline} ({files})\n
896 896 >
897 897 > [extensions]
898 898 > failafterfinalize = $TESTTMP/failafterfinalize.py
899 899 > EOF
900 900
901 901 - test failure with "empty changelog"
902 902
903 903 $ echo foo > foo
904 904 $ hg add foo
905 905
906 906 (failure before finalization)
907 907
908 908 >>> from hgclient import check, readchannel, runcommand
909 909 >>> @check
910 910 ... def abort(server):
911 911 ... readchannel(server)
912 912 ... runcommand(server, [b'commit',
913 913 ... b'--config', b'hooks.pretxncommit=false',
914 914 ... b'-mfoo'])
915 915 ... runcommand(server, [b'log'])
916 916 ... runcommand(server, [b'verify', b'-q'])
917 917 *** runcommand commit --config hooks.pretxncommit=false -mfoo
918 918 transaction abort!
919 919 rollback completed
920 920 abort: pretxncommit hook exited with status 1
921 921 [255]
922 922 *** runcommand log
923 923 *** runcommand verify -q
924 924
925 925 (failure after finalization)
926 926
927 927 >>> from hgclient import check, readchannel, runcommand
928 928 >>> @check
929 929 ... def abort(server):
930 930 ... readchannel(server)
931 931 ... runcommand(server, [b'commit',
932 932 ... b'--config', b'failafterfinalize.fail=true',
933 933 ... b'-mfoo'])
934 934 ... runcommand(server, [b'log'])
935 935 ... runcommand(server, [b'verify', b'-q'])
936 936 *** runcommand commit --config failafterfinalize.fail=true -mfoo
937 937 transaction abort!
938 938 rollback completed
939 939 abort: fail after finalization
940 940 [255]
941 941 *** runcommand log
942 942 *** runcommand verify -q
943 943
944 944 - test failure with "not-empty changelog"
945 945
946 946 $ echo bar > bar
947 947 $ hg add bar
948 948 $ hg commit -mbar bar
949 949
950 950 (failure before finalization)
951 951
952 952 >>> from hgclient import check, readchannel, runcommand
953 953 >>> @check
954 954 ... def abort(server):
955 955 ... readchannel(server)
956 956 ... runcommand(server, [b'commit',
957 957 ... b'--config', b'hooks.pretxncommit=false',
958 958 ... b'-mfoo', b'foo'])
959 959 ... runcommand(server, [b'log'])
960 960 ... runcommand(server, [b'verify', b'-q'])
961 961 *** runcommand commit --config hooks.pretxncommit=false -mfoo foo
962 962 transaction abort!
963 963 rollback completed
964 964 abort: pretxncommit hook exited with status 1
965 965 [255]
966 966 *** runcommand log
967 967 0 bar (bar)
968 968 *** runcommand verify -q
969 969
970 970 (failure after finalization)
971 971
972 972 >>> from hgclient import check, readchannel, runcommand
973 973 >>> @check
974 974 ... def abort(server):
975 975 ... readchannel(server)
976 976 ... runcommand(server, [b'commit',
977 977 ... b'--config', b'failafterfinalize.fail=true',
978 978 ... b'-mfoo', b'foo'])
979 979 ... runcommand(server, [b'log'])
980 980 ... runcommand(server, [b'verify', b'-q'])
981 981 *** runcommand commit --config failafterfinalize.fail=true -mfoo foo
982 982 transaction abort!
983 983 rollback completed
984 984 abort: fail after finalization
985 985 [255]
986 986 *** runcommand log
987 987 0 bar (bar)
988 988 *** runcommand verify -q
989 989
990 990 $ cd ..
991 991
992 992 Test symlink traversal over cached audited paths:
993 993 -------------------------------------------------
994 994
995 995 #if symlink
996 996
997 997 set up symlink hell
998 998
999 999 $ mkdir merge-symlink-out
1000 1000 $ hg init merge-symlink
1001 1001 $ cd merge-symlink
1002 1002 $ touch base
1003 1003 $ hg commit -qAm base
1004 1004 $ ln -s ../merge-symlink-out a
1005 1005 $ hg commit -qAm 'symlink a -> ../merge-symlink-out'
1006 1006 $ hg up -q 0
1007 1007 $ mkdir a
1008 1008 $ touch a/poisoned
1009 1009 $ hg commit -qAm 'file a/poisoned'
1010 1010 $ hg log -G -T '{rev}: {desc}\n'
1011 1011 @ 2: file a/poisoned
1012 1012 |
1013 1013 | o 1: symlink a -> ../merge-symlink-out
1014 1014 |/
1015 1015 o 0: base
1016 1016
1017 1017
1018 1018 try trivial merge after update: cache of audited paths should be discarded,
1019 1019 and the merge should fail (issue5628)
1020 1020
1021 1021 $ hg up -q null
1022 1022 >>> from hgclient import check, readchannel, runcommand
1023 1023 >>> @check
1024 1024 ... def merge(server):
1025 1025 ... readchannel(server)
1026 1026 ... # audit a/poisoned as a good path
1027 1027 ... runcommand(server, [b'up', b'-qC', b'2'])
1028 1028 ... runcommand(server, [b'up', b'-qC', b'1'])
1029 1029 ... # here a is a symlink, so a/poisoned is bad
1030 1030 ... runcommand(server, [b'merge', b'2'])
1031 1031 *** runcommand up -qC 2
1032 1032 *** runcommand up -qC 1
1033 1033 *** runcommand merge 2
1034 1034 abort: path 'a/poisoned' traverses symbolic link 'a'
1035 1035 [255]
1036 1036 $ ls ../merge-symlink-out
1037 1037
1038 1038 cache of repo.auditor should be discarded, so matcher would never traverse
1039 1039 symlinks:
1040 1040
1041 1041 $ hg up -qC 0
1042 1042 $ touch ../merge-symlink-out/poisoned
1043 1043 >>> from hgclient import check, readchannel, runcommand
1044 1044 >>> @check
1045 1045 ... def files(server):
1046 1046 ... readchannel(server)
1047 1047 ... runcommand(server, [b'up', b'-qC', b'2'])
1048 1048 ... # audit a/poisoned as a good path
1049 1049 ... runcommand(server, [b'files', b'a/poisoned'])
1050 1050 ... runcommand(server, [b'up', b'-qC', b'0'])
1051 1051 ... runcommand(server, [b'up', b'-qC', b'1'])
1052 1052 ... # here 'a' is a symlink, so a/poisoned should be warned
1053 1053 ... runcommand(server, [b'files', b'a/poisoned'])
1054 1054 *** runcommand up -qC 2
1055 1055 *** runcommand files a/poisoned
1056 1056 a/poisoned
1057 1057 *** runcommand up -qC 0
1058 1058 *** runcommand up -qC 1
1059 1059 *** runcommand files a/poisoned
1060 1060 abort: path 'a/poisoned' traverses symbolic link 'a'
1061 1061 [255]
1062 1062
1063 1063 $ cd ..
1064 1064
1065 1065 #endif
General Comments 0
You need to be logged in to leave comments. Login now