diff --git a/src/main/java/com/amazon/jenkins/ec2fleet/AbstractEC2FleetCloud.java b/src/main/java/com/amazon/jenkins/ec2fleet/AbstractEC2FleetCloud.java index a9b9c779..7f132c22 100644 --- a/src/main/java/com/amazon/jenkins/ec2fleet/AbstractEC2FleetCloud.java +++ b/src/main/java/com/amazon/jenkins/ec2fleet/AbstractEC2FleetCloud.java @@ -17,8 +17,4 @@ protected AbstractEC2FleetCloud(String name) { public abstract boolean hasExcessCapacity(); public abstract boolean scheduleToTerminate(String instanceId, boolean ignoreMinConstraints, EC2AgentTerminationReason reason); - - public abstract String getOldId(); - - public abstract String getFleet(); } diff --git a/src/main/java/com/amazon/jenkins/ec2fleet/EC2FleetCloud.java b/src/main/java/com/amazon/jenkins/ec2fleet/EC2FleetCloud.java index a9d82f61..c851946f 100644 --- a/src/main/java/com/amazon/jenkins/ec2fleet/EC2FleetCloud.java +++ b/src/main/java/com/amazon/jenkins/ec2fleet/EC2FleetCloud.java @@ -4,7 +4,6 @@ import com.amazon.jenkins.ec2fleet.aws.RegionHelper; import com.amazon.jenkins.ec2fleet.fleet.EC2Fleet; import com.amazon.jenkins.ec2fleet.fleet.EC2Fleets; -import com.amazon.jenkins.ec2fleet.utils.EC2FleetCloudAwareUtils; import com.amazonaws.services.ec2.AmazonEC2; import com.amazonaws.services.ec2.model.Instance; import com.amazonaws.services.ec2.model.InstanceStateName; @@ -13,6 +12,7 @@ import hudson.Extension; import hudson.model.Computer; import hudson.model.Descriptor; +import hudson.model.Failure; import hudson.model.Label; import hudson.model.Node; import hudson.model.Queue; @@ -86,25 +86,6 @@ public class EC2FleetCloud extends AbstractEC2FleetCloud { private static final Logger LOGGER = Logger.getLogger(EC2FleetCloud.class.getName()); private static final ScheduledExecutorService EXECUTOR = Executors.newSingleThreadScheduledExecutor(); - // Counter to keep track of planned nodes per EC2FleetCloud, used in node's display name - private transient AtomicInteger plannedNodeCounter = new AtomicInteger(1); - - /** - * Provide unique identifier for this instance of {@link EC2FleetCloud}, transient - * will not be stored. Not available for customer, instead use {@link EC2FleetCloud#name} - * will be used only during Jenkins configuration update config.jelly, - * when new instance of same cloud is created and we need to find old instance and - * repoint resources like {@link Computer} {@link Node} etc. - *

- * It's lazy to support old versions which don't have this field at all. - *

- * However it's stable, as soon as it will be created and called first uuid will be same - * for all future calls to the same instances of lazy uuid. - * - * @see EC2FleetCloudAware - */ - private transient LazyUuid id; - /** * Replaced with {@link EC2FleetCloud#awsCredentialsId} *

@@ -178,9 +159,11 @@ public class EC2FleetCloud extends AbstractEC2FleetCloud { private transient ArrayList> plannedNodeScheduledFutures; + // Counter to keep track of planned nodes per EC2FleetCloud, used in node's display name + private transient AtomicInteger plannedNodeCounter = new AtomicInteger(1); + @DataBoundConstructor public EC2FleetCloud(final String name, - final String oldId, final String awsCredentialsId, final @Deprecated String credentialsId, final String region, @@ -238,8 +221,6 @@ public EC2FleetCloud(final String name, if (fleet != null) { this.stats = EC2Fleets.get(fleet).getState( getAwsCredentialsId(), region, endpoint, getFleet()); - // Reassign existing nodes/computer with new reference of cloud - EC2FleetCloudAwareUtils.reassign(fleet, this); } } @@ -259,16 +240,6 @@ public String getAwsCredentialsId() { return StringUtils.isNotBlank(awsCredentialsId) ? awsCredentialsId : credentialsId; } - /** - * Called old as will be used by new instance of cloud, for - * which this id is old (not current) - * - * @return id of current cloud - */ - public String getOldId() { - return id.getValue(); - } - public boolean isDisableTaskResubmit() { return disableTaskResubmit; } @@ -298,7 +269,6 @@ public String getEndpoint() { return endpoint; } - @Override public String getFleet() { return fleet; } @@ -419,6 +389,15 @@ private synchronized int getNextPlannedNodeCounter() { @Override public synchronized Collection provision(@Nonnull final Cloud.CloudState cloudState, final int excessWorkload) { + Jenkins jenkinsInstance = Jenkins.get(); + if (jenkinsInstance.isQuietingDown()) { + LOGGER.log(Level.FINE, "Not provisioning nodes, Jenkins instance is quieting down"); + return Collections.emptyList(); + } else if (jenkinsInstance.isTerminating()) { + LOGGER.log(Level.FINE, "Not provisioning nodes, Jenkins instance is terminating"); + return Collections.emptyList(); + } + fine("excessWorkload %s", excessWorkload); if (stats == null) { @@ -469,6 +448,7 @@ public synchronized Collection provision(@Nonnull f // This protects us from leaving planned nodes stranded within Jenkins NodeProvisioner when the Fleet // is updated or removed before it can scale. After scaling, EC2FleetOnlineChecker will cancel the future // if something happens to the Fleet. + // TODO: refactor to consolidate logic with EC2FleetOnlineChecker final ScheduledFuture scheduledFuture = EXECUTOR.schedule(() -> { if (completableFuture.isDone()) { return; @@ -644,7 +624,7 @@ public void run() { final Set jenkinsInstances = new HashSet<>(); for (final Node node : jenkins.getNodes()) { - if (node instanceof EC2FleetNode && ((EC2FleetNode) node).getCloud().getFleet().equals(fleet)) { + if (node instanceof EC2FleetNode && ((EC2FleetCloud)((EC2FleetNode) node).getCloud()).getFleet().equals(fleet)) { jenkinsInstances.add(node.getNodeName()); } } @@ -776,7 +756,6 @@ public synchronized boolean scheduleToTerminate(final String instanceId, final b @Override public boolean canProvision(final Cloud.CloudState cloudState) { final Label label = cloudState.getLabel(); - fine("CanProvision called on fleet: \"" + this.labelString + "\" wanting: \"" + (label == null ? "(unspecified)" : label.getName()) + "\"."); if (fleet == null) { fine("Fleet/ASG for cloud is null, returning false"); return false; @@ -786,7 +765,7 @@ public boolean canProvision(final Cloud.CloudState cloudState) { return false; } if (label != null && !Label.parse(this.labelString).containsAll(label.listAtoms())) { - fine("Label '%s' not found within Fleet's labels '%s', returning false", label, this.labelString); + finer("Label '%s' not found within Fleet's labels '%s', returning false", label, this.labelString); return false; } return true; @@ -798,8 +777,6 @@ private Object readResolve() { } private void init() { - id = new LazyUuid(); - plannedNodesCache = new HashSet<>(); instanceIdsToTerminate = new HashMap<>(); plannedNodeScheduledFutures = new ArrayList<>(); @@ -864,7 +841,7 @@ private void addNewAgent(final AmazonEC2 ec2, final Instance instance, FleetStat final Node.Mode nodeMode = restrictUsage ? Node.Mode.EXCLUSIVE : Node.Mode.NORMAL; final EC2FleetNode node = new EC2FleetNode(instanceId, "Fleet agent for " + instanceId, effectiveFsRoot, effectiveNumExecutors, nodeMode, labelString, new ArrayList>(), - this, computerLauncher, maxTotalUses); + this.name, computerLauncher, maxTotalUses); // Initialize our retention strategy node.setRetentionStrategy(new EC2RetentionStrategy()); @@ -905,7 +882,7 @@ private int getCurrentSpareInstanceCount(final FleetStateStats currentState, fin } // Do not count computer if it is not a part of the given fleet - if (!Objects.equals(((EC2FleetNodeComputer) computer).getCloud().getFleet(), currentState.getFleetId())) { + if (!Objects.equals(((EC2FleetCloud)((EC2FleetNodeComputer) computer).getCloud()).getFleet(), currentState.getFleetId())) { continue; } currentBusyInstances++; @@ -928,6 +905,10 @@ private void fine(final String msg, final Object... args) { LOGGER.fine(getLogPrefix() + String.format(msg, args)); } + private void finer(final String msg, final Object... args) { + LOGGER.finer(getLogPrefix() + String.format(msg, args)); + } + private void warning(final String msg, final Object... args) { LOGGER.warning(getLogPrefix() + String.format(msg, args)); } @@ -936,6 +917,11 @@ private void warning(final Throwable t, final String msg, final Object... args) LOGGER.log(Level.WARNING, getLogPrefix() + String.format(msg, args), t); } + @Override + public DescriptorImpl getDescriptor() { + return (DescriptorImpl) super.getDescriptor(); + } + @Extension @SuppressWarnings("unused") public static class DescriptorImpl extends Descriptor { @@ -972,6 +958,15 @@ public FormValidation doCheckMaxTotalUses(@QueryParameter String value) { return FormValidation.error("Maximum Total Uses must be greater or equal to -1"); } + public FormValidation doCheckCloudName(@QueryParameter final String name) { + try { + Jenkins.checkGoodName(name); + } catch (Failure e) { + return FormValidation.error(e.getMessage()); + } + return FormValidation.ok(); + } + public ListBoxModel doFillFleetItems(@QueryParameter final boolean showAllFleets, @QueryParameter final String region, @QueryParameter final String endpoint, @@ -985,7 +980,7 @@ public ListBoxModel doFillFleetItems(@QueryParameter final boolean showAllFleets awsCredentialsId, region, endpoint, model, fleet, showAllFleets); } } catch (final Exception ex) { - LOGGER.log(Level.WARNING, String.format("Cannot describe fleets in %s or by endpoint %s", region, endpoint), ex); + LOGGER.log(Level.WARNING, String.format("Cannot describe fleets in '%s' or by endpoint '%s'", region, endpoint), ex); return model; } @@ -1026,7 +1021,5 @@ public boolean configure(final StaplerRequest req, final JSONObject formData) th save(); return super.configure(req, formData); } - } - } diff --git a/src/main/java/com/amazon/jenkins/ec2fleet/EC2FleetCloudAware.java b/src/main/java/com/amazon/jenkins/ec2fleet/EC2FleetCloudAware.java deleted file mode 100644 index 1694a849..00000000 --- a/src/main/java/com/amazon/jenkins/ec2fleet/EC2FleetCloudAware.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.amazon.jenkins.ec2fleet; - -import javax.annotation.Nonnull; - -/** - * Interface to mark object that it's require cloud change update. Jenkins always creates - * new instance of {@link hudson.slaves.Cloud} each time when you save Jenkins configuration page - * regardless of was it actually changed or not. - *

- * Jenkins never mutate existent {@link hudson.slaves.Cloud} instance - *

- * As result all objects which depends on info from cloud - * should be start to consume new instance of object to be able get new configuration if any. - *

- * {@link EC2FleetCloud} is responsible to update all dependencies with new reference - */ -public interface EC2FleetCloudAware { - - AbstractEC2FleetCloud getCloud(); - - void setCloud(@Nonnull AbstractEC2FleetCloud cloud); - -} diff --git a/src/main/java/com/amazon/jenkins/ec2fleet/EC2FleetLabelCloud.java b/src/main/java/com/amazon/jenkins/ec2fleet/EC2FleetLabelCloud.java index 1eb1c696..03177986 100644 --- a/src/main/java/com/amazon/jenkins/ec2fleet/EC2FleetLabelCloud.java +++ b/src/main/java/com/amazon/jenkins/ec2fleet/EC2FleetLabelCloud.java @@ -6,7 +6,6 @@ import com.amazon.jenkins.ec2fleet.aws.RegionHelper; import com.amazon.jenkins.ec2fleet.fleet.EC2Fleets; import com.amazon.jenkins.ec2fleet.fleet.EC2SpotFleet; -import com.amazon.jenkins.ec2fleet.utils.EC2FleetCloudAwareUtils; import com.amazonaws.services.cloudformation.AmazonCloudFormation; import com.amazonaws.services.cloudformation.model.StackStatus; import com.amazonaws.services.ec2.AmazonEC2; @@ -16,7 +15,6 @@ import com.cloudbees.jenkins.plugins.awscredentials.AWSCredentialsHelper; import hudson.Extension; import hudson.model.AbstractProject; -import hudson.model.Computer; import hudson.model.Descriptor; import hudson.model.Item; import hudson.model.Label; @@ -75,22 +73,6 @@ public class EC2FleetLabelCloud extends AbstractEC2FleetCloud { private static final SimpleFormatter sf = new SimpleFormatter(); private static final Logger LOGGER = Logger.getLogger(EC2FleetLabelCloud.class.getName()); - /** - * Provide unique identifier for this instance of {@link EC2FleetLabelCloud}, transient - * will not be stored. Not available for customer, instead use {@link EC2FleetLabelCloud#name} - * will be used only during Jenkins configuration update config.jelly, - * when new instance of same cloud is created and we need to find old instance and - * repoint resources like {@link Computer} {@link Node} etc. - *

- * It's lazy to support old versions which don't have this field at all. - *

- * However it's stable, as soon as it will be created and called first uuid will be same - * for all future calls to the same instances of lazy uuid. - * - * @see EC2FleetCloudAware - */ - private transient LazyUuid id; - private final String awsCredentialsId; private final String region; private final String endpoint; @@ -123,7 +105,6 @@ public class EC2FleetLabelCloud extends AbstractEC2FleetCloud { @DataBoundConstructor public EC2FleetLabelCloud(final String name, - final String oldId, final String awsCredentialsId, final String region, final String endpoint, @@ -162,12 +143,6 @@ public EC2FleetLabelCloud(final String name, this.cloudStatusIntervalSec = cloudStatusIntervalSec; this.noDelayProvision = noDelayProvision; this.ec2KeyPairName = ec2KeyPairName; - - if (StringUtils.isNotEmpty(oldId)) { - // existent cloud was modified, let's re-assign all dependencies of old cloud instance - // to new one - EC2FleetCloudAwareUtils.reassign(oldId, this); - } } public String getEc2KeyPairName() { @@ -182,22 +157,6 @@ public String getAwsCredentialsId() { return awsCredentialsId; } - /** - * Called old as will be used by new instance of cloud, for - * which this id is old (not current) - * - * @return id of current cloud - */ - public String getOldId() { - return id.getValue(); - } - - @Override - public String getFleet() { - // TODO: We need a way to map existing node/computer's cloud reference rather than relying on oldId - return null; - } - public boolean isDisableTaskResubmit() { return disableTaskResubmit; } @@ -295,6 +254,15 @@ public synchronized boolean hasExcessCapacity() { @Override public synchronized Collection provision(@Nonnull final Cloud.CloudState cloudState, int excessWorkload) { + Jenkins jenkinsInstance = Jenkins.get(); + if (jenkinsInstance.isQuietingDown()) { + LOGGER.log(Level.FINE, "Not provisioning nodes, Jenkins instance is quieting down"); + return Collections.emptyList(); + } else if (jenkinsInstance.isTerminating()) { + LOGGER.log(Level.FINE, "Not provisioning nodes, Jenkins instance is terminating"); + return Collections.emptyList(); + } + info("excessWorkload %s", excessWorkload); final Label label = cloudState.getLabel(); @@ -608,7 +576,6 @@ private Object readResolve() { } private void init() { - id = new LazyUuid(); states = new HashMap<>(); } @@ -653,7 +620,7 @@ private void addNewAgent( //TODO: Add maxTotalUses to EC2FleetLabelCloud similar to EC2FleetCloud final EC2FleetNode node = new EC2FleetNode(instanceId, "Fleet agent for " + instanceId, effectiveFsRoot, effectiveNumExecutors, nodeMode, labelString, new ArrayList>(), - this, computerLauncher, -1); + this.name, computerLauncher, -1); // Initialize our retention strategy node.setRetentionStrategy(new EC2RetentionStrategy()); @@ -812,6 +779,11 @@ public void run() { } } + @Override + public EC2FleetLabelCloud.DescriptorImpl getDescriptor() { + return (EC2FleetLabelCloud.DescriptorImpl) super.getDescriptor(); + } + @Extension @SuppressWarnings("unused") public static class DescriptorImpl extends Descriptor { diff --git a/src/main/java/com/amazon/jenkins/ec2fleet/EC2FleetNode.java b/src/main/java/com/amazon/jenkins/ec2fleet/EC2FleetNode.java index a973a9a1..37b6b011 100644 --- a/src/main/java/com/amazon/jenkins/ec2fleet/EC2FleetNode.java +++ b/src/main/java/com/amazon/jenkins/ec2fleet/EC2FleetNode.java @@ -3,63 +3,55 @@ import hudson.Extension; import hudson.model.Computer; import hudson.model.Descriptor; +import hudson.model.Failure; import hudson.model.Node; import hudson.model.Slave; import hudson.slaves.ComputerLauncher; import hudson.slaves.EphemeralNode; import hudson.slaves.NodeProperty; import hudson.slaves.RetentionStrategy; +import jenkins.model.Jenkins; -import javax.annotation.Nonnull; import java.io.IOException; import java.util.List; +import java.util.logging.Logger; /** * The {@link EC2FleetNode} represents an agent running on an EC2 instance, responsible for creating {@link EC2FleetNodeComputer}. */ -public class EC2FleetNode extends Slave implements EphemeralNode, EC2FleetCloudAware { +public class EC2FleetNode extends Slave implements EphemeralNode { + private static final Logger LOGGER = Logger.getLogger(EC2FleetNode.class.getName()); - private volatile AbstractEC2FleetCloud cloud; + // TODO: Update cloud name on user-initiated change. + // Current mitigation in place: A warning message is include in cloud name field's description. + private String cloudName; + + private String instanceId; private final int maxTotalUses; private int usesRemaining; - public EC2FleetNode(final String name, final String nodeDescription, final String remoteFS, final int numExecutors, final Mode mode, final String label, - final List> nodeProperties, final AbstractEC2FleetCloud cloud, ComputerLauncher launcher, final int maxTotalUses) throws IOException, Descriptor.FormException { + public EC2FleetNode(final String instanceId, final String nodeDescription, final String remoteFS, final int numExecutors, final Mode mode, final String label, + final List> nodeProperties, final String cloudName, ComputerLauncher launcher, final int maxTotalUses) throws IOException, Descriptor.FormException { //noinspection deprecation - super(name, nodeDescription, remoteFS, numExecutors, mode, label, + super(instanceId, nodeDescription, remoteFS, numExecutors, mode, label, launcher, RetentionStrategy.NOOP, nodeProperties); - this.cloud = cloud; + + this.cloudName = cloudName; + this.instanceId = instanceId; this.maxTotalUses = maxTotalUses; this.usesRemaining = maxTotalUses; } - @Override - public Node asNode() { - return this; - } - - @Override - public String getDisplayName() { - // in some multi-thread edge cases cloud could be null for some time, just be ok with that - return (cloud == null ? "unknown fleet" : cloud.getDisplayName()) + " " + name; - } - - @Override - public Computer createComputer() { - return new EC2FleetNodeComputer(this, name, cloud); + public String getCloudName() { + return cloudName; } - @Override - public AbstractEC2FleetCloud getCloud() { - return cloud; + public String getInstanceId() { + return instanceId; } - /** - * {@inheritDoc} - */ - @Override - public void setCloud(@Nonnull AbstractEC2FleetCloud cloud) { - this.cloud = cloud; + public void setInstanceId(String instanceId) { + this.instanceId = instanceId; } public int getMaxTotalUses() { @@ -74,8 +66,38 @@ public void decrementUsesRemaining() { this.usesRemaining--; } + @Override + public Node asNode() { + return this; + } + + @Override + public String getDisplayName() { + final String name = String.format("%s %s", cloudName, instanceId); + try { + Jenkins.checkGoodName(name); + return name; + } catch (Failure e) { + return instanceId; + } + } + + @Override + public Computer createComputer() { + return new EC2FleetNodeComputer(this); + } + + public AbstractEC2FleetCloud getCloud() { + return (AbstractEC2FleetCloud) Jenkins.get().getCloud(cloudName); + } + + public DescriptorImpl getDescriptor() { + return (DescriptorImpl) super.getDescriptor(); + } + @Extension public static final class DescriptorImpl extends SlaveDescriptor { + public DescriptorImpl() { super(); } diff --git a/src/main/java/com/amazon/jenkins/ec2fleet/EC2FleetNodeComputer.java b/src/main/java/com/amazon/jenkins/ec2fleet/EC2FleetNodeComputer.java index 89d4599a..ec5e3125 100644 --- a/src/main/java/com/amazon/jenkins/ec2fleet/EC2FleetNodeComputer.java +++ b/src/main/java/com/amazon/jenkins/ec2fleet/EC2FleetNodeComputer.java @@ -1,29 +1,26 @@ package com.amazon.jenkins.ec2fleet; -import hudson.model.Slave; import hudson.slaves.SlaveComputer; import org.apache.commons.lang.StringUtils; import org.kohsuke.stapler.HttpResponse; +import javax.annotation.CheckForNull; import javax.annotation.Nonnull; import javax.annotation.concurrent.ThreadSafe; import java.io.IOException; +import java.util.logging.Logger; /** * The {@link EC2FleetNodeComputer} represents the running state of {@link EC2FleetNode} that holds executors. * @see hudson.model.Computer */ @ThreadSafe -public class EC2FleetNodeComputer extends SlaveComputer implements EC2FleetCloudAware { - - private final String name; - private volatile AbstractEC2FleetCloud cloud; +public class EC2FleetNodeComputer extends SlaveComputer { + private static final Logger LOGGER = Logger.getLogger(EC2FleetNodeComputer.class.getName()); private boolean isMarkedForDeletion; - public EC2FleetNodeComputer(final Slave agent, @Nonnull final String name, @Nonnull final AbstractEC2FleetCloud cloud) { + public EC2FleetNodeComputer(final EC2FleetNode agent) { super(agent); - this.name = name; - this.cloud = cloud; this.isMarkedForDeletion = false; } @@ -36,41 +33,35 @@ public EC2FleetNode getNode() { return (EC2FleetNode) super.getNode(); } + @CheckForNull + public String getInstanceId() { + EC2FleetNode node = getNode(); + return node == null ? null : node.getInstanceId(); + } + + public AbstractEC2FleetCloud getCloud() { + final EC2FleetNode node = getNode(); + return node == null ? null : node.getCloud(); + } + /** * Return label which will represent executor in "Build Executor Status" * section of Jenkins UI. * - * @return node display name + * @return Node's display name */ @Nonnull @Override public String getDisplayName() { - if(cloud != null) { - final String displayName = String.format("%s %s", cloud.getDisplayName(), name); - final EC2FleetNode node = getNode(); - if(node != null) { - final int usesRemaining = node.getUsesRemaining(); - if(usesRemaining != -1) { - return String.format("%s Builds left: %d ", displayName, usesRemaining); - } + final EC2FleetNode node = getNode(); + if(node != null) { + final int totalUses = node.getMaxTotalUses(); + if(totalUses != -1) { + return String.format("%s Builds left: %d ", node.getDisplayName(), totalUses); } - return displayName; + return node.getDisplayName(); } - // in some multi-thread edge cases cloud could be null for some time, just be ok with that - return "unknown fleet" + " " + name; - } - - /** - * {@inheritDoc} - */ - @Override - public void setCloud(@Nonnull final AbstractEC2FleetCloud cloud) { - this.cloud = cloud; - } - - @Override - public AbstractEC2FleetCloud getCloud() { - return cloud; + return "unknown fleet" + " " + getName(); } /** @@ -83,7 +74,7 @@ public HttpResponse doDoDelete() throws IOException { checkPermission(DELETE); final EC2FleetNode node = getNode(); if (node != null) { - final String instanceId = node.getNodeName(); + final String instanceId = node.getInstanceId(); final AbstractEC2FleetCloud cloud = node.getCloud(); if (cloud != null && StringUtils.isNotBlank(instanceId)) { cloud.scheduleToTerminate(instanceId, false, EC2AgentTerminationReason.AGENT_DELETED); diff --git a/src/main/java/com/amazon/jenkins/ec2fleet/EC2RetentionStrategy.java b/src/main/java/com/amazon/jenkins/ec2fleet/EC2RetentionStrategy.java index 6f122af3..655b7273 100644 --- a/src/main/java/com/amazon/jenkins/ec2fleet/EC2RetentionStrategy.java +++ b/src/main/java/com/amazon/jenkins/ec2fleet/EC2RetentionStrategy.java @@ -7,7 +7,6 @@ import hudson.model.Node; import hudson.model.Queue; import hudson.slaves.RetentionStrategy; -import hudson.slaves.SlaveComputer; import java.util.concurrent.TimeUnit; import java.util.logging.Level; diff --git a/src/main/java/com/amazon/jenkins/ec2fleet/LazyUuid.java b/src/main/java/com/amazon/jenkins/ec2fleet/LazyUuid.java deleted file mode 100644 index b79e0d20..00000000 --- a/src/main/java/com/amazon/jenkins/ec2fleet/LazyUuid.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.amazon.jenkins.ec2fleet; - -import javax.annotation.concurrent.ThreadSafe; -import java.util.UUID; - -/** - * Provide uuid string, create it when first call happens - */ -@ThreadSafe -@SuppressWarnings("WeakerAccess") -public class LazyUuid { - - private String value; - - public synchronized String getValue() { - if (value == null) { - value = UUID.randomUUID().toString(); - } - return value; - } - - public synchronized void setValue(String value) { - this.value = value; - } -} diff --git a/src/main/java/com/amazon/jenkins/ec2fleet/fleet/AutoScalingGroupFleet.java b/src/main/java/com/amazon/jenkins/ec2fleet/fleet/AutoScalingGroupFleet.java index 4198aa9b..50f5b456 100644 --- a/src/main/java/com/amazon/jenkins/ec2fleet/fleet/AutoScalingGroupFleet.java +++ b/src/main/java/com/amazon/jenkins/ec2fleet/fleet/AutoScalingGroupFleet.java @@ -112,6 +112,7 @@ public Map getStateBatch(String awsCredentialsId, Strin throw new UnsupportedOperationException(); } + // TODO: move to Registry public AmazonAutoScalingClient createClient( final String awsCredentialsId, final String regionName, final String endpoint) { final AmazonWebServicesCredentials credentials = AWSCredentialsHelper.getCredentials(awsCredentialsId, Jenkins.get()); @@ -125,7 +126,7 @@ public AmazonAutoScalingClient createClient( return client; } - // todo do we want to merge with EC2Api#getEndpoint + // TODO: merge with EC2Api#getEndpoint @Nullable private String getEndpoint(@Nullable final String regionName, @Nullable final String endpoint) { if (StringUtils.isNotEmpty(endpoint)) { diff --git a/src/main/java/com/amazon/jenkins/ec2fleet/utils/EC2FleetCloudAwareUtils.java b/src/main/java/com/amazon/jenkins/ec2fleet/utils/EC2FleetCloudAwareUtils.java deleted file mode 100644 index 0579f954..00000000 --- a/src/main/java/com/amazon/jenkins/ec2fleet/utils/EC2FleetCloudAwareUtils.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.amazon.jenkins.ec2fleet.utils; - -import com.amazon.jenkins.ec2fleet.AbstractEC2FleetCloud; -import com.amazon.jenkins.ec2fleet.EC2FleetCloudAware; -import hudson.model.Computer; -import hudson.model.Node; -import jenkins.model.Jenkins; -import org.apache.commons.lang.StringUtils; - -import javax.annotation.Nonnull; -import java.util.logging.Logger; - -/** - * @see EC2FleetCloudAware - */ -@SuppressWarnings("WeakerAccess") -public class EC2FleetCloudAwareUtils { - - private static final Logger LOGGER = Logger.getLogger(EC2FleetCloudAwareUtils.class.getName()); - - public static void reassign(final @Nonnull String id, @Nonnull final AbstractEC2FleetCloud cloud) { - if (Jenkins.get() != null ) { - if (Jenkins.get().getComputers() != null) { - for (final Computer computer : Jenkins.get().getComputers()) { - LOGGER.info("Trying to reassign Jenkins computer:" + computer.getDisplayName()); - checkAndReassign(id, cloud, computer); - } - } - - if (Jenkins.get().getNodes() != null) { - for (final Node node : Jenkins.get().getNodes()) { - LOGGER.info("Trying to reassign Jenkins node:" + node.getDisplayName()); - checkAndReassign(id, cloud, node); - } - } - } - } - - private static void checkAndReassign(final String id, final AbstractEC2FleetCloud cloud, final Object object) { - if (object instanceof EC2FleetCloudAware) { - final EC2FleetCloudAware cloudAware = (EC2FleetCloudAware) object; - final AbstractEC2FleetCloud oldCloud = cloudAware.getCloud(); - // EC2FleetLabelCloud uses `oldId` and EC2FleetCloud uses `fleet` as id to map the cloud reference - if (oldCloud != null && (StringUtils.equals(id, oldCloud.getOldId()) || StringUtils.equals(id, oldCloud.getFleet()))) { - ((EC2FleetCloudAware) object).setCloud(cloud); - LOGGER.info("Reassigned " + object + " from " + oldCloud.getDisplayName() + " to " + cloud.getDisplayName()); - } - } - } -} diff --git a/src/main/resources/com/amazon/jenkins/ec2fleet/EC2FleetCloud/config.jelly b/src/main/resources/com/amazon/jenkins/ec2fleet/EC2FleetCloud/config.jelly index 8ac2c788..ab383486 100644 --- a/src/main/resources/com/amazon/jenkins/ec2fleet/EC2FleetCloud/config.jelly +++ b/src/main/resources/com/amazon/jenkins/ec2fleet/EC2FleetCloud/config.jelly @@ -4,16 +4,12 @@ xmlns:t="/lib/hudson" xmlns:f="/lib/form" xmlns:c="/lib/credentials"> + A unique name for this EC2 Fleet cloud + Warning: Cloud name is used to track agents belonging to this cloud. Please do not modify an existing cloud's name. See this issue for details - - - - - Select AWS Credentials or leave set to none to use AWS EC2 Instance Role diff --git a/src/main/resources/com/amazon/jenkins/ec2fleet/EC2FleetLabelCloud/config.jelly b/src/main/resources/com/amazon/jenkins/ec2fleet/EC2FleetLabelCloud/config.jelly index d79354e8..1852e841 100644 --- a/src/main/resources/com/amazon/jenkins/ec2fleet/EC2FleetLabelCloud/config.jelly +++ b/src/main/resources/com/amazon/jenkins/ec2fleet/EC2FleetLabelCloud/config.jelly @@ -4,16 +4,12 @@ xmlns:t="/lib/hudson" xmlns:f="/lib/form" xmlns:c="/lib/credentials"> + A unique name for this EC2 Fleet label cloud + Warning: Cloud name is used to track agents belonging to this cloud. Please do not modify an existing cloud's name. See this issue for details - - - - - Select AWS Credentials or leave set to none to use AWS EC2 Instance Role diff --git a/src/main/resources/com/amazon/jenkins/ec2fleet/EC2FleetNode/configure-entries.jelly b/src/main/resources/com/amazon/jenkins/ec2fleet/EC2FleetNode/configure-entries.jelly index 6b97a145..761f399a 100644 --- a/src/main/resources/com/amazon/jenkins/ec2fleet/EC2FleetNode/configure-entries.jelly +++ b/src/main/resources/com/amazon/jenkins/ec2fleet/EC2FleetNode/configure-entries.jelly @@ -1,4 +1,4 @@ -EC2 Spot Fleet Instance +EC2 Instance diff --git a/src/test/java/com/amazon/jenkins/ec2fleet/AutoResubmitIntegrationTest.java b/src/test/java/com/amazon/jenkins/ec2fleet/AutoResubmitIntegrationTest.java index d16f4d87..f3c6b7c1 100644 --- a/src/test/java/com/amazon/jenkins/ec2fleet/AutoResubmitIntegrationTest.java +++ b/src/test/java/com/amazon/jenkins/ec2fleet/AutoResubmitIntegrationTest.java @@ -73,7 +73,7 @@ public void before() { @Test public void should_successfully_resubmit_freestyle_task() throws Exception { - EC2FleetCloud cloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud cloud = new EC2FleetCloud(null, "credId", null, "region", null, "fId", "momo", null, new LocalComputerConnector(j), false, false, 0, 0, 10, 0, 1, false, true, "-1", false, 0, 0, false, @@ -109,7 +109,7 @@ public void should_successfully_resubmit_freestyle_task() throws Exception { @Test public void should_successfully_resubmit_parametrized_task() throws Exception { - EC2FleetCloud cloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud cloud = new EC2FleetCloud(null, "credId", null, "region", null, "fId", "momo", null, new LocalComputerConnector(j), false, false, 0, 0, 10, 0, 1, false, true, "-1", false, 0, 0, false, @@ -165,7 +165,7 @@ public void should_successfully_resubmit_parametrized_task() throws Exception { @Test public void should_not_resubmit_if_disabled() throws Exception { - EC2FleetCloud cloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud cloud = new EC2FleetCloud(null, "credId", null, "region", null, "fId", "momo", null, new LocalComputerConnector(j), false, false, 0, 0, 10, 0, 1, false, true, "-1", true, 0, 0, false, 10, false); diff --git a/src/test/java/com/amazon/jenkins/ec2fleet/EC2FleetCloudTest.java b/src/test/java/com/amazon/jenkins/ec2fleet/EC2FleetCloudTest.java index c87a6861..f596e88a 100644 --- a/src/test/java/com/amazon/jenkins/ec2fleet/EC2FleetCloudTest.java +++ b/src/test/java/com/amazon/jenkins/ec2fleet/EC2FleetCloudTest.java @@ -159,7 +159,7 @@ public void after() { @Test public void canProvision_fleetIsNull(){ - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", null, "", null, null, false, false, 0, 0, 10, 0, 1, true, false, "-1", false, 0, 0, false, @@ -172,7 +172,7 @@ public void canProvision_fleetIsNull(){ @Test public void canProvision_restrictUsageLabelIsNull(){ - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "", "", null, null, false, false, 0, 0, 10, 0, 1, true, true, "-1", false, 0, 0, false, @@ -185,7 +185,7 @@ public void canProvision_restrictUsageLabelIsNull(){ @Test public void canProvision_LabelNotInLabelString(){ - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "", "", null, null, false, false, 0, 0, 10, 0, 1, true, false, "-1", false, 0, 0, false, @@ -198,7 +198,7 @@ public void canProvision_LabelNotInLabelString(){ @Test public void canProvision_LabelInLabelString(){ - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "", "label1 momo", null, null, false, false, 0, 0, 10, 0, 1, true, false, "-1", false, 0, 0, false, @@ -222,7 +222,7 @@ public void provision_shouldProvisionNoneWhenMaxReached() { .thenReturn(new FleetStateStats("", 0, FleetStateStats.State.active(), Collections.emptySet(), Collections.emptyMap())); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "", "", null, null, false, false, 0, 0, 10, 0, 1, true, false, "-1", false, 0, 0, false, @@ -248,7 +248,7 @@ public void provision_shouldProvisionNoneWhenMaxReachedAndNumExecutorsMoreOne() .thenReturn(new FleetStateStats("", 0, FleetStateStats.State.active(), Collections.emptySet(), Collections.emptyMap())); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "", "", null, null, false, false, 0, 1, 8, 0, 3, true, false, "-1", false, 0, 0, false, @@ -274,7 +274,7 @@ public void provision_shouldProvisionNoneWhenMaxReachedAndNumExecutorsMoreOne1() .thenReturn(new FleetStateStats("", 0, FleetStateStats.State.active(), Collections.emptySet(), Collections.emptyMap())); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "", "", null, null, false, false, 0, 1, 8, 0, 3, true, false, "-1", false, 0, 0, false, @@ -300,7 +300,7 @@ public void provision_shouldProvisionNoneWhenExceedMax() { .thenReturn(new FleetStateStats("", 0, FleetStateStats.State.active(), Collections.emptySet(), Collections.emptyMap())); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "", "", null, null, false, false, 0, 0, 9, 0, 1, true, false, "-1", false, 0, 0, false, @@ -326,7 +326,7 @@ public void provision_shouldProvisionIfBelowMax() { .thenReturn(new FleetStateStats("", 0, FleetStateStats.State.active(), Collections.emptySet(), Collections.emptyMap())); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "", "", null, null, false, false, 0, 0, 10, 0, 1, true, false, "-1", false, 0, 0, false, @@ -352,7 +352,7 @@ public void provision_shouldProvisionNoMoreMax() { .thenReturn(new FleetStateStats("", 0, FleetStateStats.State.active(), Collections.emptySet(), Collections.emptyMap())); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "", "", null, null, false, false, 0, 0, 10, 0, 1, true, false, "-1", false, 0, 0, false, @@ -378,7 +378,7 @@ public void provision_shouldProvisionNoMoreMaxWhenMultipleCallBeforeUpdate() { .thenReturn(new FleetStateStats("", 0, FleetStateStats.State.active(), Collections.emptySet(), Collections.emptyMap())); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "", "", null, null, false, false, 0, 0, 10, 0, 1, true, false, "-1", false, 0, 0, false, @@ -408,7 +408,7 @@ public void provision_shouldProvisionNoneIfNotYetUpdated() { PowerMockito.when(ec2Fleet.getState(anyString(), anyString(), anyString(), anyString())) .thenReturn(null); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "", "", null, null, false, false, 0, 0, 1, 0, 1, true, false, "-1", false, 0, 0, false, @@ -431,7 +431,7 @@ public void scheduleToTerminate_shouldNotRemoveIfStatsNotUpdated() { PowerMockito.when(ec2Fleet.getState(anyString(), anyString(), anyString(), anyString())) .thenReturn(null); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "", "", null, null, false, false, 0, 0, 1, 0, 1, true, false, "-1", false, 0, 0, false, @@ -453,7 +453,7 @@ public void scheduleToTerminate_notRemoveIfBelowMin() { .thenReturn(new FleetStateStats("", 0, FleetStateStats.State.active(), Collections.emptySet(), Collections.emptyMap())); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "", "", null, null, false, false, 0, 1, 1, 0, 1, true, false, "-1", false, 0, 0, false, @@ -478,7 +478,7 @@ public void scheduleToTerminate_notRemoveIfEqualMin() { .thenReturn(new FleetStateStats("", 0, FleetStateStats.State.active(), Collections.emptySet(), Collections.emptyMap())); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "", "", null, null, false, false, 0, 1, 1, 0, 1, true, false, "-1", false, 0, 0, false, @@ -504,7 +504,7 @@ public void scheduleToTerminate_notRemoveIfEqualMinSpare() { Collections.emptySet(), Collections.emptyMap())); when(jenkins.getComputers()).thenReturn(new Computer[0]); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "", "", null, null, false, false, 0, 0, 5, 1, 1, true, false, "-1", false, 0, 0, false, @@ -529,7 +529,7 @@ public void scheduleToTerminate_remove() { .thenReturn(new FleetStateStats("", 0, FleetStateStats.State.active(), Collections.emptySet(), Collections.emptyMap())); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "", "", null, null, false, false, 0, 1, 1, 0, 1, true, false, "-1", false, 0, 0, false, @@ -555,7 +555,7 @@ public void scheduleToTerminate_upToZeroNodes() { .thenReturn(new FleetStateStats("", 0, FleetStateStats.State.active(), Collections.emptySet(), Collections.emptyMap())); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "", "", null, null, false, false, 0, 0, 1, 0, 1, true, false, "-1", false, 0, 0, false, @@ -586,7 +586,7 @@ public void scheduleToTerminate_removeNoMoreMinIfCalledMultipleBeforeUpdate() { .thenReturn(new FleetStateStats("", 0, FleetStateStats.State.active(), Collections.emptySet(), Collections.emptyMap())); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "", "", null, null, false, false, 0, 1, 1, 0, 1, true, false, "-1", false, 0, 0, false, @@ -619,7 +619,7 @@ public void update_shouldDoNothingIfNoTerminationOrProvisionAndFleetIsEmpty() { .thenReturn(new FleetStateStats("fleetId", 0, FleetStateStats.State.active(), Collections.emptySet(), Collections.emptyMap())); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "fleetId", "", null, null, false, false, 0, 0, 1, 0, 1, true, false, "-1", false, 0, @@ -643,7 +643,7 @@ public void update_shouldIncreaseTargetCapacityWhenProvisioned() { .thenReturn(new FleetStateStats("fleetId", 0, FleetStateStats.State.active(), Collections.emptySet(), Collections.emptyMap())); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "fleetId", "", null, null, false, false, 0, 0, 10, 0, 1, true, false, "-1", false, 0, @@ -671,7 +671,7 @@ public void update_shouldResetTerminateAndProvision() { PowerMockito.when(ec2Fleet.getState(anyString(), anyString(), anyString(), anyString())) .thenReturn(currentState); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "fleetId", "", null, null, false, false, 0, 0, 10, 0, 1, true, false, "-1", false, 0, @@ -700,7 +700,7 @@ public void update_shouldNotIncreaseMoreThenMax() { .thenReturn(new FleetStateStats("fleetId", 0, FleetStateStats.State.active(), Collections.emptySet(), Collections.emptyMap())); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "fleetId", "", null, null, false, false, 0, 0, 10, 0, 1, true, false, "-1", false, 0, @@ -731,7 +731,7 @@ public void update_shouldNotCountScheduledToTerminateWhenScaleUp() { .thenReturn(new FleetStateStats("fleetId", 5, FleetStateStats.State.active(), Collections.emptySet(), Collections.emptyMap())); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "fleetId", "", null, null, false, false, 0, 0, 10, 0, 1, true, false, "-1", false, 0, @@ -761,7 +761,7 @@ public void update_shouldDecreaseTargetCapacityAndTerminateInstancesIfScheduled( .thenReturn(new FleetStateStats("fleetId", 4, FleetStateStats.State.active(), Collections.emptySet(), Collections.emptyMap())); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "fleetId", "", null, null, false, false, 0, 0, 10, 0, 1, true, false, "-1", false, 0, @@ -802,7 +802,7 @@ public void update_shouldAddNodeIfAnyNewDescribed() throws IOException { mockNodeCreatingPart(); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "fleetId", "", null, PowerMockito.mock(ComputerConnector.class), false, false, 0, 0, 1, 0, 1, false, false, "-1", false, @@ -844,7 +844,7 @@ public void update_shouldTagNewNodesBeforeAdding() throws IOException { mockNodeCreatingPart(); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "fleetId", "", null, PowerMockito.mock(ComputerConnector.class), false, false, 0, 0, 2, 0, 1, false, false, "-1", false, @@ -880,7 +880,7 @@ public void update_shouldTagNewNodesBeforeAddingWithFleetName() throws IOExcepti mockNodeCreatingPart(); - EC2FleetCloud fleetCloud = new EC2FleetCloud("my-fleet", null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud("my-fleet", "credId", null, "region", "", "fleetId", "", null, PowerMockito.mock(ComputerConnector.class), false, false, 0, 0, 1, 0, 1, false, false, "-1", false, @@ -921,7 +921,7 @@ public void update_givenFailedTaggingShouldIgnoreExceptionAndAddNode() throws IO mockNodeCreatingPart(); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "fleetId", "", null, PowerMockito.mock(ComputerConnector.class), false, false, 0, 0, 1, 0, 1, false, false, "-1", false, @@ -959,7 +959,7 @@ public void update_shouldAddNodeIfAnyNewDescribed_restrictUsage() throws IOExcep mockNodeCreatingPart(); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "fleetId", "", null, PowerMockito.mock(ComputerConnector.class), false, false, 0, 0, 1, 0, 1, false, true, "-1", false, @@ -1004,7 +1004,7 @@ public void update_shouldAddNodeWithNumExecutors_whenWeightProvidedButNotEnabled mockNodeCreatingPart(); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "fleetId", "", null, PowerMockito.mock(ComputerConnector.class), false, false, 0, 0, 1, 0, 1, false, true, "-1", false, @@ -1037,7 +1037,7 @@ public void update_givenManuallyUpdatedFleetShouldCorrectLocalTargetCapacityToKe mockNodeCreatingPart(); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "fleetId", "", null, PowerMockito.mock(ComputerConnector.class), false, false, 0, 0, 10, 0, 1, false, true, "-1", false, @@ -1074,7 +1074,7 @@ public void update_shouldTrimPlannedNodesIfExceedTargetCapacity() throws IOExcep mockNodeCreatingPart(); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "fleetId", "", null, PowerMockito.mock(ComputerConnector.class), false, false, 0, 0, 10, 0, 1, false, true, "-1", false, @@ -1122,7 +1122,7 @@ public void update_shouldTrimPlannedNodesBasedOnUpdatedTargetCapacityIfProvision mockNodeCreatingPart(); - final EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + final EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "fleetId", "", null, PowerMockito.mock(ComputerConnector.class), false, false, 0, 0, 10, 0, 1, false, true, "-1", false, @@ -1174,7 +1174,7 @@ public void update_shouldUpdateStateWithFleetTargetCapacityPlusToAdd() throws IO mockNodeCreatingPart(); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "fleetId", "", null, PowerMockito.mock(ComputerConnector.class), false, false, 0, 0, 10, 0,1, false, true, "-1", false, @@ -1220,7 +1220,7 @@ public void update_shouldUpdateStateWithFleetTargetCapacityMinusToTerminate() th mockNodeCreatingPart(); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "fleetId", "", null, PowerMockito.mock(ComputerConnector.class), false, false, 0, 0, 10,0, 1, false, true, "-1", false, @@ -1255,7 +1255,7 @@ public void update_shouldTerminateIdleOrNullInstancesOnly() { new HashSet<>(Arrays.asList("i-1", "i-2", "i-3")), Collections.emptyMap())); mockNodeCreatingPart(); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "fleetId", "", null, PowerMockito.mock(ComputerConnector.class), false, false, 0, 0, 2, 0, 1, false, false, "-1", false, @@ -1299,7 +1299,7 @@ public void update_shouldUpdateStateWithMinSpare() throws IOException { PowerMockito.when(ec2Fleet.getState(anyString(), anyString(), anyString(), anyString())) .thenReturn(initState); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "fleetId", "", null, PowerMockito.mock(ComputerConnector.class), false, false, 0, 0, 10, minSpareSize, 1, false, true, "-1", false, @@ -1340,7 +1340,7 @@ public void update_shouldAddNodeWithScaledNumExecutors_whenWeightPresentAndEnabl mockNodeCreatingPart(); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "fleetId", "", null, PowerMockito.mock(ComputerConnector.class), false, false, 0, 0, 1, 0, 1, false, true, "-1", false, @@ -1382,7 +1382,7 @@ public void update_shouldAddNodeWithNumExecutors_whenWeightPresentAndEnabledButF mockNodeCreatingPart(); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "fleetId", "", null, PowerMockito.mock(ComputerConnector.class), false, false, 0, 0, 1, 0, 1, false, true, "-1", false, @@ -1424,7 +1424,7 @@ public void update_shouldAddNodeWithRoundToLowScaledNumExecutors_whenWeightPrese mockNodeCreatingPart(); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "fleetId", "", null, PowerMockito.mock(ComputerConnector.class), false, false, 0, 0, 1, 0, 1, false, true, "-1", false, @@ -1466,13 +1466,13 @@ public void update_shouldAddNodeWithRoundToLowScaledNumExecutors_whenWeightPrese mockNodeCreatingPart(); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "fleetId", "", null, PowerMockito.mock(ComputerConnector.class), false, false, 0, 0, 1, 0, 1, false, true, "-1", false, 0, 0, true, 10, false); - ArgumentCaptor nodeCaptor = ArgumentCaptor.forClass(Node.class); + ArgumentCaptor nodeCaptor = ArgumentCaptor.forClass(EC2FleetNode.class); doNothing().when(jenkins).addNode(nodeCaptor.capture()); // when @@ -1509,7 +1509,7 @@ public void update_shouldAddNodeWithScaledToOneNumExecutors_whenWeightPresentBut PowerMockito.doThrow(new UnsupportedOperationException("Test exception")).when(ec2Fleet) .modify(anyString(), anyString(), anyString(), anyString(), anyInt(), anyInt(), anyInt()); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "fleetId", "", null, PowerMockito.mock(ComputerConnector.class), false, false, 0, 0, 1, 0, 1, false, true, "-1", false, @@ -1554,7 +1554,7 @@ public void update_givenFailedModifyShouldNotUpdateToAddToDelete() throws IOExce mockNodeCreatingPart(); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "fleetId", "", null, PowerMockito.mock(ComputerConnector.class), false, false, 0, 0, 1, 0, 1, false, true, "-1", false, @@ -1602,7 +1602,7 @@ public void update_givenFleetInModifyingShouldNotDoAnyUpdates() throws IOExcepti mockNodeCreatingPart(); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "fleetId", "", null, PowerMockito.mock(ComputerConnector.class), false, false, 0, 0, 1, 0, 1, false, true, "-1", false, @@ -1632,7 +1632,7 @@ public void update_scheduledFuturesExecutesAfterTimeout() throws IOException, In final int timeout = 1; - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "", "", null, null, false, false, 0, 0, 10, 0,1, true, false, "-1", false, timeout, 0, false, @@ -1663,7 +1663,7 @@ public void update_scheduledFuturesIsCancelledAfterUpdate() throws IOException, final int timeout = 1; - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "", "", null, null, false, false, 0, 0, 10, 0,1, true, false, "-1", false, timeout, 0, false, @@ -1690,7 +1690,7 @@ public void update_shouldScaleUpToMinSize() { .thenReturn(new FleetStateStats("", 0, FleetStateStats.State.active(), Collections.emptySet(), Collections.emptyMap())); - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "fleetId", "", null, PowerMockito.mock(ComputerConnector.class), false, false, 0, 1, 1, 0,1, false, true, "-1", false, @@ -1706,7 +1706,7 @@ public void update_shouldScaleUpToMinSize() { @Test public void removeScheduledFutures_success() { // given - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "fleetId", "", null, PowerMockito.mock(ComputerConnector.class), false, false, 0, 0, 1, 0, 1, false, true, "-1", false, @@ -1727,7 +1727,7 @@ public void removeScheduledFutures_success() { @Test public void removeScheduledFutures_scheduledFutureIsEmpty() { // given - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "fleetId", "", null, PowerMockito.mock(ComputerConnector.class), false, false, 0, 0, 1, 0, 1, false, true, "-1", false, @@ -1746,7 +1746,7 @@ public void removeScheduledFutures_scheduledFutureIsEmpty() { @Test public void removeScheduledFutures_numToRemoveIsZero() { // given - EC2FleetCloud fleetCloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud fleetCloud = new EC2FleetCloud(null, "credId", null, "region", "", "fleetId", "", null, PowerMockito.mock(ComputerConnector.class), false, false, 0, 0, 1, 0, 1, false, true, "-1", false, @@ -1944,7 +1944,7 @@ public void descriptorImpl_doCheckFleet_nonDefault() { @Test public void getDisplayName_returnDefaultWhenNull() { EC2FleetCloud ec2FleetCloud = new EC2FleetCloud( - null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, false, false, null, 0, 1, 0, 1, true, false, "-1", false @@ -1955,7 +1955,7 @@ public void getDisplayName_returnDefaultWhenNull() { @Test public void getDisplayName_returnDisplayName() { EC2FleetCloud ec2FleetCloud = new EC2FleetCloud( - "CloudName", null, null, null, null, null, null, + "CloudName", null, null, null, null, null, null, null, null, false, false, null, 0, 1, 0, 1, true, false, "-1", false @@ -1967,7 +1967,7 @@ public void getDisplayName_returnDisplayName() { @Test public void getAwsCredentialsId_returnNull_whenNoCredentialsIdOrAwsCredentialsId() { EC2FleetCloud ec2FleetCloud = new EC2FleetCloud( - null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, false, false, null, 0, 1, 0, 1, true, false, "-1", false, @@ -1979,7 +1979,7 @@ public void getAwsCredentialsId_returnNull_whenNoCredentialsIdOrAwsCredentialsId @Test public void getAwsCredentialsId_returnValue_whenCredentialsIdPresent() { EC2FleetCloud ec2FleetCloud = new EC2FleetCloud( - null, null, null, "Opa", null, null, null, + null, null, "Opa", null, null, null, null, null, null, false, false, null, 0, 1, 0, 1, true, false, "-1", false @@ -1991,7 +1991,7 @@ public void getAwsCredentialsId_returnValue_whenCredentialsIdPresent() { @Test public void getAwsCredentialsId_returnValue_whenAwsCredentialsIdPresent() { EC2FleetCloud ec2FleetCloud = new EC2FleetCloud( - null, null, "Opa", null, null, null, null, + null, "Opa", null, null, null, null, null, null, null, false, false, null, 0, 1, 0, 1, true, false, "-1", false @@ -2003,7 +2003,7 @@ public void getAwsCredentialsId_returnValue_whenAwsCredentialsIdPresent() { @Test public void getAwsCredentialsId_returnAwsCredentialsId_whenAwsCredentialsIdAndCredentialsIdPresent() { EC2FleetCloud ec2FleetCloud = new EC2FleetCloud( - null, null, "A", "B", null, null, null, + null, "A", "B", null, null, null, null, null, null, false, false, null, 0, 1, 0, 1, true, false, "-1", false @@ -2017,7 +2017,7 @@ public void getAwsCredentialsId_returnAwsCredentialsId_whenAwsCredentialsIdAndCr @Test public void getCloudStatusInterval_returnCloudStatusInterval() { EC2FleetCloud ec2FleetCloud = new EC2FleetCloud( - "CloudName", null, null, null, null, null, null, + "CloudName", null, null, null, null, null, null, null, null, false, false, null, 0, 1, 0, 1, true, false, "-1", false @@ -2029,7 +2029,7 @@ public void getCloudStatusInterval_returnCloudStatusInterval() { @Test public void create_numExecutorsLessThenOneShouldUpgradedToOne() { EC2FleetCloud ec2FleetCloud = new EC2FleetCloud( - "CloudName", null, null, null, null, null, null, + "CloudName", null, null, null, null, null, null, null, null, false, false, null, 0, 1, 0, 0, true, false, "-1", false @@ -2042,7 +2042,7 @@ public void create_numExecutorsLessThenOneShouldUpgradedToOne() { public void hasUnlimitedUsesForNodes_shouldReturnTrueWhenUnlimited() { final int maxTotalUses = -1; EC2FleetCloud ec2FleetCloud = new EC2FleetCloud( - "CloudName", null, null, null, null, null, null, + "CloudName", null, null, null, null, null, null, null, null, false, false, null, 0, 1, 0, 0, true, false, String.valueOf(maxTotalUses), false @@ -2055,7 +2055,7 @@ public void hasUnlimitedUsesForNodes_shouldReturnTrueWhenUnlimited() { public void hasUnlimitedUsesForNodes_shouldReturnDefaultTrueForNull() { final String maxTotalUses = null; EC2FleetCloud ec2FleetCloud = new EC2FleetCloud( - "CloudName", null, null, null, null, null, null, + "CloudName", null, null, null, null, null, null, null, null, false, false, null, 0, 1, 0, 0, true, false, maxTotalUses, false @@ -2068,7 +2068,7 @@ public void hasUnlimitedUsesForNodes_shouldReturnDefaultTrueForNull() { public void hasUnlimitedUsesForNodes_shouldReturnDefaultTrueForEmptyString() { final String maxTotalUses = ""; EC2FleetCloud ec2FleetCloud = new EC2FleetCloud( - "CloudName", null, null, null, null, null, null, + "CloudName", null, null, null, null, null, null, null, null, false, false, null, 0, 1, 0, 0, true, false, maxTotalUses, false @@ -2081,7 +2081,7 @@ public void hasUnlimitedUsesForNodes_shouldReturnDefaultTrueForEmptyString() { public void hasUnlimitedUsesForNodes_shouldReturnFalseWhenLimited() { final int maxTotalUses = 5; EC2FleetCloud ec2FleetCloud = new EC2FleetCloud( - "CloudName", null, null, null, null, null, null, + "CloudName", null, null, null, null, null, null, null, null, false, false, null, 0, 1, 0, 0, true, false, String.valueOf(maxTotalUses), false diff --git a/src/test/java/com/amazon/jenkins/ec2fleet/EC2FleetCloudWithHistory.java b/src/test/java/com/amazon/jenkins/ec2fleet/EC2FleetCloudWithHistory.java index ad7e5924..54877c8a 100644 --- a/src/test/java/com/amazon/jenkins/ec2fleet/EC2FleetCloudWithHistory.java +++ b/src/test/java/com/amazon/jenkins/ec2fleet/EC2FleetCloudWithHistory.java @@ -13,13 +13,13 @@ public class EC2FleetCloudWithHistory extends EC2FleetCloud { public CopyOnWriteArrayList provisionTimes = new CopyOnWriteArrayList<>(); public EC2FleetCloudWithHistory( - String name, String oldId, String awsCredentialsId, String credentialsId, String region, + String name, String awsCredentialsId, String credentialsId, String region, String endpoint, String fleet, String labelString, String fsRoot, ComputerConnector computerConnector, boolean privateIpUsed, boolean alwaysReconnect, Integer idleMinutes, Integer minSize, Integer maxSize, Integer minSpareSize, Integer numExecutors, boolean addNodeOnlyIfRunning, boolean restrictUsage, boolean disableTaskResubmit, Integer initOnlineTimeoutSec, Integer initOnlineCheckIntervalSec, boolean scaleExecutorsByWeight, Integer cloudStatusIntervalSec, boolean immediatelyProvision) { - super(name, oldId, awsCredentialsId, credentialsId, region, endpoint, fleet, labelString, fsRoot, + super(name, awsCredentialsId, credentialsId, region, endpoint, fleet, labelString, fsRoot, computerConnector, privateIpUsed, alwaysReconnect, idleMinutes, minSize, maxSize, minSpareSize, numExecutors, addNodeOnlyIfRunning, restrictUsage, "-1", disableTaskResubmit, initOnlineTimeoutSec, initOnlineCheckIntervalSec, scaleExecutorsByWeight, cloudStatusIntervalSec, immediatelyProvision); diff --git a/src/test/java/com/amazon/jenkins/ec2fleet/EC2FleetCloudWithMeter.java b/src/test/java/com/amazon/jenkins/ec2fleet/EC2FleetCloudWithMeter.java index 17353580..18828334 100644 --- a/src/test/java/com/amazon/jenkins/ec2fleet/EC2FleetCloudWithMeter.java +++ b/src/test/java/com/amazon/jenkins/ec2fleet/EC2FleetCloudWithMeter.java @@ -14,13 +14,13 @@ public class EC2FleetCloudWithMeter extends EC2FleetCloud { public final Meter removeMeter = new Meter("remove"); public EC2FleetCloudWithMeter( - String name, String oldId, String awsCredentialsId, String credentialsId, String region, + String name, String awsCredentialsId, String credentialsId, String region, String endpoint, String fleet, String labelString, String fsRoot, ComputerConnector computerConnector, boolean privateIpUsed, boolean alwaysReconnect, Integer idleMinutes, Integer minSize, Integer maxSize, Integer minSpareSize, Integer numExecutors, boolean addNodeOnlyIfRunning, boolean restrictUsage, boolean disableTaskResubmit, Integer initOnlineTimeoutSec, Integer initOnlineCheckIntervalSec, boolean scaleExecutorsByWeight, Integer cloudStatusIntervalSec, boolean immediatelyProvision) { - super(name, oldId, awsCredentialsId, credentialsId, region, endpoint, fleet, labelString, fsRoot, + super(name, awsCredentialsId, credentialsId, region, endpoint, fleet, labelString, fsRoot, computerConnector, privateIpUsed, alwaysReconnect, idleMinutes, minSize, maxSize, minSpareSize, numExecutors, addNodeOnlyIfRunning, restrictUsage, "-1", disableTaskResubmit, initOnlineTimeoutSec, initOnlineCheckIntervalSec, scaleExecutorsByWeight, cloudStatusIntervalSec, immediatelyProvision); diff --git a/src/test/java/com/amazon/jenkins/ec2fleet/EC2FleetLabelCloudIntegrationTest.java b/src/test/java/com/amazon/jenkins/ec2fleet/EC2FleetLabelCloudIntegrationTest.java index 866ffc2e..4f61a3c0 100644 --- a/src/test/java/com/amazon/jenkins/ec2fleet/EC2FleetLabelCloudIntegrationTest.java +++ b/src/test/java/com/amazon/jenkins/ec2fleet/EC2FleetLabelCloudIntegrationTest.java @@ -29,7 +29,7 @@ public void should_create_stack_and_provision_node_for_task_execution() throws E mockEc2FleetApiToEc2SpotFleet(InstanceStateName.Running); mockCloudFormationApi(); - EC2FleetLabelCloud cloud = new EC2FleetLabelCloud("FleetLabel", null, "credId", "region", + EC2FleetLabelCloud cloud = new EC2FleetLabelCloud("FleetLabel", "credId", "region", null, null, new LocalComputerConnector(j), false, false, 0, 0, 0, 1, false, false, 0, 0, @@ -58,7 +58,7 @@ public void should_delete_resources_if_label_unused() throws Exception { mockEc2FleetApiToEc2SpotFleet(InstanceStateName.Running); final AmazonCloudFormation amazonCloudFormation = mockCloudFormationApi(); - EC2FleetLabelCloud cloud = new EC2FleetLabelCloud("FleetLabel", null, "credId", "region", + EC2FleetLabelCloud cloud = new EC2FleetLabelCloud("FleetLabel", "credId", "region", null, null, new LocalComputerConnector(j), false, false, 0, 0, 0, 1, false, false, 0, 0, diff --git a/src/test/java/com/amazon/jenkins/ec2fleet/EC2FleetNodeComputerTest.java b/src/test/java/com/amazon/jenkins/ec2fleet/EC2FleetNodeComputerTest.java index cde13dd3..684aaafc 100644 --- a/src/test/java/com/amazon/jenkins/ec2fleet/EC2FleetNodeComputerTest.java +++ b/src/test/java/com/amazon/jenkins/ec2fleet/EC2FleetNodeComputerTest.java @@ -1,7 +1,6 @@ package com.amazon.jenkins.ec2fleet; import hudson.model.Queue; -import hudson.model.Slave; import jenkins.model.Jenkins; import org.junit.Assert; import org.junit.Before; @@ -12,6 +11,7 @@ import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; @@ -20,7 +20,7 @@ public class EC2FleetNodeComputerTest { @Mock - private Slave agent; + private EC2FleetNode agent; @Mock private Jenkins jenkins; @@ -28,9 +28,6 @@ public class EC2FleetNodeComputerTest { @Mock private Queue queue; - @Mock - private EC2FleetCloud cloud; - @Before public void before() { PowerMockito.mockStatic(Jenkins.class); @@ -42,23 +39,25 @@ public void before() { } @Test - public void getDisplayName_should_be_ok_with_init_null_cloud() { - EC2FleetNodeComputer computer = spy(new EC2FleetNodeComputer(agent, "a", null)); - Assert.assertEquals("unknown fleet a", computer.getDisplayName()); - } + public void getDisplayName_returns_node_display_name_for_default_maxTotalUses() { + when(agent.getDisplayName()).thenReturn("a n"); + when(agent.getMaxTotalUses()).thenReturn(-1); - @Test - public void getDisplayName_should_be_ok_with_set_null_cloud() { - EC2FleetNodeComputer computer = spy(new EC2FleetNodeComputer(agent, "a", cloud)); - computer.setCloud(null); - Assert.assertEquals("unknown fleet a", computer.getDisplayName()); + EC2FleetNodeComputer computer = spy(new EC2FleetNodeComputer(agent)); + doReturn(agent).when(computer).getNode(); + + Assert.assertEquals("a n", computer.getDisplayName()); } @Test - public void getDisplayName_returns_node_display_name() { - when(cloud.getDisplayName()).thenReturn("a"); - EC2FleetNodeComputer computer = spy(new EC2FleetNodeComputer(agent, "n", cloud)); - Assert.assertEquals("a n", computer.getDisplayName()); + public void getDisplayName_returns_builds_left_for_non_default_maxTotalUses() { + when(agent.getDisplayName()).thenReturn("a n"); + when(agent.getMaxTotalUses()).thenReturn(1); + + EC2FleetNodeComputer computer = spy(new EC2FleetNodeComputer(agent)); + doReturn(agent).when(computer).getNode(); + + Assert.assertEquals("a n Builds left: 1 ", computer.getDisplayName()); } } diff --git a/src/test/java/com/amazon/jenkins/ec2fleet/EC2RetentionStrategyIntegrationTest.java b/src/test/java/com/amazon/jenkins/ec2fleet/EC2RetentionStrategyIntegrationTest.java index 9650b698..6ccf1b10 100644 --- a/src/test/java/com/amazon/jenkins/ec2fleet/EC2RetentionStrategyIntegrationTest.java +++ b/src/test/java/com/amazon/jenkins/ec2fleet/EC2RetentionStrategyIntegrationTest.java @@ -6,16 +6,14 @@ import com.amazonaws.services.ec2.AmazonEC2; import com.amazonaws.services.ec2.model.DescribeInstancesRequest; import com.amazonaws.services.ec2.model.DescribeInstancesResult; +import com.amazonaws.services.ec2.model.DescribeSpotFleetRequestsRequest; +import com.amazonaws.services.ec2.model.DescribeSpotFleetRequestsResult; import com.amazonaws.services.ec2.model.Instance; import com.amazonaws.services.ec2.model.InstanceState; import com.amazonaws.services.ec2.model.InstanceStateName; import com.amazonaws.services.ec2.model.Reservation; import com.amazonaws.services.ec2.model.TerminateInstancesRequest; import com.amazonaws.services.ec2.model.TerminateInstancesResult; -import com.gargoylesoftware.htmlunit.html.HtmlForm; -import com.gargoylesoftware.htmlunit.html.HtmlFormUtil; -import com.gargoylesoftware.htmlunit.html.HtmlPage; -import com.gargoylesoftware.htmlunit.html.HtmlTextInput; import hudson.model.Node; import hudson.model.queue.QueueTaskFuture; import org.junit.Before; @@ -28,11 +26,7 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; @@ -78,7 +72,7 @@ public void before() { @Test public void shouldTerminateNodeMarkedForDeletion() throws Exception { - final EC2FleetCloud cloud = new EC2FleetCloud(null, null, "credId", null, "region", + final EC2FleetCloud cloud = new EC2FleetCloud(null, "credId", null, "region", null, "fId", "momo", null, new LocalComputerConnector(j), false, false, 1, 0, 0, 0, 1, false, true, "-1", false, 0, 0, false, 999, false); // Set initial jenkins nodes @@ -102,7 +96,7 @@ public void shouldTerminateNodeMarkedForDeletion() throws Exception { @Test public void shouldTerminateExcessCapacity() throws Exception { - final EC2FleetCloud cloud = new EC2FleetCloud(null, null, "credId", null, "region", + final EC2FleetCloud cloud = new EC2FleetCloud(null, "credId", null, "region", null, "fId", "momo", null, new LocalComputerConnector(j), false, false, 1, 0, 0, 0, 1, false, true, "-1", false, 0, 0, false, 999, false); // Set initial jenkins nodes @@ -141,14 +135,14 @@ public void shouldNotTerminateExcessCapacityWhenNodeIsBusy() throws Exception { List rs = enqueTask(10, 90); triggerSuggestReviewNow(); - EC2FleetCloud cloud = new EC2FleetCloud(null, "null", "credId", null, "region", + EC2FleetCloud cloud = new EC2FleetCloud(null, "credId", null, "region", null, "fId", "momo", null, new LocalComputerConnector(j), false, false, 1, 2, 2, 0, 1, false, true, "-1", false, 0, 0, false, 999, false); j.jenkins.clouds.add(cloud); cloud.update(); assertAtLeastOneNode(); - cloud = new EC2FleetCloud(null, null, "credId", null, "region", + cloud = new EC2FleetCloud(null, "credId", null, "region", null, "fId", "momo", null, new LocalComputerConnector(j), false, false, 1, 0, 0, 0, 1, false, true, "-1", false, 0, 0, false, 99, false); j.jenkins.clouds.clear(); @@ -174,7 +168,7 @@ public void shouldNotTerminateExcessCapacityWhenNodeIsBusy() throws Exception { @Test public void shouldTerminateIdleNodesAfterIdleTimeout() throws Exception { - final EC2FleetCloud cloud = new EC2FleetCloud(null, null, "credId", null, "region", + final EC2FleetCloud cloud = new EC2FleetCloud(null, "credId", null, "region", null, "fId", "momo", null, new LocalComputerConnector(j), false, false, 1, 0, 2, 0, 1, false, true, "-1", false, 0, 0, false, 99, false); j.jenkins.clouds.add(cloud); @@ -205,7 +199,7 @@ public void shouldTerminateIdleNodesAfterIdleTimeout() throws Exception { @Test public void shouldNotTerminateBelowMinSize() throws Exception { - final EC2FleetCloud cloud = new EC2FleetCloud(null, null, "credId", null, "region", + final EC2FleetCloud cloud = new EC2FleetCloud(null, "credId", null, "region", null, "fId", "momo", null, new LocalComputerConnector(j), false, false, 1, 2, 5, 0, 1, false, true, "-1", false, 0, 0, false, 30, false); j.jenkins.clouds.add(cloud); @@ -229,7 +223,7 @@ public void shouldNotTerminateBelowMinSize() throws Exception { @Test public void shouldNotTerminateBelowMinSpareSize() throws Exception { - final EC2FleetCloud cloud = new EC2FleetCloud(null, null, "credId", null, "region", + final EC2FleetCloud cloud = new EC2FleetCloud(null, "credId", null, "region", null, "fId", "momo", null, new LocalComputerConnector(j), false, false, 1, 0, 5, 2, 1, false, true, "-1", false, 0, 0, false, 30, false); j.jenkins.clouds.add(cloud); @@ -258,7 +252,7 @@ public void shouldTerminateWhenMaxTotalUsesIsExhausted() throws Exception { final int maxTotalUses = 2; final int taskSleepTime = 1; - EC2FleetCloud cloud = spy(new EC2FleetCloud("testCloud", null, "credId", null, "region", + EC2FleetCloud cloud = spy(new EC2FleetCloud("testCloud", "credId", null, "region", null, "fId", label, null, new LocalComputerConnector(j), false, false, 0, 0, 10, 0, 1, false, true, String.valueOf(maxTotalUses), true, 0, 0, false, 10, false)); @@ -277,74 +271,4 @@ public void shouldTerminateWhenMaxTotalUsesIsExhausted() throws Exception { verify((amazonEC2)).terminateInstances(argument.capture()); assertTrue(argument.getAllValues().get(0).getInstanceIds().containsAll(Arrays.asList("i-1", "i-2"))); } - - @Test - public void shouldTerminateNodeForMaxTotalUsesIsExhaustedAfterConfigChange() throws Exception { - final String label = "momo"; - final int numTasks = 4; // schedule a total of 4 tasks, 2 per instance - final int maxTotalUses = 2; - final long scheduleInterval = 5; - final int cloudStatusInternalSec = 60; // increase to trigger update manually - final int taskSleepTime = 1; - - EC2FleetCloud cloud = new EC2FleetCloud("testCloud", null, "credId", null, "region", - null, "fId", label, null, new LocalComputerConnector(j), false, false, - 0, 0, 10, 0, 1, false, true, - String.valueOf(maxTotalUses), true, 0, 0, false, - cloudStatusInternalSec, false); - j.jenkins.clouds.add(cloud); - cloud.update(); - assertAtLeastOneNode(); - - // initiate a config change after a node exhausts maxTotalUses and is scheduled for termination - EC2FleetCloud newCloud; - String nodeToTerminate = null; - int taskCount = 0; - final List tasks = new ArrayList<>(); - for (int i=numTasks; i > 0 ; i--) { - // get first node that is about to get terminated, before scheduling more tasks - List nodesWithExhaustedMaxUses = j.jenkins.getNodes().stream() - .filter(n -> ((EC2FleetNode)n).getUsesRemaining() == 0) - .map(Node::getNodeName) - .collect(Collectors.toList()); - if (nodesWithExhaustedMaxUses != null && !nodesWithExhaustedMaxUses.isEmpty()) { - nodeToTerminate = nodesWithExhaustedMaxUses.get(0); - break; // we have what we want, stop scheduling more tasks - exit loop and verify - } - - // schedule a task - tasks.addAll(enqueTask(1, taskSleepTime)); - taskCount++; - System.out.println("scheduled task " + taskCount + ", waiting " + scheduleInterval + " sec"); - Thread.sleep(TimeUnit.SECONDS.toMillis(scheduleInterval)); - } - waitJobSuccessfulExecution(tasks); // wait for scheduleToTerminate to be called - - assertNotNull(nodeToTerminate); - - // make a config change after a node is scheduled to terminate - HtmlPage page = j.createWebClient().goTo("configureClouds"); - HtmlForm form = page.getFormByName("config"); - System.out.println(form.toString()); - System.out.println(IntegrationTest.getElementsByNameWithoutJdk(page, "_.name")); - ((HtmlTextInput) IntegrationTest.getElementsByNameWithoutJdk(page, "_.name").get(0)).setText("new-name"); - HtmlFormUtil.submit(form); - - // verify cloud object was re-created, leading to lost state (i.e. instanceIdsToTerminate) - newCloud = (EC2FleetCloud) j.jenkins.clouds.get(0); - assertNotSame(cloud, newCloud); - assertTrue(cloud.getInstanceIdsToTerminate().containsKey(nodeToTerminate)); - assertTrue(newCloud.getInstanceIdsToTerminate().isEmpty()); - - // initiate check to schedule instance to terminate again - EC2FleetNode node = (EC2FleetNode) j.jenkins.getNode(nodeToTerminate); - node.getRetentionStrategy().check(node.toComputer()); - - // terminate scheduled instances - cloud.update(); - - final ArgumentCaptor argument = ArgumentCaptor.forClass(TerminateInstancesRequest.class); - verify((amazonEC2)).terminateInstances(argument.capture()); - assertTrue(argument.getAllValues().get(0).getInstanceIds().contains(nodeToTerminate)); - } } diff --git a/src/test/java/com/amazon/jenkins/ec2fleet/LazyUuidTest.java b/src/test/java/com/amazon/jenkins/ec2fleet/LazyUuidTest.java deleted file mode 100644 index 9e7066b1..00000000 --- a/src/test/java/com/amazon/jenkins/ec2fleet/LazyUuidTest.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.amazon.jenkins.ec2fleet; - -import org.junit.Assert; -import org.junit.Test; - -import java.util.HashSet; -import java.util.Set; -import java.util.concurrent.TimeUnit; - -public class LazyUuidTest { - - @Test - public void getValue_provides_uuid() { - Assert.assertEquals(36, new LazyUuid().getValue().length()); - } - - @Test - public void getValue_provides_same_value_if_multiplecall() { - final LazyUuid lazyUuid = new LazyUuid(); - Assert.assertEquals(lazyUuid.getValue(), lazyUuid.getValue()); - Assert.assertEquals(lazyUuid.getValue(), lazyUuid.getValue()); - } - - @Test - public void getValue_is_thread_safe() throws InterruptedException { - final LazyUuid lazyUuid = new LazyUuid(); - - final LazyUuidGetter[] threads = new LazyUuidGetter[3]; - - for (int i = 0; i < threads.length; i++) { - threads[i] = new LazyUuidGetter(lazyUuid); - threads[i].start(); - } - - Thread.sleep(TimeUnit.SECONDS.toMillis(10)); - - final Set history = new HashSet<>(); - - for (final LazyUuidGetter thread : threads) { - thread.interrupt(); - - history.addAll(thread.history); - } - - Assert.assertEquals(1, history.size()); - Assert.assertNotNull(history.iterator().next()); - } - - private static class LazyUuidGetter extends Thread { - - private final Set history; - private final LazyUuid lazyUuid; - - LazyUuidGetter(LazyUuid lazyUuid) { - this.lazyUuid = lazyUuid; - history = new HashSet<>(); - } - - @Override - public void run() { - while (true) { - history.add(lazyUuid.getValue()); - - try { - Thread.sleep(100); - } catch (InterruptedException e) { - return; // stop - } - } - } - } -} diff --git a/src/test/java/com/amazon/jenkins/ec2fleet/NoDelayProvisionStrategyPerformanceTest.java b/src/test/java/com/amazon/jenkins/ec2fleet/NoDelayProvisionStrategyPerformanceTest.java index 0713b09d..eb2b0463 100644 --- a/src/test/java/com/amazon/jenkins/ec2fleet/NoDelayProvisionStrategyPerformanceTest.java +++ b/src/test/java/com/amazon/jenkins/ec2fleet/NoDelayProvisionStrategyPerformanceTest.java @@ -53,7 +53,7 @@ private void test(final boolean noDelay) throws IOException, InterruptedExceptio final ComputerConnector computerConnector = new LocalComputerConnector(j); final String label = "momo"; - final EC2FleetCloudWithHistory cloud = new EC2FleetCloudWithHistory(null, null, "credId", null, "region", + final EC2FleetCloudWithHistory cloud = new EC2FleetCloudWithHistory(null, "credId", null, "region", null, "fId", label, null, computerConnector, false, false, 1, 0, maxWorkers, 0, 1, true, false, false, 0, 0, false, diff --git a/src/test/java/com/amazon/jenkins/ec2fleet/ProvisionIntegrationTest.java b/src/test/java/com/amazon/jenkins/ec2fleet/ProvisionIntegrationTest.java index 8375a5d0..33ebb110 100644 --- a/src/test/java/com/amazon/jenkins/ec2fleet/ProvisionIntegrationTest.java +++ b/src/test/java/com/amazon/jenkins/ec2fleet/ProvisionIntegrationTest.java @@ -65,7 +65,7 @@ public void dont_provide_any_planned_if_empty_and_reached_max_capacity() throws new FleetStateStats("", 0, FleetStateStats.State.active(), Collections.emptySet(), Collections.emptyMap())); - EC2FleetCloud cloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud cloud = new EC2FleetCloud(null, "credId", null, "region", null, "fId", "momo", null, computerConnector, false, false, 0, 0, 0, 0, 1, true, false, "-1", false, 0, 0, false, @@ -99,7 +99,7 @@ public void should_add_planned_if_capacity_required_but_not_described_yet() thro mockEc2FleetApi(); - EC2FleetCloud cloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud cloud = new EC2FleetCloud(null, "credId", null, "region", null, "fId", "momo", null, computerConnector, false, false, 0, 0, 10, 0, 1, true, false, "-1", false, 0, 0, false, @@ -134,7 +134,7 @@ public void should_keep_planned_node_until_node_will_not_be_online_so_jenkins_wi when(ec2Fleet.getState(anyString(), anyString(), anyString(), anyString())).thenReturn( new FleetStateStats("", 0, FleetStateStats.State.active(), Collections.emptySet(), Collections.emptyMap())); - EC2FleetCloud cloud = spy(new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud cloud = spy(new EC2FleetCloud(null, "credId", null, "region", null, "fId", "momo", null, computerConnector, false, false, 0, 0, 10, 0, 1, true, false, "-1", false, 300, 15, false, @@ -168,7 +168,7 @@ public void should_not_keep_planned_node_if_configured_so_jenkins_will_overprovi when(ec2Fleet.getState(anyString(), anyString(), anyString(), anyString())).thenReturn( new FleetStateStats("", 0, FleetStateStats.State.active(), Collections.emptySet(), Collections.emptyMap())); - final EC2FleetCloud cloud = spy(new EC2FleetCloud(null, null, "credId", null, "region", + final EC2FleetCloud cloud = spy(new EC2FleetCloud(null, "credId", null, "region", null, "fId", "momo", null, computerConnector, false, false, 0, 0, 10, 0, 1, true, false, "-1", false, 0, 0, false, @@ -196,7 +196,7 @@ public void should_not_allow_jenkins_to_provision_if_address_not_available() thr ComputerConnector computerConnector = mock(ComputerConnector.class); when(computerConnector.launch(anyString(), any(TaskListener.class))).thenReturn(computerLauncher); - EC2FleetCloud cloud = spy(new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud cloud = spy(new EC2FleetCloud(null, "credId", null, "region", null, "fId", "momo", null, computerConnector, false, false, 0, 0, 10, 0, 1, true, false, "-1", false, 0, 0, false, @@ -257,7 +257,7 @@ public void should_not_convert_planned_to_node_if_state_is_not_running_and_check when(ec2Fleet.getState(anyString(), anyString(), anyString(), anyString())).thenReturn( new FleetStateStats("", 0, FleetStateStats.State.active(), Collections.emptySet(), Collections.emptyMap())); - EC2FleetCloud cloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud cloud = new EC2FleetCloud(null, "credId", null, "region", null, "fId", "momo", null, computerConnector, false, false, 0, 0, 10, 0, 1, true, false, "-1", false, 0, 0, false, @@ -294,7 +294,7 @@ public void should_successfully_create_nodes() throws Exception { when(ec2Fleet.getState(anyString(), anyString(), anyString(), anyString())).thenReturn( new FleetStateStats("", 0, FleetStateStats.State.active(), Collections.emptySet(), Collections.emptyMap())); - EC2FleetCloud cloud = new EC2FleetCloud(null, null, "credId", null, "region", + EC2FleetCloud cloud = new EC2FleetCloud(null, "credId", null, "region", null, "fId", "momo", null, computerConnector, false, false, 0, 0, 2, 0, 1, true, false, "-1", false, 0, 0, false, @@ -325,7 +325,7 @@ public void should_continue_update_after_termination() throws IOException { mockEc2FleetApiToEc2SpotFleet(InstanceStateName.Running, 5); final ComputerConnector computerConnector = new LocalComputerConnector(j); - final EC2FleetCloud cloud = new EC2FleetCloud(null, null, "credId", null, "region", + final EC2FleetCloud cloud = new EC2FleetCloud(null, "credId", null, "region", null, "fId", "momo", null, computerConnector, false, false, 1, 0, 5, 0, 1, true, false, "-1", false, 0, 0, false, @@ -338,13 +338,14 @@ public void should_continue_update_after_termination() throws IOException { j.jenkins.getLabelAtom("momo").nodeProvisioner.suggestReviewNow(); System.out.println("tasks submitted"); - // wait full execution + // wait ful l execution waitJobSuccessfulExecution(tasks); // wait until downscale happens tryUntil(new Runnable() { @Override public void run() { + System.out.println("Inside " + j.jenkins.getLabel("momo").getNodes().size()); // defect in termination logic, that why 1 MatcherAssert.assertThat(j.jenkins.getLabel("momo").getNodes().size(), Matchers.lessThanOrEqualTo(1)); } diff --git a/src/test/java/com/amazon/jenkins/ec2fleet/ProvisionPerformanceTest.java b/src/test/java/com/amazon/jenkins/ec2fleet/ProvisionPerformanceTest.java index 43b4af2a..f835d804 100644 --- a/src/test/java/com/amazon/jenkins/ec2fleet/ProvisionPerformanceTest.java +++ b/src/test/java/com/amazon/jenkins/ec2fleet/ProvisionPerformanceTest.java @@ -39,7 +39,7 @@ private void test(int workers, int maxTasks) throws IOException, InterruptedExce mockEc2FleetApiToEc2SpotFleetWithDelay(InstanceStateName.Running, 500); final ComputerConnector computerConnector = new LocalComputerConnector(j); - final EC2FleetCloudWithMeter cloud = new EC2FleetCloudWithMeter(null, null, "credId", null, "region", + final EC2FleetCloudWithMeter cloud = new EC2FleetCloudWithMeter(null, "credId", null, "region", null, "fId", "momo", null, computerConnector, false, false, 1, 0, workers, 0, 1, true, false, false, 0, 0, false, diff --git a/src/test/java/com/amazon/jenkins/ec2fleet/RealTest.java b/src/test/java/com/amazon/jenkins/ec2fleet/RealTest.java index d2686a3f..51d5d195 100644 --- a/src/test/java/com/amazon/jenkins/ec2fleet/RealTest.java +++ b/src/test/java/com/amazon/jenkins/ec2fleet/RealTest.java @@ -130,7 +130,7 @@ public void run() { 22, sshCredentialId, null, null, null, null, null, null, null, new NonVerifyingKeyVerificationStrategy()); final EC2FleetCloud cloud = new EC2FleetCloud( - "", null, credentialId, null, null, null, + "", credentialId, null, null, null, autoScalingGroupName, "momo", null, computerConnector, false, false, 1, 0, 5, 0, 1, true, false, @@ -182,7 +182,7 @@ public void givenEc2SpotFleet_shouldScaleUpExecuteTaskAndScaleDown() throws Exce 22, sshCredentialId, null, null, null, null, null, null, null, new NonVerifyingKeyVerificationStrategy()); final EC2FleetCloud cloud = new EC2FleetCloud( - "", null, credentialId, null, null, null, + "", credentialId, null, null, null, requestSpotFleetResult.getSpotFleetRequestId(), "momo", null, computerConnector, false, false, 1, 0, 5, 0, 1, true, false, diff --git a/src/test/java/com/amazon/jenkins/ec2fleet/UiIntegrationTest.java b/src/test/java/com/amazon/jenkins/ec2fleet/UiIntegrationTest.java index fa35de5f..d31e96d5 100644 --- a/src/test/java/com/amazon/jenkins/ec2fleet/UiIntegrationTest.java +++ b/src/test/java/com/amazon/jenkins/ec2fleet/UiIntegrationTest.java @@ -72,67 +72,53 @@ public void shouldFindThePluginByShortName() { assertNotNull("should have a valid plugin", wrapper); } - @Test - public void shouldShowAsHiddenCloudIdAsOldId() throws IOException, SAXException { - Cloud cloud = new EC2FleetCloud(null, null, null, null, null, null, null, - null, null, null, false, false, - 0, 0, 0, 0, 0, true, false, - "-1", false, 0, 0, false, - 10, false); - j.jenkins.clouds.add(cloud); - - HtmlPage page = j.createWebClient().goTo("configureClouds"); - - assertTrue(StringUtils.isNotBlank(((HtmlTextInput) IntegrationTest.getElementsByNameWithoutJdk(page, "_.oldId").get(0)).getText())); - } - @Test public void shouldShowNodeConfigurationPage() throws Exception { - EC2FleetCloud cloud = new EC2FleetCloud(null, null, null, null, null, null, null, - null, null, null, false, false, + final String nodeName = "node-name"; + EC2FleetCloud cloud = new EC2FleetCloud("test-cloud", null, null, null, null, null, + "test-label", null, null, false, false, 0, 0, 0, 0, 0, true, false, "-1", false, 0, 0, false, 10, false); j.jenkins.clouds.add(cloud); - j.jenkins.addNode(new EC2FleetNode("node-name", "", "", 1, - Node.Mode.EXCLUSIVE, "", new ArrayList>(), cloud, + j.jenkins.addNode(new EC2FleetNode(nodeName, "", "", 1, + Node.Mode.EXCLUSIVE, "label", new ArrayList>(), cloud.name, j.createComputerLauncher(null), -1)); - HtmlPage page = j.createWebClient().goTo("computer/node-name/configure"); + HtmlPage page = j.createWebClient().goTo("computer/" + nodeName + "/configure"); assertTrue(StringUtils.isNotBlank(((HtmlTextInput) IntegrationTest.getElementsByNameWithoutJdk(page, "_.name").get(0)).getText())); } @Test public void shouldReplaceCloudForNodesAfterConfigurationSave() throws Exception { - EC2FleetCloud cloud = new EC2FleetCloud(null, null, null, null, null, null, "", - null, null, null, false, false, + EC2FleetCloud cloud = new EC2FleetCloud("test-cloud", null, null, null, null, "", + "label", null, null, false, false, 0, 0, 0, 0, 0, true, false, "-1", false, 0, 0, false, 10, false); j.jenkins.clouds.add(cloud); j.jenkins.addNode(new EC2FleetNode("mock", "", "", 1, - Node.Mode.EXCLUSIVE, "", new ArrayList>(), cloud, + Node.Mode.EXCLUSIVE, "", new ArrayList>(), cloud.name, j.createComputerLauncher(null), -1)); HtmlPage page = j.createWebClient().goTo("configureClouds"); HtmlForm form = page.getFormByName("config"); - ((HtmlTextInput) IntegrationTest.getElementsByNameWithoutJdk(page, "_.name").get(0)).setText("a"); + ((HtmlTextInput) IntegrationTest.getElementsByNameWithoutJdk(page, "_.labelString").get(0)).setText("new-label"); HtmlFormUtil.submit(form); final Cloud newCloud = j.jenkins.clouds.get(0); assertNotSame(cloud, newCloud); - assertSame(newCloud, ((EC2FleetNode) j.jenkins.getNode("mock")).getCloud()); } @Test public void shouldShowInConfigurationClouds() throws IOException, SAXException { - Cloud cloud = new EC2FleetCloud(null, null, null, null, null, null, null, + Cloud cloud = new EC2FleetCloud(null, null, null, null, null, null, null, null, null, false, false, 0, 0, 0, 0, 0, true, false, "-1", false, 0, 0, false, @@ -146,15 +132,15 @@ public void shouldShowInConfigurationClouds() throws IOException, SAXException { @Test public void shouldShowMultipleClouds() throws IOException, SAXException { - Cloud cloud1 = new EC2FleetCloud("a", null, null, null, null, null, - null, null, null, null, false, false, + Cloud cloud1 = new EC2FleetCloud("a", null, null, null, null, + null, "label", null, null, false, false, 0, 0, 0, 0, 0, true, false, "-1", false, 0, 0, false, 10, false); j.jenkins.clouds.add(cloud1); - Cloud cloud2 = new EC2FleetCloud("b", null, null, null, null, null, - null, null, null, null, false, false, + Cloud cloud2 = new EC2FleetCloud("b", null, null, null, null, + null, "label", null, null, false, false, 0, 0, 0, 0, 0, true, false, "-1", false, 0, 0, false, 10, false); @@ -170,15 +156,15 @@ public void shouldShowMultipleClouds() throws IOException, SAXException { @Test public void shouldShowMultipleCloudsWithDefaultName() throws IOException, SAXException { - Cloud cloud1 = new EC2FleetCloud(null, null, null, null, null, null, - null, null, null, null, false, false, + Cloud cloud1 = new EC2FleetCloud(null, null, null, null, null, + null, "label", null, null, false, false, 0, 0, 0, 0, 0, true, false, "-1", false, 0, 0, false, 10, false); j.jenkins.clouds.add(cloud1); - Cloud cloud2 = new EC2FleetCloud(null, null, null, null, null, null, - null, null, null, null, false, false, + Cloud cloud2 = new EC2FleetCloud(null, null, null, null, null, + null, "label", null, null, false, false, 0, 0, 0, 0, 0, true, false, "-1", false, 0, 0, false, 10, false); @@ -193,16 +179,16 @@ public void shouldShowMultipleCloudsWithDefaultName() throws IOException, SAXExc } @Test - public void shouldUpdateProperCloudWhenMultiple() throws IOException, SAXException { - EC2FleetCloud cloud1 = new EC2FleetCloud(null, null, null, null, null, null, - null, null, null, null, false, false, + public void shouldUpdateProperCloudWhenMultiple() throws Exception { + EC2FleetCloud cloud1 = new EC2FleetCloud(null, null, null, null, null, + null, "label", null, null, false, false, 0, 0, 0, 0, 0, true, false, "-1", false, 0, 0, false, 10, false); j.jenkins.clouds.add(cloud1); - EC2FleetCloud cloud2 = new EC2FleetCloud(null, null, null, null, null, null, - null, null, null, null, false, false, + EC2FleetCloud cloud2 = new EC2FleetCloud(null, null, null, null, null, + null, "label", null, null, false, false, 0, 0, 0, 0, 0, true, false, "-1", false, 0, 0, false, 10, false); @@ -221,8 +207,8 @@ public void shouldUpdateProperCloudWhenMultiple() throws IOException, SAXExcepti @Test public void shouldContainRegionValueInRegionLabel() throws IOException, SAXException { - EC2FleetCloud cloud1 = new EC2FleetCloud(null, null, "uh", null, null, null, - null, null, null, null, false, false, + EC2FleetCloud cloud1 = new EC2FleetCloud(null, "uh", null, null, null, + null, "label", null, null, false, false, 0, 0, 0, 0, 0, true, false, "-1", false, 0, 0, false, 10, false); @@ -243,8 +229,8 @@ public void shouldContainRegionValueInRegionLabel() throws IOException, SAXExcep public void shouldHaveRegionCodeAndRegionDescriptionInRegionLabel() throws IOException, SAXException { final String regionName = "us-east-1"; final String displayName = "us-east-1 US East (N. Virginia)"; - EC2FleetCloud cloud1 = new EC2FleetCloud(null, null, "uh", null, null, null, - null, null, null, null, false, false, + EC2FleetCloud cloud1 = new EC2FleetCloud(null, "uh", null, null, null, + null, "label", null, null, false, false, 0, 0, 0, 0, 0, true, false, "-1", false, 0, 0, false, 10, false); @@ -270,15 +256,15 @@ public void shouldHaveRegionCodeAndRegionDescriptionInRegionLabel() throws IOExc @Test public void shouldGetFirstWhenMultipleCloudWithSameName() { - EC2FleetCloud cloud1 = new EC2FleetCloud(null, null, null, null, null, null, - null, null, null, null, false, false, + EC2FleetCloud cloud1 = new EC2FleetCloud(null, null, null, null, null, + null, "label", null, null, false, false, 0, 0, 0, 0, 0, true, false, "-1", false, 0, 0, false, 10, false); j.jenkins.clouds.add(cloud1); - EC2FleetCloud cloud2 = new EC2FleetCloud(null, null, null, null, null, null, - null, null, null, null, false, false, + EC2FleetCloud cloud2 = new EC2FleetCloud(null, null, null, null, null, + null, "label", null, null, false, false, 0, 0, 0, 0, 0, true, false, "-1", false, 0, 0, false, 10, false); @@ -289,14 +275,14 @@ public void shouldGetFirstWhenMultipleCloudWithSameName() { @Test public void shouldGetProperWhenMultipleWithDiffName() { - EC2FleetCloud cloud1 = new EC2FleetCloud("a", null, null, null, null, null, + EC2FleetCloud cloud1 = new EC2FleetCloud("a", null, null, null, null, null, null, null, null, false, false, 0, 0, 0, 0, 0, true, false, "-1", false, 0, 0, false, 10, false); j.jenkins.clouds.add(cloud1); - EC2FleetCloud cloud2 = new EC2FleetCloud("b", null, null, null, null, null, + EC2FleetCloud cloud2 = new EC2FleetCloud("b", null, null, null, null, null, null, null, null, false, false, 0, 0, 0, 0, 0, true, false, "-1", false, 0, 0, false, @@ -306,4 +292,31 @@ public void shouldGetProperWhenMultipleWithDiffName() { assertSame(cloud1, j.jenkins.getCloud("a")); assertSame(cloud2, j.jenkins.getCloud("b")); } + + // This is expected behavior until https://github.com/jenkinsci/ec2-fleet-plugin/issues/382 is addressed. + // Current mitigation in place: A warning message is displayed next to the cloud name field in the UI. + // No mitigation for configuration as code users. + @Test + public void verifyCloudNameNotReplacedWhenChangedForNodesAfterConfigurationSave() throws Exception { + EC2FleetCloud cloud = new EC2FleetCloud("test-cloud", null, null, null, null, "", + "label", null, null, false, false, + 0, 0, 0, 0, 0, true, false, + "-1", false, 0, 0, false, + 10, false); + j.jenkins.clouds.add(cloud); + + j.jenkins.addNode(new EC2FleetNode("mock", "", "", 1, + Node.Mode.EXCLUSIVE, "", new ArrayList>(), cloud.name, + j.createComputerLauncher(null), -1)); + + HtmlPage page = j.createWebClient().goTo("configureClouds"); + HtmlForm form = page.getFormByName("config"); + + ((HtmlTextInput) IntegrationTest.getElementsByNameWithoutJdk(page, "_.name").get(0)).setText("new-cloud-name"); + HtmlFormUtil.submit(form); + + final Cloud newCloud = j.jenkins.clouds.get(0); + assertNotSame(cloud, newCloud); + assertNotSame(newCloud.name, ((EC2FleetNode) j.jenkins.getNode("mock")).getCloudName()); + } } diff --git a/src/test/java/com/amazon/jenkins/ec2fleet/utils/EC2FleetCloudAwareUtilsTest.java b/src/test/java/com/amazon/jenkins/ec2fleet/utils/EC2FleetCloudAwareUtilsTest.java deleted file mode 100644 index 3ded1689..00000000 --- a/src/test/java/com/amazon/jenkins/ec2fleet/utils/EC2FleetCloudAwareUtilsTest.java +++ /dev/null @@ -1,124 +0,0 @@ -package com.amazon.jenkins.ec2fleet.utils; - -import com.amazon.jenkins.ec2fleet.EC2FleetCloud; -import com.amazon.jenkins.ec2fleet.EC2FleetNode; -import com.amazon.jenkins.ec2fleet.EC2FleetNodeComputer; -import com.amazon.jenkins.ec2fleet.utils.EC2FleetCloudAwareUtils; -import hudson.model.Computer; -import hudson.model.LabelFinder; -import hudson.model.Node; -import jenkins.model.Jenkins; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; - -import java.util.Arrays; -import java.util.Collections; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -@SuppressWarnings("ArraysAsListWithZeroOrOneArgument") -@RunWith(PowerMockRunner.class) -@PrepareForTest({Jenkins.class, LabelFinder.class}) -public class EC2FleetCloudAwareUtilsTest { - - @Mock - private Jenkins jenkins; - - @Mock - private EC2FleetCloud cloud; - - @Mock - private EC2FleetCloud oldCloud; - - @Mock - private EC2FleetCloud otherCloud; - - @Mock - private EC2FleetNodeComputer computer; - - @Mock - private EC2FleetNode node; - - @Before - public void before() { - PowerMockito.mockStatic(LabelFinder.class); - - PowerMockito.mockStatic(Jenkins.class); - PowerMockito.when(Jenkins.get()).thenReturn(jenkins); - - when(oldCloud.getOldId()).thenReturn("cloud"); - when(computer.getCloud()).thenReturn(oldCloud); - when(node.getCloud()).thenReturn(oldCloud); - - when(cloud.getOldId()).thenReturn("cloud"); - when(otherCloud.getOldId()).thenReturn("other"); - - when(jenkins.getNodes()).thenReturn(Collections.emptyList()); - when(jenkins.getComputers()).thenReturn(new Computer[0]); - } - - @Test - public void reassign_nothing_if_no_nodes_or_computers() { - EC2FleetCloudAwareUtils.reassign("cloud", cloud); - } - - @Test - public void reassign_nothing_if_computers_belong_to_diff_cloud_id() { - when(jenkins.getNodes()).thenReturn(Collections.emptyList()); - when(computer.getCloud()).thenReturn(otherCloud); - when(jenkins.getComputers()).thenReturn(new Computer[]{computer}); - - EC2FleetCloudAwareUtils.reassign("cloud", cloud); - - verify(computer, times(0)).setCloud(any(EC2FleetCloud.class)); - } - - @Test - public void reassign_nothing_if_computer_cloud_is_null() { - when(computer.getCloud()).thenReturn(null); - when(jenkins.getComputers()).thenReturn(new Computer[]{computer}); - - EC2FleetCloudAwareUtils.reassign("cloud", cloud); - - verify(computer, times(0)).setCloud(any(EC2FleetCloud.class)); - } - - @Test - public void reassign_if_computer_belong_to_old_cloud() { - when(jenkins.getComputers()).thenReturn(new Computer[]{computer}); - - EC2FleetCloudAwareUtils.reassign("cloud", cloud); - - verify(computer, times(1)).setCloud(cloud); - } - - @Test - public void reassign_if_node_belong_to_same_cloud() { - when(computer.getCloud()).thenReturn(cloud); - when(jenkins.getNodes()).thenReturn(Arrays.asList((Node) node)); - - EC2FleetCloudAwareUtils.reassign("cloud", cloud); - - verify(node, times(1)).setCloud(cloud); - } - - @Test - public void reassign_nothing_if_node_belong_to_other_cloud_id() { - when(computer.getCloud()).thenReturn(cloud); - when(node.getCloud()).thenReturn(otherCloud); - when(jenkins.getNodes()).thenReturn(Arrays.asList((Node) node)); - - EC2FleetCloudAwareUtils.reassign("cloud", cloud); - - verify(node, times(0)).setCloud(cloud); - } - -}