Exemple #1
0
def test_shell_raises_if_no_command_provided():
    with Flow(name="test") as f:
        task = ShellTask()()

    with pytest.raises(TypeError):
        with raise_on_exception():
            out = f.run()
Exemple #2
0
    def test_can_push_with_tags(self):
        self.tag_repo(['1.0.0', '1', '1.0', '1.0.0+20200228.blue-ivory'])

        checkout = SemanticCheckoutTask(upstream_repos=dict(
            abc=f'sgr://{remote_name}/abc/1234?tag=1', ), )

        workspaces = checkout.run()
        push = PushRepoTask(workspaces=workspaces, )

        self.repo.commit()

        runner = TaskRunner(task=push)
        tags_edge = Edge(Task(), push, key='sgr_tags')
        tag_state = Success(result=ConstantResult(value=dict(
            abc=['foo', 'bar', 'tag1_w_upstream'])))

        with raise_on_exception():
            with prefect.context():
                state = runner.run(upstream_states={tags_edge: tag_state})

                if state.is_failed():
                    print(state)
                    self.fail()

                self.assertCountEqual(
                    self.repo.head.get_tags(),
                    ['HEAD', 'foo', 'bar', 'tag1_w_upstream'])
    def test_retries_cache_parameters_as_well(self, executor):
        with Flow(name="test") as f:
            a = Parameter("a")
            b = ReturnTask(max_retries=1, retry_delay=datetime.timedelta(0))
            a_res = a()
            b_res = b(a_res)

        first_state = FlowRunner(flow=f).run(executor=executor,
                                             parameters=dict(a=1),
                                             return_tasks=f.tasks)
        assert first_state.is_running()

        a_state = first_state.result[a_res]
        a_state.result = (
            NoResult
        )  # remove the result to see if the cached results are picked up
        b_state = first_state.result[b_res]
        b_state.cached_inputs = dict(x=Result(2))  # artificially alter state

        with raise_on_exception():  # without caching we'd expect a KeyError
            second_state = FlowRunner(flow=f).run(
                executor=executor,
                return_tasks=[b_res],
                task_states=first_state.result)
        assert isinstance(second_state, Success)
        assert second_state.result[b_res].result == 1
Exemple #4
0
    def test_can_clone_with_hourly_prerelease_tags(self):
        self.tag_repo([
            '1.0.0', '1', '1.0', '1.0.0+20200228.blue-ivory', '1.0.1',
            '1.0.1+20200307.pink-bear', '1-hourly', '1.0-hourly',
            '1.0.2-hourly.1+20200301.blue-ivory',
            '1.0.2-hourly.2+20200301.green-monster'
        ])

        checkout = SemanticCheckoutTask(upstream_repos=dict(
            abc='sgr:///abc/1234?tag=1.1-hourly', ), )
        runner = TaskRunner(task=checkout)

        with raise_on_exception():
            with prefect.context():
                state = runner.run()

                if state.is_failed():
                    print(state)
                    self.fail()

                workspaces = state.result
                workspace = workspaces['abc']
                self.assertEqual(
                    workspace['version'],
                    Version('1.0.2-hourly.2+20200301.green-monster'))
Exemple #5
0
def test_raise_on_exception_raises_basic_prefect_signal():
    flow = Flow(name="test")
    flow.add_task(BusinessTask())
    with pytest.raises(prefect.engine.signals.FAIL) as error:
        with raise_on_exception():
            flow.run()
    assert "needs more blockchain!" in str(error.value)
Exemple #6
0
    def run(
        self,
        small_area_period_built_filepath: Path,
        ber_archetypes_filepath: Path,
        small_area_geometries_filepath: Path,
        output_filepath: Path,
    ) -> gpd.GeoDataFrame:
        """Run EstimateSmallAreaDemand flow.

        Args:
            small_area_period_built_filepath (Path): Path to Clean Small Area Period
                Built Data
            ber_archetypes_filepath (Path): Path to BER Archetypal Energy Averages
            small_area_geometries_filepath (Path): Path to Clean Small Area Geometries
            output_filepath (Path): Path to a Small Area Demand Estimate
        """
        with raise_on_exception():
            state = flow.run(parameters=dict(
                sa_periods_built_fpath=small_area_period_built_filepath,
                ber_archetype_averages_fpath=ber_archetypes_filepath,
                sa_geometries_fpath=small_area_geometries_filepath,
            ), )

        result = state.result[sa_demand_with_geometries].result

        result.to_parquet(output_filepath)
