Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
roginluo
Jenkins
提交
b98e0abe
J
Jenkins
项目概览
roginluo
/
Jenkins
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
Jenkins
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
b98e0abe
编写于
3月 14, 2014
作者:
M
Mads Nielsen
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Added test for JENKINS-21394
上级
ce580257
变更
2
显示空白变更内容
内联
并排
Showing
2 changed file
with
237 addition
and
1 deletion
+237
-1
test/src/main/java/org/jvnet/hudson/test/JenkinsRule.java
test/src/main/java/org/jvnet/hudson/test/JenkinsRule.java
+1
-1
test/src/test/java/hudson/model/ProjectTest.java
test/src/test/java/hudson/model/ProjectTest.java
+236
-0
未找到文件。
test/src/main/java/org/jvnet/hudson/test/JenkinsRule.java
浏览文件 @
b98e0abe
test/src/test/java/hudson/model/ProjectTest.java
浏览文件 @
b98e0abe
...
...
@@ -60,6 +60,12 @@ import java.io.File;
import
hudson.FilePath
;
import
hudson.slaves.EnvironmentVariablesNodeProperty
;
import
hudson.EnvVars
;
import
hudson.model.labels.LabelAtom
;
import
hudson.slaves.Cloud
;
import
hudson.slaves.DumbSlave
;
import
hudson.slaves.DummyCloudImpl
;
import
hudson.slaves.NodeProvisioner
;
import
hudson.slaves.OfflineCause
;
import
hudson.tasks.Shell
;
import
org.jvnet.hudson.test.MilliSecLogFormatter
;
import
org.jvnet.hudson.test.TestExtension
;
...
...
@@ -75,12 +81,17 @@ import org.jvnet.hudson.test.JenkinsRule;
import
static
org
.
junit
.
Assert
.*;
import
hudson.tasks.Fingerprinter
;
import
hudson.tasks.ArtifactArchiver
;
import
hudson.util.OneShotEvent
;
import
java.util.Map
;
import
java.util.concurrent.Callable
;
import
java.util.concurrent.ExecutionException
;
import
java.util.concurrent.Future
;
import
java.util.concurrent.TimeUnit
;
import
java.util.logging.Logger
;
import
org.junit.Ignore
;
import
org.jvnet.localizer.Localizable
;
import
sun.awt.image.OffScreenImage
;
/**
*
...
...
@@ -638,6 +649,110 @@ public class ProjectTest {
assertFalse
(
"Project should be enabled."
,
project
.
isDisabled
());
}
/**
* Job is un-restricted (no nabel), this is submitted to queue, which spawns an on demand slave
* @throws Exception
*/
@Test
public
void
testJobSubmittedShouldSpawnCloud
()
throws
Exception
{
/**
* Setup a project with an SCM. Jenkins should have no executors in itself.
*/
FreeStyleProject
proj
=
j
.
createFreeStyleProject
(
"JENKINS-21394-spawn"
);
RequiresWorkspaceSCM
requiresWorkspaceScm
=
new
RequiresWorkspaceSCM
(
true
);
proj
.
setScm
(
requiresWorkspaceScm
);
j
.
jenkins
.
setNumExecutors
(
0
);
/*
* We have a cloud
*/
DummyCloudImpl2
c2
=
new
DummyCloudImpl2
(
j
,
0
);
c2
.
label
=
new
LabelAtom
(
"test-cloud-label"
);
j
.
jenkins
.
clouds
.
add
(
c2
);
SCMTrigger
t
=
new
SCMTrigger
(
"@daily"
,
true
);
t
.
start
(
proj
,
true
);
proj
.
addTrigger
(
t
);
t
.
new
Runner
().
run
();
Thread
.
sleep
(
1000
);
//Assert that the job IS submitted to Queue.
assertEquals
(
1
,
j
.
jenkins
.
getQueue
().
getItems
().
length
);
}
/**
* Job is restricted, but label can not be provided by any cloud, only normal slaves. Then job will not submit, because no slave is available.
* @throws Exception
*/
@Test
public
void
testUnrestrictedJobNoLabelByCloudNoQueue
()
throws
Exception
{
assertTrue
(
j
.
jenkins
.
clouds
.
isEmpty
());
//Create slave. (Online)
Slave
s1
=
j
.
createOnlineSlave
();
//Create a project, and bind the job to the created slave
FreeStyleProject
proj
=
j
.
createFreeStyleProject
(
"JENKINS-21394-noqueue"
);
proj
.
setAssignedLabel
(
s1
.
getSelfLabel
());
//Add an SCM to the project. We require a workspace for the poll
RequiresWorkspaceSCM
requiresWorkspaceScm
=
new
RequiresWorkspaceSCM
(
true
);
proj
.
setScm
(
requiresWorkspaceScm
);
j
.
buildAndAssertSuccess
(
proj
);
//Now create another slave. And restrict the job to that slave. The slave is offline, leaving the job with no assignable nodes.
//We tell our mock SCM to return that it has got changes. But since there are no slaves, we get the desired result.
Slave
s2
=
j
.
createSlave
();
proj
.
setAssignedLabel
(
s2
.
getSelfLabel
());
requiresWorkspaceScm
.
hasChange
=
true
;
//Poll (We now should have NO online slaves, this should now return NO_CHANGES.
PollingResult
pr
=
proj
.
poll
(
j
.
createTaskListener
());
assertFalse
(
pr
.
hasChanges
());
SCMTrigger
t
=
new
SCMTrigger
(
"@daily"
,
true
);
t
.
start
(
proj
,
true
);
proj
.
addTrigger
(
t
);
t
.
new
Runner
().
run
();
/**
* Assert that the log contains the correct message.
*/
HtmlPage
log
=
j
.
createWebClient
().
getPage
(
proj
,
"scmPollLog"
);
String
logastext
=
log
.
asText
();
assertTrue
(
logastext
.
contains
(
"("
+
AbstractProject
.
WorkspaceOfflineReason
.
all_suitable_nodes_are_offline
.
name
()
+
")"
));
}
/**
* Job is restricted. Label is on slave that can be started in cloud. Job is submitted to queue, which spawns an on demand slave.
* @throws Exception
*/
@Test
public
void
testRestrictedLabelOnSlaveYesQueue
()
throws
Exception
{
FreeStyleProject
proj
=
j
.
createFreeStyleProject
(
"JENKINS-21394-yesqueue"
);
RequiresWorkspaceSCM
requiresWorkspaceScm
=
new
RequiresWorkspaceSCM
(
true
);
proj
.
setScm
(
requiresWorkspaceScm
);
j
.
jenkins
.
setNumExecutors
(
0
);
/*
* We have a cloud
*/
DummyCloudImpl2
c2
=
new
DummyCloudImpl2
(
j
,
0
);
c2
.
label
=
new
LabelAtom
(
"test-cloud-label"
);
j
.
jenkins
.
clouds
.
add
(
c2
);
proj
.
setAssignedLabel
(
c2
.
label
);
SCMTrigger
t
=
new
SCMTrigger
(
"@daily"
,
true
);
t
.
start
(
proj
,
true
);
proj
.
addTrigger
(
t
);
t
.
new
Runner
().
run
();
Thread
.
sleep
(
1000
);
//The job should be in queue
assertEquals
(
1
,
j
.
jenkins
.
getQueue
().
getItems
().
length
);
}
public
static
class
TransientAction
extends
InvisibleAction
{
}
...
...
@@ -655,6 +770,36 @@ public class ProjectTest {
}
@TestExtension
public
static
class
RequiresWorkspaceSCM
extends
NullSCM
{
public
boolean
hasChange
=
false
;
public
RequiresWorkspaceSCM
()
{
}
public
RequiresWorkspaceSCM
(
boolean
hasChange
)
{
this
.
hasChange
=
hasChange
;
}
@Override
public
boolean
pollChanges
(
AbstractProject
<?,
?>
project
,
Launcher
launcher
,
FilePath
workspace
,
TaskListener
listener
)
throws
IOException
,
InterruptedException
{
return
true
;
}
@Override
public
boolean
requiresWorkspaceForPolling
(){
return
true
;
}
@Override
protected
PollingResult
compareRemoteRevisionWith
(
AbstractProject
project
,
Launcher
launcher
,
FilePath
workspace
,
TaskListener
listener
,
SCMRevisionState
baseline
)
throws
IOException
,
InterruptedException
{
if
(!
hasChange
)
{
return
PollingResult
.
NO_CHANGES
;
}
return
PollingResult
.
SIGNIFICANT
;
}
}
@TestExtension
public
static
class
AlwaysChangedSCM
extends
NullSCM
{
...
...
@@ -662,6 +807,7 @@ public class ProjectTest {
public
boolean
pollChanges
(
AbstractProject
<?,
?>
project
,
Launcher
launcher
,
FilePath
workspace
,
TaskListener
listener
)
throws
IOException
,
InterruptedException
{
return
true
;
}
@Override
public
boolean
requiresWorkspaceForPolling
(){
return
false
;
...
...
@@ -749,4 +895,94 @@ public class ProjectTest {
public
class
ActionImpl
extends
InvisibleAction
{
}
@TestExtension
public
static
class
DummyCloudImpl2
extends
Cloud
{
private
final
transient
JenkinsRule
caller
;
/**
* Configurable delay between the {@link Cloud#provision(Label,int)} and the actual launch of a slave,
* to emulate a real cloud that takes some time for provisioning a new system.
*
* <p>
* Number of milliseconds.
*/
private
final
int
delay
;
// stats counter to perform assertions later
public
int
numProvisioned
;
/**
* Only reacts to provisioning for this label.
*/
public
Label
label
;
public
DummyCloudImpl2
()
{
super
(
"test"
);
this
.
delay
=
0
;
this
.
caller
=
null
;
}
public
DummyCloudImpl2
(
JenkinsRule
caller
,
int
delay
)
{
super
(
"test"
);
this
.
caller
=
caller
;
this
.
delay
=
delay
;
}
@Override
public
Collection
<
NodeProvisioner
.
PlannedNode
>
provision
(
Label
label
,
int
excessWorkload
)
{
List
<
NodeProvisioner
.
PlannedNode
>
r
=
new
ArrayList
<
NodeProvisioner
.
PlannedNode
>();
//Always provision...even if there is no workload.
while
(
excessWorkload
>=
0
)
{
System
.
out
.
println
(
"Provisioning"
);
numProvisioned
++;
Future
<
Node
>
f
=
Computer
.
threadPoolForRemoting
.
submit
(
new
ProjectTest
.
DummyCloudImpl2
.
Launcher
(
delay
));
r
.
add
(
new
NodeProvisioner
.
PlannedNode
(
name
+
" #"
+
numProvisioned
,
f
,
1
));
excessWorkload
-=
1
;
}
return
r
;
}
@Override
public
boolean
canProvision
(
Label
label
)
{
//This cloud can ALWAYS provision
return
true
;
/* return label==this.label; */
}
private
final
class
Launcher
implements
Callable
<
Node
>
{
private
final
long
time
;
/**
* This is so that we can find out the status of Callable from the debugger.
*/
private
volatile
Computer
computer
;
private
Launcher
(
long
time
)
{
this
.
time
=
time
;
}
@Override
public
Node
call
()
throws
Exception
{
// simulate the delay in provisioning a new slave,
// since it's normally some async operation.
Thread
.
sleep
(
time
);
System
.
out
.
println
(
"launching slave"
);
DumbSlave
slave
=
caller
.
createSlave
(
label
);
computer
=
slave
.
toComputer
();
computer
.
connect
(
false
).
get
();
synchronized
(
ProjectTest
.
DummyCloudImpl2
.
this
)
{
System
.
out
.
println
(
computer
.
getName
()+
" launch"
+(
computer
.
isOnline
()?
"ed successfully"
:
" failed"
));
System
.
out
.
println
(
computer
.
getLog
());
}
return
slave
;
}
}
@Override
public
Descriptor
<
Cloud
>
getDescriptor
()
{
throw
new
UnsupportedOperationException
();
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录