1 /* 2 * Copyright (C) 2018 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 package com.android.tradefed.device.metric; 17 18 import static org.junit.Assert.assertEquals; 19 import static org.mockito.Mockito.mock; 20 21 import com.android.tradefed.device.ITestDevice; 22 import com.android.tradefed.invoker.IInvocationContext; 23 import com.android.tradefed.invoker.InvocationContext; 24 import com.android.tradefed.metrics.proto.MetricMeasurement.Measurements; 25 import com.android.tradefed.metrics.proto.MetricMeasurement.Metric; 26 27 import org.junit.Before; 28 import org.junit.Test; 29 import org.junit.runner.RunWith; 30 import org.junit.runners.JUnit4; 31 32 import java.util.Collections; 33 import java.util.HashMap; 34 import java.util.List; 35 import java.util.UUID; 36 import java.util.concurrent.Callable; 37 import java.util.concurrent.ExecutionException; 38 import java.util.concurrent.ExecutorService; 39 import java.util.concurrent.Executors; 40 import java.util.concurrent.Future; 41 42 /** Functional tests for {@link DeviceMetricData} * */ 43 @RunWith(JUnit4.class) 44 public class DeviceMetricDataFuncTest { 45 46 private IInvocationContext mContext; 47 48 @Before setUp()49 public void setUp() { 50 mContext = new InvocationContext(); 51 ITestDevice device = mock(ITestDevice.class); 52 mContext.addAllocatedDevice("device1", device); 53 } 54 55 @Test testAddToMetricsMultiThreaded_success()56 public void testAddToMetricsMultiThreaded_success() 57 throws InterruptedException, ExecutionException { 58 // Incrementing threadCounts in steps and then testing makes sure that there is no 59 // flakyness, sticking to one value of threadCount will cause flakyness. 60 for (int threadCount = 10; threadCount <= 200; threadCount += 10) { 61 testAddToMetricsMultiThreaded(threadCount); 62 } 63 } 64 testAddToMetricsMultiThreaded(int threadCount)65 private void testAddToMetricsMultiThreaded(int threadCount) 66 throws InterruptedException, ExecutionException { 67 // Create the object to test. 68 DeviceMetricData deviceMetricData = new DeviceMetricData(mContext); 69 70 // Create a callable wrapper of DeviceMetricData#addStringMetric and 71 // DeviceMetricData#addToMetrics which will add a metric and then try to retrieve it. 72 Callable<HashMap<String, Metric>> task = 73 new Callable<HashMap<String, Metric>>() { 74 75 @Override 76 public HashMap<String, Metric> call() throws Exception { 77 deviceMetricData.addMetric( 78 UUID.randomUUID().toString(), 79 Metric.newBuilder() 80 .setMeasurements( 81 Measurements.newBuilder() 82 .setSingleString("value") 83 .build())); 84 HashMap<String, Metric> data = new HashMap<>(); 85 deviceMetricData.addToMetrics(data); 86 return data; 87 } 88 }; 89 // Create a copy of this callable for every thread. 90 List<Callable<HashMap<String, Metric>>> tasks = Collections.nCopies(threadCount, task); 91 92 // Create a thread pool to execute the tasks. 93 ExecutorService executorService = Executors.newFixedThreadPool(threadCount); 94 95 // Invoke the tasks. The call to ExecutorService#invokeAll blocks until all the threads are 96 // done. 97 List<Future<HashMap<String, Metric>>> futures = executorService.invokeAll(tasks); 98 99 // Store the results from all the tasks in a common data structure. 100 HashMap<String, Metric> metricsData = new HashMap<String, Metric>(futures.size()); 101 for (Future<HashMap<String, Metric>> future : futures) { 102 metricsData.putAll(future.get()); 103 } 104 105 // assert that the number of metrics out is equal to number of metrics in. 106 assertEquals(threadCount, metricsData.size()); 107 108 // discard all the threads. 109 executorService.shutdownNow(); 110 } 111 } 112