Package com.alibaba.citrus.service.pipeline

Source Code of com.alibaba.citrus.service.pipeline.InvokeMultipleTimes

/*
* Copyright (c) 2002-2012 Alibaba Group Holding Limited.
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.alibaba.citrus.service.pipeline;

import static com.alibaba.citrus.test.TestUtil.*;
import static org.junit.Assert.*;

import com.alibaba.citrus.service.pipeline.impl.PipelineImpl;
import com.alibaba.citrus.service.pipeline.valve.LogAndBreakValve;
import com.alibaba.citrus.service.pipeline.valve.LogAndInvokeSubValve;
import com.alibaba.citrus.service.pipeline.valve.LogAndReturnValve;
import com.alibaba.citrus.service.pipeline.valve.LogValve;
import org.junit.Before;
import org.junit.Test;

/**
* 测试pipeline本身的功能,不包括配置。
*
* @author Michael Zhou
*/
public class PipelineTests extends AbstractPipelineTests {
    @Before
    public void init() {
        pipeline = createPipeline();
    }

    @Test
    public void pipeline_getLabel() throws Exception {
        // init is null
        assertNull(pipeline.getLabel());

        // set empty label
        pipeline.setLabel(null);
        assertNull(pipeline.getLabel());

        pipeline.setLabel(" ");
        assertNull(pipeline.getLabel());

        // set value
        pipeline.setLabel(" testLabel");
        assertEquals("testLabel", pipeline.getLabel());
    }

    @Test
    public void pipeline_getValves() throws Exception {
        // init value
        assertArrayEquals(new Valve[0], pipeline.getValves());

        // set null
        pipeline = createPipeline((Valve[]) null);
        assertArrayEquals(new Valve[0], pipeline.getValves());
    }

    @Test
    public void pipeline_newInvocation() throws Exception {
        pipeline = createPipeline(new LogValve(), new LogValve(), new LogValve());

        try {
            pipeline.newInvocation(null);
            fail();
        } catch (IllegalArgumentException e) {
            assertThat(e, exception("no parent PipelineContext"));
        }
    }

    @Test
    public void pipeline_toString() {
        String str;

        // no valves
        assertEquals("Pipeline[]", pipeline.toString());

        // with valves
        pipeline = createPipeline(new LogValve(), new LogValve(), new LogValve());

        str = "";
        str += "Pipeline [\n";
        str += "  [1/3] LogValve\n";
        str += "  [2/3] LogValve\n";
        str += "  [3/3] LogValve\n";
        str += "]";

        assertEquals(str, pipeline.toString());

        pipeline = createPipeline(new LogValve(), new LogAndBreakValve(), new LogValve());

        str = "";
        str += "Pipeline [\n";
        str += "  [1/3] LogValve\n";
        str += "  [2/3] LogAndBreakValve[<null>, 0]\n";
        str += "  [3/3] LogValve\n";
        str += "]";

        assertEquals(str, pipeline.toString());
    }

    @Test
    public void pipeline_init() throws Exception {
        try {
            createPipeline(new LogValve(), null, new LogValve());
            fail();
        } catch (IllegalArgumentException e) {
            assertThat(e, exception("valves[1] == null"));
        }
    }

    @Test
    public void handle_getAttribute() throws Exception {
        pipeline = createPipeline(new LogValve(), new LogAndBreakValve(), new LogValve());
        PipelineInvocationHandle handle = assertInvoke(pipeline, true);

        // init is null
        assertNull(getFieldValue(handle, "attributes", null));

        // getAttribute,不会创建attributes
        assertNull(handle.getAttribute("test"));
        assertNull(getFieldValue(handle, "attributes", null));

        // setAttribute(null),会创建attributes
        handle.setAttribute("test", null);
        assertNotNull(getFieldValue(handle, "attributes", null));
        assertNull(handle.getAttribute("test"));

        // setAttribute(value),自动创建attributes
        handle.setAttribute("test", "value");
        assertNotNull(getFieldValue(handle, "attributes", null));
        assertEquals("value", handle.getAttribute("test"));

        // 再次invoke,context不同
        handle = assertInvoke(pipeline, true);
        assertNull(handle.getAttribute("test"));
    }

