+ @Test
+ public void testAddDeleteQos() throws InterruptedException {
+ ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
+ OvsdbNodeAugmentation ovsdbNodeAugmentation;
+ Uri qosUri = new Uri("QOS-ROW");
+ List<String> typeList = new ArrayList<String>();
+ typeList.add(SouthboundConstants.QOS_LINUX_HTB);
+ typeList.add(SouthboundConstants.QOS_LINUX_HFSC);
+
+ for (String qosType : typeList) {
+ try (TestQos testQos = new TestQos(connectionInfo, qosUri, SouthboundMapper.createQosType(qosType), null, null)) {
+ ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
+ LogicalDatastoreType.OPERATIONAL);
+ QosEntries operQosHtb = getQos(qosUri, ovsdbNodeAugmentation);
+ Assert.assertNotNull(operQosHtb);
+ }
+ ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
+ LogicalDatastoreType.OPERATIONAL);
+ QosEntries operQosHtb = getQos(qosUri, ovsdbNodeAugmentation);
+ Assert.assertNull(operQosHtb);
+ }
+ }
+
+ @Test
+ public void testAddDeleteQueue() throws InterruptedException {
+ ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
+ Uri queueUri = new Uri("QUEUE-A1");
+
+ try (TestQueue testQueue = new TestQueue(connectionInfo, queueUri, new Short("25"), null, null)) {
+ OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
+ LogicalDatastoreType.OPERATIONAL);
+ Queues operQueue = getQueue(queueUri, ovsdbNodeAugmentation);
+ Assert.assertNotNull(operQueue);
+ }
+ OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
+ LogicalDatastoreType.OPERATIONAL);
+ Queues operQueue = getQueue(queueUri, ovsdbNodeAugmentation);
+ Assert.assertNull(operQueue);
+ }
+
+ private static class SouthboundQueuesExternalIdsHelper implements SouthboundQueueHelper<QueuesExternalIds> {
+ @Override
+ public void writeValues(QueuesBuilder builder, List<QueuesExternalIds> values) {
+ builder.setQueuesExternalIds(values);
+ }
+
+ @Override
+ public List<QueuesExternalIds> readValues(Queues queue) {
+ return queue.getQueuesExternalIds();
+ }
+ }
+
+ private static class SouthboundQueuesOtherConfigHelper implements SouthboundQueueHelper<QueuesOtherConfig> {
+ @Override
+ public void writeValues(QueuesBuilder builder, List<QueuesOtherConfig> values) {
+ builder.setQueuesOtherConfig(values);
+ }
+
+ @Override
+ public List<QueuesOtherConfig> readValues(Queues queue) {
+ return queue.getQueuesOtherConfig();
+ }
+ }
+
+ private interface SouthboundQueueHelper<T> {
+ void writeValues(QueuesBuilder builder, List<T> values);
+ List<T> readValues(Queues queue);
+ }
+
+ private Queues getQueue(Uri queueId, OvsdbNodeAugmentation node) {
+ for (Queues queue : node.getQueues()) {
+ if (queue.getKey().getQueueId().getValue().equals(queueId.getValue()))
+ return queue;
+ }
+ return null;
+ }
+
+ private static class SouthboundQosExternalIdsHelper implements SouthboundQosHelper<QosExternalIds> {
+ @Override
+ public void writeValues(QosEntriesBuilder builder, List<QosExternalIds> values) {
+ builder.setQosExternalIds(values);
+ }
+
+ @Override
+ public List<QosExternalIds> readValues(QosEntries qos) {
+ return qos.getQosExternalIds();
+ }
+ }
+
+ private static class SouthboundQosOtherConfigHelper implements SouthboundQosHelper<QosOtherConfig> {
+ @Override
+ public void writeValues(QosEntriesBuilder builder, List<QosOtherConfig> values) {
+ builder.setQosOtherConfig(values);
+ }
+
+ @Override
+ public List<QosOtherConfig> readValues(QosEntries qos) {
+ return qos.getQosOtherConfig();
+ }
+ }
+
+ private interface SouthboundQosHelper<T> {
+ void writeValues(QosEntriesBuilder builder, List<T> values);
+ List<T> readValues(QosEntries qos);
+ }
+
+ private QosEntries getQos(Uri qosId, OvsdbNodeAugmentation node) {
+ for (QosEntries qos : node.getQosEntries()) {
+ if (qos.getKey().getQosId().equals(qosId))
+ return qos;
+ }
+ return null;
+ }
+
+ private <T> void testCRUDQueue(
+ KeyValueBuilder<T> builder, String prefix, SouthboundQueueHelper<T> helper)
+ throws InterruptedException {
+
+ ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
+
+ // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after
+ // the update has been performed.
+ List<SouthboundTestCase<T>> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From");
+ List<SouthboundTestCase<T>> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To");
+
+ for (SouthboundTestCase<T> updateFromTestCase : updateFromTestCases) {
+ for (SouthboundTestCase<T> updateToTestCase : updateToTestCases) {
+ String testQueueId = String.format("%s_%s", prefix, updateToTestCase.name);
+
+ // CREATE: and update the test queue with starting values.
+ try (TestQueue testQueue = new TestQueue(connectionInfo, new Uri(testQueueId), new Short("45"), null, null)) {
+ QueuesBuilder queuesBuilder = new QueuesBuilder();
+ queuesBuilder.setQueueId(new Uri(testQueueId));
+ InstanceIdentifier<Queues> queueIid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
+ .augmentation(OvsdbNodeAugmentation.class)
+ .child(Queues.class, queuesBuilder.build().getKey());
+ final NotifyingDataChangeListener queueConfigurationListener =
+ new NotifyingDataChangeListener(LogicalDatastoreType.CONFIGURATION, queueIid);
+ queueConfigurationListener.registerDataChangeListener();
+ final NotifyingDataChangeListener queueOperationalListener =
+ new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, queueIid);
+ queueOperationalListener.registerDataChangeListener();
+
+ helper.writeValues(queuesBuilder, updateFromTestCase.inputValues);
+ Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
+ queueIid, queuesBuilder.build()));
+ queueConfigurationListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
+
+ // READ: Read the test queue and ensure changes are propagated to the CONFIGURATION data store,
+ // then repeat for OPERATIONAL data store
+ OvsdbNodeAugmentation updateFromConfigurationOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
+ LogicalDatastoreType.CONFIGURATION);
+ Queues queueFromConfig = getQueue(new Uri(testQueueId), updateFromConfigurationOvsdbNodeAugmentation);
+ if (queueFromConfig != null) {
+ List<T> updateFromConfigurationValues =
+ helper.readValues(queueFromConfig);
+ assertExpectedExist(updateFromTestCase.expectedValues, updateFromConfigurationValues);
+ }
+
+ queueOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
+ OvsdbNodeAugmentation updateFromOperationalOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
+ LogicalDatastoreType.OPERATIONAL);
+ Queues queueFromOper = getQueue(new Uri(testQueueId), updateFromOperationalOvsdbNodeAugmentation);
+ if (queueFromOper != null) {
+ List<T> updateFromOperationalValues =
+ helper.readValues(queueFromOper);
+ assertExpectedExist(updateFromTestCase.expectedValues, updateFromOperationalValues);
+ }
+
+ // UPDATE: update the values
+ QueuesBuilder queuesUpdateBuilder = new QueuesBuilder();
+ queuesUpdateBuilder.setQueueId(new Uri(testQueueId));
+ helper.writeValues(queuesUpdateBuilder, updateToTestCase.inputValues);
+ Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
+ queueIid, queuesUpdateBuilder.build()));
+ queueConfigurationListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
+
+ // READ: the test queue and ensure changes are propagated to the CONFIGURATION data store,
+ // then repeat for OPERATIONAL data store
+ OvsdbNodeAugmentation updateToConfigurationOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
+ LogicalDatastoreType.CONFIGURATION);
+ Queues queueToConfig = getQueue(new Uri(testQueueId), updateToConfigurationOvsdbNodeAugmentation);
+ if (queueToConfig != null) {
+ List<T> updateToConfigurationValues =
+ helper.readValues(queueToConfig);
+ assertExpectedExist(updateToTestCase.expectedValues, updateToConfigurationValues);
+ }
+
+ queueOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
+ OvsdbNodeAugmentation updateToOperationalOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
+ LogicalDatastoreType.OPERATIONAL);
+ Queues queueToOper = getQueue(new Uri(testQueueId), updateToOperationalOvsdbNodeAugmentation);
+ if (queueToOper != null) {
+ List<T> updateToOperationalValues =
+ helper.readValues(queueToOper);
+ assertExpectedExist(updateToTestCase.expectedValues, updateToOperationalValues);
+ }
+
+ // DELETE handled by TestQueue
+ }
+ }
+ }
+ }
+
+ @Test
+ public void testCRUDQueueExternalIds() throws InterruptedException {
+ testCRUDQueue(new SouthboundQueuesExternalIdsBuilder(), "QueueExternalIds",
+ new SouthboundQueuesExternalIdsHelper());
+ }
+
+ @Test
+ public void testCRUDQueueOtherConfig() throws InterruptedException {
+ testCRUDQueue(new SouthboundQueuesOtherConfigBuilder(), "QueueOtherConfig",
+ new SouthboundQueuesOtherConfigHelper());
+ }
+
+ @Test
+ public void testCRUDQueueDscp() throws InterruptedException {
+ ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
+ String testQueueId = "testQueueDscp";
+
+ // CREATE: and update the test queue with starting values.
+ try (TestQueue testQueue = new TestQueue(connectionInfo, new Uri(testQueueId), new Short("0"), null, null)) {
+ for (Short dscp = 1; dscp < 64; dscp++) {
+ QueuesBuilder queuesBuilder = new QueuesBuilder();
+ queuesBuilder.setQueueId(new Uri(testQueueId));
+ InstanceIdentifier<Queues> queueIid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
+ .augmentation(OvsdbNodeAugmentation.class)
+ .child(Queues.class, queuesBuilder.build().getKey());
+ final NotifyingDataChangeListener queueOperationalListener =
+ new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, queueIid);
+ queueOperationalListener.registerDataChangeListener();
+
+ queuesBuilder.setDscp(dscp);
+ Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
+ queueIid, queuesBuilder.build()));
+ queueOperationalListener.waitForUpdate(OVSDB_ROUNDTRIP_TIMEOUT);
+
+ // READ: Read the test queue and ensure changes are propagated to the OPERATIONAL data store
+ // assumption is that CONFIGURATION was updated if OPERATIONAL is correct
+ OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
+ LogicalDatastoreType.OPERATIONAL);
+ Queues operQueue = getQueue(new Uri(testQueueId), ovsdbNodeAugmentation);
+ Assert.assertNotNull(operQueue);
+ Short operDscp = operQueue.getDscp();
+ Assert.assertNotNull(operDscp);
+ Assert.assertEquals(dscp, operDscp);
+ }
+
+ // DELETE handled by TestQueue
+ }
+
+ }
+
+ private <T> void testCRUDQos(
+ KeyValueBuilder<T> builder, String prefix, SouthboundQosHelper<T> helper)
+ throws InterruptedException {
+
+ ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
+
+ // updateFromTestCases represent the original test case value. updateToTestCases represent the new value after
+ // the update has been performed.
+ List<SouthboundTestCase<T>> updateFromTestCases = generateKeyValueTestCases(builder, prefix + "From");
+ List<SouthboundTestCase<T>> updateToTestCases = generateKeyValueTestCases(builder, prefix + "To");
+
+ for (SouthboundTestCase<T> updateFromTestCase : updateFromTestCases) {
+ for (SouthboundTestCase<T> updateToTestCase : updateToTestCases) {
+ String testQosId = String.format("%s_%s", prefix, updateToTestCase.name);
+
+ // CREATE: and update the test qos with starting values.
+ try (TestQos testQos = new TestQos(connectionInfo, new Uri(testQosId), SouthboundMapper.createQosType(SouthboundConstants.QOS_LINUX_HTB), null, null)) {
+ QosEntriesBuilder qosBuilder = new QosEntriesBuilder();
+ qosBuilder.setQosId(new Uri(testQosId));
+ InstanceIdentifier<QosEntries> qosIid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
+ .augmentation(OvsdbNodeAugmentation.class)
+ .child(QosEntries.class, qosBuilder.build().getKey());
+ final NotifyingDataChangeListener qosConfigurationListener =
+ new NotifyingDataChangeListener(LogicalDatastoreType.CONFIGURATION, qosIid);
+ qosConfigurationListener.registerDataChangeListener();
+ final NotifyingDataChangeListener qosOperationalListener =
+ new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, qosIid);
+ qosOperationalListener.registerDataChangeListener();
+
+ helper.writeValues(qosBuilder, updateFromTestCase.inputValues);
+ Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
+ qosIid, qosBuilder.build()));
+ qosConfigurationListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
+
+ // READ: Read the test queue and ensure changes are propagated to the CONFIGURATION data store,
+ // then repeat for OPERATIONAL data store
+ OvsdbNodeAugmentation updateFromConfigurationOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
+ LogicalDatastoreType.CONFIGURATION);
+ QosEntries qosFromConfig = getQos(new Uri(testQosId), updateFromConfigurationOvsdbNodeAugmentation);
+ if (qosFromConfig != null) {
+ List<T> updateFromConfigurationValues =
+ helper.readValues(qosFromConfig);
+ assertExpectedExist(updateFromTestCase.expectedValues, updateFromConfigurationValues);
+ }
+
+ qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
+ OvsdbNodeAugmentation updateFromOperationalOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
+ LogicalDatastoreType.OPERATIONAL);
+ QosEntries qosFromOper = getQos(new Uri(testQosId), updateFromOperationalOvsdbNodeAugmentation);
+ if (qosFromOper != null) {
+ List<T> updateFromOperationalValues =
+ helper.readValues(qosFromOper);
+ assertExpectedExist(updateFromTestCase.expectedValues, updateFromOperationalValues);
+ }
+
+ // UPDATE: update the values
+ QosEntriesBuilder qosUpdateBuilder = new QosEntriesBuilder();
+ qosUpdateBuilder.setQosId(new Uri(testQosId));
+ helper.writeValues(qosUpdateBuilder, updateToTestCase.inputValues);
+ Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
+ qosIid, qosUpdateBuilder.build()));
+ qosConfigurationListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
+
+ // READ: the test queue and ensure changes are propagated to the CONFIGURATION data store,
+ // then repeat for OPERATIONAL data store
+ OvsdbNodeAugmentation updateToConfigurationOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
+ LogicalDatastoreType.CONFIGURATION);
+ QosEntries qosToConfig = getQos(new Uri(testQosId), updateToConfigurationOvsdbNodeAugmentation);
+ if (qosToConfig != null) {
+ List<T> updateToConfigurationValues =
+ helper.readValues(qosToConfig);
+ assertExpectedExist(updateToTestCase.expectedValues, updateToConfigurationValues);
+ }
+
+ qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
+ OvsdbNodeAugmentation updateToOperationalOvsdbNodeAugmentation = getOvsdbNode(connectionInfo,
+ LogicalDatastoreType.OPERATIONAL);
+ QosEntries qosToOper = getQos(new Uri(testQosId), updateToOperationalOvsdbNodeAugmentation);
+ if (qosToOper != null) {
+ List<T> updateToOperationalValues =
+ helper.readValues(qosToOper);
+ assertExpectedExist(updateToTestCase.expectedValues, updateToOperationalValues);
+ }
+
+ // DELETE handled by TestQueue
+ }
+ }
+ }
+ }
+
+ @Test
+ public void testCRUDQosExternalIds() throws InterruptedException {
+ testCRUDQos(new SouthboundQosExternalIdsBuilder(), "QosExternalIds",
+ new SouthboundQosExternalIdsHelper());
+ }
+
+ @Test
+ public void testCRUDQosOtherConfig() throws InterruptedException {
+ testCRUDQos(new SouthboundQosOtherConfigBuilder(), "QosOtherConfig",
+ new SouthboundQosOtherConfigHelper());
+ }
+ @Test
+ public void testCRUDQosQueues() throws InterruptedException {
+ ConnectionInfo connectionInfo = getConnectionInfo(addressStr, portNumber);
+ String testQosId = "testQosQueues";
+
+ // CREATE: and update the test queue with starting values.
+ try (TestQos testQos = new TestQos(connectionInfo, new Uri(testQosId),
+ SouthboundMapper.createQosType(SouthboundConstants.QOS_LINUX_HTB), null, null);
+ TestQueue testQueue1 = new TestQueue(connectionInfo, new Uri("queue1"), new Short("12"), null, null);
+ TestQueue testQueue2 = new TestQueue(connectionInfo, new Uri("queue2"), new Short("35"), null, null)) {
+ QosEntriesBuilder qosBuilder = new QosEntriesBuilder();
+ qosBuilder.setQosId(new Uri(testQosId));
+ InstanceIdentifier<QosEntries> qosIid = SouthboundUtils.createInstanceIdentifier(connectionInfo)
+ .augmentation(OvsdbNodeAugmentation.class)
+ .child(QosEntries.class, qosBuilder.build().getKey());
+ final NotifyingDataChangeListener qosOperationalListener =
+ new NotifyingDataChangeListener(LogicalDatastoreType.OPERATIONAL, qosIid);
+ qosOperationalListener.registerDataChangeListener();
+
+ // READ, UPDATE: Read the UUIDs of the Queue rows and add them to the
+ // configuration of the Qos row.
+ OvsdbNodeAugmentation ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
+ LogicalDatastoreType.OPERATIONAL);
+ Queues operQueue1 = getQueue(new Uri("queue1"), ovsdbNodeAugmentation);
+ Assert.assertNotNull(operQueue1);
+ Uuid queue1Uuid = new Uuid(operQueue1.getQueueUuid().getValue());
+ Queues operQueue2 = getQueue(new Uri("queue2"), ovsdbNodeAugmentation);
+ Assert.assertNotNull(operQueue2);
+ Uuid queue2Uuid = new Uuid(operQueue2.getQueueUuid().getValue());
+
+ List<QueueList> queueList = new ArrayList<>();
+ queueList.add(new QueueListBuilder().setQueueNumber(new Long("0"))
+ .setQueueUuid(queue1Uuid).build());
+ queueList.add(new QueueListBuilder().setQueueNumber(new Long("1"))
+ .setQueueUuid(queue2Uuid).build());
+ qosBuilder.setQueueList(queueList);
+
+ Assert.assertTrue(mdsalUtils.merge(LogicalDatastoreType.CONFIGURATION,
+ qosIid, qosBuilder.build()));
+ qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
+
+ // READ: Read the test qos and ensure changes are propagated to the OPERATIONAL data store
+ // assumption is that CONFIGURATION was updated if OPERATIONAL is correct
+ ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
+ LogicalDatastoreType.OPERATIONAL);
+ QosEntries operQos = getQos(new Uri(testQosId), ovsdbNodeAugmentation);
+ Assert.assertNotNull(operQos);
+ List<QueueList> operQueueList = operQos.getQueueList();
+ Assert.assertNotNull(operQueueList);
+ for (QueueList queueEntry : queueList) {
+ Assert.assertTrue(isQueueInList(operQueueList, queueEntry));
+ }
+
+ // DELETE one queue from queue list and check that one remains
+ KeyedInstanceIdentifier<QueueList, QueueListKey> qosQueueIid = qosIid
+ .child(QueueList.class, new QueueListKey(new Long("0")));
+ Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, qosQueueIid));
+ qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
+
+ // READ: Read the test qos and ensure changes are propagated to the OPERATIONAL data store
+ // assumption is that CONFIGURATION was updated if OPERATIONAL is correct
+ ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
+ LogicalDatastoreType.OPERATIONAL);
+ operQos = getQos(new Uri(testQosId), ovsdbNodeAugmentation);
+ Assert.assertNotNull(operQos);
+ operQueueList = operQos.getQueueList();
+ Assert.assertNotNull(operQueueList);
+ for (QueueList queueEntry : queueList) {
+ if (queueEntry.getQueueUuid().equals(queue2Uuid)) {
+ Assert.assertTrue(isQueueInList(operQueueList, queueEntry));
+ } else if (queueEntry.getQueueUuid().equals(queue1Uuid)) {
+ Assert.assertFalse(isQueueInList(operQueueList, queueEntry));
+ } else {
+ Assert.assertTrue("Unknown queue entry in qos queue list", false);
+ }
+ }
+
+ // DELETE queue list and check that list is empty
+ qosQueueIid = qosIid
+ .child(QueueList.class, new QueueListKey(new Long("1")));
+ Assert.assertTrue(mdsalUtils.delete(LogicalDatastoreType.CONFIGURATION, qosQueueIid));
+ qosOperationalListener.waitForUpdate(OVSDB_UPDATE_TIMEOUT);
+
+ ovsdbNodeAugmentation = getOvsdbNode(connectionInfo,
+ LogicalDatastoreType.OPERATIONAL);
+ operQos = getQos(new Uri(testQosId), ovsdbNodeAugmentation);
+ Assert.assertNotNull(operQos);
+ operQueueList = operQos.getQueueList();
+ Assert.assertNotNull(operQueueList);
+ Assert.assertTrue(operQueueList.isEmpty());
+ }
+ }
+
+ private Boolean isQueueInList(List<QueueList> queueList, QueueList queue) {
+ for (QueueList queueEntry : queueList) {
+ if (queueEntry.getQueueNumber().equals(queue.getQueueNumber())
+ && queueEntry.getQueueUuid().equals(queue.getQueueUuid())) {
+ return true;
+ }
+ }
+ return false;
+ }
+