-
Notifications
You must be signed in to change notification settings - Fork 318
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
NAVAND-1250 auto tests for offline EV routing fallback + NavigationRo…
- Loading branch information
1 parent
2f7cc7a
commit 4342c2c
Showing
15 changed files
with
32,482 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
- Fixed `NavigationRoutes#waypoints` being null for EV offline fallback. |
130 changes: 130 additions & 0 deletions
130
...ts/src/androidTest/java/com/mapbox/navigation/instrumentation_tests/core/EvOfflineTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
package com.mapbox.navigation.instrumentation_tests.core | ||
|
||
import android.location.Location | ||
import com.mapbox.navigation.base.route.RouterOrigin | ||
import com.mapbox.navigation.core.directions.session.RoutesExtra | ||
import com.mapbox.navigation.instrumentation_tests.utils.location.stayOnPosition | ||
import com.mapbox.navigation.instrumentation_tests.utils.routes.EvRoutesProvider | ||
import com.mapbox.navigation.instrumentation_tests.utils.routes.MockedEvRoutes | ||
import com.mapbox.navigation.instrumentation_tests.utils.tiles.OfflineRegions | ||
import com.mapbox.navigation.instrumentation_tests.utils.tiles.withMapboxNavigationAndOfflineTilesForRegion | ||
import com.mapbox.navigation.instrumentation_tests.utils.withMapboxNavigation | ||
import com.mapbox.navigation.instrumentation_tests.utils.withoutInternet | ||
import com.mapbox.navigation.testing.ui.BaseCoreNoCleanUpTest | ||
import com.mapbox.navigation.testing.ui.utils.coroutines.RouteRequestResult | ||
import com.mapbox.navigation.testing.ui.utils.coroutines.getSuccessfulResultOrThrowException | ||
import com.mapbox.navigation.testing.ui.utils.coroutines.requestRoutes | ||
import com.mapbox.navigation.testing.ui.utils.coroutines.routesUpdates | ||
import com.mapbox.navigation.testing.ui.utils.coroutines.sdkTest | ||
import com.mapbox.navigation.testing.ui.utils.coroutines.setNavigationRoutesAsync | ||
import kotlinx.coroutines.flow.first | ||
import org.junit.Assert.assertEquals | ||
import org.junit.Assert.assertTrue | ||
import org.junit.Test | ||
|
||
// TODO: remove in the scope of NAVAND-1351 | ||
const val INCREASED_TIMEOUT_BECAUSE_OF_REAL_ROUTING_TILES_USAGE = 80_000L | ||
|
||
class EvOfflineTest : BaseCoreNoCleanUpTest() { | ||
|
||
override fun setupMockLocation(): Location { | ||
return mockLocationUpdatesRule.generateLocationUpdate { | ||
longitude = 13.361378213031003 | ||
latitude = 52.49813341962201 | ||
} | ||
} | ||
|
||
@Test | ||
fun requestRouteWithoutInternetAndTiles() = sdkTest { | ||
val testRoute = setupBerlinEvRoute() | ||
withMapboxNavigation { navigation -> | ||
withoutInternet { | ||
val routes = navigation.requestRoutes(testRoute.routeOptions) | ||
assertTrue(routes is RouteRequestResult.Failure) | ||
} | ||
} | ||
} | ||
|
||
@Test | ||
fun requestOnlineRouteWithoutInternetHavingTiles() = sdkTest( | ||
timeout = INCREASED_TIMEOUT_BECAUSE_OF_REAL_ROUTING_TILES_USAGE | ||
) { | ||
val originalTestRoute = setupBerlinEvRoute() | ||
withMapboxNavigationAndOfflineTilesForRegion( | ||
OfflineRegions.Berlin | ||
) { navigation -> | ||
navigation.startTripSession() | ||
withoutInternet { | ||
val requestResult = navigation.requestRoutes(originalTestRoute.routeOptions) | ||
.getSuccessfulResultOrThrowException() | ||
assertEquals(RouterOrigin.Onboard, requestResult.routerOrigin) | ||
navigation.setNavigationRoutesAsync(requestResult.routes) | ||
|
||
assertEquals( | ||
"onboard router doesn't add charging waypoints", | ||
requestResult.routes.map { 2 }, | ||
requestResult.routes.map { it.waypoints?.size } | ||
) | ||
} | ||
} | ||
} | ||
|
||
@Test | ||
fun deviateFromOnlinePrimaryRouteWithoutInternet() = sdkTest( | ||
timeout = INCREASED_TIMEOUT_BECAUSE_OF_REAL_ROUTING_TILES_USAGE | ||
) { | ||
val originalTestRoute = setupBerlinEvRoute() | ||
val testRouteAfterReroute = setupBerlinEvRouteAfterReroute() | ||
|
||
withMapboxNavigationAndOfflineTilesForRegion( | ||
OfflineRegions.Berlin | ||
) { navigation -> | ||
navigation.startTripSession() | ||
val requestResult = navigation.requestRoutes(originalTestRoute.routeOptions) | ||
.getSuccessfulResultOrThrowException() | ||
assertEquals(RouterOrigin.Offboard, requestResult.routerOrigin) | ||
assertEquals( | ||
"online route for this case is expected to add charging station", | ||
listOf(3, 3), | ||
requestResult.routes.map { it.waypoints?.size } | ||
) | ||
navigation.setNavigationRoutesAsync(requestResult.routes) | ||
|
||
withoutInternet { | ||
stayOnPosition( | ||
// off route position | ||
latitude = testRouteAfterReroute.origin.latitude(), | ||
longitude = testRouteAfterReroute.origin.longitude(), | ||
bearing = 280.0f | ||
) { | ||
val newRoutes = navigation.routesUpdates() | ||
.first { it.reason == RoutesExtra.ROUTES_UPDATE_REASON_REROUTE } | ||
assertEquals(RouterOrigin.Onboard, newRoutes.navigationRoutes.first().origin) | ||
assertEquals( | ||
"onboard router doesn't add waypoints", | ||
newRoutes.navigationRoutes.map { 2 }, | ||
newRoutes.navigationRoutes.map { it.waypoints?.size } | ||
) | ||
} | ||
} | ||
} | ||
} | ||
|
||
private fun setupBerlinEvRouteAfterReroute(): MockedEvRoutes { | ||
val testRouteAfterReroute = EvRoutesProvider.getBerlinEvRouteReroute( | ||
context, | ||
mockWebServerRule.baseUrl | ||
) | ||
mockWebServerRule.requestHandlers.add(testRouteAfterReroute.mockWebServerHandler) | ||
return testRouteAfterReroute | ||
} | ||
|
||
private fun setupBerlinEvRoute(): MockedEvRoutes { | ||
val originalTestRoute = EvRoutesProvider.getBerlinEvRoute( | ||
context, | ||
mockWebServerRule.baseUrl | ||
) | ||
mockWebServerRule.requestHandlers.add(originalTestRoute.mockWebServerHandler) | ||
return originalTestRoute | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 24 additions & 0 deletions
24
...n-tests/src/androidTest/java/com/mapbox/navigation/instrumentation_tests/utils/Network.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package com.mapbox.navigation.instrumentation_tests.utils | ||
|
||
import androidx.test.platform.app.InstrumentationRegistry | ||
import com.mapbox.navigation.testing.ui.BaseCoreNoCleanUpTest | ||
|
||
suspend fun BaseCoreNoCleanUpTest.withoutInternet(block: suspend () -> Unit) { | ||
withoutWifiAndMobileData { | ||
mockWebServerRule.withoutWebServer { | ||
block() | ||
} | ||
} | ||
} | ||
|
||
suspend fun withoutWifiAndMobileData(block: suspend () -> Unit) { | ||
val uiAutomation = InstrumentationRegistry.getInstrumentation().uiAutomation | ||
uiAutomation.executeShellCommand("svc wifi disable") | ||
uiAutomation.executeShellCommand("svc data disable") | ||
try { | ||
block() | ||
} finally { | ||
uiAutomation.executeShellCommand("svc wifi enable") | ||
uiAutomation.executeShellCommand("svc data enable") | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
...oidTest/java/com/mapbox/navigation/instrumentation_tests/utils/location/LocationUpdate.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package com.mapbox.navigation.instrumentation_tests.utils.location | ||
|
||
import com.mapbox.navigation.testing.ui.BaseCoreNoCleanUpTest | ||
import kotlinx.coroutines.coroutineScope | ||
import kotlinx.coroutines.delay | ||
import kotlinx.coroutines.launch | ||
|
||
suspend fun BaseCoreNoCleanUpTest.stayOnPosition( | ||
latitude: Double, | ||
longitude: Double, | ||
bearing: Float, | ||
frequencyHz: Int = 10, | ||
block: suspend () -> Unit | ||
) { | ||
coroutineScope { | ||
val updateLocations = launch { | ||
while (true) { | ||
mockLocationUpdatesRule.pushLocationUpdate { | ||
this.latitude = latitude | ||
this.longitude = longitude | ||
this.bearing = bearing | ||
} | ||
delay(1000L / frequencyHz) | ||
} | ||
} | ||
try { | ||
block() | ||
} finally { | ||
updateLocations.cancel() | ||
} | ||
} | ||
} |
79 changes: 79 additions & 0 deletions
79
...androidTest/java/com/mapbox/navigation/instrumentation_tests/utils/routes/MockEvRoutes.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package com.mapbox.navigation.instrumentation_tests.utils.routes | ||
|
||
import android.content.Context | ||
import com.mapbox.api.directions.v5.DirectionsCriteria | ||
import com.mapbox.api.directions.v5.models.RouteOptions | ||
import com.mapbox.geojson.Point | ||
import com.mapbox.navigation.base.extensions.applyDefaultNavigationOptions | ||
import com.mapbox.navigation.instrumentation_tests.R | ||
import com.mapbox.navigation.instrumentation_tests.utils.http.MockDirectionsRequestHandler | ||
import com.mapbox.navigation.instrumentation_tests.utils.readRawFileText | ||
import com.mapbox.navigation.testing.ui.http.BaseMockRequestHandler | ||
|
||
data class MockedEvRoutes( | ||
val routeOptions: RouteOptions, | ||
val mockWebServerHandler: BaseMockRequestHandler | ||
) { | ||
val origin get() = routeOptions.coordinatesList().first() | ||
} | ||
|
||
object EvRoutesProvider { | ||
fun getBerlinEvRoute(context: Context, baseUrl: String? = null): MockedEvRoutes { | ||
val routeOptions = berlinEvRouteOptions(baseUrl) | ||
val jsonResponse = readRawFileText(context, R.raw.ev_routes_berlin) | ||
val evRouteRequestHandler = MockDirectionsRequestHandler( | ||
profile = DirectionsCriteria.PROFILE_DRIVING_TRAFFIC, | ||
jsonResponse = jsonResponse, | ||
expectedCoordinates = routeOptions.coordinatesList(), | ||
) | ||
return MockedEvRoutes( | ||
routeOptions, | ||
evRouteRequestHandler | ||
) | ||
} | ||
|
||
/*** | ||
* has the same destination as [getBerlinEvRoute], but different origin, | ||
* could be use for reroute cases | ||
*/ | ||
fun getBerlinEvRouteReroute(context: Context, baseUrl: String? = null): MockedEvRoutes { | ||
val originalRouteOptions = berlinEvRouteOptions(baseUrl) | ||
val newRouteOptions = originalRouteOptions.toBuilder() | ||
.coordinatesList( | ||
originalRouteOptions.coordinatesList().apply { | ||
set(0, Point.fromLngLat(13.36742058325467, 52.49745756017697)) | ||
} | ||
) | ||
.build() | ||
val newRouteOnlineRouteRequestHandler = MockDirectionsRequestHandler( | ||
profile = DirectionsCriteria.PROFILE_DRIVING_TRAFFIC, | ||
jsonResponse = readRawFileText(context, R.raw.ev_routes_berlin_reroute), | ||
expectedCoordinates = newRouteOptions.coordinatesList() | ||
) | ||
return MockedEvRoutes(newRouteOptions, newRouteOnlineRouteRequestHandler) | ||
} | ||
|
||
private fun berlinEvRouteOptions(baseUrl: String?): RouteOptions = RouteOptions.builder() | ||
.applyDefaultNavigationOptions() | ||
.coordinates("13.361378213031003,52.49813341962201;13.393450988895268,52.50913924804004") | ||
.annotations("state_of_charge") | ||
.alternatives(true) | ||
.waypointsPerRoute(true) | ||
.unrecognizedProperties( | ||
mapOf( | ||
"engine" to "electric", | ||
"ev_initial_charge" to "1000", | ||
"ev_max_charge" to "50000", | ||
"ev_connector_types" to "ccs_combo_type1,ccs_combo_type2", | ||
"energy_consumption_curve" to "0,300;20,160;80,140;120,180", | ||
"ev_charging_curve" to "0,100000;40000,70000;60000,30000;80000,10000", | ||
"ev_min_charge_at_charging_station" to "1" | ||
) | ||
) | ||
.apply { | ||
if (baseUrl != null) { | ||
baseUrl(baseUrl) | ||
} | ||
} | ||
.build() | ||
} |
20 changes: 20 additions & 0 deletions
20
...ndroidTest/java/com/mapbox/navigation/instrumentation_tests/utils/tiles/OfflineRegions.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package com.mapbox.navigation.instrumentation_tests.utils.tiles | ||
|
||
import androidx.test.platform.app.InstrumentationRegistry | ||
import com.mapbox.geojson.FeatureCollection | ||
import com.mapbox.navigation.instrumentation_tests.R | ||
import com.mapbox.navigation.instrumentation_tests.utils.readRawFileText | ||
|
||
object OfflineRegions { | ||
val Berlin = OfflineRegion( | ||
id = "berlin-test-tiles", | ||
geometry = BERLIN_GEOMETRY | ||
) | ||
} | ||
|
||
private val BERLIN_GEOMETRY = FeatureCollection.fromJson( | ||
readRawFileText( | ||
InstrumentationRegistry.getInstrumentation().targetContext, | ||
R.raw.geometry_berlin | ||
) | ||
).features()!!.first().geometry()!! |
Oops, something went wrong.