Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

qa-engine: define cloud eligibility #21961

Merged
merged 5 commits into from
Jan 27, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions tools/ci_connector_ops/ci_connector_ops/qa_engine/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#


from datetime import datetime
from enum import Enum
from typing import List

Expand Down Expand Up @@ -32,6 +33,8 @@ class ConnectorQAReport(BaseModel):
number_of_connections: int
number_of_users: int
sync_success_rate: float
is_eligible_for_cloud: bool
report_generation_datetime: datetime

class QAReport(BaseModel):
connectors_qa_report: List[ConnectorQAReport]
24 changes: 24 additions & 0 deletions tools/ci_connector_ops/ci_connector_ops/qa_engine/validations.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,22 @@
#


from datetime import datetime
from typing import Iterable

import pandas as pd
import requests

from .constants import INAPPROPRIATE_FOR_CLOUD_USE_CONNECTORS
from .inputs import OSS_CATALOG
from .models import ConnectorQAReport, QAReport

TRUTHY_COLUMNS_TO_BE_ELIGIBLE = [
"documentation_is_available",
"is_appropriate_for_cloud_use",
"latest_build_is_successful"
]

class QAReportGenerationError(Exception):
pass

Expand All @@ -20,6 +29,14 @@ def url_is_reachable(url: str) -> bool:
def is_appropriate_for_cloud_use(definition_id: str) -> bool:
return definition_id not in INAPPROPRIATE_FOR_CLOUD_USE_CONNECTORS

def is_eligible_for_cloud(connector_qa_data: pd.Series) -> bool:
if connector_qa_data["is_on_cloud"]:
return False
erohmensing marked this conversation as resolved.
Show resolved Hide resolved
return all([
connector_qa_data[col]
for col in TRUTHY_COLUMNS_TO_BE_ELIGIBLE
])

def get_qa_report(enriched_catalog: pd.DataFrame) -> pd.DataFrame:
"""Perform validation steps on top of the enriched catalog.
Adds the following columns:
Expand Down Expand Up @@ -51,10 +68,17 @@ def get_qa_report(enriched_catalog: pd.DataFrame) -> pd.DataFrame:
qa_report["number_of_users"] = 0 # TODO, tracked in https://github.com/airbytehq/airbyte/issues/21721
qa_report["sync_success_rate"] = .0 # TODO, tracked in https://github.com/airbytehq/airbyte/issues/21721

qa_report["is_eligible_for_cloud"] = qa_report.apply(is_eligible_for_cloud, axis="columns")
qa_report["report_generation_datetime"] = datetime.utcnow()

# Only select dataframe columns defined in the ConnectorQAReport model.
qa_report= qa_report[[field.name for field in ConnectorQAReport.__fields__.values()]]
# Validate the report structure with pydantic QAReport model.
QAReport(connectors_qa_report=qa_report.to_dict(orient="records"))
if len(qa_report) != len(OSS_CATALOG):
raise QAReportGenerationError("The QA report does not contain all the connectors defined in the OSS catalog.")
return qa_report

def get_connectors_eligible_for_cloud(qa_report: pd.DataFrame) -> Iterable[ConnectorQAReport]:
for _, row in qa_report[qa_report["is_eligible_for_cloud"]].iterrows():
yield ConnectorQAReport(**row)
2 changes: 1 addition & 1 deletion tools/ci_connector_ops/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@


setup(
version="0.1.6",
version="0.1.8",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anticipating the bump of #21917

name="ci_connector_ops",
description="Packaged maintained by the connector operations team to perform CI for connectors",
author="Airbyte",
Expand Down
74 changes: 73 additions & 1 deletion tools/ci_connector_ops/tests/test_qa_engine/test_validations.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import pandas as pd
import pytest

from ci_connector_ops.qa_engine import inputs, enrichments, models, validations
from ci_connector_ops.qa_engine import enrichments, inputs, models, validations

@pytest.fixture
def enriched_catalog() -> pd.DataFrame:
Expand All @@ -32,3 +32,75 @@ def test_report_generation_error(enriched_catalog, mocker):
mocker.patch.object(validations, "url_is_reachable", mocker.Mock(return_value=True))
with pytest.raises(validations.QAReportGenerationError):
return validations.get_qa_report(enriched_catalog.sample(10))

@pytest.mark.parametrize(
"connector_qa_data, expected_to_be_eligible",
[
(
pd.Series({
"is_on_cloud": False,
"documentation_is_available": True,
"is_appropriate_for_cloud_use": True,
"latest_build_is_successful": True
}),
True
),
(
pd.Series({
"is_on_cloud": True,
"documentation_is_available": True,
"is_appropriate_for_cloud_use": True,
"latest_build_is_successful": True
}),
False
),
(
pd.Series({
"is_on_cloud": True,
"documentation_is_available": False,
"is_appropriate_for_cloud_use": False,
"latest_build_is_successful": False
}),
False
),
(
pd.Series({
"is_on_cloud": False,
"documentation_is_available": False,
"is_appropriate_for_cloud_use": True,
"latest_build_is_successful": True
}),
False
),
(
pd.Series({
"is_on_cloud": False,
"documentation_is_available": True,
"is_appropriate_for_cloud_use": False,
"latest_build_is_successful": True
}),
False
),
(
pd.Series({
"is_on_cloud": False,
"documentation_is_available": True,
"is_appropriate_for_cloud_use": True,
"latest_build_is_successful": False
}),
False
)
]
)
def test_is_eligible_for_cloud(connector_qa_data: pd.Series, expected_to_be_eligible: bool):
assert validations.is_eligible_for_cloud(connector_qa_data) == expected_to_be_eligible

def test_get_connectors_eligible_for_cloud(qa_report: pd.DataFrame):
qa_report["is_eligible_for_cloud"] = True
connectors_eligible_for_cloud = list(validations.get_connectors_eligible_for_cloud(qa_report))
assert len(qa_report) == len(connectors_eligible_for_cloud)
assert all([c.is_eligible_for_cloud for c in connectors_eligible_for_cloud])

qa_report["is_eligible_for_cloud"] = False
connectors_eligible_for_cloud = list(validations.get_connectors_eligible_for_cloud(qa_report))
assert len(connectors_eligible_for_cloud) == 0