diff --git a/javatests/google/registry/monitoring/metrics/BUILD b/javatests/google/registry/monitoring/metrics/BUILD
index 522ae8786..922f09d4b 100644
--- a/javatests/google/registry/monitoring/metrics/BUILD
+++ b/javatests/google/registry/monitoring/metrics/BUILD
@@ -12,6 +12,7 @@ java_library(
srcs = glob(["*.java"]),
deps = [
"//java/google/registry/monitoring/metrics",
+ "//third_party/junit",
"@com_google_guava",
"@com_google_truth",
"@com_google_truth_extensions_truth_java8_extension",
diff --git a/javatests/google/registry/monitoring/metrics/CounterTest.java b/javatests/google/registry/monitoring/metrics/CounterTest.java
index 9f794bb16..949c635fb 100644
--- a/javatests/google/registry/monitoring/metrics/CounterTest.java
+++ b/javatests/google/registry/monitoring/metrics/CounterTest.java
@@ -15,7 +15,7 @@
package google.registry.monitoring.metrics;
import static com.google.common.truth.Truth.assertThat;
-import static google.registry.monitoring.metrics.JUnitBackports.expectThrows;
+import static google.registry.testing.JUnitBackports.expectThrows;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
diff --git a/javatests/google/registry/monitoring/metrics/CustomFitterTest.java b/javatests/google/registry/monitoring/metrics/CustomFitterTest.java
index 3044c6785..d85d1645f 100644
--- a/javatests/google/registry/monitoring/metrics/CustomFitterTest.java
+++ b/javatests/google/registry/monitoring/metrics/CustomFitterTest.java
@@ -15,7 +15,7 @@
package google.registry.monitoring.metrics;
import static com.google.common.truth.Truth.assertThat;
-import static google.registry.monitoring.metrics.JUnitBackports.expectThrows;
+import static google.registry.testing.JUnitBackports.expectThrows;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
diff --git a/javatests/google/registry/monitoring/metrics/EventMetricTest.java b/javatests/google/registry/monitoring/metrics/EventMetricTest.java
index d9416b23c..7124ab175 100644
--- a/javatests/google/registry/monitoring/metrics/EventMetricTest.java
+++ b/javatests/google/registry/monitoring/metrics/EventMetricTest.java
@@ -15,7 +15,7 @@
package google.registry.monitoring.metrics;
import static com.google.common.truth.Truth.assertThat;
-import static google.registry.monitoring.metrics.JUnitBackports.expectThrows;
+import static google.registry.testing.JUnitBackports.expectThrows;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableRangeMap;
diff --git a/javatests/google/registry/monitoring/metrics/ExponentialFitterTest.java b/javatests/google/registry/monitoring/metrics/ExponentialFitterTest.java
index 2b007fb26..a8f25aa18 100644
--- a/javatests/google/registry/monitoring/metrics/ExponentialFitterTest.java
+++ b/javatests/google/registry/monitoring/metrics/ExponentialFitterTest.java
@@ -15,7 +15,7 @@
package google.registry.monitoring.metrics;
import static com.google.common.truth.Truth.assertThat;
-import static google.registry.monitoring.metrics.JUnitBackports.expectThrows;
+import static google.registry.testing.JUnitBackports.expectThrows;
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/javatests/google/registry/monitoring/metrics/FibonacciFitterTest.java b/javatests/google/registry/monitoring/metrics/FibonacciFitterTest.java
index bb86b952d..c58dc5141 100644
--- a/javatests/google/registry/monitoring/metrics/FibonacciFitterTest.java
+++ b/javatests/google/registry/monitoring/metrics/FibonacciFitterTest.java
@@ -15,7 +15,7 @@
package google.registry.monitoring.metrics;
import static com.google.common.truth.Truth.assertThat;
-import static google.registry.monitoring.metrics.JUnitBackports.expectThrows;
+import static google.registry.testing.JUnitBackports.expectThrows;
import com.google.common.collect.ImmutableList;
import org.junit.Test;
diff --git a/javatests/google/registry/monitoring/metrics/JUnitBackports.java b/javatests/google/registry/monitoring/metrics/JUnitBackports.java
deleted file mode 100644
index 3ee402777..000000000
--- a/javatests/google/registry/monitoring/metrics/JUnitBackports.java
+++ /dev/null
@@ -1,122 +0,0 @@
-package google.registry.monitoring.metrics;
-
-/**
- * A testing utility class that contains backports of useful but not yet released JUnit methods.
- *
- *
All of this code was taken directly from
- * https://github.com/junit-team/junit4/blob/a832c5afe5b0e7c2590d057a1a49a344d207f8a0/src/main/java/org/junit/Assert.java
- */
-public class JUnitBackports {
- // TODO(b/68257761): Delete these and switch over to JUnit 4.13 methods upon release.
-
- /**
- * This interface facilitates the use of expectThrows from Java 8. It allows method references to
- * void methods (that declare checked exceptions) to be passed directly into expectThrows without
- * wrapping. It is not meant to be implemented directly.
- *
- * @since 4.13
- */
- public interface ThrowingRunnable {
- void run() throws Throwable;
- }
-
- /**
- * Asserts that {@code runnable} throws an exception of type {@code expectedThrowable} when
- * executed. If it does not throw an exception, an {@link AssertionError} is thrown. If it throws
- * the wrong type of exception, an {@code AssertionError} is thrown describing the mismatch; the
- * exception that was actually thrown can be obtained by calling {@link AssertionError#getCause}.
- *
- * @param expectedThrowable the expected type of the exception
- * @param runnable a function that is expected to throw an exception when executed
- * @since 4.13
- */
- public static void assertThrows(
- Class extends Throwable> expectedThrowable, ThrowingRunnable runnable) {
- expectThrows(expectedThrowable, runnable);
- }
-
- /**
- * Asserts that {@code runnable} throws an exception of type {@code expectedThrowable} when
- * executed. If it does, the exception object is returned. If it does not throw an exception, an
- * {@link AssertionError} is thrown. If it throws the wrong type of exception, an {@code
- * AssertionError} is thrown describing the mismatch; the exception that was actually thrown can
- * be obtained by calling {@link AssertionError#getCause}.
- *
- * @param expectedThrowable the expected type of the exception
- * @param runnable a function that is expected to throw an exception when executed
- * @return the exception thrown by {@code runnable}
- * @since 4.13
- */
- public static T expectThrows(
- Class expectedThrowable, ThrowingRunnable runnable) {
- try {
- runnable.run();
- } catch (Throwable actualThrown) {
- if (expectedThrowable.isInstance(actualThrown)) {
- @SuppressWarnings("unchecked")
- T retVal = (T) actualThrown;
- return retVal;
- } else {
- String expected = formatClass(expectedThrowable);
- Class extends Throwable> actualThrowable = actualThrown.getClass();
- String actual = formatClass(actualThrowable);
- if (expected.equals(actual)) {
- // There must be multiple class loaders. Add the identity hash code so the message
- // doesn't say "expected: java.lang.String ..."
- expected += "@" + Integer.toHexString(System.identityHashCode(expectedThrowable));
- actual += "@" + Integer.toHexString(System.identityHashCode(actualThrowable));
- }
- String mismatchMessage = format("unexpected exception type thrown;", expected, actual);
-
- // The AssertionError(String, Throwable) ctor is only available on JDK7.
- AssertionError assertionError = new AssertionError(mismatchMessage);
- assertionError.initCause(actualThrown);
- throw assertionError;
- }
- }
- String message =
- String.format(
- "expected %s to be thrown, but nothing was thrown", formatClass(expectedThrowable));
- throw new AssertionError(message);
- }
-
- static String format(String message, Object expected, Object actual) {
- String formatted = "";
- if (message != null && !"".equals(message)) {
- formatted = message + " ";
- }
- String expectedString = String.valueOf(expected);
- String actualString = String.valueOf(actual);
- if (equalsRegardingNull(expectedString, actualString)) {
- return formatted
- + "expected: "
- + formatClassAndValue(expected, expectedString)
- + " but was: "
- + formatClassAndValue(actual, actualString);
- } else {
- return formatted + "expected:<" + expectedString + "> but was:<" + actualString + ">";
- }
- }
-
- private static String formatClass(Class> value) {
- String className = value.getCanonicalName();
- return className == null ? value.getName() : className;
- }
-
- private static String formatClassAndValue(Object value, String valueString) {
- String className = value == null ? "null" : value.getClass().getName();
- return className + "<" + valueString + ">";
- }
-
- private static boolean equalsRegardingNull(Object expected, Object actual) {
- if (expected == null) {
- return actual == null;
- }
-
- return isEquals(expected, actual);
- }
-
- private static boolean isEquals(Object expected, Object actual) {
- return expected.equals(actual);
- }
-}
diff --git a/javatests/google/registry/monitoring/metrics/LabelDescriptorTest.java b/javatests/google/registry/monitoring/metrics/LabelDescriptorTest.java
index 854daa781..1d7def2a5 100644
--- a/javatests/google/registry/monitoring/metrics/LabelDescriptorTest.java
+++ b/javatests/google/registry/monitoring/metrics/LabelDescriptorTest.java
@@ -15,7 +15,7 @@
package google.registry.monitoring.metrics;
import static com.google.common.truth.Truth.assertThat;
-import static google.registry.monitoring.metrics.JUnitBackports.expectThrows;
+import static google.registry.testing.JUnitBackports.expectThrows;
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/javatests/google/registry/monitoring/metrics/LinearFitterTest.java b/javatests/google/registry/monitoring/metrics/LinearFitterTest.java
index de9b957cc..f4ced9c6b 100644
--- a/javatests/google/registry/monitoring/metrics/LinearFitterTest.java
+++ b/javatests/google/registry/monitoring/metrics/LinearFitterTest.java
@@ -15,7 +15,7 @@
package google.registry.monitoring.metrics;
import static com.google.common.truth.Truth.assertThat;
-import static google.registry.monitoring.metrics.JUnitBackports.expectThrows;
+import static google.registry.testing.JUnitBackports.expectThrows;
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/javatests/google/registry/monitoring/metrics/MetricRegistryImplTest.java b/javatests/google/registry/monitoring/metrics/MetricRegistryImplTest.java
index 4884cdef2..3ee96cd22 100644
--- a/javatests/google/registry/monitoring/metrics/MetricRegistryImplTest.java
+++ b/javatests/google/registry/monitoring/metrics/MetricRegistryImplTest.java
@@ -15,7 +15,7 @@
package google.registry.monitoring.metrics;
import static com.google.common.truth.Truth.assertThat;
-import static google.registry.monitoring.metrics.JUnitBackports.expectThrows;
+import static google.registry.testing.JUnitBackports.expectThrows;
import static org.mockito.Mockito.mock;
import com.google.common.collect.ImmutableList;
diff --git a/javatests/google/registry/monitoring/metrics/MetricSchemaTest.java b/javatests/google/registry/monitoring/metrics/MetricSchemaTest.java
index 7f2d4c1ca..ea4a689a1 100644
--- a/javatests/google/registry/monitoring/metrics/MetricSchemaTest.java
+++ b/javatests/google/registry/monitoring/metrics/MetricSchemaTest.java
@@ -15,7 +15,7 @@
package google.registry.monitoring.metrics;
import static com.google.common.truth.Truth.assertThat;
-import static google.registry.monitoring.metrics.JUnitBackports.expectThrows;
+import static google.registry.testing.JUnitBackports.expectThrows;
import com.google.common.collect.ImmutableSet;
import google.registry.monitoring.metrics.MetricSchema.Kind;
diff --git a/javatests/google/registry/monitoring/metrics/MutableDistributionTest.java b/javatests/google/registry/monitoring/metrics/MutableDistributionTest.java
index bba75783d..02c7dca40 100644
--- a/javatests/google/registry/monitoring/metrics/MutableDistributionTest.java
+++ b/javatests/google/registry/monitoring/metrics/MutableDistributionTest.java
@@ -15,7 +15,7 @@
package google.registry.monitoring.metrics;
import static com.google.common.truth.Truth.assertThat;
-import static google.registry.monitoring.metrics.JUnitBackports.expectThrows;
+import static google.registry.testing.JUnitBackports.expectThrows;
import com.google.common.collect.ImmutableRangeMap;
import com.google.common.collect.ImmutableSet;
diff --git a/javatests/google/registry/monitoring/metrics/StoredMetricTest.java b/javatests/google/registry/monitoring/metrics/StoredMetricTest.java
index 62b0918f4..7732f085b 100644
--- a/javatests/google/registry/monitoring/metrics/StoredMetricTest.java
+++ b/javatests/google/registry/monitoring/metrics/StoredMetricTest.java
@@ -15,7 +15,7 @@
package google.registry.monitoring.metrics;
import static com.google.common.truth.Truth.assertThat;
-import static google.registry.monitoring.metrics.JUnitBackports.expectThrows;
+import static google.registry.testing.JUnitBackports.expectThrows;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
diff --git a/javatests/google/registry/monitoring/metrics/contrib/BUILD b/javatests/google/registry/monitoring/metrics/contrib/BUILD
index 3d35e1445..5d4efe8a7 100644
--- a/javatests/google/registry/monitoring/metrics/contrib/BUILD
+++ b/javatests/google/registry/monitoring/metrics/contrib/BUILD
@@ -13,7 +13,7 @@ java_library(
deps = [
"//java/google/registry/monitoring/metrics",
"//java/google/registry/monitoring/metrics/contrib",
- "//javatests/google/registry/monitoring/metrics",
+ "//third_party/junit",
"@com_google_guava",
"@com_google_truth",
"@com_google_truth_extensions_truth_java8_extension",
diff --git a/javatests/google/registry/monitoring/metrics/contrib/DistributionMetricSubjectTest.java b/javatests/google/registry/monitoring/metrics/contrib/DistributionMetricSubjectTest.java
index 7fd0db04a..832415691 100644
--- a/javatests/google/registry/monitoring/metrics/contrib/DistributionMetricSubjectTest.java
+++ b/javatests/google/registry/monitoring/metrics/contrib/DistributionMetricSubjectTest.java
@@ -15,8 +15,8 @@
package google.registry.monitoring.metrics.contrib;
import static com.google.common.truth.Truth.assertThat;
-import static google.registry.monitoring.metrics.JUnitBackports.expectThrows;
import static google.registry.monitoring.metrics.contrib.DistributionMetricSubject.assertThat;
+import static google.registry.testing.JUnitBackports.expectThrows;
import com.google.common.collect.ImmutableSet;
import google.registry.monitoring.metrics.EventMetric;
diff --git a/javatests/google/registry/monitoring/metrics/contrib/LongMetricSubjectTest.java b/javatests/google/registry/monitoring/metrics/contrib/LongMetricSubjectTest.java
index b78abf8d2..0e4155274 100644
--- a/javatests/google/registry/monitoring/metrics/contrib/LongMetricSubjectTest.java
+++ b/javatests/google/registry/monitoring/metrics/contrib/LongMetricSubjectTest.java
@@ -15,8 +15,8 @@
package google.registry.monitoring.metrics.contrib;
import static com.google.common.truth.Truth.assertThat;
-import static google.registry.monitoring.metrics.JUnitBackports.expectThrows;
import static google.registry.monitoring.metrics.contrib.LongMetricSubject.assertThat;
+import static google.registry.testing.JUnitBackports.expectThrows;
import com.google.common.collect.ImmutableSet;
import google.registry.monitoring.metrics.IncrementableMetric;
diff --git a/javatests/google/registry/monitoring/metrics/stackdriver/BUILD b/javatests/google/registry/monitoring/metrics/stackdriver/BUILD
index fd3b26751..593d4724b 100644
--- a/javatests/google/registry/monitoring/metrics/stackdriver/BUILD
+++ b/javatests/google/registry/monitoring/metrics/stackdriver/BUILD
@@ -13,7 +13,7 @@ java_library(
deps = [
"//java/google/registry/monitoring/metrics",
"//java/google/registry/monitoring/metrics/stackdriver",
- "//javatests/google/registry/monitoring/metrics",
+ "//third_party/junit",
"@com_google_api_client",
"@com_google_apis_google_api_services_monitoring",
"@com_google_guava",
diff --git a/javatests/google/registry/monitoring/metrics/stackdriver/StackdriverWriterTest.java b/javatests/google/registry/monitoring/metrics/stackdriver/StackdriverWriterTest.java
index 3b3fe3f83..6becb8c92 100644
--- a/javatests/google/registry/monitoring/metrics/stackdriver/StackdriverWriterTest.java
+++ b/javatests/google/registry/monitoring/metrics/stackdriver/StackdriverWriterTest.java
@@ -15,7 +15,7 @@
package google.registry.monitoring.metrics.stackdriver;
import static com.google.common.truth.Truth.assertThat;
-import static google.registry.monitoring.metrics.JUnitBackports.assertThrows;
+import static google.registry.testing.JUnitBackports.assertThrows;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
diff --git a/javatests/google/registry/testing/BUILD b/javatests/google/registry/testing/BUILD
index ebc11d7b4..7bfedbe13 100644
--- a/javatests/google/registry/testing/BUILD
+++ b/javatests/google/registry/testing/BUILD
@@ -19,6 +19,7 @@ java_library(
"//java/google/registry:env/common/default/WEB-INF/datastore-indexes.xml",
"//java/google/registry:env/common/default/WEB-INF/queue.xml",
] + glob(["*.csv"]) + glob(["testdata/*"]),
+ exports = ["//third_party/junit"],
deps = [
"//java/google/registry/config",
"//java/google/registry/dns:constants",
diff --git a/third_party/junit/BUILD b/third_party/junit/BUILD
new file mode 100644
index 000000000..590b35e3f
--- /dev/null
+++ b/third_party/junit/BUILD
@@ -0,0 +1,16 @@
+package(
+ default_visibility = ["//visibility:public"],
+)
+
+licenses(["reciprocal"]) # EPL 1.0
+
+exports_files(["LICENSE"])
+
+java_library(
+ name = "junit",
+ srcs = glob(["**/*.java"]),
+ visibility = [
+ "//javatests/google/registry/monitoring/metrics:__subpackages__",
+ "//javatests/google/registry/testing:__pkg__",
+ ],
+)
diff --git a/third_party/junit/LICENSE b/third_party/junit/LICENSE
new file mode 100644
index 000000000..c8824a5a5
--- /dev/null
+++ b/third_party/junit/LICENSE
@@ -0,0 +1,214 @@
+JUnit
+
+Eclipse Public License - v 1.0
+
+THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
+LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM
+CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+"Contribution" means:
+
+ a) in the case of the initial Contributor, the initial code and
+ documentation distributed under this Agreement, and
+ b) in the case of each subsequent Contributor:
+
+ i) changes to the Program, and
+
+ ii) additions to the Program;
+
+ where such changes and/or additions to the Program originate from and are
+distributed by that particular Contributor. A Contribution 'originates' from a
+Contributor if it was added to the Program by such Contributor itself or anyone
+acting on such Contributor's behalf. Contributions do not include additions to
+the Program which: (i) are separate modules of software distributed in
+conjunction with the Program under their own license agreement, and (ii) are
+not derivative works of the Program.
+
+"Contributor" means any person or entity that distributes the Program.
+
+"Licensed Patents " mean patent claims licensable by a Contributor which are
+necessarily infringed by the use or sale of its Contribution alone or when
+combined with the Program.
+
+"Program" means the Contributions distributed in accordance with this Agreement.
+
+"Recipient" means anyone who receives the Program under this Agreement,
+including all Contributors.
+
+2. GRANT OF RIGHTS
+
+ a) Subject to the terms of this Agreement, each Contributor hereby grants
+Recipient a non-exclusive, worldwide, royalty-free copyright license to
+reproduce, prepare derivative works of, publicly display, publicly perform,
+distribute and sublicense the Contribution of such Contributor, if any, and
+such derivative works, in source code and object code form.
+
+ b) Subject to the terms of this Agreement, each Contributor hereby grants
+Recipient a non-exclusive, worldwide, royalty-free patent license under
+Licensed Patents to make, use, sell, offer to sell, import and otherwise
+transfer the Contribution of such Contributor, if any, in source code and
+object code form. This patent license shall apply to the combination of the
+Contribution and the Program if, at the time the Contribution is added by the
+Contributor, such addition of the Contribution causes such combination to be
+covered by the Licensed Patents. The patent license shall not apply to any
+other combinations which include the Contribution. No hardware per se is
+licensed hereunder.
+
+ c) Recipient understands that although each Contributor grants the
+licenses to its Contributions set forth herein, no assurances are provided by
+any Contributor that the Program does not infringe the patent or other
+intellectual property rights of any other entity. Each Contributor disclaims
+any liability to Recipient for claims brought by any other entity based on
+infringement of intellectual property rights or otherwise. As a condition to
+exercising the rights and licenses granted hereunder, each Recipient hereby
+assumes sole responsibility to secure any other intellectual property rights
+needed, if any. For example, if a third party patent license is required to
+allow Recipient to distribute the Program, it is Recipient's responsibility to
+acquire that license before distributing the Program.
+
+ d) Each Contributor represents that to its knowledge it has sufficient
+copyright rights in its Contribution, if any, to grant the copyright license
+set forth in this Agreement.
+
+3. REQUIREMENTS
+
+A Contributor may choose to distribute the Program in object code form under
+its own license agreement, provided that:
+
+ a) it complies with the terms and conditions of this Agreement; and
+
+ b) its license agreement:
+
+ i) effectively disclaims on behalf of all Contributors all warranties and
+conditions, express and implied, including warranties or conditions of title
+and non-infringement, and implied warranties or conditions of merchantability
+and fitness for a particular purpose;
+
+ ii) effectively excludes on behalf of all Contributors all liability for
+damages, including direct, indirect, special, incidental and consequential
+damages, such as lost profits;
+
+ iii) states that any provisions which differ from this Agreement are
+offered by that Contributor alone and not by any other party; and
+
+ iv) states that source code for the Program is available from such
+Contributor, and informs licensees how to obtain it in a reasonable manner on
+or through a medium customarily used for software exchange
+
+When the Program is made available in source code form:
+
+ a) it must be made available under this Agreement; and
+
+ b) a copy of this Agreement must be included with each copy of the
+Program.
+
+Contributors may not remove or alter any copyright notices contained within the
+Program.
+
+Each Contributor must identify itself as the originator of its Contribution, if
+any, in a manner that reasonably allows subsequent Recipients to identify the
+originator of the Contribution.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain responsibilities with
+respect to end users, business partners and the like. While this license is
+intended to facilitate the commercial use of the Program, the Contributor who
+includes the Program in a commercial product offering should do so in a manner
+which does not create potential liability for other Contributors. Therefore, if
+a Contributor includes the Program in a commercial product offering, such
+Contributor ("Commercial Contributor") hereby agrees to defend and indemnify
+every other Contributor ("Indemnified Contributor") against any losses, damages
+and costs (collectively "Losses") arising from claims, lawsuits and other legal
+actions brought by a third party against the Indemnified Contributor to the
+extent caused by the acts or omissions of such Commercial Contributor in
+connection with its distribution of the Program in a commercial product
+offering. The obligations in this section do not apply to any claims or Losses
+relating to any actual or alleged intellectual property infringement. In order
+to qualify, an Indemnified Contributor must: a) promptly notify the Commercial
+Contributor in writing of such claim, and b) allow the Commercial Contributor
+to control, and cooperate with the Commercial Contributor in, the defense and
+any related settlement negotiations. The Indemnified Contributor may
+participate in any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial product
+offering, Product X. That Contributor is then a Commercial Contributor. If that
+Commercial Contributor then makes performance claims, or offers warranties
+related to Product X, those performance claims and warranties are such
+Commercial Contributor's responsibility alone. Under this section, the
+Commercial Contributor would have to defend claims against the other
+Contributors related to those performance claims and warranties, and if a court
+requires any other Contributor to pay any damages as a result, the Commercial
+Contributor must pay those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
+IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each
+Recipient is solely responsible for determining the appropriateness of using
+and distributing the Program and assumes all risks associated with its exercise
+of rights under this Agreement, including but not limited to the risks and
+costs of program errors, compliance with applicable laws, damage to or loss of
+data, programs or equipment, and unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
+CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST
+PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS
+GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under applicable
+law, it shall not affect the validity or enforceability of the remainder of the
+terms of this Agreement, and without further action by the parties hereto, such
+provision shall be reformed to the minimum extent necessary to make such
+provision valid and enforceable.
+
+If Recipient institutes patent litigation against any
+entity (including a cross-claim or counterclaim in a lawsuit) alleging that the
+Program itself (excluding combinations of the Program with other software or
+hardware) infringes such Recipient's patent(s), then such Recipient's rights
+granted under Section 2(b) shall terminate as of the date such litigation is
+filed.
+
+All Recipient's rights under this Agreement shall terminate if it fails to
+comply with any of the material terms or conditions of this Agreement and does
+not cure such failure in a reasonable period of time after becoming aware of
+such noncompliance. If all Recipient's rights under this Agreement terminate,
+Recipient agrees to cease use and distribution of the Program as soon as
+reasonably practicable. However, Recipient's obligations under this Agreement
+and any licenses granted by Recipient relating to the Program shall continue
+and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement, but in
+order to avoid inconsistency the Agreement is copyrighted and may only be
+modified in the following manner. The Agreement Steward reserves the right to
+publish new versions (including revisions) of this Agreement from time to time.
+No one other than the Agreement Steward has the right to modify this Agreement.
+The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to
+serve as the Agreement Steward to a suitable separate entity. Each new version
+of the Agreement will be given a distinguishing version number. The Program
+(including Contributions) may always be distributed subject to the version of
+the Agreement under which it was received. In addition, after a new version of
+the Agreement is published, Contributor may elect to distribute the Program
+(including its Contributions) under the new version. Except as expressly stated
+in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to
+the intellectual property of any Contributor under this Agreement, whether
+expressly, by implication, estoppel or otherwise. All rights in the Program not
+expressly granted under this Agreement are reserved.
+
+This Agreement is governed by the laws of the State of New York and the
+intellectual property laws of the United States of America. No party to this
+Agreement will bring a legal action under this Agreement more than one year
+after the cause of action arose. Each party waives its rights to a jury trial
+in any resulting litigation.
+
diff --git a/javatests/google/registry/testing/JUnitBackports.java b/third_party/junit/google/registry/testing/JUnitBackports.java
similarity index 100%
rename from javatests/google/registry/testing/JUnitBackports.java
rename to third_party/junit/google/registry/testing/JUnitBackports.java