下面列出了怎么用hudson.model.Actionable的API类实例代码及写法,或者点击链接到github查看源代码。
private void assertThatCheckstyleAndEclipseChartExist(final Actionable actionable, final boolean shouldChartBeVisible) {
List<JobAction> jobActions = actionable.getActions(JobAction.class);
assertThat(jobActions).hasSize(2);
JobAction checkstyle;
JobAction eclipse;
if ("checkstyle".equals(jobActions.get(0).getUrlName())) {
checkstyle = jobActions.get(0);
eclipse = jobActions.get(1);
}
else {
checkstyle = jobActions.get(1);
eclipse = jobActions.get(0);
}
assertThat(eclipse.getTrendName()).isEqualTo(ECLIPSE);
assertThat(eclipse.getIconFileName()).contains(ANALYSIS_ICON);
assertThat(checkstyle.getTrendName()).isEqualTo(CHECKSTYLE);
assertThat(checkstyle.getIconFileName()).contains(CHECKSTYLE_ICON);
if (shouldChartBeVisible) {
assertThatTrendChartIsVisible(eclipse);
assertThatTrendChartIsVisible(checkstyle);
}
else {
assertThatTrendChartIsHidden(eclipse);
assertThatTrendChartIsHidden(checkstyle);
}
}
private void assertThatAggregationChartExists(final Actionable actionable, final boolean shouldChartBeVisible) {
AggregatedTrendAction aggregatedTrendAction = actionable.getAction(AggregatedTrendAction.class);
assertThat(aggregatedTrendAction.getUrlName()).isEqualTo("warnings-aggregation");
if (shouldChartBeVisible) {
assertThatTrendChartIsVisible(aggregatedTrendAction);
}
else {
assertThatTrendChartIsHidden(aggregatedTrendAction);
}
}
private void assertThatAggregationChartDoesNotExists(final Actionable actionable) {
List<AggregatedTrendAction> aggregatedTrendActions = actionable.getActions(AggregatedTrendAction.class);
assertThat(aggregatedTrendActions).hasSize(0);
}
/** {@inheritDoc} */
@NonNull
@Override
protected List<Action> retrieveActions(
@NonNull SCMHead head, @CheckForNull SCMHeadEvent event, @NonNull TaskListener listener)
throws IOException, InterruptedException {
final List<Action> actions =
doRetrieve(
head,
(GitClient client,
GerritSCMSourceContext context,
String remoteName,
Changes.QueryRequest changeQuery) -> {
SCMSourceOwner owner = getOwner();
if (owner instanceof Actionable && head instanceof ChangeSCMHead) {
final Actionable actionableOwner = (Actionable) owner;
final ChangeSCMHead change = (ChangeSCMHead) head;
String gerritBaseUrl = getGerritBaseUrl();
return actionableOwner
.getActions(GitRemoteHeadRefAction.class)
.stream()
.filter(action -> action.getRemote().equals(getRemote()))
.map(
action ->
new ObjectMetadataAction(
change.getName(),
change.getId(),
String.format("%s%d", gerritBaseUrl, change.getChangeNumber())))
.collect(Collectors.toList());
} else {
return Collections.emptyList();
}
},
new GerritSCMSourceContext(null, SCMHeadObserver.none()).withTraits(getTraits()),
listener,
false);
final ImmutableList.Builder<Action> resultBuilder = new ImmutableList.Builder<>();
resultBuilder.addAll(super.retrieveActions(head, event, listener));
resultBuilder.addAll(actions);
return resultBuilder.build();
}
private boolean filter(Item item) {
return !(item instanceof Actionable) || !defaultBranchOnly || ((Actionable) item).getAction(PrimaryInstanceMetadataAction.class) != null;
}
/**
* {@link ComputerLauncher#afterDisconnect(SlaveComputer, TaskListener)}
* <p>
* EC2 Fleet plugin overrides this method to detect jobs which were failed because of
* EC2 instance was terminated/stopped. It could be manual stop or because of Spot marked.
* In all cases as soon as job aborted because of broken connection and slave is offline
* it will try to resubmit aborted job back to the queue, so user doesn't need to do that manually
* and another slave could take it.
* <p>
* Implementation details
* <p>
* There is no official recommendation about way how to resubmit job according to
* https://issues.jenkins-ci.org/browse/JENKINS-49707 moreover some of Jenkins code says it impossible.
* <p>
* method checks {@link SlaveComputer#getOfflineCause()} for disconnect because of EC2 instance termination
* it returns
* <code>
* result = {[email protected]} "Connection was broken: java.io.IOException:
* Unexpected termination of the channel\n\tat hudson.remoting.SynchronousCommandTransport$ReaderThread...
* cause = {[email protected]} "java.io.IOException: Unexpected termination of the channel"
* timestamp = 1561067177837
* </code>
*
* @param computer computer
* @param listener listener
*/
@Override
public void afterDisconnect(final SlaveComputer computer, final TaskListener listener) {
// according to jenkins docs could be null in edge cases, check ComputerLauncher.afterDisconnect
if (computer == null) return;
// in some multi-thread edge cases cloud could be null for some time, just be ok with that
final EC2FleetCloud cloud = ((EC2FleetNodeComputer) computer).getCloud();
if (cloud == null) {
LOGGER.warning("Edge case cloud is null for computer " + computer.getDisplayName()
+ " should be autofixed in a few minutes, if no please create issue for plugin");
return;
}
final boolean unexpectedDisconnect = computer.isOffline() && computer.getOfflineCause() instanceof OfflineCause.ChannelTermination;
if (!cloud.isDisableTaskResubmit() && unexpectedDisconnect) {
final List<Executor> executors = computer.getExecutors();
LOGGER.log(LOG_LEVEL, "Unexpected " + computer.getDisplayName()
+ " termination, resubmit");
for (Executor executor : executors) {
if (executor.getCurrentExecutable() != null) {
executor.interrupt(Result.ABORTED, new EC2TerminationCause(computer.getDisplayName()));
final Queue.Executable executable = executor.getCurrentExecutable();
// if executor is not idle
if (executable != null) {
final SubTask subTask = executable.getParent();
final Queue.Task task = subTask.getOwnerTask();
List<Action> actions = new ArrayList<>();
if (executable instanceof Actionable) {
actions = ((Actionable) executable).getActions();
}
Queue.getInstance().schedule2(task, RESCHEDULE_QUIET_PERIOD_SEC, actions);
LOGGER.log(LOG_LEVEL, "Unexpected " + computer.getDisplayName()
+ " termination, resubmit " + task + " with actions " + actions);
}
}
}
LOGGER.log(LOG_LEVEL, "Unexpected " + computer.getDisplayName()
+ " termination, resubmit finished");
} else {
LOGGER.log(LOG_LEVEL, "Unexpected " + computer.getDisplayName()
+ " termination but resubmit disabled, no actions, disableTaskResubmit: "
+ cloud.isDisableTaskResubmit() + ", offline: " + computer.isOffline()
+ ", offlineCause: " + (computer.getOfflineCause() != null ? computer.getOfflineCause().getClass() : "null"));
}
// call parent
super.afterDisconnect(computer, listener);
}
@Before
public void before() {
executable1 = mock(Actionable.class, withSettings().extraInterfaces(Queue.Executable.class));
when(computer.getDisplayName()).thenReturn("i-12");
PowerMockito.mockStatic(Jenkins.class);
when(Jenkins.getInstance()).thenReturn(jenkins);
when(Queue.getInstance()).thenReturn(queue);
when(slave.getNumExecutors()).thenReturn(1);
when(fleetNode.getDisplayName()).thenReturn("fleet node name");
when(((Queue.Executable) executable1).getParent()).thenReturn(subTask1);
when(executable2.getParent()).thenReturn(subTask2);
when(subTask1.getOwnerTask()).thenReturn(task1);
when(subTask2.getOwnerTask()).thenReturn(task2);
when(executor1.getCurrentExecutable()).thenReturn((Queue.Executable) executable1);
when(executor2.getCurrentExecutable()).thenReturn(executable2);
when(computer.getExecutors()).thenReturn(Arrays.asList(executor1, executor2));
when(computer.isOffline()).thenReturn(true);
when(computer.getCloud()).thenReturn(cloud);
}