iris-devtester 1.12.0__tar.gz → 1.12.2__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.
Files changed (250) hide show
  1. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/PKG-INFO +1 -1
  2. iris_devtester-1.12.2/docs/learnings/iris-connection-access-denied-bug.md +37 -0
  3. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/__init__.py +1 -1
  4. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/cli/container.py +73 -4
  5. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/config/discovery.py +3 -0
  6. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/containers/iris_container.py +59 -9
  7. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester.egg-info/PKG-INFO +1 -1
  8. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester.egg-info/SOURCES.txt +1 -0
  9. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/pyproject.toml +1 -1
  10. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/AGENTS.md +0 -0
  11. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/CLAUDE.md +0 -0
  12. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/CONSTITUTION.md +0 -0
  13. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/LICENSE +0 -0
  14. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/MANIFEST.in +0 -0
  15. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/README.md +0 -0
  16. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/SKILL.md +0 -0
  17. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/GETTING_STARTED.md +0 -0
  18. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/LANGCHAIN_INTEGRATION_QUICKSTART.md +0 -0
  19. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/ROADMAP.md +0 -0
  20. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/SQL_VS_OBJECTSCRIPT.md +0 -0
  21. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/TROUBLESHOOTING.md +0 -0
  22. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/WHATS_NEW_v1.4.0.md +0 -0
  23. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/archive/AGENTIC_SANDBOX_ENHANCEMENT_REPORT.md +0 -0
  24. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/archive/IMPACT_ANALYSIS.md +0 -0
  25. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/archive/IRIS_DEVTESTER_POSITIONING_REPORT.md +0 -0
  26. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/archive/LANGCHAIN_INTEGRATION_STRATEGY.md +0 -0
  27. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/archive/LANGCHAIN_INTEGRATION_TEST_RESULTS.md +0 -0
  28. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/archive/PHASE_2_PLAN.md +0 -0
  29. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/archive/RAG_TEMPLATES_ANALYSIS.md +0 -0
  30. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/archive/README.md +0 -0
  31. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/archive/STRATEGIC_ROADMAP_SUMMARY.md +0 -0
  32. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/archive/feature-009-refactor-plan.md +0 -0
  33. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/development/BUG_REPORT.md +0 -0
  34. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/development/EXTRACTION_SUMMARY.md +0 -0
  35. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/development/FEATURE_006_SUMMARY.md +0 -0
  36. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/development/PHASE2_RESULTS.md +0 -0
  37. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/development/PRE_PUBLISH_REVIEW.md +0 -0
  38. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/development/PROGRESS.md +0 -0
  39. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/development/PYPI_READINESS.md +0 -0
  40. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/development/SESSION-INTEGRATION-TESTS.md +0 -0
  41. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/development/SESSION-SUMMARY.md +0 -0
  42. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/development/STATUS-002-PIVOTED.md +0 -0
  43. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/development/STATUS-003-COMPLETE.md +0 -0
  44. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/development/STATUS.md +0 -0
  45. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/development/V1_COMPLETION_PLAN.md +0 -0
  46. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/development/V1_RELEASE_SUMMARY.md +0 -0
  47. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/features/WSGI-ASGI-SERVER-SETUP.md +0 -0
  48. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/features/agent-skills.md +0 -0
  49. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/features/dat-fixtures.md +0 -0
  50. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/features/docker-compose.md +0 -0
  51. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/features/performance-monitoring.md +0 -0
  52. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/features/testcontainers.md +0 -0
  53. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/learnings/api-contract-synchronization.md +0 -0
  54. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/learnings/callin-service-requirement.md +0 -0
  55. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/learnings/cpf-merge-and-container-restarts.md +0 -0
  56. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/learnings/dat-fixtures-docker-exec-pattern.md +0 -0
  57. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/learnings/dat-restore-database-isolation-problem.md +0 -0
  58. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/learnings/dbapi-bulk-insert-performance-issue.md +0 -0
  59. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/learnings/dbapi-objectscript-limitation.md +0 -0
  60. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/learnings/dbapi-password-reset-limitation.md +0 -0
  61. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/learnings/dbapi-private-module-myth.md +0 -0
  62. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/learnings/docker-hub-image-naming.md +0 -0
  63. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/learnings/embedded-python-considerations.md +0 -0
  64. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/learnings/feature-002-pivot-summary.md +0 -0
  65. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/learnings/integration-test-dbapi-limitation.md +0 -0
  66. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/learnings/iris-backup-patterns.md +0 -0
  67. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/learnings/iris-container-performance.md +0 -0
  68. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/learnings/iris-container-readiness.md +0 -0
  69. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/learnings/iris-docker-sdk-environment-variables.md +0 -0
  70. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/learnings/iris-performance-monitoring-landscape.md +0 -0
  71. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/learnings/iris-security-users-api.md +0 -0
  72. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/learnings/password-reset-changeflag-fix.md +0 -0
  73. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/learnings/rag-templates-production-patterns.md +0 -0
  74. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/learnings/sql-task-manager-operations.md +0 -0
  75. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/learnings/test-isolation-fix-summary.md +0 -0
  76. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/learnings/test-isolation-investigation.md +0 -0
  77. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/docs/learnings/testcontainers-ryuk-lifecycle.md +0 -0
  78. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/examples/01_quickstart.py +0 -0
  79. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/examples/02_connection_management.py +0 -0
  80. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/examples/04_pytest_fixtures.py +0 -0
  81. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/examples/05_ci_cd.py +0 -0
  82. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/examples/08_auto_discovery.py +0 -0
  83. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/examples/09_enterprise.py +0 -0
  84. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/examples/10_docker_compose_integration.py +0 -0
  85. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/examples/langchain_integration_example.py +0 -0
  86. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/__main__.py +0 -0
  87. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/cli/__init__.py +0 -0
  88. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/cli/__main__.py +0 -0
  89. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/cli/connection_commands.py +0 -0
  90. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/cli/container_commands.py +0 -0
  91. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/cli/dev_commands.py +0 -0
  92. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/cli/fixture_commands.py +0 -0
  93. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/config/__init__.py +0 -0
  94. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/config/auto_discovery.py +0 -0
  95. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/config/container_config.py +0 -0
  96. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/config/container_state.py +0 -0
  97. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/config/defaults.py +0 -0
  98. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/config/models.py +0 -0
  99. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/config/presets.py +0 -0
  100. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/config/yaml_loader.py +0 -0
  101. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/connections/__init__.py +0 -0
  102. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/connections/auto_discovery.py +0 -0
  103. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/connections/connection.py +0 -0
  104. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/connections/dbapi.py +0 -0
  105. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/connections/jdbc.py +0 -0
  106. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/connections/manager.py +0 -0
  107. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/connections/models.py +0 -0
  108. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/connections/retry.py +0 -0
  109. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/containers/__init__.py +0 -0
  110. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/containers/cpf_manager.py +0 -0
  111. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/containers/dev_instance.py +0 -0
  112. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/containers/models.py +0 -0
  113. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/containers/monitor_utils.py +0 -0
  114. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/containers/monitoring.py +0 -0
  115. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/containers/performance.py +0 -0
  116. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/containers/validation.py +0 -0
  117. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/containers/wait_strategies.py +0 -0
  118. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/fixtures/__init__.py +0 -0
  119. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/fixtures/creator.py +0 -0
  120. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/fixtures/loader.py +0 -0
  121. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/fixtures/manifest.py +0 -0
  122. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/fixtures/obj_export.py +0 -0
  123. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/fixtures/validator.py +0 -0
  124. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/integrations/__init__.py +0 -0
  125. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/integrations/langchain.py +0 -0
  126. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/ports/__init__.py +0 -0
  127. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/ports/assignment.py +0 -0
  128. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/ports/exceptions.py +0 -0
  129. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/ports/registry.py +0 -0
  130. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/testing/__init__.py +0 -0
  131. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/testing/fixtures.py +0 -0
  132. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/testing/helpers.py +0 -0
  133. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/testing/models.py +0 -0
  134. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/testing/schema_reset.py +0 -0
  135. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/utils/__init__.py +0 -0
  136. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/utils/container_port.py +0 -0
  137. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/utils/container_status.py +0 -0
  138. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/utils/dbapi_compat.py +0 -0
  139. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/utils/enable_callin.py +0 -0
  140. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/utils/health_checks.py +0 -0
  141. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/utils/iris_container_adapter.py +0 -0
  142. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/utils/namespace.py +0 -0
  143. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/utils/password.py +0 -0
  144. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/utils/progress.py +0 -0
  145. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester/utils/test_connection.py +0 -0
  146. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester.egg-info/dependency_links.txt +0 -0
  147. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester.egg-info/entry_points.txt +0 -0
  148. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester.egg-info/requires.txt +0 -0
  149. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/iris_devtester.egg-info/top_level.txt +0 -0
  150. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/setup.cfg +0 -0
  151. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/__init__.py +0 -0
  152. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/conftest.py +0 -0
  153. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/__init__.py +0 -0
  154. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/cli/test_container_logs_contract.py +0 -0
  155. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/cli/test_container_remove_contract.py +0 -0
  156. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/cli/test_container_restart_contract.py +0 -0
  157. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/cli/test_container_start_contract.py +0 -0
  158. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/cli/test_container_status_contract.py +0 -0
  159. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/cli/test_container_stop_contract.py +0 -0
  160. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/cli/test_container_up_contract.py +0 -0
  161. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/test_agent_skills.py +0 -0
  162. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/test_cli_container_commands.py +0 -0
  163. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/test_cli_fixture_commands.py +0 -0
  164. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/test_connection_api.py +0 -0
  165. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/test_container_api.py +0 -0
  166. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/test_container_integration_contract.py +0 -0
  167. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/test_container_status_api.py +0 -0
  168. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/test_container_validation_api.py +0 -0
  169. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/test_enable_callin_api.py +0 -0
  170. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/test_fixture_creator_api.py +0 -0
  171. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/test_fixture_loader_api.py +0 -0
  172. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/test_fixture_validator_api.py +0 -0
  173. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/test_iriscontainer_attach.py +0 -0
  174. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/test_legacy_package_contract.py +0 -0
  175. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/test_modern_package_contract.py +0 -0
  176. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/test_monitoring_config_api.py +0 -0
  177. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/test_package_detection.py +0 -0
  178. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/test_port_registry_contract.py +0 -0
  179. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/test_preconfig_contract.py +0 -0
  180. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/test_reset_verification_contract.py +0 -0
  181. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/test_resource_monitoring_api.py +0 -0
  182. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/test_retry_logic_contract.py +0 -0
  183. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/test_task_manager_api.py +0 -0
  184. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/test_test_connection_api.py +0 -0
  185. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/contract/test_testing_fixtures_api.py +0 -0
  186. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/e2e/__init__.py +0 -0
  187. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/e2e/test_skill_workflow.py +0 -0
  188. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/__init__.py +0 -0
  189. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/conftest.py +0 -0
  190. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/ports/__init__.py +0 -0
  191. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/ports/test_manual_port_override.py +0 -0
  192. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/ports/test_multi_project_isolation.py +0 -0
  193. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/ports/test_port_exhaustion.py +0 -0
  194. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/ports/test_port_persistence.py +0 -0
  195. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/ports/test_stale_cleanup.py +0 -0
  196. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/test_bug_fixes.py +0 -0
  197. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/test_bug_fixes_011.py +0 -0
  198. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/test_cli_container_integration.py +0 -0
  199. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/test_connection_integration.py +0 -0
  200. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/test_container_health_monitor.py +0 -0
  201. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/test_container_status_integration.py +0 -0
  202. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/test_container_validation.py +0 -0
  203. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/test_cpf_merge.py +0 -0
  204. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/test_cpf_presets.py +0 -0
  205. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/test_cpf_security.py +0 -0
  206. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/test_custom_user_remediation.py +0 -0
  207. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/test_dev_instance.py +0 -0
  208. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/test_enable_callin_integration.py +0 -0
  209. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/test_fixture_export_patterns.py +0 -0
  210. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/test_fixture_performance.py +0 -0
  211. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/test_fixture_refresh.py +0 -0
  212. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/test_fixtures_integration.py +0 -0
  213. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/test_implicit_namespace.py +0 -0
  214. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/test_iriscontainer_attach_integration.py +0 -0
  215. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/test_monitor_utils_integration.py +0 -0
  216. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/test_monitoring_integration.py +0 -0
  217. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/test_password_preconfig_integration.py +0 -0
  218. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/test_password_reset_both_editions.py +0 -0
  219. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/test_password_reset_integration.py +0 -0
  220. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/test_password_reset_macos.py +0 -0
  221. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/test_password_reset_timing.py +0 -0
  222. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/test_password_reset_validation.py +0 -0
  223. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/test_proactive_password_reset.py +0 -0
  224. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/test_real_world_problems.py +0 -0
  225. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/test_reliable_password_reset.py +0 -0
  226. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/integration/test_test_connection_integration.py +0 -0
  227. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/unit/__init__.py +0 -0
  228. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/unit/config/test_config_hierarchy.py +0 -0
  229. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/unit/config/test_container_config.py +0 -0
  230. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/unit/config/test_yaml_loader.py +0 -0
  231. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/unit/test_auto_discovery.py +0 -0
  232. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/unit/test_config_discovery.py +0 -0
  233. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/unit/test_connection_fallback.py +0 -0
  234. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/unit/test_connection_info.py +0 -0
  235. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/unit/test_cpf_manager.py +0 -0
  236. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/unit/test_dev_instance_logic.py +0 -0
  237. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/unit/test_iris_config.py +0 -0
  238. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/unit/test_iris_container.py +0 -0
  239. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/unit/test_manifest.py +0 -0
  240. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/unit/test_monitoring_policy.py +0 -0
  241. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/unit/test_namespace_utils.py +0 -0
  242. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/unit/test_password_preconfig.py +0 -0
  243. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/unit/test_password_preconfig_unit.py +0 -0
  244. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/unit/test_performance_metrics.py +0 -0
  245. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/unit/test_resource_thresholds.py +0 -0
  246. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/unit/test_retry.py +0 -0
  247. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/unit/test_schema_models.py +0 -0
  248. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/unit/test_validation_results.py +0 -0
  249. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/unit/test_wait_strategies.py +0 -0
  250. {iris_devtester-1.12.0 → iris_devtester-1.12.2}/tests/unit/utils/test_iris_container_adapter.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iris-devtester
