Пример #1
0
        protected override Task <ResultStatus> DoCommandOverride(ICommandContext commandContext)
        {
            // This path for effects xml is now part of this tool, but it should be done in a separate exporter?
            using (var inputStream = File.OpenRead(SourcePath))
                using (var outputStream = ContentManager.FileProvider.OpenStream(Location, VirtualFileMode.Create, VirtualFileAccess.Write))
                {
                    inputStream.CopyTo(outputStream);

                    var objectURL = new ObjectUrl(UrlType.ContentLink, Location);

                    if (DisableCompression)
                    {
                        commandContext.AddTag(objectURL, disableCompressionSymbol);
                    }
                }

            if (SaveSourcePath)
            {
                // store absolute path to source
                // TODO: the "/path" is hardcoded, used in EffectSystem and ShaderSourceManager. Find a place to share this correctly.
                var pathLocation = new UFile(Location.FullPath + "/path");
                using (var outputStreamPath = ContentManager.FileProvider.OpenStream(pathLocation, VirtualFileMode.Create, VirtualFileAccess.Write))
                {
                    using (var sw = new StreamWriter(outputStreamPath))
                    {
                        sw.Write(SourcePath.FullPath);
                    }
                }
            }

            return(Task.FromResult(ResultStatus.Successful));
        }
Пример #2
0
        public async Task GetWritableAccessorAsync_GivenValidAccessorRequest_ShouldReturnAccessor()
        {
            var mockUrlProvider = new Mock <IInputObjectUrlProvider>();
            var mockSigner      = new Mock <ISigner <ObjectUrl> >();

            var objectUrlAccessorProvider = new InputObjectUrlAccessorProvider(mockUrlProvider.Object, mockSigner.Object);

            var accessorRequest = new InputObjectAccessorRequest
            {
                ExecutionMetadata = new ExecutionRequest {
                    ExecutionId = Guid.NewGuid().ToString()
                },
                ObjectMetadata = new ExtensionInputObject {
                    Name = "InputObjectA"
                }
            };

            var objectUrl = new ObjectUrl
            {
                Url        = "http://test.com/some-object",
                HttpMethod = HttpMethod.Put.Method
            };

            var objectUrlJson = JObject.FromObject(objectUrl);

            mockUrlProvider.Setup(up => up.GetWritableUrlAsync(It.Is <ObjectUrlRequest>(
                                                                   ur => ur.ExecutionMetadata.ExecutionId == accessorRequest.ExecutionMetadata.ExecutionId &&
                                                                   ur.ObjectName == accessorRequest.ObjectMetadata.Name)))
            .Returns(Task.FromResult(objectUrl));

            var accessor = await objectUrlAccessorProvider.GetWritableAccessorAsync(accessorRequest);

            accessor.Should().NotBeNull();
            accessor.Should().BeEquivalentTo(objectUrlJson);
        }
Пример #3
0
        protected override Task<ResultStatus> DoCommandOverride(ICommandContext commandContext)
        {
            // This path for effects xml is now part of this tool, but it should be done in a separate exporter?
            using (var inputStream = File.OpenRead(SourcePath))
            using (var outputStream = AssetManager.FileProvider.OpenStream(Location, VirtualFileMode.Create, VirtualFileAccess.Write))
            {
                inputStream.CopyTo(outputStream);

                var objectURL = new ObjectUrl(UrlType.ContentLink, Location);

                if (DisableCompression)
                    commandContext.AddTag(objectURL, DisableCompressionSymbol);
            }

            if (SaveSourcePath)
            {
                // store absolute path to source
                // TODO: the "/path" is hardcoded, used in EffectSystem and ShaderSourceManager. Find a place to share this correctly.
                var pathLocation = new UFile(Location.FullPath + "/path");
                using (var outputStreamPath = AssetManager.FileProvider.OpenStream(pathLocation, VirtualFileMode.Create, VirtualFileAccess.Write))
                {
                    using (var sw = new StreamWriter(outputStreamPath))
                    {
                        sw.Write(SourcePath.FullPath);
                    }
                }
            }

            return Task.FromResult(ResultStatus.Successful);
        }
Пример #4
0
        public bool TryGetValue(string url, out ObjectId objectId)
        {
            var objUrl = new ObjectUrl(UrlType.Internal, url);

            // Lock TransactionAssetIndexMap
            lock (transactionOutputObjects)
            {
                if (transactionOutputObjects.TryGetValue(objUrl, out objectId))
                {
                    return(true);
                }

                foreach (var outputObjects in outputObjectsGroups)
                {
                    // Lock underlying EnumerableBuildStep.OutputObjects
                    lock (outputObjects)
                    {
                        OutputObject outputObject;
                        if (outputObjects.TryGetValue(objUrl, out outputObject))
                        {
                            objectId = outputObject.ObjectId;
                            return(true);
                        }
                    }
                }
            }

            objectId = ObjectId.Empty;
            return(false);
        }
