### Question:
MeterPool { @TransactionRequired public MeterId allocate(SwitchId switchId, String flowId, PathId pathId) { MeterId nextMeter = nextMeters.get(switchId); if (nextMeter != null && nextMeter.getValue() > 0) { if (nextMeter.compareTo(maxMeterId) <= 0 && !flowMeterRepository.exists(switchId, nextMeter)) { addMeter(flowId, pathId, switchId, nextMeter); nextMeters.put(switchId, new MeterId(nextMeter.getValue() + 1)); return nextMeter; } else { nextMeters.remove(switchId); } } if (!nextMeters.containsKey(switchId)) { long numOfPools = (maxMeterId.getValue() - minMeterId.getValue()) / poolSize; if (numOfPools > 1) { long poolToTake = Math.abs(new Random().nextInt()) % numOfPools; Optional<MeterId> availableMeter = flowMeterRepository.findFirstUnassignedMeter(switchId, new MeterId(minMeterId.getValue() + poolToTake * poolSize), new MeterId(minMeterId.getValue() + (poolToTake + 1) * poolSize - 1)); if (availableMeter.isPresent()) { nextMeter = availableMeter.get(); addMeter(flowId, pathId, switchId, nextMeter); nextMeters.put(switchId, new MeterId(nextMeter.getValue() + 1)); return nextMeter; } } nextMeter = new MeterId(-1); nextMeters.put(switchId, nextMeter); } if (nextMeter != null && nextMeter.getValue() == -1) { Optional<MeterId> availableMeter = flowMeterRepository.findFirstUnassignedMeter(switchId, minMeterId, maxMeterId); if (availableMeter.isPresent()) { nextMeter = availableMeter.get(); addMeter(flowId, pathId, switchId, nextMeter); nextMeters.put(switchId, new MeterId(nextMeter.getValue() + 1)); return nextMeter; } } throw new ResourceNotAvailableException(format("No meter available for switch %s", switchId)); } MeterPool(PersistenceManager persistenceManager, MeterId minMeterId, MeterId maxMeterId, int poolSize); @TransactionRequired MeterId allocate(SwitchId switchId, String flowId, PathId pathId); void deallocate(PathId... pathIds);  }### Answer:
@Test(expected = ResourceNotAvailableException.class) public void meterPoolFullTest() { transactionManager.doInTransaction(() -> { for (long i = MIN_METER_ID.getValue(); i <= MAX_METER_ID.getValue() + 1; i++) { meterPool.allocate(SWITCH_ID, format("flow_%d", i), new PathId(format("path_%d", i))); } }); }
@Ignore("InMemoryGraph doesn't enforce constraint") @Test(expected = ConstraintViolationException.class) public void createTwoMeterForOnePathTest() { transactionManager.doInTransaction(() -> { long first = meterPool.allocate(SWITCH_ID, FLOW_1, PATH_ID_1).getValue(); long second = meterPool.allocate(SWITCH_ID, FLOW_1, PATH_ID_1).getValue(); }); }