Exemple #7
0
def test_flow_runner_uses_user_provided_executor():
    t = SuccessTask()
    with Flow(name="test") as f:
        result = t()
    with raise_on_exception():
        with pytest.raises(NotImplementedError):
            FlowRunner(flow=f).run(executor=Executor())
Exemple #8
0
    def test_can_semantic_bump_prerelease(self):
        semantic_bump = SemanticBumpTask()

        runner = TaskRunner(task=semantic_bump)
        edge = Edge(Task(), semantic_bump, key='workspaces')
        upstream_state = Success(result=ConstantResult(value=dict(abc=dict(
            repo_uri='sgr:///abc/1234?tag=1-hourly',
            version=Version('1.0.1-hourly.4+2021-03-08.zip-fur'),
        ))))

        date = datetime.utcnow()
        flow_run_name = 'testflow1'
        with raise_on_exception():
            with prefect.context(date=date, flow_run_name=flow_run_name):
                state = runner.run(upstream_states={edge: upstream_state})

                if state.is_failed():
                    print(state)
                    self.fail()

                self.assertEqual(
                    state.result,
                    dict(abc=[
                        '1-hourly', '1.0-hourly',
                        f'1.0.1-hourly.5+{date:%Y-%m-%dT%H}.{date:%M}.{flow_run_name}'
                    ]))
Exemple #9
0
    def run(
        self,
        input_filepath: Path,
        sa_glossary_filepath: Path,
        postcodes_filepath: Path,
        sa_geometries_filepath: Path,
        output_filepath_period_built: Path,
        output_filepath_boilers: Path,
    ) -> None:
        """Run local flow.

        Args:
            input_filepath (Path): Path to Small Area Statistics Raw Data
            sa_glossary_filepath (Path): Path to Small Area Statistics Glossary
            postcodes_filepath (Path): Path to Postcode Geometries Data
            sa_geometries_filepath (Path): Path to Small Area Geometries Data
            output_filepath_period_built (Path): Path to Small Area Period Built Stats
            output_filepath_boilers (Path): Path to Small Area Period Boiler Stats
        """
        with raise_on_exception():
            state = self.flow.run(parameters=dict(
                sa_stats_fpath=input_filepath,
                sa_glossary_fpath=sa_glossary_filepath,
                postcode_geometries_fpath=postcodes_filepath,
                sa_geometries_fpath=sa_geometries_filepath,
            ), )

        period_built = state.result[clean_year_built].result
        boilers = state.result[clean_boiler_stats].result

        period_built.to_parquet(output_filepath_period_built)
        boilers.to_parquet(output_filepath_boilers)
Exemple #10
0
def etl_flow_state(monkeypatch: MonkeyPatch, mock_data_dir: Mock) -> State:
    """Run etl flow with dummy test data.

    Args:
        monkeypatch (MonkeyPatch): Pytest fixture to mock out objects s.a. PrefectSecret
        mock_data_dir (Mock): See https://docs.pytest.org/en/stable/tmpdir.html

    Returns:
        [State]: A Prefect State object containing flow run information
    """
    from drem.etl import residential

    # Mock out PrefectSecret as no secrets are required in CI (data already downloaded)
    monkeypatch.setattr(
        residential.PrefectSecret,
        "run",
        mock_prefectsecret_run,
    )

    # Mock out task load as CI doesn't need flow outputs on-disk
    monkeypatch.setattr(
        residential.Download,
        "run",
        mock_task_run,
    )
    monkeypatch.setattr(
        residential.download.BERPublicsearch,
        "run",
        mock_task_run,
    )

    with raise_on_exception():
        state = residential.flow.run()

    return state
Exemple #11
0
def test_not_forced_with_prefect_cache(mocker, temp_url):
    # Test that the prefect cache is used when force=False
    run_method = mocker.patch(
        'iguazu.Task.run',
        side_effect=['result1', Exception('should not be called')])
    task = Task(force=False)

    with Flow('test_not_forced_with_prefect_cache') as flow:
        task()

    with prefect.context(caches={}):
        flow_state1 = flow.run(run_on_schedule=True)
        cache = prefect.context.caches

    result1 = list(flow_state1.result.values())[0].result

    with raise_on_exception(), prefect.context(
            caches=cache):  # Note: cache is from previous run
        flow_state2 = flow.run(run_on_schedule=True)

    result2 = list(flow_state2.result.values())[0].result

    assert result1 == 'result1'
    assert result2 == 'result1'
    assert run_method.call_count == 1
