Home | History | Annotate | Download | only in sensoroperations
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.hardware.cts.helpers.sensoroperations;
     18 
     19 import junit.framework.TestCase;
     20 
     21 import android.hardware.cts.helpers.SensorStats;
     22 import android.hardware.cts.helpers.SensorTestPlatformException;
     23 import android.hardware.cts.helpers.reporting.ISensorTestNode;
     24 
     25 import java.util.Set;
     26 import java.util.concurrent.TimeUnit;
     27 
     28 /**
     29  * Tests for the primitive {@link SensorOperation}s including {@link DelaySensorOperation},
     30  * {@link ParallelSensorOperation}, {@link RepeatingSensorOperation} and
     31  * {@link SequentialSensorOperation}.
     32  */
     33 public class SensorOperationTest extends TestCase {
     34     private static final long TEST_DURATION_THRESHOLD_MS = TimeUnit.SECONDS.toMillis(5);
     35 
     36     private final ISensorTestNode mTestNode = new ISensorTestNode() {
     37         @Override
     38         public String getName() throws SensorTestPlatformException {
     39             return "SensorOperationUnitTest";
     40         }
     41     };
     42 
     43     /**
     44      * Test that the {@link FakeSensorOperation} functions correctly. Other tests in this class
     45      * rely on this operation.
     46      */
     47     public void testFakeSensorOperation() throws Exception {
     48         final int opDurationMs = 100;
     49 
     50         SensorOperation op = new FakeSensorOperation(opDurationMs, TimeUnit.MILLISECONDS);
     51 
     52         assertFalse(op.getStats().flatten().containsKey("executed"));
     53         long start = System.currentTimeMillis();
     54         op.execute(mTestNode);
     55         long duration = System.currentTimeMillis() - start;
     56         assertTrue(Math.abs(opDurationMs - duration) < TEST_DURATION_THRESHOLD_MS);
     57         assertTrue(op.getStats().flatten().containsKey("executed"));
     58 
     59         op = new FakeSensorOperation(true, 0, TimeUnit.MILLISECONDS);
     60         try {
     61             op.execute(mTestNode);
     62             throw new Error("AssertionError expected");
     63         } catch (AssertionError e) {
     64             // Expected
     65         }
     66         assertTrue(op.getStats().flatten().keySet().contains(SensorStats.ERROR));
     67     }
     68 
     69     /**
     70      * Test that the {@link DelaySensorOperation} functions correctly.
     71      */
     72     public void testDelaySensorOperation() throws Exception {
     73         final int opDurationMs = 500;
     74         final int subOpDurationMs = 100;
     75 
     76         FakeSensorOperation subOp = new FakeSensorOperation(subOpDurationMs, TimeUnit.MILLISECONDS);
     77         SensorOperation op = new DelaySensorOperation(subOp, opDurationMs, TimeUnit.MILLISECONDS);
     78 
     79         long startMs = System.currentTimeMillis();
     80         op.execute(mTestNode);
     81         long durationMs = System.currentTimeMillis() - startMs;
     82         long durationDeltaMs = Math.abs(opDurationMs + subOpDurationMs - durationMs);
     83         assertTrue(durationDeltaMs < TEST_DURATION_THRESHOLD_MS);
     84     }
     85 
     86     /**
     87      * Test that the {@link ParallelSensorOperation} functions correctly.
     88      */
     89     public void testParallelSensorOperation() throws Exception {
     90         final int subOpCount = 100;
     91         final int subOpDurationMs = 500;
     92 
     93         ParallelSensorOperation op = new ParallelSensorOperation();
     94         for (int i = 0; i < subOpCount; i++) {
     95             SensorOperation subOp = new FakeSensorOperation(subOpDurationMs,
     96                     TimeUnit.MILLISECONDS);
     97             op.add(subOp);
     98         }
     99 
    100         Set<String> statsKeys = op.getStats().flatten().keySet();
    101         assertEquals(0, statsKeys.size());
    102 
    103         long start = System.currentTimeMillis();
    104         op.execute(mTestNode);
    105         long durationMs = System.currentTimeMillis() - start;
    106         long durationDeltaMs = Math.abs(subOpDurationMs - durationMs);
    107         String message = String.format(
    108                 "Expected duration=%sms, observed=%sms, delta=%sms, thresold=%sms",
    109                 subOpDurationMs,
    110                 durationMs,
    111                 durationDeltaMs,
    112                 TEST_DURATION_THRESHOLD_MS);
    113         // starting threads might have an impact in the order of 100s ms, depending on the load of
    114         // the system, so we relax the benchmark part of the test, and we just expect all operations
    115         // to complete
    116         assertTrue(message, durationDeltaMs < TEST_DURATION_THRESHOLD_MS);
    117 
    118         statsKeys = op.getStats().flatten().keySet();
    119         assertEquals(subOpCount, statsKeys.size());
    120         for (int i = 0; i < subOpCount; i++) {
    121             assertTrue(statsKeys.contains(String.format("%s_%03d%sexecuted",
    122                     ParallelSensorOperation.STATS_TAG, i, SensorStats.DELIMITER)));
    123         }
    124     }
    125 
    126     /**
    127      * Test that the {@link ParallelSensorOperation} functions correctly if there is a failure in
    128      * a child operation.
    129      */
    130     public void testParallelSensorOperation_fail() throws Exception {
    131         final int subOpCount = 100;
    132 
    133         ParallelSensorOperation op = new ParallelSensorOperation();
    134         for (int i = 0; i < subOpCount; i++) {
    135             // Trigger failures in the 5th, 55th operations at t=5ms, t=55ms
    136             SensorOperation subOp = new FakeSensorOperation(i % 50 == 5, i, TimeUnit.MILLISECONDS);
    137             op.add(subOp);
    138         }
    139 
    140         Set<String> statsKeys = op.getStats().flatten().keySet();
    141         assertEquals(0, statsKeys.size());
    142 
    143         try {
    144             op.execute(mTestNode);
    145             fail("AssertionError expected");
    146         } catch (AssertionError e) {
    147             // Expected
    148             System.out.println(e.getMessage());
    149         }
    150 
    151         statsKeys = op.getStats().flatten().keySet();
    152         assertEquals(subOpCount + 3, statsKeys.size());
    153         for (int i = 0; i < subOpCount; i++) {
    154             assertTrue(statsKeys.contains(String.format("%s_%03d%sexecuted",
    155                     ParallelSensorOperation.STATS_TAG, i, SensorStats.DELIMITER)));
    156             if (i % 50 == 5) {
    157                 assertTrue(statsKeys.contains(String.format("%s_%03d%s%s",
    158                         ParallelSensorOperation.STATS_TAG, i, SensorStats.DELIMITER,
    159                         SensorStats.ERROR)));
    160             }
    161 
    162         }
    163         assertTrue(statsKeys.contains(SensorStats.ERROR));
    164     }
    165 
    166     /**
    167      * Test that the {@link ParallelSensorOperation} functions correctly if a child exceeds the
    168      * timeout.
    169      */
    170     public void testParallelSensorOperation_timeout() throws Exception {
    171         final int subOpCount = 100;
    172 
    173         ParallelSensorOperation op = new ParallelSensorOperation(1, TimeUnit.SECONDS);
    174         for (int i = 0; i < subOpCount; i++) {
    175             // Trigger timeouts in the 5th, 55th operations (5 seconds vs 1 seconds)
    176             SensorOperation subOp = new FakeSensorOperation(i % 50 == 5 ? 5 : 0, TimeUnit.SECONDS);
    177             op.add(subOp);
    178         }
    179 
    180         Set<String> statsKeys = op.getStats().flatten().keySet();
    181         assertEquals(0, statsKeys.size());
    182 
    183         try {
    184             op.execute(mTestNode);
    185             fail("AssertionError expected");
    186         } catch (AssertionError e) {
    187             // Expected
    188             System.out.println(e.getMessage());
    189         }
    190 
    191         statsKeys = op.getStats().flatten().keySet();
    192         assertEquals(subOpCount - 2, statsKeys.size());
    193         for (int i = 0; i < subOpCount; i++) {
    194             if (i % 50 != 5) {
    195                 assertTrue(statsKeys.contains(String.format("%s_%03d%sexecuted",
    196                         ParallelSensorOperation.STATS_TAG, i, SensorStats.DELIMITER)));
    197             }
    198         }
    199     }
    200 
    201     /**
    202      * Test that the {@link RepeatingSensorOperation} functions correctly.
    203      */
    204     public void testRepeatingSensorOperation() throws Exception {
    205         final int iterations = 10;
    206         final int subOpDurationMs = 100;
    207 
    208         SensorOperation subOp = new FakeSensorOperation(subOpDurationMs, TimeUnit.MILLISECONDS);
    209         SensorOperation op = new RepeatingSensorOperation(subOp, iterations);
    210 
    211         Set<String> statsKeys = op.getStats().flatten().keySet();
    212         assertEquals(0, statsKeys.size());
    213 
    214         long start = System.currentTimeMillis();
    215         op.execute(mTestNode);
    216         long duration = System.currentTimeMillis() - start;
    217         assertTrue(Math.abs(subOpDurationMs * iterations - duration) < TEST_DURATION_THRESHOLD_MS);
    218 
    219         statsKeys = op.getStats().flatten().keySet();
    220         assertEquals(iterations, statsKeys.size());
    221         for (int i = 0; i < iterations; i++) {
    222             assertTrue(statsKeys.contains(String.format("%s_%03d%sexecuted",
    223                     RepeatingSensorOperation.STATS_TAG, i, SensorStats.DELIMITER)));
    224         }
    225     }
    226 
    227     /**
    228      * Test that the {@link RepeatingSensorOperation} functions correctly if there is a failure in
    229      * a child operation.
    230      */
    231     public void testRepeatingSensorOperation_fail() throws Exception {
    232         final int iterations = 100;
    233         final int failCount = 75;
    234 
    235         SensorOperation subOp = new FakeSensorOperation(0, TimeUnit.MILLISECONDS) {
    236             private int mExecutedCount = 0;
    237             private SensorStats mFakeStats = new SensorStats();
    238 
    239             @Override
    240             public void execute(ISensorTestNode parent) {
    241                 super.execute(parent);
    242                 mExecutedCount++;
    243 
    244                 if (failCount == mExecutedCount) {
    245                     doFail();
    246                 }
    247             }
    248 
    249             @Override
    250             public FakeSensorOperation clone() {
    251                 // Don't clone
    252                 mFakeStats = new SensorStats();
    253                 return this;
    254             }
    255 
    256             @Override
    257             public SensorStats getStats() {
    258                 return mFakeStats;
    259             }
    260         };
    261         SensorOperation op = new RepeatingSensorOperation(subOp, iterations);
    262 
    263         Set<String> statsKeys = op.getStats().flatten().keySet();
    264         assertEquals(0, statsKeys.size());
    265 
    266         try {
    267             op.execute(mTestNode);
    268             fail("AssertionError expected");
    269         } catch (AssertionError e) {
    270             // Expected
    271             System.out.println(e.getMessage());
    272         }
    273 
    274         statsKeys = op.getStats().flatten().keySet();
    275         assertEquals(failCount + 2, statsKeys.size());
    276         for (int i = 0; i < failCount; i++) {
    277             assertTrue(statsKeys.contains(String.format("%s_%03d%sexecuted",
    278                     RepeatingSensorOperation.STATS_TAG, i, SensorStats.DELIMITER)));
    279         }
    280         assertTrue(statsKeys.contains(String.format("%s_%03d%s%s",
    281                 RepeatingSensorOperation.STATS_TAG, failCount - 1, SensorStats.DELIMITER,
    282                 SensorStats.ERROR)));
    283         assertTrue(statsKeys.contains(SensorStats.ERROR));
    284     }
    285 
    286     /**
    287      * Test that the {@link SequentialSensorOperation} functions correctly.
    288      */
    289     public void testSequentialSensorOperation() throws Exception {
    290         final int subOpCount = 10;
    291         final int subOpDurationMs = 100;
    292 
    293         SequentialSensorOperation op = new SequentialSensorOperation();
    294         for (int i = 0; i < subOpCount; i++) {
    295             SensorOperation subOp = new FakeSensorOperation(subOpDurationMs,
    296                     TimeUnit.MILLISECONDS);
    297             op.add(subOp);
    298         }
    299 
    300         Set<String> statsKeys = op.getStats().flatten().keySet();
    301         assertEquals(0, statsKeys.size());
    302 
    303         long start = System.currentTimeMillis();
    304         op.execute(mTestNode);
    305         long duration = System.currentTimeMillis() - start;
    306         assertTrue(Math.abs(subOpDurationMs * subOpCount - duration) < TEST_DURATION_THRESHOLD_MS);
    307 
    308         statsKeys = op.getStats().flatten().keySet();
    309         assertEquals(subOpCount, statsKeys.size());
    310         for (int i = 0; i < subOpCount; i++) {
    311             assertTrue(statsKeys.contains(String.format("%s_%03d%sexecuted",
    312                     SequentialSensorOperation.STATS_TAG, i, SensorStats.DELIMITER)));
    313         }
    314     }
    315 
    316     /**
    317      * Test that the {@link SequentialSensorOperation} functions correctly if there is a failure in
    318      * a child operation.
    319      */
    320     public void testSequentialSensorOperation_fail() throws Exception {
    321         final int subOpCount = 100;
    322         final int failCount = 75;
    323 
    324         SequentialSensorOperation op = new SequentialSensorOperation();
    325         for (int i = 0; i < subOpCount; i++) {
    326             // Trigger a failure in the 75th operation only
    327             SensorOperation subOp = new FakeSensorOperation(i + 1 == failCount, 0,
    328                     TimeUnit.MILLISECONDS);
    329             op.add(subOp);
    330         }
    331 
    332         Set<String> statsKeys = op.getStats().flatten().keySet();
    333         assertEquals(0, statsKeys.size());
    334 
    335         try {
    336             op.execute(mTestNode);
    337             fail("AssertionError expected");
    338         } catch (AssertionError e) {
    339             // Expected
    340             System.out.println(e.getMessage());
    341         }
    342 
    343         statsKeys = op.getStats().flatten().keySet();
    344         assertEquals(failCount + 2, statsKeys.size());
    345         for (int i = 0; i < failCount; i++) {
    346             assertTrue(statsKeys.contains(String.format("%s_%03d%sexecuted",
    347                     SequentialSensorOperation.STATS_TAG, i, SensorStats.DELIMITER)));
    348         }
    349         assertTrue(statsKeys.contains(String.format("%s_%03d%s%s",
    350                 SequentialSensorOperation.STATS_TAG, failCount - 1, SensorStats.DELIMITER,
    351                 SensorStats.ERROR)));
    352         assertTrue(statsKeys.contains(SensorStats.ERROR));
    353     }
    354 }
    355