Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
308dbf32
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
3
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
308dbf32
编写于
3月 29, 2014
作者:
I
iignatyev
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8038186: [TESTBUG] improvements of test j.l.i.MethodHandles
Reviewed-by: iveresov, twisti, vlivanov
上级
0f6f7e79
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
846 addition
and
102 deletion
+846
-102
test/java/lang/invoke/MethodHandles/CatchExceptionTest.java
test/java/lang/invoke/MethodHandles/CatchExceptionTest.java
+542
-0
test/java/lang/invoke/MethodHandlesTest.java
test/java/lang/invoke/MethodHandlesTest.java
+0
-102
test/lib/testlibrary/jdk/testlibrary/Asserts.java
test/lib/testlibrary/jdk/testlibrary/Asserts.java
+28
-0
test/lib/testlibrary/jsr292/com/oracle/testlibrary/jsr292/Helper.java
...tlibrary/jsr292/com/oracle/testlibrary/jsr292/Helper.java
+276
-0
未找到文件。
test/java/lang/invoke/MethodHandles/CatchExceptionTest.java
0 → 100644
浏览文件 @
308dbf32
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package
test.java.lang.invoke.MethodHandles
;
import
com.oracle.testlibrary.jsr292.Helper
;
import
jdk.testlibrary.Asserts
;
import
java.lang.invoke.MethodHandle
;
import
java.lang.invoke.MethodHandles
;
import
java.lang.invoke.MethodType
;
import
java.lang.reflect.Array
;
import
java.util.*
;
import
java.util.function.BiFunction
;
import
java.util.function.Function
;
import
java.util.function.Supplier
;
/* @test
* @library /lib/testlibrary/jsr292 /lib/testlibrary/
* @compile CatchExceptionTest.java
* @run main/othervm -esa test.java.lang.invoke.MethodHandles.CatchExceptionTest
*/
public
class
CatchExceptionTest
{
private
static
final
List
<
Class
<?>>
ARGS_CLASSES
;
protected
static
final
int
MAX_ARITY
=
Helper
.
MAX_ARITY
-
1
;
static
{
Class
<?>
classes
[]
=
{
Object
.
class
,
long
.
class
,
int
.
class
,
byte
.
class
,
Integer
[].
class
,
double
[].
class
,
String
.
class
,
};
List
<
Class
<?>>
list
=
new
ArrayList
<>(
MAX_ARITY
);
for
(
int
i
=
0
;
i
<
MAX_ARITY
;
++
i
)
{
list
.
add
(
classes
[
Helper
.
RNG
.
nextInt
(
classes
.
length
)]);
}
ARGS_CLASSES
=
Collections
.
unmodifiableList
(
list
);
}
private
final
TestCase
testCase
;
private
final
int
nargs
;
private
final
int
argsCount
;
private
final
MethodHandle
catcher
;
private
int
dropped
;
private
MethodHandle
thrower
;
public
CatchExceptionTest
(
TestCase
testCase
,
final
boolean
isVararg
,
final
int
argsCount
,
final
int
catchDrops
)
{
this
.
testCase
=
testCase
;
this
.
dropped
=
catchDrops
;
if
(
Helper
.
IS_VERBOSE
)
{
System
.
out
.
printf
(
"CatchException::CatchException(%s, isVararg=%b "
+
"argsCount=%d catchDrops=%d)%n"
,
testCase
,
isVararg
,
argsCount
,
catchDrops
);
}
MethodHandle
thrower
=
testCase
.
thrower
;
int
throwerLen
=
thrower
.
type
().
parameterCount
();
List
<
Class
<?>>
classes
;
int
extra
=
Math
.
max
(
0
,
argsCount
-
throwerLen
);
classes
=
getThrowerParams
(
isVararg
,
extra
);
this
.
argsCount
=
throwerLen
+
classes
.
size
();
thrower
=
Helper
.
addTrailingArgs
(
thrower
,
this
.
argsCount
,
classes
);
if
(
isVararg
&&
argsCount
>
throwerLen
)
{
MethodType
mt
=
thrower
.
type
();
Class
<?>
lastParam
=
mt
.
parameterType
(
mt
.
parameterCount
()
-
1
);
thrower
=
thrower
.
asVarargsCollector
(
lastParam
);
}
this
.
thrower
=
thrower
;
this
.
dropped
=
Math
.
min
(
this
.
argsCount
,
catchDrops
);
catcher
=
testCase
.
getCatcher
(
getCatcherParams
());
nargs
=
Math
.
max
(
2
,
this
.
argsCount
);
}
public
static
void
main
(
String
[]
args
)
throws
Throwable
{
for
(
CatchExceptionTest
test
:
TestFactory
.
MANDATORY_TEST_CASES
)
{
test
.
runTest
();
}
TestFactory
factory
=
new
TestFactory
();
CatchExceptionTest
test
;
while
((
test
=
factory
.
nextTest
())
!=
null
)
{
test
.
runTest
();
}
}
private
List
<
Class
<?>>
getThrowerParams
(
boolean
isVararg
,
int
argsCount
)
{
boolean
unmodifiable
=
true
;
List
<
Class
<?>>
classes
;
classes
=
ARGS_CLASSES
.
subList
(
0
,
Math
.
min
(
argsCount
,
(
MAX_ARITY
/
2
)
-
1
));
int
extra
=
0
;
if
(
argsCount
>=
MAX_ARITY
/
2
)
{
classes
=
new
ArrayList
<>(
classes
);
unmodifiable
=
false
;
extra
=
(
int
)
classes
.
stream
().
filter
(
Helper:
:
isDoubleCost
).
count
();
int
i
=
classes
.
size
();
while
(
classes
.
size
()
+
extra
<
argsCount
)
{
Class
<?>
aClass
=
ARGS_CLASSES
.
get
(
i
);
if
(
Helper
.
isDoubleCost
(
aClass
))
{
++
extra
;
if
(
classes
.
size
()
+
extra
>=
argsCount
)
{
break
;
}
}
classes
.
add
(
aClass
);
}
}
if
(
isVararg
&&
classes
.
size
()
>
0
)
{
if
(
unmodifiable
)
{
classes
=
new
ArrayList
<>(
classes
);
}
int
last
=
classes
.
size
()
-
1
;
Class
<?>
aClass
=
classes
.
get
(
classes
.
size
()
-
1
);
aClass
=
Array
.
newInstance
(
aClass
,
2
).
getClass
();
classes
.
set
(
last
,
aClass
);
}
return
classes
;
}
private
List
<
Class
<?>>
getCatcherParams
()
{
int
catchArgc
=
1
+
this
.
argsCount
-
dropped
;
List
<
Class
<?>>
result
=
new
ArrayList
<>(
thrower
.
type
().
parameterList
().
subList
(
0
,
catchArgc
-
1
));
// prepend throwable
result
.
add
(
0
,
testCase
.
throwableClass
);
return
result
;
}
private
void
runTest
()
{
Helper
.
clear
();
Object
[]
args
=
Helper
.
randomArgs
(
argsCount
,
thrower
.
type
().
parameterArray
());
Object
arg0
=
Helper
.
MISSING_ARG
;
Object
arg1
=
testCase
.
thrown
;
if
(
argsCount
>
0
)
{
arg0
=
args
[
0
];
}
if
(
argsCount
>
1
)
{
args
[
1
]
=
arg1
;
}
Asserts
.
assertEQ
(
nargs
,
thrower
.
type
().
parameterCount
());
if
(
argsCount
<
nargs
)
{
Object
[]
appendArgs
=
{
arg0
,
arg1
};
appendArgs
=
Arrays
.
copyOfRange
(
appendArgs
,
argsCount
,
nargs
);
thrower
=
MethodHandles
.
insertArguments
(
thrower
,
argsCount
,
appendArgs
);
}
Asserts
.
assertEQ
(
argsCount
,
thrower
.
type
().
parameterCount
());
MethodHandle
target
=
MethodHandles
.
catchException
(
testCase
.
filter
(
thrower
),
testCase
.
throwableClass
,
testCase
.
filter
(
catcher
));
Asserts
.
assertEQ
(
thrower
.
type
(),
target
.
type
());
Asserts
.
assertEQ
(
argsCount
,
target
.
type
().
parameterCount
());
Object
returned
;
try
{
returned
=
target
.
invokeWithArguments
(
args
);
}
catch
(
Throwable
ex
)
{
testCase
.
assertCatch
(
ex
);
returned
=
ex
;
}
testCase
.
assertReturn
(
returned
,
arg0
,
arg1
,
dropped
,
args
);
}
}
class
TestFactory
{
public
static
final
List
<
CatchExceptionTest
>
MANDATORY_TEST_CASES
=
new
ArrayList
<>();
private
static
final
int
MIN_TESTED_ARITY
=
10
;
static
{
for
(
int
[]
args
:
new
int
[][]{
{
0
,
0
},
{
MIN_TESTED_ARITY
,
0
},
{
MIN_TESTED_ARITY
,
MIN_TESTED_ARITY
},
{
CatchExceptionTest
.
MAX_ARITY
,
0
},
{
CatchExceptionTest
.
MAX_ARITY
,
CatchExceptionTest
.
MAX_ARITY
},
})
{
MANDATORY_TEST_CASES
.
addAll
(
createTests
(
args
[
0
],
args
[
1
]));
}
}
private
int
count
;
private
int
args
;
private
int
dropArgs
;
private
int
currentMaxDrops
;
private
int
maxArgs
;
private
int
maxDrops
;
private
int
constructor
;
private
int
constructorSize
;
private
boolean
isVararg
;
public
TestFactory
()
{
if
(
Helper
.
IS_THOROUGH
)
{
maxArgs
=
maxDrops
=
CatchExceptionTest
.
MAX_ARITY
;
}
else
{
maxArgs
=
MIN_TESTED_ARITY
+
Helper
.
RNG
.
nextInt
(
CatchExceptionTest
.
MAX_ARITY
-
MIN_TESTED_ARITY
)
+
1
;
maxDrops
=
MIN_TESTED_ARITY
+
Helper
.
RNG
.
nextInt
(
maxArgs
-
MIN_TESTED_ARITY
)
+
1
;
args
=
1
;
}
if
(
Helper
.
IS_VERBOSE
)
{
System
.
out
.
printf
(
"maxArgs = %d%nmaxDrops = %d%n"
,
maxArgs
,
maxDrops
);
}
constructorSize
=
TestCase
.
CONSTRUCTORS
.
size
();
}
private
static
List
<
CatchExceptionTest
>
createTests
(
int
argsCount
,
int
catchDrops
)
{
if
(
catchDrops
>
argsCount
||
argsCount
<
0
||
catchDrops
<
0
)
{
throw
new
IllegalArgumentException
(
"argsCount = "
+
argsCount
+
", catchDrops = "
+
catchDrops
);
}
List
<
CatchExceptionTest
>
result
=
new
ArrayList
<>(
TestCase
.
CONSTRUCTORS
.
size
());
for
(
Supplier
<
TestCase
>
constructor
:
TestCase
.
CONSTRUCTORS
)
{
result
.
add
(
new
CatchExceptionTest
(
constructor
.
get
(),
/* isVararg = */
true
,
argsCount
,
catchDrops
));
result
.
add
(
new
CatchExceptionTest
(
constructor
.
get
(),
/* isVararg = */
false
,
argsCount
,
catchDrops
));
}
return
result
;
}
/**
* @return next test from test matrix:
* {varArgs, noVarArgs} x TestCase.rtypes x TestCase.THROWABLES x {1, .., maxArgs } x {1, .., maxDrops}
*/
public
CatchExceptionTest
nextTest
()
{
if
(
constructor
<
constructorSize
)
{
return
createTest
();
}
constructor
=
0
;
count
++;
if
(!
Helper
.
IS_THOROUGH
&&
count
>
Helper
.
TEST_LIMIT
)
{
System
.
out
.
println
(
"test limit is exceeded"
);
return
null
;
}
if
(
dropArgs
<=
currentMaxDrops
)
{
if
(
dropArgs
==
1
)
{
if
(
Helper
.
IS_THOROUGH
||
Helper
.
RNG
.
nextBoolean
())
{
++
dropArgs
;
return
createTest
();
}
else
if
(
Helper
.
IS_VERBOSE
)
{
System
.
out
.
printf
(
"argsCount=%d : \"drop\" scenarios are skipped%n"
,
args
);
}
}
else
{
++
dropArgs
;
return
createTest
();
}
}
if
(
args
<=
maxArgs
)
{
dropArgs
=
1
;
currentMaxDrops
=
Math
.
min
(
args
,
maxDrops
);
++
args
;
return
createTest
();
}
return
null
;
}
private
CatchExceptionTest
createTest
()
{
if
(!
Helper
.
IS_THOROUGH
)
{
return
new
CatchExceptionTest
(
TestCase
.
CONSTRUCTORS
.
get
(
constructor
++).
get
(),
Helper
.
RNG
.
nextBoolean
(),
args
,
dropArgs
);
}
else
{
if
(
isVararg
)
{
isVararg
=
false
;
return
new
CatchExceptionTest
(
TestCase
.
CONSTRUCTORS
.
get
(
constructor
++).
get
(),
isVararg
,
args
,
dropArgs
);
}
else
{
isVararg
=
true
;
return
new
CatchExceptionTest
(
TestCase
.
CONSTRUCTORS
.
get
(
constructor
).
get
(),
isVararg
,
args
,
dropArgs
);
}
}
}
}
class
TestCase
<
T
>
{
private
static
enum
ThrowMode
{
NOTHING
,
CAUGHT
,
UNCAUGHT
,
ADAPTER
}
@SuppressWarnings
(
"unchecked"
)
public
static
final
List
<
Supplier
<
TestCase
>>
CONSTRUCTORS
;
private
static
final
MethodHandle
FAKE_IDENTITY
;
private
static
final
MethodHandle
THROW_OR_RETURN
;
private
static
final
MethodHandle
CATCHER
;
static
{
try
{
MethodHandles
.
Lookup
lookup
=
MethodHandles
.
lookup
();
THROW_OR_RETURN
=
lookup
.
findStatic
(
TestCase
.
class
,
"throwOrReturn"
,
MethodType
.
methodType
(
Object
.
class
,
Object
.
class
,
Throwable
.
class
)
);
CATCHER
=
lookup
.
findStatic
(
TestCase
.
class
,
"catcher"
,
MethodType
.
methodType
(
Object
.
class
,
Object
.
class
));
FAKE_IDENTITY
=
lookup
.
findVirtual
(
TestCase
.
class
,
"fakeIdentity"
,
MethodType
.
methodType
(
Object
.
class
,
Object
.
class
));
}
catch
(
NoSuchMethodException
|
IllegalAccessException
e
)
{
throw
new
Error
(
e
);
}
PartialConstructor
[]
constructors
=
{
create
(
Object
.
class
,
Object
.
class
::
cast
),
create
(
String
.
class
,
Objects:
:
toString
),
create
(
int
[].
class
,
x
->
new
int
[]{
Objects
.
hashCode
(
x
)}),
create
(
long
.
class
,
x
->
Objects
.
hashCode
(
x
)
&
(-
1L
>>>
32
)),
create
(
void
.
class
,
TestCase:
:
noop
)};
Throwable
[]
throwables
=
{
new
ClassCastException
(
"testing"
),
new
java
.
io
.
IOException
(
"testing"
),
new
LinkageError
(
"testing"
)};
List
<
Supplier
<
TestCase
>>
list
=
new
ArrayList
<>(
constructors
.
length
*
throwables
.
length
*
ThrowMode
.
values
().
length
);
//noinspection unchecked
for
(
PartialConstructor
f
:
constructors
)
{
for
(
ThrowMode
mode
:
ThrowMode
.
values
())
{
for
(
Throwable
t
:
throwables
)
{
list
.
add
(
f
.
apply
(
mode
,
t
));
}
}
}
CONSTRUCTORS
=
Collections
.
unmodifiableList
(
list
);
}
public
final
Class
<
T
>
rtype
;
public
final
ThrowMode
throwMode
;
public
final
Throwable
thrown
;
public
final
Class
<?
extends
Throwable
>
throwableClass
;
/**
* MH which takes 2 args (Object,Throwable), 1st is the return value,
* 2nd is the exception which will be thrown, if it's supposed in current
* {@link #throwMode}.
*/
public
final
MethodHandle
thrower
;
private
final
Function
<
Object
,
T
>
cast
;
protected
MethodHandle
filter
;
private
int
fakeIdentityCount
;
private
TestCase
(
Class
<
T
>
rtype
,
Function
<
Object
,
T
>
cast
,
ThrowMode
throwMode
,
Throwable
thrown
)
throws
NoSuchMethodException
,
IllegalAccessException
{
this
.
cast
=
cast
;
filter
=
MethodHandles
.
lookup
().
findVirtual
(
Function
.
class
,
"apply"
,
MethodType
.
methodType
(
Object
.
class
,
Object
.
class
))
.
bindTo
(
cast
);
this
.
rtype
=
rtype
;
this
.
throwMode
=
throwMode
;
this
.
throwableClass
=
thrown
.
getClass
();
switch
(
throwMode
)
{
case
NOTHING:
this
.
thrown
=
null
;
break
;
case
ADAPTER:
case
UNCAUGHT:
this
.
thrown
=
new
Error
(
"do not catch this"
);
break
;
default
:
this
.
thrown
=
thrown
;
}
MethodHandle
throwOrReturn
=
THROW_OR_RETURN
;
if
(
throwMode
==
ThrowMode
.
ADAPTER
)
{
MethodHandle
fakeIdentity
=
FAKE_IDENTITY
.
bindTo
(
this
);
for
(
int
i
=
0
;
i
<
10
;
++
i
)
{
throwOrReturn
=
MethodHandles
.
filterReturnValue
(
throwOrReturn
,
fakeIdentity
);
}
}
thrower
=
throwOrReturn
.
asType
(
MethodType
.
genericMethodType
(
2
));
}
private
static
Void
noop
(
Object
x
)
{
return
null
;
}
private
static
<
T2
>
PartialConstructor
create
(
Class
<
T2
>
rtype
,
Function
<
Object
,
T2
>
cast
)
{
return
(
t
,
u
)
->
()
->
{
try
{
return
new
TestCase
<>(
rtype
,
cast
,
t
,
u
);
}
catch
(
NoSuchMethodException
|
IllegalAccessException
e
)
{
throw
new
Error
(
e
);
}
};
}
private
static
<
T
extends
Throwable
>
Object
throwOrReturn
(
Object
normal
,
T
exception
)
throws
T
{
if
(
exception
!=
null
)
{
Helper
.
called
(
"throwOrReturn/throw"
,
normal
,
exception
);
throw
exception
;
}
Helper
.
called
(
"throwOrReturn/normal"
,
normal
,
exception
);
return
normal
;
}
private
static
<
T
extends
Throwable
>
Object
catcher
(
Object
o
)
{
Helper
.
called
(
"catcher"
,
o
);
return
o
;
}
public
MethodHandle
filter
(
MethodHandle
target
)
{
return
MethodHandles
.
filterReturnValue
(
target
,
filter
);
}
public
MethodHandle
getCatcher
(
List
<
Class
<?>>
classes
)
{
return
MethodHandles
.
filterReturnValue
(
Helper
.
AS_LIST
.
asType
(
MethodType
.
methodType
(
Object
.
class
,
classes
)),
CATCHER
);
}
@Override
public
String
toString
()
{
return
"TestCase{"
+
"rtype="
+
rtype
+
", throwMode="
+
throwMode
+
", throwableClass="
+
throwableClass
+
'}'
;
}
public
String
callName
()
{
return
"throwOrReturn/"
+
(
throwMode
==
ThrowMode
.
NOTHING
?
"normal"
:
"throw"
);
}
public
void
assertReturn
(
Object
returned
,
Object
arg0
,
Object
arg1
,
int
catchDrops
,
Object
...
args
)
{
int
lag
=
0
;
if
(
throwMode
==
ThrowMode
.
CAUGHT
)
{
lag
=
1
;
}
Helper
.
assertCalled
(
lag
,
callName
(),
arg0
,
arg1
);
if
(
throwMode
==
ThrowMode
.
NOTHING
)
{
assertEQ
(
cast
.
apply
(
arg0
),
returned
);
}
else
if
(
throwMode
==
ThrowMode
.
CAUGHT
)
{
List
<
Object
>
catchArgs
=
new
ArrayList
<>(
Arrays
.
asList
(
args
));
// catcher receives an initial subsequence of target arguments:
catchArgs
.
subList
(
args
.
length
-
catchDrops
,
args
.
length
).
clear
();
// catcher also receives the exception, prepended:
catchArgs
.
add
(
0
,
thrown
);
Helper
.
assertCalled
(
"catcher"
,
catchArgs
);
assertEQ
(
cast
.
apply
(
catchArgs
),
returned
);
}
Asserts
.
assertEQ
(
0
,
fakeIdentityCount
);
}
private
void
assertEQ
(
T
t
,
Object
returned
)
{
if
(
rtype
.
isArray
())
{
Asserts
.
assertEQ
(
t
.
getClass
(),
returned
.
getClass
());
int
n
=
Array
.
getLength
(
t
);
Asserts
.
assertEQ
(
n
,
Array
.
getLength
(
returned
));
for
(
int
i
=
0
;
i
<
n
;
++
i
)
{
Asserts
.
assertEQ
(
Array
.
get
(
t
,
i
),
Array
.
get
(
returned
,
i
));
}
}
else
{
Asserts
.
assertEQ
(
t
,
returned
);
}
}
private
Object
fakeIdentity
(
Object
x
)
{
System
.
out
.
println
(
"should throw through this!"
);
++
fakeIdentityCount
;
return
x
;
}
public
void
assertCatch
(
Throwable
ex
)
{
try
{
Asserts
.
assertSame
(
thrown
,
ex
,
"must get the out-of-band exception"
);
}
catch
(
Throwable
t
)
{
ex
.
printStackTrace
();
}
}
public
interface
PartialConstructor
extends
BiFunction
<
ThrowMode
,
Throwable
,
Supplier
<
TestCase
>>
{
}
}
test/java/lang/invoke/MethodHandlesTest.java
浏览文件 @
308dbf32
...
...
@@ -2405,108 +2405,6 @@ public class MethodHandlesTest {
}
}
@Test
public
void
testCatchException
()
throws
Throwable
{
if
(
CAN_SKIP_WORKING
)
return
;
startTest
(
"catchException"
);
for
(
int
nargs
=
0
;
nargs
<
40
;
nargs
++)
{
if
(
CAN_TEST_LIGHTLY
&&
nargs
>
11
)
break
;
for
(
int
throwMode
=
0
;
throwMode
<
THROW_MODE_LIMIT
;
throwMode
++)
{
testCatchException
(
int
.
class
,
new
ClassCastException
(
"testing"
),
throwMode
,
nargs
);
if
(
CAN_TEST_LIGHTLY
&&
nargs
>
3
)
continue
;
testCatchException
(
void
.
class
,
new
java
.
io
.
IOException
(
"testing"
),
throwMode
,
nargs
);
testCatchException
(
String
.
class
,
new
LinkageError
(
"testing"
),
throwMode
,
nargs
);
}
}
}
static
final
int
THROW_NOTHING
=
0
,
THROW_CAUGHT
=
1
,
THROW_UNCAUGHT
=
2
,
THROW_THROUGH_ADAPTER
=
3
,
THROW_MODE_LIMIT
=
4
;
void
testCatchException
(
Class
<?>
returnType
,
Throwable
thrown
,
int
throwMode
,
int
nargs
)
throws
Throwable
{
testCatchException
(
returnType
,
thrown
,
throwMode
,
nargs
,
0
);
if
(
nargs
<=
5
||
nargs
%
10
==
3
)
{
for
(
int
catchDrops
=
1
;
catchDrops
<=
nargs
;
catchDrops
++)
testCatchException
(
returnType
,
thrown
,
throwMode
,
nargs
,
catchDrops
);
}
}
private
static
<
T
extends
Throwable
>
Object
throwOrReturn
(
Object
normal
,
T
exception
)
throws
T
{
if
(
exception
!=
null
)
{
called
(
"throwOrReturn/throw"
,
normal
,
exception
);
throw
exception
;
}
called
(
"throwOrReturn/normal"
,
normal
,
exception
);
return
normal
;
}
private
int
fakeIdentityCount
;
private
Object
fakeIdentity
(
Object
x
)
{
System
.
out
.
println
(
"should throw through this!"
);
fakeIdentityCount
++;
return
x
;
}
void
testCatchException
(
Class
<?>
returnType
,
Throwable
thrown
,
int
throwMode
,
int
nargs
,
int
catchDrops
)
throws
Throwable
{
countTest
();
if
(
verbosity
>=
3
)
System
.
out
.
println
(
"catchException rt="
+
returnType
+
" throw="
+
throwMode
+
" nargs="
+
nargs
+
" drops="
+
catchDrops
);
Class
<?
extends
Throwable
>
exType
=
thrown
.
getClass
();
if
(
throwMode
>
THROW_CAUGHT
)
thrown
=
new
UnsupportedOperationException
(
"do not catch this"
);
MethodHandle
throwOrReturn
=
PRIVATE
.
findStatic
(
MethodHandlesTest
.
class
,
"throwOrReturn"
,
MethodType
.
methodType
(
Object
.
class
,
Object
.
class
,
Throwable
.
class
));
if
(
throwMode
==
THROW_THROUGH_ADAPTER
)
{
MethodHandle
fakeIdentity
=
PRIVATE
.
findVirtual
(
MethodHandlesTest
.
class
,
"fakeIdentity"
,
MethodType
.
methodType
(
Object
.
class
,
Object
.
class
)).
bindTo
(
this
);
for
(
int
i
=
0
;
i
<
10
;
i
++)
throwOrReturn
=
MethodHandles
.
filterReturnValue
(
throwOrReturn
,
fakeIdentity
);
}
int
nargs1
=
Math
.
max
(
2
,
nargs
);
MethodHandle
thrower
=
throwOrReturn
.
asType
(
MethodType
.
genericMethodType
(
2
));
thrower
=
addTrailingArgs
(
thrower
,
nargs
,
Object
.
class
);
int
catchArgc
=
1
+
nargs
-
catchDrops
;
MethodHandle
catcher
=
varargsList
(
catchArgc
).
asType
(
MethodType
.
genericMethodType
(
catchArgc
));
Object
[]
args
=
randomArgs
(
nargs
,
Object
.
class
);
Object
arg0
=
MISSING_ARG
;
Object
arg1
=
(
throwMode
==
THROW_NOTHING
)
?
(
Throwable
)
null
:
thrown
;
if
(
nargs
>
0
)
arg0
=
args
[
0
];
if
(
nargs
>
1
)
args
[
1
]
=
arg1
;
assertEquals
(
nargs1
,
thrower
.
type
().
parameterCount
());
if
(
nargs
<
nargs1
)
{
Object
[]
appendArgs
=
{
arg0
,
arg1
};
appendArgs
=
Arrays
.
copyOfRange
(
appendArgs
,
nargs
,
nargs1
);
thrower
=
MethodHandles
.
insertArguments
(
thrower
,
nargs
,
appendArgs
);
}
assertEquals
(
nargs
,
thrower
.
type
().
parameterCount
());
MethodHandle
target
=
MethodHandles
.
catchException
(
thrower
,
exType
,
catcher
);
assertEquals
(
thrower
.
type
(),
target
.
type
());
assertEquals
(
nargs
,
target
.
type
().
parameterCount
());
//System.out.println("catching with "+target+" : "+throwOrReturn);
Object
returned
;
try
{
returned
=
target
.
invokeWithArguments
(
args
);
}
catch
(
Throwable
ex
)
{
assertSame
(
"must get the out-of-band exception"
,
thrown
,
ex
);
if
(
throwMode
<=
THROW_CAUGHT
)
assertEquals
(
THROW_UNCAUGHT
,
throwMode
);
returned
=
ex
;
}
assertCalled
(
"throwOrReturn/"
+(
throwMode
==
THROW_NOTHING
?
"normal"
:
"throw"
),
arg0
,
arg1
);
//System.out.println("return from "+target+" : "+returned);
if
(
throwMode
==
THROW_NOTHING
)
{
assertSame
(
arg0
,
returned
);
}
else
if
(
throwMode
==
THROW_CAUGHT
)
{
List
<
Object
>
catchArgs
=
new
ArrayList
<>(
Arrays
.
asList
(
args
));
// catcher receives an initial subsequence of target arguments:
catchArgs
.
subList
(
nargs
-
catchDrops
,
nargs
).
clear
();
// catcher also receives the exception, prepended:
catchArgs
.
add
(
0
,
thrown
);
assertEquals
(
catchArgs
,
returned
);
}
assertEquals
(
0
,
fakeIdentityCount
);
}
@Test
public
void
testThrowException
()
throws
Throwable
{
if
(
CAN_SKIP_WORKING
)
return
;
...
...
test/lib/testlibrary/jdk/testlibrary/Asserts.java
浏览文件 @
308dbf32
...
...
@@ -170,6 +170,34 @@ public class Asserts {
}
}
/**
* Calls {@link #assertSame(java.lang.Object, java.lang.Object, java.lang.String)} with a default message.
*
* @param lhs The left hand side of the comparison.
* @param rhs The right hand side of the comparison.
* @see #assertSame(Object, Object, String)
*/
public
static
void
assertSame
(
Object
lhs
,
Object
rhs
)
{
assertSame
(
lhs
,
rhs
,
null
);
}
/**
* Asserts that {@code lhs} is the same as {@code rhs}.
*
* @param lhs The left hand side of the comparison.
* @param rhs The right hand side of the comparison.
* @param msg A description of the assumption; {@code null} for a default message.
* @throws RuntimeException if the assertion is not true.
*/
public
static
void
assertSame
(
Object
lhs
,
Object
rhs
,
String
msg
)
{
if
(
lhs
!=
rhs
)
{
msg
=
Objects
.
toString
(
msg
,
"assertSame"
)
+
": expected "
+
Objects
.
toString
(
lhs
)
+
" to equal "
+
Objects
.
toString
(
rhs
);
fail
(
msg
);
}
}
/**
* Shorthand for {@link #assertGreaterThanOrEqual(T, T)}.
*
...
...
test/lib/testlibrary/jsr292/com/oracle/testlibrary/jsr292/Helper.java
0 → 100644
浏览文件 @
308dbf32
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package
com.oracle.testlibrary.jsr292
;
import
jdk.testlibrary.Asserts
;
import
java.lang.invoke.MethodHandle
;
import
java.lang.invoke.MethodHandles
;
import
java.lang.invoke.MethodType
;
import
java.lang.reflect.Array
;
import
java.util.*
;
public
class
Helper
{
/** Flag for verbose output, true if {@code -Dverbose} specified */
public
static
final
boolean
IS_VERBOSE
=
System
.
getProperty
(
"verbose"
)
!=
null
;
/**
* Flag for thorough testing -- all test will be executed,
* true if {@code -Dthorough} specified. */
public
static
final
boolean
IS_THOROUGH
=
System
.
getProperty
(
"thorough"
)
!=
null
;
/** Random number generator w/ initial seed equal to {@code -Dseed} */
public
static
final
Random
RNG
;
static
{
String
str
=
System
.
getProperty
(
"seed"
);
long
seed
=
str
!=
null
?
Long
.
parseLong
(
str
)
:
new
Random
().
nextLong
();
RNG
=
new
Random
(
seed
);
System
.
out
.
printf
(
"-Dseed=%d%n"
,
seed
);
}
public
static
final
long
TEST_LIMIT
;
static
{
String
str
=
System
.
getProperty
(
"testLimit"
);
TEST_LIMIT
=
str
!=
null
?
Long
.
parseUnsignedLong
(
str
)
:
2_000L
;
System
.
out
.
printf
(
"-DtestLimit=%d%n"
,
TEST_LIMIT
);
}
public
static
final
int
MAX_ARITY
=
254
;
public
static
final
String
MISSING_ARG
=
"missingArg"
;
public
static
final
String
MISSING_ARG_2
=
"missingArg#2"
;
private
static
final
int
// first int value
ONE_MILLION
=
(
1000
*
1000
),
// scale factor to reach upper 32 bits
TEN_BILLION
=
(
10
*
1000
*
1000
*
1000
),
// <<1 makes space for sign bit;
INITIAL_ARG_VAL
=
ONE_MILLION
<<
1
;
public
static
final
MethodHandle
AS_LIST
;
static
{
try
{
AS_LIST
=
MethodHandles
.
lookup
().
findStatic
(
Arrays
.
class
,
"asList"
,
MethodType
.
methodType
(
List
.
class
,
Object
[].
class
));
}
catch
(
NoSuchMethodException
|
IllegalAccessException
ex
)
{
throw
new
Error
(
ex
);
}
}
public
static
boolean
isDoubleCost
(
Class
<?>
aClass
)
{
return
aClass
==
double
.
class
||
aClass
==
long
.
class
;
}
private
static
List
<
List
<
Object
>>
calledLog
=
new
ArrayList
<>();
private
static
long
nextArgVal
;
public
static
void
assertCalled
(
String
name
,
Object
...
args
)
{
assertCalled
(
0
,
name
,
args
);
}
public
static
void
assertCalled
(
int
lag
,
String
name
,
Object
...
args
)
{
Object
expected
=
logEntry
(
name
,
args
);
Object
actual
=
getCalled
(
lag
);
Asserts
.
assertEQ
(
expected
,
actual
,
"method call w/ lag = "
+
lag
);
}
public
static
Object
called
(
String
name
,
Object
...
args
)
{
List
<
Object
>
entry
=
logEntry
(
name
,
args
);
calledLog
.
add
(
entry
);
return
entry
;
}
private
static
List
<
Object
>
logEntry
(
String
name
,
Object
...
args
)
{
return
Arrays
.
asList
(
name
,
Arrays
.
asList
(
args
));
}
public
static
void
clear
()
{
calledLog
.
clear
();
}
public
static
List
<
Object
>
getCalled
(
int
lag
)
{
int
size
=
calledLog
.
size
();
return
size
<=
lag
?
null
:
calledLog
.
get
(
size
-
lag
-
1
);
}
public
static
MethodHandle
addTrailingArgs
(
MethodHandle
target
,
int
nargs
,
List
<
Class
<?>>
classes
)
{
int
targetLen
=
target
.
type
().
parameterCount
();
int
extra
=
(
nargs
-
targetLen
);
if
(
extra
<=
0
)
{
return
target
;
}
List
<
Class
<?>>
fakeArgs
=
new
ArrayList
<>(
extra
);
for
(
int
i
=
0
;
i
<
extra
;
++
i
)
{
fakeArgs
.
add
(
classes
.
get
(
i
%
classes
.
size
()));
}
return
MethodHandles
.
dropArguments
(
target
,
targetLen
,
fakeArgs
);
}
public
static
MethodHandle
varargsList
(
int
arity
)
{
return
AS_LIST
.
asCollector
(
Object
[].
class
,
arity
);
}
private
static
long
nextArg
(
boolean
moreBits
)
{
long
val
=
nextArgVal
++;
long
sign
=
-(
val
&
1
);
// alternate signs
val
>>=
1
;
if
(
moreBits
)
// Guarantee some bits in the high word.
// In any case keep the decimal representation simple-looking,
// with lots of zeroes, so as not to make the printed decimal
// strings unnecessarily noisy.
{
val
+=
(
val
%
ONE_MILLION
)
*
TEN_BILLION
;
}
return
val
^
sign
;
}
private
static
int
nextArg
()
{
// Produce a 32-bit result something like ONE_MILLION+(smallint).
// Example: 1_000_042.
return
(
int
)
nextArg
(
false
);
}
private
static
long
nextArg
(
Class
<?>
kind
)
{
if
(
kind
==
long
.
class
||
kind
==
Long
.
class
||
kind
==
double
.
class
||
kind
==
Double
.
class
)
// produce a 64-bit result something like
// ((TEN_BILLION+1) * (ONE_MILLION+(smallint)))
// Example: 10_000_420_001_000_042.
{
return
nextArg
(
true
);
}
return
(
long
)
nextArg
();
}
private
static
Object
randomArg
(
Class
<?>
param
)
{
Object
wrap
=
castToWrapperOrNull
(
nextArg
(
param
),
param
);
if
(
wrap
!=
null
)
{
return
wrap
;
}
if
(
param
.
isInterface
())
{
for
(
Class
<?>
c
:
param
.
getClasses
())
{
if
(
param
.
isAssignableFrom
(
c
)
&&
!
c
.
isInterface
())
{
param
=
c
;
break
;
}
}
}
if
(
param
.
isArray
())
{
Class
<?>
ctype
=
param
.
getComponentType
();
Object
arg
=
Array
.
newInstance
(
ctype
,
2
);
Array
.
set
(
arg
,
0
,
randomArg
(
ctype
));
return
arg
;
}
if
(
param
.
isInterface
()
&&
param
.
isAssignableFrom
(
List
.
class
))
{
return
Arrays
.
asList
(
"#"
+
nextArg
());
}
if
(
param
.
isInterface
()
||
param
.
isAssignableFrom
(
String
.
class
))
{
return
"#"
+
nextArg
();
}
try
{
return
param
.
newInstance
();
}
catch
(
InstantiationException
|
IllegalAccessException
ex
)
{
}
return
null
;
// random class not Object, String, Integer, etc.
}
public
static
Object
[]
randomArgs
(
Class
<?>...
params
)
{
Object
[]
args
=
new
Object
[
params
.
length
];
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
args
[
i
]
=
randomArg
(
params
[
i
]);
}
return
args
;
}
public
static
Object
[]
randomArgs
(
int
nargs
,
Class
<?>
param
)
{
Object
[]
args
=
new
Object
[
nargs
];
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
args
[
i
]
=
randomArg
(
param
);
}
return
args
;
}
public
static
Object
[]
randomArgs
(
int
nargs
,
Class
<?>...
params
)
{
Object
[]
args
=
new
Object
[
nargs
];
for
(
int
i
=
0
;
i
<
args
.
length
;
i
++)
{
Class
<?>
param
=
params
[
i
%
params
.
length
];
args
[
i
]
=
randomArg
(
param
);
}
return
args
;
}
public
static
Object
[]
randomArgs
(
List
<
Class
<?>>
params
)
{
return
randomArgs
(
params
.
toArray
(
new
Class
<?>[
params
.
size
()]));
}
private
static
Object
castToWrapper
(
Object
value
,
Class
<?>
dst
)
{
Object
wrap
=
null
;
if
(
value
instanceof
Number
)
{
wrap
=
castToWrapperOrNull
(((
Number
)
value
).
longValue
(),
dst
);
}
if
(
value
instanceof
Character
)
{
wrap
=
castToWrapperOrNull
((
char
)
(
Character
)
value
,
dst
);
}
if
(
wrap
!=
null
)
{
return
wrap
;
}
return
dst
.
cast
(
value
);
}
@SuppressWarnings
(
"cast"
)
// primitive cast to (long) is part of the pattern
private
static
Object
castToWrapperOrNull
(
long
value
,
Class
<?>
dst
)
{
if
(
dst
==
int
.
class
||
dst
==
Integer
.
class
)
{
return
(
int
)
(
value
);
}
if
(
dst
==
long
.
class
||
dst
==
Long
.
class
)
{
return
(
long
)
(
value
);
}
if
(
dst
==
char
.
class
||
dst
==
Character
.
class
)
{
return
(
char
)
(
value
);
}
if
(
dst
==
short
.
class
||
dst
==
Short
.
class
)
{
return
(
short
)
(
value
);
}
if
(
dst
==
float
.
class
||
dst
==
Float
.
class
)
{
return
(
float
)
(
value
);
}
if
(
dst
==
double
.
class
||
dst
==
Double
.
class
)
{
return
(
double
)
(
value
);
}
if
(
dst
==
byte
.
class
||
dst
==
Byte
.
class
)
{
return
(
byte
)
(
value
);
}
if
(
dst
==
boolean
.
class
||
dst
==
boolean
.
class
)
{
return
((
value
%
29
)
&
1
)
==
0
;
}
return
null
;
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录