Skip to content

Commit 48066b1

Browse files
committed
Move large data allocation tests into separate serialized suite
1 parent 5ceae50 commit 48066b1

File tree

2 files changed

+110
-98
lines changed

2 files changed

+110
-98
lines changed

Tests/FoundationEssentialsTests/DataIOTests.swift

Lines changed: 40 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,20 @@ import Testing
1818
@testable import FoundationEssentials
1919
#endif // FOUNDATION_FRAMEWORK
2020

21+
private func generateTestData(count: Int = 16_777_216) -> Data {
22+
// Set a few bytes so we're sure to not be all zeros
23+
let buf = UnsafeMutableBufferPointer<UInt8>.allocate(capacity: count)
24+
for i in 0..<15 {
25+
for j in 0..<128 {
26+
buf[j * 1024 + i] = UInt8.random(in: 1..<42)
27+
}
28+
}
29+
30+
return Data(bytesNoCopy: buf.baseAddress!, count: count, deallocator: .custom({ ptr, _ in
31+
ptr.deallocate()
32+
}))
33+
}
34+
2135
@Suite("Data I/O")
2236
private final class DataIOTests {
2337

@@ -29,20 +43,6 @@ private final class DataIOTests {
2943
// Generate a random file name
3044
url = URL.temporaryDirectory.appendingPathComponent("testfile-\(UUID().uuidString)")
3145
}
32-
33-
func generateTestData(count: Int = 16_777_216) -> Data {
34-
// Set a few bytes so we're sure to not be all zeros
35-
let buf = UnsafeMutableBufferPointer<UInt8>.allocate(capacity: count)
36-
for i in 0..<15 {
37-
for j in 0..<128 {
38-
buf[j * 1024 + i] = UInt8.random(in: 1..<42)
39-
}
40-
}
41-
42-
return Data(bytesNoCopy: buf.baseAddress!, count: count, deallocator: .custom({ ptr, _ in
43-
ptr.deallocate()
44-
}))
45-
}
4646

4747
func writeAndVerifyTestData(to url: URL, writeOptions: Data.WritingOptions = [], readOptions: Data.ReadingOptions = [], sourceLocation: SourceLocation = #_sourceLocation) throws {
4848
let data = generateTestData()
@@ -166,27 +166,6 @@ private final class DataIOTests {
166166
}
167167
#endif
168168

169-
#if !os(watchOS)
170-
func largeFile() throws {
171-
// More than 2 GB
172-
let size = 0x80010000
173-
174-
let data = generateTestData(count: size)
175-
176-
try data.write(to: url)
177-
let read = try Data(contentsOf: url, options: .mappedIfSafe)
178-
179-
// No need to compare the contents, but do compare the size
180-
#expect(data.count == read.count)
181-
182-
#if FOUNDATION_FRAMEWORK
183-
// Try the NSData path
184-
let readNS = try NSData(contentsOf: url, options: .mappedIfSafe) as Data
185-
#expect(data.count == readNS.count)
186-
#endif
187-
}
188-
#endif
189-
190169
#if os(Linux) || os(Windows)
191170
@Test
192171
#else
@@ -216,3 +195,29 @@ private final class DataIOTests {
216195
}
217196
}
218197

198+
extension LargeDataTests {
199+
// This test is placed in the LargeDataTests suite since it allocates an extremely large amount of memory for some devices
200+
#if !os(watchOS)
201+
@Test func readLargeFile() throws {
202+
let url = URL.temporaryDirectory.appendingPathComponent("testfile-\(UUID().uuidString)")
203+
defer { try? FileManager.default.removeItem(at: url) }
204+
// More than 2 GB
205+
let size = 0x80010000
206+
207+
let data = generateTestData(count: size)
208+
209+
try data.write(to: url)
210+
let read = try Data(contentsOf: url, options: .mappedIfSafe)
211+
212+
// No need to compare the contents, but do compare the size
213+
#expect(data.count == read.count)
214+
215+
#if FOUNDATION_FRAMEWORK
216+
// Try the NSData path
217+
let readNS = try NSData(contentsOf: url, options: .mappedIfSafe) as Data
218+
#expect(data.count == readNS.count)
219+
#endif
220+
}
221+
#endif
222+
}
223+

Tests/FoundationEssentialsTests/DataTests.swift

Lines changed: 70 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1669,23 +1669,6 @@ private final class DataTests {
16691669
#expect(span[span.indices.last!] == .max)
16701670
}
16711671

1672-
@available(FoundationSpan 6.2, *)
1673-
@Test func largeSliceDataSpan() throws {
1674-
#if _pointerBitWidth(_64)
1675-
let count = Int(Int32.max)
1676-
#elseif _pointerBitWidth(_32)
1677-
let count = Int(Int16.max)
1678-
#else
1679-
#error("This test needs updating")
1680-
#endif
1681-
1682-
let source = Data(repeating: 0, count: count).dropFirst()
1683-
#expect(source.startIndex != 0)
1684-
let span = source.span
1685-
let isEmpty = span.isEmpty
1686-
#expect(!isEmpty)
1687-
}
1688-
16891672
@available(FoundationSpan 6.2, *)
16901673
@Test func inlineDataMutableSpan() throws {
16911674
#if !canImport(Darwin) || FOUNDATION_FRAMEWORK
@@ -1695,7 +1678,7 @@ private final class DataTests {
16951678
#expect(isEmpty)
16961679

16971680
source.append(contentsOf: [1, 2, 3])
1698-
var count = source.count
1681+
let count = source.count
16991682
span = source.mutableSpan
17001683
let indices = span.indices
17011684
let i = try #require(indices.randomElement())
@@ -1724,29 +1707,6 @@ private final class DataTests {
17241707
#endif
17251708
}
17261709

1727-
@available(FoundationSpan 6.2, *)
1728-
@Test func largeSliceDataMutableSpan() throws {
1729-
#if _pointerBitWidth(_64)
1730-
var count = Int(Int32.max)
1731-
#elseif _pointerBitWidth(_32)
1732-
var count = Int(Int16.max)
1733-
#else
1734-
#error("This test needs updating")
1735-
#endif
1736-
1737-
#if !canImport(Darwin) || FOUNDATION_FRAMEWORK
1738-
var source = Data(repeating: 0, count: count).dropFirst()
1739-
#expect(source.startIndex != 0)
1740-
count = source.count
1741-
var span = source.mutableSpan
1742-
#expect(span.count == count)
1743-
let i = try #require(span.indices.dropFirst().randomElement())
1744-
span[i] = .max
1745-
#expect(source[i] == 0)
1746-
#expect(source[i+1] == .max)
1747-
#endif
1748-
}
1749-
17501710
@available(FoundationSpan 6.2, *)
17511711
@Test func inlineDataMutableRawSpan() throws {
17521712
var source = Data()
@@ -1781,28 +1741,6 @@ private final class DataTests {
17811741
#expect(source[i] == .max)
17821742
}
17831743

1784-
@available(FoundationSpan 6.2, *)
1785-
@Test func largeSliceDataMutableRawSpan() throws {
1786-
#if _pointerBitWidth(_64)
1787-
var count = Int(Int32.max)
1788-
#elseif _pointerBitWidth(_32)
1789-
var count = Int(Int16.max)
1790-
#else
1791-
#error("This test needs updating")
1792-
#endif
1793-
1794-
var source = Data(repeating: 0, count: count).dropFirst()
1795-
#expect(source.startIndex != 0)
1796-
count = source.count
1797-
var span = source.mutableBytes
1798-
let byteCount = span.byteCount
1799-
#expect(byteCount == count)
1800-
let i = try #require(span.byteOffsets.dropFirst().randomElement())
1801-
span.storeBytes(of: -1, toByteOffset: i, as: Int8.self)
1802-
#expect(source[i] == 0)
1803-
#expect(source[i+1] == .max)
1804-
}
1805-
18061744
#if FOUNDATION_EXIT_TESTS
18071745
@Test func bounding_failure_subdata() async {
18081746
await #expect(processExitsWith: .failure) {
@@ -2443,3 +2381,72 @@ extension DataTests {
24432381
}
24442382
}
24452383
#endif
2384+
2385+
// These tests require allocating an extremely large amount of data and are serialized to prevent the test runner from using all available memory at once
2386+
@Suite("Large Data Tests", .serialized)
2387+
struct LargeDataTests {
2388+
@Test
2389+
@available(FoundationSpan 6.2, *)
2390+
func largeSliceDataSpan() throws {
2391+
#if _pointerBitWidth(_64)
2392+
let count = Int(Int32.max)
2393+
#elseif _pointerBitWidth(_32)
2394+
let count = Int(Int16.max)
2395+
#else
2396+
#error("This test needs updating")
2397+
#endif
2398+
2399+
let source = Data(repeating: 0, count: count).dropFirst()
2400+
#expect(source.startIndex != 0)
2401+
let span = source.span
2402+
let isEmpty = span.isEmpty
2403+
#expect(!isEmpty)
2404+
}
2405+
2406+
@Test
2407+
@available(FoundationSpan 6.2, *)
2408+
func largeSliceDataMutableSpan() throws {
2409+
#if _pointerBitWidth(_64)
2410+
var count = Int(Int32.max)
2411+
#elseif _pointerBitWidth(_32)
2412+
var count = Int(Int16.max)
2413+
#else
2414+
#error("This test needs updating")
2415+
#endif
2416+
2417+
#if !canImport(Darwin) || FOUNDATION_FRAMEWORK
2418+
var source = Data(repeating: 0, count: count).dropFirst()
2419+
#expect(source.startIndex != 0)
2420+
count = source.count
2421+
var span = source.mutableSpan
2422+
#expect(span.count == count)
2423+
let i = try #require(span.indices.dropFirst().randomElement())
2424+
span[i] = .max
2425+
#expect(source[i] == 0)
2426+
#expect(source[i+1] == .max)
2427+
#endif
2428+
}
2429+
2430+
@Test
2431+
@available(FoundationSpan 6.2, *)
2432+
func largeSliceDataMutableRawSpan() throws {
2433+
#if _pointerBitWidth(_64)
2434+
var count = Int(Int32.max)
2435+
#elseif _pointerBitWidth(_32)
2436+
var count = Int(Int16.max)
2437+
#else
2438+
#error("This test needs updating")
2439+
#endif
2440+
2441+
var source = Data(repeating: 0, count: count).dropFirst()
2442+
#expect(source.startIndex != 0)
2443+
count = source.count
2444+
var span = source.mutableBytes
2445+
let byteCount = span.byteCount
2446+
#expect(byteCount == count)
2447+
let i = try #require(span.byteOffsets.dropFirst().randomElement())
2448+
span.storeBytes(of: -1, toByteOffset: i, as: Int8.self)
2449+
#expect(source[i] == 0)
2450+
#expect(source[i+1] == .max)
2451+
}
2452+
}

0 commit comments

Comments
 (0)