mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-21 08:28:11 +01:00
Add support for UUID buckets in remote config
This commit is contained in:
@@ -22,9 +22,11 @@ import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import io.dropwizard.auth.PolymorphicAuthValueFactoryProvider;
|
||||
import io.dropwizard.testing.junit.ResourceTestRule;
|
||||
@@ -52,9 +54,22 @@ public class RemoteConfigControllerTest {
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
when(remoteConfigsManager.getAll()).thenReturn(new LinkedList<>() {{
|
||||
add(new RemoteConfig("android.stickers", 25));
|
||||
add(new RemoteConfig("ios.stickers", 50));
|
||||
add(new RemoteConfig("always.true", 100));
|
||||
add(new RemoteConfig("android.stickers", 25, new HashSet<>() {{
|
||||
add(AuthHelper.DISABLED_UUID);
|
||||
add(AuthHelper.INVALID_UUID);
|
||||
}}));
|
||||
|
||||
add(new RemoteConfig("ios.stickers", 50, new HashSet<>() {{
|
||||
|
||||
}}));
|
||||
|
||||
add(new RemoteConfig("always.true", 100, new HashSet<>() {{
|
||||
|
||||
}}));
|
||||
|
||||
add(new RemoteConfig("only.special", 0, new HashSet<>() {{
|
||||
add(AuthHelper.VALID_UUID);
|
||||
}}));
|
||||
}});
|
||||
}
|
||||
|
||||
@@ -68,13 +83,33 @@ public class RemoteConfigControllerTest {
|
||||
|
||||
verify(remoteConfigsManager, times(1)).getAll();
|
||||
|
||||
assertThat(configuration.getConfig().size()).isEqualTo(3);
|
||||
assertThat(configuration.getConfig().size()).isEqualTo(4);
|
||||
assertThat(configuration.getConfig().get(0).getName()).isEqualTo("android.stickers");
|
||||
assertThat(configuration.getConfig().get(1).getName()).isEqualTo("ios.stickers");
|
||||
assertThat(configuration.getConfig().get(2).getName()).isEqualTo("always.true");
|
||||
assertThat(configuration.getConfig().get(2).isEnabled()).isEqualTo(true);
|
||||
assertThat(configuration.getConfig().get(3).isEnabled()).isEqualTo(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRetrieveConfigNotSpecial() {
|
||||
UserRemoteConfigList configuration = resources.getJerseyTest()
|
||||
.target("/v1/config/")
|
||||
.request()
|
||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER_TWO, AuthHelper.VALID_PASSWORD_TWO))
|
||||
.get(UserRemoteConfigList.class);
|
||||
|
||||
verify(remoteConfigsManager, times(1)).getAll();
|
||||
|
||||
assertThat(configuration.getConfig().size()).isEqualTo(4);
|
||||
assertThat(configuration.getConfig().get(0).getName()).isEqualTo("android.stickers");
|
||||
assertThat(configuration.getConfig().get(1).getName()).isEqualTo("ios.stickers");
|
||||
assertThat(configuration.getConfig().get(2).getName()).isEqualTo("always.true");
|
||||
assertThat(configuration.getConfig().get(2).isEnabled()).isEqualTo(true);
|
||||
assertThat(configuration.getConfig().get(3).isEnabled()).isEqualTo(false);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testRetrieveConfigUnauthorized() {
|
||||
Response response = resources.getJerseyTest()
|
||||
@@ -95,7 +130,7 @@ public class RemoteConfigControllerTest {
|
||||
.target("/v1/config")
|
||||
.request()
|
||||
.header("Config-Token", "foo")
|
||||
.put(Entity.entity(new RemoteConfig("android.stickers", 88), MediaType.APPLICATION_JSON_TYPE));
|
||||
.put(Entity.entity(new RemoteConfig("android.stickers", 88, new HashSet<>()), MediaType.APPLICATION_JSON_TYPE));
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(204);
|
||||
|
||||
@@ -105,6 +140,7 @@ public class RemoteConfigControllerTest {
|
||||
|
||||
assertThat(captor.getValue().getName()).isEqualTo("android.stickers");
|
||||
assertThat(captor.getValue().getPercentage()).isEqualTo(88);
|
||||
assertThat(captor.getValue().getUuids()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -113,7 +149,19 @@ public class RemoteConfigControllerTest {
|
||||
.target("/v1/config")
|
||||
.request()
|
||||
.header("Config-Token", "baz")
|
||||
.put(Entity.entity(new RemoteConfig("android.stickers", 88), MediaType.APPLICATION_JSON_TYPE));
|
||||
.put(Entity.entity(new RemoteConfig("android.stickers", 88, new HashSet<>()), MediaType.APPLICATION_JSON_TYPE));
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(401);
|
||||
|
||||
verifyNoMoreInteractions(remoteConfigsManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSetConfigMissingUnauthorized() {
|
||||
Response response = resources.getJerseyTest()
|
||||
.target("/v1/config")
|
||||
.request()
|
||||
.put(Entity.entity(new RemoteConfig("android.stickers", 88, new HashSet<>()), MediaType.APPLICATION_JSON_TYPE));
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(401);
|
||||
|
||||
@@ -126,7 +174,7 @@ public class RemoteConfigControllerTest {
|
||||
.target("/v1/config")
|
||||
.request()
|
||||
.header("Config-Token", "foo")
|
||||
.put(Entity.entity(new RemoteConfig("android-stickers", 88), MediaType.APPLICATION_JSON_TYPE));
|
||||
.put(Entity.entity(new RemoteConfig("android-stickers", 88, new HashSet<>()), MediaType.APPLICATION_JSON_TYPE));
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(422);
|
||||
|
||||
@@ -139,7 +187,7 @@ public class RemoteConfigControllerTest {
|
||||
.target("/v1/config")
|
||||
.request()
|
||||
.header("Config-Token", "foo")
|
||||
.put(Entity.entity(new RemoteConfig("", 88), MediaType.APPLICATION_JSON_TYPE));
|
||||
.put(Entity.entity(new RemoteConfig("", 88, new HashSet<>()), MediaType.APPLICATION_JSON_TYPE));
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(422);
|
||||
|
||||
@@ -186,7 +234,7 @@ public class RemoteConfigControllerTest {
|
||||
int count = enabledMap.getOrDefault(config.getName(), 0);
|
||||
int random = new SecureRandom().nextInt(iterations);
|
||||
|
||||
if (RemoteConfigController.isInBucket(digest, ("+121322" + String.format("%05d", random)).getBytes(), config.getName().getBytes(), config.getPercentage())) {
|
||||
if (RemoteConfigController.isInBucket(digest, UUID.randomUUID(), config.getName().getBytes(), config.getPercentage(), new HashSet<>())) {
|
||||
count++;
|
||||
}
|
||||
|
||||
|
||||
@@ -12,9 +12,12 @@ import org.whispersystems.textsecuregcm.storage.FaultTolerantDatabase;
|
||||
import org.whispersystems.textsecuregcm.storage.RemoteConfig;
|
||||
import org.whispersystems.textsecuregcm.storage.RemoteConfigs;
|
||||
import org.whispersystems.textsecuregcm.storage.RemoteConfigsManager;
|
||||
import org.whispersystems.textsecuregcm.tests.util.AuthHelper;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import io.dropwizard.auth.Auth;
|
||||
import static org.assertj.core.api.Java6Assertions.assertThat;
|
||||
|
||||
public class RemoteConfigsManagerTest {
|
||||
@@ -33,9 +36,11 @@ public class RemoteConfigsManagerTest {
|
||||
|
||||
@Test
|
||||
public void testUpdate() throws InterruptedException {
|
||||
remoteConfigs.set(new RemoteConfig("android.stickers", 50));
|
||||
remoteConfigs.set(new RemoteConfig("ios.stickers", 50));
|
||||
remoteConfigs.set(new RemoteConfig("ios.stickers", 75));
|
||||
remoteConfigs.set(new RemoteConfig("android.stickers", 50, new HashSet<>() {{
|
||||
add(AuthHelper.VALID_UUID);
|
||||
}}));
|
||||
remoteConfigs.set(new RemoteConfig("ios.stickers", 50, new HashSet<>()));
|
||||
remoteConfigs.set(new RemoteConfig("ios.stickers", 75, new HashSet<>()));
|
||||
|
||||
Thread.sleep(501);
|
||||
|
||||
@@ -44,8 +49,12 @@ public class RemoteConfigsManagerTest {
|
||||
assertThat(results.size()).isEqualTo(2);
|
||||
assertThat(results.get(0).getName()).isEqualTo("android.stickers");
|
||||
assertThat(results.get(0).getPercentage()).isEqualTo(50);
|
||||
assertThat(results.get(0).getUuids().size()).isEqualTo(1);
|
||||
assertThat(results.get(0).getUuids().contains(AuthHelper.VALID_UUID)).isTrue();
|
||||
|
||||
assertThat(results.get(1).getName()).isEqualTo("ios.stickers");
|
||||
assertThat(results.get(1).getPercentage()).isEqualTo(75);
|
||||
assertThat(results.get(1).getUuids()).isEmpty();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -11,10 +11,13 @@ import org.whispersystems.textsecuregcm.configuration.CircuitBreakerConfiguratio
|
||||
import org.whispersystems.textsecuregcm.storage.FaultTolerantDatabase;
|
||||
import org.whispersystems.textsecuregcm.storage.RemoteConfig;
|
||||
import org.whispersystems.textsecuregcm.storage.RemoteConfigs;
|
||||
import org.whispersystems.textsecuregcm.tests.util.AuthHelper;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import io.dropwizard.auth.Auth;
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
|
||||
public class RemoteConfigsTest {
|
||||
@@ -31,35 +34,51 @@ public class RemoteConfigsTest {
|
||||
|
||||
@Test
|
||||
public void testStore() throws SQLException {
|
||||
remoteConfigs.set(new RemoteConfig("android.stickers", 50));
|
||||
remoteConfigs.set(new RemoteConfig("android.stickers", 50, new HashSet<>() {{
|
||||
add(AuthHelper.VALID_UUID);
|
||||
add(AuthHelper.VALID_UUID_TWO);
|
||||
}}));
|
||||
|
||||
List<RemoteConfig> configs = remoteConfigs.getAll();
|
||||
|
||||
assertThat(configs.size()).isEqualTo(1);
|
||||
assertThat(configs.get(0).getName()).isEqualTo("android.stickers");
|
||||
assertThat(configs.get(0).getPercentage()).isEqualTo(50);
|
||||
assertThat(configs.get(0).getUuids().size()).isEqualTo(2);
|
||||
assertThat(configs.get(0).getUuids().contains(AuthHelper.VALID_UUID)).isTrue();
|
||||
assertThat(configs.get(0).getUuids().contains(AuthHelper.VALID_UUID_TWO)).isTrue();
|
||||
assertThat(configs.get(0).getUuids().contains(AuthHelper.INVALID_UUID)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdate() throws SQLException {
|
||||
remoteConfigs.set(new RemoteConfig("android.stickers", 50));
|
||||
remoteConfigs.set(new RemoteConfig("ios.stickers", 50));
|
||||
remoteConfigs.set(new RemoteConfig("ios.stickers", 75));
|
||||
remoteConfigs.set(new RemoteConfig("android.stickers", 50, new HashSet<>()));
|
||||
|
||||
remoteConfigs.set(new RemoteConfig("ios.stickers", 50, new HashSet<>() {{
|
||||
add(AuthHelper.DISABLED_UUID);
|
||||
}}));
|
||||
|
||||
remoteConfigs.set(new RemoteConfig("ios.stickers", 75, new HashSet<>()));
|
||||
|
||||
List<RemoteConfig> configs = remoteConfigs.getAll();
|
||||
|
||||
assertThat(configs.size()).isEqualTo(2);
|
||||
assertThat(configs.get(0).getName()).isEqualTo("android.stickers");
|
||||
assertThat(configs.get(0).getPercentage()).isEqualTo(50);
|
||||
assertThat(configs.get(0).getUuids().size()).isEqualTo(0);
|
||||
|
||||
assertThat(configs.get(1).getName()).isEqualTo("ios.stickers");
|
||||
assertThat(configs.get(1).getPercentage()).isEqualTo(75);
|
||||
assertThat(configs.get(1).getUuids().size()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDelete() {
|
||||
remoteConfigs.set(new RemoteConfig("android.stickers", 50));
|
||||
remoteConfigs.set(new RemoteConfig("ios.stickers", 50));
|
||||
remoteConfigs.set(new RemoteConfig("ios.stickers", 75));
|
||||
remoteConfigs.set(new RemoteConfig("android.stickers", 50, new HashSet<>() {{
|
||||
add(AuthHelper.VALID_UUID);
|
||||
}}));
|
||||
remoteConfigs.set(new RemoteConfig("ios.stickers", 50, new HashSet<>()));
|
||||
remoteConfigs.set(new RemoteConfig("ios.stickers", 75, new HashSet<>()));
|
||||
remoteConfigs.delete("android.stickers");
|
||||
|
||||
List<RemoteConfig> configs = remoteConfigs.getAll();
|
||||
|
||||
Reference in New Issue
Block a user