mirror of
https://github.com/google/nomulus.git
synced 2025-05-13 16:07:15 +02:00
Improve handling of lastSubordinateChange and beef up tests
See [] for the comments that led to this. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=147796087
This commit is contained in:
parent
be30ecdf66
commit
c23bbe35bb
5 changed files with 159 additions and 124 deletions
|
@ -128,9 +128,10 @@ public final class HostUpdateFlow implements TransactionalFlow {
|
||||||
boolean isHostRename = suppliedNewHostName != null;
|
boolean isHostRename = suppliedNewHostName != null;
|
||||||
String oldHostName = targetId;
|
String oldHostName = targetId;
|
||||||
String newHostName = firstNonNull(suppliedNewHostName, oldHostName);
|
String newHostName = firstNonNull(suppliedNewHostName, oldHostName);
|
||||||
Optional<DomainResource> superordinateDomain =
|
// Note that lookupSuperordinateDomain calls cloneProjectedAtTime on the domain for us.
|
||||||
|
Optional<DomainResource> newSuperordinateDomain =
|
||||||
Optional.fromNullable(lookupSuperordinateDomain(validateHostName(newHostName), now));
|
Optional.fromNullable(lookupSuperordinateDomain(validateHostName(newHostName), now));
|
||||||
verifyUpdateAllowed(command, existingHost, superordinateDomain.orNull());
|
verifyUpdateAllowed(command, existingHost, newSuperordinateDomain.orNull());
|
||||||
if (isHostRename && loadAndGetKey(HostResource.class, newHostName, now) != null) {
|
if (isHostRename && loadAndGetKey(HostResource.class, newHostName, now) != null) {
|
||||||
throw new HostAlreadyExistsException(newHostName);
|
throw new HostAlreadyExistsException(newHostName);
|
||||||
}
|
}
|
||||||
|
@ -138,6 +139,13 @@ public final class HostUpdateFlow implements TransactionalFlow {
|
||||||
AddRemove remove = command.getInnerRemove();
|
AddRemove remove = command.getInnerRemove();
|
||||||
checkSameValuesNotAddedAndRemoved(add.getStatusValues(), remove.getStatusValues());
|
checkSameValuesNotAddedAndRemoved(add.getStatusValues(), remove.getStatusValues());
|
||||||
checkSameValuesNotAddedAndRemoved(add.getInetAddresses(), remove.getInetAddresses());
|
checkSameValuesNotAddedAndRemoved(add.getInetAddresses(), remove.getInetAddresses());
|
||||||
|
Key<DomainResource> newSuperordinateDomainKey =
|
||||||
|
newSuperordinateDomain.isPresent() ? Key.create(newSuperordinateDomain.get()) : null;
|
||||||
|
// If the superordinateDomain field is changing, set the lastSuperordinateChange to now.
|
||||||
|
DateTime lastSuperordinateChange =
|
||||||
|
Objects.equals(newSuperordinateDomainKey, existingHost.getSuperordinateDomain())
|
||||||
|
? existingHost.getLastSuperordinateChange()
|
||||||
|
: now;
|
||||||
HostResource newHost = existingHost.asBuilder()
|
HostResource newHost = existingHost.asBuilder()
|
||||||
.setFullyQualifiedHostName(newHostName)
|
.setFullyQualifiedHostName(newHostName)
|
||||||
.addStatusValues(add.getStatusValues())
|
.addStatusValues(add.getStatusValues())
|
||||||
|
@ -146,12 +154,8 @@ public final class HostUpdateFlow implements TransactionalFlow {
|
||||||
.removeInetAddresses(remove.getInetAddresses())
|
.removeInetAddresses(remove.getInetAddresses())
|
||||||
.setLastEppUpdateTime(now)
|
.setLastEppUpdateTime(now)
|
||||||
.setLastEppUpdateClientId(clientId)
|
.setLastEppUpdateClientId(clientId)
|
||||||
// The superordinateDomain can be missing if the new name is external.
|
.setSuperordinateDomain(newSuperordinateDomainKey)
|
||||||
// Note that the value of superordinateDomain is projected to the current time inside of
|
.setLastSuperordinateChange(lastSuperordinateChange)
|
||||||
// the lookupSuperordinateDomain(...) call above, so that it will never be stale.
|
|
||||||
.setSuperordinateDomain(
|
|
||||||
superordinateDomain.isPresent() ? Key.create(superordinateDomain.get()) : null)
|
|
||||||
.setLastSuperordinateChange(superordinateDomain.isPresent() ? now : null)
|
|
||||||
.build()
|
.build()
|
||||||
// Rely on the host's cloneProjectedAtTime() method to handle setting of transfer data.
|
// Rely on the host's cloneProjectedAtTime() method to handle setting of transfer data.
|
||||||
.cloneProjectedAtTime(now);
|
.cloneProjectedAtTime(now);
|
||||||
|
|
|
@ -85,8 +85,11 @@ public class HostResource extends EppResource implements ForeignKeyedEppResource
|
||||||
DateTime lastTransferTime;
|
DateTime lastTransferTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The most recent time that the superordinate domain was changed, or null if this host is
|
* The most recent time that the {@link #superordinateDomain} field was changed.
|
||||||
* external.
|
*
|
||||||
|
* <p>This should be updated whenever the superordinate domain changes, including when it is set
|
||||||
|
* to null. This field will be null for new hosts that have never experienced a change of
|
||||||
|
* superordinate domain.
|
||||||
*/
|
*/
|
||||||
DateTime lastSuperordinateChange;
|
DateTime lastSuperordinateChange;
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
package google.registry.flows.host;
|
package google.registry.flows.host;
|
||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static google.registry.model.ofy.ObjectifyService.ofy;
|
import static google.registry.model.EppResourceUtils.loadByForeignKey;
|
||||||
import static google.registry.testing.DatastoreHelper.assertNoBillingEvents;
|
import static google.registry.testing.DatastoreHelper.assertNoBillingEvents;
|
||||||
import static google.registry.testing.DatastoreHelper.createTld;
|
import static google.registry.testing.DatastoreHelper.createTld;
|
||||||
import static google.registry.testing.DatastoreHelper.persistActiveDomain;
|
import static google.registry.testing.DatastoreHelper.persistActiveDomain;
|
||||||
|
@ -27,6 +27,7 @@ import static google.registry.testing.TaskQueueHelper.assertNoDnsTasksEnqueued;
|
||||||
|
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.googlecode.objectify.Key;
|
||||||
import google.registry.flows.EppXmlTransformer.IpAddressVersionMismatchException;
|
import google.registry.flows.EppXmlTransformer.IpAddressVersionMismatchException;
|
||||||
import google.registry.flows.ResourceFlowTestCase;
|
import google.registry.flows.ResourceFlowTestCase;
|
||||||
import google.registry.flows.exceptions.ResourceAlreadyExistsException;
|
import google.registry.flows.exceptions.ResourceAlreadyExistsException;
|
||||||
|
@ -39,6 +40,7 @@ import google.registry.flows.host.HostFlowUtils.HostNameTooLongException;
|
||||||
import google.registry.flows.host.HostFlowUtils.HostNameTooShallowException;
|
import google.registry.flows.host.HostFlowUtils.HostNameTooShallowException;
|
||||||
import google.registry.flows.host.HostFlowUtils.InvalidHostNameException;
|
import google.registry.flows.host.HostFlowUtils.InvalidHostNameException;
|
||||||
import google.registry.flows.host.HostFlowUtils.SuperordinateDomainDoesNotExistException;
|
import google.registry.flows.host.HostFlowUtils.SuperordinateDomainDoesNotExistException;
|
||||||
|
import google.registry.model.domain.DomainResource;
|
||||||
import google.registry.model.host.HostResource;
|
import google.registry.model.host.HostResource;
|
||||||
import google.registry.model.reporting.HistoryEntry;
|
import google.registry.model.reporting.HistoryEntry;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
@ -80,6 +82,7 @@ public class HostCreateFlowTest extends ResourceFlowTestCase<HostCreateFlow, Hos
|
||||||
runFlowAssertResponse(readFile("host_create_response.xml"));
|
runFlowAssertResponse(readFile("host_create_response.xml"));
|
||||||
// Check that the host was created and persisted with a history entry.
|
// Check that the host was created and persisted with a history entry.
|
||||||
assertAboutHosts().that(reloadResourceByForeignKey())
|
assertAboutHosts().that(reloadResourceByForeignKey())
|
||||||
|
.hasLastSuperordinateChange(null).and()
|
||||||
.hasOnlyOneHistoryEntryWhich()
|
.hasOnlyOneHistoryEntryWhich()
|
||||||
.hasType(HistoryEntry.Type.HOST_CREATE);
|
.hasType(HistoryEntry.Type.HOST_CREATE);
|
||||||
assertNoBillingEvents();
|
assertNoBillingEvents();
|
||||||
|
@ -101,17 +104,18 @@ public class HostCreateFlowTest extends ResourceFlowTestCase<HostCreateFlow, Hos
|
||||||
@Test
|
@Test
|
||||||
public void testSuccess_externalNeverExisted() throws Exception {
|
public void testSuccess_externalNeverExisted() throws Exception {
|
||||||
doSuccessfulTest();
|
doSuccessfulTest();
|
||||||
|
assertAboutHosts().that(reloadResourceByForeignKey()).hasSuperordinateDomain(null);
|
||||||
assertNoDnsTasksEnqueued();
|
assertNoDnsTasksEnqueued();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSuccess_internalNeverExisted() throws Exception {
|
public void testSuccess_internalNeverExisted() throws Exception {
|
||||||
doSuccessfulInternalTest("tld");
|
doSuccessfulInternalTest("tld");
|
||||||
assertThat(ofy().load().key(reloadResourceByForeignKey().getSuperordinateDomain())
|
HostResource host = reloadResourceByForeignKey();
|
||||||
.now().getFullyQualifiedDomainName())
|
DomainResource superordinateDomain =
|
||||||
.isEqualTo("example.tld");
|
loadByForeignKey(DomainResource.class, "example.tld", clock.nowUtc());
|
||||||
assertThat(ofy().load().key(reloadResourceByForeignKey().getSuperordinateDomain())
|
assertAboutHosts().that(host).hasSuperordinateDomain(Key.create(superordinateDomain));
|
||||||
.now().getSubordinateHosts()).containsExactly("ns1.example.tld");
|
assertThat(superordinateDomain.getSubordinateHosts()).containsExactly("ns1.example.tld");
|
||||||
assertDnsTasksEnqueued("ns1.example.tld");
|
assertDnsTasksEnqueued("ns1.example.tld");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,6 +123,7 @@ public class HostCreateFlowTest extends ResourceFlowTestCase<HostCreateFlow, Hos
|
||||||
public void testSuccess_externalExistedButWasDeleted() throws Exception {
|
public void testSuccess_externalExistedButWasDeleted() throws Exception {
|
||||||
persistDeletedHost(getUniqueIdFromCommand(), clock.nowUtc().minusDays(1));
|
persistDeletedHost(getUniqueIdFromCommand(), clock.nowUtc().minusDays(1));
|
||||||
doSuccessfulTest();
|
doSuccessfulTest();
|
||||||
|
assertAboutHosts().that(reloadResourceByForeignKey()).hasSuperordinateDomain(null);
|
||||||
assertNoDnsTasksEnqueued();
|
assertNoDnsTasksEnqueued();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,11 +131,11 @@ public class HostCreateFlowTest extends ResourceFlowTestCase<HostCreateFlow, Hos
|
||||||
public void testSuccess_internalExistedButWasDeleted() throws Exception {
|
public void testSuccess_internalExistedButWasDeleted() throws Exception {
|
||||||
persistDeletedHost(getUniqueIdFromCommand(), clock.nowUtc().minusDays(1));
|
persistDeletedHost(getUniqueIdFromCommand(), clock.nowUtc().minusDays(1));
|
||||||
doSuccessfulInternalTest("tld");
|
doSuccessfulInternalTest("tld");
|
||||||
assertThat(ofy().load().key(reloadResourceByForeignKey().getSuperordinateDomain())
|
HostResource host = reloadResourceByForeignKey();
|
||||||
.now().getFullyQualifiedDomainName())
|
DomainResource superordinateDomain =
|
||||||
.isEqualTo("example.tld");
|
loadByForeignKey(DomainResource.class, "example.tld", clock.nowUtc());
|
||||||
assertThat(ofy().load().key(reloadResourceByForeignKey().getSuperordinateDomain())
|
assertAboutHosts().that(host).hasSuperordinateDomain(Key.create(superordinateDomain));
|
||||||
.now().getSubordinateHosts()).containsExactly("ns1.example.tld");
|
assertThat(superordinateDomain.getSubordinateHosts()).containsExactly("ns1.example.tld");
|
||||||
assertDnsTasksEnqueued("ns1.example.tld");
|
assertDnsTasksEnqueued("ns1.example.tld");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ import static com.google.common.base.Strings.nullToEmpty;
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
import static google.registry.flows.async.AsyncFlowEnqueuer.QUEUE_ASYNC_HOST_RENAME;
|
import static google.registry.flows.async.AsyncFlowEnqueuer.QUEUE_ASYNC_HOST_RENAME;
|
||||||
import static google.registry.model.EppResourceUtils.loadByForeignKey;
|
import static google.registry.model.EppResourceUtils.loadByForeignKey;
|
||||||
|
import static google.registry.model.ofy.ObjectifyService.ofy;
|
||||||
import static google.registry.testing.DatastoreHelper.assertNoBillingEvents;
|
import static google.registry.testing.DatastoreHelper.assertNoBillingEvents;
|
||||||
import static google.registry.testing.DatastoreHelper.createTld;
|
import static google.registry.testing.DatastoreHelper.createTld;
|
||||||
import static google.registry.testing.DatastoreHelper.getOnlyHistoryEntryOfType;
|
import static google.registry.testing.DatastoreHelper.getOnlyHistoryEntryOfType;
|
||||||
|
@ -174,80 +175,107 @@ public class HostUpdateFlowTest extends ResourceFlowTestCase<HostUpdateFlow, Hos
|
||||||
setEppInput("host_update_name_unchanged.xml");
|
setEppInput("host_update_name_unchanged.xml");
|
||||||
createTld("tld");
|
createTld("tld");
|
||||||
DomainResource domain = persistActiveDomain("example.tld");
|
DomainResource domain = persistActiveDomain("example.tld");
|
||||||
persistActiveSubordinateHost(oldHostName(), domain);
|
HostResource oldHost = persistActiveSubordinateHost(oldHostName(), domain);
|
||||||
|
|
||||||
clock.advanceOneMilli();
|
clock.advanceOneMilli();
|
||||||
runFlowAssertResponse(readFile("host_update_response.xml"));
|
runFlowAssertResponse(readFile("host_update_response.xml"));
|
||||||
// The example xml doesn't do a host rename, so reloading the host should work.
|
// The example xml doesn't do a host rename, so reloading the host should work.
|
||||||
assertAboutHosts().that(reloadResourceByForeignKey())
|
assertAboutHosts().that(reloadResourceByForeignKey())
|
||||||
|
.hasLastSuperordinateChange(oldHost.getLastSuperordinateChange()).and()
|
||||||
|
.hasSuperordinateDomain(Key.create(domain)).and()
|
||||||
.hasOnlyOneHistoryEntryWhich()
|
.hasOnlyOneHistoryEntryWhich()
|
||||||
.hasType(HistoryEntry.Type.HOST_UPDATE);
|
.hasType(HistoryEntry.Type.HOST_UPDATE);
|
||||||
assertDnsTasksEnqueued("ns1.example.tld");
|
assertDnsTasksEnqueued("ns1.example.tld");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSuccess_renameWithSameSuperordinateDomain() throws Exception {
|
public void testSuccess_internalToInternalOnSameDomain() throws Exception {
|
||||||
setEppHostUpdateInput(
|
setEppHostUpdateInput(
|
||||||
"ns1.example.tld",
|
"ns1.example.tld",
|
||||||
"ns2.example.tld",
|
"ns2.example.tld",
|
||||||
"<host:addr ip=\"v4\">192.0.2.22</host:addr>",
|
"<host:addr ip=\"v4\">192.0.2.22</host:addr>",
|
||||||
"<host:addr ip=\"v6\">1080:0:0:0:8:800:200C:417A</host:addr>");
|
"<host:addr ip=\"v6\">1080:0:0:0:8:800:200C:417A</host:addr>");
|
||||||
createTld("tld");
|
createTld("tld");
|
||||||
DomainResource domain = persistActiveDomain("example.tld");
|
DomainResource domain = persistResource(newDomainResource("example.tld")
|
||||||
persistActiveSubordinateHost(oldHostName(), domain);
|
.asBuilder()
|
||||||
persistResource(
|
|
||||||
domain.asBuilder()
|
|
||||||
.setSubordinateHosts(ImmutableSet.of(oldHostName()))
|
.setSubordinateHosts(ImmutableSet.of(oldHostName()))
|
||||||
.build());
|
.build());
|
||||||
assertThat(
|
HostResource oldHost = persistActiveSubordinateHost(oldHostName(), domain);
|
||||||
loadByForeignKey(
|
assertThat(domain.getSubordinateHosts()).containsExactly("ns1.example.tld");
|
||||||
DomainResource.class, "example.tld", clock.nowUtc()).getSubordinateHosts())
|
|
||||||
.containsExactly("ns1.example.tld");
|
|
||||||
HostResource renamedHost = doSuccessfulTest();
|
HostResource renamedHost = doSuccessfulTest();
|
||||||
assertThat(renamedHost.getSuperordinateDomain()).isEqualTo(Key.create(domain));
|
assertAboutHosts().that(renamedHost)
|
||||||
assertThat(
|
.hasSuperordinateDomain(Key.create(domain)).and()
|
||||||
loadByForeignKey(
|
.hasLastSuperordinateChange(oldHost.getLastSuperordinateChange());
|
||||||
DomainResource.class, "example.tld", clock.nowUtc()).getSubordinateHosts())
|
DomainResource reloadedDomain =
|
||||||
.containsExactly("ns2.example.tld");
|
ofy().load().entity(domain).now().cloneProjectedAtTime(clock.nowUtc());
|
||||||
|
assertThat(reloadedDomain.getSubordinateHosts()).containsExactly("ns2.example.tld");
|
||||||
assertDnsTasksEnqueued("ns1.example.tld", "ns2.example.tld");
|
assertDnsTasksEnqueued("ns1.example.tld", "ns2.example.tld");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSuccess_internalToSameInternal() throws Exception {
|
public void testSuccess_internalToInternalOnSameTld() throws Exception {
|
||||||
setEppHostUpdateInput(
|
setEppHostUpdateInput(
|
||||||
"ns2.foo.tld",
|
"ns2.foo.tld",
|
||||||
"ns2.example.tld",
|
"ns2.example.tld",
|
||||||
"<host:addr ip=\"v4\">192.0.2.22</host:addr>",
|
"<host:addr ip=\"v4\">192.0.2.22</host:addr>",
|
||||||
"<host:addr ip=\"v6\">1080:0:0:0:8:800:200C:417A</host:addr>");
|
"<host:addr ip=\"v6\">1080:0:0:0:8:800:200C:417A</host:addr>");
|
||||||
createTld("tld");
|
createTld("tld");
|
||||||
DomainResource foo = persistActiveDomain("foo.tld");
|
|
||||||
DomainResource example = persistActiveDomain("example.tld");
|
DomainResource example = persistActiveDomain("example.tld");
|
||||||
persistActiveSubordinateHost(oldHostName(), foo);
|
DomainResource foo = persistResource(newDomainResource("foo.tld").asBuilder()
|
||||||
persistResource(
|
|
||||||
foo.asBuilder()
|
|
||||||
.setSubordinateHosts(ImmutableSet.of(oldHostName()))
|
.setSubordinateHosts(ImmutableSet.of(oldHostName()))
|
||||||
.build());
|
.build());
|
||||||
assertThat(
|
persistActiveSubordinateHost(oldHostName(), foo);
|
||||||
loadByForeignKey(
|
assertThat(foo.getSubordinateHosts()).containsExactly("ns2.foo.tld");
|
||||||
DomainResource.class, "foo.tld", clock.nowUtc()).getSubordinateHosts())
|
assertThat(example.getSubordinateHosts()).isEmpty();
|
||||||
.containsExactly("ns2.foo.tld");
|
|
||||||
assertThat(
|
|
||||||
loadByForeignKey(
|
|
||||||
DomainResource.class, "example.tld", clock.nowUtc()).getSubordinateHosts())
|
|
||||||
.isEmpty();
|
|
||||||
HostResource renamedHost = doSuccessfulTest();
|
HostResource renamedHost = doSuccessfulTest();
|
||||||
assertThat(renamedHost.getSuperordinateDomain()).isEqualTo(Key.create(example));
|
DateTime now = clock.nowUtc();
|
||||||
assertThat(
|
assertAboutHosts().that(renamedHost)
|
||||||
loadByForeignKey(
|
.hasSuperordinateDomain(Key.create(example)).and()
|
||||||
DomainResource.class, "foo.tld", clock.nowUtc()).getSubordinateHosts())
|
.hasLastSuperordinateChange(now);
|
||||||
|
assertThat(ofy().load().entity(foo).now().cloneProjectedAtTime(now).getSubordinateHosts())
|
||||||
.isEmpty();
|
.isEmpty();
|
||||||
assertThat(
|
assertThat(ofy().load().entity(example).now().cloneProjectedAtTime(now).getSubordinateHosts())
|
||||||
loadByForeignKey(
|
|
||||||
DomainResource.class, "example.tld", clock.nowUtc()).getSubordinateHosts())
|
|
||||||
.containsExactly("ns2.example.tld");
|
.containsExactly("ns2.example.tld");
|
||||||
assertDnsTasksEnqueued("ns2.foo.tld", "ns2.example.tld");
|
assertDnsTasksEnqueued("ns2.foo.tld", "ns2.example.tld");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSuccess_internalToInternalOnDifferentTld() throws Exception {
|
||||||
|
setEppHostUpdateInput(
|
||||||
|
"ns1.example.foo",
|
||||||
|
"ns2.example.tld",
|
||||||
|
"<host:addr ip=\"v4\">192.0.2.22</host:addr>",
|
||||||
|
"<host:addr ip=\"v6\">1080:0:0:0:8:800:200C:417A</host:addr>");
|
||||||
|
createTld("foo");
|
||||||
|
createTld("tld");
|
||||||
|
DomainResource fooDomain = persistResource(newDomainResource("example.foo").asBuilder()
|
||||||
|
.setSubordinateHosts(ImmutableSet.of(oldHostName()))
|
||||||
|
.build());
|
||||||
|
DomainResource tldDomain = persistActiveDomain("example.tld");
|
||||||
|
HostResource oldHost = persistActiveSubordinateHost(oldHostName(), fooDomain);
|
||||||
|
assertThat(oldHost.getCurrentSponsorClientId()).isEqualTo("TheRegistrar");
|
||||||
|
assertThat(fooDomain.getSubordinateHosts()).containsExactly("ns1.example.foo");
|
||||||
|
assertThat(tldDomain.getSubordinateHosts()).isEmpty();
|
||||||
|
HostResource renamedHost = doSuccessfulTest();
|
||||||
|
DateTime now = clock.nowUtc();
|
||||||
|
assertAboutHosts().that(renamedHost)
|
||||||
|
.hasSuperordinateDomain(Key.create(tldDomain)).and()
|
||||||
|
.hasLastSuperordinateChange(now);
|
||||||
|
DomainResource reloadedFooDomain =
|
||||||
|
ofy().load().entity(fooDomain).now().cloneProjectedAtTime(now);
|
||||||
|
assertThat(reloadedFooDomain.getSubordinateHosts()).isEmpty();
|
||||||
|
DomainResource reloadedTldDomain =
|
||||||
|
ofy().load().entity(tldDomain).now().cloneProjectedAtTime(now);
|
||||||
|
assertThat(reloadedTldDomain.getSubordinateHosts()).containsExactly("ns2.example.tld");
|
||||||
|
assertDnsTasksEnqueued("ns1.example.foo", "ns2.example.tld");
|
||||||
|
// Ensure that the client id is read off the domain because this is a subordinate host now.
|
||||||
|
persistResource(
|
||||||
|
tldDomain.asBuilder().setCurrentSponsorClientId("it_should_be_this").build());
|
||||||
|
assertThat(
|
||||||
|
renamedHost.cloneProjectedAtTime(clock.nowUtc().plusMinutes(1)).getCurrentSponsorClientId())
|
||||||
|
.isEqualTo("it_should_be_this");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSuccess_internalToExternal() throws Exception {
|
public void testSuccess_internalToExternal() throws Exception {
|
||||||
setEppHostUpdateInput(
|
setEppHostUpdateInput(
|
||||||
|
@ -256,62 +284,28 @@ public class HostUpdateFlowTest extends ResourceFlowTestCase<HostUpdateFlow, Hos
|
||||||
null,
|
null,
|
||||||
"<host:addr ip=\"v6\">1080:0:0:0:8:800:200C:417A</host:addr>");
|
"<host:addr ip=\"v6\">1080:0:0:0:8:800:200C:417A</host:addr>");
|
||||||
createTld("foo");
|
createTld("foo");
|
||||||
DomainResource domain = persistActiveDomain("example.foo");
|
DomainResource domain = persistResource(newDomainResource("example.foo").asBuilder()
|
||||||
persistActiveSubordinateHost(oldHostName(), domain);
|
|
||||||
persistResource(
|
|
||||||
domain.asBuilder()
|
|
||||||
.setSubordinateHosts(ImmutableSet.of(oldHostName()))
|
.setSubordinateHosts(ImmutableSet.of(oldHostName()))
|
||||||
.build());
|
.build());
|
||||||
assertThat(
|
assertThat(domain.getCurrentSponsorClientId()).isEqualTo("TheRegistrar");
|
||||||
loadByForeignKey(
|
HostResource oldHost = persistResource(
|
||||||
DomainResource.class, "example.foo", clock.nowUtc()).getSubordinateHosts())
|
persistActiveSubordinateHost(oldHostName(), domain).asBuilder()
|
||||||
.containsExactly("ns1.example.foo");
|
.setCurrentSponsorClientId("ClientThatShouldBeSupersededByDomainClient")
|
||||||
|
.build());
|
||||||
|
assertThat(oldHost.isSubordinate()).isTrue();
|
||||||
|
assertThat(domain.getSubordinateHosts()).containsExactly("ns1.example.foo");
|
||||||
HostResource renamedHost = doSuccessfulTest();
|
HostResource renamedHost = doSuccessfulTest();
|
||||||
assertThat(renamedHost.isSubordinate()).isFalse();
|
assertAboutHosts().that(renamedHost)
|
||||||
// Ensure that the client id is set to the new registrar correctly (and that this necessarily
|
// Ensure that the client id is copied off of the superordinate domain.
|
||||||
// comes from the field on the host itself, because the superordinate domain is null).
|
.hasCurrentSponsorClientId("TheRegistrar").and()
|
||||||
assertThat(renamedHost.getCurrentSponsorClientId()).isEqualTo("TheRegistrar");
|
.hasSuperordinateDomain(null).and()
|
||||||
assertThat(
|
.hasLastSuperordinateChange(clock.nowUtc());
|
||||||
loadByForeignKey(
|
DomainResource reloadedDomain =
|
||||||
DomainResource.class, "example.foo", clock.nowUtc()).getSubordinateHosts())
|
ofy().load().entity(domain).now().cloneProjectedAtTime(clock.nowUtc());
|
||||||
.isEmpty();
|
assertThat(reloadedDomain.getSubordinateHosts()).isEmpty();
|
||||||
assertDnsTasksEnqueued("ns1.example.foo");
|
assertDnsTasksEnqueued("ns1.example.foo");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSuccess_internalToDifferentInternal() throws Exception {
|
|
||||||
setEppHostUpdateInput(
|
|
||||||
"ns1.example.foo",
|
|
||||||
"ns2.example.tld",
|
|
||||||
"<host:addr ip=\"v4\">192.0.2.22</host:addr>",
|
|
||||||
"<host:addr ip=\"v6\">1080:0:0:0:8:800:200C:417A</host:addr>");
|
|
||||||
createTld("foo");
|
|
||||||
persistActiveDomain("example.foo");
|
|
||||||
createTld("tld");
|
|
||||||
DomainResource tldDomain = persistActiveDomain("example.tld");
|
|
||||||
persistActiveHost(oldHostName());
|
|
||||||
|
|
||||||
assertThat(loadByForeignKey(
|
|
||||||
HostResource.class, oldHostName(), clock.nowUtc()).getCurrentSponsorClientId())
|
|
||||||
.isEqualTo("TheRegistrar");
|
|
||||||
assertThat(
|
|
||||||
loadByForeignKey(
|
|
||||||
DomainResource.class, "example.tld", clock.nowUtc()).getSubordinateHosts())
|
|
||||||
.isEmpty();
|
|
||||||
HostResource renamedHost = doSuccessfulTest();
|
|
||||||
assertThat(renamedHost.getSuperordinateDomain()).isEqualTo(Key.create(tldDomain));
|
|
||||||
assertThat(loadByForeignKey(
|
|
||||||
DomainResource.class, "example.tld", clock.nowUtc()).getSubordinateHosts())
|
|
||||||
.containsExactly("ns2.example.tld");
|
|
||||||
assertDnsTasksEnqueued("ns2.example.tld");
|
|
||||||
// Ensure that the client id is read off the domain because this is a subordinate host now.
|
|
||||||
persistResource(
|
|
||||||
tldDomain.asBuilder().setCurrentSponsorClientId("it_should_be_this").build());
|
|
||||||
assertThat(
|
|
||||||
renamedHost.cloneProjectedAtTime(clock.nowUtc().plusMinutes(1)).getCurrentSponsorClientId())
|
|
||||||
.isEqualTo("it_should_be_this");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSuccess_externalToInternal() throws Exception {
|
public void testSuccess_externalToInternal() throws Exception {
|
||||||
setEppHostUpdateInput(
|
setEppHostUpdateInput(
|
||||||
|
@ -321,28 +315,41 @@ public class HostUpdateFlowTest extends ResourceFlowTestCase<HostUpdateFlow, Hos
|
||||||
null);
|
null);
|
||||||
createTld("tld");
|
createTld("tld");
|
||||||
DomainResource domain = persistActiveDomain("example.tld");
|
DomainResource domain = persistActiveDomain("example.tld");
|
||||||
persistActiveHost(oldHostName());
|
HostResource oldHost = persistActiveHost(oldHostName());
|
||||||
|
assertThat(oldHost.getCurrentSponsorClientId()).isEqualTo("TheRegistrar");
|
||||||
assertThat(loadByForeignKey(
|
assertThat(domain.getSubordinateHosts()).isEmpty();
|
||||||
HostResource.class, oldHostName(), clock.nowUtc()).getCurrentSponsorClientId())
|
|
||||||
.isEqualTo("TheRegistrar");
|
|
||||||
assertThat(loadByForeignKey(
|
|
||||||
DomainResource.class, "example.tld", clock.nowUtc()).getSubordinateHosts())
|
|
||||||
.isEmpty();
|
|
||||||
HostResource renamedHost = doSuccessfulTest();
|
HostResource renamedHost = doSuccessfulTest();
|
||||||
assertThat(renamedHost.getSuperordinateDomain()).isEqualTo(Key.create(domain));
|
DateTime now = clock.nowUtc();
|
||||||
assertThat(loadByForeignKey(
|
assertAboutHosts().that(renamedHost)
|
||||||
DomainResource.class, "example.tld", clock.nowUtc()).getSubordinateHosts())
|
.hasSuperordinateDomain(Key.create(domain)).and()
|
||||||
|
.hasLastSuperordinateChange(now);
|
||||||
|
assertThat(ofy().load().entity(domain).now().cloneProjectedAtTime(now).getSubordinateHosts())
|
||||||
.containsExactly("ns2.example.tld");
|
.containsExactly("ns2.example.tld");
|
||||||
assertDnsTasksEnqueued("ns2.example.tld");
|
assertDnsTasksEnqueued("ns2.example.tld");
|
||||||
// Ensure that the client id is read off the domain because this is a subordinate host now.
|
// Ensure that the client id is read off the domain because this is a subordinate host now.
|
||||||
persistResource(
|
persistResource(
|
||||||
domain.asBuilder().setCurrentSponsorClientId("it_should_be_this").build());
|
domain.asBuilder().setCurrentSponsorClientId("it_should_be_this").build());
|
||||||
assertThat(
|
assertThat(
|
||||||
renamedHost.cloneProjectedAtTime(clock.nowUtc().plusMinutes(1)).getCurrentSponsorClientId())
|
renamedHost.cloneProjectedAtTime(now.plusMinutes(1)).getCurrentSponsorClientId())
|
||||||
.isEqualTo("it_should_be_this");
|
.isEqualTo("it_should_be_this");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSuccess_externalToExternal() throws Exception {
|
||||||
|
setEppHostUpdateInput(
|
||||||
|
"ns1.example.foo",
|
||||||
|
"ns2.example.tld",
|
||||||
|
null,
|
||||||
|
null);
|
||||||
|
HostResource oldHost = persistActiveHost(oldHostName());
|
||||||
|
assertThat(oldHost.getCurrentSponsorClientId()).isEqualTo("TheRegistrar");
|
||||||
|
HostResource renamedHost = doSuccessfulTest();
|
||||||
|
assertAboutHosts().that(renamedHost)
|
||||||
|
.hasSuperordinateDomain(null).and()
|
||||||
|
.hasLastSuperordinateChange(null);
|
||||||
|
assertNoDnsTasksEnqueued();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSuccess_superuserClientUpdateProhibited() throws Exception {
|
public void testSuccess_superuserClientUpdateProhibited() throws Exception {
|
||||||
setEppInput("host_update_add_status.xml");
|
setEppInput("host_update_add_status.xml");
|
||||||
|
@ -550,7 +557,7 @@ public class HostUpdateFlowTest extends ResourceFlowTestCase<HostUpdateFlow, Hos
|
||||||
// update, not what it is later changed to.
|
// update, not what it is later changed to.
|
||||||
assertThat(renamedHost.getLastTransferTime()).isEqualTo(lastTransferTime);
|
assertThat(renamedHost.getLastTransferTime()).isEqualTo(lastTransferTime);
|
||||||
// External hosts should always have null lastSuperordinateChange.
|
// External hosts should always have null lastSuperordinateChange.
|
||||||
assertThat(renamedHost.getLastSuperordinateChange()).isNull();
|
assertThat(renamedHost.getLastSuperordinateChange()).isEqualTo(clock.nowUtc());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -19,6 +19,8 @@ import static com.google.common.truth.Truth.assertAbout;
|
||||||
|
|
||||||
import com.google.common.truth.AbstractVerb.DelegatedVerb;
|
import com.google.common.truth.AbstractVerb.DelegatedVerb;
|
||||||
import com.google.common.truth.FailureStrategy;
|
import com.google.common.truth.FailureStrategy;
|
||||||
|
import com.googlecode.objectify.Key;
|
||||||
|
import google.registry.model.domain.DomainResource;
|
||||||
import google.registry.model.host.HostResource;
|
import google.registry.model.host.HostResource;
|
||||||
import google.registry.testing.TruthChainer.And;
|
import google.registry.testing.TruthChainer.And;
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
|
@ -52,4 +54,18 @@ public final class HostResourceSubject
|
||||||
actual().getLastTransferTime(),
|
actual().getLastTransferTime(),
|
||||||
"lastTransferTime");
|
"lastTransferTime");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public And<HostResourceSubject> hasLastSuperordinateChange(DateTime lastSuperordinateChange) {
|
||||||
|
return hasValue(
|
||||||
|
lastSuperordinateChange,
|
||||||
|
actual().getLastSuperordinateChange(),
|
||||||
|
"has lastSuperordinateChange");
|
||||||
|
}
|
||||||
|
|
||||||
|
public And<HostResourceSubject> hasSuperordinateDomain(Key<DomainResource> superordinateDomain) {
|
||||||
|
return hasValue(
|
||||||
|
superordinateDomain,
|
||||||
|
actual().getSuperordinateDomain(),
|
||||||
|
"has superordinateDomain");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue