rocketmq_remoting/base/
connection_net_event.rs

1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17use std::net::SocketAddr;
18
19#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
20pub enum ConnectionNetEvent {
21    CONNECTED(SocketAddr),
22    DISCONNECTED,
23    EXCEPTION,
24    IDLE,
25}
26
27#[cfg(test)]
28mod tests {
29    use std::collections::HashSet;
30
31    use super::*;
32
33    fn create_socket_addr(ip: &str, port: u16) -> SocketAddr {
34        format!("{}:{}", ip, port).parse().unwrap()
35    }
36
37    #[test]
38    fn test_connected_event_creation() {
39        let addr = create_socket_addr("127.0.0.1", 9876);
40        let event = ConnectionNetEvent::CONNECTED(addr);
41
42        match event {
43            ConnectionNetEvent::CONNECTED(a) => assert_eq!(a, addr),
44            _ => panic!("Expected CONNECTED event"),
45        }
46    }
47
48    #[test]
49    fn test_disconnected_event_creation() {
50        let event = ConnectionNetEvent::DISCONNECTED;
51        assert!(matches!(event, ConnectionNetEvent::DISCONNECTED));
52    }
53
54    #[test]
55    fn test_exception_event_creation() {
56        let event = ConnectionNetEvent::EXCEPTION;
57        assert!(matches!(event, ConnectionNetEvent::EXCEPTION));
58    }
59
60    #[test]
61    fn test_idle_event_creation() {
62        let event = ConnectionNetEvent::IDLE;
63        assert!(matches!(event, ConnectionNetEvent::IDLE));
64    }
65
66    #[test]
67    fn test_event_equality() {
68        let addr1 = create_socket_addr("192.168.1.100", 10911);
69        let addr2 = create_socket_addr("192.168.1.100", 10911);
70        let addr3 = create_socket_addr("192.168.1.101", 10911);
71
72        // CONNECTED events with same address should be equal
73        assert_eq!(
74            ConnectionNetEvent::CONNECTED(addr1),
75            ConnectionNetEvent::CONNECTED(addr2)
76        );
77
78        // CONNECTED events with different addresses should not be equal
79        assert_ne!(
80            ConnectionNetEvent::CONNECTED(addr1),
81            ConnectionNetEvent::CONNECTED(addr3)
82        );
83
84        // Same variant events should be equal
85        assert_eq!(
86            ConnectionNetEvent::DISCONNECTED,
87            ConnectionNetEvent::DISCONNECTED
88        );
89        assert_eq!(ConnectionNetEvent::EXCEPTION, ConnectionNetEvent::EXCEPTION);
90        assert_eq!(ConnectionNetEvent::IDLE, ConnectionNetEvent::IDLE);
91
92        // Different variant events should not be equal
93        assert_ne!(
94            ConnectionNetEvent::DISCONNECTED,
95            ConnectionNetEvent::EXCEPTION
96        );
97        assert_ne!(ConnectionNetEvent::EXCEPTION, ConnectionNetEvent::IDLE);
98        assert_ne!(ConnectionNetEvent::IDLE, ConnectionNetEvent::DISCONNECTED);
99    }
100
101    #[test]
102    fn test_event_clone() {
103        let addr = create_socket_addr("10.0.0.1", 8080);
104        let event1 = ConnectionNetEvent::CONNECTED(addr);
105        let event2 = event1;
106
107        assert_eq!(event1, event2);
108
109        let event3 = ConnectionNetEvent::DISCONNECTED;
110        let event4 = event3;
111        assert_eq!(event3, event4);
112    }
113
114    #[test]
115    fn test_event_copy() {
116        let addr = create_socket_addr("172.16.0.1", 3000);
117        let event1 = ConnectionNetEvent::CONNECTED(addr);
118        let event2 = event1; // Copy occurs here
119
120        // Both should be usable after copy
121        assert_eq!(event1, event2);
122        match (event1, event2) {
123            (ConnectionNetEvent::CONNECTED(a1), ConnectionNetEvent::CONNECTED(a2)) => {
124                assert_eq!(a1, a2);
125            }
126            _ => panic!("Expected CONNECTED events"),
127        }
128    }
129
130    #[test]
131    fn test_event_hash() {
132        let addr1 = create_socket_addr("192.168.1.1", 9000);
133        let addr2 = create_socket_addr("192.168.1.1", 9000);
134        let addr3 = create_socket_addr("192.168.1.2", 9000);
135
136        let mut set = HashSet::new();
137
138        // Insert first CONNECTED event
139        set.insert(ConnectionNetEvent::CONNECTED(addr1));
140        assert_eq!(set.len(), 1);
141
142        // Insert duplicate CONNECTED event (same address)
143        set.insert(ConnectionNetEvent::CONNECTED(addr2));
144        assert_eq!(set.len(), 1); // Should not increase
145
146        // Insert different CONNECTED event (different address)
147        set.insert(ConnectionNetEvent::CONNECTED(addr3));
148        assert_eq!(set.len(), 2);
149
150        // Insert other event types
151        set.insert(ConnectionNetEvent::DISCONNECTED);
152        assert_eq!(set.len(), 3);
153
154        set.insert(ConnectionNetEvent::EXCEPTION);
155        assert_eq!(set.len(), 4);
156
157        set.insert(ConnectionNetEvent::IDLE);
158        assert_eq!(set.len(), 5);
159
160        // Insert duplicate of variant without data
161        set.insert(ConnectionNetEvent::IDLE);
162        assert_eq!(set.len(), 5); // Should not increase
163    }
164
165    #[test]
166    fn test_event_ordering() {
167        let addr1 = create_socket_addr("10.0.0.1", 1000);
168        let addr2 = create_socket_addr("10.0.0.2", 1000);
169
170        // Test ordering of CONNECTED events by address
171        let event1 = ConnectionNetEvent::CONNECTED(addr1);
172        let event2 = ConnectionNetEvent::CONNECTED(addr2);
173        assert!(event1 < event2);
174
175        // Test ordering between different variants
176        // The order is determined by the enum variant order
177        assert!(ConnectionNetEvent::CONNECTED(addr1) < ConnectionNetEvent::DISCONNECTED);
178        assert!(ConnectionNetEvent::DISCONNECTED < ConnectionNetEvent::EXCEPTION);
179        assert!(ConnectionNetEvent::EXCEPTION < ConnectionNetEvent::IDLE);
180    }
181
182    #[test]
183    fn test_event_debug_format() {
184        let addr = create_socket_addr("127.0.0.1", 12345);
185
186        let connected = ConnectionNetEvent::CONNECTED(addr);
187        let debug_str = format!("{:?}", connected);
188        assert!(debug_str.contains("CONNECTED"));
189        assert!(debug_str.contains("127.0.0.1"));
190        assert!(debug_str.contains("12345"));
191
192        let disconnected = ConnectionNetEvent::DISCONNECTED;
193        assert_eq!(format!("{:?}", disconnected), "DISCONNECTED");
194
195        let exception = ConnectionNetEvent::EXCEPTION;
196        assert_eq!(format!("{:?}", exception), "EXCEPTION");
197
198        let idle = ConnectionNetEvent::IDLE;
199        assert_eq!(format!("{:?}", idle), "IDLE");
200    }
201
202    #[test]
203    fn test_connected_with_ipv6() {
204        let addr: SocketAddr = "[::1]:8080".parse().unwrap();
205        let event = ConnectionNetEvent::CONNECTED(addr);
206
207        match event {
208            ConnectionNetEvent::CONNECTED(a) => {
209                assert_eq!(a, addr);
210                assert!(a.is_ipv6());
211            }
212            _ => panic!("Expected CONNECTED event"),
213        }
214    }
215
216    #[test]
217    fn test_event_pattern_matching() {
218        let addr = create_socket_addr("192.168.0.1", 5000);
219        let events = vec![
220            ConnectionNetEvent::CONNECTED(addr),
221            ConnectionNetEvent::DISCONNECTED,
222            ConnectionNetEvent::EXCEPTION,
223            ConnectionNetEvent::IDLE,
224        ];
225
226        let mut connected_count = 0;
227        let mut disconnected_count = 0;
228        let mut exception_count = 0;
229        let mut idle_count = 0;
230
231        for event in events {
232            match event {
233                ConnectionNetEvent::CONNECTED(_) => connected_count += 1,
234                ConnectionNetEvent::DISCONNECTED => disconnected_count += 1,
235                ConnectionNetEvent::EXCEPTION => exception_count += 1,
236                ConnectionNetEvent::IDLE => idle_count += 1,
237            }
238        }
239
240        assert_eq!(connected_count, 1);
241        assert_eq!(disconnected_count, 1);
242        assert_eq!(exception_count, 1);
243        assert_eq!(idle_count, 1);
244    }
245
246    #[test]
247    fn test_event_in_option() {
248        let addr = create_socket_addr("10.10.10.10", 7777);
249        let some_event: Option<ConnectionNetEvent> = Some(ConnectionNetEvent::CONNECTED(addr));
250        let none_event: Option<ConnectionNetEvent> = None;
251
252        assert!(some_event.is_some());
253        assert!(none_event.is_none());
254
255        if let Some(ConnectionNetEvent::CONNECTED(a)) = some_event {
256            assert_eq!(a, addr);
257        } else {
258            panic!("Expected Some(CONNECTED)");
259        }
260    }
261
262    #[test]
263    fn test_event_in_result() {
264        let addr = create_socket_addr("172.16.1.1", 6666);
265        let ok_event: Result<ConnectionNetEvent, &str> = Ok(ConnectionNetEvent::CONNECTED(addr));
266        let err_event: Result<ConnectionNetEvent, &str> = Err("connection failed");
267
268        assert!(ok_event.is_ok());
269        assert!(err_event.is_err());
270
271        match ok_event {
272            Ok(ConnectionNetEvent::CONNECTED(a)) => assert_eq!(a, addr),
273            _ => panic!("Expected Ok(CONNECTED)"),
274        }
275    }
276
277    #[test]
278    fn test_multiple_connected_events_different_ports() {
279        let addr1 = create_socket_addr("192.168.1.100", 8000);
280        let addr2 = create_socket_addr("192.168.1.100", 8001);
281        let addr3 = create_socket_addr("192.168.1.100", 8002);
282
283        let event1 = ConnectionNetEvent::CONNECTED(addr1);
284        let event2 = ConnectionNetEvent::CONNECTED(addr2);
285        let event3 = ConnectionNetEvent::CONNECTED(addr3);
286
287        // All should be different
288        assert_ne!(event1, event2);
289        assert_ne!(event2, event3);
290        assert_ne!(event1, event3);
291
292        // Test ordering
293        assert!(event1 < event2);
294        assert!(event2 < event3);
295    }
296
297    #[test]
298    fn test_event_size() {
299        use std::mem::size_of;
300
301        // Verify the enum size is reasonable
302        let size = size_of::<ConnectionNetEvent>();
303
304        // SocketAddr is either SocketAddrV4 (16 bytes) or SocketAddrV6 (28 bytes)
305        // Plus enum discriminant (typically 1-8 bytes depending on alignment)
306        // The size should be reasonable (not too large)
307        assert!(size <= 32, "ConnectionNetEvent size is {} bytes", size);
308    }
309}