def test_map_composition(executor):
    ll = ListTask()
    a = AddTask()

    with Flow(name="test") as f:
        r1 = a.map(ll)
        r2 = a.map(r1)

    with raise_on_exception():
        s = f.run(executor=executor)

    m1 = s.result[r1]
    m2 = s.result[r2]
    assert s.is_successful()
    assert m1.is_mapped()
    assert m2.is_mapped()

    assert isinstance(m1.map_states, list)
    assert all(s.is_successful() for s in m1.map_states)
    assert len(m1.map_states) == 3
    assert m1.result == [2, 3, 4]

    assert isinstance(m2.map_states, list)
    assert all(s.is_successful() for s in m2.map_states)
    assert len(m2.map_states) == 3
    assert m2.result == [3, 4, 5]
Exemple #13
0
def test_function_order(mocker):
    manager = mocker.Mock()
    funcs = {
        'contexts': tuple(),
        'prepare_inputs': dict(),
        'handle_outputs': None,
    }
    for name, rv in funcs.items():
        mocked_func = mocker.patch(f'iguazu.core.tasks.ManagedTask.{name}',
                                   return_value=rv)
        manager.attach_mock(mocked_func, name)

    with Flow('test_function_order') as flow:
        instance = ManagedTask()
        instance()

    with raise_on_exception(), prefect.context(caches={}):
        flow.run()

    expected_calls = [
        mocker.call.contexts(),
        mocker.call.prepare_inputs(),
        mocker.call.handle_outputs(None),
    ]
    manager.assert_has_calls(expected_calls, any_order=False)
Exemple #14
0
def test_graceful_exceptions_fail(temp_url):
    task = TaskWithException(graceful_exceptions=())

    with Flow('test_graceful_exceptions_fail') as flow:
        task(value=-1)

    with raise_on_exception(), prefect.context(caches={}), pytest.raises(CustomException):
        flow.run()
Exemple #15
0
def test_flow_runner_uses_default_executor_on_flow_if_present():
    t = SuccessTask()
    with Flow(name="test", executor=Executor()) as flow:
        result = t()

    with raise_on_exception():
        with pytest.raises(NotImplementedError):
            FlowRunner(flow=flow).run()
Exemple #16
0
def execute(flow: Flow) -> state:
    """
    Returns:
        state: (state) state of league flow
    """
    with raise_on_exception():
        executor = DaskExecutor(address=os.getenv("WORKER_ADDRESS"))
        state = flow.run()

        return state
Exemple #17
0
def test_auto_manage_dataframe_incorrect_type(local_file, caplog):
    task = TaskWithInputDataFrame()

    with Flow('test_auto_manage_dataframe_default_string') as flow:
        file = prefect.Parameter('local_file', default=123456)
        task(input_one=file)

    with pytest.raises(ValueError), caplog.at_level('FATAL', logger='prefect'):
        with raise_on_exception(), prefect.context(caches={}):
            flow.run()
Exemple #18
0
def test_raise_on_exception_plays_well_with_context():
    flow = Flow(name="test")
    flow.add_task(MathTask())
    try:
        assert "raise_on_exception" not in prefect.context
        with raise_on_exception():
            assert "raise_on_exception" in prefect.context
            flow.run()
    except ZeroDivisionError:
        assert "raise_on_exception" not in prefect.context
        pass
Exemple #19
0
def test_graceful_exceptions_handle_failed(mocker, temp_url):
    graceful_fail_task_method = mocker.patch('iguazu.core.tasks.Task._graceful_fail',
                                             side_effect=[ENDRUN(state=Finished())])
    task = TaskWithException(graceful_exceptions=(CustomException, ))

    with Flow('test_graceful_exceptions_handle_failed') as flow:
        task(value=+1)

    with raise_on_exception(), prefect.context(caches={}), pytest.raises(ValueError):
        flow.run()

    graceful_fail_task_method.assert_not_called()
Exemple #20
0
def test_pandas_context_raise(temp_url):
    initial_mode = pd.get_option('mode.chained_assignment')

    with Flow('test_pandas_context_error') as flow:
        task = PandasModeSpy(pandas_chained_assignment='raise')
        task()

    with pytest.raises(pandas.core.common.SettingWithCopyError):
        with raise_on_exception(), prefect.context(caches={}):
            flow.run()

    assert pd.get_option('mode.chained_assignment') == initial_mode
Exemple #21
0
def test_switch_works_with_raise_on_exception():
    @prefect.task
    def return_b():
        return "b"

    tasks = {let: prefect.Task(name=let) for let in "abcde"}

    with Flow(name="test") as flow:
        res = switch(return_b, tasks)

    with raise_on_exception():
        flow_state = flow.run()
