/// <summary>
        /// Adds a new physical machine.
        /// </summary>
        /// <param name="machine">The new machine.</param>
        public void Add(PhysicalMachineDescription machine)
        {
            VerifySchemaVersion();

            var result = StoredMachineDescriptions.Add(machine) as PhysicalMachineDescription;
            Debug.Assert(result != null, "The machine should be a physical machine.");

            Patch(result);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="PhysicalMachineModel"/> class.
        /// </summary>
        /// <param name="model">The object that handles the data storage.</param>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if <paramref name="model"/> is <see langword="null" />.
        /// </exception>
        public PhysicalMachineModel(PhysicalMachineDescription model)
            : base(model)
        {
            {
                Lokad.Enforce.Argument(() => model);
            }

            m_Model = model;
        }
        private void Update(PhysicalMachineDescription stored, PhysicalMachineDescription changed)
        {
            var shouldPatch = Update(stored as MachineDescription, changed as MachineDescription);
            stored.CanStartRemotely = changed.CanStartRemotely;

            if (shouldPatch)
            {
                stored.IsPatched = false;
                Patch(stored);
            }
        }
        private PhysicalMachineDescription Patch(PhysicalMachineDescription description)
        {
            var result = (StoredMachineDescriptions.Find(description.Id) ?? StoredMachineDescriptions.Add(description)) as PhysicalMachineDescription;
            Debug.Assert(result != null, "The machine should be a physical machine.");

            if (!result.IsPatched && !result.IsPatching)
            {
                result.IsPatching = true;
                try
                {
                    var selectedHypervMachines = GetHypervMachinesByHostId(result.Id)
                        .Select(Patch)
                        .ToList();
                    result.HypervMachines = selectedHypervMachines;

                    var selectedMachineApplications = GetMachineApplicationByMachineId(result.Id)
                        .Select(Patch)
                        .ToList();
                    result.MachineApplications = selectedMachineApplications;

                    var selectedOperatingSystem = GetOperatingSystemsById(result.OperatingSystemId)
                        .Select(Patch)
                        .FirstOrDefault();
                    result.OperatingSystem = selectedOperatingSystem;

                    var selectedTestEnvironments = GetTestEnvironmentByMachineId(result.Id)
                        .Select(Patch)
                        .ToList();
                    result.TestEnvironments = selectedTestEnvironments;

                    result.IsPatched = true;
                }
                finally
                {
                    result.IsPatching = false;
                }
            }

            return result;
        }
        private static Mock<IProvideTestingContext> CreateEnvironmentContext(
            PhysicalMachineDescription machineDescription,
            Shared.DataAccess.Test test,
            List<TestStep> steps)
        {
            var environmentContext = new Mock<IProvideTestingContext>();
            {
                environmentContext.Setup(
                    e => e.InactiveMachinesWith(It.IsAny<OperatingSystemDescription>(), It.IsAny<IEnumerable<ApplicationDescription>>()))
                    .Returns(
                        new List<MachineDescription>
                            {
                                machineDescription,
                            });
                environmentContext.Setup(e => e.InactiveTests())
                    .Returns(
                        new List<Shared.DataAccess.Test>
                            {
                                test
                            });
                environmentContext.Setup(e => e.TestStepsForEnvironment(It.IsAny<int>()))
                    .Returns(steps);
                environmentContext.Setup(e => e.StartTest(It.IsAny<int>()))
                    .Verifiable();
                environmentContext.Setup(e => e.MarkMachineAsActive(It.IsAny<string>()))
                    .Verifiable();
                environmentContext.Setup(e => e.TestEnvironmentSupportedByMachine(It.IsAny<int>(), It.IsAny<string>()))
                    .Verifiable();
            }

            return environmentContext;
        }
        public void ActivateTestsWithSingleEnvironment()
        {
            var configuration = CreateConfiguration();
            var environmentName = "td";
            var testEnvironment = CreateFakeTestEnvironment(environmentName);
            var test = CreateFakeTestSpecification(testEnvironment);
            var steps = new List<TestStep>
            {
                new MsiInstallTestStep
                    {
                        Order = 0,
                        FailureMode = TestStepFailureMode.Continue,
                    }
            };

            var diagnostics = new SystemDiagnostics((l, s) => { }, null);
            var activeTests = new ActiveTestStorage(diagnostics);
            var machineDescription = new PhysicalMachineDescription
                {
                    Id = "a-b",
                    Name = "ma",
                    Description = "mb",
                    MacAddress = "mc",
                    NetworkName = "md",
                    OperatingSystemId = 0,
                    IsAvailableForTesting = true,
                    CanStartRemotely = false,
                };
            var environmentContext = CreateEnvironmentContext(machineDescription, test, steps);

            var activeEnvironment = new Mock<IActiveEnvironment>();
            {
                activeEnvironment.Setup(
                        a => a.Execute(
                            It.IsAny<int>(),
                            It.IsAny<IEnumerable<TestStep>>(),
                            It.IsAny<IEnumerable<InputParameter>>(),
                            It.IsAny<string>()))
                    .Callback<int, IEnumerable<TestStep>, IEnumerable<InputParameter>, string>(
                        (id, s, parameters, file) =>
                        {
                            Assert.AreEqual(test.Id, id);
                            Assert.AreEqual(1, s.Count());
                            Assert.IsInstanceOf(typeof(MsiInstallTestStep), s.First());
                            Assert.AreEqual(1, parameters.Count());

                            var parameter = parameters.First();
                            Assert.AreEqual(environmentName, parameter.Key);
                            Assert.AreEqual(machineDescription.NetworkName, parameter.Value);
                            Assert.False(string.IsNullOrWhiteSpace(file));
                        })
                    .Verifiable();
                activeEnvironment.Setup(a => a.Environment)
                    .Returns("ea");
            }

            var activator = new Mock<IEnvironmentActivator>();
            {
                activator.Setup(a => a.EnvironmentTypeToLoad)
                    .Returns(typeof(PhysicalMachineDescription));
                activator.Setup(a => a.Load(It.IsAny<MachineDescription>(), It.IsAny<ITestSectionBuilder>(), It.IsAny<Action<string>>()))
                    .Returns(activeEnvironment.Object);
            }

            var activators = new List<IEnvironmentActivator>
                {
                    activator.Object,
                };

            var environmentPackage = new Mock<ITestEnvironmentPackage>();
            {
                environmentPackage.Setup(e => e.PackagePath)
                    .Returns("a");
            }

            var suitePackage = new Mock<ITestSuitePackage>();
            {
                suitePackage.Setup(s => s.Environment(It.IsAny<string>()))
                    .Returns(environmentPackage.Object);
            }

            Func<ITestSuitePackage> packageFunc = () => suitePackage.Object;
            var fileSystem = new Mock<IFileSystem>();
            {
                fileSystem.Setup(f => f.Path)
                    .Returns(new MockPath());
            }

            Func<IReportBuilder> reportBuilders = () => new Mock<IReportBuilder>().Object;
            Func<string, IReportBuilder, ITestSectionBuilder> sectionBuilders = (s, b) => new Mock<ITestSectionBuilder>().Object;
            var controller = new TestController(
                configuration.Object,
                activeTests,
                () => new Owned<IProvideTestingContext>(environmentContext.Object, new MockDisposable()),
                activators,
                packageFunc,
                fileSystem.Object,
                reportBuilders,
                sectionBuilders,
                diagnostics);
            controller.ActivateTests();
            Assert.AreEqual(1, activeTests.Count());
            activeEnvironment.Verify(
                a => a.Execute(
                    It.IsAny<int>(),
                    It.IsAny<IEnumerable<TestStep>>(),
                    It.IsAny<IEnumerable<InputParameter>>(),
                    It.IsAny<string>()),
                Times.Once());
        }