From 4dfe5606f1bb250bd97389653358633461fd5b8c Mon Sep 17 00:00:00 2001 From: Timotej Kubas Date: Thu, 12 Feb 2015 15:42:40 +0100 Subject: [PATCH] BUG-2661:Sonar issue - introducing integration test for flow as a preparation for reducing complexity of test-provider Change-Id: Ic87a91697f55dbd461517de4c79ff9fb11bc254a Signed-off-by: Timotej Kubas --- openflowplugin-it/pom.xml | 12 + .../openflow/md/it/OFPaxOptionsAssistant.java | 4 + .../openflow/md/it/OFPluginFlowTest.java | 374 ++++++++++++++++++ .../openflow/md/it/OFPluginToLibraryTest.java | 2 +- .../openflow/md/it/SalIntegrationTest.java | 2 +- .../openflow/md/it/ScenarioFactory.java | 41 +- 6 files changed, 429 insertions(+), 6 deletions(-) create mode 100644 openflowplugin-it/src/test/java/org/opendaylight/openflowplugin/openflow/md/it/OFPluginFlowTest.java diff --git a/openflowplugin-it/pom.xml b/openflowplugin-it/pom.xml index 3e10e906f4..8649615748 100644 --- a/openflowplugin-it/pom.xml +++ b/openflowplugin-it/pom.xml @@ -250,6 +250,18 @@ config-manager test + + org.opendaylight.controller.md + forwardingrules-manager + test + ${mdsal.version} + + + org.opendaylight.controller.md + inventory-manager + test + ${mdsal.version} + commons-codec diff --git a/openflowplugin-it/src/test/java/org/opendaylight/openflowplugin/openflow/md/it/OFPaxOptionsAssistant.java b/openflowplugin-it/src/test/java/org/opendaylight/openflowplugin/openflow/md/it/OFPaxOptionsAssistant.java index ed62919663..0ebcd01167 100644 --- a/openflowplugin-it/src/test/java/org/opendaylight/openflowplugin/openflow/md/it/OFPaxOptionsAssistant.java +++ b/openflowplugin-it/src/test/java/org/opendaylight/openflowplugin/openflow/md/it/OFPaxOptionsAssistant.java @@ -27,6 +27,8 @@ public abstract class OFPaxOptionsAssistant { public static final String DEBUG_PORT = "6000"; /** base controller package */ public static final String CONTROLLER = "org.opendaylight.controller"; + /** base controller.md package */ + public static final String CONTROLLER_MD = "org.opendaylight.controller.md"; /** OFLibrary package */ public static final String OFLIBRARY = "org.opendaylight.openflowjava"; /** OFLibrary package */ @@ -79,6 +81,8 @@ public abstract class OFPaxOptionsAssistant { mavenBundle(OFPLUGIN, "openflowplugin-api").versionAsInProject(), mavenBundle(OFPLUGIN, "openflowplugin-extension-api").versionAsInProject(), mavenBundle(OFPLUGIN, "openflowplugin").versionAsInProject(), + mavenBundle(CONTROLLER_MD, "forwardingrules-manager").versionAsInProject(), + mavenBundle(CONTROLLER_MD, "inventory-manager").versionAsInProject(), mavenBundle("org.openexi", "nagasena").versionAsInProject() ); } diff --git a/openflowplugin-it/src/test/java/org/opendaylight/openflowplugin/openflow/md/it/OFPluginFlowTest.java b/openflowplugin-it/src/test/java/org/opendaylight/openflowplugin/openflow/md/it/OFPluginFlowTest.java new file mode 100644 index 0000000000..4cd426cc98 --- /dev/null +++ b/openflowplugin-it/src/test/java/org/opendaylight/openflowplugin/openflow/md/it/OFPluginFlowTest.java @@ -0,0 +1,374 @@ +/** + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.openflowplugin.openflow.md.it; + +import static org.ops4j.pax.exam.CoreOptions.options; +import static org.ops4j.pax.exam.CoreOptions.systemProperty; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Deque; +import java.util.List; +import java.util.Set; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import javax.inject.Inject; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.DataChangeListener; +import org.opendaylight.controller.md.sal.binding.api.ReadTransaction; +import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction; +import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope; +import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; +import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; +import org.opendaylight.controller.sal.binding.api.NotificationProviderService; +import org.opendaylight.controller.test.sal.binding.it.TestHelper; +import org.opendaylight.openflowjava.protocol.impl.clients.ClientEvent; +import org.opendaylight.openflowjava.protocol.impl.clients.ScenarioHandler; +import org.opendaylight.openflowjava.protocol.impl.clients.SimpleClient; +import org.opendaylight.openflowjava.protocol.impl.clients.SleepEvent; +import org.opendaylight.openflowjava.protocol.impl.clients.WaitForMessageEvent; +import org.opendaylight.openflowjava.util.ByteBufUtils; +import org.opendaylight.openflowplugin.openflow.md.core.ThreadPoolLoggingExecutor; +import org.opendaylight.openflowplugin.openflow.md.core.sal.OpenflowPluginProvider; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DecNwTtlCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtl; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.dec.nw.ttl._case.DecNwTtlBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowCapableNode; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.TableKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowCookie; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.FlowModFlags; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node; +import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetTypeBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match; +import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.ops4j.pax.exam.Configuration; +import org.ops4j.pax.exam.Option; +import org.ops4j.pax.exam.junit.PaxExam; +import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy; +import org.ops4j.pax.exam.spi.reactors.PerClass; +import org.ops4j.pax.exam.util.Filter; +import org.osgi.framework.BundleContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Optional; +import com.google.common.util.concurrent.CheckedFuture; +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; + +/** + * covers basic handshake scenarios + */ +@RunWith(PaxExam.class) +@ExamReactorStrategy(PerClass.class) +public class OFPluginFlowTest { + + static final Logger LOG = LoggerFactory + .getLogger(OFPluginFlowTest.class); + + private static final ArrayBlockingQueue SCENARIO_POOL_QUEUE = new ArrayBlockingQueue<>(1); + + @Inject @Filter(timeout=20000) + OpenflowPluginProvider openflowPluginProvider; + + @Inject + BundleContext ctx; + + @Inject @Filter(timeout=20000) + static DataBroker dataBroker; + + @Inject @Filter(timeout=20000) + NotificationProviderService notificationService; + + private SimpleClient switchSim; + private ThreadPoolLoggingExecutor scenarioPool; + + /** + * test setup + * @throws InterruptedException + */ + @Before + public void setUp() throws InterruptedException { + LOG.debug("openflowPluginProvider: "+openflowPluginProvider); + scenarioPool = new ThreadPoolLoggingExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, SCENARIO_POOL_QUEUE, "scenario"); + //FIXME: plugin should provide service exposing startup result via future + Thread.sleep(5000); + } + + /** + * test tear down + */ + @After + public void tearDown() { + try { + LOG.debug("tearing down simulator"); + switchSim.getScenarioDone().get(getFailSafeTimeout(), TimeUnit.MILLISECONDS); + } catch (Exception e) { + String msg = "waiting for scenario to finish failed: "+e.getMessage(); + LOG.error(msg, e); + Assert.fail(msg); + } finally { + scenarioPool.shutdownNow(); + SCENARIO_POOL_QUEUE.clear(); + } + + try { + LOG.debug("checking if simulator succeeded to connect to controller"); + boolean simulatorWasOnline = switchSim.getIsOnlineFuture().get(100, TimeUnit.MILLISECONDS); + Assert.assertTrue("simulator failed to connect to controller", simulatorWasOnline); + } catch (Exception e) { + String message = "simulator probably failed to connect to controller"; + LOG.error(message, e); + Assert.fail(message); + } + } + + final class TriggerTestListener implements DataChangeListener { + + public TriggerTestListener() { + // NOOP + } + + @Override + public void onDataChanged( + AsyncDataChangeEvent, DataObject> arg0) { + Set> keySet = arg0.getCreatedData().keySet(); + if (keySet.size() == 1) { + for (InstanceIdentifier key : keySet) { + InstanceIdentifier neededKey = + key.firstIdentifierOf(FlowCapableNode.class); + if (neededKey != null) { + LOG.info("Node was added (brm) {}", neededKey); + writeFlow(createTestFlow(), neededKey); + break; + } + } + } + } + } + + /** + * test basic integration with OFLib running the handshake + * @throws Exception + */ + @Test + public void testFlowMod() throws Exception { + LOG.debug("testFlowMod integration test"); + TriggerTestListener brmListener = new TriggerTestListener(); + + dataBroker.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL, + getWildcardPath(), brmListener, DataChangeScope.BASE); + + switchSim = createSimpleClient(); + switchSim.setSecuredClient(false); + Deque handshakeScenario = ScenarioFactory.createHandshakeScenarioVBM( + ScenarioFactory.VERSION_BITMAP_13, (short) 0, ScenarioFactory.VERSION_BITMAP_10_13, false); + handshakeScenario.addFirst(new SleepEvent(3000L)); + ScenarioFactory.appendPostHandshakeScenario(handshakeScenario, true); + WaitForMessageEvent flowModEvent = new WaitForMessageEvent(ByteBufUtils + .hexStringToBytes( + "04 0e 00 58 00 00 00 05 00 00 00 00 00 00 00 0a " + + "00 00 00 00 00 00 00 0a 00 00 00 00 00 00 80 00 " + + "ff ff ff ff ff ff ff ff ff ff ff ff 00 01 00 00 " + + "00 01 00 16 80 00 0a 02 08 00 80 00 19 08 0a 00 " + + "00 01 ff ff ff 00 00 00 00 04 00 10 00 00 00 00 " + + "00 18 00 08 00 00 00 00")); + handshakeScenario.addFirst(flowModEvent); + ScenarioHandler scenario = new ScenarioHandler(handshakeScenario); + switchSim.setScenarioHandler(scenario); + scenarioPool.execute(switchSim); + LOG.info("finishing testFlowMod"); + } + + private static InstanceIdentifier getWildcardPath() { + return InstanceIdentifier.create(Nodes.class).child(Node.class).augmentation(FlowCapableNode.class); + } + + /** + * @return + */ + private static SimpleClient createSimpleClient() { + return new SimpleClient("localhost", 6653); + } + + /** + * @return timeout for case of failure + */ + private static long getFailSafeTimeout() { + return 20000; + } + + + /** + * @return bundle options + */ + @Configuration + public Option[] config() { + LOG.info("configuring..."); + return options( + systemProperty("osgi.console").value("2401"), + systemProperty("osgi.bundles.defaultStartLevel").value("4"), + systemProperty("pax.exam.osgi.unresolved.fail").value("true"), + + OFPaxOptionsAssistant.osgiConsoleBundles(), + OFPaxOptionsAssistant.loggingBudles(), + + TestHelper.junitAndMockitoBundles(), + TestHelper.mdSalCoreBundles(), + TestHelper.configMinumumBundles(), + TestHelper.baseModelBundles(), + TestHelper.flowCapableModelBundles(), + + OFPaxOptionsAssistant.ofPluginBundles()); + } + + static FlowBuilder createTestFlow() { + short tableId = 0; + FlowBuilder flow = new FlowBuilder(); + flow.setMatch(createMatch1().build()); + flow.setInstructions(createDecNwTtlInstructions().build()); + + FlowId flowId = new FlowId("127"); + FlowKey key = new FlowKey(flowId); + if (null == flow.isBarrier()) { + flow.setBarrier(Boolean.FALSE); + } + BigInteger value = BigInteger.TEN; + flow.setCookie(new FlowCookie(value)); + flow.setCookieMask(new FlowCookie(value)); + flow.setHardTimeout(0); + flow.setIdleTimeout(0); + flow.setInstallHw(false); + flow.setStrict(false); + flow.setContainerName(null); + flow.setFlags(new FlowModFlags(false, false, false, false, true)); + flow.setId(flowId); + flow.setTableId(tableId); + + flow.setKey(key); + flow.setFlowName("Foo" + "X" + "f1"); + + return flow; + } + + private static MatchBuilder createMatch1() { + MatchBuilder match = new MatchBuilder(); + Ipv4MatchBuilder ipv4Match = new Ipv4MatchBuilder(); + Ipv4Prefix prefix = new Ipv4Prefix("10.0.0.1/24"); + ipv4Match.setIpv4Destination(prefix); + Ipv4Match i4m = ipv4Match.build(); + match.setLayer3Match(i4m); + + EthernetMatchBuilder eth = new EthernetMatchBuilder(); + EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder(); + ethTypeBuilder.setType(new EtherType(0x0800L)); + eth.setEthernetType(ethTypeBuilder.build()); + match.setEthernetMatch(eth.build()); + return match; + } + + private static InstructionsBuilder createDecNwTtlInstructions() { + DecNwTtlBuilder ta = new DecNwTtlBuilder(); + DecNwTtl decNwTtl = ta.build(); + ActionBuilder ab = new ActionBuilder(); + ab.setAction(new DecNwTtlCaseBuilder().setDecNwTtl(decNwTtl).build()); + ab.setKey(new ActionKey(0)); + // Add our drop action to a list + List actionList = new ArrayList(); + actionList.add(ab.build()); + + // Create an Apply Action + ApplyActionsBuilder aab = new ApplyActionsBuilder(); + aab.setAction(actionList); + + // Wrap our Apply Action in an Instruction + InstructionBuilder ib = new InstructionBuilder(); + ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build()); + ib.setKey(new InstructionKey(0)); + ib.setOrder(0); + + // Put our Instruction in a list of Instructions + InstructionsBuilder isb = new InstructionsBuilder(); + List instructions = new ArrayList(); + instructions.add(ib.build()); + ib.setKey(new InstructionKey(0)); + isb.setInstruction(instructions); + return isb; + } + + static void writeFlow(FlowBuilder flow, InstanceIdentifier flowNodeIdent) { + ReadWriteTransaction modification = dataBroker.newReadWriteTransaction(); + final InstanceIdentifier path1 = flowNodeIdent.child(Table.class, new TableKey(flow.getTableId())) + .child(Flow.class, flow.getKey()); + modification.merge(LogicalDatastoreType.CONFIGURATION, path1, flow.build(), true); + CheckedFuture commitFuture = modification.submit(); + Futures.addCallback(commitFuture, new FutureCallback() { + @Override + public void onSuccess(Void aVoid) { + LOG.debug("Write of flow on device succeeded."); + } + + @Override + public void onFailure(Throwable throwable) { + LOG.error("Write of flow on device failed.", throwable); + } + }); + } + + //TODO move to separate test util class + private final static Flow readFlow(InstanceIdentifier flow) { + Flow searchedFlow = null; + ReadTransaction rt = dataBroker.newReadOnlyTransaction(); + CheckedFuture, ReadFailedException> flowFuture = + rt.read(LogicalDatastoreType.CONFIGURATION, flow); + + try { + Optional maybeFlow = flowFuture.checkedGet(500, TimeUnit.SECONDS); + if(maybeFlow.isPresent()) { + searchedFlow = maybeFlow.get(); + } + } catch (TimeoutException e) { + LOG.error("Future timed out. Getting FLOW from DataStore failed.", e); + } catch (ReadFailedException e) { + LOG.error("Something wrong happened in DataStore. Getting FLOW for userId {} failed.", e); + } + + return searchedFlow; + } +} diff --git a/openflowplugin-it/src/test/java/org/opendaylight/openflowplugin/openflow/md/it/OFPluginToLibraryTest.java b/openflowplugin-it/src/test/java/org/opendaylight/openflowplugin/openflow/md/it/OFPluginToLibraryTest.java index 774cd1ae37..57af591609 100644 --- a/openflowplugin-it/src/test/java/org/opendaylight/openflowplugin/openflow/md/it/OFPluginToLibraryTest.java +++ b/openflowplugin-it/src/test/java/org/opendaylight/openflowplugin/openflow/md/it/OFPluginToLibraryTest.java @@ -110,7 +110,7 @@ public class OFPluginToLibraryTest { switchSim = createSimpleClient(); switchSim.setSecuredClient(false); Deque handshakeScenario = ScenarioFactory.createHandshakeScenarioVBM( - ScenarioFactory.VERSION_BITMAP_13, (short) 0, ScenarioFactory.VERSION_BITMAP_10_13); + ScenarioFactory.VERSION_BITMAP_13, (short) 0, ScenarioFactory.VERSION_BITMAP_10_13, true); ScenarioHandler scenario = new ScenarioHandler(handshakeScenario); switchSim.setScenarioHandler(scenario); diff --git a/openflowplugin-it/src/test/java/org/opendaylight/openflowplugin/openflow/md/it/SalIntegrationTest.java b/openflowplugin-it/src/test/java/org/opendaylight/openflowplugin/openflow/md/it/SalIntegrationTest.java index 9091ca430b..9fdf2087b0 100644 --- a/openflowplugin-it/src/test/java/org/opendaylight/openflowplugin/openflow/md/it/SalIntegrationTest.java +++ b/openflowplugin-it/src/test/java/org/opendaylight/openflowplugin/openflow/md/it/SalIntegrationTest.java @@ -103,7 +103,7 @@ public class SalIntegrationTest { SimpleClient switchSim = new SimpleClient("localhost", 6653); switchSim.setSecuredClient(false); ScenarioHandler scenario = new ScenarioHandler(ScenarioFactory.createHandshakeScenarioVBM( - ScenarioFactory.VERSION_BITMAP_13, (short) 0, ScenarioFactory.VERSION_BITMAP_10_13)); + ScenarioFactory.VERSION_BITMAP_13, (short) 0, ScenarioFactory.VERSION_BITMAP_10_13, true)); switchSim.setScenarioHandler(scenario); switchSim.run(); diff --git a/openflowplugin-it/src/test/java/org/opendaylight/openflowplugin/openflow/md/it/ScenarioFactory.java b/openflowplugin-it/src/test/java/org/opendaylight/openflowplugin/openflow/md/it/ScenarioFactory.java index a0cb314737..a6fe35f9bb 100644 --- a/openflowplugin-it/src/test/java/org/opendaylight/openflowplugin/openflow/md/it/ScenarioFactory.java +++ b/openflowplugin-it/src/test/java/org/opendaylight/openflowplugin/openflow/md/it/ScenarioFactory.java @@ -21,6 +21,8 @@ import org.opendaylight.openflowjava.util.ByteBufUtils; */ public abstract class ScenarioFactory { + /** default sleep time [ms] - at scenario end */ + public static final int DEFAULT_SCENARIO_SLEEP = 2000; /** version bitmap hex-string containing version 1.3 */ public static final String VERSION_BITMAP_13 = "00 01 00 08 00 00 00 10"; /** version bitmap hex-string containing versions: 1.0 + 1.3 */ @@ -37,10 +39,11 @@ public abstract class ScenarioFactory { * @param switchVersionBitmap * @param auxId * @param pluginVersionBitmap + * @param addSleep if true - then add final sleep {@link #DEFAULT_SCENARIO_SLEEP} * @return stack filled with Handshake messages */ public static Deque createHandshakeScenarioVBM( - String switchVersionBitmap, short auxId, String pluginVersionBitmap) { + String switchVersionBitmap, short auxId, String pluginVersionBitmap, boolean addSleep) { Deque stack = new ArrayDeque<>(); stack.addFirst(new SendEvent(ByteBufUtils @@ -56,15 +59,45 @@ public abstract class ScenarioFactory { + "00 01 02 03 04 05 06 07 " + "00 01 02 03 01 " + Integer.toHexString(auxId) + " 00 00 00 01 02 03 00 01 02 03"))); - addSleep(stack); + + if (addSleep) { + addSleep(stack); + } + return stack; } - + + /** + * @param stack + * @param addSleep if true - then add final sleep {@link #DEFAULT_SCENARIO_SLEEP} + * @return + */ + public static Deque appendPostHandshakeScenario(Deque stack, boolean addSleep) { + stack.addFirst(new WaitForMessageEvent(ByteBufUtils + .hexStringToBytes("04 12 00 10 00 00 00 01 "+ + "00 0d 00 00 00 00 00 00" ))); + stack.addFirst(new WaitForMessageEvent(ByteBufUtils + .hexStringToBytes("04 12 00 10 00 00 00 02 "+ + "00 08 00 00 00 00 00 00" ))); + stack.addFirst(new WaitForMessageEvent(ByteBufUtils + .hexStringToBytes("04 12 00 10 00 00 00 03 "+ + "00 0b 00 00 00 00 00 00" ))); + stack.addFirst(new WaitForMessageEvent(ByteBufUtils + .hexStringToBytes("04 12 00 10 00 00 00 04 "+ + "00 00 00 00 00 00 00 00" ))); + + if (addSleep) { + addSleep(stack); + } + + return stack; + } + /** * @param stack */ private static void addSleep(Deque stack) { - stack.addFirst(new SleepEvent(2000)); + stack.addFirst(new SleepEvent(DEFAULT_SCENARIO_SLEEP)); } /** -- 2.36.6