]> source.dussan.org Git - sonarqube.git/commitdiff
Extract an interface from org.sonar.process.ProcessCommands
authorSimon Brandhof <simon.brandhof@sonarsource.com>
Fri, 29 May 2015 09:25:01 +0000 (11:25 +0200)
committerSimon Brandhof <simon.brandhof@sonarsource.com>
Fri, 29 May 2015 09:25:01 +0000 (11:25 +0200)
Try to stabilize StopWatcherTest when machine is slow or under pressure. More than 1 second could
be spent in the creation of ProcessCommands mock.

server/sonar-process-monitor/src/main/java/org/sonar/process/monitor/JavaProcessLauncher.java
server/sonar-process-monitor/src/main/java/org/sonar/process/monitor/Monitor.java
server/sonar-process-monitor/src/test/java/org/sonar/process/monitor/MonitorTest.java
server/sonar-process/src/main/java/org/sonar/process/DefaultProcessCommands.java [new file with mode: 0644]
server/sonar-process/src/main/java/org/sonar/process/ProcessCommands.java
server/sonar-process/src/main/java/org/sonar/process/ProcessEntryPoint.java
server/sonar-process/src/test/java/org/sonar/process/DefaultProcessCommandsTest.java [new file with mode: 0644]
server/sonar-process/src/test/java/org/sonar/process/ProcessCommandsTest.java [deleted file]
server/sonar-process/src/test/java/org/sonar/process/StopWatcherTest.java
sonar-application/src/main/java/org/sonar/application/App.java

index 1e3ee06648e677d976b2c87ea908f7042509c23e..390746bca5977a42c268183f6982f45c85eb6032 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.process.monitor;
 
 import org.apache.commons.lang.StringUtils;
 import org.slf4j.LoggerFactory;
+import org.sonar.process.DefaultProcessCommands;
 import org.sonar.process.ProcessCommands;
 import org.sonar.process.ProcessEntryPoint;
 import org.sonar.process.ProcessUtils;
