Add excluded E164s configuration to pre-registration experiment

This commit is contained in:
Chris Eager 2021-07-29 11:29:41 -05:00 committed by Chris Eager
parent df9c0051c9
commit 51b7a8d868
4 changed files with 50 additions and 22 deletions

View File

@ -20,12 +20,16 @@ public class DynamicPreRegistrationExperimentEnrollmentConfiguration {
@JsonProperty @JsonProperty
@Valid @Valid
private Set<String> excludedCountryCodes = Collections.emptySet(); private Set<String> excludedE164s = Collections.emptySet();
@JsonProperty @JsonProperty
@Valid @Valid
private Set<String> includedCountryCodes = Collections.emptySet(); private Set<String> includedCountryCodes = Collections.emptySet();
@JsonProperty
@Valid
private Set<String> excludedCountryCodes = Collections.emptySet();
@JsonProperty @JsonProperty
@Valid @Valid
@Min(0) @Min(0)
@ -36,14 +40,18 @@ public class DynamicPreRegistrationExperimentEnrollmentConfiguration {
return enrolledE164s; return enrolledE164s;
} }
public Set<String> getExcludedCountryCodes() { public Set<String> getExcludedE164s() {
return excludedCountryCodes; return excludedE164s;
} }
public Set<String> getIncludedCountryCodes() { public Set<String> getIncludedCountryCodes() {
return includedCountryCodes; return includedCountryCodes;
} }
public Set<String> getExcludedCountryCodes() {
return excludedCountryCodes;
}
public int getEnrollmentPercentage() { public int getEnrollmentPercentage() {
return enrollmentPercentage; return enrollmentPercentage;
} }

View File

