• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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.cuttlefish.test;
17 
18 import static com.google.common.base.Preconditions.checkNotNull;
19 import static com.google.common.base.Preconditions.checkState;
20 
21 import com.android.tradefed.build.IBuildInfo;
22 import com.android.tradefed.config.Option;
23 import com.android.tradefed.invoker.TestInformation;
24 import com.android.tradefed.testtype.HostTest;
25 import com.android.tradefed.testtype.IBuildReceiver;
26 import com.android.tradefed.testtype.ISetOptionReceiver;
27 import com.android.tradefed.testtype.ITestInformationReceiver;
28 import com.google.auto.value.AutoAnnotation;
29 import com.google.common.collect.ImmutableMap;
30 import com.google.inject.AbstractModule;
31 import com.google.inject.Binder;
32 import com.google.inject.Guice;
33 import com.google.inject.Injector;
34 import java.io.File;
35 import java.io.FileNotFoundException;
36 import java.util.ArrayList;
37 import java.util.HashMap;
38 import java.util.HashSet;
39 import java.util.List;
40 import java.util.Map;
41 import java.util.regex.Pattern;
42 import org.junit.runners.BlockJUnit4ClassRunner;
43 import org.junit.runners.model.InitializationError;
44 import org.junit.runners.model.TestClass;
45 
46 public final class CuttlefishIntegrationTestRunner extends BlockJUnit4ClassRunner
47     implements ITestInformationReceiver, ISetOptionReceiver, IBuildReceiver {
48   @Option(name = HostTest.SET_OPTION_NAME, description = HostTest.SET_OPTION_DESC)
49   private HashSet<String> keyValueOptions = new HashSet<>();
50 
51   private IBuildInfo buildInfo;
52   private TestInformation testInfo;
53   private final TestClass testClass;
54 
55   // Required by JUnit
CuttlefishIntegrationTestRunner(Class<?> testClass)56   public CuttlefishIntegrationTestRunner(Class<?> testClass) throws InitializationError {
57     this(new TestClass(testClass));
58   }
59 
CuttlefishIntegrationTestRunner(TestClass testClass)60   private CuttlefishIntegrationTestRunner(TestClass testClass) throws InitializationError {
61     super(testClass);
62     this.testClass = testClass;
63   }
64 
65   @Override
setBuild(IBuildInfo buildInfo)66   public void setBuild(IBuildInfo buildInfo) {
67     this.buildInfo = checkNotNull(buildInfo);
68   }
69 
70   @Override
setTestInformation(TestInformation testInfo)71   public void setTestInformation(TestInformation testInfo) {
72     this.testInfo = checkNotNull(testInfo);
73   }
74 
75   @Override
getTestInformation()76   public TestInformation getTestInformation() {
77     return checkNotNull(testInfo);
78   }
79 
processOptions()80   private ImmutableMap<String, String> processOptions() {
81     // Regex from HostTest.setOptionToLoadedObject
82     String delim = ":";
83     String esc = "\\";
84     String regex = "(?<!" + Pattern.quote(esc) + ")" + Pattern.quote(delim);
85     ImmutableMap.Builder<String, String> optMap = ImmutableMap.builder();
86     for (String item : keyValueOptions) {
87       String[] fields = item.split(regex);
88       checkState(fields.length == 2, "Could not parse \"%s\"", item);
89       String value = fields[1].replaceAll(Pattern.quote(esc) + Pattern.quote(delim), delim);
90       optMap.put(fields[0], value);
91     }
92     return optMap.build();
93   }
94 
95   @AutoAnnotation
setOptionAnnotation(String value)96   private static SetOption setOptionAnnotation(String value) {
97     return new AutoAnnotation_CuttlefishIntegrationTestRunner_setOptionAnnotation(value);
98   }
99 
bindOptions(Binder binder)100   private void bindOptions(Binder binder) {
101     // TODO(schuffelen): Handle collections and maps
102     for (Map.Entry<String, String> option : processOptions().entrySet()) {
103       SetOption annotation = setOptionAnnotation(option.getKey());
104       binder.bind(String.class).annotatedWith(annotation).toInstance(option.getValue());
105     }
106   }
107 
108   private final class TradefedClassesModule extends AbstractModule {
109     @Override
configure()110     protected void configure() {
111       bind(TestInformation.class).toInstance(testInfo);
112       bind(IBuildInfo.class).toInstance(buildInfo);
113       bindOptions(binder());
114     }
115   }
116 
117   @Override
createTest()118   protected Object createTest() {
119     Injector injector = Guice.createInjector(new TradefedClassesModule());
120     return injector.getInstance(testClass.getJavaClass());
121   }
122 }
123