Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tidy up copy-pasted code in integration tests. #201

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,72 +42,63 @@ class CustomTypesSpec extends Spec with ScalaCheckDrivenPropertyChecks {
}
}

for {
binaryResults <- Seq(false, true)
binaryParams <- Seq(false, true)
hostPort <- sys.env.get("PG_HOST_PORT")
user <- sys.env.get("PG_USER")
password = sys.env.get("PG_PASSWORD")
dbname <- sys.env.get("PG_DBNAME")
useSsl = sys.env.getOrElse("USE_PG_SSL", "0") == "1"
} yield {
IntegrationSpec.clientBuilder().foreach { clientBuilder =>
for {
binaryResults <- Seq(false, true)
binaryParams <- Seq(false, true)
} yield {
implicit val client = clientBuilder
.withBinaryParams(binaryParams)
.withBinaryResults(binaryResults)
.withSessionPool.maxSize(1)
.newRichClient()

implicit val client = Postgres.Client()
.database(dbname)
.withCredentials(user, password)
.withBinaryParams(binaryParams)
.withBinaryResults(binaryResults)
.conditionally(useSsl, _.withTransport.tlsWithoutValidation)
.withSessionPool.maxSize(1)
.newRichClient(hostPort)
val mode = if(binaryResults) "binary mode" else "text mode"
val paramsMode = if(binaryParams)
"binary"
else
"text"

implicit val useBinaryParams = binaryParams

val mode = if(binaryResults) "binary mode" else "text mode"
val paramsMode = if(binaryParams)
"binary"
else
"text"

implicit val useBinaryParams = binaryParams

s"A $mode postgres client with $paramsMode params" should {
"retrieve the available types from the remote DB" in {
val types = Await.result(client.typeMap())
assert(types.nonEmpty)
assert(types != PostgresClient.defaultTypes)
s"A $mode postgres client with $paramsMode params" should {
"retrieve the available types from the remote DB" in {
val types = Await.result(client.typeMap())
assert(types.nonEmpty)
assert(types != PostgresClient.defaultTypes)
}
}
}

s"Retrieved type map decoders for $mode client with $paramsMode params" must {
"parse varchars" in test(ValueDecoder.string)("varchar")
"parse text" in test(ValueDecoder.string)("text")
"parse booleans" in test(ValueDecoder.boolean)("boolean")
"parse shorts" in test(ValueDecoder.int2)("int2")
"parse ints" in test(ValueDecoder.int4)("int4")
"parse longs" in test(ValueDecoder.int8)("int8")
//precision seems to be an issue when postgres parses text floats
"parse floats" in test(ValueDecoder.float4)("numeric::float4")
"parse doubles" in test(ValueDecoder.float8)("numeric::float8")
"parse numerics" in test(ValueDecoder.bigDecimal)("numeric")
"parse timestamps" in test(ValueDecoder.localDateTime)(
"timestamp",
(a, b) => a.getLong(ChronoField.MICRO_OF_DAY) == b.getLong(ChronoField.MICRO_OF_DAY)
)
"parse timestamps with time zone" in test(ValueDecoder.zonedDateTime)(
"timestamptz",
(a, b) =>
// when reading the value, the timezone may have changed:
// the binary protocol does not include timezone information (everything is in UTC)
// the text protocol returns in the server's timezone which may be different than the supplied tz.
// so we convert the input value to the read value's timezone and then compare them
a.withZoneSameInstant(b.getOffset) == b
)
"parse times" in test(ValueDecoder.localTime)("time")
"parse times with timezone" in test(ValueDecoder.offsetTime)("timetz")
"parse intervals" in test(ValueDecoder.interval)("interval")
"parse uuids" in test(ValueDecoder.uuid)("uuid")
"parse hstore maps" in test(ValueDecoder.hstoreMap)("hstore")
s"Retrieved type map decoders for $mode client with $paramsMode params" must {
"parse varchars" in test(ValueDecoder.string)("varchar")
"parse text" in test(ValueDecoder.string)("text")
"parse booleans" in test(ValueDecoder.boolean)("boolean")
"parse shorts" in test(ValueDecoder.int2)("int2")
"parse ints" in test(ValueDecoder.int4)("int4")
"parse longs" in test(ValueDecoder.int8)("int8")
//precision seems to be an issue when postgres parses text floats
"parse floats" in test(ValueDecoder.float4)("numeric::float4")
"parse doubles" in test(ValueDecoder.float8)("numeric::float8")
"parse numerics" in test(ValueDecoder.bigDecimal)("numeric")
"parse timestamps" in test(ValueDecoder.localDateTime)(
"timestamp",
(a, b) => a.getLong(ChronoField.MICRO_OF_DAY) == b.getLong(ChronoField.MICRO_OF_DAY)
)
"parse timestamps with time zone" in test(ValueDecoder.zonedDateTime)(
"timestamptz",
(a, b) =>
// when reading the value, the timezone may have changed:
// the binary protocol does not include timezone information (everything is in UTC)
// the text protocol returns in the server's timezone which may be different than the supplied tz.
// so we convert the input value to the read value's timezone and then compare them
a.withZoneSameInstant(b.getOffset) == b
)
"parse times" in test(ValueDecoder.localTime)("time")
"parse times with timezone" in test(ValueDecoder.offsetTime)("timetz")
"parse intervals" in test(ValueDecoder.interval)("interval")
"parse uuids" in test(ValueDecoder.uuid)("uuid")
"parse hstore maps" in test(ValueDecoder.hstoreMap)("hstore")
}
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,24 @@ import com.twitter.util.Future

object IntegrationSpec {
val pgTestTable = "finagle_test"

def clientBuilder(): Option[Postgres.Client] = (for {
hostPort <- sys.env.get("PG_HOST_PORT")
user <- sys.env.get("PG_USER")
password = sys.env.get("PG_PASSWORD")
dbname <- sys.env.get("PG_DBNAME")
useSsl = sys.env.getOrElse("USE_PG_SSL", "0") == "1"
sslHost = sys.env.get("PG_SSL_HOST")
} yield {
Postgres.Client()
.withCredentials(user, password)
.database(dbname)
.conditionally(useSsl, c => sslHost.fold(c.withTransport.tls)(c.withTransport.tls(_)))
.dest(hostPort)
}).orElse {
println("WARNING: Skipping integration tests due to missing environment variables, see IntegrationSpec.scala for details")
None
}
}

/*
Expand All @@ -30,41 +48,22 @@ object IntegrationSpec {
*
*/
class IntegrationSpec extends Spec {

for {
hostPort <- sys.env.get("PG_HOST_PORT")
user <- sys.env.get("PG_USER")
password = sys.env.get("PG_PASSWORD")
dbname <- sys.env.get("PG_DBNAME")
useSsl = sys.env.getOrElse("USE_PG_SSL", "0") == "1"
sslHost = sys.env.get("PG_SSL_HOST")
} yield {

IntegrationSpec.clientBuilder().foreach { clientBuilder =>

val queryTimeout = Duration.fromSeconds(2)

def getClient: PostgresClientImpl = {
val client = Postgres.Client()
.withCredentials(user, password)
.database(dbname)
val client = clientBuilder
.withSessionPool.maxSize(1)
.conditionally(useSsl, c => sslHost.fold(c.withTransport.tls)(c.withTransport.tls(_)))
.newRichClient(hostPort)
.newRichClient()

Await.result(Future[PostgresClientImpl] {
while (!client.isAvailable) {}
client
})
}

def getBadClient = {
Postgres.Client()
.withCredentials(user, password)
.database(dbname)
.withSessionPool.maxSize(1)
.conditionally(useSsl, c => sslHost.fold(c.withTransport.tls)(c.withTransport.tls(_)))
.newRichClient("badhost:5432")
}
def getBadClient = Postgres.Client().newRichClient("badhost:5432")

def cleanDb(client: PostgresClient): Unit = {
val dropQuery = client.executeUpdate("DROP TABLE IF EXISTS %s".format(IntegrationSpec.pgTestTable))
Expand Down Expand Up @@ -362,7 +361,7 @@ class IntegrationSpec extends Spec {

// this test will fail if the test DB user doesn't have permission
"create an extension using CREATE EXTENSION" in {
if(user == "postgres") {
if(clientBuilder.params[Postgres.User].user == "postgres") {
val client = getClient
val result = client.prepareAndExecute("CREATE EXTENSION IF NOT EXISTS hstore")
Await.result(result)
Expand Down Expand Up @@ -430,8 +429,12 @@ class IntegrationSpec extends Spec {
}
"client is bad" in {
val badClient: PostgresClient = getBadClient
badClient.isAvailable must equal(false)
Set(Status.Busy, Status.Closed) must contain (badClient.status)
try {
badClient.isAvailable must equal(false)
Set(Status.Busy, Status.Closed) must contain (badClient.status)
} finally {
badClient.close()
}
}
"client is closed" in {
val client: PostgresClient = getClient
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,16 @@ import com.twitter.util.{Await, Future}
import org.scalatestplus.scalacheck.ScalaCheckDrivenPropertyChecks

class NumericSpec extends Spec with ScalaCheckDrivenPropertyChecks {


for {
hostPort <- sys.env.get("PG_HOST_PORT")
user <- sys.env.get("PG_USER")
password = sys.env.get("PG_PASSWORD")
dbname <- sys.env.get("PG_DBNAME")
useSsl = sys.env.getOrElse("USE_PG_SSL", "0") == "1"
} yield {

val binaryClient = Postgres.Client()
.database(dbname)
.withCredentials(user, password)
IntegrationSpec.clientBuilder().foreach { clientBuilder =>
val binaryClient = clientBuilder
.withBinaryParams(true)
.withBinaryResults(true)
.newRichClient(hostPort)
.newRichClient()

val textClient = Postgres.Client()
.database(dbname)
.withCredentials(user, password)
val textClient = clientBuilder
.withBinaryParams(false)
.withBinaryResults(false)
.newRichClient(hostPort)
.newRichClient()

Await.result((textClient.query(
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,8 @@ import com.twitter.finagle.postgres.Spec
import com.twitter.util.{Await, Future}

class TransactionSpec extends Spec {
for {
hostPort <- sys.env.get("PG_HOST_PORT")
user <- sys.env.get("PG_USER")
password = sys.env.get("PG_PASSWORD")
dbname <- sys.env.get("PG_DBNAME")
useSsl = sys.env.getOrElse("USE_PG_SSL", "0") == "1"
} yield {

val client = Postgres.Client()
.withCredentials(user, password)
.database(dbname)
.conditionally(useSsl, _.withTransport.tlsWithoutValidation)
.newRichClient(hostPort)
IntegrationSpec.clientBuilder().foreach { clientBuilder =>
val client = clientBuilder.newRichClient()

Await.result(client.query(
"""
Expand Down