3
- Version: 1.12.0
3
+ Version: 1.12.2
4
4
  Summary: Battle-tested InterSystems IRIS infrastructure utilities for Python development
5
5
  Author-email: InterSystems Community <community@intersystems.com>
6
6
  Maintainer-email: Thomas Dyar <thomas.dyar@intersystems.com>
@@ -0,0 +1,37 @@
1
+ # Learning: IRIS Connection "Access Denied" / "Invalid Message received"
2
+
3
+ ## Symptoms
4
+ When connecting to an InterSystems IRIS container using `iris.connect` (Python Native SDK / DB-API), the connection fails with:
5
+ ```
6
+ <COMMUNICATION LINK ERROR> Failed to connect to server;
7
+ Details: <COMMUNICATION ERROR> Invalid Message received;
8
+ Details: Access Denied
9
+ ```
10
+ This happens even if the port, username, and password appear correct, and direct connections to `localhost` work.
11
+
12
+ ## Root Cause
13
+ The "Invalid Message received" error is a specific response from the IRIS Superserver when it receives data that does not match the expected wire protocol (e.g., hitting the Superserver port with an HTTP request, or hitting the Web port with a Superserver client).
14
+
15
+ In `iris-devtester`, `IRISContainer.get_config()` was using `get_container_host_ip()` to determine the host. On some platforms or Docker configurations, this can return `0.0.0.0`. While `0.0.0.0` is valid for *listening*, it is often problematic for *connecting* on certain OSs or when IRIS security policies restrict connections to specific interfaces. More importantly, if the discovery logic returned the **Web Port** (52773) instead of the **Superserver Port** (1972) due to misconfiguration or "attached" container inspection errors, the Superserver would reject the "invalid" protocol message.
16
+
17
+ ## Solution
18
+ Sanitize the discovered host and ensure the Superserver port is correctly prioritized over other mapped ports.
19
+
20
+ In `iris_devtester/containers/iris_container.py`:
21
+ ```python
22
+ def get_config(self) -> IRISConfig:
23
+ ...
24
+ discovered_host = self.get_container_host_ip()
25
+ # Sanitize 0.0.0.0 to localhost for client connections
26
+ if discovered_host in ("0.0.0.0", "::"):
27
+ discovered_host = "localhost"
28
+
29
+ self.host = discovered_host
30
+ self._mapped_port = int(self.get_exposed_port(1972))
31
+ ...
32
+ ```
33
+
34
+ ## Prevention
35
+ 1. **Explicit Port Discovery**: Always use the internal port (1972) as the key for `get_exposed_port()` discovery, rather than assuming the first available port.
36
+ 2. **Host Sanitization**: Always translate `0.0.0.0` or `::` to `localhost` for client-side connection strings.
37
+ 3. **Validation**: Validate that `container_name` is never `None` during `attach()` calls to ensure Docker SDK inspection succeeds.
@@ -26,7 +26,7 @@ LangChain Integration:
26
26
  ... # Build your RAG app...
