diff --git a/launch/src/test/scala/ScalaProviderTest.scala b/launch/src/test/scala/ScalaProviderTest.scala index 2071b3773..55a2381eb 100644 --- a/launch/src/test/scala/ScalaProviderTest.scala +++ b/launch/src/test/scala/ScalaProviderTest.scala @@ -24,7 +24,7 @@ object ScalaProviderTest extends Specification checkLoad(List(), "xsbt.boot.test.ArgumentTest") must throwA[RuntimeException] } "Successfully load an application from local repository and run it with correct sbt version" in { - checkLoad(List(), "xsbt.boot.test.AppVersionTest").asInstanceOf[Exit].code must be(0) + checkLoad(List(AppVersion), "xsbt.boot.test.AppVersionTest").asInstanceOf[Exit].code must be(0) } } @@ -49,7 +49,7 @@ object ScalaProviderTest extends Specification } object LaunchTest { - def testApp(main: String) = Application("org.scala-tools.sbt", "launch-test", new Version.Explicit(test.MainTest.Version), main, Nil, false) + def testApp(main: String) = Application("org.scala-tools.sbt", "launch-test", new Version.Explicit(AppVersion), main, Nil, false) import Repository.Predefined._ def testRepositories = List(Local, ScalaToolsReleases, ScalaToolsSnapshots).map(Repository.Predefined.apply) def withLauncher[T](f: xsbti.Launcher => T): T = @@ -68,13 +68,16 @@ object LaunchTest properties.load(propertiesStream) properties.getProperty("version.number") } + lazy val AppVersion = + { + val properties = new java.util.Properties + val propertiesStream = getClass.getResourceAsStream("/xsbt.version.properties") + try { properties.load(propertiesStream) } finally { propertiesStream.close() } + "test-" + properties.getProperty("version") + } } package test { - object MainTest - { - val Version = "test-" + System.currentTimeMillis - } class Exit(val code: Int) extends xsbti.Exit final class MainException(message: String) extends RuntimeException(message) final class ArgumentTest extends AppMain @@ -88,9 +91,12 @@ package test class AppVersionTest extends AppMain { def run(configuration: xsbti.AppConfiguration) = - if(configuration.provider.id.version == MainTest.Version) + { + val expected = configuration.arguments.headOption.getOrElse("") + if(configuration.provider.id.version == expected) new Exit(0) else - throw new MainException("app version was " + configuration.provider.id.version + ", expected: " + MainTest.Version) + throw new MainException("app version was " + configuration.provider.id.version + ", expected: " + expected) + } } } diff --git a/project/build/XSbt.scala b/project/build/XSbt.scala index b09be38cf..87c514625 100644 --- a/project/build/XSbt.scala +++ b/project/build/XSbt.scala @@ -82,7 +82,7 @@ class XSbt(info: ProjectInfo) extends ParentProject(info) def testID = "launch-test" override def testClasspath = super.testClasspath +++ interfaceSub.compileClasspath lazy val rawTestCompile = super.testCompileAction dependsOn(interfaceSub.compile) - override def testCompileAction = publishLocal dependsOn(rawTestCompile) + override def testCompileAction = publishLocal dependsOn(rawTestCompile, interfaceSub.publishLocal) } trait TestDependencies extends Project { diff --git a/tasks/src/test/scala/TaskGen.scala b/tasks/src/test/scala/TaskGen.scala new file mode 100644 index 000000000..65ddbfbe5 --- /dev/null +++ b/tasks/src/test/scala/TaskGen.scala @@ -0,0 +1,16 @@ +import org.scalacheck._ +import Gen.choose + +object TaskGen +{ + // upper bounds to make the tests finish in reasonable time + val MaxTasks = 10000 + val MaxWorkers = 257 + val MaxJoin = 100 + + val MaxTasksGen = choose(0, MaxTasks) + val MaxWorkersGen = choose(1, MaxWorkers) + val MaxJoinGen = choose(0, MaxJoin) + val TaskListGen = MaxTasksGen.flatMap(size => Gen.listOfN(size, Arbitrary.arbInt.arbitrary)) + +} \ No newline at end of file diff --git a/tasks/src/test/scala/TaskRunnerCircular.scala b/tasks/src/test/scala/TaskRunnerCircular.scala index 795875fb2..aebf163bf 100644 --- a/tasks/src/test/scala/TaskRunnerCircular.scala +++ b/tasks/src/test/scala/TaskRunnerCircular.scala @@ -2,15 +2,12 @@ import xsbt._ import org.scalacheck._ import Prop._ +import TaskGen._ object TaskRunnerCircularTest extends Properties("TaskRunner Circular") { - specify("Catches circular references", (intermediate: Int, workers: Int) => - (workers > 0 && intermediate >= 0) ==> checkCircularReferences(intermediate, workers) - ) - specify("Allows references to completed tasks", forAllNoShrink(Arbitrary.arbitrary[(Int,Int)])(x=>x) { case (intermediate: Int, workers: Int) => - (workers > 0 && intermediate >= 0) ==> allowedReference(intermediate, workers) - }) + property("Catches circular references") = forAll(MaxTasksGen, MaxWorkersGen) { checkCircularReferences _ } + property("Allows references to completed tasks") = forAllNoShrink(MaxTasksGen, MaxWorkersGen) { allowedReference _ } final def allowedReference(intermediate: Int, workers: Int) = { val top = Task(intermediate) named("top") diff --git a/tasks/src/test/scala/TaskRunnerFork.scala b/tasks/src/test/scala/TaskRunnerFork.scala index cffaffa1b..8d72217bd 100644 --- a/tasks/src/test/scala/TaskRunnerFork.scala +++ b/tasks/src/test/scala/TaskRunnerFork.scala @@ -3,36 +3,35 @@ import xsbt._ import org.scalacheck._ import Prop._ import Task._ +import TaskGen._ import Math.abs object TaskRunnerForkTest extends Properties("TaskRunner Fork") { - specify("fork m tasks and wait for all to complete", (m: Int, workers: Int) => - (workers > 0 && m >= 0) ==> { - val values = (0 until m).toList - checkResult(TaskRunner(values.fork(f => () ).join.map(_.toList),workers), values) - true - } - ) - specify("Fork and reduce 2", (m: Int, workers: Int) => - (workers > 0 && m > 1) ==> { + property("fork m tasks and wait for all to complete") = forAll(MaxTasksGen, MaxWorkersGen) { (m: Int, workers: Int) => + val values = (0 until m).toList + checkResult(TaskRunner(values.fork(f => () ).join.map(_.toList),workers), values) + true + } + property("Fork and reduce 2") = forAll(MaxTasksGen, MaxWorkersGen) { (m: Int, workers: Int) => + (m > 1) ==> { val task = (0 to m) fork {_ * 10} reduce{_ + _} checkResult(TaskRunner(task, workers), 5*(m+1)*m) } - ) - specify("Double join", (a: Int, b: Int, workers: Int) => - (workers > 0) ==> { runDoubleJoin(abs(a),abs(b),workers); true } - ) + } + property("Double join") = forAll(MaxJoinGen, MaxJoinGen, MaxWorkersGen) { (a: Int, b: Int, workers: Int) => + runDoubleJoin(abs(a),abs(b),workers) + true + } def runDoubleJoin(a: Int, b: Int, workers: Int) { def inner(i: Int) = List.range(0, b).map(j => Task(j) named(j.toString)).join.named("Join " + i) TaskRunner( List.range(0,a).map(inner).join.named("Outermost join"), workers) } - specify("fork and reduce", (m: List[Int], workers: Int) => { - (workers > 0 && !m.isEmpty) ==> { - val expected = m.reduceLeft(_+_) - checkResult(TaskRunner( m.reduce(_ + _), workers), expected) - } + property("fork and reduce") = forAll(TaskListGen, MaxWorkersGen) { (m: List[Int], workers: Int) => + (!m.isEmpty) ==> { + val expected = m.reduceLeft(_+_) + checkResult(TaskRunner( m.reduce(_ + _), workers), expected) } - ) -} \ No newline at end of file + } +} diff --git a/tasks/src/test/scala/TestRunner.scala b/tasks/src/test/scala/TestRunner.scala index 75c539926..ceba8527a 100644 --- a/tasks/src/test/scala/TestRunner.scala +++ b/tasks/src/test/scala/TestRunner.scala @@ -2,51 +2,44 @@ import xsbt._ import org.scalacheck._ import Prop._ +import TaskGen._ object TaskRunnerSpec extends Properties("TaskRunner") { - specify("evaluates simple task", (i: Int, workers: Int) => - (workers > 0) ==> { - ("Workers: " + workers) |: - checkResult(TaskRunner(Task(i), workers), i) + val iGen = Arbitrary.arbInt.arbitrary + property("evaluates simple task") = forAll(iGen, MaxWorkersGen) { (i: Int, workers: Int) => + ("Workers: " + workers) |: + checkResult(TaskRunner(Task(i), workers), i) + } + property("evaluates simple static graph") = forAll(iGen, MaxWorkersGen) { (i: Int, workers: Int) => + ("Workers: " + workers) |: + { + def result = TaskRunner(Task(i) dependsOn(Task(false),Task("a")), workers) + checkResult(result, i) } - ) - specify("evaluates simple static graph", (i: Int, workers: Int) => - (workers > 0) ==> { - ("Workers: " + workers) |: - { - def result = TaskRunner(Task(i) dependsOn(Task(false),Task("a")), workers) - checkResult(result, i) - } + } + + property("evaluates simple mapped task") = forAll(iGen, MaxTasksGen, MaxWorkersGen) { (i: Int, times: Int, workers: Int) => + ("Workers: " + workers) |: ("Value: " + i) |: ("Times: " + times) |: + { + def result = TaskRunner(Task(i).map(_*times), workers) + checkResult(result, i*times) } - ) - specify("evaluates simple mapped task", (i: Int, times: Int, workers: Int) => - (workers > 0) ==> { - ("Workers: " + workers) |: ("Value: " + i) |: ("Times: " + times) |: - { - def result = TaskRunner(Task(i).map(_*times), workers) - checkResult(result, i*times) - } + } + property("evaluates chained mapped task") = forAllNoShrink(iGen, Gen.choose(0, 1000), MaxWorkersGen) { (i: Int, times: Int, workers: Int) => + ("Workers: " + workers) |: ("Value: " + i) |: ("Times: " + times) |: + { + val initial = Task(0) map(identity[Int]) + def task = ( initial /: (0 until times) )( (t,ignore) => t.map(_ + i)) + checkResult(TaskRunner(task, workers), i*times) } - ) - specify("evaluates chained mapped task", (i: Int, times: Int, workers: Int) => - (workers > 0 && times >= 0) ==> { - ("Workers: " + workers) |: ("Value: " + i) |: ("Times: " + times) |: - { - val initial = Task(0) map(identity[Int]) - def task = ( initial /: (0 until times) )( (t,ignore) => t.map(_ + i)) - checkResult(TaskRunner(task, workers), i*times) - } - } - ) + } - specify("evaluates simple bind", (i: Int, times: Int, workers: Int) => - (workers > 0) ==> { - ("Workers: " + workers) |: ("Value: " + i) |: ("Times: " + times) |: - { - def result = TaskRunner(Task(i).bind(x => Task(x*times)), workers) - checkResult(result, i*times) - } + property("evaluates simple bind") = forAll(iGen, MaxTasksGen, MaxWorkersGen) { (i: Int, times: Int, workers: Int) => + ("Workers: " + workers) |: ("Value: " + i) |: ("Times: " + times) |: + { + def result = TaskRunner(Task(i).bind(x => Task(x*times)), workers) + checkResult(result, i*times) } - ) + } } \ No newline at end of file diff --git a/tasks/src/test/scala/TestRunnerCall.scala b/tasks/src/test/scala/TestRunnerCall.scala index 2d62084f5..2b8549937 100644 --- a/tasks/src/test/scala/TestRunnerCall.scala +++ b/tasks/src/test/scala/TestRunnerCall.scala @@ -2,11 +2,12 @@ import xsbt._ import org.scalacheck._ import Prop._ +import TaskGen._ object TaskRunnerCallTest extends Properties("TaskRunner Call") { - specify("calculates fibonacci", (i: Int, workers: Int) => - (workers > 0 && i > 0) ==> { + property("calculates fibonacci") = forAll(MaxTasksGen, MaxWorkersGen) { (i: Int, workers: Int) => + (i > 0) ==> { val f = fibDirect(i) ("Workers: " + workers) |: ("i: " + i) |: ("fib(i): " + f) |: { @@ -14,7 +15,7 @@ object TaskRunnerCallTest extends Properties("TaskRunner Call") checkResult(result, f) } } - ) + } final def fibTask(i: Int) = { require(i > 0) diff --git a/tasks/src/test/scala/TestRunnerSort.scala b/tasks/src/test/scala/TestRunnerSort.scala index c4138d2be..8ea0c4e75 100644 --- a/tasks/src/test/scala/TestRunnerSort.scala +++ b/tasks/src/test/scala/TestRunnerSort.scala @@ -2,20 +2,20 @@ import xsbt._ import org.scalacheck._ import Prop._ +import TaskGen._ object TaskRunnerSortTest extends Properties("TaskRunnerSort") { - specify("sort", (a: Array[Int], workers: Int) => - (workers > 0) ==> { - val sorted = a.toArray - java.util.Arrays.sort(sorted) - ("Workers: " + workers) |: ("Array: " + a.toList) |: - { - def result = TaskRunner( sort(a.toArray), workers) - checkResult(result.toList, sorted.toList) - } + property("sort") = forAll(TaskListGen, MaxWorkersGen) { (list: List[Int], workers: Int) => + val a = list.toArray + val sorted = a.toArray + java.util.Arrays.sort(sorted) + ("Workers: " + workers) |: ("Array: " + a.toList) |: + { + def result = TaskRunner( sort(a.toArray), workers) + checkResult(result.toList, sorted.toList) } - ) + } final def sortDirect(a: RandomAccessSeq[Int]): RandomAccessSeq[Int] = { if(a.length < 2)