@ -47,6 +47,10 @@ public class ExperimentEnrollmentManager {
return true; return true;
} }
if (config.getExcludedE164s().contains(e164)) {
return false;
}
{ {
final String countryCode = Util.getCountryCode(e164); final String countryCode = Util.getCountryCode(e164);

View File

@ -94,6 +94,9 @@ class DynamicConfigurationTest {
" enrolledE164s:\n" + " enrolledE164s:\n" +
" - +120255551212\n" + " - +120255551212\n" +
" - +3655323174\n" + " - +3655323174\n" +
" excludedE164s:\n" +
" - +120255551213\n" +
" - +3655323175\n" +
" enrollmentPercentage: 46\n" + " enrollmentPercentage: 46\n" +
" excludedCountryCodes:\n" + " excludedCountryCodes:\n" +
" - 47\n" + " - 47\n" +
@ -118,6 +121,8 @@ class DynamicConfigurationTest {
percentageOnly.get().getEnrollmentPercentage()); percentageOnly.get().getEnrollmentPercentage());
assertEquals(Collections.emptySet(), assertEquals(Collections.emptySet(),
percentageOnly.get().getEnrolledE164s()); percentageOnly.get().getEnrolledE164s());
assertEquals(Collections.emptySet(),
percentageOnly.get().getExcludedE164s());
} }
{ {
@ -129,6 +134,8 @@ class DynamicConfigurationTest {
e164sCountryCodesAndPercentage.get().getEnrollmentPercentage()); e164sCountryCodesAndPercentage.get().getEnrollmentPercentage());
assertEquals(Set.of("+120255551212", "+3655323174"), assertEquals(Set.of("+120255551212", "+3655323174"),
e164sCountryCodesAndPercentage.get().getEnrolledE164s()); e164sCountryCodesAndPercentage.get().getEnrolledE164s());
assertEquals(Set.of("+120255551213", "+3655323175"),
e164sCountryCodesAndPercentage.get().getExcludedE164s());
assertEquals(Set.of("47"), assertEquals(Set.of("47"),
e164sCountryCodesAndPercentage.get().getExcludedCountryCodes()); e164sCountryCodesAndPercentage.get().getExcludedCountryCodes());
assertEquals(Set.of("56"), assertEquals(Set.of("56"),
@ -142,6 +149,7 @@ class DynamicConfigurationTest {
assertEquals(0, e164sAndExcludedCodes.get().getEnrollmentPercentage()); assertEquals(0, e164sAndExcludedCodes.get().getEnrollmentPercentage());
assertEquals(Set.of("+120255551212"), assertEquals(Set.of("+120255551212"),
e164sAndExcludedCodes.get().getEnrolledE164s()); e164sAndExcludedCodes.get().getEnrolledE164s());
assertTrue(e164sAndExcludedCodes.get().getExcludedE164s().isEmpty());
assertEquals(Set.of("47"), assertEquals(Set.of("47"),
e164sAndExcludedCodes.get().getExcludedCountryCodes()); e164sAndExcludedCodes.get().getExcludedCountryCodes());
} }

View File

@ -5,7 +5,9 @@
package org.whispersystems.textsecuregcm.experiment; package org.whispersystems.textsecuregcm.experiment;
import static org.junit.Assert.*; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@ -37,7 +39,8 @@ class ExperimentEnrollmentManagerTest {
private static final UUID ACCOUNT_UUID = UUID.randomUUID(); private static final UUID ACCOUNT_UUID = UUID.randomUUID();
private static final String UUID_EXPERIMENT_NAME = "uuid_test"; private static final String UUID_EXPERIMENT_NAME = "uuid_test";
private static final String E164 = "+12025551212"; private static final String ENROLLED_164 = "+12025551212";
private static final String EXCLUDED_164 = "+18005551212";
private static final String E164_EXPERIMENT_NAME = "e164_test"; private static final String E164_EXPERIMENT_NAME = "e164_test";
@BeforeEach @BeforeEach
@ -82,35 +85,40 @@ class ExperimentEnrollmentManagerTest {
@ParameterizedTest @ParameterizedTest
@MethodSource @MethodSource
void testIsEnrolled_PreRegistrationExperiment(final String e164, final String experimentName, void testIsEnrolled_PreRegistrationExperiment(final String e164, final String experimentName,
final Set<String> enrolledE164s, final Set<String> includedCountryCodes, final Set<String> excludedCountryCodes, final Set<String> enrolledE164s, final Set<String> excludedE164s, final Set<String> includedCountryCodes,
final Set<String> excludedCountryCodes,
final int enrollmentPercentage, final int enrollmentPercentage,
final boolean expectedEnrolled, final String message) { final boolean expectEnrolled, final String message) {
when(preRegistrationExperimentEnrollmentConfiguration.getEnrolledE164s()).thenReturn(enrolledE164s); when(preRegistrationExperimentEnrollmentConfiguration.getEnrolledE164s()).thenReturn(enrolledE164s);
when(preRegistrationExperimentEnrollmentConfiguration.getExcludedE164s()).thenReturn(excludedE164s);
when(preRegistrationExperimentEnrollmentConfiguration.getEnrollmentPercentage()).thenReturn(enrollmentPercentage); when(preRegistrationExperimentEnrollmentConfiguration.getEnrollmentPercentage()).thenReturn(enrollmentPercentage);
when(preRegistrationExperimentEnrollmentConfiguration.getIncludedCountryCodes()).thenReturn(includedCountryCodes); when(preRegistrationExperimentEnrollmentConfiguration.getIncludedCountryCodes()).thenReturn(includedCountryCodes);
when(preRegistrationExperimentEnrollmentConfiguration.getExcludedCountryCodes()).thenReturn(excludedCountryCodes); when(preRegistrationExperimentEnrollmentConfiguration.getExcludedCountryCodes()).thenReturn(excludedCountryCodes);
assertEquals(message, expectedEnrolled, experimentEnrollmentManager.isEnrolled(e164, experimentName)); assertEquals(expectEnrolled, experimentEnrollmentManager.isEnrolled(e164, experimentName), message);
} }
@SuppressWarnings("unused")
static Stream<Arguments> testIsEnrolled_PreRegistrationExperiment() { static Stream<Arguments> testIsEnrolled_PreRegistrationExperiment() {
return Stream.of( return Stream.of(
Arguments.of(E164, E164_EXPERIMENT_NAME, Collections.emptySet(), Collections.emptySet(), Arguments.of(ENROLLED_164, E164_EXPERIMENT_NAME, Collections.emptySet(), Collections.emptySet(),
Collections.emptySet(), 0, false, "default configuration expects no enrollment"), Collections.emptySet(), Collections.emptySet(), 0, false, "default configuration expects no enrollment"),
Arguments Arguments.of(ENROLLED_164, E164_EXPERIMENT_NAME + "-unrelated-experiment", Collections.emptySet(),
.of(E164, E164_EXPERIMENT_NAME + "-unrelated-experiment", Collections.emptySet(), Collections.emptySet(), Collections.emptySet(), Collections.emptySet(), Collections.emptySet(), 0, false,
Collections.emptySet(), 0, false, "unknown experiment expects no enrollment"), "unknown experiment expects no enrollment"),
Arguments.of(E164, E164_EXPERIMENT_NAME, Set.of(E164), Collections.emptySet(), Arguments.of(ENROLLED_164, E164_EXPERIMENT_NAME, Set.of(ENROLLED_164), Set.of(EXCLUDED_164),
Collections.emptySet(), 0, true, "explicitly enrolled E164 overrides 0% rollout"), Collections.emptySet(), Collections.emptySet(), 0, true, "explicitly enrolled E164 overrides 0% rollout"),
Arguments.of(E164, E164_EXPERIMENT_NAME, Set.of(E164), Collections.emptySet(), Arguments.of(ENROLLED_164, E164_EXPERIMENT_NAME, Set.of(ENROLLED_164), Set.of(EXCLUDED_164),
Set.of("1"), 0, true, "explicitly enrolled E164 overrides excluded country code"), Collections.emptySet(), Set.of("1"), 0, true, "explicitly enrolled E164 overrides excluded country code"),
Arguments.of(E164, E164_EXPERIMENT_NAME, Collections.emptySet(), Set.of("1"), Arguments.of(ENROLLED_164, E164_EXPERIMENT_NAME, Collections.emptySet(), Collections.emptySet(), Set.of("1"),
Collections.emptySet(), 0, true, "included country code overrides 0% rollout"), Collections.emptySet(), 0, true, "included country code overrides 0% rollout"),
Arguments.of(E164, E164_EXPERIMENT_NAME, Collections.emptySet(), Collections.emptySet(), Arguments.of(EXCLUDED_164, E164_EXPERIMENT_NAME, Collections.emptySet(), Set.of(EXCLUDED_164), Set.of("1"),
Set.of("1"), 100, false, "excluded country code overrides 100% rollout"), Collections.emptySet(), 100, false, "excluded E164 overrides 100% rollout"),
Arguments.of(E164, E164_EXPERIMENT_NAME, Collections.emptySet(), Collections.emptySet(), Arguments.of(ENROLLED_164, E164_EXPERIMENT_NAME, Collections.emptySet(), Collections.emptySet(),
Collections.emptySet(), 100, true, "enrollment expected for 100% rollout") Collections.emptySet(), Set.of("1"), 100, false, "excluded country code overrides 100% rollout"),
Arguments.of(ENROLLED_164, E164_EXPERIMENT_NAME, Collections.emptySet(), Collections.emptySet(),
Collections.emptySet(), Collections.emptySet(), 100, true, "enrollment expected for 100% rollout")
); );
} }
} }