Compare commits

..
Author SHA1 Message Date
Weimin YuandGitHub 0fcf26def0 Exclude proxy configs from the FOSS jar (#558)
* Exclude proxy configs from the FOSS jar

No sensitve data exposed.

Added a todo to modify the release process and stop
building the foss jar on the merged repo.
2020-04-15 12:21:41 -04:00
gbrodmanandGitHub 3d88ba4e1b Add verification that domain labels aren't multi-level domains (#553)
* Add verification that domain labels aren't multi-level domains

In addition, I did a bit of test refactoring because previously, the
CreateOrUpdateReserveListCommandTestCase test cases weren't actually
testing the proper things -- they were failing with
IllegalArgumentExceptions, but not the right ones.

* Change test name and use IDN library

* Handle numeric labels

String like "0" or "2018" are valid labels but not valid domain names

* Use IDN validation with a dummy TLD
2020-04-15 11:54:40 -04:00
Weimin YuandGitHub 580a3b6981 Disable JpaEntityCoverageCheck by default (#555)
* Disable JpaEntityCoverageCheck by default

Only members of SqlIntegrationTestSuite should enable the check,
which incurs per-test overhead.
2020-04-14 12:48:21 -04:00
gbrodmanandGitHub 6990d6058f Allow a --token option when checking a domain (#556)
* Allow a --token option when checking a domain
2020-04-14 10:20:27 -04:00
gbrodmanandGitHub dfeed63c40 Run automated NPM update (#554) 2020-04-11 11:47:25 -04:00
Lai JiangandGitHub 9eac9621cb Add a Test workaround for certain Linux distro (#552)
On Arch Linux, DumpGoldenSchemaCommandTest failed due to the follow
error:

java.lang.RuntimeException: Container.ExecResult(exitCode=1, stdout=, stderr=pg_dump: [archiver] could not open output file "/tmp/pg_dump.out": Is a directory)

However I cannot figure out why this permission error happens, as the
docker command is executed as root. Saving the pg_dump output to a
temporary file and copy it over the mapped file works, so I don't
know...
2020-04-10 12:44:36 -04:00
Weimin YuandGitHub b7efc5dd25 Migrate SqlIntegrationTestSuite members to Junit5 (#550)
* Migrate SqlIntegrationTestSuite members  to Junit5

Made InjectRule and EntityTestCase work with both JUnit4 and 5.

Note that "@RunWith(JUnit4.class)" is no longer needed on
JUnit4 test classes. Therefore, its removal from EntityTestCase
has no impact on child classes. All of them are still included in
tests.

Migrated remaining member classes in SqlIntegrationTestSuite to JUnit5.
2020-04-09 12:54:16 -04:00
Weimin YuandGitHub 1911c11623 Add Test suite support for JUnit 5 classes (#549)
* Add Test suite support for JUnit 5 classes

Added Gradle dependencies and updated lockfiles.

Updated SqlInegrationTestSuite to use new annotations.

Migrated one member class in SqlIntegrationTestSuite (CursorDaoTest)
to JUnit 5, and verified that the new Suite runner can handle a
mixture of JUnit 4 and 5 tests in one suite.

Note that Gradle tests that run TestSuites must choose JUnit 4.
Updated core/build.gradle and integration/build.gradle.
2020-04-07 21:06:49 -04:00
Weimin YuandGitHub b8df0bac24 Make AppEngineRule work with JUnit 5 (#548)
* Make AppEngineRule work with JUnit 5

Made AppEngineRule work with both JUnit4 and JUnit 5 and applied
it to PremiumListTest.

Next step is to convert SqlIntegrationTestSuite.java to JUnit5.
2020-04-07 14:59:25 -04:00
Lai JiangandGitHub 0561c7754e Upgrade to Gradle 6.3 (#546) 2020-04-06 22:14:14 -04:00
Weimin YuandGitHub 904f16c8b5 Actually run JUnit 5 tests (#545)
* Actually run JUnit 5 tests

In Gradle, JUnit 5 must be explicitly enabled with a call to
test.useJUnitPlatform().

The FilteringTest used in :core must also enable JUnit5 separately.

Fixed AppEngineRule to work with the few tests that have migrated
to JUnit5.

More work is needed with AppEngine before we can migrate tests
that actually use Cloud SQL.

For context, with @EnableRuleMigrationSupport, JUnit 5 runner calls
an external resource's before() and after() methods. TestRule.apply()
is not called, therefore any setup done their will be bypassed with
JUnit 5.
2020-04-06 13:26:38 -04:00
Weimin YuandGitHub 3a7d71e411 Upgrade CompareDbBackup for Datastore V3 (#543)
* Upgrade CompareDbBackup for Datastore V3

Upgrade the CompareDbBackup class to work with latest
Datastore backup directory structure.

Also fixed a few unrelated minor issues:
- Remaining cases of improper use of System.setOut
- Wrong import order in one class
2020-04-06 10:50:38 -04:00
Shicong HuangandGitHub 1ded33ecea Resolve warnings in the Hibernate log (#542) 2020-04-03 18:04:55 -04:00
Shicong HuangandGitHub bf4659f11c Auto-apply JPA converters for map type (#520)
* Add map converter

* Delete old map usertype

* Refactor bind

* Change to use map entry

* Use Map.Entry
2020-04-03 10:47:42 -04:00
Shicong HuangandGitHub bac1998d6a Auto-apply JPA converters for map type (#520)
* Add map converter

* Delete old map usertype

* Refactor bind

* Change to use map entry

* Use Map.Entry
2020-04-02 16:43:08 -04:00
gbrodmanandGitHub 4a34369ba9 Submit a task to relock domains if desired upon verification (#529)
* Submit a task to relock domains if desired upon verification

* Merge remote-tracking branch 'origin/master' into verifyRelock

* Respond to CR
2020-04-02 15:18:29 -04:00
Shicong HuangandGitHub db7d49801d Supress exccesive logging message from Cloud SQL (#540)
* Supress exccesive logging message from Cloud SQL

* Upgrade package versions that were downgraded before
2020-03-31 17:57:18 -04:00
sarahcaseybotandGitHub 0c52d209e5 Fix IllegalArgumentException (#536)
* Fix IllegalArgumentException

* Add more information about global locks

* Add null checks
2020-03-30 11:36:09 -04:00
gbrodmanandGitHub 73b98d298b Add a set of radio buttons for relock duration (#535)
* Add a set of radio buttons for relock duration
2020-03-30 11:06:32 -04:00
Michael MullerandGitHub 7880aab386 Fix optional access for VKey nested keys (#539)
* Fix optional access for VKey nested keys

We should have used ofNullable() instead of of() for key creation.  Also add a
unit test.
2020-03-30 11:01:25 -04:00
170 changed files with 2272 additions and 1404 deletions
@@ -61,12 +61,12 @@ org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:2.10.0
org.hamcrest:hamcrest-core:1.3
org.json:json:20160212
org.junit.jupiter:junit-jupiter-api:5.6.0
org.junit.jupiter:junit-jupiter-engine:5.6.0
org.junit.platform:junit-platform-commons:1.6.0
org.junit.platform:junit-platform-engine:1.6.0
org.junit.vintage:junit-vintage-engine:5.6.0
org.junit:junit-bom:5.6.0
org.junit.jupiter:junit-jupiter-api:5.6.1
org.junit.jupiter:junit-jupiter-engine:5.6.1
org.junit.platform:junit-platform-commons:1.6.1
org.junit.platform:junit-platform-engine:1.6.1
org.junit.vintage:junit-vintage-engine:5.6.1
org.junit:junit-bom:5.6.1
org.mockito:mockito-core:2.25.0
org.objenesis:objenesis:2.6
org.opentest4j:opentest4j:1.2.0
@@ -61,12 +61,12 @@ org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:2.10.0
org.hamcrest:hamcrest-core:1.3
org.json:json:20160212
org.junit.jupiter:junit-jupiter-api:5.6.0
org.junit.jupiter:junit-jupiter-engine:5.6.0
org.junit.platform:junit-platform-commons:1.6.0
org.junit.platform:junit-platform-engine:1.6.0
org.junit.vintage:junit-vintage-engine:5.6.0
org.junit:junit-bom:5.6.0
org.junit.jupiter:junit-jupiter-api:5.6.1
org.junit.jupiter:junit-jupiter-engine:5.6.1
org.junit.platform:junit-platform-commons:1.6.1
org.junit.platform:junit-platform-engine:1.6.1
org.junit.vintage:junit-vintage-engine:5.6.1
org.junit:junit-bom:5.6.1
org.mockito:mockito-core:2.25.0
org.objenesis:objenesis:2.6
org.opentest4j:opentest4j:1.2.0
@@ -61,12 +61,12 @@ org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:2.10.0
org.hamcrest:hamcrest-core:1.3
org.json:json:20160212
org.junit.jupiter:junit-jupiter-api:5.6.0
org.junit.jupiter:junit-jupiter-engine:5.6.0
org.junit.platform:junit-platform-commons:1.6.0
org.junit.platform:junit-platform-engine:1.6.0
org.junit.vintage:junit-vintage-engine:5.6.0
org.junit:junit-bom:5.6.0
org.junit.jupiter:junit-jupiter-api:5.6.1
org.junit.jupiter:junit-jupiter-engine:5.6.1
org.junit.platform:junit-platform-commons:1.6.1
org.junit.platform:junit-platform-engine:1.6.1
org.junit.vintage:junit-vintage-engine:5.6.1
org.junit:junit-bom:5.6.1
org.mockito:mockito-core:2.25.0
org.objenesis:objenesis:2.6
org.opentest4j:opentest4j:1.2.0
@@ -61,12 +61,12 @@ org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:2.10.0
org.hamcrest:hamcrest-core:1.3
org.json:json:20160212
org.junit.jupiter:junit-jupiter-api:5.6.0
org.junit.jupiter:junit-jupiter-engine:5.6.0
org.junit.platform:junit-platform-commons:1.6.0
org.junit.platform:junit-platform-engine:1.6.0
org.junit.vintage:junit-vintage-engine:5.6.0
org.junit:junit-bom:5.6.0
org.junit.jupiter:junit-jupiter-api:5.6.1
org.junit.jupiter:junit-jupiter-engine:5.6.1
org.junit.platform:junit-platform-commons:1.6.1
org.junit.platform:junit-platform-engine:1.6.1
org.junit.vintage:junit-vintage-engine:5.6.1
org.junit:junit-bom:5.6.1
org.mockito:mockito-core:2.25.0
org.objenesis:objenesis:2.6
org.opentest4j:opentest4j:1.2.0
@@ -20,10 +20,10 @@ org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:2.10.0
org.eclipse.jgit:org.eclipse.jgit:4.4.1.201607150455-r
org.hamcrest:hamcrest-core:1.3
org.junit.jupiter:junit-jupiter-api:5.6.0
org.junit.jupiter:junit-jupiter-engine:5.6.0
org.junit.platform:junit-platform-commons:1.6.0
org.junit.platform:junit-platform-engine:1.6.0
org.junit.vintage:junit-vintage-engine:5.6.0
org.junit:junit-bom:5.6.0
org.junit.jupiter:junit-jupiter-api:5.6.1
org.junit.jupiter:junit-jupiter-engine:5.6.1
org.junit.platform:junit-platform-commons:1.6.1
org.junit.platform:junit-platform-engine:1.6.1
org.junit.vintage:junit-vintage-engine:5.6.1
org.junit:junit-bom:5.6.1
org.opentest4j:opentest4j:1.2.0
@@ -20,10 +20,10 @@ org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:2.10.0
org.eclipse.jgit:org.eclipse.jgit:4.4.1.201607150455-r
org.hamcrest:hamcrest-core:1.3
org.junit.jupiter:junit-jupiter-api:5.6.0
org.junit.jupiter:junit-jupiter-engine:5.6.0
org.junit.platform:junit-platform-commons:1.6.0
org.junit.platform:junit-platform-engine:1.6.0
org.junit.vintage:junit-vintage-engine:5.6.0
org.junit:junit-bom:5.6.0
org.junit.jupiter:junit-jupiter-api:5.6.1
org.junit.jupiter:junit-jupiter-engine:5.6.1
org.junit.platform:junit-platform-commons:1.6.1
org.junit.platform:junit-platform-engine:1.6.1
org.junit.vintage:junit-vintage-engine:5.6.1
org.junit:junit-bom:5.6.1
org.opentest4j:opentest4j:1.2.0
@@ -21,10 +21,10 @@ org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:2.10.0
org.eclipse.jgit:org.eclipse.jgit:4.4.1.201607150455-r
org.hamcrest:hamcrest-core:1.3
org.junit.jupiter:junit-jupiter-api:5.6.0
org.junit.jupiter:junit-jupiter-engine:5.6.0
org.junit.platform:junit-platform-commons:1.6.0
org.junit.platform:junit-platform-engine:1.6.0
org.junit.vintage:junit-vintage-engine:5.6.0
org.junit:junit-bom:5.6.0
org.junit.jupiter:junit-jupiter-api:5.6.1
org.junit.jupiter:junit-jupiter-engine:5.6.1
org.junit.platform:junit-platform-commons:1.6.1
org.junit.platform:junit-platform-engine:1.6.1
org.junit.vintage:junit-vintage-engine:5.6.1
org.junit:junit-bom:5.6.1
org.opentest4j:opentest4j:1.2.0
@@ -21,10 +21,10 @@ org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:2.10.0
org.eclipse.jgit:org.eclipse.jgit:4.4.1.201607150455-r
org.hamcrest:hamcrest-core:1.3
org.junit.jupiter:junit-jupiter-api:5.6.0
org.junit.jupiter:junit-jupiter-engine:5.6.0
org.junit.platform:junit-platform-commons:1.6.0
org.junit.platform:junit-platform-engine:1.6.0
org.junit.vintage:junit-vintage-engine:5.6.0
org.junit:junit-bom:5.6.0
org.junit.jupiter:junit-jupiter-api:5.6.1
org.junit.jupiter:junit-jupiter-engine:5.6.1
org.junit.platform:junit-platform-commons:1.6.1
org.junit.platform:junit-platform-engine:1.6.1
org.junit.vintage:junit-vintage-engine:5.6.1
org.junit:junit-bom:5.6.1
org.opentest4j:opentest4j:1.2.0
+18
View File
@@ -177,6 +177,8 @@ dependencies {
compile deps['com.beust:jcommander']
compile deps['com.google.api-client:google-api-client']
compile deps['com.google.api-client:google-api-client-appengine']
compile deps['com.google.api-client:google-api-client-servlet']
compile deps['com.google.monitoring-client:metrics']
compile deps['com.google.monitoring-client:stackdriver']
compile deps['com.google.api-client:google-api-client-java6']
@@ -216,6 +218,8 @@ dependencies {
compile deps['com.google.oauth-client:google-oauth-client']
compile deps['com.google.oauth-client:google-oauth-client-java6']
compile deps['com.google.oauth-client:google-oauth-client-jetty']
compile deps['com.google.oauth-client:google-oauth-client-appengine']
compile deps['com.google.oauth-client:google-oauth-client-servlet']
compile deps['com.google.re2j:re2j']
compile deps['com.google.template:soy']
compile deps['com.googlecode.json-simple:json-simple']
@@ -262,6 +266,7 @@ dependencies {
testCompile deps['org.seleniumhq.selenium:selenium-chrome-driver']
testCompile deps['org.seleniumhq.selenium:selenium-java']
testCompile deps['org.seleniumhq.selenium:selenium-remote-driver']
runtimeOnly deps['org.slf4j:slf4j-jdk14']
testCompile deps['org.testcontainers:jdbc']
compile deps['org.testcontainers:postgresql']
testCompile deps['org.testcontainers:selenium']
@@ -304,6 +309,8 @@ dependencies {
testCompile deps['org.junit.jupiter:junit-jupiter-api']
testCompile deps['org.junit.jupiter:junit-jupiter-engine']
testCompile deps['org.junit.jupiter:junit-jupiter-migrationsupport']
testCompile deps['org.junit.platform:junit-platform-runner']
testCompile deps['org.junit.platform:junit-platform-suite-api']
testCompile deps['org.junit.vintage:junit-vintage-engine']
testCompile deps['org.mockito:mockito-core']
runtime deps['org.postgresql:postgresql']
@@ -641,6 +648,10 @@ artifacts {
*/
class FilteringTest extends Test {
FilteringTest() {
useJUnitPlatform();
}
private void applyTestFilter() {
if (project.testFilter) {
testNameIncludePatterns = project.testFilter.split(',')
@@ -728,6 +739,10 @@ task registryToolIntegrationTest {
// Dedicated test suite for schema-dependent tests.
task sqlIntegrationTest(type: FilteringTest) {
// TestSuite still requires a JUnit 4 runner, which knows how to handle JUnit 5 tests.
// Here we need to override parent's choice of JUnit 5. If changing this, remember to
// change :integration:sqlIntegrationTest too.
useJUnit()
excludeTestCases = false
tests = ['google/registry/schema/integration/SqlIntegrationTestSuite.*']
}
@@ -879,11 +894,14 @@ createUberJar('nomulus', 'nomulus', 'google.registry.tools.RegistryTool')
// A jar with classes and resources from main sourceSet, excluding internal
// data. See comments on configurations.nomulus_test above for details.
// TODO(weiminyu): release process should build this using the public repo to eliminate the need
// for excludes.
task nomulusFossJar (type: Jar) {
archiveBaseName = 'nomulus'
archiveClassifier = 'public'
from (project.sourceSets.main.output) {
exclude 'google/registry/config/files/**'
exclude 'google/registry/proxy/config/**'
}
from (project.sourceSets.main.output) {
include 'google/registry/config/files/default-config.yaml'
@@ -235,6 +235,7 @@ org.rnorth.visible-assertions:visible-assertions:2.1.2
org.rnorth:tcp-unix-socket-proxy:1.0.2
org.scijava:native-lib-loader:2.0.2
org.slf4j:slf4j-api:1.7.28
org.slf4j:slf4j-jdk14:1.7.28
org.testcontainers:database-commons:1.12.1
org.testcontainers:jdbc:1.12.1
org.testcontainers:postgresql:1.12.1
@@ -232,6 +232,7 @@ org.rnorth.visible-assertions:visible-assertions:2.1.2
org.rnorth:tcp-unix-socket-proxy:1.0.2
org.scijava:native-lib-loader:2.0.2
org.slf4j:slf4j-api:1.7.28
org.slf4j:slf4j-jdk14:1.7.28
org.testcontainers:database-commons:1.12.1
org.testcontainers:jdbc:1.12.1
org.testcontainers:postgresql:1.12.1
@@ -232,6 +232,7 @@ org.rnorth.visible-assertions:visible-assertions:2.1.2
org.rnorth:tcp-unix-socket-proxy:1.0.2
org.scijava:native-lib-loader:2.0.2
org.slf4j:slf4j-api:1.7.28
org.slf4j:slf4j-jdk14:1.7.28
org.testcontainers:database-commons:1.12.1
org.testcontainers:jdbc:1.12.1
org.testcontainers:postgresql:1.12.1
@@ -243,13 +243,16 @@ org.jboss:jandex:2.0.5.Final
org.jetbrains:annotations:17.0.0
org.joda:joda-money:1.0.1
org.json:json:20160810
org.junit.jupiter:junit-jupiter-api:5.6.0
org.junit.jupiter:junit-jupiter-engine:5.6.0
org.junit.jupiter:junit-jupiter-migrationsupport:5.6.0
org.junit.platform:junit-platform-commons:1.6.0
org.junit.platform:junit-platform-engine:1.6.0
org.junit.vintage:junit-vintage-engine:5.6.0
org.junit:junit-bom:5.6.0
org.junit.jupiter:junit-jupiter-api:5.6.1
org.junit.jupiter:junit-jupiter-engine:5.6.1
org.junit.jupiter:junit-jupiter-migrationsupport:5.6.1
org.junit.platform:junit-platform-commons:1.6.1
org.junit.platform:junit-platform-engine:1.6.1
org.junit.platform:junit-platform-launcher:1.6.1
org.junit.platform:junit-platform-runner:1.6.1
org.junit.platform:junit-platform-suite-api:1.6.1
org.junit.vintage:junit-vintage-engine:5.6.1
org.junit:junit-bom:5.6.1
org.jvnet.staxex:stax-ex:1.8
org.mockito:mockito-core:2.25.0
org.mortbay.jetty:jetty-util:6.1.26
@@ -241,13 +241,16 @@ org.jboss:jandex:2.0.5.Final
org.jetbrains:annotations:17.0.0
org.joda:joda-money:1.0.1
org.json:json:20160810
org.junit.jupiter:junit-jupiter-api:5.6.0
org.junit.jupiter:junit-jupiter-engine:5.6.0
org.junit.jupiter:junit-jupiter-migrationsupport:5.6.0
org.junit.platform:junit-platform-commons:1.6.0
org.junit.platform:junit-platform-engine:1.6.0
org.junit.vintage:junit-vintage-engine:5.6.0
org.junit:junit-bom:5.6.0
org.junit.jupiter:junit-jupiter-api:5.6.1
org.junit.jupiter:junit-jupiter-engine:5.6.1
org.junit.jupiter:junit-jupiter-migrationsupport:5.6.1
org.junit.platform:junit-platform-commons:1.6.1
org.junit.platform:junit-platform-engine:1.6.1
org.junit.platform:junit-platform-launcher:1.6.1
org.junit.platform:junit-platform-runner:1.6.1
org.junit.platform:junit-platform-suite-api:1.6.1
org.junit.vintage:junit-vintage-engine:5.6.1
org.junit:junit-bom:5.6.1
org.jvnet.staxex:stax-ex:1.8
org.mockito:mockito-core:2.25.0
org.mortbay.jetty:jetty-util:6.1.26
@@ -246,13 +246,16 @@ org.jboss:jandex:2.0.5.Final
org.jetbrains:annotations:17.0.0
org.joda:joda-money:1.0.1
org.json:json:20160810
org.junit.jupiter:junit-jupiter-api:5.6.0
org.junit.jupiter:junit-jupiter-engine:5.6.0
org.junit.jupiter:junit-jupiter-migrationsupport:5.6.0
org.junit.platform:junit-platform-commons:1.6.0
org.junit.platform:junit-platform-engine:1.6.0
org.junit.vintage:junit-vintage-engine:5.6.0
org.junit:junit-bom:5.6.0
org.junit.jupiter:junit-jupiter-api:5.6.1
org.junit.jupiter:junit-jupiter-engine:5.6.1
org.junit.jupiter:junit-jupiter-migrationsupport:5.6.1
org.junit.platform:junit-platform-commons:1.6.1
org.junit.platform:junit-platform-engine:1.6.1
org.junit.platform:junit-platform-launcher:1.6.1
org.junit.platform:junit-platform-runner:1.6.1
org.junit.platform:junit-platform-suite-api:1.6.1
org.junit.vintage:junit-vintage-engine:5.6.1
org.junit:junit-bom:5.6.1
org.jvnet.staxex:stax-ex:1.8
org.mockito:mockito-core:2.25.0
org.mortbay.jetty:jetty-util:6.1.26
@@ -246,13 +246,16 @@ org.jboss:jandex:2.0.5.Final
org.jetbrains:annotations:17.0.0
org.joda:joda-money:1.0.1
org.json:json:20160810
org.junit.jupiter:junit-jupiter-api:5.6.0
org.junit.jupiter:junit-jupiter-engine:5.6.0
org.junit.jupiter:junit-jupiter-migrationsupport:5.6.0
org.junit.platform:junit-platform-commons:1.6.0
org.junit.platform:junit-platform-engine:1.6.0
org.junit.vintage:junit-vintage-engine:5.6.0
org.junit:junit-bom:5.6.0
org.junit.jupiter:junit-jupiter-api:5.6.1
org.junit.jupiter:junit-jupiter-engine:5.6.1
org.junit.jupiter:junit-jupiter-migrationsupport:5.6.1
org.junit.platform:junit-platform-commons:1.6.1
org.junit.platform:junit-platform-engine:1.6.1
org.junit.platform:junit-platform-launcher:1.6.1
org.junit.platform:junit-platform-runner:1.6.1
org.junit.platform:junit-platform-suite-api:1.6.1
org.junit.vintage:junit-vintage-engine:5.6.1
org.junit:junit-bom:5.6.1
org.jvnet.staxex:stax-ex:1.8
org.mockito:mockito-core:2.25.0
org.mortbay.jetty:jetty-util:6.1.26
@@ -280,6 +283,7 @@ org.seleniumhq.selenium:selenium-remote-driver:3.141.59
org.seleniumhq.selenium:selenium-safari-driver:3.141.59
org.seleniumhq.selenium:selenium-support:3.141.59
org.slf4j:slf4j-api:1.7.28
org.slf4j:slf4j-jdk14:1.7.28
org.testcontainers:database-commons:1.12.1
org.testcontainers:jdbc:1.12.1
org.testcontainers:postgresql:1.12.1
@@ -31,6 +31,7 @@ import google.registry.model.ImmutableObject;
import google.registry.model.eppcommon.Trid;
import google.registry.model.host.HostResource;
import google.registry.persistence.VKey;
import google.registry.schema.domain.RegistryLock;
import google.registry.util.AppEngineServiceUtils;
import google.registry.util.Retrier;
import javax.inject.Inject;
@@ -158,6 +159,26 @@ public final class AsyncTaskEnqueuer {
.param(PARAM_REQUESTED_TIME, now.toString()));
}
/**
* Enqueues a task to asynchronously re-lock a registry-locked domain after it was unlocked.
*
* <p>Note: the relockDuration must be present on the lock object.
*/
public void enqueueDomainRelock(RegistryLock lock) {
checkArgument(
lock.getRelockDuration().isPresent(),
"Lock with ID %s not configured for relock",
lock.getRevisionId());
addTaskToQueueWithRetry(
asyncActionsPushQueue,
TaskOptions.Builder.withUrl(RelockDomainAction.PATH)
.method(Method.POST)
.param(
RelockDomainAction.OLD_UNLOCK_REVISION_ID_PARAM,
String.valueOf(lock.getRevisionId()))
.countdownMillis(lock.getRelockDuration().get().getMillis()));
}
/**
* Adds a task to a queue with retrying, to avoid aborting the entire flow over a transient issue
* enqueuing a task.
@@ -50,6 +50,7 @@ import javax.inject.Inject;
public class RelockDomainAction implements Runnable {
public static final String PATH = "/_dr/task/relockDomain";
public static final String OLD_UNLOCK_REVISION_ID_PARAM = "oldUnlockRevisionId";
private static final FluentLogger logger = FluentLogger.forEnclosingClass();
@@ -59,7 +60,7 @@ public class RelockDomainAction implements Runnable {
@Inject
public RelockDomainAction(
@Parameter("oldUnlockRevisionId") long oldUnlockRevisionId,
@Parameter(OLD_UNLOCK_REVISION_ID_PARAM) long oldUnlockRevisionId,
DomainLockUtils domainLockUtils,
Response response) {
this.oldUnlockRevisionId = oldUnlockRevisionId;
@@ -392,8 +392,6 @@ public class Registrar extends ImmutableObject implements Buildable, Jsonifiable
*/
@Nullable
@Mapify(CurrencyMapper.class)
@org.hibernate.annotations.Type(
type = "google.registry.persistence.converter.CurrencyToBillingMapUserType")
Map<CurrencyUnit, BillingAccountEntry> billingAccountMap;
/** A billing account entry for this registrar, consisting of a currency and an account Id. */
@@ -19,6 +19,7 @@ import static com.google.common.base.Strings.emptyToNull;
import static google.registry.util.DomainNameUtils.canonicalizeDomainName;
import static google.registry.util.PreconditionsUtils.checkArgumentNotNull;
import com.google.common.net.InternetDomainName;
import com.googlecode.objectify.annotation.Id;
import google.registry.model.Buildable.GenericBuilder;
import google.registry.model.ImmutableObject;
@@ -83,6 +84,13 @@ public abstract class DomainLabelEntry<T extends Comparable<?>, D extends Domain
"Label '%s' must be in puny-coded, lower-case form",
getInstance().label);
checkArgumentNotNull(getInstance().getValue(), "Value must be specified");
// Verify that the label creates a valid SLD if we add a TLD to the end of it.
// We require that the label is not already a full domain name including a dot.
// Domain name validation is tricky, so let InternetDomainName handle it for us.
checkArgument(
InternetDomainName.from(getInstance().label + ".tld").parts().size() == 2,
"Label %s must not be a multi-level domain name",
getInstance().label);
return super.build();
}
}
@@ -41,8 +41,8 @@ import org.joda.time.Duration;
/**
* A lock on some shared resource.
*
* <p>Locks are either specific to a tld or global to the entire system, in which case a tld of
* null is used.
* <p>Locks are either specific to a tld or global to the entire system, in which case a tld of null
* is used.
*
* <p>This is the "barebone" lock implementation, that requires manual locking and unlocking. For
* safe calls that automatically lock and unlock, see LockHandler.
@@ -201,8 +201,12 @@ public class Lock extends ImmutableObject implements Serializable {
jpaTm()
.transact(
() -> {
Optional<google.registry.schema.server.Lock> cloudSqlLockOptional =
LockDao.load(resourceName, tld);
Optional<google.registry.schema.server.Lock> cloudSqlLockOptional;
if (tld == null) {
cloudSqlLockOptional = LockDao.load(resourceName);
} else {
cloudSqlLockOptional = LockDao.load(resourceName, tld);
}
LockDao.compare(Optional.ofNullable(lock), cloudSqlLockOptional);
});
} catch (Exception e) {
@@ -238,13 +242,23 @@ public class Lock extends ImmutableObject implements Serializable {
jpaTm()
.transact(
() -> {
google.registry.schema.server.Lock cloudSqlLock =
google.registry.schema.server.Lock.create(
resourceName,
Optional.ofNullable(tld).orElse("GLOBAL"),
requestStatusChecker.getLogId(),
now,
leaseLength);
google.registry.schema.server.Lock cloudSqlLock;
if (tld == null) {
cloudSqlLock =
google.registry.schema.server.Lock.createGlobal(
resourceName,
requestStatusChecker.getLogId(),
now,
leaseLength);
} else {
cloudSqlLock =
google.registry.schema.server.Lock.create(
resourceName,
tld,
requestStatusChecker.getLogId(),
now,
leaseLength);
}
LockDao.save(cloudSqlLock);
});
} catch (Exception e) {
@@ -274,8 +288,12 @@ public class Lock extends ImmutableObject implements Serializable {
jpaTm()
.transact(
() -> {
Optional<google.registry.schema.server.Lock> cloudSqlLockOptional =
LockDao.load(resourceName, tld);
Optional<google.registry.schema.server.Lock> cloudSqlLockOptional;
if (tld == null) {
cloudSqlLockOptional = LockDao.load(resourceName);
} else {
cloudSqlLockOptional = LockDao.load(resourceName, tld);
}
LockDao.compare(Optional.ofNullable(loadedLock), cloudSqlLockOptional);
});
} catch (Exception e) {
@@ -292,9 +310,13 @@ public class Lock extends ImmutableObject implements Serializable {
try {
jpaTm()
.transact(
() ->
LockDao.delete(
resourceName, Optional.ofNullable(tld).orElse("GLOBAL")));
() -> {
if (tld == null) {
LockDao.delete(resourceName);
} else {
LockDao.delete(resourceName, tld);
}
});
} catch (Exception e) {
logger.atSevere().withCause(e).log(
"Error deleting lock from Cloud SQL: %s", loadedLock);
@@ -16,6 +16,7 @@ package google.registry.module.frontend;
import dagger.Module;
import dagger.Subcomponent;
import google.registry.batch.BatchModule;
import google.registry.dns.DnsModule;
import google.registry.flows.EppTlsAction;
import google.registry.flows.FlowComponent;
@@ -38,6 +39,7 @@ import google.registry.ui.server.registrar.RegistryLockVerifyAction;
@RequestScope
@Subcomponent(
modules = {
BatchModule.class,
DnsModule.class,
EppTlsModule.class,
RegistrarConsoleModule.class,
@@ -14,6 +14,7 @@
package google.registry.persistence;
import google.registry.persistence.converter.StringCollectionDescriptor;
import google.registry.persistence.converter.StringMapDescriptor;
import java.sql.Types;
import org.hibernate.boot.model.TypeContributions;
import org.hibernate.dialect.PostgreSQL95Dialect;
@@ -26,7 +27,7 @@ public class NomulusPostgreSQLDialect extends PostgreSQL95Dialect {
registerColumnType(Types.VARCHAR, "text");
registerColumnType(Types.TIMESTAMP_WITH_TIMEZONE, "timestamptz");
registerColumnType(Types.TIMESTAMP, "timestamptz");
registerColumnType(Types.OTHER, "hstore");
registerColumnType(StringMapDescriptor.COLUMN_TYPE, StringMapDescriptor.COLUMN_NAME);
registerColumnType(
StringCollectionDescriptor.COLUMN_TYPE, StringCollectionDescriptor.COLUMN_DDL_NAME);
}
@@ -37,5 +38,7 @@ public class NomulusPostgreSQLDialect extends PostgreSQL95Dialect {
super.contributeTypes(typeContributions, serviceRegistry);
typeContributions.contributeJavaTypeDescriptor(StringCollectionDescriptor.getInstance());
typeContributions.contributeSqlTypeDescriptor(StringCollectionDescriptor.getInstance());
typeContributions.contributeJavaTypeDescriptor(StringMapDescriptor.getInstance());
typeContributions.contributeSqlTypeDescriptor(StringMapDescriptor.getInstance());
}
}
@@ -41,11 +41,6 @@ public class VKey<T> extends ImmutableObject {
this.primaryKey = primaryKey;
}
public static <T> VKey<T> create(
Class<? extends T> kind, com.googlecode.objectify.Key<T> ofyKey, Object primaryKey) {
return new VKey(kind, ofyKey, primaryKey);
}
public static <T> VKey<T> createSql(Class<? extends T> kind, Object primaryKey) {
return new VKey(kind, null, primaryKey);
}
@@ -72,7 +67,7 @@ public class VKey<T> extends ImmutableObject {
/** Returns the SQL primary key if it exists. */
public Optional<Object> maybeGetSqlKey() {
return Optional.of(this.primaryKey);
return Optional.ofNullable(this.primaryKey);
}
/** Returns the objectify key. */
@@ -83,6 +78,6 @@ public class VKey<T> extends ImmutableObject {
/** Returns the objectify key if it exists. */
public Optional<com.googlecode.objectify.Key<T>> maybeGetOfyKey() {
return Optional.of(this.ofyKey);
return Optional.ofNullable(this.ofyKey);
}
}
@@ -0,0 +1,43 @@
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.persistence.converter;
import static google.registry.model.registrar.Registrar.BillingAccountEntry;
import com.google.common.collect.Maps;
import java.util.Map;
import javax.persistence.Converter;
import org.joda.money.CurrencyUnit;
/** JPA converter for storing/retrieving {@link Map <CurrencyUnit, BillingAccountEntry>} objects. */
@Converter(autoApply = true)
public class CurrencyToBillingConverter
extends StringMapConverterBase<CurrencyUnit, BillingAccountEntry> {
@Override
Map.Entry<String, String> convertToDatabaseMapEntry(
Map.Entry<CurrencyUnit, BillingAccountEntry> entry) {
return Maps.immutableEntry(entry.getKey().getCode(), entry.getValue().getAccountId());
}
@Override
Map.Entry<CurrencyUnit, BillingAccountEntry> convertToEntityMapEntry(
Map.Entry<String, String> entry) {
CurrencyUnit currencyUnit = CurrencyUnit.of(entry.getKey());
BillingAccountEntry billingAccountEntry =
new BillingAccountEntry(currencyUnit, entry.getValue());
return Maps.immutableEntry(currencyUnit, billingAccountEntry);
}
}
@@ -1,54 +0,0 @@
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.persistence.converter;
import static com.google.common.collect.ImmutableMap.toImmutableMap;
import google.registry.model.registrar.Registrar.BillingAccountEntry;
import java.util.Map;
import org.hibernate.usertype.UserType;
import org.joda.money.CurrencyUnit;
/**
* A custom {@link UserType} for storing/retrieving {@link Map<CurrencyUnit, BillingAccountEntry>}
* objects.
*/
public class CurrencyToBillingMapUserType extends MapUserType {
@Override
public Object toEntityTypeMap(Map<String, String> map) {
return map == null
? null
: map.entrySet().stream()
.collect(
toImmutableMap(
entry -> CurrencyUnit.of(entry.getKey()),
entry ->
new BillingAccountEntry(
CurrencyUnit.of(entry.getKey()), entry.getValue())));
}
@Override
public Map<String, String> toDbSupportedMap(Object map) {
return map == null
? null
: ((Map<CurrencyUnit, BillingAccountEntry>) map)
.entrySet().stream()
.collect(
toImmutableMap(
entry -> entry.getKey().getCode(),
entry -> entry.getValue().getAccountId()));
}
}
@@ -1,73 +0,0 @@
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.persistence.converter;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Map;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.usertype.UserType;
/**
* A custom {@link UserType} used to convert a Java {@link Map<String, String>} to/from PostgreSQL
* hstore type. Per this <a href="https://www.postgresql.org/docs/current/hstore.html">doc</a>, as
* hstore keys and values are simply text strings, the type of key and value in the Java map has to
* be {@link String} as well.
*/
public class MapUserType extends MutableUserType {
@Override
public int[] sqlTypes() {
return new int[] {Types.OTHER};
}
@Override
public Class returnedClass() {
return Map.class;
}
@Override
public Object nullSafeGet(
ResultSet rs, String[] names, SharedSessionContractImplementor session, Object owner)
throws HibernateException, SQLException {
return toEntityTypeMap((Map<String, String>) rs.getObject(names[0]));
}
@Override
public void nullSafeSet(
PreparedStatement st, Object value, int index, SharedSessionContractImplementor session)
throws HibernateException, SQLException {
st.setObject(index, toDbSupportedMap(value));
}
/**
* Subclass can override this method to convert the {@link Map<String, String>} to a {@link Map}
* of specific type defined in the entity class.
*/
public Object toEntityTypeMap(Map<String, String> map) {
return map;
}
/**
* Subclass can override this method to convert the {@link Map} of specific type to a {@link
* Map<String, String>} that can be stored in the hstore type column.
*/
public Map<String, String> toDbSupportedMap(Object map) {
return (Map<String, String>) map;
}
}
@@ -1,63 +0,0 @@
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.persistence.converter;
import java.io.Serializable;
import java.util.Objects;
import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;
/**
* An abstract class represents a mutable Hibernate user type which implements related methods
* defined in {@link UserType}.
*/
public abstract class MutableUserType implements UserType {
@Override
public boolean equals(Object x, Object y) throws HibernateException {
return Objects.equals(x, y);
}
@Override
public int hashCode(Object x) throws HibernateException {
return x == null ? 0 : x.hashCode();
}
// TODO(b/147489651): Investigate how to properly implement the below methods.
@Override
public Object deepCopy(Object value) throws HibernateException {
return value;
}
@Override
public boolean isMutable() {
return false;
}
@Override
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value;
}
@Override
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return cached;
}
@Override
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}
}
@@ -0,0 +1,52 @@
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.persistence.converter;
import static com.google.common.collect.ImmutableMap.toImmutableMap;
import google.registry.persistence.converter.StringMapDescriptor.StringMap;
import java.util.Map;
import javax.persistence.AttributeConverter;
/**
* Base JPA converter for {@link Map} objects that are stored in a column with data type of hstore
* in the database.
*/
public abstract class StringMapConverterBase<K, V>
implements AttributeConverter<Map<K, V>, StringMap> {
abstract Map.Entry<String, String> convertToDatabaseMapEntry(Map.Entry<K, V> entry);
abstract Map.Entry<K, V> convertToEntityMapEntry(Map.Entry<String, String> entry);
@Override
public StringMap convertToDatabaseColumn(Map<K, V> attribute) {
return attribute == null
? null
: StringMap.create(
attribute.entrySet().stream()
.map(this::convertToDatabaseMapEntry)
.collect(toImmutableMap(Map.Entry::getKey, Map.Entry::getValue)));
}
@Override
public Map<K, V> convertToEntityAttribute(StringMap dbData) {
return dbData == null
? null
: dbData.getMap().entrySet().stream()
.map(this::convertToEntityMapEntry)
.collect(toImmutableMap(Map.Entry::getKey, Map.Entry::getValue));
}
}
@@ -0,0 +1,177 @@
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.persistence.converter;
import static google.registry.persistence.converter.StringMapDescriptor.StringMap;
import com.google.common.collect.ImmutableMap;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Map;
import org.hibernate.type.descriptor.ValueBinder;
import org.hibernate.type.descriptor.ValueExtractor;
import org.hibernate.type.descriptor.WrapperOptions;
import org.hibernate.type.descriptor.java.AbstractTypeDescriptor;
import org.hibernate.type.descriptor.java.JavaTypeDescriptor;
import org.hibernate.type.descriptor.spi.JdbcRecommendedSqlTypeMappingContext;
import org.hibernate.type.descriptor.sql.BasicBinder;
import org.hibernate.type.descriptor.sql.BasicExtractor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
/**
* The {@link JavaTypeDescriptor} and {@link SqlTypeDescriptor} for {@link StringMap}.
*
* <p>A {@link StringMap} object is a simple wrapper for a {@link Map <String, String>} which can be
* stored in a column with data type of hstore in the database. The {@link JavaTypeDescriptor} and
* {@link SqlTypeDescriptor} is used by JPA/Hibernate to map between the map and hstore which is the
* actual type that JDBC uses to read from and write to the database.
*
* @see <a
* href="https://docs.jboss.org/hibernate/orm/current/userguide/html_single/Hibernate_User_Guide.html#basic-jpa-convert">JPA
* 2.1 AttributeConverters</a>
* @see <a href="https://www.postgresql.org/docs/current/hstore.html">hstore</a>
*/
public class StringMapDescriptor extends AbstractTypeDescriptor<StringMap>
implements SqlTypeDescriptor {
public static final int COLUMN_TYPE = Types.OTHER;
public static final String COLUMN_NAME = "hstore";
private static final StringMapDescriptor INSTANCE = new StringMapDescriptor();
protected StringMapDescriptor() {
super(StringMap.class);
}
public static StringMapDescriptor getInstance() {
return INSTANCE;
}
@Override
public StringMap fromString(String string) {
throw new UnsupportedOperationException(
"Constructing StringMapDescriptor from string is not allowed");
}
@Override
public <X> X unwrap(StringMap value, Class<X> type, WrapperOptions options) {
if (value == null) {
return null;
}
if (Map.class.isAssignableFrom(type)) {
return (X) value.getMap();
}
throw unknownUnwrap(type);
}
@Override
public <X> StringMap wrap(X value, WrapperOptions options) {
if (value == null) {
return null;
}
if (value instanceof Map) {
return StringMap.create((Map<String, String>) value);
}
throw unknownWrap(value.getClass());
}
@Override
public SqlTypeDescriptor getJdbcRecommendedSqlType(JdbcRecommendedSqlTypeMappingContext context) {
return this;
}
@Override
public int getSqlType() {
return COLUMN_TYPE;
}
@Override
public boolean canBeRemapped() {
return false;
}
@Override
public <X> ValueBinder<X> getBinder(JavaTypeDescriptor<X> javaTypeDescriptor) {
return new BasicBinder<X>(javaTypeDescriptor, this) {
@Override
protected void doBind(PreparedStatement st, X value, int index, WrapperOptions options)
throws SQLException {
st.setObject(index, getStringMap(value));
}
@Override
protected void doBind(CallableStatement st, X value, String name, WrapperOptions options)
throws SQLException {
st.setObject(name, getStringMap(value));
}
private Map<String, String> getStringMap(X value) {
if (value == null) {
return null;
}
if (value instanceof StringMap) {
return ((StringMap) value).getMap();
} else {
throw new UnsupportedOperationException(
String.format(
"Binding type %s is not supported by StringMapDescriptor",
value.getClass().getName()));
}
}
};
}
@Override
public <X> ValueExtractor<X> getExtractor(JavaTypeDescriptor<X> javaTypeDescriptor) {
return new BasicExtractor<X>(javaTypeDescriptor, this) {
@Override
protected X doExtract(ResultSet rs, String name, WrapperOptions options) throws SQLException {
return javaTypeDescriptor.wrap(rs.getObject(name), options);
}
@Override
protected X doExtract(CallableStatement statement, int index, WrapperOptions options)
throws SQLException {
return javaTypeDescriptor.wrap(statement.getObject(index), options);
}
@Override
protected X doExtract(CallableStatement statement, String name, WrapperOptions options)
throws SQLException {
return javaTypeDescriptor.wrap(statement.getObject(name), options);
}
};
}
/** A simple wrapper class for {@link Map<String, String>}. */
public static class StringMap {
private Map<String, String> map;
private StringMap(Map<String, String> map) {
this.map = map;
}
/** Constructs an instance of {@link StringMap} from the given map. */
public static StringMap create(Map<String, String> map) {
return new StringMap(ImmutableMap.copyOf(map));
}
/** Returns the underlying {@link Map<String, String>} object. */
public Map<String, String> getMap() {
return map;
}
}
}
@@ -14,6 +14,7 @@
package google.registry.schema.tld;
import google.registry.model.ImmutableObject;
import java.io.Serializable;
import java.math.BigDecimal;
import javax.persistence.Column;
@@ -26,7 +27,7 @@ import javax.persistence.Id;
* <p>These are not persisted directly, but rather, using {@link PremiumList#getLabelsToPrices()}.
*/
@Entity
public class PremiumEntry implements Serializable {
public class PremiumEntry extends ImmutableObject implements Serializable {
@Id
@Column(nullable = false)
@@ -14,6 +14,8 @@
package google.registry.tools;
import static com.google.common.base.Strings.isNullOrEmpty;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import com.google.common.collect.Multimap;
@@ -39,6 +41,11 @@ final class CheckDomainCommand extends NonMutatingEppToolCommand {
required = true)
private List<String> mainParameters;
@Parameter(
names = {"-t", "--token"},
description = "Allocation token to use in the command, if desired")
private String allocationToken;
@Inject
@Config("registryAdminClientId")
String registryAdminClientId;
@@ -53,7 +60,11 @@ final class CheckDomainCommand extends NonMutatingEppToolCommand {
Multimap<String, String> domainNameMap = validateAndGroupDomainNamesByTld(mainParameters);
for (Collection<String> values : domainNameMap.asMap().values()) {
setSoyTemplate(DomainCheckSoyInfo.getInstance(), DomainCheckSoyInfo.DOMAINCHECK);
addSoyRecord(clientId, new SoyMapData("domainNames", values));
SoyMapData soyMapData = new SoyMapData("domainNames", values);
if (!isNullOrEmpty(allocationToken)) {
soyMapData.put("allocationToken", allocationToken);
}
addSoyRecord(clientId, soyMapData);
}
}
}
@@ -18,9 +18,20 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.common.collect.Sets.SetView;
import java.io.File;
import java.util.function.Predicate;
/** Compare two database backups. */
/**
* Compares two Datastore backups in V3 format on local file system. This is for use in tests and
* experiments with small data sizes.
*
* <p>This utility only supports the current Datastore backup format (version 3). A backup is a
* two-level directory hierarchy with data files in level-db format (output-*) and Datastore
* metadata files (*.export_metadata).
*/
class CompareDbBackups {
private static final String DS_V3_BACKUP_FILE_PREFIX = "output-";
private static final Predicate<File> DATA_FILE_MATCHER =
file -> file.isFile() && file.getName().startsWith(DS_V3_BACKUP_FILE_PREFIX);
public static void main(String[] args) {
if (args.length != 2) {
@@ -29,9 +40,13 @@ class CompareDbBackups {
}
ImmutableSet<ComparableEntity> entities1 =
new RecordAccumulator().readDirectory(new File(args[0])).getComparableEntitySet();
new RecordAccumulator()
.readDirectory(new File(args[0]), DATA_FILE_MATCHER)
.getComparableEntitySet();
ImmutableSet<ComparableEntity> entities2 =
new RecordAccumulator().readDirectory(new File(args[1])).getComparableEntitySet();
new RecordAccumulator()
.readDirectory(new File(args[1]), DATA_FILE_MATCHER)
.getComparableEntitySet();
// Calculate the entities added and removed.
SetView<ComparableEntity> added = Sets.difference(entities2, entities1);
@@ -54,6 +69,10 @@ class CompareDbBackups {
System.out.println(entity);
}
}
if (added.isEmpty() && removed.isEmpty()) {
System.out.printf("\nBoth sets have the same %d entities.\n", entities1.size());
}
}
/** Print out multi-line text in a pretty ASCII header frame. */
@@ -24,6 +24,7 @@ import static google.registry.tools.LockOrUnlockDomainCommand.REGISTRY_LOCK_STAT
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.googlecode.objectify.Key;
import google.registry.batch.AsyncTaskEnqueuer;
import google.registry.model.billing.BillingEvent;
import google.registry.model.billing.BillingEvent.Reason;
import google.registry.model.domain.DomainBase;
@@ -51,10 +52,14 @@ public final class DomainLockUtils {
private static final int VERIFICATION_CODE_LENGTH = 32;
private final StringGenerator stringGenerator;
private final AsyncTaskEnqueuer asyncTaskEnqueuer;
@Inject
public DomainLockUtils(@Named("base58StringGenerator") StringGenerator stringGenerator) {
public DomainLockUtils(
@Named("base58StringGenerator") StringGenerator stringGenerator,
AsyncTaskEnqueuer asyncTaskEnqueuer) {
this.stringGenerator = stringGenerator;
this.asyncTaskEnqueuer = asyncTaskEnqueuer;
}
/**
@@ -115,35 +120,41 @@ public final class DomainLockUtils {
/** Verifies and applies the unlock request previously requested by a user. */
public RegistryLock verifyAndApplyUnlock(String verificationCode, boolean isAdmin) {
return jpaTm()
.transact(
() -> {
DateTime now = jpaTm().getTransactionTime();
RegistryLock lock = getByVerificationCode(verificationCode);
checkArgument(
!lock.getUnlockCompletionTimestamp().isPresent(),
"Domain %s is already unlocked",
lock.getDomainName());
RegistryLock lock =
jpaTm()
.transact(
() -> {
DateTime now = jpaTm().getTransactionTime();
RegistryLock previousLock = getByVerificationCode(verificationCode);
checkArgument(
!previousLock.getUnlockCompletionTimestamp().isPresent(),
"Domain %s is already unlocked",
previousLock.getDomainName());
checkArgument(
!lock.isUnlockRequestExpired(now),
"The pending unlock has expired; please try again");
checkArgument(
!previousLock.isUnlockRequestExpired(now),
"The pending unlock has expired; please try again");
checkArgument(
isAdmin || !lock.isSuperuser(), "Non-admin user cannot complete admin unlock");
checkArgument(
isAdmin || !previousLock.isSuperuser(),
"Non-admin user cannot complete admin unlock");
RegistryLock newLock =
RegistryLockDao.save(lock.asBuilder().setUnlockCompletionTimestamp(now).build());
tm().transact(() -> removeLockStatuses(newLock, isAdmin, now));
return newLock;
});
RegistryLock newLock =
RegistryLockDao.save(
previousLock.asBuilder().setUnlockCompletionTimestamp(now).build());
tm().transact(() -> removeLockStatuses(newLock, isAdmin, now));
return newLock;
});
// Submit relock outside of the transaction to make sure that it fully succeeded
submitRelockIfNecessary(lock);
return lock;
}
/**
* Creates and applies a lock in one step -- this should only be used for admin actions, e.g.
* Nomulus tool commands or relocks.
* Creates and applies a lock in one step.
*
* <p>Note: in the case of relocks, isAdmin is determined by the previous lock.
* <p>This should only be used for admin actions, e.g. Nomulus tool commands or relocks.
* Note: in the case of relocks, isAdmin is determined by the previous lock.
*/
public RegistryLock administrativelyApplyLock(
String domainName, String registrarId, @Nullable String registrarPocId, boolean isAdmin) {
@@ -163,23 +174,34 @@ public final class DomainLockUtils {
}
/**
* Creates and applies an unlock in one step -- this should only be used for admin actions, e.g.
* Nomulus tool commands.
* Creates and applies an unlock in one step.
*
* <p>This should only be used for admin actions, e.g. Nomulus tool commands.
*/
public RegistryLock administrativelyApplyUnlock(
String domainName, String registrarId, boolean isAdmin, Optional<Duration> relockDuration) {
return jpaTm()
.transact(
() -> {
DateTime now = jpaTm().getTransactionTime();
RegistryLock result =
RegistryLockDao.save(
createUnlockBuilder(domainName, registrarId, isAdmin, relockDuration)
.setUnlockCompletionTimestamp(now)
.build());
tm().transact(() -> removeLockStatuses(result, isAdmin, now));
return result;
});
RegistryLock lock =
jpaTm()
.transact(
() -> {
DateTime now = jpaTm().getTransactionTime();
RegistryLock result =
RegistryLockDao.save(
createUnlockBuilder(domainName, registrarId, isAdmin, relockDuration)
.setUnlockCompletionTimestamp(now)
.build());
tm().transact(() -> removeLockStatuses(result, isAdmin, now));
return result;
});
// Submit relock outside of the transaction to make sure that it fully succeeded
submitRelockIfNecessary(lock);
return lock;
}
private void submitRelockIfNecessary(RegistryLock lock) {
if (lock.getRelockDuration().isPresent()) {
asyncTaskEnqueuer.enqueueDomainRelock(lock);
}
}
private void setAsRelock(RegistryLock newLock) {
@@ -20,17 +20,18 @@ import com.google.storage.onestore.v3.OnestoreEntity.EntityProto;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.function.Predicate;
/** Utility class that accumulates Entity records from level db files. */
/** Accumulates Entity records from level db files under a directory hierarchy. */
class RecordAccumulator {
private final LevelDbLogReader reader = new LevelDbLogReader();
/** Recursively reads all records in the directory. */
public final RecordAccumulator readDirectory(File dir) {
public final RecordAccumulator readDirectory(File dir, Predicate<File> fileMatcher) {
for (File child : dir.listFiles()) {
if (child.isDirectory()) {
readDirectory(child);
} else if (child.isFile()) {
readDirectory(child, fileMatcher);
} else if (fileMatcher.test(child)) {
try {
reader.readFrom(new FileInputStream(child));
} catch (IOException e) {
@@ -16,6 +16,7 @@ package google.registry.tools;
import dagger.BindsInstance;
import dagger.Component;
import google.registry.batch.BatchModule;
import google.registry.bigquery.BigqueryModule;
import google.registry.config.CredentialModule.LocalCredentialJson;
import google.registry.config.RegistryConfig.ConfigModule;
@@ -54,6 +55,7 @@ import javax.inject.Singleton;
modules = {
AppEngineAdminApiModule.class,
AuthModule.class,
BatchModule.class,
BigqueryModule.class,
ConfigModule.class,
CloudDnsWriterModule.class,
@@ -2,4 +2,6 @@ handlers = java.util.logging.ConsoleHandler
.level = INFO
com.google.wrappers.base.GoogleInit.level = WARNING
com.google.monitoring.metrics.MetricRegistryImpl.level = WARNING
com.google.cloud.sql.level = WARNING
com.zaxxer.hikari.level = WARNING
org.hibernate.level = WARNING
@@ -167,6 +167,7 @@ registry.registrar.RegistryLock.prototype.lockOrUnlockDomain_ = function(isLock,
var domain = goog.dom.getRequiredElement('domain-lock-input-value').value;
var passwordElem = goog.dom.getElement('domain-lock-password');
var password = passwordElem == null ? null : passwordElem.value;
var relockDuration = this.getRelockDurationFromModal_()
goog.net.XhrIo.send('/registry-lock-post',
e => this.fillLocksPage_(e),
'POST',
@@ -174,13 +175,30 @@ registry.registrar.RegistryLock.prototype.lockOrUnlockDomain_ = function(isLock,
'clientId': this.clientId,
'fullyQualifiedDomainName': domain,
'isLock': isLock,
'password': password
'password': password,
'relockDurationMillis': relockDuration
}), {
'X-CSRF-Token': this.xsrfToken,
'Content-Type': 'application/json; charset=UTF-8'
});
}
/**
* Returns the duration after which we will re-lock a locked domain. Will return null if we
* are locking a domain, or if the user selects the "Never" option
* @private
*/
registry.registrar.RegistryLock.prototype.getRelockDurationFromModal_ = function() {
var inputElements = goog.dom.getElementsByTagNameAndClass("input", "relock-duration-input");
for (var i = 0; i < inputElements.length; i++) {
var elem = inputElements[i];
if (elem.checked && elem.value !== "0") {
return elem.value;
}
}
return null;
}
/**
* Click handler for unlocking domains (button click).
* @private
+1 -6
View File
@@ -4,15 +4,10 @@
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm
http://xmlns.jcp.org/xml/ns/persistence/orm_2_2.xsd"
version="2.2">
<embeddable class="org.joda.money.Money" access="FIELD">
<attributes>
<embedded name="money" access="FIELD"/>
</attributes>
</embeddable>
<embeddable class="org.joda.money.Money" access="FIELD" />
<embeddable class="org.joda.money.BigMoney" access="FIELD">
<attributes>
<basic name="amount" access="FIELD"/>
<basic name="currency" access="FIELD"/>
</attributes>
</embeddable>
</entity-mappings>
@@ -36,6 +36,7 @@
<class>google.registry.persistence.converter.BloomFilterConverter</class>
<class>google.registry.persistence.converter.CidrAddressBlockListConverter</class>
<class>google.registry.persistence.converter.CreateAutoTimestampConverter</class>
<class>google.registry.persistence.converter.CurrencyToBillingConverter</class>
<class>google.registry.persistence.converter.CurrencyUnitConverter</class>
<class>google.registry.persistence.converter.DateTimeConverter</class>
<class>google.registry.persistence.converter.DurationConverter</class>
@@ -19,6 +19,7 @@
*/
{template .domaincheck stricthtml="false"}
{@param domainNames: list<string>}
{@param? allocationToken: string|null}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
@@ -39,6 +40,12 @@
</fee:domain>
{/for}
</fee:check>
{if isNonnull($allocationToken)}
<allocationToken:allocationToken
xmlns:allocationToken="urn:ietf:params:xml:ns:allocationToken-1.0">
{$allocationToken}
</allocationToken:allocationToken>
{/if}
</extension>
<clTRID>RegistryTool</clTRID>
</command>
@@ -132,6 +132,24 @@
<input type="password" id="domain-lock-password">
<br>
{/if}
{if not $isLock}
<div>
<br>
<p>Automatically re-lock the domain after:</p>
<input type="radio" name="relock-duration" id="one-hour-duration" value="3600000"
class="relock-duration-input">
<label for="one-hour-duration">1 hour</label><br>
<input type="radio" name="relock-duration" id="six-hour-duration" value="21600000"
class="relock-duration-input" checked>
<label for="six-hour-duration">6 hours</label><br>
<input type="radio" name="relock-duration" id="twenty-four-hour-duration" value="86400000"
class="relock-duration-input">
<label for="twenty-four-hour-duration">24 hours</label><br>
<input type="radio" name="relock-duration" id="never-relock-duration" value="0"
class="relock-duration-input">
<label for="never-relock-duration">Never</label><br>
</div>
{/if}
<div id="modal-error-message" hidden class="{css('kd-errormessage')}"></div>
<div class="{css('buttons-div')}">
<button id="domain-lock-cancel" class="{css('kd-button')}">Cancel</button>
@@ -36,6 +36,9 @@ public class DumpGoldenSchemaCommand extends PostgresqlCommand {
// The mount point in the container.
private static final String CONTAINER_MOUNT_POINT = "/tmp/pg_dump.out";
// Temporary workaround to fix permission issues on certain Linux distro (e. g. Arch Linux).
private static final String CONTAINER_MOUNT_POINT_TMP = "/tmp/pg_dump.tmp";
@Parameter(
names = {"--output", "-o"},
description = "Output file",
@@ -61,6 +64,11 @@ public class DumpGoldenSchemaCommand extends PostgresqlCommand {
if (result.getExitCode() != 0) {
throw new RuntimeException(result.toString());
}
result = postgresContainer.execInContainer(
"cp", CONTAINER_MOUNT_POINT_TMP, CONTAINER_MOUNT_POINT);
if (result.getExitCode() != 0) {
throw new RuntimeException(result.toString());
}
}
@Override
@@ -79,7 +87,7 @@ public class DumpGoldenSchemaCommand extends PostgresqlCommand {
"-U",
username,
"-f",
CONTAINER_MOUNT_POINT,
CONTAINER_MOUNT_POINT_TMP,
"--schema-only",
"--no-owner",
"--no-privileges",
@@ -15,6 +15,7 @@
package google.registry.batch;
import static com.google.appengine.api.taskqueue.QueueFactory.getQueue;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.batch.AsyncTaskEnqueuer.PARAM_REQUESTED_TIME;
import static google.registry.batch.AsyncTaskEnqueuer.PARAM_RESAVE_TIMES;
import static google.registry.batch.AsyncTaskEnqueuer.PARAM_RESOURCE_KEY;
@@ -23,18 +24,21 @@ import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_ACTIONS;
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_DELETE;
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_HOST_RENAME;
import static google.registry.testing.DatastoreHelper.persistActiveContact;
import static google.registry.testing.SqlHelper.saveRegistryLock;
import static google.registry.testing.TaskQueueHelper.assertNoTasksEnqueued;
import static google.registry.testing.TaskQueueHelper.assertTasksEnqueued;
import static google.registry.testing.TestLogHandlerUtils.assertLogMessage;
import static org.joda.time.Duration.standardDays;
import static org.joda.time.Duration.standardHours;
import static org.joda.time.Duration.standardSeconds;
import static org.junit.Assert.assertThrows;
import static org.mockito.Mockito.when;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.flogger.LoggerConfig;
import com.googlecode.objectify.Key;
import google.registry.model.contact.ContactResource;
import google.registry.schema.domain.RegistryLock;
import google.registry.testing.AppEngineRule;
import google.registry.testing.FakeClock;
import google.registry.testing.FakeSleeper;
@@ -46,6 +50,7 @@ import google.registry.util.CapturingLogHandler;
import google.registry.util.Retrier;
import java.util.logging.Level;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -77,14 +82,18 @@ public class AsyncTaskEnqueuerTest extends ShardableTestCase {
public void setUp() {
LoggerConfig.getConfig(AsyncTaskEnqueuer.class).addHandler(logHandler);
when(appEngineServiceUtils.getServiceHostname("backend")).thenReturn("backend.hostname.fake");
asyncTaskEnqueuer =
new AsyncTaskEnqueuer(
getQueue(QUEUE_ASYNC_ACTIONS),
getQueue(QUEUE_ASYNC_DELETE),
getQueue(QUEUE_ASYNC_HOST_RENAME),
standardSeconds(90),
appEngineServiceUtils,
new Retrier(new FakeSleeper(clock), 1));
asyncTaskEnqueuer = createForTesting(appEngineServiceUtils, clock, standardSeconds(90));
}
public static AsyncTaskEnqueuer createForTesting(
AppEngineServiceUtils appEngineServiceUtils, FakeClock clock, Duration asyncDeleteDelay) {
return new AsyncTaskEnqueuer(
getQueue(QUEUE_ASYNC_ACTIONS),
getQueue(QUEUE_ASYNC_DELETE),
getQueue(QUEUE_ASYNC_HOST_RENAME),
asyncDeleteDelay,
appEngineServiceUtils,
new Retrier(new FakeSleeper(clock), 1));
}
@Test
@@ -137,4 +146,56 @@ public class AsyncTaskEnqueuerTest extends ShardableTestCase {
assertNoTasksEnqueued(QUEUE_ASYNC_ACTIONS);
assertLogMessage(logHandler, Level.INFO, "Ignoring async re-save");
}
@Test
public void testEnqueueRelock() {
RegistryLock lock =
saveRegistryLock(
new RegistryLock.Builder()
.setLockCompletionTimestamp(clock.nowUtc())
.setUnlockRequestTimestamp(clock.nowUtc())
.setUnlockCompletionTimestamp(clock.nowUtc())
.isSuperuser(false)
.setDomainName("example.tld")
.setRepoId("repoId")
.setRelockDuration(standardHours(6))
.setRegistrarId("TheRegistrar")
.setRegistrarPocId("someone@example.com")
.setVerificationCode("hi")
.build());
asyncTaskEnqueuer.enqueueDomainRelock(lock);
assertTasksEnqueued(
QUEUE_ASYNC_ACTIONS,
new TaskMatcher()
.url(RelockDomainAction.PATH)
.method("POST")
.param(
RelockDomainAction.OLD_UNLOCK_REVISION_ID_PARAM,
String.valueOf(lock.getRevisionId()))
.etaDelta(
standardHours(6).minus(standardSeconds(30)),
standardHours(6).plus(standardSeconds(30))));
}
@Test
public void testFailure_enqueueRelock_noDuration() {
RegistryLock lockWithoutDuration =
saveRegistryLock(
new RegistryLock.Builder()
.isSuperuser(false)
.setDomainName("example.tld")
.setRepoId("repoId")
.setRegistrarId("TheRegistrar")
.setRegistrarPocId("someone@example.com")
.setVerificationCode("hi")
.build());
assertThat(
assertThrows(
IllegalArgumentException.class,
() -> asyncTaskEnqueuer.enqueueDomainRelock(lockWithoutDuration)))
.hasMessageThat()
.isEqualTo(
String.format(
"Lock with ID %s not configured for relock", lockWithoutDuration.getRevisionId()));
}
}
@@ -18,9 +18,7 @@ import static com.google.appengine.api.taskqueue.QueueFactory.getQueue;
import static com.google.common.collect.MoreCollectors.onlyElement;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_ACTIONS;
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_DELETE;
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_HOST_RENAME;
import static google.registry.batch.AsyncTaskMetrics.OperationResult.STALE;
import static google.registry.model.EppResourceUtils.loadByForeignKey;
import static google.registry.model.eppcommon.StatusValue.PENDING_DELETE;
@@ -151,13 +149,8 @@ public class DeleteContactsAndHostsActionTest
public void setup() {
inject.setStaticField(Ofy.class, "clock", clock);
enqueuer =
new AsyncTaskEnqueuer(
getQueue(QUEUE_ASYNC_ACTIONS),
getQueue(QUEUE_ASYNC_DELETE),
getQueue(QUEUE_ASYNC_HOST_RENAME),
Duration.ZERO,
mock(AppEngineServiceUtils.class),
new Retrier(new FakeSleeper(clock), 1));
AsyncTaskEnqueuerTest.createForTesting(
mock(AppEngineServiceUtils.class), clock, Duration.ZERO);
AsyncTaskMetrics asyncTaskMetricsMock = mock(AsyncTaskMetrics.class);
action = new DeleteContactsAndHostsAction();
action.asyncTaskMetrics = asyncTaskMetricsMock;
@@ -17,8 +17,6 @@ package google.registry.batch;
import static com.google.appengine.api.taskqueue.QueueFactory.getQueue;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth8.assertThat;
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_ACTIONS;
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_DELETE;
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_HOST_RENAME;
import static google.registry.batch.AsyncTaskMetrics.OperationType.DNS_REFRESH;
import static google.registry.model.ofy.ObjectifyService.ofy;
@@ -86,13 +84,8 @@ public class RefreshDnsOnHostRenameActionTest
public void setup() {
createTld("tld");
enqueuer =
new AsyncTaskEnqueuer(
getQueue(QUEUE_ASYNC_ACTIONS),
getQueue(QUEUE_ASYNC_DELETE),
getQueue(QUEUE_ASYNC_HOST_RENAME),
Duration.ZERO,
mock(AppEngineServiceUtils.class),
new Retrier(new FakeSleeper(clock), 1));
AsyncTaskEnqueuerTest.createForTesting(
mock(AppEngineServiceUtils.class), clock, Duration.ZERO);
AsyncTaskMetrics asyncTaskMetricsMock = mock(AsyncTaskMetrics.class);
action = new RefreshDnsOnHostRenameAction();
action.asyncTaskMetrics = asyncTaskMetricsMock;
@@ -28,6 +28,7 @@ import static google.registry.testing.SqlHelper.getRegistryLockByVerificationCod
import static google.registry.testing.SqlHelper.saveRegistryLock;
import static google.registry.tools.LockOrUnlockDomainCommand.REGISTRY_LOCK_STATUSES;
import static javax.servlet.http.HttpServletResponse.SC_NO_CONTENT;
import static org.mockito.Mockito.mock;
import com.google.common.collect.ImmutableSet;
import google.registry.model.domain.DomainBase;
@@ -39,8 +40,10 @@ import google.registry.testing.FakeClock;
import google.registry.testing.FakeResponse;
import google.registry.testing.UserInfo;
import google.registry.tools.DomainLockUtils;
import google.registry.util.AppEngineServiceUtils;
import google.registry.util.StringGenerator.Alphabets;
import java.util.Optional;
import org.joda.time.Duration;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -58,7 +61,10 @@ public class RelockDomainActionTest {
private final FakeResponse response = new FakeResponse();
private final FakeClock clock = new FakeClock();
private final DomainLockUtils domainLockUtils =
new DomainLockUtils(new DeterministicStringGenerator(Alphabets.BASE_58));
new DomainLockUtils(
new DeterministicStringGenerator(Alphabets.BASE_58),
AsyncTaskEnqueuerTest.createForTesting(
mock(AppEngineServiceUtils.class), clock, Duration.ZERO));
@Rule
public final AppEngineRule appEngineRule =
@@ -14,14 +14,11 @@
package google.registry.batch;
import static com.google.appengine.api.taskqueue.QueueFactory.getQueue;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.batch.AsyncTaskEnqueuer.PARAM_REQUESTED_TIME;
import static google.registry.batch.AsyncTaskEnqueuer.PARAM_RESOURCE_KEY;
import static google.registry.batch.AsyncTaskEnqueuer.PATH_RESAVE_ENTITY;
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_ACTIONS;
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_DELETE;
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_HOST_RENAME;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.testing.DatastoreHelper.createTld;
import static google.registry.testing.DatastoreHelper.newDomainBase;
@@ -47,12 +44,10 @@ import google.registry.model.ofy.Ofy;
import google.registry.request.Response;
import google.registry.testing.AppEngineRule;
import google.registry.testing.FakeClock;
import google.registry.testing.FakeSleeper;
import google.registry.testing.InjectRule;
import google.registry.testing.ShardableTestCase;
import google.registry.testing.TaskQueueHelper.TaskMatcher;
import google.registry.util.AppEngineServiceUtils;
import google.registry.util.Retrier;
import org.joda.time.DateTime;
import org.joda.time.Duration;
import org.junit.Before;
@@ -85,13 +80,7 @@ public class ResaveEntityActionTest extends ShardableTestCase {
inject.setStaticField(Ofy.class, "clock", clock);
when(appEngineServiceUtils.getServiceHostname("backend")).thenReturn("backend.hostname.fake");
asyncTaskEnqueuer =
new AsyncTaskEnqueuer(
getQueue(QUEUE_ASYNC_ACTIONS),
getQueue(QUEUE_ASYNC_DELETE),
getQueue(QUEUE_ASYNC_HOST_RENAME),
Duration.ZERO,
appEngineServiceUtils,
new Retrier(new FakeSleeper(clock), 1));
AsyncTaskEnqueuerTest.createForTesting(appEngineServiceUtils, clock, Duration.ZERO);
createTld("tld");
}
@@ -14,10 +14,7 @@
package google.registry.flows;
import static com.google.appengine.api.taskqueue.QueueFactory.getQueue;
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_ACTIONS;
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_DELETE;
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_HOST_RENAME;
import static org.joda.time.Duration.standardSeconds;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -26,6 +23,7 @@ import dagger.Module;
import dagger.Provides;
import dagger.Subcomponent;
import google.registry.batch.AsyncTaskEnqueuer;
import google.registry.batch.AsyncTaskEnqueuerTest;
import google.registry.config.RegistryConfig.ConfigModule;
import google.registry.config.RegistryConfig.ConfigModule.TmchCaMode;
import google.registry.dns.DnsQueue;
@@ -42,10 +40,8 @@ import google.registry.tmch.TmchCertificateAuthority;
import google.registry.tmch.TmchXmlSignature;
import google.registry.util.AppEngineServiceUtils;
import google.registry.util.Clock;
import google.registry.util.Retrier;
import google.registry.util.Sleeper;
import javax.inject.Singleton;
import org.joda.time.Duration;
/** Dagger component for running EPP tests. */
@Singleton
@@ -84,20 +80,12 @@ interface EppTestComponent {
}
public static FakesAndMocksModule create(
FakeClock clock,
EppMetric.Builder eppMetricBuilder,
TmchXmlSignature tmchXmlSignature) {
FakeClock clock, EppMetric.Builder eppMetricBuilder, TmchXmlSignature tmchXmlSignature) {
FakesAndMocksModule instance = new FakesAndMocksModule();
AppEngineServiceUtils appEngineServiceUtils = mock(AppEngineServiceUtils.class);
when(appEngineServiceUtils.getServiceHostname("backend")).thenReturn("backend.hostname.fake");
instance.asyncTaskEnqueuer =
new AsyncTaskEnqueuer(
getQueue(QUEUE_ASYNC_ACTIONS),
getQueue(QUEUE_ASYNC_DELETE),
getQueue(QUEUE_ASYNC_HOST_RENAME),
Duration.standardSeconds(90),
appEngineServiceUtils,
new Retrier(new FakeSleeper(clock), 1));
AsyncTaskEnqueuerTest.createForTesting(appEngineServiceUtils, clock, standardSeconds(90));
instance.clock = clock;
instance.domainFlowTmchUtils = new DomainFlowTmchUtils(tmchXmlSignature);
instance.sleeper = new FakeSleeper(clock);
@@ -42,22 +42,33 @@ import java.util.Set;
import org.joda.time.DateTime;
import org.junit.Before;
import org.junit.Rule;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.RegisterExtension;
/** Base class of all unit tests for entities which are persisted to Datastore via Objectify. */
@RunWith(JUnit4.class)
public abstract class EntityTestCase {
protected FakeClock fakeClock = new FakeClock(DateTime.now(UTC));
@Rule
public final AppEngineRule appEngine =
AppEngineRule.builder().withDatastoreAndCloudSql().withClock(fakeClock).build();
@Rule @RegisterExtension public final AppEngineRule appEngine;
@Rule public InjectRule inject = new InjectRule();
@Rule @RegisterExtension public InjectRule inject = new InjectRule();
protected EntityTestCase() {
this(false);
}
protected EntityTestCase(boolean enableJpaEntityCheck) {
appEngine =
AppEngineRule.builder()
.withDatastoreAndCloudSql()
.enableJpaEntityCoverageCheck(enableJpaEntityCheck)
.withClock(fakeClock)
.build();
}
@Before
@BeforeEach
public void injectClock() {
inject.setStaticField(Ofy.class, "clock", fakeClock);
}
@@ -28,20 +28,21 @@ import google.registry.model.domain.secdns.DelegationSignerData;
import google.registry.model.eppcommon.AuthInfo.PasswordAuth;
import google.registry.model.eppcommon.StatusValue;
import javax.persistence.EntityManager;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/** Verify that we can store/retrieve DomainBase objects from a SQL database. */
@RunWith(JUnit4.class)
public class DomainBaseSqlTest extends EntityTestCase {
DomainBase domain;
Key<ContactResource> contactKey;
Key<ContactResource> contact2Key;
@Before
public DomainBaseSqlTest() {
super(true);
}
@BeforeEach
public void setUp() {
contactKey = Key.create(ContactResource.class, "contact_id1");
contact2Key = Key.create(ContactResource.class, "contact_id2");
@@ -31,20 +31,21 @@ import google.registry.testing.AppEngineRule;
import google.registry.testing.FakeClock;
import java.util.Optional;
import org.joda.time.Duration;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
/** Unit tests for {@link RegistryLockDao}. */
@RunWith(JUnit4.class)
public final class RegistryLockDaoTest {
private final FakeClock fakeClock = new FakeClock();
@Rule
@RegisterExtension
public final AppEngineRule appEngine =
AppEngineRule.builder().withDatastoreAndCloudSql().withClock(fakeClock).build();
AppEngineRule.builder()
.withDatastoreAndCloudSql()
.enableJpaEntityCoverageCheck(true)
.withClock(fakeClock)
.build();
@Test
public void testSaveAndLoad_success() {
@@ -29,16 +29,14 @@ import google.registry.model.registry.label.PremiumList.PremiumListEntry;
import google.registry.model.registry.label.PremiumList.PremiumListRevision;
import google.registry.testing.AppEngineRule;
import org.joda.money.Money;
import org.junit.Rule;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.migrationsupport.rules.EnableRuleMigrationSupport;
import org.junit.jupiter.api.extension.RegisterExtension;
/** Unit tests for {@link PremiumList}. */
@EnableRuleMigrationSupport
public class PremiumListTest {
@Rule
@RegisterExtension
public final AppEngineRule appEngine = AppEngineRule.builder().withDatastoreAndCloudSql().build();
@BeforeEach
@@ -0,0 +1,45 @@
// Copyright 2020 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.persistence;
import static com.google.common.truth.Truth.assertThat;
import com.googlecode.objectify.Key;
import google.registry.testing.AppEngineRule;
import google.registry.testing.TestObject;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public class VKeyTest {
@Rule
public final AppEngineRule appEngineRule =
AppEngineRule.builder().withDatastoreAndCloudSql().build();
public VKeyTest() {}
@Test
public void testOptionalAccessors() {
VKey<TestObject> key = VKey.create(TestObject.class, null, null);
assertThat(key.maybeGetSqlKey().isPresent()).isFalse();
assertThat(key.maybeGetOfyKey().isPresent()).isFalse();
Key<TestObject> ofyKey = Key.create(TestObject.create("foo"));
assertThat(VKey.createOfy(TestObject.class, ofyKey).maybeGetOfyKey().get()).isEqualTo(ofyKey);
assertThat(VKey.createSql(TestObject.class, "foo").maybeGetSqlKey().get()).isEqualTo("foo");
}
}
@@ -32,7 +32,7 @@ import org.junit.runners.JUnit4;
/** Unit tests for {@link CidrAddressBlockListConverter}. */
@RunWith(JUnit4.class)
public class CidrAddressBlockListUserTypeTest {
public class CidrAddressBlockListConverterTest {
@Rule
public final JpaUnitTestRule jpaRule =
new JpaTestRules.Builder().withEntityClass(TestEntity.class).buildUnitTestRule();
@@ -25,16 +25,15 @@ import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule;
import java.util.Map;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.hibernate.annotations.Type;
import org.joda.money.CurrencyUnit;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Unit tests for {@link CurrencyToBillingMapUserType}. */
/** Unit tests for {@link CurrencyToBillingConverter}. */
@RunWith(JUnit4.class)
public class CurrencyToBillingMapUserTypeTest {
public class CurrencyToBillingConverterTest {
@Rule
public final JpaUnitTestRule jpaRule =
new JpaTestRules.Builder()
@@ -62,7 +61,6 @@ public class CurrencyToBillingMapUserTypeTest {
@Id String name = "id";
@Type(type = "google.registry.persistence.converter.CurrencyToBillingMapUserType")
Map<CurrencyUnit, BillingAccountEntry> currencyToBilling;
private TestEntity() {}
@@ -19,54 +19,56 @@ import static google.registry.persistence.transaction.TransactionManagerFactory.
import static org.junit.Assert.assertThrows;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import google.registry.model.ImmutableObject;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaUnitTestRule;
import java.util.Map;
import javax.persistence.Converter;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.NoResultException;
import org.hibernate.annotations.Type;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Unit tests for {@link MapUserType}. */
/** Unit tests for {@link StringMapConverterBase}. */
@RunWith(JUnit4.class)
public class MapUserTypeTest {
// Reusing production script sql/flyway/V14__load_extension_for_hstore.sql, which loads the
// hstore extension but nothing else.
public class StringMapConverterBaseTest {
@Rule
public final JpaUnitTestRule jpaRule =
public final JpaTestRules.JpaUnitTestRule jpaRule =
new JpaTestRules.Builder()
.withInitScript("sql/flyway/V14__load_extension_for_hstore.sql")
.withEntityClass(TestEntity.class)
.withEntityClass(TestStringMapConverter.class, TestEntity.class)
.buildUnitTestRule();
private static final ImmutableMap<Key, Value> MAP =
ImmutableMap.of(
new Key("key1"), new Value("value1"),
new Key("key2"), new Value("value2"),
new Key("key3"), new Value("value3"));
@Test
public void roundTripConversion_returnsSameMap() {
Map<String, String> map = ImmutableMap.of("key1", "value1", "key2", "value2");
TestEntity testEntity = new TestEntity(map);
TestEntity testEntity = new TestEntity(MAP);
jpaTm().transact(() -> jpaTm().getEntityManager().persist(testEntity));
TestEntity persisted =
jpaTm().transact(() -> jpaTm().getEntityManager().find(TestEntity.class, "id"));
assertThat(persisted.map).containsExactly("key1", "value1", "key2", "value2");
assertThat(persisted.map).containsExactlyEntriesIn(MAP);
}
@Test
public void testMerge_succeeds() {
Map<String, String> map = ImmutableMap.of("key1", "value1", "key2", "value2");
TestEntity testEntity = new TestEntity(map);
public void testUpdateColumn_succeeds() {
TestEntity testEntity = new TestEntity(MAP);
jpaTm().transact(() -> jpaTm().getEntityManager().persist(testEntity));
TestEntity persisted =
jpaTm().transact(() -> jpaTm().getEntityManager().find(TestEntity.class, "id"));
persisted.map = ImmutableMap.of("key3", "value3");
assertThat(persisted.map).containsExactlyEntriesIn(MAP);
persisted.map = ImmutableMap.of(new Key("key4"), new Value("value4"));
jpaTm().transact(() -> jpaTm().getEntityManager().merge(persisted));
TestEntity updated =
jpaTm().transact(() -> jpaTm().getEntityManager().find(TestEntity.class, "id"));
assertThat(updated.map).containsExactly("key3", "value3");
assertThat(updated.map).containsExactly(new Key("key4"), new Value("value4"));
}
@Test
@@ -79,7 +81,7 @@ public class MapUserTypeTest {
}
@Test
public void testEmptyCollection_writesAndReadsEmptyCollectionSuccessfully() {
public void testEmptyMap_writesAndReadsEmptyCollectionSuccessfully() {
TestEntity testEntity = new TestEntity(ImmutableMap.of());
jpaTm().transact(() -> jpaTm().getEntityManager().persist(testEntity));
TestEntity persisted =
@@ -88,7 +90,7 @@ public class MapUserTypeTest {
}
@Test
public void testNativeQuery_succeeds() throws Exception {
public void testNativeQuery_succeeds() {
executeNativeQuery(
"INSERT INTO \"TestEntity\" (name, map) VALUES ('id', 'key1=>value1, key2=>value2')");
@@ -126,17 +128,46 @@ public class MapUserTypeTest {
.transact(() -> jpaTm().getEntityManager().createNativeQuery(sql).executeUpdate());
}
private static class Key extends ImmutableObject {
private String key;
private Key(String key) {
this.key = key;
}
}
private static class Value extends ImmutableObject {
private String value;
private Value(String value) {
this.value = value;
}
}
@Converter(autoApply = true)
private static class TestStringMapConverter extends StringMapConverterBase<Key, Value> {
@Override
Map.Entry<String, String> convertToDatabaseMapEntry(Map.Entry<Key, Value> entry) {
return Maps.immutableEntry(entry.getKey().key, entry.getValue().value);
}
@Override
Map.Entry<Key, Value> convertToEntityMapEntry(Map.Entry<String, String> entry) {
return Maps.immutableEntry(new Key(entry.getKey()), new Value(entry.getValue()));
}
}
@Entity(name = "TestEntity") // Override entity name to avoid the nested class reference.
private static class TestEntity extends ImmutableObject {
@Id String name = "id";
@Type(type = "google.registry.persistence.converter.MapUserType")
Map<String, String> map;
Map<Key, Value> map;
private TestEntity() {}
private TestEntity(Map<String, String> map) {
private TestEntity(Map<Key, Value> map) {
this.map = map;
}
}
@@ -27,6 +27,7 @@ import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Supplier;
import javax.persistence.Entity;
import org.junit.rules.ExternalResource;
@@ -51,15 +52,15 @@ public class JpaEntityCoverage extends ExternalResource {
private static final Map<String, Boolean> testsJpaEntities = Maps.newHashMap();
// Provides class name of the test being executed.
private final TestCaseWatcher watcher;
private final Supplier<String> currTestClassNameSupplier;
public JpaEntityCoverage(TestCaseWatcher watcher) {
this.watcher = watcher;
public JpaEntityCoverage(Supplier<String> currTestClassNameSupplier) {
this.currTestClassNameSupplier = currTestClassNameSupplier;
}
@Override
public void before() {
testsJpaEntities.putIfAbsent(watcher.getTestClass(), false);
testsJpaEntities.putIfAbsent(currTestClassNameSupplier.get(), false);
}
@Override
@@ -69,7 +70,7 @@ public class JpaEntityCoverage extends ExternalResource {
.forEach(
entity -> {
allCoveredJpaEntities.add(entity);
testsJpaEntities.put(watcher.getTestClass(), true);
testsJpaEntities.put(currTestClassNameSupplier.get(), true);
});
}
@@ -29,6 +29,9 @@ import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import org.joda.time.DateTime;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.rules.RuleChain;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
@@ -88,7 +91,7 @@ public class JpaTestRules {
this.ruleChain =
RuleChain.outerRule(watcher)
.around(integrationTestRule)
.around(new JpaEntityCoverage(watcher));
.around(new JpaEntityCoverage(watcher::getTestClass));
}
@Override
@@ -97,6 +100,40 @@ public class JpaTestRules {
}
}
/**
* JUnit extension for member classes of {@link
* google.registry.schema.integration.SqlIntegrationTestSuite}. In addition to providing a
* database through {@link JpaIntegrationTestRule}, it also keeps track of the test coverage of
* the declared JPA entities (in persistence.xml). Per-class statistics are stored in static
* variables. The SqlIntegrationTestSuite inspects the cumulative statistics after all test
* classes have run.
*/
public static final class JpaIntegrationWithCoverageExtension
implements BeforeEachCallback, AfterEachCallback {
private String currentTestClassName = null;
private final JpaEntityCoverage jpaEntityCoverage =
new JpaEntityCoverage(() -> this.currentTestClassName);
private final JpaIntegrationTestRule integrationTestRule;
JpaIntegrationWithCoverageExtension(JpaIntegrationTestRule integrationTestRule) {
this.integrationTestRule = integrationTestRule;
}
@Override
public void beforeEach(ExtensionContext context) throws Exception {
this.currentTestClassName = context.getRequiredTestClass().getName();
integrationTestRule.before();
jpaEntityCoverage.before();
}
@Override
public void afterEach(ExtensionContext context) throws Exception {
jpaEntityCoverage.after();
integrationTestRule.after();
this.currentTestClassName = null;
}
}
/** Builder of test rules that provide {@link JpaTransactionManager}. */
public static class Builder {
private String initScript;
@@ -149,6 +186,15 @@ public class JpaTestRules {
return new JpaIntegrationWithCoverageRule(buildIntegrationTestRule());
}
/**
* JUnit extension that adapts {@link JpaIntegrationTestRule} for JUnit 5 and also checks test
* coverage of JPA entity classes.
*/
public JpaIntegrationWithCoverageExtension buildIntegrationWithCoverageExtension() {
checkState(initScript == null, "Integration tests do not accept initScript");
return new JpaIntegrationWithCoverageExtension(buildIntegrationTestRule());
}
/** Builds a {@link JpaUnitTestRule} instance. */
public JpaUnitTestRule buildUnitTestRule() {
checkState(
@@ -30,13 +30,10 @@ import google.registry.testing.FakeClock;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
/** Unit tests for {@link Cursor}. */
@RunWith(JUnit4.class)
public class CursorDaoTest {
private final FakeClock fakeClock = new FakeClock();
@@ -44,9 +41,13 @@ public class CursorDaoTest {
private final TestLogHandler logHandler = new TestLogHandler();
private final Logger loggerToIntercept = Logger.getLogger(CursorDao.class.getCanonicalName());
@Rule
@RegisterExtension
public final AppEngineRule appEngine =
AppEngineRule.builder().withDatastoreAndCloudSql().withClock(fakeClock).build();
AppEngineRule.builder()
.withDatastoreAndCloudSql()
.enableJpaEntityCoverageCheck(true)
.withClock(fakeClock)
.build();
@Test
public void save_worksSuccessfullyOnNewCursor() {
@@ -27,9 +27,9 @@ import google.registry.schema.tmch.ClaimsListDaoTest;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.platform.suite.api.SelectClasses;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
/**
* Groups all JPA entity tests in one suite for easy invocation. This suite is used for
@@ -48,8 +48,8 @@ import org.junit.runners.Suite.SuiteClasses;
* database. Therefore this is not the right place for verifying backward data compatibility in
* end-to-end functional tests.
*/
@RunWith(Suite.class)
@SuiteClasses({
@RunWith(JUnitPlatform.class)
@SelectClasses({
ClaimsListDaoTest.class,
CursorDaoTest.class,
DomainBaseSqlTest.class,
@@ -23,20 +23,21 @@ import google.registry.model.EntityTestCase;
import google.registry.model.registrar.Registrar;
import google.registry.model.registrar.RegistrarAddress;
import google.registry.persistence.VKey;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link RegistrarDao}. */
@RunWith(JUnit4.class)
/** Unit tests for persisting {@link Registrar} entities. */
public class RegistrarDaoTest extends EntityTestCase {
private final VKey<Registrar> registrarKey = VKey.createSql(Registrar.class, "registrarId");
private Registrar testRegistrar;
@Before
public RegistrarDaoTest() {
super(true);
}
@BeforeEach
public void setUp() {
testRegistrar =
new Registrar.Builder()
@@ -19,28 +19,25 @@ import static google.registry.testing.LogsSubject.assertAboutLogs;
import com.google.common.testing.TestLogHandler;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationWithCoverageRule;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationWithCoverageExtension;
import google.registry.testing.FakeClock;
import java.util.Optional;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.joda.time.Duration;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
/** Unit tests for {@link Lock}. */
@RunWith(JUnit4.class)
public class LockDaoTest {
private final FakeClock fakeClock = new FakeClock();
private final TestLogHandler logHandler = new TestLogHandler();
private final Logger loggerToIntercept = Logger.getLogger(LockDao.class.getCanonicalName());
@Rule
public final JpaIntegrationWithCoverageRule jpaRule =
new JpaTestRules.Builder().withClock(fakeClock).buildIntegrationWithCoverageRule();
@RegisterExtension
public final JpaIntegrationWithCoverageExtension jpa =
new JpaTestRules.Builder().withClock(fakeClock).buildIntegrationWithCoverageExtension();
@Test
public void save_worksSuccessfully() {
@@ -34,21 +34,22 @@ import java.math.BigDecimal;
import java.util.Optional;
import org.joda.money.CurrencyUnit;
import org.joda.money.Money;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
/** Unit tests for {@link PremiumListDao}. */
@RunWith(JUnit4.class)
public class PremiumListDaoTest {
private final FakeClock fakeClock = new FakeClock();
@Rule
@RegisterExtension
public final AppEngineRule appEngine =
AppEngineRule.builder().withDatastoreAndCloudSql().withClock(fakeClock).build();
AppEngineRule.builder()
.withDatastoreAndCloudSql()
.enableJpaEntityCoverageCheck(true)
.withClock(fakeClock)
.build();
private static final ImmutableMap<String, BigDecimal> TEST_PRICES =
ImmutableMap.of(
@@ -124,7 +125,7 @@ public class PremiumListDaoTest {
// TODO(b/147246613): Un-ignore this.
@Test
@Ignore
@Disabled
public void update_throwsWhenListDoesntExist() {
IllegalArgumentException thrown =
assertThrows(
@@ -20,23 +20,20 @@ import static google.registry.persistence.transaction.TransactionManagerFactory.
import com.google.common.collect.ImmutableMap;
import google.registry.model.registry.label.ReservationType;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationWithCoverageRule;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationWithCoverageExtension;
import google.registry.schema.tld.ReservedList.ReservedEntry;
import google.registry.testing.FakeClock;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
/** Unit tests for {@link ReservedListDao}. */
@RunWith(JUnit4.class)
public class ReservedListDaoTest {
private final FakeClock fakeClock = new FakeClock();
@Rule
public final JpaIntegrationWithCoverageRule jpaRule =
new JpaTestRules.Builder().withClock(fakeClock).buildIntegrationWithCoverageRule();
@RegisterExtension
public final JpaIntegrationWithCoverageExtension jpa =
new JpaTestRules.Builder().withClock(fakeClock).buildIntegrationWithCoverageExtension();
private static final ImmutableMap<String, ReservedEntry> TEST_RESERVATIONS =
ImmutableMap.of(
@@ -18,22 +18,19 @@ import static com.google.common.truth.Truth.assertThat;
import com.google.common.collect.ImmutableMap;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationWithCoverageRule;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationWithCoverageExtension;
import google.registry.testing.FakeClock;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
/** Unit tests for {@link ClaimsListDao}. */
@RunWith(JUnit4.class)
public class ClaimsListDaoTest {
private final FakeClock fakeClock = new FakeClock();
@Rule
public final JpaIntegrationWithCoverageRule jpaRule =
new JpaTestRules.Builder().withClock(fakeClock).buildIntegrationWithCoverageRule();
@RegisterExtension
public final JpaIntegrationWithCoverageExtension jpa =
new JpaTestRules.Builder().withClock(fakeClock).buildIntegrationWithCoverageExtension();
@Test
public void trySave_insertsClaimsListSuccessfully() {
@@ -14,6 +14,7 @@
package google.registry.testing;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.truth.Truth.assertWithMessage;
import static google.registry.testing.DatastoreHelper.persistSimpleResources;
import static google.registry.util.ResourceUtils.readResourceUtf8;
@@ -40,6 +41,9 @@ import google.registry.model.registrar.Registrar.State;
import google.registry.model.registrar.RegistrarAddress;
import google.registry.model.registrar.RegistrarContact;
import google.registry.persistence.transaction.JpaTestRules;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationTestRule;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationWithCoverageExtension;
import google.registry.persistence.transaction.JpaTestRules.JpaIntegrationWithCoverageRule;
import google.registry.util.Clock;
import java.io.ByteArrayInputStream;
import java.io.File;
@@ -52,6 +56,9 @@ import javax.annotation.Nullable;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.rules.ExternalResource;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.Description;
@@ -65,9 +72,15 @@ import org.junit.runners.model.Statement;
*
* <p>This rule also resets global Objectify for the current thread.
*
* <p>This class works with both JUnit 4 and JUnit 5. With JUnit 4, the test runner calls {@link
* #apply(Statement, Description)}, which in turns calls {@link #before()} on entry and {@link
* #after()} on exit. With JUnit 5, the test runner calls {@link #beforeEach(ExtensionContext)} and
* {@link #afterEach(ExtensionContext)}.
*
* @see org.junit.rules.ExternalResource
*/
public final class AppEngineRule extends ExternalResource {
public final class AppEngineRule extends ExternalResource
implements BeforeEachCallback, AfterEachCallback {
public static final String NEW_REGISTRAR_GAE_USER_ID = "666";
public static final String THE_REGISTRAR_GAE_USER_ID = "31337";
@@ -92,8 +105,19 @@ public final class AppEngineRule extends ExternalResource {
/** A rule-within-a-rule to provide a temporary folder for AppEngineRule's internal temp files. */
TemporaryFolder temporaryFolder = new TemporaryFolder();
/**
* Sets up a SQL database when running on JUnit 5. This is for test classes that are not member of
* the {@code SqlIntegrationTestSuite}.
*/
JpaIntegrationTestRule jpaIntegrationTestRule = null;
/**
* Sets up a SQL database when running on JUnit 5 and records the JPA entities tested by each test
* class. This is for {@code SqlIntegrationTestSuite} members.
*/
JpaIntegrationWithCoverageExtension jpaIntegrationWithCoverageExtension = null;
private boolean withDatastoreAndCloudSql;
private boolean enableJpaEntityCoverageCheck;
private boolean withLocalModules;
private boolean withTaskQueue;
private boolean withUserService;
@@ -113,6 +137,14 @@ public final class AppEngineRule extends ExternalResource {
rule.withDatastoreAndCloudSql = true;
return this;
}
/**
* Enables JPA entity coverage check if {@code enabled} is true. This should only be enabled for
* members of SqlIntegrationTestSuite.
*/
public Builder enableJpaEntityCoverageCheck(boolean enabled) {
rule.enableJpaEntityCoverageCheck = enabled;
return this;
}
/** Turn on the use of local modules. */
public Builder withLocalModules() {
@@ -150,6 +182,9 @@ public final class AppEngineRule extends ExternalResource {
}
public AppEngineRule build() {
checkState(
!rule.enableJpaEntityCoverageCheck || rule.withDatastoreAndCloudSql,
"withJpaEntityCoverageCheck enabled without Cloud SQL");
return rule;
}
}
@@ -256,7 +291,45 @@ public final class AppEngineRule extends ExternalResource {
.build();
}
/** Hack to make sure AppEngineRule is always wrapped in a TemporaryFolder rule. */
/** Called before every test method. JUnit 5 only. */
@Override
public void beforeEach(ExtensionContext context) throws Exception {
before();
if (withDatastoreAndCloudSql) {
JpaTestRules.Builder builder = new JpaTestRules.Builder();
if (clock != null) {
builder.withClock(clock);
}
if (enableJpaEntityCoverageCheck) {
jpaIntegrationWithCoverageExtension = builder.buildIntegrationWithCoverageExtension();
jpaIntegrationWithCoverageExtension.beforeEach(context);
} else {
jpaIntegrationTestRule = builder.buildIntegrationTestRule();
jpaIntegrationTestRule.before();
}
}
}
/** Called after each test method. JUnit 5 only. */
@Override
public void afterEach(ExtensionContext context) throws Exception {
if (withDatastoreAndCloudSql) {
if (enableJpaEntityCoverageCheck) {
jpaIntegrationWithCoverageExtension.afterEach(context);
} else {
jpaIntegrationTestRule.after();
}
}
after();
}
/**
* Hack to make sure AppEngineRule is always wrapped in a {@link JpaIntegrationWithCoverageRule}.
* JUnit 4 only.
*/
// Note: Even with @EnableRuleMigrationSupport, JUnit5 runner does not call this method.
// Note 2: Do not migrate members of SqlIntegrationTestSuite to JUnit5 individually.
// TODO(weiminyu): migrate SqlIntegrationTestSuite in one go.
@Override
public Statement apply(Statement base, Description description) {
Statement statement = base;
@@ -265,14 +338,18 @@ public final class AppEngineRule extends ExternalResource {
if (clock != null) {
builder.withClock(clock);
}
statement = builder.buildIntegrationWithCoverageRule().apply(base, description);
checkState(
!enableJpaEntityCoverageCheck,
"JUnit4 tests must not enable withJpaEntityCoverageCheck.");
statement = builder.buildIntegrationTestRule().apply(base, description);
}
return temporaryFolder.apply(super.apply(statement, description), description);
return super.apply(statement, description);
}
@Override
protected void before() throws IOException {
setupLogging();
temporaryFolder.create();
Set<LocalServiceTestConfig> configs = new HashSet<>();
if (withUrlFetch) {
configs.add(new LocalURLFetchServiceTestConfig());
@@ -346,10 +423,10 @@ public final class AppEngineRule extends ExternalResource {
helper = null;
// Test that Datastore didn't need any indexes we don't have listed in our index file.
File indexFile = new File(temporaryFolder.getRoot(), "datastore-indexes-auto.xml");
if (!indexFile.exists()) {
return;
}
try {
if (!indexFile.exists()) {
return;
}
String indexFileContent = Files.asCharSource(indexFile, UTF_8).read();
if (indexFileContent.trim().isEmpty()) {
return;
@@ -361,6 +438,8 @@ public final class AppEngineRule extends ExternalResource {
}
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
temporaryFolder.delete();
}
}
@@ -22,6 +22,8 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;
import org.junit.jupiter.api.extension.AfterEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.rules.ExternalResource;
/**
@@ -44,9 +46,10 @@ import org.junit.rules.ExternalResource;
* to be evil; but hopefully one day we'll be able to delete this class and do things
* <i>properly</i> with <a href="http://square.github.io/dagger/">Dagger</a> dependency injection.
*
* <p>You use this class by declaring it as a {@link org.junit.Rule &#064;Rule} field and then
* calling {@link #setStaticField} from either your {@link org.junit.Test &#064;Test} or {@link
* org.junit.Before &#064;Before} methods. For example:
* <p>This class temporarily supports both JUnit4 and JUnit5. You use this class in JUnit4 by
* declaring it as a {@link org.junit.Rule &#064;Rule} field and then calling {@link
* #setStaticField} from either your {@link org.junit.Test &#064;Test} or {@link org.junit.Before
* &#064;Before} methods. For example:
*
* <pre>
* // Doomsday.java
@@ -85,7 +88,7 @@ import org.junit.rules.ExternalResource;
* @see google.registry.util.NonFinalForTesting
* @see org.junit.rules.ExternalResource
*/
public class InjectRule extends ExternalResource {
public class InjectRule extends ExternalResource implements AfterEachCallback {
private static class Change {
private final Field field;
@@ -140,6 +143,11 @@ public class InjectRule extends ExternalResource {
injected.add(field);
}
@Override
public void afterEach(ExtensionContext context) throws Exception {
after();
}
@Override
protected void after() {
RuntimeException thrown = null;
@@ -76,6 +76,12 @@ public class CheckDomainCommandTest extends EppToolCommandTestCase<CheckDomainCo
eppVerifier.expectDryRun().expectClientId("adminreg").verifySent("domain_check_fee.xml");
}
@Test
public void testSuccess_allocationToken_reserved() throws Exception {
runCommand("--client=NewRegistrar", "--token=abc123", "example.tld");
eppVerifier.expectDryRun().verifySent("domain_check_fee_allocationtoken.xml");
}
@Test
public void testFailure_NoMainParameter() {
assertThrows(ParameterException.class, () -> runCommand("--client=NewRegistrar"));
@@ -17,11 +17,15 @@ package google.registry.tools;
import static com.google.common.truth.Truth.assertThat;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.io.Resources;
import google.registry.testing.AppEngineRule;
import google.registry.tools.LevelDbFileBuilder.Property;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.PrintStream;
import java.net.URL;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
@@ -35,18 +39,38 @@ public class CompareDbBackupsTest {
// Capture standard output.
private final ByteArrayOutputStream stdout = new ByteArrayOutputStream();
private PrintStream orgStdout;
@Rule public final TemporaryFolder tempFs = new TemporaryFolder();
@Rule
public final AppEngineRule appEngine = AppEngineRule.builder().withDatastoreAndCloudSql().build();
@Before
public void before() {
orgStdout = System.out;
System.setOut(new PrintStream(stdout));
}
@After
public void after() {
System.setOut(orgStdout);
}
@Test
public void testCommand() throws Exception {
public void testLoadBackup() {
URL backupRootFolder = Resources.getResource("google/registry/tools/datastore-export");
CompareDbBackups.main(new String[] {backupRootFolder.getPath(), backupRootFolder.getPath()});
String output = new String(stdout.toByteArray(), UTF_8);
assertThat(output).containsMatch("Both sets have the same 41 entities");
}
@Test
public void testCompareBackups() throws Exception {
// Create two directories corresponding to data dumps.
File dump1 = tempFs.newFolder("dump1");
LevelDbFileBuilder builder = new LevelDbFileBuilder(new File(dump1, "data1"));
LevelDbFileBuilder builder = new LevelDbFileBuilder(new File(dump1, "output-data1"));
builder.addEntityProto(
BASE_ID,
Property.create("eeny", 100L),
@@ -60,7 +84,7 @@ public class CompareDbBackupsTest {
builder.build();
File dump2 = tempFs.newFolder("dump2");
builder = new LevelDbFileBuilder(new File(dump2, "data2"));
builder = new LevelDbFileBuilder(new File(dump2, "output-data2"));
builder.addEntityProto(
BASE_ID + 1,
Property.create("moxey", 100L),
@@ -73,7 +97,6 @@ public class CompareDbBackupsTest {
Property.create("strutz", 300L));
builder.build();
System.setOut(new PrintStream(stdout));
CompareDbBackups.main(new String[] {dump1.getCanonicalPath(), dump2.getCanonicalPath()});
String output = new String(stdout.toByteArray(), UTF_8);
assertThat(output)
@@ -61,18 +61,43 @@ public abstract class CreateOrUpdateReservedListCommandTestCase<
@Test
public void testFailure_fileDoesntExist() {
assertThrows(
ParameterException.class,
() ->
runCommandForced(
"--name=xn--q9jyb4c-blah", "--input=" + reservedTermsPath + "-nonexistent"));
assertThat(
assertThrows(
ParameterException.class,
() ->
runCommandForced(
"--name=xn--q9jyb4c_common-reserved",
"--input=" + reservedTermsPath + "-nonexistent")))
.hasMessageThat()
.contains("-i not found");
}
@Test
public void testFailure_fileDoesntParse() {
assertThrows(
IllegalArgumentException.class,
() -> runCommandForced("--name=xn--q9jyb4c-blork", "--input=" + invalidReservedTermsPath));
assertThat(
assertThrows(
IllegalArgumentException.class,
() ->
runCommandForced(
"--name=xn--q9jyb4c_common-reserved",
"--input=" + invalidReservedTermsPath)))
.hasMessageThat()
.contains("No enum constant");
}
@Test
public void testFailure_invalidLabel_includesFullDomainName() throws Exception {
Files.asCharSink(new File(invalidReservedTermsPath), UTF_8)
.write("example.tld,FULLY_BLOCKED\n\n");
assertThat(
assertThrows(
IllegalArgumentException.class,
() ->
runCommandForced(
"--name=xn--q9jyb4c_common-reserved",
"--input=" + invalidReservedTermsPath)))
.hasMessageThat()
.isEqualTo("Label example.tld must not be a multi-level domain name");
}
google.registry.schema.tld.ReservedList createCloudSqlReservedList(
@@ -15,6 +15,7 @@
package google.registry.tools;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.batch.AsyncTaskEnqueuer.QUEUE_ASYNC_ACTIONS;
import static google.registry.model.ofy.ObjectifyService.ofy;
import static google.registry.testing.DatastoreHelper.assertNoBillingEvents;
import static google.registry.testing.DatastoreHelper.createTlds;
@@ -25,10 +26,17 @@ import static google.registry.testing.DatastoreHelper.persistActiveHost;
import static google.registry.testing.DatastoreHelper.persistResource;
import static google.registry.testing.SqlHelper.getRegistryLockByRevisionId;
import static google.registry.testing.SqlHelper.getRegistryLockByVerificationCode;
import static google.registry.testing.TaskQueueHelper.assertTasksEnqueued;
import static google.registry.tools.LockOrUnlockDomainCommand.REGISTRY_LOCK_STATUSES;
import static org.joda.time.Duration.standardDays;
import static org.joda.time.Duration.standardHours;
import static org.joda.time.Duration.standardSeconds;
import static org.junit.Assert.assertThrows;
import static org.mockito.Mockito.mock;
import com.google.common.collect.ImmutableList;
import google.registry.batch.AsyncTaskEnqueuerTest;
import google.registry.batch.RelockDomainAction;
import google.registry.model.billing.BillingEvent;
import google.registry.model.billing.BillingEvent.Reason;
import google.registry.model.domain.DomainBase;
@@ -40,12 +48,15 @@ import google.registry.testing.AppEngineRule;
import google.registry.testing.DatastoreHelper;
import google.registry.testing.DeterministicStringGenerator;
import google.registry.testing.FakeClock;
import google.registry.testing.TaskQueueHelper.TaskMatcher;
import google.registry.testing.UserInfo;
import google.registry.util.AppEngineServiceUtils;
import google.registry.util.StringGenerator.Alphabets;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import org.joda.time.Duration;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -59,15 +70,19 @@ public final class DomainLockUtilsTest {
private static final String DOMAIN_NAME = "example.tld";
private static final String POC_ID = "marla.singer@example.com";
private final FakeClock clock = new FakeClock();
private final FakeClock clock = new FakeClock(DateTime.now(DateTimeZone.UTC));
private final DomainLockUtils domainLockUtils =
new DomainLockUtils(new DeterministicStringGenerator(Alphabets.BASE_58));
new DomainLockUtils(
new DeterministicStringGenerator(Alphabets.BASE_58),
AsyncTaskEnqueuerTest.createForTesting(
mock(AppEngineServiceUtils.class), clock, standardSeconds(90)));
@Rule
public final AppEngineRule appEngineRule =
AppEngineRule.builder()
.withDatastoreAndCloudSql()
.withClock(clock)
.withTaskQueue()
.withUserService(UserInfo.create(POC_ID, "12345"))
.build();
@@ -109,7 +124,7 @@ public final class DomainLockUtilsTest {
@Test
public void testSuccess_createLock_previousLockExpired() {
domainLockUtils.saveNewRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
clock.advanceBy(Duration.standardDays(1));
clock.advanceBy(standardDays(1));
RegistryLock lock =
domainLockUtils.saveNewRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
domainLockUtils.verifyAndApplyLock(lock.getVerificationCode(), false);
@@ -121,7 +136,7 @@ public final class DomainLockUtilsTest {
domainLockUtils.administrativelyApplyLock(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
domainLockUtils.saveNewRegistryUnlockRequest(
DOMAIN_NAME, "TheRegistrar", false, Optional.empty());
clock.advanceBy(Duration.standardDays(1));
clock.advanceBy(standardDays(1));
RegistryLock unlockRequest =
domainLockUtils.saveNewRegistryUnlockRequest(
DOMAIN_NAME, "TheRegistrar", false, Optional.empty());
@@ -232,8 +247,28 @@ public final class DomainLockUtilsTest {
domainLockUtils.administrativelyApplyLock(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
RegistryLock lock =
domainLockUtils.saveNewRegistryUnlockRequest(
DOMAIN_NAME, "TheRegistrar", false, Optional.of(Duration.standardDays(1)));
assertThat(lock.getRelockDuration()).isEqualTo(Optional.of(Duration.standardDays(1)));
DOMAIN_NAME, "TheRegistrar", false, Optional.of(standardDays(1)));
assertThat(lock.getRelockDuration()).isEqualTo(Optional.of(standardDays(1)));
}
@Test
public void testSuccess_unlock_relockSubmitted() {
domainLockUtils.administrativelyApplyLock(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
RegistryLock lock =
domainLockUtils.saveNewRegistryUnlockRequest(
DOMAIN_NAME, "TheRegistrar", false, Optional.of(standardHours(6)));
domainLockUtils.verifyAndApplyUnlock(lock.getVerificationCode(), false);
assertTasksEnqueued(
QUEUE_ASYNC_ACTIONS,
new TaskMatcher()
.url(RelockDomainAction.PATH)
.method("POST")
.param(
RelockDomainAction.OLD_UNLOCK_REVISION_ID_PARAM,
String.valueOf(lock.getRevisionId()))
.etaDelta(
standardHours(6).minus(standardSeconds(30)),
standardDays(6).plus(standardSeconds(30))));
}
@Test
@@ -338,7 +373,7 @@ public final class DomainLockUtilsTest {
public void testFailure_applyLock_expired() {
RegistryLock lock =
domainLockUtils.saveNewRegistryLockRequest(DOMAIN_NAME, "TheRegistrar", POC_ID, false);
clock.advanceBy(Duration.standardDays(1));
clock.advanceBy(standardDays(1));
assertThat(
assertThrows(
IllegalArgumentException.class,
@@ -23,11 +23,8 @@ import google.registry.rde.Ghostryde;
import google.registry.testing.BouncyCastleProviderRule;
import google.registry.testing.FakeKeyringModule;
import google.registry.testing.InjectRule;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -61,19 +58,12 @@ public class GhostrydeCommandTest extends CommandTestCase<GhostrydeCommand> {
public final BouncyCastleProviderRule bouncy = new BouncyCastleProviderRule();
private Keyring keyring;
private PrintStream orgStdout;
@Before
public void before() {
keyring = new FakeKeyringModule().get();
command.rdeStagingDecryptionKey = keyring::getRdeStagingDecryptionKey;
command.rdeStagingEncryptionKey = keyring::getRdeStagingEncryptionKey;
orgStdout = System.out;
}
@After
public void after() {
System.setOut(orgStdout);
}
@Test
@@ -153,9 +143,7 @@ public class GhostrydeCommandTest extends CommandTestCase<GhostrydeCommand> {
Path inFile = tmpDir.newFolder().toPath().resolve("atrain.ghostryde");
Files.write(
inFile, Ghostryde.encode(SONG_BY_CHRISTINA_ROSSETTI, keyring.getRdeStagingEncryptionKey()));
ByteArrayOutputStream out = new ByteArrayOutputStream();
System.setOut(new PrintStream(out));
runCommand("--decrypt", "--input=" + inFile);
assertThat(out.toByteArray()).isEqualTo(SONG_BY_CHRISTINA_ROSSETTI);
assertThat(getStdoutAsString().getBytes(UTF_8)).isEqualTo(SONG_BY_CHRISTINA_ROSSETTI);
}
}
@@ -24,15 +24,19 @@ import static google.registry.testing.DatastoreHelper.persistResource;
import static google.registry.testing.SqlHelper.getMostRecentRegistryLockByRepoId;
import static google.registry.tools.LockOrUnlockDomainCommand.REGISTRY_LOCK_STATUSES;
import static org.junit.Assert.assertThrows;
import static org.mockito.Mockito.mock;
import com.google.common.collect.ImmutableList;
import google.registry.batch.AsyncTaskEnqueuerTest;
import google.registry.model.domain.DomainBase;
import google.registry.model.registrar.Registrar.Type;
import google.registry.testing.DeterministicStringGenerator;
import google.registry.util.AppEngineServiceUtils;
import google.registry.util.StringGenerator.Alphabets;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.joda.time.Duration;
import org.junit.Before;
import org.junit.Test;
@@ -45,7 +49,10 @@ public class LockDomainCommandTest extends CommandTestCase<LockDomainCommand> {
createTld("tld");
command.registryAdminClientId = "adminreg";
command.domainLockUtils =
new DomainLockUtils(new DeterministicStringGenerator(Alphabets.BASE_58));
new DomainLockUtils(
new DeterministicStringGenerator(Alphabets.BASE_58),
AsyncTaskEnqueuerTest.createForTesting(
mock(AppEngineServiceUtils.class), fakeClock, Duration.ZERO));
}
@Test
@@ -76,7 +76,7 @@ public class RecordAccumulatorTest {
builder.build();
ImmutableSet<ComparableEntity> entities =
new RecordAccumulator().readDirectory(subdir).getComparableEntitySet();
new RecordAccumulator().readDirectory(subdir, any -> true).getComparableEntitySet();
assertThat(entities).containsExactly(e1, e2, e3);
}
}
@@ -25,17 +25,21 @@ import static google.registry.testing.DatastoreHelper.persistResource;
import static google.registry.testing.SqlHelper.getMostRecentRegistryLockByRepoId;
import static google.registry.tools.LockOrUnlockDomainCommand.REGISTRY_LOCK_STATUSES;
import static org.junit.Assert.assertThrows;
import static org.mockito.Mockito.mock;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import google.registry.batch.AsyncTaskEnqueuerTest;
import google.registry.model.domain.DomainBase;
import google.registry.model.registrar.Registrar.Type;
import google.registry.schema.domain.RegistryLock;
import google.registry.testing.DeterministicStringGenerator;
import google.registry.util.AppEngineServiceUtils;
import google.registry.util.StringGenerator.Alphabets;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import org.joda.time.Duration;
import org.junit.Before;
import org.junit.Test;
@@ -48,7 +52,10 @@ public class UnlockDomainCommandTest extends CommandTestCase<UnlockDomainCommand
createTld("tld");
command.registryAdminClientId = "adminreg";
command.domainLockUtils =
new DomainLockUtils(new DeterministicStringGenerator(Alphabets.BASE_58));
new DomainLockUtils(
new DeterministicStringGenerator(Alphabets.BASE_58),
AsyncTaskEnqueuerTest.createForTesting(
mock(AppEngineServiceUtils.class), fakeClock, Duration.ZERO));
}
private DomainBase persistLockedDomain(String domainName, String registrarId) {
@@ -26,12 +26,18 @@ import com.google.common.collect.ImmutableMap;
import google.registry.model.registry.label.ReservedList;
import google.registry.schema.tld.ReservedList.ReservedEntry;
import google.registry.schema.tld.ReservedListDao;
import org.junit.Before;
import org.junit.Test;
/** Unit tests for {@link UpdateReservedListCommand}. */
public class UpdateReservedListCommandTest extends
CreateOrUpdateReservedListCommandTestCase<UpdateReservedListCommand> {
@Before
public void setup() {
populateInitialReservedListInDatastore(true);
}
private void populateInitialReservedListInDatastore(boolean shouldPublish) {
persistResource(
new ReservedList.Builder()
@@ -63,7 +69,6 @@ public class UpdateReservedListCommandTest extends
@Test
public void testSuccess_lastUpdateTime_updatedCorrectly() throws Exception {
populateInitialReservedListInDatastore(true);
ReservedList original = ReservedList.get("xn--q9jyb4c_common-reserved").get();
runCommandForced("--input=" + reservedTermsPath);
ReservedList updated = ReservedList.get("xn--q9jyb4c_common-reserved").get();
@@ -90,7 +95,6 @@ public class UpdateReservedListCommandTest extends
}
private void runSuccessfulUpdateTest(String... args) throws Exception {
populateInitialReservedListInDatastore(true);
runCommandForced(args);
assertThat(ReservedList.get("xn--q9jyb4c_common-reserved")).isPresent();
ReservedList reservedList = ReservedList.get("xn--q9jyb4c_common-reserved").get();
@@ -114,7 +118,6 @@ public class UpdateReservedListCommandTest extends
@Test
public void testSaveToCloudSql_succeeds() throws Exception {
populateInitialReservedListInDatastore(true);
populateInitialReservedListInCloudSql(true);
runCommandForced("--name=xn--q9jyb4c_common-reserved", "--input=" + reservedTermsPath);
verifyXnq9jyb4cInDatastore();
@@ -126,7 +129,6 @@ public class UpdateReservedListCommandTest extends
// Note that, during the dual-write phase, we always save the reserved list to Cloud SQL without
// checking if there is a list with same name. This is to backfill the existing list in Cloud
// Datastore when we update it.
populateInitialReservedListInDatastore(true);
runCommandForced("--name=xn--q9jyb4c_common-reserved", "--input=" + reservedTermsPath);
verifyXnq9jyb4cInDatastore();
assertThat(ReservedListDao.checkExists("xn--q9jyb4c_common-reserved")).isTrue();
@@ -25,6 +25,7 @@ import static google.registry.testing.SqlHelper.getRegistryLockByVerificationCod
import static google.registry.testing.SqlHelper.saveRegistryLock;
import static google.registry.tools.LockOrUnlockDomainCommand.REGISTRY_LOCK_STATUSES;
import static google.registry.ui.server.registrar.RegistryLockGetActionTest.userFromRegistrarContact;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -32,6 +33,7 @@ import com.google.appengine.api.users.User;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSetMultimap;
import google.registry.batch.AsyncTaskEnqueuerTest;
import google.registry.model.domain.DomainBase;
import google.registry.request.JsonActionRunner;
import google.registry.request.JsonResponse;
@@ -46,6 +48,7 @@ import google.registry.testing.AppEngineRule;
import google.registry.testing.DeterministicStringGenerator;
import google.registry.testing.FakeClock;
import google.registry.tools.DomainLockUtils;
import google.registry.util.AppEngineServiceUtils;
import google.registry.util.EmailMessage;
import google.registry.util.SendEmailService;
import google.registry.util.StringGenerator.Alphabets;
@@ -424,7 +427,10 @@ public final class RegistryLockPostActionTest {
JsonActionRunner jsonActionRunner =
new JsonActionRunner(ImmutableMap.of(), new JsonResponse(new ResponseImpl(mockResponse)));
DomainLockUtils domainLockUtils =
new DomainLockUtils(new DeterministicStringGenerator(Alphabets.BASE_58));
new DomainLockUtils(
new DeterministicStringGenerator(Alphabets.BASE_58),
AsyncTaskEnqueuerTest.createForTesting(
mock(AppEngineServiceUtils.class), clock, Duration.ZERO));
return new RegistryLockPostAction(
jsonActionRunner,
authResult,
@@ -33,6 +33,7 @@ import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.common.collect.ImmutableMap;
import google.registry.batch.AsyncTaskEnqueuerTest;
import google.registry.model.billing.BillingEvent;
import google.registry.model.billing.BillingEvent.Reason;
import google.registry.model.domain.DomainBase;
@@ -51,6 +52,7 @@ import google.registry.testing.FakeClock;
import google.registry.testing.FakeResponse;
import google.registry.testing.UserInfo;
import google.registry.tools.DomainLockUtils;
import google.registry.util.AppEngineServiceUtils;
import google.registry.util.StringGenerator;
import google.registry.util.StringGenerator.Alphabets;
import javax.servlet.http.HttpServletRequest;
@@ -328,7 +330,12 @@ public final class RegistryLockVerifyActionTest {
response = new FakeResponse();
RegistryLockVerifyAction action =
new RegistryLockVerifyAction(
new DomainLockUtils(stringGenerator), lockVerificationCode, isLock);
new DomainLockUtils(
stringGenerator,
AsyncTaskEnqueuerTest.createForTesting(
mock(AppEngineServiceUtils.class), fakeClock, Duration.ZERO)),
lockVerificationCode,
isLock);
authResult = AuthResult.create(AuthLevel.USER, UserAuthInfo.create(user, false));
action.req = request;
action.response = response;
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<epp xmlns="urn:ietf:params:xml:ns:epp-1.0">
<command>
<check>
<domain:check xmlns:domain="urn:ietf:params:xml:ns:domain-1.0">
<domain:name>example.tld</domain:name>
</domain:check>
</check>
<extension>
<fee:check xmlns:fee="urn:ietf:params:xml:ns:fee-0.6">
<fee:domain>
<fee:name>example.tld</fee:name>
<fee:command>create</fee:command>
<fee:period unit="y">1</fee:period>
</fee:domain>
</fee:check>
<allocationToken:allocationToken
xmlns:allocationToken="urn:ietf:params:xml:ns:allocationToken-1.0">
abc123
</allocationToken:allocationToken>
</extension>
<clTRID>RegistryTool</clTRID>
</command>
</epp>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 57 KiB

@@ -26,12 +26,12 @@ org.checkerframework:checker-qual:2.10.0
org.flywaydb:flyway-core:5.2.4
org.hamcrest:hamcrest-core:1.3
org.jetbrains:annotations:17.0.0
org.junit.jupiter:junit-jupiter-api:5.6.0
org.junit.jupiter:junit-jupiter-engine:5.6.0
org.junit.platform:junit-platform-commons:1.6.0
org.junit.platform:junit-platform-engine:1.6.0
org.junit.vintage:junit-vintage-engine:5.6.0
org.junit:junit-bom:5.6.0
org.junit.jupiter:junit-jupiter-api:5.6.1
org.junit.jupiter:junit-jupiter-engine:5.6.1
org.junit.platform:junit-platform-commons:1.6.1
org.junit.platform:junit-platform-engine:1.6.1
org.junit.vintage:junit-vintage-engine:5.6.1
org.junit:junit-bom:5.6.1
org.opentest4j:opentest4j:1.2.0
org.rnorth.duct-tape:duct-tape:1.0.8
org.rnorth.visible-assertions:visible-assertions:2.1.2
@@ -26,12 +26,12 @@ org.checkerframework:checker-qual:2.10.0
org.flywaydb:flyway-core:5.2.4
org.hamcrest:hamcrest-core:1.3
org.jetbrains:annotations:17.0.0
org.junit.jupiter:junit-jupiter-api:5.6.0
org.junit.jupiter:junit-jupiter-engine:5.6.0
org.junit.platform:junit-platform-commons:1.6.0
org.junit.platform:junit-platform-engine:1.6.0
org.junit.vintage:junit-vintage-engine:5.6.0
org.junit:junit-bom:5.6.0
org.junit.jupiter:junit-jupiter-api:5.6.1
org.junit.jupiter:junit-jupiter-engine:5.6.1
org.junit.platform:junit-platform-commons:1.6.1
org.junit.platform:junit-platform-engine:1.6.1
org.junit.vintage:junit-vintage-engine:5.6.1
org.junit:junit-bom:5.6.1
org.opentest4j:opentest4j:1.2.0
org.rnorth.duct-tape:duct-tape:1.0.8
org.rnorth.visible-assertions:visible-assertions:2.1.2
@@ -29,12 +29,12 @@ org.eclipse.jgit:org.eclipse.jgit:4.4.1.201607150455-r
org.flywaydb:flyway-core:5.2.4
org.hamcrest:hamcrest-core:1.3
org.jetbrains:annotations:17.0.0
org.junit.jupiter:junit-jupiter-api:5.6.0
org.junit.jupiter:junit-jupiter-engine:5.6.0
org.junit.platform:junit-platform-commons:1.6.0
org.junit.platform:junit-platform-engine:1.6.0
org.junit.vintage:junit-vintage-engine:5.6.0
org.junit:junit-bom:5.6.0
org.junit.jupiter:junit-jupiter-api:5.6.1
org.junit.jupiter:junit-jupiter-engine:5.6.1
org.junit.platform:junit-platform-commons:1.6.1
org.junit.platform:junit-platform-engine:1.6.1
org.junit.vintage:junit-vintage-engine:5.6.1
org.junit:junit-bom:5.6.1
org.opentest4j:opentest4j:1.2.0
org.rnorth.duct-tape:duct-tape:1.0.8
org.rnorth.visible-assertions:visible-assertions:2.1.2
@@ -49,12 +49,12 @@ org.eclipse.jgit:org.eclipse.jgit:4.4.1.201607150455-r
org.flywaydb:flyway-core:5.2.4
org.hamcrest:hamcrest-core:1.3
org.jetbrains:annotations:17.0.0
org.junit.jupiter:junit-jupiter-api:5.6.0
org.junit.jupiter:junit-jupiter-engine:5.6.0
org.junit.platform:junit-platform-commons:1.6.0
org.junit.platform:junit-platform-engine:1.6.0
org.junit.vintage:junit-vintage-engine:5.6.0
org.junit:junit-bom:5.6.0
org.junit.jupiter:junit-jupiter-api:5.6.1
org.junit.jupiter:junit-jupiter-engine:5.6.1
org.junit.platform:junit-platform-commons:1.6.1
org.junit.platform:junit-platform-engine:1.6.1
org.junit.vintage:junit-vintage-engine:5.6.1
org.junit:junit-bom:5.6.1
org.opentest4j:opentest4j:1.2.0
org.ow2.asm:asm-analysis:7.0
org.ow2.asm:asm-commons:5.0.3
+18 -11
View File
@@ -19,7 +19,9 @@ ext {
'args4j:args4j:2.0.26',
'com.beust:jcommander:1.60',
'com.google.api-client:google-api-client-java6:1.27.0',
'com.google.api-client:google-api-client:1.29.2',
'com.google.api-client:google-api-client:1.30.8',
'com.google.api-client:google-api-client-appengine:1.30.8',
'com.google.api-client:google-api-client-servlet:1.30.8',
'com.google.apis:google-api-services-admin-directory:directory_v1-rev72-1.22.0',
'com.google.apis:google-api-services-appengine:v1-rev101-1.25.0',
'com.google.apis:google-api-services-bigquery:v2-rev325-1.22.0',
@@ -57,16 +59,18 @@ ext {
'com.google.guava:guava-testlib:28.2-jre',
'com.google.guava:guava:28.2-jre',
'com.google.gwt:gwt-user:2.8.2',
'com.google.http-client:google-http-client-appengine:1.29.2',
'com.google.http-client:google-http-client-jackson2:1.29.2',
'com.google.http-client:google-http-client:1.29.2',
'com.google.http-client:google-http-client-appengine:1.34.1',
'com.google.http-client:google-http-client-jackson2:1.34.1',
'com.google.http-client:google-http-client:1.34.1',
'com.google.javascript:closure-compiler:v20190301',
'com.google.monitoring-client:contrib:1.0.7',
'com.google.monitoring-client:metrics:1.0.7',
'com.google.monitoring-client:stackdriver:1.0.7',
'com.google.oauth-client:google-oauth-client:1.30.5',
'com.google.oauth-client:google-oauth-client-appengine:1.30.5',
'com.google.oauth-client:google-oauth-client-java6:1.27.0',
'com.google.oauth-client:google-oauth-client-jetty:1.28.0',
'com.google.oauth-client:google-oauth-client:1.29.2',
'com.google.oauth-client:google-oauth-client-servlet:1.30.5',
'com.google.re2j:re2j:1.1',
'com.google.template:soy:2018-03-14',
'com.google.truth.extensions:truth-java8-extension:1.0',
@@ -99,10 +103,12 @@ ext {
'jline:jline:1.0',
'joda-time:joda-time:2.9.2',
'junit:junit:4.13',
'org.junit.jupiter:junit-jupiter-api:5.6.0',
'org.junit.jupiter:junit-jupiter-engine:5.6.0',
'org.junit.jupiter:junit-jupiter-migrationsupport:5.6.0',
'org.junit.vintage:junit-vintage-engine:5.6.0',
'org.junit.jupiter:junit-jupiter-api:5.6.1',
'org.junit.jupiter:junit-jupiter-engine:5.6.1',
'org.junit.jupiter:junit-jupiter-migrationsupport:5.6.1',
'org.junit.platform:junit-platform-runner:1.6.1',
'org.junit.platform:junit-platform-suite-api:1.6.1',
'org.junit.vintage:junit-vintage-engine:5.6.1',
'org.apache.avro:avro:1.8.2',
'org.apache.beam:beam-runners-direct-java:2.16.0',
'org.apache.beam:beam-runners-google-cloud-dataflow-java:2.16.0',
@@ -113,8 +119,8 @@ ext {
'org.apache.commons:commons-text:1.6',
'org.apache.ftpserver:ftplet-api:1.0.6',
'org.apache.ftpserver:ftpserver-core:1.0.6',
'org.apache.httpcomponents:httpclient:4.5.2',
'org.apache.httpcomponents:httpcore:4.4.4',
'org.apache.httpcomponents:httpclient:4.5.11',
'org.apache.httpcomponents:httpcore:4.4.13',
'org.apache.sshd:sshd-core:2.0.0',
'org.apache.sshd:sshd-scp:2.0.0',
'org.apache.sshd:sshd-sftp:2.0.0',
@@ -138,6 +144,7 @@ ext {
'org.seleniumhq.selenium:selenium-chrome-driver:3.141.59',
'org.seleniumhq.selenium:selenium-java:3.141.59',
'org.seleniumhq.selenium:selenium-remote-driver:3.141.59',
'org.slf4j:slf4j-jdk14:1.7.28',
'org.testcontainers:jdbc:1.12.1',
'org.testcontainers:postgresql:1.12.1',
'org.testcontainers:selenium:1.12.1',
+1 -1
View File
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.2.2-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
+2
View File
@@ -80,6 +80,8 @@ task extractSqlIntegrationTestSuite (type: Copy) {
// TODO(weiminyu): inherit from FilteringTest (defined in :core).
task sqlIntegrationTest(type: Test) {
// Explicitly choose JUnit 4 for test suites. See :core:sqlIntegrationTest for details.
useJUnit()
testClassesDirs = files(unpackedTestDir)
classpath = configurations.testRuntime
include 'google/registry/schema/integration/SqlIntegrationTestSuite.*'
+4
View File
@@ -72,6 +72,10 @@ dependencies {
errorprone("com.google.errorprone:error_prone_core:2.3.3")
}
test {
useJUnitPlatform()
}
tasks.withType(JavaCompile).configureEach {
// The -Werror flag causes Intellij to fail on deprecated api use.
// Allow IDE user to turn off this flag by specifying a Gradle VM
@@ -1,8 +1,9 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.fasterxml.jackson.core:jackson-core:2.9.9
com.google.api-client:google-api-client:1.29.2
androidx.annotation:annotation:1.1.0
com.fasterxml.jackson.core:jackson-core:2.10.2
com.google.api-client:google-api-client:1.30.8
com.google.appengine:appengine-api-1.0-sdk:1.9.48
com.google.appengine:appengine-testing:1.9.58
com.google.auth:google-auth-library-credentials:0.16.1
@@ -16,15 +17,15 @@ com.google.flogger:flogger:0.1
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.http-client:google-http-client-jackson2:1.30.1
com.google.http-client:google-http-client:1.30.1
com.google.http-client:google-http-client-jackson2:1.34.1
com.google.http-client:google-http-client:1.34.1
com.google.j2objc:j2objc-annotations:1.3
com.google.oauth-client:google-oauth-client:1.29.2
com.google.oauth-client:google-oauth-client:1.30.5
com.google.re2j:re2j:1.1
com.ibm.icu:icu4j:57.1
commons-codec:commons-codec:1.11
commons-logging:commons-logging:1.2
io.grpc:grpc-context:1.19.0
io.grpc:grpc-context:1.22.1
io.netty:netty-buffer:4.1.31.Final
io.netty:netty-codec-http:4.1.31.Final
io.netty:netty-codec:4.1.31.Final
@@ -32,15 +33,15 @@ io.netty:netty-common:4.1.31.Final
io.netty:netty-handler:4.1.31.Final
io.netty:netty-resolver:4.1.31.Final
io.netty:netty-transport:4.1.31.Final
io.opencensus:opencensus-api:0.21.0
io.opencensus:opencensus-contrib-http-util:0.21.0
io.opencensus:opencensus-api:0.24.0
io.opencensus:opencensus-contrib-http-util:0.24.0
javax.activation:activation:1.1
javax.inject:javax.inject:1
javax.mail:mail:1.4
javax.xml.bind:jaxb-api:2.3.0
joda-time:joda-time:2.9.2
org.apache.httpcomponents:httpclient:4.5.8
org.apache.httpcomponents:httpcore:4.4.11
org.apache.httpcomponents:httpclient:4.5.11
org.apache.httpcomponents:httpcore:4.4.13
org.bouncycastle:bcpkix-jdk15on:1.61
org.bouncycastle:bcprov-jdk15on:1.61
org.checkerframework:checker-qual:2.10.0
@@ -1,8 +1,9 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.fasterxml.jackson.core:jackson-core:2.9.9
com.google.api-client:google-api-client:1.29.2
androidx.annotation:annotation:1.1.0
com.fasterxml.jackson.core:jackson-core:2.10.2
com.google.api-client:google-api-client:1.30.8
com.google.appengine:appengine-api-1.0-sdk:1.9.48
com.google.appengine:appengine-testing:1.9.58
com.google.auth:google-auth-library-credentials:0.16.1
@@ -16,15 +17,15 @@ com.google.flogger:flogger:0.1
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.http-client:google-http-client-jackson2:1.30.1
com.google.http-client:google-http-client:1.30.1
com.google.http-client:google-http-client-jackson2:1.34.1
com.google.http-client:google-http-client:1.34.1
com.google.j2objc:j2objc-annotations:1.3
com.google.oauth-client:google-oauth-client:1.29.2
com.google.oauth-client:google-oauth-client:1.30.5
com.google.re2j:re2j:1.1
com.ibm.icu:icu4j:57.1
commons-codec:commons-codec:1.11
commons-logging:commons-logging:1.2
io.grpc:grpc-context:1.19.0
io.grpc:grpc-context:1.22.1
io.netty:netty-buffer:4.1.31.Final
io.netty:netty-codec-http:4.1.31.Final
io.netty:netty-codec:4.1.31.Final
@@ -32,15 +33,15 @@ io.netty:netty-common:4.1.31.Final
io.netty:netty-handler:4.1.31.Final
io.netty:netty-resolver:4.1.31.Final
io.netty:netty-transport:4.1.31.Final
io.opencensus:opencensus-api:0.21.0
io.opencensus:opencensus-contrib-http-util:0.21.0
io.opencensus:opencensus-api:0.24.0
io.opencensus:opencensus-contrib-http-util:0.24.0
javax.activation:activation:1.1
javax.inject:javax.inject:1
javax.mail:mail:1.4
javax.xml.bind:jaxb-api:2.3.0
joda-time:joda-time:2.9.2
org.apache.httpcomponents:httpclient:4.5.8
org.apache.httpcomponents:httpcore:4.4.11
org.apache.httpcomponents:httpclient:4.5.11
org.apache.httpcomponents:httpcore:4.4.13
org.bouncycastle:bcpkix-jdk15on:1.61
org.bouncycastle:bcprov-jdk15on:1.61
org.checkerframework:checker-qual:2.10.0
@@ -1,8 +1,9 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.fasterxml.jackson.core:jackson-core:2.9.9
com.google.api-client:google-api-client:1.29.2
androidx.annotation:annotation:1.1.0
com.fasterxml.jackson.core:jackson-core:2.10.2
com.google.api-client:google-api-client:1.30.8
com.google.appengine:appengine-api-1.0-sdk:1.9.48
com.google.appengine:appengine-testing:1.9.58
com.google.auth:google-auth-library-credentials:0.16.1
@@ -17,15 +18,15 @@ com.google.flogger:flogger:0.1
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.http-client:google-http-client-jackson2:1.30.1
com.google.http-client:google-http-client:1.30.1
com.google.http-client:google-http-client-jackson2:1.34.1
com.google.http-client:google-http-client:1.34.1
com.google.j2objc:j2objc-annotations:1.3
com.google.oauth-client:google-oauth-client:1.29.2
com.google.oauth-client:google-oauth-client:1.30.5
com.google.re2j:re2j:1.1
com.ibm.icu:icu4j:57.1
commons-codec:commons-codec:1.11
commons-logging:commons-logging:1.2
io.grpc:grpc-context:1.19.0
io.grpc:grpc-context:1.22.1
io.netty:netty-buffer:4.1.31.Final
io.netty:netty-codec-http:4.1.31.Final
io.netty:netty-codec:4.1.31.Final
@@ -34,15 +35,15 @@ io.netty:netty-handler:4.1.31.Final
io.netty:netty-resolver:4.1.31.Final
io.netty:netty-tcnative-boringssl-static:2.0.22.Final
io.netty:netty-transport:4.1.31.Final
io.opencensus:opencensus-api:0.21.0
io.opencensus:opencensus-contrib-http-util:0.21.0
io.opencensus:opencensus-api:0.24.0
io.opencensus:opencensus-contrib-http-util:0.24.0
javax.activation:activation:1.1
javax.inject:javax.inject:1
javax.mail:mail:1.4
javax.xml.bind:jaxb-api:2.3.0
joda-time:joda-time:2.9.2
org.apache.httpcomponents:httpclient:4.5.8
org.apache.httpcomponents:httpcore:4.4.11
org.apache.httpcomponents:httpclient:4.5.11
org.apache.httpcomponents:httpcore:4.4.13
org.bouncycastle:bcpkix-jdk15on:1.61
org.bouncycastle:bcprov-jdk15on:1.61
org.checkerframework:checker-qual:2.10.0
@@ -1,8 +1,9 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.fasterxml.jackson.core:jackson-core:2.9.9
com.google.api-client:google-api-client:1.29.2
androidx.annotation:annotation:1.1.0
com.fasterxml.jackson.core:jackson-core:2.10.2
com.google.api-client:google-api-client:1.30.8
com.google.appengine:appengine-api-1.0-sdk:1.9.48
com.google.appengine:appengine-testing:1.9.58
com.google.auth:google-auth-library-credentials:0.16.1
@@ -17,15 +18,15 @@ com.google.flogger:flogger:0.1
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.http-client:google-http-client-jackson2:1.30.1
com.google.http-client:google-http-client:1.30.1
com.google.http-client:google-http-client-jackson2:1.34.1
com.google.http-client:google-http-client:1.34.1
com.google.j2objc:j2objc-annotations:1.3
com.google.oauth-client:google-oauth-client:1.29.2
com.google.oauth-client:google-oauth-client:1.30.5
com.google.re2j:re2j:1.1
com.ibm.icu:icu4j:57.1
commons-codec:commons-codec:1.11
commons-logging:commons-logging:1.2
io.grpc:grpc-context:1.19.0
io.grpc:grpc-context:1.22.1
io.netty:netty-buffer:4.1.31.Final
io.netty:netty-codec-http:4.1.31.Final
io.netty:netty-codec:4.1.31.Final
@@ -34,15 +35,15 @@ io.netty:netty-handler:4.1.31.Final
io.netty:netty-resolver:4.1.31.Final
io.netty:netty-tcnative-boringssl-static:2.0.22.Final
io.netty:netty-transport:4.1.31.Final
io.opencensus:opencensus-api:0.21.0
io.opencensus:opencensus-contrib-http-util:0.21.0
io.opencensus:opencensus-api:0.24.0
io.opencensus:opencensus-contrib-http-util:0.24.0
javax.activation:activation:1.1
javax.inject:javax.inject:1
javax.mail:mail:1.4
javax.xml.bind:jaxb-api:2.3.0
joda-time:joda-time:2.9.2
org.apache.httpcomponents:httpclient:4.5.8
org.apache.httpcomponents:httpcore:4.4.11
org.apache.httpcomponents:httpclient:4.5.11
org.apache.httpcomponents:httpcore:4.4.13
org.bouncycastle:bcpkix-jdk15on:1.61
org.bouncycastle:bcprov-jdk15on:1.61
org.checkerframework:checker-qual:2.10.0
@@ -1,8 +1,9 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.fasterxml.jackson.core:jackson-core:2.9.9
com.google.api-client:google-api-client:1.29.2
androidx.annotation:annotation:1.1.0
com.fasterxml.jackson.core:jackson-core:2.10.2
com.google.api-client:google-api-client:1.30.8
com.google.appengine:appengine-api-1.0-sdk:1.9.48
com.google.appengine:appengine-testing:1.9.58
com.google.auth:google-auth-library-credentials:0.16.1
@@ -17,15 +18,15 @@ com.google.flogger:flogger:0.1
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.http-client:google-http-client-jackson2:1.30.1
com.google.http-client:google-http-client:1.30.1
com.google.http-client:google-http-client-jackson2:1.34.1
com.google.http-client:google-http-client:1.34.1
com.google.j2objc:j2objc-annotations:1.3
com.google.oauth-client:google-oauth-client:1.29.2
com.google.oauth-client:google-oauth-client:1.30.5
com.google.re2j:re2j:1.1
com.ibm.icu:icu4j:57.1
commons-codec:commons-codec:1.11
commons-logging:commons-logging:1.2
io.grpc:grpc-context:1.19.0
io.grpc:grpc-context:1.22.1
io.netty:netty-buffer:4.1.31.Final
io.netty:netty-codec-http:4.1.31.Final
io.netty:netty-codec:4.1.31.Final
@@ -34,15 +35,15 @@ io.netty:netty-handler:4.1.31.Final
io.netty:netty-resolver:4.1.31.Final
io.netty:netty-tcnative-boringssl-static:2.0.22.Final
io.netty:netty-transport:4.1.31.Final
io.opencensus:opencensus-api:0.21.0
io.opencensus:opencensus-contrib-http-util:0.21.0
io.opencensus:opencensus-api:0.24.0
io.opencensus:opencensus-contrib-http-util:0.24.0
javax.activation:activation:1.1
javax.inject:javax.inject:1
javax.mail:mail:1.4
javax.xml.bind:jaxb-api:2.3.0
joda-time:joda-time:2.9.2
org.apache.httpcomponents:httpclient:4.5.8
org.apache.httpcomponents:httpcore:4.4.11
org.apache.httpcomponents:httpclient:4.5.11
org.apache.httpcomponents:httpcore:4.4.13
org.bouncycastle:bcpkix-jdk15on:1.61
org.bouncycastle:bcprov-jdk15on:1.61
org.checkerframework:checker-qual:2.10.0
@@ -1,8 +1,9 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.fasterxml.jackson.core:jackson-core:2.9.9
com.google.api-client:google-api-client:1.29.2
androidx.annotation:annotation:1.1.0
com.fasterxml.jackson.core:jackson-core:2.10.2
com.google.api-client:google-api-client:1.30.8
com.google.appengine:appengine-api-1.0-sdk:1.9.48
com.google.appengine:appengine-testing:1.9.58
com.google.auth:google-auth-library-credentials:0.16.1
@@ -17,15 +18,15 @@ com.google.flogger:flogger:0.1
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.http-client:google-http-client-jackson2:1.30.1
com.google.http-client:google-http-client:1.30.1
com.google.http-client:google-http-client-jackson2:1.34.1
com.google.http-client:google-http-client:1.34.1
com.google.j2objc:j2objc-annotations:1.3
com.google.oauth-client:google-oauth-client:1.29.2
com.google.oauth-client:google-oauth-client:1.30.5
com.google.re2j:re2j:1.1
com.ibm.icu:icu4j:57.1
commons-codec:commons-codec:1.11
commons-logging:commons-logging:1.2
io.grpc:grpc-context:1.19.0
io.grpc:grpc-context:1.22.1
io.netty:netty-buffer:4.1.31.Final
io.netty:netty-codec-http:4.1.31.Final
io.netty:netty-codec:4.1.31.Final
@@ -34,15 +35,15 @@ io.netty:netty-handler:4.1.31.Final
io.netty:netty-resolver:4.1.31.Final
io.netty:netty-tcnative-boringssl-static:2.0.22.Final
io.netty:netty-transport:4.1.31.Final
io.opencensus:opencensus-api:0.21.0
io.opencensus:opencensus-contrib-http-util:0.21.0
io.opencensus:opencensus-api:0.24.0
io.opencensus:opencensus-contrib-http-util:0.24.0
javax.activation:activation:1.1
javax.inject:javax.inject:1
javax.mail:mail:1.4
javax.xml.bind:jaxb-api:2.3.0
joda-time:joda-time:2.9.2
org.apache.httpcomponents:httpclient:4.5.8
org.apache.httpcomponents:httpcore:4.4.11
org.apache.httpcomponents:httpclient:4.5.11
org.apache.httpcomponents:httpcore:4.4.13
org.bouncycastle:bcpkix-jdk15on:1.61
org.bouncycastle:bcprov-jdk15on:1.61
org.checkerframework:checker-qual:2.10.0
@@ -1,8 +1,9 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.fasterxml.jackson.core:jackson-core:2.9.9
com.google.api-client:google-api-client:1.29.2
androidx.annotation:annotation:1.1.0
com.fasterxml.jackson.core:jackson-core:2.10.2
com.google.api-client:google-api-client:1.30.8
com.google.appengine:appengine-api-1.0-sdk:1.9.48
com.google.appengine:appengine-testing:1.9.58
com.google.auth:google-auth-library-credentials:0.16.1
@@ -16,17 +17,17 @@ com.google.flogger:flogger:0.1
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.http-client:google-http-client-jackson2:1.30.1
com.google.http-client:google-http-client:1.30.1
com.google.http-client:google-http-client-jackson2:1.34.1
com.google.http-client:google-http-client:1.34.1
com.google.j2objc:j2objc-annotations:1.3
com.google.oauth-client:google-oauth-client:1.29.2
com.google.oauth-client:google-oauth-client:1.30.5
com.google.re2j:re2j:1.1
com.google.truth:truth:1.0
com.googlecode.java-diff-utils:diffutils:1.3.0
com.ibm.icu:icu4j:57.1
commons-codec:commons-codec:1.11
commons-logging:commons-logging:1.2
io.grpc:grpc-context:1.19.0
io.grpc:grpc-context:1.22.1
io.netty:netty-buffer:4.1.31.Final
io.netty:netty-codec-http:4.1.31.Final
io.netty:netty-codec:4.1.31.Final
@@ -34,27 +35,27 @@ io.netty:netty-common:4.1.31.Final
io.netty:netty-handler:4.1.31.Final
io.netty:netty-resolver:4.1.31.Final
io.netty:netty-transport:4.1.31.Final
io.opencensus:opencensus-api:0.21.0
io.opencensus:opencensus-contrib-http-util:0.21.0
io.opencensus:opencensus-api:0.24.0
io.opencensus:opencensus-contrib-http-util:0.24.0
javax.activation:activation:1.1
javax.inject:javax.inject:1
javax.mail:mail:1.4
javax.xml.bind:jaxb-api:2.3.0
joda-time:joda-time:2.9.2
junit:junit:4.13
org.apache.httpcomponents:httpclient:4.5.8
org.apache.httpcomponents:httpcore:4.4.11
org.apache.httpcomponents:httpclient:4.5.11
org.apache.httpcomponents:httpcore:4.4.13
org.apiguardian:apiguardian-api:1.1.0
org.bouncycastle:bcpkix-jdk15on:1.61
org.bouncycastle:bcprov-jdk15on:1.61
org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:2.10.0
org.hamcrest:hamcrest-core:1.3
org.junit.jupiter:junit-jupiter-api:5.6.0
org.junit.jupiter:junit-jupiter-engine:5.6.0
org.junit.platform:junit-platform-commons:1.6.0
org.junit.platform:junit-platform-engine:1.6.0
org.junit.vintage:junit-vintage-engine:5.6.0
org.junit:junit-bom:5.6.0
org.junit.jupiter:junit-jupiter-api:5.6.1
org.junit.jupiter:junit-jupiter-engine:5.6.1
org.junit.platform:junit-platform-commons:1.6.1
org.junit.platform:junit-platform-engine:1.6.1
org.junit.vintage:junit-vintage-engine:5.6.1
org.junit:junit-bom:5.6.1
org.opentest4j:opentest4j:1.2.0
org.yaml:snakeyaml:1.17
@@ -1,8 +1,9 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.fasterxml.jackson.core:jackson-core:2.9.9
com.google.api-client:google-api-client:1.29.2
androidx.annotation:annotation:1.1.0
com.fasterxml.jackson.core:jackson-core:2.10.2
com.google.api-client:google-api-client:1.30.8
com.google.appengine:appengine-api-1.0-sdk:1.9.48
com.google.appengine:appengine-testing:1.9.58
com.google.auth:google-auth-library-credentials:0.16.1
@@ -16,17 +17,17 @@ com.google.flogger:flogger:0.1
com.google.guava:failureaccess:1.0.1
com.google.guava:guava:28.2-jre
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava
com.google.http-client:google-http-client-jackson2:1.30.1
com.google.http-client:google-http-client:1.30.1
com.google.http-client:google-http-client-jackson2:1.34.1
com.google.http-client:google-http-client:1.34.1
com.google.j2objc:j2objc-annotations:1.3
com.google.oauth-client:google-oauth-client:1.29.2
com.google.oauth-client:google-oauth-client:1.30.5
com.google.re2j:re2j:1.1
com.google.truth:truth:1.0
com.googlecode.java-diff-utils:diffutils:1.3.0
com.ibm.icu:icu4j:57.1
commons-codec:commons-codec:1.11
commons-logging:commons-logging:1.2
io.grpc:grpc-context:1.19.0
io.grpc:grpc-context:1.22.1
io.netty:netty-buffer:4.1.31.Final
io.netty:netty-codec-http:4.1.31.Final
io.netty:netty-codec:4.1.31.Final
@@ -34,27 +35,27 @@ io.netty:netty-common:4.1.31.Final
io.netty:netty-handler:4.1.31.Final
io.netty:netty-resolver:4.1.31.Final
io.netty:netty-transport:4.1.31.Final
io.opencensus:opencensus-api:0.21.0
io.opencensus:opencensus-contrib-http-util:0.21.0
io.opencensus:opencensus-api:0.24.0
io.opencensus:opencensus-contrib-http-util:0.24.0
javax.activation:activation:1.1
javax.inject:javax.inject:1
javax.mail:mail:1.4
javax.xml.bind:jaxb-api:2.3.0
joda-time:joda-time:2.9.2
junit:junit:4.13
org.apache.httpcomponents:httpclient:4.5.8
org.apache.httpcomponents:httpcore:4.4.11
org.apache.httpcomponents:httpclient:4.5.11
org.apache.httpcomponents:httpcore:4.4.13
org.apiguardian:apiguardian-api:1.1.0
org.bouncycastle:bcpkix-jdk15on:1.61
org.bouncycastle:bcprov-jdk15on:1.61
org.checkerframework:checker-compat-qual:2.5.5
org.checkerframework:checker-qual:2.10.0
org.hamcrest:hamcrest-core:1.3
org.junit.jupiter:junit-jupiter-api:5.6.0
org.junit.jupiter:junit-jupiter-engine:5.6.0
org.junit.platform:junit-platform-commons:1.6.0
org.junit.platform:junit-platform-engine:1.6.0
org.junit.vintage:junit-vintage-engine:5.6.0
org.junit:junit-bom:5.6.0
org.junit.jupiter:junit-jupiter-api:5.6.1
org.junit.jupiter:junit-jupiter-engine:5.6.1
org.junit.platform:junit-platform-commons:1.6.1
org.junit.platform:junit-platform-engine:1.6.1
org.junit.vintage:junit-vintage-engine:5.6.1
org.junit:junit-bom:5.6.1
org.opentest4j:opentest4j:1.2.0
org.yaml:snakeyaml:1.17

Some files were not shown because too many files have changed in this diff Show More