Skip to content

Commit

Permalink
fix [JENKINS-45095]
Browse files Browse the repository at this point in the history
implement Queuelistener that will cleanup the memory when queue entry is
cancelled.
  • Loading branch information
mawinter69 committed Jul 25, 2017
1 parent 1b5a1e6 commit e3ec526
Show file tree
Hide file tree
Showing 5 changed files with 265 additions and 54 deletions.
Expand Up @@ -23,39 +23,39 @@
*/
package com.sonyericsson.hudson.plugins.gerrit.trigger.gerritnotifier;

import com.sonyericsson.hudson.plugins.gerrit.trigger.diagnostics.BuildMemoryReport;
import com.sonymobile.tools.gerrit.gerritevents.dto.events.GerritTriggeredEvent;
import com.sonyericsson.hudson.plugins.gerrit.trigger.events.lifecycle.GerritEventLifecycle;
import com.sonyericsson.hudson.plugins.gerrit.trigger.gerritnotifier.model.BuildMemory;
import com.sonyericsson.hudson.plugins.gerrit.trigger.gerritnotifier.model.BuildsStartedStats;
import com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.GerritCause;
import com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.GerritTrigger;

import hudson.EnvVars;
import hudson.Extension;
import hudson.ExtensionList;
import hudson.FilePath;
import hudson.model.Result;
import hudson.model.TaskListener;
import hudson.model.AbstractBuild;
import hudson.model.Cause;
import hudson.model.CauseAction;
import hudson.model.Job;
import hudson.model.Result;
import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.model.listeners.RunListener;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.List;

import jenkins.model.Jenkins;

import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import jenkins.model.Jenkins;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sonyericsson.hudson.plugins.gerrit.trigger.diagnostics.BuildMemoryReport;
import com.sonyericsson.hudson.plugins.gerrit.trigger.events.lifecycle.GerritEventLifecycle;
import com.sonyericsson.hudson.plugins.gerrit.trigger.gerritnotifier.model.BuildMemory;
import com.sonyericsson.hudson.plugins.gerrit.trigger.gerritnotifier.model.BuildsStartedStats;
import com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.GerritCause;
import com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.GerritTrigger;
import com.sonymobile.tools.gerrit.gerritevents.dto.events.GerritTriggeredEvent;

/**
* The Big RunListener in charge of coordinating build results and reporting back to Gerrit.
*
Expand Down Expand Up @@ -401,6 +401,20 @@ public boolean isTriggered(Job project, GerritTriggeredEvent event) {
}
}

/**
* Sets the memory of the project to buildCompleted. Used when the entry is canceled in the Queue.
*
* @param project the project
* @param event the event
*/
public void setQueueCancelled(Job project, GerritTriggeredEvent event) {
if (project == null || event == null) {
return;
} else {
memory.cancelled(event, project);
}
}

/**
* Finds the GerritCause for a build if there is one.
*
Expand Down
Expand Up @@ -24,24 +24,13 @@
*/
package com.sonyericsson.hudson.plugins.gerrit.trigger.gerritnotifier.model;

import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
import com.sonyericsson.hudson.plugins.gerrit.trigger.diagnostics.BuildMemoryReport;
import com.sonyericsson.hudson.plugins.gerrit.trigger.gerritnotifier.model.BuildMemory.MemoryImprint.Entry;
import com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.GerritCause;
import com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.GerritTrigger;
import com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.data.TriggerContext;
import com.sonymobile.tools.gerrit.gerritevents.dto.events.GerritTriggeredEvent;
import static com.sonyericsson.hudson.plugins.gerrit.trigger.utils.Logic.shouldSkip;
import hudson.model.Result;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.Job;
import hudson.model.Result;
import hudson.model.Run;
import jenkins.model.Jenkins;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Comparator;
Expand All @@ -50,7 +39,21 @@
import java.util.Map;
import java.util.TreeMap;

import static com.sonyericsson.hudson.plugins.gerrit.trigger.utils.Logic.shouldSkip;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;

import jenkins.model.Jenkins;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.infradna.tool.bridge_method_injector.WithBridgeMethods;
import com.sonyericsson.hudson.plugins.gerrit.trigger.diagnostics.BuildMemoryReport;
import com.sonyericsson.hudson.plugins.gerrit.trigger.gerritnotifier.model.BuildMemory.MemoryImprint.Entry;
import com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.GerritCause;
import com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.GerritTrigger;
import com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.data.TriggerContext;
import com.sonymobile.tools.gerrit.gerritevents.dto.events.GerritTriggeredEvent;

