/*
* Copyright (c) 2023 Proton AG
*
* This file is part of ProtonVPN.
*
* ProtonVPN is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ProtonVPN is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ProtonVPN. If not, see .
*/
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NSubstitute;
using ProtonVPN.Common.Core.Extensions;
using ProtonVPN.Logging;
using ProtonVPN.Logging.Contracts;
using ProtonVPN.Tests.Common;
namespace ProtonVPN.Common.Tests.Logging
{
[TestClass]
public class LogCleanerTest
{
private ILogger _logger;
[TestInitialize]
public void TestInitialize()
{
_logger = Substitute.For();
}
[TestMethod]
public void Clean_ShouldNotThrow_WhenFolderNotExists()
{
// Arrange
const string logPath = "Folder\\Does\\Not\\Exist";
LogCleaner cleaner = new(_logger);
// Act
Action action = () => cleaner.Clean(logPath, 0);
//Assert
action.Should().NotThrow();
}
[TestMethod]
public void Clean_ShouldDeleteOldFiles()
{
DateTime lastWriteDate = DateTime.UtcNow.Subtract(LogCleaner.MAXIMUM_FILE_AGE).AddDays(-2);
IEnumerable result = ArrangeAndActByLastWriteDate(lastWriteDate);
// Assert
result.Should().HaveCount(0);
}
private IEnumerable ArrangeAndActByLastWriteDate(DateTime lastWriteDate)
{
// Arrange
string logPath = TestConfig.GetFolderPath();
CreateEmptyDirectory(logPath);
IList files = new[] { "file.log", "file1.log", "file2.log", "file3.log", "file4.log" }.Select(f => Path.Combine(logPath, f)).ToList();
files.ForEach(CreateEmptyFile);
File.SetLastWriteTimeUtc(files[0], lastWriteDate.AddMinutes(50));
File.SetLastWriteTimeUtc(files[1], lastWriteDate.AddMinutes(40));
File.SetLastWriteTimeUtc(files[2], lastWriteDate.AddMinutes(30));
File.SetLastWriteTimeUtc(files[3], lastWriteDate.AddMinutes(20));
File.SetLastWriteTimeUtc(files[4], lastWriteDate.AddMinutes(10));
LogCleaner cleaner = new(_logger);
// Act
cleaner.Clean(logPath, 2);
return Directory.GetFiles(logPath).Select(Path.GetFileName);
}
[TestMethod]
public void Clean_ShouldDeleteOldestFiles()
{
DateTime lastWriteDate = DateTime.UtcNow.Subtract(LogCleaner.MAXIMUM_FILE_AGE).AddDays(2);
IEnumerable result = ArrangeAndActByLastWriteDate(lastWriteDate);
// Assert
result.Should().HaveCount(2)
.And.Contain(new[] { "file.log", "file1.log" });
}
[TestMethod]
public void Clean_ShouldSkipLockedFile()
{
// Arrange
string logPath = TestConfig.GetFolderPath();
CreateEmptyDirectory(logPath);
IList files = new[] { "file2.log", "file1.log", "file.log" }.Select(f => Path.Combine(logPath, f)).ToList();
files.ForEach(CreateEmptyFile);
File.SetCreationTimeUtc(files[0], new(2000, 01, 01, 0, 10, 0));
File.SetCreationTimeUtc(files[1], new(2000, 01, 01, 0, 20, 0));
File.SetCreationTimeUtc(files[2], new(2000, 01, 01, 0, 30, 0));
LogCleaner cleaner = new(_logger);
// Act
using (File.OpenRead(files[1]))
{
cleaner.Clean(logPath, 0);
}
IEnumerable result = Directory.GetFiles(logPath).Select(Path.GetFileName);
// Assert
result.Should().HaveCount(1)
.And.Contain(new[] { "file1.log" });
}
#region Helpers
private static void CreateEmptyDirectory(string path)
{
if (Directory.Exists(path))
{
Directory.Delete(path, true);
}
Directory.CreateDirectory(path);
}
private static void CreateEmptyFile(string filename)
{
File.Create(filename).Dispose();
}
#endregion
}
}