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.4 kB

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