Skip to main content

Speed Test

KapeSpeedTest measures download, upload and latency against a Kape server. It is published as its own artifact, com.kape:kape-speed-test, which depends on kape-core only, so it adds no tunnel native libraries. The fused kape-platform-sdk already includes it.

val speedTest = KapeSpeedTest(handle)

// In a coroutine (e.g. viewModelScope.launch):
when (val outcome = speedTest.run(locationId = null) { progress -> render(progress) }) {
is RunSpeedTestResult.Success -> show(outcome.result)
RunSpeedTestResult.Cancelled -> { /* speedTest.cancel() was called */ }
is RunSpeedTestResult.Error -> showError(outcome.error)
}

Choosing the server​

  • locationId = null lets the SDK pick a server near the user.
  • A location ID from KapeLocationService.allLocations tests that location. The test runs over TCP, because not every server answers the UDP probe.
  • A Dedicated IP location's ID is its IP address, which the speed test cannot resolve. Pass the catalog location the Dedicated IP belongs to, or null.

result.server is the server actually tested. Its locationId can differ from the one you asked for.

The test measures whatever network the device is on. To measure through the VPN, connect first. To measure the ISP, disconnect first.

Progress​

onProgress is called in order, in the caller's coroutine context, and never after run returns.

EventMeaning
ServerSelected(server, ping)The SDK picked the server. It can repeat if the SDK retries the run; the latest one wins.
Download(currentMbps, gaugeMaxMbps)Live download throughput. gaugeMaxMbps is a suggested scale for a gauge. It can change between updates or be 0, so keep your own default (for example 1000).
Upload(currentMbps, gaugeMaxMbps)Live upload throughput, in the same shape.

Result​

FieldTypeNotes
downloadMbps / uploadMbpsDouble?null when the SDK did not measure that phase. Never 0 as a stand-in.
pingKapeSpeedTestPing?latencyMs, jitterMs, packetLossPercent
serverKapeSpeedTestServer?locationId, name, ip
ratingsKapeSpeedTestRatingsoverall, gaming, streaming, videoConference, browsing, downloads

Each rating is Excellent, Good, Ok, Degraded, Poor or Unknown. If ranking fails, the measurements are still returned and every rating is Unknown.

Cancelling​

  • Calling speedTest.cancel() stops the measurement, and run returns RunSpeedTestResult.Cancelled. It does nothing when this instance has no run in progress.
  • Cancelling the coroutine that called run (for example, the viewModelScope being cleared) also stops the measurement. In that case run throws CancellationException.

The library does not watch the network. If the network changes or the VPN connects or disconnects, cancel the run yourself. The measurement would be wrong anyway.

One operation at a time​

The SDK runs one ping, Smart Location or speed test operation at a time.

  • If a ping or Smart Location operation is running, run cancels it, waits up to 10 s for the SDK to go idle, then starts.
  • If another speed test is running, from this instance or another one, run returns Busy and leaves that test running.

Errors​

RunSpeedTestResult.Error.error is a KapeSpeedTestError:

CaseMeaning
NotLicensedThe license does not grant CategoryInstanceDiscovery and SpeedTest. Checked before anything runs.
NoActiveSubscriptionhandle.activeSubscriptionId is empty, for example when the user is signed out.
BusyAnother speed test is running, or the SDK did not go idle in time.
AbortedThe SDK aborted the measurement twice. One abort is retried automatically.
DnsFailureThe test server could not be resolved.
NetworkA network error.
TestFailedThe measurement failed.
Sdk(error)Any other SDK error, as a KapeError.