Skip to content

Commit

Permalink
Update test relying on network type detection to run on all API levels.
Browse files Browse the repository at this point in the history
This ensures we test the API level specific logic, in particular
around 5G-NSA detection.

Robolectric has a remaining bug that it doesn't support listening
to service state changes. Hence, we need to ignore some tests on
these API levels still until this is fixed.

PiperOrigin-RevId: 421505951
  • Loading branch information
tonihei authored and icbaker committed Jan 14, 2022
1 parent 4647a74 commit b77204e
Showing 1 changed file with 137 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@
import android.net.NetworkInfo;
import android.net.NetworkInfo.DetailedState;
import android.net.Uri;
import android.telephony.TelephonyDisplayInfo;
import android.telephony.TelephonyManager;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.testutil.FakeClock;
import com.google.android.exoplayer2.testutil.FakeDataSource;
import com.google.android.exoplayer2.util.NetworkTypeObserver;
import com.google.android.exoplayer2.util.Util;
import java.util.Random;
import org.junit.Before;
import org.junit.Test;
Expand All @@ -40,9 +42,11 @@
import org.robolectric.annotation.Config;
import org.robolectric.shadows.ShadowLooper;
import org.robolectric.shadows.ShadowNetworkInfo;
import org.robolectric.shadows.ShadowTelephonyManager;

