It forks a process for evaluating a block you passing.
And it works quite well if there's no exception during block evaluation..
but if there is, then it signals the TestFailure exception, not in a
process who waits test to be finished,
but in a process which forked.
And then since there is no exception handler, it using default action,
which just to open a debugger.
In headless mode it leads to immediate quit from image and logging
error report.
Like following:
THERE_BE_DRAGONS_HERE
MessageNotUnderstood:
NonInteractiveUIManager>>openDebuggerOn:context:label:contents:fullView:
26 July 2011 6:35:08 pm
VM: unix - i686 - linux-gnu - Croquet Closure Cog VM [CoInterpreter
VMMaker-oscog-IgorStasenko.108]
Image: Pharo1.4a [Latest update: #14025]
NonInteractiveUIManager(Object)>>doesNotUnderstand:
#openDebuggerOn:context:label:contents:fullView:
Receiver: a NonInteractiveUIManager
Arguments and temporary variables:
aMessage: openDebuggerOn: a Process in nil context:
MethodContextTest(TestCase)...etc...
exception: MessageNotUnderstood:
NonInteractiveUIManager>>openDebuggerOn:contex...etc...
resumeValue: nil
Receiver's instance variables:
uiManager: a MorphicUIManager
doNotQuitOnRestart: false
Debugger class>>openOn:context:label:contents:fullView:
Receiver: Debugger
Arguments and temporary variables:
process: a Process in nil
context: MethodContextTest(TestCase)>>signalFailure:
title: 'TestFailure: Assertion failed'
contentsStringOrNil: nil
bool: false
fullView: false
Receiver's instance variables:
superclass: CodeHolder
methodDict: a
MethodDictionary(#addOptionalButtonsTo:at:plus:->(Debugger>>#addO...etc...
format: 168
instanceVariables: #('interruptedProcess'
'interruptedController'
'contextStack...etc...
organization: ('*Polymorph-Widgets'
addOptionalButtonsTo:at:plus:
buildMorphicN...etc...
subclasses: nil
name: #Debugger
classPool: a Dictionary(#AlwaysOpenFullDebugger->false
#ContextStackKeystrokes-...etc...
sharedPools: nil
environment: a SystemDictionary(lots of globals)
category: #'Tools-Debugger'
traitComposition: {}
localSelectors: nil
[:tool | ^ tool
openOn: aProcess
context: aContext
label: aString
contents: contents
fullView: aBool] in
ToolRegistry>>debug:context:label:contents:fullView:
Receiver: a ToolRegistry
Arguments and temporary variables:
aProcess: Debugger
aContext: a Process in nil
aString: MethodContextTest(TestCase)>>signalFailure:
contents: 'TestFailure: Assertion failed'
aBool: nil
tool: false
Receiver's instance variables:
tools: an IdentityDictionary(#basicInspector->BasicInspector
#browser->[self de...etc...
inspectorsMap: an
IdentityDictionary(#CompiledMethod->#CompiledMethodInspector ...etc...
ToolRegistry>>using:do:
Receiver: a ToolRegistry
Arguments and temporary variables:
aToolName: #debugger
aBlock: [:tool | ^ tool
openOn: aProcess
context: aContext
label: aString...etc...
tool: Debugger
Receiver's instance variables:
tools: an IdentityDictionary(#basicInspector->BasicInspector
#browser->[self de...etc...
inspectorsMap: an
IdentityDictionary(#CompiledMethod->#CompiledMethodInspector ...etc...
ToolRegistry>>debug:context:label:contents:fullView:
Receiver: a ToolRegistry
Arguments and temporary variables:
aProcess: a Process in nil
aContext: MethodContextTest(TestCase)>>signalFailure:
aString: 'TestFailure: Assertion failed'
contents: nil
aBool: false
Receiver's instance variables:
tools: an IdentityDictionary(#basicInspector->BasicInspector
#browser->[self de...etc...
inspectorsMap: an
IdentityDictionary(#CompiledMethod->#CompiledMethodInspector ...etc...
Process>>debug:title:full:
Receiver: a Process in nil
Arguments and temporary variables:
context: MethodContextTest(TestCase)>>signalFailure:
title: 'TestFailure: Assertion failed'
bool: false
topCtxt: Process>>debug:title:full:
Receiver's instance variables:
nextLink: nil
suspendedContext: nil
priority: 40
myList: nil
threadId: nil
errorHandler: nil
name: 'Process to evaluate should:
notTakeMoreThanMilliseconds:'
env: nil
Process>>debug:title:
Receiver: a Process in nil
Arguments and temporary variables:
context: MethodContextTest(TestCase)>>signalFailure:
title: 'TestFailure: Assertion failed'
Receiver's instance variables:
nextLink: nil
suspendedContext: nil
priority: 40
myList: nil
threadId: nil
errorHandler: nil
name: 'Process to evaluate should:
notTakeMoreThanMilliseconds:'
env: nil
TestFailure>>defaultAction
Receiver: TestFailure: Assertion failed
Arguments and temporary variables:
Receiver's instance variables:
messageText: 'Assertion failed'
tag: nil
signaler: MethodContextTest>>#testClosureRestart
signalContext: TestFailure(Exception)>>signal
handlerContext: nil
outerContext: nil
....
This happens when you run a
MethodContextTest>>#testClosureRestart
on Cog VM.
Why it fails is another story :)
But we need to fix the tester somehow, in order to continue running
rest of tests instead of quitting to OS.
The problem is that "aBlock value" which signals the exception should
be wrapped by exception handler.
And then #should:notTakeMoreThan: should report that exception to the
main process which runs the test.
So, a failure would be either due to timeout or due to failing running
the code without exceptions.
Any suggestions?
--
Best regards,
Igor Stasenko AKA sig.