Skip to content

Commit 8464ea3

Browse files
committed
feat(ci): add never-worked status for test regression classification
1 parent dda7618 commit 8464ea3

16 files changed

Lines changed: 325 additions & 77 deletions

File tree

install/ci-vm/ci-linux/startup-script.sh

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ curl -L -O https://github.com/GoogleCloudPlatform/gcsfuse/releases/download/v3.2
44
dpkg --install gcsfuse_3.2.0_amd64.deb
55
rm gcsfuse_3.2.0_amd64.deb
66

7-
apt install gnupg ca-certificates
7+
apt install -y gnupg ca-certificates
88
gpg --homedir /tmp --no-default-keyring --keyring /usr/share/keyrings/mono-official-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
99
echo "deb [signed-by=/usr/share/keyrings/mono-official-archive-keyring.gpg] https://download.mono-project.com/repo/ubuntu stable-focal main" | sudo tee /etc/apt/sources.list.d/mono-official-stable.list
1010
sudo apt update
@@ -14,7 +14,8 @@ mkdir repository
1414
cd repository
1515

1616
# Use gcsfuse and import required files
17-
mkdir temp TestFiles TestResults vm_data reports
17+
# TempFiles is used by the tester (--tempfolder) and must exist
18+
mkdir temp TestFiles TestResults TempFiles vm_data reports
1819

