Skip to content

Conversation

@pesap
Copy link
Collaborator

@pesap pesap commented Feb 11, 2026

No description provided.

@pesap pesap requested a review from mcllerena February 11, 2026 22:21
@github-actions github-actions bot added the tests label Feb 11, 2026
@codecov-commenter
Copy link

Codecov Report

❌ Patch coverage is 90.62500% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.20%. Comparing base (f518c0f) to head (ed48c9e).

Files with missing lines Patch % Lines
src/plexosdb/utils.py 89.09% 6 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #96      +/-   ##
==========================================
- Coverage   95.36%   95.20%   -0.16%     
==========================================
  Files           8        8              
  Lines        1638     1688      +50     
==========================================
+ Hits         1562     1607      +45     
- Misses         76       81       +5     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Bobby-Heyer
Copy link

Hi @pesap

Thanks for the quick turnaround on this! I’ve run a regression test against my model (where the System object is named "NEM") using the changes in PR #96.

I can confirm that the AssertionError is resolved and the property membership is now correctly handled. I verified the internal state of the database using get_object_properties at each step to ensure the Round-Trip (Delete -> Add -> Query) works as expected.

Summary Test Results:

  1. System Name Detection: Correctiy identified "NEM" instead of defaulting to "System".
  2. Property Deletion: Successfully removed the target property without a crash even when System name = NEM.
  3. Bulk Add: add_properties_from_records correctly mapped the property back to the generator.

LOG OUTPUTS

============================================================
RUNNING 96 TEST: Central_2026_02_10a_scen.xml
============================================================
2026-02-12 08:44:02.003 | INFO     | plexosdb.db_manager:__init__:78 - Creating in-memory database.
2026-02-12 08:44:02.003 | DEBUG    | plexosdb.db:create_schema:2071 - Using default schema
STEP 0: Detected System Object Name: 'NEM'
--- Initial State ---
  Max Capacity: 660.0 MW
  Units: 1.0 -
  Units: 0.0 -

STEP 1: Testing delete_property with parent_class=System...
--- Post-Deletion Verify ---
  Units: 1.0 -
  Units: 0.0 -
  ✅ SUCCESS: Property removed correctly.

STEP 2: Testing add_properties_from_records (Bulk Add)...
2026-02-12 08:44:03.974 | DEBUG    | plexosdb.db:add_properties_from_records:924 - Successfully processed 1 property and text records in batches
--- Post-Addition Verify ---
  Units: 1.0 -
  Units: 0.0 -
  Max Capacity: 150.0 MW
  ✅ SUCCESS: Property re-added with correct value.

STEP 3: Finalizing XML Export...
2026-02-12 08:44:04.631 | DEBUG    | plexosdb.xml_handler:to_xml:188 - Saving xml file to validated_nem_model.xml
2026-02-12 08:44:05.774 | INFO     | plexosdb.xml_handler:to_xml:194 - Saved xml file to validated_nem_model.xml
2026-02-12 08:44:05.774 | INFO     | plexosdb.xml_handler:to_xml:196 - Deleting Cache
DONE: Test complete. Model saved to validated_nem_model.xml

TEST CODE

import logging
from pathlib import Path
from plexosdb import PlexosDB
from plexosdb.enums import ClassEnum, CollectionEnum

# Smick logging config
logging.basicConfig(
    level=logging.INFO,
    format='%(message)s'  # Clean format for GitHub logs
)
logger = logging.getLogger(__name__)


def log_props(db, obj_class, obj_name, prop_names, label="Current State"):
    """Helper to cleanly display and verify property states."""
    props = db.get_object_properties(obj_class, obj_name, property_names=prop_names)
    logger.info(f"--- {label} ---")
    if not props:
        logger.info(f"  [No properties found for {obj_name}]")
    for p in props:
        logger.info(f"  {p['property']}: {p['value']} {p.get('unit') or ''}")
    return props


def test_pr_96_fix(xml_input_path: str):
    logger.info("=" * 60)
    logger.info(f"RUNNING 96 TEST: {Path(xml_input_path).name}")
    logger.info("=" * 60)

    db = PlexosDB.from_xml(xml_input_path)
    target_gen = "BW01"
    target_prop = "Max Capacity"
    test_props = [target_prop, "Units"]

    # 1. System Name Detection
    system_objects = db.list_objects_by_class(ClassEnum.System)
    system_name = system_objects[0] if system_objects else "System"
    logger.info(f"STEP 0: Detected System Object Name: '{system_name}'")

    # 2. Baseline
    log_props(db, ClassEnum.Generator, target_gen, test_props, "Initial State")

    # 3. Test Deletion
    logger.info(f"\nSTEP 1: Testing delete_property with parent_class=System...")
    try:
        db.delete_property(
            ClassEnum.Generator, target_gen,
            property_name=target_prop,
            parent_class=ClassEnum.System,
            collection=CollectionEnum.Generators
        )
        # Verify
        current = log_props(db, ClassEnum.Generator, target_gen, test_props, "Post-Deletion Verify")
        if any(p['property'] == target_prop for p in current):
            logger.error("  ❌ ERROR: Property still exists!")
        else:
            logger.info("  ✅ SUCCESS: Property removed correctly.")
    except Exception as e:
        logger.error(f"  ❌ FAILED: Deletion triggered an error: {e}")
        return

    # 4. Test Add
    logger.info(f"\nSTEP 2: Testing add_properties_from_records (Bulk Add)...")
    flat_records = [{"name": target_gen, "property": target_prop, "value": 150}]
    try:
        db.add_properties_from_records(
            flat_records,
            object_class=ClassEnum.Generator,
            parent_class=ClassEnum.System,
            collection=CollectionEnum.Generators,
            scenario=''
        )
        # Verify
        current = log_props(db, ClassEnum.Generator, target_gen, test_props, "Post-Addition Verify")
        if any(p['property'] == target_prop and float(p['value']) == 150 for p in current):
            logger.info("  ✅ SUCCESS: Property re-added with correct value.")
        else:
            logger.error("  ❌ ERROR: Property not found or value mismatch.")
    except Exception as e:
        logger.error(f"  ❌ FAILED: Add operation triggered an error: {e}")
        return

    # 5. Export
    logger.info(f"\nSTEP 3: Finalizing XML Export...")
    output = Path("validated_nem_model.xml")
    if db.to_xml(output):
        logger.info(f"DONE: Test complete. Model saved to {output}")
    else:
        logger.error("DONE: Export failed.")


if __name__ == "__main__":
    XML_PATH = r"path\to\xml"
    test_pr_96_fix(XML_PATH)

@pesap pesap merged commit 6f3e408 into main Feb 12, 2026
24 checks passed
@pesap pesap deleted the pesap/system branch February 12, 2026 01:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants