1 /* 2 * Copyright (C) 2016 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.util; 17 18 import com.android.tradefed.log.ITestLogger; 19 import com.android.tradefed.log.LogUtil.CLog; 20 import com.android.tradefed.result.FileInputStreamSource; 21 import com.android.tradefed.result.InputStreamSource; 22 import com.android.tradefed.result.LogDataType; 23 24 import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; 25 import org.apache.commons.compress.archivers.zip.ZipFile; 26 27 import java.io.Closeable; 28 import java.io.File; 29 import java.io.IOException; 30 import java.util.ArrayList; 31 import java.util.Collections; 32 import java.util.List; 33 34 /** 35 * Object holding the bugreport files references, compatible of flat bugreport and zipped bugreport 36 * (bugreportz). 37 */ 38 public class Bugreport implements Closeable { 39 private File mBugreport; 40 private boolean mIsZipped; 41 Bugreport(File bugreportFile, boolean isZipped)42 public Bugreport(File bugreportFile, boolean isZipped) { 43 mBugreport = bugreportFile; 44 mIsZipped = isZipped; 45 } 46 47 /** 48 * Return true if it's a zipped bugreport, false otherwise. 49 */ isZipped()50 public boolean isZipped() { 51 return mIsZipped; 52 } 53 54 /** 55 * Helper to log the Bugreport whether its zipped or not. 56 * 57 * @param dataName the name of the data once logged. 58 * @param logger a {@link ITestLogger} to receive the log. 59 */ log(String dataName, ITestLogger logger)60 public void log(String dataName, ITestLogger logger) { 61 LogDataType type = isZipped() ? LogDataType.BUGREPORTZ : LogDataType.BUGREPORT; 62 try (InputStreamSource source = new FileInputStreamSource(mBugreport)) { 63 logger.testLog(dataName, type, source); 64 } 65 } 66 67 /** 68 * Return a {@link File} pointing to the bugreport main file. For a flat bugreport, it returns 69 * the flat bugreport itself. For a zipped bugreport, it returns the main entry file. 70 * The returned file is a copy and should be appropriately managed by the user. 71 */ getMainFile()72 public File getMainFile() { 73 if (mBugreport == null) { 74 return null; 75 } 76 if (!mIsZipped) { 77 return mBugreport; 78 } else { 79 File mainEntry = null; 80 try { 81 try (ZipFile zip = new ZipFile(mBugreport)) { 82 // We get the main_entry.txt that contains the bugreport name. 83 mainEntry = ZipUtil2.extractFileFromZip(zip, "main_entry.txt"); 84 if (mainEntry == null) { 85 CLog.w("main_entry.txt was not found inside the bugreport"); 86 return null; 87 } 88 String bugreportName = FileUtil.readStringFromFile(mainEntry).trim(); 89 CLog.d("bugreport name: '%s'", bugreportName); 90 return ZipUtil2.extractFileFromZip(zip, bugreportName); 91 } 92 } catch (IOException e) { 93 CLog.e("Error while unzipping bugreportz"); 94 CLog.e(e); 95 } finally { 96 FileUtil.deleteFile(mainEntry); 97 } 98 } 99 return null; 100 } 101 102 /** 103 * Returns the list of files contained inside the zipped bugreport. Null if it's not a zipped 104 * bugreport. 105 */ getListOfFiles()106 public List<String> getListOfFiles() { 107 if (mBugreport == null) { 108 return null; 109 } 110 List<String> list = new ArrayList<>(); 111 if (!mIsZipped) { 112 return null; 113 } 114 try (ZipFile zipBugreport = new ZipFile(mBugreport)) { 115 for (ZipArchiveEntry entry : Collections.list(zipBugreport.getEntries())) { 116 list.add(entry.getName()); 117 } 118 } catch (IOException e) { 119 CLog.e("Error reading the list of files in the bugreport"); 120 CLog.e(e); 121 } 122 return list; 123 } 124 125 /** 126 * Return the {@link File} associated with the name in the bugreport. Null if not found or if 127 * name is null. Non zipped bugreport always return null. 128 * The returned file is a copy and should be appropriately managed by the user. 129 */ getFileByName(String name)130 public File getFileByName(String name) { 131 if (mBugreport == null || name == null) { 132 return null; 133 } 134 if (mIsZipped) { 135 return extractFileBugreport(name); 136 } 137 return null; 138 } 139 140 /** 141 * Helper to extract and return a file from the zipped bugreport. 142 */ extractFileBugreport(String name)143 private File extractFileBugreport(String name) { 144 File bugreport = null; 145 try (ZipFile zip = new ZipFile(mBugreport)) { 146 bugreport = ZipUtil2.extractFileFromZip(zip, name); 147 return bugreport; 148 } catch (IOException e) { 149 CLog.e("Error while unzipping bugreportz"); 150 CLog.e(e); 151 } 152 return null; 153 } 154 155 /** 156 * Clean up the files held by the bugreport object. Must be called when the object is not used 157 * anymore. 158 */ 159 @Override close()160 public void close() throws IOException { 161 FileUtil.deleteFile(mBugreport); 162 } 163 } 164