1
0
mirror of https://github.com/google/nomulus synced 2026-04-24 02:00:50 +00:00

Add RST support in Sandbox (#2917)

* Add RST support in Sandbox

Added RST test label files as resources.

Added a RstTmchUtils class that loads appropriate labels according to
TLD pattern.

Temporarily changed label fetching in production to include the TLD
string, so that the new class may know which set of labels to use.

* Addressing comments

* Addressing comments
This commit is contained in:
Weimin Yu
2025-12-30 20:59:28 +00:00
committed by GitHub
parent 2562d582f3
commit f9c22ff1c5
13 changed files with 456 additions and 9 deletions

View File

@@ -0,0 +1,161 @@
// Copyright 2025 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.tmch;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.persistence.transaction.TransactionManagerFactory.tm;
import static google.registry.util.RegistryEnvironment.PRODUCTION;
import static google.registry.util.RegistryEnvironment.SANDBOX;
import static org.joda.time.DateTime.now;
import static org.joda.time.DateTimeZone.UTC;
import com.google.common.base.Splitter;
import google.registry.model.smd.SignedMarkRevocationList;
import google.registry.model.smd.SignedMarkRevocationListDao;
import google.registry.model.tmch.ClaimsListDao;
import google.registry.persistence.transaction.JpaTestExtensions;
import google.registry.testing.FakeClock;
import google.registry.util.RegistryEnvironment;
import java.util.stream.Stream;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
public class RstTmchUtilsIntTest {
private final FakeClock clock = new FakeClock();
@RegisterExtension
final JpaTestExtensions.JpaIntegrationTestExtension jpa =
new JpaTestExtensions.Builder().withClock(clock).buildIntegrationTestExtension();
private static final String TMCH_CLAIM_LABEL = "tmch";
// RST label found in *.rst.dnl.csv resources. Currently both files are identical
private static final String RST_CLAIM_LABEL = "test--validate";
private static final String TMCH_SMD_ID = "tmch";
// RST label found in *.rst.smdrl.csv resources. Currently both files are identical
private static final String RST_SMD_ID = "0000001761385117375880-65535";
private static final String TMCH_DNL =
"""
1,2024-09-13T02:21:12.0Z
DNL,lookup-key,insertion-datetime
LABEL,2024091300/6/a/b/arJyPPf2CK7f21bVGne0qMgW0000000001,2024-09-13T02:21:12.0Z
"""
.replace("LABEL", TMCH_CLAIM_LABEL);
private static final String TMCH_SMDRL =
"""
1,2022-11-22T01:49:36.9Z
smd-id,insertion-datetime
ID,2013-07-15T00:00:00.0Z
"""
.replace("ID", TMCH_SMD_ID);
@BeforeEach
void setup() throws Exception {
Splitter lineSplitter = Splitter.on("\n").omitEmptyStrings().trimResults();
tm().transact(
() -> ClaimsListDao.save(ClaimsListParser.parse(lineSplitter.splitToList(TMCH_DNL))));
tm().transact(
() ->
SignedMarkRevocationListDao.save(
SmdrlCsvParser.parse(lineSplitter.splitToList(TMCH_SMDRL))));
}
@ParameterizedTest
@MethodSource("provideTestCases")
@SuppressWarnings("unused") // testCaseName
void getClaimsList_production(String testCaseName, String tld) {
var currEnv = RegistryEnvironment.get();
try {
PRODUCTION.setup();
var claimsList = ClaimsListDao.get(tld);
assertThat(claimsList.getClaimKey(TMCH_CLAIM_LABEL)).isPresent();
assertThat(claimsList.getClaimKey(RST_CLAIM_LABEL)).isEmpty();
} finally {
currEnv.setup();
}
}
@ParameterizedTest
@MethodSource("provideTestCases")
@SuppressWarnings("unused") // testCaseName
void getSmdrList_production(String testCaseName, String tld) {
var currEnv = RegistryEnvironment.get();
try {
PRODUCTION.setup();
var smdrl = SignedMarkRevocationList.get(tld);
assertThat(smdrl.isSmdRevoked(TMCH_SMD_ID, now(UTC))).isTrue();
assertThat(smdrl.isSmdRevoked(RST_SMD_ID, now(UTC))).isFalse();
assertThat(smdrl.size()).isEqualTo(1);
} finally {
currEnv.setup();
}
}
@ParameterizedTest
@MethodSource("provideTestCases")
@SuppressWarnings("unused") // testCaseName
void getClaimsList_sandbox(String testCaseName, String tld) {
var currEnv = RegistryEnvironment.get();
try {
SANDBOX.setup();
var claimsList = ClaimsListDao.get(tld);
if (tld.equals("app")) {
assertThat(claimsList.getClaimKey(TMCH_CLAIM_LABEL)).isPresent();
assertThat(claimsList.getClaimKey(RST_CLAIM_LABEL)).isEmpty();
} else {
assertThat(claimsList.getClaimKey(TMCH_CLAIM_LABEL)).isEmpty();
// Currently ote and prod have the same data.
assertThat(claimsList.getClaimKey(RST_CLAIM_LABEL)).isPresent();
}
} finally {
currEnv.setup();
}
}
@ParameterizedTest
@MethodSource("provideTestCases")
@SuppressWarnings("unused") // testCaseName
void getSmdrList_sandbox(String testCaseName, String tld) {
var currEnv = RegistryEnvironment.get();
try {
SANDBOX.setup();
var smdrList = SignedMarkRevocationList.get(tld);
if (tld.equals("app")) {
assertThat(smdrList.size()).isEqualTo(1);
assertThat(smdrList.isSmdRevoked(TMCH_SMD_ID, now(UTC))).isTrue();
assertThat(smdrList.isSmdRevoked(RST_SMD_ID, now(UTC))).isFalse();
} else {
// Currently ote and prod have the same data.
assertThat(smdrList.size()).isEqualTo(5);
assertThat(smdrList.isSmdRevoked(TMCH_SMD_ID, now())).isFalse();
assertThat(smdrList.isSmdRevoked(RST_SMD_ID, now())).isTrue();
}
} finally {
currEnv.setup();
}
}
private static Stream<Arguments> provideTestCases() {
return Stream.of(
Arguments.of("NotRST", "app"),
Arguments.of("OTE", "cc-rst-test-tld-1"),
Arguments.of("PROD", "zz--idn-123"));
}
}

View File

@@ -0,0 +1,117 @@
// Copyright 2025 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.tmch;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.tmch.RstTmchUtils.getClaimsList;
import static google.registry.tmch.RstTmchUtils.getSmdrList;
import static google.registry.util.RegistryEnvironment.PRODUCTION;
import static google.registry.util.RegistryEnvironment.SANDBOX;
import google.registry.util.RegistryEnvironment;
import java.util.stream.Stream;
import org.joda.time.DateTime;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
public class RstTmchUtilsTest {
@ParameterizedTest
@MethodSource("provideTestCases")
@SuppressWarnings("unused") // testCaseName
void getClaimsList_production(String testCaseName, String tld) {
var currEnv = RegistryEnvironment.get();
try {
PRODUCTION.setup();
assertThat(getClaimsList(tld)).isEmpty();
} finally {
currEnv.setup();
}
}
@ParameterizedTest
@MethodSource("provideTestCases")
@SuppressWarnings("unused") // testCaseName
void getSmdrList_production(String testCaseName, String tld) {
var currEnv = RegistryEnvironment.get();
try {
PRODUCTION.setup();
assertThat(getSmdrList(tld)).isEmpty();
} finally {
currEnv.setup();
}
}
@ParameterizedTest
@MethodSource("provideTestCases")
@SuppressWarnings("unused") // testCaseName
void getClaimsList_sandbox(String testCaseName, String tld) {
var currEnv = RegistryEnvironment.get();
try {
SANDBOX.setup();
var claimsListOptional = getClaimsList(tld);
if (tld.equals("app")) {
assertThat(claimsListOptional).isEmpty();
} else {
// Currently ote and prod have the same data.
var claimsList = claimsListOptional.get();
assertThat(claimsList.getClaimKey("test-and-validate")).isPresent();
var labelsToKeys = claimsList.getLabelsToKeys();
assertThat(labelsToKeys).hasSize(8);
assertThat(labelsToKeys)
.containsEntry(
"test---validate", "2024091300/6/a/b/arJyPPf2CK7f21bVGne0qMgW0000000001");
}
} finally {
currEnv.setup();
}
}
@ParameterizedTest
@MethodSource("provideTestCases")
@SuppressWarnings("unused") // testCaseName
void getSmdrList_sandbox(String testCaseName, String tld) {
var currEnv = RegistryEnvironment.get();
try {
SANDBOX.setup();
var smdrListOptional = getSmdrList(tld);
if (tld.equals("app")) {
assertThat(smdrListOptional).isEmpty();
} else {
// Currently ote and prod have the same data.
var smdrList = smdrListOptional.get();
assertThat(smdrList.size()).isEqualTo(5);
assertThat(
smdrList.isSmdRevoked(
"000000541526299609231-65535", DateTime.parse("2018-05-14T17:52:23.6Z")))
.isFalse();
assertThat(
smdrList.isSmdRevoked(
"000000541526299609231-65535", DateTime.parse("2018-05-14T17:52:23.7Z")))
.isTrue();
}
} finally {
currEnv.setup();
}
}
private static Stream<Arguments> provideTestCases() {
return Stream.of(
Arguments.of("NotRST", "app"),
Arguments.of("OTE", "cc-rst-test-tld-1"),
Arguments.of("PROD", "zz--idn-123"));
}
}

View File

@@ -57,7 +57,7 @@ class TmchTestDataExpirationTest {
String tmchData = loadFile(TmchTestDataExpirationTest.class, filePath);
EncodedSignedMark smd = TmchData.readEncodedSignedMark(tmchData);
try {
tmchUtils.verifyEncodedSignedMark(smd, DateTime.now(UTC));
tmchUtils.verifyEncodedSignedMark("", smd, DateTime.now(UTC));
} catch (EppException e) {
throw new AssertionError("Error verifying signed mark " + filePath, e);
}