Skip to content

Commit

Permalink
Cleanup SSHErrorTests
Browse files Browse the repository at this point in the history
  • Loading branch information
yury committed Feb 16, 2021
1 parent f627f49 commit 7889842
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 99 deletions.
153 changes: 56 additions & 97 deletions SSHTests/SSHErrorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,17 @@ import Dispatch

@testable import SSH

func __assertCompletionFailure(_ completion: Any?, withError error: SSHError, file: StaticString = #filePath, line: UInt = #line) {
guard
let c = completion as? Subscribers.Completion<Error>,
let err = c.error as? SSHError,
err == error
else {
XCTFail("Should completed with .faulure(\(error). Got: " + String(describing: completion), file: file, line: line)
return
}
}

class SSHErrorTests: XCTestCase {

/**
Expand All @@ -45,88 +56,60 @@ class SSHErrorTests: XCTestCase {
- SSHError.notImplemented(_:)
*/

var cancellableBag = Set<AnyCancellable>()

override func setUpWithError() throws {
// Put setup code here. This method is called before the invocation of each test method in the class.
}

override func tearDownWithError() throws {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}

/**
SSHError.authError(:) is thrown when trying to use a method to authenticate on a host that's not allowed.
In this case is trying to use `AuthNone()` as an authetnication method for a host that doesn't accept it.
*/
func testAuthError() throws {
func testAuthError() {
let config = SSHClientConfig(
user: MockCredentials.wrongCredentials.user,
port: MockCredentials.port,
authMethods: []
)

let expectation = self.expectation(description: "Buffer Written")

SSHClient.dial(MockCredentials.wrongCredentials.host, with: config)
.sink(receiveCompletion: { completion in
switch completion {
case .finished:
XCTFail("Authentication should not have succeeded")
case .failure(let error as SSHError):
dump(error)
if error == .authError(msg: "") {
expectation.fulfill()
} else {
XCTFail("Unknown error")
}
case .failure(_):
XCTFail("It should present an error of type SSHError.authError(msg:)")
var completion: Any? = nil

SSHClient
.dial(MockCredentials.wrongCredentials.host, with: config)
.sink(
test: self,
receiveCompletion: {
completion = $0
},
receiveValue: { _ in
XCTFail("Should not have received a connection")
}
}, receiveValue: { _ in
XCTFail("Should not have received a connection")
}).store(in: &cancellableBag)
)

waitForExpectations(timeout: 5, handler: nil)
__assertCompletionFailure(completion, withError: .authError(msg: ""))
}

func testConnectionError() throws {

func testConnectionError() {
let config = SSHClientConfig(
user: MockCredentials.wrongHost.user,
port: MockCredentials.port,
authMethods: [AuthPassword(with: MockCredentials.wrongHost.password)]
)
let expectation = self.expectation(description: "Buffer Written")

var completion: Any? = nil

SSHClient.dial(MockCredentials.wrongHost.host, with: config)
.sink(receiveCompletion: { completion in
switch completion {
case .finished:
XCTFail("Authentication should not have succeeded")
case .failure(let error as SSHError):
dump(error)
if error == .connError(msg: "") {
expectation.fulfill()
} else {
XCTFail("Unknown error")
}
case .failure(_):
XCTFail("It should present an error of type SSHError.connError(msg:)")
.sink(
test: self,
receiveCompletion: {
completion = $0
}, receiveValue: { _ in
XCTFail("Should not have received a connection")
}
}, receiveValue: { _ in
XCTFail("Should not have received a connection")
}).store(in: &cancellableBag)
)

waitForExpectations(timeout: 5, handler: nil)
__assertCompletionFailure(completion, withError: .connError(msg: ""))
}

/**
Trying to authenticate against a host with either incorrect username or password credentials
*/
func testAuthFailed() throws {

func testAuthFailed() {
let authMethods = [AuthPassword(with: MockCredentials.wrongCredentials.password)]

let config = SSHClientConfig(
Expand All @@ -135,35 +118,21 @@ class SSHErrorTests: XCTestCase {
authMethods: authMethods
)

let expectation = self.expectation(description: "Buffer Written")
var completion: Any? = nil

SSHClient.dial(MockCredentials.wrongCredentials.host, with: config)
.sink(receiveCompletion: { completion in
switch completion {
case .finished:
XCTFail("Authentication should not have succeeded")
case .failure(let error as SSHError):

if error == .authFailed(methods: authMethods) {
expectation.fulfill()
} else {
XCTFail("Unknown error")
}
case .failure(_):
XCTFail("It should present an error of type SSHError.authFailed(methods:)")

}
.sink(
test: self,
receiveCompletion: {
completion = $0
}, receiveValue: { _ in
XCTFail("Should not have received a connection")
}).store(in: &cancellableBag)

waitForExpectations(timeout: 10, handler: nil)
})
__assertCompletionFailure(completion, withError: .authFailed(methods: authMethods))
}

/**
Given a wrong/fake IP it should fail as the host couldn't be translated to a usable IP.

Uses the `SSHClient.urlToIpHostResolution(_:)`
*/
func testCouldntResolveHostAddress() throws {
let config = SSHClientConfig(
Expand All @@ -172,28 +141,18 @@ class SSHErrorTests: XCTestCase {
authMethods: [AuthPassword(with: MockCredentials.password)]
)

let expectation = self.expectation(description: "Buffer Written")
var completion: Any? = nil

SSHClient.dial(MockCredentials.incorrectIpHost, with: config)
.sink(receiveCompletion: { completion in
switch completion {
case .finished:
break
case .failure(let error as SSHError):
/// The given IP address couldn't be resolved into an IP address
expectation.fulfill()

case .failure(let genericError):
XCTFail("Shouldn't have received an error that's not of type SSHError \(genericError.localizedDescription)")
}
}, receiveValue: { _ in
XCTFail("Shouldn't have received a connection")
}).store(in: &cancellableBag)
.sink(
test: self,
receiveCompletion: {
completion = $0
},
receiveValue: { _ in
XCTFail("Shouldn't have received a connection")
})

waitForExpectations(timeout: 5, handler: nil)
}

override func tearDown() {
cancellableBag.removeAll()
__assertCompletionFailure(completion, withError: .connError(msg: "Socket error: No such file or directory"))
}
}
15 changes: 13 additions & 2 deletions SSHTests/XCTestCase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,13 @@ extension XCTestCase {
}

extension Publisher {

func sink(
test: XCTestCase,
timeout: TimeInterval = 5,
receiveCompletion: @escaping ((Subscribers.Completion<Self.Failure>) -> Void) = { _ in },
receiveValue: @escaping ((Self.Output) -> Void) = {_ in } )
{
receiveValue: @escaping ((Self.Output) -> Void) = {_ in }
) {
test.waitPublisher(self, timeout: timeout, receiveCompletion: receiveCompletion, receiveValue: receiveValue)
}

Expand Down Expand Up @@ -92,3 +93,13 @@ extension Publisher {
return value
}
}


extension Subscribers.Completion {
var error: Error? {
switch self {
case .finished: return nil
case .failure(let err): return err
}
}
}

0 comments on commit 7889842

Please sign in to comment.