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

Adding Code Coverage webserver code and Fix TypeError and AttributeError in Views.py #40254

Merged
merged 33 commits into from
Jul 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
e985287
Fix unit tests for coverage issue and refactor request handling
andyjianzhou Jun 15, 2024
9ad4404
Spaces fix
andyjianzhou Jun 15, 2024
a20d7eb
Adding coverage
andyjianzhou Jun 15, 2024
e081547
Fixed spacing
andyjianzhou Jun 17, 2024
6a921bb
Changes before repo fix
andyjianzhou Jun 17, 2024
581646a
Increased Coverage to 85%, adding proper mock dag generation and resp…
andyjianzhou Jun 18, 2024
f04434d
Fixing conflicts
andyjianzhou Jul 10, 2024
6160f64
Fixing conflicts
andyjianzhou Jul 10, 2024
8224047
Re-added reset_dagruns mistake
andyjianzhou Jun 18, 2024
52b3b24
Fixed linting issues
andyjianzhou Jun 18, 2024
2890acb
linting issues
andyjianzhou Jun 19, 2024
98a9a76
Added Missing testCases for taskmap.py to 100%
andyjianzhou Jun 20, 2024
cb8ccb1
Pre-commit fixes
andyjianzhou Jun 24, 2024
d368d27
Pre-commit fixes
andyjianzhou Jun 24, 2024
44388b8
Removed unassigned dag_run functionality
Jun 25, 2024
7ac808a
Fix unittest date error
andyjianzhou Jul 2, 2024
dd9bd27
Resolving Pre-commit single quotation marks
andyjianzhou Jul 3, 2024
2e1e1c6
Merge branch 'main' into Andy/Unittest_Coverage_Issue
andyjianzhou Jul 10, 2024
85b42c2
Merge branch 'main' into Andy/Unittest_Coverage_Issue
RNHTTR Jul 10, 2024
7477ff2
Merge branch 'main' into Andy/Unittest_Coverage_Issue
andyjianzhou Jul 12, 2024
4ccbe48
Resolving hidden conflicts after rebasing
andyjianzhou Jul 12, 2024
799ac66
Merge branch 'main' into Andy/Unittest_Coverage_Issue
andyjianzhou Jul 15, 2024
5ef7631
Merge branch 'main' into Andy/Unittest_Coverage_Issue
andyjianzhou Jul 16, 2024
fdc095a
Merge branch 'main' into Andy/Unittest_Coverage_Issue
RNHTTR Jul 16, 2024
a2164cb
Merge branch 'main' into Andy/Unittest_Coverage_Issue
andyjianzhou Jul 16, 2024
bcb1846
Merge branch 'main' into Andy/Unittest_Coverage_Issue
RNHTTR Jul 17, 2024
a978f57
Merge branch 'main' into Andy/Unittest_Coverage_Issue
andyjianzhou Jul 17, 2024
0b806ad
fix pre-commit
andyjianzhou Jul 17, 2024
f8accc1
fix pre-commit
andyjianzhou Jul 17, 2024
865a40d
Merge branch 'main' into Andy/Unittest_Coverage_Issue
RNHTTR Jul 18, 2024
a6d102a
added test case for invalid XCom TasKInstance
Jul 19, 2024
0b8fd2b
Merge branch 'main' into Andy/Unittest_Coverage_Issue
andyjianzhou Jul 19, 2024
d783301
Merge branch 'main' into Andy/Unittest_Coverage_Issue
andyjianzhou Jul 22, 2024
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
53 changes: 53 additions & 0 deletions tests/models/test_xcom_arg_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
import pytest

from airflow.exceptions import AirflowSkipException
from airflow.models.taskinstance import TaskInstance
from airflow.models.taskmap import TaskMap, TaskMapVariant
from airflow.operators.empty import EmptyOperator
from airflow.utils.state import TaskInstanceState
from airflow.utils.trigger_rule import TriggerRule

Expand Down Expand Up @@ -188,6 +191,56 @@ def does_not_work_with_c(v):
]


def test_task_map_from_task_instance_xcom():
andyjianzhou marked this conversation as resolved.
Show resolved Hide resolved
task = EmptyOperator(task_id="test_task")
ti = TaskInstance(task=task, run_id="test_run", map_index=0)
ti.dag_id = "test_dag"
value = {"key1": "value1", "key2": "value2"}

# Test case where run_id is not None
task_map = TaskMap.from_task_instance_xcom(ti, value)
assert task_map.dag_id == ti.dag_id
assert task_map.task_id == ti.task_id
assert task_map.run_id == ti.run_id
assert task_map.map_index == ti.map_index
assert task_map.length == len(value)
assert task_map.keys == list(value)

# Test case where run_id is None
ti.run_id = None
with pytest.raises(ValueError, match="cannot record task map for unrun task instance"):
TaskMap.from_task_instance_xcom(ti, value)


def test_task_map_with_invalid_task_instance():
task = EmptyOperator(task_id="test_task")
ti = TaskInstance(task=task, run_id=None, map_index=0)
ti.dag_id = "test_dag"

# Define some arbitrary XCom-like value data
value = {"example_key": "example_value"}

with pytest.raises(ValueError, match="cannot record task map for unrun task instance"):
TaskMap.from_task_instance_xcom(ti, value)


