Split damlc integration tests per DAML-LF version (#6577)

* Split damlc integration tests per DAML-LF version

Currently, we have one test for all stable DAML-LF versions. This test
takes quite a while to run and times out occasionally. This PR splits
the big test into one test per stable DAML-LF version.

CHANGELOG_BEGIN
CHANGELOG_END

* Address some feedback
This commit is contained in:
Martin Huschenbett 2020-07-02 13:13:33 +02:00 committed by GitHub
parent 3296f56519
commit 4accae15cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 134 additions and 97 deletions

2
BUILD
View File

@ -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",

View File

@ -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
```

View File

@ -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",

View File

@ -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(

View File

@ -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

View File

@ -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

View File

@ -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"],
)

View File

@ -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",
]