1- import ETCD
2- import NIO
3-
41//===----------------------------------------------------------------------===//
52//
63// This source file is part of the swift-etcd-client-gsoc open source project
@@ -14,18 +11,22 @@ import NIO
1411// SPDX-License-Identifier: Apache-2.0
1512//
1613//===----------------------------------------------------------------------===//
14+
15+ import ETCD
16+ import NIO
1717import XCTest
1818
19- final class EtcdClientTests : XCTestCase {
20- var eventLoopGroup : EventLoopGroup !
21- var etcdClient : EtcdClient !
19+ final class IntegrationTests : XCTestCase {
20+
21+ private static let integrationTestEnabled = getBoolEnv ( " SWIFT_ETCD_CLIENT_INTEGRATION_TEST_ENABLED " ) ?? false
2222
2323 override func setUp( ) async throws {
24- eventLoopGroup = MultiThreadedEventLoopGroup . singleton
25- etcdClient = EtcdClient ( host: " localhost " , port: 2379 , eventLoopGroup: eventLoopGroup)
24+ try XCTSkipUnless ( Self . integrationTestEnabled)
2625 }
2726
2827 func testSetAndGetStringValue( ) async throws {
28+ let etcdClient = EtcdClient . testClient
29+
2930 try await etcdClient. set ( " testKey " , value: " testValue " )
3031 let key = " testKey " . data ( using: . utf8) !
3132 let rangeRequest = RangeRequest ( key: key)
@@ -36,13 +37,17 @@ final class EtcdClientTests: XCTestCase {
3637 }
3738
3839 func testGetNonExistentKey( ) async throws {
40+ let etcdClient = EtcdClient . testClient
41+
3942 let key = " nonExistentKey " . data ( using: . utf8) !
4043 let rangeRequest = RangeRequest ( key: key)
4144 let result = try await etcdClient. getRange ( rangeRequest)
4245 XCTAssertNil ( result)
4346 }
4447
4548 func testDeleteKeyExists( ) async throws {
49+ let etcdClient = EtcdClient . testClient
50+
4651 let key = " testKey "
4752 let value = " testValue "
4853 try await etcdClient. set ( key, value: value)
@@ -54,12 +59,14 @@ final class EtcdClientTests: XCTestCase {
5459
5560 let deleteRangeRequest = DeleteRangeRequest ( key: rangeRequestKey)
5661 try await etcdClient. deleteRange ( deleteRangeRequest)
57-
62+
5863 fetchedValue = try await etcdClient. getRange ( rangeRequest)
5964 XCTAssertNil ( fetchedValue)
6065 }
6166
6267 func testDeleteNonExistentKey( ) async throws {
68+ let etcdClient = EtcdClient . testClient
69+
6370 let key = " testKey " . data ( using: . utf8) !
6471 let rangeRequest = RangeRequest ( key: key)
6572
@@ -68,12 +75,14 @@ final class EtcdClientTests: XCTestCase {
6875
6976 let deleteRangeRequest = DeleteRangeRequest ( key: key)
7077 try await etcdClient. deleteRange ( deleteRangeRequest)
71-
78+
7279 fetchedValue = try await etcdClient. getRange ( rangeRequest)
7380 XCTAssertNil ( fetchedValue)
7481 }
7582
7683 func testUpdateExistingKey( ) async throws {
84+ let etcdClient = EtcdClient . testClient
85+
7786 let key = " testKey "
7887 let value = " testValue "
7988 try await etcdClient. set ( key, value: value)
@@ -95,14 +104,16 @@ final class EtcdClientTests: XCTestCase {
95104 }
96105
97106 func testWatch( ) async throws {
107+ let etcdClient = EtcdClient . testClient
108+
98109 let key = " testKey "
99110 let value = " testValue " . data ( using: . utf8) !
100111
101112 try await etcdClient. put ( key, value: " foo " )
102113
103114 try await withThrowingTaskGroup ( of: Void . self) { group in
104115 group. addTask {
105- try await self . etcdClient. watch ( key) { watchAsyncSequence in
116+ try await etcdClient. watch ( key) { watchAsyncSequence in
106117 var iterator = watchAsyncSequence. makeAsyncIterator ( )
107118 let events = try await iterator. next ( )
108119 guard let events = events else {
@@ -122,8 +133,27 @@ final class EtcdClientTests: XCTestCase {
122133 }
123134
124135 try await Task . sleep ( nanoseconds: 1_000_000_000 )
125- try await self . etcdClient. put ( key, value: String ( data: value, encoding: . utf8) !)
136+ try await etcdClient. put ( key, value: String ( data: value, encoding: . utf8) !)
126137 group. cancelAll ( )
127138 }
128139 }
129140}
141+
142+ extension EtcdClient {
143+ fileprivate static let testClient = EtcdClient (
144+ host: ProcessInfo . processInfo. environment [ " ETCD_HOST " ] ?? " localhost " ,
145+ port: getIntEnv ( " ETCD_PORT " ) ?? 2379 ,
146+ eventLoopGroup: . singletonMultiThreadedEventLoopGroup
147+ )
148+ }
149+
150+ /// Returns true if `key` is a truthy string, otherwise returns false.
151+ private func getBoolEnv( _ key: String ) -> Bool ? {
152+ switch ProcessInfo . processInfo. environment [ key] ? . lowercased ( ) {
153+ case . none: return nil
154+ case " true " , " y " , " yes " , " on " , " 1 " : return true
155+ default : return false
156+ }
157+ }
158+
159+ private func getIntEnv( _ key: String ) -> Int ? { ProcessInfo . processInfo. environment [ key] . flatMap ( Int . init ( _: ) ) }
0 commit comments