use of org.openhab.core.thing.binding.ThingHandlerFactory in project openhab-core by openhab.
the class ThingManagerOSGiTest method thingManagerCallsBridgeStatusChangedOnThingHandlerCorrectly.
@Test
@SuppressWarnings("null")
public void thingManagerCallsBridgeStatusChangedOnThingHandlerCorrectly() {
class BridgeHandlerState {
@Nullable
ThingHandlerCallback callback;
}
final BridgeHandlerState bridgeState = new BridgeHandlerState();
Bridge bridge = BridgeBuilder.create(new ThingTypeUID("binding:test"), new ThingUID("binding:test:someBridgeUID-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.callback.statusUpdated(bridge, ThingStatusInfoBuilder.create(ThingStatus.REMOVED, ThingStatusDetail.NONE).build());
return null;
}
}).when(bridgeHandler).handleRemoval();
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);
managedThingProvider.add(thing);
waitForAssert(() -> assertThat(bridge.getStatus(), is(ThingStatus.ONLINE)));
waitForAssert(() -> assertThat(thing.getStatus(), is(ThingStatus.ONLINE)));
// initial bridge initialization is not reported as status change
waitForAssert(() -> verify(thingHandler, never()).bridgeStatusChanged(any(ThingStatusInfo.class)));
// the same status is also not reported, because it's not a change
ThingStatusInfo onlineNone = ThingStatusInfoBuilder.create(ThingStatus.ONLINE, ThingStatusDetail.NONE).build();
bridgeState.callback.statusUpdated(bridge, onlineNone);
waitForAssert(() -> verify(thingHandler, never()).bridgeStatusChanged(any(ThingStatusInfo.class)));
// report a change to OFFLINE
ThingStatusInfo offlineNone = ThingStatusInfoBuilder.create(ThingStatus.OFFLINE, ThingStatusDetail.NONE).build();
bridgeState.callback.statusUpdated(bridge, offlineNone);
waitForAssert(() -> verify(thingHandler, times(1)).bridgeStatusChanged(any(ThingStatusInfo.class)));
// report a change to ONLINE
bridgeState.callback.statusUpdated(bridge, onlineNone);
waitForAssert(() -> verify(thingHandler, times(2)).bridgeStatusChanged(any(ThingStatusInfo.class)));
ThingRegistry thingRegistry = getService(ThingRegistry.class);
thingRegistry.remove(bridge.getUID());
waitForAssert(() -> {
assertThat(bridge.getStatus(), is(equalTo(ThingStatus.UNINITIALIZED)));
waitForAssert(() -> verify(thingHandler, times(2)).bridgeStatusChanged(any(ThingStatusInfo.class)));
});
}
use of org.openhab.core.thing.binding.ThingHandlerFactory in project openhab-core by openhab.
the class ThingManagerOSGiTest method thingManagerConsidersUNKNOWNasReadyToUseAndForwardsCommand.
@Test
public void thingManagerConsidersUNKNOWNasReadyToUseAndForwardsCommand() {
class ThingHandlerState {
boolean handleCommandCalled;
@Nullable
ChannelUID calledChannelUID;
@Nullable
Command calledCommand;
@Nullable
ThingHandlerCallback callback;
}
final ThingHandlerState state = new ThingHandlerState();
managedThingProvider.add(thing);
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 {
state.handleCommandCalled = true;
state.calledChannelUID = (ChannelUID) invocation.getArgument(0);
state.calledCommand = (Command) invocation.getArgument(1);
return null;
}
}).when(thingHandler).handleCommand(any(ChannelUID.class), any(Command.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);
String itemName = "testItem";
Item item = new StringItem(itemName);
itemRegistry.add(item);
itemChannelLinkRegistry.add(new ItemChannelLink(itemName, new ChannelUID(thing.getUID(), "channel")));
waitForAssert(() -> assertThat(itemRegistry.get(itemName), is(notNullValue())));
eventPublisher.post(ItemEventFactory.createCommandEvent(itemName, OnOffType.ON));
assertThat(state.handleCommandCalled, is(false));
ThingStatusInfo unknownNone = ThingStatusInfoBuilder.create(ThingStatus.UNKNOWN, ThingStatusDetail.NONE).build();
state.callback.statusUpdated(thing, unknownNone);
assertThat(thing.getStatusInfo(), is(unknownNone));
eventPublisher.post(ItemEventFactory.createCommandEvent(itemName, OnOffType.ON));
waitForAssert(() -> {
assertThat(state.handleCommandCalled, is(true));
assertThat(state.calledChannelUID, is(equalTo(new ChannelUID(thing.getUID(), "channel"))));
assertThat(state.calledCommand, is(equalTo(OnOffType.ON)));
});
}
use of org.openhab.core.thing.binding.ThingHandlerFactory in project openhab-core by openhab.
the class ThingManagerOSGiTest method thingManagerWaitsWithThingUpdatedUntilInitializeReturned.
@Test
public void thingManagerWaitsWithThingUpdatedUntilInitializeReturned() {
registerThingTypeProvider();
Thing thing2 = ThingBuilder.create(THING_TYPE_UID, THING_UID).withChannels(List.of(ChannelBuilder.create(CHANNEL_UID, CoreItemFactory.SWITCH).build())).build();
class ThingHandlerState {
boolean raceCondition;
boolean initializeRunning;
boolean thingUpdatedCalled;
}
final ThingHandlerState state = new ThingHandlerState();
ThingHandler thingHandler = mock(ThingHandler.class);
doAnswer(new Answer<Void>() {
@Override
@Nullable
public Void answer(InvocationOnMock invocation) throws Throwable {
state.initializeRunning = true;
Thread.sleep(3000);
state.initializeRunning = false;
return null;
}
}).when(thingHandler).initialize();
when(thingHandler.getThing()).thenReturn(thing);
doAnswer(new Answer<Void>() {
@Override
@Nullable
public Void answer(InvocationOnMock invocation) throws Throwable {
state.thingUpdatedCalled = true;
if (state.initializeRunning) {
state.raceCondition = true;
}
return null;
}
}).when(thingHandler).thingUpdated(any(Thing.class));
ThingHandlerFactory thingHandlerFactory = mock(ThingHandlerFactory.class);
when(thingHandlerFactory.supportsThingType(any(ThingTypeUID.class))).thenReturn(true);
when(thingHandlerFactory.registerHandler(any(Thing.class))).thenReturn(thingHandler);
registerService(thingHandlerFactory);
new Thread(() -> managedThingProvider.add(thing)).start();
waitForAssert(() -> assertThat(thing.getStatus(), is(ThingStatus.INITIALIZING)));
new Thread(() -> managedThingProvider.update(thing2)).start();
waitForAssert(() -> assertThat(state.thingUpdatedCalled, is(true)));
assertThat(state.raceCondition, is(false));
}
use of org.openhab.core.thing.binding.ThingHandlerFactory in project openhab-core by openhab.
the class ThingManagerOSGiJavaTest method initializeThingHandlerCallback.
private AtomicReference<ThingHandlerCallback> initializeThingHandlerCallback() throws Exception {
registerThingTypeProvider();
registerChannelTypeProvider();
registerChannelGroupTypeProvider();
AtomicReference<ThingHandlerCallback> thc = new AtomicReference<>();
ThingHandlerFactory thingHandlerFactory = new BaseThingHandlerFactory() {
@Override
public boolean supportsThingType(ThingTypeUID thingTypeUID) {
return true;
}
@Override
@Nullable
protected ThingHandler createHandler(Thing thing) {
ThingHandler mockHandler = mock(ThingHandler.class);
doAnswer(a -> {
thc.set((ThingHandlerCallback) a.getArguments()[0]);
return null;
}).when(mockHandler).setCallback(any(ThingHandlerCallback.class));
when(mockHandler.getThing()).thenReturn(thing);
return mockHandler;
}
};
registerService(thingHandlerFactory, ThingHandlerFactory.class.getName());
new Thread((Runnable) () -> managedThingProvider.add(thing)).start();
waitForAssert(() -> {
assertNotNull(thc.get());
});
return thc;
}
use of org.openhab.core.thing.binding.ThingHandlerFactory in project openhab-core by openhab.
the class ThingManagerOSGiTest method thingManagerChangesTheThingType.
@Test
@SuppressWarnings("null")
public void thingManagerChangesTheThingType() {
registerThingTypeProvider();
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()));
migrator.migrateThingType(thing, newThingTypeUID, thing.getConfiguration());
waitForAssert(() -> assertThat(thing.getThingTypeUID().getAsString(), is(equalTo(newThingTypeUID.getAsString()))));
}
Aggregations