public void UndoRunInReverseOrder()
        {
            List<string> undosRun = new List<string>();

            UndoStack undo = new UndoStack();
            undo.Push(() => undosRun.Add("first"));
            undo.Push(() => undosRun.Add("second"));
            undo.Push(() => undosRun.Add("third"));

            undo.UndoAll();

            Assert.Equal(3, undosRun.Count);
            Assert.Equal("third", undosRun[0]);
            Assert.Equal("second", undosRun[1]);
            Assert.Equal("first", undosRun[2]);
        }
        public void WhenUndoThrows_ItThrowsAggregate()
        {
            UndoStack undo = new UndoStack();

            undo.Push(() => { throw new ArgumentException(); });
            undo.Push(() => { throw new InvalidOperationException(); });
            undo.Push(() => { });

            Action undoAction = () => undo.UndoAll();
            Assert.Throws<AggregateException>(undoAction);

            try
            {
                undoAction();
            }
            catch (AggregateException ex)
            {
                Assert.Equal(2, ex.InnerExceptions.Count);
                Assert.Equal(typeof(InvalidOperationException), ex.InnerExceptions[0].GetType());
                Assert.Equal(typeof(ArgumentException), ex.InnerExceptions[1].GetType());
            }
        }
        public void EveryUndoIsRun()
        {
            UndoStack undo = new UndoStack();

            bool firstUndo = false;
            bool thirdUndo = false;

            undo.Push(() => { firstUndo = true; });
            undo.Push(() => { throw new InvalidOperationException(); });
            undo.Push(() => { thirdUndo = true;  });

            try
            {
                undo.UndoAll();
                Assert.True(false, "Expected an Aggregate exception to be thrown.");
            }
            catch (AggregateException)
            {
            }

            Assert.Equal(true, firstUndo);
            Assert.Equal(true, thirdUndo);
        }
        public IContainer CreateContainer(ContainerSpec containerSpec)
        {
            Guard.NotNull(containerSpec, "containerSpec");

            UndoStack undoStack = new UndoStack();
            IContainer container;

            try
            {
                var handle = containerSpec.Handle;
                if (String.IsNullOrEmpty(handle))
                    handle = handleHelper.GenerateHandle();

                var id = handleHelper.GenerateId(handle);

                var user = ContainerUser.Create(userManager, id);
                undoStack.Push(() => user.Delete());

                var directory = directoryFactory.Create(fileSystem, containerBasePath, id);
                directory.CreateSubdirectories(user);
                undoStack.Push(directory.Destroy);

                directory.CreateBindMounts(containerSpec.BindMounts, user);

                var jobObject = new JobObject(id);
                undoStack.Push(() => jobObject.Dispose());

                var containerHostClient = containerHostService.StartContainerHost(id, directory, jobObject, user.GetCredential());
                undoStack.Push(() => containerHostClient.Shutdown());

                var constrainedProcessRunner = new ConstrainedProcessRunner(containerHostClient);
                undoStack.Push(() => constrainedProcessRunner.Dispose());

                var processHelper = new ProcessHelper();
                var dependencyHelper = new ContainerHostDependencyHelper();

                var diskQuotaControl = diskQuotaManager.CreateDiskQuotaControl(directory);

                container = new Container(
                    id,
                    handle,
                    user,
                    directory,
                    containerPropertiesService,
                    tcpPortManager,
                    jobObject,
                    diskQuotaControl,
                    processRunner,
                    constrainedProcessRunner,
                    processHelper,
                    containerSpec.Environment,
                    dependencyHelper);

                containerPropertiesService.SetProperties(container, containerSpec.Properties);
                lock (containers)
                {
                    containers.Add(container);
                }
            }
            catch (Exception e)
            {
                try
                {
                    undoStack.UndoAll();
                    throw;
                }
                catch (AggregateException undoException)
                {
                    throw new AggregateException(new[] { e, undoException });
                }
            }

            return container;
        }