Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
jenkins
提交
23758d49
J
jenkins
项目概览
xxadev
/
jenkins
与 Fork 源项目一致
从无法访问的项目Fork
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
jenkins
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
23758d49
编写于
5月 01, 2015
作者:
J
Jesse Glick
浏览文件
操作
浏览文件
下载
差异文件
[JENKINS-26964] Merging #1577.
上级
0a6e00cb
161a0092
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
288 addition
and
3 deletion
+288
-3
changelog.html
changelog.html
+3
-0
core/src/main/java/hudson/model/AbstractBuild.java
core/src/main/java/hudson/model/AbstractBuild.java
+18
-3
test/src/test/java/hudson/model/FreestyleJobPublisherTest.java
...src/test/java/hudson/model/FreestyleJobPublisherTest.java
+108
-0
test/src/test/java/hudson/model/utils/AbortExceptionPublisher.java
...test/java/hudson/model/utils/AbortExceptionPublisher.java
+35
-0
test/src/test/java/hudson/model/utils/IOExceptionPublisher.java
...rc/test/java/hudson/model/utils/IOExceptionPublisher.java
+35
-0
test/src/test/java/hudson/model/utils/ResultWriterPublisher.java
...c/test/java/hudson/model/utils/ResultWriterPublisher.java
+47
-0
test/src/test/java/hudson/model/utils/TrueFalsePublisher.java
.../src/test/java/hudson/model/utils/TrueFalsePublisher.java
+42
-0
未找到文件。
changelog.html
浏览文件 @
23758d49
...
@@ -55,6 +55,9 @@ Upcoming changes</a>
...
@@ -55,6 +55,9 @@ Upcoming changes</a>
<!-- Record your changes in the trunk here. -->
<!-- Record your changes in the trunk here. -->
<div
id=
"trunk"
style=
"display:none"
>
<!--=TRUNK-BEGIN=-->
<div
id=
"trunk"
style=
"display:none"
>
<!--=TRUNK-BEGIN=-->
<ul
class=
image
>
<ul
class=
image
>
<li
class=
bug
>
Handle AbortException publisher status in the same way as deprecated false boolean status
(
<a
href=
"https://issues.jenkins-ci.org/browse/JENKINS-26964"
>
issue 26964
</a>
)
<li
class=
bug
>
<li
class=
bug
>
Ensures GlobalSettingsProvider does not swallow fatal exceptions
Ensures GlobalSettingsProvider does not swallow fatal exceptions
(
<a
href=
"https://issues.jenkins-ci.org/browse/JENKINS-26604"
>
issue 26604
</a>
)
(
<a
href=
"https://issues.jenkins-ci.org/browse/JENKINS-26604"
>
issue 26604
</a>
)
...
...
core/src/main/java/hudson/model/AbstractBuild.java
浏览文件 @
23758d49
...
@@ -715,6 +715,8 @@ public abstract class AbstractBuild<P extends AbstractProject<P,R>,R extends Abs
...
@@ -715,6 +715,8 @@ public abstract class AbstractBuild<P extends AbstractProject<P,R>,R extends Abs
*
*
* @param phase
* @param phase
* true for the post build processing, and false for the final "run after finished" execution.
* true for the post build processing, and false for the final "run after finished" execution.
*
* @return false if any build step failed
*/
*/
protected
final
boolean
performAllBuildSteps
(
BuildListener
listener
,
Iterable
<?
extends
BuildStep
>
buildSteps
,
boolean
phase
)
throws
InterruptedException
,
IOException
{
protected
final
boolean
performAllBuildSteps
(
BuildListener
listener
,
Iterable
<?
extends
BuildStep
>
buildSteps
,
boolean
phase
)
throws
InterruptedException
,
IOException
{
boolean
r
=
true
;
boolean
r
=
true
;
...
@@ -724,20 +726,33 @@ public abstract class AbstractBuild<P extends AbstractProject<P,R>,R extends Abs
...
@@ -724,20 +726,33 @@ public abstract class AbstractBuild<P extends AbstractProject<P,R>,R extends Abs
if
(!
perform
(
bs
,
listener
))
{
if
(!
perform
(
bs
,
listener
))
{
LOGGER
.
log
(
Level
.
FINE
,
"{0} : {1} failed"
,
new
Object
[]
{
AbstractBuild
.
this
,
bs
});
LOGGER
.
log
(
Level
.
FINE
,
"{0} : {1} failed"
,
new
Object
[]
{
AbstractBuild
.
this
,
bs
});
r
=
false
;
r
=
false
;
if
(
phase
)
{
setResult
(
Result
.
FAILURE
);
}
}
}
}
catch
(
Exception
e
)
{
}
catch
(
Exception
e
)
{
reportError
(
bs
,
e
,
listener
,
phase
);
reportError
(
bs
,
e
,
listener
,
phase
);
r
=
false
;
}
catch
(
LinkageError
e
)
{
}
catch
(
LinkageError
e
)
{
reportError
(
bs
,
e
,
listener
,
phase
);
reportError
(
bs
,
e
,
listener
,
phase
);
r
=
false
;
}
}
}
}
return
r
;
return
r
;
}
}
private
void
reportError
(
BuildStep
bs
,
Throwable
e
,
BuildListener
listener
,
boolean
phase
)
{
private
void
reportError
(
BuildStep
bs
,
Throwable
e
,
BuildListener
listener
,
boolean
phase
)
{
String
msg
=
"Publisher "
+
bs
.
getClass
().
getName
()
+
" aborted due to exception"
;
final
String
publisher
=
((
Publisher
)
bs
).
getDescriptor
().
getDisplayName
();
e
.
printStackTrace
(
listener
.
error
(
msg
));
LOGGER
.
log
(
WARNING
,
msg
,
e
);
if
(
e
instanceof
AbortException
)
{
LOGGER
.
log
(
Level
.
FINE
,
"{0} : {1} failed"
,
new
Object
[]
{
AbstractBuild
.
this
,
publisher
});
listener
.
error
(
"Publisher '"
+
publisher
+
"' failed: "
+
e
.
getMessage
());
}
else
{
String
msg
=
"Publisher '"
+
publisher
+
"' aborted due to exception: "
;
e
.
printStackTrace
(
listener
.
error
(
msg
));
LOGGER
.
log
(
WARNING
,
msg
,
e
);
}
if
(
phase
)
{
if
(
phase
)
{
setResult
(
Result
.
FAILURE
);
setResult
(
Result
.
FAILURE
);
}
}
...
...
test/src/test/java/hudson/model/FreestyleJobPublisherTest.java
0 → 100644
浏览文件 @
23758d49
package
hudson.model
;
import
hudson.model.FreeStyleBuild
;
import
hudson.model.FreeStyleProject
;
import
hudson.model.Result
;
import
hudson.model.utils.AbortExceptionPublisher
;
import
hudson.model.utils.IOExceptionPublisher
;
import
hudson.model.utils.ResultWriterPublisher
;
import
hudson.model.utils.TrueFalsePublisher
;
import
hudson.tasks.ArtifactArchiver
;
import
org.apache.commons.io.FileUtils
;
import
org.junit.Rule
;
import
org.junit.Test
;
import
org.jvnet.hudson.test.Issue
;
import
org.jvnet.hudson.test.JenkinsRule
;
import
java.io.File
;
import
java.io.IOException
;
import
java.util.concurrent.ExecutionException
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertFalse
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
/**
* Freestyle publishers statuses tests
*
* @author Kanstantsin Shautsou
*/
public
class
FreestyleJobPublisherTest
{
@Rule
public
JenkinsRule
j
=
new
JenkinsRule
();
/**
* Execute all publishers even one of publishers return false.
*/
@Issue
(
"JENKINS-26964"
)
@Test
public
void
testFreestyleWithFalsePublisher
()
throws
Exception
{
FreeStyleProject
p
=
j
.
createFreeStyleProject
();
p
.
getPublishersList
().
add
(
new
TrueFalsePublisher
(
true
));
// noop
p
.
getPublishersList
().
add
(
new
TrueFalsePublisher
(
false
));
// FAIL build with false
p
.
getPublishersList
().
add
(
new
ResultWriterPublisher
(
"result.txt"
));
// catch result to file
final
ArtifactArchiver
artifactArchiver
=
new
ArtifactArchiver
(
"result.txt"
);
artifactArchiver
.
setOnlyIfSuccessful
(
false
);
p
.
getPublishersList
().
add
(
artifactArchiver
);
// transfer file to build dir
FreeStyleBuild
b
=
p
.
scheduleBuild2
(
0
).
get
();
assertEquals
(
"Build must fail, because we used FalsePublisher"
,
b
.
getResult
(),
Result
.
FAILURE
);
File
file
=
new
File
(
b
.
getArtifactsDir
(),
"result.txt"
);
assertTrue
(
"ArtifactArchiver is executed even prior publisher fails"
,
file
.
exists
());
assertTrue
(
"Publisher, after publisher with return false status, must see FAILURE status"
,
FileUtils
.
readFileToString
(
file
).
equals
(
Result
.
FAILURE
.
toString
()));
}
/**
* Execute all publishers even one of them throws AbortException.
*/
@Issue
(
"JENKINS-26964"
)
@Test
public
void
testFreestyleWithExceptionPublisher
()
throws
Exception
{
FreeStyleProject
p
=
j
.
createFreeStyleProject
();
p
.
getPublishersList
().
add
(
new
TrueFalsePublisher
(
true
));
// noop
p
.
getPublishersList
().
add
(
new
AbortExceptionPublisher
());
// FAIL build with AbortException
p
.
getPublishersList
().
add
(
new
ResultWriterPublisher
(
"result.txt"
));
// catch result to file
final
ArtifactArchiver
artifactArchiver
=
new
ArtifactArchiver
(
"result.txt"
);
artifactArchiver
.
setOnlyIfSuccessful
(
false
);
p
.
getPublishersList
().
add
(
artifactArchiver
);
// transfer file to build dir
FreeStyleBuild
b
=
p
.
scheduleBuild2
(
0
).
get
();
assertEquals
(
"Build must fail, because we used AbortExceptionPublisher"
,
b
.
getResult
(),
Result
.
FAILURE
);
j
.
assertLogNotContains
(
"\tat"
,
b
);
// log must not contain stacktrace
j
.
assertLogContains
(
"Threw AbortException from publisher!"
,
b
);
// log must contain exact error message
File
file
=
new
File
(
b
.
getArtifactsDir
(),
"result.txt"
);
assertTrue
(
"ArtifactArchiver is executed even prior publisher fails"
,
file
.
exists
());
assertTrue
(
"Third publisher must see FAILURE status"
,
FileUtils
.
readFileToString
(
file
).
equals
(
Result
.
FAILURE
.
toString
()));
}
/**
* Execute all publishers even one of them throws any Exceptions.
*/
@Issue
(
"JENKINS-26964"
)
@Test
public
void
testFreestyleWithIOExceptionPublisher
()
throws
Exception
{
FreeStyleProject
p
=
j
.
createFreeStyleProject
();
p
.
getPublishersList
().
add
(
new
TrueFalsePublisher
(
true
));
// noop
p
.
getPublishersList
().
add
(
new
IOExceptionPublisher
());
// fail with IOException
p
.
getPublishersList
().
add
(
new
ResultWriterPublisher
(
"result.txt"
));
//catch result to file
final
ArtifactArchiver
artifactArchiver
=
new
ArtifactArchiver
(
"result.txt"
);
artifactArchiver
.
setOnlyIfSuccessful
(
false
);
p
.
getPublishersList
().
add
(
artifactArchiver
);
// transfer file to build dir
FreeStyleBuild
b
=
p
.
scheduleBuild2
(
0
).
get
();
assertEquals
(
"Build must fail, because we used FalsePublisher"
,
b
.
getResult
(),
Result
.
FAILURE
);
j
.
assertLogContains
(
"\tat hudson.model.utils.IOExceptionPublisher"
,
b
);
// log must contain stacktrace
j
.
assertLogContains
(
"Threw IOException from publisher!"
,
b
);
// log must contain exact error message
File
file
=
new
File
(
b
.
getArtifactsDir
(),
"result.txt"
);
assertTrue
(
"ArtifactArchiver is executed even prior publisher fails"
,
file
.
exists
());
assertTrue
(
"Third publisher must see FAILURE status"
,
FileUtils
.
readFileToString
(
file
).
equals
(
Result
.
FAILURE
.
toString
()));
}
}
test/src/test/java/hudson/model/utils/AbortExceptionPublisher.java
0 → 100644
浏览文件 @
23758d49
package
hudson.model.utils
;
import
hudson.AbortException
;
import
hudson.Extension
;
import
hudson.Launcher
;
import
hudson.model.AbstractBuild
;
import
hudson.model.AbstractProject
;
import
hudson.model.BuildListener
;
import
hudson.tasks.BuildStepDescriptor
;
import
hudson.tasks.BuildStepMonitor
;
import
hudson.tasks.Publisher
;
import
hudson.tasks.Recorder
;
import
java.io.IOException
;
/**
* Publisher that throws AbortException
*/
public
class
AbortExceptionPublisher
extends
Recorder
{
@Override
public
boolean
perform
(
AbstractBuild
<?,
?>
build
,
Launcher
launcher
,
BuildListener
listener
)
throws
InterruptedException
,
IOException
{
throw
new
AbortException
(
"Threw AbortException from publisher!"
);
}
@Override
public
BuildStepMonitor
getRequiredMonitorService
()
{
return
BuildStepMonitor
.
NONE
;
}
@Extension
public
static
class
DescriptorImpl
extends
BuildStepDescriptor
<
Publisher
>
{
@Override
public
String
getDisplayName
()
{
return
"ThrowAbortExceptionRecorder"
;
}
@Override
public
boolean
isApplicable
(
Class
<?
extends
AbstractProject
>
jobType
)
{
return
true
;
}
}
}
test/src/test/java/hudson/model/utils/IOExceptionPublisher.java
0 → 100644
浏览文件 @
23758d49
package
hudson.model.utils
;
import
hudson.Extension
;
import
hudson.Launcher
;
import
hudson.model.AbstractBuild
;
import
hudson.model.AbstractProject
;
import
hudson.model.BuildListener
;
import
hudson.tasks.BuildStepDescriptor
;
import
hudson.tasks.BuildStepMonitor
;
import
hudson.tasks.Publisher
;
import
hudson.tasks.Recorder
;
import
java.io.IOException
;
/**
* Publisher that throw IOException
* @author Kanstantsin Shautsou
*/
public
class
IOExceptionPublisher
extends
Recorder
{
@Override
public
boolean
perform
(
AbstractBuild
<?,
?>
build
,
Launcher
launcher
,
BuildListener
listener
)
throws
InterruptedException
,
IOException
{
throw
new
IOException
(
"Threw IOException from publisher!"
);
}
@Override
public
BuildStepMonitor
getRequiredMonitorService
()
{
return
BuildStepMonitor
.
NONE
;
}
@Extension
public
static
class
DescriptorImpl
extends
BuildStepDescriptor
<
Publisher
>
{
@Override
public
String
getDisplayName
()
{
return
"Throw IOException Publisher"
;
}
@Override
public
boolean
isApplicable
(
Class
<?
extends
AbstractProject
>
jobType
)
{
return
true
;
}
}
}
test/src/test/java/hudson/model/utils/ResultWriterPublisher.java
0 → 100644
浏览文件 @
23758d49
package
hudson.model.utils
;
import
hudson.Extension
;
import
hudson.FilePath
;
import
hudson.Launcher
;
import
hudson.model.AbstractBuild
;
import
hudson.model.AbstractProject
;
import
hudson.model.BuildListener
;
import
hudson.tasks.BuildStepDescriptor
;
import
hudson.tasks.BuildStepMonitor
;
import
hudson.tasks.Publisher
;
import
hudson.tasks.Recorder
;
import
java.io.IOException
;
import
java.nio.charset.Charset
;
/**
* Wrote build status to file
* @author Kanstantsin Shautsou
*/
public
class
ResultWriterPublisher
extends
Recorder
{
private
final
String
fileName
;
public
ResultWriterPublisher
(
String
fileName
)
{
this
.
fileName
=
fileName
;
}
@Override
public
BuildStepMonitor
getRequiredMonitorService
()
{
return
BuildStepMonitor
.
NONE
;
}
@Override
public
boolean
perform
(
AbstractBuild
<?,
?>
build
,
Launcher
launcher
,
BuildListener
listener
)
throws
InterruptedException
,
IOException
{
FilePath
file
=
build
.
getWorkspace
().
child
(
fileName
);
file
.
write
(
build
.
getResult
().
toString
(),
Charset
.
defaultCharset
().
name
());
return
true
;
}
@Extension
public
static
class
DescriptorImpl
extends
BuildStepDescriptor
<
Publisher
>
{
@Override
public
String
getDisplayName
()
{
return
"wrote result to file"
;
}
@Override
public
boolean
isApplicable
(
Class
<?
extends
AbstractProject
>
jobType
)
{
return
true
;
}
}
}
test/src/test/java/hudson/model/utils/TrueFalsePublisher.java
0 → 100644
浏览文件 @
23758d49
package
hudson.model.utils
;
import
hudson.Extension
;
import
hudson.Launcher
;
import
hudson.model.AbstractBuild
;
import
hudson.model.AbstractProject
;
import
hudson.model.BuildListener
;
import
hudson.tasks.BuildStepDescriptor
;
import
hudson.tasks.BuildStepMonitor
;
import
hudson.tasks.Publisher
;
import
hudson.tasks.Recorder
;
import
org.kohsuke.stapler.DataBoundConstructor
;
import
java.io.IOException
;
/**
* @author Kanstantsin Shautsou
*/
public
class
TrueFalsePublisher
extends
Recorder
{
private
final
boolean
b
;
@DataBoundConstructor
public
TrueFalsePublisher
(
boolean
b
)
{
this
.
b
=
b
;
}
@Override
public
boolean
perform
(
AbstractBuild
<?,
?>
build
,
Launcher
launcher
,
BuildListener
listener
)
throws
InterruptedException
,
IOException
{
return
b
;
}
@Override
public
BuildStepMonitor
getRequiredMonitorService
()
{
return
BuildStepMonitor
.
NONE
;
}
@Extension
public
static
class
DescriptorImpl
extends
BuildStepDescriptor
<
Publisher
>
{
@Override
public
String
getDisplayName
()
{
return
"return true or false"
;
}
@Override
public
boolean
isApplicable
(
Class
<?
extends
AbstractProject
>
jobType
)
{
return
true
;
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录