Skip to content

Commit

Permalink
Add configuration cache compatibility and config cache test
Browse files Browse the repository at this point in the history
  • Loading branch information
IgorDomagala committed Aug 31, 2023
1 parent 4c933e7 commit 2b6586a
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,53 +4,60 @@
import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.GradleRunner;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import sun.misc.Unsafe;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.nio.charset.StandardCharsets;

import static cz.habarta.typescript.generator.gradle.GradlePluginClasspathProvider.getClasspath;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.CoreMatchers.containsString;


public class BuildLogicFunctionalTest {


String sampleGradle = "/Users/igor/typescript-generator/sample-gradle";
String sampleGradle = "../../typescript-generator/sample-gradle";
File sourceDir = new File(sampleGradle + "/src");
@TempDir
File testProjectDir;
private File buildFile;
private File classpathFile;

@BeforeEach
public void setup() throws IOException {
// settingsFile = new File(testProjectDir, "settings.gradle");

public void setup() {
buildFile = new File(testProjectDir, "build.gradle");
classpathFile = new File(new File(BuildLogicFunctionalTest.class.getResource("/build.gradle.template").getPath()).getParent(), "plugin-under-test-metadata.properties");
classpathFile = new File(buildGradleTemplate().getParent(), "plugin-under-test-metadata.properties");
}


@Test
public void testConfigurationCache() throws IOException {
writeFile(classpathFile, "implementation-classpath=" + getClasspath(testProjectDir).stream().collect(Collectors.joining(File.pathSeparator)));
FileUtils.copyToFile(getClass().getResourceAsStream("/build.gradle.template"), buildFile);
public void shouldWorkWithConfigurationCache() throws IOException, NoSuchFieldException, IllegalAccessException {
String classpath = "implementation-classpath=" + String.join(File.pathSeparator, getClasspath(testProjectDir));
System.out.println("Classpath: " + classpath);
writeFile(classpathFile, classpath);
FileUtils.copyToFile(buildGradleTemplateUrl().openStream(), buildFile);
FileUtils.copyDirectory(sourceDir, new File(testProjectDir, "src"));

assertTrue(runGradle("assemble").getOutput().contains("BUILD SUCCESSFUL"));
BuildResult generateTypeScript = runGradle("generateTypeScript");
assertTrue(generateTypeScript.getOutput().contains("BUILD SUCCESSFUL"));

String testFileName = testProjectDir.getName() + ".d.ts";
String testFilePath = testProjectDir.toString() + "/build/typescript-generator/" + testFileName;
String schema = FileUtils.readFileToString(new File(testFilePath) , StandardCharsets.UTF_8);
assertThat(schema, containsString("export interface Person {\n"));
assertThat(schema, containsString("export interface PersonGroovy {\n"));
assertThat(schema, containsString("export interface PersonKt {\n"));
assertThat(schema, containsString("export interface PersonScala {\n"));

}

private BuildResult runGradle(String task) {
Expand All @@ -59,71 +66,28 @@ private BuildResult runGradle(String task) {
.withGradleVersion("8.2.1")
.withPluginClasspath()
.withArguments(
"--stacktrace",
"--info",
"--stacktrace",
"--info",
"--configuration-cache",
task
)
.build();
}

private static List<String> getClasspath(File projectDir) {
List<String> list = new ArrayList<>(Arrays.asList(getUrls(ClassLoader.getSystemClassLoader())).stream().map(URL::getFile).collect(Collectors.toList()));
list.addAll(buildDirs(projectDir.toString()));
return list;
@NotNull
private static File buildGradleTemplate() {
return new File(buildGradleTemplateUrl().getPath());
}

@NotNull
private static List<String> buildDirs(String sampleGradle) {
List<String> projectBuildDirs = new ArrayList<>();
projectBuildDirs.add(sampleGradle + "/build/classes/java/main/");
projectBuildDirs.add(sampleGradle + "/build/classes/groovy/main/");
projectBuildDirs.add(sampleGradle + "/build/classes/scala/main/");
projectBuildDirs.add(sampleGradle + "/build/classes/kotlin/main/");
return projectBuildDirs;
@Nullable
private static URL buildGradleTemplateUrl() {
return BuildLogicFunctionalTest.class.getResource("/build.gradle.template");
}

private void writeFile(File destination, String content) throws IOException {
BufferedWriter output = null;
try {
output = new BufferedWriter(new FileWriter(destination));
try (BufferedWriter output = new BufferedWriter(new FileWriter(destination))) {
output.write(content);
} finally {
if (output != null) {
output.close();
}
}
}

public static URL[] getUrls(ClassLoader classLoader) {
if (classLoader instanceof URLClassLoader) {
return ((URLClassLoader) classLoader).getURLs();
}

// jdk9
if (classLoader.getClass().getName().startsWith("jdk.internal.loader.ClassLoaders$")) {
try {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
Unsafe unsafe = (Unsafe) field.get(null);

// jdk.internal.loader.ClassLoaders.AppClassLoader.ucp
Field ucpField = classLoader.getClass().getSuperclass().getDeclaredField("ucp");
long ucpFieldOffset = unsafe.objectFieldOffset(ucpField);
Object ucpObject = unsafe.getObject(classLoader, ucpFieldOffset);

// jdk.internal.loader.URLClassPath.path
Field pathField = ucpField.getType().getDeclaredField("path");
long pathFieldOffset = unsafe.objectFieldOffset(pathField);
ArrayList<URL> path = (ArrayList<URL>) unsafe.getObject(ucpObject, pathFieldOffset);

return path.toArray(new URL[path.size()]);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
return null;
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package cz.habarta.typescript.generator.gradle;

import org.jetbrains.annotations.NotNull;
import sun.misc.Unsafe;

import java.io.File;
import java.lang.reflect.Field;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.*;
import java.util.stream.Collectors;

public class GradlePluginClasspathProvider {
public static List<String> getClasspath(File projectDir) throws NoSuchFieldException, IllegalAccessException {
List<String> list = new ArrayList<>(Arrays.asList(GradlePluginClasspathProvider.getUrls(ClassLoader.getSystemClassLoader())).stream().map(URL::getFile).collect(Collectors.toList()));
list.addAll(buildDirs(projectDir.toString()));
return list;
}

public static URL[] getUrls(ClassLoader classLoader) throws NoSuchFieldException, IllegalAccessException {
System.out.println(classLoader.getClass().getName());
if (classLoader instanceof URLClassLoader) {
return ((URLClassLoader) classLoader).getURLs();
}

// jdk9
if (classLoader.getClass().getName().startsWith("jdk.internal.loader.ClassLoaders$")) {
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
Unsafe unsafe = (Unsafe) field.get(null);

// jdk.internal.loader.ClassLoaders.AppClassLoader.ucp
Field ucpField = classLoader.getClass().getSuperclass().getDeclaredField("ucp");
long ucpFieldOffset = unsafe.objectFieldOffset(ucpField);
Object ucpObject = unsafe.getObject(classLoader, ucpFieldOffset);

// jdk.internal.loader.URLClassPath.path
Field pathField = ucpField.getType().getDeclaredField("path");
long pathFieldOffset = unsafe.objectFieldOffset(pathField);
ArrayList<URL> path = (ArrayList<URL>) unsafe.getObject(ucpObject, pathFieldOffset);

Field mapField = ucpField.getType().getDeclaredField("lmap");
long mapFieldOffset = unsafe.objectFieldOffset(mapField);
Map<String, Object> map = (Map<String, Object>) unsafe.getObject(ucpObject, mapFieldOffset);
List<URL> all = new ArrayList<>();
all.addAll(path);
all.addAll(map.keySet().stream().map(url -> {
try {
return new URL(url);
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
}).collect(Collectors.toSet()));
return all.toArray(new URL[0]);
}
return null;
}

@NotNull
private static List<String> buildDirs(String sampleGradleDir) {
List<String> buildDirs = new ArrayList<>();
buildDirs.add(sampleGradleDir + "/build/classes/java/main/");
buildDirs.add(sampleGradleDir + "/build/classes/groovy/main/");
buildDirs.add(sampleGradleDir + "/build/classes/scala/main/");
buildDirs.add(sampleGradleDir + "/build/classes/kotlin/main/");
return buildDirs;
}

}

0 comments on commit 2b6586a

Please sign in to comment.