コード例 #1
0
ファイル: test_persistent.py プロジェクト: keyz/dagster
def test_load_via_env_var():
    port = find_free_port()
    python_file = file_relative_path(__file__, "grpc_repo.py")

    subprocess_args = [
        "dagster",
        "api",
        "grpc",
        "--python-file",
        python_file,
    ]

    with environ({
            "DAGSTER_CLI_API_GRPC_HOST": "localhost",
            "DAGSTER_CLI_API_GRPC_PORT": str(port)
    }):
        process = subprocess.Popen(
            subprocess_args,
            stdout=subprocess.PIPE,
        )

        try:
            wait_for_grpc_server(
                process, DagsterGrpcClient(port=port, host="localhost"),
                subprocess_args)
            assert DagsterGrpcClient(port=port).ping("foobar") == "foobar"
        finally:
            process.terminate()
コード例 #2
0
def test_load_with_empty_working_directory(capfd):
    port = find_free_port()
    # File that will fail if working directory isn't set to default
    python_file = file_relative_path(__file__, "grpc_repo_with_local_import.py")

    subprocess_args = [
        "dagster",
        "api",
        "grpc",
        "--port",
        str(port),
        "--python-file",
        python_file,
    ]

    with new_cwd(os.path.dirname(__file__)):
        process = subprocess.Popen(
            subprocess_args,
            stdout=subprocess.PIPE,
        )

        try:
            wait_for_grpc_server(
                process, DagsterGrpcClient(port=port, host="localhost"), subprocess_args
            )
            assert DagsterGrpcClient(port=port).ping("foobar") == "foobar"
        finally:
            process.terminate()

        # indicating the working directory is empty fails

        port = find_free_port()
        subprocess_args = [
            "dagster",
            "api",
            "grpc",
            "--port",
            str(port),
            "--python-file",
            python_file,
            "--empty-working-directory",
        ]

        process = subprocess.Popen(
            subprocess_args,
            stdout=subprocess.PIPE,
        )
        try:
            with pytest.raises(Exception):
                wait_for_grpc_server(
                    process, DagsterGrpcClient(port=port, host="localhost"), subprocess_args
                )

            process.wait()

            _, err = capfd.readouterr()
            assert "No module named" in err
        finally:
            if process.poll() is None:
                process.terminate()
コード例 #3
0
ファイル: test_persistent.py プロジェクト: keyz/dagster
def test_lazy_load_with_error():
    port = find_free_port()
    python_file = file_relative_path(__file__, "grpc_repo_with_error.py")

    subprocess_args = [
        "dagster",
        "api",
        "grpc",
        "--port",
        str(port),
        "--python-file",
        python_file,
        "--lazy-load-user-code",
    ]

    process = subprocess.Popen(subprocess_args, stdout=subprocess.PIPE)

    try:
        wait_for_grpc_server(process,
                             DagsterGrpcClient(port=port, host="localhost"),
                             subprocess_args)
        list_repositories_response = deserialize_json_to_dagster_namedtuple(
            DagsterGrpcClient(port=port).list_repositories())
        assert isinstance(list_repositories_response, SerializableErrorInfo)
        assert "No module named" in list_repositories_response.message
    finally:
        process.terminate()
コード例 #4
0
ファイル: test_persistent.py プロジェクト: keyz/dagster
def test_lazy_load_via_env_var():
    with environ({"DAGSTER_CLI_API_GRPC_LAZY_LOAD_USER_CODE": "1"}):
        port = find_free_port()
        python_file = file_relative_path(__file__, "grpc_repo_with_error.py")

        subprocess_args = [
            "dagster",
            "api",
            "grpc",
            "--port",
            str(port),
            "--python-file",
            python_file,
        ]

        process = subprocess.Popen(
            subprocess_args,
            stdout=subprocess.PIPE,
        )

        try:
            wait_for_grpc_server(
                process, DagsterGrpcClient(port=port, host="localhost"),
                subprocess_args)
            list_repositories_response = deserialize_json_to_dagster_namedtuple(
                DagsterGrpcClient(port=port).list_repositories())
            assert isinstance(list_repositories_response,
                              SerializableErrorInfo)
            assert "No module named" in list_repositories_response.message
        finally:
            process.terminate()
