Skip to content
This repository has been archived by the owner on May 7, 2020. It is now read-only.

fix orphaned items #3639

Merged
merged 1 commit into from
Jun 12, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src/test/groovy"/>
<classpathentry kind="src" path="src/test/resources"/>
<classpathentry kind="src" path="src/test/java"/>
<classpathentry exported="true" kind="con" path="GROOVY_DSL_SUPPORT"/>
<classpathentry kind="output" path="target/test-classes"/>
</classpath>
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Import-Package: com.google.gson,
org.codehaus.groovy.runtime.callsite,
org.codehaus.groovy.runtime.typehandling,
org.eclipse.smarthome.config.core,
org.eclipse.smarthome.core.items,
org.eclipse.smarthome.core.library.items,
org.eclipse.smarthome.core.library.types,
org.eclipse.smarthome.core.storage,
Expand All @@ -21,5 +22,10 @@ Import-Package: com.google.gson,
org.hamcrest;core=split,
org.junit;version="4.0.0",
org.junit.rules,
org.mockito,
org.mockito.invocation,
org.mockito.stubbing,
org.mockito.verification,
org.osgi.framework,
org.osgi.service.cm
Require-Bundle: org.hamcrest
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
source.. = src/test/groovy,\
src/test/resources
src/test/resources,\
src/test/java/
output.. = target/test-classes/
bin.includes = META-INF/,\
.,\
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@
<booleanAttribute key="includeOptional" value="false"/>
<stringAttribute key="location" value="${workspace_loc}/../junit-workspace"/>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/org.eclipse.smarthome.core.thing.test/src/test/groovy"/>
<listEntry value="/org.eclipse.smarthome.core.thing.test"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="2"/>
<listEntry value="4"/>
</listAttribute>
<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value="=org.eclipse.smarthome.core.thing.test/src\/test\/groovy"/>
<stringAttribute key="org.eclipse.jdt.junit.CONTAINER" value="=org.eclipse.smarthome.core.thing.test"/>
<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/>
Expand All @@ -34,7 +34,7 @@
<stringAttribute key="pde.version" value="3.3"/>
<stringAttribute key="product" value="org.eclipse.equinox.p2.director.app.product"/>
<booleanAttribute key="run_in_ui_thread" value="false"/>
<stringAttribute key="selected_target_plugins" value="ch.qos.logback.classic@default:default,ch.qos.logback.core@default:default,ch.qos.logback.slf4j@default:false,com.eclipsesource.jaxrs.jersey-min@default:default,com.google.gson*2.2.4.v201311231704@default:default,com.google.gson*2.5.0@default:default,com.google.guava@default:default,com.ibm.icu.base@default:default,com.ibm.icu@default:default,javax.annotation@default:default,javax.inject@default:default,javax.transaction@default:false,javax.xml@default:default,org.apache.ant@default:default,org.apache.batik.css@default:default,org.apache.batik.util.gui@default:default,org.apache.batik.util@default:default,org.apache.commons.collections@default:default,org.apache.commons.io@default:default,org.apache.commons.lang@default:default,org.codehaus.groovy@default:default,org.eclipse.compare.core@default:default,org.eclipse.core.commands@default:default,org.eclipse.core.contenttype@default:default,org.eclipse.core.databinding.observable@default:default,org.eclipse.core.databinding.property@default:default,org.eclipse.core.databinding@default:default,org.eclipse.core.expressions@default:default,org.eclipse.core.filesystem.java7@default:false,org.eclipse.core.filesystem.macosx@default:false,org.eclipse.core.filesystem@default:default,org.eclipse.core.jobs@default:default,org.eclipse.core.resources@default:default,org.eclipse.core.runtime.compatibility.registry@default:false,org.eclipse.core.runtime@default:true,org.eclipse.e4.core.commands@default:default,org.eclipse.e4.core.contexts@default:default,org.eclipse.e4.core.di.extensions@default:default,org.eclipse.e4.core.di@default:default,org.eclipse.e4.core.services@default:default,org.eclipse.e4.ui.bindings@default:default,org.eclipse.e4.ui.css.core@default:default,org.eclipse.e4.ui.css.swt.theme@default:default,org.eclipse.e4.ui.css.swt@default:default,org.eclipse.e4.ui.di@default:default,org.eclipse.e4.ui.model.workbench@default:default,org.eclipse.e4.ui.services@default:default,org.eclipse.e4.ui.widgets@default:default,org.eclipse.e4.ui.workbench.addons.swt@default:default,org.eclipse.e4.ui.workbench.renderers.swt.cocoa@default:false,org.eclipse.e4.ui.workbench.renderers.swt@default:default,org.eclipse.e4.ui.workbench.swt@default:default,org.eclipse.e4.ui.workbench3@default:default,org.eclipse.e4.ui.workbench@default:default,org.eclipse.emf.common@default:default,org.eclipse.emf.ecore.change@default:default,org.eclipse.emf.ecore.xmi@default:default,org.eclipse.emf.ecore@default:default,org.eclipse.equinox.app@default:default,org.eclipse.equinox.cm@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.ds@1:true,org.eclipse.equinox.event@default:true,org.eclipse.equinox.preferences@default:default,org.eclipse.equinox.region@default:false,org.eclipse.equinox.registry@default:default,org.eclipse.equinox.transforms.hook@default:false,org.eclipse.equinox.util@default:default,org.eclipse.equinox.weaving.hook@default:false,org.eclipse.help@default:default,org.eclipse.jface.databinding@default:default,org.eclipse.jface@default:default,org.eclipse.osgi.compatibility.state@default:false,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.eclipse.swt.cocoa.macosx.x86_64@default:false,org.eclipse.swt@default:default,org.eclipse.team.core@default:default,org.eclipse.ui.cocoa@default:false,org.eclipse.ui.trace@default:default,org.eclipse.ui.workbench@default:default,org.eclipse.ui@default:default,org.hamcrest.core@default:default,org.junit@default:default,org.slf4j.api@default:default,org.w3c.css.sac@default:default,org.w3c.dom.events@default:default,org.w3c.dom.smil@default:default,org.w3c.dom.svg@default:default"/>
<stringAttribute key="selected_target_plugins" value="ch.qos.logback.classic@default:default,ch.qos.logback.core@default:default,ch.qos.logback.slf4j@default:false,com.eclipsesource.jaxrs.jersey-min@default:default,com.google.gson*2.2.4.v201311231704@default:default,com.google.gson*2.5.0@default:default,com.google.guava@default:default,com.ibm.icu.base@default:default,com.ibm.icu@default:default,javax.annotation@default:default,javax.inject@default:default,javax.transaction@default:false,javax.xml@default:default,org.apache.ant@default:default,org.apache.batik.css@default:default,org.apache.batik.util.gui@default:default,org.apache.batik.util@default:default,org.apache.commons.collections@default:default,org.apache.commons.io@default:default,org.apache.commons.lang@default:default,org.codehaus.groovy@default:default,org.eclipse.compare.core@default:default,org.eclipse.core.commands@default:default,org.eclipse.core.contenttype@default:default,org.eclipse.core.databinding.observable@default:default,org.eclipse.core.databinding.property@default:default,org.eclipse.core.databinding@default:default,org.eclipse.core.expressions@default:default,org.eclipse.core.filesystem.java7@default:false,org.eclipse.core.filesystem.macosx@default:false,org.eclipse.core.filesystem@default:default,org.eclipse.core.jobs@default:default,org.eclipse.core.resources@default:default,org.eclipse.core.runtime.compatibility.registry@default:false,org.eclipse.core.runtime@default:true,org.eclipse.e4.core.commands@default:default,org.eclipse.e4.core.contexts@default:default,org.eclipse.e4.core.di.extensions@default:default,org.eclipse.e4.core.di@default:default,org.eclipse.e4.core.services@default:default,org.eclipse.e4.ui.bindings@default:default,org.eclipse.e4.ui.css.core@default:default,org.eclipse.e4.ui.css.swt.theme@default:default,org.eclipse.e4.ui.css.swt@default:default,org.eclipse.e4.ui.di@default:default,org.eclipse.e4.ui.model.workbench@default:default,org.eclipse.e4.ui.services@default:default,org.eclipse.e4.ui.widgets@default:default,org.eclipse.e4.ui.workbench.addons.swt@default:default,org.eclipse.e4.ui.workbench.renderers.swt.cocoa@default:false,org.eclipse.e4.ui.workbench.renderers.swt@default:default,org.eclipse.e4.ui.workbench.swt@default:default,org.eclipse.e4.ui.workbench3@default:default,org.eclipse.e4.ui.workbench@default:default,org.eclipse.emf.common@default:default,org.eclipse.emf.ecore.change@default:default,org.eclipse.emf.ecore.xmi@default:default,org.eclipse.emf.ecore@default:default,org.eclipse.equinox.app@default:default,org.eclipse.equinox.cm@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.ds@1:true,org.eclipse.equinox.event@default:true,org.eclipse.equinox.preferences@default:default,org.eclipse.equinox.region@default:false,org.eclipse.equinox.registry@default:default,org.eclipse.equinox.transforms.hook@default:false,org.eclipse.equinox.util@default:default,org.eclipse.equinox.weaving.hook@default:false,org.eclipse.help@default:default,org.eclipse.jface.databinding@default:default,org.eclipse.jface@default:default,org.eclipse.osgi.compatibility.state@default:false,org.eclipse.osgi.services@default:default,org.eclipse.osgi@-1:true,org.eclipse.swt.cocoa.macosx.x86_64@default:false,org.eclipse.swt@default:default,org.eclipse.team.core@default:default,org.eclipse.ui.cocoa@default:false,org.eclipse.ui.trace@default:default,org.eclipse.ui.workbench@default:default,org.eclipse.ui@default:default,org.hamcrest.core@default:default,org.hamcrest.integration@default:default,org.hamcrest.library@default:default,org.hamcrest.text@default:default,org.hamcrest@default:default,org.junit@default:default,org.mockito@default:default,org.objenesis@default:default,org.slf4j.api@default:default,org.w3c.css.sac@default:default,org.w3c.dom.events@default:default,org.w3c.dom.smil@default:default,org.w3c.dom.svg@default:default"/>
<stringAttribute key="selected_workspace_plugins" value="org.eclipse.smarthome.config.core.test@default:false,org.eclipse.smarthome.config.core@default:default,org.eclipse.smarthome.config.xml.test@default:false,org.eclipse.smarthome.config.xml@default:default,org.eclipse.smarthome.core.autoupdate@default:default,org.eclipse.smarthome.core.test@default:false,org.eclipse.smarthome.core.thing.test@default:false,org.eclipse.smarthome.core.thing@default:true,org.eclipse.smarthome.core@default:true,org.eclipse.smarthome.io.console@default:default,org.eclipse.smarthome.test@default:default"/>
<booleanAttribute key="show_selected_only" value="false"/>
<booleanAttribute key="tracing" value="false"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/**
* Copyright (c) 2014-2017 by the respective copyright holders.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.smarthome.core.thing.internal;

import static org.mockito.Matchers.*;
import static org.mockito.Mockito.*;
import static org.mockito.MockitoAnnotations.initMocks;

import java.util.Collections;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import org.eclipse.smarthome.core.common.registry.ProviderChangeListener;
import org.eclipse.smarthome.core.i18n.LocaleProvider;
import org.eclipse.smarthome.core.items.Item;
import org.eclipse.smarthome.core.items.ItemFactory;
import org.eclipse.smarthome.core.items.ItemRegistry;
import org.eclipse.smarthome.core.library.items.NumberItem;
import org.eclipse.smarthome.core.thing.Channel;
import org.eclipse.smarthome.core.thing.ChannelUID;
import org.eclipse.smarthome.core.thing.ThingRegistry;
import org.eclipse.smarthome.core.thing.link.ItemChannelLink;
import org.eclipse.smarthome.core.thing.link.ItemChannelLinkRegistry;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;

/**
*
* @author Simon Kaufmann - initial contribution and API
*
*/
public class ChannelItemProviderTest {

private static final String ITEM_NAME = "test";
private static final ChannelUID CHANNEL_UID = new ChannelUID("test:test:test:test");
private static final NumberItem ITEM = new NumberItem(ITEM_NAME);

@Mock
private ItemRegistry itemRegistry;
@Mock
private ThingRegistry thingRegistry;
@Mock
private ItemFactory itemFactory;
@Mock
private ProviderChangeListener<Item> listener;
@Mock
private LocaleProvider localeProvider;
@Mock
private ItemChannelLinkRegistry linkRegistry;

private ChannelItemProvider provider;

@Before
public void setup() throws Exception {
initMocks(this);

provider = new ChannelItemProvider();
provider.setItemRegistry(itemRegistry);
provider.setThingRegistry(thingRegistry);
provider.setItemChannelLinkRegistry(linkRegistry);
provider.addItemFactory(itemFactory);
provider.setLocaleProvider(localeProvider);
provider.addProviderChangeListener(listener);

Map<String, Object> props = new HashMap<>();
props.put("enable", "true");
provider.activate(props);
Thread.sleep(2500);

when(thingRegistry.getChannel(same(CHANNEL_UID))).thenReturn(new Channel(CHANNEL_UID, "Number"));
when(itemFactory.createItem("Number", ITEM_NAME)).thenReturn(ITEM);
when(localeProvider.getLocale()).thenReturn(Locale.ENGLISH);
}

@Test
public void testItemCreation_notThere() throws Exception {
provider.linkRegistryListener.added(new ItemChannelLink(ITEM_NAME, CHANNEL_UID));
verify(listener, only()).added(same(provider), same(ITEM));
}

@Test
public void testItemCreation_alreadyExists() throws Exception {
when(itemRegistry.get(eq(ITEM_NAME))).thenReturn(ITEM);

provider.linkRegistryListener.added(new ItemChannelLink(ITEM_NAME, CHANNEL_UID));
verify(listener, never()).added(same(provider), same(ITEM));
}

@Test
public void testItemRemoval_linkRemoved() throws Exception {
provider.linkRegistryListener.added(new ItemChannelLink(ITEM_NAME, CHANNEL_UID));

resetAndPrepareListener();

provider.linkRegistryListener.removed(new ItemChannelLink(ITEM_NAME, CHANNEL_UID));
verify(listener, never()).added(same(provider), same(ITEM));
verify(listener, only()).removed(same(provider), same(ITEM));
}

@Test
public void testItemRemoval_itemFromOtherProvider() throws Exception {
provider.linkRegistryListener.added(new ItemChannelLink(ITEM_NAME, CHANNEL_UID));

resetAndPrepareListener();

provider.itemRegistryListener.added(new NumberItem(ITEM_NAME));
verify(listener, only()).removed(same(provider), same(ITEM));
verify(listener, never()).added(same(provider), same(ITEM));
}

@SuppressWarnings("unchecked")
private void resetAndPrepareListener() {
reset(listener);
doAnswer(invocation -> {
// this is crucial as it mimicks the real ItemRegistry's behavior
provider.itemRegistryListener.removed((Item) invocation.getArguments()[1]);
return null;
}).when(listener).removed(same(provider), any(Item.class));
doAnswer(invocation -> {
// this is crucial as it mimicks the real ItemRegistry's behavior
provider.itemRegistryListener.added((Item) invocation.getArguments()[1]);
return null;
}).when(listener).added(same(provider), any(Item.class));
when(linkRegistry.getBoundChannels(eq(ITEM_NAME))).thenReturn(Collections.singleton(CHANNEL_UID));
when(linkRegistry.getLinks(eq(CHANNEL_UID)))
.thenReturn(Collections.singleton(new ItemChannelLink(ITEM_NAME, CHANNEL_UID)));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,6 @@ private void removeItem(String key) {
}
Item item = items.get(key);
if (item != null) {
items.remove(key);
for (ProviderChangeListener<Item> listener : listeners) {
listener.removed(this, item);
}
Expand Down Expand Up @@ -329,17 +328,25 @@ public void added(Item element) {
}
}
// it is from some other provider, so remove ours, if we have one
Item oldElement = items.remove(element.getName());
Item oldElement = items.get(element.getName());
if (oldElement != null) {
for (ProviderChangeListener<Item> listener : listeners) {
listener.removed(ChannelItemProvider.this, oldElement);
}
items.remove(element.getName());
}
lastUpdate = System.nanoTime();
}

@Override
public void removed(Item element) {
// check, if it is our own item
for (Item item : items.values()) {
if (item == element) {
return;
}
}
// it is from some other provider, so create one ourselves if needed
for (ChannelUID uid : linkRegistry.getBoundChannels(element.getName())) {
for (ItemChannelLink link : linkRegistry.getLinks(uid)) {
if (itemRegistry.get(link.getItemName()) == null) {
Expand Down