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.targetprep; 17 18 import com.android.tradefed.config.OptionClass; 19 import com.android.tradefed.device.DeviceNotAvailableException; 20 import com.android.tradefed.invoker.TestInformation; 21 import com.android.tradefed.log.LogUtil.CLog; 22 23 import java.util.concurrent.Semaphore; 24 25 /** 26 * This is a preparer used to use token to serialize test excution in tradefed host. only the device 27 * acquire token will be allow to start the test. Others will wait until it released This can't be 28 * only used when you have one test in tradefed and use shared resources. Please make sure only a 29 * single test running on the host with different DUTs User need to add --semaphore-token:no-disable 30 * in the command file. 31 */ 32 @OptionClass(alias = "semaphore-token") 33 public class SemaphoreTokenTargetPreparer extends BaseTargetPreparer { 34 private boolean mTokenAcquired = true; 35 static final Semaphore mRunToken = new Semaphore(1); 36 private boolean mInvokedTeardown = true; 37 SemaphoreTokenTargetPreparer()38 public SemaphoreTokenTargetPreparer() { 39 // This preparer is disabled by default. 40 setDisable(true); 41 } 42 43 /** {@inheritDoc} */ 44 @Override setUp(TestInformation testInfo)45 public void setUp(TestInformation testInfo) 46 throws TargetSetupError, BuildError, DeviceNotAvailableException { 47 // Avoid re-entry if teardown wasn't called. This can happen during 48 // device reset since target preparers rerun 49 if (mInvokedTeardown) { 50 try { 51 CLog.v("Waiting to acquire run token"); 52 mRunToken.acquire(); 53 mTokenAcquired = true; 54 CLog.v("Token acquired"); 55 } catch (InterruptedException e) { 56 mTokenAcquired = false; 57 CLog.e(e); 58 CLog.e("Interrupted error during token acquire"); 59 } 60 } 61 mInvokedTeardown = false; 62 } 63 64 /** {@inheritDoc} */ 65 @Override tearDown(TestInformation testInfo, Throwable e)66 public void tearDown(TestInformation testInfo, Throwable e) throws DeviceNotAvailableException { 67 mInvokedTeardown = true; 68 if (mTokenAcquired) { 69 CLog.v("Releasing run token"); 70 mRunToken.drainPermits(); 71 mRunToken.release(); 72 } else { 73 CLog.v("Did not acquire token, skip releasing run token"); 74 } 75 } 76 } 77