Regenerate phone number identifiers when regenerating secondary table data

This commit is contained in:
Jon Chambers
2025-06-05 15:12:33 -04:00
committed by GitHub
parent 981d929f50
commit 1a7a446150
11 changed files with 111 additions and 50 deletions

View File

@@ -8,12 +8,16 @@ package org.whispersystems.textsecuregcm.storage;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import java.io.IOException;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicInteger;
@@ -21,6 +25,7 @@ import java.util.function.Supplier;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.whispersystems.textsecuregcm.identity.IdentityType;
import org.whispersystems.textsecuregcm.storage.DynamoDbExtensionSchema.Tables;
import org.whispersystems.textsecuregcm.util.CompletableFutureTestUtil;
import software.amazon.awssdk.services.dynamodb.model.TransactionCanceledException;
@@ -200,4 +205,25 @@ class PhoneNumberIdentifiersTest {
final UUID pni = phoneNumberIdentifiers.getPhoneNumberIdentifier(number).join();
assertEquals(List.of(number), phoneNumberIdentifiers.getPhoneNumber(pni).join());
}
@Test
void regeneratePhoneNumberIdentifierMappings() {
// libphonenumber 8.13.50 and on generate new-format numbers for Benin
final String newFormatBeninE164 = PhoneNumberUtil.getInstance()
.format(PhoneNumberUtil.getInstance().getExampleNumber("BJ"), PhoneNumberUtil.PhoneNumberFormat.E164);
final String oldFormatBeninE164 = newFormatBeninE164.replaceFirst("01", "");
final UUID phoneNumberIdentifier = UUID.randomUUID();
final Account account = mock(Account.class);
when(account.getNumber()).thenReturn(newFormatBeninE164);
when(account.getIdentifier(IdentityType.PNI)).thenReturn(phoneNumberIdentifier);
phoneNumberIdentifiers.regeneratePhoneNumberIdentifierMappings(account).join();
assertEquals(phoneNumberIdentifier, phoneNumberIdentifiers.getPhoneNumberIdentifier(newFormatBeninE164).join());
assertEquals(phoneNumberIdentifier, phoneNumberIdentifiers.getPhoneNumberIdentifier(oldFormatBeninE164).join());
assertEquals(Set.of(newFormatBeninE164, oldFormatBeninE164),
new HashSet<>(phoneNumberIdentifiers.getPhoneNumber(phoneNumberIdentifier).join()));
}
}

View File

@@ -64,8 +64,7 @@ class FinishPushNotificationExperimentCommandTest {
new PushNotificationExperimentSample<>(accountIdentifier, deviceId, true, "test", "test"));
});
commandDependencies = new CommandDependencies(null,
accountsManager,
commandDependencies = new CommandDependencies(accountsManager,
null,
null,
null,
@@ -84,6 +83,7 @@ class FinishPushNotificationExperimentCommandTest {
null,
null,
null,
null,
null);
//noinspection unchecked

View File

@@ -51,7 +51,6 @@ class NotifyIdleDevicesCommandTest {
null,
null,
null,
null,
messagesManager,
null,
null,
@@ -66,6 +65,7 @@ class NotifyIdleDevicesCommandTest {
null,
null,
null,
null,
null);
this.idleDeviceNotificationScheduler = idleDeviceNotificationScheduler;

View File

@@ -19,19 +19,20 @@ import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.whispersystems.textsecuregcm.storage.Account;
import org.whispersystems.textsecuregcm.storage.Accounts;
import org.whispersystems.textsecuregcm.storage.DynamoDbRecoveryManager;
import reactor.core.publisher.Flux;
class RegenerateAccountConstraintDataCommandTest {
class RegenerateSecondaryDynamoDbTableDataCommandTest {
private Accounts accounts;
private DynamoDbRecoveryManager dynamoDbRecoveryManager;
private static class TestRegenerateAccountConstraintDataCommand extends RegenerateAccountConstraintDataCommand {
private static class TestRegenerateSecondaryDynamoDbTableDataCommand extends RegenerateSecondaryDynamoDbTableDataCommand {
private final CommandDependencies commandDependencies;
private final Namespace namespace;
TestRegenerateAccountConstraintDataCommand(final Accounts accounts, final boolean dryRun) {
commandDependencies = new CommandDependencies(accounts,
TestRegenerateSecondaryDynamoDbTableDataCommand(final DynamoDbRecoveryManager dynamoDbRecoveryManager, final boolean dryRun) {
commandDependencies = new CommandDependencies(null,
null,
null,
null,
@@ -51,12 +52,12 @@ class RegenerateAccountConstraintDataCommandTest {
null,
null,
null,
null);
dynamoDbRecoveryManager);
namespace = new Namespace(Map.of(
RegenerateAccountConstraintDataCommand.DRY_RUN_ARGUMENT, dryRun,
RegenerateAccountConstraintDataCommand.MAX_CONCURRENCY_ARGUMENT, 16,
RegenerateAccountConstraintDataCommand.RETRIES_ARGUMENT, 3));
RegenerateSecondaryDynamoDbTableDataCommand.DRY_RUN_ARGUMENT, dryRun,
RegenerateSecondaryDynamoDbTableDataCommand.MAX_CONCURRENCY_ARGUMENT, 16,
RegenerateSecondaryDynamoDbTableDataCommand.RETRIES_ARGUMENT, 3));
}
@Override
@@ -72,9 +73,9 @@ class RegenerateAccountConstraintDataCommandTest {
@BeforeEach
void setUp() {
accounts = mock(Accounts.class);
dynamoDbRecoveryManager = mock(DynamoDbRecoveryManager.class);
when(accounts.regenerateConstraints(any())).thenReturn(CompletableFuture.completedFuture(null));
when(dynamoDbRecoveryManager.regenerateData(any())).thenReturn(CompletableFuture.completedFuture(null));
}
@ParameterizedTest
@@ -82,15 +83,15 @@ class RegenerateAccountConstraintDataCommandTest {
void crawlAccounts(final boolean dryRun) {
final Account account = mock(Account.class);
final RegenerateAccountConstraintDataCommand regenerateAccountConstraintDataCommand =
new TestRegenerateAccountConstraintDataCommand(accounts, dryRun);
final RegenerateSecondaryDynamoDbTableDataCommand regenerateSecondaryDynamoDbTableDataCommand =
new TestRegenerateSecondaryDynamoDbTableDataCommand(dynamoDbRecoveryManager, dryRun);
regenerateAccountConstraintDataCommand.crawlAccounts(Flux.just(account));
regenerateSecondaryDynamoDbTableDataCommand.crawlAccounts(Flux.just(account));
if (!dryRun) {
verify(accounts).regenerateConstraints(account);
verify(dynamoDbRecoveryManager).regenerateData(account);
}
verifyNoMoreInteractions(accounts);
verifyNoMoreInteractions(dynamoDbRecoveryManager);
}
}

View File

@@ -64,7 +64,6 @@ class StartPushNotificationExperimentCommandTest {
null,
null,
null,
null,
pushNotificationExperimentSamples,
null,
null,
@@ -73,6 +72,7 @@ class StartPushNotificationExperimentCommandTest {
null,
null,
null,
null,
null);
}