Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2008 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.os.cts;
     18 
     19 import android.os.FileObserver;
     20 import android.test.AndroidTestCase;
     21 
     22 import java.io.File;
     23 import java.io.FileOutputStream;
     24 import java.util.ArrayList;
     25 import java.util.Arrays;
     26 import java.util.List;
     27 
     28 public class FileObserverTest extends AndroidTestCase {
     29 
     30     private File mTestFile;
     31     private File mTestDir;
     32     private File mMoveDestFile;
     33     private FileOutputStream mOut;
     34     private static final String PATH = "/PATH";
     35     private static final String TEST_FILE = "file_observer_test.txt";
     36     private static final String TEST_DIR = "fileobserver_dir";
     37     private static final int FILE_DATA = 0x20;
     38     private static final int UNDEFINED = 0x8000;
     39     private static final long DELAY_MSECOND = 2000;
     40 
     41     @Override
     42     protected void setUp() throws Exception {
     43         super.setUp();
     44         File dir = getContext().getFilesDir();
     45         mTestFile = new File(dir, TEST_FILE);
     46         mTestFile.createNewFile();
     47         mTestDir = new File(dir, TEST_DIR);
     48         mTestDir.mkdirs();
     49     }
     50 
     51     @Override
     52     protected void tearDown() throws Exception {
     53         super.tearDown();
     54         if (mTestFile != null && mTestFile.exists()) {
     55             mTestFile.delete();
     56         }
     57 
     58         if (mMoveDestFile != null && mMoveDestFile.exists()) {
     59             mMoveDestFile.delete();
     60         }
     61 
     62         if (mTestDir != null && mTestDir.exists()) {
     63             mTestDir.delete();
     64         }
     65 
     66         if (mOut != null) {
     67             mOut.close();
     68         }
     69     }
     70 
     71     public void testConstructor() {
     72         // new the instance
     73         new MockFileObserver(PATH);
     74         // new the instance
     75         new MockFileObserver(PATH, FileObserver.ACCESS);
     76     }
     77 
     78     /*
     79      * Test point
     80      * 1. Observe a dir, when it's child file have been written and closed,
     81      * observer should get modify open-child modify-child and closed-write events.
     82      * 2. While stop observer a dir, observer should't get any event while delete it's child file.
     83      * 3. Observer a dir, when create delete a child file and delete self,
     84      * observer should get create-child close-nowrite delete-child delete-self events.
     85      * 4. Observer a file, the file moved from dir and the file moved to dir, move the file,
     86      * file observer should get move-self event,
     87      * moved from dir observer should get moved-from event,
     88      * moved to dir observer should get moved-to event.
     89      */
     90     public void testFileObserver() throws Exception {
     91         MockFileObserver fileObserver = null;
     92         int[] expected = null;
     93         FileEvent[] moveEvents = null;
     94 
     95         fileObserver = new MockFileObserver(mTestFile.getParent());
     96         try {
     97             fileObserver.startWatching();
     98             mOut = new FileOutputStream(mTestFile);
     99 
    100             mOut.write(FILE_DATA); // modify, open, write, modify
    101             mOut.close(); // close_write
    102 
    103             expected = new int[] {FileObserver.MODIFY, FileObserver.OPEN, FileObserver.MODIFY,
    104                     FileObserver.CLOSE_WRITE};
    105             moveEvents = waitForEvent(fileObserver);
    106             assertEventsEquals(expected, moveEvents);
    107 
    108             fileObserver.stopWatching();
    109 
    110             // action after observer stop watching
    111             mTestFile.delete(); // delete
    112 
    113             // should not get any event
    114             expected = new int[] {UNDEFINED};
    115             moveEvents = waitForEvent(fileObserver);
    116             assertEventsEquals(expected, moveEvents);
    117         } finally {
    118             fileObserver.stopWatching();
    119             mOut.close();
    120             mOut = null;
    121         }
    122 
    123         fileObserver = new MockFileObserver(mTestDir.getPath());
    124         try {
    125             fileObserver.startWatching();
    126             mTestFile = new File(mTestDir, TEST_FILE);
    127             assertTrue(mTestFile.createNewFile());
    128             assertTrue(mTestFile.exists());
    129             mTestFile.delete();
    130             mTestDir.delete();
    131 
    132             expected = new int[] {FileObserver.CREATE,
    133                     FileObserver.OPEN, FileObserver.CLOSE_WRITE,
    134                     FileObserver.DELETE, FileObserver.DELETE_SELF, UNDEFINED};
    135             moveEvents = waitForEvent(fileObserver);
    136             assertEventsEquals(expected, moveEvents);
    137         } finally {
    138             fileObserver.stopWatching();
    139         }
    140 
    141         File dir = getContext().getFilesDir();
    142         mTestFile = new File(dir, TEST_FILE);
    143         mTestFile.createNewFile();
    144         mTestDir = new File(dir, TEST_DIR);
    145         mTestDir.mkdirs();
    146         mMoveDestFile = new File(mTestDir, TEST_FILE);
    147         MockFileObserver movedFrom = new MockFileObserver(dir.getPath());
    148         MockFileObserver movedTo = new MockFileObserver(mTestDir.getPath());
    149         fileObserver = new MockFileObserver(mTestFile.getPath());
    150         try {
    151             movedFrom.startWatching();
    152             movedTo.startWatching();
    153             fileObserver.startWatching();
    154             mTestFile.renameTo(mMoveDestFile);
    155 
    156             expected = new int[] {FileObserver.MOVE_SELF};
    157             moveEvents = waitForEvent(fileObserver);
    158             assertEventsEquals(expected, moveEvents);
    159 
    160             expected = new int[] {FileObserver.MOVED_FROM};
    161             moveEvents = waitForEvent(movedFrom);
    162             assertEventsEquals(expected, moveEvents);
    163 
    164             expected = new int[] {FileObserver.MOVED_TO};
    165             moveEvents = waitForEvent(movedTo);
    166             assertEventsEquals(expected, moveEvents);
    167         } finally {
    168             fileObserver.stopWatching();
    169             movedTo.stopWatching();
    170             movedFrom.stopWatching();
    171         }
    172 
    173         // Because Javadoc didn't specify when should a event happened,
    174         // here ACCESS ATTRIB we found no way to test.
    175     }
    176 
    177     private void assertEventsEquals(final int[] expected, final FileEvent[] moveEvents) {
    178         List<Integer> expectedEvents = new ArrayList<Integer>();
    179         for (int i = 0; i < expected.length; i++) {
    180             expectedEvents.add(expected[i]);
    181         }
    182         List<FileEvent> actualEvents = Arrays.asList(moveEvents);
    183         String message = "Expected: " + expectedEvents + " Actual: " + actualEvents;
    184         assertEquals(message, expected.length, moveEvents.length);
    185         for (int i = 0; i < expected.length; i++) {
    186             assertEquals(message, expected[i], moveEvents[i].event);
    187         }
    188     }
    189 
    190     private FileEvent[] waitForEvent(MockFileObserver fileObserver)
    191             throws InterruptedException {
    192         Thread.sleep(DELAY_MSECOND);
    193         synchronized (fileObserver) {
    194             return fileObserver.getEvents();
    195        }
    196     }
    197 
    198     private static class FileEvent {
    199         public int event = UNDEFINED;
    200         public String path;
    201 
    202         public FileEvent(final int event, final String path) {
    203             this.event = event;
    204             this.path = path;
    205         }
    206 
    207         @Override
    208         public String toString() {
    209             return Integer.toString(event);
    210         }
    211     }
    212 
    213     /*
    214      * MockFileObserver
    215      */
    216     private static class MockFileObserver extends FileObserver {
    217 
    218         private List<FileEvent> mEvents = new ArrayList<FileEvent>();
    219 
    220         public MockFileObserver(String path) {
    221             super(path);
    222         }
    223 
    224         public MockFileObserver(String path, int mask) {
    225             super(path, mask);
    226         }
    227 
    228         @Override
    229         public synchronized void onEvent(int event, String path) {
    230             mEvents.add(new FileEvent(event, path));
    231         }
    232 
    233         public synchronized FileEvent[] getEvents() {
    234             final FileEvent[] events = new FileEvent[mEvents.size()];
    235             mEvents.toArray(events);
    236             mEvents.clear();
    237             return events;
    238         }
    239     }
    240 }
    241