blob: ce137b00563712353f061059b51b64b4635f1474 [file] [log] [blame]
# Copyright 2020 The LUCI Authors. All rights reserved.
# Use of this source code is governed under the Apache License, Version 2.0
# that can be found in the LICENSE file.
from recipe_engine import post_process
from recipe_engine.config_types import Path
from google.protobuf import json_format as jsonpb
from google.protobuf import timestamp_pb2
from PB.recipe_modules.recipe_engine.step.tests import (
properties as properties_pb2
)
from PB.go.chromium.org.luci.buildbucket.proto import build as build_pb2
from PB.go.chromium.org.luci.buildbucket.proto import common as common_pb2
from PB.go.chromium.org.luci.buildbucket.proto import step as step_pb2
DEPS = [
'assertions',
'context',
'json',
'path',
'properties',
'step',
]
PROPERTIES = properties_pb2.SubBuildInputProps
def RunSteps(api, props):
output_path = None
if props.HasField('output_path'):
output_path = (
api.path[props.output_path.base].join(props.output_path.file))
with api.context(infra_steps=props.infra_step):
input_build = props.input_build if props.HasField('input_build') else (
build_pb2.Build(id=11111, status=common_pb2.SCHEDULED))
ret = api.step.sub_build(
'launch sub build',
['luciexe', '--foo', 'bar', '--json-summary', api.json.output()],
input_build,
output_path=output_path,
step_test_data= lambda: (
api.json.test_api.output('{"hello": "world"}') +
api.step.test_api.sub_build(
build_pb2.Build(id=11111, status=common_pb2.SUCCESS))
),
)
api.assertions.assertIsNotNone(ret.step.sub_build)
if props.HasField('expected_sub_build'):
api.assertions.assertEqual(ret.step.sub_build, props.expected_sub_build)
def GenTests(api):
yield (
api.test('basic') +
api.properties(properties_pb2.SubBuildInputProps(
expected_sub_build=build_pb2.Build(id=11111, status=common_pb2.SUCCESS),
))
)
yield (
api.test('output') +
api.properties(properties_pb2.SubBuildInputProps(
output_path=properties_pb2.SubBuildInputProps.Path(
base='start_dir',
file='sub_build.json'),
expected_sub_build=build_pb2.Build(id=45678, status=common_pb2.SUCCESS),
)) +
api.step_data('launch sub build', api.step.sub_build(
build_pb2.Build(id=45678, status=common_pb2.SUCCESS))
)
)
yield (
api.test('output_file_exists') +
api.properties(
output_path=properties_pb2.SubBuildInputProps.Path(
base='start_dir',
file='sub_build.json'),
) +
api.path.exists(api.path['start_dir'].join('sub_build.json')) +
api.expect_exception('ValueError') +
api.post_process(
post_process.ResultReasonRE,
r'.*expected non-existent output path') +
api.post_process(post_process.DropExpectation)
)
yield (
api.test('invalid_extension') +
api.properties(properties_pb2.SubBuildInputProps(
output_path=properties_pb2.SubBuildInputProps.Path(
base='start_dir',
file='sub_build.yaml'),
)) +
api.expect_exception('ValueError') +
api.post_process(
post_process.ResultReasonRE,
r'.*expected extension of output path to be one of') +
api.post_process(post_process.DropExpectation)
)
yield (
api.test('failure_status') +
api.step_data('launch sub build', api.step.sub_build(
build_pb2.Build(id=1, status=common_pb2.FAILURE))
) +
api.post_process(post_process.StepFailure, 'launch sub build') +
api.post_process(post_process.DropExpectation)
)
yield (
api.test('infra_failure_status') +
api.step_data('launch sub build', api.step.sub_build(
build_pb2.Build(id=1, status=common_pb2.INFRA_FAILURE))
) +
api.post_process(post_process.StepException, 'launch sub build') +
api.post_process(post_process.DropExpectation)
)
yield (
api.test('infra_step') +
api.step_data('launch sub build', api.step.sub_build(
build_pb2.Build(id=1, status=common_pb2.FAILURE))
) +
api.properties(properties_pb2.SubBuildInputProps(infra_step=True)) +
api.post_process(post_process.StepException, 'launch sub build') +
api.post_process(post_process.DropExpectation)
)
yield (
api.test('output_summary_markdown') +
api.step_data('launch sub build', api.step.sub_build(
build_pb2.Build(id=1, status=common_pb2.SUCCESS,
summary_markdown='This is the summary of sub build'))
) +
api.post_process(post_process.StepTextEquals, 'launch sub build',
'This is the summary of sub build')+
api.post_process(post_process.DropExpectation)
)
build = build_pb2.Build(id=1234, status=common_pb2.SUCCESS)
build.output.logs.extend([
common_pb2.Log(
name='cool',
url='some/cool',
),
common_pb2.Log(
name='awesome',
url='some/awesome',
)
])
yield (
api.test('merge_output_logs') +
api.step_data('launch sub build', api.step.sub_build(build))
)
yield (
api.test('non_terminal_status') +
api.step_data('launch sub build', api.step.sub_build(
build_pb2.Build(id=1, status=common_pb2.STARTED))
) +
api.post_process(post_process.StepException, 'launch sub build') +
api.post_process(post_process.StepTextEquals, 'launch sub build',
'Merge Step Error: expected terminal build status of sub build; '
'got status: STARTED.')+
api.post_process(post_process.DropExpectation)
)
yield (
api.test('output_missing') +
api.step_data('launch sub build', api.step.sub_build(None)) +
api.post_process(post_process.StepException, 'launch sub build') +
api.post_process(post_process.StepTextEquals, 'launch sub build',
"Merge Step Error: Can't find the final build output for luciexe.") +
api.post_process(post_process.DropExpectation)
)
input_build=build_pb2.Build(
id=88888,
status=common_pb2.INFRA_FAILURE,
status_details=common_pb2.StatusDetails(
timeout=common_pb2.StatusDetails.Timeout()),
create_time=timestamp_pb2.Timestamp(seconds=1598338800),
start_time=timestamp_pb2.Timestamp(seconds=1598338801),
end_time=timestamp_pb2.Timestamp(seconds=1598425200),
update_time=timestamp_pb2.Timestamp(seconds=1598425200),
summary_markdown='awesome summary',
steps=[step_pb2.Step(name='first step'),],
tags=[common_pb2.StringPair(key='foo', value='bar'),],
)
build.output.properties['some_key'] = 'some_value'
build.output.logs.add(name='stdout')
def check_luciexe_initial_build(check, steps):
initial_build = build_pb2.Build()
initial_build.ParseFromString(steps['launch sub build'].stdin)
check(initial_build.id == 88888)
check(initial_build.status == common_pb2.STARTED)
check(initial_build.create_time.ToSeconds() == 1677836800)
check(initial_build.start_time.ToSeconds() == 1677836801)
check(initial_build.tags == input_build.tags)
check(not initial_build.summary_markdown)
check(not initial_build.HasField('status_details'))
check(not initial_build.HasField('end_time'))
check(not initial_build.HasField('update_time'))
check(not initial_build.steps)
check(not initial_build.HasField('output'))
yield (
api.test('clear_fields_of_input_build') +
api.properties(properties_pb2.SubBuildInputProps(
input_build=input_build,
)) +
api.step.initial_build_create_time(1677836800) +
api.step.initial_build_start_time(1677836801) +
api.post_check(check_luciexe_initial_build) +
api.post_process(post_process.DropExpectation)
)