Package org.jenkinsci.plugins.workflow.stm

Source Code of org.jenkinsci.plugins.workflow.stm.STMExecutionTest$ThingPickle

/*
* The MIT License
*
* Copyright (c) 2013-2014, CloudBees, 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.jenkinsci.plugins.workflow.stm;

import org.jenkinsci.plugins.workflow.flow.FlowExecution;
import org.jenkinsci.plugins.workflow.flow.FlowExecutionOwner;
import org.jenkinsci.plugins.workflow.graph.AtomNode;
import org.jenkinsci.plugins.workflow.graph.BlockEndNode;
import org.jenkinsci.plugins.workflow.graph.BlockStartNode;
import org.jenkinsci.plugins.workflow.graph.FlowEndNode;
import org.jenkinsci.plugins.workflow.graph.FlowNode;
import org.jenkinsci.plugins.workflow.graph.FlowStartNode;
import org.jenkinsci.plugins.workflow.support.pickles.SingleTypedPickleFactory;
import org.jenkinsci.plugins.workflow.pickles.Pickle;
import org.jenkinsci.plugins.workflow.support.concurrent.Futures;
import org.jenkinsci.plugins.workflow.test.SemaphoreListener;
import org.jenkinsci.plugins.workflow.test.steps.BlockSemaphoreStep;
import org.jenkinsci.plugins.workflow.test.steps.SemaphoreStep;
import com.google.common.util.concurrent.ListenableFuture;
import hudson.model.Action;
import hudson.model.Queue;
import hudson.util.XStream2;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.ConsoleHandler;
import java.util.logging.Handler;
import java.util.logging.Level;

import static org.junit.Assert.*;

public class STMExecutionTest {

    static {
        STMExecution.LOGGER.setLevel(Level.FINE);
        Handler handler = new ConsoleHandler();
        handler.setLevel(Level.ALL);
        STMExecution.LOGGER.addHandler(handler);
    }

    @Rule public TemporaryFolder tmp = new TemporaryFolder();

    @Test public void basics() throws Exception {
        SemaphoreStep step = new SemaphoreStep();
        final AtomicReference<FlowExecution> exec = new AtomicReference<FlowExecution>();
        exec.set(new STMFlowDefinition(Collections.<State>singletonList(new StepState("run", null, step))).create(new OwnerImpl(exec, tmp), Collections.<Action>emptyList()));
        SemaphoreListener l = new SemaphoreListener();
        exec.get().addListener(l);
        exec.get().start();
        FlowNode n = l.next();
        assertTrue(String.valueOf(n), n instanceof FlowStartNode);
        n = l.next();
        assertTrue(n instanceof BlockStartNode);
        step.success(null);
        n = l.next();
        assertTrue(n instanceof AtomNode);
        // TODO check that it is finished now
        n = l.next();
        assertTrue(n instanceof BlockEndNode);
        // TODO check that it matches the BlockStartNode
        n = l.next();
        assertTrue(n instanceof FlowEndNode);
        // TODO check that it matches the FlowStartNode
        // TODO check that its parent list is the BlockEndNode
        assertTrue(exec.get().isComplete());
    }

    @Test public void blocks() throws Throwable {
        SemaphoreStep step = new SemaphoreStep();
        BlockSemaphoreStep block = new BlockSemaphoreStep();
        final AtomicReference<FlowExecution> exec = new AtomicReference<FlowExecution>();
        exec.set(new STMFlowDefinition(Arrays.<State>asList(new BlockState("block", STMExecution.END, block, "step"), new StepState("step", STMExecution.END, step))).create(new OwnerImpl(exec, tmp), Collections.<Action>emptyList()));
        SemaphoreListener l = new SemaphoreListener();
        exec.get().addListener(l);
        exec.get().start();
        FlowNode n = l.next();
        assertTrue(String.valueOf(n), n instanceof FlowStartNode);
        n = l.next();
        assertTrue(n instanceof BlockStartNode);
        n = l.next();
        assertTrue(n instanceof BlockStartNode);
        block.startBlock();
        step.success(null);
        n = l.next();
        assertTrue(n instanceof AtomNode);
        assertEquals(null, block.waitForBlock());
        block.finishSuccess(null);
        n = l.next();
        assertTrue(n instanceof BlockEndNode);
        n = l.next();
        assertTrue(n instanceof BlockEndNode);
        n = l.next();
        assertTrue(n instanceof FlowEndNode);
        assertTrue(exec.get().isComplete());
    }

    @Ignore("TODO")
    @Test public void contextOverridesAndSerialization() throws Throwable {
        SemaphoreStep step = new SemaphoreStep();
        BlockSemaphoreStep block = new BlockSemaphoreStep();
        final AtomicReference<FlowExecution> exec = new AtomicReference<FlowExecution>();
        exec.set(new STMFlowDefinition(Arrays.<State>asList(new BlockState("block", STMExecution.END, block, "step"), new StepState("step", STMExecution.END, step))).create(new OwnerImpl(exec, tmp), Collections.<Action>emptyList()));
        exec.get().start();
        block.startBlock(new Thing(17));
        Thing t = step.getContext().get(Thing.class);
        assertNotNull(t);
        assertEquals(17, t.number);
        exec.set(reserialize(exec.get()));
        step = reserialize(step);
        block = reserialize(block);
        t = step.getContext().get(Thing.class);
        assertNotNull(t);
        assertEquals(17, t.number);
        step.success(null);
        assertEquals(null, block.waitForBlock());
        block.finishSuccess(null);
    }

    @SuppressWarnings("unchecked")
    private static <T> T reserialize(T object) {
        XStream2 xs = new XStream2();
        String xml = xs.toXML(object);
        System.out.println(xml);
        return (T) xs.fromXML(xml);
    }

    private static class Thing {
        final int number;
        Thing(int number) {
            this.number = number;
        }
        private Object writeReplace() {
            throw new AssertionError("not directly serializable");
        }
    }
    private static class ThingPickle extends Pickle {
        final int number;
        ThingPickle(Thing t) {
            number = t.number;
        }
        @Override public ListenableFuture<Thing> rehydrate() {
            return Futures.immediateFuture(new Thing(number));
        }
    }
    static {
        STMExecution.valueFactories = Collections.singleton(new SingleTypedPickleFactory<Thing>() {
            @Override protected Pickle pickle(Thing thing) {
                return new ThingPickle(thing);
            }
        });
    }

    private static class OwnerImpl extends FlowExecutionOwner {
        private static final List<AtomicReference<FlowExecution>> execs = new ArrayList<AtomicReference<FlowExecution>>();
        private final int which;
        private final File rootDir;
        OwnerImpl(AtomicReference<FlowExecution> exec,TemporaryFolder tmp) {
            which = execs.size();
            execs.add(exec);
            rootDir = tmp.getRoot();
        }
        @Override public FlowExecution get() throws IOException {
            return execs.get(which).get();
        }
        @Override public File getRootDir() throws IOException {
            return rootDir;
        }
        @Override public Queue.Executable getExecutable() throws IOException {
            throw new IOException();
        }
        @Override public PrintStream getConsole() {
            return System.out;
        }
        @Override public String getUrl() {
            return "TODO";
        }

        @Override
        public boolean equals(Object o) {
            return this==o;
        }

        @Override
        public int hashCode() {
            return 0;
        }
    }

}
TOP

Related Classes of org.jenkinsci.plugins.workflow.stm.STMExecutionTest$ThingPickle

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.