Skip to content

Commit

Permalink
Initial boilerplate for cross-version compatibility testing (#5665)
Browse files Browse the repository at this point in the history
This is a first step towards testing cross-version
compatibility. It doesn’t actuall do much yet but hopefully it should
be easier to parallelize once we have the initial boilerplate in place
so ideally I’d like to address most missing things and issues in
separate PRs.

changelog_begin
changelog_end
  • Loading branch information
cocreature authored Apr 23, 2020
1 parent 85b5e66 commit 7d36402
Show file tree
Hide file tree
Showing 16 changed files with 456 additions and 4 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ ledger-api/.bin
**/.history/
### Bazel: https://www.gitignore.io/api/bazel ###
/bazel-*
/compatibility/bazel-*
.bazelrc.local
.ijwb
.bazelproject
Expand Down
29 changes: 29 additions & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,35 @@ jobs:
trigger_sha: '$(trigger_sha)'
- template: ci/report-end.yml

- job: compatibility
dependsOn:
- check_for_release
timeoutInMinutes: 60
pool:
name: 'linux-pool'
steps:
- template: ci/report-start.yml
- checkout: self
- bash: ci/dev-env-install.sh
displayName: 'Build/Install the Developer Environment'
- bash: ci/configure-bazel.sh
displayName: 'Configure Bazel'
env:
BAZEL_CONFIG_DIR: compatibility
IS_FORK: $(System.PullRequest.IsFork)
# to upload to the bazel cache
GOOGLE_APPLICATION_CREDENTIALS_CONTENT: $(GOOGLE_APPLICATION_CREDENTIALS_CONTENT)
- bash: |
set -euo pipefail
eval "$(./dev-env/bin/dade-assist)"
cd compatibility
bazel build //...
# Run one test as a sanity check. We do not run all of them
# since the test matrix will get large.
bazel test //:ledger-api-test-tool-1.0.1-snapshot.20200417.3908.1.722bac90-platform-1.0.0
- template: ci/tell-slack-failed.yml
- template: ci/report-end.yml

- job: check_for_release
dependsOn:
- git_sha
Expand Down
4 changes: 4 additions & 0 deletions ci/configure-bazel.sh
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ cd "$(dirname "$0")"/..

step "configuring bazel"

if [ ! -z "${BAZEL_CONFIG_DIR:-}" ]; then
cd "$BAZEL_CONFIG_DIR"
fi

if is_windows; then
echo "build --config windows" > .bazelrc.local
echo "build --config windows-ci" >> .bazelrc.local
Expand Down
12 changes: 8 additions & 4 deletions ci/cron/daily-compat.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@ jobs:
matrix:
linux:
pool: 'linux-pool'
macos:
pool: 'macOS-pool'
#windows:
#pool: 'windows-pool'
# macos:
# pool: 'macOS-pool'
# windows:
# pool: 'windows-pool'
pool:
name: $(pool)
steps:
Expand All @@ -42,6 +42,10 @@ jobs:
- bash: |
set -euo pipefail
cd compatibility
bazel build //...
bazel test //...
# FIXME: fill in the gaps.
exit 0
- template: ci/tell-slack-failed.yml
1 change: 1 addition & 0 deletions compatibility/.bazelrc
26 changes: 26 additions & 0 deletions compatibility/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

load(
"@daml//bazel_tools/client_server:client_server_test.bzl",
"client_server_test",
)
load("@os_info//:os_info.bzl", "is_linux")

# TODO Abstract over this.
client_server_test(
name = "ledger-api-test-tool-1.0.1-snapshot.20200417.3908.1.722bac90-platform-1.0.0",
client = "@daml-sdk-1.0.1-snapshot.20200417.3908.1.722bac90//:ledger-api-test-tool",
client_args = [
"localhost:6865",
"--open-world",
"--exclude=ClosedWorldIT",
],
data = ["@daml-sdk-1.0.1-snapshot.20200417.3908.1.722bac90//:dar-files"],
runner = "@//bazel_tools/client_server:runner",
runner_args = ["6865"],
server = "@daml-sdk-1.0.0//:daml",
server_args = ["sandbox"],
server_files = ["$(rootpaths @daml-sdk-1.0.1-snapshot.20200417.3908.1.722bac90//:dar-files)"],
tags = ["exclusive"],
) if is_linux else None
4 changes: 4 additions & 0 deletions compatibility/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
This directory contains the infrastructure and test setup for
cross-version compatibility testing. We make this a separate Bazel
workspace to make it easier to enforce that we only depend on release
artifacts.
106 changes: 106 additions & 0 deletions compatibility/WORKSPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
workspace(name = "compatibility")

# We import the main workspace for nix stuff and some shared Bazel rules.
# This is mainly so we don’t have to symlink a bunch of files.
# Note that you should never depend on targets from @daml.
local_repository(
name = "daml",
path = "..",
)
load("@daml//bazel_tools:os_info.bzl", "os_info")
os_info(name = "os_info")
load("@os_info//:os_info.bzl", "is_darwin", "is_linux", "is_windows")

load("//:deps.bzl", "daml_deps")
daml_deps()

load("@rules_haskell//haskell:repositories.bzl", "rules_haskell_dependencies")
rules_haskell_dependencies()
load(
"@rules_haskell//haskell:nixpkgs.bzl",
"haskell_register_ghc_nixpkgs",
)

load(
"@io_tweag_rules_nixpkgs//nixpkgs:nixpkgs.bzl",
"nixpkgs_cc_configure",
"nixpkgs_local_repository",
"nixpkgs_package",
"nixpkgs_python_configure",
)
common_nix_file_deps = [
"@daml//nix:bazel.nix",
"@daml//nix:nixpkgs.nix",
"@daml//nix:nixpkgs/default.nix",
"@daml//nix:nixpkgs/default.src.json",
]
nix_ghc_deps = common_nix_file_deps + [
"@daml//nix:ghc.nix",
"@daml//nix:with-packages-wrapper.nix",
"@daml//nix:overrides/ghc-8.6.5.nix",
"@daml//nix:overrides/ghc-8.6.3-binary.nix",
]
dev_env_nix_repos = {
"nixpkgs": "@nixpkgs",
}
nixpkgs_local_repository(
name = "nixpkgs",
nix_file = "@daml//nix:nixpkgs.nix",
nix_file_deps = [
"@daml//nix:nixpkgs/default.nix",
"@daml//nix:nixpkgs/default.src.json",
],
)
nixpkgs_cc_configure(
nix_file = "@daml//nix:bazel-cc-toolchain.nix",
nix_file_deps = common_nix_file_deps + [
"@daml//nix:bazel-cc-toolchain.nix",
"@daml//nix:tools/bazel-cc-toolchain/default.nix",
],
repositories = dev_env_nix_repos,
)

nixpkgs_package(
name = "glibc_locales",
attribute_path = "glibcLocales",
build_file_content = """
package(default_visibility = ["//visibility:public"])
filegroup(
name = "locale-archive",
srcs = ["lib/locale/locale-archive"],
)
""",
nix_file = "@daml//nix:bazel.nix",
nix_file_deps = common_nix_file_deps,
repositories = dev_env_nix_repos,
) if is_linux else None

haskell_register_ghc_nixpkgs(
attribute_path = "ghcStatic",
build_file = "@io_tweag_rules_nixpkgs//nixpkgs:BUILD.pkg",
is_static = True,
locale_archive = "@glibc_locales//:locale-archive",
nix_file = "@daml//nix:bazel.nix",
nix_file_deps = nix_ghc_deps,
repositories = dev_env_nix_repos,
version = "8.6.5",
)

nixpkgs_python_configure(repository = "@nixpkgs")

load("//:bazel-haskell-deps.bzl", "daml_haskell_deps")
daml_haskell_deps()

load("//bazel_tools:daml_sdk.bzl", "daml_sdk")

daml_sdk(
version = "1.0.0",
sdk_sha256 = "ee7e2f50394d44fb3490068de64d37f4f87534e802717bd7e07e8767df2e4e05",
test_tool_sha256 = "cf66efafd9490e1256e825f377b208b8ae90151f56e411b596fbaaef91353e14",
)

daml_sdk(
version = "1.0.1-snapshot.20200417.3908.1.722bac90",
sdk_sha256 = "aaf832ceda1a66a8469460d5a4b6c14f681ce692d4e9ef6010896febbaf4b6e1",
test_tool_sha256 = "762cd4836a8359dca0fb3271ba2e1d0629138f7d8d914298324418a174c5d22a",
)
49 changes: 49 additions & 0 deletions compatibility/bazel-haskell-deps.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

# Defines external Haskell dependencies.
#
# Add Stackage dependencies to the `packages` attribute of the `@stackage`
# `stack_snapshot` in the very bottom of this file. If a package or version is
# not available on Stackage, add it to the custom stack snapshot in
# `stack-snapshot.yaml`. If a library requires patching, then add it as an
# `http_archive` and add it to the `vendored_packages` attribute of
# `stack_snapshot`. Executables are defined in an `http_archive` using
# `haskell_cabal_binary`.

load("@bazel_skylib//lib:dicts.bzl", "dicts")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load("@os_info//:os_info.bzl", "is_windows")
load("@rules_haskell//haskell:cabal.bzl", "stack_snapshot")

def daml_haskell_deps():
"""Load all Haskell dependencies of the DAML repository."""

use_integer_simple = True

stack_snapshot(
name = "stackage",
extra_deps = {
"zlib": ["@com_github_madler_zlib//:libz"],
},
flags = dicts.add(
{
"integer-logarithms": ["-integer-gmp"],
"text": ["integer-simple"],
"scientific": ["integer-simple"],
} if use_integer_simple else {},
),
haddock = False,
local_snapshot = "//:stack-snapshot.yaml",
packages = [
"base",
"monad-loops",
"network",
"process",
"safe-exceptions",
"split",
] + (["unix"] if not is_windows else ["Win32"]),
stack = None,
tools = [
],
)
Empty file added compatibility/bazel_tools/BUILD
Empty file.
18 changes: 18 additions & 0 deletions compatibility/bazel_tools/client_server/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
load(
"@rules_haskell//haskell:defs.bzl",
"haskell_binary",
)

haskell_binary(
name = "runner",
srcs = ["Main.hs"],
deps = [
"@stackage//:base",
"@stackage//:monad-loops",
"@stackage//:network",
"@stackage//:process",
"@stackage//:safe-exceptions",
"@stackage//:split",
],
visibility = ["//visibility:public"],
)
39 changes: 39 additions & 0 deletions compatibility/bazel_tools/client_server/Main.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
-- Copyright (c) 2020 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
-- SPDX-License-Identifier: Apache-2.0
{-# LANGUAGE ScopedTypeVariables #-}
module Main(main) where

import System.Environment
import Control.Exception.Safe
import Control.Monad.Loops (untilJust)
import System.Process
import Data.List.Split (splitOn)
import Control.Monad (forM_)
import Network.Socket
import Control.Concurrent

main :: IO ()
main = do
[clientExe, clientArgs, serverExe, serverArgs, runnerArgs] <- getArgs
let splitArgs = filter (/= "") . splitOn " "
let serverProc = proc serverExe (splitArgs serverArgs)
let ports :: [Int] = read <$> splitArgs runnerArgs
withCreateProcess serverProc $ \_stdin _stdout _stderr _ph -> do
forM_ ports $ \port -> waitForConnectionOnPort (threadDelay 500000) port
callProcess clientExe (splitArgs clientArgs)


waitForConnectionOnPort :: IO () -> Int -> IO ()
waitForConnectionOnPort sleep port = do
let hints = defaultHints { addrFlags = [AI_NUMERICHOST, AI_NUMERICSERV], addrSocketType = Stream }
addr : _ <- getAddrInfo (Just hints) (Just "127.0.0.1") (Just $ show port)
untilJust $ do
r <- tryIO $ checkConnection addr
case r of
Left _ -> sleep *> pure Nothing
Right _ -> pure $ Just ()
where
checkConnection addr = bracket
(socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr))
close
(\s -> connect s (addrAddress addr))
Loading

0 comments on commit 7d36402

Please sign in to comment.