@Test
  public final void testUpdatePortStatus() {
    putDevice(DID1, SW1);
    List<PortDescription> pds =
        Arrays.<PortDescription>asList(new DefaultPortDescription(P1, true));
    deviceStore.updatePorts(PID, DID1, pds);

    Capture<InternalPortStatusEvent> message = new Capture<>();
    Capture<MessageSubject> subject = new Capture<>();
    Capture<Function<InternalPortStatusEvent, byte[]>> encoder = new Capture<>();

    resetCommunicatorExpectingSingleBroadcast(message, subject, encoder);
    final DefaultPortDescription desc = new DefaultPortDescription(P1, false);
    DeviceEvent event = deviceStore.updatePortStatus(PID, DID1, desc);
    assertEquals(PORT_UPDATED, event.type());
    assertDevice(DID1, SW1, event.subject());
    assertEquals(P1, event.port().number());
    assertFalse("Port is disabled", event.port().isEnabled());
    verify(clusterCommunicator);
    assertInternalPortStatusEvent(NID1, DID1, PID, desc, NO_ANNOTATION, message, subject, encoder);
    assertTrue(message.hasCaptured());
  }
  @Test
  public final void testUpdatePortStatusAncillary() throws IOException {
    putDeviceAncillary(DID1, SW1);
    putDevice(DID1, SW1);
    List<PortDescription> pds =
        Arrays.<PortDescription>asList(new DefaultPortDescription(P1, true, A1));
    deviceStore.updatePorts(PID, DID1, pds);

    Capture<InternalPortStatusEvent> message = new Capture<>();
    Capture<MessageSubject> subject = new Capture<>();
    Capture<Function<InternalPortStatusEvent, byte[]>> encoder = new Capture<>();

    // update port from primary
    resetCommunicatorExpectingSingleBroadcast(message, subject, encoder);

    final DefaultPortDescription desc1 = new DefaultPortDescription(P1, false, A1_2);
    DeviceEvent event = deviceStore.updatePortStatus(PID, DID1, desc1);
    assertEquals(PORT_UPDATED, event.type());
    assertDevice(DID1, SW1, event.subject());
    assertEquals(P1, event.port().number());
    assertAnnotationsEquals(event.port().annotations(), A1, A1_2);
    assertFalse("Port is disabled", event.port().isEnabled());
    verify(clusterCommunicator);
    assertInternalPortStatusEvent(
        NID1, DID1, PID, desc1, asList(A1, A1_2), message, subject, encoder);
    assertTrue(message.hasCaptured());

    // update port from ancillary with no attributes
    resetCommunicatorExpectingNoBroadcast(message, subject, encoder);
    final DefaultPortDescription desc2 = new DefaultPortDescription(P1, true);
    DeviceEvent event2 = deviceStore.updatePortStatus(PIDA, DID1, desc2);
    assertNull("Ancillary is ignored if primary exists", event2);
    verify(clusterCommunicator);
    assertFalse(message.hasCaptured());

    // but, Ancillary annotation update will be notified
    resetCommunicatorExpectingSingleBroadcast(message, subject, encoder);
    final DefaultPortDescription desc3 = new DefaultPortDescription(P1, true, A2);
    DeviceEvent event3 = deviceStore.updatePortStatus(PIDA, DID1, desc3);
    assertEquals(PORT_UPDATED, event3.type());
    assertDevice(DID1, SW1, event3.subject());
    assertEquals(P1, event3.port().number());
    assertAnnotationsEquals(event3.port().annotations(), A1, A1_2, A2);
    assertFalse("Port is disabled", event3.port().isEnabled());
    verify(clusterCommunicator);
    assertInternalPortStatusEvent(NID1, DID1, PIDA, desc3, asList(A2), message, subject, encoder);
    assertTrue(message.hasCaptured());

    // port only reported from Ancillary will be notified as down
    resetCommunicatorExpectingSingleBroadcast(message, subject, encoder);
    final DefaultPortDescription desc4 = new DefaultPortDescription(P2, true);
    DeviceEvent event4 = deviceStore.updatePortStatus(PIDA, DID1, desc4);
    assertEquals(PORT_ADDED, event4.type());
    assertDevice(DID1, SW1, event4.subject());
    assertEquals(P2, event4.port().number());
    assertAnnotationsEquals(event4.port().annotations());
    assertFalse("Port is disabled if not given from primary provider", event4.port().isEnabled());
    verify(clusterCommunicator);
    // TODO: verify broadcast message content
    assertInternalPortStatusEvent(
        NID1, DID1, PIDA, desc4, NO_ANNOTATION, message, subject, encoder);
    assertTrue(message.hasCaptured());
  }