blob: 6834bd88f38387f902687540c145d1c2535e88a0 [file] [log] [blame]
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.csuite.config;
import static com.google.common.truth.Truth.assertThat;
import static org.testng.Assert.assertThrows;
import com.android.tradefed.build.BuildInfo;
import com.android.tradefed.config.OptionSetter;
import com.android.tradefed.device.ITestDevice;
import com.android.tradefed.invoker.IInvocationContext;
import com.android.tradefed.invoker.InvocationContext;
import com.android.tradefed.invoker.TestInformation;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ListMultimap;
import com.google.common.jimfs.Configuration;
import com.google.common.jimfs.Jimfs;
import com.google.common.truth.IterableSubject;
import com.google.common.truth.StringSubject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.Mockito;
import java.io.IOException;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@RunWith(JUnit4.class)
public final class ModuleGeneratorTest {
private static final String TEST_PACKAGE_NAME1 = "test.package.name1";
private static final String TEST_PACKAGE_NAME2 = "test.package.name2";
private static final String PACKAGE_PLACEHOLDER = "{package}";
private static final Exception NO_EXCEPTION = null;
private final FileSystem mFileSystem = Jimfs.newFileSystem(Configuration.unix());
@Test
public void tearDown_packageOptionIsSet_deletesGeneratedModules() throws Exception {
Path testsDir = createTestsDir();
ModuleGenerator generator1 =
createGeneratorBuilder()
.setTestsDir(testsDir)
.addPackage(TEST_PACKAGE_NAME1)
.addPackage(TEST_PACKAGE_NAME1) // Simulate duplicate package option
.addPackage(TEST_PACKAGE_NAME2)
.build();
generator1.split();
ModuleGenerator generator2 =
createGeneratorBuilder()
.setTestsDir(testsDir)
.addPackage(TEST_PACKAGE_NAME1)
.addPackage(TEST_PACKAGE_NAME1) // Simulate duplicate package option
.addPackage(TEST_PACKAGE_NAME2)
.build();
generator2.tearDown(createTestInfo(), NO_EXCEPTION);
assertThatListDirectory(testsDir).isEmpty();
}
@Test
public void tearDown_packageOptionIsNotSet_doesNotThrowError() throws Exception {
ModuleGenerator generator = createGeneratorBuilder().setTestsDir(createTestsDir()).build();
generator.split();
generator.tearDown(createTestInfo(), NO_EXCEPTION);
}
@Test
public void split_packageNameIsEmptyString_throwsError() throws Exception {
ModuleGenerator generator = createGeneratorBuilder().addPackage("").build();
assertThrows(IllegalArgumentException.class, () -> generator.split());
}
@Test
public void split_packageNameContainsPlaceholder_throwsError() throws Exception {
ModuleGenerator generator =
createGeneratorBuilder().addPackage("a" + PACKAGE_PLACEHOLDER + "b").build();
assertThrows(IllegalArgumentException.class, () -> generator.split());
}
@Test
public void split_packageOptionContainsDuplicates_ignoreDuplicates() throws Exception {
Path testsDir = createTestsDir();
ModuleGenerator generator =
createGeneratorBuilder()
.setTestsDir(testsDir)
.addPackage(TEST_PACKAGE_NAME1)
.addPackage(TEST_PACKAGE_NAME1) // Simulate duplicate package option
.addPackage(TEST_PACKAGE_NAME2)
.build();
generator.split();
assertThatListDirectory(testsDir)
.containsExactly(
getModuleConfigFile(testsDir, TEST_PACKAGE_NAME1),
getModuleConfigFile(testsDir, TEST_PACKAGE_NAME2));
}
@Test
public void split_packageOptionNotSet_doesNotGenerate() throws Exception {
Path testsDir = createTestsDir();
ModuleGenerator generator = createGeneratorBuilder().setTestsDir(testsDir).build();
generator.split();
assertThatListDirectory(testsDir).isEmpty();
}
@Test
public void split_templateContainsPlaceholders_replacesPlaceholdersInOutput() throws Exception {
Path testsDir = createTestsDir();
String content = "hello placeholder%s%s world";
ModuleGenerator generator =
createGeneratorBuilder()
.setTestsDir(testsDir)
.addPackage(TEST_PACKAGE_NAME1)
.addPackage(TEST_PACKAGE_NAME2)
.setTemplateContent(
String.format(content, PACKAGE_PLACEHOLDER, PACKAGE_PLACEHOLDER))
.build();
generator.split();
assertThatModuleConfigFileContent(testsDir, TEST_PACKAGE_NAME1)
.isEqualTo(String.format(content, TEST_PACKAGE_NAME1, TEST_PACKAGE_NAME1));
assertThatModuleConfigFileContent(testsDir, TEST_PACKAGE_NAME2)
.isEqualTo(String.format(content, TEST_PACKAGE_NAME2, TEST_PACKAGE_NAME2));
}
@Test
public void split_templateDoesNotContainPlaceholder_outputsTemplateContent() throws Exception {
Path testsDir = createTestsDir();
String content = "no placeholder";
ModuleGenerator generator =
createGeneratorBuilder()
.setTestsDir(testsDir)
.addPackage(TEST_PACKAGE_NAME1)
.addPackage(TEST_PACKAGE_NAME2)
.setTemplateContent(content)
.build();
generator.split();
assertThatModuleConfigFileContent(testsDir, TEST_PACKAGE_NAME1).isEqualTo(content);
assertThatModuleConfigFileContent(testsDir, TEST_PACKAGE_NAME2).isEqualTo(content);
}
@Test
public void split_templateContentIsEmpty_outputsTemplateContent() throws Exception {
Path testsDir = createTestsDir();
String content = "";
ModuleGenerator generator =
createGeneratorBuilder()
.setTestsDir(testsDir)
.addPackage(TEST_PACKAGE_NAME1)
.addPackage(TEST_PACKAGE_NAME2)
.setTemplateContent(content)
.build();
generator.split();
assertThatModuleConfigFileContent(testsDir, TEST_PACKAGE_NAME1).isEqualTo(content);
assertThatModuleConfigFileContent(testsDir, TEST_PACKAGE_NAME2).isEqualTo(content);
}
private static StringSubject assertThatModuleConfigFileContent(
Path testsDir, String packageName) throws IOException {
return assertThat(
new String(Files.readAllBytes(getModuleConfigFile(testsDir, packageName))));
}
private static IterableSubject assertThatListDirectory(Path dir) throws IOException {
// Convert stream to list because com.google.common.truth.Truth8 is not available.
return assertThat(
Files.walk(dir)
.filter(p -> !p.equals(dir))
.collect(ImmutableList.toImmutableList()));
}
private static Path getModuleConfigFile(Path baseDir, String packageName) {
return baseDir.resolve(packageName + ".config");
}
private Path createTestsDir() throws IOException {
Path rootPath = mFileSystem.getPath("csuite");
Files.createDirectories(rootPath);
return Files.createTempDirectory(rootPath, "testDir");
}
private static TestInformation createTestInfo() {
IInvocationContext context = new InvocationContext();
context.addAllocatedDevice("device1", Mockito.mock(ITestDevice.class));
context.addDeviceBuildInfo("device1", new BuildInfo());
return TestInformation.newBuilder().setInvocationContext(context).build();
}
private GeneratorBuilder createGeneratorBuilder() throws IOException {
return new GeneratorBuilder()
.setFileSystem(mFileSystem)
.setTemplateContent(MODULE_TEMPLATE_CONTENT)
.setOption(ModuleGenerator.OPTION_TEMPLATE, "empty_path");
}
private static final class GeneratorBuilder {
private final ListMultimap<String, String> mOptions = ArrayListMultimap.create();
private final List<String> mPackages = new ArrayList<>();
private Path mTestsDir;
private String mTemplateContent;
private FileSystem mFileSystem;
GeneratorBuilder addPackage(String packageName) {
mPackages.add(packageName);
return this;
}
GeneratorBuilder setFileSystem(FileSystem fileSystem) {
mFileSystem = fileSystem;
return this;
}
GeneratorBuilder setTemplateContent(String templateContent) {
mTemplateContent = templateContent;
return this;
}
GeneratorBuilder setTestsDir(Path testsDir) {
mTestsDir = testsDir;
return this;
}
GeneratorBuilder setOption(String key, String value) {
mOptions.put(key, value);
return this;
}
ModuleGenerator build() throws Exception {
ModuleGenerator generator =
new ModuleGenerator(
mFileSystem, buildInfo -> mTestsDir, resourcePath -> mTemplateContent);
OptionSetter optionSetter = new OptionSetter(generator);
for (Map.Entry<String, String> entry : mOptions.entries()) {
optionSetter.setOptionValue(entry.getKey(), entry.getValue());
}
for (String packageName : mPackages) {
optionSetter.setOptionValue(ModuleGenerator.OPTION_PACKAGE, packageName);
}
return generator;
}
}
private static final String MODULE_TEMPLATE_CONTENT =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<configuration description=\"description\">\n"
+ " <option name=\"package-name\" value=\"{package}\"/>\n"
+ " <target_generator class=\"some.generator.class\">\n"
+ " <option name=\"test-file-name\" value=\"app://{package}\"/>\n"
+ " </target_generator>\n"
+ " <test class=\"some.test.class\"/>\n"
+ "</configuration>";
}