Search in sources :

Example 96 with ThingStatusInfo

use of org.openhab.core.thing.ThingStatusInfo in project openhab-core by openhab.

the class ThingManagerOSGiTest method thingManagerHandlesThingHandlerLifecycleCorrectly.

@Test
public void thingManagerHandlesThingHandlerLifecycleCorrectly() {
    class ThingHandlerState {

        @Nullable
        ThingHandlerCallback callback = null;
    }
    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));
    doAnswer(new Answer<Void>() {

        @Override
        @Nullable
        public Void answer(InvocationOnMock invocation) throws Throwable {
            state.callback.statusUpdated(thing, ThingStatusInfoBuilder.create(ThingStatus.ONLINE).build());
            return null;
        }
    }).when(thingHandler).initialize();
    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 ThingStatusInfo uninitializedNone = ThingStatusInfoBuilder.create(ThingStatus.UNINITIALIZED, ThingStatusDetail.NONE).build();
    assertThat(thing.getStatusInfo(), is(uninitializedNone));
    // add thing - provokes handler registration & initialization
    managedThingProvider.add(thing);
    waitForAssert(() -> verify(thingHandlerFactory, times(1)).registerHandler(thing));
    waitForAssert(() -> verify(thingHandler, times(1)).initialize());
    final ThingStatusInfo onlineNone = ThingStatusInfoBuilder.create(ThingStatus.ONLINE, ThingStatusDetail.NONE).build();
    waitForAssert(() -> assertThat(thing.getStatusInfo(), is(onlineNone)));
    // remove handler factory - provokes handler deregistration & disposal
    unregisterService(thingHandlerFactory);
    waitForAssert(() -> verify(thingHandlerFactory, times(1)).unregisterHandler(thing));
    waitForAssert(() -> verify(thingHandler, times(1)).dispose());
    final ThingStatusInfo uninitializedHandlerMissing = ThingStatusInfoBuilder.create(ThingStatus.UNINITIALIZED, ThingStatusDetail.HANDLER_MISSING_ERROR).build();
    waitForAssert(() -> assertThat(thing.getStatusInfo(), is(uninitializedHandlerMissing)));
    // add handler factory - provokes handler registration & initialization
    registerService(thingHandlerFactory);
    waitForAssert(() -> verify(thingHandlerFactory, times(2)).registerHandler(thing));
    waitForAssert(() -> verify(thingHandler, times(2)).initialize());
    waitForAssert(() -> assertThat(thing.getStatusInfo(), is(onlineNone)));
    // remove thing - provokes handler deregistration & disposal
    managedThingProvider.remove(thing.getUID());
    waitForAssert(() -> verify(thingHandlerFactory, times(2)).unregisterHandler(thing));
    waitForAssert(() -> verify(thingHandler, times(2)).dispose());
    waitForAssert(() -> assertThat(thing.getStatusInfo(), is(uninitializedHandlerMissing)));
}
Also used : ThingHandlerCallback(org.openhab.core.thing.binding.ThingHandlerCallback) ThingHandler(org.openhab.core.thing.binding.ThingHandler) ThingStatusInfo(org.openhab.core.thing.ThingStatusInfo) ThingHandlerFactory(org.openhab.core.thing.binding.ThingHandlerFactory) InvocationOnMock(org.mockito.invocation.InvocationOnMock) ThingTypeUID(org.openhab.core.thing.ThingTypeUID) Nullable(org.eclipse.jdt.annotation.Nullable) Thing(org.openhab.core.thing.Thing) Test(org.junit.jupiter.api.Test) JavaOSGiTest(org.openhab.core.test.java.JavaOSGiTest)

Example 97 with ThingStatusInfo

use of org.openhab.core.thing.ThingStatusInfo in project openhab-core by openhab.

the class ThingManagerOSGiJavaTest method testStorageEntryRetainedOnThingRemoval.

