Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
LinuxSuRen
jenkins
提交
c24a2b1e
J
jenkins
项目概览
LinuxSuRen
/
jenkins
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
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,发现更多精彩内容 >>
提交
c24a2b1e
编写于
10月 19, 2011
作者:
N
Nicolas De loof
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #294 from stephenc/master
Nice improvement to Jenkins testability
上级
0f2f7be9
1d5cdddf
变更
11
展开全部
隐藏空白更改
内联
并排
Showing
11 changed file
with
2543 addition
and
6 deletion
+2543
-6
cli/pom.xml
cli/pom.xml
+1
-1
core/pom.xml
core/pom.xml
+1
-1
maven-plugin/pom.xml
maven-plugin/pom.xml
+1
-1
plugins/pom.xml
plugins/pom.xml
+1
-1
pom.xml
pom.xml
+13
-1
test/pom.xml
test/pom.xml
+5
-1
test/src/main/java/org/jvnet/hudson/test/JenkinsComputerConnectorTester.java
...org/jvnet/hudson/test/JenkinsComputerConnectorTester.java
+66
-0
test/src/main/java/org/jvnet/hudson/test/JenkinsMatchers.java
.../src/main/java/org/jvnet/hudson/test/JenkinsMatchers.java
+399
-0
test/src/main/java/org/jvnet/hudson/test/JenkinsRecipe.java
test/src/main/java/org/jvnet/hudson/test/JenkinsRecipe.java
+55
-0
test/src/main/java/org/jvnet/hudson/test/JenkinsRule.java
test/src/main/java/org/jvnet/hudson/test/JenkinsRule.java
+1982
-0
test/src/main/java/org/jvnet/hudson/test/WithoutJenkins.java
test/src/main/java/org/jvnet/hudson/test/WithoutJenkins.java
+19
-0
未找到文件。
cli/pom.xml
浏览文件 @
c24a2b1e
...
...
@@ -25,7 +25,7 @@
</dependency>
<dependency>
<groupId>
junit
</groupId>
<artifactId>
junit
</artifactId>
<artifactId>
junit
-dep
</artifactId>
<scope>
test
</scope>
</dependency>
<dependency>
...
...
core/pom.xml
浏览文件 @
c24a2b1e
...
...
@@ -422,7 +422,7 @@ THE SOFTWARE.
</dependency>
<dependency>
<groupId>
junit
</groupId>
<artifactId>
junit
</artifactId>
<artifactId>
junit
-dep
</artifactId>
<scope>
test
</scope>
</dependency>
<dependency>
<!-- needed by Jelly -->
...
...
maven-plugin/pom.xml
浏览文件 @
c24a2b1e
...
...
@@ -353,7 +353,7 @@ THE SOFTWARE.
<dependency>
<groupId>
junit
</groupId>
<artifactId>
junit
</artifactId>
<artifactId>
junit
-dep
</artifactId>
<scope>
test
</scope>
</dependency>
<dependency>
...
...
plugins/pom.xml
浏览文件 @
c24a2b1e
...
...
@@ -66,7 +66,7 @@
</dependency>
<dependency>
<groupId>
junit
</groupId>
<artifactId>
junit
</artifactId>
<artifactId>
junit
-dep
</artifactId>
<version>
4.10
</version>
<scope>
test
</scope>
</dependency>
...
...
pom.xml
浏览文件 @
c24a2b1e
...
...
@@ -130,10 +130,22 @@ THE SOFTWARE.
<dependency>
<groupId>
junit
</groupId>
<artifactId>
junit
</artifactId>
<artifactId>
junit
-dep
</artifactId>
<version>
4.10
</version>
</dependency>
<dependency>
<groupId>
org.hamcrest
</groupId>
<artifactId>
hamcrest-core
</artifactId>
<version>
1.2.1
</version>
</dependency>
<dependency>
<groupId>
org.hamcrest
</groupId>
<artifactId>
hamcrest-library
</artifactId>
<version>
1.2.1
</version>
</dependency>
<dependency>
<groupId>
org.mockito
</groupId>
<artifactId>
mockito-core
</artifactId>
...
...
test/pom.xml
浏览文件 @
c24a2b1e
...
...
@@ -89,7 +89,11 @@ THE SOFTWARE.
</dependency>
<dependency>
<groupId>
junit
</groupId>
<artifactId>
junit
</artifactId>
<artifactId>
junit-dep
</artifactId>
</dependency>
<dependency>
<groupId>
org.hamcrest
</groupId>
<artifactId>
hamcrest-library
</artifactId>
</dependency>
<dependency>
<groupId>
org.jenkins-ci
</groupId>
...
...
test/src/main/java/org/jvnet/hudson/test/JenkinsComputerConnectorTester.java
0 → 100644
浏览文件 @
c24a2b1e
/*
* The MIT License
*
* Copyright (c) 2010, InfraDNA, 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
org.jvnet.hudson.test
;
import
hudson.Extension
;
import
hudson.model.AbstractDescribableImpl
;
import
hudson.model.Descriptor
;
import
hudson.slaves.ComputerConnector
;
import
hudson.slaves.ComputerConnectorDescriptor
;
import
org.kohsuke.stapler.StaplerRequest
;
import
javax.servlet.ServletException
;
import
java.io.IOException
;
import
java.util.List
;
/**
* Test bed to verify the configuration roundtripness of the {@link ComputerConnector}.
*
* @author Kohsuke Kawaguchi
* @see HudsonTestCase#computerConnectorTester
*/
public
class
JenkinsComputerConnectorTester
extends
AbstractDescribableImpl
<
JenkinsComputerConnectorTester
>
{
public
final
JenkinsRule
jenkinsRule
;
public
ComputerConnector
connector
;
public
JenkinsComputerConnectorTester
(
JenkinsRule
testCase
)
{
this
.
jenkinsRule
=
testCase
;
}
public
void
doConfigSubmit
(
StaplerRequest
req
)
throws
IOException
,
ServletException
{
connector
=
req
.
bindJSON
(
ComputerConnector
.
class
,
req
.
getSubmittedForm
().
getJSONObject
(
"connector"
));
}
public
List
getConnectorDescriptors
()
{
return
ComputerConnectorDescriptor
.
all
();
}
@Extension
public
static
class
DescriptorImpl
extends
Descriptor
<
JenkinsComputerConnectorTester
>
{
@Override
public
String
getDisplayName
()
{
return
""
;
}
}
}
test/src/main/java/org/jvnet/hudson/test/JenkinsMatchers.java
0 → 100644
浏览文件 @
c24a2b1e
package
org.jvnet.hudson.test
;
import
hudson.util.FormValidation
;
import
org.hamcrest.BaseMatcher
;
import
org.hamcrest.CoreMatchers
;
import
org.hamcrest.Description
;
import
org.hamcrest.Matcher
;
import
java.lang.reflect.Constructor
;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.Modifier
;
import
static
org
.
hamcrest
.
Matchers
.
allOf
;
/**
* Some handy matchers.
*
* @author Stephen Connolly
*/
public
class
JenkinsMatchers
{
public
static
Matcher
<
Class
>
privateConstructorThrows
(
Class
<?
extends
Throwable
>
cause
)
{
return
new
PrivateConstructorThrows
(
cause
);
}
public
static
Matcher
<
FormValidation
>
causedBy
(
Class
<?
extends
Throwable
>
cause
)
{
return
new
FormValidationCauseMatcher
(
cause
);
}
public
static
Matcher
<
FormValidation
>
hasKind
(
FormValidation
.
Kind
kind
)
{
return
new
FormValidationKindMatcher
(
kind
);
}
private
static
class
PrivateConstructorThrows
extends
BaseMatcher
<
Class
>
{
private
final
Class
<?
extends
Throwable
>
cause
;
public
PrivateConstructorThrows
(
Class
<?
extends
Throwable
>
cause
)
{
this
.
cause
=
cause
;
}
public
boolean
matches
(
Object
o
)
{
Class
<?>
clazz
=
(
Class
<?>)
o
;
try
{
Constructor
<?>
c
=
clazz
.
getDeclaredConstructor
();
if
(!
Modifier
.
isPrivate
(
c
.
getModifiers
()))
{
return
false
;
}
boolean
accessible
=
c
.
isAccessible
();
try
{
c
.
setAccessible
(
true
);
c
.
newInstance
();
}
catch
(
InvocationTargetException
e
)
{
Throwable
t
=
e
;
while
(
t
!=
null
)
{
if
(
cause
.
isInstance
(
t
))
{
return
true
;
}
t
=
t
.
getCause
();
}
}
catch
(
InstantiationException
e
)
{
// ignore
}
catch
(
IllegalAccessException
e
)
{
// ignore
}
finally
{
c
.
setAccessible
(
accessible
);
}
}
catch
(
NoSuchMethodException
e
)
{
// ignore
}
return
false
;
}
public
void
describeTo
(
Description
description
)
{
description
.
appendText
(
"with a private constructor that throws "
);
description
.
appendValue
(
cause
);
}
}
private
static
class
FormValidationCauseMatcher
extends
BaseMatcher
<
FormValidation
>
{
private
final
Class
<?
extends
Throwable
>
cause
;
public
FormValidationCauseMatcher
(
Class
<?
extends
Throwable
>
cause
)
{
cause
.
getClass
();
this
.
cause
=
cause
;
}
public
boolean
matches
(
Object
o
)
{
FormValidation
v
=
(
FormValidation
)
o
;
return
v
.
getMessage
().
contains
(
cause
.
getName
());
}
public
void
describeTo
(
Description
description
)
{
description
.
appendText
(
"caused by "
);
description
.
appendValue
(
cause
);
}
}
private
static
class
FormValidationKindMatcher
extends
BaseMatcher
<
FormValidation
>
{
private
final
FormValidation
.
Kind
kind
;
public
FormValidationKindMatcher
(
FormValidation
.
Kind
kind
)
{
kind
.
getClass
();
this
.
kind
=
kind
;
}
public
boolean
matches
(
Object
o
)
{
FormValidation
v
=
(
FormValidation
)
o
;
return
v
.
kind
==
kind
;
}
public
void
describeTo
(
Description
description
)
{
description
.
appendText
(
"of kind "
);
description
.
appendValue
(
kind
);
}
}
/**
* A matcher which checks that the class is a Utility class (i.e. is final and has only private constructors).
*
* @return A matcher which checks that the class is a Utility class (i.e. is final and has only private
* constructors).
*/
public
static
Matcher
<
Class
<?>>
isUtilityClass
()
{
return
CoreMatchers
.
allOf
(
isFinalClass
(),
isClassWithOnlyPrivateConstructors
());
}
/**
* A matcher which checks that the class has only private constructors.
*
* @return A matcher which checks that the class has only private constructors.
*/
public
static
Matcher
<
Class
<?>>
isClassWithOnlyPrivateConstructors
()
{
return
new
IsClassWithOnlyPrivateConstructors
();
}
/**
* A matcher which checks that the class is final.
*
* @return A matcher which checks that the class is final.
*/
public
static
Matcher
<
Class
<?>>
isFinalClass
()
{
return
new
IsFinalClass
();
}
/**
* A matcher which checks that the class has the default constructor.
*
* @return A matcher which checks that the class has the default constructor.
*/
public
static
Matcher
<
Class
<?>>
hasDefaultConstructor
()
{
return
new
HasDefaultConstructor
();
}
/**
* A matcher that verifies that the a root cause of an exception is of the specified type.
*
* @param cause the type of exception that caused this.
* @return A matcher that verifies that the a root cause of an exception is of the specified type.
*/
public
static
Matcher
<
Throwable
>
hasCause
(
Class
<?
extends
Throwable
>
cause
)
{
return
new
HasCause
(
cause
);
}
public
static
Matcher
<
Object
>
hasImplementedEquals
()
{
return
new
HasImplementedEquals
();
}
public
static
Matcher
<
Object
>
hasReflexiveEquals
()
{
return
new
HasReflexiveEquals
();
}
public
static
Matcher
<
Object
>
hasNonEqualityWithNulls
()
{
return
new
HasNonNullEquals
();
}
public
static
Matcher
<
Object
>
hasSymmetricEquals
(
Object
other
)
{
return
new
HasSymmetricEquals
(
other
);
}
public
static
Matcher
<
Object
>
hasConsistentEquals
(
Object
other
)
{
return
new
HasConsistentEquals
(
other
);
}
public
static
Matcher
<
Object
>
hasTransitiveEquals
(
Object
a
,
Object
b
)
{
return
new
HasTransitiveEquals
(
a
,
b
);
}
public
static
Matcher
<
Object
>
hasImplementedHashCode
()
{
return
new
HasImplementedHashCode
();
}
public
static
Matcher
<
Object
>
hasHashCodeContract
(
Object
other
)
{
return
new
HasHashCodeContract
(
other
);
}
private
static
class
HasDefaultConstructor
extends
BaseMatcher
<
Class
<?>>
{
public
boolean
matches
(
Object
item
)
{
Class
<?>
clazz
=
(
Class
<?>)
item
;
try
{
Constructor
<?>
constructor
=
clazz
.
getConstructor
();
return
Modifier
.
isPublic
(
constructor
.
getModifiers
());
}
catch
(
NoSuchMethodException
e
)
{
return
false
;
}
}
public
void
describeTo
(
Description
description
)
{
description
.
appendText
(
"a class with the default constructor"
);
}
}
private
static
class
HasImplementedEquals
extends
BaseMatcher
<
Object
>
{
public
boolean
matches
(
Object
item
)
{
if
(
item
==
null
)
{
return
false
;
}
Class
<?>
clazz
=
item
instanceof
Class
?
(
Class
<?>)
item
:
item
.
getClass
();
try
{
return
!
clazz
.
getMethod
(
"equals"
,
Object
.
class
).
equals
(
Object
.
class
.
getMethod
(
"equals"
,
Object
.
class
));
}
catch
(
NoSuchMethodException
e
)
{
return
false
;
}
}
public
void
describeTo
(
Description
description
)
{
description
.
appendText
(
"has overridden the default equals(Object) method"
);
}
}
private
static
class
HasImplementedHashCode
extends
BaseMatcher
<
Object
>
{
public
boolean
matches
(
Object
item
)
{
if
(
item
==
null
)
{
return
false
;
}
Class
<?>
clazz
=
item
instanceof
Class
?
(
Class
<?>)
item
:
item
.
getClass
();
try
{
return
!
clazz
.
getMethod
(
"hashCode"
).
equals
(
Object
.
class
.
getMethod
(
"hashCode"
));
}
catch
(
NoSuchMethodException
e
)
{
return
false
;
}
}
public
void
describeTo
(
Description
description
)
{
description
.
appendText
(
"has overridden the default hashCode() method"
);
}
}
private
static
class
IsClassWithOnlyPrivateConstructors
extends
BaseMatcher
<
Class
<?>>
{
public
boolean
matches
(
Object
item
)
{
Class
<?>
clazz
=
(
Class
<?>)
item
;
for
(
Constructor
<?>
c
:
clazz
.
getConstructors
())
{
if
(!
Modifier
.
isPrivate
(
c
.
getModifiers
()))
{
return
false
;
}
}
return
true
;
}
public
void
describeTo
(
Description
description
)
{
description
.
appendText
(
"a class with only private constructors"
);
}
}
private
static
class
IsFinalClass
extends
BaseMatcher
<
Class
<?>>
{
public
boolean
matches
(
Object
item
)
{
Class
<?>
clazz
=
(
Class
<?>)
item
;
return
Modifier
.
isFinal
(
clazz
.
getModifiers
());
}
public
void
describeTo
(
Description
description
)
{
description
.
appendText
(
"a final class"
);
}
}
private
static
class
HasCause
extends
BaseMatcher
<
Throwable
>
{
private
final
Class
<?
extends
Throwable
>
cause
;
public
HasCause
(
Class
<?
extends
Throwable
>
cause
)
{
this
.
cause
=
cause
;
}
public
boolean
matches
(
Object
item
)
{
Throwable
throwable
=
(
Throwable
)
item
;
while
(
throwable
!=
null
&&
!
cause
.
isInstance
(
throwable
))
{
throwable
=
throwable
.
getCause
();
}
return
cause
.
isInstance
(
throwable
);
}
public
void
describeTo
(
Description
description
)
{
description
.
appendText
(
"was caused by a "
).
appendValue
(
cause
).
appendText
(
" being thrown"
);
}
}
private
static
class
HasNonNullEquals
extends
BaseMatcher
<
Object
>
{
public
boolean
matches
(
Object
o
)
{
return
o
!=
null
&&
!
o
.
equals
(
null
);
}
public
void
describeTo
(
Description
description
)
{
description
.
appendText
(
"has an equals(Object) method that returns false for null"
);
}
}
private
static
class
HasReflexiveEquals
extends
BaseMatcher
<
Object
>
{
public
boolean
matches
(
Object
o
)
{
return
o
!=
null
&&
o
.
equals
(
o
);
}
public
void
describeTo
(
Description
description
)
{
description
.
appendText
(
"has a reflexive equals(Object) method"
);
}
}
private
static
class
HasSymmetricEquals
extends
BaseMatcher
<
Object
>
{
private
final
Object
other
;
public
HasSymmetricEquals
(
Object
other
)
{
this
.
other
=
other
;
}
public
boolean
matches
(
Object
o
)
{
return
o
==
null
?
other
==
null
:
(
o
.
equals
(
other
)
?
other
.
equals
(
o
)
:
!
other
.
equals
(
o
));
}
public
void
describeTo
(
Description
description
)
{
description
.
appendText
(
"has a symmetric equals(Object) method with "
);
description
.
appendValue
(
other
);
}
}
private
static
class
HasConsistentEquals
extends
BaseMatcher
<
Object
>
{
private
final
Object
other
;
public
HasConsistentEquals
(
Object
other
)
{
this
.
other
=
other
;
}
public
boolean
matches
(
Object
o
)
{
return
o
==
null
?
other
==
null
:
(
o
.
equals
(
other
)
?
o
.
equals
(
other
)
:
!
o
.
equals
(
other
));
}
public
void
describeTo
(
Description
description
)
{
description
.
appendText
(
"has a symmetric equals(Object) method with "
);
description
.
appendValue
(
other
);
}
}
private
static
class
HasTransitiveEquals
extends
BaseMatcher
<
Object
>
{
private
final
Object
a
;
private
final
Object
b
;
public
HasTransitiveEquals
(
Object
a
,
Object
b
)
{
this
.
a
=
a
;
this
.
b
=
b
;
}
public
boolean
matches
(
Object
o
)
{
return
o
!=
null
&&
(!(
o
.
equals
(
a
)
&&
a
.
equals
(
b
))
||
o
.
equals
(
b
));
}
public
void
describeTo
(
Description
description
)
{
description
.
appendText
(
"has a transitive equals(Object) method with "
);
description
.
appendValue
(
a
);
description
.
appendText
(
" and "
);
description
.
appendValue
(
b
);
}
}
private
static
class
HasHashCodeContract
extends
BaseMatcher
<
Object
>
{
private
final
Object
other
;
public
HasHashCodeContract
(
Object
other
)
{
this
.
other
=
other
;
}
public
boolean
matches
(
Object
o
)
{
return
o
==
null
?
other
==
null
:
(!
o
.
equals
(
other
)
||
o
.
hashCode
()
==
other
.
hashCode
());
}
public
void
describeTo
(
Description
description
)
{
description
.
appendText
(
"follows the hashCode contract when compared to "
);
description
.
appendValue
(
other
);
}
}
}
test/src/main/java/org/jvnet/hudson/test/JenkinsRecipe.java
0 → 100644
浏览文件 @
c24a2b1e
package
org.jvnet.hudson.test
;
import
java.lang.annotation.Documented
;
import
static
java
.
lang
.
annotation
.
ElementType
.
ANNOTATION_TYPE
;
import
java.lang.annotation.Retention
;
import
static
java
.
lang
.
annotation
.
RetentionPolicy
.
RUNTIME
;
import
java.lang.annotation.Target
;
import
java.lang.annotation.Annotation
;
import
java.io.File
;
import
junit.framework.TestCase
;
/**
* Meta-annotation for recipe annotations, which controls
* the test environment set up.
*
* @author Kohsuke Kawaguchi
*/
@Retention
(
RUNTIME
)
@Documented
@Target
(
ANNOTATION_TYPE
)
public
@interface
JenkinsRecipe
{
/**
* Specifies the class that sets up the test environment.
*
* <p>
* When a recipe annotation is placed on a test method,
*/
Class
<?
extends
Runner
>
value
();
/**
* The code that implements the recipe semantics.
*
* @param <T>
* The recipe annotation associated with this runner.
*/
public
abstract
class
Runner
<
T
extends
Annotation
>
{
/**
* Called during {@link TestCase#setUp()} to prepare the test environment.
*/
public
void
setup
(
JenkinsRule
jenkinsRule
,
T
recipe
)
throws
Exception
{}
/**
* Called right before {@link jenkins.model.Jenkins#Jenkins(java.io.File, javax.servlet.ServletContext)} is invoked
* to decorate the hudson home directory.
*/
public
void
decorateHome
(
JenkinsRule
jenkinsRule
,
File
home
)
throws
Exception
{}
/**
* Called during {@link TestCase#tearDown()} to shut down the test environment.
*/
public
void
tearDown
(
JenkinsRule
jenkinsRule
,
T
recipe
)
throws
Exception
{}
}
}
test/src/main/java/org/jvnet/hudson/test/JenkinsRule.java
0 → 100644
浏览文件 @
c24a2b1e
此差异已折叠。
点击以展开。
test/src/main/java/org/jvnet/hudson/test/WithoutJenkins.java
0 → 100644
浏览文件 @
c24a2b1e
package
org.jvnet.hudson.test
;
import
java.lang.annotation.Documented
;
import
java.lang.annotation.Retention
;
import
java.lang.annotation.Target
;
import
static
java
.
lang
.
annotation
.
ElementType
.
ANNOTATION_TYPE
;
import
static
java
.
lang
.
annotation
.
ElementType
.
METHOD
;
import
static
java
.
lang
.
annotation
.
RetentionPolicy
.
RUNTIME
;
/**
* An annotation for test methods that do not require the {@link JenkinsRule} to create and tear down the jenkins
* instance.
*/
@Retention
(
RUNTIME
)
@Documented
@Target
(
METHOD
)
public
@interface
WithoutJenkins
{
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录