@@ -64,6 +64,18 @@ extension IntegrationSuite {
6464 }
6565 }
6666
67+ final class DiscardingWriter : @unchecked Sendable , Writer {
68+ var count : Int = 0
69+
70+ func write( _ data: Data ) throws {
71+ count += data. count
72+ }
73+
74+ func close( ) throws {
75+ return
76+ }
77+ }
78+
6779 final class BufferWriter : Writer {
6880 // `data` isn't used concurrently.
6981 nonisolated ( unsafe) var data = Data ( )
@@ -1027,4 +1039,67 @@ extension IntegrationSuite {
10271039 try " hello " . write ( to: dir. appendingPathComponent ( " hi.txt " ) , atomically: true , encoding: . utf8)
10281040 return dir
10291041 }
1042+
1043+ func testLargeStdioOutput( ) async throws {
1044+ let id = " test-large-stdout-stderr-output "
1045+
1046+ let bs = try await bootstrap ( id)
1047+ let container = try LinuxContainer ( id, rootfs: bs. rootfs, vmm: bs. vmm) { config in
1048+ config. process. arguments = [ " /bin/sleep " , " 1000 " ]
1049+ config. bootlog = bs. bootlog
1050+ }
1051+
1052+ do {
1053+ try await container. create ( )
1054+ try await container. start ( )
1055+
1056+ let stdoutBuffer = DiscardingWriter ( )
1057+ let stderrBuffer = DiscardingWriter ( )
1058+
1059+ let exec = try await container. exec ( " large-output " ) { config in
1060+ config. arguments = [
1061+ " sh " ,
1062+ " -c " ,
1063+ """
1064+ dd if=/dev/zero bs=1M count=250 status=none && \
1065+ dd if=/dev/zero bs=1M count=250 status=none >&2
1066+ """ ,
1067+ ]
1068+ config. stdout = stdoutBuffer
1069+ config. stderr = stderrBuffer
1070+ }
1071+
1072+ let started = CFAbsoluteTimeGetCurrent ( )
1073+
1074+ try await exec. start ( )
1075+ let status = try await exec. wait ( )
1076+
1077+ let lasted = CFAbsoluteTimeGetCurrent ( ) - started
1078+ print ( " Test \( id) finished process ingesting stdio in \( lasted) " )
1079+
1080+ guard status. exitCode == 0 else {
1081+ throw IntegrationError . assert ( msg: " exec process status \( status) != 0 " )
1082+ }
1083+
1084+ try await exec. delete ( )
1085+
1086+ let expectedSize = 250 * 1024 * 1024
1087+ guard stdoutBuffer. count == expectedSize else {
1088+ throw IntegrationError . assert (
1089+ msg: " stdout size \( stdoutBuffer. count) != expected \( expectedSize) " )
1090+ }
1091+
1092+ guard stderrBuffer. count == expectedSize else {
1093+ throw IntegrationError . assert (
1094+ msg: " stderr size \( stderrBuffer. count) != expected \( expectedSize) " )
1095+ }
1096+
1097+ try await container. kill ( SIGKILL)
1098+ try await container. wait ( )
1099+ try await container. stop ( )
1100+ } catch {
1101+ try ? await container. stop ( )
1102+ throw error
1103+ }
1104+ }
10301105}
0 commit comments