Пример #5
0
        public void TestConcurrencyReadWriteAccess()
        {
            Utils.CleanContext();
            Utils.GenerateSourceFile("input1", "{99D73F8B-587A-4869-97AE-4A7185D88AC9}");
            var inputDep = new ObjectUrl(UrlType.File, Utils.GetSourcePath("input1"));

            var builder           = Utils.CreateBuilder(false);
            CommandBuildStep step = builder.Root.Add(new InputOutputTestCommand {
                Delay = 100, Source = new ObjectUrl(UrlType.File, Utils.GetSourcePath("input1")), OutputUrl = "/db/url1", InputDependencies = { inputDep }
            });
            CommandBuildStep concurrencyStep1 = builder.Root.Add(new InputOutputTestCommand {
                Delay = 100, Source = new ObjectUrl(UrlType.Content, "/db/url1"), OutputUrl = "/db/url1", InputDependencies = { inputDep }
            });
            CommandBuildStep concurrencyStep2 = builder.Root.Add(new InputOutputTestCommand {
                Delay = 150, Source = new ObjectUrl(UrlType.Content, "/db/url1"), OutputUrl = "/db/url2", InputDependencies = { inputDep }
            });

            BuildStep.LinkBuildSteps(step, concurrencyStep1);
            BuildStep.LinkBuildSteps(step, concurrencyStep2);

            builder.Run(Builder.Mode.Build);
            var logger = (LoggerResult)builder.Logger;

            Assert.Contains("Command InputOutputTestCommand /db/url1 > /db/url1 is writing /db/url1 while command InputOutputTestCommand /db/url1 > /db/url2 is reading it", logger.Messages.Select(x => x.Text));
        }
Пример #6
0
        public void TestInputDependencies()
        {
            Utils.CleanContext();
            Utils.GenerateSourceFile("input1", "{A7246DF6-3A68-40E2-BA58-6C9A0EFF552B}");
            Utils.GenerateSourceFile("inputDeps", "{8EE7A4BC-88E1-4CC8-B03F-1E6EA8B23955}");

            var builder  = Utils.CreateBuilder(false);
            var inputDep = new ObjectUrl(UrlType.File, Utils.GetSourcePath("inputDeps"));
            var command  = new InputOutputTestCommand {
                Delay = 100, Source = new ObjectUrl(UrlType.File, Utils.GetSourcePath("input1")), OutputUrl = "/db/url1"
            };

            command.InputDependencies.Add(inputDep);
            CommandBuildStep step = builder.Root.Add(command);

            builder.Run(Builder.Mode.Build);

            var indexMap = ContentIndexMap.Load(VirtualFileSystem.ApplicationDatabaseIndexPath);

            indexMap.UseTransaction = true;
            indexMap.LoadNewValues();

            ObjectId inputDepId;
            bool     inputDepFound = step.Result.InputDependencyVersions.TryGetValue(inputDep, out inputDepId);

            Assert.True(inputDepFound);
        }
Пример #7
0
        public void TestConcurrencyReadWriteAccess()
        {
            Utils.CleanContext();
            Utils.GenerateSourceFile("input1", "{99D73F8B-587A-4869-97AE-4A7185D88AC9}");
            var inputDep = new ObjectUrl(UrlType.File, Utils.GetSourcePath("input1"));

            var builder           = Utils.CreateBuilder();
            CommandBuildStep step = builder.Root.Add(new InputOutputCommand {
                Delay = 100, Source = new ObjectUrl(UrlType.File, Utils.GetSourcePath("input1")), OutputUrl = "/db/url1", InputDependencies = { inputDep }
            });

            builder.Root.Add(new WaitBuildStep());
            CommandBuildStep concurrencyStep1 = builder.Root.Add(new InputOutputCommand {
                Delay = 100, Source = new ObjectUrl(UrlType.Internal, "/db/url1"), OutputUrl = "/db/url1", InputDependencies = { inputDep }
            });
            CommandBuildStep concurrencyStep2 = builder.Root.Add(new InputOutputCommand {
                Delay = 150, Source = new ObjectUrl(UrlType.Internal, "/db/url1"), OutputUrl = "/db/url2", InputDependencies = { inputDep }
            });

            BuildStep.LinkBuildSteps(step, concurrencyStep1);
            BuildStep.LinkBuildSteps(step, concurrencyStep2);

            Utils.StartCapturingLog();
            builder.Run(Builder.Mode.Build);
            string log = Utils.StopCapturingLog();

            Assert.That(log.Contains("Command InputOutputCommand /db/url1 > /db/url1 is writing /db/url1 while command InputOutputCommand /db/url1 > /db/url2 is reading it"));
        }
Пример #8
0
        public void TestConcurrencyWriteAccess()
        {
            Utils.CleanContext();
            Utils.GenerateSourceFile("input1", "{99D73F8B-587A-4869-97AE-4A7185D88AC9}");
            Utils.GenerateSourceFile("input2", "{9FEABA51-4CE6-4DB0-9866-45A7492FD1B7}");
            var inputDep = new ObjectUrl(UrlType.File, Utils.GetSourcePath("input1"));

            var builder            = Utils.CreateBuilder(false);
            CommandBuildStep step1 = builder.Root.Add(new InputOutputTestCommand {
                Delay = 100, Source = new ObjectUrl(UrlType.File, Utils.GetSourcePath("input1")), OutputUrl = "/db/url1", InputDependencies = { inputDep }
            });
            CommandBuildStep step2 = builder.Root.Add(new InputOutputTestCommand {
                Delay = 100, Source = new ObjectUrl(UrlType.File, Utils.GetSourcePath("input2")), OutputUrl = "/db/url2", InputDependencies = { inputDep }
            });
            CommandBuildStep concurrencyStep1 = builder.Root.Add(new InputOutputTestCommand {
                Delay = 100, Source = new ObjectUrl(UrlType.Content, "/db/url1"), OutputUrl = "/db/url", InputDependencies = { inputDep }
            });
            CommandBuildStep concurrencyStep2 = builder.Root.Add(new InputOutputTestCommand {
                Delay = 150, Source = new ObjectUrl(UrlType.Content, "/db/url2"), OutputUrl = "/db/url", InputDependencies = { inputDep }
            });

            BuildStep.LinkBuildSteps(step1, concurrencyStep1);
            BuildStep.LinkBuildSteps(step2, concurrencyStep2);

            builder.Run(Builder.Mode.Build);
            var logger = (LoggerResult)builder.Logger;

            Assert.Contains(logger.Messages, x => x.Text.Contains("Commands InputOutputTestCommand /db/url2 > /db/url and InputOutputTestCommand /db/url1 > /db/url are both writing /db/url at the same time"));
        }
Пример #9
0
        public void TestConcurrencyWriteAccess()
        {
            Utils.CleanContext();
            Utils.GenerateSourceFile("input1", "{99D73F8B-587A-4869-97AE-4A7185D88AC9}");
            Utils.GenerateSourceFile("input2", "{9FEABA51-4CE6-4DB0-9866-45A7492FD1B7}");
            var inputDep = new ObjectUrl(UrlType.File, Utils.GetSourcePath("input1"));

            var builder            = Utils.CreateBuilder();
            CommandBuildStep step1 = builder.Root.Add(new InputOutputCommand {
                Delay = 100, Source = new ObjectUrl(UrlType.File, Utils.GetSourcePath("input1")), OutputUrl = "/db/url1", InputDependencies = { inputDep }
            });
            CommandBuildStep step2 = builder.Root.Add(new InputOutputCommand {
                Delay = 100, Source = new ObjectUrl(UrlType.File, Utils.GetSourcePath("input2")), OutputUrl = "/db/url2", InputDependencies = { inputDep }
            });

            builder.Root.Add(new WaitBuildStep());
            CommandBuildStep concurrencyStep1 = builder.Root.Add(new InputOutputCommand {
                Delay = 100, Source = new ObjectUrl(UrlType.Internal, "/db/url1"), OutputUrl = "/db/url", InputDependencies = { inputDep }
            });
            CommandBuildStep concurrencyStep2 = builder.Root.Add(new InputOutputCommand {
                Delay = 150, Source = new ObjectUrl(UrlType.Internal, "/db/url2"), OutputUrl = "/db/url", InputDependencies = { inputDep }
            });

            BuildStep.LinkBuildSteps(step1, concurrencyStep1);
            BuildStep.LinkBuildSteps(step2, concurrencyStep2);

            Utils.StartCapturingLog();
            builder.Run(Builder.Mode.Build);
            string log = Utils.StopCapturingLog();

            Assert.That(log.Contains("Commands InputOutputCommand /db/url2 > /db/url and InputOutputCommand /db/url1 > /db/url are both writing /db/url at the same time"));
        }
Пример #10
0
        public bool TryGetValue(string url, out ObjectId objectId)
        {
            var objUrl = new ObjectUrl(UrlType.ContentLink, url);

            // Lock TransactionAssetIndexMap
            lock (transactionOutputObjects)
            {
                if (transactionOutputObjects.TryGetValue(objUrl, out objectId))
                    return true;

                foreach (var outputObjects in outputObjectsGroups)
                {
                    // Lock underlying EnumerableBuildStep.OutputObjects
                    lock (outputObjects)
                    {
                        OutputObject outputObject;
                        if (outputObjects.TryGetValue(objUrl, out outputObject))
                        {
                            objectId = outputObject.ObjectId;
                            return true;
                        }
                    }
                }

                // Check asset index map (if set)
                if (assetIndexMap != null)
                {
                    if (assetIndexMap.TryGetValue(url, out objectId))
                        return true;
                }
            }

            objectId = ObjectId.Empty;
            return false;
        }
