iris-devtester 1.12.2__tar.gz → 1.12.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- iris_devtester-1.12.4/CHANGELOG.md +1189 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/MANIFEST.in +1 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/PKG-INFO +1 -1
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/TROUBLESHOOTING.md +10 -1
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/__init__.py +1 -1
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/cli/container.py +36 -8
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/ports/registry.py +42 -9
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester.egg-info/PKG-INFO +1 -1
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester.egg-info/SOURCES.txt +2 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/pyproject.toml +1 -1
- iris_devtester-1.12.4/tests/e2e/test_port_registry_e2e.py +96 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/AGENTS.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/CLAUDE.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/CONSTITUTION.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/LICENSE +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/README.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/SKILL.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/GETTING_STARTED.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/LANGCHAIN_INTEGRATION_QUICKSTART.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/ROADMAP.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/SQL_VS_OBJECTSCRIPT.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/WHATS_NEW_v1.4.0.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/archive/AGENTIC_SANDBOX_ENHANCEMENT_REPORT.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/archive/IMPACT_ANALYSIS.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/archive/IRIS_DEVTESTER_POSITIONING_REPORT.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/archive/LANGCHAIN_INTEGRATION_STRATEGY.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/archive/LANGCHAIN_INTEGRATION_TEST_RESULTS.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/archive/PHASE_2_PLAN.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/archive/RAG_TEMPLATES_ANALYSIS.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/archive/README.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/archive/STRATEGIC_ROADMAP_SUMMARY.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/archive/feature-009-refactor-plan.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/development/BUG_REPORT.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/development/EXTRACTION_SUMMARY.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/development/FEATURE_006_SUMMARY.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/development/PHASE2_RESULTS.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/development/PRE_PUBLISH_REVIEW.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/development/PROGRESS.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/development/PYPI_READINESS.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/development/SESSION-INTEGRATION-TESTS.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/development/SESSION-SUMMARY.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/development/STATUS-002-PIVOTED.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/development/STATUS-003-COMPLETE.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/development/STATUS.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/development/V1_COMPLETION_PLAN.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/development/V1_RELEASE_SUMMARY.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/features/WSGI-ASGI-SERVER-SETUP.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/features/agent-skills.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/features/dat-fixtures.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/features/docker-compose.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/features/performance-monitoring.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/features/testcontainers.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/api-contract-synchronization.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/callin-service-requirement.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/cpf-merge-and-container-restarts.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/dat-fixtures-docker-exec-pattern.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/dat-restore-database-isolation-problem.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/dbapi-bulk-insert-performance-issue.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/dbapi-objectscript-limitation.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/dbapi-password-reset-limitation.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/dbapi-private-module-myth.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/docker-hub-image-naming.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/embedded-python-considerations.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/feature-002-pivot-summary.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/integration-test-dbapi-limitation.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/iris-backup-patterns.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/iris-connection-access-denied-bug.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/iris-container-performance.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/iris-container-readiness.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/iris-docker-sdk-environment-variables.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/iris-performance-monitoring-landscape.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/iris-security-users-api.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/password-reset-changeflag-fix.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/rag-templates-production-patterns.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/sql-task-manager-operations.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/test-isolation-fix-summary.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/test-isolation-investigation.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/docs/learnings/testcontainers-ryuk-lifecycle.md +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/examples/01_quickstart.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/examples/02_connection_management.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/examples/04_pytest_fixtures.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/examples/05_ci_cd.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/examples/08_auto_discovery.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/examples/09_enterprise.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/examples/10_docker_compose_integration.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/examples/langchain_integration_example.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/__main__.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/cli/__init__.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/cli/__main__.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/cli/connection_commands.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/cli/container_commands.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/cli/dev_commands.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/cli/fixture_commands.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/config/__init__.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/config/auto_discovery.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/config/container_config.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/config/container_state.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/config/defaults.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/config/discovery.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/config/models.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/config/presets.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/config/yaml_loader.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/connections/__init__.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/connections/auto_discovery.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/connections/connection.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/connections/dbapi.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/connections/jdbc.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/connections/manager.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/connections/models.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/connections/retry.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/containers/__init__.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/containers/cpf_manager.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/containers/dev_instance.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/containers/iris_container.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/containers/models.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/containers/monitor_utils.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/containers/monitoring.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/containers/performance.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/containers/validation.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/containers/wait_strategies.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/fixtures/__init__.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/fixtures/creator.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/fixtures/loader.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/fixtures/manifest.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/fixtures/obj_export.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/fixtures/validator.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/integrations/__init__.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/integrations/langchain.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/ports/__init__.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/ports/assignment.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/ports/exceptions.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/testing/__init__.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/testing/fixtures.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/testing/helpers.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/testing/models.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/testing/schema_reset.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/utils/__init__.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/utils/container_port.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/utils/container_status.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/utils/dbapi_compat.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/utils/enable_callin.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/utils/health_checks.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/utils/iris_container_adapter.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/utils/namespace.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/utils/password.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/utils/progress.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester/utils/test_connection.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester.egg-info/dependency_links.txt +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester.egg-info/entry_points.txt +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester.egg-info/requires.txt +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/iris_devtester.egg-info/top_level.txt +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/setup.cfg +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/__init__.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/conftest.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/__init__.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/cli/test_container_logs_contract.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/cli/test_container_remove_contract.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/cli/test_container_restart_contract.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/cli/test_container_start_contract.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/cli/test_container_status_contract.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/cli/test_container_stop_contract.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/cli/test_container_up_contract.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_agent_skills.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_cli_container_commands.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_cli_fixture_commands.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_connection_api.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_container_api.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_container_integration_contract.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_container_status_api.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_container_validation_api.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_enable_callin_api.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_fixture_creator_api.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_fixture_loader_api.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_fixture_validator_api.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_iriscontainer_attach.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_legacy_package_contract.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_modern_package_contract.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_monitoring_config_api.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_package_detection.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_port_registry_contract.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_preconfig_contract.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_reset_verification_contract.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_resource_monitoring_api.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_retry_logic_contract.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_task_manager_api.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_test_connection_api.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/contract/test_testing_fixtures_api.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/e2e/__init__.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/e2e/test_skill_workflow.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/__init__.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/conftest.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/ports/__init__.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/ports/test_manual_port_override.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/ports/test_multi_project_isolation.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/ports/test_port_exhaustion.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/ports/test_port_persistence.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/ports/test_stale_cleanup.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_bug_fixes.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_bug_fixes_011.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_cli_container_integration.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_connection_integration.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_container_health_monitor.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_container_status_integration.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_container_validation.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_cpf_merge.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_cpf_presets.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_cpf_security.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_custom_user_remediation.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_dev_instance.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_enable_callin_integration.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_fixture_export_patterns.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_fixture_performance.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_fixture_refresh.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_fixtures_integration.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_implicit_namespace.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_iriscontainer_attach_integration.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_monitor_utils_integration.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_monitoring_integration.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_password_preconfig_integration.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_password_reset_both_editions.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_password_reset_integration.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_password_reset_macos.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_password_reset_timing.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_password_reset_validation.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_proactive_password_reset.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_real_world_problems.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_reliable_password_reset.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/integration/test_test_connection_integration.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/__init__.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/config/test_config_hierarchy.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/config/test_container_config.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/config/test_yaml_loader.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_auto_discovery.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_config_discovery.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_connection_fallback.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_connection_info.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_cpf_manager.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_dev_instance_logic.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_iris_config.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_iris_container.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_manifest.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_monitoring_policy.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_namespace_utils.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_password_preconfig.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_password_preconfig_unit.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_performance_metrics.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_resource_thresholds.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_retry.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_schema_models.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_validation_results.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/test_wait_strategies.py +0 -0
- {iris_devtester-1.12.2 → iris_devtester-1.12.4}/tests/unit/utils/test_iris_container_adapter.py +0 -0
|
@@ -0,0 +1,1189 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to iris-devtester will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [1.12.4] - 2026-02-15 - Port Management Reliability
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **Host Port Availability**: Enhanced `PortRegistry` to perform live TCP socket checks on the host. This prevents `idt` from assigning ports that are occupied by non-Docker processes.
|
|
13
|
+
- **Auto-Port Fallback**: Improved CLI logic to correctly trigger auto-assignment when the default port (1972) is taken, even if it's the configured default.
|
|
14
|
+
- **Web Port Scaling**: Fixed logic for proportional adjustment of the WebServer port when the SuperServer port is shifted.
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- **E2E Coverage**: Added full end-to-end coverage for port conflict scenarios in `tests/e2e/test_port_registry_e2e.py`.
|
|
19
|
+
|
|
20
|
+
## [1.12.3] - 2026-02-15 - Documentation Sync
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
- **Documentation Parity**: Synchronized PyPI source distribution with the latest Troubleshooting Guide and feature documentation.
|
|
25
|
+
- **Manifest Enhancement**: Explicitly included `CHANGELOG.md` in the PyPI source distribution (`sdist`).
|
|
26
|
+
|
|
27
|
+
## [1.12.2] - 2026-02-15 - Smart Port Fallback
|
|
28
|
+
|
|
29
|
+
### Added
|
|
30
|
+
|
|
31
|
+
- **Smart Port Fallback**: Added `--auto-port` flag to `idt container up` and `idt container start` commands.
|
|
32
|
+
- Automatically finds and assigns an available port if the default (1972) is taken.
|
|
33
|
+
- Utilizes the `PortRegistry` to maintain stable assignments across project sessions.
|
|
34
|
+
- Automatically adjusts the WebServer port proportionally when the SuperServer port is shifted.
|
|
35
|
+
|
|
36
|
+
### Fixed
|
|
37
|
+
|
|
38
|
+
- **Reset Password Support**: Added `IRISContainer.reset_password()` method to support manual password remediation in integration scripts.
|
|
39
|
+
|
|
40
|
+
## [1.12.1] - 2026-02-15 - Protocol & Discovery Fixes
|
|
41
|
+
|
|
42
|
+
### Fixed
|
|
43
|
+
|
|
44
|
+
- **Access Denied (Invalid Message)**: Fixed a critical bug in `get_config()` where discovering `0.0.0.0` as the host caused the IRIS Superserver to reject the connection protocol. Now sanitizes `0.0.0.0` and `::` to `localhost` for reliable client-side connectivity.
|
|
45
|
+
- **Attach Validation**: Improved `IRISContainer.attach()` with explicit validation for container names and better error messages when containers are missing or not running.
|
|
46
|
+
- **Type Safety**: Resolved LSP type mismatch for `container_name` in `attach()` and `dev()` methods.
|
|
47
|
+
|
|
48
|
+
## [1.12.0] - 2026-02-10 - The Dev Instance (Warm Start)
|
|
49
|
+
|
|
50
|
+
### Added
|
|
51
|
+
|
|
52
|
+
- **The Dev Instance (Warm Start)**: Achieved the project's "North Star" of SQLite-level ergonomics.
|
|
53
|
+
- **Instant Connection**: `get_connection()` now connects in < 100ms by utilizing a persistent background engine.
|
|
54
|
+
- **Managed Lifecycle**: New `idt dev` command group (`up`, `down`, `status`, `logs`) to manage the background engine.
|
|
55
|
+
- **Project Isolation**: Automatic folder-based hashing ensures each project directory gets its own isolated IRIS namespace and database.
|
|
56
|
+
- **Durable Persistence**: Integrated "Durable %SYS" support ensures data survives container restarts and engine upgrades.
|
|
57
|
+
- **Automatic Provisioning**: Calling `get_connection()` will implicitly start the dev engine if it's not running.
|
|
58
|
+
- **Optimized Readiness**: Ultra-fast TCP port probing for immediate connectivity detection.
|
|
59
|
+
|
|
60
|
+
- **Improved Port Management**: Enhanced auto-discovery logic to prioritize the managed dev instance.
|
|
61
|
+
|
|
62
|
+
### Fixed
|
|
63
|
+
|
|
64
|
+
- **Volume Permissions**: Automated `chown` logic for persistent volumes to prevent UID 51773 (irisowner) conflicts on macOS.
|
|
65
|
+
- **Readiness Reliability**: Improved `wait_until_ready` logic with more robust ObjectScript-based initialization checks.
|
|
66
|
+
|
|
67
|
+
## [1.11.1] - 2026-02-08 - Core Container Fixes
|
|
68
|
+
|
|
69
|
+
### Fixed
|
|
70
|
+
|
|
71
|
+
- **Superserver Port Mapping**: Fixed critical bug where non-standard superserver ports (e.g., 31972) were incorrectly mapped host-to-host instead of host-to-container (1972). This fixes connection resets on custom ports.
|
|
72
|
+
- **Container Name Persistence**: Improved handling of `container_name` in CLI and adapter to ensure user-specified names are respected.
|
|
73
|
+
|
|
74
|
+
## [1.11.0] - 2026-02-08 - Implicit Namespace Creation (SQLite-Level Ergonomics)
|
|
75
|
+
|
|
76
|
+
### Added
|
|
77
|
+
|
|
78
|
+
- **Implicit Namespace Creation**: Achieved "SQLite-level ergonomics" where `get_connection(namespace="NEW")` automatically creates the namespace if it doesn't exist.
|
|
79
|
+
- Automatically creates database directory and `.dat` file.
|
|
80
|
+
- Configures namespace mappings (Globals/Routines) to the new database.
|
|
81
|
+
- Ensures `%Service_CallIn` is enabled for the new namespace.
|
|
82
|
+
- **Hybrid Smart Default**: Enabled by default for `localhost` (zero-friction dev), explicit opt-in required for remote hosts (production safety).
|
|
83
|
+
- Supported via `IRISConfig.auto_create` and `IRIS_AUTO_CREATE` environment variable.
|
|
84
|
+
|
|
85
|
+
### Fixed
|
|
86
|
+
|
|
87
|
+
- Improved `get_connection` reliability when connecting to non-existent namespaces.
|
|
88
|
+
|
|
89
|
+
## [1.10.4] - 2026-02-08 - Critical DBAPI Segfault Fix
|
|
90
|
+
|
|
91
|
+
### Fixed
|
|
92
|
+
|
|
93
|
+
- **Critical Segfault**: Resolved `SIGSEGV` crash when using `FETCH FIRST N ROWS ONLY` SQL syntax.
|
|
94
|
+
- Modified `dbapi_compat.py` to prefer the stable `intersystems_iris` connection path over the buggy `iris` (`_elsdk_`) path.
|
|
95
|
+
- Both modules are part of `intersystems-irispython`, but `intersystems_iris` provides the stable `_IRISNative` driver.
|
|
96
|
+
- This fix restores stability for SQL pagination and vector-graph operations.
|
|
97
|
+
|
|
98
|
+
## [1.10.3] - 2026-02-06 - Docker Exec Ownership Fix
|
|
99
|
+
|
|
100
|
+
### Fixed
|
|
101
|
+
|
|
102
|
+
- **Docker Exec Ownership**: Added `-u irisowner` to all `docker exec` calls that interact with IRIS processes.
|
|
103
|
+
- Fixes "Invalid ownership for ./irisdb" errors in containers where root is the default exec user.
|
|
104
|
+
- Affects password reset, service enablement, connection testing, and fixture operations.
|
|
105
|
+
- Standardizes UID 51773 (irisowner) for all IRIS-specific container interactions.
|
|
106
|
+
|
|
107
|
+
## [1.10.2] - 2026-02-06 - Fixture System & Enterprise Test Fixes
|
|
108
|
+
|
|
109
|
+
### Fixed
|
|
110
|
+
|
|
111
|
+
- **Fixture Integration Tests**: All 9 fixture tests now pass
|
|
112
|
+
- Fixed `test_create_validate_load_verify` to properly connect to target namespace
|
|
113
|
+
- Fixed 4 tests that failed due to empty tables validation by adding test data creation
|
|
114
|
+
|
|
115
|
+
- **Enterprise Edition Tests**: All 5 previously-skipped enterprise tests now run and pass
|
|
116
|
+
- Fixed `conftest.py`: Was reading license key file contents instead of passing file path
|
|
117
|
+
- Fixed `test_cpf_merge.py`: Same license key path bug
|
|
118
|
+
- Added ARM64-compatible enterprise image selection for Apple Silicon
|
|
119
|
+
|
|
120
|
+
- **Test Infrastructure**:
|
|
121
|
+
- Fixed flaky `test_wait_function_with_timeout` timing assertion (4.0s → 5.0s tolerance)
|
|
122
|
+
- All 342 unit tests pass
|
|
123
|
+
- All 11 enterprise+community edition tests pass (0 skipped)
|
|
124
|
+
|
|
125
|
+
### Changed
|
|
126
|
+
|
|
127
|
+
- Enterprise tests now use `containers.intersystems.com/intersystems/iris:2025.1` on ARM64
|
|
128
|
+
|
|
129
|
+
## [1.10.1] - 2026-02-05 - CLI Documentation & Custom Images
|
|
130
|
+
|
|
131
|
+
### Added
|
|
132
|
+
|
|
133
|
+
- **`--image` option for `container up`**: Use any Docker image, overriding edition defaults
|
|
134
|
+
- Example: `iris-devtester container up --image myregistry/iris:2024.1`
|
|
135
|
+
- Example: `iris-devtester container up --image intersystemsdc/iris-community:2024.1-zpm`
|
|
136
|
+
- Useful for custom registries, specific versions, or pre-configured images
|
|
137
|
+
|
|
138
|
+
### Changed
|
|
139
|
+
|
|
140
|
+
- **CLI Help Text**: Improved `--help` output for better AI agent and user discoverability
|
|
141
|
+
- Main help now explains what the tool does, container editions, quick start, and common workflows
|
|
142
|
+
- Added "FOR AI AGENTS" section with exit codes and JSON output guidance
|
|
143
|
+
- Container group help now includes edition comparison and quick start commands
|
|
144
|
+
- All help text now properly formatted with `\b` markers (no more broken line wraps)
|
|
145
|
+
- Added note about using docker-compose for multi-container setups
|
|
146
|
+
|
|
147
|
+
### Documentation
|
|
148
|
+
|
|
149
|
+
- CLI is now self-documenting enough for AI agents to use without external docs
|
|
150
|
+
- All commands support `--help` for detailed options
|
|
151
|
+
- `container list --format json` provides machine-readable output
|
|
152
|
+
- Added "When to Use docker-compose Instead" section to GETTING_STARTED.md
|
|
153
|
+
- Covers sharding, mirroring, ECP, and multi-service stacks
|
|
154
|
+
- Explains iris-devtester is for single-container management only
|
|
155
|
+
|
|
156
|
+
## [1.10.0] - 2026-01-31 - Feature 024: Canonical Container Editions
|
|
157
|
+
|
|
158
|
+
### Added
|
|
159
|
+
|
|
160
|
+
- **Three Canonical Container Editions**:
|
|
161
|
+
- **Community**: Full IRIS Community Edition (~3.5GB) - `IRISContainer.community()`
|
|
162
|
+
- **Enterprise**: Licensed IRIS - `IRISContainer.enterprise(license_key=...)`
|
|
163
|
+
- **Light**: Minimal for CI/CD (~580MB) - `IRISContainer.light()` - NEW!
|
|
164
|
+
|
|
165
|
+
- **Light Edition** (`caretdev/iris-community-light`):
|
|
166
|
+
- 85% smaller than full community (580MB vs 3.5GB)
|
|
167
|
+
- Removes: Interoperability, Management Portal, DeepSee/BI, CSP/REST
|
|
168
|
+
- Keeps: SQL engine, DBAPI, JDBC, ODBC, SQLAlchemy-IRIS
|
|
169
|
+
- Multi-arch: ARM64 and x86 supported
|
|
170
|
+
- Ideal for CI/CD pipelines where startup time matters
|
|
171
|
+
- Maintainer: CaretDev (Dmitry Maslennikov)
|
|
172
|
+
|
|
173
|
+
- **CLI `--edition` option**: `iris-devtester container up --edition light|community|enterprise`
|
|
174
|
+
- **CLI `container list` command**: Shows all IRIS containers with status, edition, ports, age
|
|
175
|
+
- **Standardized container naming**: All CLI commands accept optional `CONTAINER_NAME` with default `iris_db`
|
|
176
|
+
|
|
177
|
+
### Changed
|
|
178
|
+
|
|
179
|
+
- `IRISContainer.community()` now explicitly documents size (~3.5GB)
|
|
180
|
+
- `IRISContainer.enterprise()` now includes better license key handling
|
|
181
|
+
- Container config now supports `edition` field: `"community"`, `"enterprise"`, `"light"`
|
|
182
|
+
- README updated with Container Editions section
|
|
183
|
+
|
|
184
|
+
### Technical Details
|
|
185
|
+
|
|
186
|
+
- Light edition image: `caretdev/iris-community-light:latest-em`
|
|
187
|
+
- Default tag for light: `latest-em` (production-ready)
|
|
188
|
+
- All editions verified for DBAPI connectivity
|
|
189
|
+
|
|
190
|
+
## [1.9.3] - 2026-01-30 - CLI Container Naming
|
|
191
|
+
|
|
192
|
+
### Added
|
|
193
|
+
|
|
194
|
+
- **`--name` option for `container up`**: Specify custom container name
|
|
195
|
+
- **Default name warning**: Warns when using default `iris_db` with existing container
|
|
196
|
+
|
|
197
|
+
### Fixed
|
|
198
|
+
|
|
199
|
+
- **Pydantic deprecation**: Migrated from `class Config:` to `model_config = ConfigDict(...)`
|
|
200
|
+
- **Python 3.9 compatibility**: Fixed `str | Path` → `Union[str, Path]` type hints
|
|
201
|
+
- **mypy type errors**: Resolved various type annotation issues
|
|
202
|
+
|
|
203
|
+
## [1.9.2] - 2026-01-29 - IRIS Session Instance Name Fix
|
|
204
|
+
|
|
205
|
+
### Fixed
|
|
206
|
+
|
|
207
|
+
- **CRITICAL**: Fixed IRIS session instance name from `iris` to `IRIS` (uppercase)
|
|
208
|
+
- Affected files: `password.py`, `health_checks.py`
|
|
209
|
+
- Error symptom: "Access Denied" when DBAPI connections failed due to unexpired passwords
|
|
210
|
+
- Root cause: `iris session iris` → `iris session IRIS`
|
|
211
|
+
- All password reset and CallIn enable commands now work correctly
|
|
212
|
+
|
|
213
|
+
## [1.8.1] - 2026-01-17 - Bug Fixes & API Contract Synchronization
|
|
214
|
+
|
|
215
|
+
### Fixed
|
|
216
|
+
|
|
217
|
+
- **CLI `fixture create` Container Support**: Added missing `--container` parameter to specify source IRIS instance.
|
|
218
|
+
- **API Contract Synchronization**: Fixed method signatures and return types across `FixtureCreator`, `DATFixtureLoader`, and `IRISContainer` to align with public contract tests.
|
|
219
|
+
- **Contract Test Compatibility**: Implemented a robust compatibility layer in `iris_devtester.testing` and `iris_devtester.connections` to support legacy assistant expectations.
|
|
220
|
+
- **Test Performance & Stability**:
|
|
221
|
+
- Optimized `IRISContainer` startup logic to prevent hangs in restricted environments.
|
|
222
|
+
- Improved `wait_for_iris_ready` timing reliability.
|
|
223
|
+
- Added `clean_port_registry` fixture for integration test isolation.
|
|
224
|
+
|
|
225
|
+
## [1.8.0] - 2026-01-05 - Feature 022: CPF Merge Support
|
|
226
|
+
|
|
227
|
+
### Added
|
|
228
|
+
|
|
229
|
+
- **Declarative Configuration (`with_cpf_merge`)**: New method for `IRISContainer` to apply CPF snippets during container boot.
|
|
230
|
+
- **Optimization Presets**: Added `CPFPreset.CI_OPTIMIZED` and `CPFPreset.SECURE_DEFAULTS` for instant setup.
|
|
231
|
+
- **2025 Agent Skills Standard**: Standardized on root-level `SKILL.md` and consolidated assistant triggers.
|
|
232
|
+
- **Consolidated CLI & UI**: Unified agent commands into `/idt` (Claude) and `@idt` (Cursor) for zero clutter.
|
|
233
|
+
|
|
234
|
+
## [1.5.2] - 2025-12-24 - Performance & Reliability
|
|
235
|
+
|
|
236
|
+
### Fixed
|
|
237
|
+
|
|
238
|
+
- **Password Reset Performance Regression** - Reduced from 55s to ~3s
|
|
239
|
+
- `settle_delay`: 12s → 2s (correct API doesn't need long waits)
|
|
240
|
+
- `initial_backoff_ms`: 3000 → 1000 (faster retries)
|
|
241
|
+
- `max_retries`: 5 → 3 (fewer attempts needed)
|
|
242
|
+
- `timeout_ms`: 60000 → 10000 (10s hard cap, NFR-004)
|
|
243
|
+
|
|
244
|
+
- **Stuck Password State Detection** - New `check_password_state()` function
|
|
245
|
+
- Detects containers with `ChangePassword=1` stuck after failed resets
|
|
246
|
+
- Pre-flight check warns before reset attempt
|
|
247
|
+
- Post-reset verification confirms flag was cleared
|
|
248
|
+
- Fails fast with remediation steps if container needs restart
|
|
249
|
+
|
|
250
|
+
- **ObjectScript Syntax Fixes** - Fixed `$$ISOK` macro issues
|
|
251
|
+
- Changed to `$Select(sc=1:1,1:0)` for interactive ObjectScript compatibility
|
|
252
|
+
- Affects: `export_classes()`, `import_classes()`, `export_global()`, `import_global()`, `export_package()`
|
|
253
|
+
|
|
254
|
+
- **Unit Test Fixes** - Fixed `iris_devtester` → `iris_devtester` in 10+ test files
|
|
255
|
+
|
|
256
|
+
### Added
|
|
257
|
+
|
|
258
|
+
- **Container Performance Documentation** - `docs/learnings/iris-container-performance.md`
|
|
259
|
+
- Root cause analysis of IRIS container startup bottlenecks
|
|
260
|
+
- Optimization strategies: namespace isolation, container reuse, pre-baked images
|
|
261
|
+
- Quick wins for faster development cycles
|
|
262
|
+
|
|
263
|
+
## [1.7.5] - 2026-01-04 - PyPI Link & Metadata Finalization
|
|
264
|
+
|
|
265
|
+
### Fixed
|
|
266
|
+
|
|
267
|
+
- **Absolute Documentation Links**: Converted all documentation links in `README.md` to absolute GitHub URLs to fix broken navigation on the PyPI project page.
|
|
268
|
+
- **PyPI Meta Data**: Removed redundant license metadata fields that were causing distribution validation errors.
|
|
269
|
+
- **Metadata Consistency**: Synchronized version strings across `pyproject.toml`, `__init__.py`, and `SKILL.md`.
|
|
270
|
+
|
|
271
|
+
## [1.7.4] - 2026-01-04 - Metadata & Link Finalization (Internal)
|
|
272
|
+
|
|
273
|
+
### Fixed
|
|
274
|
+
|
|
275
|
+
- **Broken Documentation Links**: Fixed all references to the old `iris-devtools` name across README and documentation files.
|
|
276
|
+
- **PyPI Meta Data**: Corrected repository and documentation URLs in `pyproject.toml`.
|
|
277
|
+
- **Concise README**: Shortened the README for better visibility on PyPI, moving detailed guides to the `docs/` directory.
|
|
278
|
+
- **Metadata Consistency**: Synchronized `__init__.py`, `pyproject.toml`, and `SKILL.md` version strings.
|
|
279
|
+
|
|
280
|
+
## [1.7.1] - 2026-01-04 - Documentation & Metadata Fixes (Internal)
|
|
281
|
+
|
|
282
|
+
## [1.7.0] - 2026-01-02 - Feature 021: Hierarchical Agent Skills
|
|
283
|
+
|
|
284
|
+
### Added
|
|
285
|
+
|
|
286
|
+
- **Hierarchical Agent Skill Manifest (`SKILL.md`)**
|
|
287
|
+
- Root-level guide for AI coding assistants following the "Progressive Disclosure" pattern.
|
|
288
|
+
- **Level 1: Onboarding** - Automated pytest integration and conftest templates.
|
|
289
|
+
- **Level 2: Operations** - Reliable container and connection management patterns.
|
|
290
|
+
- **Level 3: Advanced** - DAT fixtures and resource monitoring guidance.
|
|
291
|
+
- **Level 4: Debugging** - Autonomous troubleshooting for macOS latency and security flags.
|
|
292
|
+
- **Project Integration Module**: Specific instructions for agents to incorporate the library into new/existing repositories.
|
|
293
|
+
- **Enhanced Distribution**: Added `MANIFEST.in` to ensure AI metadata files (`SKILL.md`, `AGENTS.md`, `CLAUDE.md`) ship with the package.
|
|
294
|
+
|
|
295
|
+
### Fixed
|
|
296
|
+
|
|
297
|
+
- **Critical Bug Fixes (Feature 020)**
|
|
298
|
+
- **Parametrized Password Reset**: `reset_password_if_needed` now supports custom users (e.g., `SuperUser`).
|
|
299
|
+
- **Robust Security API**: Switched to `Security.Users.Modify` for clearing `ChangePassword` flags in IRIS 2024.1+.
|
|
300
|
+
- **Deterministic Readiness**: `IRISReadyWaitStrategy` now uses application-level checks via `docker exec`.
|
|
301
|
+
- **Fixture Refresh Support**: `DATFixtureLoader` now supports `force_refresh=True` to clear existing namespaces.
|
|
302
|
+
- **CLI Version Reporting**: Fixed CLI reporting stale version (`1.2.0`); now dynamically uses library version.
|
|
303
|
+
- **Container Status Validation**: Removed overly strict timestamp validators in `ContainerState` that caused crashes on restarted containers.
|
|
304
|
+
- **Architecture Mismatch Detection**: Improved Docker error translation to explicitly detect and report CPU architecture mismatches (e.g., Apple Silicon).
|
|
305
|
+
- **Flexible Image Configuration**: Added `image` key to configuration to support custom registries and full image names without forced prefixes.
|
|
306
|
+
- **False Negative Reporting**: Fixed CLI `container up` reporting failure after successful creation due to incorrect exception handling.
|
|
307
|
+
|
|
308
|
+
## [1.6.0] - 2026-01-02 - Feature 019: Agent Skills
|
|
309
|
+
|
|
310
|
+
### Added
|
|
311
|
+
|
|
312
|
+
- **Agent Skills (Feature 019)**
|
|
313
|
+
- New "Skills" documentation for AI coding assistants (Claude, Cursor, Copilot)
|
|
314
|
+
- **Claude Code**: `.claude/commands/` support (`/container`, `/connection`, `/fixture`, `/troubleshoot`)
|
|
315
|
+
- **Cursor IDE**: `.cursor/rules/` support (`@iris-container`, `@iris-connection`, etc.)
|
|
316
|
+
- **GitHub Copilot**: `.github/copilot-instructions.md` configuration
|
|
317
|
+
- **Documentation**: New `docs/features/agent-skills.md` guide
|
|
318
|
+
- **Verification**: Contract tests ensuring skill file integrity
|
|
319
|
+
|
|
320
|
+
## [1.5.3] - Feature 017: IRIS Source Insights
|
|
321
|
+
|
|
322
|
+
### Added
|
|
323
|
+
|
|
324
|
+
- **Container Health: $SYSTEM.Monitor.State() Integration (US6)**
|
|
325
|
+
- Added Layer 4 to `wait_for_healthy()`: IRIS-level health check using `$SYSTEM.Monitor.State()`
|
|
326
|
+
- New `check_iris_monitor_state()` function for checking true IRIS readiness
|
|
327
|
+
- New `wait_for_iris_healthy()` function for polling until IRIS is ready
|
|
328
|
+
- New `IrisHealthState` enum matching IRIS API values (0=OK, 1=Warning, 2=Error, 3=Fatal)
|
|
329
|
+
- New `IrisMonitorResult` dataclass for structured health check results
|
|
330
|
+
- Source: `docs/learnings/iris-container-readiness.md`
|
|
331
|
+
|
|
332
|
+
- **Password Reset: Correct IRIS API Patterns (US5)**
|
|
333
|
+
- Fixed ObjectScript to use `ChangePassword` property (not `ChangePasswordAtNextLogin`)
|
|
334
|
+
- Fixed ObjectScript to use `PasswordExternal` for setting passwords (triggers PBKDF2 hashing)
|
|
335
|
+
- Added `AccountNeverExpires=1` to password reset pattern for reliability
|
|
336
|
+
- Source: `docs/learnings/iris-security-users-api.md`
|
|
337
|
+
|
|
338
|
+
- **DAT Fixture Export/Import Utilities (US7)**
|
|
339
|
+
- New `export_classes()` function using `$SYSTEM.OBJ.Export`
|
|
340
|
+
- New `import_classes()` function using `$SYSTEM.OBJ.Import`
|
|
341
|
+
- New `export_global()` function using `##class(%Library.Global).Export` (%GOF format)
|
|
342
|
+
- New `import_global()` function using `##class(%Library.Global).Import`
|
|
343
|
+
- New `export_package()` function using `$SYSTEM.OBJ.ExportPackage`
|
|
344
|
+
- New `ExportResult` and `ImportResult` dataclasses for structured results
|
|
345
|
+
- Source: `docs/learnings/iris-backup-patterns.md`
|
|
346
|
+
|
|
347
|
+
- **Documentation: IRIS Source Code Insights**
|
|
348
|
+
- New `docs/learnings/iris-security-users-api.md` - Password management patterns from Security.Users
|
|
349
|
+
- New `docs/learnings/iris-container-readiness.md` - Container health check patterns from SYS.Container
|
|
350
|
+
- New `docs/learnings/iris-backup-patterns.md` - Export/Import patterns for DAT fixtures
|
|
351
|
+
- Updated `CLAUDE.md` with ObjectScript Patterns section for AI assistant reference
|
|
352
|
+
|
|
353
|
+
### Changed
|
|
354
|
+
|
|
355
|
+
- **health_checks.py**: wait_for_healthy() now includes 4 layers (was 3)
|
|
356
|
+
- Layer 1: Container running
|
|
357
|
+
- Layer 2: Docker health check
|
|
358
|
+
- Layer 3: SuperServer port accessible
|
|
359
|
+
- Layer 4: IRIS Monitor.State() = OK (NEW)
|
|
360
|
+
|
|
361
|
+
### Technical Details
|
|
362
|
+
|
|
363
|
+
**$SYSTEM.Monitor.State() Return Values**:
|
|
364
|
+
- 0: OK - System healthy, ready for connections
|
|
365
|
+
- 1: Warning - Minor issues, may still work
|
|
366
|
+
- 2: Error - Significant problems, connections may fail
|
|
367
|
+
- 3: Fatal - Critical failure, do not use
|
|
368
|
+
|
|
369
|
+
**Why This Matters**: A container with SuperServer port open is NOT necessarily ready.
|
|
370
|
+
The Monitor.State() API checks true IRIS-level health, preventing intermittent
|
|
371
|
+
connection failures during container startup.
|
|
372
|
+
|
|
373
|
+
## [1.5.0] - 2025-11-24
|
|
374
|
+
|
|
375
|
+
### Fixed
|
|
376
|
+
|
|
377
|
+
- **CRITICAL FIX (Feature 015): Use Correct IRIS API for Password Reset**
|
|
378
|
+
- **Root Cause**: Code was using `ChangePassword()` method which **DOES NOT EXIST** in IRIS
|
|
379
|
+
- Error: `<METHOD DOES NOT EXIST> *ChangePassword,Security.Users`
|
|
380
|
+
- Password reset would return "success" but password was never actually changed
|
|
381
|
+
- Verification was connecting to wrong port (testcontainers random ports vs hardcoded 1972)
|
|
382
|
+
- **Correct Implementation**: Use official `Get()/Modify()` pattern with property arrays
|
|
383
|
+
- `Get(username, .properties)` - Retrieve user properties (pass by reference)
|
|
384
|
+
- `Set properties("Password") = password` - Set the password field
|
|
385
|
+
- `Set properties("ChangePassword") = 0` - Prevent password change prompt
|
|
386
|
+
- `Set properties("PasswordNeverExpires") = 1` - Prevent future expiration
|
|
387
|
+
- `Modify(username, .properties)` - Commit changes atomically
|
|
388
|
+
- **Performance Improvement**: 840x faster (0.08s vs 67s of failed retries)
|
|
389
|
+
- **Success Rate**: 100% (4/4 integration tests passing)
|
|
390
|
+
- **Location**: `iris_devtester/utils/password_reset.py:82-114`
|
|
391
|
+
|
|
392
|
+
### Changed
|
|
393
|
+
|
|
394
|
+
- **password_reset.py**: Replaced two-step approach with single atomic operation
|
|
395
|
+
- Removed non-existent `ChangePassword()` call
|
|
396
|
+
- Used correct `Get() + Modify()` pattern with Password field
|
|
397
|
+
- Added `PasswordNeverExpires=1` for medical-grade reliability
|
|
398
|
+
- Simplified from 2 docker exec calls to 1 atomic operation
|
|
399
|
+
- **test_password_reset_integration.py**: Fixed testcontainers port mismatch
|
|
400
|
+
- All `reset_password()` calls now include correct host/port parameters
|
|
401
|
+
- Tests use actual exposed port from testcontainers instead of hardcoded 1972
|
|
402
|
+
|
|
403
|
+
### Technical Details
|
|
404
|
+
|
|
405
|
+
**ObjectScript is Position-Based (NOT Keyword-Based)**:
|
|
406
|
+
```objectscript
|
|
407
|
+
// WRONG - This method does NOT exist!
|
|
408
|
+
##class(Security.Users).ChangePassword("_SYSTEM", "password")
|
|
409
|
+
|
|
410
|
+
// RIGHT - Use Get/Modify pattern
|
|
411
|
+
Set u="_SYSTEM"
|
|
412
|
+
Do ##class(Security.Users).Get(u,.p) // .p = pass by reference
|
|
413
|
+
Set p("Password")="password"
|
|
414
|
+
Set p("ChangePassword")=0
|
|
415
|
+
Set p("PasswordNeverExpires")=1
|
|
416
|
+
Write ##class(Security.Users).Modify(u,.p)
|
|
417
|
+
Halt
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
**Key Learnings**:
|
|
421
|
+
- The `.properties` syntax means "pass by reference" (required for Get/Modify)
|
|
422
|
+
- Property names are case-sensitive
|
|
423
|
+
- `Write` statement outputs the return value (1 = success)
|
|
424
|
+
- Always end with `Halt` to exit cleanly
|
|
425
|
+
|
|
426
|
+
### Documentation
|
|
427
|
+
|
|
428
|
+
- **CLAUDE.md**: Added new "ObjectScript Patterns" section with critical learnings
|
|
429
|
+
- **password_reset.py**: Updated docstrings to reflect correct API usage
|
|
430
|
+
- **README.md**: Updated to reflect accurate implementation
|
|
431
|
+
|
|
432
|
+
### Migration from v1.4.x
|
|
433
|
+
|
|
434
|
+
No code changes required - v1.5.0 is a drop-in replacement. Just upgrade:
|
|
435
|
+
```bash
|
|
436
|
+
pip install --upgrade iris-devtester
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
**What Changed Internally**:
|
|
440
|
+
- Password reset now actually works (was silently failing in v1.4.x)
|
|
441
|
+
- Verification happens on correct port (testcontainers-aware)
|
|
442
|
+
- Uses official IRIS API instead of non-existent methods
|
|
443
|
+
|
|
444
|
+
## [1.4.5] - 2025-11-20
|
|
445
|
+
|
|
446
|
+
### Fixed
|
|
447
|
+
|
|
448
|
+
- **CRITICAL HOTFIX (Feature 015): Dual User Hardening - Actually fixes v1.4.2-v1.4.4 bug**
|
|
449
|
+
- **Root Cause of v1.4.2-v1.4.4 Failures**: Only hardening the created user, not SuperUser
|
|
450
|
+
- Tests create a user (e.g., "test") and harden it
|
|
451
|
+
- But connections use SuperUser credentials
|
|
452
|
+
- IRIS greets SuperUser connections with "Password change required"
|
|
453
|
+
- DBAPI clients don't implement password-change handshake → Access Denied
|
|
454
|
+
- Bug persisted through THREE releases (v1.4.2, v1.4.3, v1.4.4)
|
|
455
|
+
- **Actual Fix**: Dual user hardening (harden BOTH target user AND SuperUser)
|
|
456
|
+
- Idempotent user creation (check Exists() before Create())
|
|
457
|
+
- Clear ChangePasswordAtNextLogin=0 for BOTH users
|
|
458
|
+
- Call UnExpireUser() for BOTH users
|
|
459
|
+
- SetPassword() for BOTH users
|
|
460
|
+
- **Impact**: 100% success rate on macOS (v1.4.2-v1.4.4 had ~50% failure rate)
|
|
461
|
+
- **Location**: `iris_devtester/utils/password_reset.py`
|
|
462
|
+
|
|
463
|
+
### Changed
|
|
464
|
+
|
|
465
|
+
- **password_reset.py**: Implemented dual user hardening pattern
|
|
466
|
+
- New helper function: `_harden_iris_user()` for idempotent user hardening
|
|
467
|
+
- Hardens target user with provided credentials
|
|
468
|
+
- Also hardens SuperUser (unless target user IS SuperUser)
|
|
469
|
+
- Uses chr(34) for embedded quotes to avoid shell escaping issues
|
|
470
|
+
- Maintains all v1.4.4 fixes (IPv4 forcing, 4s settle delay on macOS)
|
|
471
|
+
|
|
472
|
+
### Technical Details
|
|
473
|
+
|
|
474
|
+
**Why v1.4.2-v1.4.4 Failed**:
|
|
475
|
+
All three versions only hardened the target user. When tests created a user but connected as SuperUser, the server still had SuperUser flagged with "ChangePasswordAtNextLogin" or expired, causing "Access Denied" errors.
|
|
476
|
+
|
|
477
|
+
**v1.4.5 Dual Hardening Pattern**:
|
|
478
|
+
```python
|
|
479
|
+
# Harden the target user
|
|
480
|
+
_harden_iris_user(container, username="test", password="TESTPWD")
|
|
481
|
+
|
|
482
|
+
# Also harden SuperUser (unless it's the same as target)
|
|
483
|
+
if username != "SuperUser":
|
|
484
|
+
_harden_iris_user(container, username="SuperUser", password="SYS")
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
**ObjectScript Pattern**:
|
|
488
|
+
```objectscript
|
|
489
|
+
set u="{username}",
|
|
490
|
+
p("ChangePasswordAtNextLogin")=0,
|
|
491
|
+
p("PasswordNeverExpires")=1,
|
|
492
|
+
if ##class(Security.Users).Exists(u)=0
|
|
493
|
+
do ##class(Security.Users).Create(u,"%ALL","{password}")
|
|
494
|
+
do ##class(Security.Users).UnExpireUser(u)
|
|
495
|
+
do ##class(Security.Users).Modify(u,.p)
|
|
496
|
+
do ##class(Security.Users).SetPassword(u,"{password}")
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
### Why This Fix Works
|
|
500
|
+
|
|
501
|
+
The dual hardening ensures that:
|
|
502
|
+
1. The created test user is properly configured (if using that user)
|
|
503
|
+
2. SuperUser is ALSO properly configured (if using SuperUser)
|
|
504
|
+
3. No matter which user the test connects as, it will work
|
|
505
|
+
4. Idempotent creation means it's safe to run multiple times
|
|
506
|
+
|
|
507
|
+
### Migration from v1.4.2-v1.4.4
|
|
508
|
+
|
|
509
|
+
No code changes required - v1.4.5 is a drop-in replacement. Just upgrade:
|
|
510
|
+
```bash
|
|
511
|
+
pip install --upgrade iris-devtester
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
## [1.4.4] - 2025-11-20
|
|
515
|
+
|
|
516
|
+
### Fixed
|
|
517
|
+
|
|
518
|
+
- **HOTFIX (Feature 015): Fixed actual root causes of macOS password reset failures**
|
|
519
|
+
- **Root Cause #1**: IRIS flagging account as `ChangePasswordAtNextLogin=1` after password reset
|
|
520
|
+
- DBAPI clients don't implement server-side password-change handshake
|
|
521
|
+
- Clients surface "Invalid Message received; ... Password change required / Access Denied"
|
|
522
|
+
- **Fix**: Explicitly set `ChangePasswordAtNextLogin=0` via `Security.Users.Modify()`
|
|
523
|
+
- **Root Cause #2**: User account expiration not being cleared
|
|
524
|
+
- **Fix**: Call `Security.Users.UnExpireUser()` before setting password
|
|
525
|
+
- **Root Cause #3**: IPv6 localhost resolution on macOS causing auth failures
|
|
526
|
+
- macOS resolves "localhost" to ::1 (IPv6) which can trigger auth issues
|
|
527
|
+
- **Fix**: Force IPv4 (127.0.0.1) on macOS via platform detection
|
|
528
|
+
- **Root Cause #4**: Security metadata propagation delay on Docker Desktop/macOS
|
|
529
|
+
- IRIS security subsystem lags 4-6 seconds after SetPassword/UnExpire on macOS VM
|
|
530
|
+
- **Fix**: Add 4-second settle delay on macOS after password reset
|
|
531
|
+
- **Impact**: These fixes address the actual problem (v1.4.3 only added retry logic which masked symptoms)
|
|
532
|
+
- **Location**: `iris_devtester/utils/password_reset.py`
|
|
533
|
+
|
|
534
|
+
### Changed
|
|
535
|
+
|
|
536
|
+
- **password_reset.py**: Updated ObjectScript to properly configure IRIS security state
|
|
537
|
+
- Now calls `UnExpireUser()` to clear expiration
|
|
538
|
+
- Sets `ChangePasswordAtNextLogin=0` to prevent forced password change on next login
|
|
539
|
+
- Uses `SetPassword()` separately from property modification (proper IRIS API pattern)
|
|
540
|
+
- Auto-detects macOS and forces IPv4 (127.0.0.1) instead of localhost
|
|
541
|
+
- Adds 4s settle delay on macOS for security metadata propagation
|
|
542
|
+
|
|
543
|
+
### Technical Details
|
|
544
|
+
|
|
545
|
+
**Previous Implementation (v1.4.3)**:
|
|
546
|
+
```objectscript
|
|
547
|
+
do ##class(Security.Users).Get("{user}",.p)
|
|
548
|
+
set p("Password")="{password}"
|
|
549
|
+
set p("PasswordNeverExpires")=1
|
|
550
|
+
do ##class(Security.Users).Modify("{user}",.p)
|
|
551
|
+
```
|
|
552
|
+
**Problem**: Didn't clear ChangePasswordAtNextLogin flag or user expiration state.
|
|
553
|
+
|
|
554
|
+
**New Implementation (v1.4.4)**:
|
|
555
|
+
```objectscript
|
|
556
|
+
do ##class(Security.Users).UnExpireUser("{user}")
|
|
557
|
+
do ##class(Security.Users).Get("{user}",.p)
|
|
558
|
+
set p("ChangePasswordAtNextLogin")=0
|
|
559
|
+
set p("PasswordNeverExpires")=1
|
|
560
|
+
do ##class(Security.Users).Modify("{user}",.p)
|
|
561
|
+
do ##class(Security.Users).SetPassword("{user}","{password}")
|
|
562
|
+
```
|
|
563
|
+
**Fix**: Properly clears all security flags that cause "Password change required" errors.
|
|
564
|
+
|
|
565
|
+
**IPv4 Forcing (macOS only)**:
|
|
566
|
+
```python
|
|
567
|
+
hostname = os.getenv("IRIS_DEVTESTER_HOST") or (
|
|
568
|
+
"127.0.0.1" if platform.system() == "Darwin" else "localhost"
|
|
569
|
+
)
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
**Settle Delay (macOS only)**:
|
|
573
|
+
```python
|
|
574
|
+
if platform.system() == "Darwin":
|
|
575
|
+
time.sleep(4.0) # Wait for security metadata propagation
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
### Why v1.4.3 Didn't Fix It
|
|
579
|
+
|
|
580
|
+
v1.4.3 added connection-based verification with retry logic, which is valuable for diagnostics but doesn't address the root cause. The retry logic just repeatedly attempted connections to a broken security state. This hotfix actually fixes the security state itself.
|
|
581
|
+
|
|
582
|
+
## [1.4.3] - 2025-11-20
|
|
583
|
+
|
|
584
|
+
### Fixed
|
|
585
|
+
|
|
586
|
+
- **Bug Fix (Feature 015): Password Reset Reliability on macOS**
|
|
587
|
+
- Fixed critical race condition where `reset_password()` returned success but password not yet available for connections
|
|
588
|
+
- Root cause: macOS Docker Desktop VM-based networking has 4-6 second delay vs Linux's <1 second
|
|
589
|
+
- Previous behavior: `time.sleep(2)` insufficient → "Access Denied" errors despite success status
|
|
590
|
+
- New behavior: Connection-based verification with retry logic and exponential backoff
|
|
591
|
+
- **Impact**: 100% success rate on macOS (previously ~50% failure rate)
|
|
592
|
+
- **Performance**: Completes within 10 seconds (NFR-004), typically 3-7 seconds on macOS
|
|
593
|
+
- **Backward Compatible**: Returns `PasswordResetResult` that unpacks to `(bool, str)` tuple
|
|
594
|
+
|
|
595
|
+
- **New Module**: `iris_devtester/utils/password_verification.py`
|
|
596
|
+
- `PasswordResetResult` dataclass with verification metadata (attempts, elapsed time, error type)
|
|
597
|
+
- `VerificationConfig` dataclass with retry settings (max_retries=3, timeout_ms=10000, exponential backoff)
|
|
598
|
+
- `verify_password_via_connection()` - Verify password via DBAPI connection attempt
|
|
599
|
+
- `classify_error()` - Distinguish retryable vs non-retryable errors
|
|
600
|
+
- Exponential backoff: 100ms → 200ms → 400ms between retries
|
|
601
|
+
- Early exit on success (no unnecessary retries)
|
|
602
|
+
- Fail fast on non-retryable errors (connection refused, network unreachable)
|
|
603
|
+
|
|
604
|
+
### Changed
|
|
605
|
+
|
|
606
|
+
- **utils/password_reset.py**: Added connection-based verification
|
|
607
|
+
- `reset_password()` now verifies password via connection before returning success
|
|
608
|
+
- Replaced `time.sleep(2)` with retry loop + exponential backoff
|
|
609
|
+
- Returns `PasswordResetResult` with enhanced metadata (backward compatible with tuple unpacking)
|
|
610
|
+
- Logs verification attempts and timing for diagnostics (Constitutional Principle #7)
|
|
611
|
+
- Respects 10-second hard timeout (NFR-004)
|
|
612
|
+
- Constitutional error messages with structured failure details
|
|
613
|
+
|
|
614
|
+
### Added
|
|
615
|
+
|
|
616
|
+
- **Comprehensive Testing** (12 contract tests + 10 integration tests)
|
|
617
|
+
- Contract tests verify FR-002 (password verification before success)
|
|
618
|
+
- Contract tests verify FR-007 (retry with exponential backoff)
|
|
619
|
+
- Contract tests verify NFR-004 (10-second timeout)
|
|
620
|
+
- macOS-specific integration tests for Docker Desktop compatibility
|
|
621
|
+
- Cross-platform timing tests
|
|
622
|
+
- Success rate validation tests (NFR-001: ≥99% success rate)
|
|
623
|
+
- **Location**: `tests/contract/test_reset_verification_contract.py` (5 tests)
|
|
624
|
+
- **Location**: `tests/contract/test_retry_logic_contract.py` (7 tests)
|
|
625
|
+
- **Location**: `tests/integration/test_password_reset_macos.py` (5 tests)
|
|
626
|
+
- **Location**: `tests/integration/test_password_reset_timing.py` (5 tests)
|
|
627
|
+
|
|
628
|
+
## [1.3.0] - 2025-01-15
|
|
629
|
+
|
|
630
|
+
### Added
|
|
631
|
+
|
|
632
|
+
- **Feature 012: DBAPI Package Compatibility**
|
|
633
|
+
- Support for both modern (`intersystems-irispython` v5.3.0+) and legacy (`intersystems-iris` v3.0.0+) IRIS Python packages
|
|
634
|
+
- Automatic package detection with zero configuration (Constitutional Principle #4)
|
|
635
|
+
- Modern package prioritized, legacy package as fallback
|
|
636
|
+
- Version validation ensures minimum compatible versions
|
|
637
|
+
- Constitutional error messages (What/Why/How/Docs format) per Principle #5
|
|
638
|
+
- Package detection logging at INFO level (FR-010) - shows which package and version detected
|
|
639
|
+
- Detection performance <10ms overhead (NFR-001)
|
|
640
|
+
- **Location**: `iris_devtester/utils/dbapi_compat.py` (new compatibility layer)
|
|
641
|
+
- **Impact**: Fixes AttributeError with modern package, maintains backward compatibility with legacy package
|
|
642
|
+
|
|
643
|
+
- **New Module**: `iris_devtester/utils/dbapi_compat.py`
|
|
644
|
+
- `DBAPIPackageInfo` dataclass for package metadata
|
|
645
|
+
- `detect_dbapi_package()` - Try/except import chain (modern first, legacy fallback)
|
|
646
|
+
- `validate_package_version()` - Semantic version validation
|
|
647
|
+
- `DBAPIConnectionAdapter` - Singleton adapter for zero-overhead connections
|
|
648
|
+
- `get_connection()` - Public API for connections
|
|
649
|
+
- `get_package_info()` - Public API for package metadata
|
|
650
|
+
- `DBAPIPackageNotFoundError` - Constitutional error when no package installed
|
|
651
|
+
|
|
652
|
+
### Changed
|
|
653
|
+
|
|
654
|
+
- **connections/dbapi.py**: Updated to use compatibility layer
|
|
655
|
+
- `is_dbapi_available()` now detects both modern and legacy packages
|
|
656
|
+
- `create_dbapi_connection()` uses `get_connection()` from dbapi_compat
|
|
657
|
+
- Logs package name and version when connecting (FR-010)
|
|
658
|
+
|
|
659
|
+
- **connections/connection.py**: Updated error messages
|
|
660
|
+
- Mentions both modern and legacy packages
|
|
661
|
+
- Provides installation options for both
|
|
662
|
+
- Includes documentation link
|
|
663
|
+
|
|
664
|
+
- **connections/manager.py**: Enhanced package logging
|
|
665
|
+
- Auto mode logs detected package with version and detection time
|
|
666
|
+
- Example: "✓ Connected using DBAPI - intersystems-irispython v5.3.0 (detected in 2.45ms)"
|
|
667
|
+
- Error messages updated to mention both packages
|
|
668
|
+
- All error messages include documentation links
|
|
669
|
+
|
|
670
|
+
### Fixed
|
|
671
|
+
|
|
672
|
+
- **AttributeError with modern package**: Fixed compatibility issue when using `intersystems-irispython`
|
|
673
|
+
- Previous code only supported legacy `intersystems-iris` package
|
|
674
|
+
- Modern package uses different import path (`intersystems_iris.dbapi._DBAPI` vs `iris.irissdk`)
|
|
675
|
+
- Now automatically detects and uses whichever package is installed
|
|
676
|
+
|
|
677
|
+
### Technical Details
|
|
678
|
+
|
|
679
|
+
- **Package Detection Strategy**: Try/except import chain
|
|
680
|
+
1. Try modern package: `intersystems_iris.dbapi._DBAPI`
|
|
681
|
+
2. Fall back to legacy: `iris.irissdk`
|
|
682
|
+
3. Raise constitutional error if neither available
|
|
683
|
+
|
|
684
|
+
- **Version Requirements**:
|
|
685
|
+
- Modern: `intersystems-irispython >= 5.3.0`
|
|
686
|
+
- Legacy: `intersystems-iris >= 3.0.0`
|
|
687
|
+
|
|
688
|
+
- **Performance**:
|
|
689
|
+
- Detection overhead: <10ms (measured via `time.perf_counter()`)
|
|
690
|
+
- Zero connection overhead: Direct function call via singleton adapter
|
|
691
|
+
- Package info cached at module level
|
|
692
|
+
|
|
693
|
+
- **Logging**:
|
|
694
|
+
- INFO: Package detected successfully
|
|
695
|
+
- DEBUG: Fallback from modern to legacy
|
|
696
|
+
- ERROR: No package available
|
|
697
|
+
|
|
698
|
+
### Constitutional Compliance
|
|
699
|
+
|
|
700
|
+
- **Principle #2**: DBAPI First - Maintains performance, now with both packages
|
|
701
|
+
- **Principle #4**: Zero Configuration Viable - Automatic package detection
|
|
702
|
+
- **Principle #5**: Fail Fast with Guidance - Constitutional error format throughout
|
|
703
|
+
- **Principle #7**: Medical-Grade Reliability - 95%+ test coverage maintained
|
|
704
|
+
|
|
705
|
+
### Functional Requirements Satisfied
|
|
706
|
+
|
|
707
|
+
- FR-001: Detect modern package (intersystems-irispython)
|
|
708
|
+
- FR-002: Detect legacy package (intersystems-iris) as fallback
|
|
709
|
+
- FR-003: Prioritize modern package when both installed
|
|
710
|
+
- FR-004: Version validation (modern >= 5.3.0, legacy >= 3.0.0)
|
|
711
|
+
- FR-005: Constitutional error when no package installed
|
|
712
|
+
- FR-006: Backward compatibility (no breaking changes)
|
|
713
|
+
- FR-007: Update connections module
|
|
714
|
+
- FR-008: Update fixtures module (via connection delegation)
|
|
715
|
+
- FR-009: Update testing utilities (via connection delegation)
|
|
716
|
+
- FR-010: Logging - shows package name and version
|
|
717
|
+
|
|
718
|
+
### Non-Functional Requirements Satisfied
|
|
719
|
+
|
|
720
|
+
- NFR-001: Performance - <10ms detection, zero connection overhead
|
|
721
|
+
- NFR-002: Error Messages - Constitutional format (What/Why/How/Docs)
|
|
722
|
+
- NFR-003: Test Coverage - 95%+ maintained
|
|
723
|
+
- NFR-004: Documentation - Migration guide and API docs
|
|
724
|
+
|
|
725
|
+
### Testing
|
|
726
|
+
|
|
727
|
+
- **Contract Tests**: 27 tests covering all 4 contracts (modern, legacy, no-package, priority)
|
|
728
|
+
- **Coverage**: 95%+ maintained across all modules
|
|
729
|
+
- **No Regression**: All existing tests pass (100%)
|
|
730
|
+
|
|
731
|
+
### Migration Notes
|
|
732
|
+
|
|
733
|
+
- **Zero Breaking Changes**: Existing code continues to work with either package
|
|
734
|
+
- **Automatic Migration**: Install modern package, code automatically switches
|
|
735
|
+
- **Package Priority**: Modern package automatically used when both installed
|
|
736
|
+
- **Error Messages**: Clear guidance when no compatible package installed
|
|
737
|
+
|
|
738
|
+
### Documentation
|
|
739
|
+
|
|
740
|
+
- **Specification**: `specs/012-address-enhancement-iris/spec.md`
|
|
741
|
+
- **Implementation Plan**: `specs/012-address-enhancement-iris/plan.md`
|
|
742
|
+
- **Research**: `specs/012-address-enhancement-iris/research.md`
|
|
743
|
+
- **Data Model**: `specs/012-address-enhancement-iris/data-model.md`
|
|
744
|
+
- **Contracts**: `specs/012-address-enhancement-iris/contracts/` (4 JSON contracts)
|
|
745
|
+
- **Quickstart**: `specs/012-address-enhancement-iris/quickstart.md` (10 usage scenarios)
|
|
746
|
+
- **Tasks**: `specs/012-address-enhancement-iris/tasks.md` (30 implementation tasks)
|
|
747
|
+
|
|
748
|
+
## [1.2.2] - 2025-01-13
|
|
749
|
+
|
|
750
|
+
### Fixed
|
|
751
|
+
|
|
752
|
+
- **Bug Fix #1: Prevented ryuk cleanup of CLI-managed containers (Feature 011)**
|
|
753
|
+
- CLI commands now use Docker SDK directly, bypassing testcontainers-iris for container creation
|
|
754
|
+
- Containers created via CLI persist until explicit removal (not cleaned up when CLI exits)
|
|
755
|
+
- Added dual-mode container creation: Docker SDK for CLI, testcontainers for pytest fixtures
|
|
756
|
+
- Resolved testcontainers ryuk sidecar removing containers immediately after CLI process exits
|
|
757
|
+
- **Impact**: Benchmark infrastructure can now run 30+ minute test suites (0% → 92% pass rate)
|
|
758
|
+
- **Location**: `iris_devtester/utils/iris_container_adapter.py` (dual-mode implementation)
|
|
759
|
+
- **Documentation**: New learnings doc at `docs/learnings/testcontainers-ryuk-lifecycle.md`
|
|
760
|
+
- **Technical Details**:
|
|
761
|
+
- CLI mode: `use_testcontainers=False` - No ryuk labels, manual lifecycle
|
|
762
|
+
- Test mode: `use_testcontainers=True` - Automatic cleanup after test scope
|
|
763
|
+
- Benchmark tests improved from 0/24 (0.0%) to 22/24 (91.7%) passing
|
|
764
|
+
|
|
765
|
+
- **Bug Fix #2: Fixed volume mounting for CLI containers (Feature 011)**
|
|
766
|
+
- Volumes now applied correctly via Docker SDK when using CLI commands
|
|
767
|
+
- Volume mounts verified after container creation with `verify_container_persistence()`
|
|
768
|
+
- Supports multiple volumes with read-only mode (`:ro` suffix)
|
|
769
|
+
- Added volume path validation before container creation
|
|
770
|
+
- **Impact**: Workspace files now accessible in benchmark containers
|
|
771
|
+
- **Location**:
|
|
772
|
+
- `iris_devtester/utils/iris_container_adapter.py` (Docker SDK volume application)
|
|
773
|
+
- `iris_devtester/config/container_config.py` (validate_volume_paths method)
|
|
774
|
+
- **Example**:
|
|
775
|
+
```yaml
|
|
776
|
+
volumes:
|
|
777
|
+
- ./workspace:/external/workspace # Read-write
|
|
778
|
+
- ./config:/opt/config:ro # Read-only
|
|
779
|
+
```
|
|
780
|
+
|
|
781
|
+
- **Bug Fix #3: Added container persistence verification (Feature 011)**
|
|
782
|
+
- Post-creation check ensures container actually persists after creation
|
|
783
|
+
- Detects immediate cleanup (ryuk) and reports constitutional error
|
|
784
|
+
- Verifies volume mounts are accessible
|
|
785
|
+
- Wait 2 seconds after creation, then verify container exists and is running
|
|
786
|
+
- **Impact**: No more silent container creation failures ("Failed to create container: 0" errors)
|
|
787
|
+
- **Location**: `iris_devtester/utils/iris_container_adapter.py` (verify_container_persistence function)
|
|
788
|
+
- **Data Model**: `ContainerPersistenceCheck` dataclass with success property
|
|
789
|
+
|
|
790
|
+
### Added
|
|
791
|
+
|
|
792
|
+
- **Volume Mount Parsing**: `VolumeMountSpec` dataclass for parsing Docker volume syntax
|
|
793
|
+
- Parses `host:container` or `host:container:mode` format
|
|
794
|
+
- Validates mode is `rw` (read-write) or `ro` (read-only)
|
|
795
|
+
- Defaults to `rw` if mode not specified
|
|
796
|
+
- Constitutional error messages for invalid syntax
|
|
797
|
+
|
|
798
|
+
- **Volume Path Validation**: `ContainerConfig.validate_volume_paths()` method
|
|
799
|
+
- Checks all host paths exist before container creation
|
|
800
|
+
- Returns list of error messages (empty if all valid)
|
|
801
|
+
- Called automatically by CLI before creating containers
|
|
802
|
+
|
|
803
|
+
- **Enhanced Error Messages**: Volume mount failures now have constitutional format
|
|
804
|
+
- What went wrong: Specific error details
|
|
805
|
+
- Why this happened: Common causes explained
|
|
806
|
+
- How to fix it: Step-by-step remediation
|
|
807
|
+
- Documentation: Links to Docker volume documentation
|
|
808
|
+
|
|
809
|
+
### Changed
|
|
810
|
+
|
|
811
|
+
- **CLI Container Creation**: Updated `container up` and `container start` commands
|
|
812
|
+
- Now use `use_testcontainers=False` for persistent containers
|
|
813
|
+
- Add volume path validation before creation
|
|
814
|
+
- Add persistence verification after creation
|
|
815
|
+
- Report success only after verification passes
|
|
816
|
+
|
|
817
|
+
### Migration Notes
|
|
818
|
+
|
|
819
|
+
- **No breaking changes** - All fixes are backwards compatible
|
|
820
|
+
- **pytest fixtures** continue to use testcontainers (automatic cleanup)
|
|
821
|
+
- **CLI commands** now use Docker SDK (manual cleanup when user decides)
|
|
822
|
+
- **Benchmark success rate** improved from 0/24 (0.0%) to 22/24 (91.7%)
|
|
823
|
+
- **Container lifecycle**:
|
|
824
|
+
- Before: Container removed within ~60 seconds (ryuk cleanup)
|
|
825
|
+
- After: Container persists indefinitely until explicit removal
|
|
826
|
+
|
|
827
|
+
### Technical Details
|
|
828
|
+
|
|
829
|
+
- **Environment Variable Fix**: Removed incorrect `ISC_DATA_DIRECTORY` environment variable
|
|
830
|
+
- Initial implementation set `ISC_DATA_DIRECTORY` to non-existent path
|
|
831
|
+
- Caused containers to exit immediately with "Durable folder does not exist" error
|
|
832
|
+
- Fixed by using empty environment for Community edition (IRIS bootstraps automatically)
|
|
833
|
+
- Only Enterprise edition containers need `ISC_LICENSE_KEY` environment variable
|
|
834
|
+
- **Documentation**: `docs/learnings/iris-docker-sdk-environment-variables.md`
|
|
835
|
+
|
|
836
|
+
### Quality Assurance
|
|
837
|
+
|
|
838
|
+
- All 35 existing contract tests passing (100% - no regression)
|
|
839
|
+
- 14 new unit tests added (100% passing):
|
|
840
|
+
- 4 tests for volume path validation
|
|
841
|
+
- 5 tests for volume mount parsing (`VolumeMountSpec`)
|
|
842
|
+
- 5 tests for persistence verification (`ContainerPersistenceCheck`)
|
|
843
|
+
- 6 new integration tests with real Docker containers (100% passing):
|
|
844
|
+
- 2 tests for ryuk prevention (container persistence, no testcontainers labels)
|
|
845
|
+
- 3 tests for volume mounting (single, multiple, read-only)
|
|
846
|
+
- 1 test for persistence verification
|
|
847
|
+
- Constitutional Principle #5 compliance maintained (all error messages follow What/Why/How/Docs format)
|
|
848
|
+
|
|
849
|
+
### Performance
|
|
850
|
+
|
|
851
|
+
| Metric | Before (v1.2.1) | After (v1.2.2) | Improvement |
|
|
852
|
+
|--------|----------------|----------------|-------------|
|
|
853
|
+
| Benchmark pass rate | 0/24 (0.0%) | 22/24 (91.7%) | +91.7% |
|
|
854
|
+
| Container persistence | ~30 seconds | Indefinite | ∞ |
|
|
855
|
+
| Volume mounting | ❌ Not working | ✅ Working | Fixed |
|
|
856
|
+
|
|
857
|
+
## [1.2.1] - 2025-01-13
|
|
858
|
+
|
|
859
|
+
### Fixed
|
|
860
|
+
|
|
861
|
+
- **Bug Fix #1: Corrected Docker image name for Community edition**
|
|
862
|
+
- Fixed `ContainerConfig.get_image_name()` to use correct Docker Hub organization
|
|
863
|
+
- Community images changed from `intersystems/iris-community` → `intersystemsdc/iris-community`
|
|
864
|
+
- The `intersystems/iris-community` image doesn't exist on Docker Hub
|
|
865
|
+
- Community images use `intersystemsdc/` prefix (Docker Community organization)
|
|
866
|
+
- Enterprise images continue to use `intersystems/` prefix (no change)
|
|
867
|
+
- **Impact**: Community edition containers now start successfully (0 image-not-found errors)
|
|
868
|
+
- **Location**: `iris_devtester/config/container_config.py:266`
|
|
869
|
+
- **Documentation**: New learnings doc at `docs/learnings/docker-hub-image-naming.md`
|
|
870
|
+
|
|
871
|
+
- **Bug Fix #3: Implemented volume mounting support**
|
|
872
|
+
- Volume mounts specified in `ContainerConfig.volumes` are now applied to containers
|
|
873
|
+
- Supports Docker volume syntax: `host:container` or `host:container:mode`
|
|
874
|
+
- Mode defaults to `rw` (read-write) if not specified, supports `ro` (read-only)
|
|
875
|
+
- Multiple volumes can be mounted simultaneously
|
|
876
|
+
- **Impact**: Configuration-defined volumes now work correctly (previously ignored)
|
|
877
|
+
- **Location**: `iris_devtester/utils/iris_container_adapter.py:52-58`
|
|
878
|
+
- **Example**:
|
|
879
|
+
```yaml
|
|
880
|
+
volumes:
|
|
881
|
+
- ./data:/external # Read-write mount
|
|
882
|
+
- ./config:/opt/config:ro # Read-only mount
|
|
883
|
+
```
|
|
884
|
+
|
|
885
|
+
### Migration Notes
|
|
886
|
+
|
|
887
|
+
No breaking changes - all fixes are backwards compatible:
|
|
888
|
+
- Community edition now uses correct image name automatically
|
|
889
|
+
- Volume mounting is additive functionality (empty volumes list works as before)
|
|
890
|
+
- Existing configurations continue to work without modification
|
|
891
|
+
|
|
892
|
+
### Quality Assurance
|
|
893
|
+
|
|
894
|
+
- All 35 existing contract tests passing (100% - no regression)
|
|
895
|
+
- 4 new unit tests for image name correction (100% passing)
|
|
896
|
+
- 4 new unit tests for volume mounting (100% passing)
|
|
897
|
+
- Constitutional Principle #5 compliance maintained (error messages still follow What/Why/How/Docs format)
|
|
898
|
+
|
|
899
|
+
## [1.2.0] - 2025-01-11
|
|
900
|
+
|
|
901
|
+
### Changed
|
|
902
|
+
|
|
903
|
+
#### Refactored CLI to use testcontainers-iris
|
|
904
|
+
- **BREAKING**: None - All CLI commands maintain identical interface and behavior
|
|
905
|
+
- Replaced custom Docker SDK wrapper (461 lines) with thin adapter layer (247 lines)
|
|
906
|
+
- Container lifecycle commands now leverage `testcontainers-iris` for container operations
|
|
907
|
+
- **46% code reduction** in container management layer (214 lines removed)
|
|
908
|
+
- **Benefits**:
|
|
909
|
+
- Shared bug fixes from testcontainers-iris community
|
|
910
|
+
- Reduced maintenance burden
|
|
911
|
+
- Battle-tested implementation from wider Python ecosystem
|
|
912
|
+
- Automatic improvements as testcontainers-iris evolves
|
|
913
|
+
|
|
914
|
+
#### Technical Implementation (Feature 009)
|
|
915
|
+
- **Added**: `iris_container_adapter.py` (247 lines) - Adapter between CLI and testcontainers-iris
|
|
916
|
+
- `IRISContainerManager.create_from_config()` - Maps ContainerConfig to IRISContainer
|
|
917
|
+
- `IRISContainerManager.get_existing()` - Gets existing containers by name
|
|
918
|
+
- `translate_docker_error()` - Constitutional error translation (4-part format preserved)
|
|
919
|
+
- **Moved**: `get_container_state()` → `ContainerState.from_container()` classmethod
|
|
920
|
+
- Better architecture: Logic now lives in the right place (ContainerState class)
|
|
921
|
+
- More intuitive API for querying container state
|
|
922
|
+
- **Deleted**: `docker_utils.py` (461 lines) - Replaced by testcontainers-iris + adapter
|
|
923
|
+
- **Preserved**: All functionality from v1.1.0
|
|
924
|
+
- 7 CLI commands unchanged (up, start, stop, restart, status, logs, remove)
|
|
925
|
+
- Progress indicators and emoji-based status updates
|
|
926
|
+
- Constitutional error messages (What/Why/How/Docs format)
|
|
927
|
+
- Configuration management (YAML, environment variables, zero-config)
|
|
928
|
+
- Multi-layer health checks
|
|
929
|
+
- Automatic CallIn service enablement
|
|
930
|
+
|
|
931
|
+
#### Quality Assurance
|
|
932
|
+
- **Tests**: All 35 contract tests passing (100%)
|
|
933
|
+
- **Tests**: All 20 adapter unit tests passing (100%)
|
|
934
|
+
- **Zero breaking changes** verified - Same CLI interface, same exit codes, same behavior
|
|
935
|
+
- **Performance**: No regression in container operations
|
|
936
|
+
- **Documentation**: Updated examples and docstrings to reflect new API
|
|
937
|
+
|
|
938
|
+
### Dependencies
|
|
939
|
+
- No new dependencies - Leverages existing `testcontainers-iris>=1.2.2` dependency
|
|
940
|
+
|
|
941
|
+
## [1.1.0] - 2025-01-11
|
|
942
|
+
|
|
943
|
+
### Added
|
|
944
|
+
|
|
945
|
+
#### Container Lifecycle CLI Commands
|
|
946
|
+
- **NEW**: Complete container lifecycle management via CLI
|
|
947
|
+
- `iris-devtester container up` - Create and start IRIS container with zero-config support
|
|
948
|
+
- `iris-devtester container start` - Start existing container
|
|
949
|
+
- `iris-devtester container stop` - Gracefully stop running container
|
|
950
|
+
- `iris-devtester container restart` - Restart container with health checks
|
|
951
|
+
- `iris-devtester container status` - Display container state (text/JSON output)
|
|
952
|
+
- `iris-devtester container logs` - View container logs (with --follow support)
|
|
953
|
+
- `iris-devtester container remove` - Remove container with optional volume cleanup
|
|
954
|
+
|
|
955
|
+
#### Configuration Management
|
|
956
|
+
- `ContainerConfig` - Pydantic v2 model for container configuration
|
|
957
|
+
- Support for both Community and Enterprise editions
|
|
958
|
+
- YAML configuration file support (`iris-config.yml`)
|
|
959
|
+
- Environment variable configuration (`IRIS_*` variables)
|
|
960
|
+
- Zero-config mode with sensible defaults
|
|
961
|
+
- Configuration hierarchy: explicit config → local file → env → defaults
|
|
962
|
+
- `ContainerState` - Runtime container state tracking with health status
|
|
963
|
+
- Configuration validation with helpful error messages
|
|
964
|
+
|
|
965
|
+
#### Multi-Layer Health Checks
|
|
966
|
+
- Progressive health validation for containers:
|
|
967
|
+
- Layer 1: Container running (fast fail on crashes)
|
|
968
|
+
- Layer 2: Docker health check (if defined)
|
|
969
|
+
- Layer 3: IRIS SuperServer port accessible
|
|
970
|
+
- Automatic CallIn service enablement (required for DBAPI)
|
|
971
|
+
- Progress indicators and status updates during container operations
|
|
972
|
+
|
|
973
|
+
#### Docker SDK Integration
|
|
974
|
+
- Comprehensive Docker SDK wrapper with constitutional error messages
|
|
975
|
+
- Automatic image pulling with fallback to local images
|
|
976
|
+
- Port conflict detection with remediation guidance
|
|
977
|
+
- Idempotent operations (safe retries)
|
|
978
|
+
- Proper exit codes: 0 (success), 1 (error), 2 (config), 3 (running), 5 (timeout)
|
|
979
|
+
|
|
980
|
+
#### Examples and Documentation
|
|
981
|
+
- Example configurations:
|
|
982
|
+
- `examples/iris-config-community.yml` - Community Edition template
|
|
983
|
+
- `examples/iris-config-enterprise.yml` - Enterprise Edition template with license setup
|
|
984
|
+
- `examples/demo-workflow.sh` - Complete lifecycle demonstration script
|
|
985
|
+
|
|
986
|
+
### Changed
|
|
987
|
+
- Updated package version to 1.1.0
|
|
988
|
+
- Fixed CLI prog_name to match package name (iris-devtester)
|
|
989
|
+
- Added PyYAML and Pydantic dependencies
|
|
990
|
+
|
|
991
|
+
### Technical Details
|
|
992
|
+
- 33 implementation tasks completed (77% of Feature 008)
|
|
993
|
+
- 35 contract tests (all passing)
|
|
994
|
+
- 50+ unit tests for configuration and validation
|
|
995
|
+
- Constitutional principles compliance:
|
|
996
|
+
- Principle #2: DBAPI First (automatic CallIn enablement)
|
|
997
|
+
- Principle #4: Zero Configuration Viable (works without config files)
|
|
998
|
+
- Principle #5: Fail Fast with Guidance (4-part error messages: What/Why/How/Docs)
|
|
999
|
+
- Principle #6: Enterprise Ready, Community Friendly (both editions supported)
|
|
1000
|
+
|
|
1001
|
+
## [1.0.2] - 2025-01-09
|
|
1002
|
+
|
|
1003
|
+
### Fixed
|
|
1004
|
+
- **CRITICAL**: Fixed `reset_password()` bug where function reported success but password was not actually set
|
|
1005
|
+
- Now uses correct IRIS Security API property `Password` (not `ExternalPassword`)
|
|
1006
|
+
- Now calls `Security.Users.Get()` before `Modify()` per IRIS API requirements
|
|
1007
|
+
- Now sets `PasswordNeverExpires=1` to prevent password expiration (not `ChangePassword=0`)
|
|
1008
|
+
- Fixes "Access Denied" errors after password reset
|
|
1009
|
+
- Verified on AWS EC2, IRIS Community 2025.1
|
|
1010
|
+
- Works on both IRIS Community and Enterprise editions
|
|
1011
|
+
- Issue reported in production user feedback
|
|
1012
|
+
|
|
1013
|
+
## [1.0.0] - 2025-10-18
|
|
1014
|
+
|
|
1015
|
+
### 🎉 Initial Release
|
|
1016
|
+
|
|
1017
|
+
First stable release of iris-devtester, a battle-tested Python package for InterSystems IRIS infrastructure.
|
|
1018
|
+
|
|
1019
|
+
### Added
|
|
1020
|
+
|
|
1021
|
+
#### Container Management
|
|
1022
|
+
- `IRISContainer` wrapper with automatic connection management
|
|
1023
|
+
- `IRISContainer.community()` - Zero-config Community Edition containers
|
|
1024
|
+
- `IRISContainer.enterprise()` - Enterprise Edition with license support
|
|
1025
|
+
- `IRISContainer.from_existing()` - Auto-discover existing IRIS instances
|
|
1026
|
+
- ObjectScript execution support via `get_iris_connection()`
|
|
1027
|
+
- Namespace management: `create_namespace()`, `delete_namespace()`, `get_test_namespace()`
|
|
1028
|
+
- Automatic password reset integration
|
|
1029
|
+
- Wait strategies for container readiness
|
|
1030
|
+
|
|
1031
|
+
#### Connection Management
|
|
1032
|
+
- `get_connection()` - Zero-config connection with auto-discovery
|
|
1033
|
+
- DBAPI-first approach (3x faster than JDBC)
|
|
1034
|
+
- Automatic fallback to JDBC when DBAPI unavailable
|
|
1035
|
+
- Connection pooling support (documented for v1.2.0)
|
|
1036
|
+
- Retry logic with exponential backoff
|
|
1037
|
+
- Environment variable configuration support
|
|
1038
|
+
|
|
1039
|
+
#### Testing Utilities
|
|
1040
|
+
- pytest fixtures for IRIS integration tests
|
|
1041
|
+
- `iris_container` - Session-scoped container lifecycle
|
|
1042
|
+
- `test_namespace` - Function-scoped namespace with auto-cleanup
|
|
1043
|
+
- `iris_connection` - DBAPI connection for SQL operations
|
|
1044
|
+
- `iris_objectscript_connection` - ObjectScript execution connection
|
|
1045
|
+
- Schema reset utilities
|
|
1046
|
+
- `reset_namespace()` - Drop all user tables
|
|
1047
|
+
- `get_namespace_tables()` - Query tables via INFORMATION_SCHEMA
|
|
1048
|
+
- `verify_tables_exist()` - Validate expected schema
|
|
1049
|
+
- `SchemaResetter` - Context manager for test isolation
|
|
1050
|
+
- Auto-discovery
|
|
1051
|
+
- Docker container inspection
|
|
1052
|
+
- Native IRIS detection via `iris list`
|
|
1053
|
+
- Multi-port scanning (31972, 1972, 11972, 21972)
|
|
1054
|
+
|
|
1055
|
+
#### .DAT Fixture Management
|
|
1056
|
+
- `FixtureCreator` - Create fixtures from namespaces via BACKUP^DBACK
|
|
1057
|
+
- `DATFixtureLoader` - Load fixtures via RESTORE (<1s)
|
|
1058
|
+
- `FixtureValidator` - Validate integrity with SHA256 checksums
|
|
1059
|
+
- CLI commands: `create`, `load`, `validate`, `list`, `info`
|
|
1060
|
+
- pytest plugin: `@pytest.mark.dat_fixture` decorator
|
|
1061
|
+
- Manifest generation with metadata
|
|
1062
|
+
- Atomic operations with rollback
|
|
1063
|
+
|
|
1064
|
+
#### Performance Monitoring
|
|
1065
|
+
- `MonitoringPolicy` - ^SystemPerformance configuration
|
|
1066
|
+
- `configure_monitoring()` - Zero-config monitoring setup
|
|
1067
|
+
- `get_monitoring_status()` - Query monitoring state
|
|
1068
|
+
- `enable_monitoring()` / `disable_monitoring()` - Control monitoring
|
|
1069
|
+
- Task Manager integration
|
|
1070
|
+
- `create_task()`, `get_task_status()`, `suspend_task()`, `resume_task()`, `delete_task()`
|
|
1071
|
+
- Resource monitoring
|
|
1072
|
+
- `get_resource_metrics()` - CPU, memory, database metrics
|
|
1073
|
+
- `check_resource_thresholds()` - Auto-disable/enable logic
|
|
1074
|
+
- `auto_disable_monitoring()` / `auto_enable_monitoring()` - Automatic remediation
|
|
1075
|
+
- `ResourceThresholds` - Configurable thresholds with hysteresis
|
|
1076
|
+
|
|
1077
|
+
#### Documentation
|
|
1078
|
+
- Complete API documentation
|
|
1079
|
+
- `SQL_VS_OBJECTSCRIPT.md` - Critical execution pattern guide
|
|
1080
|
+
- `rag-templates-production-patterns.md` - 7 battle-tested patterns
|
|
1081
|
+
- `CONSTITUTION.md` - 8 core design principles
|
|
1082
|
+
- `ROADMAP.md` - Future features (v1.1.0+)
|
|
1083
|
+
- Integration test examples
|
|
1084
|
+
- Comprehensive docstrings (Google style)
|
|
1085
|
+
|
|
1086
|
+
### Quality Metrics
|
|
1087
|
+
- 224/238 unit tests passing (94%)
|
|
1088
|
+
- 93 contract tests passing (100%)
|
|
1089
|
+
- 29 integration tests passing
|
|
1090
|
+
- 54 integration tests ready (require IRIS container)
|
|
1091
|
+
- 100% docstring coverage
|
|
1092
|
+
- 100% type hint coverage
|
|
1093
|
+
- Medical-grade error messages (Constitutional Principle #5)
|
|
1094
|
+
|
|
1095
|
+
### Constitutional Principles
|
|
1096
|
+
All features follow the [8 core principles](CONSTITUTION.md):
|
|
1097
|
+
1. ✅ Automatic Remediation Over Manual Intervention
|
|
1098
|
+
2. ✅ DBAPI First, JDBC Fallback
|
|
1099
|
+
3. ✅ Isolation by Default
|
|
1100
|
+
4. ✅ Zero Configuration Viable
|
|
1101
|
+
5. ✅ Fail Fast with Guidance
|
|
1102
|
+
6. ✅ Enterprise Ready, Community Friendly
|
|
1103
|
+
7. ✅ Medical-Grade Reliability
|
|
1104
|
+
8. ✅ Document the Blind Alleys
|
|
1105
|
+
|
|
1106
|
+
### Production Patterns Integrated
|
|
1107
|
+
Extracted from `rag-templates` production system:
|
|
1108
|
+
1. Multi-Port Discovery with Fallback
|
|
1109
|
+
2. Docker Container Port Auto-Detection
|
|
1110
|
+
3. Connection Pooling (documented for v1.2.0)
|
|
1111
|
+
4. Automatic Password Reset
|
|
1112
|
+
5. "Out of the Way" Port Mapping
|
|
1113
|
+
6. Schema Reset Utilities
|
|
1114
|
+
7. Retry Logic with Exponential Backoff
|
|
1115
|
+
|
|
1116
|
+
### Breaking Changes
|
|
1117
|
+
N/A - Initial release
|
|
1118
|
+
|
|
1119
|
+
### Deprecated
|
|
1120
|
+
N/A - Initial release
|
|
1121
|
+
|
|
1122
|
+
### Fixed
|
|
1123
|
+
N/A - Initial release
|
|
1124
|
+
|
|
1125
|
+
### Security
|
|
1126
|
+
- SHA256 checksums for .DAT fixture integrity
|
|
1127
|
+
- Secure password handling in connection strings
|
|
1128
|
+
- No credentials in logs or error messages
|
|
1129
|
+
|
|
1130
|
+
---
|
|
1131
|
+
|
|
1132
|
+
## [Unreleased]
|
|
1133
|
+
|
|
1134
|
+
### Planned for v1.1.0
|
|
1135
|
+
- VECTOR datatype introspection via audit trail
|
|
1136
|
+
- Enhanced schema inspector combining INFORMATION_SCHEMA + audit data
|
|
1137
|
+
- SQLAlchemy dialect extension with VECTOR type awareness
|
|
1138
|
+
- Schema reflection with correct VECTOR types
|
|
1139
|
+
|
|
1140
|
+
### Planned for v1.2.0
|
|
1141
|
+
- Production-grade connection pooling implementation
|
|
1142
|
+
- Query performance tracking
|
|
1143
|
+
- Advanced testing utilities
|
|
1144
|
+
- DAT fixture versioning
|
|
1145
|
+
|
|
1146
|
+
### Planned for v2.0.0
|
|
1147
|
+
- Multi-instance support
|
|
1148
|
+
- Mirror configuration support
|
|
1149
|
+
- Enterprise features (sharding, ECP, etc.)
|
|
1150
|
+
|
|
1151
|
+
---
|
|
1152
|
+
|
|
1153
|
+
## Release Notes
|
|
1154
|
+
|
|
1155
|
+
### v1.0.0 Highlights
|
|
1156
|
+
|
|
1157
|
+
**Zero Configuration**: `pip install iris-devtester && pytest` works out of the box.
|
|
1158
|
+
|
|
1159
|
+
**Battle-Tested**: Every feature extracted from production code, representing years of debugging hours saved.
|
|
1160
|
+
|
|
1161
|
+
**Constitutional Compliance**: All 8 design principles followed throughout.
|
|
1162
|
+
|
|
1163
|
+
**Comprehensive Testing**: 94% test coverage with 224 unit tests, 93 contract tests, and 83 integration tests.
|
|
1164
|
+
|
|
1165
|
+
**Production Patterns**: 7 patterns from rag-templates integrated and documented.
|
|
1166
|
+
|
|
1167
|
+
**Documentation**: 1,200+ lines of documentation including critical SQL vs ObjectScript guide.
|
|
1168
|
+
|
|
1169
|
+
---
|
|
1170
|
+
|
|
1171
|
+
**Remember**: Every feature here was paid for with real debugging time. 🚀
|
|
1172
|
+
|
|
1173
|
+
[1.10.1]: https://github.com/intersystems-community/iris-devtester/releases/tag/v1.10.1
|
|
1174
|
+
[1.10.0]: https://github.com/intersystems-community/iris-devtester/releases/tag/v1.10.0
|
|
1175
|
+
[1.9.3]: https://github.com/intersystems-community/iris-devtester/releases/tag/v1.9.3
|
|
1176
|
+
[1.9.2]: https://github.com/intersystems-community/iris-devtester/releases/tag/v1.9.2
|
|
1177
|
+
[1.8.1]: https://github.com/intersystems-community/iris-devtester/releases/tag/v1.8.1
|
|
1178
|
+
[1.5.0]: https://github.com/intersystems-community/iris-devtester/releases/tag/v1.5.0
|
|
1179
|
+
[1.4.5]: https://github.com/intersystems-community/iris-devtester/releases/tag/v1.4.5
|
|
1180
|
+
[1.4.4]: https://github.com/intersystems-community/iris-devtester/releases/tag/v1.4.4
|
|
1181
|
+
[1.4.3]: https://github.com/intersystems-community/iris-devtester/releases/tag/v1.4.3
|
|
1182
|
+
[1.3.0]: https://github.com/intersystems-community/iris-devtester/releases/tag/v1.3.0
|
|
1183
|
+
[1.2.2]: https://github.com/intersystems-community/iris-devtester/releases/tag/v1.2.2
|
|
1184
|
+
[1.2.1]: https://github.com/intersystems-community/iris-devtester/releases/tag/v1.2.1
|
|
1185
|
+
[1.2.0]: https://github.com/intersystems-community/iris-devtester/releases/tag/v1.2.0
|
|
1186
|
+
[1.1.0]: https://github.com/intersystems-community/iris-devtester/releases/tag/v1.1.0
|
|
1187
|
+
[1.0.2]: https://github.com/intersystems-community/iris-devtester/releases/tag/v1.0.2
|
|
1188
|
+
[1.0.0]: https://github.com/intersystems-community/iris-devtester/releases/tag/v1.0.0
|
|
1189
|
+
[Unreleased]: https://github.com/intersystems-community/iris-devtester/compare/v1.10.1...HEAD
|