From 1ed110a4a5f748779e533bab20d04bd514b80b78 Mon Sep 17 00:00:00 2001 From: 8nevil8 Date: Fri, 18 Nov 2011 12:52:50 +0300 Subject: [PATCH] Improve SCM cascading handling: Inherit SCM if it wasn't configured. Speed-up code: drop instanceof checking. Implement unit-tests for new logic --- .../src/main/java/hudson/model/Items.java | 4 +- .../src/main/java/hudson/model/Job.java | 17 +-- .../hudsonci/api/model/IProjectProperty.java | 5 + .../project/property/BaseProjectProperty.java | 26 ++++ .../property/ExternalProjectProperty.java | 8 ++ .../project/property/SCMProjectProperty.java | 11 ++ .../property/TriggerProjectProperty.java | 11 ++ .../property/BaseProjectPropertyTest.java | 95 ++++++++---- .../property/ExternalProjectPropertyTest.java | 21 ++- .../project/property/ProjectPropertyTest.java | 127 +--------------- .../property/SCMProjectPropertyTest.java | 135 ++++++++++++++++++ .../property/TriggerProjectPropertyTest.java | 119 +++++++++++++++ 12 files changed, 404 insertions(+), 175 deletions(-) create mode 100644 hudson-core/src/test/java/org/hudsonci/model/project/property/SCMProjectPropertyTest.java create mode 100644 hudson-core/src/test/java/org/hudsonci/model/project/property/TriggerProjectPropertyTest.java diff --git a/hudson-core/src/main/java/hudson/model/Items.java b/hudson-core/src/main/java/hudson/model/Items.java index 057f9d0aa..1cdc87242 100644 --- a/hudson-core/src/main/java/hudson/model/Items.java +++ b/hudson-core/src/main/java/hudson/model/Items.java @@ -47,6 +47,7 @@ import org.hudsonci.model.project.property.IntegerProjectProperty; import org.hudsonci.model.project.property.LogRotatorProjectProperty; import org.hudsonci.model.project.property.ResultProjectProperty; +import org.hudsonci.model.project.property.SCMProjectProperty; import org.hudsonci.model.project.property.StringProjectProperty; import org.hudsonci.model.project.property.TriggerProjectProperty; @@ -146,6 +147,7 @@ public static XmlFile getConfigFile(Item item) { XSTREAM.alias("matrix-config",MatrixConfiguration.class); //aliases for project properties. + //TODO: think about migrating to xstream's annotations. XSTREAM.alias("base-property", BaseProjectProperty.class); XSTREAM.alias("external-property", ExternalProjectProperty.class); XSTREAM.alias("trigger-property", TriggerProjectProperty.class); @@ -154,12 +156,12 @@ public static XmlFile getConfigFile(Item item) { XSTREAM.alias("string-property", StringProjectProperty.class); XSTREAM.alias("log-rotator-property", LogRotatorProjectProperty.class); XSTREAM.alias("result-property", ResultProjectProperty.class); + XSTREAM.alias("scm-property", SCMProjectProperty.class); XSTREAM.alias("copy-write-list-property", CopyOnWriteListProjectProperty.class); XSTREAM.alias("axis-list-property", AxisListProjectProperty.class); XSTREAM.alias("describable-list-property", DescribableListProjectProperty.class); XSTREAM.aliasField("project-properties", Job.class, "jobProperties"); - //TODO: think about migrating to xstream's annotations. XSTREAM.alias("appointed-node-property", AppointedNode.class); } } diff --git a/hudson-core/src/main/java/hudson/model/Job.java b/hudson-core/src/main/java/hudson/model/Job.java index bbb73df04..5a3710700 100644 --- a/hudson-core/src/main/java/hudson/model/Job.java +++ b/hudson-core/src/main/java/hudson/model/Job.java @@ -88,7 +88,6 @@ import org.hudsonci.api.model.IJob; import org.hudsonci.api.model.IProjectProperty; import org.hudsonci.model.project.property.ExternalProjectProperty; -import org.hudsonci.model.project.property.TriggerProjectProperty; import org.jfree.chart.ChartFactory; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.CategoryAxis; @@ -108,8 +107,7 @@ import org.kohsuke.stapler.StaplerResponse; import org.kohsuke.stapler.export.Exported; -import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST; -import static javax.servlet.http.HttpServletResponse.SC_NO_CONTENT; +import static javax.servlet.http.HttpServletResponse.*; /** * A job is an runnable entity under the monitoring of Hudson. @@ -1679,12 +1677,7 @@ public synchronized void setCascadingProjectName(String cascadingProjectName) { cascadingProjectName); CascadingUtil.linkCascadingProjectsToChild(cascadingProject, name); for (IProjectProperty property : jobProperties.values()) { - if (property instanceof ExternalProjectProperty) { - property.setOverridden(((ExternalProjectProperty) property).isModified()); - } else { - property.setOverridden( - property.allowOverrideValue(property.getCascadingValue(), property.getValue())); - } + property.onCascadingProjectChanged(); } } } @@ -1729,11 +1722,7 @@ private void clearCascadingProject() { this.cascadingProject = null; this.cascadingProjectName = null; for (IProjectProperty property : jobProperties.values()) { - if (property instanceof TriggerProjectProperty && !property.isOverridden() && property.getValue() != null) { - ((TriggerProjectProperty) property).getValue().stop(); - property.resetValue(); - } - property.setOverridden(false); + property.onCascadingProjectChanged(); } } diff --git a/hudson-core/src/main/java/org/hudsonci/api/model/IProjectProperty.java b/hudson-core/src/main/java/org/hudsonci/api/model/IProjectProperty.java index c77f178ad..193bee7e8 100644 --- a/hudson-core/src/main/java/org/hudsonci/api/model/IProjectProperty.java +++ b/hudson-core/src/main/java/org/hudsonci/api/model/IProjectProperty.java @@ -118,4 +118,9 @@ public interface IProjectProperty extends Serializable { */ void setOverridden(boolean overridden); + /** + * Method that is called while changing cascading parent. Update property internal states.l + */ + void onCascadingProjectChanged(); + } diff --git a/hudson-core/src/main/java/org/hudsonci/model/project/property/BaseProjectProperty.java b/hudson-core/src/main/java/org/hudsonci/model/project/property/BaseProjectProperty.java index f4c62a3f0..ca623c3c1 100644 --- a/hudson-core/src/main/java/org/hudsonci/model/project/property/BaseProjectProperty.java +++ b/hudson-core/src/main/java/org/hudsonci/model/project/property/BaseProjectProperty.java @@ -226,4 +226,30 @@ protected T prepareValue(T candidateValue) { public T getOriginalValue() { return originalValue; } + + /** + * {@inheritDoc} + */ + public final void onCascadingProjectChanged() { + if (getJob().hasCascadingProject()) { + onCascadingProjectSet(); + } else { + onCascadingProjectRemoved(); + } + } + + /** + * Executes when cascading parent is cleared. Default implementation marks property as not overridden. + */ + protected void onCascadingProjectRemoved() { + setOverridden(false); + } + + /** + * Executes when cascading project is set. Default implementation compares cascading and current value. + * If values are not equal - mark property as overridden. + */ + protected void onCascadingProjectSet() { + setOverridden(allowOverrideValue(getCascadingValue(), getValue())); + } } diff --git a/hudson-core/src/main/java/org/hudsonci/model/project/property/ExternalProjectProperty.java b/hudson-core/src/main/java/org/hudsonci/model/project/property/ExternalProjectProperty.java index 2af80eae7..51e7940db 100644 --- a/hudson-core/src/main/java/org/hudsonci/model/project/property/ExternalProjectProperty.java +++ b/hudson-core/src/main/java/org/hudsonci/model/project/property/ExternalProjectProperty.java @@ -76,4 +76,12 @@ public boolean isModified() { protected boolean updateOriginalValue(T value, T cascadingValue) { return isModified() && super.updateOriginalValue(value, cascadingValue); } + + /** + * {@inheritDoc} + */ + @Override + protected void onCascadingProjectSet() { + setOverridden(isModified()); + } } diff --git a/hudson-core/src/main/java/org/hudsonci/model/project/property/SCMProjectProperty.java b/hudson-core/src/main/java/org/hudsonci/model/project/property/SCMProjectProperty.java index 8288361d0..983d4bc52 100644 --- a/hudson-core/src/main/java/org/hudsonci/model/project/property/SCMProjectProperty.java +++ b/hudson-core/src/main/java/org/hudsonci/model/project/property/SCMProjectProperty.java @@ -40,8 +40,19 @@ public SCMProjectProperty(IJob job) { super(job); } + /** + * {@inheritDoc} + */ @Override public SCM getDefaultValue() { return new NullSCM(); } + + /** + * {@inheritDoc} + */ + @Override + protected boolean returnOriginalValue() { + return isOverridden() || (null != getOriginalValue() && !getDefaultValue().equals(getOriginalValue())); + } } \ No newline at end of file diff --git a/hudson-core/src/main/java/org/hudsonci/model/project/property/TriggerProjectProperty.java b/hudson-core/src/main/java/org/hudsonci/model/project/property/TriggerProjectProperty.java index 6d057bf6c..3732f8638 100644 --- a/hudson-core/src/main/java/org/hudsonci/model/project/property/TriggerProjectProperty.java +++ b/hudson-core/src/main/java/org/hudsonci/model/project/property/TriggerProjectProperty.java @@ -42,4 +42,15 @@ public TriggerProjectProperty(IJob job) { protected void clearOriginalValue(Trigger originalValue) { setOriginalValue(originalValue, false); } + + /** + * {@inheritDoc} + */ + @Override + protected void onCascadingProjectRemoved() { + if (isOverridden() && null != getValue()) { + getValue().stop(); + resetValue(); + } + } } diff --git a/hudson-core/src/test/java/org/hudsonci/model/project/property/BaseProjectPropertyTest.java b/hudson-core/src/test/java/org/hudsonci/model/project/property/BaseProjectPropertyTest.java index 3fd4abab2..39b38dc0f 100644 --- a/hudson-core/src/test/java/org/hudsonci/model/project/property/BaseProjectPropertyTest.java +++ b/hudson-core/src/test/java/org/hudsonci/model/project/property/BaseProjectPropertyTest.java @@ -30,12 +30,7 @@ import org.junit.Before; import org.junit.Test; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertNotNull; -import static junit.framework.Assert.assertNull; -import static junit.framework.Assert.assertTrue; -import static junit.framework.Assert.fail; +import static junit.framework.Assert.*; /** * Contains test-cases for {@link BaseProjectProperty}. @@ -49,8 +44,10 @@ public class BaseProjectPropertyTest { private final String propertyKey = "propertyKey"; private BaseProjectProperty property; + private BaseProjectProperty parentProperty; private FreeStyleProjectMock project; private FreeStyleProjectMock parent; + private String parentPropertyValue = "parentValue"; @Before public void setUp() { @@ -59,6 +56,10 @@ public void setUp() { property = new BaseProjectProperty(project); property.setKey(propertyKey); + parentProperty = new BaseProjectProperty(parent); + parentProperty.setKey(propertyKey); + parentProperty.setValue(parentPropertyValue); + parent.putProjectProperty(propertyKey, parentProperty); } /** @@ -135,7 +136,7 @@ public void testAllowOverrideValue() { */ @Test public void testGetCascadingValue() { - String parentValue = "parentValue"; + parentProperty.setValue(null); //If project doesn't have cascading project - default value is used as cascading value. assertEquals(property.getDefaultValue(), property.getCascadingValue()); @@ -145,14 +146,10 @@ public void testGetCascadingValue() { //If project has cascading project and cascading value is not set - default value is used. assertEquals(property.getDefaultValue(), property.getCascadingValue()); - BaseProjectProperty parentProperty = new BaseProjectProperty(parent); - parentProperty.setKey(propertyKey); - parentProperty.setValue(parentValue); - parent.putProjectProperty(propertyKey, parentProperty); project.setCascadingProject(parent); property = new BaseProjectProperty(project); property.setKey(propertyKey); - property.setValue(parentValue); + property.setValue(parentPropertyValue); //If project has cascading project and cascading value is set - property value will be used. assertEquals(parentProperty.getOriginalValue(), property.getCascadingValue()); } @@ -255,9 +252,6 @@ public void testReturnOriginalValue() { */ @Test public void testSetValue() { - BaseProjectProperty property = new BaseProjectProperty(project); - property.setKey(propertyKey); - property.setValue(null); //If project doesn't have cascading - default boolean value is used for propertyOverridden flag assertFalse(property.isOverridden()); assertNull(property.getOriginalValue()); @@ -268,11 +262,6 @@ public void testSetValue() { assertFalse(property.isOverridden()); assertEquals(value, property.getOriginalValue()); - String parentValue = "equalValue"; - BaseProjectProperty parentProperty = new BaseProjectProperty(parent); - parentProperty.setKey(propertyKey); - parentProperty.setValue(parentValue); - parent.putProjectProperty(propertyKey, parentProperty); project.setCascadingProject(parent); //If value set to null, need to check whether default value is equals to cascading @@ -285,7 +274,7 @@ public void testSetValue() { //Check whether current value is not null, after setting equal-to-cascading value current will be null assertNotNull(property.getOriginalValue()); assertTrue(property.isOverridden()); - property.setValue(parentValue); + property.setValue(parentPropertyValue); //Reset current property to null assertNull(property.getOriginalValue()); //Cascading value is equal to current - reset flag to false. @@ -356,28 +345,74 @@ public void testUpdateOriginalValue() { */ @Test public void testGetValue() { - Integer propertyValue = 10; - property.setValue(propertyValue); + property.setValue(parentPropertyValue); //if value is not null - return it - assertEquals(propertyValue, property.getValue()); + assertEquals(parentPropertyValue, property.getValue()); property.setValue(null); assertNull(property.getValue()); - BaseProjectProperty parentProperty = new BaseProjectProperty(parent); - parentProperty.setKey(propertyKey); - parentProperty.setValue(propertyValue); - parent.putProjectProperty(propertyKey, parentProperty); - + parentProperty.setValue(parentPropertyValue); project.setCascadingProject(parent); property = new BaseProjectProperty(project); property.setKey(propertyKey); //if current value is null and is not overridden value, take from cascading assertNull(property.getOriginalValue()); - assertEquals(propertyValue, property.getValue()); + assertEquals(parentPropertyValue, property.getValue()); property.setOverridden(true); //Property is overridden - return current value even if it is null. assertNull(property.getOriginalValue()); assertNull(property.getValue()); } + + /** + * Verify {@link BaseProjectProperty#onCascadingProjectRemoved()} method. + */ + @Test + public void testOnCascadingProjectRemoved() { + //Overridden flag should be set to false when cascading project was removed + property.setOverridden(true); + property.onCascadingProjectRemoved(); + assertFalse(property.isOverridden()); + } + + /** + * Verify {@link BaseProjectProperty#onCascadingProjectRemoved()} method. + */ + @Test + public void testOnCascadingProjectSet() { + property.setValue(parentPropertyValue); + project.setCascadingProject(parent); + //If parent value equals to current value - isOverridden flag should be set to false. + property.setOverridden(true); + assertTrue(property.isOverridden()); + assertFalse(property.allowOverrideValue(parentProperty.getOriginalValue(), property.getValue())); + property.onCascadingProjectSet(); + assertFalse(property.isOverridden()); + + property.setValue("newValue"); + assertTrue(property.allowOverrideValue(parentProperty.getOriginalValue(), property.getValue())); + property.onCascadingProjectSet(); + assertTrue(property.isOverridden()); + } + + /** + * Verify {@link BaseProjectProperty#onCascadingProjectChanged()} method. + */ + @Test + public void testOnCascadingProjectChanged() { + //Overridden flag should be set to false when cascading project was removed + property.setOverridden(true); + property.onCascadingProjectChanged(); + assertFalse(property.isOverridden()); + + property.setValue(parentPropertyValue); + project.setCascadingProject(parent); + //If parent value equals to current value - isOverridden flag should be set to false. + property.setOverridden(true); + assertTrue(property.isOverridden()); + assertFalse(property.allowOverrideValue(parentProperty.getOriginalValue(), property.getValue())); + property.onCascadingProjectChanged(); + assertFalse(property.isOverridden()); + } } diff --git a/hudson-core/src/test/java/org/hudsonci/model/project/property/ExternalProjectPropertyTest.java b/hudson-core/src/test/java/org/hudsonci/model/project/property/ExternalProjectPropertyTest.java index 919ad3711..b01727fab 100644 --- a/hudson-core/src/test/java/org/hudsonci/model/project/property/ExternalProjectPropertyTest.java +++ b/hudson-core/src/test/java/org/hudsonci/model/project/property/ExternalProjectPropertyTest.java @@ -27,10 +27,7 @@ import org.junit.Before; import org.junit.Test; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertTrue; -import static junit.framework.Assert.fail; +import static junit.framework.Assert.*; /** * Contains test-cases for {@link ExternalProjectProperty}. @@ -81,6 +78,22 @@ public void testUpdateOriginalValue() { assertTrue(property.isModified()); assertFalse(property.updateOriginalValue(new Object(), new Object())); assertTrue(property.updateOriginalValue(new Object(), project)); + } + /** + * Verify {@link ExternalProjectProperty#onCascadingProjectSet()} method. + */ + @Test + public void testOnCascadingProjectSet() { + assertFalse(property.isModified()); + assertFalse(property.isOverridden()); + //When cascading project was set, isModified should equal to isOverridden + property.onCascadingProjectSet(); + assertEquals(property.isModified(), property.isOverridden()); + + property.setModified(Boolean.TRUE); + property.onCascadingProjectSet(); + assertTrue(property.isModified()); + assertEquals(property.isModified(), property.isOverridden()); } } diff --git a/hudson-core/src/test/java/org/hudsonci/model/project/property/ProjectPropertyTest.java b/hudson-core/src/test/java/org/hudsonci/model/project/property/ProjectPropertyTest.java index c10898a99..7a2b2c673 100644 --- a/hudson-core/src/test/java/org/hudsonci/model/project/property/ProjectPropertyTest.java +++ b/hudson-core/src/test/java/org/hudsonci/model/project/property/ProjectPropertyTest.java @@ -23,32 +23,12 @@ */ package org.hudsonci.model.project.property; -import antlr.ANTLRException; -import hudson.FilePath; -import hudson.Launcher; -import hudson.model.AbstractBuild; -import hudson.model.AbstractProject; -import hudson.model.BuildListener; import hudson.model.FreeStyleProjectMock; -import hudson.model.TaskListener; -import hudson.scm.ChangeLogParser; -import hudson.scm.NullSCM; -import hudson.scm.PollingResult; -import hudson.scm.SCM; -import hudson.scm.SCMRevisionState; import hudson.tasks.LogRotator; -import hudson.triggers.TimerTrigger; -import hudson.triggers.Trigger; -import java.io.File; -import java.io.IOException; import org.junit.Before; import org.junit.Test; -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertFalse; -import static junit.framework.Assert.assertNull; -import static junit.framework.Assert.assertTrue; -import static junit.framework.Assert.fail; +import static junit.framework.Assert.*; /** * Contains test-cases for IProjectProperty and its' implementations. @@ -107,26 +87,6 @@ public void testLogRotatorProjectPropertyConstructor() { } } - @Test - public void testSCMProjectPropertyConstructor() { - try { - new SCMProjectProperty(null); - fail("Null should be handled by SCMProjectProperty constructor."); - } catch (Exception e) { - assertEquals(BaseProjectProperty.INVALID_JOB_EXCEPTION, e.getMessage()); - } - } - - @Test - public void testTriggerProjectPropertyConstructor() { - try { - new TriggerProjectProperty(null); - fail("Null should be handled by TriggerProjectProperty constructor."); - } catch (Exception e) { - assertEquals(BaseProjectProperty.INVALID_JOB_EXCEPTION, e.getMessage()); - } - } - @Test public void testBooleanProjectPropertyPrepareValue() { //Boolean property acts as BaseProperty @@ -165,15 +125,6 @@ public void testStringProjectPropertyPrepareValue() { assertEquals("abc", property.prepareValue(" abc ")); } - @Test - public void testSCMProjectPropertyPrepareValue() { - //Boolean property acts as BaseProperty - BaseProjectProperty property = new SCMProjectProperty(project); - assertNull(property.prepareValue(null)); - SCM value = new NullSCM(); - assertEquals(value, property.prepareValue(value)); - } - @Test public void testStringProjectPropertyGetDefaultValue() { BaseProjectProperty property = new StringProjectProperty(project); @@ -198,12 +149,6 @@ public void testLogRotatorProjectPropertyGetDefaultValue() { assertNull(property.getDefaultValue()); } - @Test - public void testScmProjectPropertyGetDefaultValue() { - BaseProjectProperty property = new SCMProjectProperty(project); - assertEquals(new NullSCM(), property.getDefaultValue()); - } - @Test public void testBooleanProjectPropertyAllowOverrideValue() { BaseProjectProperty property = new BooleanProjectProperty(project); @@ -244,15 +189,6 @@ public void testLogRotatorProjectPropertyAllowOverrideValue() { assertTrue(property.allowOverrideValue(new LogRotator(1, 1, 1, 2), new LogRotator(1, 1, 1, 1))); } - @Test - public void testSCMProjectPropertyAllowOverrideValue() { - BaseProjectProperty property = new SCMProjectProperty(project); - assertFalse(property.allowOverrideValue(null, null)); - assertTrue(property.allowOverrideValue(new NullSCM(), null)); - assertTrue(property.allowOverrideValue(null, new NullSCM())); - assertTrue(property.allowOverrideValue(new NullSCM(), new FakeSCM())); - } - @Test public void testIntegerProjectPropertyGetOriginalValue() { int value = 10; @@ -290,65 +226,4 @@ public void testLogRotatorProjectPropertyGetOriginalValue() { property.setValue(value); assertEquals(value, property.getOriginalValue()); } - - @Test - public void testScmProjectPropertyGetOriginalValue() { - SCM value = new NullSCM(); - BaseProjectProperty property = new SCMProjectProperty(project); - property.setKey(propertyKey); - property.setValue(value); - assertEquals(value, property.getOriginalValue()); - } - - /** - * Test 1updateOriginalValue method for TriggerProjectProperty. - * - * @throws ANTLRException if any - */ - @Test - public void testTriggerProjectPropertyUpdateOriginalValue() throws ANTLRException { - TriggerProjectProperty property = new TriggerProjectProperty(project); - Trigger originalTrigger = new TimerTrigger("* * * * *"); - Trigger cascadingTrigger = new TimerTrigger("* * * * *"); - property.updateOriginalValue(originalTrigger, cascadingTrigger); - //Property isn't overridden because of values equal. - assertFalse(property.isOverridden()); - //If trigger property value equals to cascading be sure that sets original value instead of cascading. - assertEquals(property.getOriginalValue(), originalTrigger); - - cascadingTrigger = new TimerTrigger("*/2 * * * *"); - property.updateOriginalValue(originalTrigger, cascadingTrigger); - assertTrue(property.isOverridden()); - assertEquals(property.getOriginalValue(), originalTrigger); - } - - private class FakeSCM extends SCM { - @Override - public SCMRevisionState calcRevisionsFromBuild(AbstractBuild build, Launcher launcher, - TaskListener listener) - throws IOException, InterruptedException { - return null; - } - - @Override - protected PollingResult compareRemoteRevisionWith(AbstractProject project, Launcher launcher, - FilePath workspace, TaskListener listener, - SCMRevisionState baseline) - throws IOException, InterruptedException { - return null; - } - - @Override - public boolean checkout(AbstractBuild build, Launcher launcher, FilePath workspace, - BuildListener listener, - File changelogFile) throws IOException, InterruptedException { - return false; - } - - @Override - public ChangeLogParser createChangeLogParser() { - return null; - } - } - } diff --git a/hudson-core/src/test/java/org/hudsonci/model/project/property/SCMProjectPropertyTest.java b/hudson-core/src/test/java/org/hudsonci/model/project/property/SCMProjectPropertyTest.java new file mode 100644 index 000000000..88b042540 --- /dev/null +++ b/hudson-core/src/test/java/org/hudsonci/model/project/property/SCMProjectPropertyTest.java @@ -0,0 +1,135 @@ +/* + * The MIT License + * + * Copyright (c) 2011, Oracle Corporation, Nikita Levyankov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.hudsonci.model.project.property; + +import hudson.FilePath; +import hudson.Launcher; +import hudson.model.AbstractBuild; +import hudson.model.AbstractProject; +import hudson.model.BuildListener; +import hudson.model.FreeStyleProjectMock; +import hudson.model.TaskListener; +import hudson.scm.ChangeLogParser; +import hudson.scm.NullSCM; +import hudson.scm.PollingResult; +import hudson.scm.SCM; +import hudson.scm.SCMRevisionState; +import java.io.File; +import java.io.IOException; +import org.junit.Before; +import org.junit.Test; + +import static junit.framework.Assert.*; + +/** + * Contains test-cases for {@link SCMProjectProperty}. + *

+ * Date: 11/17/11 + * + * @author Nikita Levyankov + */ +public class SCMProjectPropertyTest { + + private SCMProjectProperty property; + private FreeStyleProjectMock project; + + @Before + public void setUp() { + project = new FreeStyleProjectMock("project"); + final String propertyKey = "propertyKey"; + property = new SCMProjectProperty(project); + property.setKey(propertyKey); + } + + /** + * Verify constructor + */ + @Test + public void testConstructor() { + try { + new SCMProjectProperty(null); + fail("Null should be handled by SCMProjectProperty constructor."); + } catch (Exception e) { + assertEquals(BaseProjectProperty.INVALID_JOB_EXCEPTION, e.getMessage()); + } + } + + /** + * Verify {@link SCMProjectProperty#getDefaultValue()} method. + */ + @Test + public void testGetDefaultValue() { + assertEquals(new NullSCM(), property.getDefaultValue()); + } + + /** + * Verify {@link SCMProjectProperty#returnOriginalValue()} method. + */ + @Test + public void testReturnOriginalValue() { + //If property is marked as overridden or original value is not null and not equals to default value, + //than original should be used. + property.setOverridden(true); + assertTrue(property.returnOriginalValue()); + property.setOriginalValue(new FakeSCM(), false); + assertTrue(property.returnOriginalValue()); + + //If property is not marked as overridden and original value is null or equals to default value - use cascading. + property.setOriginalValue(property.getDefaultValue(), false); + assertFalse(property.returnOriginalValue()); + property.setOriginalValue(null, false); + assertFalse(property.returnOriginalValue()); + + } + + private class FakeSCM extends SCM { + @Override + public SCMRevisionState calcRevisionsFromBuild(AbstractBuild build, Launcher launcher, + TaskListener listener) + throws IOException, InterruptedException { + return null; + } + + @Override + protected PollingResult compareRemoteRevisionWith(AbstractProject project, Launcher launcher, + FilePath workspace, TaskListener listener, + SCMRevisionState baseline) + throws IOException, InterruptedException { + return null; + } + + @Override + public boolean checkout(AbstractBuild build, Launcher launcher, FilePath workspace, + BuildListener listener, + File changelogFile) throws IOException, InterruptedException { + return false; + } + + @Override + public ChangeLogParser createChangeLogParser() { + return null; + } + } + +} diff --git a/hudson-core/src/test/java/org/hudsonci/model/project/property/TriggerProjectPropertyTest.java b/hudson-core/src/test/java/org/hudsonci/model/project/property/TriggerProjectPropertyTest.java new file mode 100644 index 000000000..cd4bcb30d --- /dev/null +++ b/hudson-core/src/test/java/org/hudsonci/model/project/property/TriggerProjectPropertyTest.java @@ -0,0 +1,119 @@ +/* + * The MIT License + * + * Copyright (c) 2011, Oracle Corporation, Nikita Levyankov + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package org.hudsonci.model.project.property; + +import antlr.ANTLRException; +import hudson.model.FreeStyleProjectMock; +import hudson.triggers.TimerTrigger; +import hudson.triggers.Trigger; +import org.junit.Before; +import org.junit.Test; + +import static junit.framework.Assert.*; + +/** + * Contains test-cases for {@link TriggerProjectProperty}. + *

+ * Date: 11/17/11 + * + * @author Nikita Levyankov + */ +public class TriggerProjectPropertyTest { + + private TriggerProjectProperty property; + + @Before + public void setUp() { + final String propertyKey = "propertyKey"; + FreeStyleProjectMock project = new FreeStyleProjectMock("project"); + property = new TriggerProjectProperty(project); + property.setKey(propertyKey); + } + + @Test + public void testConstructor() { + try { + new TriggerProjectProperty(null); + fail("Null should be handled by TriggerProjectProperty constructor."); + } catch (Exception e) { + assertEquals(BaseProjectProperty.INVALID_JOB_EXCEPTION, e.getMessage()); + } + } + + /** + * Verify {@link TriggerProjectProperty#clearOriginalValue(hudson.triggers.Trigger)} method. + * + * @throws antlr.ANTLRException if any + */ + @Test + public void testClearOriginalValue() throws ANTLRException { + //Overridden flag should be cleared to false. Pre-set true value + property.setOverridden(true); + assertTrue(property.isOverridden()); + Trigger trigger = new TimerTrigger("* * * * *"); + property.clearOriginalValue(trigger); + //Original value should be set with overridden flag == false + assertFalse(property.isOverridden()); + assertTrue(trigger == property.getOriginalValue()); + } + + + /** + * Test updateOriginalValue method for TriggerProjectProperty. + * + * @throws antlr.ANTLRException if any + */ + @Test + public void testUpdateOriginalValue() throws ANTLRException { + Trigger originalTrigger = new TimerTrigger("* * * * *"); + Trigger cascadingTrigger = new TimerTrigger("* * * * *"); + property.updateOriginalValue(originalTrigger, cascadingTrigger); + //Property isn't overridden because of values equal. + assertFalse(property.isOverridden()); + //If trigger property value equals to cascading be sure that sets original value instead of cascading. + assertEquals(property.getOriginalValue(), originalTrigger); + + cascadingTrigger = new TimerTrigger("*/2 * * * *"); + property.updateOriginalValue(originalTrigger, cascadingTrigger); + assertTrue(property.isOverridden()); + assertEquals(property.getOriginalValue(), originalTrigger); + } + + /** + * Verify {@link TriggerProjectProperty#onCascadingProjectRemoved()} method. + * + * @throws antlr.ANTLRException if any + */ + @Test + public void testOnCascadingProjectRemoved() throws ANTLRException { + Trigger trigger = new TimerTrigger("* * * * *"); + property.setOriginalValue(trigger, false); + assertTrue(trigger == property.getOriginalValue()); + assertFalse(property.isOverridden()); + property.onCascadingProjectRemoved(); + assertFalse(property.isOverridden()); + assertTrue(trigger == property.getOriginalValue()); + } + +}