On 26 July 2011 20:40, Stéphane Ducasse <[email protected]> wrote:
> may be I'm wrong but should:notTakeMoreThan: does not tell me that it is 
> forking a process.
> So I would prefer it does not.
>
It forks a process, because if code under the question takes forever
to evaluate,
you cannot stop it unless using another process who watching over it.

   evaluationProcess := [
        result := aBlock value.
        evaluated := true.
        delay unschedule.
        testProcess resume ] forkNamed: 'Process to evaluate should:
notTakeMoreThanMilliseconds:'.

>
> On Jul 26, 2011, at 7:06 PM, Igor Stasenko wrote:
>
>> 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.
>>
>
>
>



-- 
Best regards,
Igor Stasenko AKA sig.

Reply via email to