catchError {
    def append = { m, x ->
        def y = x[0].collect()
        y.add(x[1])
        m.add(y)
        m
    }

    def plist = [
        [string(name: "WORKLOAD", value: "append")],
        [string(name: "WORKLOAD", value: "bank"), booleanParam(name: "UPDATE_IN_PLACE", value: true)],
        [string(name: "WORKLOAD", value: "bank"), booleanParam(name: "UPDATE_IN_PLACE", value: false)],
        [string(name: "WORKLOAD", value: "bank-multitable"), booleanParam(name: "UPDATE_IN_PLACE", value: true)],
        [string(name: "WORKLOAD", value: "bank-multitable"), booleanParam(name: "UPDATE_IN_PLACE", value: false)],
        [string(name: "WORKLOAD", value: "register"), booleanParam(name: "USE_INDEX", value: true)],
        [string(name: "WORKLOAD", value: "register"), booleanParam(name: "USE_INDEX", value: false)],
        [string(name: "WORKLOAD", value: "set-cas")],
    ]

    plist = [plist, [
        string(name: "TXN_MODE", value: "pessimistic"),
        string(name: "TXN_MODE", value: "mixed"),
    ]].combinations().inject([], append)

    plist = [plist, [
        string(name: "NEMESIS", value: "none"),
        string(name: "NEMESIS", value: "partition"),
        string(name: "NEMESIS", value: "kill"),
        string(name: "NEMESIS", value: "shuffle-leader,shuffle-region,random-merge"),
    ]].combinations().inject([], append)

    plist = [plist, [
        booleanParam(name: "FOLLOWER_READ", value: false),
        booleanParam(name: "FOLLOWER_READ", value: true),
    ]].combinations().inject([], append)


    def c = 2
    def ok = true
    def tasks = [:]
    for (k = 0; k < c; k++) {
        def sub = plist.withIndex().findAll { it[1] % c == k }.collect { it[0] }
        tasks["Group $k"] =  {
            sub.each {
                echo("# $it")
                try {
                    it.add(string(name: "TITLE", value: params.TITLE))
                    it.add(string(name: "TARBALL_URL", value: params.TARBALL_URL))
                    it.add(string(name: "IMAGE", value: params.IMAGE))
                    it.add(booleanParam(name: "REPORT", value: params.REPORT))
                    build(job: "jepsen-test", parameters: it)
                } catch (e) {
                    echo("Error: $e")
                    ok = false
                }
            }
        }
    }

    stage('Test') { parallel(tasks) }

    stage('Check') { assert ok }

}
