// // Copyright (c) ZeroC, Inc. All rights reserved. // import Foundation import Ice import PromiseKit import TestCommon class Condition { var _lock = os_unfair_lock() var _value: Bool init(value: Bool) { _value = value } func set(value: Bool) { withLock(&_lock) { self._value = value } } func value() -> Bool { return withLock(&_lock) { self._value } } } func allTests(_ helper: TestHelper) throws { func test(_ value: Bool, file: String = #file, line: Int = #line) throws { try helper.test(value, file: file, line: line) } let output = helper.getWriter() let communicator = helper.communicator() output.write("testing stringToProxy... ") let base = try communicator.stringToProxy("hold:\(helper.getTestEndpoint(num: 0))")! let baseSerialized = try communicator.stringToProxy("hold:\(helper.getTestEndpoint(num: 1))")! output.writeLine("ok") output.write("testing checked cast... ") let hold = try checkedCast(prx: base, type: HoldPrx.self)! let holdOneway = uncheckedCast(prx: base.ice_oneway(), type: HoldPrx.self) try test(hold == base) let holdSerialized = try checkedCast(prx: baseSerialized, type: HoldPrx.self)! let holdSerializedOneway = uncheckedCast(prx: baseSerialized.ice_oneway(), type: HoldPrx.self) try test(holdSerialized == baseSerialized) output.writeLine("ok") output.write("changing state between active and hold rapidly... ") for _ in 0 ..< 100 { try hold.putOnHold(0) } for _ in 0 ..< 100 { try holdOneway.putOnHold(0) } for _ in 0 ..< 100 { try holdSerialized.putOnHold(0) } for _ in 0 ..< 100 { try holdSerializedOneway.putOnHold(0) } output.writeLine("ok") output.write("testing without serialize mode... ") do { let cond = Condition(value: true) var value: Int32 = 0 var completed: Promise! var sent: Promise! while cond.value() { let expected = value sent = Promise { seal in completed = hold.setAsync(value: value + 1, delay: Int32.random(in: 0 ..< 5)) { seal.fulfill($0) } } _ = completed!.done { (v: Int32) throws -> Void in if v != expected { cond.set(value: false) } } value += 1 if value % 100 == 0 { _ = try sent.wait() } if value > 100_000 { // Don't continue, it's possible that out-of-order dispatch doesn't occur // after 100000 iterations and we don't want the test to last for too long // when this occurs. break } } try test(value > 100_000 || !cond.value()) _ = try sent.wait() } output.writeLine("ok") output.write("testing with serialize mode... ") do { let cond = Condition(value: true) var value: Int32 = 0 var completed: Promise? while value < 3000, cond.value() { let expected = value let sent = Promise { seal in completed = holdSerialized.setAsync(value: value + 1, delay: 0) { seal.fulfill($0) } } _ = completed!.done { (v: Int32) throws -> Void in if v != expected { cond.set(value: false) } } value += 1 if value % 100 == 0 { _ = try sent.wait() } } _ = try completed!.wait() try test(cond.value()) for i in 0 ..< 10000 { try holdSerializedOneway.setOneway(value: value + 1, expected: value) value += 1 if i % 100 == 0 { try holdSerializedOneway.putOnHold(1) } } } output.writeLine("ok") output.write("testing serialization... ") do { var value: Int32 = 0 _ = try holdSerialized.set(value: value, delay: 0) var completed: Promise! for i in 0 ..< 10000 { // Create a new proxy for each request completed = holdSerialized.ice_oneway().setOnewayAsync(value: value + 1, expected: value) value += 1 if (i % 100) == 0 { try completed.wait() try holdSerialized.ice_ping() // Ensure everything's dispatched. try holdSerialized.ice_getConnection()!.close(.GracefullyWithWait) } } try completed.wait() } output.writeLine("ok") output.write("testing waitForHold... ") do { try hold.waitForHold() try hold.waitForHold() for i in 0 ..< 1000 { try holdOneway.ice_ping() if (i % 20) == 0 { try hold.putOnHold(0) } } try hold.putOnHold(-1) try hold.ice_ping() try hold.putOnHold(-1) try hold.ice_ping() } output.writeLine("ok") output.write("changing state to hold and shutting down server... ") try hold.shutdown() output.writeLine("ok") }