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