diff --git a/testFrontend/SafeNSound.FakeUser/MonitorService.cs b/testFrontend/SafeNSound.FakeUser/MonitorService.cs
index 57d90a5..83c9c29 100644
--- a/testFrontend/SafeNSound.FakeUser/MonitorService.cs
+++ b/testFrontend/SafeNSound.FakeUser/MonitorService.cs
@@ -1,14 +1,21 @@
+using System.Net;
using ArcaneLibs.Extensions;
namespace SafeNSound.FakeUser;
-public class MonitorService(ILogger<MonitorService> logger, UserStore userStore): IHostedService {
- private Task? _getAllAlarmsTask, _assignBudgetTask;
+public class MonitorService(ILogger<MonitorService> logger, UserStore userStore) : IHostedService {
+ private Task? _getAllAlarmsTask,
+ _assignBudgetTask,
+ _getAlarmForRandomUserTask,
+ _rotateMonitoredUsersTask;
+
private readonly CancellationTokenSource _cts = new();
-
+
public async Task StartAsync(CancellationToken cancellationToken) {
_getAllAlarmsTask = GetAllAlarms(_cts.Token);
_assignBudgetTask = AssignBudget(_cts.Token);
+ _getAlarmForRandomUserTask = GetAlarmForRandomUser(_cts.Token);
+ _rotateMonitoredUsersTask = RotateMonitoredUsers(_cts.Token);
}
private async Task GetAllAlarms(CancellationToken cancellationToken) {
@@ -16,37 +23,96 @@ public class MonitorService(ILogger<MonitorService> logger, UserStore userStore)
try {
var user = userStore.GetRandomMonitor();
var alarms = await user.Client!.GetAllAlarms();
- if(alarms.Count > 0)
+ if (alarms.Count > 0) {
logger.LogInformation("Monitor {UserId} has outstanding alarms: {Alarm}", user.Auth.Username, alarms.ToJson(indent: false));
- // else
- // logger.LogInformation("Monitor {UserId} found no alarms to query", user.Auth.Username);
+ await user.Client!.GetAlarm(alarms.Keys.First());
+ await user.Client!.DeleteAlarm(alarms.Keys.First());
+ }
+
await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
- } catch (Exception ex) {
- logger.LogError(ex, "Error querying alarm");
+ }
+ catch (Exception ex) {
+ logger.LogError(ex, "Error querying alarm list");
}
}
}
-
- private async Task AssignBudget(CancellationToken cancellationToken) {
+
+ private async Task GetAlarmForRandomUser(CancellationToken cancellationToken) {
while (!cancellationToken.IsCancellationRequested) {
try {
var user = userStore.GetRandomMonitor();
- // var alarms = await user.Client!.GetAllAlarms();
- // if(alarms.Count > 0)
- // logger.LogInformation("Monitor {UserId} has outstanding alarms: {Alarm}", user.Auth.Username, alarms.ToJson(indent: false));
- // else
- // logger.LogInformation("Monitor {UserId} found no alarms to query", user.Auth.Username);
- await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
+ var watchedUserIds = await user.Client!.GetAssignedUsers();
+ if (watchedUserIds.Count == 0) {
+ logger.LogInformation("Monitor {UserId} has no assigned users", user.Auth.Username);
+ continue;
+ }
- } catch (Exception ex) {
- logger.LogError(ex, "Error querying alarm");
+ await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
+ }
+ catch (Exception ex) {
+ logger.LogError(ex, "Error querying alarm for user");
}
+ }
+ }
+
+ private async Task RotateMonitoredUsers(CancellationToken cancellationToken) {
+ while (!cancellationToken.IsCancellationRequested) {
+ try {
+ var user = userStore.GetRandomMonitor();
+ var watchedUserIds = (await user.Client!.GetAssignedUsers()).ToArray();
+ if (watchedUserIds.Length == 0) {
+ logger.LogInformation("Monitor {UserId} has no assigned users", user.Auth.Username);
+ }
+ else {
+ var idToRemove = Random.Shared.GetItems(watchedUserIds, 1).First();
+ await user.Client!.RemoveAssignedUser(idToRemove);
+ }
+
+ string idToAdd;
+ do {
+ idToAdd = userStore.GetRandomUserOfAnyType().WhoAmI!.UserId;
+ } while (watchedUserIds.Contains(idToAdd));
+ await user.Client!.AddAssignedUser(idToAdd);
+
+ await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
+ }
+ catch (Exception ex) {
+ logger.LogError(ex, "Error rotating monitored users");
+ }
+ }
+ }
+
+ private async Task AssignBudget(CancellationToken cancellationToken) {
+ while (!cancellationToken.IsCancellationRequested) {
+ try {
+ var user = userStore.GetRandomMonitor();
+ var monitoredUsers = (await user.Client!.GetAssignedUsers()).ToArray();
+ if (monitoredUsers.Length == 0) {
+ logger.LogInformation("Monitor {UserId} has no assigned users", user.Auth.Username);
+ continue;
+ }
+ var userId = Random.Shared.GetItems(monitoredUsers, 1).First();
+ var budget = Random.Shared.NextDouble();
+ await user.Client!.GetBudget(userId);
+ await user.Client!.AddBudget(userId, new() {
+ Amount = budget,
+ Reason = "Random budget assignment",
+ Venue = "FakeUser"
+ });
+ await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
+ }
+ catch (Exception ex) {
+ logger.LogError(ex, "Error assigning budget");
+ }
}
}
public async Task StopAsync(CancellationToken cancellationToken) {
await _cts.CancelAsync();
await _getAllAlarmsTask!;
+ await _assignBudgetTask!;
+ await _getAlarmForRandomUserTask!;
+ await _rotateMonitoredUsersTask!;
}
}
\ No newline at end of file
diff --git a/testFrontend/SafeNSound.FakeUser/Program.cs b/testFrontend/SafeNSound.FakeUser/Program.cs
index 7c3eaff..0852e6f 100644
--- a/testFrontend/SafeNSound.FakeUser/Program.cs
+++ b/testFrontend/SafeNSound.FakeUser/Program.cs
@@ -15,7 +15,7 @@ builder.Services.AddSingleton<SafeNSoundConfiguration>();
builder.Services.AddSingleton<SafeNSoundAuthentication>();
builder.Services.AddSingleton<UserStore>();
builder.Services.AddHostedService<UserStore>(sp => sp.GetRequiredService<UserStore>());
-builder.Services.AddHostedService<RandomAlarmService>();
+builder.Services.AddHostedService<UserService>();
builder.Services.AddHostedService<MonitorService>();
// WrappedHttpClient.LogRequests = false;
diff --git a/testFrontend/SafeNSound.FakeUser/RandomAlarmService.cs b/testFrontend/SafeNSound.FakeUser/RandomAlarmService.cs
deleted file mode 100644
index 7835f89..0000000
--- a/testFrontend/SafeNSound.FakeUser/RandomAlarmService.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-namespace SafeNSound.FakeUser;
-
-public class RandomAlarmService(UserStore userStore): IHostedService {
- private Task? _listenerTask;
- private readonly CancellationTokenSource _cts = new();
-
- public async Task StartAsync(CancellationToken cancellationToken) {
- _listenerTask = Run(_cts.Token);
- }
-
- private async Task Run(CancellationToken cancellationToken) {
- while (!cancellationToken.IsCancellationRequested) {
- try {
- var user = userStore.GetRandomUser();
- if (Random.Shared.Next(100) > 90) {
- await user.Client!.SetAlarm(new Sdk.AlarmDto {
- Reason = "fall"
- });
- }
- else {
- await user.Client!.DeleteAlarm();
- }
- }
- catch (Exception ex) {
- Console.WriteLine($"Error setting/deleting alarm: {ex.Message}");
- }
-
- await Task.Delay(TimeSpan.FromMilliseconds(100), cancellationToken);
- }
- }
-
- public async Task StopAsync(CancellationToken cancellationToken) {
- await _cts.CancelAsync();
- }
-}
\ No newline at end of file
diff --git a/testFrontend/SafeNSound.FakeUser/UserService.cs b/testFrontend/SafeNSound.FakeUser/UserService.cs
new file mode 100644
index 0000000..e717458
--- /dev/null
+++ b/testFrontend/SafeNSound.FakeUser/UserService.cs
@@ -0,0 +1,59 @@
+namespace SafeNSound.FakeUser;
+
+public class UserService(ILogger<UserService> logger, UserStore userStore) : IHostedService {
+ private Task _alarmTask, _spendBudgetTask;
+ private readonly CancellationTokenSource _cts = new();
+
+ public async Task StartAsync(CancellationToken cancellationToken) {
+ _alarmTask = ManageAlarms(_cts.Token);
+ _spendBudgetTask = AssignBudget(_cts.Token);
+ }
+
+ private static readonly string[] validReasons = ["fall", "toilet"];
+
+ private async Task ManageAlarms(CancellationToken cancellationToken) {
+ while (!cancellationToken.IsCancellationRequested) {
+ try {
+ var user = userStore.GetRandomUser();
+ var currentAlarm = await user.Client!.GetAlarm();
+ if (currentAlarm is null) {
+ await user.Client!.SetAlarm(new Sdk.AlarmDto {
+ Reason = Random.Shared.GetItems(validReasons, 1).First()
+ });
+ }
+ else {
+ await user.Client!.DeleteAlarm();
+ }
+ }
+ catch (Exception ex) {
+ logger.LogError(ex, "Error setting/deleting alarm");
+ }
+
+ await Task.Delay(TimeSpan.FromMilliseconds(250), cancellationToken);
+ }
+ }
+
+ private async Task AssignBudget(CancellationToken cancellationToken) {
+ while (!cancellationToken.IsCancellationRequested) {
+ try {
+ var user = userStore.GetRandomUser();
+ var budget = await user.Client!.GetBudget();
+ await user.Client!.SpendBudget(new() {
+ Amount = Math.Min(budget.Amount, Random.Shared.NextDouble()),
+ Reason = "Random budget spending",
+ Venue = "The Store"
+ });
+ await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
+ }
+ catch (Exception ex) {
+ logger.LogError(ex, "Error spending budget");
+ }
+ }
+ }
+
+ public async Task StopAsync(CancellationToken cancellationToken) {
+ await _cts.CancelAsync();
+ await _alarmTask;
+ await _spendBudgetTask;
+ }
+}
\ No newline at end of file
diff --git a/testFrontend/SafeNSound.FakeUser/UserStore.cs b/testFrontend/SafeNSound.FakeUser/UserStore.cs
index 9b04efb..f643a68 100644
--- a/testFrontend/SafeNSound.FakeUser/UserStore.cs
+++ b/testFrontend/SafeNSound.FakeUser/UserStore.cs
@@ -5,7 +5,7 @@ namespace SafeNSound.FakeUser;
public class UserStore(SafeNSoundAuthentication authService, SafeNSoundConfiguration config) : IHostedService {
public List<ClientContainer> Admins { get; } = Enumerable.Range(0, 1).Select(_ => new ClientContainer()).ToList();
public List<ClientContainer> Monitors { get; } = Enumerable.Range(0, 5).Select(_ => new ClientContainer()).ToList();
- public List<ClientContainer> Users { get; } = Enumerable.Range(0, 150000).Select(_ => new ClientContainer()).ToList();
+ public List<ClientContainer> Users { get; } = Enumerable.Range(0, 15).Select(_ => new ClientContainer()).ToList();
public List<ClientContainer> AllUsers => [.. Users, .. Monitors, .. Admins];
public ClientContainer GetRandomUser() {
@@ -51,8 +51,16 @@ public class UserStore(SafeNSoundAuthentication authService, SafeNSoundConfigura
var tasks = ((ClientContainer[]) [..Users, ..Monitors, ..Admins]).Select(async container => {
await ss.WaitAsync();
await authService.Register(container.Auth);
- // container.Client = new SafeNSoundClient(config, (await authService.Login(container.Auth)).AccessToken);
- // container.WhoAmI = await container.Client.WhoAmI();
+ container.Client = new SafeNSoundClient(config, (await authService.Login(container.Auth)).AccessToken);
+ container.WhoAmI = await container.Client.WhoAmI();
+ await container.Client.UpdateDevice(container.WhoAmI.DeviceId, new() {
+ Name = "FakeUser-" + container.Auth.Username,
+ });
+
+ if (container.Auth.UserType == "admin") {
+ await container.Client.MonitorAllUsers();
+ }
+
ss.Release();
}).ToList();
await Task.WhenAll(tasks);
@@ -76,6 +84,10 @@ public class UserStore(SafeNSoundAuthentication authService, SafeNSoundConfigura
private async Task Cleanup(ClientContainer container) {
if (container.Client == null) return;
try {
+ _ = await container.Client.GetDevices();
+ if(Random.Shared.Next(100)>50)
+ await container.Client.DeleteDevice(container.WhoAmI!.DeviceId);
+ else await container.Client.LogOut();
await container.Client.DeleteAccount(container.Auth);
}
catch {
|