Пример #11
0
        private OutputObject AddOutputObject(IExecuteContext executeContext, ObjectUrl outputObjectUrl, ObjectId outputObjectId, Command command)
        {
            OutputObject outputObject;

            if (!outputObjects.TryGetValue(outputObjectUrl, out outputObject))
            {
                // New item?
                outputObject = new OutputObject(outputObjectUrl, outputObjectId);
                outputObjects.Add(outputObjectUrl, outputObject);
            }
            else
            {
                // ObjectId should be similar (if no Wait happened), otherwise two tasks spawned with same parameters did output different results
                if (outputObject.ObjectId != outputObjectId && outputObject.Counter == mergeCounter)
                {
                    var error = $"Commands {command} and {outputObject.Command} are both writing {outputObjectUrl} at the same time";
                    executeContext.Logger.Error(error);
                    throw new InvalidOperationException(error);
                }

                // Update new ObjectId
                outputObject.ObjectId = outputObjectId;
            }

            // Update Counter so that we know if a wait happened since this output object has been merged.
            outputObject.Counter = mergeCounter;
            outputObject.Command = command;

            return(outputObject);
        }
Пример #12
0
        /// <summary></summary>
        public override int GetHashCode()
        {
            var code = 13;

            // Calculate hash on each properties one by one
            code = (code * 7) + Id.GetHashCode();
            if (ItemReference != null)
            {
                code = (code * 7) + ItemReference.GetHashCode();
            }
            if (this.AnnotationsUrl != null)
            {
                code = (code * 7) + AnnotationsUrl.GetHashCode();
            }
            if (this.CategoryUrl != null)
            {
                code = (code * 7) + CategoryUrl.GetHashCode();
            }
            if (this.CreationTime != null)
            {
                code = (code * 7) + CreationTime.GetHashCode();
            }
            code = (code * 7) + IsAckRequired.GetHashCode();
            code = (code * 7) + IsAcknowledged.GetHashCode();
            code = (code * 7) + IsDiscarded.GetHashCode();
            if (this.Message != null)
            {
                code = (code * 7) + Message.GetHashCode();
            }
            if (this.Name != null)
            {
                code = (code * 7) + Name.GetHashCode();
            }
            if (this.ObjectUrl != null)
            {
                code = (code * 7) + ObjectUrl.GetHashCode();
            }
            code = (code * 7) + Priority.GetHashCode();
            if (this.Self != null)
            {
                code = (code * 7) + Self.GetHashCode();
            }
            if (this.TypeUrl != null)
            {
                code = (code * 7) + TypeUrl.GetHashCode();
            }
            if (this.Type != null)
            {
                code = (code * 7) + Type.GetHashCode();
            }
            if (this.Category != null)
            {
                code = (code * 7) + Category.GetHashCode();
            }
            return(code);
        }
Пример #13
0
 /// <summary>
 ///   Adds the output object. Will try to detect input/output conflicts, and output with different <see cref="ObjectId" /> conflicts.
 /// </summary>
 /// <param name="executeContext">The execute context.</param>
 /// <param name="outputObjectUrl">The output object URL.</param>
 /// <param name="command">The command that produced the output object.</param>
 /// <exception cref="InvalidOperationException">Two <see cref="CommandBuildStep"/> with the same inputs did output different results.</exception>
 private void CheckOutputObject(IExecuteContext executeContext, ObjectUrl outputObjectUrl, Command command)
 {
     if (inputObjects.TryGetValue(outputObjectUrl, out InputObject inputObject) &&
         inputObject.Command != command &&
         inputObject.Counter == mergeCounter)
     {
         var error = $"Command {command} is writing {outputObjectUrl} while command {inputObject.Command} is reading it.";
         executeContext.Logger.Error(error);
         throw new InvalidOperationException(error);
     }
 }
Пример #14
0
        /// <summary>
        /// Adds the output object. Will try to detect input/output conflicts, and output with different <see cref="ObjectId" /> conflicts.
        /// </summary>
        /// <param name="executeContext">The execute context.</param>
        /// <param name="outputObjectUrl">The output object URL.</param>
        /// <param name="outputObjectId">The output object id.</param>
        /// <param name="command">The command that produced the output object.</param>
        /// <exception cref="System.InvalidOperationException">Two CommandBuildStep with same inputs did output different results.</exception>
        private void CheckOutputObject(IExecuteContext executeContext, ObjectUrl outputObjectUrl, ObjectId outputObjectId, Command command)
        {
            InputObject inputObject;

            if (inputObjects.TryGetValue(outputObjectUrl, out inputObject) &&
                inputObject.Command != command &&
                inputObject.Counter == mergeCounter)
            {
                var error = string.Format("Command {0} is writing {1} while command {2} is reading it", command, outputObjectUrl, inputObject.Command);
                executeContext.Logger.Error(error);
                throw new InvalidOperationException(error);
            }
        }
Пример #15
0
        private void AddInputObject(ObjectUrl inputObjectUrl, Command command)
        {
            if (outputObjects.TryGetValue(inputObjectUrl, out OutputObject outputObject) &&
                mergeCounter > outputObject.Counter)
            {
                // Object was output by ourselves, so reading it as input should be ignored
                return;
            }

            inputObjects[inputObjectUrl] = new InputObject {
                Command = command, Counter = mergeCounter
            };
        }