    @Test
    public void handle_getAttribute_withParents() throws Exception {
        final PipelineContext[] contexts = new PipelineContext[3];

        final PipelineImpl p3 = createPipeline(new Valve() {
            public void invoke(PipelineContext pipelineContext) throws Exception {
                contexts[2] = pipelineContext;
                pipelineContext.invokeNext();
            }
        });

        final PipelineImpl p2 = createPipeline(new Valve() {
            public void invoke(PipelineContext pipelineContext) throws Exception {
                contexts[1] = pipelineContext;
                p3.newInvocation(pipelineContext).invoke();
                pipelineContext.invokeNext();
            }
        });

        pipeline = createPipeline(new Valve() {
            public void invoke(PipelineContext pipelineContext) throws Exception {
                contexts[0] = pipelineContext;
                p2.newInvocation(pipelineContext).invoke();
                pipelineContext.invokeNext();
            }
        });

        assertInvoke(pipeline, false);

        PipelineContext c1 = contexts[0];
        PipelineContext c2 = contexts[1];
        PipelineContext c3 = contexts[2];

        assertSame(c2, getFieldValue(c3, "parentContext", null));
        assertSame(c1, getFieldValue(c2, "parentContext", null));
        assertSame(null, getFieldValue(c1, "parentContext", null));

        c1.setAttribute("count", 1);
        assertEquals(1, c1.getAttribute("count"));
        assertEquals(1, c2.getAttribute("count"));
        assertEquals(1, c3.getAttribute("count"));

        c2.setAttribute("count", null);
        assertEquals(1, c1.getAttribute("count"));
        assertEquals(null, c2.getAttribute("count"));
        assertEquals(null, c3.getAttribute("count"));

        c3.setAttribute("count", 3);
        assertEquals(1, c1.getAttribute("count"));
        assertEquals(null, c2.getAttribute("count"));
        assertEquals(3, c3.getAttribute("count"));

        c2.setAttribute("count", null);
        assertEquals(1, c1.getAttribute("count"));
        assertEquals(null, c2.getAttribute("count"));
        assertEquals(3, c3.getAttribute("count"));
    }

    @Test
    public void handle_toString() {
        pipeline = createPipeline(new LogValve(), new LogValve(), new LogValve());

        PipelineInvocationHandle handle = pipeline.newInvocation();
        assertEquals("Executing Pipeline Valve[#0/3, level 1]", handle.toString());
    }

    @Test
    public void handle_status() {
        pipeline = createPipeline(new LogValve(), new LogValve(), new LogValve());

        // init status
        PipelineInvocationHandle handle = pipeline.newInvocation();
        assertFalse(handle.isBroken());
        assertFalse(handle.isFinished());

        // finish status
        handle.invoke();
        assertFalse(handle.isBroken());
        assertTrue(handle.isFinished());

        // broken status
        pipeline = createPipeline(new LogValve(), new LogAndBreakValve(), new LogValve());
        handle = pipeline.newInvocation();

        handle.invoke();
        assertTrue(handle.isBroken());
        assertFalse(handle.isFinished());
    }

    @Test
    public void invoke_uninited() {
        try {
            new PipelineImpl().newInvocation().invoke();
            fail();
        } catch (IllegalStateException e) {
            assertThat(e, exception("has not been initialized"));
        }
    }

    @Test
    public void invoke_noValves() throws Exception {
        // invoke
        assertInvoke(pipeline, false);
        assertLog();

        // invoke again
        assertInvoke(pipeline, false);
        assertLog();
    }

    @Test
    public void invoke_simple() throws Exception {
        pipeline = createPipeline(new LogValve(), new LogValve(), new LogValve());

        assertInvoke(pipeline, false);
        assertLog("1-1", "1-2", "1-3");
    }

