diff --git a/core/src/test/java/google/registry/flows/contact/ContactUpdateFlowTest.java b/core/src/test/java/google/registry/flows/contact/ContactUpdateFlowTest.java index b86a4d067..c16d19e8c 100644 --- a/core/src/test/java/google/registry/flows/contact/ContactUpdateFlowTest.java +++ b/core/src/test/java/google/registry/flows/contact/ContactUpdateFlowTest.java @@ -42,12 +42,19 @@ import google.registry.model.contact.PostalInfo; import google.registry.model.contact.PostalInfo.Type; import google.registry.model.eppcommon.StatusValue; import google.registry.testing.DualDatabaseTest; +import google.registry.testing.ReplayExtension; import google.registry.testing.TestOfyAndSql; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.extension.RegisterExtension; /** Unit tests for {@link ContactUpdateFlow}. */ @DualDatabaseTest class ContactUpdateFlowTest extends ResourceFlowTestCase { + @Order(value = Order.DEFAULT - 2) + @RegisterExtension + final ReplayExtension replayExtension = ReplayExtension.createWithCompare(clock); + ContactUpdateFlowTest() { setEppInput("contact_update.xml"); } diff --git a/core/src/test/java/google/registry/flows/domain/DomainCheckFlowTest.java b/core/src/test/java/google/registry/flows/domain/DomainCheckFlowTest.java index 18fbccfab..a481aa21e 100644 --- a/core/src/test/java/google/registry/flows/domain/DomainCheckFlowTest.java +++ b/core/src/test/java/google/registry/flows/domain/DomainCheckFlowTest.java @@ -72,6 +72,7 @@ import google.registry.model.registry.Registry.TldState; import google.registry.model.registry.label.ReservedList; import google.registry.model.reporting.HistoryEntry; import google.registry.testing.ReplayExtension; +import google.registry.testing.SetClockExtension; import org.joda.money.CurrencyUnit; import org.joda.money.Money; import org.joda.time.DateTime; @@ -79,8 +80,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.BeforeEachCallback; -import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.RegisterExtension; /** Unit tests for {@link DomainCheckFlow}. */ @@ -88,7 +87,7 @@ class DomainCheckFlowTest extends ResourceCheckFlowTestCaseThis has to happen first, we'll get timestamp inversions if we try to set the clock after - * these objects are created. - */ - class SetClockExtension implements BeforeEachCallback { - @Override - public void beforeEach(ExtensionContext context) { - // we have to go far enough back before the expiration time so that the clock advances we do - // after each persist don't move us into a grace period. The current value is likely beyond - // what is necessary, but this doesn't hurt. - clock.setTo(expirationTime.minusMillis(20)); - } - } } diff --git a/core/src/test/java/google/registry/flows/host/HostCreateFlowTest.java b/core/src/test/java/google/registry/flows/host/HostCreateFlowTest.java index 1e1ee5bcd..1434caed2 100644 --- a/core/src/test/java/google/registry/flows/host/HostCreateFlowTest.java +++ b/core/src/test/java/google/registry/flows/host/HostCreateFlowTest.java @@ -55,13 +55,20 @@ import google.registry.model.eppcommon.StatusValue; import google.registry.model.host.HostResource; import google.registry.model.reporting.HistoryEntry; import google.registry.testing.DualDatabaseTest; +import google.registry.testing.ReplayExtension; import google.registry.testing.TestOfyAndSql; import org.joda.time.DateTime; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.extension.RegisterExtension; /** Unit tests for {@link HostCreateFlow}. */ @DualDatabaseTest class HostCreateFlowTest extends ResourceFlowTestCase { + @Order(value = Order.DEFAULT - 2) + @RegisterExtension + final ReplayExtension replayExtension = ReplayExtension.createWithCompare(clock); + private void setEppHostCreateInput(String hostName, String hostAddrs) { setEppInput( "host_create.xml", diff --git a/core/src/test/java/google/registry/flows/host/HostDeleteFlowTest.java b/core/src/test/java/google/registry/flows/host/HostDeleteFlowTest.java index afe5ed7a2..dbb6db1c0 100644 --- a/core/src/test/java/google/registry/flows/host/HostDeleteFlowTest.java +++ b/core/src/test/java/google/registry/flows/host/HostDeleteFlowTest.java @@ -47,14 +47,21 @@ import google.registry.model.reporting.HistoryEntry; import google.registry.model.transfer.DomainTransferData; import google.registry.model.transfer.TransferStatus; import google.registry.testing.DualDatabaseTest; +import google.registry.testing.ReplayExtension; import google.registry.testing.TestOfyAndSql; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.extension.RegisterExtension; /** Unit tests for {@link HostDeleteFlow}. */ @DualDatabaseTest class HostDeleteFlowTest extends ResourceFlowTestCase { + @Order(value = Order.DEFAULT - 2) + @RegisterExtension + final ReplayExtension replayExtension = ReplayExtension.createWithCompare(clock); + @BeforeEach void initFlowTest() { setEppInput("host_delete.xml", ImmutableMap.of("HOSTNAME", "ns1.example.tld")); diff --git a/core/src/test/java/google/registry/flows/host/HostInfoFlowTest.java b/core/src/test/java/google/registry/flows/host/HostInfoFlowTest.java index 9fd4f45f4..739aec939 100644 --- a/core/src/test/java/google/registry/flows/host/HostInfoFlowTest.java +++ b/core/src/test/java/google/registry/flows/host/HostInfoFlowTest.java @@ -18,6 +18,7 @@ import static com.google.common.truth.Truth.assertThat; import static google.registry.testing.DatabaseHelper.assertNoBillingEvents; import static google.registry.testing.DatabaseHelper.createTld; import static google.registry.testing.DatabaseHelper.newDomainBase; +import static google.registry.testing.DatabaseHelper.persistNewRegistrar; import static google.registry.testing.DatabaseHelper.persistResource; import static google.registry.testing.EppExceptionSubject.assertAboutEppExceptions; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -34,14 +35,21 @@ import google.registry.flows.host.HostFlowUtils.HostNameNotPunyCodedException; import google.registry.model.domain.DomainBase; import google.registry.model.eppcommon.StatusValue; import google.registry.model.host.HostResource; +import google.registry.testing.ReplayExtension; import javax.annotation.Nullable; import org.joda.time.DateTime; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; /** Unit tests for {@link HostInfoFlow}. */ class HostInfoFlowTest extends ResourceFlowTestCase { + @Order(value = Order.DEFAULT - 2) + @RegisterExtension + final ReplayExtension replayExtension = ReplayExtension.createWithCompare(clock); + HostInfoFlowTest() { setEppInput("host_info.xml", ImmutableMap.of("HOSTNAME", "ns1.example.tld")); } @@ -105,6 +113,7 @@ class HostInfoFlowTest extends ResourceFlowTestCase private void runTest_superordinateDomain( DateTime domainTransferTime, @Nullable DateTime lastSuperordinateChange) throws Exception { + persistNewRegistrar("superclientid"); DomainBase domain = persistResource( newDomainBase("parent.foobar") diff --git a/core/src/test/java/google/registry/flows/host/HostUpdateFlowTest.java b/core/src/test/java/google/registry/flows/host/HostUpdateFlowTest.java index 8a81a3e04..6bda395ee 100644 --- a/core/src/test/java/google/registry/flows/host/HostUpdateFlowTest.java +++ b/core/src/test/java/google/registry/flows/host/HostUpdateFlowTest.java @@ -79,15 +79,22 @@ import google.registry.model.reporting.HistoryEntry; import google.registry.model.transfer.DomainTransferData; import google.registry.model.transfer.TransferStatus; import google.registry.testing.DualDatabaseTest; +import google.registry.testing.ReplayExtension; import google.registry.testing.TaskQueueHelper.TaskMatcher; import google.registry.testing.TestOfyAndSql; import javax.annotation.Nullable; import org.joda.time.DateTime; +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.extension.RegisterExtension; /** Unit tests for {@link HostUpdateFlow}. */ @DualDatabaseTest class HostUpdateFlowTest extends ResourceFlowTestCase { + @Order(value = Order.DEFAULT - 2) + @RegisterExtension + final ReplayExtension replayExtension = ReplayExtension.createWithCompare(clock); + private void setEppHostUpdateInput( String oldHostName, String newHostName, String ipOrStatusToAdd, String ipOrStatusToRem) { setEppInput( @@ -712,6 +719,7 @@ class HostUpdateFlowTest extends ResourceFlowTestCase { + @Order(value = Order.DEFAULT - 2) + @RegisterExtension + final ReplayExtension replayExtension = ReplayExtension.createWithCompare(clock); + /** This is the message id being sent in the ACK request. */ private static final long MESSAGE_ID = 3; diff --git a/core/src/test/java/google/registry/flows/poll/PollRequestFlowTest.java b/core/src/test/java/google/registry/flows/poll/PollRequestFlowTest.java index 2e9a5b8e6..cc9fad844 100644 --- a/core/src/test/java/google/registry/flows/poll/PollRequestFlowTest.java +++ b/core/src/test/java/google/registry/flows/poll/PollRequestFlowTest.java @@ -19,6 +19,7 @@ import static google.registry.testing.DatabaseHelper.createTld; import static google.registry.testing.DatabaseHelper.newDomainBase; import static google.registry.testing.DatabaseHelper.persistActiveContact; import static google.registry.testing.DatabaseHelper.persistActiveHost; +import static google.registry.testing.DatabaseHelper.persistNewRegistrar; import static google.registry.testing.DatabaseHelper.persistResource; import static google.registry.testing.EppExceptionSubject.assertAboutEppExceptions; import static org.junit.jupiter.api.Assertions.assertThrows; @@ -37,13 +38,24 @@ import google.registry.model.reporting.HistoryEntry; import google.registry.model.transfer.TransferResponse.ContactTransferResponse; import google.registry.model.transfer.TransferResponse.DomainTransferResponse; import google.registry.model.transfer.TransferStatus; -import org.joda.time.DateTime; +import google.registry.testing.ReplayExtension; +import google.registry.testing.SetClockExtension; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; /** Unit tests for {@link PollRequestFlow}. */ class PollRequestFlowTest extends FlowTestCase { + @Order(value = Order.DEFAULT - 3) + @RegisterExtension + final SetClockExtension setClockExtension = new SetClockExtension(clock, "2011-01-02T01:01:01Z"); + + @Order(value = Order.DEFAULT - 2) + @RegisterExtension + final ReplayExtension replayExtension = ReplayExtension.createWithCompare(clock); + private DomainBase domain; private ContactResource contact; private HostResource host; @@ -52,8 +64,8 @@ class PollRequestFlowTest extends FlowTestCase { void setUp() { setEppInput("poll.xml"); setClientIdForFlow("NewRegistrar"); - clock.setTo(DateTime.parse("2011-01-02T01:01:01Z")); createTld("example"); + persistNewRegistrar("BadRegistrar"); contact = persistActiveContact("jd1234"); domain = persistResource(newDomainBase("test.example", contact)); host = persistActiveHost("ns1.test.example"); @@ -97,7 +109,6 @@ class PollRequestFlowTest extends FlowTestCase { @Test void testSuccess_contactTransferPending() throws Exception { - clock.setTo(DateTime.parse("2000-06-13T22:00:00.0Z")); setClientIdForFlow("TheRegistrar"); persistResource( new PollMessage.OneTime.Builder() @@ -157,7 +168,7 @@ class PollRequestFlowTest extends FlowTestCase { void testSuccess_wrongRegistrar() throws Exception { persistResource( new PollMessage.OneTime.Builder() - .setClientId("different client id") + .setClientId("BadRegistrar") .setEventTime(clock.nowUtc().minusDays(1)) .setMsg("Poll message") .setParent(createHistoryEntryForEppResource(domain)) @@ -229,6 +240,7 @@ class PollRequestFlowTest extends FlowTestCase { .setParent(historyEntry) .setEventTime(clock.nowUtc().minusDays(1)) .build()); + clock.advanceOneMilli(); assertTransactionalFlow(false); runFlowAssertResponse(loadFile("poll_response_host_delete.xml")); } diff --git a/core/src/test/java/google/registry/testing/DatabaseHelper.java b/core/src/test/java/google/registry/testing/DatabaseHelper.java index feed9ca31..2102484ef 100644 --- a/core/src/test/java/google/registry/testing/DatabaseHelper.java +++ b/core/src/test/java/google/registry/testing/DatabaseHelper.java @@ -1168,7 +1168,12 @@ public class DatabaseHelper { public static HistoryEntry createHistoryEntryForEppResource( T parentResource) { - return persistResource(new HistoryEntry.Builder().setParent(parentResource).build()); + return persistResource( + new HistoryEntry.Builder() + .setType(getHistoryEntryType(parentResource)) + .setModificationTime(DateTime.now(DateTimeZone.UTC)) + .setParent(parentResource) + .build()); } /** Persists a single Objectify resource, without adjusting foreign resources or keys. */ diff --git a/core/src/test/java/google/registry/testing/SetClockExtension.java b/core/src/test/java/google/registry/testing/SetClockExtension.java new file mode 100644 index 000000000..df443cefa --- /dev/null +++ b/core/src/test/java/google/registry/testing/SetClockExtension.java @@ -0,0 +1,47 @@ +// Copyright 2021 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.testing; + +import org.joda.time.DateTime; +import org.junit.jupiter.api.extension.BeforeEachCallback; +import org.junit.jupiter.api.extension.ExtensionContext; + +/** + * Extension used for tests that a) set the clock to a specific time and b) make use of + * ReplayExtension or any other test feature that requires writing to a commit log from test + * utilities that aren't controlled by the ultimate test class (e.g. AppEngineExtension). + */ +public class SetClockExtension implements BeforeEachCallback { + + private FakeClock clock; + private DateTime dateTime; + + /** Construct from a DateTime, that being the time to set the clock to. */ + public SetClockExtension(FakeClock clock, DateTime dateTime) { + this.clock = clock; + this.dateTime = dateTime; + } + + /** Construct from a dateTime (the time to set the clock to) represented as a string. */ + public SetClockExtension(FakeClock clock, String dateTime) { + this.clock = clock; + this.dateTime = DateTime.parse(dateTime); + } + + @Override + public void beforeEach(ExtensionContext context) { + clock.setTo(dateTime); + } +} diff --git a/core/src/test/resources/google/registry/flows/poll/poll_response_contact_transfer.xml b/core/src/test/resources/google/registry/flows/poll/poll_response_contact_transfer.xml index 7dfdb112f..54b0c5f4a 100644 --- a/core/src/test/resources/google/registry/flows/poll/poll_response_contact_transfer.xml +++ b/core/src/test/resources/google/registry/flows/poll/poll_response_contact_transfer.xml @@ -3,8 +3,8 @@ Command completed successfully; ack to dequeue - - 2000-06-08T22:00:00Z + + 2010-12-28T01:01:01Z Transfer requested. @@ -12,9 +12,9 @@ sh8013 pending TheRegistrar - 2000-06-08T22:00:00.0Z + 2010-12-28T01:01:01Z NewRegistrar - 2000-06-13T22:00:00.0Z + 2011-01-02T01:01:01Z diff --git a/db/src/main/resources/sql/er_diagram/brief_er_diagram.html b/db/src/main/resources/sql/er_diagram/brief_er_diagram.html index 62b70ce3b..590d5b0cb 100644 --- a/db/src/main/resources/sql/er_diagram/brief_er_diagram.html +++ b/db/src/main/resources/sql/er_diagram/brief_er_diagram.html @@ -261,11 +261,11 @@ td.section { generated on - 2021-03-18 19:08:16.381352 + 2021-03-19 12:31:33.396532 last flyway file - V88__transfer_billing_cancellation_history_id.sql + V89__host_history_host_deferred.sql @@ -284,7 +284,7 @@ td.section { generated on - 2021-03-18 19:08:16.381352 + 2021-03-19 12:31:33.396532 @@ -2484,8 +2484,8 @@ td.section { - - fk3d09knnmxrt6iniwnp8j2ykga + + fk_history_registrar_id @@ -5357,7 +5357,7 @@ td.section { - fk3d09knnmxrt6iniwnp8j2ykga + fk_history_registrar_id [foreign key, with no action] @@ -6110,7 +6110,7 @@ td.section { - fk3d09knnmxrt6iniwnp8j2ykga + fk_history_registrar_id [foreign key, with no action] diff --git a/db/src/main/resources/sql/er_diagram/full_er_diagram.html b/db/src/main/resources/sql/er_diagram/full_er_diagram.html index 434149697..54c3b23a5 100644 --- a/db/src/main/resources/sql/er_diagram/full_er_diagram.html +++ b/db/src/main/resources/sql/er_diagram/full_er_diagram.html @@ -261,11 +261,11 @@ td.section { generated on - 2021-03-18 19:08:14.574191 + 2021-03-19 12:31:31.233378 last flyway file - V88__transfer_billing_cancellation_history_id.sql + V89__host_history_host_deferred.sql @@ -284,7 +284,7 @@ td.section { generated on - 2021-03-18 19:08:14.574191 + 2021-03-19 12:31:31.233378 @@ -5580,8 +5580,8 @@ td.section { - - fk3d09knnmxrt6iniwnp8j2ykga + + fk_history_registrar_id @@ -11079,7 +11079,7 @@ td.section { - fk3d09knnmxrt6iniwnp8j2ykga + fk_history_registrar_id [foreign key, with no action] @@ -12436,7 +12436,7 @@ td.section { - fk3d09knnmxrt6iniwnp8j2ykga + fk_history_registrar_id [foreign key, with no action] diff --git a/db/src/main/resources/sql/flyway.txt b/db/src/main/resources/sql/flyway.txt index c1f4cc3f1..fdbf14e20 100644 --- a/db/src/main/resources/sql/flyway.txt +++ b/db/src/main/resources/sql/flyway.txt @@ -86,3 +86,4 @@ V85__add_required_columns_in_transfer_data.sql V86__third_poll_message.sql V87__fix_super_domain_fk.sql V88__transfer_billing_cancellation_history_id.sql +V89__host_history_host_deferred.sql diff --git a/db/src/main/resources/sql/flyway/V89__host_history_host_deferred.sql b/db/src/main/resources/sql/flyway/V89__host_history_host_deferred.sql new file mode 100644 index 000000000..a9b990a17 --- /dev/null +++ b/db/src/main/resources/sql/flyway/V89__host_history_host_deferred.sql @@ -0,0 +1,25 @@ +-- Copyright 2021 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. + +ALTER TABLE "HostHistory" DROP CONSTRAINT fk3d09knnmxrt6iniwnp8j2ykga; +ALTER TABLE "HostHistory" DROP CONSTRAINT fk_hosthistory_host; +ALTER TABLE "HostHistory" ADD CONSTRAINT fk_history_registrar_id + FOREIGN KEY (history_registrar_id) + REFERENCES "Registrar"(registrar_id) + DEFERRABLE INITIALLY DEFERRED; +ALTER TABLE "HostHistory" ADD CONSTRAINT fk_hosthistory_host + FOREIGN KEY (host_repo_id) + REFERENCES "Host"(repo_id) + DEFERRABLE INITIALLY DEFERRED; + diff --git a/db/src/main/resources/sql/schema/nomulus.golden.sql b/db/src/main/resources/sql/schema/nomulus.golden.sql index 10a3274ae..6c2baad19 100644 --- a/db/src/main/resources/sql/schema/nomulus.golden.sql +++ b/db/src/main/resources/sql/schema/nomulus.golden.sql @@ -1867,14 +1867,6 @@ ALTER TABLE ONLY public."Domain" ADD CONSTRAINT fk2u3srsfbei272093m3b3xwj23 FOREIGN KEY (current_sponsor_registrar_id) REFERENCES public."Registrar"(registrar_id); --- --- Name: HostHistory fk3d09knnmxrt6iniwnp8j2ykga; Type: FK CONSTRAINT; Schema: public; Owner: - --- - -ALTER TABLE ONLY public."HostHistory" - ADD CONSTRAINT fk3d09knnmxrt6iniwnp8j2ykga FOREIGN KEY (history_registrar_id) REFERENCES public."Registrar"(registrar_id); - - -- -- Name: SignedMarkRevocationEntry fk5ivlhvs3121yx2li5tqh54u4; Type: FK CONSTRAINT; Schema: public; Owner: - -- @@ -2171,6 +2163,14 @@ ALTER TABLE ONLY public."GracePeriod" ADD CONSTRAINT fk_grace_period_registrar_id FOREIGN KEY (registrar_id) REFERENCES public."Registrar"(registrar_id); +-- +-- Name: HostHistory fk_history_registrar_id; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public."HostHistory" + ADD CONSTRAINT fk_history_registrar_id FOREIGN KEY (history_registrar_id) REFERENCES public."Registrar"(registrar_id) DEFERRABLE INITIALLY DEFERRED; + + -- -- Name: Host fk_host_creation_registrar_id; Type: FK CONSTRAINT; Schema: public; Owner: - -- @@ -2208,7 +2208,7 @@ ALTER TABLE ONLY public."Host" -- ALTER TABLE ONLY public."HostHistory" - ADD CONSTRAINT fk_hosthistory_host FOREIGN KEY (host_repo_id) REFERENCES public."Host"(repo_id); + ADD CONSTRAINT fk_hosthistory_host FOREIGN KEY (host_repo_id) REFERENCES public."Host"(repo_id) DEFERRABLE INITIALLY DEFERRED; --