From 9862fbb4d75b1c64abcbfee4a782da3d795d5281 Mon Sep 17 00:00:00 2001 From: Livar Date: Wed, 23 Nov 2016 22:59:54 -0800 Subject: [PATCH] Checking that the lock file exists before trying to acquire the lock for it. (#4797) * Checking that the lock file exists before trying to acquire a lock for it, which takes up to 30 seconds. * Adding a test for failing when reading the lock file and it does not exists. --- .../Extensions/LockFileFormatExtensions.cs | 9 ++++ .../GivenThatWeWantToReadLockFilesQuickly.cs | 49 +++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 test/Microsoft.DotNet.Cli.Utils.Tests/GivenThatWeWantToReadLockFilesQuickly.cs diff --git a/src/Microsoft.DotNet.Cli.Utils/Extensions/LockFileFormatExtensions.cs b/src/Microsoft.DotNet.Cli.Utils/Extensions/LockFileFormatExtensions.cs index a5f5d7c92..01eafe3d9 100644 --- a/src/Microsoft.DotNet.Cli.Utils/Extensions/LockFileFormatExtensions.cs +++ b/src/Microsoft.DotNet.Cli.Utils/Extensions/LockFileFormatExtensions.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System; +using System.IO; using System.Threading; using System.Threading.Tasks; @@ -19,6 +20,14 @@ namespace Microsoft.DotNet.Cli.Utils public static async Task ReadWithLock(this LockFileFormat subject, string path) { + if(!File.Exists(path)) + { + throw new GracefulException(string.Join( + Environment.NewLine, + $"File not found `{path}`.", + "The project may not have been restored or restore failed - run `dotnet restore`")); + } + return await ConcurrencyUtilities.ExecuteWithFileLockedAsync( path, lockedToken => diff --git a/test/Microsoft.DotNet.Cli.Utils.Tests/GivenThatWeWantToReadLockFilesQuickly.cs b/test/Microsoft.DotNet.Cli.Utils.Tests/GivenThatWeWantToReadLockFilesQuickly.cs new file mode 100644 index 000000000..410e8c9b2 --- /dev/null +++ b/test/Microsoft.DotNet.Cli.Utils.Tests/GivenThatWeWantToReadLockFilesQuickly.cs @@ -0,0 +1,49 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.Diagnostics; +using System.IO; +using FluentAssertions; +using Microsoft.DotNet.Cli; +using Microsoft.DotNet.Cli.Utils; +using Microsoft.DotNet.InternalAbstractions; +using Microsoft.DotNet.TestFramework; +using Microsoft.DotNet.Tools.Test.Utilities; +using NuGet.Frameworks; +using NuGet.ProjectModel; +using Xunit; + +namespace Microsoft.DotNet.Cli.Utils.Tests +{ + public class GivenThatWeWantToReadLockFilesQuickly : TestBase + { + [Fact] + public void ItFailsInLessThanOneSecondWhenTheProjectAssetsJsonDoesNotExist() + { + var testInstance = TestAssets.Get("TestAppWithProjDepTool") + .CreateInstance() + .WithSourceFiles(); + + var assetsFile = testInstance.Root.GetDirectory("obj").GetFile("project.assets.json").FullName; + var expectedMessage = string.Join( + Environment.NewLine, + $"File not found `{assetsFile}`.", + "The project may not have been restored or restore failed - run `dotnet restore`"); + + Action action = () => + { + var lockFile = new LockFileFormat() + .ReadWithLock(assetsFile) + .Result; + }; + + var stopWatch = Stopwatch.StartNew(); + + action.ShouldThrow().WithMessage(expectedMessage); + + stopWatch.Stop(); + stopWatch.ElapsedMilliseconds.Should().BeLessThan(1000); + } + } +} \ No newline at end of file