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)); }
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); }
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); }
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); }
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)); }
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); }
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")); }
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")); }
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")); }
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; }
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); }
/// <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); }
/// <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); } }
/// <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); } }
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 }; }
/// <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); }
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 }; }
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)); }
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); }
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); }
/// <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>(); }
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); }
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)); }
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; }
public void AddTag(ObjectUrl url, string tag) { ResultEntry.TagSymbols.Add(new KeyValuePair <ObjectUrl, string>(url, tag)); }
public void RegisterOutput(ObjectUrl url, ObjectId hash) { ResultEntry.OutputObjects.Add(url, hash); }
public void RegisterInputDependency(ObjectUrl url) { ResultEntry.InputDependencyVersions.Add(url, ComputeInputHash(url.Type, url.Path)); }
/// <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>(); }
public void AddTag(ObjectUrl url, TagSymbol tagSymbol) { ResultEntry.TagSymbols.Add(new KeyValuePair<ObjectUrl, string>(url, tagSymbol.Name)); }