27
27
  """
28
28
 
29
- __version__ = "1.10.3"
29
+ __version__ = "1.12.2"
30
30
  __author__ = "InterSystems Community"
31
31
  __license__ = "MIT"
32
32
 
@@ -80,8 +80,11 @@ def container_group(ctx):
80
80
  "--timeout", type=int, default=60, help="Health check timeout in seconds (default: 60)"
81
81
  )
82
82
  @click.option("--cpf", help="Path to CPF merge file or raw CPF content")
83
+ @click.option(
84
+ "--auto-port", is_flag=True, help="Automatically find and assign free ports via registry"
85
+ )
83
86
  @click.pass_context
84
- def up(ctx, config, name, edition, image, license_key, detach, timeout, cpf):
87
+ def up(ctx, config, name, edition, image, license_key, detach, timeout, cpf, auto_port):
85
88
  """
86
89
  Create and start IRIS container from configuration.
87
90
 
@@ -161,6 +164,37 @@ def up(ctx, config, name, edition, image, license_key, detach, timeout, cpf):
161
164
  container_config.cpf_merge = cpf
162
165
  click.echo(f" → CPF Merge: {cpf[:50]}...")
163
166
 
167
+ # Handle auto-port assignment (Feature 027 - Smart Port Fallback)
168
+ if auto_port:
169
+ from iris_devtester.ports.registry import PortRegistry
170
+
171
+ registry = PortRegistry()
172
+ project_path = str(Path.cwd().absolute())
173
+
174
+ click.echo(f"⏳ Engaging port registry for project: {project_path}")
175
+ # Use current config port as preferred
176
+ preferred = container_config.superserver_port
177
+ assignment = registry.assign_port(project_path, preferred_port=preferred)
178
+
179
+ if assignment.port != preferred:
180
+ click.echo(
181
+ click.style(
182
+ f"⚠️ Port {preferred} was unavailable. Assigned {assignment.port} instead.",
183
+ fg="yellow",
184
+ )
185
+ )
186
+ else:
187
+ click.echo(f"✓ Port {assignment.port} assigned and verified.")
188
+
189
+ container_config.superserver_port = assignment.port
190
+ # Update web port proportionally if it's the default
191
+ if container_config.webserver_port == 52773:
192
+ # Simple logic: if superserver shifted by N, shift webserver by N
193
+ offset = assignment.port - 1972
194
+ if offset > 0:
195
+ container_config.webserver_port = 52773 + offset
196
+ click.echo(f" → Web port adjusted to {container_config.webserver_port}")
197
+
164
198
  # Check if container already exists
