Skip to content

Commit

Permalink
Merge branch 'main' into zhennan_support_urlsession
Browse files Browse the repository at this point in the history
  • Loading branch information
johnnzhou committed Jun 21, 2024
2 parents 3e53336 + 5f527c4 commit d966586
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 132 deletions.
18 changes: 6 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,31 +39,25 @@ Then import the module to your project
### Basic Usage
```swift
// Reachability Test
let isReachable = LCLPing.reachable(via: .ipv4ICMP, strategy: .multiple, host: "google.com")
let isReachable = LCLPing.reachable(via: .icmp, strategy: .multiple, host: "google.com")
print("is reachable: \(isReachable)")
```

```swift
// Run Ping Test

// create ping configuration
// create ping configuration for each run
let icmpConfig = ICMPPingClient.Configuration(endpoint: .ipv4("127.0.0.1", 0), count: 1)
let httpConfig = try HTTPPingClient.Configuration(url: "http://127.0.0.1:8080", count: 1)

// initialize test client
let icmpClient = LCLPing(pingType: .icmp(icmpConfig))
let httpClient = LCLPing(pingType: .http(httpConfig))
let icmpClient = ICMPPingClient(configuration: icmpConfig)
let httpClient = HTTPPingClient(configuration: httpConfig)

do {
// run the test using SwiftNIO EventLoopFuture
let result = try icmpClient.start().whenComplete { res in
switch (res) {
case .success(let summary):
print(summary)
case .failure(let error):
print(error)
}
}
let result = try icmpClient.start().wait()
print(result)
} catch {
print("received: \(error)")
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/Demo/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ let icmpConfig = try ICMPPingClient.Configuration(endpoint: .ipv4("127.0.0.1", 0
let httpConfig = try HTTPPingClient.Configuration(url: "http://127.0.0.1:8080", count: 1)

// initialize test client
let icmpClient = LCLPing(pingType: .icmp(icmpConfig))
let httpClient = LCLPing(pingType: .http(httpConfig))
let icmpClient = ICMPPingClient(configuration: icmpConfig)
let httpClient = HTTPPingClient(configuration: httpConfig)

do {
// run the test using SwiftNIO EventLoopFuture
Expand Down
15 changes: 6 additions & 9 deletions Sources/LCLPing/Configuration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,11 @@

import Foundation

extension LCLPing {
/// Type of reachability test that `LCLPing` supports
public enum PingType {
/// Perform reachability ping test through the ICMP protocol.
case icmp

/// Type of reachability test that `LCLPing` supports
public enum PingType {
/// Perform reachability ping test through the ICMP protocol.
case icmp(ICMPPingClient.Configuration)

/// Perform reachability ping test through the HTTP protocol.
case http(HTTPPingClient.Configuration)
}
/// Perform reachability ping test through the HTTP protocol.
case http
}
55 changes: 0 additions & 55 deletions Sources/LCLPing/LCLPing.swift

This file was deleted.

101 changes: 47 additions & 54 deletions Sources/LCLPing/Reachability.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,65 +12,57 @@

import Foundation

extension LCLPing {

/// Check if the target host is reachable or not
///
/// - Parameters:
/// - via: the `ReachabilityTestMethod` that will be used to run the reachability tes
/// - host: the endpoint host
/// - Returns: true if the host is reachable; false otherwise.
public static func reachable(via method: ReachabilityTestMethod, host: String) throws -> Bool {
return try reachable(via: method, strategy: .multiple, host: host)
}

/// Check if the target host is reachable or not.
/// A simple majority of the successful test could be considered as reachable
///
/// - Parameters:
/// - via: the `ReachabilityTestMethod` that will be used to run the reachability tes
/// - strategy: the `TestStrategy` that indicates how many times the `LCLPing` should run to make the result reliable
/// - host: the endpoint host
public static func reachable(via method: ReachabilityTestMethod,
strategy: TestStrategy,
host: String
) throws -> Bool {
switch method {
case .http:
let httpConfig = try HTTPPingClient.Configuration(url: host, count: strategy.count)
let client = HTTPPingClient(configuration: httpConfig)
let result = try client.start().wait()
return result.isSimpleMajority()
case .ipv4ICMP:
let icmpConfig = try ICMPPingClient.Configuration(endpoint: .ipv4(host, 0), count: strategy.count)
let client = ICMPPingClient(configuration: icmpConfig)
let result = try client.start().wait()
return result.isSimpleMajority()
}
}
/// Check if the target host is reachable or not
///
/// - Parameters:
/// - via: the `ReachabilityTestMethod` that will be used to run the reachability tes
/// - host: the endpoint host
/// - Returns: true if the host is reachable; false otherwise.
public func reachable(via method: PingType, host: String) throws -> Bool {
return try reachable(via: method, strategy: .multiple, host: host)
}

public enum ReachabilityTestMethod {
case ipv4ICMP
case http
/// Check if the target host is reachable or not.
/// A simple majority of the successful test could be considered as reachable
///
/// - Parameters:
/// - via: the `ReachabilityTestMethod` that will be used to run the reachability test
/// - strategy: the `TestStrategy` that indicates how many times the `LCLPing` should run to make the result reliable
/// - host: the endpoint host
public func reachable(via method: PingType,
strategy: TestStrategy,
host: String
) throws -> Bool {
switch method {
case .http:
let httpConfig = try HTTPPingClient.Configuration(url: host, count: strategy.count)
let client = HTTPPingClient(configuration: httpConfig)
let result = try client.start().wait()
return result.isSimpleMajority()
case .icmp:
let icmpConfig = ICMPPingClient.Configuration(endpoint: .ipv4(host, 0), count: strategy.count)
let client = ICMPPingClient(configuration: icmpConfig)
let result = try client.start().wait()
return result.isSimpleMajority()
}
}

public enum TestStrategy {
case single
case multiple
case extended
public enum TestStrategy {
case single
case multiple
case extended

// TODO: need to support continuous, stream of testing
// case continuous
// TODO: need to support continuous, stream of testing
// case continuous

var count: Int {
switch self {
case .single:
return 1
case .multiple:
return 3
case .extended:
return 10
}
var count: Int {
switch self {
case .single:
return 1
case .multiple:
return 3
case .extended:
return 10
}
}
}
Expand All @@ -83,6 +75,7 @@ extension PingSummary {
if self.totalCount == 0 {
return false
}

let majority = self.totalCount % 2 == 0 ? self.totalCount / 2 : self.totalCount / 2 + 1
return self.details.count >= majority
}
Expand Down

0 comments on commit d966586

Please sign in to comment.