BaseCompilationTest.java revision 3e3bf43a2e11fb433b43558e2e05255edfa5b6a8
1/* 2 * Copyright (C) 2015 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 17package android.databinding.compilationTest; 18 19import org.apache.commons.io.FileUtils; 20import org.apache.commons.io.IOUtils; 21import org.junit.Before; 22 23import java.io.File; 24import java.io.FileOutputStream; 25import java.io.IOException; 26import java.io.InputStream; 27import java.net.URISyntaxException; 28import java.net.URL; 29import java.nio.file.Files; 30import java.nio.file.Paths; 31import java.nio.file.attribute.PosixFilePermission; 32import java.util.HashMap; 33import java.util.HashSet; 34import java.util.Map; 35import java.util.Set; 36import java.util.regex.Matcher; 37import java.util.regex.Pattern; 38 39import static org.junit.Assert.assertEquals; 40import static org.junit.Assert.assertNotNull; 41import static org.junit.Assert.assertTrue; 42 43 44public class BaseCompilationTest { 45 static Pattern VARIABLES = Pattern.compile("!@\\{([A-Za-z0-9_-]*)}"); 46 47 public static final String KEY_MANIFEST_PACKAGE = "PACKAGE"; 48 public static final String KEY_DEPENDENCIES = "DEPENDENCIES"; 49 public static final String KEY_SETTINGS_INCLUDES = "SETTINGS_INCLUDES"; 50 public static final String DEFAULT_APP_PACKAGE = "com.android.databinding.compilationTest.test"; 51 52 File testFolder = new File("./build/build-test"); 53 54 protected void copyResourceTo(String name, String path) throws IOException { 55 copyResourceTo(name, new File(testFolder, path)); 56 } 57 58 protected void copyResourceDirectory(String name, String targetPath) 59 throws URISyntaxException, IOException { 60 URL dir = getClass().getResource(name); 61 assertNotNull(dir); 62 assertEquals("file", dir.getProtocol()); 63 File folder = new File(dir.toURI()); 64 assertTrue(folder.isDirectory()); 65 File target = new File(testFolder, targetPath); 66 int len = folder.getAbsolutePath().length() + 1; 67 for (File item : FileUtils.listFiles(folder, null, true)) { 68 if (item.getAbsolutePath().equals(folder.getAbsolutePath())) { 69 continue; 70 } 71 String resourcePath = item.getAbsolutePath().substring(len); 72 73 copyResourceTo(name + "/" + resourcePath, new File(target, resourcePath)); 74 } 75 } 76 77 @Before 78 public void clear() throws IOException { 79 if (testFolder.exists()) { 80 FileUtils.forceDelete(testFolder); 81 } 82 } 83 84 protected void copyResourceTo(String name, File targetFile) throws IOException { 85 File directory = targetFile.getParentFile(); 86 FileUtils.forceMkdir(directory); 87 InputStream contents = getClass().getResourceAsStream(name); 88 FileOutputStream fos = new FileOutputStream(targetFile); 89 IOUtils.copy(contents, fos); 90 IOUtils.closeQuietly(fos); 91 IOUtils.closeQuietly(contents); 92 } 93 94 protected static Map<String, String> toMap(String... keysAndValues) { 95 assertEquals(0, keysAndValues.length % 2); 96 Map<String, String> map = new HashMap<>(); 97 for (int i = 0; i < keysAndValues.length; i+=2) { 98 map.put(keysAndValues[i], keysAndValues[i + 1]); 99 } 100 return map; 101 } 102 103 protected void copyResourceTo(String name, File targetFile, Map<String, String> replacements) 104 throws IOException { 105 if (replacements.isEmpty()) { 106 copyResourceTo(name, targetFile); 107 } 108 InputStream inputStream = getClass().getResourceAsStream(name); 109 final String contents = IOUtils.toString(inputStream); 110 IOUtils.closeQuietly(inputStream); 111 112 StringBuilder out = new StringBuilder(contents.length()); 113 final Matcher matcher = VARIABLES.matcher(contents); 114 int location = 0; 115 while (matcher.find()) { 116 int start = matcher.start(); 117 if (start > location) { 118 out.append(contents, location, start); 119 } 120 final String key = matcher.group(1); 121 final String replacement = replacements.get(key); 122 if (replacement != null) { 123 out.append(replacement); 124 } 125 location = matcher.end(); 126 } 127 if (location < contents.length()) { 128 out.append(contents, location, contents.length()); 129 } 130 131 FileUtils.writeStringToFile(targetFile, out.toString()); 132 } 133 134 protected void prepareProject() throws IOException, URISyntaxException { 135 prepareApp(null); 136 } 137 138 private Map<String, String> addDefaults(Map<String, String> map) { 139 if (map == null) { 140 map = new HashMap<>(); 141 } 142 if (!map.containsKey(KEY_MANIFEST_PACKAGE)) { 143 map.put(KEY_MANIFEST_PACKAGE, DEFAULT_APP_PACKAGE); 144 } 145 if (!map.containsKey(KEY_SETTINGS_INCLUDES)) { 146 map.put(KEY_SETTINGS_INCLUDES, "include ':app'"); 147 } 148 return map; 149 } 150 151 protected void prepareApp(Map<String, String> replacements) throws IOException, 152 URISyntaxException { 153 replacements = addDefaults(replacements); 154 // how to get build folder, pass from gradle somehow ? 155 FileUtils.forceMkdir(testFolder); 156 copyResourceTo("/AndroidManifest.xml", new File(testFolder, "app/src/main/AndroidManifest.xml"), replacements); 157 copyResourceTo("/project_build.gradle", new File(testFolder, "build.gradle"), replacements); 158 copyResourceTo("/app_build.gradle", new File(testFolder, "app/build.gradle"), replacements); 159 copyResourceTo("/settings.gradle", new File(testFolder, "settings.gradle"), replacements); 160 File localProperties = new File("../local.properties"); 161 if (localProperties.exists()) { 162 FileUtils.copyFile(localProperties, new File(testFolder, "local.properties")); 163 } 164 FileUtils.copyFile(new File("../gradlew"), new File(testFolder, "gradlew")); 165 FileUtils.copyDirectory(new File("../gradle"), new File(testFolder, "gradle")); 166 } 167 168 protected void prepareModule(String moduleName, String packageName, 169 Map<String, String> replacements) throws IOException, URISyntaxException { 170 replacements = addDefaults(replacements); 171 replacements.put(KEY_MANIFEST_PACKAGE, packageName); 172 File moduleFolder = new File(testFolder, moduleName); 173 if (moduleFolder.exists()) { 174 FileUtils.forceDelete(moduleFolder); 175 } 176 FileUtils.forceMkdir(moduleFolder); 177 copyResourceTo("/AndroidManifest.xml", 178 new File(moduleFolder, "src/main/AndroidManifest.xml"), replacements); 179 copyResourceTo("/module_build.gradle", new File(moduleFolder, "build.gradle"), replacements); 180 } 181 182 protected CompilationResult runGradle(String params) throws IOException, InterruptedException { 183 setExecutable(); 184 File pathToExecutable = new File(testFolder, "gradlew"); 185 ProcessBuilder builder = new ProcessBuilder(pathToExecutable.getAbsolutePath(), params); 186 builder.environment().putAll(System.getenv()); 187 builder.directory(testFolder); 188 //builder.redirectErrorStream(true); // merges error and input streams 189 Process process = builder.start(); 190 String output = IOUtils.toString(process.getInputStream()); 191 String error = IOUtils.toString(process.getErrorStream()); 192 int result = process.waitFor(); 193 return new CompilationResult(result, output, error); 194 } 195 196 private void setExecutable() throws IOException { 197 Set<PosixFilePermission> perms = new HashSet<PosixFilePermission>(); 198 //add owners permission 199 perms.add(PosixFilePermission.OWNER_READ); 200 perms.add(PosixFilePermission.OWNER_WRITE); 201 perms.add(PosixFilePermission.OWNER_EXECUTE); 202 //add group permissions 203 perms.add(PosixFilePermission.GROUP_READ); 204 //add others permissions 205 perms.add(PosixFilePermission.OTHERS_READ); 206 Files.setPosixFilePermissions(Paths.get(new File(testFolder, "gradlew").getAbsolutePath()), perms); 207 } 208 209 210} 211