PageRenderTime 42ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Test/L0/Worker/Build/BuildDirectoryManagerL0.cs

https://gitlab.com/srbhgupta/vsts-agent
C# | 318 lines | 247 code | 35 blank | 36 comment | 12 complexity | a91a409320dffa259d93aa1d9c9de80d MD5 | raw file
  1. using Microsoft.TeamFoundation.DistributedTask.WebApi;
  2. using Microsoft.VisualStudio.Services.Agent.Worker;
  3. using Microsoft.VisualStudio.Services.Agent.Worker.Build;
  4. using Moq;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.IO;
  8. using System.Reflection;
  9. using System.Runtime.CompilerServices;
  10. using Xunit;
  11. namespace Microsoft.VisualStudio.Services.Agent.Tests.Worker.Build
  12. {
  13. public sealed class BuildDirectoryManagerL0
  14. {
  15. private const string HashKey = "1234567890123456789012345678901234567890";
  16. private const string NonmatchingHashKey = "0987654321098765432109876543210987654321";
  17. private const string CollectionId = "31ffacb8-b468-4e60-b2f9-c50ce437da92";
  18. private const string DefinitionId = "1234";
  19. private BuildDirectoryManager _buildDirectoryManager;
  20. private Mock<IExecutionContext> _ec;
  21. private ServiceEndpoint _endpoint;
  22. private TrackingConfig _existingConfig;
  23. private TrackingConfig _newConfig;
  24. private Mock<ISourceProvider> _sourceProvider;
  25. private string _trackingFile;
  26. private Mock<ITrackingManager> _trackingManager;
  27. private Variables _variables;
  28. private string _workFolder;
  29. [Fact]
  30. [Trait("Level", "L0")]
  31. [Trait("Category", "Worker")]
  32. public void CreatesBuildDirectories()
  33. {
  34. // Arrange.
  35. using (TestHostContext hc = Setup())
  36. {
  37. // Act.
  38. _buildDirectoryManager.PrepareDirectory(_ec.Object, _endpoint, _sourceProvider.Object);
  39. // Assert.
  40. Assert.True(Directory.Exists(Path.Combine(_workFolder, _newConfig.BuildDirectory, Constants.Build.Path.ArtifactsDirectory)));
  41. Assert.True(Directory.Exists(Path.Combine(_workFolder, _newConfig.BuildDirectory, Constants.Build.Path.BinariesDirectory)));
  42. Assert.True(Directory.Exists(Path.Combine(_workFolder, _newConfig.BuildDirectory, Constants.Build.Path.TestResultsDirectory)));
  43. }
  44. }
  45. [Fact]
  46. [Trait("Level", "L0")]
  47. [Trait("Category", "Worker")]
  48. public void CreatesNewConfig()
  49. {
  50. // Arrange.
  51. using (TestHostContext hc = Setup())
  52. {
  53. // Act.
  54. _buildDirectoryManager.PrepareDirectory(_ec.Object, _endpoint, _sourceProvider.Object);
  55. // Assert.
  56. _trackingManager.Verify(x => x.Create(_ec.Object, _endpoint, HashKey, _trackingFile));
  57. }
  58. }
  59. [Fact]
  60. [Trait("Level", "L0")]
  61. [Trait("Category", "Worker")]
  62. public void CreatesNewConfigWhenHashKeyIsDifferent()
  63. {
  64. // Arrange.
  65. using (TestHostContext hc = Setup(existingConfigKind: ExistingConfigKind.Nonmatching))
  66. {
  67. // Act.
  68. _buildDirectoryManager.PrepareDirectory(_ec.Object, _endpoint, _sourceProvider.Object);
  69. // Assert.
  70. _trackingManager.Verify(x => x.LoadIfExists(_ec.Object, _trackingFile));
  71. _trackingManager.Verify(x => x.Create(_ec.Object, _endpoint, HashKey, _trackingFile));
  72. _trackingManager.Verify(x => x.MarkForGarbageCollection(_ec.Object, _existingConfig));
  73. }
  74. }
  75. [Fact]
  76. [Trait("Level", "L0")]
  77. [Trait("Category", "Worker")]
  78. public void DeletesSourcesDirectoryWhenCleanIsSources()
  79. {
  80. // Arrange.
  81. using (TestHostContext hc = Setup(cleanOption: BuildCleanOption.Source))
  82. {
  83. string sourcesDirectory = Path.Combine(_workFolder, _newConfig.BuildDirectory, Constants.Build.Path.SourcesDirectory);
  84. string sourceFile = Path.Combine(sourcesDirectory, "some subdirectory", "some source file");
  85. Directory.CreateDirectory(Path.GetDirectoryName(sourceFile));
  86. File.WriteAllText(path: sourceFile, contents: "some source contents");
  87. // Act.
  88. _buildDirectoryManager.PrepareDirectory(_ec.Object, _endpoint, _sourceProvider.Object);
  89. // Assert.
  90. Assert.True(Directory.Exists(sourcesDirectory));
  91. Assert.Equal(0, Directory.GetFileSystemEntries(sourcesDirectory, "*", SearchOption.AllDirectories).Length);
  92. }
  93. }
  94. [Fact]
  95. [Trait("Level", "L0")]
  96. [Trait("Category", "Worker")]
  97. public void RecreatesArtifactsAndTestResultsDirectory()
  98. {
  99. // Arrange.
  100. using (TestHostContext hc = Setup())
  101. {
  102. string artifactsDirectory = Path.Combine(_workFolder, _newConfig.BuildDirectory, Constants.Build.Path.ArtifactsDirectory);
  103. string artifactFile = Path.Combine(artifactsDirectory, "some subdirectory", "some artifact file");
  104. Directory.CreateDirectory(Path.GetDirectoryName(artifactFile));
  105. File.WriteAllText(path: artifactFile, contents: "some artifact contents");
  106. string testResultsDirectory = Path.Combine(_workFolder, _newConfig.BuildDirectory, Constants.Build.Path.TestResultsDirectory);
  107. string testResultsFile = Path.Combine(testResultsDirectory, "some subdirectory", "some test results file");
  108. Directory.CreateDirectory(Path.GetDirectoryName(testResultsFile));
  109. File.WriteAllText(path: testResultsFile, contents: "some test result contents");
  110. // Act.
  111. _buildDirectoryManager.PrepareDirectory(_ec.Object, _endpoint, _sourceProvider.Object);
  112. // Assert.
  113. Assert.True(Directory.Exists(artifactsDirectory));
  114. Assert.Equal(0, Directory.GetFileSystemEntries(artifactsDirectory).Length);
  115. Assert.True(Directory.Exists(testResultsDirectory));
  116. Assert.Equal(0, Directory.GetFileSystemEntries(testResultsDirectory).Length);
  117. }
  118. }
  119. // Recreates build directory when clean is all.
  120. [Fact]
  121. [Trait("Level", "L0")]
  122. [Trait("Category", "Worker")]
  123. public void RecreatesBuildDirectoryWhenCleanIsAll()
  124. {
  125. // Arrange.
  126. using (TestHostContext hc = Setup(cleanOption: BuildCleanOption.All))
  127. {
  128. string buildDirectory = Path.Combine(_workFolder, _newConfig.BuildDirectory);
  129. string looseFile = Path.Combine(buildDirectory, "some loose directory", "some loose file");
  130. Directory.CreateDirectory(Path.GetDirectoryName(looseFile));
  131. File.WriteAllText(path: looseFile, contents: "some loose file contents");
  132. // Act.
  133. _buildDirectoryManager.PrepareDirectory(_ec.Object, _endpoint, _sourceProvider.Object);
  134. // Assert.
  135. Assert.Equal(4, Directory.GetFileSystemEntries(buildDirectory, "*", SearchOption.AllDirectories).Length);
  136. Assert.True(Directory.Exists(Path.Combine(_workFolder, _newConfig.BuildDirectory, Constants.Build.Path.ArtifactsDirectory)));
  137. Assert.True(Directory.Exists(Path.Combine(_workFolder, _newConfig.BuildDirectory, Constants.Build.Path.BinariesDirectory)));
  138. Assert.True(Directory.Exists(Path.Combine(_workFolder, _newConfig.BuildDirectory, Constants.Build.Path.SourcesDirectory)));
  139. Assert.True(Directory.Exists(Path.Combine(_workFolder, _newConfig.BuildDirectory, Constants.Build.Path.TestResultsDirectory)));
  140. }
  141. }
  142. [Fact]
  143. [Trait("Level", "L0")]
  144. [Trait("Category", "Worker")]
  145. public void RecreatesBinariesDirectoryWhenCleanIsBinary()
  146. {
  147. // Arrange.
  148. using (TestHostContext hc = Setup(cleanOption: BuildCleanOption.Binary))
  149. {
  150. string binariesDirectory = Path.Combine(_workFolder, _newConfig.BuildDirectory, Constants.Build.Path.BinariesDirectory);
  151. string binaryFile = Path.Combine(binariesDirectory, "some subdirectory", "some binary file");
  152. Directory.CreateDirectory(Path.GetDirectoryName(binaryFile));
  153. File.WriteAllText(path: binaryFile, contents: "some binary contents");
  154. // Act.
  155. _buildDirectoryManager.PrepareDirectory(_ec.Object, _endpoint, _sourceProvider.Object);
  156. // Assert.
  157. Assert.True(Directory.Exists(binariesDirectory));
  158. Assert.Equal(0, Directory.GetFileSystemEntries(binariesDirectory).Length);
  159. }
  160. }
  161. [Fact]
  162. [Trait("Level", "L0")]
  163. [Trait("Category", "Worker")]
  164. public void UpdatesExistingConfig()
  165. {
  166. // Arrange.
  167. using (TestHostContext hc = Setup(existingConfigKind: ExistingConfigKind.Matching))
  168. {
  169. // Act.
  170. _buildDirectoryManager.PrepareDirectory(_ec.Object, _endpoint, _sourceProvider.Object);
  171. // Assert.
  172. _trackingManager.Verify(x => x.LoadIfExists(_ec.Object, _trackingFile));
  173. _trackingManager.Verify(x => x.UpdateJobRunProperties(_ec.Object, _existingConfig, _trackingFile));
  174. }
  175. }
  176. // TODO: Updates legacy config.
  177. private TestHostContext Setup(
  178. [CallerMemberName] string name = "",
  179. BuildCleanOption? cleanOption = null,
  180. ExistingConfigKind existingConfigKind = ExistingConfigKind.None)
  181. {
  182. // Setup the host context.
  183. TestHostContext hc = new TestHostContext(this, name);
  184. // Create a random work path.
  185. var configStore = new Mock<IConfigurationStore>();
  186. _workFolder = Path.Combine(
  187. Path.GetDirectoryName(Assembly.GetEntryAssembly().Location),
  188. $"_work_{Path.GetRandomFileName()}");
  189. var settings = new AgentSettings() { WorkFolder = _workFolder };
  190. configStore.Setup(x => x.GetSettings()).Returns(settings);
  191. hc.SetSingleton<IConfigurationStore>(configStore.Object);
  192. // Setup the execution context.
  193. _ec = new Mock<IExecutionContext>();
  194. List<string> warnings;
  195. _variables = new Variables(hc, new Dictionary<string, string>(), new List<MaskHint>(), out warnings);
  196. _variables.Set(Constants.Variables.System.CollectionId, CollectionId);
  197. _variables.Set(Constants.Variables.System.DefinitionId, DefinitionId);
  198. _variables.Set(Constants.Variables.Build.Clean, $"{cleanOption}");
  199. _ec.Setup(x => x.Variables).Returns(_variables);
  200. // Store the expected tracking file path.
  201. _trackingFile = Path.Combine(
  202. _workFolder,
  203. Constants.Build.Path.SourceRootMappingDirectory,
  204. _ec.Object.Variables.System_CollectionId,
  205. _ec.Object.Variables.System_DefinitionId,
  206. Constants.Build.Path.TrackingConfigFile);
  207. // Setup the endpoint.
  208. _endpoint = new ServiceEndpoint()
  209. {
  210. Name = "Some endpoint name",
  211. Url = new Uri("http://contoso.visualstudio.com"),
  212. };
  213. // Setup the source provider.
  214. _sourceProvider = new Mock<ISourceProvider>();
  215. _sourceProvider
  216. .Setup(x => x.GetBuildDirectoryHashKey(_ec.Object, _endpoint))
  217. .Returns(HashKey);
  218. hc.SetSingleton<ISourceProvider>(_sourceProvider.Object);
  219. // Store the existing config object.
  220. switch (existingConfigKind)
  221. {
  222. case ExistingConfigKind.Matching:
  223. _existingConfig = new TrackingConfig(_ec.Object, _endpoint, 1, HashKey);
  224. Assert.Equal("1", _existingConfig.BuildDirectory);
  225. break;
  226. case ExistingConfigKind.Nonmatching:
  227. _existingConfig = new TrackingConfig(_ec.Object, _endpoint, 2, NonmatchingHashKey);
  228. Assert.Equal("2", _existingConfig.BuildDirectory);
  229. break;
  230. case ExistingConfigKind.None:
  231. break;
  232. default:
  233. throw new NotSupportedException();
  234. }
  235. // Store the new config object.
  236. if (existingConfigKind == ExistingConfigKind.Matching)
  237. {
  238. _newConfig = _existingConfig;
  239. }
  240. else
  241. {
  242. _newConfig = new TrackingConfig(_ec.Object, _endpoint, 3, HashKey);
  243. Assert.Equal("3", _newConfig.BuildDirectory);
  244. }
  245. // Setup the tracking manager.
  246. _trackingManager = new Mock<ITrackingManager>();
  247. _trackingManager
  248. .Setup(x => x.LoadIfExists(_ec.Object, _trackingFile))
  249. .Returns(_existingConfig);
  250. if (existingConfigKind == ExistingConfigKind.None || existingConfigKind == ExistingConfigKind.Nonmatching)
  251. {
  252. _trackingManager
  253. .Setup(x => x.Create(_ec.Object, _endpoint, HashKey, _trackingFile))
  254. .Returns(_newConfig);
  255. if (existingConfigKind == ExistingConfigKind.Nonmatching)
  256. {
  257. _trackingManager
  258. .Setup(x => x.MarkForGarbageCollection(_ec.Object, _existingConfig));
  259. }
  260. }
  261. else if (existingConfigKind == ExistingConfigKind.Matching)
  262. {
  263. _trackingManager
  264. .Setup(x => x.UpdateJobRunProperties(_ec.Object, _existingConfig, _trackingFile));
  265. }
  266. else
  267. {
  268. throw new NotSupportedException();
  269. }
  270. hc.SetSingleton<ITrackingManager>(_trackingManager.Object);
  271. // Setup the build directory manager.
  272. _buildDirectoryManager = new BuildDirectoryManager();
  273. _buildDirectoryManager.Initialize(hc);
  274. return hc;
  275. }
  276. private enum ExistingConfigKind
  277. {
  278. None,
  279. Matching,
  280. Nonmatching,
  281. }
  282. }
  283. }