Skip to main content

mssf_util/mock/
runtime.rs

1// ------------------------------------------------------------
2// Copyright (c) Microsoft Corporation.  All rights reserved.
3// Licensed under the MIT License (MIT). See License.txt in the repo root for license information.
4// ------------------------------------------------------------
5
6use mssf_core::{
7    GUID, WString,
8    runtime::{IStatelessServiceFactory, IStatelessServiceInstance},
9    types::{ServicePartitionInformation, Uri},
10};
11
12use crate::mock::StatelessServicePartitionMock;
13
14/// Test driver for a single stateless service instance.
15pub struct StatelessServiceInstanceDriver {
16    service_factory: Box<dyn IStatelessServiceFactory>,
17    instance: Option<Box<dyn IStatelessServiceInstance>>,
18}
19
20impl StatelessServiceInstanceDriver {
21    pub fn new(service_factory: Box<dyn IStatelessServiceFactory>) -> Self {
22        Self {
23            service_factory,
24            instance: None,
25        }
26    }
27}
28
29pub struct CreateStatelessServiceArg {
30    pub init_data: Vec<u8>,
31    pub partition_id: GUID,
32    pub instance_id: i64, // Currently partition id and instance id should be globally unique
33    pub service_name: Uri,
34    pub service_type_name: WString,
35}
36
37// Driver code.
38
39impl StatelessServiceInstanceDriver {
40    pub async fn create_service_instance(
41        &mut self,
42        desc: &CreateStatelessServiceArg,
43    ) -> mssf_core::Result<()> {
44        let service_instance = self
45            .service_factory
46            .create_instance(
47                desc.service_type_name.clone(),
48                desc.service_name.clone(),
49                &desc.init_data,
50                desc.partition_id,
51                desc.instance_id,
52            )
53            .inspect_err(|e| {
54                tracing::error!("Failed to create stateless service instance: {:?}", e)
55            })?;
56        let prev = self.instance.replace(service_instance);
57        assert!(prev.is_none(), "Service instance already exists");
58        let cancellation_token = mssf_core::sync::SimpleCancelToken::new_boxed();
59
60        let instance_ref = self.instance.as_ref().unwrap();
61        let partition =
62            StatelessServicePartitionMock::new_arc(ServicePartitionInformation::Singleton(
63                mssf_core::types::SingletonPartitionInformation {
64                    id: desc.partition_id,
65                },
66            ));
67
68        // start the service instance
69        instance_ref.open(partition, cancellation_token).await?;
70        Ok(())
71    }
72
73    pub async fn delete_service_instance(&mut self) -> mssf_core::Result<()> {
74        if let Some(instance) = self.instance.take() {
75            let cancellation_token = mssf_core::sync::SimpleCancelToken::new_boxed();
76            instance.close(cancellation_token).await?;
77        }
78        Ok(())
79    }
80
81    pub fn delete_service_instance_force(&mut self) {
82        if let Some(instance) = self.instance.take() {
83            instance.abort();
84        }
85    }
86}