208 $ hg ci -m 'First one.' |
208 $ hg ci -m 'First one.' |
209 $ hg rollback |
209 $ hg rollback |
210 abort: rollback is disabled because it is unsafe |
210 abort: rollback is disabled because it is unsafe |
211 (see `hg help -v rollback` for information) |
211 (see `hg help -v rollback` for information) |
212 [255] |
212 [255] |
|
213 |
|
214 $ cd .. |
|
215 |
|
216 I/O errors on stdio are handled properly (issue5658) |
|
217 |
|
218 $ cat > badui.py << EOF |
|
219 > import errno |
|
220 > from mercurial.i18n import _ |
|
221 > from mercurial import ( |
|
222 > error, |
|
223 > ui as uimod, |
|
224 > ) |
|
225 > |
|
226 > def pretxncommit(ui, repo, **kwargs): |
|
227 > ui.warn('warn during pretxncommit\n') |
|
228 > |
|
229 > def pretxnclose(ui, repo, **kwargs): |
|
230 > ui.warn('warn during pretxnclose\n') |
|
231 > |
|
232 > def txnclose(ui, repo, **kwargs): |
|
233 > ui.warn('warn during txnclose\n') |
|
234 > |
|
235 > def txnabort(ui, repo, **kwargs): |
|
236 > ui.warn('warn during abort\n') |
|
237 > |
|
238 > class fdproxy(object): |
|
239 > def __init__(self, ui, o): |
|
240 > self._ui = ui |
|
241 > self._o = o |
|
242 > |
|
243 > def __getattr__(self, attr): |
|
244 > return getattr(self._o, attr) |
|
245 > |
|
246 > def write(self, msg): |
|
247 > errors = set(self._ui.configlist('ui', 'ioerrors', [])) |
|
248 > pretxncommit = msg == 'warn during pretxncommit\n' |
|
249 > pretxnclose = msg == 'warn during pretxnclose\n' |
|
250 > txnclose = msg == 'warn during txnclose\n' |
|
251 > txnabort = msg == 'warn during abort\n' |
|
252 > msgabort = msg == _('transaction abort!\n') |
|
253 > msgrollback = msg == _('rollback completed\n') |
|
254 > |
|
255 > if pretxncommit and 'pretxncommit' in errors: |
|
256 > raise IOError(errno.EPIPE, 'simulated epipe') |
|
257 > if pretxnclose and 'pretxnclose' in errors: |
|
258 > raise IOError(errno.EIO, 'simulated eio') |
|
259 > if txnclose and 'txnclose' in errors: |
|
260 > raise IOError(errno.EBADF, 'simulated badf') |
|
261 > if txnabort and 'txnabort' in errors: |
|
262 > raise IOError(errno.EPIPE, 'simulated epipe') |
|
263 > if msgabort and 'msgabort' in errors: |
|
264 > raise IOError(errno.EBADF, 'simulated ebadf') |
|
265 > if msgrollback and 'msgrollback' in errors: |
|
266 > raise IOError(errno.EIO, 'simulated eio') |
|
267 > |
|
268 > return self._o.write(msg) |
|
269 > |
|
270 > def uisetup(ui): |
|
271 > class badui(ui.__class__): |
|
272 > def write_err(self, *args, **kwargs): |
|
273 > olderr = self.ferr |
|
274 > try: |
|
275 > self.ferr = fdproxy(self, olderr) |
|
276 > return super(badui, self).write_err(*args, **kwargs) |
|
277 > finally: |
|
278 > self.ferr = olderr |
|
279 > |
|
280 > ui.__class__ = badui |
|
281 > |
|
282 > def reposetup(ui, repo): |
|
283 > ui.setconfig('hooks', 'pretxnclose.badui', pretxnclose, 'badui') |
|
284 > ui.setconfig('hooks', 'txnclose.badui', txnclose, 'badui') |
|
285 > ui.setconfig('hooks', 'pretxncommit.badui', pretxncommit, 'badui') |
|
286 > ui.setconfig('hooks', 'txnabort.badui', txnabort, 'badui') |
|
287 > EOF |
|
288 |
|
289 $ cat >> $HGRCPATH << EOF |
|
290 > [extensions] |
|
291 > badui = $TESTTMP/badui.py |
|
292 > EOF |
|
293 |
|
294 An I/O error during pretxncommit is handled |
|
295 |
|
296 $ hg init ioerror-pretxncommit |
|
297 $ cd ioerror-pretxncommit |
|
298 $ echo 0 > foo |
|
299 $ hg -q commit -A -m initial |
|
300 warn during pretxncommit |
|
301 warn during pretxnclose |
|
302 warn during txnclose |
|
303 $ echo 1 > foo |
|
304 $ hg --config ui.ioerrors=pretxncommit commit -m 'error during pretxncommit' |
|
305 error: pretxncommit.badui hook raised an exception: [Errno *] simulated epipe (glob) |
|
306 transaction abort! |
|
307 warn during abort |
|
308 rollback completed |
|
309 [255] |
|
310 |
|
311 $ hg commit -m 'commit 1' |
|
312 warn during pretxncommit |
|
313 warn during pretxnclose |
|
314 warn during txnclose |
|
315 |
|
316 $ cd .. |
|
317 |
|
318 An I/O error during pretxnclose is handled |
|
319 |
|
320 $ hg init ioerror-pretxnclose |
|
321 $ cd ioerror-pretxnclose |
|
322 $ echo 0 > foo |
|
323 $ hg -q commit -A -m initial |
|
324 warn during pretxncommit |
|
325 warn during pretxnclose |
|
326 warn during txnclose |
|
327 |
|
328 $ echo 1 > foo |
|
329 $ hg --config ui.ioerrors=pretxnclose commit -m 'error during pretxnclose' |
|
330 warn during pretxncommit |
|
331 error: pretxnclose.badui hook raised an exception: [Errno *] simulated eio (glob) |
|
332 transaction abort! |
|
333 warn during abort |
|
334 rollback completed |
|
335 abort: simulated eio |
|
336 [255] |
|
337 |
|
338 $ hg commit -m 'commit 1' |
|
339 warn during pretxncommit |
|
340 warn during pretxnclose |
|
341 warn during txnclose |
|
342 |
|
343 $ cd .. |
|
344 |
|
345 An I/O error during txnclose is handled |
|
346 |
|
347 $ hg init ioerror-txnclose |
|
348 $ cd ioerror-txnclose |
|
349 $ echo 0 > foo |
|
350 $ hg -q commit -A -m initial |
|
351 warn during pretxncommit |
|
352 warn during pretxnclose |
|
353 warn during txnclose |
|
354 |
|
355 $ echo 1 > foo |
|
356 $ hg --config ui.ioerrors=txnclose commit -m 'error during txnclose' |
|
357 warn during pretxncommit |
|
358 warn during pretxnclose |
|
359 error: txnclose.badui hook raised an exception: [Errno *] simulated badf (glob) |
|
360 (run with --traceback for stack trace) |
|
361 |
|
362 $ hg commit -m 'commit 1' |
|
363 nothing changed |
|
364 [1] |
|
365 |
|
366 $ cd .. |
|
367 |
|
368 An I/O error writing "transaction abort" is handled |
|
369 |
|
370 $ hg init ioerror-msgabort |
|
371 $ cd ioerror-msgabort |
|
372 |
|
373 $ echo 0 > foo |
|
374 $ hg -q commit -A -m initial |
|
375 warn during pretxncommit |
|
376 warn during pretxnclose |
|
377 warn during txnclose |
|
378 |
|
379 $ echo 1 > foo |
|
380 $ hg --config ui.ioerrors=msgabort --config hooks.pretxncommit=false commit -m 'error during abort message' |
|
381 abort: simulated ebadf |
|
382 *: DeprecationWarning: use lock.release instead of del lock (glob) |
|
383 return -1 |
|
384 [255] |
|
385 |
|
386 $ hg commit -m 'commit 1' |
|
387 abort: abandoned transaction found! |
|
388 (run 'hg recover' to clean up transaction) |
|
389 [255] |
|
390 |
|
391 $ cd .. |
|
392 |
|
393 An I/O error during txnabort should still result in rollback |
|
394 |
|
395 $ hg init ioerror-txnabort |
|
396 $ cd ioerror-txnabort |
|
397 |
|
398 $ echo 0 > foo |
|
399 $ hg -q commit -A -m initial |
|
400 warn during pretxncommit |
|
401 warn during pretxnclose |
|
402 warn during txnclose |
|
403 |
|
404 $ echo 1 > foo |
|
405 $ hg --config ui.ioerrors=txnabort --config hooks.pretxncommit=false commit -m 'error during abort' |
|
406 transaction abort! |
|
407 error: txnabort.badui hook raised an exception: [Errno *] simulated epipe (glob) |
|
408 (run with --traceback for stack trace) |
|
409 rollback completed |
|
410 abort: pretxncommit hook exited with status 1 |
|
411 [255] |
|
412 |
|
413 $ hg commit -m 'commit 1' |
|
414 warn during pretxncommit |
|
415 warn during pretxnclose |
|
416 warn during txnclose |
|
417 |
|
418 $ cd .. |
|
419 |
|
420 An I/O error writing "rollback completed" is handled |
|
421 |
|
422 $ hg init ioerror-msgrollback |
|
423 $ cd ioerror-msgrollback |
|
424 |
|
425 $ echo 0 > foo |
|
426 $ hg -q commit -A -m initial |
|
427 warn during pretxncommit |
|
428 warn during pretxnclose |
|
429 warn during txnclose |
|
430 |
|
431 $ echo 1 > foo |
|
432 |
|
433 $ hg --config ui.ioerrors=msgrollback --config hooks.pretxncommit=false commit -m 'error during rollback message' |
|
434 transaction abort! |
|
435 warn during abort |
|
436 rollback failed - please run hg recover |
|
437 abort: pretxncommit hook exited with status 1 |
|
438 [255] |
|
439 |
|
440 $ hg verify |
|
441 checking changesets |
|
442 checking manifests |
|
443 crosschecking files in changesets and manifests |
|
444 checking files |
|
445 1 files, 1 changesets, 1 total revisions |
|
446 |
|
447 $ cd .. |
|
448 |
|
449 Multiple I/O errors after transaction open are handled. |
|
450 This is effectively what happens if a peer disconnects in the middle |
|
451 of a transaction. |
|
452 |
|
453 $ hg init ioerror-multiple |
|
454 $ cd ioerror-multiple |
|
455 $ echo 0 > foo |
|
456 $ hg -q commit -A -m initial |
|
457 warn during pretxncommit |
|
458 warn during pretxnclose |
|
459 warn during txnclose |
|
460 |
|
461 $ echo 1 > foo |
|
462 |
|
463 $ hg --config ui.ioerrors=pretxncommit,pretxnclose,txnclose,txnabort,msgabort,msgrollback commit -m 'multiple errors' |
|
464 error: pretxncommit.badui hook raised an exception: [Errno *] simulated epipe (glob) |
|
465 abort: simulated ebadf |
|
466 *: DeprecationWarning: use lock.release instead of del lock (glob) |
|
467 return -1 |
|
468 [255] |
|
469 |
|
470 $ hg verify |
|
471 abandoned transaction found - run hg recover |
|
472 checking changesets |
|
473 checking manifests |
|
474 manifest@?: rev 1 points to nonexistent changeset 1 |
|
475 manifest@?: 94e0ee43dbfe not in changesets |
|
476 crosschecking files in changesets and manifests |
|
477 checking files |
|
478 foo@?: rev 1 points to nonexistent changeset 1 |
|
479 (expected 0) |
|
480 1 files, 1 changesets, 2 total revisions |
|
481 1 warnings encountered! |
|
482 3 integrity errors encountered! |
|
483 [1] |
|
484 |
|
485 $ cd .. |