diff --git a/tests/unused/integration/a2a/__init__.py b/tests/unused/integration/a2a/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/tests/unused/integration/a2a/test_a2a_streaming.py b/tests/unused/integration/a2a/test_a2a_streaming.py deleted file mode 100644 index 71032a7e679..00000000000 --- a/tests/unused/integration/a2a/test_a2a_streaming.py +++ /dev/null @@ -1,436 +0,0 @@ -#!/usr/bin/env python -import sys -import json -import time -import requests -import uuid -import argparse -import pytest -import os -from typing import Dict, List, Set - -# Default test configuration -DEFAULT_HOST = "0.0.0.0" -DEFAULT_PORT = 10002 -DEFAULT_TIMEOUT = 120 # seconds -DEFAULT_QUERY = "What's the average price for a one bed?" -DEFAULT_AGENT_NAME = "my_agent" # Default agent name to use for requests - -""" -Run instructions: - -start A2A server and mindsdb - -You should have an agent created in MindsDB (this script does NOT create the agent) - -By default the agent is named "my_agent" - -e.g. - -CREATE AGENT my_agent -USING - - model='gemini-2.0-flash', - include_knowledge_bases=['mindsdb.kb_test'], - include_tables=['postgresql_conn.home_rentals', 'postgresql_conn2.car_info'], - prompt_template=' - mindsdb.kb_test knowledge base has info about cities - postgresql_conn.home_rentals database tables has rental data - postgresql_conn2.car_info contains info on cars specs - '; - -source .venv/bin/activate -python test_a2a_streaming.py --host 0.0.0.0 --port 10002 --timeout 180 "What's the average price of homes in berkeley_hills?" -""" - - -def generate_uuid() -> str: - """Generate a random UUID string.""" - return str(uuid.uuid4()).replace("-", "") - - -def stream_a2a_query( - query: str, - host: str = DEFAULT_HOST, - port: int = DEFAULT_PORT, - timeout: int = DEFAULT_TIMEOUT, - verbose: bool = False, - agent_name: str = DEFAULT_AGENT_NAME, # Added agent_name parameter with default -): - """ - Stream a query to the A2A server and yield the responses incrementally. - - Args: - query: The text query to send to the agent - host: A2A server host - port: A2A server port - timeout: Maximum time to wait for responses (seconds) - verbose: Whether to print responses to stdout - agent_name: Name of the agent to use (REQUIRED - the A2A API requires an explicit agent name) - - Yields: - Dict: Response messages from the A2A server - """ - # Generate unique IDs for the request - task_id = generate_uuid() - session_id = generate_uuid() - request_id = generate_uuid() - - # Prepare the request payload - payload = { - "jsonrpc": "2.0", - "id": request_id, - "method": "tasks/sendSubscribe", - "params": { - "id": task_id, - "sessionId": session_id, - "message": { - "role": "user", - "parts": [ - {"type": "text", "text": query}, - ], - "metadata": {"agent_name": agent_name}, # Using the provided agent_name - }, - "acceptedOutputModes": ["text/plain"], - }, - } - - url = f"http://{host}:{port}/a2a" - if verbose: - print(f"Sending streaming request to {url}") - print(f"Query: {query}") - print("Streaming responses:") - print("-" * 60) - - # Set up headers for SSE - headers = { - "Content-Type": "application/json", - "Accept": "text/event-stream", - "Cache-Control": "no-cache", - "Connection": "keep-alive", - } - - # Track seen messages to avoid duplicates - seen_messages: Set[str] = set() - all_responses: List[Dict] = [] - start_time = time.time() - - try: - # Make the streaming request - with requests.post(url, json=payload, headers=headers, stream=True) as response: - if not response.ok: - error_msg = f"Error: HTTP {response.status_code} - {response.text}" - if verbose: - print(error_msg) - yield {"error": error_msg} - return - - # Process the SSE stream - buffer = "" - for chunk in response.iter_content(chunk_size=1): - # Check timeout - if time.time() - start_time > timeout: - error_msg = f"Timeout after {timeout} seconds" - if verbose: - print(error_msg) - yield {"error": error_msg, "timeout": True} - return - - if not chunk: - continue - - # Decode the chunk and add to buffer - buffer += chunk.decode("utf-8") - - # Process complete lines - while "\n" in buffer: - line, buffer = buffer.split("\n", 1) - line = line.rstrip() - - # Skip empty lines - if not line: - continue - - # Process data lines - if line.startswith("data:"): - data_str = line[5:].strip() - if not data_str: - continue - - try: - # Parse the JSON data - data = json.loads(data_str) - - # Extract and display content - if "result" in data: - result = data["result"] - - # Handle status updates - if "status" in result: - message = result["status"].get("message", {}) - parts = message.get("parts", []) - - for part in parts: - # Get content and metadata - content = part.get("text", "") - metadata = part.get("metadata", {}) - thought_type = metadata.get("thought_type", "") - - # Create a unique key for deduplication - message_key = f"{thought_type}:{content}" - - # Skip if we've seen this message before - if message_key in seen_messages: - continue - - # Add to seen messages - seen_messages.add(message_key) - - # Create response object - response_obj = { - "type": thought_type - or part.get("type", "text"), - "content": content, - "metadata": metadata, - } - - # Display based on thought type - if verbose: - if thought_type == "thought": - print(f"Thought: {content}") - elif thought_type == "observation": - print(f"Observation: {content}") - elif thought_type == "sql": - print(f"SQL Query: {content}") - elif part.get("type") == "text": - print(content) - sys.stdout.flush() - - # Yield the response - yield response_obj - all_responses.append(response_obj) - - # Handle artifact updates - if "artifact" in result: - artifact = result["artifact"] - parts = artifact.get("parts", []) - - for part in parts: - content = part.get("text", "") - if content: - response_obj = { - "type": "answer", - "content": content, - } - if verbose: - print(content) - sys.stdout.flush() - yield response_obj - all_responses.append(response_obj) - - # Handle completion - if result.get("final"): - response_obj = {"type": "completion", "final": True} - if verbose: - print("\n[Completed]") - sys.stdout.flush() - yield response_obj - all_responses.append(response_obj) - - # Handle errors - elif "error" in data: - error_msg = data["error"].get("message", "") - response_obj = {"error": error_msg} - if verbose: - print(f"Error: {error_msg}") - sys.stdout.flush() - yield response_obj - all_responses.append(response_obj) - - except json.JSONDecodeError: - if verbose: - print(f"Warning: Invalid JSON: {data_str[:50]}...") - sys.stdout.flush() - - # Process event end - elif line == "": - # Event boundary - process the event - pass - - except KeyboardInterrupt: - if verbose: - print("\nInterrupted by user") - yield {"error": "Interrupted by user"} - except Exception as e: - error_msg = f"Error: {str(e)}" - if verbose: - print(error_msg) - yield {"error": error_msg} - - # Return all collected responses - return all_responses - - -def run_manual_test(): - """Run a manual test with command line arguments.""" - parser = argparse.ArgumentParser( - description="Test A2A streaming with direct requests" - ) - parser.add_argument("--host", default=DEFAULT_HOST, help="A2A server host") - parser.add_argument( - "--port", type=int, default=DEFAULT_PORT, help="A2A server port" - ) - parser.add_argument( - "--timeout", type=int, default=DEFAULT_TIMEOUT, help="Timeout in seconds" - ) - parser.add_argument( - "--agent-name", default=DEFAULT_AGENT_NAME, help="Name of the agent to use" - ) - parser.add_argument( - "query", nargs="?", default=DEFAULT_QUERY, help="Query to send to the agent" - ) - - args = parser.parse_args() - - # Run with verbose output for manual testing - for _ in stream_a2a_query( - args.query, - args.host, - args.port, - args.timeout, - verbose=True, - agent_name=args.agent_name, - ): - pass # Just consume the generator to display output - - -@pytest.mark.integration -def test_a2a_streaming_integration(): - """ - Integration test for A2A streaming functionality. - - This test requires a running A2A server. It can be configured with environment variables: - - A2A_TEST_HOST: A2A server host (default: 0.0.0.0) - - A2A_TEST_PORT: A2A server port (default: 10002) - - A2A_TEST_QUERY: Query to send (default: "What's the average price for a one bed?") - - A2A_TEST_TIMEOUT: Timeout in seconds (default: 120) - - A2A_TEST_AGENT_NAME: Agent name to use (default: my_agent) - - IMPORTANT: You must create the agent in MindsDB before running this test. - """ - # Get configuration from environment variables - host = os.environ.get("A2A_TEST_HOST", DEFAULT_HOST) - port = int(os.environ.get("A2A_TEST_PORT", DEFAULT_PORT)) - query = os.environ.get("A2A_TEST_QUERY", DEFAULT_QUERY) - timeout = int(os.environ.get("A2A_TEST_TIMEOUT", DEFAULT_TIMEOUT)) - agent_name = os.environ.get("A2A_TEST_AGENT_NAME", DEFAULT_AGENT_NAME) - - # Check if we should skip the test - skip_test = os.environ.get("SKIP_A2A_TEST", "false").lower() == "true" - if skip_test: - pytest.skip( - "Skipping A2A test as requested by SKIP_A2A_TEST environment variable" - ) - - # First, check if the agent exists by making a simple request - try: - # Make a simple request to check if the agent exists - url = f"http://{host}:{port}/a2a" - check_payload = { - "jsonrpc": "2.0", - "id": generate_uuid(), - "method": "tasks/send", - "params": { - "id": generate_uuid(), - "sessionId": generate_uuid(), - "message": { - "role": "user", - "parts": [{"type": "text", "text": "test"}], - "metadata": {"agent_name": agent_name}, - }, - }, - } - - response = requests.post(url, json=check_payload, timeout=10) - if response.status_code == 404 or "not found" in response.text.lower(): - pytest.skip( - f"Agent '{agent_name}' not found. Please create the agent before running this test." - ) - except Exception as e: - pytest.skip(f"Error checking if agent exists: {str(e)}") - - # Collect all responses - responses = list( - stream_a2a_query( - query, host, port, timeout, verbose=False, agent_name=agent_name - ) - ) - - # Basic assertions - assert len(responses) > 0, "No responses received from A2A server" - - # Check for error responses, but be more tolerant of task tracking errors and validation errors - errors = [r for r in responses if "error" in r] - - # Identify different types of non-critical errors - task_tracking_errors = [ - e - for e in errors - if "Task" in e.get("error", "") and "not found" in e.get("error", "") - ] - validation_errors = [e for e in errors if "validation error" in e.get("error", "")] - non_critical_errors = task_tracking_errors + validation_errors - - # If all errors are non-critical, we can consider the test passed - if len(errors) > 0 and len(non_critical_errors) == len(errors): - print(f"Ignoring non-critical errors: {non_critical_errors}") - else: - # If there are other types of errors, fail the test - real_errors = [e for e in errors if e not in non_critical_errors] - assert len(real_errors) == 0, f"Errors in responses: {real_errors}" - - # Print response types for debugging - response_types = set(r.get("type", "") for r in responses) - print(f"Response types found: {response_types}") - - # Verify we have different types of responses (thoughts, observations, etc.) - assert len(response_types) > 1, f"Only found response types: {response_types}" - - # Look for any kind of final/completion message - # More flexible approach - check for any of these indicators - final_messages = [ - r - for r in responses - if ( - # Original strict check - (r.get("type") == "completion" and r.get("final")) - or r.get("final") is True - or r.get("type") == "answer" - or ( - r.get("type") == "text" - and r.get("content", "").strip() - and len(r.get("content", "")) > 20 - ) - ) - ] - - print(f"Found {len(final_messages)} potential final/completion messages") - if len(final_messages) == 0: - # Print the last few responses for debugging - print("Last 5 responses for debugging:") - for r in responses[-5:]: - print(f" {r}") - - # More lenient assertion - just check if we got any responses at all - assert len(responses) > 5, "Not enough responses received" - - # Skip the completion check for now as the format may vary - # assert len(final_messages) > 0, "No completion or final message received" - - print(f"✅ Integration test passed with {len(responses)} responses") - return responses - - -if __name__ == "__main__": - # If run directly, use the manual test mode - run_manual_test() diff --git a/tests/unused/integration/flows/test_ml_task_queue.py b/tests/unused/integration/flows/test_ml_task_queue.py deleted file mode 100644 index 8e17fca4d08..00000000000 --- a/tests/unused/integration/flows/test_ml_task_queue.py +++ /dev/null @@ -1,142 +0,0 @@ -import json -import os - -import pytest -from walrus import Database - -from mindsdb.api.executor.data_types.response_type import RESPONSE_TYPE -from mindsdb.utilities.ml_task_queue.const import TASKS_STREAM_NAME - -from tests.integration.utils.http_test_helpers import HTTPHelperMixin -from tests.integration.conftest import HTTP_API_ROOT - -REDIS_HOST = os.environ.get("INTERNAL_URL", "").replace("mindsdb", "redis-master") - - -@pytest.mark.skipif("localhost" in HTTP_API_ROOT or "127.0.0.1" in HTTP_API_ROOT, reason="Requires redis") -class TestMLTaskQueue(HTTPHelperMixin): - - def test_redis_connection(self): - db = Database(protocol=3, host=REDIS_HOST) - db.ping() - - def test_create_model(self, train_finetune_lock): - """ 1. create db connection - 2. create test dataset - 3. start to train model in 'async' mode: check status - 4. start to train model in 'sync' mode: check status - 5. await model 2 is finished - 6. 2 messages in redis stream - """ - - db_details = { - "type": "postgres", - "connection_data": { - "type": "postgres", - "host": "samples.mindsdb.com", - "port": "5432", - "user": "demo_user", - "password": "demo_password", - "database": "demo" - } - } - - self.sql_via_http("DROP MODEL IF EXISTS p_test_queue_async;", RESPONSE_TYPE.OK) - self.sql_via_http("DROP MODEL IF EXISTS p_test_queue_sync;", RESPONSE_TYPE.OK) - - query = f""" - CREATE DATABASE IF NOT EXISTS test_demo_queue - WITH ENGINE = 'postgres', - PARAMETERS = {json.dumps(db_details['connection_data'])}; - """ - self.sql_via_http(query, RESPONSE_TYPE.OK) - - with train_finetune_lock.acquire(timeout=600): - query = """ - create predictor p_test_queue_async - from test_demo_queue (select sqft, location, rental_price from demo_data.home_rentals limit 30) - predict rental_price; - """ - response = self.sql_via_http(query, RESPONSE_TYPE.TABLE) - status = response['data'][0][response['column_names'].index('STATUS')] - assert status in ('generating', 'training') - - query = """ - create predictor p_test_queue_sync - from test_demo_queue (select sqft, location, rental_price from demo_data.home_rentals limit 30) - predict rental_price - USING join_learn_process=true; - """ - response = self.sql_via_http(query, RESPONSE_TYPE.TABLE) - status = response['data'][0][response['column_names'].index('STATUS')] - assert status == 'complete' - - status = self.await_model('p_test_queue_async') - assert status == 'complete' - - db = Database(protocol=3, host=REDIS_HOST) - assert TASKS_STREAM_NAME in db.keys() - - assert db.type(TASKS_STREAM_NAME) == b'stream' - xlen = db.xlen(TASKS_STREAM_NAME) - if xlen != 0: - lol = db.xrange(TASKS_STREAM_NAME) - assert False, "Caught non-zero length ml queue: " + str(lol) - assert db.xlen(TASKS_STREAM_NAME) == 0 - - def test_predict(self): - """ make predict queries to both trained models - """ - - query = """ - SELECT rental_price, - rental_price_explain - FROM mindsdb.p_test_queue_async - WHERE b = 10; - """ - response = self.sql_via_http(query, RESPONSE_TYPE.TABLE) - assert len(response['data']) == 1 - assert len(response['data'][0]) == 2 - - query = """ - SELECT rental_price, - rental_price_explain - FROM test_demo_queue.demo_data.home_rentals - JOIN mindsdb.p_test_queue_async - LIMIT 3; - """ - response = self.sql_via_http(query, RESPONSE_TYPE.TABLE) - assert len(response['data']) == 3 - assert len(response['data'][0]) == 2 - - db = Database(protocol=3, host=REDIS_HOST) - assert db.xlen(TASKS_STREAM_NAME) == 0 - - def test_finetune(self, train_finetune_lock): - """ check that finetune is working - """ - - with train_finetune_lock.acquire(timeout=600): - query = """ - FINETUNE p_test_queue_sync - FROM test_demo_queue (SELECT * FROM demo_data.home_rentals LIMIT 10) - USING join_learn_process=true; - """ - response = self.sql_via_http(query, RESPONSE_TYPE.TABLE) - status = response['data'][0][response['column_names'].index('STATUS')] - assert status == 'complete' - - query = """ - FINETUNE p_test_queue_async - FROM test_demo_queue (SELECT * FROM demo_data.home_rentals LIMIT 10); - """ - response = self.sql_via_http(query, RESPONSE_TYPE.TABLE) - status = response['data'][0][response['column_names'].index('STATUS')] - # FINETUNE in this case may be very fast, so add 'complete' to check - assert status in ('generating', 'training', 'complete') - - status = self.await_model('p_test_queue_async', version_number=2) - assert status == 'complete' - - db = Database(protocol=3, host=REDIS_HOST) - assert db.xlen(TASKS_STREAM_NAME) == 0 diff --git a/tests/unused/integration/knowledge_bases/data/seed.sql b/tests/unused/integration/knowledge_bases/data/seed.sql deleted file mode 100644 index 69fe7847fc2..00000000000 --- a/tests/unused/integration/knowledge_bases/data/seed.sql +++ /dev/null @@ -1,14 +0,0 @@ --- Make sure pgvector extension is enabled -DROP EXTENSION IF EXISTS vector; -CREATE EXTENSION vector; - --- Create the table -CREATE TABLE IF NOT EXISTS items ( - id text PRIMARY KEY, - content text NOT NULL, - embeddings vector NOT NULL, - metadata jsonb -); - --- Dummy data will be handled in tests themselves. Leave it empty. -COMMIT; diff --git a/tests/unused/integration/knowledge_bases/mindsdb_langchain_pgvector_integration_test.py b/tests/unused/integration/knowledge_bases/mindsdb_langchain_pgvector_integration_test.py deleted file mode 100644 index 3a16dac44d0..00000000000 --- a/tests/unused/integration/knowledge_bases/mindsdb_langchain_pgvector_integration_test.py +++ /dev/null @@ -1,64 +0,0 @@ -from mindsdb.integrations.utilities.rag.loaders.vector_store_loader.pgvector import PGVectorMDB -from mindsdb.integrations.handlers.langchain_embedding_handler.fastapi_embeddings import FastAPIEmbeddings - - -def setup_pgvector_database(): - """Setup pgvector database""" - # Using port 15432 to avoid conflicts with local PostgreSQL - connection_string = "postgresql://gateway:gateway@localhost:15432/gateway" - - print(f"Connecting to: {connection_string}") - - # Initialize FastAPI embeddings - embeddings = FastAPIEmbeddings( - api_base="http://localhost:8043/v1/embeddings", - model="sparse_model" - ) - - # Initialize PGVectorMDB - vector_db = PGVectorMDB( - connection_string=connection_string, - collection_name="test_dev_doc_vectors", - embedding_function=embeddings, - is_sparse=True, # Using sparse vectors - vector_size=30522 # Size for sparse vectors - ) - - return vector_db - - -def test_vector_queries(vector_db): - """Test various vector queries""" - print("\nTesting vector queries...") - - # Test text to be embedded - test_text = "For the Bsecondaryl containment" - - # Get embeddings for the test text - embedding = vector_db.embedding_function.embed_query(test_text) - - # Query similar vectors - results = vector_db._query_collection( - embedding=embedding, - k=5 - ) - - print("\nVector similarity search results:") - for item, distance in results: - print(f"Content: {item.content}") - print(f"Metadata: {item.metadata}") - print(f"Distance: {distance}") - print("---") - - -def main(): - # Setup vector database - print("\nSetting up pgvector database...") - vector_db = setup_pgvector_database() - - # Run tests - test_vector_queries(vector_db) - - -if __name__ == "__main__": - main() diff --git a/tests/unused/integration/knowledge_bases/test_knowledge_bases.py b/tests/unused/integration/knowledge_bases/test_knowledge_bases.py deleted file mode 100644 index a43c1a77ce5..00000000000 --- a/tests/unused/integration/knowledge_bases/test_knowledge_bases.py +++ /dev/null @@ -1,337 +0,0 @@ -from http import HTTPStatus -from tempfile import TemporaryDirectory -from time import perf_counter, sleep -from uuid import uuid4 - -import os -import psycopg2 -import pytest - -from mindsdb.api.http.initialize import initialize_app -from mindsdb.migrations import migrate -from mindsdb.interfaces.storage import db -from mindsdb.utilities.config import config - -# Should match table name in data/seed.sql -TEST_TABLE_NAME = 'items' -# Should match column names in data/seed.sql -COLUMN_NAMES = ['id', 'content', 'embeddings', 'metadata'] - -CONNECTION_KWARGS = { - 'connection_data': { - 'host': os.environ.get('MDB_TEST_PGVECTOR_HOST', '127.0.0.1'), - 'port': os.environ.get('MDB_TEST_PGVECTOR_PORT', '5432'), - 'user': os.environ.get('MDB_TEST_PGVECTOR_USER', 'postgres'), - 'password': os.environ.get('MDB_TEST_PGVECTOR_PASSWORD', 'supersecret'), - 'database': None # Different for each test. - } -} - -MODEL_WAIT_DURATION_SECONDS = 5 -MODEL_WAIT_SLEEP_INTERVAL_SECONDS = 0.2 - - -@pytest.fixture(scope="session", autouse=True) -def app(): - old_minds_db_con = '' - if 'MINDSDB_DB_CON' in os.environ: - old_minds_db_con = os.environ['MINDSDB_DB_CON'] - with TemporaryDirectory(prefix='knowledge_bases_integration_test_') as temp_dir: - db_path = 'sqlite:///' + os.path.join(temp_dir, 'mindsdb.sqlite3.db') - # Need to change env variable for migrate module, since it calls db.init(). - os.environ['MINDSDB_DB_CON'] = db_path - db.init() - migrate.migrate_to_head() - config["gui"]["open_on_start"] = False - config["gui"]["autoupdate"] = False - app = initialize_app() - - test_client = app.test_client() - - # Create langchain embedding model to use in all tests. - create_ml_engine_query = 'CREATE ML_ENGINE langchain_embedding FROM langchain_embedding;' - create_ml_engine_data = { - 'query': create_ml_engine_query - } - response = test_client.post('/api/sql/query', json=create_ml_engine_data, follow_redirects=True) - assert '200' in response.status - - # Create model to use in all tests. Use OpenAI for embeddings. - create_query = ''' - CREATE MODEL mindsdb.test_embedding_model - PREDICT embeddings - USING - engine='langchain_embedding', - class = 'OpenAIEmbeddings', - input_columns = ['content']; - ''' - train_data = { - 'query': create_query - } - response = test_client.post('/api/projects/mindsdb/models', json=train_data, follow_redirects=True) - assert '201' in response.status - - # Wait for model to complete. - model_complete = False - model_start_time = perf_counter() - while not model_complete: - if (perf_counter() - model_start_time) > MODEL_WAIT_DURATION_SECONDS: - pytest.fail('Model test_embedding_model did not finish training in time') - response = test_client.get('/api/projects/mindsdb/models/test_embedding_model') - model_status = response.get_json().get('status', 'error') - if model_status == 'complete': - model_complete = True - continue - if model_status == 'error': - pytest.fail('Model test_embedding_model encountered an error while training') - sleep(MODEL_WAIT_SLEEP_INTERVAL_SECONDS) - yield app - os.environ['MINDSDB_DB_CON'] = old_minds_db_con - - -@pytest.fixture() -def client(app): - return app.test_client() - - -def init_db(): - '''Initialize a new DB for every test.''' - conn_info = CONNECTION_KWARGS['connection_data'].copy() - conn_info['database'] = 'postgres' - db = psycopg2.connect(**conn_info) - db.autocommit = True - cursor = db.cursor() - - try: - new_db_name = f'test_pgvector_{uuid4().hex}' - # Create the test database if it does not exist. - cursor.execute(f'DROP DATABASE IF EXISTS {new_db_name}') - db.commit() - cursor.execute(f'CREATE DATABASE {new_db_name};') - db.commit() - - # Reconnect to the new database - conn_info['database'] = new_db_name - db = psycopg2.connect(**conn_info) - db.autocommit = True - cursor = db.cursor() - - # Seed the database with data - curr_dir = os.path.dirname(os.path.realpath(__file__)) - seed_sql_path = os.path.join(curr_dir, 'data', 'seed.sql') - with open(seed_sql_path, 'r') as sql_seed_file: - cursor.execute(sql_seed_file.read()) - db.commit() - - finally: - # Close the cursor and the connection - cursor.close() - db.close() - - return new_db_name - - -@pytest.fixture(autouse=True) -def pgvector_database_name(client): - # Initialize a fresh DB for each test. - new_db_name = init_db() - # Connect new DB to MindsDB. - conn_info = CONNECTION_KWARGS['connection_data'].copy() - conn_info['database'] = new_db_name - example_db_data = { - 'database': { - 'name': new_db_name, - 'engine': 'pgvector', - 'parameters': conn_info - } - } - response = client.post('/api/databases', json=example_db_data, follow_redirects=True) - assert '201' in response.status - return new_db_name - - -@pytest.mark.skipif(os.environ.get('MDB_TEST_PGVECTOR_HOST') is None, reason='MDB_TEST_PGVECTOR_HOST environment variable not set') -@pytest.mark.skipif(os.environ.get('OPENAI_API_KEY') is None, reason='OPENAI_API_KEY environment variable not set') -class TestKnowledgeBaseCompletion: - def test_chat_completion(self, client, pgvector_database_name): - test_kb_name = 'test_chat_completion_kb' - create_request = { - 'knowledge_base': { - 'name': test_kb_name, - 'model': 'test_embedding_model', - 'storage': { - 'table': TEST_TABLE_NAME, - 'database': pgvector_database_name - } - } - } - create_kb_response = client.post('/api/projects/mindsdb/knowledge_bases', json=create_request, follow_redirects=True) - assert create_kb_response.status_code == HTTPStatus.CREATED - - # Insert documents to help answer the question. - rows_to_insert = [ - {'content': 'The capital of Tyler Fantasy RAG Land is MindsDB'} - ] - update_request = { - 'knowledge_base': { - 'rows': rows_to_insert - } - } - update_kb_response = client.put(f'/api/projects/mindsdb/knowledge_bases/{test_kb_name}', - json=update_request, follow_redirects=True) - assert update_kb_response.status_code == HTTPStatus.OK - - completion_request = { - 'query': 'What is the capital of Tyler Fantasy RAG Land?', - 'llm_model': 'gpt-4o' - } - response = client.post(f'/api/projects/mindsdb/knowledge_bases/{test_kb_name}/completions', - json=completion_request, follow_redirects=True) - assert response.status_code == HTTPStatus.OK - response_data = response.get_json() - assert 'message' in response_data - assert 'content' in response_data['message'] - assert 'context' in response_data['message'] - assert response_data['message']['role'] == 'assistant' - # Should get the right answer. - assert 'mindsdb' in response_data['message']['content'].lower() - - def test_context_completion_with_keywords(self, client, pgvector_database_name): - test_kb_name = 'test_context_completion_with_keywords' - create_request = { - 'knowledge_base': { - 'name': test_kb_name, - 'model': 'test_embedding_model', - 'storage': { - 'table': TEST_TABLE_NAME, - 'database': pgvector_database_name - } - } - } - create_kb_response = client.post('/api/projects/mindsdb/knowledge_bases', json=create_request, follow_redirects=True) - assert create_kb_response.status_code == HTTPStatus.CREATED - - # Insert documents for context. - rows_to_insert = [ - {'content': 'The capital of Tyler Fantasy RAG Land is MindsDB'}, - {'content': 'The population of Tyler Fantasy RAG Land is 6'} - ] - update_request = { - 'knowledge_base': { - 'rows': rows_to_insert - } - } - update_kb_response = client.put(f'/api/projects/mindsdb/knowledge_bases/{test_kb_name}', - json=update_request, follow_redirects=True) - assert update_kb_response.status_code == HTTPStatus.OK - - completion_request = { - 'query': 'Population of rag land', - 'keywords': 'population rag land', - 'type': 'context' - } - response = client.post(f'/api/projects/mindsdb/knowledge_bases/{test_kb_name}/completions', - json=completion_request, follow_redirects=True) - assert response.status_code == HTTPStatus.OK - response_data = response.get_json() - # Should have the most relevant document first. - assert 'documents' in response_data - assert len(response_data['documents']) == 2 - assert 'population' in response_data['documents'][0]['content'] - - def test_context_completion_with_metadata(self, client, pgvector_database_name): - test_kb_name = 'test_context_completion_with_metadata' - create_request = { - 'knowledge_base': { - 'name': test_kb_name, - 'model': 'test_embedding_model', - 'storage': { - 'table': TEST_TABLE_NAME, - 'database': pgvector_database_name - } - } - } - create_kb_response = client.post('/api/projects/mindsdb/knowledge_bases', json=create_request, follow_redirects=True) - assert create_kb_response.status_code == HTTPStatus.CREATED - - # Insert documents for context. - rows_to_insert = [ - {'content': 'The capital of Tyler Fantasy RAG Land is MindsDB', 'author': 'Danya'}, - {'content': 'The population of Tyler Fantasy RAG Land is 6', 'author': 'Tyler'}, - {'content': 'Totally unrelated', 'author': 'Tyler'} - - ] - update_request = { - 'knowledge_base': { - 'rows': rows_to_insert - } - } - update_kb_response = client.put(f'/api/projects/mindsdb/knowledge_bases/{test_kb_name}', - json=update_request, follow_redirects=True) - assert update_kb_response.status_code == HTTPStatus.OK - - completion_request = { - 'query': 'Population of rag land', - 'metadata': { - 'author': 'Tyler' - }, - 'type': 'context' - } - response = client.post(f'/api/projects/mindsdb/knowledge_bases/{test_kb_name}/completions', - json=completion_request, follow_redirects=True) - assert response.status_code == HTTPStatus.OK - response_data = response.get_json() - assert 'documents' in response_data - # Only 2 have matching metadata. - assert len(response_data['documents']) == 2 - # Should have the most relevant document first. - assert 'population' in response_data['documents'][0]['content'] - - def test_context_completion_with_keywords_and_metadata(self, client, pgvector_database_name): - test_kb_name = 'test_context_completion_with_keywords_and_metadata' - create_request = { - 'knowledge_base': { - 'name': test_kb_name, - 'model': 'test_embedding_model', - 'storage': { - 'table': TEST_TABLE_NAME, - 'database': pgvector_database_name - } - } - } - create_kb_response = client.post('/api/projects/mindsdb/knowledge_bases', json=create_request, follow_redirects=True) - assert create_kb_response.status_code == HTTPStatus.CREATED - - # Insert documents for context. - rows_to_insert = [ - {'content': 'The capital of Tyler Fantasy RAG Land is MindsDB', 'author': 'Danya'}, - {'content': 'The population of Tyler Fantasy RAG Land is 6', 'author': 'Tyler'}, - {'content': 'Totally unrelated', 'author': 'Tyler'} - - ] - update_request = { - 'knowledge_base': { - 'rows': rows_to_insert - } - } - update_kb_response = client.put(f'/api/projects/mindsdb/knowledge_bases/{test_kb_name}', - json=update_request, follow_redirects=True) - assert update_kb_response.status_code == HTTPStatus.OK - - completion_request = { - 'query': 'Population of rag land', - 'metadata': { - 'author': 'Tyler' - }, - 'keywords': 'rag land population', - 'type': 'context' - } - response = client.post(f'/api/projects/mindsdb/knowledge_bases/{test_kb_name}/completions', - json=completion_request, follow_redirects=True) - assert response.status_code == HTTPStatus.OK - response_data = response.get_json() - assert 'documents' in response_data - # Only 2 have matching metadata. - assert len(response_data['documents']) == 2 - # Should have the most relevant document first. - assert 'population' in response_data['documents'][0]['content'] diff --git a/tests/unused/integration/metrics/test_metrics.py b/tests/unused/integration/metrics/test_metrics.py deleted file mode 100644 index 970b592d834..00000000000 --- a/tests/unused/integration/metrics/test_metrics.py +++ /dev/null @@ -1,68 +0,0 @@ -import datetime -import os -import pytest -import requests -import time -from typing import Dict - -from tests.integration.utils.http_test_helpers import HTTPHelperMixin -from tests.integration.conftest import HTTP_API_ROOT - - -def _get_metrics(): - url = HTTP_API_ROOT.rstrip("api") + "metrics" - print(f"Getting metrics from {url}") - resp = requests.get(url).text - print(f"Metrics response: {resp}") - return resp - - -def _wait_for_metric(name: str, labels: Dict[str, str], timeout: datetime.timedelta = None): - if timeout is None: - timeout = datetime.timedelta(seconds=30) - start_time = datetime.datetime.now() - while datetime.datetime.now() - start_time < timeout: - metrics = _get_metrics() - for metrics_line in metrics.split('\n'): - if name not in metrics_line: - continue - # Check labels match metric. - found = True - for label_name, label_value in labels.items(): - if f'{label_name}="{label_value}"' not in metrics_line: - found = False - break - if found: - print(f"Found metric: {metrics_line}") - metrics_value = metrics_line.split()[-1] - return float(metrics_value) - time.sleep(0.5) - return -1 - - -class TestMetrics(HTTPHelperMixin): - @pytest.mark.skipif(("localhost" in HTTP_API_ROOT or "127.0.0.1" in HTTP_API_ROOT) and os.getenv('PROMETHEUS_MULTIPROC_DIR') is None, reason="PROMETHEUS_MULTIPROC_DIR environment variable is not set") - def test_http_metrics(self): - # Make an HTTP request and check for updated metrics. - api_metric_labels = { - 'endpoint': '/util/ping_native', - 'method': 'GET', - 'status': '200' - } - - before_metric = _wait_for_metric( - 'mindsdb_rest_api_latency_seconds_count', - api_metric_labels, - ) - print(f"Before metric: {before_metric}") - _ = self.api_request('get', '/util/ping_native') - assert _wait_for_metric( - 'mindsdb_rest_api_latency_seconds_count', - api_metric_labels, - ) == before_metric + 1 - # Check multiproc dir is populated. - multiproc_dir = os.getenv('PROMETHEUS_MULTIPROC_DIR') - # We can't check this dir if we're running against a remote env. - if multiproc_dir is not None: - assert os.path.isdir(multiproc_dir) - assert len(os.listdir(os.getenv('PROMETHEUS_MULTIPROC_DIR'))) > 0 diff --git a/tests/unused/integration/rag/test_rag_search_kwargs.py b/tests/unused/integration/rag/test_rag_search_kwargs.py deleted file mode 100644 index 7ee668790fd..00000000000 --- a/tests/unused/integration/rag/test_rag_search_kwargs.py +++ /dev/null @@ -1,271 +0,0 @@ -import os -import uuid -import pytest -from unittest.mock import Mock, patch -from langchain_openai import ChatOpenAI, OpenAIEmbeddings -from langchain_core.documents import Document -from langchain.vectorstores.base import VectorStore -import tempfile -import shutil -from langchain_community.vectorstores import Chroma -from langchain_text_splitters import RecursiveCharacterTextSplitter - -from mindsdb.integrations.utilities.rag.settings import ( - RAGPipelineModel, - RetrieverType, - SearchKwargs, - SearchType, - MultiVectorRetrieverMode, - DEFAULT_LLM_MODEL, - DEFAULT_LLM_ENDPOINT -) -from mindsdb.integrations.utilities.rag.pipelines.rag import LangChainRAGPipeline - -requires_openai = pytest.mark.skipif( - not os.getenv("OPENAI_API_KEY"), - reason="OPENAI_API_KEY environment variable not set" -) - - -@pytest.fixture -def chat_llm(): - api_key = os.getenv("OPENAI_API_KEY") - if not api_key: - pytest.skip("OPENAI_API_KEY environment variable not set") - return ChatOpenAI( - model=DEFAULT_LLM_MODEL, - openai_api_base=DEFAULT_LLM_ENDPOINT, - api_key=api_key - ) - - -@pytest.fixture -def embeddings(): - api_key = os.getenv("OPENAI_API_KEY") - if not api_key: - pytest.skip("OPENAI_API_KEY environment variable not set") - return OpenAIEmbeddings(api_key=api_key) - - -class MockVectorStore(VectorStore): - def add_texts(self, *args, **kwargs): - pass - - def similarity_search(self, *args, **kwargs): - pass - - def as_retriever(self, **kwargs): - return Mock() - - -@pytest.fixture -def sample_documents(): - return [ - Document(page_content="Test document 1", metadata={"source": "test1"}), - Document(page_content="Test document 2", metadata={"source": "test2"}) - ] - - -@pytest.fixture -def vector_store_path(): - temp_dir = tempfile.mkdtemp() - yield temp_dir - shutil.rmtree(temp_dir) - - -@pytest.fixture -def vector_store(embeddings, vector_store_path): - return Chroma( - embedding_function=embeddings, - persist_directory=vector_store_path - ) - - -@pytest.fixture -def base_config(sample_documents, chat_llm, embeddings, vector_store): - return RAGPipelineModel( - documents=sample_documents, - vector_store=vector_store, - embedding_model=embeddings, - llm=chat_llm - ) - - -class TestRAGSearchKwargs: - @pytest.fixture(autouse=True) - def setup(self, base_config, sample_documents, chat_llm, embeddings, vector_store): - """Setup test configuration with fixtures""" - self.base_config = base_config - self.sample_documents = sample_documents - self.chat_llm = chat_llm - self.embeddings = embeddings - self.vector_store = vector_store - self.base_dict = { - 'documents': self.sample_documents, - 'vector_store': self.vector_store, - 'embedding_model': self.embeddings, - 'llm': self.chat_llm - } - - @requires_openai - def test_vector_store_retriever_search_kwargs(self): - config = RAGPipelineModel( - **self.base_dict, - search_type=SearchType.SIMILARITY_SCORE_THRESHOLD, - search_kwargs=SearchKwargs( - k=3, - score_threshold=0.5 - ), - retriever_type=RetrieverType.VECTOR_STORE - ) - mock_retriever = Mock() - mock_retriever.search_kwargs = {"k": 3, "score_threshold": 0.5} - with patch('mindsdb.integrations.utilities.rag.vector_store.VectorStoreOperator') as mock_vs_op: - mock_vs_op.return_value.vector_store.as_retriever.return_value = mock_retriever - _ = LangChainRAGPipeline.from_retriever(config) - assert mock_retriever.search_kwargs == {"k": 3, "score_threshold": 0.5} - - def test_auto_retriever_search_kwargs(self): - config = RAGPipelineModel( - **self.base_dict, - search_type=SearchType.MMR, - search_kwargs=SearchKwargs( - k=2, - fetch_k=4, - lambda_mult=0.7 - ), - retriever_type=RetrieverType.AUTO - ) - mock_retriever = Mock() - mock_retriever.search_kwargs = {"k": 2, "fetch_k": 4, "lambda_mult": 0.7} - mock_llm_response = Mock() - mock_llm_response.content = '[{"name": "source", "description": "Source field", "type": "string"}]' - with patch('mindsdb.integrations.utilities.rag.retrievers.auto_retriever.AutoRetriever') as MockAutoRetriever, \ - patch('langchain_openai.chat_models.ChatOpenAI.invoke', return_value=mock_llm_response): - mock_auto = Mock() - mock_auto.as_runnable.return_value = mock_retriever - MockAutoRetriever.return_value = mock_auto - _ = LangChainRAGPipeline.from_auto_retriever(config) - assert mock_retriever.search_kwargs == {"k": 2, "fetch_k": 4, "lambda_mult": 0.7} - - def test_search_kwargs_validation(self): - """Test the validation rules for SearchKwargs""" - # Test fetch_k validation for MMR search type - with pytest.raises(ValueError, match="fetch_k must be greater than k"): - RAGPipelineModel( - **self.base_dict, - search_type=SearchType.MMR, - search_kwargs=SearchKwargs( - k=5, - fetch_k=3, - lambda_mult=0.7 - ) - ) - - # Test MMR parameter requirements - with pytest.raises(ValueError, match="lambda_mult is required when using fetch_k"): - RAGPipelineModel( - **self.base_dict, - search_type=SearchType.MMR, - search_kwargs=SearchKwargs( - k=3, - fetch_k=5 - ) - ) - - with pytest.raises(ValueError, match="fetch_k is required when using lambda_mult"): - RAGPipelineModel( - **self.base_dict, - search_type=SearchType.MMR, - search_kwargs=SearchKwargs( - k=3, - lambda_mult=0.7 - ) - ) - - # Test score_threshold requirement for SIMILARITY_SCORE_THRESHOLD - with pytest.raises(ValueError, match="score_threshold is required"): - RAGPipelineModel( - **self.base_dict, - search_type=SearchType.SIMILARITY_SCORE_THRESHOLD, - search_kwargs=SearchKwargs( - k=3 - ) - ) - - def test_search_type_compatibility(self): - """Test that search kwargs match the search type""" - # Test MMR search configuration - config = RAGPipelineModel( - **self.base_dict, - search_type=SearchType.MMR, - search_kwargs=SearchKwargs( - k=3, - fetch_k=6, - lambda_mult=0.7 - ) - ) - assert config.search_kwargs.fetch_k == 6 - assert config.search_kwargs.lambda_mult == 0.7 - - # Test similarity_score_threshold configuration - config = RAGPipelineModel( - **self.base_dict, - search_type=SearchType.SIMILARITY_SCORE_THRESHOLD, - search_kwargs=SearchKwargs( - k=3, - score_threshold=0.5 - ) - ) - assert config.search_kwargs.score_threshold == 0.5 - - # Test basic similarity configuration - config = RAGPipelineModel( - **self.base_dict, - search_type=SearchType.SIMILARITY, - search_kwargs=SearchKwargs( - k=3, - filter={"source": "test1"} - ) - ) - assert config.search_kwargs.filter == {"source": "test1"} - - def test_multi_vector_retriever_search_kwargs(self): - """Test search kwargs for multi vector retriever""" - config = RAGPipelineModel( - **self.base_dict, - search_type=SearchType.SIMILARITY, - search_kwargs=SearchKwargs( - k=5, - filter={"source": "test1"} - ), - retriever_type=RetrieverType.MULTI, - multi_retriever_mode=MultiVectorRetrieverMode.BOTH - ) - - mock_retriever = Mock() - mock_retriever.search_kwargs = {"k": 5, "filter": {"source": "test1"}} - - with patch('mindsdb.integrations.utilities.rag.pipelines.rag.MultiVectorRetriever') as MockMultiRetrieverClass: - class MockMultiRetriever: - def __init__(self, config): - self.text_splitter = RecursiveCharacterTextSplitter( - chunk_size=config.chunk_size, - chunk_overlap=config.chunk_overlap - ) - self.documents = config.documents - self.config = config - - def as_runnable(self): - return mock_retriever - - def _split_documents(self): - return [], [] - - def _generate_id_and_split_document(self, doc): - return str(uuid.uuid4()), [doc] - - MockMultiRetrieverClass.side_effect = MockMultiRetriever - - _ = LangChainRAGPipeline.from_multi_vector_retriever(config) - assert mock_retriever.search_kwargs == {"k": 5, "filter": {"source": "test1"}} diff --git a/tests/unused/integrations/utilities/rag/rerankers/test_openai_reranker.py b/tests/unused/integrations/utilities/rag/rerankers/test_openai_reranker.py deleted file mode 100644 index 7b0c5cafa91..00000000000 --- a/tests/unused/integrations/utilities/rag/rerankers/test_openai_reranker.py +++ /dev/null @@ -1,47 +0,0 @@ -from langchain.schema import Document -import pytest - -from mindsdb.integrations.utilities.rag.rerankers.reranker_compressor import LLMReranker -from mindsdb.integrations.utilities.rag.settings import RerankerConfig - - -@pytest.mark.asyncio -async def test_openai_reranker(): - openai_reranker = LLMReranker() - results = await openai_reranker.compress_documents( - documents=[Document(page_content="Jack declared that he likes cats more than dogs"), - Document(page_content="Jack declared that he likes AI")], - query="Jack's opinion on animals", - ) - assert len(results) == 1 - assert "cats" in results[0].page_content - - -@pytest.mark.asyncio -async def test_openai_reranker_diff_threshold(): - openai_reranker = LLMReranker(filtering_threshold=0.6) - assert openai_reranker.filtering_threshold == 0.6 - results = await openai_reranker.compress_documents( - documents=[Document(page_content="Jack declared that he likes cats more than dogs"), - Document(page_content="Jack declared that he likes AI")], - query="Jack's opinion on animals", - ) - assert len(results) == 1 - assert "cats" in results[0].page_content - assert openai_reranker.filtering_threshold == 0.6 - - -@pytest.mark.asyncio -async def test_openai_reranker_config(): - config = RerankerConfig(filtering_threshold=0.6, model="gpt-3.5-turbo", base_url="https://api.openai.com/v1") - openai_reranker = LLMReranker(filtering_threshold=config.filtering_threshold, model=config.model, - base_url=config.base_url) - assert openai_reranker.filtering_threshold == 0.6 - results = await openai_reranker.compress_documents( - documents=[Document(page_content="Jack declared that he likes cats more than dogs"), - Document(page_content="Jack declared that he likes AI")], - query="Jack's opinion on animals", - ) - assert len(results) == 1 - assert "cats" in results[0].page_content - assert openai_reranker.filtering_threshold == 0.6 diff --git a/tests/unused/integrations/utilities/rag/retrievers/test_multi_hop_retriever.py b/tests/unused/integrations/utilities/rag/retrievers/test_multi_hop_retriever.py deleted file mode 100644 index 9cbb199f966..00000000000 --- a/tests/unused/integrations/utilities/rag/retrievers/test_multi_hop_retriever.py +++ /dev/null @@ -1,127 +0,0 @@ -from typing import List, Any, Optional - -import pytest -from langchain_core.documents import Document -from langchain_core.retrievers import BaseRetriever -from langchain_core.language_models import BaseChatModel -from langchain_core.messages import BaseMessage - -from mindsdb.integrations.utilities.rag.retrievers import MultiHopRetriever - - -# Simple template for testing -TEST_TEMPLATE = """Question: {question} -Context: {context} -Generate follow-up questions:""" - - -class MockRetriever(BaseRetriever): - """Simple mock retriever that returns predefined documents""" - def _get_relevant_documents(self, query: str, **kwargs) -> List[Document]: - if "Wright brothers" in query: - return [Document(page_content="The Wright brothers invented the airplane.")] - if "World War 1" in query: - return [Document(page_content="Airplanes were used extensively in WWI.")] - return [] - - -class MockLLM(BaseChatModel): - """Simple mock LLM that returns predefined responses""" - @property - def _llm_type(self) -> str: - return "mock" - - def _generate(self, messages: List[BaseMessage], stop: Optional[List[str]] = None, run_manager: Optional[Any] = None, **kwargs) -> Any: - raise NotImplementedError("Not needed for tests") - - def invoke(self, input_str: str, **kwargs) -> str: - if "Wright brothers" in str(input_str): - return '["How were airplanes used in World War 1?"]' - return "[]" - - -class InvalidOutputLLM(BaseChatModel): - """Mock LLM that always returns invalid JSON""" - @property - def _llm_type(self) -> str: - return "mock" - - def _generate(self, messages: List[BaseMessage], stop: Optional[List[str]] = None, run_manager: Optional[Any] = None, **kwargs) -> Any: - raise NotImplementedError("Not needed for tests") - - def invoke(self, input_str: str, **kwargs) -> str: - return "invalid json" - - -@pytest.fixture -def mock_retriever(): - return MockRetriever() - - -@pytest.fixture -def mock_llm(): - return MockLLM() - - -def test_multi_hop_retriever_basic_functionality(mock_retriever, mock_llm): - """Test the basic functionality of MultiHopRetriever""" - retriever = MultiHopRetriever( - base_retriever=mock_retriever, - llm=mock_llm, - max_hops=2, - reformulation_template=TEST_TEMPLATE - ) - - # Test with a query that should trigger follow-up - docs = retriever._get_relevant_documents("Tell me about the Wright brothers") - - # Should have documents from both queries - assert len(docs) == 2 - assert any("Wright brothers" in doc.page_content for doc in docs) - assert any("WWI" in doc.page_content for doc in docs) - - -def test_multi_hop_retriever_no_results(mock_retriever, mock_llm): - """Test behavior when no documents are found""" - retriever = MultiHopRetriever( - base_retriever=mock_retriever, - llm=mock_llm, - max_hops=2, - reformulation_template=TEST_TEMPLATE - ) - - # Test with a query that won't find any documents - docs = retriever._get_relevant_documents("Something unrelated") - - # Should have no documents - assert len(docs) == 0 - - -def test_multi_hop_retriever_invalid_llm_output(mock_retriever): - """Test handling of invalid LLM output""" - retriever = MultiHopRetriever( - base_retriever=mock_retriever, - llm=InvalidOutputLLM(), - max_hops=2, - reformulation_template=TEST_TEMPLATE - ) - - # Should still work and return initial results - docs = retriever._get_relevant_documents("Tell me about the Wright brothers") - assert len(docs) == 1 - assert "Wright brothers" in docs[0].page_content - - -def test_multi_hop_retriever_max_hops(mock_retriever, mock_llm): - """Test that max_hops is respected""" - retriever = MultiHopRetriever( - base_retriever=mock_retriever, - llm=mock_llm, - max_hops=1, # Only allow 1 hop - reformulation_template=TEST_TEMPLATE - ) - - # Should only get initial documents - docs = retriever._get_relevant_documents("Tell me about the Wright brothers") - assert len(docs) == 1 - assert "Wright brothers" in docs[0].page_content diff --git a/tests/unused/integrations/utilities/rag/test_file_loader.py b/tests/unused/integrations/utilities/rag/test_file_loader.py deleted file mode 100644 index 092ca0936f2..00000000000 --- a/tests/unused/integrations/utilities/rag/test_file_loader.py +++ /dev/null @@ -1,41 +0,0 @@ -from mindsdb.integrations.utilities.rag.loaders.file_loader import FileLoader - - -def test_load_pdf(): - loader = FileLoader('./tests/data/test.pdf') - docs = loader.load() - # Each page is a doc. - assert len(docs) == 3 - assert 'THE CASE FOR MACHINE LEARNING' in docs[0].page_content - assert 'INTRODUCTION' in docs[1].page_content - assert 'THE CASE FOR \nDEMOCRATIZING \nMACHINE LEARNING' in docs[2].page_content - - -def test_load_csv(): - loader = FileLoader('./tests/data/movies.csv') - docs = loader.load() - # Each row is a doc. - assert len(docs) == 10 - assert 'Toy Story' in docs[0].page_content - assert 'GoldenEye' in docs[9].page_content - - -def test_load_html(): - loader = FileLoader('./tests/data/test.html') - docs = loader.load() - assert len(docs) == 1 - assert 'Some intro text about Foo' in docs[0].page_content - - -def test_load_md(): - loader = FileLoader('./mindsdb/integrations/handlers/langchain_handler/README.md') - docs = loader.load() - assert len(docs) == 1 - assert 'This documentation describes the integration of MindsDB with LangChain' in docs[0].page_content - - -def test_load_text(): - loader = FileLoader('./tests/data/test.txt') - docs = loader.load() - assert len(docs) == 1 - assert 'This is a test plaintext file' in docs[0].page_content diff --git a/tests/unused/integrations/utilities/rag/test_file_splitter.py b/tests/unused/integrations/utilities/rag/test_file_splitter.py deleted file mode 100644 index ce757284b4b..00000000000 --- a/tests/unused/integrations/utilities/rag/test_file_splitter.py +++ /dev/null @@ -1,164 +0,0 @@ -from unittest.mock import patch - -from langchain_core.documents import Document -from langchain_text_splitters import MarkdownHeaderTextSplitter, HTMLHeaderTextSplitter, RecursiveCharacterTextSplitter -from mindsdb.integrations.utilities.rag.splitters.file_splitter import FileSplitter, FileSplitterConfig - - -def test_split_documents_pdf(): - pdf_doc = Document( - page_content='This is a test PDF file. Let us try to do some splitting!', - metadata={'extension': '.pdf'} - ) - recursive_splitter = RecursiveCharacterTextSplitter() - file_splitter = FileSplitter(FileSplitterConfig( - recursive_splitter=recursive_splitter - )) - split_pdf_docs = file_splitter.split_documents([pdf_doc]) - assert len(split_pdf_docs) > 0 - - -def test_split_documents_md(): - md_content = ''' - # Unit Testing for Dummies - This MD document covers how to write basic unit tests. - ## Introduction - Unit testing helps ensure code works as expected and prevents regressions. Time to dive in! - ## How to Write Tests - To be continued! -''' - md_doc = Document( - page_content=md_content, - metadata={'extension': '.md'} - ) - headers_to_split_on = [ - ('#', 'Header 1'), - ('##', 'Header 2'), - ] - md_text_splitter = MarkdownHeaderTextSplitter(headers_to_split_on=headers_to_split_on) - file_splitter = FileSplitter(FileSplitterConfig( - markdown_splitter=md_text_splitter - )) - split_md_docs = file_splitter.split_documents([md_doc]) - assert len(split_md_docs) == 3 - # Check we actually split on headers. - assert 'This MD document covers how to write basic unit tests.' in split_md_docs[0].page_content - assert 'Unit testing helps ensure code works as expected and prevents regressions. Time to dive in!' in split_md_docs[1].page_content - assert 'To be continued!' in split_md_docs[2].page_content - - -def test_split_documents_html(): - html_content = ''' - - -
-Some intro text about Foo.
-Some intro text about Bar.
-Some text about the first subtopic of Bar.
-Some text about the second subtopic of Bar.
-Some text about Baz
-Some concluding text about Foo
-Hello, World!
", - "Hello, World!
", - "Hello, World!", - ], - "from_field": ["", "", ""], - "id": ["", "", ""], - "to_field": ["", "", ""], - "subject": ["", "", ""], - } - ) - - self.emails_table_instance.handler.connection.search_email = MagicMock(return_value=mock_df) - - query = parse_sql("SELECT * FROM emails limit 1") - - self.emails_table_instance.select(query) - - assert self.emails_table_instance.handler.connection.search_email.called, ( - "The search_email method must be called." - ) - - # select using invalid column should raise Exception - query = parse_sql("SELECT invalid_column FROM emails limit 1") - - with pytest.raises(Exception): - self.emails_table_instance.select(query) - - def test_insert(self): - """ - Test the insert method of EmailsTable Class - """ - - self.emails_table_instance.handler.connection.send_email = MagicMock() - - query = parse_sql( - "INSERT INTO email_datasource.emails(to_field, subject, body) " - 'VALUES ("toemail@email.com", "MindsDB", "Hello from MindsDB!")' - ) - - self.emails_table_instance.insert(query) - assert self.emails_table_instance.handler.connection.send_email.called, "The send_email method must be called." - - # insert using invalid column should raise Exception - query = parse_sql( - "INSERT INTO email_datasource.emails(to_field, subject, body, invalid_column) " - 'VALUES ("toemail@email.com", "MindsDB", "blaha" , "invalid")' - ) - - with pytest.raises(Exception): - self.emails_table_instance.insert(query) - - def test_get_columns(self): - """ - Test the get_columns method of EmailsTable Class - """ - - columns = self.emails_table_instance.get_columns() - assert isinstance(columns, list), "The returned value must be a list." - assert "id" in columns, "Column 'id' must be in the columns list." - assert "body" in columns, "Column 'body' must be in the columns list." - assert "subject" in columns, "Column 'subject' must be in the columns list." - assert "to_field" in columns, "Column 'to_field' must be in the columns list." - assert "from_field" in columns, "Column 'from_field' must be in the columns list." - assert "datetime" in columns, "Column 'datetime' must be in the columns list." - - def test_undetectable_encoding_handling(self): - """ - Test that the email handler can process emails with undetectable encodings - without raising exceptions. - """ - - undetectable_content = b"\x80\x81\x82\x83\x84\x85\x86\x87" - mock_df = pd.DataFrame( - { - "date": ["Wed, 02 Feb 2022 15:30:00 +0000"], - "body_content_type": ["text"], - "body": [undetectable_content], - "from_field": ["test@example.com"], - "id": ["test1"], - "to_field": ["recipient@example.com"], - "subject": ["Test email with undetectable encoding"], - } - ) - - self.emails_table_instance.handler.connection.search_email = MagicMock(return_value=mock_df) - query = parse_sql("SELECT * FROM emails limit 1") - result = self.emails_table_instance.select(query) - - assert result is not None, "The result must not be None." - assert "body" in result.columns, "The body should be in the result columns." - assert len(result) > 0, "The result should not be empty." diff --git a/tests/unused/unit/handler_tests/test_eventbrite_handler.py b/tests/unused/unit/handler_tests/test_eventbrite_handler.py deleted file mode 100644 index b07e3f09cdd..00000000000 --- a/tests/unused/unit/handler_tests/test_eventbrite_handler.py +++ /dev/null @@ -1,405 +0,0 @@ -from mindsdb.integrations.handlers.eventbrite_handler.eventbrite_handler import ( - EventbriteHandler, -) - -from mindsdb.integrations.handlers.eventbrite_handler.eventbrite_handler import ( - CategoryInfoTable, - EventDetailsTable, -) - -from mindsdb_sql_parser import ast -from mindsdb_sql_parser.ast.select.identifier import Identifier - -from unittest.mock import Mock - -import pandas as pd -import unittest - - -class CategoryInfoTableTest(unittest.TestCase): - def test_get_columns_returns_all_columns(self): - api_handler = Mock(EventbriteHandler) - trades_table = CategoryInfoTable(api_handler) - # Order matters. - expected_columns = [ - "resource_uri", - "id", - "name", - "name_localized", - "short_name", - "short_name_localized", - ] - self.assertListEqual(trades_table.get_columns(), expected_columns) - - def test_select_returns_some_columns(self): - api_handler = Mock() - api_handler.api.list_categories.return_value = pd.DataFrame( - { - "locale": "en_US", - "categories": [ - { - "resource_uri": "https://www.eventbriteapi.com/v3/categories/103/", - "id": "103", - "name": "Music", - "name_localized": "Music", - "short_name": "Music", - "short_name_localized": "Music", - }, - { - "resource_uri": "https://www.eventbriteapi.com/v3/categories/101/", - "id": "101", - "name": "Business & Professional", - "name_localized": "Business & Professional", - "short_name": "Business", - "short_name_localized": "Business", - }, - { - "resource_uri": "https://www.eventbriteapi.com/v3/categories/110/", - "id": "110", - "name": "Food & Drink", - "name_localized": "Food & Drink", - "short_name": "Food & Drink", - "short_name_localized": "Food & Drink", - }, - { - "resource_uri": "https://www.eventbriteapi.com/v3/categories/113/", - "id": "113", - "name": "Community & Culture", - "name_localized": "Community & Culture", - "short_name": "Community", - "short_name_localized": "Community", - }, - { - "resource_uri": "https://www.eventbriteapi.com/v3/categories/105/", - "id": "105", - "name": "Performing & Visual Arts", - "name_localized": "Performing & Visual Arts", - "short_name": "Arts", - "short_name_localized": "Arts", - }, - { - "resource_uri": "https://www.eventbriteapi.com/v3/categories/104/", - "id": "104", - "name": "Film, Media & Entertainment", - "name_localized": "Film, Media & Entertainment", - "short_name": "Film & Media", - "short_name_localized": "Film & Media", - }, - { - "resource_uri": "https://www.eventbriteapi.com/v3/categories/108/", - "id": "108", - "name": "Sports & Fitness", - "name_localized": "Sports & Fitness", - "short_name": "Sports & Fitness", - "short_name_localized": "Sports & Fitness", - }, - { - "resource_uri": "https://www.eventbriteapi.com/v3/categories/107/", - "id": "107", - "name": "Health & Wellness", - "name_localized": "Health & Wellness", - "short_name": "Health", - "short_name_localized": "Health", - }, - { - "resource_uri": "https://www.eventbriteapi.com/v3/categories/102/", - "id": "102", - "name": "Science & Technology", - "name_localized": "Science & Technology", - "short_name": "Science & Tech", - "short_name_localized": "Science & Tech", - }, - { - "resource_uri": "https://www.eventbriteapi.com/v3/categories/109/", - "id": "109", - "name": "Travel & Outdoor", - "name_localized": "Travel & Outdoor", - "short_name": "Travel & Outdoor", - "short_name_localized": "Travel & Outdoor", - }, - { - "resource_uri": "https://www.eventbriteapi.com/v3/categories/111/", - "id": "111", - "name": "Charity & Causes", - "name_localized": "Charity & Causes", - "short_name": "Charity & Causes", - "short_name_localized": "Charity & Causes", - }, - { - "resource_uri": "https://www.eventbriteapi.com/v3/categories/114/", - "id": "114", - "name": "Religion & Spirituality", - "name_localized": "Religion & Spirituality", - "short_name": "Spirituality", - "short_name_localized": "Spirituality", - }, - { - "resource_uri": "https://www.eventbriteapi.com/v3/categories/115/", - "id": "115", - "name": "Family & Education", - "name_localized": "Family & Education", - "short_name": "Family & Education", - "short_name_localized": "Family & Education", - }, - { - "resource_uri": "https://www.eventbriteapi.com/v3/categories/116/", - "id": "116", - "name": "Seasonal & Holiday", - "name_localized": "Seasonal & Holiday", - "short_name": "Holiday", - "short_name_localized": "Holiday", - }, - { - "resource_uri": "https://www.eventbriteapi.com/v3/categories/112/", - "id": "112", - "name": "Government & Politics", - "name_localized": "Government & Politics", - "short_name": "Government", - "short_name_localized": "Government", - }, - { - "resource_uri": "https://www.eventbriteapi.com/v3/categories/106/", - "id": "106", - "name": "Fashion & Beauty", - "name_localized": "Fashion & Beauty", - "short_name": "Fashion", - "short_name_localized": "Fashion", - }, - { - "resource_uri": "https://www.eventbriteapi.com/v3/categories/117/", - "id": "117", - "name": "Home & Lifestyle", - "name_localized": "Home & Lifestyle", - "short_name": "Home & Lifestyle", - "short_name_localized": "Home & Lifestyle", - }, - { - "resource_uri": "https://www.eventbriteapi.com/v3/categories/118/", - "id": "118", - "name": "Auto, Boat & Air", - "name_localized": "Auto, Boat & Air", - "short_name": "Auto, Boat & Air", - "short_name_localized": "Auto, Boat & Air", - }, - { - "resource_uri": "https://www.eventbriteapi.com/v3/categories/119/", - "id": "119", - "name": "Hobbies & Special Interest", - "name_localized": "Hobbies & Special Interest", - "short_name": "Hobbies", - "short_name_localized": "Hobbies", - }, - { - "resource_uri": "https://www.eventbriteapi.com/v3/categories/199/", - "id": "199", - "name": "Other", - "name_localized": "Other", - "short_name": "Other", - "short_name_localized": "Other", - }, - { - "resource_uri": "https://www.eventbriteapi.com/v3/categories/120/", - "id": "120", - "name": "School Activities", - "name_localized": "School Activities", - "short_name": "School Activities", - "short_name_localized": "School Activities", - }, - ], - } - ) - eventbrite_table = CategoryInfoTable(api_handler) - - resource_uri_identifier = Identifier(path_str="resource_uri") - id_identifier = Identifier(path_str="id") - name_identifier = Identifier(path_str="name") - name_localized_identifier = Identifier(path_str="name_localized") - - select_all = ast.Select( - targets=[ - resource_uri_identifier, - id_identifier, - name_identifier, - name_localized_identifier, - ], - from_table="categoryInfoTable", - ) - - all_category_data = eventbrite_table.select(select_all) - - self.assertEqual(all_category_data.shape[0], 20) - self.assertEqual(all_category_data.shape[1], 4) - - -class EventDetailsTableTest(unittest.TestCase): - def test_get_columns_returns_all_columns(self): - api_handler = Mock(EventbriteHandler) - trades_table = EventDetailsTable(api_handler) - # Order matters. - expected_columns = [ - "name_text", - "name_html", - "description_text", - "description_html", - "url", - "start_timezone", - "start_local", - "start_utc", - "end_timezone", - "end_local", - "end_utc", - "organization_id", - "created", - "changed", - "published", - "capacity", - "capacity_is_custom", - "status", - "currency", - "listed", - "shareable", - "online_event", - "tx_time_limit", - "hide_start_date", - "hide_end_date", - "locale", - "is_locked", - "privacy_setting", - "is_series", - "is_series_parent", - "inventory_type", - "is_reserved_seating", - "show_pick_a_seat", - "show_seatmap_thumbnail", - "show_colors_in_seatmap_thumbnail", - "source", - "is_free", - "version", - "summary", - "facebook_event_id", - "logo_id", - "organizer_id", - "venue_id", - "category_id", - "subcategory_id", - "format_id", - "id", - "resource_uri", - "is_externally_ticketed", - "logo_crop_mask", - "logo_original", - "logo_id", - "logo_url", - "logo_aspect_ratio", - "logo_edge_color", - "logo_edge_color_set", - ] - self.assertListEqual(trades_table.get_columns(), expected_columns) - - def test_select_returns_some_columns(self): - api_handler = Mock() - api_handler.api.get_event.return_value = pd.DataFrame( - { - "name": { - "text": "AI Forum: Can AI Fix Climate Change?", - "html": "AI Forum: Can AI Fix Climate Change?", - }, - "description": { - "text": "The third in a series of lunchtime presentations by King's researchers at Science Gallery London", - "html": "The third in a series of lunchtime presentations by King's researchers at Science Gallery London", - }, - "url": "https://www.eventbrite.co.uk/e/ai-forum-can-ai-fix-climate-change-tickets-717926867587", - "start": { - "timezone": "Europe/London", - "local": "2023-11-01T13:15:00", - "utc": "2023-11-01T13:15:00Z", - }, - "end": { - "timezone": "Europe/London", - "local": "2023-11-01T14:00:00", - "utc": "2023-11-01T14:00:00Z", - }, - "organization_id": "112948679745", - "created": "2023-09-12T15:38:12Z", - "changed": "2023-10-11T20:01:50Z", - "published": "2023-09-12T15:44:26Z", - "capacity": None, - "capacity_is_custom": None, - "status": "live", - "currency": "GBP", - "listed": True, - "shareable": True, - "online_event": False, - "tx_time_limit": 1200, - "hide_start_date": False, - "hide_end_date": False, - "locale": "en_GB", - "is_locked": False, - "privacy_setting": "unlocked", - "is_series": False, - "is_series_parent": False, - "inventory_type": "limited", - "is_reserved_seating": False, - "show_pick_a_seat": False, - "show_seatmap_thumbnail": False, - "show_colors_in_seatmap_thumbnail": False, - "source": "coyote", - "is_free": True, - "version": None, - "summary": "The third in a series of lunchtime presentations by King's researchers at Science Gallery London", - "facebook_event_id": None, - "logo_id": "596060689", - "organizer_id": "7201076133", - "venue_id": "173614819", - "category_id": "102", - "subcategory_id": None, - "format_id": "2", - "id": "717926867587", - "resource_uri": "https://www.eventbriteapi.com/v3/events/717926867587/", - "is_externally_ticketed": False, - "logo": { - "crop_mask": { - "top_left": {"x": 0, "y": 0}, - "width": 2160, - "height": 1080, - }, - "original": { - "url": "https://img.evbuc.com/https%3A%2F%2Fcdn.evbuc.com%2Fimages%2F596060689%2F112948679745%2F1%2Foriginal.20230912-154003?auto=format%2Ccompress&q=75&sharp=10&s=0bb5e81d009275e956f98c418a9a3025", - "width": 2160, - "height": 1080, - }, - "id": "596060689", - "url": "https://img.evbuc.com/https%3A%2F%2Fcdn.evbuc.com%2Fimages%2F596060689%2F112948679745%2F1%2Foriginal.20230912-154003?h=200&w=450&auto=format%2Ccompress&q=75&sharp=10&rect=0%2C0%2C2160%2C1080&s=282ef80475d468edff954cb243435432", - "aspect_ratio": "2", - "edge_color": "#d6b4be", - "edge_color_set": True, - }, - } - ) - eventbrite_table = EventDetailsTable(api_handler) - - name_text_identifier = Identifier(path_str="name_text") - description_text_identifier = Identifier(path_str="description_text") - url_identifier = Identifier(path_str="url") - - select_all = ast.Select( - targets=[name_text_identifier, description_text_identifier, url_identifier], - from_table="eventDetailsTable", - where='locationId = "717926867587"', - ) - - review_data = eventbrite_table.select(select_all) - first_data = review_data.iloc[0] - - self.assertEqual(review_data.shape[1], 3) - self.assertEqual( - first_data["name_text"], "AI Forum: Can AI Fix Climate Change?" - ) - self.assertEqual( - first_data["description_text"], - "The third in a series of lunchtime presentations by King's researchers at Science Gallery London", - ) - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/unused/unit/handler_tests/test_gmail_handler.py b/tests/unused/unit/handler_tests/test_gmail_handler.py deleted file mode 100644 index 7e8fe86758d..00000000000 --- a/tests/unused/unit/handler_tests/test_gmail_handler.py +++ /dev/null @@ -1,240 +0,0 @@ -from mindsdb.api.executor.data_types.response_type import RESPONSE_TYPE -from mindsdb.integrations.handlers.gmail_handler.gmail_handler import GmailHandler -from mindsdb.integrations.handlers.gmail_handler.gmail_handler import EmailsTable -from google.oauth2.credentials import Credentials -from mindsdb_sql_parser import parse_sql -import unittest -from unittest.mock import Mock, patch -from unittest import mock - - -class GmailHandlerTest(unittest.TestCase): - def setUp(self) -> None: - self.credentials_file = 'test1_credentials.json' - self.credentials_url = 's3://your-bucket/test_credentials.json' - self.handler = GmailHandler(connection_data={ - 'credentials_file': self.credentials_file, - 'credentials_url': self.credentials_url - }) - - @patch('mindsdb.integrations.handlers.gmail_handler.gmail_handler.requests.get') # Patching the requests.get method - def test_has_creds_file_with_valid_s3_link(self, mock_get): - # Configure the mock behavior - mock_response = mock_get.return_value - mock_response.status_code = 200 - mock_response.text = 'Mocked credentials file content' - - result = self.handler._has_creds_file(self.credentials_file) - # Assert that the requests.get method was called with the correct URL - mock_get.assert_called_once_with(self.credentials_url) - # Assert that the method returns True - self.assertTrue(result) - - @patch('mindsdb.integrations.handlers.gmail_handler.gmail_handler.requests.get') # Patching the requests.get method - def test_has_creds_file_with_invalid_s3_link(self, mock_get): - # Test when invalid S3 credentials file is provided - mock_response = mock.Mock() - mock_response.status_code = 404 - mock_get.return_value = mock_response - - # TODO this will be broken now that we don't use global loggers anymore - with patch('mindsdb.utilities.log.logger') as mock_logger: - result = self.handler._has_creds_file(self.credentials_file) - # Assert that the requests.get method was called with the correct URL - self.assertFalse(result) - # Assert that the error message is logged - mock_logger.error.assert_called_once_with("Failed to get credentials from S3", 404) - - def test_create_connection_with_mocked_token(self): - with mock.patch('google.oauth2.credentials.Credentials.from_authorized_user_file') as mock_credentials: - mock_credentials.return_value = Credentials('token.json') - with mock.patch('os.path.isfile') as mock_isfile: - mock_isfile.return_value = True - result = self.handler.create_connection() - self.assertIsNotNone(result) - - def test_create_connection_with_mocked_credentials_file(self): - with mock.patch('google.oauth2.credentials.Credentials.from_authorized_user_file') as mock_credentials: - mock_credentials.is_valid.return_value = False - with mock.patch('os.path.isfile') as mock_isfile: - mock_isfile.return_value = True - result = self.handler.create_connection() - self.assertIsNotNone(result) - - def test_create_connection_with_mocked_credentials_file_and_s3(self): - with mock.patch('google.oauth2.credentials.Credentials.from_authorized_user_file') as mock_credentials: - mock_credentials.is_valid.return_value = False - with mock.patch('os.path.isfile') as mock_isfile: - mock_isfile.return_value = True - with mock.patch( - 'mindsdb.integrations.handlers.gmail_handler.gmail_handler.GmailHandler._has_creds_file') \ - as mock_has_creds_file: - mock_has_creds_file.return_value = True - result = self.handler.create_connection() - self.assertIsNotNone(result) - - def test_parse_parts_with_multipart_mime_type(self): - email_parts = [ - { - 'mimeType': 'multipart/mixed', - 'parts': [ - { - 'mimeType': 'multipart/alternative', - 'parts': [ - { - 'mimeType': 'text/plain', - 'body': { - 'data': 'VGhpcyBpcyB0aGUgcGxhaW4gdGV4dCBib2R5IG9mIHRoZSBlbWFpbC4=' - } - }, - { - 'mimeType': 'text/html', - 'body': { - 'data': 'PGh0bWw+CiAgICA8Ym9keT4KICAgICAgPHA+V' - 'GhpcyBpcyB0aGUgSFRNTCBib2R5IG9mIHRoZSBlbWFpbC4' - 'gPC9wPgogICAgPC9ib2R5PjwvaHRtbD4=' - } - } - ] - }, - { - 'mimeType': 'application/pdf', - 'filename': 'example.pdf', - 'body': { - 'attachmentId': '<New gifts in store for the jolly season
' - WHERE id = {_id};''' - self.assertTrue(self.handler.native_query(query=query)) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/unused/unit/handler_tests/test_lightdash_handler.py b/tests/unused/unit/handler_tests/test_lightdash_handler.py deleted file mode 100644 index 84cba655bd4..00000000000 --- a/tests/unused/unit/handler_tests/test_lightdash_handler.py +++ /dev/null @@ -1,146 +0,0 @@ -import importlib -import os - -import pytest -from mindsdb_sql_parser import parse_sql - -from ..unit.executor_test_base import BaseExecutorTest - -try: - importlib.import_module("requests") - REQUESTS_INSTALLED = True -except ImportError: - REQUESTS_INSTALLED = False - - -@pytest.mark.skipif(not REQUESTS_INSTALLED, reason="requests package is not installed") -class TestLightdashHandler(BaseExecutorTest): - - def run_sql(self, sql): - ret = self.command_executor.execute_command(parse_sql(sql)) - assert ret.error_code is None - if ret.data is not None: - return ret.data.to_df() - - def setup_method(self): - super().setup_method() - self.api_key = os.environ.get("LIGHTDASH_API_KEY") - self.base_url = os.environ.get("LIGHTDASH_BASE_URL") - self.project_uuid = os.environ.get("LIGHTDASH_PROJECT_UUID") - self.space_uuid = os.environ.get("LIGHTDASH_SPACE_UUID") - self.chart_uuid = os.environ.get("LIGHTDASH_CHART_UUID") - self.chart_version_uuid = os.environ.get("LIGHTDASH_CHART_VERSION_UUID") - self.scheduler_uuid = os.environ.get("LIGHTDASH_SCHEDULER_UUID") - self.job_id = os.environ.get("LIGHTDASH_JOB_ID") - self.run_sql(f""" - CREATE DATABASE lightdash_datasource - WITH ENGINE = "lightdash", - PARAMETERS = {{ - "api_key": '{self.api_key}', - "base_url": '{self.base_url}' - }}; - """) - - def test_basic_select_from(self): - sql = """ - SELECT * FROM lightdash_datasource.user; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM lightdash_datasource.user_ability; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM lightdash_datasource.org; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM lightdash_datasource.org_projects; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM lightdash_datasource.org_members; - """ - self.run_sql(sql) - sql = f""" - SELECT * FROM lightdash_datasource.project_table WHERE project_uuid='{self.project_uuid}'; - """ - self.run_sql(sql) - sql = f""" - SELECT * FROM lightdash_datasource.warehouse_connection WHERE project_uuid='{self.project_uuid}'; - """ - self.run_sql(sql) - sql = f""" - SELECT * FROM lightdash_datasource.dbt_connection WHERE project_uuid='{self.project_uuid}'; - """ - self.run_sql(sql) - sql = f""" - SELECT * FROM lightdash_datasource.dbt_env_vars WHERE project_uuid='{self.project_uuid}'; - """ - self.run_sql(sql) - sql = f""" - SELECT * FROM lightdash_datasource.charts WHERE project_uuid='{self.project_uuid}'; - """ - self.run_sql(sql) - sql = f""" - SELECT * FROM lightdash_datasource.spaces WHERE project_uuid='{self.project_uuid}'; - """ - self.run_sql(sql) - sql = f""" - SELECT * FROM lightdash_datasource.access WHERE project_uuid='{self.project_uuid}'; - """ - self.run_sql(sql) - sql = f""" - SELECT * FROM lightdash_datasource.validation WHERE project_uuid='{self.project_uuid}'; - """ - self.run_sql(sql) - sql = f""" - SELECT * FROM lightdash_datasource.dashboards WHERE project_uuid='{self.project_uuid}' AND space_uuid='{self.space_uuid}'; - """ - self.run_sql(sql) - sql = f""" - SELECT * FROM lightdash_datasource.queries WHERE project_uuid='{self.project_uuid}' AND space_uuid='{self.space_uuid}'; - """ - self.run_sql(sql) - sql = f""" - SELECT * FROM lightdash_datasource.chart_history WHERE chart_uuid='{self.chart_uuid}'; - """ - self.run_sql(sql) - sql = f""" - SELECT * FROM lightdash_datasource.chart_config WHERE chart_uuid='{self.chart_uuid}' AND version_uuid='{self.chart_version_uuid}'; - """ - self.run_sql(sql) - sql = f""" - SELECT * FROM lightdash_datasource.chart_additional_metrics WHERE chart_uuid='{self.chart_uuid}' AND version_uuid='{self.chart_version_uuid}'; - """ - self.run_sql(sql) - sql = f""" - SELECT * FROM lightdash_datasource.chart_table_calculations WHERE chart_uuid='{self.chart_uuid}' AND version_uuid='{self.chart_version_uuid}'; - """ - self.run_sql(sql) - sql = f""" - SELECT * FROM lightdash_datasource.scheduler_logs WHERE project_uuid='{self.project_uuid}'; - """ - self.run_sql(sql) - sql = f""" - SELECT * FROM lightdash_datasource.scheduler WHERE scheduler_uuid='{self.scheduler_uuid}'; - """ - self.run_sql(sql) - sql = f""" - SELECT * FROM lightdash_datasource.scheduler_jobs WHERE scheduler_uuid='{self.scheduler_uuid}'; - """ - self.run_sql(sql) - sql = f""" - SELECT * FROM lightdash_datasource.scheduler_job_status WHERE job_id='{self.job_id}'; - """ - self.run_sql(sql) - - def test_complex_select(self): - sql = """ - SELECT firstName, lastName FROM lightdash_datasource.user; - """ - assert self.run_sql(sql).shape[1] == 2 - sql = f""" - SELECT name FROM lightdash_datasource.project_table WHERE project_uuid='{self.project_uuid}'; - """ - assert self.run_sql(sql).shape[1] == 1 diff --git a/tests/unused/unit/handler_tests/test_luma_handler.py b/tests/unused/unit/handler_tests/test_luma_handler.py deleted file mode 100644 index 9bf31289dc9..00000000000 --- a/tests/unused/unit/handler_tests/test_luma_handler.py +++ /dev/null @@ -1,40 +0,0 @@ -import importlib -import os -import pytest -from mindsdb_sql_parser import parse_sql - -from ..unit.executor_test_base import BaseExecutorTest - -try: - importlib.import_module("requests") - REQUESTS_INSTALLED = True -except ImportError: - REQUESTS_INSTALLED = False - - -@pytest.mark.skipif(not REQUESTS_INSTALLED, reason="requests package is not installed") -class TestLumaHandler(BaseExecutorTest): - - def run_sql(self, sql): - ret = self.command_executor.execute_command(parse_sql(sql)) - assert ret.error_code is None - if ret.data is not None: - return ret.data.to_df() - - def setup_method(self): - super().setup_method() - self.api_key = os.environ.get("LUMA_API_KEY") - self.run_sql(f""" - CREATE DATABASE mindsdb_luma - WITH ENGINE = 'luma', - PARAMETERS = { - "api_key": '{self.api_key}' - }; - """) - - def test_basic_select_from(self): - sql = "SELECT * FROM mindsdb_luma.events;" - self.run_sql(sql) - - sql = 'SELECT * FROM mindsdb_luma.events where event_id = "evt-HQ36IFDwncocuGy";' - assert self.run_sql(sql).shape[0] == 1 diff --git a/tests/unused/unit/handler_tests/test_mariadb_handler.py b/tests/unused/unit/handler_tests/test_mariadb_handler.py deleted file mode 100644 index fd3db056f7e..00000000000 --- a/tests/unused/unit/handler_tests/test_mariadb_handler.py +++ /dev/null @@ -1,169 +0,0 @@ -import time -import os -import shutil -import tarfile - -import pytest -import docker - -from mindsdb.integrations.handlers.mariadb_handler.mariadb_handler import MariaDBHandler -from mindsdb.api.executor.data_types.response_type import RESPONSE_TYPE -from mindsdb.utilities.fs import safe_extract - -HANDLER_KWARGS = { - "connection_data": { - "host": "localhost", - "port": "13306", - "user": "root", - "password": "supersecret", - "database": "test", - "ssl": False - } -} - -CERTS_ARCHIVE = "certs.tar" -CERTS_DIR = "mysql" - - -def get_certs(): - certs_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "mysql") - certs = {} - for cert_key, fname in [("ssl_ca", "ca.pem"), ("ssl_cert", "client-cert.pem"), ("ssl_key", "client-key.pem")]: - cert_file = os.path.join(certs_dir, fname) - certs[cert_key] = cert_file - return certs - - -def get_certificates(container): - cur_dir = os.path.dirname(os.path.abspath(__file__)) - archive_path = os.path.join(cur_dir, CERTS_ARCHIVE) - with open(archive_path, "wb") as f: - bits, _ = container.get_archive('/var/lib/mysql') - for chunk in bits: - f.write(chunk) - - with tarfile.open(archive_path) as tf: - safe_extract(tf, path=cur_dir) - certs = get_certs() - HANDLER_KWARGS["connection_data"].update(certs) - - -def waitReadiness(container, timeout=30): - threshold = time.time() + timeout - ready_msg = "mariadbd: ready for connections" - while True: - lines = container.logs().decode() - # container fully ready - # because it reloads the db server during initialization - # need to check that the 'ready for connections' has found second time - if lines.count(ready_msg) >= 2: - break - if time.time() > threshold: - raise Exception("timeout exceeded, container is still not ready") - - -@pytest.fixture(scope="module", params=[{"ssl": False}, {"ssl": True}], ids=["NoSSL", "SSL"]) -def handler(request): - image_name = "mindsdb/mariadb-handler-test" - docker_client = docker.from_env() - with_ssl = request.param["ssl"] - container = None - try: - container = docker_client.containers.run( - image_name, - command="--secure-file-priv=/", - detach=True, - environment={"MYSQL_ROOT_PASSWORD": "supersecret"}, - ports={"3306/tcp": 13306}, - ) - waitReadiness(container) - # ubnormal teardown - except Exception as e: - if container is not None: - container.kill() - raise e - - if with_ssl: - get_certificates(container) - handler = MariaDBHandler('test_mariadb_handler', **HANDLER_KWARGS) - yield handler - - # normal teardown - container.kill() - docker_client.close() - if with_ssl: - cur_dir = os.path.dirname(os.path.abspath(__file__)) - try: - os.remove(os.path.join(cur_dir, CERTS_ARCHIVE)) - shutil.rmtree(os.path.join(cur_dir, CERTS_DIR)) - except Exception as e: - print(f"unable to delete .tar/files of certificates: {e}") - - -class TestMariaDBHandler: - def test_connect(self, handler): - handler.connect() - assert handler.is_connected, "connection error" - - def test_check_connection(self, handler): - res = handler.check_connection() - assert res.success, res.error_message - - def test_native_query_show_dbs(self, handler): - dbs = handler.native_query("SHOW DATABASES;") - dbs = dbs.data_frame - assert dbs is not None, "expected to get some data, but got None" - assert 'Database' in dbs, f"expected to get 'Database' column in response:\n{dbs}" - dbs = list(dbs["Database"]) - expected_db = HANDLER_KWARGS["connection_data"]["database"] - assert expected_db in dbs, f"expected to have {expected_db} db in response: {dbs}" - - def test_get_tables(self, handler): - tables = self.get_table_names(handler) - assert "rentals" in tables, f"expected to have 'rentals' table in the db but got: {tables}" - - def test_describe_table(self, handler): - described = handler.get_columns("rentals") - describe_data = described.data_frame - self.check_valid_response(described) - got_columns = list(describe_data.iloc[:, 0]) - want_columns = ["number_of_rooms", "number_of_bathrooms", - "sqft", "location", "days_on_market", - "initial_price", "neighborhood", "rental_price"] - assert got_columns == want_columns, f"expected to have next columns in rentals table:\n{want_columns}\nbut got:\n{got_columns}" - - def test_create_table(self, handler): - new_table = "test_mdb" - res = handler.native_query(f"CREATE TABLE IF NOT EXISTS {new_table} (test_col INT)") - self.check_valid_response(res) - tables = self.get_table_names(handler) - assert new_table in tables, f"expected to have {new_table} in database, but got: {tables}" - - def test_drop_table(self, handler): - drop_table = "test_md" - res = handler.native_query(f"DROP TABLE IF EXISTS {drop_table}") - self.check_valid_response(res) - tables = self.get_table_names(handler) - assert drop_table not in tables - - def test_select_query(self, handler): - limit = 5 - query = f"SELECT * FROM rentals WHERE number_of_rooms = 2 LIMIT {limit}" - res = handler.query(query) - self.check_valid_response(res) - got_rows = res.data_frame.shape[0] - want_rows = limit - assert got_rows == want_rows, f"expected to have {want_rows} rows in response but got: {got_rows}" - - def check_valid_response(self, res): - if res.resp_type == RESPONSE_TYPE.TABLE: - assert res.data_frame is not None, "expected to have some data, but got None" - assert res.error_code == 0, f"expected to have zero error_code, but got {res.error_code}" - assert res.error_message is None, f"expected to have None in error message, but got {res.error_message}" - - def get_table_names(self, handler): - res = handler.get_tables() - tables = res.data_frame - assert tables is not None, "expected to have some tables in the db, but got None" - assert 'table_name' in tables, f"expected to get 'table_name' column in the response:\n{tables}" - return list(tables['table_name']) diff --git a/tests/unused/unit/handler_tests/test_milvus_handler.py b/tests/unused/unit/handler_tests/test_milvus_handler.py deleted file mode 100644 index 0e2170ba57c..00000000000 --- a/tests/unused/unit/handler_tests/test_milvus_handler.py +++ /dev/null @@ -1,460 +0,0 @@ -import importlib -from unittest.mock import patch - -import pandas as pd -import pytest -import time -from mindsdb_sql_parser import parse_sql - -from ..unit.executor_test_base import BaseExecutorTest - -try: - pymilvus = importlib.import_module("pymilvus") - MILVUS_INSTALLED = True -except ImportError: - MILVUS_INSTALLED = False - - -@pytest.mark.skipif(not MILVUS_INSTALLED, reason="pymilvus is not installed") -class TestMilvusHandler(BaseExecutorTest): - - def run_sql(self, sql): - ret = self.command_executor.execute_command(parse_sql(sql)) - assert ret.error_code is None - if ret.data is not None: - return ret.data.to_df() - - def setup_method(self): - super().setup_method() - # create a milvus database - self.run_sql(""" - CREATE DATABASE milvus_test - WITH - ENGINE = 'milvus', - PARAMETERS = { - "uri": "./milvus.db", - "create_embedding_dim": 3 - }; - """) - self.run_sql(""" - CREATE DATABASE milvus_test_auto_id - WITH - ENGINE = 'milvus', - PARAMETERS = { - "uri": "./milvus.db", - "create_embedding_dim": 3, - "create_auto_id": true - }; - """) - - def drop_table(self, table_name): - pymilvus.connections.connect( - uri="./milvus.db", - ) - pymilvus.utility.drop_collection(table_name) - - @pytest.mark.xfail(reason="create table for vectordatabase is not well supported") - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_create_table(self, postgres_handler_mock): - # create an empty table - sql = """ - CREATE TABLE milvus_test.testable; - """ - self.run_sql(sql) - # create a table with the schema definition is not allowed - sql = """ - CREATE TABLE milvus_test.testable ( - id int, - metadata text, - embedding float[] - ); - """ - with pytest.raises(Exception): - self.run_sql(sql) - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_create_with_select(self, postgres_handler_mock): - df = pd.DataFrame( - { - "id": ["id1", "id2"], - "content": ["this is a test", "this is a test"], - "metadata": [{"test": "test"}, {"test": "test"}], - "embeddings": [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0]], - } - ) - - self.set_handler(postgres_handler_mock, "pg", tables={"df": df}) - - self.drop_table("testable") - - sql = """ - CREATE TABLE milvus_test.testable ( - SELECT * FROM pg.df - ) - """ - # this should work - self.run_sql(sql) - - sql = """ - CREATE TABLE milvus_test.testable ( - SELECT * FROM pg.df - ) - """ - # this should work - self.run_sql(sql) - - self.drop_table("testable") - - @pytest.mark.xfail(reason="drop table for vectordatabase is not working") - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_drop_table(self, postgres_handler_mock): - df = pd.DataFrame( - { - "id": ["id1", "id2"], - "content": ["this is a test", "this is a test"], - "metadata": [{"test": "test"}, {"test": "test"}], - "embeddings": [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0]], - } - ) - self.set_handler(postgres_handler_mock, "pg", tables={"testable": df}) - - self.drop_table("testable") - - # create a table - sql = """ - CREATE TABLE milvus_test.testable ( - SELECT * FROM pg.df - ) - """ - self.run_sql(sql) - - # drop a table - sql = """ - DROP TABLE milvus_test.testable; - """ - self.run_sql(sql) - - # drop a non existent table will raise an error - sql = """ - DROP TABLE milvus_test.test_table2; - """ - with pytest.raises(Exception): - self.run_sql(sql) - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_insert_into(self, postgres_handler_mock): - df = pd.DataFrame( - { - "id": ["id1", "id2", "id3"], - "content": ["this is a test", "this is a test", "this is a test"], - "metadata": [{"test": "test1"}, {"test": "test2"}, {"test": "test3"}], - "embeddings": [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0], [1.0, 2.0, 3.0]], - } - ) - df2 = pd.DataFrame( - { - "content": ["this is a test", "this is a test", "this is a test"], - "metadata": [{"test": "test1"}, {"test": "test2"}, {"test": "test3"}], - "embeddings": [ - [1.0, 2.0, 4.0], - [1.0, 2.0, 5.0], - [1.0, 2.0, 3.0], - ], - } - ) - self.set_handler(postgres_handler_mock, "pg", tables={"df": df, "df2": df2}) - - self.drop_table("testable") - self.drop_table("testableauto") - - # create tables - sql = """ - CREATE TABLE milvus_test.testable ( - SELECT * FROM pg.df - ) - """ - self.run_sql(sql) - sql = """ - CREATE TABLE milvus_test_auto_id.testableauto ( - SELECT * FROM pg.df2 - ) - """ - self.run_sql(sql) - - # insert into a table with values - sql = """ - INSERT INTO milvus_test.testable ( - id,content,metadata,embeddings - ) - VALUES ( - "id4", 'this is a test', '{"test": "test"}', '[1.0, 8.0, 9.0]' - ) - """ - self.run_sql(sql) - - time.sleep(1) # wait for milvus to load the data asynchronously - # check if the data is inserted - sql = """ - SELECT * FROM milvus_test.testable - WHERE id = "id4" - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 1 - - # insert without specifying id should work in autoid one - sql = """ - INSERT INTO milvus_test_auto_id.testableauto ( - content,metadata,embeddings - ) - VALUES ( - 'this is a test', '{"test": "test"}', '[1.0, 2.0, 3.0]' - ) - """ - self.run_sql(sql) - - time.sleep(1) # wait for milvus to load the data asynchronously - # check if the data is inserted - sql = """ - SELECT * FROM milvus_test_auto_id.testableauto - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 4 - - # insert into a table with a select statement - sql = """ - INSERT INTO milvus_test_auto_id.testableauto (content,metadata,embeddings) - SELECT * FROM pg.df2 - """ - self.run_sql(sql) - - time.sleep(1) # wait for milvus to load the data asynchronously - # check if the data is inserted - sql = """ - SELECT * FROM milvus_test.testableauto - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 7 - - self.drop_table("testable") - self.drop_table("testableauto") - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_select_from(self, postgres_handler_mock): - df = pd.DataFrame( - { - "id": ["id1", "id2"], - "content": ["this is a test", "this is a test"], - "metadata": [{"test": "test"}, {"test": "test"}], - "embeddings": [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0]], - } - ) - self.set_handler(postgres_handler_mock, "pg", tables={"testable": df}) - - self.drop_table("testable") - - # create a table - sql = """ - CREATE TABLE milvus_test.testable ( - SELECT * FROM pg.df - ) - """ - self.run_sql(sql) - - time.sleep(1) # wait for milvus to load the data asynchronously - # query a table without any filters - sql = """ - SELECT * FROM milvus_test.testable - """ - self.run_sql(sql) - - # query a table with id - sql = """ - SELECT * FROM milvus_test.testable - WHERE id = 'id1' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 1 - - # query a table with a search vector, without limit - sql = """ - SELECT * FROM milvus_test.testable - WHERE search_vector = '[1.0, 2.0, 3.0]' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - - # query a table with a search vector, with limit - sql = """ - SELECT * FROM milvus_test.testable - WHERE search_vector = '[1.0, 2.0, 3.0]' - LIMIT 1 - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 1 - - # query a table with a metadata filter - sql = """ - SELECT * FROM milvus_test.testable - WHERE test = 'test' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - - # query a table with a metadata filter and a search vector - sql = """ - SELECT * FROM milvus_test.testable - WHERE test = 'test' - AND search_vector = '[1.0, 2.0, 3.0]' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - - self.drop_table("testable") - - @pytest.mark.xfail(reason="update for vectordatabase is not implemented") - def test_update(self): - # update a table with a metadata filter - sql = """ - UPDATE milvus_test.testable - SET test = 'test2' - WHERE test = 'test' - """ - self.run_sql(sql) - # check if the data is updated - sql = """ - SELECT * FROM milvus_test.testable - WHERE test = 'test2' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - - # update the embeddings - sql = """ - UPDATE milvus_test.testable - SET embedding = [3.0, 2.0, 1.0] - WHERE test = 'test2' - """ - self.run_sql(sql) - # check if the data is updated - sql = """ - SELECT * FROM milvus_test.testable - WHERE test = 'test2' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - assert ret.embedding[0] == [3.0, 2.0, 1.0] - - # update multiple columns - sql = """ - UPDATE milvus_test.testable - SET test = 'test3', - embedding = [1.0, 2.0, 3.0] - content = 'this is a test' - WHERE test = 'test2' - """ - self.run_sql(sql) - # check if the data is updated - sql = """ - SELECT * FROM milvus_test.testable - WHERE test = 'test3' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - assert ret.embedding[0] == [1.0, 2.0, 3.0] - assert ret.content[0] == "this is a test" - - # update a table with a search vector filter is not allowed - sql = """ - UPDATE milvus_test.testable - SET `metadata.test = 'test2' - WHERE search_vector = [1.0, 2.0, 3.0] - """ - with pytest.raises(Exception): - self.run_sql(sql) - - # update a table without any filters is allowed - sql = """ - UPDATE milvus_test.testable - SET metadata.test = 'test3' - """ - self.run_sql(sql) - # check if the data is updated - sql = """ - SELECT * FROM milvus_test.testable - WHERE `metadata.test` = 'test3' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - - # update a table with a search vector filter and a metadata filter is not allowed - sql = """ - UPDATE milvus_test.testable - SET metadata.test = 'test3' - WHERE metadata.test = 'test2' - AND search_vector = [1.0, 2.0, 3.0] - """ - with pytest.raises(Exception): - self.run_sql(sql) - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_delete(self, postgres_handler_mock): - df = pd.DataFrame( - { - "id": ["id1", "id2", "id3"], - "content": ["this is a test", "this is a test", "this is a test"], - "metadata": [{"test": "test1"}, {"test": "test2"}, {"test": "test3"}], - "embeddings": [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0], [1.0, 2.0, 3.0]], - } - ) - - self.drop_table("testable") - - self.set_handler(postgres_handler_mock, "pg", tables={"testable": df}) - - # create a table - sql = """ - CREATE TABLE milvus_test.testable ( - SELECT * FROM pg.df - ) - """ - self.run_sql(sql) - - time.sleep(1) # wait for milvus to load the data asynchronously - # delete by id - sql = """ - DELETE FROM milvus_test.testable - WHERE id IN ('id1') - """ - self.run_sql(sql) - - time.sleep(1) # wait for milvus to load the data asynchronously - # check if the data is deleted - sql = """ - SELECT * FROM milvus_test.testable - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - - # delete by multiple ids - sql = """ - DELETE FROM milvus_test.testable - WHERE id IN ('id2', 'id3') - """ - self.run_sql(sql) - - time.sleep(1) # wait for milvus to load the data asynchronously - # check if the data is deleted - sql = """ - SELECT * FROM milvus_test.testable - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - - # delete from a table without any filters is not allowed - sql = """ - DELETE FROM milvus_test.testable - """ - with pytest.raises(Exception): - self.run_sql(sql) - - self.drop_table("testable") diff --git a/tests/unused/unit/handler_tests/test_ms_teams_handler.py b/tests/unused/unit/handler_tests/test_ms_teams_handler.py deleted file mode 100644 index f12e6e3de9d..00000000000 --- a/tests/unused/unit/handler_tests/test_ms_teams_handler.py +++ /dev/null @@ -1,1050 +0,0 @@ -import unittest -from unittest.mock import Mock, patch - -from mindsdb_sql_parser import ast -from mindsdb_sql_parser.ast import Constant, BinaryOperation - -from mindsdb_sql_parser.ast.select.star import Star -from mindsdb_sql_parser.ast.select.identifier import Identifier - -from mindsdb.integrations.handlers.ms_teams_handler.ms_teams_handler import MSTeamsHandler -from mindsdb.integrations.handlers.ms_teams_handler.settings import ms_teams_handler_config -from mindsdb.integrations.handlers.ms_teams_handler.ms_graph_api_teams_client import MSGraphAPITeamsClient -from mindsdb.integrations.handlers.ms_teams_handler.ms_teams_tables import ChatsTable, ChatMessagesTable, ChannelsTable, ChannelMessagesTable - - -class TestMSGraphAPITeamsClient(unittest.TestCase): - @classmethod - def setUpClass(cls): - """ - Set up the tests. - """ - - # mock the api client with a dummy access_token parameter (calls to the API that use this parameter will be mocked) - cls.api_client = MSGraphAPITeamsClient("test_access_token") - - @patch('requests.get') - def test_get_chat_returns_chat_data(self, mock_get): - """ - Test that get_chat returns chat data. - """ - - # configure the mock to return a response with 'status_code' 200 - mock_get.return_value = Mock( - status_code=200, - headers={'Content-Type': 'application/json'}, - json=Mock(return_value=ms_teams_handler_config.TEST_CHAT_DATA) - ) - - chat_data = self.api_client.get_chat("test_id") - - # assert the requests.get call was made with the expected arguments - mock_get.assert_called_once_with( - 'https://graph.microsoft.com/v1.0/chats/test_id/', - headers={'Authorization': 'Bearer test_access_token'}, - params={'$expand': 'lastMessagePreview'} - ) - - self.assertEqual(chat_data["id"], "test_id") - self.assertEqual(chat_data["chatType"], "oneOnOne") - - @patch('requests.get') - def test_get_chats_returns_chats_data(self, mock_get): - """ - Test that get_chats returns chats data. - """ - - # configure the mock to return a response with 'status_code' 200 - mock_get.return_value = Mock( - status_code=200, - headers={'Content-Type': 'application/json'}, - json=Mock(return_value={'value': ms_teams_handler_config.TEST_CHATS_DATA}) - ) - - chats_data = self.api_client.get_chats() - - # assert the requests.get call was made with the expected arguments - mock_get.assert_called_once_with( - 'https://graph.microsoft.com/v1.0/chats/', - headers={'Authorization': 'Bearer test_access_token'}, - params={'$expand': 'lastMessagePreview', '$top': 20} - ) - - self.assertEqual(chats_data[0]["id"], "test_id") - self.assertEqual(chats_data[0]["chatType"], "oneOnOne") - - @patch('requests.get') - def test_get_chat_message_returns_chat_message_data(self, mock_get): - """ - Test that get_chat_message returns chat message data. - """ - - # configure the mock to return a response with 'status_code' 200 - mock_get.return_value = Mock( - status_code=200, - headers={'Content-Type': 'application/json'}, - json=Mock(return_value=ms_teams_handler_config.TEST_CHAT_MESSAGE_DATA) - ) - - chat_message_data = self.api_client.get_chat_message("test_chat_id", "test_id") - - # assert the requests.get call was made with the expected arguments - mock_get.assert_called_once_with( - 'https://graph.microsoft.com/v1.0/chats/test_chat_id/messages/test_id/', - headers={'Authorization': 'Bearer test_access_token'}, - params=None - ) - - self.assertEqual(chat_message_data["id"], "test_id") - self.assertEqual(chat_message_data["messageType"], "message") - self.assertEqual(chat_message_data["chatId"], "test_chat_id") - - @patch('requests.get') - def test_get_chat_messages_returns_chat_messages_data(self, mock_get): - """ - Test that get_chat_messages returns chat messages data. - """ - - # configure the mock to return a response with 'status_code' 200 - mock_get.return_value = Mock( - status_code=200, - headers={'Content-Type': 'application/json'}, - json=Mock(return_value={'value': ms_teams_handler_config.TEST_CHAT_MESSAGES_DATA}) - ) - - chat_messages_data = self.api_client.get_chat_messages("test_chat_id") - - # assert the requests.get call was made with the expected arguments - mock_get.assert_called_once_with( - 'https://graph.microsoft.com/v1.0/chats/test_chat_id/messages/', - headers={'Authorization': 'Bearer test_access_token'}, - params={'$top': 20} - ) - - self.assertEqual(chat_messages_data[0]["id"], "test_id") - self.assertEqual(chat_messages_data[0]["messageType"], "message") - self.assertEqual(chat_messages_data[0]["chatId"], "test_chat_id") - - @patch('requests.get') - def test_get_all_chat_messages_returns_all_chat_messages_data(self, mock_get): - """ - Test that get_all_chat_messages returns all chat messages data. - """ - - # configure the mock to return a response with 'status_code' 200 - mock_get.side_effect = [ - Mock( - status_code=200, - headers={'Content-Type': 'application/json'}, - json=Mock(return_value={'value': ms_teams_handler_config.TEST_CHATS_DATA}) - ), - Mock( - status_code=200, - headers={'Content-Type': 'application/json'}, - json=Mock(return_value={'value': ms_teams_handler_config.TEST_CHAT_MESSAGES_DATA}) - ) - ] - - chat_messages_data = self.api_client.get_all_chat_messages() - - # assert the requests.get calls were made with the expected arguments - mock_get.assert_any_call( - 'https://graph.microsoft.com/v1.0/chats/', - headers={'Authorization': 'Bearer test_access_token'}, - params={'$expand': 'lastMessagePreview', '$top': 20} - ) - - mock_get.assert_any_call( - 'https://graph.microsoft.com/v1.0/chats/test_id/messages/', - headers={'Authorization': 'Bearer test_access_token'}, - params={'$top': 20} - ) - - self.assertEqual(chat_messages_data[0]["id"], "test_id") - self.assertEqual(chat_messages_data[0]["messageType"], "message") - self.assertEqual(chat_messages_data[0]["chatId"], "test_chat_id") - - @patch('requests.post') - def test_send_chat_message_sends_correct_request(self, mock_post): - """ - Test that send_chat_message sends a chat message. - """ - - # configure the mock to return a response with 'status_code' 201 - mock_post.return_value = Mock( - status_code=201, - headers={'Content-Type': 'application/json'}, - ) - - self.api_client.send_chat_message("test_chat_id", "test_message", "test_subject") - - # assert the requests.post call was made with the expected arguments - mock_post.assert_called_once_with( - 'https://graph.microsoft.com/v1.0/chats/test_chat_id/messages/', - headers={'Authorization': 'Bearer test_access_token'}, - json={'subject': 'test_subject', 'body': {'content': 'test_message'}} - ) - - @patch('requests.get') - def test_get_channel_returns_channel_data(self, mock_get): - """ - Test that get_channel returns channel data. - """ - - # configure the mock to return a response with 'status_code' 200 - mock_get.return_value = Mock( - status_code=200, - headers={'Content-Type': 'application/json'}, - json=Mock(return_value=ms_teams_handler_config.TEST_CHANNEL_DATA) - ) - - channel_data = self.api_client.get_channel("test_team_id", "test_id") - - # assert the requests.get call was made with the expected arguments - mock_get.assert_called_once_with( - 'https://graph.microsoft.com/v1.0/teams/test_team_id/channels/test_id/', - headers={'Authorization': 'Bearer test_access_token'}, - params=None - ) - - self.assertEqual(channel_data["id"], "test_id") - self.assertEqual(channel_data["displayName"], "test_display_name") - self.assertEqual(channel_data["teamId"], "test_team_id") - - @patch('requests.get') - def test_get_channels_returns_channels_data(self, mock_get): - """ - Test that get_channels returns channels data. - """ - - # check if the group_ids parameter in the API client is set - is_group_ids_set = True if self.api_client._group_ids is not None else False - - # configure the mock to return a response with 'status_code' 200 - # if the group_ids parameter is not set, the mock will return the group data first, then the channels data - if not is_group_ids_set: - mock_get.side_effect = [ - Mock( - status_code=200, - headers={'Content-Type': 'application/json'}, - json=Mock(return_value=ms_teams_handler_config.TEST_GROUP_DATA) - ), - Mock( - status_code=200, - headers={'Content-Type': 'application/json'}, - json=Mock(return_value={'value': ms_teams_handler_config.TEST_CHANNELS_DATA}) - ) - ] - - # if the group_ids parameter is set, the mock will only return the channels data - else: - mock_get.return_value = Mock( - status_code=200, - headers={'Content-Type': 'application/json'}, - json=Mock(return_value={'value': ms_teams_handler_config.TEST_CHANNELS_DATA}) - ) - - channels_data = self.api_client.get_channels() - - # assert the requests.get calls were made with the expected arguments - # if the group_ids parameter is not set, the mock will check the calls to both the groups and channels endpoints - if not is_group_ids_set: - mock_get.assert_any_call( - 'https://graph.microsoft.com/v1.0/groups/', - headers={'Authorization': 'Bearer test_access_token'}, - params={'$select': 'id,resourceProvisioningOptions'} - ) - - mock_get.assert_any_call( - 'https://graph.microsoft.com/v1.0/teams/test_team_id/channels/', - headers={'Authorization': 'Bearer test_access_token'}, - params=None - ) - - # if the group_ids parameter is set, the mock will only check the call to the channels endpoint - else: - mock_get.assert_called_once_with( - 'https://graph.microsoft.com/v1.0/teams/test_team_id/channels/', - headers={'Authorization': 'Bearer test_access_token'}, - params=None - ) - - self.assertEqual(channels_data[0]["id"], "test_id") - self.assertEqual(channels_data[0]["displayName"], "test_display_name") - self.assertEqual(channels_data[0]["teamId"], "test_team_id") - - @patch('requests.get') - def test_get_channel_message_returns_channel_message_data(self, mock_get): - """ - Test that get_channel_message returns channel message data. - """ - - # configure the mock to return a response with 'status_code' 200 - mock_get.return_value = Mock( - status_code=200, - headers={'Content-Type': 'application/json'}, - json=Mock(return_value=ms_teams_handler_config.TEST_CHANNEL_MESSAGE_DATA) - ) - - channel_message_data = self.api_client.get_channel_message("test_team_id", "test_channel_id", "test_id") - - # assert the requests.get call was made with the expected arguments - mock_get.assert_called_once_with( - 'https://graph.microsoft.com/v1.0/teams/test_team_id/channels/test_channel_id/messages/test_id/', - headers={'Authorization': 'Bearer test_access_token'}, - params=None - ) - - self.assertEqual(channel_message_data["id"], "test_id") - self.assertEqual(channel_message_data["messageType"], "message") - self.assertEqual(channel_message_data["channelIdentity"]["channelId"], "test_channel_id") - self.assertEqual(channel_message_data["channelIdentity"]["teamId"], "test_team_id") - - @patch('requests.get') - def test_get_channel_messages_returns_channel_messages_data(self, mock_get): - """ - Test that get_channel_messages returns channel messages data. - """ - - # check if the group_ids parameter in the API client is set - is_group_ids_set = True if self.api_client._group_ids is not None else False - - # configure the mocks to return a response with 'status_code' 200 - # if the group_ids parameter is not set, the mocks will return the group data first, then the channel ID data, then the channel messages data - if not is_group_ids_set: - mock_get.side_effect = [ - Mock( - status_code=200, - headers={'Content-Type': 'application/json'}, - json=Mock(return_value=ms_teams_handler_config.TEST_GROUP_DATA) - ), - Mock( - status_code=200, - headers={'Content-Type': 'application/json'}, - json=Mock(return_value=ms_teams_handler_config.TEST_CHANNEL_ID_DATA) - ), - Mock( - status_code=200, - headers={'Content-Type': 'application/json'}, - json=Mock(return_value={'value': ms_teams_handler_config.TEST_CHANNEL_MESSAGES_DATA}) - ), - ] - - # if the group_ids parameter is set, the mocks will only return the channel ID data, then the channel messages data - else: - mock_get.side_effect = [ - Mock( - status_code=200, - headers={'Content-Type': 'application/json'}, - json=Mock(return_value=ms_teams_handler_config.TEST_CHANNEL_ID_DATA) - ), - Mock( - status_code=200, - headers={'Content-Type': 'application/json'}, - json=Mock(return_value={'value': ms_teams_handler_config.TEST_CHANNEL_MESSAGES_DATA}) - ), - ] - - channel_messages_data = self.api_client.get_channel_messages() - - # assert the requests.get calls were made with the expected arguments - # if the group_ids parameter is not set, check the calls to the groups endpoint - if not is_group_ids_set: - mock_get.assert_any_call( - 'https://graph.microsoft.com/v1.0/groups/', - headers={'Authorization': 'Bearer test_access_token'}, - params={'$select': 'id,resourceProvisioningOptions'} - ) - - mock_get.assert_any_call( - 'https://graph.microsoft.com/v1.0/teams/test_team_id/channels/', - headers={'Authorization': 'Bearer test_access_token'}, - params=None - ) - - mock_get.assert_any_call( - 'https://graph.microsoft.com/v1.0/teams/test_team_id/channels/test_channel_id/messages/', - headers={'Authorization': 'Bearer test_access_token'}, - params={'$top': 20} - ) - - self.assertEqual(channel_messages_data[0]["id"], "test_id") - self.assertEqual(channel_messages_data[0]["messageType"], "message") - self.assertEqual(channel_messages_data[0]["channelIdentity"]["channelId"], "test_channel_id") - self.assertEqual(channel_messages_data[0]["channelIdentity"]["teamId"], "test_team_id") - - @patch('requests.post') - def test_send_channel_message_sends_correct_request(self, mock_post): - """ - Test that send_channel_message sends a channel message. - """ - - # configure the mock to return a response with 'status_code' 201 - mock_post.return_value = Mock( - status_code=201, - headers={'Content-Type': 'application/json'}, - ) - - self.api_client.send_channel_message("test_team_id", "test_channel_id", "test_message", "test_subject") - - # assert the requests.post call was made with the expected arguments - mock_post.assert_called_once_with( - 'https://graph.microsoft.com/v1.0/teams/test_team_id/channels/test_channel_id/messages/', - headers={'Authorization': 'Bearer test_access_token'}, - json={'subject': 'test_subject', 'body': {'content': 'test_message'}} - ) - - -class TestChatsTable(unittest.TestCase): - """ - Tests for the ChatsTable class. - """ - - @classmethod - def setUpClass(cls): - """ - Set up the tests. - """ - - # mock the api handler - cls.api_handler = Mock(MSTeamsHandler) - - def test_get_columns_returns_all_columns(self): - """ - Test that get_columns returns all columns. - """ - - chats_table = ChatsTable(self.api_handler) - - self.assertListEqual(chats_table.get_columns(), ms_teams_handler_config.CHATS_TABLE_COLUMNS) - - def test_select_star_for_single_chat_returns_all_columns(self): - # patch the api handler to return the chat data - with patch.object(self.api_handler.connect(), 'get_chat', return_value=ms_teams_handler_config.TEST_CHAT_DATA): - chats_table = ChatsTable(self.api_handler) - - select_all = ast.Select( - # select all columns - targets=[Star()], - from_table="chats", - where=BinaryOperation( - op='=', - args=[ - Identifier('id'), - Constant("test_id") - ] - ) - ) - - all_chats = chats_table.select(select_all) - first_chat = all_chats.iloc[0] - - self.assertEqual(all_chats.shape[1], len(ms_teams_handler_config.CHATS_TABLE_COLUMNS)) - self.assertEqual(first_chat["id"], "test_id") - self.assertEqual(first_chat["chatType"], "oneOnOne") - - def test_select_star_for_all_chats_returns_all_columns(self): - # patch the api handler to return the chat data - with patch.object(self.api_handler.connect(), 'get_chats', return_value=ms_teams_handler_config.TEST_CHATS_DATA): - chats_table = ChatsTable(self.api_handler) - - select_all = ast.Select( - # select all columns - targets=[Star()], - from_table="chats", - ) - - all_chats = chats_table.select(select_all) - first_chat = all_chats.iloc[0] - - self.assertEqual(all_chats.shape[1], len(ms_teams_handler_config.CHATS_TABLE_COLUMNS)) - self.assertEqual(first_chat["id"], "test_id") - self.assertEqual(first_chat["chatType"], "oneOnOne") - - def test_select_for_single_chat_returns_only_selected_columns(self): - # patch the api handler to return the chat data - with patch.object(self.api_handler.connect(), 'get_chat', return_value=ms_teams_handler_config.TEST_CHAT_DATA): - chats_table = ChatsTable(self.api_handler) - - select_all = ast.Select( - # select only the id and chatType columns - targets=[ - Identifier('id'), - Identifier('chatType'), - ], - from_table="chats", - where=BinaryOperation( - op='=', - args=[ - Identifier('id'), - Constant("test_id") - ] - ) - ) - - all_chats = chats_table.select(select_all) - first_chat = all_chats.iloc[0] - - self.assertEqual(all_chats.shape[1], 2) - self.assertEqual(first_chat["id"], "test_id") - self.assertEqual(first_chat["chatType"], "oneOnOne") - - def test_select_for_all_chats_returns_only_selected_columns(self): - # patch the api handler to return the chat data - with patch.object(self.api_handler.connect(), 'get_chats', return_value=ms_teams_handler_config.TEST_CHATS_DATA): - chats_table = ChatsTable(self.api_handler) - - select_all = ast.Select( - # select all columns - targets=[ - Identifier('id'), - Identifier('chatType'), - ], - from_table="chats", - ) - - all_chats = chats_table.select(select_all) - first_chat = all_chats.iloc[0] - - self.assertEqual(all_chats.shape[1], 2) - self.assertEqual(first_chat["id"], "test_id") - self.assertEqual(first_chat["chatType"], "oneOnOne") - - -class TestChatMessagesTable(unittest.TestCase): - """ - Tests for the ChatMessagesTable class. - """ - - @classmethod - def setUpClass(cls): - """ - Set up the tests. - """ - - # mock the api handler - cls.api_handler = Mock(MSTeamsHandler) - - def test_get_columns_returns_all_columns(self): - """ - Test that get_columns returns all columns. - """ - - chat_messages_table = ChatMessagesTable(self.api_handler) - - self.assertListEqual(chat_messages_table.get_columns(), ms_teams_handler_config.CHAT_MESSAGES_TABLE_COLUMNS) - - def test_select_star_for_single_chat_returns_all_columns(self): - # patch the api handler to return the chat message data - with patch.object(self.api_handler.connect(), 'get_chat_message', return_value=ms_teams_handler_config.TEST_CHAT_MESSAGE_DATA): - chat_messages_table = ChatMessagesTable(self.api_handler) - - select_all = ast.Select( - # select all columns - targets=[Star()], - from_table="chat_messages", - where=[ - BinaryOperation( - op='=', - args=[ - Identifier('id'), - Constant("test_id") - ] - ), - BinaryOperation( - op='=', - args=[ - Identifier('chatId'), - Constant("test_chat_id") - ] - ) - ] - ) - - all_chat_messages = chat_messages_table.select(select_all) - first_chat_message = all_chat_messages.iloc[0] - - self.assertEqual(all_chat_messages.shape[1], len(ms_teams_handler_config.CHAT_MESSAGES_TABLE_COLUMNS)) - self.assertEqual(first_chat_message["id"], "test_id") - self.assertEqual(first_chat_message["messageType"], "message") - - def test_select_star_for_multiple_chats_returns_all_columns(self): - # patch the api handler to return the chat message data - with patch.object(self.api_handler.connect(), 'get_chat_messages', return_value=ms_teams_handler_config.TEST_CHAT_MESSAGES_DATA): - chat_messages_table = ChatMessagesTable(self.api_handler) - - select_all = ast.Select( - # select all columns - targets=[Star()], - from_table="chat_messages", - where=[ - BinaryOperation( - op='=', - args=[ - Identifier('chatId'), - Constant("test_chat_id") - ] - ) - ] - ) - - all_chat_messages = chat_messages_table.select(select_all) - first_chat_message = all_chat_messages.iloc[0] - - self.assertEqual(all_chat_messages.shape[1], len(ms_teams_handler_config.CHAT_MESSAGES_TABLE_COLUMNS)) - self.assertEqual(first_chat_message["id"], "test_id") - self.assertEqual(first_chat_message["messageType"], "message") - - def test_select_star_for_all_chats_returns_all_columns(self): - # patch the api handler to return the chat message data - with patch.object(self.api_handler.connect(), 'get_all_chat_messages', return_value=ms_teams_handler_config.TEST_CHAT_MESSAGES_DATA): - chat_messages_table = ChatMessagesTable(self.api_handler) - - select_all = ast.Select( - # select all columns - targets=[Star()], - from_table="chat_messages", - ) - - all_chat_messages = chat_messages_table.select(select_all) - first_chat_message = all_chat_messages.iloc[0] - - self.assertEqual(all_chat_messages.shape[1], len(ms_teams_handler_config.CHAT_MESSAGES_TABLE_COLUMNS)) - self.assertEqual(first_chat_message["id"], "test_id") - self.assertEqual(first_chat_message["messageType"], "message") - - def test_select_for_single_chat_returns_only_selected_columns(self): - # patch the api handler to return the chat message data - with patch.object(self.api_handler.connect(), 'get_chat_message', return_value=ms_teams_handler_config.TEST_CHAT_MESSAGE_DATA): - chat_messages_table = ChatMessagesTable(self.api_handler) - - select_all = ast.Select( - # select only the id and messageType columns - targets=[ - Identifier('id'), - Identifier('messageType'), - ], - from_table="chat_messages", - where=[ - BinaryOperation( - op='=', - args=[ - Identifier('id'), - Constant("test_id") - ] - ), - BinaryOperation( - op='=', - args=[ - Identifier('chatId'), - Constant("test_chat_id") - ] - ) - ] - ) - - all_chat_messages = chat_messages_table.select(select_all) - first_chat_message = all_chat_messages.iloc[0] - - self.assertEqual(all_chat_messages.shape[1], 2) - self.assertEqual(first_chat_message["id"], "test_id") - self.assertEqual(first_chat_message["messageType"], "message") - - def test_select_for_multiple_chats_returns_only_selected_columns(self): - # patch the api handler to return the chat message data - with patch.object(self.api_handler.connect(), 'get_chat_messages', return_value=ms_teams_handler_config.TEST_CHAT_MESSAGES_DATA): - chat_messages_table = ChatMessagesTable(self.api_handler) - - select_all = ast.Select( - # select only the id and messageType columns - targets=[ - Identifier('id'), - Identifier('messageType'), - ], - from_table="chat_messages", - where=[ - BinaryOperation( - op='=', - args=[ - Identifier('chatId'), - Constant("test_chat_id") - ] - ) - ] - ) - - all_chat_messages = chat_messages_table.select(select_all) - first_chat_message = all_chat_messages.iloc[0] - - self.assertEqual(all_chat_messages.shape[1], 2) - self.assertEqual(first_chat_message["id"], "test_id") - self.assertEqual(first_chat_message["messageType"], "message") - - def test_select_for_all_chats_returns_only_selected_columns(self): - # patch the api handler to return the chat message data - with patch.object(self.api_handler.connect(), 'get_all_chat_messages', return_value=ms_teams_handler_config.TEST_CHAT_MESSAGES_DATA): - chat_messages_table = ChatMessagesTable(self.api_handler) - - select_all = ast.Select( - # select only the id and messageType columns - targets=[ - Identifier('id'), - Identifier('messageType'), - ], - from_table="chat_messages", - ) - - all_chat_messages = chat_messages_table.select(select_all) - first_chat_message = all_chat_messages.iloc[0] - - self.assertEqual(all_chat_messages.shape[1], 2) - self.assertEqual(first_chat_message["id"], "test_id") - self.assertEqual(first_chat_message["messageType"], "message") - - def test_insert_chat_message_calls_correct_method_in_client(self): - """ - Test that send_chat_message sends a chat message. - """ - - # patch the api handler to return the chat message data - with patch.object(self.api_handler.connect(), 'send_chat_message', return_value=None) as mock_send_chat_message: - chat_messages_table = ChatMessagesTable(self.api_handler) - - insert = ast.Insert( - table="chat_messages", - columns=[ - Identifier('chatId'), - Identifier('body_content'), - Identifier('subject'), - ], - values=[ - ( - "test_chat_id", - "test_message", - "test_subject" - ) - ] - ) - - chat_messages_table.insert(insert) - - # assert the api handler's send_chat_message method was called with the expected arguments - mock_send_chat_message.assert_called_once_with(chat_id='test_chat_id', message='test_message', subject='test_subject') - - -class TestChannelsTable(unittest.TestCase): - """ - Tests for the ChannelsTable class. - """ - - @classmethod - def setUpClass(cls): - """ - Set up the tests. - """ - - # mock the api handler - cls.api_handler = Mock(MSTeamsHandler) - - def test_get_columns_returns_all_columns(self): - """ - Test that get_columns returns all columns. - """ - - channels_table = ChannelsTable(self.api_handler) - - self.assertListEqual(channels_table.get_columns(), ms_teams_handler_config.CHANNELS_TABLE_COLUMNS) - - def test_select_star_for_single_channel_returns_all_columns(self): - # patch the api handler to return the channel data - with patch.object(self.api_handler.connect(), 'get_channel', return_value=ms_teams_handler_config.TEST_CHANNEL_DATA): - channels_table = ChannelsTable(self.api_handler) - - select_all = ast.Select( - # select all columns - targets=[Star()], - from_table="channels", - where=[ - BinaryOperation( - op='=', - args=[ - Identifier('id'), - Constant("test_id") - ] - ), - BinaryOperation( - op='=', - args=[ - Identifier('teamId'), - Constant("test_team_id") - ] - ) - ] - ) - - all_channels = channels_table.select(select_all) - first_channel = all_channels.iloc[0] - - self.assertEqual(all_channels.shape[1], len(ms_teams_handler_config.CHANNELS_TABLE_COLUMNS)) - self.assertEqual(first_channel["id"], "test_id") - self.assertEqual(first_channel["displayName"], "test_display_name") - - def test_select_star_for_all_channels_returns_all_columns(self): - # patch the api handler to return the channel data - with patch.object(self.api_handler.connect(), 'get_channels', return_value=ms_teams_handler_config.TEST_CHANNELS_DATA): - channels_table = ChannelsTable(self.api_handler) - - select_all = ast.Select( - # select all columns - targets=[Star()], - from_table="channels", - ) - - all_channels = channels_table.select(select_all) - first_channel = all_channels.iloc[0] - - self.assertEqual(all_channels.shape[1], len(ms_teams_handler_config.CHANNELS_TABLE_COLUMNS)) - self.assertEqual(first_channel["id"], "test_id") - self.assertEqual(first_channel["displayName"], "test_display_name") - - def test_select_for_single_channel_returns_only_selected_columns(self): - # patch the api handler to return the channel data - with patch.object(self.api_handler.connect(), 'get_channel', return_value=ms_teams_handler_config.TEST_CHANNEL_DATA): - channels_table = ChannelsTable(self.api_handler) - - select_all = ast.Select( - # select only the id and displayName columns - targets=[ - Identifier('id'), - Identifier('displayName'), - ], - from_table="channels", - where=[ - BinaryOperation( - op='=', - args=[ - Identifier('id'), - Constant("test_id") - ] - ), - BinaryOperation( - op='=', - args=[ - Identifier('teamId'), - Constant("test_team_id") - ] - ) - ] - ) - - all_channels = channels_table.select(select_all) - first_channel = all_channels.iloc[0] - - self.assertEqual(all_channels.shape[1], 2) - self.assertEqual(first_channel["id"], "test_id") - self.assertEqual(first_channel["displayName"], "test_display_name") - - def test_select_for_all_channels_returns_only_selected_columns(self): - # patch the api handler to return the channel data - with patch.object(self.api_handler.connect(), 'get_channels', return_value=ms_teams_handler_config.TEST_CHANNELS_DATA): - channels_table = ChannelsTable(self.api_handler) - - select_all = ast.Select( - # select only the id and displayName columns - targets=[ - Identifier('id'), - Identifier('displayName'), - ], - from_table="channels", - ) - - all_channels = channels_table.select(select_all) - first_channel = all_channels.iloc[0] - - self.assertEqual(all_channels.shape[1], 2) - self.assertEqual(first_channel["id"], "test_id") - self.assertEqual(first_channel["displayName"], "test_display_name") - - -class TestChannelMessagesTable(unittest.TestCase): - """ - Tests for the ChannelMessagesTable class. - """ - - @classmethod - def setUpClass(cls): - """ - Set up the tests. - """ - - # mock the api handler - cls.api_handler = Mock(MSTeamsHandler) - - def test_get_columns_returns_all_columns(self): - """ - Test that get_columns returns all columns. - """ - - channel_messages_table = ChannelMessagesTable(self.api_handler) - - self.assertListEqual(channel_messages_table.get_columns(), ms_teams_handler_config.CHANNEL_MESSAGES_TABLE_COLUMNS) - - def test_select_star_for_single_channel_message_returns_all_columns(self): - # patch the api handler to return the channel message data - with patch.object(self.api_handler.connect(), 'get_channel_message', return_value=ms_teams_handler_config.TEST_CHANNEL_MESSAGE_DATA): - channel_messages_table = ChannelMessagesTable(self.api_handler) - - select_all = ast.Select( - # select all columns - targets=[Star()], - from_table="channel_messages", - where=[ - BinaryOperation( - op='=', - args=[ - Identifier('id'), - Constant("test_id") - ] - ), - BinaryOperation( - op='=', - args=[ - Identifier('channelIdentity_channelId'), - Constant("test_channel_id") - ] - ), - BinaryOperation( - op='=', - args=[ - Identifier('channelIdentity_teamId'), - Constant("test_team_id") - ] - ) - ] - ) - - all_channel_messages = channel_messages_table.select(select_all) - first_channel_message = all_channel_messages.iloc[0] - - self.assertEqual(all_channel_messages.shape[1], len(ms_teams_handler_config.CHANNEL_MESSAGES_TABLE_COLUMNS)) - self.assertEqual(first_channel_message["id"], "test_id") - self.assertEqual(first_channel_message["messageType"], "message") - - def test_select_star_for_all_channel_messages_returns_all_columns(self): - # patch the api handler to return the channel message data - with patch.object(self.api_handler.connect(), 'get_channel_messages', return_value=ms_teams_handler_config.TEST_CHANNEL_MESSAGES_DATA): - channel_messages_table = ChannelMessagesTable(self.api_handler) - - select_all = ast.Select( - # select all columns - targets=[Star()], - from_table="channel_messages", - ) - - all_channel_messages = channel_messages_table.select(select_all) - first_channel_message = all_channel_messages.iloc[0] - - self.assertEqual(all_channel_messages.shape[1], len(ms_teams_handler_config.CHANNEL_MESSAGES_TABLE_COLUMNS)) - self.assertEqual(first_channel_message["id"], "test_id") - self.assertEqual(first_channel_message["messageType"], "message") - - def test_select_for_single_channel_message_returns_only_selected_columns(self): - # patch the api handler to return the channel message data - with patch.object(self.api_handler.connect(), 'get_channel_message', return_value=ms_teams_handler_config.TEST_CHANNEL_MESSAGE_DATA): - channel_messages_table = ChannelMessagesTable(self.api_handler) - - select_all = ast.Select( - # select only the id and messageType columns - targets=[ - Identifier('id'), - Identifier('messageType'), - ], - from_table="channel_messages", - where=[ - BinaryOperation( - op='=', - args=[ - Identifier('id'), - Constant("test_id") - ] - ), - BinaryOperation( - op='=', - args=[ - Identifier('channelIdentity_channelId'), - Constant("test_channel_id") - ] - ), - BinaryOperation( - op='=', - args=[ - Identifier('channelIdentity_teamId'), - Constant("test_team_id") - ] - ) - ] - ) - - all_channel_messages = channel_messages_table.select(select_all) - first_channel_message = all_channel_messages.iloc[0] - - self.assertEqual(all_channel_messages.shape[1], 2) - self.assertEqual(first_channel_message["id"], "test_id") - self.assertEqual(first_channel_message["messageType"], "message") - - def test_select_for_all_channel_messages_returns_only_selected_columns(self): - # patch the api handler to return the channel message data - with patch.object(self.api_handler.connect(), 'get_channel_messages', return_value=ms_teams_handler_config.TEST_CHANNEL_MESSAGES_DATA): - channel_messages_table = ChannelMessagesTable(self.api_handler) - - select_all = ast.Select( - # select only the id and messageType columns - targets=[ - Identifier('id'), - Identifier('messageType'), - ], - from_table="channel_messages", - ) - - all_channel_messages = channel_messages_table.select(select_all) - first_channel_message = all_channel_messages.iloc[0] - - self.assertEqual(all_channel_messages.shape[1], 2) - self.assertEqual(first_channel_message["id"], "test_id") - self.assertEqual(first_channel_message["messageType"], "message") - - def test_insert_channel_message_calls_correct_method_in_client(self): - """ - Test that insert_channel_message calls the correct method in the client. - """ - - # patch the api handler to return the channel message data - with patch.object(self.api_handler.connect(), 'send_channel_message', return_value=None) as mock_send_channel_message: - channel_messages_table = ChannelMessagesTable(self.api_handler) - - insert = ast.Insert( - table="channel_messages", - columns=[ - Identifier('channelIdentity_teamId'), - Identifier('channelIdentity_channelId'), - Identifier('body_content'), - Identifier('subject'), - ], - values=[ - ( - "test_team_id", - "test_channel_id", - "test_message", - "test_subject" - ) - ] - ) - - channel_messages_table.insert(insert) - - # assert the api handler's send_channel_message method was called with the expected arguments - mock_send_channel_message.assert_called_once_with(group_id='test_team_id', channel_id='test_channel_id', message='test_message', subject='test_subject') - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/unused/unit/handler_tests/test_npm_handler.py b/tests/unused/unit/handler_tests/test_npm_handler.py deleted file mode 100644 index 44fffb13f4f..00000000000 --- a/tests/unused/unit/handler_tests/test_npm_handler.py +++ /dev/null @@ -1,86 +0,0 @@ -import importlib - -import pytest -from mindsdb_sql_parser import parse_sql - -from ..unit.executor_test_base import BaseExecutorTest - -try: - importlib.import_module("requests") - REQUESTS_INSTALLED = True -except ImportError: - REQUESTS_INSTALLED = False - - -@pytest.mark.skipif(not REQUESTS_INSTALLED, reason="requests package is not installed") -class TestNPMHandler(BaseExecutorTest): - - def run_sql(self, sql): - ret = self.command_executor.execute_command(parse_sql(sql)) - assert ret.error_code is None - if ret.data is not None: - return ret.data.to_df() - - def setup_method(self): - super().setup_method() - self.test_package_name = "handlebars" - self.run_sql(""" - CREATE DATABASE npm_test - WITH ENGINE = "npm"; - """) - - def test_basic_select_from(self): - # Select from metadata table - sql = f""" - SELECT * FROM npm_test.metadata WHERE package='{self.test_package_name}'; - """ - assert self.run_sql(sql).shape[0] == 1 - - # Select from maintainers table - sql = f""" - SELECT * FROM npm_test.maintainers WHERE package='{self.test_package_name}'; - """ - self.run_sql(sql) - - # Select from keywords table - sql = f""" - SELECT * FROM npm_test.keywords WHERE package='{self.test_package_name}'; - """ - self.run_sql(sql) - - # Select from dependencies table - sql = f""" - SELECT * FROM npm_test.dependencies WHERE package='{self.test_package_name}'; - """ - self.run_sql(sql) - - # Select from dev_dependencies table - sql = f""" - SELECT * FROM npm_test.dev_dependencies WHERE package='{self.test_package_name}'; - """ - self.run_sql(sql) - - # Select from optional_dependencies table - sql = f""" - SELECT * FROM npm_test.optional_dependencies WHERE package='{self.test_package_name}'; - """ - self.run_sql(sql) - - # Select from github_stats table - sql = f""" - SELECT * FROM npm_test.github_stats WHERE package='{self.test_package_name}'; - """ - assert self.run_sql(sql).shape[0] == 1 - - def test_complex_select(self): - # Select email maintainers table - sql = f""" - SELECT email FROM npm_test.maintainers WHERE package='{self.test_package_name}'; - """ - assert self.run_sql(sql).shape[1] == 1 - - # Select single dependency - sql = f""" - SELECT * FROM npm_test.dependencies WHERE package='{self.test_package_name}' LIMIT 1; - """ - assert self.run_sql(sql).shape[0] == 1 diff --git a/tests/unused/unit/handler_tests/test_oilpriceapi_handler.py b/tests/unused/unit/handler_tests/test_oilpriceapi_handler.py deleted file mode 100644 index 907a171cab0..00000000000 --- a/tests/unused/unit/handler_tests/test_oilpriceapi_handler.py +++ /dev/null @@ -1,47 +0,0 @@ -import importlib -import os -import pytest -from mindsdb_sql_parser import parse_sql - -from ..unit.executor_test_base import BaseExecutorTest - -try: - importlib.import_module("requests") - REQUESTS_INSTALLED = True -except ImportError: - REQUESTS_INSTALLED = False - - -@pytest.mark.skipif(not REQUESTS_INSTALLED, reason="requests package is not installed") -class TestOilPriceAPIHandler(BaseExecutorTest): - - def run_sql(self, sql): - ret = self.command_executor.execute_command(parse_sql(sql)) - assert ret.error_code is None - if ret.data is not None: - return ret.data.to_df() - - def setup_method(self): - super().setup_method() - self.api_key = os.environ.get("OILPRICEAPI_KEY") - self.run_sql(f""" - CREATE DATABASE mindsdb_oilpriceapi - WITH ENGINE = 'oilpriceapi', - PARAMETERS = { - "api_key": '{self.api_key}' - }; - """) - - def test_basic_select_from(self): - sql = "SELECT * FROM mindsdb_oilpriceapi.latest_price;" - assert self.run_sql(sql).shape[0] == 1 - - sql = "SELECT * FROM mindsdb_oilpriceapi.past_day_price;" - assert self.run_sql(sql).shape[0] == 20 - - def test_complex_select(self): - sql = 'SELECT price FROM mindsdb_oilpriceapi.latest_price where by_type="daily_average_price" and by_code="WTI_USD";' - assert self.run_sql(sql).shape[1] == 1 - - sql = "SELECT * FROM npm_test.past_day_price LIMIT 1;" - assert self.run_sql(sql).shape[0] == 1 diff --git a/tests/unused/unit/handler_tests/test_paypal_handler.py b/tests/unused/unit/handler_tests/test_paypal_handler.py deleted file mode 100644 index cc02e8bb676..00000000000 --- a/tests/unused/unit/handler_tests/test_paypal_handler.py +++ /dev/null @@ -1,46 +0,0 @@ -import os -import unittest - -from mindsdb.integrations.handlers.paypal_handler.paypal_handler import PayPalHandler -from mindsdb.api.executor.data_types.response_type import RESPONSE_TYPE - - -class PayPalHandlerTest(unittest.TestCase): - - @classmethod - def setUpClass(cls): - cls.kwargs = { - "connection_data": { - "mode": os.environ.get('MODE'), - "client_id": os.environ.get('CLIENT_ID'), - "client_secret": os.environ.get('CLIENT_SECRET'), - } - } - cls.handler = PayPalHandler('test_paypal_handler', **cls.kwargs) - - def test_0_check_connection(self): - assert self.handler.check_connection() - - def test_1_get_tables(self): - tables = self.handler.get_tables() - assert tables.type is not RESPONSE_TYPE.ERROR - - def test_2_select_payments_query(self): - query = "SELECT * FROM test_paypal_handler.payments" - result = self.handler.native_query(query) - assert result.type is RESPONSE_TYPE.TABLE - - def test_3_select_invoices_query(self): - query = "SELECT * FROM test_paypal_handler.invoices" - result = self.handler.native_query(query) - assert result.type is RESPONSE_TYPE.TABLE - - def test_4_select_subscriptions_query(self): - query = "SELECT * FROM test_paypal_handler.subscriptions" - result = self.handler.native_query(query) - assert result.type is RESPONSE_TYPE.TABLE - - def test_5_select_orders_query(self): - query = "SELECT * FROM test_paypal_handler.orders WHERE ids = ('')" - result = self.handler.native_query(query) - assert result.type is RESPONSE_TYPE.TABLE diff --git a/tests/unused/unit/handler_tests/test_pgvector_handler.py b/tests/unused/unit/handler_tests/test_pgvector_handler.py deleted file mode 100644 index cc520bc4ee8..00000000000 --- a/tests/unused/unit/handler_tests/test_pgvector_handler.py +++ /dev/null @@ -1,134 +0,0 @@ -import os -import psycopg2 -import pytest - -from mindsdb.integrations.handlers.pgvector_handler.pgvector_handler import PgVectorHandler - - -TEST_DB_NAME = os.environ.get('MDB_TEST_PGVECTOR_DATABASE', 'pgvector_handler_test_db') -# Should match table name in data/pgvector/seed.sql -TEST_TABLE_NAME = 'items' -# Should match column names in data/pgvector/seed.sql -COLUMN_NAMES = ['id', 'content', 'embeddings', 'metadata'] - -HANDLER_KWARGS = { - 'connection_data': { - 'host': os.environ.get('MDB_TEST_PGVECTOR_HOST', '127.0.0.1'), - 'port': os.environ.get('MDB_TEST_PGVECTOR_PORT', '5432'), - 'user': os.environ.get('MDB_TEST_PGVECTOR_USER', 'postgres'), - 'password': os.environ.get('MDB_TEST_PGVECTOR_PASSWORD', 'supersecret'), - 'database': TEST_DB_NAME - } -} - - -def init_db(): - '''Seed the test DB with some data''' - conn_info = HANDLER_KWARGS['connection_data'].copy() - conn_info['database'] = 'postgres' - db = psycopg2.connect(**conn_info) - db.autocommit = True - cursor = db.cursor() - - try: - cursor.execute(f'DROP DATABASE IF EXISTS {TEST_DB_NAME};') - db.commit() - - # Create the test database - cursor.execute(f'CREATE DATABASE {TEST_DB_NAME};') - db.commit() - - # Reconnect to the new database - conn_info['database'] = TEST_DB_NAME - db = psycopg2.connect(**conn_info) - db.autocommit = True - cursor = db.cursor() - - # Seed the database with data - curr_dir = os.path.dirname(os.path.realpath(__file__)) - seed_sql_path = os.path.join(curr_dir, 'data', 'pgvector', 'seed.sql') - with open(seed_sql_path, 'r') as sql_seed_file: - cursor.execute(sql_seed_file.read()) - db.commit() - - finally: - # Close the cursor and the connection - cursor.close() - db.close() - - -@pytest.fixture(scope='module') -def handler(): - init_db() - handler = PgVectorHandler('test_handler', **HANDLER_KWARGS) - yield handler - - -@pytest.mark.skipif(os.environ.get('MDB_TEST_PGVECTOR_HOST') is None, reason='MDB_TEST_PGVECTOR_HOST environment variable not set') -class TestPgvectorConnection: - def test_connect(self, handler): - handler.connect() - assert handler.is_connected, 'connection error' - - def test_check_connection(self, handler): - res = handler.check_connection() - assert res.success, res.error_message - - -@pytest.mark.skipif(os.environ.get('MDB_TEST_PGVECTOR_HOST') is None, reason='MDB_TEST_PGVECTOR_HOST environment variable not set') -class TestPgvectorQuery: - def test_select(self, handler): - result = handler.select(TEST_TABLE_NAME) - assert not result.empty - for col in COLUMN_NAMES: - assert col in result.columns - - def test_hybrid_search_with_keywords(self, handler): - result = handler.hybrid_search( - TEST_TABLE_NAME, - # Embeddings (semantic) search. - [7.0, 8.0, 9.0], - # Keyword search. - query='cat rat' - ) - # Top result is an exact embeddings match. - assert result.iloc[0]['embeddings'].tolist() == [7.0, 8.0, 9.0] - # Top result should include both keywords. - assert 'cat' in result.iloc[0]['content'] - assert 'rat' in result.iloc[0]['content'] - - def test_hybrid_search_with_metadata(self, handler): - result = handler.hybrid_search( - TEST_TABLE_NAME, - # Embeddings (semantic) search. - [4.0, 5.0, 6.0], - # Metadata filters. - metadata={'location': 'Wonderland', 'author': 'Taishan'} - ) - # Only two items match metadata filters. - assert len(result.index) == 2 - # Top result is an exact embeddings match. - assert result.iloc[0]['embeddings'].tolist() == [4.0, 5.0, 6.0] - - def test_hybrid_search_with_keywords_and_metadata(self, handler): - result = handler.hybrid_search( - TEST_TABLE_NAME, - # Embeddings (semantic) search. - [4.0, 5.0, 6.0], - # Keyword search. - query='fat cat', - # Metadata filters. - metadata={'location': 'Wonderland', 'author': 'Taishan'} - ) - # Only two items match metadata filters. - assert len(result.index) == 2 - # Top result is actually a keyword match because embeddings are close. - assert result.iloc[0]['embeddings'].tolist() == [1.0, 2.0, 3.0] - - def test_hybrid_search_no_query_or_metadata(self, handler): - with pytest.raises(ValueError): - _ = handler.hybrid_search( - TEST_TABLE_NAME, - # Embeddings (semantic) search. - [4.0, 5.0, 6.0], - ) diff --git a/tests/unused/unit/handler_tests/test_pinecone_handler.py b/tests/unused/unit/handler_tests/test_pinecone_handler.py deleted file mode 100644 index 46def1b070a..00000000000 --- a/tests/unused/unit/handler_tests/test_pinecone_handler.py +++ /dev/null @@ -1,274 +0,0 @@ -# check if chroma_db is installed -import importlib -from unittest.mock import patch -import os - -import pandas as pd -import pytest -from mindsdb_sql_parser import parse_sql - -from tests.unit.executor_test_base import BaseExecutorTest - -try: - pinecone = importlib.import_module("pinecone") - PINECONE_CLIENT_INSTALLED = True -except ImportError: - PINECONE_CLIENT_INSTALLED = False - - -# NOTE: These tests might fail since pinecone is eventually consistent. Some queries return wrong result when tested - -@pytest.mark.skipif(not PINECONE_CLIENT_INSTALLED, reason="pinecone client is not installed") -class TestPineconeHandler(BaseExecutorTest): - - def run_sql(self, sql): - ret = self.command_executor.execute_command(parse_sql(sql)) - assert ret.error_code is None - if ret.data is not None: - return ret.data.to_df() - - def setup_method(self): - super().setup_method() - # Replace with your pinecone key - self.api_key = os.environ['PINECONE_API_KEY'] - self.environment = os.environ['PINECONE_ENV'] - self.run_sql(f""" - CREATE DATABASE pinecone_test - WITH ENGINE = "pinecone", - PARAMETERS = {{ - "api_key": "{self.api_key}", - "environment": "{self.environment}" - }} - """) - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_create_with_select(self, postgres_handler_mock): - df = pd.DataFrame( - { - "id": ["id1", "id2"], - "content": ["this is a test", "this is a test"], - "metadata": [{"test": "test"}, {"test": "test"}], - "embeddings": [[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0], [1.0, 2.0, 3.0, 5.0, 6.0, 8.0, 9.0, 3.0]], - } - ) - - self.set_handler(postgres_handler_mock, "pg", tables={"df": df}) - sql = """ - CREATE TABLE pinecone_test.testtable ( - SELECT * FROM pg.df - ) - """ - self.run_sql(sql) - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_select_from(self, postgres_handler_mock): - df = pd.DataFrame( - { - "id": ["id1", "id2"], - "content": ["this is a test", "this is a test"], - "metadata": [{"test": "test"}, {"test": "test"}], - "embeddings": [[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0], [1.0, 2.0, 3.0, 5.0, 6.0, 8.0, 9.0, 3.0]], - } - ) - - self.set_handler(postgres_handler_mock, "pg", tables={"testtable": df}) - sql = """ - CREATE TABLE pinecone_test.testtable ( - SELECT * FROM pg.df - ) - """ - self.run_sql(sql) - - # query a table with id - sql = """ - SELECT * FROM pinecone_test.testtable - WHERE id = 'id1' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - - # query a table with a search vector, with out limit - sql = """ - SELECT * FROM pinecone_test.testtable - WHERE search_vector = '[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - - # query a table with a search vector, with limit - sql = """ - SELECT * FROM pinecone_test.testtable - WHERE search_vector = '[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]' - LIMIT 1 - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 1 - - # query a table with a metadata filter and a search vector - sql = """ - SELECT * FROM pinecone_test.testtable - WHERE testable.metadata.test = 'test' - AND search_vector = '[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_insert_into(self, postgres_handler_mock): - df = pd.DataFrame( - { - "id": ["id1", "id2"], - "content": ["this is a test", "this is a test"], - "metadata": [{"test": "test"}, {"test": "test"}], - "embeddings": [[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0], [1.0, 2.0, 3.0, 5.0, 6.0, 8.0, 9.0, 3.0]], - } - ) - - df2 = pd.DataFrame( - { - "id": ["id1", "id2", "id3"], - "content": ["this is a test", "this is a test", "this is a test"], - "metadata": [{"test": "test1"}, {"test": "test2"}, {"test": "test3"}], - "embeddings": [ - [1.0, 2.0, 3.0, 4.0, 3.0, 5.0, 2.0, 8.1], - [4.0, 2.0, 7.0, 4.0, 2.0, 5.0, 2.0, 9.0], - [5.0, 2.0, 3.0, 2.0, 3.0, 3.0, 2.0, 7.0], - ], - } - ) - self.set_handler(postgres_handler_mock, "pg", tables={"df": df, "df2": df2}) - - sql = """ - CREATE TABLE pinecone_test.testtable ( - SELECT * FROM pg.df - ) - """ - self.run_sql(sql) - - sql = """ - INSERT INTO pinecone_test.testtable ( - id,content,metadata,embeddings - ) - VALUES ( - 'some_unique_id', 'this is a test', '{"test": "test"}', '[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]' - ) - """ - self.run_sql(sql) - # check if the data is inserted - sql = """ - SELECT * FROM pinecone_test.testtable - WHERE id = 'some_unique_id' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 3 - - # insert into a table with existing id, shall work - sql = """ - INSERT INTO pinecone_test.testtable ( - id,content,metadata,embeddings - ) - VALUES ( - 'id1', 'this is a test', '{"test": "tester"}', '[1.0, 2.0, 3.0, 4.0, 6.0, 7.0, 8.0, 9.0]' - ) - """ - self.run_sql(sql) - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_delete(self, postgres_handler_mock): - df = pd.DataFrame( - { - "id": ["id1", "id2"], - "content": ["this is a test", "this is a test"], - "metadata": [{"test": "test1"}, {"test": "test2"}], - "embeddings": [[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0], [1.0, 2.0, 3.0, 5.0, 6.0, 8.0, 9.0, 3.0]], - } - ) - self.set_handler(postgres_handler_mock, "pg", tables={"testtable": df}) - - # create a table - sql = """ - CREATE TABLE pinecone_test.testtable ( - SELECT * FROM pg.df - ) - """ - self.run_sql(sql) - - # delete from a table with a metadata filter - sql = """ - DELETE FROM pinecone_test.testtable - WHERE testtable.metadata.test = 'test1' - """ - self.run_sql(sql) - - # delete by id - sql = """ - DELETE FROM pinecone_test.testtable - WHERE id = 'id2' - """ - self.run_sql(sql) - - # delete from a table without any filters is not allowed - sql = """ - DELETE FROM pinecone_test.testtable - """ - with pytest.raises(Exception): - self.run_sql(sql) - - @pytest.mark.xfail(reason="update for pinecone is not implemented, use insert") - def test_update(self): - # update a table with a metadata filter - sql = """ - UPDATE pinecone_test.testtable - SET metadata.test = 'test2' - WHERE metadata.test = 'test' - """ - # sql shoudl fail - with pytest.raises(Exception): - self.run_sql(sql) - - @pytest.mark.xfail(reason="create table for vectordatabase is not well supported") - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_create_table(self, postgres_handler_mock): - # create an empty table - sql = """ - CREATE TABLE pinecone_test.testtable; - """ - self.run_sql(sql) - # create a table with the schema definition is not allowed - sql = """ - CREATE TABLE pinecone_test.testtable ( - id int, - metadata text, - embedding float[] - ); - """ - with pytest.raises(Exception): - self.run_sql(sql) - - @pytest.mark.xfail(reason="drop table for vectordatabase is not working") - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_drop_table(self, postgres_handler_mock): - df = pd.DataFrame( - { - "id": ["id1", "id2"], - "content": ["this is a test", "this is a test"], - "metadata": [{"test": "test"}, {"test": "test"}], - "embeddings": [[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0], [1.0, 2.0, 3.0, 5.0, 6.0, 8.0, 9.0, 3.0]], - } - ) - self.set_handler(postgres_handler_mock, "pg", tables={"testtable": df}) - sql = """ - CREATE TABLE piecone_test.testtable( - SELECT * FROM pg.df - ) - """ - self.run_sql(sql) - sql = """ - DROP TABLE pinecone_test.testtable; - """ - self.run_sql(sql) - sql = """ - DROP TABLE pinecone_test.testtable2; - """ - with pytest.raises(Exception): - self.run_sql(sql) diff --git a/tests/unused/unit/handler_tests/test_qdrant_handler.py b/tests/unused/unit/handler_tests/test_qdrant_handler.py deleted file mode 100644 index 205fb9db392..00000000000 --- a/tests/unused/unit/handler_tests/test_qdrant_handler.py +++ /dev/null @@ -1,442 +0,0 @@ -from unittest.mock import patch - -import pytest -import pandas as pd -from mindsdb_sql_parser import parse_sql - -from tests.unit.executor_test_base import BaseExecutorTest - - -class TestQdrantHandler(BaseExecutorTest): - def run_sql(self, sql): - ret = self.command_executor.execute_command(parse_sql(sql)) - - assert ret.error_code is None - if ret.data is not None: - return ret.data.to_df() - - def setup_method(self): - super().setup_method() - # connect to a Qdrant instance and create a database - self.run_sql( - """ - CREATE DATABASE qtest - WITH ENGINE = "qdrant", - PARAMETERS = { - "location": ":memory:", - "collection_config": { - "size": 3, - "distance": "Cosine" - } - } - """ - ) - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_create_with_select(self, postgres_handler_mock): - df = pd.DataFrame( - { - - "id": [1, 2], - "content": ["this is a test", "this is a test"], - "metadata": [{"test": "test"}, {"test": "test"}], - "embeddings": [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0]], - } - ) - - self.set_handler(postgres_handler_mock, "pg", tables={"test_table": df}) - - sql = """ - CREATE TABLE qtest.test_table_1 ( - SELECT * FROM pg.df - ) - """ - self.run_sql(sql) - - @pytest.mark.xfail(reason="drop table for vectordatabase is not working") - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_drop_table(self, postgres_handler_mock): - df = pd.DataFrame( - { - "id": [32, 13], - "content": ["this is a test", "this is a test"], - "metadata": [{"test": "test"}, {"test": "test"}], - "embeddings": [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0]], - } - ) - self.set_handler(postgres_handler_mock, "pg", tables={"test_table": df}) - - # create a table - sql = """ - CREATE TABLE qtest.test_table_2 ( - SELECT * FROM pg.df - ) - """ - self.run_sql(sql) - - sql = """ - DROP TABLE qtest.test_table_2; - """ - self.run_sql(sql) - - sql = """ - DROP TABLE qtest.test_table_22; - """ - with pytest.raises(Exception): - self.run_sql(sql) - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_insert_into(self, postgres_handler_mock): - df = pd.DataFrame( - { - "id": [81, 24, 33], - "content": ["this is a test", "this is a test", "this is a test"], - "metadata": [{"test": "test1"}, {"test": "test2"}, {"test": "test3"}], - "embeddings": [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0], [1.0, 2.0, 3.0]], - } - ) - df2 = pd.DataFrame( - { - "id": [1, 2, 3], - "content": ["this is a test", "this is a test", "this is a test"], - "metadata": [{"test": "test1"}, {"test": "test2"}, {"test": "test3"}], - "embeddings": [ - [1.0, 2.0, 3.0, 4.0], - [1.0, 2.0], - [1.0, 2.0, 3.0], - ], # different dimensions - } - ) - self.set_handler(postgres_handler_mock, "pg", tables={"df": df, "df2": df2}) - num_record = df.shape[0] - - # create a table - sql = """ - CREATE TABLE qtest.test_table_3 ( - SELECT * FROM pg.df - ) - """ - self.run_sql(sql) - - # insert into a table with values - sql = """ - INSERT INTO qtest.test_table_3 ( - id,content,metadata,embeddings - ) - VALUES ( - 4, 'this is a test', '{"test": "test"}', '[1.0, 2.0, 3.0]' - ) - """ - self.run_sql(sql) - # check if the data is inserted - sql = """ - SELECT * FROM qtest.test_table_3 - WHERE id = 4 AND search_vector = '[1.0, 2.0, 3.0]' AND search_vector= '[1.0, 2.0, 4.0]' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 1 - - # insert without ids should auto-generate ids - sql = """ - INSERT INTO qtest.test_table_3 ( - content,metadata,embeddings - ) - VALUES ( - 'this is a test without ID', '{"test": "test"}', '[1.0, 2.0, 3.0]' - ) - """ - self.run_sql(sql) - - # check if the data is inserted - sql = """ - SELECT * FROM qtest.test_table_3 - """ - ret = self.run_sql(sql) - assert ret.shape[0] == num_record + 2 - - # insert into a table with a select statement - sql = """ - INSERT INTO qtest.test_table_3 ( - content,metadata,embeddings - ) - SELECT - content,metadata,embeddings - FROM - pg.df - """ - self.run_sql(sql) - - # check if the data is inserted - sql = """ - SELECT * FROM qtest.test_table_3 - """ - ret = self.run_sql(sql) - assert ret.shape[0] == num_record * 2 + 2 - - # insert into a table with a select statement, but wrong columns - sql = """ - INSERT INTO qtest.test_table_3 - SELECT - content,metadata,embeddings as wrong_column - FROM - pg.df - """ - with pytest.raises(Exception): - self.run_sql(sql) - - # insert into a table with a select statement, missing metadata column - sql = """ - INSERT INTO qtest.test_table_3 - SELECT - content,embeddings - FROM - pg.df - """ - self.run_sql(sql) - - # insert into a table with a select statement, missing embedding column, shall raise an error - sql = """ - INSERT INTO qtest.test_table_3 - SELECT - content,metadata - FROM - pg.df - """ - with pytest.raises(Exception): - self.run_sql(sql) - - # insert into a table with a select statement, with different embedding dimensions, shall raise an error - sql = """ - INSERT INTO qtest.test_table_3 - SELECT - content,metadata,embeddings - FROM - pg.df2 - """ - with pytest.raises(Exception): - self.run_sql(sql) - - # insert into a table with existing id overwrites the existing record - sql = """ - INSERT INTO qtest.test_table_3 ( - id,content,metadata,embeddings - ) - VALUES ( - 4, 'this is a test', '{"test": "test"}', '[1.0, 2.0, 3.0]' - ) - """ - self.run_sql(sql) - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_select_from(self, postgres_handler_mock): - df = pd.DataFrame( - { - "id": [32, 33], - "content": ["this is a test", "this is a test"], - "metadata": [{"test": "Info"}, {"test": "Info"}], - "embeddings": [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0]], - } - ) - self.set_handler(postgres_handler_mock, "pg", tables={"test_table": df}) - # create a table - sql = """ - CREATE TABLE qtest.test_table_4 ( - SELECT * FROM pg.df - ) - """ - self.run_sql(sql) - - # query a table without any filters - sql = """ - SELECT * FROM qtest.test_table_4 - """ - self.run_sql(sql) - - # query a table with id - sql = """ - SELECT * FROM qtest.test_table_4 - WHERE id = 32 - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 1 - - # query a table with a search vector, without limit - sql = """ - SELECT * FROM qtest.test_table_4 - WHERE search_vector = '[1.0, 2.0, 3.0]' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - - # query a table with a search vector, with limit - sql = """ - SELECT * FROM qtest.test_table_4 - WHERE search_vector = '[1.0, 2.0, 3.0]' - LIMIT 1 - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 1 - - # query a table with a metadata filter - sql = """ - SELECT * FROM qtest.test_table_4 - WHERE `metadata.test` = 'Info'; - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - - sql = """ - SELECT * FROM qtest.test_table_4 - WHERE `metadata.test` = 'Info' - AND search_vector = '[1.0, 2.0, 3.0]' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - - @pytest.mark.xfail(reason="upsert for vectordatabase is not implemented") - def test_update(self): - # update a table with a metadata filter - sql = """ - UPDATE qtest.test_table_5 - SET `metadata.test` = 'test2' - WHERE `metadata.test` = 'test' - """ - self.run_sql(sql) - # check if the data is updated - sql = """ - SELECT * FROM qtest.test_table_5 - WHERE `metadata.test` = 'test2' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - - # update the embeddings - sql = """ - UPDATE qtest.test_table_5 - SET embedding = [3.0, 2.0, 1.0] - WHERE `metadata.test` = 'test2' - """ - self.run_sql(sql) - # check if the data is updated - sql = """ - SELECT * FROM qtest.test_table_5 - WHERE `metadata.test` = 'test2' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - assert ret.embedding[0] == [3.0, 2.0, 1.0] - - # update multiple columns - sql = """ - UPDATE qtest.test_table_5 - SET `metadata.test` = 'test3', - embedding = [1.0, 2.0, 3.0] - content = 'this is a test' - WHERE `metadata.test` = 'test2' - """ - self.run_sql(sql) - # check if the data is updated - sql = """ - SELECT * FROM qtest.test_table_5 - WHERE `metadata.test` = 'test3' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - assert ret.embedding[0] == [1.0, 2.0, 3.0] - assert ret.content[0] == "this is a test" - - # update a table with a search vector filter is not allowed - sql = """ - UPDATE qtest.test_table_5 - SET `metadata.test = 'test2' - WHERE search_vector = [1.0, 2.0, 3.0] - """ - with pytest.raises(Exception): - self.run_sql(sql) - - # update a table without any filters is allowed - sql = """ - UPDATE qtest.test_table_5 - SET metadata.test = 'test3' - """ - self.run_sql(sql) - # check if the data is updated - sql = """ - SELECT * FROM qtest.test_table_5 - WHERE `metadata.test` = 'test3' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - - # update a table with a search vector filter and a metadata filter is not allowed - sql = """ - UPDATE qtest.test_table_5 - SET metadata.test = 'test3' - WHERE metadata.test = 'test2' - AND search_vector = [1.0, 2.0, 3.0] - """ - with pytest.raises(Exception): - self.run_sql(sql) - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_delete(self, postgres_handler_mock): - df = pd.DataFrame( - { - "id": [1, 2], - "content": ["this is a test", "this is a test"], - "metadata": [{"test": "test1"}, {"test": "test2"}], - "embeddings": [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0]], - } - ) - self.set_handler(postgres_handler_mock, "pg", tables={"test_table": df}) - - # create a table - sql = """ - CREATE TABLE qtest.test_table_6 ( - SELECT * FROM pg.df - ) - """ - self.run_sql(sql) - - # delete from a table with a metadata filter - sql = """ - DELETE FROM qtest.test_table_6 - WHERE `metadata.test` = 'test1' - """ - self.run_sql(sql) - # check if the data is deleted - sql = """ - SELECT * FROM qtest.test_table_6 - WHERE `metadata.test` = 'test2' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 1 - - # delete by id - sql = """ - DELETE FROM qtest.test_table_6 - WHERE id = 2 - """ - self.run_sql(sql) - # check if the data is deleted - sql = """ - SELECT * FROM qtest.test_table_6 - WHERE id = 2 - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 0 - - # delete from a table with a search vector filter is not allowed - sql = """ - DELETE FROM qtest.test_table_6 - WHERE search_vector = [1.0, 2.0, 3.0] - """ - with pytest.raises(Exception): - self.run_sql(sql) - - # delete from a table without any filters is not allowed - sql = """ - DELETE FROM qtest.test_table_6 - """ - with pytest.raises(Exception): - self.run_sql(sql) diff --git a/tests/unused/unit/handler_tests/test_rag_pipelines.py b/tests/unused/unit/handler_tests/test_rag_pipelines.py deleted file mode 100644 index d2f884b8322..00000000000 --- a/tests/unused/unit/handler_tests/test_rag_pipelines.py +++ /dev/null @@ -1,53 +0,0 @@ -import pytest -import yaml -from langchain_core.documents import Document -from langchain_openai import ChatOpenAI, OpenAIEmbeddings - -from mindsdb.integrations.utilities.rag.rag_pipeline_builder import RAG -from pathlib import Path - -from mindsdb.integrations.utilities.rag.settings import DEFAULT_LLM_MODEL, RAGPipelineModel - -DEFAULT_LLM = ChatOpenAI(model_name=DEFAULT_LLM_MODEL, temperature=0) -DEFAULT_EMBEDDINGS = OpenAIEmbeddings() - -path = Path(__file__).parent -config_path = path / "data" / "rag_pipelines" -pipeline_configs = list(config_path.glob('*.yml')) - - -def create_test_documents(): - return [ - Document( - page_content="This is a test document", - metadata={"doc_id": "1"} - ), - Document( - page_content="This is also a test document", - metadata={"doc_id": "2"} - ), - Document( - page_content="This is another test document", - metadata={"doc_id": "3"} - ) - ] - - -@pytest.fixture(params=pipeline_configs, ids=lambda x: x.stem, scope='module') -def config(request): - with open(request.param, 'r') as file: - config = yaml.safe_load(file) - config['documents'] = create_test_documents() - config['llm'] = DEFAULT_LLM - config['embedding_model'] = DEFAULT_EMBEDDINGS - - return RAGPipelineModel(**config) - - -def test_rag_pipeline_creation(config): - rag = RAG(config) - result = rag.pipeline.invoke('test document') - - assert result is not None - assert isinstance(result, dict) - assert all(key in result for key in ['answer', 'context', 'question']) diff --git a/tests/unused/unit/handler_tests/test_rocket_chat_handler.py b/tests/unused/unit/handler_tests/test_rocket_chat_handler.py deleted file mode 100644 index 575ab17ab9a..00000000000 --- a/tests/unused/unit/handler_tests/test_rocket_chat_handler.py +++ /dev/null @@ -1,96 +0,0 @@ -from mindsdb.integrations.handlers.rocket_chat_handler.rocket_chat_tables import ( - RocketChatMessagesTable, -) -from mindsdb.integrations.handlers.rocket_chat_handler.rocket_chat_handler import ( - RocketChatHandler, -) -from mindsdb_sql_parser import ast -from mindsdb_sql_parser.ast.select.star import Star -from mindsdb_sql_parser.ast.select.identifier import Identifier - -from unittest.mock import Mock - -import pandas as pd -import unittest - - -class RocketChatMessagesTableTest(unittest.TestCase): - def test_get_columns_returns_all_columns(self): - api_handler = Mock(RocketChatHandler) - messages_table = RocketChatMessagesTable(api_handler) - # Order matters. - expected_columns = [ - "id", - "room_id", - "bot_id", - "text", - "username", - "name", - "sent_at", - ] - self.assertListEqual(messages_table.get_columns(), expected_columns) - - def test_select_returns_all_columns(self): - api_handler = Mock(RocketChatHandler) - api_handler.call_rocket_chat_api.return_value = pd.DataFrame( - [ - [ - "message_id_1", # id - "GENERAL", # room_id - "bot_id_1", # bot_id - "YEWWWWW", # text - "shoresey", # username - "Shore Keeso", # name - "2023-05-05T00:31:46.825Z", # sent_at - ] - ] - ) - messages_table = RocketChatMessagesTable(api_handler) - - select_all = ast.Select( - targets=[Star()], from_table="channel_messages", where='room_id = "GENERAL"' - ) - - all_messages = messages_table.select(select_all) - first_message = all_messages.iloc[0] - - self.assertEqual(all_messages.shape[1], 7) - self.assertEqual(first_message["id"], "message_id_1") - self.assertEqual(first_message["room_id"], "GENERAL") - self.assertEqual(first_message["bot_id"], "bot_id_1") - self.assertEqual(first_message["text"], "YEWWWWW") - self.assertEqual(first_message["username"], "shoresey") - self.assertEqual(first_message["name"], "Shore Keeso") - self.assertEqual(first_message["sent_at"], "2023-05-05T00:31:46.825Z") - - def test_select_returns_only_selected_columns(self): - api_handler = Mock(RocketChatHandler) - api_handler.call_rocket_chat_api.return_value = pd.DataFrame( - [ - [ - "message_id_1", # id - "GENERAL", # room_id - "bot_id_1", # bot_id - "YEWWWWW", # text - "shoresey", # username - "Shore Keeso", # name - "2023-05-05T00:31:46.825Z", # sent_at - ] - ] - ) - messages_table = RocketChatMessagesTable(api_handler) - - room_id_identifier = Identifier(path_str="room_id") - text_identifier = Identifier(path_str="text") - select_basic = ast.Select( - targets=[room_id_identifier, text_identifier], - from_table="channel_messages", - where='room_id = "GENERAL"', - ) - - all_messages = messages_table.select(select_basic) - first_message = all_messages.iloc[0] - - self.assertEqual(all_messages.shape[1], 2) - self.assertEqual(first_message["room_id"], "GENERAL") - self.assertEqual(first_message["text"], "YEWWWWW") diff --git a/tests/unused/unit/handler_tests/test_sap_erp_handler.py b/tests/unused/unit/handler_tests/test_sap_erp_handler.py deleted file mode 100644 index 4568907c150..00000000000 --- a/tests/unused/unit/handler_tests/test_sap_erp_handler.py +++ /dev/null @@ -1,240 +0,0 @@ -import importlib -import os - -import pytest -from mindsdb_sql_parser import parse_sql - -from ..unit.executor_test_base import BaseExecutorTest - -try: - importlib.import_module("requests") - REQUESTS_INSTALLED = True -except ImportError: - REQUESTS_INSTALLED = False - - -@pytest.mark.skipif(not REQUESTS_INSTALLED, reason="requests package is not installed") -class TestSAPERPHandler(BaseExecutorTest): - - def run_sql(self, sql): - ret = self.command_executor.execute_command(parse_sql(sql)) - assert ret.error_code is None - if ret.data is not None: - return ret.data.to_df() - - def setup_method(self): - super().setup_method() - self.base_url = os.environ.get("SAP_ERP_BASE_URL") - self.api_key = os.environ.get("SAP_ERP_API_KEY") - self.run_sql(f""" - CREATE DATABASE sap_datasource - WITH ENGINE = "sap_erp", - PARAMETERS = {{ - "api_key": '{self.api_key}', - "base_url": '{self.base_url}' - }}; - """) - - def test_basic_select_from(self): - sql = """ - SELECT * FROM sap_datasource.address_email_address; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.address_fax_number; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.address_home_page; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.address_phone_number; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.bp_addr_depdnt_intl_loc_number; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.bp_contact_to_address; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.bp_contact_to_func_and_dept; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.bp_credit_worthiness; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.bp_data_controller; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.bp_financial_services_extn; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.bp_financial_services_reporting; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.bp_fiscal_year_information; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.bp_relationship; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.bu_pa_address_usage; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.bu_pa_identification; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.bu_pa_industry; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.business_partner; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.business_partner_address; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.business_partner_contact; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.business_partner_payment_card; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.business_partner_rating; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.business_partner_role; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.business_partner_tax_number; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.business_partner_address_dependent_tax_number; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.cust_addr_depdnt_ext_identifier; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.customer; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.customer_company; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.customer_company_text; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.customer_dunning; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.customer_sales_area; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.customer_sales_area_tax; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.customer_sales_area_text; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.customer_tax_grouping; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.customer_text; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.customer_unloading_point; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.customer_withholding_tax; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.customer_sales_partner_func; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.customer_sales_area_addr_depdnt_info; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.customer_sales_area_addr_depdnt_tax_info; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.customer_unloading_point_addr_depdnt_info; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.supplier; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.supplier_company; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.supplier_company_text; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.supplier_dunning; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.supplier_partner_func; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.supplier_purchasing_org; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.supplier_purchasing_org_text; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.supplier_text; - """ - self.run_sql(sql) - sql = """ - SELECT * FROM sap_datasource.supplier_withholding_tax; - """ - self.run_sql(sql) - - def test_complex_select(self): - sql = """ - SELECT AddressID FROM sap_datasource.address_email_address; - """ - assert self.run_sql(sql).shape[1] == 1 diff --git a/tests/unused/unit/handler_tests/test_storage_handler.py b/tests/unused/unit/handler_tests/test_storage_handler.py deleted file mode 100644 index 1aba0fd5a35..00000000000 --- a/tests/unused/unit/handler_tests/test_storage_handler.py +++ /dev/null @@ -1,23 +0,0 @@ -import unittest - -from mindsdb.utilities.config import Config -from mindsdb.integrations.libs.storage_handler import RedisStorageHandler, SqliteStorageHandler - - -class StorageHandlerTest(unittest.TestCase): - def test_1_redis_storage(self): - store = RedisStorageHandler({'test_1_redis_storage': 'value'}, config={'host': 'localhost', 'port': '6379'}) - store.set('test_key', 42) - self.assertTrue(store.get('test_key') == 42) - self.assertRaises(Exception, store.get('test_key2')) - - def test_2_sqlite_storage(self): - config = Config() - name = 'test_2_sqlite_storage' - store = SqliteStorageHandler(context=name, config={ - 'path': config['paths']['root'], - 'name': name - }) - store.set('test_key', 42) - self.assertTrue(store.get('test_key') == 42) - self.assertRaises(Exception, store.get('test_key2')) diff --git a/tests/unused/unit/handler_tests/test_symbl_handler.py b/tests/unused/unit/handler_tests/test_symbl_handler.py deleted file mode 100644 index 2911d433674..00000000000 --- a/tests/unused/unit/handler_tests/test_symbl_handler.py +++ /dev/null @@ -1,57 +0,0 @@ -import importlib -import os -import pytest -from mindsdb_sql_parser import parse_sql - -from ..unit.executor_test_base import BaseExecutorTest - -try: - importlib.import_module("symbl") - SYMBL_INSTALLED = True -except ImportError: - SYMBL_INSTALLED = False - - -@pytest.mark.skipif(not SYMBL_INSTALLED, reason="symbl package is not installed") -class TestSymblAPIHandler(BaseExecutorTest): - - def run_sql(self, sql): - ret = self.command_executor.execute_command(parse_sql(sql)) - assert ret.error_code is None - if ret.data is not None: - return ret.data.to_df() - - def setup_method(self): - super().setup_method() - self.app_id = os.environ.get("SYMBL_APP_ID") - self.app_secret = os.environ.get("SYMBL_APP_SECRET") - self.run_sql(f""" - CREATE DATABASE mindsdb_symbl - WITH ENGINE = 'symbl', - PARAMETERS = { - "app_id": '{self.app_id}', - "app_secret": '{self.app_secret}' - }; - """) - - def test_basic_select_from(self): - - conversation_id = "5682305049034752" - - sql = f'SELECT * FROM mindsdb_symbl.get_messages where conversation_id="{conversation_id}"' - self.run_sql(sql) - - sql = f'SELECT * FROM mindsdb_symbl.get_topics where conversation_id="{conversation_id}"' - self.run_sql(sql) - - sql = f'SELECT * FROM mindsdb_symbl.get_questions where conversation_id="{conversation_id}"' - self.run_sql(sql) - - sql = f'SELECT * FROM mindsdb_symbl.get_analytics where conversation_id="{conversation_id}"' - self.run_sql(sql) - - sql = f'SELECT * FROM mindsdb_symbl.get_action_items where conversation_id="{conversation_id}"' - self.run_sql(sql) - - sql = f'SELECT * FROM mindsdb_symbl.get_follow_ups where conversation_id="{conversation_id}"' - self.run_sql(sql) diff --git a/tests/unused/unit/handler_tests/test_tripadvisor_handler.py b/tests/unused/unit/handler_tests/test_tripadvisor_handler.py deleted file mode 100644 index 51d7a02b833..00000000000 --- a/tests/unused/unit/handler_tests/test_tripadvisor_handler.py +++ /dev/null @@ -1,324 +0,0 @@ -from mindsdb.integrations.handlers.tripadvisor_handler.tripadvisor_handler import ( - TripAdvisorHandler, -) - -from mindsdb.integrations.handlers.tripadvisor_handler.tripadvisor_table import ( - SearchLocationTable, - LocationDetailsTable, - ReviewsTable, - PhotosTable, - NearbyLocationTable, -) - -from mindsdb_sql_parser import ast -from mindsdb_sql_parser.ast.select.star import Star -from mindsdb_sql_parser.ast.select.identifier import Identifier - -from unittest.mock import Mock - -import pandas as pd -import unittest - - -class SearchLocationTableTest(unittest.TestCase): - def test_get_columns_returns_all_columns(self): - api_handler = Mock(TripAdvisorHandler) - trades_table = SearchLocationTable(api_handler) - # Order matters. - expected_columns = [ - "location_id", - "name", - "distance", - "rating", - "bearing", - "street1", - "street2", - "city", - "state", - "country", - "postalcode", - "address_string", - "phone", - "latitude", - "longitude", - ] - self.assertListEqual(trades_table.get_columns(), expected_columns) - - def test_select_returns_some_columns(self): - api_handler = Mock(TripAdvisorHandler) - api_handler.call_tripadvisor_searchlocation_api.return_value = pd.DataFrame( - [ - [ - "186338", # locationId - "London", # name - "United Kingdom", # country - "London England", # address_string - ] - ] - ) - tripadvisor_table = SearchLocationTable(api_handler) - - select_all = ast.Select( - targets=[Star()], - from_table="searchLocationTable", - where='searchQuery = "London"', - ) - - all_location_data = tripadvisor_table.select(select_all) - first_data = all_location_data.iloc[0] - - self.assertEqual(first_data["locationId"], "186338") - self.assertEqual(first_data["name"], "London") - self.assertEqual(first_data["country"], "United Kingdom") - self.assertEqual(first_data["address_string"], "London England") - - -class LocationDetailsTableTest(unittest.TestCase): - def test_get_columns_returns_all_columns(self): - api_handler = Mock(TripAdvisorHandler) - trades_table = LocationDetailsTable(api_handler) - # Order matters. - expected_columns = [ - "location_id", - "distance", - "name", - "description", - "web_url", - "street1", - "street2", - "city", - "state", - "country", - "postalcode", - "address_string", - "latitude", - "longitude", - "timezone", - "email", - "phone", - "website", - "write_review", - "ranking_data", - "rating", - "rating_image_url", - "num_reviews", - "photo_count", - "see_all_photos", - "price_level", - "brand", - "parent_brand", - "ancestors", - "periods", - "weekday", - "features", - "cuisines", - "amenities", - "trip_types", - "styles", - "awards", - "neighborhood_info", - "parent_brand", - "brand", - "groups", - ] - self.assertListEqual(trades_table.get_columns(), expected_columns) - - def test_select_returns_some_columns(self): - api_handler = Mock(TripAdvisorHandler) - api_handler.call_tripadvisor_searchlocation_api.return_value = pd.DataFrame( - [ - [ - "23322232", # locationId - "La Polleria Alicante", # name - "We are revolutionizing Alicante! Come and try the waffle that is on everyone's mouth. Come and get your #pollofre or #pollolo, we are waiting for you!", # description - "https://www.tripadvisor.com/Restaurant_Review-g1064230-d23322232-Reviews-La_Polleria_Alicante-Alicante_Costa_Blanca_Province_of_Alicante_Valencian_Commu.html?m=66827", # web_url - ] - ] - ) - - tripadvisor_table = LocationDetailsTable(api_handler) - - select_all = ast.Select( - targets=[Star()], - from_table="locationDetailsTable", - where='searchQuery = "23322232"', - ) - - all_location_data = tripadvisor_table.select(select_all) - first_data = all_location_data.iloc[0] - - self.assertEqual(first_data["locationId"], "23322232") - self.assertEqual(first_data["name"], "La Polleria Alicante") - self.assertEqual( - first_data["description"], - "We are revolutionizing Alicante! Come and try the waffle that is on everyone's mouth. Come and get your #pollofre or #pollolo, we are waiting for you!", - ) - self.assertEqual( - first_data["web_url"], - "https://www.tripadvisor.com/Restaurant_Review-g1064230-d23322232-Reviews-La_Polleria_Alicante-Alicante_Costa_Blanca_Province_of_Alicante_Valencian_Commu.html?m=66827", - ) - - -class ReviewTableTest(unittest.TestCase): - def test_get_columns_returns_all_columns(self): - api_handler = Mock(TripAdvisorHandler) - trades_table = ReviewsTable(api_handler) - # Order matters. - expected_columns = [ - "id", - "lang", - "location_id", - "published_date", - "rating", - "helpful_votes", - "rating_image_url", - "url", - "trip_type", - "travel_date", - "text_review", - "title", - "owner_response", - "is_machine_translated", - "user", - "subratings", - ] - self.assertListEqual(trades_table.get_columns(), expected_columns) - - def test_select_returns_some_columns(self): - api_handler = Mock(TripAdvisorHandler) - api_handler.call_tripadvisor_searchlocation_api.return_value = pd.DataFrame( - [ - [ - "921095426", # id - "en", # lang - "99288", # location_id - "2023-10-13T09:48:46Z", # published_date - "1", # rating - "Check in is at 4:00 - my room wasn't ready until 9:00. I had no A/C on my first night and it was too late for engineering to fix it. I was offered a $40 discount from some ridiculous hoteL fee - that was a joke on a 700/night stay. I would not recommend this place at all.", # text review - "POOR CHECK -IN - NO A/C AND NO DISCOUNT", # title - ] - ] - ) - tripadvisor_table = ReviewsTable(api_handler) - - id_identifier = Identifier(path_str='id') - lang_identifier = Identifier(path_str='en') - location_id_identifier = Identifier(path_str='location_id') - published_date_identifier = Identifier(path_str='published_date') - rating_identifier = Identifier(path_str='rating') - text_review_identifier = Identifier(path_str='room_id') - title_identifier = Identifier(path_str='text') - select_all = ast.Select( - targets=[id_identifier, lang_identifier, location_id_identifier, published_date_identifier, rating_identifier, text_review_identifier, title_identifier], - from_table="reviewsTable", - where='locationId = "99288"', - ) - - review_data = tripadvisor_table.select(select_all) - first_data = review_data.iloc[0] - - self.assertEqual(review_data.shape[1], 7) - self.assertEqual(first_data["id"], "921095426") - self.assertEqual(first_data["en"], "en") - self.assertEqual(first_data["rating"], "1") - self.assertEqual(first_data["title"], "POOR CHECK -IN - NO A/C AND NO DISCOUNT") - - -class PhotosTableTest(unittest.TestCase): - def test_get_columns_returns_all_columns(self): - api_handler = Mock(TripAdvisorHandler) - trades_table = PhotosTable(api_handler) - # Order matters. - expected_columns = [ - "id", - "is_blessed", - "album", - "caption", - "published_date", - "images", - "source", - "user", - ] - self.assertListEqual(trades_table.get_columns(), expected_columns) - - def test_select_returns_some_columns(self): - api_handler = Mock(TripAdvisorHandler) - api_handler.call_tripadvisor_searchlocation_api.return_value = pd.DataFrame( - [ - [ - "673312657", # id - "false", # is_blessed - "Hotel & Grounds", # album - "{'name': 'Management', 'localized_name': 'Management'}", # source - ] - ] - ) - tripadvisor_table = PhotosTable(api_handler) - - id_identifier = Identifier(path_str='id') - is_blessed_identifier = Identifier(path_str='is_blessed') - album_identifier = Identifier(path_str='album') - source_identifier = Identifier(path_str='source') - select_all = ast.Select( - targets=[id_identifier, is_blessed_identifier, album_identifier, source_identifier], - from_table="photosTable", - where='locationId = "99288"', - ) - - all_location_data = tripadvisor_table.select(select_all) - first_data = all_location_data.iloc[0] - - self.assertEqual(all_location_data.shape[1], 4) - self.assertEqual(first_data["id"], "673312657") - self.assertEqual(first_data["is_blessed"], "false") - self.assertEqual(first_data["album"], "Hotel & Grounds") - self.assertEqual(first_data["source"], "{'name': 'Management', 'localized_name': 'Management'}") - - -class NearbySearchTableTest(unittest.TestCase): - def test_get_columns_returns_all_columns(self): - api_handler = Mock(TripAdvisorHandler) - trades_table = NearbyLocationTable(api_handler) - # Order matters. - expected_columns = [ - "location_id", - "name", - "distance", - "rating", - "bearing", - "address_obj", - ] - self.assertListEqual(trades_table.get_columns(), expected_columns) - - def test_select_returns_some_columns(self): - api_handler = Mock(TripAdvisorHandler) - api_handler.call_tripadvisor_searchlocation_api.return_value = pd.DataFrame( - [ - [ - "210108", # location_id - "American Museum of Natural History", # name - "0.039615104835680856", # distance - "{'street1': '79th Street', 'street2': 'Central Park West', 'city': 'New York City', 'state': 'New York', 'country': 'United States', 'postalcode': '10024', 'address_string': '79th Street Central Park West, New York City, NY 10024'}", # address_obj - ] - ] - ) - tripadvisor_table = NearbyLocationTable(api_handler) - - location_id_identifier = Identifier(path_str='location_id') - name_identifier = Identifier(path_str='name') - distance_identifier = Identifier(path_str='distance') - address_obj_identifier = Identifier(path_str='address_obj') - select_all = ast.Select( - targets=[location_id_identifier, name_identifier, distance_identifier, address_obj_identifier], - from_table="nearbyLocationTable", - where='latLong = "40.780825, -73.972781"', - ) - - all_location_data = tripadvisor_table.select(select_all) - first_data = all_location_data.iloc[0] - - self.assertEqual(all_location_data.shape[1], 4) - self.assertEqual(first_data["location_id"], "210108") - self.assertEqual(first_data["name"], "American Museum of Natural History") - self.assertEqual(first_data["distance"], "0.039615104835680856") - self.assertEqual(first_data["address_obj"], "{'street1': '79th Street', 'street2': 'Central Park West', 'city': 'New York City', 'state': 'New York', 'country': 'United States', 'postalcode': '10024', 'address_string': '79th Street Central Park West, New York City, NY 10024'}") diff --git a/tests/unused/unit/handler_tests/test_vectordatabase_dispatch.py b/tests/unused/unit/handler_tests/test_vectordatabase_dispatch.py deleted file mode 100644 index 3bf6b2d6b9a..00000000000 --- a/tests/unused/unit/handler_tests/test_vectordatabase_dispatch.py +++ /dev/null @@ -1,282 +0,0 @@ -from unittest.mock import Mock - -import pandas as pd -import pytest -from mindsdb_sql_parser import parse_sql -from pandas.testing import assert_frame_equal - -from mindsdb.integrations.libs.vectordatabase_handler import ( - FilterCondition, - FilterOperator, - VectorStoreHandler, -) - - -@pytest.fixture -def vector_store_handler(): - # patch the actual "execute" methods of the handler with Mock - vector_store_handler: VectorStoreHandler = VectorStoreHandler("test") - vector_store_handler.create_table = Mock() - vector_store_handler.drop_table = Mock() - vector_store_handler.insert = Mock() - vector_store_handler.update = Mock() - vector_store_handler.delete = Mock() - vector_store_handler.select = Mock() - - return vector_store_handler - - -def test_vectordatabase_parsing(vector_store_handler): - # create a table - # due to the limitation of the parser - # we can only create a table with a select statement - sql = """ - CREATE TABLE chroma_db.test_table ( - SELECT * - FROM chroma_db.test_table - ) - """ - query = parse_sql(sql) - vector_store_handler._dispatch(query) - vector_store_handler.create_table.assert_called_once() - vector_store_handler.create_table.assert_called_with( - "test_table", if_not_exists=False - ) - - # drop a table - sql = """ - DROP TABLE chroma_db.test_table - """ - query = parse_sql(sql) - vector_store_handler._dispatch(query) - vector_store_handler.drop_table.assert_called_once() - vector_store_handler.drop_table.assert_called_with("test_table", if_exists=False) - - # insert into a table - sql = """ - INSERT INTO chroma_db.test_table ( - id,content,metadata,embeddings - ) - VALUES ( - 1, 'test', '{"some_field": "some_value"}', '[1,2,3]' - ), - ( - 2, 'test', '{"some_field": "some_value"}', '[1,2,3]' - ) - """ - - data = pd.DataFrame( - { - "id": [1, 2], - "content": ["test", "test"], - "embeddings": [[1, 2, 3], [1, 2, 3]], - "metadata": [{"some_field": "some_value"}, {"some_field": "some_value"}], - } - ) - - query = parse_sql(sql) - vector_store_handler._dispatch(query) - vector_store_handler.insert.assert_called_once() - # get the args passed to the insert method - args, kwargs = vector_store_handler.insert.call_args - # get the data passed to the insert method - assert args[0] == "test_table" - data = args[1] - # assert the data is the same - assert_frame_equal(data, data) - assert kwargs["columns"] == ["id", "content", "metadata", "embeddings"] - - # select from a table - # select without filters - sql = """ - SELECT * - FROM chroma_db.test_table - """ - query = parse_sql(sql) - vector_store_handler._dispatch(query) - vector_store_handler.select.assert_called_once() - vector_store_handler.select.assert_called_with( - "test_table", - columns=["id", "content", "embeddings", "metadata"], - conditions=None, - offset=None, - limit=None, - ) - # select with search_vector filter - sql = """ - SELECT * - FROM chroma_db.test_table - WHERE search_vector = '[1, 2, 3]' - LIMIT 10 - """ - query = parse_sql(sql) - # reset the mock - vector_store_handler.select.reset_mock() - vector_store_handler._dispatch(query) - vector_store_handler.select.assert_called_once() - vector_store_handler.select.assert_called_with( - "test_table", - columns=["id", "content", "embeddings", "metadata"], - conditions=[ - FilterCondition( - column="search_vector", op=FilterOperator.EQUAL, value=[1, 2, 3] - ) - ], - limit=10, - offset=None, - ) - - # select with limit and offset - sql = """ - SELECT * - FROM chroma_db.test_table - LIMIT 10 - OFFSET 5 - """ - query = parse_sql(sql) - # reset the mock - vector_store_handler.select.reset_mock() - vector_store_handler._dispatch(query) - vector_store_handler.select.assert_called_once() - vector_store_handler.select.assert_called_with( - "test_table", - columns=["id", "content", "embeddings", "metadata"], - conditions=None, - limit=10, - offset=5, - ) - - # select with a subset of columns - sql = """ - SELECT id, content - FROM chroma_db.test_table - """ - query = parse_sql(sql) - # reset the mock - vector_store_handler.select.reset_mock() - vector_store_handler._dispatch(query) - vector_store_handler.select.assert_called_once() - vector_store_handler.select.assert_called_with( - "test_table", - columns=["id", "content"], - conditions=None, - limit=None, - offset=None, - ) - - # select with metadata filter - sql = """ - SELECT * - FROM chroma_db.test_table - WHERE metadata.created_at = '2021-01-01' - AND metadata.some_field in ('some_value', 'some_other_value') - AND search_vector = '[1, 2, 3]' - """ - query = parse_sql(sql) - # reset the mock - vector_store_handler.select.reset_mock() - vector_store_handler._dispatch(query) - vector_store_handler.select.assert_called_once() - vector_store_handler.select.assert_called_with( - "test_table", - columns=["id", "content", "embeddings", "metadata"], - conditions=[ - FilterCondition( - column="metadata.created_at", - op=FilterOperator.EQUAL, - value="2021-01-01", - ), - FilterCondition( - column="metadata.some_field", - op=FilterOperator.IN, - value=["some_value", "some_other_value"], - ), - FilterCondition( - column="search_vector", op=FilterOperator.EQUAL, value=[1, 2, 3] - ), - ], - limit=None, - offset=None, - ) - - # delete from a table - sql = """ - DELETE FROM chroma_db.test_table - WHERE id = 1 - """ - query = parse_sql(sql) - vector_store_handler._dispatch(query) - vector_store_handler.delete.assert_called_once() - vector_store_handler.delete.assert_called_with( - "test_table", - conditions=[FilterCondition(column="id", op=FilterOperator.EQUAL, value=1)], - ) - - -def test_unsupported_ops(vector_store_handler): - # select unsupported columns - sql = """ - SELECT id, some_column_not_supported - FROM chroma_db.test_table - """ - query = parse_sql(sql) - with pytest.raises(Exception) as e: - vector_store_handler._dispatch(query) - assert "not allowed" in str(e.value) - - # insert unsupported columns - sql = """ - INSERT INTO chroma_db.test_table ( - id, some_column_not_supported - ) - VALUES ( - 1, 'test' - ) - """ - query = parse_sql(sql) - with pytest.raises(Exception) as e: - vector_store_handler._dispatch(query) - assert "not allowed" in str(e.value) - - # unsupported filter - sql = """ - SELECT * - FROM chroma_db.test_table - WHERE metadata.created_at > '2021-01-01' - AND unknown_column = 'some_value' - """ - query = parse_sql(sql) - # reset the mock - vector_store_handler.select.reset_mock() - vector_store_handler._dispatch(query) - vector_store_handler.select.assert_called_once() - vector_store_handler.select.assert_called_with( - "test_table", - columns=["id", "content", "embeddings", "metadata"], - conditions=[ - FilterCondition( - column="metadata.created_at", - op=FilterOperator.GREATER_THAN, - value="2021-01-01", - ), - FilterCondition( - column="metadata.unknown_column", # we will treat this as a metadata filter - op=FilterOperator.EQUAL, - value="some_value", - ), - ], - limit=None, - offset=None, - ) - - -@pytest.mark.xfail(reason="not implemented yet") -def test_unimplemented_yet(vector_store_handler): - # select count(*) is not implemented yet - sql = """ - SELECT count(*) - FROM chroma_db.test_table - """ - query = parse_sql(sql) - with pytest.raises(Exception): - vector_store_handler._dispatch(query) diff --git a/tests/unused/unit/handler_tests/test_weaviate_handler.py b/tests/unused/unit/handler_tests/test_weaviate_handler.py deleted file mode 100644 index cf71e1dbc7f..00000000000 --- a/tests/unused/unit/handler_tests/test_weaviate_handler.py +++ /dev/null @@ -1,503 +0,0 @@ -# check if weaviate is installed -import re -import importlib -from unittest.mock import patch -import tempfile -import psutil -import pandas as pd -import pytest -from mindsdb_sql_parser import parse_sql - -from ..unit.executor_test_base import BaseExecutorTest - -try: - importlib.import_module("weaviate") - WEAVIATE_INSTALLED = True -except ImportError: - WEAVIATE_INSTALLED = False - - -@pytest.mark.skipif(not WEAVIATE_INSTALLED, reason="weaviate is not installed") -class TestWeaviateHandler(BaseExecutorTest): - def run_sql(self, sql): - ret = self.command_executor.execute_command(parse_sql(sql)) - - assert ret.error_code is None - if ret.data is not None: - return ret.data.to_df() - - def setup_method(self): - super().setup_method() - # create a weaviate database connection - tmp_directory = tempfile.mkdtemp() - self.run_sql( - f""" - CREATE DATABASE weaviate_test - WITH ENGINE = "weaviate", - PARAMETERS = {{ - "persistence_directory": "{tmp_directory}" - }} - """ - ) - - @staticmethod - def teardown_class(cls): - super().teardown_class(cls) - for proc in psutil.process_iter(): - # check whether the process name matches (kill orphan processes) - if re.search("weaviate*", proc.name()): - proc.kill() - - @pytest.mark.xfail(reason="create table for vectordatabase is not well supported") - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_create_table(self, postgres_handler_mock): - # create an empty table - sql = """ - CREATE TABLE weaviate_test.test_table; - """ - self.run_sql(sql) - - # create a table with the schema definition is not allowed - sql = """ - CREATE TABLE weaviate_test.test_table ( - id int, - metadata text, - embedding float[] - ); - """ - with pytest.raises(Exception): - self.run_sql(sql) - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_create_with_select(self, postgres_handler_mock): - df = pd.DataFrame( - { - "id": [ - "6af613b6-569c-5c22-9c37-2ed93f31d3af", - "b04965e6-a9bb-591f-8f8a-1adcb2c8dc39", - ], - "content": ["this is a test", "this is a test"], - "metadata": [{"test": "test"}, {"test": "test"}], - "embeddings": [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0]], - } - ) - - self.set_handler(postgres_handler_mock, "weaviate", tables={"test_table2": df}) - - sql = """ - CREATE TABLE weaviate_test.test_table2 ( - SELECT * FROM weaviate.df - ) - """ - # this should work - self.run_sql(sql) - - @pytest.mark.xfail(reason="drop table for vectordatabase is not working") - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_drop_table(self, postgres_handler_mock): - df = pd.DataFrame( - { - "id": [ - "4b166dbe-d99d-5091-abdd-95b83330ed3a", - "98123fde-012f-5ff3-8b50-881449dac91a", - ], - "content": ["this is a test", "this is a test"], - "metadata": [{"test": "test"}, {"test": "test"}], - "embeddings": [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0]], - } - ) - self.set_handler(postgres_handler_mock, "weaviate", tables={"test_table3": df}) - - # create a table - sql = """ - CREATE TABLE weaviate_test.test_table3 ( - SELECT * FROM weaviate.df - ) - """ - with pytest.raises(Exception): - self.run_sql(sql) - - # drop a table - sql = """ - DROP TABLE weaviate_test.test_table3; - """ - self.run_sql(sql) - - # drop a non existent table will raise an error - sql = """ - DROP TABLE weaviate_test.test_table4; - """ - with pytest.raises(Exception): - self.run_sql(sql) - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_insert_into(self, postgres_handler_mock): - df = pd.DataFrame( - { - "id": [ - "6ed955c6-506a-5343-9be4-2c0afae02eef", - "c8691da2-158a-5ed6-8537-0e6f140801f2", - "a6c4fc8f-6950-51de-a9ae-2c519c465071", - ], - "content": ["this is a test", "this is a test", "this is a test"], - "metadata": [{"test": "test1"}, {"test": "test2"}, {"test": "test3"}], - "embeddings": [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0], [1.0, 2.0, 3.0]], - } - ) - df2 = pd.DataFrame( - { - "id": [ - "a9f96b98-dd44-5216-ab0d-dbfc6b262edf", - "e99caacd-6c45-5906-bd9f-b79e62f25963", - "e4d80b30-151e-51b5-9f4f-18a3b82718e6", - ], - "content": ["this is a test", "this is a test", "this is a test"], - "metadata": [{"test": "test1"}, {"test": "test2"}, {"test": "test3"}], - "embeddings": [ - [1.0, 2.0, 3.0, 4.0], - [1.0, 2.0], - [1.0, 2.0, 3.0], - ], # different dimensions - } - ) - self.set_handler( - postgres_handler_mock, "weaviate", tables={"df": df, "df2": df2} - ) - num_record = df.shape[0] - - # create a table - sql = """ - CREATE TABLE weaviate_test.test_table5 ( - SELECT * FROM weaviate.df - ) - """ - self.run_sql(sql) - - # insert into a table with values - sql = """ - INSERT INTO weaviate_test.test_table5 ( - id,content,metadata,embeddings - ) - VALUES ( - '0159d6c7-973f-5e7a-a9a0-d195d0ea6fe2', 'this is a test', '{"test": "test"}', '[1.0, 2.0, 3.0]' - ) - """ - self.run_sql(sql) - # check if the data is inserted - sql = """ - SELECT * FROM weaviate_test.test_table5 - WHERE id = '0159d6c7-973f-5e7a-a9a0-d195d0ea6fe2' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 1 - - # insert without specifying id should also work - sql = """ - INSERT INTO weaviate_test.test_table5 ( - content,metadata,embeddings - ) - VALUES ( - 'this is a test', '{"test": "test"}', '[1.0, 2.0, 3.0]' - ) - """ - self.run_sql(sql) - # check if the data is inserted - sql = """ - SELECT * FROM weaviate_test.test_table5 - """ - ret = self.run_sql(sql) - assert ret.shape[0] == num_record + 2 - - # insert into a table with a select statement - sql = """ - INSERT INTO weaviate_test.test_table5 ( - content,metadata,embeddings - ) - SELECT - content,metadata,embeddings - FROM - weaviate.df - """ - self.run_sql(sql) - # check if the data is inserted - sql = """ - SELECT * FROM weaviate_test.test_table5 - """ - ret = self.run_sql(sql) - assert ret.shape[0] == num_record * 2 + 2 - - # insert into a table with a select statement, but wrong columns - with pytest.raises(Exception): - sql = """ - INSERT INTO weaviate_test.test_table5 - SELECT - content,metadata,embeddings as wrong_column - FROM - weaviate.df - """ - self.run_sql(sql) - - # insert into a table with a select statement, missing metadata column - sql = """ - INSERT INTO weaviate_test.test_table5 - SELECT - content,embeddings - FROM - weaviate.df - """ - self.run_sql(sql) - - # insert into a table with a select statement, missing embedding column, shall raise an error - with pytest.raises(Exception): - sql = """ - INSERT INTO weaviate_test.test_table5 - SELECT - content,metadata - FROM - weaviate.df - """ - self.run_sql(sql) - - # insert into a table with a select statement, with different embedding dimensions, shall raise an error - sql = """ - INSERT INTO weaviate_test.test_table5 - SELECT - content,metadata,embeddings - FROM - weaviate.df2 - """ - with pytest.raises(Exception): - self.run_sql(sql) - - # insert into a table with existing id, shall raise an error - sql = """ - INSERT INTO weaviate_test.test_table5 ( - id,content,metadata,embeddings - ) - VALUES ( - '6ed955c6-506a-5343-9be4-2c0afae02eef', 'this is a test', '{"test": "test"}', '[1.0, 2.0, 3.0]' - ) - """ - with pytest.raises(Exception): - self.run_sql(sql) - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_select_from(self, postgres_handler_mock): - df = pd.DataFrame( - { - "id": [ - "7fef88f7-411d-5669-b42d-bf5fc7f9b58b", - "52524d6e-10dc-5261-aa36-8b2efcbaa5f0", - ], - "content": ["this is a test", "this is a test"], - "metadata": [{"test": "test"}, {"test": "test"}], - "embeddings": [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0]], - } - ) - self.set_handler(postgres_handler_mock, "weaviate", tables={"test_table6": df}) - # create a table - sql = """ - CREATE TABLE weaviate_test.test_table6 ( - SELECT * FROM weaviate.df - ) - """ - self.run_sql(sql) - - # query a table without any filters - sql = """ - SELECT * FROM weaviate_test.test_table6 - """ - self.run_sql(sql) - - # query a table with id - sql = """ - SELECT * FROM weaviate_test.test_table6 - WHERE id = '7fef88f7-411d-5669-b42d-bf5fc7f9b58b' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 1 - - # query a table with a search vector, without limit - sql = """ - SELECT * FROM weaviate_test.test_table6 - WHERE search_vector = '[1.0, 2.0, 3.0]' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - - # query a table with a search vector, with limit - sql = """ - SELECT * FROM weaviate_test.test_table6 - WHERE search_vector = '[1.0, 2.0, 3.0]' - LIMIT 1 - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 1 - - # query a table with a metadata filter - sql = """ - SELECT * FROM weaviate_test.test_table6 - WHERE `metadata.test` = 'test' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - - # query a table with a metadata filter and a search vector - sql = """ - SELECT * FROM weaviate_test.test_table6 - WHERE `metadata.test` = 'test' - AND search_vector = '[1.0, 2.0, 3.0]' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - - @pytest.mark.xfail(reason="upsert for vectordatabase is not implemented") - def test_update(self): - # update a table with a metadata filter - sql = """ - UPDATE weaviate_test.test_table6 - SET `metadata.test` = 'test2' - WHERE `metadata.test` = 'test' - """ - self.run_sql(sql) - # check if the data is updated - sql = """ - SELECT * FROM weaviate_test.test_table6 - WHERE `metadata.test` = 'test2' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - - # update the embeddings - sql = """ - UPDATE weaviate_test.test_table6 - SET embedding = [3.0, 2.0, 1.0] - WHERE `metadata.test` = 'test2' - """ - self.run_sql(sql) - # check if the data is updated - sql = """ - SELECT * FROM weaviate_test.test_table6 - WHERE `metadata.test` = 'test2' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - assert ret.embedding[0] == [3.0, 2.0, 1.0] - - # update multiple columns - sql = """ - UPDATE weaviate_test.test_table6 - SET `metadata.test` = 'test3', - embedding = [1.0, 2.0, 3.0] - content = 'this is a test' - WHERE `metadata.test` = 'test2' - """ - self.run_sql(sql) - # check if the data is updated - sql = """ - SELECT * FROM weaviate_test.test_table6 - WHERE `metadata.test` = 'test3' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - assert ret.embedding[0] == [1.0, 2.0, 3.0] - assert ret.content[0] == "this is a test" - - # update a table with a search vector filter is not allowed - sql = """ - UPDATE weaviate_test.test_table6 - SET `metadata.test = 'test2' - WHERE search_vector = [1.0, 2.0, 3.0] - """ - with pytest.raises(Exception): - self.run_sql(sql) - - # update a table without any filters is allowed - sql = """ - UPDATE weaviate_test.test_table6 - SET metadata.test = 'test3' - """ - self.run_sql(sql) - # check if the data is updated - sql = """ - SELECT * FROM weaviate_test.test_table6 - WHERE `metadata.test` = 'test3' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - - # update a table with a search vector filter and a metadata filter is not allowed - sql = """ - UPDATE weaviate_test.test_table6 - SET metadata.test = 'test3' - WHERE metadata.test = 'test2' - AND search_vector = [1.0, 2.0, 3.0] - """ - with pytest.raises(Exception): - self.run_sql(sql) - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_delete(self, postgres_handler_mock): - df = pd.DataFrame( - { - "id": [ - "91c274f2-9a0d-5ce6-ac3d-7529f452df21", - "0ff1e264-520d-543a-87dd-181a491e667e", - ], - "content": ["this is a test", "this is a test"], - "metadata": [{"test": "test1"}, {"test": "test2"}], - "embeddings": [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0]], - } - ) - self.set_handler(postgres_handler_mock, "weaviate", tables={"test_table7": df}) - - # create a table - sql = """ - CREATE TABLE weaviate_test.test_table7 ( - SELECT * FROM weaviate.df - ) - """ - self.run_sql(sql) - - # delete from a table with a metadata filter - sql = """ - DELETE FROM weaviate_test.test_table7 - WHERE `metadata.test` = 'test1' - """ - self.run_sql(sql) - # check if the data is deleted - sql = """ - SELECT * FROM weaviate_test.test_table7 - WHERE `metadata.test` = 'test2' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 1 - - # delete by id - sql = """ - DELETE FROM weaviate_test.test_table7 - WHERE id = '0ff1e264-520d-543a-87dd-181a491e667e' - """ - self.run_sql(sql) - # check if the data is deleted - sql = """ - SELECT * FROM weaviate_test.test_table7 - WHERE id = '0ff1e264-520d-543a-87dd-181a491e667e' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 0 - - # delete from a table with a search vector filter is not allowed - sql = """ - DELETE FROM weaviate_test.test_table7 - WHERE search_vector = [1.0, 2.0, 3.0] - """ - with pytest.raises(Exception): - self.run_sql(sql) - - # delete from a table without any filters is not allowed - sql = """ - DELETE FROM weaviate_test.test_table7 - """ - with pytest.raises(Exception): - self.run_sql(sql) diff --git a/tests/unused/unit/handler_tests/test_webz_handler.py b/tests/unused/unit/handler_tests/test_webz_handler.py deleted file mode 100644 index 6cc22fc7e69..00000000000 --- a/tests/unused/unit/handler_tests/test_webz_handler.py +++ /dev/null @@ -1,227 +0,0 @@ -import unittest -from unittest.mock import Mock - -import pandas as pd -from mindsdb_sql_parser import parse_sql - -from mindsdb.integrations.handlers.webz_handler.webz_handler import WebzHandler -from mindsdb.integrations.handlers.webz_handler.webz_tables import ( - WebzPostsTable, - WebzReviewsTable, -) - -COLUMNS_POST = [ - "thread__uuid", - "thread__url", - "thread__site_full", - "thread__site", - "thread__site_section", - "thread__section_title", - "thread__title", - "thread__title_full", - "thread__published", - "thread__replies_count", - "thread__participants_count", - "thread__site_type", - "thread__main_image", - "thread__country", - "thread__site_categories", - "thread__social__facebook__likes", - "thread__social__facebook__shares", - "thread__social__facebook__comments", - "thread__social__gplus__shares", - "thread__social__pinterest__shares", - "thread__social__linkedin__shares", - "thread__social__stumbledupon__shares", - "thread__social__vk__shares", - "thread__performance_score", - "thread__domain_rank", - "thread__domain_rank_updated", - "thread__reach__per_million", - "thread__reach__page_views", - "thread__reach__updated", - "uuid", - "url", - "ord_in_thread", - "parent_url", - "author", - "published", - "title", - "text", - "language", - "external_links", - "external_images", - "rating", - "entities__persons", - "entities__organizations", - "entities__locations", - "crawled", -] - - -SAMPLE_POST = { - "thread__uuid": "e893796adad8a85e6ab5202ac34b5791c8fbb017", - "thread__url": "https://www.economist.com/business/2023/06/06/generative-ai-could-radically-alter-the-practice-of-law", - "thread__site_full": "https://www.economist.com", - "thread__site": "economist.com", -} - - -class WebzPostsTableTest(unittest.TestCase): - def test_get_columns_returns_all_columns(self): - webz_handler = Mock(WebzHandler) - posts_table = WebzPostsTable(webz_handler) - # Order matters. - expected_columns = COLUMNS_POST - self.assertListEqual(posts_table.get_columns(), expected_columns) - - def test_select_with_query_order_by_and_limit(self): - webz_handler = Mock(WebzHandler) - webz_handler.call_webz_api.return_value = pd.DataFrame([SAMPLE_POST]) - posts_table = WebzPostsTable(webz_handler) - query = parse_sql( - "SELECT * FROM posts WHERE query='language:english' ORDER BY posts.relevancy LIMIT 10", - ) - results = posts_table.select(query) - first_result = results.iloc[0] - webz_handler.call_webz_api.assert_called_once_with( - method_name="posts", - params={ - "q": "language:english", - "sort": "relevancy", - "order": "default", - "size": 10, - }, - ) - self.assertEqual(results.shape[1], len(COLUMNS_POST)) - for column in COLUMNS_POST: - self.assertEqual(first_result[column], SAMPLE_POST.get(column, None)) - - def test_select_with_targets(self): - webz_handler = Mock(WebzHandler) - webz_handler.call_webz_api.return_value = pd.DataFrame([SAMPLE_POST]) - posts_table = WebzPostsTable(webz_handler) - target_field = "thread__uuid" - query = parse_sql( - f"SELECT {target_field} FROM posts", - ) - results = posts_table.select(query) - first_result = results.iloc[0] - webz_handler.call_webz_api.assert_called_once_with( - method_name="posts", - params={}, - ) - self.assertEqual(results.shape[1], 1) - self.assertEqual(first_result[target_field], SAMPLE_POST[target_field]) - - def test_select_with_invalid_order_by_field_fails(self): - webz_handler = Mock(WebzHandler) - webz_handler.call_webz_api.return_value = pd.DataFrame([SAMPLE_POST]) - posts_table = WebzPostsTable(webz_handler) - query = parse_sql( - "SELECT thread__uuid FROM posts ORDER BY posts.invalid_field", - ) - with self.assertRaises(ValueError) as context: - posts_table.select(query) - self.assertEqual( - str(context.exception), "Order by unknown column invalid_field" - ) - - -COLUMNS_REVIEW = [ - "item__uuid", - "item__url", - "item__site_full", - "item__site", - "item__site_section", - "item__section_title", - "item__title", - "item__title_full", - "item__published", - "item__reviews_count", - "item__reviewers_count", - "item__main_image", - "item__country", - "item__site_categories", - "item__domain_rank", - "item__domain_rank_updated", - "uuid", - "url", - "ord_in_thread", - "author", - "published", - "title", - "text", - "language", - "external_links", - "rating", - "crawled", -] - - -SAMPLE_REVIEW = { - "item__uuid": "3bf76e1cee69da4e89ec88d5f0f23d0b66f4b5c6", - "item__url": "https://www.watsons.com.my/baking-soda-laundry-detergent/p/BP_56634", - "item__site_full": "www.watsons.com.my", - "uuid": "d6afd2c04c995f34d9003cea353d7f5e01fcce0b", -} - - -class WebzReviewsTableTest(unittest.TestCase): - def test_get_columns_returns_all_columns(self): - webz_handler = Mock(WebzHandler) - reviews_table = WebzReviewsTable(webz_handler) - expected_columns = COLUMNS_REVIEW - self.assertListEqual(reviews_table.get_columns(), expected_columns) - - def test_select_with_query_order_by_and_limit(self): - webz_handler = Mock(WebzHandler) - webz_handler.call_webz_api.return_value = pd.DataFrame([SAMPLE_REVIEW]) - reviews_table = WebzReviewsTable(webz_handler) - query = parse_sql( - "SELECT * FROM reviews WHERE query='language:english' ORDER BY reviews.reviews_count LIMIT 10", - ) - results = reviews_table.select(query) - first_result = results.iloc[0] - webz_handler.call_webz_api.assert_called_once_with( - method_name="reviews", - params={ - "q": "language:english", - "sort": "reviews_count", - "order": "default", - "size": 10, - }, - ) - self.assertEqual(results.shape[1], len(COLUMNS_REVIEW)) - for column in COLUMNS_REVIEW: - self.assertEqual(first_result[column], SAMPLE_REVIEW.get(column, None)) - - def test_select_with_targets(self): - webz_handler = Mock(WebzHandler) - webz_handler.call_webz_api.return_value = pd.DataFrame([SAMPLE_REVIEW]) - reviews_table = WebzReviewsTable(webz_handler) - target_field = "uuid" - query = parse_sql( - f"SELECT {target_field} FROM reviews", - ) - results = reviews_table.select(query) - first_result = results.iloc[0] - webz_handler.call_webz_api.assert_called_once_with( - method_name="reviews", - params={}, - ) - self.assertEqual(results.shape[1], 1) - self.assertEqual(first_result[target_field], SAMPLE_REVIEW[target_field]) - - def test_select_with_invalid_order_by_field_fails(self): - webz_handler = Mock(WebzHandler) - webz_handler.call_webz_api.return_value = pd.DataFrame([SAMPLE_REVIEW]) - reviews_table = WebzReviewsTable(webz_handler) - query = parse_sql( - "SELECT item__uuid FROM reviews ORDER BY reviews.invalid_field", - ) - with self.assertRaises(ValueError) as context: - reviews_table.select(query) - self.assertEqual( - str(context.exception), "Order by unknown column invalid_field" - ) diff --git a/tests/unused/unit/handler_tests/test_xata_handler.py b/tests/unused/unit/handler_tests/test_xata_handler.py deleted file mode 100644 index c0192795f5b..00000000000 --- a/tests/unused/unit/handler_tests/test_xata_handler.py +++ /dev/null @@ -1,413 +0,0 @@ -import os -import importlib -from unittest.mock import patch - -import pandas as pd -import pytest -from mindsdb_sql_parser import parse_sql - -from mindsdb.tests.unit.executor_test_base import BaseExecutorTest - -try: - xata = importlib.import_module("xata") - XATA_INSTALLED = True -except ImportError: - XATA_INSTALLED = False - - -@pytest.mark.skipif(not XATA_INSTALLED, reason="xata is not installed") -class TestXetaHandler(BaseExecutorTest): - - def run_sql(self, sql): - ret = self.command_executor.execute_command(parse_sql(sql)) - assert ret.error_code is None - if ret.data is not None: - return ret.data.to_df() - - def setup_method(self): - super().setup_method() - self.api_key = os.environ['XATA_TESTING_API_KEY'] - self.db_url = os.environ['XATA_TESTING_DB_URL'] - self.run_sql(f""" - CREATE DATABASE xata_test - WITH - ENGINE = 'xata', - PARAMETERS = {{ - "api_key": "{self.api_key}", - "db_url": "{self.db_url}", - "dimension": 3 - }}; - """) - self._client = xata.XataClient(api_key=self.api_key, db_url=self.db_url) - - def drop_table(self, table_name): - resp = self._client.table().delete(table_name) - if not resp.is_success(): - print(f"Unable to delete {table_name}: {resp['message']}") - - def get_num_records(self, table_name): - return self._client.search_and_filter().summarize(table_name, {"columns": [], "summaries": {"total": {"count": "*"}}})["summaries"][0]["total"] - - @pytest.mark.xfail(reason="create table for vectordatabase is not well supported") - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_create_table(self, postgres_handler_mock): - # create an empty table - sql = """CREATE TABLE xata_test.testingtable;""" - self.run_sql(sql) - # create a table with the schema definition is not allowed - sql = """ - CREATE TABLE xata_test.testingtable ( - id int, - metadata text, - embedding float[] - ); - """ - with pytest.raises(Exception): - self.run_sql(sql) - - @pytest.mark.xfail(reason="drop table for vectordatabase is not working") - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_drop_table(self, postgres_handler_mock): - df = pd.DataFrame( - { - "id": ["id1", "id2"], - "content": ["this is a test", "this is a test"], - "metadata": [{"test": "test"}, {"test": "test"}], - "embeddings": [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0]], - } - ) - self.set_handler(postgres_handler_mock, "pg", tables={"testingtable": df}) - # create a table - sql = """ - CREATE TABLE xata_test.testingtable ( - SELECT * FROM pg.df - ) - """ - self.run_sql(sql) - # drop a table - sql = """ - DROP TABLE xata_test.testingtable; - """ - self.run_sql(sql) - - @pytest.mark.xfail(reason="update for vectordatabase is not implemented") - def test_update(self): - # update a table with a metadata filter - sql = """ - UPDATE xata_test.testingtable - SET metadata.test = 'test2' - WHERE metadata.test = 'test' - """ - self.run_sql(sql) - # check if the data is updated - sql = """ - SELECT * FROM xata_test.testingtable - WHERE metadata.test = 'test2' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - # update the embeddings - sql = """ - UPDATE xata_test.testingtable - SET embedding = '[3.0, 2.0, 1.0]' - WHERE metadata.test = 'test2' - """ - self.run_sql(sql) - # check if the data is updated - sql = """ - SELECT * FROM xata_test.testingtable - WHERE metadata.test = 'test2' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - assert ret.embedding[0] == [3.0, 2.0, 1.0] - # update multiple columns - sql = """ - UPDATE xata_test.testingtable - SET metadata.test = 'test3', - embedding = '[1.0, 2.0, 3.0]' - content = 'this is a test' - WHERE metadata.test = 'test2' - """ - self.run_sql(sql) - # check if the data is updated - sql = """ - SELECT * FROM xata_test.testingtable - WHERE metadata.test = 'test3' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - assert ret.embedding[0] == [1.0, 2.0, 3.0] - assert ret.content[0] == "this is a test" - # update a table with a search vector filter is not allowed - sql = """ - UPDATE xata_test.testingtable - SET metadata.test = 'test2' - WHERE search_vector = '[1.0, 2.0, 3.0]' - """ - with pytest.raises(Exception): - self.run_sql(sql) - # update a table without any filters is allowed - sql = """ - UPDATE xata_test.testingtable - SET metadata.test = 'test3' - """ - self.run_sql(sql) - # check if the data is updated - sql = """ - SELECT * FROM xata_test.testingtable - WHERE metadata.test = 'test3' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - # update a table with a search vector filter and a metadata filter is not allowed - sql = """ - UPDATE xata_test.testingtable - SET metadata.test = 'test3' - WHERE metadata.test = 'test2' - AND search_vector = '[1.0, 2.0, 3.0]' - """ - with pytest.raises(Exception): - self.run_sql(sql) - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_create_with_select(self, postgres_handler_mock): - df = pd.DataFrame( - { - "id": ["id1", "id2"], - "content": ["this is a test", "this is a test"], - "metadata": ['{"test": "test"}', '{"test": "test"}'], - "embeddings": [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0]], - } - ) - self.set_handler(postgres_handler_mock, "pg", tables={"testingtable": df}) - sql = """ - CREATE TABLE xata_test.testingtable (SELECT * FROM pg.df) - """ - self.drop_table("testingtable") - # this should work - self.run_sql(sql) - assert self.get_num_records("testingtable") == 2 - self.drop_table("testingtable") - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_insert_into(self, postgres_handler_mock): - df = pd.DataFrame( - { - "id": ["id1", "id2", "id3"], - "content": ["this is a test", "this is a test", "this is a test"], - "metadata": ['{"test": "test1"}', '{"test": "test2"}', '{"test": "test3"}'], - "embeddings": [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0], [1.0, 2.0, 3.0]], - } - ) - df2 = pd.DataFrame( - { - "id": ["id4", "id5", "id6"], - "content": ["this is a test", "this is a test", "this is a test"], - "metadata": [{"test": "test1"}, {"test": "test2"}, {"test": "test3"}], - "embeddings": [ - [1.0, 2.0, 3.0], - [1.0, 2.0, 4.0], - [5.0, 2.0, 3.0], - ], - } - ) - self.set_handler(postgres_handler_mock, "pg", tables={"df": df, "df2": df2}) - # create a table - sql = """ - CREATE TABLE xata_test.testingtable (SELECT * FROM pg.df) - """ - self.drop_table("testingtable") - self.run_sql(sql) - # insert into a table with values - sql = """ - INSERT INTO xata_test.testingtable (id,content,metadata,embeddings) - VALUES ('some_unique_id', 'this is a test', '{"test": "test"}', '[1.0, 2.0, 3.0]') - """ - self.run_sql(sql) - self.get_num_records("testingtable") == 4 - # insert without specifying id should also work - sql = """ - INSERT INTO xata_test.testingtable (content,metadata,embeddings) - VALUES ('this is a test', '{"test": "test"}', '[1.0, 2.0, 3.0]') - """ - self.run_sql(sql) - self.get_num_records("testingtable") == 5 - # insert into a table with a select statement - sql = """ - INSERT INTO xata_test.testingtable (content,metadata,embeddings) - SELECT content,metadata,embeddings FROM pg.df2 - """ - self.run_sql(sql) - self.get_num_records("testingtable") == 8 - # insert into a table with a select statement, but wrong columns - with pytest.raises(Exception): - sql = """ - INSERT INTO xata_test.testingtable - SELECT (content,metadata,embeddings as wrong_column) FROM pg.df - """ - self.run_sql(sql) - # insert into a table with a select statement, missing metadata column - sql = """ - INSERT INTO xata_test.testingtable - SELECT content,embeddings FROM pg.df - """ - self.run_sql(sql) - self.get_num_records("testingtable") == 11 - # insert into a table with a select statement, with different embedding dimensions, shall raise an error - sql = """ - INSERT INTO xata_test.testingtable - VALUES ('this is a test', '{"test": "test"}', '[1.0, 2.0, 3.0, 4.0]') - """ - with pytest.raises(Exception): - self.run_sql(sql) - self.drop_table("testingtable") - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_general_select_queries(self, postgres_handler_mock): - df = pd.DataFrame( - { - "id": ["id1", "id2", "id3", "id4", "id5", "id6"], - "content": ["test content", "test paragraph", "toast types", "", "tast misspelled", "hello"], - "metadata": ['{"price": 10}', '{"price": 100}', '{"price": 30}', '{"test": "test1"}', '{"test": "test2"}', '{"test": "test3"}'], - "embeddings": [[1.0, 2.0, 3.0], [5.0, 2.0, 8.0], [3.0, 6.0, 3.0], [1.0, 2.0, 3.0], [3.0, 1.0, 8.0], [1.0, 3.0, 7.0]], - } - ) - self.set_handler(postgres_handler_mock, "pg", tables={"testingtable": df}) - # create a table - sql = """ - CREATE TABLE xata_test.testingtable (SELECT * FROM pg.df) - """ - self.drop_table("testingtable") - self.run_sql(sql) - # query a table without any filters - sql = """ - SELECT * FROM xata_test.testingtable - """ - assert self.run_sql(sql).shape[0] == 6 - # query a table with limit - sql = """ - SELECT * FROM xata_test.testingtable - LIMIT 2 - """ - assert self.run_sql(sql).shape[0] == 2 - # query a table with id - sql = """ - SELECT * FROM xata_test.testingtable - WHERE id = 'id1' - """ - assert self.run_sql(sql).shape[0] == 1 - # query a table with a metadata filter - sql = """ - SELECT * FROM xata_test.testingtable - WHERE testingtable.metadata.test = 'test1' - """ - assert self.run_sql(sql).shape[0] == 1 - # query a table with a metadata complex filter - sql = """ - SELECT * FROM xata_test.testingtable - WHERE testingtable.metadata.price > 10 AND testingtable.metadata.price <= 100 - """ - assert self.run_sql(sql).shape[0] == 2 - # query a table with a content filter - sql = """ - SELECT * FROM xata_test.testingtable - WHERE content = 'test content' - """ - assert self.run_sql(sql).shape[0] == 1 - # query a table with a content filter - sql = """ - SELECT * FROM xata_test.testingtable - WHERE content = 'test content' - """ - assert self.run_sql(sql).shape[0] == 1 - # query a table with like operator - sql = """ - SELECT * FROM xata_test.testingtable - WHERE content LIKE 'test%' - """ - assert self.run_sql(sql).shape[0] == 2 - self.drop_table("testingtable") - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_vector_search(self, postgres_handler_mock): - df = pd.DataFrame( - { - "id": ["id1", "id2", "id3", "id4", "id5", "id6"], - "content": ["test content", "test paragraph", "toast types", "", "tast misspelled", "hello"], - "metadata": ['{"price": 10}', '{"price": 100}', '{"price": 30}', '{"test": "test1"}', '{"test": "test2"}', '{"test": "test3"}'], - "embeddings": [[1.0, 2.0, 3.0], [5.0, 2.0, 8.0], [3.0, 6.0, 3.0], [1.0, 2.0, 3.0], [3.0, 1.0, 8.0], [1.0, 3.0, 7.0]], - } - ) - self.set_handler(postgres_handler_mock, "pg", tables={"testingtable": df}) - # create a table - sql = """ - CREATE TABLE xata_test.testingtable ( - SELECT * FROM pg.df - ) - """ - self.drop_table("testingtable") - self.run_sql(sql) - # query a table with a search vector, without limit - sql = """ - SELECT * FROM xata_test.testingtable - WHERE search_vector = '[1.0, 2.0, 3.0]' - """ - assert self.run_sql(sql).shape[0] == 6 - # query a table with a search vector, with limit - sql = """ - SELECT * FROM xata_test.testingtable - WHERE search_vector = '[1.0, 2.0, 3.0]' - LIMIT 1 - """ - assert self.run_sql(sql).shape[0] == 1 - # query a table with a search vector, and content column - sql = """ - SELECT * FROM xata_test.testingtable - WHERE search_vector = '[1.0, 2.0, 3.0]' - AND content LIKE 'test%' - """ - assert self.run_sql(sql).shape[0] == 2 - # query a table with a metadata filter and a search vector does not work - sql = """ - SELECT * FROM xata_test.testingtable - WHERE metadata.price < 200 - AND search_vector = '[1.0, 2.0, 3.0]' - """ - with pytest.raises(Exception): - self.run_sql(sql) - self.drop_table("testingtable") - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_delete(self, postgres_handler_mock): - df = pd.DataFrame( - { - "id": ["id1", "id2", "id3", "id4", "id5", "id6"], - "content": ["test content", "test paragraph", "toast types", "", "tast misspelled", "hello"], - "metadata": ['{"price": 10}', '{"price": 100}', '{"price": 30}', '{"test": "test1"}', '{"test": "test2"}', '{"test": "test3"}'], - "embeddings": [[1.0, 2.0, 3.0], [5.0, 2.0, 8.0], [3.0, 6.0, 3.0], [1.0, 2.0, 3.0], [3.0, 1.0, 8.0], [1.0, 3.0, 7.0]], - } - ) - self.set_handler(postgres_handler_mock, "pg", tables={"testingtable": df}) - # create a table - sql = """ - CREATE TABLE xata_test.testingtable ( - SELECT * FROM pg.df - ) - """ - self.drop_table("testingtable") - self.run_sql(sql) - # delete by id - sql = """ - DELETE FROM xata_test.testingtable - WHERE id = 'id2' - """ - self.run_sql(sql) - self.get_num_records("testingtable") == 5 - # delete non existant passes - sql = """ - DELETE FROM xata_test.testingtable - WHERE id = 'id9' - """ - self.run_sql(sql) - self.drop_table("testingtable") diff --git a/tests/unused/unit/handler_tests/test_zipcodebase_handler.py b/tests/unused/unit/handler_tests/test_zipcodebase_handler.py deleted file mode 100644 index fa1c72992cf..00000000000 --- a/tests/unused/unit/handler_tests/test_zipcodebase_handler.py +++ /dev/null @@ -1,47 +0,0 @@ -import importlib -import os -import pytest -from mindsdb_sql_parser import parse_sql - -from ..unit.executor_test_base import BaseExecutorTest - -try: - importlib.import_module("requests") - REQUESTS_INSTALLED = True -except ImportError: - REQUESTS_INSTALLED = False - - -@pytest.mark.skipif(not REQUESTS_INSTALLED, reason="requests package is not installed") -class TestZipCodeBaseHandler(BaseExecutorTest): - - def run_sql(self, sql): - ret = self.command_executor.execute_command(parse_sql(sql)) - assert ret.error_code is None - if ret.data is not None: - return ret.data.to_df() - - def setup_method(self): - super().setup_method() - self.api_key = os.environ.get("ZIPCODEBASE_API_KEY") - self.run_sql(f""" - CREATE DATABASE mindsdb_zipcodebase - WITH ENGINE = 'zipcodebase', - PARAMETERS = { - "api_key": '{self.api_key}' - }; - """) - - def test_basic_select_from(self): - sql = "SELECT * FROM mindsdb_zipcodebase.code_to_location where codes='10005';" - self.run_sql(sql) - - sql = 'SELECT * FROM mindsdb_zipcodebase.codes_within_radius WHERE code="10005" AND radius="100" AND country="us";' - self.run_sql(sql) - - def test_complex_select(self): - sql = 'SELECT state FROM mindsdb_zipcodebase.codes_within_radius WHERE code="10005" AND radius="100" AND country="us";' - assert self.run_sql(sql).shape[1] == 6 - - sql = "SELECT * FROM mindsdb_zipcodebase.code_to_location where codes='10005'; LIMIT 1;" - assert self.run_sql(sql).shape[0] == 1 diff --git a/tests/unused/unit/handler_tests/test_zotero_handler.py b/tests/unused/unit/handler_tests/test_zotero_handler.py deleted file mode 100644 index ceae6780595..00000000000 --- a/tests/unused/unit/handler_tests/test_zotero_handler.py +++ /dev/null @@ -1,175 +0,0 @@ -import unittest -from unittest.mock import Mock, patch -import pandas as pd -from mindsdb_sql_parser import ast -from mindsdb_sql_parser import parse_sql -from mindsdb.integrations.handlers.zotero_handler.zotero_handler import ZoteroHandler -from mindsdb.integrations.handlers.zotero_handler.zotero_tables import AnnotationsTable - - -class AnnotationsTableTest(unittest.TestCase): - def setUp(self): - self.api_handler = Mock(ZoteroHandler) - self.annotations_table = AnnotationsTable(self.api_handler) - - def test_get_columns_returns_all_columns(self): - expected_columns = [ - 'annotationColor', 'annotationComment', 'annotationPageLabel', 'annotationText', - 'annotationType', 'dateAdded', 'dateModified', 'key', 'parentItem', - 'relations', 'tags', 'version' - ] - self.assertListEqual(self.annotations_table.get_columns(), expected_columns) - - @patch.object(AnnotationsTable, '_get_items') - def test_select_returns_all_columns(self, mock_get_items): - mock_get_items.return_value = pd.DataFrame([ - { - 'annotationColor': 'red', - 'annotationComment': 'comment', - 'annotationPageLabel': 'page1', - 'annotationText': 'text', - 'annotationType': 'highlight', - 'dateAdded': '2023-01-01', - 'dateModified': '2023-01-02', - 'key': '12345', - 'parentItem': '67890', - 'relations': {}, - 'tags': [], - 'version': 1 - } - ]) - - select_all = ast.Select( - targets=[ast.Star()], - from_table='annotations' - ) - - result = self.annotations_table.select(select_all) - first_row = result.iloc[0] - - self.assertEqual(result.shape[1], 12) - self.assertEqual(first_row['annotationColor'], 'red') - self.assertEqual(first_row['annotationComment'], 'comment') - self.assertEqual(first_row['annotationPageLabel'], 'page1') - self.assertEqual(first_row['annotationText'], 'text') - self.assertEqual(first_row['annotationType'], 'highlight') - self.assertEqual(first_row['dateAdded'], '2023-01-01') - self.assertEqual(first_row['dateModified'], '2023-01-02') - self.assertEqual(first_row['key'], '12345') - self.assertEqual(first_row['parentItem'], '67890') - self.assertEqual(first_row['relations'], {}) - self.assertEqual(first_row['tags'], []) - self.assertEqual(first_row['version'], 1) - - @patch.object(AnnotationsTable, '_get_item') - def test_select_with_conditions_item_id(self, mock_get_item): - mock_get_item.return_value = pd.DataFrame([ - { - 'annotationColor': 'blue', - 'annotationComment': 'another comment', - 'annotationPageLabel': 'page2', - 'annotationText': 'another text', - 'annotationType': 'underline', - 'dateAdded': '2023-03-01', - 'dateModified': '2023-03-02', - 'key': '54321', - 'parentItem': '09876', - 'relations': {}, - 'tags': [], - 'version': 2 - } - ]) - - select_query = parse_sql('SELECT * FROM annotations WHERE item_id = "12345"') - - result = self.annotations_table.select(select_query) - first_row = result.iloc[0] - - self.assertEqual(result.shape[1], 12) - self.assertEqual(first_row['annotationColor'], 'blue') - self.assertEqual(first_row['annotationComment'], 'another comment') - self.assertEqual(first_row['annotationPageLabel'], 'page2') - self.assertEqual(first_row['annotationText'], 'another text') - self.assertEqual(first_row['annotationType'], 'underline') - self.assertEqual(first_row['dateAdded'], '2023-03-01') - self.assertEqual(first_row['dateModified'], '2023-03-02') - self.assertEqual(first_row['key'], '54321') - self.assertEqual(first_row['parentItem'], '09876') - self.assertEqual(first_row['relations'], {}) - self.assertEqual(first_row['tags'], []) - self.assertEqual(first_row['version'], 2) - - @patch.object(AnnotationsTable, '_get_item_children') - def test_select_with_conditions_parent_item_id(self, mock_get_item_children): - mock_get_item_children.return_value = pd.DataFrame([ - { - 'annotationColor': 'green', - 'annotationComment': 'yet another comment', - 'annotationPageLabel': 'page3', - 'annotationText': 'yet another text', - 'annotationType': 'strikeout', - 'dateAdded': '2023-05-01', - 'dateModified': '2023-05-02', - 'key': '98765', - 'parentItem': '43210', - 'relations': {}, - 'tags': [], - 'version': 3 - } - ]) - - select_query = parse_sql('SELECT * FROM annotations WHERE parent_item_id = "67890"') - - result = self.annotations_table.select(select_query) - first_row = result.iloc[0] - - self.assertEqual(result.shape[1], 12) - self.assertEqual(first_row['annotationColor'], 'green') - self.assertEqual(first_row['annotationComment'], 'yet another comment') - self.assertEqual(first_row['annotationPageLabel'], 'page3') - self.assertEqual(first_row['annotationText'], 'yet another text') - self.assertEqual(first_row['annotationType'], 'strikeout') - self.assertEqual(first_row['dateAdded'], '2023-05-01') - self.assertEqual(first_row['dateModified'], '2023-05-02') - self.assertEqual(first_row['key'], '98765') - self.assertEqual(first_row['parentItem'], '43210') - self.assertEqual(first_row['relations'], {}) - self.assertEqual(first_row['tags'], []) - self.assertEqual(first_row['version'], 3) - - -class ZoteroHandlerTest(unittest.TestCase): - - @patch('pyzotero.zotero.Zotero') - def setUp(self, mock_zotero): - self.mock_zotero = mock_zotero - connection_data = { - 'library_id': 'test_lib_id', - 'library_type': 'user', - 'api_key': 'test_api_key' - } - self.handler = ZoteroHandler(connection_data=connection_data) - self.handler.connect() - - def test_connect(self): - self.handler.connect() - self.mock_zotero.assert_called_once_with( - 'test_lib_id', 'user', 'test_api_key' - ) - self.assertTrue(self.handler.is_connected) - - def test_check_connection_success(self): - self.handler.connect = Mock(return_value=None) - self.handler.is_connected = True - response = self.handler.check_connection() - self.assertTrue(response.success) - - def test_check_connection_failure(self): - self.handler.connect = Mock(side_effect=Exception('Connection failed')) - response = self.handler.check_connection() - self.assertFalse(response.success) - self.assertIn('Error connecting to Zotero API', response.error_message) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/unused/unit/handlers/test_chromadb_handler.py b/tests/unused/unit/handlers/test_chromadb_handler.py deleted file mode 100644 index 5268c2ea441..00000000000 --- a/tests/unused/unit/handlers/test_chromadb_handler.py +++ /dev/null @@ -1,529 +0,0 @@ -import shutil -import tempfile -from unittest.mock import patch - -import pandas as pd -import pytest - -from tests.unit.executor_test_base import BaseExecutorTest - -# check if chroma_db is installed -import importlib - -try: - importlib.import_module("chromadb") - CHROMA_DB_INSTALLED = True -except ImportError: - CHROMA_DB_INSTALLED = False - - -@pytest.mark.skipif(not CHROMA_DB_INSTALLED, reason="chroma_db is not installed") -class TestChromaDBHandler(BaseExecutorTest): - - @pytest.fixture(autouse=True, scope="function") - def setup_method(self): - super().setup_method() - # create a chroma database under the tmp directory - tmp_directory = tempfile.mkdtemp() - self.run_sql( - f""" - CREATE DATABASE chroma_test - WITH ENGINE = "chromadb", - PARAMETERS = {{ - "persist_directory" : "{tmp_directory}" - }} - """ - ) - yield - # Teardown code: drop the database and remove the temporary directory - self.run_sql("DROP DATABASE chroma_test;") - shutil.rmtree(tmp_directory) - - @pytest.mark.xfail(reason="create table for vectordatabase is not well supported") - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_create_table(self, postgres_handler_mock): - # create an empty table - sql = """ - CREATE TABLE chroma_test.test_table; - """ - self.run_sql(sql) - - # create a table with the schema definition is not allowed - - sql = """ - CREATE TABLE chroma_test.test_table ( - id int, - metadata text, - embedding float[] - ); - """ - with pytest.raises(Exception): - self.run_sql(sql) - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_create_with_select(self, postgres_handler_mock): - df = pd.DataFrame( - { - "id": ["id1", "id2"], - "content": ["this is a test", "this is a test"], - "metadata": [{"test": "test"}, {"test": "test"}], - "embeddings": [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0]], - } - ) - - self.set_handler(postgres_handler_mock, "pg", tables={"test_table": df}) - - sql = """ - CREATE TABLE chroma_test.test_table2 ( - SELECT * FROM pg.df - ) - """ - # this should work - self.run_sql(sql) - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_drop_table(self, postgres_handler_mock): - df = pd.DataFrame( - { - "id": ["id1", "id2"], - "content": ["this is a test", "this is a test"], - "metadata": [{"test": "test"}, {"test": "test"}], - "embeddings": [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0]], - } - ) - self.set_handler(postgres_handler_mock, "pg", tables={"test_table": df}) - - # create a table - sql = """ - CREATE TABLE chroma_test.test_table ( - SELECT * FROM pg.df - ) - """ - self.run_sql(sql) - - # drop a table - sql = """ - DROP TABLE chroma_test.test_table; - """ - self.run_sql(sql) - - # drop a non existent table will raise an error - sql = """ - DROP TABLE chroma_test.test_table2; - """ - with pytest.raises(Exception): - self.run_sql(sql) - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_insert_into(self, postgres_handler_mock): - df = pd.DataFrame( - { - "id": ["id1", "id2", "id3"], - "content": ["this is a test", "this is a test", "this is a test"], - "metadata": [{"test": "test1"}, {"test": "test2"}, {"test": "test3"}], - "embeddings": [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0], [1.0, 2.0, 3.0]], - } - ) - df2 = pd.DataFrame( - { - "id": ["id1", "id2", "id3"], - "content": ["this is a test", "this is a test", "this is a test"], - "metadata": [{"test": "test1"}, {"test": "test2"}, {"test": "test3"}], - "embeddings": [ - [1.0, 2.0, 3.0, 4.0], - [1.0, 2.0], - [1.0, 2.0, 3.0], - ], # different dimensions - } - ) - self.set_handler(postgres_handler_mock, "pg", tables={"df": df, "df2": df2}) - num_record = df.shape[0] - - # create a table - sql = """ - CREATE TABLE chroma_test.test_table ( - SELECT * FROM pg.df - ) - """ - self.run_sql(sql) - - # insert into a table with values - sql = """ - INSERT INTO chroma_test.test_table ( - id,content,metadata,embeddings - ) - VALUES ( - 'some_unique_id', 'this is a test', '{"test": "test"}', '[1.0, 2.0, 3.0]' - ) - """ - self.run_sql(sql) - # check if the data is inserted - sql = """ - SELECT * FROM chroma_test.test_table - WHERE id = 'some_unique_id' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 1 - - # insert without specifying id should also work - sql = """ - INSERT INTO chroma_test.test_table ( - content,metadata,embeddings - ) - VALUES ( - 'this is a test 0', '{"test": "test"}', '[1.0, 2.0, 3.0]' - ) - """ - self.run_sql(sql) - # check if the data is inserted - sql = """ - SELECT * FROM chroma_test.test_table - """ - ret = self.run_sql(sql) - assert ret.shape[0] == num_record + 2 - - # insert into a table with a select statement - sql = """ - INSERT INTO chroma_test.test_table ( - content,metadata,embeddings - ) - SELECT - content,metadata,embeddings - FROM - pg.df - """ - self.run_sql(sql) - # check if the data is inserted - sql = """ - SELECT * FROM chroma_test.test_table - """ - ret = self.run_sql(sql) - assert ret.shape[0] == num_record + 3 # only one unique record was added - - # insert into a table with a select statement, but wrong columns - with pytest.raises(Exception): - sql = """ - INSERT INTO chroma_test.test_table - SELECT - content,metadata,embeddings as wrong_column - FROM - pg.df - """ - self.run_sql(sql) - - # insert into a table with a select statement, missing metadata column - sql = """ - INSERT INTO chroma_test.test_table - SELECT - content,embeddings - FROM - pg.df - """ - self.run_sql(sql) - - # insert into a table with a select statement, missing embedding column, shall raise an error - with pytest.raises(Exception): - sql = """ - INSERT INTO chroma_test.test_table - SELECT - content,metadata - FROM - pg.df - """ - self.run_sql(sql) - - # insert into a table with a select statement, with different embedding dimensions, shall raise an error - sql = """ - INSERT INTO chroma_test.test_table - SELECT - content,metadata,embeddings - FROM - pg.df2 - """ - with pytest.raises(Exception): - self.run_sql(sql) - - # TODO: this behavior is not consistent with chromadb doc - # tracked in https://github.com/chroma-core/chroma/issues/1062 - # insert into a table with existing id, shall raise an error - # sql = """ - # INSERT INTO chroma_test.test_table ( - # id,content,metadata,embeddings - # ) - # VALUES ( - # 'id1', 'this is a test', '{"test": "test"}', '[1.0, 2.0, 3.0]' - # ) - # """ - # with pytest.raises(Exception): - # self.run_sql(sql) - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_select_from(self, postgres_handler_mock): - df = pd.DataFrame( - { - "id": ["id1", "id2"], - "content": ["this is a test", "this is a test"], - "metadata": [{"test": "test"}, {"test": "test"}], - "embeddings": [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0]], - } - ) - self.set_handler(postgres_handler_mock, "pg", tables={"test_table": df}) - # create a table - sql = """ - CREATE TABLE chroma_test.test_table ( - SELECT * FROM pg.df - ) - """ - self.run_sql(sql) - - # query a table without any filters - sql = """ - SELECT * FROM chroma_test.test_table - """ - self.run_sql(sql) - - # query a table with id - sql = """ - SELECT * FROM chroma_test.test_table - WHERE id = 'id1' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 1 - - # query a table with a search vector, without limit - sql = """ - SELECT * FROM chroma_test.test_table - WHERE search_vector = '[1.0, 2.0, 3.0]' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - - # query a table with a search vector, with limit - sql = """ - SELECT * FROM chroma_test.test_table - WHERE search_vector = '[1.0, 2.0, 3.0]' - LIMIT 1 - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 1 - - # query a table with a metadata filter - sql = """ - SELECT * FROM chroma_test.test_table - WHERE `metadata.test` = 'test' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - - # query a table with a metadata filter and a search vector - sql = """ - SELECT * FROM chroma_test.test_table - WHERE `metadata.test` = 'test' - AND search_vector = '[1.0, 2.0, 3.0]' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 2 - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_update(self, postgres_handler_mock): - - df = pd.DataFrame( - { - "id": ["id1", "id2"], - "content": ["this is a test", "this is a test"], - "metadata": [{"ext_id": "1"}, {"ext_id": "2"}], - "embeddings": [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0]], - } - ) - self.set_handler(postgres_handler_mock, "pg", tables={"test_table": df}) - - # create a table - sql = """ - CREATE TABLE chroma_test.test_table ( - SELECT * FROM pg.df - ) - """ - self.run_sql(sql) - - # updating the collection with only embeddings and not content is not allowed - sql = """ - UPDATE chroma_test.test_table - SET embeddings = '[3.0, 2.0, 1.0]', - id = 'id1' - """ - - with pytest.raises(Exception): - self.run_sql(sql) - - # updating the collection with only content and not embeddings is not allowed - sql = """ - UPDATE chroma_test.test_table - SET content = 'blah blah', - id = 'id1' - """ - - with pytest.raises(Exception): - self.run_sql(sql) - - # update multiple columns - sql = """ - UPDATE chroma_test.test_table - SET id = 'id1', - embeddings = '[1.0, 2.0, 3.0]', - content = 'this is a test' - """ - self.run_sql(sql) - # check if the data is updated - sql = """ - SELECT * FROM chroma_test.test_table - WHERE id = 'id1' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 1 - assert ret.embeddings[0] == [1.0, 2.0, 3.0] - assert ret.content[0] == "this is a test" - - # update a table with a where clause is not allowed - sql = """ - UPDATE chroma_test.test_table - SET `metadata.test` = 'test2' - WHERE search_vector = [1.0, 2.0, 3.0] - """ - with pytest.raises(Exception): - self.run_sql(sql) - - # update a table with all columns - sql = """ - UPDATE chroma_test.test_table - SET id = 'id1', - embeddings = '[1.0, 2.0, 3.0]', - content = 'this is a test', - `metadata.ext_id` = '1' - """ - self.run_sql(sql) - # check if the data is updated - sql = """ - SELECT * FROM chroma_test.test_table - WHERE id = 'id1' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 1 - assert ret.embeddings[0] == [1.0, 2.0, 3.0] - assert ret.content[0] == "this is a test" - assert ret.metadata[0] == {"ext_id": "1"} - - # update a table without providing a id is not allowed - sql = """ - UPDATE chroma_test.test_table - SET metadata.test = 'test3' - - """ - with pytest.raises(Exception): - self.run_sql(sql) - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_delete(self, postgres_handler_mock): - df = pd.DataFrame( - { - "id": ["id1", "id2"], - "content": ["this is a test", "this is a test"], - "metadata": [{"test": "test1"}, {"test": "test2"}], - "embeddings": [[1.0, 2.0, 3.0], [1.0, 2.0, 3.0]], - } - ) - self.set_handler(postgres_handler_mock, "pg", tables={"test_table": df}) - - # create a table - sql = """ - CREATE TABLE chroma_test.test_table ( - SELECT * FROM pg.df - ) - """ - self.run_sql(sql) - - # delete from a table with a metadata filter - sql = """ - DELETE FROM chroma_test.test_table - WHERE `metadata.test` = 'test1' - """ - self.run_sql(sql) - # check if the data is deleted - sql = """ - SELECT * FROM chroma_test.test_table - WHERE `metadata.test` = 'test2' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 1 - - # delete by id - sql = """ - DELETE FROM chroma_test.test_table - WHERE id = 'id2' - """ - self.run_sql(sql) - # check if the data is deleted - sql = """ - SELECT * FROM chroma_test.test_table - WHERE id = 'id2' - """ - ret = self.run_sql(sql) - assert ret.shape[0] == 0 - - # delete from a table with a search vector filter is not allowed - sql = """ - DELETE FROM chroma_test.test_table - WHERE search_vector = [1.0, 2.0, 3.0] - """ - with pytest.raises(Exception): - self.run_sql(sql) - - # delete from a table without any filters is not allowed - sql = """ - DELETE FROM chroma_test.test_table - """ - with pytest.raises(Exception): - self.run_sql(sql) - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_insert_upsert_behavior(self, postgres_handler_mock): - # Initial data with IDs - df1 = pd.DataFrame({ - "id": ["id1", "id2"], - "content": ["content1", "content2"], - "metadata": [{"test": "test1"}, {"test": "test2"}], - "embeddings": [[1.0, 2.0], [2.0, 3.0]] - }) - - # Same IDs, different metadata - df2 = pd.DataFrame({ - "id": ["id1", "id2"], - "content": ["content1", "content2"], - "metadata": [{"test": "updated1"}, {"test": "updated2"}], - "embeddings": [[1.0, 2.0], [2.0, 3.0]] - }) - - self.set_handler(postgres_handler_mock, "pg", tables={"df1": df1, "df2": df2}) - - # Create table and insert initial data - self.run_sql(""" - CREATE TABLE chroma_test.test_table ( - SELECT * FROM pg.df1 - ) - """) - - # Verify initial insert - result = self.run_sql("SELECT * FROM chroma_test.test_table") - assert result.shape[0] == 2 - assert result.iloc[0].metadata == {"test": "test1"} - - # Insert same IDs with different metadata (should update) - self.run_sql(""" - INSERT INTO chroma_test.test_table ( - SELECT * FROM pg.df2 - ) - """) - - # Verify update - result = self.run_sql("SELECT * FROM chroma_test.test_table") - assert result.shape[0] == 2 # Should still have 2 rows - assert result.iloc[0].metadata == {"test": "updated1"} # Metadata should be updated diff --git a/tests/unused/unit/interfaces/agents/test_api_key_handling.py b/tests/unused/unit/interfaces/agents/test_api_key_handling.py deleted file mode 100644 index 484ba775577..00000000000 --- a/tests/unused/unit/interfaces/agents/test_api_key_handling.py +++ /dev/null @@ -1,106 +0,0 @@ -import os -import unittest -from unittest.mock import patch, MagicMock - -from mindsdb.integrations.utilities.handler_utils import get_api_key -from mindsdb.interfaces.agents.agents_controller import AgentsController - - -class TestAgentApiKeyHandling(unittest.TestCase): - """Test API key handling in agent creation and usage.""" - - def setUp(self): - """Set up test environment.""" - # Mock environment variables - self.env_patcher = patch.dict(os.environ, { - 'OPENAI_API_KEY': 'test-env-api-key', - 'ANTHROPIC_API_KEY': 'test-env-anthropic-key' - }) - self.env_patcher.start() - - def tearDown(self): - """Clean up after tests.""" - self.env_patcher.stop() - - def test_get_api_key_from_env(self): - """Test retrieving API key from environment variables.""" - # Test getting API key from environment variable - api_key = get_api_key('openai', {}) - self.assertEqual(api_key, 'test-env-api-key') - - def test_get_api_key_from_args(self): - """Test retrieving API key from create_args.""" - # Test getting API key from create_args - api_key = get_api_key('openai', {'openai_api_key': 'test-args-api-key'}) - self.assertEqual(api_key, 'test-args-api-key') - - def test_get_api_key_from_params(self): - """Test retrieving API key from params dictionary.""" - # Test getting API key from params dictionary - api_key = get_api_key('openai', {'params': {'openai_api_key': 'test-params-api-key'}}) - self.assertEqual(api_key, 'test-params-api-key') - - def test_get_api_key_priority(self): - """Test API key retrieval priority.""" - # Test that create_args takes priority over environment variables - api_key = get_api_key('openai', {'openai_api_key': 'test-args-api-key'}) - self.assertEqual(api_key, 'test-args-api-key') - - # Test that params takes priority over environment variables - api_key = get_api_key('openai', {'params': {'openai_api_key': 'test-params-api-key'}}) - self.assertEqual(api_key, 'test-params-api-key') - - # Test that create_args takes priority over params - api_key = get_api_key('openai', { - 'openai_api_key': 'test-args-api-key', - 'params': {'openai_api_key': 'test-params-api-key'} - }) - self.assertEqual(api_key, 'test-args-api-key') - - @patch('mindsdb.interfaces.agents.agents_controller.AgentsController.check_model_provider') - @patch('mindsdb.interfaces.agents.agents_controller.AgentsController.get_agent') - @patch('mindsdb.interfaces.agents.agents_controller.ProjectController') - @patch('mindsdb.interfaces.storage.db.session') - def test_add_agent_with_api_key(self, mock_session, mock_project_controller, mock_get_agent, mock_check_model_provider): - """Test adding an agent with an API key in params.""" - # Mock project controller - mock_project = MagicMock() - mock_project_controller.return_value.get.return_value = mock_project - - # Mock get_agent to return None (agent doesn't exist yet) - mock_get_agent.return_value = None - - # Mock check_model_provider to return a provider - mock_check_model_provider.return_value = (None, 'openai') - - # Create an instance of AgentsController - agent_controller = AgentsController() - - # Test adding an agent with an API key in params - params = { - 'openai_api_key': 'test-agent-api-key', - 'other_param': 'value' - } - - # Create a mock agent with proper params - mock_agent = MagicMock() - mock_agent.params = params.copy() # Set params directly - - # Mock db.Agents to return our prepared mock agent - with patch('mindsdb.interfaces.storage.db.Agents', return_value=mock_agent): - # Add the agent - agent = agent_controller.add_agent( - name='test_agent', - project_name='mindsdb', - model_name='gpt-4', - skills=[], - provider='openai', - params=params - ) - - # Verify that the API key was preserved in the params - self.assertEqual(agent.params.get('openai_api_key'), 'test-agent-api-key') - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/unused/unit/interfaces/skills/custom/text2sql/test_mindsdb_kb_tools.py b/tests/unused/unit/interfaces/skills/custom/text2sql/test_mindsdb_kb_tools.py deleted file mode 100644 index 468756c16bc..00000000000 --- a/tests/unused/unit/interfaces/skills/custom/text2sql/test_mindsdb_kb_tools.py +++ /dev/null @@ -1,163 +0,0 @@ -import unittest -from unittest.mock import MagicMock - -from typing import List, Dict, Any - -from mindsdb.interfaces.skills.custom.text2sql.mindsdb_kb_tools import ( - KnowledgeBaseListTool, - KnowledgeBaseInfoTool, - KnowledgeBaseQueryTool -) - - -class TestKnowledgeBaseTools(unittest.TestCase): - """Test cases for the MindsDB knowledge base tools.""" - - def setUp(self) -> None: - """Set up test fixtures.""" - self.mock_db = MagicMock() - - # Sample knowledge base data - self.kb_list_data: List[Dict[str, str]] = [ - {"name": "kb1"}, - {"name": "kb2"}, - {"name": "kb3"} - ] - - self.kb_schema_data: List[Dict[str, Any]] = [ - { - "name": "kb1", - "engine": "vector", - "embedding_model": "openai", - "storage": "qdrant", - "metadata_columns": ["product", "category"] - } - ] - - self.kb_sample_data: List[Dict[str, Any]] = [ - { - "id": "A1B", - "chunk_id": "A1B_notes:1of1:0to20", - "chunk_content": "Request color: black", - "metadata": {"product": "Wireless Mouse", "category": "Electronics"}, - "distance": 0.574, - "relevance": 0.509 - }, - { - "id": "Q7P", - "chunk_id": "Q7P_notes:1of1:0to22", - "chunk_content": "Prefer aluminum finish", - "metadata": {"product": "Aluminum Laptop Stand", "category": "Accessories"}, - "distance": 0.774, - "relevance": 0.250 - } - ] - - def test_knowledge_base_list_tool(self) -> None: - """Test the KnowledgeBaseListTool.""" - # Configure mock - self.mock_db.run.return_value = self.kb_list_data - - # Create tool instance - kb_list_tool = KnowledgeBaseListTool(db=self.mock_db) - - # Test tool execution - result = kb_list_tool._run("") - - # Verify results - self.assertEqual(result, "`kb1`, `kb2`, `kb3`") - self.mock_db.run.assert_called_once_with("SHOW KNOWLEDGE_BASES;") - - def test_knowledge_base_list_tool_empty_result(self) -> None: - """Test the KnowledgeBaseListTool with empty result.""" - # Configure mock - self.mock_db.run.return_value = [] - - # Create tool instance - kb_list_tool = KnowledgeBaseListTool(db=self.mock_db) - - # Test tool execution - result = kb_list_tool._run("") - - # Verify results - self.assertEqual(result, "No knowledge bases found.") - - def test_knowledge_base_info_tool(self) -> None: - """Test the KnowledgeBaseInfoTool.""" - # Configure mock - self.mock_db.run.side_effect = [self.kb_schema_data, self.kb_sample_data] - - # Create tool instance - kb_info_tool = KnowledgeBaseInfoTool(db=self.mock_db) - - # Test tool execution - result = kb_info_tool._run("$START$ `kb1` $STOP$") - - # Verify results - self.assertIn("## Knowledge Base: `kb1`", result) - self.assertIn("### Schema Information:", result) - self.assertIn("### Sample Data:", result) - self.assertEqual(self.mock_db.run.call_count, 2) - - def test_knowledge_base_info_tool_invalid_input(self) -> None: - """Test the KnowledgeBaseInfoTool with invalid input.""" - # Create tool instance - kb_info_tool = KnowledgeBaseInfoTool(db=self.mock_db) - - # Test tool execution with invalid input - result = kb_info_tool._run("invalid input") - - # Verify results - self.assertEqual( - result, - "No valid knowledge base names provided. Please provide names enclosed in backticks between $START$ and $STOP$." - ) - - def test_knowledge_base_query_tool(self) -> None: - """Test the KnowledgeBaseQueryTool.""" - # Configure mock - self.mock_db.run.return_value = self.kb_sample_data - - # Create tool instance - kb_query_tool = KnowledgeBaseQueryTool(db=self.mock_db) - - # Test tool execution - query = "SELECT * FROM kb1 WHERE content = 'color';" - result = kb_query_tool._run(f"$START$ {query} $STOP$") - - # Verify results - self.assertIn("| id | chunk_id | chunk_content | metadata | distance | relevance |", result) - self.mock_db.run.assert_called_once_with(query) - - def test_knowledge_base_query_tool_invalid_input(self) -> None: - """Test the KnowledgeBaseQueryTool with invalid input.""" - # Create tool instance - kb_query_tool = KnowledgeBaseQueryTool(db=self.mock_db) - - # Test tool execution with invalid input - result = kb_query_tool._run("invalid input") - - # Verify results - self.assertEqual( - result, - "No valid SQL query provided. Please provide a query between $START$ and $STOP$." - ) - - def test_knowledge_base_query_tool_empty_result(self) -> None: - """Test the KnowledgeBaseQueryTool with empty result.""" - # Configure mock - self.mock_db.run.return_value = [] - - # Create tool instance - kb_query_tool = KnowledgeBaseQueryTool(db=self.mock_db) - - # Test tool execution - query = "SELECT * FROM kb1 WHERE content = 'nonexistent';" - result = kb_query_tool._run(f"$START$ {query} $STOP$") - - # Verify results - self.assertEqual(result, "Query executed successfully, but no results were returned.") - - -if __name__ == "__main__": - unittest.main() diff --git a/tests/unused/unit/ml_handlers/conftest.py b/tests/unused/unit/ml_handlers/conftest.py deleted file mode 100644 index 8ffd64431cb..00000000000 --- a/tests/unused/unit/ml_handlers/conftest.py +++ /dev/null @@ -1,24 +0,0 @@ -from pathlib import Path - -import pandas as pd -import pytest - -TEST_DATA_PATH = Path(__file__).parent.resolve() / "data" - - -def get_df(file_name: str, dtype: dict = None) -> pd.DataFrame: - return pd.read_csv(TEST_DATA_PATH / file_name, dtype=dtype) - - -@pytest.fixture -def lightfm_interaction_data() -> pd.DataFrame: - return get_df( - "ratings.csv", dtype={"userId": "str", "movieId": "str", "rating": "float64"} - ) - - -@pytest.fixture -def lightfm_item_data() -> pd.DataFrame: - return get_df( - "movies.csv", dtypes={"movieId": "str", "title": "str", "genres": "str"} - ) diff --git a/tests/unused/unit/ml_handlers/data/anomaly_detection.csv b/tests/unused/unit/ml_handlers/data/anomaly_detection.csv deleted file mode 100644 index 3aaa58d2eb4..00000000000 --- a/tests/unused/unit/ml_handlers/data/anomaly_detection.csv +++ /dev/null @@ -1,7 +0,0 @@ -carat,depth,table,x,y,z,category,class -0.23,61.5,55,3.95,3.98,2.43,"a",0 -0.21,59.8,61,3.89,3.84,2.31,"b",0 -0.23,56.9,65,4.05,4.07,2.31,"c",1 -0.29,62.4,58,4.2,4.23,2.63,"a",0 -0.31,63.3,58,4.34,4.35,2.75,"b",0 -0.31,64.3,28,4.24,4.35,2.75,"c",1 diff --git a/tests/unused/unit/ml_handlers/data/house_sales.csv b/tests/unused/unit/ml_handlers/data/house_sales.csv deleted file mode 100644 index 5eaf7a7304b..00000000000 --- a/tests/unused/unit/ml_handlers/data/house_sales.csv +++ /dev/null @@ -1,348 +0,0 @@ -saledate,ma,type,bedrooms -2007-09-30,441854,house,2 -2007-12-31,441854,house,2 -2008-03-31,441854,house,2 -2008-06-30,441854,house,2 -2008-09-30,451583,house,2 -2008-12-31,440256,house,2 -2009-03-31,442566,house,2 -2009-06-30,446113,house,2 -2009-09-30,440123,house,2 -2009-12-31,442131,house,2 -2010-03-31,459222,house,2 -2010-06-30,456822,house,2 -2010-09-30,457806,house,2 -2010-12-31,459109,house,2 -2011-03-31,460758,house,2 -2011-06-30,464788,house,2 -2011-09-30,467546,house,2 -2011-12-31,470333,house,2 -2012-03-31,470365,house,2 -2012-06-30,469149,house,2 -2012-09-30,465919,house,2 -2012-12-31,463090,house,2 -2013-03-31,451077,house,2 -2013-06-30,451516,house,2 -2013-09-30,454270,house,2 -2013-12-31,456548,house,2 -2014-03-31,469920,house,2 -2014-06-30,472726,house,2 -2014-09-30,475326,house,2 -2014-12-31,478413,house,2 -2015-03-31,478398,house,2 -2015-06-30,477238,house,2 -2015-09-30,477330,house,2 -2015-12-31,479010,house,2 -2016-03-31,482440,house,2 -2016-06-30,486436,house,2 -2016-09-30,489104,house,2 -2016-12-31,491152,house,2 -2017-03-31,494544,house,2 -2017-06-30,498846,house,2 -2017-09-30,504592,house,2 -2017-12-31,506578,house,2 -2018-03-31,507248,house,2 -2018-06-30,506116,house,2 -2018-09-30,504318,house,2 -2018-12-31,506001,house,2 -2019-03-31,496133,house,2 -2019-06-30,500158,house,2 -2019-09-30,510712,house,2 -2007-03-31,421291,house,3 -2007-06-30,421291,house,3 -2007-09-30,421291,house,3 -2007-12-31,421291,house,3 -2008-03-31,416031,house,3 -2008-06-30,419628,house,3 -2008-09-30,423811,house,3 -2008-12-31,426488,house,3 -2009-03-31,437724,house,3 -2009-06-30,444351,house,3 -2009-09-30,449742,house,3 -2009-12-31,457394,house,3 -2010-03-31,466433,house,3 -2010-06-30,474590,house,3 -2010-09-30,483176,house,3 -2010-12-31,491715,house,3 -2011-03-31,498022,house,3 -2011-06-30,503891,house,3 -2011-09-30,507090,house,3 -2011-12-31,507744,house,3 -2012-03-31,507449,house,3 -2012-06-30,507014,house,3 -2012-09-30,506615,house,3 -2012-12-31,506615,house,3 -2013-03-31,506380,house,3 -2013-06-30,505739,house,3 -2013-09-30,505823,house,3 -2013-12-31,506406,house,3 -2014-03-31,508499,house,3 -2014-06-30,512374,house,3 -2014-09-30,516618,house,3 -2014-12-31,522103,house,3 -2015-03-31,528926,house,3 -2015-06-30,534927,house,3 -2015-09-30,542051,house,3 -2015-12-31,549278,house,3 -2016-03-31,556586,house,3 -2016-06-30,564267,house,3 -2016-09-30,572582,house,3 -2016-12-31,581485,house,3 -2017-03-31,590949,house,3 -2017-06-30,601041,house,3 -2017-09-30,609355,house,3 -2017-12-31,615743,house,3 -2018-03-31,619638,house,3 -2018-06-30,622466,house,3 -2018-09-30,624602,house,3 -2018-12-31,626608,house,3 -2019-03-31,628423,house,3 -2019-06-30,630814,house,3 -2019-09-30,631875,house,3 -2007-03-31,548969,house,4 -2007-06-30,548969,house,4 -2007-09-30,548969,house,4 -2007-12-31,548969,house,4 -2008-03-31,552484,house,4 -2008-06-30,559580,house,4 -2008-09-30,561852,house,4 -2008-12-31,565467,house,4 -2009-03-31,569682,house,4 -2009-06-30,574680,house,4 -2009-09-30,579369,house,4 -2009-12-31,588379,house,4 -2010-03-31,599614,house,4 -2010-06-30,608528,house,4 -2010-09-30,615603,house,4 -2010-12-31,623105,house,4 -2011-03-31,628969,house,4 -2011-06-30,634155,house,4 -2011-09-30,636582,house,4 -2011-12-31,637421,house,4 -2012-03-31,635411,house,4 -2012-06-30,633695,house,4 -2012-09-30,634803,house,4 -2012-12-31,633875,house,4 -2013-03-31,634229,house,4 -2013-06-30,635515,house,4 -2013-09-30,636687,house,4 -2013-12-31,641125,house,4 -2014-03-31,648174,house,4 -2014-06-30,655757,house,4 -2014-09-30,664635,house,4 -2014-12-31,673762,house,4 -2015-03-31,684006,house,4 -2015-06-30,694800,house,4 -2015-09-30,706711,house,4 -2015-12-31,718261,house,4 -2016-03-31,727736,house,4 -2016-06-30,737159,house,4 -2016-09-30,745430,house,4 -2016-12-31,755683,house,4 -2017-03-31,771216,house,4 -2017-06-30,789732,house,4 -2017-09-30,810694,house,4 -2017-12-31,828058,house,4 -2018-03-31,836056,house,4 -2018-06-30,837295,house,4 -2018-09-30,830727,house,4 -2018-12-31,820924,house,4 -2019-03-31,811121,house,4 -2019-06-30,803925,house,4 -2019-09-30,791446,house,4 -2007-09-30,735904,house,5 -2007-12-31,735904,house,5 -2008-03-31,735904,house,5 -2008-06-30,735904,house,5 -2008-09-30,758340,house,5 -2008-12-31,764025,house,5 -2009-03-31,770046,house,5 -2009-06-30,765555,house,5 -2009-09-30,765515,house,5 -2009-12-31,771280,house,5 -2010-03-31,773355,house,5 -2010-06-30,776325,house,5 -2010-09-30,772699,house,5 -2010-12-31,775199,house,5 -2011-03-31,778470,house,5 -2011-06-30,789627,house,5 -2011-09-30,789614,house,5 -2011-12-31,790965,house,5 -2012-03-31,794533,house,5 -2012-06-30,792171,house,5 -2012-09-30,800432,house,5 -2012-12-31,804474,house,5 -2013-03-31,807826,house,5 -2013-06-30,812224,house,5 -2013-09-30,805066,house,5 -2013-12-31,805682,house,5 -2014-03-31,811908,house,5 -2014-06-30,820368,house,5 -2014-09-30,843904,house,5 -2014-12-31,855039,house,5 -2015-03-31,866489,house,5 -2015-06-30,880625,house,5 -2015-09-30,891981,house,5 -2015-12-31,909131,house,5 -2016-03-31,923594,house,5 -2016-06-30,933589,house,5 -2016-09-30,952327,house,5 -2016-12-31,968331,house,5 -2017-03-31,980953,house,5 -2017-06-30,995349,house,5 -2017-09-30,1004117,house,5 -2017-12-31,1010848,house,5 -2018-03-31,1015529,house,5 -2018-06-30,1017752,house,5 -2018-09-30,1007114,house,5 -2018-12-31,1002323,house,5 -2019-03-31,998136,house,5 -2019-06-30,995363,house,5 -2019-09-30,970268,house,5 -2007-12-31,326076,unit,1 -2008-03-31,326076,unit,1 -2008-06-30,326076,unit,1 -2008-09-30,326076,unit,1 -2008-12-31,327321,unit,1 -2009-03-31,324712,unit,1 -2009-06-30,323556,unit,1 -2009-09-30,318922,unit,1 -2009-12-31,316914,unit,1 -2010-03-31,316751,unit,1 -2010-06-30,317711,unit,1 -2010-09-30,318695,unit,1 -2010-12-31,324778,unit,1 -2011-03-31,329856,unit,1 -2011-06-30,333049,unit,1 -2011-09-30,337144,unit,1 -2011-12-31,337400,unit,1 -2012-03-31,339125,unit,1 -2012-06-30,341807,unit,1 -2012-09-30,344793,unit,1 -2012-12-31,347754,unit,1 -2013-03-31,348491,unit,1 -2013-06-30,348512,unit,1 -2013-09-30,347962,unit,1 -2013-12-31,345573,unit,1 -2014-03-31,343298,unit,1 -2014-06-30,341289,unit,1 -2014-09-30,338293,unit,1 -2014-12-31,336520,unit,1 -2015-03-31,334488,unit,1 -2015-06-30,332703,unit,1 -2015-09-30,330278,unit,1 -2015-12-31,328300,unit,1 -2016-03-31,326476,unit,1 -2016-06-30,324725,unit,1 -2016-09-30,325127,unit,1 -2016-12-31,325521,unit,1 -2017-03-31,327870,unit,1 -2017-06-30,330319,unit,1 -2017-09-30,332481,unit,1 -2017-12-31,334804,unit,1 -2018-03-31,336637,unit,1 -2018-06-30,338105,unit,1 -2018-09-30,339220,unit,1 -2018-12-31,339350,unit,1 -2019-03-31,337838,unit,1 -2019-06-30,336551,unit,1 -2019-09-30,335449,unit,1 -2007-06-30,368817,unit,2 -2007-09-30,368817,unit,2 -2007-12-31,368817,unit,2 -2008-03-31,368817,unit,2 -2008-06-30,373482,unit,2 -2008-09-30,377481,unit,2 -2008-12-31,382010,unit,2 -2009-03-31,380810,unit,2 -2009-06-30,385791,unit,2 -2009-09-30,391161,unit,2 -2009-12-31,396448,unit,2 -2010-03-31,402898,unit,2 -2010-06-30,408608,unit,2 -2010-09-30,412509,unit,2 -2010-12-31,415991,unit,2 -2011-03-31,417970,unit,2 -2011-06-30,419777,unit,2 -2011-09-30,421158,unit,2 -2011-12-31,423144,unit,2 -2012-03-31,424673,unit,2 -2012-06-30,424249,unit,2 -2012-09-30,425453,unit,2 -2012-12-31,425922,unit,2 -2013-03-31,425751,unit,2 -2013-06-30,426621,unit,2 -2013-09-30,428398,unit,2 -2013-12-31,428365,unit,2 -2014-03-31,429283,unit,2 -2014-06-30,429361,unit,2 -2014-09-30,428911,unit,2 -2014-12-31,429832,unit,2 -2015-03-31,431567,unit,2 -2015-06-30,432730,unit,2 -2015-09-30,432791,unit,2 -2015-12-31,432801,unit,2 -2016-03-31,431418,unit,2 -2016-06-30,430880,unit,2 -2016-09-30,430654,unit,2 -2016-12-31,430308,unit,2 -2017-03-31,429897,unit,2 -2017-06-30,429059,unit,2 -2017-09-30,428878,unit,2 -2017-12-31,428532,unit,2 -2018-03-31,427856,unit,2 -2018-06-30,427623,unit,2 -2018-09-30,426970,unit,2 -2018-12-31,426936,unit,2 -2019-03-31,426669,unit,2 -2019-06-30,425659,unit,2 -2019-09-30,424412,unit,2 -2007-09-30,518911,unit,3 -2007-12-31,518911,unit,3 -2008-03-31,518911,unit,3 -2008-06-30,518911,unit,3 -2008-09-30,518911,unit,3 -2008-12-31,518911,unit,3 -2009-03-31,518911,unit,3 -2009-06-30,518911,unit,3 -2009-09-30,523285,unit,3 -2009-12-31,522862,unit,3 -2010-03-31,524008,unit,3 -2010-06-30,535063,unit,3 -2010-09-30,538694,unit,3 -2010-12-31,555117,unit,3 -2011-03-31,550851,unit,3 -2011-06-30,547981,unit,3 -2011-09-30,539828,unit,3 -2011-12-31,530987,unit,3 -2012-03-31,540344,unit,3 -2012-06-30,537592,unit,3 -2012-09-30,548326,unit,3 -2012-12-31,555644,unit,3 -2013-03-31,566706,unit,3 -2013-06-30,580696,unit,3 -2013-09-30,581428,unit,3 -2013-12-31,586470,unit,3 -2014-03-31,583883,unit,3 -2014-06-30,583370,unit,3 -2014-09-30,598512,unit,3 -2014-12-31,598812,unit,3 -2015-03-31,599507,unit,3 -2015-06-30,602877,unit,3 -2015-09-30,603343,unit,3 -2015-12-31,612295,unit,3 -2016-03-31,617363,unit,3 -2016-06-30,622045,unit,3 -2016-09-30,616198,unit,3 -2016-12-31,610618,unit,3 -2017-03-31,606935,unit,3 -2017-06-30,605273,unit,3 -2017-09-30,606850,unit,3 -2017-12-31,604413,unit,3 -2018-03-31,604293,unit,3 -2018-06-30,603434,unit,3 -2018-09-30,603281,unit,3 -2018-12-31,601167,unit,3 -2019-03-31,605637,unit,3 -2019-06-30,599339,unit,3 -2019-09-30,597884,unit,3 \ No newline at end of file diff --git a/tests/unused/unit/ml_handlers/data/movies.csv b/tests/unused/unit/ml_handlers/data/movies.csv deleted file mode 100644 index b2e75d71137..00000000000 --- a/tests/unused/unit/ml_handlers/data/movies.csv +++ /dev/null @@ -1,90 +0,0 @@ -movieId,title,genres -1,Toy Story (1995),Adventure|Animation|Children|Comedy|Fantasy -2,Jumanji (1995),Adventure|Children|Fantasy -3,Grumpier Old Men (1995),Comedy|Romance -4,Waiting to Exhale (1995),Comedy|Drama|Romance -5,Father of the Bride Part II (1995),Comedy -6,Heat (1995),Action|Crime|Thriller -7,Sabrina (1995),Comedy|Romance -8,Tom and Huck (1995),Adventure|Children -9,Sudden Death (1995),Action -10,GoldenEye (1995),Action|Adventure|Thriller -11,"American President, The (1995)",Comedy|Drama|Romance -12,Dracula: Dead and Loving It (1995),Comedy|Horror -13,Balto (1995),Adventure|Animation|Children -14,Nixon (1995),Drama -15,Cutthroat Island (1995),Action|Adventure|Romance -16,Casino (1995),Crime|Drama -17,Sense and Sensibility (1995),Drama|Romance -18,Four Rooms (1995),Comedy -19,Ace Ventura: When Nature Calls (1995),Comedy -20,Money Train (1995),Action|Comedy|Crime|Drama|Thriller -21,Get Shorty (1995),Comedy|Crime|Thriller -22,Copycat (1995),Crime|Drama|Horror|Mystery|Thriller -23,Assassins (1995),Action|Crime|Thriller -24,Powder (1995),Drama|Sci-Fi -25,Leaving Las Vegas (1995),Drama|Romance -26,Othello (1995),Drama -27,Now and Then (1995),Children|Drama -28,Persuasion (1995),Drama|Romance -29,"City of Lost Children, The (Cité des enfants perdus, La) (1995)",Adventure|Drama|Fantasy|Mystery|Sci-Fi -30,Shanghai Triad (Yao a yao yao dao waipo qiao) (1995),Crime|Drama -31,Dangerous Minds (1995),Drama -32,Twelve Monkeys (a.k.a. 12 Monkeys) (1995),Mystery|Sci-Fi|Thriller -34,Babe (1995),Children|Drama -36,Dead Man Walking (1995),Crime|Drama -38,It Takes Two (1995),Children|Comedy -39,Clueless (1995),Comedy|Romance -40,"Cry, the Beloved Country (1995)",Drama -41,Richard III (1995),Drama|War -42,Dead Presidents (1995),Action|Crime|Drama -43,Restoration (1995),Drama -44,Mortal Kombat (1995),Action|Adventure|Fantasy -45,To Die For (1995),Comedy|Drama|Thriller -46,How to Make an American Quilt (1995),Drama|Romance -47,Seven (a.k.a. Se7en) (1995),Mystery|Thriller -48,Pocahontas (1995),Animation|Children|Drama|Musical|Romance -49,When Night Is Falling (1995),Drama|Romance -50,"Usual Suspects, The (1995)",Crime|Mystery|Thriller -52,Mighty Aphrodite (1995),Comedy|Drama|Romance -53,Lamerica (1994),Adventure|Drama -54,"Big Green, The (1995)",Children|Comedy -55,Georgia (1995),Drama -57,Home for the Holidays (1995),Drama -58,"Postman, The (Postino, Il) (1994)",Comedy|Drama|Romance -60,"Indian in the Cupboard, The (1995)",Adventure|Children|Fantasy -61,Eye for an Eye (1996),Drama|Thriller -62,Mr. Holland's Opus (1995),Drama -63,Don't Be a Menace to South Central While Drinking Your Juice in the Hood (1996),Comedy|Crime -64,Two if by Sea (1996),Comedy|Romance -65,Bio-Dome (1996),Comedy -66,Lawnmower Man 2: Beyond Cyberspace (1996),Action|Sci-Fi|Thriller -68,French Twist (Gazon maudit) (1995),Comedy|Romance -69,Friday (1995),Comedy -70,From Dusk Till Dawn (1996),Action|Comedy|Horror|Thriller -71,Fair Game (1995),Action -72,Kicking and Screaming (1995),Comedy|Drama -73,"Misérables, Les (1995)",Drama|War -74,Bed of Roses (1996),Drama|Romance -75,Big Bully (1996),Comedy|Drama -76,Screamers (1995),Action|Sci-Fi|Thriller -77,Nico Icon (1995),Documentary -78,"Crossing Guard, The (1995)",Action|Crime|Drama|Thriller -79,"Juror, The (1996)",Drama|Thriller -80,"White Balloon, The (Badkonake sefid) (1995)",Children|Drama -81,Things to Do in Denver When You're Dead (1995),Crime|Drama|Romance -82,Antonia's Line (Antonia) (1995),Comedy|Drama -83,Once Upon a Time... When We Were Colored (1995),Drama|Romance -85,Angels and Insects (1995),Drama|Romance -86,White Squall (1996),Action|Adventure|Drama -87,Dunston Checks In (1996),Children|Comedy -88,Black Sheep (1996),Comedy -89,Nick of Time (1995),Action|Thriller -92,Mary Reilly (1996),Drama|Horror|Thriller -93,Vampire in Brooklyn (1995),Comedy|Horror|Romance -94,Beautiful Girls (1996),Comedy|Drama|Romance -95,Broken Arrow (1996),Action|Adventure|Thriller -96,In the Bleak Midwinter (1995),Comedy|Drama -97,"Hate (Haine, La) (1995)",Crime|Drama -99,Heidi Fleiss: Hollywood Madam (1995),Documentary -100,City Hall (1996),Drama|Thriller diff --git a/tests/unused/unit/ml_handlers/data/ratings.csv b/tests/unused/unit/ml_handlers/data/ratings.csv deleted file mode 100644 index eb8ce0e976d..00000000000 --- a/tests/unused/unit/ml_handlers/data/ratings.csv +++ /dev/null @@ -1,3207 +0,0 @@ -userId,movieId,rating,timestamp -1,1,4.0,964982703 -1,3,4.0,964981247 -1,6,4.0,964982224 -1,47,5.0,964983815 -1,50,5.0,964982931 -1,70,3.0,964982400 -3,31,0.5,1306463578 -4,21,3.0,986935199 -4,32,2.0,945173447 -4,45,3.0,986935047 -4,47,2.0,945173425 -4,52,3.0,964622786 -4,58,3.0,964538444 -5,1,4.0,847434962 -5,21,4.0,847435238 -5,34,4.0,847434881 -5,36,4.0,847435292 -5,39,3.0,847434961 -5,50,4.0,847434881 -5,58,5.0,847435238 -6,2,4.0,845553522 -6,3,5.0,845554296 -6,4,3.0,845554349 -6,5,5.0,845553938 -6,6,4.0,845553757 -6,7,4.0,845554264 -6,8,3.0,845555281 -6,10,3.0,845553253 -6,11,4.0,845553489 -6,13,3.0,845555588 -6,15,4.0,845554505 -6,16,4.0,845553819 -6,17,4.0,845553559 -6,19,2.0,845553382 -6,21,2.0,845553382 -6,22,5.0,845553875 -6,24,4.0,845554397 -6,25,3.0,845553695 -6,26,4.0,845555362 -6,27,3.0,845555402 -6,31,3.0,845553819 -6,32,4.0,845553426 -6,34,4.0,845553354 -6,36,5.0,845553726 -6,41,4.0,845554962 -6,43,4.0,845555607 -6,45,3.0,845553907 -6,46,4.0,845554551 -6,47,4.0,845553317 -6,50,1.0,845553381 -6,54,4.0,845555402 -6,60,4.0,845554263 -6,61,4.0,845555454 -6,62,4.0,845553660 -6,65,3.0,845555070 -6,66,3.0,845555151 -6,76,4.0,845555317 -6,79,3.0,845554907 -6,86,5.0,845556131 -6,87,3.0,845555300 -6,88,2.0,845555694 -6,89,4.0,845555124 -6,92,4.0,845555454 -6,93,4.0,845554584 -6,95,4.0,845553559 -6,100,3.0,845555151 -7,1,4.5,1106635946 -7,50,4.5,1106635993 -7,58,3.0,1106635520 -8,2,4.0,839463806 -8,10,2.0,839463509 -8,11,4.0,839463806 -8,21,4.0,839463564 -8,32,3.0,839463624 -8,34,5.0,839463546 -8,39,3.0,839463644 -8,47,4.0,839463546 -8,50,5.0,839463644 -9,41,3.0,1044656650 -11,6,5.0,902154266 -11,10,3.0,902154316 -11,36,4.0,902155135 -11,44,2.0,902154593 -11,95,3.0,902154458 -12,39,4.0,1247264471 -13,47,5.0,987895819 -14,4,3.0,835441653 -14,7,3.0,835441989 -14,19,1.0,835441168 -14,25,4.0,835441394 -14,32,4.0,835441168 -14,39,3.0,835441186 -14,47,5.0,835441133 -14,95,5.0,835441295 -15,1,2.5,1510577970 -15,44,1.0,1299424916 -15,47,3.5,1510571970 -16,47,3.5,1377477814 -16,50,4.0,1377476781 -17,1,4.5,1305696483 -17,44,3.5,1305696245 -17,47,4.0,1307262715 -17,50,4.5,1305697013 -18,1,3.5,1455209816 -18,2,3.0,1455617462 -18,6,4.0,1460138360 -18,16,4.5,1461311583 -18,32,4.0,1455209840 -18,34,2.5,1455617533 -18,36,4.0,1455617478 -18,47,4.5,1455050013 -18,50,5.0,1455049343 -18,70,3.5,1455735732 -19,1,4.0,965705637 -19,2,3.0,965704331 -19,3,3.0,965707636 -19,7,2.0,965706657 -19,10,2.0,965709556 -19,12,1.0,965705347 -19,13,3.0,965709102 -19,15,2.0,965710039 -19,19,2.0,965708339 -19,32,4.0,965703646 -19,34,4.0,965705661 -19,44,3.0,965710019 -19,47,3.0,965710720 -19,48,1.0,965709172 -19,54,2.0,965702660 -19,64,2.0,965708037 -19,65,2.0,965708217 -19,70,2.0,965704974 -19,87,2.0,965708059 -19,92,2.0,965712048 -20,2,3.0,1054038313 -20,8,1.0,1054038422 -20,13,4.0,1054038425 -20,34,4.0,1054038093 -20,48,5.0,1054038357 -21,1,3.5,1407618878 -21,2,3.5,1419795031 -21,10,5.0,1403459783 -21,19,2.5,1419795052 -21,38,2.5,1419795113 -21,44,1.0,1376822969 -21,48,3.0,1376822924 -23,6,4.0,1107342267 -23,29,4.0,1107341574 -23,32,3.5,1107341750 -23,50,4.0,1107163741 -23,58,3.0,1107164183 -24,6,4.5,1458941767 -24,32,3.5,1458942033 -24,50,4.0,1458942023 -26,10,3.0,836950403 -26,34,3.0,836950483 -26,47,4.0,836950431 -27,1,3.0,962685262 -27,2,4.0,962685711 -27,34,5.0,962685351 -27,48,4.0,962685318 -27,60,3.0,962685387 -27,62,5.0,962684909 -28,6,3.5,1234570483 -28,16,2.5,1234570375 -28,21,3.0,1242290535 -28,23,1.5,1242290862 -28,31,2.5,1234334920 -28,32,3.5,1234335329 -28,47,3.0,1235975946 -28,50,3.5,1234337966 -28,62,3.5,1242290542 -28,95,2.0,1234516201 -29,50,3.5,1308007653 -31,1,5.0,850466616 -31,5,3.0,850466642 -31,7,4.0,850466642 -31,10,4.0,850467366 -31,17,3.0,850466616 -31,25,2.0,850466616 -31,62,4.0,850466616 -32,1,3.0,856736119 -32,3,3.0,856736172 -32,6,3.0,856736172 -32,7,4.0,856736173 -32,21,4.0,856737002 -32,24,3.0,856737205 -32,25,4.0,856736119 -32,26,4.0,856736347 -32,32,4.0,856736119 -32,36,4.0,856736172 -32,39,3.0,856737205 -32,50,5.0,856737002 -32,52,3.0,856736227 -32,58,5.0,856736227 -32,62,3.0,856736119 -32,74,4.0,856736316 -32,78,4.0,856736477 -32,95,3.0,856736119 -32,100,4.0,856736290 -33,1,3.0,939647444 -33,7,1.0,939654896 -33,11,2.0,939654896 -33,17,4.0,939654828 -33,21,4.0,939715904 -33,25,3.0,939646902 -33,28,5.0,939654815 -33,32,3.0,939647370 -33,34,3.0,939646940 -33,36,5.0,939715317 -33,39,5.0,939654896 -33,43,2.0,939716739 -33,50,5.0,939646733 -33,58,4.0,939646784 -33,94,4.0,939716218 -34,10,5.0,1162048773 -34,70,3.5,1162048002 -35,11,4.0,830939577 -35,21,5.0,830939505 -35,39,3.0,830939546 -35,50,5.0,830939598 -35,60,5.0,830939912 -35,62,5.0,830939748 -36,25,2.5,1100803583 -38,11,5.0,841341447 -38,17,3.0,841341494 -38,21,3.0,841341362 -38,39,3.0,841341384 -38,48,3.0,841341570 -38,50,5.0,841341362 -38,62,3.0,841341570 -39,32,3.0,974787510 -39,47,3.0,974789632 -39,50,5.0,974788030 -40,1,5.0,832058959 -40,17,5.0,832059273 -40,19,2.0,832059137 -40,21,4.0,832059053 -40,26,4.0,832059937 -40,31,4.0,832059371 -40,34,5.0,832059080 -40,44,3.0,832059393 -40,46,4.0,832059892 -40,48,2.0,832059371 -40,60,4.0,832059509 -40,62,5.0,832059339 -40,82,5.0,832060151 -41,47,3.5,1458939486 -41,50,3.0,1459367479 -42,3,4.0,996221045 -42,7,3.0,996220162 -42,10,5.0,996215205 -42,11,5.0,996219314 -42,16,5.0,996218017 -42,19,2.0,996256258 -42,21,4.0,996219086 -42,22,5.0,996219167 -42,47,4.0,996218105 -42,50,5.0,996217838 -42,86,4.0,996220615 -42,95,3.0,996214545 -43,1,5.0,848993983 -43,3,5.0,848994405 -43,5,5.0,848994281 -43,7,5.0,848994392 -43,8,5.0,848994814 -43,10,4.0,848993747 -43,11,4.0,848993928 -43,23,5.0,848994451 -43,29,5.0,848994937 -43,34,5.0,848993816 -43,47,4.0,848993793 -43,48,5.0,848994152 -43,57,5.0,848994678 -43,60,5.0,848994424 -43,79,5.0,848994617 -43,95,4.0,848993983 -44,1,3.0,869251860 -44,3,3.0,869251910 -44,6,3.0,869251910 -44,12,1.0,869252043 -44,18,4.0,869252115 -44,36,4.0,869251910 -44,65,3.0,869252497 -44,66,3.0,869252563 -44,94,4.0,869252333 -44,95,4.0,869251861 -45,1,4.0,951170182 -45,5,3.0,959625102 -45,6,4.0,1121724608 -45,7,3.0,951170390 -45,11,3.0,951170225 -45,19,4.5,1091306129 -45,21,4.0,1091306011 -45,32,4.5,1121724503 -45,39,3.0,951170338 -45,50,5.0,951756750 -45,62,4.0,1091306047 -45,65,3.0,1020803228 -45,69,3.0,951170141 -45,70,4.0,951170563 -45,88,4.0,951170543 -46,1,5.0,834787906 -46,10,3.0,834787826 -46,32,4.0,834788094 -46,39,3.0,834788093 -46,50,5.0,834788094 -47,31,3.0,1496205717 -47,47,3.0,1496209354 -47,62,3.0,1496205312 -48,48,4.0,1127128718 -50,1,3.0,1514238116 -50,32,3.0,1523740563 -51,2,4.5,1230932741 -51,3,4.0,1230932736 -51,7,4.0,1230932700 -51,36,3.0,1230929322 -51,65,3.5,1230930652 -51,70,5.0,1230932691 -51,76,5.0,1230930644 -51,93,3.0,1230931640 -54,1,3.0,830247330 -54,17,3.0,830248246 -54,21,3.0,839921390 -54,32,3.0,830247417 -54,47,3.0,839921084 -54,50,3.0,830248246 -56,10,4.0,835799162 -56,11,4.0,835799366 -56,19,5.0,835799219 -56,39,4.0,835799274 -56,47,5.0,835799219 -56,69,4.0,835799457 -57,1,5.0,965796031 -57,6,3.0,972173446 -57,10,3.0,965798286 -57,11,3.0,965797264 -57,21,3.0,965796969 -57,32,4.0,965798685 -57,39,3.0,965796392 -57,50,5.0,965796686 -57,52,3.0,969753586 -57,65,1.0,965797815 -57,69,4.0,965797105 -57,70,1.0,965797305 -57,89,2.0,972174827 -57,95,3.0,969754664 -58,3,3.0,847719397 -58,5,4.0,847719151 -58,7,5.0,847719397 -58,19,1.0,847718718 -58,21,4.0,847718718 -58,22,3.0,847719108 -58,31,4.0,847719088 -58,32,5.0,847718745 -58,36,4.0,847718991 -58,39,5.0,847718745 -58,44,2.0,847718960 -58,47,5.0,847718657 -58,48,3.0,847719035 -58,50,5.0,847718718 -58,62,3.0,847718910 -59,10,3.0,953609378 -59,41,5.0,953609923 -60,48,3.0,1393541734 -60,50,3.0,1393542060 -60,60,3.0,1393541955 -61,16,4.0,1145531659 -61,32,4.5,1145532647 -61,50,4.5,1145532639 -62,2,4.0,1528843890 -62,6,4.5,1522190219 -62,47,4.5,1521489234 -63,1,5.0,1443199669 -63,10,3.0,1443201199 -63,32,3.0,1443199999 -63,34,3.0,1443201169 -63,47,4.0,1443201084 -63,50,5.0,1443199758 -64,1,4.0,1161520134 -64,3,3.5,1161519668 -64,6,4.5,1161520752 -64,16,5.0,1161528794 -64,19,3.5,1161521687 -64,22,3.5,1161559916 -64,25,3.5,1161521571 -64,32,4.0,1161520763 -64,34,4.5,1161520212 -64,36,4.0,1161521343 -64,39,4.0,1161520967 -64,45,3.5,1161564506 -64,47,4.5,1161520185 -64,48,3.0,1161529467 -64,50,3.0,1161528982 -64,70,4.0,1161559767 -66,1,4.0,1104643957 -66,5,4.0,1113190367 -66,18,4.0,1113190353 -66,19,3.0,1093143913 -66,21,4.0,1113190363 -66,29,4.5,1099187646 -66,32,5.0,1093747471 -66,47,5.0,1093747353 -66,50,4.0,1104644110 -68,1,2.5,1158531426 -68,2,2.5,1158532776 -68,3,2.0,1158533415 -68,5,2.0,1158533624 -68,6,4.0,1158532058 -68,7,2.0,1230498124 -68,10,4.5,1158531612 -68,11,4.5,1158531050 -68,16,3.5,1158533018 -68,17,3.5,1158531987 -68,18,2.0,1532897231 -68,19,1.5,1158532448 -68,25,3.5,1158531974 -68,26,3.0,1158534106 -68,31,3.5,1158535464 -68,34,1.0,1158531735 -68,39,4.0,1158532000 -68,44,3.0,1158534993 -68,47,4.0,1158531489 -68,48,4.0,1158533544 -68,50,3.0,1158531764 -68,62,3.5,1158531021 -68,65,1.5,1269123315 -68,70,4.0,1158534541 -68,95,3.5,1158532180 -69,50,5.0,1021646926 -70,36,5.0,1355198746 -71,1,5.0,864737933 -71,7,3.0,864738008 -71,17,1.0,864737933 -71,24,2.0,864740028 -71,62,4.0,864737933 -71,86,5.0,864738119 -71,95,4.0,864737933 -72,32,4.5,1217324825 -72,47,4.5,1217324851 -72,50,4.5,1217324720 -73,1,4.5,1464196374 -74,58,5.0,1207502891 -75,47,2.0,1158968272 -76,1,0.5,1439165548 -76,47,3.5,1439168120 -76,48,0.5,1439168949 -78,1,4.0,1252575124 -78,20,3.0,1252573422 -78,32,3.5,1252575140 -79,6,4.0,975282111 -80,32,4.0,1377308186 -80,50,4.5,1377308037 -81,10,1.0,845299756 -81,32,5.0,845299983 -81,47,3.0,845299983 -82,1,2.5,1084467729 -82,2,3.0,1084465035 -82,6,3.5,1084467865 -82,10,3.5,1084467796 -82,34,2.0,1084467775 -82,47,3.5,1084467783 -84,4,3.0,858772461 -84,5,3.0,857653289 -84,6,4.0,857653289 -84,7,3.0,857653289 -84,10,3.0,860397812 -84,11,4.0,858771861 -84,14,4.0,857653349 -84,17,5.0,857653240 -84,21,4.0,858772111 -84,25,5.0,860396793 -84,31,3.0,860398679 -84,34,4.0,858772153 -84,36,5.0,857653289 -84,45,4.0,858772239 -84,46,3.0,858771890 -84,50,4.0,857653594 -84,52,5.0,857653318 -84,55,4.0,858772543 -84,57,3.0,858771951 -84,62,4.0,857653240 -84,94,4.0,857653422 -84,95,2.0,857653240 -84,100,3.0,860396882 -85,53,5.0,889468268 -86,1,4.0,1344082549 -87,60,3.0,1270702696 -88,16,4.5,1331421395 -88,50,5.0,1331421330 -88,69,3.5,1331420307 -89,1,3.0,1520408314 -89,11,2.5,1520408449 -89,88,2.0,1520408790 -90,1,3.0,856353996 -90,7,4.0,856354037 -90,14,5.0,856354100 -90,17,5.0,856353996 -90,25,5.0,856353996 -90,32,4.0,856353996 -90,36,4.0,856354037 -90,52,5.0,856354072 -90,58,5.0,856354071 -90,68,3.0,856354249 -90,81,3.0,856354174 -90,82,5.0,856354212 -90,85,5.0,856354195 -91,1,4.0,1112713037 -91,2,3.0,1112713392 -91,3,3.0,1112712323 -91,6,5.0,1112712032 -91,10,3.5,1112713269 -91,16,4.5,1112710867 -91,19,2.0,1112713417 -91,21,4.0,1112712052 -91,22,3.5,1112712292 -91,25,2.0,1112713314 -91,29,4.0,1112711719 -91,32,4.0,1112711273 -91,36,3.0,1112712316 -91,39,1.5,1112713319 -91,41,4.0,1112716937 -91,47,4.5,1112712832 -91,50,4.5,1112712816 -91,58,2.0,1112710933 -91,88,3.0,1112716912 -91,92,2.0,1112716903 -91,95,3.0,1112711260 -93,1,3.0,942767337 -93,2,5.0,942946208 -93,10,4.0,942946208 -93,15,4.0,942946091 -93,34,5.0,942767143 -93,60,4.0,942946445 -93,86,4.0,942946013 -94,2,4.0,843406960 -94,10,3.0,843406732 -94,11,3.0,843406930 -94,17,1.0,843406942 -94,19,2.0,843406846 -94,21,3.0,843406846 -94,32,5.0,843406866 -94,34,4.0,843406765 -94,39,1.0,843406866 -94,44,1.0,843406960 -94,47,2.0,843406765 -94,95,3.0,843406942 -95,7,3.0,1043340043 -95,18,3.5,1105400752 -95,25,5.0,1044744590 -95,29,5.0,1043340522 -95,32,4.0,1043340522 -95,34,4.0,1071803856 -95,39,4.0,1043339476 -96,1,5.0,964772990 -96,34,5.0,964773008 -96,50,5.0,964773008 -98,1,4.5,1532457849 -99,10,4.0,829827514 -99,22,4.0,829828005 -99,23,4.0,829828005 -100,3,3.5,1100183804 -100,11,4.0,1100184041 -100,16,4.5,1100185959 -100,17,4.5,1100184147 -100,19,1.0,1100183757 -100,28,4.5,1100184447 -100,62,4.0,1100185952 -100,74,4.0,1100186732 -100,89,4.0,1100186731 -100,95,4.5,1100185961 -102,3,5.0,840635033 -102,6,3.0,835877535 -102,21,3.0,835876107 -102,23,3.0,835877570 -102,39,3.0,835876151 -102,47,5.0,835876045 -103,1,4.0,1431954238 -103,2,4.0,1431957270 -103,5,4.0,1431957598 -103,16,5.0,1450982615 -103,18,5.0,1431969228 -103,19,3.5,1431957278 -103,34,4.0,1431957104 -103,36,4.0,1431957252 -103,48,3.5,1431957563 -103,50,4.0,1431955220 -103,60,4.0,1431968436 -103,70,3.5,1431957632 -104,2,3.0,1114809641 -104,10,3.0,1048595683 -104,31,4.0,1049135743 -104,39,4.0,1048587379 -104,47,0.5,1053336550 -104,87,3.0,1048795372 -105,6,4.0,1446773632 -105,16,4.5,1446749417 -105,32,3.5,1446571805 -105,47,5.0,1446571714 -105,50,5.0,1446571713 -107,1,4.0,829322340 -107,2,5.0,829322340 -107,5,4.0,829322340 -107,11,5.0,829322340 -107,62,5.0,829322340 -108,25,4.0,1042838964 -108,82,5.0,1042839636 -109,6,3.0,841108665 -109,11,4.0,841108045 -109,14,4.0,841109326 -109,16,4.0,841108751 -109,18,3.0,841109921 -109,21,3.0,841107538 -109,25,5.0,841108589 -109,31,3.0,841108623 -109,32,4.0,841107643 -109,34,3.0,841107487 -109,36,5.0,841143673 -109,39,3.0,841107584 -109,45,3.0,841108914 -109,47,3.0,841107393 -109,50,4.0,841107584 -109,52,3.0,841109666 -109,62,5.0,841108564 -109,76,3.0,841151480 -110,47,4.5,1175330162 -111,5,3.5,1517441319 -111,16,4.5,1518640768 -111,24,2.5,1518640854 -111,34,2.5,1516153818 -111,39,4.0,1516153474 -111,48,3.5,1518640791 -111,65,3.5,1518640926 -112,1,3.0,1442535639 -112,2,1.5,1513989948 -112,6,4.5,1513989933 -112,16,4.5,1513990003 -112,17,0.5,1513989967 -112,19,4.0,1513989970 -112,21,2.0,1513989975 -112,25,2.5,1513989973 -112,32,5.0,1442535842 -112,36,0.5,1513989966 -112,39,0.5,1513989927 -112,47,5.0,1442535846 -112,50,5.0,1442535839 -112,62,4.0,1513989987 -112,95,1.5,1513989977 -113,11,3.0,980051838 -113,25,1.0,980051660 -113,39,3.0,980051704 -113,46,3.0,980051838 -113,64,2.0,980051988 -113,71,1.0,980051522 -113,74,3.0,980051922 -115,21,4.0,970756771 -115,32,5.0,958574098 -115,34,2.0,957760059 -116,3,3.5,1337200325 -116,47,3.5,1337199584 -117,2,3.0,844163002 -117,3,3.0,844163663 -117,5,3.0,844163754 -117,6,3.0,844163102 -117,7,4.0,844163615 -117,10,3.0,844162850 -117,11,4.0,844162970 -117,17,3.0,844163037 -117,19,2.0,844162892 -117,21,4.0,844162913 -117,26,4.0,844163712 -117,31,3.0,844163204 -117,32,3.0,844162955 -117,34,3.0,844163454 -117,36,3.0,844163102 -117,39,3.0,844162955 -117,41,4.0,844163693 -117,44,2.0,844163037 -117,47,4.0,844162892 -117,48,3.0,844163082 -117,50,4.0,844162933 -117,60,3.0,844163754 -117,62,4.0,844163122 -117,73,4.0,844163663 -118,25,2.0,944924731 -119,1,3.5,1435942468 -119,10,4.0,1435943180 -119,44,3.0,1435943918 -120,5,4.0,860070029 -120,12,3.0,860070182 -120,32,3.0,860069973 -120,52,3.0,860070065 -121,1,4.0,847656180 -121,5,3.0,847656405 -121,6,5.0,847656264 -121,11,4.0,847656100 -121,16,5.0,847656340 -121,19,2.0,847656045 -121,22,3.0,847656357 -121,25,4.0,847656224 -121,39,4.0,847656062 -121,44,1.0,847656224 -121,47,3.0,847656010 -121,62,5.0,847656203 -121,95,3.0,847656129 -122,2,4.0,1461561176 -122,19,3.5,1461562132 -122,32,5.0,1461561526 -122,47,4.5,1461561420 -122,50,5.0,1461561151 -122,70,4.5,1461562250 -123,47,4.5,1447291940 -124,1,4.0,1336584336 -124,50,4.5,1336412889 -125,2,4.0,1474311709 -125,81,3.0,1474415153 -126,34,3.0,845925854 -126,47,5.0,845925822 -129,47,3.5,1167376335 -130,1,3.0,832589610 -131,31,3.0,1349838570 -131,47,4.0,1349840567 -131,50,4.0,1349840171 -132,1,2.0,1157921785 -132,17,3.0,1157922698 -132,29,2.0,1157924165 -132,32,3.0,1329983726 -132,34,1.5,1157921395 -132,39,3.0,1157921453 -132,45,2.5,1157923125 -132,47,4.0,1157921243 -132,48,3.0,1157919960 -132,50,4.0,1157920377 -132,58,2.0,1157919923 -132,70,2.5,1157923053 -132,89,2.5,1157997580 -133,32,4.0,843491488 -133,47,4.0,843491396 -133,50,3.0,843491446 -134,1,3.0,832841103 -134,47,4.0,832841168 -134,48,3.0,832841524 -135,1,4.0,1009691859 -135,2,3.0,1009692764 -135,21,3.0,1009691915 -135,32,5.0,1009691695 -135,47,5.0,1009691144 -135,65,1.0,1009692359 -136,10,5.0,832449222 -136,15,5.0,832449934 -136,16,5.0,832449614 -136,19,3.0,832449345 -136,23,5.0,832449838 -136,34,2.0,832449299 -136,44,2.0,832449539 -136,47,5.0,832449299 -136,62,5.0,832449522 -136,93,4.0,832450076 -136,95,4.0,832449391 -137,1,4.0,1204859907 -139,19,1.0,1453924016 -140,1,3.0,942924980 -140,2,3.5,1085569813 -140,6,5.0,942843185 -140,11,4.0,949667337 -140,21,4.0,949666898 -140,22,3.0,951163606 -140,23,3.0,967049087 -140,34,4.0,942910010 -140,47,4.0,942842215 -140,50,3.0,942840991 -140,62,4.5,1055092420 -140,86,4.0,942844005 -140,95,2.5,1085569725 -141,1,4.0,1513130643 -141,19,2.0,1513130814 -141,47,3.0,1513130660 -142,34,4.0,838932132 -142,36,4.0,838933753 -142,47,4.0,838934238 -142,50,5.0,838934155 -142,95,3.0,838934522 -144,1,3.5,1137323419 -144,2,3.0,1137323803 -144,10,3.0,1137323629 -144,17,4.0,1137323659 -144,19,3.0,1136812137 -144,25,3.0,1136813341 -144,32,4.0,1137323444 -144,34,3.0,1137323545 -144,39,3.5,1137323676 -144,47,4.5,1137323517 -144,48,4.5,1137324255 -145,1,5.0,832105242 -145,50,5.0,832105428 -146,32,5.0,1312508179 -147,5,4.5,1203267700 -149,2,1.0,902084874 -149,32,4.0,902085272 -150,3,3.0,854203124 -150,5,3.0,854203124 -150,6,4.0,854203123 -150,7,3.0,854203124 -150,25,4.0,854203072 -150,32,5.0,854203071 -150,36,4.0,854203123 -150,52,4.0,854203163 -150,58,3.0,854203163 -150,62,3.0,854203072 -150,79,3.0,854203229 -150,95,3.0,854203072 -151,1,5.0,855947195 -151,3,3.0,855947242 -151,9,4.0,855947372 -151,12,3.0,855947434 -151,62,4.0,855947196 -151,75,3.0,855948083 -151,92,1.0,855948256 -151,95,4.0,855947196 -152,47,5.0,1450867741 -152,50,4.5,1450572430 -153,1,2.0,1525548642 -153,2,2.0,1525550601 -155,1,3.0,961861723 -156,1,4.0,1106854640 -156,11,3.0,946799769 -156,17,4.0,939884874 -156,19,3.0,1106855017 -156,21,5.0,946799679 -156,25,4.0,1106854805 -156,34,4.0,939853183 -156,39,1.0,939842934 -156,45,4.0,946799570 -156,47,3.5,1106854709 -156,50,4.0,940001349 -156,52,3.5,1106855391 -156,58,4.0,1106855269 -156,62,2.0,1106854830 -156,68,2.0,946799375 -159,1,4.5,1508640172 -159,31,3.5,1508641164 -159,62,3.0,1508641179 -160,1,4.0,971115026 -160,2,4.0,971619578 -160,6,2.0,971115114 -160,10,1.0,971196422 -160,22,1.0,971437089 -160,32,5.0,971113953 -160,34,5.0,971619022 -160,44,3.0,971115727 -160,47,5.0,971115962 -160,50,4.0,971113158 -160,60,2.0,971619579 -160,76,4.0,971196402 -160,79,1.0,971196754 -160,85,5.0,991075851 -160,93,1.0,976798624 -160,95,1.0,971112529 -161,1,4.0,1176751765 -161,48,4.0,1176498494 -162,4,3.0,836684306 -162,16,5.0,836511416 -162,17,5.0,836510953 -162,31,4.0,836511596 -162,36,5.0,836511416 -162,50,4.0,836511263 -162,62,5.0,836510953 -166,1,5.0,1189980529 -166,6,3.5,1190828796 -166,10,4.5,1190827465 -166,17,4.0,1190828781 -166,32,4.0,1189038252 -166,47,4.0,1188774624 -166,50,5.0,1188774404 -167,1,3.5,1154721923 -167,39,2.0,1154723333 -167,69,2.5,1154719322 -169,1,4.5,1059427918 -169,2,4.0,1078284713 -169,3,5.0,1078284750 -169,5,5.0,1078284788 -169,7,4.5,1078284741 -169,11,4.0,1059427956 -169,34,4.0,1059427862 -169,39,3.5,1059428140 -169,48,3.5,1059427123 -169,60,4.0,1078285375 -169,62,5.0,1078284604 -169,73,4.0,1070250173 -170,5,3.0,840473290 -170,10,3.0,840472869 -170,34,5.0,840472895 -170,48,4.0,840473093 -170,95,3.0,840473046 -171,1,5.0,866904159 -171,25,5.0,866904159 -171,29,5.0,866904396 -171,32,5.0,866904158 -171,36,4.0,866904192 -171,47,5.0,866905267 -171,81,5.0,866904379 -173,10,3.0,843397944 -173,17,4.0,843398078 -174,10,3.0,848486985 -174,11,5.0,848487132 -174,32,3.0,848487101 -174,34,4.0,848487060 -174,39,4.0,848487101 -174,50,3.0,848487075 -174,62,1.0,848487212 -176,10,5.0,840108984 -176,39,3.0,840108930 -176,47,5.0,840109138 -177,1,5.0,1435533535 -177,2,3.5,1435534109 -177,7,1.0,1435534432 -177,11,3.0,1435890660 -177,16,3.0,1435890664 -177,19,2.0,1435534140 -177,28,2.5,1435536420 -177,39,4.0,1435890554 -177,47,4.5,1435533571 -177,48,3.0,1435534447 -177,50,4.0,1435523529 -177,60,3.0,1435535258 -178,1,4.0,1164354911 -178,10,4.0,1164355337 -178,25,4.5,1164355401 -178,47,4.5,1164355292 -178,50,4.5,1163673981 -179,1,4.0,852114051 -179,3,4.0,852114317 -179,7,3.0,852115405 -179,9,3.0,852114156 -179,18,4.0,852115405 -179,19,3.0,840907679 -179,32,4.0,852114116 -179,34,5.0,840907679 -179,47,4.0,840907616 -179,52,4.0,852115696 -179,65,3.0,852115576 -179,95,3.0,852114051 -181,5,3.0,845470124 -181,6,3.0,845469804 -181,7,3.0,845470611 -181,10,2.0,845469438 -181,11,5.0,845469653 -181,16,3.0,845469893 -181,21,2.0,845469555 -181,22,3.0,845469972 -181,24,3.0,845470571 -181,25,1.0,845469842 -181,31,3.0,845469893 -181,34,5.0,845469500 -181,39,3.0,845469625 -181,45,3.0,845470124 -181,47,3.0,845469500 -181,61,4.0,845472115 -181,62,4.0,845469756 -181,79,4.0,845470717 -181,86,4.0,845472271 -181,100,3.0,845470909 -182,1,4.0,1063289621 -182,6,4.5,1054782012 -182,10,3.5,1054782216 -182,14,4.0,1063289654 -182,16,5.0,1054783631 -182,17,4.0,1066428620 -182,18,5.0,1055153282 -182,21,2.5,1054782030 -182,23,3.5,1055153587 -182,25,4.5,1054783186 -182,26,4.0,1063648819 -182,29,4.0,1054779789 -182,32,4.0,1054779785 -182,36,4.5,1063289589 -182,41,4.5,1054781875 -182,44,1.5,1055150820 -182,45,3.0,1075764933 -182,47,4.0,1054781315 -182,50,4.5,1054781309 -182,69,3.0,1054784267 -182,70,4.5,1077804802 -182,76,3.5,1055152107 -182,81,3.5,1055154219 -182,89,3.0,1055151186 -182,94,4.0,1075765007 -182,97,4.5,1075764905 -182,100,3.0,1055153511 -185,1,4.0,1044311830 -185,34,2.0,1044311830 -186,1,4.0,1031080831 -186,2,4.0,1031087675 -186,10,4.0,1031088020 -187,16,4.0,1161849621 -187,25,3.0,1161872627 -187,29,4.0,1161849623 -187,47,4.0,1161850486 -187,50,4.5,1161849680 -187,70,4.0,1161849108 -187,97,3.0,1180301412 -188,7,4.0,962559461 -191,1,4.0,829759809 -191,6,4.0,829759809 -191,16,4.0,829759809 -191,17,5.0,829759809 -191,21,4.0,829759809 -191,25,5.0,829759809 -191,32,5.0,829759809 -191,34,4.0,829760897 -191,36,5.0,829759809 -191,39,1.0,829760897 -191,47,4.0,829760898 -191,50,5.0,829760898 -191,52,5.0,829759809 -191,58,4.0,829759809 -191,72,4.0,829760897 -191,85,5.0,829759809 -191,94,4.0,829759809 -191,95,3.0,829759809 -191,99,5.0,829759809 -192,10,5.0,835128874 -192,47,3.0,835129031 -193,1,2.0,1435856890 -194,48,2.0,1110316714 -195,6,4.0,974705807 -195,10,4.0,974705349 -195,16,4.0,974705903 -195,25,4.0,1008558673 -195,32,4.0,974709650 -195,36,4.0,1008558588 -195,50,5.0,974705671 -195,70,4.0,979858326 -196,62,4.5,1460954240 -197,50,3.0,947462391 -198,17,3.0,1034136028 -198,24,4.0,1034138101 -198,25,4.0,1034136139 -198,32,5.0,1034135531 -198,34,4.0,1034137414 -198,36,5.0,1034136028 -198,47,5.0,1034136177 -198,50,5.0,1034136008 -198,58,5.0,1034137364 -198,66,1.0,1034135137 -199,6,4.0,1057590506 -199,7,3.0,940544181 -199,11,4.0,940543988 -199,20,2.0,1022161793 -199,21,4.0,940372914 -199,25,5.0,940372513 -199,36,4.0,940372656 -199,47,3.0,940372883 -199,50,4.0,940372419 -199,62,1.0,941295529 -199,81,3.0,940544216 -199,85,1.0,940380890 -200,1,3.5,1229886312 -200,5,4.0,1229876436 -200,10,4.5,1229887453 -200,19,3.5,1229877095 -200,34,2.5,1229877775 -200,39,5.0,1229886362 -200,47,4.0,1229885752 -200,62,3.0,1229886642 -201,1,5.0,939801780 -201,11,4.0,939227085 -201,16,4.0,939227554 -201,24,4.0,941211478 -201,25,5.0,939227591 -201,32,4.0,939833041 -201,34,5.0,939801740 -201,46,1.0,939227085 -202,1,4.0,974923506 -202,2,4.0,974923336 -202,6,5.0,974918622 -202,10,4.0,974919042 -202,11,4.0,975013705 -202,29,4.0,974923156 -202,32,4.0,974925068 -202,44,2.0,974923392 -202,49,3.0,974925453 -202,50,4.0,974924628 -202,58,4.0,975013724 -202,62,3.0,975013683 -203,31,3.5,1390094511 -204,47,5.0,1327182956 -206,1,5.0,850763267 -206,7,4.0,850763310 -206,14,4.0,850763367 -206,17,5.0,850763267 -206,25,5.0,850763267 -206,32,3.0,850763267 -206,36,5.0,850763310 -206,58,5.0,850763367 -206,62,4.0,850763267 -206,95,3.0,850763267 -207,100,3.0,1258548270 -208,10,2.0,940639452 -211,50,4.0,1350912267 -213,1,3.5,1316196157 -214,1,3.0,853937855 -214,17,3.0,853937855 -214,25,2.0,853937855 -214,62,3.0,853937855 -214,66,3.0,853938014 -214,83,3.0,853938185 -215,50,5.0,1260908668 -216,1,3.0,975211713 -216,21,3.0,975212544 -216,34,5.0,975212451 -216,39,3.0,975212451 -216,48,2.0,975211866 -217,1,4.0,955942540 -217,2,2.0,955942327 -217,3,1.0,955944713 -217,6,2.0,955935939 -217,9,3.0,955941157 -217,10,4.0,955940584 -217,12,3.0,955945336 -217,19,1.0,955945611 -217,20,2.0,955941424 -217,22,3.0,955943052 -217,34,4.0,955943345 -217,38,2.0,955945548 -217,44,2.0,955941505 -217,45,2.0,955943999 -217,47,2.0,955942953 -217,50,3.0,955942801 -217,60,2.0,955942221 -217,65,1.0,955945452 -217,87,3.0,955945423 -217,89,4.0,955940533 -217,95,3.0,955941157 -219,1,3.5,1194681084 -219,2,2.5,1194740185 -219,6,3.5,1198783144 -219,10,4.5,1194932162 -219,19,2.5,1194932235 -219,21,3.5,1199581468 -219,32,3.5,1194686177 -219,44,1.5,1195349252 -219,47,3.5,1194686017 -219,50,5.0,1194685882 -219,65,1.0,1198782611 -219,95,1.5,1198782277 -220,1,5.0,1230055565 -220,6,3.5,1230061735 -220,10,4.0,1230055828 -220,32,4.5,1230055680 -220,34,4.5,1230055796 -220,47,3.0,1230055738 -220,50,5.0,1230054959 -221,2,3.5,1111177796 -221,29,4.5,1119984574 -221,32,5.0,1111177792 -221,50,4.5,1118246575 -221,58,4.5,1111176234 -222,2,2.5,1391353926 -222,19,3.5,1391351897 -222,32,3.0,1391353917 -222,47,4.0,1391350444 -222,50,3.0,1391346849 -223,1,3.5,1226209758 -223,34,1.0,1226209953 -223,47,3.0,1226209770 -224,39,5.0,971812919 -225,69,5.0,949111262 -226,1,3.5,1095662606 -226,2,3.0,1095662788 -226,3,3.5,1095662861 -226,10,4.0,1095662675 -226,16,4.5,1095662900 -226,19,3.5,1095662814 -226,22,2.0,1095662268 -226,32,4.0,1095662618 -226,39,3.0,1095662724 -226,44,3.5,1095663137 -226,47,5.0,1160003508 -226,48,3.0,1095663041 -226,60,2.5,1114838860 -226,63,3.5,1096420461 -226,65,3.0,1095712984 -226,69,4.0,1172040506 -226,88,3.0,1097545177 -227,17,3.5,1447210004 -227,32,4.5,1447210296 -227,47,5.0,1447209787 -228,50,4.5,1363222968 -228,65,2.0,1363222731 -229,1,5.0,838144316 -229,5,3.0,838143681 -229,10,4.0,836941790 -229,19,3.0,836942063 -229,21,4.0,836942097 -229,34,5.0,836942064 -229,36,4.0,838147251 -229,45,3.0,838143681 -230,2,2.5,1196305107 -230,34,2.0,1196304670 -230,39,3.0,1196304844 -230,47,3.0,1196304391 -232,1,3.5,1076955621 -232,2,4.0,1085351710 -232,10,3.0,1218167397 -232,39,3.0,1182909940 -232,47,4.5,1241823324 -232,48,2.5,1218169473 -233,1,3.0,1524781249 -233,47,3.5,1524781264 -233,50,4.0,1472587568 -234,1,5.0,1004409347 -234,24,5.0,1004407893 -234,34,3.0,1004409582 -234,42,4.0,1004408338 -234,48,5.0,1004409503 -234,60,4.0,1004409020 -234,65,3.0,1001975877 -235,10,2.0,841422389 -235,11,4.0,841422530 -235,21,4.0,841422461 -235,25,5.0,841422634 -235,32,4.0,841422499 -235,34,4.0,841422446 -235,36,4.0,841422650 -235,39,3.0,841422477 -235,48,3.0,841422615 -235,62,5.0,841422615 -237,32,5.0,1411233598 -237,50,2.5,1410631753 -239,1,4.0,1221158265 -239,6,5.0,1221158564 -239,11,5.0,1221159019 -239,16,4.5,1221159148 -239,20,3.5,1221147484 -239,21,4.0,1221158640 -239,23,3.5,1221147477 -239,32,5.0,1221159452 -239,47,5.0,1221158250 -239,50,4.5,1221158083 -239,95,3.5,1221158503 -240,1,5.0,849122434 -240,2,5.0,849122404 -240,3,4.0,849122858 -240,10,3.0,849122194 -240,16,3.0,849122640 -240,19,5.0,849122301 -240,31,4.0,849122640 -240,34,5.0,849122277 -240,39,5.0,849122324 -240,44,4.0,849122528 -240,46,3.0,849123161 -240,48,3.0,849122594 -240,60,4.0,849122924 -240,95,5.0,849122434 -241,47,4.0,1447540959 -241,50,4.0,1447536935 -242,21,3.0,834073178 -242,32,5.0,834073281 -242,39,3.0,834073303 -242,47,5.0,834073178 -243,10,5.0,837155138 -243,36,4.0,837155409 -243,44,4.0,837155345 -243,48,4.0,837155356 -243,62,5.0,837155394 -244,6,5.0,975092819 -244,10,5.0,975091789 -246,17,5.0,1354126066 -246,28,4.5,1354126962 -246,29,5.0,1353864666 -246,50,4.5,1353869486 -247,1,5.0,1467644119 -247,32,3.0,1467661273 -247,47,4.0,1467644262 -247,50,5.0,1467643861 -248,10,3.5,1534591944 -249,1,4.0,1347317775 -249,2,4.0,1353800871 -249,19,3.5,1354107358 -249,20,3.5,1355366891 -249,32,5.0,1346752537 -249,47,5.0,1346757700 -249,48,3.0,1346752050 -249,50,4.0,1364546154 -249,70,4.0,1355677606 -249,89,3.5,1370785235 -250,45,4.0,1121217522 -251,47,5.0,1470677268 -252,1,4.5,1498284904 -253,29,4.5,1286643322 -254,1,4.5,1180446553 -254,32,4.5,1180446451 -254,47,4.5,1180447550 -254,50,4.5,1180564704 -254,79,2.0,1180443477 -255,34,1.0,1005717433 -256,18,5.0,1447000271 -257,7,1.0,1141625546 -257,16,3.5,1141625441 -259,2,2.0,1146845339 -259,32,5.0,1146845633 -260,29,4.0,1109409486 -260,47,4.5,1109408487 -260,50,5.0,1109410623 -261,16,4.0,1404881583 -261,47,4.0,1404881499 -261,50,4.0,1404881245 -262,4,1.0,840306203 -262,7,3.0,840306238 -262,10,2.0,840305646 -262,17,3.0,840305810 -262,21,3.0,840305713 -262,25,3.0,840305912 -262,26,3.0,840309913 -262,28,5.0,840310932 -262,36,5.0,840305940 -262,48,1.0,840305912 -262,50,3.0,840305713 -262,57,3.0,840306644 -262,85,3.0,840306620 -263,1,4.0,940384199 -263,11,4.0,941590364 -263,17,5.0,940384427 -263,24,3.0,941590705 -263,34,4.0,940384374 -263,36,4.0,940384427 -263,39,4.0,941590574 -264,1,4.0,1136978964 -264,32,1.0,1136979041 -264,48,3.0,1136978326 -265,25,1.0,965318357 -265,32,4.0,965316504 -265,36,4.0,965316145 -265,79,2.0,965318627 -266,1,2.0,945669542 -266,6,4.0,944980835 -266,16,5.0,944981193 -266,17,1.0,944980787 -266,21,4.0,945669287 -266,24,1.0,948586506 -266,32,4.0,945751855 -266,39,2.0,945669397 -266,45,2.0,945669246 -266,50,4.0,944980462 -266,64,1.0,945669246 -266,69,5.0,945669505 -266,95,3.0,946768666 -267,29,4.0,997136080 -267,58,5.0,959807857 -268,29,5.0,940182766 -268,41,4.0,940181204 -268,46,1.0,940180773 -268,47,3.0,940180858 -268,50,5.0,940180799 -269,1,5.0,850865423 -269,3,4.0,850865480 -269,5,3.0,850865480 -269,6,5.0,850865480 -269,9,2.0,850865553 -269,25,5.0,850865423 -269,32,4.0,850865423 -269,63,3.0,850865688 -269,74,5.0,850865586 -269,76,2.0,850865622 -269,79,4.0,850865553 -269,81,3.0,850865720 -269,95,3.0,850865423 -270,1,5.0,853918728 -270,3,3.0,853918793 -270,5,3.0,853918793 -270,6,3.0,853918793 -270,7,3.0,853918793 -270,9,3.0,853918943 -270,14,5.0,853918850 -270,17,4.0,853918728 -270,25,4.0,853918728 -270,32,4.0,853918727 -270,36,5.0,853918793 -270,52,4.0,853918850 -270,58,4.0,853918849 -270,62,5.0,853918728 -270,79,2.0,853918942 -270,95,2.0,853918728 -271,32,4.0,1234302161 -273,1,5.0,835861234 -273,12,1.0,835860711 -273,21,5.0,835860782 -273,32,5.0,835861257 -273,34,4.0,835860782 -274,1,4.0,1171410158 -274,2,3.5,1171934785 -274,6,4.0,1197022122 -274,8,3.0,1172030892 -274,10,4.0,1171428459 -274,12,3.5,1171829597 -274,16,4.5,1171493420 -274,19,4.0,1171934796 -274,20,3.5,1171830022 -274,22,3.5,1171759024 -274,23,3.5,1171829251 -274,24,3.5,1171785219 -274,29,4.0,1238050945 -274,32,4.0,1171409321 -274,34,4.0,1171756208 -274,44,4.0,1171759773 -274,47,4.0,1171172762 -274,48,2.0,1171943719 -274,50,4.0,1171408986 -274,60,3.5,1171827419 -274,62,3.0,1171492326 -274,65,3.0,1171829616 -274,69,4.0,1171932360 -274,70,4.5,1171493880 -274,86,3.5,1171828191 -274,87,3.0,1197272712 -274,88,3.5,1171828649 -274,93,3.5,1172024378 -274,95,2.5,1174524214 -275,1,5.0,1049076484 -275,17,5.0,1049079511 -275,21,5.0,1049076555 -275,25,3.0,1049079449 -275,32,5.0,1049078728 -275,34,5.0,1049078728 -275,39,4.0,1049076538 -275,45,2.0,1049076616 -275,50,4.0,1049078044 -276,1,4.0,858350384 -276,2,4.0,858351189 -276,5,3.0,858350427 -276,7,4.0,858350645 -276,12,4.0,858350757 -276,19,4.0,858351186 -276,62,5.0,858350385 -276,88,5.0,858350816 -277,1,4.0,861812794 -277,32,5.0,861812794 -277,62,2.0,861812794 -277,65,3.0,861812976 -277,95,3.0,861812794 -278,50,5.0,1193753316 -279,1,3.0,1506394495 -279,50,3.5,1506394189 -280,1,4.5,1348435273 -280,7,4.5,1348532595 -280,19,3.0,1348435266 -280,27,4.5,1348531940 -280,39,4.0,1348532012 -280,50,4.5,1348434052 -282,1,4.5,1378495714 -282,6,4.0,1378497085 -282,10,3.5,1378497072 -282,16,4.0,1378491787 -282,25,4.0,1378490653 -282,31,4.5,1378488783 -282,32,4.0,1378497758 -282,50,4.5,1378489751 -283,1,3.0,901227602 -283,39,1.0,901228254 -283,63,3.0,901228285 -283,69,4.0,901228313 -283,70,3.0,901228337 -284,2,4.0,832699451 -284,10,4.0,832699451 -284,15,4.0,832699795 -284,19,4.0,832786975 -284,20,1.0,832699760 -284,21,3.0,832699760 -284,32,5.0,832699723 -284,39,3.0,832786975 -284,44,3.0,832699890 -284,47,3.0,832695534 -284,95,5.0,832699673 -286,6,4.5,1119563039 -286,7,3.5,1119562096 -286,39,3.5,1119562094 -286,47,5.0,1119562911 -286,70,3.0,1119563855 -287,16,2.0,1110229950 -287,29,4.5,1110231627 -287,48,1.0,1110229874 -287,50,3.5,1110230077 -287,62,2.0,1110231040 -288,1,4.5,1054568869 -288,2,2.0,978467973 -288,3,4.0,975691635 -288,5,2.0,978622571 -288,10,3.0,978465794 -288,12,2.0,978622871 -288,13,2.0,978469581 -288,17,3.5,1054569627 -288,21,4.0,975693063 -288,32,5.0,975692000 -288,34,4.0,975693063 -288,43,3.0,976122034 -288,47,3.5,1054568985 -288,48,2.0,978469623 -288,73,3.0,979163671 -288,87,3.0,1174395882 -288,95,1.0,978466299 -289,3,2.5,1143424657 -289,16,4.5,1143424648 -290,1,4.0,975031464 -290,11,4.0,974943069 -290,24,3.0,975032355 -290,25,4.0,974942930 -290,34,4.0,974942304 -290,36,4.0,975031318 -290,50,4.0,975031748 -291,1,4.0,1453051567 -292,1,4.0,1219625000 -292,10,3.5,1219625069 -292,19,1.5,1442099069 -292,32,2.0,1019516667 -292,34,3.5,1219625047 -292,62,3.0,1293563062 -293,1,3.0,1044870886 -294,2,3.0,966634189 -294,3,1.0,966596854 -294,6,3.0,966597476 -294,10,3.0,966634030 -294,12,1.0,966597190 -294,19,2.0,966597233 -294,21,3.0,966595514 -294,39,2.0,966595276 -294,44,3.0,966634266 -294,47,2.0,966597476 -294,50,3.0,966597387 -294,60,1.0,966634119 -294,65,3.0,966597039 -294,69,4.0,966596095 -294,70,4.0,966595946 -295,18,3.5,1320064940 -295,29,5.0,1320064417 -295,50,5.0,1320064969 -295,70,5.0,1320064943 -296,50,5.0,1532993858 -297,6,5.0,900871748 -297,22,2.0,900871989 -297,47,4.0,900871748 -297,50,5.0,900871748 -297,70,2.0,900871989 -297,79,1.0,900872461 -297,95,1.0,900872461 -297,100,1.0,900872461 -298,1,2.0,1447518257 -298,2,0.5,1450452897 -298,16,4.0,1447597782 -298,32,4.0,1450369288 -298,47,4.0,1447518037 -298,50,3.5,1447516828 -299,2,3.0,974620151 -301,10,4.0,1211378532 -301,17,4.0,1211378910 -301,21,4.0,1211378459 -301,36,4.5,1211378851 -301,47,4.5,1211377521 -301,50,4.5,1211377304 -302,3,3.0,854472084 -302,14,4.0,854472122 -302,17,5.0,854472022 -302,21,4.0,854473184 -302,25,5.0,854472022 -302,32,3.0,854472021 -302,36,4.0,854472084 -302,47,5.0,854473264 -302,58,5.0,854472122 -302,95,3.0,854472021 -303,16,2.5,1053302761 -303,32,3.5,1053303318 -304,1,5.0,881428344 -304,2,4.0,891173962 -304,7,4.0,881428370 -304,10,4.0,891173528 -304,11,5.0,891173135 -304,13,4.0,913327439 -304,17,3.0,891174111 -304,21,4.0,896268435 -304,32,4.0,881427991 -304,36,1.0,881428195 -304,46,5.0,911720227 -304,58,4.0,899026578 -304,60,1.0,891174024 -304,62,5.0,881427812 -304,73,4.0,920884193 -304,81,4.0,947050233 -304,86,5.0,880915450 -305,2,3.5,1460136227 -305,6,3.5,1460222104 -305,16,4.5,1460136042 -305,25,3.0,1518197993 -305,32,5.0,1460222250 -305,34,3.0,1460136295 -305,47,4.0,1460135569 -305,50,5.0,1460134079 -305,70,5.0,1494259450 -307,1,4.0,1186160893 -307,2,2.5,1186161482 -307,3,3.5,1186161652 -307,10,2.5,1186161010 -307,16,4.5,1186087665 -307,18,3.0,1186410788 -307,19,4.0,1186084466 -307,21,2.5,1189457112 -307,22,2.0,1186162078 -307,24,2.0,1186162409 -307,27,2.5,1186172544 -307,31,1.5,1186162274 -307,32,3.5,1186160917 -307,39,2.0,1186161053 -307,47,4.0,1186160966 -307,50,4.5,1186160949 -307,62,3.0,1186161410 -307,65,2.5,1186086548 -307,70,3.5,1186161936 -307,72,2.0,1186173251 -307,88,3.5,1186086639 -307,94,3.5,1186086089 -308,2,3.0,1421374418 -308,3,0.5,1421374465 -308,6,1.0,1421374400 -308,19,1.0,1421374425 -308,21,1.0,1421374404 -308,25,1.0,1421374411 -308,36,1.0,1421374415 -308,39,3.0,1421374380 -308,48,4.0,1421374475 -308,50,2.5,1421373873 -309,50,4.5,1126451972 -310,16,1.0,1078647827 -310,58,4.5,1078647847 -311,16,2.5,1057854247 -311,40,3.5,1057854804 -312,6,4.0,1043177752 -312,16,4.0,1043177752 -312,32,4.0,1043176620 -313,6,3.0,1030556299 -313,10,4.0,1030556439 -313,29,4.0,1030474666 -313,32,4.0,1030475177 -313,39,4.0,1030555731 -313,47,5.0,1030476272 -313,50,5.0,1030476169 -313,70,4.0,1030475884 -313,76,1.0,1030475081 -314,1,3.0,834398280 -314,6,3.0,842432711 -314,7,4.0,834241492 -314,10,3.0,834241870 -314,11,5.0,834241810 -314,15,2.0,834428676 -314,17,4.0,834398442 -314,21,3.0,834398026 -314,22,3.0,834398622 -314,23,3.0,834241586 -314,26,4.0,834398961 -314,31,3.0,834241586 -314,32,3.0,839857723 -314,39,3.0,834398364 -314,41,3.0,834398878 -314,44,3.0,834398518 -314,47,1.0,834398302 -314,50,4.0,847175449 -314,52,3.0,845285951 -314,60,3.0,834790837 -314,62,4.0,836234560 -314,95,2.0,834241545 -314,100,3.0,847175533 -316,45,4.5,1111493212 -316,48,1.5,1111493120 -317,6,5.0,1430532917 -317,16,5.0,1430598211 -317,32,4.0,1430361493 -317,47,5.0,1430361508 -317,50,5.0,1430361374 -317,97,3.0,1430598706 -318,2,3.5,1270753195 -318,6,4.0,1347180277 -318,18,3.0,1426353075 -318,19,3.5,1262805276 -318,29,3.5,1413627585 -318,32,4.5,1263848497 -318,47,4.0,1433139531 -318,48,3.5,1275844835 -318,72,4.5,1417278807 -318,97,4.5,1419694783 -321,2,5.0,843212595 -321,3,3.0,843212762 -321,5,3.0,843212719 -321,19,3.0,843212522 -321,21,3.0,843212550 -321,24,4.0,843212762 -322,1,3.5,1217676206 -322,2,3.0,1217676495 -322,10,4.0,1217676313 -322,11,4.0,1217676534 -322,47,4.0,1217676246 -322,50,4.0,1217675827 -323,1,3.5,1422640363 -323,2,4.0,1422640110 -323,17,3.5,1422640288 -323,19,2.5,1422640116 -323,22,3.0,1422640551 -323,29,3.5,1422640570 -323,32,2.5,1422640375 -323,34,2.5,1422640415 -323,36,3.5,1422640290 -323,48,3.5,1422640448 -323,50,4.5,1422640061 -323,60,3.0,1422640654 -323,62,2.5,1422640114 -325,6,4.0,1039398204 -325,19,2.0,1039395714 -325,22,3.0,1039397193 -325,29,4.0,1039398353 -325,30,4.0,1039399501 -325,32,4.0,1039396494 -325,58,4.0,1039395583 -325,80,4.0,1039397611 -326,20,3.5,1322250792 -326,47,4.0,1419880411 -326,50,2.0,1322867550 -326,97,3.5,1443983581 -327,50,4.5,1234788095 -328,1,5.0,1494210665 -328,13,3.0,1494212082 -328,34,5.0,1494210549 -328,39,2.0,1494210780 -328,47,4.5,1494211964 -328,50,4.0,1494206971 -329,50,2.0,1523468332 -330,1,4.0,1285904910 -330,2,1.5,1285905277 -330,3,3.0,1285905545 -330,16,3.5,1285905440 -330,25,4.5,1285905238 -330,29,3.0,1285903982 -330,32,5.0,1285904958 -330,34,3.0,1285905096 -330,47,3.0,1285904519 -330,50,5.0,1285904637 -330,58,5.0,1285904454 -330,62,3.0,1285905259 -331,10,3.0,1537157573 -331,34,2.0,1537157568 -331,50,5.0,1537157516 -332,1,4.0,1352672340 -332,16,3.5,1352673555 -332,32,2.5,1352671273 -332,47,4.0,1352672211 -332,50,4.0,1352671786 -334,1,3.5,1225477466 -334,10,3.5,1234629982 -334,47,2.0,1234629901 -335,50,5.0,1261542414 -336,1,4.0,1122227329 -336,6,4.0,1122227549 -336,47,4.5,1122227343 -336,50,5.0,1120568496 -336,70,4.0,1120568169 -337,1,4.0,860255715 -337,3,4.0,860255784 -337,5,4.0,860255784 -337,6,5.0,860255784 -337,7,3.0,860255784 -337,9,5.0,860255929 -337,12,3.0,860255992 -337,14,3.0,860255866 -337,16,4.0,860256120 -337,17,4.0,860255716 -337,24,5.0,860256119 -337,25,4.0,860255716 -337,27,5.0,860256159 -337,31,5.0,860256120 -337,32,4.0,860255715 -337,36,4.0,860255783 -337,41,3.0,860255992 -337,47,5.0,860256118 -337,50,3.0,860256158 -337,62,3.0,860255716 -337,65,3.0,860255929 -337,66,4.0,860255992 -337,74,5.0,860255992 -337,76,5.0,860256043 -337,79,4.0,860255867 -337,95,5.0,860255716 -337,100,3.0,860255992 -338,50,4.5,1530148314 -339,1,4.0,1460183470 -339,6,4.0,1460345729 -339,16,4.5,1460794139 -339,32,3.0,1460518918 -339,47,4.5,1460186377 -340,10,4.0,848666415 -341,1,5.0,1439750939 -342,24,3.0,1042822170 -343,50,4.5,1202061253 -345,11,2.5,1342828883 -345,32,3.5,1342827269 -346,17,4.0,1155066710 -346,47,3.5,1172693170 -346,50,4.0,1125857414 -347,1,5.0,847645986 -347,2,3.0,847645925 -347,10,4.0,847645690 -347,11,4.0,847645925 -347,19,4.0,847645789 -347,32,3.0,847645812 -347,34,4.0,847645761 -347,39,4.0,847645812 -347,47,3.0,847645738 -348,50,5.0,1378850183 -349,10,4.0,834750699 -349,34,5.0,834750842 -350,1,4.0,864940931 -350,7,3.0,864941017 -350,12,3.0,864941118 -350,17,2.0,864940932 -350,32,4.0,864940930 -350,65,3.0,864941118 -350,95,3.0,864940931 -351,12,5.0,1325978665 -351,47,4.5,1326027964 -352,47,5.0,1493931953 -352,50,5.0,1493931911 -353,1,5.0,831939685 -353,2,4.0,831939875 -353,5,3.0,831939914 -353,6,4.0,831939947 -353,9,3.0,831940313 -353,10,3.0,831939669 -353,11,4.0,831939792 -353,19,4.0,831939775 -353,22,5.0,831939991 -353,25,4.0,831939875 -353,32,5.0,831939731 -353,34,5.0,831939731 -353,39,1.0,831939750 -353,47,5.0,831939731 -353,69,3.0,831940600 -353,70,4.0,831940127 -354,10,3.5,1200870391 -354,32,4.0,1200870157 -354,34,3.5,1200870571 -354,44,3.5,1200865357 -354,47,4.0,1200870867 -354,50,4.5,1200869832 -354,70,4.5,1200953640 -355,60,3.0,974966167 -356,21,3.5,1229140823 -356,50,3.5,1229142733 -356,62,4.5,1229142896 -357,1,5.0,1348610184 -357,2,3.0,1348611277 -357,11,3.5,1348612270 -357,16,3.5,1348610125 -357,17,5.0,1348612178 -357,19,2.0,1348612202 -357,34,4.0,1348611388 -357,36,3.5,1348610447 -357,39,4.5,1348612128 -357,50,5.0,1348610163 -357,62,3.0,1348612191 -359,1,4.0,1198112023 -359,2,3.5,1198112829 -359,34,2.5,1198112136 -359,58,4.5,1198113196 -361,10,3.5,1204045505 -361,70,2.0,1204046026 -362,6,4.0,1530637587 -362,16,4.0,1530640994 -362,31,4.0,1530642798 -362,47,4.5,1530640109 -362,50,3.5,1530637009 -362,70,4.0,1530637651 -363,50,4.0,1502584540 -363,95,3.0,1502584443 -364,1,5.0,869443366 -364,9,3.0,869443802 -364,32,3.0,869443366 -364,95,5.0,869443367 -367,1,5.0,997811550 -367,34,3.0,997811126 -367,39,4.0,997812337 -368,3,3.0,971273951 -368,6,4.0,971275527 -368,10,3.0,971276726 -368,16,4.0,971275668 -368,21,3.0,975828964 -368,22,3.0,971276062 -368,42,2.0,975828507 -368,47,4.0,971275475 -368,50,4.0,971275320 -368,70,3.0,971273705 -368,79,2.0,971276901 -368,81,3.0,975828421 -368,95,2.0,971277081 -369,19,4.0,1237081519 -369,47,3.5,1237083091 -370,39,3.5,1159162930 -370,47,3.5,1159162973 -370,50,4.5,1159161956 -371,48,4.5,1407691602 -372,1,3.0,874416443 -372,6,5.0,874415865 -372,8,2.0,874415441 -372,10,3.0,874416808 -372,11,4.0,874415285 -372,14,4.0,874416949 -372,16,4.0,874415966 -372,21,3.0,874416570 -372,25,4.0,874415164 -372,31,2.0,874416808 -372,32,4.0,874415441 -372,34,4.0,874415934 -372,36,3.0,874414994 -372,39,3.0,874417086 -372,41,4.0,874415991 -372,47,5.0,874417240 -372,48,2.0,874416616 -372,50,5.0,874414678 -372,52,4.0,874416234 -372,62,3.0,874415902 -372,70,3.0,874415199 -372,71,2.0,874416544 -372,81,2.0,874416280 -373,1,3.0,846830172 -373,2,3.0,846830111 -373,6,5.0,846830247 -373,11,2.0,846830094 -373,16,4.0,846830296 -373,19,1.0,846830035 -373,21,1.0,846830035 -373,22,3.0,846830333 -373,25,5.0,846830207 -373,32,4.0,846830055 -373,34,4.0,846830015 -373,44,1.0,846830190 -373,47,5.0,846829997 -373,50,5.0,846830055 -373,60,3.0,846830521 -373,95,2.0,846830128 -375,32,5.0,1225314381 -376,10,4.5,1364994181 -376,19,2.0,1364994453 -376,32,5.0,1364994049 -376,95,3.5,1364994336 -377,19,2.0,1340342704 -377,32,4.5,1340342216 -377,34,4.0,1340347654 -378,1,4.5,1445347576 -378,36,4.0,1445347078 -379,19,2.0,847397556 -379,21,2.0,847397556 -379,34,5.0,847397499 -379,47,3.0,847397459 -380,1,5.0,1493420345 -380,2,5.0,1493420295 -380,6,5.0,1494278663 -380,10,5.0,1493419787 -380,12,4.0,1493668065 -380,16,3.0,1494803499 -380,18,4.0,1494278868 -380,19,5.0,1493667522 -380,21,2.0,1493422718 -380,32,5.0,1493494899 -380,34,4.0,1493420018 -380,44,4.0,1493667678 -380,47,5.0,1493494893 -380,48,3.0,1493423481 -380,50,4.0,1493420347 -380,60,4.0,1494035896 -380,70,5.0,1493423196 -380,76,3.0,1494278971 -380,95,3.0,1493420301 -381,1,3.5,1164383653 -381,2,4.0,1166971855 -381,19,2.5,1165975855 -381,32,3.5,1200824503 -381,34,3.5,1164877286 -381,47,2.0,1166980226 -381,48,3.0,1165976148 -381,50,4.5,1168576731 -381,62,4.5,1263494357 -382,1,4.5,1515162628 -382,50,5.0,1515160611 -384,60,4.0,994038823 -385,1,4.0,834691642 -385,6,3.0,840648313 -385,10,3.0,834691622 -385,14,3.0,834692097 -385,16,3.0,834691914 -385,21,5.0,835118614 -385,25,3.0,834691845 -385,32,4.0,838323677 -385,45,3.0,837949548 -385,50,3.0,834691694 -385,62,3.0,836844635 -385,68,3.0,865024733 -385,85,3.0,844794767 -385,94,4.0,847137503 -385,95,3.0,834691768 -386,6,3.0,842613783 -386,10,3.0,842610246 -386,16,4.0,842613849 -386,20,2.0,842614033 -386,21,4.0,842610304 -386,22,3.0,842613867 -386,25,2.0,842613763 -386,32,3.0,842610360 -386,34,4.0,842610286 -386,39,3.0,842610325 -386,44,2.0,842613763 -386,45,3.0,842613904 -386,47,3.0,842610286 -386,50,3.0,842610344 -387,10,3.5,1094938515 -387,11,2.5,1117415000 -387,29,3.5,1094875272 -387,31,2.5,1094939853 -387,32,3.5,1094876449 -387,39,2.5,1095040527 -387,44,1.0,1182720368 -387,45,2.5,1094877493 -387,47,4.5,1094876919 -387,50,4.5,1094876246 -387,63,2.0,1095042100 -387,70,3.5,1183536308 -387,71,1.5,1150877466 -387,97,4.5,1199607279 -389,1,5.0,857934174 -389,5,4.0,857934242 -389,6,5.0,857934242 -389,9,3.0,857934552 -389,17,4.0,857934174 -389,25,4.0,857934175 -389,32,4.0,857934174 -389,62,5.0,857934174 -389,65,4.0,857934553 -389,95,4.0,857934174 -391,1,3.0,1032388077 -391,6,4.0,1030944221 -391,10,3.0,1030944309 -391,25,5.0,1030827466 -391,29,5.0,1030826859 -391,32,4.0,1030826859 -391,34,3.0,1032389962 -391,47,3.0,1030944178 -391,50,4.0,1030827636 -391,58,4.0,1030827343 -391,70,1.0,1030944454 -394,34,3.0,838994398 -394,50,5.0,838994626 -395,2,3.0,841503884 -395,10,3.0,841503555 -395,34,3.0,841503656 -395,48,2.0,841504003 -395,60,3.0,841505041 -395,95,3.0,841503940 -396,1,5.0,1111688626 -396,44,2.0,1111688564 -396,45,3.0,1111688518 -396,50,4.0,1111688630 -398,32,5.0,1311207513 -399,1,4.0,1167220428 -400,6,5.0,1498870480 -400,47,5.0,1498870391 -400,50,5.0,1498870285 -401,1,3.5,1510450550 -401,48,2.0,1514347122 -402,5,3.0,849598135 -402,9,3.0,849598259 -402,25,3.0,849598104 -402,36,3.0,849598135 -402,47,3.0,849654599 -402,52,3.0,849598217 -402,61,5.0,849598453 -402,95,4.0,849598075 -403,47,5.0,1225243620 -404,11,4.0,838376006 -404,17,4.0,838376049 -404,21,3.0,838375894 -404,34,4.0,838375864 -404,36,3.0,838376195 -404,47,3.0,838375864 -404,62,4.0,838376141 -405,16,4.0,1295916006 -405,25,4.0,1299377952 -405,32,4.5,1295910764 -405,70,4.0,1295917097 -408,10,4.5,1467913128 -408,19,3.5,1469521999 -408,44,3.5,1484264475 -409,39,4.0,968979119 -410,3,4.0,990910830 -410,11,3.0,990910298 -410,21,3.0,990910575 -410,52,4.0,990910213 -410,58,4.0,990807791 -411,1,5.0,835532155 -411,2,4.0,835532398 -411,4,2.0,835533021 -411,7,3.0,835533471 -411,10,3.0,835532065 -411,11,4.0,835532370 -411,21,4.0,835532191 -411,22,3.0,835532644 -411,31,4.0,835532539 -411,34,4.0,835532191 -411,46,2.0,835533337 -411,47,4.0,835532191 -411,50,3.0,835532221 -411,52,2.0,835533198 -411,62,5.0,835532559 -412,1,2.0,939114353 -412,17,5.0,939136944 -412,34,5.0,939114265 -412,47,3.0,939114573 -413,16,5.0,1484440002 -414,1,4.0,961438127 -414,2,3.0,961594981 -414,3,4.0,961439278 -414,5,2.0,961437647 -414,6,3.0,961515642 -414,7,3.0,961439170 -414,8,3.0,961594849 -414,10,3.0,961515863 -414,11,5.0,1052148205 -414,15,2.0,961514611 -414,16,3.0,961517557 -414,17,4.0,961513829 -414,18,3.0,961682128 -414,21,4.0,961438199 -414,22,3.0,961518227 -414,23,2.0,961682276 -414,24,3.0,961436964 -414,25,3.0,961517140 -414,27,2.0,961518812 -414,31,3.0,961518520 -414,32,5.0,961514667 -414,34,5.0,961438127 -414,36,3.0,961516989 -414,39,4.0,961438265 -414,42,2.0,961515844 -414,44,2.0,961516249 -414,45,3.0,961438476 -414,46,2.0,961514407 -414,47,4.0,961681857 -414,48,3.0,961437741 -414,50,5.0,961681714 -414,52,3.0,961438413 -414,54,1.0,1027521065 -414,57,3.0,961517912 -414,62,4.0,961517885 -414,65,2.0,961439623 -414,71,2.0,961515844 -414,72,4.0,961438532 -414,75,1.0,1027521022 -414,78,3.0,961518581 -414,81,2.0,961514568 -414,86,3.0,961437096 -414,88,2.0,961439433 -414,89,3.0,961515928 -414,92,2.0,961518731 -414,94,5.0,961517421 -414,95,2.0,961515958 -415,47,4.0,1382470301 -415,50,4.5,1382469955 -417,47,5.0,1532134167 -418,50,4.5,1461865740 -419,10,3.5,1321659128 -419,47,4.0,1321659049 -419,50,4.0,1321854706 -420,1,4.0,1218207191 -420,32,3.5,1218047864 -420,73,4.0,1218036406 -421,73,4.0,1311494239 -422,1,4.0,986173307 -424,32,3.5,1457901858 -424,47,5.0,1457842442 -424,50,5.0,1457842255 -425,2,3.0,1085477682 -425,6,4.0,1085477536 -425,10,3.0,1085477406 -425,32,4.0,1085477320 -425,34,3.5,1114173653 -425,36,3.0,1085477524 -425,47,4.5,1085477391 -425,50,4.5,1085477355 -425,58,3.5,1085490369 -425,70,4.0,1085490625 -425,95,2.5,1085477510 -426,2,4.5,1451080838 -426,31,5.0,1451080848 -426,47,0.5,1451081886 -427,16,4.0,1053068794 -427,58,2.0,1053071377 -428,9,2.0,1111524871 -428,19,1.0,1111523373 -428,22,2.5,1111487500 -428,44,2.0,1111623964 -428,69,3.5,1111524882 -428,70,3.0,1111524672 -428,95,2.0,1111524678 -429,22,4.0,828124615 -429,48,4.0,828124616 -429,60,4.0,828124616 -430,34,3.0,963889406 -432,1,2.5,1316391457 -432,2,4.0,1316391739 -432,19,2.0,1316391760 -432,25,4.5,1315243647 -432,36,3.5,1316391708 -432,47,4.0,1315244565 -432,50,3.0,1315243055 -433,47,3.0,1506823900 -433,50,5.0,1506823884 -434,1,4.0,1270604402 -434,2,2.5,1271039378 -434,6,4.0,1270603905 -434,10,3.5,1270606683 -434,32,3.5,1270604323 -434,34,3.5,1270604933 -434,39,3.0,1270606827 -434,47,4.0,1270603499 -434,95,2.0,1270606732 -435,48,4.0,1366675847 -435,50,4.0,1366676016 -436,1,4.0,833529571 -436,2,4.0,833529751 -436,8,3.0,833530760 -436,34,5.0,833529621 -436,48,4.0,833529821 -436,60,3.0,833530067 -437,5,2.0,859721015 -437,6,5.0,859721015 -437,9,3.0,859721103 -437,14,3.0,859721080 -437,16,5.0,859721743 -437,17,4.0,859720978 -437,25,4.0,859720978 -437,31,4.0,859721815 -437,32,4.0,859720977 -437,36,4.0,859721015 -437,43,3.0,859721556 -437,47,4.0,859721361 -437,50,4.0,859721362 -437,52,4.0,859721046 -437,62,3.0,859720978 -437,78,3.0,859721693 -437,79,2.0,859721080 -437,81,3.0,859721790 -437,86,3.0,859721170 -437,95,1.0,859720977 -438,1,4.5,1105650469 -438,6,5.0,1105664272 -438,10,4.0,1105664201 -438,11,4.0,1105668426 -438,19,3.0,1105666629 -438,21,3.5,1105666251 -438,32,4.0,1105666143 -438,44,3.0,1105667144 -438,62,4.0,1105649800 -438,70,3.0,1105762813 -438,71,2.0,1105664825 -438,95,3.5,1105666265 -440,29,4.5,1237569069 -441,10,4.5,1449070452 -441,47,4.5,1451166486 -443,1,4.0,1501722482 -444,6,4.0,832677558 -444,16,4.0,832678415 -444,21,4.0,832670075 -444,47,4.0,832670399 -444,50,5.0,832670838 -444,58,5.0,832679295 -444,97,5.0,839310140 -444,100,3.0,839310140 -445,17,3.5,1454621917 -445,32,5.0,1454622049 -445,47,4.5,1454622061 -446,2,3.0,843839379 -446,10,3.0,843839232 -446,11,4.0,843839379 -446,16,3.0,843839544 -446,17,5.0,843839379 -446,21,3.0,843839290 -446,25,3.0,843839504 -446,32,4.0,843839327 -446,34,5.0,843839272 -446,39,3.0,843839306 -446,45,3.0,843839593 -446,47,4.0,843839250 -446,50,4.0,843839306 -446,95,4.0,843839401 -447,2,5.0,836961067 -447,10,3.0,836960825 -447,31,4.0,836961195 -447,44,5.0,836961153 -447,48,3.0,836961178 -448,1,5.0,1019126661 -448,2,3.0,1019125424 -448,3,3.0,1019128536 -448,5,3.0,1019128415 -448,10,4.0,1019124400 -448,12,2.0,1019563753 -448,16,5.0,1019138531 -448,19,2.0,1019132168 -448,20,3.0,1019124922 -448,21,2.0,1019124231 -448,32,2.0,1019132949 -448,38,3.0,1019227804 -448,47,4.0,1019132386 -448,50,4.0,1064741727 -448,65,1.0,1028111080 -448,66,2.0,1019133230 -448,95,2.0,1019124644 -449,32,4.0,1053200119 -449,50,4.5,1053199959 -450,70,2.0,974705218 -451,1,5.0,854089165 -451,5,3.0,854089243 -451,6,4.0,854089242 -451,7,3.0,854089243 -451,17,5.0,854089172 -451,25,5.0,854089175 -451,32,5.0,854089163 -451,94,4.0,854089769 -451,95,4.0,854089167 -452,10,4.0,1013395144 -452,44,4.0,1019580991 -452,47,5.0,1019581177 -452,69,5.0,1019585277 -452,70,4.0,1013397998 -453,1,5.0,1005966797 -453,10,2.0,972621985 -453,16,3.0,972622830 -453,21,3.0,972621787 -453,32,5.0,972621444 -453,34,4.0,972622496 -453,47,5.0,972622637 -453,50,5.0,972621262 -453,70,4.0,972622055 -454,82,3.5,1279476639 -455,11,4.0,836436201 -455,34,4.0,836436023 -455,50,3.0,836436049 -455,62,4.0,836436499 -456,1,5.0,856883308 -456,3,3.0,856883349 -456,5,3.0,856883349 -456,9,4.0,856883450 -456,32,3.0,856883308 -456,64,3.0,856883540 -456,65,2.0,856883450 -456,74,4.0,856883468 -456,79,2.0,856883417 -457,34,2.0,993610564 -458,2,4.0,845653124 -458,5,3.0,845652992 -458,10,4.0,845651737 -458,21,5.0,845653030 -458,27,5.0,845652968 -458,39,4.0,845653086 -458,48,3.0,845652560 -458,62,5.0,845652560 -458,95,5.0,845652537 -460,1,4.5,1359177505 -462,1,1.5,1154037653 -462,10,3.0,1269929071 -462,16,3.5,1123893685 -462,21,4.0,1121923492 -462,25,3.0,1154037817 -462,32,3.5,1121921239 -462,36,3.5,1123891148 -462,47,4.0,1154037716 -462,50,3.5,1154037688 -462,52,3.0,1123890939 -464,9,2.5,1287400084 -464,16,4.5,1287400356 -464,20,4.0,1275548142 -464,23,3.0,1275548130 -464,25,4.0,1287400227 -464,31,4.0,1287400817 -464,32,3.5,1275548714 -464,47,5.0,1275549635 -465,95,3.0,959896430 -467,41,4.0,919671922 -467,58,5.0,919672099 -468,1,4.0,831400444 -468,32,4.0,831400500 -468,39,5.0,831400519 -468,47,5.0,831400545 -469,1,4.0,965336888 -469,6,3.0,965336673 -469,10,2.0,965334356 -469,11,3.0,965425831 -469,29,4.0,965335401 -469,32,5.0,965335350 -469,36,3.0,965846167 -469,39,2.0,965425327 -469,44,1.0,965335037 -469,45,4.0,965425742 -469,47,4.0,965336711 -469,50,4.0,965336630 -469,70,2.0,965334011 -469,89,4.0,965334954 -470,1,4.0,849224825 -470,2,3.0,849224778 -470,3,3.0,849370396 -470,5,3.0,849370453 -470,6,3.0,849843318 -470,7,3.0,849370453 -470,10,3.0,849075144 -470,14,4.0,849843318 -470,19,3.0,849075545 -470,21,3.0,849075545 -470,26,3.0,849843245 -470,32,3.0,849075682 -470,34,4.0,849075432 -470,36,4.0,849370395 -470,39,3.0,849075682 -470,41,3.0,849843245 -470,43,3.0,849370292 -470,47,3.0,849075299 -470,50,3.0,849075545 -470,62,3.0,849224778 -470,95,3.0,849843245 -471,1,5.0,1496671820 -472,50,5.0,1345843346 -473,60,2.0,1169351160 -474,1,4.0,978575760 -474,2,3.0,1046886814 -474,5,1.5,1053021982 -474,6,3.0,1047054565 -474,7,3.0,978576381 -474,11,2.5,1053021437 -474,14,3.0,1120827247 -474,16,4.0,1088426731 -474,17,5.0,974668666 -474,21,4.0,1119232784 -474,22,3.0,1046896006 -474,24,3.0,1060105861 -474,25,3.5,1127143175 -474,26,3.5,1136942664 -474,27,2.0,1069686414 -474,28,4.5,1165540007 -474,29,3.5,1053021379 -474,31,3.0,1060105936 -474,32,4.0,1081177409 -474,34,4.5,1081177349 -474,36,5.0,979180034 -474,38,1.0,1089387538 -474,39,3.5,1129579520 -474,41,3.5,1089386983 -474,43,3.5,1081177921 -474,45,4.0,1014924369 -474,46,3.0,1081178156 -474,47,4.0,979180247 -474,50,4.0,979179872 -474,52,4.0,1004131663 -474,57,3.0,1060105374 -474,58,3.5,1126533613 -474,62,2.5,1053021366 -474,74,3.0,974669217 -474,82,2.5,1121262740 -474,92,3.5,1087832141 -474,96,3.5,1053020997 -474,100,2.0,1048710159 -475,2,4.5,1498031744 -475,19,4.0,1498031776 -476,1,4.0,835021447 -476,2,4.0,835021693 -476,10,3.0,835021420 -476,11,3.0,835021635 -476,13,3.0,835022487 -476,32,4.0,835021513 -476,34,4.0,835021494 -476,45,3.0,835022455 -476,48,4.0,835022192 -476,73,4.0,835022035 -477,1,4.0,1200939636 -477,2,4.0,1200939962 -477,3,3.0,1200941177 -477,19,3.0,1200939977 -477,24,4.0,1201159341 -477,32,4.5,1200939654 -477,34,4.0,1200939719 -477,47,4.0,1200939679 -477,66,0.5,1201158662 -477,76,4.0,1201158833 -479,24,3.0,1039362593 -479,31,3.0,1039362413 -479,45,3.0,1039367502 -479,82,5.0,1039362593 -480,1,3.0,1179178004 -480,2,3.0,1179178191 -480,3,2.5,1179178556 -480,6,4.0,1179162163 -480,10,4.0,1179177922 -480,16,4.0,1179161099 -480,19,1.5,1179178233 -480,21,2.5,1179161927 -480,32,4.0,1179177844 -480,34,4.0,1179178044 -480,39,2.5,1179177930 -480,47,4.5,1179177656 -480,50,3.5,1179160287 -480,60,2.0,1179159595 -480,62,3.5,1179178063 -480,69,2.0,1179161861 -480,95,1.0,1179177869 -482,2,4.5,1105395956 -482,16,2.0,1105396054 -482,50,4.0,1105396885 -482,62,5.0,1105396550 -483,1,4.0,1178293130 -483,2,4.0,1178293652 -483,5,2.5,1327277284 -483,10,2.0,1178293444 -483,16,4.0,1178293782 -483,18,4.0,1215897224 -483,19,3.5,1181494938 -483,23,3.0,1215897538 -483,24,2.5,1327277916 -483,26,4.0,1215898801 -483,29,5.0,1181495581 -483,31,2.0,1181495275 -483,32,5.0,1178213437 -483,47,3.5,1178215187 -483,48,3.0,1181496689 -483,50,4.5,1204405320 -483,81,3.5,1215898195 -484,1,4.5,1342295949 -484,2,2.5,1342296219 -484,39,4.5,1342296074 -484,47,4.0,1342228947 -484,48,4.5,1342296910 -484,63,4.0,1342228081 -484,69,4.5,1342300148 -484,72,4.0,1342369324 -485,10,4.0,837943350 -486,6,5.0,839537263 -486,10,4.0,839537237 -486,21,4.0,839537017 -486,32,5.0,839537271 -486,39,3.0,839537186 -486,44,4.0,839537298 -486,47,3.0,839537220 -486,86,5.0,839537298 -486,95,3.0,839537249 -488,1,4.5,1112382025 -488,17,5.0,1112382176 -488,26,2.5,1112382126 -488,34,3.0,1112382292 -488,36,4.5,1112382199 -488,73,2.5,1112382455 -489,2,2.5,1333101570 -489,5,2.0,1385823772 -489,7,4.0,1334587547 -489,10,2.5,1333101410 -489,11,1.5,1334170648 -489,17,4.5,1332773255 -489,18,2.0,1333234401 -489,19,2.0,1333101593 -489,21,2.5,1333101507 -489,22,3.5,1333022826 -489,32,3.5,1333023575 -489,34,2.0,1333101391 -489,39,3.5,1332772964 -489,46,3.5,1333658594 -489,47,3.0,1333101316 -489,48,4.0,1334587634 -489,70,2.0,1385823826 -489,95,1.5,1333101502 -490,1,3.5,1328229305 -490,5,0.5,1324370305 -492,1,4.0,863975949 -492,3,4.0,863976005 -492,5,3.0,863976004 -492,6,3.0,863976004 -492,7,3.0,863976055 -492,9,5.0,863976201 -492,12,3.0,863976249 -492,14,3.0,863976101 -492,32,3.0,863975946 -492,36,4.0,863976004 -492,52,3.0,863976101 -492,61,4.0,863976447 -492,62,4.0,863975954 -492,63,3.0,863976526 -492,64,3.0,863976525 -492,65,5.0,863976248 -492,66,3.0,863976249 -492,74,4.0,863976249 -492,75,3.0,863976878 -492,76,5.0,863976409 -492,79,4.0,863976101 -492,88,5.0,863976409 -492,95,3.0,863975954 -492,100,3.0,863976249 -493,6,4.0,1001562846 -495,19,4.5,1458636447 -495,50,4.0,1458634563 -497,2,2.5,1429127190 -497,19,4.0,1429127195 -497,50,3.0,1429127291 -498,7,4.0,839197378 -498,10,3.0,839197307 -498,34,3.0,839197341 -498,47,3.0,839197341 -498,62,5.0,839197444 -500,1,4.0,1005527755 -500,11,1.0,1005528017 -500,39,1.0,1005527926 -501,2,3.0,844973419 -501,3,5.0,844973817 -501,5,3.0,844973535 -501,6,3.0,844973487 -501,7,4.0,844973817 -501,8,3.0,844974090 -501,10,4.0,844973340 -501,11,3.0,844973340 -501,15,1.0,844973980 -501,16,3.0,844973535 -501,17,3.0,844973419 -501,18,5.0,844974006 -501,20,1.0,844974037 -501,21,3.0,844973340 -501,25,2.0,844973487 -501,27,3.0,844973931 -501,32,3.0,844973340 -501,36,3.0,844973487 -501,45,3.0,844973535 -501,50,3.0,844973340 -501,61,3.0,844973980 -501,62,3.0,844973487 -501,73,2.0,844974214 -501,86,3.0,844974037 -501,93,3.0,844974090 -501,95,4.0,844973419 -502,45,3.5,1111757345 -504,1,4.0,1063644695 -504,22,3.5,1063644469 -505,47,5.0,1298780253 -506,27,3.0,1424487740 -506,39,5.0,1424487595 -507,34,5.0,838964683 -507,39,3.0,838964728 -507,47,3.0,838964683 -509,1,4.0,1435992343 -509,5,1.5,1435992893 -509,13,3.0,1436101243 -509,17,3.0,1435992515 -509,19,4.0,1436027225 -509,28,3.5,1436031727 -509,32,4.0,1435998135 -509,34,3.5,1435998986 -509,39,4.0,1435992749 -509,48,3.5,1436000115 -510,7,1.0,1141158812 -510,16,1.0,1141158760 -510,50,4.0,1141160526 -512,2,3.0,841449636 -512,32,5.0,841449445 -512,39,4.0,841449426 -512,47,5.0,841449359 -512,50,5.0,841449402 -513,7,3.0,1159980407 -513,32,4.0,1159980466 -514,1,4.0,1533872400 -514,11,4.0,1533949297 -514,16,3.5,1533872553 -514,22,3.0,1533947171 -514,34,4.0,1533872519 -514,44,2.5,1533945558 -514,47,4.0,1533872325 -514,62,4.0,1533949200 -515,50,4.5,1513678307 -517,1,4.0,1487954343 -517,2,3.0,1487954340 -517,10,0.5,1487957717 -517,17,0.5,1487953834 -517,34,5.0,1487954303 -517,47,2.0,1487958109 -518,24,2.5,1056907643 -518,31,1.0,1056907629 -520,10,4.0,1326609139 -520,19,1.0,1326609359 -520,32,3.5,1326608236 -521,5,3.0,852713143 -521,6,4.0,852713143 -521,7,3.0,852713143 -521,14,4.0,852713185 -521,18,4.0,852713356 -521,25,5.0,852713083 -521,29,3.0,852713417 -521,32,3.0,852713082 -521,36,4.0,852713143 -521,43,4.0,852713446 -521,52,4.0,852713185 -521,58,4.0,852713185 -521,79,4.0,852713251 -521,81,3.0,852713417 -521,86,4.0,852713380 -521,95,3.0,852713082 -522,1,3.0,1253344674 -522,10,4.5,1253344761 -522,50,4.5,1253430096 -522,62,3.0,1253345769 -523,2,4.5,1503126180 -524,1,4.0,851608466 -524,6,4.0,852404399 -524,10,4.0,851608818 -524,12,1.0,852404800 -524,19,3.0,851609256 -524,20,2.0,851609083 -524,21,3.0,852404913 -524,23,2.0,851608986 -524,25,3.0,851608466 -524,32,3.0,851608466 -524,47,5.0,851608960 -524,50,2.0,851608781 -524,76,2.0,852404800 -524,86,3.0,852404550 -524,95,4.0,851608466 -525,1,4.0,1476475973 -525,2,3.5,1476480324 -525,34,3.0,1476480775 -525,39,4.5,1476477672 -525,47,3.5,1476476493 -525,48,3.0,1476480566 -525,50,4.5,1476476363 -525,62,3.5,1476480183 -527,2,4.0,1033173338 -527,30,1.0,1033173581 -527,34,5.0,1033173966 -527,48,3.0,1033173290 -528,1,2.5,1391736605 -529,1,3.0,855583216 -529,7,2.0,855583292 -529,32,5.0,855583215 -529,62,3.0,855583216 -529,65,1.0,855583470 -529,95,4.0,855583216 -530,11,4.0,843227087 -531,10,4.0,1032961647 -532,6,5.0,1025523798 -533,1,5.0,1424753740 -534,1,4.0,1459787997 -534,2,4.5,1459787996 -534,10,4.0,1459787996 -534,19,4.0,1459787996 -534,31,3.5,1459788707 -534,34,4.0,1459793302 -534,44,4.0,1459788735 -534,47,4.0,1459787998 -534,48,4.0,1459792580 -536,45,5.0,832840081 -539,65,4.5,1332474525 -539,88,3.5,1332474517 -540,47,4.5,1179109020 -541,1,3.0,835643027 -541,7,4.0,835644446 -541,10,4.0,835642985 -541,11,4.0,835643146 -541,15,3.0,835643931 -541,19,2.0,835643052 -541,22,4.0,835643333 -541,47,1.0,835643038 -541,50,5.0,835643052 -541,95,3.0,835643186 -542,47,5.0,1163386913 -544,1,3.0,850688537 -544,3,3.0,850688562 -544,14,3.0,850688581 -544,32,3.0,850688537 -544,40,5.0,850688776 -544,62,5.0,850688537 -544,68,5.0,850688776 -544,95,4.0,850688537 -545,44,2.5,1240358381 -546,70,5.0,973588518 -548,69,5.0,1488243429 -550,1,4.0,1488728441 -551,47,4.5,1505548073 -552,3,1.0,1111472953 -552,19,3.5,1111473056 -552,25,3.0,1112151250 -552,95,1.5,1111473067 -553,6,5.0,1219558120 -553,16,5.0,1219558107 -553,32,5.0,1219564918 -553,42,4.0,1219559052 -553,50,4.0,1219557525 -555,1,4.0,978746159 -555,3,5.0,978747454 -555,19,3.0,980123949 -555,21,4.0,978746440 -555,24,5.0,978841879 -555,29,4.0,978841345 -555,32,4.0,978841464 -555,39,4.0,978746326 -555,50,5.0,978819462 -555,65,3.0,980125946 -555,72,3.0,978746552 -555,75,3.0,980125866 -555,88,4.0,980126008 -557,10,4.5,1452797765 -558,94,3.0,1035415930 -559,1,5.0,865095758 -559,2,4.0,845476032 -559,6,5.0,865095857 -559,10,3.0,845475880 -559,15,3.0,845476569 -559,19,2.0,845475946 -559,32,3.0,845475965 -559,34,5.0,845475917 -559,36,4.0,845476089 -559,39,3.0,845475987 -559,48,3.0,845476159 -559,58,4.0,865095758 -559,66,3.0,865096234 -559,76,3.0,865096444 -559,95,4.0,865095801 -560,1,3.0,1469653413 -560,32,3.5,1469647882 -560,34,2.5,1469647264 -560,47,4.0,1469648029 -560,48,2.5,1469654312 -560,50,4.0,1469647239 -560,70,4.0,1469653546 -560,97,4.0,1469653182 -561,1,4.0,1491094681 -561,2,4.0,1491094318 -561,5,3.0,1491094488 -561,6,4.0,1491092289 -561,31,2.5,1491094481 -561,32,3.5,1491091981 -561,34,2.5,1491095062 -561,39,3.0,1491091334 -561,44,2.0,1491091620 -561,47,4.5,1491091954 -561,50,4.5,1491090860 -562,1,4.5,1368893997 -562,50,4.0,1368894758 -563,2,2.5,1447185161 -563,34,2.0,1441846213 -563,48,3.5,1440800284 -564,39,3.5,1478453734 -565,19,3.0,846533399 -565,21,3.0,846533399 -565,32,5.0,846533428 -565,34,4.0,846533367 -565,47,4.0,846533338 -565,50,5.0,846533399 -566,2,4.0,849005893 -566,7,4.0,849006845 -566,10,3.0,849005345 -566,11,5.0,849005826 -566,17,5.0,849006000 -566,21,4.0,849005643 -566,25,2.0,849006116 -566,32,4.0,849005720 -566,39,4.0,849005720 -566,50,5.0,849005642 -566,57,3.0,849006827 -567,1,3.5,1525286001 -567,34,2.5,1525288053 -567,50,1.0,1525282012 -568,50,5.0,1243576177 -569,10,4.0,849190709 -569,50,3.0,849190709 -570,1,4.0,1181476989 -570,2,3.5,1181477805 -570,10,3.5,1181477300 -570,11,3.5,1181477768 -570,25,4.0,1181477537 -570,32,4.0,1181477032 -570,34,3.5,1181477210 -570,39,3.0,1181477492 -570,47,3.5,1181477162 -570,95,2.5,1181477499 -571,12,1.0,966901337 -571,70,2.0,966900368 -572,1,4.0,945892484 -572,17,5.0,945888053 -572,21,5.0,945890765 -572,62,4.0,945890338 -573,1,5.0,1186722182 -573,2,4.5,1187044862 -573,6,4.5,1248842019 -573,10,4.5,1186722464 -573,47,5.0,1186589586 -573,50,5.0,1248841981 -574,47,5.0,834634527 -576,29,3.5,1358151482 -577,6,4.0,945967415 -577,39,3.0,945964946 -577,88,3.0,945968259 -579,1,4.0,958881146 -579,11,3.0,958879371 -579,17,5.0,977364909 -579,34,3.0,958880089 -579,48,4.0,958881238 -580,1,3.0,1167792349 -580,6,4.0,1167789917 -580,10,3.5,1167792602 -580,16,4.5,1167790725 -580,22,4.0,1167861702 -580,25,4.0,1167789966 -580,32,5.0,1167790855 -580,34,2.5,1167673463 -580,47,5.0,1167791127 -580,50,5.0,1167789884 -580,62,2.0,1167790047 -580,70,5.0,1167673477 -583,39,5.0,1481474136 -584,1,5.0,834987643 -584,10,5.0,834987172 -584,19,3.0,834987751 -584,22,4.0,834988132 -584,34,3.0,834987730 -584,39,1.0,834987810 -584,47,5.0,834987730 -584,48,5.0,834988006 -584,60,5.0,834988340 -585,16,5.0,1307417343 -585,88,4.0,1307416427 -586,2,4.0,1529901723 -587,1,5.0,953137847 -587,11,4.0,953138510 -587,21,4.0,953138653 -587,32,5.0,953141417 -587,50,5.0,953141366 -587,58,5.0,953141592 -588,3,3.0,839317471 -588,6,5.0,839316454 -588,10,3.0,839316215 -588,16,4.0,839316454 -588,20,2.0,839317230 -588,21,3.0,839316350 -588,22,3.0,839317568 -588,25,3.0,839316993 -588,36,2.0,839316709 -588,42,3.0,839316637 -588,47,3.0,839316278 -588,50,5.0,839316659 -589,25,5.0,856038816 -589,36,5.0,856038894 -590,1,4.0,1258420408 -590,2,2.5,1258420835 -590,3,3.0,1258416995 -590,5,2.0,1258421220 -590,6,3.5,1258420706 -590,10,3.5,1258420600 -590,11,3.0,1258419975 -590,17,3.5,1258418302 -590,19,2.0,1258420848 -590,32,3.0,1258420444 -590,36,3.5,1258420766 -590,47,3.0,1258420506 -590,50,4.5,1264910688 -591,24,2.0,970525102 -592,2,4.0,837350242 -592,6,3.0,837350390 -592,10,3.0,837349966 -592,15,4.0,837350747 -592,19,4.0,837350082 -592,21,3.0,837350081 -592,24,4.0,837350801 -592,39,4.0,837350111 -592,44,3.0,837350308 -592,93,3.0,837350801 -592,95,3.0,837350282 -593,34,4.0,1181008004 -593,41,4.0,1181007216 -593,50,4.5,1181007737 -594,2,4.0,1109037094 -594,3,4.0,1108798921 -594,11,5.0,1109036973 -594,17,4.0,1108972872 -594,28,4.5,1108973143 -594,39,4.5,1115885611 -594,46,4.5,1108973615 -594,48,4.5,1109038257 -594,70,3.5,1108951120 -595,50,5.0,938807286 -596,1,4.0,1535709666 -596,32,3.5,1535709749 -596,34,4.0,1535827362 -596,39,4.0,1535827547 -596,50,3.5,1535709301 -597,1,4.0,941557863 -597,6,3.0,940420695 -597,7,1.0,941558874 -597,10,3.0,941729264 -597,11,3.0,941558713 -597,17,3.0,940362409 -597,21,5.0,941559030 -597,34,4.0,940362281 -597,39,4.0,941558116 -597,42,3.0,941729264 -597,45,5.0,941559030 -597,47,4.0,940361541 -597,50,5.0,940362491 -597,52,4.0,941559030 -597,69,4.0,941558258 -597,70,2.0,941559139 -599,1,3.0,1498524204 -599,2,2.5,1498514085 -599,3,1.5,1498505071 -599,6,4.5,1498539623 -599,7,2.5,1498514161 -599,9,1.5,1498504960 -599,10,3.5,1498500281 -599,11,2.5,1498516445 -599,12,1.5,1519181787 -599,15,1.5,1519239842 -599,16,3.0,1498523389 -599,17,3.5,1498501103 -599,18,3.0,1498523048 -599,19,3.0,1498524930 -599,20,1.5,1498504813 -599,21,4.0,1498499235 -599,23,1.0,1498503332 -599,24,2.5,1498517444 -599,26,2.5,1498518655 -599,29,3.5,1498500987 -599,31,2.0,1498511120 -599,32,3.0,1498519822 -599,39,3.0,1498525783 -599,41,2.5,1498518847 -599,42,3.0,1498525483 -599,43,3.0,1519347048 -599,44,2.5,1498517161 -599,45,2.5,1498516640 -599,47,4.0,1498499364 -599,50,3.5,1498500777 -599,52,3.0,1498525392 -599,57,2.5,1519240604 -599,60,2.0,1519118310 -599,61,2.5,1519327817 -599,65,2.0,1498511235 -599,69,2.5,1498515243 -599,70,3.5,1498501183 -599,73,3.0,1519421396 -599,75,1.0,1519353713 -599,76,2.5,1498518457 -599,79,2.0,1519336237 -599,81,2.5,1498517265 -599,87,0.5,1519184941 -599,88,0.5,1498533540 -599,89,2.5,1498517086 -599,93,1.5,1498504070 -599,95,2.0,1498510588 -599,97,3.0,1519120150 -599,100,2.0,1498511085 -600,1,2.5,1237764347 -600,2,4.0,1237764627 -600,4,1.5,1237760055 -600,5,2.5,1237759452 -600,7,3.5,1237851387 -600,17,3.5,1237712509 -600,19,3.0,1237709125 -600,24,2.0,1237707977 -600,29,4.5,1237713604 -600,32,4.5,1237858629 -600,34,2.0,1237711536 -600,39,3.0,1237858693 -600,46,3.0,1237851925 -600,47,4.0,1237852430 -600,52,3.5,1237715563 -600,62,2.5,1237713038 -600,72,1.0,1237760885 -600,73,3.5,1237760041 -601,1,4.0,1521467801 -601,47,4.0,1521467863 -601,50,5.0,1441639169 -602,2,4.0,840875851 -602,6,3.0,840876055 -602,10,3.0,840875622 -602,11,3.0,840875825 -602,14,5.0,840875999 -602,16,3.0,840876085 -602,19,2.0,840875700 -602,21,4.0,840875720 -602,22,3.0,840876417 -602,25,4.0,840875998 -602,29,2.0,840876620 -602,32,3.0,840875779 -602,34,1.0,840875700 -602,36,3.0,840876228 -602,39,5.0,840875757 -602,45,5.0,840876055 -602,47,5.0,840875668 -602,50,5.0,840875720 -602,52,3.0,840876566 -602,95,3.0,840875901 -602,100,3.0,840876228 -603,1,4.0,963178147 -603,6,4.0,963177624 -603,16,4.0,963179585 -603,17,3.0,954482210 -603,21,5.0,963177624 -603,25,4.0,954482181 -603,28,5.0,953925191 -603,29,2.0,963177361 -603,30,4.0,963179273 -603,32,3.0,963179615 -603,34,4.0,963179273 -603,36,4.0,953925157 -603,39,5.0,954482276 -603,45,4.0,963179538 -603,52,1.0,963178236 -603,53,5.0,963180003 -603,57,2.0,963180025 -603,58,3.0,954482414 -603,62,1.0,963180075 -603,70,4.0,953925705 -603,77,4.0,954482106 -603,82,1.0,963180075 -603,85,5.0,953925191 -603,97,4.0,963179791 -603,99,5.0,954482070 -604,1,3.0,832079851 -604,2,5.0,832080293 -604,5,3.0,832080355 -604,6,3.0,832080355 -604,14,4.0,832081027 -604,17,4.0,832080092 -604,19,1.0,832080050 -604,22,3.0,832080546 -604,23,4.0,832081042 -604,25,3.0,832080316 -604,32,4.0,832079958 -604,34,4.0,832079958 -604,39,3.0,832079983 -604,60,4.0,832080939 -604,62,4.0,832080293 -604,76,4.0,832080615 -604,92,3.0,832080615 -604,95,4.0,832080071 -605,1,4.0,1277097561 -605,2,3.5,1277176522 -605,28,4.0,1277094943 -605,73,3.0,1277094964 -606,1,2.5,1349082950 -606,7,2.5,1171754710 -606,11,2.5,1174349629 -606,15,3.5,1171839063 -606,17,4.0,1171838026 -606,18,4.0,1171327151 -606,19,2.0,1171814553 -606,28,3.5,1173049970 -606,29,4.5,1179419005 -606,32,4.0,1173653921 -606,36,3.5,1171820699 -606,46,4.0,1171757334 -606,47,3.0,1171927423 -606,50,4.5,1171234887 -606,58,3.5,1181771144 -606,68,4.0,1171817003 -606,70,4.0,1171733439 -606,73,4.0,1171410274 -606,80,4.0,1171409272 -606,82,4.0,1175637619 -606,92,3.5,1171365342 -607,1,4.0,964744033 -607,11,3.0,964744602 -607,25,3.0,963078417 -607,34,3.0,963079238 -607,36,4.0,964744413 -607,86,4.0,963079311 -608,1,2.5,1117408267 -608,2,2.0,1117490786 -608,3,2.0,1117504413 -608,10,4.0,1117408486 -608,16,4.5,1189471181 -608,19,2.0,1117504385 -608,21,3.5,1147210949 -608,24,2.0,1117504646 -608,31,3.0,1117504582 -608,32,3.5,1117336682 -608,34,3.5,1117491662 -608,39,3.0,1117415401 -608,44,0.5,1117504562 -608,47,4.5,1117162426 -608,48,0.5,1117161754 -608,50,4.5,1117491010 -608,63,0.5,1117506926 -608,65,2.0,1117415653 -608,70,3.0,1117415406 -608,88,2.5,1117505159 -608,93,2.5,1117506858 -608,95,2.0,1117490752 -609,1,3.0,847221025 -609,10,4.0,847220937 -610,1,5.0,1479542900 -610,6,5.0,1493850345 -610,16,4.5,1479542171 -610,32,4.5,1479543331 -610,47,5.0,1479545853 -610,50,4.0,1493844757 -610,70,4.0,1495959282 -610,95,3.5,1479542004 diff --git a/tests/unused/unit/ml_handlers/data/vertex_anomaly_detection.csv b/tests/unused/unit/ml_handlers/data/vertex_anomaly_detection.csv deleted file mode 100755 index b87f4cb8e2d..00000000000 --- a/tests/unused/unit/ml_handlers/data/vertex_anomaly_detection.csv +++ /dev/null @@ -1,6 +0,0 @@ -carat,cut,color,clarity,depth,table,x,y,z -0.23,Ideal,E,VS2,61.5,55,3.95,3.98,2.43 -0.21,Premium,E,VS2,59.8,61,3.89,3.84,2.31 -0.23,Good,E,VS2,56.9,65,4.05,4.07,2.31 -0.29,Premium,I,VS2,62.4,58,4.2,4.23,2.63 -0.31,Good,J,VS2,63.3,58,4.34,4.35,2.75 \ No newline at end of file diff --git a/tests/unused/unit/ml_handlers/data/vertex_classification.csv b/tests/unused/unit/ml_handlers/data/vertex_classification.csv deleted file mode 100644 index 994bd3a5804..00000000000 --- a/tests/unused/unit/ml_handlers/data/vertex_classification.csv +++ /dev/null @@ -1,6 +0,0 @@ -Amount,Class,Time,V1,V10,V11,V12,V13,V14,V15,V16,V17,V18,V19,V2,V20,V21,V22,V23,V24,V25,V26,V27,V28,V3,V4,V5,V6,V7,V8,V9 -149.62,'0',0,-1.3598071337,0.090794172,-0.5515995333,-0.6178008558,-0.9913898472,-0.3111693537,1.4681769721,-0.47040052530000004,0.20797124190000002,0.0257905802,0.40399296030000004,-0.0727811733,0.2514120982,-0.0183067779,0.2778375756,-0.1104739102,0.06692807490000001,0.12853935830000002,-0.1891148439,0.1335583767,-0.021053053500000002,2.5363467379999998,1.3781552243,-0.3383207699,0.4623877778,0.2395985541,0.0986979013,0.3637869696 -2.69,'0',0,1.1918571113,-0.16697441400000002,1.6127266611,1.0652353114,0.48909501590000004,-0.1437722964,0.6355580933,0.46391704100000003,-0.11480466310000001,-0.1833612701,-0.1457830413,0.2661507121,-0.0690831352,-0.225775248,-0.6386719528,0.1012880213,-0.3398464755,0.1671704044,0.1258945324,-0.008983099100000001,0.0147241692,0.16648011340000002,0.4481540785,0.0600176493,-0.0823608088,-0.0788029833,0.0851016549,-0.2554251281 -378.66,'0',1,-1.3583540616,0.2076428652,0.6245014594,0.0660836853,0.7172927314,-0.1659459228,2.345864949,-2.8900831944,1.1099693787,-0.1213593132,-2.2618570953,-1.3401630747,0.5249797252,0.2479981535,0.7716794019000001,0.9094122623,-0.6892809565,-0.3276418337,-0.13909657150000002,-0.055352794000000004,-0.0597518406,1.7732093426,0.379779593,-0.5031981333000001,1.8004993808,0.7914609565,0.2476757866,-1.5146543226 -123.5,'0',1,-0.9662717116,-0.0549519225,-0.2264872638,0.1782282259,0.50775687,-0.2879237455,-0.6314181177,-1.0596472454,-0.6840927863,1.9657750035000001,-1.2326219701,-0.1852260081,-0.2080377812,-0.108300452,0.0052735968000000005,-0.1903205187,-1.1755753319,0.6473760346,-0.2219288445,0.0627228487,0.0614576285,1.7929933396000002,-0.863291275,-0.010308879600000001,1.2472031675,0.2376089398,0.3774358747,-1.3870240627000001 -69.99,'0',2,-1.1582330935,0.753074432,-0.8228428779,0.5381955501,1.3458515932,-1.1196698347,0.17512113,-0.4514491828,-0.2370332394,-0.038194787,0.8034869250000001,0.8777367548,0.4085423604,-0.0094306971,0.7982784946,-0.1374580796,0.1412669838,-0.20600958760000002,0.5022922242,0.2194222295,0.2151531475,1.5487178465,0.40303393400000004,-0.4071933773,0.0959214625,0.5929407454,-0.2705326772,0.8177393082000001 diff --git a/tests/unused/unit/ml_handlers/data/vertex_regression.csv b/tests/unused/unit/ml_handlers/data/vertex_regression.csv deleted file mode 100644 index dba96576054..00000000000 --- a/tests/unused/unit/ml_handlers/data/vertex_regression.csv +++ /dev/null @@ -1,5 +0,0 @@ -date,quarter,department,day,team,targeted_productivity,smv,wip,over_time,incentive,idle_time,idle_men,no_of_style_change,no_of_workers,actual_productivity -1/1/2015,Quarter1,sweing,Thursday,8,0.8,26.16,1108,7080,98,0,0,0,59,0.940725424 -1/1/2015,Quarter1,finishing ,Thursday,1,0.75,3.94,,960,0,0,0,0,8,0.8865 -1/1/2015,Quarter1,sweing,Thursday,11,0.8,11.41,968,3660,50,0,0,0,30.5,0.800570492 -1/1/2015,Quarter1,sweing,Thursday,12,0.8,11.41,968,3660,50,0,0,0,30.5,0.800570492 diff --git a/tests/unused/unit/ml_handlers/test_anomaly_detection.py b/tests/unused/unit/ml_handlers/test_anomaly_detection.py deleted file mode 100644 index c27f77c7a86..00000000000 --- a/tests/unused/unit/ml_handlers/test_anomaly_detection.py +++ /dev/null @@ -1,291 +0,0 @@ -import time -import pandas as pd -from unittest.mock import patch -from mindsdb_sql_parser import parse_sql - -from tests.unit.executor_test_base import BaseExecutorTest -from mindsdb.integrations.handlers.anomaly_detection_handler.anomaly_detection_handler import ( - choose_model, - preprocess_data, -) - - -def test_choose_model(): - df = pd.read_csv("tests/unit/ml_handlers/data/anomaly_detection.csv") - # If no target is specified, we should use the unsupervised model - model = choose_model(df) - assert model.__class__.__name__ == "ECOD" - # If the size of the dataset is less than the semi_supervised_threshold, we should use the semi-supervised model - model = choose_model(df, target="class", supervised_threshold=50) - assert model.__class__.__name__ == "XGBOD" - # If the model type is specified, we should use that model type and override default logic - model = choose_model(df, target="class", model_type="supervised", supervised_threshold=50) - assert model.__class__.__name__ == "CatBoostClassifier" - # If the size of the dataset is greater than the semi_supervised_threshold, we should use the supervised model - model = choose_model(df, target="class", supervised_threshold=2) - assert model.__class__.__name__ == "CatBoostClassifier" - # If the model type is specified, we should use that model type and override default logic - model = choose_model(df, target="class", model_type="semi-supervised", supervised_threshold=2) - assert model.__class__.__name__ == "XGBOD" - # If the model name is specified, we should use that model name and override default logic - model = choose_model(df, target=None, model_name="knn", supervised_threshold=2) - assert model.__class__.__name__ == "KNN" - # If the model does not exist, we should raise an error - try: - model = choose_model(df, target="class", model_name="not_a_model", supervised_threshold=2) - assert False - except AssertionError: - assert True - - -def test_preprocess_data(): - df = pd.read_csv("tests/unit/ml_handlers/data/anomaly_detection.csv") - preprocessed_df = preprocess_data(df) - assert len(preprocessed_df) == len(df) - - -class TestAnomalyDetectionHandler(BaseExecutorTest): - def wait_predictor(self, project, name): - # wait - done = False - for attempt in range(200): - ret = self.run_sql(f"select * from {project}.models where name='{name}'") - if not ret.empty: - if ret["STATUS"][0] == "complete": - done = True - break - elif ret["STATUS"][0] == "error": - break - time.sleep(0.5) - if not done: - raise RuntimeError("predictor wasn't created") - - def run_sql(self, sql): - ret = self.command_executor.execute_command(parse_sql(sql)) - assert ret.error_code is None - if ret.data is not None: - return ret.data.to_df() - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_default_supervised_model(self, mock_handler): - # create project - self.run_sql("create database proj") - df = pd.read_csv("tests/unit/ml_handlers/data/anomaly_detection.csv") - self.set_handler(mock_handler, name="pg", tables={"df": df}) - - # create predictor - self.run_sql( - """ - create model proj.modelx - from pg (select * from df) - predict class - using - engine='anomaly_detection', - type='supervised' - """ - ) - self.wait_predictor("proj", "modelx") - - # run predict - ret = self.run_sql( - """ - SELECT p.* - FROM pg.df as t - JOIN proj.modelx as p - """ - ) - assert len(ret) == len(df) - - ret = self.run_sql( - """ - describe model proj.modelx.model - """ - ) - assert ret["model_name"][0] == "CatBoostClassifier" - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_non_default_supervised_model(self, mock_handler): - # create project - self.run_sql("create database proj") - df = pd.read_csv("tests/unit/ml_handlers/data/anomaly_detection.csv") - self.set_handler(mock_handler, name="pg", tables={"df": df}) - - # create predictor - self.run_sql( - """ - create model proj.modelx - from pg (select * from df) - predict class - using - engine='anomaly_detection', - type='supervised', - model_name='nb' - """ - ) - self.wait_predictor("proj", "modelx") - - # run predict - ret = self.run_sql( - """ - SELECT p.* - FROM pg.df as t - JOIN proj.modelx as p - """ - ) - assert len(ret) == len(df) - - ret = self.run_sql( - """ - describe model proj.modelx.model - """ - ) - assert ret["model_name"][0] == "GaussianNB" - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_specify_anomaly_type(self, mock_handler): - # create project - self.run_sql("create database proj") - df = pd.read_csv("tests/unit/ml_handlers/data/anomaly_detection.csv") - self.set_handler(mock_handler, name="pg", tables={"df": df}) - - # create predictor - self.run_sql( - """ - create model proj.modelx - from pg (select * from df) - predict outlier - using - engine='anomaly_detection', - anomaly_type='clustered', - type='unsupervised' - """ - ) - self.wait_predictor("proj", "modelx") - - # run predict - ret = self.run_sql( - """ - SELECT p.* - FROM pg.df as t - JOIN proj.modelx as p - """ - ) - assert len(ret) == len(df) - - ret = self.run_sql( - """ - describe model proj.modelx.model - """ - ) - assert ret["model_name"][0] == "PCA" - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_ensemble(self, mock_handler): - # create project - self.run_sql("create database proj") - df = pd.read_csv("tests/unit/ml_handlers/data/anomaly_detection.csv") - self.set_handler(mock_handler, name="pg", tables={"df": df}) - - # create predictor - self.run_sql( - """ - create ANOMALY DETECTION MODEL proj.modelx - from pg (select * from df) - using - engine='anomaly_detection', - ensemble_models=['pca', 'knn', 'ecod'] - """ - ) - # change model_names to ensemble_models for clarity - self.wait_predictor("proj", "modelx") - - # run predict - ret = self.run_sql( - """ - SELECT p.* - FROM pg.df as t - JOIN proj.modelx as p - """ - ) - assert len(ret) == len(df) - - ret = self.run_sql( - """ - describe model proj.modelx.model - """ - ) - assert all(ret["model_name"] == pd.Series(["PCA", "KNN", "ECOD"])) - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_default_semi_supervised_model(self, mock_handler): - # create database - self.run_sql("create database proj") - df = pd.read_csv("tests/unit/ml_handlers/data/anomaly_detection.csv") - self.set_handler(mock_handler, name="pg", tables={"df": df}) - - # create predictor - self.run_sql( - """ - create model proj.modelx - from pg (select * from df) - predict class - using - engine='anomaly_detection', - type='semi-supervised' - """ - ) - self.wait_predictor("proj", "modelx") - - # run predict - ret = self.run_sql( - """ - SELECT p.* - FROM pg.df as t - JOIN proj.modelx as p - """ - ) - assert len(ret) == len(df) - - ret = self.run_sql( - """ - describe model proj.modelx.model - """ - ) - assert ret["model_name"][0] == "XGBOD" - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_default_unsupervised_model(self, mock_handler): - # dataset, string values - df = pd.read_csv("tests/unit/ml_handlers/data/anomaly_detection.csv") - self.set_handler(mock_handler, name="pg", tables={"df": df}) - - # create project - self.run_sql("create database proj") - - # create predictor - self.run_sql( - """ - create anomaly detection model proj.modelx - from pg (select * from df) - using - engine='anomaly_detection' - """ - ) - self.wait_predictor("proj", "modelx") - - # run predict - ret = self.run_sql( - """ - SELECT p.outlier - FROM pg.df as t - JOIN proj.modelx as p - """ - ) - assert len(ret) == len(df) - - ret = self.run_sql( - """ - describe model proj.modelx.model - """ - ) - assert ret["model_name"][0] == "ECOD" diff --git a/tests/unused/unit/ml_handlers/test_anthropic.py b/tests/unused/unit/ml_handlers/test_anthropic.py deleted file mode 100644 index 020e1d13e57..00000000000 --- a/tests/unused/unit/ml_handlers/test_anthropic.py +++ /dev/null @@ -1,110 +0,0 @@ -import os -import pytest -import pandas as pd -from unittest.mock import patch - -from .base_ml_test import BaseMLAPITest - - -@pytest.mark.skipif(os.environ.get('ANTHROPIC_API_KEY') is None, reason='Missing API key!') -class TestAnthropic(BaseMLAPITest): - """Test Class for Anthropic Integration Testing""" - - def setup_method(self): - """Setup test environment, creating a project""" - super().setup_method() - self.run_sql("create database proj") - self.run_sql( - f""" - CREATE ML_ENGINE anthropic - FROM anthropic - USING - anthropic_api_key = '{self.get_api_key('ANTHROPIC_API_KEY')}'; - """ - ) - - def test_invalid_model_parameter(self): - """Test for invalid Anthropic model parameter""" - self.run_sql( - f""" - CREATE MODEL proj.test_anthropic_invalid_model - PREDICT answer - USING - engine='anthropic', - column='question', - model='this-claude-does-not-exist', - api_key='{self.get_api_key('ANTHROPIC_API_KEY')}'; - """ - ) - with pytest.raises(Exception): - self.wait_predictor("proj", "test_anthropic_invalid_model") - - def test_unknown_model_argument(self): - """Test for unknown argument when creating a Anthropic model""" - self.run_sql( - f""" - CREATE MODEL proj.test_anthropic_unknown_argument - PREDICT answer - USING - engine='anthropic', - column='question', - api_key='{self.get_api_key('ANTHROPIC_API_KEY')}', - evidently_wrong_argument='wrong value'; - """ - ) - with pytest.raises(Exception): - self.wait_predictor("proj", "test_anthropic_unknown_argument") - - def test_single_qa(self): - """Test for single question/answer pair""" - self.run_sql( - f""" - CREATE MODEL proj.test_anthropic_single_qa - PREDICT answer - USING - engine='anthropic', - column='question', - api_key='{self.get_api_key('ANTHROPIC_API_KEY')}'; - """ - ) - self.wait_predictor("proj", "test_anthropic_single_qa") - - result_df = self.run_sql( - """ - SELECT answer - FROM proj.test_anthropic_single_qa - WHERE question = 'What is the capital of Sweden?'; - """ - ) - assert "stockholm" in result_df["answer"].iloc[0].lower() - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_bulk_qa(self, mock_handler): - """Test for bulk question/answer pairs""" - df = pd.DataFrame.from_dict({"question": [ - "What is the capital of Sweden?", - "What is the second planet of the solar system?" - ]}) - self.set_handler(mock_handler, name="pg", tables={"df": df}) - - self.run_sql( - f""" - CREATE MODEL proj.test_anthropic_bulk_qa - PREDICT answer - USING - engine='anthropic', - column='question', - api_key='{self.get_api_key('ANTHROPIC_API_KEY')}'; - """ - ) - self.wait_predictor("proj", "test_anthropic_bulk_qa") - - result_df = self.run_sql( - """ - SELECT p.answer - FROM pg.df as t - JOIN proj.test_anthropic_bulk_qa as p; - """ - ) - assert "stockholm" in result_df["answer"].iloc[0].lower() - assert "venus" in result_df["answer"].iloc[1].lower() diff --git a/tests/unused/unit/ml_handlers/test_autogluon.py b/tests/unused/unit/ml_handlers/test_autogluon.py deleted file mode 100644 index 1b35d2bc45f..00000000000 --- a/tests/unused/unit/ml_handlers/test_autogluon.py +++ /dev/null @@ -1,77 +0,0 @@ -import time -from unittest.mock import patch -import pandas as pd - -from mindsdb_sql_parser import parse_sql - - -from unit.executor_test_base import BaseExecutorTest - - -class TestAutoGluon(BaseExecutorTest): - def wait_predictor(self, project, name): - # wait - done = False - for attempt in range(200): - ret = self.run_sql( - f"select * from {project}.models where name='{name}'" - ) - # print(ret['STATUS'][0]) - if not ret.empty: - if ret['STATUS'][0] == 'complete': - done = True - break - elif ret['STATUS'][0] == 'error': - # print(f"{ret['ERROR'][0]}") - break - time.sleep(15) - if not done: - raise RuntimeError("predictor wasn't created") - - def run_sql(self, sql): - ret = self.command_executor.execute_command( - parse_sql(sql) - ) - assert ret.error_code is None - if ret.data is not None: - return ret.data.to_df() - - @patch('mindsdb.integrations.handlers.postgres_handler.Handler') - def test_simple(self, mock_handler): - - # dataset, string values - df = pd.DataFrame(range(1, 50), columns=['a']) - df['b'] = 50 - df.a - df['c'] = round((df['a'] * 3 + df['b']) / 50) - - self.set_handler(mock_handler, name='pg', tables={'df': df}) - - # create project - self.run_sql('create database proj;') - - # create predictor - self.run_sql(''' - create model proj.modelx - from pg (select * from df) - predict c - using - engine='autogluon'; - ''') - - self.wait_predictor('proj', 'modelx') - - # run predict - ret = self.run_sql(''' - SELECT p.* - FROM pg.df as t - JOIN proj.modelx as p - where t.c=1 - ''') - avg_c = pd.to_numeric(ret.c).mean() - # value is around 1 - assert (avg_c > 0.9) and (avg_c < 1.1) - - -# df = pd.DataFrame(range(1, 50), columns=['a']) -# df['b'] = 50 - df.a -# df['c'] = round((df['a']*3 + df['b']) / 50) diff --git a/tests/unused/unit/ml_handlers/test_autokeras.py b/tests/unused/unit/ml_handlers/test_autokeras.py deleted file mode 100644 index fd63a03875a..00000000000 --- a/tests/unused/unit/ml_handlers/test_autokeras.py +++ /dev/null @@ -1,276 +0,0 @@ -import time -from unittest.mock import patch -import pandas as pd -import numpy as np - -from mindsdb_sql_parser import parse_sql - - -from mindsdb.integrations.handlers.autokeras_handler.autokeras_handler import ( - format_categorical_preds, -) -from tests.unit.executor_test_base import BaseExecutorTest - - -def test_format_categorical_preds(): - """Tests helper function to put categorical predictions into the right format""" - predictions = np.array([[0.9, 0.05, 0.05], [0, 1, 0], [0, 0, 1]]) - original_y = pd.Series(["a", "b", "c"]) - keras_output_df = pd.DataFrame({"target": predictions.tolist()}) - formatted_df = format_categorical_preds(predictions, original_y, keras_output_df, "target") - assert formatted_df["target"].tolist() == ["a", "b", "c"] - assert formatted_df["confidence"].tolist() == [max(row) for row in predictions] - - -class TestAutokeras(BaseExecutorTest): - def wait_predictor(self, project, name): - # wait - done = False - for attempt in range(200): - ret = self.run_sql(f"select * from {project}.models where name='{name}'") - if not ret.empty: - if ret["STATUS"][0] == "complete": - done = True - break - elif ret["STATUS"][0] == "error": - break - time.sleep(0.5) - if not done: - raise RuntimeError("predictor wasn't created") - - def run_sql(self, sql): - ret = self.command_executor.execute_command(parse_sql(sql)) - assert ret.error_code is None - if ret.data is not None: - return ret.data.to_df() - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_regression_with_numerical_training(self, mock_handler): - # dataset, string values - df = pd.DataFrame(range(1, 50), columns=["a"]) - df["b"] = 50 - df.a - df["c"] = round((df["a"] * 3 + df["b"]) / 50) - - self.set_handler(mock_handler, name="pg", tables={"df": df}) - - # create project - self.run_sql("create database proj") - - # create predictor - self.run_sql( - """ - create model proj.modelx - from pg (select * from df) - predict c - using - engine='autokeras', - train_time=0.01 - """ - ) - self.wait_predictor("proj", "modelx") - - # run predict - ret = self.run_sql( - """ - SELECT * - FROM proj.modelx - WHERE a=1 - AND b=25; - """ - ) - avg_c = pd.to_numeric(ret.c).mean() - assert ret.columns.tolist() == ["a", "b", "c"] - assert len(ret) == 1 - assert (avg_c > -5) and (avg_c < 5) - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_regression_with_categorical_training(self, mock_handler): - # dataset, string values - df = pd.DataFrame(range(1, 50), columns=["a"]) - df["b"] = 50 - df.a - df["c"] = round((df["a"] * 3 + df["b"]) / 50) - df["d"] = np.where(df.index % 2, "even", "odd") - - self.set_handler(mock_handler, name="pg", tables={"df": df}) - - # create project - self.run_sql("create database proj") - - # create predictor - self.run_sql( - """ - create model proj.modelx - from pg (select * from df) - predict c - using - engine='autokeras', - train_time=0.01 - """ - ) - self.wait_predictor("proj", "modelx") - - # run predict - ret = self.run_sql( - """ - SELECT c - FROM proj.modelx - WHERE a=1 AND b=25 AND d="odd" - """ - ) - avg_c = pd.to_numeric(ret.c).mean() - assert (avg_c > -5) and (avg_c < 5) - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_regression_with_nulls_in_training_data(self, mock_handler): - # dataset, string values - df = pd.DataFrame(range(1, 50), columns=["a"]) - df["b"] = 50 - df.a - df["c"] = round((df["a"] * 3 + df["b"]) / 50) - df["d"] = np.where(df.index % 2, "even", "odd") - # Make it look like we have missing data - df["a"][10] = None - df["b"][25] = np.nan - df["d"][31] = "" - - self.set_handler(mock_handler, name="pg", tables={"df": df}) - - # create project - self.run_sql("create database proj") - - # create predictor - self.run_sql( - """ - create model proj.modelx - from pg (select * from df) - predict c - using - engine='autokeras', - train_time=0.01 - """ - ) - self.wait_predictor("proj", "modelx") - - # run predict - ret = self.run_sql( - """ - SELECT c - FROM proj.modelx - WHERE a=1 AND b=25 AND d="odd"; - """ - ) - avg_c = pd.to_numeric(ret.c).mean() - assert (avg_c > -5) and (avg_c < 5) - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_regression_with_bulk_predict_query(self, mock_handler): - # dataset, string values - df = pd.DataFrame(range(1, 50), columns=["a"]) - df["b"] = 50 - df.a - df["c"] = round((df["a"] * 3 + df["b"]) / 50) - df["d"] = np.where(df.index % 2, "even", "odd") - - self.set_handler(mock_handler, name="pg", tables={"df": df}) - - # create project - self.run_sql("create database proj") - - # create predictor - self.run_sql( - """ - create model proj.modelx - from pg (select * from df) - predict c - using - engine='autokeras', - train_time=0.01 - """ - ) - self.wait_predictor("proj", "modelx") - - # run predict - ret = self.run_sql( - """ - SELECT m.* - FROM pg.df as t - JOIN proj.modelx as m - where t.b>25 - """ - ) - avg_c = pd.to_numeric(ret.c).mean() - assert (avg_c > -5) and (avg_c < 5) - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_regression_error_on_predict_query_missing_cols(self, mock_handler): - # dataset, string values - df = pd.DataFrame(range(1, 50), columns=["a"]) - df["b"] = 50 - df.a - df["c"] = round((df["a"] * 3 + df["b"]) / 50) - df["d"] = np.where(df.index % 2, "even", "odd") - - self.set_handler(mock_handler, name="pg", tables={"df": df}) - - # create project - self.run_sql("create database proj") - - # create predictor - self.run_sql( - """ - create model proj.modelx - from pg (select * from df) - predict c - using - engine='autokeras', - train_time=0.01 - """ - ) - self.wait_predictor("proj", "modelx") - - try: - # run predict but missing column d in the WHERE clause - _ = self.run_sql( - """ - SELECT c - FROM proj.modelx - WHERE a=1 - AND b=2; - """ - ) - assert False - except Exception: - assert True - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_classification_with_numerical_training(self, mock_handler): - # dataset, string values - df = pd.DataFrame(range(1, 50), columns=["a"]) - df["b"] = 50 - df.a - df["c"] = round((df["a"] * 3 + df["b"]) / 50) - df["d"] = np.where(df.index % 2, "even", "odd") - - self.set_handler(mock_handler, name="pg", tables={"df": df}) - - # create project - self.run_sql("create database proj") - - # create predictor - self.run_sql( - """ - create model proj.modelx - from pg (select * from df) - predict d - using - engine='autokeras', - train_time=0.01 - """ - ) - self.wait_predictor("proj", "modelx") - - # run predict - ret = self.run_sql( - """ - SELECT d - FROM proj.modelx - WHERE a=1 AND b=25 AND c=10 - """ - ) - assert ret.d[0] in ["even", "odd"] diff --git a/tests/unused/unit/ml_handlers/test_clipdrop.py b/tests/unused/unit/ml_handlers/test_clipdrop.py deleted file mode 100644 index bd4cb473b7b..00000000000 --- a/tests/unused/unit/ml_handlers/test_clipdrop.py +++ /dev/null @@ -1,110 +0,0 @@ -import os -import pytest -import pandas as pd -from unittest.mock import patch - -from .base_ml_test import BaseMLAPITest - - -@pytest.mark.skipif(os.environ.get('CLIPDROP_API_KEY') is None, reason='Missing API key!') -class TestClipdrop(BaseMLAPITest): - """Test Class for Clipdrop Integration Testing""" - - def setup_method(self): - """Setup test environment, creating a project""" - super().setup_method() - self.run_sql("create database proj") - self.run_sql( - f""" - CREATE ML_ENGINE clipdrop_engine - FROM clipdrop - USING - clipdrop_api_key = '{self.get_api_key('CLIPDROP_API_KEY')}'; - """ - ) - - def test_missing_task_argument(self): - """Test for unknown argument when creating a clidrop model""" - self.run_sql( - f""" - CREATE MODEL proj.test_clipdrop_invalid_model - PREDICT answer - USING - engine='clipdrop_engine', - local_directory_path = "tests/unit/ml_handlers/data", - api_key='{self.get_api_key('CLIPDROP_API_KEY')}'; - """ - ) - with pytest.raises(Exception): - self.wait_predictor("proj", "test_missing_task_argument") - - def test_unknown_task_argument(self): - """Test for unknown argument when creating a clipdrop model""" - self.run_sql( - f""" - CREATE MODEL proj.test_clipdrop_invalid_model - PREDICT answer - USING - engine='clipdrop_engine', - task = "unknown-task", - local_directory_path = "tests/unit/ml_handlers/data", - api_key='{self.get_api_key('CLIPDROP_API_KEY')}'; - """ - ) - with pytest.raises(Exception): - self.wait_predictor("proj", "test_unknown_task_argument") - - def test_text_image_single(self): - """Test for single text""" - self.run_sql( - f""" - CREATE MODEL proj.test_clipdrop_t2i_single - PREDICT answer - USING - engine='clipdrop_engine', - task = "text_to_image", - local_directory_path = "tests/unit/ml_handlers/data", - api_key='{self.get_api_key('CLIPDROP_API_KEY')}'; - """ - ) - self.wait_predictor("proj", "test_clipdrop_t2i_single") - - result_df = self.run_sql( - """ - SELECT * - FROM proj.test_clipdrop_t2i_single - WHERE text = 'A blue lagoon'; - """ - ) - assert result_df["answer"].size == 1 - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_bulk_text(self, mock_handler): - """Test for bulk question/answer pairs""" - df = pd.DataFrame.from_dict({"text": [ - "A black swan", - "A pink unicorn" - ]}) - self.set_handler(mock_handler, name="pg", tables={"df": df}) - - self.run_sql( - f""" - CREATE MODEL proj.test_clipdrop_bulk_text - PREDICT answer - USING - engine='clipdrop_engine', - task = "text_to_image", - local_directory_path = "tests/unit/ml_handlers/data", - api_key='{self.get_api_key('CLIPDROP_API_KEY')}'; - """ - ) - self.wait_predictor("proj", "test_clipdrop_bulk_text") - - result_df = self.run_sql( - """ - SELECT p.answer - FROM pg.df as t - JOIN proj.test_clipdrop_bulk_text as p; - """ - ) - assert result_df["answer"].size == 2 diff --git a/tests/unused/unit/ml_handlers/test_dspy.py b/tests/unused/unit/ml_handlers/test_dspy.py deleted file mode 100644 index 10d5ad4ebe3..00000000000 --- a/tests/unused/unit/ml_handlers/test_dspy.py +++ /dev/null @@ -1,100 +0,0 @@ -import os - - -import ollama -import pytest -from ..executor_test_base import BaseExecutorTest - - -OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY") - - -def ollama_model_exists(model_name: str) -> bool: - - try: - ollama.show(model_name) - return True - except Exception: - return False - - -class TestDSPy(BaseExecutorTest): - - """Test Class for DSPy Integration Testing""" - @pytest.fixture(autouse=True, scope="function") - def setup_method(self): - """Setup test environment, creating a project""" - super().setup_method() - self.run_sql("create database proj") - - @pytest.mark.skipif(OPENAI_API_KEY is None, reason='Missing OpenAI API key (OPENAI_API_KEY env variable)') - def test_default_provider(self): - - self.run_sql( - f""" - CREATE ML_ENGINE dspy_engine - FROM dspy - USING - openai_api_key = '{OPENAI_API_KEY}'; - """ - ) - - self.run_sql( - """ - create model proj.test_conversational_model - predict answer - using - engine='dspy_engine', - provider = 'openai', - model_name = 'gpt-4', - mode = 'conversational', - user_column = 'question', - assistant_column = 'answer', - prompt_template='Answer the user in a useful way'; - """ - ) - self.wait_predictor("proj", "test_conversational_model") - result_df = self.run_sql( - """ - SELECT question, answer - FROM proj.test_conversational_model - WHERE question='What is the capital of Sweden?;' - """ - ) - assert "stockholm" in result_df['answer'].iloc[0].lower() - - @pytest.mark.skipif(OPENAI_API_KEY is None, reason='Missing OpenAI API key (OPENAI_API_KEY env variable)') - def test_default_provider2(self): - - self.run_sql( - f""" - CREATE ML_ENGINE dspy_engine - FROM dspy - USING - openai_api_key = '{OPENAI_API_KEY}'; - """ - ) - - self.run_sql( - """ - create model proj.test_conversational_model - predict answer - using - engine='dspy_engine', - provider = 'openai', - model_name = 'gpt-3.5-turbo', - mode = 'conversational', - user_column = 'question', - assistant_column = 'answer', - prompt_template='Answer the user in a useful way'; - """ - ) - self.wait_predictor("proj", "test_conversational_model") - result_df = self.run_sql( - """ - SELECT question, answer - FROM proj.test_conversational_model - WHERE question='What is 3 + 4?;' - """ - ) - assert "7" in result_df['answer'].iloc[0].lower() diff --git a/tests/unused/unit/ml_handlers/test_google_gemini.py b/tests/unused/unit/ml_handlers/test_google_gemini.py deleted file mode 100644 index 8e6726f2343..00000000000 --- a/tests/unused/unit/ml_handlers/test_google_gemini.py +++ /dev/null @@ -1,105 +0,0 @@ -import os -import pytest -import pandas as pd -from unittest.mock import patch - -from .base_ml_test import BaseMLAPITest - -GEMINI_API_KEY = os.environ.get('GOOGLE_GENAI_API_KEY') - - -@pytest.mark.skipif(GEMINI_API_KEY is None, reason='Missing API key!') -class TestGeminiHandler(BaseMLAPITest): - """Test Class for Google Gemini (Bard) API handler""" - - def setup_method(self): - """Setup test environment, creating a project""" - super().setup_method() - self.run_sql("create database proj") - - def test_invalid_model_parameter(self): - """Test for invalid Gemini model parameter""" - self.run_sql( - f""" - CREATE MODEL proj.test_google_invalid_model - PREDICT answer - USING - engine='google_gemini', - column='question', - model='non-existing-gemini-model', - api_key='{GEMINI_API_KEY}'; - """ - ) - with pytest.raises(Exception): - self.wait_predictor("proj", "test_google_invalid_model") - - @pytest.mark.skip(reason="This test is failing as no error is being thrown") - def test_unknown_model_argument(self): - """Test for unknown argument when creating Gemini model""" - self.run_sql( - f""" - CREATE MODEL proj.test_google_unknown_arg - PREDICT answer - USING - engine='google', - column='question', - api_key='{GEMINI_API_KEY}', - evidently_wrong_argument='wrong value'; - """ - ) - with pytest.raises(Exception): - self.wait_predictor("proj", "test_google_unknown_arg") - - def test_single_qa(self): - """Test for single question/answer pair""" - self.run_sql( - f""" - CREATE MODEL proj.test_google_single_qa - PREDICT answer - USING - engine='google_gemini', - column='question', - api_key='{GEMINI_API_KEY}'; - """ - ) - self.wait_predictor("proj", "test_google_single_qa") - - result_df = self.run_sql( - """ - SELECT answer - FROM proj.test_google_single_qa - WHERE question = 'What is the capital of Sweden?'; - """ - ) - assert "stockholm" in result_df["answer"].iloc[0].lower() - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_bulk_qa(self, mock_handler): - """Test for bulk question/answer pairs""" - df = pd.DataFrame.from_dict({"question": [ - "What is the capital of Sweden?", - "What is the second planet of the solar system?" - ]}) - self.set_handler(mock_handler, name="pg", tables={"df": df}) - - self.run_sql( - f""" - CREATE MODEL proj.test_google_bulk_qa - PREDICT answer - USING - engine='google_gemini', - column='question', - api_key='{GEMINI_API_KEY}'; - """ - ) - self.wait_predictor("proj", "test_google_bulk_qa") - - result_df = self.run_sql( - """ - SELECT p.answer - FROM pg.df as t - JOIN proj.test_google_bulk_qa as p; - """ - ) - assert "stockholm" in result_df["answer"].iloc[0].lower() - assert "venus" in result_df["answer"].iloc[1].lower() diff --git a/tests/unused/unit/ml_handlers/test_huggingface.py b/tests/unused/unit/ml_handlers/test_huggingface.py deleted file mode 100644 index f83d62de50b..00000000000 --- a/tests/unused/unit/ml_handlers/test_huggingface.py +++ /dev/null @@ -1,381 +0,0 @@ -import time -from unittest.mock import patch - -import pandas as pd -from mindsdb_sql_parser import parse_sql -from tests.unit.executor_test_base import BaseExecutorTest - -# How to run: -# env PYTHONPATH=./ pytest -vx tests/unit/test_ml_handlers.py -# Warning: a big huggingface models will be downloaded - - -class TestHuggingface(BaseExecutorTest): - def run_sql(self, sql): - return self.command_executor.execute_command(parse_sql(sql)) - - def hf_test_run(self, mock_handler, model_name, create_sql, predict_sql): - # prepare table - text_spammy = [ - "It is the best time to launch the Robot to get more money. https:\\/\\/Gof.bode-roesch.de\\/Gof", - "Start making thousands of dollars every week just using this robot. https:\\/\\/Gof.coronect.de\\/Gof", - ] - - text_short = ["I want to dance", "Baking is the best"] - - text_long = [ - "Dance is a performing art form consisting of sequences of movement, either improvised or purposefully selected. This movement has aesthetic and often symbolic value.[nb 1] Dance can be categorized and described by its choreography, by its repertoire of movements, or by its historical period or place of origin.", - "Baking is a method of preparing food that uses dry heat, typically in an oven, but can also be done in hot ashes, or on hot stones. The most common baked item is bread but many other types of foods can be baked. Heat is gradually transferred from the surface of cakes, cookies, and pieces of bread to their center. As heat travels through, it transforms batters and doughs into baked goods and more with a firm dry crust and a softer center. Baking can be combined with grilling to produce a hybrid barbecue variant by using both methods simultaneously, or one after the other. Baking is related to barbecuing because the concept of the masonry oven is similar to that of a smoke pit.", - ] - - df = pd.DataFrame(data=[text_spammy, text_short, text_long]).T - df.columns = ["text_spammy", "text_short", "text_long"] - - self.set_handler(mock_handler, name="pg", tables={"df": df}) - - # create predictor - ret = self.run_sql(create_sql) - assert ret.error_code is None - - # wait - done = False - for attempt in range(900): - ret = self.run_sql( - f"select status from mindsdb.models where name='{model_name}'" - ) - data = ret.data.to_lists() - if len(data) > 0: - if data[0][0] == "complete": - done = True - break - elif data[0][0] == "error": - break - time.sleep(0.5) - if not done: - raise RuntimeError("predictor not created") - - # use predictor - ret = self.command_executor.execute_command( - parse_sql(predict_sql) - ) - assert ret.error_code is None - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_hf_classification_bin(self, mock_handler): - # create predictor - create_sql = """ - CREATE PREDICTOR mindsdb.spam_classifier - predict PRED - USING - engine='huggingface', - join_learn_process=true, - task='text-classification', - model_name= "mrm8488/bert-tiny-finetuned-sms-spam-detection", - input_column = 'text_spammy', - labels=['ham','spam'] - """ - - model_name = "spam_classifier" - - predict_sql = """ - SELECT h.* - FROM pg.df as t - JOIN mindsdb.spam_classifier as h - """ - self.hf_test_run(mock_handler, model_name, create_sql, predict_sql) - - # one line prediction - predict_sql = """ - SELECT * from mindsdb.spam_classifier - where text_spammy= 'It is the best time to launch the Robot to get more money. https:\\/\\/Gof.bode-roesch.de\\/Gof' - """ - # use predictor - ret = self.command_executor.execute_command( - parse_sql(predict_sql) - ) - assert ret.error_code is None - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_hf_classification_multy(self, mock_handler): - # create predictor - create_sql = """ - CREATE PREDICTOR mindsdb.sentiment_classifier - predict PRED - USING - engine='huggingface', - join_learn_process=true, - task='text-classification', - model_name= "cardiffnlp/twitter-roberta-base-sentiment", - input_column = 'text_short', - labels=['neg','neu','pos'] - """ - - model_name = "sentiment_classifier" - - predict_sql = """ - SELECT h.* - FROM pg.df as t - JOIN mindsdb.sentiment_classifier as h - """ - self.hf_test_run(mock_handler, model_name, create_sql, predict_sql) - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_hf_zero_shot(self, mock_handler): - # create predictor - create_sql = """ - CREATE PREDICTOR mindsdb.zero_shot_tcd - predict PREDZS - USING - engine='huggingface', - join_learn_process=true, - task="zero-shot-classification", - model_name= "facebook/bart-large-mnli", - input_column = "text_short", - candidate_labels=['travel', 'cooking', 'dancing'] - """ - - model_name = "zero_shot_tcd" - - predict_sql = """ - SELECT h.* - FROM pg.df as t - JOIN mindsdb.zero_shot_tcd as h - """ - self.hf_test_run(mock_handler, model_name, create_sql, predict_sql) - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_summarization(self, mock_handler): - # create predictor - create_sql = """ - CREATE MODEL mindsdb.hf_summarization - PREDICT summary - USING - engine = 'huggingface', - task = 'summarization', - model_name = 'sshleifer/distilbart-xsum-12-1', - input_column = 'text_long', - min_output_length = 5, - max_output_length = 20; - """ - - model_name = "hf_summarization" - - predict_sql = """ - SELECT h.* - FROM pg.df as t - JOIN mindsdb.hf_summarization as h - """ - - self.hf_test_run(mock_handler, model_name, create_sql, predict_sql) - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_hf_translation(self, mock_handler): - # create predictor - create_sql = """ - CREATE PREDICTOR mindsdb.translator_en_fr - predict TRANSLATION - USING - engine='huggingface', - join_learn_process=true, - task = "translation", - model_name = "t5-base", - input_column = "text_short", - lang_input = "en", - lang_output = "fr" - """ - - model_name = "translator_en_fr" - - predict_sql = """ - SELECT h.* - FROM pg.df as t - JOIN mindsdb.translator_en_fr as h - """ - self.hf_test_run(mock_handler, model_name, create_sql, predict_sql) - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_hf_text2text(self, mock_handler): - # create predictor - create_sql = """ - CREATE MODEL mindsdb.text_generator - predict PREDICTION - USING - engine='huggingface', - join_learn_process=true, - task = "text2text-generation", - model_name = "google/flan-t5-base", - input_column = 'comment' - """ - - model_name = "text_generator" - - predict_sql = """ - SELECT * FROM text_generator - WHERE comment='Question: Why did the chicken cross the road?' - """ - self.hf_test_run(mock_handler, model_name, create_sql, predict_sql) - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_hf_text_classification_finetune(self, mock_handler): - create_sql = """ - CREATE PREDICTOR mindsdb.spam_classifier - predict PRED - USING - engine='huggingface', - join_learn_process=true, - task='text-classification', - model_name= "mrm8488/bert-tiny-finetuned-sms-spam-detection", - input_column = 'text_spammy', - labels=['ham','spam'] - """ - - model_name = "spam_classifier" - - predict_sql = """ - SELECT h.* - FROM pg.df as t - JOIN mindsdb.spam_classifier as h - """ - self.hf_test_run(mock_handler, model_name, create_sql, predict_sql) - - # one line prediction - predict_sql = """ - SELECT * from mindsdb.spam_classifier - where text_spammy= 'It is the best time to launch the Robot to get more money. https:\\/\\/Gof.bode-roesch.de\\/Gof' - """ - # use predictor - ret = self.command_executor.execute_command( - parse_sql(predict_sql) - ) - assert ret.error_code is None - - # fine tune - - fine_tune_sql = """ - FINETUNE mindsdb.spam_classifier - FROM pg ( - SELECT label as PRED, text as text_spammy FROM df WHERE PRED <= 1 - ) - USING - tokenizer_from = 'bert-base-uncased'; - """ - - ret = self.command_executor.execute_command( - parse_sql(fine_tune_sql) - ) - - assert ret.error_code is None - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_hf_zero_shot_classification_finetune(self, mock_handler): - # create predictor - create_sql = """ - CREATE PREDICTOR mindsdb.zero_shot_tcd - predict PREDZS - USING - engine='huggingface', - join_learn_process=true, - task="zero-shot-classification", - model_name= "facebook/bart-large-mnli", - input_column = "text_short", - candidate_labels=['travel', 'cooking', 'dancing'] - """ - - model_name = "zero_shot_tcd" - - predict_sql = """ - SELECT h.* - FROM pg.df as t - JOIN mindsdb.zero_shot_tcd as h - """ - self.hf_test_run(mock_handler, model_name, create_sql, predict_sql) - - # fine tune - - fine_tune_sql = """ - FINETUNE mindsdb.zero_shot_tcd - FROM pg (SELECT label, hypothesis FROM df); - """ - - ret = self.command_executor.execute_command( - parse_sql(fine_tune_sql) - ) - - assert ret.error_code is None - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_hf_translation_finetune(self, mock_handler): - # create predictor - create_sql = """ - CREATE PREDICTOR mindsdb.translator_en_fr - predict TRANSLATION - USING - engine='huggingface', - join_learn_process=true, - task = "translation", - model_name = "t5-base", - input_column = "text_short", - lang_input = "en", - lang_output = "fr" - """ - - model_name = "translator_en_fr" - - predict_sql = """ - SELECT h.* - FROM pg.df as t - JOIN mindsdb.translator_en_fr as h - """ - self.hf_test_run(mock_handler, model_name, create_sql, predict_sql) - - # fine tune - - fine_tune_sql = """ - FINETUNE mindsdb.translator_en_fr - FROM pg (SELECT text_long, transl FROM df); - """ - - ret = self.command_executor.execute_command( - parse_sql(fine_tune_sql) - ) - - assert ret.error_code is None - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_hf_summarization_finetune(self, mock_handler): - # create predictor - create_sql = """ - CREATE MODEL mindsdb.hf_summarization - PREDICT summary - USING - engine = 'huggingface', - task = 'summarization', - model_name = 'sshleifer/distilbart-xsum-12-1', - input_column = 'text_long', - min_output_length = 5, - max_output_length = 20; - """ - - model_name = "hf_summarization" - - predict_sql = """ - SELECT h.* - FROM pg.df as t - JOIN mindsdb.hf_summarization as h - """ - - self.hf_test_run(mock_handler, model_name, create_sql, predict_sql) - - # fine tune - fine_tune_sql = """ - FINETUNE mindsdb.hf_summarization - FROM pg ( - SELECT text, summary FROM df - ); - """ - - ret = self.command_executor.execute_command( - parse_sql(fine_tune_sql) - ) - - assert ret.error_code is None diff --git a/tests/unused/unit/ml_handlers/test_huggingface_api.py b/tests/unused/unit/ml_handlers/test_huggingface_api.py deleted file mode 100644 index 4ee84429123..00000000000 --- a/tests/unused/unit/ml_handlers/test_huggingface_api.py +++ /dev/null @@ -1,46 +0,0 @@ -from unittest.mock import patch -import pandas as pd - -from mindsdb_sql_parser import parse_sql - -from tests.unit.executor_test_base import BaseExecutorTest - - -class TestHuggingFaceAPI(BaseExecutorTest): - def run_sql(self, sql): - ret = self.command_executor.execute_command(parse_sql(sql)) - assert ret.error_code is None - if ret.data is not None: - return ret.data.to_df() - - @patch("mindsdb.integrations.handlers.postgres_handler.Handler") - def test_text_classification(self, mock_handler): - self.run_sql("CREATE DATABASE proj") - - texts = ["I like you. I love you", "I don't like you. I hate you"] - df = pd.DataFrame(texts, columns=['texts']) - - self.set_handler(mock_handler, name="pg", tables={"df": df}) - - self.run_sql( - """ - CREATE MODEL proj.test_hfapi_text_classification - PREDICT sentiment - USING - task = 'text-classification', - engine = 'hf_api_engine', - api_key = '