15873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath/*
25873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath * Copyright (C) 2016 The Android Open Source Project
35873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath *
45873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath * Licensed under the Apache License, Version 2.0 (the "License");
55873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath * you may not use this file except in compliance with the License.
65873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath * You may obtain a copy of the License at
75873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath *
85873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath *      http://www.apache.org/licenses/LICENSE-2.0
95873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath *
105873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath * Unless required by applicable law or agreed to in writing, software
115873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath * distributed under the License is distributed on an "AS IS" BASIS,
125873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath * See the License for the specific language governing permissions and
145873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath * limitations under the License
155873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath */
165873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
175873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamathpackage dalvik.system;
185873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
195873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamathimport junit.framework.TestCase;
205873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
215873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamathimport java.io.File;
225873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamathimport java.io.FileInputStream;
235873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamathimport java.io.FileOutputStream;
245873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamathimport java.util.ArrayList;
255873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamathimport java.util.List;
265873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
275873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath/**
285873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath * Created by narayan on 1/7/16.
295873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath */
305873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamathpublic class BlockGuardTest extends TestCase {
315873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
325873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath    private BlockGuard.Policy oldPolicy;
335873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath    private RecordingPolicy recorder = new RecordingPolicy();
345873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
355873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath    @Override
365873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath    public void setUp() {
375873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        oldPolicy = BlockGuard.getThreadPolicy();
385873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        BlockGuard.setThreadPolicy(recorder);
395873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath    }
405873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
415873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath    @Override
425873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath    public void tearDown() {
435873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        BlockGuard.setThreadPolicy(oldPolicy);
445873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        recorder.clear();
455873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath    }
465873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
475873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath    public void testFile() throws Exception {
485873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        File f = File.createTempFile("foo", "bar");
495873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        recorder.expectAndClear("onReadFromDisk", "onWriteToDisk");
505873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
515873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        f.getAbsolutePath();
525873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        f.getParentFile();
535873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        f.getName();
545873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        f.getParent();
555873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        f.getPath();
565873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        f.isAbsolute();
575873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        recorder.expectNoViolations();
585873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
595873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        f.mkdir();
605873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        recorder.expectAndClear("onWriteToDisk");
615873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
625873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        f.listFiles();
635873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        recorder.expectAndClear("onReadFromDisk");
645873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
655873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        f.list();
665873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        recorder.expectAndClear("onReadFromDisk");
675873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
685873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        f.length();
695873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        recorder.expectAndClear("onReadFromDisk");
705873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
715873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        f.lastModified();
725873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        recorder.expectAndClear("onReadFromDisk");
735873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
745873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        f.canExecute();
755873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        recorder.expectAndClear("onReadFromDisk");
765873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
775873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        f.canRead();
785873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        recorder.expectAndClear("onReadFromDisk");
795873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
805873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        f.canWrite();
815873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        recorder.expectAndClear("onReadFromDisk");
825873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
835873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        f.isFile();
845873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        recorder.expectAndClear("onReadFromDisk");
855873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
865873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        f.isDirectory();
875873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        recorder.expectAndClear("onReadFromDisk");
885873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
895873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        f.setExecutable(true, false);
905873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        recorder.expectAndClear("onWriteToDisk");
915873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
925873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        f.setReadable(true, false);
935873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        recorder.expectAndClear("onWriteToDisk");
945873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
955873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        f.setWritable(true, false);
965873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        recorder.expectAndClear("onWriteToDisk");
975873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
985873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        f.delete();
995873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        recorder.expectAndClear("onWriteToDisk");
1005873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath    }
1015873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
1025873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath    public void testFileInputStream() throws Exception {
1035873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        File f = new File("/proc/version");
1045873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        recorder.clear();
1055873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
1065873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        FileInputStream fis = new FileInputStream(f);
1075873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        recorder.expectAndClear("onReadFromDisk");
1085873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
1095873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        fis.read(new byte[4],0, 4);
1105873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        recorder.expectAndClear("onReadFromDisk");
1115873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
1125873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        fis.read();
1135873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        recorder.expectAndClear("onReadFromDisk");
1145873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
1155873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        fis.skip(1);
1165873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        recorder.expectAndClear("onReadFromDisk");
1175873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
1185873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        fis.close();
1195873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath    }
1205873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
1215873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath    public void testFileOutputStream() throws Exception {
1225873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        File f = File.createTempFile("foo", "bar");
1235873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        recorder.clear();
1245873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
1255873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        FileOutputStream fos = new FileOutputStream(f);
1265873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        recorder.expectAndClear("onWriteToDisk");
1275873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
1285873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        fos.write(new byte[3]);
1295873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        recorder.expectAndClear("onWriteToDisk");
1305873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
1315873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        fos.write(4);
1325873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        recorder.expectAndClear("onWriteToDisk");
1335873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
1345873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        fos.flush();
1355873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        recorder.expectNoViolations();
1365873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
1375873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        fos.close();
1385873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        recorder.expectNoViolations();
1395873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath    }
1405873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
1415873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
1425873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath    public static class RecordingPolicy implements BlockGuard.Policy {
1435873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        private final List<String> violations = new ArrayList<>();
1445873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
1455873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        @Override
1465873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        public void onWriteToDisk() {
1475873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath            addViolation("onWriteToDisk");
1485873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        }
1495873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
1505873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        @Override
1515873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        public void onReadFromDisk() {
1525873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath            addViolation("onReadFromDisk");
1535873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        }
1545873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
1555873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        @Override
1565873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        public void onNetwork() {
1575873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath            addViolation("onNetwork");
1585873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        }
1595873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
1605873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        private void addViolation(String type) {
1615873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath            StackTraceElement[] threadTrace = Thread.currentThread().getStackTrace();
1625873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
1635873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath            final StackTraceElement violator = threadTrace[4];
1645873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath            violations.add(type + " [caller= " + violator.getMethodName() + "]");
1655873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        }
1665873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
1675873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        public void clear() {
1685873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath            violations.clear();
1695873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        }
1705873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
1715873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        public void expectNoViolations() {
1725873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath            if (violations.size() != 0) {
1735873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath                throw new AssertionError("Expected 0 violations but found " + violations.size());
1745873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath            }
1755873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        }
1765873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
1775873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        public void expectAndClear(String... expected) {
1785873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath            if (expected.length != violations.size()) {
1795873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath                throw new AssertionError("Expected " + expected.length + " violations but found "
1805873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath                        + violations.size());
1815873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath            }
1825873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
1835873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath            for (int i = 0; i < expected.length; ++i) {
1845873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath                if (!violations.get(i).startsWith(expected[i])) {
1855873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath                    throw new AssertionError("Expected: " + expected[i] + " but was "
1865873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath                            + violations.get(i));
1875873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath                }
1885873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath            }
1895873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
1905873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath            clear();
1915873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        }
1925873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath
1935873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        @Override
1945873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        public int getPolicyMask() {
1955873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath            return 0;
1965873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath        }
1975873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath    }
1985873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath}
199