1920
gcs_bucket=$(curl http://metadata/computeMetadata/v1/instance/attributes/bucket -H "Metadata-Flavor: Google")
2021

@@ -31,6 +32,9 @@ mount vm_data
3132
mount TestFiles
3233
mount TestResults
3334

35+
# Give gcsfuse mounts time to become ready
36+
sleep 10
37+
3438
cp temp/* ./
3539

3640
chmod +x bootstrap
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"""Add never_worked column to regression_test table
2+
3+
Revision ID: d9f4e5a6b7c8
4+
Revises: c8f3a2b1d4e5
5+
Create Date: 2026-03-20 23:25:21.411651000000
6+
7+
"""
8+
import sqlalchemy as sa
9+
from alembic import op
10+
11+
# revision identifiers, used by Alembic.
12+
revision = 'd9f4e5a6b7c8'
13+
down_revision = 'c8f3a2b1d4e5'
14+
branch_labels = None
15+
depends_on = None
16+
17+
18+
def upgrade():
19+
# ### commands auto generated by Alembic - please adjust! ###
20+
op.add_column('regression_test', sa.Column('never_worked', sa.Boolean(), nullable=False, server_default='false'))
21+
# ### end Alembic commands ###
22+
23+
24+
def downgrade():
25+
# ### commands auto generated by Alembic - please adjust! ###
26+
op.drop_column('regression_test', 'never_worked')
27+
# ### end Alembic commands ###

mod_ci/controllers.py

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@
4545
from mod_sample.models import Issue
4646
from mod_test.controllers import get_test_results
4747
from mod_test.models import (Fork, Test, TestPlatform, TestProgress,
48-
TestResult, TestResultFile, TestStatus, TestType)
48+
TestResult, TestResultFile, TestResultStatus,
49+
TestStatus, TestType)
4950
from utility import is_valid_signature, request_from_github
5051

5152
# Timeout constants (in seconds)
@@ -2760,6 +2761,7 @@ def get_info_for_pr_comment(test: Test) -> PrCommentInfo:
27602761
extra_failed_tests = []
27612762
common_failed_tests = []
27622763
fixed_tests = []
2764+
never_worked_tests = []
27632765
category_stats = []
27642766

27652767
test_results = get_test_results(test)
@@ -2768,20 +2770,26 @@ def get_info_for_pr_comment(test: Test) -> PrCommentInfo:
27682770
category_name = category_results['category'].name
27692771

27702772
category_test_pass_count = 0
2771-
for test in category_results['tests']:
2772-
if not test['error']:
2773+
for t in category_results['tests']:
2774+
if not t['error']:
27732775
category_test_pass_count += 1
2774-
if last_test_master and getattr(test['test'], platform_column) != last_test_master.id:
2775-
fixed_tests.append(test['test'])
2776+
if last_test_master and getattr(t['test'], platform_column) != last_test_master.id:
2777+
fixed_tests.append(t['test'])
27762778
else:
2777-
if last_test_master and getattr(test['test'], platform_column) != last_test_master.id:
2778-
common_failed_tests.append(test['test'])
2779+
# Separate out tests that have NEVER passed on any CCExtractor version
2780+
if t['status'] == TestResultStatus.never_worked:
2781+
never_worked_tests.append(t['test'])
2782+
elif last_test_master and getattr(t['test'], platform_column) != last_test_master.id:
2783+
common_failed_tests.append(t['test'])
27792784
else:
2780-
extra_failed_tests.append(test['test'])
2785+
extra_failed_tests.append(t['test'])
27812786

27822787
category_stats.append(CategoryTestInfo(category_name, len(category_results['tests']), category_test_pass_count))
27832788

2784-
return PrCommentInfo(category_stats, extra_failed_tests, fixed_tests, common_failed_tests, last_test_master)
2789+
return PrCommentInfo(
2790+
category_stats, extra_failed_tests, fixed_tests, common_failed_tests,
2791+
last_test_master, never_worked_tests
2792+
)
27852793

27862794

27872795
def comment_pr(test: Test) -> str:
@@ -2817,6 +2825,9 @@ def comment_pr(test: Test) -> str:
28172825
log.debug(f"GitHub PR Comment ID {comment.id} Uploaded for Test_id: {test_id}")
28182826
except Exception as e:
28192827
log.error(f"GitHub PR Comment Failed for Test_id: {test_id} with Exception {e}")
2828+
2829+
# Determine PR status:
2830+
# SUCCESS if no regressions caused by PR (never_worked tests don't count)
28202831
return Status.SUCCESS if len(comment_info.extra_failed_tests) == 0 else Status.FAILURE
28212832

28222833

mod_ci/models.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,3 +179,4 @@ class PrCommentInfo:
179179
fixed_tests: List[RegressionTest]
180180
common_failed_tests: List[RegressionTest]
181181
last_test_master: Test
182+
never_worked_tests: List[RegressionTest]

mod_regression/controllers.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ def test_edit(regression_id):
160160
test.input_type = InputType.from_string(form.input_type.data)
161161
test.output_type = OutputType.from_string(form.output_type.data)
162162
test.description = form.description.data
163+
test.never_worked = form.never_worked.data
163164

164165
g.db.commit()
165166
g.log.info(f'regression test with id: {regression_id} updated!')
@@ -174,6 +175,7 @@ def test_edit(regression_id):
174175
form.input_type.data = test.input_type.value
175176
form.output_type.data = test.output_type.value
176177
form.description.data = test.description
178+
form.never_worked.data = test.never_worked
177179

178180
return {'form': form, 'regression_id': regression_id}
179181

@@ -247,6 +249,7 @@ def test_add():
247249
input_type=InputType.from_string(form.input_type.data),
248250
output_type=OutputType.from_string(form.output_type.data),
249251
description=form.description.data,
252+
never_worked=form.never_worked.data
250253
)
251254
g.db.add(new_test)
252255
category = Category.query.filter(Category.id == form.category_id.data).first()

mod_regression/forms.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
"""Maintain forms related to CRUD operations on regression tests."""
22

33
from flask_wtf import FlaskForm
4-
from wtforms import (HiddenField, IntegerField, SelectField, StringField,
5-
SubmitField, TextAreaField)
4+
from wtforms import (BooleanField, HiddenField, IntegerField, SelectField,
5+
StringField, SubmitField, TextAreaField)
66
from wtforms.validators import DataRequired, InputRequired, Length
77

88
from mod_regression.models import InputType, OutputType
@@ -36,6 +36,7 @@ class CommonTestForm(FlaskForm):
3636
)
3737
category_id = SelectField("Category", coerce=int)
3838
expected_rc = IntegerField("Expected Runtime Code", [InputRequired(message="Expected Runtime Code can't be empty")])
39+
never_worked = BooleanField("Never Worked", default=False)
3940

4041

4142
class AddTestForm(CommonTestForm):

mod_regression/models.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,10 @@ class RegressionTest(Base):
9797
last_passed_on_windows = Column(Integer, ForeignKey('test.id', onupdate="CASCADE", ondelete="SET NULL"))
9898
last_passed_on_linux = Column(Integer, ForeignKey('test.id', onupdate="CASCADE", ondelete="SET NULL"))
9999
description = Column(String(length=1024))
100+
never_worked = Column(Boolean(), default=False, nullable=False, server_default='false')
100101

101102
def __init__(self, sample_id, command, input_type, output_type, category_id, expected_rc,
102-
active=True, description="") -> None:
103+
active=True, description="", never_worked=False) -> None:
103104
"""
104105
Parametrized constructor for the RegressionTest model.
105106
@@ -117,7 +118,10 @@ def __init__(self, sample_id, command, input_type, output_type, category_id, exp
117118
:type expected_rc: int
118119
:param active: The value of the 'active' field of RegressionTest model
119120
:type active: bool
120-
121+
:param description: The value of the 'description' field of RegressionTest model
122+
:type description: str
123+
:param never_worked: Boolean flag whether the test has never worked for this sample
124+
:type never_worked: bool
121125
"""
122126
self.sample_id = sample_id
123127
self.command = command
@@ -127,6 +131,7 @@ def __init__(self, sample_id, command, input_type, output_type, category_id, exp
127131
self.expected_rc = expected_rc
128132
self.active = active
129133
self.description = description
134+
self.never_worked = never_worked
130135

131136
def __repr__(self) -> str:
132137
"""

0 commit comments

Comments
 (0)