Juniper-NETCONF provider: Extend UTs; fix warnings

New UTs based on NETCONF responses lab devices.
No functional changes here; it is refactoring only.

Change-Id: I6a011fce9496285539c7a11deb8fbac930b12483
diff --git a/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/ControllerConfigJuniperImpl.java b/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/ControllerConfigJuniperImpl.java
index 536c1bc..fde4b1d 100644
--- a/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/ControllerConfigJuniperImpl.java
+++ b/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/ControllerConfigJuniperImpl.java
@@ -79,7 +79,7 @@
         }
     }
 
-    private String buildRpcGetOpenFlowController() {
+    private static String buildRpcGetOpenFlowController() {
         StringBuilder rpc = new StringBuilder(RPC_TAG_NETCONF_BASE);
 
         rpc.append("<get-configuration>");
@@ -102,7 +102,7 @@
         return rpc.toString();
     }
 
-    private String buildRpcSetOpenFlowController(List<ControllerInfo> controllers) {
+    private static String buildRpcSetOpenFlowController(List<ControllerInfo> controllers) {
         StringBuilder request = new StringBuilder();
 
         request.append("<protocols>");
@@ -115,15 +115,15 @@
         request.append("<ofagent-mode>");
 
         request.append("<controller>");
-        for (int i = 0; i < controllers.size(); i++) {
+        for (ControllerInfo controller : controllers) {
             request.append("<ip>");
             request.append("<name>");
-            request.append(controllers.get(i).ip().toString());
+            request.append(controller.ip().toString());
             request.append("</name>");
             request.append("<protocol>");
             request.append("<tcp>");
             request.append("<port>");
-            request.append(Integer.toString(controllers.get(i).port()));
+            request.append(controller.port());
             request.append("</port>");
             request.append("</tcp>");
             request.append("</protocol>");
@@ -138,7 +138,7 @@
         return cliSetRequestBuilder(request);
     }
 
-    private String buildRpcRemoveOpenFlowController() {
+    private static String buildRpcRemoveOpenFlowController() {
         StringBuilder request = new StringBuilder();
 
         request.append("<protocols>");
@@ -154,7 +154,7 @@
         return cliDeleteRequestBuilder(request);
     }
 
-    private String buildCommit() {
+    private static String buildCommit() {
         StringBuilder rpc = new StringBuilder(RPC_TAG_NETCONF_BASE);
 
         rpc.append("<commit/>");
@@ -164,7 +164,7 @@
         return rpc.toString();
     }
 
-    private String buildDiscardChanges() {
+    private static String buildDiscardChanges() {
         StringBuilder rpc = new StringBuilder(RPC_TAG_NETCONF_BASE);
 
         rpc.append("<discard-changes/>");
@@ -226,7 +226,7 @@
             }
 
             reply = session.requestSync(buildCommit()).trim();
-            log.debug(reply);
+            log.debug("reply : {}", reply);
         } catch (NetconfException e) {
             log.debug(e.getMessage());
             return false;
@@ -235,10 +235,7 @@
         return true;
     }
 
-    private boolean isOK(String reply) {
-        if (reply != null && reply.indexOf("<ok/>") >= 0) {
-            return true;
-        }
-        return false;
+    private static boolean isOK(String reply) {
+        return reply != null && reply.contains("<ok/>");
     }
 }
\ No newline at end of file
diff --git a/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/FlowRuleJuniperImpl.java b/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/FlowRuleJuniperImpl.java
index 3f4adb6..075d3dc 100644
--- a/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/FlowRuleJuniperImpl.java
+++ b/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/FlowRuleJuniperImpl.java
@@ -81,7 +81,6 @@
         implements FlowRuleProgrammable {
 
     private static final String OK = "<ok/>";
-    public static final String IP_STRING = "ip";
     private final org.slf4j.Logger log = getLogger(getClass());
 
     @Override
@@ -92,7 +91,7 @@
         NetconfSession session = controller.getDevicesMap().get(devId).getSession();
         if (session == null) {
             log.warn("Device {} is not registered in netconf", devId);
-            return Collections.EMPTY_LIST;
+            return Collections.emptyList();
         }
 
         //Installed static routes
@@ -273,7 +272,7 @@
         //Find if the route refers to a local interface.
         Optional<Port> local = deviceService.getPorts(devId).stream().filter(this::isIp)
                 .filter(p -> criteria.ip().getIp4Prefix().contains(
-                        Ip4Address.valueOf(p.annotations().value(IP_STRING)))).findAny();
+                        Ip4Address.valueOf(p.annotations().value(JuniperUtils.AK_IP)))).findAny();
 
         if (local.isPresent()) {
             return Optional.of(new StaticRoute(criteria.ip().getIp4Prefix(),
@@ -310,12 +309,11 @@
      * @return the output instruction
      */
     private Optional<OutputInstruction> getOutput(FlowRule flowRule) {
-        Optional<OutputInstruction> output = flowRule
+        return flowRule
                 .treatment().allInstructions().stream()
                 .filter(instruction -> instruction
                         .type() == Instruction.Type.OUTPUT)
-                .map(x -> (OutputInstruction) x).findFirst();
-        return output;
+                .map(OutputInstruction.class::cast).findFirst();
     }
 
     private String routingTableBuilder() {
@@ -339,10 +337,7 @@
                     e));
         }
 
-        if (replay != null && replay.indexOf(OK) >= 0) {
-            return true;
-        }
-        return false;
+        return replay != null && replay.contains(OK);
     }
 
     private boolean rollback() {
@@ -359,10 +354,7 @@
                     e));
         }
 
-        if (replay != null && replay.indexOf(OK) >= 0) {
-            return true;
-        }
-        return false;
+        return replay != null && replay.contains(OK);
     }
 
     /**
@@ -381,7 +373,7 @@
         DeviceService deviceService = this.handler().get(DeviceService.class);
         //Using only links with adjacency discovered by the LLDP protocol (see LinkDiscoveryJuniperImpl)
         Map<DeviceId, Port> dstPorts = links.stream().filter(l ->
-                IP_STRING.toUpperCase().equals(l.annotations().value(AnnotationKeys.LAYER)))
+                JuniperUtils.AK_IP.toUpperCase().equals(l.annotations().value(AnnotationKeys.LAYER)))
                 .collect(Collectors.toMap(
                         l -> l.dst().deviceId(),
                         l -> deviceService.getPort(l.dst().deviceId(), l.dst().port())));
@@ -391,10 +383,10 @@
             Optional<Port> childPort = deviceService.getPorts(entry.getKey()).stream()
                     .filter(p -> Strings.nullToEmpty(
                             p.annotations().value(AnnotationKeys.PORT_NAME)).contains(portName.trim()))
-                    .filter(p -> isIp(p))
+                    .filter(this::isIp)
                     .findAny();
             if (childPort.isPresent()) {
-                return Optional.ofNullable(Ip4Address.valueOf(childPort.get().annotations().value("ip")));
+                return Optional.ofNullable(Ip4Address.valueOf(childPort.get().annotations().value(JuniperUtils.AK_IP)));
             }
         }
 
@@ -409,13 +401,12 @@
      * @return true if the IP address is present. Otherwise false.
      */
     private boolean isIp(Port port) {
-        String ip4 = port.annotations().value(IP_STRING);
-        if (StringUtils.isEmpty(ip4)) {
+        final String ipv4 = port.annotations().value(JuniperUtils.AK_IP);
+        if (StringUtils.isEmpty(ipv4)) {
             return false;
         }
         try {
-
-            Ip4Address.valueOf(port.annotations().value(IP_STRING));
+            Ip4Address.valueOf(ipv4);
         } catch (IllegalArgumentException e) {
             return false;
         }
diff --git a/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/JuniperUtils.java b/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/JuniperUtils.java
index 1fc4f6c..77612cb 100644
--- a/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/JuniperUtils.java
+++ b/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/JuniperUtils.java
@@ -19,6 +19,8 @@
 import com.google.common.base.MoreObjects;
 import org.apache.commons.configuration.HierarchicalConfiguration;
 import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
 import org.onlab.packet.ChassisId;
 import org.onlab.packet.Ip4Address;
 import org.onlab.packet.Ip4Prefix;
@@ -120,7 +122,7 @@
             Pattern.compile(".*Private base address\\s*([:,0-9,a-f,A-F]*).*", Pattern.DOTALL);
 
 
-    public static final String PROTOCOL_NAME = "protocol-name";
+    private static final String PROTOCOL_NAME = "protocol-name";
 
     private static final String JUNIPER = "JUNIPER";
     private static final String UNKNOWN = "UNKNOWN";
@@ -136,6 +138,12 @@
     static final String AK_ENCAPSULATION = "encapsulation";
 
     /**
+     * Annotation key for IP.
+     */
+    static final String AK_IP = "ip";
+
+
+    /**
      * Annotation key for interface description.
      */
     static final String AK_DESCRIPTION = "description";
@@ -168,7 +176,7 @@
     /**
      * Default port speed {@value} Mbps.
      */
-    private static final long DEFAULT_PORT_SPEED = 1000;
+    static final long DEFAULT_PORT_SPEED = 1000;
 
 
     private JuniperUtils() {
@@ -226,11 +234,11 @@
         rpc.append("<routing-options>\n");
         rpc.append("<static>\n");
         rpc.append("<route>\n");
-        rpc.append("<destination>" + staticRoute.ipv4Dst().toString() + "</destination>\n");
-        rpc.append("<next-hop>" + staticRoute.nextHop() + "</next-hop>\n");
+        rpc.append("<destination>").append(staticRoute.ipv4Dst().toString()).append("</destination>\n");
+        rpc.append("<next-hop>").append(staticRoute.nextHop()).append("</next-hop>\n");
 
         if (staticRoute.getMetric() != DEFAULT_METRIC_STATIC_ROUTE) {
-            rpc.append("<metric>" + staticRoute.getMetric() + "</metric>");
+            rpc.append("<metric>").append(staticRoute.getMetric()).append("</metric>");
         }
 
         rpc.append("</route>\n");
@@ -419,7 +427,7 @@
 
             // preserving former behavior
             setIfNonNull(lannotations,
-                         "ip",
+                         AK_IP,
                          logIntf.getString("address-family.interface-address.ifa-local"));
 
             setIfNonNull(lannotations,
@@ -445,7 +453,7 @@
      * @param portStatus port status
      * @return "up" if {@code portStats} is {@literal true}, "down" otherwise
      */
-    static String toUpDown(boolean portStatus) {
+    private static String toUpDown(boolean portStatus) {
         return portStatus ? "up" : "down";
     }
 
@@ -458,7 +466,7 @@
      * @param speed in String
      * @return Mbps
      */
-    static long toMbps(String speed) {
+    private static long toMbps(String speed) {
         String s = Strings.nullToEmpty(speed).trim().toLowerCase();
         Matcher matcher = SPEED_PATTERN.matcher(s);
         if (matcher.matches()) {
@@ -485,7 +493,7 @@
      * @param key Annotation key
      * @param value Annotation value (can be {@literal null})
      */
-    static void setIfNonNull(Builder builder, String key, String value) {
+    private static void setIfNonNull(Builder builder, String key, String value) {
         if (value != null) {
             builder.set(key, value.trim());
         }
@@ -499,7 +507,7 @@
      * @param s port number as string
      * @return PortNumber instance or null on error
      */
-    static PortNumber safePortNumber(String s) {
+    private static PortNumber safePortNumber(String s) {
         try {
             return portNumber(s);
         } catch (RuntimeException e) {
@@ -602,14 +610,14 @@
     }
 
     /**
-     * Device representation of the adjacency at the IP Layer.
+     * Device representation of the adjacency at the IP Layer. It is immutable.
      */
     static final class LinkAbstraction {
-        protected String localPortName;
-        protected ChassisId remoteChassisId;
-        protected long remotePortIndex;
-        protected String remotePortId;
-        protected String remotePortDescription;
+        protected final String localPortName;
+        protected final ChassisId remoteChassisId;
+        protected final long remotePortIndex;
+        protected final String remotePortId;
+        protected final String remotePortDescription;
 
         protected LinkAbstraction(String pName, long chassisId, long pIndex, String pPortId, String pDescription) {
             this.localPortName = pName;
@@ -628,6 +636,38 @@
                     .add("remotePortDescription", remotePortDescription)
                     .toString();
         }
+
+        @Override
+        public boolean equals(final Object o) {
+            if (this == o) {
+                return true;
+            }
+
+            if (o == null || getClass() != o.getClass()) {
+                return false;
+            }
+
+            final LinkAbstraction that = (LinkAbstraction) o;
+
+            return new EqualsBuilder()
+                    .append(remotePortIndex, that.remotePortIndex)
+                    .append(localPortName, that.localPortName)
+                    .append(remoteChassisId, that.remoteChassisId)
+                    .append(remotePortId, that.remotePortId)
+                    .append(remotePortDescription, that.remotePortDescription)
+                    .isEquals();
+        }
+
+        @Override
+        public int hashCode() {
+            return new HashCodeBuilder(17, 37)
+                    .append(localPortName)
+                    .append(remoteChassisId)
+                    .append(remotePortIndex)
+                    .append(remotePortId)
+                    .append(remotePortDescription)
+                    .toHashCode();
+        }
     }
 
     enum OperationType {
@@ -737,7 +777,7 @@
     }
 
     public static List<ControllerInfo> getOpenFlowControllersFromConfig(HierarchicalConfiguration cfg) {
-        List<ControllerInfo> controllers = new ArrayList<ControllerInfo>();
+        List<ControllerInfo> controllers = new ArrayList<>();
         String ipKey = "configuration.protocols.openflow.mode.ofagent-mode.controller.ip";
 
         if (!cfg.configurationsAt(ipKey).isEmpty()) {
diff --git a/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/LinkDiscoveryJuniperImpl.java b/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/LinkDiscoveryJuniperImpl.java
index bdb8883..95c02a1 100644
--- a/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/LinkDiscoveryJuniperImpl.java
+++ b/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/LinkDiscoveryJuniperImpl.java
@@ -83,13 +83,8 @@
 
             //find source port by local port name
             Optional<Port> localPort = deviceService.getPorts(localDeviceId).stream()
-                    .filter(port -> {
-                        if (linkAbs.localPortName.equals(
-                                port.annotations().value(PORT_NAME))) {
-                            return true;
-                        }
-                        return false;
-                    }).findAny();
+                    .filter(port -> linkAbs.localPortName.equals(
+                            port.annotations().value(PORT_NAME))).findAny();
             if (!localPort.isPresent()) {
                 log.warn("Port name {} does not exist in device {}",
                          linkAbs.localPortName, localDeviceId);
diff --git a/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/package-info.java b/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/package-info.java
index 0831659..63f98cf 100644
--- a/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/package-info.java
+++ b/drivers/juniper/src/main/java/org/onosproject/drivers/juniper/package-info.java
@@ -15,6 +15,6 @@
  */
 
 /**
- * Package for juniper device drivers.
+ * Package for Juniper Networks device drivers.
  */
 package org.onosproject.drivers.juniper;
diff --git a/drivers/juniper/src/test/java/org/onosproject/drivers/juniper/JuniperUtilsTest.java b/drivers/juniper/src/test/java/org/onosproject/drivers/juniper/JuniperUtilsTest.java
index 5898612..78ab43b 100644
--- a/drivers/juniper/src/test/java/org/onosproject/drivers/juniper/JuniperUtilsTest.java
+++ b/drivers/juniper/src/test/java/org/onosproject/drivers/juniper/JuniperUtilsTest.java
@@ -16,25 +16,37 @@
 
 package org.onosproject.drivers.juniper;
 
-
-import static org.hamcrest.Matchers.*;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
-import static org.onosproject.net.Device.Type.ROUTER;
-
+import com.google.common.io.CharStreams;
 import org.apache.commons.configuration.HierarchicalConfiguration;
 import org.junit.Test;
 import org.onlab.packet.ChassisId;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip4Prefix;
 import org.onosproject.drivers.utilities.XmlConfigParser;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.DefaultAnnotations;
 import org.onosproject.net.DeviceId;
+import org.onosproject.net.Port;
+import org.onosproject.net.PortNumber;
 import org.onosproject.net.device.DefaultDeviceDescription;
+import org.onosproject.net.device.DefaultPortDescription;
 import org.onosproject.net.device.DeviceDescription;
+import org.onosproject.net.device.PortDescription;
 
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
 
-import com.google.common.io.CharStreams;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.Matchers.allOf;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.onosproject.net.Device.Type.ROUTER;
 
 public class JuniperUtilsTest {
 
@@ -51,12 +63,11 @@
                 new InputStreamReader(
                         getClass().getResourceAsStream("/Junos_get-chassis-mac-addresses_response_15.1.xml")));
 
-        DeviceDescription actual = JuniperUtils.parseJuniperDescription(deviceId, getSystemInfoResp, chassisText);
         DeviceDescription expected =
                 new DefaultDeviceDescription(URI.create(DEVICE_ID), ROUTER, "JUNIPER", "mx240",
                         "junos 15.1R5.5", "JN11AC665AFC", new ChassisId("8418889983c0"));
 
-        assertEquals(expected, actual);
+        assertEquals(expected, JuniperUtils.parseJuniperDescription(deviceId, getSystemInfoResp, chassisText));
 
     }
 
@@ -70,27 +81,81 @@
                 new InputStreamReader(
                         getClass().getResourceAsStream("/Junos_get-chassis-mac-addresses_response_19.2.xml")));
 
-        DeviceDescription actual = JuniperUtils.parseJuniperDescription(deviceId, getSystemInfoResp, chassisText);
         DeviceDescription expected =
                 new DefaultDeviceDescription(URI.create(DEVICE_ID), ROUTER, "JUNIPER", "acx6360-or",
                         "junos 19.2I-20190228_dev_common.0.2316", "DX004", new ChassisId("f4b52f1f81c0"));
 
-        assertEquals(expected, actual);
+        assertEquals(expected, JuniperUtils.parseJuniperDescription(deviceId, getSystemInfoResp, chassisText));
+
+    }
+
+    @Test
+    public void testLinkAbstractionToString() {
+        final JuniperUtils.LinkAbstraction x = new JuniperUtils.LinkAbstraction("foo", 1, 2, null, null);
+
+        assertThat("Null attributes excluded", x.toString(), allOf(
+                containsString("LinkAbstraction"),
+                containsString("localPortName=foo"),
+                not(containsString("remotePortDescription"))));
+    }
+
+
+    @Test
+    public void testLldpNeighborsInformationParsedFromJunos18() {
+        HierarchicalConfiguration reply = XmlConfigParser.loadXml(
+                getClass().getResourceAsStream("/Junos_get-lldp-neighbors-information_response_18.4.xml"));
+
+        final Set<JuniperUtils.LinkAbstraction> expected = new HashSet<>();
+        expected.add(new JuniperUtils.LinkAbstraction("ge-0/0/1", 0x2c6bf509b0c0L, 527L, null, null));
+        expected.add(new JuniperUtils.LinkAbstraction("ge-0/0/2", 0x2c6bf5bde7c0L, 528L, null, null));
+
+        assertEquals(expected, JuniperUtils.parseJuniperLldp(reply));
 
     }
 
 
     @Test
-    public void testLinkAbstractionToString() throws IOException {
-        final JuniperUtils.LinkAbstraction x = new JuniperUtils.LinkAbstraction("foo", 1, 2, null, null);
-        assertThat("Null attributes excluded", x.toString(), allOf(
-                containsString("LinkAbstraction"),
-                containsString("localPortName=foo"),
-                not(containsString("remotePortDescription"))));
+    public void testStaticRoutesParsedFromJunos18() {
+        HierarchicalConfiguration reply = XmlConfigParser.loadXml(
+                getClass().getResourceAsStream("/Junos_get-route-information_response_18.4.xml"));
 
+        final Collection<StaticRoute> expected = new HashSet<>();
+        expected.add(new StaticRoute(Ip4Prefix.valueOf("0.0.0.0/0"), Ip4Address.valueOf("172.26.138.1"), false, 100));
 
+        assertEquals(expected, JuniperUtils.parseRoutingTable(reply));
     }
 
 
+    @Test
+    public void testInterfacesParsedFromJunos18() {
+        HierarchicalConfiguration reply = XmlConfigParser.loadXml(
+                getClass().getResourceAsStream("/Junos_get-interface-information_response_18.4.xml"));
 
-}
\ No newline at end of file
+        final Collection<PortDescription> expected = new ArrayList<>();
+        expected.add(DefaultPortDescription.builder()
+                .withPortNumber(PortNumber.portNumber(513L)).isRemoved(false)
+                .type(Port.Type.COPPER).portSpeed(JuniperUtils.DEFAULT_PORT_SPEED)
+                .annotations(DefaultAnnotations.builder()
+                        .set(JuniperUtils.AK_OPER_STATUS, "up")
+                        .set(AnnotationKeys.PORT_NAME, "jsrv")
+                        .set(JuniperUtils.AK_IF_TYPE, "Ethernet")
+                        .set(AnnotationKeys.PORT_MAC, "2c:6b:f5:03:ff:c0")
+                        .set(JuniperUtils.AK_ADMIN_STATUS, "up")
+                        .build()).build());
+        expected.add(DefaultPortDescription.builder()
+                .withPortNumber(PortNumber.portNumber(514L))
+                .isRemoved(false).type(Port.Type.COPPER)
+                .portSpeed(JuniperUtils.DEFAULT_PORT_SPEED)
+                .annotations(
+                        DefaultAnnotations.builder()
+                        .set(JuniperUtils.AK_ENCAPSULATION, "unknown")
+                        .set("portName", "jsrv.1")
+                        .set(JuniperUtils.AK_PHYSICAL_PORT_NAME, "jsrv")
+                        .set("inet", "128.0.0.127")
+                        .set("ip", "128.0.0.127")
+                        .build()).build());
+
+        assertEquals(expected, JuniperUtils.parseJuniperPorts(reply));
+    }
+
+}
diff --git a/drivers/juniper/src/test/resources/Junos_get-interface-information_response_18.4.xml b/drivers/juniper/src/test/resources/Junos_get-interface-information_response_18.4.xml
new file mode 100644
index 0000000..581229d
--- /dev/null
+++ b/drivers/juniper/src/test/resources/Junos_get-interface-information_response_18.4.xml
@@ -0,0 +1,86 @@
+<rpc-reply xmlns:junos="http://xml.juniper.net/junos/18.4R1/junos">
+    <interface-information xmlns="http://xml.juniper.net/junos/18.4R1/junos-interface" junos:style="normal">
+        <!-- Other physical-interface entries manually stripped out for brevity -->
+        <physical-interface>
+            <name>jsrv</name>
+            <admin-status junos:format="Enabled">up</admin-status>
+            <oper-status>up</oper-status>
+            <local-index>144</local-index>
+            <snmp-index>513</snmp-index>
+            <if-type>Ethernet</if-type>
+            <link-level-type>Ethernet</link-level-type>
+            <mtu>1514</mtu>
+
+            <if-device-flags>
+                <ifdf-present/>
+                <ifdf-running/>
+            </if-device-flags>
+            <ifd-specific-config-flags>
+                <internal-flags>0x200</internal-flags>
+            </ifd-specific-config-flags>
+            <if-config-flags>
+            </if-config-flags>
+            <link-type>Full-Duplex</link-type>
+            <if-media-flags>
+                <ifmf-none/>
+            </if-media-flags>
+            <current-physical-address junos:format="MAC 2c:6b:f5:03:ff:c0">2c:6b:f5:03:ff:c0</current-physical-address>
+            <hardware-physical-address junos:format="MAC 2c:6b:f5:03:ff:c0">2c:6b:f5:03:ff:c0</hardware-physical-address>
+            <interface-flapped junos:seconds="0">Never</interface-flapped>
+            <traffic-statistics junos:style="brief">
+                <input-packets>0</input-packets>
+                <output-packets>0</output-packets>
+            </traffic-statistics>
+            <logical-interface>
+                <name>jsrv.1</name>
+                <local-index>323</local-index>
+                <snmp-index>514</snmp-index>
+                <if-config-flags>
+                    <iff-up/>
+                    <internal-flags>0x24004000</internal-flags>
+                </if-config-flags>
+                <encapsulation>unknown</encapsulation>
+                <policer-overhead>
+                </policer-overhead>
+                <logical-interface-bandwidth>1Gbps</logical-interface-bandwidth>
+                <irb-domain>
+                    <irb-routing-instance>None</irb-routing-instance>
+                    <irb-bridge>None</irb-bridge>
+                </irb-domain>
+                <traffic-statistics junos:style="brief">
+                    <input-packets>0</input-packets>
+                    <output-packets>0</output-packets>
+                </traffic-statistics>
+                <filter-information>
+                </filter-information>
+                <address-family>
+                    <address-family-name>inet</address-family-name>
+                    <mtu>1514</mtu>
+                    <max-local-cache>75000</max-local-cache>
+                    <new-hold-limit>75000</new-hold-limit>
+                    <intf-curr-cnt>0</intf-curr-cnt>
+                    <intf-unresolved-cnt>0</intf-unresolved-cnt>
+                    <intf-dropcnt>0</intf-dropcnt>
+                    <address-family-flags>
+                        <ifff-is-primary/>
+                    </address-family-flags>
+                    <interface-address>
+                        <ifa-flags>
+                            <ifaf-primary/>
+                            <ifaf-current-default/>
+                            <ifaf-current-preferred/>
+                            <ifaf-current-primary/>
+                        </ifa-flags>
+                        <ifa-destination>128/2</ifa-destination>
+                        <ifa-local>128.0.0.127</ifa-local>
+                        <ifa-broadcast>191.255.255.255</ifa-broadcast>
+                    </interface-address>
+                </address-family>
+            </logical-interface>
+        </physical-interface>
+
+    </interface-information>
+    <cli>
+        <banner></banner>
+    </cli>
+</rpc-reply>
\ No newline at end of file
diff --git a/drivers/juniper/src/test/resources/Junos_get-lldp-neighbors-information_response_18.4.xml b/drivers/juniper/src/test/resources/Junos_get-lldp-neighbors-information_response_18.4.xml
new file mode 100644
index 0000000..50bf6fd
--- /dev/null
+++ b/drivers/juniper/src/test/resources/Junos_get-lldp-neighbors-information_response_18.4.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<rpc-reply xmlns:junos="http://xml.juniper.net/junos/18.4R1/junos">
+    <lldp-neighbors-information junos:style="brief">
+        <lldp-neighbor-information>
+            <lldp-local-port-id>ge-0/0/1</lldp-local-port-id>
+            <lldp-local-parent-interface-name>-</lldp-local-parent-interface-name>
+            <lldp-remote-chassis-id-subtype>Mac address</lldp-remote-chassis-id-subtype>
+            <lldp-remote-chassis-id>2c:6b:f5:09:b0:c0</lldp-remote-chassis-id>
+            <lldp-remote-port-id-subtype>Locally assigned</lldp-remote-port-id-subtype>
+            <lldp-remote-port-id>527</lldp-remote-port-id>
+            <lldp-remote-system-name>access-pe1</lldp-remote-system-name>
+        </lldp-neighbor-information>
+        <lldp-neighbor-information>
+            <lldp-local-port-id>ge-0/0/2</lldp-local-port-id>
+            <lldp-local-parent-interface-name>-</lldp-local-parent-interface-name>
+            <lldp-remote-chassis-id-subtype>Mac address</lldp-remote-chassis-id-subtype>
+            <lldp-remote-chassis-id>2c:6b:f5:bd:e7:c0</lldp-remote-chassis-id>
+            <lldp-remote-port-id-subtype>Locally assigned</lldp-remote-port-id-subtype>
+            <lldp-remote-port-id>528</lldp-remote-port-id>
+            <lldp-remote-system-name>core-p1</lldp-remote-system-name>
+        </lldp-neighbor-information>
+    </lldp-neighbors-information>
+    <cli>
+        <banner></banner>
+    </cli>
+</rpc-reply>
\ No newline at end of file
diff --git a/drivers/juniper/src/test/resources/Junos_get-route-information_response_18.4.xml b/drivers/juniper/src/test/resources/Junos_get-route-information_response_18.4.xml
new file mode 100644
index 0000000..e1e934e
--- /dev/null
+++ b/drivers/juniper/src/test/resources/Junos_get-route-information_response_18.4.xml
@@ -0,0 +1,34 @@
+<rpc-reply xmlns:junos="http://xml.juniper.net/junos/18.4R1/junos">
+    <route-information xmlns="http://xml.juniper.net/junos/18.4R1/junos-routing">
+        <!-- keepalive -->
+        <route-table>
+            <table-name>inet.0</table-name>
+            <destination-count>28</destination-count>
+            <total-route-count>28</total-route-count>
+            <active-route-count>28</active-route-count>
+            <holddown-route-count>0</holddown-route-count>
+            <hidden-route-count>0</hidden-route-count>
+            <rt junos:style="brief">
+                <rt-destination>0.0.0.0/0</rt-destination>
+                <rt-entry>
+                    <active-tag>*</active-tag>
+                    <current-active/>
+                    <last-active/>
+                    <protocol-name>Static</protocol-name>
+                    <preference>5</preference>
+                    <age junos:seconds="7854905">12w6d 21:55:05</age>
+                    <nh>
+                        <selected-next-hop/>
+                        <to>172.26.138.1</to>
+                        <via>fxp0.0</via>
+                    </nh>
+                </rt-entry>
+            </rt>
+            <!-- Other rt entries manually stripped out for brevity -->
+        </route-table>
+        <!-- Other route-table entries manually stripped out for brevity -->
+    </route-information>
+    <cli>
+        <banner></banner>
+    </cli>
+</rpc-reply>