You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

KtorLineBufferedSocketTest.kt 7.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. package com.dmdirc.ktirc.io
  2. import kotlinx.coroutines.GlobalScope
  3. import kotlinx.coroutines.async
  4. import kotlinx.coroutines.launch
  5. import kotlinx.coroutines.runBlocking
  6. import org.junit.jupiter.api.Assertions.assertEquals
  7. import org.junit.jupiter.api.Assertions.assertNotNull
  8. import org.junit.jupiter.api.Test
  9. import org.junit.jupiter.api.parallel.Execution
  10. import org.junit.jupiter.api.parallel.ExecutionMode
  11. import java.net.ServerSocket
  12. @Execution(ExecutionMode.SAME_THREAD)
  13. internal class KtorLineBufferedSocketTest {
  14. @Test
  15. fun `KtorLineBufferedSocket can connect to a server`() = runBlocking {
  16. ServerSocket(12321).use { serverSocket ->
  17. val socket = KtorLineBufferedSocket("localhost", 12321)
  18. val clientSocketAsync = GlobalScope.async { serverSocket.accept() }
  19. socket.connect()
  20. assertNotNull(clientSocketAsync.await())
  21. }
  22. }
  23. @Test
  24. fun `KtorLineBufferedSocket can send a whole byte array to a server`() = runBlocking {
  25. ServerSocket(12321).use { serverSocket ->
  26. val socket = KtorLineBufferedSocket("localhost", 12321)
  27. val clientBytesAsync = GlobalScope.async {
  28. ByteArray(13).apply {
  29. serverSocket.accept().getInputStream().read(this)
  30. }
  31. }
  32. socket.connect()
  33. socket.sendLine("Hello World".toByteArray())
  34. val bytes = clientBytesAsync.await()
  35. assertNotNull(bytes)
  36. assertEquals("Hello World\r\n", String(bytes))
  37. }
  38. }
  39. @Test
  40. fun `KtorLineBufferedSocket can send a string to a server`() = runBlocking {
  41. ServerSocket(12321).use { serverSocket ->
  42. val socket = KtorLineBufferedSocket("localhost", 12321)
  43. val clientBytesAsync = GlobalScope.async {
  44. ByteArray(13).apply {
  45. serverSocket.accept().getInputStream().read(this)
  46. }
  47. }
  48. socket.connect()
  49. socket.sendLine("Hello World")
  50. val bytes = clientBytesAsync.await()
  51. assertNotNull(bytes)
  52. assertEquals("Hello World\r\n", String(bytes))
  53. }
  54. }
  55. @Test
  56. fun `KtorLineBufferedSocket can send a partial byte array to a server`() = runBlocking {
  57. ServerSocket(12321).use { serverSocket ->
  58. val socket = KtorLineBufferedSocket("localhost", 12321)
  59. val clientBytesAsync = GlobalScope.async {
  60. ByteArray(7).apply {
  61. serverSocket.accept().getInputStream().read(this)
  62. }
  63. }
  64. socket.connect()
  65. socket.sendLine("Hello World".toByteArray(), 6, 5)
  66. val bytes = clientBytesAsync.await()
  67. assertNotNull(bytes)
  68. assertEquals("World\r\n", String(bytes))
  69. }
  70. }
  71. @Test
  72. fun `KtorLineBufferedSocket can receive a line of CRLF delimited text`() = runBlocking {
  73. ServerSocket(12321).use { serverSocket ->
  74. val socket = KtorLineBufferedSocket("localhost", 12321)
  75. GlobalScope.launch {
  76. serverSocket.accept().getOutputStream().write("Hi there\r\n".toByteArray())
  77. }
  78. socket.connect()
  79. assertEquals("Hi there", String(socket.readLines(GlobalScope).receive()))
  80. }
  81. }
  82. @Test
  83. fun `KtorLineBufferedSocket can receive a line of LF delimited text`() = runBlocking {
  84. ServerSocket(12321).use { serverSocket ->
  85. val socket = KtorLineBufferedSocket("localhost", 12321)
  86. GlobalScope.launch {
  87. serverSocket.accept().getOutputStream().write("Hi there\n".toByteArray())
  88. }
  89. socket.connect()
  90. assertEquals("Hi there", String(socket.readLines(GlobalScope).receive()))
  91. }
  92. }
  93. @Test
  94. fun `KtorLineBufferedSocket can receive multiple lines of text in one packet`() = runBlocking {
  95. ServerSocket(12321).use { serverSocket ->
  96. val socket = KtorLineBufferedSocket("localhost", 12321)
  97. GlobalScope.launch {
  98. serverSocket.accept().getOutputStream().write("Hi there\nThis is a test\r".toByteArray())
  99. }
  100. socket.connect()
  101. val lineProducer = socket.readLines(GlobalScope)
  102. assertEquals("Hi there", String(lineProducer.receive()))
  103. assertEquals("This is a test", String(lineProducer.receive()))
  104. }
  105. }
  106. @Test
  107. fun `KtorLineBufferedSocket can receive one line of text over multiple packets`() = runBlocking {
  108. ServerSocket(12321).use { serverSocket ->
  109. val socket = KtorLineBufferedSocket("localhost", 12321)
  110. GlobalScope.launch {
  111. with(serverSocket.accept().getOutputStream()) {
  112. write("Hi".toByteArray())
  113. flush()
  114. write(" t".toByteArray())
  115. flush()
  116. write("here\r\n".toByteArray())
  117. flush()
  118. }
  119. }
  120. socket.connect()
  121. val lineProducer = socket.readLines(GlobalScope)
  122. assertEquals("Hi there", String(lineProducer.receive()))
  123. }
  124. }
  125. @Test
  126. fun `KtorLineBufferedSocket returns from readLines when socket is closed`() = runBlocking {
  127. ServerSocket(12321).use { serverSocket ->
  128. val socket = KtorLineBufferedSocket("localhost", 12321)
  129. GlobalScope.launch {
  130. with(serverSocket.accept()) {
  131. getOutputStream().write("Hi there\r\n".toByteArray())
  132. close()
  133. }
  134. }
  135. socket.connect()
  136. val lineProducer = socket.readLines(GlobalScope)
  137. assertEquals("Hi there", String(lineProducer.receive()))
  138. }
  139. }
  140. @Test
  141. fun `KtorLineBufferedSocket disconnects from server`() = runBlocking {
  142. ServerSocket(12321).use { serverSocket ->
  143. val socket = KtorLineBufferedSocket("localhost", 12321)
  144. val clientSocketAsync = GlobalScope.async { serverSocket.accept() }
  145. socket.connect()
  146. socket.disconnect()
  147. assertEquals(-1, clientSocketAsync.await().getInputStream().read()) { "Server socket should EOF after KtorLineBufferedSocket disconnects" }
  148. }
  149. }
  150. @Test
  151. fun `KtorLineBufferedSocket reports sent lines to debug receiver`() = runBlocking {
  152. ServerSocket(12321).use { serverSocket ->
  153. val socket = KtorLineBufferedSocket("localhost", 12321)
  154. GlobalScope.launch {
  155. serverSocket.accept()
  156. }
  157. var received = ""
  158. socket.debugReceiver = { str -> received = str }
  159. socket.connect()
  160. socket.sendLine("Test 123")
  161. assertEquals(">>> Test 123", received)
  162. }
  163. }
  164. @Test
  165. fun `KtorLineBufferedSocket reports received lines to debug receiver`() = runBlocking {
  166. ServerSocket(12321).use { serverSocket ->
  167. val socket = KtorLineBufferedSocket("localhost", 12321)
  168. GlobalScope.launch {
  169. with(serverSocket.accept()) {
  170. getOutputStream().write("Hi there\r\n".toByteArray())
  171. close()
  172. }
  173. }
  174. var received = ""
  175. socket.debugReceiver = { str -> received = str }
  176. socket.connect()
  177. socket.readLines(this).receive()
  178. assertEquals("<<< Hi there", received)
  179. }
  180. }
  181. }