You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by pt...@apache.org on 2021/10/01 17:11:30 UTC

[ignite-3] branch main updated: IGNITE-15670 .NET: Fix ClientSocketTests flakiness (#372)

This is an automated email from the ASF dual-hosted git repository.

ptupitsyn pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git


The following commit(s) were added to refs/heads/main by this push:
     new 0093c83  IGNITE-15670 .NET: Fix ClientSocketTests flakiness (#372)
0093c83 is described below

commit 0093c836ffbe0ac423f513382cd03e95b4918fe8
Author: Pavel Tupitsyn <pt...@apache.org>
AuthorDate: Fri Oct 1 20:11:26 2021 +0300

    IGNITE-15670 .NET: Fix ClientSocketTests flakiness (#372)
    
    `mvn exec` downloads artifacts on the first run, which may cause node start timeout when the network is slow. Perform a separate, dry run of the command with a bigger timeout to download artifacts and compile the code with a bigger timeout (5 minutes). Then start the node with a smaller timeout.
---
 .../dotnet/Apache.Ignite.Tests/JavaServer.cs       | 103 ++++++++++++++++-----
 .../runner/app/PlatformTestNodeRunner.java         |  19 +++-
 2 files changed, 100 insertions(+), 22 deletions(-)

diff --git a/modules/platforms/dotnet/Apache.Ignite.Tests/JavaServer.cs b/modules/platforms/dotnet/Apache.Ignite.Tests/JavaServer.cs
index 7d1628d..730fe54 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Tests/JavaServer.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Tests/JavaServer.cs
@@ -33,12 +33,19 @@ namespace Apache.Ignite.Tests
     {
         private const int DefaultClientPort = 10942;
 
+        private const int ConnectTimeoutSeconds = 20;
+
         /** Maven command to execute the main class. */
         private const string MavenCommandExec = "exec:java@platform-test-node-runner";
 
+        /** Maven arg to perform a dry run to ensure that code is compiled and all artifacts are downloaded. */
+        private const string MavenCommandDryRunArg = " -Dexec.args=dry-run";
+
         /** Full path to Maven binary. */
         private static readonly string MavenPath = GetMaven();
 
+        private static volatile bool _dryRunComplete;
+
         private readonly Process? _process;
 
         public JavaServer(int port, Process? process)
@@ -65,25 +72,8 @@ namespace Apache.Ignite.Tests
 
             Log(">>> Java server is not detected, starting...");
 
-            var file = TestUtils.IsWindows ? "cmd.exe" : "/bin/bash";
-
-            var process = new Process
-            {
-                StartInfo = new ProcessStartInfo
-                {
-                    FileName = file,
-                    ArgumentList =
-                    {
-                        TestUtils.IsWindows ? "/c" : "-c",
-                        $"{MavenPath} {MavenCommandExec}"
-                    },
-                    CreateNoWindow = true,
-                    UseShellExecute = false,
-                    WorkingDirectory = Path.Combine(TestUtils.RepoRootDir, "modules", "runner"),
-                    RedirectStandardOutput = true,
-                    RedirectStandardError = true
-                }
-            };
+            EnsureBuild();
+            var process = CreateProcess();
 
             var evt = new ManualResetEventSlim(false);
             int[]? ports = null;
@@ -115,7 +105,7 @@ namespace Apache.Ignite.Tests
 
             var port = ports?.FirstOrDefault() ?? DefaultClientPort;
 
-            if (!evt.Wait(TimeSpan.FromSeconds(15)) || !WaitForServer(port))
+            if (!evt.Wait(TimeSpan.FromSeconds(ConnectTimeoutSeconds)) || !WaitForServer(port))
             {
                 process.Kill(true);
 
@@ -133,6 +123,77 @@ namespace Apache.Ignite.Tests
             _process?.Dispose();
         }
 
+        /// <summary>
+        /// Performs a dry run of the Maven executable to ensure that code is compiled and all artifacts are downloaded.
+        /// Does not start the actual node.
+        /// </summary>
+        private static void EnsureBuild()
+        {
+            if (_dryRunComplete)
+            {
+                return;
+            }
+
+            using var process = CreateProcess(dryRun: true);
+
+            DataReceivedEventHandler handler = (_, eventArgs) =>
+            {
+                var line = eventArgs.Data;
+                if (line == null)
+                {
+                    return;
+                }
+
+                Log(line);
+            };
+
+            process.OutputDataReceived += handler;
+            process.ErrorDataReceived += handler;
+
+            process.Start();
+
+            process.BeginErrorReadLine();
+            process.BeginOutputReadLine();
+
+            // 5 min timeout for the build process (may take time to download artifacts on slow networks).
+            if (!process.WaitForExit(5 * 60_000))
+            {
+                process.Kill();
+                throw new Exception("Failed to wait for Maven exec dry run.");
+            }
+
+            if (process.ExitCode != 0)
+            {
+                throw new Exception($"Maven exec failed with code {process.ExitCode}, check log for details.");
+            }
+
+            _dryRunComplete = true;
+        }
+
+        private static Process CreateProcess(bool dryRun = false)
+        {
+            var file = TestUtils.IsWindows ? "cmd.exe" : "/bin/bash";
+
+            var process = new Process
+            {
+                StartInfo = new ProcessStartInfo
+                {
+                    FileName = file,
+                    ArgumentList =
+                    {
+                        TestUtils.IsWindows ? "/c" : "-c",
+                        $"{MavenPath} {MavenCommandExec}" + (dryRun ? MavenCommandDryRunArg : string.Empty)
+                    },
+                    CreateNoWindow = true,
+                    UseShellExecute = false,
+                    WorkingDirectory = Path.Combine(TestUtils.RepoRootDir, "modules", "runner"),
+                    RedirectStandardOutput = true,
+                    RedirectStandardError = true
+                }
+            };
+            return process;
+        }
+
         private static void Log(string? line)
         {
             // For IDE.
@@ -148,7 +209,7 @@ namespace Apache.Ignite.Tests
 
             try
             {
-                return TryConnectForever(port, cts.Token).Wait(TimeSpan.FromSeconds(15));
+                return TryConnectForever(port, cts.Token).Wait(TimeSpan.FromSeconds(ConnectTimeoutSeconds));
             }
             finally
             {
diff --git a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/PlatformTestNodeRunner.java b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/PlatformTestNodeRunner.java
index b9416e1..f7a8f84 100644
--- a/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/PlatformTestNodeRunner.java
+++ b/modules/runner/src/integrationTest/java/org/apache/ignite/internal/runner/app/PlatformTestNodeRunner.java
@@ -48,6 +48,9 @@ public class PlatformTestNodeRunner {
     /** */
     private static final String TABLE_NAME = "tbl1";
 
+    /** Time to keep the node alive. */
+    private static final int RUN_TIME_MINUTES = 30;
+
     /** Nodes bootstrap configuration. */
     private static final Map<String, String> nodesBootstrapCfg = new LinkedHashMap<>() {{
         put(NODE_NAME, "{\n" +
@@ -70,6 +73,18 @@ public class PlatformTestNodeRunner {
      * @param args Args.
      */
     public static void main(String[] args) throws Exception {
+        System.out.println("Starting test node runner...");
+
+        for (int i = 0; i < args.length; i++) {
+            System.out.println("Arg " + i + ": " + args[i]);
+        }
+
+        if (args.length > 0 && "dry-run".equals(args[0]))
+        {
+            System.out.println("Dry run succeeded.");
+            return;
+        }
+
         IgniteUtils.deleteIfExists(BASE_PATH);
         Files.createDirectories(BASE_PATH);
 
@@ -99,7 +114,9 @@ public class PlatformTestNodeRunner {
 
         System.out.println("THIN_CLIENT_PORTS=" + ports);
 
-        Thread.sleep(Long.MAX_VALUE);
+        Thread.sleep(RUN_TIME_MINUTES * 60_000);
+
+        System.out.println("Exiting after " + RUN_TIME_MINUTES + " minutes.");
     }
 
     /**