diff --git a/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceUniqueIndexTest.java b/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceUniqueIndexTest.java new file mode 100644 index 0000000000000000000000000000000000000000..c6c9c7329f3ea95204c744a4bd8ec16a2340ad19 --- /dev/null +++ b/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceUniqueIndexTest.java @@ -0,0 +1,167 @@ +/** +* Copyright 2012 Big Switch Networks, Inc. +* +* Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 +* +* 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 net.floodlightcontroller.devicemanager.internal; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.Iterator; + +import org.junit.Test; +import net.floodlightcontroller.devicemanager.IDeviceService.DeviceField; +import junit.framework.TestCase; + +/** + * + * @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 e4; + + @Override + protected void setUp() throws Exception { + super.setUp(); + e1a = new Entity(1L, (short)1, 1, 1L, 1, new Date()); + e1b = new Entity(1L, (short)2, 1, 1L, 1, new Date()); + List<Entity> d1Entities = new ArrayList<Entity>(2); + d1Entities.add(e1a); + d1Entities.add(e1b); + d1 = new Device(null, Long.valueOf(1), d1Entities, null); + + // e2 and e2 alt match in MAC and VLAN + e2 = new Entity(2L, (short)2, 2, 2L, 2, new Date()); + e2alt = new Entity(2, (short)2, null, null, null, null); + + // IP is null + e3 = new Entity(3L, (short)3, null, 3L, 3, new Date()); + + // IP and switch and port are null + e4 = new Entity(4L, (short)4, null, 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<Long> expected, Iterator<Long> it) { + HashSet<Long> actual = new HashSet<Long>(); + 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<Long> expectedKeys = new HashSet<Long>(); + expectedKeys.add(1L); + expectedKeys.add(2L); + verifyIterator(expectedKeys, idx1.getAll()); + + + //------------- + // Test queryByEntity() + verifyIterator(Collections.<Long>singleton(1L), + idx1.queryByEntity(e1a)); + verifyIterator(Collections.<Long>singleton(1L), + idx1.queryByEntity(e1b)); + verifyIterator(Collections.<Long>singleton(2L), + idx1.queryByEntity(e2)); + verifyIterator(Collections.<Long>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.SWITCH)); + // only one key field is null + idx2.updateIndex(e3, 3L); + assertEquals(Long.valueOf(3L), idx2.findByEntity(e3)); + e3.ipv4Address = 3; + assertEquals(null, idx2.findByEntity(e3)); + // all key fields are null + idx2.updateIndex(e4, 4L); + assertEquals(null, idx2.findByEntity(e4)); + Device d4 = new Device(null, 4L, Collections.<Entity>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)); + } +}