From 3e29bd7eff12d73a9b49c1d6039dc6d0699db15a Mon Sep 17 00:00:00 2001 From: christ66 Date: Tue, 6 Jan 2015 19:41:51 -0800 Subject: [PATCH] [JENKINS-22811] Folder loading can break when an item inside the folder fails to load or throws an Exception. --- .../java/hudson/model/ItemGroupMixIn.java | 2 + .../java/hudson/model/ItemGroupMixInTest.java | 79 ++++++++++++++++++ .../xmlFileReadExceptionOnLoad.zip | Bin 0 -> 1545 bytes 3 files changed, 81 insertions(+) create mode 100644 test/src/test/resources/hudson/model/ItemGroupMixInTest/xmlFileReadExceptionOnLoad.zip diff --git a/core/src/main/java/hudson/model/ItemGroupMixIn.java b/core/src/main/java/hudson/model/ItemGroupMixIn.java index d34b5e7f93..e2f2e0e2b7 100644 --- a/core/src/main/java/hudson/model/ItemGroupMixIn.java +++ b/core/src/main/java/hudson/model/ItemGroupMixIn.java @@ -116,6 +116,8 @@ public abstract class ItemGroupMixIn { configurations.put(key.call(item), item); } catch (IOException e) { Logger.getLogger(ItemGroupMixIn.class.getName()).log(Level.WARNING, "could not load " + subdir, e); + } catch (Exception e) { + Logger.getLogger(ItemGroupMixIn.class.getName()).log(Level.WARNING, "could not load " + subdir, e); } } diff --git a/test/src/test/java/hudson/model/ItemGroupMixInTest.java b/test/src/test/java/hudson/model/ItemGroupMixInTest.java index ddf14573db..b9ff4ec32f 100644 --- a/test/src/test/java/hudson/model/ItemGroupMixInTest.java +++ b/test/src/test/java/hudson/model/ItemGroupMixInTest.java @@ -26,13 +26,20 @@ package hudson.model; import java.util.Collection; import static org.junit.Assert.*; +import hudson.Extension; +import hudson.tasks.BuildWrapper; +import hudson.tasks.BuildWrapperDescriptor; +import org.apache.commons.io.FileUtils; import org.junit.Rule; import org.junit.Test; import org.jvnet.hudson.test.Bug; +import org.jvnet.hudson.test.Issue; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.MockFolder; import org.jvnet.hudson.test.recipes.LocalData; +import java.io.File; + public class ItemGroupMixInTest { @Rule public JenkinsRule r = new JenkinsRule(); @@ -47,4 +54,76 @@ public class ItemGroupMixInTest { assertEquals("valid", items.iterator().next().getName()); } + /** + * This test unit makes sure that if part of the config.xml file is + * deleted it will still load everything else inside the folder. + * The test unit expects an IOException is thrown, and the one failed + * job fails to load. + */ + @Issue("JENKINS-22811") + @Test + public void xmlFileFailsToLoad() throws Exception { + MockFolder folder = r.createFolder("folder"); + assertNotNull(folder); + + AbstractProject project = folder.createProject(FreeStyleProject.class, "job1"); + AbstractProject project2 = folder.createProject(FreeStyleProject.class, "job2"); + AbstractProject project3 = folder.createProject(FreeStyleProject.class, "job3"); + + File configFile = project.getConfigFile().getFile(); + + List lines = FileUtils.readLines(configFile).subList(0, 5); + configFile.delete(); + + // Remove half of the config.xml file to make "invalid" or fail to load + FileUtils.writeByteArrayToFile(configFile, lines.toString().getBytes()); + for (int i = lines.size() / 2; i < lines.size(); i++) { + FileUtils.writeStringToFile(configFile, lines.get(i), true); + } + + // Reload Jenkins. + r.jenkins.reload(); + + // Folder + assertNotNull("Folder failed to load.", folder); + assertNull("Job should have failed to load.", r.jenkins.getItemByFullName("folder/job1")); + assertNotNull("Other job in folder should have loaded.", r.jenkins.getItemByFullName("folder/job2")); + assertNotNull("Other job in folder should have loaded.", r.jenkins.getItemByFullName("folder/job3")); + } + + /** + * This test unit makes sure that any exception that is thrown is caught, however the folder + * will continue to load not impacting any other jobs in the folder. + */ + @LocalData + @Issue("JENKINS-22811") + @Test + public void xmlFileReadExceptionOnLoad() throws Exception { + MockFolder d = r.jenkins.getItemByFullName("d", MockFolder.class); + assertNotNull(d); + Collection items = d.getItems(); + assertEquals(1, items.size()); + assertEquals("valid", items.iterator().next().getName()); + } + + @Extension + public static class MockBuilderThrowsError extends BuildWrapper { + @Override + public Collection getProjectActions(AbstractProject project){ + throw new NullPointerException(); + } + + @Extension + public static class DescriptorImpl extends BuildWrapperDescriptor { + @Override + public boolean isApplicable(AbstractProject item) { + return true; + } + + @Override + public String getDisplayName() { + return null; + } + } + } } diff --git a/test/src/test/resources/hudson/model/ItemGroupMixInTest/xmlFileReadExceptionOnLoad.zip b/test/src/test/resources/hudson/model/ItemGroupMixInTest/xmlFileReadExceptionOnLoad.zip new file mode 100644 index 0000000000000000000000000000000000000000..70b2d12f980864ecc812c3c6b8c589a91d57d6d9 GIT binary patch literal 1545 zcmWIWW@h1H0D-j0UCv+zlwf6$VaUo)D%KAT;bdSASiC%F5fGPFa5FHnykKTv022Xl z?WJhi*5T-Pv znIeK_N@iYJVooMB2-<)q;Rr(!V1RNkgv?ZPvt7OH$TOh#e=;&K$N_1vV^Z|N6wEY4 zc(evu2OTyLSbI{_=;cOzg&+qBwN_09A1}9QV$m-9Z%$Q{k@q}l<|i0h6<-_X!n1$D zrLwOIehh`|f_vE3^IZ7m9>sJ~|L3E%8#!ihz0y{BdhL|gqUC4jn6lm%T~>YmTHQXL z*=d27>RDdyn35Q{MbR?qf{x+3TN%w(w&}@V3)%K_r~7j{?sAi~FMKxd{kGTI_p+0& zZ&F`4Q_W$QjdsOU!Gp`w9!^u;8#P_^*skX(XBL~980Xv)Ozml1`ES~ef6KU~a<=s&jGp!iit@8klS{x!jFCx>8CRZ?09phB0t|m0 zK{Pb2u|jefnyCTa2%|9b7qU_IFrz?84QLpa?163=YF>jF2267dTN)b>h9Uc&u(6nV z3fYbC5ym2X4a#A7e2tmEkWDlNx))pi00#jmw_!2ao*8#u13C~06dJZPHsdfE5gy3F ziJ2;qUAdGA)s?U`3JgyyDGA+N)D(&wO&_tEi*O-06tLRB$_DZ$2M{g