From 0faf0bb94a42a9d6adb2bf21ad194a715e281f41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Andr=C3=A9n?= Date: Wed, 28 Aug 2019 16:44:41 +0200 Subject: [PATCH] Don't rely on OS DNS lookup failure in spec #27031 (#27571) Instead mock out the DNS provider and return failure to lookup immediately --- .../test/scala/akka/stream/io/TcpSpec.scala | 97 +++++++++++++++---- 1 file changed, 79 insertions(+), 18 deletions(-) diff --git a/akka-stream-tests/src/test/scala/akka/stream/io/TcpSpec.scala b/akka-stream-tests/src/test/scala/akka/stream/io/TcpSpec.scala index f406f81860..99496bd757 100644 --- a/akka-stream-tests/src/test/scala/akka/stream/io/TcpSpec.scala +++ b/akka-stream-tests/src/test/scala/akka/stream/io/TcpSpec.scala @@ -8,26 +8,76 @@ import java.net._ import java.security.SecureRandom import java.util.concurrent.atomic.AtomicInteger -import javax.net.ssl.{ KeyManagerFactory, SSLContext, TrustManagerFactory } -import akka.actor.{ ActorIdentity, ActorSystem, ExtendedActorSystem, Identify, Kill } +import akka.Done +import akka.NotUsed +import akka.actor.Actor +import akka.actor.ActorIdentity +import akka.actor.ActorRef +import akka.actor.ActorSystem +import akka.actor.ExtendedActorSystem +import akka.actor.Identify +import akka.actor.Kill +import akka.io.Dns +import akka.io.DnsProvider +import akka.io.SimpleDnsCache import akka.io.Tcp._ import akka.stream._ -import akka.stream.scaladsl.Tcp.{ IncomingConnection, ServerBinding } -import akka.stream.scaladsl.{ Flow, _ } -import akka.stream.testkit.scaladsl.StreamTestKit._ +import akka.stream.scaladsl.Flow +import akka.stream.scaladsl.Tcp.IncomingConnection +import akka.stream.scaladsl.Tcp.ServerBinding +import akka.stream.scaladsl._ import akka.stream.testkit._ -import akka.testkit.{ EventFilter, TestKit, TestLatch, TestProbe } +import akka.stream.testkit.scaladsl.StreamTestKit._ +import akka.testkit.EventFilter import akka.testkit.SocketUtil.temporaryServerAddress +import akka.testkit.TestKit +import akka.testkit.TestLatch +import akka.testkit.TestProbe import akka.testkit.WithLogCapturing import akka.util.ByteString -import akka.{ Done, NotUsed } +import com.github.ghik.silencer.silent +import com.typesafe.config.Config import com.typesafe.config.ConfigFactory import org.scalatest.concurrent.PatienceConfiguration import org.scalatest.concurrent.PatienceConfiguration.Timeout import scala.collection.immutable +import scala.concurrent.Await +import scala.concurrent.ExecutionContext +import scala.concurrent.Future +import scala.concurrent.Promise import scala.concurrent.duration._ -import scala.concurrent.{ Await, ExecutionContext, Future, Promise } + +@silent("never used") +class NonResolvingDnsActor(cache: SimpleDnsCache, config: Config) extends Actor { + def receive = { + case msg => + throw new RuntimeException(s"Unexpected resolve message $msg") + } +} + +@silent("never used") +class NonResolvingDnsManager(ext: akka.io.DnsExt) extends Actor { + + def receive = { + case msg => + throw new RuntimeException(s"Unexpected resolve message $msg") + } +} + +class FailingDnsResolver extends DnsProvider { + override val cache: Dns = new Dns { + override def cached(name: String): Option[Dns.Resolved] = None + override def resolve(name: String)(system: ActorSystem, sender: ActorRef): Option[Dns.Resolved] = { + // tricky impl detail this is actually where the resolve response is triggered + // we fake that it fails directly from here + sender ! Dns.Resolved(name, immutable.Seq.empty, immutable.Seq.empty) + None + } + } + override def actorClass = classOf[NonResolvingDnsActor] + override def managerClass = classOf[NonResolvingDnsManager] +} class TcpSpec extends StreamSpec(""" akka.loglevel = debug @@ -505,17 +555,27 @@ class TcpSpec extends StreamSpec(""" } "provide full exceptions when connection attempt fails because name cannot be resolved" in { - val unknownHostName = "abcdefghijklmnopkuh" + val systemWithBrokenDns = ActorSystem( + "TcpSpec-resolution-failure", + ConfigFactory.parseString(""" + akka.io.dns.inet-address.provider-object = akka.stream.io.FailingDnsResolver + """).withFallback(system.settings.config)) + try { + val unknownHostName = "abcdefghijklmnopkuh" - val test = - Source.maybe - .viaMat(Tcp().outgoingConnection(unknownHostName, 12345))(Keep.right) - .to(Sink.ignore) - .run() - .failed - .futureValue + val test = + Source.maybe + .viaMat(Tcp(systemWithBrokenDns).outgoingConnection(unknownHostName, 12345))(Keep.right) + .to(Sink.ignore) + .run()(SystemMaterializer(systemWithBrokenDns).materializer) + .failed + .futureValue - test.getCause shouldBe a[UnknownHostException] + test.getCause shouldBe a[UnknownHostException] + + } finally { + TestKit.shutdownActorSystem(systemWithBrokenDns) + } } } @@ -813,10 +873,11 @@ class TcpSpec extends StreamSpec(""" def initSslMess() = { // #setting-up-ssl-context + import java.security.KeyStore + import akka.stream.TLSClientAuth import akka.stream.TLSProtocol import com.typesafe.sslconfig.akka.AkkaSSLConfig - import java.security.KeyStore import javax.net.ssl._ val sslConfig = AkkaSSLConfig()