Skip to content

Commit 290f3c1

Browse files
authored
Split out IntegrationTests into separate testTarget (#157)
This splits out all the integration tests into a separate test target. This makes a number of things easier in day to day development: - Unit tests can be run without setting up a test database. - We can observe the test coverage in our unit tests only. - This allows us to decouple testing the language vs. testing the functionality against a database.
1 parent 8c611ce commit 290f3c1

File tree

7 files changed

+87
-105
lines changed

7 files changed

+87
-105
lines changed

Package.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,9 @@ let package = Package(
3333
.target(name: "PostgresNIO"),
3434
.product(name: "NIOTestUtils", package: "swift-nio"),
3535
]),
36+
.testTarget(name: "IntegrationTests", dependencies: [
37+
.target(name: "PostgresNIO"),
38+
.product(name: "NIOTestUtils", package: "swift-nio"),
39+
]),
3640
]
3741
)
File renamed without changes.
File renamed without changes.

Tests/PostgresNIOTests/PostgresNIOTests.swift renamed to Tests/IntegrationTests/PostgresNIOTests.swift

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,7 +1050,9 @@ final class PostgresNIOTests: XCTestCase {
10501050
defer { XCTAssertNoThrow( try conn?.close().wait() ) }
10511051
let binds = [PostgresData].init(repeating: .null, count: Int(Int16.max) + 1)
10521052
XCTAssertThrowsError(try conn?.query("SELECT version()", binds).wait()) { error in
1053-
XCTAssertEqual(error as? PSQLError, .tooManyParameters)
1053+
guard case .tooManyParameters = (error as? PSQLError)?.base else {
1054+
return XCTFail("Unexpected error: \(error)")
1055+
}
10541056
}
10551057
}
10561058

@@ -1189,10 +1191,6 @@ final class PostgresNIOTests: XCTestCase {
11891191
}
11901192
}
11911193

