diff --git a/.drone.yml b/.drone.yml index 2cbbadfdddbd..62cffc3435c2 100644 --- a/.drone.yml +++ b/.drone.yml @@ -14,13 +14,6 @@ pipeline: # TESTS: # We run tests in parallel. Tests run in a copy of the working directory to avoid conflict - test_legacy: - group: test - image: lampepfl/dotty:2018-01-17 - commands: - - cp -R . /tmp/0/ && cd /tmp/0/ - - ./project/scripts/sbt legacyTests - test: group: test image: lampepfl/dotty:2018-01-17 diff --git a/compiler/test/dotc/tests.scala b/compiler/test/dotc/tests.scala deleted file mode 100644 index 5123cb34a841..000000000000 --- a/compiler/test/dotc/tests.scala +++ /dev/null @@ -1,389 +0,0 @@ -package dotc - -import dotty.Jars -import dotty.LegacyTests -import dotty.tools.dotc.CompilerTest -import dotty.tools.StdLibSources -import org.junit.experimental.categories.Category -import org.junit.{Before, Test} -import org.junit.Assert._ - -import java.io.{ File => JFile } -import dotty.tools.io.Directory -import scala.io.Source - -/** WARNING - * ======= - * These are legacy, do not add tests here, see `CompilationTests.scala` - */ -@Category(Array(classOf[LegacyTests])) -class tests extends CompilerTest { - - // tests that match regex '(pos|dotc|run|java|compileStdLib)\.*' would be - // executed as benchmarks. - - val defaultOutputDir = "out/" - - val noCheckOptions = List( -// "-verbose", -// "-Ylog:frontend", -// "-Xprompt", -// "-explaintypes", -// "-Yshow-suppressed-errors", - "-pagewidth", "120", - "-d", defaultOutputDir - ) - - val checkOptions = List( - "-Yno-deep-subtypes", - "-Yno-double-bindings", - "-Yforce-sbt-phases", - "-color:never" - ) - - val classPath = { - val paths = Jars.dottyTestDeps map { p => - val file = new JFile(p) - assert( - file.exists, - s"""|File "$p" couldn't be found. Run `packageAll` from build tool before - |testing. - | - |If running without sbt, test paths need to be setup environment variables: - | - | - DOTTY_LIBRARY - | - DOTTY_COMPILER - | - DOTTY_INTERFACES - | - DOTTY_EXTRAS - | - |Where these all contain locations, except extras which is a colon - |separated list of jars. - | - |When compiling with eclipse, you need the sbt-interfaces jar, put - |it in extras.""" - ) - file.getAbsolutePath - } mkString (":") - - List("-classpath", paths) - } - - implicit val defaultOptions: List[String] = noCheckOptions ++ { - if (dotty.Properties.isRunByDrone) List("-Ycheck:tailrec,resolveSuper,erasure,mixin,getClass,elimStaticThis,labelDef") // should be Ycheck:all, but #725 - else List("-Ycheck:tailrec,resolveSuper,mixin,elimStaticThis,labelDef,simplify") - } ++ checkOptions ++ classPath - - val testPickling = List("-Xprint-types", "-Ytest-pickler", "-Ystop-after:pickler", "-Yprint-pos", "-Yprint-pos-syms") - - val twice = List("#runs", "2") - val staleSymbolError: List[String] = List() - - val allowDeepSubtypes = defaultOptions diff List("-Yno-deep-subtypes") - val allowDoubleBindings = defaultOptions diff List("-Yno-double-bindings") - val scala2mode = List("-language:Scala2") - - val explicitUTF8 = List("-encoding", "UTF8") - val explicitUTF16 = List("-encoding", "UTF16") - - val testsDir = "tests/" - val posDir = testsDir + "pos/" - val posSpecialDir = testsDir + "pos-special/" - val posScala2Dir = testsDir + "pos-scala2/" - val negDir = testsDir + "neg/" - val runDir = testsDir + "run/" - val newDir = testsDir + "new/" - val javaDir = testsDir + "pos-java-interop/" - - val sourceDir = "compiler/src/" - val dottyDir = sourceDir + "dotty/" - val toolsDir = dottyDir + "tools/" - val backendDir = toolsDir + "backend/" - val dotcDir = toolsDir + "dotc/" - val coreDir = dotcDir + "core/" - val parsingDir = dotcDir + "parsing/" - val dottyReplDir = dotcDir + "repl/" - val typerDir = dotcDir + "typer/" - val libDir = "library/src/" - - def dottyBootedLib = compileDir(libDir, ".", List("-deep", "-Ycheck-reentrant", "-strict"))(allowDeepSubtypes) // note the -deep argument - def dottyDependsOnBootedLib = compileDir(dottyDir, ".", List("-deep", "-Ycheck-reentrant"))(allowDeepSubtypes) // note the -deep argument - - @Before def cleanup(): Unit = { - // remove class files from stdlib and tests compilation - Directory(defaultOutputDir + "scala").deleteRecursively() - Directory(defaultOutputDir + "java").deleteRecursively() - Directory(defaultOutputDir).createDirectory() - } - - @Test def pickle_pickleOK = compileFiles(testsDir + "pickling/", testPickling) -// This directory doesn't exist anymore -// @Test def pickle_pickling = compileDir(coreDir, "pickling", testPickling) - @Test def pickle_ast = compileDir(dotcDir, "ast", testPickling) - @Test def pickle_inf = compileFile(posDir, "pickleinf", testPickling) - - //@Test def pickle_core = compileDir(dotcDir, "core", testPickling, xerrors = 2) // two spurious comparison errors in Types and TypeOps - - @Test def pos_arraycopy = - compileFile(runDir, "arraycopy", List("-Ylog-classpath")) - @Test def pos_t2168_pat = compileFile(posDir, "t2168", twice) - @Test def pos_erasure = compileFile(posDir, "erasure", twice) - @Test def pos_Coder() = compileFile(posDir, "Coder", twice) - @Test def pos_blockescapes() = compileFile(posDir, "blockescapes", twice) - @Test def pos_collections() = compileFile(posDir, "collections", twice) - @Test def pos_functions1() = compileFile(posDir, "functions1", twice) - @Test def pos_implicits1() = compileFile(posDir, "implicits1", twice) - @Test def pos_inferred() = compileFile(posDir, "inferred", twice) - @Test def pos_Patterns() = compileFile(posDir, "Patterns", twice) - @Test def pos_selftypes() = compileFile(posDir, "selftypes", twice) - @Test def pos_varargs() = compileFile(posDir, "varargs", twice) - @Test def pos_vararg_patterns() = compileFile(posDir, "vararg-pattern", twice) - @Test def pos_opassign() = compileFile(posDir, "opassign", twice) - @Test def pos_typedapply() = compileFile(posDir, "typedapply", twice) - @Test def pos_nameddefaults() = compileFile(posDir, "nameddefaults", twice) - @Test def pos_desugar() = compileFile(posDir, "desugar", twice) - @Test def pos_sigs() = compileFile(posDir, "sigs", twice) - @Test def pos_typers() = compileFile(posDir, "typers", twice) - @Test def pos_typedIdents() = compileDir(posDir, "typedIdents", twice) - @Test def pos_assignments() = compileFile(posDir, "assignments", twice) - @Test def pos_packageobject() = compileFile(posDir, "packageobject", twice) - @Test def pos_overloaded() = compileFile(posDir, "overloaded", twice) - @Test def pos_overrides() = compileFile(posDir, "overrides", twice) - @Test def pos_javaOverride() = compileDir(posDir, "java-override", twice) - @Test def pos_templateParents() = compileFile(posDir, "templateParents", twice) - @Test def pos_overloadedAccess = compileFile(posDir, "overloadedAccess", twice) - @Test def pos_approximateUnion = compileFile(posDir, "approximateUnion", twice) - @Test def pos_tailcall = compileDir(posDir, "tailcall", twice) - @Test def pos_valueclasses = compileFiles(posDir + "pos_valueclasses/", twice) - @Test def pos_nullarify = compileFile(posDir, "nullarify", args = "-Ycheck:nullarify" :: Nil) - @Test def pos_subtyping = compileFile(posDir, "subtyping", twice) - @Test def pos_packageObj = compileFile(posDir, "i0239", twice) - @Test def pos_anonClassSubtyping = compileFile(posDir, "anonClassSubtyping", twice) - @Test def pos_extmethods = compileFile(posDir, "extmethods", twice) - @Test def pos_companions = compileFile(posDir, "companions", twice) - @Test def posVarargsT1625 = compileFiles(posDir + "varargsInMethodsT1625/") - - @Test def pos_all = compileFiles(posDir) // twice omitted to make tests run faster - - @Test def pos_scala2_all = compileFiles(posScala2Dir, scala2mode) - - @Test def rewrites = compileFile(posScala2Dir, "rewrites", "-rewrite" :: scala2mode) - - @Test def pos_jon = compileFile(posSpecialDir, "jon")(allowDeepSubtypes) - - @Test def pos_t5545 = { - // compile by hand in two batches, since junit lacks the infrastructure to - // compile files in multiple batches according to _1, _2, ... suffixes. - compileFile(posSpecialDir, "spec-t5545/S_1") - compileFile(posSpecialDir, "spec-t5545/S_2") - } - @Test def pos_utf8 = compileFile(posSpecialDir, "utf8encoded", explicitUTF8) - @Test def pos_utf16 = compileFile(posSpecialDir, "utf16encoded", explicitUTF16) - - @Test def new_all = compileFiles(newDir, twice) - - @Test def neg_all = compileFiles(negDir, verbose = true, compileSubDirs = false) - @Test def neg_typedIdents() = compileDir(negDir, "typedIdents") - - @Test def negVarargsT1625 = compileFiles(negDir + "varargsInMethodsT1625/") - - val negCustomArgs = testsDir + "neg-custom-args/" - val negAllowDoubleBindings = negCustomArgs + "allow-double-bindings/" - - @Test def neg_typers() = compileFile(negAllowDoubleBindings, "typers")(allowDoubleBindings) - @Test def neg_overrideClass = compileFile(negCustomArgs, "overrideClass", scala2mode) - @Test def neg_autoTupling = compileFile(negCustomArgs, "autoTuplingTest", args = "-language:noAutoTupling" :: Nil) - @Test def neg_i1050 = compileFile(negCustomArgs, "i1050", List("-strict")) - @Test def neg_i1240 = compileFile(negAllowDoubleBindings, "i1240")(allowDoubleBindings) - @Test def neg_i2002 = compileFile(negAllowDoubleBindings, "i2002")(allowDoubleBindings) - @Test def neg_valueclasses_doubledefs = compileFile(negCustomArgs, "valueclasses-doubledefs")(allowDoubleBindings) - @Test def neg_valueclasses_pavlov = compileFile(negCustomArgs, "valueclasses-pavlov")(allowDoubleBindings) - @Test def neg_trailingUnderscore = compileFile(negCustomArgs, "trailingUnderscore", args = "-strict" :: Nil) - - val negTailcallDir = testsDir + "neg-tailcall/" - @Test def neg_tailcall_t1672b = compileFile(negTailcallDir, "t1672b") - @Test def neg_tailcall_t3275 = compileFile(negTailcallDir, "t3275") - @Test def neg_tailcall_t6574 = compileFile(negTailcallDir, "t6574") - @Test def neg_tailcall = compileFile(negTailcallDir, "tailrec") - @Test def neg_tailcall2 = compileFile(negTailcallDir, "tailrec-2") - @Test def neg_tailcall3 = compileFile(negTailcallDir, "tailrec-3") - - @Test def neg_nopredef = compileFile(negCustomArgs, "nopredef", List("-Yno-predef")) - @Test def neg_noimports = compileFile(negCustomArgs, "noimports", List("-Yno-imports")) - @Test def neg_noimpots2 = compileFile(negCustomArgs, "noimports2", List("-Yno-imports")) - - @Test def run_all = runFiles(runDir) - - private val stdlibFiles: List[String] = StdLibSources.whitelisted - - @Test def compileStdLib = - compileList("compileStdLib", stdlibFiles, "-migration" :: "-Yno-inline" :: scala2mode) - - @Test def compileMixed = compileLine( - """tests/pos/B.scala - |scala2-library/src/library/scala/collection/immutable/Seq.scala - |scala2-library/src/library/scala/collection/parallel/ParSeq.scala - |scala2-library/src/library/scala/package.scala - |scala2-library/src/library/scala/collection/GenSeqLike.scala - |scala2-library/src/library/scala/collection/SeqLike.scala - |scala2-library/src/library/scala/collection/generic/GenSeqFactory.scala""".stripMargin)(scala2mode ++ defaultOptions) - @Test def compileIndexedSeq = compileLine("scala2-library/src/library/scala/collection/immutable/IndexedSeq.scala") - @Test def compileParSetLike = compileLine("scala2-library/src/library/scala/collection/parallel/mutable/ParSetLike.scala") - @Test def compileParSetSubset = compileLine( - """scala2-library/src/library/scala/collection/parallel/mutable/ParSetLike.scala - |scala2-library/src/library/scala/collection/parallel/mutable/ParSet.scala - |scala2-library/src/library/scala/collection/mutable/SetLike.scala""".stripMargin)(scala2mode ++ defaultOptions) - - @Test def dottyBooted = { - dottyBootedLib - dottyDependsOnBootedLib - } - - @Test def dotc_ast = compileDir(dotcDir, "ast") - @Test def dotc_config = compileDir(dotcDir, "config") - @Test def dotc_core = compileDir(dotcDir, "core")(allowDeepSubtypes)// twice omitted to make tests run faster - @Test def dotc_core_nocheck = compileDir(dotcDir, "core")(noCheckOptions ++ classPath) - -// This directory doesn't exist anymore -// @Test def dotc_core_pickling = compileDir(coreDir, "pickling")(allowDeepSubtypes)// twice omitted to make tests run faster - - @Test def dotc_transform = compileDir(dotcDir, "transform")(allowDeepSubtypes)// twice omitted to make tests run faster - - @Test def dotc_parsing = compileDir(dotcDir, "parsing") // twice omitted to make tests run faster - - @Test def dotc_printing = compileDir(dotcDir, "printing") // twice omitted to make tests run faster - - @Test def dotc_reporting = compileDir(dotcDir, "reporting") // twice omitted to make tests run faster - - @Test def dotc_typer = compileDir(dotcDir, "typer")// twice omitted to make tests run faster - // error: error while loading Checking$$anon$2$, - // class file 'target/scala-2.11/dotty_2.11-0.1.1-bin-SNAPSHOT.jar(dotty/tools/dotc/typer/Checking$$anon$2.class)' - // has location not matching its contents: contains class $anon - - @Test def dotc_util = compileDir(dotcDir, "util") // twice omitted to make tests run faster - - @Test def tools_io = compileDir(toolsDir, "io") // inner class has symbol - - @Test def helloWorld = compileFile(posDir, "HelloWorld") - @Test def labels = compileFile(posDir, "Labels", twice) - //@Test def tools = compileDir(dottyDir, "tools", "-deep" :: Nil)(allowDeepSubtypes) - - @Test def testNonCyclic = compileList("testNonCyclic", List( - dotcDir + "CompilationUnit.scala", - coreDir + "Types.scala", - dotcDir + "ast/Trees.scala" - ), List("-Xprompt") ++ staleSymbolError ++ twice) - - @Test def testIssue_34 = compileList("testIssue_34", List( - dotcDir + "config/Properties.scala", - dotcDir + "config/PathResolver.scala" - ), List(/* "-Ylog:frontend", */ "-Xprompt") ++ staleSymbolError ++ twice) - - @Test def java_all = compileFiles(javaDir, twice) - //@Test def dotc_compilercommand = compileFile(dotcDir + "config/", "CompilerCommand") - - //TASTY tests - @Test def tasty_new_all = compileFiles(newDir, testPickling) - - @Test def tasty_dotty = compileDir(sourceDir, "dotty", testPickling) - - // Disabled because we get stale symbol errors on the SourceFile annotation, which is normal. - // @Test def tasty_annotation_internal = compileDir(s"${dottyDir}annotation/", "internal", testPickling) - - @Test def tasty_runtime = compileDir(s"${libDir}dotty/", "runtime", testPickling) - @Test def tasty_runtime_vc = compileDir(s"${libDir}dotty/runtime/", "vc", testPickling) - - @Test def tasty_tools = compileDir(dottyDir, "tools", testPickling) - - //TODO: issue with ./src/dotty/tools/backend/jvm/DottyBackendInterface.scala - @Test def tasty_backend_jvm = compileList("tasty_backend_jvm", List( - "CollectEntryPoints.scala", "GenBCode.scala", "LabelDefs.scala", - "scalaPrimitives.scala" - ) map (s"${backendDir}jvm/" + _), testPickling) - - //@Test def tasty_backend_sjs = compileDir(s"${backendDir}", "sjs", testPickling) - - @Test def tasty_dotc = compileDir(toolsDir, "dotc", testPickling) - @Test def tasty_dotc_ast = compileDir(dotcDir, "ast", testPickling) - @Test def tasty_dotc_config = compileDir(dotcDir, "config", testPickling) - - //TODO: issue with ./src/dotty/tools/dotc/core/Types.scala - @Test def tasty_core = compileList("tasty_core", List( - "Annotations.scala", "Constants.scala", "Constraint.scala", "ConstraintHandling.scala", - "ConstraintRunInfo.scala", "Contexts.scala", "Decorators.scala", "Definitions.scala", - "DenotTransformers.scala", "Denotations.scala", "Flags.scala", "Hashable.scala", - "NameOps.scala", "Names.scala", "OrderingConstraint.scala", "Periods.scala", - "Phases.scala", "Scopes.scala", "Signature.scala", "StdNames.scala", - "Substituters.scala", "SymDenotations.scala", "SymbolLoaders.scala", "Symbols.scala", - "TypeApplications.scala", "TypeComparer.scala", "TypeErasure.scala", "TypeOps.scala", - "TyperState.scala", "Uniques.scala" - ) map (coreDir + _), testPickling) - - @Test def tasty_classfile = compileDir(coreDir, "classfile", testPickling) - @Test def tasty_tasty = compileDir(coreDir, "tasty", testPickling) - @Test def tasty_unpickleScala2 = compileDir(coreDir, "unpickleScala2", testPickling) - - //TODO: issue with ./src/dotty/tools/dotc/parsing/Parsers.scala - @Test def tasty_dotc_parsing = compileList("tasty_dotc_parsing", List( - "CharArrayReader.scala", "JavaParsers.scala", "JavaScanners.scala", "JavaTokens.scala", - "MarkupParserCommon.scala", "MarkupParsers.scala", "package.scala" ,"Scanners.scala", - "ScriptParsers.scala", "SymbolicXMLBuilder.scala", "Tokens.scala", "Utility.scala" - ) map (parsingDir + _), testPickling) - - @Test def tasty_dotc_printing = compileDir(dotcDir, "printing", testPickling) - - @Test def tasty_dotc_repl = compileDir(dotcDir, "repl", testPickling) - - //@Test def tasty_dotc_reporting = compileDir(dotcDir, "reporting", testPickling) - @Test def tasty_dotc_rewrite = compileDir(dotcDir, "rewrite", testPickling) - - //TODO: issues with LazyVals.scala, PatternMatcher.scala - @Test def tasty_dotc_transform = compileList("tasty_dotc_transform", List( - "AugmentScala2Traits.scala", "CapturedVars.scala", "CheckReentrant.scala", "CheckStatic.scala", - "ClassOf.scala", "CollectEntryPoints.scala", "Constructors.scala", "CrossCastAnd.scala", - "CtxLazy.scala", "ElimByName.scala", "ElimErasedValueType.scala", "ElimRepeated.scala", - "ElimStaticThis.scala", "Erasure.scala", "ExpandPrivate.scala", "ExpandSAMs.scala", - "ExplicitOuter.scala", "ExtensionMethods.scala", "FirstTransform.scala", - "Flatten.scala", "FullParameterization.scala", "FunctionalInterfaces.scala", "GetClass.scala", - "Getters.scala", "InterceptedMethods.scala", "LambdaLift.scala", "LiftTry.scala", "LinkScala2Impls.scala", - "MacroTransform.scala", "Memoize.scala", "Mixin.scala", "MixinOps.scala", "NonLocalReturns.scala", - "NormalizeFlags.scala", "OverridingPairs.scala", "ParamForwarding.scala", "Pickler.scala", "PostTyper.scala", - "ResolveSuper.scala", "RestoreScopes.scala", "SeqLiterals.scala", "Splitter.scala", "SuperAccessors.scala", - "SymUtils.scala", "SyntheticMethods.scala", "TailRec.scala", "TreeChecker.scala", "TreeExtractors.scala", - "TreeGen.scala", "MegaPhase.scala", "TypeTestsCasts.scala", "TypeUtils.scala", "ValueClasses.scala", - "VCElideAllocations.scala", "VCInlineMethods.scala" - ) map (s"${dotcDir}transform/" + _), testPickling) - - //TODO: issue with ./src/dotty/tools/dotc/typer/Namer.scala - @Test def tasty_typer = compileList("tasty_typer", List( - "Applications.scala", "Checking.scala", "ConstFold.scala", "ErrorReporting.scala", - "EtaExpansion.scala", "FrontEnd.scala", "Implicits.scala", "ImportInfo.scala", - "Inferencing.scala", "ProtoTypes.scala", "ReTyper.scala", "RefChecks.scala", - "TypeAssigner.scala", "Typer.scala", "VarianceChecker.scala", "Variances.scala" - ) map (typerDir + _), testPickling) - - @Test def tasty_dotc_util = compileDir(dotcDir, "util", testPickling) - @Test def tasty_tools_io = compileDir(toolsDir, "io", testPickling) - - // Disabled, not worth porting since we're getting rid of the old JUnit tests soon. - /*@Test*/ def tasty_bootstrap = { - val logging = if (false) List("-Ylog-classpath", "-verbose") else Nil - val opt = List("-priorityclasspath", defaultOutputDir) ++ logging - // first compile dotty - compileDir(dottyDir, ".", List("-deep", "-Ycheck-reentrant", "-strict") ++ logging)(allowDeepSubtypes) - - compileDir(libDir, "dotty", "-deep" :: opt) - compileDir(libDir, "scala", "-deep" :: opt) - compileDir(dottyDir, "tools", opt) - compileDir(toolsDir, "dotc", opt) - compileDir(dotcDir, "ast", opt) - compileDir(dotcDir, "config", opt) - compileDir(dotcDir, "parsing", opt) - compileDir(dotcDir, "printing", opt) - compileDir(dotcDir, "repl", opt) - compileDir(dotcDir, "reporting", opt) - compileDir(dotcDir, "rewrite", opt) - compileDir(dotcDir, "transform", opt) - compileDir(dotcDir, "typer", opt) - compileDir(dotcDir, "util", opt) - } -} diff --git a/compiler/test/dotty/TestCategories.scala b/compiler/test/dotty/TestCategories.scala index b411fac93ade..d7a011719637 100644 --- a/compiler/test/dotty/TestCategories.scala +++ b/compiler/test/dotty/TestCategories.scala @@ -3,5 +3,5 @@ package dotty /** SlowTest category for JUnit */ trait SlowTests -/** Legacy tests category for JUnit */ -trait LegacyTests +/** Meta tests category for JUnit */ +trait VulpixMetaTests diff --git a/compiler/test/dotty/tools/dotc/CompilerTest.scala b/compiler/test/dotty/tools/dotc/CompilerTest.scala deleted file mode 100644 index 2a3b3253742e..000000000000 --- a/compiler/test/dotty/tools/dotc/CompilerTest.scala +++ /dev/null @@ -1,438 +0,0 @@ -package dotty.tools.dotc - -import core.Contexts._ -import interfaces.Diagnostic.ERROR -import reporting._ -import diagnostic.MessageContainer -import util.SourcePosition -import config.CompilerCommand -import dotty.tools.io.{PlainFile, Path} -import scala.collection.mutable.ListBuffer -import dotty.tools.io.{ Path, Directory, File => SFile, AbstractFile } -import scala.annotation.tailrec -import java.io.{ RandomAccessFile, File => JFile } - - -/** Legacy compiler tests that run single threaded */ -abstract class CompilerTest { - - /** Override with output dir of test so it can be patched. Partest expects - * classes to be in partest-generated/[kind]/[testname]-[kind].obj/ */ - val defaultOutputDir: String - - /** Override to filter out tests that should not be run by partest. */ - def partestableFile(prefix: String, fileName: String, extension: String, args: List[String]) = true - def partestableDir(prefix: String, dirName: String, args: List[String]) = true - def partestableList(testName: String, files: List[String], args: List[String]) = true - - /** Always run with JUnit. */ - def compileLine(cmdLine: String)(implicit defaultOptions: List[String]): Unit = - compileArgs(cmdLine.split("\n"), Nil) - - /** Compiles the given code file. - * - * @param prefix the parent directory (including separator at the end) - * @param fileName the filename, by default without extension - * @param args arguments to the compiler - * @param extension the file extension, .scala by default - * @param defaultOptions more arguments to the compiler - */ - def compileFile(prefix: String, fileName: String, args: List[String] = Nil, extension: String = ".scala", runTest: Boolean = false) - (implicit defaultOptions: List[String]): Unit = { - val filePath = s"$prefix$fileName$extension" - val expErrors = expectedErrors(filePath) - if (runTest) - log(s"WARNING: run tests can only be run by partest, JUnit just verifies compilation: $prefix$fileName$extension") - if (args.contains("-rewrite")) { - val file = new PlainFile(Path(filePath)) - val data = file.toByteArray - // compile with rewrite - compileArgs((filePath :: args).toArray, expErrors) - // compile again, check that file now compiles without -language:Scala2 - val plainArgs = args.filter(arg => arg != "-rewrite" && arg != "-language:Scala2") - compileFile(prefix, fileName, plainArgs, extension, runTest) - // restore original test file - val out = file.output - out.write(data) - out.close() - } - else compileArgs((filePath :: args).toArray, expErrors) - } - def runFile(prefix: String, fileName: String, args: List[String] = Nil, extension: String = ".scala") - (implicit defaultOptions: List[String]): Unit = { - compileFile(prefix, fileName, args, extension, true) - } - - def findJarFromRuntime(partialName: String): String = { - val urls = ClassLoader.getSystemClassLoader.asInstanceOf[java.net.URLClassLoader].getURLs.map(_.getFile.toString) - urls.find(_.contains(partialName)).getOrElse { - throw new java.io.FileNotFoundException( - s"""Unable to locate $partialName on classpath:\n${urls.toList.mkString("\n")}""" - ) - } - } - - private def compileWithJavac( - fs: Array[String], - args: Array[String] - )(implicit defaultOptions: List[String]): Boolean = { - val scalaLib = dotty.Jars.scalaLibrary - val fullArgs = Array( - "javac", - "-classpath", - s".:$scalaLib" - ) ++ args ++ defaultOptions.dropWhile("-d" != _).take(2) ++ fs - - Runtime.getRuntime.exec(fullArgs).waitFor() == 0 - } - - /** Compiles the code files in the given directory together. If args starts - * with "-deep", all files in subdirectories (and so on) are included. */ - def compileDir(prefix: String, dirName: String, args: List[String] = Nil, runTest: Boolean = false) - (implicit defaultOptions: List[String]): Unit = { - def computeFilePathsAndExpErrors = { - val dir = Directory(prefix + dirName) - val (files, normArgs) = args match { - case "-deep" :: args1 => (dir.deepFiles, args1) - case _ => (dir.files, args) - } - val (filePaths, javaFilePaths) = files - .toArray.map(_.toString) - .foldLeft((Array.empty[String], Array.empty[String])) { case (acc @ (fp, jfp), name) => - if (name endsWith ".scala") (name +: fp, jfp) - else if (name endsWith ".java") (fp, name +: jfp) - else (fp, jfp) - } - val expErrors = expectedErrors(filePaths.toList) - (filePaths.sorted, javaFilePaths.sorted, normArgs, expErrors) - } - if (runTest) - log(s"WARNING: run tests can only be run by partest, JUnit just verifies compilation: $prefix$dirName") - val (filePaths, javaFilePaths, normArgs, expErrors) = computeFilePathsAndExpErrors - if (filePaths.exists(_.endsWith("_1.scala"))) { - log(s"WARNING: separate compilation test can not be run as legacy test: $prefix$dirName") - } else { - compileWithJavac(javaFilePaths, Array.empty) // javac needs to run first on dotty-library - compileArgs(javaFilePaths ++ filePaths ++ normArgs, expErrors) - } - } - def runDir(prefix: String, dirName: String, args: List[String] = Nil) - (implicit defaultOptions: List[String]): Unit = - compileDir(prefix, dirName, args, true) - - /** Compiles each source in the directory path separately by calling - * compileFile resp. compileDir. */ - def compileFiles(path: String, args: List[String] = Nil, verbose: Boolean = true, runTest: Boolean = false, - compileSubDirs: Boolean = true)(implicit defaultOptions: List[String]): Unit = { - val dir = Directory(path) - val fileNames = dir.files.toArray.map(_.name).filter(name => (name endsWith ".scala") || (name endsWith ".java")) - for (name <- fileNames) { - if (verbose) log(s"testing $path$name") - compileFile(path, name, args, "", runTest) - } - if (compileSubDirs) - for (subdir <- dir.dirs) { - if (verbose) log(s"testing $subdir") - compileDir(path, subdir.name, args, runTest) - } - } - def runFiles(path: String, args: List[String] = Nil, verbose: Boolean = true) - (implicit defaultOptions: List[String]): Unit = - compileFiles(path, args, verbose, true) - - /** Compiles the given list of code files. */ - def compileList(testName: String, files: List[String], args: List[String] = Nil) - (implicit defaultOptions: List[String]): Unit = { - val expErrors = expectedErrors(files) - compileArgs((files ++ args).toArray, expErrors) - } - - // ========== HELPERS ============= - - private def expectedErrors(filePaths: List[String]): List[ErrorsInFile] = if (filePaths.exists(isNegTest(_))) filePaths.map(getErrors(_)) else Nil - - private def expectedErrors(filePath: String): List[ErrorsInFile] = expectedErrors(List(filePath)) - - private def isNegTest(testPath: String) = - testPath.contains("/neg/") || testPath.contains("/neg-custom-args/") || testPath.contains("/neg-tailcall/") - - private def compileArgs(args: Array[String], expectedErrorsPerFile: List[ErrorsInFile]) - (implicit defaultOptions: List[String]): Unit = { - val allArgs = args ++ defaultOptions - val verbose = allArgs.contains("-verbose") - //println(s"""all args: ${allArgs.mkString("\n")}""") - val processor = if (allArgs.exists(_.startsWith("#"))) Bench else Main - val storeReporter = new Reporter with UniqueMessagePositions with HideNonSensicalMessages { - private val consoleReporter = new ConsoleReporter() - private val innerStoreReporter = new StoreReporter(consoleReporter) - def doReport(m: MessageContainer)(implicit ctx: Context): Unit = { - if (m.level == ERROR || verbose) { - innerStoreReporter.flush() - consoleReporter.doReport(m) - } - else if (errorCount > 0) consoleReporter.doReport(m) - else innerStoreReporter.doReport(m) - } - } - val reporter = processor.process(allArgs, storeReporter) - - val nerrors = reporter.errorCount - val xerrors = (expectedErrorsPerFile map {_.totalErrors}).sum - def expectedErrorFiles = - expectedErrorsPerFile.collect{ - case er if er.totalErrors > 0 => er.fileName - } - assert(nerrors == xerrors, - s"""Wrong # of errors. Expected: $xerrors, found: $nerrors - |Files with expected errors: $expectedErrorFiles - |errors: - """.stripMargin) - // NEG TEST - if (xerrors > 0) { - val errorLines = reporter.allErrors.map(_.pos) - // reporter didn't record as many errors as its errorCount says - assert(errorLines.length == nerrors, s"Not enough errors recorded.") - - // Some compiler errors have an associated source position. Each error - // needs to correspond to a "// error" marker on that line in the source - // file and vice versa. - // Other compiler errors don't have an associated source position. Their - // number should correspond to the total count of "// nopos-error" - // markers in all files - val (errorsByFile, errorsWithoutPos) = errorLines.groupBy(_.source.file).toList.partition(_._1.toString != "") - - // check errors with source position - val foundErrorsPerFile = errorsByFile.map({ case (fileName, errorList) => - val posErrorLinesToNr = errorList.groupBy(_.line).toList.map({ case (line, list) => (line, list.length) }).sortBy(_._1) - ErrorsInFile(fileName.toString, 0, posErrorLinesToNr) - }) - val expectedErrorsPerFileZeroed = expectedErrorsPerFile.map({ - case ErrorsInFile(fileName, _, posErrorLinesToNr) => - ErrorsInFile(fileName.toString, 0, posErrorLinesToNr) - }) - checkErrorsWithPosition(expectedErrorsPerFileZeroed, foundErrorsPerFile) - - // check errors without source position - val expectedNoPos = expectedErrorsPerFile.map(_.noposErrorNr).sum - val foundNoPos = errorsWithoutPos.map(_._2.length).sum - assert(foundNoPos == expectedNoPos, - s"Wrong # of errors without source position. Expected (all files): $expectedNoPos, found (compiler): $foundNoPos") - } - } - - // ========== NEG TEST HELPERS ============= - - /** Captures the number of nopos-errors in the given file and the number of - * errors with a position, represented as a tuple of source line and number - * of errors on that line. */ - case class ErrorsInFile(fileName: String, noposErrorNr: Int, posErrorLinesToNr: List[(Int, Int)]) { - def totalErrors = noposErrorNr + posErrorLinesToNr.map(_._2).sum - } - - /** Extracts the errors expected for the given neg test file. */ - def getErrors(fileName: String): ErrorsInFile = { - val content = SFile(fileName).slurp() - val (line, rest) = content.span(_ != '\n') - - @tailrec - def checkLine(line: String, rest: String, index: Int, noposAcc: Int, posAcc: List[(Int, Int)]): ErrorsInFile = { - val posErrors = "// ?error".r.findAllIn(line).length - val newPosAcc = if (posErrors > 0) (index, posErrors) :: posAcc else posAcc - val newNoPosAcc = noposAcc + "// ?nopos-error".r.findAllIn(line).length - val (newLine, newRest) = rest.span(_ != '\n') - if (newRest.isEmpty) - ErrorsInFile(fileName.toString, newNoPosAcc, newPosAcc.reverse) - else - checkLine(newLine, newRest.tail, index + 1, newNoPosAcc, newPosAcc) // skip leading '\n' - } - - checkLine(line, rest.tail, 0, 0, Nil) // skip leading '\n' - } - - /** Asserts that the expected and found number of errors correspond, and - * otherwise throws an error with the filename, plus optionally a line - * number if available. */ - def errorMsg(fileName: String, lineNumber: Option[Int], exp: Int, found: Int) = { - val i = lineNumber.map({ i => ":" + (i + 1) }).getOrElse("") - assert(found == exp, s"Wrong # of errors for $fileName$i. Expected (file): $exp, found (compiler): $found") - } - - /** Compares the expected with the found errors and creates a nice error - * message if they don't agree. */ - def checkErrorsWithPosition(expected: List[ErrorsInFile], found: List[ErrorsInFile]): Unit = { - // create nice error messages - expected.diff(found) match { - case Nil => // nothing missing - case ErrorsInFile(fileName, _, expectedLines) :: xs => - found.find(_.fileName == fileName) match { - case None => - // expected some errors, but none found for this file - errorMsg(fileName, None, expectedLines.map(_._2).sum, 0) - case Some(ErrorsInFile(_,_,foundLines)) => - // found wrong number/location of markers for this file - compareLines(fileName, expectedLines, foundLines) - } - } - - found.diff(expected) match { - case Nil => // nothing missing - case ErrorsInFile(fileName, _, foundLines) :: xs => - expected.find(_.fileName == fileName) match { - case None => - // found some errors, but none expected for this file - errorMsg(fileName, None, 0, foundLines.map(_._2).sum) - case Some(ErrorsInFile(_,_,expectedLines)) => - // found wrong number/location of markers for this file - compareLines(fileName, expectedLines, foundLines) - } - } - } - - /** Gives an error message for one line where the expected number of errors and - * the number of compiler errors differ. */ - def compareLines(fileName: String, expectedLines: List[(Int, Int)], foundLines: List[(Int, Int)]) = { - expectedLines foreach{ - case (line, expNr) => - foundLines.find(_._1 == line) match { - case Some((_, `expNr`)) => // this line is ok - case Some((_, foundNr)) => errorMsg(fileName, Some(line), expNr, foundNr) - case None => - println(s"expected lines = $expectedLines%, %") - println(s"found lines = $foundLines%, %") - errorMsg(fileName, Some(line), expNr, 0) - } - } - foundLines foreach { - case (line, foundNr) => - expectedLines.find(_._1 == line) match { - case Some((_, `foundNr`)) => // this line is ok - case Some((_, expNr)) => errorMsg(fileName, Some(line), expNr, foundNr) - case None => errorMsg(fileName, Some(line), 0, foundNr) - } - } - } - - // ========== PARTEST HELPERS ============= - - // In particular, don't copy flags from scalac tests - private val extensionsToCopy = scala.collection.immutable.HashSet("scala", "java") - - /** Determines what kind of test to run. */ - private def testKind(prefixDir: String, runTest: Boolean) = { - if (runTest) "run" - else if (isNegTest(prefixDir)) "neg" - else if (prefixDir.endsWith("run" + JFile.separator)) { - log("WARNING: test is being run as pos test despite being in a run directory. " + - "Use runFile/runDir instead of compileFile/compileDir to do a run test") - "pos" - } else "pos" - } - - /** The three possibilities: no generated sources exist yet, the same sources - * exist already, different sources exist. */ - object Difference extends Enumeration { - type Difference = Value - val NotExists, ExistsSame, ExistsDifferent = Value - } - import Difference._ - - /** Recursively copy over source files and directories, excluding extensions - * that aren't in extensionsToCopy. */ - private def recCopyFiles(sourceFile: Path, dest: Path): Unit = { - - @tailrec def copyfile(file: SFile, bytewise: Boolean): Unit = { - if (bytewise) { - val in = file.inputStream() - val out = dest.toFile.outputStream() - val buffer = new Array[Byte](1024) - @tailrec def loop(available: Int):Unit = { - if (available < 0) {()} - else { - out.write(buffer, 0, available) - val read = in.read(buffer) - loop(read) - } - } - loop(0) - in.close() - out.close() - } else { - try { - SFile(dest.jpath)(scala.io.Codec.UTF8).writeAll((s"/* !!!!! WARNING: DO NOT MODIFY. Original is at: $file !!!!! */").replace("\\", "/"), file.slurp("UTF-8")) - } catch { - case unmappable: java.nio.charset.MalformedInputException => - copyfile(file, true) //there are bytes that can't be mapped with UTF-8. Bail and just do a straight byte-wise copy without the warning header. - } - } - } - - processFileDir(sourceFile, { sf => - if (extensionsToCopy.contains(sf.extension)) { - dest.parent.createDirectory(force = true) - copyfile(sf, false) - } else { - log(s"WARNING: ignoring $sf") - } - }, { sdir => - dest.createDirectory(force = true) - sdir.list.foreach(path => recCopyFiles(path, dest / path.name)) - }, Some("DPCompilerTest.recCopyFiles: sourceFile not found: " + sourceFile)) - } - - /** Reads the existing files for the given test source if any. */ - private def getExisting(dest: Path): ExistingFiles = { - val content: Option[Option[String]] = processFileDir(dest, f => try Some(f.slurp("UTF8")) catch {case io: java.io.IOException => Some(io.toString())}, d => Some("")) - if (content.isDefined && content.get.isDefined) { - val flags = (dest changeExtension "flags").toFile.safeSlurp() - val nerr = (dest changeExtension "nerr").toFile.safeSlurp() - ExistingFiles(content.get, flags, nerr) - } else ExistingFiles() - } - - /** Encapsulates existing generated test files. */ - case class ExistingFiles(genSrc: Option[String] = None, flags: Option[String] = None, nerr: Option[String] = None) { - def isDifferent(sourceFile: JFile, otherFlags: List[String], otherNerr: String): Difference = { - if (!genSrc.isDefined) { - NotExists - } else { - val source = processFileDir(Path(sourceFile.toPath), { f => try Some(f.slurp("UTF8")) catch {case _: java.io.IOException => None} }, { d => Some("") }, - Some("DPCompilerTest sourceFile doesn't exist: " + sourceFile)).get - if (source == genSrc) { - nerr match { - case Some(n) if (n != otherNerr) => ExistsDifferent - case None if (otherNerr != "0") => ExistsDifferent - case _ if (flags.map(_ == otherFlags.mkString(" ")).getOrElse(otherFlags.isEmpty)) => ExistsSame - case _ => ExistsDifferent - } - } else ExistsDifferent - } - } - } - - import scala.util.matching.Regex - val nrFinder = """(.*_v)(\d+)""".r - /** Changes the version number suffix in the name (without extension). */ - private def replaceVersion(name: String, nr: Int): Option[String] = { - val nrString = nr.toString - name match { - case nrFinder(prefix, `nrString`) => Some(prefix + (nr + 1)) - case _ if nr != 0 => None - case _ => Some(name + "_v1") - } - } - - /** Returns None if the given path doesn't exist, otherwise returns Some of - * applying either processFile or processDir, depending on what the path - * refers to in the file system. If failMsgOnNone is defined, this function - * asserts that the file exists using the provided message. */ - private def processFileDir[T](input: Path, processFile: SFile => T, processDir: Directory => T, failMsgOnNone: Option[String] = None): Option[T] = { - val res = input.ifFile(f => processFile(f)).orElse(input.ifDirectory(d => processDir(d))) - (failMsgOnNone, res) match { - case (Some(msg), None) => assert(false, msg); None - case _ => res - } - } - - /** Write either to console */ - private def log(msg: String) = println(msg) -} diff --git a/compiler/test/dotty/tools/vulpix/VulpixMetaTests.scala b/compiler/test/dotty/tools/vulpix/VulpixMetaTests.scala new file mode 100644 index 000000000000..68e6989ef252 --- /dev/null +++ b/compiler/test/dotty/tools/vulpix/VulpixMetaTests.scala @@ -0,0 +1,27 @@ +package dotty.tools +package vulpix + +import org.junit.Test +import org.junit.experimental.categories.Category +import scala.concurrent.duration._ +import dotty.Properties +import TestConfiguration._ + +/** Meta tests for the Vulpix test suite. This test follows the structure of + * CompilationTests.scala. It is ment to be called from bash to diff with + * output againts an expected result. + */ +@Category(Array(classOf[dotty.VulpixMetaTests])) +class VulpixMetaTests extends ParallelTesting { + def maxDuration = 1.seconds + def numberOfSlaves = 5 + def safeMode = Properties.testsSafeMode + def isInteractive = SummaryReport.isInteractive + def testFilter = Properties.testsFilter + implicit val summaryReport: SummaryReporting = new SummaryReport + implicit def testGroup: TestGroup = TestGroup("VulpixMetaTests") + + @Test def compilePos: Unit = compileFilesInDir("tests/vulpix-tests/meta/pos", defaultOptions).checkCompile() + @Test def compileNeg: Unit = compileFilesInDir("tests/vulpix-tests/meta/neg", defaultOptions).checkExpectedErrors() + @Test def runAll: Unit = compileFilesInDir("tests/vulpix-tests/meta/run", defaultOptions).checkRuns() +} diff --git a/compiler/test/dotty/tools/vulpix/VulpixTests.scala b/compiler/test/dotty/tools/vulpix/VulpixTests.scala deleted file mode 100644 index bd4a09907141..000000000000 --- a/compiler/test/dotty/tools/vulpix/VulpixTests.scala +++ /dev/null @@ -1,84 +0,0 @@ -package dotty.tools -package vulpix - -import org.junit.Assert._ -import org.junit.Test - -import scala.concurrent.duration._ -import scala.util.control.NonFatal - -/** Meta tests for the Vulpix test suite */ -class VulpixTests extends ParallelTesting { - import TestConfiguration._ - - implicit val _: SummaryReporting = new NoSummaryReport - - implicit def testGroup: TestGroup = TestGroup("VulpixTests") - - def maxDuration = 3.seconds - def numberOfSlaves = 5 - def safeMode = sys.env.get("SAFEMODE").isDefined - def isInteractive = !sys.env.contains("DRONE") - def testFilter = None - - @Test def missingFile: Unit = - try { - compileFile("tests/partest-test/i-dont-exist.scala", defaultOptions).expectFailure.checkExpectedErrors() - fail("didn't fail properly") - } - catch { - case _: IllegalArgumentException => // pass! - case NonFatal(_) => fail("wrong exception thrown") - } - - @Test def pos1Error: Unit = - compileFile("tests/partest-test/posFail1Error.scala", defaultOptions).expectFailure.checkCompile() - - @Test def negMissingAnnot: Unit = - compileFile("tests/partest-test/negMissingAnnot.scala", defaultOptions).expectFailure.checkExpectedErrors() - - @Test def negAnnotWrongLine: Unit = - compileFile("tests/partest-test/negAnnotWrongLine.scala", defaultOptions).expectFailure.checkExpectedErrors() - - @Test def negTooManyAnnots: Unit = - compileFile("tests/partest-test/negTooManyAnnots.scala", defaultOptions).expectFailure.checkExpectedErrors() - - @Test def negNoPositionAnnot: Unit = - compileFile("tests/partest-test/negNoPositionAnnots.scala", defaultOptions).expectFailure.checkExpectedErrors() - - @Test def runCompileFail: Unit = - compileFile("tests/partest-test/posFail1Error.scala", defaultOptions).expectFailure.checkRuns() - - @Test def runWrongOutput1: Unit = - compileFile("tests/partest-test/runWrongOutput1.scala", defaultOptions).expectFailure.checkRuns() - - @Test def runWrongOutput2: Unit = - compileFile("tests/partest-test/runWrongOutput2.scala", defaultOptions).expectFailure.checkRuns() - - @Test def runDiffOutput1: Unit = - compileFile("tests/partest-test/runDiffOutput1.scala", defaultOptions).expectFailure.checkRuns() - - @Test def runStackOverflow: Unit = - compileFile("tests/partest-test/stackOverflow.scala", defaultOptions).expectFailure.checkRuns() - - @Test def runOutRedirects: Unit = - compileFile("tests/partest-test/i2147.scala", defaultOptions).expectFailure.checkRuns() - - @Test def infiteNonRec: Unit = - compileFile("tests/partest-test/infinite.scala", defaultOptions).expectFailure.checkRuns() - - @Test def infiteTailRec: Unit = - compileFile("tests/partest-test/infiniteTail.scala", defaultOptions).expectFailure.checkRuns() - - @Test def infiniteAlloc: Unit = - compileFile("tests/partest-test/infiniteAlloc.scala", defaultOptions).expectFailure.checkRuns() - - @Test def deadlock: Unit = - compileFile("tests/partest-test/deadlock.scala", defaultOptions).expectFailure.checkRuns() - - @Test def badJava: Unit = - try compileFile("tests/partest-test/BadJava.java", defaultOptions).suppressAllOutput.checkCompile() - catch { - case ae: AssertionError => assert(ae.getMessage.contains("java compilation failed")) - } -} diff --git a/compiler/test/dotty/tools/vulpix/VulpixUnitTests.scala b/compiler/test/dotty/tools/vulpix/VulpixUnitTests.scala new file mode 100644 index 000000000000..50cc51b4fccb --- /dev/null +++ b/compiler/test/dotty/tools/vulpix/VulpixUnitTests.scala @@ -0,0 +1,97 @@ +package dotty.tools +package vulpix + +import org.junit.Assert._ +import org.junit.Test + +import scala.concurrent.duration._ +import scala.util.control.NonFatal + +/** Unit tests for the Vulpix test suite */ +class VulpixUnitTests extends ParallelTesting { + import TestConfiguration._ + + implicit val _: SummaryReporting = new NoSummaryReport + + implicit def testGroup: TestGroup = TestGroup("VulpixTests") + + def maxDuration = 3.seconds + def numberOfSlaves = 5 + def safeMode = sys.env.get("SAFEMODE").isDefined + def isInteractive = !sys.env.contains("DRONE") + def testFilter = None + + // To fail with something else than an AssertionError + def fail(): Unit = throw new Exception("didn't fail properly") + + @Test def missingFile: Unit = + try { + compileFile("tests/vulpix-tests/unit/i-dont-exist.scala", defaultOptions).expectFailure.checkExpectedErrors() + fail() + } catch { + case _: IllegalArgumentException => // pass! + } + + @Test def pos1Error: Unit = + compileFile("tests/vulpix-tests/unit/posFail1Error.scala", defaultOptions).expectFailure.checkCompile() + + @Test def negMissingAnnot: Unit = + compileFile("tests/vulpix-tests/unit/negMissingAnnot.scala", defaultOptions).expectFailure.checkExpectedErrors() + + @Test def negAnnotWrongLine: Unit = + compileFile("tests/vulpix-tests/unit/negAnnotWrongLine.scala", defaultOptions).expectFailure.checkExpectedErrors() + + @Test def negTooManyAnnots: Unit = + compileFile("tests/vulpix-tests/unit/negTooManyAnnots.scala", defaultOptions).expectFailure.checkExpectedErrors() + + @Test def negNoPositionAnnot: Unit = + compileFile("tests/vulpix-tests/unit/negNoPositionAnnots.scala", defaultOptions).expectFailure.checkExpectedErrors() + + @Test def runCompileFail: Unit = + compileFile("tests/vulpix-tests/unit/posFail1Error.scala", defaultOptions).expectFailure.checkRuns() + + @Test def runWrongOutput1: Unit = + compileFile("tests/vulpix-tests/unit/runWrongOutput1.scala", defaultOptions).expectFailure.checkRuns() + + @Test def runWrongOutput2: Unit = + compileFile("tests/vulpix-tests/unit/runWrongOutput2.scala", defaultOptions).expectFailure.checkRuns() + + @Test def runDiffOutput1: Unit = + compileFile("tests/vulpix-tests/unit/runDiffOutput1.scala", defaultOptions).expectFailure.checkRuns() + + @Test def runStackOverflow: Unit = + compileFile("tests/vulpix-tests/unit/stackOverflow.scala", defaultOptions).expectFailure.checkRuns() + + @Test def runOutRedirects: Unit = + compileFile("tests/vulpix-tests/unit/i2147.scala", defaultOptions).expectFailure.checkRuns() + + @Test def infiteNonRec: Unit = + compileFile("tests/vulpix-tests/unit/infinite.scala", defaultOptions).expectFailure.checkRuns() + + @Test def infiteTailRec: Unit = + compileFile("tests/vulpix-tests/unit/infiniteTail.scala", defaultOptions).expectFailure.checkRuns() + + @Test def infiniteAlloc: Unit = + compileFile("tests/vulpix-tests/unit/infiniteAlloc.scala", defaultOptions).expectFailure.checkRuns() + + @Test def deadlock: Unit = + compileFile("tests/vulpix-tests/unit/deadlock.scala", defaultOptions).expectFailure.checkRuns() + + @Test def badJava: Unit = + try { + compileFile("tests/vulpix-tests/unit/BadJava.java", defaultOptions).suppressAllOutput.checkCompile() + fail() + } catch { + case ae: AssertionError => assertTrue(ae.getMessage.contains("java compilation failed")) + } + + @Test def runTimeout: Unit = { + try { + compileFile("tests/vulpix-tests/unit/timeout.scala", defaultOptions).checkRuns() + fail() + } catch { + case ae: AssertionError => + assertEquals(ae.getMessage, "Run test failed, but should not, reasons:\n - test 'tests/vulpix-tests/unit/timeout.scala' timed out") + } + } +} diff --git a/project/Build.scala b/project/Build.scala index 81fcf606e5e3..6833571ed594 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -501,8 +501,8 @@ object Build { baseDirectory in Test := baseDirectory.value / "..", test in Test := { - // Exclude legacy tests by default - (testOnly in Test).toTask(" -- --exclude-categories=dotty.LegacyTests").value + // Exclude VulpixMetaTests + (testOnly in Test).toTask(" -- --exclude-categories=dotty.VulpixMetaTests").value }, testOptions in Test += Tests.Argument( @@ -1148,8 +1148,7 @@ object Build { dependsOn(dottyCompiler). dependsOn(dottyLibrary). nonBootstrappedSettings( - addCommandAlias("run", "dotty-compiler/run") ++ - addCommandAlias("legacyTests", "dotty-compiler/testOnly dotc.tests") + addCommandAlias("run", "dotty-compiler/run") ) def asDottyCompiler(implicit mode: Mode): Project = project.withCommonSettings. diff --git a/project/scripts/cmdTests b/project/scripts/cmdTests index 3a857f2cce41..e9fba6b7e514 100755 --- a/project/scripts/cmdTests +++ b/project/scripts/cmdTests @@ -92,3 +92,24 @@ mkdir -p out/scriptedtest2 # echo ":quit" | ./dist-bootstrapped/target/pack/bin/dotr # not supported by CI mkdir -p _site && ./bin/dotd -project Hello -siteroot _site tests/run/hello.scala + +echo "running Vulpix meta test" +tmp=$(mktemp) +if ./project/scripts/sbt "dotty-compiler/testOnly dotty.tools.vulpix.VulpixMetaTests" > "$tmp" 2>&1; then + cat "$tmp" + echo "failed: sbt exited without error on VulpixMetaTests, these tests are expected to fail" + exit -1 +fi +tmp1=$(mktemp) +cat "$tmp" | sed '/Test run started/,$!d' > "$tmp1" +set +x # Or the code below produces too much noise +while read expected <&4 && read actual <&3; do + if [[ "$expected" != *"SKIP" ]]; then + if [ "$actual" != "$expected" ]; then + echo "failed Vulpix meta: the output of sbt differs from the expected output" + echo "expected : $expected" + echo "actual : $actual" + exit -1 + fi + fi +done 3<"$tmp1" 4<"./tests/vulpix-tests/meta/sbt-output.check" diff --git a/project/scripts/sbt b/project/scripts/sbt index 3c35e1b1e2e4..957b229128d1 100755 --- a/project/scripts/sbt +++ b/project/scripts/sbt @@ -12,4 +12,5 @@ sbt -J-Xmx4096m \ -J-XX:MaxMetaspaceSize=1024m \ -Ddotty.drone.mem=4096m \ -Dsbt.ivy.home=/var/cache/drone/ivy2 \ + -no-colors \ "$CMD" diff --git a/tests/vulpix-tests/meta/neg/missing-error-annotation.scala b/tests/vulpix-tests/meta/neg/missing-error-annotation.scala new file mode 100644 index 000000000000..2ff28358a7be --- /dev/null +++ b/tests/vulpix-tests/meta/neg/missing-error-annotation.scala @@ -0,0 +1,7 @@ +class MissingErrorAnnotation { + // Missing annotation for the following unbound identifier: + a + + // Another one (to check that both of them get reported) + b +} diff --git a/tests/vulpix-tests/meta/pos/does-not-compile.scala b/tests/vulpix-tests/meta/pos/does-not-compile.scala new file mode 100644 index 000000000000..edfc73c43e3c --- /dev/null +++ b/tests/vulpix-tests/meta/pos/does-not-compile.scala @@ -0,0 +1,3 @@ +class NegTest { + a // Does not compile +} diff --git a/tests/vulpix-tests/meta/run/wrong-check-file.check b/tests/vulpix-tests/meta/run/wrong-check-file.check new file mode 100644 index 000000000000..94954abda49d --- /dev/null +++ b/tests/vulpix-tests/meta/run/wrong-check-file.check @@ -0,0 +1,2 @@ +hello +world diff --git a/tests/vulpix-tests/meta/run/wrong-check-file.scala b/tests/vulpix-tests/meta/run/wrong-check-file.scala new file mode 100644 index 000000000000..52073b5d4401 --- /dev/null +++ b/tests/vulpix-tests/meta/run/wrong-check-file.scala @@ -0,0 +1,6 @@ +object Test { + def main(args: Array[String]): Unit = { + println("world") + println("hello") // Out of order + } +} diff --git a/tests/vulpix-tests/meta/sbt-output.check b/tests/vulpix-tests/meta/sbt-output.check new file mode 100644 index 000000000000..26f604786b14 --- /dev/null +++ b/tests/vulpix-tests/meta/sbt-output.check @@ -0,0 +1,42 @@ +[info] Test run started +[info] Test dotty.tools.vulpix.VulpixMetaTests.runAll started +Testing tests/vulpix-tests/meta/run/wrong-check-file.scala +Output from 'tests/vulpix-tests/meta/run/wrong-check-file.scala' did not match check file. +Diff (expected on the left, actual right): +hello | world +world | hello +EOF | EOF + +[error] Test dotty.tools.vulpix.VulpixMetaTests.runAll failed: java.lang.AssertionError: Run test failed, but should not, reasons: +[error] , took 1.682 sec SKIP +[error] at dotty.tools.vulpix.ParallelTesting$CompilationTest.checkRuns(ParallelTesting.scala:993) SKIP +[error] at dotty.tools.vulpix.VulpixMetaTests.runAll(VulpixMetaTests.scala:26) SKIP +[error] ... +[info] Test dotty.tools.vulpix.VulpixMetaTests.compileNeg started +Testing tests/vulpix-tests/meta/neg/missing-error-annotation.scala + +Wrong number of errors encountered when compiling ../out/VulpixMetaTests/neg/missing-error-annotation, expected: 0, actual: 2 +[error] Test dotty.tools.vulpix.VulpixMetaTests.compileNeg failed: java.lang.AssertionError: Neg test shouldn't have failed, but did. Reasons: +[error] +[error] - encountered 2 error(s), took 0.093 sec SKIP +[error] at dotty.tools.vulpix.ParallelTesting$CompilationTest.checkExpectedErrors(ParallelTesting.scala:975) SKIP +[error] at dotty.tools.vulpix.VulpixMetaTests.compileNeg(VulpixMetaTests.scala:25) SKIP +[error] ... +[info] Test dotty.tools.vulpix.VulpixMetaTests.compilePos started +Testing tests/vulpix-tests/meta/pos/does-not-compile.scala +-- [E006] Unbound Identifier Error: /home/olivier/workspace/dotty/tests/vulpix-tests/meta/pos/does-not-compile.scala:2:2 SKIP +2 | a // Does not compile + | ^ + | not found: a +[error] Test dotty.tools.vulpix.VulpixMetaTests.compilePos failed: java.lang.AssertionError: Expected no errors when compiling, failed for the following reason(s): +[error] +[error] - encountered 1 error(s), took 0.069 sec SKIP +[error] at dotty.tools.vulpix.ParallelTesting$CompilationTest.checkCompile(ParallelTesting.scala:958) SKIP +[error] at dotty.tools.vulpix.VulpixMetaTests.compilePos(VulpixMetaTests.scala:24) SKIP +[error] ... +[info] Test run finished: 3 failed, 0 ignored, 3 total, 1.982s SKIP +[error] Failed: Total 3, Failed 3, Errors 0, Passed 0 +[error] Failed tests: +[error] dotty.tools.vulpix.VulpixMetaTests +[error] (dotty-compiler/test:testOnly) sbt.TestsFailedException: Tests unsuccessful +[error] Total time: 3 s, completed Feb 5, 2018 5:10:12 PM SKIP diff --git a/tests/partest-test/BadJava.java b/tests/vulpix-tests/unit/BadJava.java similarity index 100% rename from tests/partest-test/BadJava.java rename to tests/vulpix-tests/unit/BadJava.java diff --git a/tests/partest-test/deadlock.scala b/tests/vulpix-tests/unit/deadlock.scala similarity index 100% rename from tests/partest-test/deadlock.scala rename to tests/vulpix-tests/unit/deadlock.scala diff --git a/tests/partest-test/i2147.check b/tests/vulpix-tests/unit/i2147.check similarity index 100% rename from tests/partest-test/i2147.check rename to tests/vulpix-tests/unit/i2147.check diff --git a/tests/partest-test/i2147.scala b/tests/vulpix-tests/unit/i2147.scala similarity index 100% rename from tests/partest-test/i2147.scala rename to tests/vulpix-tests/unit/i2147.scala diff --git a/tests/partest-test/infinite.scala b/tests/vulpix-tests/unit/infinite.scala similarity index 100% rename from tests/partest-test/infinite.scala rename to tests/vulpix-tests/unit/infinite.scala diff --git a/tests/partest-test/infiniteAlloc.scala b/tests/vulpix-tests/unit/infiniteAlloc.scala similarity index 100% rename from tests/partest-test/infiniteAlloc.scala rename to tests/vulpix-tests/unit/infiniteAlloc.scala diff --git a/tests/partest-test/infiniteTail.scala b/tests/vulpix-tests/unit/infiniteTail.scala similarity index 100% rename from tests/partest-test/infiniteTail.scala rename to tests/vulpix-tests/unit/infiniteTail.scala diff --git a/tests/partest-test/negAnnotWrongLine.scala b/tests/vulpix-tests/unit/negAnnotWrongLine.scala similarity index 100% rename from tests/partest-test/negAnnotWrongLine.scala rename to tests/vulpix-tests/unit/negAnnotWrongLine.scala diff --git a/tests/partest-test/negMissingAnnot.scala b/tests/vulpix-tests/unit/negMissingAnnot.scala similarity index 100% rename from tests/partest-test/negMissingAnnot.scala rename to tests/vulpix-tests/unit/negMissingAnnot.scala diff --git a/tests/partest-test/negNoPositionAnnots.scala b/tests/vulpix-tests/unit/negNoPositionAnnots.scala similarity index 100% rename from tests/partest-test/negNoPositionAnnots.scala rename to tests/vulpix-tests/unit/negNoPositionAnnots.scala diff --git a/tests/partest-test/negTooManyAnnots.scala b/tests/vulpix-tests/unit/negTooManyAnnots.scala similarity index 100% rename from tests/partest-test/negTooManyAnnots.scala rename to tests/vulpix-tests/unit/negTooManyAnnots.scala diff --git a/tests/partest-test/posFail1Error.scala b/tests/vulpix-tests/unit/posFail1Error.scala similarity index 100% rename from tests/partest-test/posFail1Error.scala rename to tests/vulpix-tests/unit/posFail1Error.scala diff --git a/tests/partest-test/runDiffOutput1.check b/tests/vulpix-tests/unit/runDiffOutput1.check similarity index 100% rename from tests/partest-test/runDiffOutput1.check rename to tests/vulpix-tests/unit/runDiffOutput1.check diff --git a/tests/partest-test/runDiffOutput1.scala b/tests/vulpix-tests/unit/runDiffOutput1.scala similarity index 100% rename from tests/partest-test/runDiffOutput1.scala rename to tests/vulpix-tests/unit/runDiffOutput1.scala diff --git a/tests/partest-test/runWrongOutput1.check b/tests/vulpix-tests/unit/runWrongOutput1.check similarity index 100% rename from tests/partest-test/runWrongOutput1.check rename to tests/vulpix-tests/unit/runWrongOutput1.check diff --git a/tests/partest-test/runWrongOutput1.scala b/tests/vulpix-tests/unit/runWrongOutput1.scala similarity index 100% rename from tests/partest-test/runWrongOutput1.scala rename to tests/vulpix-tests/unit/runWrongOutput1.scala diff --git a/tests/partest-test/runWrongOutput2.check b/tests/vulpix-tests/unit/runWrongOutput2.check similarity index 100% rename from tests/partest-test/runWrongOutput2.check rename to tests/vulpix-tests/unit/runWrongOutput2.check diff --git a/tests/partest-test/runWrongOutput2.scala b/tests/vulpix-tests/unit/runWrongOutput2.scala similarity index 100% rename from tests/partest-test/runWrongOutput2.scala rename to tests/vulpix-tests/unit/runWrongOutput2.scala diff --git a/tests/partest-test/stackOverflow.scala b/tests/vulpix-tests/unit/stackOverflow.scala similarity index 100% rename from tests/partest-test/stackOverflow.scala rename to tests/vulpix-tests/unit/stackOverflow.scala diff --git a/tests/vulpix-tests/unit/timeout.scala b/tests/vulpix-tests/unit/timeout.scala new file mode 100644 index 000000000000..ce9c9a6693d6 --- /dev/null +++ b/tests/vulpix-tests/unit/timeout.scala @@ -0,0 +1,5 @@ +object Test { + def main(args: Array[String]): Unit = { + Thread.sleep(10 * 1000) + } +}