Convert AuthenticatedRegAccessor and OteStats to SQL (#1039)

This required adding a new HistoryEntryDao method but it's fairly
similar to the ones we already have.
This commit is contained in:
gbrodman 2021-04-02 11:41:26 -04:00 committed by GitHub
parent 4e7dd7a95a
commit c077aca433
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 230 additions and 119 deletions

View file

@ -15,19 +15,28 @@
package google.registry.model;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.testing.DatabaseHelper.createTld;
import google.registry.model.OteStats.StatType;
import google.registry.testing.AppEngineExtension;
import org.junit.jupiter.api.Test;
import google.registry.testing.DualDatabaseTest;
import google.registry.testing.TestOfyAndSql;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.RegisterExtension;
@DualDatabaseTest
public final class OteStatsTest {
@RegisterExtension
public final AppEngineExtension appEngine =
AppEngineExtension.builder().withDatastoreAndCloudSql().build();
@Test
@BeforeEach
void beforeEach() {
createTld("tld");
}
@TestOfyAndSql
void testSuccess_allPass() throws Exception {
OteStatsTestHelper.setupCompleteOte("blobio");
OteStats stats = OteStats.getFromRegistrar("blobio");
@ -35,7 +44,7 @@ public final class OteStatsTest {
assertThat(stats.getSize()).isEqualTo(30);
}
@Test
@TestOfyAndSql
void testSuccess_incomplete() throws Exception {
OteStatsTestHelper.setupIncompleteOte("blobio");
OteStats stats = OteStats.getFromRegistrar("blobio");
@ -46,7 +55,7 @@ public final class OteStatsTest {
assertThat(stats.getSize()).isEqualTo(34);
}
@Test
@TestOfyAndSql
void testSuccess_toString() throws Exception {
OteStatsTestHelper.setupCompleteOte("blobio");
OteStats stats = OteStats.getFromRegistrar("blobio");
@ -87,7 +96,7 @@ public final class OteStatsTest {
assertThat(stats.toString()).isEqualTo(expected);
}
@Test
@TestOfyAndSql
void testIncomplete_toString() throws Exception {
OteStatsTestHelper.setupIncompleteOte("blobio");
OteStats stats = OteStats.getFromRegistrar("blobio");

View file

@ -14,126 +14,168 @@
package google.registry.model;
import static google.registry.testing.DatabaseHelper.createTld;
import static google.registry.testing.DatabaseHelper.persistActiveDomain;
import static google.registry.testing.DatabaseHelper.persistActiveHost;
import static google.registry.testing.DatabaseHelper.persistDeletedDomain;
import static google.registry.testing.DatabaseHelper.persistDeletedHost;
import static google.registry.testing.DatabaseHelper.persistPremiumList;
import static google.registry.testing.DatabaseHelper.persistResource;
import static google.registry.testing.TestDataHelper.loadBytes;
import static google.registry.util.DateTimeUtils.END_OF_TIME;
import google.registry.model.domain.DomainHistory;
import google.registry.model.eppcommon.Trid;
import google.registry.model.reporting.HistoryEntry;
import google.registry.model.host.HostHistory;
import google.registry.model.reporting.HistoryEntry.Type;
import java.io.IOException;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
public final class OteStatsTestHelper {
public static void setupCompleteOte(String baseClientId) throws IOException {
setupIncompleteOte(baseClientId);
String oteAccount1 = String.format("%s-1", baseClientId);
DateTime now = DateTime.now(DateTimeZone.UTC);
persistResource(
new HistoryEntry.Builder()
new DomainHistory.Builder()
.setDomainRepoId(persistActiveDomain("xn--abc-873b2e7eb1k8a4lpjvv.tld").getRepoId())
.setClientId(oteAccount1)
.setType(Type.DOMAIN_CREATE)
.setXmlBytes(getBytes("domain_create_idn.xml"))
.setModificationTime(now)
.build());
persistResource(
new HistoryEntry.Builder()
new DomainHistory.Builder()
.setDomainRepoId(persistActiveDomain("example.tld").getRepoId())
.setClientId(oteAccount1)
.setType(Type.DOMAIN_RESTORE)
.setXmlBytes(getBytes("domain_restore.xml"))
.setModificationTime(now)
.build());
persistResource(
new HistoryEntry.Builder()
new HostHistory.Builder()
.setHostRepoId(persistDeletedHost("ns1.example.tld", now).getRepoId())
.setClientId(oteAccount1)
.setType(Type.HOST_DELETE)
.setXmlBytes(getBytes("host_delete.xml"))
.setModificationTime(now)
.build());
}
/**
* Sets up an incomplete OT&E registrar. It is missing the following entries:
*
* - DOMAIN_CREATES_IDN
* - DOMAIN_RESTORES
* - HOST_DELETES
* <ul>
* <li>DOMAIN_CREATES_IDN
* <li>DOMAIN_RESTORES
* <li>HOST_DELETES
* </ul>
*
* TODO(b/122830156): Have this replicate the exact OT&E workflow with the correct client IDs
* <p>TODO(b/122830156): Have this replicate the exact OT&E workflow with the correct client IDs
*/
public static void setupIncompleteOte(String baseClientId) throws IOException {
createTld("tld");
persistPremiumList("default_sandbox_list", "sandbox,USD 1000");
OteAccountBuilder.forClientId(baseClientId).addContact("email@example.com").buildAndPersist();
String oteAccount1 = String.format("%s-1", baseClientId);
DateTime now = DateTime.now(DateTimeZone.UTC);
persistResource(
new HistoryEntry.Builder()
new DomainHistory.Builder()
.setDomainRepoId(persistActiveDomain("exampleone.tld").getRepoId())
.setClientId(oteAccount1)
.setType(Type.DOMAIN_CREATE)
.setXmlBytes(getBytes("domain_create_sunrise.xml"))
.setModificationTime(now)
.build());
persistResource(
new HistoryEntry.Builder()
new DomainHistory.Builder()
.setDomainRepoId(persistActiveDomain("example-one.tld").getRepoId())
.setClientId(oteAccount1)
.setType(Type.DOMAIN_CREATE)
.setXmlBytes(getBytes("domain_create_claim_notice.xml"))
.setModificationTime(now)
.build());
persistResource(
new HistoryEntry.Builder()
new DomainHistory.Builder()
.setDomainRepoId(persistActiveDomain("example.tld").getRepoId())
.setClientId(oteAccount1)
.setType(Type.DOMAIN_CREATE)
.setXmlBytes(getBytes("domain_create_anchor_tenant_fee_standard.xml"))
.setModificationTime(now)
.build());
persistResource(
new HistoryEntry.Builder()
new DomainHistory.Builder()
.setDomainRepoId(persistActiveDomain("example.tld").getRepoId())
.setClientId(oteAccount1)
.setType(Type.DOMAIN_CREATE)
.setXmlBytes(getBytes("domain_create_dsdata.xml"))
.setModificationTime(now)
.build());
persistResource(
new HistoryEntry.Builder()
new DomainHistory.Builder()
.setDomainRepoId(persistDeletedDomain("example.tld", now).getRepoId())
.setClientId(oteAccount1)
.setType(Type.DOMAIN_DELETE)
.setXmlBytes(getBytes("domain_delete.xml"))
.setModificationTime(now)
.build());
persistResource(
new HistoryEntry.Builder()
new DomainHistory.Builder()
.setDomainRepoId(persistActiveDomain("example.tld").getRepoId())
.setClientId(oteAccount1)
.setType(Type.DOMAIN_TRANSFER_APPROVE)
.setXmlBytes(getBytes("domain_transfer_approve.xml"))
.setModificationTime(now)
.build());
persistResource(
new HistoryEntry.Builder()
new DomainHistory.Builder()
.setDomainRepoId(persistActiveDomain("example.tld").getRepoId())
.setClientId(oteAccount1)
.setType(Type.DOMAIN_TRANSFER_CANCEL)
.setXmlBytes(getBytes("domain_transfer_cancel.xml"))
.setModificationTime(now)
.build());
persistResource(
new HistoryEntry.Builder()
new DomainHistory.Builder()
.setDomainRepoId(persistActiveDomain("example.tld").getRepoId())
.setClientId(oteAccount1)
.setType(Type.DOMAIN_TRANSFER_REJECT)
.setXmlBytes(getBytes("domain_transfer_reject.xml"))
.setModificationTime(now)
.build());
persistResource(
new HistoryEntry.Builder()
new DomainHistory.Builder()
.setDomainRepoId(persistActiveDomain("example.tld").getRepoId())
.setClientId(oteAccount1)
.setType(Type.DOMAIN_TRANSFER_REQUEST)
.setXmlBytes(getBytes("domain_transfer_request.xml"))
.setModificationTime(now)
.build());
persistResource(
new HistoryEntry.Builder()
new DomainHistory.Builder()
.setDomainRepoId(persistActiveDomain("example.tld").getRepoId())
.setClientId(oteAccount1)
.setType(Type.DOMAIN_UPDATE)
.setXmlBytes(getBytes("domain_update_with_secdns.xml"))
.setModificationTime(now)
.build());
persistResource(
new HistoryEntry.Builder()
new HostHistory.Builder()
.setHostRepoId(persistActiveHost("example.tld").getRepoId())
.setClientId(oteAccount1)
.setType(Type.HOST_CREATE)
.setXmlBytes(getBytes("host_create_complete.xml"))
.setModificationTime(now)
.build());
// Persist 10 host updates for a total of 25 history entries. Since these also sort last by
// modification time, when these cause all tests to pass, only the first will be recorded and
// the rest will be skipped.
for (int i = 0; i < 10; i++) {
persistResource(
new HistoryEntry.Builder()
new HostHistory.Builder()
.setHostRepoId(persistActiveHost("example.tld").getRepoId())
.setClientId(oteAccount1)
.setType(Type.HOST_UPDATE)
.setXmlBytes(getBytes("host_update.xml"))

View file

@ -38,14 +38,15 @@ import google.registry.model.registrar.Registrar;
import google.registry.model.registrar.Registrar.State;
import google.registry.request.auth.AuthenticatedRegistrarAccessor.RegistrarAccessDeniedException;
import google.registry.testing.AppEngineExtension;
import google.registry.testing.DualDatabaseTest;
import google.registry.testing.InjectExtension;
import google.registry.testing.TestOfyAndSql;
import java.util.Optional;
import java.util.logging.Level;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.mockito.Mock;
@ -56,6 +57,7 @@ import org.mockito.quality.Strictness;
/** Unit tests for {@link AuthenticatedRegistrarAccessor}. */
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.LENIENT)
@DualDatabaseTest
class AuthenticatedRegistrarAccessorTest {
@RegisterExtension
@ -132,7 +134,7 @@ class AuthenticatedRegistrarAccessorTest {
}
/** Users are owners for registrars if and only if they are in the contacts for that registrar. */
@Test
@TestOfyAndSql
void getAllClientIdWithAccess_user() {
AuthenticatedRegistrarAccessor registrarAccessor =
new AuthenticatedRegistrarAccessor(
@ -144,7 +146,7 @@ class AuthenticatedRegistrarAccessorTest {
}
/** Logged out users don't have access to anything. */
@Test
@TestOfyAndSql
void getAllClientIdWithAccess_loggedOutUser() {
AuthenticatedRegistrarAccessor registrarAccessor =
new AuthenticatedRegistrarAccessor(
@ -165,7 +167,7 @@ class AuthenticatedRegistrarAccessorTest {
*
* <p>(in other words - they don't have OWNER access only to REAL registrars owned by others)
*/
@Test
@TestOfyAndSql
void getAllClientIdWithAccess_gaeAdmin() {
AuthenticatedRegistrarAccessor registrarAccessor =
new AuthenticatedRegistrarAccessor(
@ -197,7 +199,7 @@ class AuthenticatedRegistrarAccessorTest {
*
* <p>(in other words - they don't have OWNER access only to REAL registrars owned by others)
*/
@Test
@TestOfyAndSql
void getAllClientIdWithAccess_userInSupportGroup() {
when(groupsConnection.isMemberOfGroup("user@gmail.com", SUPPORT_GROUP.get())).thenReturn(true);
AuthenticatedRegistrarAccessor registrarAccessor =
@ -220,7 +222,7 @@ class AuthenticatedRegistrarAccessorTest {
}
/** Empty Support group email - skips check and doesn't generate the lazy. */
@Test
@TestOfyAndSql
void getAllClientIdWithAccess_emptySupportEmail_works() {
AuthenticatedRegistrarAccessor registrarAccessor =
new AuthenticatedRegistrarAccessor(
@ -233,7 +235,7 @@ class AuthenticatedRegistrarAccessorTest {
}
/** Support group check throws - continue anyway. */
@Test
@TestOfyAndSql
void getAllClientIdWithAccess_throwingGroupCheck_stillWorks() {
when(groupsConnection.isMemberOfGroup(any(), any())).thenThrow(new RuntimeException("blah"));
AuthenticatedRegistrarAccessor registrarAccessor =
@ -247,7 +249,7 @@ class AuthenticatedRegistrarAccessorTest {
}
/** Fail loading registrar if user doesn't have access to it. */
@Test
@TestOfyAndSql
void testGetRegistrarForUser_noAccess_isNotAdmin() {
expectGetRegistrarFailure(
REAL_CLIENT_ID_WITHOUT_CONTACT,
@ -256,7 +258,7 @@ class AuthenticatedRegistrarAccessorTest {
verify(lazyGroupsConnection).get();
}
@Test
@TestOfyAndSql
void testGetRegistrarForUser_registrarIsDisabled_isNotAdmin() {
persistResource(
Registrar.loadByClientId("TheRegistrar")
@ -272,7 +274,7 @@ class AuthenticatedRegistrarAccessorTest {
}
/** Fail loading registrar if user doesn't have access to it, even if it's not REAL. */
@Test
@TestOfyAndSql
void testGetRegistrarForUser_noAccess_isNotAdmin_notReal() {
expectGetRegistrarFailure(
OTE_CLIENT_ID_WITHOUT_CONTACT,
@ -282,7 +284,7 @@ class AuthenticatedRegistrarAccessorTest {
}
/** Fail loading registrar if there's no user associated with the request. */
@Test
@TestOfyAndSql
void testGetRegistrarForUser_noUser() {
expectGetRegistrarFailure(
CLIENT_ID_WITH_CONTACT,
@ -292,7 +294,7 @@ class AuthenticatedRegistrarAccessorTest {
}
/** Succeed loading registrar if user has access to it. */
@Test
@TestOfyAndSql
void testGetRegistrarForUser_inContacts_isNotAdmin() throws Exception {
expectGetRegistrarSuccess(
CLIENT_ID_WITH_CONTACT,
@ -302,7 +304,7 @@ class AuthenticatedRegistrarAccessorTest {
}
/** Succeed loading registrar if admin with access. */
@Test
@TestOfyAndSql
void testGetRegistrarForUser_inContacts_isAdmin() throws Exception {
expectGetRegistrarSuccess(
CLIENT_ID_WITH_CONTACT,
@ -312,7 +314,7 @@ class AuthenticatedRegistrarAccessorTest {
}
/** Succeed loading registrar for admin even if they aren't on the approved contacts list. */
@Test
@TestOfyAndSql
void testGetRegistrarForUser_notInContacts_isAdmin() throws Exception {
expectGetRegistrarSuccess(
REAL_CLIENT_ID_WITHOUT_CONTACT,
@ -321,7 +323,7 @@ class AuthenticatedRegistrarAccessorTest {
verifyNoInteractions(lazyGroupsConnection);
}
@Test
@TestOfyAndSql
void testGetRegistrarForUser_registrarIsDisabled_isAdmin() throws Exception {
persistResource(
Registrar.loadByClientId("NewRegistrar")
@ -337,7 +339,7 @@ class AuthenticatedRegistrarAccessorTest {
}
/** Succeed loading non-REAL registrar for admin. */
@Test
@TestOfyAndSql
void testGetRegistrarForUser_notInContacts_isAdmin_notReal() throws Exception {
expectGetRegistrarSuccess(
OTE_CLIENT_ID_WITHOUT_CONTACT,
@ -347,7 +349,7 @@ class AuthenticatedRegistrarAccessorTest {
}
/** Fail loading registrar even if admin, if registrar doesn't exist. */
@Test
@TestOfyAndSql
void testGetRegistrarForUser_doesntExist_isAdmin() {
expectGetRegistrarFailure(
"BadClientId",
@ -382,7 +384,7 @@ class AuthenticatedRegistrarAccessorTest {
}
/** guessClientIdForUser returns the first clientId in getAllClientIdWithRoles. */
@Test
@TestOfyAndSql
void testGuessClientIdForUser_hasAccess_returnsFirst() throws Exception {
AuthenticatedRegistrarAccessor registrarAccessor =
AuthenticatedRegistrarAccessor.createForTesting(
@ -395,7 +397,7 @@ class AuthenticatedRegistrarAccessorTest {
}
/** If a user doesn't have access to any registrars, guess fails. */
@Test
@TestOfyAndSql
void testGuessClientIdForUser_noAccess_fails() {
AuthenticatedRegistrarAccessor registrarAccessor =
AuthenticatedRegistrarAccessor.createForTesting(ImmutableSetMultimap.of());
@ -405,7 +407,7 @@ class AuthenticatedRegistrarAccessorTest {
.isEqualTo("TestUserId isn't associated with any registrar");
}
@Test
@TestOfyAndSql
void testNullness() {
new NullPointerTester()
.setDefault(HttpServletRequest.class, req)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Before After
Before After