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
17package com.android.internal.os;
18
19import static org.junit.Assert.assertEquals;
20import static org.junit.Assert.assertNotNull;
21import static org.junit.Assert.assertNull;
22import static org.junit.Assert.assertTrue;
23
24import android.content.Context;
25import android.os.FileUtils;
26import android.os.SystemClock;
27import android.support.test.InstrumentationRegistry;
28import android.support.test.filters.SmallTest;
29import android.support.test.runner.AndroidJUnit4;
30
31import org.junit.After;
32import org.junit.Before;
33import org.junit.Test;
34import org.junit.runner.RunWith;
35
36import java.io.File;
37import java.io.OutputStream;
38import java.nio.ByteBuffer;
39import java.nio.file.Files;
40import java.util.Arrays;
41import java.util.Random;
42
43/**
44 * Test class for {@link KernelCpuProcReader}.
45 *
46 * $ atest FrameworksCoreTests:com.android.internal.os.KernelCpuProcReader
47 */
48@SmallTest
49@RunWith(AndroidJUnit4.class)
50public class KernelCpuProcReaderTest {
51
52    private File mRoot;
53    private File mTestDir;
54    private File mTestFile;
55    private Random mRand = new Random();
56
57    private KernelCpuProcReader mKernelCpuProcReader;
58
59    private Context getContext() {
60        return InstrumentationRegistry.getContext();
61    }
62
63    @Before
64    public void setUp() {
65        mTestDir = getContext().getDir("test", Context.MODE_PRIVATE);
66        mRoot = getContext().getFilesDir();
67        mTestFile = new File(mTestDir, "test.file");
68        mKernelCpuProcReader = new KernelCpuProcReader(mTestFile.getAbsolutePath());
69    }
70
71    @After
72    public void tearDown() throws Exception {
73        FileUtils.deleteContents(mTestDir);
74        FileUtils.deleteContents(mRoot);
75    }
76
77
78    /**
79     * Tests that reading will return null if the file does not exist.
80     */
81    @Test
82    public void testReadInvalidFile() throws Exception {
83        assertEquals(null, mKernelCpuProcReader.readBytes());
84    }
85
86    /**
87     * Tests that reading will always return null after 5 failures.
88     */
89    @Test
90    public void testReadErrorsLimit() throws Exception {
91        mKernelCpuProcReader.setThrottleInterval(0);
92        for (int i = 0; i < 3; i++) {
93            assertNull(mKernelCpuProcReader.readBytes());
94            SystemClock.sleep(50);
95        }
96
97        final byte[] data = new byte[1024];
98        mRand.nextBytes(data);
99        try (OutputStream os = Files.newOutputStream(mTestFile.toPath())) {
100            os.write(data);
101        }
102        assertTrue(Arrays.equals(data, toArray(mKernelCpuProcReader.readBytes())));
103
104        assertTrue(mTestFile.delete());
105        for (int i = 0; i < 3; i++) {
106            assertNull(mKernelCpuProcReader.readBytes());
107            SystemClock.sleep(50);
108        }
109        try (OutputStream os = Files.newOutputStream(mTestFile.toPath())) {
110            os.write(data);
111        }
112        assertNull(mKernelCpuProcReader.readBytes());
113    }
114
115    /**
116     * Tests reading functionality.
117     */
118    @Test
119    public void testSimpleRead() throws Exception {
120        final byte[] data = new byte[1024];
121        mRand.nextBytes(data);
122        try (OutputStream os = Files.newOutputStream(mTestFile.toPath())) {
123            os.write(data);
124        }
125        assertTrue(Arrays.equals(data, toArray(mKernelCpuProcReader.readBytes())));
126    }
127
128    /**
129     * Tests multiple reading functionality.
130     */
131    @Test
132    public void testMultipleRead() throws Exception {
133        mKernelCpuProcReader.setThrottleInterval(0);
134        for (int i = 0; i < 100; i++) {
135            final byte[] data = new byte[mRand.nextInt(102400) + 4];
136            mRand.nextBytes(data);
137            try (OutputStream os = Files.newOutputStream(mTestFile.toPath())) {
138                os.write(data);
139            }
140            assertTrue(Arrays.equals(data, toArray(mKernelCpuProcReader.readBytes())));
141            assertTrue(mTestFile.delete());
142        }
143    }
144
145    /**
146     * Tests reading with resizing.
147     */
148    @Test
149    public void testReadWithResize() throws Exception {
150        final byte[] data = new byte[128001];
151        mRand.nextBytes(data);
152        try (OutputStream os = Files.newOutputStream(mTestFile.toPath())) {
153            os.write(data);
154        }
155        assertTrue(Arrays.equals(data, toArray(mKernelCpuProcReader.readBytes())));
156    }
157
158    /**
159     * Tests that reading a file over the limit (1MB) will return null.
160     */
161    @Test
162    public void testReadOverLimit() throws Exception {
163        final byte[] data = new byte[1228800];
164        mRand.nextBytes(data);
165        try (OutputStream os = Files.newOutputStream(mTestFile.toPath())) {
166            os.write(data);
167        }
168        assertNull(mKernelCpuProcReader.readBytes());
169    }
170
171    /**
172     * Tests throttling. Deleting underlying file should not affect cache.
173     */
174    @Test
175    public void testThrottle() throws Exception {
176        mKernelCpuProcReader.setThrottleInterval(3000);
177        final byte[] data = new byte[20001];
178        mRand.nextBytes(data);
179        try (OutputStream os = Files.newOutputStream(mTestFile.toPath())) {
180            os.write(data);
181        }
182        assertTrue(Arrays.equals(data, toArray(mKernelCpuProcReader.readBytes())));
183        assertTrue(mTestFile.delete());
184        for (int i = 0; i < 5; i++) {
185            assertTrue(Arrays.equals(data, toArray(mKernelCpuProcReader.readBytes())));
186            SystemClock.sleep(10);
187        }
188        SystemClock.sleep(5000);
189        assertNull(mKernelCpuProcReader.readBytes());
190    }
191
192    private byte[] toArray(ByteBuffer buffer) {
193        assertNotNull(buffer);
194        byte[] arr = new byte[buffer.remaining()];
195        buffer.get(arr);
196        return arr;
197    }
198}
199