Make failfastForCreate for domain and application creates explicitly hit memcache

TESTED=For all tests, I added @Cache to DomainBase because otherwise the tests will
    fail. We aren't ready to do this in prod yet, which is why the tests are still
    marked @Ignore. The new tests fail if you change line 134 in Ofy to not use memcache
    and either use the unchanged original DomainCreateFlow code, or use the new
    inlined code and change loadWithMemcache() to load(). They pass with the new
    inlined code that calls loadWithMemcache(), as long as the @Cache is added to
    DomainResource.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=154224748
This commit is contained in:
cgoldfeder 2017-04-25 14:50:08 -07:00 committed by Ben McIlwain
parent cb145e0721
commit 9e61f1d6ef
5 changed files with 119 additions and 26 deletions

View file

@ -16,6 +16,7 @@ package google.registry.flows.domain;
import static com.google.common.io.BaseEncoding.base16;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assert_;
import static google.registry.model.domain.fee.Fee.FEE_EXTENSION_URIS;
import static google.registry.model.eppcommon.StatusValue.OK;
import static google.registry.model.eppcommon.StatusValue.SERVER_TRANSFER_PROHIBITED;
@ -39,6 +40,7 @@ import static google.registry.testing.DatastoreHelper.persistDeletedDomain;
import static google.registry.testing.DatastoreHelper.persistReservedList;
import static google.registry.testing.DatastoreHelper.persistResource;
import static google.registry.testing.DomainResourceSubject.assertAboutDomains;
import static google.registry.testing.MemcacheHelper.setMemcacheContents;
import static google.registry.testing.TaskQueueHelper.assertDnsTasksEnqueued;
import static google.registry.testing.TaskQueueHelper.assertNoDnsTasksEnqueued;
import static google.registry.testing.TaskQueueHelper.assertNoTasksEnqueued;
@ -55,6 +57,7 @@ import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedMap;
import com.googlecode.objectify.Key;
import google.registry.flows.EppException.UnimplementedExtensionException;
import google.registry.flows.EppRequestSource;
import google.registry.flows.ExtensionManager.UndeclaredServiceExtensionException;
@ -120,6 +123,8 @@ import google.registry.model.domain.launch.LaunchNotice;
import google.registry.model.domain.rgp.GracePeriodStatus;
import google.registry.model.domain.secdns.DelegationSignerData;
import google.registry.model.eppcommon.StatusValue;
import google.registry.model.index.ForeignKeyIndex;
import google.registry.model.ofy.RequestCapturingAsyncDatastoreService;
import google.registry.model.poll.PollMessage;
import google.registry.model.registrar.Registrar;
import google.registry.model.registry.Registry;
@ -890,21 +895,43 @@ public class DomainCreateFlowTest extends ResourceFlowTestCase<DomainCreateFlow,
}
@Test
public void testFailure_alreadyExists() throws Exception {
public void testFailure_alreadyExists_triggersFailfast() throws Exception {
// This fails fast and throws DomainAlreadyExistsException from init() as a special case.
persistContactsAndHosts();
persistActiveDomain(getUniqueIdFromCommand());
thrown.expect(
ResourceAlreadyExistsException.class,
String.format("Object with given ID (%s) already exists", getUniqueIdFromCommand()));
try {
runFlow();
assert_().fail(
"Expected to throw ResourceAlreadyExistsException with message "
+ "Object with given ID (%s) already exists",
getUniqueIdFromCommand());
} catch (ResourceAlreadyExistsException e) {
assertThat(e.isFailfast()).isTrue();
throw e;
}
}
@Test
public void testFailfast_withMemcachedDomainAndFki_hitsMemcache() throws Exception {
persistContactsAndHosts();
DomainResource domain = persistActiveDomain(getUniqueIdFromCommand());
setMemcacheContents(Key.create(domain), ForeignKeyIndex.createKey(domain));
int numPreviousReads = RequestCapturingAsyncDatastoreService.getReads().size();
try {
runFlow();
assert_().fail("Expected to throw ResourceAlreadyExistsException");
} catch (ResourceAlreadyExistsException e) {
assertThat(e.isFailfast()).isTrue();
}
// Everything should have been loaded from memcache so nothing should hit datastore.
int numReadsInFlow =
RequestCapturingAsyncDatastoreService.getReads().size() - numPreviousReads;
// TODO(b/27424173): This is 1 because there is no @Cache annotation on DomainBase, and we
// don't want to blindly add it because that's a production change that adds potentially
// dangerous caching. When the recommendations from the audit in b/27424173 are done and we've
// tested the new safer caching this should be set to 0.
assertThat(numReadsInFlow).isEqualTo(1);
}
/**
* There is special logic that disallows a failfast for domains in add grace period and sunrush
* add grace period, so make sure that they fail anyways in the actual flow.