diff --git a/src/main/java/jenkins/metrics/impl/JenkinsMetricProviderImpl.java b/src/main/java/jenkins/metrics/impl/JenkinsMetricProviderImpl.java index cbe7f9e..7aab1a5 100644 --- a/src/main/java/jenkins/metrics/impl/JenkinsMetricProviderImpl.java +++ b/src/main/java/jenkins/metrics/impl/JenkinsMetricProviderImpl.java @@ -1018,7 +1018,7 @@ private void checkEnterQueue(Queue.Item i) { null, null); executorService.submit(() -> { - QueueItemMetricsListener.notifyStarted(m); + QueueItemMetricsListener.notifyQueued(m); }); return new ItemTotals(id); }); diff --git a/src/test/java/jenkins/metrics/impl/JenkinsMetricProviderImplTest.java b/src/test/java/jenkins/metrics/impl/JenkinsMetricProviderImplTest.java index bf7cec1..435aa84 100644 --- a/src/test/java/jenkins/metrics/impl/JenkinsMetricProviderImplTest.java +++ b/src/test/java/jenkins/metrics/impl/JenkinsMetricProviderImplTest.java @@ -25,48 +25,89 @@ package jenkins.metrics.impl; import hudson.ExtensionList; +import hudson.model.FreeStyleBuild; import hudson.model.FreeStyleProject; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.concurrent.TimeUnit; +import hudson.model.queue.QueueTaskFuture; import jenkins.metrics.api.Metrics; import jenkins.metrics.api.QueueItemMetricsEvent; import jenkins.metrics.api.QueueItemMetricsListener; +import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; +import org.jvnet.hudson.test.BuildWatcher; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.SleepBuilder; import org.jvnet.hudson.test.TestExtension; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.TimeUnit; + +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.emptyCollectionOf; import static org.hamcrest.Matchers.greaterThan; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.lessThan; import static org.hamcrest.Matchers.notNullValue; -import static org.junit.Assert.assertThat; public class JenkinsMetricProviderImplTest { @Rule public JenkinsRule j = new JenkinsRule(); + @ClassRule + public static BuildWatcher w = new BuildWatcher(); + + @Test + public void given__a_job_which_is_cancelled() throws Exception { + MyListener listener = ExtensionList.lookup(QueueItemMetricsListener.class).get(MyListener.class); + assertThat(listener, notNullValue()); + + FreeStyleProject job = j.createProject(FreeStyleProject.class); + + QueueTaskFuture taskFuture = job.scheduleBuild2(10); + taskFuture.cancel(true); + + try{ + j.waitForCompletion(taskFuture.waitForStart()); + }catch (Throwable t){ + //CancellationException expected + } + + //wait for completion + while (!listener.state.toString().contains("C")){ + Thread.sleep(10); + } + + assertThat(listener.state.toString(), is("QC")); + + } + @Test public void given__a_job__when__built__then__events_and_metrics_include_build() throws Exception { j.jenkins.setQuietPeriod(0); MyListener listener = ExtensionList.lookup(QueueItemMetricsListener.class).get(MyListener.class); assertThat(listener, notNullValue()); + FreeStyleProject p = j.createProject(FreeStyleProject.class); p.setQuietPeriod(0); p.getBuildersList().add(new SleepBuilder(3000)); assertThat(Metrics.metricRegistry().getTimers().get("jenkins.job.building.duration").getCount(), is(0L)); assertThat(listener.getEvents(), is(emptyCollectionOf(QueueItemMetricsEvent.class))); j.assertBuildStatusSuccess(p.scheduleBuild2(2)); + + //wait for completion + while (!listener.state.toString().contains("F")){ + Thread.sleep(10); + } + assertThat(listener.state.toString(), is("QSF")); + assertThat(Metrics.metricRegistry().getTimers().get("jenkins.job.building.duration").getCount(), is(1L)); assertThat(Metrics.metricRegistry().getTimers().get("jenkins.job.building.duration").getSnapshot().getMean(), allOf(greaterThan(TimeUnit.MILLISECONDS.toNanos(2500)*1.0), - lessThan(TimeUnit.MILLISECONDS.toNanos(3500) * 1.0))); + lessThan(TimeUnit.MILLISECONDS.toNanos(3800) * 1.0))); List events = listener.getEvents(); assertThat(events.size(), is(3)); Collections.sort(events, QueueItemMetricsEvent::compareEventSequence); @@ -89,16 +130,18 @@ public void given__a_job__when__built__then__events_and_metrics_include_build() assertThat(events.get(2).getExecutable(), is(Optional.of(p.getBuildByNumber(1)))); assertThat(events.get(2).getQueuingTotalMillis().orElse(null), greaterThan(1500L)); assertThat(events.get(2).getQueuingWaitingMillis().orElse(null), greaterThan(1500L)); - assertThat(events.get(2).getExecutingMillis().orElse(null), allOf(greaterThan(2500L), lessThan(3500L))); + assertThat(events.get(2).getExecutingMillis().orElse(null), allOf(greaterThan(2500L), lessThan(3800L))); assertThat(events.get(2).getExecutorCount().orElse(null), is(1)); } @TestExtension public static class MyListener extends QueueItemMetricsListener { private final List events = new ArrayList<>(); + public StringBuilder state = new StringBuilder(); @Override public void onQueued(QueueItemMetricsEvent event) { + state.append("Q"); synchronized (events) { events.add(event); } @@ -107,6 +150,7 @@ public void onQueued(QueueItemMetricsEvent event) { @Override public void onCancelled(QueueItemMetricsEvent event) { + state.append("C"); synchronized (events) { events.add(event); } @@ -114,6 +158,7 @@ public void onCancelled(QueueItemMetricsEvent event) { @Override public void onStarted(QueueItemMetricsEvent event) { + state.append("S"); synchronized (events) { events.add(event); } @@ -121,6 +166,7 @@ public void onStarted(QueueItemMetricsEvent event) { @Override public void onFinished(QueueItemMetricsEvent event) { + state.append("F"); synchronized (events) { events.add(event); }