lavina/crates/projection-xmpp/src/testkit.rs

79 lines
2.4 KiB
Rust
Raw Normal View History

use prometheus::Registry as MetricsRegistry;
use crate::{Authenticated, XmppConnection};
use lavina_core::clustering::{ClusterConfig, ClusterMetadata};
use lavina_core::player::PlayerConnection;
use lavina_core::repo::{Storage, StorageConfig};
use lavina_core::LavinaCore;
use proto_xmpp::bind::{BindRequest, BindResponse, Jid, Name, Resource, Server};
pub(crate) struct TestServer {
pub core: LavinaCore,
}
impl TestServer {
pub async fn start() -> anyhow::Result<TestServer> {
let _ = tracing_subscriber::fmt::try_init();
core: separate the model from the logic implementation (#66) This separates the core in two layers – the model objects and the `LavinaCore` service. Service is responsible for implementing the application logic and exposing it as core's public API to projections, while the model objects will be independent of each other and responsible only for managing and owning in-memory data. The model objects include: 1. `Storage` – the open connection to the SQLite DB. 2. `PlayerRegistry` – creates, stores refs to, and stops player actors. 3. `RoomRegistry` – manages active rooms. 4. `DialogRegistry` – manages active dialogs. 5. `Broadcasting` – manages subscriptions of players to rooms on remote cluster nodes. 6. `LavinaClient` – manages HTTP connections to remote cluster nodes. 7. `ClusterMetadata` – read-only configuration of the cluster metadata, i.e. allocation of entities to nodes. As a result: 1. Model objects will be fully independent of each other, e.g. it's no longer necessary to provide a `Storage` to all registries, or to provide `PlayerRegistry` and `DialogRegistry` to each other. 2. Model objects will no longer be `Arc`-wrapped; instead the whole `Services` object will be `Arc`ed and provided to projections. 3. The public API of `lavina-core` will be properly delimited by the APIs of `LavinaCore`, `PlayerConnection` and so on. 4. `LavinaCore` and `PlayerConnection` will also contain APIs of all features, unlike it was previously with `RoomRegistry` and `DialogRegistry`. This is unfortunate, but it could be improved in future. Reviewed-on: https://git.vilunov.me/lavina/lavina/pulls/66
2024-05-13 14:32:45 +00:00
let mut metrics = MetricsRegistry::new();
let storage = Storage::open(StorageConfig {
db_path: ":memory:".into(),
})
.await?;
let cluster_config = ClusterConfig {
metadata: ClusterMetadata {
node_id: 0,
main_owner: 0,
rooms: Default::default(),
},
addresses: vec![],
};
core: separate the model from the logic implementation (#66) This separates the core in two layers – the model objects and the `LavinaCore` service. Service is responsible for implementing the application logic and exposing it as core's public API to projections, while the model objects will be independent of each other and responsible only for managing and owning in-memory data. The model objects include: 1. `Storage` – the open connection to the SQLite DB. 2. `PlayerRegistry` – creates, stores refs to, and stops player actors. 3. `RoomRegistry` – manages active rooms. 4. `DialogRegistry` – manages active dialogs. 5. `Broadcasting` – manages subscriptions of players to rooms on remote cluster nodes. 6. `LavinaClient` – manages HTTP connections to remote cluster nodes. 7. `ClusterMetadata` – read-only configuration of the cluster metadata, i.e. allocation of entities to nodes. As a result: 1. Model objects will be fully independent of each other, e.g. it's no longer necessary to provide a `Storage` to all registries, or to provide `PlayerRegistry` and `DialogRegistry` to each other. 2. Model objects will no longer be `Arc`-wrapped; instead the whole `Services` object will be `Arc`ed and provided to projections. 3. The public API of `lavina-core` will be properly delimited by the APIs of `LavinaCore`, `PlayerConnection` and so on. 4. `LavinaCore` and `PlayerConnection` will also contain APIs of all features, unlike it was previously with `RoomRegistry` and `DialogRegistry`. This is unfortunate, but it could be improved in future. Reviewed-on: https://git.vilunov.me/lavina/lavina/pulls/66
2024-05-13 14:32:45 +00:00
let core = LavinaCore::new(&mut metrics, cluster_config, storage).await?;
Ok(TestServer { core })
}
pub async fn reboot(self) -> anyhow::Result<TestServer> {
core: separate the model from the logic implementation (#66) This separates the core in two layers – the model objects and the `LavinaCore` service. Service is responsible for implementing the application logic and exposing it as core's public API to projections, while the model objects will be independent of each other and responsible only for managing and owning in-memory data. The model objects include: 1. `Storage` – the open connection to the SQLite DB. 2. `PlayerRegistry` – creates, stores refs to, and stops player actors. 3. `RoomRegistry` – manages active rooms. 4. `DialogRegistry` – manages active dialogs. 5. `Broadcasting` – manages subscriptions of players to rooms on remote cluster nodes. 6. `LavinaClient` – manages HTTP connections to remote cluster nodes. 7. `ClusterMetadata` – read-only configuration of the cluster metadata, i.e. allocation of entities to nodes. As a result: 1. Model objects will be fully independent of each other, e.g. it's no longer necessary to provide a `Storage` to all registries, or to provide `PlayerRegistry` and `DialogRegistry` to each other. 2. Model objects will no longer be `Arc`-wrapped; instead the whole `Services` object will be `Arc`ed and provided to projections. 3. The public API of `lavina-core` will be properly delimited by the APIs of `LavinaCore`, `PlayerConnection` and so on. 4. `LavinaCore` and `PlayerConnection` will also contain APIs of all features, unlike it was previously with `RoomRegistry` and `DialogRegistry`. This is unfortunate, but it could be improved in future. Reviewed-on: https://git.vilunov.me/lavina/lavina/pulls/66
2024-05-13 14:32:45 +00:00
let storage = self.core.shutdown().await;
core: separate the model from the logic implementation (#66) This separates the core in two layers – the model objects and the `LavinaCore` service. Service is responsible for implementing the application logic and exposing it as core's public API to projections, while the model objects will be independent of each other and responsible only for managing and owning in-memory data. The model objects include: 1. `Storage` – the open connection to the SQLite DB. 2. `PlayerRegistry` – creates, stores refs to, and stops player actors. 3. `RoomRegistry` – manages active rooms. 4. `DialogRegistry` – manages active dialogs. 5. `Broadcasting` – manages subscriptions of players to rooms on remote cluster nodes. 6. `LavinaClient` – manages HTTP connections to remote cluster nodes. 7. `ClusterMetadata` – read-only configuration of the cluster metadata, i.e. allocation of entities to nodes. As a result: 1. Model objects will be fully independent of each other, e.g. it's no longer necessary to provide a `Storage` to all registries, or to provide `PlayerRegistry` and `DialogRegistry` to each other. 2. Model objects will no longer be `Arc`-wrapped; instead the whole `Services` object will be `Arc`ed and provided to projections. 3. The public API of `lavina-core` will be properly delimited by the APIs of `LavinaCore`, `PlayerConnection` and so on. 4. `LavinaCore` and `PlayerConnection` will also contain APIs of all features, unlike it was previously with `RoomRegistry` and `DialogRegistry`. This is unfortunate, but it could be improved in future. Reviewed-on: https://git.vilunov.me/lavina/lavina/pulls/66
2024-05-13 14:32:45 +00:00
let mut metrics = MetricsRegistry::new();
let cluster_config = ClusterConfig {
metadata: ClusterMetadata {
node_id: 0,
main_owner: 0,
rooms: Default::default(),
},
addresses: vec![],
};
core: separate the model from the logic implementation (#66) This separates the core in two layers – the model objects and the `LavinaCore` service. Service is responsible for implementing the application logic and exposing it as core's public API to projections, while the model objects will be independent of each other and responsible only for managing and owning in-memory data. The model objects include: 1. `Storage` – the open connection to the SQLite DB. 2. `PlayerRegistry` – creates, stores refs to, and stops player actors. 3. `RoomRegistry` – manages active rooms. 4. `DialogRegistry` – manages active dialogs. 5. `Broadcasting` – manages subscriptions of players to rooms on remote cluster nodes. 6. `LavinaClient` – manages HTTP connections to remote cluster nodes. 7. `ClusterMetadata` – read-only configuration of the cluster metadata, i.e. allocation of entities to nodes. As a result: 1. Model objects will be fully independent of each other, e.g. it's no longer necessary to provide a `Storage` to all registries, or to provide `PlayerRegistry` and `DialogRegistry` to each other. 2. Model objects will no longer be `Arc`-wrapped; instead the whole `Services` object will be `Arc`ed and provided to projections. 3. The public API of `lavina-core` will be properly delimited by the APIs of `LavinaCore`, `PlayerConnection` and so on. 4. `LavinaCore` and `PlayerConnection` will also contain APIs of all features, unlike it was previously with `RoomRegistry` and `DialogRegistry`. This is unfortunate, but it could be improved in future. Reviewed-on: https://git.vilunov.me/lavina/lavina/pulls/66
2024-05-13 14:32:45 +00:00
let core = LavinaCore::new(&mut metrics, cluster_config, storage).await?;
core: separate the model from the logic implementation (#66) This separates the core in two layers – the model objects and the `LavinaCore` service. Service is responsible for implementing the application logic and exposing it as core's public API to projections, while the model objects will be independent of each other and responsible only for managing and owning in-memory data. The model objects include: 1. `Storage` – the open connection to the SQLite DB. 2. `PlayerRegistry` – creates, stores refs to, and stops player actors. 3. `RoomRegistry` – manages active rooms. 4. `DialogRegistry` – manages active dialogs. 5. `Broadcasting` – manages subscriptions of players to rooms on remote cluster nodes. 6. `LavinaClient` – manages HTTP connections to remote cluster nodes. 7. `ClusterMetadata` – read-only configuration of the cluster metadata, i.e. allocation of entities to nodes. As a result: 1. Model objects will be fully independent of each other, e.g. it's no longer necessary to provide a `Storage` to all registries, or to provide `PlayerRegistry` and `DialogRegistry` to each other. 2. Model objects will no longer be `Arc`-wrapped; instead the whole `Services` object will be `Arc`ed and provided to projections. 3. The public API of `lavina-core` will be properly delimited by the APIs of `LavinaCore`, `PlayerConnection` and so on. 4. `LavinaCore` and `PlayerConnection` will also contain APIs of all features, unlike it was previously with `RoomRegistry` and `DialogRegistry`. This is unfortunate, but it could be improved in future. Reviewed-on: https://git.vilunov.me/lavina/lavina/pulls/66
2024-05-13 14:32:45 +00:00
Ok(TestServer { core })
}
pub async fn shutdown(self) -> anyhow::Result<()> {
core: separate the model from the logic implementation (#66) This separates the core in two layers – the model objects and the `LavinaCore` service. Service is responsible for implementing the application logic and exposing it as core's public API to projections, while the model objects will be independent of each other and responsible only for managing and owning in-memory data. The model objects include: 1. `Storage` – the open connection to the SQLite DB. 2. `PlayerRegistry` – creates, stores refs to, and stops player actors. 3. `RoomRegistry` – manages active rooms. 4. `DialogRegistry` – manages active dialogs. 5. `Broadcasting` – manages subscriptions of players to rooms on remote cluster nodes. 6. `LavinaClient` – manages HTTP connections to remote cluster nodes. 7. `ClusterMetadata` – read-only configuration of the cluster metadata, i.e. allocation of entities to nodes. As a result: 1. Model objects will be fully independent of each other, e.g. it's no longer necessary to provide a `Storage` to all registries, or to provide `PlayerRegistry` and `DialogRegistry` to each other. 2. Model objects will no longer be `Arc`-wrapped; instead the whole `Services` object will be `Arc`ed and provided to projections. 3. The public API of `lavina-core` will be properly delimited by the APIs of `LavinaCore`, `PlayerConnection` and so on. 4. `LavinaCore` and `PlayerConnection` will also contain APIs of all features, unlike it was previously with `RoomRegistry` and `DialogRegistry`. This is unfortunate, but it could be improved in future. Reviewed-on: https://git.vilunov.me/lavina/lavina/pulls/66
2024-05-13 14:32:45 +00:00
let storage = self.core.shutdown().await;
storage.close().await;
Ok(())
}
}
pub async fn expect_user_authenticated<'a>(
server: &'a TestServer,
user: &'a Authenticated,
conn: &'a mut PlayerConnection,
) -> anyhow::Result<XmppConnection<'a>> {
let conn = XmppConnection {
user: &user,
user_handle: conn,
core: separate the model from the logic implementation (#66) This separates the core in two layers – the model objects and the `LavinaCore` service. Service is responsible for implementing the application logic and exposing it as core's public API to projections, while the model objects will be independent of each other and responsible only for managing and owning in-memory data. The model objects include: 1. `Storage` – the open connection to the SQLite DB. 2. `PlayerRegistry` – creates, stores refs to, and stops player actors. 3. `RoomRegistry` – manages active rooms. 4. `DialogRegistry` – manages active dialogs. 5. `Broadcasting` – manages subscriptions of players to rooms on remote cluster nodes. 6. `LavinaClient` – manages HTTP connections to remote cluster nodes. 7. `ClusterMetadata` – read-only configuration of the cluster metadata, i.e. allocation of entities to nodes. As a result: 1. Model objects will be fully independent of each other, e.g. it's no longer necessary to provide a `Storage` to all registries, or to provide `PlayerRegistry` and `DialogRegistry` to each other. 2. Model objects will no longer be `Arc`-wrapped; instead the whole `Services` object will be `Arc`ed and provided to projections. 3. The public API of `lavina-core` will be properly delimited by the APIs of `LavinaCore`, `PlayerConnection` and so on. 4. `LavinaCore` and `PlayerConnection` will also contain APIs of all features, unlike it was previously with `RoomRegistry` and `DialogRegistry`. This is unfortunate, but it could be improved in future. Reviewed-on: https://git.vilunov.me/lavina/lavina/pulls/66
2024-05-13 14:32:45 +00:00
core: &server.core,
hostname: "localhost".into(),
hostname_rooms: "rooms.localhost".into(),
};
let result = conn.bind(&BindRequest(Resource("whatever".into()))).await;
let expected = BindResponse(Jid {
name: Some(Name("tester".into())),
server: Server("localhost".into()),
resource: Some(Resource("tester".into())),
});
assert_eq!(expected, result);
Ok(conn)
}