Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JENKINS-71959] Rename blank cloud names to be non-blank #1010

Merged
merged 4 commits into from
Sep 4, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@
super(name);
this.dockerApi = dockerApi;
this.templates = templates;
if (name == null || name.isBlank()) {
LOGGER.warn("Docker cloud requires a non-blank name after Jenkins 2.402");
}
}

@Deprecated
Expand Down Expand Up @@ -727,6 +730,10 @@
dockerApi = new DockerAPI(dockerHost, connectTimeout, readTimeout, version, dockerHostname);
}

if (name == null || name.isBlank()) {

Check warning on line 733 in src/main/java/com/nirima/jenkins/plugins/docker/DockerCloud.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Partially covered line

Line 733 is only partially covered, 4 branches are missing
LOGGER.warn("Docker cloud requires a non-blank name after Jenkins 2.402");

Check warning on line 734 in src/main/java/com/nirima/jenkins/plugins/docker/DockerCloud.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 734 is not covered by tests
Copy link
Member

@Vlatombe Vlatombe Sep 4, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
LOGGER.warn("Docker cloud requires a non-blank name after Jenkins 2.402");
LOGGER.warn("Docker cloud requires a non-blank name after Jenkins 2.402");
return new DockerCloud("docker-" + UUID.randomUUID().toString().substring(0, 8), this);

And implement a copy constructor like this (this is what is used in kubernetes-plugin)

  public DockerCloud(@NonNull String name, @NonNull DockerCloud source) {
    super(name);
    XStream2 xs = new XStream2();
    xs.omitField(Cloud.class, "name");
    xs.unmarshal(XStream2.getDefaultDriver().createReader(new StringReader(xs.toXML(source))), this);
  }

Probably requires saving configuration afterwards (or switch uuid to a digest based on current content) to avoid getting a different name on each instance start.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks very much @Vlatombe !

The XStream2 call caused complaints from Jenkins core that it was trying to marshal unsafe entities, so I switched to a simple assignment in 57d3010 . I'll run some interactive tests to confirm that change is behaving as expected. Let me know if you detect errors in 57d3010

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simple assignment works too, but can be source of maintenance issues because you need to remember that it needs to be updated every time a field is added.

}

return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,17 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import org.hamcrest.MatcherAssert;
import org.hamcrest.core.IsIterableContaining;
import org.jenkinsci.plugins.docker.commons.credentials.DockerServerCredentials;
import org.jenkinsci.plugins.docker.commons.credentials.DockerServerEndpoint;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.Issue;
import org.jvnet.hudson.test.JenkinsRule;
import org.jvnet.hudson.test.LoggerRule;

/**
* @author Kanstantsin Shautsou
Expand All @@ -33,6 +38,9 @@ public class DockerCloudTest {
@Rule
public JenkinsRule jenkins = new JenkinsRule();

@Rule
public LoggerRule lr = new LoggerRule();

@SuppressWarnings("unused")
@Test
public void testConstructor_0_10_2() {
Expand All @@ -48,6 +56,28 @@ public void testConstructor_0_10_2() {
null); // dockerHostname
}

private static final String LOG_MESSAGE = "Docker cloud requires a non-blank name after Jenkins 2.402";

@Issue("JENKINS-70729") // Warn if cloud name is empty
@Test
public void testConstructorWithEmptyName() {
lr.record(DockerCloud.class.getName(), Level.ALL).capture(16);
DockerCloud cloud =
new DockerCloud("", new DockerAPI(new DockerServerEndpoint("uri", "credentialsId")), List.of());
Assert.assertEquals(cloud.getDisplayName(), "");
MatcherAssert.assertThat(lr.getMessages(), IsIterableContaining.hasItem(LOG_MESSAGE));
}

@Issue("JENKINS-70729") // Warn if cloud name is null
@Test
public void testConstructorWithNullName() {
lr.record(DockerCloud.class.getName(), Level.ALL).capture(16);
DockerCloud cloud =
new DockerCloud(null, new DockerAPI(new DockerServerEndpoint("uri", "credentialsId")), List.of());
Assert.assertEquals(cloud.getDisplayName(), null);
MatcherAssert.assertThat(lr.getMessages(), IsIterableContaining.hasItem(LOG_MESSAGE));
}

@Test
public void globalConfigRoundtrip() throws Exception {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,11 @@ public class JenkinsUtilsTest {
public void getCloudByNameOrThrowGivenNameThenReturnsCloud() throws Exception {
// Given
final DockerAPI dockerApi = new DockerAPI(new DockerServerEndpoint("uri", "credentialsId"));
final DockerCloud cloudEmpty = new DockerCloud("", dockerApi, Collections.emptyList());
final String expectedCloudName = "expectedCloudName";
final DockerCloud cloudExpected = new DockerCloud(expectedCloudName, dockerApi, Collections.emptyList());
final DockerCloud cloudOther = new DockerCloud("otherCloudName", dockerApi, Collections.emptyList());
final OtherTypeOfCloud cloudForeign = new OtherTypeOfCloud("foreign");
final List<Cloud> clouds = List.of(cloudEmpty, cloudOther, cloudExpected, cloudForeign);
final List<Cloud> clouds = List.of(cloudOther, cloudExpected, cloudForeign);
jenkins.getInstance().clouds.replaceBy(clouds);

// When
Expand All @@ -47,14 +46,13 @@ public void getCloudByNameOrThrowGivenNameThenReturnsCloud() throws Exception {
public void getCloudByNameOrThrowGivenUnknownNameThenThrows() throws Exception {
// Given
final DockerAPI dockerApi = new DockerAPI(new DockerServerEndpoint("uri", "credentialsId"));
final DockerCloud cloudEmpty = new DockerCloud("", dockerApi, Collections.emptyList());
final String requestedCloudName = "anUnknownCloudName";
final String cloudName1 = "expectedCloudName";
final DockerCloud cloud1 = new DockerCloud(cloudName1, dockerApi, Collections.emptyList());
final String cloudName2 = "otherCloudName";
final DockerCloud cloud2 = new DockerCloud(cloudName2, dockerApi, Collections.emptyList());
final OtherTypeOfCloud cloudForeign = new OtherTypeOfCloud("foreign");
final List<Cloud> clouds = List.of(cloudEmpty, cloud2, cloud1, cloudForeign);
final List<Cloud> clouds = List.of(cloud2, cloud1, cloudForeign);
jenkins.getInstance().clouds.replaceBy(clouds);

try {
Expand All @@ -75,14 +73,13 @@ public void getCloudByNameOrThrowGivenUnknownNameThenThrows() throws Exception {
public void getCloudByNameOrThrowGivenForeignCloudNameThenThrows() throws Exception {
// Given
final DockerAPI dockerApi = new DockerAPI(new DockerServerEndpoint("uri", "credentialsId"));
final DockerCloud cloudEmpty = new DockerCloud("", dockerApi, Collections.emptyList());
final String requestedCloudName = "foreign";
final String cloudName1 = "DockerCloud1Name";
final DockerCloud cloud1 = new DockerCloud(cloudName1, dockerApi, Collections.emptyList());
final String cloudName2 = "DockerCloud2Name";
final DockerCloud cloud2 = new DockerCloud(cloudName2, dockerApi, Collections.emptyList());
final OtherTypeOfCloud cloudForeign = new OtherTypeOfCloud(requestedCloudName);
final List<Cloud> clouds = List.of(cloudEmpty, cloud2, cloud1, cloudForeign);
final List<Cloud> clouds = List.of(cloud2, cloud1, cloudForeign);
jenkins.getInstance().clouds.replaceBy(clouds);

try {
Expand Down
Loading