@@ -19,3 +19,127 @@ pub trait TofuStore: Send + Sync + Debug {
1919 ) -> Result < ( ) , Box < dyn Send + Sync + Error > > ;
2020}
2121
22+ #[ cfg( test) ]
23+ mod tests {
24+ use super :: * ;
25+ use std:: collections:: HashMap ;
26+ use std:: sync:: Mutex ;
27+
28+ #[ derive( Debug ) ]
29+ struct InMemoryTofuStore {
30+ store : Mutex < HashMap < String , Vec < u8 > > > ,
31+ }
32+
33+ impl InMemoryTofuStore {
34+ fn new ( ) -> Self {
35+ Self {
36+ store : Mutex :: new ( HashMap :: new ( ) ) ,
37+ }
38+ }
39+ }
40+
41+ impl TofuStore for InMemoryTofuStore {
42+ fn get_certificate (
43+ & self ,
44+ host : & str ,
45+ ) -> Result < Option < Vec < u8 > > , Box < dyn Send + Sync + Error > > {
46+ let store = self . store . lock ( ) . unwrap ( ) ;
47+ Ok ( store. get ( host) . cloned ( ) )
48+ }
49+
50+ fn set_certificate (
51+ & self ,
52+ host : & str ,
53+ cert : Vec < u8 > ,
54+ ) -> Result < ( ) , Box < dyn Send + Sync + Error > > {
55+ let mut store = self . store . lock ( ) . unwrap ( ) ;
56+ store. insert ( host. to_string ( ) , cert) ;
57+ Ok ( ( ) )
58+ }
59+ }
60+
61+ #[ test]
62+ fn test_tofu_first_use ( ) {
63+ let store = InMemoryTofuStore :: new ( ) ;
64+
65+ let host = "example.com" ;
66+ let cert = b"test certificate data" . to_vec ( ) ;
67+
68+ // First use: certificate should not exist
69+ let result = store. get_certificate ( host) . unwrap ( ) ;
70+ assert ! (
71+ result. is_none( ) ,
72+ "Certificate should not exist on first use"
73+ ) ;
74+
75+ store. set_certificate ( host, cert. clone ( ) ) . unwrap ( ) ;
76+
77+ let stored = store. get_certificate ( host) . unwrap ( ) ;
78+ assert_eq ! ( stored, Some ( cert) , "Certificate should be stored" ) ;
79+ }
80+
81+ #[ test]
82+ fn test_tofu_certificate_match ( ) {
83+ let store = InMemoryTofuStore :: new ( ) ;
84+
85+ let host = "example.com" ;
86+ let cert = b"test certificate data" . to_vec ( ) ;
87+
88+ // Store certificate
89+ store. set_certificate ( host, cert. clone ( ) ) . unwrap ( ) ;
90+
91+ // Retrieve and verify it matches
92+ let stored = store. get_certificate ( host) . unwrap ( ) ;
93+ assert_eq ! ( stored, Some ( cert) , "Stored certificate should match" ) ;
94+ }
95+
96+ #[ test]
97+ fn test_tofu_certificate_change ( ) {
98+ let store = InMemoryTofuStore :: new ( ) ;
99+
100+ let host = "example.com" ;
101+ let cert1 = b"first certificate" . to_vec ( ) ;
102+ let cert2 = b"second certificate" . to_vec ( ) ;
103+
104+ // Store first certificate
105+ store. set_certificate ( host, cert1. clone ( ) ) . unwrap ( ) ;
106+ let stored1 = store. get_certificate ( host) . unwrap ( ) ;
107+ assert_eq ! (
108+ stored1,
109+ Some ( cert1. clone( ) ) ,
110+ "First certificate should be stored"
111+ ) ;
112+
113+ // Update with different certificate
114+ store. set_certificate ( host, cert2. clone ( ) ) . unwrap ( ) ;
115+ let stored2 = store. get_certificate ( host) . unwrap ( ) ;
116+ assert_eq ! (
117+ stored2,
118+ Some ( cert2. clone( ) ) ,
119+ "Second certificate should replace first"
120+ ) ;
121+ assert_ne ! (
122+ stored2,
123+ Some ( cert1) ,
124+ "Stored certificate should not match first"
125+ ) ;
126+ }
127+
128+ #[ test]
129+ fn test_tofu_large_certificate ( ) {
130+ let store = InMemoryTofuStore :: new ( ) ;
131+
132+ let host = "example.com" ;
133+ // Create a large certificate (10KB)
134+ let cert = vec ! [ 0x42 ; 10 * 1024 ] ;
135+
136+ // Store large certificate
137+ store. set_certificate ( host, cert. clone ( ) ) . unwrap ( ) ;
138+ let stored = store. get_certificate ( host) . unwrap ( ) ;
139+ assert_eq ! (
140+ stored,
141+ Some ( cert) ,
142+ "Large certificate should be stored correctly"
143+ ) ;
144+ }
145+ }
0 commit comments