Skip to content

Commit

Permalink
[FIXED JENKINS-22575] Optinally keep records for deleted builds up to…
Browse files Browse the repository at this point in the history
… Plot#numBuilds
  • Loading branch information
olivergondza committed Sep 10, 2014
1 parent 0fc3da7 commit 78af008
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 10 deletions.
37 changes: 31 additions & 6 deletions src/main/java/hudson/plugins/plot/Plot.java
Expand Up @@ -29,8 +29,6 @@
import java.util.logging.Level;
import java.util.logging.Logger;

import au.com.bytecode.opencsv.CSVReader;
import au.com.bytecode.opencsv.CSVWriter;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.jfree.chart.ChartFactory;
Expand All @@ -50,6 +48,9 @@
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;

import au.com.bytecode.opencsv.CSVReader;
import au.com.bytecode.opencsv.CSVWriter;

/**
* Represents the configuration for a single plot. A plot can
* have one or more data series (lines). Each data series
Expand Down Expand Up @@ -177,14 +178,17 @@ public class Plot implements Comparable<Plot> {
/** Whether or not to use build descriptions as X-axis labels. Optional. */
public boolean useDescr;

/** keep records for builds that was deleted */
private boolean keepRecords;

/**
* Creates a new plot with the given paramenters. If numBuilds
* is the empty string, then all builds will be included. Must
* not be zero.
*/
@DataBoundConstructor
public Plot(String title, String yaxis,
String group, String numBuilds, String csvFileName, String style, boolean useDescr)
String group, String numBuilds, String csvFileName, String style, boolean useDescr, boolean keepRecords)
{
this.title = title;
this.yaxis = yaxis;
Expand All @@ -197,11 +201,24 @@ public Plot(String title, String yaxis,
this.csvFileName = csvFileName;
this.style = style;
this.useDescr = useDescr;
this.keepRecords = keepRecords;
}

/**
* @deprecated Kept for backward compatibility.
*/
@Deprecated
public Plot(String title, String yaxis, String group, String numBuilds, String csvFileName, String style, boolean useDescr) {
this(title, yaxis, group, numBuilds, csvFileName, style, useDescr, false);
}

// needed for serialization
public Plot() {}

public boolean getKeepRecords() {
return keepRecords;
}

public int compareTo(Plot o) {
return title.compareTo(o.getTitle());
}
Expand Down Expand Up @@ -542,8 +559,7 @@ public String numDateString() {
int buildNum;
try {
buildNum = Integer.valueOf(record[2]);
if (project.getBuildByNumber(buildNum) == null
|| buildNum > getRightBuildNum()) {
if (!reportBuild(buildNum) || buildNum > getRightBuildNum()) {
continue; // skip this record
}
} catch (NumberFormatException nfe) {
Expand Down Expand Up @@ -736,7 +752,7 @@ private void savePlotData() {
writer.writeNext(header2);
// write each entry of rawPlotData to a new line in the CSV file
for (String[] entry : rawPlotData) {
if (project.getBuildByNumber(Integer.parseInt(entry[2])) != null) {
if (reportBuild(Integer.parseInt(entry[2]))) {
writer.writeNext(entry);
}
}
Expand All @@ -752,4 +768,13 @@ private void savePlotData() {
}
}
}

/**
* @return true if the build should be part of the graph.
*/
/*package*/ boolean reportBuild(int buildNumber) {
int numBuilds = Integer.parseInt(this.numBuilds);
if (buildNumber < project.getNextBuildNumber() - numBuilds) return false;
return keepRecords || project.getBuildByNumber(buildNumber) != null;
}
}
8 changes: 4 additions & 4 deletions src/main/java/hudson/plugins/plot/PlotReport.java
Expand Up @@ -9,18 +9,18 @@
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.ArrayList;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;

import au.com.bytecode.opencsv.CSVReader;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;

/**
* Represents a plot report for a single group of plots.
Expand Down Expand Up @@ -120,7 +120,7 @@ public List<List<String>> getTable(int i) {
String[] nextLine;
while ((nextLine = reader.readNext()) != null) {
String buildNumber = nextLine[2];
if (project.getBuildByNumber(Integer.parseInt(buildNumber)) == null) {
if (!plot.reportBuild(Integer.parseInt(buildNumber))) {
continue;
}
String seriesLabel = nextLine[1];
Expand Down
Expand Up @@ -42,6 +42,10 @@
<f:checkbox name="useDescr" checked="${plot.useDescr}" />
</f:entry>

<f:entry title="${%Keep records for deleted builds}" help="/plugin/plot/help-keepRecords.html">
<f:checkbox name="keepRecords" checked="${plot.keepRecords}" />
</f:entry>

<f:entry title="" description="${%A new data series definition}">
<f:repeatable var="series" items="${plot.series}" minimum="1">
<table width="100%" bgcolor="#EEEEEE">
Expand Down
5 changes: 5 additions & 0 deletions src/main/webapp/help-keepRecords.html
@@ -0,0 +1,5 @@
<div>
When unchecked (default), data from deleted builds are not part of the graph.
<p/>
When checked, show all builds up to 'Number of builds to include'.
</div>
137 changes: 137 additions & 0 deletions src/test/java/hudson/plugins/plot/PlotTest.java
@@ -0,0 +1,137 @@
/*
* The MIT License
*
* Copyright (c) 2014 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson.plugins.plot;

import static org.junit.Assert.assertEquals;
import hudson.model.FreeStyleProject;
import hudson.model.Job;
import hudson.tasks.LogRotator;
import hudson.tasks.Shell;

import java.util.Arrays;
import java.util.List;

import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.test.JenkinsRule;

public class PlotTest {

@Rule public JenkinsRule j = new JenkinsRule();

@Test
public void discardPlotSamplesForOldBuilds() throws Exception {
FreeStyleProject p = jobArchivingBuilds(1);

plotBuilds(p, 2, false);

j.buildAndAssertSuccess(p);
assertSampleCount(p, 1);

j.buildAndAssertSuccess(p);
assertSampleCount(p, 1); // Truncated to 1

j.buildAndAssertSuccess(p);
assertSampleCount(p, 1); // Still 1
}

@Test
public void discardPlotSamplesForDeletedBuilds() throws Exception {
FreeStyleProject p = jobArchivingBuilds(10);

plotBuilds(p, 10, false);

j.buildAndAssertSuccess(p);
assertSampleCount(p, 1);

j.buildAndAssertSuccess(p);
assertSampleCount(p, 2);

j.buildAndAssertSuccess(p);
assertSampleCount(p, 3);

p.getLastBuild().delete();
assertSampleCount(p, 2); // Data should be removed with the build
}

@Test
public void keepPlotSamplesForOldBuilds() throws Exception {
FreeStyleProject p = jobArchivingBuilds(1);

plotBuilds(p, 2, true);

j.buildAndAssertSuccess(p);
assertSampleCount(p, 1);

j.buildAndAssertSuccess(p);
assertSampleCount(p, 2);

j.buildAndAssertSuccess(p);
assertSampleCount(p, 2); // Plot 2 builds

j.buildAndAssertSuccess(p);
assertSampleCount(p, 2); // Still 2
}

@Test
public void keepPlotSamplesForDeletedBuilds() throws Exception {
FreeStyleProject p = jobArchivingBuilds(10);

plotBuilds(p, 10, true);

j.buildAndAssertSuccess(p);
assertSampleCount(p, 1);

j.buildAndAssertSuccess(p);
assertSampleCount(p, 2);

j.buildAndAssertSuccess(p);
assertSampleCount(p, 3);

p.getLastBuild().delete();
assertSampleCount(p, 3); // Data should be kept
}

private FreeStyleProject jobArchivingBuilds(int count) throws Exception {
FreeStyleProject p = j.createFreeStyleProject();
p.getBuildersList().add(new Shell("echo YVALUE=$BUILD_NUMBER > src.properties"));
p.setBuildDiscarder(new LogRotator(-1, count, -1, -1));

return p;
}

private void plotBuilds(FreeStyleProject p, int count, boolean keepRecords) {
final PlotPublisher publisher = new PlotPublisher();
final Plot plot = new Plot("Title", "Number", "default", String.valueOf(count), null, "line", false, keepRecords);
p.getPublishersList().add(publisher);
publisher.addPlot(plot);
plot.series = Arrays.<Series>asList(new PropertiesSeries("src.properties", null));
}

private void assertSampleCount(Job p, int count) throws Exception {
PlotReport pr = p.getAction(PlotAction.class).getDynamic("default", null, null);
List<List<String>> table = pr.getTable(0);
assertEquals("Plot sample count", count, table.size() - 1);
}
}

0 comments on commit 78af008

Please sign in to comment.