    @Test
    public void invoke_alreadyInvoked() throws Exception {
        class InvokeMultipleTimes extends LogValve {
            @Override
            public void invoke(PipelineContext pipelineContext) {
                super.invoke(pipelineContext);

                // invoke 2nd times, catched IllegalStateException
                try {
                    pipelineContext.invokeNext();
                    fail();
                } catch (IllegalStateException e) {
                    assertThat(e, exception("Valve[#3/3, level 1] has already been invoked: LogValve"));
                }

                // invoke 3rd times, throws out PipelineException
                pipelineContext.invokeNext();
            }
        }

        pipeline = createPipeline(new LogValve(), new InvokeMultipleTimes(), new LogValve());

        try {
            pipeline.newInvocation().invoke();
            fail();
        } catch (PipelineException e) {
            assertThat(e,
                       exception(IllegalStateException.class, "Valve[#3/3, level 1] has already been invoked: LogValve"));
        }

        assertLog("1-1", "1-2", "1-3");
    }

    @Test
    public void invoke_subPipeline() throws Exception {
        Pipeline p3 = createPipeline(new LogValve(), new LogValve(), new LogValve());
        Pipeline p2 = createPipeline(new LogValve(), new LogAndInvokeSubValve(p3), new LogValve());
        pipeline = createPipeline(new LogValve(), new LogAndInvokeSubValve(p2), new LogValve());

        // invoke
        assertInvoke(pipeline, false);
        assertLog("1-1", "1-2", "2-1", "2-2", "3-1", "3-2", "3-3", "2-3", "1-3");
    }

    @Test
    public void invoke_again() throws Exception {
        pipeline = createPipeline(new LogValve(), new LogValve(), new LogValve());

        PipelineInvocationHandle handle = pipeline.newInvocation();

        handle.invoke();
        handle.invoke(); // again

        assertLog("1-1", "1-2", "1-3", "1-1", "1-2", "1-3");
    }

    @Test
    public void invoke_brokenPipeline() throws Exception {
        pipeline = createPipeline(new LogValve(), new LogAndBreakValve(), new LogValve());

        PipelineInvocationHandle handle = assertInvoke(pipeline, true);

        try {
            handle.invoke();
            fail();
        } catch (IllegalStateException e) {
            assertThat(e, exception("cannot reinvoke a broken pipeline"));
        }
    }

    @Test
    public void invoke_simpleReturn() {
        pipeline = createPipeline(new LogValve(), new LogAndReturnValve(), new LogValve());

        // invoke
        PipelineInvocationHandle handle = pipeline.newInvocation();
        handle.invoke();
        assertFalse(handle.isBroken());
        assertFalse(handle.isFinished());
        assertLog("1-1", "1-2");

        // invoke again
        handle = pipeline.newInvocation();
        handle.invoke();
        assertFalse(handle.isBroken());
        assertFalse(handle.isFinished());
        assertLog("1-1", "1-2");
    }

    @Test
    public void break_simple() throws Exception {
        pipeline = createPipeline(new LogValve(), new LogAndBreakValve(), new LogValve());

        // invoke
        assertInvoke(pipeline, true);
        assertLog("1-1", "1-2");

        // invoke again
        assertInvoke(pipeline, true);
        assertLog("1-1", "1-2");
    }

    @Test
    public void break_levels_outOfBounds() throws Exception {
        PipelineImpl p3 = createPipeline(new LogValve(), new LogValve(), new LogValve());
        PipelineImpl p2 = createPipeline(new LogValve(), new LogAndInvokeSubValve(p3), new LogValve());
        pipeline = createPipeline(new LogValve(), new LogAndInvokeSubValve(p2), new LogValve());

        // break levels=3
        p3.getValves()[1] = new LogAndBreakValve(3);

        try {
            pipeline.newInvocation().invoke();
            fail();
        } catch (PipelineException e) {
            assertThat(
                    e,
                    exception(IllegalArgumentException.class, "Failed to invoke Valve[#2/3, level 3]",
                              "invalid break levels: 3, should be in range of [0, 3)"));
        }

        // break levels=-1
        p3.getValves()[1] = new LogAndBreakValve(-1);

        try {
            pipeline.newInvocation().invoke();
            fail();
        } catch (PipelineException e) {
            assertThat(
                    e,
                    exception(IllegalArgumentException.class, "Failed to invoke Valve[#2/3, level 3]",
                              "invalid break levels: -1, should be in range of [0, 3)"));
        }
    }

