|
1 | 1 | """Tests for admin API endpoints.""" |
2 | 2 |
|
3 | | -import datetime |
4 | 3 | from unittest.mock import MagicMock, patch |
5 | 4 |
|
6 | 5 | import pytest |
@@ -406,101 +405,3 @@ def test_update_problems_with_errors(self, test_client, mock_backend): |
406 | 405 | assert data["status"] == "ok" |
407 | 406 | assert len(data["errors"]) == 1 |
408 | 407 | assert data["errors"][0]["name"] == "bad-problem" |
409 | | - |
410 | | - |
411 | | -class TestSubmissionRateLimit: |
412 | | - """Test per-user submission rate limiting on Modal B200 for leaderboard 730.""" |
413 | | - |
414 | | - def test_rate_limit_blocks_b200_leaderboard_730(self, test_client, mock_backend): |
415 | | - """Second B200 submission to leaderboard 730 within 1 hour is rejected with 429.""" |
416 | | - mock_backend.db.__enter__ = MagicMock(return_value=mock_backend.db) |
417 | | - mock_backend.db.__exit__ = MagicMock(return_value=None) |
418 | | - |
419 | | - recent_time = datetime.datetime.now(tz=datetime.timezone.utc) |
420 | | - mock_backend.db.check_user_rate_limit = MagicMock(return_value=recent_time) |
421 | | - mock_backend.db.get_leaderboard_id = MagicMock(return_value=730) |
422 | | - mock_backend.db.validate_cli_id = MagicMock( |
423 | | - return_value={"user_id": "123", "user_name": "testuser"} |
424 | | - ) |
425 | | - |
426 | | - response = test_client.post( |
427 | | - "/test-lb/B200/test", |
428 | | - headers={"X-Popcorn-Cli-Id": "test-cli-id"}, |
429 | | - files={"file": ("solution.py", b"print('hello')", "text/plain")}, |
430 | | - ) |
431 | | - assert response.status_code == 429 |
432 | | - assert "Rate limit exceeded" in response.json()["detail"] |
433 | | - assert "NVIDIA runner" in response.json()["detail"] |
434 | | - |
435 | | - def test_rate_limit_skipped_for_non_b200(self, test_client, mock_backend): |
436 | | - """Rate limit is not enforced for non-B200 GPUs even on leaderboard 730.""" |
437 | | - mock_backend.db.__enter__ = MagicMock(return_value=mock_backend.db) |
438 | | - mock_backend.db.__exit__ = MagicMock(return_value=None) |
439 | | - mock_backend.accepts_jobs = True |
440 | | - |
441 | | - mock_backend.db.validate_cli_id = MagicMock( |
442 | | - return_value={"user_id": "123", "user_name": "testuser"} |
443 | | - ) |
444 | | - |
445 | | - mock_lb = MagicMock() |
446 | | - mock_lb.__getitem__ = lambda self, key: {"gpu_types": ["H100"]}[key] |
447 | | - mock_lb.get = lambda key, default=None: {"gpu_types": ["H100"]}.get(key, default) |
448 | | - mock_backend.db.get_leaderboard = MagicMock(return_value=mock_lb) |
449 | | - |
450 | | - response = test_client.post( |
451 | | - "/test-lb/H100/test", |
452 | | - headers={"X-Popcorn-Cli-Id": "test-cli-id"}, |
453 | | - files={"file": ("solution.py", b"print('hello')", "text/plain")}, |
454 | | - ) |
455 | | - # Should not hit rate limit at all — check_user_rate_limit should not be called |
456 | | - assert response.status_code != 429 |
457 | | - |
458 | | - def test_rate_limit_skipped_for_other_leaderboard(self, test_client, mock_backend): |
459 | | - """Rate limit is not enforced for B200 on a leaderboard other than 730.""" |
460 | | - mock_backend.db.__enter__ = MagicMock(return_value=mock_backend.db) |
461 | | - mock_backend.db.__exit__ = MagicMock(return_value=None) |
462 | | - mock_backend.accepts_jobs = True |
463 | | - |
464 | | - recent_time = datetime.datetime.now(tz=datetime.timezone.utc) |
465 | | - mock_backend.db.check_user_rate_limit = MagicMock(return_value=recent_time) |
466 | | - mock_backend.db.get_leaderboard_id = MagicMock(return_value=999) |
467 | | - mock_backend.db.validate_cli_id = MagicMock( |
468 | | - return_value={"user_id": "123", "user_name": "testuser"} |
469 | | - ) |
470 | | - |
471 | | - mock_lb = MagicMock() |
472 | | - mock_lb.__getitem__ = lambda self, key: {"gpu_types": ["B200"]}[key] |
473 | | - mock_lb.get = lambda key, default=None: {"gpu_types": ["B200"]}.get(key, default) |
474 | | - mock_backend.db.get_leaderboard = MagicMock(return_value=mock_lb) |
475 | | - |
476 | | - response = test_client.post( |
477 | | - "/other-lb/B200/test", |
478 | | - headers={"X-Popcorn-Cli-Id": "test-cli-id"}, |
479 | | - files={"file": ("solution.py", b"print('hello')", "text/plain")}, |
480 | | - ) |
481 | | - # Should not be rate limited since leaderboard ID is not 730 |
482 | | - assert response.status_code != 429 |
483 | | - |
484 | | - def test_rate_limit_allows_first_b200_submission(self, test_client, mock_backend): |
485 | | - """First B200 submission to leaderboard 730 passes the rate limit check.""" |
486 | | - mock_backend.db.__enter__ = MagicMock(return_value=mock_backend.db) |
487 | | - mock_backend.db.__exit__ = MagicMock(return_value=None) |
488 | | - mock_backend.accepts_jobs = True |
489 | | - |
490 | | - mock_backend.db.check_user_rate_limit = MagicMock(return_value=None) |
491 | | - mock_backend.db.get_leaderboard_id = MagicMock(return_value=730) |
492 | | - mock_backend.db.validate_cli_id = MagicMock( |
493 | | - return_value={"user_id": "123", "user_name": "testuser"} |
494 | | - ) |
495 | | - |
496 | | - mock_lb = MagicMock() |
497 | | - mock_lb.__getitem__ = lambda self, key: {"gpu_types": ["B200"]}[key] |
498 | | - mock_lb.get = lambda key, default=None: {"gpu_types": ["B200"]}.get(key, default) |
499 | | - mock_backend.db.get_leaderboard = MagicMock(return_value=mock_lb) |
500 | | - |
501 | | - response = test_client.post( |
502 | | - "/test-lb/B200/test", |
503 | | - headers={"X-Popcorn-Cli-Id": "test-cli-id"}, |
504 | | - files={"file": ("solution.py", b"print('hello')", "text/plain")}, |
505 | | - ) |
506 | | - assert response.status_code != 429 |
0 commit comments