/** Unit test for {@link DefaultBandwidthMeter}. */
@RunWith(AndroidJUnit4.class)
@Config(sdk = Config.ALL_SDKS) // Test all SDKs because network detection logic changed over time.
public final class DefaultBandwidthMeterTest {

private static final int SIMULATED_TRANSFER_COUNT = 100;
Expand All @@ -56,8 +60,6 @@ public final class DefaultBandwidthMeterTest {
private NetworkInfo networkInfo2g;
private NetworkInfo networkInfo3g;
private NetworkInfo networkInfo4g;
// TODO: Add tests covering 5G-NSA networks. Not testable right now because we need to set the
// TelephonyDisplayInfo on API 31, which isn't available for Robolectric yet.
private NetworkInfo networkInfo5gSa;
private NetworkInfo networkInfoEthernet;

Expand Down Expand Up @@ -183,9 +185,15 @@ public void defaultInitialBitrateEstimate_forEthernet_isGreaterThanEstimateFor3G
assertThat(initialEstimateEthernet).isGreaterThan(initialEstimate3g);
}

@Config(sdk = 28) // TODO(b/190021699): Fix 4G tests to work on newer API levels
@Test
public void defaultInitialBitrateEstimate_for4G_isGreaterThanEstimateFor2G() {
if (Util.SDK_INT == 29 || Util.SDK_INT == 30) {
// Robolectric doesn't support listening to service state changes, which we need on APIs 29
// and 30 to run this test successfully.
// TODO(b/190021699): Update once Robolectric released support for this.
return;
}

setActiveNetworkInfo(networkInfo4g);
DefaultBandwidthMeter bandwidthMeter4g =
new DefaultBandwidthMeter.Builder(ApplicationProvider.getApplicationContext()).build();
Expand All @@ -199,9 +207,15 @@ public void defaultInitialBitrateEstimate_for4G_isGreaterThanEstimateFor2G() {
assertThat(initialEstimate4g).isGreaterThan(initialEstimate2g);
}

@Config(sdk = 28) // TODO(b/190021699): Fix 4G tests to work on newer API levels
@Test
public void defaultInitialBitrateEstimate_for4G_isGreaterThanEstimateFor3G() {
if (Util.SDK_INT == 29 || Util.SDK_INT == 30) {
// Robolectric doesn't support listening to service state changes, which we need on APIs 29
// and 30 to run this test successfully.
// TODO(b/190021699): Update once Robolectric released support for this.
return;
}

setActiveNetworkInfo(networkInfo4g);
DefaultBandwidthMeter bandwidthMeter4g =
new DefaultBandwidthMeter.Builder(ApplicationProvider.getApplicationContext()).build();
Expand Down Expand Up @@ -231,18 +245,42 @@ public void defaultInitialBitrateEstimate_for3G_isGreaterThanEstimateFor2G() {
}

@Test
public void defaultInitialBitrateEstimate_for5gSa_isGreaterThanEstimateFor4g() {
@Config(minSdk = 29) // 5G detection support was added in API 29.
public void defaultInitialBitrateEstimate_for5gNsa_isGreaterThanEstimateFor4g() {
if (Util.SDK_INT == 29 || Util.SDK_INT == 30) {
// Robolectric doesn't support listening to service state changes, which we need on APIs 29
// and 30 to run this test successfully.
// TODO(b/190021699): Update once Robolectric released support for this.
return;
}

setActiveNetworkInfo(networkInfo4g);
DefaultBandwidthMeter bandwidthMeter4g =
new DefaultBandwidthMeter.Builder(ApplicationProvider.getApplicationContext()).build();
long initialEstimate4g = bandwidthMeter4g.getBitrateEstimate();

setActiveNetworkInfo(networkInfo4g, TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA);
DefaultBandwidthMeter bandwidthMeter5gNsa =
new DefaultBandwidthMeter.Builder(ApplicationProvider.getApplicationContext()).build();
long initialEstimate5gNsa = bandwidthMeter5gNsa.getBitrateEstimate();

assertThat(initialEstimate5gNsa).isGreaterThan(initialEstimate4g);
}

@Test
@Config(minSdk = 29) // 5G detection support was added in API 29.
public void defaultInitialBitrateEstimate_for5gSa_isGreaterThanEstimateFor3g() {
setActiveNetworkInfo(networkInfo3g);
DefaultBandwidthMeter bandwidthMeter3g =
new DefaultBandwidthMeter.Builder(ApplicationProvider.getApplicationContext()).build();
long initialEstimate3g = bandwidthMeter3g.getBitrateEstimate();

setActiveNetworkInfo(networkInfo5gSa);
DefaultBandwidthMeter bandwidthMeter5gSa =
new DefaultBandwidthMeter.Builder(ApplicationProvider.getApplicationContext()).build();
long initialEstimate5gSa = bandwidthMeter5gSa.getBitrateEstimate();

assertThat(initialEstimate5gSa).isGreaterThan(initialEstimate4g);
assertThat(initialEstimate5gSa).isGreaterThan(initialEstimate3g);
}

@Test
Expand Down Expand Up @@ -324,10 +362,16 @@ public void defaultInitialBitrateEstimate_forOffline_isReasonable() {
assertThat(initialEstimateFast).isGreaterThan(initialEstimateSlow);
}

@Config(sdk = 28) // TODO(b/190021699): Fix 4G tests to work on newer API levels
@Test
public void
defaultInitialBitrateEstimate_for4g_forFastCountry_isGreaterThanEstimateForSlowCountry() {
if (Util.SDK_INT == 29 || Util.SDK_INT == 30) {
// Robolectric doesn't support listening to service state changes, which we need on APIs 29
// and 30 to run this test successfully.
// TODO(b/190021699): Update once Robolectric released support for this.
return;
}

setActiveNetworkInfo(networkInfo4g);
setNetworkCountryIso(FAST_COUNTRY_ISO);
DefaultBandwidthMeter bandwidthMeterFast =
Expand All @@ -343,6 +387,32 @@ public void defaultInitialBitrateEstimate_forOffline_isReasonable() {
}

@Test
@Config(minSdk = 29) // 5G detection support was added in API 29.
public void
defaultInitialBitrateEstimate_for5gNsa_forFastCountry_isGreaterThanEstimateForSlowCountry() {
if (Util.SDK_INT == 29 || Util.SDK_INT == 30) {
// Robolectric doesn't support listening to service state changes, which we need on APIs 29
// and 30 to run this test successfully.
// TODO(b/190021699): Update once Robolectric released support for this.
return;
}

setActiveNetworkInfo(networkInfo4g, TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA);
setNetworkCountryIso(FAST_COUNTRY_ISO);
DefaultBandwidthMeter bandwidthMeterFast =
new DefaultBandwidthMeter.Builder(ApplicationProvider.getApplicationContext()).build();
long initialEstimateFast = bandwidthMeterFast.getBitrateEstimate();

setNetworkCountryIso(SLOW_COUNTRY_ISO);
DefaultBandwidthMeter bandwidthMeterSlow =
new DefaultBandwidthMeter.Builder(ApplicationProvider.getApplicationContext()).build();
long initialEstimateSlow = bandwidthMeterSlow.getBitrateEstimate();

assertThat(initialEstimateFast).isGreaterThan(initialEstimateSlow);
}

@Test
@Config(minSdk = 29) // 5G detection support was added in API 29.
public void
defaultInitialBitrateEstimate_for5gSa_forFastCountry_isGreaterThanEstimateForSlowCountry() {
setActiveNetworkInfo(networkInfo5gSa);
Expand Down Expand Up @@ -484,9 +554,15 @@ public void initialBitrateEstimateOverwrite_for3G_whileConnectedTo3G_setsInitial
assertThat(initialEstimate).isNotEqualTo(123456789);
}

@Config(sdk = 28) // TODO(b/190021699): Fix 4G tests to work on newer API levels
@Test
public void initialBitrateEstimateOverwrite_for4G_whileConnectedTo4G_setsInitialEstimate() {
if (Util.SDK_INT == 29 || Util.SDK_INT == 30) {
// Robolectric doesn't support listening to service state changes, which we need on APIs 29
// and 30 to run this test successfully.
// TODO(b/190021699): Update once Robolectric released support for this.
return;
}

setActiveNetworkInfo(networkInfo4g);
DefaultBandwidthMeter bandwidthMeter =
new DefaultBandwidthMeter.Builder(ApplicationProvider.getApplicationContext())
Expand All @@ -497,7 +573,6 @@ public void initialBitrateEstimateOverwrite_for4G_whileConnectedTo4G_setsInitial
assertThat(initialEstimate).isEqualTo(123456789);
}

@Config(sdk = 28) // TODO(b/190021699): Fix 4G tests to work on newer API levels
@Test
public void
initialBitrateEstimateOverwrite_for4G_whileConnectedToOtherNetwork_doesNotSetInitialEstimate() {
Expand All @@ -512,6 +587,41 @@ public void initialBitrateEstimateOverwrite_for4G_whileConnectedTo4G_setsInitial
}

@Test
@Config(minSdk = 29) // 5G detection support was added in API 29.
public void initialBitrateEstimateOverwrite_for5gNsa_whileConnectedTo5gNsa_setsInitialEstimate() {
if (Util.SDK_INT == 29 || Util.SDK_INT == 30) {
// Robolectric doesn't support listening to service state changes, which we need on APIs 29
// and 30 to run this test successfully.
// TODO(b/190021699): Update once Robolectric released support for this.
return;
}

setActiveNetworkInfo(networkInfo4g, TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA);
DefaultBandwidthMeter bandwidthMeter =
new DefaultBandwidthMeter.Builder(ApplicationProvider.getApplicationContext())
.setInitialBitrateEstimate(C.NETWORK_TYPE_5G_NSA, 123456789)
.build();
long initialEstimate = bandwidthMeter.getBitrateEstimate();

assertThat(initialEstimate).isEqualTo(123456789);
}

@Test
@Config(minSdk = 29) // 5G detection support was added in API 29.
public void
initialBitrateEstimateOverwrite_for5gNsa_whileConnectedToOtherNetwork_doesNotSetInitialEstimate() {
setActiveNetworkInfo(networkInfo4g);
DefaultBandwidthMeter bandwidthMeter =
new DefaultBandwidthMeter.Builder(ApplicationProvider.getApplicationContext())
.setInitialBitrateEstimate(C.NETWORK_TYPE_5G_NSA, 123456789)
.build();
long initialEstimate = bandwidthMeter.getBitrateEstimate();

assertThat(initialEstimate).isNotEqualTo(123456789);
}

@Test
@Config(minSdk = 29) // 5G detection support was added in API 29.
public void initialBitrateEstimateOverwrite_for5gSa_whileConnectedTo5gSa_setsInitialEstimate() {
setActiveNetworkInfo(networkInfo5gSa);
DefaultBandwidthMeter bandwidthMeter =
Expand All @@ -524,6 +634,7 @@ public void initialBitrateEstimateOverwrite_for5gSa_whileConnectedTo5gSa_setsIni
}

@Test
@Config(minSdk = 29) // 5G detection support was added in API 29.
public void
initialBitrateEstimateOverwrite_for5gSa_whileConnectedToOtherNetwork_doesNotSetInitialEstimate() {
setActiveNetworkInfo(networkInfoWifi);
Expand Down Expand Up @@ -636,11 +747,27 @@ public void defaultInitialBitrateEstimate_withoutContext_isReasonable() {
assertThat(initialEstimateWithoutBuilder).isLessThan(50_000_000L);
}

@SuppressWarnings("StickyBroadcast")
private void setActiveNetworkInfo(NetworkInfo networkInfo) {
setActiveNetworkInfo(networkInfo, TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE);
}

@SuppressWarnings("StickyBroadcast")
private void setActiveNetworkInfo(NetworkInfo networkInfo, int networkTypeOverride) {
// Set network info in ConnectivityManager and TelephonyDisplayInfo in TelephonyManager.
Shadows.shadowOf(connectivityManager).setActiveNetworkInfo(networkInfo);
if (Util.SDK_INT >= 31) {
Object displayInfo =
ShadowTelephonyManager.createTelephonyDisplayInfo(
networkInfo.getType(), networkTypeOverride);
Shadows.shadowOf(telephonyManager).setTelephonyDisplayInfo(displayInfo);
}
// Create a sticky broadcast for the connectivity action because Roboletric isn't replying with
// the current network state if a receiver for this intent is registered.
ApplicationProvider.getApplicationContext()
.sendStickyBroadcast(new Intent(ConnectivityManager.CONNECTIVITY_ACTION));
// Trigger initialization of static network type observer.
NetworkTypeObserver.getInstance(ApplicationProvider.getApplicationContext());
// Wait until all pending messages are handled and the network initialization is done.
ShadowLooper.idleMainLooper();
}

Expand Down

0 comments on commit b77204e

Please sign in to comment.