Пример #16
0
        /// <summary></summary>
        public override int GetHashCode()
        {
            var code = 13;

            // Calculate hash on each properties one by one
            code = (code * 7) + Id.GetHashCode();
            if (CreationTime != null)
            {
                code = (code * 7) + CreationTime.GetHashCode();
            }
            if (this.ActionTypeUrl != null)
            {
                code = (code * 7) + ActionTypeUrl.GetHashCode();
            }
            if (this.ActionType != null)
            {
                code = (code * 7) + ActionType.GetHashCode();
            }
            code = (code * 7) + Discarded.GetHashCode();
            if (this.StatusUrl != null)
            {
                code = (code * 7) + StatusUrl.GetHashCode();
            }
            if (this.Status != null)
            {
                code = (code * 7) + Status.GetHashCode();
            }
            if (this.ErrorString != null)
            {
                code = (code * 7) + ErrorString.GetHashCode();
            }
            if (this.User != null)
            {
                code = (code * 7) + User.GetHashCode();
            }
            if (this.ObjectUrl != null)
            {
                code = (code * 7) + ObjectUrl.GetHashCode();
            }
            if (this.AnnotationsUrl != null)
            {
                code = (code * 7) + AnnotationsUrl.GetHashCode();
            }
            if (this.Self != null)
            {
                code = (code * 7) + Self.GetHashCode();
            }
            return(code);
        }
Пример #17
0
        private void AddInputObject(IExecuteContext executeContext, ObjectUrl inputObjectUrl, Command command)
        {
            OutputObject outputObject;

            if (outputObjects.TryGetValue(inputObjectUrl, out outputObject) &&
                mergeCounter > outputObject.Counter)
            {
                // Object was outputed by ourself, so reading it as input should be ignored.
                return;
            }

            inputObjects[inputObjectUrl] = new InputObject {
                Command = command, Counter = mergeCounter
            };
        }
Пример #18
0
        public void TestConcurrencyReadWriteAccess2()
        {
            Utils.CleanContext();
            Utils.GenerateSourceFile("input1", "{99D73F8B-587A-4869-97AE-4A7185D88AC9}");
            var inputDep = new ObjectUrl(UrlType.File, Utils.GetSourcePath("input1"));

            var buildStepList1 = new ListBuildStep
            {
                new ListBuildStep {
                    new InputOutputCommand {
                        Delay = 100, Source = inputDep, OutputUrl = "/db/url1", InputDependencies = { inputDep }
                    }
                },
                new WaitBuildStep(),
                new InputOutputCommand {
                    Delay = 1500, Source = new ObjectUrl(UrlType.Internal, "/db/url1"), OutputUrl = "/db/dump1", InputDependencies = { inputDep }
                },
            };
            var buildStepList2 = new ListBuildStep
            {
                new ListBuildStep {
                    new InputOutputCommand {
                        Delay = 100, Source = inputDep, OutputUrl = "/db/url1", InputDependencies = { inputDep }
                    }
                },
                new WaitBuildStep(),
                new InputOutputCommand {
                    Delay = 1500, Source = new ObjectUrl(UrlType.Internal, "/db/url1"), OutputUrl = "/db/dump2", InputDependencies = { inputDep }
                },
            };

            var builder = Utils.CreateBuilder();

            builder.ThreadCount = 1;
            builder.Root.Add(buildStepList1);
            builder.Root.Add(buildStepList2);

            Utils.StartCapturingLog();
            var buildResult = builder.Run(Builder.Mode.Build);

            Assert.That(buildResult, Is.EqualTo(BuildResultCode.Successful));
        }
Пример #19
0
        public void TestConcurrencyReadWriteAccess2()
        {
            Utils.CleanContext();
            Utils.GenerateSourceFile("input1", "{99D73F8B-587A-4869-97AE-4A7185D88AC9}");
            var inputDep = new ObjectUrl(UrlType.File, Utils.GetSourcePath("input1"));

            var buildStepList1 = new ListBuildStep();
            var step           = new ListBuildStep();

            step.Add(new InputOutputTestCommand {
                Delay = 100, Source = inputDep, OutputUrl = "/db/url1", InputDependencies = { inputDep }
            });
            buildStepList1.Add(step);
            buildStepList1.Add(new InputOutputTestCommand {
                Delay = 1500, Source = new ObjectUrl(UrlType.Content, "/db/url1"), OutputUrl = "/db/dump1", InputDependencies = { inputDep }
            });
            var buildStepList2 = new ListBuildStep();

            step = new ListBuildStep();
            step.Add(new InputOutputTestCommand {
                Delay = 100, Source = inputDep, OutputUrl = "/db/url1", InputDependencies = { inputDep }
            });
            buildStepList2.Add(step);
            buildStepList2.Add(new InputOutputTestCommand {
                Delay = 1500, Source = new ObjectUrl(UrlType.Content, "/db/url1"), OutputUrl = "/db/dump2", InputDependencies = { inputDep }
            });

            var builder = Utils.CreateBuilder(false);

            builder.ThreadCount = 1;
            builder.Root.Add(buildStepList1);
            builder.Root.Add(buildStepList2);

            var buildResult = builder.Run(Builder.Mode.Build);

            Assert.Equal(BuildResultCode.Successful, buildResult);
        }