    @Test
    public void break_levels() throws Exception {
        PipelineImpl p3 = createPipeline(new LogValve(), new LogValve(), new LogValve());
        PipelineImpl p2 = createPipeline(new LogValve(), new LogAndInvokeSubValve(p3), new LogValve());
        pipeline = createPipeline(new LogValve(), new LogAndInvokeSubValve(p2), new LogValve());

        // break levels=2
        p3.getValves()[1] = new LogAndBreakValve(2);
        assertInvoke(pipeline, true);
        assertLog("1-1", "1-2", "2-1", "2-2", "3-1", "3-2"/* break */);

        // break levels=1
        p3.getValves()[1] = new LogAndBreakValve(1);
        assertInvoke(pipeline, false);
        assertLog("1-1", "1-2", "2-1", "2-2", "3-1", "3-2"/* break */, "1-3");

        // break levels=0
        p3.getValves()[1] = new LogAndBreakValve(0);
        assertInvoke(pipeline, false);
        assertLog("1-1", "1-2", "2-1", "2-2", "3-1", "3-2"/* break */, "2-3", "1-3");
    }

    @Test
    public void break_label_empty() throws Exception {
        pipeline = createPipeline(new LogAndBreakValve("  "));

        try {
            pipeline.newInvocation().invoke();
            fail();
        } catch (PipelineException e) {
            assertThat(e, exception(IllegalArgumentException.class, "no label"));
        }

        pipeline = createPipeline(new LogAndBreakValve(null));

        try {
            pipeline.newInvocation().invoke();
            fail();
        } catch (PipelineException e) {
            assertThat(e, exception(IllegalArgumentException.class, "no label"));
        }
    }

    @Test
    public void break_label_NotFound() throws Exception {
        PipelineImpl p3 = createPipeline(new LogValve(), new LogAndBreakValve(" mylabel "), new LogValve());
        PipelineImpl p2 = createPipeline(new LogValve(), new LogAndInvokeSubValve(p3), new LogValve());
        pipeline = createPipeline(new LogValve(), new LogAndInvokeSubValve(p2), new LogValve());

        pipeline.setLabel("mylabel2");

        // invoke
        try {
            pipeline.newInvocation().invoke();
            fail();
        } catch (LabelNotDefinedException e) {
            assertThat(e, exception("Could not find pipeline or sub-pipeline with label \"mylabel\" "
                                    + "in the pipeline invocation stack"));
        }
    }

    @Test
    public void break_label() throws Exception {
        PipelineImpl p3 = createPipeline(new LogValve(), new LogAndBreakValve(" mylabel "), new LogValve());
        PipelineImpl p2 = createPipeline(new LogValve(), new LogAndInvokeSubValve(p3), new LogValve());
        pipeline = createPipeline(new LogValve(), new LogAndInvokeSubValve(p2), new LogValve());

        // levels = 2
        pipeline.setLabel("mylabel");
        assertInvoke(pipeline, true);
        assertLog("1-1", "1-2", "2-1", "2-2", "3-1", "3-2"/* break */);

        // levels = 1
        p2.setLabel("mylabel");
        assertInvoke(pipeline, false);
        assertLog("1-1", "1-2", "2-1", "2-2", "3-1", "3-2"/* break */, "1-3");

        // levels = 0
        p3.setLabel("mylabel");
        assertInvoke(pipeline, false);
        assertLog("1-1", "1-2", "2-1", "2-2", "3-1", "3-2"/* break */, "2-3", "1-3");
    }

    @Test
    public void break_toTop() throws Exception {
        PipelineImpl p3 = createPipeline(new LogValve(), new LogAndBreakValve(" #TOP "), new LogValve());
        PipelineImpl p2 = createPipeline(new LogValve(), new LogAndInvokeSubValve(p3), new LogValve());
        pipeline = createPipeline(new LogValve(), new LogAndInvokeSubValve(p2), new LogValve());

        // levels = 2
        assertInvoke(pipeline, true);
        assertLog("1-1", "1-2", "2-1", "2-2", "3-1", "3-2"/* break */);
    }
}
TOP

Related Classes of com.alibaba.citrus.service.pipeline.InvokeMultipleTimes

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.