Exemple #22
0
def test_bad_graceful_implementation(mocker, temp_url):
    graceful_fail_task_method = mocker.patch('iguazu.core.tasks.Task._graceful_fail',
                                             return_value=['something'])
    task = TaskWithException(graceful_exceptions=(CustomException, ))

    with Flow('test_bad_graceful_implementation') as flow:
        task(value=-1)

    with raise_on_exception(), prefect.context(caches={}), pytest.raises(RuntimeError):
        flow.run()

    graceful_fail_task_method.assert_called_once()
def test_mapping_over_constants():
    @prefect.task
    def add_one(x):
        return x + 1

    with Flow("constants") as f:
        output = add_one.map(x=[1, 2, 3, 4])

    with raise_on_exception():
        flow_state = f.run()
    assert flow_state.is_successful()
    assert flow_state.result[output].result == [2, 3, 4, 5]
    def run(self, input_filepath: Path, output_filepath: Path) -> None:
        """Run flow.

        Args:
            input_filepath (Path): Path to input data
            output_filepath (Path): Path to output data
        """
        with raise_on_exception():
            state = self.flow.run(ber_fpath=input_filepath)

        result = state.result[bin_year_built_into_census_categories].result
        result.to_parquet(output_filepath)
Exemple #25
0
    def run(self, input_filepath: Path, output_filepath: Path) -> pd.DataFrame:
        """Run Flow.

        Args:
            input_filepath (Path): Path to Clean BER Data
            output_filepath (Path): Path to BER archetypes
        """
        with raise_on_exception():
            state = self.flow.run(parameters=dict(ber_fpath=input_filepath))

        result = state.result[ber_archetypes].result

        result.to_parquet(output_filepath)
Exemple #26
0
def test_raise_on_exception_ignores_all_prefect_signals(signal):
    flow = Flow(name="test")

    @prefect.task
    def raise_signal():
        if (prefect.context.get("task_loop_count", 1) < 2
                and prefect.context.get("task_run_count", 1) < 2
                and signal.__name__ != "PAUSE"):
            raise signal("my message")

    flow.add_task(raise_signal)
    with raise_on_exception():
        flow_state = flow.run()
Exemple #27
0
def test_auto_manage_dataframe_init_overwrite(local_file):
    task = TaskWithInputDataFrame(input_one_key='/bar')

    with Flow('test_auto_manage_dataframe_init_overwrite') as flow:
        file = prefect.Parameter('local_file', default=local_file)
        task(input_one=file)

    with raise_on_exception(), prefect.context(caches={}):
        flow_state = flow.run()

    result = list(flow_state.result.values())[0].result

    df_bar = pd.read_hdf(local_file.file, '/bar')
    assert isinstance(df_bar, pd.DataFrame)

    tm.assert_equal(result, df_bar.mean())
Exemple #28
0
    def test_flatmap_reduced_result(self, executor):
        # flatmap over a reduced flattened mapped task
        ll = ListTask()
        nest = NestTask()
        a = AddTask()

        with Flow(name="test") as f:
            nested = nest.map(ll())
            nested2 = nest(flatten(nested))
            x = a.map(flatten(nested2))

        from prefect.utilities.debug import raise_on_exception

        with raise_on_exception():
            s = f.run(executor=executor)

        assert s.result[x].result == [2, 3, 4]
Exemple #29
0
def test(e: Optional[Executor]):
    with TemporaryDirectory() as tmpdir:
        flow_result = LocalResult(tmpdir, serializer=JSONSerializer(),
                                  location="{task_name}.json")

        with Flow("write_result", result=flow_result) as f:
            _terminal = task(lambda: 42, checkpoint=True, name="magic")()

        with set_temporary_config({"flows.checkpointing": True}), \
             raise_on_exception():
            f.run(executor=e)

        files = os.listdir(tmpdir)
        assert files == ["magic.json"], files
        with open(os.path.join(tmpdir, files[0]), "rb") as file:
            val = json.load(file)
        assert val==42
Exemple #30
0
def test_auto_manage_dataframe_default_string(local_file):
    task = TaskWithInputDataFrame()
    filename = local_file.file.resolve()

    with Flow('test_auto_manage_dataframe_default_string') as flow:
        file = prefect.Parameter('local_file', default=filename)
        task(input_one=file)

    with raise_on_exception(), prefect.context(caches={}):
        flow_state = flow.run()

    result = list(flow_state.result.values())[0].result

    df_foo = pd.read_hdf(local_file.file, '/foo')
    assert isinstance(df_foo, pd.DataFrame)

    tm.assert_equal(result, df_foo.mean())