Hi Michael,
I had work pipeline job. But after add more environments (envList) job
broke with log:
[Pipeline] End of Pipeline
an exception which occurred:
in field delegate
in field closures
in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@1845f26
Caused: java.io.NotSerializableException: java.util.LinkedHashMap$Entry
at
org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:860)
at
org.jboss.marshalling.river.BlockMarshaller.doWriteObject(BlockMarshaller.java:65)
at
org.jboss.marshalling.river.BlockMarshaller.writeObject(BlockMarshaller.java:56)
at
org.jboss.marshalling.MarshallerObjectOutputStream.writeObjectOverride(MarshallerObjectOutputStream.java:50)
at
org.jboss.marshalling.river.RiverObjectOutputStream.writeObjectOverride(RiverObjectOutputStream.java:179)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:344)
at java.util.LinkedHashMap.internalWriteEntries(LinkedHashMap.java:333)
at java.util.HashMap.writeObject(HashMap.java:1362)
at sun.reflect.GeneratedMethodAccessor61.invoke(Unknown Source)
I use NonCPS function sortSuites() and it always return list. I don't
have more ideas how to fix. Can you help?
Thank you!
My test pipeline:
#!groovy
def envList = []
envList.add('NODE=behat3 ORO_PHP=7.1 ORO_APP=application/commerce-crm-ee
ORO_TEST_SUITE=behat ORO_DB=pgsql BEHAT_MODE=standalone')
envList.add('NODE=docker-doc ORO_TEST_SUITE=documentation
ORO_APP=documentation/crm ORO_DOC=OroCRM_Documentation')
envList.add('NODE=docker-doc ORO_TEST_SUITE=documentation
ORO_APP=documentation/commerce ORO_DOC=OroCommerce_Documentation')
envList.add('NODE=func_2cpu ORO_PHP=7.1
ORO_APP=application/crm-enterprise ORO_TEST_SUITE=functional
ORO_DB=PG ORO_INSTALLED=crm-enterprise_1.12 ORO_SE=ES ES_VER=2.4.3
UPGRADE=true TEST_RUNNER_OPTIONS=--group=search,dist')
envList.add('NODE=func_2cpu ORO_PHP=7.1
ORO_APP=application/crm-enterprise ORO_TEST_SUITE=functional
ORO_DB=PG ORO_INSTALLED=crm-enterprise_2.0.0 ORO_SE=ES ES_VER=2.4.3')
envList.add('NODE=func_2cpu ORO_PHP=7.0
ORO_APP=application/crm-enterprise ORO_TEST_SUITE=functional
ORO_DB=PG ORO_INSTALLED=crm-enterprise_1.12 UPGRADE=true')
envList.add('NODE=func ORO_PHP=7.1
ORO_APP=application/commerce-enterprise ORO_TEST_SUITE=functional
ORO_DB=PG ORO_INSTALLED=commerce_1.3.0 ORO_SE=ES ES_VER=2.3.5')
envList.add('NODE=func ORO_PHP=7.0
ORO_APP=application/commerce-enterprise ORO_TEST_SUITE=functional
ORO_DB=MYSQL ORO_INSTALLED=commerce_1.0.0')
envList.add('NODE=func ORO_PHP=7.1
ORO_APP=application/commerce ORO_TEST_SUITE=functional
ORO_DB=PG ORO_INSTALLED=commerce_1.0.0')
envList.add('NODE=func ORO_PHP=7.1
ORO_APP=application/commerce-crm ORO_TEST_SUITE=functional
ORO_DB=PG ORO_ENABLE_PRICE_SHARDING=true')
envList.add('NODE=func ORO_PHP=7.1
ORO_APP=application/commerce-crm-ee ORO_TEST_SUITE=functional
ORO_DB=PG ORO_INSTALLED=commerce_1.3.0')
envList.add('NODE=func ORO_PHP=7.1
ORO_APP=application/commerce-crm-ee ORO_TEST_SUITE=functional
ORO_DB=MYSQL ORO_INSTALLED=crm-enterprise_1.12 UPGRADE=true')
envList.add('NODE=func_2cpu ORO_PHP=7.1
ORO_APP=application/platform ORO_TEST_SUITE=functional
ORO_DB=PG')
envList.add('NODE=func_2cpu ORO_PHP=7.1
ORO_APP=application/crm ORO_TEST_SUITE=functional
ORO_DB=MYSQL')
envList.add('NODE=func_2cpu ORO_PHP=7.1 ORO_TEST_SUITE=behat_wiring')
envList.add('NODE=func ORO_PHP=7.1 ORO_TEST_SUITE=javascript JS=YES CS=YES')
envList.add('NODE=func_2cpu ORO_PHP=7.0
ORO_APP=application/commerce-crm-ee ORO_TEST_SUITE=unit')
envList.add('NODE=func_2cpu ORO_PHP=7.1
ORO_APP=application/commerce-crm-ee ORO_TEST_SUITE=unit')
def behatList = []
def enviroments = [:]
for (int i = 0; i < envList.size() ; i++) {
int index=i, e = i+1
enviroments["TestEnv_${e}"] = {
stage ("TestEnv_${e}"){
withEnv(["NETWORK=${index}"] + ["TESTENV=TestEnv_${e}"] +
envList[index].tokenize()) {
if (env.ORO_TEST_SUITE == 'behat') {
node() {
ws("${HOME}/workspace/dev_${EXECUTOR_NUMBER}") {
sh """
echo "Install"
"""
behatStr = sh (
script: 'echo AutoSuiteSet_1 AutoSuiteSet_2
AutoSuiteSet_3',
returnStdout: true
).trim()
}
}
behatList=behatStr.tokenize()
echo "SUITES=${behatList}"
behatList=sortSuites(behatList)
echo "SUITES SORTED=${behatList}"
echo "behatList TYPE=${behatList.getClass()}"
def enviroments_b = [:]
for (int j = 0; j < behatList.size() ; j++) {
int index_b=j
enviroments_b["TestEnv_${e}
behat=${behatList[index_b]}"] = {
withEnv(["BEHAT_SUIT=${behatList[index_b]}"]) {
node() {
ws("${HOME}/workspace/dev_${EXECUTOR_NUMBER}") {
sh """
echo "Run BEHAT_SUIT=$BEHAT_SUIT"
"""
} //workspace
} //node
} //withEnv
} //enviroments_b
} //for
try {
parallel enviroments_b
} catch (error) {
throw (error)
}
} else if (env.ORO_TEST_SUITE == 'functional' ||
env.ORO_TEST_SUITE == 'unit' || env.ORO_TEST_SUITE == 'behat_wiring' ||
env.ORO_TEST_SUITE == 'javascript'){
node() {
ws("${HOME}/workspace/dev_${EXECUTOR_NUMBER}") {
sh """
echo "Run $ORO_TEST_SUITE"
"""
}
}
} else {
node() {
ws("${HOME}/workspace/dev_${EXECUTOR_NUMBER}") {
sh """
echo "Run $ORO_TEST_SUITE"
"""
}
}
}
}
}
}
}
try {
parallel enviroments
} catch (error) {
throw (error)
}
@NonCPS
def sortSuites(suites){
def suitesStat=[AutoSuiteSet_1:435, AutoSuiteSet_2:323,
AutoSuiteSet_3:363]
def suites_time = suitesStat
// def suites_time = [:]
def suitesMap = [:]
if (suites_time.size()>0){
def timeLimit = suites_time.values().max() //find max value
for(s in suites){
x = suites_time.find{ artifact -> artifact.key == s}
if(x){
suitesMap.put(x.key, x.value)
}else{
suitesMap.put(s, timeLimit)
}
}
}else{
def suitesList = suites.collect { t -> [t] }
return suitesList
}
tasks = divideList(suitesMap)
tasks = sortListInMap(tasks)
tasksList = tasks.collect { t -> t.keySet()}
return tasksList
}
@NonCPS
def divideList(inputMap){
// Sort an incoming array in descending order
inputMap=sortMap(inputMap)
maxValue = inputMap.values().max()
// Resulting set of maps
def outputSet = []
// Variable for storing an individual map
def outputMap = [:]
for (inputElement in inputMap) {
// We add to the temporary map and consider the resulting sum of
the maps items
possibleMap = outputMap + [inputElement]
possibleMapSum = possibleMap.values().sum()
// If the amount in the temporary map is less than maxValue, go
to the next iteration, we will try to supplement the map with one more
element
if (possibleMapSum < maxValue) {
outputMap = possibleMap
// If the amount in the temporary map is maxValue, add a
temporary map to the result set and zero the temporary map
}else if(possibleMapSum == maxValue) {
outputSet.add(possibleMap)
outputMap = [:]
// If the amount in the temporary map exceeded maxValue, add
the previous version of the temporary map to the result set (without the
current element), and create a new temporary map with the current element
}else if(possibleMapSum > maxValue) {
outputSet.add(outputMap)
outputMap = [:]
outputMap.put(inputElement.key, inputElement.value)
}
}
if (outputMap) {
outputSet.add(outputMap)
}
return outputSet
}
@NonCPS
def sortMap(map) {
map.sort{a, b -> b.value <=> a.value }
}
@NonCPS
def sortListInMap(map) {
map.sort { a, b -> b.values().sum() <=> a.values().sum() }
}
06.08.2017 17:47, Michael Pailloncy пишет:
It seems like there are some variables used out of their scope and
some misused Groovy methods.
Here is a working version, IIUC your pipeline :-)
#!groovy
def behatList =['AutoSuiteSet_0', 'AutoSuiteSet_1', 'AutoSuiteSet_2',
'AutoSuiteSet_3', 'AutoSuiteSet_4', 'AutoSuiteSet_5']
def suitesStat=[AutoSuiteSet_0:0, AutoSuiteSet_1:1, AutoSuiteSet_2:2,
AutoSuiteSet_3:3, AutoSuiteSet_4:4, AutoSuiteSet_5:5]
stage("test") {
node('master') {
behatList2=sortSuites(behatList, suitesStat)
echo "SUITES2=${behatList2}"
}
}
@NonCPS
def sortSuites(suites, suites_time){
def timeLimit = suites_time.values().max()
def suitesMap= [:]
for(s in suites){
def x = suites_time.find{ artifact -> artifact.key == s}
if(x){
suitesMap.put(x.key, x.value)
}else{
suitesMap.put(s, timeLimit)
}
}
def tasks = [suitesMap]
timeLimit = suitesMap.values().max()
while(canSplit(tasks, timeLimit)) {
tasks = tasks.collect { t ->
if(checkLimit(t, timeLimit)){
t = splitTo2(t)
}
t
}.flatten()
}
tasks.sort { a, b -> b.values().sum() <=> a.values().sum() }
// tasks = tasks.collect { t -> t.keySet()} // not working, multiple
elements are collected here
tasks = tasks.collectMany { t -> t.keySet()}
return tasks
}
@NonCPS
def checkLimit(t, timeLimit) {
if(t.values().sum()>timeLimit && t.size()>1){
return true
}else{
return false
}
}
@NonCPS
def canSplit(tasks, timeLimit) {
for(t in tasks) {
if(checkLimit(t, timeLimit)){
return true
}
}
return false
}
@NonCPS
def splitTo2(int_map) {
A=[:]
B=[:]
// int_map.sort{it.value} not working
// for(n in int_map.sort{it.value}) {
for(n in int_map) {
if (A.size() < B.size()) {
A.put(n.key, n.value)
}else{
B.put(n.key, n.value)
}
}
return [A, B]
}
However, what do you want to achieve exactly ? One of the main
advantage of Pipeline is its resumability after restart. But if you
use too many @NonCPS, you avoid this feature and this could lead to
unexpected behaviour sometimes.
Hopefully it helps :-)
2017-08-04 19:17 GMT+02:00 Slava Dubrovskiy <[email protected]
<mailto:[email protected]>>:
Hi.
I use a special algorithm to pre-sort the steps for parallel start.
Here is my test pipeline:
|
#!groovy
defbehatList
=['AutoSuiteSet_0','AutoSuiteSet_1','AutoSuiteSet_2','AutoSuiteSet_3','AutoSuiteSet_4','AutoSuiteSet_5']
defsuitesStat=[AutoSuiteSet_0:0,AutoSuiteSet_1:1,AutoSuiteSet_2:2,AutoSuiteSet_3:3,AutoSuiteSet_4:4,AutoSuiteSet_5:5]
stage("test"){
node('master'){
behatList2=sortSuites(behatList,suitesStat)
echo "SUITES2=${behatList2}"
}
}
@NonCPS
defsortSuites(suites,suites_time){
timeLimit =suites_time.values().max()
defsuitesMap=[:]
for(s insuites){
x=suites_time.find{artifact ->artifact.key ==s}
if(x){
suitesMap.put(x.key,x.value)
}else{
suitesMap.put(s,timeLimit)
}
}
tasks =[suitesMap]
timeLimit =suitesMap.values().max()
while(canSplit()){
tasks =tasks.collect {t ->
if(checkLimit(t)){
t =splitTo2(t)
}
t
}.flatten()
}
tasks.sort {a,b ->b.values().sum()<=>a.values().sum()}
tasks =tasks.collect {t ->t.keySet()}
returntasks
}
@NonCPS
defcheckLimit(t){
if(t.values().sum()>timeLimit &&t.size()>1){
returntrue
}else{
returnfalse
}
}
@NonCPS
defcanSplit(){
for(t intasks){
if(checkLimit(t)){
returntrue
}
}
returnfalse
}
@NonCPS
defsplitTo2(int_map){
A=[:]
B=[:]
for(n inint_map.sort{it.value}){
if(A.size()<B.size()){
A.put(n.key,n.value)
}else{
B.put(n.key,n.value)
}
}
return[A,B]
}
|
If I run it, I get the error:
|
an exception which occurred:
infield delegate
infield closures
inobjectorg.jenkinsci.plugins.workflow.cps.CpsThreadGroup@7fd2cde1
Caused:java.io.NotSerializableException:java.util.LinkedHashMap$Entry
at
org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:860)
at
org.jboss.marshalling.river.BlockMarshaller.doWriteObject(BlockMarshaller.java:65)
at
org.jboss.marshalling.river.BlockMarshaller.writeObject(BlockMarshaller.java:56)
at
org.jboss.marshalling.MarshallerObjectOutputStream.writeObjectOverride(MarshallerObjectOu
...
|
Please, help me what is wrong?
All methods under @NonCPS directive.
--
WBR,
Slava.
--
You received this message because you are subscribed to the Google
Groups "Jenkins Users" group.
To unsubscribe from this group and stop receiving emails from it,
send an email to [email protected]
<mailto:[email protected]>.
To view this discussion on the web visit
https://groups.google.com/d/msgid/jenkinsci-users/e7a79c56-512f-4706-ab65-9a347966abb3%40googlegroups.com
<https://groups.google.com/d/msgid/jenkinsci-users/e7a79c56-512f-4706-ab65-9a347966abb3%40googlegroups.com?utm_medium=email&utm_source=footer>.
For more options, visit https://groups.google.com/d/optout
<https://groups.google.com/d/optout>.
--
You received this message because you are subscribed to the Google
Groups "Jenkins Users" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to [email protected]
<mailto:[email protected]>.
To view this discussion on the web visit
https://groups.google.com/d/msgid/jenkinsci-users/CAPO77c0_uu7GwQGL3GNGoyh-D878mrbiMj-1fUZefgN0bRPmsA%40mail.gmail.com
<https://groups.google.com/d/msgid/jenkinsci-users/CAPO77c0_uu7GwQGL3GNGoyh-D878mrbiMj-1fUZefgN0bRPmsA%40mail.gmail.com?utm_medium=email&utm_source=footer>.
For more options, visit https://groups.google.com/d/optout.
--
WBD,
Viacheslav Dubrovskyi
--
You received this message because you are subscribed to the Google Groups "Jenkins
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/jenkinsci-users/2493fd53-6fd8-e528-462f-663457813e98%40gmail.com.
For more options, visit https://groups.google.com/d/optout.