1192-
func env(_ name: String) -> String? {
1193-
getenv(name).flatMap { String(cString: $0) }
1194-
}
1195-
11961194
let isLoggingConfigured: Bool = {
11971195
LoggingSystem.bootstrap { label in
11981196
var handler = StreamLogHandler.standardOutput(label: label)
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import PostgresNIO
2+
import XCTest
3+
import Logging
4+
#if canImport(Darwin)
5+
import Darwin.C
6+
#else
7+
import Glibc
8+
#endif
9+
10+
extension PostgresConnection {
11+
static func address() throws -> SocketAddress {
12+
try .makeAddressResolvingHost(env("POSTGRES_HOSTNAME") ?? "localhost", port: 5432)
13+
}
14+
15+
static func testUnauthenticated(on eventLoop: EventLoop, logLevel: Logger.Level = .info) -> EventLoopFuture<PostgresConnection> {
16+
var logger = Logger(label: "postgres.connection.test")
17+
logger.logLevel = logLevel
18+
do {
19+
return connect(to: try address(), logger: logger, on: eventLoop)
20+
} catch {
21+
return eventLoop.makeFailedFuture(error)
22+
}
23+
}
24+
25+
static func test(on eventLoop: EventLoop, logLevel: Logger.Level = .info) -> EventLoopFuture<PostgresConnection> {
26+
return testUnauthenticated(on: eventLoop, logLevel: logLevel).flatMap { conn in
27+
return conn.authenticate(
28+
username: env("POSTGRES_USER") ?? "vapor_username",
29+
database: env("POSTGRES_DB") ?? "vapor_database",
30+
password: env("POSTGRES_PASSWORD") ?? "vapor_password"
31+
).map {
32+
return conn
33+
}.flatMapError { error in
34+
conn.close().flatMapThrowing {
35+
throw error
36+
}
37+
}
38+
}
39+
}
40+
}
41+
42+
extension Logger {
43+
static var psqlTest: Logger {
44+
var logger = Logger(label: "psql.test")
45+
logger.logLevel = .info
46+
return logger
47+
}
48+
}
49+
50+
func env(_ name: String) -> String? {
51+
getenv(name).flatMap { String(cString: $0) }
52+
}
53+
54+
extension XCTestCase {
55+
56+
public static var shouldRunLongRunningTests: Bool {
57+
// The env var must be set and have the value `"true"`, `"1"`, or `"yes"` (case-insensitive).
58+
// For the sake of sheer annoying pedantry, values like `"2"` are treated as false.
59+
guard let rawValue = env("POSTGRES_LONG_RUNNING_TESTS") else { return false }
60+
if let boolValue = Bool(rawValue) { return boolValue }
61+
if let intValue = Int(rawValue) { return intValue == 1 }
62+
return rawValue.lowercased() == "yes"
63+
}
64+
65+
public static var shouldRunPerformanceTests: Bool {
66+
// Same semantics as above. Any present non-truthy value will explicitly disable performance
67+
// tests even if they would've overwise run in the current configuration.
68+
let defaultValue = !_isDebugAssertConfiguration() // default to not running in debug builds
69+
70+
guard let rawValue = env("POSTGRES_PERFORMANCE_TESTS") else { return defaultValue }
71+
if let boolValue = Bool(rawValue) { return boolValue }
72+
if let intValue = Int(rawValue) { return intValue == 1 }
73+
return rawValue.lowercased() == "yes"
74+
}
75+
}
Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,2 @@
11
import Logging
22

3-
extension Logger {
4-
static var psqlTest: Logger {
5-
var logger = Logger(label: "psql.test")
6-
logger.logLevel = .info
7-
return logger
8-
}
9-
}
Lines changed: 5 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,9 @@
11
import Logging
2-
import PostgresNIO
3-
import XCTest
42

5-
extension PostgresConnection {
6-
static func address() throws -> SocketAddress {
7-
try .makeAddressResolvingHost( env("POSTGRES_HOSTNAME") ?? "localhost", port: 5432)
3+
extension Logger {
4+
static var psqlTest: Logger {
5+
var logger = Logger(label: "psql.test")
6+
logger.logLevel = .info
7+
return logger
88
}
9-
10-
static func testUnauthenticated(on eventLoop: EventLoop, logLevel: Logger.Level = .info) -> EventLoopFuture<PostgresConnection> {
11-
var logger = Logger(label: "postgres.connection.test")
12-
logger.logLevel = logLevel
13-
do {
14-
return connect(to: try address(), logger: logger, on: eventLoop)
15-
} catch {
16-
return eventLoop.makeFailedFuture(error)
17-
}
18-
}
19-
20-
static func test(on eventLoop: EventLoop, logLevel: Logger.Level = .info) -> EventLoopFuture<PostgresConnection> {
21-
return testUnauthenticated(on: eventLoop, logLevel: logLevel).flatMap { conn in
22-
return conn.authenticate(
23-
username: env("POSTGRES_USER") ?? "vapor_username",
24-
database: env("POSTGRES_DB") ?? "vapor_database",
25-
password: env("POSTGRES_PASSWORD") ?? "vapor_password"
26-
).map {
27-
return conn
28-
}.flatMapError { error in
29-
conn.close().flatMapThrowing {
30-
throw error
31-
}
32-
}
33-
}
34-
}
35-
}
36-
37-
extension XCTestCase {
38-
39-
public static var shouldRunLongRunningTests: Bool {
40-
// The env var must be set and have the value `"true"`, `"1"`, or `"yes"` (case-insensitive).
41-
// For the sake of sheer annoying pedantry, values like `"2"` are treated as false.
42-
guard let rawValue = ProcessInfo.processInfo.environment["POSTGRES_LONG_RUNNING_TESTS"] else { return false }
43-
if let boolValue = Bool(rawValue) { return boolValue }
44-
if let intValue = Int(rawValue) { return intValue == 1 }
45-
return rawValue.lowercased() == "yes"
46-
}
47-
48-
public static var shouldRunPerformanceTests: Bool {
49-
// Same semantics as above. Any present non-truthy value will explicitly disable performance
50-
// tests even if they would've overwise run in the current configuration.
51-
let defaultValue = !_isDebugAssertConfiguration() // default to not running in debug builds
52-
53-
guard let rawValue = ProcessInfo.processInfo.environment["POSTGRES_PERFORMANCE_TESTS"] else { return defaultValue }
54-
if let boolValue = Bool(rawValue) { return boolValue }
55-
if let intValue = Int(rawValue) { return intValue == 1 }
56-
return rawValue.lowercased() == "yes"
57-
}
58-
59-
}
60-
61-
62-
// 1247.typisdefined: 0x01 (BOOLEAN)
63-
// 1247.typbasetype: 0x00000000 (OID)
64-
// 1247.typnotnull: 0x00 (BOOLEAN)
65-
// 1247.typcategory: 0x42 (CHAR)
66-
// 1247.typname: 0x626f6f6c (NAME)
67-
// 1247.typbyval: 0x01 (BOOLEAN)
68-
// 1247.typrelid: 0x00000000 (OID)
69-
// 1247.typalign: 0x63 (CHAR)
70-
// 1247.typndims: 0x00000000 (INTEGER)
71-
// 1247.typacl: null
72-
// 1247.typsend: 0x00000985 (REGPROC)
73-
// 1247.typmodout: 0x00000000 (REGPROC)
74-
// 1247.typstorage: 0x70 (CHAR)
75-
// 1247.typispreferred: 0x01 (BOOLEAN)
76-
// 1247.typinput: 0x000004da (REGPROC)
77-
// 1247.typoutput: 0x000004db (REGPROC)
78-
// 1247.typlen: 0x0001 (SMALLINT)
79-
// 1247.typcollation: 0x00000000 (OID)
80-
// 1247.typdefaultbin: null
81-
// 1247.typelem: 0x00000000 (OID)
82-
// 1247.typnamespace: 0x0000000b (OID)
83-
// 1247.typtype: 0x62 (CHAR)
84-
// 1247.typowner: 0x0000000a (OID)
85-
// 1247.typdefault: null
86-
// 1247.typtypmod: 0xffffffff (INTEGER)
87-
// 1247.typarray: 0x000003e8 (OID)
88-
// 1247.typreceive: 0x00000984 (REGPROC)
89-
// 1247.typmodin: 0x00000000 (REGPROC)
90-
// 1247.typanalyze: 0x00000000 (REGPROC)
91-
// 1247.typdelim: 0x2c (CHAR)
92-
struct PGType: Decodable {
93-
var typname: String
94-
var typnamespace: UInt32
95-
var typowner: UInt32
96-
var typlen: Int16
979
}

0 commit comments

Comments
 (0)