From 548200889cce7d5c1d31c41702246a480789e455 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20S=C3=A1nchez=20L=C3=B3pez?= <1175054+carlossanlop@users.noreply.github.com> Date: Mon, 17 Jul 2023 12:20:26 -0700 Subject: [PATCH] Move tests for large files to a new manual tests project. --- .../System.Formats.Tar/System.Formats.Tar.sln | 9 ++ .../tests/Manual/ManualTests.cs | 93 +++++++++++++++++++ .../tests/Manual/ManualTestsAsync.cs | 82 ++++++++++++++++ .../System.Formats.Tar.Manual.Tests.csproj | 15 +++ .../tests/System.Formats.Tar.Tests.csproj | 3 - .../TarWriter.WriteEntry.LongFile.Tests.cs | 92 ------------------ ...arWriter.WriteEntryAsync.LongFile.Tests.cs | 82 ---------------- 7 files changed, 199 insertions(+), 177 deletions(-) create mode 100644 src/libraries/System.Formats.Tar/tests/Manual/ManualTests.cs create mode 100644 src/libraries/System.Formats.Tar/tests/Manual/ManualTestsAsync.cs create mode 100644 src/libraries/System.Formats.Tar/tests/Manual/System.Formats.Tar.Manual.Tests.csproj delete mode 100644 src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.WriteEntry.LongFile.Tests.cs delete mode 100644 src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.WriteEntryAsync.LongFile.Tests.cs diff --git a/src/libraries/System.Formats.Tar/System.Formats.Tar.sln b/src/libraries/System.Formats.Tar/System.Formats.Tar.sln index fb37626ec3e44..a5ff8f46a4388 100644 --- a/src/libraries/System.Formats.Tar/System.Formats.Tar.sln +++ b/src/libraries/System.Formats.Tar/System.Formats.Tar.sln @@ -9,6 +9,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Formats.Tar", "src\S EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Formats.Tar.Tests", "tests\System.Formats.Tar.Tests.csproj", "{6FD1E284-7B50-4077-B73A-5B31CB0E3577}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Formats.Tar.Manual.Tests", "tests\Manual\System.Formats.Tar.Manual.Tests.csproj", "{D2788A26-CDAE-4388-AE4B-A36B0E6DFF9D}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ComInterfaceGenerator", "..\System.Runtime.InteropServices\gen\ComInterfaceGenerator\ComInterfaceGenerator.csproj", "{00477EA4-C3E5-48A9-8CA8-8CCF689E0DB4}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LibraryImportGenerator", "..\System.Runtime.InteropServices\gen\LibraryImportGenerator\LibraryImportGenerator.csproj", "{E89FEF3E-E0B9-41C4-A51C-9759AD1A3B69}" @@ -67,6 +69,10 @@ Global {A00011A0-E609-4A49-B893-EBFC72C98707}.Debug|Any CPU.Build.0 = Debug|Any CPU {A00011A0-E609-4A49-B893-EBFC72C98707}.Release|Any CPU.ActiveCfg = Release|Any CPU {A00011A0-E609-4A49-B893-EBFC72C98707}.Release|Any CPU.Build.0 = Release|Any CPU + {D2788A26-CDAE-4388-AE4B-A36B0E6DFF9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D2788A26-CDAE-4388-AE4B-A36B0E6DFF9D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D2788A26-CDAE-4388-AE4B-A36B0E6DFF9D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D2788A26-CDAE-4388-AE4B-A36B0E6DFF9D}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -78,9 +84,12 @@ Global {E0B882C6-2082-45F2-806E-568461A61975} = {9BE8AFF4-D37B-49AF-AFD3-A15E514AC8AE} {A00011A0-E609-4A49-B893-EBFC72C98707} = {9BE8AFF4-D37B-49AF-AFD3-A15E514AC8AE} {9F751C2B-56DD-4604-A3F3-568627F8C006} = {55A8C7E4-925C-4F21-B68B-CEFC19137A4B} + {6FD1E284-7B50-4077-B73A-5B31CB0E3577} = {6CF0D830-3EE9-44B1-B548-EA8750AD7B3E} {00477EA4-C3E5-48A9-8CA8-8CCF689E0DB4} = {0345BAA8-92BC-4499-B550-21AC44910FD2} {E89FEF3E-E0B9-41C4-A51C-9759AD1A3B69} = {0345BAA8-92BC-4499-B550-21AC44910FD2} {50E6D5FD-0E06-4D07-966E-C28E5448A1D3} = {0345BAA8-92BC-4499-B550-21AC44910FD2} + {A00011A0-E609-4A49-B893-EBFC72C98707} = {9BE8AFF4-D37B-49AF-AFD3-A15E514AC8AE} + {D2788A26-CDAE-4388-AE4B-A36B0E6DFF9D} = {6CF0D830-3EE9-44B1-B548-EA8750AD7B3E} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {F9B8DA67-C83B-466D-907C-9541CDBDCFEF} diff --git a/src/libraries/System.Formats.Tar/tests/Manual/ManualTests.cs b/src/libraries/System.Formats.Tar/tests/Manual/ManualTests.cs new file mode 100644 index 0000000000000..1fa1c686e40e8 --- /dev/null +++ b/src/libraries/System.Formats.Tar/tests/Manual/ManualTests.cs @@ -0,0 +1,93 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.IO; +using Xunit; + +namespace System.Formats.Tar.Tests; + +[OuterLoop] +[Collection(nameof(DisableParallelization))] // don't create multiple large files at the same time +public class ManualTests : TarTestsBase +{ + public static bool ManualTestsEnabled => !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("MANUAL_TESTS")); + + public static IEnumerable WriteEntry_LongFileSize_TheoryData() + { + foreach (bool unseekableStream in new[] { false, true }) + { + foreach (TarEntryFormat entryFormat in new[] { TarEntryFormat.V7, TarEntryFormat.Ustar, TarEntryFormat.Gnu, TarEntryFormat.Pax }) + { + yield return new object[] { entryFormat, LegacyMaxFileSize, unseekableStream }; + } + + // Pax supports unlimited size files. + yield return new object[] { TarEntryFormat.Pax, LegacyMaxFileSize + 1, unseekableStream }; + } + } + + [ConditionalTheory(nameof(ManualTestsEnabled))] + [MemberData(nameof(WriteEntry_LongFileSize_TheoryData))] + [SkipOnPlatform(TestPlatforms.iOS | TestPlatforms.tvOS | TestPlatforms.Android | TestPlatforms.Browser, "Needs too much disk space.")] + public void WriteEntry_LongFileSize(TarEntryFormat entryFormat, long size, bool unseekableStream) + { + // Write archive with a 8 Gb long entry. + using FileStream tarFile = File.Open(GetTestFilePath(), new FileStreamOptions { Access = FileAccess.ReadWrite, Mode = FileMode.Create, Options = FileOptions.DeleteOnClose }); + Stream s = unseekableStream ? new WrappedStream(tarFile, tarFile.CanRead, tarFile.CanWrite, canSeek: false) : tarFile; + + using (TarWriter writer = new(s, leaveOpen: true)) + { + TarEntry writeEntry = InvokeTarEntryCreationConstructor(entryFormat, entryFormat is TarEntryFormat.V7 ? TarEntryType.V7RegularFile : TarEntryType.RegularFile, "foo"); + writeEntry.DataStream = new SimulatedDataStream(size); + writer.WriteEntry(writeEntry); + } + + tarFile.Position = 0; + + // Read archive back. + using TarReader reader = new TarReader(s); + TarEntry entry = reader.GetNextEntry(); + Assert.Equal(size, entry.Length); + + Stream dataStream = entry.DataStream; + Assert.Equal(size, dataStream.Length); + Assert.Equal(0, dataStream.Position); + + ReadOnlySpan dummyData = SimulatedDataStream.DummyData.Span; + + // Read the first bytes. + Span buffer = new byte[dummyData.Length]; + Assert.Equal(buffer.Length, dataStream.Read(buffer)); + AssertExtensions.SequenceEqual(dummyData, buffer); + Assert.Equal(0, dataStream.ReadByte()); // check next byte is correct. + buffer.Clear(); + + // Read the last bytes. + long dummyDataOffset = size - dummyData.Length - 1; + if (dataStream.CanSeek) + { + Assert.False(unseekableStream); + dataStream.Seek(dummyDataOffset, SeekOrigin.Begin); + } + else + { + Assert.True(unseekableStream); + Span seekBuffer = new byte[4_096]; + + while (dataStream.Position < dummyDataOffset) + { + int bufSize = (int)Math.Min(seekBuffer.Length, dummyDataOffset - dataStream.Position); + int res = dataStream.Read(seekBuffer.Slice(0, bufSize)); + Assert.True(res > 0, "Unseekable stream finished before expected - Something went very wrong"); + } + } + + Assert.Equal(0, dataStream.ReadByte()); // check previous byte is correct. + Assert.Equal(buffer.Length, dataStream.Read(buffer)); + AssertExtensions.SequenceEqual(dummyData, buffer); + Assert.Equal(size, dataStream.Position); + + Assert.Null(reader.GetNextEntry()); + } +} diff --git a/src/libraries/System.Formats.Tar/tests/Manual/ManualTestsAsync.cs b/src/libraries/System.Formats.Tar/tests/Manual/ManualTestsAsync.cs new file mode 100644 index 0000000000000..5262c71525617 --- /dev/null +++ b/src/libraries/System.Formats.Tar/tests/Manual/ManualTestsAsync.cs @@ -0,0 +1,82 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using Xunit; + +namespace System.Formats.Tar.Tests; + +[OuterLoop] +[Collection(nameof(DisableParallelization))] // don't create multiple large files at the same time +public class ManualTestsAsync : TarTestsBase +{ + public static IEnumerable WriteEntry_LongFileSize_TheoryDataAsync() + // Fixes error xUnit1015: MemberData needs to be in the same class + => ManualTests.WriteEntry_LongFileSize_TheoryData(); + + [ConditionalTheory(nameof(ManualTests.ManualTestsEnabled))] + [MemberData(nameof(WriteEntry_LongFileSize_TheoryDataAsync))] + [SkipOnPlatform(TestPlatforms.iOS | TestPlatforms.tvOS | TestPlatforms.Android | TestPlatforms.Browser, "Needs too much disk space.")] + public async Task WriteEntry_LongFileSizeAsync(TarEntryFormat entryFormat, long size, bool unseekableStream) + { + // Write archive with a 8 Gb long entry. + await using FileStream tarFile = File.Open(GetTestFilePath(), new FileStreamOptions { Access = FileAccess.ReadWrite, Mode = FileMode.Create, Options = FileOptions.DeleteOnClose }); + Stream s = unseekableStream ? new WrappedStream(tarFile, tarFile.CanRead, tarFile.CanWrite, canSeek: false) : tarFile; + + await using (TarWriter writer = new(s, leaveOpen: true)) + { + TarEntry writeEntry = InvokeTarEntryCreationConstructor(entryFormat, entryFormat is TarEntryFormat.V7 ? TarEntryType.V7RegularFile : TarEntryType.RegularFile, "foo"); + writeEntry.DataStream = new SimulatedDataStream(size); + await writer.WriteEntryAsync(writeEntry); + } + + tarFile.Position = 0; + + // Read the archive back. + await using TarReader reader = new TarReader(s); + TarEntry entry = await reader.GetNextEntryAsync(); + Assert.Equal(size, entry.Length); + + Stream dataStream = entry.DataStream; + Assert.Equal(size, dataStream.Length); + Assert.Equal(0, dataStream.Position); + + ReadOnlyMemory dummyData = SimulatedDataStream.DummyData; + + // Read the first bytes. + byte[] buffer = new byte[dummyData.Length]; + Assert.Equal(buffer.Length, dataStream.Read(buffer)); + AssertExtensions.SequenceEqual(dummyData.Span, buffer); + Assert.Equal(0, dataStream.ReadByte()); // check next byte is correct. + buffer.AsSpan().Clear(); + + // Read the last bytes. + long dummyDataOffset = size - dummyData.Length - 1; + if (dataStream.CanSeek) + { + Assert.False(unseekableStream); + dataStream.Seek(dummyDataOffset, SeekOrigin.Begin); + } + else + { + Assert.True(unseekableStream); + Memory seekBuffer = new byte[4_096]; + + while (dataStream.Position < dummyDataOffset) + { + int bufSize = (int)Math.Min(seekBuffer.Length, dummyDataOffset - dataStream.Position); + int res = await dataStream.ReadAsync(seekBuffer.Slice(0, bufSize)); + Assert.True(res > 0, "Unseekable stream finished before expected - Something went very wrong"); + } + } + + Assert.Equal(0, dataStream.ReadByte()); // check previous byte is correct. + Assert.Equal(buffer.Length, dataStream.Read(buffer)); + AssertExtensions.SequenceEqual(dummyData.Span, buffer); + Assert.Equal(size, dataStream.Position); + + Assert.Null(await reader.GetNextEntryAsync()); + } +} diff --git a/src/libraries/System.Formats.Tar/tests/Manual/System.Formats.Tar.Manual.Tests.csproj b/src/libraries/System.Formats.Tar/tests/Manual/System.Formats.Tar.Manual.Tests.csproj new file mode 100644 index 0000000000000..99adaab083f71 --- /dev/null +++ b/src/libraries/System.Formats.Tar/tests/Manual/System.Formats.Tar.Manual.Tests.csproj @@ -0,0 +1,15 @@ + + + $(NetCoreAppCurrent) + true + + + + + + + + + + + diff --git a/src/libraries/System.Formats.Tar/tests/System.Formats.Tar.Tests.csproj b/src/libraries/System.Formats.Tar/tests/System.Formats.Tar.Tests.csproj index fd3f3baed2e2a..f3a341d4adc63 100644 --- a/src/libraries/System.Formats.Tar/tests/System.Formats.Tar.Tests.csproj +++ b/src/libraries/System.Formats.Tar/tests/System.Formats.Tar.Tests.csproj @@ -53,10 +53,8 @@ - - @@ -74,7 +72,6 @@ - diff --git a/src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.WriteEntry.LongFile.Tests.cs b/src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.WriteEntry.LongFile.Tests.cs deleted file mode 100644 index 1368f452c0165..0000000000000 --- a/src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.WriteEntry.LongFile.Tests.cs +++ /dev/null @@ -1,92 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Generic; -using System.IO; -using Xunit; - -namespace System.Formats.Tar.Tests -{ - [OuterLoop] - [Collection(nameof(DisableParallelization))] // don't create multiple large files at the same time - public class TarWriter_WriteEntry_LongFile_Tests : TarTestsBase - { - public static IEnumerable WriteEntry_LongFileSize_TheoryData() - { - foreach (bool unseekableStream in new[] { false, true }) - { - foreach (TarEntryFormat entryFormat in new[] { TarEntryFormat.V7, TarEntryFormat.Ustar, TarEntryFormat.Gnu, TarEntryFormat.Pax }) - { - yield return new object[] { entryFormat, LegacyMaxFileSize, unseekableStream }; - } - - // Pax supports unlimited size files. - yield return new object[] { TarEntryFormat.Pax, LegacyMaxFileSize + 1, unseekableStream }; - } - } - - [Theory] - [MemberData(nameof(WriteEntry_LongFileSize_TheoryData))] - [SkipOnPlatform(TestPlatforms.iOS | TestPlatforms.tvOS | TestPlatforms.Android | TestPlatforms.Browser, "Needs too much disk space.")] - public void WriteEntry_LongFileSize(TarEntryFormat entryFormat, long size, bool unseekableStream) - { - // Write archive with a 8 Gb long entry. - using FileStream tarFile = File.Open(GetTestFilePath(), new FileStreamOptions { Access = FileAccess.ReadWrite, Mode = FileMode.Create, Options = FileOptions.DeleteOnClose }); - Stream s = unseekableStream ? new WrappedStream(tarFile, tarFile.CanRead, tarFile.CanWrite, canSeek: false) : tarFile; - - using (TarWriter writer = new(s, leaveOpen: true)) - { - TarEntry writeEntry = InvokeTarEntryCreationConstructor(entryFormat, entryFormat is TarEntryFormat.V7 ? TarEntryType.V7RegularFile : TarEntryType.RegularFile, "foo"); - writeEntry.DataStream = new SimulatedDataStream(size); - writer.WriteEntry(writeEntry); - } - - tarFile.Position = 0; - - // Read archive back. - using TarReader reader = new TarReader(s); - TarEntry entry = reader.GetNextEntry(); - Assert.Equal(size, entry.Length); - - Stream dataStream = entry.DataStream; - Assert.Equal(size, dataStream.Length); - Assert.Equal(0, dataStream.Position); - - ReadOnlySpan dummyData = SimulatedDataStream.DummyData.Span; - - // Read the first bytes. - Span buffer = new byte[dummyData.Length]; - Assert.Equal(buffer.Length, dataStream.Read(buffer)); - AssertExtensions.SequenceEqual(dummyData, buffer); - Assert.Equal(0, dataStream.ReadByte()); // check next byte is correct. - buffer.Clear(); - - // Read the last bytes. - long dummyDataOffset = size - dummyData.Length - 1; - if (dataStream.CanSeek) - { - Assert.False(unseekableStream); - dataStream.Seek(dummyDataOffset, SeekOrigin.Begin); - } - else - { - Assert.True(unseekableStream); - Span seekBuffer = new byte[4_096]; - - while (dataStream.Position < dummyDataOffset) - { - int bufSize = (int)Math.Min(seekBuffer.Length, dummyDataOffset - dataStream.Position); - int res = dataStream.Read(seekBuffer.Slice(0, bufSize)); - Assert.True(res > 0, "Unseekable stream finished before expected - Something went very wrong"); - } - } - - Assert.Equal(0, dataStream.ReadByte()); // check previous byte is correct. - Assert.Equal(buffer.Length, dataStream.Read(buffer)); - AssertExtensions.SequenceEqual(dummyData, buffer); - Assert.Equal(size, dataStream.Position); - - Assert.Null(reader.GetNextEntry()); - } - } -} diff --git a/src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.WriteEntryAsync.LongFile.Tests.cs b/src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.WriteEntryAsync.LongFile.Tests.cs deleted file mode 100644 index 837da5fea212f..0000000000000 --- a/src/libraries/System.Formats.Tar/tests/TarWriter/TarWriter.WriteEntryAsync.LongFile.Tests.cs +++ /dev/null @@ -1,82 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Collections.Generic; -using System.IO; -using System.Threading.Tasks; -using Xunit; - -namespace System.Formats.Tar.Tests -{ - [OuterLoop] - [Collection(nameof(DisableParallelization))] // don't create multiple large files at the same time - public class TarWriter_WriteEntryAsync_LongFile_Tests : TarTestsBase - { - public static IEnumerable WriteEntry_LongFileSize_TheoryDataAsync() - => TarWriter_WriteEntry_LongFile_Tests.WriteEntry_LongFileSize_TheoryData(); - - [Theory] - [MemberData(nameof(WriteEntry_LongFileSize_TheoryDataAsync))] - [SkipOnPlatform(TestPlatforms.iOS | TestPlatforms.tvOS | TestPlatforms.Android | TestPlatforms.Browser, "Needs too much disk space.")] - public async Task WriteEntry_LongFileSizeAsync(TarEntryFormat entryFormat, long size, bool unseekableStream) - { - // Write archive with a 8 Gb long entry. - await using FileStream tarFile = File.Open(GetTestFilePath(), new FileStreamOptions { Access = FileAccess.ReadWrite, Mode = FileMode.Create, Options = FileOptions.DeleteOnClose }); - Stream s = unseekableStream ? new WrappedStream(tarFile, tarFile.CanRead, tarFile.CanWrite, canSeek: false) : tarFile; - - await using (TarWriter writer = new(s, leaveOpen: true)) - { - TarEntry writeEntry = InvokeTarEntryCreationConstructor(entryFormat, entryFormat is TarEntryFormat.V7 ? TarEntryType.V7RegularFile : TarEntryType.RegularFile, "foo"); - writeEntry.DataStream = new SimulatedDataStream(size); - await writer.WriteEntryAsync(writeEntry); - } - - tarFile.Position = 0; - - // Read the archive back. - await using TarReader reader = new TarReader(s); - TarEntry entry = await reader.GetNextEntryAsync(); - Assert.Equal(size, entry.Length); - - Stream dataStream = entry.DataStream; - Assert.Equal(size, dataStream.Length); - Assert.Equal(0, dataStream.Position); - - ReadOnlyMemory dummyData = SimulatedDataStream.DummyData; - - // Read the first bytes. - byte[] buffer = new byte[dummyData.Length]; - Assert.Equal(buffer.Length, dataStream.Read(buffer)); - AssertExtensions.SequenceEqual(dummyData.Span, buffer); - Assert.Equal(0, dataStream.ReadByte()); // check next byte is correct. - buffer.AsSpan().Clear(); - - // Read the last bytes. - long dummyDataOffset = size - dummyData.Length - 1; - if (dataStream.CanSeek) - { - Assert.False(unseekableStream); - dataStream.Seek(dummyDataOffset, SeekOrigin.Begin); - } - else - { - Assert.True(unseekableStream); - Memory seekBuffer = new byte[4_096]; - - while (dataStream.Position < dummyDataOffset) - { - int bufSize = (int)Math.Min(seekBuffer.Length, dummyDataOffset - dataStream.Position); - int res = await dataStream.ReadAsync(seekBuffer.Slice(0, bufSize)); - Assert.True(res > 0, "Unseekable stream finished before expected - Something went very wrong"); - } - } - - Assert.Equal(0, dataStream.ReadByte()); // check previous byte is correct. - Assert.Equal(buffer.Length, dataStream.Read(buffer)); - AssertExtensions.SequenceEqual(dummyData.Span, buffer); - Assert.Equal(size, dataStream.Position); - - Assert.Null(await reader.GetNextEntryAsync()); - } - } -}