summaryrefslogtreecommitdiff
path: root/tests/frontend/logging.py
blob: 6a17bf7715d4572b580dad251a9b77ec344d95bb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# Pylint doesn't play well with fixtures and dependency injection from pytest
# pylint: disable=redefined-outer-name

import os
import re

import pytest

from buildstream.testing import create_repo

from buildstream import _yaml
from buildstream._exceptions import ErrorDomain
from buildstream.testing import cli  # pylint: disable=unused-import

# Project directory
DATA_DIR = os.path.join(
    os.path.dirname(os.path.realpath(__file__)),
    "project",
)


@pytest.mark.datafiles(DATA_DIR)
def test_default_logging(cli, tmpdir, datafiles):
    project = str(datafiles)
    bin_files_path = os.path.join(project, 'files', 'bin-files')
    element_path = os.path.join(project, 'elements')
    element_name = 'fetch-test-git.bst'

    # Create our repo object of the given source type with
    # the bin files, and then collect the initial ref.
    #
    repo = create_repo('git', str(tmpdir))
    ref = repo.create(bin_files_path)

    # Write out our test target
    element = {
        'kind': 'import',
        'sources': [
            repo.source_config(ref=ref)
        ]
    }
    _yaml.roundtrip_dump(element,
                         os.path.join(element_path, element_name))

    # Now try to fetch it
    result = cli.run(project=project, args=['source', 'fetch', element_name])
    result.assert_success()

    m = re.search(r"\[\d\d:\d\d:\d\d\]\[\s*\]\[.*\] SUCCESS Checking sources", result.stderr)
    assert m is not None


@pytest.mark.datafiles(DATA_DIR)
def test_custom_logging(cli, tmpdir, datafiles):
    project = str(datafiles)
    bin_files_path = os.path.join(project, 'files', 'bin-files')
    element_path = os.path.join(project, 'elements')
    element_name = 'fetch-test-git.bst'

    custom_log_format = ('%{elapsed},%{elapsed-us},%{wallclock},%{wallclock-us},'
                         '%{key},%{element},%{action},%{message}')
    user_config = {'logging': {'message-format': custom_log_format}}
    cli.configure(user_config)

    # Create our repo object of the given source type with
    # the bin files, and then collect the initial ref.
    #
    repo = create_repo('git', str(tmpdir))
    ref = repo.create(bin_files_path)

    # Write out our test target
    element = {
        'kind': 'import',
        'sources': [
            repo.source_config(ref=ref)
        ]
    }
    _yaml.roundtrip_dump(element,
                         os.path.join(element_path, element_name))

    # Now try to fetch it
    result = cli.run(project=project, args=['source', 'fetch', element_name])
    result.assert_success()

    m = re.search(r"\d\d:\d\d:\d\d,\d\d:\d\d:\d\d.\d{6},\d\d:\d\d:\d\d,\d\d:\d\d:\d\d.\d{6}\s*,.*"
                  r",SUCCESS,Checking sources", result.stderr)
    assert m is not None


@pytest.mark.datafiles(DATA_DIR)
def test_failed_build_listing(cli, datafiles):
    project = str(datafiles)
    element_names = []
    for i in range(3):
        element_name = 'testfail-{}.bst'.format(i)
        element_path = os.path.join('elements', element_name)
        element = {
            'kind': 'script',
            'config': {
                'commands': [
                    'false'
                ]
            }
        }
        _yaml.roundtrip_dump(element, os.path.join(project, element_path))
        element_names.append(element_name)
    result = cli.run(project=project, args=['--on-error=continue', 'build', *element_names])
    result.assert_main_error(ErrorDomain.STREAM, None)

    # Check that we re-print the failure summaries only in the "Failure Summary"
    # section.
    # e.g.
    #
    # Failure Summary
    #   testfail-0.bst:
    #     [00:00:00][44f1b8c3][   build:testfail-0.bst                ] FAILURE Running 'commands'
    #
    failure_heading_pos = re.search(r'^Failure Summary$', result.stderr, re.MULTILINE).start()
    pipeline_heading_pos = re.search(r'^Pipeline Summary$', result.stderr, re.MULTILINE).start()
    failure_summary_range = range(failure_heading_pos, pipeline_heading_pos)
    matches = tuple(re.finditer(r'^\s+testfail-.\.bst:$', result.stderr, re.MULTILINE))
    for m in matches:
        assert m.start() in failure_summary_range
        assert m.end() in failure_summary_range
    assert len(matches) == 3  # each element should be matched once.

    # Note that if we mess up the 'unique_id' of Messages, they won't be printed
    # with the name of the relevant element, e.g. 'testfail-1.bst'. Check that
    # they have the name as expected.
    pattern = r"\[..:..:..\] FAILURE testfail-.\.bst: Staged artifacts do not provide command 'sh'"
    assert len(re.findall(pattern, result.stderr, re.MULTILINE)) == 6  # each element should be matched twice.