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