165
199
  existing_container = IRISContainerManager.get_existing(container_config.container_name)
166
200
 
@@ -475,8 +509,11 @@ def list_containers(ctx, show_all, output_format):
475
509
  @click.option(
476
510
  "--timeout", type=int, default=60, help="Health check timeout in seconds (default: 60)"
477
511
  )
512
+ @click.option(
513
+ "--auto-port", is_flag=True, help="Automatically find and assign free ports via registry"
514
+ )
478
515
  @click.pass_context
479
- def start(ctx, container_name, config, timeout):
516
+ def start(ctx, container_name, config, timeout, auto_port):
480
517
  """
481
518
  Start existing IRIS container or create new one.
482
519
 
@@ -517,8 +554,40 @@ def start(ctx, container_name, config, timeout):
517
554
  else:
518
555
  container_config = ContainerConfig.default()
519
556
 
520
- # Create and start container using Docker SDK (Feature 011 - T015)
521
- click.echo("⏳ Configuring and starting container with Docker SDK...")
557
+ # Override name
558
+ container_config.container_name = container_name
559
+
560
+ # Handle auto-port assignment (Feature 027 - Smart Port Fallback)
561
+ if auto_port:
562
+ from iris_devtester.ports.registry import PortRegistry
563
+
564
+ registry = PortRegistry()
565
+ project_path = str(Path.cwd().absolute())
566
+
567
+ click.echo(f"⏳ Engaging port registry for project: {project_path}")
568
+ preferred = container_config.superserver_port
569
+ assignment = registry.assign_port(project_path, preferred_port=preferred)
570
+
571
+ if assignment.port != preferred:
572
+ click.echo(
573
+ click.style(
574
+ f"⚠️ Port {preferred} was unavailable. Assigned {assignment.port} instead.",
575
+ fg="yellow",
576
+ )
577
+ )
578
+ else:
579
+ click.echo(f"✓ Port {assignment.port} assigned and verified.")
580
+
581
+ container_config.superserver_port = assignment.port
582
+ # Update web port proportionally if it's the default
583
+ if container_config.webserver_port == 52773:
584
+ offset = assignment.port - 1972
585
+ if offset > 0:
586
+ container_config.webserver_port = 52773 + offset
587
+ click.echo(f" → Web port adjusted to {container_config.webserver_port}")
588
+
589
+ # Create and start container using Docker SDK (Feature 011 - T015)
590
+ click.echo("⏳ Configuring and starting container with Docker SDK...")
522
591
 
523
592
  # Validate volume paths before creation
524
593
  volume_errors = container_config.validate_volume_paths()
@@ -9,6 +9,7 @@ Automatically discovers IRIS configuration from multiple sources:
9
9
  5. Sensible defaults (lowest priority)
10
10
  """