/**
* Keeps track of what builds have been triggered and if all builds are done for specific events.
Expand Down Expand Up @@ -233,6 +236,23 @@ public synchronized void retriggered(
pb.reset(project);
}

/**
* Sets the status if a project to completed when queue is cancelled.
*
* @param event the event to be retriggered.
* @param project the project that has been retriggered.
*/
public synchronized void cancelled(GerritTriggeredEvent event, Job project) {
MemoryImprint pb = memory.get(event);
if (pb == null) {
//Shoudn't happen but just in case, keep the memory.
pb = new MemoryImprint(event);
memory.put(event, pb);
}
pb.set(project, true);
}


/**
* Removes the memory for the event.
*
Expand Down Expand Up @@ -344,11 +364,7 @@ public synchronized boolean isBuilding(GerritTriggeredEvent event, Job project)
} else {
for (Entry entry : pb.getEntries()) {
if (entry.isProject(project)) {
if (entry.getBuild() != null) {
return !entry.isBuildCompleted();
} else {
return true;
}
return !entry.isBuildCompleted();
}
}
return false;
Expand Down Expand Up @@ -571,6 +587,23 @@ private synchronized void set(Job project, Run build, boolean buildCompleted) {
}
}

/**
* Sets all the values of an entry and adds it if the project has not been added before.
*
* @param project the project
* @param buildCompleted if the build is finished.
*/
private synchronized void set(Job project, boolean buildCompleted) {
Entry entry = getEntry(project);
if (entry == null) {
entry = new Entry(project);
entry.setBuildCompleted(buildCompleted);
list.add(entry);
} else {
entry.setBuildCompleted(buildCompleted);
}
}

/**
* Tells if all builds have a value (not null).
*
Expand Down
@@ -0,0 +1,32 @@
package com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger;

import hudson.Extension;
import hudson.model.Cause;
import hudson.model.Job;
import hudson.model.Queue.LeftItem;
import hudson.model.queue.QueueListener;

import com.sonyericsson.hudson.plugins.gerrit.trigger.gerritnotifier.ToGerritRunListener;
import com.sonymobile.tools.gerrit.gerritevents.dto.events.GerritTriggeredEvent;

/**
* Listens to delete events in the Jenkins Queue to clean up the BuildMemory.
*/
@Extension
public class GerritQueueListener extends QueueListener {

@Override
public void onLeft(LeftItem item) {
if (item.isCancelled() && item.task instanceof Job) {
for (Cause cause : item.getCauses()) {
if (cause instanceof GerritCause && !((GerritCause)cause).isSilentMode()) {
GerritCause gerritCause = (GerritCause)cause;
GerritTriggeredEvent event = gerritCause.getEvent();
ToGerritRunListener runListener = ToGerritRunListener.getInstance();
runListener.setQueueCancelled((Job)item.task, event);
}
}
}
}

}
Expand Up @@ -24,38 +24,40 @@
*/
package com.sonyericsson.hudson.plugins.gerrit.trigger.gerritnotifier.model;

import com.sonymobile.tools.gerrit.gerritevents.dto.events.PatchsetCreated;
import com.sonyericsson.hudson.plugins.gerrit.trigger.gerritnotifier.model.BuildMemory.MemoryImprint;
import com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.GerritTrigger;
import com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.data.SkipVote;
import com.sonyericsson.hudson.plugins.gerrit.trigger.mock.Setup;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.same;
import static org.powermock.api.mockito.PowerMockito.doReturn;
import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.when;
import hudson.model.Result;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.Job;
import hudson.model.Result;
import hudson.triggers.Trigger;
import hudson.triggers.TriggerDescriptor;

import java.util.Collections;
import java.util.HashMap;

import jenkins.model.Jenkins;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import java.util.Collections;
import java.util.HashMap;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.same;
import static org.powermock.api.mockito.PowerMockito.doReturn;
import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.when;
import com.sonyericsson.hudson.plugins.gerrit.trigger.gerritnotifier.model.BuildMemory.MemoryImprint;
import com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.GerritTrigger;
import com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.data.SkipVote;
import com.sonyericsson.hudson.plugins.gerrit.trigger.mock.Setup;
import com.sonymobile.tools.gerrit.gerritevents.dto.events.PatchsetCreated;

//CS IGNORE MagicNumber FOR NEXT 700 LINES. REASON: test-data.

Expand Down Expand Up @@ -312,6 +314,20 @@ public void testCompleted() {
assertTrue(instance.isAllBuildsCompleted(event));
}


/**
* test.
*/
@Test
public void testCancelled() {
System.out.println("cancelled");
PatchsetCreated event = Setup.createPatchsetCreated();

BuildMemory instance = new BuildMemory();
instance.cancelled(event, project);
assertTrue(instance.isAllBuildsCompleted(event));
}

/**
* test.
*/
Expand Down

0 comments on commit e3ec526

Please sign in to comment.