Package javaflow.network.impl

Source Code of javaflow.network.impl.SimpleNetworkBuilderTest$T2

package javaflow.network.impl;

import javaflow.components.*;
import javaflow.components.api.Component;
import javaflow.components.api.OutputPort;
import javaflow.components.api.Packet;
import javaflow.components.metadata.AddMetadata;
import javaflow.components.metadata.MetadataExtractor;
import javaflow.network.api.*;
import javaflow.network.definer.NetworkDefiner;
import javaflow.network.utils.ComponentHandlingTimes;
import javaflow.network.utils.PacketCountInComponent;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;

public class SimpleNetworkBuilderTest {

    List out;
    NetworkBuilder builder;

    @BeforeMethod
    public void setUp() {
        out = new CopyOnWriteArrayList();
        builder = new SimpleNetworkBuilder();
    }

    @Test
    public void simpleGeneratorNetwork() {
        runNetworkDefinition(new NetworkDefiner() {
            {
                component("generator", IntegerGenerator.class);
                component("out", ToCollection.class);

                from("generator").to("out");
                initialize("generator.COUNT", 10);
                initialize("out.COLLECTION", out);
            }
        });
        Assert.assertEquals(out.size(), 10);
    }

    private void runNetworkDefinition(final NetworkDefinition definitionBuilder) {
        Network network = builder.build(definitionBuilder);
        network.runInCurrentThread();
    }

    @Test(timeOut = 1000)
    public void packetListenerIsCalled() {
        Network network = builder.build(new NetworkDefiner() {
            {
                component("generator", IntegerGenerator.class);
                component("out", ToCollection.class);

                from("generator").to("out");

                initialize("generator.COUNT", 10);
                initialize("out.COLLECTION", out);
            }
        });
        ComponentHandlingTimes times = new ComponentHandlingTimes(network.components().size());
        network.addPacketListener(times);
        network.runInCurrentThread();
        Assert.assertEquals(times.getPacketCount(1), 11); // Initialization packet and the other 10

    }

    @Test(timeOut = 1000, description = "Tests that non-looping component is able to run multiple times")
    public void nonLoopingElementInTheMiddle() {
        runNetworkDefinition(new NetworkDefiner() {
            {
                component("generator", IntegerGenerator.class);
                component("copy", Copy.class);
                component("out", ToCollection.class);

                from("generator").to("copy").to("out");

                initialize("generator.COUNT", 10);
                initialize("out.COLLECTION", out);
            }
        });
        Assert.assertEquals(out.size(), 10);

    }

    @Test(timeOut = 10000, description = "Tests that a lots of components can be run when not all of them has to run at the same time")
    public void lotsOfSequentialMooving() {
        final int max = 1000;

        runNetworkDefinition(new NetworkDefiner() {
            {
                component("generator", IntegerGenerator.class);
                component("out", ToCollection.class);

                for (int i = 0; i < max; i++) {
                    component("copy" + i, Copy.class);
                }

                from("generator").to("copy0");

                for (int i = 1; i < max; i++) {
                    from("copy" + (i - 1)).to("copy" + i);
                }

                from("copy" + (max - 1)).to("out");

                initialize("generator.COUNT", 10);
                initialize("out.COLLECTION", out);
            }
        });
        Assert.assertEquals(out.size(), 10);
        for (int i = 0; i < 10; i++) {
            Assert.assertEquals(out.get(i), i);
        }

    }

    @Test(timeOut = 10000, description = "Test that multiple senders work")
    public void multipleSenders() {
        runNetworkDefinition(new NetworkDefiner() {
            {
                component("copy", Copy.class);
                component("out", ToCollection.class);
                int max = 50;
                for (int i = 0; i < max; i++) {
                    final String name = "generator" + i;
                    component(name, IntegerGenerator.class);
                    from(name).to("copy");
                }
                from("copy").to("out");
                initialize("out.COLLECTION", out);
            }
        });
        Assert.assertEquals(out.size(), 500);
    }

