Skip to content

Commit

Permalink
Reproducing issue JENKINS-33219 by test (and neccessary update of jen…
Browse files Browse the repository at this point in the history
…kins version)
  • Loading branch information
Lucie Votypkova committed Sep 14, 2017
1 parent 04b3ea2 commit a13fd18
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 104 deletions.
31 changes: 21 additions & 10 deletions pom.xml
@@ -1,17 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>1.580.3</version>
</parent>
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>2.29</version>
</parent>

<artifactId>disk-usage</artifactId>
<packaging>hpi</packaging>
<name>Jenkins disk-usage plugin</name>
<version>0.29-SNAPSHOT</version>
<url>http://wiki.jenkins-ci.org/display/JENKINS/Disk+Usage+Plugin</url>

<properties>
<jenkins.version>1.650</jenkins.version>
</properties>

<artifactId>disk-usage</artifactId>
<packaging>hpi</packaging>
<name>Jenkins disk-usage plugin</name>
<version>0.29-SNAPSHOT</version>
<url>http://wiki.jenkins-ci.org/display/JENKINS/Disk+Usage+Plugin</url>

<developers>
<developer>
Expand Down Expand Up @@ -94,6 +99,12 @@
<version>2.28</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.olivergondza.dumpling</groupId>
<artifactId>dumpling</artifactId>
<version>2.2</version>
<scope>test</scope>
</dependency>
</dependencies>