コード例 #5
0
def test_streaming():
    port = find_free_port()
    python_file = file_relative_path(__file__, "grpc_repo.py")

    ipc_output_file = _get_ipc_output_file()

    process = subprocess.Popen(
        [
            "dagster",
            "api",
            "grpc",
            "--port",
            str(port),
            "--python-file",
            python_file,
            "--ipc-output-file",
            ipc_output_file,
        ],
        stdout=subprocess.PIPE,
    )

    try:
        wait_for_grpc_server(ipc_output_file)
        api_client = DagsterGrpcClient(port=port)
        results = [
            result for result in api_client.streaming_ping(sequence_length=10,
                                                           echo="foo")
        ]
        assert len(results) == 10
        for sequence_number, result in enumerate(results):
            assert result["sequence_number"] == sequence_number
            assert result["echo"] == "foo"
    finally:
        process.terminate()
コード例 #6
0
ファイル: handle.py プロジェクト: uttasarga9067/dagster
    def __init__(self, origin):
        from dagster.grpc.client import DagsterGrpcClient
        from dagster.grpc.server_watcher import create_grpc_watch_thread

        self._origin = check.inst_param(origin, "origin",
                                        GrpcServerRepositoryLocationOrigin)

        port = self.origin.port
        socket = self.origin.socket
        host = self.origin.host

        self._watch_thread_shutdown_event = None
        self._watch_thread = None

        try:
            self.client = DagsterGrpcClient(port=port,
                                            socket=socket,
                                            host=host)
            list_repositories_response = sync_list_repositories_grpc(
                self.client)

            self.server_id = sync_get_server_id(self.client)
            self.repository_names = set(
                symbol.repository_name
                for symbol in list_repositories_response.repository_symbols)

            self._state_subscribers = []
            self._watch_thread_shutdown_event, self._watch_thread = create_grpc_watch_thread(
                self.client,
                on_updated=lambda new_server_id: self.
                _send_state_event_to_subscribers(
                    LocationStateChangeEvent(
                        LocationStateChangeEventType.LOCATION_UPDATED,
                        location_name=self.location_name,
                        message="Server has been updated.",
                        server_id=new_server_id,
                    )),
                on_error=lambda: self._send_state_event_to_subscribers(
                    LocationStateChangeEvent(
                        LocationStateChangeEventType.LOCATION_ERROR,
                        location_name=self.location_name,
                        message=
                        "Unable to reconnect to server. You can reload the server once it is "
                        "reachable again",
                    )),
            )

            self._watch_thread.start()

            self.executable_path = list_repositories_response.executable_path
            self.repository_code_pointer_dict = (
                list_repositories_response.repository_code_pointer_dict)

            self.container_image = self._reload_current_image()
        except:
            self.cleanup()
            raise
コード例 #7
0
def test_cleanup_after_force_terminate(run_config):
    with instance_for_test() as instance, get_managed_grpc_server_workspace(
            instance) as workspace:
        external_pipeline = (
            workspace.get_repository_location("test").get_repository(
                "nope").get_full_external_pipeline("sleepy_pipeline"))
        pipeline_run = instance.create_run_for_pipeline(
            pipeline_def=sleepy_pipeline,
            run_config=run_config,
            external_pipeline_origin=external_pipeline.get_external_origin(),
            pipeline_code_origin=external_pipeline.get_python_origin(),
        )

        run_id = pipeline_run.run_id

        instance.launch_run(pipeline_run.run_id, workspace)

        poll_for_step_start(instance, run_id)

        # simulate the sequence of events that happen during force-termination:
        # run moves immediately into canceled status while termination happens
        instance.report_run_canceling(pipeline_run)

        instance.report_run_canceled(pipeline_run)

        reloaded_run = instance.get_run_by_id(run_id)
        grpc_info = json.loads(reloaded_run.tags.get(GRPC_INFO_TAG))
        client = DagsterGrpcClient(
            port=grpc_info.get("port"),
            socket=grpc_info.get("socket"),
            host=grpc_info.get("host"),
        )
        client.cancel_execution(CancelExecutionRequest(run_id=run_id))

        # Wait for the run worker to clean up
        start_time = time.time()
        while True:
            if time.time() - start_time > 30:
                raise Exception("Timed out waiting for cleanup message")

            logs = instance.all_logs(run_id)
            if any([
                    "Computational resources were cleaned up after the run was forcibly marked as canceled."
                    in str(event) for event in logs
            ]):
                break

            time.sleep(1)

        assert instance.get_run_by_id(
            run_id).status == PipelineRunStatus.CANCELED
