| /* |
| * Copyright (C) 2016 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.hardware.cts.helpers.sensorverification; |
| |
| import junit.framework.TestCase; |
| |
| import android.hardware.cts.helpers.SensorStats; |
| import android.hardware.cts.helpers.TestSensorEnvironment; |
| import android.hardware.cts.helpers.TestSensorEvent; |
| import android.os.SystemClock; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| |
| import android.util.Log; |
| |
| /** |
| * Tests for {@link TimestampClockSourceVerification}. |
| */ |
| public class TimestampClockSourceVerificationTest extends TestCase { |
| private final String TAG = "TimestampClockSourceVerificationTest"; |
| |
| private final int MIN_DELTA_BETWEEN_CLOCKS_MS = 2000; |
| private boolean mAdjustUptime = false; |
| |
| private long getValidTimestamp() { |
| return SystemClock.elapsedRealtimeNanos(); |
| } |
| |
| private long getInvalidTimestamp() { |
| long ms = SystemClock.uptimeMillis(); |
| if (mAdjustUptime == true) { |
| ms -= MIN_DELTA_BETWEEN_CLOCKS_MS; |
| } |
| return (ms * 1000000); |
| } |
| |
| private void verifyClockDelta() throws Throwable { |
| long uptimeMs = SystemClock.uptimeMillis(); |
| long realtimeNs = SystemClock.elapsedRealtimeNanos(); |
| long deltaMs = (realtimeNs/1000000 - uptimeMs); |
| if (deltaMs < MIN_DELTA_BETWEEN_CLOCKS_MS) { |
| Log.i(TAG, "Device has not slept, will use different clock source for test purposes"); |
| mAdjustUptime = true; |
| } else { |
| mAdjustUptime = false; |
| Log.i(TAG, "CLOCK_MONOTONIC="+uptimeMs*1000000+", CLOCK_BOOTTIME="+realtimeNs+", delta=" + deltaMs + " mS"); |
| } |
| } |
| |
| |
| /** |
| * Test that the verification passes when there are not missing events. |
| */ |
| public void testVerify_pass() throws Throwable { |
| try { |
| verifyClockDelta(); |
| long ts = getValidTimestamp(); |
| long[] timestamps = {ts-4000000, ts-3000000, ts-2000000, ts-1000000, ts}; |
| // Timestamps in ns, expected in us |
| runVerification(MIN_DELTA_BETWEEN_CLOCKS_MS*1000, timestamps, true, new int[]{}); |
| } finally { |
| } |
| } |
| |
| /** |
| * Test that the verification fails when there are not missing events, |
| * but wrong clock source is used. |
| */ |
| public void testVerify_fail() throws Throwable { |
| try { |
| verifyClockDelta(); |
| long ts = getInvalidTimestamp(); |
| long[] timestamps = {ts-4000000, ts-3000000, ts-2000000, ts-1000000, ts}; |
| // Timestamps in ns, expected in us |
| runVerification(MIN_DELTA_BETWEEN_CLOCKS_MS*1000, timestamps, false, new int[]{0,1,2,3,4}); |
| } finally { |
| } |
| } |
| |
| /** |
| * Test that the verification passes when there are not missing events but some jitter. |
| */ |
| public void testVerify_jitter_pass() throws Throwable { |
| try { |
| verifyClockDelta(); |
| long ts = getValidTimestamp(); |
| long[] timestamps = {ts-3900000, ts-2950000, ts-2050000, ts-1000000, ts-50000}; |
| // Timestamps in ns, expected in us |
| runVerification(MIN_DELTA_BETWEEN_CLOCKS_MS*1000, timestamps, true, new int[]{}); |
| } finally { |
| } |
| } |
| |
| /** |
| * Test that the verification passes when there are not missing events but some jitter. |
| */ |
| public void testVerify_jitter_fail() throws Throwable { |
| try { |
| verifyClockDelta(); |
| long ts = getInvalidTimestamp(); |
| long[] timestamps = {ts-3900000, ts-2950000, ts-2050000, ts-1000000, ts-50000}; |
| // Timestamps in ns, expected in us |
| runVerification(MIN_DELTA_BETWEEN_CLOCKS_MS*1000, timestamps, false, new int[]{0,1,2,3,4}); |
| } finally { |
| } |
| } |
| |
| /** |
| * Test that the verification does not fail when there are missing events. |
| */ |
| public void testVerify_missing_events_pass() throws Throwable { |
| try { |
| verifyClockDelta(); |
| long ts = getValidTimestamp(); |
| long[] timestamps = {ts-4000000, ts-3000000, ts-1000000, ts}; |
| // Timestamps in ns, expected in us |
| runVerification(MIN_DELTA_BETWEEN_CLOCKS_MS*1000, timestamps, true, new int[]{}); |
| } finally { |
| } |
| } |
| |
| /** |
| * Test that the verification fails when there are missing events, but wrong |
| * timestamp |
| */ |
| public void testVerify_missing_events_fail() throws Throwable { |
| try { |
| verifyClockDelta(); |
| long ts = getInvalidTimestamp(); |
| long[] timestamps = {ts-4000000, ts-3000000, ts-1000000, ts}; |
| // Timestamps in ns, expected in us |
| runVerification(MIN_DELTA_BETWEEN_CLOCKS_MS*1000, timestamps, false, new int[]{0,1,2,3}); |
| } finally { |
| } |
| } |
| |
| /** |
| * Test that the verification fails when there are no results. |
| */ |
| public void testVerify_no_events_fail() throws Throwable { |
| try { |
| verifyClockDelta(); |
| // Timestamps in ns, expected in us |
| runVerification(MIN_DELTA_BETWEEN_CLOCKS_MS*1000, new long[]{}, false, new int[]{}); |
| } finally { |
| } |
| } |
| |
| private void runVerification(int expectedUs, long[] timestamps, boolean pass, |
| int[] indices) { |
| SensorStats stats = new SensorStats(); |
| ISensorVerification verification = getVerification(expectedUs, timestamps); |
| TestSensorEnvironment environment = new TestSensorEnvironment(null, null, false, 0, 0); |
| if (pass) { |
| verification.verify(environment, stats); |
| } else { |
| boolean failed = false; |
| try { |
| verification.verify(environment, stats); |
| } catch (AssertionError e) { |
| // Expected; |
| failed = true; |
| } |
| assertTrue("Expected an AssertionError", failed); |
| } |
| |
| assertEquals(pass, stats.getValue(TimestampClockSourceVerification.PASSED_KEY)); |
| assertEquals(indices.length, stats.getValue(SensorStats.EVENT_TIME_WRONG_CLOCKSOURCE_COUNT_KEY)); |
| if (0 != (Integer) stats.getValue(SensorStats.EVENT_TIME_WRONG_CLOCKSOURCE_COUNT_KEY)) { |
| assertNotNull(stats.getValue(SensorStats.EVENT_TIME_WRONG_CLOCKSOURCE_POSITIONS_KEY)); |
| } |
| try { |
| int[] actualIndices = (int[]) stats.getValue(SensorStats.EVENT_TIME_WRONG_CLOCKSOURCE_POSITIONS_KEY); |
| assertEquals(indices.length, actualIndices.length); |
| |
| for (int i = 0; i < indices.length; i++) { |
| assertEquals(indices[i], actualIndices[i]); |
| } |
| } catch (Throwable t) { |
| } |
| } |
| |
| private static TimestampClockSourceVerification getVerification(int expectedUs, long ... timestamps) { |
| Collection<TestSensorEvent> events = new ArrayList<>(timestamps.length); |
| long expectedNs = expectedUs * 1000; |
| long now = SystemClock.elapsedRealtimeNanos(); |
| long receiveTime; |
| for (long timestamp : timestamps) { |
| //receiveTime = now - (expectedNs * count); |
| receiveTime = SystemClock.elapsedRealtimeNanos(); |
| events.add(new TestSensorEvent(null, timestamp, receiveTime, 0, null)); |
| } |
| TimestampClockSourceVerification verification = new TimestampClockSourceVerification(expectedUs); |
| verification.addSensorEvents(events); |
| return verification; |
| } |
| } |