Skip to content

Commit

Permalink
Merge pull request #8448 from Vlatombe/labelAtomSet-robustness
Browse files Browse the repository at this point in the history
Label parsing robustness fix
  • Loading branch information
Vlatombe committed Sep 2, 2023
2 parents c98e76b + 65ce750 commit e79ac42
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 1 deletion.
15 changes: 14 additions & 1 deletion core/src/main/java/hudson/model/Slave.java
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,10 @@ public DescribableList<NodeProperty<?>, NodePropertyDescriptor> getNodePropertie

@DataBoundSetter
public void setNodeProperties(List<? extends NodeProperty<?>> properties) throws IOException {
if (nodeProperties == null) {

Check warning on line 314 in core/src/main/java/hudson/model/Slave.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Partially covered line

Line 314 is only partially covered, one branch is missing
warnPlugin();

Check warning on line 315 in core/src/main/java/hudson/model/Slave.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 315 is not covered by tests
nodeProperties = new DescribableList<>(this);

Check warning on line 316 in core/src/main/java/hudson/model/Slave.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 316 is not covered by tests
}
nodeProperties.replaceBy(properties);
}

Expand Down Expand Up @@ -341,14 +345,23 @@ private void _setLabelString(String labelString) {
this.labelAtomSet = Collections.unmodifiableSet(Label.parse(label));
}

@NonNull
@CheckForNull // should be @NonNull, but we've seen plugins overriding readResolve() without calling super.
private transient Set<LabelAtom> labelAtomSet;

@Override
protected Set<LabelAtom> getLabelAtomSet() {
if (labelAtomSet == null) {
warnPlugin();
this.labelAtomSet = Collections.unmodifiableSet(Label.parse(label));
}
return labelAtomSet;
}

private void warnPlugin() {
LOGGER.log(Level.WARNING, () -> getClass().getName() + " or one of its superclass overrides readResolve() without calling super implementation." +
"Please file an issue against the plugin implementing it: " + Jenkins.get().getPluginManager().whichPlugin(getClass()));
}

@Override
public Callable<ClockDifference, IOException> getClockDifferenceCallable() {
return new GetClockDifference1();
Expand Down
47 changes: 47 additions & 0 deletions test/src/test/java/jenkins/model/NodesRestartTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package jenkins.model;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import static org.junit.Assert.assertNotNull;

import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.model.Descriptor;
import hudson.model.Slave;
import hudson.slaves.ComputerLauncher;
import java.io.IOException;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.JenkinsSessionRule;

public class NodesRestartTest {
@Rule
public JenkinsSessionRule s = new JenkinsSessionRule();

// The point of this implementation is to override readResolve so that Slave#readResolve doesn't get called.
public static class DummyAgent extends Slave {
public DummyAgent(@NonNull String name, String remoteFS, ComputerLauncher launcher) throws Descriptor.FormException, IOException {
super(name, remoteFS, launcher);
}

@Override
protected Object readResolve() {
return this;
}
}

@Test
public void checkNodeRestart() throws Throwable {
s.then(r -> {
assertThat(r.jenkins.getNodes(), hasSize(0));
var node = new DummyAgent("my-node", "temp", r.createComputerLauncher(null));
r.jenkins.addNode(node);
assertThat(r.jenkins.getNodes(), hasSize(1));
});
s.then(r -> {
assertThat(r.jenkins.getNodes(), hasSize(1));
var node = r.jenkins.getNode("my-node");
assertNotNull(node.getNodeProperties());
assertNotNull(node.getAssignedLabels());
});
}
}

0 comments on commit e79ac42

Please sign in to comment.