Пример #20
0
        public void TestInputDependenciesChange()
        {
            Utils.CleanContext();
            Utils.GenerateSourceFile("input1", "{A7246DF6-3A68-40E2-BA58-6C9A0EFF552B}");
            Utils.GenerateSourceFile("inputDeps", "{8EE7A4BC-88E1-4CC8-B03F-1E6EA8B23955}");
            var inputDep = new ObjectUrl(UrlType.File, Utils.GetSourcePath("inputDeps"));

            var builder1           = Utils.CreateBuilder(false);
            CommandBuildStep step1 = builder1.Root.Add(new InputOutputTestCommand {
                Delay = 100, Source = new ObjectUrl(UrlType.File, Utils.GetSourcePath("input1")), OutputUrl = "/db/url1", InputDependencies = { inputDep }
            });

            builder1.Run(Builder.Mode.Build);

            Utils.GenerateSourceFile("inputDeps", "{E505A61B-5F2A-4BB8-8F6C-3788C76BAE5F}", true);

            var builder2           = Utils.CreateBuilder(false);
            CommandBuildStep step2 = builder2.Root.Add(new InputOutputTestCommand {
                Delay = 100, Source = new ObjectUrl(UrlType.File, Utils.GetSourcePath("input1")), OutputUrl = "/db/url1", InputDependencies = { inputDep }
            });

            builder2.Run(Builder.Mode.Build);

            var indexMap = ContentIndexMap.Load(VirtualFileSystem.ApplicationDatabaseIndexPath);

            indexMap.LoadNewValues();

            Assert.Equal(ResultStatus.Successful, step1.Status);
            Assert.Equal(ResultStatus.Successful, step2.Status);
            ObjectId inputDepId1;
            ObjectId inputDepId2;

            Assert.True(step1.Result.InputDependencyVersions.TryGetValue(inputDep, out inputDepId1));
            Assert.True(step2.Result.InputDependencyVersions.TryGetValue(inputDep, out inputDepId2));
            Assert.NotEqual(inputDepId1, inputDepId2);
        }
Пример #21
0
 /// <summary>
 /// Initializes a new instance of the <see cref="OutputObject"/> class.
 /// </summary>
 /// <param name="url">The url of the output object.</param>
 /// <param name="objectId">The hash of the output object.</param>
 public OutputObject(ObjectUrl url, ObjectId objectId)
 {
     Url = url;
     ObjectId = objectId;
     Tags = new HashSet<string>();
 }
Пример #22
0
        public void TestInputDependencies()
        {
            Utils.CleanContext();
            Utils.GenerateSourceFile("input1", "{A7246DF6-3A68-40E2-BA58-6C9A0EFF552B}");
            Utils.GenerateSourceFile("inputDeps", "{8EE7A4BC-88E1-4CC8-B03F-1E6EA8B23955}");

            var builder = Utils.CreateBuilder();
            var inputDep = new ObjectUrl(UrlType.File, Utils.GetSourcePath("inputDeps"));
            var command = new InputOutputCommand { Delay = 100, Source = new ObjectUrl(UrlType.File, Utils.GetSourcePath("input1")), OutputUrl = "/db/url1" };
            command.InputDependencies.Add(inputDep);
            CommandBuildStep step = builder.Root.Add(command);
            builder.Run(Builder.Mode.Build);

            var indexMap = AssetIndexMap.Load();
            indexMap.UseTransaction = true;
            indexMap.LoadNewValues();

            ObjectId inputDepId;
            bool inputDepFound = step.Result.InputDependencyVersions.TryGetValue(inputDep, out inputDepId);
            Assert.IsTrue(inputDepFound);
        }
Пример #23
0
        public void TestInputDependenciesChange()
        {
            Utils.CleanContext();
            Utils.GenerateSourceFile("input1", "{A7246DF6-3A68-40E2-BA58-6C9A0EFF552B}");
            Utils.GenerateSourceFile("inputDeps", "{8EE7A4BC-88E1-4CC8-B03F-1E6EA8B23955}");
            var inputDep = new ObjectUrl(UrlType.File, Utils.GetSourcePath("inputDeps"));

            var builder1 = Utils.CreateBuilder();
            CommandBuildStep step1 = builder1.Root.Add(new InputOutputCommand { Delay = 100, Source = new ObjectUrl(UrlType.File, Utils.GetSourcePath("input1")), OutputUrl = "/db/url1", InputDependencies = { inputDep } });
            builder1.Run(Builder.Mode.Build);

            Utils.GenerateSourceFile("inputDeps", "{E505A61B-5F2A-4BB8-8F6C-3788C76BAE5F}", true);
            
            var builder2 = Utils.CreateBuilder();
            CommandBuildStep step2 = builder2.Root.Add(new InputOutputCommand { Delay = 100, Source = new ObjectUrl(UrlType.File, Utils.GetSourcePath("input1")), OutputUrl = "/db/url1", InputDependencies = { inputDep } });
            builder2.Run(Builder.Mode.Build);

            var indexMap = AssetIndexMap.Load();
            indexMap.LoadNewValues();

            Assert.That(step1.Status, Is.EqualTo(ResultStatus.Successful));
            Assert.That(step2.Status, Is.EqualTo(ResultStatus.Successful));
            ObjectId inputDepId1;
            ObjectId inputDepId2;
            Assert.IsTrue(step1.Result.InputDependencyVersions.TryGetValue(inputDep, out inputDepId1));
            Assert.IsTrue(step2.Result.InputDependencyVersions.TryGetValue(inputDep, out inputDepId2));
            Assert.That(inputDepId1, !Is.EqualTo(inputDepId2));
        }