コード例 #8
0
def open_server_process(
    port,
    socket,
    loadable_target_origin=None,
    max_workers=None,
    heartbeat=False,
    heartbeat_timeout=30,
    fixed_server_id=None,
    startup_timeout=20,
):
    check.invariant((port or socket) and not (port and socket), "Set only port or socket")
    check.opt_inst_param(loadable_target_origin, "loadable_target_origin", LoadableTargetOrigin)
    check.opt_int_param(max_workers, "max_workers")

    from dagster.core.test_utils import get_mocked_system_timezone

    mocked_system_timezone = get_mocked_system_timezone()

    executable_path = loadable_target_origin.executable_path if loadable_target_origin else None

    subprocess_args = (
        (
            get_python_environment_entry_point(executable_path)
            if executable_path
            else DEFAULT_DAGSTER_ENTRY_POINT
        )
        + ["api", "grpc"]
        + ["--lazy-load-user-code"]
        + (["--port", str(port)] if port else [])
        + (["--socket", socket] if socket else [])
        + (["-n", str(max_workers)] if max_workers else [])
        + (["--heartbeat"] if heartbeat else [])
        + (["--heartbeat-timeout", str(heartbeat_timeout)] if heartbeat_timeout else [])
        + (["--fixed-server-id", fixed_server_id] if fixed_server_id else [])
        + (["--override-system-timezone", mocked_system_timezone] if mocked_system_timezone else [])
        + (["--log-level", "WARNING"])  # don't log INFO messages for automatically spun up servers
        + (["--use-python-environment-entry-point"] if executable_path else [])
    )

    if loadable_target_origin:
        subprocess_args += loadable_target_origin.get_cli_args()

    server_process = open_ipc_subprocess(subprocess_args)

    from dagster.grpc.client import DagsterGrpcClient

    client = DagsterGrpcClient(
        port=port,
        socket=socket,
        host="localhost",
    )

    try:
        wait_for_grpc_server(server_process, client, subprocess_args, timeout=startup_timeout)
    except:
        if server_process.poll() is None:
            server_process.terminate()
        raise

    return server_process
コード例 #9
0
def test_lazy_load_via_env_var():
    with environ({"DAGSTER_CLI_API_GRPC_LAZY_LOAD_USER_CODE": "1"}):
        port = find_free_port()
        python_file = file_relative_path(__file__, "grpc_repo_with_error.py")

        ipc_output_file = _get_ipc_output_file()

        process = subprocess.Popen(
            [
                "dagster",
                "api",
                "grpc",
                "--port",
                str(port),
                "--python-file",
                python_file,
                "--ipc-output-file",
                ipc_output_file,
            ],
            stdout=subprocess.PIPE,
        )

        try:
            wait_for_grpc_server(process, ipc_output_file)
            list_repositories_response = DagsterGrpcClient(port=port).list_repositories()
            assert isinstance(list_repositories_response, SerializableErrorInfo)
            assert "No module named" in list_repositories_response.message
        finally:
            process.terminate()
