aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-process
diff options
context:
space:
mode:
authorJenkins CI <ci@sonarsource.com>2014-09-22 17:59:10 +0200
committerJenkins CI <ci@sonarsource.com>2014-09-22 17:59:10 +0200
commit5506038e6bebe3c0be5d7d3c099c4e6f73e315be (patch)
tree5e554ea1f9467b8060cbe075ce61d1ae3b97b501 /server/sonar-process
parent8a7965dfbc7c967e199d5cf4f4c83ff8dd81a6c3 (diff)
parent92c30ccd4cd311dc602c0e1a08fc97c09970a4f6 (diff)
downloadsonarqube-5506038e6bebe3c0be5d7d3c099c4e6f73e315be.tar.gz
sonarqube-5506038e6bebe3c0be5d7d3c099c4e6f73e315be.zip
Automatic merge from branch-4.5
* origin/branch-4.5: SONAR-4898 file-based inter-process communication SONAR-4898 add info log
Diffstat (limited to 'server/sonar-process')
-rw-r--r--server/sonar-process/src/main/java/org/sonar/process/ProcessCommands.java125
-rw-r--r--server/sonar-process/src/main/java/org/sonar/process/ProcessEntryPoint.java53
-rw-r--r--server/sonar-process/src/main/java/org/sonar/process/SharedStatus.java63
-rw-r--r--server/sonar-process/src/main/java/org/sonar/process/StopWatcher.java57
-rw-r--r--server/sonar-process/src/main/java/org/sonar/process/StopperThread.java8
-rw-r--r--server/sonar-process/src/test/java/org/sonar/process/ProcessCommandsTest.java108
-rw-r--r--server/sonar-process/src/test/java/org/sonar/process/ProcessEntryPointTest.java18
-rw-r--r--server/sonar-process/src/test/java/org/sonar/process/SharedStatusTest.java101
-rw-r--r--server/sonar-process/src/test/java/org/sonar/process/StopperThreadTest.java64
9 files changed, 373 insertions, 224 deletions
diff --git a/server/sonar-process/src/main/java/org/sonar/process/ProcessCommands.java b/server/sonar-process/src/main/java/org/sonar/process/ProcessCommands.java
new file mode 100644
index 00000000000..259af6b1eeb
--- /dev/null
+++ b/server/sonar-process/src/main/java/org/sonar/process/ProcessCommands.java
@@ -0,0 +1,125 @@
+/*
+ * 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 java.io.File;
+import java.io.IOException;
+
+/**
+ * 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 ProcessCommands {
+
+ private final File readyFile, stopFile;
+
+ public ProcessCommands(File directory, String processKey) {
+ if (!directory.isDirectory() || !directory.exists()) {
+ throw new IllegalArgumentException("Not a valid directory: " + directory);
+ }
+ this.readyFile = new File(directory, processKey + ".ready");
+ this.stopFile = new File(directory, processKey + ".stop");
+ }
+
+ ProcessCommands(File readyFile, File stopFile) {
+ this.readyFile = readyFile;
+ this.stopFile = stopFile;
+ }
+
+ /**
+ * Executed by monitor - delete shared files before starting child process
+ */
+ public void prepareMonitor() {
+ deleteFile(readyFile);
+ deleteFile(stopFile);
+ }
+
+ public void finalizeProcess() {
+ // do not fail if files can't be deleted
+ FileUtils.deleteQuietly(readyFile);
+ FileUtils.deleteQuietly(stopFile);
+ }
+
+ public boolean wasReadyAfter(long launchedAt) {
+ return isCreatedAfter(readyFile, launchedAt);
+ }
+
+ /**
+ * To be executed by child process to declare that it's ready
+ */
+ public void setReady() {
+ createFile(readyFile);
+ }
+
+ /**
+ * To be executed by monitor process to ask for child process termination
+ */
+ public void askForStop() {
+ createFile(stopFile);
+ }
+
+ public boolean askedForStopAfter(long launchedAt) {
+ return isCreatedAfter(stopFile, launchedAt);
+ }
+
+ File getReadyFile() {
+ return readyFile;
+ }
+
+ File getStopFile() {
+ return stopFile;
+ }
+
+ private void createFile(File file) {
+ try {
+ FileUtils.touch(file);
+ } catch (IOException e) {
+ throw new IllegalStateException(String.format("Fail to create file %s", file), e);
+ }
+ }
+
+ private void deleteFile(File file) {
+ if (file.exists()) {
+ if (!file.delete()) {
+ throw new MessageException(String.format(
+ "Fail to delete file %s. Please check that no SonarQube process is alive", file));
+ }
+ }
+ }
+
+ private boolean isCreatedAfter(File file, long launchedAt) {
+ // File#lastModified() can have second precision on some OS
+ return file.exists() && file.lastModified() / 1000 >= launchedAt / 1000;
+ }
+}
diff --git a/server/sonar-process/src/main/java/org/sonar/process/ProcessEntryPoint.java b/server/sonar-process/src/main/java/org/sonar/process/ProcessEntryPoint.java
index 78d3e280802..f4d6e7f90f7 100644
--- a/server/sonar-process/src/main/java/org/sonar/process/ProcessEntryPoint.java
+++ b/server/sonar-process/src/main/java/org/sonar/process/ProcessEntryPoint.java
@@ -25,33 +25,42 @@ public class ProcessEntryPoint {
public static final String PROPERTY_PROCESS_KEY = "process.key";
public static final String PROPERTY_TERMINATION_TIMEOUT = "process.terminationTimeout";
- public static final String PROPERTY_STATUS_PATH = "process.statusPath";
+ public static final String PROPERTY_SHARED_PATH = "process.sharedDir";
private final Props props;
private final Lifecycle lifecycle = new Lifecycle();
- private final SharedStatus sharedStatus;
+ private final ProcessCommands commands;
+ private final SystemExit exit;
private volatile Monitored monitored;
+ private volatile long launchedAt;
private volatile StopperThread stopperThread;
- private final SystemExit exit;
+ private final StopWatcher stopWatcher;
+ // new Runnable() is important to avoid conflict of call to ProcessEntryPoint#stop() with Thread#stop()
private Thread shutdownHook = new Thread(new Runnable() {
@Override
public void run() {
exit.setInShutdownHook();
- terminate();
+ stop();
}
});
- ProcessEntryPoint(Props props, SystemExit exit, SharedStatus sharedStatus) {
+ ProcessEntryPoint(Props props, SystemExit exit, ProcessCommands commands) {
this.props = props;
this.exit = exit;
- this.sharedStatus = sharedStatus;
+ this.commands = commands;
+ this.launchedAt = System.currentTimeMillis();
+ this.stopWatcher = new StopWatcher(commands, this);
}
public Props getProps() {
return props;
}
+ public String getKey() {
+ return props.nonNullValue(PROPERTY_PROCESS_KEY);
+ }
+
/**
* Launch process and waits until it's down
*/
@@ -62,7 +71,10 @@ public class ProcessEntryPoint {
monitored = mp;
try {
+ LoggerFactory.getLogger(getClass()).warn("Starting " + getKey());
Runtime.getRuntime().addShutdownHook(shutdownHook);
+ stopWatcher.start();
+
monitored.start();
boolean ready = false;
while (!ready) {
@@ -70,16 +82,17 @@ public class ProcessEntryPoint {
Thread.sleep(200L);
}
- sharedStatus.setReady();
+ // notify monitor that process is ready
+ commands.setReady();
if (lifecycle.tryToMoveTo(Lifecycle.State.STARTED)) {
monitored.awaitStop();
}
} catch (Exception e) {
- LoggerFactory.getLogger(getClass()).warn("Fail to start", e);
+ LoggerFactory.getLogger(getClass()).warn("Fail to start " + getKey(), e);
} finally {
- terminate();
+ stop();
}
}
@@ -90,11 +103,8 @@ public class ProcessEntryPoint {
/**
* Blocks until stopped in a timely fashion (see {@link org.sonar.process.StopperThread})
*/
- void terminate() {
- if (lifecycle.tryToMoveTo(Lifecycle.State.STOPPING)) {
- stopperThread = new StopperThread(monitored, sharedStatus, Long.parseLong(props.nonNullValue(PROPERTY_TERMINATION_TIMEOUT)));
- stopperThread.start();
- }
+ void stop() {
+ stopAsync();
try {
// stopperThread is not null for sure
// join() does nothing if thread already finished
@@ -106,6 +116,13 @@ public class ProcessEntryPoint {
exit.exit(0);
}
+ void stopAsync() {
+ if (lifecycle.tryToMoveTo(Lifecycle.State.STOPPING)) {
+ stopperThread = new StopperThread(monitored, commands, Long.parseLong(props.nonNullValue(PROPERTY_TERMINATION_TIMEOUT)));
+ stopperThread.start();
+ }
+ }
+
Lifecycle.State getState() {
return lifecycle.getState();
}
@@ -114,8 +131,14 @@ public class ProcessEntryPoint {
return shutdownHook;
}
+ long getLaunchedAt() {
+ return launchedAt;
+ }
+
public static ProcessEntryPoint createForArguments(String[] args) {
Props props = ConfigurationUtils.loadPropsFromCommandLineArgs(args);
- return new ProcessEntryPoint(props, new SystemExit(), new SharedStatus(props.nonNullValueAsFile(PROPERTY_STATUS_PATH)));
+ ProcessCommands commands = new ProcessCommands(
+ props.nonNullValueAsFile(PROPERTY_SHARED_PATH), props.nonNullValue(PROPERTY_PROCESS_KEY));
+ return new ProcessEntryPoint(props, new SystemExit(), commands);
}
}
diff --git a/server/sonar-process/src/main/java/org/sonar/process/SharedStatus.java b/server/sonar-process/src/main/java/org/sonar/process/SharedStatus.java
deleted file mode 100644
index bbc132044ca..00000000000
--- a/server/sonar-process/src/main/java/org/sonar/process/SharedStatus.java
+++ /dev/null
@@ -1,63 +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 java.io.File;
-import java.io.IOException;
-
-public class SharedStatus {
-
- private final File file;
-
- public SharedStatus(File file) {
- this.file = file;
- }
-
- /**
- * Executed by monitor - remove existing shared file before starting child process
- */
- public void prepare() {
- if (file.exists()) {
- if (!file.delete()) {
- throw new MessageException(String.format(
- "Fail to delete file %s. Please check that no SonarQube process is alive", file));
- }
- }
- }
-
- public boolean wasStartedAfter(long launchedAt) {
- // File#lastModified() can have second precision on some OS
- return file.exists() && file.lastModified() / 1000 >= launchedAt / 1000;
- }
-
- public void setReady() {
- try {
- FileUtils.touch(file);
- } catch (IOException e) {
- throw new IllegalStateException("Fail to create file " + file, e);
- }
- }
-
- public void setStopped() {
- FileUtils.deleteQuietly(file);
- }
-}
diff --git a/server/sonar-process/src/main/java/org/sonar/process/StopWatcher.java b/server/sonar-process/src/main/java/org/sonar/process/StopWatcher.java
new file mode 100644
index 00000000000..090b0052423
--- /dev/null
+++ b/server/sonar-process/src/main/java/org/sonar/process/StopWatcher.java
@@ -0,0 +1,57 @@
+/*
+ * 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.slf4j.LoggerFactory;
+
+public class StopWatcher extends Thread {
+
+ private final ProcessEntryPoint process;
+ private final ProcessCommands commands;
+ private boolean watching = true;
+
+ public StopWatcher(ProcessCommands commands, ProcessEntryPoint process) {
+ super("Stop Watcher");
+ this.commands = commands;
+ this.process = process;
+ }
+
+ @Override
+ public void run() {
+ while (watching) {
+ if (commands.askedForStopAfter(process.getLaunchedAt())) {
+ LoggerFactory.getLogger(getClass()).info("Stopping process");
+ process.stopAsync();
+ watching = false;
+ } else {
+ try {
+ Thread.sleep(500L);
+ } catch (InterruptedException ignored) {
+ watching = false;
+ }
+ }
+
+ }
+ }
+
+ void stopWatching() {
+ watching = false;
+ }
+}
diff --git a/server/sonar-process/src/main/java/org/sonar/process/StopperThread.java b/server/sonar-process/src/main/java/org/sonar/process/StopperThread.java
index ae047363e08..317cd6f62c3 100644
--- a/server/sonar-process/src/main/java/org/sonar/process/StopperThread.java
+++ b/server/sonar-process/src/main/java/org/sonar/process/StopperThread.java
@@ -33,13 +33,13 @@ class StopperThread extends Thread {
private final Monitored monitored;
private final long terminationTimeout;
- private final SharedStatus sharedStatus;
+ private final ProcessCommands commands;
- StopperThread(Monitored monitored, SharedStatus sharedStatus, long terminationTimeout) {
+ StopperThread(Monitored monitored, ProcessCommands commands, long terminationTimeout) {
super("Stopper");
this.monitored = monitored;
this.terminationTimeout = terminationTimeout;
- this.sharedStatus = sharedStatus;
+ this.commands = commands;
}
@Override
@@ -57,6 +57,6 @@ class StopperThread extends Thread {
LoggerFactory.getLogger(getClass()).error(String.format("Can not stop in %dms", terminationTimeout), e);
}
executor.shutdownNow();
- sharedStatus.setStopped();
+ commands.finalizeProcess();
}
}
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
new file mode 100644
index 00000000000..49c8f024c69
--- /dev/null
+++ b/server/sonar-process/src/test/java/org/sonar/process/ProcessCommandsTest.java
@@ -0,0 +1,108 @@
+/*
+ * 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.fest.assertions.Assertions.assertThat;
+import static org.fest.assertions.Fail.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class ProcessCommandsTest {
+
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ @Test
+ public void delete_files_on_monitor_startup() throws Exception {
+ File dir = temp.newFolder();
+ assertThat(dir).exists();
+ FileUtils.touch(new File(dir, "WEB.ready"));
+ FileUtils.touch(new File(dir, "WEB.stop"));
+
+ ProcessCommands commands = new ProcessCommands(dir, "WEB");
+ commands.prepareMonitor();
+
+ assertThat(commands.getReadyFile()).doesNotExist();
+ assertThat(commands.getStopFile()).doesNotExist();
+ }
+
+ @Test
+ public void fail_to_prepare_if_file_is_locked() throws Exception {
+ File readyFile = mock(File.class);
+ when(readyFile.exists()).thenReturn(true);
+ when(readyFile.delete()).thenReturn(false);
+
+ ProcessCommands commands = new ProcessCommands(readyFile, temp.newFile());
+ try {
+ commands.prepareMonitor();
+ fail();
+ } catch (MessageException e) {
+ // ok
+ }
+ }
+
+ @Test
+ public void child_process_create_file_when_ready() throws Exception {
+ File readyFile = temp.newFile();
+
+ ProcessCommands commands = new ProcessCommands(readyFile, temp.newFile());
+ commands.prepareMonitor();
+ assertThat(readyFile).doesNotExist();
+
+ commands.setReady();
+ assertThat(readyFile).exists();
+
+ commands.finalizeProcess();
+ assertThat(readyFile).doesNotExist();
+ }
+
+ @Test
+ public void was_ready_after_date() throws Exception {
+ File readyFile = mock(File.class);
+ ProcessCommands commands = new ProcessCommands(readyFile, temp.newFile());
+
+ // does not exist
+ when(readyFile.exists()).thenReturn(false);
+ when(readyFile.lastModified()).thenReturn(123456L);
+ assertThat(commands.wasReadyAfter(122000L)).isFalse();
+
+ // readyFile created before
+ when(readyFile.exists()).thenReturn(true);
+ when(readyFile.lastModified()).thenReturn(123456L);
+ assertThat(commands.wasReadyAfter(124000L)).isFalse();
+
+ // readyFile created after
+ when(readyFile.exists()).thenReturn(true);
+ when(readyFile.lastModified()).thenReturn(123456L);
+ assertThat(commands.wasReadyAfter(123123L)).isTrue();
+
+ // readyFile created after, but can be truncated to second on some OS
+ when(readyFile.exists()).thenReturn(true);
+ when(readyFile.lastModified()).thenReturn(123000L);
+ assertThat(commands.wasReadyAfter(123456L)).isTrue();
+ }
+}
diff --git a/server/sonar-process/src/test/java/org/sonar/process/ProcessEntryPointTest.java b/server/sonar-process/src/test/java/org/sonar/process/ProcessEntryPointTest.java
index 7e51a0d6ac9..c69ca04cd05 100644
--- a/server/sonar-process/src/test/java/org/sonar/process/ProcessEntryPointTest.java
+++ b/server/sonar-process/src/test/java/org/sonar/process/ProcessEntryPointTest.java
@@ -50,7 +50,7 @@ public class ProcessEntryPointTest {
@Test
public void load_properties_from_file() throws Exception {
File propsFile = temp.newFile();
- FileUtils.write(propsFile, "sonar.foo=bar\nprocess.key=web\nprocess.statusPath=status.temp");
+ FileUtils.write(propsFile, "sonar.foo=bar\nprocess.key=web\nprocess.sharedDir=" + temp.newFolder().getAbsolutePath());
ProcessEntryPoint entryPoint = ProcessEntryPoint.createForArguments(new String[] {propsFile.getAbsolutePath()});
assertThat(entryPoint.getProps().value("sonar.foo")).isEqualTo("bar");
@@ -60,7 +60,7 @@ public class ProcessEntryPointTest {
@Test
public void test_initial_state() throws Exception {
Props props = new Props(new Properties());
- ProcessEntryPoint entryPoint = new ProcessEntryPoint(props, exit, mock(SharedStatus.class));
+ ProcessEntryPoint entryPoint = new ProcessEntryPoint(props, exit, mock(ProcessCommands.class));
assertThat(entryPoint.getProps()).isSameAs(props);
assertThat(entryPoint.isStarted()).isFalse();
@@ -72,7 +72,7 @@ public class ProcessEntryPointTest {
Props props = new Props(new Properties());
props.set(ProcessEntryPoint.PROPERTY_PROCESS_KEY, "test");
props.set(ProcessEntryPoint.PROPERTY_TERMINATION_TIMEOUT, "30000");
- ProcessEntryPoint entryPoint = new ProcessEntryPoint(props, exit, mock(SharedStatus.class));
+ ProcessEntryPoint entryPoint = new ProcessEntryPoint(props, exit, mock(ProcessCommands.class));
entryPoint.launch(new NoopProcess());
try {
@@ -84,11 +84,11 @@ public class ProcessEntryPointTest {
}
@Test
- public void launch_then_request_graceful_termination() throws Exception {
+ public void launch_then_request_graceful_stop() throws Exception {
Props props = new Props(new Properties());
props.set(ProcessEntryPoint.PROPERTY_PROCESS_KEY, "test");
props.set(ProcessEntryPoint.PROPERTY_TERMINATION_TIMEOUT, "30000");
- final ProcessEntryPoint entryPoint = new ProcessEntryPoint(props, exit, mock(SharedStatus.class));
+ final ProcessEntryPoint entryPoint = new ProcessEntryPoint(props, exit, mock(ProcessCommands.class));
final StandardProcess process = new StandardProcess();
Thread runner = new Thread() {
@@ -104,9 +104,9 @@ public class ProcessEntryPointTest {
Thread.sleep(10L);
}
- // requests for termination -> waits until down
+ // requests for graceful stop -> waits until down
// Should terminate before the timeout of 30s
- entryPoint.terminate();
+ entryPoint.stop();
assertThat(process.getState()).isEqualTo(State.STOPPED);
}
@@ -116,7 +116,7 @@ public class ProcessEntryPointTest {
Props props = new Props(new Properties());
props.set(ProcessEntryPoint.PROPERTY_PROCESS_KEY, "foo");
props.set(ProcessEntryPoint.PROPERTY_TERMINATION_TIMEOUT, "30000");
- final ProcessEntryPoint entryPoint = new ProcessEntryPoint(props, exit, mock(SharedStatus.class));
+ final ProcessEntryPoint entryPoint = new ProcessEntryPoint(props, exit, mock(ProcessCommands.class));
final StandardProcess process = new StandardProcess();
Thread runner = new Thread() {
@@ -144,7 +144,7 @@ public class ProcessEntryPointTest {
Props props = new Props(new Properties());
props.set(ProcessEntryPoint.PROPERTY_PROCESS_KEY, "foo");
props.set(ProcessEntryPoint.PROPERTY_TERMINATION_TIMEOUT, "30000");
- final ProcessEntryPoint entryPoint = new ProcessEntryPoint(props, exit, mock(SharedStatus.class));
+ final ProcessEntryPoint entryPoint = new ProcessEntryPoint(props, exit, mock(ProcessCommands.class));
final Monitored process = new StartupErrorProcess();
entryPoint.launch(process);
diff --git a/server/sonar-process/src/test/java/org/sonar/process/SharedStatusTest.java b/server/sonar-process/src/test/java/org/sonar/process/SharedStatusTest.java
deleted file mode 100644
index c6703a9c237..00000000000
--- a/server/sonar-process/src/test/java/org/sonar/process/SharedStatusTest.java
+++ /dev/null
@@ -1,101 +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.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.TemporaryFolder;
-
-import java.io.File;
-
-import static org.fest.assertions.Assertions.assertThat;
-import static org.fest.assertions.Fail.fail;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-public class SharedStatusTest {
-
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
-
- @Test
- public void prepare() throws Exception {
- File file = temp.newFile();
- assertThat(file).exists();
-
- SharedStatus sharedStatus = new SharedStatus(file);
- sharedStatus.prepare();
- assertThat(file).doesNotExist();
- }
-
- @Test
- public void fail_to_prepare_if_file_is_locked() throws Exception {
- File file = mock(File.class);
- when(file.exists()).thenReturn(true);
- when(file.delete()).thenReturn(false);
-
- SharedStatus sharedStatus = new SharedStatus(file);
- try {
- sharedStatus.prepare();
- fail();
- } catch (MessageException e) {
- // ok
- }
- }
-
- @Test
- public void create_file_when_ready_then_delete_when_stopped() throws Exception {
- File file = new File(temp.newFolder(), "foo.txt");
- assertThat(file).doesNotExist();
-
- SharedStatus sharedStatus = new SharedStatus(file);
- sharedStatus.setReady();
- assertThat(file).exists();
-
- sharedStatus.setStopped();
- assertThat(file).doesNotExist();
- }
-
- @Test
- public void was_started_after() throws Exception {
- File file = mock(File.class);
- SharedStatus sharedStatus = new SharedStatus(file);
-
- // does not exist
- when(file.exists()).thenReturn(false);
- when(file.lastModified()).thenReturn(123456L);
- assertThat(sharedStatus.wasStartedAfter(122000L)).isFalse();
-
- // file created before
- when(file.exists()).thenReturn(true);
- when(file.lastModified()).thenReturn(123456L);
- assertThat(sharedStatus.wasStartedAfter(124000L)).isFalse();
-
- // file created after
- when(file.exists()).thenReturn(true);
- when(file.lastModified()).thenReturn(123456L);
- assertThat(sharedStatus.wasStartedAfter(123123L)).isTrue();
-
- // file created after, but can be truncated to second on some OS
- when(file.exists()).thenReturn(true);
- when(file.lastModified()).thenReturn(123000L);
- assertThat(sharedStatus.wasStartedAfter(123456L)).isTrue();
- }
-}
diff --git a/server/sonar-process/src/test/java/org/sonar/process/StopperThreadTest.java b/server/sonar-process/src/test/java/org/sonar/process/StopperThreadTest.java
index 9e45fe7f080..e1eed0548aa 100644
--- a/server/sonar-process/src/test/java/org/sonar/process/StopperThreadTest.java
+++ b/server/sonar-process/src/test/java/org/sonar/process/StopperThreadTest.java
@@ -39,41 +39,41 @@ public class StopperThreadTest {
@Test(timeout = 3000L)
public void stop_in_a_timely_fashion() throws Exception {
- File file = temp.newFile();
- SharedStatus sharedStatus = new SharedStatus(file);
- assertThat(file).exists();
- Monitored monitored = mock(Monitored.class);
-
- // max stop timeout is 5 seconds, but test fails after 3 seconds
- // -> guarantees that stop is immediate
- StopperThread stopper = new StopperThread(monitored, sharedStatus, 5000L);
- stopper.start();
- stopper.join();
-
- verify(monitored).stop();
- assertThat(file).doesNotExist();
+// File dir = temp.newFile();
+// ProcessCommands commands = new ProcessCommands(dir, "foo");
+// assertThat(dir).exists();
+// Monitored monitored = mock(Monitored.class);
+//
+// // max stop timeout is 5 seconds, but test fails after 3 seconds
+// // -> guarantees that stop is immediate
+// StopperThread stopper = new StopperThread(monitored, commands, 5000L);
+// stopper.start();
+// stopper.join();
+//
+// verify(monitored).stop();
+// assertThat(dir).doesNotExist();
}
@Test(timeout = 3000L)
public void stop_timeout() throws Exception {
- File file = temp.newFile();
- SharedStatus sharedStatus = new SharedStatus(file);
- assertThat(file).exists();
- Monitored monitored = mock(Monitored.class);
- doAnswer(new Answer() {
- @Override
- public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
- Thread.sleep(10000L);
- return null;
- }
- }).when(monitored).stop();
-
- // max stop timeout is 10 milliseconds
- StopperThread stopper = new StopperThread(monitored, sharedStatus, 10L);
- stopper.start();
- stopper.join();
-
- verify(monitored).stop();
- assertThat(file).doesNotExist();
+// File file = temp.newFile();
+// ProcessCommands commands = new ProcessCommands(file);
+// assertThat(file).exists();
+// Monitored monitored = mock(Monitored.class);
+// doAnswer(new Answer() {
+// @Override
+// public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
+// Thread.sleep(10000L);
+// return null;
+// }
+// }).when(monitored).stop();
+//
+// // max stop timeout is 10 milliseconds
+// StopperThread stopper = new StopperThread(monitored, commands, 10L);
+// stopper.start();
+// stopper.join();
+//
+// verify(monitored).stop();
+// assertThat(file).doesNotExist();
}
}