Пример #24
0
        public void TestConcurrencyReadWriteAccess2()
        {
            Utils.CleanContext();
            Utils.GenerateSourceFile("input1", "{99D73F8B-587A-4869-97AE-4A7185D88AC9}");
            var inputDep = new ObjectUrl(UrlType.File, Utils.GetSourcePath("input1"));

            var buildStepList1 = new ListBuildStep
                {
                    new ListBuildStep { new InputOutputCommand { Delay = 100, Source = inputDep, OutputUrl = "/db/url1", InputDependencies = { inputDep } } },
                    new WaitBuildStep(),
                    new InputOutputCommand { Delay = 1500, Source = new ObjectUrl(UrlType.Internal, "/db/url1"), OutputUrl = "/db/dump1", InputDependencies = { inputDep } },
                };
            var buildStepList2 = new ListBuildStep
                {
                    new ListBuildStep { new InputOutputCommand { Delay = 100, Source = inputDep, OutputUrl = "/db/url1", InputDependencies = { inputDep } } },
                    new WaitBuildStep(),
                    new InputOutputCommand { Delay = 1500, Source = new ObjectUrl(UrlType.Internal, "/db/url1"), OutputUrl = "/db/dump2", InputDependencies = { inputDep } },
                };

            var builder = Utils.CreateBuilder();
            builder.ThreadCount = 1;
            builder.Root.Add(buildStepList1);
            builder.Root.Add(buildStepList2);

            Utils.StartCapturingLog();
            var buildResult = builder.Run(Builder.Mode.Build);
            Assert.That(buildResult, Is.EqualTo(BuildResultCode.Successful));
        }
Пример #25
0
        internal OutputObject AddOutputObject(IExecuteContext executeContext, ObjectUrl outputObjectUrl, ObjectId outputObjectId, Command command)
        {
            OutputObject outputObject;

            if (!outputObjects.TryGetValue(outputObjectUrl, out outputObject))
            {
                // New item?
                outputObject = new OutputObject(outputObjectUrl, outputObjectId);
                outputObjects.Add(outputObjectUrl, outputObject);
            }
            else
            {
                // ObjectId should be similar (if no Wait happened), otherwise two tasks spawned with same parameters did output different results
                if (outputObject.ObjectId != outputObjectId && outputObject.Counter == mergeCounter)
                {
                    var error = string.Format("Commands {0} and {1} are both writing {2} at the same time", command, outputObject.Command, outputObjectUrl);
                    executeContext.Logger.Error(error);
                    throw new InvalidOperationException(error);
                }

                // Update new ObjectId
                outputObject.ObjectId = outputObjectId;
            }

            // Update Counter so that we know if a wait happened since this output object has been merged.
            outputObject.Counter = mergeCounter;
            outputObject.Command = command;

            return outputObject;
        }
Пример #26
0
 /// <summary>
 /// Adds the output object. Will try to detect input/output conflicts, and output with different <see cref="ObjectId" /> conflicts.
 /// </summary>
 /// <param name="executeContext">The execute context.</param>
 /// <param name="outputObjectUrl">The output object URL.</param>
 /// <param name="outputObjectId">The output object id.</param>
 /// <param name="command">The command that produced the output object.</param>
 /// <exception cref="System.InvalidOperationException">Two CommandBuildStep with same inputs did output different results.</exception>
 private void CheckOutputObject(IExecuteContext executeContext, ObjectUrl outputObjectUrl, ObjectId outputObjectId, Command command)
 {
     InputObject inputObject;
     if (inputObjects.TryGetValue(outputObjectUrl, out inputObject)
         && inputObject.Command != command
         && inputObject.Counter == mergeCounter)
     {
         var error = string.Format("Command {0} is writing {1} while command {2} is reading it", command, outputObjectUrl, inputObject.Command);
         executeContext.Logger.Error(error);
         throw new InvalidOperationException(error);
     }
 }
Пример #27
0
        private void AddInputObject(IExecuteContext executeContext, ObjectUrl inputObjectUrl, Command command)
        {
            OutputObject outputObject;
            if (outputObjects.TryGetValue(inputObjectUrl, out outputObject)
                && mergeCounter > outputObject.Counter)
            {
                // Object was outputed by ourself, so reading it as input should be ignored.
                return;
            }

            inputObjects[inputObjectUrl] = new InputObject { Command = command, Counter = mergeCounter };
        }
Пример #28
0
 public void AddTag(ObjectUrl url, string tag)
 {
     ResultEntry.TagSymbols.Add(new KeyValuePair <ObjectUrl, string>(url, tag));
 }