コード例 #10
0
def test_load_with_empty_working_directory(capfd):
    port = find_free_port()
    # File that will fail if working directory isn't set to default
    python_file = file_relative_path(__file__, "grpc_repo_with_local_import.py")

    with new_cwd(os.path.dirname(__file__)):

        ipc_output_file = _get_ipc_output_file()

        process = subprocess.Popen(
            [
                "dagster",
                "api",
                "grpc",
                "--port",
                str(port),
                "--python-file",
                python_file,
                "--ipc-output-file",
                ipc_output_file,
            ],
            stdout=subprocess.PIPE,
        )

        try:
            wait_for_grpc_server(process, ipc_output_file)
            assert DagsterGrpcClient(port=port).ping("foobar") == "foobar"
        finally:
            process.terminate()

        # indicating the working directory is empty fails

        ipc_output_file = _get_ipc_output_file()

        process = subprocess.Popen(
            [
                "dagster",
                "api",
                "grpc",
                "--port",
                str(port),
                "--python-file",
                python_file,
                "--empty-working-directory",
                "--ipc-output-file",
                ipc_output_file,
            ],
            stdout=subprocess.PIPE,
        )
        try:
            with pytest.raises(DagsterUserCodeProcessError):
                wait_for_grpc_server(process, ipc_output_file)

            process.wait()

            _, err = capfd.readouterr()
            assert "No module named" in err
        finally:
            if process.poll() is None:
                process.terminate()
コード例 #11
0
ファイル: test_persistent.py プロジェクト: prezi/dagster
def test_load_with_invalid_param(capfd):
    port = find_free_port()
    python_file = file_relative_path(__file__, "grpc_repo.py")

    subprocess_args = [
        "dagster",
        "api",
        "grpc",
        "--port",
        str(port),
        "--python-file",
        python_file,
        "--foo-param",
        "bar_value",
    ]

    process = subprocess.Popen(
        subprocess_args,
        stdout=subprocess.PIPE,
    )

    try:
        with pytest.raises(
            Exception,
            match='gRPC server exited with return code 2 while starting up with the command: "dagster api grpc --port',
        ):
            wait_for_grpc_server(
                process, DagsterGrpcClient(port=port, host="localhost"), subprocess_args
            )
    finally:
        process.terminate()

    _, err = capfd.readouterr()

    assert "no such option" in err
コード例 #12
0
ファイル: test_persistent.py プロジェクト: keyz/dagster
def test_load_with_error(capfd):
    port = find_free_port()
    python_file = file_relative_path(__file__, "grpc_repo_with_error.py")

    subprocess_args = [
        "dagster",
        "api",
        "grpc",
        "--port",
        str(port),
        "--python-file",
        python_file,
    ]

    process = subprocess.Popen(
        subprocess_args,
        stdout=subprocess.PIPE,
    )

    try:
        with pytest.raises(Exception):
            wait_for_grpc_server(
                process, DagsterGrpcClient(port=port, host="localhost"),
                subprocess_args)
        process.wait()

        _, err = capfd.readouterr()
        assert "No module named" in err
    finally:
        if process.poll() is None:
            process.terminate()
コード例 #13
0
ファイル: test_persistent.py プロジェクト: keyz/dagster
def test_load_grpc_server_python_env():
    port = find_free_port()
    python_file = file_relative_path(__file__, "grpc_repo.py")

    subprocess_args = [
        "dagster",
        "api",
        "grpc",
        "--port",
        str(port),
        "--python-file",
        python_file,
        "--use-python-environment-entry-point",
    ]

    process = subprocess.Popen(subprocess_args)

    try:

        client = DagsterGrpcClient(port=port, host="localhost")

        wait_for_grpc_server(process, client, subprocess_args)

        list_repositories_response = sync_list_repositories_grpc(client)
        assert list_repositories_response.entry_point == [
            sys.executable, "-m", "dagster"
        ]
        assert list_repositories_response.executable_path == sys.executable

    finally:
        process.terminate()
