Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Q
QueryR
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Julien Lopez
QueryR
Commits
bdef5e6d
Commit
bdef5e6d
authored
8 years ago
by
Mick Jordan
Browse files
Options
Downloads
Patches
Plain Diff
Use Truffle TimeBoxing to timeout unit tests
parent
253ff760
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/generate/FastRSession.java
+68
-131
68 additions, 131 deletions
.../src/com/oracle/truffle/r/test/generate/FastRSession.java
with
68 additions
and
131 deletions
com.oracle.truffle.r.test/src/com/oracle/truffle/r/test/generate/FastRSession.java
+
68
−
131
View file @
bdef5e6d
...
@@ -26,11 +26,12 @@ import java.util.ArrayDeque;
...
@@ -26,11 +26,12 @@ import java.util.ArrayDeque;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
java.util.Deque
;
import
java.util.Deque
;
import
java.util.TimeZone
;
import
java.util.TimeZone
;
import
java.util.concurrent.Semaphore
;
import
java.util.Timer
;
import
java.util.concurrent.TimeUnit
;
import
java.util.TimerTask
;
import
java.util.concurrent.TimeoutException
;
import
com.oracle.truffle.api.CompilerDirectives.TruffleBoundary
;
import
com.oracle.truffle.api.CompilerDirectives.TruffleBoundary
;
import
com.oracle.truffle.api.debug.Debugger
;
import
com.oracle.truffle.api.debug.SuspendedCallback
;
import
com.oracle.truffle.api.debug.SuspendedEvent
;
import
com.oracle.truffle.api.source.Source
;
import
com.oracle.truffle.api.source.Source
;
import
com.oracle.truffle.api.vm.PolyglotEngine
;
import
com.oracle.truffle.api.vm.PolyglotEngine
;
import
com.oracle.truffle.r.runtime.RCmdOptions
;
import
com.oracle.truffle.r.runtime.RCmdOptions
;
...
@@ -133,8 +134,6 @@ public final class FastRSession implements RSession {
...
@@ -133,8 +134,6 @@ public final class FastRSession implements RSession {
private
final
PolyglotEngine
main
;
private
final
PolyglotEngine
main
;
private
final
RContext
mainContext
;
private
final
RContext
mainContext
;
private
EvalThread
evalThread
;
public
static
FastRSession
create
()
{
public
static
FastRSession
create
()
{
if
(
singleton
==
null
)
{
if
(
singleton
==
null
)
{
singleton
=
new
FastRSession
();
singleton
=
new
FastRSession
();
...
@@ -191,143 +190,81 @@ public final class FastRSession implements RSession {
...
@@ -191,143 +190,81 @@ public final class FastRSession implements RSession {
* {@link #eval} but also used for package installation via the {@code system2} command, where
* {@link #eval} but also used for package installation via the {@code system2} command, where
* the result is used to check whether the installation succeeded.
* the result is used to check whether the installation succeeded.
*/
*/
@SuppressWarnings
(
"deprecation"
)
public
Object
evalAsObject
(
TestBase
testClass
,
String
expression
,
ContextInfo
contextInfo
,
boolean
longTimeout
)
throws
Throwable
{
public
Object
evalAsObject
(
TestBase
testClass
,
String
expression
,
ContextInfo
contextInfo
,
boolean
longTimeout
)
throws
Throwable
{
Object
result
=
null
;
Timer
timer
=
null
;
consoleHandler
.
reset
();
consoleHandler
.
reset
();
EvalThread
thread
=
evalThread
;
if
(
thread
==
null
||
!
thread
.
isAlive
()
||
contextInfo
!=
thread
.
contextInfo
)
{
thread
=
new
EvalThread
(
contextInfo
);
thread
.
setName
(
"FastR evaluation"
);
thread
.
start
();
evalThread
=
thread
;
}
thread
.
push
(
testClass
,
expression
);
try
{
try
{
if
(!
thread
.
await
(
longTimeout
?
longTimeoutValue
:
timeoutValue
))
{
ContextInfo
actualContextInfo
=
checkContext
(
contextInfo
);
consoleHandler
.
println
(
"<timeout>"
);
// set up some interop objects used by fastr-specific tests:
System
.
out
.
println
(
"timeout in "
+
testClass
.
getClass
()
+
": "
+
expression
);
PolyglotEngine
.
Builder
builder
=
PolyglotEngine
.
newBuilder
();
for
(
StackTraceElement
element
:
thread
.
getStackTrace
())
{
if
(
testClass
!=
null
)
{
System
.
out
.
println
(
element
);
testClass
.
addPolyglotSymbols
(
builder
);
}
thread
.
stop
();
evalThread
.
ensureContextDestroyed
();
evalThread
=
null
;
throw
new
TimeoutException
();
}
}
}
catch
(
InterruptedException
e1
)
{
PolyglotEngine
vm
=
actualContextInfo
.
createVM
(
builder
);
e1
.
printStackTrace
();
timer
=
scheduleTimeBoxing
(
vm
,
longTimeout
?
longTimeoutValue
:
timeoutValue
);
}
consoleHandler
.
setInput
(
expression
.
split
(
"\n"
));
if
(
thread
.
killedByException
!=
null
)
{
try
{
evalThread
=
null
;
String
input
=
consoleHandler
.
readLine
();
throw
thread
.
killedByException
;
while
(
input
!=
null
)
{
}
Source
source
=
RSource
.
fromTextInternal
(
input
,
RSource
.
Internal
.
UNIT_TEST
);
return
evalThread
.
result
;
}
private
final
class
EvalThread
extends
RContext
.
ContextThread
{
private
volatile
String
expression
;
private
volatile
Throwable
killedByException
;
private
final
Semaphore
entry
=
new
Semaphore
(
0
);
private
final
Semaphore
exit
=
new
Semaphore
(
0
);
private
final
ContextInfo
contextInfo
;
private
TestBase
testClass
;
private
Object
result
;
/**
* Create an evaluation thread (to handle timeouts).
*
* @param contextInfo {@code null} for a lightweight test context, else an existing one to
* use.
*/
EvalThread
(
ContextInfo
contextInfo
)
{
super
(
null
);
this
.
contextInfo
=
contextInfo
;
setDaemon
(
true
);
}
public
void
push
(
TestBase
testClassArg
,
String
exp
)
{
this
.
expression
=
exp
;
this
.
testClass
=
testClassArg
;
this
.
entry
.
release
();
}
public
boolean
await
(
int
millisTimeout
)
throws
InterruptedException
{
return
exit
.
tryAcquire
(
millisTimeout
,
TimeUnit
.
MILLISECONDS
);
}
/**
* In case the vm is not disposed by the {@code finally} clause in run after a timeout,
* (which should not happen), we explicitly destroy the context, to avoid subsequent errors
* relating to multiple children of a single SHARED_RW context.
*/
public
void
ensureContextDestroyed
()
{
context
.
destroy
();
}
@Override
public
void
run
()
{
while
(
killedByException
==
null
)
{
try
{
entry
.
acquire
();
}
catch
(
InterruptedException
e
)
{
break
;
}
try
{
ContextInfo
actualContextInfo
=
checkContext
(
contextInfo
);
// set up some interop objects used by fastr-specific tests:
PolyglotEngine
.
Builder
builder
=
PolyglotEngine
.
newBuilder
();
if
(
testClass
!=
null
)
{
testClass
.
addPolyglotSymbols
(
builder
);
}
PolyglotEngine
vm
=
actualContextInfo
.
createVM
(
builder
);
consoleHandler
.
setInput
(
expression
.
split
(
"\n"
));
try
{
try
{
String
input
=
consoleHandler
.
readLine
();
try
{
while
(
input
!=
null
)
{
result
=
vm
.
eval
(
source
).
get
();
Source
source
=
RSource
.
fromTextInternal
(
input
,
RSource
.
Internal
.
UNIT_TEST
);
// checked exceptions are wrapped in RuntimeExceptions
try
{
}
catch
(
RuntimeException
e
)
{
try
{
if
(
e
.
getCause
()
instanceof
com
.
oracle
.
truffle
.
api
.
vm
.
IncompleteSourceException
)
{
result
=
vm
.
eval
(
source
).
get
();
throw
e
.
getCause
().
getCause
();
// checked exceptions are wrapped in RuntimeExceptions
}
else
{
}
catch
(
RuntimeException
e
)
{
throw
e
;
if
(
e
.
getCause
()
instanceof
com
.
oracle
.
truffle
.
api
.
vm
.
IncompleteSourceException
)
{
throw
e
.
getCause
().
getCause
();
}
else
{
throw
e
;
}
}
input
=
consoleHandler
.
readLine
();
}
catch
(
IncompleteSourceException
e
)
{
String
additionalInput
=
consoleHandler
.
readLine
();
if
(
additionalInput
==
null
)
{
throw
e
;
}
input
+=
"\n"
+
additionalInput
;
}
}
}
}
}
finally
{
input
=
consoleHandler
.
readLine
();
vm
.
dispose
();
}
catch
(
IncompleteSourceException
e
)
{
}
String
additionalInput
=
consoleHandler
.
readLine
();
}
catch
(
ParseException
e
)
{
if
(
additionalInput
==
null
)
{
e
.
report
(
consoleHandler
);
throw
e
;
}
catch
(
RError
e
)
{
// nothing to do
}
catch
(
Throwable
t
)
{
if
(!
TestBase
.
ProcessFailedTests
)
{
if
(
t
instanceof
RInternalError
)
{
RInternalError
.
reportError
(
t
);
}
}
t
.
printStackTrace
()
;
input
+=
"\n"
+
additionalInput
;
}
}
killedByException
=
t
;
}
finally
{
exit
.
release
();
}
}
}
finally
{
vm
.
dispose
();
}
}
catch
(
ParseException
e
)
{
e
.
report
(
consoleHandler
);
}
catch
(
RError
e
)
{
// nothing to do
}
catch
(
Throwable
t
)
{
if
(!
TestBase
.
ProcessFailedTests
)
{
if
(
t
instanceof
RInternalError
)
{
RInternalError
.
reportError
(
t
);
}
t
.
printStackTrace
();
}
throw
t
;
}
finally
{
if
(
timer
!=
null
)
{
timer
.
cancel
();
}
}
}
}
return
result
;
}
private
static
Timer
scheduleTimeBoxing
(
PolyglotEngine
engine
,
long
timeout
)
{
Timer
timer
=
new
Timer
();
timer
.
schedule
(
new
TimerTask
()
{
@Override
public
void
run
()
{
Debugger
.
find
(
engine
).
startSession
(
new
SuspendedCallback
()
{
@Override
public
void
onSuspend
(
SuspendedEvent
event
)
{
event
.
prepareKill
();
}
}).
suspendNextExecution
();
}
},
timeout
);
return
timer
;
}
}
@Override
@Override
...
...
This diff is collapsed.
Click to expand it.
Julien Lopez
@jlopez
mentioned in commit
e598e2f1
·
8 years ago
mentioned in commit
e598e2f1
mentioned in commit e598e2f11b1a5bb04a5f6efe77fa9c0a6cd4a808
Toggle commit list
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment