Bug 4837 - BMP test tool 25/32825/1
authorMilos Fabian <milfabia@cisco.com>
Mon, 4 Jan 2016 08:45:39 +0000 (09:45 +0100)
committerRobert Varga <nite@hq.sk>
Fri, 15 Jan 2016 13:44:10 +0000 (13:44 +0000)
The bmp-mock is a standalone java application for puropose of
testing BMP monitoring station, in a way of faking BMP-enabled routers
and their peers. It allows to report mock Route Monitoring messages including
simple BGP routes.

Change-Id: Ibed6d239a933f84a5dfeda8ff18bcf6ddf2b8c3e
Signed-off-by: Milos Fabian <milfabia@cisco.com>
14 files changed:
artifacts/pom.xml
bgp/bmp-mock/.project [new file with mode: 0644]
bgp/bmp-mock/pom.xml [new file with mode: 0644]
bgp/bmp-mock/src/main/java/org/opendaylight/protocol/bmp/mock/BmpMock.java [new file with mode: 0644]
bgp/bmp-mock/src/main/java/org/opendaylight/protocol/bmp/mock/BmpMockArguments.java [new file with mode: 0644]
bgp/bmp-mock/src/main/java/org/opendaylight/protocol/bmp/mock/BmpMockDispatcher.java [new file with mode: 0644]
bgp/bmp-mock/src/main/java/org/opendaylight/protocol/bmp/mock/BmpMockSession.java [new file with mode: 0644]
bgp/bmp-mock/src/main/java/org/opendaylight/protocol/bmp/mock/BmpMockUtil.java [new file with mode: 0644]
bgp/bmp-mock/src/test/java/org/opendaylight/protocol/bmp/mock/BmpMockArgumentsTest.java [new file with mode: 0644]
bgp/bmp-mock/src/test/java/org/opendaylight/protocol/bmp/mock/BmpMockDispatcherTest.java [new file with mode: 0644]
bgp/bmp-mock/src/test/java/org/opendaylight/protocol/bmp/mock/BmpMockSessionTest.java [new file with mode: 0644]
bgp/bmp-mock/src/test/java/org/opendaylight/protocol/bmp/mock/BmpMockTest.java [new file with mode: 0644]
bgp/bmp-mock/src/test/java/org/opendaylight/protocol/bmp/mock/BmpMockUtilTest.java [new file with mode: 0644]
bgp/pom.xml

index 03db7f65853a819ad7af1a65f279c3a9cd3941f8..e019affe82f915bc235f19af8f12bfb762a43591 100644 (file)
                 <artifactId>bgp-bmp-impl</artifactId>
                 <version>${project.version}</version>
             </dependency>
+            <dependency>
+                <groupId>${project.groupId}</groupId>
+                <artifactId>bgp-bmp-mock</artifactId>
+                <version>${project.version}</version>
+            </dependency>
             <dependency>
                 <groupId>${project.groupId}</groupId>
                 <artifactId>bgp-openconfig-api</artifactId>
diff --git a/bgp/bmp-mock/.project b/bgp/bmp-mock/.project
new file mode 100644 (file)
index 0000000..685e9ce
--- /dev/null
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>bgp-bmp-mock</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+               <buildCommand>
+                       <name>org.eclipse.m2e.core.maven2Builder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+               <nature>org.eclipse.m2e.core.maven2Nature</nature>
+       </natures>
+</projectDescription>
diff --git a/bgp/bmp-mock/pom.xml b/bgp/bmp-mock/pom.xml
new file mode 100644 (file)
index 0000000..2a2e940
--- /dev/null
@@ -0,0 +1,120 @@
+<?xml version="1.0"?>
+<project
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
+ xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.opendaylight.bgpcep</groupId>
+        <artifactId>bgp-parent</artifactId>
+        <version>0.5.0-SNAPSHOT</version>
+    </parent>
+    <artifactId>bgp-bmp-mock</artifactId>
+    <name>bmp-mock</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.opendaylight.bgpcep</groupId>
+             <artifactId>bgp-bmp-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.bgpcep</groupId>
+            <artifactId>bgp-bmp-spi</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.bgpcep</groupId>
+            <artifactId>bgp-bmp-impl</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.bgpcep</groupId>
+            <artifactId>bgp-parser-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.bgpcep</groupId>
+            <artifactId>bgp-parser-spi</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.bgpcep</groupId>
+            <artifactId>bgp-parser-impl</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.bgpcep</groupId>
+            <artifactId>bgp-concepts</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.mdsal.model</groupId>
+            <artifactId>ietf-inet-types</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.opendaylight.mdsal</groupId>
+            <artifactId>yang-binding</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.netty</groupId>
+            <artifactId>netty-transport</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>net.sourceforge.argparse4j</groupId>
+            <artifactId>argparse4j</artifactId>
+            <version>0.7.0</version>
+        </dependency>
+        <!-- test-scope dependencies -->
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-jar-plugin</artifactId>
+                <configuration>
+                    <archive>
+                        <manifest>
+                            <mainClass>org.opendaylight.protocol.bmp.mock.BmpMock</mainClass>
+                        </manifest>
+                    </archive>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-shade-plugin</artifactId>
+                <configuration>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>shade</goal>
+                        </goals>
+                       <configuration>
+                           <transformers>
+                               <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+                               <mainClass>org.opendaylight.protocol.bmp.mock.BmpMock</mainClass>
+                           </transformer>
+                           </transformers>
+                           <shadedArtifactAttached>true</shadedArtifactAttached>
+                           <shadedClassifierName>executable</shadedClassifierName>
+                       </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+ </build>
+</project>
diff --git a/bgp/bmp-mock/src/main/java/org/opendaylight/protocol/bmp/mock/BmpMock.java b/bgp/bmp-mock/src/main/java/org/opendaylight/protocol/bmp/mock/BmpMock.java
new file mode 100644 (file)
index 0000000..a1bb519
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2016 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.protocol.bmp.mock;
+
+import ch.qos.logback.classic.LoggerContext;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import com.google.common.net.InetAddresses;
+import io.netty.channel.Channel;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import org.opendaylight.protocol.bgp.parser.spi.pojo.ServiceLoaderBGPExtensionProviderContext;
+import org.opendaylight.protocol.bmp.api.BmpSession;
+import org.opendaylight.protocol.bmp.api.BmpSessionFactory;
+import org.opendaylight.protocol.bmp.api.BmpSessionListenerFactory;
+import org.opendaylight.protocol.bmp.impl.BmpActivator;
+import org.opendaylight.protocol.bmp.spi.registry.BmpExtensionProviderActivator;
+import org.opendaylight.protocol.bmp.spi.registry.BmpExtensionProviderContext;
+import org.opendaylight.protocol.bmp.spi.registry.SimpleBmpExtensionProviderContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class BmpMock {
+
+    private static final Logger LOG = LoggerFactory.getLogger(BmpMock.class);
+
+    public static void main(final String[] args) {
+        LOG.info("Starting BMP test tool.");
+        final BmpMockArguments arguments = BmpMockArguments.parseArguments(args);
+        initiateLogger(arguments);
+        final BmpMockDispatcher dispatcher = initiateMock(arguments);
+        deployClients(dispatcher, arguments);
+
+    }
+
+    private static void initiateLogger(final BmpMockArguments arguments) {
+        getRootLogger((LoggerContext) LoggerFactory.getILoggerFactory()).setLevel(arguments.getLogLevel());
+    }
+
+    private static BmpMockDispatcher initiateMock(final BmpMockArguments arguments) {
+        final BmpExtensionProviderContext ctx = new SimpleBmpExtensionProviderContext();
+        final BmpExtensionProviderActivator bmpActivator = new BmpActivator(
+                ServiceLoaderBGPExtensionProviderContext.getSingletonInstance());
+        bmpActivator.start(ctx);
+
+        return new BmpMockDispatcher(ctx.getBmpMessageRegistry(),
+                new BmpSessionFactory() {
+                    @Override
+                    public BmpSession getSession(final Channel channel,
+                            final BmpSessionListenerFactory sessionListenerFactory) {
+                        return new BmpMockSession(arguments.getPeersCount(), arguments.getPrePolicyRoutesCount(), arguments.getPostPolicyRoutesCount());
+                    }
+                });
+    }
+
+    private static void deployClients(final BmpMockDispatcher dispatcher, final BmpMockArguments arguments) {
+        final InetSocketAddress localAddress = arguments.getLocalAddress();
+        final InetSocketAddress remoteAddress = arguments.getRemoteAddress();
+        InetAddress currentLocal = localAddress.getAddress();
+        final int port = localAddress.getPort();
+        for (int i = 0; i < arguments.getRoutersCount(); i++) {
+            dispatcher.createClient(new InetSocketAddress(currentLocal, port), remoteAddress);
+            currentLocal = InetAddresses.increment(currentLocal);
+        }
+    }
+
+    private static ch.qos.logback.classic.Logger getRootLogger(final LoggerContext lc) {
+        return Iterables.find(lc.getLoggerList(), new Predicate<Logger>() {
+            @Override
+            public boolean apply(final Logger input) {
+                return (input != null) ? input.getName().equals(Logger.ROOT_LOGGER_NAME) : false;
+            }
+        });
+    }
+}
diff --git a/bgp/bmp-mock/src/main/java/org/opendaylight/protocol/bmp/mock/BmpMockArguments.java b/bgp/bmp-mock/src/main/java/org/opendaylight/protocol/bmp/mock/BmpMockArguments.java
new file mode 100644 (file)
index 0000000..f7bc76c
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2016 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.protocol.bmp.mock;
+
+import ch.qos.logback.classic.Level;
+import com.google.common.net.HostAndPort;
+import com.google.common.net.InetAddresses;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import net.sourceforge.argparse4j.ArgumentParsers;
+import net.sourceforge.argparse4j.inf.Argument;
+import net.sourceforge.argparse4j.inf.ArgumentParser;
+import net.sourceforge.argparse4j.inf.ArgumentParserException;
+import net.sourceforge.argparse4j.inf.ArgumentType;
+import net.sourceforge.argparse4j.inf.Namespace;
+
+public final class BmpMockArguments {
+
+    private static final int DEFAULT_LOCAL_PORT = 0;
+    private static final int DEFAULT_REMOTE_PORT = 12345;
+    private static final InetAddress LOCALHOST = InetAddresses.forString("127.0.0.1");
+
+    private static final InetSocketAddress REMOTE_ADDRESS = new InetSocketAddress(LOCALHOST, DEFAULT_REMOTE_PORT);
+    private static final InetSocketAddress LOCAL_ADDRESS = new InetSocketAddress(LOCALHOST, DEFAULT_LOCAL_PORT);
+
+    private static final String PROGRAM_NAME = "BGP Monitoring Protocol testing tool.";
+    private static final String ARG_PREFIX = "--";
+    private static final String ROUTERS_COUNT_DST = "routers_count";
+    private static final String PEERS_COUNT_DST = "peers_count";
+    private static final String PRE_POLICY_ROUTES_COUNT_DST = "pre_policy_routes";
+    private static final String POST_POLICY_ROUTES_COUNT_DST = "post_policy_routes";
+    private static final String LOCAL_ADDRESS_DST = "local_address";
+    private static final String REMOTE_ADDRESS_DST = "remote_address";
+    private static final String LOG_LEVEL_DST = "log_level";
+
+    private static final ArgumentParser ARGUMENT_PARSER = initializeArgumentParser();
+
+    private final Namespace parseArgs;
+
+    private BmpMockArguments(final Namespace parseArgs) {
+        this.parseArgs = parseArgs;
+    }
+
+    public static BmpMockArguments parseArguments(final String[] args) {
+        try {
+            final Namespace namespace = ARGUMENT_PARSER.parseArgs(args);
+            return new BmpMockArguments(namespace);
+        } catch (final ArgumentParserException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    public int getRoutersCount() {
+        return this.parseArgs.getInt(ROUTERS_COUNT_DST);
+    }
+
+    public int getPeersCount() {
+        return this.parseArgs.getInt(PEERS_COUNT_DST);
+    }
+
+    public int getPrePolicyRoutesCount() {
+        return this.parseArgs.getInt(PRE_POLICY_ROUTES_COUNT_DST);
+    }
+
+    public int getPostPolicyRoutesCount() {
+        return this.parseArgs.getInt(POST_POLICY_ROUTES_COUNT_DST);
+    }
+
+    public InetSocketAddress getLocalAddress() {
+        return this.parseArgs.get(LOCAL_ADDRESS_DST);
+    }
+
+    public InetSocketAddress getRemoteAddress() {
+        return this.parseArgs.get(REMOTE_ADDRESS_DST);
+    }
+
+    public Level getLogLevel() {
+        return this.parseArgs.get(LOG_LEVEL_DST);
+    }
+
+    private static ArgumentParser initializeArgumentParser() {
+        final ArgumentParser parser = ArgumentParsers.newArgumentParser(PROGRAM_NAME);
+        parser.addArgument(toArgName(ROUTERS_COUNT_DST)).type(Integer.class).setDefault(1);
+        parser.addArgument(toArgName(PEERS_COUNT_DST)).type(Integer.class).setDefault(0);
+        parser.addArgument(toArgName(PRE_POLICY_ROUTES_COUNT_DST)).type(Integer.class).setDefault(0);
+        parser.addArgument(toArgName(POST_POLICY_ROUTES_COUNT_DST)).type(Integer.class).setDefault(0);
+        parser.addArgument(toArgName(LOCAL_ADDRESS_DST)).type(new ArgumentType<InetSocketAddress>() {
+            @Override
+            public InetSocketAddress convert(final ArgumentParser parser, final Argument arg, final String value)
+                    throws ArgumentParserException {
+                return getInetSocketAddress(value, DEFAULT_LOCAL_PORT);
+            }
+        }).setDefault(LOCAL_ADDRESS);
+        parser.addArgument(toArgName(REMOTE_ADDRESS_DST)).type(new ArgumentType<InetSocketAddress>() {
+            @Override
+            public InetSocketAddress convert(final ArgumentParser parser, final Argument arg, final String value)
+                    throws ArgumentParserException {
+                return getInetSocketAddress(value, DEFAULT_LOCAL_PORT);
+            }
+        }).setDefault(REMOTE_ADDRESS);
+        parser.addArgument(toArgName(LOG_LEVEL_DST)).type(new ArgumentType<Level>(){
+            @Override
+            public Level convert(final ArgumentParser parser, final Argument arg, final String value) throws ArgumentParserException {
+                return Level.toLevel(value);
+            }}).setDefault(Level.INFO);
+        return parser;
+    }
+
+    private static InetSocketAddress getInetSocketAddress(final String hostPortString, final int defaultPort) {
+        final HostAndPort hostAndPort = HostAndPort.fromString(hostPortString).withDefaultPort(defaultPort);
+        return new InetSocketAddress(hostAndPort.getHostText(), hostAndPort.getPort());
+    }
+
+    private static String toArgName(final String dst) {
+        return ARG_PREFIX + dst;
+    }
+}
diff --git a/bgp/bmp-mock/src/main/java/org/opendaylight/protocol/bmp/mock/BmpMockDispatcher.java b/bgp/bmp-mock/src/main/java/org/opendaylight/protocol/bmp/mock/BmpMockDispatcher.java
new file mode 100644 (file)
index 0000000..9d60873
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016 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.protocol.bmp.mock;
+
+import com.google.common.base.Preconditions;
+import io.netty.bootstrap.Bootstrap;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelInitializer;
+import io.netty.channel.ChannelOption;
+import io.netty.channel.nio.NioEventLoopGroup;
+import io.netty.channel.socket.nio.NioSocketChannel;
+import java.net.SocketAddress;
+import org.opendaylight.protocol.bmp.api.BmpSessionFactory;
+import org.opendaylight.protocol.bmp.impl.BmpHandlerFactory;
+import org.opendaylight.protocol.bmp.spi.registry.BmpMessageRegistry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class BmpMockDispatcher {
+
+    private static final Logger LOG = LoggerFactory.getLogger(BmpMockDispatcher.class);
+
+    final BmpHandlerFactory hf;
+    private final BmpSessionFactory sessionFactory;
+
+    public BmpMockDispatcher(final BmpMessageRegistry registry, final BmpSessionFactory sessionFactory) {
+        this.sessionFactory = Preconditions.checkNotNull(sessionFactory);
+        Preconditions.checkNotNull(registry);
+        this.hf = new BmpHandlerFactory(registry);
+    }
+
+    public ChannelFuture createClient(final SocketAddress localAddress, final SocketAddress remoteAddress) {
+        final NioEventLoopGroup workergroup = new NioEventLoopGroup();
+        final Bootstrap b = new Bootstrap();
+
+        b.channel(NioSocketChannel.class);
+        b.option(ChannelOption.SO_KEEPALIVE, true);
+        b.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 2000);
+        b.group(workergroup);
+
+        b.handler(new ChannelInitializer<NioSocketChannel>() {
+            @Override
+            protected void initChannel(final NioSocketChannel ch) throws Exception {
+                ch.pipeline().addLast(BmpMockDispatcher.this.sessionFactory.getSession(ch, null));
+                ch.pipeline().addLast(BmpMockDispatcher.this.hf.getEncoders());
+            }
+        });
+        b.localAddress(localAddress);
+        b.remoteAddress(remoteAddress);
+        LOG.debug("BMP client {} <--> {} deployed", localAddress, remoteAddress);
+        return b.connect();
+    }
+}
diff --git a/bgp/bmp-mock/src/main/java/org/opendaylight/protocol/bmp/mock/BmpMockSession.java b/bgp/bmp-mock/src/main/java/org/opendaylight/protocol/bmp/mock/BmpMockSession.java
new file mode 100644 (file)
index 0000000..f0150dc
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2016 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.protocol.bmp.mock;
+
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.ChannelFutureListener;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import org.opendaylight.protocol.bmp.api.BmpSession;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+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.params.xml.ns.yang.bmp.message.rev150512.AdjRibInType;
+import org.opendaylight.yangtools.yang.binding.Notification;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public final class BmpMockSession extends SimpleChannelInboundHandler<Notification> implements BmpSession {
+
+    private static final Logger LOG = LoggerFactory.getLogger(BmpMockSession.class);
+
+    private static final Ipv4Address NEXT_HOP = new Ipv4Address("1.1.1.1");
+    private static final Ipv4Prefix PREFIX = new Ipv4Prefix("1.1.1.1/32");
+    private static final Ipv4Address PEER_ADDRESS = NEXT_HOP;
+
+    private final int peersCount;
+    private final int prePolicyRoutesCount;
+    private final int postPolicyRoutesCount;
+
+    private InetSocketAddress remoteAddress;
+    private Channel channel;
+
+    public BmpMockSession(final int peersCount, final int prePolicyRoutesCount, final int postPolicyRoutesCount) {
+        this.peersCount = peersCount;
+        this.prePolicyRoutesCount = prePolicyRoutesCount;
+        this.postPolicyRoutesCount = postPolicyRoutesCount;
+    }
+
+    @Override
+    public void close() throws InterruptedException {
+        this.channel.close().sync();
+    }
+
+    @Override
+    public InetAddress getRemoteAddress() {
+        return this.remoteAddress.getAddress();
+    }
+
+    @Override
+    protected void channelRead0(final ChannelHandlerContext ctx, final Notification msg) throws Exception {
+        // nothing to read
+    }
+
+    @Override
+    public void channelActive(final ChannelHandlerContext ctx) {
+        this.channel = ctx.channel();
+        this.channel.closeFuture().addListener(new ChannelFutureListener() {
+            @Override
+            public void operationComplete(final ChannelFuture future) throws Exception {
+                LOG.info("BMP session {} final successfully established.", BmpMockSession.this.channel);
+            }
+        });
+        LOG.info("BMP session {} sucesfully established.", this.channel);
+        final InetSocketAddress localAddress = (InetSocketAddress) this.channel.localAddress();
+        this.remoteAddress = (InetSocketAddress) this.channel.remoteAddress();
+        advertizePeers(this.channel, localAddress);
+    }
+
+    private void advertizePeers(final Channel channel, final InetSocketAddress localAddress) {
+        channel.writeAndFlush(BmpMockUtil.createInitiation());
+        Ipv4Address peerAddress = PEER_ADDRESS;
+        for (int i = 0; i < this.peersCount; i++) {
+            channel.writeAndFlush(BmpMockUtil.createPeerUp(peerAddress, localAddress.getAddress()));
+            LOG.debug("BMP router {} advertized peer {}", channel.localAddress(), peerAddress);
+            advertizeRoutes(this.prePolicyRoutesCount, AdjRibInType.PrePolicy, channel, peerAddress);
+            advertizeRoutes(this.postPolicyRoutesCount, AdjRibInType.PostPolicy, channel, peerAddress);
+            peerAddress = BmpMockUtil.incrementIpv4Address(peerAddress);
+        }
+    }
+
+    private static void advertizeRoutes(final int count, final AdjRibInType type, final Channel channel,
+            final Ipv4Address peerAddress) {
+        Ipv4Prefix prefix = PREFIX;
+        for (int i = 0; i < count; i++) {
+            channel.writeAndFlush(BmpMockUtil.createRouteMonitoring(peerAddress, type, prefix));
+            prefix = BmpMockUtil.incrementIpv4Prefix(prefix);
+        }
+    }
+
+}
diff --git a/bgp/bmp-mock/src/main/java/org/opendaylight/protocol/bmp/mock/BmpMockUtil.java b/bgp/bmp-mock/src/main/java/org/opendaylight/protocol/bmp/mock/BmpMockUtil.java
new file mode 100644 (file)
index 0000000..1d2cfad
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2016 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.protocol.bmp.mock;
+
+import com.google.common.net.InetAddresses;
+import java.net.InetAddress;
+import java.util.Collections;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.OpenBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.OpenMessage;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.ProtocolVersion;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.AttributesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.message.NlriBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv4NextHopCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.ipv4.next.hop._case.Ipv4NextHopBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.AdjRibInType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.InitiationMessage;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.InitiationMessageBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.PeerType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.PeerUpNotification;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.PeerUpNotificationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.RouteMonitoringMessage;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.RouteMonitoringMessageBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.description.tlv.DescriptionTlvBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.initiation.TlvsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.name.tlv.NameTlvBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.peer.header.PeerHeader;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.peer.header.PeerHeaderBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.peer.up.ReceivedOpenBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.peer.up.SentOpenBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.route.monitoring.message.Update;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.route.monitoring.message.UpdateBuilder;
+
+public final class BmpMockUtil {
+
+    private static final String SLASH = "/";
+    private static final String DESCRIPTION = "OpenDaylight";
+    private static final String NAME = "BMP mock";
+    private static final int HOLD_TIMER = 180;
+    private static final AsNumber ASN = new AsNumber(65431L);
+    private static final Ipv4Address NEXT_HOP = new Ipv4Address("1.2.3.4");
+    private static final PortNumber PEER_PORT = new PortNumber(179);
+    private static final ProtocolVersion PROTOCOL_VERSION = new ProtocolVersion((short) 4);
+
+    private BmpMockUtil() {
+        throw new UnsupportedOperationException();
+    }
+
+    public static InitiationMessage createInitiation() {
+        final InitiationMessageBuilder msgBuilder = new InitiationMessageBuilder();
+        msgBuilder.setTlvs(
+                new TlvsBuilder()
+                    .setDescriptionTlv(new DescriptionTlvBuilder().setDescription(DESCRIPTION).build())
+                    .setNameTlv(new NameTlvBuilder().setName(NAME).build())
+                    .build());
+        return msgBuilder.build();
+    }
+
+    public static PeerUpNotification createPeerUp(final Ipv4Address peerIp, final InetAddress localAddress) {
+        final PeerUpNotificationBuilder msgBuilder = new PeerUpNotificationBuilder();
+        msgBuilder.setLocalAddress(new IpAddress(new Ipv4Address(localAddress.getHostAddress())));
+        msgBuilder.setLocalPort(PEER_PORT);
+        msgBuilder.setRemotePort(PEER_PORT);
+        msgBuilder.setReceivedOpen(new ReceivedOpenBuilder(createOpen(peerIp)).build());
+        msgBuilder.setSentOpen(new SentOpenBuilder(createOpen(new Ipv4Address(localAddress.getHostAddress()))).build());
+        msgBuilder.setPeerHeader(createPeerHeader(peerIp, AdjRibInType.PrePolicy));
+        return msgBuilder.build();
+    }
+
+    private static OpenMessage createOpen(final Ipv4Address address) {
+        final OpenBuilder msgBuilder = new OpenBuilder();
+        msgBuilder.setBgpIdentifier(address);
+        msgBuilder.setHoldTimer(HOLD_TIMER);
+        msgBuilder.setMyAsNumber(ASN.getValue().intValue());
+        msgBuilder.setVersion(PROTOCOL_VERSION);
+        return msgBuilder.build();
+    }
+
+    private static PeerHeader createPeerHeader(final Ipv4Address bgpId, final AdjRibInType ribType) {
+        return new PeerHeaderBuilder()
+        .setAddress(new IpAddress(bgpId))
+        .setAdjRibInType(AdjRibInType.PrePolicy)
+        .setAs(new AsNumber(ASN))
+        .setBgpId(bgpId)
+        .setIpv4(true)
+        .setType(PeerType.Global)
+        .build();
+    }
+
+    public static RouteMonitoringMessage createRouteMonitoring(final Ipv4Address bgpId, final AdjRibInType ribType, final Ipv4Prefix prefix) {
+        final RouteMonitoringMessageBuilder routeMonitMsgBuilder = new RouteMonitoringMessageBuilder()
+            .setPeerHeader(createPeerHeader(bgpId, ribType))
+            .setUpdate(createUpdate(prefix));
+        return routeMonitMsgBuilder.build();
+    }
+
+    private static Update createUpdate(final Ipv4Prefix prefix) {
+        final UpdateBuilder updateBuilder = new UpdateBuilder()
+            .setAttributes(new AttributesBuilder().setCNextHop(
+                    new Ipv4NextHopCaseBuilder().setIpv4NextHop(new Ipv4NextHopBuilder().setGlobal(NEXT_HOP).build()).build()).build())
+            .setNlri(new NlriBuilder().setNlri(Collections.singletonList(prefix)).build());
+        return updateBuilder.build();
+    }
+
+    private static String incrementIpv4Address(final String ipv4Address) {
+        return InetAddresses.increment(InetAddresses.forString(ipv4Address)).getHostAddress();
+    }
+
+    public static Ipv4Address incrementIpv4Address(final Ipv4Address ipv4Address) {
+        return new Ipv4Address(incrementIpv4Address(ipv4Address.getValue()));
+    }
+
+    public static Ipv4Prefix incrementIpv4Prefix(final Ipv4Prefix ipv4Prefix) {
+        final String prefixStringValue = ipv4Prefix.getValue();
+        final String[] split = prefixStringValue.split(SLASH);
+        return new Ipv4Prefix(incrementIpv4Address(split[0]) + SLASH + split[1]);
+    }
+
+}
diff --git a/bgp/bmp-mock/src/test/java/org/opendaylight/protocol/bmp/mock/BmpMockArgumentsTest.java b/bgp/bmp-mock/src/test/java/org/opendaylight/protocol/bmp/mock/BmpMockArgumentsTest.java
new file mode 100644 (file)
index 0000000..acc7134
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2016 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.protocol.bmp.mock;
+
+import static org.junit.Assert.assertEquals;
+
+import ch.qos.logback.classic.Level;
+import java.net.InetSocketAddress;
+import net.sourceforge.argparse4j.inf.ArgumentParserException;
+import org.junit.Test;
+
+public class BmpMockArgumentsTest {
+
+    @Test
+    public void testDefaultArguments() {
+        final BmpMockArguments arguments = BmpMockArguments.parseArguments(new String[] {});
+        assertEquals(1, arguments.getRoutersCount());
+        assertEquals(0, arguments.getPeersCount());
+        assertEquals(0, arguments.getPrePolicyRoutesCount());
+        assertEquals(0, arguments.getPostPolicyRoutesCount());
+        assertEquals(Level.INFO, arguments.getLogLevel());
+        assertEquals(new InetSocketAddress("127.0.0.1", 0), arguments.getLocalAddress());
+        assertEquals(new InetSocketAddress("127.0.0.1", 12345), arguments.getRemoteAddress());
+    }
+
+    @Test(expected=IllegalArgumentException.class)
+    public void testWrongArgument() {
+        BmpMockArguments.parseArguments(new String[] {"--routers_count", "abcd"});
+    }
+
+    @Test
+    public void testGetRoutersCount() throws ArgumentParserException {
+        final BmpMockArguments arguments = BmpMockArguments.parseArguments(new String[] {"--routers_count", "10"});
+        assertEquals(10, arguments.getRoutersCount());
+    }
+
+    @Test
+    public void testGetPeersCount() {
+        final BmpMockArguments arguments = BmpMockArguments.parseArguments(new String[] {"--peers_count", "5"});
+        assertEquals(5, arguments.getPeersCount());
+    }
+
+    @Test
+    public void testGetPrePolicyRoutesCount() {
+        final BmpMockArguments arguments = BmpMockArguments.parseArguments(new String[] {"--pre_policy_routes", "20"});
+        assertEquals(20, arguments.getPrePolicyRoutesCount());
+    }
+
+    @Test
+    public void testGetPostPolicyRoutesCount() {
+        final BmpMockArguments arguments = BmpMockArguments.parseArguments(new String[] {"--post_policy_routes", "100"});
+        assertEquals(100, arguments.getPostPolicyRoutesCount());
+    }
+
+    @Test
+    public void testGetLocalAddress() {
+        final BmpMockArguments arguments = BmpMockArguments.parseArguments(new String[] {"--local_address", "1.2.3.4"});
+        assertEquals(new InetSocketAddress("1.2.3.4", 0), arguments.getLocalAddress());
+    }
+
+    @Test
+    public void testGetRemoteAddress() {
+        final BmpMockArguments arguments = BmpMockArguments.parseArguments(new String[] {"--remote_address", "4.5.6.7:1025"});
+        assertEquals(new InetSocketAddress("4.5.6.7", 1025), arguments.getRemoteAddress());
+    }
+
+    @Test
+    public void testGetLogLevel() {
+        final BmpMockArguments arguments = BmpMockArguments.parseArguments(new String[] {"--log_level", "TRACE"});
+        assertEquals(Level.TRACE, arguments.getLogLevel());
+    }
+
+}
diff --git a/bgp/bmp-mock/src/test/java/org/opendaylight/protocol/bmp/mock/BmpMockDispatcherTest.java b/bgp/bmp-mock/src/test/java/org/opendaylight/protocol/bmp/mock/BmpMockDispatcherTest.java
new file mode 100644 (file)
index 0000000..5c88113
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2016 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.protocol.bmp.mock;
+
+import com.google.common.base.Optional;
+import com.google.common.net.InetAddresses;
+import io.netty.channel.Channel;
+import io.netty.channel.ChannelFuture;
+import io.netty.channel.nio.NioEventLoopGroup;
+import java.net.InetSocketAddress;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.opendaylight.protocol.bmp.api.BmpSessionFactory;
+import org.opendaylight.protocol.bmp.api.BmpSessionListenerFactory;
+import org.opendaylight.protocol.bmp.impl.BmpDispatcherImpl;
+import org.opendaylight.protocol.bmp.spi.registry.BmpMessageRegistry;
+import org.opendaylight.tcpmd5.api.KeyMapping;
+
+public class BmpMockDispatcherTest {
+
+    private final BmpMessageRegistry registry = Mockito.mock(BmpMessageRegistry.class);
+    private final BmpSessionFactory sessionFactory = Mockito.mock(BmpSessionFactory.class);
+    private final BmpSessionListenerFactory slf = Mockito.mock(BmpSessionListenerFactory.class);
+
+    @Test
+    public void testCreateClient() throws InterruptedException {
+        final BmpMockDispatcher dispatcher = new BmpMockDispatcher(this.registry, this.sessionFactory);
+        final int port = getRandomPort();
+        final BmpDispatcherImpl serverDispatcher = new BmpDispatcherImpl(new NioEventLoopGroup(), new NioEventLoopGroup(),
+                this.registry, this.sessionFactory);
+        serverDispatcher.createServer(new InetSocketAddress(InetAddresses.forString("0.0.0.0"), port), this.slf, Optional.<KeyMapping>absent());
+
+        final ChannelFuture channelFuture = dispatcher.createClient(new InetSocketAddress(InetAddresses.forString("127.0.0.2"), 0),
+                new InetSocketAddress(InetAddresses.forString("127.0.0.3"), port));
+        final Channel channel = channelFuture.sync().channel();
+
+        Assert.assertTrue(channel.isActive());
+        serverDispatcher.close();
+    }
+
+    protected static int getRandomPort() {
+        return (int) (Math.random() * 64000 + 1024);
+    }
+
+}
diff --git a/bgp/bmp-mock/src/test/java/org/opendaylight/protocol/bmp/mock/BmpMockSessionTest.java b/bgp/bmp-mock/src/test/java/org/opendaylight/protocol/bmp/mock/BmpMockSessionTest.java
new file mode 100644 (file)
index 0000000..349aa8a
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2016 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.protocol.bmp.mock;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import com.google.common.collect.Lists;
+import com.google.common.net.InetAddresses;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.ChannelOutboundHandlerAdapter;
+import io.netty.channel.ChannelPromise;
+import io.netty.channel.embedded.EmbeddedChannel;
+import java.net.InetSocketAddress;
+import java.util.List;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.InitiationMessage;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.PeerUp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.RouteMonitoringMessage;
+import org.opendaylight.yangtools.yang.binding.Notification;
+
+public class BmpMockSessionTest {
+
+    private static final InetSocketAddress REMOTE_ADDRESS = new InetSocketAddress(InetAddresses.forString("127.0.0.1"), 0);
+    private static final InetSocketAddress LOCAL_ADDRESS = new InetSocketAddress(InetAddresses.forString("127.0.0.2"), 0);
+
+    private ChannelHandlerContext context;
+    private EmbeddedChannel channel;
+    private BmpMockSession session;
+
+    @Before
+    public void setUp() {
+        this.session = new BmpMockSession(1, 1, 1);
+        this.channel = Mockito.spy(new EmbeddedChannel());
+        Mockito.doReturn(REMOTE_ADDRESS).when(this.channel).remoteAddress();
+        Mockito.doReturn(LOCAL_ADDRESS).when(this.channel).localAddress();
+        this.channel.pipeline().addLast(this.session);
+        this.context = Mockito.mock(ChannelHandlerContext.class);
+        Mockito.doReturn(this.channel).when(this.context).channel();
+    }
+
+    @Test
+    public void testBmpMockSession() throws Exception {
+        final List<Notification> messages = Lists.newArrayList();
+        this.channel.pipeline().addLast(new ChannelOutboundHandlerAdapter() {
+            @Override
+            public void write(final ChannelHandlerContext ctx, final Object msg, final ChannelPromise promise) throws Exception {
+                messages.add((Notification) msg);
+            }
+        });
+        this.session.channelActive(this.context);
+
+        assertEquals(REMOTE_ADDRESS.getAddress(), this.session.getRemoteAddress());
+        assertTrue(messages.get(0) instanceof InitiationMessage);
+        assertTrue(messages.get(1) instanceof PeerUp);
+        assertTrue(messages.get(2) instanceof RouteMonitoringMessage);
+        assertTrue(messages.get(3) instanceof RouteMonitoringMessage);
+
+        this.session.close();
+        assertFalse(this.channel.isWritable());
+    }
+
+}
diff --git a/bgp/bmp-mock/src/test/java/org/opendaylight/protocol/bmp/mock/BmpMockTest.java b/bgp/bmp-mock/src/test/java/org/opendaylight/protocol/bmp/mock/BmpMockTest.java
new file mode 100644 (file)
index 0000000..53b2e88
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2016 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.protocol.bmp.mock;
+
+import com.google.common.base.Optional;
+import io.netty.channel.Channel;
+import io.netty.channel.nio.NioEventLoopGroup;
+import java.net.InetSocketAddress;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.opendaylight.protocol.bgp.parser.spi.pojo.ServiceLoaderBGPExtensionProviderContext;
+import org.opendaylight.protocol.bmp.api.BmpDispatcher;
+import org.opendaylight.protocol.bmp.api.BmpSession;
+import org.opendaylight.protocol.bmp.api.BmpSessionListener;
+import org.opendaylight.protocol.bmp.api.BmpSessionListenerFactory;
+import org.opendaylight.protocol.bmp.impl.BmpActivator;
+import org.opendaylight.protocol.bmp.impl.BmpDispatcherImpl;
+import org.opendaylight.protocol.bmp.impl.session.DefaultBmpSessionFactory;
+import org.opendaylight.protocol.bmp.spi.registry.BmpExtensionProviderActivator;
+import org.opendaylight.protocol.bmp.spi.registry.BmpExtensionProviderContext;
+import org.opendaylight.protocol.bmp.spi.registry.SimpleBmpExtensionProviderContext;
+import org.opendaylight.tcpmd5.api.KeyMapping;
+import org.opendaylight.yangtools.yang.binding.Notification;
+
+public class BmpMockTest {
+
+    private final BmpSessionListener sessionListener = Mockito.mock(BmpSessionListener.class);
+    private int serverPort;
+    private Channel serverChannel;
+    private BmpExtensionProviderActivator bmpActivator;
+    private BmpDispatcher bmpDispatcher;
+
+    @Before
+    public void setUp() {
+        final BmpExtensionProviderContext ctx = new SimpleBmpExtensionProviderContext();
+        this.bmpActivator = new BmpActivator(
+                ServiceLoaderBGPExtensionProviderContext.getSingletonInstance());
+        this.bmpActivator.start(ctx);
+        this.bmpDispatcher = new BmpDispatcherImpl(new NioEventLoopGroup(), new NioEventLoopGroup(), ctx.getBmpMessageRegistry(),
+                new DefaultBmpSessionFactory());
+        final BmpSessionListenerFactory bmpSessionListenerFactory = new BmpSessionListenerFactory() {
+            @Override
+            public BmpSessionListener getSessionListener() {
+                return BmpMockTest.this.sessionListener;
+            }
+        };
+        this.serverPort = BmpMockDispatcherTest.getRandomPort();
+        this.serverChannel = this.bmpDispatcher.createServer(new InetSocketAddress("127.0.0.1", this.serverPort),
+                bmpSessionListenerFactory, Optional.<KeyMapping>absent()).channel();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        this.serverChannel.close().sync();
+        this.bmpActivator.stop();
+        this.bmpDispatcher.close();
+    }
+
+    @Test
+    public void testMain() throws Exception {
+        BmpMock.main(new String[] {"--remote_address", "127.0.0.1:" + serverPort, "--peers_count", "3", "--pre_policy_routes", "3"});
+        Thread.sleep(1000);
+        Mockito.verify(this.sessionListener).onSessionUp(Mockito.any(BmpSession.class));
+        //1 * Initiate message + 3 * PeerUp Notification + 9 * Route Monitoring message
+        Mockito.verify(this.sessionListener, Mockito.times(13)).onMessage(Mockito.any(BmpSession.class), Mockito.any(Notification.class));
+    }
+
+}
diff --git a/bgp/bmp-mock/src/test/java/org/opendaylight/protocol/bmp/mock/BmpMockUtilTest.java b/bgp/bmp-mock/src/test/java/org/opendaylight/protocol/bmp/mock/BmpMockUtilTest.java
new file mode 100644 (file)
index 0000000..a33f343
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2016 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.protocol.bmp.mock;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import com.google.common.net.InetAddresses;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.net.InetAddress;
+import org.junit.Test;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
+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.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv4NextHopCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.AdjRibInType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.InitiationMessage;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.PeerType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.PeerUpNotification;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.RouteMonitoringMessage;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.initiation.Tlvs;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.peer.header.PeerHeader;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev150512.route.monitoring.message.Update;
+
+public class BmpMockUtilTest {
+
+    private static final Ipv4Address PEER_IP = new Ipv4Address("127.0.0.1");
+    private static final InetAddress LOCAL_ADDRESS = InetAddresses.forString("127.0.0.2");
+    private static final Ipv4Prefix PREFIX = new Ipv4Prefix("1.2.3.4/32");
+
+    @Test
+    public void testCreateInitiation() {
+        final InitiationMessage initiation = BmpMockUtil.createInitiation();
+        final Tlvs tlvs = initiation.getTlvs();
+        assertEquals("OpenDaylight", tlvs.getDescriptionTlv().getDescription());
+        assertEquals("BMP mock", tlvs.getNameTlv().getName());
+        assertNull(tlvs.getStringInformation());
+    }
+
+    @Test
+    public void testCreatePeerUp() {
+        final PeerUpNotification peerUp = BmpMockUtil.createPeerUp(PEER_IP, LOCAL_ADDRESS);
+        final PeerHeader peerHeader = peerUp.getPeerHeader();
+        assertEquals(PEER_IP, peerHeader.getAddress().getIpv4Address());
+        assertEquals(65431L, peerHeader.getAs().getValue().longValue());
+        assertEquals(PEER_IP, peerHeader.getBgpId());
+        assertEquals(PeerType.Global, peerHeader.getType());
+        assertNull(peerUp.getInformation());
+        assertEquals(LOCAL_ADDRESS.getHostAddress(), peerUp.getLocalAddress().getIpv4Address().getValue());
+        assertEquals(179, peerUp.getLocalPort().getValue().intValue());
+        assertEquals(179, peerUp.getRemotePort().getValue().intValue());
+        assertNotNull(peerUp.getReceivedOpen());
+        assertNotNull(peerUp.getSentOpen());
+    }
+
+    @Test
+    public void testCreateRouteMonitoringPrePolicy() {
+        final RouteMonitoringMessage routeMonitoring = BmpMockUtil.createRouteMonitoring(PEER_IP, AdjRibInType.PrePolicy, PREFIX);
+        final PeerHeader peerHeader = routeMonitoring.getPeerHeader();
+        assertEquals(PEER_IP, peerHeader.getAddress().getIpv4Address());
+        assertEquals(65431L, peerHeader.getAs().getValue().longValue());
+        assertEquals(PEER_IP, peerHeader.getBgpId());
+        assertEquals(PeerType.Global, peerHeader.getType());
+        assertEquals(AdjRibInType.PrePolicy, peerHeader.getAdjRibInType());
+        final Update update = routeMonitoring.getUpdate();
+        assertEquals(PREFIX, update.getNlri().getNlri().get(0));
+        assertEquals("1.2.3.4", ((Ipv4NextHopCase)update.getAttributes().getCNextHop()).getIpv4NextHop().getGlobal().getValue());
+    }
+
+    @Test
+    public void testCreateRouteMonitoringPostPolicy() {
+        final RouteMonitoringMessage routeMonitoring = BmpMockUtil.createRouteMonitoring(PEER_IP, AdjRibInType.PostPolicy, PREFIX);
+        assertEquals(AdjRibInType.PrePolicy, routeMonitoring.getPeerHeader().getAdjRibInType());
+    }
+
+    @Test
+    public void testIncrementIpv4Address() {
+        final Ipv4Address incremented = BmpMockUtil.incrementIpv4Address(PEER_IP);
+        assertEquals("127.0.0.2", incremented.getValue());
+    }
+
+    @Test
+    public void testIncrementIpv4Prefix() {
+        final Ipv4Prefix incremented = BmpMockUtil.incrementIpv4Prefix(new Ipv4Prefix("1.2.3.4/32"));
+        assertEquals("1.2.3.5/32", incremented.getValue());
+    }
+
+    @Test(expected=UnsupportedOperationException.class)
+    public void testPrivateConstructor() throws Throwable {
+        final Constructor<BmpMockUtil> c = BmpMockUtil.class.getDeclaredConstructor();
+        c.setAccessible(true);
+        try {
+            c.newInstance();
+        } catch (final InvocationTargetException e) {
+            throw e.getCause();
+        }
+    }
+
+}
index dbd78eadfc37067b8394a7a6002e720902390802..9024c95370ac6f99fc352b022d15e24c23c25286 100644 (file)
@@ -49,6 +49,7 @@
         <module>bmp-api</module>
         <module>bmp-spi</module>
         <module>bmp-impl</module>
+        <module>bmp-mock</module>
         <module>controller-config</module>
         <module>openconfig-api</module>
         <module>openconfig-spi</module>