8297353: Regenerated checked-in html files with new pandoc
Reviewed-by: lancea, erikj
This commit is contained in:
parent
b366d17a94
commit
15e2e2852b
2193
doc/building.html
2193
doc/building.html
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -5,11 +5,19 @@
|
||||
<meta name="generator" content="pandoc" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<title>Native/Unit Test Development Guidelines</title>
|
||||
<style type="text/css">
|
||||
<style>
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
span.underline{text-decoration: underline;}
|
||||
div.column{display: inline-block; vertical-align: top; width: 50%;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
ul.task-list{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1.6em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
||||
</style>
|
||||
<link rel="stylesheet" href="../make/data/docs-resources/resources/jdk-default.css" />
|
||||
<!--[if lt IE 9]>
|
||||
@ -20,174 +28,442 @@
|
||||
<header id="title-block-header">
|
||||
<h1 class="title">Native/Unit Test Development Guidelines</h1>
|
||||
</header>
|
||||
<nav id="TOC">
|
||||
<nav id="TOC" role="doc-toc">
|
||||
<ul>
|
||||
<li><a href="#good-test-properties">Good test properties</a><ul>
|
||||
<li><a href="#lightness">Lightness</a></li>
|
||||
<li><a href="#isolation">Isolation</a></li>
|
||||
<li><a href="#atomicity-and-self-containment">Atomicity and self-containment</a></li>
|
||||
<li><a href="#repeatability">Repeatability</a></li>
|
||||
<li><a href="#informativeness">Informativeness</a></li>
|
||||
<li><a href="#testing-instead-of-visiting">Testing instead of visiting</a></li>
|
||||
<li><a href="#nearness">Nearness</a></li>
|
||||
<li><a href="#good-test-properties" id="toc-good-test-properties">Good
|
||||
test properties</a>
|
||||
<ul>
|
||||
<li><a href="#lightness" id="toc-lightness">Lightness</a></li>
|
||||
<li><a href="#isolation" id="toc-isolation">Isolation</a></li>
|
||||
<li><a href="#atomicity-and-self-containment"
|
||||
id="toc-atomicity-and-self-containment">Atomicity and
|
||||
self-containment</a></li>
|
||||
<li><a href="#repeatability"
|
||||
id="toc-repeatability">Repeatability</a></li>
|
||||
<li><a href="#informativeness"
|
||||
id="toc-informativeness">Informativeness</a></li>
|
||||
<li><a href="#testing-instead-of-visiting"
|
||||
id="toc-testing-instead-of-visiting">Testing instead of
|
||||
visiting</a></li>
|
||||
<li><a href="#nearness" id="toc-nearness">Nearness</a></li>
|
||||
</ul></li>
|
||||
<li><a href="#asserts">Asserts</a><ul>
|
||||
<li><a href="#several-checks">Several checks</a></li>
|
||||
<li><a href="#first-parameter-is-expected-value">First parameter is expected value</a></li>
|
||||
<li><a href="#floating-point-comparison">Floating-point comparison</a></li>
|
||||
<li><a href="#c-string-comparison">C string comparison</a></li>
|
||||
<li><a href="#error-messages">Error messages</a></li>
|
||||
<li><a href="#uncluttered-output">Uncluttered output</a></li>
|
||||
<li><a href="#failures-propagation">Failures propagation</a></li>
|
||||
<li><a href="#asserts" id="toc-asserts">Asserts</a>
|
||||
<ul>
|
||||
<li><a href="#several-checks" id="toc-several-checks">Several
|
||||
checks</a></li>
|
||||
<li><a href="#first-parameter-is-expected-value"
|
||||
id="toc-first-parameter-is-expected-value">First parameter is expected
|
||||
value</a></li>
|
||||
<li><a href="#floating-point-comparison"
|
||||
id="toc-floating-point-comparison">Floating-point comparison</a></li>
|
||||
<li><a href="#c-string-comparison" id="toc-c-string-comparison">C string
|
||||
comparison</a></li>
|
||||
<li><a href="#error-messages" id="toc-error-messages">Error
|
||||
messages</a></li>
|
||||
<li><a href="#uncluttered-output"
|
||||
id="toc-uncluttered-output">Uncluttered output</a></li>
|
||||
<li><a href="#failures-propagation"
|
||||
id="toc-failures-propagation">Failures propagation</a></li>
|
||||
</ul></li>
|
||||
<li><a href="#naming-and-grouping">Naming and Grouping</a><ul>
|
||||
<li><a href="#test-group-names">Test group names</a></li>
|
||||
<li><a href="#filename">Filename</a></li>
|
||||
<li><a href="#file-location">File location</a></li>
|
||||
<li><a href="#test-names">Test names</a></li>
|
||||
<li><a href="#fixture-classes">Fixture classes</a></li>
|
||||
<li><a href="#friend-classes">Friend classes</a></li>
|
||||
<li><a href="#oscpu-specific-tests">OS/CPU specific tests</a></li>
|
||||
<li><a href="#naming-and-grouping" id="toc-naming-and-grouping">Naming
|
||||
and Grouping</a>
|
||||
<ul>
|
||||
<li><a href="#test-group-names" id="toc-test-group-names">Test group
|
||||
names</a></li>
|
||||
<li><a href="#filename" id="toc-filename">Filename</a></li>
|
||||
<li><a href="#file-location" id="toc-file-location">File
|
||||
location</a></li>
|
||||
<li><a href="#test-names" id="toc-test-names">Test names</a></li>
|
||||
<li><a href="#fixture-classes" id="toc-fixture-classes">Fixture
|
||||
classes</a></li>
|
||||
<li><a href="#friend-classes" id="toc-friend-classes">Friend
|
||||
classes</a></li>
|
||||
<li><a href="#oscpu-specific-tests" id="toc-oscpu-specific-tests">OS/CPU
|
||||
specific tests</a></li>
|
||||
</ul></li>
|
||||
<li><a href="#miscellaneous">Miscellaneous</a><ul>
|
||||
<li><a href="#hotspot-style">Hotspot style</a></li>
|
||||
<li><a href="#codetest-metrics">Code/test metrics</a></li>
|
||||
<li><a href="#access-to-non-public-members">Access to non-public members</a></li>
|
||||
<li><a href="#death-tests">Death tests</a></li>
|
||||
<li><a href="#external-flags">External flags</a></li>
|
||||
<li><a href="#test-specific-flags">Test-specific flags</a></li>
|
||||
<li><a href="#flag-restoring">Flag restoring</a></li>
|
||||
<li><a href="#googletest-documentation">GoogleTest documentation</a></li>
|
||||
<li><a href="#miscellaneous" id="toc-miscellaneous">Miscellaneous</a>
|
||||
<ul>
|
||||
<li><a href="#hotspot-style" id="toc-hotspot-style">Hotspot
|
||||
style</a></li>
|
||||
<li><a href="#codetest-metrics" id="toc-codetest-metrics">Code/test
|
||||
metrics</a></li>
|
||||
<li><a href="#access-to-non-public-members"
|
||||
id="toc-access-to-non-public-members">Access to non-public
|
||||
members</a></li>
|
||||
<li><a href="#death-tests" id="toc-death-tests">Death tests</a></li>
|
||||
<li><a href="#external-flags" id="toc-external-flags">External
|
||||
flags</a></li>
|
||||
<li><a href="#test-specific-flags"
|
||||
id="toc-test-specific-flags">Test-specific flags</a></li>
|
||||
<li><a href="#flag-restoring" id="toc-flag-restoring">Flag
|
||||
restoring</a></li>
|
||||
<li><a href="#googletest-documentation"
|
||||
id="toc-googletest-documentation">GoogleTest documentation</a></li>
|
||||
</ul></li>
|
||||
<li><a href="#todo">TODO</a></li>
|
||||
<li><a href="#todo" id="toc-todo">TODO</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<p>The purpose of these guidelines is to establish a shared vision on what kind of native tests and how we want to develop them for Hotspot using GoogleTest. Hence these guidelines include style items as well as test approach items.</p>
|
||||
<p>First section of this document describes properties of good tests which are common for almost all types of test regardless of language, framework, etc. Further sections provide recommendations to achieve those properties and other HotSpot and/or GoogleTest specific guidelines.</p>
|
||||
<p>The purpose of these guidelines is to establish a shared vision on
|
||||
what kind of native tests and how we want to develop them for Hotspot
|
||||
using GoogleTest. Hence these guidelines include style items as well as
|
||||
test approach items.</p>
|
||||
<p>First section of this document describes properties of good tests
|
||||
which are common for almost all types of test regardless of language,
|
||||
framework, etc. Further sections provide recommendations to achieve
|
||||
those properties and other HotSpot and/or GoogleTest specific
|
||||
guidelines.</p>
|
||||
<h2 id="good-test-properties">Good test properties</h2>
|
||||
<h3 id="lightness">Lightness</h3>
|
||||
<p>Use the most lightweight type of tests.</p>
|
||||
<p>In Hotspot, there are 3 different types of tests regarding their dependency on a JVM, each next level is slower than previous</p>
|
||||
<p>In Hotspot, there are 3 different types of tests regarding their
|
||||
dependency on a JVM, each next level is slower than previous</p>
|
||||
<ul>
|
||||
<li><p><code>TEST</code> : a test does not depend on a JVM</p></li>
|
||||
<li><p><code>TEST_VM</code> : a test does depend on an initialized JVM, but are supposed not to break a JVM, i.e. leave it in a workable state.</p></li>
|
||||
<li><p><code>TEST_OTHER_VM</code> : a test depends on a JVM and requires a freshly initialized JVM or leaves a JVM in non-workable state</p></li>
|
||||
<li><p><code>TEST_VM</code> : a test does depend on an initialized JVM,
|
||||
but are supposed not to break a JVM, i.e. leave it in a workable
|
||||
state.</p></li>
|
||||
<li><p><code>TEST_OTHER_VM</code> : a test depends on a JVM and requires
|
||||
a freshly initialized JVM or leaves a JVM in non-workable state</p></li>
|
||||
</ul>
|
||||
<h3 id="isolation">Isolation</h3>
|
||||
<p>Tests have to be isolated: not to have visible side-effects, influences on other tests results.</p>
|
||||
<p>Results of one test should not depend on test execution order, other tests, otherwise it is becoming almost impossible to find out why a test failed. Due to hotspot-specific, it is not so easy to get a full isolation, e.g. we share an initialized JVM between all <code>TEST_VM</code> tests, so if your test changes JVM's state too drastically and does not change it back, you had better consider <code>TEST_OTHER_VM</code>.</p>
|
||||
<h3 id="atomicity-and-self-containment">Atomicity and self-containment</h3>
|
||||
<p>Tests should be <em>atomic</em> and <em>self-contained</em> at the same time.</p>
|
||||
<p>One test should check a particular part of a class, subsystem, functionality, etc. Then it is quite easy to determine what parts of a product are broken basing on test failures. On the other hand, a test should test that part more-or-less entirely, because when one sees a test <code>FooTest::bar</code>, they assume all aspects of bar from <code>Foo</code> are tested.</p>
|
||||
<p>However, it is impossible to cover all aspects even of a method, not to mention a subsystem. In such cases, it is recommended to have several tests, one for each aspect of a thing under test. For example one test to tests how <code>Foo::bar</code> works if an argument is <code>null</code>, another test to test how it works if an argument is acceptable but <code>Foo</code> is not in the right state to accept it and so on. This helps not only to make tests atomic, self-contained but also makes test name self-descriptive (discussed in more details in <a href="#test-names">Test names</a>).</p>
|
||||
<p>Tests have to be isolated: not to have visible side-effects,
|
||||
influences on other tests results.</p>
|
||||
<p>Results of one test should not depend on test execution order, other
|
||||
tests, otherwise it is becoming almost impossible to find out why a test
|
||||
failed. Due to hotspot-specific, it is not so easy to get a full
|
||||
isolation, e.g. we share an initialized JVM between all
|
||||
<code>TEST_VM</code> tests, so if your test changes JVM's state too
|
||||
drastically and does not change it back, you had better consider
|
||||
<code>TEST_OTHER_VM</code>.</p>
|
||||
<h3 id="atomicity-and-self-containment">Atomicity and
|
||||
self-containment</h3>
|
||||
<p>Tests should be <em>atomic</em> and <em>self-contained</em> at the
|
||||
same time.</p>
|
||||
<p>One test should check a particular part of a class, subsystem,
|
||||
functionality, etc. Then it is quite easy to determine what parts of a
|
||||
product are broken basing on test failures. On the other hand, a test
|
||||
should test that part more-or-less entirely, because when one sees a
|
||||
test <code>FooTest::bar</code>, they assume all aspects of bar from
|
||||
<code>Foo</code> are tested.</p>
|
||||
<p>However, it is impossible to cover all aspects even of a method, not
|
||||
to mention a subsystem. In such cases, it is recommended to have several
|
||||
tests, one for each aspect of a thing under test. For example one test
|
||||
to tests how <code>Foo::bar</code> works if an argument is
|
||||
<code>null</code>, another test to test how it works if an argument is
|
||||
acceptable but <code>Foo</code> is not in the right state to accept it
|
||||
and so on. This helps not only to make tests atomic, self-contained but
|
||||
also makes test name self-descriptive (discussed in more details in <a
|
||||
href="#test-names">Test names</a>).</p>
|
||||
<h3 id="repeatability">Repeatability</h3>
|
||||
<p>Tests have to be repeatable.</p>
|
||||
<p>Reproducibility is very crucial for a test. No one likes sporadic test failures, they are hard to investigate, fix and verify a fix.</p>
|
||||
<p>In some cases, it is quite hard to write a 100% repeatable test, since besides a test there can be other moving parts, e.g. in case of <code>TEST_VM</code> there are several concurrently running threads. Despite this, we should try to make a test as reproducible as possible.</p>
|
||||
<p>Reproducibility is very crucial for a test. No one likes sporadic
|
||||
test failures, they are hard to investigate, fix and verify a fix.</p>
|
||||
<p>In some cases, it is quite hard to write a 100% repeatable test,
|
||||
since besides a test there can be other moving parts, e.g. in case of
|
||||
<code>TEST_VM</code> there are several concurrently running threads.
|
||||
Despite this, we should try to make a test as reproducible as
|
||||
possible.</p>
|
||||
<h3 id="informativeness">Informativeness</h3>
|
||||
<p>In case of a failure, a test should be as <em>informative</em> as possible.</p>
|
||||
<p>Having more information about a test failure than just compared values can be very useful for failure troubleshooting, it can reduce or even completely eliminate debugging hours. This is even more important in case of not 100% reproducible failures.</p>
|
||||
<p>Achieving this property, one can easily make a test too verbose, so it will be really hard to find useful information in the ocean of useless information. Hence they should not only think about how to provide <a href="#error-messages">good information</a>, but also <a href="#uncluttered-output">when to do it</a>.</p>
|
||||
<p>In case of a failure, a test should be as <em>informative</em> as
|
||||
possible.</p>
|
||||
<p>Having more information about a test failure than just compared
|
||||
values can be very useful for failure troubleshooting, it can reduce or
|
||||
even completely eliminate debugging hours. This is even more important
|
||||
in case of not 100% reproducible failures.</p>
|
||||
<p>Achieving this property, one can easily make a test too verbose, so
|
||||
it will be really hard to find useful information in the ocean of
|
||||
useless information. Hence they should not only think about how to
|
||||
provide <a href="#error-messages">good information</a>, but also <a
|
||||
href="#uncluttered-output">when to do it</a>.</p>
|
||||
<h3 id="testing-instead-of-visiting">Testing instead of visiting</h3>
|
||||
<p>Tests should <em>test</em>.</p>
|
||||
<p>It is not enough just to "visit" some code, a test should check that code does that it has to do, compare return values with expected values, check that desired side effects are done, and undesired are not, and so on. In other words, a test should contain at least one GoogleTest assertion and do not rely on JVM asserts.</p>
|
||||
<p>Generally speaking to write a good test, one should create a model of the system under tests, a model of possible bugs (or bugs which one wants to find) and design tests using those models.</p>
|
||||
<p>It is not enough just to "visit" some code, a test should check that
|
||||
code does that it has to do, compare return values with expected values,
|
||||
check that desired side effects are done, and undesired are not, and so
|
||||
on. In other words, a test should contain at least one GoogleTest
|
||||
assertion and do not rely on JVM asserts.</p>
|
||||
<p>Generally speaking to write a good test, one should create a model of
|
||||
the system under tests, a model of possible bugs (or bugs which one
|
||||
wants to find) and design tests using those models.</p>
|
||||
<h3 id="nearness">Nearness</h3>
|
||||
<p>Prefer having checks inside test code.</p>
|
||||
<p>Not only does having test logic outside, e.g. verification method, depending on asserts in product code contradict with several items above but also decreases test’s readability and stability. It is much easier to understand that a test is testing when all testing logic is located inside a test or nearby in shared test libraries. As a rule of thumb, the closer a check to a test, the better.</p>
|
||||
<p>Not only does having test logic outside, e.g. verification method,
|
||||
depending on asserts in product code contradict with several items above
|
||||
but also decreases test’s readability and stability. It is much easier
|
||||
to understand that a test is testing when all testing logic is located
|
||||
inside a test or nearby in shared test libraries. As a rule of thumb,
|
||||
the closer a check to a test, the better.</p>
|
||||
<h2 id="asserts">Asserts</h2>
|
||||
<h3 id="several-checks">Several checks</h3>
|
||||
<p>Prefer <code>EXPECT</code> over <code>ASSERT</code> if possible.</p>
|
||||
<p>This is related to the <a href="#informativeness">informativeness</a> property of tests, information for other checks can help to better localize a defect’s root-cause. One should use <code>ASSERT</code> if it is impossible to continue test execution or if it does not make much sense. Later in the text, <code>EXPECT</code> forms will be used to refer to both <code>ASSERT/EXPECT</code>.</p>
|
||||
<p>When it is possible to make several different checks, but impossible to continue test execution if at least one check fails, you can use <code>::testing::Test::HasNonfatalFailure()</code> function. The recommended way to express that is <code>ASSERT_FALSE(::testing::Test::HasNonfatalFailure())</code>. Besides making it clear why a test is aborted, it also allows you to provide more information about a failure.</p>
|
||||
<h3 id="first-parameter-is-expected-value">First parameter is expected value</h3>
|
||||
<p>In all equality assertions, expected values should be passed as the first parameter.</p>
|
||||
<p>This convention is adopted by GoogleTest, and there is a slight difference in how GoogleTest treats parameters, the most important one is <code>null</code> detection. Due to different reasons, <code>null</code> detection is enabled only for the first parameter, that is to said <code>EXPECT_EQ(NULL, object)</code> checks that object is <code>null</code>, while <code>EXPECT_EQ(object, NULL)</code> checks that object equals to <code>NULL</code>, GoogleTest is very strict regarding types of compared values so the latter will generates a compile-time error.</p>
|
||||
<p>This is related to the <a href="#informativeness">informativeness</a>
|
||||
property of tests, information for other checks can help to better
|
||||
localize a defect’s root-cause. One should use <code>ASSERT</code> if it
|
||||
is impossible to continue test execution or if it does not make much
|
||||
sense. Later in the text, <code>EXPECT</code> forms will be used to
|
||||
refer to both <code>ASSERT/EXPECT</code>.</p>
|
||||
<p>When it is possible to make several different checks, but impossible
|
||||
to continue test execution if at least one check fails, you can use
|
||||
<code>::testing::Test::HasNonfatalFailure()</code> function. The
|
||||
recommended way to express that is
|
||||
<code>ASSERT_FALSE(::testing::Test::HasNonfatalFailure())</code>.
|
||||
Besides making it clear why a test is aborted, it also allows you to
|
||||
provide more information about a failure.</p>
|
||||
<h3 id="first-parameter-is-expected-value">First parameter is expected
|
||||
value</h3>
|
||||
<p>In all equality assertions, expected values should be passed as the
|
||||
first parameter.</p>
|
||||
<p>This convention is adopted by GoogleTest, and there is a slight
|
||||
difference in how GoogleTest treats parameters, the most important one
|
||||
is <code>null</code> detection. Due to different reasons,
|
||||
<code>null</code> detection is enabled only for the first parameter,
|
||||
that is to said <code>EXPECT_EQ(NULL, object)</code> checks that object
|
||||
is <code>null</code>, while <code>EXPECT_EQ(object, NULL)</code> checks
|
||||
that object equals to <code>NULL</code>, GoogleTest is very strict
|
||||
regarding types of compared values so the latter will generates a
|
||||
compile-time error.</p>
|
||||
<h3 id="floating-point-comparison">Floating-point comparison</h3>
|
||||
<p>Use floating-point special macros to compare <code>float/double</code> values.</p>
|
||||
<p>Because of floating-point number representations and round-off errors, regular equality comparison will not return true in most cases. There are special <code>EXPECT_FLOAT_EQ/EXPECT_DOUBLE_EQ</code> assertions which check that the distance between compared values is not more than 4 ULPs, there is also <code>EXPECT_NEAR(v1, v2, eps)</code> which checks that the absolute value of the difference between <code>v1</code> and <code>v2</code> is not greater than <code>eps</code>.</p>
|
||||
<p>Use floating-point special macros to compare
|
||||
<code>float/double</code> values.</p>
|
||||
<p>Because of floating-point number representations and round-off
|
||||
errors, regular equality comparison will not return true in most cases.
|
||||
There are special <code>EXPECT_FLOAT_EQ/EXPECT_DOUBLE_EQ</code>
|
||||
assertions which check that the distance between compared values is not
|
||||
more than 4 ULPs, there is also <code>EXPECT_NEAR(v1, v2, eps)</code>
|
||||
which checks that the absolute value of the difference between
|
||||
<code>v1</code> and <code>v2</code> is not greater than
|
||||
<code>eps</code>.</p>
|
||||
<h3 id="c-string-comparison">C string comparison</h3>
|
||||
<p>Use string special macros for C strings comparisons.</p>
|
||||
<p><code>EXPECT_EQ</code> just compares pointers’ values, which is hardly what one wants comparing C strings. GoogleTest provides <code>EXPECT_STREQ</code> and <code>EXPECT_STRNE</code> macros to compare C string contents. There are also case-insensitive versions <code>EXPECT_STRCASEEQ</code>, <code>EXPECT_STRCASENE</code>.</p>
|
||||
<p><code>EXPECT_EQ</code> just compares pointers’ values, which is
|
||||
hardly what one wants comparing C strings. GoogleTest provides
|
||||
<code>EXPECT_STREQ</code> and <code>EXPECT_STRNE</code> macros to
|
||||
compare C string contents. There are also case-insensitive versions
|
||||
<code>EXPECT_STRCASEEQ</code>, <code>EXPECT_STRCASENE</code>.</p>
|
||||
<h3 id="error-messages">Error messages</h3>
|
||||
<p>Provide informative, but not too verbose error messages.</p>
|
||||
<p>All GoogleTest asserts print compared expressions and their values, so there is no need to have them in error messages. Asserts print only compared values, they do not print any of interim variables, e.g. <code>ASSERT_TRUE((val1 == val2 && isFail(foo(8)) || i == 18)</code> prints only one value. If you use some complex predicates, please consider <code>EXPECT_PRED*</code> or <code>EXPECT_FORMAT_PRED</code> assertions family, they check that a predicate returns true/success and print out all parameters values.</p>
|
||||
<p>However in some cases, default information is not enough, a commonly used example is an assert inside a loop, GoogleTest will not print iteration values (unless it is an assert's parameter). Other demonstrative examples are printing error code and a corresponding error message; printing internal states which might have an impact on results. One should add this information to assert message using <code><<</code> operator.</p>
|
||||
<p>All GoogleTest asserts print compared expressions and their values,
|
||||
so there is no need to have them in error messages. Asserts print only
|
||||
compared values, they do not print any of interim variables, e.g.
|
||||
<code>ASSERT_TRUE((val1 == val2 && isFail(foo(8)) || i == 18)</code>
|
||||
prints only one value. If you use some complex predicates, please
|
||||
consider <code>EXPECT_PRED*</code> or <code>EXPECT_FORMAT_PRED</code>
|
||||
assertions family, they check that a predicate returns true/success and
|
||||
print out all parameters values.</p>
|
||||
<p>However in some cases, default information is not enough, a commonly
|
||||
used example is an assert inside a loop, GoogleTest will not print
|
||||
iteration values (unless it is an assert's parameter). Other
|
||||
demonstrative examples are printing error code and a corresponding error
|
||||
message; printing internal states which might have an impact on results.
|
||||
One should add this information to assert message using
|
||||
<code><<</code> operator.</p>
|
||||
<h3 id="uncluttered-output">Uncluttered output</h3>
|
||||
<p>Print information only if it is needed.</p>
|
||||
<p>Too verbose tests which print all information even if they pass are very bad practice. They just pollute output, so it becomes harder to find useful information. In order not print information till it is really needed, one should consider saving it to a temporary buffer and pass to an assert. <a href="https://git.openjdk.org/jdk/blob/master/test/hotspot/gtest/gc/shared/test_memset_with_concurrent_readers.cpp" class="uri">https://git.openjdk.org/jdk/blob/master/test/hotspot/gtest/gc/shared/test_memset_with_concurrent_readers.cpp</a> has a good example how to do that.</p>
|
||||
<p>Too verbose tests which print all information even if they pass are
|
||||
very bad practice. They just pollute output, so it becomes harder to
|
||||
find useful information. In order not print information till it is
|
||||
really needed, one should consider saving it to a temporary buffer and
|
||||
pass to an assert. <a
|
||||
href="https://git.openjdk.org/jdk/blob/master/test/hotspot/gtest/gc/shared/test_memset_with_concurrent_readers.cpp"
|
||||
class="uri">https://git.openjdk.org/jdk/blob/master/test/hotspot/gtest/gc/shared/test_memset_with_concurrent_readers.cpp</a>
|
||||
has a good example how to do that.</p>
|
||||
<h3 id="failures-propagation">Failures propagation</h3>
|
||||
<p>Wrap a subroutine call into <code>EXPECT_NO_FATAL_FAILURE</code> macro to propagate failures.</p>
|
||||
<p><code>ASSERT</code> and <code>FAIL</code> abort only the current function, so if you have them in a subroutine, a test will not be aborted after the subroutine even if <code>ASSERT</code> or <code>FAIL</code> fails. You should call such subroutines in <code>ASSERT_NO_FATAL_FAILURE</code> macro to propagate fatal failures and abort a test. <code>(EXPECT|ASSERT)_NO_FATAL_FAILURE</code> can also be used to provide more information.</p>
|
||||
<p>Due to obvious reasons, there are no <code>(EXPECT|ASSERT)_NO_NONFATAL_FAILURE</code> macros. However, if you need to check if a subroutine generated a nonfatal failure (failed an <code>EXPECT</code>), you can use <code>::testing::Test::HasNonfatalFailure</code> function, or <code>::testing::Test::HasFailure</code> function to check if a subroutine generated any failures, see <a href="#several-checks">Several checks</a>.</p>
|
||||
<p>Wrap a subroutine call into <code>EXPECT_NO_FATAL_FAILURE</code>
|
||||
macro to propagate failures.</p>
|
||||
<p><code>ASSERT</code> and <code>FAIL</code> abort only the current
|
||||
function, so if you have them in a subroutine, a test will not be
|
||||
aborted after the subroutine even if <code>ASSERT</code> or
|
||||
<code>FAIL</code> fails. You should call such subroutines in
|
||||
<code>ASSERT_NO_FATAL_FAILURE</code> macro to propagate fatal failures
|
||||
and abort a test. <code>(EXPECT|ASSERT)_NO_FATAL_FAILURE</code> can also
|
||||
be used to provide more information.</p>
|
||||
<p>Due to obvious reasons, there are no
|
||||
<code>(EXPECT|ASSERT)_NO_NONFATAL_FAILURE</code> macros. However, if you
|
||||
need to check if a subroutine generated a nonfatal failure (failed an
|
||||
<code>EXPECT</code>), you can use
|
||||
<code>::testing::Test::HasNonfatalFailure</code> function, or
|
||||
<code>::testing::Test::HasFailure</code> function to check if a
|
||||
subroutine generated any failures, see <a href="#several-checks">Several
|
||||
checks</a>.</p>
|
||||
<h2 id="naming-and-grouping">Naming and Grouping</h2>
|
||||
<h3 id="test-group-names">Test group names</h3>
|
||||
<p>Test group names should be in CamelCase, start and end with a letter. A test group should be named after tested class, functionality, subsystem, etc.</p>
|
||||
<p>This naming scheme helps to find tests, filter them and simplifies test failure analysis. For example, class <code>Foo</code> - test group <code>Foo</code>, compiler logging subsystem - test group <code>CompilerLogging</code>, G1 GC — test group <code>G1GC</code>, and so forth.</p>
|
||||
<p>Test group names should be in CamelCase, start and end with a letter.
|
||||
A test group should be named after tested class, functionality,
|
||||
subsystem, etc.</p>
|
||||
<p>This naming scheme helps to find tests, filter them and simplifies
|
||||
test failure analysis. For example, class <code>Foo</code> - test group
|
||||
<code>Foo</code>, compiler logging subsystem - test group
|
||||
<code>CompilerLogging</code>, G1 GC — test group <code>G1GC</code>, and
|
||||
so forth.</p>
|
||||
<h3 id="filename">Filename</h3>
|
||||
<p>A test file must have <code>test_</code> prefix and <code>.cpp</code> suffix.</p>
|
||||
<p>Both are actually requirements from the current build system to recognize your tests.</p>
|
||||
<p>A test file must have <code>test_</code> prefix and <code>.cpp</code>
|
||||
suffix.</p>
|
||||
<p>Both are actually requirements from the current build system to
|
||||
recognize your tests.</p>
|
||||
<h3 id="file-location">File location</h3>
|
||||
<p>Test file location should reflect a location of the tested part of the product.</p>
|
||||
<p>Test file location should reflect a location of the tested part of
|
||||
the product.</p>
|
||||
<ul>
|
||||
<li><p>All unit tests for a class from <code>foo/bar/baz.cpp</code> should be placed <code>foo/bar/test_baz.cpp</code> in <code>hotspot/test/native/</code> directory. Having all tests for a class in one file is a common practice for unit tests, it helps to see all existing tests at once, share functions and/or resources without losing encapsulation.</p></li>
|
||||
<li><p>For tests which test more than one class, directory hierarchy should be the same as product hierarchy, and file name should reflect the name of the tested subsystem/functionality. For example, if a sub-system under tests belongs to <code>gc/g1</code>, tests should be placed in <code>gc/g1</code> directory.</p></li>
|
||||
<li><p>All unit tests for a class from <code>foo/bar/baz.cpp</code>
|
||||
should be placed <code>foo/bar/test_baz.cpp</code> in
|
||||
<code>hotspot/test/native/</code> directory. Having all tests for a
|
||||
class in one file is a common practice for unit tests, it helps to see
|
||||
all existing tests at once, share functions and/or resources without
|
||||
losing encapsulation.</p></li>
|
||||
<li><p>For tests which test more than one class, directory hierarchy
|
||||
should be the same as product hierarchy, and file name should reflect
|
||||
the name of the tested subsystem/functionality. For example, if a
|
||||
sub-system under tests belongs to <code>gc/g1</code>, tests should be
|
||||
placed in <code>gc/g1</code> directory.</p></li>
|
||||
</ul>
|
||||
<p>Please note that framework prepends directory name to a test group name. For example, if <code>TEST(foo, check_this)</code> and <code>TEST(bar, check_that)</code> are defined in <code>hotspot/test/native/gc/shared/test_foo.cpp</code> file, they will be reported as <code>gc/shared/foo::check_this</code> and <code>gc/shared/bar::check_that</code>.</p>
|
||||
<p>Please note that framework prepends directory name to a test group
|
||||
name. For example, if <code>TEST(foo, check_this)</code> and
|
||||
<code>TEST(bar, check_that)</code> are defined in
|
||||
<code>hotspot/test/native/gc/shared/test_foo.cpp</code> file, they will
|
||||
be reported as <code>gc/shared/foo::check_this</code> and
|
||||
<code>gc/shared/bar::check_that</code>.</p>
|
||||
<h3 id="test-names">Test names</h3>
|
||||
<p>Test names should be in small_snake_case, start and end with a letter. A test name should reflect that a test checks.</p>
|
||||
<p>Such naming makes tests self-descriptive and helps a lot during the whole test life cycle. It is easy to do test planning, test inventory, to see what things are not tested, to review tests, to analyze test failures, to evolve a test, etc. For example <code>foo_return_0_if_name_is_null</code> is better than <code>foo_sanity</code> or <code>foo_basic</code> or just <code>foo</code>, <code>humongous_objects_can_not_be_moved_by_young_gc</code> is better than <code>ho_young_gc</code>.</p>
|
||||
<p>Actually using underscore is against GoogleTest project convention, because it can lead to illegal identifiers, however, this is too strict. Restricting usage of underscore for test names only and prohibiting test name starts or ends with an underscore are enough to be safe.</p>
|
||||
<p>Test names should be in small_snake_case, start and end with a
|
||||
letter. A test name should reflect that a test checks.</p>
|
||||
<p>Such naming makes tests self-descriptive and helps a lot during the
|
||||
whole test life cycle. It is easy to do test planning, test inventory,
|
||||
to see what things are not tested, to review tests, to analyze test
|
||||
failures, to evolve a test, etc. For example
|
||||
<code>foo_return_0_if_name_is_null</code> is better than
|
||||
<code>foo_sanity</code> or <code>foo_basic</code> or just
|
||||
<code>foo</code>,
|
||||
<code>humongous_objects_can_not_be_moved_by_young_gc</code> is better
|
||||
than <code>ho_young_gc</code>.</p>
|
||||
<p>Actually using underscore is against GoogleTest project convention,
|
||||
because it can lead to illegal identifiers, however, this is too strict.
|
||||
Restricting usage of underscore for test names only and prohibiting test
|
||||
name starts or ends with an underscore are enough to be safe.</p>
|
||||
<h3 id="fixture-classes">Fixture classes</h3>
|
||||
<p>Fixture classes should be named after tested classes, subsystems, etc (follow <a href="#test-group-names">Test group names rule</a>) and have <code>Test</code> suffix to prevent class name conflicts.</p>
|
||||
<p>Fixture classes should be named after tested classes, subsystems, etc
|
||||
(follow <a href="#test-group-names">Test group names rule</a>) and have
|
||||
<code>Test</code> suffix to prevent class name conflicts.</p>
|
||||
<h3 id="friend-classes">Friend classes</h3>
|
||||
<p>All test purpose friends should have either <code>Test</code> or <code>Testable</code> suffix.</p>
|
||||
<p>It greatly simplifies understanding of friendship’s purpose and allows statically check that private members are not exposed unexpectedly. Having <code>FooTest</code> as a friend of <code>Foo</code> without any comments will be understood as a necessary evil to get testability.</p>
|
||||
<p>All test purpose friends should have either <code>Test</code> or
|
||||
<code>Testable</code> suffix.</p>
|
||||
<p>It greatly simplifies understanding of friendship’s purpose and
|
||||
allows statically check that private members are not exposed
|
||||
unexpectedly. Having <code>FooTest</code> as a friend of
|
||||
<code>Foo</code> without any comments will be understood as a necessary
|
||||
evil to get testability.</p>
|
||||
<h3 id="oscpu-specific-tests">OS/CPU specific tests</h3>
|
||||
<p>Guard OS/CPU specific tests by <code>#ifdef</code> and have OS/CPU name in filename.</p>
|
||||
<p>For the time being, we do not support separate directories for OS, CPU, OS-CPU specific tests, in case we will have lots of such tests, we will change directory layout and build system to support that in the same way it is done in hotspot.</p>
|
||||
<p>Guard OS/CPU specific tests by <code>#ifdef</code> and have OS/CPU
|
||||
name in filename.</p>
|
||||
<p>For the time being, we do not support separate directories for OS,
|
||||
CPU, OS-CPU specific tests, in case we will have lots of such tests, we
|
||||
will change directory layout and build system to support that in the
|
||||
same way it is done in hotspot.</p>
|
||||
<h2 id="miscellaneous">Miscellaneous</h2>
|
||||
<h3 id="hotspot-style">Hotspot style</h3>
|
||||
<p>Abide the norms and rules accepted in Hotspot style guide.</p>
|
||||
<p>Tests are a part of Hotspot, so everything (if applicable) we use for Hotspot, should be used for tests as well. Those guidelines cover test-specific things.</p>
|
||||
<p>Tests are a part of Hotspot, so everything (if applicable) we use for
|
||||
Hotspot, should be used for tests as well. Those guidelines cover
|
||||
test-specific things.</p>
|
||||
<h3 id="codetest-metrics">Code/test metrics</h3>
|
||||
<p>Coverage information and other code/test metrics are quite useful to decide what tests should be written, what tests should be improved and what can be removed.</p>
|
||||
<p>For unit tests, widely used and well-known coverage metric is branch coverage, which provides good quality of tests with relatively easy test development process. For other levels of testing, branch coverage is not as good, and one should consider others metrics, e.g. transaction flow coverage, data flow coverage.</p>
|
||||
<p>Coverage information and other code/test metrics are quite useful to
|
||||
decide what tests should be written, what tests should be improved and
|
||||
what can be removed.</p>
|
||||
<p>For unit tests, widely used and well-known coverage metric is branch
|
||||
coverage, which provides good quality of tests with relatively easy test
|
||||
development process. For other levels of testing, branch coverage is not
|
||||
as good, and one should consider others metrics, e.g. transaction flow
|
||||
coverage, data flow coverage.</p>
|
||||
<h3 id="access-to-non-public-members">Access to non-public members</h3>
|
||||
<p>Use explicit friend class to get access to non-public members.</p>
|
||||
<p>We do not use GoogleTest macro to declare friendship relation, because, from our point of view, it is less clear than an explicit declaration.</p>
|
||||
<p>Declaring a test fixture class as a friend class of a tested test is the easiest and the clearest way to get access. However, it has some disadvantages, here is some of them:</p>
|
||||
<p>We do not use GoogleTest macro to declare friendship relation,
|
||||
because, from our point of view, it is less clear than an explicit
|
||||
declaration.</p>
|
||||
<p>Declaring a test fixture class as a friend class of a tested test is
|
||||
the easiest and the clearest way to get access. However, it has some
|
||||
disadvantages, here is some of them:</p>
|
||||
<ul>
|
||||
<li>Each test has to be declared as a friend</li>
|
||||
<li>Subclasses do not inheritance friendship relation</li>
|
||||
</ul>
|
||||
<p>In other words, it is harder to share code between tests. Hence if you want to share code or expect it to be useful in other tests, you should consider making members in a tested class protected and introduce a shared test-only class which expose those members via public functions, or even making members publicly accessible right away in a product class. If it is not an option to change members visibility, one can create a friend class which exposes members.</p>
|
||||
<p>In other words, it is harder to share code between tests. Hence if
|
||||
you want to share code or expect it to be useful in other tests, you
|
||||
should consider making members in a tested class protected and introduce
|
||||
a shared test-only class which expose those members via public
|
||||
functions, or even making members publicly accessible right away in a
|
||||
product class. If it is not an option to change members visibility, one
|
||||
can create a friend class which exposes members.</p>
|
||||
<h3 id="death-tests">Death tests</h3>
|
||||
<p>You can not use death tests inside <code>TEST_OTHER_VM</code> and <code>TEST_VM_ASSERT*</code>.</p>
|
||||
<p>We tried to make Hotspot-GoogleTest integration as transparent as possible, however, due to the current implementation of <code>TEST_OTHER_VM</code> and <code>TEST_VM_ASSERT*</code> tests, you cannot use death test functionality in them. These tests are implemented as GoogleTest death tests, and GoogleTest does not allow to have a death test inside another death test.</p>
|
||||
<p>You can not use death tests inside <code>TEST_OTHER_VM</code> and
|
||||
<code>TEST_VM_ASSERT*</code>.</p>
|
||||
<p>We tried to make Hotspot-GoogleTest integration as transparent as
|
||||
possible, however, due to the current implementation of
|
||||
<code>TEST_OTHER_VM</code> and <code>TEST_VM_ASSERT*</code> tests, you
|
||||
cannot use death test functionality in them. These tests are implemented
|
||||
as GoogleTest death tests, and GoogleTest does not allow to have a death
|
||||
test inside another death test.</p>
|
||||
<h3 id="external-flags">External flags</h3>
|
||||
<p>Passing external flags to a tested JVM is not supported.</p>
|
||||
<p>The rationality of such design decision is to simplify both tests and a test framework and to avoid failures related to incompatible flags combination till there is a good solution for that. However there are cases when one wants to test a JVM with specific flags combination, <code>_JAVA_OPTIONS</code> environment variable can be used to do that. Flags from <code>_JAVA_OPTIONS</code> will be used in <code>TEST_VM</code>, <code>TEST_OTHER_VM</code> and <code>TEST_VM_ASSERT*</code> tests.</p>
|
||||
<p>The rationality of such design decision is to simplify both tests and
|
||||
a test framework and to avoid failures related to incompatible flags
|
||||
combination till there is a good solution for that. However there are
|
||||
cases when one wants to test a JVM with specific flags combination,
|
||||
<code>_JAVA_OPTIONS</code> environment variable can be used to do that.
|
||||
Flags from <code>_JAVA_OPTIONS</code> will be used in
|
||||
<code>TEST_VM</code>, <code>TEST_OTHER_VM</code> and
|
||||
<code>TEST_VM_ASSERT*</code> tests.</p>
|
||||
<h3 id="test-specific-flags">Test-specific flags</h3>
|
||||
<p>Passing flags to a tested JVM in <code>TEST_OTHER_VM</code> and <code>TEST_VM_ASSERT*</code> should be possible, but is not implemented yet.</p>
|
||||
<p>Facility to pass test-specific flags is needed for system, regression or other types of tests which require a fully initialized JVM in some particular configuration, e.g. with Serial GC selected. There is no support for such tests now, however, there is a plan to add that in upcoming releases.</p>
|
||||
<p>For now, if a test depends on flags values, it should have <code>if (!<flag>) { return }</code> guards in the very beginning and <code>@requires</code> comment similar to jtreg <code>@requires</code> directive right before test macros. <a href="https://git.openjdk.org/jdk/blob/master/test/hotspot/gtest/gc/g1/test_g1IHOPControl.cpp" class="uri">https://git.openjdk.org/jdk/blob/master/test/hotspot/gtest/gc/g1/test_g1IHOPControl.cpp</a> ha an example of this temporary workaround. It is important to follow that pattern as it allows us to easily find all such tests and update them as soon as there is an implementation of flag passing facility.</p>
|
||||
<p>In long-term, we expect jtreg to support GoogleTest tests as first class citizens, that is to say, jtreg will parse <span class="citation" data-cites="requires">@requires</span> comments and filter out inapplicable tests.</p>
|
||||
<p>Passing flags to a tested JVM in <code>TEST_OTHER_VM</code> and
|
||||
<code>TEST_VM_ASSERT*</code> should be possible, but is not implemented
|
||||
yet.</p>
|
||||
<p>Facility to pass test-specific flags is needed for system, regression
|
||||
or other types of tests which require a fully initialized JVM in some
|
||||
particular configuration, e.g. with Serial GC selected. There is no
|
||||
support for such tests now, however, there is a plan to add that in
|
||||
upcoming releases.</p>
|
||||
<p>For now, if a test depends on flags values, it should have
|
||||
<code>if (!<flag>) { return }</code> guards in the very beginning
|
||||
and <code>@requires</code> comment similar to jtreg
|
||||
<code>@requires</code> directive right before test macros. <a
|
||||
href="https://git.openjdk.org/jdk/blob/master/test/hotspot/gtest/gc/g1/test_g1IHOPControl.cpp"
|
||||
class="uri">https://git.openjdk.org/jdk/blob/master/test/hotspot/gtest/gc/g1/test_g1IHOPControl.cpp</a>
|
||||
ha an example of this temporary workaround. It is important to follow
|
||||
that pattern as it allows us to easily find all such tests and update
|
||||
them as soon as there is an implementation of flag passing facility.</p>
|
||||
<p>In long-term, we expect jtreg to support GoogleTest tests as first
|
||||
class citizens, that is to say, jtreg will parse <span class="citation"
|
||||
data-cites="requires">@requires</span> comments and filter out
|
||||
inapplicable tests.</p>
|
||||
<h3 id="flag-restoring">Flag restoring</h3>
|
||||
<p>Restore changed flags.</p>
|
||||
<p>It is quite common for tests to configure JVM in a certain way changing flags’ values. GoogleTest provides two ways to set up environment before a test and restore it afterward: using either constructor and destructor or <code>SetUp</code> and <code>TearDown</code> functions. Both ways require to use a test fixture class, which sometimes is too wordy. The simpler facilities like <code>FLAG_GUARD</code> macro or <code>*FlagSetting</code> classes could be used in such cases to restore/set values.</p>
|
||||
<p>It is quite common for tests to configure JVM in a certain way
|
||||
changing flags’ values. GoogleTest provides two ways to set up
|
||||
environment before a test and restore it afterward: using either
|
||||
constructor and destructor or <code>SetUp</code> and
|
||||
<code>TearDown</code> functions. Both ways require to use a test fixture
|
||||
class, which sometimes is too wordy. The simpler facilities like
|
||||
<code>FLAG_GUARD</code> macro or <code>*FlagSetting</code> classes could
|
||||
be used in such cases to restore/set values.</p>
|
||||
<p>Caveats:</p>
|
||||
<ul>
|
||||
<li><p>Changing a flag’s value could break the invariants between flags' values and hence could lead to unexpected/unsupported JVM state.</p></li>
|
||||
<li><p><code>FLAG_SET_*</code> macros can change more than one flag (in order to maintain invariants) so it is hard to predict what flags will be changed and it makes restoring all changed flags a nontrivial task. Thus in case one uses <code>FLAG_SET_*</code> macros, they should use <code>TEST_OTHER_VM</code> test type.</p></li>
|
||||
<li><p>Changing a flag’s value could break the invariants between flags'
|
||||
values and hence could lead to unexpected/unsupported JVM
|
||||
state.</p></li>
|
||||
<li><p><code>FLAG_SET_*</code> macros can change more than one flag (in
|
||||
order to maintain invariants) so it is hard to predict what flags will
|
||||
be changed and it makes restoring all changed flags a nontrivial task.
|
||||
Thus in case one uses <code>FLAG_SET_*</code> macros, they should use
|
||||
<code>TEST_OTHER_VM</code> test type.</p></li>
|
||||
</ul>
|
||||
<h3 id="googletest-documentation">GoogleTest documentation</h3>
|
||||
<p>In case you have any questions regarding GoogleTest itself, its asserts, test declaration macros, other macros, etc, please consult its documentation.</p>
|
||||
<p>In case you have any questions regarding GoogleTest itself, its
|
||||
asserts, test declaration macros, other macros, etc, please consult its
|
||||
documentation.</p>
|
||||
<h2 id="todo">TODO</h2>
|
||||
<p>Although this document provides guidelines on the most important parts of test development using GTest, it still misses a few items:</p>
|
||||
<p>Although this document provides guidelines on the most important
|
||||
parts of test development using GTest, it still misses a few items:</p>
|
||||
<ul>
|
||||
<li><p>Examples, esp for <a href="#access-to-non-public-members">access to non-public members</a></p></li>
|
||||
<li>test types: purpose, drawbacks, limitation
|
||||
<li><p>Examples, esp for <a href="#access-to-non-public-members">access
|
||||
to non-public members</a></p></li>
|
||||
<li><p>test types: purpose, drawbacks, limitation</p>
|
||||
<ul>
|
||||
<li><code>TEST_VM</code></li>
|
||||
<li><code>TEST_VM_F</code></li>
|
||||
@ -195,7 +471,7 @@
|
||||
<li><code>TEST_VM_ASSERT</code></li>
|
||||
<li><code>TEST_VM_ASSERT_MSG</code></li>
|
||||
</ul></li>
|
||||
<li>Miscellaneous
|
||||
<li><p>Miscellaneous</p>
|
||||
<ul>
|
||||
<li>Test libraries
|
||||
<ul>
|
||||
@ -208,7 +484,8 @@
|
||||
<li>how to run tests in random order</li>
|
||||
<li>how to run only specific tests</li>
|
||||
<li>how to run each test separately</li>
|
||||
<li>check that a test can find bugs it is supposed to by introducing them</li>
|
||||
<li>check that a test can find bugs it is supposed to by introducing
|
||||
them</li>
|
||||
</ul></li>
|
||||
<li>mocks/stubs/dependency injection</li>
|
||||
<li>setUp/tearDown
|
||||
|
91
doc/ide.html
91
doc/ide.html
@ -5,11 +5,19 @@
|
||||
<meta name="generator" content="pandoc" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<title>IDE support in the JDK</title>
|
||||
<style type="text/css">
|
||||
<style>
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
span.underline{text-decoration: underline;}
|
||||
div.column{display: inline-block; vertical-align: top; width: 50%;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
ul.task-list{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1.6em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
||||
</style>
|
||||
<link rel="stylesheet" href="../make/data/docs-resources/resources/jdk-default.css" />
|
||||
<!--[if lt IE 9]>
|
||||
@ -20,41 +28,82 @@
|
||||
<header id="title-block-header">
|
||||
<h1 class="title">IDE support in the JDK</h1>
|
||||
</header>
|
||||
<nav id="TOC">
|
||||
<nav id="TOC" role="doc-toc">
|
||||
<ul>
|
||||
<li><a href="#introduction">Introduction</a><ul>
|
||||
<li><a href="#ide-support-for-native-code">IDE support for native code</a></li>
|
||||
<li><a href="#ide-support-for-java-code">IDE support for Java code</a></li>
|
||||
<li><a href="#introduction" id="toc-introduction">Introduction</a>
|
||||
<ul>
|
||||
<li><a href="#ide-support-for-native-code"
|
||||
id="toc-ide-support-for-native-code">IDE support for native
|
||||
code</a></li>
|
||||
<li><a href="#ide-support-for-java-code"
|
||||
id="toc-ide-support-for-java-code">IDE support for Java code</a></li>
|
||||
</ul></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<h2 id="introduction">Introduction</h2>
|
||||
<p>When you are familiar with building and testing the JDK, you may want to configure an IDE to work with the source code. The instructions differ a bit depending on whether you are interested in working with the native (C/C++) or the Java code.</p>
|
||||
<p>When you are familiar with building and testing the JDK, you may want
|
||||
to configure an IDE to work with the source code. The instructions
|
||||
differ a bit depending on whether you are interested in working with the
|
||||
native (C/C++) or the Java code.</p>
|
||||
<h3 id="ide-support-for-native-code">IDE support for native code</h3>
|
||||
<p>There are a few ways to generate IDE configuration for the native sources, depending on which IDE to use.</p>
|
||||
<p>There are a few ways to generate IDE configuration for the native
|
||||
sources, depending on which IDE to use.</p>
|
||||
<h4 id="visual-studio-code">Visual Studio Code</h4>
|
||||
<p>The make system can generate a <a href="https://code.visualstudio.com">Visual Studio Code</a> workspace that has C/C++ source indexing configured correctly, as well as launcher targets for tests and the Java launcher. After configuring, a workspace for the configuration can be generated using:</p>
|
||||
<p>The make system can generate a <a
|
||||
href="https://code.visualstudio.com">Visual Studio Code</a> workspace
|
||||
that has C/C++ source indexing configured correctly, as well as launcher
|
||||
targets for tests and the Java launcher. After configuring, a workspace
|
||||
for the configuration can be generated using:</p>
|
||||
<pre class="shell"><code>make vscode-project</code></pre>
|
||||
<p>This creates a file called <code>jdk.code-workspace</code> in the build output folder. The full location will be printed after the workspace has been generated. To use it, choose <code>File -> Open Workspace...</code> in Visual Studio Code.</p>
|
||||
<p>This creates a file called <code>jdk.code-workspace</code> in the
|
||||
build output folder. The full location will be printed after the
|
||||
workspace has been generated. To use it, choose
|
||||
<code>File -> Open Workspace...</code> in Visual Studio Code.</p>
|
||||
<h5 id="alternative-indexers">Alternative indexers</h5>
|
||||
<p>The main <code>vscode-project</code> target configures the default C++ support in Visual Studio Code. There are also other source indexers that can be installed, that may provide additional features. It's currently possible to generate configuration for two such indexers, <a href="https://clang.llvm.org/extra/clangd/">clangd</a> and <a href="https://github.com/Andersbakken/rtags">rtags</a>. These can be configured by appending the name of the indexer to the make target, such as:</p>
|
||||
<p>The main <code>vscode-project</code> target configures the default
|
||||
C++ support in Visual Studio Code. There are also other source indexers
|
||||
that can be installed, that may provide additional features. It's
|
||||
currently possible to generate configuration for two such indexers, <a
|
||||
href="https://clang.llvm.org/extra/clangd/">clangd</a> and <a
|
||||
href="https://github.com/Andersbakken/rtags">rtags</a>. These can be
|
||||
configured by appending the name of the indexer to the make target, such
|
||||
as:</p>
|
||||
<pre class="shell"><code>make vscode-project-clangd</code></pre>
|
||||
<p>Additional instructions for configuring the given indexer will be displayed after the workspace has been generated.</p>
|
||||
<p>Additional instructions for configuring the given indexer will be
|
||||
displayed after the workspace has been generated.</p>
|
||||
<h4 id="visual-studio">Visual Studio</h4>
|
||||
<p>The make system can generate a Visual Studio project for the Hotspot native source. After configuring, the project is generated using:</p>
|
||||
<p>The make system can generate a Visual Studio project for the Hotspot
|
||||
native source. After configuring, the project is generated using:</p>
|
||||
<pre class="shell"><code>make hotspot-ide-project</code></pre>
|
||||
<p>This creates a file named <code>jvm.vcxproj</code> in <code>ide\hotspot-visualstudio</code> subfolder of the build output folder. The file can be opened in Visual Studio via <code>File -> Open -> Project/Solution</code>.</p>
|
||||
<p>This creates a file named <code>jvm.vcxproj</code> in
|
||||
<code>ide\hotspot-visualstudio</code> subfolder of the build output
|
||||
folder. The file can be opened in Visual Studio via
|
||||
<code>File -> Open -> Project/Solution</code>.</p>
|
||||
<h4 id="compilation-database">Compilation Database</h4>
|
||||
<p>The make system can generate generic native code indexing support in the form of a <a href="https://clang.llvm.org/docs/JSONCompilationDatabase.html">Compilation Database</a> that can be used by many different IDEs and source code indexers.</p>
|
||||
<p>The make system can generate generic native code indexing support in
|
||||
the form of a <a
|
||||
href="https://clang.llvm.org/docs/JSONCompilationDatabase.html">Compilation
|
||||
Database</a> that can be used by many different IDEs and source code
|
||||
indexers.</p>
|
||||
<pre class="shell"><code>make compile-commands</code></pre>
|
||||
<p>It's also possible to generate the Compilation Database for the HotSpot source code only, which is a bit faster as it includes less information.</p>
|
||||
<p>It's also possible to generate the Compilation Database for the
|
||||
HotSpot source code only, which is a bit faster as it includes less
|
||||
information.</p>
|
||||
<pre class="shell"><code>make compile-commands-hotspot</code></pre>
|
||||
<h3 id="ide-support-for-java-code">IDE support for Java code</h3>
|
||||
<h4 id="intellij-idea">IntelliJ IDEA</h4>
|
||||
<p>The JDK project has a script that can be used for indexing the project with IntelliJ. After configuring and building the JDK, an IntelliJ workspace can be generated by running the following command in the top-level folder of the cloned repository:</p>
|
||||
<p>The JDK project has a script that can be used for indexing the
|
||||
project with IntelliJ. After configuring and building the JDK, an
|
||||
IntelliJ workspace can be generated by running the following command in
|
||||
the top-level folder of the cloned repository:</p>
|
||||
<pre class="shell"><code>bash bin/idea.sh</code></pre>
|
||||
<p>To use it, choose <code>File -> Open...</code> in IntelliJ and select the folder where you ran the above script.</p>
|
||||
<p>Next, configure the project SDK in IntelliJ. Open <code>File -> Project Structure -> Project</code> and select <code>build/<config>/images/jdk</code> as the SDK to use.</p>
|
||||
<p>In order to run the tests from the IDE, you can use the JTReg plugin. Instructions for building and using the plugin can be found <a href="https://github.com/openjdk/jtreg/tree/master/plugins/idea">here</a>.</p>
|
||||
<p>To use it, choose <code>File -> Open...</code> in IntelliJ and
|
||||
select the folder where you ran the above script.</p>
|
||||
<p>Next, configure the project SDK in IntelliJ. Open
|
||||
<code>File -> Project Structure -> Project</code> and select
|
||||
<code>build/<config>/images/jdk</code> as the SDK to use.</p>
|
||||
<p>In order to run the tests from the IDE, you can use the JTReg plugin.
|
||||
Instructions for building and using the plugin can be found <a
|
||||
href="https://github.com/openjdk/jtreg/tree/master/plugins/idea">here</a>.</p>
|
||||
</body>
|
||||
</html>
|
||||
|
592
doc/testing.html
592
doc/testing.html
@ -5,57 +5,99 @@
|
||||
<meta name="generator" content="pandoc" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<title>Testing the JDK</title>
|
||||
<style type="text/css">
|
||||
<style>
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
span.underline{text-decoration: underline;}
|
||||
div.column{display: inline-block; vertical-align: top; width: 50%;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
ul.task-list{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1.6em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
||||
</style>
|
||||
<link rel="stylesheet" href="../make/data/docs-resources/resources/jdk-default.css" />
|
||||
<style type="text/css">pre, code, tt { color: #1d6ae5; }</style>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
|
||||
<![endif]-->
|
||||
<style type="text/css">pre, code, tt { color: #1d6ae5; }</style>
|
||||
</head>
|
||||
<body>
|
||||
<header id="title-block-header">
|
||||
<h1 class="title">Testing the JDK</h1>
|
||||
</header>
|
||||
<nav id="TOC">
|
||||
<nav id="TOC" role="doc-toc">
|
||||
<ul>
|
||||
<li><a href="#overview">Overview</a></li>
|
||||
<li><a href="#running-tests-locally-with-make-test">Running tests locally with <code>make test</code></a><ul>
|
||||
<li><a href="#configuration">Configuration</a></li>
|
||||
<li><a href="#overview" id="toc-overview">Overview</a></li>
|
||||
<li><a href="#running-tests-locally-with-make-test"
|
||||
id="toc-running-tests-locally-with-make-test">Running tests locally with
|
||||
<code>make test</code></a>
|
||||
<ul>
|
||||
<li><a href="#configuration"
|
||||
id="toc-configuration">Configuration</a></li>
|
||||
</ul></li>
|
||||
<li><a href="#test-selection">Test selection</a><ul>
|
||||
<li><a href="#common-test-groups">Common Test Groups</a></li>
|
||||
<li><a href="#jtreg">JTReg</a></li>
|
||||
<li><a href="#gtest">Gtest</a></li>
|
||||
<li><a href="#microbenchmarks">Microbenchmarks</a></li>
|
||||
<li><a href="#special-tests">Special tests</a></li>
|
||||
<li><a href="#test-selection" id="toc-test-selection">Test selection</a>
|
||||
<ul>
|
||||
<li><a href="#common-test-groups" id="toc-common-test-groups">Common
|
||||
Test Groups</a></li>
|
||||
<li><a href="#jtreg" id="toc-jtreg">JTReg</a></li>
|
||||
<li><a href="#gtest" id="toc-gtest">Gtest</a></li>
|
||||
<li><a href="#microbenchmarks"
|
||||
id="toc-microbenchmarks">Microbenchmarks</a></li>
|
||||
<li><a href="#special-tests" id="toc-special-tests">Special
|
||||
tests</a></li>
|
||||
</ul></li>
|
||||
<li><a href="#test-results-and-summary">Test results and summary</a></li>
|
||||
<li><a href="#test-suite-control">Test suite control</a><ul>
|
||||
<li><a href="#general-keywords-test_opts">General keywords (TEST_OPTS)</a></li>
|
||||
<li><a href="#jtreg-keywords">JTReg keywords</a></li>
|
||||
<li><a href="#gtest-keywords">Gtest keywords</a></li>
|
||||
<li><a href="#microbenchmark-keywords">Microbenchmark keywords</a></li>
|
||||
<li><a href="#test-results-and-summary"
|
||||
id="toc-test-results-and-summary">Test results and summary</a></li>
|
||||
<li><a href="#test-suite-control" id="toc-test-suite-control">Test suite
|
||||
control</a>
|
||||
<ul>
|
||||
<li><a href="#general-keywords-test_opts"
|
||||
id="toc-general-keywords-test_opts">General keywords
|
||||
(TEST_OPTS)</a></li>
|
||||
<li><a href="#jtreg-keywords" id="toc-jtreg-keywords">JTReg
|
||||
keywords</a></li>
|
||||
<li><a href="#gtest-keywords" id="toc-gtest-keywords">Gtest
|
||||
keywords</a></li>
|
||||
<li><a href="#microbenchmark-keywords"
|
||||
id="toc-microbenchmark-keywords">Microbenchmark keywords</a></li>
|
||||
</ul></li>
|
||||
<li><a href="#notes-for-specific-tests">Notes for Specific Tests</a><ul>
|
||||
<li><a href="#docker-tests">Docker Tests</a></li>
|
||||
<li><a href="#non-us-locale">Non-US locale</a></li>
|
||||
<li><a href="#pkcs11-tests">PKCS11 Tests</a></li>
|
||||
<li><a href="#client-ui-tests">Client UI Tests</a></li>
|
||||
<li><a href="#notes-for-specific-tests"
|
||||
id="toc-notes-for-specific-tests">Notes for Specific Tests</a>
|
||||
<ul>
|
||||
<li><a href="#docker-tests" id="toc-docker-tests">Docker Tests</a></li>
|
||||
<li><a href="#non-us-locale" id="toc-non-us-locale">Non-US
|
||||
locale</a></li>
|
||||
<li><a href="#pkcs11-tests" id="toc-pkcs11-tests">PKCS11 Tests</a></li>
|
||||
<li><a href="#client-ui-tests" id="toc-client-ui-tests">Client UI
|
||||
Tests</a></li>
|
||||
</ul></li>
|
||||
<li><a href="#editing-this-document">Editing this document</a></li>
|
||||
<li><a href="#editing-this-document"
|
||||
id="toc-editing-this-document">Editing this document</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
<h2 id="overview">Overview</h2>
|
||||
<p>The bulk of JDK tests use <a href="https://openjdk.org/jtreg/">jtreg</a>, a regression test framework and test runner built for the JDK's specific needs. Other test frameworks are also used. The different test frameworks can be executed directly, but there is also a set of make targets intended to simplify the interface, and figure out how to run your tests for you.</p>
|
||||
<h2 id="running-tests-locally-with-make-test">Running tests locally with <code>make test</code></h2>
|
||||
<p>This is the easiest way to get started. Assuming you've built the JDK locally, execute:</p>
|
||||
<p>The bulk of JDK tests use <a
|
||||
href="https://openjdk.org/jtreg/">jtreg</a>, a regression test framework
|
||||
and test runner built for the JDK's specific needs. Other test
|
||||
frameworks are also used. The different test frameworks can be executed
|
||||
directly, but there is also a set of make targets intended to simplify
|
||||
the interface, and figure out how to run your tests for you.</p>
|
||||
<h2 id="running-tests-locally-with-make-test">Running tests locally with
|
||||
<code>make test</code></h2>
|
||||
<p>This is the easiest way to get started. Assuming you've built the JDK
|
||||
locally, execute:</p>
|
||||
<pre><code>$ make test</code></pre>
|
||||
<p>This will run a default set of tests against the JDK, and present you with the results. <code>make test</code> is part of a family of test-related make targets which simplify running tests, because they invoke the various test frameworks for you. The "make test framework" is simple to start with, but more complex ad-hoc combination of tests is also possible. You can always invoke the test frameworks directly if you want even more control.</p>
|
||||
<p>This will run a default set of tests against the JDK, and present you
|
||||
with the results. <code>make test</code> is part of a family of
|
||||
test-related make targets which simplify running tests, because they
|
||||
invoke the various test frameworks for you. The "make test framework" is
|
||||
simple to start with, but more complex ad-hoc combination of tests is
|
||||
also possible. You can always invoke the test frameworks directly if you
|
||||
want even more control.</p>
|
||||
<p>Some example command-lines:</p>
|
||||
<pre><code>$ make test-tier1
|
||||
$ make test-jdk_lang JTREG="JOBS=8"
|
||||
@ -65,54 +107,214 @@ $ make test TEST="hotspot:hotspot_gc" JTREG="JOBS=1;TIMEOUT_FACTO
|
||||
$ make test TEST="jtreg:test/hotspot:hotspot_gc test/hotspot/jtreg/native_sanity/JniVersion.java"
|
||||
$ make test TEST="micro:java.lang.reflect" MICRO="FORK=1;WARMUP_ITER=2"
|
||||
$ make exploded-test TEST=tier2</code></pre>
|
||||
<p>"tier1" and "tier2" refer to tiered testing, see further down. "TEST" is a test selection argument which the make test framework will use to try to find the tests you want. It iterates over the available test frameworks, and if the test isn't present in one, it tries the next one. The main target <code>test</code> uses the jdk-image as the tested product. There is also an alternate target <code>exploded-test</code> that uses the exploded image instead. Not all tests will run successfully on the exploded image, but using this target can greatly improve rebuild times for certain workflows.</p>
|
||||
<p>Previously, <code>make test</code> was used to invoke an old system for running tests, and <code>make run-test</code> was used for the new test framework. For backward compatibility with scripts and muscle memory, <code>run-test</code> and variants like <code>exploded-run-test</code> or <code>run-test-tier1</code> are kept as aliases.</p>
|
||||
<p>"tier1" and "tier2" refer to tiered testing, see further down. "TEST"
|
||||
is a test selection argument which the make test framework will use to
|
||||
try to find the tests you want. It iterates over the available test
|
||||
frameworks, and if the test isn't present in one, it tries the next one.
|
||||
The main target <code>test</code> uses the jdk-image as the tested
|
||||
product. There is also an alternate target <code>exploded-test</code>
|
||||
that uses the exploded image instead. Not all tests will run
|
||||
successfully on the exploded image, but using this target can greatly
|
||||
improve rebuild times for certain workflows.</p>
|
||||
<p>Previously, <code>make test</code> was used to invoke an old system
|
||||
for running tests, and <code>make run-test</code> was used for the new
|
||||
test framework. For backward compatibility with scripts and muscle
|
||||
memory, <code>run-test</code> and variants like
|
||||
<code>exploded-run-test</code> or <code>run-test-tier1</code> are kept
|
||||
as aliases.</p>
|
||||
<h3 id="configuration">Configuration</h3>
|
||||
<p>To be able to run JTReg tests, <code>configure</code> needs to know where to find the JTReg test framework. If it is not picked up automatically by configure, use the <code>--with-jtreg=<path to jtreg home></code> option to point to the JTReg framework. Note that this option should point to the JTReg home, i.e. the top directory, containing <code>lib/jtreg.jar</code> etc. (An alternative is to set the <code>JT_HOME</code> environment variable to point to the JTReg home before running <code>configure</code>.)</p>
|
||||
<p>To be able to run microbenchmarks, <code>configure</code> needs to know where to find the JMH dependency. Use <code>--with-jmh=<path to JMH jars></code> to point to a directory containing the core JMH and transitive dependencies. The recommended dependencies can be retrieved by running <code>sh make/devkit/createJMHBundle.sh</code>, after which <code>--with-jmh=build/jmh/jars</code> should work.</p>
|
||||
<p>When tests fail or timeout, jtreg runs its failure handler to capture necessary data from the system where the test was run. This data can then be used to analyze the test failures. Collecting this data involves running various commands (which are listed in files residing in <code>test/failure_handler/src/share/conf</code>) and some of these commands use <code>sudo</code>. If the system's <code>sudoers</code> file isn't configured to allow running these commands, then it can result in password being prompted during the failure handler execution. Typically, when running locally, collecting this additional data isn't always necessary. To disable running the failure handler, use <code>--enable-jtreg-failure-handler=no</code> when running <code>configure</code>. If, however, you want to let the failure handler to run and don't want to be prompted for sudo password, then you can configure your <code>sudoers</code> file appropriately. Please read the necessary documentation of your operating system to see how to do that; here we only show one possible way of doing that - edit the <code>/etc/sudoers.d/sudoers</code> file to include the following line:</p>
|
||||
<p>To be able to run JTReg tests, <code>configure</code> needs to know
|
||||
where to find the JTReg test framework. If it is not picked up
|
||||
automatically by configure, use the
|
||||
<code>--with-jtreg=<path to jtreg home></code> option to point to
|
||||
the JTReg framework. Note that this option should point to the JTReg
|
||||
home, i.e. the top directory, containing <code>lib/jtreg.jar</code> etc.
|
||||
(An alternative is to set the <code>JT_HOME</code> environment variable
|
||||
to point to the JTReg home before running <code>configure</code>.)</p>
|
||||
<p>To be able to run microbenchmarks, <code>configure</code> needs to
|
||||
know where to find the JMH dependency. Use
|
||||
<code>--with-jmh=<path to JMH jars></code> to point to a directory
|
||||
containing the core JMH and transitive dependencies. The recommended
|
||||
dependencies can be retrieved by running
|
||||
<code>sh make/devkit/createJMHBundle.sh</code>, after which
|
||||
<code>--with-jmh=build/jmh/jars</code> should work.</p>
|
||||
<p>When tests fail or timeout, jtreg runs its failure handler to capture
|
||||
necessary data from the system where the test was run. This data can
|
||||
then be used to analyze the test failures. Collecting this data involves
|
||||
running various commands (which are listed in files residing in
|
||||
<code>test/failure_handler/src/share/conf</code>) and some of these
|
||||
commands use <code>sudo</code>. If the system's <code>sudoers</code>
|
||||
file isn't configured to allow running these commands, then it can
|
||||
result in password being prompted during the failure handler execution.
|
||||
Typically, when running locally, collecting this additional data isn't
|
||||
always necessary. To disable running the failure handler, use
|
||||
<code>--enable-jtreg-failure-handler=no</code> when running
|
||||
<code>configure</code>. If, however, you want to let the failure handler
|
||||
to run and don't want to be prompted for sudo password, then you can
|
||||
configure your <code>sudoers</code> file appropriately. Please read the
|
||||
necessary documentation of your operating system to see how to do that;
|
||||
here we only show one possible way of doing that - edit the
|
||||
<code>/etc/sudoers.d/sudoers</code> file to include the following
|
||||
line:</p>
|
||||
<pre><code>johndoe ALL=(ALL) NOPASSWD: /sbin/dmesg</code></pre>
|
||||
<p>This line configures <code>sudo</code> to <em>not</em> prompt for password for the <code>/sbin/dmesg</code> command (this is one of the commands that is listed in the files at <code>test/failure_handler/src/share/conf</code>), for the user <code>johndoe</code>. Here <code>johndoe</code> is the user account under which the jtreg tests are run. Replace the username with a relevant user account of your system.</p>
|
||||
<p>This line configures <code>sudo</code> to <em>not</em> prompt for
|
||||
password for the <code>/sbin/dmesg</code> command (this is one of the
|
||||
commands that is listed in the files at
|
||||
<code>test/failure_handler/src/share/conf</code>), for the user
|
||||
<code>johndoe</code>. Here <code>johndoe</code> is the user account
|
||||
under which the jtreg tests are run. Replace the username with a
|
||||
relevant user account of your system.</p>
|
||||
<h2 id="test-selection">Test selection</h2>
|
||||
<p>All functionality is available using the <code>test</code> make target. In this use case, the test or tests to be executed is controlled using the <code>TEST</code> variable. To speed up subsequent test runs with no source code changes, <code>test-only</code> can be used instead, which do not depend on the source and test image build.</p>
|
||||
<p>For some common top-level tests, direct make targets have been generated. This includes all JTReg test groups, the hotspot gtest, and custom tests (if present). This means that <code>make test-tier1</code> is equivalent to <code>make test TEST="tier1"</code>, but the latter is more tab-completion friendly. For more complex test runs, the <code>test TEST="x"</code> solution needs to be used.</p>
|
||||
<p>The test specifications given in <code>TEST</code> is parsed into fully qualified test descriptors, which clearly and unambigously show which tests will be run. As an example, <code>:tier1</code> will expand to <code>jtreg:$(TOPDIR)/test/hotspot/jtreg:tier1 jtreg:$(TOPDIR)/test/jdk:tier1 jtreg:$(TOPDIR)/test/langtools:tier1 jtreg:$(TOPDIR)/test/nashorn:tier1 jtreg:$(TOPDIR)/test/jaxp:tier1</code>. You can always submit a list of fully qualified test descriptors in the <code>TEST</code> variable if you want to shortcut the parser.</p>
|
||||
<p>All functionality is available using the <code>test</code> make
|
||||
target. In this use case, the test or tests to be executed is controlled
|
||||
using the <code>TEST</code> variable. To speed up subsequent test runs
|
||||
with no source code changes, <code>test-only</code> can be used instead,
|
||||
which do not depend on the source and test image build.</p>
|
||||
<p>For some common top-level tests, direct make targets have been
|
||||
generated. This includes all JTReg test groups, the hotspot gtest, and
|
||||
custom tests (if present). This means that <code>make test-tier1</code>
|
||||
is equivalent to <code>make test TEST="tier1"</code>, but the latter is
|
||||
more tab-completion friendly. For more complex test runs, the
|
||||
<code>test TEST="x"</code> solution needs to be used.</p>
|
||||
<p>The test specifications given in <code>TEST</code> is parsed into
|
||||
fully qualified test descriptors, which clearly and unambigously show
|
||||
which tests will be run. As an example, <code>:tier1</code> will expand
|
||||
to
|
||||
<code>jtreg:$(TOPDIR)/test/hotspot/jtreg:tier1 jtreg:$(TOPDIR)/test/jdk:tier1 jtreg:$(TOPDIR)/test/langtools:tier1 jtreg:$(TOPDIR)/test/nashorn:tier1 jtreg:$(TOPDIR)/test/jaxp:tier1</code>.
|
||||
You can always submit a list of fully qualified test descriptors in the
|
||||
<code>TEST</code> variable if you want to shortcut the parser.</p>
|
||||
<h3 id="common-test-groups">Common Test Groups</h3>
|
||||
<p>Ideally, all tests are run for every change but this may not be practical due to the limited testing resources, the scope of the change, etc.</p>
|
||||
<p>The source tree currently defines a few common test groups in the relevant <code>TEST.groups</code> files. There are test groups that cover a specific component, for example <code>hotspot_gc</code>. It is a good idea to look into <code>TEST.groups</code> files to get a sense what tests are relevant to a particular JDK component.</p>
|
||||
<p>Component-specific tests may miss some unintended consequences of a change, so other tests should also be run. Again, it might be impractical to run all tests, and therefore <em>tiered</em> test groups exist. Tiered test groups are not component-specific, but rather cover the significant parts of the entire JDK.</p>
|
||||
<p>Multiple tiers allow balancing test coverage and testing costs. Lower test tiers are supposed to contain the simpler, quicker and more stable tests. Higher tiers are supposed to contain progressively more thorough, slower, and sometimes less stable tests, or the tests that require special configuration.</p>
|
||||
<p>Contributors are expected to run the tests for the areas that are changed, and the first N tiers they can afford to run, but at least tier1.</p>
|
||||
<p>Ideally, all tests are run for every change but this may not be
|
||||
practical due to the limited testing resources, the scope of the change,
|
||||
etc.</p>
|
||||
<p>The source tree currently defines a few common test groups in the
|
||||
relevant <code>TEST.groups</code> files. There are test groups that
|
||||
cover a specific component, for example <code>hotspot_gc</code>. It is a
|
||||
good idea to look into <code>TEST.groups</code> files to get a sense
|
||||
what tests are relevant to a particular JDK component.</p>
|
||||
<p>Component-specific tests may miss some unintended consequences of a
|
||||
change, so other tests should also be run. Again, it might be
|
||||
impractical to run all tests, and therefore <em>tiered</em> test groups
|
||||
exist. Tiered test groups are not component-specific, but rather cover
|
||||
the significant parts of the entire JDK.</p>
|
||||
<p>Multiple tiers allow balancing test coverage and testing costs. Lower
|
||||
test tiers are supposed to contain the simpler, quicker and more stable
|
||||
tests. Higher tiers are supposed to contain progressively more thorough,
|
||||
slower, and sometimes less stable tests, or the tests that require
|
||||
special configuration.</p>
|
||||
<p>Contributors are expected to run the tests for the areas that are
|
||||
changed, and the first N tiers they can afford to run, but at least
|
||||
tier1.</p>
|
||||
<p>A brief description of the tiered test groups:</p>
|
||||
<ul>
|
||||
<li><p><code>tier1</code>: This is the lowest test tier. Multiple developers run these tests every day. Because of the widespread use, the tests in <code>tier1</code> are carefully selected and optimized to run fast, and to run in the most stable manner. The test failures in <code>tier1</code> are usually followed up on quickly, either with fixes, or adding relevant tests to problem list. GitHub Actions workflows, if enabled, run <code>tier1</code> tests.</p></li>
|
||||
<li><p><code>tier2</code>: This test group covers even more ground. These contain, among other things, tests that either run for too long to be at <code>tier1</code>, or may require special configuration, or tests that are less stable, or cover the broader range of non-core JVM and JDK features/components(for example, XML).</p></li>
|
||||
<li><p><code>tier3</code>: This test group includes more stressful tests, the tests for corner cases not covered by previous tiers, plus the tests that require GUIs. As such, this suite should either be run with low concurrency (<code>TEST_JOBS=1</code>), or without headful tests(<code>JTREG_KEYWORDS=\!headful</code>), or both.</p></li>
|
||||
<li><p><code>tier4</code>: This test group includes every other test not covered by previous tiers. It includes, for example, <code>vmTestbase</code> suites for Hotspot, which run for many hours even on large machines. It also runs GUI tests, so the same <code>TEST_JOBS</code> and <code>JTREG_KEYWORDS</code> caveats apply.</p></li>
|
||||
<li><p><code>tier1</code>: This is the lowest test tier. Multiple
|
||||
developers run these tests every day. Because of the widespread use, the
|
||||
tests in <code>tier1</code> are carefully selected and optimized to run
|
||||
fast, and to run in the most stable manner. The test failures in
|
||||
<code>tier1</code> are usually followed up on quickly, either with
|
||||
fixes, or adding relevant tests to problem list. GitHub Actions
|
||||
workflows, if enabled, run <code>tier1</code> tests.</p></li>
|
||||
<li><p><code>tier2</code>: This test group covers even more ground.
|
||||
These contain, among other things, tests that either run for too long to
|
||||
be at <code>tier1</code>, or may require special configuration, or tests
|
||||
that are less stable, or cover the broader range of non-core JVM and JDK
|
||||
features/components(for example, XML).</p></li>
|
||||
<li><p><code>tier3</code>: This test group includes more stressful
|
||||
tests, the tests for corner cases not covered by previous tiers, plus
|
||||
the tests that require GUIs. As such, this suite should either be run
|
||||
with low concurrency (<code>TEST_JOBS=1</code>), or without headful
|
||||
tests(<code>JTREG_KEYWORDS=\!headful</code>), or both.</p></li>
|
||||
<li><p><code>tier4</code>: This test group includes every other test not
|
||||
covered by previous tiers. It includes, for example,
|
||||
<code>vmTestbase</code> suites for Hotspot, which run for many hours
|
||||
even on large machines. It also runs GUI tests, so the same
|
||||
<code>TEST_JOBS</code> and <code>JTREG_KEYWORDS</code> caveats
|
||||
apply.</p></li>
|
||||
</ul>
|
||||
<h3 id="jtreg">JTReg</h3>
|
||||
<p>JTReg tests can be selected either by picking a JTReg test group, or a selection of files or directories containing JTReg tests. Documentation can be found at <a href="https://openjdk.org/jtreg/">https://openjdk.org/jtreg/</a>, note especially the extensive <a href="https://openjdk.org/jtreg/faq.html">FAQ</a>.</p>
|
||||
<p>JTReg test groups can be specified either without a test root, e.g. <code>:tier1</code> (or <code>tier1</code>, the initial colon is optional), or with, e.g. <code>hotspot:tier1</code>, <code>test/jdk:jdk_util</code> or <code>$(TOPDIR)/test/hotspot/jtreg:hotspot_all</code>. The test root can be specified either as an absolute path, or a path relative to the JDK top directory, or the <code>test</code> directory. For simplicity, the hotspot JTReg test root, which really is <code>hotspot/jtreg</code> can be abbreviated as just <code>hotspot</code>.</p>
|
||||
<p>When specified without a test root, all matching groups from all test roots will be added. Otherwise, only the group from the specified test root will be added.</p>
|
||||
<p>Individual JTReg tests or directories containing JTReg tests can also be specified, like <code>test/hotspot/jtreg/native_sanity/JniVersion.java</code> or <code>hotspot/jtreg/native_sanity</code>. Just like for test root selection, you can either specify an absolute path (which can even point to JTReg tests outside the source tree), or a path relative to either the JDK top directory or the <code>test</code> directory. <code>hotspot</code> can be used as an alias for <code>hotspot/jtreg</code> here as well.</p>
|
||||
<p>As long as the test groups or test paths can be uniquely resolved, you do not need to enter the <code>jtreg:</code> prefix. If this is not possible, or if you want to use a fully qualified test descriptor, add <code>jtreg:</code>, e.g. <code>jtreg:test/hotspot/jtreg/native_sanity</code>.</p>
|
||||
<p>JTReg tests can be selected either by picking a JTReg test group, or
|
||||
a selection of files or directories containing JTReg tests.
|
||||
Documentation can be found at <a
|
||||
href="https://openjdk.org/jtreg/">https://openjdk.org/jtreg/</a>, note
|
||||
especially the extensive <a
|
||||
href="https://openjdk.org/jtreg/faq.html">FAQ</a>.</p>
|
||||
<p>JTReg test groups can be specified either without a test root, e.g.
|
||||
<code>:tier1</code> (or <code>tier1</code>, the initial colon is
|
||||
optional), or with, e.g. <code>hotspot:tier1</code>,
|
||||
<code>test/jdk:jdk_util</code> or
|
||||
<code>$(TOPDIR)/test/hotspot/jtreg:hotspot_all</code>. The test root can
|
||||
be specified either as an absolute path, or a path relative to the JDK
|
||||
top directory, or the <code>test</code> directory. For simplicity, the
|
||||
hotspot JTReg test root, which really is <code>hotspot/jtreg</code> can
|
||||
be abbreviated as just <code>hotspot</code>.</p>
|
||||
<p>When specified without a test root, all matching groups from all test
|
||||
roots will be added. Otherwise, only the group from the specified test
|
||||
root will be added.</p>
|
||||
<p>Individual JTReg tests or directories containing JTReg tests can also
|
||||
be specified, like
|
||||
<code>test/hotspot/jtreg/native_sanity/JniVersion.java</code> or
|
||||
<code>hotspot/jtreg/native_sanity</code>. Just like for test root
|
||||
selection, you can either specify an absolute path (which can even point
|
||||
to JTReg tests outside the source tree), or a path relative to either
|
||||
the JDK top directory or the <code>test</code> directory.
|
||||
<code>hotspot</code> can be used as an alias for
|
||||
<code>hotspot/jtreg</code> here as well.</p>
|
||||
<p>As long as the test groups or test paths can be uniquely resolved,
|
||||
you do not need to enter the <code>jtreg:</code> prefix. If this is not
|
||||
possible, or if you want to use a fully qualified test descriptor, add
|
||||
<code>jtreg:</code>, e.g.
|
||||
<code>jtreg:test/hotspot/jtreg/native_sanity</code>.</p>
|
||||
<h3 id="gtest">Gtest</h3>
|
||||
<p><strong>Note:</strong> To be able to run the Gtest suite, you need to configure your build to be able to find a proper version of the gtest source. For details, see the section <a href="building.html#running-tests">"Running Tests" in the build documentation</a>.</p>
|
||||
<p>Since the Hotspot Gtest suite is so quick, the default is to run all tests. This is specified by just <code>gtest</code>, or as a fully qualified test descriptor <code>gtest:all</code>.</p>
|
||||
<p>If you want, you can single out an individual test or a group of tests, for instance <code>gtest:LogDecorations</code> or <code>gtest:LogDecorations.level_test_vm</code>. This can be particularly useful if you want to run a shaky test repeatedly.</p>
|
||||
<p>For Gtest, there is a separate test suite for each JVM variant. The JVM variant is defined by adding <code>/<variant></code> to the test descriptor, e.g. <code>gtest:Log/client</code>. If you specify no variant, gtest will run once for each JVM variant present (e.g. server, client). So if you only have the server JVM present, then <code>gtest:all</code> will be equivalent to <code>gtest:all/server</code>.</p>
|
||||
<p><strong>Note:</strong> To be able to run the Gtest suite, you need to
|
||||
configure your build to be able to find a proper version of the gtest
|
||||
source. For details, see the section <a
|
||||
href="building.html#running-tests">"Running Tests" in the build
|
||||
documentation</a>.</p>
|
||||
<p>Since the Hotspot Gtest suite is so quick, the default is to run all
|
||||
tests. This is specified by just <code>gtest</code>, or as a fully
|
||||
qualified test descriptor <code>gtest:all</code>.</p>
|
||||
<p>If you want, you can single out an individual test or a group of
|
||||
tests, for instance <code>gtest:LogDecorations</code> or
|
||||
<code>gtest:LogDecorations.level_test_vm</code>. This can be
|
||||
particularly useful if you want to run a shaky test repeatedly.</p>
|
||||
<p>For Gtest, there is a separate test suite for each JVM variant. The
|
||||
JVM variant is defined by adding <code>/<variant></code> to the
|
||||
test descriptor, e.g. <code>gtest:Log/client</code>. If you specify no
|
||||
variant, gtest will run once for each JVM variant present (e.g. server,
|
||||
client). So if you only have the server JVM present, then
|
||||
<code>gtest:all</code> will be equivalent to
|
||||
<code>gtest:all/server</code>.</p>
|
||||
<h3 id="microbenchmarks">Microbenchmarks</h3>
|
||||
<p>Which microbenchmarks to run is selected using a regular expression following the <code>micro:</code> test descriptor, e.g., <code>micro:java.lang.reflect</code>. This delegates the test selection to JMH, meaning package name, class name and even benchmark method names can be used to select tests.</p>
|
||||
<p>Using special characters like <code>|</code> in the regular expression is possible, but needs to be escaped multiple times: <code>micro:ArrayCopy\\\\\|reflect</code>.</p>
|
||||
<p>Which microbenchmarks to run is selected using a regular expression
|
||||
following the <code>micro:</code> test descriptor, e.g.,
|
||||
<code>micro:java.lang.reflect</code>. This delegates the test selection
|
||||
to JMH, meaning package name, class name and even benchmark method names
|
||||
can be used to select tests.</p>
|
||||
<p>Using special characters like <code>|</code> in the regular
|
||||
expression is possible, but needs to be escaped multiple times:
|
||||
<code>micro:ArrayCopy\\\\\|reflect</code>.</p>
|
||||
<h3 id="special-tests">Special tests</h3>
|
||||
<p>A handful of odd tests that are not covered by any other testing framework are accessible using the <code>special:</code> test descriptor. Currently, this includes <code>failure-handler</code> and <code>make</code>.</p>
|
||||
<p>A handful of odd tests that are not covered by any other testing
|
||||
framework are accessible using the <code>special:</code> test
|
||||
descriptor. Currently, this includes <code>failure-handler</code> and
|
||||
<code>make</code>.</p>
|
||||
<ul>
|
||||
<li><p>Failure handler testing is run using <code>special:failure-handler</code> or just <code>failure-handler</code> as test descriptor.</p></li>
|
||||
<li><p>Tests for the build system, including both makefiles and related functionality, is run using <code>special:make</code> or just <code>make</code> as test descriptor. This is equivalent to <code>special:make:all</code>.</p>
|
||||
<p>A specific make test can be run by supplying it as argument, e.g. <code>special:make:idea</code>. As a special syntax, this can also be expressed as <code>make-idea</code>, which allows for command lines as <code>make test-make-idea</code>.</p></li>
|
||||
<li><p>Failure handler testing is run using
|
||||
<code>special:failure-handler</code> or just
|
||||
<code>failure-handler</code> as test descriptor.</p></li>
|
||||
<li><p>Tests for the build system, including both makefiles and related
|
||||
functionality, is run using <code>special:make</code> or just
|
||||
<code>make</code> as test descriptor. This is equivalent to
|
||||
<code>special:make:all</code>.</p>
|
||||
<p>A specific make test can be run by supplying it as argument, e.g.
|
||||
<code>special:make:idea</code>. As a special syntax, this can also be
|
||||
expressed as <code>make-idea</code>, which allows for command lines as
|
||||
<code>make test-make-idea</code>.</p></li>
|
||||
</ul>
|
||||
<h2 id="test-results-and-summary">Test results and summary</h2>
|
||||
<p>At the end of the test run, a summary of all tests run will be presented. This will have a consistent look, regardless of what test suites were used. This is a sample summary:</p>
|
||||
<p>At the end of the test run, a summary of all tests run will be
|
||||
presented. This will have a consistent look, regardless of what test
|
||||
suites were used. This is a sample summary:</p>
|
||||
<pre><code>==============================
|
||||
Test summary
|
||||
==============================
|
||||
@ -122,20 +324,61 @@ Test summary
|
||||
jtreg:nashorn/test:tier1 133 133 0 0
|
||||
==============================
|
||||
TEST FAILURE</code></pre>
|
||||
<p>Tests where the number of TOTAL tests does not equal the number of PASSed tests will be considered a test failure. These are marked with the <code>>> ... <<</code> marker for easy identification.</p>
|
||||
<p>The classification of non-passed tests differs a bit between test suites. In the summary, ERROR is used as a catch-all for tests that neither passed nor are classified as failed by the framework. This might indicate test framework error, timeout or other problems.</p>
|
||||
<p>In case of test failures, <code>make test</code> will exit with a non-zero exit value.</p>
|
||||
<p>All tests have their result stored in <code>build/$BUILD/test-results/$TEST_ID</code>, where TEST_ID is a path-safe conversion from the fully qualified test descriptor, e.g. for <code>jtreg:jdk/test:tier1</code> the TEST_ID is <code>jtreg_jdk_test_tier1</code>. This path is also printed in the log at the end of the test run.</p>
|
||||
<p>Additional work data is stored in <code>build/$BUILD/test-support/$TEST_ID</code>. For some frameworks, this directory might contain information that is useful in determining the cause of a failed test.</p>
|
||||
<p>Tests where the number of TOTAL tests does not equal the number of
|
||||
PASSed tests will be considered a test failure. These are marked with
|
||||
the <code>>> ... <<</code> marker for easy
|
||||
identification.</p>
|
||||
<p>The classification of non-passed tests differs a bit between test
|
||||
suites. In the summary, ERROR is used as a catch-all for tests that
|
||||
neither passed nor are classified as failed by the framework. This might
|
||||
indicate test framework error, timeout or other problems.</p>
|
||||
<p>In case of test failures, <code>make test</code> will exit with a
|
||||
non-zero exit value.</p>
|
||||
<p>All tests have their result stored in
|
||||
<code>build/$BUILD/test-results/$TEST_ID</code>, where TEST_ID is a
|
||||
path-safe conversion from the fully qualified test descriptor, e.g. for
|
||||
<code>jtreg:jdk/test:tier1</code> the TEST_ID is
|
||||
<code>jtreg_jdk_test_tier1</code>. This path is also printed in the log
|
||||
at the end of the test run.</p>
|
||||
<p>Additional work data is stored in
|
||||
<code>build/$BUILD/test-support/$TEST_ID</code>. For some frameworks,
|
||||
this directory might contain information that is useful in determining
|
||||
the cause of a failed test.</p>
|
||||
<h2 id="test-suite-control">Test suite control</h2>
|
||||
<p>It is possible to control various aspects of the test suites using make control variables.</p>
|
||||
<p>These variables use a keyword=value approach to allow multiple values to be set. So, for instance, <code>JTREG="JOBS=1;TIMEOUT_FACTOR=8"</code> will set the JTReg concurrency level to 1 and the timeout factor to 8. This is equivalent to setting <code>JTREG_JOBS=1 JTREG_TIMEOUT_FACTOR=8</code>, but using the keyword format means that the <code>JTREG</code> variable is parsed and verified for correctness, so <code>JTREG="TMIEOUT_FACTOR=8"</code> would give an error, while <code>JTREG_TMIEOUT_FACTOR=8</code> would just pass unnoticed.</p>
|
||||
<p>To separate multiple keyword=value pairs, use <code>;</code> (semicolon). Since the shell normally eats <code>;</code>, the recommended usage is to write the assignment inside qoutes, e.g. <code>JTREG="...;..."</code>. This will also make sure spaces are preserved, as in <code>JTREG="JAVA_OPTIONS=-XshowSettings -Xlog:gc+ref=debug"</code>.</p>
|
||||
<p>(Other ways are possible, e.g. using backslash: <code>JTREG=JOBS=1\;TIMEOUT_FACTOR=8</code>. Also, as a special technique, the string <code>%20</code> will be replaced with space for certain options, e.g. <code>JTREG=JAVA_OPTIONS=-XshowSettings%20-Xlog:gc+ref=debug</code>. This can be useful if you have layers of scripts and have trouble getting proper quoting of command line arguments through.)</p>
|
||||
<p>As far as possible, the names of the keywords have been standardized between test suites.</p>
|
||||
<p>It is possible to control various aspects of the test suites using
|
||||
make control variables.</p>
|
||||
<p>These variables use a keyword=value approach to allow multiple values
|
||||
to be set. So, for instance,
|
||||
<code>JTREG="JOBS=1;TIMEOUT_FACTOR=8"</code> will set the JTReg
|
||||
concurrency level to 1 and the timeout factor to 8. This is equivalent
|
||||
to setting <code>JTREG_JOBS=1 JTREG_TIMEOUT_FACTOR=8</code>, but using
|
||||
the keyword format means that the <code>JTREG</code> variable is parsed
|
||||
and verified for correctness, so <code>JTREG="TMIEOUT_FACTOR=8"</code>
|
||||
would give an error, while <code>JTREG_TMIEOUT_FACTOR=8</code> would
|
||||
just pass unnoticed.</p>
|
||||
<p>To separate multiple keyword=value pairs, use <code>;</code>
|
||||
(semicolon). Since the shell normally eats <code>;</code>, the
|
||||
recommended usage is to write the assignment inside qoutes, e.g.
|
||||
<code>JTREG="...;..."</code>. This will also make sure spaces are
|
||||
preserved, as in
|
||||
<code>JTREG="JAVA_OPTIONS=-XshowSettings -Xlog:gc+ref=debug"</code>.</p>
|
||||
<p>(Other ways are possible, e.g. using backslash:
|
||||
<code>JTREG=JOBS=1\;TIMEOUT_FACTOR=8</code>. Also, as a special
|
||||
technique, the string <code>%20</code> will be replaced with space for
|
||||
certain options, e.g.
|
||||
<code>JTREG=JAVA_OPTIONS=-XshowSettings%20-Xlog:gc+ref=debug</code>.
|
||||
This can be useful if you have layers of scripts and have trouble
|
||||
getting proper quoting of command line arguments through.)</p>
|
||||
<p>As far as possible, the names of the keywords have been standardized
|
||||
between test suites.</p>
|
||||
<h3 id="general-keywords-test_opts">General keywords (TEST_OPTS)</h3>
|
||||
<p>Some keywords are valid across different test suites. If you want to run tests from multiple test suites, or just don't want to care which test suite specific control variable to use, then you can use the general TEST_OPTS control variable.</p>
|
||||
<p>There are also some keywords that applies globally to the test runner system, not to any specific test suites. These are also available as TEST_OPTS keywords.</p>
|
||||
<p>Some keywords are valid across different test suites. If you want to
|
||||
run tests from multiple test suites, or just don't want to care which
|
||||
test suite specific control variable to use, then you can use the
|
||||
general TEST_OPTS control variable.</p>
|
||||
<p>There are also some keywords that applies globally to the test runner
|
||||
system, not to any specific test suites. These are also available as
|
||||
TEST_OPTS keywords.</p>
|
||||
<h4 id="jobs">JOBS</h4>
|
||||
<p>Currently only applies to JTReg.</p>
|
||||
<h4 id="timeout_factor">TIMEOUT_FACTOR</h4>
|
||||
@ -147,28 +390,49 @@ TEST FAILURE</code></pre>
|
||||
<h4 id="aot_modules">AOT_MODULES</h4>
|
||||
<p>Applies to JTReg and GTest.</p>
|
||||
<h4 id="jcov">JCOV</h4>
|
||||
<p>This keywords applies globally to the test runner system. If set to <code>true</code>, it enables JCov coverage reporting for all tests run. To be useful, the JDK under test must be run with a JDK built with JCov instrumentation (<code>configure --with-jcov=<path to directory containing lib/jcov.jar></code>, <code>make jcov-image</code>).</p>
|
||||
<p>The simplest way to run tests with JCov coverage report is to use the special target <code>jcov-test</code> instead of <code>test</code>, e.g. <code>make jcov-test TEST=jdk_lang</code>. This will make sure the JCov image is built, and that JCov reporting is enabled.</p>
|
||||
<p>The JCov report is stored in <code>build/$BUILD/test-results/jcov-output/report</code>.</p>
|
||||
<p>Please note that running with JCov reporting can be very memory intensive.</p>
|
||||
<p>This keywords applies globally to the test runner system. If set to
|
||||
<code>true</code>, it enables JCov coverage reporting for all tests run.
|
||||
To be useful, the JDK under test must be run with a JDK built with JCov
|
||||
instrumentation
|
||||
(<code>configure --with-jcov=<path to directory containing lib/jcov.jar></code>,
|
||||
<code>make jcov-image</code>).</p>
|
||||
<p>The simplest way to run tests with JCov coverage report is to use the
|
||||
special target <code>jcov-test</code> instead of <code>test</code>, e.g.
|
||||
<code>make jcov-test TEST=jdk_lang</code>. This will make sure the JCov
|
||||
image is built, and that JCov reporting is enabled.</p>
|
||||
<p>The JCov report is stored in
|
||||
<code>build/$BUILD/test-results/jcov-output/report</code>.</p>
|
||||
<p>Please note that running with JCov reporting can be very memory
|
||||
intensive.</p>
|
||||
<h4 id="jcov_diff_changeset">JCOV_DIFF_CHANGESET</h4>
|
||||
<p>While collecting code coverage with JCov, it is also possible to find coverage for only recently changed code. JCOV_DIFF_CHANGESET specifies a source revision. A textual report will be generated showing coverage of the diff between the specified revision and the repository tip.</p>
|
||||
<p>The report is stored in <code>build/$BUILD/test-results/jcov-output/diff_coverage_report</code> file.</p>
|
||||
<p>While collecting code coverage with JCov, it is also possible to find
|
||||
coverage for only recently changed code. JCOV_DIFF_CHANGESET specifies a
|
||||
source revision. A textual report will be generated showing coverage of
|
||||
the diff between the specified revision and the repository tip.</p>
|
||||
<p>The report is stored in
|
||||
<code>build/$BUILD/test-results/jcov-output/diff_coverage_report</code>
|
||||
file.</p>
|
||||
<h3 id="jtreg-keywords">JTReg keywords</h3>
|
||||
<h4 id="jobs-1">JOBS</h4>
|
||||
<p>The test concurrency (<code>-concurrency</code>).</p>
|
||||
<p>Defaults to TEST_JOBS (if set by <code>--with-test-jobs=</code>), otherwise it defaults to JOBS, except for Hotspot, where the default is <em>number of CPU cores/2</em>, but never more than <em>memory size in GB/2</em>.</p>
|
||||
<p>Defaults to TEST_JOBS (if set by <code>--with-test-jobs=</code>),
|
||||
otherwise it defaults to JOBS, except for Hotspot, where the default is
|
||||
<em>number of CPU cores/2</em>, but never more than <em>memory size in
|
||||
GB/2</em>.</p>
|
||||
<h4 id="timeout_factor-1">TIMEOUT_FACTOR</h4>
|
||||
<p>The timeout factor (<code>-timeoutFactor</code>).</p>
|
||||
<p>Defaults to 4.</p>
|
||||
<h4 id="failure_handler_timeout">FAILURE_HANDLER_TIMEOUT</h4>
|
||||
<p>Sets the argument <code>-timeoutHandlerTimeout</code> for JTReg. The default value is 0. This is only valid if the failure handler is built.</p>
|
||||
<p>Sets the argument <code>-timeoutHandlerTimeout</code> for JTReg. The
|
||||
default value is 0. This is only valid if the failure handler is
|
||||
built.</p>
|
||||
<h4 id="test_mode">TEST_MODE</h4>
|
||||
<p>The test mode (<code>agentvm</code> or <code>othervm</code>).</p>
|
||||
<p>Defaults to <code>agentvm</code>.</p>
|
||||
<h4 id="assert">ASSERT</h4>
|
||||
<p>Enable asserts (<code>-ea -esa</code>, or none).</p>
|
||||
<p>Set to <code>true</code> or <code>false</code>. If true, adds <code>-ea -esa</code>. Defaults to true, except for hotspot.</p>
|
||||
<p>Set to <code>true</code> or <code>false</code>. If true, adds
|
||||
<code>-ea -esa</code>. Defaults to true, except for hotspot.</p>
|
||||
<h4 id="verbose">VERBOSE</h4>
|
||||
<p>The verbosity level (<code>-verbose</code>).</p>
|
||||
<p>Defaults to <code>fail,error,summary</code>.</p>
|
||||
@ -176,92 +440,172 @@ TEST FAILURE</code></pre>
|
||||
<p>What test data to retain (<code>-retain</code>).</p>
|
||||
<p>Defaults to <code>fail,error</code>.</p>
|
||||
<h4 id="max_mem">MAX_MEM</h4>
|
||||
<p>Limit memory consumption (<code>-Xmx</code> and <code>-vmoption:-Xmx</code>, or none).</p>
|
||||
<p>Limit memory consumption for JTReg test framework and VM under test. Set to 0 to disable the limits.</p>
|
||||
<p>Defaults to 512m, except for hotspot, where it defaults to 0 (no limit).</p>
|
||||
<p>Limit memory consumption (<code>-Xmx</code> and
|
||||
<code>-vmoption:-Xmx</code>, or none).</p>
|
||||
<p>Limit memory consumption for JTReg test framework and VM under test.
|
||||
Set to 0 to disable the limits.</p>
|
||||
<p>Defaults to 512m, except for hotspot, where it defaults to 0 (no
|
||||
limit).</p>
|
||||
<h4 id="max_output">MAX_OUTPUT</h4>
|
||||
<p>Set the property <code>javatest.maxOutputSize</code> for the launcher, to change the default JTReg log limit.</p>
|
||||
<p>Set the property <code>javatest.maxOutputSize</code> for the
|
||||
launcher, to change the default JTReg log limit.</p>
|
||||
<h4 id="keywords">KEYWORDS</h4>
|
||||
<p>JTReg keywords sent to JTReg using <code>-k</code>. Please be careful in making sure that spaces and special characters (like <code>!</code>) are properly quoted. To avoid some issues, the special value <code>%20</code> can be used instead of space.</p>
|
||||
<p>JTReg keywords sent to JTReg using <code>-k</code>. Please be careful
|
||||
in making sure that spaces and special characters (like <code>!</code>)
|
||||
are properly quoted. To avoid some issues, the special value
|
||||
<code>%20</code> can be used instead of space.</p>
|
||||
<h4 id="extra_problem_lists">EXTRA_PROBLEM_LISTS</h4>
|
||||
<p>Use additional problem lists file or files, in addition to the default ProblemList.txt located at the JTReg test roots.</p>
|
||||
<p>If multiple file names are specified, they should be separated by space (or, to help avoid quoting issues, the special value <code>%20</code>).</p>
|
||||
<p>The file names should be either absolute, or relative to the JTReg test root of the tests to be run.</p>
|
||||
<p>Use additional problem lists file or files, in addition to the
|
||||
default ProblemList.txt located at the JTReg test roots.</p>
|
||||
<p>If multiple file names are specified, they should be separated by
|
||||
space (or, to help avoid quoting issues, the special value
|
||||
<code>%20</code>).</p>
|
||||
<p>The file names should be either absolute, or relative to the JTReg
|
||||
test root of the tests to be run.</p>
|
||||
<h4 id="run_problem_lists">RUN_PROBLEM_LISTS</h4>
|
||||
<p>Use the problem lists to select tests instead of excluding them.</p>
|
||||
<p>Set to <code>true</code> or <code>false</code>. If <code>true</code>, JTReg will use <code>-match:</code> option, otherwise <code>-exclude:</code> will be used. Default is <code>false</code>.</p>
|
||||
<p>Set to <code>true</code> or <code>false</code>. If <code>true</code>,
|
||||
JTReg will use <code>-match:</code> option, otherwise
|
||||
<code>-exclude:</code> will be used. Default is <code>false</code>.</p>
|
||||
<h4 id="options">OPTIONS</h4>
|
||||
<p>Additional options to the JTReg test framework.</p>
|
||||
<p>Use <code>JTREG="OPTIONS=--help all"</code> to see all available JTReg options.</p>
|
||||
<p>Use <code>JTREG="OPTIONS=--help all"</code> to see all available
|
||||
JTReg options.</p>
|
||||
<h4 id="java_options-1">JAVA_OPTIONS</h4>
|
||||
<p>Additional Java options for running test classes (sent to JTReg as <code>-javaoption</code>).</p>
|
||||
<p>Additional Java options for running test classes (sent to JTReg as
|
||||
<code>-javaoption</code>).</p>
|
||||
<h4 id="vm_options-1">VM_OPTIONS</h4>
|
||||
<p>Additional Java options to be used when compiling and running classes (sent to JTReg as <code>-vmoption</code>).</p>
|
||||
<p>This option is only needed in special circumstances. To pass Java options to your test classes, use <code>JAVA_OPTIONS</code>.</p>
|
||||
<p>Additional Java options to be used when compiling and running classes
|
||||
(sent to JTReg as <code>-vmoption</code>).</p>
|
||||
<p>This option is only needed in special circumstances. To pass Java
|
||||
options to your test classes, use <code>JAVA_OPTIONS</code>.</p>
|
||||
<h4 id="launcher_options">LAUNCHER_OPTIONS</h4>
|
||||
<p>Additional Java options that are sent to the java launcher that starts the JTReg harness.</p>
|
||||
<p>Additional Java options that are sent to the java launcher that
|
||||
starts the JTReg harness.</p>
|
||||
<h4 id="aot_modules-1">AOT_MODULES</h4>
|
||||
<p>Generate AOT modules before testing for the specified module, or set of modules. If multiple modules are specified, they should be separated by space (or, to help avoid quoting issues, the special value <code>%20</code>).</p>
|
||||
<p>Generate AOT modules before testing for the specified module, or set
|
||||
of modules. If multiple modules are specified, they should be separated
|
||||
by space (or, to help avoid quoting issues, the special value
|
||||
<code>%20</code>).</p>
|
||||
<h4 id="retry_count">RETRY_COUNT</h4>
|
||||
<p>Retry failed tests up to a set number of times, until they pass. This allows to pass the tests with intermittent failures. Defaults to 0.</p>
|
||||
<p>Retry failed tests up to a set number of times, until they pass. This
|
||||
allows to pass the tests with intermittent failures. Defaults to 0.</p>
|
||||
<h4 id="repeat_count">REPEAT_COUNT</h4>
|
||||
<p>Repeat the tests up to a set number of times, stopping at first failure. This helps to reproduce intermittent test failures. Defaults to 0.</p>
|
||||
<p>Repeat the tests up to a set number of times, stopping at first
|
||||
failure. This helps to reproduce intermittent test failures. Defaults to
|
||||
0.</p>
|
||||
<h3 id="gtest-keywords">Gtest keywords</h3>
|
||||
<h4 id="repeat">REPEAT</h4>
|
||||
<p>The number of times to repeat the tests (<code>--gtest_repeat</code>).</p>
|
||||
<p>Default is 1. Set to -1 to repeat indefinitely. This can be especially useful combined with <code>OPTIONS=--gtest_break_on_failure</code> to reproduce an intermittent problem.</p>
|
||||
<p>The number of times to repeat the tests
|
||||
(<code>--gtest_repeat</code>).</p>
|
||||
<p>Default is 1. Set to -1 to repeat indefinitely. This can be
|
||||
especially useful combined with
|
||||
<code>OPTIONS=--gtest_break_on_failure</code> to reproduce an
|
||||
intermittent problem.</p>
|
||||
<h4 id="options-1">OPTIONS</h4>
|
||||
<p>Additional options to the Gtest test framework.</p>
|
||||
<p>Use <code>GTEST="OPTIONS=--help"</code> to see all available Gtest options.</p>
|
||||
<p>Use <code>GTEST="OPTIONS=--help"</code> to see all available Gtest
|
||||
options.</p>
|
||||
<h4 id="aot_modules-2">AOT_MODULES</h4>
|
||||
<p>Generate AOT modules before testing for the specified module, or set of modules. If multiple modules are specified, they should be separated by space (or, to help avoid quoting issues, the special value <code>%20</code>).</p>
|
||||
<p>Generate AOT modules before testing for the specified module, or set
|
||||
of modules. If multiple modules are specified, they should be separated
|
||||
by space (or, to help avoid quoting issues, the special value
|
||||
<code>%20</code>).</p>
|
||||
<h3 id="microbenchmark-keywords">Microbenchmark keywords</h3>
|
||||
<h4 id="fork">FORK</h4>
|
||||
<p>Override the number of benchmark forks to spawn. Same as specifying <code>-f <num></code>.</p>
|
||||
<p>Override the number of benchmark forks to spawn. Same as specifying
|
||||
<code>-f <num></code>.</p>
|
||||
<h4 id="iter">ITER</h4>
|
||||
<p>Number of measurement iterations per fork. Same as specifying <code>-i <num></code>.</p>
|
||||
<p>Number of measurement iterations per fork. Same as specifying
|
||||
<code>-i <num></code>.</p>
|
||||
<h4 id="time">TIME</h4>
|
||||
<p>Amount of time to spend in each measurement iteration, in seconds. Same as specifying <code>-r <num></code></p>
|
||||
<p>Amount of time to spend in each measurement iteration, in seconds.
|
||||
Same as specifying <code>-r <num></code></p>
|
||||
<h4 id="warmup_iter">WARMUP_ITER</h4>
|
||||
<p>Number of warmup iterations to run before the measurement phase in each fork. Same as specifying <code>-wi <num></code>.</p>
|
||||
<p>Number of warmup iterations to run before the measurement phase in
|
||||
each fork. Same as specifying <code>-wi <num></code>.</p>
|
||||
<h4 id="warmup_time">WARMUP_TIME</h4>
|
||||
<p>Amount of time to spend in each warmup iteration. Same as specifying <code>-w <num></code>.</p>
|
||||
<p>Amount of time to spend in each warmup iteration. Same as specifying
|
||||
<code>-w <num></code>.</p>
|
||||
<h4 id="results_format">RESULTS_FORMAT</h4>
|
||||
<p>Specify to have the test run save a log of the values. Accepts the same values as <code>-rff</code>, i.e., <code>text</code>, <code>csv</code>, <code>scsv</code>, <code>json</code>, or <code>latex</code>.</p>
|
||||
<p>Specify to have the test run save a log of the values. Accepts the
|
||||
same values as <code>-rff</code>, i.e., <code>text</code>,
|
||||
<code>csv</code>, <code>scsv</code>, <code>json</code>, or
|
||||
<code>latex</code>.</p>
|
||||
<h4 id="vm_options-2">VM_OPTIONS</h4>
|
||||
<p>Additional VM arguments to provide to forked off VMs. Same as <code>-jvmArgs <args></code></p>
|
||||
<p>Additional VM arguments to provide to forked off VMs. Same as
|
||||
<code>-jvmArgs <args></code></p>
|
||||
<h4 id="options-2">OPTIONS</h4>
|
||||
<p>Additional arguments to send to JMH.</p>
|
||||
<h2 id="notes-for-specific-tests">Notes for Specific Tests</h2>
|
||||
<h3 id="docker-tests">Docker Tests</h3>
|
||||
<p>Docker tests with default parameters may fail on systems with glibc versions not compatible with the one used in the default docker image (e.g., Oracle Linux 7.6 for x86). For example, they pass on Ubuntu 16.04 but fail on Ubuntu 18.04 if run like this on x86:</p>
|
||||
<p>Docker tests with default parameters may fail on systems with glibc
|
||||
versions not compatible with the one used in the default docker image
|
||||
(e.g., Oracle Linux 7.6 for x86). For example, they pass on Ubuntu 16.04
|
||||
but fail on Ubuntu 18.04 if run like this on x86:</p>
|
||||
<pre><code>$ make test TEST="jtreg:test/hotspot/jtreg/containers/docker"</code></pre>
|
||||
<p>To run these tests correctly, additional parameters for the correct docker image are required on Ubuntu 18.04 by using <code>JAVA_OPTIONS</code>.</p>
|
||||
<p>To run these tests correctly, additional parameters for the correct
|
||||
docker image are required on Ubuntu 18.04 by using
|
||||
<code>JAVA_OPTIONS</code>.</p>
|
||||
<pre><code>$ make test TEST="jtreg:test/hotspot/jtreg/containers/docker" \
|
||||
JTREG="JAVA_OPTIONS=-Djdk.test.docker.image.name=ubuntu
|
||||
-Djdk.test.docker.image.version=latest"</code></pre>
|
||||
<h3 id="non-us-locale">Non-US locale</h3>
|
||||
<p>If your locale is non-US, some tests are likely to fail. To work around this you can set the locale to US. On Unix platforms simply setting <code>LANG="en_US"</code> in the environment before running tests should work. On Windows or MacOS, setting <code>JTREG="VM_OPTIONS=-Duser.language=en -Duser.country=US"</code> helps for most, but not all test cases.</p>
|
||||
<p>If your locale is non-US, some tests are likely to fail. To work
|
||||
around this you can set the locale to US. On Unix platforms simply
|
||||
setting <code>LANG="en_US"</code> in the environment before running
|
||||
tests should work. On Windows or MacOS, setting
|
||||
<code>JTREG="VM_OPTIONS=-Duser.language=en -Duser.country=US"</code>
|
||||
helps for most, but not all test cases.</p>
|
||||
<p>For example:</p>
|
||||
<pre><code>$ export LANG="en_US" && make test TEST=...
|
||||
$ make test JTREG="VM_OPTIONS=-Duser.language=en -Duser.country=US" TEST=...</code></pre>
|
||||
<h3 id="pkcs11-tests">PKCS11 Tests</h3>
|
||||
<p>It is highly recommended to use the latest NSS version when running PKCS11 tests. Improper NSS version may lead to unexpected failures which are hard to diagnose. For example, sun/security/pkcs11/Secmod/AddTrustedCert.java may fail on Ubuntu 18.04 with the default NSS version in the system. To run these tests correctly, the system property <code>test.nss.lib.paths</code> is required on Ubuntu 18.04 to specify the alternative NSS lib directories.</p>
|
||||
<p>It is highly recommended to use the latest NSS version when running
|
||||
PKCS11 tests. Improper NSS version may lead to unexpected failures which
|
||||
are hard to diagnose. For example,
|
||||
sun/security/pkcs11/Secmod/AddTrustedCert.java may fail on Ubuntu 18.04
|
||||
with the default NSS version in the system. To run these tests
|
||||
correctly, the system property <code>test.nss.lib.paths</code> is
|
||||
required on Ubuntu 18.04 to specify the alternative NSS lib
|
||||
directories.</p>
|
||||
<p>For example:</p>
|
||||
<pre><code>$ make test TEST="jtreg:sun/security/pkcs11/Secmod/AddTrustedCert.java" \
|
||||
JTREG="JAVA_OPTIONS=-Dtest.nss.lib.paths=/path/to/your/latest/NSS-libs"</code></pre>
|
||||
<p>For more notes about the PKCS11 tests, please refer to test/jdk/sun/security/pkcs11/README.</p>
|
||||
<p>For more notes about the PKCS11 tests, please refer to
|
||||
test/jdk/sun/security/pkcs11/README.</p>
|
||||
<h3 id="client-ui-tests">Client UI Tests</h3>
|
||||
<p>Some Client UI tests use key sequences which may be reserved by the operating system. Usually that causes the test failure. So it is highly recommended to disable system key shortcuts prior testing. The steps to access and disable system key shortcuts for various platforms are provided below.</p>
|
||||
<p>Some Client UI tests use key sequences which may be reserved by the
|
||||
operating system. Usually that causes the test failure. So it is highly
|
||||
recommended to disable system key shortcuts prior testing. The steps to
|
||||
access and disable system key shortcuts for various platforms are
|
||||
provided below.</p>
|
||||
<h4 id="macos">MacOS</h4>
|
||||
<p>Choose Apple menu; System Preferences, click Keyboard, then click Shortcuts; select or deselect desired shortcut.</p>
|
||||
<p>For example, test/jdk/javax/swing/TooltipManager/JMenuItemToolTipKeyBindingsTest/JMenuItemToolTipKeyBindingsTest.java fails on MacOS because it uses <code>CTRL + F1</code> key sequence to show or hide tooltip message but the key combination is reserved by the operating system. To run the test correctly the default global key shortcut should be disabled using the steps described above, and then deselect "Turn keyboard access on or off" option which is responsible for <code>CTRL + F1</code> combination.</p>
|
||||
<p>Choose Apple menu; System Preferences, click Keyboard, then click
|
||||
Shortcuts; select or deselect desired shortcut.</p>
|
||||
<p>For example,
|
||||
test/jdk/javax/swing/TooltipManager/JMenuItemToolTipKeyBindingsTest/JMenuItemToolTipKeyBindingsTest.java
|
||||
fails on MacOS because it uses <code>CTRL + F1</code> key sequence to
|
||||
show or hide tooltip message but the key combination is reserved by the
|
||||
operating system. To run the test correctly the default global key
|
||||
shortcut should be disabled using the steps described above, and then
|
||||
deselect "Turn keyboard access on or off" option which is responsible
|
||||
for <code>CTRL + F1</code> combination.</p>
|
||||
<h4 id="linux">Linux</h4>
|
||||
<p>Open the Activities overview and start typing Settings; Choose Settings, click Devices, then click Keyboard; set or override desired shortcut.</p>
|
||||
<p>Open the Activities overview and start typing Settings; Choose
|
||||
Settings, click Devices, then click Keyboard; set or override desired
|
||||
shortcut.</p>
|
||||
<h4 id="windows">Windows</h4>
|
||||
<p>Type <code>gpedit</code> in the Search and then click Edit group policy; navigate to User Configuration -> Administrative Templates -> Windows Components -> File Explorer; in the right-side pane look for "Turn off Windows key hotkeys" and double click on it; enable or disable hotkeys.</p>
|
||||
<p>Type <code>gpedit</code> in the Search and then click Edit group
|
||||
policy; navigate to User Configuration -> Administrative Templates
|
||||
-> Windows Components -> File Explorer; in the right-side pane
|
||||
look for "Turn off Windows key hotkeys" and double click on it; enable
|
||||
or disable hotkeys.</p>
|
||||
<p>Note: restart is required to make the settings take effect.</p>
|
||||
<h2 id="editing-this-document">Editing this document</h2>
|
||||
<p>If you want to contribute changes to this document, edit <code>doc/testing.md</code> and then run <code>make update-build-docs</code> to generate the same changes in <code>doc/testing.html</code>.</p>
|
||||
<p>If you want to contribute changes to this document, edit
|
||||
<code>doc/testing.md</code> and then run
|
||||
<code>make update-build-docs</code> to generate the same changes in
|
||||
<code>doc/testing.html</code>.</p>
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
Reference in New Issue
Block a user