def test_task_map_variant():
# Test case where keys is None
task_map = TaskMap(
dag_id="test_dag",
task_id="test_task",
run_id="test_run",
map_index=0,
length=3,
keys=None,
)
assert task_map.variant == TaskMapVariant.LIST

# Test case where keys is not None
task_map.keys = ["key1", "key2"]
assert task_map.variant == TaskMapVariant.DICT


def test_xcom_map_raise_to_skip(dag_maker, session):
result = None

Expand Down
52 changes: 52 additions & 0 deletions tests/www/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@
import pytest
from bs4 import BeautifulSoup
from flask_appbuilder.models.sqla.filters import get_field_setup_query, set_value_to_type
from flask_wtf import FlaskForm
from markupsafe import Markup
from sqlalchemy.orm import Query
from wtforms.fields import StringField, TextAreaField

from airflow.models import DagRun
from airflow.utils import json as utils_json
Expand All @@ -41,6 +43,7 @@
json_f,
wrapped_markdown,
)
from airflow.www.widgets import AirflowDateTimePickerROWidget, BS3TextAreaROWidget, BS3TextFieldROWidget
from tests.test_utils.config import conf_vars


Expand Down Expand Up @@ -703,3 +706,52 @@ def test_dag_run_custom_sqla_interface_delete_no_collateral_damage(dag_maker, se
assert len(dag_runs) == 6
assert len(set(x.dag_id for x in dag_runs)) == 3
assert len(set(x.run_id for x in dag_runs)) == 3


@pytest.fixture
def app():
from flask import Flask

app = Flask(__name__)
app.config["WTF_CSRF_ENABLED"] = False
app.config["SECRET_KEY"] = "secret"
with app.app_context():
yield app


class TestWidgets:
def test_airflow_datetime_picker_ro_widget(self, app):
class TestForm(FlaskForm):
datetime_field = StringField(widget=AirflowDateTimePickerROWidget())

form = TestForm()
field = form.datetime_field

html_output = field()

assert 'readonly="true"' in html_output
assert "input-group datetime datetimepicker" in html_output

def test_bs3_text_field_ro_widget(self, app):
class TestForm(FlaskForm):
text_field = StringField(widget=BS3TextFieldROWidget())

form = TestForm()
field = form.text_field

html_output = field()

assert 'readonly="true"' in html_output
assert "form-control" in html_output

def test_bs3_text_area_ro_widget(self, app):
class TestForm(FlaskForm):
textarea_field = TextAreaField(widget=BS3TextAreaROWidget())

form = TestForm()
field = form.textarea_field

html_output = field()

assert 'readonly="true"' in html_output
assert "form-control" in html_output
33 changes: 31 additions & 2 deletions tests/www/views/test_views_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
from airflow.utils.session import create_session
from airflow.utils.state import DagRunState, State
from airflow.utils.types import DagRunType
from airflow.www.views import TaskInstanceModelView
from airflow.www.views import TaskInstanceModelView, _safe_parse_datetime
from tests.test_utils.api_connexion_utils import create_user, delete_roles, delete_user
from tests.test_utils.config import conf_vars
from tests.test_utils.db import clear_db_runs, clear_db_xcom
Expand All @@ -66,7 +66,7 @@ def reset_dagruns():


@pytest.fixture(autouse=True)
def init_dagruns(app, reset_dagruns):
andyjianzhou marked this conversation as resolved.
Show resolved Hide resolved
def init_dagruns(app):
with time_machine.travel(DEFAULT_DATE, tick=False):
app.dag_bag.get_dag("example_bash_operator").create_dagrun(
run_id=DEFAULT_DAGRUN,
Expand Down Expand Up @@ -1050,6 +1050,35 @@ def test_graph_view_doesnt_fail_on_recursion_error(app, dag_maker, admin_client)
assert resp.status_code == 200


def test_get_date_time_num_runs_dag_runs_form_data_graph_view(app, dag_maker, admin_client):
"""Test the get_date_time_num_runs_dag_runs_form_data function."""
from airflow.www.views import get_date_time_num_runs_dag_runs_form_data

execution_date = pendulum.now(tz="UTC")
with dag_maker(
dag_id="test_get_date_time_num_runs_dag_runs_form_data",
start_date=execution_date,
) as dag:
BashOperator(task_id="task_1", bash_command="echo test")

with unittest.mock.patch.object(app, "dag_bag") as mocked_dag_bag:
mocked_dag_bag.get_dag.return_value = dag
url = f"/dags/{dag.dag_id}/graph"
resp = admin_client.get(url, follow_redirects=True)
assert resp.status_code == 200

with create_session() as session:
data = get_date_time_num_runs_dag_runs_form_data(resp.request, session, dag)

dttm = pendulum.parse(data["dttm"].isoformat())
base_date = pendulum.parse(data["base_date"].isoformat())

assert dttm.date() == execution_date.date()
assert dttm.time().hour == _safe_parse_datetime(execution_date.time().isoformat()).time().hour
assert dttm.time().minute == _safe_parse_datetime(execution_date.time().isoformat()).time().minute
assert base_date.date() == execution_date.date()


def test_task_instances(admin_client):
"""Test task_instances view."""
resp = admin_client.get(
Expand Down