1 /* 2 * Copyright (C) 2019 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.device.cloud; 17 18 import com.android.tradefed.device.TestDeviceOptions; 19 import com.android.tradefed.device.TestDeviceOptions.InstanceType; 20 import com.android.tradefed.log.ITestLogger; 21 import com.android.tradefed.log.LogUtil.CLog; 22 import com.android.tradefed.result.LogDataType; 23 import com.android.tradefed.util.IRunUtil; 24 import com.android.tradefed.util.MultiMap; 25 26 import java.util.List; 27 28 /** 29 * This utility allows to avoid code duplication across the different remote device representation 30 * for the remote log fetching logic of common files. 31 */ 32 public class CommonLogRemoteFileUtil { 33 34 /** The directory where to find debug logs for a nested remote instance. */ 35 public static final String NESTED_REMOTE_LOG_DIR = "/home/%s/cuttlefish_runtime/"; 36 /** The directory where to find debug logs for an emulator instance. */ 37 public static final String EMULATOR_REMOTE_LOG_DIR = "/home/%s/log/"; 38 39 public static final MultiMap<InstanceType, KnownLogFileEntry> KNOWN_FILES_TO_FETCH = 40 new MultiMap<>(); 41 42 static { 43 // Cuttlefish known files to collect KNOWN_FILES_TO_FETCH.put( InstanceType.CUTTLEFISH, new KnownLogFileEntry( NESTED_REMOTE_LOG_DIR + "kernel.log", null, LogDataType.TEXT))44 KNOWN_FILES_TO_FETCH.put( 45 InstanceType.CUTTLEFISH, 46 new KnownLogFileEntry( 47 NESTED_REMOTE_LOG_DIR + "kernel.log", null, LogDataType.TEXT)); KNOWN_FILES_TO_FETCH.put( InstanceType.CUTTLEFISH, new KnownLogFileEntry( NESTED_REMOTE_LOG_DIR + "logcat", "full_gce_logcat", LogDataType.LOGCAT))48 KNOWN_FILES_TO_FETCH.put( 49 InstanceType.CUTTLEFISH, 50 new KnownLogFileEntry( 51 NESTED_REMOTE_LOG_DIR + "logcat", "full_gce_logcat", LogDataType.LOGCAT)); KNOWN_FILES_TO_FETCH.put( InstanceType.CUTTLEFISH, new KnownLogFileEntry( NESTED_REMOTE_LOG_DIR + "cuttlefish_config.json", null, LogDataType.TEXT))52 KNOWN_FILES_TO_FETCH.put( 53 InstanceType.CUTTLEFISH, 54 new KnownLogFileEntry( 55 NESTED_REMOTE_LOG_DIR + "cuttlefish_config.json", null, LogDataType.TEXT)); 56 // Emulator known files to collect KNOWN_FILES_TO_FETCH.put( InstanceType.EMULATOR, new KnownLogFileEntry( EMULATOR_REMOTE_LOG_DIR + "logcat.log", "full_gce_emulator_logcat", LogDataType.LOGCAT))57 KNOWN_FILES_TO_FETCH.put( 58 InstanceType.EMULATOR, 59 new KnownLogFileEntry( 60 EMULATOR_REMOTE_LOG_DIR + "logcat.log", 61 "full_gce_emulator_logcat", 62 LogDataType.LOGCAT)); KNOWN_FILES_TO_FETCH.put( InstanceType.EMULATOR, new KnownLogFileEntry(EMULATOR_REMOTE_LOG_DIR + "adb.log", null, LogDataType.TEXT))63 KNOWN_FILES_TO_FETCH.put( 64 InstanceType.EMULATOR, 65 new KnownLogFileEntry(EMULATOR_REMOTE_LOG_DIR + "adb.log", null, LogDataType.TEXT)); KNOWN_FILES_TO_FETCH.put( InstanceType.EMULATOR, new KnownLogFileEntry( EMULATOR_REMOTE_LOG_DIR + "kernel.log", null, LogDataType.TEXT))66 KNOWN_FILES_TO_FETCH.put( 67 InstanceType.EMULATOR, 68 new KnownLogFileEntry( 69 EMULATOR_REMOTE_LOG_DIR + "kernel.log", null, LogDataType.TEXT)); KNOWN_FILES_TO_FETCH.put( InstanceType.EMULATOR, new KnownLogFileEntry("/var/log/daemon.log", null, LogDataType.TEXT))70 KNOWN_FILES_TO_FETCH.put( 71 InstanceType.EMULATOR, 72 new KnownLogFileEntry("/var/log/daemon.log", null, LogDataType.TEXT)); 73 } 74 75 /** A representation of a known log entry for remote devices. */ 76 public static class KnownLogFileEntry { 77 public String path; 78 public String logName; 79 public LogDataType type; 80 KnownLogFileEntry(String path, String logName, LogDataType type)81 KnownLogFileEntry(String path, String logName, LogDataType type) { 82 this.path = path; 83 this.logName = logName; 84 this.type = type; 85 } 86 } 87 88 /** 89 * Fetch and log the commonly known files from remote instances. 90 * 91 * @param testLogger The {@link ITestLogger} where to log the files. 92 * @param gceAvd The descriptor of the remote instance. 93 * @param options The {@link TestDeviceOptions} describing the device options 94 * @param runUtil A {@link IRunUtil} to execute commands. 95 */ fetchCommonFiles( ITestLogger testLogger, GceAvdInfo gceAvd, TestDeviceOptions options, IRunUtil runUtil)96 public static void fetchCommonFiles( 97 ITestLogger testLogger, 98 GceAvdInfo gceAvd, 99 TestDeviceOptions options, 100 IRunUtil runUtil) { 101 if (gceAvd == null) { 102 CLog.e("GceAvdInfo was null, cannot collect remote files."); 103 return; 104 } 105 // Capture known extra files 106 List<KnownLogFileEntry> toFetch = KNOWN_FILES_TO_FETCH.get(options.getInstanceType()); 107 if (toFetch != null) { 108 for (KnownLogFileEntry entry : toFetch) { 109 LogRemoteFile( 110 testLogger, 111 gceAvd, 112 options, 113 runUtil, 114 // Default fetch rely on main user 115 String.format(entry.path, options.getInstanceUser()), 116 entry.type, 117 entry.logName); 118 } 119 } 120 121 if (options.getRemoteFetchFilePattern().isEmpty()) { 122 return; 123 } 124 for (String file : options.getRemoteFetchFilePattern()) { 125 // TODO: Improve type of files. 126 LogRemoteFile(testLogger, gceAvd, options, runUtil, file, LogDataType.TEXT, null); 127 } 128 } 129 130 /** 131 * Captures a log from the remote destination. 132 * 133 * @param testLogger The {@link ITestLogger} where to log the files. 134 * @param gceAvd The descriptor of the remote instance. 135 * @param options The {@link TestDeviceOptions} describing the device options 136 * @param runUtil A {@link IRunUtil} to execute commands. 137 * @param fileToRetrieve The remote path to the file to pull. 138 * @param logType The expected type of the pulled log. 139 * @param baseName The base name that will be used to log the file, if null the actually file 140 * name will be used. 141 */ LogRemoteFile( ITestLogger testLogger, GceAvdInfo gceAvd, TestDeviceOptions options, IRunUtil runUtil, String fileToRetrieve, LogDataType logType, String baseName)142 private static void LogRemoteFile( 143 ITestLogger testLogger, 144 GceAvdInfo gceAvd, 145 TestDeviceOptions options, 146 IRunUtil runUtil, 147 String fileToRetrieve, 148 LogDataType logType, 149 String baseName) { 150 GceManager.logNestedRemoteFile( 151 testLogger, gceAvd, options, runUtil, fileToRetrieve, logType, baseName); 152 } 153 } 154