]> source.dussan.org Git - sonarqube.git/blob
3beb208ec25c808bb653f86d6f656355bfa99556
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2017 SonarSource SA
4  * mailto:info AT sonarsource DOT com
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 3 of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20 package org.sonar.application.process;
21
22 import java.io.File;
23 import java.io.FileReader;
24 import java.io.IOException;
25 import java.util.HashMap;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Properties;
29 import org.junit.Rule;
30 import org.junit.Test;
31 import org.junit.rules.ExpectedException;
32 import org.junit.rules.TemporaryFolder;
33 import org.sonar.application.process.JavaCommand;
34 import org.sonar.application.process.JavaProcessLauncher;
35 import org.sonar.application.process.JavaProcessLauncherImpl;
36 import org.sonar.application.process.ProcessMonitor;
37 import org.sonar.process.AllProcessesCommands;
38 import org.sonar.process.ProcessId;
39
40 import static org.assertj.core.api.Java6Assertions.assertThat;
41 import static org.assertj.core.data.MapEntry.entry;
42 import static org.mockito.Mockito.RETURNS_MOCKS;
43 import static org.mockito.Mockito.mock;
44 import static org.mockito.Mockito.when;
45
46 public class JavaProcessLauncherImplTest {
47
48   @Rule
49   public TemporaryFolder temp = new TemporaryFolder();
50   @Rule
51   public ExpectedException expectedException = ExpectedException.none();
52
53   private AllProcessesCommands commands = mock(AllProcessesCommands.class, RETURNS_MOCKS);
54
55   @Test
56   public void launch_forks_a_new_process() throws Exception {
57     File tempDir = temp.newFolder();
58     TestProcessBuilder processBuilder = new TestProcessBuilder();
59     JavaProcessLauncher underTest = new JavaProcessLauncherImpl(tempDir, commands, () -> processBuilder);
60     JavaCommand command = new JavaCommand(ProcessId.ELASTICSEARCH);
61     command.addClasspath("lib/*.class");
62     command.addClasspath("lib/*.jar");
63     command.setArgument("foo", "bar");
64     command.setClassName("org.sonarqube.Main");
65     command.setEnvVariable("VAR1", "valueOfVar1");
66     command.setWorkDir(temp.newFolder());
67
68     ProcessMonitor monitor = underTest.launch(command);
69
70     assertThat(monitor).isNotNull();
71     assertThat(processBuilder.started).isTrue();
72     assertThat(processBuilder.commands.get(0)).endsWith("java");
73     assertThat(processBuilder.commands).containsSequence(
74       "-Djava.io.tmpdir=" + tempDir.getAbsolutePath(),
75       "-cp",
76       "lib/*.class" + System.getProperty("path.separator") + "lib/*.jar",
77       "org.sonarqube.Main");
78     assertThat(processBuilder.dir).isEqualTo(command.getWorkDir());
79     assertThat(processBuilder.redirectErrorStream).isTrue();
80     assertThat(processBuilder.environment)
81       .contains(entry("VAR1", "valueOfVar1"))
82       .containsAllEntriesOf(command.getEnvVariables());
83   }
84
85   @Test
86   public void properties_are_passed_to_command_via_a_temporary_properties_file() throws Exception {
87     File tempDir = temp.newFolder();
88     TestProcessBuilder processBuilder = new TestProcessBuilder();
89     JavaProcessLauncher underTest = new JavaProcessLauncherImpl(tempDir, commands, () -> processBuilder);
90     JavaCommand command = new JavaCommand(ProcessId.ELASTICSEARCH);
91     command.setArgument("foo", "bar");
92     command.setArgument("baz", "woo");
93
94     underTest.launch(command);
95
96     String propsFilePath = processBuilder.commands.get(processBuilder.commands.size() - 1);
97     File file = new File(propsFilePath);
98     assertThat(file).exists().isFile();
99     try (FileReader reader = new FileReader(file)) {
100       Properties props = new Properties();
101       props.load(reader);
102       assertThat(props).containsOnly(
103         entry("foo", "bar"),
104         entry("baz", "woo"),
105         entry("process.terminationTimeout", "60000"),
106         entry("process.key", ProcessId.ELASTICSEARCH.getKey()),
107         entry("process.index", String.valueOf(ProcessId.ELASTICSEARCH.getIpcIndex())),
108         entry("process.sharedDir", tempDir.getAbsolutePath()));
109     }
110   }
111
112   @Test
113   public void throw_ISE_if_command_fails() throws IOException {
114     File tempDir = temp.newFolder();
115     JavaProcessLauncher.SystemProcessBuilder processBuilder = mock(JavaProcessLauncher.SystemProcessBuilder.class, RETURNS_MOCKS);
116     when(processBuilder.start()).thenThrow(new IOException("error"));
117     JavaProcessLauncher underTest = new JavaProcessLauncherImpl(tempDir, commands, () -> processBuilder);
118
119     expectedException.expect(IllegalStateException.class);
120     expectedException.expectMessage("Fail to launch process [es]");
121
122     underTest.launch(new JavaCommand(ProcessId.ELASTICSEARCH));
123   }
124
125   private static class TestProcessBuilder extends JavaProcessLauncher.SystemProcessBuilder {
126     private List<String> commands = null;
127     private File dir = null;
128     private Boolean redirectErrorStream = null;
129     private final Map<String, String> environment = new HashMap<>();
130     private boolean started = false;
131
132     @Override
133     public List<String> command() {
134       return commands;
135     }
136
137     @Override
138     public TestProcessBuilder command(List<String> commands) {
139       this.commands = commands;
140       return this;
141     }
142
143     @Override
144     public TestProcessBuilder directory(File dir) {
145       this.dir = dir;
146       return this;
147     }
148
149     @Override
150     public Map<String, String> environment() {
151       return environment;
152     }
153
154     @Override
155     public TestProcessBuilder redirectErrorStream(boolean b) {
156       this.redirectErrorStream = b;
157       return this;
158     }
159
160     @Override
161     public Process start() throws IOException {
162       this.started = true;
163       return mock(Process.class);
164     }
165   }
166 }