2626import com .cloudbees .jenkins .plugins .bitbucket .api .BitbucketApi ;
2727import com .cloudbees .jenkins .plugins .bitbucket .api .BitbucketHref ;
2828import com .cloudbees .jenkins .plugins .bitbucket .api .BitbucketRepository ;
29- import com .cloudbees .jenkins .plugins .bitbucket .endpoints .BitbucketCloudEndpoint ;
3029import com .cloudbees .jenkins .plugins .bitbucket .impl .extension .BitbucketEnvVarExtension ;
3130import com .cloudbees .jenkins .plugins .bitbucket .impl .extension .GitClientAuthenticatorExtension ;
3231import com .cloudbees .jenkins .plugins .bitbucket .server .client .BitbucketServerAPIClient ;
3837import com .cloudbees .plugins .credentials .common .StandardUsernameCredentials ;
3938import com .cloudbees .plugins .credentials .domains .Domain ;
4039import com .cloudbees .plugins .credentials .impl .UsernamePasswordCredentialsImpl ;
40+ import hudson .model .Item ;
41+ import hudson .model .Descriptor .FormException ;
4142import hudson .plugins .git .GitSCM ;
4243import hudson .plugins .git .UserRemoteConfig ;
4344import hudson .plugins .git .extensions .impl .BuildChooserSetting ;
4445import java .io .ByteArrayOutputStream ;
46+ import java .io .IOException ;
4547import java .nio .charset .StandardCharsets ;
4648import java .util .Arrays ;
4749import java .util .List ;
4850import java .util .Map ;
4951import jenkins .plugins .git .AbstractGitSCMSource ;
5052import jenkins .plugins .git .GitSCMSourceDefaults ;
5153import jenkins .plugins .git .GitSampleRepoRule ;
54+ import jenkins .plugins .git .junit .jupiter .WithGitSampleRepo ;
5255import org .jenkinsci .plugins .workflow .cps .CpsScmFlowDefinition ;
5356import org .jenkinsci .plugins .workflow .job .WorkflowJob ;
5457import org .jenkinsci .plugins .workflow .job .WorkflowRun ;
5558import org .jenkinsci .plugins .workflow .multibranch .WorkflowMultiBranchProject ;
56- import org .junit .Rule ;
57- import org .junit .Test ;
58- import org .junit .runner .RunWith ;
59+ import org .junit .jupiter .api .AfterEach ;
60+ import org .junit .jupiter .api .BeforeAll ;
61+ import org .junit .jupiter .api .BeforeEach ;
62+ import org .junit .jupiter .api .Test ;
5963import org .jvnet .hudson .test .Issue ;
6064import org .jvnet .hudson .test .JenkinsRule ;
65+ import org .jvnet .hudson .test .junit .jupiter .WithJenkins ;
6166import org .jvnet .hudson .test .recipes .WithTimeout ;
62- import org .mockito .junit .MockitoJUnitRunner ;
6367
6468import static org .hamcrest .MatcherAssert .assertThat ;
6569import static org .hamcrest .Matchers .containsInAnyOrder ;
7377 * Tests different scenarios of the
7478 * {@link BitbucketSCMSource#build(jenkins.scm.api.SCMHead, jenkins.scm.api.SCMRevision)} method.
7579 */
76- @ RunWith (MockitoJUnitRunner .class )
80+ @ WithJenkins
81+ @ WithGitSampleRepo
7782public class BitbucketSCMSourceBuildTest {
7883
7984 private static final String CLOUD_REPO_OWNER = "cloudbeers" ;
@@ -109,37 +114,46 @@ public class BitbucketSCMSourceBuildTest {
109114 "sroT/IHW2jKMD0v8kKLUnKCZYzlw0By7+RvJ8lgzHB0D71f6EC1UWg==\n " +
110115 "-----END RSA PRIVATE KEY-----\n " ;
111116
112- @ Rule
113- public JenkinsRule j = new JenkinsRule ();
117+ public static JenkinsRule rule = new JenkinsRule ();
118+
119+ @ BeforeAll
120+ static void init (JenkinsRule r ) {
121+ rule = r ;
122+ }
114123
115- @ Rule
116124 public GitSampleRepoRule sampleRepo = new GitSampleRepoRule ();
117125
126+ @ BeforeEach
127+ void setup (GitSampleRepoRule gitRule ) {
128+ sampleRepo = gitRule ;
129+ }
130+
131+ @ AfterEach
132+ void setup () throws Exception {
133+ for (Item item : rule .jenkins .getAllItems ()) {
134+ item .delete ();
135+ }
136+ }
118137
119138 @ Test
120139 @ Issue ("JENKINS-73471" )
121140 @ WithTimeout (120 )
122- public void buildWhenSetSSHCheckoutTraitThenEmptyAuthenticatorExtension () throws Exception {
141+ void buildWhenSetSSHCheckoutTraitThenEmptyAuthenticatorExtension () throws Exception {
123142 String jenkinsFile = "Jenkinsfile" ;
124143 sampleRepo .init ();
125144 sampleRepo .write (jenkinsFile , "node { checkout scm }" );
126145 sampleRepo .git ("add" , jenkinsFile );
127146 sampleRepo .git ("commit" , "--all" , "--message=defined" );
128147
129- StandardUsernameCredentials userPassCredentials = new UsernamePasswordCredentialsImpl (CredentialsScope .GLOBAL ,
130- "user-pass" , null , "user" , "pass" );
131- CredentialsProvider .lookupStores (j .jenkins ).iterator ().next ()
132- .addCredentials (Domain .global (), userPassCredentials );
133- StandardUsernameCredentials sshCredentials = new BasicSSHUserPrivateKey (CredentialsScope .GLOBAL , "user-key" , "user" ,
134- new BasicSSHUserPrivateKey .DirectEntryPrivateKeySource (PRIVATE_KEY ), null , null );
135- CredentialsProvider .lookupStores (j .jenkins ).iterator ().next ()
136- .addCredentials (Domain .global (), sshCredentials );
148+ StandardUsernameCredentials userPassCredentials = registerUserCredentials ();
149+ StandardUsernameCredentials sshCredentials = registerSSHCredentials ();
137150
138- WorkflowMultiBranchProject owner = j .createProject (WorkflowMultiBranchProject .class , "testMultibranch" );
139- BitbucketSCMSource instance = new BitbucketSCMSource (CLOUD_REPO_OWNER , REPO_NAME );
140- instance .setOwner (owner );
141- instance .setCredentialsId (userPassCredentials .getId ());
142- instance .setTraits (Arrays .asList (
151+ WorkflowMultiBranchProject owner = rule .createProject (WorkflowMultiBranchProject .class , "testMultibranch" );
152+ BitbucketSCMSource scmSource = new BitbucketSCMSource (CLOUD_REPO_OWNER , REPO_NAME );
153+ scmSource .setServerUrl ("http://localhost:7990/bitbucket" );
154+ scmSource .setOwner (owner );
155+ scmSource .setCredentialsId (userPassCredentials .getId ());
156+ scmSource .setTraits (Arrays .asList (
143157 new BranchDiscoveryTrait (1 ),
144158 new SSHCheckoutTrait (sshCredentials .getId ())));
145159
@@ -149,13 +163,14 @@ public void buildWhenSetSSHCheckoutTraitThenEmptyAuthenticatorExtension() throws
149163 new BitbucketHref ("ssh" , String .format ("ssh://user@localhost/%s" , sampleRepo ))
150164 )));
151165 BitbucketApi client = mock (BitbucketApi .class );
152- BitbucketMockApiFactory .add (BitbucketCloudEndpoint . SERVER_URL , client );
166+ BitbucketMockApiFactory .add (scmSource . getServerUrl () , client );
153167 when (client .getRepository ()).thenReturn (repository );
154168
155169 BranchSCMHead head = new BranchSCMHead (BRANCH_NAME );
156170 AbstractGitSCMSource .SCMRevisionImpl revision =
157171 new AbstractGitSCMSource .SCMRevisionImpl (head , sampleRepo .head ());
158- GitSCM build = (GitSCM )instance .build (head , revision );
172+ GitSCM build = (GitSCM ) scmSource .build (head , revision );
173+
159174 assertThat (build .getUserRemoteConfigs ().size (), is (1 ));
160175 UserRemoteConfig remoteConfig = build .getUserRemoteConfigs ().get (0 );
161176 assertThat (remoteConfig .getUrl (), is (String .format ("ssh://user@localhost/%s" , sampleRepo )));
@@ -170,7 +185,7 @@ public void buildWhenSetSSHCheckoutTraitThenEmptyAuthenticatorExtension() throws
170185
171186 // Create a Pipeline with CpsScmFlowDefinition based of the GitSCM produced
172187 // Then check that the checkout uses GIT_SSH from the git-client logs
173- WorkflowJob job = j .jenkins .createProject (WorkflowJob .class , "testGitScm" );
188+ WorkflowJob job = rule .jenkins .createProject (WorkflowJob .class , "testGitScm" );
174189 job .setDefinition (new CpsScmFlowDefinition (build , jenkinsFile ));
175190 WorkflowRun run = job .scheduleBuild2 (0 ).get ();
176191
@@ -181,37 +196,36 @@ public void buildWhenSetSSHCheckoutTraitThenEmptyAuthenticatorExtension() throws
181196
182197 @ Test
183198 @ WithTimeout (120 )
184- public void buildBasicAuthThenAuthenticatorExtension () throws Exception {
199+ void buildBasicAuthThenAuthenticatorExtension () throws Exception {
185200 String jenkinsFile = "Jenkinsfile" ;
186201 sampleRepo .init ();
187202 sampleRepo .write (jenkinsFile , "node { checkout scm }" );
188203 sampleRepo .git ("add" , jenkinsFile );
189204 sampleRepo .git ("commit" , "--all" , "--message=defined" );
190205
191- StandardUsernameCredentials userPassCredentials = new UsernamePasswordCredentialsImpl (CredentialsScope .GLOBAL ,
192- "user-pass" , null , "user" , "pass" );
193- CredentialsProvider .lookupStores (j .jenkins ).iterator ().next ()
194- .addCredentials (Domain .global (), userPassCredentials );
206+ StandardUsernameCredentials userPassCredentials = registerUserCredentials ();
195207
196- WorkflowMultiBranchProject owner = j .createProject (WorkflowMultiBranchProject .class , "testMultibranch" );
197- BitbucketSCMSource instance = new BitbucketSCMSource (CLOUD_REPO_OWNER , REPO_NAME );
198- instance .setOwner (owner );
199- instance .setCredentialsId (userPassCredentials .getId ());
200- instance .setTraits (List .of (new BranchDiscoveryTrait (1 )));
208+ WorkflowMultiBranchProject owner = rule .createProject (WorkflowMultiBranchProject .class , "testMultibranch" );
209+ BitbucketSCMSource scmSource = new BitbucketSCMSource (CLOUD_REPO_OWNER , REPO_NAME );
210+ scmSource .setServerUrl ("http://localhost:7990/bitbucket" );
211+ scmSource .setOwner (owner );
212+ scmSource .setCredentialsId (userPassCredentials .getId ());
213+ scmSource .setTraits (List .of (new BranchDiscoveryTrait (1 )));
201214
202215 BitbucketRepository repository = mock (BitbucketRepository .class );
203216 when (repository .getLinks ()).thenReturn (Map .of ("clone" , List .of (
204217 new BitbucketHref ("http" , sampleRepo .toString ()),
205218 new BitbucketHref ("ssh" , String .format ("ssh://localhost:%s" , sampleRepo ))
206219 )));
207220 BitbucketServerAPIClient client = mock (BitbucketServerAPIClient .class );
208- BitbucketMockApiFactory .add (BitbucketCloudEndpoint . SERVER_URL , client );
221+ BitbucketMockApiFactory .add (scmSource . getServerUrl () , client );
209222 when (client .getRepository ()).thenReturn (repository );
210223
211224 BranchSCMHead head = new BranchSCMHead (BRANCH_NAME );
212225 AbstractGitSCMSource .SCMRevisionImpl revision =
213226 new AbstractGitSCMSource .SCMRevisionImpl (head , sampleRepo .head ());
214- GitSCM build = (GitSCM )instance .build (head , revision );
227+ GitSCM build = (GitSCM ) scmSource .build (head , revision );
228+
215229 assertThat (build .getUserRemoteConfigs ().size (), is (1 ));
216230 UserRemoteConfig remoteConfig = build .getUserRemoteConfigs ().get (0 );
217231 assertThat (remoteConfig .getUrl (), is (sampleRepo .toString ()));
@@ -226,12 +240,71 @@ public void buildBasicAuthThenAuthenticatorExtension() throws Exception {
226240
227241 // Create a Pipeline with CpsScmFlowDefinition based of the GitSCM produced
228242 // Then check that the checkout scm uses GIT_ASKPASS from the git-client logs
229- WorkflowJob job = j .jenkins .createProject (WorkflowJob .class , "testGitScm" );
243+ WorkflowJob job = rule .jenkins .createProject (WorkflowJob .class , "testGitScm" );
230244 job .setDefinition (new CpsScmFlowDefinition (build , jenkinsFile ));
231245 WorkflowRun run = job .scheduleBuild2 (0 ).get ();
232246
233247 ByteArrayOutputStream byteArrayOutStr = new ByteArrayOutputStream ();
234248 run .writeWholeLogTo (byteArrayOutStr );
235249 assertThat (byteArrayOutStr .toString (StandardCharsets .UTF_8 ), containsString ("using GIT_ASKPASS to set credentials" ));
236250 }
251+
252+ @ Test
253+ @ Issue ("JENKINS-75611" )
254+ void verify_ssh_trait_on_data_center_with_disabled_https_protocol () throws Exception {
255+ StandardUsernameCredentials userPassCredentials = registerUserCredentials ();
256+ StandardUsernameCredentials sshCredentials = registerSSHCredentials ();
257+
258+ WorkflowMultiBranchProject owner = rule .createProject (WorkflowMultiBranchProject .class , "testMultibranch" );
259+ BitbucketSCMSource scmSource = new BitbucketSCMSource (CLOUD_REPO_OWNER , REPO_NAME );
260+ scmSource .setServerUrl ("http://localhost:7990/bitbucket" );
261+ scmSource .setOwner (owner );
262+ scmSource .setCredentialsId (userPassCredentials .getId ());
263+ scmSource .setTraits (Arrays .asList (
264+ new BranchDiscoveryTrait (1 ),
265+ new SSHCheckoutTrait (sshCredentials .getId ())));
266+
267+ String sshCloneURL = String .format ("ssh://user@localhost::7999/%s/%s.git" , CLOUD_REPO_OWNER , REPO_NAME );
268+
269+ BitbucketRepository repository = mock (BitbucketRepository .class );
270+ when (repository .getLinks ()).thenReturn (Map .of ("clone" , List .of (
271+ new BitbucketHref ("http" , sampleRepo .toString ()),
272+ new BitbucketHref ("ssh" , sshCloneURL )
273+ )));
274+ BitbucketApi client = mock (BitbucketApi .class );
275+ BitbucketMockApiFactory .add (scmSource .getServerUrl (), client );
276+ when (client .getRepository ()).thenReturn (repository );
277+
278+ BranchSCMHead head = new BranchSCMHead (BRANCH_NAME );
279+ AbstractGitSCMSource .SCMRevisionImpl revision = new AbstractGitSCMSource .SCMRevisionImpl (head , "1dbb02d4c1b99f1e84459c6947e3caa53cadfad1" );
280+ GitSCM build = (GitSCM ) scmSource .build (head , revision );
281+
282+ assertThat (build .getUserRemoteConfigs ().size (), is (1 ));
283+ UserRemoteConfig remoteConfig = build .getUserRemoteConfigs ().get (0 );
284+ assertThat (remoteConfig .getUrl (), is (sshCloneURL ));
285+ assertThat (remoteConfig .getRefspec (), is (String .format ("+refs/heads/%s:refs/remotes/origin/%s" , BRANCH_NAME , BRANCH_NAME )));
286+ assertThat (remoteConfig .getCredentialsId (), is (sshCredentials .getId ()));
287+ assertThat (build .getExtensions (), containsInAnyOrder (
288+ instanceOf (BuildChooserSetting .class ),
289+ instanceOf (GitSCMSourceDefaults .class ),
290+ instanceOf (GitClientAuthenticatorExtension .class ),
291+ instanceOf (BitbucketEnvVarExtension .class ))
292+ );
293+ }
294+
295+ private StandardUsernameCredentials registerSSHCredentials () throws IOException {
296+ StandardUsernameCredentials sshCredentials = new BasicSSHUserPrivateKey (CredentialsScope .GLOBAL , "user-key" , "user" ,
297+ new BasicSSHUserPrivateKey .DirectEntryPrivateKeySource (PRIVATE_KEY ), null , null );
298+ CredentialsProvider .lookupStores (rule .jenkins ).iterator ().next ()
299+ .addCredentials (Domain .global (), sshCredentials );
300+ return sshCredentials ;
301+ }
302+
303+ private StandardUsernameCredentials registerUserCredentials () throws FormException , IOException {
304+ StandardUsernameCredentials userPassCredentials = new UsernamePasswordCredentialsImpl (CredentialsScope .GLOBAL ,
305+ "user-pass" , null , "user" , "pass" );
306+ CredentialsProvider .lookupStores (rule .jenkins ).iterator ().next ()
307+ .addCredentials (Domain .global (), userPassCredentials );
308+ return userPassCredentials ;
309+ }
237310}
0 commit comments