mirror of https://github.com/sbt/sbt.git
Remove launcher tests
This commit is contained in:
parent
60e2057b15
commit
56cc49a6b0
|
|
@ -1,14 +0,0 @@
|
|||
package xsbt.boot
|
||||
|
||||
import org.scalacheck._
|
||||
import Prop._
|
||||
|
||||
object CacheTest extends Properties("Cache") {
|
||||
implicit val functions: Arbitrary[Int => Int] = Arbitrary { Gen.oneOf(Seq(identity[Int], i => -i, i => i / 2, i => i + 1)) }
|
||||
|
||||
property("Cache") = Prop.forAll { (key: Int, keys: List[Int], map: Int => Int) =>
|
||||
val cache = new Cache((i: Int, _: Unit) => map(i))
|
||||
def toProperty(key: Int) = ("Key " + key) |: ("Value: " + map(key)) |: (cache.apply(key, ()) == map(key))
|
||||
Prop.all(keys.map(toProperty): _*)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
package xsbt.boot
|
||||
|
||||
import java.io.{ File, InputStream }
|
||||
import java.net.URL
|
||||
import java.util.Properties
|
||||
import xsbti._
|
||||
import org.specs2._
|
||||
import mutable.Specification
|
||||
import sbt.IO.{ createDirectory, touch, withTemporaryDirectory }
|
||||
|
||||
object ConfigurationParserTest extends Specification {
|
||||
"Configuration Parser" should {
|
||||
"Correctly parse bootOnly" in {
|
||||
|
||||
repoFileContains("""|[repositories]
|
||||
| local: bootOnly""".stripMargin,
|
||||
Repository.Predefined("local", true))
|
||||
|
||||
repoFileContains("""|[repositories]
|
||||
| local""".stripMargin,
|
||||
Repository.Predefined("local", false))
|
||||
|
||||
repoFileContains("""|[repositories]
|
||||
| id: https://repo1.maven.org""".stripMargin,
|
||||
Repository.Maven("id", new URL("https://repo1.maven.org"), false))
|
||||
|
||||
repoFileContains("""|[repositories]
|
||||
| id: https://repo1.maven.org, bootOnly""".stripMargin,
|
||||
Repository.Maven("id", new URL("https://repo1.maven.org"), true))
|
||||
|
||||
repoFileContains("""|[repositories]
|
||||
| id: https://repo1.maven.org, [orgPath]""".stripMargin,
|
||||
Repository.Ivy("id", new URL("https://repo1.maven.org"), "[orgPath]", "[orgPath]", false, false))
|
||||
|
||||
repoFileContains("""|[repositories]
|
||||
| id: https://repo1.maven.org, [orgPath], mavenCompatible""".stripMargin,
|
||||
Repository.Ivy("id", new URL("https://repo1.maven.org"), "[orgPath]", "[orgPath]", true, false))
|
||||
|
||||
repoFileContains("""|[repositories]
|
||||
| id: https://repo1.maven.org, [orgPath], mavenCompatible, bootOnly""".stripMargin,
|
||||
Repository.Ivy("id", new URL("https://repo1.maven.org"), "[orgPath]", "[orgPath]", true, true))
|
||||
|
||||
repoFileContains("""|[repositories]
|
||||
| id: https://repo1.maven.org, [orgPath], bootOnly, mavenCompatible""".stripMargin,
|
||||
Repository.Ivy("id", new URL("https://repo1.maven.org"), "[orgPath]", "[orgPath]", true, true))
|
||||
|
||||
repoFileContains("""|[repositories]
|
||||
| id: https://repo1.maven.org, [orgPath], bootOnly""".stripMargin,
|
||||
Repository.Ivy("id", new URL("https://repo1.maven.org"), "[orgPath]", "[orgPath]", false, true))
|
||||
|
||||
repoFileContains("""|[repositories]
|
||||
| id: https://repo1.maven.org, [orgPath], [artPath]""".stripMargin,
|
||||
Repository.Ivy("id", new URL("https://repo1.maven.org"), "[orgPath]", "[artPath]", false, false))
|
||||
|
||||
repoFileContains("""|[repositories]
|
||||
| id: https://repo1.maven.org, [orgPath], [artPath], descriptorOptional""".stripMargin,
|
||||
Repository.Ivy("id", new URL("https://repo1.maven.org"), "[orgPath]", "[artPath]", false, false, true, false))
|
||||
|
||||
repoFileContains("""|[repositories]
|
||||
| id: https://repo1.maven.org, [orgPath], [artPath], descriptorOptional, skipConsistencyCheck""".stripMargin,
|
||||
Repository.Ivy("id", new URL("https://repo1.maven.org"), "[orgPath]", "[artPath]", false, false, true, true))
|
||||
|
||||
repoFileContains("""|[repositories]
|
||||
| id: https://repo1.maven.org, [orgPath], [artPath], skipConsistencyCheck, descriptorOptional""".stripMargin,
|
||||
Repository.Ivy("id", new URL("https://repo1.maven.org"), "[orgPath]", "[artPath]", false, false, true, true))
|
||||
|
||||
repoFileContains("""|[repositories]
|
||||
| id: https://repo1.maven.org, [orgPath], [artPath], skipConsistencyCheck, descriptorOptional, mavenCompatible, bootOnly""".stripMargin,
|
||||
Repository.Ivy("id", new URL("https://repo1.maven.org"), "[orgPath]", "[artPath]", true, true, true, true))
|
||||
|
||||
repoFileContains("""|[repositories]
|
||||
| id: https://repo1.maven.org, [orgPath], [artPath], bootOnly""".stripMargin,
|
||||
Repository.Ivy("id", new URL("https://repo1.maven.org"), "[orgPath]", "[artPath]", false, true))
|
||||
|
||||
repoFileContains("""|[repositories]
|
||||
| id: https://repo1.maven.org, [orgPath], [artPath], bootOnly, mavenCompatible""".stripMargin,
|
||||
Repository.Ivy("id", new URL("https://repo1.maven.org"), "[orgPath]", "[artPath]", true, true))
|
||||
|
||||
repoFileContains("""|[repositories]
|
||||
| id: https://repo1.maven.org, [orgPath], [artPath], mavenCompatible, bootOnly""".stripMargin,
|
||||
Repository.Ivy("id", new URL("https://repo1.maven.org"), "[orgPath]", "[artPath]", true, true))
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
def repoFileContains(file: String, repo: Repository.Repository) =
|
||||
loadRepoFile(file) must contain(repo)
|
||||
|
||||
def loadRepoFile(file: String) =
|
||||
(new ConfigurationParser) readRepositoriesConfig file
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
package xsbt.boot
|
||||
|
||||
import org.scalacheck._
|
||||
import Prop.{ Exception => _, _ }
|
||||
|
||||
object EnumerationTest extends Properties("Enumeration") {
|
||||
property("MultiEnum.toValue") = checkToValue(MultiEnum, multiElements: _*)
|
||||
property("MultiEnum.elements") = checkElements(MultiEnum, multiElements: _*)
|
||||
property("EmptyEnum.toValue") = checkToValue(EmptyEnum)
|
||||
property("EmptyEnum.elements") = EmptyEnum.elements.isEmpty
|
||||
property("SingleEnum.toValue") = checkToValue(SingleEnum, singleElements)
|
||||
property("SingleEnum.elements") = checkElements(SingleEnum, singleElements)
|
||||
|
||||
def singleElements = ("A", SingleEnum.a)
|
||||
def multiElements =
|
||||
{
|
||||
import MultiEnum.{ a, b, c }
|
||||
List(("A" -> a), ("B" -> b), ("C" -> c))
|
||||
}
|
||||
|
||||
def checkElements(enum: Enumeration, mapped: (String, Enumeration#Value)*) =
|
||||
{
|
||||
val elements = enum.elements
|
||||
("elements: " + elements) |:
|
||||
(mapped.forall { case (s, v) => elements.contains(v) } && (elements.length == mapped.length))
|
||||
}
|
||||
def checkToValue(enum: Enumeration, mapped: (String, Enumeration#Value)*) =
|
||||
{
|
||||
def invalid(s: String) =
|
||||
("valueOf(" + s + ")") |:
|
||||
Prop.throws(classOf[Exception])(enum.toValue(s))
|
||||
def valid(s: String, expected: Enumeration#Value) =
|
||||
("valueOf(" + s + ")") |:
|
||||
("Expected " + expected) |:
|
||||
(enum.toValue(s) == expected)
|
||||
val map = Map(mapped: _*)
|
||||
Prop.forAll((s: String) =>
|
||||
map.get(s) match {
|
||||
case Some(v) => valid(s, v)
|
||||
case None => invalid(s)
|
||||
})
|
||||
}
|
||||
object MultiEnum extends Enumeration {
|
||||
val a = value("A")
|
||||
val b = value("B")
|
||||
val c = value("C")
|
||||
}
|
||||
object SingleEnum extends Enumeration {
|
||||
val a = value("A")
|
||||
}
|
||||
object EmptyEnum extends Enumeration
|
||||
}
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
package xsbt.boot
|
||||
|
||||
import org.scalacheck._
|
||||
|
||||
object ListMapProperties extends Properties("ListMap") {
|
||||
implicit val genListMap = Arbitrary(for (list <- Arbitrary.arbitrary[List[(Int, Int)]]) yield ListMap(list: _*))
|
||||
|
||||
property("ListMap from List contains all members of that List") = Prop.forAll { (list: List[(Int, Int)]) =>
|
||||
val map = ListMap(list: _*)
|
||||
list forall { entry => map contains entry._1 }
|
||||
}
|
||||
property("contains added entry") = Prop.forAll { (map: ListMap[Int, Int], key: Int, value: Int) =>
|
||||
{ (map + (key, value)) contains (key) } &&
|
||||
{ (map + (key, value))(key) == value } &&
|
||||
{ (map + (key, value)).get(key) == Some(value) }
|
||||
}
|
||||
property("remove") = Prop.forAll { (map: ListMap[Int, Int], key: Int) =>
|
||||
{ Prop.throws(classOf[Exception])((map - key)(key)) } &&
|
||||
{ !(map - key).contains(key) } &&
|
||||
{ (map - key).get(key).isEmpty }
|
||||
}
|
||||
property("empty") = Prop.forAll { (key: Int) =>
|
||||
{ Prop.throws(classOf[Exception])(ListMap.empty(key)) }
|
||||
{ !ListMap.empty.contains(key) } &&
|
||||
{ ListMap.empty.get(key).isEmpty }
|
||||
}
|
||||
}
|
||||
|
||||
object ListMapEmpty extends Properties("ListMap.empty") {
|
||||
import ListMap.empty
|
||||
property("isEmpty") = empty.isEmpty
|
||||
property("toList.isEmpty") = empty.toList.isEmpty
|
||||
property("toSeq.isEmpty") = empty.toSeq.isEmpty
|
||||
property("toStream.isEmpty") = empty.toStream.isEmpty
|
||||
property("keys.isEmpty") = empty.keys.isEmpty
|
||||
property("iterator.isEmpty") = empty.iterator.isEmpty
|
||||
}
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
package xsbt.boot
|
||||
|
||||
import org.scalacheck._
|
||||
import Prop._
|
||||
import java.io.File
|
||||
import sbt.IO.withTemporaryDirectory
|
||||
|
||||
/**
|
||||
* These mainly test that things work in the uncontested case and that no OverlappingFileLockExceptions occur.
|
||||
* There is no real locking testing, just the coordination of locking.
|
||||
*/
|
||||
object LocksTest extends Properties("Locks") {
|
||||
property("Lock in nonexisting directory") = spec {
|
||||
withTemporaryDirectory { dir =>
|
||||
val lockFile = new File(dir, "doesntexist/lock")
|
||||
Locks(lockFile, callTrue)
|
||||
}
|
||||
}
|
||||
|
||||
property("Uncontested re-entrant lock") = spec {
|
||||
withTemporaryDirectory { dir =>
|
||||
val lockFile = new File(dir, "lock")
|
||||
Locks(lockFile, callLocked(lockFile)) &&
|
||||
Locks(lockFile, callLocked(lockFile))
|
||||
}
|
||||
}
|
||||
|
||||
property("Uncontested double lock") = spec {
|
||||
withTemporaryDirectory { dir =>
|
||||
val lockFileA = new File(dir, "lockA")
|
||||
val lockFileB = new File(dir, "lockB")
|
||||
Locks(lockFileA, callLocked(lockFileB)) &&
|
||||
Locks(lockFileB, callLocked(lockFileA))
|
||||
}
|
||||
}
|
||||
|
||||
property("Contested single lock") = spec {
|
||||
withTemporaryDirectory { dir =>
|
||||
val lockFile = new File(dir, "lock")
|
||||
forkFold(2000) { i => Locks(lockFile, callTrue) }
|
||||
}
|
||||
}
|
||||
|
||||
private def spec(f: => Boolean): Prop = Prop { _ => Result(if (f) True else False) }
|
||||
|
||||
private def call[T](impl: => T) = new java.util.concurrent.Callable[T] { def call = impl }
|
||||
private def callLocked(lockFile: File) = call { Locks(lockFile, callTrue) }
|
||||
private lazy val callTrue = call { true }
|
||||
|
||||
private def forkFold(n: Int)(impl: Int => Boolean): Boolean =
|
||||
(true /: forkWait(n)(impl))(_ && _)
|
||||
private def forkWait(n: Int)(impl: Int => Boolean): Iterable[Boolean] =
|
||||
{
|
||||
import scala.concurrent.Future
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.concurrent.Await
|
||||
import scala.concurrent.duration.Duration.Inf
|
||||
// TODO - Don't wait forever...
|
||||
val futures = (0 until n).map { i => Future { impl(i) } }
|
||||
futures.toList.map(f => Await.result(f, Inf))
|
||||
}
|
||||
}
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
package xsbt.boot
|
||||
|
||||
import java.io.File
|
||||
import java.util.Arrays.{ equals => arrEquals }
|
||||
import org.scalacheck._
|
||||
|
||||
object PreTest extends Properties("Pre") {
|
||||
import Pre._
|
||||
property("isEmpty") = Prop.forAll((s: String) => (s.isEmpty == isEmpty(s)))
|
||||
property("isNonEmpty") = Prop.forAll((s: String) => (isEmpty(s) != isNonEmpty(s)))
|
||||
property("assert true") = { assert(true); true }
|
||||
property("assert false") = Prop.throws(classOf[AssertionError])(assert(false))
|
||||
property("assert true with message") = Prop.forAll { (s: String) => assert(true, s); true }
|
||||
property("assert false with message") = Prop.forAll((s: String) => Prop.throws(classOf[AssertionError])(assert(false, s)))
|
||||
property("require false") = Prop.forAll((s: String) => Prop.throws(classOf[IllegalArgumentException])(require(false, s)))
|
||||
property("require true") = Prop.forAll { (s: String) => require(true, s); true }
|
||||
property("error") = Prop.forAll((s: String) => Prop.throws(classOf[BootException])(error(s)))
|
||||
property("toBoolean") = Prop.forAll((s: String) => trap(toBoolean(s)) == trap(java.lang.Boolean.parseBoolean(s)))
|
||||
property("toArray") = Prop.forAll((list: List[Int]) => arrEquals(list.toArray, toArray(list)))
|
||||
property("toArray") = Prop.forAll((list: List[String]) => objArrEquals(list.toArray, toArray(list)))
|
||||
property("concat") = Prop.forAll(genFiles, genFiles) { (a: Array[File], b: Array[File]) => (a ++ b) sameElements concat(a, b) }
|
||||
property("array") = Prop.forAll(genFiles) { (a: Array[File]) => array(a.toList: _*) sameElements Array(a: _*) }
|
||||
|
||||
implicit lazy val arbFile: Arbitrary[File] = Arbitrary { for (i <- Arbitrary.arbitrary[Int]) yield new File(i.toString) }
|
||||
implicit lazy val genFiles: Gen[Array[File]] = Arbitrary.arbitrary[Array[File]]
|
||||
|
||||
def trap[T](t: => T): Option[T] = try { Some(t) } catch { case e: Exception => None }
|
||||
|
||||
private[this] def objArrEquals[T <: AnyRef](a: Array[T], b: Array[T]): Boolean =
|
||||
arrEquals(a.asInstanceOf[Array[AnyRef]], b.asInstanceOf[Array[AnyRef]])
|
||||
}
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
package xsbt.boot
|
||||
|
||||
import java.io.{ File, InputStream }
|
||||
import java.net.URL
|
||||
import java.util.Properties
|
||||
import xsbti._
|
||||
import org.specs2._
|
||||
import mutable.Specification
|
||||
import LaunchTest._
|
||||
import sbt.IO.{ createDirectory, touch, withTemporaryDirectory }
|
||||
|
||||
object ScalaProviderTest extends Specification {
|
||||
"Launch" should {
|
||||
//"provide ClassLoader for Scala 2.8.0" in { checkScalaLoader("2.8.0") }
|
||||
"provide ClassLoader for Scala 2.8.2" in { checkScalaLoader("2.8.2") }
|
||||
"provide ClassLoader for Scala 2.9.0" in { checkScalaLoader("2.9.0") }
|
||||
"provide ClassLoader for Scala 2.9.2" in { checkScalaLoader("2.9.2") }
|
||||
"provide ClassLoader for Scala 2.10.4" in { checkScalaLoader("2.10.4") }
|
||||
"provide ClassLoader for Scala 2.11.0" in { checkScalaLoader("2.11.0") }
|
||||
}
|
||||
|
||||
"Launch" should {
|
||||
"Successfully load an application from local repository and run it with correct arguments" in {
|
||||
checkLoad(List("test"), "xsbt.boot.test.ArgumentTest").asInstanceOf[Exit].code must equalTo(0)
|
||||
checkLoad(List(), "xsbt.boot.test.ArgumentTest") must throwA[RuntimeException]
|
||||
}
|
||||
"Successfully load an plain application from local repository and run it with correct arguments" in {
|
||||
checkLoad(List("test"), "xsbt.boot.test.PlainArgumentTest").asInstanceOf[Exit].code must equalTo(0)
|
||||
checkLoad(List(), "xsbt.boot.test.PlainArgumentTest") must throwA[RuntimeException]
|
||||
}
|
||||
"Successfully load an plain application with int return from local repository and run it with correct arguments" in {
|
||||
checkLoad(List("test"), "xsbt.boot.test.PlainArgumentTestWithReturn").asInstanceOf[Exit].code must equalTo(0)
|
||||
checkLoad(List(), "xsbt.boot.test.PlainArgumentTestWithReturn").asInstanceOf[Exit].code must equalTo(1)
|
||||
}
|
||||
"Successfully load an application from local repository and run it with correct sbt version" in {
|
||||
checkLoad(List(AppVersion), "xsbt.boot.test.AppVersionTest").asInstanceOf[Exit].code must equalTo(0)
|
||||
}
|
||||
"Add extra resources to the classpath" in {
|
||||
checkLoad(testResources, "xsbt.boot.test.ExtraTest", createExtra).asInstanceOf[Exit].code must equalTo(0)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
def checkLoad(arguments: List[String], mainClassName: String): MainResult =
|
||||
checkLoad(arguments, mainClassName, _ => Array[File]())
|
||||
def checkLoad(arguments: List[String], mainClassName: String, extra: File => Array[File]): MainResult =
|
||||
withTemporaryDirectory { currentDirectory =>
|
||||
withLauncher { launcher =>
|
||||
Launch.run(launcher)(
|
||||
new RunConfiguration(Some(unmapScalaVersion(LaunchTest.getScalaVersion)), LaunchTest.testApp(mainClassName, extra(currentDirectory)).toID, currentDirectory, arguments)
|
||||
)
|
||||
}
|
||||
}
|
||||
private def testResources = List("test-resourceA", "a/b/test-resourceB", "sub/test-resource")
|
||||
private def createExtra(currentDirectory: File) =
|
||||
{
|
||||
val resourceDirectory = new File(currentDirectory, "resources")
|
||||
createDirectory(resourceDirectory)
|
||||
testResources.foreach(resource => touch(new File(resourceDirectory, resource.replace('/', File.separatorChar))))
|
||||
Array(resourceDirectory)
|
||||
}
|
||||
private def checkScalaLoader(version: String) = withLauncher(checkLauncher(version, mapScalaVersion(version)))
|
||||
private def checkLauncher(version: String, versionValue: String)(launcher: Launcher) =
|
||||
{
|
||||
val provider = launcher.getScala(version)
|
||||
val loader = provider.loader
|
||||
// ensure that this loader can load Scala classes by trying scala.ScalaObject.
|
||||
tryScala(loader)
|
||||
getScalaVersion(loader) must beEqualTo(versionValue)
|
||||
}
|
||||
private def tryScala(loader: ClassLoader) = Class.forName("scala.Product", false, loader).getClassLoader must be(loader)
|
||||
}
|
||||
object LaunchTest {
|
||||
def testApp(main: String): Application = testApp(main, Array[File]())
|
||||
def testApp(main: String, extra: Array[File]): Application = Application("org.scala-sbt", "launch-test", new Explicit(AppVersion), main, Nil, CrossValue.Disabled, extra)
|
||||
import Predefined._
|
||||
def testRepositories = List(Local, ScalaToolsReleases, ScalaToolsSnapshots).map(Repository.Predefined(_))
|
||||
def withLauncher[T](f: xsbti.Launcher => T): T =
|
||||
withTemporaryDirectory { bootDirectory =>
|
||||
f(Launcher(bootDirectory, testRepositories))
|
||||
}
|
||||
|
||||
val finalStyle = Set("2.9.1", "2.9.0-1", "2.9.0", "2.8.2", "2.8.1", "2.8.0")
|
||||
def unmapScalaVersion(versionNumber: String) = versionNumber.stripSuffix(".final")
|
||||
def mapScalaVersion(versionNumber: String) = if (finalStyle(versionNumber)) versionNumber + ".final" else versionNumber
|
||||
|
||||
def getScalaVersion: String = getScalaVersion(getClass.getClassLoader)
|
||||
def getScalaVersion(loader: ClassLoader): String = getProperty(loader, "library.properties", "version.number")
|
||||
lazy val AppVersion = getProperty(getClass.getClassLoader, "xsbt.version.properties", "version")
|
||||
|
||||
private[this] def getProperty(loader: ClassLoader, res: String, prop: String) = loadProperties(loader.getResourceAsStream(res)).getProperty(prop)
|
||||
private[this] def loadProperties(propertiesStream: InputStream): Properties =
|
||||
{
|
||||
val properties = new Properties
|
||||
try { properties.load(propertiesStream) } finally { propertiesStream.close() }
|
||||
properties
|
||||
}
|
||||
}
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
package xsbt.boot
|
||||
|
||||
import java.io.{ File, InputStream }
|
||||
import java.net.URL
|
||||
import java.util.Properties
|
||||
import xsbti._
|
||||
import org.specs2._
|
||||
import mutable.Specification
|
||||
import LaunchTest._
|
||||
import sbt.IO.{ createDirectory, touch, withTemporaryDirectory }
|
||||
import java.net.URI
|
||||
|
||||
object ServerLocatorTest extends Specification {
|
||||
"ServerLocator" should {
|
||||
// TODO - Maybe use scalacheck to randomnly generate URIs
|
||||
"read and write server URI properties" in {
|
||||
withTemporaryDirectory { dir =>
|
||||
val propFile = new File(dir, "server.properties")
|
||||
val expected = new java.net.URI("http://localhost:8080")
|
||||
ServerLocator.writeProperties(propFile, expected)
|
||||
ServerLocator.readProperties(propFile) must equalTo(Some(expected))
|
||||
}
|
||||
}
|
||||
"detect listening ports" in {
|
||||
val serverSocket = new java.net.ServerSocket(0)
|
||||
object serverThread extends Thread {
|
||||
override def run(): Unit = {
|
||||
// Accept one connection.
|
||||
val result = serverSocket.accept()
|
||||
result.close()
|
||||
serverSocket.close()
|
||||
}
|
||||
}
|
||||
serverThread.start()
|
||||
val uri = new java.net.URI(s"http://${serverSocket.getInetAddress.getHostAddress}:${serverSocket.getLocalPort}")
|
||||
ServerLocator.isReachable(uri) must beTrue
|
||||
}
|
||||
}
|
||||
"ServerLauncher" should {
|
||||
"detect start URI from reader" in {
|
||||
val expected = new java.net.URI("http://localhost:8080")
|
||||
val input = s"""|Some random text
|
||||
|to start the server
|
||||
|${ServerApplication.SERVER_SYNCH_TEXT}${expected.toASCIIString}
|
||||
|Some more output.""".stripMargin
|
||||
val inputStream = new java.io.BufferedReader(new java.io.StringReader(input))
|
||||
val result = try ServerLauncher.readUntilSynch(inputStream)
|
||||
finally inputStream.close()
|
||||
result must equalTo(Some(expected))
|
||||
}
|
||||
"determine a JVM version" in {
|
||||
withTemporaryDirectory { dir =>
|
||||
// javaIs8OrAbove returns None for pathological situations
|
||||
// (weird errors running java -version or something),
|
||||
// but when testing sbt we should not be in such a situation.
|
||||
val determined = ServerLauncher.javaIsAbove(dir, 7)
|
||||
determined must beSome
|
||||
}
|
||||
}
|
||||
"have JVM memory defaults" in {
|
||||
withTemporaryDirectory { dir =>
|
||||
val defaults = ServerLauncher.serverJvmArgs(dir, Nil)
|
||||
defaults must contain(beEqualTo("-Xms256m"))
|
||||
defaults must contain(beEqualTo("-Xmx1024m"))
|
||||
if (ServerLauncher.javaIsAbove(dir, 7).getOrElse(false)) {
|
||||
defaults must contain(beEqualTo("-XX:MetaspaceSize=64m"))
|
||||
defaults must contain(beEqualTo("-XX:MaxMetaspaceSize=256m"))
|
||||
} else {
|
||||
defaults must contain(beEqualTo("-XX:PermSize=64m"))
|
||||
defaults must contain(beEqualTo("-XX:MaxPermSize=256m"))
|
||||
}
|
||||
}
|
||||
}
|
||||
"leave user-specified memory options alone" in {
|
||||
withTemporaryDirectory { dir =>
|
||||
val args = ServerLauncher.serverJvmArgs(dir, List("-Xmx4321m"))
|
||||
args must contain(beEqualTo("-Xmx4321m"))
|
||||
args must not contain (beEqualTo("-Xms256m"))
|
||||
args must not contain (beEqualTo("-Xmx1024m"))
|
||||
}
|
||||
}
|
||||
"ignore whitespace in jvm args file" in {
|
||||
withTemporaryDirectory { dir =>
|
||||
val args = ServerLauncher.serverJvmArgs(dir, List("", " ", " -Xmx4321m ", " ", ""))
|
||||
args must equalTo(List("-Xmx4321m"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
package xsbt.boot
|
||||
|
||||
import org.scalacheck._
|
||||
import Prop._
|
||||
import Configuration._
|
||||
import java.io.File
|
||||
import java.net.URI
|
||||
|
||||
object URITests extends Properties("URI Tests") {
|
||||
// Need a platform-specific root, otherwise URI will not be absolute (e.g. if we use a "/a/b/c" path in Windows)
|
||||
// Note:
|
||||
// If I use "C:" instead of "/C:", then isAbsolute == true for the resulting URI, but resolve is broken:
|
||||
// e.g. scala> new URI("file", "c:/a/b'/has spaces", null).resolve("a") broken
|
||||
// res0: java.net.URI = a
|
||||
// scala> new URI("file", "/c:/a/b'/has spaces", null).resolve("a") working
|
||||
// res1: java.net.URI = file:/c:/a/b'/a
|
||||
val Root = if (xsbt.boot.Pre.isWindows) "/C:/" else "/"
|
||||
|
||||
val FileProtocol = "file"
|
||||
property("directoryURI adds trailing slash") = secure {
|
||||
val dirURI = directoryURI(new File(Root + "a/b/c"))
|
||||
val directURI = filePathURI(Root + "a/b/c/")
|
||||
dirURI == directURI
|
||||
}
|
||||
property("directoryURI preserves trailing slash") = secure {
|
||||
directoryURI(new File(Root + "a/b/c/")) == filePathURI(Root + "a/b/c/")
|
||||
}
|
||||
|
||||
property("filePathURI encodes spaces") = secure {
|
||||
val decoded = "has spaces"
|
||||
val encoded = "has%20spaces"
|
||||
val fpURI = filePathURI(decoded)
|
||||
val directURI = new URI(encoded)
|
||||
s"filePathURI: $fpURI" |:
|
||||
s"direct URI: $directURI" |:
|
||||
s"getPath: ${fpURI.getPath}" |:
|
||||
s"getRawPath: ${fpURI.getRawPath}" |:
|
||||
(fpURI == directURI) &&
|
||||
(fpURI.getPath == decoded) &&
|
||||
(fpURI.getRawPath == encoded)
|
||||
}
|
||||
|
||||
property("filePathURI and File.toURI agree for absolute file") = secure {
|
||||
val s = Root + "a/b'/has spaces"
|
||||
val viaPath = filePathURI(s)
|
||||
val viaFile = new File(s).toURI
|
||||
s"via path: $viaPath" |:
|
||||
s"via file: $viaFile" |:
|
||||
(viaPath == viaFile)
|
||||
}
|
||||
|
||||
property("filePathURI supports URIs") = secure {
|
||||
val s = s"file://${Root}is/a/uri/with%20spaces"
|
||||
val decoded = Root + "is/a/uri/with spaces"
|
||||
val encoded = Root + "is/a/uri/with%20spaces"
|
||||
val fpURI = filePathURI(s)
|
||||
val directURI = new URI(s)
|
||||
s"filePathURI: $fpURI" |:
|
||||
s"direct URI: $directURI" |:
|
||||
s"getPath: ${fpURI.getPath}" |:
|
||||
s"getRawPath: ${fpURI.getRawPath}" |:
|
||||
(fpURI == directURI) &&
|
||||
(fpURI.getPath == decoded) &&
|
||||
(fpURI.getRawPath == encoded)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
package xsbt.boot
|
||||
|
||||
import org.scalacheck._
|
||||
import Prop._
|
||||
|
||||
object VersionParts extends Properties("VersionParts") {
|
||||
property("Valid version, no qualifier") = Prop.forAll { (x0: Int, y0: Int, z0: Int) =>
|
||||
val (x, y, z) = (norm(x0), norm(y0), norm(z0))
|
||||
val str = s"$x.$y.$z"
|
||||
val expected =
|
||||
s"$x.$y.$z" ::
|
||||
s"$x.$y" ::
|
||||
"" ::
|
||||
Nil
|
||||
check(str, expected)
|
||||
}
|
||||
|
||||
property("Valid version with qualifier") = Prop.forAll { (x0: Int, y0: Int, z0: Int, q0: String) =>
|
||||
val (x, y, z, q) = (norm(x0), norm(y0), norm(z0), normS(q0))
|
||||
val str = s"$x.$y.$z-$q"
|
||||
val expected =
|
||||
s"$x.$y.$z-$q" ::
|
||||
s"$x.$y.$z" ::
|
||||
s"$x.$y" ::
|
||||
"" ::
|
||||
Nil
|
||||
check(str, expected)
|
||||
}
|
||||
|
||||
property("Invalid version") = Prop.forAll { (x0: Int, y0: Int, z0: Int, q0: String) =>
|
||||
val (x, y, z, q) = (norm(x0), norm(y0), norm(z0), normS(q0))
|
||||
val strings =
|
||||
x.toString ::
|
||||
s"$x.$y" ::
|
||||
s"$x.$y-$q" ::
|
||||
s"$x.$y.$z.$q" ::
|
||||
Nil
|
||||
all(strings.map(str => check(str, Configuration.noMatchParts)): _*)
|
||||
}
|
||||
|
||||
private[this] def check(versionString: String, expectedParts: List[String]) =
|
||||
{
|
||||
def printParts(s: List[String]): String = s.map("'" + _ + "'").mkString("(", ", ", ")")
|
||||
val actual = Configuration.versionParts(versionString)
|
||||
s"Version string '$versionString'" |:
|
||||
s"Expected '${printParts(expectedParts)}'" |:
|
||||
s"Actual'${printParts(actual)}'" |:
|
||||
(actual == expectedParts)
|
||||
}
|
||||
|
||||
// Make `i` non-negative
|
||||
private[this] def norm(i: Int): Int =
|
||||
if (i == Int.MinValue) Int.MaxValue else math.abs(i)
|
||||
|
||||
// Make `s` non-empty and suitable for java.util.regex input
|
||||
private[this] def normS(s: String): String =
|
||||
{
|
||||
val filtered = s filter validChar
|
||||
if (filtered.isEmpty) "q" else filtered
|
||||
}
|
||||
|
||||
// strip whitespace and characters not supported by Pattern
|
||||
private[this] def validChar(c: Char) =
|
||||
!java.lang.Character.isWhitespace(c) &&
|
||||
!java.lang.Character.isISOControl(c) &&
|
||||
!Character.isHighSurrogate(c) &&
|
||||
!Character.isLowSurrogate(c)
|
||||
}
|
||||
Loading…
Reference in New Issue