ZlibTests.swift 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /*
  2. * Copyright 2024, gRPC Authors All rights reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. import GRPCCore
  17. import NIOCore
  18. import XCTest
  19. @testable import GRPCHTTP2Core
  20. final class ZlibTests: XCTestCase {
  21. private let text = """
  22. Here's to the crazy ones. The misfits. The rebels. The troublemakers. The round pegs in the
  23. square holes. The ones who see things differently. They're not fond of rules. And they have
  24. no respect for the status quo. You can quote them, disagree with them, glorify or vilify them.
  25. About the only thing you can't do is ignore them. Because they change things. They push the
  26. human race forward. And while some may see them as the crazy ones, we see genius. Because
  27. the people who are crazy enough to think they can change the world, are the ones who do.
  28. """
  29. private func compress(_ input: [UInt8], method: Zlib.Method) throws -> ByteBuffer {
  30. let compressor = Zlib.Compressor(method: method)
  31. defer { compressor.end() }
  32. var buffer = ByteBuffer()
  33. try compressor.compress(input, into: &buffer)
  34. return buffer
  35. }
  36. private func decompress(
  37. _ input: ByteBuffer,
  38. method: Zlib.Method,
  39. limit: Int = .max
  40. ) throws -> [UInt8] {
  41. let decompressor = Zlib.Decompressor(method: method)
  42. defer { decompressor.end() }
  43. var input = input
  44. return try decompressor.decompress(&input, limit: limit)
  45. }
  46. func testRoundTripUsingDeflate() throws {
  47. let original = Array(self.text.utf8)
  48. let compressed = try self.compress(original, method: .deflate)
  49. let decompressed = try self.decompress(compressed, method: .deflate)
  50. XCTAssertEqual(original, decompressed)
  51. }
  52. func testRoundTripUsingGzip() throws {
  53. let original = Array(self.text.utf8)
  54. let compressed = try self.compress(original, method: .gzip)
  55. let decompressed = try self.decompress(compressed, method: .gzip)
  56. XCTAssertEqual(original, decompressed)
  57. }
  58. func testRepeatedCompresses() throws {
  59. let original = Array(self.text.utf8)
  60. let compressor = Zlib.Compressor(method: .deflate)
  61. defer { compressor.end() }
  62. var compressed = ByteBuffer()
  63. let bytesWritten = try compressor.compress(original, into: &compressed)
  64. XCTAssertEqual(compressed.readableBytes, bytesWritten)
  65. for _ in 0 ..< 10 {
  66. var buffer = ByteBuffer()
  67. try compressor.compress(original, into: &buffer)
  68. XCTAssertEqual(compressed, buffer)
  69. }
  70. }
  71. func testRepeatedDecompresses() throws {
  72. let original = Array(self.text.utf8)
  73. let decompressor = Zlib.Decompressor(method: .deflate)
  74. defer { decompressor.end() }
  75. let compressed = try self.compress(original, method: .deflate)
  76. var input = compressed
  77. let decompressed = try decompressor.decompress(&input, limit: .max)
  78. for _ in 0 ..< 10 {
  79. var input = compressed
  80. let buffer = try decompressor.decompress(&input, limit: .max)
  81. XCTAssertEqual(buffer, decompressed)
  82. }
  83. }
  84. func testDecompressGrowsOutputBuffer() throws {
  85. // This compresses down to 17 bytes with deflate. The decompressor sets the output buffer to
  86. // be double the size of the input buffer and will grow it if necessary. This test exercises
  87. // that path.
  88. let original = [UInt8](repeating: 0, count: 1024)
  89. let compressed = try self.compress(original, method: .deflate)
  90. let decompressed = try self.decompress(compressed, method: .deflate)
  91. XCTAssertEqual(decompressed, original)
  92. }
  93. func testDecompressRespectsLimit() throws {
  94. let compressed = try self.compress(Array(self.text.utf8), method: .deflate)
  95. let limit = compressed.readableBytes - 1
  96. XCTAssertThrowsError(
  97. ofType: RPCError.self,
  98. try self.decompress(compressed, method: .deflate, limit: limit)
  99. ) { error in
  100. XCTAssertEqual(error.code, .resourceExhausted)
  101. }
  102. }
  103. func testCompressAppendsToBuffer() throws {
  104. let compressor = Zlib.Compressor(method: .deflate)
  105. defer { compressor.end() }
  106. var buffer = ByteBuffer()
  107. try compressor.compress(Array(repeating: 0, count: 1024), into: &buffer)
  108. // Should be some readable bytes.
  109. let byteCount1 = buffer.readableBytes
  110. XCTAssertGreaterThan(byteCount1, 0)
  111. try compressor.compress(Array(repeating: 1, count: 1024), into: &buffer)
  112. // Should be some readable bytes.
  113. let byteCount2 = buffer.readableBytes
  114. XCTAssertGreaterThan(byteCount2, byteCount1)
  115. let slice1 = buffer.readSlice(length: byteCount1)!
  116. let decompressed1 = try self.decompress(slice1, method: .deflate)
  117. XCTAssertEqual(decompressed1, Array(repeating: 0, count: 1024))
  118. let decompressed2 = try self.decompress(buffer, method: .deflate)
  119. XCTAssertEqual(decompressed2, Array(repeating: 1, count: 1024))
  120. }
  121. }