11
11
 
12
+ import logging
12
13
  import os
13
14
  from pathlib import Path
14
15
  from typing import Any, Dict, Optional, Union
@@ -25,6 +26,8 @@ from iris_devtester.config.defaults import (
25
26
  )
26
27
  from iris_devtester.config.models import IRISConfig
27
28
 
29
+ logger = logging.getLogger(__name__)
30
+
28
31
 
29
32
  def discover_config(explicit_config: Optional[IRISConfig] = None) -> IRISConfig:
30
33
  """
@@ -126,7 +126,8 @@ class IRISContainer(IRISBase):
126
126
  project_ns = get_project_namespace()
127
127
  kwargs.setdefault("namespace", project_ns)
128
128
 
129
- return cls.attach(instance.name, **kwargs)
129
+ container_name = str(instance.name) if instance.name else "iris_db"
130
+ return cls.attach(container_name, **kwargs)
130
131
 
131
132
  @classmethod
132
133
  def community(
@@ -245,6 +246,9 @@ class IRISContainer(IRISBase):
245
246
  Returns:
246
247
  An IRISContainer instance attached to the existing container.
247
248
  """
249
+ if not container_name:
250
+ raise ValueError("container_name must be a non-empty string")
251
+
248
252
  instance = cls(image="", name=container_name, **kwargs)
