/* * Copyright (C) 2015 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.builder.profile; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import com.android.annotations.NonNull; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import java.io.IOException; import java.io.StringWriter; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; /** * Tests for the {@link ProcessRecorder} class */ public class ProcessRecorderTest { @Before public void setUp() { // reset for each test. ProcessRecorderFactory.setEnabled(true); ProcessRecorderFactory.sINSTANCE = new ProcessRecorderFactory(); } @After public void shutdown() throws InterruptedException { ProcessRecorderFactory.shutdown(); } @Test public void testBasicRecord() throws InterruptedException { StringWriter stringWriter = new StringWriter(); ProcessRecorder.JsonRecordWriter jsonRecordWriter = new ProcessRecorder.JsonRecordWriter(stringWriter); ProcessRecorderFactory.initializeForTests(jsonRecordWriter); ThreadRecorder.get().record(ExecutionType.SOME_RANDOM_PROCESSING, new Recorder.Block<Integer>() { @Override public Integer call() throws Exception { return 10; } }); ProcessRecorder.get().finish(); String jsonText = stringWriter.toString(); assertNotNull(jsonText); Assert.assertFalse(jsonText.isEmpty()); assertTrue(jsonText.contains("id")); assertTrue(jsonText.contains("parentId")); assertTrue(jsonText.contains("startTimeInMs")); assertTrue(jsonText.contains("\"type\":\"SOME_RANDOM_PROCESSING\"")); } @Test public void testRecordWithAttributes() throws InterruptedException { StringWriter stringWriter = new StringWriter(); ProcessRecorder.JsonRecordWriter jsonRecordWriter = new ProcessRecorder.JsonRecordWriter(stringWriter); ProcessRecorderFactory.initializeForTests(jsonRecordWriter); ThreadRecorder.get().record(ExecutionType.SOME_RANDOM_PROCESSING, new Recorder.Block<Integer>() { @Override public Integer call() throws Exception { return 10; } }, new Recorder.Property("variant", "foo")); ProcessRecorder.get().finish(); String jsonText = stringWriter.toString(); assertTrue(jsonText.contains("[{\"name\":\"variant\",\"value\":\"foo\"}]")); } @Test public void testRecordsOrder() throws InterruptedException { final List<ExecutionRecord> records = new ArrayList<ExecutionRecord>(); ProcessRecorder.ExecutionRecordWriter recorderWriter = new ProcessRecorder.ExecutionRecordWriter() { @Override public void write(@NonNull ExecutionRecord executionRecord) { records.add(executionRecord); } @Override public void close() throws IOException { } }; ProcessRecorderFactory.initializeForTests(recorderWriter); ThreadRecorder.get().record(ExecutionType.SOME_RANDOM_PROCESSING, new Recorder.Block<Integer>() { @Override public Integer call() throws Exception { return ThreadRecorder.get().record(ExecutionType.SOME_RANDOM_PROCESSING, new Recorder.Block<Integer>() { @Override public Integer call() throws Exception { return 10; } }); } }); ProcessRecorder.get().finish(); setExecutionRecords(records); // delete the initial metadata record. assertEquals(ExecutionType.INITIAL_METADATA, records.remove(0).type); assertEquals(2, records.size()); assertTrue(records.get(1).parentId == records.get(0).id); } @Test public void testMultipleSpans() throws InterruptedException { final List<ExecutionRecord> records = new ArrayList<ExecutionRecord>(); ProcessRecorder.ExecutionRecordWriter recorderWriter = new ProcessRecorder.ExecutionRecordWriter() { @Override public void write(@NonNull ExecutionRecord executionRecord) { records.add(executionRecord); } @Override public void close() throws IOException { } }; ProcessRecorderFactory.initializeForTests(recorderWriter); Integer value = ThreadRecorder.get().record(ExecutionType.SOME_RANDOM_PROCESSING, new Recorder.Block<Integer>() { @Override public Integer call() throws Exception { return ThreadRecorder.get().record(ExecutionType.SOME_RANDOM_PROCESSING, new Recorder.Block<Integer>() { @Override public Integer call() throws Exception { Integer first = ThreadRecorder.get().record( ExecutionType.SOME_RANDOM_PROCESSING, new Recorder.Block<Integer>() { @Override public Integer call() throws Exception { return 1; } }); Integer second = ThreadRecorder.get().record( ExecutionType.SOME_RANDOM_PROCESSING, new Recorder.Block<Integer>() { @Override public Integer call() throws Exception { return 3; } }); Integer third = ThreadRecorder.get().record( ExecutionType.SOME_RANDOM_PROCESSING, new Recorder.Block<Integer>() { @Override public Integer call() throws Exception { Integer value = ThreadRecorder.get().record( ExecutionType.SOME_RANDOM_PROCESSING, new Recorder.Block<Integer>() { @Override public Integer call() throws Exception { return 7; } }); assertNotNull(value); return 5 + value; } }); assertNotNull(first); assertNotNull(second); assertNotNull(third); return first + second + third; } }); } }); assertNotNull(value); assertEquals(16, value.intValue()); ProcessRecorder.get().finish(); // delete the initial metadata record. assertEquals(ExecutionType.INITIAL_METADATA, records.remove(0).type); assertEquals(6, records.size()); // re-order by event id. setExecutionRecords(records); assertEquals(records.get(0).id, records.get(1).parentId); assertEquals(records.get(1).id, records.get(2).parentId); assertEquals(records.get(1).id, records.get(3).parentId); assertEquals(records.get(1).id, records.get(4).parentId); assertEquals(records.get(4).id, records.get(5).parentId); assertTrue( records.get(1).durationInMs >= records.get(2).durationInMs + records.get(3).durationInMs + records.get(4).durationInMs); assertTrue(records.get(4).durationInMs >= records.get(5).durationInMs); } private static void setExecutionRecords(List<ExecutionRecord> records) { Collections.sort(records, new Comparator<ExecutionRecord>() { @Override public int compare(ExecutionRecord o1, ExecutionRecord o2) { return new Long(o1.id).compareTo(o2.id); } }); } }