Praseed Balakrishnan

Merge branch 'master' of ssh://gerrit.onlab.us:29418/onos-next

Showing 31 changed files with 2586 additions and 260 deletions
......@@ -45,6 +45,12 @@
<dependency>
<groupId>org.onlab.onos</groupId>
<artifactId>onlab-junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.onlab.onos</groupId>
<artifactId>onos-cli</artifactId>
<version>${project.version}</version>
</dependency>
......
package org.onlab.onos.sdnip;
import java.util.List;
import org.onlab.onos.ApplicationId;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.flow.DefaultTrafficSelector;
......@@ -8,6 +10,7 @@ import org.onlab.onos.net.flow.TrafficSelector;
import org.onlab.onos.net.flow.TrafficTreatment;
import org.onlab.onos.net.intent.IntentService;
import org.onlab.onos.net.intent.PointToPointIntent;
import org.onlab.onos.sdnip.bgp.BgpConstants;
import org.onlab.onos.sdnip.config.BgpPeer;
import org.onlab.onos.sdnip.config.BgpSpeaker;
import org.onlab.onos.sdnip.config.Interface;
......@@ -20,8 +23,6 @@ import org.onlab.packet.IpPrefix;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
/**
* Manages the connectivity requirements between peers.
*/
......@@ -30,37 +31,44 @@ public class PeerConnectivityManager {
private static final Logger log = LoggerFactory.getLogger(
PeerConnectivityManager.class);
// TODO these shouldn't be defined here
private static final short BGP_PORT = 179;
private static final int IPV4_BIT_LENGTH = 32;
private final SdnIpConfigService configInfoService;
private final SdnIpConfigService configService;
private final InterfaceService interfaceService;
private final IntentService intentService;
private final ApplicationId appId;
/**
* Creates a new PeerConnectivityManager.
*
* @param appId the application ID
* @param configService the SDN-IP config service
* @param interfaceService the interface service
* @param intentService the intent service
*/
public PeerConnectivityManager(ApplicationId appId,
SdnIpConfigService configInfoService,
SdnIpConfigService configService,
InterfaceService interfaceService,
IntentService intentService) {
this.appId = appId;
this.configInfoService = configInfoService;
this.configService = configService;
this.interfaceService = interfaceService;
this.intentService = intentService;
}
/**
* Starts the peer connectivity manager.
*/
public void start() {
// TODO are any of these errors?
if (interfaceService.getInterfaces().isEmpty()) {
log.warn("The interface in configuration file is empty. "
+ "Thus, the SDN-IP application can not be started.");
} else if (configInfoService.getBgpPeers().isEmpty()) {
} else if (configService.getBgpPeers().isEmpty()) {
log.warn("The BGP peer in configuration file is empty."
+ "Thus, the SDN-IP application can not be started.");
} else if (configInfoService.getBgpSpeakers() == null) {
} else if (configService.getBgpSpeakers() == null) {
log.error("The BGP speaker in configuration file is empty. "
+ "Thus, the SDN-IP application can not be started.");
......@@ -79,7 +87,7 @@ public class PeerConnectivityManager {
* for paths from all peers to each BGP speaker.
*/
private void setupBgpPaths() {
for (BgpSpeaker bgpSpeaker : configInfoService.getBgpSpeakers()
for (BgpSpeaker bgpSpeaker : configService.getBgpSpeakers()
.values()) {
log.debug("Start to set up BGP paths for BGP speaker: {}",
bgpSpeaker);
......@@ -88,7 +96,7 @@ public class PeerConnectivityManager {
List<InterfaceAddress> interfaceAddresses =
bgpSpeaker.interfaceAddresses();
for (BgpPeer bgpPeer : configInfoService.getBgpPeers().values()) {
for (BgpPeer bgpPeer : configService.getBgpPeers().values()) {
log.debug("Start to set up BGP paths between BGP speaker: {} "
+ "to BGP peer: {}", bgpSpeaker, bgpPeer);
......@@ -121,16 +129,14 @@ public class PeerConnectivityManager {
// install intent for BGP path from BGPd to BGP peer matching
// destination TCP port 179
// TODO: The usage of PacketMatchBuilder will be improved, then we
// only need to new the PacketMatchBuilder once.
// By then, the code here will be improved accordingly.
TrafficSelector selector = DefaultTrafficSelector.builder()
.matchEthType(Ethernet.TYPE_IPV4)
.matchIPProtocol(IPv4.PROTOCOL_TCP)
.matchIPSrc(IpPrefix.valueOf(bgpdAddress.toInt(), IPV4_BIT_LENGTH))
.matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toInt(), IPV4_BIT_LENGTH))
.matchTcpDst(BGP_PORT)
.matchIPSrc(IpPrefix.valueOf(bgpdAddress.toInt(),
IpAddress.MAX_INET_MASK))
.matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toInt(),
IpAddress.MAX_INET_MASK))
.matchTcpDst((short) BgpConstants.BGP_PORT)
.build();
TrafficTreatment treatment = DefaultTrafficTreatment.builder()
......@@ -149,9 +155,11 @@ public class PeerConnectivityManager {
selector = DefaultTrafficSelector.builder()
.matchEthType(Ethernet.TYPE_IPV4)
.matchIPProtocol(IPv4.PROTOCOL_TCP)
.matchIPSrc(IpPrefix.valueOf(bgpdAddress.toInt(), IPV4_BIT_LENGTH))
.matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toInt(), IPV4_BIT_LENGTH))
.matchTcpSrc(BGP_PORT)
.matchIPSrc(IpPrefix.valueOf(bgpdAddress.toInt(),
IpAddress.MAX_INET_MASK))
.matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toInt(),
IpAddress.MAX_INET_MASK))
.matchTcpSrc((short) BgpConstants.BGP_PORT)
.build();
PointToPointIntent intentMatchSrcTcpPort =
......@@ -167,9 +175,11 @@ public class PeerConnectivityManager {
selector = DefaultTrafficSelector.builder()
.matchEthType(Ethernet.TYPE_IPV4)
.matchIPProtocol(IPv4.PROTOCOL_TCP)
.matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toInt(), IPV4_BIT_LENGTH))
.matchIPDst(IpPrefix.valueOf(bgpdAddress.toInt(), IPV4_BIT_LENGTH))
.matchTcpDst(BGP_PORT)
.matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toInt(),
IpAddress.MAX_INET_MASK))
.matchIPDst(IpPrefix.valueOf(bgpdAddress.toInt(),
IpAddress.MAX_INET_MASK))
.matchTcpDst((short) BgpConstants.BGP_PORT)
.build();
PointToPointIntent reversedIntentMatchDstTcpPort =
......@@ -185,9 +195,11 @@ public class PeerConnectivityManager {
selector = DefaultTrafficSelector.builder()
.matchEthType(Ethernet.TYPE_IPV4)
.matchIPProtocol(IPv4.PROTOCOL_TCP)
.matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toInt(), IPV4_BIT_LENGTH))
.matchIPDst(IpPrefix.valueOf(bgpdAddress.toInt(), IPV4_BIT_LENGTH))
.matchTcpSrc(BGP_PORT)
.matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toInt(),
IpAddress.MAX_INET_MASK))
.matchIPDst(IpPrefix.valueOf(bgpdAddress.toInt(),
IpAddress.MAX_INET_MASK))
.matchTcpSrc((short) BgpConstants.BGP_PORT)
.build();
PointToPointIntent reversedIntentMatchSrcTcpPort =
......@@ -211,7 +223,7 @@ public class PeerConnectivityManager {
* for paths from all peers to each BGP speaker.
*/
private void setupIcmpPaths() {
for (BgpSpeaker bgpSpeaker : configInfoService.getBgpSpeakers()
for (BgpSpeaker bgpSpeaker : configService.getBgpSpeakers()
.values()) {
log.debug("Start to set up ICMP paths for BGP speaker: {}",
bgpSpeaker);
......@@ -219,7 +231,7 @@ public class PeerConnectivityManager {
List<InterfaceAddress> interfaceAddresses = bgpSpeaker
.interfaceAddresses();
for (BgpPeer bgpPeer : configInfoService.getBgpPeers().values()) {
for (BgpPeer bgpPeer : configService.getBgpPeers().values()) {
Interface peerInterface = interfaceService.getInterface(
bgpPeer.connectPoint());
......@@ -253,8 +265,10 @@ public class PeerConnectivityManager {
TrafficSelector selector = DefaultTrafficSelector.builder()
.matchEthType(Ethernet.TYPE_IPV4)
.matchIPProtocol(IPv4.PROTOCOL_ICMP)
.matchIPSrc(IpPrefix.valueOf(bgpdAddress.toInt(), IPV4_BIT_LENGTH))
.matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toInt(), IPV4_BIT_LENGTH))
.matchIPSrc(IpPrefix.valueOf(bgpdAddress.toInt(),
IpAddress.MAX_INET_MASK))
.matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toInt(),
IpAddress.MAX_INET_MASK))
.build();
TrafficTreatment treatment = DefaultTrafficTreatment.builder()
......@@ -271,8 +285,10 @@ public class PeerConnectivityManager {
selector = DefaultTrafficSelector.builder()
.matchEthType(Ethernet.TYPE_IPV4)
.matchIPProtocol(IPv4.PROTOCOL_ICMP)
.matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toInt(), IPV4_BIT_LENGTH))
.matchIPDst(IpPrefix.valueOf(bgpdAddress.toInt(), IPV4_BIT_LENGTH))
.matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toInt(),
IpAddress.MAX_INET_MASK))
.matchIPDst(IpPrefix.valueOf(bgpdAddress.toInt(),
IpAddress.MAX_INET_MASK))
.build();
PointToPointIntent reversedIntent =
......
......@@ -55,8 +55,6 @@ import com.googlecode.concurrenttrees.radixinverted.InvertedRadixTree;
/**
* This class processes BGP route update, translates each update into a intent
* and submits the intent.
* <p/>
* TODO: Make it thread-safe.
*/
public class Router implements RouteListener {
......@@ -69,14 +67,13 @@ public class Router implements RouteListener {
// Stores all incoming route updates in a queue.
private BlockingQueue<RouteUpdate> routeUpdates;
// The Ip4Address is the next hop address of each route update.
// The IpAddress is the next hop address of each route update.
private SetMultimap<IpAddress, RouteEntry> routesWaitingOnArp;
private ConcurrentHashMap<IpPrefix, MultiPointToSinglePointIntent> pushedRouteIntents;
private IntentService intentService;
//private IProxyArpService proxyArp;
private HostService hostService;
private SdnIpConfigService configInfoService;
private SdnIpConfigService configService;
private InterfaceService interfaceService;
private ExecutorService bgpUpdatesExecutor;
......@@ -98,18 +95,19 @@ public class Router implements RouteListener {
/**
* Class constructor.
*
* @param appId the application ID
* @param intentService the intent service
* @param hostService the host service
* @param configInfoService the configuration service
* @param configService the configuration service
* @param interfaceService the interface service
*/
public Router(ApplicationId appId, IntentService intentService,
HostService hostService, SdnIpConfigService configInfoService,
HostService hostService, SdnIpConfigService configService,
InterfaceService interfaceService) {
this.appId = appId;
this.intentService = intentService;
this.hostService = hostService;
this.configInfoService = configInfoService;
this.configService = configService;
this.interfaceService = interfaceService;
bgpRoutes = new ConcurrentInvertedRadixTree<>(
......@@ -172,7 +170,7 @@ public class Router implements RouteListener {
@Override
public void update(RouteUpdate routeUpdate) {
log.debug("Received new route Update: {}", routeUpdate);
log.debug("Received new route update: {}", routeUpdate);
try {
routeUpdates.put(routeUpdate);
......@@ -498,9 +496,11 @@ public class Router implements RouteListener {
private void executeRouteAdd(RouteEntry routeEntry) {
log.debug("Executing route add: {}", routeEntry);
// Monitor the IP address so we'll get notified of updates to the MAC
// address.
hostService.startMonitoringIp(routeEntry.nextHop());
// See if we know the MAC address of the next hop
//MacAddress nextHopMacAddress =
//proxyArp.getMacAddress(routeEntry.getNextHop());
MacAddress nextHopMacAddress = null;
Set<Host> hosts = hostService.getHostsByIp(
routeEntry.nextHop().toPrefix());
......@@ -511,9 +511,6 @@ public class Router implements RouteListener {
if (nextHopMacAddress == null) {
routesWaitingOnArp.put(routeEntry.nextHop(), routeEntry);
//proxyArp.sendArpRequest(routeEntry.getNextHop(), this, true);
// TODO maybe just do this for every prefix anyway
hostService.startMonitoringIp(routeEntry.nextHop());
return;
}
......@@ -536,11 +533,11 @@ public class Router implements RouteListener {
// Find the attachment point (egress interface) of the next hop
Interface egressInterface;
if (configInfoService.getBgpPeers().containsKey(nextHopIpAddress)) {
if (configService.getBgpPeers().containsKey(nextHopIpAddress)) {
// Route to a peer
log.debug("Route to peer {}", nextHopIpAddress);
BgpPeer peer =
configInfoService.getBgpPeers().get(nextHopIpAddress);
configService.getBgpPeers().get(nextHopIpAddress);
egressInterface =
interfaceService.getInterface(peer.connectPoint());
} else {
......@@ -593,17 +590,12 @@ public class Router implements RouteListener {
}
// Match the destination IP prefix at the first hop
//PacketMatchBuilder builder = new PacketMatchBuilder();
//builder.setEtherType(Ethernet.TYPE_IPV4).setDstIpNet(prefix);
//PacketMatch packetMatch = builder.build();
TrafficSelector selector = DefaultTrafficSelector.builder()
.matchEthType(Ethernet.TYPE_IPV4)
.matchIPDst(prefix)
.build();
// Rewrite the destination MAC address
//ModifyDstMacAction modifyDstMacAction =
//new ModifyDstMacAction(nextHopMacAddress);
TrafficTreatment treatment = DefaultTrafficTreatment.builder()
.setEthDst(nextHopMacAddress)
.build();
......@@ -635,10 +627,6 @@ public class Router implements RouteListener {
log.debug("Processing route delete: {}", routeEntry);
IpPrefix prefix = routeEntry.prefix();
// TODO check the change of logic here - remove doesn't check that
// the route entry was what we expected (and we can't do this
// concurrently)
if (bgpRoutes.remove(RouteEntry.createBinaryString(prefix))) {
//
// Only delete flows if an entry was actually removed from the
......@@ -680,17 +668,19 @@ public class Router implements RouteListener {
}
/**
* This method handles the prefixes which are waiting for ARP replies for
* MAC addresses of next hops.
* Signals the Router that the MAC to IP mapping has potentially been
* updated. This has the effect of updating the MAC address for any
* installed prefixes if it has changed, as well as installing any pending
* prefixes that were waiting for MAC resolution.
*
* @param ipAddress next hop router IP address, for which we sent ARP
* request out
* @param macAddress MAC address which is relative to the ipAddress
* @param ipAddress the IP address that an event was received for
* @param macAddress the most recently known MAC address for the IP address
*/
//@Override
// TODO change name
public void arpResponse(IpAddress ipAddress, MacAddress macAddress) {
log.debug("Received ARP response: {} => {}", ipAddress, macAddress);
private void updateMac(IpAddress ipAddress, MacAddress macAddress) {
log.debug("Received updated MAC info: {} => {}", ipAddress, macAddress);
// TODO here we should check whether the next hop for any of our
// installed prefixes has changed, not just prefixes pending installation.
// We synchronize on this to prevent changes to the radix tree
// while we're pushing intents. If the tree changes, the
......@@ -708,8 +698,6 @@ public class Router implements RouteListener {
bgpRoutes.getValueForExactKey(binaryString);
if (foundRouteEntry != null &&
foundRouteEntry.nextHop().equals(routeEntry.nextHop())) {
log.debug("Pushing prefix {} next hop {}",
routeEntry.prefix(), routeEntry.nextHop());
// We only push prefix flows if the prefix is still in the
// radix tree and the next hop is the same as our
// update.
......@@ -717,9 +705,8 @@ public class Router implements RouteListener {
// for the ARP, or the next hop could have changed.
addRouteIntentToNextHop(prefix, ipAddress, macAddress);
} else {
log.debug("Received ARP response, but {}/{} is no longer in"
+ " the radix tree", routeEntry.prefix(),
routeEntry.nextHop());
log.debug("{} has been revoked before the MAC was resolved",
routeEntry);
}
}
}
......@@ -769,7 +756,7 @@ public class Router implements RouteListener {
event.type() == HostEvent.Type.HOST_UPDATED) {
Host host = event.subject();
for (IpPrefix ip : host.ipAddresses()) {
arpResponse(ip.toIpAddress(), host.mac());
updateMac(ip.toIpAddress(), host.mac());
}
}
}
......
......@@ -26,7 +26,7 @@ import org.slf4j.Logger;
@Service
public class SdnIp implements SdnIpService {
private static final String SDN_ID_APP = "org.onlab.onos.sdnip";
private static final String SDN_IP_APP = "org.onlab.onos.sdnip";
private final Logger log = getLogger(getClass());
......@@ -53,8 +53,10 @@ public class SdnIp implements SdnIpService {
InterfaceService interfaceService = new HostToInterfaceAdaptor(hostService);
ApplicationId appId = coreService.registerApplication(SDN_ID_APP);
peerConnectivity = new PeerConnectivityManager(appId, config, interfaceService, intentService);
ApplicationId appId = coreService.registerApplication(SDN_IP_APP);
peerConnectivity = new PeerConnectivityManager(appId, config,
interfaceService, intentService);
peerConnectivity.start();
router = new Router(appId, intentService, hostService, config, interfaceService);
......
package org.onlab.onos.sdnip;
import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.reset;
import static org.easymock.EasyMock.verify;
......@@ -15,6 +17,8 @@ import java.util.Set;
import org.junit.Before;
import org.junit.Test;
import org.onlab.junit.TestUtils;
import org.onlab.junit.TestUtils.TestUtilsException;
import org.onlab.onos.ApplicationId;
import org.onlab.onos.net.ConnectPoint;
import org.onlab.onos.net.DefaultHost;
......@@ -27,6 +31,7 @@ import org.onlab.onos.net.flow.DefaultTrafficSelector;
import org.onlab.onos.net.flow.DefaultTrafficTreatment;
import org.onlab.onos.net.flow.TrafficSelector;
import org.onlab.onos.net.flow.TrafficTreatment;
import org.onlab.onos.net.host.HostListener;
import org.onlab.onos.net.host.HostService;
import org.onlab.onos.net.intent.IntentService;
import org.onlab.onos.net.intent.MultiPointToSinglePointIntent;
......@@ -39,8 +44,6 @@ import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onlab.util.TestUtils;
import org.onlab.util.TestUtils.TestUtilsException;
import com.google.common.collect.Sets;
......@@ -55,10 +58,17 @@ public class RouterTest {
private IntentService intentService;
private HostService hostService;
private Map<IpAddress, BgpPeer> bgpPeers;
private Map<IpAddress, BgpPeer> configuredPeers;
private Set<Interface> interfaces;
private Set<Interface> configuredInterfaces;
private static final ConnectPoint SW1_ETH1 = new ConnectPoint(
DeviceId.deviceId("of:0000000000000001"),
PortNumber.portNumber(1));
private static final ConnectPoint SW2_ETH1 = new ConnectPoint(
DeviceId.deviceId("of:0000000000000002"),
PortNumber.portNumber(1));
private static final ConnectPoint SW3_ETH1 = new ConnectPoint(
DeviceId.deviceId("of:0000000000000003"),
PortNumber.portNumber(1));
private static final ApplicationId APPID = new ApplicationId() {
@Override
......@@ -76,55 +86,12 @@ public class RouterTest {
@Before
public void setUp() throws Exception {
bgpPeers = setUpBgpPeers();
interfaces = setUpInterfaces();
initRouter();
}
setUpBgpPeers();
/**
* Initializes Router class.
*/
private void initRouter() {
setUpInterfaceService();
setUpHostService();
intentService = createMock(IntentService.class);
hostService = createMock(HostService.class);
interfaceService = createMock(InterfaceService.class);
expect(interfaceService.getInterfaces()).andReturn(
interfaces).anyTimes();
Set<IpPrefix> ipAddressesOnSw1Eth1 = new HashSet<IpPrefix>();
ipAddressesOnSw1Eth1.add(IpPrefix.valueOf("192.168.10.0/24"));
Interface expectedInterface =
new Interface(new ConnectPoint(
DeviceId.deviceId("of:0000000000000001"),
PortNumber.portNumber("1")),
ipAddressesOnSw1Eth1,
MacAddress.valueOf("00:00:00:00:00:01"));
ConnectPoint egressPoint = new ConnectPoint(
DeviceId.deviceId("of:0000000000000001"),
PortNumber.portNumber(1));
expect(interfaceService.getInterface(egressPoint)).andReturn(
expectedInterface).anyTimes();
Set<IpPrefix> ipAddressesOnSw2Eth1 = new HashSet<IpPrefix>();
ipAddressesOnSw2Eth1.add(IpPrefix.valueOf("192.168.20.0/24"));
Interface expectedInterfaceNew =
new Interface(new ConnectPoint(
DeviceId.deviceId("of:0000000000000002"),
PortNumber.portNumber("1")),
ipAddressesOnSw2Eth1,
MacAddress.valueOf("00:00:00:00:00:02"));
ConnectPoint egressPointNew = new ConnectPoint(
DeviceId.deviceId("of:0000000000000002"),
PortNumber.portNumber(1));
expect(interfaceService.getInterface(egressPointNew)).andReturn(
expectedInterfaceNew).anyTimes();
replay(interfaceService);
sdnIpConfigService = createMock(SdnIpConfigService.class);
expect(sdnIpConfigService.getBgpPeers()).andReturn(bgpPeers).anyTimes();
replay(sdnIpConfigService);
router = new Router(APPID, intentService,
hostService, sdnIpConfigService, interfaceService);
......@@ -132,67 +99,99 @@ public class RouterTest {
/**
* Sets up BGP peers in external networks.
*
* @return configured BGP peers as a Map from peer IP address to BgpPeer
*/
private Map<IpAddress, BgpPeer> setUpBgpPeers() {
private void setUpBgpPeers() {
configuredPeers = new HashMap<>();
Map<IpAddress, BgpPeer> peers = new HashMap<>();
String peerSw1Eth1 = "192.168.10.1";
configuredPeers.put(IpAddress.valueOf(peerSw1Eth1),
peers.put(IpAddress.valueOf(peerSw1Eth1),
new BgpPeer("00:00:00:00:00:00:00:01", 1, peerSw1Eth1));
// Two BGP peers are connected to switch 2 port 1.
String peer1Sw2Eth1 = "192.168.20.1";
configuredPeers.put(IpAddress.valueOf(peer1Sw2Eth1),
peers.put(IpAddress.valueOf(peer1Sw2Eth1),
new BgpPeer("00:00:00:00:00:00:00:02", 1, peer1Sw2Eth1));
String peer2Sw2Eth1 = "192.168.20.2";
configuredPeers.put(IpAddress.valueOf(peer2Sw2Eth1),
peers.put(IpAddress.valueOf(peer2Sw2Eth1),
new BgpPeer("00:00:00:00:00:00:00:02", 1, peer2Sw2Eth1));
return configuredPeers;
sdnIpConfigService = createMock(SdnIpConfigService.class);
expect(sdnIpConfigService.getBgpPeers()).andReturn(peers).anyTimes();
replay(sdnIpConfigService);
}
/**
* Sets up logical interfaces, which emulate the configured interfaces
* in SDN-IP application.
*
* @return configured interfaces as a Set
*/
private Set<Interface> setUpInterfaces() {
private void setUpInterfaceService() {
interfaceService = createMock(InterfaceService.class);
configuredInterfaces = Sets.newHashSet();
Set<Interface> interfaces = Sets.newHashSet();
Set<IpPrefix> ipAddressesOnSw1Eth1 = new HashSet<IpPrefix>();
ipAddressesOnSw1Eth1.add(IpPrefix.valueOf("192.168.10.0/24"));
configuredInterfaces.add(
new Interface(new ConnectPoint(
DeviceId.deviceId("of:0000000000000001"),
PortNumber.portNumber(1)),
ipAddressesOnSw1Eth1,
MacAddress.valueOf("00:00:00:00:00:01")));
Set<IpPrefix> ipAddressesOnSw2Eth1 = new HashSet<IpPrefix>();
ipAddressesOnSw2Eth1.add(IpPrefix.valueOf("192.168.20.0/24"));
configuredInterfaces.add(
new Interface(new ConnectPoint(
DeviceId.deviceId("of:0000000000000002"),
PortNumber.portNumber(1)),
ipAddressesOnSw2Eth1,
MacAddress.valueOf("00:00:00:00:00:02")));
Set<IpPrefix> ipAddressesOnSw3Eth1 = new HashSet<IpPrefix>();
ipAddressesOnSw3Eth1.add(IpPrefix.valueOf("192.168.30.0/24"));
configuredInterfaces.add(
new Interface(new ConnectPoint(
DeviceId.deviceId("of:0000000000000003"),
PortNumber.portNumber(1)),
ipAddressesOnSw3Eth1,
MacAddress.valueOf("00:00:00:00:00:03")));
Interface sw1Eth1 = new Interface(SW1_ETH1,
Sets.newHashSet(IpPrefix.valueOf("192.168.10.101/24")),
MacAddress.valueOf("00:00:00:00:00:01"));
expect(interfaceService.getInterface(SW1_ETH1)).andReturn(sw1Eth1).anyTimes();
interfaces.add(sw1Eth1);
Interface sw2Eth1 = new Interface(SW2_ETH1,
Sets.newHashSet(IpPrefix.valueOf("192.168.20.101/24")),
MacAddress.valueOf("00:00:00:00:00:02"));
expect(interfaceService.getInterface(SW2_ETH1)).andReturn(sw2Eth1).anyTimes();
interfaces.add(sw2Eth1);
Interface sw3Eth1 = new Interface(SW3_ETH1,
Sets.newHashSet(IpPrefix.valueOf("192.168.30.101/24")),
MacAddress.valueOf("00:00:00:00:00:03"));
expect(interfaceService.getInterface(SW3_ETH1)).andReturn(sw3Eth1).anyTimes();
interfaces.add(sw3Eth1);
return configuredInterfaces;
expect(interfaceService.getInterfaces()).andReturn(interfaces).anyTimes();
replay(interfaceService);
}
/**
* Sets up the host service with details of some hosts.
*/
private void setUpHostService() {
hostService = createMock(HostService.class);
hostService.addListener(anyObject(HostListener.class));
expectLastCall().anyTimes();
IpPrefix host1Address = IpPrefix.valueOf("192.168.10.1/32");
Host host1 = new DefaultHost(ProviderId.NONE, HostId.NONE,
MacAddress.valueOf("00:00:00:00:00:01"), VlanId.NONE,
new HostLocation(SW1_ETH1, 1),
Sets.newHashSet(host1Address));
expect(hostService.getHostsByIp(host1Address))
.andReturn(Sets.newHashSet(host1)).anyTimes();
hostService.startMonitoringIp(host1Address.toIpAddress());
expectLastCall().anyTimes();
IpPrefix host2Address = IpPrefix.valueOf("192.168.20.1/32");
Host host2 = new DefaultHost(ProviderId.NONE, HostId.NONE,
MacAddress.valueOf("00:00:00:00:00:02"), VlanId.NONE,
new HostLocation(SW2_ETH1, 1),
Sets.newHashSet(host2Address));
expect(hostService.getHostsByIp(host2Address))
.andReturn(Sets.newHashSet(host2)).anyTimes();
hostService.startMonitoringIp(host2Address.toIpAddress());
expectLastCall().anyTimes();
replay(hostService);
}
/**
......@@ -200,7 +199,6 @@ public class RouterTest {
*/
@Test
public void testProcessRouteAdd() throws TestUtilsException {
// Construct a route entry
RouteEntry routeEntry = new RouteEntry(
IpPrefix.valueOf("1.1.1.0/24"),
......@@ -217,36 +215,13 @@ public class RouterTest {
treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:01"));
Set<ConnectPoint> ingressPoints = new HashSet<ConnectPoint>();
ingressPoints.add(new ConnectPoint(
DeviceId.deviceId("of:0000000000000002"),
PortNumber.portNumber("1")));
ingressPoints.add(new ConnectPoint(
DeviceId.deviceId("of:0000000000000003"),
PortNumber.portNumber("1")));
ConnectPoint egressPoint = new ConnectPoint(
DeviceId.deviceId("of:0000000000000001"),
PortNumber.portNumber("1"));
ingressPoints.add(SW2_ETH1);
ingressPoints.add(SW3_ETH1);
MultiPointToSinglePointIntent intent =
new MultiPointToSinglePointIntent(APPID,
selectorBuilder.build(), treatmentBuilder.build(),
ingressPoints, egressPoint);
// Reset host service
reset(hostService);
Set<Host> hosts = new HashSet<Host>(1);
Set<IpPrefix> ipPrefixes = new HashSet<IpPrefix>();
ipPrefixes.add(IpPrefix.valueOf("192.168.10.1/32"));
hosts.add(new DefaultHost(ProviderId.NONE, HostId.NONE,
MacAddress.valueOf("00:00:00:00:00:01"), VlanId.NONE,
new HostLocation(
DeviceId.deviceId("of:0000000000000001"),
PortNumber.portNumber(1), 1),
ipPrefixes));
expect(hostService.getHostsByIp(
IpPrefix.valueOf("192.168.10.1/32"))).andReturn(hosts);
replay(hostService);
ingressPoints, SW1_ETH1);
// Set up test expectation
reset(intentService);
......@@ -274,7 +249,6 @@ public class RouterTest {
*/
@Test
public void testRouteUpdate() throws TestUtilsException {
// Firstly add a route
testProcessRouteAdd();
......@@ -293,22 +267,14 @@ public class RouterTest {
DefaultTrafficTreatment.builder();
treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:01"));
ConnectPoint egressPoint = new ConnectPoint(
DeviceId.deviceId("of:0000000000000001"),
PortNumber.portNumber("1"));
Set<ConnectPoint> ingressPoints = new HashSet<ConnectPoint>();
ingressPoints.add(new ConnectPoint(
DeviceId.deviceId("of:0000000000000002"),
PortNumber.portNumber("1")));
ingressPoints.add(new ConnectPoint(
DeviceId.deviceId("of:0000000000000003"),
PortNumber.portNumber("1")));
ingressPoints.add(SW2_ETH1);
ingressPoints.add(SW3_ETH1);
MultiPointToSinglePointIntent intent =
new MultiPointToSinglePointIntent(APPID,
selectorBuilder.build(), treatmentBuilder.build(),
ingressPoints, egressPoint);
ingressPoints, SW1_ETH1);
// Start to construct a new route entry and new intent
RouteEntry routeEntryUpdate = new RouteEntry(
......@@ -325,38 +291,16 @@ public class RouterTest {
DefaultTrafficTreatment.builder();
treatmentBuilderNew.setEthDst(MacAddress.valueOf("00:00:00:00:00:02"));
ConnectPoint egressPointNew = new ConnectPoint(
DeviceId.deviceId("of:0000000000000002"),
PortNumber.portNumber("1"));
Set<ConnectPoint> ingressPointsNew = new HashSet<ConnectPoint>();
ingressPointsNew.add(new ConnectPoint(
DeviceId.deviceId("of:0000000000000001"),
PortNumber.portNumber("1")));
ingressPointsNew.add(new ConnectPoint(
DeviceId.deviceId("of:0000000000000003"),
PortNumber.portNumber("1")));
ingressPointsNew.add(SW1_ETH1);
ingressPointsNew.add(SW3_ETH1);
MultiPointToSinglePointIntent intentNew =
new MultiPointToSinglePointIntent(APPID,
selectorBuilderNew.build(),
treatmentBuilderNew.build(),
ingressPointsNew, egressPointNew);
// Reset host service
reset(hostService);
Set<Host> hosts = new HashSet<Host>(1);
Set<IpPrefix> ipPrefixes = new HashSet<IpPrefix>();
ipPrefixes.add(IpPrefix.valueOf("192.168.20.1/32"));
hosts.add(new DefaultHost(ProviderId.NONE, HostId.NONE,
MacAddress.valueOf("00:00:00:00:00:02"), VlanId.NONE,
new HostLocation(
DeviceId.deviceId("of:0000000000000002"),
PortNumber.portNumber(1), 1),
ipPrefixes));
expect(hostService.getHostsByIp(
IpPrefix.valueOf("192.168.20.1/32"))).andReturn(hosts);
replay(hostService);
ingressPointsNew, SW2_ETH1);
// Set up test expectation
reset(intentService);
......@@ -383,7 +327,6 @@ public class RouterTest {
*/
@Test
public void testProcessRouteDelete() throws TestUtilsException {
// Firstly add a route
testProcessRouteAdd();
......@@ -402,22 +345,14 @@ public class RouterTest {
DefaultTrafficTreatment.builder();
treatmentBuilder.setEthDst(MacAddress.valueOf("00:00:00:00:00:01"));
ConnectPoint egressPoint = new ConnectPoint(
DeviceId.deviceId("of:0000000000000001"),
PortNumber.portNumber("1"));
Set<ConnectPoint> ingressPoints = new HashSet<ConnectPoint>();
ingressPoints.add(new ConnectPoint(
DeviceId.deviceId("of:0000000000000002"),
PortNumber.portNumber("1")));
ingressPoints.add(new ConnectPoint(
DeviceId.deviceId("of:0000000000000003"),
PortNumber.portNumber("1")));
ingressPoints.add(SW2_ETH1);
ingressPoints.add(SW3_ETH1);
MultiPointToSinglePointIntent intent =
new MultiPointToSinglePointIntent(APPID,
selectorBuilder.build(), treatmentBuilder.build(),
ingressPoints, egressPoint);
ingressPoints, SW1_ETH1);
// Set up expectation
reset(intentService);
......@@ -442,7 +377,6 @@ public class RouterTest {
*/
@Test
public void testLocalRouteAdd() throws TestUtilsException {
// Construct a route entry, the next hop is the local BGP speaker
RouteEntry routeEntry = new RouteEntry(
IpPrefix.valueOf("1.1.1.0/24"), IpAddress.valueOf("0.0.0.0"));
......
......@@ -26,12 +26,12 @@ import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.junit.TestUtils;
import org.onlab.junit.TestUtils.TestUtilsException;
import org.onlab.onos.sdnip.RouteListener;
import org.onlab.onos.sdnip.RouteUpdate;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.util.TestUtils;
import org.onlab.util.TestUtils.TestUtilsException;
import com.google.common.net.InetAddresses;
......
......@@ -6,6 +6,7 @@ import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
/**
* This class tests the immutability, equality, and non-equality of
......@@ -17,7 +18,7 @@ public class IntentIdTest {
*/
@Test
public void intentIdFollowsGuidelineForImmutableObject() {
ImmutableClassChecker.assertThatClassIsImmutable(IntentId.class);
assertThatClassIsImmutable(IntentId.class);
}
/**
......
......@@ -11,6 +11,7 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
import static org.onlab.onos.net.NetTestTools.hid;
/**
......@@ -104,6 +105,6 @@ public class TestHostToHostIntent {
*/
@Test
public void checkImmutability() {
ImmutableClassChecker.assertThatClassIsImmutable(HostToHostIntent.class);
assertThatClassIsImmutable(HostToHostIntent.class);
}
}
......
......@@ -4,6 +4,7 @@ import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
import static org.onlab.onos.net.NetTestTools.link;
import java.util.HashSet;
......@@ -154,6 +155,6 @@ public class TestLinkCollectionIntent {
*/
@Test
public void checkImmutability() {
ImmutableClassChecker.assertThatClassIsImmutable(LinkCollectionIntent.class);
assertThatClassIsImmutable(LinkCollectionIntent.class);
}
}
......
......@@ -15,6 +15,7 @@ import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
import static org.onlab.onos.net.NetTestTools.connectPoint;
/**
......@@ -135,7 +136,6 @@ public class TestMultiPointToSinglePointIntent {
*/
@Test
public void checkImmutability() {
ImmutableClassChecker.
assertThatClassIsImmutable(MultiPointToSinglePointIntent.class);
}
}
......
......@@ -35,6 +35,7 @@
<dependency>
<groupId>org.onlab.onos</groupId>
<artifactId>onlab-junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
......
......@@ -11,6 +11,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
......@@ -159,6 +160,21 @@ public class DistributedFlowRuleStore
}
});
clusterCommunicator.addSubscriber(GET_DEVICE_FLOW_ENTRIES, new ClusterMessageHandler() {
@Override
public void handle(ClusterMessage message) {
DeviceId deviceId = SERIALIZER.decode(message.payload());
log.info("Received get flow entries request for {} from {}", deviceId, message.sender());
Set<FlowEntry> flowEntries = getFlowEntriesInternal(deviceId);
try {
message.respond(SERIALIZER.encode(flowEntries));
} catch (IOException e) {
log.error("Failed to respond to peer's getFlowEntries request", e);
}
}
});
log.info("Started");
}
......@@ -217,9 +233,33 @@ public class DistributedFlowRuleStore
@Override
public synchronized Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) {
ReplicaInfo replicaInfo = replicaInfoManager.getReplicaInfoFor(deviceId);
if (replicaInfo.master().get().equals(clusterService.getLocalNode().id())) {
return getFlowEntriesInternal(deviceId);
}
log.info("Forwarding getFlowEntries to {}, which is the primary (master) for device {}",
replicaInfo.master().orNull(), deviceId);
ClusterMessage message = new ClusterMessage(
clusterService.getLocalNode().id(),
GET_DEVICE_FLOW_ENTRIES,
SERIALIZER.encode(deviceId));
try {
ClusterMessageResponse response = clusterCommunicator.sendAndReceive(message, replicaInfo.master().get());
return SERIALIZER.decode(response.get(FLOW_RULE_STORE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS));
} catch (IOException | TimeoutException e) {
// FIXME: throw a FlowStoreException
throw new RuntimeException(e);
}
}
private Set<FlowEntry> getFlowEntriesInternal(DeviceId deviceId) {
Collection<? extends FlowEntry> rules = flowEntries.get(deviceId);
if (rules == null) {
return Collections.emptyList();
return Collections.emptySet();
}
return ImmutableSet.copyOf(rules);
}
......
......@@ -13,4 +13,7 @@ public final class FlowStoreMessageSubjects {
public static final MessageSubject GET_FLOW_ENTRY
= new MessageSubject("peer-forward-get-flow-entry");
public static final MessageSubject GET_DEVICE_FLOW_ENTRIES
= new MessageSubject("peer-forward-get-device-flow-entries");
}
......
......@@ -34,7 +34,7 @@
<version>2.10.1</version>
<configuration>
<show>package</show>
<excludePackageNames>org.onlab.thirdparty:*.impl:*.impl.*:org.onlab.onos.provider.*:org.onlab.onos.gui:org.onlab.onos.rest:org.onlab.onos.cli*:org.onlab.onos.tvue:org.onlab.onos.foo:org.onlab.onos.mobility:org.onlab.onos.proxyarp:org.onlab.onos.fwd:org.onlab.onos.ifwd:org.onlab.onos.optical:org.onlab.onos.config:org.onlab.onos.calendar:org.onlab.onos.sdnip*:org.onlab.onos.metrics</excludePackageNames>
<excludePackageNames>org.onlab.thirdparty:*.impl:*.impl.*:org.onlab.onos.provider.*:org.onlab.onos.gui:org.onlab.onos.rest:org.onlab.onos.cli*:org.onlab.onos.tvue:org.onlab.onos.foo:org.onlab.onos.mobility:org.onlab.onos.proxyarp:org.onlab.onos.fwd:org.onlab.onos.ifwd:org.onlab.onos.optical:org.onlab.onos.config:org.onlab.onos.calendar:org.onlab.onos.sdnip*:org.onlab.onos.metrics:org.onlab.onos.store.*:org.onlab.onos.openflow.*</excludePackageNames>
<docfilessubdirs>true</docfilessubdirs>
<doctitle>ONOS Java API</doctitle>
<groups>
......
......@@ -248,7 +248,7 @@
<dependency>
<groupId>org.onlab.onos</groupId>
<artifactId>onlab-junit</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
......
......@@ -27,6 +27,16 @@
<artifactId>guava-testlib</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
......
package org.onlab.onos.net.intent;
//TODO is this the right package?
package org.onlab.junit;
import org.hamcrest.Description;
import org.hamcrest.StringDescription;
......
package org.onlab.util;
package org.onlab.junit;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
......
package org.onlab.junit;
import org.hamcrest.Description;
import org.hamcrest.StringDescription;
import org.onlab.junit.TestUtils.TestUtilsException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/**
* Hamcrest style class for verifying that a class follows the
* accepted rules for utility classes.
*
* The rules that are enforced for utility classes:
* - the class must be declared final
* - the class must have only one constructor
* - the constructor must be private and inaccessible to callers
* - the class must have only static methods
*/
public class UtilityClassChecker {
private String failureReason = "";
/**
* Method to determine if a given class is a properly specified
* utility class. In addition to checking that the class meets the criteria
* for utility classes, an object of the class type is allocated to force
* test code coverage onto the class constructor.
*
* @param clazz the class to check
* @return true if the given class is a properly specified utility class.
*/
private boolean isProperlyDefinedUtilityClass(Class<?> clazz) {
// class must be declared final
if (!Modifier.isFinal(clazz.getModifiers())) {
failureReason = "a class that is not final";
return false;
}
// class must have only one constructor
final Constructor<?>[] constructors = clazz.getDeclaredConstructors();
if (constructors.length != 1) {
failureReason = "a class with more than one constructor";
return false;
}
// constructor must not be accessible outside of the class
final Constructor<?> constructor = constructors[0];
if (constructor.isAccessible()) {
failureReason = "a class with an accessible default constructor";
return false;
}
// constructor must be private
if (!Modifier.isPrivate(constructor.getModifiers())) {
failureReason = "a class with a default constructor that is not private";
return false;
}
// class must have only static methods
for (final Method method : clazz.getMethods()) {
if (method.getDeclaringClass().equals(clazz)) {
if (!Modifier.isStatic(method.getModifiers())) {
failureReason = "a class with one or more non-static methods";
return false;
}
}
}
try {
final Object newObject = TestUtils.callConstructor(constructor);
if (newObject == null) {
failureReason = "could not instantiate a new object";
return false;
}
} catch (TestUtilsException e) {
failureReason = "could not instantiate a new object";
return false;
}
return true;
}
/**
* Describe why an error was reported. Uses Hamcrest style Description
* interfaces.
*
* @param description the Description object to use for reporting the
* mismatch
*/
public void describeMismatch(Description description) {
description.appendText(failureReason);
}
/**
* Describe the source object that caused an error, using a Hamcrest
* Matcher style interface. In this case, it always returns
* that we are looking for a properly defined utility class.
*
* @param description the Description object to use to report the "to"
* object
*/
public void describeTo(Description description) {
description.appendText("a properly defined utility class");
}
/**
* Assert that the given class adheres to the utility class rules.
*
* @param clazz the class to check
*
* @throws java.lang.AssertionError if the class is not a valid
* utility class
*/
public static void assertThatClassIsUtility(Class<?> clazz) {
final UtilityClassChecker checker = new UtilityClassChecker();
if (!checker.isProperlyDefinedUtilityClass(clazz)) {
final Description toDescription = new StringDescription();
final Description mismatchDescription = new StringDescription();
checker.describeTo(toDescription);
checker.describeMismatch(mismatchDescription);
final String reason =
"\n" +
"Expected: is \"" + toDescription.toString() + "\"\n" +
" but : was \"" + mismatchDescription.toString() + "\"";
throw new AssertionError(reason);
}
}
}
package org.onlab.junit;
import org.junit.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
/**
* Set of unit tests to check the implementation of the immutable class
* checker.
*/
public class ImmutableClassCheckerTest {
/**
* Test class for non final class check.
*/
// CHECKSTYLE IGNORE FinalClass FOR NEXT 1 LINES
static class NonFinal {
private NonFinal() { }
}
/**
* Check that a non final class correctly produces an error.
* @throws Exception if any of the reflection lookups fail.
*/
@Test
public void testNonFinalClass() throws Exception {
boolean gotException = false;
try {
assertThatClassIsImmutable(NonFinal.class);
} catch (AssertionError assertion) {
assertThat(assertion.getMessage(),
containsString("is not final"));
gotException = true;
}
assertThat(gotException, is(true));
}
/**
* Test class for non private member class check.
*/
static final class FinalProtectedMember {
protected final int x = 0;
}
/**
* Check that a final class with a non-private member is properly detected.
*
* @throws Exception if any of the reflection lookups fail.
*/
@Test
public void testFinalProtectedMember() throws Exception {
boolean gotException = false;
try {
assertThatClassIsImmutable(FinalProtectedMember.class);
} catch (AssertionError assertion) {
assertThat(assertion.getMessage(),
containsString("a field named 'x' that is not private"));
gotException = true;
}
assertThat(gotException, is(true));
}
/**
* Test class for non private member class check.
*/
static final class NotFinalPrivateMember {
private int x = 0;
}
/**
* Check that a final class with a non-final private
* member is properly detected.
*
* @throws Exception if any of the reflection lookups fail.
*/
@Test
public void testNotFinalPrivateMember() throws Exception {
boolean gotException = false;
try {
assertThatClassIsImmutable(NotFinalPrivateMember.class);
} catch (AssertionError assertion) {
assertThat(assertion.getMessage(),
containsString("a field named 'x' that is not final"));
gotException = true;
}
assertThat(gotException, is(true));
}
/**
* Test class for non private member class check.
*/
static final class ClassWithSetter {
private final int x = 0;
public void setX(int newX) {
}
}
/**
* Check that a final class with a final private
* member that is modifyable by a setter is properly detected.
*
* @throws Exception if any of the reflection lookups fail.
*/
@Test
public void testClassWithSetter() throws Exception {
boolean gotException = false;
try {
assertThatClassIsImmutable(ClassWithSetter.class);
} catch (AssertionError assertion) {
assertThat(assertion.getMessage(),
containsString("a class with a setter named 'setX'"));
gotException = true;
}
assertThat(gotException, is(true));
}
}
package org.onlab.util;
package org.onlab.junit;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
......@@ -6,7 +6,7 @@ import static org.junit.Assert.assertNull;
import org.junit.Before;
import org.junit.Test;
import org.onlab.util.TestUtils.TestUtilsException;
import org.onlab.junit.TestUtils.TestUtilsException;
/**
* Test and usage examples for TestUtils.
......
package org.onlab.junit;
import org.junit.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import static org.onlab.junit.UtilityClassChecker.assertThatClassIsUtility;
/**
* Set of unit tests to check the implementation of the utility class
* checker.
*/
public class UtilityClassCheckerTest {
// CHECKSTYLE:OFF test data intentionally not final
/**
* Test class for non final class check.
*/
static class NonFinal {
private NonFinal() { }
}
// CHECKSTYLE:ON
/**
* Check that a non final class correctly produces an error.
* @throws Exception if any of the reflection lookups fail.
*/
@Test
public void testNonFinalClass() throws Exception {
boolean gotException = false;
try {
assertThatClassIsUtility(NonFinal.class);
} catch (AssertionError assertion) {
assertThat(assertion.getMessage(),
containsString("is not final"));
gotException = true;
}
assertThat(gotException, is(true));
}
/**
* Test class for final no constructor class check.
*/
static final class FinalNoConstructor {
}
/**
* Check that a final class with no declared constructor correctly produces
* an error. In this case, the compiler generates a default constructor
* for you, but the constructor is 'protected' and will fail the check.
*
* @throws Exception if any of the reflection lookups fail.
*/
@Test
public void testFinalNoConstructorClass() throws Exception {
boolean gotException = false;
try {
assertThatClassIsUtility(FinalNoConstructor.class);
} catch (AssertionError assertion) {
assertThat(assertion.getMessage(),
containsString("class with a default constructor that " +
"is not private"));
gotException = true;
}
assertThat(gotException, is(true));
}
/**
* Test class for class with more than one constructor check.
*/
static final class TwoConstructors {
private TwoConstructors() { }
private TwoConstructors(int x) { }
}
/**
* Check that a non static class correctly produces an error.
* @throws Exception if any of the reflection lookups fail.
*/
@Test
public void testOnlyOneConstructor() throws Exception {
boolean gotException = false;
try {
assertThatClassIsUtility(TwoConstructors.class);
} catch (AssertionError assertion) {
assertThat(assertion.getMessage(),
containsString("more than one constructor"));
gotException = true;
}
assertThat(gotException, is(true));
}
/**
* Test class with a non private constructor.
*/
static final class NonPrivateConstructor {
protected NonPrivateConstructor() { }
}
/**
* Check that a class with a non private constructor correctly
* produces an error.
* @throws Exception if any of the reflection lookups fail.
*/
@Test
public void testNonPrivateConstructor() throws Exception {
boolean gotException = false;
try {
assertThatClassIsUtility(NonPrivateConstructor.class);
} catch (AssertionError assertion) {
assertThat(assertion.getMessage(),
containsString("constructor that is not private"));
gotException = true;
}
assertThat(gotException, is(true));
}
/**
* Test class with a non static method.
*/
static final class NonStaticMethod {
private NonStaticMethod() { }
public void aPublicMethod() { }
}
/**
* Check that a class with a non static method correctly produces an error.
* @throws Exception if any of the reflection lookups fail.
*/
@Test
public void testNonStaticMethod() throws Exception {
boolean gotException = false;
try {
assertThatClassIsUtility(NonStaticMethod.class);
} catch (AssertionError assertion) {
assertThat(assertion.getMessage(),
containsString("one or more non-static methods"));
gotException = true;
}
assertThat(gotException, is(true));
}
}
......@@ -24,6 +24,7 @@
<dependency>
<groupId>org.onlab.onos</groupId>
<artifactId>onlab-junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.netty</groupId>
......
package org.onlab.packet;
import java.nio.ByteBuffer;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* The class representing an IPv4 address.
* This class is immutable.
*/
public final class Ip4Address implements Comparable<Ip4Address> {
private final int value;
/** The length of the address in bytes (octets). */
public static final int BYTE_LENGTH = 4;
/** The length of the address in bits. */
public static final int BIT_LENGTH = BYTE_LENGTH * Byte.SIZE;
/**
* Default constructor.
*/
public Ip4Address() {
this.value = 0;
}
/**
* Copy constructor.
*
* @param other the object to copy from
*/
public Ip4Address(Ip4Address other) {
this.value = other.value;
}
/**
* Constructor from an integer value.
*
* @param value the value to use
*/
public Ip4Address(int value) {
this.value = value;
}
/**
* Constructor from a byte array with the IPv4 address stored in network
* byte order (i.e., the most significant byte first).
*
* @param value the value to use
*/
public Ip4Address(byte[] value) {
this(value, 0);
}
/**
* Constructor from a byte array with the IPv4 address stored in network
* byte order (i.e., the most significant byte first), and a given offset
* from the beginning of the byte array.
*
* @param value the value to use
* @param offset the offset in bytes from the beginning of the byte array
*/
public Ip4Address(byte[] value, int offset) {
checkNotNull(value);
// Verify the arguments
if ((offset < 0) || (offset + BYTE_LENGTH > value.length)) {
String msg;
if (value.length < BYTE_LENGTH) {
msg = "Invalid IPv4 address array: array length: " +
value.length + ". Must be at least " + BYTE_LENGTH;
} else {
msg = "Invalid IPv4 address array: array offset: " +
offset + ". Must be in the interval [0, " +
(value.length - BYTE_LENGTH) + "]";
}
throw new IllegalArgumentException(msg);
}
// Read the address
ByteBuffer bb = ByteBuffer.wrap(value);
this.value = bb.getInt(offset);
}
/**
* Constructs an IPv4 address from a string representation of the address.
*<p>
* Example: "1.2.3.4"
*
* @param value the value to use
*/
public Ip4Address(String value) {
checkNotNull(value);
String[] splits = value.split("\\.");
if (splits.length != 4) {
final String msg = "Invalid IPv4 address string: " + value;
throw new IllegalArgumentException(msg);
}
int result = 0;
for (int i = 0; i < BYTE_LENGTH; i++) {
result |= Integer.parseInt(splits[i]) <<
((BYTE_LENGTH - (i + 1)) * Byte.SIZE);
}
this.value = result;
}
/**
* Gets the IPv4 address as a byte array.
*
* @return a byte array with the IPv4 address stored in network byte order
* (i.e., the most significant byte first).
*/
public byte[] toOctets() {
return ByteBuffer.allocate(BYTE_LENGTH).putInt(value).array();
}
/**
* Creates an IPv4 network mask prefix.
*
* @param prefixLen the length of the mask prefix. Must be in the interval
* [0, 32].
* @return a new IPv4 address that contains a mask prefix of the
* specified length
*/
public static Ip4Address makeMaskPrefix(int prefixLen) {
// Verify the prefix length
if ((prefixLen < 0) || (prefixLen > Ip4Address.BIT_LENGTH)) {
final String msg = "Invalid IPv4 prefix length: " + prefixLen +
". Must be in the interval [0, 32].";
throw new IllegalArgumentException(msg);
}
long v =
(0xffffffffL << (Ip4Address.BIT_LENGTH - prefixLen)) & 0xffffffffL;
return new Ip4Address((int) v);
}
/**
* Creates an IPv4 address by masking it with a network mask of given
* mask length.
*
* @param addr the address to mask
* @param prefixLen the length of the mask prefix. Must be in the interval
* [0, 32].
* @return a new IPv4 address that is masked with a mask prefix of the
* specified length
*/
public static Ip4Address makeMaskedAddress(final Ip4Address addr,
int prefixLen) {
Ip4Address mask = Ip4Address.makeMaskPrefix(prefixLen);
long v = addr.value & mask.value;
return new Ip4Address((int) v);
}
/**
* Gets the value of the IPv4 address.
*
* @return the value of the IPv4 address
*/
public int getValue() {
return value;
}
/**
* Converts the IPv4 value to a '.' separated string.
*
* @return the IPv4 value as a '.' separated string
*/
@Override
public String toString() {
return ((this.value >> 24) & 0xff) + "." +
((this.value >> 16) & 0xff) + "." +
((this.value >> 8) & 0xff) + "." +
(this.value & 0xff);
}
@Override
public boolean equals(Object o) {
if (!(o instanceof Ip4Address)) {
return false;
}
Ip4Address other = (Ip4Address) o;
if (this.value != other.value) {
return false;
}
return true;
}
@Override
public int hashCode() {
return this.value;
}
@Override
public int compareTo(Ip4Address o) {
Long lv = ((long) this.value) & 0xffffffffL;
Long rv = ((long) o.value) & 0xffffffffL;
return lv.compareTo(rv);
}
}
package org.onlab.packet;
import java.util.Objects;
/**
* The class representing an IPv4 network address.
* This class is immutable.
*/
public final class Ip4Prefix {
private final Ip4Address address; // The IPv4 address
private final short prefixLen; // The prefix length
/**
* Default constructor.
*/
public Ip4Prefix() {
this.address = new Ip4Address();
this.prefixLen = 0;
}
/**
* Copy constructor.
*
* @param other the object to copy from
*/
public Ip4Prefix(Ip4Prefix other) {
this.address = new Ip4Address(other.address);
this.prefixLen = other.prefixLen;
}
/**
* Constructor for a given address and prefix length.
*
* @param address the address to use
* @param prefixLen the prefix length to use
*/
public Ip4Prefix(Ip4Address address, short prefixLen) {
this.address = Ip4Address.makeMaskedAddress(address, prefixLen);
this.prefixLen = prefixLen;
}
/**
* Constructs an IPv4 prefix from a string representation of the
* prefix.
*<p>
* Example: "1.2.0.0/16"
*
* @param value the value to use
*/
public Ip4Prefix(String value) {
String[] splits = value.split("/");
if (splits.length != 2) {
throw new IllegalArgumentException("Specified IPv4 prefix must contain an IPv4 " +
"address and a prefix length separated by '/'");
}
this.prefixLen = Short.decode(splits[1]);
this.address = Ip4Address.makeMaskedAddress(new Ip4Address(splits[0]),
this.prefixLen);
}
/**
* Gets the address value of the IPv4 prefix.
*
* @return the address value of the IPv4 prefix
*/
public Ip4Address getAddress() {
return address;
}
/**
* Gets the prefix length value of the IPv4 prefix.
*
* @return the prefix length value of the IPv4 prefix
*/
public short getPrefixLen() {
return prefixLen;
}
/**
* Converts the IPv4 prefix value to an "address/prefixLen" string.
*
* @return the IPv4 prefix value as an "address/prefixLen" string
*/
@Override
public String toString() {
return this.address.toString() + "/" + this.prefixLen;
}
/**
* Compares the value of two Ip4Prefix objects.
* <p/>
* Note the value of the IPv4 address is compared directly between the
* objects, and must match exactly for the objects to be considered equal.
* This may result in objects which represent the same IP prefix being
* classified as unequal, because the unsignificant bits of the address
* field don't match (the bits to the right of the prefix length).
* <p/>
* TODO Change this behavior so that objects that represent the same prefix
* are classified as equal according to this equals method.
*
* @see Object#equals(Object)
*/
@Override
public boolean equals(Object other) {
if (other == this) {
return true;
}
if (!(other instanceof Ip4Prefix)) {
return false;
}
Ip4Prefix otherIp4Prefix = (Ip4Prefix) other;
return Objects.equals(this.address, otherIp4Prefix.address)
&& this.prefixLen == otherIp4Prefix.prefixLen;
}
@Override
public int hashCode() {
return Objects.hash(address, prefixLen);
}
}
package org.onlab.packet;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.util.Objects;
import com.google.common.net.InetAddresses;
import com.google.common.primitives.UnsignedLongs;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
/**
* The class representing an IPv6 address.
* This class is immutable.
*/
public final class Ip6Address implements Comparable<Ip6Address> {
private final long valueHigh; // The higher (more significant) 64 bits
private final long valueLow; // The lower (less significant) 64 bits
/** The length of the address in bytes (octets). */
public static final int BYTE_LENGTH = 16;
/** The length of the address in bits. */
public static final int BIT_LENGTH = BYTE_LENGTH * Byte.SIZE;
/**
* Default constructor.
*/
public Ip6Address() {
this.valueHigh = 0;
this.valueLow = 0;
}
/**
* Copy constructor.
*
* @param other the object to copy from
*/
public Ip6Address(Ip6Address other) {
this.valueHigh = other.valueHigh;
this.valueLow = other.valueLow;
}
/**
* Constructor from integer values.
*
* @param valueHigh the higher (more significant) 64 bits of the address
* @param valueLow the lower (less significant) 64 bits of the address
*/
public Ip6Address(long valueHigh, long valueLow) {
this.valueHigh = valueHigh;
this.valueLow = valueLow;
}
/**
* Constructor from a byte array with the IPv6 address stored in network
* byte order (i.e., the most significant byte first).
*
* @param value the value to use
*/
public Ip6Address(byte[] value) {
this(value, 0);
}
/**
* Constructor from a byte array with the IPv6 address stored in network
* byte order (i.e., the most significant byte first), and a given offset
* from the beginning of the byte array.
*
* @param value the value to use
* @param offset the offset in bytes from the beginning of the byte array
*/
public Ip6Address(byte[] value, int offset) {
checkNotNull(value);
// Verify the arguments
if ((offset < 0) || (offset + BYTE_LENGTH > value.length)) {
String msg;
if (value.length < BYTE_LENGTH) {
msg = "Invalid IPv6 address array: array length: " +
value.length + ". Must be at least " + BYTE_LENGTH;
} else {
msg = "Invalid IPv6 address array: array offset: " +
offset + ". Must be in the interval [0, " +
(value.length - BYTE_LENGTH) + "]";
}
throw new IllegalArgumentException(msg);
}
// Read the address
ByteBuffer bb = ByteBuffer.wrap(value);
bb.position(offset);
this.valueHigh = bb.getLong();
this.valueLow = bb.getLong();
}
/**
* Constructs an IPv6 address from a string representation of the address.
*<p>
* Example: "1111:2222::8888"
*
* @param value the value to use
*/
public Ip6Address(String value) {
checkNotNull(value);
if (value.isEmpty()) {
final String msg = "Specified IPv6 cannot be an empty string";
throw new IllegalArgumentException(msg);
}
InetAddress addr = null;
try {
addr = InetAddresses.forString(value);
} catch (IllegalArgumentException e) {
final String msg = "Invalid IPv6 address string: " + value;
throw new IllegalArgumentException(msg);
}
byte[] bytes = addr.getAddress();
ByteBuffer bb = ByteBuffer.wrap(bytes);
this.valueHigh = bb.getLong();
this.valueLow = bb.getLong();
}
/**
* Gets the IPv6 address as a byte array.
*
* @return a byte array with the IPv6 address stored in network byte order
* (i.e., the most significant byte first).
*/
public byte[] toOctets() {
return ByteBuffer.allocate(BYTE_LENGTH)
.putLong(valueHigh).putLong(valueLow).array();
}
/**
* Creates an IPv6 network mask prefix.
*
* @param prefixLen the length of the mask prefix. Must be in the interval
* [0, 128].
* @return a new IPv6 address that contains a mask prefix of the
* specified length
*/
public static Ip6Address makeMaskPrefix(int prefixLen) {
long vh, vl;
// Verify the prefix length
if ((prefixLen < 0) || (prefixLen > Ip6Address.BIT_LENGTH)) {
final String msg = "Invalid IPv6 prefix length: " + prefixLen +
". Must be in the interval [0, 128].";
throw new IllegalArgumentException(msg);
}
if (prefixLen == 0) {
//
// NOTE: Apparently, the result of "<< 64" shifting to the left
// results in all 1s instead of all 0s, hence we handle it as
// a special case.
//
vh = 0;
vl = 0;
} else if (prefixLen <= 64) {
vh = (0xffffffffffffffffL << (64 - prefixLen)) & 0xffffffffffffffffL;
vl = 0;
} else {
vh = -1L; // All 1s
vl = (0xffffffffffffffffL << (128 - prefixLen)) & 0xffffffffffffffffL;
}
return new Ip6Address(vh, vl);
}
/**
* Creates an IPv6 address by masking it with a network mask of given
* mask length.
*
* @param addr the address to mask
* @param prefixLen the length of the mask prefix. Must be in the interval
* [0, 128].
* @return a new IPv6 address that is masked with a mask prefix of the
* specified length
*/
public static Ip6Address makeMaskedAddress(final Ip6Address addr,
int prefixLen) {
Ip6Address mask = Ip6Address.makeMaskPrefix(prefixLen);
long vh = addr.valueHigh & mask.valueHigh;
long vl = addr.valueLow & mask.valueLow;
return new Ip6Address(vh, vl);
}
/**
* Gets the value of the higher (more significant) 64 bits of the address.
*
* @return the value of the higher (more significant) 64 bits of the
* address
*/
public long getValueHigh() {
return valueHigh;
}
/**
* Gets the value of the lower (less significant) 64 bits of the address.
*
* @return the value of the lower (less significant) 64 bits of the
* address
*/
public long getValueLow() {
return valueLow;
}
/**
* Converts the IPv6 value to a ':' separated string.
*
* @return the IPv6 value as a ':' separated string
*/
@Override
public String toString() {
ByteBuffer bb = ByteBuffer.allocate(Ip6Address.BYTE_LENGTH);
bb.putLong(valueHigh);
bb.putLong(valueLow);
InetAddress inetAddr = null;
try {
inetAddr = InetAddress.getByAddress(bb.array());
} catch (UnknownHostException e) {
// Should never happen
checkState(false, "Internal error: Ip6Address.toString()");
return "::";
}
return InetAddresses.toAddrString(inetAddr);
}
@Override
public boolean equals(Object o) {
if (!(o instanceof Ip6Address)) {
return false;
}
Ip6Address other = (Ip6Address) o;
return this.valueHigh == other.valueHigh
&& this.valueLow == other.valueLow;
}
@Override
public int hashCode() {
return Objects.hash(valueHigh, valueLow);
}
@Override
public int compareTo(Ip6Address o) {
// Compare the high-order 64-bit value
if (this.valueHigh != o.valueHigh) {
return UnsignedLongs.compare(this.valueHigh, o.valueHigh);
}
// Compare the low-order 64-bit value
if (this.valueLow != o.valueLow) {
return UnsignedLongs.compare(this.valueLow, o.valueLow);
}
return 0;
}
}
package org.onlab.packet;
import java.util.Objects;
/**
* The class representing an IPv6 network address.
* This class is immutable.
*/
public final class Ip6Prefix {
private final Ip6Address address; // The IPv6 address
private final short prefixLen; // The prefix length
/**
* Default constructor.
*/
public Ip6Prefix() {
this.address = new Ip6Address();
this.prefixLen = 0;
}
/**
* Copy constructor.
*
* @param other the object to copy from
*/
public Ip6Prefix(Ip6Prefix other) {
this.address = new Ip6Address(other.address);
this.prefixLen = other.prefixLen;
}
/**
* Constructor for a given address and prefix length.
*
* @param address the address to use
* @param prefixLen the prefix length to use
*/
public Ip6Prefix(Ip6Address address, short prefixLen) {
this.address = Ip6Address.makeMaskedAddress(address, prefixLen);
this.prefixLen = prefixLen;
}
/**
* Constructs an IPv6 prefix from a string representation of the
* prefix.
*<p>
* Example: "1111:2222::/32"
*
* @param value the value to use
*/
public Ip6Prefix(String value) {
String[] splits = value.split("/");
if (splits.length != 2) {
throw new IllegalArgumentException("Specified IPv6 prefix must contain an IPv6 " +
"address and a prefix length separated by '/'");
}
this.prefixLen = Short.decode(splits[1]);
this.address = Ip6Address.makeMaskedAddress(new Ip6Address(splits[0]),
this.prefixLen);
}
/**
* Gets the address value of the IPv6 prefix.
*
* @return the address value of the IPv6 prefix
*/
public Ip6Address getAddress() {
return address;
}
/**
* Gets the prefix length value of the IPv6 prefix.
*
* @return the prefix length value of the IPv6 prefix
*/
public short getPrefixLen() {
return prefixLen;
}
/**
* Converts the IPv6 prefix value to an "address/prefixLen" string.
*
* @return the IPv6 prefix value as an "address/prefixLen" string
*/
@Override
public String toString() {
return this.address.toString() + "/" + this.prefixLen;
}
/**
* Compares the value of two Ip6Prefix objects.
* <p/>
* Note the value of the IPv6 address is compared directly between the
* objects, and must match exactly for the objects to be considered equal.
* This may result in objects which represent the same IP prefix being
* classified as unequal, because the unsignificant bits of the address
* field don't match (the bits to the right of the prefix length).
* <p/>
* TODO Change this behavior so that objects that represent the same prefix
* are classified as equal according to this equals method.
*
* @see Object#equals(Object)
*/
@Override
public boolean equals(Object other) {
if (other == this) {
return true;
}
if (!(other instanceof Ip6Prefix)) {
return false;
}
Ip6Prefix otherIp6Prefix = (Ip6Prefix) other;
return Objects.equals(this.address, otherIp6Prefix.address)
&& this.prefixLen == otherIp6Prefix.prefixLen;
}
@Override
public int hashCode() {
return Objects.hash(address, prefixLen);
}
}
package org.onlab.packet;
import org.junit.Test;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
/**
* Tests for class {@link Ip4Address}.
*/
public class Ip4AddressTest {
/**
* Tests the immutability of {@link Ip4Address}.
*/
@Test
public void testImmutable() {
assertThatClassIsImmutable(Ip4Address.class);
}
/**
* Tests the length of the address in bytes (octets).
*/
@Test
public void testAddrBytelen() {
assertThat(Ip4Address.BYTE_LENGTH, is(4));
}
/**
* Tests the length of the address in bits.
*/
@Test
public void testAddrBitlen() {
assertThat(Ip4Address.BIT_LENGTH, is(32));
}
/**
* Tests default class constructor.
*/
@Test
public void testDefaultConstructor() {
Ip4Address ip4Address = new Ip4Address();
assertThat(ip4Address.toString(), is("0.0.0.0"));
}
/**
* Tests valid class copy constructor.
*/
@Test
public void testCopyConstructor() {
Ip4Address fromAddr = new Ip4Address("1.2.3.4");
Ip4Address ip4Address = new Ip4Address(fromAddr);
assertThat(ip4Address.toString(), is("1.2.3.4"));
fromAddr = new Ip4Address("0.0.0.0");
ip4Address = new Ip4Address(fromAddr);
assertThat(ip4Address.toString(), is("0.0.0.0"));
fromAddr = new Ip4Address("255.255.255.255");
ip4Address = new Ip4Address(fromAddr);
assertThat(ip4Address.toString(), is("255.255.255.255"));
}
/**
* Tests invalid class copy constructor for a null object to copy from.
*/
@Test(expected = NullPointerException.class)
public void testInvalidConstructorNullObject() {
Ip4Address fromAddr = null;
Ip4Address ip4Address = new Ip4Address(fromAddr);
}
/**
* Tests valid class constructor for an integer value.
*/
@Test
public void testConstructorForInteger() {
Ip4Address ip4Address = new Ip4Address(0x01020304);
assertThat(ip4Address.toString(), is("1.2.3.4"));
ip4Address = new Ip4Address(0);
assertThat(ip4Address.toString(), is("0.0.0.0"));
ip4Address = new Ip4Address(0xffffffff);
assertThat(ip4Address.toString(), is("255.255.255.255"));
}
/**
* Tests valid class constructor for an array value.
*/
@Test
public void testConstructorForArray() {
final byte[] value1 = new byte[] {1, 2, 3, 4};
Ip4Address ip4Address = new Ip4Address(value1);
assertThat(ip4Address.toString(), is("1.2.3.4"));
final byte[] value2 = new byte[] {0, 0, 0, 0};
ip4Address = new Ip4Address(value2);
assertThat(ip4Address.toString(), is("0.0.0.0"));
final byte[] value3 = new byte[] {(byte) 0xff, (byte) 0xff,
(byte) 0xff, (byte) 0xff};
ip4Address = new Ip4Address(value3);
assertThat(ip4Address.toString(), is("255.255.255.255"));
}
/**
* Tests valid class constructor for an array value and an offset.
*/
@Test
public void testConstructorForArrayAndOffset() {
final byte[] value1 = new byte[] {11, 22, 33, // Preamble
1, 2, 3, 4,
44, 55}; // Extra bytes
Ip4Address ip4Address = new Ip4Address(value1, 3);
assertThat(ip4Address.toString(), is("1.2.3.4"));
final byte[] value2 = new byte[] {11, 22, // Preamble
0, 0, 0, 0,
33}; // Extra bytes
ip4Address = new Ip4Address(value2, 2);
assertThat(ip4Address.toString(), is("0.0.0.0"));
final byte[] value3 = new byte[] {11, 22, // Preamble
(byte) 0xff, (byte) 0xff,
(byte) 0xff, (byte) 0xff,
33}; // Extra bytes
ip4Address = new Ip4Address(value3, 2);
assertThat(ip4Address.toString(), is("255.255.255.255"));
}
/**
* Tests invalid class constructor for a null array.
*/
@Test(expected = NullPointerException.class)
public void testInvalidConstructorNullArray() {
final byte[] fromArray = null;
Ip4Address ip4Address = new Ip4Address(fromArray);
}
/**
* Tests invalid class constructor for an array that is too short.
*/
@Test(expected = IllegalArgumentException.class)
public void testInvalidConstructorShortArray() {
final byte[] fromArray = new byte[] {1, 2, 3};
Ip4Address ip4Address = new Ip4Address(fromArray);
}
/**
* Tests invalid class constructor for an array and an invalid offset.
*/
@Test(expected = IllegalArgumentException.class)
public void testInvalidConstructorArrayInvalidOffset() {
final byte[] value1 = new byte[] {11, 22, 33, // Preamble
1, 2, 3, 4,
44, 55}; // Extra bytes
Ip4Address ip4Address = new Ip4Address(value1, 6);
}
/**
* Tests valid class constructor for a string.
*/
@Test
public void testConstructorForString() {
Ip4Address ip4Address = new Ip4Address("1.2.3.4");
assertThat(ip4Address.toString(), is("1.2.3.4"));
ip4Address = new Ip4Address("0.0.0.0");
assertThat(ip4Address.toString(), is("0.0.0.0"));
ip4Address = new Ip4Address("255.255.255.255");
assertThat(ip4Address.toString(), is("255.255.255.255"));
}
/**
* Tests invalid class constructor for a null string.
*/
@Test(expected = NullPointerException.class)
public void testInvalidConstructorNullString() {
String fromString = null;
Ip4Address ip4Address = new Ip4Address(fromString);
}
/**
* Tests invalid class constructor for an empty string.
*/
@Test(expected = IllegalArgumentException.class)
public void testInvalidConstructors() {
// Check constructor for invalid ID: empty string
Ip4Address ip4Address = new Ip4Address("");
}
/**
* Tests returning the address as a byte array.
*/
@Test
public void testAddressToOctets() {
final byte[] value1 = new byte[] {1, 2, 3, 4};
Ip4Address ip4Address = new Ip4Address("1.2.3.4");
assertThat(ip4Address.toOctets(), is(value1));
final byte[] value2 = new byte[] {0, 0, 0, 0};
ip4Address = new Ip4Address("0.0.0.0");
assertThat(ip4Address.toOctets(), is(value2));
final byte[] value3 = new byte[] {(byte) 0xff, (byte) 0xff,
(byte) 0xff, (byte) 0xff};
ip4Address = new Ip4Address("255.255.255.255");
assertThat(ip4Address.toOctets(), is(value3));
}
/**
* Tests making a mask prefix for a given prefix length.
*/
@Test
public void testMakeMaskPrefix() {
Ip4Address ip4Address = Ip4Address.makeMaskPrefix(25);
assertThat(ip4Address.toString(), is("255.255.255.128"));
ip4Address = Ip4Address.makeMaskPrefix(0);
assertThat(ip4Address.toString(), is("0.0.0.0"));
ip4Address = Ip4Address.makeMaskPrefix(32);
assertThat(ip4Address.toString(), is("255.255.255.255"));
}
/**
* Tests making of a masked address.
*/
@Test
public void testMakeMaskedAddress() {
Ip4Address ip4Address = new Ip4Address("1.2.3.5");
Ip4Address ip4AddressMasked =
Ip4Address.makeMaskedAddress(ip4Address, 24);
assertThat(ip4AddressMasked.toString(), is("1.2.3.0"));
ip4AddressMasked = Ip4Address.makeMaskedAddress(ip4Address, 0);
assertThat(ip4AddressMasked.toString(), is("0.0.0.0"));
ip4AddressMasked = Ip4Address.makeMaskedAddress(ip4Address, 32);
assertThat(ip4AddressMasked.toString(), is("1.2.3.5"));
}
/**
* Tests getting the value of an address.
*/
@Test
public void testGetValue() {
Ip4Address ip4Address = new Ip4Address("1.2.3.4");
assertThat(ip4Address.getValue(), is(0x01020304));
ip4Address = new Ip4Address("0.0.0.0");
assertThat(ip4Address.getValue(), is(0));
ip4Address = new Ip4Address("255.255.255.255");
assertThat(ip4Address.getValue(), is(-1));
}
/**
* Tests equality of {@link Ip4Address}.
*/
@Test
public void testEquality() {
Ip4Address addr1 = new Ip4Address("1.2.3.4");
Ip4Address addr2 = new Ip4Address("1.2.3.4");
assertThat(addr1, is(addr2));
addr1 = new Ip4Address("0.0.0.0");
addr2 = new Ip4Address("0.0.0.0");
assertThat(addr1, is(addr2));
addr1 = new Ip4Address("255.255.255.255");
addr2 = new Ip4Address("255.255.255.255");
assertThat(addr1, is(addr2));
}
/**
* Tests non-equality of {@link Ip4Address}.
*/
@Test
public void testNonEquality() {
Ip4Address addr1 = new Ip4Address("1.2.3.4");
Ip4Address addr2 = new Ip4Address("1.2.3.5");
Ip4Address addr3 = new Ip4Address("0.0.0.0");
Ip4Address addr4 = new Ip4Address("255.255.255.255");
assertThat(addr1, is(not(addr2)));
assertThat(addr3, is(not(addr2)));
assertThat(addr4, is(not(addr2)));
}
/**
* Tests comparison of {@link Ip4Address}.
*/
@Test
public void testComparison() {
Ip4Address addr1 = new Ip4Address("1.2.3.4");
Ip4Address addr2 = new Ip4Address("1.2.3.4");
Ip4Address addr3 = new Ip4Address("1.2.3.3");
Ip4Address addr4 = new Ip4Address("1.2.3.5");
assertTrue(addr1.compareTo(addr2) == 0);
assertTrue(addr1.compareTo(addr3) > 0);
assertTrue(addr1.compareTo(addr4) < 0);
addr1 = new Ip4Address("255.2.3.4");
addr2 = new Ip4Address("255.2.3.4");
addr3 = new Ip4Address("255.2.3.3");
addr4 = new Ip4Address("255.2.3.5");
assertTrue(addr1.compareTo(addr2) == 0);
assertTrue(addr1.compareTo(addr3) > 0);
assertTrue(addr1.compareTo(addr4) < 0);
}
/**
* Tests object string representation.
*/
@Test
public void testToString() {
Ip4Address ip4Address = new Ip4Address("1.2.3.4");
assertThat(ip4Address.toString(), is("1.2.3.4"));
ip4Address = new Ip4Address("0.0.0.0");
assertThat(ip4Address.toString(), is("0.0.0.0"));
ip4Address = new Ip4Address("255.255.255.255");
assertThat(ip4Address.toString(), is("255.255.255.255"));
}
}
package org.onlab.packet;
import org.junit.Test;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertThat;
import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
/**
* Tests for class {@link Ip4Prefix}.
*/
public class Ip4PrefixTest {
/**
* Tests the immutability of {@link Ip4Prefix}.
*/
@Test
public void testImmutable() {
assertThatClassIsImmutable(Ip4Prefix.class);
}
/**
* Tests default class constructor.
*/
@Test
public void testDefaultConstructor() {
Ip4Prefix ip4prefix = new Ip4Prefix();
assertThat(ip4prefix.toString(), is("0.0.0.0/0"));
}
/**
* Tests valid class copy constructor.
*/
@Test
public void testCopyConstructor() {
Ip4Prefix fromAddr = new Ip4Prefix("1.2.3.0/24");
Ip4Prefix ip4prefix = new Ip4Prefix(fromAddr);
assertThat(ip4prefix.toString(), is("1.2.3.0/24"));
fromAddr = new Ip4Prefix("0.0.0.0/0");
ip4prefix = new Ip4Prefix(fromAddr);
assertThat(ip4prefix.toString(), is("0.0.0.0/0"));
fromAddr = new Ip4Prefix("255.255.255.255/32");
ip4prefix = new Ip4Prefix(fromAddr);
assertThat(ip4prefix.toString(), is("255.255.255.255/32"));
}
/**
* Tests invalid class copy constructor for a null object to copy from.
*/
@Test(expected = NullPointerException.class)
public void testInvalidConstructorNullObject() {
Ip4Prefix fromAddr = null;
Ip4Prefix ip4prefix = new Ip4Prefix(fromAddr);
}
/**
* Tests valid class constructor for an address and prefix length.
*/
@Test
public void testConstructorForAddressAndPrefixLength() {
Ip4Prefix ip4prefix =
new Ip4Prefix(new Ip4Address("1.2.3.0"), (short) 24);
assertThat(ip4prefix.toString(), is("1.2.3.0/24"));
ip4prefix = new Ip4Prefix(new Ip4Address("1.2.3.4"), (short) 24);
assertThat(ip4prefix.toString(), is("1.2.3.0/24"));
ip4prefix = new Ip4Prefix(new Ip4Address("1.2.3.5"), (short) 32);
assertThat(ip4prefix.toString(), is("1.2.3.5/32"));
ip4prefix = new Ip4Prefix(new Ip4Address("0.0.0.0"), (short) 0);
assertThat(ip4prefix.toString(), is("0.0.0.0/0"));
ip4prefix =
new Ip4Prefix(new Ip4Address("255.255.255.255"), (short) 32);
assertThat(ip4prefix.toString(), is("255.255.255.255/32"));
}
/**
* Tests valid class constructor for a string.
*/
@Test
public void testConstructorForString() {
Ip4Prefix ip4prefix = new Ip4Prefix("1.2.3.0/24");
assertThat(ip4prefix.toString(), is("1.2.3.0/24"));
ip4prefix = new Ip4Prefix("1.2.3.4/24");
assertThat(ip4prefix.toString(), is("1.2.3.0/24"));
ip4prefix = new Ip4Prefix("1.2.3.5/32");
assertThat(ip4prefix.toString(), is("1.2.3.5/32"));
ip4prefix = new Ip4Prefix("0.0.0.0/0");
assertThat(ip4prefix.toString(), is("0.0.0.0/0"));
ip4prefix = new Ip4Prefix("255.255.255.255/32");
assertThat(ip4prefix.toString(), is("255.255.255.255/32"));
}
/**
* Tests invalid class constructor for a null string.
*/
@Test(expected = NullPointerException.class)
public void testInvalidConstructorNullString() {
String fromString = null;
Ip4Prefix ip4prefix = new Ip4Prefix(fromString);
}
/**
* Tests invalid class constructor for an empty string.
*/
@Test(expected = IllegalArgumentException.class)
public void testInvalidConstructors() {
// Check constructor for invalid ID: empty string
Ip4Prefix ip4prefix = new Ip4Prefix("");
}
/**
* Tests getting the value of an address.
*/
@Test
public void testGetValue() {
Ip4Prefix ip4prefix = new Ip4Prefix("1.2.3.0/24");
assertThat(ip4prefix.getAddress(), equalTo(new Ip4Address("1.2.3.0")));
assertThat(ip4prefix.getPrefixLen(), is((short) 24));
ip4prefix = new Ip4Prefix("0.0.0.0/0");
assertThat(ip4prefix.getAddress(), equalTo(new Ip4Address("0.0.0.0")));
assertThat(ip4prefix.getPrefixLen(), is((short) 0));
ip4prefix = new Ip4Prefix("255.255.255.255/32");
assertThat(ip4prefix.getAddress(),
equalTo(new Ip4Address("255.255.255.255")));
assertThat(ip4prefix.getPrefixLen(), is((short) 32));
}
/**
* Tests equality of {@link Ip4Address}.
*/
@Test
public void testEquality() {
Ip4Prefix addr1net = new Ip4Prefix("1.2.3.0/24");
Ip4Prefix addr2net = new Ip4Prefix("1.2.3.0/24");
assertThat(addr1net, is(addr2net));
addr1net = new Ip4Prefix("1.2.3.0/24");
addr2net = new Ip4Prefix("1.2.3.4/24");
assertThat(addr1net, is(addr2net));
addr1net = new Ip4Prefix("0.0.0.0/0");
addr2net = new Ip4Prefix("0.0.0.0/0");
assertThat(addr1net, is(addr2net));
addr1net = new Ip4Prefix("255.255.255.255/32");
addr2net = new Ip4Prefix("255.255.255.255/32");
assertThat(addr1net, is(addr2net));
}
/**
* Tests non-equality of {@link Ip4Address}.
*/
@Test
public void testNonEquality() {
Ip4Prefix addr1net = new Ip4Prefix("1.2.0.0/16");
Ip4Prefix addr2net = new Ip4Prefix("1.3.0.0/16");
Ip4Prefix addr3net = new Ip4Prefix("1.3.0.0/24");
Ip4Prefix addr4net = new Ip4Prefix("0.0.0.0/0");
Ip4Prefix addr5net = new Ip4Prefix("255.255.255.255/32");
assertThat(addr1net, is(not(addr2net)));
assertThat(addr3net, is(not(addr2net)));
assertThat(addr4net, is(not(addr2net)));
assertThat(addr5net, is(not(addr2net)));
}
/**
* Tests object string representation.
*/
@Test
public void testToString() {
Ip4Prefix ip4prefix = new Ip4Prefix("1.2.3.0/24");
assertThat(ip4prefix.toString(), is("1.2.3.0/24"));
ip4prefix = new Ip4Prefix("1.2.3.4/24");
assertThat(ip4prefix.toString(), is("1.2.3.0/24"));
ip4prefix = new Ip4Prefix("0.0.0.0/0");
assertThat(ip4prefix.toString(), is("0.0.0.0/0"));
ip4prefix = new Ip4Prefix("255.255.255.255/32");
assertThat(ip4prefix.toString(), is("255.255.255.255/32"));
}
}
package org.onlab.packet;
import org.junit.Test;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
/**
* Tests for class {@link Ip6Address}.
*/
public class Ip6AddressTest {
/**
* Tests the immutability of {@link Ip6Address}.
*/
@Test
public void testImmutable() {
assertThatClassIsImmutable(Ip6Address.class);
}
/**
* Tests the length of the address in bytes (octets).
*/
@Test
public void testAddrBytelen() {
assertThat(Ip6Address.BYTE_LENGTH, is(16));
}
/**
* Tests the length of the address in bits.
*/
@Test
public void testAddrBitlen() {
assertThat(Ip6Address.BIT_LENGTH, is(128));
}
/**
* Tests default class constructor.
*/
@Test
public void testDefaultConstructor() {
Ip6Address ip6Address = new Ip6Address();
assertThat(ip6Address.toString(), is("::"));
}
/**
* Tests valid class copy constructor.
*/
@Test
public void testCopyConstructor() {
Ip6Address fromAddr =
new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8888");
Ip6Address ip6Address = new Ip6Address(fromAddr);
assertThat(ip6Address.toString(),
is("1111:2222:3333:4444:5555:6666:7777:8888"));
fromAddr = new Ip6Address("::");
ip6Address = new Ip6Address(fromAddr);
assertThat(ip6Address.toString(), is("::"));
fromAddr = new Ip6Address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
ip6Address = new Ip6Address(fromAddr);
assertThat(ip6Address.toString(),
is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
}
/**
* Tests invalid class copy constructor for a null object to copy from.
*/
@Test(expected = NullPointerException.class)
public void testInvalidConstructorNullObject() {
Ip6Address fromAddr = null;
Ip6Address ip6Address = new Ip6Address(fromAddr);
}
/**
* Tests valid class constructor for integer values.
*/
@Test
public void testConstructorForInteger() {
Ip6Address ip6Address =
new Ip6Address(0x1111222233334444L, 0x5555666677778888L);
assertThat(ip6Address.toString(),
is("1111:2222:3333:4444:5555:6666:7777:8888"));
ip6Address = new Ip6Address(0L, 0L);
assertThat(ip6Address.toString(), is("::"));
ip6Address = new Ip6Address(-1L, -1L);
assertThat(ip6Address.toString(),
is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
}
/**
* Tests valid class constructor for an array value.
*/
@Test
public void testConstructorForArray() {
final byte[] value1 = new byte[] {0x11, 0x11, 0x22, 0x22,
0x33, 0x33, 0x44, 0x44,
0x55, 0x55, 0x66, 0x66,
0x77, 0x77,
(byte) 0x88, (byte) 0x88};
Ip6Address ip6Address = new Ip6Address(value1);
assertThat(ip6Address.toString(),
is("1111:2222:3333:4444:5555:6666:7777:8888"));
final byte[] value2 = new byte[] {0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00};
ip6Address = new Ip6Address(value2);
assertThat(ip6Address.toString(), is("::"));
final byte[] value3 = new byte[] {(byte) 0xff, (byte) 0xff,
(byte) 0xff, (byte) 0xff,
(byte) 0xff, (byte) 0xff,
(byte) 0xff, (byte) 0xff,
(byte) 0xff, (byte) 0xff,
(byte) 0xff, (byte) 0xff,
(byte) 0xff, (byte) 0xff,
(byte) 0xff, (byte) 0xff};
ip6Address = new Ip6Address(value3);
assertThat(ip6Address.toString(),
is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
}
/**
* Tests valid class constructor for an array value and an offset.
*/
@Test
public void testConstructorForArrayAndOffset() {
final byte[] value1 = new byte[] {11, 22, 33, // Preamble
0x11, 0x11, 0x22, 0x22,
0x33, 0x33, 0x44, 0x44,
0x55, 0x55, 0x66, 0x66,
0x77, 0x77,
(byte) 0x88, (byte) 0x88,
44, 55}; // Extra bytes
Ip6Address ip6Address = new Ip6Address(value1, 3);
assertThat(ip6Address.toString(),
is("1111:2222:3333:4444:5555:6666:7777:8888"));
final byte[] value2 = new byte[] {11, 22, // Preamble
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
33}; // Extra bytes
ip6Address = new Ip6Address(value2, 2);
assertThat(ip6Address.toString(), is("::"));
final byte[] value3 = new byte[] {11, 22, // Preamble
(byte) 0xff, (byte) 0xff,
(byte) 0xff, (byte) 0xff,
(byte) 0xff, (byte) 0xff,
(byte) 0xff, (byte) 0xff,
(byte) 0xff, (byte) 0xff,
(byte) 0xff, (byte) 0xff,
(byte) 0xff, (byte) 0xff,
(byte) 0xff, (byte) 0xff,
33}; // Extra bytes
ip6Address = new Ip6Address(value3, 2);
assertThat(ip6Address.toString(),
is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
}
/**
* Tests invalid class constructor for a null array.
*/
@Test(expected = NullPointerException.class)
public void testInvalidConstructorNullArray() {
final byte[] fromArray = null;
Ip6Address ip6Address = new Ip6Address(fromArray);
}
/**
* Tests invalid class constructor for an array that is too short.
*/
@Test(expected = IllegalArgumentException.class)
public void testInvalidConstructorShortArray() {
final byte[] fromArray = new byte[] {1, 2, 3, 4, 5, 6, 7, 8, 9};
Ip6Address ip6Address = new Ip6Address(fromArray);
}
/**
* Tests invalid class constructor for an array and an invalid offset.
*/
@Test(expected = IllegalArgumentException.class)
public void testInvalidConstructorArrayInvalidOffset() {
final byte[] value1 = new byte[] {11, 22, 33, // Preamble
0x11, 0x11, 0x22, 0x22,
0x33, 0x33, 0x44, 0x44,
0x55, 0x55, 0x66, 0x66,
0x77, 0x77,
(byte) 0x88, (byte) 0x88,
44, 55}; // Extra bytes
Ip6Address ip6Address = new Ip6Address(value1, 6);
}
/**
* Tests valid class constructor for a string.
*/
@Test
public void testConstructorForString() {
Ip6Address ip6Address =
new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8888");
assertThat(ip6Address.toString(),
is("1111:2222:3333:4444:5555:6666:7777:8888"));
ip6Address = new Ip6Address("::");
assertThat(ip6Address.toString(), is("::"));
ip6Address = new Ip6Address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
assertThat(ip6Address.toString(),
is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
}
/**
* Tests invalid class constructor for a null string.
*/
@Test(expected = NullPointerException.class)
public void testInvalidConstructorNullString() {
String fromString = null;
Ip6Address ip6Address = new Ip6Address(fromString);
}
/**
* Tests invalid class constructor for an empty string.
*/
@Test(expected = IllegalArgumentException.class)
public void testInvalidConstructors() {
// Check constructor for invalid ID: empty string
Ip6Address ip6Address = new Ip6Address("");
}
/**
* Tests returning the address as a byte array.
*/
@Test
public void testAddressToOctets() {
final byte[] value1 = new byte[] {0x11, 0x11, 0x22, 0x22,
0x33, 0x33, 0x44, 0x44,
0x55, 0x55, 0x66, 0x66,
0x77, 0x77,
(byte) 0x88, (byte) 0x88};
Ip6Address ip6Address =
new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8888");
assertThat(ip6Address.toOctets(), is(value1));
final byte[] value2 = new byte[] {0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00};
ip6Address = new Ip6Address("::");
assertThat(ip6Address.toOctets(), is(value2));
final byte[] value3 = new byte[] {(byte) 0xff, (byte) 0xff,
(byte) 0xff, (byte) 0xff,
(byte) 0xff, (byte) 0xff,
(byte) 0xff, (byte) 0xff,
(byte) 0xff, (byte) 0xff,
(byte) 0xff, (byte) 0xff,
(byte) 0xff, (byte) 0xff,
(byte) 0xff, (byte) 0xff};
ip6Address = new Ip6Address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
assertThat(ip6Address.toOctets(), is(value3));
}
/**
* Tests making a mask prefix for a given prefix length.
*/
@Test
public void testMakeMaskPrefix() {
Ip6Address ip6Address = Ip6Address.makeMaskPrefix(8);
assertThat(ip6Address.toString(), is("ff00::"));
ip6Address = Ip6Address.makeMaskPrefix(120);
assertThat(ip6Address.toString(),
is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00"));
ip6Address = Ip6Address.makeMaskPrefix(0);
assertThat(ip6Address.toString(), is("::"));
ip6Address = Ip6Address.makeMaskPrefix(128);
assertThat(ip6Address.toString(),
is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
ip6Address = Ip6Address.makeMaskPrefix(64);
assertThat(ip6Address.toString(), is("ffff:ffff:ffff:ffff::"));
}
/**
* Tests making of a masked address.
*/
@Test
public void testMakeMaskedAddress() {
Ip6Address ip6Address =
new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8885");
Ip6Address ip6AddressMasked =
Ip6Address.makeMaskedAddress(ip6Address, 8);
assertThat(ip6AddressMasked.toString(), is("1100::"));
ip6AddressMasked = Ip6Address.makeMaskedAddress(ip6Address, 120);
assertThat(ip6AddressMasked.toString(),
is("1111:2222:3333:4444:5555:6666:7777:8800"));
ip6AddressMasked = Ip6Address.makeMaskedAddress(ip6Address, 0);
assertThat(ip6AddressMasked.toString(), is("::"));
ip6AddressMasked = Ip6Address.makeMaskedAddress(ip6Address, 128);
assertThat(ip6AddressMasked.toString(),
is("1111:2222:3333:4444:5555:6666:7777:8885"));
ip6AddressMasked = Ip6Address.makeMaskedAddress(ip6Address, 64);
assertThat(ip6AddressMasked.toString(), is("1111:2222:3333:4444::"));
}
/**
* Tests getting the value of an address.
*/
@Test
public void testGetValue() {
Ip6Address ip6Address =
new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8888");
assertThat(ip6Address.getValueHigh(), is(0x1111222233334444L));
assertThat(ip6Address.getValueLow(), is(0x5555666677778888L));
ip6Address = new Ip6Address(0, 0);
assertThat(ip6Address.getValueHigh(), is(0L));
assertThat(ip6Address.getValueLow(), is(0L));
ip6Address = new Ip6Address(-1L, -1L);
assertThat(ip6Address.getValueHigh(), is(-1L));
assertThat(ip6Address.getValueLow(), is(-1L));
}
/**
* Tests equality of {@link Ip6Address}.
*/
@Test
public void testEquality() {
Ip6Address addr1 =
new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8888");
Ip6Address addr2 =
new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8888");
assertThat(addr1, is(addr2));
addr1 = new Ip6Address("::");
addr2 = new Ip6Address("::");
assertThat(addr1, is(addr2));
addr1 = new Ip6Address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
addr2 = new Ip6Address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
assertThat(addr1, is(addr2));
}
/**
* Tests non-equality of {@link Ip6Address}.
*/
@Test
public void testNonEquality() {
Ip6Address addr1 =
new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8888");
Ip6Address addr2 =
new Ip6Address("1111:2222:3333:4444:5555:6666:7777:888A");
Ip6Address addr3 = new Ip6Address("::");
Ip6Address addr4 =
new Ip6Address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
assertThat(addr1, is(not(addr2)));
assertThat(addr3, is(not(addr2)));
assertThat(addr4, is(not(addr2)));
}
/**
* Tests comparison of {@link Ip6Address}.
*/
@Test
public void testComparison() {
Ip6Address addr1 =
new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8888");
Ip6Address addr2 =
new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8888");
Ip6Address addr3 =
new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8887");
Ip6Address addr4 =
new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8889");
assertTrue(addr1.compareTo(addr2) == 0);
assertTrue(addr1.compareTo(addr3) > 0);
assertTrue(addr1.compareTo(addr4) < 0);
addr1 = new Ip6Address("ffff:2222:3333:4444:5555:6666:7777:8888");
addr2 = new Ip6Address("ffff:2222:3333:4444:5555:6666:7777:8888");
addr3 = new Ip6Address("ffff:2222:3333:4444:5555:6666:7777:8887");
addr4 = new Ip6Address("ffff:2222:3333:4444:5555:6666:7777:8889");
assertTrue(addr1.compareTo(addr2) == 0);
assertTrue(addr1.compareTo(addr3) > 0);
assertTrue(addr1.compareTo(addr4) < 0);
addr1 = new Ip6Address("ffff:2222:3333:4444:5555:6666:7777:8888");
addr2 = new Ip6Address("ffff:2222:3333:4444:5555:6666:7777:8888");
addr3 = new Ip6Address("ffff:2222:3333:4443:5555:6666:7777:8888");
addr4 = new Ip6Address("ffff:2222:3333:4445:5555:6666:7777:8888");
assertTrue(addr1.compareTo(addr2) == 0);
assertTrue(addr1.compareTo(addr3) > 0);
assertTrue(addr1.compareTo(addr4) < 0);
}
/**
* Tests object string representation.
*/
@Test
public void testToString() {
Ip6Address ip6Address =
new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8888");
assertThat(ip6Address.toString(),
is("1111:2222:3333:4444:5555:6666:7777:8888"));
ip6Address = new Ip6Address("1111::8888");
assertThat(ip6Address.toString(), is("1111::8888"));
ip6Address = new Ip6Address("1111::");
assertThat(ip6Address.toString(), is("1111::"));
ip6Address = new Ip6Address("::8888");
assertThat(ip6Address.toString(), is("::8888"));
ip6Address = new Ip6Address("::");
assertThat(ip6Address.toString(), is("::"));
ip6Address = new Ip6Address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
assertThat(ip6Address.toString(),
is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"));
}
}
package org.onlab.packet;
import org.junit.Test;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertThat;
import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
/**
* Tests for class {@link Ip6Prefix}.
*/
public class Ip6PrefixTest {
/**
* Tests the immutability of {@link Ip6Prefix}.
*/
@Test
public void testImmutable() {
assertThatClassIsImmutable(Ip6Prefix.class);
}
/**
* Tests default class constructor.
*/
@Test
public void testDefaultConstructor() {
Ip6Prefix ip6prefix = new Ip6Prefix();
assertThat(ip6prefix.toString(), is("::/0"));
}
/**
* Tests valid class copy constructor.
*/
@Test
public void testCopyConstructor() {
Ip6Prefix fromAddr = new Ip6Prefix("1100::/8");
Ip6Prefix ip6prefix = new Ip6Prefix(fromAddr);
assertThat(ip6prefix.toString(), is("1100::/8"));
fromAddr = new Ip6Prefix("::/0");
ip6prefix = new Ip6Prefix(fromAddr);
assertThat(ip6prefix.toString(), is("::/0"));
fromAddr =
new Ip6Prefix("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128");
ip6prefix = new Ip6Prefix(fromAddr);
assertThat(ip6prefix.toString(),
is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"));
}
/**
* Tests invalid class copy constructor for a null object to copy from.
*/
@Test(expected = NullPointerException.class)
public void testInvalidConstructorNullObject() {
Ip6Prefix fromAddr = null;
Ip6Prefix ip6prefix = new Ip6Prefix(fromAddr);
}
/**
* Tests valid class constructor for an address and prefix length.
*/
@Test
public void testConstructorForAddressAndPrefixLength() {
Ip6Prefix ip6prefix =
new Ip6Prefix(new Ip6Address("1100::"), (short) 8);
assertThat(ip6prefix.toString(), is("1100::/8"));
ip6prefix =
new Ip6Prefix(new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8885"),
(short) 8);
assertThat(ip6prefix.toString(), is("1100::/8"));
ip6prefix =
new Ip6Prefix(new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8800"),
(short) 120);
assertThat(ip6prefix.toString(),
is("1111:2222:3333:4444:5555:6666:7777:8800/120"));
ip6prefix = new Ip6Prefix(new Ip6Address("::"), (short) 0);
assertThat(ip6prefix.toString(), is("::/0"));
ip6prefix =
new Ip6Prefix(new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8885"),
(short) 128);
assertThat(ip6prefix.toString(),
is("1111:2222:3333:4444:5555:6666:7777:8885/128"));
ip6prefix =
new Ip6Prefix(new Ip6Address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"),
(short) 128);
assertThat(ip6prefix.toString(),
is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"));
ip6prefix =
new Ip6Prefix(new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8885"),
(short) 64);
assertThat(ip6prefix.toString(), is("1111:2222:3333:4444::/64"));
}
/**
* Tests valid class constructor for a string.
*/
@Test
public void testConstructorForString() {
Ip6Prefix ip6prefix = new Ip6Prefix("1100::/8");
assertThat(ip6prefix.toString(), is("1100::/8"));
ip6prefix = new Ip6Prefix("1111:2222:3333:4444:5555:6666:7777:8885/8");
assertThat(ip6prefix.toString(), is("1100::/8"));
ip6prefix =
new Ip6Prefix("1111:2222:3333:4444:5555:6666:7777:8800/120");
assertThat(ip6prefix.toString(),
is("1111:2222:3333:4444:5555:6666:7777:8800/120"));
ip6prefix = new Ip6Prefix("::/0");
assertThat(ip6prefix.toString(), is("::/0"));
ip6prefix =
new Ip6Prefix("1111:2222:3333:4444:5555:6666:7777:8885/128");
assertThat(ip6prefix.toString(),
is("1111:2222:3333:4444:5555:6666:7777:8885/128"));
ip6prefix = new Ip6Prefix("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128");
assertThat(ip6prefix.toString(),
is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"));
ip6prefix =
new Ip6Prefix("1111:2222:3333:4444:5555:6666:7777:8885/64");
assertThat(ip6prefix.toString(), is("1111:2222:3333:4444::/64"));
}
/**
* Tests invalid class constructor for a null string.
*/
@Test(expected = NullPointerException.class)
public void testInvalidConstructorNullString() {
String fromString = null;
Ip6Prefix ip6prefix = new Ip6Prefix(fromString);
}
/**
* Tests invalid class constructor for an empty string.
*/
@Test(expected = IllegalArgumentException.class)
public void testInvalidConstructors() {
// Check constructor for invalid ID: empty string
Ip6Prefix ip6prefix = new Ip6Prefix("");
}
/**
* Tests getting the value of an address.
*/
@Test
public void testGetValue() {
Ip6Prefix ip6prefix = new Ip6Prefix("1100::/8");
assertThat(ip6prefix.getAddress(), equalTo(new Ip6Address("1100::")));
assertThat(ip6prefix.getPrefixLen(), is((short) 8));
ip6prefix = new Ip6Prefix("1111:2222:3333:4444:5555:6666:7777:8885/8");
assertThat(ip6prefix.getAddress(), equalTo(new Ip6Address("1100::")));
assertThat(ip6prefix.getPrefixLen(), is((short) 8));
ip6prefix =
new Ip6Prefix("1111:2222:3333:4444:5555:6666:7777:8800/120");
assertThat(ip6prefix.getAddress(),
equalTo(new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8800")));
assertThat(ip6prefix.getPrefixLen(), is((short) 120));
ip6prefix = new Ip6Prefix("::/0");
assertThat(ip6prefix.getAddress(), equalTo(new Ip6Address("::")));
assertThat(ip6prefix.getPrefixLen(), is((short) 0));
ip6prefix =
new Ip6Prefix("1111:2222:3333:4444:5555:6666:7777:8885/128");
assertThat(ip6prefix.getAddress(),
equalTo(new Ip6Address("1111:2222:3333:4444:5555:6666:7777:8885")));
assertThat(ip6prefix.getPrefixLen(), is((short) 128));
ip6prefix =
new Ip6Prefix("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128");
assertThat(ip6prefix.getAddress(),
equalTo(new Ip6Address("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff")));
assertThat(ip6prefix.getPrefixLen(), is((short) 128));
ip6prefix =
new Ip6Prefix("1111:2222:3333:4444:5555:6666:7777:8885/64");
assertThat(ip6prefix.getAddress(),
equalTo(new Ip6Address("1111:2222:3333:4444::")));
assertThat(ip6prefix.getPrefixLen(), is((short) 64));
}
/**
* Tests equality of {@link Ip6Address}.
*/
@Test
public void testEquality() {
Ip6Prefix addr1net = new Ip6Prefix("1100::/8");
Ip6Prefix addr2net = new Ip6Prefix("1100::/8");
assertThat(addr1net, is(addr2net));
addr1net = new Ip6Prefix("1111:2222:3333:4444:5555:6666:7777:8885/8");
addr2net = new Ip6Prefix("1100::/8");
assertThat(addr1net, is(addr2net));
addr1net = new Ip6Prefix("::/0");
addr2net = new Ip6Prefix("::/0");
assertThat(addr1net, is(addr2net));
addr1net =
new Ip6Prefix("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128");
addr2net =
new Ip6Prefix("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128");
assertThat(addr1net, is(addr2net));
}
/**
* Tests non-equality of {@link Ip6Address}.
*/
@Test
public void testNonEquality() {
Ip6Prefix addr1net = new Ip6Prefix("1100::/8");
Ip6Prefix addr2net = new Ip6Prefix("1200::/8");
Ip6Prefix addr3net = new Ip6Prefix("1200::/12");
Ip6Prefix addr4net = new Ip6Prefix("::/0");
Ip6Prefix addr5net =
new Ip6Prefix("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128");
assertThat(addr1net, is(not(addr2net)));
assertThat(addr3net, is(not(addr2net)));
assertThat(addr4net, is(not(addr2net)));
assertThat(addr5net, is(not(addr2net)));
}
/**
* Tests object string representation.
*/
@Test
public void testToString() {
Ip6Prefix ip6prefix = new Ip6Prefix("1100::/8");
assertThat(ip6prefix.toString(), is("1100::/8"));
ip6prefix = new Ip6Prefix("1111:2222:3333:4444:5555:6666:7777:8885/8");
assertThat(ip6prefix.toString(), is("1100::/8"));
ip6prefix = new Ip6Prefix("::/0");
assertThat(ip6prefix.toString(), is("::/0"));
ip6prefix =
new Ip6Prefix("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128");
assertThat(ip6prefix.toString(),
is("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128"));
}
}