コード例 #14
0
ファイル: test_persistent.py プロジェクト: keyz/dagster
def test_crash_during_load():
    port = find_free_port()
    python_file = file_relative_path(__file__, "crashy_grpc_repo.py")

    subprocess_args = [
        "dagster",
        "api",
        "grpc",
        "--port",
        str(port),
        "--python-file",
        python_file,
    ]

    process = subprocess.Popen(
        subprocess_args,
        stdout=subprocess.PIPE,
    )
    try:

        with pytest.raises(
                Exception,
                match=re.escape(
                    'gRPC server exited with return code 123 while starting up with the command: "dagster api grpc --port'
                ),
        ):
            wait_for_grpc_server(
                process, DagsterGrpcClient(port=port, host="localhost"),
                subprocess_args)
    finally:
        if process.poll() is None:
            process.terminate()
コード例 #15
0
ファイル: conftest.py プロジェクト: sd2k/dagster
def docker_grpc_client(dagster_docker_image, grpc_host, grpc_port):  # pylint: disable=redefined-outer-name, unused-argument
    if not IS_BUILDKITE:
        docker_service_up(file_relative_path(__file__, "docker-compose.yml"),
                          "dagster-grpc-server")

    wait_for_connection(grpc_host, grpc_port)
    yield DagsterGrpcClient(port=grpc_port, host=grpc_host)
コード例 #16
0
def test_ping():
    port = find_free_port()
    python_file = file_relative_path(__file__, "grpc_repo.py")

    ipc_output_file = _get_ipc_output_file()
    process = subprocess.Popen(
        [
            "dagster",
            "api",
            "grpc",
            "--port",
            str(port),
            "--python-file",
            python_file,
            "--ipc-output-file",
            ipc_output_file,
        ],
        stdout=subprocess.PIPE,
    )

    try:
        wait_for_grpc_server(ipc_output_file)
        assert DagsterGrpcClient(port=port).ping("foobar") == "foobar"
    finally:
        process.terminate()
コード例 #17
0
def test_grpc_watch_thread_server_update():
    port = find_free_port()

    called = {}

    def on_updated():
        called["yup"] = True

    # Create initial server
    server_process = open_server_process(port=port, socket=None)

    try:
        # Start watch thread
        client = DagsterGrpcClient(port=port)
        watch_interval = 4
        shutdown_event, watch_thread = create_grpc_watch_thread(
            client, on_updated=on_updated, watch_interval=watch_interval)
        watch_thread.start()
        time.sleep(watch_interval * 2)
    finally:
        interrupt_ipc_subprocess_pid(server_process.pid)

    assert not called

    # Create updated server
    server_process = open_server_process(port=port, socket=None)

    try:
        time.sleep(watch_interval * 2)
    finally:
        interrupt_ipc_subprocess_pid(server_process.pid)

    shutdown_event.set()
    watch_thread.join()
    assert called
コード例 #18
0
def test_run_grpc_watch_thread():
    client = DagsterGrpcClient(port=8080)
    shutdown_event, watch_thread = create_grpc_watch_thread(client)

    watch_thread.start()
    shutdown_event.set()
    watch_thread.join()
コード例 #19
0
def test_lazy_load_with_error():
    port = find_free_port()
    python_file = file_relative_path(__file__, "grpc_repo_with_error.py")

    ipc_output_file = _get_ipc_output_file()

    process = subprocess.Popen(
        [
            "dagster",
            "api",
            "grpc",
            "--port",
            str(port),
            "--python-file",
            python_file,
            "--lazy-load-user-code",
            "--ipc-output-file",
            ipc_output_file,
        ],
        stdout=subprocess.PIPE,
    )

    try:
        wait_for_grpc_server(ipc_output_file)
        list_repositories_response = DagsterGrpcClient(
            port=port).list_repositories()
        assert isinstance(list_repositories_response, SerializableErrorInfo)
        assert "No module named" in list_repositories_response.message
    finally:
        process.terminate()