@@ -45,7 +46,7 @@ public class JavaProcessLauncher {
     Process process = null;
     try {
       // cleanup existing monitor files
-      ProcessCommands commands = new ProcessCommands(command.getTempDir(), command.getProcessIndex());
+      ProcessCommands commands = new DefaultProcessCommands(command.getTempDir(), command.getProcessIndex());
 
       ProcessBuilder processBuilder = create(command);
       LoggerFactory.getLogger(getClass()).info("Launch process[{}]: {}",
index df3d53518ee9d585929539cdc3840416825d568d..dd0ca58ba0a4c26588eaea6f694454d6b01ccbab 100644 (file)
  */
 package org.sonar.process.monitor;
 
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
 import org.slf4j.LoggerFactory;
 import org.sonar.process.Lifecycle;
 import org.sonar.process.Lifecycle.State;
 import org.sonar.process.ProcessCommands;
 import org.sonar.process.SystemExit;
 
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
-
 public class Monitor {
 
   private final List<ProcessRef> processes = new CopyOnWriteArrayList<>();
@@ -165,8 +164,8 @@ public class Monitor {
   }
 
   public static int getNextProcessId() {
-    if (nextProcessId >= ProcessCommands.getMaxProcesses()) {
-      throw new IllegalStateException("The maximum number of processes launched has been reached " + ProcessCommands.getMaxProcesses());
+    if (nextProcessId >= ProcessCommands.MAX_PROCESSES) {
+      throw new IllegalStateException("The maximum number of processes launched has been reached " + ProcessCommands.MAX_PROCESSES);
     }
     return nextProcessId++;
   }
index 57e3478162ca5d8168d043b344a29cf2ca150ec4..00ae573ed6a36a1862573816ab2f6c6813b18d33 100644 (file)
 package org.sonar.process.monitor;
 
 import com.github.kevinsawicki.http.HttpRequest;
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
 import org.apache.commons.io.FileUtils;
 import org.junit.After;
 import org.junit.BeforeClass;
@@ -27,17 +32,11 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 import org.junit.rules.Timeout;
-import org.sonar.process.NetworkUtils;
 import org.sonar.process.Lifecycle.State;
+import org.sonar.process.NetworkUtils;
 import org.sonar.process.ProcessCommands;
 import org.sonar.process.SystemExit;
 
-import java.io.File;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.Assert.fail;
 import static org.mockito.Mockito.mock;
@@ -211,7 +210,8 @@ public class MonitorTest {
 
   @Test
   public void test_too_many_processes() {
-    while (Monitor.getNextProcessId() < ProcessCommands.getMaxProcesses() - 1) {}
+    while (Monitor.getNextProcessId() < ProcessCommands.MAX_PROCESSES - 1) {
+    }
     try {
       newDefaultMonitor();
     } catch (IllegalStateException e) {
diff --git a/server/sonar-process/src/main/java/org/sonar/process/DefaultProcessCommands.java b/server/sonar-process/src/main/java/org/sonar/process/DefaultProcessCommands.java
new file mode 100644 (file)
index 0000000..f299252
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.process;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+import org.apache.commons.io.IOUtils;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Process inter-communication to :
+ * <ul>
+ *   <li>share status of child process</li>
+ *   <li>stop child process</li>
+ * </ul>
+ *
+ * <p/>
+ * It relies on files shared by both processes. Following alternatives were considered but not selected :
+ * <ul>
+ *   <li>JMX beans over RMI: network issues (mostly because of Java reverse-DNS) + requires to configure and open a new port</li>
+ *   <li>simple socket protocol: same drawbacks are RMI connection</li>
+ *   <li>java.lang.Process#destroy(): shutdown hooks are not executed on some OS (mostly MSWindows)</li>
+ *   <li>execute OS-specific commands (for instance kill on *nix): OS-specific, so hell to support. Moreover how to get identify a process ?</li>
+ * </ul>
+ */
+public class DefaultProcessCommands implements ProcessCommands {
+
+  /**
+   * The ByteBuffer will contains :
+   * <ul>
+   *   <li>First byte will contains 0x00 until stop command is issued = 0xFF</li>
+   *   <li>Then each 10 bytes will be reserved for each process</li>
+   * </ul>
+   *
+   * Description of ten bytes of each process :
+   * <ul>
+   *   <li>First byte will contains the state 0x00 until READY 0x01</li>
+   *   <li>The second byte will contains the request for stopping 0x00 or STOP (0xFF)</li>
+   *   <li>The next 8 bytes contains a long (System.currentTimeInMillis for ping)</li>
+   * </ul>
+   */
+  final MappedByteBuffer mappedByteBuffer;
+  private final RandomAccessFile sharedMemory;
+  private static final int BYTE_LENGTH_FOR_ONE_PROCESS = 1 + 1 + 8;
+
+  // With this shared memory we can handle up to MAX_PROCESSES processes
+  private static final int MAX_SHARED_MEMORY = BYTE_LENGTH_FOR_ONE_PROCESS * MAX_PROCESSES;
+
+  public static final byte STOP = (byte) 0xFF;
+  public static final byte READY = (byte) 0x01;
+  public static final byte EMPTY = (byte) 0x00;
+
+  private int processNumber;
+
+  public DefaultProcessCommands(File directory, int processNumber) {
+    // processNumber should not excess MAX_PROCESSES and must not be below -1
+    assert processNumber <= MAX_PROCESSES : "Incorrect process number";
+    assert processNumber >= -1 : "Incorrect process number";
+
+    this.processNumber = processNumber;
+    if (!directory.isDirectory() || !directory.exists()) {
+      throw new IllegalArgumentException("Not a valid directory: " + directory);
+    }
+
+    try {
+      sharedMemory = new RandomAccessFile(new File(directory, "sharedmemory"), "rw");
+      mappedByteBuffer = sharedMemory.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, MAX_SHARED_MEMORY);
+      cleanData();
+    } catch (IOException e) {
+      throw new IllegalArgumentException("Unable to create shared memory : ", e);
+    }
+  }
+
+  @Override
+  public boolean isReady() {
+    return canBeMonitored() && mappedByteBuffer.get(offset()) == READY;
+  }
+
+  /**
+   * To be executed by child process to declare that it's ready
+   */
+  @Override
+  public void setReady() {
+    if (canBeMonitored()) {
+      mappedByteBuffer.put(offset(), READY);
+    }
+  }
+
+  @Override
+  public void ping() {
+    if (canBeMonitored()) {
+      mappedByteBuffer.putLong(2 + offset(), System.currentTimeMillis());
+    }
+  }
+
+  @Override
+  public long getLastPing() {
+    if (canBeMonitored()) {
+      return mappedByteBuffer.getLong(2 + offset());
+    } else {
+      return -1;
+    }
+  }
+
+  /**
+   * To be executed by monitor process to ask for child process termination
+   */
+  @Override
+  public void askForStop() {
+    mappedByteBuffer.put(offset() + 1, STOP);
+  }
+
+  @Override
+  public boolean askedForStop() {
+    return mappedByteBuffer.get(offset() + 1) == STOP;
+  }
+
+  @Override
+  public void endWatch() {
+    IOUtils.closeQuietly(sharedMemory);
+  }
+
+  int offset() {
+    return BYTE_LENGTH_FOR_ONE_PROCESS * processNumber;
+  }
+
+  private boolean canBeMonitored() {
+    boolean result = processNumber >= 0 && processNumber < MAX_PROCESSES;
+    if (!result) {
+      LoggerFactory.getLogger(getClass()).info("This process cannot be monitored. Process Id : [{}]", processNumber);
+    }
+    return result;
+  }
+
+  private void cleanData() {
+    for (int i = 0; i < BYTE_LENGTH_FOR_ONE_PROCESS; i++) {
+      mappedByteBuffer.put(offset() + i, EMPTY);
+    }
+  }
+}
index d697f542f3234a9e7173e49de4c5eafadd5f3c9c..8c027d45c7c11d8c5823d9edb23bfa62e4611ffe 100644 (file)
  */
 package org.sonar.process;
 
-import org.apache.commons.io.IOUtils;
-import org.slf4j.LoggerFactory;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.nio.MappedByteBuffer;
-import java.nio.channels.FileChannel;
-
 /**
  * Process inter-communication to :
  * <ul>
@@ -44,116 +35,27 @@ import java.nio.channels.FileChannel;
  *   <li>execute OS-specific commands (for instance kill on *nix): OS-specific, so hell to support. Moreover how to get identify a process ?</li>
  * </ul>
  */
-public class ProcessCommands {
-
-  /**
-   * The ByteBuffer will contains :
-   * <ul>
-   *   <li>First byte will contains 0x00 until stop command is issued = 0xFF</li>
-   *   <li>Then each 10 bytes will be reserved for each process</li>
-   * </ul>
-   *
-   * Description of ten bytes of each process :
-   * <ul>
-   *   <li>First byte will contains the state 0x00 until READY 0x01</li>
-   *   <li>The second byte will contains the request for stopping 0x00 or STOP (0xFF)</li>
-   *   <li>The next 8 bytes contains a long (System.currentTimeInMillis for ping)</li>
-   * </ul>
-   */
-  final MappedByteBuffer mappedByteBuffer;
-  private final RandomAccessFile sharedMemory;
-  private static final int MAX_PROCESSES = 50;
-  private static final int BYTE_LENGTH_FOR_ONE_PROCESS = 1 + 1 + 8;
-
-  // With this shared memory we can handle up to MAX_PROCESSES processes
-  private static final int MAX_SHARED_MEMORY = BYTE_LENGTH_FOR_ONE_PROCESS * MAX_PROCESSES;
-
-  public static final byte STOP = (byte) 0xFF;
-  public static final byte READY = (byte) 0x01;
-  public static final byte EMPTY = (byte) 0x00;
+public interface ProcessCommands {
 
-  private int processNumber;
+  int MAX_PROCESSES = 50;
 
-  public ProcessCommands(File directory, int processNumber) {
-    // processNumber should not excess MAX_PROCESSES and must not be below -1
-    assert processNumber <= MAX_PROCESSES : "Incorrect process number";
-    assert processNumber >= -1 : "Incorrect process number";
-
-    this.processNumber = processNumber;
-    if (!directory.isDirectory() || !directory.exists()) {
-      throw new IllegalArgumentException("Not a valid directory: " + directory);
-    }
-
-    try {
-      sharedMemory = new RandomAccessFile(new File(directory, "sharedmemory"), "rw");
-      mappedByteBuffer = sharedMemory.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, MAX_SHARED_MEMORY);
-      cleanData();
-    } catch (IOException e) {
-      throw new IllegalArgumentException("Unable to create shared memory : ", e);
-    }
-  }
-
-  public boolean isReady() {
-    return canBeMonitored() && mappedByteBuffer.get(offset()) == READY;
-  }
+  boolean isReady();
 
   /**
    * To be executed by child process to declare that it's ready
    */
-  public void setReady() {
-    if (canBeMonitored()) {
-      mappedByteBuffer.put(offset(), READY);
-    }
-  }
+  void setReady();
 
-  public void ping() {
-    if (canBeMonitored()) {
-      mappedByteBuffer.putLong(2 + offset(), System.currentTimeMillis());
-    }
-  }
+  void ping();
 
-  public long getLastPing() {
-    if (canBeMonitored()) {
-      return mappedByteBuffer.getLong(2 + offset());
-    } else {
-      return -1;
-    }
-  }
+  long getLastPing();
 
   /**
    * To be executed by monitor process to ask for child process termination
    */
-  public void askForStop() {
-    mappedByteBuffer.put(offset() + 1, STOP);
-  }
-
-  public boolean askedForStop() {
-    return mappedByteBuffer.get(offset() + 1) == STOP;
-  }
-
-  public void endWatch() {
-    IOUtils.closeQuietly(sharedMemory);
-  }
-
-  int offset() {
-    return BYTE_LENGTH_FOR_ONE_PROCESS * processNumber;
-  }
-
-  private boolean canBeMonitored() {
-    boolean result = processNumber >= 0 && processNumber < MAX_PROCESSES;
-    if (!result) {
-      LoggerFactory.getLogger(getClass()).info("This process cannot be monitored. Process Id : [{}]", processNumber);
-    }
-    return result;
-  }
+  void askForStop();
 
-  private void cleanData() {
-    for (int i = 0; i < BYTE_LENGTH_FOR_ONE_PROCESS; i++) {
-      mappedByteBuffer.put(offset() + i, EMPTY);
-    }
-  }
+  boolean askedForStop();
 
-  public static int getMaxProcesses() {
-    return MAX_PROCESSES;
-  }
+  void endWatch();
 }
index 49f954a16ac96eabe67599c861fbdf7f5e418d81..19f361911cf5202b06b393efac38a3c5ec4721c0 100644 (file)
@@ -134,7 +134,7 @@ public class ProcessEntryPoint implements Stoppable {
 
   public static ProcessEntryPoint createForArguments(String[] args) {
     Props props = ConfigurationUtils.loadPropsFromCommandLineArgs(args);
-    ProcessCommands commands = new ProcessCommands(
+    ProcessCommands commands = new DefaultProcessCommands(
       props.nonNullValueAsFile(PROPERTY_SHARED_PATH), Integer.parseInt(props.nonNullValue(PROPERTY_PROCESS_INDEX)));
     return new ProcessEntryPoint(props, new SystemExit(), commands);
   }
diff --git a/server/sonar-process/src/test/java/org/sonar/process/DefaultProcessCommandsTest.java b/server/sonar-process/src/test/java/org/sonar/process/DefaultProcessCommandsTest.java
new file mode 100644 (file)
index 0000000..16bc7e5
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+package org.sonar.process;
+
+import java.io.File;
+import org.apache.commons.io.FileUtils;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;
+import static org.junit.Assert.fail;
+
+public class DefaultProcessCommandsTest {
+
+  @Rule
+  public TemporaryFolder temp = new TemporaryFolder();
+
+  @Test
+  public void fail_to_init_if_dir_does_not_exist() throws Exception {
+    File dir = temp.newFolder();
+    FileUtils.deleteQuietly(dir);
+
+    try {
+      new DefaultProcessCommands(dir, 1);
+      fail();
+    } catch (IllegalArgumentException e) {
+      assertThat(e).hasMessage("Not a valid directory: " + dir.getAbsolutePath());
+    }
+  }
+
+  @Test
+  public void child_process_update_the_mapped_memory() throws Exception {
+    File dir = temp.newFolder();
+
+    DefaultProcessCommands commands = new DefaultProcessCommands(dir, 1);
+    assertThat(commands.isReady()).isFalse();
+    assertThat(commands.mappedByteBuffer.get(commands.offset())).isEqualTo(DefaultProcessCommands.EMPTY);
+    assertThat(commands.mappedByteBuffer.getLong(2 + commands.offset())).isEqualTo(0L);
+
+    commands.setReady();
+    assertThat(commands.isReady()).isTrue();
+    assertThat(commands.mappedByteBuffer.get(commands.offset())).isEqualTo(DefaultProcessCommands.READY);
+
+    long currentTime = System.currentTimeMillis();
+    commands.ping();
+    assertThat(commands.mappedByteBuffer.getLong(2 + commands.offset())).isGreaterThanOrEqualTo(currentTime);
+  }
+
+  @Test
+  public void ask_for_stop() throws Exception {
+    File dir = temp.newFolder();
+
+    DefaultProcessCommands commands = new DefaultProcessCommands(dir, 1);
+    assertThat(commands.mappedByteBuffer.get(commands.offset() + 1)).isNotEqualTo(DefaultProcessCommands.STOP);
+    assertThat(commands.askedForStop()).isFalse();
+
+    commands.askForStop();
+    assertThat(commands.askedForStop()).isTrue();
+    assertThat(commands.mappedByteBuffer.get(commands.offset() + 1)).isEqualTo(DefaultProcessCommands.STOP);
+  }
+
+  @Test
+  public void test_max_processes() throws Exception {
+    File dir = temp.newFolder();
+    try {
+      new DefaultProcessCommands(dir, -2);
+      failBecauseExceptionWasNotThrown(AssertionError.class);
+    } catch (AssertionError e) {
+      assertThat(e).hasMessage("Incorrect process number");
+    }
+    try {
+      new DefaultProcessCommands(dir, ProcessCommands.MAX_PROCESSES + 1);
+      failBecauseExceptionWasNotThrown(AssertionError.class);
+    } catch (AssertionError e) {
+      assertThat(e).hasMessage("Incorrect process number");
+    }
+  }
+}
diff --git a/server/sonar-process/src/test/java/org/sonar/process/ProcessCommandsTest.java b/server/sonar-process/src/test/java/org/sonar/process/ProcessCommandsTest.java
deleted file mode 100644 (file)
index aba88fe..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.process;
-
-import org.apache.commons.io.FileUtils;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-
-import java.io.File;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;
-import static org.junit.Assert.fail;
-
-public class ProcessCommandsTest {
-
-  @Rule
-  public TemporaryFolder temp = new TemporaryFolder();
-
-  @Test
-  public void fail_to_init_if_dir_does_not_exist() throws Exception {
-    File dir = temp.newFolder();
-    FileUtils.deleteQuietly(dir);
-
-    try {
-      new ProcessCommands(dir, 1);
-      fail();
-    } catch (IllegalArgumentException e) {
-      assertThat(e).hasMessage("Not a valid directory: " + dir.getAbsolutePath());
-    }
-  }
-
-  @Test
-  public void child_process_update_the_mapped_memory() throws Exception {
-    File dir = temp.newFolder();
-
-    ProcessCommands commands = new ProcessCommands(dir, 1);
-    assertThat(commands.isReady()).isFalse();
-    assertThat(commands.mappedByteBuffer.get(commands.offset())).isEqualTo(ProcessCommands.EMPTY);
-    assertThat(commands.mappedByteBuffer.getLong(2 + commands.offset())).isEqualTo(0L);
-
-    commands.setReady();
-    assertThat(commands.isReady()).isTrue();
-    assertThat(commands.mappedByteBuffer.get(commands.offset())).isEqualTo(ProcessCommands.READY);
-
-    long currentTime = System.currentTimeMillis();
-    commands.ping();
-    assertThat(commands.mappedByteBuffer.getLong(2 + commands.offset())).isGreaterThanOrEqualTo(currentTime);
-  }
-
-  @Test
-  public void ask_for_stop() throws Exception {
-    File dir = temp.newFolder();
-
-    ProcessCommands commands = new ProcessCommands(dir, 1);
-    assertThat(commands.mappedByteBuffer.get(commands.offset() + 1)).isNotEqualTo(ProcessCommands.STOP);
-    assertThat(commands.askedForStop()).isFalse();
-
-    commands.askForStop();
-    assertThat(commands.askedForStop()).isTrue();
-    assertThat(commands.mappedByteBuffer.get(commands.offset() + 1)).isEqualTo(ProcessCommands.STOP);
-  }
-
-  @Test
-  public void test_max_processes() throws Exception {
-    File dir = temp.newFolder();
-    try {
-      new ProcessCommands(dir, -2);
-      failBecauseExceptionWasNotThrown(AssertionError.class);
-    } catch (AssertionError e) {
-      assertThat(e).hasMessage("Incorrect process number");
-    }
-    try {
-      new ProcessCommands(dir, ProcessCommands.getMaxProcesses() + 1);
-      failBecauseExceptionWasNotThrown(AssertionError.class);
-    } catch (AssertionError e) {
-      assertThat(e).hasMessage("Incorrect process number");
-    }
-  }
-}
index ac045982ef77dbbc846a11cf74a64d7ce2bb7689..e78d1c17b3eb961b4a6e847f8e7371582510031c 100644 (file)
  */
 package org.sonar.process;
 
+import java.util.concurrent.TimeUnit;
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.Timeout;
 
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 public class StopWatcherTest {
 
-  @Test(timeout = 1000L)
+  @Rule
+  public Timeout timeout = new Timeout(1000, TimeUnit.MILLISECONDS);
+
+  @Test
   public void stop_if_receive_command() throws InterruptedException {
     ProcessCommands commands = mock(ProcessCommands.class);
-    when(commands.askedForStop()).thenReturn(false).thenReturn(true);
+    when(commands.askedForStop()).thenReturn(falsetrue);
     Stoppable stoppable = mock(Stoppable.class);
 
     StopWatcher watcher = new StopWatcher(commands, stoppable, 1L);
@@ -38,7 +47,7 @@ public class StopWatcherTest {
     verify(stoppable).stopAsync();
   }
 
-  @Test(timeout = 1000L)
+  @Test
   public void stop_watching_on_interruption() throws InterruptedException {
     ProcessCommands commands = mock(ProcessCommands.class);
     when(commands.askedForStop()).thenReturn(false);
index 26130401dac1686521dadeac76da5c0cf3c56bc4..9547d50589515917715e52307a043847abb4121e 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.application;
 
 import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.lang.StringUtils;
+import org.sonar.process.DefaultProcessCommands;
 import org.sonar.process.MinimumViableSystem;
 import org.sonar.process.ProcessCommands;
 import org.sonar.process.ProcessProperties;
@@ -54,7 +55,7 @@ public class App implements Stoppable {
   public void start(Props props) {
     if (props.valueAsBoolean(ProcessProperties.ENABLE_STOP_COMMAND, false)) {
       File tempDir = props.nonNullValueAsFile(ProcessProperties.PATH_TEMP);
-      ProcessCommands commands = new ProcessCommands(tempDir, 0);
+      ProcessCommands commands = new DefaultProcessCommands(tempDir, 0);
       stopWatcher = new StopWatcher(commands, this);
       stopWatcher.start();
     }