diff options
Diffstat (limited to 'tests/unit/src/com/android/tv')
45 files changed, 4022 insertions, 426 deletions
diff --git a/tests/unit/src/com/android/tv/BaseMainActivityTestCase.java b/tests/unit/src/com/android/tv/BaseMainActivityTestCase.java index 84283d90..4e280d1a 100644 --- a/tests/unit/src/com/android/tv/BaseMainActivityTestCase.java +++ b/tests/unit/src/com/android/tv/BaseMainActivityTestCase.java @@ -23,7 +23,7 @@ import android.support.test.rule.ActivityTestRule; import android.text.TextUtils; import com.android.tv.data.Channel; import com.android.tv.data.ChannelDataManager; -import com.android.tv.testing.data.ChannelInfo; +import com.android.tv.testing.ChannelInfo; import com.android.tv.testing.testinput.ChannelStateData; import com.android.tv.testing.testinput.TestInputControlConnection; import com.android.tv.testing.testinput.TestInputControlUtils; diff --git a/tests/unit/src/com/android/tv/CurrentPositionMediatorTest.java b/tests/unit/src/com/android/tv/CurrentPositionMediatorTest.java index 1c6a0e3b..6a48e635 100644 --- a/tests/unit/src/com/android/tv/CurrentPositionMediatorTest.java +++ b/tests/unit/src/com/android/tv/CurrentPositionMediatorTest.java @@ -18,17 +18,15 @@ package com.android.tv; import static com.android.tv.TimeShiftManager.INVALID_TIME; import static com.android.tv.TimeShiftManager.REQUEST_TIMEOUT_MS; -import static com.google.common.truth.Truth.assertWithMessage; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotSame; import android.support.test.annotation.UiThreadTest; import android.support.test.filters.MediumTest; -import android.support.test.runner.AndroidJUnit4; import org.junit.Before; import org.junit.Test; -import org.junit.runner.RunWith; @MediumTest -@RunWith(AndroidJUnit4.class) public class CurrentPositionMediatorTest extends BaseMainActivityTestCase { private TimeShiftManager.CurrentPositionMediator mMediator; @@ -52,12 +50,8 @@ public class CurrentPositionMediatorTest extends BaseMainActivityTestCase { public void testOnSeekRequested() { long seekToTimeMs = System.currentTimeMillis() - REQUEST_TIMEOUT_MS * 3; mMediator.onSeekRequested(seekToTimeMs); - assertWithMessage("Seek request time") - .that(mMediator.mSeekRequestTimeMs) - .isNotSameAs(INVALID_TIME); - assertWithMessage("Current position") - .that(mMediator.mCurrentPositionMs) - .isEqualTo(seekToTimeMs); + assertNotSame("Seek request time", INVALID_TIME, mMediator.mSeekRequestTimeMs); + assertEquals("Current position", seekToTimeMs, mMediator.mCurrentPositionMs); } @UiThreadTest @@ -67,15 +61,9 @@ public class CurrentPositionMediatorTest extends BaseMainActivityTestCase { long newCurrentTimeMs = seekToTimeMs + REQUEST_TIMEOUT_MS; mMediator.onSeekRequested(seekToTimeMs); mMediator.onCurrentPositionChanged(newCurrentTimeMs); - assertWithMessage("Seek request time") - .that(mMediator.mSeekRequestTimeMs) - .isNotSameAs(INVALID_TIME); - assertWithMessage("Current position") - .that(mMediator.mCurrentPositionMs) - .isNotSameAs(seekToTimeMs); - assertWithMessage("Current position") - .that(mMediator.mCurrentPositionMs) - .isNotSameAs(newCurrentTimeMs); + assertNotSame("Seek request time", INVALID_TIME, mMediator.mSeekRequestTimeMs); + assertNotSame("Current position", seekToTimeMs, mMediator.mCurrentPositionMs); + assertNotSame("Current position", newCurrentTimeMs, mMediator.mCurrentPositionMs); } @UiThreadTest @@ -90,11 +78,7 @@ public class CurrentPositionMediatorTest extends BaseMainActivityTestCase { private void assertCurrentPositionMediator( long expectedSeekRequestTimeMs, long expectedCurrentPositionMs) { - assertWithMessage("Seek request time") - .that(mMediator.mSeekRequestTimeMs) - .isEqualTo(expectedSeekRequestTimeMs); - assertWithMessage("Current position") - .that(mMediator.mCurrentPositionMs) - .isEqualTo(expectedCurrentPositionMs); + assertEquals("Seek request time", expectedSeekRequestTimeMs, mMediator.mSeekRequestTimeMs); + assertEquals("Current position", expectedCurrentPositionMs, mMediator.mCurrentPositionMs); } } diff --git a/tests/unit/src/com/android/tv/FeaturesTest.java b/tests/unit/src/com/android/tv/FeaturesTest.java index e19f4b7c..b6be6866 100644 --- a/tests/unit/src/com/android/tv/FeaturesTest.java +++ b/tests/unit/src/com/android/tv/FeaturesTest.java @@ -16,21 +16,18 @@ package com.android.tv; -import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertFalse; import android.support.test.filters.SmallTest; -import android.support.test.runner.AndroidJUnit4; import org.junit.Test; -import org.junit.runner.RunWith; /** Test for features. */ @SmallTest -@RunWith(AndroidJUnit4.class) public class FeaturesTest { @Test public void testPropertyFeatureKeyLength() { // This forces the class to be loaded and verifies all PropertyFeature key lengths. // If any keys are too long the test will fail to load. - assertThat(TvFeatures.TEST_FEATURE.isEnabled(null)).isFalse(); + assertFalse(Features.TEST_FEATURE.isEnabled(null)); } } diff --git a/tests/unit/src/com/android/tv/MainActivityTest.java b/tests/unit/src/com/android/tv/MainActivityTest.java index d28a8cd2..00aa79d8 100644 --- a/tests/unit/src/com/android/tv/MainActivityTest.java +++ b/tests/unit/src/com/android/tv/MainActivityTest.java @@ -16,11 +16,10 @@ package com.android.tv; import static android.support.test.InstrumentationRegistry.getInstrumentation; -import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth.assertWithMessage; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import android.support.test.filters.MediumTest; -import android.support.test.runner.AndroidJUnit4; import android.view.View; import android.widget.TextView; import com.android.tv.data.Channel; @@ -28,17 +27,15 @@ import com.android.tv.testing.testinput.TvTestInputConstants; import com.android.tv.ui.ChannelBannerView; import java.util.List; import org.junit.Test; -import org.junit.runner.RunWith; /** Tests for {@link MainActivity}. */ @MediumTest -@RunWith(AndroidJUnit4.class) public class MainActivityTest extends BaseMainActivityTestCase { @Test public void testInitialConditions() { waitUntilChannelLoadingFinish(); List<Channel> channelList = mActivity.getChannelDataManager().getChannelList(); - assertWithMessage("Expected at least one channel").that(channelList.size() > 0).isTrue(); + assertTrue("Expected at least one channel", channelList.size() > 0); } @Test @@ -71,7 +68,7 @@ public class MainActivityTest extends BaseMainActivityTestCase { private void assertChannelName(String displayName) { TextView channelNameView = (TextView) mActivity.findViewById(R.id.channel_name); - assertWithMessage("Channel Name").that(channelNameView.getText()).isEqualTo(displayName); + assertEquals("Channel Name", displayName, channelNameView.getText()); } private void assertProgramGuide(boolean isShown) { @@ -89,7 +86,7 @@ public class MainActivityTest extends BaseMainActivityTestCase { assertViewIsShown( expectedClass.getSimpleName(), R.id.scene_transition_common, expectedShown); if (v != null) { - assertThat(v.getClass()).isEqualTo(expectedClass); + assertEquals(expectedClass, v.getClass()); } return v; } @@ -103,7 +100,7 @@ public class MainActivityTest extends BaseMainActivityTestCase { return null; } } - assertWithMessage(viewName + " shown").that(view.isShown()).isEqualTo(expected); + assertEquals(viewName + " shown", expected, view.isShown()); return view; } } diff --git a/tests/unit/src/com/android/tv/TimeShiftManagerTest.java b/tests/unit/src/com/android/tv/TimeShiftManagerTest.java index e30a9226..7ad6bdbf 100644 --- a/tests/unit/src/com/android/tv/TimeShiftManagerTest.java +++ b/tests/unit/src/com/android/tv/TimeShiftManagerTest.java @@ -22,16 +22,13 @@ import static com.android.tv.TimeShiftManager.TIME_SHIFT_ACTION_ID_JUMP_TO_PREVI import static com.android.tv.TimeShiftManager.TIME_SHIFT_ACTION_ID_PAUSE; import static com.android.tv.TimeShiftManager.TIME_SHIFT_ACTION_ID_PLAY; import static com.android.tv.TimeShiftManager.TIME_SHIFT_ACTION_ID_REWIND; -import static com.google.common.truth.Truth.assertWithMessage; +import static org.junit.Assert.assertEquals; import android.support.test.filters.MediumTest; -import android.support.test.runner.AndroidJUnit4; import org.junit.Before; import org.junit.Test; -import org.junit.runner.RunWith; @MediumTest -@RunWith(AndroidJUnit4.class) public class TimeShiftManagerTest extends BaseMainActivityTestCase { private TimeShiftManager mTimeShiftManager; @@ -94,23 +91,29 @@ public class TimeShiftManagerTest extends BaseMainActivityTestCase { boolean fastForwardEnabled, boolean jumpToPreviousEnabled, boolean jumpToNextEnabled) { - assertWithMessage("Play Action") - .that(mTimeShiftManager.isActionEnabled(TIME_SHIFT_ACTION_ID_PLAY)) - .isEqualTo(playEnabled); - assertWithMessage("Pause Action") - .that(mTimeShiftManager.isActionEnabled(TIME_SHIFT_ACTION_ID_PAUSE)) - .isEqualTo(pauseEnabled); - assertWithMessage("Rewind Action") - .that(mTimeShiftManager.isActionEnabled(TIME_SHIFT_ACTION_ID_REWIND)) - .isEqualTo(rewindEnabled); - assertWithMessage("Fast Forward Action") - .that(mTimeShiftManager.isActionEnabled(TIME_SHIFT_ACTION_ID_FAST_FORWARD)) - .isEqualTo(fastForwardEnabled); - assertWithMessage("Jump To Previous Action") - .that(mTimeShiftManager.isActionEnabled(TIME_SHIFT_ACTION_ID_JUMP_TO_PREVIOUS)) - .isEqualTo(jumpToPreviousEnabled); - assertWithMessage("Jump To Next Action") - .that(mTimeShiftManager.isActionEnabled(TIME_SHIFT_ACTION_ID_JUMP_TO_NEXT)) - .isEqualTo(jumpToNextEnabled); + assertEquals( + "Play Action", + playEnabled, + mTimeShiftManager.isActionEnabled(TIME_SHIFT_ACTION_ID_PLAY)); + assertEquals( + "Pause Action", + pauseEnabled, + mTimeShiftManager.isActionEnabled(TIME_SHIFT_ACTION_ID_PAUSE)); + assertEquals( + "Rewind Action", + rewindEnabled, + mTimeShiftManager.isActionEnabled(TIME_SHIFT_ACTION_ID_REWIND)); + assertEquals( + "Fast Forward Action", + fastForwardEnabled, + mTimeShiftManager.isActionEnabled(TIME_SHIFT_ACTION_ID_FAST_FORWARD)); + assertEquals( + "Jump To Previous Action", + jumpToPreviousEnabled, + mTimeShiftManager.isActionEnabled(TIME_SHIFT_ACTION_ID_JUMP_TO_PREVIOUS)); + assertEquals( + "Jump To Next Action", + jumpToNextEnabled, + mTimeShiftManager.isActionEnabled(TIME_SHIFT_ACTION_ID_JUMP_TO_NEXT)); } } diff --git a/tests/unit/src/com/android/tv/data/ChannelDataManagerTest.java b/tests/unit/src/com/android/tv/data/ChannelDataManagerTest.java index 9b81f5d5..0adfd1be 100644 --- a/tests/unit/src/com/android/tv/data/ChannelDataManagerTest.java +++ b/tests/unit/src/com/android/tv/data/ChannelDataManagerTest.java @@ -18,8 +18,9 @@ package com.android.tv.data; import static android.support.test.InstrumentationRegistry.getInstrumentation; import static android.support.test.InstrumentationRegistry.getTargetContext; -import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth.assertWithMessage; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import android.content.ContentProvider; import android.content.ContentUris; @@ -31,7 +32,6 @@ import android.media.tv.TvContract; import android.media.tv.TvContract.Channels; import android.net.Uri; import android.support.test.filters.SmallTest; -import android.support.test.runner.AndroidJUnit4; import android.test.MoreAsserts; import android.test.mock.MockContentProvider; import android.test.mock.MockContentResolver; @@ -39,8 +39,8 @@ import android.test.mock.MockCursor; import android.text.TextUtils; import android.util.Log; import android.util.SparseArray; -import com.android.tv.testing.constants.Constants; -import com.android.tv.testing.data.ChannelInfo; +import com.android.tv.testing.ChannelInfo; +import com.android.tv.testing.Constants; import com.android.tv.util.TvInputManagerHelper; import java.util.ArrayList; import java.util.Arrays; @@ -50,7 +50,6 @@ import java.util.concurrent.TimeUnit; import org.junit.After; import org.junit.Before; import org.junit.Test; -import org.junit.runner.RunWith; import org.mockito.Matchers; import org.mockito.Mockito; @@ -61,7 +60,6 @@ import org.mockito.Mockito; * the methods of {@link ChannelDataManager} should be called from the UI thread. */ @SmallTest -@RunWith(AndroidJUnit4.class) public class ChannelDataManagerTest { private static final boolean DEBUG = false; private static final String TAG = "ChannelDataManagerTest"; @@ -79,9 +77,7 @@ public class ChannelDataManagerTest { @Before public void setUp() { - assertWithMessage("More than 2 channels to test") - .that(Constants.UNIT_TEST_CHANNEL_COUNT > 2) - .isTrue(); + assertTrue("More than 2 channels to test", Constants.UNIT_TEST_CHANNEL_COUNT > 2); mContentProvider = new FakeContentProvider(getTargetContext()); mContentResolver = new FakeContentResolver(); @@ -125,8 +121,7 @@ public class ChannelDataManagerTest { mChannelDataManager.start(); } }); - assertThat(mListener.loadFinishedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS)) - .isTrue(); + assertTrue(mListener.loadFinishedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS)); } private void restart() throws InterruptedException { @@ -145,7 +140,7 @@ public class ChannelDataManagerTest { @Test public void testIsDbLoadFinished() throws InterruptedException { startAndWaitForComplete(); - assertThat(mChannelDataManager.isDbLoadFinished()).isTrue(); + assertTrue(mChannelDataManager.isDbLoadFinished()); } /** @@ -157,8 +152,7 @@ public class ChannelDataManagerTest { startAndWaitForComplete(); // Test {@link ChannelDataManager#getChannelCount} - assertThat(mChannelDataManager.getChannelCount()) - .isEqualTo(Constants.UNIT_TEST_CHANNEL_COUNT); + assertEquals(Constants.UNIT_TEST_CHANNEL_COUNT, mChannelDataManager.getChannelCount()); // Test {@link ChannelDataManager#getChannelList} List<ChannelInfo> channelInfoList = new ArrayList<>(); @@ -169,18 +163,19 @@ public class ChannelDataManagerTest { for (Channel channel : channelList) { boolean found = false; for (ChannelInfo channelInfo : channelInfoList) { - if (TextUtils.equals(channelInfo.name, channel.getDisplayName())) { + if (TextUtils.equals(channelInfo.name, channel.getDisplayName()) + && TextUtils.equals(channelInfo.name, channel.getDisplayName())) { found = true; channelInfoList.remove(channelInfo); break; } } - assertWithMessage("Cannot find (" + channel + ")").that(found).isTrue(); + assertTrue("Cannot find (" + channel + ")", found); } // Test {@link ChannelDataManager#getChannelIndex()} for (Channel channel : channelList) { - assertThat(mChannelDataManager.getChannel(channel.getId())).isEqualTo(channel); + assertEquals(channel, mChannelDataManager.getChannel(channel.getId())); } } @@ -189,7 +184,7 @@ public class ChannelDataManagerTest { public void testGetChannels_noChannels() throws InterruptedException { mContentProvider.clear(); startAndWaitForComplete(); - assertThat(mChannelDataManager.getChannelCount()).isEqualTo(0); + assertEquals(0, mChannelDataManager.getChannelCount()); } /** @@ -205,9 +200,9 @@ public class ChannelDataManagerTest { List<Channel> browsableChannelList = mChannelDataManager.getBrowsableChannelList(); for (Channel browsableChannel : browsableChannelList) { boolean found = channelList.remove(browsableChannel); - assertWithMessage("Cannot find (" + browsableChannel + ")").that(found).isTrue(); + assertTrue("Cannot find (" + browsableChannel + ")", found); } - assertThat(channelList).isEmpty(); + assertEquals(0, channelList.size()); // Prepare for next tests. channelList = mChannelDataManager.getChannelList(); @@ -218,8 +213,8 @@ public class ChannelDataManagerTest { // Test {@link ChannelDataManager#updateBrowsable} & notification. mChannelDataManager.updateBrowsable(channel1.getId(), false, false); - assertThat(mListener.channelBrowsableChangedCalled).isTrue(); - assertThat(mChannelDataManager.getBrowsableChannelList()).doesNotContain(channel1); + assertTrue(mListener.channelBrowsableChangedCalled); + assertFalse(mChannelDataManager.getBrowsableChannelList().contains(channel1)); MoreAsserts.assertContentsInAnyOrder(channelListener.updatedChannels, channel1); channelListener.reset(); @@ -229,8 +224,8 @@ public class ChannelDataManagerTest { mChannelDataManager.applyUpdatedValuesToDb(); restart(); browsableChannelList = mChannelDataManager.getBrowsableChannelList(); - assertThat(browsableChannelList).hasSize(Constants.UNIT_TEST_CHANNEL_COUNT - 1); - assertThat(browsableChannelList).doesNotContain(channel1); + assertEquals(Constants.UNIT_TEST_CHANNEL_COUNT - 1, browsableChannelList.size()); + assertFalse(browsableChannelList.contains(channel1)); } /** @@ -254,10 +249,10 @@ public class ChannelDataManagerTest { mChannelDataManager.updateBrowsable(channel1.getId(), false, true); mChannelDataManager.updateBrowsable(channel2.getId(), false, true); mChannelDataManager.updateBrowsable(channel1.getId(), true, true); - assertThat(mListener.channelBrowsableChangedCalled).isFalse(); + assertFalse(mListener.channelBrowsableChangedCalled); List<Channel> browsableChannelList = mChannelDataManager.getBrowsableChannelList(); - assertThat(browsableChannelList).contains(channel1); - assertThat(browsableChannelList).doesNotContain(channel2); + assertTrue(browsableChannelList.contains(channel1)); + assertFalse(browsableChannelList.contains(channel2)); // Test {@link ChannelDataManager#applyUpdatedValuesToDb} // Disable the update notification to avoid the unwanted call of "onLoadFinished". @@ -265,8 +260,8 @@ public class ChannelDataManagerTest { mChannelDataManager.applyUpdatedValuesToDb(); restart(); browsableChannelList = mChannelDataManager.getBrowsableChannelList(); - assertThat(browsableChannelList).hasSize(Constants.UNIT_TEST_CHANNEL_COUNT - 1); - assertThat(browsableChannelList).doesNotContain(channel2); + assertEquals(Constants.UNIT_TEST_CHANNEL_COUNT - 1, browsableChannelList.size()); + assertFalse(browsableChannelList.contains(channel2)); } /** @@ -280,7 +275,7 @@ public class ChannelDataManagerTest { // Test if all channels aren't locked at the first time. List<Channel> channelList = mChannelDataManager.getChannelList(); for (Channel channel : channelList) { - assertWithMessage(channel + " is locked").that(channel.isLocked()).isFalse(); + assertFalse(channel + " is locked", channel.isLocked()); } // Prepare for next tests. @@ -288,14 +283,14 @@ public class ChannelDataManagerTest { // Test {@link ChannelDataManager#updateLocked} mChannelDataManager.updateLocked(channel.getId(), true); - assertThat(mChannelDataManager.getChannel(channel.getId()).isLocked()).isTrue(); + assertTrue(mChannelDataManager.getChannel(channel.getId()).isLocked()); // Test {@link ChannelDataManager#applyUpdatedValuesToDb}. // Disable the update notification to avoid the unwanted call of "onLoadFinished". mContentResolver.mNotifyDisabled = true; mChannelDataManager.applyUpdatedValuesToDb(); restart(); - assertThat(mChannelDataManager.getChannel(channel.getId()).isLocked()).isTrue(); + assertTrue(mChannelDataManager.getChannel(channel.getId()).isLocked()); // Cleanup mChannelDataManager.updateLocked(channel.getId(), false); @@ -312,10 +307,9 @@ public class ChannelDataManagerTest { ChannelInfo testChannelInfo = ChannelInfo.create(getTargetContext(), (int) testChannelId); testChannelId = Constants.UNIT_TEST_CHANNEL_COUNT + 1; mContentProvider.simulateInsert(testChannelInfo); - assertThat(mListener.channelListUpdatedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS)) - .isTrue(); - assertThat(mChannelDataManager.getChannelCount()) - .isEqualTo(Constants.UNIT_TEST_CHANNEL_COUNT + 1); + assertTrue( + mListener.channelListUpdatedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS)); + assertEquals(Constants.UNIT_TEST_CHANNEL_COUNT + 1, mChannelDataManager.getChannelCount()); // Test channel update mListener.reset(); @@ -324,41 +318,35 @@ public class ChannelDataManagerTest { mChannelDataManager.addChannelListener(testChannelId, channelListener); String newName = testChannelInfo.name + "_test"; mContentProvider.simulateUpdate(testChannelId, newName); - assertThat(mListener.channelListUpdatedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS)) - .isTrue(); - assertThat( - channelListener.channelChangedLatch.await( - WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS)) - .isTrue(); - assertThat(channelListener.removedChannels).isEmpty(); - assertThat(channelListener.updatedChannels).hasSize(1); + assertTrue( + mListener.channelListUpdatedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS)); + assertTrue( + channelListener.channelChangedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS)); + assertEquals(0, channelListener.removedChannels.size()); + assertEquals(1, channelListener.updatedChannels.size()); Channel updatedChannel = channelListener.updatedChannels.get(0); - assertThat(updatedChannel.getId()).isEqualTo(testChannelId); - assertThat(updatedChannel.getDisplayNumber()).isEqualTo(testChannelInfo.number); - assertThat(updatedChannel.getDisplayName()).isEqualTo(newName); - assertThat(mChannelDataManager.getChannelCount()) - .isEqualTo(Constants.UNIT_TEST_CHANNEL_COUNT + 1); + assertEquals(testChannelId, updatedChannel.getId()); + assertEquals(testChannelInfo.number, updatedChannel.getDisplayNumber()); + assertEquals(newName, updatedChannel.getDisplayName()); + assertEquals(Constants.UNIT_TEST_CHANNEL_COUNT + 1, mChannelDataManager.getChannelCount()); // Test channel remove. mListener.reset(); channelListener.reset(); mContentProvider.simulateDelete(testChannelId); - assertThat(mListener.channelListUpdatedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS)) - .isTrue(); - assertThat( - channelListener.channelChangedLatch.await( - WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS)) - .isTrue(); - assertThat(channelListener.removedChannels).hasSize(1); - assertThat(channelListener.updatedChannels).isEmpty(); + assertTrue( + mListener.channelListUpdatedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS)); + assertTrue( + channelListener.channelChangedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS)); + assertEquals(1, channelListener.removedChannels.size()); + assertEquals(0, channelListener.updatedChannels.size()); Channel removedChannel = channelListener.removedChannels.get(0); - assertThat(removedChannel.getDisplayName()).isEqualTo(newName); - assertThat(removedChannel.getDisplayNumber()).isEqualTo(testChannelInfo.number); - assertThat(mChannelDataManager.getChannelCount()) - .isEqualTo(Constants.UNIT_TEST_CHANNEL_COUNT); + assertEquals(newName, removedChannel.getDisplayName()); + assertEquals(testChannelInfo.number, removedChannel.getDisplayNumber()); + assertEquals(Constants.UNIT_TEST_CHANNEL_COUNT, mChannelDataManager.getChannelCount()); } - private static class ChannelInfoWrapper { + private class ChannelInfoWrapper { public ChannelInfo channelInfo; public boolean browsable; public boolean locked; @@ -525,9 +513,9 @@ public class ChannelDataManagerTest { } private void assertChannelUri(Uri uri) { - assertWithMessage("Uri(" + uri + ") isn't channel uri") - .that(uri.toString().startsWith(Channels.CONTENT_URI.toString())) - .isTrue(); + assertTrue( + "Uri(" + uri + ") isn't channel uri", + uri.toString().startsWith(Channels.CONTENT_URI.toString())); } public void clear() { @@ -548,7 +536,7 @@ public class ChannelDataManagerTest { } private class FakeCursor extends MockCursor { - private final String[] allColumns = { + private final String[] ALL_COLUMNS = { Channels._ID, Channels.COLUMN_DISPLAY_NAME, Channels.COLUMN_DISPLAY_NUMBER, @@ -562,7 +550,7 @@ public class ChannelDataManagerTest { private int mPosition; public FakeCursor(String[] columns) { - mColumns = (columns == null) ? allColumns : columns; + mColumns = (columns == null) ? ALL_COLUMNS : columns; mPosition = -1; } @@ -587,7 +575,6 @@ public class ChannelDataManagerTest { switch (columnName) { case Channels._ID: return mContentProvider.keyAt(mPosition); - default: // fall out } if (DEBUG) { Log.d(TAG, "Column (" + columnName + ") is ignored in getLong()"); @@ -608,7 +595,6 @@ public class ChannelDataManagerTest { return DUMMY_INPUT_ID; case Channels.COLUMN_VIDEO_FORMAT: return channel.channelInfo.getVideoFormat(); - default: // fall out } if (DEBUG) { Log.d(TAG, "Column (" + columnName + ") is ignored in getString()"); @@ -627,7 +613,6 @@ public class ChannelDataManagerTest { return channel.browsable ? 1 : 0; case COLUMN_LOCKED: return channel.locked ? 1 : 0; - default: // fall out } if (DEBUG) { Log.d(TAG, "Column (" + columnName + ") is ignored in getInt()"); @@ -651,7 +636,7 @@ public class ChannelDataManagerTest { } } - private static class TestChannelDataManagerListener implements ChannelDataManager.Listener { + private class TestChannelDataManagerListener implements ChannelDataManager.Listener { public CountDownLatch loadFinishedLatch = new CountDownLatch(1); public CountDownLatch channelListUpdatedLatch = new CountDownLatch(1); public boolean channelBrowsableChangedCalled; @@ -678,7 +663,7 @@ public class ChannelDataManagerTest { } } - private static class TestChannelDataManagerChannelListener + private class TestChannelDataManagerChannelListener implements ChannelDataManager.ChannelListener { public CountDownLatch channelChangedLatch = new CountDownLatch(1); public final List<Channel> removedChannels = new ArrayList<>(); diff --git a/tests/unit/src/com/android/tv/data/ChannelNumberTest.java b/tests/unit/src/com/android/tv/data/ChannelNumberTest.java new file mode 100644 index 00000000..86d27efa --- /dev/null +++ b/tests/unit/src/com/android/tv/data/ChannelNumberTest.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2015 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.tv.data; + +import static com.android.tv.data.ChannelNumber.parseChannelNumber; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import android.support.test.filters.SmallTest; +import com.android.tv.testing.ComparableTester; +import org.junit.Test; + +/** Tests for {@link ChannelNumber}. */ +@SmallTest +public class ChannelNumberTest { + /** Test method for {@link ChannelNumber#ChannelNumber()}. */ + @Test + public void testChannelNumber() { + assertChannelEquals(new ChannelNumber(), "", false, ""); + } + + /** + * Test method for {@link + * com.android.tv.data.ChannelNumber#parseChannelNumber(java.lang.String)}. + */ + @Test + public void testParseChannelNumber() { + assertNull(parseChannelNumber("")); + assertNull(parseChannelNumber("-")); + assertNull(parseChannelNumber("abcd12")); + assertNull(parseChannelNumber("12abcd")); + assertNull(parseChannelNumber("-12")); + assertChannelEquals(parseChannelNumber("1"), "1", false, ""); + assertChannelEquals(parseChannelNumber("1234-4321"), "1234", true, "4321"); + assertChannelEquals(parseChannelNumber("3-4"), "3", true, "4"); + assertChannelEquals(parseChannelNumber("5-6"), "5", true, "6"); + } + + /** Test method for {@link ChannelNumber#compareTo(com.android.tv.data.ChannelNumber)}. */ + @Test + public void testCompareTo() { + new ComparableTester<ChannelNumber>() + .addEquivalentGroup(parseChannelNumber("1"), parseChannelNumber("1")) + .addEquivalentGroup(parseChannelNumber("2")) + .addEquivalentGroup(parseChannelNumber("2-1")) + .addEquivalentGroup(parseChannelNumber("2-2")) + .addEquivalentGroup(parseChannelNumber("2-10")) + .addEquivalentGroup(parseChannelNumber("3")) + .addEquivalentGroup(parseChannelNumber("4"), parseChannelNumber("4-0")) + .addEquivalentGroup(parseChannelNumber("10")) + .addEquivalentGroup(parseChannelNumber("100")) + .test(); + } + + /** Test method for {@link ChannelNumber#compare(java.lang.String, java.lang.String)}. */ + @Test + public void testCompare() { + // Only need to test nulls, the reset is tested by testCompareTo + assertEquals("compareTo(null,null)", 0, ChannelNumber.compare(null, null)); + assertEquals("compareTo(1,1)", 0, ChannelNumber.compare("1", "1")); + assertEquals("compareTo(null,1)<0", true, ChannelNumber.compare(null, "1") < 0); + assertEquals("compareTo(mal-formatted,1)<0", true, ChannelNumber.compare("abcd", "1") < 0); + assertEquals("compareTo(mal-formatted,1)<0", true, ChannelNumber.compare(".4", "1") < 0); + assertEquals("compareTo(1,null)>0", true, ChannelNumber.compare("1", null) > 0); + } + + private void assertChannelEquals( + ChannelNumber actual, + String expectedMajor, + boolean expectedHasDelimiter, + String expectedMinor) { + assertEquals(actual + " major", actual.majorNumber, expectedMajor); + assertEquals(actual + " hasDelimiter", actual.hasDelimiter, expectedHasDelimiter); + assertEquals(actual + " minor", actual.minorNumber, expectedMinor); + } +} diff --git a/tests/unit/src/com/android/tv/data/ChannelTest.java b/tests/unit/src/com/android/tv/data/ChannelTest.java index 1f30a819..a7bac9fb 100644 --- a/tests/unit/src/com/android/tv/data/ChannelTest.java +++ b/tests/unit/src/com/android/tv/data/ChannelTest.java @@ -16,8 +16,7 @@ package com.android.tv.data; -import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth.assertWithMessage; +import static org.junit.Assert.assertEquals; import android.content.ComponentName; import android.content.Context; @@ -26,13 +25,11 @@ import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.support.test.filters.SmallTest; -import android.support.test.runner.AndroidJUnit4; import com.android.tv.testing.ComparatorTester; import com.android.tv.util.TvInputManagerHelper; import java.util.Comparator; import org.junit.Before; import org.junit.Test; -import org.junit.runner.RunWith; import org.mockito.Matchers; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; @@ -40,20 +37,17 @@ import org.mockito.stubbing.Answer; /** Tests for {@link Channel}. */ @SmallTest -@RunWith(AndroidJUnit4.class) public class ChannelTest { // Used for testing TV inputs with invalid input package. This could happen when a TV input is // uninstalled while drawing an app link card. - private static final String INVALID_TV_INPUT_PACKAGE_NAME = - "com.android.tv.invalid_tv_input"; + private static final String INVALID_TV_INPUT_PACKAGE_NAME = "com.android.tv.invalid_tv_input"; // Used for testing TV inputs defined inside of Live TV. private static final String LIVE_CHANNELS_PACKAGE_NAME = "com.android.tv"; // Used for testing a TV input which doesn't have its leanback launcher activity. private static final String NONE_LEANBACK_TV_INPUT_PACKAGE_NAME = "com.android.tv.none_leanback_tv_input"; // Used for testing a TV input which has its leanback launcher activity. - private static final String LEANBACK_TV_INPUT_PACKAGE_NAME = - "com.android.tv.leanback_tv_input"; + private static final String LEANBACK_TV_INPUT_PACKAGE_NAME = "com.android.tv.leanback_tv_input"; private static final String TEST_APP_LINK_TEXT = "test_app_link_text"; private static final String PARTNER_INPUT_ID = "partner"; private static final ActivityInfo TEST_ACTIVITY_INFO = new ActivityInfo(); @@ -133,7 +127,6 @@ public class ChannelTest { assertAppLinkType(Channel.APP_LINK_TYPE_APP, LEANBACK_TV_INPUT_PACKAGE_NAME, null, null); } - @Test public void testGetAppLinkType_NoText_InvalidIntent() { assertAppLinkType( Channel.APP_LINK_TYPE_NONE, INVALID_TV_INPUT_PACKAGE_NAME, null, mInvalidIntent); @@ -148,7 +141,6 @@ public class ChannelTest { Channel.APP_LINK_TYPE_APP, LEANBACK_TV_INPUT_PACKAGE_NAME, null, mInvalidIntent); } - @Test public void testGetAppLinkType_NoText_ValidIntent() { assertAppLinkType( Channel.APP_LINK_TYPE_NONE, INVALID_TV_INPUT_PACKAGE_NAME, null, mValidIntent); @@ -163,7 +155,6 @@ public class ChannelTest { Channel.APP_LINK_TYPE_APP, LEANBACK_TV_INPUT_PACKAGE_NAME, null, mValidIntent); } - @Test public void testGetAppLinkType_HasText_NoIntent() { assertAppLinkType( Channel.APP_LINK_TYPE_NONE, @@ -184,7 +175,6 @@ public class ChannelTest { null); } - @Test public void testGetAppLinkType_HasText_InvalidIntent() { assertAppLinkType( Channel.APP_LINK_TYPE_NONE, @@ -208,7 +198,6 @@ public class ChannelTest { mInvalidIntent); } - @Test public void testGetAppLinkType_HasText_ValidIntent() { assertAppLinkType( Channel.APP_LINK_TYPE_CHANNEL, @@ -245,13 +234,14 @@ public class ChannelTest { ? null : appLinkIntent.toUri(Intent.URI_INTENT_SCHEME)) .build(); - assertWithMessage("Unexpected app-link type for for " + testChannel) - .that(testChannel.getAppLinkType(mMockContext)) - .isEqualTo(expectedType); + assertEquals( + "Unexpected app-link type for for " + testChannel, + expectedType, + testChannel.getAppLinkType(mMockContext)); } - @Test public void testComparator() { + TvInputManagerHelper manager = Mockito.mock(TvInputManagerHelper.class); Mockito.when(manager.isPartnerInput(Matchers.anyString())) .thenAnswer( @@ -303,7 +293,6 @@ public class ChannelTest { * <p>Sort partner inputs first, then sort by input label, then by input id. See <a * href="http://b/23031603">b/23031603</a>. */ - @Test public void testComparatorLabel() { TvInputManagerHelper manager = Mockito.mock(TvInputManagerHelper.class); Mockito.when(manager.isPartnerInput(Matchers.anyString())) @@ -332,7 +321,6 @@ public class ChannelTest { comparatorTester.test(); } - @Test public void testNormalizeChannelNumber() { assertNormalizedDisplayNumber(null, null); assertNormalizedDisplayNumber("", ""); @@ -353,10 +341,10 @@ public class ChannelTest { } private void assertNormalizedDisplayNumber(String displayNumber, String normalized) { - assertThat(Channel.normalizeDisplayNumber(displayNumber)).isEqualTo(normalized); + assertEquals(normalized, Channel.normalizeDisplayNumber(displayNumber)); } - private static final class TestChannelComparator extends Channel.DefaultComparator { + private class TestChannelComparator extends Channel.DefaultComparator { public TestChannelComparator(TvInputManagerHelper manager) { super(null, manager); } @@ -367,8 +355,7 @@ public class ChannelTest { } } - private static final class ChannelComparatorWithDescriptionAsLabel - extends Channel.DefaultComparator { + private static class ChannelComparatorWithDescriptionAsLabel extends Channel.DefaultComparator { public ChannelComparatorWithDescriptionAsLabel(TvInputManagerHelper manager) { super(null, manager); } diff --git a/tests/unit/src/com/android/tv/data/GenreItemTest.java b/tests/unit/src/com/android/tv/data/GenreItemTest.java index 02bf4b30..dbf99eac 100644 --- a/tests/unit/src/com/android/tv/data/GenreItemTest.java +++ b/tests/unit/src/com/android/tv/data/GenreItemTest.java @@ -17,18 +17,18 @@ package com.android.tv.data; import static android.support.test.InstrumentationRegistry.getTargetContext; -import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import android.media.tv.TvContract.Programs.Genres; import android.os.Build; import android.support.test.filters.SmallTest; -import android.support.test.runner.AndroidJUnit4; import org.junit.Test; -import org.junit.runner.RunWith; /** Tests for {@link Channel}. */ @SmallTest -@RunWith(AndroidJUnit4.class) public class GenreItemTest { private static final String INVALID_GENRE = "INVALID GENRE"; @@ -41,17 +41,17 @@ public class GenreItemTest { @Test public void testGetCanonicalGenre() { int count = GenreItems.getGenreCount(); - assertThat(GenreItems.getCanonicalGenre(GenreItems.ID_ALL_CHANNELS)).isNull(); + assertNull(GenreItems.getCanonicalGenre(GenreItems.ID_ALL_CHANNELS)); for (int i = 1; i < count; ++i) { - assertThat(GenreItems.getCanonicalGenre(i)).isNotNull(); + assertNotNull(GenreItems.getCanonicalGenre(i)); } } @Test public void testGetId_base() { int count = GenreItems.getGenreCount(); - assertThat(GenreItems.getId(null)).isEqualTo(GenreItems.ID_ALL_CHANNELS); - assertThat(GenreItems.getId(INVALID_GENRE)).isEqualTo(GenreItems.ID_ALL_CHANNELS); + assertEquals(GenreItems.ID_ALL_CHANNELS, GenreItems.getId(null)); + assertEquals(GenreItems.ID_ALL_CHANNELS, GenreItems.getId(INVALID_GENRE)); assertInRange(GenreItems.getId(Genres.FAMILY_KIDS), 1, count - 1); assertInRange(GenreItems.getId(Genres.SPORTS), 1, count - 1); assertInRange(GenreItems.getId(Genres.SHOPPING), 1, count - 1); @@ -68,13 +68,12 @@ public class GenreItemTest { @Test public void testGetId_lmp_mr1() { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) { - assertThat(GenreItems.getId(Genres.ARTS)).isEqualTo(GenreItems.ID_ALL_CHANNELS); - assertThat(GenreItems.getId(Genres.ENTERTAINMENT)) - .isEqualTo(GenreItems.ID_ALL_CHANNELS); - assertThat(GenreItems.getId(Genres.LIFE_STYLE)).isEqualTo(GenreItems.ID_ALL_CHANNELS); - assertThat(GenreItems.getId(Genres.MUSIC)).isEqualTo(GenreItems.ID_ALL_CHANNELS); - assertThat(GenreItems.getId(Genres.PREMIER)).isEqualTo(GenreItems.ID_ALL_CHANNELS); - assertThat(GenreItems.getId(Genres.TECH_SCIENCE)).isEqualTo(GenreItems.ID_ALL_CHANNELS); + assertEquals(GenreItems.ID_ALL_CHANNELS, GenreItems.getId(Genres.ARTS)); + assertEquals(GenreItems.ID_ALL_CHANNELS, GenreItems.getId(Genres.ENTERTAINMENT)); + assertEquals(GenreItems.ID_ALL_CHANNELS, GenreItems.getId(Genres.LIFE_STYLE)); + assertEquals(GenreItems.ID_ALL_CHANNELS, GenreItems.getId(Genres.MUSIC)); + assertEquals(GenreItems.ID_ALL_CHANNELS, GenreItems.getId(Genres.PREMIER)); + assertEquals(GenreItems.ID_ALL_CHANNELS, GenreItems.getId(Genres.TECH_SCIENCE)); } else { int count = GenreItems.getGenreCount(); assertInRange(GenreItems.getId(Genres.ARTS), 1, count - 1); @@ -87,6 +86,6 @@ public class GenreItemTest { } private void assertInRange(int value, int lower, int upper) { - assertThat(value >= lower && value <= upper).isTrue(); + assertTrue(value >= lower && value <= upper); } } diff --git a/tests/unit/src/com/android/tv/data/ProgramDataManagerTest.java b/tests/unit/src/com/android/tv/data/ProgramDataManagerTest.java index c1d670fe..2b75ee4b 100644 --- a/tests/unit/src/com/android/tv/data/ProgramDataManagerTest.java +++ b/tests/unit/src/com/android/tv/data/ProgramDataManagerTest.java @@ -17,8 +17,10 @@ package com.android.tv.data; import static android.support.test.InstrumentationRegistry.getTargetContext; -import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth.assertWithMessage; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import android.content.Context; import android.database.ContentObserver; @@ -28,15 +30,14 @@ import android.net.Uri; import android.os.HandlerThread; import android.support.test.InstrumentationRegistry; import android.support.test.filters.SmallTest; -import android.support.test.runner.AndroidJUnit4; import android.test.mock.MockContentProvider; import android.test.mock.MockContentResolver; import android.test.mock.MockCursor; import android.util.Log; import android.util.SparseArray; +import com.android.tv.testing.Constants; import com.android.tv.testing.FakeClock; -import com.android.tv.testing.constants.Constants; -import com.android.tv.testing.data.ProgramInfo; +import com.android.tv.testing.ProgramInfo; import com.android.tv.util.Utils; import java.util.ArrayList; import java.util.Arrays; @@ -45,14 +46,10 @@ import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import org.junit.After; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; -import org.junit.runner.RunWith; /** Test for {@link com.android.tv.data.ProgramDataManager} */ @SmallTest -@RunWith(AndroidJUnit4.class) -@Ignore("b/69836704") public class ProgramDataManagerTest { private static final boolean DEBUG = false; private static final String TAG = "ProgramDataManagerTest"; @@ -97,8 +94,7 @@ public class ProgramDataManagerTest { private void startAndWaitForComplete() throws InterruptedException { mProgramDataManager.start(); - assertThat(mListener.programUpdatedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS)) - .isTrue(); + assertTrue(mListener.programUpdatedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS)); } /** Test for {@link ProgramInfo#getIndex} and {@link ProgramInfo#getStartTimeMs}. */ @@ -109,8 +105,8 @@ public class ProgramDataManagerTest { int index = stub.getIndex(mClock.currentTimeMillis(), channelId); long startTimeMs = stub.getStartTimeMs(index, channelId); ProgramInfo programAt = stub.build(InstrumentationRegistry.getContext(), index); - assertThat(startTimeMs).isAtMost(mClock.currentTimeMillis()); - assertThat(mClock.currentTimeMillis()).isLessThan(startTimeMs + programAt.durationMs); + assertTrue(startTimeMs <= mClock.currentTimeMillis()); + assertTrue(mClock.currentTimeMillis() < startTimeMs + programAt.durationMs); } } @@ -134,11 +130,9 @@ public class ProgramDataManagerTest { for (long channelId = 1; channelId <= Constants.UNIT_TEST_CHANNEL_COUNT; channelId++) { Program currentProgram = mProgramDataManager.getCurrentProgram(channelId); // Test {@link ProgramDataManager#getCurrentProgram(long)}. - assertThat( - currentProgram.getStartTimeUtcMillis() <= mClock.currentTimeMillis() - && mClock.currentTimeMillis() - <= currentProgram.getEndTimeUtcMillis()) - .isTrue(); + assertTrue( + currentProgram.getStartTimeUtcMillis() <= mClock.currentTimeMillis() + && mClock.currentTimeMillis() <= currentProgram.getEndTimeUtcMillis()); // Test {@link ProgramDataManager#getPrograms(long)}. // Case #1: Normal case @@ -155,14 +149,14 @@ public class ProgramDataManagerTest { // Case #2: Corner cases where there's a program that starts at the start of the range. long startTimeMs = programs.get(0).getStartTimeUtcMillis(); programs = mProgramDataManager.getPrograms(channelId, startTimeMs); - assertThat(programs.get(0).getStartTimeUtcMillis()).isEqualTo(startTimeMs); + assertEquals(startTimeMs, programs.get(0).getStartTimeUtcMillis()); // Test {@link ProgramDataManager#setPrefetchTimeRange(long)}. programs = mProgramDataManager.getPrograms( channelId, prefetchTimeRangeStartMs - TimeUnit.HOURS.toMillis(1)); for (Program program : programs) { - assertThat(program.getEndTimeUtcMillis()).isAtLeast(prefetchTimeRangeStartMs); + assertTrue(program.getEndTimeUtcMillis() >= prefetchTimeRangeStartMs); } } } @@ -192,14 +186,12 @@ public class ProgramDataManagerTest { TestProgramDataManagerOnCurrentProgramUpdatedListener listener = new TestProgramDataManagerOnCurrentProgramUpdatedListener(); mProgramDataManager.addOnCurrentProgramUpdatedListener(testChannelId, listener); - assertThat( - listener.currentProgramUpdatedLatch.await( - WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS)) - .isTrue(); - assertThat(listener.updatedChannelId).isEqualTo(testChannelId); + assertTrue( + listener.currentProgramUpdatedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS)); + assertEquals(testChannelId, listener.updatedChannelId); Program currentProgram = mProgramDataManager.getCurrentProgram(testChannelId); assertProgramEquals(nextProgramStartTimeMs, nextProgramInfo, currentProgram); - assertThat(currentProgram).isEqualTo(listener.updatedProgram); + assertEquals(listener.updatedProgram, currentProgram); } /** Test if program data is refreshed after the program insertion. */ @@ -212,15 +204,14 @@ public class ProgramDataManagerTest { mListener.reset(); List<Program> programList = mProgramDataManager.getPrograms(testChannelId, mClock.currentTimeMillis()); - assertThat(programList).isNotNull(); + assertNotNull(programList); long lastProgramEndTime = programList.get(programList.size() - 1).getEndTimeUtcMillis(); // Make change in content provider mContentProvider.simulateAppend(testChannelId); - assertThat(mListener.programUpdatedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS)) - .isTrue(); + assertTrue(mListener.programUpdatedLatch.await(WAIT_TIME_OUT_MS, TimeUnit.MILLISECONDS)); programList = mProgramDataManager.getPrograms(testChannelId, mClock.currentTimeMillis()); - assertThat(lastProgramEndTime) - .isLessThan(programList.get(programList.size() - 1).getEndTimeUtcMillis()); + assertTrue( + lastProgramEndTime < programList.get(programList.size() - 1).getEndTimeUtcMillis()); } /** Test for {@link ProgramDataManager#setPauseProgramUpdate(boolean)}. */ @@ -233,28 +224,23 @@ public class ProgramDataManagerTest { mListener.reset(); mProgramDataManager.setPauseProgramUpdate(true); mContentProvider.simulateAppend(testChannelId); - assertThat(mListener.programUpdatedLatch.await(FAILURE_TIME_OUT_MS, TimeUnit.MILLISECONDS)) - .isFalse(); + assertFalse( + mListener.programUpdatedLatch.await(FAILURE_TIME_OUT_MS, TimeUnit.MILLISECONDS)); } public static void assertProgramEquals( long expectedStartTime, ProgramInfo expectedInfo, Program actualProgram) { - assertWithMessage("title").that(actualProgram.getTitle()).isEqualTo(expectedInfo.title); - assertWithMessage("episode") - .that(actualProgram.getEpisodeTitle()) - .isEqualTo(expectedInfo.episode); - assertWithMessage("description") - .that(actualProgram.getDescription()) - .isEqualTo(expectedInfo.description); - assertWithMessage("startTime") - .that(actualProgram.getStartTimeUtcMillis()) - .isEqualTo(expectedStartTime); - assertWithMessage("endTime") - .that(actualProgram.getEndTimeUtcMillis()) - .isEqualTo(expectedStartTime + expectedInfo.durationMs); + assertEquals("title", expectedInfo.title, actualProgram.getTitle()); + assertEquals("episode", expectedInfo.episode, actualProgram.getEpisodeTitle()); + assertEquals("description", expectedInfo.description, actualProgram.getDescription()); + assertEquals("startTime", expectedStartTime, actualProgram.getStartTimeUtcMillis()); + assertEquals( + "endTime", + expectedStartTime + expectedInfo.durationMs, + actualProgram.getEndTimeUtcMillis()); } - private final class FakeContentResolver extends MockContentResolver { + private class FakeContentResolver extends MockContentResolver { @Override public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) { super.notifyChange(uri, observer, syncToNetwork); @@ -269,7 +255,7 @@ public class ProgramDataManagerTest { } } - private static final class ProgramInfoWrapper { + private static class ProgramInfoWrapper { private final int index; private final long startTimeMs; private final ProgramInfo programInfo; @@ -283,7 +269,7 @@ public class ProgramDataManagerTest { // This implements the minimal methods in content resolver // and detailed assumptions are written in each method. - private final class FakeContentProvider extends MockContentProvider { + private class FakeContentProvider extends MockContentProvider { private final SparseArray<List<ProgramInfoWrapper>> mProgramInfoList = new SparseArray<>(); /** @@ -374,9 +360,9 @@ public class ProgramDataManagerTest { } private void assertProgramUri(Uri uri) { - assertWithMessage("Uri(" + uri + ") isn't channel uri") - .that(uri.toString().startsWith(TvContract.Programs.CONTENT_URI.toString())) - .isTrue(); + assertTrue( + "Uri(" + uri + ") isn't channel uri", + uri.toString().startsWith(TvContract.Programs.CONTENT_URI.toString())); } public ProgramInfoWrapper get(long channelId, int position) { @@ -388,8 +374,8 @@ public class ProgramDataManagerTest { } } - private final class FakeCursor extends MockCursor { - private final String[] allColumns = { + private class FakeCursor extends MockCursor { + private final String[] ALL_COLUMNS = { TvContract.Programs.COLUMN_CHANNEL_ID, TvContract.Programs.COLUMN_TITLE, TvContract.Programs.COLUMN_SHORT_DESCRIPTION, @@ -417,7 +403,7 @@ public class ProgramDataManagerTest { * @param endTimeMs end of the time range to query programs. */ public FakeCursor(String[] columns, long channelId, long startTimeMs, long endTimeMs) { - mColumns = (columns == null) ? allColumns : columns; + mColumns = (columns == null) ? ALL_COLUMNS : columns; mIsQueryForSingleChannel = (channelId > 0); mChannelId = channelId; mProgramPosition = -1; @@ -480,12 +466,11 @@ public class ProgramDataManagerTest { return mCurrentProgram.startTimeMs; case TvContract.Programs.COLUMN_END_TIME_UTC_MILLIS: return mCurrentProgram.startTimeMs + mCurrentProgram.programInfo.durationMs; - default: - if (DEBUG) { - Log.d(TAG, "Column (" + columnName + ") is ignored in getLong()"); - } - return 0; } + if (DEBUG) { + Log.d(TAG, "Column (" + columnName + ") is ignored in getLong()"); + } + return 0; } @Override @@ -498,12 +483,11 @@ public class ProgramDataManagerTest { return mCurrentProgram.programInfo.description; case TvContract.Programs.COLUMN_EPISODE_TITLE: return mCurrentProgram.programInfo.episode; - default: - if (DEBUG) { - Log.d(TAG, "Column (" + columnName + ") is ignored in getString()"); - } - return null; } + if (DEBUG) { + Log.d(TAG, "Column (" + columnName + ") is ignored in getString()"); + } + return null; } @Override diff --git a/tests/unit/src/com/android/tv/data/ProgramTest.java b/tests/unit/src/com/android/tv/data/ProgramTest.java index 3f2a9f26..a69688d2 100644 --- a/tests/unit/src/com/android/tv/data/ProgramTest.java +++ b/tests/unit/src/com/android/tv/data/ProgramTest.java @@ -17,24 +17,22 @@ package com.android.tv.data; import static android.media.tv.TvContract.Programs.Genres.COMEDY; import static android.media.tv.TvContract.Programs.Genres.FAMILY_KIDS; -import static com.google.common.truth.Truth.assertThat; -import static com.google.common.truth.Truth.assertWithMessage; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import android.media.tv.TvContentRating; import android.media.tv.TvContract.Programs.Genres; import android.os.Parcel; import android.support.test.filters.SmallTest; -import android.support.test.runner.AndroidJUnit4; import com.android.tv.data.Program.CriticScore; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.junit.Test; -import org.junit.runner.RunWith; /** Tests for {@link Program}. */ @SmallTest -@RunWith(AndroidJUnit4.class) public class ProgramTest { private static final int NOT_FOUND_GENRE = 987; @@ -45,7 +43,7 @@ public class ProgramTest { @Test public void testBuild() { Program program = new Program.Builder().build(); - assertWithMessage("isValid").that(program.isValid()).isFalse(); + assertEquals("isValid", false, program.isValid()); } @Test @@ -129,7 +127,7 @@ public class ProgramTest { p2.unmarshall(bytes, 0, bytes.length); p2.setDataPosition(0); Program r2 = Program.fromParcel(p2); - assertThat(r2).isEqualTo(p); + assertEquals(p, r2); } finally { p1.recycle(); p2.recycle(); @@ -143,36 +141,34 @@ public class ProgramTest { .setTitle("MyTitle") .addCriticScore( new CriticScore( - "default source", "5/10", "http://testurl/testimage.jpg")) + "default source", "5/10", "https://testurl/testimage.jpg")) .build(); Parcel parcel = Parcel.obtain(); program.writeToParcel(parcel, 0); parcel.setDataPosition(0); Program programFromParcel = Program.CREATOR.createFromParcel(parcel); - assertThat(programFromParcel.getCriticScores()).isNotNull(); - assertThat(programFromParcel.getCriticScores().get(0).source).isEqualTo("default source"); - assertThat(programFromParcel.getCriticScores().get(0).score).isEqualTo("5/10"); - assertThat(programFromParcel.getCriticScores().get(0).logoUrl) - .isEqualTo("http://testurl/testimage.jpg"); + assertNotNull(programFromParcel.getCriticScores()); + assertEquals(programFromParcel.getCriticScores().get(0).source, "default source"); + assertEquals(programFromParcel.getCriticScores().get(0).score, "5/10"); + assertEquals( + programFromParcel.getCriticScores().get(0).logoUrl, + "https://testurl/testimage.jpg"); } private static void assertNullCanonicalGenres(Program program) { String[] actual = program.getCanonicalGenres(); - assertWithMessage("Expected null canonical genres but was " + Arrays.toString(actual)) - .that(actual) - .isNull(); + assertNull("Expected null canonical genres but was " + Arrays.toString(actual), actual); } private static void assertCanonicalGenres(Program program, String... expected) { - assertWithMessage("canonical genres") - .that(Arrays.asList(program.getCanonicalGenres())) - .isEqualTo(Arrays.asList(expected)); + assertEquals( + "canonical genres", + Arrays.asList(expected), + Arrays.asList(program.getCanonicalGenres())); } private static void assertHasGenre(Program program, int genreId, boolean expected) { - assertWithMessage("hasGenre(" + genreId + ")") - .that(program.hasGenre(genreId)) - .isEqualTo(expected); + assertEquals("hasGenre(" + genreId + ")", expected, program.hasGenre(genreId)); } } diff --git a/tests/unit/src/com/android/tv/data/TvInputNewComparatorTest.java b/tests/unit/src/com/android/tv/data/TvInputNewComparatorTest.java index 8bf3efbc..496d1018 100644 --- a/tests/unit/src/com/android/tv/data/TvInputNewComparatorTest.java +++ b/tests/unit/src/com/android/tv/data/TvInputNewComparatorTest.java @@ -19,7 +19,6 @@ package com.android.tv.data; import android.content.pm.ResolveInfo; import android.media.tv.TvInputInfo; import android.support.test.filters.SmallTest; -import android.support.test.runner.AndroidJUnit4; import android.util.Pair; import com.android.tv.testing.ComparatorTester; import com.android.tv.util.SetupUtils; @@ -28,7 +27,6 @@ import com.android.tv.util.TvInputManagerHelper; import java.util.Comparator; import java.util.LinkedHashMap; import org.junit.Test; -import org.junit.runner.RunWith; import org.mockito.Matchers; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; @@ -36,7 +34,6 @@ import org.mockito.stubbing.Answer; /** Test for {@link TvInputNewComparator} */ @SmallTest -@RunWith(AndroidJUnit4.class) public class TvInputNewComparatorTest { @Test public void testComparator() throws Exception { diff --git a/tests/unit/src/com/android/tv/data/WatchedHistoryManagerTest.java b/tests/unit/src/com/android/tv/data/WatchedHistoryManagerTest.java index 539698bf..e65a71fb 100644 --- a/tests/unit/src/com/android/tv/data/WatchedHistoryManagerTest.java +++ b/tests/unit/src/com/android/tv/data/WatchedHistoryManagerTest.java @@ -17,16 +17,16 @@ package com.android.tv.data; import static android.support.test.InstrumentationRegistry.getTargetContext; -import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import android.os.Looper; import android.support.test.filters.MediumTest; -import android.support.test.runner.AndroidJUnit4; import com.android.tv.data.WatchedHistoryManager.WatchedRecord; import java.util.concurrent.TimeUnit; import org.junit.Before; import org.junit.Test; -import org.junit.runner.RunWith; /** * Test for {@link com.android.tv.data.WatchedHistoryManagerTest} @@ -34,7 +34,6 @@ import org.junit.runner.RunWith; * <p>This is a medium test because it load files which accessing SharedPreferences. */ @MediumTest -@RunWith(AndroidJUnit4.class) public class WatchedHistoryManagerTest { // Wait time for expected success. private static final int MAX_HISTORY_SIZE = 100; @@ -54,13 +53,13 @@ public class WatchedHistoryManagerTest { private void startAndWaitForComplete() throws InterruptedException { mWatchedHistoryManager.start(); - assertThat(mListener.mLoadFinished).isTrue(); + assertTrue(mListener.mLoadFinished); } @Test public void testIsLoaded() throws InterruptedException { startAndWaitForComplete(); - assertThat(mWatchedHistoryManager.isLoaded()).isTrue(); + assertTrue(mWatchedHistoryManager.isLoaded()); } @Test @@ -75,10 +74,10 @@ public class WatchedHistoryManagerTest { WatchedRecord record = mWatchedHistoryManager.getRecord(0); WatchedRecord recordFromSharedPreferences = mWatchedHistoryManager.getRecordFromSharedPreferences(0); - assertThat(fakeId).isEqualTo(record.channelId); - assertThat(time - duration).isEqualTo(record.watchedStartTime); - assertThat(duration).isEqualTo(record.duration); - assertThat(recordFromSharedPreferences).isEqualTo(record); + assertEquals(record.channelId, fakeId); + assertEquals(record.watchedStartTime, time - duration); + assertEquals(record.duration, duration); + assertEquals(record, recordFromSharedPreferences); } @Test @@ -97,21 +96,22 @@ public class WatchedHistoryManagerTest { WatchedRecord record = mWatchedHistoryManager.getRecord(i); WatchedRecord recordFromSharedPreferences = mWatchedHistoryManager.getRecordFromSharedPreferences(i); - assertThat(recordFromSharedPreferences).isEqualTo(record); - assertThat(startChannelId + size - 1 - i).isEqualTo(record.channelId); + assertEquals(record, recordFromSharedPreferences); + assertEquals(record.channelId, startChannelId + size - 1 - i); } // Since the WatchedHistory is a circular queue, the value for 0 and maxHistorySize // are same. - assertThat(mWatchedHistoryManager.getRecordFromSharedPreferences(MAX_HISTORY_SIZE)) - .isEqualTo(mWatchedHistoryManager.getRecordFromSharedPreferences(0)); + assertEquals( + mWatchedHistoryManager.getRecordFromSharedPreferences(0), + mWatchedHistoryManager.getRecordFromSharedPreferences(MAX_HISTORY_SIZE)); } @Test public void testWatchedRecordEquals() { - assertThat(new WatchedRecord(1, 2, 3).equals(new WatchedRecord(1, 2, 3))).isTrue(); - assertThat(new WatchedRecord(1, 2, 3).equals(new WatchedRecord(1, 2, 4))).isFalse(); - assertThat(new WatchedRecord(1, 2, 3).equals(new WatchedRecord(1, 4, 3))).isFalse(); - assertThat(new WatchedRecord(1, 2, 3).equals(new WatchedRecord(4, 2, 3))).isFalse(); + assertTrue(new WatchedRecord(1, 2, 3).equals(new WatchedRecord(1, 2, 3))); + assertFalse(new WatchedRecord(1, 2, 3).equals(new WatchedRecord(1, 2, 4))); + assertFalse(new WatchedRecord(1, 2, 3).equals(new WatchedRecord(1, 4, 3))); + assertFalse(new WatchedRecord(1, 2, 3).equals(new WatchedRecord(4, 2, 3))); } @Test @@ -122,11 +122,10 @@ public class WatchedHistoryManagerTest { WatchedRecord record = new WatchedRecord(fakeId, time, duration); WatchedRecord sameRecord = mWatchedHistoryManager.decode(mWatchedHistoryManager.encode(record)); - assertThat(sameRecord).isEqualTo(record); + assertEquals(record, sameRecord); } - private static final class TestWatchedHistoryManagerListener - implements WatchedHistoryManager.Listener { + private class TestWatchedHistoryManagerListener implements WatchedHistoryManager.Listener { boolean mLoadFinished; @Override diff --git a/tests/unit/src/com/android/tv/dvr/BaseDvrDataManagerTest.java b/tests/unit/src/com/android/tv/dvr/BaseDvrDataManagerTest.java new file mode 100644 index 00000000..c9c76a5a --- /dev/null +++ b/tests/unit/src/com/android/tv/dvr/BaseDvrDataManagerTest.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2016 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.tv.dvr; + +import static android.support.test.InstrumentationRegistry.getContext; + +import android.os.Build; +import android.support.annotation.NonNull; +import android.support.test.filters.SdkSuppress; +import android.support.test.filters.SmallTest; +import android.test.MoreAsserts; +import com.android.tv.common.feature.CommonFeatures; +import com.android.tv.common.feature.TestableFeature; +import com.android.tv.dvr.data.ScheduledRecording; +import com.android.tv.testing.FakeClock; +import com.android.tv.testing.dvr.RecordingTestUtils; +import java.util.List; +import java.util.concurrent.TimeUnit; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** Tests for {@link BaseDvrDataManager} using {@link DvrDataManagerInMemoryImpl}. */ +@SmallTest +@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N) +public class BaseDvrDataManagerTest { + private static final String INPUT_ID = "input_id"; + private static final int CHANNEL_ID = 273; + + private final TestableFeature mDvrFeature = CommonFeatures.DVR; + private DvrDataManagerInMemoryImpl mDvrDataManager; + private FakeClock mFakeClock; + + @Before + public void setUp() { + mDvrFeature.enableForTest(); + mFakeClock = FakeClock.createWithCurrentTime(); + mDvrDataManager = new DvrDataManagerInMemoryImpl(getContext(), mFakeClock); + } + + @After + public void tearDown() { + mDvrFeature.resetForTests(); + } + + @Test + public void testGetNonStartedScheduledRecordings() { + ScheduledRecording recording = + mDvrDataManager.addScheduledRecordingInternal( + createNewScheduledRecordingStartingNow()); + List<ScheduledRecording> result = mDvrDataManager.getNonStartedScheduledRecordings(); + MoreAsserts.assertContentsInAnyOrder(result, recording); + } + + @Test + public void testGetNonStartedScheduledRecordings_past() { + mDvrDataManager.addScheduledRecordingInternal(createNewScheduledRecordingStartingNow()); + mFakeClock.increment(TimeUnit.MINUTES, 6); + List<ScheduledRecording> result = mDvrDataManager.getNonStartedScheduledRecordings(); + MoreAsserts.assertContentsInAnyOrder(result); + } + + @NonNull + private ScheduledRecording createNewScheduledRecordingStartingNow() { + return ScheduledRecording.buildFrom( + RecordingTestUtils.createTestRecordingWithIdAndPeriod( + ScheduledRecording.ID_NOT_SET, + INPUT_ID, + CHANNEL_ID, + mFakeClock.currentTimeMillis(), + mFakeClock.currentTimeMillis() + TimeUnit.MINUTES.toMillis(5))) + .setState(ScheduledRecording.STATE_RECORDING_NOT_STARTED) + .build(); + } +} diff --git a/tests/unit/src/com/android/tv/dvr/DvrDataManagerImplTest.java b/tests/unit/src/com/android/tv/dvr/DvrDataManagerImplTest.java new file mode 100644 index 00000000..8a5dfabd --- /dev/null +++ b/tests/unit/src/com/android/tv/dvr/DvrDataManagerImplTest.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2015 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.tv.dvr; + +import static org.junit.Assert.assertEquals; + +import android.os.Build; +import android.support.test.filters.SdkSuppress; +import android.support.test.filters.SmallTest; +import com.android.tv.dvr.data.ScheduledRecording; +import com.android.tv.testing.dvr.RecordingTestUtils; +import java.util.ArrayList; +import java.util.List; +import org.junit.Test; + +/** Tests for {@link DvrDataManagerImpl} */ +@SmallTest +@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N) +public class DvrDataManagerImplTest { + private static final String INPUT_ID = "input_id"; + private static final int CHANNEL_ID = 273; + + @Test + public void testGetNextScheduledStartTimeAfter() { + long id = 1; + List<ScheduledRecording> scheduledRecordings = new ArrayList<>(); + assertNextStartTime(scheduledRecordings, 0L, DvrDataManager.NEXT_START_TIME_NOT_FOUND); + scheduledRecordings.add( + RecordingTestUtils.createTestRecordingWithIdAndPeriod( + id++, INPUT_ID, CHANNEL_ID, 10L, 20L)); + assertNextStartTime(scheduledRecordings, 9L, 10L); + assertNextStartTime(scheduledRecordings, 10L, DvrDataManager.NEXT_START_TIME_NOT_FOUND); + scheduledRecordings.add( + RecordingTestUtils.createTestRecordingWithIdAndPeriod( + id++, INPUT_ID, CHANNEL_ID, 20L, 30L)); + assertNextStartTime(scheduledRecordings, 9L, 10L); + assertNextStartTime(scheduledRecordings, 10L, 20L); + assertNextStartTime(scheduledRecordings, 20L, DvrDataManager.NEXT_START_TIME_NOT_FOUND); + scheduledRecordings.add( + RecordingTestUtils.createTestRecordingWithIdAndPeriod( + id++, INPUT_ID, CHANNEL_ID, 30L, 40L)); + assertNextStartTime(scheduledRecordings, 9L, 10L); + assertNextStartTime(scheduledRecordings, 10L, 20L); + assertNextStartTime(scheduledRecordings, 20L, 30L); + assertNextStartTime(scheduledRecordings, 30L, DvrDataManager.NEXT_START_TIME_NOT_FOUND); + scheduledRecordings.clear(); + scheduledRecordings.add( + RecordingTestUtils.createTestRecordingWithIdAndPeriod( + id++, INPUT_ID, CHANNEL_ID, 10L, 20L)); + scheduledRecordings.add( + RecordingTestUtils.createTestRecordingWithIdAndPeriod( + id++, INPUT_ID, CHANNEL_ID, 10L, 20L)); + scheduledRecordings.add( + RecordingTestUtils.createTestRecordingWithIdAndPeriod( + id++, INPUT_ID, CHANNEL_ID, 10L, 20L)); + assertNextStartTime(scheduledRecordings, 9L, 10L); + assertNextStartTime(scheduledRecordings, 10L, DvrDataManager.NEXT_START_TIME_NOT_FOUND); + } + + private void assertNextStartTime( + List<ScheduledRecording> scheduledRecordings, long startTime, long expected) { + assertEquals( + "getNextScheduledStartTimeAfter()", + expected, + DvrDataManagerImpl.getNextStartTimeAfter(scheduledRecordings, startTime)); + } +} diff --git a/tests/unit/src/com/android/tv/dvr/DvrDataManagerInMemoryImpl.java b/tests/unit/src/com/android/tv/dvr/DvrDataManagerInMemoryImpl.java new file mode 100644 index 00000000..a16f7acc --- /dev/null +++ b/tests/unit/src/com/android/tv/dvr/DvrDataManagerInMemoryImpl.java @@ -0,0 +1,310 @@ +/* + * Copyright (C) 2015 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.tv.dvr; + +import android.content.Context; +import android.os.Build; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; +import android.support.test.filters.SdkSuppress; +import android.text.TextUtils; +import android.util.Log; +import android.util.Range; +import com.android.tv.common.SoftPreconditions; +import com.android.tv.dvr.data.RecordedProgram; +import com.android.tv.dvr.data.ScheduledRecording; +import com.android.tv.dvr.data.ScheduledRecording.RecordingState; +import com.android.tv.dvr.data.SeriesRecording; +import com.android.tv.util.Clock; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicLong; + +/** A DVR Data manager that stores values in memory suitable for testing. */ +@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N) +public final class DvrDataManagerInMemoryImpl extends BaseDvrDataManager { + private static final String TAG = "DvrDataManagerInMemory"; + private final AtomicLong mNextId = new AtomicLong(1); + private final Map<Long, ScheduledRecording> mScheduledRecordings = new HashMap<>(); + private final Map<Long, RecordedProgram> mRecordedPrograms = new HashMap<>(); + private final Map<Long, SeriesRecording> mSeriesRecordings = new HashMap<>(); + + public DvrDataManagerInMemoryImpl(Context context, Clock clock) { + super(context, clock); + } + + @Override + public boolean isInitialized() { + return true; + } + + @Override + public boolean isDvrScheduleLoadFinished() { + return true; + } + + @Override + public boolean isRecordedProgramLoadFinished() { + return true; + } + + private List<ScheduledRecording> getScheduledRecordingsPrograms() { + return new ArrayList<>(mScheduledRecordings.values()); + } + + @Override + public List<RecordedProgram> getRecordedPrograms() { + return new ArrayList<>(mRecordedPrograms.values()); + } + + @Override + public List<ScheduledRecording> getAllScheduledRecordings() { + return new ArrayList<>(mScheduledRecordings.values()); + } + + public List<SeriesRecording> getSeriesRecordings() { + return new ArrayList<>(mSeriesRecordings.values()); + } + + @Override + public List<SeriesRecording> getSeriesRecordings(String inputId) { + List<SeriesRecording> result = new ArrayList<>(); + for (SeriesRecording r : mSeriesRecordings.values()) { + if (TextUtils.equals(r.getInputId(), inputId)) { + result.add(r); + } + } + return result; + } + + @Override + public long getNextScheduledStartTimeAfter(long startTime) { + + List<ScheduledRecording> temp = getNonStartedScheduledRecordings(); + Collections.sort(temp, ScheduledRecording.START_TIME_COMPARATOR); + for (ScheduledRecording r : temp) { + if (r.getStartTimeMs() > startTime) { + return r.getStartTimeMs(); + } + } + return DvrDataManager.NEXT_START_TIME_NOT_FOUND; + } + + @Override + public List<ScheduledRecording> getScheduledRecordings( + Range<Long> period, @RecordingState int state) { + List<ScheduledRecording> temp = getScheduledRecordingsPrograms(); + List<ScheduledRecording> result = new ArrayList<>(); + for (ScheduledRecording r : temp) { + if (r.isOverLapping(period) && r.getState() == state) { + result.add(r); + } + } + return result; + } + + @Override + public List<ScheduledRecording> getScheduledRecordings(long seriesRecordingId) { + List<ScheduledRecording> result = new ArrayList<>(); + for (ScheduledRecording r : mScheduledRecordings.values()) { + if (r.getSeriesRecordingId() == seriesRecordingId) { + result.add(r); + } + } + return result; + } + + @Override + public List<ScheduledRecording> getScheduledRecordings(String inputId) { + List<ScheduledRecording> result = new ArrayList<>(); + for (ScheduledRecording r : mScheduledRecordings.values()) { + if (TextUtils.equals(r.getInputId(), inputId)) { + result.add(r); + } + } + return result; + } + + /** Add a new scheduled recording. */ + @Override + public void addScheduledRecording(ScheduledRecording... scheduledRecordings) { + for (ScheduledRecording r : scheduledRecordings) { + addScheduledRecordingInternal(r); + } + } + + public void addRecordedProgram(RecordedProgram recordedProgram) { + addRecordedProgramInternal(recordedProgram); + } + + public void updateRecordedProgram(RecordedProgram r) { + long id = r.getId(); + if (mRecordedPrograms.containsKey(id)) { + mRecordedPrograms.put(id, r); + notifyRecordedProgramsChanged(r); + } else { + throw new IllegalArgumentException("Recording not found:" + r); + } + } + + public void removeRecordedProgram(RecordedProgram scheduledRecording) { + mRecordedPrograms.remove(scheduledRecording.getId()); + notifyRecordedProgramsRemoved(scheduledRecording); + } + + public ScheduledRecording addScheduledRecordingInternal(ScheduledRecording scheduledRecording) { + SoftPreconditions.checkState( + scheduledRecording.getId() == ScheduledRecording.ID_NOT_SET, + TAG, + "expected id of " + + ScheduledRecording.ID_NOT_SET + + " but was " + + scheduledRecording); + scheduledRecording = + ScheduledRecording.buildFrom(scheduledRecording) + .setId(mNextId.incrementAndGet()) + .build(); + mScheduledRecordings.put(scheduledRecording.getId(), scheduledRecording); + notifyScheduledRecordingAdded(scheduledRecording); + return scheduledRecording; + } + + public RecordedProgram addRecordedProgramInternal(RecordedProgram recordedProgram) { + SoftPreconditions.checkState( + recordedProgram.getId() == RecordedProgram.ID_NOT_SET, + TAG, + "expected id of " + RecordedProgram.ID_NOT_SET + " but was " + recordedProgram); + recordedProgram = + RecordedProgram.buildFrom(recordedProgram).setId(mNextId.incrementAndGet()).build(); + mRecordedPrograms.put(recordedProgram.getId(), recordedProgram); + notifyRecordedProgramsAdded(recordedProgram); + return recordedProgram; + } + + @Override + public void addSeriesRecording(SeriesRecording... seriesRecordings) { + for (SeriesRecording r : seriesRecordings) { + mSeriesRecordings.put(r.getId(), r); + } + notifySeriesRecordingAdded(seriesRecordings); + } + + @Override + public void removeScheduledRecording(ScheduledRecording... scheduledRecordings) { + for (ScheduledRecording r : scheduledRecordings) { + mScheduledRecordings.remove(r.getId()); + } + notifyScheduledRecordingRemoved(scheduledRecordings); + } + + @Override + public void removeScheduledRecording(boolean forceRemove, ScheduledRecording... schedule) { + removeScheduledRecording(schedule); + } + + @Override + public void removeSeriesRecording(SeriesRecording... seriesRecordings) { + for (SeriesRecording r : seriesRecordings) { + mSeriesRecordings.remove(r.getId()); + } + notifySeriesRecordingRemoved(seriesRecordings); + } + + @Override + public void updateScheduledRecording(ScheduledRecording... scheduledRecordings) { + for (ScheduledRecording r : scheduledRecordings) { + long id = r.getId(); + if (mScheduledRecordings.containsKey(id)) { + mScheduledRecordings.put(id, r); + } else { + Log.d(TAG, "Recording not found:" + r); + } + } + notifyScheduledRecordingStatusChanged(scheduledRecordings); + } + + @Override + public void updateSeriesRecording(SeriesRecording... seriesRecordings) { + for (SeriesRecording r : seriesRecordings) { + long id = r.getId(); + if (mSeriesRecordings.containsKey(id)) { + mSeriesRecordings.put(id, r); + } else { + throw new IllegalArgumentException("Recording not found:" + r); + } + } + notifySeriesRecordingChanged(seriesRecordings); + } + + @Nullable + @Override + public ScheduledRecording getScheduledRecording(long id) { + return mScheduledRecordings.get(id); + } + + @Nullable + @Override + public ScheduledRecording getScheduledRecordingForProgramId(long programId) { + for (ScheduledRecording r : mScheduledRecordings.values()) { + if (r.getProgramId() == programId) { + return r; + } + } + return null; + } + + @Nullable + @Override + public SeriesRecording getSeriesRecording(long seriesRecordingId) { + return mSeriesRecordings.get(seriesRecordingId); + } + + @Nullable + @Override + public SeriesRecording getSeriesRecording(String seriesId) { + for (SeriesRecording r : mSeriesRecordings.values()) { + if (r.getSeriesId().equals(seriesId)) { + return r; + } + } + return null; + } + + @Nullable + @Override + public RecordedProgram getRecordedProgram(long recordingId) { + return mRecordedPrograms.get(recordingId); + } + + @Override + @NonNull + protected List<ScheduledRecording> getRecordingsWithState(int... states) { + ArrayList<ScheduledRecording> result = new ArrayList<>(); + for (ScheduledRecording r : mScheduledRecordings.values()) { + for (int state : states) { + if (r.getState() == state) { + result.add(r); + break; + } + } + } + return result; + } +} diff --git a/tests/unit/src/com/android/tv/dvr/DvrScheduleManagerTest.java b/tests/unit/src/com/android/tv/dvr/DvrScheduleManagerTest.java new file mode 100644 index 00000000..ab464b18 --- /dev/null +++ b/tests/unit/src/com/android/tv/dvr/DvrScheduleManagerTest.java @@ -0,0 +1,831 @@ +/* + * Copyright (C) 2016 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.tv.dvr; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import android.os.Build; +import android.support.test.filters.SdkSuppress; +import android.support.test.filters.SmallTest; +import android.test.MoreAsserts; +import android.util.Range; +import com.android.tv.dvr.DvrScheduleManager.ConflictInfo; +import com.android.tv.dvr.data.ScheduledRecording; +import com.android.tv.testing.dvr.RecordingTestUtils; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.junit.Test; + +/** Tests for {@link DvrScheduleManager} */ +@SmallTest +@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N) +public class DvrScheduleManagerTest { + private static final String INPUT_ID = "input_id"; + + @Test + public void testGetConflictingSchedules_emptySchedule() { + List<ScheduledRecording> schedules = new ArrayList<>(); + MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 1)); + } + + @Test + public void testGetConflictingSchedules_noConflict() { + long priority = 0; + long channelId = 0; + List<ScheduledRecording> schedules = new ArrayList<>(); + + schedules.add( + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 0L, 200L)); + MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 1)); + + schedules.add( + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 0L, 100L)); + MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 2)); + + schedules.add( + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 100L, 200L)); + MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 2)); + + schedules.add( + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 0L, 100L)); + MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 3)); + + schedules.add( + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 100L, 200L)); + MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 3)); + } + + @Test + public void testGetConflictingSchedules_noTuner() { + long priority = 0; + long channelId = 0; + List<ScheduledRecording> schedules = new ArrayList<>(); + MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 0)); + + schedules.add( + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 0L, 200L)); + assertEquals(schedules, DvrScheduleManager.getConflictingSchedules(schedules, 0)); + schedules.add( + 0, + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 0L, 100L)); + assertEquals(schedules, DvrScheduleManager.getConflictingSchedules(schedules, 0)); + } + + @Test + public void testGetConflictingSchedules_conflict() { + long priority = 0; + long channelId = 0; + List<ScheduledRecording> schedules = new ArrayList<>(); + + ScheduledRecording r1 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 0L, 200L); + schedules.add(r1); + MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 1)); + + ScheduledRecording r2 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 0L, 100L); + schedules.add(r2); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 1), r1); + MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 2)); + + ScheduledRecording r3 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 100L, 200L); + schedules.add(r3); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 1), r1); + MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 2)); + + ScheduledRecording r4 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 0L, 100L); + schedules.add(r4); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 1), r2, r1); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 2), r1); + MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 3)); + + ScheduledRecording r5 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 100L, 200L); + schedules.add(r5); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 1), r3, r2, r1); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 2), r1); + MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 3)); + + ScheduledRecording r6 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 10L, 90L); + schedules.add(r6); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 1), r4, r3, r2, r1); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 2), r2, r1); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 3), r1); + MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 4)); + + ScheduledRecording r7 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 110L, 190L); + schedules.add(r7); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 1), r5, r4, r3, r2, r1); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 2), r3, r2, r1); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 3), r1); + MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 4)); + + ScheduledRecording r8 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 50L, 150L); + schedules.add(r8); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 1), + r7, + r6, + r5, + r4, + r3, + r2, + r1); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 2), r5, r4, r3, r2, r1); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 3), r3, r2, r1); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 4), r1); + MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 5)); + } + + @Test + public void testGetConflictingSchedules_conflict2() { + // The case when there is a long schedule. + long priority = 0; + long channelId = 0; + List<ScheduledRecording> schedules = new ArrayList<>(); + + ScheduledRecording r1 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 0L, 1000L); + schedules.add(r1); + MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 1)); + + ScheduledRecording r2 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 0L, 100L); + schedules.add(r2); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 1), r1); + MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 2)); + + ScheduledRecording r3 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 100L, 200L); + schedules.add(r3); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 1), r1); + MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 2)); + } + + @Test + public void testGetConflictingSchedules_reverseOrder() { + long priority = 0; + long channelId = 0; + List<ScheduledRecording> schedules = new ArrayList<>(); + + ScheduledRecording r1 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 0L, 200L); + schedules.add(0, r1); + MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 1)); + + ScheduledRecording r2 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 0L, 100L); + schedules.add(0, r2); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 1), r1); + MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 2)); + + ScheduledRecording r3 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 100L, 200L); + schedules.add(0, r3); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 1), r1); + MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 2)); + + ScheduledRecording r4 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 0L, 100L); + schedules.add(0, r4); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 1), r2, r1); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 2), r1); + MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 3)); + + ScheduledRecording r5 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 100L, 200L); + schedules.add(0, r5); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 1), r3, r2, r1); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 2), r1); + MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 3)); + + ScheduledRecording r6 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 10L, 90L); + schedules.add(0, r6); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 1), r4, r3, r2, r1); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 2), r2, r1); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 3), r1); + MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 4)); + + ScheduledRecording r7 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 110L, 190L); + schedules.add(0, r7); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 1), r5, r4, r3, r2, r1); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 2), r3, r2, r1); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 3), r1); + MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 4)); + + ScheduledRecording r8 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 50L, 150L); + schedules.add(0, r8); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 1), + r7, + r6, + r5, + r4, + r3, + r2, + r1); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 2), r5, r4, r3, r2, r1); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 3), r3, r2, r1); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 4), r1); + MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 5)); + } + + @Test + public void testGetConflictingSchedules_period1() { + long priority = 0; + long channelId = 0; + List<ScheduledRecording> schedules = new ArrayList<>(); + + ScheduledRecording r1 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 0L, 200L); + schedules.add(r1); + ScheduledRecording r2 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 0L, 100L); + schedules.add(r2); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules( + schedules, 1, Collections.singletonList(new Range<>(10L, 20L))), + r1); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules( + schedules, 1, Collections.singletonList(new Range<>(110L, 120L))), + r1); + } + + @Test + public void testGetConflictingSchedules_period2() { + long priority = 0; + long channelId = 0; + List<ScheduledRecording> schedules = new ArrayList<>(); + + ScheduledRecording r1 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 0L, 200L); + schedules.add(r1); + ScheduledRecording r2 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 100L, 200L); + schedules.add(r2); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules( + schedules, 1, Collections.singletonList(new Range<>(10L, 20L))), + r1); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules( + schedules, 1, Collections.singletonList(new Range<>(110L, 120L))), + r1); + } + + @Test + public void testGetConflictingSchedules_period3() { + long priority = 0; + long channelId = 0; + List<ScheduledRecording> schedules = new ArrayList<>(); + + ScheduledRecording r1 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 0L, 100L); + schedules.add(r1); + ScheduledRecording r2 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 100L, 200L); + schedules.add(r2); + ScheduledRecording r3 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 0L, 100L); + schedules.add(r3); + ScheduledRecording r4 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 100L, 200L); + schedules.add(r4); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules( + schedules, 1, Collections.singletonList(new Range<>(10L, 20L))), + r1); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules( + schedules, 1, Collections.singletonList(new Range<>(110L, 120L))), + r2); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules( + schedules, 1, Collections.singletonList(new Range<>(50L, 150L))), + r2, + r1); + List<Range<Long>> ranges = new ArrayList<>(); + ranges.add(new Range<>(10L, 20L)); + ranges.add(new Range<>(110L, 120L)); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 1, ranges), r2, r1); + } + + @Test + public void testGetConflictingSchedules_addSchedules1() { + long priority = 0; + long channelId = 0; + List<ScheduledRecording> schedules = new ArrayList<>(); + + ScheduledRecording r1 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 0L, 200L); + schedules.add(r1); + ScheduledRecording r2 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 0L, 100L); + schedules.add(r2); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules( + Collections.singletonList( + ScheduledRecording.builder(INPUT_ID, ++channelId, 10L, 20L) + .setPriority(++priority) + .build()), + schedules, + 1), + r2, + r1); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules( + Collections.singletonList( + ScheduledRecording.builder(INPUT_ID, ++channelId, 110L, 120L) + .setPriority(++priority) + .build()), + schedules, + 1), + r1); + } + + @Test + public void testGetConflictingSchedules_addSchedules2() { + long priority = 0; + long channelId = 0; + List<ScheduledRecording> schedules = new ArrayList<>(); + + ScheduledRecording r1 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 0L, 200L); + schedules.add(r1); + ScheduledRecording r2 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 100L, 200L); + schedules.add(r2); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules( + Collections.singletonList( + ScheduledRecording.builder(INPUT_ID, ++channelId, 10L, 20L) + .setPriority(++priority) + .build()), + schedules, + 1), + r1); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules( + Collections.singletonList( + ScheduledRecording.builder(INPUT_ID, ++channelId, 110L, 120L) + .setPriority(++priority) + .build()), + schedules, + 1), + r2, + r1); + } + + @Test + public void testGetConflictingSchedules_addLowestPriority() { + long priority = 0; + long channelId = 0; + List<ScheduledRecording> schedules = new ArrayList<>(); + + ScheduledRecording r1 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 0L, 400L); + schedules.add(r1); + ScheduledRecording r2 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 100L, 200L); + schedules.add(r2); + // Returning r1 even though r1 has the higher priority than the new one. That's because r1 + // starts at 0 and stops at 100, and the new one will be recorded successfully. + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules( + Collections.singletonList( + ScheduledRecording.builder(INPUT_ID, ++channelId, 200L, 300L) + .setPriority(0) + .build()), + schedules, + 1), + r1); + } + + @Test + public void testGetConflictingSchedules_sameChannel() { + long priority = 0; + long channelId = 1; + List<ScheduledRecording> schedules = new ArrayList<>(); + schedules.add( + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + channelId, ++priority, 0L, 200L)); + schedules.add( + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + channelId, ++priority, 0L, 200L)); + MoreAsserts.assertEmpty(DvrScheduleManager.getConflictingSchedules(schedules, 3)); + } + + @Test + public void testGetConflictingSchedule_startEarlyAndFail() { + long priority = 0; + long channelId = 0; + List<ScheduledRecording> schedules = new ArrayList<>(); + ScheduledRecording r1 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 200L, 300L); + schedules.add(r1); + ScheduledRecording r2 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 0L, 400L); + schedules.add(r2); + ScheduledRecording r3 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 100L, 200L); + schedules.add(r3); + // r2 starts recording and fails when r3 starts. r1 is recorded successfully. + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 1), r2); + } + + @Test + public void testGetConflictingSchedule_startLate() { + long priority = 0; + long channelId = 0; + List<ScheduledRecording> schedules = new ArrayList<>(); + ScheduledRecording r1 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 200L, 400L); + schedules.add(r1); + ScheduledRecording r2 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 100L, 300L); + schedules.add(r2); + ScheduledRecording r3 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 0L, 200L); + schedules.add(r3); + // r2 and r1 are clipped. + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedules(schedules, 1), r2, r1); + } + + @Test + public void testGetConflictingSchedulesForTune_canTune() { + // Can tune to the recorded channel if tuner count is 1. + long priority = 0; + long channelId = 1; + List<ScheduledRecording> schedules = new ArrayList<>(); + schedules.add( + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + channelId, ++priority, 0L, 200L)); + MoreAsserts.assertEmpty( + DvrScheduleManager.getConflictingSchedulesForTune( + INPUT_ID, channelId, 0L, priority + 1, schedules, 1)); + } + + @Test + public void testGetConflictingSchedulesForTune_cannotTune() { + // Can't tune to a channel if other channel is recording and tuner count is 1. + long priority = 0; + long channelId = 1; + List<ScheduledRecording> schedules = new ArrayList<>(); + schedules.add( + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + channelId, ++priority, 0L, 200L)); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedulesForTune( + INPUT_ID, channelId + 1, 0L, priority + 1, schedules, 1), + schedules.get(0)); + } + + @Test + public void testGetConflictingSchedulesForWatching_otherChannels() { + // The other channels are to be recorded. + long priority = 0; + long channelToWatch = 1; + long channelId = 1; + List<ScheduledRecording> schedules = new ArrayList<>(); + ScheduledRecording r1 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 0L, 200L); + schedules.add(r1); + ScheduledRecording r2 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 0L, 200L); + schedules.add(r2); + MoreAsserts.assertEmpty( + DvrScheduleManager.getConflictingSchedulesForWatching( + INPUT_ID, channelToWatch, 0L, ++priority, schedules, 3)); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedulesForWatching( + INPUT_ID, channelToWatch, 0L, ++priority, schedules, 2), + r1); + } + + @Test + public void testGetConflictingSchedulesForWatching_sameChannel1() { + long priority = 0; + long channelToWatch = 1; + long channelId = 1; + List<ScheduledRecording> schedules = new ArrayList<>(); + ScheduledRecording r1 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + channelToWatch, ++priority, 0L, 200L); + schedules.add(r1); + ScheduledRecording r2 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 0L, 200L); + schedules.add(r2); + MoreAsserts.assertEmpty( + DvrScheduleManager.getConflictingSchedulesForWatching( + INPUT_ID, channelToWatch, 0L, ++priority, schedules, 2)); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedulesForWatching( + INPUT_ID, channelToWatch, 0L, ++priority, schedules, 1), + r2); + } + + @Test + public void testGetConflictingSchedulesForWatching_sameChannel2() { + long priority = 0; + long channelToWatch = 1; + long channelId = 1; + List<ScheduledRecording> schedules = new ArrayList<>(); + ScheduledRecording r1 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 0L, 200L); + schedules.add(r1); + ScheduledRecording r2 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + channelToWatch, ++priority, 0L, 200L); + schedules.add(r2); + MoreAsserts.assertEmpty( + DvrScheduleManager.getConflictingSchedulesForWatching( + INPUT_ID, channelToWatch, 0L, ++priority, schedules, 2)); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedulesForWatching( + INPUT_ID, channelToWatch, 0L, ++priority, schedules, 1), + r1); + } + + @Test + public void testGetConflictingSchedulesForWatching_sameChannelConflict1() { + long priority = 0; + long channelToWatch = 1; + long channelId = 1; + List<ScheduledRecording> schedules = new ArrayList<>(); + ScheduledRecording r1 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 0L, 200L); + schedules.add(r1); + ScheduledRecording r2 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + channelToWatch, ++priority, 0L, 200L); + schedules.add(r2); + ScheduledRecording r3 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + channelToWatch, ++priority, 0L, 200L); + schedules.add(r3); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedulesForWatching( + INPUT_ID, channelToWatch, 0L, ++priority, schedules, 3), + r2); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedulesForWatching( + INPUT_ID, channelToWatch, 0L, ++priority, schedules, 2), + r2); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedulesForWatching( + INPUT_ID, channelToWatch, 0L, ++priority, schedules, 1), + r2, + r1); + } + + @Test + public void testGetConflictingSchedulesForWatching_sameChannelConflict2() { + long priority = 0; + long channelToWatch = 1; + long channelId = 1; + List<ScheduledRecording> schedules = new ArrayList<>(); + ScheduledRecording r1 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + channelToWatch, ++priority, 0L, 200L); + schedules.add(r1); + ScheduledRecording r2 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + channelToWatch, ++priority, 0L, 200L); + schedules.add(r2); + ScheduledRecording r3 = + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, ++priority, 0L, 200L); + schedules.add(r3); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedulesForWatching( + INPUT_ID, channelToWatch, 0L, ++priority, schedules, 3), + r1); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedulesForWatching( + INPUT_ID, channelToWatch, 0L, ++priority, schedules, 2), + r1); + MoreAsserts.assertContentsInOrder( + DvrScheduleManager.getConflictingSchedulesForWatching( + INPUT_ID, channelToWatch, 0L, ++priority, schedules, 1), + r3, + r1); + } + + @Test + public void testPartiallyConflictingSchedules() { + long priority = 100; + long channelId = 0; + List<ScheduledRecording> schedules = + new ArrayList<>( + Arrays.asList( + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, --priority, 0L, 400L), + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, --priority, 0L, 200L), + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, --priority, 200L, 500L), + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, --priority, 400L, 600L), + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, --priority, 700L, 800L), + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, --priority, 600L, 900L), + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, --priority, 800L, 900L), + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, --priority, 800L, 900L), + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, --priority, 750L, 850L), + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, --priority, 300L, 450L), + RecordingTestUtils.createTestRecordingWithPriorityAndPeriod( + ++channelId, --priority, 50L, 900L))); + List<ConflictInfo> conflicts = DvrScheduleManager.getConflictingSchedulesInfo(schedules, 1); + + assertNotInList(schedules.get(0), conflicts); + assertFullConflict(schedules.get(1), conflicts); + assertPartialConflict(schedules.get(2), conflicts); + assertPartialConflict(schedules.get(3), conflicts); + assertNotInList(schedules.get(4), conflicts); + assertPartialConflict(schedules.get(5), conflicts); + assertNotInList(schedules.get(6), conflicts); + assertFullConflict(schedules.get(7), conflicts); + assertFullConflict(schedules.get(8), conflicts); + assertFullConflict(schedules.get(9), conflicts); + assertFullConflict(schedules.get(10), conflicts); + + conflicts = DvrScheduleManager.getConflictingSchedulesInfo(schedules, 2); + + assertNotInList(schedules.get(0), conflicts); + assertNotInList(schedules.get(1), conflicts); + assertNotInList(schedules.get(2), conflicts); + assertNotInList(schedules.get(3), conflicts); + assertNotInList(schedules.get(4), conflicts); + assertNotInList(schedules.get(5), conflicts); + assertNotInList(schedules.get(6), conflicts); + assertFullConflict(schedules.get(7), conflicts); + assertFullConflict(schedules.get(8), conflicts); + assertFullConflict(schedules.get(9), conflicts); + assertPartialConflict(schedules.get(10), conflicts); + + conflicts = DvrScheduleManager.getConflictingSchedulesInfo(schedules, 3); + + assertNotInList(schedules.get(0), conflicts); + assertNotInList(schedules.get(1), conflicts); + assertNotInList(schedules.get(2), conflicts); + assertNotInList(schedules.get(3), conflicts); + assertNotInList(schedules.get(4), conflicts); + assertNotInList(schedules.get(5), conflicts); + assertNotInList(schedules.get(6), conflicts); + assertNotInList(schedules.get(7), conflicts); + assertPartialConflict(schedules.get(8), conflicts); + assertNotInList(schedules.get(9), conflicts); + assertPartialConflict(schedules.get(10), conflicts); + } + + private void assertNotInList(ScheduledRecording schedule, List<ConflictInfo> conflicts) { + for (ConflictInfo conflictInfo : conflicts) { + if (conflictInfo.schedule.equals(schedule)) { + fail(schedule + " conflicts with others."); + } + } + } + + private void assertPartialConflict(ScheduledRecording schedule, List<ConflictInfo> conflicts) { + for (ConflictInfo conflictInfo : conflicts) { + if (conflictInfo.schedule.equals(schedule)) { + if (conflictInfo.partialConflict) { + return; + } else { + fail(schedule + " fully conflicts with others."); + } + } + } + fail(schedule + " doesn't conflict"); + } + + private void assertFullConflict(ScheduledRecording schedule, List<ConflictInfo> conflicts) { + for (ConflictInfo conflictInfo : conflicts) { + if (conflictInfo.schedule.equals(schedule)) { + if (!conflictInfo.partialConflict) { + return; + } else { + fail(schedule + " partially conflicts with others."); + } + } + } + fail(schedule + " doesn't conflict"); + } +} diff --git a/tests/unit/src/com/android/tv/dvr/ScheduledRecordingTest.java b/tests/unit/src/com/android/tv/dvr/ScheduledRecordingTest.java new file mode 100644 index 00000000..bf1b4d38 --- /dev/null +++ b/tests/unit/src/com/android/tv/dvr/ScheduledRecordingTest.java @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2015 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.tv.dvr; + +import static com.android.tv.testing.dvr.RecordingTestUtils.createTestRecordingWithIdAndPeriod; +import static com.android.tv.testing.dvr.RecordingTestUtils.normalizePriority; +import static junit.framework.TestCase.assertEquals; + +import android.os.Build; +import android.support.test.filters.SdkSuppress; +import android.support.test.filters.SmallTest; +import android.test.MoreAsserts; +import android.util.Range; +import com.android.tv.data.Channel; +import com.android.tv.data.Program; +import com.android.tv.dvr.data.ScheduledRecording; +import com.android.tv.testing.dvr.RecordingTestUtils; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import org.junit.Test; + +/** Tests for {@link ScheduledRecordingTest} */ +@SmallTest +@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N) +public class ScheduledRecordingTest { + private static final String INPUT_ID = "input_id"; + private static final int CHANNEL_ID = 273; + + @Test + public void testIsOverLapping() { + ScheduledRecording r = + createTestRecordingWithIdAndPeriod(1, INPUT_ID, CHANNEL_ID, 10L, 20L); + assertOverLapping(false, 1L, 9L, r); + + assertOverLapping(true, 1L, 20L, r); + assertOverLapping(false, 1L, 10L, r); + assertOverLapping(true, 10L, 19L, r); + assertOverLapping(true, 10L, 20L, r); + assertOverLapping(true, 11L, 20L, r); + assertOverLapping(true, 11L, 21L, r); + assertOverLapping(false, 20L, 21L, r); + + assertOverLapping(false, 21L, 29L, r); + } + + @Test + public void testBuildProgram() { + Channel c = new Channel.Builder().build(); + Program p = new Program.Builder().build(); + ScheduledRecording actual = + ScheduledRecording.builder(INPUT_ID, p).setChannelId(c.getId()).build(); + assertEquals("type", ScheduledRecording.TYPE_PROGRAM, actual.getType()); + } + + @Test + public void testBuildTime() { + ScheduledRecording actual = + createTestRecordingWithIdAndPeriod(1, INPUT_ID, CHANNEL_ID, 10L, 20L); + assertEquals("type", ScheduledRecording.TYPE_TIMED, actual.getType()); + } + + @Test + public void testBuildFrom() { + ScheduledRecording expected = + createTestRecordingWithIdAndPeriod(1, INPUT_ID, CHANNEL_ID, 10L, 20L); + ScheduledRecording actual = ScheduledRecording.buildFrom(expected).build(); + RecordingTestUtils.assertRecordingEquals(expected, actual); + } + + @Test + public void testBuild_priority() { + ScheduledRecording a = + normalizePriority( + createTestRecordingWithIdAndPeriod(1, INPUT_ID, CHANNEL_ID, 10L, 20L)); + ScheduledRecording b = + normalizePriority( + createTestRecordingWithIdAndPeriod(2, INPUT_ID, CHANNEL_ID, 10L, 20L)); + ScheduledRecording c = + normalizePriority( + createTestRecordingWithIdAndPeriod(3, INPUT_ID, CHANNEL_ID, 10L, 20L)); + + // default priority + MoreAsserts.assertContentsInOrder(sortByPriority(c, b, a), a, b, c); + + // make A preferred over B + a = ScheduledRecording.buildFrom(a).setPriority(b.getPriority() + 2).build(); + MoreAsserts.assertContentsInOrder(sortByPriority(a, b, c), b, c, a); + } + + public Collection<ScheduledRecording> sortByPriority( + ScheduledRecording a, ScheduledRecording b, ScheduledRecording c) { + List<ScheduledRecording> list = Arrays.asList(a, b, c); + Collections.sort(list, ScheduledRecording.PRIORITY_COMPARATOR); + return list; + } + + private void assertOverLapping(boolean expected, long lower, long upper, ScheduledRecording r) { + assertEquals( + "isOverlapping(Range(" + lower + "," + upper + "), recording " + r, + expected, + r.isOverLapping(new Range<>(lower, upper))); + } +} diff --git a/tests/unit/src/com/android/tv/dvr/data/SeriesRecordingTest.java b/tests/unit/src/com/android/tv/dvr/data/SeriesRecordingTest.java new file mode 100644 index 00000000..68929e95 --- /dev/null +++ b/tests/unit/src/com/android/tv/dvr/data/SeriesRecordingTest.java @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2016 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.tv.dvr.data; + +import static org.junit.Assert.assertEquals; + +import android.os.Build; +import android.os.Parcel; +import android.support.test.filters.SdkSuppress; +import android.support.test.filters.SmallTest; +import com.android.tv.data.Program; +import org.junit.Test; + +/** Tests for {@link SeriesRecording}. */ +@SmallTest +@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N) +public class SeriesRecordingTest { + private static final String PROGRAM_TITLE = "MyProgram"; + private static final long CHANNEL_ID = 123; + private static final long OTHER_CHANNEL_ID = 321; + private static final String SERIES_ID = "SERIES_ID"; + private static final String OTHER_SERIES_ID = "OTHER_SERIES_ID"; + + private final SeriesRecording mBaseSeriesRecording = + new SeriesRecording.Builder() + .setTitle(PROGRAM_TITLE) + .setChannelId(CHANNEL_ID) + .setSeriesId(SERIES_ID) + .build(); + private final SeriesRecording mSeriesRecordingSeason2 = + SeriesRecording.buildFrom(mBaseSeriesRecording).setStartFromSeason(2).build(); + private final SeriesRecording mSeriesRecordingSeason2Episode5 = + SeriesRecording.buildFrom(mSeriesRecordingSeason2).setStartFromEpisode(5).build(); + private final Program mBaseProgram = + new Program.Builder() + .setTitle(PROGRAM_TITLE) + .setChannelId(CHANNEL_ID) + .setSeriesId(SERIES_ID) + .build(); + + @Test + public void testParcelable() { + SeriesRecording r1 = + new SeriesRecording.Builder() + .setId(1) + .setChannelId(2) + .setPriority(3) + .setTitle("4") + .setDescription("5") + .setLongDescription("5-long") + .setSeriesId("6") + .setStartFromEpisode(7) + .setStartFromSeason(8) + .setChannelOption(SeriesRecording.OPTION_CHANNEL_ALL) + .setCanonicalGenreIds(new int[] {9, 10}) + .setPosterUri("11") + .setPhotoUri("12") + .build(); + Parcel p1 = Parcel.obtain(); + Parcel p2 = Parcel.obtain(); + try { + r1.writeToParcel(p1, 0); + byte[] bytes = p1.marshall(); + p2.unmarshall(bytes, 0, bytes.length); + p2.setDataPosition(0); + SeriesRecording r2 = SeriesRecording.fromParcel(p2); + assertEquals(r1, r2); + } finally { + p1.recycle(); + p2.recycle(); + } + } + + @Test + public void testDoesProgramMatch_simpleMatch() { + assertDoesProgramMatch(mBaseProgram, mBaseSeriesRecording, true); + } + + @Test + public void testDoesProgramMatch_differentSeriesId() { + Program program = new Program.Builder(mBaseProgram).setSeriesId(OTHER_SERIES_ID).build(); + assertDoesProgramMatch(program, mBaseSeriesRecording, false); + } + + @Test + public void testDoesProgramMatch_differentChannel() { + Program program = new Program.Builder(mBaseProgram).setChannelId(OTHER_CHANNEL_ID).build(); + assertDoesProgramMatch(program, mBaseSeriesRecording, false); + } + + @Test + public void testDoesProgramMatch_startFromSeason2() { + Program program = mBaseProgram; + assertDoesProgramMatch(program, mSeriesRecordingSeason2, true); + program = new Program.Builder(program).setSeasonNumber("1").build(); + assertDoesProgramMatch(program, mSeriesRecordingSeason2, false); + program = new Program.Builder(program).setSeasonNumber("2").build(); + assertDoesProgramMatch(program, mSeriesRecordingSeason2, true); + program = new Program.Builder(program).setSeasonNumber("3").build(); + assertDoesProgramMatch(program, mSeriesRecordingSeason2, true); + } + + @Test + public void testDoesProgramMatch_startFromSeason2episode5() { + Program program = mBaseProgram; + assertDoesProgramMatch(program, mSeriesRecordingSeason2Episode5, true); + program = new Program.Builder(program).setSeasonNumber("2").build(); + assertDoesProgramMatch(program, mSeriesRecordingSeason2Episode5, true); + program = new Program.Builder(program).setEpisodeNumber("4").build(); + assertDoesProgramMatch(program, mSeriesRecordingSeason2Episode5, false); + program = new Program.Builder(program).setEpisodeNumber("5").build(); + assertDoesProgramMatch(program, mSeriesRecordingSeason2Episode5, true); + program = new Program.Builder(program).setEpisodeNumber("6").build(); + assertDoesProgramMatch(program, mSeriesRecordingSeason2Episode5, true); + program = new Program.Builder(program).setSeasonNumber("3").setEpisodeNumber("1").build(); + assertDoesProgramMatch(program, mSeriesRecordingSeason2Episode5, true); + } + + private void assertDoesProgramMatch( + Program p, SeriesRecording seriesRecording, boolean expected) { + assertEquals( + seriesRecording + " doesProgramMatch " + p, + expected, + seriesRecording.matchProgram(p)); + } +} diff --git a/tests/unit/src/com/android/tv/dvr/provider/DvrDbSyncTest.java b/tests/unit/src/com/android/tv/dvr/provider/DvrDbSyncTest.java new file mode 100644 index 00000000..10a882f6 --- /dev/null +++ b/tests/unit/src/com/android/tv/dvr/provider/DvrDbSyncTest.java @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2016 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.tv.dvr.provider; + +import static android.support.test.InstrumentationRegistry.getContext; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyObject; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.os.Build; +import android.support.test.filters.SdkSuppress; +import android.support.test.filters.SmallTest; +import com.android.tv.data.ChannelDataManager; +import com.android.tv.data.Program; +import com.android.tv.dvr.DvrDataManagerImpl; +import com.android.tv.dvr.DvrManager; +import com.android.tv.dvr.data.ScheduledRecording; +import com.android.tv.dvr.data.SeriesRecording; +import com.android.tv.dvr.recorder.SeriesRecordingScheduler; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** Tests for {@link com.android.tv.dvr.DvrScheduleManager} */ +@SmallTest +@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N) +public class DvrDbSyncTest { + private static final String INPUT_ID = "input_id"; + private static final long BASE_PROGRAM_ID = 1; + private static final long BASE_START_TIME_MS = 0; + private static final long BASE_END_TIME_MS = 1; + private static final String BASE_SEASON_NUMBER = "2"; + private static final String BASE_EPISODE_NUMBER = "3"; + private static final Program BASE_PROGRAM = + new Program.Builder() + .setId(BASE_PROGRAM_ID) + .setStartTimeUtcMillis(BASE_START_TIME_MS) + .setEndTimeUtcMillis(BASE_END_TIME_MS) + .build(); + private static final Program BASE_SERIES_PROGRAM = + new Program.Builder() + .setId(BASE_PROGRAM_ID) + .setStartTimeUtcMillis(BASE_START_TIME_MS) + .setEndTimeUtcMillis(BASE_END_TIME_MS) + .setSeasonNumber(BASE_SEASON_NUMBER) + .setEpisodeNumber(BASE_EPISODE_NUMBER) + .build(); + private static final ScheduledRecording BASE_SCHEDULE = + ScheduledRecording.builder(INPUT_ID, BASE_PROGRAM).build(); + private static final ScheduledRecording BASE_SERIES_SCHEDULE = + ScheduledRecording.builder(INPUT_ID, BASE_SERIES_PROGRAM).build(); + + private DvrDbSync mDbSync; + @Mock private DvrManager mDvrManager; + @Mock private DvrDataManagerImpl mDataManager; + @Mock private ChannelDataManager mChannelDataManager; + @Mock private SeriesRecordingScheduler mSeriesRecordingScheduler; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + when(mChannelDataManager.isDbLoadFinished()).thenReturn(true); + when(mDvrManager.addSeriesRecording(anyObject(), anyObject(), anyInt())) + .thenReturn(SeriesRecording.builder(INPUT_ID, BASE_PROGRAM).build()); + mDbSync = + new DvrDbSync( + getContext(), + mDataManager, + mChannelDataManager, + mDvrManager, + mSeriesRecordingScheduler); + } + + @Test + public void testHandleUpdateProgram_null() { + addSchedule(BASE_PROGRAM_ID, BASE_SCHEDULE); + mDbSync.handleUpdateProgram(null, BASE_PROGRAM_ID); + verify(mDataManager).removeScheduledRecording(BASE_SCHEDULE); + } + + @Test + public void testHandleUpdateProgram_changeTimeNotStarted() { + addSchedule(BASE_PROGRAM_ID, BASE_SCHEDULE); + long startTimeMs = BASE_START_TIME_MS + 1; + long endTimeMs = BASE_END_TIME_MS + 1; + Program program = + new Program.Builder(BASE_PROGRAM) + .setStartTimeUtcMillis(startTimeMs) + .setEndTimeUtcMillis(endTimeMs) + .build(); + mDbSync.handleUpdateProgram(program, BASE_PROGRAM_ID); + assertUpdateScheduleCalled(program); + } + + @Test + public void testHandleUpdateProgram_changeTimeInProgressNotCalled() { + addSchedule( + BASE_PROGRAM_ID, + ScheduledRecording.buildFrom(BASE_SCHEDULE) + .setState(ScheduledRecording.STATE_RECORDING_IN_PROGRESS) + .build()); + long startTimeMs = BASE_START_TIME_MS + 1; + Program program = + new Program.Builder(BASE_PROGRAM).setStartTimeUtcMillis(startTimeMs).build(); + mDbSync.handleUpdateProgram(program, BASE_PROGRAM_ID); + verify(mDataManager, never()).updateScheduledRecording(anyObject()); + } + + @Test + public void testHandleUpdateProgram_changeSeason() { + addSchedule(BASE_PROGRAM_ID, BASE_SERIES_SCHEDULE); + String seasonNumber = BASE_SEASON_NUMBER + "1"; + String episodeNumber = BASE_EPISODE_NUMBER + "1"; + Program program = + new Program.Builder(BASE_SERIES_PROGRAM) + .setSeasonNumber(seasonNumber) + .setEpisodeNumber(episodeNumber) + .build(); + mDbSync.handleUpdateProgram(program, BASE_PROGRAM_ID); + assertUpdateScheduleCalled(program); + } + + @Test + public void testHandleUpdateProgram_finished() { + addSchedule( + BASE_PROGRAM_ID, + ScheduledRecording.buildFrom(BASE_SERIES_SCHEDULE) + .setState(ScheduledRecording.STATE_RECORDING_FINISHED) + .build()); + String seasonNumber = BASE_SEASON_NUMBER + "1"; + String episodeNumber = BASE_EPISODE_NUMBER + "1"; + Program program = + new Program.Builder(BASE_SERIES_PROGRAM) + .setSeasonNumber(seasonNumber) + .setEpisodeNumber(episodeNumber) + .build(); + mDbSync.handleUpdateProgram(program, BASE_PROGRAM_ID); + verify(mDataManager, never()).updateScheduledRecording(anyObject()); + } + + private void addSchedule(long programId, ScheduledRecording schedule) { + when(mDataManager.getScheduledRecordingForProgramId(programId)).thenReturn(schedule); + } + + private void assertUpdateScheduleCalled(Program program) { + verify(mDataManager) + .updateScheduledRecording( + eq(ScheduledRecording.builder(INPUT_ID, program).build())); + } +} diff --git a/tests/unit/src/com/android/tv/dvr/provider/EpisodicProgramLoadTaskTest.java b/tests/unit/src/com/android/tv/dvr/provider/EpisodicProgramLoadTaskTest.java new file mode 100644 index 00000000..a586fd9e --- /dev/null +++ b/tests/unit/src/com/android/tv/dvr/provider/EpisodicProgramLoadTaskTest.java @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2016 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.tv.dvr.provider; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import android.os.Build; +import android.support.test.filters.SdkSuppress; +import android.support.test.filters.SmallTest; +import com.android.tv.dvr.data.SeasonEpisodeNumber; +import java.util.ArrayList; +import java.util.List; +import org.junit.Test; + +/** Tests for {@link EpisodicProgramLoadTask} */ +@SmallTest +@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N) +public class EpisodicProgramLoadTaskTest { + private static final long SERIES_RECORDING_ID1 = 1; + private static final long SERIES_RECORDING_ID2 = 2; + private static final String SEASON_NUMBER1 = "SEASON NUMBER1"; + private static final String SEASON_NUMBER2 = "SEASON NUMBER2"; + private static final String EPISODE_NUMBER1 = "EPISODE NUMBER1"; + private static final String EPISODE_NUMBER2 = "EPISODE NUMBER2"; + + @Test + public void testEpisodeAlreadyScheduled_true() { + List<SeasonEpisodeNumber> seasonEpisodeNumbers = new ArrayList<>(); + SeasonEpisodeNumber seasonEpisodeNumber = + new SeasonEpisodeNumber(SERIES_RECORDING_ID1, SEASON_NUMBER1, EPISODE_NUMBER1); + seasonEpisodeNumbers.add(seasonEpisodeNumber); + assertTrue( + seasonEpisodeNumbers.contains( + new SeasonEpisodeNumber( + SERIES_RECORDING_ID1, SEASON_NUMBER1, EPISODE_NUMBER1))); + } + + @Test + public void testEpisodeAlreadyScheduled_false() { + List<SeasonEpisodeNumber> seasonEpisodeNumbers = new ArrayList<>(); + SeasonEpisodeNumber seasonEpisodeNumber = + new SeasonEpisodeNumber(SERIES_RECORDING_ID1, SEASON_NUMBER1, EPISODE_NUMBER1); + seasonEpisodeNumbers.add(seasonEpisodeNumber); + assertFalse( + seasonEpisodeNumbers.contains( + new SeasonEpisodeNumber( + SERIES_RECORDING_ID2, SEASON_NUMBER1, EPISODE_NUMBER1))); + assertFalse( + seasonEpisodeNumbers.contains( + new SeasonEpisodeNumber( + SERIES_RECORDING_ID1, SEASON_NUMBER2, EPISODE_NUMBER1))); + assertFalse( + seasonEpisodeNumbers.contains( + new SeasonEpisodeNumber( + SERIES_RECORDING_ID1, SEASON_NUMBER1, EPISODE_NUMBER2))); + } + + @Test + public void testEpisodeAlreadyScheduled_null() { + List<SeasonEpisodeNumber> seasonEpisodeNumbers = new ArrayList<>(); + SeasonEpisodeNumber seasonEpisodeNumber = + new SeasonEpisodeNumber(SERIES_RECORDING_ID1, SEASON_NUMBER1, EPISODE_NUMBER1); + seasonEpisodeNumbers.add(seasonEpisodeNumber); + assertFalse( + seasonEpisodeNumbers.contains( + new SeasonEpisodeNumber(SERIES_RECORDING_ID1, null, EPISODE_NUMBER1))); + assertFalse( + seasonEpisodeNumbers.contains( + new SeasonEpisodeNumber(SERIES_RECORDING_ID1, SEASON_NUMBER1, null))); + assertFalse( + seasonEpisodeNumbers.contains( + new SeasonEpisodeNumber(SERIES_RECORDING_ID1, null, null))); + } +} diff --git a/tests/unit/src/com/android/tv/dvr/recorder/InputTaskSchedulerTest.java b/tests/unit/src/com/android/tv/dvr/recorder/InputTaskSchedulerTest.java new file mode 100644 index 00000000..f4e6cdf9 --- /dev/null +++ b/tests/unit/src/com/android/tv/dvr/recorder/InputTaskSchedulerTest.java @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2016 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.tv.dvr.recorder; + +import static android.support.test.InstrumentationRegistry.getContext; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyLong; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.timeout; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.app.AlarmManager; +import android.media.tv.TvInputInfo; +import android.os.Build; +import android.os.Looper; +import android.os.SystemClock; +import android.support.test.filters.SdkSuppress; +import android.support.test.filters.SmallTest; +import com.android.tv.InputSessionManager; +import com.android.tv.data.Channel; +import com.android.tv.data.ChannelDataManager; +import com.android.tv.dvr.DvrManager; +import com.android.tv.dvr.WritableDvrDataManager; +import com.android.tv.dvr.data.ScheduledRecording; +import com.android.tv.dvr.recorder.InputTaskScheduler.RecordingTaskFactory; +import com.android.tv.testing.FakeClock; +import com.android.tv.testing.dvr.RecordingTestUtils; +import com.android.tv.util.Clock; +import com.android.tv.util.TestUtils; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** Tests for {@link InputTaskScheduler}. */ +@SmallTest +@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N) +public class InputTaskSchedulerTest { + private static final String INPUT_ID = "input_id"; + private static final int CHANNEL_ID = 1; + private static final long LISTENER_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(1); + private static final int TUNER_COUNT_ONE = 1; + private static final int TUNER_COUNT_TWO = 2; + private static final long LOW_PRIORITY = 1; + private static final long HIGH_PRIORITY = 2; + + private FakeClock mFakeClock; + private InputTaskScheduler mScheduler; + @Mock private DvrManager mDvrManager; + @Mock private WritableDvrDataManager mDataManager; + @Mock private InputSessionManager mSessionManager; + @Mock private AlarmManager mMockAlarmManager; + @Mock private ChannelDataManager mChannelDataManager; + private List<RecordingTask> mRecordingTasks; + + @Before + public void setUp() throws Exception { + if (Looper.myLooper() == null) { + Looper.prepare(); + } + mRecordingTasks = new ArrayList(); + MockitoAnnotations.initMocks(this); + mFakeClock = FakeClock.createWithCurrentTime(); + TvInputInfo input = createTvInputInfo(TUNER_COUNT_ONE); + mScheduler = + new InputTaskScheduler( + getContext(), + input, + Looper.myLooper(), + mChannelDataManager, + mDvrManager, + mDataManager, + mSessionManager, + mFakeClock, + new RecordingTaskFactory() { + @Override + public RecordingTask createRecordingTask( + ScheduledRecording scheduledRecording, + Channel channel, + DvrManager dvrManager, + InputSessionManager sessionManager, + WritableDvrDataManager dataManager, + Clock clock) { + RecordingTask task = mock(RecordingTask.class); + when(task.getPriority()) + .thenReturn(scheduledRecording.getPriority()); + when(task.getEndTimeMs()) + .thenReturn(scheduledRecording.getEndTimeMs()); + mRecordingTasks.add(task); + return task; + } + }); + } + + @Test + public void testAddSchedule_past() { + ScheduledRecording r = + RecordingTestUtils.createTestRecordingWithPeriod(INPUT_ID, CHANNEL_ID, 0L, 1L); + when(mDataManager.getScheduledRecording(anyLong())).thenReturn(r); + mScheduler.handleAddSchedule(r); + mScheduler.handleBuildSchedule(); + verify(mDataManager, timeout((int) LISTENER_TIMEOUT_MS).times(1)) + .changeState( + any(ScheduledRecording.class), + eq(ScheduledRecording.STATE_RECORDING_FAILED)); + } + + @Test + public void testAddSchedule_start() { + mScheduler.handleAddSchedule( + RecordingTestUtils.createTestRecordingWithPeriod( + INPUT_ID, + CHANNEL_ID, + mFakeClock.currentTimeMillis(), + mFakeClock.currentTimeMillis() + TimeUnit.HOURS.toMillis(1))); + mScheduler.handleBuildSchedule(); + verify(mRecordingTasks.get(0), timeout((int) LISTENER_TIMEOUT_MS).times(1)).start(); + } + + @Test + public void testAddSchedule_consecutiveNoStop() { + long startTimeMs = mFakeClock.currentTimeMillis(); + long endTimeMs = startTimeMs + TimeUnit.SECONDS.toMillis(1); + long id = 0; + mScheduler.handleAddSchedule( + RecordingTestUtils.createTestRecordingWithIdAndPriorityAndPeriod( + ++id, CHANNEL_ID, LOW_PRIORITY, startTimeMs, endTimeMs)); + mScheduler.handleBuildSchedule(); + startTimeMs = endTimeMs; + endTimeMs = startTimeMs + TimeUnit.SECONDS.toMillis(1); + mScheduler.handleAddSchedule( + RecordingTestUtils.createTestRecordingWithIdAndPriorityAndPeriod( + ++id, CHANNEL_ID, HIGH_PRIORITY, startTimeMs, endTimeMs)); + mScheduler.handleBuildSchedule(); + verify(mRecordingTasks.get(0), timeout((int) LISTENER_TIMEOUT_MS).times(1)).start(); + // The first schedule should not be stopped because the second one should wait for the end + // of the first schedule. + SystemClock.sleep(LISTENER_TIMEOUT_MS); + verify(mRecordingTasks.get(0), never()).stop(); + } + + @Test + public void testAddSchedule_consecutiveNoFail() { + long startTimeMs = mFakeClock.currentTimeMillis(); + long endTimeMs = startTimeMs + TimeUnit.SECONDS.toMillis(1); + long id = 0; + when(mDataManager.getScheduledRecording(anyLong())) + .thenReturn(ScheduledRecording.builder(INPUT_ID, CHANNEL_ID, 0L, 0L).build()); + mScheduler.handleAddSchedule( + RecordingTestUtils.createTestRecordingWithIdAndPriorityAndPeriod( + ++id, CHANNEL_ID, HIGH_PRIORITY, startTimeMs, endTimeMs)); + mScheduler.handleBuildSchedule(); + startTimeMs = endTimeMs; + endTimeMs = startTimeMs + TimeUnit.SECONDS.toMillis(1); + mScheduler.handleAddSchedule( + RecordingTestUtils.createTestRecordingWithIdAndPriorityAndPeriod( + ++id, CHANNEL_ID, LOW_PRIORITY, startTimeMs, endTimeMs)); + mScheduler.handleBuildSchedule(); + verify(mRecordingTasks.get(0), timeout((int) LISTENER_TIMEOUT_MS).times(1)).start(); + SystemClock.sleep(LISTENER_TIMEOUT_MS); + verify(mRecordingTasks.get(0), never()).stop(); + // The second schedule should not fail because it can starts after the first one finishes. + SystemClock.sleep(LISTENER_TIMEOUT_MS); + verify(mDataManager, never()) + .changeState( + any(ScheduledRecording.class), + eq(ScheduledRecording.STATE_RECORDING_FAILED)); + } + + @Test + public void testAddSchedule_consecutiveUseLessSession() throws Exception { + TvInputInfo input = createTvInputInfo(TUNER_COUNT_TWO); + mScheduler.updateTvInputInfo(input); + long startTimeMs = mFakeClock.currentTimeMillis(); + long endTimeMs = startTimeMs + TimeUnit.SECONDS.toMillis(1); + long id = 0; + mScheduler.handleAddSchedule( + RecordingTestUtils.createTestRecordingWithIdAndPriorityAndPeriod( + ++id, CHANNEL_ID, LOW_PRIORITY, startTimeMs, endTimeMs)); + mScheduler.handleBuildSchedule(); + startTimeMs = endTimeMs; + endTimeMs = startTimeMs + TimeUnit.SECONDS.toMillis(1); + mScheduler.handleAddSchedule( + RecordingTestUtils.createTestRecordingWithIdAndPriorityAndPeriod( + ++id, CHANNEL_ID, HIGH_PRIORITY, startTimeMs, endTimeMs)); + mScheduler.handleBuildSchedule(); + verify(mRecordingTasks.get(0), timeout((int) LISTENER_TIMEOUT_MS).times(1)).start(); + SystemClock.sleep(LISTENER_TIMEOUT_MS); + verify(mRecordingTasks.get(0), never()).stop(); + // The second schedule should wait until the first one finishes rather than creating a new + // session even though there are available tuners. + assertTrue(mRecordingTasks.size() == 1); + } + + @Test + public void testUpdateSchedule_noCancel() { + ScheduledRecording r = + RecordingTestUtils.createTestRecordingWithPeriod( + INPUT_ID, + CHANNEL_ID, + mFakeClock.currentTimeMillis(), + mFakeClock.currentTimeMillis() + TimeUnit.HOURS.toMillis(1)); + mScheduler.handleAddSchedule(r); + mScheduler.handleBuildSchedule(); + mScheduler.handleUpdateSchedule(r); + SystemClock.sleep(LISTENER_TIMEOUT_MS); + verify(mRecordingTasks.get(0), never()).cancel(); + } + + @Test + public void testUpdateSchedule_cancel() { + ScheduledRecording r = + RecordingTestUtils.createTestRecordingWithPeriod( + INPUT_ID, + CHANNEL_ID, + mFakeClock.currentTimeMillis(), + mFakeClock.currentTimeMillis() + TimeUnit.HOURS.toMillis(2)); + mScheduler.handleAddSchedule(r); + mScheduler.handleBuildSchedule(); + mScheduler.handleUpdateSchedule( + ScheduledRecording.buildFrom(r) + .setStartTimeMs(mFakeClock.currentTimeMillis() + TimeUnit.HOURS.toMillis(1)) + .build()); + verify(mRecordingTasks.get(0), timeout((int) LISTENER_TIMEOUT_MS).times(1)).cancel(); + } + + private TvInputInfo createTvInputInfo(int tunerCount) throws Exception { + return TestUtils.createTvInputInfo(null, null, null, 0, false, true, tunerCount); + } +} diff --git a/tests/unit/src/com/android/tv/dvr/recorder/RecordingTaskTest.java b/tests/unit/src/com/android/tv/dvr/recorder/RecordingTaskTest.java new file mode 100644 index 00000000..03a4fe50 --- /dev/null +++ b/tests/unit/src/com/android/tv/dvr/recorder/RecordingTaskTest.java @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2015 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.tv.dvr.recorder; + +import static android.support.test.InstrumentationRegistry.getContext; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.anyLong; +import static org.mockito.Matchers.anyObject; +import static org.mockito.Matchers.anyString; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.when; + +import android.os.Build; +import android.os.Handler; +import android.os.Looper; +import android.os.Message; +import android.support.test.filters.SdkSuppress; +import android.support.test.filters.SmallTest; +import com.android.tv.InputSessionManager; +import com.android.tv.InputSessionManager.RecordingSession; +import com.android.tv.common.feature.CommonFeatures; +import com.android.tv.common.feature.TestableFeature; +import com.android.tv.data.Channel; +import com.android.tv.dvr.DvrDataManagerInMemoryImpl; +import com.android.tv.dvr.DvrManager; +import com.android.tv.dvr.data.ScheduledRecording; +import com.android.tv.dvr.recorder.RecordingTask.State; +import com.android.tv.testing.FakeClock; +import com.android.tv.testing.dvr.RecordingTestUtils; +import java.util.concurrent.TimeUnit; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** Tests for {@link RecordingTask}. */ +@SmallTest +@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N) +public class RecordingTaskTest { + private static final long DURATION = TimeUnit.MINUTES.toMillis(30); + private static final long START_OFFSET_MS = RecordingScheduler.MS_TO_WAKE_BEFORE_START; + private static final String INPUT_ID = "input_id"; + private static final int CHANNEL_ID = 273; + + private FakeClock mFakeClock; + private DvrDataManagerInMemoryImpl mDataManager; + @Mock Handler mMockHandler; + @Mock DvrManager mDvrManager; + @Mock InputSessionManager mMockSessionManager; + @Mock RecordingSession mMockRecordingSession; + private final TestableFeature mDvrFeature = CommonFeatures.DVR; + + @Before + public void setUp() { + mDvrFeature.enableForTest(); + if (Looper.myLooper() == null) { + Looper.prepare(); + } + MockitoAnnotations.initMocks(this); + mFakeClock = FakeClock.createWithCurrentTime(); + mDataManager = new DvrDataManagerInMemoryImpl(getContext(), mFakeClock); + } + + @After + public void tearDown() { + mDvrFeature.resetForTests(); + } + + @Test + public void testHandle_init() { + Channel channel = createTestChannel(); + ScheduledRecording r = createRecording(channel); + RecordingTask task = createRecordingTask(r, channel); + String inputId = channel.getInputId(); + when(mMockSessionManager.createRecordingSession( + eq(inputId), anyString(), eq(task), eq(mMockHandler), anyLong())) + .thenReturn(mMockRecordingSession); + when(mMockHandler.sendMessageAtTime(anyObject(), anyLong())).thenReturn(true); + assertTrue(task.handleMessage(createMessage(RecordingTask.MSG_INITIALIZE))); + assertEquals(State.CONNECTION_PENDING, task.getState()); + verify(mMockSessionManager) + .createRecordingSession( + eq(inputId), anyString(), eq(task), eq(mMockHandler), anyLong()); + verify(mMockRecordingSession).tune(eq(inputId), eq(channel.getUri())); + verifyNoMoreInteractions(mMockHandler, mMockRecordingSession, mMockSessionManager); + } + + private static Channel createTestChannel() { + return new Channel.Builder() + .setInputId(INPUT_ID) + .setId(CHANNEL_ID) + .setDisplayName("Test Ch " + CHANNEL_ID) + .build(); + } + + @Test + public void testOnConnected() { + Channel channel = createTestChannel(); + ScheduledRecording r = createRecording(channel); + mDataManager.addScheduledRecording(r); + RecordingTask task = createRecordingTask(r, channel); + String inputId = channel.getInputId(); + when(mMockSessionManager.createRecordingSession( + eq(inputId), anyString(), eq(task), eq(mMockHandler), anyLong())) + .thenReturn(mMockRecordingSession); + when(mMockHandler.sendMessageAtTime(anyObject(), anyLong())).thenReturn(true); + task.handleMessage(createMessage(RecordingTask.MSG_INITIALIZE)); + task.onTuned(channel.getUri()); + assertEquals(State.CONNECTED, task.getState()); + } + + private ScheduledRecording createRecording(Channel c) { + long startTime = mFakeClock.currentTimeMillis() + START_OFFSET_MS; + long endTime = startTime + DURATION; + return RecordingTestUtils.createTestRecordingWithPeriod( + c.getInputId(), c.getId(), startTime, endTime); + } + + private RecordingTask createRecordingTask(ScheduledRecording r, Channel channel) { + RecordingTask recordingTask = + new RecordingTask( + getContext(), + r, + channel, + mDvrManager, + mMockSessionManager, + mDataManager, + mFakeClock); + recordingTask.setHandler(mMockHandler); + return recordingTask; + } + + private Message createMessage(int what) { + Message msg = new Message(); + msg.setTarget(mMockHandler); + msg.what = what; + return msg; + } +} diff --git a/tests/unit/src/com/android/tv/dvr/recorder/ScheduledProgramReaperTest.java b/tests/unit/src/com/android/tv/dvr/recorder/ScheduledProgramReaperTest.java new file mode 100644 index 00000000..dc47fc86 --- /dev/null +++ b/tests/unit/src/com/android/tv/dvr/recorder/ScheduledProgramReaperTest.java @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2016 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.tv.dvr.recorder; + +import static android.support.test.InstrumentationRegistry.getContext; +import static org.junit.Assert.assertTrue; + +import android.os.Build; +import android.support.test.filters.SdkSuppress; +import android.support.test.filters.SmallTest; +import android.test.MoreAsserts; +import com.android.tv.common.feature.CommonFeatures; +import com.android.tv.common.feature.TestableFeature; +import com.android.tv.dvr.DvrDataManagerInMemoryImpl; +import com.android.tv.dvr.DvrManager; +import com.android.tv.dvr.data.ScheduledRecording; +import com.android.tv.testing.FakeClock; +import com.android.tv.testing.dvr.RecordingTestUtils; +import java.util.concurrent.TimeUnit; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** Tests for {@link ScheduledProgramReaper}. */ +@SmallTest +@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N) +public class ScheduledProgramReaperTest { + private static final String INPUT_ID = "input_id"; + private static final int CHANNEL_ID = 273; + private static final long DURATION = TimeUnit.HOURS.toMillis(1); + + private ScheduledProgramReaper mReaper; + private FakeClock mFakeClock; + private DvrDataManagerInMemoryImpl mDvrDataManager; + @Mock private DvrManager mDvrManager; + private final TestableFeature mDvrFeature = CommonFeatures.DVR; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mDvrFeature.enableForTest(); + mFakeClock = FakeClock.createWithTimeOne(); + mDvrDataManager = new DvrDataManagerInMemoryImpl(getContext(), mFakeClock); + mReaper = new ScheduledProgramReaper(mDvrDataManager, mFakeClock); + } + + @After + public void tearDown() { + mDvrFeature.resetForTests(); + } + + @Test + public void testRun_noRecordings() { + assertTrue(mDvrDataManager.getAllScheduledRecordings().isEmpty()); + mReaper.run(); + assertTrue(mDvrDataManager.getAllScheduledRecordings().isEmpty()); + } + + @Test + public void testRun_oneRecordingsTomorrow() { + ScheduledRecording recording = addNewScheduledRecordingForTomorrow(); + MoreAsserts.assertContentsInAnyOrder( + mDvrDataManager.getAllScheduledRecordings(), recording); + mReaper.run(); + MoreAsserts.assertContentsInAnyOrder( + mDvrDataManager.getAllScheduledRecordings(), recording); + } + + @Test + public void testRun_oneRecordingsStarted() { + ScheduledRecording recording = addNewScheduledRecordingForTomorrow(); + MoreAsserts.assertContentsInAnyOrder( + mDvrDataManager.getAllScheduledRecordings(), recording); + mFakeClock.increment(TimeUnit.DAYS); + mReaper.run(); + MoreAsserts.assertContentsInAnyOrder( + mDvrDataManager.getAllScheduledRecordings(), recording); + } + + @Test + public void testRun_oneRecordingsFinished() { + ScheduledRecording recording = addNewScheduledRecordingForTomorrow(); + MoreAsserts.assertContentsInAnyOrder( + mDvrDataManager.getAllScheduledRecordings(), recording); + mFakeClock.increment(TimeUnit.DAYS); + mFakeClock.increment(TimeUnit.MINUTES, 2); + mReaper.run(); + MoreAsserts.assertContentsInAnyOrder( + mDvrDataManager.getAllScheduledRecordings(), recording); + } + + @Test + public void testRun_oneRecordingsExpired() { + ScheduledRecording recording = addNewScheduledRecordingForTomorrow(); + MoreAsserts.assertContentsInAnyOrder( + mDvrDataManager.getAllScheduledRecordings(), recording); + mFakeClock.increment(TimeUnit.DAYS, 1 + ScheduledProgramReaper.DAYS); + mFakeClock.increment(TimeUnit.MILLISECONDS, DURATION); + // After the cutoff and enough so we can see on the clock + mFakeClock.increment(TimeUnit.SECONDS, 1); + + mReaper.run(); + assertTrue( + "Recordings after reaper at " + + com.android.tv.util.Utils.toIsoDateTimeString( + mFakeClock.currentTimeMillis()), + mDvrDataManager.getAllScheduledRecordings().isEmpty()); + } + + private ScheduledRecording addNewScheduledRecordingForTomorrow() { + long startTime = mFakeClock.currentTimeMillis() + TimeUnit.DAYS.toMillis(1); + ScheduledRecording recording = + RecordingTestUtils.createTestRecordingWithPeriod( + INPUT_ID, CHANNEL_ID, startTime, startTime + DURATION); + return mDvrDataManager.addScheduledRecordingInternal( + ScheduledRecording.buildFrom(recording) + .setState(ScheduledRecording.STATE_RECORDING_FINISHED) + .build()); + } +} diff --git a/tests/unit/src/com/android/tv/dvr/recorder/SchedulerTest.java b/tests/unit/src/com/android/tv/dvr/recorder/SchedulerTest.java new file mode 100644 index 00000000..008e43f1 --- /dev/null +++ b/tests/unit/src/com/android/tv/dvr/recorder/SchedulerTest.java @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2015 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.tv.dvr.recorder; + +import static android.support.test.InstrumentationRegistry.getTargetContext; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyZeroInteractions; + +import android.app.AlarmManager; +import android.app.PendingIntent; +import android.os.Build; +import android.os.Looper; +import android.support.test.filters.SdkSuppress; +import android.support.test.filters.SmallTest; +import com.android.tv.InputSessionManager; +import com.android.tv.common.feature.CommonFeatures; +import com.android.tv.common.feature.TestableFeature; +import com.android.tv.data.ChannelDataManager; +import com.android.tv.dvr.DvrDataManagerInMemoryImpl; +import com.android.tv.dvr.DvrManager; +import com.android.tv.dvr.data.ScheduledRecording; +import com.android.tv.testing.FakeClock; +import com.android.tv.testing.dvr.RecordingTestUtils; +import com.android.tv.util.TvInputManagerHelper; +import java.util.concurrent.TimeUnit; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; + +/** Tests for {@link RecordingScheduler}. */ +@SmallTest +@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N) +public class SchedulerTest { + private static final String INPUT_ID = "input_id"; + private static final int CHANNEL_ID = 273; + + private FakeClock mFakeClock; + private DvrDataManagerInMemoryImpl mDataManager; + private RecordingScheduler mScheduler; + @Mock DvrManager mDvrManager; + @Mock InputSessionManager mSessionManager; + @Mock AlarmManager mMockAlarmManager; + @Mock ChannelDataManager mChannelDataManager; + @Mock TvInputManagerHelper mInputManager; + private final TestableFeature mDvrFeature = CommonFeatures.DVR; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mDvrFeature.enableForTest(); + mFakeClock = FakeClock.createWithCurrentTime(); + mDataManager = new DvrDataManagerInMemoryImpl(getTargetContext(), mFakeClock); + Mockito.when(mChannelDataManager.isDbLoadFinished()).thenReturn(true); + mScheduler = + new RecordingScheduler( + Looper.myLooper(), + mDvrManager, + mSessionManager, + mDataManager, + mChannelDataManager, + mInputManager, + getTargetContext(), + mFakeClock, + mMockAlarmManager); + } + + @After + public void tearDown() { + mDvrFeature.resetForTests(); + } + + @Test + public void testUpdate_none() { + mScheduler.updateAndStartServiceIfNeeded(); + verifyZeroInteractions(mMockAlarmManager); + } + + @Test + public void testUpdate_nextIn12Hours() { + long now = mFakeClock.currentTimeMillis(); + long startTime = now + TimeUnit.HOURS.toMillis(12); + ScheduledRecording r = + RecordingTestUtils.createTestRecordingWithPeriod( + INPUT_ID, CHANNEL_ID, startTime, startTime + TimeUnit.HOURS.toMillis(1)); + mDataManager.addScheduledRecording(r); + verify(mMockAlarmManager) + .setExactAndAllowWhileIdle( + eq(AlarmManager.RTC_WAKEUP), + eq(startTime - RecordingScheduler.MS_TO_WAKE_BEFORE_START), + any(PendingIntent.class)); + Mockito.reset(mMockAlarmManager); + mScheduler.updateAndStartServiceIfNeeded(); + verify(mMockAlarmManager) + .setExactAndAllowWhileIdle( + eq(AlarmManager.RTC_WAKEUP), + eq(startTime - RecordingScheduler.MS_TO_WAKE_BEFORE_START), + any(PendingIntent.class)); + } + + @Test + public void testStartsWithin() { + long now = mFakeClock.currentTimeMillis(); + long startTime = now + 3; + ScheduledRecording r = + RecordingTestUtils.createTestRecordingWithPeriod( + INPUT_ID, CHANNEL_ID, startTime, startTime + 100); + assertFalse(mScheduler.startsWithin(r, 2)); + assertTrue(mScheduler.startsWithin(r, 3)); + } +} diff --git a/tests/unit/src/com/android/tv/dvr/recorder/SeriesRecordingSchedulerTest.java b/tests/unit/src/com/android/tv/dvr/recorder/SeriesRecordingSchedulerTest.java new file mode 100644 index 00000000..c7cbff55 --- /dev/null +++ b/tests/unit/src/com/android/tv/dvr/recorder/SeriesRecordingSchedulerTest.java @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2016 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.tv.dvr.recorder; + +import static android.support.test.InstrumentationRegistry.getContext; + +import android.os.Build; +import android.support.test.filters.SdkSuppress; +import android.support.test.filters.SmallTest; +import android.test.MoreAsserts; +import android.util.LongSparseArray; +import com.android.tv.common.feature.CommonFeatures; +import com.android.tv.common.feature.TestableFeature; +import com.android.tv.data.Program; +import com.android.tv.dvr.DvrDataManagerInMemoryImpl; +import com.android.tv.dvr.data.SeriesRecording; +import com.android.tv.testing.FakeClock; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** Tests for {@link SeriesRecordingScheduler} */ +@SmallTest +@SdkSuppress(minSdkVersion = Build.VERSION_CODES.N) +public class SeriesRecordingSchedulerTest { + private static final String PROGRAM_TITLE = "MyProgram"; + private static final long CHANNEL_ID = 123; + private static final long SERIES_RECORDING_ID1 = 1; + private static final String SERIES_ID = "SERIES_ID"; + private static final String SEASON_NUMBER1 = "SEASON NUMBER1"; + private static final String SEASON_NUMBER2 = "SEASON NUMBER2"; + private static final String EPISODE_NUMBER1 = "EPISODE NUMBER1"; + private static final String EPISODE_NUMBER2 = "EPISODE NUMBER2"; + + private final SeriesRecording mBaseSeriesRecording = + new SeriesRecording.Builder() + .setTitle(PROGRAM_TITLE) + .setChannelId(CHANNEL_ID) + .setSeriesId(SERIES_ID) + .build(); + private final Program mBaseProgram = + new Program.Builder() + .setTitle(PROGRAM_TITLE) + .setChannelId(CHANNEL_ID) + .setSeriesId(SERIES_ID) + .build(); + private final TestableFeature mDvrFeature = CommonFeatures.DVR; + + private DvrDataManagerInMemoryImpl mDataManager; + + @Before + public void setUp() { + mDvrFeature.enableForTest(); + FakeClock fakeClock = FakeClock.createWithCurrentTime(); + mDataManager = new DvrDataManagerInMemoryImpl(getContext(), fakeClock); + } + + @After + public void tearDown() { + mDvrFeature.resetForTests(); + } + + @Test + public void testPickOneProgramPerEpisode_onePerEpisode() { + SeriesRecording seriesRecording = + SeriesRecording.buildFrom(mBaseSeriesRecording).setId(SERIES_RECORDING_ID1).build(); + mDataManager.addSeriesRecording(seriesRecording); + List<Program> programs = new ArrayList<>(); + Program program1 = + new Program.Builder(mBaseProgram) + .setSeasonNumber(SEASON_NUMBER1) + .setEpisodeNumber(EPISODE_NUMBER1) + .build(); + programs.add(program1); + Program program2 = + new Program.Builder(mBaseProgram) + .setSeasonNumber(SEASON_NUMBER2) + .setEpisodeNumber(EPISODE_NUMBER2) + .build(); + programs.add(program2); + LongSparseArray<List<Program>> result = + SeriesRecordingScheduler.pickOneProgramPerEpisode( + mDataManager, Collections.singletonList(seriesRecording), programs); + MoreAsserts.assertContentsInAnyOrder(result.get(SERIES_RECORDING_ID1), program1, program2); + } + + @Test + public void testPickOneProgramPerEpisode_manyPerEpisode() { + SeriesRecording seriesRecording = + SeriesRecording.buildFrom(mBaseSeriesRecording).setId(SERIES_RECORDING_ID1).build(); + mDataManager.addSeriesRecording(seriesRecording); + List<Program> programs = new ArrayList<>(); + Program program1 = + new Program.Builder(mBaseProgram) + .setSeasonNumber(SEASON_NUMBER1) + .setEpisodeNumber(EPISODE_NUMBER1) + .setStartTimeUtcMillis(0) + .build(); + programs.add(program1); + Program program2 = new Program.Builder(program1).setStartTimeUtcMillis(1).build(); + programs.add(program2); + Program program3 = + new Program.Builder(mBaseProgram) + .setSeasonNumber(SEASON_NUMBER2) + .setEpisodeNumber(EPISODE_NUMBER2) + .build(); + programs.add(program3); + Program program4 = new Program.Builder(program1).setStartTimeUtcMillis(1).build(); + programs.add(program4); + LongSparseArray<List<Program>> result = + SeriesRecordingScheduler.pickOneProgramPerEpisode( + mDataManager, Collections.singletonList(seriesRecording), programs); + MoreAsserts.assertContentsInAnyOrder(result.get(SERIES_RECORDING_ID1), program1, program3); + } + + @Test + public void testPickOneProgramPerEpisode_nullEpisode() { + SeriesRecording seriesRecording = + SeriesRecording.buildFrom(mBaseSeriesRecording).setId(SERIES_RECORDING_ID1).build(); + mDataManager.addSeriesRecording(seriesRecording); + List<Program> programs = new ArrayList<>(); + Program program1 = new Program.Builder(mBaseProgram).setStartTimeUtcMillis(0).build(); + programs.add(program1); + Program program2 = new Program.Builder(mBaseProgram).setStartTimeUtcMillis(1).build(); + programs.add(program2); + LongSparseArray<List<Program>> result = + SeriesRecordingScheduler.pickOneProgramPerEpisode( + mDataManager, Collections.singletonList(seriesRecording), programs); + MoreAsserts.assertContentsInAnyOrder(result.get(SERIES_RECORDING_ID1), program1, program2); + } +} diff --git a/tests/unit/src/com/android/tv/dvr/ui/SortedArrayAdapterTest.java b/tests/unit/src/com/android/tv/dvr/ui/SortedArrayAdapterTest.java new file mode 100644 index 00000000..2a1b5667 --- /dev/null +++ b/tests/unit/src/com/android/tv/dvr/ui/SortedArrayAdapterTest.java @@ -0,0 +1,246 @@ +/* + * Copyright (C) 2016 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.tv.dvr.ui; + +import android.support.test.filters.SmallTest; +import android.support.v17.leanback.widget.ClassPresenterSelector; +import android.support.v17.leanback.widget.ObjectAdapter; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Objects; +import junit.framework.TestCase; +import org.junit.Before; +import org.junit.Test; + +/** Tests for {@link SortedArrayAdapter}. */ +@SmallTest +public class SortedArrayAdapterTest extends TestCase { + public static final TestData P1 = TestData.create(1, "c"); + public static final TestData P2 = TestData.create(2, "b"); + public static final TestData P3 = TestData.create(3, "a"); + public static final TestData EXTRA = TestData.create(4, "k"); + private TestSortedArrayAdapter mAdapter; + + @Before + public void setUp() { + mAdapter = new TestSortedArrayAdapter(Integer.MAX_VALUE, null); + } + + @Test + public void testContents_empty() { + assertEmpty(); + } + + @Test + public void testAdd_one() { + mAdapter.add(P1); + assertNotEmpty(); + assertContentsInOrder(mAdapter, P1); + } + + @Test + public void testAdd_two() { + mAdapter.add(P1); + mAdapter.add(P2); + assertNotEmpty(); + assertContentsInOrder(mAdapter, P2, P1); + } + + @Test + public void testSetInitialItems_two() { + mAdapter.setInitialItems(Arrays.asList(P1, P2)); + assertNotEmpty(); + assertContentsInOrder(mAdapter, P2, P1); + } + + @Test + public void testMaxInitialCount() { + mAdapter = new TestSortedArrayAdapter(1, null); + mAdapter.setInitialItems(Arrays.asList(P1, P2)); + assertNotEmpty(); + assertEquals(mAdapter.size(), 1); + assertEquals(mAdapter.get(0), P2); + } + + @Test + public void testExtraItem() { + mAdapter = new TestSortedArrayAdapter(Integer.MAX_VALUE, EXTRA); + mAdapter.setInitialItems(Arrays.asList(P1, P2)); + assertNotEmpty(); + assertEquals(mAdapter.size(), 3); + assertEquals(mAdapter.get(0), P2); + assertEquals(mAdapter.get(2), EXTRA); + mAdapter.remove(P2); + mAdapter.remove(P1); + assertEquals(mAdapter.size(), 1); + assertEquals(mAdapter.get(0), EXTRA); + } + + @Test + public void testExtraItemWithMaxCount() { + mAdapter = new TestSortedArrayAdapter(1, EXTRA); + mAdapter.setInitialItems(Arrays.asList(P1, P2)); + assertNotEmpty(); + assertEquals(mAdapter.size(), 2); + assertEquals(mAdapter.get(0), P2); + assertEquals(mAdapter.get(1), EXTRA); + mAdapter.remove(P2); + assertEquals(mAdapter.size(), 1); + assertEquals(mAdapter.get(0), EXTRA); + } + + @Test + public void testRemove() { + mAdapter.add(P1); + mAdapter.add(P2); + assertNotEmpty(); + assertContentsInOrder(mAdapter, P2, P1); + mAdapter.remove(P3); + assertContentsInOrder(mAdapter, P2, P1); + mAdapter.remove(P2); + assertContentsInOrder(mAdapter, P1); + mAdapter.remove(P1); + assertEmpty(); + mAdapter.add(P1); + mAdapter.add(P2); + mAdapter.add(P3); + assertContentsInOrder(mAdapter, P3, P2, P1); + mAdapter.removeItems(0, 2); + assertContentsInOrder(mAdapter, P1); + mAdapter.add(P2); + mAdapter.add(P3); + mAdapter.addExtraItem(EXTRA); + assertContentsInOrder(mAdapter, P3, P2, P1, EXTRA); + mAdapter.removeItems(1, 1); + assertContentsInOrder(mAdapter, P3, P1, EXTRA); + mAdapter.removeItems(1, 2); + assertContentsInOrder(mAdapter, P3); + mAdapter.addExtraItem(EXTRA); + mAdapter.addExtraItem(P2); + mAdapter.add(P1); + assertContentsInOrder(mAdapter, P3, P1, EXTRA, P2); + mAdapter.removeItems(1, 2); + assertContentsInOrder(mAdapter, P3, P2); + mAdapter.add(P1); + assertContentsInOrder(mAdapter, P3, P1, P2); + } + + @Test + public void testReplace() { + mAdapter.add(P1); + mAdapter.add(P2); + assertNotEmpty(); + assertContentsInOrder(mAdapter, P2, P1); + mAdapter.replace(1, P3); + assertContentsInOrder(mAdapter, P3, P2); + mAdapter.replace(0, P1); + assertContentsInOrder(mAdapter, P2, P1); + mAdapter.addExtraItem(EXTRA); + assertContentsInOrder(mAdapter, P2, P1, EXTRA); + mAdapter.replace(2, P3); + assertContentsInOrder(mAdapter, P2, P1, P3); + } + + @Test + public void testChange_sorting() { + TestData p2_changed = TestData.create(2, "z changed"); + mAdapter.add(P1); + mAdapter.add(P2); + assertNotEmpty(); + assertContentsInOrder(mAdapter, P2, P1); + mAdapter.change(p2_changed); + assertContentsInOrder(mAdapter, P1, p2_changed); + } + + @Test + public void testChange_new() { + mAdapter.change(P1); + assertNotEmpty(); + assertContentsInOrder(mAdapter, P1); + } + + private void assertEmpty() { + assertEquals("empty", true, mAdapter.isEmpty()); + } + + private void assertNotEmpty() { + assertEquals("empty", false, mAdapter.isEmpty()); + } + + private static void assertContentsInOrder(ObjectAdapter adapter, Object... contents) { + int ex = contents.length; + assertEquals("size", ex, adapter.size()); + for (int i = 0; i < ex; i++) { + assertEquals("element " + 1, contents[i], adapter.get(i)); + } + } + + private static class TestData { + @Override + public String toString() { + return "TestData[" + mId + "]{" + mText + '}'; + } + + static TestData create(long first, String text) { + return new TestData(first, text); + } + + private final long mId; + private final String mText; + + private TestData(long id, String second) { + this.mId = id; + this.mText = second; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof TestData)) return false; + TestData that = (TestData) o; + return mId == that.mId && Objects.equals(mText, that.mText); + } + + @Override + public int hashCode() { + return Objects.hash(mId, mText); + } + } + + private static class TestSortedArrayAdapter extends SortedArrayAdapter<TestData> { + + private static final Comparator<TestData> TEXT_COMPARATOR = + new Comparator<TestData>() { + @Override + public int compare(TestData lhs, TestData rhs) { + return lhs.mText.compareTo(rhs.mText); + } + }; + + TestSortedArrayAdapter(int maxInitialCount, Object extra) { + super(new ClassPresenterSelector(), TEXT_COMPARATOR, maxInitialCount); + if (extra != null) { + addExtraItem((TestData) extra); + } + } + + @Override + protected long getId(TestData item) { + return item.mId; + } + } +} diff --git a/tests/unit/src/com/android/tv/experiments/ExperimentsTest.java b/tests/unit/src/com/android/tv/experiments/ExperimentsTest.java new file mode 100644 index 00000000..f5fb353c --- /dev/null +++ b/tests/unit/src/com/android/tv/experiments/ExperimentsTest.java @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2016 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.tv.experiments; + +import static org.junit.Assert.assertEquals; + +import android.support.test.filters.SmallTest; +import com.android.tv.common.BuildConfig; +import org.junit.Before; +import org.junit.Test; + +/** Tests for {@link Experiments}. */ +@SmallTest +public class ExperimentsTest { + @Before + public void setUp() { + ExperimentFlag.initForTest(); + } + + @Test + public void testEngOnlyDefault() { + assertEquals( + "ENABLE_DEVELOPER_FEATURES", + Boolean.valueOf(BuildConfig.ENG), + Experiments.ENABLE_DEVELOPER_FEATURES.get()); + } +} diff --git a/tests/unit/src/com/android/tv/menu/TvOptionsRowAdapterTest.java b/tests/unit/src/com/android/tv/menu/TvOptionsRowAdapterTest.java index 04d86bfc..4faca569 100644 --- a/tests/unit/src/com/android/tv/menu/TvOptionsRowAdapterTest.java +++ b/tests/unit/src/com/android/tv/menu/TvOptionsRowAdapterTest.java @@ -24,7 +24,7 @@ import android.os.SystemClock; import android.support.test.filters.MediumTest; import android.text.TextUtils; import com.android.tv.BaseMainActivityTestCase; -import com.android.tv.testing.constants.Constants; +import com.android.tv.testing.Constants; import com.android.tv.testing.testinput.ChannelState; import com.android.tv.testing.testinput.ChannelStateData; import com.android.tv.testing.testinput.TvTestInputConstants; diff --git a/tests/unit/src/com/android/tv/recommendation/ChannelRecordTest.java b/tests/unit/src/com/android/tv/recommendation/ChannelRecordTest.java index c2f0d0c5..d868d3f8 100644 --- a/tests/unit/src/com/android/tv/recommendation/ChannelRecordTest.java +++ b/tests/unit/src/com/android/tv/recommendation/ChannelRecordTest.java @@ -20,7 +20,7 @@ import static android.support.test.InstrumentationRegistry.getContext; import static org.junit.Assert.assertEquals; import android.support.test.filters.SmallTest; -import com.android.tv.testing.utils.Utils; +import com.android.tv.testing.Utils; import java.util.Random; import java.util.concurrent.TimeUnit; import org.junit.Before; diff --git a/tests/unit/src/com/android/tv/recommendation/EvaluatorTestCase.java b/tests/unit/src/com/android/tv/recommendation/EvaluatorTestCase.java index 6e76bf36..af941177 100644 --- a/tests/unit/src/com/android/tv/recommendation/EvaluatorTestCase.java +++ b/tests/unit/src/com/android/tv/recommendation/EvaluatorTestCase.java @@ -23,7 +23,7 @@ import static org.junit.Assert.assertTrue; import com.android.tv.data.Channel; import com.android.tv.recommendation.RecommendationUtils.ChannelRecordSortedMapHelper; import com.android.tv.recommendation.Recommender.Evaluator; -import com.android.tv.testing.utils.Utils; +import com.android.tv.testing.Utils; import java.util.ArrayList; import java.util.List; import org.junit.Before; diff --git a/tests/unit/src/com/android/tv/recommendation/RecommendationUtils.java b/tests/unit/src/com/android/tv/recommendation/RecommendationUtils.java index 2fc4bb1c..eea42bf5 100644 --- a/tests/unit/src/com/android/tv/recommendation/RecommendationUtils.java +++ b/tests/unit/src/com/android/tv/recommendation/RecommendationUtils.java @@ -18,7 +18,7 @@ package com.android.tv.recommendation; import android.content.Context; import com.android.tv.data.Channel; -import com.android.tv.testing.utils.Utils; +import com.android.tv.testing.Utils; import java.util.ArrayList; import java.util.Collection; import java.util.List; diff --git a/tests/unit/src/com/android/tv/recommendation/RecommenderTest.java b/tests/unit/src/com/android/tv/recommendation/RecommenderTest.java index e2b0b249..062633a5 100644 --- a/tests/unit/src/com/android/tv/recommendation/RecommenderTest.java +++ b/tests/unit/src/com/android/tv/recommendation/RecommenderTest.java @@ -25,7 +25,7 @@ import android.support.test.filters.SmallTest; import android.test.MoreAsserts; import com.android.tv.data.Channel; import com.android.tv.recommendation.RecommendationUtils.ChannelRecordSortedMapHelper; -import com.android.tv.testing.utils.Utils; +import com.android.tv.testing.Utils; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -46,7 +46,7 @@ public class RecommenderTest { System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1); private static final long DEFAULT_MAX_WATCH_DURATION_MS = TimeUnit.HOURS.toMillis(1); - private final Comparator<Channel> mChannelSortKeyComparator = + private final Comparator<Channel> CHANNEL_SORT_KEY_COMPARATOR = new Comparator<Channel>() { @Override public int compare(Channel lhs, Channel rhs) { @@ -55,7 +55,7 @@ public class RecommenderTest { .compareTo(mRecommender.getChannelSortKey(rhs.getId())); } }; - private final Runnable mStartDatamanagerRunnableAddFourChannels = + private final Runnable START_DATAMANAGER_RUNNABLE_ADD_FOUR_CHANNELS = new Runnable() { @Override public void run() { @@ -89,7 +89,7 @@ public class RecommenderTest { @Test public void testRecommendChannels_includeRecommendedOnly_allChannelsHaveNoScore() { - createRecommender(true, mStartDatamanagerRunnableAddFourChannels); + createRecommender(true, START_DATAMANAGER_RUNNABLE_ADD_FOUR_CHANNELS); // Recommender doesn't recommend any channels because all channels are not recommended. assertEquals(0, mRecommender.recommendChannels().size()); @@ -102,7 +102,7 @@ public class RecommenderTest { @Test public void testRecommendChannels_notIncludeRecommendedOnly_allChannelsHaveNoScore() { - createRecommender(false, mStartDatamanagerRunnableAddFourChannels); + createRecommender(false, START_DATAMANAGER_RUNNABLE_ADD_FOUR_CHANNELS); // Recommender recommends every channel because it recommends not-recommended channels too. assertEquals(4, mRecommender.recommendChannels().size()); @@ -115,7 +115,7 @@ public class RecommenderTest { @Test public void testRecommendChannels_includeRecommendedOnly_allChannelsHaveScore() { - createRecommender(true, mStartDatamanagerRunnableAddFourChannels); + createRecommender(true, START_DATAMANAGER_RUNNABLE_ADD_FOUR_CHANNELS); setChannelScores_scoreIncreasesAsChannelIdIncreases(); @@ -135,7 +135,7 @@ public class RecommenderTest { @Test public void testRecommendChannels_notIncludeRecommendedOnly_allChannelsHaveScore() { - createRecommender(false, mStartDatamanagerRunnableAddFourChannels); + createRecommender(false, START_DATAMANAGER_RUNNABLE_ADD_FOUR_CHANNELS); setChannelScores_scoreIncreasesAsChannelIdIncreases(); @@ -155,7 +155,7 @@ public class RecommenderTest { @Test public void testRecommendChannels_includeRecommendedOnly_fewChannelsHaveScore() { - createRecommender(true, mStartDatamanagerRunnableAddFourChannels); + createRecommender(true, START_DATAMANAGER_RUNNABLE_ADD_FOUR_CHANNELS); mEvaluator.setChannelScore(mChannel_1.getId(), 1.0); mEvaluator.setChannelScore(mChannel_2.getId(), 1.0); @@ -175,7 +175,7 @@ public class RecommenderTest { @Test public void testRecommendChannels_notIncludeRecommendedOnly_fewChannelsHaveScore() { - createRecommender(false, mStartDatamanagerRunnableAddFourChannels); + createRecommender(false, START_DATAMANAGER_RUNNABLE_ADD_FOUR_CHANNELS); mEvaluator.setChannelScore(mChannel_1.getId(), 1.0); mEvaluator.setChannelScore(mChannel_2.getId(), 1.0); @@ -202,13 +202,13 @@ public class RecommenderTest { @Test public void testGetChannelSortKey_recommendAllChannels() { - createRecommender(true, mStartDatamanagerRunnableAddFourChannels); + createRecommender(true, START_DATAMANAGER_RUNNABLE_ADD_FOUR_CHANNELS); setChannelScores_scoreIncreasesAsChannelIdIncreases(); List<Channel> expectedChannelList = mRecommender.recommendChannels(); List<Channel> channelList = Arrays.asList(mChannel_1, mChannel_2, mChannel_3, mChannel_4); - Collections.sort(channelList, mChannelSortKeyComparator); + Collections.sort(channelList, CHANNEL_SORT_KEY_COMPARATOR); // Recommended channel list and channel list sorted by sort key must be the same. MoreAsserts.assertContentsInOrder(channelList, expectedChannelList.toArray()); @@ -218,7 +218,7 @@ public class RecommenderTest { @Test public void testGetChannelSortKey_recommendFewChannels() { // Test with recommending 3 channels. - createRecommender(true, mStartDatamanagerRunnableAddFourChannels); + createRecommender(true, START_DATAMANAGER_RUNNABLE_ADD_FOUR_CHANNELS); setChannelScores_scoreIncreasesAsChannelIdIncreases(); @@ -229,7 +229,7 @@ public class RecommenderTest { mRecommender.getChannelSortKey(mChannel_1.getId())); List<Channel> channelList = Arrays.asList(mChannel_2, mChannel_3, mChannel_4); - Collections.sort(channelList, mChannelSortKeyComparator); + Collections.sort(channelList, CHANNEL_SORT_KEY_COMPARATOR); MoreAsserts.assertContentsInOrder(channelList, expectedChannelList.toArray()); assertSortKeyNotInvalid(channelList); @@ -237,7 +237,7 @@ public class RecommenderTest { @Test public void testListener_onRecommendationChanged() { - createRecommender(true, mStartDatamanagerRunnableAddFourChannels); + createRecommender(true, START_DATAMANAGER_RUNNABLE_ADD_FOUR_CHANNELS); // FakeEvaluator doesn't recommend a channel with empty watch log. As every channel // doesn't have a watch log, nothing is recommended and recommendation isn't changed. assertFalse(mOnRecommendationChanged); diff --git a/tests/unit/src/com/android/tv/recommendation/RoutineWatchEvaluatorTest.java b/tests/unit/src/com/android/tv/recommendation/RoutineWatchEvaluatorTest.java index a675df85..3c972e93 100644 --- a/tests/unit/src/com/android/tv/recommendation/RoutineWatchEvaluatorTest.java +++ b/tests/unit/src/com/android/tv/recommendation/RoutineWatchEvaluatorTest.java @@ -124,47 +124,47 @@ public class RoutineWatchEvaluatorTest extends EvaluatorTestCase<RoutineWatchEva int tomorrowDayOfWeek = (todayDayOfWeek % 7) + 1; // Today 00:00 - 01:00. - ProgramTime programTimeToday0000to0100 = + ProgramTime programTimeToday0000_0100 = ProgramTime.createFromProgram( createDummyProgram(todayAtHourMin(0, 0), TimeUnit.HOURS.toMillis(1))); assertProgramTime( todayDayOfWeek, hourMinuteToSec(0, 0), hourMinuteToSec(1, 0), - programTimeToday0000to0100); + programTimeToday0000_0100); // Today 23:30 - 24:30. - ProgramTime programTimeToday2330to2430 = + ProgramTime programTimeToday2330_2430 = ProgramTime.createFromProgram( createDummyProgram(todayAtHourMin(23, 30), TimeUnit.HOURS.toMillis(1))); assertProgramTime( todayDayOfWeek, hourMinuteToSec(23, 30), hourMinuteToSec(24, 30), - programTimeToday2330to2430); + programTimeToday2330_2430); // Tomorrow 00:00 - 01:00. - ProgramTime programTimeTomorrow0000to0100 = + ProgramTime programTimeTomorrow0000_0100 = ProgramTime.createFromProgram( createDummyProgram(tomorrowAtHourMin(0, 0), TimeUnit.HOURS.toMillis(1))); assertProgramTime( tomorrowDayOfWeek, hourMinuteToSec(0, 0), hourMinuteToSec(1, 0), - programTimeTomorrow0000to0100); + programTimeTomorrow0000_0100); // Tomorrow 23:30 - 24:30. - ProgramTime programTimeTomorrow2330to2430 = + ProgramTime programTimeTomorrow2330_2430 = ProgramTime.createFromProgram( createDummyProgram(tomorrowAtHourMin(23, 30), TimeUnit.HOURS.toMillis(1))); assertProgramTime( tomorrowDayOfWeek, hourMinuteToSec(23, 30), hourMinuteToSec(24, 30), - programTimeTomorrow2330to2430); + programTimeTomorrow2330_2430); // Today 18:00 - Tomorrow 12:00. - ProgramTime programTimeToday1800to3600 = + ProgramTime programTimeToday1800_3600 = ProgramTime.createFromProgram( createDummyProgram(todayAtHourMin(18, 0), TimeUnit.HOURS.toMillis(18))); // Maximum duration of ProgramTime is 12 hours. @@ -173,42 +173,42 @@ public class RoutineWatchEvaluatorTest extends EvaluatorTestCase<RoutineWatchEva todayDayOfWeek, hourMinuteToSec(18, 0), hourMinuteToSec(30, 0), - programTimeToday1800to3600); + programTimeToday1800_3600); } @Test public void testCalculateOverlappedIntervalScore() { // Today 21:00 - 24:00. - ProgramTime programTimeToday2100to2400 = + ProgramTime programTimeToday2100_2400 = ProgramTime.createFromProgram( createDummyProgram(todayAtHourMin(21, 0), TimeUnit.HOURS.toMillis(3))); // Today 22:00 - 01:00. - ProgramTime programTimeToday2200to0100 = + ProgramTime programTimeToday2200_0100 = ProgramTime.createFromProgram( createDummyProgram(todayAtHourMin(22, 0), TimeUnit.HOURS.toMillis(3))); // Tomorrow 00:00 - 03:00. - ProgramTime programTimeTomorrow0000to0300 = + ProgramTime programTimeTomorrow0000_0300 = ProgramTime.createFromProgram( createDummyProgram(tomorrowAtHourMin(0, 0), TimeUnit.HOURS.toMillis(3))); // Tomorrow 20:00 - Tomorrow 23:00. - ProgramTime programTimeTomorrow2000to2300 = + ProgramTime programTimeTomorrow2000_2300 = ProgramTime.createFromProgram( createDummyProgram(tomorrowAtHourMin(20, 0), TimeUnit.HOURS.toMillis(3))); // Check intersection time and commutative law in all cases. int oneHourInSec = hourMinuteToSec(1, 0); assertOverlappedIntervalScore( - 2 * oneHourInSec, true, programTimeToday2100to2400, programTimeToday2200to0100); + 2 * oneHourInSec, true, programTimeToday2100_2400, programTimeToday2200_0100); assertOverlappedIntervalScore( - 0, false, programTimeToday2100to2400, programTimeTomorrow0000to0300); + 0, false, programTimeToday2100_2400, programTimeTomorrow0000_0300); assertOverlappedIntervalScore( - 2 * oneHourInSec, false, programTimeToday2100to2400, programTimeTomorrow2000to2300); + 2 * oneHourInSec, false, programTimeToday2100_2400, programTimeTomorrow2000_2300); assertOverlappedIntervalScore( - oneHourInSec, true, programTimeToday2200to0100, programTimeTomorrow0000to0300); + oneHourInSec, true, programTimeToday2200_0100, programTimeTomorrow0000_0300); assertOverlappedIntervalScore( - oneHourInSec, false, programTimeToday2200to0100, programTimeTomorrow2000to2300); + oneHourInSec, false, programTimeToday2200_0100, programTimeTomorrow2000_2300); assertOverlappedIntervalScore( - 0, false, programTimeTomorrow0000to0300, programTimeTomorrow2000to2300); + 0, false, programTimeTomorrow0000_0300, programTimeTomorrow2000_2300); } @Test diff --git a/tests/unit/src/com/android/tv/search/LocalSearchProviderTest.java b/tests/unit/src/com/android/tv/search/LocalSearchProviderTest.java index 2bc5f05a..9ac81301 100644 --- a/tests/unit/src/com/android/tv/search/LocalSearchProviderTest.java +++ b/tests/unit/src/com/android/tv/search/LocalSearchProviderTest.java @@ -25,10 +25,10 @@ import android.database.Cursor; import android.net.Uri; import android.support.test.filters.SmallTest; import android.test.ProviderTestCase2; +import com.android.tv.ApplicationSingletons; import com.android.tv.TvApplication; -import com.android.tv.common.BaseSingletons; import com.android.tv.perf.PerformanceMonitor; -import com.android.tv.util.MockTvSingletons; +import com.android.tv.util.MockApplicationSingletons; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -37,7 +37,6 @@ import org.mockito.MockitoAnnotations; /** Unit test for {@link LocalSearchProvider}. */ @SmallTest -@SuppressWarnings("TryWithResources") // TODO(b/62143348): remove when error prone check fixed public class LocalSearchProviderTest extends ProviderTestCase2<LocalSearchProvider> { private static final String AUTHORITY = "com.android.tv.search"; private static final String KEYWORD = "keyword"; @@ -49,11 +48,11 @@ public class LocalSearchProviderTest extends ProviderTestCase2<LocalSearchProvid + SearchManager.SUGGEST_URI_PATH_QUERY + "/" + KEYWORD); - private static final Uri WRONG_SEARCH_URI = + private static final Uri WRONG_SERACH_URI = Uri.parse("content://" + AUTHORITY + "/wrong_path/" + KEYWORD); - private BaseSingletons mOldTvSingletons; - MockTvSingletons mMockTvSingletons; + private ApplicationSingletons mOldAppSingletons; + MockApplicationSingletons mMockAppSingletons; @Mock PerformanceMonitor mMockPerformanceMointor; @Mock SearchInterface mMockSearchInterface; @@ -66,10 +65,10 @@ public class LocalSearchProviderTest extends ProviderTestCase2<LocalSearchProvid public void setUp() throws Exception { MockitoAnnotations.initMocks(this); setContext(getTargetContext()); - mOldTvSingletons = TvApplication.sSingletons; - mMockTvSingletons = new MockTvSingletons(getTargetContext()); - mMockTvSingletons.setPerformanceMonitor(mMockPerformanceMointor); - TvApplication.sSingletons = mMockTvSingletons; + mOldAppSingletons = TvApplication.sAppSingletons; + mMockAppSingletons = new MockApplicationSingletons(getTargetContext()); + mMockAppSingletons.setPerformanceMonitor(mMockPerformanceMointor); + TvApplication.sAppSingletons = mMockAppSingletons; super.setUp(); getProvider().setSearchInterface(mMockSearchInterface); } @@ -77,7 +76,7 @@ public class LocalSearchProviderTest extends ProviderTestCase2<LocalSearchProvid @After @Override public void tearDown() throws Exception { - TvApplication.sSingletons = mOldTvSingletons; + TvApplication.sAppSingletons = mOldAppSingletons; super.tearDown(); } @@ -91,7 +90,7 @@ public class LocalSearchProviderTest extends ProviderTestCase2<LocalSearchProvid @Test public void testQuery_invalidUri() { - try (Cursor c = getProvider().query(WRONG_SEARCH_URI, null, null, null, null)) { + try (Cursor c = getProvider().query(WRONG_SERACH_URI, null, null, null, null)) { fail("Query with invalid URI should fail."); } catch (IllegalArgumentException e) { // Success. diff --git a/tests/unit/src/com/android/tv/tests/TvActivityTest.java b/tests/unit/src/com/android/tv/tests/TvActivityTest.java index 30663e9a..346b9787 100644 --- a/tests/unit/src/com/android/tv/tests/TvActivityTest.java +++ b/tests/unit/src/com/android/tv/tests/TvActivityTest.java @@ -23,7 +23,7 @@ import static org.junit.Assert.assertTrue; import android.support.test.filters.MediumTest; import android.support.test.rule.ActivityTestRule; import com.android.tv.TvActivity; -import com.android.tv.testing.utils.Utils; +import com.android.tv.testing.Utils; import org.junit.Rule; import org.junit.Test; diff --git a/tests/unit/src/com/android/tv/util/ImageCacheTest.java b/tests/unit/src/com/android/tv/util/ImageCacheTest.java index cd34895e..8352f7dc 100644 --- a/tests/unit/src/com/android/tv/util/ImageCacheTest.java +++ b/tests/unit/src/com/android/tv/util/ImageCacheTest.java @@ -21,15 +21,12 @@ import static org.junit.Assert.assertSame; import android.graphics.Bitmap; import android.support.test.filters.MediumTest; -import android.support.test.runner.AndroidJUnit4; import com.android.tv.util.BitmapUtils.ScaledBitmapInfo; import org.junit.Before; import org.junit.Test; -import org.junit.runner.RunWith; /** Tests for {@link ImageCache}. */ @MediumTest -@RunWith(AndroidJUnit4.class) public class ImageCacheTest { private static final Bitmap ORIG = Bitmap.createBitmap(100, 100, Bitmap.Config.RGB_565); diff --git a/tests/unit/src/com/android/tv/util/MockTvSingletons.java b/tests/unit/src/com/android/tv/util/MockApplicationSingletons.java index 3a74f917..4eb0c4d7 100644 --- a/tests/unit/src/com/android/tv/util/MockTvSingletons.java +++ b/tests/unit/src/com/android/tv/util/MockApplicationSingletons.java @@ -17,40 +17,31 @@ package com.android.tv.util; import android.content.Context; -import android.content.Intent; +import com.android.tv.ApplicationSingletons; import com.android.tv.InputSessionManager; import com.android.tv.MainActivityWrapper; import com.android.tv.TvApplication; -import com.android.tv.TvSingletons; import com.android.tv.analytics.Analytics; import com.android.tv.analytics.Tracker; -import com.android.tv.common.config.api.RemoteConfig; -import com.android.tv.common.experiments.ExperimentLoader; -import com.android.tv.common.recording.RecordingStorageStatusManager; -import com.android.tv.common.util.Clock; +import com.android.tv.config.RemoteConfig; import com.android.tv.data.ChannelDataManager; import com.android.tv.data.PreviewDataManager; import com.android.tv.data.ProgramDataManager; -import com.android.tv.data.epg.EpgFetcher; -import com.android.tv.data.epg.EpgReader; import com.android.tv.dvr.DvrDataManager; import com.android.tv.dvr.DvrManager; import com.android.tv.dvr.DvrScheduleManager; +import com.android.tv.dvr.DvrStorageStatusManager; import com.android.tv.dvr.DvrWatchedPositionManager; import com.android.tv.dvr.recorder.RecordingScheduler; import com.android.tv.perf.PerformanceMonitor; -import com.android.tv.testing.FakeClock; -import com.android.tv.tuner.TunerInputController; -import javax.inject.Provider; - -/** Mock {@link TvSingletons} class. */ -public class MockTvSingletons implements TvSingletons { - public final FakeClock fakeClock = FakeClock.createWithCurrentTime(); +/** Mock {@link ApplicationSingletons} class. */ +public class MockApplicationSingletons implements ApplicationSingletons { private final TvApplication mApp; + private PerformanceMonitor mPerformanceMonitor; - public MockTvSingletons(Context context) { + public MockApplicationSingletons(Context context) { mApp = (TvApplication) context.getApplicationContext(); } @@ -60,9 +51,6 @@ public class MockTvSingletons implements TvSingletons { } @Override - public void handleInputCountChanged() {} - - @Override public ChannelDataManager getChannelDataManager() { return mApp.getChannelDataManager(); } @@ -93,13 +81,8 @@ public class MockTvSingletons implements TvSingletons { } @Override - public Clock getClock() { - return fakeClock; - } - - @Override - public RecordingStorageStatusManager getRecordingStorageStatusManager() { - return mApp.getRecordingStorageStatusManager(); + public DvrStorageStatusManager getDvrStorageStatusManager() { + return mApp.getDvrStorageStatusManager(); } @Override @@ -138,37 +121,12 @@ public class MockTvSingletons implements TvSingletons { } @Override - public Provider<EpgReader> providesEpgReader() { - return mApp.providesEpgReader(); - } - - @Override - public EpgFetcher getEpgFetcher() { - return mApp.getEpgFetcher(); - } - - @Override - public SetupUtils getSetupUtils() { - return mApp.getSetupUtils(); - } - - @Override - public TunerInputController getTunerInputController() { - return mApp.getTunerInputController(); - } - - @Override - public ExperimentLoader getExperimentLoader() { - return mApp.getExperimentLoader(); - } - - @Override public MainActivityWrapper getMainActivityWrapper() { return mApp.getMainActivityWrapper(); } @Override - public com.android.tv.util.account.AccountHelper getAccountHelper() { + public AccountHelper getAccountHelper() { return mApp.getAccountHelper(); } @@ -178,11 +136,6 @@ public class MockTvSingletons implements TvSingletons { } @Override - public Intent getTunerSetupIntent(Context context) { - return mApp.getTunerSetupIntent(context); - } - - @Override public boolean isRunningInMainProcess() { return mApp.isRunningInMainProcess(); } @@ -195,9 +148,4 @@ public class MockTvSingletons implements TvSingletons { public void setPerformanceMonitor(PerformanceMonitor performanceMonitor) { mPerformanceMonitor = performanceMonitor; } - - @Override - public String getEmbeddedTunerInputId() { - return "com.android.tv/.tuner.tvinput.LiveTvTunerTvInputService"; - } } diff --git a/tests/unit/src/com/android/tv/util/MultiLongSparseArrayTest.java b/tests/unit/src/com/android/tv/util/MultiLongSparseArrayTest.java new file mode 100644 index 00000000..42325c83 --- /dev/null +++ b/tests/unit/src/com/android/tv/util/MultiLongSparseArrayTest.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2015 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.tv.util; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; + +import android.support.test.filters.SmallTest; +import android.test.MoreAsserts; +import java.util.Collections; +import org.junit.Test; + +/** Tests for {@link MultiLongSparseArray}. */ +@SmallTest +public class MultiLongSparseArrayTest { + @Test + public void testEmpty() { + MultiLongSparseArray<String> sparseArray = new MultiLongSparseArray<>(); + assertSame(Collections.EMPTY_SET, sparseArray.get(0)); + } + + @Test + public void testOneElement() { + MultiLongSparseArray<String> sparseArray = new MultiLongSparseArray<>(); + sparseArray.put(0, "foo"); + MoreAsserts.assertContentsInAnyOrder(sparseArray.get(0), "foo"); + } + + @Test + public void testTwoElements() { + MultiLongSparseArray<String> sparseArray = new MultiLongSparseArray<>(); + sparseArray.put(0, "foo"); + sparseArray.put(0, "bar"); + MoreAsserts.assertContentsInAnyOrder(sparseArray.get(0), "foo", "bar"); + } + + @Test + public void testClearEmptyCache() { + MultiLongSparseArray<String> sparseArray = new MultiLongSparseArray<>(); + sparseArray.clearEmptyCache(); + assertEquals(0, sparseArray.getEmptyCacheSize()); + sparseArray.put(0, "foo"); + sparseArray.remove(0, "foo"); + assertEquals(1, sparseArray.getEmptyCacheSize()); + sparseArray.clearEmptyCache(); + assertEquals(0, sparseArray.getEmptyCacheSize()); + } + + @Test + public void testMaxEmptyCacheSize() { + MultiLongSparseArray<String> sparseArray = new MultiLongSparseArray<>(); + sparseArray.clearEmptyCache(); + assertEquals(0, sparseArray.getEmptyCacheSize()); + for (int i = 0; i <= MultiLongSparseArray.DEFAULT_MAX_EMPTIES_KEPT + 2; i++) { + sparseArray.put(i, "foo"); + } + for (int i = 0; i <= MultiLongSparseArray.DEFAULT_MAX_EMPTIES_KEPT + 2; i++) { + sparseArray.remove(i, "foo"); + } + assertEquals( + MultiLongSparseArray.DEFAULT_MAX_EMPTIES_KEPT, sparseArray.getEmptyCacheSize()); + sparseArray.clearEmptyCache(); + assertEquals(0, sparseArray.getEmptyCacheSize()); + } + + @Test + public void testReuseEmptySets() { + MultiLongSparseArray<String> sparseArray = new MultiLongSparseArray<>(); + sparseArray.clearEmptyCache(); + assertEquals(0, sparseArray.getEmptyCacheSize()); + // create a bunch of sets + for (int i = 0; i <= MultiLongSparseArray.DEFAULT_MAX_EMPTIES_KEPT + 2; i++) { + sparseArray.put(i, "foo"); + } + // remove them so they are all put in the cache. + for (int i = 0; i <= MultiLongSparseArray.DEFAULT_MAX_EMPTIES_KEPT + 2; i++) { + sparseArray.remove(i, "foo"); + } + assertEquals( + MultiLongSparseArray.DEFAULT_MAX_EMPTIES_KEPT, sparseArray.getEmptyCacheSize()); + + // now create elements, that use the cached empty sets. + for (int i = 0; i < MultiLongSparseArray.DEFAULT_MAX_EMPTIES_KEPT; i++) { + sparseArray.put(10 + i, "bar"); + assertEquals( + MultiLongSparseArray.DEFAULT_MAX_EMPTIES_KEPT - i - 1, + sparseArray.getEmptyCacheSize()); + } + } +} diff --git a/tests/unit/src/com/android/tv/util/ScaledBitmapInfoTest.java b/tests/unit/src/com/android/tv/util/ScaledBitmapInfoTest.java index 9bb69f80..87ae5131 100644 --- a/tests/unit/src/com/android/tv/util/ScaledBitmapInfoTest.java +++ b/tests/unit/src/com/android/tv/util/ScaledBitmapInfoTest.java @@ -1,32 +1,14 @@ -/* - * Copyright (C) 2017 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.tv.util; import static org.junit.Assert.assertEquals; import android.graphics.Bitmap; import android.support.test.filters.SmallTest; -import android.support.test.runner.AndroidJUnit4; import com.android.tv.util.BitmapUtils.ScaledBitmapInfo; import org.junit.Test; -import org.junit.runner.RunWith; /** Tests for {@link ScaledBitmapInfo}. */ @SmallTest -@RunWith(AndroidJUnit4.class) public class ScaledBitmapInfoTest { private static final Bitmap B80x100 = Bitmap.createBitmap(80, 100, Bitmap.Config.RGB_565); private static final Bitmap B960x1440 = Bitmap.createBitmap(960, 1440, Bitmap.Config.RGB_565); diff --git a/tests/unit/src/com/android/tv/util/TvInputManagerHelperTest.java b/tests/unit/src/com/android/tv/util/TvInputManagerHelperTest.java index 168e7c6e..44c4477e 100644 --- a/tests/unit/src/com/android/tv/util/TvInputManagerHelperTest.java +++ b/tests/unit/src/com/android/tv/util/TvInputManagerHelperTest.java @@ -21,20 +21,17 @@ import static android.support.test.InstrumentationRegistry.getContext; import android.content.pm.ResolveInfo; import android.media.tv.TvInputInfo; import android.support.test.filters.SmallTest; -import android.support.test.runner.AndroidJUnit4; import com.android.tv.testing.ComparatorTester; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import org.junit.Test; -import org.junit.runner.RunWith; import org.mockito.Mockito; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; /** Test for {@link TvInputManagerHelper} */ @SmallTest -@RunWith(AndroidJUnit4.class) public class TvInputManagerHelperTest { final HashMap<String, TvInputInfoWrapper> TEST_INPUT_MAP = new HashMap<>(); diff --git a/tests/unit/src/com/android/tv/util/TvTrackInfoUtilsTest.java b/tests/unit/src/com/android/tv/util/TvTrackInfoUtilsTest.java index c4623bc7..e60aae05 100644 --- a/tests/unit/src/com/android/tv/util/TvTrackInfoUtilsTest.java +++ b/tests/unit/src/com/android/tv/util/TvTrackInfoUtilsTest.java @@ -20,18 +20,15 @@ import static org.junit.Assert.assertEquals; import android.media.tv.TvTrackInfo; import android.support.test.filters.SmallTest; -import android.support.test.runner.AndroidJUnit4; import com.android.tv.testing.ComparatorTester; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; import org.junit.Test; -import org.junit.runner.RunWith; /** Tests for {@link com.android.tv.util.TvTrackInfoUtils}. */ @SmallTest -@RunWith(AndroidJUnit4.class) public class TvTrackInfoUtilsTest { private static final String UN_MATCHED_ID = "no matching ID"; diff --git a/tests/unit/src/com/android/tv/util/UtilsTest_GetDurationString.java b/tests/unit/src/com/android/tv/util/UtilsTest_GetDurationString.java new file mode 100644 index 00000000..f5eefc64 --- /dev/null +++ b/tests/unit/src/com/android/tv/util/UtilsTest_GetDurationString.java @@ -0,0 +1,446 @@ +/* + * Copyright (C) 2015 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.tv.util; + +import static android.support.test.InstrumentationRegistry.getContext; +import static org.junit.Assert.assertEquals; + +import android.support.test.filters.SmallTest; +import android.text.format.DateUtils; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.Locale; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Tests for {@link com.android.tv.util.Utils#getDurationString}. + * + * <p>This test uses deprecated flags {@link DateUtils#FORMAT_12HOUR} and {@link + * DateUtils#FORMAT_24HOUR} to run this test independent to system's 12/24h format. Note that + * changing system setting requires permission android.permission.WRITE_SETTINGS and it should be + * defined in TV app, not this test. + */ +@SmallTest +public class UtilsTest_GetDurationString { + // TODO: Mock Context so we can specify current time and locale for test. + private Locale mLocale; + private static final long DATE_THIS_YEAR_2_1_MS = getFebOfThisYearInMillis(1, 0, 0); + + // All possible list for a parameter to test parameter independent result. + private static final boolean[] PARAM_USE_SHORT_FORMAT = {false, true}; + + @Before + public void setUp() { + // Set locale to US + mLocale = Locale.getDefault(); + Locale.setDefault(Locale.US); + } + + @After + public void tearDown() { + // Revive system locale. + Locale.setDefault(mLocale); + } + + /** Return time in millis assuming that whose year is this year and month is Jan. */ + private static long getJanOfThisYearInMillis(int date, int hour, int minutes) { + return new GregorianCalendar(getThisYear(), Calendar.JANUARY, date, hour, minutes) + .getTimeInMillis(); + } + + private static long getJanOfThisYearInMillis(int date, int hour) { + return getJanOfThisYearInMillis(date, hour, 0); + } + + /** Return time in millis assuming that whose year is this year and month is Feb. */ + private static long getFebOfThisYearInMillis(int date, int hour, int minutes) { + return new GregorianCalendar(getThisYear(), Calendar.FEBRUARY, date, hour, minutes) + .getTimeInMillis(); + } + + private static long getFebOfThisYearInMillis(int date, int hour) { + return getFebOfThisYearInMillis(date, hour, 0); + } + + private static int getThisYear() { + return new GregorianCalendar().get(GregorianCalendar.YEAR); + } + + @Test + public void testSameDateAndTime() { + assertEquals( + "3:00 AM", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + getFebOfThisYearInMillis(1, 3), + getFebOfThisYearInMillis(1, 3), + false, + DateUtils.FORMAT_12HOUR)); + assertEquals( + "03:00", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + getFebOfThisYearInMillis(1, 3), + getFebOfThisYearInMillis(1, 3), + false, + DateUtils.FORMAT_24HOUR)); + } + + @Test + public void testDurationWithinToday() { + assertEquals( + "12:00 – 3:00 AM", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + DATE_THIS_YEAR_2_1_MS, + getFebOfThisYearInMillis(1, 3), + false, + DateUtils.FORMAT_12HOUR)); + assertEquals( + "00:00 – 03:00", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + DATE_THIS_YEAR_2_1_MS, + getFebOfThisYearInMillis(1, 3), + false, + DateUtils.FORMAT_24HOUR)); + } + + @Test + public void testDurationFromYesterdayToToday() { + assertEquals( + "Jan 31, 3:00 AM – Feb 1, 4:00 AM", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + getJanOfThisYearInMillis(31, 3), + getFebOfThisYearInMillis(1, 4), + false, + DateUtils.FORMAT_12HOUR)); + assertEquals( + "Jan 31, 03:00 – Feb 1, 04:00", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + getJanOfThisYearInMillis(31, 3), + getFebOfThisYearInMillis(1, 4), + false, + DateUtils.FORMAT_24HOUR)); + assertEquals( + "1/31, 11:30 PM – 12:30 AM", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + getJanOfThisYearInMillis(31, 23, 30), + getFebOfThisYearInMillis(1, 0, 30), + true, + DateUtils.FORMAT_12HOUR)); + assertEquals( + "1/31, 23:30 – 00:30", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + getJanOfThisYearInMillis(31, 23, 30), + getFebOfThisYearInMillis(1, 0, 30), + true, + DateUtils.FORMAT_24HOUR)); + } + + @Test + public void testDurationFromTodayToTomorrow() { + assertEquals( + "Feb 1, 3:00 AM – Feb 2, 4:00 AM", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + getFebOfThisYearInMillis(1, 3), + getFebOfThisYearInMillis(2, 4), + false, + DateUtils.FORMAT_12HOUR)); + assertEquals( + "Feb 1, 03:00 – Feb 2, 04:00", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + getFebOfThisYearInMillis(1, 3), + getFebOfThisYearInMillis(2, 4), + false, + DateUtils.FORMAT_24HOUR)); + assertEquals( + "2/1, 3:00 AM – 2/2, 4:00 AM", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + getFebOfThisYearInMillis(1, 3), + getFebOfThisYearInMillis(2, 4), + true, + DateUtils.FORMAT_12HOUR)); + assertEquals( + "2/1, 03:00 – 2/2, 04:00", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + getFebOfThisYearInMillis(1, 3), + getFebOfThisYearInMillis(2, 4), + true, + DateUtils.FORMAT_24HOUR)); + + assertEquals( + "Feb 1, 11:30 PM – Feb 2, 12:30 AM", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + getFebOfThisYearInMillis(1, 23, 30), + getFebOfThisYearInMillis(2, 0, 30), + false, + DateUtils.FORMAT_12HOUR)); + assertEquals( + "Feb 1, 23:30 – Feb 2, 00:30", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + getFebOfThisYearInMillis(1, 23, 30), + getFebOfThisYearInMillis(2, 0, 30), + false, + DateUtils.FORMAT_24HOUR)); + assertEquals( + "11:30 PM – 12:30 AM", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + getFebOfThisYearInMillis(1, 23, 30), + getFebOfThisYearInMillis(2, 0, 30), + true, + DateUtils.FORMAT_12HOUR)); + assertEquals( + "23:30 – 00:30", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + getFebOfThisYearInMillis(1, 23, 30), + getFebOfThisYearInMillis(2, 0, 30), + true, + DateUtils.FORMAT_24HOUR)); + } + + @Test + public void testDurationWithinTomorrow() { + assertEquals( + "Feb 2, 2:00 – 4:00 AM", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + getFebOfThisYearInMillis(2, 2), + getFebOfThisYearInMillis(2, 4), + false, + DateUtils.FORMAT_12HOUR)); + assertEquals( + "Feb 2, 02:00 – 04:00", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + getFebOfThisYearInMillis(2, 2), + getFebOfThisYearInMillis(2, 4), + false, + DateUtils.FORMAT_24HOUR)); + assertEquals( + "2/2, 2:00 – 4:00 AM", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + getFebOfThisYearInMillis(2, 2), + getFebOfThisYearInMillis(2, 4), + true, + DateUtils.FORMAT_12HOUR)); + assertEquals( + "2/2, 02:00 – 04:00", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + getFebOfThisYearInMillis(2, 2), + getFebOfThisYearInMillis(2, 4), + true, + DateUtils.FORMAT_24HOUR)); + } + + @Test + public void testStartOfDay() { + assertEquals( + "12:00 – 1:00 AM", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + DATE_THIS_YEAR_2_1_MS, + getFebOfThisYearInMillis(1, 1), + false, + DateUtils.FORMAT_12HOUR)); + assertEquals( + "00:00 – 01:00", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + DATE_THIS_YEAR_2_1_MS, + getFebOfThisYearInMillis(1, 1), + false, + DateUtils.FORMAT_24HOUR)); + + assertEquals( + "Feb 2, 12:00 – 1:00 AM", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + getFebOfThisYearInMillis(2, 0), + getFebOfThisYearInMillis(2, 1), + false, + DateUtils.FORMAT_12HOUR)); + assertEquals( + "Feb 2, 00:00 – 01:00", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + getFebOfThisYearInMillis(2, 0), + getFebOfThisYearInMillis(2, 1), + false, + DateUtils.FORMAT_24HOUR)); + assertEquals( + "2/2, 12:00 – 1:00 AM", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + getFebOfThisYearInMillis(2, 0), + getFebOfThisYearInMillis(2, 1), + true, + DateUtils.FORMAT_12HOUR)); + assertEquals( + "2/2, 00:00 – 01:00", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + getFebOfThisYearInMillis(2, 0), + getFebOfThisYearInMillis(2, 1), + true, + DateUtils.FORMAT_24HOUR)); + } + + @Test + public void testEndOfDay() { + for (boolean useShortFormat : PARAM_USE_SHORT_FORMAT) { + assertEquals( + "11:00 PM – 12:00 AM", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + getFebOfThisYearInMillis(1, 23), + getFebOfThisYearInMillis(2, 0), + useShortFormat, + DateUtils.FORMAT_12HOUR)); + assertEquals( + "23:00 – 00:00", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + getFebOfThisYearInMillis(1, 23), + getFebOfThisYearInMillis(2, 0), + useShortFormat, + DateUtils.FORMAT_24HOUR)); + } + + assertEquals( + "Feb 2, 11:00 PM – 12:00 AM", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + getFebOfThisYearInMillis(2, 23), + getFebOfThisYearInMillis(3, 0), + false, + DateUtils.FORMAT_12HOUR)); + assertEquals( + "Feb 2, 23:00 – 00:00", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + getFebOfThisYearInMillis(2, 23), + getFebOfThisYearInMillis(3, 0), + false, + DateUtils.FORMAT_24HOUR)); + assertEquals( + "2/2, 11:00 PM – 12:00 AM", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + getFebOfThisYearInMillis(2, 23), + getFebOfThisYearInMillis(3, 0), + true, + DateUtils.FORMAT_12HOUR)); + assertEquals( + "2/2, 23:00 – 00:00", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + getFebOfThisYearInMillis(2, 23), + getFebOfThisYearInMillis(3, 0), + true, + DateUtils.FORMAT_24HOUR)); + assertEquals( + "2/2, 12:00 AM – 2/3, 12:00 AM", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + getFebOfThisYearInMillis(2, 0), + getFebOfThisYearInMillis(3, 0), + true, + DateUtils.FORMAT_12HOUR)); + assertEquals( + "2/2, 00:00 – 2/3, 00:00", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + getFebOfThisYearInMillis(2, 0), + getFebOfThisYearInMillis(3, 0), + true, + DateUtils.FORMAT_24HOUR)); + } + + @Test + public void testMidnight() { + for (boolean useShortFormat : PARAM_USE_SHORT_FORMAT) { + assertEquals( + "12:00 AM", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + DATE_THIS_YEAR_2_1_MS, + DATE_THIS_YEAR_2_1_MS, + useShortFormat, + DateUtils.FORMAT_12HOUR)); + assertEquals( + "00:00", + Utils.getDurationString( + getContext(), + DATE_THIS_YEAR_2_1_MS, + DATE_THIS_YEAR_2_1_MS, + DATE_THIS_YEAR_2_1_MS, + useShortFormat, + DateUtils.FORMAT_24HOUR)); + } + } +} diff --git a/tests/unit/src/com/android/tv/util/UtilsTest_GetMultiAudioString.java b/tests/unit/src/com/android/tv/util/UtilsTest_GetMultiAudioString.java new file mode 100644 index 00000000..79ed14c0 --- /dev/null +++ b/tests/unit/src/com/android/tv/util/UtilsTest_GetMultiAudioString.java @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2015 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.tv.util; + +import static android.support.test.InstrumentationRegistry.getTargetContext; +import static org.junit.Assert.assertEquals; + +import android.content.Context; +import android.media.tv.TvTrackInfo; +import android.support.test.filters.SmallTest; +import org.junit.Test; + +/** Tests for {@link com.android.tv.util.Utils#getMultiAudioString}. */ +@SmallTest +public class UtilsTest_GetMultiAudioString { + private static final String TRACK_ID = "test_track_id"; + private static final int AUDIO_SAMPLE_RATE = 48000; + + @Test + public void testAudioTrackLanguage() { + Context context = getTargetContext(); + assertEquals( + "Korean", Utils.getMultiAudioString(context, createAudioTrackInfo("kor"), false)); + assertEquals( + "English", Utils.getMultiAudioString(context, createAudioTrackInfo("eng"), false)); + assertEquals( + "Unknown language", + Utils.getMultiAudioString(context, createAudioTrackInfo(null), false)); + assertEquals( + "Unknown language", + Utils.getMultiAudioString(context, createAudioTrackInfo(""), false)); + assertEquals("abc", Utils.getMultiAudioString(context, createAudioTrackInfo("abc"), false)); + } + + @Test + public void testAudioTrackCount() { + Context context = getTargetContext(); + assertEquals( + "English", + Utils.getMultiAudioString(context, createAudioTrackInfo("eng", -1), false)); + assertEquals( + "English", + Utils.getMultiAudioString(context, createAudioTrackInfo("eng", 0), false)); + assertEquals( + "English (mono)", + Utils.getMultiAudioString(context, createAudioTrackInfo("eng", 1), false)); + assertEquals( + "English (stereo)", + Utils.getMultiAudioString(context, createAudioTrackInfo("eng", 2), false)); + assertEquals( + "English (3 channels)", + Utils.getMultiAudioString(context, createAudioTrackInfo("eng", 3), false)); + assertEquals( + "English (4 channels)", + Utils.getMultiAudioString(context, createAudioTrackInfo("eng", 4), false)); + assertEquals( + "English (5 channels)", + Utils.getMultiAudioString(context, createAudioTrackInfo("eng", 5), false)); + assertEquals( + "English (5.1 surround)", + Utils.getMultiAudioString(context, createAudioTrackInfo("eng", 6), false)); + assertEquals( + "English (7 channels)", + Utils.getMultiAudioString(context, createAudioTrackInfo("eng", 7), false)); + assertEquals( + "English (7.1 surround)", + Utils.getMultiAudioString(context, createAudioTrackInfo("eng", 8), false)); + } + + @Test + public void testShowSampleRate() { + assertEquals( + "Korean (48kHz)", + Utils.getMultiAudioString( + getTargetContext(), createAudioTrackInfo("kor", 0), true)); + assertEquals( + "Korean (7.1 surround, 48kHz)", + Utils.getMultiAudioString( + getTargetContext(), createAudioTrackInfo("kor", 8), true)); + } + + private static TvTrackInfo createAudioTrackInfo(String language) { + return createAudioTrackInfo(language, 0); + } + + private static TvTrackInfo createAudioTrackInfo(String language, int channelCount) { + return new TvTrackInfo.Builder(TvTrackInfo.TYPE_AUDIO, TRACK_ID) + .setLanguage(language) + .setAudioChannelCount(channelCount) + .setAudioSampleRate(AUDIO_SAMPLE_RATE) + .build(); + } +} diff --git a/tests/unit/src/com/android/tv/util/UtilsTest_IsInGivenDay.java b/tests/unit/src/com/android/tv/util/UtilsTest_IsInGivenDay.java new file mode 100644 index 00000000..cf0212cb --- /dev/null +++ b/tests/unit/src/com/android/tv/util/UtilsTest_IsInGivenDay.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2015 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.tv.util; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import android.support.test.filters.SmallTest; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.TimeZone; +import org.junit.Test; + +/** Tests for {@link com.android.tv.util.Utils#isInGivenDay}. */ +@SmallTest +public class UtilsTest_IsInGivenDay { + @Test + public void testIsInGivenDay() { + assertTrue( + Utils.isInGivenDay( + new GregorianCalendar(2015, Calendar.JANUARY, 1).getTimeInMillis(), + new GregorianCalendar(2015, Calendar.JANUARY, 1, 0, 30).getTimeInMillis())); + } + + @Test + public void testIsNotInGivenDay() { + assertFalse( + Utils.isInGivenDay( + new GregorianCalendar(2015, Calendar.JANUARY, 1).getTimeInMillis(), + new GregorianCalendar(2015, Calendar.JANUARY, 2).getTimeInMillis())); + } + + @Test + public void testIfTimeZoneApplied() { + TimeZone timeZone = TimeZone.getDefault(); + + TimeZone.setDefault(TimeZone.getTimeZone("Asia/Seoul")); + + // 2015.01.01 00:00 in KST = 2014.12.31 15:00 in UTC + long date2015StartMs = new GregorianCalendar(2015, Calendar.JANUARY, 1).getTimeInMillis(); + + // 2015.01.01 10:00 in KST = 2015.01.01 01:00 in UTC + long date2015Start10AMMs = + new GregorianCalendar(2015, Calendar.JANUARY, 1, 10, 0).getTimeInMillis(); + + // Those two times aren't in the same day in UTC, but they are in KST. + assertTrue(Utils.isInGivenDay(date2015StartMs, date2015Start10AMMs)); + + TimeZone.setDefault(timeZone); + } +} |