    @Test(timeOut = 1000)
    public void onlyOutComponentIsStarted() {
        runNetworkDefinition(new NetworkDefiner() {
            {
                component("generator", StaticTestMessageSender.class);
                component("out", ToCollection.class);

                from("generator").to("out");
                initialize("out.COLLECTION", out);

            }
        });
        Assert.assertEquals(out.size(), 1);
    }

    @Test(timeOut = 1000)
    public void portsInSuperclassAreFilledAlso() {
        runNetworkDefinition(new NetworkDefiner() {
            {
                component("t2", T2.class);
                component("out", ToCollection.class);

                from("t2").to("out");
                initialize("out.COLLECTION", out);

            }
        });
        Assert.assertEquals(out.size(), 1);
    }

    private static abstract class T1 implements Component {

        OutputPort out;
    }

    public static class T2 extends T1 {

        @Override
        public void execute() {
            out.createPacket("OK").send();
        }
    }

    @Test(timeOut = 1000)
    public void testArrayPorts() {

        runNetworkDefinition(new NetworkDefiner() {
            {
                component("generator", IntegerGenerator.class);
                component("splitter", RoundRobinScheduler.class);
                component("aggregator", Aggregator.class);
                component("out", ToCollection.class);

                from("generator").to("splitter");
                from("splitter","OUT[0]").to("IN[0]", "aggregator", "OUT").to("out");
                from("splitter","OUT[1]").to("IN[1]", "aggregator");

                initialize("generator.COUNT", 10);
                initialize("out.COLLECTION", out);
            }
        });

        Assert.assertEquals(out.size(), 10);
        Assert.assertEquals(out, Arrays.asList(0, 2, 4, 6, 8, 1, 3, 5, 7, 9));

    }

    @Test(timeOut = 1000)
    public void testStartAndEndTypes() {
        final Map<String, String> meta1 = new HashMap<>();
        final Map<String, String> meta2 = new HashMap<>();
        meta1.put("a", "1");
        meta2.put("b", "2");
        runNetworkDefinition(new NetworkDefiner() {
            {
                component("generator", IntegerGenerator.class);
                component("metaadder", AddMetadata.class);
                component("extractor", MetadataExtractor.class);
                component("collector", ToCollection.class);

                from("generator").to("metaadder").to("extractor");
                from("extractor", "METAOUT").to("collector");

                initialize("generator.COUNT", 2);
                initialize("collector.COLLECTION", out);
                initialize("metaadder.METAIN", meta1);
                initialize("metaadder.METAIN", meta2);
            }
        });

        Assert.assertEquals(out.size(), 2);
        Assert.assertEquals(((Map) out.get(0)).get("a"), "1");
        Assert.assertNull(((Map) out.get(0)).get("b"));
        Assert.assertEquals(((Map) out.get(1)).get("b"), "2");
        Assert.assertNull(((Map) out.get(1)).get("a"));
    }

    @Test(timeOut = 1000)
    public void testMetadataCanBeHandled() {
        runNetworkDefinition(new NetworkDefiner() {
            {
                component("generator", IntegerGenerator.class);
                component("marker", MarkSubstream.class);
                component("gather", StringsFromSubstreams.class);
                component("collector", ToCollection.class);

                from("generator").to("marker").to("gather").to("collector");

                initialize("generator.COUNT", 10);
                initialize("collector.COLLECTION", out);
            }
        });

        Assert.assertEquals(out.size(), 1);
        Assert.assertEquals(out.get(0), "0123456789");
    }

