2 * Copyright 2000-2018 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package jetbrains.buildServer.buildTriggers.vcs.git.tests;
19 import com.sun.net.httpserver.HttpsServer;
20 import jetbrains.buildServer.TempFiles;
21 import jetbrains.buildServer.buildTriggers.vcs.git.agent.*;
22 import jetbrains.buildServer.buildTriggers.vcs.git.agent.command.GetConfigCommand;
23 import jetbrains.buildServer.buildTriggers.vcs.git.agent.command.SetConfigCommand;
24 import jetbrains.buildServer.buildTriggers.vcs.git.agent.ssl.SSLInvestigator;
25 import jetbrains.buildServer.serverSide.BasePropertiesModel;
26 import jetbrains.buildServer.serverSide.TeamCityProperties;
27 import org.eclipse.jgit.transport.URIish;
28 import org.jmock.Expectations;
29 import org.jmock.Mockery;
30 import org.jmock.lib.legacy.ClassImposteriser;
31 import org.testng.annotations.*;
35 import java.util.Collections;
36 import java.util.Optional;
38 import static org.testng.Assert.*;
41 * Unit tests for {@link SSLInvestigator}.
43 * @author Mikhail Khorkov
47 public class SSLInvestigatorTest {
49 private TempFiles myTempFiles = new TempFiles();
50 private File myHomeDirectory;
51 private File myTempDirectory;
52 private Mockery myMockery;
53 private LoggingGitMetaFactory myLoggingFactory;
55 private HttpsServer myServer;
56 private SSLTestUtil mySSLTestUtil;
57 private int myServerPort;
59 private enum Plot {FEATURE_OFF, GOOD_CERT, BAD_CERT, NO_CERT}
61 private enum Result {ONLY_GET, ONLY_SET, GET_AND_SET, GET_AND_UNSET}
64 public void init() throws Exception {
65 mySSLTestUtil = new SSLTestUtil();
66 myServer = mySSLTestUtil.getHttpsServer();
67 myServerPort = mySSLTestUtil.getServerPort();
77 public void setUp() throws Exception {
78 myHomeDirectory = myTempFiles.createTempDir();
79 myTempDirectory = myTempFiles.createTempDir();
81 new TeamCityProperties() {{
82 setModel(new BasePropertiesModel() {
86 myMockery = new Mockery() {{
87 setImposteriser(ClassImposteriser.INSTANCE);
89 myLoggingFactory = new LoggingGitMetaFactory();
93 public void tearDown() {
94 myTempFiles.cleanup();
97 @DataProvider(name = "invariants")
98 public static Object[][] invariants() {
99 return new Object[][] {
100 /* plot of prerequisites | custom flag is set already | expected result */
101 new Object[]{Plot.FEATURE_OFF, false, Result.ONLY_GET},
102 new Object[]{Plot.FEATURE_OFF, true, Result.GET_AND_UNSET},
104 new Object[]{Plot.BAD_CERT, false, Result.ONLY_GET},
105 new Object[]{Plot.BAD_CERT, true, Result.GET_AND_UNSET},
107 new Object[]{Plot.NO_CERT, false, Result.ONLY_GET},
108 new Object[]{Plot.NO_CERT, true, Result.GET_AND_UNSET},
110 new Object[]{Plot.GOOD_CERT, false, Result.ONLY_SET},
111 new Object[]{Plot.GOOD_CERT, true, Result.ONLY_SET},
115 @Test(dataProvider = "invariants")
116 public void allTest(Plot plot, boolean alreadySet, Result result) throws Exception {
119 System.setProperty("teamcity.ssl.useCustomTrustStore.git", "false");
123 System.setProperty("teamcity.ssl.useCustomTrustStore.git", "true");
127 System.setProperty("teamcity.ssl.useCustomTrustStore.git", "true");
128 myTempFiles.registerAsTempFile(mySSLTestUtil.writeAnotherCert(myHomeDirectory));
132 System.setProperty("teamcity.ssl.useCustomTrustStore.git", "true");
133 myTempFiles.registerAsTempFile(mySSLTestUtil.writeServerCert(myHomeDirectory));
138 final String alreadyInProperties = alreadySet ? "something" : "";
139 final GitCommandProxyCallback gitCommandProxyCallback = (method, args) -> Optional.of(alreadyInProperties);
140 myLoggingFactory.addCallback(GetConfigCommand.class.getName() + ".call", gitCommandProxyCallback);
141 myLoggingFactory.addCallback(GetConfigCommand.class.getName() + ".callWithIgnoreExitCode", gitCommandProxyCallback);
142 myLoggingFactory.addCallback(SetConfigCommand.class.getName() + ".call", (method, args) -> Optional.empty());
144 final SSLInvestigator instance = createInstance();
146 instance.setCertificateOptions(createFactory().create(myTempDirectory));
150 assertEquals(myLoggingFactory.getNumberOfCalls(GetConfigCommand.class), 1);
151 assertEquals(myLoggingFactory.getNumberOfCalls(SetConfigCommand.class), 0);
155 assertEquals(myLoggingFactory.getNumberOfCalls(GetConfigCommand.class), 0);
156 assertEquals(myLoggingFactory.getNumberOfCalls(SetConfigCommand.class), 1);
157 assertFalse(myLoggingFactory.getInvokedMethods(SetConfigCommand.class).contains("unSet"));
161 assertEquals(myLoggingFactory.getNumberOfCalls(GetConfigCommand.class), 1);
162 assertEquals(myLoggingFactory.getNumberOfCalls(SetConfigCommand.class), 1);
163 assertFalse(myLoggingFactory.getInvokedMethods(SetConfigCommand.class).contains("unSet"));
166 case GET_AND_UNSET: {
167 assertEquals(myLoggingFactory.getNumberOfCalls(GetConfigCommand.class), 1);
168 assertEquals(myLoggingFactory.getNumberOfCalls(SetConfigCommand.class), 1);
169 assertTrue(myLoggingFactory.getInvokedMethods(SetConfigCommand.class).contains("unSet"));
175 private SSLInvestigator createInstance() throws Exception {
176 return new SSLInvestigator(new URIish(new URL("https://localhost:" + myServerPort)), myTempDirectory.getPath(), myHomeDirectory.getPath());
179 private GitFactory createFactory() throws Exception {
180 final GitAgentSSHService ssh = myMockery.mock(GitAgentSSHService.class);
181 final AgentPluginConfig pluginConfig = myMockery.mock(AgentPluginConfig.class);
182 final Context context = myMockery.mock(Context.class);
183 myMockery.checking(new Expectations() {{
184 atLeast(1).of(pluginConfig).getPathToGit();
185 will(returnValue("git"));
186 atLeast(1).of(pluginConfig).getGitVersion();
187 will(returnValue(GitVersion.MIN));
188 atLeast(1).of(pluginConfig).isDeleteTempFiles();
189 will(returnValue(false));
190 atLeast(1).of(pluginConfig).getGitExec();
191 will(returnValue(myMockery.mock(GitExec.class)));
193 final GitProgressLogger logger = myMockery.mock(GitProgressLogger.class);
194 return myLoggingFactory.createFactory(ssh, pluginConfig, logger, myTempFiles.createTempDir(), Collections.emptyMap(), context);