1 /* 2 * Copyright (C) 2018 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 static org.junit.Assert.assertEquals; 19 import static org.junit.Assert.assertNotEquals; 20 import static org.junit.Assert.assertTrue; 21 22 import com.android.tradefed.build.IFolderBuildInfo; 23 import com.android.tradefed.log.LogUtil.CLog; 24 25 import org.easymock.EasyMock; 26 import org.junit.Before; 27 import org.junit.Test; 28 import org.junit.runner.RunWith; 29 import org.junit.runners.JUnit4; 30 31 import java.io.File; 32 import java.io.IOException; 33 34 /** 35 * Unit tests for {@link VtsPythonRunnerHelper}. 36 */ 37 @RunWith(JUnit4.class) 38 public class VtsPythonRunnerHelperTest { 39 private static final String[] mPythonCmd = {"python"}; 40 private static final long mTestTimeout = 1000 * 5; 41 42 private ProcessHelper mProcessHelper = null; 43 private VtsPythonRunnerHelper mVtsPythonRunnerHelper = null; 44 private String mVirtualenvPath = "virtualenv_path_" + System.currentTimeMillis(); 45 46 @Before setUp()47 public void setUp() throws Exception { 48 IFolderBuildInfo buildInfo = EasyMock.createNiceMock(IFolderBuildInfo.class); 49 EasyMock.replay(buildInfo); 50 mVtsPythonRunnerHelper = new VtsPythonRunnerHelper(new File(mVirtualenvPath), null) { 51 @Override 52 protected ProcessHelper createProcessHelper(String[] cmd) { 53 return mProcessHelper; 54 } 55 }; 56 } 57 58 /** 59 * Create a process helper which mocks status of a running process. 60 */ createMockProcessHelper( CommandStatus status, boolean interrupted, boolean keepRunning)61 private static ProcessHelper createMockProcessHelper( 62 CommandStatus status, boolean interrupted, boolean keepRunning) { 63 Process process; 64 try { 65 process = new ProcessBuilder("true").start(); 66 } catch (IOException e) { 67 throw new RuntimeException(e); 68 } 69 return new ProcessHelper(process) { 70 @Override 71 public CommandStatus waitForProcess(long timeoutMsecs) throws RunInterruptedException { 72 if (interrupted) { 73 throw new RunInterruptedException(); 74 } 75 return status; 76 } 77 78 @Override 79 public boolean isRunning() { 80 return keepRunning; 81 } 82 }; 83 } 84 85 private static ProcessHelper createMockProcessHelper( 86 CommandStatus status, boolean interrupted) { 87 return createMockProcessHelper(status, interrupted, /*keepRunning=*/false); 88 } 89 90 private static ProcessHelper createMockProcessHelper(CommandStatus status) { 91 return createMockProcessHelper(status, /*interrupted=*/false, /*keepRunning=*/false); 92 } 93 94 /** 95 * Create a mock runUtil with returns the expected results. 96 */ 97 private IRunUtil createMockRunUtil() { 98 IRunUtil runUtil = new RunUtil() { 99 private String path = null; 100 101 @Override 102 public void setEnvVariable(String key, String value) { 103 super.setEnvVariable(key, value); 104 if (key.equals("PATH")) { 105 path = value; 106 } 107 } 108 109 @Override 110 public CommandResult runTimedCmd(final long timeout, final String... command) { 111 CommandResult cmdRes = new CommandResult(CommandStatus.SUCCESS); 112 String out = ""; 113 if (command.length == 2 && command[0].equals("which") 114 && command[1].equals("python")) { 115 if (path != null) { 116 out = path.split(":")[0] + "/python"; 117 } else { 118 out = "/usr/bin/python"; 119 } 120 } 121 cmdRes.setStdout(out); 122 return cmdRes; 123 } 124 }; 125 return runUtil; 126 } 127 128 @Test 129 public void testProcessRunSuccess() { 130 CommandResult commandResult = new CommandResult(); 131 mProcessHelper = createMockProcessHelper(CommandStatus.SUCCESS); 132 String interruptMessage = 133 mVtsPythonRunnerHelper.runPythonRunner(mPythonCmd, commandResult, mTestTimeout); 134 assertEquals(interruptMessage, null); 135 assertEquals(commandResult.getStatus(), CommandStatus.SUCCESS); 136 } 137 138 @Test 139 public void testProcessRunFailed() { 140 CommandResult commandResult = new CommandResult(); 141 mProcessHelper = createMockProcessHelper(CommandStatus.FAILED); 142 String interruptMessage = 143 mVtsPythonRunnerHelper.runPythonRunner(mPythonCmd, commandResult, mTestTimeout); 144 assertEquals(interruptMessage, null); 145 assertEquals(commandResult.getStatus(), CommandStatus.FAILED); 146 } 147 148 @Test 149 public void testProcessRunTimeout() { 150 CommandResult commandResult = new CommandResult(); 151 mProcessHelper = createMockProcessHelper(CommandStatus.TIMED_OUT); 152 String interruptMessage = 153 mVtsPythonRunnerHelper.runPythonRunner(mPythonCmd, commandResult, mTestTimeout); 154 assertEquals(interruptMessage, null); 155 assertEquals(commandResult.getStatus(), CommandStatus.TIMED_OUT); 156 } 157 158 @Test 159 public void testProcessRunInterrupted() { 160 CommandResult commandResult = new CommandResult(); 161 mProcessHelper = createMockProcessHelper(null, /*interrupted=*/true); 162 String interruptMessage = 163 mVtsPythonRunnerHelper.runPythonRunner(mPythonCmd, commandResult, mTestTimeout); 164 assertNotEquals(interruptMessage, null); 165 assertEquals(commandResult.getStatus(), CommandStatus.TIMED_OUT); 166 } 167 168 @Test 169 public void testActivateVirtualEnvNotExist() { 170 IRunUtil runUtil = createMockRunUtil(); 171 assertEquals(null, VtsPythonRunnerHelper.getPythonBinDir(mVirtualenvPath)); 172 VtsPythonRunnerHelper.activateVirtualenv(runUtil, mVirtualenvPath); 173 String pythonBinary = runUtil.runTimedCmd(1000, "which", "python").getStdout(); 174 assertEquals(pythonBinary, "/usr/bin/python"); 175 } 176 177 @Test 178 public void testActivateVirtualEnvExist() { 179 IRunUtil runUtil = createMockRunUtil(); 180 String binDirName = EnvUtil.isOnWindows() ? "Scripts" : "bin"; 181 File envDir = new File(mVirtualenvPath); 182 File binDir = new File(mVirtualenvPath, binDirName); 183 try { 184 CLog.d("%s", envDir.mkdir()); 185 CLog.d("%s", binDir.mkdir()); 186 assertTrue(binDir.exists()); 187 assertEquals(binDir.getAbsolutePath(), 188 VtsPythonRunnerHelper.getPythonBinDir(mVirtualenvPath)); 189 VtsPythonRunnerHelper.activateVirtualenv(runUtil, mVirtualenvPath); 190 String pythonBinary = runUtil.runTimedCmd(1000, "which", "python").getStdout(); 191 assertEquals(pythonBinary, new File(binDir, "python").getAbsolutePath()); 192 } finally { 193 FileUtil.recursiveDelete(envDir); 194 FileUtil.recursiveDelete(binDir); 195 } 196 } 197 198 } 199