    @Test(description = "Test that packet can be assembled to single tree structure and drop still works")
    public void assemblingPacketsWorks() {
        runNetworkDefinition(new NetworkDefiner() {
            {
                component("assembler", Assembler.class);
                component("out", LogPacketsToCollection.class);

                from("assembler").to("out");

                initialize("assembler.IN", startPacket("numbers"));
                initialize("assembler.IN", packet("1"));
                initialize("assembler.IN", packet("2"));
                initialize("assembler.IN", endPacket("numbers"));
                initialize("out.COLLECTION", out);
            }
        });

        Assert.assertEquals(out.size(), 1);
        Packet<?> rootPacket = (Packet) out.get(0);
        Assert.assertTrue(rootPacket.isTree());
        Collection<String> strings = new ArrayList<>();
        for (Packet subPacket : rootPacket) {
            strings.add(subPacket.getContent().toString());
        }
        Assert.assertEquals(strings.size(), 2);
        Assert.assertTrue(strings.contains("1"));
        Assert.assertTrue(strings.contains("2"));
    }

    @Test(timeOut = 1000)
    public void assemblingSubTreeWorks() {
        runNetworkDefinition(new NetworkDefiner() {
            {
                component("assembler", Assembler.class);
                component("out", LogPacketsToCollection.class);

                from("assembler").to("out");

                initialize("assembler.IN", startPacket("characters"));
                initialize("assembler.IN", packet("a"));
                initialize("assembler.IN", startPacket("numbers"));
                initialize("assembler.IN", packet("1"));
                initialize("assembler.IN", packet("2"));
                initialize("assembler.IN", endPacket("numbers"));
                initialize("assembler.IN", packet("b"));
                initialize("assembler.IN", endPacket("characters"));
                initialize("out.COLLECTION", out);
            }
        });

        Assert.assertEquals(out.size(), 1);
        Packet<?> rootPacket = (Packet) out.get(0);
        Assert.assertTrue(rootPacket.isTree());
        Collection<String> strings = new ArrayList<>();
        for (Packet subPacket : rootPacket) {
            strings.add(subPacket.getContent().toString());
        }
        Assert.assertEquals(strings.size(), 3);
        Assert.assertTrue(strings.contains("a"));
        Assert.assertTrue(strings.contains("numbers"));
        Assert.assertTrue(strings.contains("b"));
    }

    @Test(timeOut = 1000)
    public void disassemblingWorks() {
        runNetworkDefinition(new NetworkDefiner() {
            {
                component("assembler", Assembler.class);
                component("disassembler", Disassembler.class);
                component("out", ToCollection.class);

                from("assembler").to("disassembler").to("out");

                initialize("assembler.IN", startPacket("characters"));
                initialize("assembler.IN", packet("a"));
                initialize("assembler.IN", startPacket("numbers"));
                initialize("assembler.IN", packet("1"));
                initialize("assembler.IN", packet("2"));
                initialize("assembler.IN", endPacket("numbers"));
                initialize("assembler.IN", packet("b"));
                initialize("assembler.IN", endPacket("characters"));
                initialize("out.COLLECTION", out);
            }
        });

        Assert.assertEquals(out.size(), 8);
        Assert.assertEquals(out.get(0), "characters");
        Assert.assertEquals(out.get(1), "a");
        Assert.assertEquals(out.get(2), "numbers");
        Assert.assertEquals(out.get(3), "1");
        Assert.assertEquals(out.get(4), "2");
        Assert.assertEquals(out.get(5), "numbers");
        Assert.assertEquals(out.get(6), "b");
        Assert.assertEquals(out.get(7), "characters");

    }

