Merge "startop: Add iorapd binder integration test"

This commit is contained in:
Treehugger Robot
2018-10-04 17:46:47 +00:00
committed by Gerrit Code Review
5 changed files with 210 additions and 24 deletions

View File

@@ -26,26 +26,3 @@ java_library_static {
"**/*.java",
],
}
android_test {
name: "libiorap-java-tests",
srcs: ["tests/src/**/*.kt"],
static_libs: [
// non-test dependencies
"libiorap-java",
// test android dependencies
"platform-test-annotations",
"android-support-test",
// test framework dependencies
"mockito-target-inline-minus-junit4",
"truth-prebuilt",
],
//sdk_version: "current",
//certificate: "platform",
libs: ["android.test.base"],
test_suites: ["device-tests"],
}

View File

@@ -0,0 +1,40 @@
// 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.
// TODO: once b/80095087 is fixed, rewrite this back to android_test
java_library {
name: "libiorap-java-test-lib",
srcs: ["src/**/*.kt"],
static_libs: [
// non-test dependencies
"libiorap-java",
// test android dependencies
"platform-test-annotations",
"android-support-test",
// test framework dependencies
"mockito-target-inline-minus-junit4",
// "mockito-target-minus-junit4",
// Mockito also requires JNI (see Android.mk)
// and android:debuggable=true (see AndroidManifest.xml)
"truth-prebuilt",
],
// sdk_version: "current",
// certificate: "platform",
libs: ["android.test.base", "android.test.runner"],
// test_suites: ["device-tests"],
}

View File

@@ -0,0 +1,46 @@
# 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.
# android_test does not support JNI libraries
# TODO: once b/80095087 is fixed, rewrite this back to android_test
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := tests
LOCAL_JACK_FLAGS := --multi-dex native
LOCAL_DX_FLAGS := --multi-dex
LOCAL_PACKAGE_NAME := libiorap-java-tests
LOCAL_COMPATIBILITY_SUITE := device-tests
LOCAL_STATIC_JAVA_LIBRARIES := \
libiorap-java-test-lib
LOCAL_MULTILIB := both
LOCAL_JNI_SHARED_LIBRARIES := \
libdexmakerjvmtiagent \
libstaticjvmtiagent \
libmultiplejvmtiagentsinterferenceagent
LOCAL_JAVA_LIBRARIES := \
android.test.base \
android.test.runner
# Use private APIs
LOCAL_CERTIFICATE := platform
LOCAL_PRIVATE_PLATFORM_APIS := true
include $(BUILD_PACKAGE)

View File

@@ -25,7 +25,13 @@
android:name="android.support.test.runner.AndroidJUnitRunner"
android:targetPackage="com.google.android.startop.iorap.tests" />
<application>
<!--
'debuggable=true' is required to properly load mockito jvmti dependencies,
otherwise it gives the following error at runtime:
Openjdkjvmti plugin was loaded on a non-debuggable Runtime.
Plugin was loaded too late to change runtime state to DEBUGGABLE. -->
<application android:debuggable="true">
<uses-library android:name="android.test.runner" />
</application>
</manifest>

View File

@@ -0,0 +1,117 @@
/*
* 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.google.android.startop.iorap
import android.net.Uri
import android.os.ServiceManager
import android.support.test.filters.MediumTest
import org.junit.Test
import org.junit.Ignore
import org.mockito.Mockito.*
// @Ignore("Test is disabled until iorapd is added to init and there's selinux policies for it")
@MediumTest
class IIorapIntegrationTest {
/**
* @throws ServiceManager.ServiceNotFoundException if iorapd service could not be found
*/
private val iorapService : IIorap by lazy {
// TODO: connect to 'iorapd.stub' which doesn't actually do any work other than reply.
IIorap.Stub.asInterface(ServiceManager.getServiceOrThrow("iorapd"))
// Use 'adb shell setenforce 0' otherwise this whole test fails,
// because the servicemanager is not allowed to hand out the binder token for iorapd.
// TODO: implement the selinux policies for iorapd.
}
// A dummy binder stub implementation is required to use with mockito#spy.
// Mockito overrides the methods at runtime and tracks how methods were invoked.
open class DummyTaskListener : ITaskListener.Stub() {
// Note: make parameters nullable to avoid the kotlin IllegalStateExceptions
// from using the mockito matchers (eq, argThat, etc).
override fun onProgress(requestId: RequestId?, result: TaskResult?) {
}
override fun onComplete(requestId: RequestId?, result: TaskResult?) {
}
}
private fun testAnyMethod(func : (RequestId) -> Unit) {
val taskListener = spy(DummyTaskListener())!!
try {
iorapService.setTaskListener(taskListener)
// Note: Binder guarantees total order for oneway messages sent to the same binder
// interface, so we don't need any additional blocking here before sending later calls.
// Every new method call should have a unique request id.
val requestId = RequestId.nextValueForSequence()!!
// Apply the specific function under test.
func(requestId)
// Typical mockito behavior is to allow any-order callbacks, but we want to test order.
val inOrder = inOrder(taskListener)
// The "stub" behavior of iorapd is that every request immediately gets a response of
// BEGAN,ONGOING,COMPLETED
inOrder.verify(taskListener, timeout(100)).
onProgress(eq(requestId), argThat { it!!.state == TaskResult.STATE_BEGAN })
inOrder.verify(taskListener, timeout(100)).
onProgress(eq(requestId), argThat { it!!.state == TaskResult.STATE_ONGOING })
inOrder.verify(taskListener, timeout(100)).
onComplete(eq(requestId), argThat { it!!.state == TaskResult.STATE_COMPLETED })
inOrder.verifyNoMoreInteractions()
} finally {
iorapService.setTaskListener(null)
}
}
@Test
fun testOnPackageEvent() {
testAnyMethod { requestId : RequestId ->
iorapService.onPackageEvent(requestId,
PackageEvent.createReplaced(
Uri.parse("https://www.google.com"), "com.fake.package"))
}
}
@Test
fun testOnAppIntentEvent() {
testAnyMethod { requestId : RequestId ->
iorapService.onAppIntentEvent(requestId, AppIntentEvent.createDefaultIntentChanged(
ActivityInfo("dont care", "dont care"),
ActivityInfo("dont care 2", "dont care 2")))
}
}
@Test
fun testOnSystemServiceEvent() {
testAnyMethod { requestId : RequestId ->
iorapService.onSystemServiceEvent(requestId,
SystemServiceEvent(SystemServiceEvent.TYPE_START))
}
}
@Test
fun testOnSystemServiceUserEvent() {
testAnyMethod { requestId : RequestId ->
iorapService.onSystemServiceUserEvent(requestId,
SystemServiceUserEvent(SystemServiceUserEvent.TYPE_START_USER,0))
}
}
}