blob: 578e6cae6464c8f0ea7c396b45dd9105ac1b238d [file] [log] [blame]
/*
* 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 com.android.networkstack.metrics
import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
import android.net.captiveportal.CaptivePortalProbeResult
import android.net.metrics.ValidationProbeEvent
import android.net.util.DataStallUtils.DATA_STALL_EVALUATION_TYPE_DNS
import android.telephony.TelephonyManager
import androidx.test.filters.SmallTest
import androidx.test.runner.AndroidJUnit4
import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
import com.android.dx.mockito.inline.extended.ExtendedMockito.verify
import com.android.server.connectivity.nano.CellularData
import com.android.server.connectivity.nano.DataStallEventProto
import com.android.server.connectivity.nano.DnsEvent
import com.google.protobuf.nano.MessageNano
import java.util.Arrays
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.eq
@RunWith(AndroidJUnit4::class)
@SmallTest
class DataStallStatsUtilsTest {
private val TEST_ELAPSED_TIME_MS = 123456789L
private val TEST_MCCMNC = "123456"
private val TEST_SIGNAL_STRENGTH = -100
private val RETURN_CODE_DNS_TIMEOUT = 255
@Test
fun testProbeResultToEnum() {
assertEquals(DataStallStatsUtils.probeResultToEnum(null), DataStallEventProto.INVALID)
// Metrics cares only http response code.
assertEquals(DataStallStatsUtils.probeResultToEnum(
CaptivePortalProbeResult.failed(ValidationProbeEvent.PROBE_HTTP)),
DataStallEventProto.INVALID)
assertEquals(DataStallStatsUtils.probeResultToEnum(
CaptivePortalProbeResult.failed(ValidationProbeEvent.PROBE_HTTPS)),
DataStallEventProto.INVALID)
assertEquals(DataStallStatsUtils.probeResultToEnum(
CaptivePortalProbeResult.success(ValidationProbeEvent.PROBE_HTTP)),
DataStallEventProto.VALID)
assertEquals(DataStallStatsUtils.probeResultToEnum(
CaptivePortalProbeResult.success(ValidationProbeEvent.PROBE_HTTP)),
DataStallEventProto.VALID)
assertEquals(DataStallStatsUtils.probeResultToEnum(CaptivePortalProbeResult.PARTIAL),
DataStallEventProto.PARTIAL)
assertEquals(DataStallStatsUtils.probeResultToEnum(CaptivePortalProbeResult(
CaptivePortalProbeResult.PORTAL_CODE, ValidationProbeEvent.PROBE_HTTP)),
DataStallEventProto.PORTAL)
assertEquals(DataStallStatsUtils.probeResultToEnum(CaptivePortalProbeResult(
CaptivePortalProbeResult.PORTAL_CODE, ValidationProbeEvent.PROBE_HTTPS)),
DataStallEventProto.PORTAL)
}
@Test
fun testWrite() {
val session = mockitoSession().spyStatic(NetworkStackStatsLog::class.java).startMocking()
val stats = DataStallDetectionStats.Builder()
.setEvaluationType(DATA_STALL_EVALUATION_TYPE_DNS)
.setNetworkType(TRANSPORT_CELLULAR)
.setCellData(TelephonyManager.NETWORK_TYPE_LTE /* radioType */,
true /* roaming */,
TEST_MCCMNC /* networkMccmnc */,
TEST_MCCMNC /* simMccmnc */,
TEST_SIGNAL_STRENGTH /* signalStrength */)
.setTcpFailRate(90)
.setTcpSentSinceLastRecv(10)
generateTimeoutDnsEvent(stats, count = 5)
DataStallStatsUtils.write(stats.build(), CaptivePortalProbeResult.PARTIAL)
verify { NetworkStackStatsLog.write(
eq(NetworkStackStatsLog.DATA_STALL_EVENT),
eq(DATA_STALL_EVALUATION_TYPE_DNS),
eq(DataStallEventProto.PARTIAL),
eq(TRANSPORT_CELLULAR),
eq(DataStallDetectionStats.emptyWifiInfoIfNull(null)),
eq(makeTestCellDataNano()),
eq(makeTestDnsTimeoutNano(5)),
eq(90) /* tcpFailRate */,
eq(10) /* tcpSentSinceLastRecv */) }
session.finishMocking()
}
private fun makeTestDnsTimeoutNano(timeoutCount: Int): ByteArray? {
// Make an expected nano dns message.
val event = DnsEvent()
event.dnsReturnCode = IntArray(timeoutCount)
event.dnsTime = LongArray(timeoutCount)
Arrays.fill(event.dnsReturnCode, RETURN_CODE_DNS_TIMEOUT)
Arrays.fill(event.dnsTime, TEST_ELAPSED_TIME_MS)
return MessageNano.toByteArray(event)
}
private fun makeTestCellDataNano(): ByteArray? {
// Make an expected nano cell data message.
val data = CellularData()
data.ratType = DataStallEventProto.RADIO_TECHNOLOGY_LTE
data.networkMccmnc = TEST_MCCMNC
data.simMccmnc = TEST_MCCMNC
data.isRoaming = true
data.signalStrength = TEST_SIGNAL_STRENGTH
return MessageNano.toByteArray(data)
}
private fun generateTimeoutDnsEvent(stats: DataStallDetectionStats.Builder, count: Int) {
repeat(count) {
stats.addDnsEvent(RETURN_CODE_DNS_TIMEOUT, TEST_ELAPSED_TIME_MS)
}
}
}