コード例 #20
0
    def create_grpc_server_location(port, socket, host, location_name=None):
        from dagster.grpc.client import DagsterGrpcClient

        check.opt_int_param(port, 'port')
        check.opt_str_param(socket, 'socket')
        check.str_param(host, 'host')
        check.opt_str_param(location_name, 'location_name')

        client = DagsterGrpcClient(port=port, socket=socket, host=host)

        list_repositories_response = sync_list_repositories_grpc(client)

        repository_names = set(
            symbol.repository_name
            for symbol in list_repositories_response.repository_symbols)

        return GrpcServerRepositoryLocationHandle(
            port=port,
            socket=socket,
            host=host,
            location_name=location_name if location_name else
            _assign_grpc_location_name(port, socket, host),
            client=client,
            repository_names=repository_names,
        )
コード例 #21
0
def test_sensor_timeout():
    port = find_free_port()
    python_file = file_relative_path(__file__, "grpc_repo.py")

    subprocess_args = [
        "dagster",
        "api",
        "grpc",
        "--port",
        str(port),
        "--python-file",
        python_file,
    ]

    process = subprocess.Popen(
        subprocess_args,
        stdout=subprocess.PIPE,
    )

    try:
        wait_for_grpc_server(
            process, DagsterGrpcClient(port=port, host="localhost"), subprocess_args
        )
        client = DagsterGrpcClient(port=port)

        with instance_for_test() as instance:
            repo_origin = ExternalRepositoryOrigin(
                repository_location_origin=GrpcServerRepositoryLocationOrigin(
                    port=port, host="localhost"
                ),
                repository_name="bar_repo",
            )
            with pytest.raises(DagsterUserCodeUnreachableError) as exc_info:
                client.external_sensor_execution(
                    sensor_execution_args=SensorExecutionArgs(
                        repository_origin=repo_origin,
                        instance_ref=instance.get_ref(),
                        sensor_name="slow_sensor",
                        last_completion_time=None,
                        last_run_key=None,
                        cursor=None,
                    ),
                    timeout=2,
                )

            assert "Deadline Exceeded" in str(exc_info.getrepr())

            # Call succeeds without the timeout
            client.external_sensor_execution(
                sensor_execution_args=SensorExecutionArgs(
                    repository_origin=repo_origin,
                    instance_ref=instance.get_ref(),
                    sensor_name="slow_sensor",
                    last_completion_time=None,
                    last_run_key=None,
                    cursor=None,
                ),
            )
    finally:
        process.terminate()
コード例 #22
0
def open_server_process(
    port,
    socket,
    loadable_target_origin=None,
    max_workers=None,
    heartbeat=False,
    heartbeat_timeout=30,
    fixed_server_id=None,
):
    check.invariant((port or socket) and not (port and socket),
                    "Set only port or socket")
    check.opt_inst_param(loadable_target_origin, "loadable_target_origin",
                         LoadableTargetOrigin)
    check.opt_int_param(max_workers, "max_workers")

    from dagster.core.test_utils import get_mocked_system_timezone

    mocked_system_timezone = get_mocked_system_timezone()

    subprocess_args = (
        [
            loadable_target_origin.executable_path if loadable_target_origin
            and loadable_target_origin.executable_path else sys.executable,
            "-m",
            "dagster.grpc",
        ] + ["--lazy-load-user-code"] +
        (["--port", str(port)] if port else []) +
        (["--socket", socket] if socket else []) +
        (["-n", str(max_workers)] if max_workers else []) +
        (["--heartbeat"] if heartbeat else []) +
        (["--heartbeat-timeout", str(heartbeat_timeout)]
         if heartbeat_timeout else []) +
        (["--fixed-server-id", fixed_server_id] if fixed_server_id else []) +
        (["--override-system-timezone", mocked_system_timezone]
         if mocked_system_timezone else []))

    if loadable_target_origin:
        subprocess_args += loadable_target_origin.get_cli_args()

    server_process = open_ipc_subprocess(subprocess_args)

    from dagster.grpc.client import DagsterGrpcClient

    client = DagsterGrpcClient(
        port=port,
        socket=socket,
        host="localhost",
    )

    try:
        wait_for_grpc_server(server_process, client, subprocess_args)
    except:
        if server_process.poll() is None:
            server_process.terminate()
        raise

    return server_process
