diff --git a/BUILD b/BUILD index c13cb25bc42..dd37a31ad8e 100644 --- a/BUILD +++ b/BUILD @@ -247,7 +247,7 @@ da_haskell_repl( "//compiler/damlc/tests:damlc-test", "//compiler/damlc/tests:generate-simple-dalf", "//compiler/damlc/tests:incremental", - "//compiler/damlc/tests:integration-dev", + "//compiler/damlc/tests:integration-v1dev", "//compiler/damlc/tests:packaging", "//daml-assistant:daml", "//daml-assistant:test", diff --git a/compiler/damlc/README.md b/compiler/damlc/README.md index cada7d3c27f..607a07b88dc 100644 --- a/compiler/damlc/README.md +++ b/compiler/damlc/README.md @@ -61,8 +61,8 @@ This is a tiny wrapper around `lib` to produce the `damlc` executable. When working on the compiler: ``` -da-ghcid //compiler/damlc/tests:integration-dev --reload=compiler/damlc/tests/daml-test-files --test=":main --pattern=" -bazel run //compiler/damlc/tests:integration-dev -- --pattern= +da-ghcid //compiler/damlc/tests:integration-v1dev --reload=compiler/damlc/tests/daml-test-files --test=":main --pattern=" +bazel run //compiler/damlc/tests:integration-v1dev -- --pattern= bazel run damlc -- compile $PWD/MyDaml12File.daml ``` diff --git a/compiler/damlc/pkg-db/BUILD.bazel b/compiler/damlc/pkg-db/BUILD.bazel index ec96ae1eb9d..fbb0f8a4cfb 100644 --- a/compiler/damlc/pkg-db/BUILD.bazel +++ b/compiler/damlc/pkg-db/BUILD.bazel @@ -6,13 +6,7 @@ load( "daml_package_db", "daml_package_rule", ) - -DAML_LF_VERSIONS = [ - "1.6", - "1.7", - "1.8", - "1.dev", -] +load("//compiler/damlc:util.bzl", "DAML_LF_VERSIONS") daml_package_db( name = "package_db_for_daml-prim", diff --git a/compiler/damlc/tests/BUILD.bazel b/compiler/damlc/tests/BUILD.bazel index af01cce4514..fb6bfe2bf7a 100644 --- a/compiler/damlc/tests/BUILD.bazel +++ b/compiler/damlc/tests/BUILD.bazel @@ -1,12 +1,12 @@ # Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. # SPDX-License-Identifier: Apache-2.0 -load("//bazel_tools:haskell.bzl", "da_haskell_binary", "da_haskell_test") +load("//bazel_tools:haskell.bzl", "da_haskell_binary", "da_haskell_library", "da_haskell_test") load("@os_info//:os_info.bzl", "is_windows") -load(":util.bzl", "damlc_compile_test", "damlc_integration_test") +load(":util.bzl", "damlc_compile_test") load("//rules_daml:daml.bzl", "daml_compile") load("@build_environment//:configuration.bzl", "sdk_version") -load("//compiler/damlc:util.bzl", "ghc_pkg") +load("//compiler/damlc:util.bzl", "DAML_LF_VERSIONS", "ghc_pkg") # Tests for the lax CLI parser da_haskell_test( @@ -107,11 +107,83 @@ da_haskell_test( ], ) -# Integration tests for all non-dev DAML-LF versions -damlc_integration_test("integration-stable", "DA.Test.DamlcIntegration.mainAll") +da_haskell_library( + name = "integration-lib", + srcs = ["src/DA/Test/DamlcIntegration.hs"], + hackage_deps = [ + "aeson-pretty", + "base", + "bytestring", + "data-default", + "deepseq", + "directory", + "dlist", + "extra", + "filepath", + "ghc-lib", + "ghc-lib-parser", + "ghcide", + "haskell-lsp-types", + "optparse-applicative", + "process", + "proto3-suite", + "shake", + "tagged", + "tasty", + "tasty-hunit", + "text", + "time", + "unordered-containers", + ], + visibility = ["//visibility:public"], + deps = [ + "//compiler/daml-lf-ast", + "//compiler/daml-lf-proto", + "//compiler/damlc/daml-compiler", + "//compiler/damlc/daml-ide-core", + "//compiler/damlc/daml-lf-conversion", + "//compiler/damlc/daml-opts", + "//compiler/damlc/daml-opts:daml-opts-types", + "//compiler/scenario-service/client", + "//daml-lf/archive:daml_lf_dev_archive_haskell_proto", + "//libs-haskell/bazel-runfiles", + "//libs-haskell/da-hs-base", + "//libs-haskell/test-utils", + ], +) -# Integration tests for DAML-LF 1.dev -damlc_integration_test("integration-dev", "DA.Test.DamlcIntegration.main") +[ + da_haskell_test( + # NOTE(MH): For some reason, ghc-pkg gets very unhappy if we separate + # the components of the version number by dot, dash or underscore. + name = "integration-v{}".format(version.replace(".", "")), + size = "large", + srcs = ["src/DA/Test/DamlcIntegrationMain.hs"], + args = [ + "--daml-lf-version", + version, + ], + data = [ + ":bond-trading", + ":daml-test-files", + ":query-lf-lib", + "//compiler/damlc/pkg-db", + "//compiler/damlc/stable-packages", + "//compiler/scenario-service/server:scenario_service_jar", + "@jq_dev_env//:jq", + ], + hackage_deps = [ + "base", + ], + main_function = "DA.Test.DamlcIntegrationMain.main", + src_strip_prefix = "src", + visibility = ["//visibility:public"], + deps = [ + ":integration-lib", + ], + ) + for version in DAML_LF_VERSIONS +] # Tests for daml-doc da_haskell_test( diff --git a/compiler/damlc/tests/src/DA/Test/DamlcIntegration.hs b/compiler/damlc/tests/src/DA/Test/DamlcIntegration.hs index 154e5937afc..09c2a4ce2a6 100644 --- a/compiler/damlc/tests/src/DA/Test/DamlcIntegration.hs +++ b/compiler/damlc/tests/src/DA/Test/DamlcIntegration.hs @@ -8,7 +8,6 @@ -- typecheck with LF, test it. Test annotations are documented as 'Ann'. module DA.Test.DamlcIntegration ( main - , mainAll ) where import DA.Bazel.Runfiles @@ -78,28 +77,33 @@ import Test.Tasty.Runners (Outcome(..), Result(..)) -- Newtype to avoid mixing up the loging function and the one for registering TODOs. newtype TODO = TODO String +newtype LfVersionOpt = LfVersionOpt Version + deriving (Eq) + +instance IsOption LfVersionOpt where + defaultValue = LfVersionOpt versionDefault + -- Tasty seems to force the value somewhere so we cannot just set this + -- to `error`. However, this will always be set. + parseValue = fmap LfVersionOpt . parseVersion + optionName = Tagged "daml-lf-version" + optionHelp = Tagged "DAML-LF version to test" + main :: IO () -main = mainWithVersions [versionDev] - -mainAll :: IO () -mainAll = mainWithVersions (delete versionDev supportedOutputVersions) - -mainWithVersions :: [Version] -> IO () -mainWithVersions versions = do +main = do let scenarioConf = SS.defaultScenarioServiceConfig { SS.cnfJvmOptions = ["-Xmx200M"] } SS.withScenarioService Logger.makeNopHandle scenarioConf $ \scenarioService -> do hSetEncoding stdout utf8 setEnv "TASTY_NUM_THREADS" "1" True todoRef <- newIORef DList.empty let registerTODO (TODO s) = modifyIORef todoRef (`DList.snoc` ("TODO: " ++ s)) - integrationTests <- mapM (getIntegrationTests registerTODO scenarioService) versions - let tests = testGroup "All" $ uniqueUniques : integrationTests + integrationTests <- getIntegrationTests registerTODO scenarioService + let tests = testGroup "All" [uniqueUniques, integrationTests] defaultMainWithIngredients ingredients tests `finally` (do todos <- readIORef todoRef putStr (unlines (DList.toList todos))) where ingredients = - includingOptions [Option (Proxy :: Proxy PackageDb)] : + includingOptions [Option (Proxy :: Proxy PackageDb), Option (Proxy @LfVersionOpt)] : defaultIngredients uniqueUniques :: TestTree @@ -113,8 +117,8 @@ uniqueUniques = HUnit.testCase "Uniques" $ let n = length $ nubOrd $ concat results n @?= 10000 -getIntegrationTests :: (TODO -> IO ()) -> SS.Handle -> Version -> IO TestTree -getIntegrationTests registerTODO scenarioService version = do +getIntegrationTests :: (TODO -> IO ()) -> SS.Handle -> IO TestTree +getIntegrationTests registerTODO scenarioService = do putStrLn $ "rtsSupportsBoundThreads: " ++ show rtsSupportsBoundThreads do n <- getNumCapabilities; putStrLn $ "getNumCapabilities: " ++ show n @@ -132,27 +136,31 @@ getIntegrationTests registerTODO scenarioService version = do createDirectoryIfMissing True outdir dlintDataDir <- locateRunfiles $ mainWorkspace "compiler/damlc/daml-ide-core" - let opts = (defaultOptions (Just version)) - { optThreads = 0 - , optCoreLinting = True - , optDlintUsage = DlintEnabled dlintDataDir False - } -- initialise the compiler service vfs <- makeVFSHandle - damlEnv <- mkDamlEnv opts (Just scenarioService) -- We use a separate service for generated files so that we can test files containing internal imports. - pure $ + let tree :: TestTree + tree = askOption $ \(LfVersionOpt version) -> + let opts = (defaultOptions (Just version)) + { optThreads = 0 + , optCoreLinting = True + , optDlintUsage = DlintEnabled dlintDataDir False + } + in + withResource (mkDamlEnv opts (Just scenarioService)) (\_damlEnv -> pure ()) $ \getDamlEnv -> withResource - (initialise def (mainRule opts) (pure $ LSP.IdInt 0) (const $ pure ()) IdeLogger.noLogging noopDebouncer damlEnv (toCompileOpts opts (IdeReportProgress False)) vfs) + (getDamlEnv >>= \damlEnv -> initialise def (mainRule opts) (pure $ LSP.IdInt 0) (const $ pure ()) IdeLogger.noLogging noopDebouncer damlEnv (toCompileOpts opts (IdeReportProgress False)) vfs) shutdown $ \service -> withResource - (initialise def (mainRule opts) (pure $ LSP.IdInt 0) (const $ pure ()) IdeLogger.noLogging noopDebouncer damlEnv (toCompileOpts opts { optIsGenerated = True } (IdeReportProgress False)) vfs) + (getDamlEnv >>= \damlEnv -> initialise def (mainRule opts) (pure $ LSP.IdInt 0) (const $ pure ()) IdeLogger.noLogging noopDebouncer damlEnv (toCompileOpts opts { optIsGenerated = True } (IdeReportProgress False)) vfs) shutdown $ \serviceGenerated -> withTestArguments $ \args -> testGroup ("Tests for DAML-LF " ++ renderPretty version) $ map (testCase args version service outdir registerTODO) nongeneratedFiles <> map (testCase args version serviceGenerated outdir registerTODO) generatedFiles + pure tree + newtype TestCase = TestCase ((String -> IO ()) -> IO Result) instance IsTest TestCase where diff --git a/compiler/damlc/tests/src/DA/Test/DamlcIntegrationMain.hs b/compiler/damlc/tests/src/DA/Test/DamlcIntegrationMain.hs new file mode 100644 index 00000000000..3819c2f1858 --- /dev/null +++ b/compiler/damlc/tests/src/DA/Test/DamlcIntegrationMain.hs @@ -0,0 +1,14 @@ +-- Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved. +-- SPDX-License-Identifier: Apache-2.0 + +-- | Test driver for DAML-GHC CompilerService. +-- For each file, compile it with GHC, convert it, +-- typecheck with LF, test it. Test annotations are documented as 'Ann'. +module DA.Test.DamlcIntegrationMain + ( main + ) where + +import qualified DA.Test.DamlcIntegration as Lib + +main :: IO () +main = Lib.main diff --git a/compiler/damlc/tests/util.bzl b/compiler/damlc/tests/util.bzl index 28ac4f6a641..c02daaa118e 100644 --- a/compiler/damlc/tests/util.bzl +++ b/compiler/damlc/tests/util.bzl @@ -57,61 +57,3 @@ damlc_compile_test = rule( }, test = True, ) - -def damlc_integration_test(name, main_function): - da_haskell_test( - name = name, - size = "large", - srcs = ["src/DA/Test/DamlcIntegration.hs"], - src_strip_prefix = "src", - main_function = main_function, - data = [ - "//compiler/damlc/pkg-db", - "//compiler/damlc/stable-packages", - "//compiler/scenario-service/server:scenario_service_jar", - "@jq_dev_env//:jq", - ":daml-test-files", - ":bond-trading", - ":query-lf-lib", - ], - deps = [ - "//compiler/daml-lf-ast", - "//compiler/daml-lf-proto", - "//compiler/damlc/daml-compiler", - "//compiler/damlc/daml-ide-core", - "//compiler/damlc/daml-lf-conversion", - "//compiler/damlc/daml-opts:daml-opts-types", - "//compiler/damlc/daml-opts", - "//compiler/scenario-service/client", - "//daml-lf/archive:daml_lf_dev_archive_haskell_proto", - "//libs-haskell/bazel-runfiles", - "//libs-haskell/da-hs-base", - "//libs-haskell/test-utils", - ], - hackage_deps = [ - "aeson-pretty", - "base", - "bytestring", - "data-default", - "deepseq", - "directory", - "dlist", - "extra", - "filepath", - "ghc-lib", - "ghc-lib-parser", - "ghcide", - "haskell-lsp-types", - "optparse-applicative", - "process", - "proto3-suite", - "shake", - "tagged", - "tasty", - "tasty-hunit", - "text", - "time", - "unordered-containers", - ], - visibility = ["//visibility:public"], - ) diff --git a/compiler/damlc/util.bzl b/compiler/damlc/util.bzl index 6d23cc93837..ddf502a99f7 100644 --- a/compiler/damlc/util.bzl +++ b/compiler/damlc/util.bzl @@ -9,3 +9,10 @@ load("@os_info//:os_info.bzl", "is_windows") # not going to work. We thus use the dynamically linked executable in the runfiles of damlc # and the tarball produced by package_app in the resources of damlc-dist. ghc_pkg = "@rules_haskell_ghc_windows_amd64//:bin/ghc-pkg.exe" if is_windows else "@ghc_nix//:lib/ghc-8.6.5/bin/ghc-pkg" + +DAML_LF_VERSIONS = [ + "1.6", + "1.7", + "1.8", + "1.dev", +]