@Test
public void testStorageEntryRetainedOnThingRemoval() throws Exception {
    registerThingTypeProvider();
    AtomicReference<ThingHandlerCallback> thingHandlerCallback = new AtomicReference<>();
    AtomicReference<Boolean> initializeInvoked = new AtomicReference<>(false);
    AtomicReference<Boolean> disposeInvoked = new AtomicReference<>(false);
    registerThingHandlerFactory(THING_TYPE_UID, thing -> {
        ThingHandler mockHandler = mock(ThingHandler.class);
        doAnswer(a -> {
            thingHandlerCallback.set((ThingHandlerCallback) a.getArguments()[0]);
            return null;
        }).when(mockHandler).setCallback(ArgumentMatchers.isA(ThingHandlerCallback.class));
        doAnswer(a -> {
            initializeInvoked.set(true);
            // call thingUpdated() from within initialize()
            thingHandlerCallback.get().thingUpdated(thing);
            // hang on a little to provoke a potential dead-lock
            Thread.sleep(1000);
            ThingStatusInfo thingStatusInfo = ThingStatusInfoBuilder.create(ThingStatus.ONLINE, ThingStatusDetail.NONE).build();
            thing.setStatusInfo(thingStatusInfo);
            return null;
        }).when(mockHandler).initialize();
        doAnswer(a -> {
            disposeInvoked.set(true);
            return null;
        }).when(mockHandler).dispose();
        when(mockHandler.getThing()).thenReturn(thing);
        return mockHandler;
    });
    ThingStatusInfo thingStatusInfo = ThingStatusInfoBuilder.create(ThingStatus.UNINITIALIZED, ThingStatusDetail.NONE).build();
    thing.setStatusInfo(thingStatusInfo);
    new Thread((Runnable) () -> managedThingProvider.add(thing)).start();
    waitForAssert(() -> {
        assertThat(initializeInvoked.get(), is(true));
        assertThat(thing.getStatus(), is(ThingStatus.INITIALIZING));
    });
    initializeInvoked.set(false);
    thingManager.setEnabled(THING_UID, false);
    waitForAssert(() -> {
        assertThat(storage.containsKey(THING_UID.getAsString()), is(true));
        assertThat(disposeInvoked.get(), is(true));
        assertThat(thing.getStatus(), is(ThingStatus.UNINITIALIZED));
        assertThat(thing.getStatusInfo().getStatusDetail(), is(ThingStatusDetail.DISABLED));
    }, SafeCaller.DEFAULT_TIMEOUT - 100, 50);
    disposeInvoked.set(false);
    new Thread((Runnable) () -> managedThingProvider.remove(thing.getUID())).start();
    waitForAssert(() -> {
        assertThat(thingRegistry.get(thing.getUID()), is(equalTo(null)));
    }, SafeCaller.DEFAULT_TIMEOUT - 100, 50);
    assertThat(storage.containsKey(THING_UID.getAsString()), is(true));
}
Also used : ThingHandlerCallback(org.openhab.core.thing.binding.ThingHandlerCallback) AtomicReference(java.util.concurrent.atomic.AtomicReference) BaseThingHandler(org.openhab.core.thing.binding.BaseThingHandler) ThingHandler(org.openhab.core.thing.binding.ThingHandler) ThingStatusInfo(org.openhab.core.thing.ThingStatusInfo) Test(org.junit.jupiter.api.Test) JavaOSGiTest(org.openhab.core.test.java.JavaOSGiTest)

Example 98 with ThingStatusInfo

use of org.openhab.core.thing.ThingStatusInfo in project openhab-core by openhab.

the class ThingManagerOSGiJavaTest method testUpdateThing.

