use of org.openhab.core.thing.binding.ThingHandlerFactory in project openhab-core by openhab.
the class ThingManagerOSGiTest method thingManagerHandlesFailingHandlerInitializationCorrectly.
@Test
public void thingManagerHandlesFailingHandlerInitializationCorrectly() {
class ThingHandlerState {
@Nullable
ThingHandlerCallback callback = null;
}
final ThingHandlerState state = new ThingHandlerState();
Thing testThing = ThingBuilder.create(THING_TYPE_UID, THING_UID).withConfiguration(new Configuration()).build();
testThing.getConfiguration().put("shouldFail", true);
ThingHandler thingHandler = mock(ThingHandler.class);
doAnswer(new Answer<Void>() {
@Override
@Nullable
public Void answer(InvocationOnMock invocation) throws Throwable {
state.callback = (ThingHandlerCallback) invocation.getArgument(0);
return null;
}
}).when(thingHandler).setCallback(any(ThingHandlerCallback.class));
doAnswer(new Answer<Void>() {
@Override
@Nullable
public Void answer(InvocationOnMock invocation) throws Throwable {
Boolean shouldFail = (Boolean) testThing.getConfiguration().get("shouldFail");
if (shouldFail) {
throw new IllegalStateException("Invalid config!");
} else {
state.callback.statusUpdated(testThing, ThingStatusInfoBuilder.create(ThingStatus.ONLINE).build());
}
return null;
}
}).when(thingHandler).initialize();
when(thingHandler.getThing()).thenReturn(testThing);
ThingHandlerFactory thingHandlerFactory = mock(ThingHandlerFactory.class);
when(thingHandlerFactory.supportsThingType(any(ThingTypeUID.class))).thenReturn(true);
when(thingHandlerFactory.registerHandler(any(Thing.class))).thenReturn(thingHandler);
registerService(thingHandlerFactory);
final ThingStatusInfo uninitializedNone = ThingStatusInfoBuilder.create(ThingStatus.UNINITIALIZED, ThingStatusDetail.NONE).build();
assertThat(testThing.getStatusInfo(), is(uninitializedNone));
managedThingProvider.add(testThing);
final ThingStatusInfo uninitializedError = ThingStatusInfoBuilder.create(ThingStatus.UNINITIALIZED, ThingStatusDetail.HANDLER_INITIALIZING_ERROR).withDescription("Invalid config!").build();
waitForAssert(() -> assertThat(testThing.getStatusInfo(), is(uninitializedError)));
testThing.getConfiguration().put("shouldFail", false);
managedThingProvider.update(testThing);
final ThingStatusInfo onlineNone = ThingStatusInfoBuilder.create(ThingStatus.ONLINE, ThingStatusDetail.NONE).build();
waitForAssert(() -> assertThat(testThing.getStatusInfo(), is(onlineNone)));
}
use of org.openhab.core.thing.binding.ThingHandlerFactory in project openhab-core by openhab.
the class ThingManagerOSGiTest method thingManagerDoesNotChangeTheThingTypeWhenNewThingTypeIsNotRegistered.
@Test
@SuppressWarnings("null")
public void thingManagerDoesNotChangeTheThingTypeWhenNewThingTypeIsNotRegistered() {
ThingHandler thingHandler = mock(ThingHandler.class);
when(thingHandler.getThing()).thenReturn(thing);
ThingHandlerFactory thingHandlerFactory = mock(ThingHandlerFactory.class);
when(thingHandlerFactory.supportsThingType(any(ThingTypeUID.class))).thenReturn(true);
when(thingHandlerFactory.registerHandler(any(Thing.class))).thenReturn(thingHandler);
registerService(thingHandlerFactory);
managedThingProvider.add(thing);
assertThat(thing.getThingTypeUID().getAsString(), is(equalTo(THING_TYPE_UID.getAsString())));
ThingTypeUID newThingTypeUID = new ThingTypeUID("binding:type2");
ThingTypeMigrationService migrator = getService(ThingTypeMigrationService.class);
assertThat(migrator, is(notNullValue()));
assertThrows(RuntimeException.class, () -> migrator.migrateThingType(thing, newThingTypeUID, thing.getConfiguration()));
}
use of org.openhab.core.thing.binding.ThingHandlerFactory in project openhab-core by openhab.
the class ThingManagerOSGiTest method thingManagerPostsThingStatusEventsIfTheStatusOfAThingIsUpdated.
@Test
public void thingManagerPostsThingStatusEventsIfTheStatusOfAThingIsUpdated() {
registerThingTypeProvider();
class ThingHandlerState {
@Nullable
ThingHandlerCallback callback;
}
final ThingHandlerState state = new ThingHandlerState();
ThingHandler thingHandler = mock(ThingHandler.class);
doAnswer(new Answer<Void>() {
@Override
@Nullable
public Void answer(InvocationOnMock invocation) throws Throwable {
state.callback = (ThingHandlerCallback) invocation.getArgument(0);
return null;
}
}).when(thingHandler).setCallback(any(ThingHandlerCallback.class));
when(thingHandler.getThing()).thenReturn(thing);
ThingHandlerFactory thingHandlerFactory = mock(ThingHandlerFactory.class);
when(thingHandlerFactory.supportsThingType(any(ThingTypeUID.class))).thenReturn(true);
when(thingHandlerFactory.registerHandler(any(Thing.class))).thenReturn(thingHandler);
registerService(thingHandlerFactory);
final List<Event> receivedEvents = new ArrayList<>();
@NonNullByDefault EventSubscriber thingStatusEventSubscriber = new EventSubscriber() {
@Override
public Set<String> getSubscribedEventTypes() {
return Set.of(ThingStatusInfoEvent.TYPE);
}
@Override
@Nullable
public EventFilter getEventFilter() {
return null;
}
@Override
public void receive(Event event) {
receivedEvents.add(event);
}
};
registerService(thingStatusEventSubscriber);
// set status to INITIALIZING
ThingStatusInfo initializingNone = ThingStatusInfoBuilder.create(ThingStatus.INITIALIZING, ThingStatusDetail.NONE).build();
ThingStatusInfoEvent event = ThingEventFactory.createStatusInfoEvent(thing.getUID(), initializingNone);
managedThingProvider.add(thing);
waitForAssert(() -> assertThat(receivedEvents.size(), is(1)));
assertThat(receivedEvents.get(0).getType(), is(event.getType()));
assertThat(receivedEvents.get(0).getPayload(), is(event.getPayload()));
assertThat(receivedEvents.get(0).getTopic(), is(event.getTopic()));
receivedEvents.clear();
// set status to ONLINE
ThingStatusInfo onlineNone = ThingStatusInfoBuilder.create(ThingStatus.ONLINE, ThingStatusDetail.NONE).build();
event = ThingEventFactory.createStatusInfoEvent(thing.getUID(), onlineNone);
state.callback.statusUpdated(thing, onlineNone);
waitForAssert(() -> assertThat(receivedEvents.size(), is(1)));
assertThat(receivedEvents.get(0).getType(), is(event.getType()));
assertThat(receivedEvents.get(0).getPayload(), is(event.getPayload()));
assertThat(receivedEvents.get(0).getTopic(), is(event.getTopic()));
receivedEvents.clear();
// set status to OFFLINE
ThingStatusInfo offlineCommError = ThingStatusInfoBuilder.create(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR).build();
event = ThingEventFactory.createStatusInfoEvent(thing.getUID(), offlineCommError);
state.callback.statusUpdated(thing, offlineCommError);
waitForAssert(() -> assertThat(receivedEvents.size(), is(1)));
assertThat(receivedEvents.get(0).getType(), is(event.getType()));
assertThat(receivedEvents.get(0).getPayload(), is(event.getPayload()));
assertThat(receivedEvents.get(0).getTopic(), is(event.getTopic()));
receivedEvents.clear();
// set status to UNINITIALIZED
ThingStatusInfo uninitializedError = ThingStatusInfoBuilder.create(ThingStatus.UNINITIALIZED, ThingStatusDetail.HANDLER_MISSING_ERROR).build();
final Event uninitializedEvent = ThingEventFactory.createStatusInfoEvent(thing.getUID(), uninitializedError);
unregisterService(thingHandlerFactory);
waitForAssert(() -> {
assertThat(receivedEvents.size(), is(2));
assertThat(receivedEvents.get(1).getType(), is(uninitializedEvent.getType()));
assertThat(receivedEvents.get(1).getPayload(), is(uninitializedEvent.getPayload()));
assertThat(receivedEvents.get(1).getTopic(), is(uninitializedEvent.getTopic()));
});
}
use of org.openhab.core.thing.binding.ThingHandlerFactory in project openhab-core by openhab.
the class ThingManagerOSGiTest method thingManagerCallsChildHandlerInitializedAndChildHandlerDisposedOnBridgeHandlerCorrectlyEvenIfChildRegistrationTakesTooLong.
@Test
public void thingManagerCallsChildHandlerInitializedAndChildHandlerDisposedOnBridgeHandlerCorrectlyEvenIfChildRegistrationTakesTooLong() {
class BridgeHandlerState {
boolean childHandlerInitializedCalled;
@Nullable
ThingHandler initializedHandler;
@Nullable
Thing initializedThing;
boolean childHandlerDisposedCalled;
@Nullable
ThingHandler disposedHandler;
@Nullable
Thing disposedThing;
@Nullable
ThingHandlerCallback callback;
}
final BridgeHandlerState bridgeState = new BridgeHandlerState();
Bridge bridge = BridgeBuilder.create(new ThingTypeUID("binding:type"), new ThingUID("binding:type:bridgeUID-1")).build();
BridgeHandler bridgeHandler = mock(BridgeHandler.class);
doAnswer(new Answer<Void>() {
@Override
@Nullable
public Void answer(InvocationOnMock invocation) throws Throwable {
bridgeState.callback = (ThingHandlerCallback) invocation.getArgument(0);
return null;
}
}).when(bridgeHandler).setCallback(any(ThingHandlerCallback.class));
doAnswer(new Answer<Void>() {
@Override
@Nullable
public Void answer(InvocationOnMock invocation) throws Throwable {
bridgeState.callback.statusUpdated(bridge, ThingStatusInfoBuilder.create(ThingStatus.ONLINE, ThingStatusDetail.NONE).build());
return null;
}
}).when(bridgeHandler).initialize();
when(bridgeHandler.getThing()).thenReturn(bridge);
doAnswer(new Answer<Void>() {
@Override
@Nullable
public Void answer(InvocationOnMock invocation) throws Throwable {
bridgeState.childHandlerInitializedCalled = true;
bridgeState.initializedHandler = (ThingHandler) invocation.getArgument(0);
bridgeState.initializedThing = (Thing) invocation.getArgument(1);
return null;
}
}).when(bridgeHandler).childHandlerInitialized(any(ThingHandler.class), any(Thing.class));
doAnswer(new Answer<Void>() {
@Override
@Nullable
public Void answer(InvocationOnMock invocation) throws Throwable {
bridgeState.childHandlerDisposedCalled = true;
bridgeState.disposedHandler = (ThingHandler) invocation.getArgument(0);
bridgeState.disposedThing = (Thing) invocation.getArgument(1);
return null;
}
}).when(bridgeHandler).childHandlerDisposed(any(ThingHandler.class), any(Thing.class));
class ThingHandlerState {
@Nullable
ThingHandlerCallback callback;
}
final ThingHandlerState thingState = new ThingHandlerState();
Thing thing = ThingBuilder.create(new ThingTypeUID("binding:type"), new ThingUID("binding:type:thingUID-1")).withBridge(bridge.getUID()).build();
ThingHandler thingHandler = mock(ThingHandler.class);
doAnswer(new Answer<Void>() {
@Override
@Nullable
public Void answer(InvocationOnMock invocation) throws Throwable {
thingState.callback = (ThingHandlerCallback) invocation.getArgument(0);
return null;
}
}).when(thingHandler).setCallback(any(ThingHandlerCallback.class));
doAnswer(new Answer<Void>() {
@Override
@Nullable
public Void answer(InvocationOnMock invocation) throws Throwable {
thingState.callback.statusUpdated(thing, ThingStatusInfoBuilder.create(ThingStatus.ONLINE, ThingStatusDetail.NONE).build());
return null;
}
}).when(thingHandler).initialize();
when(thingHandler.getThing()).thenReturn(thing);
ThingHandlerFactory thingHandlerFactory = mock(ThingHandlerFactory.class);
when(thingHandlerFactory.supportsThingType(any(ThingTypeUID.class))).thenReturn(true);
doAnswer(new Answer<ThingHandler>() {
@Override
@Nullable
public ThingHandler answer(InvocationOnMock invocation) throws Throwable {
// Wait longer than the SafeMethodCaller timeout
Thread.sleep(6000);
Thing thing = (Thing) invocation.getArgument(0);
if (thing instanceof Bridge) {
return bridgeHandler;
} else if (thing instanceof Thing) {
return thingHandler;
}
return null;
}
}).when(thingHandlerFactory).registerHandler(any(Thing.class));
registerService(thingHandlerFactory);
managedThingProvider.add(bridge);
assertThat(bridgeState.childHandlerInitializedCalled, is(false));
assertThat(bridgeState.childHandlerDisposedCalled, is(false));
managedThingProvider.add(thing);
waitForAssert(() -> assertThat(bridgeState.childHandlerInitializedCalled, is(true)));
assertThat(bridgeState.initializedThing, is(thing));
assertThat(bridgeState.initializedHandler, is(thingHandler));
managedThingProvider.remove(thing.getUID());
waitForAssert(() -> assertThat(bridgeState.childHandlerDisposedCalled, is(true)));
assertThat(bridgeState.disposedThing, is(thing));
assertThat(bridgeState.disposedHandler, is(thingHandler));
}
use of org.openhab.core.thing.binding.ThingHandlerFactory in project openhab-core by openhab.
the class ThingManagerOSGiTest method thingManagerCallsChildHandlerInitializedAndChildHandlerDisposedOnBridgeHandlerCorrectly.
@Test
public void thingManagerCallsChildHandlerInitializedAndChildHandlerDisposedOnBridgeHandlerCorrectly() {
class BridgeHandlerState {
boolean childHandlerInitializedCalled;
@Nullable
ThingHandler initializedHandler;
@Nullable
Thing initializedThing;
boolean childHandlerDisposedCalled;
@Nullable
ThingHandler disposedHandler;
@Nullable
Thing disposedThing;
@Nullable
ThingHandlerCallback callback;
}
final BridgeHandlerState bridgeState = new BridgeHandlerState();
Bridge bridge = BridgeBuilder.create(new ThingTypeUID("binding:type"), new ThingUID("binding:type:bridgeUID-1")).build();
BridgeHandler bridgeHandler = mock(BridgeHandler.class);
doAnswer(new Answer<Void>() {
@Override
@Nullable
public Void answer(InvocationOnMock invocation) throws Throwable {
bridgeState.callback = (ThingHandlerCallback) invocation.getArgument(0);
return null;
}
}).when(bridgeHandler).setCallback(any(ThingHandlerCallback.class));
doAnswer(new Answer<Void>() {
@Override
@Nullable
public Void answer(InvocationOnMock invocation) throws Throwable {
bridgeState.callback.statusUpdated(bridge, ThingStatusInfoBuilder.create(ThingStatus.ONLINE, ThingStatusDetail.NONE).build());
return null;
}
}).when(bridgeHandler).initialize();
when(bridgeHandler.getThing()).thenReturn(bridge);
doAnswer(new Answer<Void>() {
@Override
@Nullable
public Void answer(InvocationOnMock invocation) throws Throwable {
bridgeState.childHandlerInitializedCalled = true;
bridgeState.initializedHandler = (ThingHandler) invocation.getArgument(0);
bridgeState.initializedThing = (Thing) invocation.getArgument(1);
return null;
}
}).when(bridgeHandler).childHandlerInitialized(any(ThingHandler.class), any(Thing.class));
doAnswer(new Answer<Void>() {
@Override
@Nullable
public Void answer(InvocationOnMock invocation) throws Throwable {
bridgeState.childHandlerDisposedCalled = true;
bridgeState.disposedHandler = (ThingHandler) invocation.getArgument(0);
bridgeState.disposedThing = (Thing) invocation.getArgument(1);
return null;
}
}).when(bridgeHandler).childHandlerDisposed(any(ThingHandler.class), any(Thing.class));
class ThingHandlerState {
@Nullable
ThingHandlerCallback callback;
}
final ThingHandlerState thingState = new ThingHandlerState();
Thing thing = ThingBuilder.create(new ThingTypeUID("binding:type"), new ThingUID("binding:type:thingUID-1")).withBridge(bridge.getUID()).build();
ThingHandler thingHandler = mock(ThingHandler.class);
doAnswer(new Answer<Void>() {
@Override
@Nullable
public Void answer(InvocationOnMock invocation) throws Throwable {
thingState.callback = (ThingHandlerCallback) invocation.getArgument(0);
return null;
}
}).when(thingHandler).setCallback(any(ThingHandlerCallback.class));
doAnswer(new Answer<Void>() {
@Override
@Nullable
public Void answer(InvocationOnMock invocation) throws Throwable {
thingState.callback.statusUpdated(thing, ThingStatusInfoBuilder.create(ThingStatus.ONLINE, ThingStatusDetail.NONE).build());
return null;
}
}).when(thingHandler).initialize();
when(thingHandler.getThing()).thenReturn(thing);
ThingHandlerFactory thingHandlerFactory = mock(ThingHandlerFactory.class);
when(thingHandlerFactory.supportsThingType(any(ThingTypeUID.class))).thenReturn(true);
doAnswer(new Answer<ThingHandler>() {
@Override
@Nullable
public ThingHandler answer(InvocationOnMock invocation) throws Throwable {
Thing thing = (Thing) invocation.getArgument(0);
if (thing instanceof Bridge) {
return bridgeHandler;
} else if (thing instanceof Thing) {
return thingHandler;
}
return null;
}
}).when(thingHandlerFactory).registerHandler(any(Thing.class));
registerService(thingHandlerFactory);
managedThingProvider.add(bridge);
assertThat(bridgeState.childHandlerInitializedCalled, is(false));
assertThat(bridgeState.childHandlerDisposedCalled, is(false));
managedThingProvider.add(thing);
waitForAssert(() -> assertThat(bridgeState.childHandlerInitializedCalled, is(true)));
assertThat(bridgeState.initializedThing, is(thing));
assertThat(bridgeState.initializedHandler, is(thingHandler));
managedThingProvider.remove(thing.getUID());
waitForAssert(() -> assertThat(bridgeState.childHandlerDisposedCalled, is(true)));
assertThat(bridgeState.disposedThing, is(thing));
assertThat(bridgeState.disposedHandler, is(thingHandler));
}
Aggregations