Hide live tie metadata and stream CI logs
This commit is contained in:
parent
3e2400616b
commit
24d4c0a253
|
|
@ -282,6 +282,11 @@ class GroupStageService
|
||||||
compared_group_score = sorted_group_scores[comparison_index]
|
compared_group_score = sorted_group_scores[comparison_index]
|
||||||
comparison_reason = group_score.comparison_reason_against(compared_group_score)
|
comparison_reason = group_score.comparison_reason_against(compared_group_score)
|
||||||
|
|
||||||
|
if comparison_reason[:tied] && !group_ready_for_decider_check
|
||||||
|
decisions[group_score_cache_key(group_score)] = nil
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
decisions[group_score_cache_key(group_score)] = {
|
decisions[group_score_cache_key(group_score)] = {
|
||||||
resolved_by: comparison_reason[:resolved_by].to_s,
|
resolved_by: comparison_reason[:resolved_by].to_s,
|
||||||
compared_with_team_id: compared_group_score.team.id,
|
compared_with_team_id: compared_group_score.team.id,
|
||||||
|
|
|
||||||
|
|
@ -300,7 +300,7 @@ RSpec.describe GroupStageService do
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not request a decider while regular matches in the group are still unfinished' do
|
it 'does not expose unresolved tie metadata while regular matches in the group are still unfinished' do
|
||||||
tournament.update!(playoff_teams_amount: 1, instant_finalists_amount: 1, intermediate_round_participants_amount: 0)
|
tournament.update!(playoff_teams_amount: 1, instant_finalists_amount: 1, intermediate_round_participants_amount: 0)
|
||||||
|
|
||||||
create(:group_match, group: group, state: :in_progress).tap do |match|
|
create(:group_match, group: group, state: :in_progress).tap do |match|
|
||||||
|
|
@ -315,23 +315,11 @@ RSpec.describe GroupStageService do
|
||||||
|
|
||||||
GroupStageService.send(:recalculate_position_of_group_scores!, [score_a, score_b, score_c, score_d]).each(&:save!)
|
GroupStageService.send(:recalculate_position_of_group_scores!, [score_a, score_b, score_c, score_d]).each(&:save!)
|
||||||
|
|
||||||
expect(GroupStageService.ranking_decision_for(score_a)).to include(
|
expect(GroupStageService.ranking_decision_for(score_a)).to be_nil
|
||||||
resolved_by: 'tie',
|
expect(GroupStageService.ranking_decision_for(score_b)).to be_nil
|
||||||
direct_comparison_result: 'draw',
|
|
||||||
hidden_points_result: 'not_played',
|
|
||||||
tied: true,
|
|
||||||
needs_decider_match: false
|
|
||||||
)
|
|
||||||
expect(GroupStageService.ranking_decision_for(score_b)).to include(
|
|
||||||
resolved_by: 'tie',
|
|
||||||
direct_comparison_result: 'draw',
|
|
||||||
hidden_points_result: 'not_played',
|
|
||||||
tied: true,
|
|
||||||
needs_decider_match: false
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'marks unresolved ties outside the advancing cutoff without requesting a decider' do
|
it 'does not expose unresolved tie metadata outside the advancing cutoff before the group is finished' do
|
||||||
tournament.update!(playoff_teams_amount: 2, instant_finalists_amount: 2, intermediate_round_participants_amount: 0)
|
tournament.update!(playoff_teams_amount: 2, instant_finalists_amount: 2, intermediate_round_participants_amount: 0)
|
||||||
|
|
||||||
score_a = create(:group_score, group: group, team: team_a, group_points: 9, scored_points: 5, received_points: 1, position: 1)
|
score_a = create(:group_score, group: group, team: team_a, group_points: 9, scored_points: 5, received_points: 1, position: 1)
|
||||||
|
|
@ -342,18 +330,8 @@ RSpec.describe GroupStageService do
|
||||||
GroupStageService.send(:recalculate_position_of_group_scores!, [score_a, score_b, score_c, score_d]).each(&:save!)
|
GroupStageService.send(:recalculate_position_of_group_scores!, [score_a, score_b, score_c, score_d]).each(&:save!)
|
||||||
|
|
||||||
expect([score_a.position, score_b.position, score_c.position, score_d.position]).to eq([1, 2, 3, 3])
|
expect([score_a.position, score_b.position, score_c.position, score_d.position]).to eq([1, 2, 3, 3])
|
||||||
expect(GroupStageService.ranking_decision_for(score_c)).to include(
|
expect(GroupStageService.ranking_decision_for(score_c)).to be_nil
|
||||||
resolved_by: 'tie',
|
expect(GroupStageService.ranking_decision_for(score_d)).to be_nil
|
||||||
hidden_points_result: 'not_played',
|
|
||||||
tied: true,
|
|
||||||
needs_decider_match: false
|
|
||||||
)
|
|
||||||
expect(GroupStageService.ranking_decision_for(score_d)).to include(
|
|
||||||
resolved_by: 'tie',
|
|
||||||
hidden_points_result: 'not_played',
|
|
||||||
tied: true,
|
|
||||||
needs_decider_match: false
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'uses the decider hidden points to resolve a cutoff tie' do
|
it 'uses the decider hidden points to resolve a cutoff tie' do
|
||||||
|
|
|
||||||
52
tasks.py
52
tasks.py
|
|
@ -131,6 +131,31 @@ def _run_subprocess(command, env=None, capture_output=False, check=True):
|
||||||
return completed
|
return completed
|
||||||
|
|
||||||
|
|
||||||
|
def _stream_subprocess(command, env=None, check=True):
|
||||||
|
process = subprocess.Popen(
|
||||||
|
command,
|
||||||
|
env=env,
|
||||||
|
text=True,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.STDOUT,
|
||||||
|
bufsize=1,
|
||||||
|
)
|
||||||
|
|
||||||
|
output_chunks = []
|
||||||
|
assert process.stdout is not None
|
||||||
|
for line in process.stdout:
|
||||||
|
print(line, end="")
|
||||||
|
output_chunks.append(line)
|
||||||
|
|
||||||
|
process.wait()
|
||||||
|
output = "".join(output_chunks)
|
||||||
|
|
||||||
|
if check and process.returncode != 0:
|
||||||
|
raise subprocess.CalledProcessError(process.returncode, command, output=output, stderr=None)
|
||||||
|
|
||||||
|
return subprocess.CompletedProcess(command, process.returncode, stdout=output, stderr="")
|
||||||
|
|
||||||
|
|
||||||
def _compose_env(
|
def _compose_env(
|
||||||
host_port=SERVER_PORT,
|
host_port=SERVER_PORT,
|
||||||
app_image=PRODUCTION_TAG,
|
app_image=PRODUCTION_TAG,
|
||||||
|
|
@ -164,6 +189,15 @@ def _format_command(command):
|
||||||
return " ".join(shlex.quote(part) for part in command)
|
return " ".join(shlex.quote(part) for part in command)
|
||||||
|
|
||||||
|
|
||||||
|
def _rspec_command(*paths):
|
||||||
|
command = ["bundle", "exec", "rspec", *paths]
|
||||||
|
if os.environ.get("CI"):
|
||||||
|
command.extend(["--format", "documentation", "--no-color"])
|
||||||
|
else:
|
||||||
|
command.extend(["--format", "progress", "--tty"])
|
||||||
|
return command
|
||||||
|
|
||||||
|
|
||||||
def _compose_run(compose_args, env, capture_output=False, check=True):
|
def _compose_run(compose_args, env, capture_output=False, check=True):
|
||||||
command = _docker_compose_cmd() + compose_args
|
command = _docker_compose_cmd() + compose_args
|
||||||
return _run_subprocess(command, env=env, capture_output=capture_output, check=check)
|
return _run_subprocess(command, env=env, capture_output=capture_output, check=check)
|
||||||
|
|
@ -283,13 +317,9 @@ def _run_blackbox_rspec(base_url, email, password, username, alt_email=E2E_ALT_E
|
||||||
TURNIERE_E2E_ALT_PASSWORD=alt_password,
|
TURNIERE_E2E_ALT_PASSWORD=alt_password,
|
||||||
TURNIERE_E2E_ALT_USERNAME=alt_username,
|
TURNIERE_E2E_ALT_USERNAME=alt_username,
|
||||||
)
|
)
|
||||||
command = ["bundle", "exec", "rspec", "spec/e2e/http", "--format", "documentation"]
|
command = _rspec_command("spec/e2e/http")
|
||||||
print(_format_command(command))
|
print(_format_command(command))
|
||||||
result = _run_subprocess(command, env=env, capture_output=True, check=False)
|
result = _stream_subprocess(command, env=env, check=False)
|
||||||
if result.stdout:
|
|
||||||
print(result.stdout.rstrip())
|
|
||||||
if result.stderr:
|
|
||||||
print(result.stderr.rstrip())
|
|
||||||
|
|
||||||
report = _parse_rspec_report(f"{result.stdout}\n{result.stderr}")
|
report = _parse_rspec_report(f"{result.stdout}\n{result.stderr}")
|
||||||
_print_header("Blackbox report")
|
_print_header("Blackbox report")
|
||||||
|
|
@ -419,7 +449,7 @@ def start_test_local(
|
||||||
@task
|
@task
|
||||||
def test(c):
|
def test(c):
|
||||||
"""Run the normal RSpec suite."""
|
"""Run the normal RSpec suite."""
|
||||||
c.run(_bundle_exec("rspec", "--format", "progress", "--tty"), pty=True)
|
_stream_subprocess(_rspec_command(), env=_env())
|
||||||
|
|
||||||
|
|
||||||
@task(name="test-shard")
|
@task(name="test-shard")
|
||||||
|
|
@ -451,11 +481,9 @@ def test_shard(c, node_index=1, node_total=8, dry_run=False):
|
||||||
if not files:
|
if not files:
|
||||||
return
|
return
|
||||||
|
|
||||||
c.run(
|
_stream_subprocess(
|
||||||
_bundle_exec("rspec", "--format", "progress", "--tty") +
|
_rspec_command("--require", "./spec/rails_helper", *files),
|
||||||
" --require ./spec/rails_helper " +
|
env=_env(),
|
||||||
" ".join(shlex.quote(path) for path in files),
|
|
||||||
pty=True,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue