##// END OF EJS Templates
blackbox: just try writing to repo.vfs and update lastlogger on success...
Yuya Nishihara -
r40828:ea2688c8 default
parent child Browse files
Show More
@@ -1,239 +1,229 b''
1 1 # blackbox.py - log repository events to a file for post-mortem debugging
2 2 #
3 3 # Copyright 2010 Nicolas Dumazet
4 4 # Copyright 2013 Facebook, Inc.
5 5 #
6 6 # This software may be used and distributed according to the terms of the
7 7 # GNU General Public License version 2 or any later version.
8 8
9 9 """log repository events to a blackbox for debugging
10 10
11 11 Logs event information to .hg/blackbox.log to help debug and diagnose problems.
12 12 The events that get logged can be configured via the blackbox.track config key.
13 13
14 14 Examples::
15 15
16 16 [blackbox]
17 17 track = *
18 18 # dirty is *EXPENSIVE* (slow);
19 19 # each log entry indicates `+` if the repository is dirty, like :hg:`id`.
20 20 dirty = True
21 21 # record the source of log messages
22 22 logsource = True
23 23
24 24 [blackbox]
25 25 track = command, commandfinish, commandexception, exthook, pythonhook
26 26
27 27 [blackbox]
28 28 track = incoming
29 29
30 30 [blackbox]
31 31 # limit the size of a log file
32 32 maxsize = 1.5 MB
33 33 # rotate up to N log files when the current one gets too big
34 34 maxfiles = 3
35 35
36 36 [blackbox]
37 37 # Include nanoseconds in log entries with %f (see Python function
38 38 # datetime.datetime.strftime)
39 39 date-format = '%Y-%m-%d @ %H:%M:%S.%f'
40 40
41 41 """
42 42
43 43 from __future__ import absolute_import
44 44
45 45 import errno
46 46 import re
47 47
48 48 from mercurial.i18n import _
49 49 from mercurial.node import hex
50 50
51 51 from mercurial import (
52 52 encoding,
53 53 pycompat,
54 54 registrar,
55 55 )
56 56 from mercurial.utils import (
57 57 dateutil,
58 58 procutil,
59 59 )
60 60
61 61 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
62 62 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
63 63 # be specifying the version(s) of Mercurial they are tested with, or
64 64 # leave the attribute unspecified.
65 65 testedwith = 'ships-with-hg-core'
66 66
67 67 cmdtable = {}
68 68 command = registrar.command(cmdtable)
69 69
70 70 configtable = {}
71 71 configitem = registrar.configitem(configtable)
72 72
73 73 configitem('blackbox', 'dirty',
74 74 default=False,
75 75 )
76 76 configitem('blackbox', 'maxsize',
77 77 default='1 MB',
78 78 )
79 79 configitem('blackbox', 'logsource',
80 80 default=False,
81 81 )
82 82 configitem('blackbox', 'maxfiles',
83 83 default=7,
84 84 )
85 85 configitem('blackbox', 'track',
86 86 default=lambda: ['*'],
87 87 )
88 88 configitem('blackbox', 'date-format',
89 89 default='%Y/%m/%d %H:%M:%S',
90 90 )
91 91
92 92 def _openlogfile(ui, vfs):
93 93 def rotate(oldpath, newpath):
94 94 try:
95 95 vfs.unlink(newpath)
96 96 except OSError as err:
97 97 if err.errno != errno.ENOENT:
98 98 ui.debug("warning: cannot remove '%s': %s\n" %
99 99 (newpath, err.strerror))
100 100 try:
101 101 if newpath:
102 102 vfs.rename(oldpath, newpath)
103 103 except OSError as err:
104 104 if err.errno != errno.ENOENT:
105 105 ui.debug("warning: cannot rename '%s' to '%s': %s\n" %
106 106 (newpath, oldpath, err.strerror))
107 107
108 108 maxsize = ui.configbytes('blackbox', 'maxsize')
109 109 name = 'blackbox.log'
110 110 if maxsize > 0:
111 111 try:
112 112 st = vfs.stat(name)
113 113 except OSError:
114 114 pass
115 115 else:
116 116 if st.st_size >= maxsize:
117 117 path = vfs.join(name)
118 118 maxfiles = ui.configint('blackbox', 'maxfiles')
119 119 for i in pycompat.xrange(maxfiles - 1, 1, -1):
120 120 rotate(oldpath='%s.%d' % (path, i - 1),
121 121 newpath='%s.%d' % (path, i))
122 122 rotate(oldpath=path,
123 123 newpath=maxfiles > 0 and path + '.1')
124 return vfs(name, 'a')
124 return vfs(name, 'a', makeparentdirs=False)
125 125
126 126 class proxylogger(object):
127 127 """Forward log events to another logger to be set later"""
128 128
129 129 def __init__(self):
130 130 self.logger = None
131 131
132 132 def tracked(self, event):
133 133 return self.logger is not None and self.logger.tracked(event)
134 134
135 135 def log(self, ui, event, msg, opts):
136 136 assert self.logger is not None
137 137 self.logger.log(ui, event, msg, opts)
138 138
139 139 _lastlogger = proxylogger()
140 140
141 141 class blackboxlogger(object):
142 142 def __init__(self, ui, repo):
143 143 self._repo = repo
144 144 self._trackedevents = set(ui.configlist('blackbox', 'track'))
145 145
146 @property
147 def _bbvfs(self):
148 vfs = self._repo.vfs
149 if not vfs.isdir('.'):
150 vfs = None
151 return vfs
152
153 146 def tracked(self, event):
154 147 return b'*' in self._trackedevents or event in self._trackedevents
155 148
156 149 def log(self, ui, event, msg, opts):
157 if self._bbvfs:
158 _lastlogger.logger = self
159 else:
160 return
161
162 150 default = ui.configdate('devel', 'default-date')
163 151 date = dateutil.datestr(default, ui.config('blackbox', 'date-format'))
164 152 user = procutil.getuser()
165 153 pid = '%d' % procutil.getpid()
166 154 rev = '(unknown)'
167 155 changed = ''
168 156 ctx = self._repo[None]
169 157 parents = ctx.parents()
170 158 rev = ('+'.join([hex(p.node()) for p in parents]))
171 159 if (ui.configbool('blackbox', 'dirty') and
172 160 ctx.dirty(missing=True, merge=False, branch=False)):
173 161 changed = '+'
174 162 if ui.configbool('blackbox', 'logsource'):
175 163 src = ' [%s]' % event
176 164 else:
177 165 src = ''
178 166 try:
179 167 fmt = '%s %s @%s%s (%s)%s> %s'
180 168 args = (date, user, rev, changed, pid, src, msg)
181 with _openlogfile(ui, self._bbvfs) as fp:
169 with _openlogfile(ui, self._repo.vfs) as fp:
182 170 fp.write(fmt % args)
183 171 except (IOError, OSError) as err:
184 172 # deactivate this to avoid failed logging again
185 173 self._trackedevents.clear()
186 174 ui.debug('warning: cannot write to blackbox.log: %s\n' %
187 175 encoding.strtolocal(err.strerror))
176 return
177 _lastlogger.logger = self
188 178
189 179 def uipopulate(ui):
190 180 ui.setlogger(b'blackbox', _lastlogger)
191 181
192 182 def reposetup(ui, repo):
193 183 # During 'hg pull' a httppeer repo is created to represent the remote repo.
194 184 # It doesn't have a .hg directory to put a blackbox in, so we don't do
195 185 # the blackbox setup for it.
196 186 if not repo.local():
197 187 return
198 188
199 189 # Since blackbox.log is stored in the repo directory, the logger should be
200 190 # instantiated per repository.
201 191 logger = blackboxlogger(ui, repo)
202 192 ui.setlogger(b'blackbox', logger)
203 193
204 194 # Set _lastlogger even if ui.log is not called. This gives blackbox a
205 195 # fallback place to log
206 196 if _lastlogger.logger is None:
207 197 _lastlogger.logger = logger
208 198
209 199 repo._wlockfreeprefix.add('blackbox.log')
210 200
211 201 @command('blackbox',
212 202 [('l', 'limit', 10, _('the number of events to show')),
213 203 ],
214 204 _('hg blackbox [OPTION]...'),
215 205 helpcategory=command.CATEGORY_MAINTENANCE,
216 206 helpbasic=True)
217 207 def blackbox(ui, repo, *revs, **opts):
218 208 '''view the recent repository events
219 209 '''
220 210
221 211 if not repo.vfs.exists('blackbox.log'):
222 212 return
223 213
224 214 limit = opts.get(r'limit')
225 215 fp = repo.vfs('blackbox.log', 'r')
226 216 lines = fp.read().split('\n')
227 217
228 218 count = 0
229 219 output = []
230 220 for line in reversed(lines):
231 221 if count >= limit:
232 222 break
233 223
234 224 # count the commands by matching lines like: 2013/01/23 19:13:36 root>
235 225 if re.match('^\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2} .*> .*', line):
236 226 count += 1
237 227 output.append(line)
238 228
239 229 ui.status('\n'.join(reversed(output)))
@@ -1,428 +1,451 b''
1 1 setup
2 2
3 3 $ cat > myextension.py <<EOF
4 4 > from mercurial import error, registrar
5 5 > cmdtable = {}
6 6 > command = registrar.command(cmdtable)
7 7 > @command(b'crash', [], b'hg crash')
8 8 > def crash(ui, *args, **kwargs):
9 9 > raise Exception("oops")
10 10 > @command(b'abort', [], b'hg abort')
11 11 > def abort(ui, *args, **kwargs):
12 12 > raise error.Abort(b"oops")
13 13 > EOF
14 14 $ abspath=`pwd`/myextension.py
15 15
16 16 $ cat >> $HGRCPATH <<EOF
17 17 > [extensions]
18 18 > blackbox=
19 19 > mock=$TESTDIR/mockblackbox.py
20 20 > mq=
21 21 > myextension=$TESTTMP/myextension.py
22 22 > [alias]
23 23 > confuse = log --limit 3
24 24 > so-confusing = confuse --style compact
25 25 > EOF
26 26
27 27 $ hg init blackboxtest
28 28 $ cd blackboxtest
29 29
30 30 command, exit codes, and duration
31 31
32 32 $ echo a > a
33 33 $ hg add a
34 34 $ hg blackbox --config blackbox.dirty=True
35 35 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> init blackboxtest exited 0 after * seconds (glob)
36 36 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> add a
37 37 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> add a exited 0 after * seconds (glob)
38 38 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000+ (5000)> blackbox --config *blackbox.dirty=True* (glob)
39 39
40 40 failure exit code
41 41 $ rm ./.hg/blackbox.log
42 42 $ hg add non-existent
43 43 non-existent: $ENOENT$
44 44 [1]
45 45 $ hg blackbox
46 46 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> add non-existent
47 47 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> add non-existent exited 1 after * seconds (glob)
48 48 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> blackbox
49 49
50 50 abort exit code
51 51 $ rm ./.hg/blackbox.log
52 52 $ hg abort 2> /dev/null
53 53 [255]
54 54 $ hg blackbox -l 2
55 55 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> abort exited 255 after * seconds (glob)
56 56 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> blackbox -l 2
57 57
58 58 unhandled exception
59 59 $ rm ./.hg/blackbox.log
60 60 $ hg crash 2> /dev/null
61 61 [1]
62 62 $ hg blackbox -l 2
63 63 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> crash exited 1 after * seconds (glob)
64 64 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> blackbox -l 2
65 65
66 66 alias expansion is logged
67 67 $ rm ./.hg/blackbox.log
68 68 $ hg confuse
69 69 $ hg blackbox
70 70 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> confuse
71 71 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> alias 'confuse' expands to 'log --limit 3'
72 72 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> confuse exited 0 after * seconds (glob)
73 73 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> blackbox
74 74
75 75 recursive aliases work correctly
76 76 $ rm ./.hg/blackbox.log
77 77 $ hg so-confusing
78 78 $ hg blackbox
79 79 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> so-confusing
80 80 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> alias 'so-confusing' expands to 'confuse --style compact'
81 81 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> alias 'confuse' expands to 'log --limit 3'
82 82 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> so-confusing exited 0 after * seconds (glob)
83 83 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> blackbox
84 84
85 85 custom date format
86 86 $ rm ./.hg/blackbox.log
87 87 $ hg --config blackbox.date-format='%Y-%m-%d @ %H:%M:%S' \
88 88 > --config devel.default-date='1334347993 0' --traceback status
89 89 A a
90 90 $ hg blackbox
91 91 2012-04-13 @ 20:13:13 bob @0000000000000000000000000000000000000000 (5000)> --config *blackbox.date-format=%Y-%m-%d @ %H:%M:%S* --config *devel.default-date=1334347993 0* --traceback status (glob)
92 92 2012-04-13 @ 20:13:13 bob @0000000000000000000000000000000000000000 (5000)> --config *blackbox.date-format=%Y-%m-%d @ %H:%M:%S* --config *devel.default-date=1334347993 0* --traceback status exited 0 after * seconds (glob)
93 93 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> blackbox
94 94
95 95 incoming change tracking
96 96
97 97 create two heads to verify that we only see one change in the log later
98 98 $ hg commit -ma
99 99 $ hg up null
100 100 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
101 101 $ echo b > b
102 102 $ hg commit -Amb
103 103 adding b
104 104 created new head
105 105
106 106 clone, commit, pull
107 107 $ hg clone . ../blackboxtest2
108 108 updating to branch default
109 109 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
110 110 $ echo c > c
111 111 $ hg commit -Amc
112 112 adding c
113 113 $ cd ../blackboxtest2
114 114 $ hg pull
115 115 pulling from $TESTTMP/blackboxtest
116 116 searching for changes
117 117 adding changesets
118 118 adding manifests
119 119 adding file changes
120 120 added 1 changesets with 1 changes to 1 files
121 121 new changesets d02f48003e62
122 122 (run 'hg update' to get a working copy)
123 123 $ hg blackbox -l 6
124 124 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> pull
125 125 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> updated served branch cache in * seconds (glob)
126 126 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> wrote served branch cache with 1 labels and 2 nodes
127 127 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> 1 incoming changes - new heads: d02f48003e62
128 128 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> pull exited 0 after * seconds (glob)
129 129 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> blackbox -l 6
130 130
131 131 we must not cause a failure if we cannot write to the log
132 132
133 133 $ hg rollback
134 134 repository tip rolled back to revision 1 (undo pull)
135 135
136 136 $ mv .hg/blackbox.log .hg/blackbox.log-
137 137 $ mkdir .hg/blackbox.log
138 138 $ hg --debug incoming
139 139 warning: cannot write to blackbox.log: * (glob)
140 140 comparing with $TESTTMP/blackboxtest
141 141 query 1; heads
142 142 searching for changes
143 143 all local heads known remotely
144 144 changeset: 2:d02f48003e62c24e2659d97d30f2a83abe5d5d51
145 145 tag: tip
146 146 phase: draft
147 147 parent: 1:6563da9dcf87b1949716e38ff3e3dfaa3198eb06
148 148 parent: -1:0000000000000000000000000000000000000000
149 149 manifest: 2:ab9d46b053ebf45b7996f2922b9893ff4b63d892
150 150 user: test
151 151 date: Thu Jan 01 00:00:00 1970 +0000
152 152 files+: c
153 153 extra: branch=default
154 154 description:
155 155 c
156 156
157 157
158 158 $ hg pull
159 159 pulling from $TESTTMP/blackboxtest
160 160 searching for changes
161 161 adding changesets
162 162 adding manifests
163 163 adding file changes
164 164 added 1 changesets with 1 changes to 1 files
165 165 new changesets d02f48003e62
166 166 (run 'hg update' to get a working copy)
167 167
168 168 a failure reading from the log is fatal
169 169
170 170 $ hg blackbox -l 3
171 171 abort: *$TESTTMP/blackboxtest2/.hg/blackbox.log* (glob)
172 172 [255]
173 173
174 174 $ rmdir .hg/blackbox.log
175 175 $ mv .hg/blackbox.log- .hg/blackbox.log
176 176
177 177 backup bundles get logged
178 178
179 179 $ touch d
180 180 $ hg commit -Amd
181 181 adding d
182 182 created new head
183 183 $ hg strip tip
184 184 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
185 185 saved backup bundle to $TESTTMP/blackboxtest2/.hg/strip-backup/*-backup.hg (glob)
186 186 $ hg blackbox -l 6
187 187 1970/01/01 00:00:00 bob @73f6ee326b27d820b0472f1a825e3a50f3dc489b (5000)> strip tip
188 188 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> saved backup bundle to $TESTTMP/blackboxtest2/.hg/strip-backup/73f6ee326b27-7612e004-backup.hg
189 189 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> updated base branch cache in * seconds (glob)
190 190 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> wrote base branch cache with 1 labels and 2 nodes
191 191 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> strip tip exited 0 after * seconds (glob)
192 192 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> blackbox -l 6
193 193
194 194 extension and python hooks - use the eol extension for a pythonhook
195 195
196 196 $ echo '[extensions]' >> .hg/hgrc
197 197 $ echo 'eol=' >> .hg/hgrc
198 198 $ echo '[hooks]' >> .hg/hgrc
199 199 $ echo 'update = echo hooked' >> .hg/hgrc
200 200 $ hg update
201 201 The fsmonitor extension is incompatible with the eol extension and has been disabled. (fsmonitor !)
202 202 hooked
203 203 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
204 204 updated to "d02f48003e62: c"
205 205 1 other heads for branch "default"
206 206 $ cat >> .hg/hgrc <<EOF
207 207 > [extensions]
208 208 > # disable eol, because it is not needed for subsequent tests
209 209 > # (in addition, keeping it requires extra care for fsmonitor)
210 210 > eol=!
211 211 > EOF
212 212 $ hg blackbox -l 5
213 213 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> update (no-chg !)
214 214 1970/01/01 00:00:00 bob @6563da9dcf87b1949716e38ff3e3dfaa3198eb06 (5000)> pythonhook-preupdate: hgext.eol.preupdate finished in * seconds (glob)
215 215 1970/01/01 00:00:00 bob @d02f48003e62c24e2659d97d30f2a83abe5d5d51 (5000)> exthook-update: echo hooked finished in * seconds (glob)
216 216 1970/01/01 00:00:00 bob @d02f48003e62c24e2659d97d30f2a83abe5d5d51 (5000)> update exited 0 after * seconds (glob)
217 217 1970/01/01 00:00:00 bob @d02f48003e62c24e2659d97d30f2a83abe5d5d51 (5000)> serve --cmdserver chgunix --address $TESTTMP.chgsock/server.* --daemon-postexec 'chdir:/' (glob) (chg !)
218 218 1970/01/01 00:00:00 bob @d02f48003e62c24e2659d97d30f2a83abe5d5d51 (5000)> blackbox -l 5
219 219
220 220 log rotation
221 221
222 222 $ echo '[blackbox]' >> .hg/hgrc
223 223 $ echo 'maxsize = 20 b' >> .hg/hgrc
224 224 $ echo 'maxfiles = 3' >> .hg/hgrc
225 225 $ hg status
226 226 $ hg status
227 227 $ hg status
228 228 $ hg tip -q
229 229 2:d02f48003e62
230 230 $ ls .hg/blackbox.log*
231 231 .hg/blackbox.log
232 232 .hg/blackbox.log.1
233 233 .hg/blackbox.log.2
234 234 $ cd ..
235 235
236 236 $ hg init blackboxtest3
237 237 $ cd blackboxtest3
238 238 $ hg blackbox
239 239 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> init blackboxtest3 exited 0 after * seconds (glob)
240 240 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> blackbox
241 241 $ mv .hg/blackbox.log .hg/blackbox.log-
242 242 $ mkdir .hg/blackbox.log
243 243 $ sed -e 's/\(.*test1.*\)/#\1/; s#\(.*commit2.*\)#os.rmdir(".hg/blackbox.log")\
244 244 > os.rename(".hg/blackbox.log-", ".hg/blackbox.log")\
245 245 > \1#' $TESTDIR/test-dispatch.py > ../test-dispatch.py
246 246 $ "$PYTHON" $TESTDIR/blackbox-readonly-dispatch.py
247 247 running: --debug add foo
248 248 warning: cannot write to blackbox.log: Is a directory (no-windows !)
249 249 warning: cannot write to blackbox.log: $TESTTMP/blackboxtest3/.hg/blackbox.log: Access is denied (windows !)
250 250 adding foo
251 251 result: 0
252 252 running: --debug commit -m commit1 -d 2000-01-01 foo
253 253 warning: cannot write to blackbox.log: Is a directory (no-windows !)
254 254 warning: cannot write to blackbox.log: $TESTTMP/blackboxtest3/.hg/blackbox.log: Access is denied (windows !)
255 255 committing files:
256 256 foo
257 257 committing manifest
258 258 committing changelog
259 259 updating the branch cache
260 260 committed changeset 0:0e46349438790c460c5c9f7546bfcd39b267bbd2
261 261 result: 0
262 262 running: --debug commit -m commit2 -d 2000-01-02 foo
263 263 committing files:
264 264 foo
265 265 committing manifest
266 266 committing changelog
267 267 updating the branch cache
268 268 committed changeset 1:45589e459b2edfbf3dbde7e01f611d2c1e7453d7
269 269 result: 0
270 270 running: --debug log -r 0
271 271 changeset: 0:0e46349438790c460c5c9f7546bfcd39b267bbd2
272 272 phase: draft
273 273 parent: -1:0000000000000000000000000000000000000000
274 274 parent: -1:0000000000000000000000000000000000000000
275 275 manifest: 0:9091aa5df980aea60860a2e39c95182e68d1ddec
276 276 user: test
277 277 date: Sat Jan 01 00:00:00 2000 +0000
278 278 files+: foo
279 279 extra: branch=default
280 280 description:
281 281 commit1
282 282
283 283
284 284 result: 0
285 285 running: --debug log -r tip
286 286 changeset: 1:45589e459b2edfbf3dbde7e01f611d2c1e7453d7
287 287 tag: tip
288 288 phase: draft
289 289 parent: 0:0e46349438790c460c5c9f7546bfcd39b267bbd2
290 290 parent: -1:0000000000000000000000000000000000000000
291 291 manifest: 1:895aa9b7886f89dd017a6d62524e1f9180b04df9
292 292 user: test
293 293 date: Sun Jan 02 00:00:00 2000 +0000
294 294 files: foo
295 295 extra: branch=default
296 296 description:
297 297 commit2
298 298
299 299
300 300 result: 0
301 301 $ hg blackbox
302 302 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> updating the branch cache
303 303 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> updated served branch cache in * seconds (glob)
304 304 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> wrote served branch cache with 1 labels and 1 nodes
305 305 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> --debug commit -m commit2 -d 2000-01-02 foo exited 0 after *.?? seconds (glob)
306 306 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> --debug log -r 0
307 307 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> writing .hg/cache/tags2-visible with 0 tags
308 308 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> --debug log -r 0 exited 0 after *.?? seconds (glob)
309 309 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> --debug log -r tip
310 310 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> --debug log -r tip exited 0 after *.?? seconds (glob)
311 311 1970/01/01 00:00:00 bob @45589e459b2edfbf3dbde7e01f611d2c1e7453d7 (5000)> blackbox
312 312
313 313 Test log recursion from dirty status check
314 314
315 315 $ cat > ../r.py <<EOF
316 316 > from mercurial import context, error, extensions
317 317 > x=[False]
318 318 > def status(orig, *args, **opts):
319 319 > args[0].repo().ui.log(b"broken", b"recursion?")
320 320 > return orig(*args, **opts)
321 321 > def reposetup(ui, repo):
322 322 > extensions.wrapfunction(context.basectx, 'status', status)
323 323 > EOF
324 324 $ hg id --config extensions.x=../r.py --config blackbox.dirty=True
325 325 45589e459b2e tip
326 326
327 327 cleanup
328 328 $ cd ..
329 329
330 Test missing log directory, which shouldn't be created automatically
331
332 $ cat <<'EOF' > closeremove.py
333 > def reposetup(ui, repo):
334 > class rmrepo(repo.__class__):
335 > def close(self):
336 > super(rmrepo, self).close()
337 > self.ui.debug(b'removing %s\n' % self.vfs.base)
338 > self.vfs.rmtree()
339 > repo.__class__ = rmrepo
340 > EOF
341
342 $ hg init gone
343 $ cd gone
344 $ cat <<'EOF' > .hg/hgrc
345 > [extensions]
346 > closeremove = ../closeremove.py
347 > EOF
348 $ hg log --debug
349 removing $TESTTMP/gone/.hg
350 warning: cannot write to blackbox.log: $ENOENT$
351 $ cd ..
352
330 353 #if chg
331 354
332 355 when using chg, blackbox.log should get rotated correctly
333 356
334 357 $ cat > $TESTTMP/noop.py << EOF
335 358 > from __future__ import absolute_import
336 359 > import time
337 360 > from mercurial import registrar, scmutil
338 361 > cmdtable = {}
339 362 > command = registrar.command(cmdtable)
340 363 > @command('noop')
341 364 > def noop(ui, repo):
342 365 > pass
343 366 > EOF
344 367
345 368 $ hg init blackbox-chg
346 369 $ cd blackbox-chg
347 370
348 371 $ cat > .hg/hgrc << EOF
349 372 > [blackbox]
350 373 > maxsize = 500B
351 374 > [extensions]
352 375 > # extension change forces chg to restart
353 376 > noop=$TESTTMP/noop.py
354 377 > EOF
355 378
356 379 $ "$PYTHON" -c 'print("a" * 400)' > .hg/blackbox.log
357 380 $ chg noop
358 381 $ chg noop
359 382 $ chg noop
360 383 $ chg noop
361 384 $ chg noop
362 385
363 386 $ cat > showsize.py << 'EOF'
364 387 > import os
365 388 > import sys
366 389 > limit = 500
367 390 > for p in sys.argv[1:]:
368 391 > size = os.stat(p).st_size
369 392 > if size >= limit:
370 393 > desc = '>='
371 394 > else:
372 395 > desc = '<'
373 396 > print('%s: %s %d' % (p, desc, limit))
374 397 > EOF
375 398
376 399 $ "$PYTHON" showsize.py .hg/blackbox*
377 400 .hg/blackbox.log: < 500
378 401 .hg/blackbox.log.1: >= 500
379 402 .hg/blackbox.log.2: >= 500
380 403
381 404 $ cd ..
382 405
383 406 With chg, blackbox should not create the log file if the repo is gone
384 407
385 408 $ hg init repo1
386 409 $ hg --config extensions.a=! -R repo1 log
387 410 $ rm -rf $TESTTMP/repo1
388 411 $ hg --config extensions.a=! init repo1
389 412
390 413 #endif
391 414
392 415 blackbox should work if repo.ui.log is not called (issue5518)
393 416
394 417 $ cat > $TESTTMP/raise.py << EOF
395 418 > from __future__ import absolute_import
396 419 > from mercurial import registrar, scmutil
397 420 > cmdtable = {}
398 421 > command = registrar.command(cmdtable)
399 422 > @command(b'raise')
400 423 > def raisecmd(*args):
401 424 > raise RuntimeError('raise')
402 425 > EOF
403 426
404 427 $ cat >> $HGRCPATH << EOF
405 428 > [blackbox]
406 429 > track = commandexception
407 430 > [extensions]
408 431 > raise=$TESTTMP/raise.py
409 432 > EOF
410 433
411 434 $ hg init $TESTTMP/blackbox-exception-only
412 435 $ cd $TESTTMP/blackbox-exception-only
413 436
414 437 #if chg
415 438 (chg exits 255 because it fails to receive an exit code)
416 439 $ hg raise 2>/dev/null
417 440 [255]
418 441 #else
419 442 (hg exits 1 because Python default exit code for uncaught exception is 1)
420 443 $ hg raise 2>/dev/null
421 444 [1]
422 445 #endif
423 446
424 447 $ head -1 .hg/blackbox.log
425 448 1970/01/01 00:00:00 bob @0000000000000000000000000000000000000000 (5000)> ** Unknown exception encountered with possibly-broken third-party extension mock
426 449 $ tail -2 .hg/blackbox.log
427 450 RuntimeError: raise
428 451
General Comments 0
You need to be logged in to leave comments. Login now