コード例 #23
0
ファイル: origin.py プロジェクト: prezi/dagster
    def create_client(self):
        from dagster.grpc.client import DagsterGrpcClient

        return DagsterGrpcClient(
            port=self.port,
            socket=self.socket,
            host=self.host,
            use_ssl=bool(self.use_ssl),
        )
コード例 #24
0
ファイル: test_persistent.py プロジェクト: keyz/dagster
def test_load_grpc_server(capfd):
    port = find_free_port()
    python_file = file_relative_path(__file__, "grpc_repo.py")

    subprocess_args = [
        "dagster",
        "api",
        "grpc",
        "--port",
        str(port),
        "--python-file",
        python_file,
    ]

    process = subprocess.Popen(subprocess_args)

    try:

        client = DagsterGrpcClient(port=port, host="localhost")

        wait_for_grpc_server(process, client, subprocess_args)
        assert client.ping("foobar") == "foobar"

        list_repositories_response = sync_list_repositories_grpc(client)
        assert list_repositories_response.entry_point == ["dagster"]
        assert list_repositories_response.executable_path == sys.executable

        subprocess.check_call(
            ["dagster", "api", "grpc-health-check", "--port",
             str(port)])

        ssl_result = subprocess.run(  # pylint:disable=subprocess-run-check
            [
                "dagster", "api", "grpc-health-check", "--port",
                str(port), "--use-ssl"
            ])
        assert ssl_result.returncode == 1

    finally:
        process.terminate()

    out, _err = capfd.readouterr()

    assert f"Started Dagster code server for file {python_file} on port {port} in process" in out
コード例 #25
0
def test_load_with_container_context(capfd):
    port = find_free_port()
    python_file = file_relative_path(__file__, "grpc_repo.py")

    container_context = {
        "k8s": {
            "image_pull_policy": "Never",
            "image_pull_secrets": [{"name": "your_secret"}],
        }
    }

    subprocess_args = [
        "dagster",
        "api",
        "grpc",
        "--port",
        str(port),
        "--python-file",
        python_file,
        "--container-context",
        json.dumps(container_context),
    ]

    process = subprocess.Popen(subprocess_args)

    try:

        client = DagsterGrpcClient(port=port, host="localhost")

        wait_for_grpc_server(process, client, subprocess_args)
        assert client.ping("foobar") == "foobar"

        list_repositories_response = sync_list_repositories_grpc(client)
        assert list_repositories_response.entry_point == ["dagster"]
        assert list_repositories_response.executable_path == sys.executable
        assert list_repositories_response.container_context == container_context

    finally:
        process.terminate()

    out, _err = capfd.readouterr()

    assert f"Started Dagster code server for file {python_file} on port {port} in process" in out
コード例 #26
0
ファイル: handle.py プロジェクト: M-EZZ/dagster
    def __init__(self, origin):
        from dagster.grpc.client import DagsterGrpcClient

        self.origin = check.inst_param(origin, "origin",
                                       GrpcServerRepositoryLocationOrigin)

        port = self.origin.port
        socket = self.origin.socket
        host = self.origin.host

        self.client = DagsterGrpcClient(port=port, socket=socket, host=host)

        list_repositories_response = sync_list_repositories_grpc(self.client)

        self.repository_names = set(
            symbol.repository_name
            for symbol in list_repositories_response.repository_symbols)

        self.executable_path = list_repositories_response.executable_path
        self.repository_code_pointer_dict = list_repositories_response.repository_code_pointer_dict
