mirror of
https://github.com/langgenius/dify.git
synced 2026-11-13 14:51:39 +08:00
fix(ci): resolve Builder security and formatting checks
This commit is contained in:
12 files changed
+158
-128
No files matched your search
@@ -9,14 +9,9 @@ import dify_agent
|
||||
import pytest
|
||||
|
||||
# API-installed SDK must be this checkout, with the missing server extra pinned by its own lock.
|
||||
assert (
|
||||
Path(dify_agent.__file__).resolve().is_relative_to(Path("dify-agent/src").resolve())
|
||||
)
|
||||
assert Path(dify_agent.__file__).resolve().is_relative_to(Path("dify-agent/src").resolve())
|
||||
packages = tomllib.loads(Path("dify-agent/uv.lock").read_text())["package"]
|
||||
assert (
|
||||
next(package["version"] for package in packages if package["name"] == "jwcrypto")
|
||||
== "1.5.7"
|
||||
)
|
||||
assert next(package["version"] for package in packages if package["name"] == "jwcrypto") == "1.5.7"
|
||||
|
||||
EXPECTED = {
|
||||
"tests.integration_tests.services.dify_builder.test_agent_recovery_postgres": {
|
||||
@@ -103,9 +98,7 @@ else:
|
||||
for module, functions in EXPECTED.items():
|
||||
print(f"COLLECTED {module}: {sum(actual[module].values())} cases", flush=True)
|
||||
if dict(actual[module]) != functions:
|
||||
problems.append(
|
||||
f"recovery case inventory mismatch {module}: {dict(actual[module])!r}"
|
||||
)
|
||||
problems.append(f"recovery case inventory mismatch {module}: {dict(actual[module])!r}")
|
||||
for problem in problems:
|
||||
print(f"COMPLETENESS {problem}", flush=True)
|
||||
raise SystemExit(int(code) or (1 if problems else 0))
|
||||
@@ -138,19 +138,13 @@ FILES += [
|
||||
]
|
||||
FILES += [
|
||||
path
|
||||
for path in [
|
||||
"api/tests/unit_tests/services/dify_builder/native_testing/test_confirmed_agent_completion.py"
|
||||
]
|
||||
for path in ["api/tests/unit_tests/services/dify_builder/native_testing/test_confirmed_agent_completion.py"]
|
||||
if path not in FILES
|
||||
]
|
||||
FILES += [
|
||||
"api/tests/unit_tests/services/dify_builder/native_testing/test_confirmed_agent_terminal_scan.py"
|
||||
]
|
||||
FILES += ["api/tests/unit_tests/services/dify_builder/native_testing/test_confirmed_agent_terminal_scan.py"]
|
||||
FILES += [
|
||||
path
|
||||
for path in [
|
||||
"api/tests/unit_tests/services/dify_builder/test_agent_model_result_canonical.py"
|
||||
]
|
||||
for path in ["api/tests/unit_tests/services/dify_builder/test_agent_model_result_canonical.py"]
|
||||
if path not in FILES
|
||||
]
|
||||
FILES += ["api/tests/unit_tests/services/dify_builder/test_test_actions.py"]
|
||||
@@ -264,10 +258,7 @@ code = pytest.main(
|
||||
)
|
||||
# Full module identity avoids silently merging same-basename owners.
|
||||
module_paths = [*FILES, *(selection.split("::", 1)[0] for selection in SELECTED_GUARDS)]
|
||||
modules = {
|
||||
Path(path).with_suffix("").as_posix().removeprefix("api/").replace("/", "."): 0
|
||||
for path in module_paths
|
||||
}
|
||||
modules = {Path(path).with_suffix("").as_posix().removeprefix("api/").replace("/", "."): 0 for path in module_paths}
|
||||
identities = set()
|
||||
problems = []
|
||||
if not Path(JUNIT).is_file():
|
||||
@@ -276,11 +267,7 @@ else:
|
||||
for case in ElementTree.parse(JUNIT).getroot().iter("testcase"):
|
||||
classname, name = case.get("classname") or "", case.get("name") or ""
|
||||
normalized = classname.removeprefix("api.")
|
||||
matching = [
|
||||
module
|
||||
for module in modules
|
||||
if normalized == module or normalized.startswith(module + ".")
|
||||
]
|
||||
matching = [module for module in modules if normalized == module or normalized.startswith(module + ".")]
|
||||
if len(matching) != 1:
|
||||
problems.append(f"unexpected unit case {classname}::{name}")
|
||||
continue
|
||||
@@ -831,12 +818,8 @@ for module, functions in {
|
||||
}.items():
|
||||
a4_expected.setdefault(module, {}).update(functions)
|
||||
# Candidate 3: frozen exact collection; retain every previously required function.
|
||||
a4_expected.setdefault(
|
||||
"tests.unit_tests.services.dify_builder.test_agent_model_result_canonical", {}
|
||||
).update(
|
||||
{
|
||||
"test_model_receipt_matches_sdk_roundtrip_without_changing_stream_or_accepting_replacement": 2
|
||||
}
|
||||
a4_expected.setdefault("tests.unit_tests.services.dify_builder.test_agent_model_result_canonical", {}).update(
|
||||
{"test_model_receipt_matches_sdk_roundtrip_without_changing_stream_or_accepting_replacement": 2}
|
||||
)
|
||||
a4_expected.setdefault(
|
||||
"tests.unit_tests.services.dify_builder.native_testing.test_confirmed_agent_completion",
|
||||
@@ -957,9 +940,7 @@ a4_expected["tests.unit_tests.core.dify_builder.test_ports"] = {
|
||||
"test_mutation_intent_defaults_and_args_not_shared": 1,
|
||||
}
|
||||
# Exact collected Code failure-policy regression inventories (Local JUnit/AST checked).
|
||||
a4_expected[
|
||||
"tests.unit_tests.services.dify_builder.test_bound_resource_plan_reconciliation"
|
||||
] = {
|
||||
a4_expected["tests.unit_tests.services.dify_builder.test_bound_resource_plan_reconciliation"] = {
|
||||
"test_confirmed_resource_reconciles_fallback_and_overview_before_approval": 1,
|
||||
"test_unusable_reconciliation_keeps_resource_gate_and_does_not_offer_approval": 3,
|
||||
"test_reconciliation_rereads_selected_facts_and_uses_one_model_reply": 1,
|
||||
@@ -2139,9 +2120,7 @@ a4_expected["tests.unit_tests.services.dify_builder.test_test_actions"] = {
|
||||
"test_standard_choice_envelope_can_submit_native_control": 1,
|
||||
"test_earlier_action_identity_cannot_be_reused_after_another_command": 1,
|
||||
}
|
||||
a4_expected[
|
||||
"tests.unit_tests.services.dify_builder.native_testing.test_confirmed_agent_completion"
|
||||
].update(
|
||||
a4_expected["tests.unit_tests.services.dify_builder.native_testing.test_confirmed_agent_completion"].update(
|
||||
{
|
||||
"test_native_control_only_commits_do_not_strand_successful_builder_run": 1,
|
||||
"test_terminal_projection_crash_is_recovered_without_get_or_dispatch": 1,
|
||||
@@ -2155,17 +2134,13 @@ a4_expected.setdefault(
|
||||
"tests.unit_tests.services.dify_builder.native_testing.test_confirmed_agent_completion",
|
||||
{},
|
||||
).update({"test_expired_terminal_context_requires_actual_owned_terminal_workflow": 7})
|
||||
a4_expected.setdefault(
|
||||
"tests.unit_tests.services.dify_builder.test_agent_operation_owner", {}
|
||||
).update(
|
||||
a4_expected.setdefault("tests.unit_tests.services.dify_builder.test_agent_operation_owner", {}).update(
|
||||
{"test_expired_completed_receipt_requires_exact_original_permit_and_result": 1}
|
||||
)
|
||||
a4_expected[
|
||||
"tests.unit_tests.services.dify_builder.native_testing.test_confirmed_agent_terminal_scan"
|
||||
] = {"test_terminal_scan_compares_input_ids_as_strings": 2}
|
||||
a4_expected[
|
||||
"tests.unit_tests.services.dify_builder.native_testing.test_confirmed_agent_completion"
|
||||
].update(
|
||||
a4_expected["tests.unit_tests.services.dify_builder.native_testing.test_confirmed_agent_terminal_scan"] = {
|
||||
"test_terminal_scan_compares_input_ids_as_strings": 2
|
||||
}
|
||||
a4_expected["tests.unit_tests.services.dify_builder.native_testing.test_confirmed_agent_completion"].update(
|
||||
{
|
||||
"test_cancel_after_completed_effects_closes_original_parent": 2,
|
||||
"test_resumed_saved_cancellation_projects_only_unchanged_terminal_proof": 17,
|
||||
@@ -2227,15 +2202,12 @@ task_control_transport_expected = {
|
||||
}
|
||||
for function, count in task_control_transport_expected.items():
|
||||
actual = sum(
|
||||
classname.removeprefix("api.")
|
||||
== "tests.unit_tests.controllers.console.test_dify_builder_routes"
|
||||
classname.removeprefix("api.") == "tests.unit_tests.controllers.console.test_dify_builder_routes"
|
||||
and name.split("[", 1)[0] == function
|
||||
for classname, name in identities
|
||||
)
|
||||
if actual != count:
|
||||
problems.append(
|
||||
f"Task control transport inventory mismatch {function}: {actual} != {count}"
|
||||
)
|
||||
problems.append(f"Task control transport inventory mismatch {function}: {actual} != {count}")
|
||||
# Current priority closeout: exact Local-collected regression inventory.
|
||||
a4_expected["tests.unit_tests.core.dify_builder.test_handlers_build"] = {
|
||||
"test_a_determinate_outcome_resets_the_unknown_outcome_count": 1,
|
||||
@@ -2701,9 +2673,7 @@ a4_expected["tests.unit_tests.services.dify_builder.test_agent_operation_owner"]
|
||||
"test_prepare_actual_call_freezes_builder_reasoning_without_business_or_oauth": 8,
|
||||
}
|
||||
)
|
||||
a4_expected[
|
||||
"tests.unit_tests.services.dify_builder.native_testing.test_agent_risk_assessor"
|
||||
].update(
|
||||
a4_expected["tests.unit_tests.services.dify_builder.native_testing.test_agent_risk_assessor"].update(
|
||||
{
|
||||
"test_risk_rubric_separates_observed_destruction_from_uncertain_side_effects": 1,
|
||||
}
|
||||
@@ -2885,20 +2855,16 @@ a4_expected.update(
|
||||
)
|
||||
# Exact first-phase P0 additions; retain all unrelated reviewed cases.
|
||||
a4_expected["tests.unit_tests.services.dify_builder.test_agent_operation_owner"].update(
|
||||
{
|
||||
"test_native_model_permission_expiring_during_metadata_prevents_preparation_and_claim": 1
|
||||
}
|
||||
{"test_native_model_permission_expiring_during_metadata_prevents_preparation_and_claim": 1}
|
||||
)
|
||||
# The latest main merge adds transaction-lifetime witnesses to the existing owner.
|
||||
a4_expected["tests.unit_tests.services.test_workflow_run_service"].update(
|
||||
{"test_trace_assembly_uses_a_session_from_the_injected_factory": 2}
|
||||
)
|
||||
a4_expected[
|
||||
"tests.unit_tests.core.workflow.generator.test_native_code_output_contract"
|
||||
].update({"test_batch_code_contract_validates_identity_before_grouping": 3})
|
||||
knowledge_cases = a4_expected[
|
||||
"tests.unit_tests.services.dify_builder.test_knowledge_discovery"
|
||||
]
|
||||
a4_expected["tests.unit_tests.core.workflow.generator.test_native_code_output_contract"].update(
|
||||
{"test_batch_code_contract_validates_identity_before_grouping": 3}
|
||||
)
|
||||
knowledge_cases = a4_expected["tests.unit_tests.services.dify_builder.test_knowledge_discovery"]
|
||||
del knowledge_cases["test_refusing_goal_change_keeps_knowledge_wait_and_never_replans"]
|
||||
knowledge_cases.update(
|
||||
{
|
||||
@@ -3140,9 +3106,7 @@ for module, functions in {
|
||||
a4_expected.setdefault(module, {}).update(functions)
|
||||
# ENG-1240: exact additions from affected module collection; retain prior inventories.
|
||||
for module, functions in {
|
||||
"tests.unit_tests.controllers.inner_api.agent.test_llm": {
|
||||
"test_post_streams_plugin_compatible_envelope": 2
|
||||
},
|
||||
"tests.unit_tests.controllers.inner_api.agent.test_llm": {"test_post_streams_plugin_compatible_envelope": 2},
|
||||
"tests.unit_tests.controllers.inner_api.test_agent_runtime_lineage": {
|
||||
"test_actual_native_identity_with_all_body_markers_removed_refuses_before_services": 20,
|
||||
"test_agent_bearer_refuses_equality_with_existing_enterprise_or_daemon_credential": 2,
|
||||
@@ -3291,9 +3255,7 @@ for module, expected in {**a3_expected, **a4_expected}.items():
|
||||
actual[function] = actual.get(function, 0) + 1
|
||||
if actual != expected:
|
||||
problems.append(f"A3 function inventory mismatch {module}: {actual}")
|
||||
json_admission_module = (
|
||||
"tests.unit_tests.services.dify_builder.test_json_tool_execution_admission"
|
||||
)
|
||||
json_admission_module = "tests.unit_tests.services.dify_builder.test_json_tool_execution_admission"
|
||||
expected_json_admission = {
|
||||
f"test_owned_json_parse_prepare_persists_restricted_request[{variant}]"
|
||||
for variant in ("raw-true", "raw-false", "constant-true", "constant-false")
|
||||
@@ -3305,14 +3267,10 @@ expected_json_admission.update(
|
||||
}
|
||||
)
|
||||
actual_json_admission = {
|
||||
name
|
||||
for classname, name in identities
|
||||
if classname.removeprefix("api.") == json_admission_module
|
||||
name for classname, name in identities if classname.removeprefix("api.") == json_admission_module
|
||||
}
|
||||
if actual_json_admission != expected_json_admission:
|
||||
problems.append(
|
||||
"JSON admission case identities differ from the reviewed prepare variants and owner checks"
|
||||
)
|
||||
problems.append("JSON admission case identities differ from the reviewed prepare variants and owner checks")
|
||||
json_policy_module = "tests.unit_tests.services.dify_builder.test_json_tool_execution"
|
||||
json_policy_expected = {
|
||||
"test_reviewed_pure_mixed_graph_admits_exact_native_chain": 1,
|
||||
@@ -3494,9 +3452,7 @@ for module, functions in {
|
||||
}.items():
|
||||
json_contract_expected.setdefault(module, {}).update(functions)
|
||||
# ENG-1417: value-free failed Code format facts and current failed-Run provenance.
|
||||
json_contract_expected.setdefault(
|
||||
"tests.unit_tests.services.dify_builder.test_condition_evidence", {}
|
||||
).update(
|
||||
json_contract_expected.setdefault("tests.unit_tests.services.dify_builder.test_condition_evidence", {}).update(
|
||||
{
|
||||
"test_failed_code_format_facts_reach_diagnosis_and_repair_without_values": 1,
|
||||
"test_failed_code_format_classifies_only_observed_table_samples": 5,
|
||||
@@ -3521,9 +3477,7 @@ for module, expected in {
|
||||
for function, expected_count in expected.items():
|
||||
if actual.get(function, 0) != expected_count:
|
||||
problems.append(f"JSON case inventory mismatch {module}::{function}")
|
||||
if (module == json_policy_module or module in json_runtime_expected) and set(
|
||||
actual
|
||||
) != set(expected):
|
||||
if (module == json_policy_module or module in json_runtime_expected) and set(actual) != set(expected):
|
||||
problems.append(f"unexpected JSON test functions {module}")
|
||||
print(f"COLLECTED total: {len(identities)} unit cases", flush=True)
|
||||
for problem in problems:
|
||||
|
||||
Reference in new issue
Block a user