You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_db_manager.py 8.3 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. import os
  2. import asyncio
  3. import pytest
  4. from sqlmodel import Session, text, select
  5. from typing import Generator
  6. from autogenstudio.database import DatabaseManager
  7. from autogenstudio.datamodel.types import (
  8. ModelConfig, AgentConfig, ToolConfig,
  9. TeamConfig, ModelTypes, AgentTypes, TeamTypes, ComponentTypes,
  10. TerminationConfig, TerminationTypes, ToolTypes
  11. )
  12. from autogenstudio.datamodel.db import Model, Tool, Agent, Team, LinkTypes
  13. @pytest.fixture
  14. def test_db() -> Generator[DatabaseManager, None, None]:
  15. """Fixture for test database"""
  16. db_path = "test.db"
  17. db = DatabaseManager(f"sqlite:///{db_path}")
  18. db.reset_db()
  19. # Initialize database instead of create_db_and_tables
  20. db.initialize_database(auto_upgrade=False)
  21. yield db
  22. # Clean up
  23. asyncio.run(db.close())
  24. db.reset_db()
  25. try:
  26. if os.path.exists(db_path):
  27. os.remove(db_path)
  28. except Exception as e:
  29. print(f"Warning: Failed to remove test database file: {e}")
  30. @pytest.fixture
  31. def test_user() -> str:
  32. return "test_user@example.com"
  33. @pytest.fixture
  34. def sample_model(test_user: str) -> Model:
  35. """Create a sample model with proper config"""
  36. return Model(
  37. user_id=test_user,
  38. config=ModelConfig(
  39. model="gpt-4",
  40. model_type=ModelTypes.OPENAI,
  41. component_type=ComponentTypes.MODEL,
  42. version="1.0.0"
  43. ).model_dump()
  44. )
  45. @pytest.fixture
  46. def sample_tool(test_user: str) -> Tool:
  47. """Create a sample tool with proper config"""
  48. return Tool(
  49. user_id=test_user,
  50. config=ToolConfig(
  51. name="test_tool",
  52. description="A test tool",
  53. content="async def test_func(x: str) -> str:\n return f'Test {x}'",
  54. tool_type=ToolTypes.PYTHON_FUNCTION,
  55. component_type=ComponentTypes.TOOL,
  56. version="1.0.0"
  57. ).model_dump()
  58. )
  59. @pytest.fixture
  60. def sample_agent(test_user: str, sample_model: Model, sample_tool: Tool) -> Agent:
  61. """Create a sample agent with proper config and relationships"""
  62. return Agent(
  63. user_id=test_user,
  64. config=AgentConfig(
  65. name="test_agent",
  66. agent_type=AgentTypes.ASSISTANT,
  67. model_client=ModelConfig.model_validate(sample_model.config),
  68. tools=[ToolConfig.model_validate(sample_tool.config)],
  69. component_type=ComponentTypes.AGENT,
  70. version="1.0.0"
  71. ).model_dump()
  72. )
  73. @pytest.fixture
  74. def sample_team(test_user: str, sample_agent: Agent) -> Team:
  75. """Create a sample team with proper config"""
  76. return Team(
  77. user_id=test_user,
  78. config=TeamConfig(
  79. name="test_team",
  80. participants=[AgentConfig.model_validate(sample_agent.config)],
  81. termination_condition=TerminationConfig(
  82. termination_type=TerminationTypes.STOP_MESSAGE,
  83. component_type=ComponentTypes.TERMINATION,
  84. version="1.0.0"
  85. ).model_dump(),
  86. team_type=TeamTypes.ROUND_ROBIN,
  87. component_type=ComponentTypes.TEAM,
  88. version="1.0.0"
  89. ).model_dump()
  90. )
  91. class TestDatabaseOperations:
  92. def test_basic_setup(self, test_db: DatabaseManager):
  93. """Test basic database setup and connection"""
  94. with Session(test_db.engine) as session:
  95. result = session.exec(text("SELECT 1")).first()
  96. assert result[0] == 1
  97. result = session.exec(select(1)).first()
  98. assert result == 1
  99. def test_basic_entity_creation(self, test_db: DatabaseManager, sample_model: Model,
  100. sample_tool: Tool, sample_agent: Agent, sample_team: Team):
  101. """Test creating all entity types with proper configs"""
  102. with Session(test_db.engine) as session:
  103. # Add all entities
  104. session.add(sample_model)
  105. session.add(sample_tool)
  106. session.add(sample_agent)
  107. session.add(sample_team)
  108. session.commit()
  109. # Store IDs
  110. model_id = sample_model.id
  111. tool_id = sample_tool.id
  112. agent_id = sample_agent.id
  113. team_id = sample_team.id
  114. # Verify all entities were created with new session
  115. with Session(test_db.engine) as session:
  116. assert session.get(Model, model_id) is not None
  117. assert session.get(Tool, tool_id) is not None
  118. assert session.get(Agent, agent_id) is not None
  119. assert session.get(Team, team_id) is not None
  120. def test_multiple_links(self, test_db: DatabaseManager, sample_agent: Agent):
  121. """Test linking multiple models to an agent"""
  122. with Session(test_db.engine) as session:
  123. # Create two models with updated configs
  124. model1 = Model(
  125. user_id="test_user",
  126. config=ModelConfig(
  127. model="gpt-4",
  128. model_type=ModelTypes.OPENAI,
  129. component_type=ComponentTypes.MODEL,
  130. version="1.0.0"
  131. ).model_dump()
  132. )
  133. model2 = Model(
  134. user_id="test_user",
  135. config=ModelConfig(
  136. model="gpt-3.5",
  137. model_type=ModelTypes.OPENAI,
  138. component_type=ComponentTypes.MODEL,
  139. version="1.0.0"
  140. ).model_dump()
  141. )
  142. # Add and commit all entities
  143. session.add(model1)
  144. session.add(model2)
  145. session.add(sample_agent)
  146. session.commit()
  147. model1_id = model1.id
  148. model2_id = model2.id
  149. agent_id = sample_agent.id
  150. # Create links using IDs
  151. test_db.link(LinkTypes.AGENT_MODEL, agent_id, model1_id)
  152. test_db.link(LinkTypes.AGENT_MODEL, agent_id, model2_id)
  153. # Verify links
  154. linked_models = test_db.get_linked_entities(
  155. LinkTypes.AGENT_MODEL, agent_id)
  156. assert len(linked_models.data) == 2
  157. # Verify model names
  158. model_names = [model.config["model"] for model in linked_models.data]
  159. assert "gpt-4" in model_names
  160. assert "gpt-3.5" in model_names
  161. def test_upsert_operations(self, test_db: DatabaseManager, sample_model: Model):
  162. """Test upsert for both create and update scenarios"""
  163. # Test Create
  164. response = test_db.upsert(sample_model)
  165. assert response.status is True
  166. assert "Created Successfully" in response.message
  167. # Test Update
  168. sample_model.config["model"] = "gpt-4-turbo"
  169. response = test_db.upsert(sample_model)
  170. assert response.status is True
  171. assert "Updated Successfully" in response.message
  172. # Verify Update
  173. result = test_db.get(Model, {"id": sample_model.id})
  174. assert result.status is True
  175. assert result.data[0].config["model"] == "gpt-4-turbo"
  176. def test_delete_operations(self, test_db: DatabaseManager, sample_model: Model):
  177. """Test delete with various filters"""
  178. # First insert the model
  179. test_db.upsert(sample_model)
  180. # Test deletion by id
  181. response = test_db.delete(Model, {"id": sample_model.id})
  182. assert response.status is True
  183. assert "Deleted Successfully" in response.message
  184. # Verify deletion
  185. result = test_db.get(Model, {"id": sample_model.id})
  186. assert len(result.data) == 0
  187. # Test deletion with non-existent id
  188. response = test_db.delete(Model, {"id": 999999})
  189. assert "Row not found" in response.message
  190. def test_initialize_database_scenarios(self):
  191. """Test different initialize_database parameters"""
  192. db_path = "test_init.db"
  193. db = DatabaseManager(f"sqlite:///{db_path}")
  194. try:
  195. # Test basic initialization
  196. response = db.initialize_database()
  197. assert response.status is True
  198. # Test with auto_upgrade
  199. response = db.initialize_database(auto_upgrade=True)
  200. assert response.status is True
  201. finally:
  202. asyncio.run(db.close())
  203. db.reset_db()
  204. if os.path.exists(db_path):
  205. os.remove(db_path)