aboutsummaryrefslogtreecommitdiff
path: root/tests/vehiclehal_test
diff options
context:
space:
mode:
authorPavel Maltsev <pavelm@google.com>2017-04-11 12:38:17 -0700
committerPavel Maltsev <pavelm@google.com>2017-04-14 10:36:04 -0700
commit82c20cdd99601923df556b99114ad5d186821977 (patch)
tree690e5a1ace0df9e96232e569c2a84cfd592f51fa /tests/vehiclehal_test
parentaacfcd53c320a5297971ce609fad920e611e95ac (diff)
downloadCar-82c20cdd99601923df556b99114ad5d186821977.tar.gz
Initial e2e Vehicle s/w stack infrastructure
Also, fixed some sensor mapping between CarSensorManager and VHAL Bug: b/36510399 Test: runtest -x packages/services/Car/tests/vehiclehal_test/ Change-Id: I556e03402c16a3b2c8cb25d7a048f8c9a072e23b
Diffstat (limited to 'tests/vehiclehal_test')
-rw-r--r--tests/vehiclehal_test/src/com/android/car/vehiclehal/test/E2ePerformanceTest.java236
-rw-r--r--tests/vehiclehal_test/src/com/android/car/vehiclehal/test/Obd2FreezeFrameTest.java44
-rw-r--r--tests/vehiclehal_test/src/com/android/car/vehiclehal/test/Obd2LiveFrameTest.java38
-rw-r--r--tests/vehiclehal_test/src/com/android/car/vehiclehal/test/Utils.java68
4 files changed, 278 insertions, 108 deletions
diff --git a/tests/vehiclehal_test/src/com/android/car/vehiclehal/test/E2ePerformanceTest.java b/tests/vehiclehal_test/src/com/android/car/vehiclehal/test/E2ePerformanceTest.java
new file mode 100644
index 0000000000..c76cc4ae81
--- /dev/null
+++ b/tests/vehiclehal_test/src/com/android/car/vehiclehal/test/E2ePerformanceTest.java
@@ -0,0 +1,236 @@
+/*
+ * Copyright (C) 2017 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.car.vehiclehal.test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeTrue;
+
+import android.car.Car;
+import android.car.hardware.CarSensorManager;
+import android.car.hardware.CarSensorManager.OnSensorChangedListener;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.ServiceConnection;
+import android.hardware.automotive.vehicle.V2_0.IVehicle;
+import android.hardware.automotive.vehicle.V2_0.StatusCode;
+import android.hardware.automotive.vehicle.V2_0.VehicleArea;
+import android.hardware.automotive.vehicle.V2_0.VehiclePropValue;
+import android.hardware.automotive.vehicle.V2_0.VehicleProperty;
+import android.hardware.automotive.vehicle.V2_0.VehiclePropertyGroup;
+import android.hardware.automotive.vehicle.V2_0.VehiclePropertyType;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.suitebuilder.annotation.LargeTest;
+
+import com.google.android.collect.Lists;
+
+import com.android.car.vehiclehal.VehiclePropValueBuilder;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * This test suite will make e2e test and measure some performance characteristics. The main idea
+ * is to send command to Vehicle HAL to generate some events with certain time interval and capture
+ * these events through car public API, e.g. CarSensorManager.
+ */
+@LargeTest
+@RunWith(AndroidJUnit4.class)
+public class E2ePerformanceTest {
+ private static String TAG = Utils.concatTag(E2ePerformanceTest.class);
+
+ private IVehicle mVehicle;
+ private final CarConnectionListener mConnectionListener = new CarConnectionListener();
+ private Context mContext;
+ private Car mCar;
+
+ private static Handler sEventHandler;
+ private static final HandlerThread sHandlerThread = new HandlerThread(TAG);
+
+ private static final int DEFAULT_WAIT_TIMEOUT_MS = 1000;
+
+ private static final int GENERATE_FAKE_DATA_CONTROLLING_PROPERTY = 0x0666
+ | VehiclePropertyGroup.VENDOR
+ | VehicleArea.GLOBAL
+ | VehiclePropertyType.COMPLEX;
+
+ private static final int CMD_START = 1;
+ private static final int CMD_STOP = 0;
+
+ private HalEventsGenerator mEventsGenerator;
+
+ @BeforeClass
+ public static void setupEventHandler() {
+ sHandlerThread.start();
+ sEventHandler = new Handler(sHandlerThread.getLooper());
+ }
+
+ @Before
+ public void connectToVehicleHal() throws Exception {
+ mVehicle = Utils.getVehicle();
+
+ mVehicle.getPropConfigs(Lists.newArrayList(GENERATE_FAKE_DATA_CONTROLLING_PROPERTY),
+ (status, propConfigs) -> assumeTrue(status == StatusCode.OK));
+
+ mEventsGenerator = new HalEventsGenerator(mVehicle);
+ }
+
+ @Before
+ public void connectToCarService() throws Exception {
+ mContext = InstrumentationRegistry.getContext();
+ mCar = Car.createCar(mContext, mConnectionListener, sEventHandler);
+ assertNotNull(mCar);
+ mCar.connect();
+ mConnectionListener.waitForConnection(DEFAULT_WAIT_TIMEOUT_MS);
+ }
+
+ @After
+ public void disconnect() throws Exception {
+ if (mVehicle != null) {
+ mEventsGenerator.stop();
+ mVehicle = null;
+ mEventsGenerator = null;
+ }
+ if (mCar != null) {
+ mCar.disconnect();
+ mCar = null;
+ }
+ }
+
+ @Test
+ public void singleOnChangeProperty() throws Exception {
+ final int PROP = CarSensorManager.SENSOR_TYPE_ODOMETER;
+ // Expecting to receive at least 10 events within 150ms.
+ final int EXPECTED_EVENTS = 10;
+ final int EXPECTED_TIME_DURATION_MS = 150;
+ final float INITIAL_VALUE = 1000;
+ final float INCREMENT = 1.0f;
+
+ CarSensorManager mgr = (CarSensorManager) mCar.getCarManager(Car.SENSOR_SERVICE);
+ assertNotNull(mgr);
+ assertTrue(mgr.isSensorSupported(CarSensorManager.SENSOR_TYPE_ODOMETER));
+
+ mEventsGenerator
+ .setIntervalMs(10)
+ .setInitialValue(INITIAL_VALUE)
+ .setIncrement(INCREMENT)
+ .setDispersion(100)
+ .start(VehicleProperty.PERF_ODOMETER);
+
+ CountDownLatch latch = new CountDownLatch(EXPECTED_EVENTS);
+ OnSensorChangedListener listener = event -> latch.countDown();
+
+ mgr.registerListener(listener, PROP, CarSensorManager.SENSOR_RATE_FASTEST);
+ try {
+ assertTrue(latch.await(EXPECTED_TIME_DURATION_MS, TimeUnit.MILLISECONDS));
+ } finally {
+ mgr.unregisterListener(listener);
+ }
+ }
+
+ private static class CarConnectionListener implements ServiceConnection {
+ private final Semaphore mConnectionWait = new Semaphore(0);
+
+ void waitForConnection(long timeoutMs) throws InterruptedException {
+ mConnectionWait.tryAcquire(timeoutMs, TimeUnit.MILLISECONDS);
+ }
+
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ mConnectionWait.release();
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) { }
+ }
+
+ static class HalEventsGenerator {
+ private final IVehicle mVehicle;
+
+ private long mIntervalMs;
+ private float mInitialValue;
+ private float mDispersion;
+ private float mIncrement;
+
+ HalEventsGenerator(IVehicle vehicle) {
+ mVehicle = vehicle;
+ reset();
+ }
+
+ HalEventsGenerator reset() {
+ mIntervalMs = 1000;
+ mInitialValue = 1000;
+ mDispersion = 0;
+ mInitialValue = 0;
+ return this;
+ }
+
+ HalEventsGenerator setIntervalMs(long intervalMs) {
+ mIntervalMs = intervalMs;
+ return this;
+ }
+
+ HalEventsGenerator setInitialValue(float initialValue) {
+ mInitialValue = initialValue;
+ return this;
+ }
+
+ HalEventsGenerator setDispersion(float dispersion) {
+ mDispersion = dispersion;
+ return this;
+ }
+
+ HalEventsGenerator setIncrement(float increment) {
+ mIncrement = increment;
+ return this;
+ }
+
+ void start(int propId) throws RemoteException {
+ VehiclePropValue request =
+ VehiclePropValueBuilder.newBuilder(GENERATE_FAKE_DATA_CONTROLLING_PROPERTY)
+ .addIntValue(CMD_START, propId)
+ .setInt64Value(mIntervalMs * 1000_000)
+ .addFloatValue(mInitialValue, mDispersion, mIncrement)
+ .build();
+ assertEquals(StatusCode.OK, mVehicle.set(request));
+ }
+
+ void stop() throws RemoteException {
+ stop(0);
+ }
+
+ void stop(int propId) throws RemoteException {
+ VehiclePropValue request =
+ VehiclePropValueBuilder.newBuilder(GENERATE_FAKE_DATA_CONTROLLING_PROPERTY)
+ .addIntValue(CMD_STOP, propId)
+ .build();
+ assertEquals(StatusCode.OK, mVehicle.set(request));
+ }
+ }
+}
diff --git a/tests/vehiclehal_test/src/com/android/car/vehiclehal/test/Obd2FreezeFrameTest.java b/tests/vehiclehal_test/src/com/android/car/vehiclehal/test/Obd2FreezeFrameTest.java
index 19047f2e67..23b9dbedbc 100644
--- a/tests/vehiclehal_test/src/com/android/car/vehiclehal/test/Obd2FreezeFrameTest.java
+++ b/tests/vehiclehal_test/src/com/android/car/vehiclehal/test/Obd2FreezeFrameTest.java
@@ -16,64 +16,45 @@
package com.android.car.vehiclehal.test;
-import static com.android.car.vehiclehal.test.Utils.dumpVehiclePropValue;
import static com.android.car.vehiclehal.test.Utils.isVhalPropertyAvailable;
import static com.android.car.vehiclehal.test.Utils.readVhalProperty;
-import static com.android.car.vehiclehal.test.Utils.tryWithDeadline;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assume.assumeTrue;
-import android.annotation.Nullable;
+import android.hardware.automotive.vehicle.V2_0.IVehicle;
import android.hardware.automotive.vehicle.V2_0.StatusCode;
import android.hardware.automotive.vehicle.V2_0.VehiclePropValue;
-import android.hardware.automotive.vehicle.V2_1.IVehicle;
import android.hardware.automotive.vehicle.V2_1.VehicleProperty;
import android.os.RemoteException;
import android.util.Log;
+
import com.android.car.vehiclehal.VehiclePropValueBuilder;
-import java.util.Objects;
+
import org.junit.Before;
import org.junit.Test;
/** Test retrieving the OBD2_FREEZE_FRAME property from VHAL */
public class Obd2FreezeFrameTest {
- private static final String TAG = Obd2FreezeFrameTest.class.getSimpleName();
- private static final long WAIT_FOR_VEHICLE_HAL_TIMEOUT_MS = 10_000;
+ private static final String TAG = Utils.concatTag(Obd2FreezeFrameTest.class);
private IVehicle mVehicle = null;
@Before
public void setUp() throws Exception {
- mVehicle = Objects.requireNonNull(getVehicle(WAIT_FOR_VEHICLE_HAL_TIMEOUT_MS));
- }
-
- @Nullable
- private IVehicle getVehicle(long waitMilliseconds) {
- return tryWithDeadline(
- waitMilliseconds,
- () -> {
- try {
- return IVehicle.getService();
- } catch (RemoteException e) {
- Log.w(TAG, "attempt to get IVehicle service " +
- " caused RemoteException: ", e);
- return null;
- }
- });
+ mVehicle = Utils.getVehicle();
+ assumeTrue("Freeze frame not available, test-case ignored.", isFreezeFrameAvailable());
}
@Test
public void testFreezeFrame() throws RemoteException {
- if (!isFreezeFrameAvailable()) {
- Log.i(TAG, "freeze frame not available; returning - our job here is done");
- return;
- }
readVhalProperty(
mVehicle,
VehicleProperty.OBD2_FREEZE_FRAME_INFO,
(Integer status, VehiclePropValue value) -> {
assertEquals(StatusCode.OK, status.intValue());
assertNotNull("OBD2_FREEZE_FRAME_INFO is supported; should not be null", value);
- Log.i(TAG, "dump of OBD2_FREEZE_FRAME_INFO:\n" + dumpVehiclePropValue(value));
+ Log.i(TAG, "dump of OBD2_FREEZE_FRAME_INFO:\n" + value);
for(long timestamp: value.value.int64Values) {
Log.i(TAG, "timestamp: " + timestamp);
readVhalProperty(
@@ -83,8 +64,9 @@ public class Obd2FreezeFrameTest {
.build(),
(Integer frameStatus, VehiclePropValue freezeFrame) -> {
if (StatusCode.OK == frameStatus.intValue()) {
- assertNotNull("OBD2_FREEZE_FRAME read OK; should not be null", freezeFrame);
- Log.i(TAG, "dump of OBD2_FREEZE_FRAME:\n" + dumpVehiclePropValue(freezeFrame));
+ assertNotNull("OBD2_FREEZE_FRAME read OK; should not be null",
+ freezeFrame);
+ Log.i(TAG, "dump of OBD2_FREEZE_FRAME:\n" + freezeFrame);
assertEquals(freezeFrame.timestamp, timestamp);
}
return true;
diff --git a/tests/vehiclehal_test/src/com/android/car/vehiclehal/test/Obd2LiveFrameTest.java b/tests/vehiclehal_test/src/com/android/car/vehiclehal/test/Obd2LiveFrameTest.java
index 1f17358610..8e14db3596 100644
--- a/tests/vehiclehal_test/src/com/android/car/vehiclehal/test/Obd2LiveFrameTest.java
+++ b/tests/vehiclehal_test/src/com/android/car/vehiclehal/test/Obd2LiveFrameTest.java
@@ -16,63 +16,43 @@
package com.android.car.vehiclehal.test;
-import static com.android.car.vehiclehal.test.Utils.dumpVehiclePropValue;
import static com.android.car.vehiclehal.test.Utils.isVhalPropertyAvailable;
import static com.android.car.vehiclehal.test.Utils.readVhalProperty;
-import static com.android.car.vehiclehal.test.Utils.tryWithDeadline;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assume.assumeTrue;
-import android.annotation.Nullable;
+import android.hardware.automotive.vehicle.V2_0.IVehicle;
import android.hardware.automotive.vehicle.V2_0.StatusCode;
import android.hardware.automotive.vehicle.V2_0.VehiclePropValue;
-import android.hardware.automotive.vehicle.V2_1.IVehicle;
import android.hardware.automotive.vehicle.V2_1.VehicleProperty;
import android.os.RemoteException;
import android.util.Log;
-import java.util.Objects;
+
import org.junit.Before;
import org.junit.Test;
/** Test retrieving the OBD2_LIVE_FRAME property from VHAL */
public class Obd2LiveFrameTest {
- private static final String TAG = Obd2LiveFrameTest.class.getSimpleName();
- private static final long WAIT_FOR_VEHICLE_HAL_TIMEOUT_MS = 10_000;
+ private static final String TAG = Utils.concatTag(Obd2LiveFrameTest.class);
private IVehicle mVehicle = null;
@Before
public void setUp() throws Exception {
- mVehicle = Objects.requireNonNull(getVehicle(WAIT_FOR_VEHICLE_HAL_TIMEOUT_MS));
- }
-
- @Nullable
- private IVehicle getVehicle(long waitMilliseconds) {
- return tryWithDeadline(
- waitMilliseconds,
- () -> {
- try {
- return IVehicle.getService();
- } catch (RemoteException e) {
- Log.w(TAG, "attempt to get IVehicle service " +
- " caused RemoteException: ", e);
- return null;
- }
- });
+ mVehicle = Utils.getVehicle();
+ assumeTrue("Live frame not available, test-case ignored.", isLiveFrameAvailable());
}
@Test
public void testLiveFrame() throws RemoteException {
- if (!isLiveFrameAvailable()) {
- Log.i(TAG, "live frame not available; returning - our job here is done");
- return;
- }
readVhalProperty(
mVehicle,
VehicleProperty.OBD2_LIVE_FRAME,
(Integer status, VehiclePropValue value) -> {
assertEquals(StatusCode.OK, status.intValue());
assertNotNull("OBD2_LIVE_FRAME is supported; should not be null", value);
- Log.i(TAG, "dump of OBD2_LIVE_FRAME:\n" + dumpVehiclePropValue(value));
+ Log.i(TAG, "dump of OBD2_LIVE_FRAME:\n" + value);
return true;
});
}
diff --git a/tests/vehiclehal_test/src/com/android/car/vehiclehal/test/Utils.java b/tests/vehiclehal_test/src/com/android/car/vehiclehal/test/Utils.java
index 67c5c2d6e1..5221907c50 100644
--- a/tests/vehiclehal_test/src/com/android/car/vehiclehal/test/Utils.java
+++ b/tests/vehiclehal_test/src/com/android/car/vehiclehal/test/Utils.java
@@ -16,65 +16,25 @@
package com.android.car.vehiclehal.test;
-import static android.os.SystemClock.elapsedRealtime;
-
import android.annotation.Nullable;
import android.hardware.automotive.vehicle.V2_0.IVehicle;
import android.hardware.automotive.vehicle.V2_0.VehiclePropConfig;
import android.hardware.automotive.vehicle.V2_0.VehiclePropValue;
import android.os.RemoteException;
import android.util.Log;
+
import com.android.car.vehiclehal.VehiclePropValueBuilder;
+
+import java.util.NoSuchElementException;
import java.util.Objects;
final class Utils {
private Utils() {}
- private static final String TAG = Utils.class.getSimpleName();
+ private static final String TAG = concatTag(Utils.class);
- @Nullable
- static <T> T tryWithDeadline(long waitMilliseconds, java.util.function.Supplier<T> f) {
- f = Objects.requireNonNull(f);
- T object = f.get();
- long start = elapsedRealtime();
- while (object == null && (start + waitMilliseconds) > elapsedRealtime()) {
- try {
- Thread.sleep(100);
- } catch (InterruptedException e) {
- throw new RuntimeException("Sleep was interrupted", e);
- }
-
- object = f.get();
- }
- return object;
- }
-
- static String dumpVehiclePropValue(VehiclePropValue vpv) {
- vpv = Objects.requireNonNull(vpv);
- return "prop = "
- + vpv.prop
- + '\n'
- + "areaId = "
- + vpv.areaId
- + '\n'
- + "timestamp = "
- + vpv.timestamp
- + '\n'
- + "int32Values = "
- + vpv.value.int32Values
- + '\n'
- + "floatValues = "
- + vpv.value.floatValues
- + '\n'
- + "int64Values ="
- + vpv.value.int64Values
- + '\n'
- + "bytes = "
- + vpv.value.bytes
- + '\n'
- + "string = "
- + vpv.value.stringValue
- + '\n';
+ static String concatTag(Class clazz) {
+ return "VehicleHalTest." + clazz.getSimpleName();
}
static boolean isVhalPropertyAvailable(IVehicle vehicle, int prop) throws RemoteException {
@@ -99,8 +59,7 @@ final class Utils {
}
});
} catch (RemoteException e) {
- Log.w(TAG, "attempt to read VHAL property " +
- dumpVehiclePropValue(request) + " caused RemoteException: ", e);
+ Log.w(TAG, "attempt to read VHAL property " + request + " caused RemoteException: ", e);
}
return vpv[0];
}
@@ -121,4 +80,17 @@ final class Utils {
VehiclePropValueBuilder.newBuilder(propertyId).setAreaId(areaId).build();
return readVhalProperty(vehicle, request, f);
}
+
+ @Nullable
+ static IVehicle getVehicle() throws RemoteException {
+ IVehicle service;
+ try {
+ service = android.hardware.automotive.vehicle.V2_0.IVehicle.getService();
+ } catch (NoSuchElementException ex) {
+ Log.d(TAG, "Couldn't connect to vehicle@2.1, connecting to vehicle@2.0...");
+ service = IVehicle.getService();
+ }
+ Log.d(TAG, "Connected to IVehicle service: " + service);
+ return service;
+ }
}