Merge "Only restart SystemUI when Server Flags actually change." into tm-qpr-dev
This commit is contained in:
@@ -85,9 +85,34 @@ public class FeatureFlagsDebug implements FeatureFlags {
|
|||||||
private final ServerFlagReader.ChangeListener mOnPropertiesChanged =
|
private final ServerFlagReader.ChangeListener mOnPropertiesChanged =
|
||||||
new ServerFlagReader.ChangeListener() {
|
new ServerFlagReader.ChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onChange(Flag<?> flag) {
|
public void onChange(Flag<?> flag, String value) {
|
||||||
mRestarter.restartSystemUI(
|
boolean shouldRestart = false;
|
||||||
"Server flag change: " + flag.getNamespace() + "." + flag.getName());
|
if (mBooleanFlagCache.containsKey(flag.getName())) {
|
||||||
|
boolean newValue = value == null ? false : Boolean.parseBoolean(value);
|
||||||
|
if (mBooleanFlagCache.get(flag.getName()) != newValue) {
|
||||||
|
shouldRestart = true;
|
||||||
|
}
|
||||||
|
} else if (mStringFlagCache.containsKey(flag.getName())) {
|
||||||
|
String newValue = value == null ? "" : value;
|
||||||
|
if (mStringFlagCache.get(flag.getName()) != value) {
|
||||||
|
shouldRestart = true;
|
||||||
|
}
|
||||||
|
} else if (mIntFlagCache.containsKey(flag.getName())) {
|
||||||
|
int newValue = 0;
|
||||||
|
try {
|
||||||
|
newValue = value == null ? 0 : Integer.parseInt(value);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
}
|
||||||
|
if (mIntFlagCache.get(flag.getName()) != newValue) {
|
||||||
|
shouldRestart = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (shouldRestart) {
|
||||||
|
mRestarter.restartSystemUI(
|
||||||
|
"Server flag change: " + flag.getNamespace() + "."
|
||||||
|
+ flag.getName());
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -53,13 +53,38 @@ public class FeatureFlagsRelease implements FeatureFlags {
|
|||||||
private final Map<String, Flag<?>> mAllFlags;
|
private final Map<String, Flag<?>> mAllFlags;
|
||||||
private final Map<String, Boolean> mBooleanCache = new HashMap<>();
|
private final Map<String, Boolean> mBooleanCache = new HashMap<>();
|
||||||
private final Map<String, String> mStringCache = new HashMap<>();
|
private final Map<String, String> mStringCache = new HashMap<>();
|
||||||
|
private final Map<String, Integer> mIntCache = new HashMap<>();
|
||||||
|
|
||||||
private final ServerFlagReader.ChangeListener mOnPropertiesChanged =
|
private final ServerFlagReader.ChangeListener mOnPropertiesChanged =
|
||||||
new ServerFlagReader.ChangeListener() {
|
new ServerFlagReader.ChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onChange(Flag<?> flag) {
|
public void onChange(Flag<?> flag, String value) {
|
||||||
mRestarter.restartSystemUI(
|
boolean shouldRestart = false;
|
||||||
"Server flag change: " + flag.getNamespace() + "." + flag.getName());
|
if (mBooleanCache.containsKey(flag.getName())) {
|
||||||
|
boolean newValue = value == null ? false : Boolean.parseBoolean(value);
|
||||||
|
if (mBooleanCache.get(flag.getName()) != newValue) {
|
||||||
|
shouldRestart = true;
|
||||||
|
}
|
||||||
|
} else if (mStringCache.containsKey(flag.getName())) {
|
||||||
|
String newValue = value == null ? "" : value;
|
||||||
|
if (mStringCache.get(flag.getName()) != newValue) {
|
||||||
|
shouldRestart = true;
|
||||||
|
}
|
||||||
|
} else if (mIntCache.containsKey(flag.getName())) {
|
||||||
|
int newValue = 0;
|
||||||
|
try {
|
||||||
|
newValue = value == null ? 0 : Integer.parseInt(value);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
}
|
||||||
|
if (mIntCache.get(flag.getName()) != newValue) {
|
||||||
|
shouldRestart = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (shouldRestart) {
|
||||||
|
mRestarter.restartSystemUI(
|
||||||
|
"Server flag change: " + flag.getNamespace() + "."
|
||||||
|
+ flag.getName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -97,68 +122,97 @@ public class FeatureFlagsRelease implements FeatureFlags {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabled(@NotNull ReleasedFlag flag) {
|
public boolean isEnabled(@NotNull ReleasedFlag flag) {
|
||||||
return mServerFlagReader.readServerOverride(flag.getNamespace(), flag.getName(), true);
|
// Fill the cache.
|
||||||
|
return isEnabledInternal(flag.getName(),
|
||||||
|
mServerFlagReader.readServerOverride(flag.getNamespace(), flag.getName(), true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabled(ResourceBooleanFlag flag) {
|
public boolean isEnabled(ResourceBooleanFlag flag) {
|
||||||
if (!mBooleanCache.containsKey(flag.getName())) {
|
// Fill the cache.
|
||||||
return isEnabled(flag.getName(), mResources.getBoolean(flag.getResourceId()));
|
return isEnabledInternal(flag.getName(), mResources.getBoolean(flag.getResourceId()));
|
||||||
}
|
|
||||||
|
|
||||||
return mBooleanCache.get(flag.getName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabled(SysPropBooleanFlag flag) {
|
public boolean isEnabled(SysPropBooleanFlag flag) {
|
||||||
if (!mBooleanCache.containsKey(flag.getName())) {
|
// Fill the cache.
|
||||||
return isEnabled(
|
return isEnabledInternal(
|
||||||
flag.getName(),
|
flag.getName(),
|
||||||
mSystemProperties.getBoolean(flag.getName(), flag.getDefault()));
|
mSystemProperties.getBoolean(flag.getName(), flag.getDefault()));
|
||||||
}
|
|
||||||
|
|
||||||
return mBooleanCache.get(flag.getName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isEnabled(String name, boolean defaultValue) {
|
/**
|
||||||
mBooleanCache.put(name, defaultValue);
|
* Checks and fills the boolean cache. This is important, Always call through to this method!
|
||||||
return defaultValue;
|
*
|
||||||
|
* We use the cache as a way to decide if we need to restart the process when server-side
|
||||||
|
* changes occur.
|
||||||
|
*/
|
||||||
|
private boolean isEnabledInternal(String name, boolean defaultValue) {
|
||||||
|
// Fill the cache.
|
||||||
|
if (!mBooleanCache.containsKey(name)) {
|
||||||
|
mBooleanCache.put(name, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mBooleanCache.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public String getString(@NonNull StringFlag flag) {
|
public String getString(@NonNull StringFlag flag) {
|
||||||
return getString(flag.getName(), flag.getDefault());
|
// Fill the cache.
|
||||||
|
return getStringInternal(flag.getName(), flag.getDefault());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public String getString(@NonNull ResourceStringFlag flag) {
|
public String getString(@NonNull ResourceStringFlag flag) {
|
||||||
if (!mStringCache.containsKey(flag.getName())) {
|
// Fill the cache.
|
||||||
return getString(flag.getName(),
|
return getStringInternal(flag.getName(),
|
||||||
requireNonNull(mResources.getString(flag.getResourceId())));
|
requireNonNull(mResources.getString(flag.getResourceId())));
|
||||||
}
|
|
||||||
|
|
||||||
return mStringCache.get(flag.getName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getString(String name, String defaultValue) {
|
/**
|
||||||
mStringCache.put(name, defaultValue);
|
* Checks and fills the String cache. This is important, Always call through to this method!
|
||||||
return defaultValue;
|
*
|
||||||
|
* We use the cache as a way to decide if we need to restart the process when server-side
|
||||||
|
* changes occur.
|
||||||
|
*/
|
||||||
|
private String getStringInternal(String name, String defaultValue) {
|
||||||
|
if (!mStringCache.containsKey(name)) {
|
||||||
|
mStringCache.put(name, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mStringCache.get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public int getInt(@NonNull IntFlag flag) {
|
public int getInt(@NonNull IntFlag flag) {
|
||||||
return flag.getDefault();
|
// Fill the cache.
|
||||||
|
return getIntInternal(flag.getName(), flag.getDefault());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public int getInt(@NonNull ResourceIntFlag flag) {
|
public int getInt(@NonNull ResourceIntFlag flag) {
|
||||||
|
// Fill the cache.
|
||||||
return mResources.getInteger(flag.getResourceId());
|
return mResources.getInteger(flag.getResourceId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks and fills the integer cache. This is important, Always call through to this method!
|
||||||
|
*
|
||||||
|
* We use the cache as a way to decide if we need to restart the process when server-side
|
||||||
|
* changes occur.
|
||||||
|
*/
|
||||||
|
private int getIntInternal(String name, int defaultValue) {
|
||||||
|
if (!mIntCache.containsKey(name)) {
|
||||||
|
mIntCache.put(name, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mIntCache.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
|
public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
|
||||||
pw.println("can override: false");
|
pw.println("can override: false");
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ interface ServerFlagReader {
|
|||||||
fun listenForChanges(values: Collection<Flag<*>>, listener: ChangeListener)
|
fun listenForChanges(values: Collection<Flag<*>>, listener: ChangeListener)
|
||||||
|
|
||||||
interface ChangeListener {
|
interface ChangeListener {
|
||||||
fun onChange(flag: Flag<*>)
|
fun onChange(flag: Flag<*>, value: String?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ class ServerFlagReaderImpl @Inject constructor(
|
|||||||
propLoop@ for (propName in properties.keyset) {
|
propLoop@ for (propName in properties.keyset) {
|
||||||
for (flag in flags) {
|
for (flag in flags) {
|
||||||
if (propName == flag.name) {
|
if (propName == flag.name) {
|
||||||
listener.onChange(flag)
|
listener.onChange(flag, properties.getString(propName, null))
|
||||||
break@propLoop
|
break@propLoop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -144,7 +144,7 @@ class ServerFlagReaderFake : ServerFlagReader {
|
|||||||
for ((listener, flags) in listeners) {
|
for ((listener, flags) in listeners) {
|
||||||
flagLoop@ for (flag in flags) {
|
flagLoop@ for (flag in flags) {
|
||||||
if (name == flag.name) {
|
if (name == flag.name) {
|
||||||
listener.onChange(flag)
|
listener.onChange(flag, if (value) "true" else "false")
|
||||||
break@flagLoop
|
break@flagLoop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -159,5 +159,6 @@ class ServerFlagReaderFake : ServerFlagReader {
|
|||||||
flags: Collection<Flag<*>>,
|
flags: Collection<Flag<*>>,
|
||||||
listener: ServerFlagReader.ChangeListener
|
listener: ServerFlagReader.ChangeListener
|
||||||
) {
|
) {
|
||||||
|
listeners.add(Pair(listener, flags))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import org.mockito.Mock
|
|||||||
import org.mockito.Mockito.anyBoolean
|
import org.mockito.Mockito.anyBoolean
|
||||||
import org.mockito.Mockito.anyString
|
import org.mockito.Mockito.anyString
|
||||||
import org.mockito.Mockito.inOrder
|
import org.mockito.Mockito.inOrder
|
||||||
|
import org.mockito.Mockito.never
|
||||||
import org.mockito.Mockito.times
|
import org.mockito.Mockito.times
|
||||||
import org.mockito.Mockito.verify
|
import org.mockito.Mockito.verify
|
||||||
import org.mockito.Mockito.verifyNoMoreInteractions
|
import org.mockito.Mockito.verifyNoMoreInteractions
|
||||||
@@ -53,7 +54,7 @@ import org.mockito.Mockito.`when` as whenever
|
|||||||
*/
|
*/
|
||||||
@SmallTest
|
@SmallTest
|
||||||
class FeatureFlagsDebugTest : SysuiTestCase() {
|
class FeatureFlagsDebugTest : SysuiTestCase() {
|
||||||
private lateinit var mFeatureFlagsDebug: FeatureFlagsDebug
|
private lateinit var featureFlagsDebug: FeatureFlagsDebug
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private lateinit var flagManager: FlagManager
|
private lateinit var flagManager: FlagManager
|
||||||
@@ -85,7 +86,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
flagMap.put(Flags.TEAMFOOD.name, Flags.TEAMFOOD)
|
flagMap.put(Flags.TEAMFOOD.name, Flags.TEAMFOOD)
|
||||||
flagMap.put(teamfoodableFlagA.name, teamfoodableFlagA)
|
flagMap.put(teamfoodableFlagA.name, teamfoodableFlagA)
|
||||||
flagMap.put(teamfoodableFlagB.name, teamfoodableFlagB)
|
flagMap.put(teamfoodableFlagB.name, teamfoodableFlagB)
|
||||||
mFeatureFlagsDebug = FeatureFlagsDebug(
|
featureFlagsDebug = FeatureFlagsDebug(
|
||||||
flagManager,
|
flagManager,
|
||||||
mockContext,
|
mockContext,
|
||||||
globalSettings,
|
globalSettings,
|
||||||
@@ -95,7 +96,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
flagMap,
|
flagMap,
|
||||||
restarter
|
restarter
|
||||||
)
|
)
|
||||||
mFeatureFlagsDebug.init()
|
featureFlagsDebug.init()
|
||||||
verify(flagManager).onSettingsChangedAction = any()
|
verify(flagManager).onSettingsChangedAction = any()
|
||||||
broadcastReceiver = withArgCaptor {
|
broadcastReceiver = withArgCaptor {
|
||||||
verify(mockContext).registerReceiver(
|
verify(mockContext).registerReceiver(
|
||||||
@@ -116,7 +117,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
whenever(flagManager.readFlagValue<Boolean>(eq("4"), any())).thenReturn(false)
|
whenever(flagManager.readFlagValue<Boolean>(eq("4"), any())).thenReturn(false)
|
||||||
|
|
||||||
assertThat(
|
assertThat(
|
||||||
mFeatureFlagsDebug.isEnabled(
|
featureFlagsDebug.isEnabled(
|
||||||
ReleasedFlag(
|
ReleasedFlag(
|
||||||
2,
|
2,
|
||||||
name = "2",
|
name = "2",
|
||||||
@@ -125,7 +126,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
)
|
)
|
||||||
).isTrue()
|
).isTrue()
|
||||||
assertThat(
|
assertThat(
|
||||||
mFeatureFlagsDebug.isEnabled(
|
featureFlagsDebug.isEnabled(
|
||||||
UnreleasedFlag(
|
UnreleasedFlag(
|
||||||
3,
|
3,
|
||||||
name = "3",
|
name = "3",
|
||||||
@@ -134,7 +135,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
)
|
)
|
||||||
).isTrue()
|
).isTrue()
|
||||||
assertThat(
|
assertThat(
|
||||||
mFeatureFlagsDebug.isEnabled(
|
featureFlagsDebug.isEnabled(
|
||||||
ReleasedFlag(
|
ReleasedFlag(
|
||||||
4,
|
4,
|
||||||
name = "4",
|
name = "4",
|
||||||
@@ -143,7 +144,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
)
|
)
|
||||||
).isFalse()
|
).isFalse()
|
||||||
assertThat(
|
assertThat(
|
||||||
mFeatureFlagsDebug.isEnabled(
|
featureFlagsDebug.isEnabled(
|
||||||
UnreleasedFlag(
|
UnreleasedFlag(
|
||||||
5,
|
5,
|
||||||
name = "5",
|
name = "5",
|
||||||
@@ -157,8 +158,8 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
fun teamFoodFlag_False() {
|
fun teamFoodFlag_False() {
|
||||||
whenever(flagManager.readFlagValue<Boolean>(
|
whenever(flagManager.readFlagValue<Boolean>(
|
||||||
eq(Flags.TEAMFOOD.name), any())).thenReturn(false)
|
eq(Flags.TEAMFOOD.name), any())).thenReturn(false)
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagA)).isFalse()
|
assertThat(featureFlagsDebug.isEnabled(teamfoodableFlagA)).isFalse()
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagB)).isTrue()
|
assertThat(featureFlagsDebug.isEnabled(teamfoodableFlagB)).isTrue()
|
||||||
|
|
||||||
// Regular boolean flags should still test the same.
|
// Regular boolean flags should still test the same.
|
||||||
// Only our teamfoodableFlag should change.
|
// Only our teamfoodableFlag should change.
|
||||||
@@ -169,8 +170,8 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
fun teamFoodFlag_True() {
|
fun teamFoodFlag_True() {
|
||||||
whenever(flagManager.readFlagValue<Boolean>(
|
whenever(flagManager.readFlagValue<Boolean>(
|
||||||
eq(Flags.TEAMFOOD.name), any())).thenReturn(true)
|
eq(Flags.TEAMFOOD.name), any())).thenReturn(true)
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagA)).isTrue()
|
assertThat(featureFlagsDebug.isEnabled(teamfoodableFlagA)).isTrue()
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagB)).isTrue()
|
assertThat(featureFlagsDebug.isEnabled(teamfoodableFlagB)).isTrue()
|
||||||
|
|
||||||
// Regular boolean flags should still test the same.
|
// Regular boolean flags should still test the same.
|
||||||
// Only our teamfoodableFlag should change.
|
// Only our teamfoodableFlag should change.
|
||||||
@@ -185,8 +186,8 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
.thenReturn(false)
|
.thenReturn(false)
|
||||||
whenever(flagManager.readFlagValue<Boolean>(
|
whenever(flagManager.readFlagValue<Boolean>(
|
||||||
eq(Flags.TEAMFOOD.name), any())).thenReturn(true)
|
eq(Flags.TEAMFOOD.name), any())).thenReturn(true)
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagA)).isTrue()
|
assertThat(featureFlagsDebug.isEnabled(teamfoodableFlagA)).isTrue()
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagB)).isFalse()
|
assertThat(featureFlagsDebug.isEnabled(teamfoodableFlagB)).isFalse()
|
||||||
|
|
||||||
// Regular boolean flags should still test the same.
|
// Regular boolean flags should still test the same.
|
||||||
// Only our teamfoodableFlag should change.
|
// Only our teamfoodableFlag should change.
|
||||||
@@ -205,7 +206,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
whenever(flagManager.readFlagValue<Boolean>(eq("5"), any())).thenReturn(false)
|
whenever(flagManager.readFlagValue<Boolean>(eq("5"), any())).thenReturn(false)
|
||||||
|
|
||||||
assertThat(
|
assertThat(
|
||||||
mFeatureFlagsDebug.isEnabled(
|
featureFlagsDebug.isEnabled(
|
||||||
ResourceBooleanFlag(
|
ResourceBooleanFlag(
|
||||||
1,
|
1,
|
||||||
"1",
|
"1",
|
||||||
@@ -214,16 +215,16 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
).isFalse()
|
).isFalse()
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(ResourceBooleanFlag(2, "2", "test", 1002))).isTrue()
|
assertThat(featureFlagsDebug.isEnabled(ResourceBooleanFlag(2, "2", "test", 1002))).isTrue()
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(ResourceBooleanFlag(3, "3", "test", 1003))).isTrue()
|
assertThat(featureFlagsDebug.isEnabled(ResourceBooleanFlag(3, "3", "test", 1003))).isTrue()
|
||||||
|
|
||||||
Assert.assertThrows(NameNotFoundException::class.java) {
|
Assert.assertThrows(NameNotFoundException::class.java) {
|
||||||
mFeatureFlagsDebug.isEnabled(ResourceBooleanFlag(4, "4", "test", 1004))
|
featureFlagsDebug.isEnabled(ResourceBooleanFlag(4, "4", "test", 1004))
|
||||||
}
|
}
|
||||||
// Test that resource is loaded (and validated) even when the setting is set.
|
// Test that resource is loaded (and validated) even when the setting is set.
|
||||||
// This prevents developers from not noticing when they reference an invalid resource.
|
// This prevents developers from not noticing when they reference an invalid resource.
|
||||||
Assert.assertThrows(NameNotFoundException::class.java) {
|
Assert.assertThrows(NameNotFoundException::class.java) {
|
||||||
mFeatureFlagsDebug.isEnabled(ResourceBooleanFlag(5, "5", "test", 1005))
|
featureFlagsDebug.isEnabled(ResourceBooleanFlag(5, "5", "test", 1005))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,11 +237,11 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
return@thenAnswer it.getArgument(1)
|
return@thenAnswer it.getArgument(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(1, "a", "test"))).isFalse()
|
assertThat(featureFlagsDebug.isEnabled(SysPropBooleanFlag(1, "a", "test"))).isFalse()
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(2, "b", "test"))).isTrue()
|
assertThat(featureFlagsDebug.isEnabled(SysPropBooleanFlag(2, "b", "test"))).isTrue()
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(3, "c", "test", true))).isTrue()
|
assertThat(featureFlagsDebug.isEnabled(SysPropBooleanFlag(3, "c", "test", true))).isTrue()
|
||||||
assertThat(
|
assertThat(
|
||||||
mFeatureFlagsDebug.isEnabled(
|
featureFlagsDebug.isEnabled(
|
||||||
SysPropBooleanFlag(
|
SysPropBooleanFlag(
|
||||||
4,
|
4,
|
||||||
"d",
|
"d",
|
||||||
@@ -249,17 +250,17 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
).isFalse()
|
).isFalse()
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(5, "e", "test"))).isFalse()
|
assertThat(featureFlagsDebug.isEnabled(SysPropBooleanFlag(5, "e", "test"))).isFalse()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun readStringFlag() {
|
fun readStringFlag() {
|
||||||
whenever(flagManager.readFlagValue<String>(eq("3"), any())).thenReturn("foo")
|
whenever(flagManager.readFlagValue<String>(eq("3"), any())).thenReturn("foo")
|
||||||
whenever(flagManager.readFlagValue<String>(eq("4"), any())).thenReturn("bar")
|
whenever(flagManager.readFlagValue<String>(eq("4"), any())).thenReturn("bar")
|
||||||
assertThat(mFeatureFlagsDebug.getString(StringFlag(1, "1", "test", "biz"))).isEqualTo("biz")
|
assertThat(featureFlagsDebug.getString(StringFlag(1, "1", "test", "biz"))).isEqualTo("biz")
|
||||||
assertThat(mFeatureFlagsDebug.getString(StringFlag(2, "2", "test", "baz"))).isEqualTo("baz")
|
assertThat(featureFlagsDebug.getString(StringFlag(2, "2", "test", "baz"))).isEqualTo("baz")
|
||||||
assertThat(mFeatureFlagsDebug.getString(StringFlag(3, "3", "test", "buz"))).isEqualTo("foo")
|
assertThat(featureFlagsDebug.getString(StringFlag(3, "3", "test", "buz"))).isEqualTo("foo")
|
||||||
assertThat(mFeatureFlagsDebug.getString(StringFlag(4, "4", "test", "buz"))).isEqualTo("bar")
|
assertThat(featureFlagsDebug.getString(StringFlag(4, "4", "test", "buz"))).isEqualTo("bar")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -276,7 +277,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
whenever(flagManager.readFlagValue<String>(eq("6"), any())).thenReturn("override6")
|
whenever(flagManager.readFlagValue<String>(eq("6"), any())).thenReturn("override6")
|
||||||
|
|
||||||
assertThat(
|
assertThat(
|
||||||
mFeatureFlagsDebug.getString(
|
featureFlagsDebug.getString(
|
||||||
ResourceStringFlag(
|
ResourceStringFlag(
|
||||||
1,
|
1,
|
||||||
"1",
|
"1",
|
||||||
@@ -286,7 +287,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
)
|
)
|
||||||
).isEqualTo("")
|
).isEqualTo("")
|
||||||
assertThat(
|
assertThat(
|
||||||
mFeatureFlagsDebug.getString(
|
featureFlagsDebug.getString(
|
||||||
ResourceStringFlag(
|
ResourceStringFlag(
|
||||||
2,
|
2,
|
||||||
"2",
|
"2",
|
||||||
@@ -296,7 +297,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
)
|
)
|
||||||
).isEqualTo("resource2")
|
).isEqualTo("resource2")
|
||||||
assertThat(
|
assertThat(
|
||||||
mFeatureFlagsDebug.getString(
|
featureFlagsDebug.getString(
|
||||||
ResourceStringFlag(
|
ResourceStringFlag(
|
||||||
3,
|
3,
|
||||||
"3",
|
"3",
|
||||||
@@ -307,15 +308,15 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
).isEqualTo("override3")
|
).isEqualTo("override3")
|
||||||
|
|
||||||
Assert.assertThrows(NullPointerException::class.java) {
|
Assert.assertThrows(NullPointerException::class.java) {
|
||||||
mFeatureFlagsDebug.getString(ResourceStringFlag(4, "4", "test", 1004))
|
featureFlagsDebug.getString(ResourceStringFlag(4, "4", "test", 1004))
|
||||||
}
|
}
|
||||||
Assert.assertThrows(NameNotFoundException::class.java) {
|
Assert.assertThrows(NameNotFoundException::class.java) {
|
||||||
mFeatureFlagsDebug.getString(ResourceStringFlag(5, "5", "test", 1005))
|
featureFlagsDebug.getString(ResourceStringFlag(5, "5", "test", 1005))
|
||||||
}
|
}
|
||||||
// Test that resource is loaded (and validated) even when the setting is set.
|
// Test that resource is loaded (and validated) even when the setting is set.
|
||||||
// This prevents developers from not noticing when they reference an invalid resource.
|
// This prevents developers from not noticing when they reference an invalid resource.
|
||||||
Assert.assertThrows(NameNotFoundException::class.java) {
|
Assert.assertThrows(NameNotFoundException::class.java) {
|
||||||
mFeatureFlagsDebug.getString(ResourceStringFlag(6, "6", "test", 1005))
|
featureFlagsDebug.getString(ResourceStringFlag(6, "6", "test", 1005))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,10 +324,10 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
fun readIntFlag() {
|
fun readIntFlag() {
|
||||||
whenever(flagManager.readFlagValue<Int>(eq("3"), any())).thenReturn(22)
|
whenever(flagManager.readFlagValue<Int>(eq("3"), any())).thenReturn(22)
|
||||||
whenever(flagManager.readFlagValue<Int>(eq("4"), any())).thenReturn(48)
|
whenever(flagManager.readFlagValue<Int>(eq("4"), any())).thenReturn(48)
|
||||||
assertThat(mFeatureFlagsDebug.getInt(IntFlag(1, "1", "test", 12))).isEqualTo(12)
|
assertThat(featureFlagsDebug.getInt(IntFlag(1, "1", "test", 12))).isEqualTo(12)
|
||||||
assertThat(mFeatureFlagsDebug.getInt(IntFlag(2, "2", "test", 93))).isEqualTo(93)
|
assertThat(featureFlagsDebug.getInt(IntFlag(2, "2", "test", 93))).isEqualTo(93)
|
||||||
assertThat(mFeatureFlagsDebug.getInt(IntFlag(3, "3", "test", 8))).isEqualTo(22)
|
assertThat(featureFlagsDebug.getInt(IntFlag(3, "3", "test", 8))).isEqualTo(22)
|
||||||
assertThat(mFeatureFlagsDebug.getInt(IntFlag(4, "4", "test", 234))).isEqualTo(48)
|
assertThat(featureFlagsDebug.getInt(IntFlag(4, "4", "test", 234))).isEqualTo(48)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -342,17 +343,17 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
whenever(flagManager.readFlagValue<Int>(eq(4), any())).thenReturn(500)
|
whenever(flagManager.readFlagValue<Int>(eq(4), any())).thenReturn(500)
|
||||||
whenever(flagManager.readFlagValue<Int>(eq(5), any())).thenReturn(9519)
|
whenever(flagManager.readFlagValue<Int>(eq(5), any())).thenReturn(9519)
|
||||||
|
|
||||||
assertThat(mFeatureFlagsDebug.getInt(ResourceIntFlag(1, "1", "test", 1001))).isEqualTo(88)
|
assertThat(featureFlagsDebug.getInt(ResourceIntFlag(1, "1", "test", 1001))).isEqualTo(88)
|
||||||
assertThat(mFeatureFlagsDebug.getInt(ResourceIntFlag(2, "2", "test", 1002))).isEqualTo(61)
|
assertThat(featureFlagsDebug.getInt(ResourceIntFlag(2, "2", "test", 1002))).isEqualTo(61)
|
||||||
assertThat(mFeatureFlagsDebug.getInt(ResourceIntFlag(3, "3", "test", 1003))).isEqualTo(20)
|
assertThat(featureFlagsDebug.getInt(ResourceIntFlag(3, "3", "test", 1003))).isEqualTo(20)
|
||||||
|
|
||||||
Assert.assertThrows(NotFoundException::class.java) {
|
Assert.assertThrows(NotFoundException::class.java) {
|
||||||
mFeatureFlagsDebug.getInt(ResourceIntFlag(4, "4", "test", 1004))
|
featureFlagsDebug.getInt(ResourceIntFlag(4, "4", "test", 1004))
|
||||||
}
|
}
|
||||||
// Test that resource is loaded (and validated) even when the setting is set.
|
// Test that resource is loaded (and validated) even when the setting is set.
|
||||||
// This prevents developers from not noticing when they reference an invalid resource.
|
// This prevents developers from not noticing when they reference an invalid resource.
|
||||||
Assert.assertThrows(NotFoundException::class.java) {
|
Assert.assertThrows(NotFoundException::class.java) {
|
||||||
mFeatureFlagsDebug.getInt(ResourceIntFlag(5, "5", "test", 1005))
|
featureFlagsDebug.getInt(ResourceIntFlag(5, "5", "test", 1005))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -432,11 +433,11 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
whenever(flagManager.readFlagValue<String>(eq("1"), any())).thenReturn("original")
|
whenever(flagManager.readFlagValue<String>(eq("1"), any())).thenReturn("original")
|
||||||
|
|
||||||
// gets the flag & cache it
|
// gets the flag & cache it
|
||||||
assertThat(mFeatureFlagsDebug.getString(flag1)).isEqualTo("original")
|
assertThat(featureFlagsDebug.getString(flag1)).isEqualTo("original")
|
||||||
verify(flagManager, times(1)).readFlagValue(eq("1"), eq(StringFlagSerializer))
|
verify(flagManager, times(1)).readFlagValue(eq("1"), eq(StringFlagSerializer))
|
||||||
|
|
||||||
// hit the cache
|
// hit the cache
|
||||||
assertThat(mFeatureFlagsDebug.getString(flag1)).isEqualTo("original")
|
assertThat(featureFlagsDebug.getString(flag1)).isEqualTo("original")
|
||||||
verifyNoMoreInteractions(flagManager)
|
verifyNoMoreInteractions(flagManager)
|
||||||
|
|
||||||
// set the flag
|
// set the flag
|
||||||
@@ -444,7 +445,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
verifyPutData("1", "{\"type\":\"string\",\"value\":\"new\"}", numReads = 2)
|
verifyPutData("1", "{\"type\":\"string\",\"value\":\"new\"}", numReads = 2)
|
||||||
whenever(flagManager.readFlagValue<String>(eq("1"), any())).thenReturn("new")
|
whenever(flagManager.readFlagValue<String>(eq("1"), any())).thenReturn("new")
|
||||||
|
|
||||||
assertThat(mFeatureFlagsDebug.getString(flag1)).isEqualTo("new")
|
assertThat(featureFlagsDebug.getString(flag1)).isEqualTo("new")
|
||||||
verify(flagManager, times(3)).readFlagValue(eq("1"), eq(StringFlagSerializer))
|
verify(flagManager, times(3)).readFlagValue(eq("1"), eq(StringFlagSerializer))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -454,7 +455,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
|
|
||||||
serverFlagReader.setFlagValue(flag.namespace, flag.name, false)
|
serverFlagReader.setFlagValue(flag.namespace, flag.name, false)
|
||||||
|
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(flag)).isFalse()
|
assertThat(featureFlagsDebug.isEnabled(flag)).isFalse()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -462,7 +463,33 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
val flag = UnreleasedFlag(100, name = "100", namespace = "test")
|
val flag = UnreleasedFlag(100, name = "100", namespace = "test")
|
||||||
|
|
||||||
serverFlagReader.setFlagValue(flag.namespace, flag.name, true)
|
serverFlagReader.setFlagValue(flag.namespace, flag.name, true)
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(flag)).isTrue()
|
assertThat(featureFlagsDebug.isEnabled(flag)).isTrue()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun serverSide_OverrideUncached_NoRestart() {
|
||||||
|
// No one has read the flag, so it's not in the cache.
|
||||||
|
serverFlagReader.setFlagValue(
|
||||||
|
teamfoodableFlagA.namespace, teamfoodableFlagA.name, !teamfoodableFlagA.default)
|
||||||
|
verify(restarter, never()).restartSystemUI(anyString())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun serverSide_Override_Restarts() {
|
||||||
|
// Read it to put it in the cache.
|
||||||
|
featureFlagsDebug.isEnabled(teamfoodableFlagA)
|
||||||
|
serverFlagReader.setFlagValue(
|
||||||
|
teamfoodableFlagA.namespace, teamfoodableFlagA.name, !teamfoodableFlagA.default)
|
||||||
|
verify(restarter).restartSystemUI(anyString())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun serverSide_RedundantOverride_NoRestart() {
|
||||||
|
// Read it to put it in the cache.
|
||||||
|
featureFlagsDebug.isEnabled(teamfoodableFlagA)
|
||||||
|
serverFlagReader.setFlagValue(
|
||||||
|
teamfoodableFlagA.namespace, teamfoodableFlagA.name, teamfoodableFlagA.default)
|
||||||
|
verify(restarter, never()).restartSystemUI(anyString())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -482,13 +509,13 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
.thenReturn("override7")
|
.thenReturn("override7")
|
||||||
|
|
||||||
// WHEN the flags have been accessed
|
// WHEN the flags have been accessed
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(flag1)).isTrue()
|
assertThat(featureFlagsDebug.isEnabled(flag1)).isTrue()
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(flag2)).isTrue()
|
assertThat(featureFlagsDebug.isEnabled(flag2)).isTrue()
|
||||||
assertThat(mFeatureFlagsDebug.isEnabled(flag3)).isFalse()
|
assertThat(featureFlagsDebug.isEnabled(flag3)).isFalse()
|
||||||
assertThat(mFeatureFlagsDebug.getString(flag4)).isEmpty()
|
assertThat(featureFlagsDebug.getString(flag4)).isEmpty()
|
||||||
assertThat(mFeatureFlagsDebug.getString(flag5)).isEqualTo("flag5default")
|
assertThat(featureFlagsDebug.getString(flag5)).isEqualTo("flag5default")
|
||||||
assertThat(mFeatureFlagsDebug.getString(flag6)).isEqualTo("resource1006")
|
assertThat(featureFlagsDebug.getString(flag6)).isEqualTo("resource1006")
|
||||||
assertThat(mFeatureFlagsDebug.getString(flag7)).isEqualTo("override7")
|
assertThat(featureFlagsDebug.getString(flag7)).isEqualTo("override7")
|
||||||
|
|
||||||
// THEN the dump contains the flags and the default values
|
// THEN the dump contains the flags and the default values
|
||||||
val dump = dumpToString()
|
val dump = dumpToString()
|
||||||
@@ -527,7 +554,7 @@ class FeatureFlagsDebugTest : SysuiTestCase() {
|
|||||||
private fun dumpToString(): String {
|
private fun dumpToString(): String {
|
||||||
val sw = StringWriter()
|
val sw = StringWriter()
|
||||||
val pw = PrintWriter(sw)
|
val pw = PrintWriter(sw)
|
||||||
mFeatureFlagsDebug.dump(pw, emptyArray<String>())
|
featureFlagsDebug.dump(pw, emptyArray<String>())
|
||||||
pw.flush()
|
pw.flush()
|
||||||
return sw.toString()
|
return sw.toString()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ import org.junit.Assert.assertThrows
|
|||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
|
import org.mockito.Mockito
|
||||||
|
import org.mockito.Mockito.never
|
||||||
import org.mockito.MockitoAnnotations
|
import org.mockito.MockitoAnnotations
|
||||||
import org.mockito.Mockito.`when` as whenever
|
import org.mockito.Mockito.`when` as whenever
|
||||||
|
|
||||||
@@ -33,7 +35,7 @@ import org.mockito.Mockito.`when` as whenever
|
|||||||
*/
|
*/
|
||||||
@SmallTest
|
@SmallTest
|
||||||
class FeatureFlagsReleaseTest : SysuiTestCase() {
|
class FeatureFlagsReleaseTest : SysuiTestCase() {
|
||||||
private lateinit var mFeatureFlagsRelease: FeatureFlagsRelease
|
private lateinit var featureFlagsRelease: FeatureFlagsRelease
|
||||||
|
|
||||||
@Mock private lateinit var mResources: Resources
|
@Mock private lateinit var mResources: Resources
|
||||||
@Mock private lateinit var mSystemProperties: SystemPropertiesHelper
|
@Mock private lateinit var mSystemProperties: SystemPropertiesHelper
|
||||||
@@ -41,15 +43,21 @@ class FeatureFlagsReleaseTest : SysuiTestCase() {
|
|||||||
private val flagMap = mutableMapOf<String, Flag<*>>()
|
private val flagMap = mutableMapOf<String, Flag<*>>()
|
||||||
private val serverFlagReader = ServerFlagReaderFake()
|
private val serverFlagReader = ServerFlagReaderFake()
|
||||||
|
|
||||||
|
|
||||||
|
private val flagA = ReleasedFlag(501, name = "a", namespace = "test")
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
MockitoAnnotations.initMocks(this)
|
MockitoAnnotations.initMocks(this)
|
||||||
mFeatureFlagsRelease = FeatureFlagsRelease(
|
flagMap.put(flagA.name, flagA)
|
||||||
|
featureFlagsRelease = FeatureFlagsRelease(
|
||||||
mResources,
|
mResources,
|
||||||
mSystemProperties,
|
mSystemProperties,
|
||||||
serverFlagReader,
|
serverFlagReader,
|
||||||
flagMap,
|
flagMap,
|
||||||
restarter)
|
restarter)
|
||||||
|
|
||||||
|
featureFlagsRelease.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -60,7 +68,7 @@ class FeatureFlagsReleaseTest : SysuiTestCase() {
|
|||||||
val flagNamespace = "test"
|
val flagNamespace = "test"
|
||||||
val flag = ResourceBooleanFlag(flagId, flagName, flagNamespace, flagResourceId)
|
val flag = ResourceBooleanFlag(flagId, flagName, flagNamespace, flagResourceId)
|
||||||
whenever(mResources.getBoolean(flagResourceId)).thenReturn(true)
|
whenever(mResources.getBoolean(flagResourceId)).thenReturn(true)
|
||||||
assertThat(mFeatureFlagsRelease.isEnabled(flag)).isTrue()
|
assertThat(featureFlagsRelease.isEnabled(flag)).isTrue()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -70,16 +78,16 @@ class FeatureFlagsReleaseTest : SysuiTestCase() {
|
|||||||
whenever(mResources.getString(1003)).thenReturn(null)
|
whenever(mResources.getString(1003)).thenReturn(null)
|
||||||
whenever(mResources.getString(1004)).thenAnswer { throw NameNotFoundException() }
|
whenever(mResources.getString(1004)).thenAnswer { throw NameNotFoundException() }
|
||||||
|
|
||||||
assertThat(mFeatureFlagsRelease.getString(
|
assertThat(featureFlagsRelease.getString(
|
||||||
ResourceStringFlag(1, "1", "test", 1001))).isEqualTo("")
|
ResourceStringFlag(1, "1", "test", 1001))).isEqualTo("")
|
||||||
assertThat(mFeatureFlagsRelease.getString(
|
assertThat(featureFlagsRelease.getString(
|
||||||
ResourceStringFlag(2, "2", "test", 1002))).isEqualTo("res2")
|
ResourceStringFlag(2, "2", "test", 1002))).isEqualTo("res2")
|
||||||
|
|
||||||
assertThrows(NullPointerException::class.java) {
|
assertThrows(NullPointerException::class.java) {
|
||||||
mFeatureFlagsRelease.getString(ResourceStringFlag(3, "3", "test", 1003))
|
featureFlagsRelease.getString(ResourceStringFlag(3, "3", "test", 1003))
|
||||||
}
|
}
|
||||||
assertThrows(NameNotFoundException::class.java) {
|
assertThrows(NameNotFoundException::class.java) {
|
||||||
mFeatureFlagsRelease.getString(ResourceStringFlag(4, "4", "test", 1004))
|
featureFlagsRelease.getString(ResourceStringFlag(4, "4", "test", 1004))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,7 +100,7 @@ class FeatureFlagsReleaseTest : SysuiTestCase() {
|
|||||||
|
|
||||||
val flag = SysPropBooleanFlag(flagId, flagName, flagNamespace, flagDefault)
|
val flag = SysPropBooleanFlag(flagId, flagName, flagNamespace, flagDefault)
|
||||||
whenever(mSystemProperties.getBoolean(flagName, flagDefault)).thenReturn(flagDefault)
|
whenever(mSystemProperties.getBoolean(flagName, flagDefault)).thenReturn(flagDefault)
|
||||||
assertThat(mFeatureFlagsRelease.isEnabled(flag)).isEqualTo(flagDefault)
|
assertThat(featureFlagsRelease.isEnabled(flag)).isEqualTo(flagDefault)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -101,7 +109,7 @@ class FeatureFlagsReleaseTest : SysuiTestCase() {
|
|||||||
|
|
||||||
serverFlagReader.setFlagValue(flag.namespace, flag.name, false)
|
serverFlagReader.setFlagValue(flag.namespace, flag.name, false)
|
||||||
|
|
||||||
assertThat(mFeatureFlagsRelease.isEnabled(flag)).isFalse()
|
assertThat(featureFlagsRelease.isEnabled(flag)).isFalse()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -110,6 +118,32 @@ class FeatureFlagsReleaseTest : SysuiTestCase() {
|
|||||||
|
|
||||||
serverFlagReader.setFlagValue(flag.namespace, flag.name, true)
|
serverFlagReader.setFlagValue(flag.namespace, flag.name, true)
|
||||||
|
|
||||||
assertThat(mFeatureFlagsRelease.isEnabled(flag)).isFalse()
|
assertThat(featureFlagsRelease.isEnabled(flag)).isFalse()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun serverSide_OverrideUncached_NoRestart() {
|
||||||
|
// No one has read the flag, so it's not in the cache.
|
||||||
|
serverFlagReader.setFlagValue(
|
||||||
|
flagA.namespace, flagA.name, !flagA.default)
|
||||||
|
Mockito.verify(restarter, never()).restartSystemUI(Mockito.anyString())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun serverSide_Override_Restarts() {
|
||||||
|
// Read it to put it in the cache.
|
||||||
|
featureFlagsRelease.isEnabled(flagA)
|
||||||
|
serverFlagReader.setFlagValue(
|
||||||
|
flagA.namespace, flagA.name, !flagA.default)
|
||||||
|
Mockito.verify(restarter).restartSystemUI(Mockito.anyString())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun serverSide_RedundantOverride_NoRestart() {
|
||||||
|
// Read it to put it in the cache.
|
||||||
|
featureFlagsRelease.isEnabled(flagA)
|
||||||
|
serverFlagReader.setFlagValue(
|
||||||
|
flagA.namespace, flagA.name, flagA.default)
|
||||||
|
Mockito.verify(restarter, never()).restartSystemUI(Mockito.anyString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,11 +21,13 @@ import android.testing.AndroidTestingRunner
|
|||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
import com.android.systemui.util.DeviceConfigProxyFake
|
import com.android.systemui.util.DeviceConfigProxyFake
|
||||||
import com.android.systemui.util.concurrency.FakeExecutor
|
import com.android.systemui.util.concurrency.FakeExecutor
|
||||||
|
import com.android.systemui.util.mockito.any
|
||||||
import com.android.systemui.util.time.FakeSystemClock
|
import com.android.systemui.util.time.FakeSystemClock
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
|
import org.mockito.Mockito.anyString
|
||||||
import org.mockito.Mockito.never
|
import org.mockito.Mockito.never
|
||||||
import org.mockito.Mockito.verify
|
import org.mockito.Mockito.verify
|
||||||
import org.mockito.MockitoAnnotations
|
import org.mockito.MockitoAnnotations
|
||||||
@@ -57,18 +59,18 @@ class ServerFlagReaderImplTest : SysuiTestCase() {
|
|||||||
deviceConfig.setProperty(NAMESPACE, "flag_1", "1", false)
|
deviceConfig.setProperty(NAMESPACE, "flag_1", "1", false)
|
||||||
executor.runAllReady()
|
executor.runAllReady()
|
||||||
|
|
||||||
verify(changeListener).onChange(flag)
|
verify(changeListener).onChange(flag, "1")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testChange_ignoresListenersDuringTest() {
|
fun testChange_ignoresListenersDuringTest() {
|
||||||
val serverFlagReader = ServerFlagReaderImpl(NAMESPACE, deviceConfig, executor, true)
|
val serverFlagReader = ServerFlagReaderImpl(NAMESPACE, deviceConfig, executor, true)
|
||||||
val flag = ReleasedFlag(1, "1", "test")
|
val flag = ReleasedFlag(1, "1", " test")
|
||||||
serverFlagReader.listenForChanges(listOf(flag), changeListener)
|
serverFlagReader.listenForChanges(listOf(flag), changeListener)
|
||||||
|
|
||||||
deviceConfig.setProperty(NAMESPACE, "flag_override_1", "1", false)
|
deviceConfig.setProperty(NAMESPACE, "flag_override_1", "1", false)
|
||||||
executor.runAllReady()
|
executor.runAllReady()
|
||||||
|
|
||||||
verify(changeListener, never()).onChange(flag)
|
verify(changeListener, never()).onChange(any(), anyString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user