Example #1
0
def sandbox() -> str:
    """
    Run an instance of the Sandbox, or use one configured through environment variables.

    Some environment variables change the nature of the Sandbox used in these tests:

     * DAZL_TEST_DAML_LEDGER_URL: If set, it is assumed to be an already-running ledger, and we
       merely return that URL instead of starting up our own sandbox. This is the way that the tests
       run in CI.
     * DAML_SDK_VERSION: If set AND DAZL_TEST_DAML_LEDGER_URL is not specified, this controls the
       version of the Sandbox that is launched through this wrapper. This value can be overridden
       to test dazl against newer (or older) versions of the SDK without making code changes:
         ```
         DAML_SDK_VERSION=1.0.0 make test
         ```
    """
    url = os.environ.get("DAZL_TEST_DAML_LEDGER_URL")
    if url:
        logging.info(
            "Using the sandbox at %s because `DAZL_TEST_DAML_LEDGER_URL` is defined",
            url)
        yield url
        return

    port = find_free_port()

    env = os.environ.copy()
    # Running dazl's tests against a different Sandbox merely requires the DAML_SDK_VERSION
    # variable be set to a different value
    if "DAML_SDK_VERSION" not in env:
        env["DAML_SDK_VERSION"] = DEFAULT_SDK_VERSION

    process = subprocess.Popen(
        ["daml", "sandbox", "--port", str(port)],
        env=env,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        universal_newlines=True,
    )
    try:
        ProcessLogger(process, logging.getLogger("sandbox")).start()
        wait_for_process_port(process, port, SANDBOX_START_TIMEOUT)

        yield f"http://localhost:{port}"

    finally:
        # Clean up the process that we started. Note that some versions of the SDK have issues that
        # leave dangling child processes running even after the parent process is killed, so make
        # sure that we find and destroy them too if the parent process doesn't kill its own children
        # quickly enough.
        kill_process_tree(process)
def _main():
    """
    Run this test case.

    If a URL is specified, then the integration test will run pointing to that ledger
    implementation. If a URL is _not_ supplied, then a local sandbox is spun up on a random port,
    the integration test is run, and the sandbox is shut down when it is complete.
    """
    import argparse
    import subprocess
    from dazl.util import ProcessLogger, find_free_port, kill_process_tree, wait_for_process_port

    argparser = argparse.ArgumentParser()

    backend_args = argparser.add_mutually_exclusive_group()
    backend_args.add_argument(
        '--url',
        required=False,
        help='The URL of the *existing* server to connect to')
    backend_args.add_argument('--port',
                              required=False,
                              type=int,
                              help='The port to spin up a NEW Sandbox')

    argparser.add_argument('--keep-alive', action='store_true')

    args = argparser.parse_args()

    if args.url:
        LOG.info('Running the test against an existing sandbox: %s', args.url)
        run_test(args.url)
    else:
        LOG.info('Spinning up a local sandbox as part of the test...')
        port = args.port if args.port else find_free_port()

        proc = subprocess.Popen([
            "daml", "start", "--start-navigator=no", "--open-browser=no",
            f"--sandbox-port={port}"
        ],
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE,
                                universal_newlines=True)
        try:
            ProcessLogger(proc, logging.getLogger('sandbox')).start()
            wait_for_process_port(proc, port, timedelta(seconds=10))

            run_test(f'http://localhost:{port}', args.keep_alive)
        finally:
            kill_process_tree(proc)