249
253
  instance._is_attached = True
250
254
  instance._container_name = container_name
@@ -268,10 +272,18 @@ class IRISContainer(IRISBase):
268
272
  instance.get_config()
269
273
 
270
274
  except Exception as e:
271
- logger.warning(f"Could not fully inspect container '{container_name}': {e}")
272
- # Fallback to defaults
273
- instance.host = instance.host or "localhost"
274
- instance._mapped_port = instance._mapped_port or 1972
275
+ # For attached containers, we MUST find the container to be useful
276
+ raise ValueError(
277
+ f"Container '{container_name}' not found or not running\n"
278
+ "\n"
279
+ "What went wrong:\n"
280
+ f" {str(e)}\n"
281
+ "\n"
282
+ "How to fix it:\n"
283
+ " 1. Verify the container name is correct: docker ps\n"
284
+ " 2. Ensure the container is started: docker start <name>\n"
285
+ " 3. Check if your user has permission to access the Docker socket"
286
+ )
275
287
 
276
288
  return instance
277
289
 
@@ -455,21 +467,29 @@ class IRISContainer(IRISBase):
455
467
  """
456
468
  # Always create fresh config to pick up any credential changes
457
469
  # (e.g., conftest may update _username/_password after start())
458
- self._config = IRISConfig(
470
+ config = IRISConfig(
459
471
  username=self._username,
460
472
  password=self._password,
461
473
  namespace=self._namespace,
462
474
  container_name=self.get_container_name(),
463
475
  )
464
- config = self._config
476
+ self._config = config
465
477
  try:
466
- # Get host and mapped port from testcontainers
478
+ # Get host and mapped port
467
479
  # IMPORTANT: self.port must remain 1972 (internal port) for get_exposed_port() to work
468
- self.host = self.get_container_host_ip()
480
+
481
+ # Use 'localhost' as default host for local containers
482
+ discovered_host = self.get_container_host_ip()
483
+ if discovered_host in ("0.0.0.0", "::"):
484
+ discovered_host = "localhost"
485
+
486
+ self.host = discovered_host
469
487
  self._mapped_port = int(self.get_exposed_port(1972)) # Use internal port to get mapping
488
+
470
489
  config.host = self.host
471
490
  config.port = self._mapped_port # Config uses the host-mapped port for connections
472
491
  except Exception:
492
+ # If discovery fails, stick with defaults (localhost:1972)
473
493
  pass
474
494
  return config
475
495
 
@@ -527,6 +547,36 @@ class IRISContainer(IRISBase):
527
547
  self._password = password
528
548
  return self
529
549
 
550
+ def reset_password(
551
+ self, username: str = "_SYSTEM", new_password: str = "SYS", timeout: int = 30
552
+ ) -> bool:
553
+ """
554
+ Reset password for a user in this container.
555
+
556
+ Args:
557
+ username: Username to reset
558
+ new_password: New password to set
559
+ timeout: Timeout in seconds
560
+
561
+ Returns:
562
+ True if successful
563
+ """
564
+ from iris_devtester.utils.password import reset_password as reset_func
565
+
566
+ config = self.get_config()
567
+ result = reset_func(
568
+ container_name=self.get_container_name(),
569
+ username=username,
570
+ new_password=new_password,
571
+ timeout=timeout,
572
+ hostname=config.host,
573
+ port=config.port,
574
+ )
575
+ if result.success:
576
+ self._password = new_password
577
+ return True
578
+ return False
579
+
530
580
  def start(self) -> "IRISContainer":
531
581
  """Start container with pre-config support and port registry integration."""
532
582
  if self._preconfigure_password:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iris-devtester
3
- Version: 1.12.0
3
+ Version: 1.12.2
4
4
  Summary: Battle-tested InterSystems IRIS infrastructure utilities for Python development
5
5
  Author-email: InterSystems Community <community@intersystems.com>
6
6
  Maintainer-email: Thomas Dyar <thomas.dyar@intersystems.com>
@@ -56,6 +56,7 @@ docs/learnings/embedded-python-considerations.md
56
56
  docs/learnings/feature-002-pivot-summary.md
57
57
  docs/learnings/integration-test-dbapi-limitation.md
58
58
  docs/learnings/iris-backup-patterns.md
59
+ docs/learnings/iris-connection-access-denied-bug.md
59
60
  docs/learnings/iris-container-performance.md
60
61
  docs/learnings/iris-container-readiness.md
61
62
  docs/learnings/iris-docker-sdk-environment-variables.md
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "iris-devtester"
7
- version = "1.12.0"
7
+ version = "1.12.2"
8
8
  description = "Battle-tested InterSystems IRIS infrastructure utilities for Python development"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
File without changes