summaryrefslogtreecommitdiffstats
path: root/updater_sample/tests/src/com/example/android/systemupdatersample
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--updater_sample/tests/src/com/example/android/systemupdatersample/UpdateConfigTest.java122
-rw-r--r--updater_sample/tests/src/com/example/android/systemupdatersample/UpdateManagerTest.java155
-rw-r--r--updater_sample/tests/src/com/example/android/systemupdatersample/util/FileDownloaderTest.java80
-rw-r--r--updater_sample/tests/src/com/example/android/systemupdatersample/util/PayloadSpecsTest.java120
-rw-r--r--updater_sample/tests/src/com/example/android/systemupdatersample/util/UpdateConfigsTest.java53
5 files changed, 530 insertions, 0 deletions
diff --git a/updater_sample/tests/src/com/example/android/systemupdatersample/UpdateConfigTest.java b/updater_sample/tests/src/com/example/android/systemupdatersample/UpdateConfigTest.java
new file mode 100644
index 000000000..48d0e424d
--- /dev/null
+++ b/updater_sample/tests/src/com/example/android/systemupdatersample/UpdateConfigTest.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2018 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.example.android.systemupdatersample;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.example.android.systemupdatersample.tests.R;
+import com.google.common.io.CharStreams;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+/**
+ * Tests for {@link UpdateConfig}
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class UpdateConfigTest {
+
+ private static final String JSON_NON_STREAMING = "{"
+ + " \"name\": \"vip update\", \"url\": \"file:///my-builds/a.zip\","
+ + " \"ab_install_type\": \"NON_STREAMING\","
+ + " \"ab_config\": {"
+ + " \"force_switch_slot\": false,"
+ + " \"verify_payload_metadata\": false } }";
+
+ @Rule
+ public final ExpectedException thrown = ExpectedException.none();
+
+ private Context mContext;
+ private Context mTargetContext;
+ private String mJsonStreaming001;
+
+ @Before
+ public void setUp() throws Exception {
+ mContext = InstrumentationRegistry.getContext();
+ mTargetContext = InstrumentationRegistry.getTargetContext();
+ mJsonStreaming001 = readResource(R.raw.update_config_001_stream);
+ }
+
+ @Test
+ public void fromJson_parsesNonStreaming() throws Exception {
+ UpdateConfig config = UpdateConfig.fromJson(JSON_NON_STREAMING);
+ assertEquals("name is parsed", "vip update", config.getName());
+ assertEquals("stores raw json", JSON_NON_STREAMING, config.getRawJson());
+ assertSame("type is parsed",
+ UpdateConfig.AB_INSTALL_TYPE_NON_STREAMING,
+ config.getInstallType());
+ assertEquals("url is parsed", "file:///my-builds/a.zip", config.getUrl());
+ }
+
+ @Test
+ public void fromJson_parsesStreaming() throws Exception {
+ UpdateConfig config = UpdateConfig.fromJson(mJsonStreaming001);
+ assertEquals("streaming-001", config.getName());
+ assertEquals("http://foo.bar/update.zip", config.getUrl());
+ assertSame(UpdateConfig.AB_INSTALL_TYPE_STREAMING, config.getInstallType());
+ assertEquals("payload.bin",
+ config.getAbConfig().getPropertyFiles()[0].getFilename());
+ assertEquals(195, config.getAbConfig().getPropertyFiles()[0].getOffset());
+ assertEquals(8, config.getAbConfig().getPropertyFiles()[0].getSize());
+ assertTrue(config.getAbConfig().getForceSwitchSlot());
+ }
+
+ @Test
+ public void getUpdatePackageFile_throwsErrorIfStreaming() throws Exception {
+ UpdateConfig config = UpdateConfig.fromJson(mJsonStreaming001);
+ thrown.expect(RuntimeException.class);
+ config.getUpdatePackageFile();
+ }
+
+ @Test
+ public void getUpdatePackageFile_throwsErrorIfNotAFile() throws Exception {
+ String json = "{"
+ + " \"name\": \"upd\", \"url\": \"http://foo.bar\","
+ + " \"ab_install_type\": \"NON_STREAMING\","
+ + " \"ab_config\": {"
+ + " \"force_switch_slot\": false,"
+ + " \"verify_payload_metadata\": false } }";
+ UpdateConfig config = UpdateConfig.fromJson(json);
+ thrown.expect(RuntimeException.class);
+ config.getUpdatePackageFile();
+ }
+
+ @Test
+ public void getUpdatePackageFile_works() throws Exception {
+ UpdateConfig c = UpdateConfig.fromJson(JSON_NON_STREAMING);
+ assertEquals("/my-builds/a.zip", c.getUpdatePackageFile().getAbsolutePath());
+ }
+
+ private String readResource(int id) throws IOException {
+ return CharStreams.toString(new InputStreamReader(
+ mContext.getResources().openRawResource(id)));
+ }
+}
diff --git a/updater_sample/tests/src/com/example/android/systemupdatersample/UpdateManagerTest.java b/updater_sample/tests/src/com/example/android/systemupdatersample/UpdateManagerTest.java
new file mode 100644
index 000000000..5ad16d477
--- /dev/null
+++ b/updater_sample/tests/src/com/example/android/systemupdatersample/UpdateManagerTest.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2018 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.example.android.systemupdatersample;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.ResultReceiver;
+import android.os.UpdateEngine;
+import android.os.UpdateEngineCallback;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.annotation.UiThreadTest;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.example.android.systemupdatersample.services.PrepareUpdateService;
+import com.example.android.systemupdatersample.tests.R;
+import com.google.common.collect.ImmutableList;
+import com.google.common.io.CharStreams;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+/**
+ * Tests for {@link UpdateManager}
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class UpdateManagerTest {
+
+ @Rule
+ public MockitoRule mockito = MockitoJUnit.rule();
+
+ @Mock
+ private UpdateEngine mUpdateEngine;
+ @Mock
+ private Context mMockContext;
+ private UpdateManager mSubject;
+ private Context mTestContext;
+ private UpdateConfig mStreamingUpdate002;
+
+ @Before
+ public void setUp() throws Exception {
+ mTestContext = InstrumentationRegistry.getContext();
+ mSubject = new UpdateManager(mUpdateEngine, null);
+ mStreamingUpdate002 =
+ UpdateConfig.fromJson(readResource(R.raw.update_config_002_stream));
+ }
+
+ @Test
+ public void applyUpdate_appliesPayloadToUpdateEngine() throws Exception {
+ mockContextStartServiceAnswer(buildMockPayloadSpec());
+ mSubject.applyUpdate(mMockContext, mStreamingUpdate002);
+
+ verify(mUpdateEngine).applyPayload(
+ "file://blah",
+ 120,
+ 340,
+ new String[]{
+ "SWITCH_SLOT_ON_REBOOT=0", // ab_config.force_switch_slot = false
+ "USER_AGENT=" + UpdateManager.HTTP_USER_AGENT
+ });
+ }
+
+ @Test
+ @UiThreadTest
+ public void stateIsRunningAndEngineStatusIsIdle_reApplyLastUpdate() throws Throwable {
+ mockContextStartServiceAnswer(buildMockPayloadSpec());
+ // UpdateEngine always returns IDLE status.
+ when(mUpdateEngine.bind(any(UpdateEngineCallback.class))).thenAnswer(answer -> {
+ // When UpdateManager is bound to update_engine, it passes
+ // UpdateEngineCallback as a callback to update_engine.
+ UpdateEngineCallback callback = answer.getArgument(0);
+ callback.onStatusUpdate(
+ UpdateEngine.UpdateStatusConstants.IDLE,
+ /*engineProgress*/ 0.0f);
+ return null;
+ });
+
+ mSubject.bind();
+ mSubject.applyUpdate(mMockContext, mStreamingUpdate002);
+ mSubject.unbind();
+ mSubject.bind(); // re-bind - now it should re-apply last update
+
+ assertEquals(mSubject.getUpdaterState(), UpdaterState.RUNNING);
+ verify(mUpdateEngine, times(2)).applyPayload(
+ "file://blah",
+ 120,
+ 340,
+ new String[]{
+ "SWITCH_SLOT_ON_REBOOT=0", // ab_config.force_switch_slot = false
+ "USER_AGENT=" + UpdateManager.HTTP_USER_AGENT
+ });
+ }
+
+ private void mockContextStartServiceAnswer(PayloadSpec payloadSpec) {
+ doAnswer(args -> {
+ Intent intent = args.getArgument(0);
+ ResultReceiver resultReceiver = intent.getParcelableExtra(
+ PrepareUpdateService.EXTRA_PARAM_RESULT_RECEIVER);
+ Bundle b = new Bundle();
+ b.putSerializable(
+ /* PrepareUpdateService.CallbackResultReceiver.BUNDLE_PARAM_PAYLOAD_SPEC */
+ "payload-spec",
+ payloadSpec);
+ resultReceiver.send(PrepareUpdateService.RESULT_CODE_SUCCESS, b);
+ return null;
+ }).when(mMockContext).startService(any(Intent.class));
+ }
+
+ private PayloadSpec buildMockPayloadSpec() {
+ PayloadSpec payload = mock(PayloadSpec.class);
+ when(payload.getUrl()).thenReturn("file://blah");
+ when(payload.getOffset()).thenReturn(120L);
+ when(payload.getSize()).thenReturn(340L);
+ when(payload.getProperties()).thenReturn(ImmutableList.of());
+ return payload;
+ }
+
+ private String readResource(int id) throws IOException {
+ return CharStreams.toString(new InputStreamReader(
+ mTestContext.getResources().openRawResource(id)));
+ }
+
+}
diff --git a/updater_sample/tests/src/com/example/android/systemupdatersample/util/FileDownloaderTest.java b/updater_sample/tests/src/com/example/android/systemupdatersample/util/FileDownloaderTest.java
new file mode 100644
index 000000000..a136ff0ed
--- /dev/null
+++ b/updater_sample/tests/src/com/example/android/systemupdatersample/util/FileDownloaderTest.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2018 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.example.android.systemupdatersample.util;
+
+import static org.junit.Assert.assertEquals;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.example.android.systemupdatersample.tests.R;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+/**
+ * Tests for {@link FileDownloader}
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class FileDownloaderTest {
+
+ @Rule
+ public final ExpectedException thrown = ExpectedException.none();
+
+ private Context mTestContext;
+ private Context mTargetContext;
+
+ @Before
+ public void setUp() {
+ mTestContext = InstrumentationRegistry.getContext();
+ mTargetContext = InstrumentationRegistry.getTargetContext();
+ }
+
+ @Test
+ public void download_downloadsChunkOfZip() throws Exception {
+ // Prepare the target file
+ File packageFile = Paths
+ .get(mTargetContext.getCacheDir().getAbsolutePath(), "ota.zip")
+ .toFile();
+ Files.deleteIfExists(packageFile.toPath());
+ Files.copy(mTestContext.getResources().openRawResource(R.raw.ota_002_package),
+ packageFile.toPath());
+ String url = "file://" + packageFile.getAbsolutePath();
+ // prepare where to download
+ File outFile = Paths
+ .get(mTargetContext.getCacheDir().getAbsolutePath(), "care_map.txt")
+ .toFile();
+ Files.deleteIfExists(outFile.toPath());
+ // download a chunk of ota.zip
+ FileDownloader downloader = new FileDownloader(url, 1674, 12, outFile);
+ downloader.download();
+ String downloadedContent = String.join("\n", Files.readAllLines(outFile.toPath()));
+ // archive contains text files with uppercase filenames
+ assertEquals("CARE_MAP-TXT", downloadedContent);
+ }
+
+}
diff --git a/updater_sample/tests/src/com/example/android/systemupdatersample/util/PayloadSpecsTest.java b/updater_sample/tests/src/com/example/android/systemupdatersample/util/PayloadSpecsTest.java
new file mode 100644
index 000000000..03086930e
--- /dev/null
+++ b/updater_sample/tests/src/com/example/android/systemupdatersample/util/PayloadSpecsTest.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2018 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.example.android.systemupdatersample.util;
+
+import static com.example.android.systemupdatersample.util.PackageFiles.PAYLOAD_BINARY_FILE_NAME;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import android.content.Context;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.example.android.systemupdatersample.PayloadSpec;
+import com.example.android.systemupdatersample.tests.R;
+import com.google.common.base.Charsets;
+import com.google.common.io.Files;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Paths;
+
+/**
+ * Tests if PayloadSpecs parses update package zip file correctly.
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class PayloadSpecsTest {
+
+ private static final String PROPERTIES_CONTENTS = "k1=val1\nkey2=val2";
+
+ private File mTestDir;
+
+ private Context mTargetContext;
+ private Context mTestContext;
+
+ private PayloadSpecs mPayloadSpecs;
+
+ @Rule
+ public final ExpectedException thrown = ExpectedException.none();
+
+ @Before
+ public void setUp() {
+ mTargetContext = InstrumentationRegistry.getTargetContext();
+ mTestContext = InstrumentationRegistry.getContext();
+
+ mTestDir = mTargetContext.getCacheDir();
+ mPayloadSpecs = new PayloadSpecs();
+ }
+
+ @Test
+ public void forNonStreaming_works() throws Exception {
+ // Prepare the target file
+ File packageFile = Paths
+ .get(mTargetContext.getCacheDir().getAbsolutePath(), "ota.zip")
+ .toFile();
+ java.nio.file.Files.deleteIfExists(packageFile.toPath());
+ java.nio.file.Files.copy(mTestContext.getResources().openRawResource(R.raw.ota_002_package),
+ packageFile.toPath());
+ PayloadSpec spec = mPayloadSpecs.forNonStreaming(packageFile);
+
+ assertEquals("correct url", "file://" + packageFile.getAbsolutePath(), spec.getUrl());
+ assertEquals("correct payload offset",
+ 30 + PAYLOAD_BINARY_FILE_NAME.length(), spec.getOffset());
+ assertEquals("correct payload size", 1392, spec.getSize());
+ assertEquals(4, spec.getProperties().size());
+ assertEquals(
+ "FILE_HASH=sEAK/NMbU7GGe01xt55FsPafIPk8IYyBOAd6SiDpiMs=",
+ spec.getProperties().get(0));
+ }
+
+ @Test
+ public void forNonStreaming_IOException() throws Exception {
+ thrown.expect(IOException.class);
+ mPayloadSpecs.forNonStreaming(new File("/fake/news.zip"));
+ }
+
+ @Test
+ public void forStreaming_works() throws Exception {
+ String url = "http://a.com/b.zip";
+ long offset = 45;
+ long size = 200;
+ File propertiesFile = createMockPropertiesFile();
+
+ PayloadSpec spec = mPayloadSpecs.forStreaming(url, offset, size, propertiesFile);
+ assertEquals("same url", url, spec.getUrl());
+ assertEquals("same offset", offset, spec.getOffset());
+ assertEquals("same size", size, spec.getSize());
+ assertArrayEquals("correct properties",
+ new String[]{"k1=val1", "key2=val2"}, spec.getProperties().toArray(new String[0]));
+ }
+
+ private File createMockPropertiesFile() throws IOException {
+ File propertiesFile = new File(mTestDir, PackageFiles.PAYLOAD_PROPERTIES_FILE_NAME);
+ Files.asCharSink(propertiesFile, Charsets.UTF_8).write(PROPERTIES_CONTENTS);
+ return propertiesFile;
+ }
+
+}
diff --git a/updater_sample/tests/src/com/example/android/systemupdatersample/util/UpdateConfigsTest.java b/updater_sample/tests/src/com/example/android/systemupdatersample/util/UpdateConfigsTest.java
new file mode 100644
index 000000000..4ccae9380
--- /dev/null
+++ b/updater_sample/tests/src/com/example/android/systemupdatersample/util/UpdateConfigsTest.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2018 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.example.android.systemupdatersample.util;
+
+import static org.junit.Assert.assertArrayEquals;
+
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.example.android.systemupdatersample.UpdateConfig;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * Tests for {@link UpdateConfigs}
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class UpdateConfigsTest {
+
+ @Rule
+ public final ExpectedException thrown = ExpectedException.none();
+
+ @Test
+ public void configsToNames_extractsNames() {
+ List<UpdateConfig> configs = Arrays.asList(
+ new UpdateConfig("blah", "http://", UpdateConfig.AB_INSTALL_TYPE_NON_STREAMING),
+ new UpdateConfig("blah 2", "http://", UpdateConfig.AB_INSTALL_TYPE_STREAMING)
+ );
+ String[] names = UpdateConfigs.configsToNames(configs);
+ assertArrayEquals(new String[] {"blah", "blah 2"}, names);
+ }
+}