HibernateUserAdministrationTest now based on the component mechanism.
[utils] / system / general / src / test / java / org / wamblee / system / core / ContainerTest.java
index 9bb53a6a6c1a615c7bd4c0218e90a4bc78921679..2104e3a94e3dbba93db6d6de0c19cfe11983cf75 100644 (file)
  * 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.wamblee.system.core;
 
+import java.io.IOException;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 
-import org.wamblee.system.core.Component;
-import org.wamblee.system.core.Container;
-import org.wamblee.system.core.DefaultProvidedInterface;
-import org.wamblee.system.core.DefaultRequiredInterface;
-import org.wamblee.system.core.ProvidedInterface;
-import org.wamblee.system.core.RequiredInterface;
-import org.wamblee.system.core.SystemAssemblyException;
-import org.wamblee.system.core.Component.Status;
+import junit.framework.TestCase;
+
+import org.easymock.classextension.ConstructorArgs;
+import org.easymock.classextension.EasyMock;
+import org.easymock.classextension.IMocksControl;
+import org.wamblee.general.Pair;
 import org.wamblee.test.AssertionUtils;
+import org.wamblee.test.EasyMockMatchers;
 import org.wamblee.test.EventTracker;
 
-import junit.framework.TestCase;
-
 public class ContainerTest extends TestCase {
 
-       private EventTracker<String> _tracker;
-
-       @Override
-       protected void setUp() throws Exception {
-               super.setUp();
-               _tracker = new EventTracker<String>();
-       }
-
-       private static class MyMultiple implements Serializable, Runnable {
-               @Override
-               public void run() {
-                       // Empty
-               }
-       }
-
-       public void testFilterProvided() {
-               RequiredInterface req1 = new DefaultRequiredInterface("name",
-                               Runnable.class);
-               RequiredInterface req2 = new DefaultRequiredInterface("name",
-                               Serializable.class);
-               ProvidedInterface prov1 = new DefaultProvidedInterface("name",
-                               Runnable.class);
-               ProvidedInterface prov2 = new DefaultProvidedInterface("name",
-                               Serializable.class);
-               ProvidedInterface prov3 = new DefaultProvidedInterface("name",
-                               MyMultiple.class);
-
-               AssertionUtils.assertEquals(new RequiredInterface[] { req1 },
-                               Container.filterRequiredServices(prov1, Arrays
-                                               .asList(new RequiredInterface[] { req1 })));
-               AssertionUtils.assertEquals(new RequiredInterface[] { req1 },
-                               Container.filterRequiredServices(prov1, Arrays
-                                               .asList(new RequiredInterface[] { req1, req2 })));
-               AssertionUtils.assertEquals(new RequiredInterface[] { req1, req2 },
-                               Container.filterRequiredServices(prov3, Arrays
-                                               .asList(new RequiredInterface[] { req1, req2 })));
-
-               AssertionUtils.assertEquals(new ProvidedInterface[] { prov1 },
-                               Container.filterProvidedServices(req1, Arrays
-                                               .asList(new ProvidedInterface[] { prov1 })));
-               AssertionUtils.assertEquals(new ProvidedInterface[] { prov1 },
-                               Container.filterProvidedServices(req1, Arrays
-                                               .asList(new ProvidedInterface[] { prov1, prov2 })));
-               AssertionUtils.assertEquals(new ProvidedInterface[] { prov1, prov3 },
-                               Container.filterProvidedServices(req1, Arrays
-                                               .asList(new ProvidedInterface[] { prov1, prov3 })));
-       }
-
-       public void testEnvironmentApplication() {
-               Component environment = new Environment(_tracker);
-               Component application = new Application(_tracker);
-               Container container = new Container("root", new Component[] {
-                               environment, application }, new ProvidedInterface[0],
-                               new RequiredInterface[0]);
-                               
-               container.start();
-               AssertionUtils.assertEquals(new String[] { "start.environment",
-                               "start.application" }, _tracker.getEvents(
-                               Thread.currentThread()).toArray(new String[0]));
-               ProvidedInterface[] envServices = environment.getRunningServices();
-               assertEquals(2, envServices.length);
-               ProvidedInterface[] appServices = environment.getRunningServices();
-               assertEquals(2, appServices.length);
-               
-       }
-
-       public void testApplicationEnvironment() {
-               try {
-                       Component environment = new Environment();
-                       Component application = new Application();
-                       Container container = new Container(
-                                       "root",
-                                       new Component[] {
-                                       application, environment }, 
-                                       new ProvidedInterface[0], new RequiredInterface[0]);
-                       container.start();
-               } catch (SystemAssemblyException e) {
-                       // e.printStackTrace();
-                       return;
-               }
-               fail();
-       }
-
-       public void testComposite() {
-               Component environment = new Environment(_tracker);
-               Component application = new Application(_tracker);
-               assertEquals(0, _tracker.getEventCount());
-               assertEquals(Status.NOT_STARTED, environment.getStatus());
-               assertEquals(Status.NOT_STARTED, application.getStatus());
-               
-               Container system = new Container("all", new Component[] { environment,
-                               application }, new ProvidedInterface[0],
-                               new RequiredInterface[0]);
-               assertEquals(Status.NOT_STARTED, system.getStatus());
-               system.start();
-               RequiredInterface[] required = system.getRequiredServices();
-               assertEquals(0, required.length);
-               ProvidedInterface[] provided = system.getProvidedServices();
-               assertEquals(0, provided.length);
-               assertEquals(Status.RUNNING, environment.getStatus());
-               assertEquals(Status.RUNNING, application.getStatus());
-               assertEquals(Status.RUNNING, system.getStatus());
-               
-               AssertionUtils.assertEquals(
-                               new String[] { "start.environment", "start.application" }, 
-                               _tracker.getEvents(Thread.currentThread()).toArray(new String[0]));
+    private EventTracker<String> _tracker;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        _tracker = new EventTracker<String>();
+    }
+
+    private static class MyMultiple implements Serializable, Runnable {
+        @Override
+        public void run() {
+            // Empty
+        }
+    }
+
+    private List<Pair<ProvidedInterface, Component>> createProvidedInput(
+            ProvidedInterface[] aProvided, Component aProvider) {
+        List<Pair<ProvidedInterface, Component>> result = new ArrayList<Pair<ProvidedInterface, Component>>();
+        for (ProvidedInterface provided : aProvided) {
+            result.add(new Pair<ProvidedInterface, Component>(provided,
+                    aProvider));
+        }
+        return result;
+    }
+
+    public void testFilterProvided() {
+        RequiredInterface req1 = new DefaultRequiredInterface("name",
+                Runnable.class);
+        RequiredInterface req2 = new DefaultRequiredInterface("name",
+                Serializable.class);
+        ProvidedInterface prov1 = new DefaultProvidedInterface("name",
+                Runnable.class);
+        ProvidedInterface prov2 = new DefaultProvidedInterface("name",
+                Serializable.class);
+        ProvidedInterface prov3 = new DefaultProvidedInterface("name",
+                MyMultiple.class);
+        
+        Component client = new Application("client");
+        Component dummy = new Application("dummy");
+        
+        InterfaceRestriction noRestriction = new InterfaceRestriction() { 
+          @Override
+            public boolean isViolated(Component aClient,
+                    RequiredInterface aRequired, Component aServer,
+                    ProvidedInterface aProvided) {
+                return false;
+            }  
+        };
+
+        AssertionUtils.assertEquals(new ProvidedInterface[] { prov1 },
+                Container.filterProvidedServices(client, req1, 
+                        createProvidedInput(new ProvidedInterface[] { prov1 }, dummy), noRestriction));
+        AssertionUtils.assertEquals(new ProvidedInterface[] { prov1 },
+                Container.filterProvidedServices(client, req1, 
+                        createProvidedInput(new ProvidedInterface[] { prov1, prov2 }, dummy), noRestriction));
+        AssertionUtils.assertEquals(new ProvidedInterface[] { prov1, prov3 },
+                Container.filterProvidedServices(client, req1, 
+                        createProvidedInput(new ProvidedInterface[] { prov1, prov3 }, dummy), noRestriction));
+        
+        InterfaceRestriction everything = new InterfaceRestriction() { 
+            @Override
+            public boolean isViolated(Component aClient,
+                    RequiredInterface aRequired, Component aServer,
+                    ProvidedInterface aProvided) {
+                return true;
+            }
+        };
+        AssertionUtils.assertEquals(new ProvidedInterface[0],
+                Container.filterProvidedServices(client, req1, 
+                        createProvidedInput(new ProvidedInterface[] { prov1, prov3 }, dummy), everything));
+        
+    }
+
+    public void testEnvironmentApplication() {
+        Environment environment = new Environment(_tracker);
+        Application application = new Application(_tracker);
+        Container container = new Container("root", new Component[] {
+                environment, application }, new ProvidedInterface[0],
+                new RequiredInterface[0]);
+        Scope scope = container.start();
+        assertTrue(container.isSealed());
+        AssertionUtils.assertEquals(new String[] { "start.environment",
+                "start.application" }, _tracker.getEvents(
+                Thread.currentThread()).toArray(new String[0]));
+        assertEquals(0, scope.getProvidedInterfaces().length);
+
+        assertEquals(environment.getString(), application.getString());
+        assertEquals(environment.getInteger(), application.getInteger());
+
+    }
+
+    public void testEnvironmentApplicationSimpleConstructor() {
+        Environment environment = new Environment(_tracker);
+        Application application = new Application(_tracker);
+        Container container = new Container("root").addComponent(environment)
+                .addComponent(application);
+
+        Scope scope = container.start();
+        AssertionUtils.assertEquals(new String[] { "start.environment",
+                "start.application" }, _tracker.getEvents(
+                Thread.currentThread()).toArray(new String[0]));
+        assertEquals(0, scope.getProvidedInterfaces().length);
+
+        assertEquals(environment.getString(), application.getString());
+        assertEquals(environment.getInteger(), application.getInteger());
+
+    }
+
+    public void testApplicationEnvironment() {
+        try {
+            Component environment = new Environment();
+            Component application = new Application();
+            Container container = new Container("root", new Component[] {
+                    application, environment }, new ProvidedInterface[0],
+                    new RequiredInterface[0]);
+            container.start();
+        } catch (SystemAssemblyException e) {
+            // e.printStackTrace();
+            return;
+        }
+        fail();
+    }
+
+    public void testComposite() {
+        Component environment = new Environment(_tracker);
+        Component application = new Application(_tracker);
+        assertEquals(0, _tracker.getEventCount());
+
+        Container system = new Container("all", new Component[] { environment,
+                application }, new ProvidedInterface[0],
+                new RequiredInterface[0]);
+        Scope runtime = system.start();
+        RequiredInterface[] required = system.getRequiredInterfaces();
+        assertEquals(0, required.length);
+        ProvidedInterface[] provided = system.getProvidedInterfaces();
+        assertEquals(0, provided.length);
+
+        AssertionUtils.assertEquals(new String[] { "start.environment",
+                "start.application" }, _tracker.getEvents(
+                Thread.currentThread()).toArray(new String[0]));
         _tracker.clear();
-               
-               system.stop();
-               assertEquals(Status.STOPPED, environment.getStatus());
-               assertEquals(Status.STOPPED, application.getStatus());
-               assertEquals(Status.STOPPED, system.getStatus());
-               
-               AssertionUtils.assertEquals(
-                               new String[] { "stop.application", "stop.environment" }, 
-                               _tracker.getEvents(Thread.currentThread()).toArray(new String[0]));
-      
-               
-       }
-
-       public void testCompositeWithWrongProvidedInfo() {
-               try {
-                       Component environment = new Environment();
-                       Component application = new Application();
-                       Container system = new Container("all", new Component[] {
-                                       environment, application },
-                                       new ProvidedInterface[] { new DefaultProvidedInterface(
-                                                       "string", String.class) },
-                                       new DefaultRequiredInterface[0]);
-               } catch (SystemAssemblyException e) {
-                       return;
-               }
-               fail();
-       }
-
-       public void testCompositeRequiredInterfaceNotProvided() {
-               try {
-                       Component environment = new Environment();
-                       Component application = new Application();
-                       Container system = new Container("all", new Component[] {
-                                       environment, application }, new ProvidedInterface[0],
-                                       new RequiredInterface[] { new DefaultRequiredInterface(
-                                                       "string", String.class) });
-                       system.start();
-               } catch (SystemAssemblyException e) {
-                       return;
-               }
-               fail();
-       }
-
-       public void testCompositeWithSuperfluousRequiredInfo() {
-               Component environment = new Environment();
-               Component application = new Application();
-               Container system = new Container("all", new Component[] { environment,
-                               application }, new ProvidedInterface[0],
-                               new RequiredInterface[] { new DefaultRequiredInterface(
-                                               "string", String.class) });
-               system.getRequiredServices()[0]
-                               .setProvider(new DefaultProvidedInterface("hallo", String.class));
-               system.start();
-               RequiredInterface[] required = system.getRequiredServices();
-               assertEquals(1, required.length);
-               ProvidedInterface[] provided = system.getProvidedServices();
-               assertEquals(0, provided.length);
-       }
-
-       public void testCompositeWithExternalDependencesNotProvided() {
-               try {
-                       Component environment = new Environment();
-                       Component application = new Application();
-                       Container system = new Container("all",
-                                       new Component[] { application }, new ProvidedInterface[0],
-                                       application.getRequiredServices());
-                       system.start();
-               } catch (SystemAssemblyException e) {
-                       return;
-               }
-               fail();
-
-       }
-
-       public void testCompositeWithExternalDependencesProvided() {
-
-               Component environment = new Environment();
-               Component application = new Application();
-               Container system = new Container("all",
-                               new Component[] { application }, new ProvidedInterface[0],
-                               application.getRequiredServices());
-               environment.start();
-               system.getRequiredServices()[0].setProvider(environment
-                               .getProvidedServices()[0]);
-               system.getRequiredServices()[1].setProvider(environment
-                               .getProvidedServices()[1]);
-
-               system.start();
-               RequiredInterface[] required = system.getRequiredServices();
-               assertEquals(2, required.length);
-               ProvidedInterface[] provided = system.getProvidedServices();
-               assertEquals(0, provided.length);
-
-       }
-
-       public void testAmbiguousInterfaces() {
-               try {
-                       Component environment1 = new Environment();
-                       Component environment2 = new Environment();
-                       Component application = new Application();
-                       Container container = new Container("root", new Component[] {
-                                       environment1, environment2, application },
-                                       new ProvidedInterface[0], new RequiredInterface[0]);
-                       container.start();
-
-               } catch (SystemAssemblyException e) {
-                       return;
-               }
-               fail();
-       }
-
-       public void testIncompleteRequirements() {
-               try {
-                       Component application = new Application();
-                       Container system = new Container("all",
-                                       new Component[] { application }, new ProvidedInterface[0],
-                                       new RequiredInterface[0]);
-                       system.start();
-               } catch (SystemAssemblyException e) {
-                       return;
-               }
-               fail();
-       }
 
+        system.stop(runtime);
+        AssertionUtils.assertEquals(new String[] { "stop.application",
+                "stop.environment" }, _tracker
+                .getEvents(Thread.currentThread()).toArray(new String[0]));
+
+    }
+
+    public void testCompositeWithWrongProvidedInfo() {
+        try {
+            Component environment = new Environment();
+            Component application = new Application();
+            Container system = new Container("all", new Component[] {
+                    environment, application },
+                    new ProvidedInterface[] { new DefaultProvidedInterface(
+                            "float", Float.class) },
+                    new DefaultRequiredInterface[0]);
+            system.validate();
+        } catch (SystemAssemblyException e) {
+            return;
+        }
+        fail();
+    }
+
+    public void testCompositeRequiredInterfaceNotProvided() {
+        try {
+            Component environment = new Environment();
+            Component application = new Application();
+            Container system = new Container("all", new Component[] {
+                    environment, application }, new ProvidedInterface[0],
+                    new RequiredInterface[] { new DefaultRequiredInterface(
+                            "string", String.class) });
+            system.start();
+        } catch (SystemAssemblyException e) {
+            return;
+        }
+        fail();
+    }
+
+    public void testCompositeWithSuperfluousRequiredInfo() {
+        Component environment = new Environment();
+        Component application = new Application();
+        Container system = new Container("all", new Component[] { environment,
+                application }, new ProvidedInterface[0],
+                new RequiredInterface[] { new DefaultRequiredInterface("float",
+                        Float.class) });
+        system.getRequiredInterfaces()[0]
+                .setProvider(new DefaultProvidedInterface("hallo", Float.class));
+        system.start();
+        RequiredInterface[] required = system.getRequiredInterfaces();
+        assertEquals(1, required.length);
+        ProvidedInterface[] provided = system.getProvidedInterfaces();
+        assertEquals(0, provided.length);
+    }
+
+    public void testCompositeWithExternalDependencesNotProvided() {
+        try {
+            Component environment = new Environment();
+            Component application = new Application();
+            Container system = new Container("all",
+                    new Component[] { application }, new ProvidedInterface[0],
+                    application.getRequiredInterfaces());
+            system.start();
+        } catch (SystemAssemblyException e) {
+            return;
+        }
+        fail();
+
+    }
+
+    public void testDuplicateComponent() {
+        try {
+            Component comp1 = new Application();
+            Component comp2 = new Application();
+            Container system = new Container("top");
+            system.addComponent(comp1).addComponent(comp2);
+        } catch (SystemAssemblyException e) {
+            return;
+        }
+        fail();
+    }
+
+    public void testInconsistentHierarchy() {
+        try {
+            Component comp = new Application();
+            Container system = new Container("top").addComponent(comp);
+            Container system2 = new Container("top2").addComponent(comp);
+        } catch (SystemAssemblyException e) {
+            return;
+        }
+        fail();
+    }
+
+    public void testCompositeWithExternalDependencesProvided() {
+
+        Component environment = new Environment();
+        Component application = new Application();
+        Container system = new Container("all",
+                new Component[] { application }, new ProvidedInterface[0],
+                application.getRequiredInterfaces());
+        environment.start(new DefaultScope(new ProvidedInterface[0]));
+        system.getRequiredInterfaces()[0].setProvider(environment
+                .getProvidedInterfaces()[0]);
+        system.getRequiredInterfaces()[1].setProvider(environment
+                .getProvidedInterfaces()[1]);
+
+        system.start();
+        RequiredInterface[] required = system.getRequiredInterfaces();
+        assertEquals(2, required.length);
+        ProvidedInterface[] provided = system.getProvidedInterfaces();
+        assertEquals(0, provided.length);
+
+    }
+
+    public void testAmbiguousInterfaces() {
+        try {
+            Component environment1 = new Environment();
+            Component environment2 = new Environment();
+            Component application = new Application();
+            Container container = new Container("root", new Component[] {
+                    environment1, environment2, application },
+                    new ProvidedInterface[0], new RequiredInterface[0]);
+            container.start();
+
+        } catch (SystemAssemblyException e) {
+            return;
+        }
+        fail();
+    }
+
+    public void testIncompleteRequirements() {
+        try {
+            Component application = new Application();
+            Container system = new Container("all",
+                    new Component[] { application }, new ProvidedInterface[0],
+                    new RequiredInterface[0]);
+            system.start();
+        } catch (SystemAssemblyException e) {
+            return;
+        }
+        fail();
+    }
+
+    public void testEnvironmentApplicationRollbackOnException()
+            throws Exception {
+        IMocksControl control = EasyMock.createStrictControl();
+
+        Environment environment = new Environment(_tracker);
+        Application application = control.createMock(Application.class,
+                new ConstructorArgs(Application.class.getConstructor()),
+                Application.class.getDeclaredMethod("doStart", Scope.class));
+
+        application.doStart(EasyMockMatchers.anyObject(Scope.class));
+        EasyMock.expectLastCall().andThrow(new RuntimeException());
+        control.replay();
+
+        try {
+            Container container = new Container("root", new Component[] {
+                    environment, application }, new ProvidedInterface[0],
+                    new RequiredInterface[0]);
+
+            container.start();
+        } catch (RuntimeException e) {
+            AssertionUtils.assertEquals(new String[] { "start.environment",
+                    "stop.environment" }, _tracker.getEvents(
+                    Thread.currentThread()).toArray(new String[0]));
+            return;
+        }
+        fail();
+    }
+
+    public void testEnvironmentApplicationRollbackOnExceptionWithExceptionOnStop()
+            throws Exception {
+        IMocksControl control = EasyMock.createControl();
+
+        Environment environment = new Environment(_tracker);
+        // Application 1 will throw an exception while stopping.
+        Application application1 = control.createMock(Application.class,
+                new ConstructorArgs(Application.class.getConstructor()),
+                Application.class.getDeclaredMethod("doStop", Object.class));
+
+        application1.doStop(EasyMock.anyObject());
+        EasyMock.expectLastCall().andThrow(new RuntimeException());
+
+        // application 2 will throw an exception while starting
+        Application application2 = control.createMock(Application.class,
+                new ConstructorArgs(Application.class
+                        .getConstructor(String.class), "application2"),
+                Application.class.getDeclaredMethod("doStart", Scope.class));
+
+        application2.doStart(EasyMockMatchers.anyObject(Scope.class));
+        EasyMock.expectLastCall().andThrow(new RuntimeException());
+
+        control.replay();
+
+        try {
+            Container container = new Container("root", new Component[] {
+                    environment, application1, application2 },
+                    new ProvidedInterface[0], new RequiredInterface[0]);
+
+            container.start();
+        } catch (RuntimeException e) {
+            AssertionUtils.assertEquals(new String[] { "start.environment",
+                    "stop.environment" }, _tracker.getEvents(
+                    Thread.currentThread()).toArray(new String[0]));
+            return;
+        }
+        fail();
+    }
+
+    public void testOptionalRequiredInterfaceProvidedOptionalInternal() {
+        Application application = new Application(true);
+        Container container = new Container("top",
+                new Component[] { application }, new ProvidedInterface[0],
+                Application.required(true));
+        Environment env = new Environment();
+        container.getRequiredInterfaces()[0].setProvider(env
+                .getProvidedInterfaces()[0]);
+        container.getRequiredInterfaces()[1].setProvider(env
+                .getProvidedInterfaces()[1]);
+        Scope external = new DefaultScope(env.getProvidedInterfaces());
+        env.start(external);
+
+        container.start(external);
+        assertSame(env.getProvidedInterfaces()[0], container
+                .getRequiredInterfaces()[0].getProvider());
+        assertSame(env.getProvidedInterfaces()[1], container
+                .getRequiredInterfaces()[1].getProvider());
+        assertSame(env.getProvidedInterfaces()[0], application
+                .getRequiredInterfaces()[0].getProvider());
+        assertSame(env.getProvidedInterfaces()[1], application
+                .getRequiredInterfaces()[1].getProvider());
+    }
+
+    public void testOptionalRequiredInterfaceNotProvidedOptionalInternal() {
+        Application application = new Application(true);
+        Container container = new Container("top",
+                new Component[] { application }, new ProvidedInterface[0],
+                Application.required(true));
+        Environment env = new Environment();
+        container.getRequiredInterfaces()[0].setProvider(env
+                .getProvidedInterfaces()[0]);
+        Scope external = new DefaultScope(new ProvidedInterface[0]);
+        external.publishInterface(env.getProvidedInterfaces()[0], env
+                .getString());
+        container.start(external);
+        assertSame(env.getProvidedInterfaces()[0], container
+                .getRequiredInterfaces()[0].getProvider());
+        assertNull(container.getRequiredInterfaces()[1].getProvider());
+        assertSame(env.getProvidedInterfaces()[0], application
+                .getRequiredInterfaces()[0].getProvider());
+        assertNull(application.getRequiredInterfaces()[1].getProvider());
+    }
+
+    public void testOptionalRequiredInterfaceProvidedMandatoryInternal() {
+        Application application = new Application();
+        Container container = new Container("top",
+                new Component[] { application }, new ProvidedInterface[0],
+                Application.required(true));
+        Environment env = new Environment();
+        container.getRequiredInterfaces()[0].setProvider(env
+                .getProvidedInterfaces()[0]);
+        container.getRequiredInterfaces()[1].setProvider(env
+                .getProvidedInterfaces()[1]);
+        container.start();
+        assertSame(env.getProvidedInterfaces()[0], container
+                .getRequiredInterfaces()[0].getProvider());
+        assertSame(env.getProvidedInterfaces()[1], container
+                .getRequiredInterfaces()[1].getProvider());
+        assertSame(env.getProvidedInterfaces()[0], application
+                .getRequiredInterfaces()[0].getProvider());
+        assertSame(env.getProvidedInterfaces()[1], application
+                .getRequiredInterfaces()[1].getProvider());
+    }
+
+    public void testSealed() {
+        final Container container = new Container("xx");
+        assertFalse(container.isSealed());
+        container.start();
+        assertTrue(container.isSealed());
+
+        AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+            @Override
+            public void run() throws Exception {
+                container.addComponent(new Application());
+            }
+        }, SystemAssemblyException.class);
+
+        AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+            @Override
+            public void run() throws Exception {
+                container.addRestriction(new InterfaceRestriction() {
+                    @Override
+                    public boolean isViolated(Component aClient,
+                            RequiredInterface aRequired, Component aServer,
+                            ProvidedInterface aProvided) {
+                        return false;
+                    }
+                });
+            }
+        }, SystemAssemblyException.class);
+        AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+            @Override
+            public void run() throws Exception {
+                container.addProvidedInterface(new DefaultProvidedInterface(
+                        "xx", String.class));
+            }
+        }, SystemAssemblyException.class);
+
+        AssertionUtils.assertException(new AssertionUtils.ErroneousCode() {
+            @Override
+            public void run() throws Exception {
+                container.addRequiredInterface(new DefaultRequiredInterface(
+                        "xx", String.class));
+            }
+        }, SystemAssemblyException.class);
+    }
+
+    public void testRestriction() {
+        Environment env1 = new Environment("env1");
+        Environment env2 = new Environment("env2");
+        Application app = new Application("app");
+        Container container = new Container("top").addComponent(env1)
+                .addComponent(env2).addComponent(app);
+        container.addRestriction(new DefaultInterfaceRestriction("app", null,
+                "env1", null));
+        container.start();
+        assertEquals(env1.getString(), app.getString());
+        assertFalse(env2.getString().equals(app.getString()));
+    }
+    
+    public void testProvidedInDifferentScopes() { 
+        // Scoping problem occurred. Externally and internally provided components clashed
+        // because unique id generation in the scope was wrong. 
+        
+        StringComponent str = new StringComponent("string");
+        Application app = new Application("app");
+        Container container = new Container("top").addComponent(str).addComponent(app);
+        container.addRequiredInterface(new DefaultRequiredInterface("integer", Integer.class));
+        
+        ProvidedInterface provided = new DefaultProvidedInterface("hallo", Integer.class);
+        container.getRequiredInterfaces()[0]
+                                       .setProvider(provided);
+        
+        Scope external = new DefaultScope(new ProvidedInterface[0]);
+        external.publishInterface(provided, 100);
+        Scope scope = container.start(external);
+    }
 }