File size: 2,715 Bytes
13fc29d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
"""
Load test for SolarWine API using Locust.

Usage:
    pip install locust
    locust -f scripts/load_test.py --host https://solarwine-api.hf.space

    # Quick headless run (10 users, 5 min):
    locust -f scripts/load_test.py --host https://solarwine-api.hf.space \
           --users 10 --spawn-rate 2 --run-time 5m --headless

    # Full stress test (50 users, 5 min):
    locust -f scripts/load_test.py --host https://solarwine-api.hf.space \
           --users 50 --spawn-rate 5 --run-time 5m --headless
"""

from locust import HttpUser, task, between


class SolarWineUser(HttpUser):
    """Simulates a frontend user browsing the SolarWine dashboard."""

    wait_time = between(1, 5)

    # ── High-frequency endpoints (dashboard polling) ──

    @task(10)
    def health(self):
        self.client.get("/api/health")

    @task(8)
    def weather_current(self):
        self.client.get("/api/weather/current")

    @task(6)
    def sensor_snapshot(self):
        self.client.get("/api/sensors/snapshot")

    @task(5)
    def energy_current(self):
        self.client.get("/api/energy/current")

    @task(4)
    def data_sources(self):
        self.client.get("/api/health/data-sources")

    # ── Medium-frequency endpoints (page navigations) ──

    @task(3)
    def energy_daily(self):
        from datetime import date
        self.client.get(f"/api/energy/daily/{date.today()}")

    @task(3)
    def weather_history(self):
        from datetime import date, timedelta
        end = date.today()
        start = end - timedelta(days=7)
        self.client.get(f"/api/weather/history?start_date={start}&end_date={end}&format=rows")

    @task(2)
    def photosynthesis_current(self):
        self.client.get("/api/photosynthesis/current")

    @task(2)
    def biology_rules(self):
        self.client.get("/api/biology/rules")

    @task(2)
    def control_status(self):
        self.client.get("/api/control/status")

    @task(2)
    def control_trackers(self):
        self.client.get("/api/control/trackers")

    @task(1)
    def phenology(self):
        self.client.get("/api/biology/phenology")

    @task(1)
    def chill_units(self):
        self.client.get("/api/biology/chill-units?season_start=2025-11-01")

    # ── Low-frequency endpoints (heavier operations) ──

    @task(1)
    def photosynthesis_forecast(self):
        self.client.get("/api/photosynthesis/forecast")

    @task(1)
    def control_plan(self):
        self.client.get("/api/control/plan")

    @task(1)
    def sensor_soil(self):
        self.client.get("/api/sensors/soil-moisture?hours=168")

    @task(1)
    def sensor_rain(self):
        self.client.get("/api/sensors/rain?hours=168")