1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.apache.thrift.test
20
21 import com.github.ajalt.clikt.core.CliktCommand
22 import com.github.ajalt.clikt.parameters.options.default
23 import com.github.ajalt.clikt.parameters.options.flag
24 import com.github.ajalt.clikt.parameters.options.option
25 import com.github.ajalt.clikt.parameters.types.enum
26 import com.github.ajalt.clikt.parameters.types.int
27 import java.nio.ByteBuffer
28 import kotlin.math.abs
29 import kotlin.system.exitProcess
30 import kotlinx.coroutines.runBlocking
31 import org.apache.thrift.TApplicationException
32 import org.apache.thrift.TException
33 import org.apache.thrift.TSerializer
34 import org.apache.thrift.async.TAsyncClientManager
35 import org.apache.thrift.protocol.TBinaryProtocol
36 import org.apache.thrift.protocol.TCompactProtocol
37 import org.apache.thrift.protocol.TJSONProtocol
38 import org.apache.thrift.protocol.TProtocol
39 import org.apache.thrift.protocol.TSimpleJSONProtocol
40 import org.apache.thrift.transport.TNonblockingSocket
41 import org.apache.thrift.transport.TNonblockingTransport
42 import org.apache.thrift.transport.TTransport
43 import thrift.test.Insanity
44 import thrift.test.Numberz
45 import thrift.test.SecondServiceClient
46 import thrift.test.ThriftTestClient
47 import thrift.test.Xception
48 import thrift.test.Xception2
49 import thrift.test.Xtruct
50 import thrift.test.Xtruct2
51
52 /**
53 * Test Java client for thrift. Essentially just a copy of the C++ version, this makes a variety of
54 * requests to enable testing for both performance and correctness of the output.
55 */
56 const val ERR_BASETYPES = 1
57 const val ERR_STRUCTS = 2
58 const val ERR_CONTAINERS = 4
59 const val ERR_EXCEPTIONS = 8
60 const val ERR_PROTOCOLS = 16
61 const val ERR_UNKNOWN = 64
62
63 enum class ProtocolType(val key: String) {
64 Binary("binary"),
65 Multi("multi"),
66 Json("json"),
67 MultiJson("multij"),
68 Compact("compact"),
69 MultiCompact("multic")
70 }
71
72 enum class TransportType(val key: String) {
73 Buffered("buffered"),
74 Framed("framed"),
75 FastFramed("fastframed"),
76 Http("http")
77 }
78
79 class TestClient : CliktCommand() {
80 private val host: String by
81 option(help = "The cross test host to connect to").default("localhost")
82 private val port: Int by option(help = "The cross test port to connect to").int().default(9090)
83 private val numTests: Int by
84 option("--testloops", "--n", help = "Number of runs in this test").int().default(1)
85 private val protocolType: ProtocolType by
86 option("--protocol", help = "Protocol type")
<lambda>null87 .enum<ProtocolType> { it.key }
88 .default(ProtocolType.Binary)
89 private val transportType: TransportType by
90 option("--transport", help = "Transport type")
<lambda>null91 .enum<TransportType> { it.key }
92 .default(TransportType.Buffered)
93 private val useHttpClient: Boolean by
94 option("--client", help = "Use http client").flag(default = false)
95 private val useSSL: Boolean by
96 option("--ssl", help = "Use SSL for encrypted transport").flag(default = false)
97 private val useZlib: Boolean by
98 option("--zlib", help = "Use zlib wrapper for compressed transport").flag(default = false)
99 private val socketTimeout: Int by
100 option("--timeout", help = "Socket timeout").int().default(1000)
101
createProtocolnull102 private fun createProtocol(transport: TTransport): TProtocol =
103 when (protocolType) {
104 ProtocolType.Binary, ProtocolType.Multi -> TBinaryProtocol(transport)
105 ProtocolType.Compact, ProtocolType.MultiCompact -> TCompactProtocol(transport)
106 ProtocolType.Json, ProtocolType.MultiJson -> TJSONProtocol(transport)
107 }
108
createTransportnull109 private fun createTransport(): TNonblockingTransport =
110 when (transportType) {
111 TransportType.Framed -> TNonblockingSocket(host, port, socketTimeout)
112 else ->
113 throw UnsupportedOperationException(
114 "only frame transport type is supported for now, got $transportType"
115 )
116 }
117
118 private val clientManager = TAsyncClientManager()
119
createClientnull120 private fun createClient(): ThriftTestClient =
121 ThriftTestClient({ createProtocol(it) }, clientManager, createTransport())
122
createSecondServiceClientnull123 private fun createSecondServiceClient(): SecondServiceClient =
124 SecondServiceClient({ createProtocol(it) }, clientManager, createTransport())
125
<lambda>null126 override fun run() = runBlocking {
127 var testClient = createClient()
128 val insane = Insanity()
129 var timeMin: Long = 0
130 var timeMax: Long = 0
131 var timeTot: Long = 0
132 var returnCode = 0
133 for (test in 0 until numTests) {
134 try {
135 /** CONNECT TEST */
136 /** CONNECT TEST */
137 // if (!transport.isOpen) {
138 // try {
139 // transport.open()
140 // } catch (ttx: TTransportException) {
141 // ttx.printStackTrace()
142 // println("Connect failed: " + ttx.message)
143 // exitProcess(ERR_UNKNOWN)
144 // }
145 // }
146 println("Test #${test + 1}, connect $host:$port")
147
148 val start = System.nanoTime()
149 /** VOID TEST */
150 /** VOID TEST */
151 returnCode = testClient.voidTest(returnCode)
152 /** STRING TEST */
153 /** STRING TEST */
154 returnCode = testClient.stringTest(returnCode)
155 /** Multiplexed test */
156 /** Multiplexed test */
157 returnCode = multiplexTest(returnCode)
158 /** BYTE TEST */
159 /** BYTE TEST */
160 returnCode = testClient.byteTest(returnCode)
161 /** I32 TEST */
162 /** I32 TEST */
163 returnCode = testClient.i32Test(returnCode)
164 /** I64 TEST */
165 /** I64 TEST */
166 returnCode = testClient.i64Test(returnCode)
167 /** DOUBLE TEST */
168 /** DOUBLE TEST */
169 returnCode = testClient.doubleTest(returnCode)
170 /** BINARY TEST */
171 /** BINARY TEST */
172 returnCode = testClient.binaryTest(returnCode)
173 /** STRUCT TEST */
174 /** STRUCT TEST */
175 val pair = testClient.structTest(returnCode)
176 val out = pair.first
177 returnCode = pair.second
178 /** NESTED STRUCT TEST */
179 /** NESTED STRUCT TEST */
180 returnCode = testClient.nestedStructTest(out, returnCode)
181 /** MAP TEST */
182 /** MAP TEST */
183 val testMapParam = (0..4).associateBy { 10 - it }
184 printMap(testMapParam)
185 val testMapResult: Map<Int, Int> = testClient.testMap(testMapParam)
186 printMap(testMapResult)
187 if (testMapParam != testMapResult) {
188 returnCode = returnCode or ERR_CONTAINERS
189 println("*** FAILURE ***\n")
190 }
191 /** STRING MAP TEST */
192 /** STRING MAP TEST */
193 returnCode = testClient.stringMapTest(returnCode)
194 /** SET TEST */
195 /** SET TEST */
196 val setout: MutableSet<Int> = HashSet()
197 for (i in -2..2) {
198 setout.add(i)
199 }
200 val setin: Set<Int> = testClient.testSet(setout)
201 if (setout != setin) {
202 returnCode = returnCode or ERR_CONTAINERS
203 println("*** FAILURE ***\n")
204 }
205 /** LIST TEST */
206 /** LIST TEST */
207 val listout: MutableList<Int> = ArrayList()
208 for (i in -2..2) {
209 listout.add(i)
210 }
211 val listin: List<Int> = testClient.testList(listout)
212 if (listout != listin) {
213 returnCode = returnCode or ERR_CONTAINERS
214 println("*** FAILURE ***\n")
215 }
216 /** ENUM TEST */
217 /** ENUM TEST */
218 returnCode = testClient.enumTest(returnCode)
219 /** TYPEDEF TEST */
220 /** TYPEDEF TEST */
221 returnCode = testClient.typedefTest(returnCode)
222 /** NESTED MAP TEST */
223 /** NESTED MAP TEST */
224 returnCode = testClient.nestedMapTest(returnCode)
225 /** INSANITY TEST */
226 /** INSANITY TEST */
227 var insanityFailed = true
228 try {
229 val hello = Xtruct()
230 hello.string_thing = "Hello2"
231 hello.byte_thing = 2
232 hello.i32_thing = 2
233 hello.i64_thing = 2
234 val goodbye = Xtruct()
235 goodbye.string_thing = "Goodbye4"
236 goodbye.byte_thing = 4.toByte()
237 goodbye.i32_thing = 4
238 goodbye.i64_thing = 4L
239 insane.userMap =
240 HashMap<Numberz, Long>().apply {
241 put(Numberz.EIGHT, 8L)
242 put(Numberz.FIVE, 5L)
243 }
244
245 insane.xtructs =
246 ArrayList<Xtruct>().apply {
247 add(goodbye)
248 add(hello)
249 }
250
251 print("testInsanity()")
252 val whoa: Map<Long, Map<Numberz, Insanity>> = testClient.testInsanity(insane)
253 print(" = {")
254 for (key in whoa.keys) {
255 val `val` = whoa[key]!!
256 print("$key => {")
257 for (k2 in `val`.keys) {
258 val v2 = `val`[k2]
259 print("$k2 => {")
260 val userMap = v2!!.userMap
261 print("{")
262 if (userMap != null) {
263 for (k3 in userMap.keys) {
264 print(k3.toString() + " => " + userMap[k3] + ", ")
265 }
266 }
267 print("}, ")
268 val xtructs = v2.xtructs
269 print("{")
270 if (xtructs != null) {
271 for ((string_thing, byte_thing, i32_thing, i64_thing) in xtructs) {
272 print(
273 "{\"$string_thing\", $byte_thing, $i32_thing, $i64_thing}, "
274 )
275 }
276 }
277 print("}")
278 print("}, ")
279 }
280 print("}, ")
281 }
282 print("}\n")
283 if (whoa.size == 2 && whoa.containsKey(1L) && whoa.containsKey(2L)) {
284 val firstMap = whoa[1L]!!
285 val secondMap = whoa[2L]!!
286 if (firstMap.size == 2 &&
287 firstMap.containsKey(Numberz.TWO) &&
288 firstMap.containsKey(Numberz.THREE) &&
289 secondMap.size == 1 &&
290 secondMap.containsKey(Numberz.SIX) &&
291 insane == firstMap[Numberz.TWO] &&
292 insane == firstMap[Numberz.THREE]
293 ) {
294 val six = secondMap[Numberz.SIX]!!
295 // Cannot use "new Insanity().equals(six)" because as of now,
296 // struct/container
297 // fields with default requiredness have isset=false for local instances
298 // and
299 // yet
300 // received empty values from other languages like C++ have isset=true .
301 if ((six.userMap?.size ?: 0) == 0 && (six.xtructs?.size ?: 0) == 0) {
302 // OK
303 insanityFailed = false
304 }
305 }
306 }
307 } catch (ex: Exception) {
308 returnCode = returnCode or ERR_STRUCTS
309 println("*** FAILURE ***\n")
310 ex.printStackTrace(System.out)
311 insanityFailed = false
312 }
313 if (insanityFailed) {
314 returnCode = returnCode or ERR_STRUCTS
315 println("*** FAILURE ***\n")
316 }
317 /** EXECPTION TEST */
318 /** EXECPTION TEST */
319 val pair2 = exceptionTest(testClient, returnCode)
320 returnCode = pair2.first
321 testClient = pair2.second
322 /** MULTI EXCEPTION TEST */
323 /** MULTI EXCEPTION TEST */
324 val pair3 = multiExceptionTest(testClient, returnCode)
325 returnCode = pair3.first
326 testClient = pair3.second
327 /** ONEWAY TEST */
328 /** ONEWAY TEST */
329 returnCode = testClient.onewayTest(returnCode)
330 val stop = System.nanoTime()
331 val tot = stop - start
332 println("Total time: " + tot / 1000 + "us")
333 if (timeMin == 0L || tot < timeMin) {
334 timeMin = tot
335 }
336 if (tot > timeMax) {
337 timeMax = tot
338 }
339 timeTot += tot
340 // transport.close()
341 } catch (x: Exception) {
342 System.out.printf("*** FAILURE ***\n")
343 x.printStackTrace()
344 returnCode = returnCode or ERR_UNKNOWN
345 }
346 }
347 val timeAvg = timeTot / numTests
348 println("Min time: " + timeMin / 1000 + "us")
349 println("Max time: " + timeMax / 1000 + "us")
350 println("Avg time: " + timeAvg / 1000 + "us")
351 try {
352 val json = TSerializer(TSimpleJSONProtocol.Factory()).toString(insane)
353 println("\nSample TSimpleJSONProtocol output:\n$json")
354 } catch (x: TException) {
355 println("*** FAILURE ***")
356 x.printStackTrace()
357 returnCode = returnCode or ERR_BASETYPES
358 }
359 exitProcess(returnCode)
360 }
361
multiplexTestnull362 private suspend fun multiplexTest(returnCode: Int): Int {
363 var code = returnCode
364 if (protocolType == ProtocolType.Multi ||
365 protocolType == ProtocolType.MultiJson ||
366 protocolType == ProtocolType.MultiCompact
367 ) {
368 val secondClient: SecondServiceClient = createSecondServiceClient()
369 print("secondtestString(\"Test2\")")
370 val s = secondClient.secondtestString("Test2")
371 print(" = \"$s\"\n")
372 if (s != "testString(\"Test2\")") {
373 code = code or ERR_PROTOCOLS
374 println("*** FAILURE ***\n")
375 }
376 }
377 return code
378 }
379
enumTestnull380 private suspend fun ThriftTestClient.enumTest(returnCode: Int): Int {
381 var returnCode1 = returnCode
382 print("testEnum(ONE)")
383 var ret: Numberz = testEnum(Numberz.ONE)
384 print(" = $ret\n")
385 if (ret !== Numberz.ONE) {
386 returnCode1 = returnCode1 or ERR_STRUCTS
387 println("*** FAILURE ***\n")
388 }
389 print("testEnum(TWO)")
390 ret = testEnum(Numberz.TWO)
391 print(" = $ret\n")
392 if (ret !== Numberz.TWO) {
393 returnCode1 = returnCode1 or ERR_STRUCTS
394 println("*** FAILURE ***\n")
395 }
396 print("testEnum(THREE)")
397 ret = testEnum(Numberz.THREE)
398 print(" = $ret\n")
399 if (ret !== Numberz.THREE) {
400 returnCode1 = returnCode1 or ERR_STRUCTS
401 println("*** FAILURE ***\n")
402 }
403 print("testEnum(FIVE)")
404 ret = testEnum(Numberz.FIVE)
405 print(" = $ret\n")
406 if (ret !== Numberz.FIVE) {
407 returnCode1 = returnCode1 or ERR_STRUCTS
408 println("*** FAILURE ***\n")
409 }
410 print("testEnum(EIGHT)")
411 ret = testEnum(Numberz.EIGHT)
412 print(" = $ret\n")
413 if (ret !== Numberz.EIGHT) {
414 returnCode1 = returnCode1 or ERR_STRUCTS
415 println("*** FAILURE ***\n")
416 }
417 return returnCode1
418 }
419
printMapnull420 private fun printMap(testMapParam: Map<Int, Int>) {
421 print("testMap({")
422 var first = true
423 for (key in testMapParam.keys) {
424 if (first) {
425 first = false
426 } else {
427 print(", ")
428 }
429 print(key.toString() + " => " + testMapParam[key])
430 }
431 print("})")
432 }
433
exceptionTestnull434 private suspend fun exceptionTest(
435 testClient: ThriftTestClient,
436 returnCode: Int
437 ): Pair<Int, ThriftTestClient> {
438 var client = testClient
439 var code = returnCode
440 try {
441 print("testClient.testException(\"Xception\") =>")
442 client.testException("Xception")
443 print(" void\n*** FAILURE ***\n")
444 code = code or ERR_EXCEPTIONS
445 } catch (e: Xception) {
446 System.out.printf(" {%d, \"%s\"}\n", e.errorCode, e.message)
447 client = createClient()
448 }
449 try {
450 print("testClient.testException(\"TException\") =>")
451 client.testException("TException")
452 print(" void\n*** FAILURE ***\n")
453 code = code or ERR_EXCEPTIONS
454 } catch (e: TException) {
455 System.out.printf(" {\"%s\"}\n", e.message)
456 client = createClient()
457 }
458 try {
459 print("testClient.testException(\"success\") =>")
460 client.testException("success")
461 print(" void\n")
462 } catch (e: Exception) {
463 System.out.printf(" exception\n*** FAILURE ***\n")
464 code = code or ERR_EXCEPTIONS
465 }
466 return code to client
467 }
468
multiExceptionTestnull469 private suspend fun multiExceptionTest(
470 testClient: ThriftTestClient,
471 returnCode: Int
472 ): Pair<Int, ThriftTestClient> {
473 var client = testClient
474 var code = returnCode
475 try {
476 System.out.printf("testClient.testMultiException(\"Xception\", \"test 1\") =>")
477 client.testMultiException("Xception", "test 1")
478 print(" result\n*** FAILURE ***\n")
479 code = code or ERR_EXCEPTIONS
480 } catch (e: Xception) {
481 System.out.printf(" {%d, \"%s\"}\n", e.errorCode, e.message)
482 client = createClient()
483 }
484 try {
485 System.out.printf("testClient.testMultiException(\"Xception2\", \"test 2\") =>")
486 client.testMultiException("Xception2", "test 2")
487 print(" result\n*** FAILURE ***\n")
488 code = code or ERR_EXCEPTIONS
489 } catch (e: Xception2) {
490 System.out.printf(" {%d, {\"%s\"}}\n", e.errorCode, e.struct_thing!!.string_thing)
491 client = createClient()
492 }
493 try {
494 print("testClient.testMultiException(\"success\", \"test 3\") =>")
495 val result: Xtruct = client.testMultiException("success", "test 3")
496 System.out.printf(" {{\"%s\"}}\n", result.string_thing)
497 } catch (e: Exception) {
498 System.out.printf(" exception\n*** FAILURE ***\n")
499 code = code or ERR_EXCEPTIONS
500 }
501 return code to client
502 }
503 }
504
typedefTestnull505 private suspend fun ThriftTestClient.typedefTest(returnCode: Int): Int {
506 var returnCode1 = returnCode
507 print("testTypedef(309858235082523)")
508 val uid: Long = testTypedef(309858235082523L)
509 print(" = $uid\n")
510 if (uid != 309858235082523L) {
511 returnCode1 = returnCode1 or ERR_BASETYPES
512 println("*** FAILURE ***\n")
513 }
514 return returnCode1
515 }
516
structTestnull517 private suspend fun ThriftTestClient.structTest(returnCode: Int): Pair<Xtruct, Int> {
518 var code = returnCode
519 print("testStruct({\"Zero\", 1, -3, -5})")
520 val out = Xtruct()
521 out.string_thing = "Zero"
522 out.byte_thing = 1.toByte()
523 out.i32_thing = -3
524 out.i64_thing = -5
525 val input: Xtruct = testStruct(out)
526 print(
527 """ = {"${input.string_thing}",${input.byte_thing}, ${input.i32_thing}, ${input.i64_thing}}"""
528 )
529 if (input != out) {
530 code = code or ERR_STRUCTS
531 println("*** FAILURE ***\n")
532 }
533 return out to code
534 }
535
onewayTestnull536 private suspend fun ThriftTestClient.onewayTest(returnCode: Int): Int {
537 var returnCode1 = returnCode
538 print("testOneway(3)...")
539 val startOneway = System.nanoTime()
540 testOneway(3)
541 val onewayElapsedMillis = (System.nanoTime() - startOneway) / 1000000
542 if (onewayElapsedMillis > 200) {
543 println("Oneway test took too long to execute failed: took " + onewayElapsedMillis + "ms")
544 println("oneway calls are 'fire and forget' and therefore should not cause blocking.")
545 println("Some transports (HTTP) have a required response, and typically this failure")
546 println("means the transport response was delayed until after the execution")
547 println("of the RPC. The server should post the transport response immediately and")
548 println("before executing the RPC.")
549 println("*** FAILURE ***")
550 returnCode1 = returnCode1 or ERR_BASETYPES
551 } else {
552 println("Success - fire and forget only took " + onewayElapsedMillis + "ms")
553 }
554 return returnCode1
555 }
556
nestedMapTestnull557 private suspend fun ThriftTestClient.nestedMapTest(returnCode: Int): Int {
558 var returnCode1 = returnCode
559 print("testMapMap(1)")
560 val mm: Map<Int, Map<Int, Int>> = testMapMap(1)
561 print(" = {")
562 for (key in mm.keys) {
563 print("$key => {")
564 val m2 = mm[key]!!
565 for (k2 in m2.keys) {
566 print(k2.toString() + " => " + m2[k2] + ", ")
567 }
568 print("}, ")
569 }
570 print("}\n")
571 if (mm.size != 2 || !mm.containsKey(4) || !mm.containsKey(-4)) {
572 returnCode1 = returnCode1 or ERR_CONTAINERS
573 println("*** FAILURE ***\n")
574 } else {
575 val m1 = mm[4]!!
576 val m2 = mm[-4]!!
577 if (m1[1] != 1 ||
578 m1[2] != 2 ||
579 m1[3] != 3 ||
580 m1[4] != 4 ||
581 m2[-1] != -1 ||
582 m2[-2] != -2 ||
583 m2[-3] != -3 ||
584 m2[-4] != -4
585 ) {
586 returnCode1 = returnCode1 or ERR_CONTAINERS
587 println("*** FAILURE ***\n")
588 }
589 }
590 return returnCode1
591 }
592
stringMapTestnull593 private suspend fun ThriftTestClient.stringMapTest(returnCode: Int): Int {
594 var returnCode1 = returnCode
595 try {
596 val smapout: MutableMap<String, String> = HashMap()
597 smapout["a"] = "2"
598 smapout["b"] = "blah"
599 smapout["some"] = "thing"
600 var first = true
601 for (key in smapout.keys) {
602 if (first) {
603 first = false
604 } else {
605 print(", ")
606 }
607 print(key + " => " + smapout[key])
608 }
609 print("})")
610 val smapin: Map<String, String> = testStringMap(smapout)
611 print(" = {")
612 first = true
613 for (key in smapin.keys) {
614 if (first) {
615 first = false
616 } else {
617 print(", ")
618 }
619 print(key + " => " + smapout[key])
620 }
621 print("}\n")
622 if (smapout != smapin) {
623 returnCode1 = returnCode1 or ERR_CONTAINERS
624 println("*** FAILURE ***\n")
625 }
626 } catch (ex: Exception) {
627 returnCode1 = returnCode1 or ERR_CONTAINERS
628 println("*** FAILURE ***\n")
629 ex.printStackTrace(System.out)
630 }
631 return returnCode1
632 }
633
nestedStructTestnull634 private suspend fun ThriftTestClient.nestedStructTest(out: Xtruct, returnCode: Int): Int {
635 var code = returnCode
636 print("testNest({1, {\"Zero\", 1, -3, -5}), 5}")
637 val out2 = Xtruct2()
638 out2.byte_thing = 1.toShort().toByte()
639 out2.struct_thing = out
640 out2.i32_thing = 5
641 val xstruct2: Xtruct2 = testNest(out2)
642 val input = xstruct2.struct_thing!!
643 print(
644 """ = {${xstruct2.byte_thing}, {"${input.string_thing}", ${input.byte_thing}, ${input.i32_thing}, ${input.i64_thing}}, ${xstruct2.i32_thing}}
645 """
646 )
647 if (xstruct2 != out2) {
648 code = code or ERR_STRUCTS
649 println("*** FAILURE ***\n")
650 }
651 return code
652 }
653
binaryTestnull654 private suspend fun ThriftTestClient.binaryTest(returnCode: Int): Int {
655 var returnCode1 = returnCode
656 try {
657 print("testBinary(-128...127) = ")
658 val data = testByteArray
659 val bin: ByteBuffer = ByteBuffer.wrap(testBinary(data))
660 bin.mark()
661 val bytes = ByteArray(bin.limit() - bin.position())
662 bin[bytes]
663 bin.reset()
664 print("{")
665 var first = true
666 for (i in bytes.indices) {
667 if (first) first = false else print(", ")
668 print(bytes[i])
669 }
670 println("}")
671 if (ByteBuffer.wrap(data) != bin) {
672 returnCode1 = returnCode1 or ERR_BASETYPES
673 println("*** FAILURE ***\n")
674 }
675 } catch (ex: Exception) {
676 returnCode1 = returnCode1 or ERR_BASETYPES
677 println("\n*** FAILURE ***\n")
678 ex.printStackTrace(System.out)
679 }
680 return returnCode1
681 }
682
doubleTestnull683 private suspend fun ThriftTestClient.doubleTest(returnCode: Int): Int {
684 var returnCode1 = returnCode
685 print("testDouble(-5.325098235)")
686 val dub: Double = testDouble(-5.325098235)
687 print(" = $dub\n")
688 if (abs(dub - -5.325098235) > 0.001) {
689 returnCode1 = returnCode1 or ERR_BASETYPES
690 println("*** FAILURE ***\n")
691 }
692 return returnCode1
693 }
694
i64Testnull695 private suspend fun ThriftTestClient.i64Test(returnCode: Int): Int {
696 var returnCode1 = returnCode
697 print("testI64(-34359738368)")
698 val i64: Long = testI64(-34359738368L)
699 print(" = $i64\n")
700 if (i64 != -34359738368L) {
701 returnCode1 = returnCode1 or ERR_BASETYPES
702 println("*** FAILURE ***\n")
703 }
704 return returnCode1
705 }
706
i32Testnull707 private suspend fun ThriftTestClient.i32Test(returnCode: Int): Int {
708 var returnCode1 = returnCode
709 print("testI32(-1)")
710 val i32: Int = testI32(-1)
711 print(" = $i32\n")
712 if (i32 != -1) {
713 returnCode1 = returnCode1 or ERR_BASETYPES
714 println("*** FAILURE ***\n")
715 }
716 return returnCode1
717 }
718
byteTestnull719 private suspend fun ThriftTestClient.byteTest(returnCode: Int): Int {
720 var returnCode1 = returnCode
721 print("testByte(1)")
722 val i8: Byte = testByte(1.toByte())
723 print(" = $i8\n")
724 if (i8.toInt() != 1) {
725 returnCode1 = returnCode1 or ERR_BASETYPES
726 println("*** FAILURE ***\n")
727 }
728 return returnCode1
729 }
730
stringTestnull731 private suspend fun ThriftTestClient.stringTest(returnCode: Int): Int {
732 var returnCode1 = returnCode
733 print("testString(\"Test\")")
734 val s: String = testString("Test")
735 print(" = \"$s\"\n")
736 if (s != "Test") {
737 returnCode1 = returnCode1 or ERR_BASETYPES
738 println("*** FAILURE ***\n")
739 }
740 return returnCode1
741 }
742
voidTestnull743 private suspend fun ThriftTestClient.voidTest(returnCode: Int): Int {
744 var returnCode1 = returnCode
745 try {
746 print("testVoid()")
747 testVoid()
748 print(" = void\n")
749 } catch (tax: TApplicationException) {
750 tax.printStackTrace()
751 returnCode1 = returnCode1 or ERR_BASETYPES
752 }
753 return returnCode1
754 }
755
mainnull756 fun main(args: Array<String>) {
757 TestClient().main(args)
758 }
759
<lambda>null760 private val testByteArray = (-128..127).map { it.toByte() }.toByteArray()
761