Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bb59253d authored by Remi NGUYEN VAN's avatar Remi NGUYEN VAN
Browse files

Add ConnectivityServiceIntegrationTest

This test exercises the Connectivity <-> NetworkMonitor integration.
This CL only contains a simple test (network validates), but more
generally it sets up a test package that contains both services.jar
classes and NetworkStack classes, and runs NetworkStack components in
another process (using TestNetworkStackService).

ConnectivityServiceIntegrationTest runs in the test process and binds to
TestNetworkStackService to obtain TestNetworkStackConnector and to
NetworkStackInstrumentationService to obtain
NetworkStackInstrumentationConnector. That last connector allows the
test to mock NetworkMonitor HTTP Requests.

Test: atest FrameworksNetIntegrationTests
Change-Id: Ieca18e273609044cf6b1870d2f0dba33ca7b38d3
parent 1566e186
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -2164,7 +2164,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
        }
    }

    void systemReady() {
    /**
     * Called when the system is ready and ConnectivityService can initialize remaining components.
     */
    @VisibleForTesting
    public void systemReady() {
        mProxyTracker.loadGlobalProxy();
        registerNetdEventCallback();
        mTethering.systemReady();
+33 −0
Original line number Diff line number Diff line
@@ -14,6 +14,39 @@
// limitations under the License.
//

android_test {
    name: "FrameworksNetIntegrationTests",
    platform_apis: true,
    certificate: "platform",
    srcs: [
        "src/**/*.kt",
        "src/**/*.aidl",
    ],
    libs: [
        "android.test.mock",
    ],
    static_libs: [
        "TestNetworkStackLib",
        "androidx.test.ext.junit",
        "frameworks-net-integration-testutils",
        "kotlin-reflect",
        "mockito-target-extended-minus-junit4",
        "net-tests-utils",
        "services.core",
        "services.net",
        "testables",
    ],
    use_embedded_native_libs: true,
    jni_libs: [
        // For mockito extended
        "libdexmakerjvmtiagent",
        "libstaticjvmtiagent",
        // android_library does not include JNI libs: include NetworkStack dependencies here
        "libnativehelper_compat_libc++",
        "libnetworkstackutilsjni",
    ],
}

// Utilities for testing framework code both in integration and unit tests.
java_library {
    name: "frameworks-net-integration-testutils",
+58 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools"
          package="com.android.server.net.integrationtests">

    <!-- For ConnectivityService registerReceiverAsUser (receiving broadcasts) -->
    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
    <!-- PermissionMonitor sets network permissions for each user -->
    <uses-permission android:name="android.permission.MANAGE_USERS" />
    <!-- ConnectivityService sends notifications to BatteryStats -->
    <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
    <application android:debuggable="true">
        <uses-library android:name="android.test.runner" />

        <!-- This manifest is merged with the base manifest of the real NetworkStack app.
             Remove the NetworkStackService from the base (real) manifest, and replace with a test
             service that responds to the same intent -->
        <service android:name="com.android.server.NetworkStackService" tools:node="remove"/>
        <service android:name=".TestNetworkStackService"
                 android:process="com.android.server.net.integrationtests.testnetworkstack">
            <intent-filter>
                <action android:name="android.net.INetworkStackConnector.Test"/>
            </intent-filter>
        </service>
        <service android:name=".NetworkStackInstrumentationService"
                 android:process="com.android.server.net.integrationtests.testnetworkstack">
            <intent-filter>
                <action android:name=".INetworkStackInstrumentation"/>
            </intent-filter>
        </service>
        <service tools:replace="android:process"
                 android:name="com.android.server.connectivity.ipmemorystore.RegularMaintenanceJobService"
                 android:process="com.android.server.net.integrationtests.testnetworkstack"/>

    </application>

    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
                     android:targetPackage="com.android.server.net.integrationtests"
                     android:label="Frameworks Net Integration Tests" />

</manifest>
+15 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!--
    Override configuration for testing. The below settings use the config_ variants, which are
    normally used by RROs to override the setting with highest priority. -->
    <integer name="config_captive_portal_dns_probe_timeout">12500</integer>
    <string name="config_captive_portal_http_url" translatable="false">http://test.android.com</string>
    <string name="config_captive_portal_https_url" translatable="false">https://secure.test.android.com</string>
    <string-array name="config_captive_portal_fallback_urls" translatable="false">
        <item>http://fallback1.android.com</item>
        <item>http://fallback2.android.com</item>
    </string-array>
    <string-array name="config_captive_portal_fallback_probe_specs" translatable="false">
    </string-array>
</resources>
+80 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package android.net

import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.os.IBinder
import com.android.server.net.integrationtests.TestNetworkStackService
import org.mockito.Mockito.any
import org.mockito.Mockito.spy
import org.mockito.Mockito.timeout
import org.mockito.Mockito.verify
import kotlin.test.fail

const val TEST_ACTION_SUFFIX = ".Test"

class TestNetworkStackClient(context: Context) : NetworkStackClient(TestDependencies(context)) {
    // TODO: consider switching to TrackRecord for more expressive checks
    private val lastCallbacks = HashMap<Network, INetworkMonitorCallbacks>()

    private class TestDependencies(private val context: Context) : Dependencies {
        override fun addToServiceManager(service: IBinder) = Unit
        override fun checkCallerUid() = Unit

        override fun getConnectivityModuleConnector(): ConnectivityModuleConnector {
            return ConnectivityModuleConnector { _, _, _, inSystemProcess ->
                getNetworkStackIntent(inSystemProcess)
            }.also { it.init(context) }
        }

        private fun getNetworkStackIntent(inSystemProcess: Boolean): Intent? {
            // Simulate out-of-system-process config: in-process service not found (null intent)
            if (inSystemProcess) return null
            val intent = Intent(INetworkStackConnector::class.qualifiedName + TEST_ACTION_SUFFIX)
            val serviceName = TestNetworkStackService::class.qualifiedName
                    ?: fail("TestNetworkStackService name not found")
            intent.component = ComponentName(context.packageName, serviceName)
            return intent
        }
    }

    // base may be an instance of an inaccessible subclass, so non-spyable.
    // Use a known open class that delegates to the original instance for all methods except
    // asBinder. asBinder needs to use its own non-delegated implementation as otherwise it would
    // return a binder token to a class that is not spied on.
    open class NetworkMonitorCallbacksWrapper(private val base: INetworkMonitorCallbacks) :
            INetworkMonitorCallbacks.Stub(), INetworkMonitorCallbacks by base {
        // asBinder is implemented by both base class and delegate: specify explicitly
        override fun asBinder(): IBinder {
            return super.asBinder()
        }
    }

    override fun makeNetworkMonitor(network: Network, name: String?, cb: INetworkMonitorCallbacks) {
        val cbSpy = spy(NetworkMonitorCallbacksWrapper(cb))
        lastCallbacks[network] = cbSpy
        super.makeNetworkMonitor(network, name, cbSpy)
    }

    fun verifyNetworkMonitorCreated(network: Network, timeoutMs: Long) {
        val cb = lastCallbacks[network]
                ?: fail("NetworkMonitor for network $network not requested")
        verify(cb, timeout(timeoutMs)).onNetworkMonitorCreated(any())
    }
}
 No newline at end of file
Loading