1 // Copyright (c) Microsoft. All rights reserved.
2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 //-----------------------------------------------------------------------
4 // </copyright>
5 // <summary>A fake task builder used for testing other components.</summary>
6 //-----------------------------------------------------------------------
7 
8 using System;
9 using System.Collections.Generic;
10 using System.Text;
11 using System.Threading;
12 using System.Linq;
13 using Microsoft.Build.Framework;
14 using Microsoft.Build.BackEnd;
15 using Microsoft.Build.Shared;
16 using Microsoft.Build.Collections;
17 using Microsoft.Build.Evaluation;
18 using Microsoft.Build.Execution;
19 
20 using TargetLoggingContext = Microsoft.Build.BackEnd.Logging.TargetLoggingContext;
21 using System.Threading.Tasks;
22 
23 namespace Microsoft.Build.UnitTests.BackEnd
24 {
25     /// <summary>
26     /// The mock task builder.
27     /// </summary>
28     internal class MockTaskBuilder : ITaskBuilder, IBuildComponent
29     {
30         /// <summary>
31         /// The component host.
32         /// </summary>
33         private IBuildComponentHost _host;
34 
35         /// <summary>
36         /// The current task number.
37         /// </summary>
38         private int _taskNumber;
39 
40         /// <summary>
41         /// Constructor.
42         /// </summary>
MockTaskBuilder()43         public MockTaskBuilder()
44         {
45             Reset();
46         }
47 
48         /// <summary>
49         /// The list of tasks executed.
50         /// </summary>
51         public List<ProjectTaskInstance> ExecutedTasks
52         {
53             get;
54             set;
55         }
56 
57         /// <summary>
58         /// The list of OnError tasks.
59         /// </summary>
60         public List<ProjectOnErrorInstance> ErrorTasks
61         {
62             get;
63             set;
64         }
65 
66         /// <summary>
67         /// The task ordinal to fail on.
68         /// </summary>
69         public int FailTaskNumber
70         {
71             get;
72             set;
73         }
74 
75         /// <summary>
76         /// Resets the mock task builder to its clean state.
77         /// </summary>
Reset()78         public void Reset()
79         {
80             ErrorTasks = new List<ProjectOnErrorInstance>();
81             ExecutedTasks = new List<ProjectTaskInstance>();
82             FailTaskNumber = -1;
83             _taskNumber = 0;
84         }
85 
86         #region ITaskBuilder Members
87 
88         /// <summary>
89         /// Executes the task.
90         /// </summary>
ExecuteTask(TargetLoggingContext targetLoggingContext, BuildRequestEntry requestEntry, ITargetBuilderCallback targetBuilderCallback, ProjectTargetInstanceChild task, TaskExecutionMode mode, Lookup lookupForInference, Lookup lookupForExecution, CancellationToken cancellationToken)91         public Task<WorkUnitResult> ExecuteTask(TargetLoggingContext targetLoggingContext, BuildRequestEntry requestEntry, ITargetBuilderCallback targetBuilderCallback, ProjectTargetInstanceChild task, TaskExecutionMode mode, Lookup lookupForInference, Lookup lookupForExecution, CancellationToken cancellationToken)
92         {
93             if (cancellationToken.IsCancellationRequested)
94             {
95                 return Task<WorkUnitResult>.FromResult(new WorkUnitResult(WorkUnitResultCode.Canceled, WorkUnitActionCode.Stop, null));
96             }
97 
98             ProjectOnErrorInstance errorTask = task as ProjectOnErrorInstance;
99             if (null != errorTask)
100             {
101                 ErrorTasks.Add(errorTask);
102             }
103             else
104             {
105                 ProjectTaskInstance taskInstance = task as ProjectTaskInstance;
106                 ExecutedTasks.Add(taskInstance);
107 
108                 if ((mode & TaskExecutionMode.InferOutputsOnly) == TaskExecutionMode.InferOutputsOnly)
109                 {
110                     lookupForInference.AddNewItem(new ProjectItemInstance(requestEntry.RequestConfiguration.Project, taskInstance.Name + "_Item", "Item", task.Location.File));
111                 }
112                 else if ((mode & TaskExecutionMode.ExecuteTaskAndGatherOutputs) == TaskExecutionMode.ExecuteTaskAndGatherOutputs)
113                 {
114                     lookupForExecution.AddNewItem(new ProjectItemInstance(requestEntry.RequestConfiguration.Project, taskInstance.Name + "_Item", "Item", task.Location.File));
115                 }
116 
117                 if (String.Equals(taskInstance.Name, "CallTarget", StringComparison.OrdinalIgnoreCase))
118                 {
119                     taskInstance.GetParameter("Targets");
120                     char[] splitter = new char[] { ';' };
121                     targetBuilderCallback.LegacyCallTarget(taskInstance.GetParameter("Targets").Split(splitter), false, taskInstance.Location);
122                 }
123 
124                 _taskNumber++;
125                 if (FailTaskNumber == _taskNumber)
126                 {
127                     if (taskInstance.ContinueOnError == "True")
128                     {
129                         return Task<WorkUnitResult>.FromResult(new WorkUnitResult(WorkUnitResultCode.Failed, WorkUnitActionCode.Continue, null));
130                     }
131 
132                     return Task<WorkUnitResult>.FromResult(new WorkUnitResult(WorkUnitResultCode.Failed, WorkUnitActionCode.Stop, null));
133                 }
134             }
135 
136             return Task<WorkUnitResult>.FromResult(new WorkUnitResult(WorkUnitResultCode.Success, WorkUnitActionCode.Continue, null));
137         }
138 
139         #endregion
140 
141         #region IBuildComponent Members
142 
143         /// <summary>
144         /// Sets the component host.
145         /// </summary>
146         /// <param name="host">The component host</param>
InitializeComponent(IBuildComponentHost host)147         public void InitializeComponent(IBuildComponentHost host)
148         {
149             _host = host;
150         }
151 
152         /// <summary>
153         /// Shuts down the component.
154         /// </summary>
ShutdownComponent()155         public void ShutdownComponent()
156         {
157             _host = null;
158         }
159 
160         #endregion
161     }
162 }
163