@Test
public void testUpdateThing() throws Exception {
    registerThingTypeProvider();
    AtomicReference<ThingHandlerCallback> thingHandlerCallback = new AtomicReference<>();
    AtomicReference<Boolean> initializeInvoked = new AtomicReference<>(false);
    AtomicReference<Boolean> disposeInvoked = new AtomicReference<>(false);
    AtomicReference<Boolean> updatedInvoked = new AtomicReference<>(false);
    registerThingHandlerFactory(THING_TYPE_UID, thing -> {
        ThingHandler mockHandler = mock(ThingHandler.class);
        doAnswer(a -> {
            thingHandlerCallback.set((ThingHandlerCallback) a.getArguments()[0]);
            return null;
        }).when(mockHandler).setCallback(ArgumentMatchers.isA(ThingHandlerCallback.class));
        doAnswer(a -> {
            initializeInvoked.set(true);
            // call thingUpdated() from within initialize()
            thingHandlerCallback.get().thingUpdated(thing);
            // hang on a little to provoke a potential dead-lock
            Thread.sleep(1000);
            ThingStatusInfo thingStatusInfo = ThingStatusInfoBuilder.create(ThingStatus.ONLINE, ThingStatusDetail.NONE).build();
            thing.setStatusInfo(thingStatusInfo);
            return null;
        }).when(mockHandler).initialize();
        doAnswer(a -> {
            disposeInvoked.set(true);
            return null;
        }).when(mockHandler).dispose();
        doAnswer(a -> {
            updatedInvoked.set(true);
            return null;
        }).when(mockHandler).thingUpdated(any());
        when(mockHandler.getThing()).thenReturn(thing);
        return mockHandler;
    });
    ThingStatusInfo thingStatusInfo = ThingStatusInfoBuilder.create(ThingStatus.UNINITIALIZED, ThingStatusDetail.NONE).build();
    thing.setStatusInfo(thingStatusInfo);
    new Thread((Runnable) () -> managedThingProvider.add(thing)).start();
    waitForAssert(() -> {
        assertThat(thing.getStatus(), is(ThingStatus.INITIALIZING));
    });
    waitForAssert(() -> {
        assertThat(initializeInvoked.get(), is(true));
    }, SafeCaller.DEFAULT_TIMEOUT - 100, 50);
    new Thread((Runnable) () -> managedThingProvider.update(thing)).start();
    waitForAssert(() -> {
        assertThat(updatedInvoked.get(), is(true));
    }, SafeCaller.DEFAULT_TIMEOUT - 100, 50);
    updatedInvoked.set(false);
    thingManager.setEnabled(THING_UID, false);
    waitForAssert(() -> {
        assertThat(storage.containsKey(THING_UID.getAsString()), is(true));
        assertThat(disposeInvoked.get(), is(true));
        assertThat(thing.getStatus(), is(ThingStatus.UNINITIALIZED));
        assertThat(thing.getStatusInfo().getStatusDetail(), is(ThingStatusDetail.DISABLED));
    }, SafeCaller.DEFAULT_TIMEOUT - 100, 50);
    disposeInvoked.set(false);
    new Thread((Runnable) () -> managedThingProvider.update(thing)).start();
    waitForAssert(() -> {
        assertThat(updatedInvoked.get(), is(false));
    }, SafeCaller.DEFAULT_TIMEOUT - 100, 50);
}
Also used : ThingHandlerCallback(org.openhab.core.thing.binding.ThingHandlerCallback) AtomicReference(java.util.concurrent.atomic.AtomicReference) BaseThingHandler(org.openhab.core.thing.binding.BaseThingHandler) ThingHandler(org.openhab.core.thing.binding.ThingHandler) ThingStatusInfo(org.openhab.core.thing.ThingStatusInfo) Test(org.junit.jupiter.api.Test) JavaOSGiTest(org.openhab.core.test.java.JavaOSGiTest)

Example 99 with ThingStatusInfo

use of org.openhab.core.thing.ThingStatusInfo in project openhab-core by openhab.

the class ThingManagerOSGiJavaTest method testDisposeNotInvokedOnAlreadyDisabledThing.

