/* * Copyright (c) 2012 Big Switch Networks, Inc. * * Licensed under the Eclipse Public License, Version 1.0 (the * "License"); you may not use this file except in compliance with the * License. You may obtain a copy of the License at * * http://www.eclipse.org/legal/epl-v10.html * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.opendaylight.controller.hosttracker.internal; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.EnumSet; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import junit.framework.TestCase; import org.junit.Test; import org.opendaylight.controller.hosttracker.Entity; import org.opendaylight.controller.hosttracker.IDeviceService.DeviceField; import org.opendaylight.controller.sal.core.Node; import org.opendaylight.controller.sal.core.NodeConnector; import org.opendaylight.controller.sal.core.NodeConnector.NodeConnectorIDType; /** * * @author gregor * */ public class DeviceUniqueIndexTest extends TestCase { protected Entity e1a; protected Entity e1b; protected Device d1; protected Entity e2; protected Entity e2alt; protected Entity e3; protected Entity e3_ip; protected Entity e4; @Override protected void setUp() throws Exception { super.setUp(); Node n1 = new Node(Node.NodeIDType.OPENFLOW, Long.valueOf(1L)); NodeConnector n1_1 = new NodeConnector(NodeConnectorIDType.OPENFLOW, Short.valueOf((short) 1), n1); e1a = new Entity(1L, (short) 1, 1, n1_1, new Date()); e1b = new Entity(1L, (short) 2, 1, n1_1, new Date()); List d1Entities = new ArrayList(2); d1Entities.add(e1a); d1Entities.add(e1b); d1 = new Device(null, Long.valueOf(1), null, null, null, d1Entities, null); Node n2 = new Node(Node.NodeIDType.OPENFLOW, Long.valueOf(2L)); NodeConnector n2_2 = new NodeConnector(NodeConnectorIDType.OPENFLOW, Short.valueOf((short) 2), n2); Node n3 = new Node(Node.NodeIDType.OPENFLOW, Long.valueOf(3L)); NodeConnector n3_3 = new NodeConnector(NodeConnectorIDType.OPENFLOW, Short.valueOf((short) 3), n3); // e2 and e2 alt match in MAC and VLAN e2 = new Entity(2L, (short) 2, 2, n2_2, new Date()); e2alt = new Entity(2, (short) 2, null, null, null); // IP is null e3 = new Entity(3L, (short) 3, null, n3_3, new Date()); e3_ip = new Entity(3L, (short) 3, 3, n3_3, new Date()); // IP and switch and port are null e4 = new Entity(4L, (short) 4, null, null, new Date()); } /* * Checks that the iterator it returns the elements in the Set expected * Doesn't check how often an element is returned as long it's at least once */ protected void verifyIterator(Set expected, Iterator it) { HashSet actual = new HashSet(); while (it.hasNext()) { actual.add(it.next()); } assertEquals(expected, actual); } @Test public void testDeviceUniqueIndex() { DeviceUniqueIndex idx1 = new DeviceUniqueIndex(EnumSet.of( DeviceField.MAC, DeviceField.VLAN)); idx1.updateIndex(d1, d1.getDeviceKey()); idx1.updateIndex(e2, 2L); // ------------- // Test findByEntity lookups assertEquals(Long.valueOf(1L), idx1.findByEntity(e1a)); assertEquals(Long.valueOf(1L), idx1.findByEntity(e1b)); assertEquals(Long.valueOf(2L), idx1.findByEntity(e2)); // we didn't add e2alt but since they key fields are the same we // should find it assertEquals(Long.valueOf(2L), idx1.findByEntity(e2alt)); assertEquals(null, idx1.findByEntity(e3)); assertEquals(null, idx1.findByEntity(e4)); // ------------- // Test getAll() HashSet expectedKeys = new HashSet(); expectedKeys.add(1L); expectedKeys.add(2L); verifyIterator(expectedKeys, idx1.getAll()); // ------------- // Test queryByEntity() verifyIterator(Collections. singleton(1L), idx1.queryByEntity(e1a)); verifyIterator(Collections. singleton(1L), idx1.queryByEntity(e1b)); verifyIterator(Collections. singleton(2L), idx1.queryByEntity(e2)); verifyIterator(Collections. singleton(2L), idx1.queryByEntity(e2alt)); assertEquals(false, idx1.queryByEntity(e3).hasNext()); assertEquals(false, idx1.queryByEntity(e3).hasNext()); // ------------- // Test removal idx1.removeEntity(e1a, 42L); // No-op. e1a isn't mapped to this key assertEquals(Long.valueOf(1L), idx1.findByEntity(e1a)); idx1.removeEntity(e1a, 1L); assertEquals(null, idx1.findByEntity(e1a)); assertEquals(Long.valueOf(1L), idx1.findByEntity(e1b)); assertEquals(Long.valueOf(2L), idx1.findByEntity(e2)); idx1.removeEntity(e2); assertEquals(null, idx1.findByEntity(e2)); assertEquals(Long.valueOf(1L), idx1.findByEntity(e1b)); // ------------- // Test null keys DeviceUniqueIndex idx2 = new DeviceUniqueIndex(EnumSet.of( DeviceField.IPV4, DeviceField.SWITCHPORT)); // only one key field is null idx2.updateIndex(e3, 3L); assertEquals(Long.valueOf(3L), idx2.findByEntity(e3)); assertEquals(null, idx2.findByEntity(e3_ip)); // all key fields are null idx2.updateIndex(e4, 4L); assertEquals(null, idx2.findByEntity(e4)); Device d4 = new Device(null, 4L, null, null, null, Collections. singleton(e4), null); idx2.updateIndex(d4, 4L); assertEquals(null, idx2.findByEntity(e4)); // ------------- // entity already exists with different deviceKey DeviceUniqueIndex idx3 = new DeviceUniqueIndex(EnumSet.of( DeviceField.MAC, DeviceField.VLAN)); idx3.updateIndex(e1a, 42L); assertEquals(false, idx3.updateIndex(d1, 1L)); // TODO: shouldn't this fail as well so that the behavior // is consistent? idx3.updateIndex(e1a, 1L); // anyways. We can now add d1 ;-) assertEquals(true, idx3.updateIndex(d1, 1L)); } }