Fix TestServer for windows

There were two issues with the server tests on windows
1) Sometimes client connections fail on the first attempt but
   will succeed with retries
2) It is possible for named pipes to leak which causes subsequent
   tests to be unable to run
3) ClientTest did not handle lines with carriage returns correctly

Issue #1 is fixed with retries. Issue #2 is fixed by using a
unique temp directory for each test run. Issue #3 was fixed by
simplifying the output stream cache to only cache the bytes returned
and then letting scala do the line splitting for us in linesIterator.

After these changes, all of the server tests work on appveyor.
This commit is contained in:
Ethan Atkins 2020-06-28 14:14:05 -07:00
parent 27e4b9cd14
commit e1103d1557
3 changed files with 23 additions and 16 deletions

View File

@ -155,4 +155,4 @@ for:
- '%USERPROFILE%\.sbt'
test_script:
- sbt "scripted actions/* classloader-cache/* nio/* watch/*" "serverTestProj/testOnly serverTestProj/testOnly testpkg.HandshakeTest"
- sbt "scripted actions/* classloader-cache/* nio/* watch/*" "serverTestProj/test"

View File

@ -27,15 +27,9 @@ object ClientTest extends AbstractServerTest {
def lines = cos.lines
}
class CachingOutputStream extends OutputStream {
private val lineBuffer = new mutable.ArrayBuffer[String]
private var byteBuffer = new mutable.ArrayBuffer[Byte]
override def write(i: Int) = {
if (i == 10) {
lineBuffer += new String(byteBuffer.toArray)
byteBuffer = new mutable.ArrayBuffer[Byte]
} else Util.ignoreResult(byteBuffer += i.toByte)
}
def lines = lineBuffer.toVector
private val byteBuffer = new mutable.ArrayBuffer[Byte]
override def write(i: Int) = Util.ignoreResult(byteBuffer += i.toByte)
def lines = new String(byteBuffer.toArray, "UTF-8").linesIterator.toSeq
}
class FixedInputStream(keys: Char*) extends InputStream {
var i = 0

View File

@ -8,7 +8,8 @@
package testpkg
import java.io.{ File, IOException }
import java.nio.file.Path
import java.net.Socket
import java.nio.file.{ Files, Path }
import java.util.concurrent.{ LinkedBlockingQueue, TimeUnit }
import java.util.concurrent.atomic.AtomicBoolean
@ -37,10 +38,11 @@ trait AbstractServerTest extends TestSuite[Unit] {
}
override def setupSuite(): Unit = {
temp = targetDir / "test-server" / testDirectory
if (temp.exists) {
IO.delete(temp)
}
val base = Files.createTempDirectory(
Files.createDirectories(targetDir.toPath.resolve("test-server")),
"server-test"
)
temp = base.toFile
val classpath = sys.props.get("sbt.server.classpath") match {
case Some(s: String) => s.split(java.io.File.pathSeparator).map(file)
case _ => throw new IllegalStateException("No server classpath was specified.")
@ -191,8 +193,19 @@ case class TestServer(
hostLog(s"wait $waitDuration until the server is ready to respond")
waitForPortfile(waitDuration)
@tailrec
private def connect(attempt: Int): Socket = {
val res = try Some(ClientSocket.socket(portfile)._1)
catch { case _: IOException if attempt < 10 => None }
res match {
case Some(s) => s
case _ =>
Thread.sleep(100)
connect(attempt + 1)
}
}
// make connection to the socket described in the portfile
val (sk, _) = ClientSocket.socket(portfile)
val sk = connect(0)
val out = sk.getOutputStream
val in = sk.getInputStream
private val lines = new LinkedBlockingQueue[String]