+ * 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 + *
+ * https://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 org.openrewrite.csharp.remote; + +import org.junit.jupiter.api.Test; +import org.openrewrite.Cursor; +import org.openrewrite.InMemoryExecutionContext; +import org.openrewrite.remote.RemotingProjectParser; +import org.openrewrite.scheduling.WatchableExecutionContext; + +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.concurrent.ThreadLocalRandom; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +public class ProjectParsingTest { + + @Test + public void testParse() { + WatchableExecutionContext ctx = + new WatchableExecutionContext(new InMemoryExecutionContext()); + + int port = ThreadLocalRandom.current().nextInt(50000, 65535); + try (DotNetRemotingServerEngine server = DotNetRemotingServerEngine.create(DotNetRemotingServerEngine.Config.builder() + .extractedDotnetBinaryDir(Paths.get(System.getProperty("java.io.tmpdir"))) + .port(port) + .logFilePath(Paths.get("./build/test.log").toAbsolutePath().toString()) + .build())) { + + server.start(); + var client = new RemotingProjectParser(server); + + Path pathToSolution = Path.of(Thread.currentThread() + .getContextClassLoader() + .getResource( + "ModerneHelloWorld/ModerneHelloWorld.sln") + .getPath()); + client.findAllProjects(pathToSolution, ctx) + .forEach(proj -> client.parseProjectSources(proj, + pathToSolution, + pathToSolution.getParent(), + ctx) + .forEach(sf -> { + System.out.println(sf.print(new Cursor(new Cursor( + null, + Cursor.ROOT_VALUE), sf))); + })); + } + } + + @Test + public void testThrowExceptionOnIncorrectDotnetPath() { + int port = ThreadLocalRandom.current().nextInt(50000, 65535); + try (DotNetRemotingServerEngine server = DotNetRemotingServerEngine.create(DotNetRemotingServerEngine.Config.builder().dotnetExecutable("dotnet1").extractedDotnetBinaryDir( + Paths.get(System.getProperty("java.io.tmpdir"))).port(port).build())) { + assertThatThrownBy(server::start) + .isInstanceOf(IOException.class); + } + } + + @Test + public void testThrowExceptionOnIncorrectRunnable() { + int port = ThreadLocalRandom.current().nextInt(50000, 65535); + try (DotNetRemotingServerEngine server = DotNetRemotingServerEngine.create(DotNetRemotingServerEngine.Config.builder() + .extractedDotnetBinaryDir(Paths.get(System.getProperty("java.io.tmpdir"))) + .dotnetServerDllName("Rewrite.Server1.dll") + .port(port) + .build())) { + assertThatThrownBy(server::start) + .isInstanceOf(IllegalStateException.class); + } + } +} diff --git a/rewrite-csharp-remote-server/src/test/java/org/openrewrite/csharp/remote/RemotingRecipeRunTest.java b/rewrite-csharp-remote-server/src/test/java/org/openrewrite/csharp/remote/RemotingRecipeRunTest.java new file mode 100644 index 00000000..9215428d --- /dev/null +++ b/rewrite-csharp-remote-server/src/test/java/org/openrewrite/csharp/remote/RemotingRecipeRunTest.java @@ -0,0 +1,111 @@ +/* + * Copyright 2024 the original author or authors. + *
+ * 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 + *
+ * https://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 org.openrewrite.csharp.remote;
+
+import lombok.extern.java.Log;
+import org.junit.jupiter.api.Test;
+import org.openrewrite.InMemoryExecutionContext;
+import org.openrewrite.RecipeRun;
+import org.openrewrite.SourceFile;
+import org.openrewrite.config.RecipeDescriptor;
+import org.openrewrite.internal.InMemoryLargeSourceSet;
+import org.openrewrite.java.JavaParser;
+import org.openrewrite.remote.InstallableRemotingRecipe;
+import org.openrewrite.remote.PackageSource;
+import org.openrewrite.remote.RemotingContext;
+import org.openrewrite.remote.RemotingExecutionContextView;
+import org.openrewrite.remote.RemotingRecipe;
+import org.openrewrite.remote.RemotingRecipeManager;
+import org.openrewrite.remote.TcpUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.logging.Level;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.fail;
+
+@Log
+public class RemotingRecipeRunTest {
+
+ @Test
+ public void testRemotingRecipeInstallAndRun() throws IOException {
+ File nuPkgLocation = new File("./build/nupkgs");
+ nuPkgLocation.mkdir();
+ int port = TcpUtils.findAvailableTcpPortInternal();
+ Path extractedDotnetBinaryDir = Paths.get("./build/dotnet-servet-archive");
+ extractedDotnetBinaryDir.toFile().mkdirs();
+ DotNetRemotingServerEngine server = DotNetRemotingServerEngine.create(
+ DotNetRemotingServerEngine.Config.builder()
+ .extractedDotnetBinaryDir(extractedDotnetBinaryDir)
+ .logFilePath(Paths.get("./build/test.log").toAbsolutePath().toString())
+ .nugetPackagesFolder(nuPkgLocation.toPath().toAbsolutePath().normalize().toString())
+ .port(port)
+ .build()
+ );
+ try {
+ server.start();
+
+ InMemoryExecutionContext ctx = new InMemoryExecutionContext((e) -> log.log(Level.WARNING, e.toString()));
+
+ RemotingExecutionContextView view = RemotingExecutionContextView.view(ctx);
+ view.setRemotingContext(new RemotingContext(this.getClass().getClassLoader(), false));
+
+ RemotingRecipeManager manager = new RemotingRecipeManager(server, () -> server);
+ InstallableRemotingRecipe recipes = manager.install(
+ "Rewrite.Recipes",
+ "0.3.3",
+ Arrays.asList(
+ new PackageSource(Paths.get("~/.nuget/packages/").toAbsolutePath().toFile().toURI().toURL(), null, null, true)
+ ),
+ true,
+ ctx
+ );
+
+ RemotingRecipe remotingRecipe = new RemotingRecipe(new RecipeDescriptor(
+ recipes.getRecipes().get(0).getDescriptor().getName(),
+ recipes.getRecipes().get(0).getDescriptor().getDisplayName(),
+ recipes.getRecipes().get(0).getDescriptor().getDescription(),
+ recipes.getRecipes().get(0).getDescriptor().getTags(),
+ recipes.getRecipes().get(0).getDescriptor().getEstimatedEffortPerOccurrence(),
+ Collections.emptyList(),
+ Collections.emptyList(),
+ Collections.emptyList(),
+ Collections.emptyList(),
+ Collections.emptyList(),
+ Collections.emptyList(),
+ recipes.getRecipes().get(0).getDescriptor().getSource() // recipe://testlibnamepackageid/1.0.1
+ ), () -> server, DotNetRemotingServerEngine.class);
+
+ SourceFile tree = JavaParser.fromJavaVersion().build().parse("class Foo {}")
+ .findFirst()
+ .orElseThrow();
+
+ RecipeRun run = remotingRecipe.run(new InMemoryLargeSourceSet(Collections.singletonList(tree)), ctx);
+ assertThat(run.getChangeset().getAllResults()).hasSize(1);
+ run.getChangeset().getAllResults().forEach(r -> System.out.println(r.diff()));
+ } catch (Exception e) {
+ server.close();
+ fail(e);
+ }
+
+ server.close();
+ }
+}
diff --git a/rewrite-csharp-remote-server/src/test/resources/ModerneHelloWorld/ConsoleApp1/ConsoleApp1.csproj b/rewrite-csharp-remote-server/src/test/resources/ModerneHelloWorld/ConsoleApp1/ConsoleApp1.csproj
new file mode 100644
index 00000000..2f4fc776
--- /dev/null
+++ b/rewrite-csharp-remote-server/src/test/resources/ModerneHelloWorld/ConsoleApp1/ConsoleApp1.csproj
@@ -0,0 +1,10 @@
+
+ * 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 + *
+ * https://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.
+ */
+public static class Program
+{
+ public static void Main(string[] args)
+ {
+ Console.WriteLine("Hello, World2!");
+ }
+}
\ No newline at end of file
diff --git a/rewrite-csharp-remote-server/src/test/resources/ModerneHelloWorld/ModerneHelloWorld.sln b/rewrite-csharp-remote-server/src/test/resources/ModerneHelloWorld/ModerneHelloWorld.sln
new file mode 100644
index 00000000..77b7fd36
--- /dev/null
+++ b/rewrite-csharp-remote-server/src/test/resources/ModerneHelloWorld/ModerneHelloWorld.sln
@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModerneHelloWorld", "ModerneHelloWorld\ModerneHelloWorld.csproj", "{F863BE90-C9B9-4269-8110-B1892375B18B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleApp1", "ConsoleApp1\ConsoleApp1.csproj", "{73E1FF0F-5CB2-4A66-A4D4-1C822E9B7D0D}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {F863BE90-C9B9-4269-8110-B1892375B18B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F863BE90-C9B9-4269-8110-B1892375B18B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F863BE90-C9B9-4269-8110-B1892375B18B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F863BE90-C9B9-4269-8110-B1892375B18B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {73E1FF0F-5CB2-4A66-A4D4-1C822E9B7D0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {73E1FF0F-5CB2-4A66-A4D4-1C822E9B7D0D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {73E1FF0F-5CB2-4A66-A4D4-1C822E9B7D0D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {73E1FF0F-5CB2-4A66-A4D4-1C822E9B7D0D}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+EndGlobal
diff --git a/rewrite-csharp-remote-server/src/test/resources/ModerneHelloWorld/ModerneHelloWorld/ModerneHelloWorld.csproj b/rewrite-csharp-remote-server/src/test/resources/ModerneHelloWorld/ModerneHelloWorld/ModerneHelloWorld.csproj
new file mode 100644
index 00000000..2f4fc776
--- /dev/null
+++ b/rewrite-csharp-remote-server/src/test/resources/ModerneHelloWorld/ModerneHelloWorld/ModerneHelloWorld.csproj
@@ -0,0 +1,10 @@
+
+ * 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 + *
+ * https://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. + */ + +namespace ModerneHelloWorld; + +public static class Program +{ + public static void Main(string[] args) + { + Console.WriteLine("Hello, World!"); + } +} \ No newline at end of file diff --git a/rewrite-csharp-remote-server/src/test/resources/ModerneHelloWorld/global.json b/rewrite-csharp-remote-server/src/test/resources/ModerneHelloWorld/global.json new file mode 100644 index 00000000..7b6bb113 --- /dev/null +++ b/rewrite-csharp-remote-server/src/test/resources/ModerneHelloWorld/global.json @@ -0,0 +1,22 @@ +/** + * Copyright 2024 the original author or authors. + *
+ * 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 + *
+ * https://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. + */ +{ + "sdk": { + "version": "8.0.0", + "rollForward": "latestMinor", + "allowPrerelease": false + } +} \ No newline at end of file