Пример #29
0
 public void RegisterOutput(ObjectUrl url, ObjectId hash)
 {
     ResultEntry.OutputObjects.Add(url, hash);
 }
Пример #30
0
 public void RegisterInputDependency(ObjectUrl url)
 {
     ResultEntry.InputDependencyVersions.Add(url, ComputeInputHash(url.Type, url.Path));
 }
Пример #31
0
        public void TestConcurrencyWriteAccess()
        {
            Utils.CleanContext();
            Utils.GenerateSourceFile("input1", "{99D73F8B-587A-4869-97AE-4A7185D88AC9}");
            Utils.GenerateSourceFile("input2", "{9FEABA51-4CE6-4DB0-9866-45A7492FD1B7}");
            var inputDep = new ObjectUrl(UrlType.File, Utils.GetSourcePath("input1"));

            var builder = Utils.CreateBuilder();
            CommandBuildStep step1 = builder.Root.Add(new InputOutputCommand { Delay = 100, Source = new ObjectUrl(UrlType.File, Utils.GetSourcePath("input1")), OutputUrl = "/db/url1", InputDependencies = { inputDep } });
            CommandBuildStep step2 = builder.Root.Add(new InputOutputCommand { Delay = 100, Source = new ObjectUrl(UrlType.File, Utils.GetSourcePath("input2")), OutputUrl = "/db/url2", InputDependencies = { inputDep } });
            builder.Root.Add(new WaitBuildStep());
            CommandBuildStep concurrencyStep1 = builder.Root.Add(new InputOutputCommand { Delay = 100, Source = new ObjectUrl(UrlType.Internal, "/db/url1"), OutputUrl = "/db/url", InputDependencies = { inputDep } });
            CommandBuildStep concurrencyStep2 = builder.Root.Add(new InputOutputCommand { Delay = 150, Source = new ObjectUrl(UrlType.Internal, "/db/url2"), OutputUrl = "/db/url", InputDependencies = { inputDep } });
            BuildStep.LinkBuildSteps(step1, concurrencyStep1);
            BuildStep.LinkBuildSteps(step2, concurrencyStep2);

            Utils.StartCapturingLog();
            builder.Run(Builder.Mode.Build);
            string log = Utils.StopCapturingLog();
            Assert.That(log.Contains("Commands InputOutputCommand /db/url2 > /db/url and InputOutputCommand /db/url1 > /db/url are both writing /db/url at the same time"));
        }
Пример #32
0
        public void TestConcurrencyReadWriteAccess()
        {
            Utils.CleanContext();
            Utils.GenerateSourceFile("input1", "{99D73F8B-587A-4869-97AE-4A7185D88AC9}");
            var inputDep = new ObjectUrl(UrlType.File, Utils.GetSourcePath("input1"));

            var builder = Utils.CreateBuilder();
            CommandBuildStep step = builder.Root.Add(new InputOutputCommand { Delay = 100, Source = new ObjectUrl(UrlType.File, Utils.GetSourcePath("input1")), OutputUrl = "/db/url1", InputDependencies = { inputDep } });
            builder.Root.Add(new WaitBuildStep());
            CommandBuildStep concurrencyStep1 = builder.Root.Add(new InputOutputCommand { Delay = 100, Source = new ObjectUrl(UrlType.Internal, "/db/url1"), OutputUrl = "/db/url1", InputDependencies = { inputDep } });
            CommandBuildStep concurrencyStep2 = builder.Root.Add(new InputOutputCommand { Delay = 150, Source = new ObjectUrl(UrlType.Internal, "/db/url1"), OutputUrl = "/db/url2", InputDependencies = { inputDep } });
            BuildStep.LinkBuildSteps(step, concurrencyStep1);
            BuildStep.LinkBuildSteps(step, concurrencyStep2);

            Utils.StartCapturingLog();
            builder.Run(Builder.Mode.Build);
            string log = Utils.StopCapturingLog();
            Assert.That(log.Contains("Command InputOutputCommand /db/url1 > /db/url1 is writing /db/url1 while command InputOutputCommand /db/url1 > /db/url2 is reading it"));
        }
Пример #33
0
 public void RegisterOutput(ObjectUrl url, ObjectId hash)
 {
     ResultEntry.OutputObjects.Add(url, hash);
 }
Пример #34
0
 public void RegisterInputDependency(ObjectUrl url)
 {
     ResultEntry.InputDependencyVersions.Add(url, ComputeInputHash(url.Type, url.Path));
 }
Пример #35
0
 /// <summary>
 /// Initializes a new instance of the <see cref="OutputObject"/> class.
 /// </summary>
 /// <param name="url">The url of the output object.</param>
 /// <param name="objectId">The hash of the output object.</param>
 public OutputObject(ObjectUrl url, ObjectId objectId)
 {
     Url      = url;
     ObjectId = objectId;
     Tags     = new HashSet <string>();
 }
Пример #36
0
 public void AddTag(ObjectUrl url, TagSymbol tagSymbol)
 {
     ResultEntry.TagSymbols.Add(new KeyValuePair<ObjectUrl, string>(url, tagSymbol.Name));
 }