    @Test//timeOut = 1000,
            expectedExceptions = Error.class,
            description = "Tests that network detects deadlocks when no component is processing packages")
    public void deadlock() {
        runNetworkDefinition(new NetworkDefiner() {
            {
                component("generator 1", IntegerGenerator.class);
                component("generator 2", IntegerGenerator.class);
                component("ss 1", MarkSubstream.class);
                component("ss 2", MarkSubstream.class);
                component("rr", RoundRobinScheduler.class);
                component("aggregator 1", Aggregator.class);
                component("aggregator 2", Aggregator.class);

                from("generator 1").to("ss 1").to("aggregator 1.IN[0]").to("rr");
                from("generator 2").to("ss 2").to("aggregator 1.IN[1]");

                // This will cause dead lock if queue size is less than 22.
                // Round robin (rr) will try to send 22 packets (20 numbers, 1 start and 1 end)
                // to aggregators _second_ port. Because aggregators tries to empty its
                // IN[0] port first the queue for the IN[1] will be filled and rr will block.
                // Aggregator on the other hand is waiting the input on the IN[0] and thus
                // the packets will never advance.
                from("rr.OUT[1]").to("aggregator 2.IN[0]");
                from("rr.OUT[0]").to("aggregator 2.IN[1]");

                initialize("generator 1.COUNT", 20);
                initialize("generator 2.COUNT", 20);
            }
        });

    }

    @Test(timeOut = 1000,
            description = "Tests that lost packets that are received are detected")
    public void lostPacketsAreDetected1() {
        try {
            runNetworkDefinition(new NetworkDefiner() {
                {
                    component("generator", IntegerGenerator.class);
                    component("eater", JustEatPacketComponent.class);

                    from("generator").to("eater");
                }
            });
            Assert.fail("Should have reported missing packets");

        } catch (Throwable t) {
            Assert.assertTrue(t.getMessage().contains("eater (NOT RUNNING): 10 in component"),
                    "Error message did not report missing packets correctly:\n" + t.getMessage());
        }

    }

    @Test(timeOut = 1000,
            description = "Tests that lost packets that are created inside component are detected")
    public void lostPacketsAreDetected2() {
        try {
            runNetworkDefinition(new NetworkDefiner() {
                {
                    component("generator", CreatePacketsButDontSendThem.class);
                }
            });
            Assert.fail("Should have reported missing packets");

        } catch (Throwable t) {
            Assert.assertTrue(t.getMessage().contains("generator (NOT RUNNING): 10 in component"),
                    "Error message did not report missing packets correctly:\n" + t.getMessage());
        }
    }

    @Test(timeOut = 1000,
            description = "Tests non correct handling of initialization packets are detected")
    public void lostPacketsAreDetected3() {
        try {
            runNetworkDefinition(new NetworkDefiner() {
                {
                    component("eater", JustEatPacketComponent.class);

                    initialize("eater.IN", "eat this");
                }
            });
            Assert.fail("Should have reported missing packets");

        } catch (Throwable t) {
            Assert.assertTrue(t.getMessage().contains("eater (NOT RUNNING): 1 in component"),
                    "Error message did not report missing packets correctly:\n" + t.getMessage());
        }
    }

    @Test(timeOut = 1000,
            description = "Tests closing input port when there is input ")
    public void lostPacketsAreDetected4() {
        runNetworkDefinition(new NetworkDefiner() {
            {
                component("dropper", TestDropAndSendComponent.class);
                component("out", ToCollection.class);

                from("dropper").to("out");

                initialize("dropper.IN", "drop this");
                initialize("out.COLLECTION", out);
            }
        });
        Assert.assertEquals(out.size(), 1);
        Assert.assertEquals(out.get(0), "testing");
    }

    @Test(timeOut = 1000,
            description = "Tests chaining packets does not confuse the counters")
    public void lostPacketsAreDetectedWithChains() {
        Network network = (NetworkImpl) builder.build(new NetworkDefiner() {
            {
                component("generator", IntegerGenerator.class);
                component("substream", MarkSubstream.class);
                component("assembler", Assembler.class);
                component("disassembler", Disassembler.class);
                component("dropper", Drop.class);

                from("generator").to("substream").to("assembler").to("disassembler").to("dropper");
            }
        });
        final PacketCountInComponent listener = new PacketCountInComponent(network.components().size());
        network.addPacketListener(listener);
        network.runInCurrentThread();
        for (NetworkComponent component : network.components()) {
            Assert.assertEquals(listener.getCount(component.componentId()), 0, component.componentName() + " has wrong message count.");
        }
    }

    @Test(//timeOut = 1000,
            description = "Sending to a closed output port is error")
    public void sendingToClosedOuputPort() {
        runNetworkDefinition(new NetworkDefiner() {
            {
                component("non-connected-out", TestSendingThrowsException.class);
                component("out", ToCollection.class);

                from("non-connected-out","RESULT").to("out");

                initialize("non-connected-out.IN", "test message");
                initialize("out.COLLECTION", out);
            }
        });
        Assert.assertEquals(out.size(), 2);
        Assert.assertEquals(out.get(0), "testing");
        Assert.assertEquals(out.get(1), "success");

    }

    @TesttimeOut=1000,
            description = "Tests that isOpen works, also @MustRun annotation is tested because there is no kicker component used.")
    public void isOpenTestAndMustRunWorks() {
        runNetworkDefinition(new NetworkDefiner() {
            {
                component("test output closes", TestOutputPortClosingComponent.class);
                component("close input, signal when ready", ReceiveOneSignalAndCloseInputComponent.class);
                component("out", ToCollection.class);

                from("test output closes").to("close input, signal when ready");
                from("close input, signal when ready","SIGNAL").to("SIGNAL", "test output closes");
                from("test output closes","RESULT").to("out");

                initialize("out.COLLECTION", out);
            }
        });
        Assert.assertEquals(out.size(), 1, "Content was " + out);
        Assert.assertEquals(out.get(0), "SUCCESS", "Content was " + out);

    }
   
    @Test
    public void testComponentIsNotStartedIfNoInputInPorts() {
        runNetworkDefinition(new NetworkDefiner() {
            {
                component("closer", SendOneMessageWaitAndCloseOutput.class);
                component("receiver", ReceiveNonNullPackets.class);
                component("out", ToCollection.class);

                from("closer").to("receiver");
                from("receiver","ERROR").to("out");

                initialize("out.COLLECTION", out);
            }
        });
        Assert.assertEquals(out.size(), 0, "Component was run when it input port was empty!");

    }

    @Test(timeOut=1000)
    public void nonlooperComponentsAllowNetworkToShutdown() {
        runNetworkDefinition(new NetworkDefiner() {
            {
                component("ex", ExtractAndSubstituteSubchain.class);
                component("copy", Copy.class);


                from("ex","EXTRACTED").to("copy").to("SUBSTITUTE","ex","OUT")
                .to(component("drop", Drop.class));
                initialize("ex.IN", "a");
                initialize("ex.CHAINPATH", "a");
            }
        });
        for (Thread t : Thread.getAllStackTraces().keySet()) {
            if ("ex".equals(t.getName())) {
                Assert.fail("Extractor component is not shutdown.");
            }
        }
    }

    @Test
    public void subnetTest() {
        final SubnetDefinition everyOther = new NetworkDefiner(){
            {
                inputPort("IN");
                outputPort("OUT");

                component("roundRobin", RoundRobinScheduler.class);
                component("drop", Drop.class);

                from("IN").to("roundRobin");
                from("roundRobin","OUT[0]").to("OUT");
                from("roundRobin","OUT[1]").to("drop");

            }
        };

        runNetworkDefinition(new NetworkDefiner() {
            {
                component("generator", IntegerGenerator.class);
                component("every other", everyOther);
                component("out", ToCollection.class);

                from("generator").to("every other").to("out");

                initialize("out.COLLECTION", out);
            }
        });
        Assert.assertEquals(out.size(), 5, "Wrong size of output Output was " + out);
        Assert.assertEquals(out.get(0).toString(),"0");
        Assert.assertEquals(out.get(1).toString(),"2");
        Assert.assertEquals(out.get(2).toString(),"4");
        Assert.assertEquals(out.get(3).toString(),"6");
        Assert.assertEquals(out.get(4).toString(),"8");
    }

    @Test
    public void subnetRelaunchTest() {
        final SubnetDefinition uniq = new NetworkDefiner(){
            {
                inputPort("IN", SUBSTREAM_SENSITIVE);
                outputPort("OUT");

                component("unique component", Unique.class);

                from("IN").to("unique component").to("OUT");
            }
        };

        runNetworkDefinition(new NetworkDefiner() {
            {
                component("uniq subnet", uniq);
                component("out", ToCollection.class);

                from("uniq subnet").to("out");

                initialize("out.COLLECTION", out);
                initialize("uniq subnet.IN", startPacket(null));
                initialize("uniq subnet.IN", packet(1));
                initialize("uniq subnet.IN", packet(1));
                initialize("uniq subnet.IN", packet(2));
                initialize("uniq subnet.IN", endPacket(null));
                initialize("uniq subnet.IN", startPacket(null));
                initialize("uniq subnet.IN", packet(1));
                initialize("uniq subnet.IN", packet(2));
                initialize("uniq subnet.IN", endPacket(null));
            }
        });
        Assert.assertEquals(out.size(), 4, "Wrong size of output. Output was " + out);
        Assert.assertEquals(out.get(0),1);
        Assert.assertEquals(out.get(1),2);
        Assert.assertEquals(out.get(2), 1);
        Assert.assertEquals(out.get(3),2);

    }

    @Test
    public void substreamSensitiveOutput() {
        final SubnetDefinition subnet = new NetworkDefiner(){
            {
                inputPort("IN", SUBSTREAM_SENSITIVE);
                outputPort("OUT", SUBSTREAM_SENSITIVE);

                component("pass", PassThrough.class);

                from("IN").to("pass").to("OUT");
            }
        };

        runNetworkDefinition(new NetworkDefiner() {
            {
                component("subnet", subnet);
                component("out", LogPacketsToCollection.class);

                from("subnet").to("out");

                initialize("out.COLLECTION", out);
                initialize("subnet.IN", startPacket(null));
                initialize("subnet.IN", packet(1));
                initialize("subnet.IN", endPacket(null));
                initialize("subnet.IN", startPacket(null));
                initialize("subnet.IN", packet(2));
                initialize("subnet.IN", endPacket(null));
            }
        });
        Assert.assertEquals(out.size(), 6, "Wrong size of output. Output was " + out);
        Assert.assertTrue(((Packet) out.get(0)).isStartPacket());
        Assert.assertEquals(((Packet) out.get(1)).getContent(),1);
        Assert.assertTrue(((Packet) out.get(2)).isEndPacket());
        Assert.assertTrue(((Packet) out.get(3)).isStartPacket());
        Assert.assertEquals(((Packet) out.get(4)).getContent(),2);
        Assert.assertTrue(((Packet) out.get(5)).isEndPacket());

    }

    @Test(description = "There have been problem that actual network does not get started by packet from subnet")
    public void subnetStartsNetwork() {
        final SubnetDefinition subnet = new NetworkDefiner(){
            {
                outputPort("OUT");
                from(c("generator", IntegerGenerator.class)).to("OUT");
            }
        };

        runNetworkDefinition(new NetworkDefiner() {
            {
                component("generator", subnet);
                component("out", ToCollection.class);

                from("generator").to(c("passthrough",PassThrough.class)).to("out");

                initialize("out.COLLECTION", out);
            }
        });
        Assert.assertEquals(out.size(), 10, "Wrong size of output Output was " + out);
    }

    @Test(timeOut = 3000,
            expectedExceptions = Error.class,
            description = "Shutdown network when there is uncatch exception in component")
    public void shutdownOnException() {
        runNetworkDefinition(new NetworkDefiner() {
            {
                component("fail", FailComponent.class);
                component("generator", ForeverGenerator.class);
                component("drop", Drop.class);

                from("generator","OUT").to("IN","drop");

            }
        });
    }

    static final class FailComponent implements Component{

        @Override
        public void execute() {
            throw new Error("I just fail");
        }
    }

    static final class ForeverGenerator implements Component{
        OutputPort out;
        @Override
        public void execute() {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException ignored) {
            }
            while(true) {
                out.createPacket("data").send();
                try {
                    Thread.sleep(1);
                } catch (InterruptedException ignored) {
                }
            }
        }
    }

}
TOP

Related Classes of javaflow.network.impl.SimpleNetworkBuilderTest$T2

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.