コード例 #27
0
def test_grpc_watch_thread_server_complex_cycle_2():
    # Server goes down, comes back up as the same server three times, then goes away and comes
    # back as a new server

    port = find_free_port()
    fixed_server_id = "fixed_id"

    events = []
    called = {}

    def on_disconnect():
        events.append("on_disconnect")

    def on_reconnected():
        events.append("on_reconnected")

    def on_updated(_):
        events.append("on_updated")

    def on_error():
        called["on_error"] = True
        events.append("on_error")

    # Create initial server
    open_server_process(port=port, socket=None, fixed_server_id=fixed_server_id)

    # Start watch thread
    client = DagsterGrpcClient(port=port)
    watch_interval = 1  # This is a faster watch interval than we would use in practice

    shutdown_event, watch_thread = create_grpc_watch_thread(
        client,
        on_disconnect=on_disconnect,
        on_reconnected=on_reconnected,
        on_updated=on_updated,
        on_error=on_error,
        watch_interval=watch_interval,
        max_reconnect_attempts=3,
    )
    watch_thread.start()
    time.sleep(watch_interval * 3)

    cycles = 3
    for x in range(1, cycles + 1):
        # Simulate server restart three times with same server ID
        client.shutdown_server()
        wait_for_condition(lambda: events.count("on_disconnect") == x, watch_interval)
        open_server_process(port=port, socket=None, fixed_server_id=fixed_server_id)
        wait_for_condition(lambda: events.count("on_reconnected") == x, watch_interval)

    # Simulate server failure
    client.shutdown_server()

    # Wait for reconnect attempts to exhaust and on_error callback to be called
    wait_for_condition(lambda: called.get("on_error"), watch_interval)

    shutdown_event.set()
    watch_thread.join()

    assert events[-1] == "on_error"
コード例 #28
0
def test_grpc_watch_thread_server_error():
    port = find_free_port()
    fixed_server_id = "fixed_id"

    called = {}

    def on_disconnect():
        called["on_disconnect"] = True

    def on_error():
        called["on_error"] = True

    def should_not_be_called():
        raise Exception("This method should not be called")

    # Create initial server
    server_process = open_server_process(port=port,
                                         socket=None,
                                         fixed_server_id=fixed_server_id)

    # Start watch thread
    client = DagsterGrpcClient(port=port)
    watch_interval = 1
    max_reconnect_attempts = 3
    shutdown_event, watch_thread = create_grpc_watch_thread(
        client,
        on_disconnect=on_disconnect,
        on_reconnected=should_not_be_called,
        on_updated=should_not_be_called,
        on_error=on_error,
        watch_interval=watch_interval,
        max_reconnect_attempts=max_reconnect_attempts,
    )
    watch_thread.start()

    # Wait three seconds, simulate restart failure
    time.sleep(watch_interval * 3)
    interrupt_ipc_subprocess_pid(server_process.pid)

    # Wait for reconnect attempts to exhaust and on_error callback to be called
    start_time = time.time()
    while not called.get("on_error"):
        if time.time() - start_time > 30:
            break

        time.sleep(1)

    shutdown_event.set()
    watch_thread.join()

    assert called["on_disconnect"]
    assert called["on_error"]
コード例 #29
0
ファイル: test_persistent.py プロジェクト: prezi/dagster
def test_ping():
    port = find_free_port()
    python_file = file_relative_path(__file__, "grpc_repo.py")

    subprocess_args = [
        "dagster",
        "api",
        "grpc",
        "--port",
        str(port),
        "--python-file",
        python_file,
    ]

    process = subprocess.Popen(subprocess_args, stdout=subprocess.PIPE)

    try:
        wait_for_grpc_server(
            process, DagsterGrpcClient(port=port, host="localhost"), subprocess_args
        )
        assert DagsterGrpcClient(port=port).ping("foobar") == "foobar"
    finally:
        process.terminate()
コード例 #30
0
def test_streaming():
    port = find_free_port()
    python_file = file_relative_path(__file__, 'grpc_repo.py')
    process = subprocess.Popen(
        [
            'dagster', 'api', 'grpc', '--port',
            str(port), '--python-file', python_file
        ],
        stdout=subprocess.PIPE,
    )

    try:
        wait_for_grpc_server(process)
        api_client = DagsterGrpcClient(port=port)
        results = [
            result for result in api_client.streaming_ping(sequence_length=10,
                                                           echo='foo')
        ]
        assert len(results) == 10
        for sequence_number, result in enumerate(results):
            assert result['sequence_number'] == sequence_number
            assert result['echo'] == 'foo'
    finally:
        process.terminate()