blob: c65f79340a0f3f089e33d6cecd6b2dba7b215ae3 [file] [log] [blame]
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.net.module.util;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static com.android.net.module.util.DeviceConfigUtils.FIXED_PACKAGE_VERSION;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import android.content.Context;
import android.content.pm.ModuleInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
import android.provider.DeviceConfig;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.MockitoSession;
/**
* Tests for DeviceConfigUtils.
*
*/
@RunWith(AndroidJUnit4.class)
@SmallTest
public class DeviceConfigUtilsTest {
private static final String TEST_NAME_SPACE = "connectivity";
private static final String TEST_EXPERIMENT_FLAG = "experiment_flag";
private static final int TEST_FLAG_VALUE = 28;
private static final String TEST_FLAG_VALUE_STRING = "28";
private static final int TEST_DEFAULT_FLAG_VALUE = 0;
private static final int TEST_MAX_FLAG_VALUE = 1000;
private static final int TEST_MIN_FLAG_VALUE = 100;
private static final long TEST_PACKAGE_VERSION = 290000000;
private static final String TEST_PACKAGE_NAME = "test.package.name";
private static final String TETHERING_AOSP_PACKAGE_NAME = "com.android.networkstack.tethering";
private static final String TEST_APEX_NAME = "test.apex.name";
private MockitoSession mSession;
@Mock private Context mContext;
@Mock private PackageManager mPm;
@Mock private ModuleInfo mMi;
@Mock private PackageInfo mPi;
@Mock private Resources mResources;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mSession = mockitoSession().spyStatic(DeviceConfig.class).startMocking();
final PackageInfo pi = new PackageInfo();
pi.setLongVersionCode(TEST_PACKAGE_VERSION);
doReturn(mPm).when(mContext).getPackageManager();
doReturn(TEST_PACKAGE_NAME).when(mContext).getPackageName();
doReturn(mMi).when(mPm).getModuleInfo(eq(TEST_APEX_NAME), anyInt());
doReturn(TEST_PACKAGE_NAME).when(mMi).getPackageName();
doReturn(pi).when(mPm).getPackageInfo(anyString(), anyInt());
doReturn(mResources).when(mContext).getResources();
}
@After
public void tearDown() {
mSession.finishMocking();
DeviceConfigUtils.resetPackageVersionCacheForTest();
}
@Test
public void testGetDeviceConfigPropertyInt_Null() {
doReturn(null).when(() -> DeviceConfig.getProperty(eq(TEST_NAME_SPACE),
eq(TEST_EXPERIMENT_FLAG)));
assertEquals(TEST_DEFAULT_FLAG_VALUE, DeviceConfigUtils.getDeviceConfigPropertyInt(
TEST_NAME_SPACE, TEST_EXPERIMENT_FLAG,
TEST_DEFAULT_FLAG_VALUE /* default value */));
}
@Test
public void testGetDeviceConfigPropertyInt_NotNull() {
doReturn(TEST_FLAG_VALUE_STRING).when(() -> DeviceConfig.getProperty(eq(TEST_NAME_SPACE),
eq(TEST_EXPERIMENT_FLAG)));
assertEquals(TEST_FLAG_VALUE, DeviceConfigUtils.getDeviceConfigPropertyInt(
TEST_NAME_SPACE, TEST_EXPERIMENT_FLAG,
TEST_DEFAULT_FLAG_VALUE /* default value */));
}
@Test
public void testGetDeviceConfigPropertyInt_NormalValue() {
doReturn(TEST_FLAG_VALUE_STRING).when(() -> DeviceConfig.getProperty(eq(TEST_NAME_SPACE),
eq(TEST_EXPERIMENT_FLAG)));
assertEquals(TEST_FLAG_VALUE, DeviceConfigUtils.getDeviceConfigPropertyInt(
TEST_NAME_SPACE, TEST_EXPERIMENT_FLAG, 0 /* minimum value */,
TEST_MAX_FLAG_VALUE /* maximum value */,
TEST_DEFAULT_FLAG_VALUE /* default value */));
}
@Test
public void testGetDeviceConfigPropertyInt_NullValue() {
doReturn(null).when(() -> DeviceConfig.getProperty(
eq(TEST_NAME_SPACE), eq(TEST_EXPERIMENT_FLAG)));
assertEquals(TEST_DEFAULT_FLAG_VALUE, DeviceConfigUtils.getDeviceConfigPropertyInt(
TEST_NAME_SPACE, TEST_EXPERIMENT_FLAG, 0 /* minimum value */,
TEST_MAX_FLAG_VALUE /* maximum value */,
TEST_DEFAULT_FLAG_VALUE /* default value */));
}
@Test
public void testGetDeviceConfigPropertyInt_OverMaximumValue() {
doReturn(Integer.toString(TEST_MAX_FLAG_VALUE + 10)).when(() -> DeviceConfig.getProperty(
eq(TEST_NAME_SPACE), eq(TEST_EXPERIMENT_FLAG)));
assertEquals(TEST_DEFAULT_FLAG_VALUE, DeviceConfigUtils.getDeviceConfigPropertyInt(
TEST_NAME_SPACE, TEST_EXPERIMENT_FLAG, TEST_MIN_FLAG_VALUE /* minimum value */,
TEST_MAX_FLAG_VALUE /* maximum value */,
TEST_DEFAULT_FLAG_VALUE /* default value */));
}
@Test
public void testGetDeviceConfigPropertyInt_EqualsMaximumValue() {
doReturn(Integer.toString(TEST_MAX_FLAG_VALUE)).when(() -> DeviceConfig.getProperty(
eq(TEST_NAME_SPACE), eq(TEST_EXPERIMENT_FLAG)));
assertEquals(TEST_MAX_FLAG_VALUE, DeviceConfigUtils.getDeviceConfigPropertyInt(
TEST_NAME_SPACE, TEST_EXPERIMENT_FLAG, TEST_MIN_FLAG_VALUE /* minimum value */,
TEST_MAX_FLAG_VALUE /* maximum value */,
TEST_DEFAULT_FLAG_VALUE /* default value */));
}
@Test
public void testGetDeviceConfigPropertyInt_BelowMinimumValue() {
doReturn(Integer.toString(TEST_MIN_FLAG_VALUE - 10)).when(() -> DeviceConfig.getProperty(
eq(TEST_NAME_SPACE), eq(TEST_EXPERIMENT_FLAG)));
assertEquals(TEST_DEFAULT_FLAG_VALUE, DeviceConfigUtils.getDeviceConfigPropertyInt(
TEST_NAME_SPACE, TEST_EXPERIMENT_FLAG, TEST_MIN_FLAG_VALUE /* minimum value */,
TEST_MAX_FLAG_VALUE /* maximum value */,
TEST_DEFAULT_FLAG_VALUE /* default value */));
}
@Test
public void testGetDeviceConfigPropertyInt_EqualsMinimumValue() {
doReturn(Integer.toString(TEST_MIN_FLAG_VALUE)).when(() -> DeviceConfig.getProperty(
eq(TEST_NAME_SPACE), eq(TEST_EXPERIMENT_FLAG)));
assertEquals(TEST_MIN_FLAG_VALUE, DeviceConfigUtils.getDeviceConfigPropertyInt(
TEST_NAME_SPACE, TEST_EXPERIMENT_FLAG, TEST_MIN_FLAG_VALUE /* minimum value */,
TEST_MAX_FLAG_VALUE /* maximum value */,
TEST_DEFAULT_FLAG_VALUE /* default value */));
}
@Test
public void testGetDeviceConfigPropertyBoolean_Null() {
doReturn(null).when(() -> DeviceConfig.getProperty(eq(TEST_NAME_SPACE),
eq(TEST_EXPERIMENT_FLAG)));
assertFalse(DeviceConfigUtils.getDeviceConfigPropertyBoolean(
TEST_NAME_SPACE, TEST_EXPERIMENT_FLAG,
false /* default value */));
}
@Test
public void testGetDeviceConfigPropertyBoolean_NotNull() {
doReturn("true").when(() -> DeviceConfig.getProperty(eq(TEST_NAME_SPACE),
eq(TEST_EXPERIMENT_FLAG)));
assertTrue(DeviceConfigUtils.getDeviceConfigPropertyBoolean(
TEST_NAME_SPACE, TEST_EXPERIMENT_FLAG,
false /* default value */));
}
@Test
public void testFeatureIsEnabled() {
doReturn(TEST_FLAG_VALUE_STRING).when(() -> DeviceConfig.getProperty(eq(TEST_NAME_SPACE),
eq(TEST_EXPERIMENT_FLAG)));
assertTrue(DeviceConfigUtils.isFeatureEnabled(mContext, TEST_NAME_SPACE,
TEST_EXPERIMENT_FLAG));
assertTrue(DeviceConfigUtils.isFeatureEnabled(mContext, TEST_NAME_SPACE,
TEST_EXPERIMENT_FLAG, TEST_APEX_NAME, false /* defaultEnabled */));
}
@Test
public void testFeatureDefaultEnabled() {
doReturn(null).when(() -> DeviceConfig.getProperty(eq(TEST_NAME_SPACE),
eq(TEST_EXPERIMENT_FLAG)));
assertFalse(DeviceConfigUtils.isFeatureEnabled(mContext, TEST_NAME_SPACE,
TEST_EXPERIMENT_FLAG));
assertFalse(DeviceConfigUtils.isFeatureEnabled(mContext, TEST_NAME_SPACE,
TEST_EXPERIMENT_FLAG, TEST_APEX_NAME, false /* defaultEnabled */));
assertTrue(DeviceConfigUtils.isFeatureEnabled(mContext, TEST_NAME_SPACE,
TEST_EXPERIMENT_FLAG, TEST_APEX_NAME, true /* defaultEnabled */));
}
@Test
public void testFeatureIsEnabledWithException() throws Exception {
doThrow(NameNotFoundException.class).when(mPm).getPackageInfo(anyString(), anyInt());
assertFalse(DeviceConfigUtils.isFeatureEnabled(mContext, TEST_NAME_SPACE,
TEST_EXPERIMENT_FLAG));
assertFalse(DeviceConfigUtils.isFeatureEnabled(mContext, TEST_NAME_SPACE,
TEST_EXPERIMENT_FLAG, TEST_APEX_NAME, false /* defaultEnabled */));
doThrow(NameNotFoundException.class).when(mPm).getModuleInfo(anyString(), anyInt());
assertFalse(DeviceConfigUtils.isFeatureEnabled(mContext, TEST_NAME_SPACE,
TEST_EXPERIMENT_FLAG, TEST_APEX_NAME, false /* defaultEnabled */));
}
@Test
public void testFeatureIsEnabledUsingFixedVersion() throws Exception {
doReturn(TETHERING_AOSP_PACKAGE_NAME).when(mContext).getPackageName();
doThrow(NameNotFoundException.class).when(mPm).getModuleInfo(anyString(), anyInt());
doReturn(Long.toString(FIXED_PACKAGE_VERSION)).when(() -> DeviceConfig.getProperty(
eq(TEST_NAME_SPACE), eq(TEST_EXPERIMENT_FLAG)));
assertTrue(DeviceConfigUtils.isFeatureEnabled(mContext, TEST_NAME_SPACE,
TEST_EXPERIMENT_FLAG, TEST_APEX_NAME, false /* defaultEnabled */));
doReturn(Long.toString(FIXED_PACKAGE_VERSION + 1)).when(() -> DeviceConfig.getProperty(
eq(TEST_NAME_SPACE), eq(TEST_EXPERIMENT_FLAG)));
assertFalse(DeviceConfigUtils.isFeatureEnabled(mContext, TEST_NAME_SPACE,
TEST_EXPERIMENT_FLAG, TEST_APEX_NAME, false /* defaultEnabled */));
doReturn(Long.toString(FIXED_PACKAGE_VERSION - 1)).when(() -> DeviceConfig.getProperty(
eq(TEST_NAME_SPACE), eq(TEST_EXPERIMENT_FLAG)));
assertTrue(DeviceConfigUtils.isFeatureEnabled(mContext, TEST_NAME_SPACE,
TEST_EXPERIMENT_FLAG, TEST_APEX_NAME, false /* defaultEnabled */));
}
@Test
public void testFeatureIsEnabledCaching() throws Exception {
doReturn(TEST_FLAG_VALUE_STRING).when(() -> DeviceConfig.getProperty(eq(TEST_NAME_SPACE),
eq(TEST_EXPERIMENT_FLAG)));
assertTrue(DeviceConfigUtils.isFeatureEnabled(mContext, TEST_NAME_SPACE,
TEST_EXPERIMENT_FLAG));
assertTrue(DeviceConfigUtils.isFeatureEnabled(mContext, TEST_NAME_SPACE,
TEST_EXPERIMENT_FLAG));
// Package info is only queried once
verify(mContext, times(1)).getPackageManager();
verify(mContext, times(1)).getPackageName();
verify(mPm, times(1)).getPackageInfo(anyString(), anyInt());
assertTrue(DeviceConfigUtils.isFeatureEnabled(mContext, TEST_NAME_SPACE,
TEST_EXPERIMENT_FLAG, TEST_APEX_NAME, false /* defaultEnabled */));
assertTrue(DeviceConfigUtils.isFeatureEnabled(mContext, TEST_NAME_SPACE,
TEST_EXPERIMENT_FLAG, TEST_APEX_NAME, false /* defaultEnabled */));
// Module info is only queried once
verify(mPm, times(1)).getModuleInfo(anyString(), anyInt());
}
@Test
public void testGetResBooleanConfig() {
final int someResId = 1234;
doReturn(true).when(mResources).getBoolean(someResId);
assertTrue(DeviceConfigUtils.getResBooleanConfig(mContext, someResId, false));
doReturn(false).when(mResources).getBoolean(someResId);
assertFalse(DeviceConfigUtils.getResBooleanConfig(mContext, someResId, false));
doThrow(new Resources.NotFoundException()).when(mResources).getBoolean(someResId);
assertFalse(DeviceConfigUtils.getResBooleanConfig(mContext, someResId, false));
}
}