Home | History | Annotate | Download | only in result
      1 /*
      2  * Copyright (C) 2011 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.result;
     17 
     18 import com.android.tradefed.device.ITestDevice;
     19 import com.android.tradefed.util.ArrayUtil;
     20 
     21 import junit.framework.TestCase;
     22 
     23 import org.easymock.EasyMock;
     24 
     25 import java.io.File;
     26 import java.util.HashMap;
     27 import java.util.List;
     28 import java.util.Map;
     29 
     30 /**
     31  * Unit tests for {@link DeviceFileReporter}
     32  */
     33 public class DeviceFileReporterTest extends TestCase {
     34     DeviceFileReporter dfr = null;
     35     ITestDevice mDevice = null;
     36     ITestInvocationListener mListener = null;
     37 
     38     // Used to control what ISS is returned
     39     InputStreamSource mDfrIss = null;
     40 
     41     @SuppressWarnings("serial")
     42     private static class FakeFile extends File {
     43         private final String mName;
     44         private final long mSize;
     45 
     46         FakeFile(String name, long size) {
     47             super(name);
     48             mName = name;
     49             mSize = size;
     50         }
     51         @Override
     52         public String toString() {
     53             return mName;
     54         }
     55         @Override
     56         public long length() {
     57             return mSize;
     58         }
     59     }
     60 
     61     @Override
     62     public void setUp() throws Exception {
     63         mDevice = EasyMock.createMock(ITestDevice.class);
     64         EasyMock.expect(mDevice.getSerialNumber()).andStubReturn("serial");
     65 
     66         mListener = EasyMock.createMock(ITestInvocationListener.class);
     67         dfr =
     68                 new DeviceFileReporter(mDevice, mListener) {
     69                     @Override
     70                     InputStreamSource createIssForFile(File file) {
     71                         return mDfrIss;
     72                     }
     73                 };
     74     }
     75 
     76     public void testSimple() throws Exception {
     77         final String result = "/data/tombstones/tombstone_00\r\n";
     78         final String filename = "/data/tombstones/tombstone_00";
     79         final String tombstone = "What do you want on your tombstone?";
     80         dfr.addPatterns("/data/tombstones/*");
     81 
     82         EasyMock.expect(mDevice.executeShellCommand(EasyMock.eq("ls /data/tombstones/*")))
     83           .andReturn(result);
     84         // This gets passed verbatim to createIssForFile above
     85         EasyMock.expect(mDevice.pullFile(EasyMock.eq(filename)))
     86                 .andReturn(new FakeFile(filename, tombstone.length()));
     87 
     88         mDfrIss = new ByteArrayInputStreamSource(tombstone.getBytes());
     89         // FIXME: use captures here to make sure we get the string back out
     90         mListener.testLog(EasyMock.eq(filename), EasyMock.eq(LogDataType.UNKNOWN),
     91                 EasyMock.eq(mDfrIss));
     92 
     93         replayMocks();
     94         dfr.run();
     95         verifyMocks();
     96     }
     97 
     98     // Files' paths should be trimmed to remove white spaces at the end of the lines.
     99     public void testTrim() throws Exception {
    100         // Result with trailing white spaces.
    101         final String result = "/data/tombstones/tombstone_00  \r\n";
    102 
    103         final String filename = "/data/tombstones/tombstone_00";
    104         final String tombstone = "What do you want on your tombstone?";
    105         dfr.addPatterns("/data/tombstones/*");
    106 
    107         EasyMock.expect(mDevice.executeShellCommand(EasyMock.eq("ls /data/tombstones/*")))
    108             .andReturn(result);
    109         // This gets passed verbatim to createIssForFile above
    110         EasyMock.expect(mDevice.pullFile(EasyMock.eq(filename)))
    111             .andReturn(new FakeFile(filename, tombstone.length()));
    112 
    113         mDfrIss = new ByteArrayInputStreamSource(tombstone.getBytes());
    114         mListener.testLog(EasyMock.eq(filename), EasyMock.eq(LogDataType.UNKNOWN),
    115             EasyMock.eq(mDfrIss));
    116 
    117         replayMocks();
    118         List<String> filenames = dfr.run();
    119         assertEquals(filename, filenames.get(0));
    120         verifyMocks();
    121     }
    122 
    123     public void testLineEnding_LF() throws Exception {
    124         final String[] filenames = {"/data/tombstones/tombstone_00",
    125                 "/data/tombstones/tombstone_01",
    126                 "/data/tombstones/tombstone_02",
    127                 "/data/tombstones/tombstone_03",
    128                 "/data/tombstones/tombstone_04"};
    129         String result = ArrayUtil.join("\n", (Object[])filenames);
    130         final String tombstone = "What do you want on your tombstone?";
    131         dfr.addPatterns("/data/tombstones/*");
    132 
    133         EasyMock.expect(mDevice.executeShellCommand((String)EasyMock.anyObject()))
    134                 .andReturn(result);
    135         mDfrIss = new ByteArrayInputStreamSource(tombstone.getBytes());
    136         // This gets passed verbatim to createIssForFile above
    137         for (String filename : filenames) {
    138             EasyMock.expect(mDevice.pullFile(EasyMock.eq(filename))).andReturn(
    139                     new FakeFile(filename, tombstone.length()));
    140 
    141             // FIXME: use captures here to make sure we get the string back out
    142             mListener.testLog(EasyMock.eq(filename), EasyMock.eq(LogDataType.UNKNOWN),
    143                     EasyMock.eq(mDfrIss));
    144         }
    145         replayMocks();
    146         dfr.run();
    147         verifyMocks();
    148     }
    149 
    150     public void testLineEnding_CRLF() throws Exception {
    151         final String[] filenames = {"/data/tombstones/tombstone_00",
    152                 "/data/tombstones/tombstone_01",
    153                 "/data/tombstones/tombstone_02",
    154                 "/data/tombstones/tombstone_03",
    155                 "/data/tombstones/tombstone_04"};
    156         String result = ArrayUtil.join("\r\n", (Object[])filenames);
    157         final String tombstone = "What do you want on your tombstone?";
    158         dfr.addPatterns("/data/tombstones/*");
    159 
    160         EasyMock.expect(mDevice.executeShellCommand((String)EasyMock.anyObject()))
    161                 .andReturn(result);
    162         mDfrIss = new ByteArrayInputStreamSource(tombstone.getBytes());
    163         // This gets passed verbatim to createIssForFile above
    164         for (String filename : filenames) {
    165             EasyMock.expect(mDevice.pullFile(EasyMock.eq(filename))).andReturn(
    166                     new FakeFile(filename, tombstone.length()));
    167 
    168             // FIXME: use captures here to make sure we get the string back out
    169             mListener.testLog(EasyMock.eq(filename), EasyMock.eq(LogDataType.UNKNOWN),
    170                     EasyMock.eq(mDfrIss));
    171         }
    172         replayMocks();
    173         dfr.run();
    174         verifyMocks();
    175     }
    176 
    177     /**
    178      * Make sure that the Reporter behaves as expected when a file is matched by multiple patterns
    179      */
    180     public void testRepeat_skip() throws Exception {
    181         final String result1 = "/data/files/file.png\r\n";
    182         final String result2 = "/data/files/file.png\r\n/data/files/file.xml\r\n";
    183         final String pngFilename = "/data/files/file.png";
    184         final String xmlFilename = "/data/files/file.xml";
    185         final Map<String, LogDataType> patMap = new HashMap<>(2);
    186         patMap.put("/data/files/*.png", LogDataType.PNG);
    187         patMap.put("/data/files/*", LogDataType.UNKNOWN);
    188 
    189         final String pngContents = "This is PNG data";
    190         final String xmlContents = "<!-- This is XML data -->";
    191         final InputStreamSource pngIss = new ByteArrayInputStreamSource(pngContents.getBytes());
    192         final InputStreamSource xmlIss = new ByteArrayInputStreamSource(xmlContents.getBytes());
    193 
    194         dfr =
    195                 new DeviceFileReporter(mDevice, mListener) {
    196                     @Override
    197                     InputStreamSource createIssForFile(File file) {
    198                         if (file.toString().endsWith(".png")) {
    199                             return pngIss;
    200                         } else if (file.toString().endsWith(".xml")) {
    201                             return xmlIss;
    202                         }
    203                         return null;
    204                     }
    205                 };
    206         dfr.addPatterns(patMap);
    207         dfr.setInferUnknownDataTypes(false);
    208 
    209         // Set file listing pulling, and reporting expectations
    210         // Expect that we go through the entire process for the PNG file, and then go through
    211         // the entire process again for the XML file
    212         EasyMock.expect(mDevice.executeShellCommand((String)EasyMock.anyObject()))
    213                 .andReturn(result1);
    214         EasyMock.expect(mDevice.pullFile(EasyMock.eq(pngFilename)))
    215                 .andReturn(new FakeFile(pngFilename, pngContents.length()));
    216         mListener.testLog(EasyMock.eq(pngFilename), EasyMock.eq(LogDataType.PNG),
    217                 EasyMock.eq(pngIss));
    218 
    219         EasyMock.expect(mDevice.executeShellCommand((String)EasyMock.anyObject()))
    220                 .andReturn(result2);
    221         EasyMock.expect(mDevice.pullFile(EasyMock.eq(xmlFilename)))
    222                 .andReturn(new FakeFile(xmlFilename, xmlContents.length()));
    223         mListener.testLog(EasyMock.eq(xmlFilename), EasyMock.eq(LogDataType.UNKNOWN),
    224                 EasyMock.eq(xmlIss));
    225 
    226         replayMocks();
    227         dfr.run();
    228         verifyMocks();
    229         // FIXME: use captures here to make sure we get the string back out
    230     }
    231 
    232     /**
    233      * Make sure that the Reporter behaves as expected when a file is matched by multiple patterns
    234      */
    235     public void testRepeat_noSkip() throws Exception {
    236         final String result1 = "/data/files/file.png\r\n";
    237         final String result2 = "/data/files/file.png\r\n/data/files/file.xml\r\n";
    238         final String pngFilename = "/data/files/file.png";
    239         final String xmlFilename = "/data/files/file.xml";
    240         final Map<String, LogDataType> patMap = new HashMap<>(2);
    241         patMap.put("/data/files/*.png", LogDataType.PNG);
    242         patMap.put("/data/files/*", LogDataType.UNKNOWN);
    243 
    244         final String pngContents = "This is PNG data";
    245         final String xmlContents = "<!-- This is XML data -->";
    246         final InputStreamSource pngIss = new ByteArrayInputStreamSource(pngContents.getBytes());
    247         final InputStreamSource xmlIss = new ByteArrayInputStreamSource(xmlContents.getBytes());
    248 
    249         dfr =
    250                 new DeviceFileReporter(mDevice, mListener) {
    251                     @Override
    252                     InputStreamSource createIssForFile(File file) {
    253                         if (file.toString().endsWith(".png")) {
    254                             return pngIss;
    255                         } else if (file.toString().endsWith(".xml")) {
    256                             return xmlIss;
    257                         }
    258                         return null;
    259                     }
    260                 };
    261         dfr.addPatterns(patMap);
    262         dfr.setInferUnknownDataTypes(false);
    263         // this should cause us to see three pulls instead of two
    264         dfr.setSkipRepeatFiles(false);
    265 
    266         // Set file listing pulling, and reporting expectations
    267         // Expect that we go through the entire process for the PNG file, and then go through
    268         // the entire process again for the PNG file (again) and the XML file
    269         EasyMock.expect(mDevice.executeShellCommand((String)EasyMock.anyObject()))
    270                 .andReturn(result1);
    271         EasyMock.expect(mDevice.pullFile(EasyMock.eq(pngFilename)))
    272                 .andReturn(new FakeFile(pngFilename, pngContents.length()));
    273         mListener.testLog(EasyMock.eq(pngFilename), EasyMock.eq(LogDataType.PNG),
    274                 EasyMock.eq(pngIss));
    275 
    276         // Note that the PNG file is picked up with the UNKNOWN data type this time
    277         EasyMock.expect(mDevice.executeShellCommand((String)EasyMock.anyObject()))
    278                 .andReturn(result2);
    279         EasyMock.expect(mDevice.pullFile(EasyMock.eq(pngFilename)))
    280                 .andReturn(new FakeFile(pngFilename, pngContents.length()));
    281         mListener.testLog(EasyMock.eq(pngFilename), EasyMock.eq(LogDataType.UNKNOWN),
    282                 EasyMock.eq(pngIss));
    283         EasyMock.expect(mDevice.pullFile(EasyMock.eq(xmlFilename)))
    284                 .andReturn(new FakeFile(xmlFilename, xmlContents.length()));
    285         mListener.testLog(EasyMock.eq(xmlFilename), EasyMock.eq(LogDataType.UNKNOWN),
    286                 EasyMock.eq(xmlIss));
    287 
    288         replayMocks();
    289         dfr.run();
    290         verifyMocks();
    291         // FIXME: use captures here to make sure we get the string back out
    292     }
    293 
    294     /**
    295      * Make sure that we correctly handle the case where a file doesn't exist while matching the
    296      * exact name.
    297      * <p />
    298      * This verifies a fix for a bug where we would mistakenly treat the
    299      * "file.txt: No such file or directory" message as a filename.  This would happen when we tried
    300      * to match an exact filename that doesn't exist, rather than using a shell glob.
    301      */
    302     public void testNoExist() throws Exception {
    303         final String file = "/data/traces.txt";
    304         final String result = file + ": No such file or directory\r\n";
    305         dfr.addPatterns(file);
    306 
    307         EasyMock.expect(mDevice.executeShellCommand((String)EasyMock.anyObject()))
    308                 .andReturn(result);
    309 
    310         replayMocks();
    311         dfr.run();
    312         // No pull attempt should happen
    313         verifyMocks();
    314     }
    315 
    316     public void testTwoFiles() throws Exception {
    317         final String result = "/data/tombstones/tombstone_00\r\n/data/tombstones/tombstone_01\r\n";
    318         final String filename1 = "/data/tombstones/tombstone_00";
    319         final String filename2 = "/data/tombstones/tombstone_01";
    320         final String tombstone = "What do you want on your tombstone?";
    321         dfr.addPatterns("/data/tombstones/*");
    322 
    323         // Search the filesystem
    324         EasyMock.expect(mDevice.executeShellCommand((String)EasyMock.anyObject()))
    325                 .andReturn(result);
    326 
    327         // Log the first file
    328         // This gets passed verbatim to createIssForFile above
    329         EasyMock.expect(mDevice.pullFile(EasyMock.eq(filename1)))
    330                 .andReturn(new FakeFile(filename1, tombstone.length()));
    331         mDfrIss = new ByteArrayInputStreamSource(tombstone.getBytes());
    332         // FIXME: use captures here to make sure we get the string back out
    333         mListener.testLog(EasyMock.eq(filename1), EasyMock.eq(LogDataType.UNKNOWN),
    334                 EasyMock.eq(mDfrIss));
    335 
    336         // Log the second file
    337         // This gets passed verbatim to createIssForFile above
    338         EasyMock.expect(mDevice.pullFile(EasyMock.eq(filename2)))
    339                 .andReturn(new FakeFile(filename2, tombstone.length()));
    340         // FIXME: use captures here to make sure we get the string back out
    341         mListener.testLog(EasyMock.eq(filename2), EasyMock.eq(LogDataType.UNKNOWN),
    342                 EasyMock.eq(mDfrIss));
    343 
    344         replayMocks();
    345         dfr.run();
    346         verifyMocks();
    347     }
    348 
    349     /**
    350      * Make sure that data type inference works as expected
    351      */
    352     public void testInferDataTypes() throws Exception {
    353         final String result = "/data/files/file.png\r\n/data/files/file.xml\r\n" +
    354                 "/data/files/file.zip\r\n";
    355         final String[] filenames = {"/data/files/file.png", "/data/files/file.xml",
    356                 "/data/files/file.zip"};
    357         final LogDataType[] expTypes = {LogDataType.PNG, LogDataType.XML, LogDataType.ZIP};
    358         dfr.addPatterns("/data/files/*");
    359 
    360         final String contents = "these are file contents";
    361         mDfrIss = new ByteArrayInputStreamSource(contents.getBytes());
    362 
    363         EasyMock.expect(mDevice.executeShellCommand((String)EasyMock.anyObject()))
    364                 .andReturn(result);
    365         // This gets passed verbatim to createIssForFile above
    366         for (int i = 0; i < filenames.length; ++i) {
    367             final String filename = filenames[i];
    368             final LogDataType expType = expTypes[i];
    369             EasyMock.expect(mDevice.pullFile(EasyMock.eq(filename)))
    370                     .andReturn(new FakeFile(filename, contents.length()));
    371 
    372             // FIXME: use captures here to make sure we get the string back out
    373             mListener.testLog(EasyMock.eq(filename), EasyMock.eq(expType),
    374                     EasyMock.eq(mDfrIss));
    375         }
    376 
    377         replayMocks();
    378         dfr.run();
    379         verifyMocks();
    380     }
    381 
    382 
    383     private void replayMocks() {
    384         EasyMock.replay(mDevice, mListener);
    385     }
    386 
    387     private void verifyMocks() {
    388         EasyMock.verify(mDevice, mListener);
    389     }
    390 }
    391