<repositories>
Expand Down
Expand Up @@ -32,7 +32,6 @@
* Entry point of the the plugin.
*
* @author dvrzalik
* @plugin
*/
@Extension
public class DiskUsagePlugin extends Plugin {
Expand Down
Expand Up @@ -4,6 +4,11 @@
*/
package hudson.plugins.disk_usage.integration;

import com.github.olivergondza.dumpling.factory.JvmRuntimeFactory;
import com.github.olivergondza.dumpling.model.jvm.JvmThread;
import com.github.olivergondza.dumpling.model.jvm.JvmThreadSet;
import com.github.olivergondza.dumpling.query.BlockingTree;
import com.github.olivergondza.dumpling.query.Deadlocks;
import hudson.EnvVars;
import hudson.model.FreeStyleBuild;
import hudson.model.Items;
Expand All @@ -14,11 +19,21 @@
import hudson.tasks.Shell;
import java.io.File;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.MonitorInfo;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.Stack;

import hudson.FilePath;
import hudson.plugins.disk_usage.DiskUsageProperty;
import hudson.model.AbstractProject;
import jenkins.model.Jenkins;
import jenkins.model.lazy.BuildReference;
import org.apache.tools.mail.ErrorInQuitException;
import org.junit.*;
import hudson.model.FreeStyleProject;
import org.jvnet.hudson.reactor.ReactorException;
Expand All @@ -33,21 +48,21 @@
* @author Lucie Votypkova
*/
public class DiskUsageBuildListenerTest {

@Rule
public JenkinsRule j = new JenkinsRule();

@BeforeClass
public static void setEnvironmentVariables() throws IOException {
System.setProperty("jenkins.model.lazy.BuildReference.MODE", "weak");

System.setProperty("jenkins.test.timeout","10000");
System.setProperty("maven.surefire.debug","10000");
// j.jenkins.getGlobalNodeProperties().add(prop);
System.setProperty("jenkins.test.timeout", "10000");
System.setProperty("maven.surefire.debug", "10000");
// j.jenkins.getGlobalNodeProperties().add(prop);
}

@Test
public void testOnDeleted() throws Exception{
public void testOnDeleted() throws Exception {
AbstractProject project = j.createFreeStyleProject();
j.buildAndAssertSuccess(project);
j.buildAndAssertSuccess(project);
Expand All @@ -58,103 +73,108 @@ public void testOnDeleted() throws Exception{
assertNotNull("Disk usage property whoud contains cashed information about build 1.", property.getDiskUsageOfBuild(1));
assertNotNull("Disk usage property whoud contains cashed information about build 3.", property.getDiskUsageOfBuild(3));
}

@Test
public void testOnCompleted() throws Exception{
public void testOnCompleted() throws Exception {
j.timeout = 10000;
FreeStyleProject project = j.createFreeStyleProject();
project.getBuildersList().add(new Shell("echo ahoj > log.log"));
j.buildAndAssertSuccess(project);
DiskUsageProperty property = (DiskUsageProperty) project.getProperty(DiskUsageProperty.class);
assertNotNull("Build information is cached.", property.getDiskUsageBuildInformation(1));
assertTrue("Build disk usage should be counted.", property.getDiskUsageOfBuild(1)>0);
assertTrue("Workspace of build should be counted.", property.getAllWorkspaceSize()>0);
assertTrue("Build disk usage should be counted.", property.getDiskUsageOfBuild(1) > 0);
assertTrue("Workspace of build should be counted.", property.getAllWorkspaceSize() > 0);
}


@Issue("JENKINS-33219")
@Test(timeout = 10000000L)
@Test(timeout = 400000L)
@LocalData
public void testOnLoadCauseDeadLock() throws Exception {
j.timeout = 10000;
BuildReference.DefaultHolderFactory f = new BuildReference.DefaultHolderFactory();

FreeStyleProject p = (FreeStyleProject) j.jenkins.getItem("job");
final File file = p.getConfigFile().getFile().getParentFile();


System.err.println(p.getConfigFile().getFile().exists() + " " + p.getConfigFile().getFile().getAbsolutePath());
// j.buildAndAssertSuccess(project);
p.removeProperty(DiskUsageProperty.class);
final FreeStyleBuild build = p.getLastBuild();
System.err.println("holder " + f.make(build).getClass() + " builds is " + p.getBuilds().toArray().length);

p = (FreeStyleProject) j.jenkins.getItem("job");
System.err.println("loaded builds " + p._getRuns().getLoadedBuilds());
final DiskUsageBuildListener listener = RunListener.all().get(DiskUsageBuildListener.class);
Thread onLoad = new Thread(){

public void run(){
FreeStyleProject project = (FreeStyleProject) j.jenkins.getItem("job");
int count = 0;
while(count<50){
count++;
project = (FreeStyleProject) j.jenkins.getItem("job");
BuildDiskUsageAction action = new BuildDiskUsageAction(project.getBuildByNumber(106));
System.err.println("loadedBuilds " + project._getRuns().getLoadedBuilds());
try {


project = (FreeStyleProject) Items.load(j.jenkins, file);
synchronized(j.jenkins) {
j.jenkins.remove(project);
j.jenkins.putItem(project);
}
project.getProperty(DiskUsageProperty.class).getDiskUsage().getConfigFile().delete();
project.removeProperty(DiskUsageProperty.class);
} catch (Exception e) {
e.printStackTrace();
}
// it is necessary to call it many times in cycle and it contains IO operations, so the test can take little longer
j.timeout = 400;
AddNewProperty onLoad = new AddNewProperty(j.jenkins);
UpdateNexBuildNumber nextBuildNumber = new UpdateNexBuildNumber(j.jenkins);
onLoad.start();
nextBuildNumber.start();
while(!onLoad.isFinished || !nextBuildNumber.isFinished) {
Deadlocks deadlocks = new Deadlocks();
Set<JvmThreadSet> set = deadlocks.query(new JvmRuntimeFactory().currentRuntime().getThreads()).getDeadlocks();
if(!set.isEmpty()) {
System.err.println("Deadlock was detected:");
for(JvmThreadSet s : set) {
System.err.println(s);
}
fail("Deadlock was detected.");
}
Thread.sleep(6000);
}
}

System.err.println("thread onLoad done, cycle left " + count + " loaded builds " + project._getRuns().getLoadedBuilds());


public static class UpdateNexBuildNumber extends Thread {
public boolean isFinished = false;
public static String name = "Add new property";
private Jenkins jenkins;

public UpdateNexBuildNumber(Jenkins jenkins) {
super(name);
this.jenkins = jenkins;
}

public void run() {
int count = 0;
while (count < 100) {
try {
//get project without DiskUsageProperty
FreeStyleProject project = DiskUsageTestUtil.getProject(jenkins, "job");
project.getLazyBuildMixIn().getBuildByNumber(55);
//need to force loading of build - so load job again without builds for next loop
project = DiskUsageTestUtil.prepareProjet(jenkins,project);
} catch (Exception e) {
e.printStackTrace();
} catch (Error e) {
e.printStackTrace();
}
count++;
}
isFinished = true;

}

}
};
Thread nextBuildNumber = new Thread(){

public void run(){

int count = 0;
FreeStyleProject project = (FreeStyleProject) j.jenkins.getItem("job");
while(count<50) {
count++;
try {
project = (FreeStyleProject) j.jenkins.getItem("job");
project.updateNextBuildNumber(107 + count);
project = (FreeStyleProject) Items.load(j.jenkins, file);
synchronized (j.jenkins) {
j.jenkins.remove(project);
j.jenkins.putItem(project);
}
project.getProperty(DiskUsageProperty.class).getDiskUsage().getConfigFile().delete();
project.removeProperty(DiskUsageProperty.class);
} catch (Exception e) {
e.printStackTrace();
}
System.err.println("loadedBuilds2 " + project._getRuns().getLoadedBuilds());

System.err.println("thread nextBuildNumber done, cycle left " + count + " loaded builds " + project._getRuns().getLoadedBuilds());
}
}

public static class AddNewProperty extends Thread {

public boolean isFinished = false;
public static String name = "Update next build number";
private Jenkins jenkins;

public AddNewProperty(Jenkins jenkins) {
super(name);
this.jenkins = jenkins;
}

public void run() {
int count = 0;
while (count < 100) {
try {
//get project without DiskUsageProperty
FreeStyleProject project = DiskUsageTestUtil.getProject(jenkins, "job");
project.updateNextBuildNumber(107 + count);
//need to force loading of build - so load job again without it
project = DiskUsageTestUtil.prepareProjet(jenkins,project);
} catch (Exception e) {
e.printStackTrace();
} catch (Error e) {
e.printStackTrace();
}
count++;
}
};
onLoad.start();
nextBuildNumber.start();
onLoad.join();
nextBuildNumber.join();
isFinished = true;
}
}


}
Expand Up @@ -499,8 +499,8 @@ public void run(){
GregorianCalendar calendar = new GregorianCalendar();
calendar.set(2014, 1, 1);
calendar.add(GregorianCalendar.MINUTE, count);
Run.ID_FORMATTER.get().format(calendar.getTime());
diskUsage.addBuildInformation(new DiskUsageBuildInformation(Run.ID_FORMATTER.get().format(calendar.getTime()),calendar.getTimeInMillis(), count, 0l), null);
//Run.ID_FORMATTER.get().format(calendar.getTime());
diskUsage.addBuildInformation(new DiskUsageBuildInformation("" +count,calendar.getTimeInMillis(), count, 0l), null);

}
} catch (ConcurrentModificationException ex) {
Expand Down
Expand Up @@ -4,12 +4,11 @@
*/
package hudson.plugins.disk_usage.integration;

import hudson.model.AbstractBuild;
import hudson.model.Action;
import hudson.model.*;
import hudson.model.Node.Mode;
import hudson.model.Slave;
import hudson.plugins.disk_usage.BuildDiskUsageAction;
import hudson.plugins.disk_usage.DiskUsageCalculation;
import hudson.plugins.disk_usage.DiskUsageProperty;
import hudson.slaves.ComputerLauncher;
import hudson.slaves.DumbSlave;
import hudson.slaves.NodeProperty;
Expand Down Expand Up @@ -85,4 +84,19 @@ protected static void createFileWithContent(File file) throws FileNotFoundExcept
stream.println("hello");
stream.close();
}

public static synchronized FreeStyleProject prepareProjet(Jenkins jenkins, FreeStyleProject project) throws Exception {
project = (FreeStyleProject) Items.load(jenkins,project.getConfigFile().getFile().getParentFile());
jenkins.remove(project);
jenkins.putItem(project);
project.removeProperty(DiskUsageProperty.class);
return project;
}

public static synchronized FreeStyleProject getProject(Jenkins jenkins, String name) throws Exception {
FreeStyleProject project = (FreeStyleProject) jenkins.getItem(name);
project.removeProperty(DiskUsageProperty.class);
return project;

}
}
Expand Up @@ -150,7 +150,7 @@ public void testCalculateDiskUsageWorkspaceForMatrixProjectWithConfigurationInSa
AxisList axes = new AxisList();
TextAxis axis1 = new TextAxis("axis","axis1 axis2 axis3");
axes.add(axis1);
MatrixProject project1 = j.createMatrixProject("project1");
MatrixProject project1 = j.createProject(MatrixProject.class, "project1");
project1.setAxes(axes);
project1.setAssignedNode(slave1);
j.buildAndAssertSuccess(project1);
Expand Down Expand Up @@ -232,7 +232,7 @@ public void testCalculateDiskUsageWorkspaceWhenReferenceFromJobDoesNotExists() t
AxisList axes = new AxisList();
TextAxis axis1 = new TextAxis("axis","axis1 axis2 axis3");
axes.add(axis1);
MatrixProject project1 = j.createMatrixProject("project1");
MatrixProject project1 = j.createProject(MatrixProject.class,"project1");
project1.setAxes(axes);
project1.setAssignedNode(slave1);
j.buildAndAssertSuccess(project1);
Expand Down
Expand Up @@ -43,7 +43,9 @@
*
* @author Lucie Votypkova
*/
public class WorkspaceDiskUsageCalculationThreadTest extends HudsonTestCase{
public class WorkspaceDiskUsageCalculationThreadTest extends HudsonTestCase{


private void waitUntilThreadEnds(WorkspaceDiskUsageCalculationThread calculation) throws InterruptedException{
Thread thread = null;
//wait until thread ends
Expand Down Expand Up @@ -132,11 +134,11 @@ public void testExecuteMatrixProject() throws Exception {
AxisList axes = new AxisList();
TextAxis axis1 = new TextAxis("axis","axis1 axis2 axis3");
axes.add(axis1);
MatrixProject project1 = createMatrixProject("project1");
MatrixProject project1 = jenkins.createProject(MatrixProject.class, "project1");
project1.setAxes(axes);
project1.setAssignedNode(slave1);
buildAndAssertSuccess(project1);
MatrixProject project2 = createMatrixProject("project2");
MatrixProject project2 = jenkins.createProject(MatrixProject.class,"project2");
AxisList axes2 = new AxisList();
TextAxis axis2 = new TextAxis("axis","axis1 axis2");
axes2.add(axis2);
Expand Down

0 comments on commit a13fd18

Please sign in to comment.