Migrate from `Object[]` parameters to `Stream<Arguments>`

This commit is contained in:
Chris Eager 2022-01-03 13:57:16 -08:00 committed by Chris Eager
parent f45a1c232f
commit bb27dd0c3b
6 changed files with 440 additions and 393 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2020 Signal Messenger, LLC
* Copyright 2013-2022 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
@ -20,9 +20,11 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
class ExperimentTest {
@ -37,7 +39,8 @@ class ExperimentTest {
matchTimer = mock(Timer.class);
errorTimer = mock(Timer.class);
experiment = new Experiment("test", matchTimer, errorTimer, mock(Timer.class), mock(Timer.class), mock(Timer.class));
experiment = new Experiment("test", matchTimer, errorTimer, mock(Timer.class), mock(Timer.class),
mock(Timer.class));
}
@Test
@ -60,7 +63,9 @@ class ExperimentTest {
@Test
void compareSupplierResultError() {
experiment.compareSupplierResult(12, () -> { throw new RuntimeException("OH NO"); });
experiment.compareSupplierResult(12, () -> {
throw new RuntimeException("OH NO");
});
verify(errorTimer).record(anyLong(), eq(TimeUnit.NANOSECONDS));
}
@ -79,7 +84,9 @@ class ExperimentTest {
void compareSupplierResultAsyncError() throws InterruptedException {
final ExecutorService experimentExecutor = Executors.newSingleThreadExecutor();
experiment.compareSupplierResultAsync(12, () -> { throw new RuntimeException("OH NO"); }, experimentExecutor);
experiment.compareSupplierResultAsync(12, () -> {
throw new RuntimeException("OH NO");
}, experimentExecutor);
experimentExecutor.shutdown();
experimentExecutor.awaitTermination(1, TimeUnit.SECONDS);
@ -96,8 +103,9 @@ class ExperimentTest {
}
@ParameterizedTest
@MethodSource("argumentsForTestRecordResult")
public void testRecordResult(final Object expected, final Object actual, final Experiment experiment, final Timer expectedTimer) {
@MethodSource
public void testRecordResult(final Object expected, final Object actual, final Experiment experiment,
final Timer expectedTimer) {
reset(expectedTimer);
final long durationNanos = 123;
@ -107,7 +115,7 @@ class ExperimentTest {
}
@SuppressWarnings("unused")
private static Object[] argumentsForTestRecordResult() {
private static Stream<Arguments> testRecordResult() {
// Hack: parameters are set before the @Before method gets called
final Timer matchTimer = mock(Timer.class);
final Timer errorTimer = mock(Timer.class);
@ -115,17 +123,18 @@ class ExperimentTest {
final Timer controlNullMismatchTimer = mock(Timer.class);
final Timer experimentNullMismatchTimer = mock(Timer.class);
final Experiment experiment = new Experiment("test", matchTimer, errorTimer, bothPresentMismatchTimer, controlNullMismatchTimer, experimentNullMismatchTimer);
final Experiment experiment = new Experiment("test", matchTimer, errorTimer, bothPresentMismatchTimer,
controlNullMismatchTimer, experimentNullMismatchTimer);
return new Object[] {
new Object[] { 12, 12, experiment, matchTimer },
new Object[] { null, 12, experiment, controlNullMismatchTimer },
new Object[] { 12, null, experiment, experimentNullMismatchTimer },
new Object[] { 12, 17, experiment, bothPresentMismatchTimer },
new Object[] { Optional.of(12), Optional.of(12), experiment, matchTimer },
new Object[] { Optional.empty(), Optional.of(12), experiment, controlNullMismatchTimer },
new Object[] { Optional.of(12), Optional.empty(), experiment, experimentNullMismatchTimer },
new Object[] { Optional.of(12), Optional.of(17), experiment, bothPresentMismatchTimer }
};
return Stream.of(
Arguments.of(12, 12, experiment, matchTimer),
Arguments.of(null, 12, experiment, controlNullMismatchTimer),
Arguments.of(12, null, experiment, experimentNullMismatchTimer),
Arguments.of(12, 17, experiment, bothPresentMismatchTimer),
Arguments.of(Optional.of(12), Optional.of(12), experiment, matchTimer),
Arguments.of(Optional.empty(), Optional.of(12), experiment, controlNullMismatchTimer),
Arguments.of(Optional.of(12), Optional.empty(), experiment, experimentNullMismatchTimer),
Arguments.of(Optional.of(12), Optional.of(17), experiment, bothPresentMismatchTimer)
);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2021 Signal Messenger, LLC
* Copyright 2013-2022 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
@ -8,7 +8,9 @@ package org.whispersystems.textsecuregcm.metrics;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
class OperatingSystemMemoryGaugeTest {
@ -71,18 +73,19 @@ class OperatingSystemMemoryGaugeTest {
""";
@ParameterizedTest
@MethodSource("argumentsForTestGetValue")
public void testGetValue(final String metricName, final long expectedValue) {
@MethodSource
void testGetValue(final String metricName, final long expectedValue) {
assertEquals(expectedValue, new OperatingSystemMemoryGauge(metricName).getValue(MEMINFO.lines()));
}
private static Object[] argumentsForTestGetValue() {
return new Object[] {
new Object[] { "MemTotal", 16052208L },
new Object[] { "Active(anon)", 5580980L },
new Object[] { "Committed_AS", 16681884L },
new Object[] { "HugePages_Free", 7L },
new Object[] { "NonsenseMetric", 0L }
};
@SuppressWarnings("unused")
private static Stream<Arguments> testGetValue() {
return Stream.of(
Arguments.of("MemTotal", 16052208L),
Arguments.of("Active(anon)", 5580980L),
Arguments.of("Committed_AS", 16681884L),
Arguments.of("HugePages_Free", 7L),
Arguments.of("NonsenseMetric", 0L)
);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2020 Signal Messenger, LLC
* Copyright 2013-2022 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
@ -11,14 +11,16 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import io.micrometer.core.instrument.Tag;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
class UserAgentTagUtilTest {
@ParameterizedTest
@MethodSource("argumentsForTestGetUserAgentTags")
@MethodSource
public void testGetUserAgentTags(final String userAgent, final List<Tag> expectedTags) {
assertEquals(new HashSet<>(expectedTags),
new HashSet<>(UserAgentTagUtil.getUserAgentTags(userAgent)));
@ -29,23 +31,23 @@ class UserAgentTagUtilTest {
}
@SuppressWarnings("unused")
private static Object[] argumentsForTestGetUserAgentTags() {
return new Object[] {
new Object[] { "This is obviously not a reasonable User-Agent string.", UserAgentTagUtil.UNRECOGNIZED_TAGS },
new Object[] { null, UserAgentTagUtil.UNRECOGNIZED_TAGS },
new Object[] { "Signal-Android 4.53.7 (Android 8.1)", platformVersionTags("android", "4.53.7") },
new Object[] { "Signal Desktop 1.2.3", platformVersionTags("desktop", "1.2.3") },
new Object[] { "Signal/3.9.0 (iPhone; iOS 12.2; Scale/3.00)", platformVersionTags("ios", "3.9.0") },
new Object[] { "Signal-Android 1.2.3 (Android 8.1)", UserAgentTagUtil.UNRECOGNIZED_TAGS },
new Object[] { "Signal Desktop 3.9.0", platformVersionTags("desktop", "3.9.0") },
new Object[] { "Signal/4.53.7 (iPhone; iOS 12.2; Scale/3.00)", platformVersionTags("ios", "4.53.7") },
new Object[] { "Signal-Android 4.68.3 (Android 9)", platformVersionTags("android", "4.68.3") },
new Object[] { "Signal-Android 1.2.3 (Android 4.3)", UserAgentTagUtil.UNRECOGNIZED_TAGS },
new Object[] { "Signal-Android 4.68.3.0-bobsbootlegclient", UserAgentTagUtil.UNRECOGNIZED_TAGS },
new Object[] { "Signal Desktop 1.22.45-foo-0", UserAgentTagUtil.UNRECOGNIZED_TAGS },
new Object[] { "Signal Desktop 1.34.5-beta.1-fakeclientemporium", UserAgentTagUtil.UNRECOGNIZED_TAGS },
new Object[] { "Signal Desktop 1.32.0-beta.3", UserAgentTagUtil.UNRECOGNIZED_TAGS },
};
private static Stream<Arguments> testGetUserAgentTags() {
return Stream.of(
Arguments.of("This is obviously not a reasonable User-Agent string.", UserAgentTagUtil.UNRECOGNIZED_TAGS),
Arguments.of(null, UserAgentTagUtil.UNRECOGNIZED_TAGS),
Arguments.of("Signal-Android 4.53.7 (Android 8.1)", platformVersionTags("android", "4.53.7")),
Arguments.of("Signal Desktop 1.2.3", platformVersionTags("desktop", "1.2.3")),
Arguments.of("Signal/3.9.0 (iPhone; iOS 12.2; Scale/3.00)", platformVersionTags("ios", "3.9.0")),
Arguments.of("Signal-Android 1.2.3 (Android 8.1)", UserAgentTagUtil.UNRECOGNIZED_TAGS),
Arguments.of("Signal Desktop 3.9.0", platformVersionTags("desktop", "3.9.0")),
Arguments.of("Signal/4.53.7 (iPhone; iOS 12.2; Scale/3.00)", platformVersionTags("ios", "4.53.7")),
Arguments.of("Signal-Android 4.68.3 (Android 9)", platformVersionTags("android", "4.68.3")),
Arguments.of("Signal-Android 1.2.3 (Android 4.3)", UserAgentTagUtil.UNRECOGNIZED_TAGS),
Arguments.of("Signal-Android 4.68.3.0-bobsbootlegclient", UserAgentTagUtil.UNRECOGNIZED_TAGS),
Arguments.of("Signal Desktop 1.22.45-foo-0", UserAgentTagUtil.UNRECOGNIZED_TAGS),
Arguments.of("Signal Desktop 1.34.5-beta.1-fakeclientemporium", UserAgentTagUtil.UNRECOGNIZED_TAGS),
Arguments.of("Signal Desktop 1.32.0-beta.3", UserAgentTagUtil.UNRECOGNIZED_TAGS)
);
}
@Test
@ -70,22 +72,24 @@ class UserAgentTagUtilTest {
assertEquals(expectedTag, UserAgentTagUtil.getPlatformTag(userAgent));
}
private static Object[] argumentsForTestGetPlatformTag() {
return new Object[] {
new Object[] { "This is obviously not a reasonable User-Agent string.", Tag.of(UserAgentTagUtil.PLATFORM_TAG, "unrecognized") },
new Object[] { null, Tag.of(UserAgentTagUtil.PLATFORM_TAG, "unrecognized") },
new Object[] { "Signal-Android 4.53.7 (Android 8.1)", Tag.of(UserAgentTagUtil.PLATFORM_TAG, "android") },
new Object[] { "Signal Desktop 1.2.3", Tag.of(UserAgentTagUtil.PLATFORM_TAG, "desktop") },
new Object[] { "Signal/3.9.0 (iPhone; iOS 12.2; Scale/3.00)", Tag.of(UserAgentTagUtil.PLATFORM_TAG, "ios") },
new Object[] { "Signal-Android 1.2.3 (Android 8.1)", Tag.of(UserAgentTagUtil.PLATFORM_TAG, "android") },
new Object[] { "Signal Desktop 3.9.0", Tag.of(UserAgentTagUtil.PLATFORM_TAG, "desktop") },
new Object[] { "Signal/4.53.7 (iPhone; iOS 12.2; Scale/3.00)", Tag.of(UserAgentTagUtil.PLATFORM_TAG, "ios") },
new Object[] { "Signal-Android 4.68.3 (Android 9)", Tag.of(UserAgentTagUtil.PLATFORM_TAG, "android") },
new Object[] { "Signal-Android 1.2.3 (Android 4.3)", Tag.of(UserAgentTagUtil.PLATFORM_TAG, "android") },
new Object[] { "Signal-Android 4.68.3.0-bobsbootlegclient", Tag.of(UserAgentTagUtil.PLATFORM_TAG, "android") },
new Object[] { "Signal Desktop 1.22.45-foo-0", Tag.of(UserAgentTagUtil.PLATFORM_TAG, "desktop") },
new Object[] { "Signal Desktop 1.34.5-beta.1-fakeclientemporium", Tag.of(UserAgentTagUtil.PLATFORM_TAG, "desktop") },
new Object[] { "Signal Desktop 1.32.0-beta.3", Tag.of(UserAgentTagUtil.PLATFORM_TAG, "desktop") },
};
private static Stream<Arguments> argumentsForTestGetPlatformTag() {
return Stream.of(
Arguments.of("This is obviously not a reasonable User-Agent string.",
Tag.of(UserAgentTagUtil.PLATFORM_TAG, "unrecognized")),
Arguments.of(null, Tag.of(UserAgentTagUtil.PLATFORM_TAG, "unrecognized")),
Arguments.of("Signal-Android 4.53.7 (Android 8.1)", Tag.of(UserAgentTagUtil.PLATFORM_TAG, "android")),
Arguments.of("Signal Desktop 1.2.3", Tag.of(UserAgentTagUtil.PLATFORM_TAG, "desktop")),
Arguments.of("Signal/3.9.0 (iPhone; iOS 12.2; Scale/3.00)", Tag.of(UserAgentTagUtil.PLATFORM_TAG, "ios")),
Arguments.of("Signal-Android 1.2.3 (Android 8.1)", Tag.of(UserAgentTagUtil.PLATFORM_TAG, "android")),
Arguments.of("Signal Desktop 3.9.0", Tag.of(UserAgentTagUtil.PLATFORM_TAG, "desktop")),
Arguments.of("Signal/4.53.7 (iPhone; iOS 12.2; Scale/3.00)", Tag.of(UserAgentTagUtil.PLATFORM_TAG, "ios")),
Arguments.of("Signal-Android 4.68.3 (Android 9)", Tag.of(UserAgentTagUtil.PLATFORM_TAG, "android")),
Arguments.of("Signal-Android 1.2.3 (Android 4.3)", Tag.of(UserAgentTagUtil.PLATFORM_TAG, "android")),
Arguments.of("Signal-Android 4.68.3.0-bobsbootlegclient", Tag.of(UserAgentTagUtil.PLATFORM_TAG, "android")),
Arguments.of("Signal Desktop 1.22.45-foo-0", Tag.of(UserAgentTagUtil.PLATFORM_TAG, "desktop")),
Arguments.of("Signal Desktop 1.34.5-beta.1-fakeclientemporium",
Tag.of(UserAgentTagUtil.PLATFORM_TAG, "desktop")),
Arguments.of("Signal Desktop 1.32.0-beta.3", Tag.of(UserAgentTagUtil.PLATFORM_TAG, "desktop"))
);
}
}

View File

@ -1,3 +1,8 @@
/*
* Copyright 2021-2022 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.sms;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
@ -6,7 +11,7 @@ import static com.github.tomakehurst.wiremock.client.WireMock.post;
import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
@ -16,11 +21,13 @@ import java.util.Collections;
import java.util.List;
import java.util.Locale.LanguageRange;
import java.util.Optional;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
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;
import org.whispersystems.textsecuregcm.configuration.TwilioConfiguration;
import org.whispersystems.textsecuregcm.http.FaultTolerantHttpClient;
@ -89,7 +96,7 @@ class TwilioVerifySenderTest {
}
@ParameterizedTest
@MethodSource("argumentsForDeliverSmsVerificationWithVerify")
@MethodSource
void deliverSmsVerificationWithVerify(@Nullable final String client, @Nullable final String languageRange,
final boolean expectAppHash, @Nullable final String expectedLocale) throws Exception {
@ -114,17 +121,18 @@ class TwilioVerifySenderTest {
)));
}
private static Object[] argumentsForDeliverSmsVerificationWithVerify() {
return new Object[][]{
@SuppressWarnings("unused")
private static Stream<Arguments> deliverSmsVerificationWithVerify() {
return Stream.of(
// client, languageRange, expectAppHash, expectedLocale
{"ios", "fr-CA, en", false, "fr"},
{"android-2021-03", "zh-HK, it", true, "zh-HK"},
{null, null, false, null}
};
Arguments.of("ios", "fr-CA, en", false, "fr"),
Arguments.of("android-2021-03", "zh-HK, it", true, "zh-HK"),
Arguments.of(null, null, false, null)
);
}
@ParameterizedTest
@MethodSource("argumentsForDeliverVoxVerificationWithVerify")
@MethodSource
void deliverVoxVerificationWithVerify(@Nullable final String languageRange,
@Nullable final String expectedLocale) throws Exception {
@ -147,14 +155,15 @@ class TwilioVerifySenderTest {
+ "&CustomCode=123456")));
}
private static Object[] argumentsForDeliverVoxVerificationWithVerify() {
return new Object[][]{
@SuppressWarnings("unused")
private static Stream<Arguments> deliverVoxVerificationWithVerify() {
return Stream.of(
// languageRange, expectedLocale
{"fr-CA, en", "fr"},
{"zh-HK, it", "zh-HK"},
{"en-CAA, en", "en"},
{null, null}
};
Arguments.of("fr-CA, en", "fr"),
Arguments.of("zh-HK, it", "zh-HK"),
Arguments.of("en-CAA, en", "en"),
Arguments.of(null, null)
);
}
@Test
@ -211,7 +220,8 @@ class TwilioVerifySenderTest {
assertThat(success).isTrue();
wireMock.verify(1, postRequestedFor(urlEqualTo("/v2/Services/" + VERIFY_SERVICE_SID + "/Verifications/" + VERIFICATION_SID))
wireMock.verify(1,
postRequestedFor(urlEqualTo("/v2/Services/" + VERIFY_SERVICE_SID + "/Verifications/" + VERIFICATION_SID))
.withHeader("Content-Type", equalTo("application/x-www-form-urlencoded"))
.withRequestBody(equalTo("Status=approved")));
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2020 Signal Messenger, LLC
* Copyright 2013-2022 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
@ -9,63 +9,69 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import java.time.Duration;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.whispersystems.textsecuregcm.entities.SignedPreKey;
class DeviceTest {
@ParameterizedTest
@MethodSource("argumentsForTestIsEnabled")
void testIsEnabled(final boolean master, final boolean fetchesMessages, final String apnId, final String gcmId, final SignedPreKey signedPreKey, final Duration timeSinceLastSeen, final boolean expectEnabled) {
@MethodSource
void testIsEnabled(final boolean master, final boolean fetchesMessages, final String apnId, final String gcmId,
final SignedPreKey signedPreKey, final Duration timeSinceLastSeen, final boolean expectEnabled) {
final long lastSeen = System.currentTimeMillis() - timeSinceLastSeen.toMillis();
final Device device = new Device(master ? 1 : 2, "test", "auth-token", "salt", gcmId, apnId, null, fetchesMessages, 1, signedPreKey, lastSeen, lastSeen, "user-agent", 0, null);
final Device device = new Device(master ? 1 : 2, "test", "auth-token", "salt", gcmId, apnId, null, fetchesMessages,
1, signedPreKey, lastSeen, lastSeen, "user-agent", 0, null);
assertEquals(expectEnabled, device.isEnabled());
}
private static Object[] argumentsForTestIsEnabled() {
return new Object[] {
private static Stream<Arguments> testIsEnabled() {
return Stream.of(
// master fetchesMessages apnId gcmId signedPreKey lastSeen expectEnabled
new Object[] { true, false, null, null, null, Duration.ofDays(60), false },
new Object[] { true, false, null, null, null, Duration.ofDays(1), false },
new Object[] { true, false, null, null, mock(SignedPreKey.class), Duration.ofDays(60), false },
new Object[] { true, false, null, null, mock(SignedPreKey.class), Duration.ofDays(1), false },
new Object[] { true, false, null, "gcm-id", null, Duration.ofDays(60), false },
new Object[] { true, false, null, "gcm-id", null, Duration.ofDays(1), false },
new Object[] { true, false, null, "gcm-id", mock(SignedPreKey.class), Duration.ofDays(60), true },
new Object[] { true, false, null, "gcm-id", mock(SignedPreKey.class), Duration.ofDays(1), true },
new Object[] { true, false, "apn-id", null, null, Duration.ofDays(60), false },
new Object[] { true, false, "apn-id", null, null, Duration.ofDays(1), false },
new Object[] { true, false, "apn-id", null, mock(SignedPreKey.class), Duration.ofDays(60), true },
new Object[] { true, false, "apn-id", null, mock(SignedPreKey.class), Duration.ofDays(1), true },
new Object[] { true, true, null, null, null, Duration.ofDays(60), false },
new Object[] { true, true, null, null, null, Duration.ofDays(1), false },
new Object[] { true, true, null, null, mock(SignedPreKey.class), Duration.ofDays(60), true },
new Object[] { true, true, null, null, mock(SignedPreKey.class), Duration.ofDays(1), true },
new Object[] { false, false, null, null, null, Duration.ofDays(60), false },
new Object[] { false, false, null, null, null, Duration.ofDays(1), false },
new Object[] { false, false, null, null, mock(SignedPreKey.class), Duration.ofDays(60), false },
new Object[] { false, false, null, null, mock(SignedPreKey.class), Duration.ofDays(1), false },
new Object[] { false, false, null, "gcm-id", null, Duration.ofDays(60), false },
new Object[] { false, false, null, "gcm-id", null, Duration.ofDays(1), false },
new Object[] { false, false, null, "gcm-id", mock(SignedPreKey.class), Duration.ofDays(60), false },
new Object[] { false, false, null, "gcm-id", mock(SignedPreKey.class), Duration.ofDays(1), true },
new Object[] { false, false, "apn-id", null, null, Duration.ofDays(60), false },
new Object[] { false, false, "apn-id", null, null, Duration.ofDays(1), false },
new Object[] { false, false, "apn-id", null, mock(SignedPreKey.class), Duration.ofDays(60), false },
new Object[] { false, false, "apn-id", null, mock(SignedPreKey.class), Duration.ofDays(1), true },
new Object[] { false, true, null, null, null, Duration.ofDays(60), false },
new Object[] { false, true, null, null, null, Duration.ofDays(1), false },
new Object[] { false, true, null, null, mock(SignedPreKey.class), Duration.ofDays(60), false },
new Object[] { false, true, null, null, mock(SignedPreKey.class), Duration.ofDays(1), true }
};
Arguments.of(true, false, null, null, null, Duration.ofDays(60), false),
Arguments.of(true, false, null, null, null, Duration.ofDays(1), false),
Arguments.of(true, false, null, null, mock(SignedPreKey.class), Duration.ofDays(60), false),
Arguments.of(true, false, null, null, mock(SignedPreKey.class), Duration.ofDays(1), false),
Arguments.of(true, false, null, "gcm-id", null, Duration.ofDays(60), false),
Arguments.of(true, false, null, "gcm-id", null, Duration.ofDays(1), false),
Arguments.of(true, false, null, "gcm-id", mock(SignedPreKey.class), Duration.ofDays(60), true),
Arguments.of(true, false, null, "gcm-id", mock(SignedPreKey.class), Duration.ofDays(1), true),
Arguments.of(true, false, "apn-id", null, null, Duration.ofDays(60), false),
Arguments.of(true, false, "apn-id", null, null, Duration.ofDays(1), false),
Arguments.of(true, false, "apn-id", null, mock(SignedPreKey.class), Duration.ofDays(60), true),
Arguments.of(true, false, "apn-id", null, mock(SignedPreKey.class), Duration.ofDays(1), true),
Arguments.of(true, true, null, null, null, Duration.ofDays(60), false),
Arguments.of(true, true, null, null, null, Duration.ofDays(1), false),
Arguments.of(true, true, null, null, mock(SignedPreKey.class), Duration.ofDays(60), true),
Arguments.of(true, true, null, null, mock(SignedPreKey.class), Duration.ofDays(1), true),
Arguments.of(false, false, null, null, null, Duration.ofDays(60), false),
Arguments.of(false, false, null, null, null, Duration.ofDays(1), false),
Arguments.of(false, false, null, null, mock(SignedPreKey.class), Duration.ofDays(60), false),
Arguments.of(false, false, null, null, mock(SignedPreKey.class), Duration.ofDays(1), false),
Arguments.of(false, false, null, "gcm-id", null, Duration.ofDays(60), false),
Arguments.of(false, false, null, "gcm-id", null, Duration.ofDays(1), false),
Arguments.of(false, false, null, "gcm-id", mock(SignedPreKey.class), Duration.ofDays(60), false),
Arguments.of(false, false, null, "gcm-id", mock(SignedPreKey.class), Duration.ofDays(1), true),
Arguments.of(false, false, "apn-id", null, null, Duration.ofDays(60), false),
Arguments.of(false, false, "apn-id", null, null, Duration.ofDays(1), false),
Arguments.of(false, false, "apn-id", null, mock(SignedPreKey.class), Duration.ofDays(60), false),
Arguments.of(false, false, "apn-id", null, mock(SignedPreKey.class), Duration.ofDays(1), true),
Arguments.of(false, true, null, null, null, Duration.ofDays(60), false),
Arguments.of(false, true, null, null, null, Duration.ofDays(1), false),
Arguments.of(false, true, null, null, mock(SignedPreKey.class), Duration.ofDays(60), false),
Arguments.of(false, true, null, null, mock(SignedPreKey.class), Duration.ofDays(1), true)
);
}
@ParameterizedTest
@MethodSource("argumentsForTestIsGroupsV2Supported")
void testIsGroupsV2Supported(final boolean master, final String apnId, final boolean gv2Capability, final boolean gv2_2Capability, final boolean gv2_3Capability, final boolean expectGv2Supported) {
final Device.DeviceCapabilities capabilities = new Device.DeviceCapabilities(gv2Capability, gv2_2Capability, gv2_3Capability, false, false, false,
void testIsGroupsV2Supported(final boolean master, final String apnId, final boolean gv2Capability,
final boolean gv2_2Capability, final boolean gv2_3Capability, final boolean expectGv2Supported) {
final Device.DeviceCapabilities capabilities = new Device.DeviceCapabilities(gv2Capability, gv2_2Capability,
gv2_3Capability, false, false, false,
false, false, false);
final Device device = new Device(master ? 1 : 2, "test", "auth-token", "salt",
null, apnId, null, false, 1, null, 0, 0, "user-agent", 0, capabilities);
@ -73,49 +79,49 @@ class DeviceTest {
assertEquals(expectGv2Supported, device.isGroupsV2Supported());
}
private static Object[] argumentsForTestIsGroupsV2Supported() {
return new Object[] {
private static Stream<Arguments> argumentsForTestIsGroupsV2Supported() {
return Stream.of(
// master apnId gv2 gv2-2 gv2-3 capable
// Android master
new Object[] { true, null, false, false, false, false },
new Object[] { true, null, true, false, false, false },
new Object[] { true, null, false, true, false, false },
new Object[] { true, null, true, true, false, false },
new Object[] { true, null, false, false, true, true },
new Object[] { true, null, true, false, true, true },
new Object[] { true, null, false, true, true, true },
new Object[] { true, null, true, true, true, true },
Arguments.of(true, null, false, false, false, false),
Arguments.of(true, null, true, false, false, false),
Arguments.of(true, null, false, true, false, false),
Arguments.of(true, null, true, true, false, false),
Arguments.of(true, null, false, false, true, true),
Arguments.of(true, null, true, false, true, true),
Arguments.of(true, null, false, true, true, true),
Arguments.of(true, null, true, true, true, true),
// iOs master
new Object[] { true, "apn-id", false, false, false, false },
new Object[] { true, "apn-id", true, false, false, false },
new Object[] { true, "apn-id", false, true, false, true },
new Object[] { true, "apn-id", true, true, false, true },
new Object[] { true, "apn-id", false, false, true, true },
new Object[] { true, "apn-id", true, false, true, true },
new Object[] { true, "apn-id", false, true, true, true },
new Object[] { true, "apn-id", true, true, true, true },
// iOS master
Arguments.of(true, "apn-id", false, false, false, false),
Arguments.of(true, "apn-id", true, false, false, false),
Arguments.of(true, "apn-id", false, true, false, true),
Arguments.of(true, "apn-id", true, true, false, true),
Arguments.of(true, "apn-id", false, false, true, true),
Arguments.of(true, "apn-id", true, false, true, true),
Arguments.of(true, "apn-id", false, true, true, true),
Arguments.of(true, "apn-id", true, true, true, true),
// iOs linked
new Object[] { false, "apn-id", false, false, false, false },
new Object[] { false, "apn-id", true, false, false, false },
new Object[] { false, "apn-id", false, true, false, true },
new Object[] { false, "apn-id", true, true, false, true },
new Object[] { false, "apn-id", false, false, true, true },
new Object[] { false, "apn-id", true, false, true, true },
new Object[] { false, "apn-id", false, true, true, true },
new Object[] { false, "apn-id", true, true, true, true },
// iOS linked
Arguments.of(false, "apn-id", false, false, false, false),
Arguments.of(false, "apn-id", true, false, false, false),
Arguments.of(false, "apn-id", false, true, false, true),
Arguments.of(false, "apn-id", true, true, false, true),
Arguments.of(false, "apn-id", false, false, true, true),
Arguments.of(false, "apn-id", true, false, true, true),
Arguments.of(false, "apn-id", false, true, true, true),
Arguments.of(false, "apn-id", true, true, true, true),
// desktop linked
new Object[] { false, null, false, false, false, false },
new Object[] { false, null, true, false, false, false },
new Object[] { false, null, false, true, false, false },
new Object[] { false, null, true, true, false, false },
new Object[] { false, null, false, false, true, true },
new Object[] { false, null, true, false, true, true },
new Object[] { false, null, false, true, true, true },
new Object[] { false, null, true, true, true, true }
};
Arguments.of(false, null, false, false, false, false),
Arguments.of(false, null, true, false, false, false),
Arguments.of(false, null, false, true, false, false),
Arguments.of(false, null, true, true, false, false),
Arguments.of(false, null, false, false, true, true),
Arguments.of(false, null, true, false, true, true),
Arguments.of(false, null, false, true, true, true),
Arguments.of(false, null, true, true, true, true)
);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2013-2020 Signal Messenger, LLC
* Copyright 2013-2022 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
@ -9,36 +9,43 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import com.vdurmont.semver4j.Semver;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
class UserAgentUtilTest {
@ParameterizedTest
@MethodSource("argumentsForTestParseUserAgentString")
void testParseUserAgentString(final String userAgentString, final UserAgent expectedUserAgent) throws UnrecognizedUserAgentException {
@MethodSource
void testParseUserAgentString(final String userAgentString, final UserAgent expectedUserAgent)
throws UnrecognizedUserAgentException {
assertEquals(expectedUserAgent, UserAgentUtil.parseUserAgentString(userAgentString));
}
private static Object[] argumentsForTestParseUserAgentString() {
return new Object[] {
new Object[] { "Signal-Android/4.68.3 Android/25", new UserAgent(ClientPlatform.ANDROID, new Semver("4.68.3"), "Android/25") },
new Object[] { "Signal-Android 4.53.7 (Android 8.1)", new UserAgent(ClientPlatform.ANDROID, new Semver("4.53.7"), "(Android 8.1)") },
};
@SuppressWarnings("unused")
private static Stream<Arguments> testParseUserAgentString() {
return Stream.of(
Arguments.of("Signal-Android/4.68.3 Android/25",
new UserAgent(ClientPlatform.ANDROID, new Semver("4.68.3"), "Android/25")),
Arguments.of("Signal-Android 4.53.7 (Android 8.1)",
new UserAgent(ClientPlatform.ANDROID, new Semver("4.53.7"), "(Android 8.1)"))
);
}
@ParameterizedTest
@MethodSource("argumentsForTestParseBogusUserAgentString")
@MethodSource
void testParseBogusUserAgentString(final String userAgentString) {
assertThrows(UnrecognizedUserAgentException.class, () -> UserAgentUtil.parseUserAgentString(userAgentString));
}
private static Object[] argumentsForTestParseBogusUserAgentString() {
return new Object[] {
@SuppressWarnings("unused")
private static Stream<String> testParseBogusUserAgentString() {
return Stream.of(
null,
"This is obviously not a reasonable User-Agent string.",
"Signal-Android/4.6-8.3.unreasonableversionstring-17"
};
);
}
@ParameterizedTest
@ -47,35 +54,43 @@ class UserAgentUtilTest {
assertEquals(expectedUserAgent, UserAgentUtil.parseStandardUserAgentString(userAgentString));
}
private static Object[] argumentsForTestParseStandardUserAgentString() {
return new Object[] {
new Object[] { "This is obviously not a reasonable User-Agent string.", null },
new Object[] { "Signal-Android/4.68.3 Android/25", new UserAgent(ClientPlatform.ANDROID, new Semver("4.68.3"), "Android/25") },
new Object[] { "Signal-Android/4.68.3", new UserAgent(ClientPlatform.ANDROID, new Semver("4.68.3")) },
new Object[] { "Signal-Desktop/1.2.3 Linux", new UserAgent(ClientPlatform.DESKTOP, new Semver("1.2.3"), "Linux") },
new Object[] { "Signal-Desktop/1.2.3 macOS", new UserAgent(ClientPlatform.DESKTOP, new Semver("1.2.3"), "macOS") },
new Object[] { "Signal-Desktop/1.2.3 Windows", new UserAgent(ClientPlatform.DESKTOP, new Semver("1.2.3"), "Windows") },
new Object[] { "Signal-Desktop/1.2.3", new UserAgent(ClientPlatform.DESKTOP, new Semver("1.2.3")) },
new Object[] { "Signal-Desktop/1.32.0-beta.3", new UserAgent(ClientPlatform.DESKTOP, new Semver("1.32.0-beta.3")) },
new Object[] { "Signal-iOS/3.9.0 (iPhone; iOS 12.2; Scale/3.00)", new UserAgent(ClientPlatform.IOS, new Semver("3.9.0"), "(iPhone; iOS 12.2; Scale/3.00)") },
new Object[] { "Signal-iOS/3.9.0 iOS/14.2", new UserAgent(ClientPlatform.IOS, new Semver("3.9.0"), "iOS/14.2") },
new Object[] { "Signal-iOS/3.9.0", new UserAgent(ClientPlatform.IOS, new Semver("3.9.0")) }
};
private static Stream<Arguments> argumentsForTestParseStandardUserAgentString() {
return Stream.of(
Arguments.of("This is obviously not a reasonable User-Agent string.", null),
Arguments.of("Signal-Android/4.68.3 Android/25",
new UserAgent(ClientPlatform.ANDROID, new Semver("4.68.3"), "Android/25")),
Arguments.of("Signal-Android/4.68.3", new UserAgent(ClientPlatform.ANDROID, new Semver("4.68.3"))),
Arguments.of("Signal-Desktop/1.2.3 Linux", new UserAgent(ClientPlatform.DESKTOP, new Semver("1.2.3"), "Linux")),
Arguments.of("Signal-Desktop/1.2.3 macOS", new UserAgent(ClientPlatform.DESKTOP, new Semver("1.2.3"), "macOS")),
Arguments.of("Signal-Desktop/1.2.3 Windows",
new UserAgent(ClientPlatform.DESKTOP, new Semver("1.2.3"), "Windows")),
Arguments.of("Signal-Desktop/1.2.3", new UserAgent(ClientPlatform.DESKTOP, new Semver("1.2.3"))),
Arguments.of("Signal-Desktop/1.32.0-beta.3",
new UserAgent(ClientPlatform.DESKTOP, new Semver("1.32.0-beta.3"))),
Arguments.of("Signal-iOS/3.9.0 (iPhone; iOS 12.2; Scale/3.00)",
new UserAgent(ClientPlatform.IOS, new Semver("3.9.0"), "(iPhone; iOS 12.2; Scale/3.00)")),
Arguments.of("Signal-iOS/3.9.0 iOS/14.2", new UserAgent(ClientPlatform.IOS, new Semver("3.9.0"), "iOS/14.2")),
Arguments.of("Signal-iOS/3.9.0", new UserAgent(ClientPlatform.IOS, new Semver("3.9.0")))
);
}
@ParameterizedTest
@MethodSource("argumentsForTestParseLegacyUserAgentString")
@MethodSource
void testParseLegacyUserAgentString(final String userAgentString, final UserAgent expectedUserAgent) {
assertEquals(expectedUserAgent, UserAgentUtil.parseLegacyUserAgentString(userAgentString));
}
private static Object[] argumentsForTestParseLegacyUserAgentString() {
return new Object[] {
new Object[] { "This is obviously not a reasonable User-Agent string.", null },
new Object[] { "Signal-Android 4.53.7 (Android 8.1)", new UserAgent(ClientPlatform.ANDROID, new Semver("4.53.7"), "(Android 8.1)") },
new Object[] { "Signal Desktop 1.2.3", new UserAgent(ClientPlatform.DESKTOP, new Semver("1.2.3")) },
new Object[] { "Signal Desktop 1.32.0-beta.3", new UserAgent(ClientPlatform.DESKTOP, new Semver("1.32.0-beta.3")) },
new Object[] { "Signal/3.9.0 (iPhone; iOS 12.2; Scale/3.00)", new UserAgent(ClientPlatform.IOS, new Semver("3.9.0"), "(iPhone; iOS 12.2; Scale/3.00)") }
};
@SuppressWarnings("unused")
private static Stream<Arguments> testParseLegacyUserAgentString() {
return Stream.of(
Arguments.of("This is obviously not a reasonable User-Agent string.", null),
Arguments.of("Signal-Android 4.53.7 (Android 8.1)",
new UserAgent(ClientPlatform.ANDROID, new Semver("4.53.7"), "(Android 8.1)")),
Arguments.of("Signal Desktop 1.2.3", new UserAgent(ClientPlatform.DESKTOP, new Semver("1.2.3"))),
Arguments.of("Signal Desktop 1.32.0-beta.3",
new UserAgent(ClientPlatform.DESKTOP, new Semver("1.32.0-beta.3"))),
Arguments.of("Signal/3.9.0 (iPhone; iOS 12.2; Scale/3.00)",
new UserAgent(ClientPlatform.IOS, new Semver("3.9.0"), "(iPhone; iOS 12.2; Scale/3.00)"))
);
}
}