Skip to content

Commit 7ac07c7

Browse files
committed
Add tests that receive or return service object in a service
1 parent c9bfceb commit 7ac07c7

File tree

3 files changed

+178
-1
lines changed

3 files changed

+178
-1
lines changed

remote-trait-object/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ serde_cbor = "0.11.1"
1313
linkme = "0.2.1"
1414

1515
[dev-dependencies]
16-
remote-trait-object-macro = { path = "../remote-trait-object-macro"}
16+
env_logger = "0.7.1"
17+
remote-trait-object-macro = { path = "../remote-trait-object-macro"}

remote-trait-object/src/tests.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
// You should have received a copy of the GNU Affero General Public License
1515
// along with this program. If not, see <https://www.gnu.org/licenses/>.
1616

17+
mod complex_trait;
18+
1719
use crate as remote_trait_object;
1820
use remote_trait_object_macro as rto_macro;
1921

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
// Copyright 2020 Kodebox, Inc.
2+
// This file is part of CodeChain.
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Affero General Public License as
6+
// published by the Free Software Foundation, either version 3 of the
7+
// License, or (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Affero General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Affero General Public License
15+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
17+
use super::TestPort;
18+
use crate as remote_trait_object;
19+
use crate::{ExportService, ImportService, Port, SArc, Service};
20+
use remote_trait_object_macro as rto_macro;
21+
use std::sync::{Arc, Mutex};
22+
23+
#[rto_macro::service]
24+
trait A: Service {
25+
fn service_object_as_argument(&self, b: SArc<dyn B>);
26+
fn service_object_as_return(&self) -> SArc<dyn B>;
27+
fn recursive_service_object(&self) -> SArc<dyn A>;
28+
fn get_recursion_count(&self) -> u32;
29+
}
30+
31+
#[rto_macro::service]
32+
trait B: Service {
33+
fn inc(&self);
34+
fn get(&self) -> i32;
35+
}
36+
37+
struct SimpleA {
38+
recursion_count: u32,
39+
}
40+
41+
impl SimpleA {
42+
pub fn new() -> Self {
43+
Self {
44+
recursion_count: 0,
45+
}
46+
}
47+
48+
pub fn with_recursion_count(recursion_count: u32) -> Self {
49+
Self {
50+
recursion_count,
51+
}
52+
}
53+
}
54+
55+
impl A for SimpleA {
56+
fn service_object_as_argument(&self, b: SArc<dyn B>) {
57+
let b = b.unwrap();
58+
assert_eq!(0, b.get());
59+
b.inc();
60+
b.inc();
61+
b.inc();
62+
assert_eq!(3, b.get());
63+
}
64+
65+
fn service_object_as_return(&self) -> SArc<dyn B> {
66+
let b = Arc::new(SimpleB::new());
67+
SArc::new(b)
68+
}
69+
70+
fn recursive_service_object(&self) -> SArc<dyn A> {
71+
let a = Arc::new(SimpleA::with_recursion_count(self.recursion_count + 1));
72+
SArc::new(a)
73+
}
74+
75+
fn get_recursion_count(&self) -> u32 {
76+
self.recursion_count
77+
}
78+
}
79+
80+
impl Service for SimpleA {}
81+
82+
struct SimpleB {
83+
count: Mutex<i32>,
84+
}
85+
86+
impl SimpleB {
87+
pub fn new() -> Self {
88+
Self {
89+
count: Mutex::new(0),
90+
}
91+
}
92+
}
93+
94+
impl Service for SimpleB {}
95+
impl B for SimpleB {
96+
fn inc(&self) {
97+
*self.count.lock().unwrap() += 1
98+
}
99+
fn get(&self) -> i32 {
100+
*self.count.lock().unwrap()
101+
}
102+
}
103+
104+
fn init_logger() {
105+
let _ = env_logger::builder().is_test(true).try_init();
106+
}
107+
108+
fn create_remote_a(port: Arc<dyn Port>) -> Arc<dyn A> {
109+
let a: Arc<dyn A> = Arc::new(SimpleA::new());
110+
let handle = <dyn A as ExportService<dyn A>>::export(Arc::downgrade(&port), a);
111+
<dyn A as ImportService<dyn A>>::import(Arc::downgrade(&port), handle)
112+
}
113+
114+
#[test]
115+
fn service_object_as_return() {
116+
init_logger();
117+
118+
let port = Arc::new(TestPort::new());
119+
let remote_a = create_remote_a(port.clone());
120+
121+
let remote_b = remote_a.service_object_as_return().unwrap();
122+
assert_eq!(remote_b.get(), 0);
123+
remote_b.inc();
124+
assert_eq!(remote_b.get(), 1);
125+
remote_b.inc();
126+
assert_eq!(remote_b.get(), 2);
127+
128+
drop(remote_a);
129+
drop(remote_b);
130+
drop(port)
131+
}
132+
133+
#[test]
134+
fn service_object_as_argument() {
135+
init_logger();
136+
137+
let port = Arc::new(TestPort::new());
138+
let remote_a = create_remote_a(port.clone());
139+
140+
let service_object_b = Arc::new(SimpleB::new());
141+
remote_a.service_object_as_argument(SArc::new(service_object_b));
142+
143+
drop(remote_a);
144+
drop(port)
145+
}
146+
147+
#[test]
148+
fn recursive_service_object() {
149+
init_logger();
150+
151+
let port = Arc::new(TestPort::new());
152+
let mut remote_a = create_remote_a(port.clone());
153+
let mut remote_as = Vec::new();
154+
remote_as.push(Arc::clone(&remote_a));
155+
156+
for i in 0..10 {
157+
assert_eq!(remote_a.get_recursion_count(), i);
158+
remote_a = remote_a.recursive_service_object().unwrap();
159+
remote_as.push(Arc::clone(&remote_a));
160+
}
161+
assert_eq!(remote_a.get_recursion_count(), 10);
162+
163+
let remote_b = remote_a.service_object_as_return().unwrap();
164+
remote_b.inc();
165+
assert_eq!(remote_b.get(), 1);
166+
167+
// remote_a + remote_b + recursive 10 remote_a = 12
168+
assert_eq!(port.register_len(), 12);
169+
170+
drop(remote_as);
171+
drop(remote_a);
172+
drop(remote_b);
173+
drop(port)
174+
}

0 commit comments

Comments
 (0)