# Path: test/cfg.py
# class ApiType(Enum):
#     JENKINS = 0
#     SCRIPT = 1
#     MOCK = 2
# 
# Path: test/framework/api_select.py
# def api(file_name, api_type, login=None, fixed_prefix=None, url_or_dir=None, fake_public_uri=None, invocation_class=None,
#         username=None, password=None):
# 
# Path: test/framework/utils.py
# def lines_in(api_type, text, *expected_lines):
#     """Assert that `*expected_lines` occur in order in the lines of `text`.
# 
#     Args:
#         *expected_lines (str or RegexObject (hasattr `match`)): For each `expected_line` in expected_lines:
#             If `expected_line` has a match method it is called and must return True for a line in `text`.
#             Otherwise, if the `expected_line` starts with '^', a line in `text` must start with `expected_line[1:]`
#             Otherwise `expected line` must simply occur in a line in `text`
#     """
# 
#     assert isinstance(api_type, test_cfg.ApiType)
#     assert text
#     assert expected_lines
# 
#     return generic_lines_in(text, partial(replace_host_port, api_type), *expected_lines)
# 
# def replace_host_port(api_type, contains_url):
#     if api_type != ApiType.SCRIPT:
#         return _http_re.sub(r'http://x.x/job/\1\2', contains_url)
#     else:
#         return _http_re.sub(r'/tmp/jenkinsflow-test/job/\1.py', contains_url)
# 
# def result_msg(api, job_name, num=None):
#     if api.api_type == ApiType.SCRIPT:
#         return repr(job_name) + " - build: " + _script_api_log_file(job_name)
#     return repr(job_name) + " - build: http://x.x/job/" + job_name + "/" + (str(num) + "/console" if api.api_type == ApiType.MOCK and num else "")
# 
# def build_started_msg(api, job_name, num, invocation_number=0):
#     return "Build started: " + repr(job_name) + ((' Invocation-' + repr(invocation_number)) if invocation_number else '') + " - " + console_url(api, job_name, num)


