package net.floodlightcontroller.util; import static org.junit.Assert.*; import java.util.EnumSet; import org.junit.Test; import net.floodlightcontroller.util.EnumBitmaps.BitmapableEnum; public class EnumBitmapsTest { private enum ColorEnum implements BitmapableEnum { RED (1 << 0), GREEN (1 << 1), BLUE ( 1 << 3); // note (1<<2) is missing private int value; private ColorEnum(int value) { this.value = value; } @Override public int getValue() { return value; } } private enum ExtremeEnum implements BitmapableEnum { SMALL (1 << 0), BIG ( 1 << 31); private int value; private ExtremeEnum(int value) { this.value = value; } @Override public int getValue() { return value; } } private enum InvalidEnum implements BitmapableEnum { FOO_VALID (0x1), BAR_INVALID (0x6); // Error: more than one bit set private int value; private InvalidEnum(int value) { this.value = value; } @Override public int getValue() { return value; } } private enum InvalidEnum2 implements BitmapableEnum { FOOFOO_INVALID (0x0), // error: no bit set BARBAR_VALID (0x1); private int value; private InvalidEnum2(int value) { this.value = value; } @Override public int getValue() { return value; } } @Test public void testNormalBehavior() { EnumSet<ColorEnum> set = null; int bitmap = 0; // With color enum. bitmap = 0; set = EnumBitmaps.toEnumSet(ColorEnum.class, bitmap); assertEquals(EnumSet.noneOf(ColorEnum.class), set); assertEquals(bitmap, EnumBitmaps.toBitmap(set)); bitmap = ColorEnum.RED.getValue(); set = EnumBitmaps.toEnumSet(ColorEnum.class, bitmap); assertEquals(EnumSet.of(ColorEnum.RED), set); assertEquals(bitmap, EnumBitmaps.toBitmap(set)); bitmap = ColorEnum.BLUE.getValue(); set = EnumBitmaps.toEnumSet(ColorEnum.class, bitmap); assertEquals(EnumSet.of(ColorEnum.BLUE), set); assertEquals(bitmap, EnumBitmaps.toBitmap(set)); bitmap = ColorEnum.RED.getValue() | ColorEnum.GREEN.getValue(); set = EnumBitmaps.toEnumSet(ColorEnum.class, bitmap); assertEquals(EnumSet.of(ColorEnum.RED, ColorEnum.GREEN), set); assertEquals(bitmap, EnumBitmaps.toBitmap(set)); bitmap = ColorEnum.RED.getValue() | ColorEnum.GREEN.getValue() | ColorEnum.BLUE.getValue(); set = EnumBitmaps.toEnumSet(ColorEnum.class, bitmap); assertEquals(EnumSet.of(ColorEnum.RED, ColorEnum.GREEN, ColorEnum.BLUE), set); assertEquals(bitmap, EnumBitmaps.toBitmap(set)); assertEquals(0xb, EnumBitmaps.getMask(ColorEnum.class)); // with extreme enum. Make sure 1 << 31 is handled correctly bitmap = 1 << 31; EnumSet<ExtremeEnum> extremeSet = EnumBitmaps.toEnumSet(ExtremeEnum.class, bitmap); assertEquals(EnumSet.of(ExtremeEnum.BIG), extremeSet); assertEquals(bitmap, EnumBitmaps.toBitmap(extremeSet)); bitmap = (1 << 31) | (1 << 0); extremeSet = EnumBitmaps.toEnumSet(ExtremeEnum.class, bitmap); assertEquals(EnumSet.of(ExtremeEnum.BIG, ExtremeEnum.SMALL), extremeSet); assertEquals(bitmap, EnumBitmaps.toBitmap(extremeSet)); assertEquals(0x80000001, EnumBitmaps.getMask(ExtremeEnum.class)); // there are some cases were InvalidEnum's can actually be used. // It's fine if a developer chooses to change the behavior and make // the cases below fail! EnumSet<InvalidEnum> s1 = EnumSet.of(InvalidEnum.FOO_VALID); assertEquals(InvalidEnum.FOO_VALID.getValue(), EnumBitmaps.toBitmap(s1)); EnumSet<InvalidEnum2> s2 = EnumSet.of(InvalidEnum2.BARBAR_VALID); assertEquals(InvalidEnum2.BARBAR_VALID.getValue(), EnumBitmaps.toBitmap(s2)); } @Test public void testExceptions() { // Exception when using an invalid enum try { EnumBitmaps.toEnumSet(InvalidEnum.class, 0); fail("Expected exception not thrown"); } catch (IllegalArgumentException e) { } try { EnumBitmaps.toEnumSet(InvalidEnum.class, 1); fail("Expected exception not thrown"); } catch (IllegalArgumentException e) { } try { EnumBitmaps.getMask(InvalidEnum.class); fail("Expected exception not thrown"); } catch (IllegalArgumentException e) { } try { EnumSet<InvalidEnum> set = EnumSet.allOf(InvalidEnum.class); EnumBitmaps.toBitmap(set); fail("Expected exception not thrown"); } catch (IllegalArgumentException e) { } try { EnumSet<InvalidEnum> set = EnumSet.of(InvalidEnum.BAR_INVALID); EnumBitmaps.toBitmap(set); fail("Expected exception not thrown"); } catch (IllegalArgumentException e) { } // Again with a different one // Exception when using an invalid enum try { EnumBitmaps.toEnumSet(InvalidEnum2.class, 0); fail("Expected exception not thrown"); } catch (IllegalArgumentException e) { } try { EnumBitmaps.toEnumSet(InvalidEnum2.class, 1); fail("Expected exception not thrown"); } catch (IllegalArgumentException e) { } try { EnumBitmaps.getMask(InvalidEnum2.class); fail("Expected exception not thrown"); } catch (IllegalArgumentException e) { } try { EnumSet<InvalidEnum2> set = EnumSet.allOf(InvalidEnum2.class); EnumBitmaps.toBitmap(set); fail("Expected exception not thrown"); } catch (IllegalArgumentException e) { } try { EnumSet<InvalidEnum2> set = EnumSet.of(InvalidEnum2.FOOFOO_INVALID); EnumBitmaps.toBitmap(set); fail("Expected exception not thrown"); } catch (IllegalArgumentException e) { } // NPEs try { EnumBitmaps.<ColorEnum>toEnumSet(null, 0); fail("Expected exception not thrown"); } catch (NullPointerException e) { } try { EnumBitmaps.<ColorEnum>getMask(null); fail("Expected exception not thrown"); } catch (NullPointerException e) { } try { EnumBitmaps.<ColorEnum>toBitmap(null); fail("Expected exception not thrown"); } catch (NullPointerException e) { } // Bits set that aren't covered by the enum try { EnumBitmaps.<ColorEnum>toEnumSet(ColorEnum.class, 1 << 23); fail("Expected exception not thrown"); } catch(IllegalArgumentException e) { } } }