You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by ro...@apache.org on 2018/04/14 01:10:31 UTC

svn commit: r1829115 [7/12] - in /aries/trunk/cdi: ./ cdi-extender/ cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/ cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/bean/ cdi-extender/src/main/java/org/apache/aries...

Added: aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/model/ReferenceModel_ServiceTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/model/ReferenceModel_ServiceTest.java?rev=1829115&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/model/ReferenceModel_ServiceTest.java (added)
+++ aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/model/ReferenceModel_ServiceTest.java Sat Apr 14 01:10:27 2018
@@ -0,0 +1,891 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.aries.cdi.container.internal.model;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.List;
+import java.util.Optional;
+import java.util.concurrent.Callable;
+
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.inject.Inject;
+
+import org.apache.aries.cdi.container.internal.model.CollectionType;
+import org.apache.aries.cdi.container.internal.model.ReferenceModel;
+import org.apache.aries.cdi.container.test.MockInjectionPoint;
+import org.apache.aries.cdi.container.test.beans.Foo;
+import org.junit.Test;
+import org.osgi.service.cdi.annotations.Reference;
+import org.osgi.util.converter.TypeReference;
+
+public class ReferenceModel_ServiceTest {
+
+	@Test
+	public void withoutServiceDefined_raw() throws Exception {
+		Type type = new TypeReference<
+			Integer
+		>(){}.getType();
+
+		class C {
+			@Inject
+			@Reference
+			public Integer m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(Integer.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertFalse(referenceModel.optional());
+		assertTrue(referenceModel.unary());
+		assertEquals(CollectionType.SERVICE, referenceModel.getCollectionType());
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void withoutServiceDefined_wildcard() throws Exception {
+		class C {
+			@Inject
+			@Reference
+			public Callable<?> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test
+	public void withoutServiceDefined_optional() throws Exception {
+		Type type = new TypeReference<
+			Optional<Integer>
+		>(){}.getType();
+
+		class C {
+			@Inject
+			@Reference
+			public Optional<Integer> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(Optional.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertTrue(referenceModel.optional());
+		assertTrue(referenceModel.unary());
+		assertEquals(CollectionType.SERVICE, referenceModel.getCollectionType());
+	}
+
+	@Test
+	public void withServiceDefined_raw() throws Exception {
+		Type type = new TypeReference<
+			Integer
+		>(){}.getType();
+
+		class C {
+			@Inject
+			@Reference(Integer.class)
+			public Integer m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(Integer.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertFalse(referenceModel.optional());
+		assertTrue(referenceModel.unary());
+		assertEquals(CollectionType.SERVICE, referenceModel.getCollectionType());
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void withServiceDefined_wildcard() throws Exception {
+		class C {
+			@Inject
+			@Reference(Callable.class)
+			public Callable<?> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test
+	public void withServiceDefined_optional() throws Exception {
+		Type type = new TypeReference<
+			Optional<?>
+		>(){}.getType();
+
+		class C {
+			@Inject
+			@Reference(Integer.class)
+			public Optional<?> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(Optional.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertTrue(referenceModel.optional());
+		assertTrue(referenceModel.unary());
+		assertEquals(CollectionType.SERVICE, referenceModel.getCollectionType());
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void withServiceDefined_wrongtype() throws Exception {
+		class C {
+			@Inject
+			@Reference(Foo.class)
+			public Integer m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void withServiceDefined_optional_wrongtype() throws Exception {
+		class C {
+			@Inject
+			@Reference(Foo.class)
+			public Optional<Integer> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void collectionwithoutServiceDefined_raw() throws Exception {
+		class C {
+			@SuppressWarnings("rawtypes")
+			@Inject
+			@Reference
+			public Collection m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void collectionwithoutServiceDefined_wildcard() throws Exception {
+		class C {
+			@Inject
+			@Reference
+			public Collection<?> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test
+	public void collectionwithoutServiceDefined_typed() throws Exception {
+		Type type = new TypeReference<
+			Collection<Integer>
+		>(){}.getType();
+
+		class C {
+			@Inject
+			@Reference
+			public Collection<Integer> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(Collection.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertTrue(referenceModel.optional());
+		assertFalse(referenceModel.unary());
+		assertEquals(CollectionType.SERVICE, referenceModel.getCollectionType());
+	}
+
+	@Test
+	public void collectionwithServiceDefined_raw() throws Exception {
+		@SuppressWarnings("rawtypes")
+		Type type = new TypeReference<
+			Collection
+		>(){}.getType();
+
+		class C {
+			@SuppressWarnings("rawtypes")
+			@Inject
+			@Reference(Integer.class)
+			public Collection m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(Collection.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertTrue(referenceModel.optional());
+		assertFalse(referenceModel.unary());
+		assertEquals(CollectionType.SERVICE, referenceModel.getCollectionType());
+	}
+
+	@Test
+	public void collectionwithServiceDefined_wildcard() throws Exception {
+		Type type = new TypeReference<
+			Collection<?>
+		>(){}.getType();
+
+		class C {
+			@Inject
+			@Reference(Integer.class)
+			public Collection<?> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(Collection.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertTrue(referenceModel.optional());
+		assertFalse(referenceModel.unary());
+		assertEquals(CollectionType.SERVICE, referenceModel.getCollectionType());
+	}
+
+	@Test
+	public void collectionwithServiceDefined_typed() throws Exception {
+		Type type = new TypeReference<
+			Collection<Integer>
+		>(){}.getType();
+
+		class C {
+			@Inject
+			@Reference(Integer.class)
+			public Collection<Integer> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(Collection.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertTrue(referenceModel.optional());
+		assertFalse(referenceModel.unary());
+		assertEquals(CollectionType.SERVICE, referenceModel.getCollectionType());
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void collectionwithServiceDefined_wrongtype() throws Exception {
+		class C {
+			@Inject
+			@Reference(Integer.class)
+			public Collection<Foo> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void listwithoutServiceDefined_raw() throws Exception {
+		class C {
+			@SuppressWarnings("rawtypes")
+			@Inject
+			@Reference
+			public List m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void listwithoutServiceDefined_wildcard() throws Exception {
+		class C {
+			@Inject
+			@Reference
+			public List<?> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test
+	public void listwithoutServiceDefined_typed() throws Exception {
+		Type type = new TypeReference<
+			List<Integer>
+		>(){}.getType();
+
+		class C {
+			@Inject
+			@Reference
+			public List<Integer> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(List.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertTrue(referenceModel.optional());
+		assertFalse(referenceModel.unary());
+		assertEquals(CollectionType.SERVICE, referenceModel.getCollectionType());
+	}
+
+	@Test
+	public void listwithServiceDefined_raw() throws Exception {
+		@SuppressWarnings("rawtypes")
+		Type type = new TypeReference<
+			List
+		>(){}.getType();
+
+		class C {
+			@SuppressWarnings("rawtypes")
+			@Inject
+			@Reference(Integer.class)
+			public List m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(List.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertTrue(referenceModel.optional());
+		assertFalse(referenceModel.unary());
+		assertEquals(CollectionType.SERVICE, referenceModel.getCollectionType());
+	}
+
+	@Test
+	public void listwithServiceDefined_wildcard() throws Exception {
+		Type type = new TypeReference<
+			List<?>
+		>(){}.getType();
+
+		class C {
+			@Inject
+			@Reference(Integer.class)
+			public List<?> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(List.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertTrue(referenceModel.optional());
+		assertFalse(referenceModel.unary());
+		assertEquals(CollectionType.SERVICE, referenceModel.getCollectionType());
+	}
+
+	@Test
+	public void listwithServiceDefined_typed() throws Exception {
+		Type type = new TypeReference<
+			List<Integer>
+		>(){}.getType();
+
+		class C {
+			@Inject
+			@Reference(Integer.class)
+			public List<Integer> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(List.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertTrue(referenceModel.optional());
+		assertFalse(referenceModel.unary());
+		assertEquals(CollectionType.SERVICE, referenceModel.getCollectionType());
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void listwithServiceDefined_wrongtype() throws Exception {
+		class C {
+			@Inject
+			@Reference(Integer.class)
+			public List<Foo> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	// params
+
+	@Test
+	public void p_withoutServiceDefined_raw() throws Exception {
+		Type type = new TypeReference<
+			Integer
+		>(){}.getType();
+
+		class C {
+			@Inject
+			public void set(@Reference Integer m) {};
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Integer.class).getParameters()[0]);
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(Integer.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertFalse(referenceModel.optional());
+		assertTrue(referenceModel.unary());
+		assertEquals(CollectionType.SERVICE, referenceModel.getCollectionType());
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void p_withoutServiceDefined_wildcard() throws Exception {
+		class C {
+			@Inject
+			public void set(@Reference Callable<?> m) {};
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Callable.class).getParameters()[0]);
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test
+	public void p_withoutServiceDefined_optional() throws Exception {
+		Type type = new TypeReference<
+			Optional<Integer>
+		>(){}.getType();
+
+		class C {
+			@Inject
+			public void set(@Reference Optional<Integer> m) {};
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Optional.class).getParameters()[0]);
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(Optional.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertTrue(referenceModel.optional());
+		assertTrue(referenceModel.unary());
+		assertEquals(CollectionType.SERVICE, referenceModel.getCollectionType());
+	}
+
+	@Test
+	public void p_withServiceDefined_raw() throws Exception {
+		Type type = new TypeReference<
+			Integer
+		>(){}.getType();
+
+		class C {
+			@Inject
+			public void set(@Reference(Integer.class) Integer m) {};
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Integer.class).getParameters()[0]);
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(Integer.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertFalse(referenceModel.optional());
+		assertTrue(referenceModel.unary());
+		assertEquals(CollectionType.SERVICE, referenceModel.getCollectionType());
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void p_withServiceDefined_wildcard() throws Exception {
+		class C {
+			@Inject
+			public void set(@Reference(Callable.class) Callable<?> m) {};
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Callable.class).getParameters()[0]);
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test
+	public void p_withServiceDefined_optional() throws Exception {
+		Type type = new TypeReference<
+			Optional<?>
+		>(){}.getType();
+
+		class C {
+			@Inject
+			public void set(@Reference(Integer.class) Optional<?> m) {};
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Optional.class).getParameters()[0]);
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(Optional.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertTrue(referenceModel.optional());
+		assertTrue(referenceModel.unary());
+		assertEquals(CollectionType.SERVICE, referenceModel.getCollectionType());
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void p_withServiceDefined_wrongtype() throws Exception {
+		class C {
+			@Inject
+			public void set(@Reference(Foo.class) Integer m) {};
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Integer.class).getParameters()[0]);
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void p_withServiceDefined_optional_wrongtype() throws Exception {
+		class C {
+			@Inject
+			public void set(@Reference(Foo.class) Optional<Integer> m) {};
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Optional.class).getParameters()[0]);
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void p_collectionwithoutServiceDefined_raw() throws Exception {
+		class C {
+			@SuppressWarnings("rawtypes")
+			@Inject
+			public void set(@Reference Collection m) {};
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Collection.class).getParameters()[0]);
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void p_collectionwithoutServiceDefined_wildcard() throws Exception {
+		class C {
+			@Inject
+			public void set(@Reference Collection<?> m) {};
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Collection.class).getParameters()[0]);
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test
+	public void p_collectionwithoutServiceDefined_typed() throws Exception {
+		Type type = new TypeReference<
+			Collection<Integer>
+		>(){}.getType();
+
+		class C {
+			@Inject
+			public void set(@Reference Collection<Integer> m) {};
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Collection.class).getParameters()[0]);
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(Collection.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertTrue(referenceModel.optional());
+		assertFalse(referenceModel.unary());
+		assertEquals(CollectionType.SERVICE, referenceModel.getCollectionType());
+	}
+
+	@Test
+	public void p_collectionwithServiceDefined_raw() throws Exception {
+		@SuppressWarnings("rawtypes")
+		Type type = new TypeReference<
+			Collection
+		>(){}.getType();
+
+		class C {
+			@SuppressWarnings("rawtypes")
+			@Inject
+			public void set(@Reference(Integer.class) Collection m) {};
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Collection.class).getParameters()[0]);
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(Collection.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertTrue(referenceModel.optional());
+		assertFalse(referenceModel.unary());
+		assertEquals(CollectionType.SERVICE, referenceModel.getCollectionType());
+	}
+
+	@Test
+	public void p_collectionwithServiceDefined_wildcard() throws Exception {
+		Type type = new TypeReference<
+			Collection<?>
+		>(){}.getType();
+
+		class C {
+			@Inject
+			public void set(@Reference(Integer.class) Collection<?> m) {};
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Collection.class).getParameters()[0]);
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(Collection.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertTrue(referenceModel.optional());
+		assertFalse(referenceModel.unary());
+		assertEquals(CollectionType.SERVICE, referenceModel.getCollectionType());
+	}
+
+	@Test
+	public void p_collectionwithServiceDefined_typed() throws Exception {
+		Type type = new TypeReference<
+			Collection<Integer>
+		>(){}.getType();
+
+		class C {
+			@Inject
+			public void set(@Reference(Integer.class) Collection<Integer> m) {};
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Collection.class).getParameters()[0]);
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(Collection.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertTrue(referenceModel.optional());
+		assertFalse(referenceModel.unary());
+		assertEquals(CollectionType.SERVICE, referenceModel.getCollectionType());
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void p_collectionwithServiceDefined_wrongtype() throws Exception {
+		class C {
+			@Inject
+			public void set(@Reference(Integer.class) Collection<Foo> m) {};
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", Collection.class).getParameters()[0]);
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void p_listwithoutServiceDefined_raw() throws Exception {
+		class C {
+			@SuppressWarnings("rawtypes")
+			@Inject
+			public void set(@Reference List m) {};
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", List.class).getParameters()[0]);
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void p_listwithoutServiceDefined_wildcard() throws Exception {
+		class C {
+			@Inject
+			public void set(@Reference List<?> m) {};
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", List.class).getParameters()[0]);
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test
+	public void p_listwithoutServiceDefined_typed() throws Exception {
+		Type type = new TypeReference<
+			List<Integer>
+		>(){}.getType();
+
+		class C {
+			@Inject
+			public void set(@Reference List<Integer> m) {};
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", List.class).getParameters()[0]);
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(List.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertTrue(referenceModel.optional());
+		assertFalse(referenceModel.unary());
+		assertEquals(CollectionType.SERVICE, referenceModel.getCollectionType());
+	}
+
+	@Test
+	public void p_listwithServiceDefined_raw() throws Exception {
+		@SuppressWarnings("rawtypes")
+		Type type = new TypeReference<
+			List
+		>(){}.getType();
+
+		class C {
+			@SuppressWarnings("rawtypes")
+			@Inject
+			public void set(@Reference(Integer.class) List m) {};
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", List.class).getParameters()[0]);
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(List.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertTrue(referenceModel.optional());
+		assertFalse(referenceModel.unary());
+		assertEquals(CollectionType.SERVICE, referenceModel.getCollectionType());
+	}
+
+	@Test
+	public void p_listwithServiceDefined_wildcard() throws Exception {
+		Type type = new TypeReference<
+			List<?>
+		>(){}.getType();
+
+		class C {
+			@Inject
+			public void set(@Reference(Integer.class) List<?> m) {};
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", List.class).getParameters()[0]);
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(List.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertTrue(referenceModel.optional());
+		assertFalse(referenceModel.unary());
+		assertEquals(CollectionType.SERVICE, referenceModel.getCollectionType());
+	}
+
+	@Test
+	public void p_listwithServiceDefined_typed() throws Exception {
+		Type type = new TypeReference<
+			List<Integer>
+		>(){}.getType();
+
+		class C {
+			@Inject
+			public void set(@Reference(Integer.class) List<Integer> m) {};
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", List.class).getParameters()[0]);
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(List.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertTrue(referenceModel.optional());
+		assertFalse(referenceModel.unary());
+		assertEquals(CollectionType.SERVICE, referenceModel.getCollectionType());
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void p_listwithServiceDefined_wrongtype() throws Exception {
+		class C {
+			@Inject
+			public void set(@Reference(Integer.class) List<Foo> m) {};
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getMethod("set", List.class).getParameters()[0]);
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+}
\ No newline at end of file

Added: aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/model/ReferenceModel_TupleTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/model/ReferenceModel_TupleTest.java?rev=1829115&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/model/ReferenceModel_TupleTest.java (added)
+++ aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/model/ReferenceModel_TupleTest.java Sat Apr 14 01:10:27 2018
@@ -0,0 +1,620 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.aries.cdi.container.internal.model;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+import javax.enterprise.inject.Instance;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.inject.Inject;
+
+import org.apache.aries.cdi.container.internal.model.CollectionType;
+import org.apache.aries.cdi.container.internal.model.ReferenceModel;
+import org.apache.aries.cdi.container.test.MockInjectionPoint;
+import org.apache.aries.cdi.container.test.beans.Foo;
+import org.junit.Test;
+import org.osgi.service.cdi.annotations.Reference;
+import org.osgi.util.converter.TypeReference;
+
+public class ReferenceModel_TupleTest {
+
+	@Test(expected = IllegalArgumentException.class)
+	public void withoutServiceType_raw() throws Exception {
+		class C {
+			@SuppressWarnings("rawtypes")
+			@Inject
+			@Reference
+			public Map.Entry m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void withoutServiceType_wildcard() throws Exception {
+		class C {
+			@Inject
+			@Reference
+			public Map.Entry<Map<String, ?>, ?> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void withoutServiceType_wildcard_b() throws Exception {
+		class C {
+			@Inject
+			@Reference
+			public Map.Entry<Map<String, Object>, ?> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test
+	public void withoutServiceType_typed() throws Exception {
+		Type type = new TypeReference<
+			Map.Entry<Map<String, ?>, Integer>
+		>(){}.getType();
+
+		class C {
+			@Inject
+			@Reference
+			public Map.Entry<Map<String, ?>, Integer> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(Map.Entry.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertFalse(referenceModel.optional());
+		assertTrue(referenceModel.unary());
+		assertEquals(CollectionType.TUPLE, referenceModel.getCollectionType());
+	}
+
+	@Test
+	public void withoutServiceType_typed_b() throws Exception {
+		Type type = new TypeReference<
+			Map.Entry<Map<String, Object>, Integer>
+		>(){}.getType();
+
+		class C {
+			@Inject
+			@Reference
+			public Map.Entry<Map<String, Object>, Integer> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(Map.Entry.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertFalse(referenceModel.optional());
+		assertTrue(referenceModel.unary());
+		assertEquals(CollectionType.TUPLE, referenceModel.getCollectionType());
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void withoutServiceType_wrongKeyType_A() throws Exception {
+		class C {
+			@Inject
+			@Reference
+			public Map.Entry<?, Integer> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void withoutServiceType_wrongKeyType_B() throws Exception {
+		class C {
+			@Inject
+			@Reference
+			public Map.Entry<Collection<?>, Integer> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void withoutServiceType_wrongKeyType_C() throws Exception {
+		class C {
+			@SuppressWarnings("rawtypes")
+			@Inject
+			@Reference
+			public Map.Entry<Map, Integer> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void withoutServiceType_wrongKeyType_D() throws Exception {
+		class C {
+			@Inject
+			@Reference
+			public Map.Entry<Map<?, Foo>, Integer> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void withoutServiceType_wrongKeyType_E() throws Exception {
+		class C {
+			@Inject
+			@Reference
+			public Map.Entry<Map<String, Foo>, Integer> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void withoutServiceType_wrongKeyType_F() throws Exception {
+		class C {
+			@Inject
+			@Reference
+			public Map.Entry<Map<String, ? extends Foo>, Integer> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void withServiceType_raw() throws Exception {
+		class C {
+			@SuppressWarnings("rawtypes")
+			@Inject
+			@Reference(Integer.class)
+			public Map.Entry m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test
+	public void withServiceType_wildcard() throws Exception {
+		Type type = new TypeReference<
+			Map.Entry<Map<String, ?>, ?>
+		>(){}.getType();
+
+		class C {
+			@Inject
+			@Reference(Integer.class)
+			public Map.Entry<Map<String, ?>, ?> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(Map.Entry.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertFalse(referenceModel.optional());
+		assertTrue(referenceModel.unary());
+		assertEquals(CollectionType.TUPLE, referenceModel.getCollectionType());
+	}
+
+	@Test
+	public void withServiceType_wildcard_b() throws Exception {
+		Type type = new TypeReference<
+			Map.Entry<Map<String, Object>, ?>
+		>(){}.getType();
+
+		class C {
+			@Inject
+			@Reference(Integer.class)
+			public Map.Entry<Map<String, Object>, ?> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(Map.Entry.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertFalse(referenceModel.optional());
+		assertTrue(referenceModel.unary());
+		assertEquals(CollectionType.TUPLE, referenceModel.getCollectionType());
+	}
+
+	@Test
+	public void withServiceType_typed() throws Exception {
+		Type type = new TypeReference<
+			Map.Entry<Map<String, ?>, Integer>
+		>(){}.getType();
+
+		class C {
+			@Inject
+			@Reference(Integer.class)
+			public Map.Entry<Map<String, ?>, Integer> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(Map.Entry.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertFalse(referenceModel.optional());
+		assertTrue(referenceModel.unary());
+		assertEquals(CollectionType.TUPLE, referenceModel.getCollectionType());
+	}
+
+	@Test
+	public void withServiceType_typed_b() throws Exception {
+		Type type = new TypeReference<
+			Map.Entry<Map<String, Object>, Integer>
+		>(){}.getType();
+
+		class C {
+			@Inject
+			@Reference(Integer.class)
+			public Map.Entry<Map<String, Object>, Integer> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(Map.Entry.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertFalse(referenceModel.optional());
+		assertTrue(referenceModel.unary());
+		assertEquals(CollectionType.TUPLE, referenceModel.getCollectionType());
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void withServiceType_wrongKeyType_A() throws Exception {
+		class C {
+			@Inject
+			@Reference(Integer.class)
+			public Map.Entry<?, Integer> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void withServiceType_wrongKeyType_B() throws Exception {
+		class C {
+			@Inject
+			@Reference(Integer.class)
+			public Map.Entry<Collection<?>, Integer> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void withServiceType_wrongKeyType_C() throws Exception {
+		class C {
+			@SuppressWarnings("rawtypes")
+			@Inject
+			@Reference(Integer.class)
+			public Map.Entry<Map, Integer> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void withServiceType_wrongKeyType_D() throws Exception {
+		class C {
+			@Inject
+			@Reference(Integer.class)
+			public Map.Entry<Map<?, Foo>, Integer> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void withServiceType_wrongKeyType_E() throws Exception {
+		class C {
+			@Inject
+			@Reference(Integer.class)
+			public Map.Entry<Map<String, Foo>, Integer> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void withServiceType_wrongKeyType_F() throws Exception {
+		class C {
+			@Inject
+			@Reference(Integer.class)
+			public Map.Entry<Map<String, ? extends Foo>, Integer> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void withServiceType_wrongtype() throws Exception {
+		class C {
+			@Inject
+			@Reference(Integer.class)
+			public Map.Entry<Map<String, ?>, Foo> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test
+	public void withServiceType_supertype() throws Exception {
+		Type type = new TypeReference<
+			Map.Entry<Map<String, ?>, Number>
+		>(){}.getType();
+
+		class C {
+			@Inject
+			@Reference(Integer.class)
+			public Map.Entry<Map<String, ?>, Number> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(Map.Entry.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertFalse(referenceModel.optional());
+		assertTrue(referenceModel.unary());
+		assertEquals(CollectionType.TUPLE, referenceModel.getCollectionType());
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void collectionWithoutServiceType_raw() throws Exception {
+		class C {
+			@SuppressWarnings("rawtypes")
+			@Inject
+			@Reference
+			public Collection<Map.Entry> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test
+	public void collectionWithoutServiceType_typed() throws Exception {
+		Type type = new TypeReference<
+			Collection<Map.Entry<Map<String, Object>, Foo>>
+		>(){}.getType();
+
+		class C {
+			@Inject
+			@Reference
+			public Collection<Map.Entry<Map<String, Object>, Foo>> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(Collection.class, referenceModel.getBeanClass());
+		assertEquals(Foo.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertTrue(referenceModel.optional());
+		assertFalse(referenceModel.unary());
+		assertEquals(CollectionType.TUPLE, referenceModel.getCollectionType());
+	}
+
+	@Test
+	public void collectionWithServiceType_typed_b() throws Exception {
+		Type type = new TypeReference<
+			Collection<Map.Entry<Map<String, ?>, Number>>
+		>(){}.getType();
+
+		class C {
+			@Inject
+			@Reference(Integer.class)
+			public Collection<Map.Entry<Map<String, ?>, Number>> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(Collection.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertTrue(referenceModel.optional());
+		assertFalse(referenceModel.unary());
+		assertEquals(CollectionType.TUPLE, referenceModel.getCollectionType());
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void collectionWithServiceType_wrongtype() throws Exception {
+		class C {
+			@Inject
+			@Reference(Integer.class)
+			public Collection<Map.Entry<Map<String, Object>, Foo>> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void listWithoutServiceType_raw() throws Exception {
+		class C {
+			@SuppressWarnings("rawtypes")
+			@Inject
+			@Reference
+			public List<Map.Entry> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test
+	public void listWithoutServiceType_typed() throws Exception {
+		Type type = new TypeReference<
+			List<Map.Entry<Map<String, Object>, Foo>>
+		>(){}.getType();
+
+		class C {
+			@Inject
+			@Reference
+			public List<Map.Entry<Map<String, Object>, Foo>> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(List.class, referenceModel.getBeanClass());
+		assertEquals(Foo.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertTrue(referenceModel.optional());
+		assertFalse(referenceModel.unary());
+		assertEquals(CollectionType.TUPLE, referenceModel.getCollectionType());
+	}
+
+	@Test
+	public void listWithServiceType_typed_b() throws Exception {
+		Type type = new TypeReference<
+			List<Map.Entry<Map<String, ?>, Number>>
+		>(){}.getType();
+
+		class C {
+			@Inject
+			@Reference(Integer.class)
+			public List<Map.Entry<Map<String, ?>, Number>> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		ReferenceModel referenceModel = new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+
+		assertEquals(List.class, referenceModel.getBeanClass());
+		assertEquals(Integer.class, referenceModel.getServiceType());
+		assertEquals(type, referenceModel.getInjectionPointType());
+		assertFalse(referenceModel.dynamic());
+		assertTrue(referenceModel.optional());
+		assertFalse(referenceModel.unary());
+		assertEquals(CollectionType.TUPLE, referenceModel.getCollectionType());
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void listWithServiceType_wrongtype() throws Exception {
+		class C {
+			@Inject
+			@Reference(Integer.class)
+			public List<Map.Entry<Map<String, ?>, Foo>> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void instanceWithoutServiceType() throws Exception {
+		class C {
+			@Inject
+			@Reference
+			public Instance<Map.Entry<Map<String, ?>, Number>> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+	@Test(expected = IllegalArgumentException.class)
+	public void instanceWithServiceType() throws Exception {
+		class C {
+			@Inject
+			@Reference(Integer.class)
+			public Instance<Map.Entry<Map<String, ?>, Number>> m;
+		}
+
+		InjectionPoint injectionPoint = new MockInjectionPoint(C.class.getField("m"));
+
+		new ReferenceModel.Builder().injectionPoint(injectionPoint).build();
+	}
+
+}
\ No newline at end of file

Added: aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/phase/CDIBundlePhaseTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/phase/CDIBundlePhaseTest.java?rev=1829115&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/phase/CDIBundlePhaseTest.java (added)
+++ aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/phase/CDIBundlePhaseTest.java Sat Apr 14 01:10:27 2018
@@ -0,0 +1,161 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.aries.cdi.container.internal.phase;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.aries.cdi.container.internal.container.CDIBundle;
+import org.apache.aries.cdi.container.internal.container.ContainerState;
+import org.apache.aries.cdi.container.internal.util.Logs;
+import org.apache.aries.cdi.container.test.BaseCDIBundleTest;
+import org.junit.Test;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.namespace.extender.ExtenderNamespace;
+import org.osgi.service.cdi.CDIConstants;
+import org.osgi.service.cdi.runtime.dto.ContainerDTO;
+
+public class CDIBundlePhaseTest extends BaseCDIBundleTest {
+
+	@Test
+	public void initial() throws Exception {
+		ContainerState containerState = new ContainerState(bundle, ccrBundle, ccrChangeCount, promiseFactory, null, new Logs.Builder(bundle.getBundleContext()).build());
+
+		CDIBundle cdiBundle = new CDIBundle(ccr, containerState, null);
+
+		cdiBundle.start();
+
+		ContainerDTO containerDTO = containerState.containerDTO();
+		assertNotNull(containerDTO);
+
+		assertNotNull(containerDTO.bundle);
+		assertEquals(1, containerDTO.bundle.id);
+		assertEquals(24l, containerDTO.bundle.lastModified);
+		assertEquals(Bundle.ACTIVE, containerDTO.bundle.state);
+		assertEquals("foo", containerDTO.bundle.symbolicName);
+		assertEquals("1.0.0", containerDTO.bundle.version);
+
+		assertEquals(1, containerDTO.changeCount);
+
+		assertTrue(containerDTO.components + "", containerDTO.components.isEmpty());
+		assertTrue(containerDTO.errors + "", containerDTO.errors.isEmpty());
+		assertTrue(containerDTO.extensions + "", containerDTO.extensions.isEmpty());
+
+		assertNotNull(containerDTO.template);
+		assertEquals(2, containerDTO.template.components.size());
+		assertEquals(0, containerDTO.template.extensions.size());
+		assertEquals("foo", containerDTO.template.id);
+
+		cdiBundle.destroy();
+	}
+
+	@Test
+	public void extensions_simple() throws Exception {
+		Map<String, Object> attributes = new HashMap<>();
+
+		attributes.put(CDIConstants.REQUIREMENT_EXTENSIONS_ATTRIBUTE, Arrays.asList("(foo=name)", "(fum=bar)"));
+		attributes.put(CDIConstants.REQUIREMENT_OSGI_BEANS_ATTRIBUTE,
+			Arrays.asList(
+				"org.apache.aries.cdi.container.test.beans.BarAnnotated",
+				"org.apache.aries.cdi.container.test.beans.FooAnnotated",
+				"org.apache.aries.cdi.container.test.beans.FooWithReferenceAndConfig"
+			)
+		);
+
+		when(
+			bundle.adapt(
+				BundleWiring.class).getRequiredWires(
+					ExtenderNamespace.EXTENDER_NAMESPACE).get(
+						0).getRequirement().getAttributes()
+		).thenReturn(attributes);
+
+		ContainerState containerState = new ContainerState(bundle, ccrBundle, ccrChangeCount, promiseFactory, null, new Logs.Builder(bundle.getBundleContext()).build());
+
+		CDIBundle cdiBundle = new CDIBundle(ccr, containerState, null);
+
+		cdiBundle.start();
+
+		ContainerDTO containerDTO = containerState.containerDTO();
+		assertNotNull(containerDTO);
+
+		assertNotNull(containerDTO.bundle);
+		assertEquals(1, containerDTO.bundle.id);
+		assertEquals(24l, containerDTO.bundle.lastModified);
+		assertEquals(Bundle.ACTIVE, containerDTO.bundle.state);
+		assertEquals("foo", containerDTO.bundle.symbolicName);
+		assertEquals("1.0.0", containerDTO.bundle.version);
+
+		assertEquals(1, containerDTO.changeCount);
+
+		assertTrue(containerDTO.components + "", containerDTO.components.isEmpty());
+		assertTrue(containerDTO.errors + "", containerDTO.errors.isEmpty());
+		assertTrue(containerDTO.extensions + "", containerDTO.extensions.isEmpty());
+
+		assertNotNull(containerDTO.template);
+		assertEquals(2, containerDTO.template.components.size());
+		assertEquals(2, containerDTO.template.extensions.size());
+		assertEquals("(foo=name)", containerDTO.template.extensions.get(0).serviceFilter);
+		assertEquals("(fum=bar)", containerDTO.template.extensions.get(1).serviceFilter);
+		assertEquals("foo", containerDTO.template.id);
+
+		cdiBundle.destroy();
+	}
+
+	@Test
+	public void extensions_invalidsyntax() throws Exception {
+		Map<String, Object> attributes = new HashMap<>();
+
+		attributes.put(CDIConstants.REQUIREMENT_EXTENSIONS_ATTRIBUTE, Arrays.asList("(foo=name)", "fum=bar)"));
+
+		when(
+			bundle.adapt(
+				BundleWiring.class).getRequiredWires(
+					ExtenderNamespace.EXTENDER_NAMESPACE).get(
+						0).getRequirement().getAttributes()
+		).thenReturn(attributes);
+
+		ContainerState containerState = new ContainerState(bundle, ccrBundle, ccrChangeCount, promiseFactory, null, new Logs.Builder(bundle.getBundleContext()).build());
+
+		CDIBundle cdiBundle = new CDIBundle(ccr, containerState, null);
+
+		cdiBundle.start();
+
+		ContainerDTO containerDTO = containerState.containerDTO();
+		assertNotNull(containerDTO);
+
+		assertNotNull(containerDTO.bundle);
+		assertEquals(1, containerDTO.bundle.id);
+		assertEquals(24l, containerDTO.bundle.lastModified);
+		assertEquals(Bundle.ACTIVE, containerDTO.bundle.state);
+		assertEquals("foo", containerDTO.bundle.symbolicName);
+		assertEquals("1.0.0", containerDTO.bundle.version);
+
+		assertEquals(1, containerDTO.changeCount);
+
+		assertTrue(containerDTO.components + "", containerDTO.components.isEmpty());
+		assertFalse(containerDTO.errors + "", containerDTO.errors.isEmpty());
+		assertEquals(1, containerDTO.errors.size());
+		assertFalse(containerDTO.template.extensions.isEmpty());
+		assertEquals("(foo=name)", containerDTO.template.extensions.get(0).serviceFilter);
+
+		cdiBundle.destroy();
+	}
+
+}

Added: aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/phase/ConfigurationListenerTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/phase/ConfigurationListenerTest.java?rev=1829115&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/phase/ConfigurationListenerTest.java (added)
+++ aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/phase/ConfigurationListenerTest.java Sat Apr 14 01:10:27 2018
@@ -0,0 +1,150 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.aries.cdi.container.internal.phase;
+
+import static org.apache.aries.cdi.container.internal.util.Reflection.*;
+import static org.junit.Assert.*;
+
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.aries.cdi.container.internal.container.CheckedCallback;
+import org.apache.aries.cdi.container.internal.container.ConfigurationListener;
+import org.apache.aries.cdi.container.internal.container.ContainerState;
+import org.apache.aries.cdi.container.internal.container.Op;
+import org.apache.aries.cdi.container.internal.model.ContainerActivator;
+import org.apache.aries.cdi.container.internal.model.ContainerComponent;
+import org.apache.aries.cdi.container.internal.util.Logs;
+import org.apache.aries.cdi.container.internal.util.Maps;
+import org.apache.aries.cdi.container.test.BaseCDIBundleTest;
+import org.apache.aries.cdi.container.test.MockConfiguration;
+import org.apache.aries.cdi.container.test.TestUtil;
+import org.junit.Test;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.service.cdi.runtime.dto.ContainerDTO;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.service.cm.ConfigurationEvent;
+import org.osgi.util.promise.Promise;
+import org.osgi.util.tracker.ServiceTracker;
+
+public class ConfigurationListenerTest extends BaseCDIBundleTest {
+
+	@Test
+	public void configuration_tracking() throws Exception {
+		ServiceTracker<ConfigurationAdmin, ConfigurationAdmin> caTracker = TestUtil.mockCaSt(bundle);
+
+		MockConfiguration mockConfiguration = new MockConfiguration("foo.config", null);
+		mockConfiguration.update(Maps.dict("fiz", "buz"));
+		TestUtil.configurations.add(mockConfiguration);
+
+		mockConfiguration = new MockConfiguration("osgi.cdi.foo", null);
+		mockConfiguration.update(Maps.dict("foo", "bar"));
+		TestUtil.configurations.add(mockConfiguration);
+
+		ContainerState containerState = new ContainerState(bundle, ccrBundle, ccrChangeCount, promiseFactory, caTracker, new Logs.Builder(bundle.getBundleContext()).build());
+
+		ConfigurationListener configurationListener = new ConfigurationListener.Builder(containerState
+		).component(
+			new ContainerComponent.Builder(containerState,
+				new ContainerActivator.Builder(containerState, null)
+			).template(
+				containerState.containerDTO().template.components.get(0)
+			).build()
+		).build();
+
+		Promise<Boolean> p0 = containerState.addCallback(
+			(CheckedCallback<Boolean, Boolean>) op -> {
+				return op.mode == Op.Mode.OPEN && op.type == Op.Type.CONTAINER_COMPONENT;
+			}
+		);
+
+		configurationListener.open();
+
+		ContainerDTO containerDTO = containerState.containerDTO();
+		assertNotNull(containerDTO);
+		assertEquals(1, containerDTO.changeCount);
+		assertTrue(containerDTO.errors + "", containerDTO.errors.isEmpty());
+		assertNotNull(containerDTO.template);
+
+		final Filter filter = FrameworkUtil.createFilter("(objectClass=" + org.osgi.service.cm.ConfigurationListener.class.getName() + ")");
+
+		AtomicReference<org.osgi.service.cm.ConfigurationListener> listener = new AtomicReference<>();
+
+		int attempts = 100;
+		do {
+			TestUtil.serviceRegistrations.stream().filter(
+				reg ->
+					filter.match(reg.getReference())
+			).findFirst().ifPresent(
+				reg -> listener.set(cast(reg.getReference().getService()))
+			);
+
+			Thread.sleep(10);
+		} while(listener.get() == null && (attempts-- > 0));
+
+		p0.timeout(200).getValue();
+
+		final String pid = containerState.containerDTO().components.get(0).template.configurations.get(0).pid;
+
+		assertNotNull(containerState.containerDTO().components.get(0).instances.get(0).properties);
+		assertEquals("bar", containerState.containerDTO().components.get(0).instances.get(0).properties.get("foo"));
+
+		Promise<Boolean> p1 = containerState.addCallback(
+			(CheckedCallback<Boolean, Boolean>) op -> {
+				return op.mode == Op.Mode.OPEN && op.type == Op.Type.CONTAINER_COMPONENT;
+			}
+		);
+
+		listener.get().configurationEvent(
+			new ConfigurationEvent(caTracker.getServiceReference(), ConfigurationEvent.CM_DELETED, null, pid));
+
+		p1.timeout(200).getFailure();
+
+		assertNotNull(containerState.containerDTO().components.get(0).instances.get(0).properties);
+		assertNull(containerState.containerDTO().components.get(0).instances.get(0).properties.get("foo"));
+
+		Promise<Boolean> p2 = containerState.addCallback(
+			(CheckedCallback<Boolean, Boolean>) op -> {
+				return op.mode == Op.Mode.OPEN && op.type == Op.Type.CONTAINER_COMPONENT;
+			}
+		);
+
+		listener.get().configurationEvent(
+			new ConfigurationEvent(caTracker.getServiceReference(), ConfigurationEvent.CM_UPDATED, null, pid));
+
+		p2.timeout(200).getValue();
+
+		assertNotNull(containerState.containerDTO().components.get(0).instances.get(0).properties);
+		assertEquals("bar", containerState.containerDTO().components.get(0).instances.get(0).properties.get("foo"));
+
+		Promise<Boolean> p3 = containerState.addCallback(
+			(CheckedCallback<Boolean, Boolean>) op -> {
+				return op.mode == Op.Mode.OPEN && op.type == Op.Type.CONTAINER_COMPONENT;
+			}
+		);
+
+		listener.get().configurationEvent(
+			new ConfigurationEvent(caTracker.getServiceReference(), ConfigurationEvent.CM_UPDATED, null, "foo.config"));
+
+		p3.timeout(200).getValue();
+
+		Map<String, Object> properties = containerState.containerDTO().components.get(0).instances.get(0).properties;
+		assertNotNull(properties);
+		assertNull(properties.get("fiz"));
+		assertEquals("bar", properties.get("foo"));
+	}
+
+}

Added: aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/phase/ContainerBootstrapTest.java
URL: http://svn.apache.org/viewvc/aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/phase/ContainerBootstrapTest.java?rev=1829115&view=auto
==============================================================================
--- aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/phase/ContainerBootstrapTest.java (added)
+++ aries/trunk/cdi/cdi-extender/src/test/java/org/apache/aries/cdi/container/internal/phase/ContainerBootstrapTest.java Sat Apr 14 01:10:27 2018
@@ -0,0 +1,111 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.aries.cdi.container.internal.phase;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.apache.aries.cdi.container.internal.container.CheckedCallback;
+import org.apache.aries.cdi.container.internal.container.ConfigurationListener;
+import org.apache.aries.cdi.container.internal.container.ContainerBootstrap;
+import org.apache.aries.cdi.container.internal.container.ContainerState;
+import org.apache.aries.cdi.container.internal.container.Op;
+import org.apache.aries.cdi.container.internal.model.ContainerActivator;
+import org.apache.aries.cdi.container.internal.model.ExtendedComponentInstanceDTO;
+import org.apache.aries.cdi.container.internal.model.FactoryComponent;
+import org.apache.aries.cdi.container.internal.model.SingleComponent;
+import org.apache.aries.cdi.container.internal.util.Logs;
+import org.apache.aries.cdi.container.test.BaseCDIBundleTest;
+import org.apache.aries.cdi.container.test.TestUtil;
+import org.apache.aries.cdi.container.test.beans.FooService;
+import org.junit.Test;
+import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.namespace.extender.ExtenderNamespace;
+import org.osgi.service.cdi.CDIConstants;
+import org.osgi.service.cdi.runtime.dto.ComponentDTO;
+import org.osgi.service.cdi.runtime.dto.ContainerDTO;
+import org.osgi.service.cm.ConfigurationAdmin;
+import org.osgi.util.promise.Promise;
+import org.osgi.util.tracker.ServiceTracker;
+
+public class ContainerBootstrapTest extends BaseCDIBundleTest {
+
+	@Test
+	public void test_publishServices() throws Exception {
+		Map<String, Object> attributes = new HashMap<>();
+
+		attributes.put(
+			CDIConstants.REQUIREMENT_OSGI_BEANS_ATTRIBUTE,
+			Arrays.asList(
+				FooService.class.getName()
+			)
+		);
+
+		when(
+			bundle.adapt(
+				BundleWiring.class).getRequiredWires(
+					ExtenderNamespace.EXTENDER_NAMESPACE).get(
+						0).getRequirement().getAttributes()
+		).thenReturn(attributes);
+
+		ServiceTracker<ConfigurationAdmin, ConfigurationAdmin> caTracker = TestUtil.mockCaSt(bundle);
+
+		ContainerState containerState = new ContainerState(bundle, ccrBundle, ccrChangeCount, promiseFactory, caTracker, new Logs.Builder(bundle.getBundleContext()).build());
+
+		ComponentDTO componentDTO = new ComponentDTO();
+		componentDTO.instances = new CopyOnWriteArrayList<>();
+		componentDTO.template = containerState.containerDTO().template.components.get(0);
+
+		ContainerBootstrap containerBootstrap = new ContainerBootstrap(
+			containerState,
+			new ConfigurationListener.Builder(containerState),
+			new SingleComponent.Builder(containerState, null),
+			new FactoryComponent.Builder(containerState, null));
+
+		ExtendedComponentInstanceDTO componentInstanceDTO = new ExtendedComponentInstanceDTO(containerState, new ContainerActivator.Builder(containerState, containerBootstrap));
+		componentInstanceDTO.activations = new CopyOnWriteArrayList<>();
+		componentInstanceDTO.configurations = new CopyOnWriteArrayList<>();
+		componentInstanceDTO.pid = componentDTO.template.configurations.get(0).pid;
+		componentInstanceDTO.properties = null;
+		componentInstanceDTO.references = new CopyOnWriteArrayList<>();
+		componentInstanceDTO.template = componentDTO.template;
+
+		componentDTO.instances.add(componentInstanceDTO);
+
+		containerState.containerDTO().components.add(componentDTO);
+
+		Promise<Boolean> p0 = containerState.addCallback(
+			(CheckedCallback<Boolean, Boolean>) op -> {
+				return op.mode == Op.Mode.OPEN && op.type == Op.Type.CONTAINER_PUBLISH_SERVICES;
+			}
+		);
+
+		containerBootstrap.open();
+
+		ContainerDTO containerDTO = containerState.containerDTO();
+		assertNotNull(containerDTO);
+		assertEquals(1, containerDTO.changeCount);
+		assertTrue(containerDTO.errors + "", containerDTO.errors.isEmpty());
+		assertNotNull(containerDTO.template);
+
+		assertTrue(p0.timeout(200).getValue());
+	}
+
+}