import re
from pytest import raises
from jenkinsflow.flow import serial, parallel, FailedChildJobException
from .cfg import ApiType
from .framework import api_select
from .framework.utils import lines_in, replace_host_port, result_msg, build_started_msg
        api.job('j23', max_fails=0, expect_invocations=1, expect_order=3)
        api.job('j13', max_fails=0, expect_invocations=1, expect_order=4, serial=True)

        with serial(api, timeout=70, job_name_prefix=api.job_name_prefix, max_tries=2) as ctrl1:
            ctrl1.invoke('j11_fail')
            ctrl1.invoke('j12')

            with ctrl1.parallel(timeout=70, max_tries=3) as ctrl2:
                ctrl2.invoke('j21')
                ctrl2.invoke('j22_fail')
                with ctrl2.serial(timeout=70, max_tries=2) as ctrl3:
                    ctrl3.invoke('j31_fail')
                    ctrl3.invoke('j32')
                ctrl2.invoke('j23')

            ctrl1.invoke('j13')

        sout, _ = capsys.readouterr()
        outer_flow_repr = "['jenkinsflow_test__reporting_retry__j11_fail', 'jenkinsflow_test__reporting_retry__j12', " \
                          "('jenkinsflow_test__reporting_retry__j21', 'jenkinsflow_test__reporting_retry__j22_fail', " \
                          "['jenkinsflow_test__reporting_retry__j31_fail', 'jenkinsflow_test__reporting_retry__j32'], " \
                          "'jenkinsflow_test__reporting_retry__j23'), 'jenkinsflow_test__reporting_retry__j13']"
        assert lines_in(
            api_type, sout,
            "^Flow Invocation (1/2,1/2): " + outer_flow_repr,
            "^Job Invocation (1/2,1/2): http://x.x/job/jenkinsflow_test__reporting_retry__j11_fail",
            build_started_msg(api, "jenkinsflow_test__reporting_retry__j11_fail", 1),
            "^FAILURE: 'jenkinsflow_test__reporting_retry__j11_fail'",
            "^RETRY: job: 'jenkinsflow_test__reporting_retry__j11_fail' failed, retrying child jobs from beginning. Up to 1 more times in current flow",
            "^Job Invocation (2/2,2/2): http://x.x/job/jenkinsflow_test__reporting_retry__j11_fail",

# Path: test/cfg.py
# class ApiType(Enum):
#     JENKINS = 0
#     SCRIPT = 1
#     MOCK = 2
# 
# Path: test/framework/api_select.py
# def api(file_name, api_type, login=None, fixed_prefix=None, url_or_dir=None, fake_public_uri=None, invocation_class=None,
#         username=None, password=None):
# 
# Path: test/framework/utils.py
# def lines_in(api_type, text, *expected_lines):
#     """Assert that `*expected_lines` occur in order in the lines of `text`.
# 
#     Args:
#         *expected_lines (str or RegexObject (hasattr `match`)): For each `expected_line` in expected_lines:
#             If `expected_line` has a match method it is called and must return True for a line in `text`.
#             Otherwise, if the `expected_line` starts with '^', a line in `text` must start with `expected_line[1:]`
#             Otherwise `expected line` must simply occur in a line in `text`
#     """
# 
#     assert isinstance(api_type, test_cfg.ApiType)
#     assert text
#     assert expected_lines
# 
#     return generic_lines_in(text, partial(replace_host_port, api_type), *expected_lines)
# 
# def replace_host_port(api_type, contains_url):
#     if api_type != ApiType.SCRIPT:
#         return _http_re.sub(r'http://x.x/job/\1\2', contains_url)
#     else:
#         return _http_re.sub(r'/tmp/jenkinsflow-test/job/\1.py', contains_url)
# 
# def result_msg(api, job_name, num=None):
#     if api.api_type == ApiType.SCRIPT:
#         return repr(job_name) + " - build: " + _script_api_log_file(job_name)
#     return repr(job_name) + " - build: http://x.x/job/" + job_name + "/" + (str(num) + "/console" if api.api_type == ApiType.MOCK and num else "")
# 
# def build_started_msg(api, job_name, num, invocation_number=0):
#     return "Build started: " + repr(job_name) + ((' Invocation-' + repr(invocation_number)) if invocation_number else '') + " - " + console_url(api, job_name, num)


# Path: test/reporting_test.py
import re
from pytest import raises
from jenkinsflow.flow import serial, parallel, FailedChildJobException
from .cfg import ApiType
from .framework import api_select
from .framework.utils import lines_in, replace_host_port, result_msg, build_started_msg

        api.job('j23', max_fails=0, expect_invocations=1, expect_order=3)
        api.job('j13', max_fails=0, expect_invocations=1, expect_order=4, serial=True)

        with serial(api, timeout=70, job_name_prefix=api.job_name_prefix, max_tries=2) as ctrl1:
            ctrl1.invoke('j11_fail')
            ctrl1.invoke('j12')

            with ctrl1.parallel(timeout=70, max_tries=3) as ctrl2:
                ctrl2.invoke('j21')
                ctrl2.invoke('j22_fail')
                with ctrl2.serial(timeout=70, max_tries=2) as ctrl3:
                    ctrl3.invoke('j31_fail')
                    ctrl3.invoke('j32')
                ctrl2.invoke('j23')

            ctrl1.invoke('j13')

        sout, _ = capsys.readouterr()
        outer_flow_repr = "['jenkinsflow_test__reporting_retry__j11_fail', 'jenkinsflow_test__reporting_retry__j12', " \
                          "('jenkinsflow_test__reporting_retry__j21', 'jenkinsflow_test__reporting_retry__j22_fail', " \
                          "['jenkinsflow_test__reporting_retry__j31_fail', 'jenkinsflow_test__reporting_retry__j32'], " \
                          "'jenkinsflow_test__reporting_retry__j23'), 'jenkinsflow_test__reporting_retry__j13']"
        assert lines_in(
            api_type, sout,
            "^Flow Invocation (1/2,1/2): " + outer_flow_repr,
            "^Job Invocation (1/2,1/2): http://x.x/job/jenkinsflow_test__reporting_retry__j11_fail",
            build_started_msg(api, "jenkinsflow_test__reporting_retry__j11_fail", 1),
            "^FAILURE: 'jenkinsflow_test__reporting_retry__j11_fail'",
            "^RETRY: job: 'jenkinsflow_test__reporting_retry__j11_fail' failed, retrying child jobs from beginning. Up to 1 more times in current flow",
            "^Job Invocation (2/2,2/2): http://x.x/job/jenkinsflow_test__reporting_retry__j11_fail",

            build_started_msg(api, "jenkinsflow_test__reporting_retry__j11_fail", 2),