Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
jenkins
提交
b3f88eff
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,发现更多精彩内容 >>
提交
b3f88eff
编写于
9月 11, 2012
作者:
J
Jesse Glick
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' into track-plugins-15003
上级
258579f2
85ee5a40
变更
14
隐藏空白更改
内联
并排
Showing
14 changed file
with
297 addition
and
37 deletion
+297
-37
changelog.html
changelog.html
+2
-0
core/src/main/java/hudson/FilePath.java
core/src/main/java/hudson/FilePath.java
+65
-1
core/src/main/java/hudson/PluginManager.java
core/src/main/java/hudson/PluginManager.java
+2
-2
core/src/main/java/hudson/model/UpdateCenter.java
core/src/main/java/hudson/model/UpdateCenter.java
+11
-5
core/src/main/java/hudson/model/UpdateSite.java
core/src/main/java/hudson/model/UpdateSite.java
+17
-5
core/src/main/java/hudson/model/UsageStatistics.java
core/src/main/java/hudson/model/UsageStatistics.java
+1
-0
core/src/main/resources/hudson/PluginManager/advanced.jelly
core/src/main/resources/hudson/PluginManager/advanced.jelly
+17
-1
core/src/test/java/hudson/util/XStream2Test.java
core/src/test/java/hudson/util/XStream2Test.java
+40
-5
core/src/test/java/jenkins/ResilientJsonObjectTest.java
core/src/test/java/jenkins/ResilientJsonObjectTest.java
+23
-0
core/src/test/resources/hudson/util/old-concurrentHashMap.xml
.../src/test/resources/hudson/util/old-concurrentHashMap.xml
+2
-2
maven-plugin/src/main/java/hudson/maven/RedeployPublisher.java
...-plugin/src/main/java/hudson/maven/RedeployPublisher.java
+12
-16
test/pom.xml
test/pom.xml
+2
-0
test/src/main/resources/plugins/tasks-update-center.json
test/src/main/resources/plugins/tasks-update-center.json
+36
-0
test/src/test/java/hudson/model/UpdateSiteTest.java
test/src/test/java/hudson/model/UpdateSiteTest.java
+67
-0
未找到文件。
changelog.html
浏览文件 @
b3f88eff
...
...
@@ -68,6 +68,8 @@ Upcoming changes</a>
Command line options to control the HTTP request handling thread behavior weren't working.
<li
class=
rfe
>
Default max # of concurrent HTTP request handling threads were brought down to a sane number (from 1000(!) to 20)
<li
class=
rfe
>
Display non-default update site URLs in the Advanced tab of Plugin Manager. (Currently not configurable from this UI.)
</ul>
</div>
<!--=TRUNK-END=-->
...
...
core/src/main/java/hudson/FilePath.java
浏览文件 @
b3f88eff
...
...
@@ -27,6 +27,7 @@ package hudson;
import
hudson.Launcher.LocalLauncher
;
import
hudson.Launcher.RemoteLauncher
;
import
hudson.model.AbstractDescribableImpl
;
import
jenkins.model.Jenkins
;
import
hudson.model.TaskListener
;
import
hudson.model.AbstractProject
;
...
...
@@ -828,7 +829,16 @@ public final class FilePath implements Serializable {
if
(
channel
!=
null
)
{
// run this on a remote system
try
{
return
channel
.
call
(
new
FileCallableWrapper
<
T
>(
callable
,
cl
));
DelegatingCallable
<
T
,
IOException
>
wrapper
=
new
FileCallableWrapper
<
T
>(
callable
,
cl
);
Jenkins
instance
=
Jenkins
.
getInstance
();
if
(
instance
!=
null
)
{
// this happens during unit tests
ExtensionList
<
FileCallableWrapperFactory
>
factories
=
instance
.
getExtensionList
(
FileCallableWrapperFactory
.
class
);
for
(
FileCallableWrapperFactory
factory
:
factories
)
{
wrapper
=
factory
.
wrap
(
wrapper
);
}
}
return
channel
.
call
(
wrapper
);
}
catch
(
TunneledInterruptedException
e
)
{
throw
(
InterruptedException
)
new
InterruptedException
().
initCause
(
e
);
}
catch
(
AbortException
e
)
{
...
...
@@ -843,6 +853,60 @@ public final class FilePath implements Serializable {
}
}
/**
* This extension point allows to contribute a wrapper around a fileCallable so that a plugin can "intercept" a
* call.
* <p>The {@link #wrap(hudson.remoting.DelegatingCallable)} method itself will be executed on master
* (and may collect contextual data if needed) and the returned wrapper will be executed on remote.
*
* @since 1.482
* @see AbstractInterceptorCallableWrapper
*/
public
static
abstract
class
FileCallableWrapperFactory
implements
ExtensionPoint
{
public
abstract
<
T
>
DelegatingCallable
<
T
,
IOException
>
wrap
(
DelegatingCallable
<
T
,
IOException
>
callable
);
}
/**
* Abstract {@link DelegatingCallable} that exposes an Before/After pattern for
* {@link hudson.FilePath.FileCallableWrapperFactory} that want to implement AOP-style interceptors
* @since 1.482
*/
public
abstract
class
AbstractInterceptorCallableWrapper
<
T
>
implements
DelegatingCallable
<
T
,
IOException
>
{
private
final
DelegatingCallable
<
T
,
IOException
>
callable
;
public
AbstractInterceptorCallableWrapper
(
DelegatingCallable
<
T
,
IOException
>
callable
)
{
this
.
callable
=
callable
;
}
@Override
public
final
ClassLoader
getClassLoader
()
{
return
callable
.
getClassLoader
();
}
public
final
T
call
()
throws
IOException
{
before
();
try
{
return
callable
.
call
();
}
finally
{
after
();
}
}
/**
* Executed before the actual FileCallable is invoked. This code will run on remote
*/
protected
void
before
()
{}
/**
* Executed after the actual FileCallable is invoked (even if this one failed). This code will run on remote
*/
protected
void
after
()
{}
}
/**
* Executes some program on the machine that this {@link FilePath} exists,
* so that one can perform local file operations.
...
...
core/src/main/java/hudson/PluginManager.java
浏览文件 @
b3f88eff
...
...
@@ -667,10 +667,10 @@ public abstract class PluginManager extends AbstractModelObject implements OnMas
UpdateCenter
uc
=
hudson
.
getUpdateCenter
();
PersistedList
<
UpdateSite
>
sites
=
uc
.
getSites
();
for
(
UpdateSite
s
:
sites
)
{
if
(
s
.
getId
().
equals
(
"default"
))
if
(
s
.
getId
().
equals
(
UpdateCenter
.
ID_DEFAULT
))
sites
.
remove
(
s
);
}
sites
.
add
(
new
UpdateSite
(
"default"
,
site
));
sites
.
add
(
new
UpdateSite
(
UpdateCenter
.
ID_DEFAULT
,
site
));
return
HttpResponses
.
redirectToContextRoot
();
}
...
...
core/src/main/java/hudson/model/UpdateCenter.java
浏览文件 @
b3f88eff
...
...
@@ -111,6 +111,12 @@ import org.kohsuke.stapler.interceptor.RequirePOST;
public
class
UpdateCenter
extends
AbstractModelObject
implements
Saveable
,
OnMaster
{
private
static
final
String
UPDATE_CENTER_URL
=
System
.
getProperty
(
UpdateCenter
.
class
.
getName
()+
".updateCenterUrl"
,
"http://updates.jenkins-ci.org/"
);
/**
* {@link #getId} of the default update site.
* @since 1.483
*/
public
static
final
String
ID_DEFAULT
=
"default"
;
/**
* {@link ExecutorService} that performs installation.
...
...
@@ -243,11 +249,11 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas
return
sites
.
toList
();
}
/**
* Alias for {@link #getById}.
*/
public
UpdateSite
getSite
(
String
id
)
{
for
(
UpdateSite
site
:
sites
)
if
(
site
.
getId
().
equals
(
id
))
return
site
;
return
null
;
return
getById
(
id
);
}
/**
...
...
@@ -479,7 +485,7 @@ public class UpdateCenter extends AbstractModelObject implements Saveable, OnMas
* Loads the data from the disk into this object.
*/
public
synchronized
void
load
()
throws
IOException
{
UpdateSite
defaultSite
=
new
UpdateSite
(
"default"
,
config
.
getUpdateCenterUrl
()
+
"update-center.json"
);
UpdateSite
defaultSite
=
new
UpdateSite
(
ID_DEFAULT
,
config
.
getUpdateCenterUrl
()
+
"update-center.json"
);
XmlFile
file
=
getConfigFile
();
if
(
file
.
exists
())
{
try
{
...
...
core/src/main/java/hudson/model/UpdateSite.java
浏览文件 @
b3f88eff
...
...
@@ -48,6 +48,7 @@ import org.kohsuke.stapler.interceptor.RequirePOST;
import
java.io.File
;
import
java.io.IOException
;
import
java.net.URI
;
import
java.security.GeneralSecurityException
;
import
java.util.ArrayList
;
import
java.util.Collections
;
...
...
@@ -378,7 +379,7 @@ public class UpdateSite {
* Is this the legacy default update center site?
*/
public
boolean
isLegacyDefault
()
{
return
id
.
equals
(
"default"
)
&&
url
.
startsWith
(
"http://hudson-ci.org/"
)
||
url
.
startsWith
(
"http://updates.hudson-labs.org/"
);
return
id
.
equals
(
UpdateCenter
.
ID_DEFAULT
)
&&
url
.
startsWith
(
"http://hudson-ci.org/"
)
||
url
.
startsWith
(
"http://updates.hudson-labs.org/"
);
}
/**
...
...
@@ -407,8 +408,8 @@ public class UpdateSite {
Data
(
JSONObject
o
)
{
this
.
sourceId
=
(
String
)
o
.
get
(
"id"
);
if
(
sourceId
.
equals
(
"default"
))
{
core
=
new
Entry
(
sourceId
,
o
.
getJSONObject
(
"core"
));
if
(
sourceId
.
equals
(
UpdateCenter
.
ID_DEFAULT
))
{
core
=
new
Entry
(
sourceId
,
o
.
getJSONObject
(
"core"
)
,
url
);
}
else
{
core
=
null
;
...
...
@@ -460,10 +461,21 @@ public class UpdateSite {
public
final
String
url
;
public
Entry
(
String
sourceId
,
JSONObject
o
)
{
this
(
sourceId
,
o
,
null
);
}
Entry
(
String
sourceId
,
JSONObject
o
,
String
baseURL
)
{
this
.
sourceId
=
sourceId
;
this
.
name
=
o
.
getString
(
"name"
);
this
.
version
=
o
.
getString
(
"version"
);
this
.
url
=
o
.
getString
(
"url"
);
String
url
=
o
.
getString
(
"url"
);
if
(!
URI
.
create
(
url
).
isAbsolute
())
{
if
(
baseURL
==
null
)
{
throw
new
IllegalArgumentException
(
"Cannot resolve "
+
url
+
" without a base URL"
);
}
url
=
URI
.
create
(
baseURL
).
resolve
(
url
).
toString
();
}
this
.
url
=
url
;
}
/**
...
...
@@ -535,7 +547,7 @@ public class UpdateSite {
@DataBoundConstructor
public
Plugin
(
String
sourceId
,
JSONObject
o
)
{
super
(
sourceId
,
o
);
super
(
sourceId
,
o
,
UpdateSite
.
this
.
url
);
this
.
wiki
=
get
(
o
,
"wiki"
);
this
.
title
=
get
(
o
,
"title"
);
this
.
excerpt
=
get
(
o
,
"excerpt"
);
...
...
core/src/main/java/hudson/model/UsageStatistics.java
浏览文件 @
b3f88eff
...
...
@@ -126,6 +126,7 @@ public class UsageStatistics extends PageDecorator {
JSONObject
o
=
new
JSONObject
();
o
.
put
(
"stat"
,
1
);
o
.
put
(
"install"
,
Util
.
getDigestOf
(
h
.
getSecretKey
()));
o
.
put
(
"servletContainer"
,
h
.
servletContext
.
getServerInfo
());
o
.
put
(
"version"
,
Jenkins
.
VERSION
);
List
<
JSONObject
>
nodes
=
new
ArrayList
<
JSONObject
>();
...
...
core/src/main/resources/hudson/PluginManager/advanced.jelly
浏览文件 @
b3f88eff
...
...
@@ -69,12 +69,28 @@ THE SOFTWARE.
<h1>${%Update Site}</h1>
<f:form method="post" action="siteConfigure">
<f:entry title="${%URL}" >
<f:textbox name="site" value="${app.updateCenter.getSite(
'default'
).url}" />
<f:textbox name="site" value="${app.updateCenter.getSite(
app.updateCenter.ID_DEFAULT
).url}" />
</f:entry>
<f:block>
<f:submit value="${%Submit}" />
</f:block>
</f:form>
<j:set var="hasNonDefault" value="${false}"/>
<j:forEach var="site" items="${app.updateCenter.sites}">
<j:if test="${site.id != app.updateCenter.ID_DEFAULT}">
<j:set var="hasNonDefault" value="${true}"/>
</j:if>
</j:forEach>
<j:if test="${hasNonDefault}">
<h2>${%Other Sites}</h2>
<ul>
<j:forEach var="site" items="${app.updateCenter.sites}">
<j:if test="${site.id != app.updateCenter.ID_DEFAULT}">
<li>${site.url}</li>
</j:if>
</j:forEach>
</ul>
</j:if>
</l:hasPermission>
</td>
</tr>
...
...
core/src/test/java/hudson/util/XStream2Test.java
浏览文件 @
b3f88eff
...
...
@@ -25,21 +25,22 @@ package hudson.util;
import
com.google.common.collect.ImmutableList
;
import
com.google.common.collect.ImmutableMap
;
import
junit.framework.TestCas
e
;
import
hudson.XmlFil
e
;
import
hudson.matrix.MatrixRun
;
import
hudson.model.Result
;
import
hudson.model.Run
;
import
org.jvnet.hudson.test.Bug
;
import
java.io.File
;
import
java.io.InputStream
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.logging.Level
;
import
java.util.logging.Logger
;
import
jenkins.model.CauseOfInterruption
;
import
jenkins.model.InterruptedBuildAction
;
import
junit.framework.TestCase
;
import
org.apache.commons.io.FileUtils
;
import
org.jvnet.hudson.test.Bug
;
/**
* Tests for XML serialization of java objects.
...
...
@@ -276,4 +277,38 @@ public class XStream2Test extends TestCase {
(
CauseOfInterruption
.
UserInterruption
)
action
.
getCauses
().
get
(
0
);
assertNotNull
(
cause
);
}
public
static
class
Foo2
{
ConcurrentHashMap
<
String
,
String
>
m
=
new
ConcurrentHashMap
<
String
,
String
>();
}
/**
* Tests that ConcurrentHashMap is serialized into a more compact format,
* but still can deserialize to older, verbose format.
*/
public
void
testConcurrentHashMapSerialization
()
throws
Exception
{
Foo2
foo
=
new
Foo2
();
foo
.
m
.
put
(
"abc"
,
"def"
);
foo
.
m
.
put
(
"ghi"
,
"jkl"
);
File
v
=
File
.
createTempFile
(
"hashmap"
,
"xml"
);
try
{
new
XmlFile
(
v
).
write
(
foo
);
// should serialize like map
String
xml
=
FileUtils
.
readFileToString
(
v
);
assertFalse
(
xml
.
contains
(
"java.util.concurrent"
));
//System.out.println(xml);
Foo2
deserialized
=
(
Foo2
)
new
XStream2
().
fromXML
(
xml
);
assertEquals
(
2
,
deserialized
.
m
.
size
());
assertEquals
(
"def"
,
deserialized
.
m
.
get
(
"abc"
));
assertEquals
(
"jkl"
,
deserialized
.
m
.
get
(
"ghi"
));
}
finally
{
v
.
delete
();
}
// should be able to read in old data just fine
Foo2
map
=
(
Foo2
)
new
XStream2
().
fromXML
(
getClass
().
getResourceAsStream
(
"old-concurrentHashMap.xml"
));
assertEquals
(
1
,
map
.
m
.
size
());
assertEquals
(
"def"
,
map
.
m
.
get
(
"abc"
));
}
}
core/src/test/java/jenkins/ResilientJsonObjectTest.java
0 → 100644
浏览文件 @
b3f88eff
package
jenkins
;
import
net.sf.json.JSONObject
;
import
org.junit.Test
;
import
org.jvnet.hudson.test.Bug
;
/**
* @author Kohsuke Kawaguchi
*/
public
class
ResilientJsonObjectTest
{
public
static
class
Foo
{
public
int
a
;
}
/**
* {@link JSONObject} databinding should be able to ignore non-existent fields.
*/
@Test
@Bug
(
15105
)
public
void
databindingShouldIgnoreUnrecognizedJsonProperty
()
{
JSONObject
o
=
JSONObject
.
fromObject
(
"{a:1,b:2}"
);
Foo
f
=
(
Foo
)
JSONObject
.
toBean
(
o
,
Foo
.
class
);
assert
f
.
a
==
1
;
}
}
core/src/test/resources/hudson/util/old-concurrentHashMap.xml
浏览文件 @
b3f88eff
<hudson.util.XStream
Test_-Foo
>
<hudson.util.XStream
2Test_-Foo2
>
<m
serialization=
"custom"
>
<unserializable-parents/>
<java.util.concurrent.ConcurrentHashMap>
...
...
@@ -222,4 +222,4 @@
<null/>
</java.util.concurrent.ConcurrentHashMap>
</m>
</hudson.util.XStreamTest_-Foo>
\ No newline at end of file
</hudson.util.XStream2Test_-Foo2>
\ No newline at end of file
maven-plugin/src/main/java/hudson/maven/RedeployPublisher.java
浏览文件 @
b3f88eff
...
...
@@ -209,7 +209,7 @@ public class RedeployPublisher extends Recorder {
String
privateRepository
=
null
;
FilePath
remoteSettingsFromConfig
=
null
;
File
tmpSettings
=
File
.
createTempFile
(
"jenkins"
,
"temp-settings.xml"
)
;
File
tmpSettings
=
null
;
try
{
AbstractProject
project
=
build
.
getProject
();
...
...
@@ -269,29 +269,25 @@ public class RedeployPublisher extends Recorder {
// assume that build was made on master
buildNode
=
Jenkins
.
getInstance
();
}
m
=
mavenModuleSet
.
getMaven
().
forNode
(
buildNode
,
listener
);
if
(
StringUtils
.
isBlank
(
altSettingsPath
)
)
{
// get userHome from the node where job has been executed
String
remoteUserHome
=
build
.
getWorkspace
().
act
(
new
GetUserHome
()
);
altSettingsPath
=
remoteUserHome
+
"/.m2/settings.xml"
;
}
// we copy this file in the master in a temporary file
FilePath
filePath
=
new
FilePath
(
tmpSettings
);
// we copy this file in the master in a temporary file
FilePath
remoteSettings
=
build
.
getWorkspace
().
child
(
altSettingsPath
);
if
(
!
remoteSettings
.
exists
()
)
{
// JENKINS-9084 we finally use $M2_HOME/conf/settings.xml as maven do
String
mavenHome
=
((
MavenModuleSet
)
project
).
getMaven
().
forNode
(
buildNode
,
listener
).
getHome
(
);
String
settingsPath
=
mavenHome
+
"/conf/settings.xml"
;
remoteSettings
=
build
.
getWorkspace
().
child
(
settingsPath
)
;
if
(
remoteSettings
!=
null
)
{
listener
.
getLogger
().
println
(
"Maven RedeployPublisher use "
+
(
buildNode
!=
null
?
buildNode
.
getNodeName
()
:
"local"
)
+
" maven settings from : "
+
remoteSettings
.
getRemote
()
);
tmpSettings
=
File
.
createTempFile
(
"jenkins"
,
"temp-settings.xml"
);
FilePath
filePath
=
new
FilePath
(
tmpSettings
);
remoteSettings
.
copyTo
(
filePath
)
;
settingsLoc
=
tmpSettings
;
}
listener
.
getLogger
().
println
(
"Maven RedeployPublisher use remote "
+
(
buildNode
!=
null
?
buildNode
.
getNodeName
()
:
"local"
)
+
" maven settings from : "
+
remoteSettings
.
getRemote
()
);
remoteSettings
.
copyTo
(
filePath
);
settingsLoc
=
tmpSettings
;
}
MavenEmbedderRequest
mavenEmbedderRequest
=
new
MavenEmbedderRequest
(
listener
,
...
...
test/pom.xml
浏览文件 @
b3f88eff
...
...
@@ -235,6 +235,7 @@ THE SOFTWARE.
<includes>
<include>
**/UseRecipesWithJenkinsRuleTest.java
</include>
<include>
hudson/model/CauseTest.java
</include>
<include>
hudson/model/UpdateSiteTest.java
</include>
<include>
hudson/triggers/TriggerStartTest.java
</include>
</includes>
</configuration>
...
...
@@ -280,6 +281,7 @@ THE SOFTWARE.
<excludes>
<exclude>
org/jvnet/hudson/main/UseRecipesWithJenkinsRuleTest.class
</exclude>
<exclude>
hudson/model/CauseTest.class
</exclude>
<exclude>
hudson/model/UpdateSiteTest.class
</exclude>
<exclude>
hudson/triggers/TriggerStartTest.class
</exclude>
</excludes>
</configuration>
...
...
test/src/main/resources/plugins/tasks-update-center.json
0 → 100644
浏览文件 @
b3f88eff
{
"core"
:
{
"buildDate"
:
"Dec 31, 1969"
,
"name"
:
"core"
,
"url"
:
"jenkins.war"
,
"version"
:
"23"
},
"id"
:
"default"
,
"plugins"
:
{
"tasks"
:
{
"buildDate"
:
"Dec 17, 2008"
,
"dependencies"
:
[],
"developers"
:
[{
"name"
:
"lokadm"
}],
"excerpt"
:
" This plug-in scans for open tasks in a specified set of files in the project modules and visualizes the results. "
,
"name"
:
"tasks"
,
"requiredCore"
:
"1.264"
,
"sha1"
:
"wtzlciUKiMcg90H5CTYkGX6+r8Y="
,
"title"
:
"Hudson Task Scanner Plug-in"
,
"url"
:
"tasks.hpi"
,
"version"
:
"2.23"
},
"dummy"
:
{
"buildDate"
:
"Dec 17, 2008"
,
"dependencies"
:
[],
"developers"
:
[],
"excerpt"
:
"…"
,
"name"
:
"dummy"
,
"requiredCore"
:
"1.100"
,
"sha1"
:
"wtzlcjUKiMcg90H5CTYkGX6+r8Y="
,
"title"
:
"Dummy"
,
"url"
:
"http://nowhere.net/dummy.hpi"
,
"version"
:
"1.0"
}
},
"updateCenterVersion"
:
1
}
core/src/test/java/hudson/util/XStream
Test.java
→
test/src/test/java/hudson/model/UpdateSite
Test.java
浏览文件 @
b3f88eff
/*
* The MIT License
*
* Copyright
(c) 2010, InfraDNA, Inc
.
* Copyright
2012 Jesse Glick
.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
...
...
@@ -21,53 +21,47 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package
hudson.util
;
import
hudson.XmlFile
;
import
junit.framework.TestCase
;
import
org.apache.commons.io.FileUtils
;
package
hudson.model
;
import
java.io.File
;
import
java.util.concurrent.ConcurrentHashMap
;
import
com.gargoylesoftware.htmlunit.HttpMethod
;
import
com.gargoylesoftware.htmlunit.Page
;
import
com.gargoylesoftware.htmlunit.WebRequestSettings
;
import
hudson.model.UpdateSite.Data
;
import
hudson.util.PersistedList
;
import
java.net.URL
;
import
java.util.Arrays
;
import
java.util.HashSet
;
import
org.apache.commons.io.IOUtils
;
import
static
org
.
junit
.
Assert
.*;
import
org.junit.Rule
;
import
org.junit.Test
;
import
org.jvnet.hudson.test.JenkinsRule
;
/**
* @author Kohsuke Kawaguchi
*/
public
class
XStreamTest
extends
TestCase
{
private
XStream2
xstream
=
new
XStream2
();
public
static
class
Foo
{
ConcurrentHashMap
<
String
,
String
>
m
=
new
ConcurrentHashMap
<
String
,
String
>();
}
public
class
UpdateSiteTest
{
/**
* Tests that ConcurrentHashMap is serialized into a more compact format,
* but still can deserialize to older, verbose format.
*/
public
void
testConcurrentHashMapSerialization
()
throws
Exception
{
Foo
foo
=
new
Foo
();
foo
.
m
.
put
(
"abc"
,
"def"
);
foo
.
m
.
put
(
"ghi"
,
"jkl"
);
File
v
=
File
.
createTempFile
(
"hashmap"
,
"xml"
);
try
{
new
XmlFile
(
v
).
write
(
foo
);
@Rule
public
JenkinsRule
j
=
new
JenkinsRule
();
// should serialize like map
String
xml
=
FileUtils
.
readFileToString
(
v
);
assertFalse
(
xml
.
contains
(
"java.util.concurrent"
));
//System.out.println(xml);
Foo
deserialized
=
(
Foo
)
xstream
.
fromXML
(
xml
);
assertEquals
(
2
,
deserialized
.
m
.
size
());
assertEquals
(
"def"
,
deserialized
.
m
.
get
(
"abc"
));
assertEquals
(
"jkl"
,
deserialized
.
m
.
get
(
"ghi"
));
}
finally
{
v
.
delete
();
@Test
public
void
relativeURLs
()
throws
Exception
{
PersistedList
<
UpdateSite
>
sites
=
j
.
jenkins
.
getUpdateCenter
().
getSites
();
sites
.
clear
();
URL
url
=
UpdateSiteTest
.
class
.
getResource
(
"/plugins/tasks-update-center.json"
);
UpdateSite
site
=
new
UpdateSite
(
UpdateCenter
.
ID_DEFAULT
,
url
.
toString
());
sites
.
add
(
site
);
UpdateSite
.
signatureCheck
=
false
;
{
// XXX pending UpdateSite.updateDirectly:
j
.
jenkins
.
setCrumbIssuer
(
null
);
WebRequestSettings
wrs
=
new
WebRequestSettings
(
new
URL
(
j
.
getURL
(),
"/updateCenter/byId/default/postBack"
),
HttpMethod
.
POST
);
wrs
.
setRequestBody
(
IOUtils
.
toString
(
url
.
openStream
()));
Page
p
=
j
.
createWebClient
().
getPage
(
wrs
);
assertEquals
(
/* FormValidation.OK */
"<div/>"
,
p
.
getWebResponse
().
getContentAsString
());
}
// should be able to read in old data just fine
Foo
map
=
(
Foo
)
new
XStream2
().
fromXML
(
getClass
().
getResourceAsStream
(
"old-concurrentHashMap.xml"
));
assertEquals
(
1
,
map
.
m
.
size
());
assertEquals
(
"def"
,
map
.
m
.
get
(
"abc"
));
Data
data
=
site
.
getData
();
assertNotNull
(
data
);
assertEquals
(
new
URL
(
url
,
"jenkins.war"
).
toString
(),
data
.
core
.
url
);
assertEquals
(
new
HashSet
<
String
>(
Arrays
.
asList
(
"tasks"
,
"dummy"
)),
data
.
plugins
.
keySet
());
assertEquals
(
new
URL
(
url
,
"tasks.hpi"
).
toString
(),
data
.
plugins
.
get
(
"tasks"
).
url
);
assertEquals
(
"http://nowhere.net/dummy.hpi"
,
data
.
plugins
.
get
(
"dummy"
).
url
);
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录