Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
Mark Duppenthaler
Updated table. No more individual rows, separate tabs for leaderboard type, export tables
7f6ef8f
| import json | |
| import os | |
| import pytest | |
| from unittest.mock import patch, MagicMock, mock_open | |
| import pandas as pd | |
| from io import StringIO | |
| from flask import Flask | |
| # Import the Flask app and other necessary modules | |
| from backend.app import app, get_leaderboard, get_chart | |
| def client(): | |
| """Create a test client for the Flask app.""" | |
| app.config['TESTING'] = True | |
| with app.test_client() as client: | |
| yield client | |
| def test_index_route(client): | |
| """Test the index route returns the index.html file.""" | |
| with patch('backend.app.send_from_directory') as mock_send: | |
| mock_send.return_value = "index content" | |
| response = client.get('/') | |
| assert response.status_code == 200 | |
| mock_send.assert_called_once_with(app.static_folder, "index.html") | |
| def test_data_files_benchmark(mock_get_leaderboard, mock_get_config, mock_read_csv, client): | |
| """Test the data_files route with benchmark dataset type.""" | |
| # Mock the DataFrame and config | |
| mock_df = pd.DataFrame({'model': ['model1', 'model2'], 'score': [0.9, 0.8]}) | |
| mock_read_csv.return_value = mock_df | |
| mock_config = {'name': 'test_dataset'} | |
| mock_get_config.return_value = mock_config | |
| mock_get_leaderboard.return_value = "leaderboard data" | |
| # Make the request | |
| response = client.get('/data/test_dataset?dataset_type=benchmark') | |
| # Assertions | |
| mock_read_csv.assert_called_once() | |
| mock_get_config.assert_called_once_with('test_dataset') | |
| mock_get_leaderboard.assert_called_once_with(mock_config, mock_df) | |
| assert response == "leaderboard data" | |
| def test_data_files_attacks_variations(mock_get_chart, mock_get_config, mock_read_csv, client): | |
| """Test the data_files route with attacks_variations dataset type.""" | |
| # Mock the DataFrame and config | |
| mock_df = pd.DataFrame({'model': ['model1', 'model2'], 'attack': ['a1', 'a2']}) | |
| mock_read_csv.return_value = mock_df | |
| mock_config = {'name': 'test_dataset'} | |
| mock_get_config.return_value = mock_config | |
| mock_get_chart.return_value = "chart data" | |
| # Make the request | |
| response = client.get('/data/test_dataset?dataset_type=attacks_variations') | |
| # Assertions | |
| mock_read_csv.assert_called_once() | |
| mock_get_config.assert_called_once_with('test_dataset') | |
| mock_get_chart.assert_called_once_with(mock_config, mock_df) | |
| assert response == "chart data" | |
| def test_data_files_missing_dataset_type(client): | |
| """Test the data_files route with missing dataset_type.""" | |
| response = client.get('/data/test_dataset') | |
| assert response.status_code == 400 | |
| assert b"Dataset type not specified" in response.data | |
| def test_data_files_file_not_found(mock_read_csv, client): | |
| """Test the data_files route when file is not found.""" | |
| mock_read_csv.side_effect = FileNotFoundError() | |
| response = client.get('/data/test_dataset?dataset_type=benchmark') | |
| assert response.status_code == 404 | |
| assert b"File not found" in response.data | |
| def test_example_files_image(mock_image_examples, client): | |
| """Test the example_files route with image type.""" | |
| mock_image_examples.return_value = {"examples": ["image1", "image2"]} | |
| response = client.get('/examples/image') | |
| assert response.status_code == 200 | |
| data = json.loads(response.data) | |
| assert "examples" in data | |
| mock_image_examples.assert_called_once() | |
| def test_example_files_audio(mock_audio_examples, client): | |
| """Test the example_files route with audio type.""" | |
| mock_audio_examples.return_value = {"examples": ["audio1", "audio2"]} | |
| response = client.get('/examples/audio') | |
| assert response.status_code == 200 | |
| data = json.loads(response.data) | |
| assert "examples" in data | |
| mock_audio_examples.assert_called_once() | |
| def test_example_files_video(mock_video_examples, client): | |
| """Test the example_files route with video type.""" | |
| mock_video_examples.return_value = {"examples": ["video1", "video2"]} | |
| response = client.get('/examples/video') | |
| assert response.status_code == 200 | |
| data = json.loads(response.data) | |
| assert "examples" in data | |
| mock_video_examples.assert_called_once() | |
| def test_example_files_invalid_type(client): | |
| """Test the example_files route with invalid type.""" | |
| response = client.get('/examples/invalid') | |
| assert response.status_code == 400 | |
| assert b"Invalid example type" in response.data | |
| def test_proxy_valid_url(mock_requests_get, client): | |
| """Test the proxy route with a valid URL.""" | |
| # Create a mock response | |
| mock_response = MagicMock() | |
| mock_response.status_code = 200 | |
| mock_response.content = b"test content" | |
| mock_response.headers = {"Content-Type": "text/plain"} | |
| mock_requests_get.return_value = mock_response | |
| # Mock the ABS_DATASET_DOMAIN constant | |
| with patch('backend.app.ABS_DATASET_DOMAIN', 'https://example.com'): | |
| response = client.get('/proxy/https%3A%2F%2Fexample.com%2Ftest.txt') | |
| assert response.status_code == 200 | |
| assert response.data == b"test content" | |
| mock_requests_get.assert_called_once() | |
| def test_proxy_invalid_domain(mock_requests_get, client): | |
| """Test the proxy route with an invalid domain.""" | |
| # Mock the ABS_DATASET_DOMAIN constant | |
| with patch('backend.app.ABS_DATASET_DOMAIN', 'https://example.com'): | |
| response = client.get('/proxy/https%3A%2F%2Fmalicious.com%2Ftest.txt') | |
| assert response.status_code == 403 | |
| data = json.loads(response.data) | |
| assert "error" in data | |
| mock_requests_get.assert_not_called() | |
| def test_proxy_request_error(mock_requests_get, client): | |
| """Test the proxy route when the request fails.""" | |
| mock_requests_get.side_effect = Exception("Connection error") | |
| # Mock the ABS_DATASET_DOMAIN constant | |
| with patch('backend.app.ABS_DATASET_DOMAIN', 'https://example.com'): | |
| response = client.get('/proxy/https%3A%2F%2Fexample.com%2Ftest.txt') | |
| assert response.status_code == 500 | |
| data = json.loads(response.data) | |
| assert "error" in data | |
| def test_get_leaderboard(mock_get_filters, mock_get_old_format): | |
| """Test the get_leaderboard function.""" | |
| # Mock the input data | |
| df = pd.DataFrame({'model': ['model1', 'model2'], 'score': [0.9, 0.8]}) | |
| config = { | |
| 'first_cols': ['model'], | |
| 'attack_scores': ['score'], | |
| 'categories': ['category1'] | |
| } | |
| # Mock the function returns | |
| mock_get_old_format.return_value = df | |
| mock_get_filters.return_value = ( | |
| {'group1': ['metric1', 'metric2']}, | |
| ['metric1'] | |
| ) | |
| # Call the function | |
| response = get_leaderboard(config, df) | |
| # Assertions | |
| assert response.status_code == 200 | |
| data = json.loads(response.data) | |
| assert 'groups' in data | |
| assert 'default_selected_metrics' in data | |
| assert 'rows' in data | |
| mock_get_old_format.assert_called_once_with(df, config['first_cols'], config['attack_scores']) | |
| mock_get_filters.assert_called_once_with(df, config['categories']) | |
| def test_get_chart(mock_mk_variations): | |
| """Test the get_chart function.""" | |
| # Mock the input data | |
| df = pd.DataFrame({'model': ['model1', 'model2'], 'attack': ['a1', 'a2']}) | |
| config = { | |
| 'attacks_with_variations': ['attack1', 'attack2'] | |
| } | |
| # Mock the function return | |
| mock_chart_data = {'chart': 'data'} | |
| mock_mk_variations.return_value = mock_chart_data | |
| # Call the function | |
| response = get_chart(config, df) | |
| # Assertions | |
| assert response.status_code == 200 | |
| data = json.loads(response.data) | |
| assert data == mock_chart_data | |
| mock_mk_variations.assert_called_once_with(df, config['attacks_with_variations']) | |
| # Add a test for the main function | |
| def test_main(): | |
| """Test the main function.""" | |
| with patch('backend.app.app.run') as mock_run: | |
| # We can't directly test __main__ block, but we can test the app.run call | |
| # by importing and calling it in a test context | |
| import backend.app | |
| if hasattr(backend.app, 'main'): # If main function exists | |
| backend.app.main() | |
| mock_run.assert_called_once_with(host="0.0.0.0", port=7860, debug=True, use_reloader=True) | |