@Test
public void testDisposeNotInvokedOnAlreadyDisabledThing() throws Exception {
    registerThingTypeProvider();
    AtomicReference<ThingHandlerCallback> thingHandlerCallback = new AtomicReference<>();
    AtomicReference<Boolean> initializeInvoked = new AtomicReference<>(false);
    AtomicReference<Boolean> disposeInvoked = new AtomicReference<>(false);
    registerThingHandlerFactory(THING_TYPE_UID, thing -> {
        ThingHandler mockHandler = mock(ThingHandler.class);
        doAnswer(a -> {
            thingHandlerCallback.set((ThingHandlerCallback) a.getArguments()[0]);
            return null;
        }).when(mockHandler).setCallback(ArgumentMatchers.isA(ThingHandlerCallback.class));
        doAnswer(a -> {
            initializeInvoked.set(true);
            // call thingUpdated() from within initialize()
            thingHandlerCallback.get().thingUpdated(thing);
            // hang on a little to provoke a potential dead-lock
            Thread.sleep(1000);
            ThingStatusInfo thingStatusInfo = ThingStatusInfoBuilder.create(ThingStatus.ONLINE, ThingStatusDetail.NONE).build();
            thing.setStatusInfo(thingStatusInfo);
            return null;
        }).when(mockHandler).initialize();
        doAnswer(a -> {
            disposeInvoked.set(true);
            return null;
        }).when(mockHandler).dispose();
        when(mockHandler.getThing()).thenReturn(thing);
        return mockHandler;
    });
    ThingStatusInfo thingStatusInfo = ThingStatusInfoBuilder.create(ThingStatus.UNINITIALIZED, ThingStatusDetail.NONE).build();
    thing.setStatusInfo(thingStatusInfo);
    new Thread((Runnable) () -> managedThingProvider.add(thing)).start();
    waitForAssert(() -> {
        assertThat(thing.getStatus(), is(ThingStatus.INITIALIZING));
    });
    // ensure it didn't run into a dead-lock which gets resolved by the SafeCaller.
    waitForAssert(() -> {
        assertThat(initializeInvoked.get(), is(true));
    }, SafeCaller.DEFAULT_TIMEOUT - 100, 50);
    thingManager.setEnabled(THING_UID, false);
    waitForAssert(() -> {
        assertThat(storage.containsKey(THING_UID.getAsString()), is(true));
        assertThat(disposeInvoked.get(), is(true));
        assertThat(thing.getStatus(), is(ThingStatus.UNINITIALIZED));
        assertThat(thing.getStatusInfo().getStatusDetail(), is(ThingStatusDetail.DISABLED));
    }, SafeCaller.DEFAULT_TIMEOUT - 100, 50);
    disposeInvoked.set(false);
    thingManager.setEnabled(THING_UID, false);
    waitForAssert(() -> {
        assertThat(storage.containsKey(THING_UID.getAsString()), is(true));
        assertThat(disposeInvoked.get(), is(false));
        assertThat(thing.getStatus(), is(ThingStatus.UNINITIALIZED));
        assertThat(thing.getStatusInfo().getStatusDetail(), is(ThingStatusDetail.DISABLED));
    }, SafeCaller.DEFAULT_TIMEOUT - 100, 50);
}
Also used : ThingHandlerCallback(org.openhab.core.thing.binding.ThingHandlerCallback) AtomicReference(java.util.concurrent.atomic.AtomicReference) BaseThingHandler(org.openhab.core.thing.binding.BaseThingHandler) ThingHandler(org.openhab.core.thing.binding.ThingHandler) ThingStatusInfo(org.openhab.core.thing.ThingStatusInfo) Test(org.junit.jupiter.api.Test) JavaOSGiTest(org.openhab.core.test.java.JavaOSGiTest)

Example 100 with ThingStatusInfo

use of org.openhab.core.thing.ThingStatusInfo 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)));
    });
}
Also used : BridgeHandler(org.openhab.core.thing.binding.BridgeHandler) ThingHandlerCallback(org.openhab.core.thing.binding.ThingHandlerCallback) ThingHandler(org.openhab.core.thing.binding.ThingHandler) ThingStatusInfo(org.openhab.core.thing.ThingStatusInfo) ThingHandlerFactory(org.openhab.core.thing.binding.ThingHandlerFactory) ThingRegistry(org.openhab.core.thing.ThingRegistry) InvocationOnMock(org.mockito.invocation.InvocationOnMock) ThingUID(org.openhab.core.thing.ThingUID) ThingTypeUID(org.openhab.core.thing.ThingTypeUID) Bridge(org.openhab.core.thing.Bridge) Nullable(org.eclipse.jdt.annotation.Nullable) Thing(org.openhab.core.thing.Thing) Test(org.junit.jupiter.api.Test) JavaOSGiTest(org.openhab.core.test.java.JavaOSGiTest)

Aggregations

ThingStatusInfo (org.openhab.core.thing.ThingStatusInfo)102 Test (org.junit.jupiter.api.Test)59 JavaOSGiTest (org.openhab.core.test.java.JavaOSGiTest)34 Thing (org.openhab.core.thing.Thing)23 ThingHandler (org.openhab.core.thing.binding.ThingHandler)23 ThingHandlerCallback (org.openhab.core.thing.binding.ThingHandlerCallback)20 ThingTypeUID (org.openhab.core.thing.ThingTypeUID)18 ThingHandlerFactory (org.openhab.core.thing.binding.ThingHandlerFactory)16 Nullable (org.eclipse.jdt.annotation.Nullable)14 Configuration (org.openhab.core.config.core.Configuration)13 ThingUID (org.openhab.core.thing.ThingUID)13 InvocationOnMock (org.mockito.invocation.InvocationOnMock)12 Bridge (org.openhab.core.thing.Bridge)12 JavaTest (org.openhab.core.test.java.JavaTest)8 AtomicReference (java.util.concurrent.atomic.AtomicReference)5 BeforeEach (org.junit.jupiter.api.BeforeEach)5 DiscoveryResult (org.openhab.core.config.discovery.DiscoveryResult)5 BaseThingHandler (org.openhab.core.thing.binding.BaseThingHandler)5 ArrayList (java.util.ArrayList)4 ThingStatus (org.openhab.core.thing.ThingStatus)4