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