trema 0.3.16 → 0.3.17

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -0
  3. data/.rvmrc +52 -0
  4. data/.travis.yml +3 -0
  5. data/Gemfile +1 -1
  6. data/Rakefile +259 -1
  7. data/Rantfile +79 -216
  8. data/features/.nav +12 -0
  9. data/features/dsl/switch_port_specifier.feature +15 -0
  10. data/features/examples/switch-event/C-add_forward_entry.feature +130 -0
  11. data/features/examples/switch-event/C-delete_forward_entry.feature +97 -0
  12. data/features/examples/switch-event/C-dump_forward_entries.feature +80 -0
  13. data/features/examples/switch-event/C-set_forward_entries.feature +85 -0
  14. data/features/examples/switch-event/README.md +40 -0
  15. data/features/examples/switch-event/add_forward_entry.feature +142 -0
  16. data/features/examples/switch-event/delete_forward_entry.feature +142 -0
  17. data/features/examples/switch-event/dump_forward_entries.feature +91 -0
  18. data/features/examples/switch-event/set_forward_entries.feature +90 -0
  19. data/features/support/hooks.rb +1 -0
  20. data/ruby/rake/c/dependency.rb +42 -0
  21. data/ruby/rake/c/library-task.rb +142 -0
  22. data/ruby/rake/c/shared-library-task.rb +38 -0
  23. data/ruby/rake/c/static-library-task.rb +32 -0
  24. data/ruby/trema/path.rb +1 -0
  25. data/ruby/trema/switch-event.c +647 -0
  26. data/{src/switch_manager/management_interface.h → ruby/trema/switch-event.h} +7 -21
  27. data/ruby/trema/trema.c +2 -0
  28. data/ruby/trema/version.rb +1 -1
  29. data/spec/spec_helper.rb +26 -2
  30. data/src/examples/switch_event_config/.gitignore +7 -0
  31. data/src/examples/switch_event_config/add_forward_entry.c +227 -0
  32. data/src/examples/switch_event_config/delete_forward_entry.c +226 -0
  33. data/src/examples/switch_event_config/dump_forward_entries.c +190 -0
  34. data/src/examples/switch_event_config/set_forward_entries.c +210 -0
  35. data/src/lib/event_forward_interface.c +783 -0
  36. data/src/lib/event_forward_interface.h +138 -0
  37. data/src/lib/trema.h +1 -0
  38. data/src/lib/utility.c +13 -1
  39. data/src/lib/utility.h +3 -0
  40. data/src/switch_manager/event_forward_entry_manipulation.c +120 -0
  41. data/src/switch_manager/event_forward_entry_manipulation.h +31 -0
  42. data/src/switch_manager/secure_channel_listener.c +23 -3
  43. data/src/switch_manager/switch.c +99 -29
  44. data/src/switch_manager/switch_manager.c +176 -3
  45. data/src/switch_manager/switch_manager.h +4 -0
  46. data/src/switch_manager/switch_option.c +30 -0
  47. data/src/switch_manager/switch_option.h +41 -0
  48. data/trema.gemspec +2 -1
  49. data/unittests/lib/event_forward_interface_test.c +1646 -0
  50. data/unittests/lib/utility_test.c +23 -1
  51. metadata +48 -10
@@ -27,10 +27,13 @@
27
27
  #include <string.h>
28
28
  #include <sys/wait.h>
29
29
  #include <unistd.h>
30
+ #include <assert.h>
30
31
  #include "trema.h"
31
32
  #include "secure_channel_listener.h"
32
33
  #include "switch_manager.h"
33
34
  #include "dpid_table.h"
35
+ #include "switch_option.h"
36
+ #include "event_forward_entry_manipulation.h"
34
37
 
35
38
 
36
39
  #ifdef UNIT_TESTING
@@ -155,7 +158,7 @@ void
155
158
  usage() {
156
159
  printf(
157
160
  "OpenFlow Switch Manager.\n"
158
- "Usage: %s [OPTION]... [-- SWITCH_MANAGER_OPTION]...\n"
161
+ "Usage: %s [OPTION]... [-- SWITCH_DAEMON_OPTION]...\n"
159
162
  "\n"
160
163
  " -s, --switch=PATH the command path of switch\n"
161
164
  " -n, --name=SERVICE_NAME service name\n"
@@ -253,6 +256,10 @@ init_listener_info( struct listener_info *listener_info ) {
253
256
  listener_info->switch_daemon = xconcatenate_path( get_trema_home(), SWITCH_MANAGER_PATH );
254
257
  listener_info->listen_port = OFP_TCP_PORT;
255
258
  listener_info->listen_fd = -1;
259
+ create_list( &listener_info->vendor_service_name_list );
260
+ create_list( &listener_info->packetin_service_name_list );
261
+ create_list( &listener_info->portstatus_service_name_list );
262
+ create_list( &listener_info->state_service_name_list );
256
263
  }
257
264
 
258
265
 
@@ -269,6 +276,25 @@ finalize_listener_info( struct listener_info *listener_info ) {
269
276
  close( listener_info->listen_fd );
270
277
  listener_info->listen_fd = -1;
271
278
  }
279
+ for ( int i = 0; i < listener_info->switch_daemon_argc; ++i ) {
280
+ xfree( listener_info->switch_daemon_argv[ i ] );
281
+ listener_info->switch_daemon_argv[ i ] = NULL;
282
+ }
283
+ xfree( listener_info->switch_daemon_argv );
284
+ listener_info->switch_daemon_argv = NULL;
285
+
286
+ iterate_list( listener_info->vendor_service_name_list, xfree_data, NULL );
287
+ delete_list( listener_info->vendor_service_name_list );
288
+ listener_info->vendor_service_name_list = NULL;
289
+ iterate_list( listener_info->packetin_service_name_list, xfree_data, NULL );
290
+ delete_list( listener_info->packetin_service_name_list );
291
+ listener_info->packetin_service_name_list = NULL;
292
+ iterate_list( listener_info->portstatus_service_name_list, xfree_data, NULL );
293
+ delete_list( listener_info->portstatus_service_name_list );
294
+ listener_info->portstatus_service_name_list = NULL;
295
+ iterate_list( listener_info->state_service_name_list, xfree_data, NULL );
296
+ delete_list( listener_info->state_service_name_list );
297
+ listener_info->state_service_name_list = NULL;
272
298
  }
273
299
 
274
300
 
@@ -310,8 +336,48 @@ parse_argument( struct listener_info *listener_info, int argc, char *argv[] ) {
310
336
  }
311
337
  }
312
338
 
313
- listener_info->switch_daemon_argc = argc - optind;
314
- listener_info->switch_daemon_argv = &argv[ optind ];
339
+ debug( "Start parsing switch daemon arguments." );
340
+ // index of first switch daemon arguments in argv
341
+ const int switch_arg_begin = optind;
342
+
343
+ // reorder switch daemon arguments
344
+ while ( getopt_long( argc, argv, switch_short_options, switch_long_options, NULL ) != -1 );
345
+
346
+ // index of first packet_in::..., etc. in argv
347
+ const int switch_arg_option_begin = optind;
348
+
349
+ // deep copy switch daemon arguments excluding packet_in::..., etc.
350
+ listener_info->switch_daemon_argc = switch_arg_option_begin - switch_arg_begin;
351
+ listener_info->switch_daemon_argv = xcalloc( ( size_t ) listener_info->switch_daemon_argc + 1,
352
+ sizeof( char * ) );
353
+ for ( int i = 0; i < listener_info->switch_daemon_argc; ++i ) {
354
+ debug( "switch daemon option: %s\n", argv[switch_arg_begin + i] );
355
+ listener_info->switch_daemon_argv[ i ] = xstrdup( argv[ switch_arg_begin + i ] );
356
+ }
357
+
358
+ // set service lists for each event type
359
+ for ( int i = switch_arg_option_begin; i < argc; i++ ) {
360
+ if ( strncmp( argv[ i ], VENDOR_PREFIX, strlen( VENDOR_PREFIX ) ) == 0 ) {
361
+ char *service_name = xstrdup( argv[ i ] + strlen( VENDOR_PREFIX ) );
362
+ debug( "event: " VENDOR_PREFIX "%s", service_name );
363
+ insert_in_front( &listener_info->vendor_service_name_list, service_name );
364
+ }
365
+ else if ( strncmp( argv[ i ], PACKET_IN_PREFIX, strlen( PACKET_IN_PREFIX ) ) == 0 ) {
366
+ char *service_name = xstrdup( argv[ i ] + strlen( PACKET_IN_PREFIX ) );
367
+ debug( "event: " PACKET_IN_PREFIX "%s", service_name );
368
+ insert_in_front( &listener_info->packetin_service_name_list, service_name );
369
+ }
370
+ else if ( strncmp( argv[ i ], PORTSTATUS_PREFIX, strlen( PORTSTATUS_PREFIX ) ) == 0 ) {
371
+ char *service_name = xstrdup( argv[ i ] + strlen( PORTSTATUS_PREFIX ) );
372
+ debug( "event: " PORTSTATUS_PREFIX "%s", service_name );
373
+ insert_in_front( &listener_info->portstatus_service_name_list, service_name );
374
+ }
375
+ else if ( strncmp( argv[ i ], STATE_PREFIX, strlen( STATE_PREFIX ) ) == 0 ) {
376
+ char *service_name = xstrdup( argv[ i ] + strlen( STATE_PREFIX ) );
377
+ debug( "event: " STATE_PREFIX "%s", service_name );
378
+ insert_in_front( &listener_info->state_service_name_list, service_name );
379
+ }
380
+ }
315
381
 
316
382
  return true;
317
383
  }
@@ -359,6 +425,112 @@ recv_request( const messenger_context_handle *handle,
359
425
  }
360
426
 
361
427
 
428
+ static void
429
+ management_event_forward_entry_operation( const messenger_context_handle *handle, uint32_t command, event_forward_operation_request *req, size_t data_len ) {
430
+
431
+ debug( "management efi command:%#x, type:%#x, n_services:%d", command, req->type, req->n_services );
432
+
433
+ list_element **subject = NULL;
434
+ switch ( req->type ) {
435
+ case EVENT_FORWARD_TYPE_VENDOR:
436
+ info( "Managing vendor event." );
437
+ subject = &listener_info.vendor_service_name_list;
438
+ break;
439
+
440
+ case EVENT_FORWARD_TYPE_PACKET_IN:
441
+ info( "Managing packet_in event." );
442
+ subject = &listener_info.packetin_service_name_list;
443
+ break;
444
+
445
+ case EVENT_FORWARD_TYPE_PORT_STATUS:
446
+ info( "Managing port_status event." );
447
+ subject = &listener_info.portstatus_service_name_list;
448
+ break;
449
+
450
+ case EVENT_FORWARD_TYPE_STATE_NOTIFY:
451
+ info( "Managing state_notify event." );
452
+ subject = &listener_info.state_service_name_list;
453
+ break;
454
+
455
+ default:
456
+ error( "Invalid EVENT_FWD_TYPE ( %#x )", req->type );
457
+ event_forward_operation_reply res;
458
+ memset( &res, 0, sizeof( event_forward_operation_reply ) );
459
+ res.type = req->type;
460
+ res.result = EFI_OPERATION_FAILED;
461
+ management_application_reply *reply = create_management_application_reply( MANAGEMENT_REQUEST_FAILED, command, &res, sizeof( event_forward_operation_reply ) );
462
+ send_management_application_reply( handle, reply );
463
+ xfree( reply );
464
+ return;
465
+ }
466
+ assert( subject != NULL );
467
+
468
+ switch ( command ) {
469
+ case EVENT_FORWARD_ENTRY_ADD:
470
+ management_event_forward_entry_add( subject, req, data_len );
471
+ break;
472
+
473
+ case EVENT_FORWARD_ENTRY_DELETE:
474
+ management_event_forward_entry_delete( subject, req, data_len );
475
+ break;
476
+
477
+ case EVENT_FORWARD_ENTRY_DUMP:
478
+ info( "Dumping current event filter." );
479
+ // do nothing
480
+ break;
481
+
482
+ case EVENT_FORWARD_ENTRY_SET:
483
+ management_event_forward_entries_set( subject, req, data_len );
484
+ break;
485
+ }
486
+
487
+ buffer *buf = create_event_forward_operation_reply( req->type, EFI_OPERATION_SUCCEEDED, *subject );
488
+ management_application_reply *reply = create_management_application_reply( MANAGEMENT_REQUEST_SUCCEEDED, command, buf->data, buf->length );
489
+ free_buffer( buf );
490
+ send_management_application_reply( handle, reply );
491
+ xfree( reply );
492
+ }
493
+
494
+
495
+ static void
496
+ management_recv( const messenger_context_handle *handle, uint32_t command, void *data, size_t data_len, void *user_data ) {
497
+ UNUSED( user_data );
498
+
499
+ switch ( command ) {
500
+ case EVENT_FORWARD_ENTRY_ADD:
501
+ case EVENT_FORWARD_ENTRY_DELETE:
502
+ case EVENT_FORWARD_ENTRY_DUMP:
503
+ case EVENT_FORWARD_ENTRY_SET:
504
+ {
505
+ event_forward_operation_request *req = data;
506
+ req->n_services = ntohl( req->n_services );
507
+ management_event_forward_entry_operation( handle, command, req, data_len );
508
+ return;
509
+ }
510
+ break;
511
+
512
+ case EFI_GET_SWLIST:
513
+ {
514
+ buffer *buf = get_switches();
515
+ management_application_reply *reply = create_management_application_reply( MANAGEMENT_REQUEST_SUCCEEDED, command, buf->data, buf->length );
516
+ free_buffer( buf );
517
+ send_management_application_reply( handle, reply );
518
+ xfree( reply );
519
+ }
520
+ break;
521
+
522
+ default:
523
+ {
524
+ error( "Undefined management command ( %#x )", command );
525
+ management_application_reply *reply = create_management_application_reply( MANAGEMENT_REQUEST_FAILED, command, NULL, 0 );
526
+ send_management_application_reply( handle, reply );
527
+ xfree( reply );
528
+ return;
529
+ }
530
+ }
531
+ }
532
+
533
+
362
534
  static bool
363
535
  start_service_management( void ) {
364
536
  return add_message_requested_callback( get_trema_name(), recv_request );
@@ -406,6 +578,7 @@ main( int argc, char *argv[] ) {
406
578
  finalize_listener_info( &listener_info );
407
579
  exit( EXIT_FAILURE );
408
580
  }
581
+ set_management_application_request_handler( management_recv, NULL );
409
582
 
410
583
  init_dpid_table();
411
584
  start_service_management();
@@ -47,6 +47,10 @@ struct listener_info {
47
47
  char **switch_daemon_argv;
48
48
  uint16_t listen_port;
49
49
  int listen_fd;
50
+ list_element *vendor_service_name_list; // vendor manager service
51
+ list_element *packetin_service_name_list; // packetin manager service
52
+ list_element *portstatus_service_name_list; // portstatus manager service
53
+ list_element *state_service_name_list; // switch state manager service
50
54
  };
51
55
 
52
56
 
@@ -0,0 +1,30 @@
1
+ /*
2
+ * Copyright (C) 2013 NEC Corporation
3
+ *
4
+ * This program is free software; you can redistribute it and/or modify
5
+ * it under the terms of the GNU General Public License, version 2, as
6
+ * published by the Free Software Foundation.
7
+ *
8
+ * This program is distributed in the hope that it will be useful,
9
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ * GNU General Public License for more details.
12
+ *
13
+ * You should have received a copy of the GNU General Public License along
14
+ * with this program; if not, write to the Free Software Foundation, Inc.,
15
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16
+ */
17
+
18
+ #include "trema.h"
19
+ #include "switch_option.h"
20
+
21
+ struct option switch_long_options[] = {
22
+ { "socket", 1, NULL, 's' },
23
+ { "no-flow-cleanup", 0, NULL, NO_FLOW_CLEANUP_LONG_OPTION_VALUE },
24
+ { "no-cookie-translation", 0, NULL, NO_COOKIE_TRANSLATION_LONG_OPTION_VALUE },
25
+ { "no-packet_in", 0, NULL, NO_PACKET_IN_LONG_OPTION_VALUE },
26
+ { NULL, 0, NULL, 0 },
27
+ };
28
+
29
+ char switch_short_options[] = "s:";
30
+
@@ -0,0 +1,41 @@
1
+ /*
2
+ * Copyright (C) 2013 NEC Corporation
3
+ *
4
+ * This program is free software; you can redistribute it and/or modify
5
+ * it under the terms of the GNU General Public License, version 2, as
6
+ * published by the Free Software Foundation.
7
+ *
8
+ * This program is distributed in the hope that it will be useful,
9
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ * GNU General Public License for more details.
12
+ *
13
+ * You should have received a copy of the GNU General Public License along
14
+ * with this program; if not, write to the Free Software Foundation, Inc.,
15
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16
+ */
17
+
18
+ #ifndef SWITCH_OPTION_H_
19
+ #define SWITCH_OPTION_H_
20
+
21
+ #include <getopt.h>
22
+
23
+ enum switch_long_options_val {
24
+ NO_FLOW_CLEANUP_LONG_OPTION_VALUE = 1,
25
+ NO_COOKIE_TRANSLATION_LONG_OPTION_VALUE = 2,
26
+ NO_PACKET_IN_LONG_OPTION_VALUE = 3,
27
+ };
28
+
29
+
30
+ extern struct option switch_long_options[];
31
+
32
+
33
+ extern char switch_short_options[];
34
+
35
+
36
+ #define VENDOR_PREFIX "vendor::"
37
+ #define PACKET_IN_PREFIX "packet_in::"
38
+ #define PORTSTATUS_PREFIX "port_status::"
39
+ #define STATE_PREFIX "state_notify::"
40
+
41
+ #endif /* SWITCH_OPTION_H_ */
data/trema.gemspec CHANGED
@@ -27,7 +27,8 @@ Gem::Specification.new do | gem |
27
27
  gem.test_files = `git ls-files -- {spec,features}/*`.split( "\n" )
28
28
 
29
29
  gem.add_dependency "bundler"
30
- gem.add_dependency "gli", "~> 2.5.4"
30
+ gem.add_dependency "gli", "~> 2.5.5"
31
+ gem.add_dependency "popen4", "~> 0.1.2"
31
32
  gem.add_dependency "rake", "~> 10.0.3"
32
33
  gem.add_dependency "rdoc", "~> 4.0.0"
33
34
  end
@@ -0,0 +1,1646 @@
1
+ /*
2
+ * Copyright (C) 2013 NEC Corporation
3
+ *
4
+ * This program is free software; you can redistribute it and/or modify
5
+ * it under the terms of the GNU General Public License, version 2, as
6
+ * published by the Free Software Foundation.
7
+ *
8
+ * This program is distributed in the hope that it will be useful,
9
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ * GNU General Public License for more details.
12
+ *
13
+ * You should have received a copy of the GNU General Public License along
14
+ * with this program; if not, write to the Free Software Foundation, Inc.,
15
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16
+ */
17
+
18
+
19
+ #include <setjmp.h>
20
+ #include <stdarg.h>
21
+ #include <stdint.h>
22
+ #include <stdio.h>
23
+ #include <stdlib.h>
24
+ #include <string.h>
25
+ #include <unistd.h>
26
+ #include "event_forward_interface.h"
27
+ #include "trema.h"
28
+ #include "trema_private.h"
29
+ #include "trema_wrapper.h"
30
+ #include "cmockery_trema.h"
31
+
32
+
33
+ /********************************************************************************
34
+ * Fwd decl for internal functions.
35
+ ********************************************************************************/
36
+
37
+ struct event_forward_operation_to_all_request_param {
38
+ bool add;
39
+ enum efi_event_type type;
40
+ char *service_name;
41
+ event_forward_entry_to_all_callback callback;
42
+ void *user_data;
43
+ };
44
+
45
+ typedef struct all_sw_tx {
46
+ uint32_t txid;
47
+ hash_table *waiting_dpid;
48
+ enum efi_result tx_result;
49
+
50
+ void *user_data;
51
+ } all_sw_tx;
52
+
53
+ struct txinfo {
54
+ uint64_t dpid;
55
+ uint32_t txid;
56
+ };
57
+
58
+ extern const char *_get_efi_queue_name( void );
59
+ extern void _get_switch_list_after_swm_succ( event_forward_operation_result result, void *user_data );
60
+ extern void _dispatch_to_all_switch( uint64_t *dpids, size_t n_dpids, void *user_data );
61
+ extern void _switch_response_handler( event_forward_operation_result result, void *user_data );
62
+ extern void _cleanup_tx_table();
63
+ extern all_sw_tx *_insert_tx( size_t n_dpids, struct event_forward_operation_to_all_request_param *param );
64
+ extern void _switch_response_timeout( void *user_data );
65
+
66
+ /********************************************************************************
67
+ * Mock functions.
68
+ ********************************************************************************/
69
+
70
+ struct callback_info {
71
+ void *callback;
72
+ void *user_data;
73
+ };
74
+
75
+
76
+ static void ( *original_error )( const char *format, ... );
77
+ static void ( *original_warn )( const char *format, ... );
78
+ static void ( *original_debug )( const char *format, ... );
79
+ static bool ( *original_add_message_requested_callback )( const char *service_name, void ( *callback )( const messenger_context_handle *handle, uint16_t tag, void *data, size_t len ) );
80
+ static bool ( *original_add_message_replied_callback )( const char *service_name, void ( *callback )( uint16_t tag, void *data, size_t len, void *user_data ) );
81
+ static bool ( *original_delete_message_replied_callback )( const char *service_name, void ( *callback )( uint16_t tag, void *data, size_t len, void *user_data ) );
82
+ static bool ( *original_delete_message_requested_callback )( const char *service_name, void ( *callback )( const messenger_context_handle *handle, uint16_t tag, void *data, size_t len ) );
83
+ static const char *( *original_get_management_service_name )( const char *service_name );
84
+ static pid_t ( *original_getpid )( void );
85
+ static void ( *handle_efi_reply )( uint16_t tag, void *data, size_t length, void *user_data ) = NULL;
86
+ static bool ( *original_send_request_message )( const char *to_service_name, const char *from_service_name, const uint16_t tag, const void *data, size_t len, void *user_data );
87
+
88
+ static void
89
+ mock_error( const char *format, ... ) {
90
+ va_list args;
91
+ va_start( args, format );
92
+ char message[ 1000 ];
93
+ vsprintf( message, format, args );
94
+ va_end( args );
95
+
96
+ check_expected( message );
97
+ }
98
+
99
+
100
+ static void
101
+ mock_warn( const char *format, ... ) {
102
+ va_list args;
103
+ va_start( args, format );
104
+ char message[ 1000 ];
105
+ vsprintf( message, format, args );
106
+ va_end( args );
107
+
108
+ check_expected( message );
109
+ }
110
+
111
+
112
+ static void
113
+ mock_debug( const char *format, ... ) {
114
+ UNUSED( format );
115
+ }
116
+
117
+
118
+ static bool
119
+ mock_add_message_requested_callback( const char *service_name,
120
+ void ( *callback )( const messenger_context_handle *handle, uint16_t tag, void *data, size_t len ) ) {
121
+ UNUSED( callback );
122
+
123
+ check_expected( service_name );
124
+
125
+ return ( bool ) mock();
126
+ }
127
+
128
+
129
+ static bool
130
+ mock_add_message_replied_callback( const char *service_name,
131
+ void ( *callback )( uint16_t tag, void *data, size_t len, void *user_data ) ) {
132
+ check_expected( service_name );
133
+ assert_true( callback != NULL );
134
+ handle_efi_reply = callback;
135
+
136
+ return ( bool ) mock();
137
+ }
138
+
139
+
140
+ static bool
141
+ mock_delete_message_replied_callback( const char *service_name,
142
+ void ( *callback )( uint16_t tag, void *data, size_t len, void *user_data ) ) {
143
+ check_expected( service_name );
144
+ assert_true( callback != NULL );
145
+ handle_efi_reply = NULL;
146
+
147
+ return ( bool ) mock();
148
+ }
149
+
150
+
151
+ static bool
152
+ mock_delete_message_requested_callback( const char *service_name,
153
+ void ( *callback )( const messenger_context_handle *handle, uint16_t tag, void *data, size_t len ) ) {
154
+ UNUSED( callback );
155
+
156
+ check_expected( service_name );
157
+
158
+ return ( bool ) mock();
159
+ }
160
+
161
+
162
+ static const char *
163
+ mock_get_management_service_name( const char *service_name ) {
164
+ check_expected( service_name );
165
+
166
+ return ( const char * ) ( intptr_t ) mock();
167
+ }
168
+
169
+
170
+ static pid_t
171
+ mock_getpid( void ) {
172
+ return 1234;
173
+ }
174
+
175
+
176
+ static bool free_user_data_member = false;
177
+
178
+
179
+ static bool
180
+ mock_send_request_message( const char *to_service_name, const char *from_service_name,
181
+ const uint16_t tag, const void *data, size_t len, void *user_data ) {
182
+ uint32_t tag32 = tag;
183
+ struct callback_info *hd = user_data;
184
+
185
+ check_expected( to_service_name );
186
+ check_expected( from_service_name );
187
+ check_expected( tag32 );
188
+ check_expected( data );
189
+ check_expected( len );
190
+ check_expected( hd->callback );
191
+ check_expected( hd->user_data );
192
+
193
+ bool sent_ok = ( bool ) mock();
194
+ if ( sent_ok ) {
195
+ if ( free_user_data_member ) {
196
+ xfree( hd->user_data );
197
+ }
198
+ xfree( hd );
199
+ }
200
+ return sent_ok;
201
+ }
202
+
203
+
204
+ void mock_event_forward_entry_operation_callback( event_forward_operation_result result, void *user_data ) {
205
+ check_expected( result.result );
206
+ check_expected( result.n_services );
207
+ for ( unsigned i = 0; i < result.n_services; ++i ) {
208
+ const char *service = result.services[i];
209
+ check_expected( service );
210
+ }
211
+ check_expected( user_data );
212
+ }
213
+
214
+
215
+ void mock_switch_list_request_callback( uint64_t *dpids, size_t n_dpids, void *user_data ) {
216
+ check_expected( n_dpids );
217
+ check_expected( dpids );
218
+ check_expected( user_data );
219
+ }
220
+
221
+
222
+ void mock_event_forward_entry_to_all_callback( enum efi_result result, void *user_data ) {
223
+ check_expected( result );
224
+ check_expected( user_data );
225
+ }
226
+
227
+
228
+ /********************************************************************************
229
+ * Setup and teardown functions.
230
+ ********************************************************************************/
231
+
232
+ static void
233
+ setup() {
234
+ free_user_data_member = false;
235
+
236
+ original_error = error;
237
+ error = mock_error;
238
+ original_warn = warn;
239
+ warn = mock_warn;
240
+ original_debug = debug;
241
+ debug = mock_debug;
242
+ original_add_message_requested_callback= add_message_requested_callback;
243
+ add_message_requested_callback = mock_add_message_requested_callback;
244
+ original_delete_message_requested_callback= delete_message_requested_callback;
245
+ delete_message_requested_callback = mock_delete_message_requested_callback;
246
+ original_get_management_service_name = get_management_service_name;
247
+ get_management_service_name = mock_get_management_service_name;
248
+ original_getpid = trema_getpid;
249
+ trema_getpid = mock_getpid;
250
+ original_add_message_replied_callback = add_message_replied_callback;
251
+ add_message_replied_callback = mock_add_message_replied_callback;
252
+ original_delete_message_replied_callback = delete_message_replied_callback;
253
+ delete_message_replied_callback = mock_delete_message_replied_callback;
254
+ original_send_request_message = send_request_message;
255
+ send_request_message = mock_send_request_message;
256
+ }
257
+
258
+
259
+ static void
260
+ setup_init_efi() {
261
+ setup();
262
+
263
+ const char service_name[] = "tetris";
264
+ const char efi_queue_name[] = "tetris-efic-1234";
265
+ set_trema_name( service_name );
266
+
267
+ expect_string( mock_add_message_replied_callback, service_name, efi_queue_name );
268
+ will_return( mock_add_message_replied_callback, true );
269
+
270
+ assert_true( _get_efi_queue_name() == NULL );
271
+ assert_true( init_event_forward_interface() );
272
+ assert_false( _get_efi_queue_name() == NULL );
273
+ }
274
+
275
+ static void
276
+ teardown() {
277
+ bool *initialized = _get_management_interface_initialized();
278
+ *initialized = false;
279
+
280
+ error = original_error;
281
+ warn = original_warn;
282
+ debug = original_debug;
283
+ add_message_requested_callback= original_add_message_requested_callback;
284
+ delete_message_requested_callback= original_delete_message_requested_callback;
285
+ get_management_service_name = original_get_management_service_name;
286
+ trema_getpid = original_getpid;
287
+ add_message_replied_callback = original_add_message_replied_callback;
288
+ delete_message_replied_callback = original_delete_message_replied_callback;
289
+ send_request_message = original_send_request_message;
290
+ }
291
+
292
+
293
+ static void
294
+ teardown_finl_efi() {
295
+ const char efi_queue_name[] = "tetris-efic-1234";
296
+ expect_string( mock_delete_message_replied_callback, service_name, efi_queue_name );
297
+ will_return( mock_delete_message_replied_callback, true );
298
+
299
+ assert_true( finalize_event_forward_interface() );
300
+ assert_true( _get_efi_queue_name() == NULL );
301
+
302
+ _free_trema_name();
303
+ teardown();
304
+ }
305
+ /********************************************************************************
306
+ * init_event_forward_interface() tests.
307
+ ********************************************************************************/
308
+
309
+ static void
310
+ test_init_event_forward_interface_succeeds() {
311
+ const char service_name[] = "tetris";
312
+ const char efi_queue_name[] = "tetris-efic-1234";
313
+
314
+ set_trema_name( service_name );
315
+
316
+ expect_string( mock_add_message_replied_callback, service_name, efi_queue_name );
317
+ will_return( mock_add_message_replied_callback, true );
318
+
319
+ assert_true( _get_efi_queue_name() == NULL );
320
+ assert_true( init_event_forward_interface() );
321
+ assert_false( _get_efi_queue_name() == NULL );
322
+ assert_string_equal( _get_efi_queue_name(), efi_queue_name );
323
+
324
+ expect_string( mock_delete_message_replied_callback, service_name, efi_queue_name );
325
+ will_return( mock_delete_message_replied_callback, true );
326
+ assert_true( finalize_event_forward_interface() );
327
+
328
+ _free_trema_name();
329
+ }
330
+
331
+
332
+ static void
333
+ test_init_event_forward_interface_succeeds_even_with_long_name() {
334
+ const char service_name[] = "tetris1234567890123456";
335
+ const char efi_queue_name[] = "efic-1234";
336
+
337
+ set_trema_name( service_name );
338
+
339
+ expect_string( mock_add_message_replied_callback, service_name, efi_queue_name );
340
+ will_return( mock_add_message_replied_callback, true );
341
+
342
+ assert_true( _get_efi_queue_name() == NULL );
343
+ assert_true( init_event_forward_interface() );
344
+ assert_false( _get_efi_queue_name() == NULL );
345
+ assert_string_equal( _get_efi_queue_name(), efi_queue_name );
346
+
347
+ expect_string( mock_delete_message_replied_callback, service_name, efi_queue_name );
348
+ will_return( mock_delete_message_replied_callback, true );
349
+ assert_true( finalize_event_forward_interface() );
350
+
351
+ _free_trema_name();
352
+ }
353
+
354
+ static void
355
+ test_init_event_forward_interface_fails_if_already_initialized() {
356
+ const char service_name[] = "tetris";
357
+ const char efi_queue_name[] = "tetris-efic-1234";
358
+
359
+ set_trema_name( service_name );
360
+
361
+ expect_string( mock_add_message_replied_callback, service_name, efi_queue_name );
362
+ will_return( mock_add_message_replied_callback, true );
363
+
364
+ init_event_forward_interface();
365
+ assert_false( _get_efi_queue_name() == NULL );
366
+ assert_string_equal( _get_efi_queue_name(), efi_queue_name );
367
+
368
+ expect_string( mock_warn, message, "already initialized." );
369
+
370
+ assert_false( init_event_forward_interface() );
371
+
372
+ assert_false( _get_efi_queue_name() == NULL );
373
+ assert_string_equal( _get_efi_queue_name(), efi_queue_name );
374
+
375
+ expect_string( mock_delete_message_replied_callback, service_name, efi_queue_name );
376
+ will_return( mock_delete_message_replied_callback, true );
377
+
378
+ assert_true( finalize_event_forward_interface() );
379
+ _free_trema_name();
380
+ }
381
+
382
+
383
+ /********************************************************************************
384
+ * finalize_event_forward_interface() tests.
385
+ ********************************************************************************/
386
+
387
+ static void
388
+ test_finalize_event_forward_interface_succeeds() {
389
+ const char service_name[] = "tetris";
390
+ const char efi_queue_name[] = "tetris-efic-1234";
391
+
392
+ set_trema_name( service_name );
393
+
394
+ expect_string( mock_add_message_replied_callback, service_name, efi_queue_name );
395
+ will_return( mock_add_message_replied_callback, true );
396
+ assert_true( init_event_forward_interface() );
397
+
398
+
399
+ expect_string( mock_delete_message_replied_callback, service_name, efi_queue_name );
400
+ will_return( mock_delete_message_replied_callback, true );
401
+
402
+ assert_true( finalize_event_forward_interface() );
403
+ assert_true( _get_efi_queue_name() == NULL );
404
+
405
+ _free_trema_name();
406
+ }
407
+
408
+
409
+ static void
410
+ test_finalize_event_forward_interface_fails_if_not_initialized() {
411
+ expect_string( mock_warn, message, "already finalized." );
412
+
413
+ assert_false( finalize_event_forward_interface() );
414
+ assert_true( _get_efi_queue_name() == NULL );
415
+ }
416
+
417
+
418
+ /********************************************************************************
419
+ * set_switch_manager_event_forward_entries() tests.
420
+ ********************************************************************************/
421
+
422
+ static void
423
+ test_set_switch_manager_event_forward_entries_succeeds() {
424
+ list_element *head;
425
+ char alpha[] = "alpha-12345678901234567890";
426
+ char bravo[] = "bravo-12345678901234567890";
427
+ create_list( &head );
428
+ append_to_tail( &head, alpha );
429
+ append_to_tail( &head, bravo );
430
+
431
+ event_forward_entry_operation_callback callback = ( event_forward_entry_operation_callback ) 0x12345678;
432
+ void *user_data = ( void * ) 0xABCDEF;
433
+
434
+ struct expected_data {
435
+ management_application_request mgmt;
436
+ event_forward_operation_request efi;
437
+ char alpha[ 6 + 21 ];
438
+ char bravo[ 6 + 21 ];
439
+ } __attribute__( ( packed ) ) expected_data = {
440
+ .mgmt = {
441
+ .header = {
442
+ .type = htons( MANAGEMENT_APPLICATION_REQUEST ),
443
+ .length = htonl( sizeof( struct expected_data ) ),
444
+ },
445
+ .application_id = htonl( EVENT_FORWARD_ENTRY_SET ),
446
+ },
447
+ .efi = {
448
+ .type = EVENT_FORWARD_TYPE_VENDOR,
449
+ .n_services = htonl( 2 ),
450
+ },
451
+ .alpha = "alpha-12345678901234567890",
452
+ .bravo = "bravo-12345678901234567890",
453
+ };
454
+
455
+ expect_string( mock_send_request_message, to_service_name, "switch_manager.m" );
456
+ expect_string( mock_send_request_message, from_service_name, "tetris-efic-1234" );
457
+ expect_value( mock_send_request_message, tag32, MESSENGER_MANAGEMENT_REQUEST );
458
+ expect_memory( mock_send_request_message, data, &expected_data, sizeof( struct expected_data ) );
459
+ expect_value( mock_send_request_message, len, sizeof( struct expected_data ) );
460
+ expect_value( mock_send_request_message, hd->callback, callback );
461
+ expect_value( mock_send_request_message, hd->user_data, user_data );
462
+ will_return( mock_send_request_message, true );
463
+
464
+ assert_true( set_switch_manager_event_forward_entries( EVENT_FORWARD_TYPE_VENDOR, head, callback, user_data ) );
465
+
466
+ delete_list( head );
467
+ }
468
+
469
+
470
+ /********************************************************************************
471
+ * add_switch_manager_event_forward_entry() tests.
472
+ ********************************************************************************/
473
+
474
+ static void
475
+ test_add_switch_manager_event_forward_entry_succeeds() {
476
+
477
+ event_forward_entry_operation_callback callback = ( event_forward_entry_operation_callback ) 0x12345678;
478
+ void *user_data = ( void * ) 0xABCDEF;
479
+
480
+ struct expected_data {
481
+ management_application_request mgmt;
482
+ event_forward_operation_request efi;
483
+ char alpha[ 6 ];
484
+ } __attribute__( ( packed ) ) expected_data = {
485
+ .mgmt = {
486
+ .header = {
487
+ .type = htons( MANAGEMENT_APPLICATION_REQUEST ),
488
+ .length = htonl( sizeof( struct expected_data ) ),
489
+ },
490
+ .application_id = htonl( EVENT_FORWARD_ENTRY_ADD ),
491
+ },
492
+ .efi = {
493
+ .type = EVENT_FORWARD_TYPE_PACKET_IN,
494
+ .n_services = htonl( 1 ),
495
+ },
496
+ .alpha = "alpha",
497
+ };
498
+
499
+ expect_string( mock_send_request_message, to_service_name, "switch_manager.m" );
500
+ expect_string( mock_send_request_message, from_service_name, "tetris-efic-1234" );
501
+ expect_value( mock_send_request_message, tag32, MESSENGER_MANAGEMENT_REQUEST );
502
+ expect_memory( mock_send_request_message, data, &expected_data, sizeof( struct expected_data ) );
503
+ expect_value( mock_send_request_message, len, sizeof( struct expected_data ) );
504
+ expect_value( mock_send_request_message, hd->callback, callback );
505
+ expect_value( mock_send_request_message, hd->user_data, user_data );
506
+ will_return( mock_send_request_message, true );
507
+
508
+ assert_true( add_switch_manager_event_forward_entry( EVENT_FORWARD_TYPE_PACKET_IN, "alpha", callback, user_data ) );
509
+ }
510
+
511
+
512
+ /********************************************************************************
513
+ * delete_switch_manager_event_forward_entry() tests.
514
+ ********************************************************************************/
515
+
516
+ static void
517
+ test_delete_switch_manager_event_forward_entry_succeeds() {
518
+
519
+ event_forward_entry_operation_callback callback = ( event_forward_entry_operation_callback ) 0x12345678;
520
+ void *user_data = ( void * ) 0xABCDEF;
521
+
522
+ struct expected_data {
523
+ management_application_request mgmt;
524
+ event_forward_operation_request efi;
525
+ char alpha[ 6 ];
526
+ } __attribute__( ( packed ) ) expected_data = {
527
+ .mgmt = {
528
+ .header = {
529
+ .type = htons( MANAGEMENT_APPLICATION_REQUEST ),
530
+ .length = htonl( sizeof( struct expected_data ) ),
531
+ },
532
+ .application_id = htonl( EVENT_FORWARD_ENTRY_DELETE ),
533
+ },
534
+ .efi = {
535
+ .type = EVENT_FORWARD_TYPE_PORT_STATUS,
536
+ .n_services = htonl( 1 ),
537
+ },
538
+ .alpha = "alpha",
539
+ };
540
+
541
+ expect_string( mock_send_request_message, to_service_name, "switch_manager.m" );
542
+ expect_string( mock_send_request_message, from_service_name, "tetris-efic-1234" );
543
+ expect_value( mock_send_request_message, tag32, MESSENGER_MANAGEMENT_REQUEST );
544
+ expect_memory( mock_send_request_message, data, &expected_data, sizeof( struct expected_data ) );
545
+ expect_value( mock_send_request_message, len, sizeof( struct expected_data ) );
546
+ expect_value( mock_send_request_message, hd->callback, callback );
547
+ expect_value( mock_send_request_message, hd->user_data, user_data );
548
+ will_return( mock_send_request_message, true );
549
+
550
+ assert_true( delete_switch_manager_event_forward_entry( EVENT_FORWARD_TYPE_PORT_STATUS, "alpha", callback, user_data ) );
551
+ }
552
+
553
+
554
+ /********************************************************************************
555
+ * dump_switch_manager_event_forward_entries() tests.
556
+ ********************************************************************************/
557
+
558
+ static void
559
+ test_dump_switch_manager_event_forward_entries_succeeds() {
560
+
561
+ event_forward_entry_operation_callback callback = ( event_forward_entry_operation_callback ) 0x12345678;
562
+ void *user_data = ( void * ) 0xABCDEF;
563
+
564
+ struct expected_data {
565
+ management_application_request mgmt;
566
+ event_forward_operation_request efi;
567
+ } __attribute__( ( packed ) ) expected_data = {
568
+ .mgmt = {
569
+ .header = {
570
+ .type = htons( MANAGEMENT_APPLICATION_REQUEST ),
571
+ .length = htonl( sizeof( struct expected_data ) ),
572
+ },
573
+ .application_id = htonl( EVENT_FORWARD_ENTRY_DUMP ),
574
+ },
575
+ .efi = {
576
+ .type = EVENT_FORWARD_TYPE_STATE_NOTIFY,
577
+ .n_services = htonl( 0 ),
578
+ },
579
+ };
580
+
581
+ expect_string( mock_send_request_message, to_service_name, "switch_manager.m" );
582
+ expect_string( mock_send_request_message, from_service_name, "tetris-efic-1234" );
583
+ expect_value( mock_send_request_message, tag32, MESSENGER_MANAGEMENT_REQUEST );
584
+ expect_memory( mock_send_request_message, data, &expected_data, sizeof( struct expected_data ) );
585
+ expect_value( mock_send_request_message, len, sizeof( struct expected_data ) );
586
+ expect_value( mock_send_request_message, hd->callback, callback );
587
+ expect_value( mock_send_request_message, hd->user_data, user_data );
588
+ will_return( mock_send_request_message, true );
589
+
590
+ assert_true( dump_switch_manager_event_forward_entries( EVENT_FORWARD_TYPE_STATE_NOTIFY, callback, user_data ) );
591
+ }
592
+
593
+
594
+ /********************************************************************************
595
+ * set_switch_event_forward_entries() tests.
596
+ ********************************************************************************/
597
+
598
+ static void
599
+ test_set_switch_event_forward_entries_succeeds() {
600
+ list_element *head;
601
+ char alpha[] = "alpha";
602
+ char bravo[] = "bravo";
603
+ create_list( &head );
604
+ append_to_tail( &head, alpha );
605
+ append_to_tail( &head, bravo );
606
+
607
+ event_forward_entry_operation_callback callback = ( event_forward_entry_operation_callback ) 0x12345678;
608
+ void *user_data = ( void * ) 0xABCDEF;
609
+
610
+ struct expected_data {
611
+ management_application_request mgmt;
612
+ event_forward_operation_request efi;
613
+ char alpha[ 6 ];
614
+ char bravo[ 6 ];
615
+ } __attribute__( ( packed ) ) expected_data = {
616
+ .mgmt = {
617
+ .header = {
618
+ .type = htons( MANAGEMENT_APPLICATION_REQUEST ),
619
+ .length = htonl( sizeof( struct expected_data ) ),
620
+ },
621
+ .application_id = htonl( EVENT_FORWARD_ENTRY_SET ),
622
+ },
623
+ .efi = {
624
+ .type = EVENT_FORWARD_TYPE_VENDOR,
625
+ .n_services = htonl( 2 ),
626
+ },
627
+ .alpha = "alpha",
628
+ .bravo = "bravo",
629
+ };
630
+
631
+ expect_string( mock_send_request_message, to_service_name, "switch.0xabc.m" );
632
+ expect_string( mock_send_request_message, from_service_name, "tetris-efic-1234" );
633
+ expect_value( mock_send_request_message, tag32, MESSENGER_MANAGEMENT_REQUEST );
634
+ expect_memory( mock_send_request_message, data, &expected_data, sizeof( struct expected_data ) );
635
+ expect_value( mock_send_request_message, len, sizeof( struct expected_data ) );
636
+ expect_value( mock_send_request_message, hd->callback, callback );
637
+ expect_value( mock_send_request_message, hd->user_data, user_data );
638
+ will_return( mock_send_request_message, true );
639
+
640
+ assert_true( set_switch_event_forward_entries( 0xabc, EVENT_FORWARD_TYPE_VENDOR, head, callback, user_data ) );
641
+
642
+ delete_list( head );
643
+ }
644
+
645
+
646
+ /********************************************************************************
647
+ * add_switch_event_forward_entry() tests.
648
+ ********************************************************************************/
649
+
650
+ static void
651
+ test_add_switch_event_forward_entry_succeeds() {
652
+
653
+ event_forward_entry_operation_callback callback = ( event_forward_entry_operation_callback ) 0x12345678;
654
+ void *user_data = ( void * ) 0xABCDEF;
655
+
656
+ struct expected_data {
657
+ management_application_request mgmt;
658
+ event_forward_operation_request efi;
659
+ char alpha[ 6 ];
660
+ } __attribute__( ( packed ) ) expected_data = {
661
+ .mgmt = {
662
+ .header = {
663
+ .type = htons( MANAGEMENT_APPLICATION_REQUEST ),
664
+ .length = htonl( sizeof( struct expected_data ) ),
665
+ },
666
+ .application_id = htonl( EVENT_FORWARD_ENTRY_ADD ),
667
+ },
668
+ .efi = {
669
+ .type = EVENT_FORWARD_TYPE_PACKET_IN,
670
+ .n_services = htonl( 1 ),
671
+ },
672
+ .alpha = "alpha",
673
+ };
674
+
675
+ expect_string( mock_send_request_message, to_service_name, "switch.0xabc.m" );
676
+ expect_string( mock_send_request_message, from_service_name, "tetris-efic-1234" );
677
+ expect_value( mock_send_request_message, tag32, MESSENGER_MANAGEMENT_REQUEST );
678
+ expect_memory( mock_send_request_message, data, &expected_data, sizeof( struct expected_data ) );
679
+ expect_value( mock_send_request_message, len, sizeof( struct expected_data ) );
680
+ expect_value( mock_send_request_message, hd->callback, callback );
681
+ expect_value( mock_send_request_message, hd->user_data, user_data );
682
+ will_return( mock_send_request_message, true );
683
+
684
+ assert_true( add_switch_event_forward_entry( 0xabc, EVENT_FORWARD_TYPE_PACKET_IN, "alpha", callback, user_data ) );
685
+ }
686
+
687
+
688
+ /********************************************************************************
689
+ * delete_switch_event_forward_entry() tests.
690
+ ********************************************************************************/
691
+
692
+ static void
693
+ test_delete_switch_event_forward_entry_succeeds() {
694
+
695
+ event_forward_entry_operation_callback callback = ( event_forward_entry_operation_callback ) 0x12345678;
696
+ void *user_data = ( void * ) 0xABCDEF;
697
+
698
+ struct expected_data {
699
+ management_application_request mgmt;
700
+ event_forward_operation_request efi;
701
+ char alpha[ 6 ];
702
+ } __attribute__( ( packed ) ) expected_data = {
703
+ .mgmt = {
704
+ .header = {
705
+ .type = htons( MANAGEMENT_APPLICATION_REQUEST ),
706
+ .length = htonl( sizeof( struct expected_data ) ),
707
+ },
708
+ .application_id = htonl( EVENT_FORWARD_ENTRY_DELETE ),
709
+ },
710
+ .efi = {
711
+ .type = EVENT_FORWARD_TYPE_PORT_STATUS,
712
+ .n_services = htonl( 1 ),
713
+ },
714
+ .alpha = "alpha",
715
+ };
716
+
717
+ expect_string( mock_send_request_message, to_service_name, "switch.0xabc.m" );
718
+ expect_string( mock_send_request_message, from_service_name, "tetris-efic-1234" );
719
+ expect_value( mock_send_request_message, tag32, MESSENGER_MANAGEMENT_REQUEST );
720
+ expect_memory( mock_send_request_message, data, &expected_data, sizeof( struct expected_data ) );
721
+ expect_value( mock_send_request_message, len, sizeof( struct expected_data ) );
722
+ expect_value( mock_send_request_message, hd->callback, callback );
723
+ expect_value( mock_send_request_message, hd->user_data, user_data );
724
+ will_return( mock_send_request_message, true );
725
+
726
+ assert_true( delete_switch_event_forward_entry( 0xabc, EVENT_FORWARD_TYPE_PORT_STATUS, "alpha", callback, user_data ) );
727
+ }
728
+
729
+
730
+ /********************************************************************************
731
+ * dump_switch_event_forward_entries() tests.
732
+ ********************************************************************************/
733
+
734
+ static void
735
+ test_dump_switch_event_forward_entries_succeeds() {
736
+
737
+ event_forward_entry_operation_callback callback = ( event_forward_entry_operation_callback ) 0x12345678;
738
+ void *user_data = ( void * ) 0xABCDEF;
739
+
740
+ struct expected_data {
741
+ management_application_request mgmt;
742
+ event_forward_operation_request efi;
743
+ } __attribute__( ( packed ) ) expected_data = {
744
+ .mgmt = {
745
+ .header = {
746
+ .type = htons( MANAGEMENT_APPLICATION_REQUEST ),
747
+ .length = htonl( sizeof( struct expected_data ) ),
748
+ },
749
+ .application_id = htonl( EVENT_FORWARD_ENTRY_DUMP ),
750
+ },
751
+ .efi = {
752
+ .type = EVENT_FORWARD_TYPE_STATE_NOTIFY,
753
+ .n_services = htonl( 0 ),
754
+ },
755
+ };
756
+
757
+ expect_string( mock_send_request_message, to_service_name, "switch.0xabc.m" );
758
+ expect_string( mock_send_request_message, from_service_name, "tetris-efic-1234" );
759
+ expect_value( mock_send_request_message, tag32, MESSENGER_MANAGEMENT_REQUEST );
760
+ expect_memory( mock_send_request_message, data, &expected_data, sizeof( struct expected_data ) );
761
+ expect_value( mock_send_request_message, len, sizeof( struct expected_data ) );
762
+ expect_value( mock_send_request_message, hd->callback, callback );
763
+ expect_value( mock_send_request_message, hd->user_data, user_data );
764
+ will_return( mock_send_request_message, true );
765
+
766
+ assert_true( dump_switch_event_forward_entries( 0xabc, EVENT_FORWARD_TYPE_STATE_NOTIFY, callback, user_data ) );
767
+ }
768
+
769
+
770
+ /********************************************************************************
771
+ * handle_efi_reply() tests.
772
+ ********************************************************************************/
773
+
774
+ static void
775
+ test_handle_efi_reply_succeeds_with_success_reply() {
776
+
777
+ struct input_data {
778
+ management_application_reply mgmt;
779
+ event_forward_operation_reply efi;
780
+ char alpha[ 6 ];
781
+ char bravo[ 6 ];
782
+ } __attribute__( ( packed ) ) input_data = {
783
+ .mgmt = {
784
+ .header = {
785
+ .type = htons( MANAGEMENT_APPLICATION_REPLY ),
786
+ .status = MANAGEMENT_REQUEST_SUCCEEDED,
787
+ .length = htonl( sizeof( struct input_data ) ),
788
+ },
789
+ .application_id = htonl( EVENT_FORWARD_ENTRY_SET ),
790
+ },
791
+ .efi = {
792
+ .type = EVENT_FORWARD_TYPE_VENDOR,
793
+ .result = EFI_OPERATION_SUCCEEDED,
794
+ .n_services = htonl( 2 ),
795
+ },
796
+ .alpha = "alpha",
797
+ .bravo = "bravo"
798
+ };
799
+
800
+ struct callback_info *user_data = xcalloc( 1, sizeof( struct callback_info ) );
801
+ user_data->callback = mock_event_forward_entry_operation_callback;
802
+ user_data->user_data = ( void * ) 0x12345678;
803
+
804
+ expect_value( mock_event_forward_entry_operation_callback, result.result, EFI_OPERATION_SUCCEEDED );
805
+ expect_value( mock_event_forward_entry_operation_callback, result.n_services, 2 );
806
+ expect_string( mock_event_forward_entry_operation_callback, service, "alpha" );
807
+ expect_string( mock_event_forward_entry_operation_callback, service, "bravo" );
808
+ expect_value( mock_event_forward_entry_operation_callback, user_data, 0x12345678 );
809
+
810
+ handle_efi_reply( MESSENGER_MANAGEMENT_REPLY, &input_data, sizeof( struct input_data ), user_data );
811
+ }
812
+
813
+
814
+ static void
815
+ test_handle_efi_reply_succeeds_with_event_forward_entry_operation_failure_reply() {
816
+
817
+ struct input_data {
818
+ management_application_reply mgmt;
819
+ event_forward_operation_reply efi;
820
+ } __attribute__( ( packed ) ) input_data = {
821
+ .mgmt = {
822
+ .header = {
823
+ .type = htons( MANAGEMENT_APPLICATION_REPLY ),
824
+ .status = MANAGEMENT_REQUEST_SUCCEEDED,
825
+ .length = htonl( sizeof( struct input_data ) ),
826
+ },
827
+ .application_id = htonl( EVENT_FORWARD_ENTRY_SET ),
828
+ },
829
+ .efi = {
830
+ .type = EVENT_FORWARD_TYPE_VENDOR,
831
+ .result = EFI_OPERATION_FAILED,
832
+ .n_services = htonl( 0 ),
833
+ },
834
+ };
835
+
836
+ struct callback_info *user_data = xcalloc( 1, sizeof( struct callback_info ) );
837
+ user_data->callback = mock_event_forward_entry_operation_callback;
838
+ user_data->user_data = ( void * ) 0x12345678;
839
+
840
+ expect_value( mock_event_forward_entry_operation_callback, result.result, EFI_OPERATION_FAILED );
841
+ expect_value( mock_event_forward_entry_operation_callback, result.n_services, 0 );
842
+ expect_value( mock_event_forward_entry_operation_callback, user_data, 0x12345678 );
843
+
844
+ handle_efi_reply( MESSENGER_MANAGEMENT_REPLY, &input_data, sizeof( struct input_data ), user_data );
845
+ }
846
+
847
+
848
+ static void
849
+ test_handle_efi_reply_succeeds_with_management_failure_reply() {
850
+
851
+ struct input_data {
852
+ management_application_reply mgmt;
853
+ event_forward_operation_reply efi;
854
+ } __attribute__( ( packed ) ) input_data = {
855
+ .mgmt = {
856
+ .header = {
857
+ .type = htons( MANAGEMENT_APPLICATION_REPLY ),
858
+ .status = MANAGEMENT_REQUEST_FAILED,
859
+ .length = htonl( sizeof( struct input_data ) ),
860
+ },
861
+ .application_id = htonl( EVENT_FORWARD_ENTRY_SET ),
862
+ },
863
+ .efi = {
864
+ .type = EVENT_FORWARD_TYPE_VENDOR,
865
+ .result = EFI_OPERATION_FAILED,
866
+ .n_services = htonl( 0 ),
867
+ },
868
+ };
869
+
870
+ struct callback_info *user_data = xcalloc( 1, sizeof( struct callback_info ) );
871
+ user_data->callback = mock_event_forward_entry_operation_callback;
872
+ user_data->user_data = ( void * ) 0x12345678;
873
+
874
+ expect_string( mock_warn, message, "Management request failed." );
875
+
876
+ expect_value( mock_event_forward_entry_operation_callback, result.result, EFI_OPERATION_FAILED );
877
+ expect_value( mock_event_forward_entry_operation_callback, result.n_services, 0 );
878
+ expect_value( mock_event_forward_entry_operation_callback, user_data, 0x12345678 );
879
+
880
+ handle_efi_reply( MESSENGER_MANAGEMENT_REPLY, &input_data, sizeof( struct input_data ), user_data );
881
+ }
882
+
883
+
884
+ static void
885
+ test_handle_efi_reply_ignores_wrong_message_tag_reply() {
886
+
887
+ struct input_data {
888
+ management_application_reply mgmt;
889
+ } __attribute__( ( packed ) ) input_data = {
890
+ .mgmt = {
891
+ .header = {
892
+ .type = htons( MANAGEMENT_APPLICATION_REPLY ),
893
+ .status = MANAGEMENT_REQUEST_FAILED,
894
+ .length = htonl( sizeof( struct input_data ) ),
895
+ },
896
+ .application_id = htonl( EVENT_FORWARD_ENTRY_SET ),
897
+ },
898
+ };
899
+
900
+ struct callback_info *user_data = xcalloc( 1, sizeof( struct callback_info ) );
901
+ user_data->callback = mock_event_forward_entry_operation_callback;
902
+ user_data->user_data = ( void * ) 0x12345678;
903
+
904
+ expect_string( mock_error, message, "Unexpected message received tag=0x1234" );
905
+
906
+ handle_efi_reply( 0x1234, &input_data, sizeof( struct input_data ), user_data );
907
+ xfree( user_data );
908
+ }
909
+
910
+
911
+ static void
912
+ test_handle_efi_reply_ignores_wrong_message_length_reply() {
913
+
914
+ struct input_data {
915
+ management_application_reply mgmt;
916
+ } __attribute__( ( packed ) ) input_data = {
917
+ .mgmt = {
918
+ .header = {
919
+ .type = htons( MANAGEMENT_APPLICATION_REPLY ),
920
+ .status = MANAGEMENT_REQUEST_FAILED,
921
+ .length = htonl( sizeof( struct input_data ) ),
922
+ },
923
+ .application_id = htonl( EVENT_FORWARD_ENTRY_SET ),
924
+ },
925
+ };
926
+
927
+ struct callback_info *user_data = xcalloc( 1, sizeof( struct callback_info ) );
928
+ user_data->callback = mock_event_forward_entry_operation_callback;
929
+ user_data->user_data = ( void * ) 0x12345678;
930
+
931
+ expect_string( mock_error, message, "Data length too short 11. expecting >= 12" );
932
+
933
+ handle_efi_reply( MESSENGER_MANAGEMENT_REPLY, &input_data, sizeof( struct input_data )-1, user_data );
934
+ xfree( user_data );
935
+ }
936
+
937
+
938
+ static void
939
+ test_handle_efi_reply_ignores_empty_reply() {
940
+
941
+ struct callback_info *user_data = xcalloc( 1, sizeof( struct callback_info ) );
942
+ user_data->callback = mock_event_forward_entry_operation_callback;
943
+ user_data->user_data = ( void * ) 0x12345678;
944
+
945
+ expect_any( mock_error, message );
946
+
947
+ handle_efi_reply( MESSENGER_MANAGEMENT_REPLY, NULL, 0, user_data );
948
+ xfree( user_data );
949
+ }
950
+
951
+
952
+ static void
953
+ test_handle_efi_reply_ignores_wrong_event_forward_operation_command_reply() {
954
+
955
+ struct input_data {
956
+ management_application_reply mgmt;
957
+ event_forward_operation_reply efi;
958
+ } __attribute__( ( packed ) ) input_data = {
959
+ .mgmt = {
960
+ .header = {
961
+ .type = htons( MANAGEMENT_APPLICATION_REPLY ),
962
+ .status = MANAGEMENT_REQUEST_SUCCEEDED,
963
+ .length = htonl( sizeof( struct input_data ) ),
964
+ },
965
+ .application_id = htonl( 0x1234 ),
966
+ },
967
+ .efi = {
968
+ .type = EVENT_FORWARD_TYPE_VENDOR,
969
+ .result = EFI_OPERATION_FAILED,
970
+ .n_services = htonl( 0 ),
971
+ },
972
+ };
973
+
974
+ struct callback_info *user_data = xcalloc( 1, sizeof( struct callback_info ) );
975
+ user_data->callback = mock_event_forward_entry_operation_callback;
976
+ user_data->user_data = ( void * ) 0x12345678;
977
+
978
+ expect_string( mock_warn, message, "Invalid command/application_id: 0x1234" );
979
+
980
+ handle_efi_reply( MESSENGER_MANAGEMENT_REPLY, &input_data, sizeof( struct input_data ), user_data );
981
+ xfree( user_data );
982
+ }
983
+
984
+
985
+ static void
986
+ test_handle_efi_reply_succeeds_with_wrong_event_forward_operation_result_reply() {
987
+
988
+ struct input_data {
989
+ management_application_reply mgmt;
990
+ event_forward_operation_reply efi;
991
+ } __attribute__( ( packed ) ) input_data = {
992
+ .mgmt = {
993
+ .header = {
994
+ .type = htons( MANAGEMENT_APPLICATION_REPLY ),
995
+ .status = MANAGEMENT_REQUEST_SUCCEEDED,
996
+ .length = htonl( sizeof( struct input_data ) ),
997
+ },
998
+ .application_id = htonl( EVENT_FORWARD_ENTRY_ADD ),
999
+ },
1000
+ .efi = {
1001
+ .type = EVENT_FORWARD_TYPE_VENDOR,
1002
+ .result = 0xFF,
1003
+ .n_services = htonl( 0 ),
1004
+ },
1005
+ };
1006
+
1007
+ struct callback_info *user_data = xcalloc( 1, sizeof( struct callback_info ) );
1008
+ user_data->callback = mock_event_forward_entry_operation_callback;
1009
+ user_data->user_data = ( void * ) 0x12345678;
1010
+
1011
+ expect_string( mock_warn, message, "Unknown result type 0xff. Translating as FAILED." );
1012
+
1013
+ expect_value( mock_event_forward_entry_operation_callback, result.result, EFI_OPERATION_FAILED );
1014
+ expect_value( mock_event_forward_entry_operation_callback, result.n_services, 0 );
1015
+ expect_value( mock_event_forward_entry_operation_callback, user_data, 0x12345678 );
1016
+
1017
+ handle_efi_reply( MESSENGER_MANAGEMENT_REPLY, &input_data, sizeof( struct input_data ), user_data );
1018
+ }
1019
+
1020
+
1021
+ static void
1022
+ test_handle_efi_reply_succeeds_with_more_service_found_then_expected_reply() {
1023
+
1024
+ struct input_data {
1025
+ management_application_reply mgmt;
1026
+ event_forward_operation_reply efi;
1027
+ char alpha[ 6 ];
1028
+ char bravo[ 6 ];
1029
+ } __attribute__( ( packed ) ) input_data = {
1030
+ .mgmt = {
1031
+ .header = {
1032
+ .type = htons( MANAGEMENT_APPLICATION_REPLY ),
1033
+ .status = MANAGEMENT_REQUEST_SUCCEEDED,
1034
+ .length = htonl( sizeof( struct input_data ) ),
1035
+ },
1036
+ .application_id = htonl( EVENT_FORWARD_ENTRY_ADD ),
1037
+ },
1038
+ .efi = {
1039
+ .type = EVENT_FORWARD_TYPE_VENDOR,
1040
+ .result = EFI_OPERATION_SUCCEEDED,
1041
+ .n_services = htonl( 1 ),
1042
+ },
1043
+ .alpha = "alpha",
1044
+ .bravo = "bravo"
1045
+ };
1046
+
1047
+ struct callback_info *user_data = xcalloc( 1, sizeof( struct callback_info ) );
1048
+ user_data->callback = mock_event_forward_entry_operation_callback;
1049
+ user_data->user_data = ( void * ) 0x12345678;
1050
+
1051
+ expect_string( mock_warn, message, "Expected 1 name(s), but found more service name. Ignoring 'bravo'." );
1052
+
1053
+ expect_value( mock_event_forward_entry_operation_callback, result.result, EFI_OPERATION_SUCCEEDED );
1054
+ expect_value( mock_event_forward_entry_operation_callback, result.n_services, 1 );
1055
+ expect_string( mock_event_forward_entry_operation_callback, service, "alpha" );
1056
+ expect_value( mock_event_forward_entry_operation_callback, user_data, 0x12345678 );
1057
+
1058
+ handle_efi_reply( MESSENGER_MANAGEMENT_REPLY, &input_data, sizeof( struct input_data ), user_data );
1059
+ }
1060
+
1061
+
1062
+ static void
1063
+ test_handle_efi_reply_succeeds_with_empty_service_name_reply() {
1064
+
1065
+ struct input_data {
1066
+ management_application_reply mgmt;
1067
+ event_forward_operation_reply efi;
1068
+ char alpha[ 6 ];
1069
+ char bravo[ 1 ];
1070
+ } __attribute__( ( packed ) ) input_data = {
1071
+ .mgmt = {
1072
+ .header = {
1073
+ .type = htons( MANAGEMENT_APPLICATION_REPLY ),
1074
+ .status = MANAGEMENT_REQUEST_SUCCEEDED,
1075
+ .length = htonl( sizeof( struct input_data ) ),
1076
+ },
1077
+ .application_id = htonl( EVENT_FORWARD_ENTRY_ADD ),
1078
+ },
1079
+ .efi = {
1080
+ .type = EVENT_FORWARD_TYPE_VENDOR,
1081
+ .result = EFI_OPERATION_SUCCEEDED,
1082
+ .n_services = htonl( 2 ),
1083
+ },
1084
+ .alpha = "alpha",
1085
+ .bravo = ""
1086
+ };
1087
+
1088
+ struct callback_info *user_data = xcalloc( 1, sizeof( struct callback_info ) );
1089
+ user_data->callback = mock_event_forward_entry_operation_callback;
1090
+ user_data->user_data = ( void * ) 0x12345678;
1091
+
1092
+ expect_string( mock_warn, message, "Encountered empty service name." );
1093
+
1094
+ expect_value( mock_event_forward_entry_operation_callback, result.result, EFI_OPERATION_SUCCEEDED );
1095
+ expect_value( mock_event_forward_entry_operation_callback, result.n_services, 1 );
1096
+ expect_string( mock_event_forward_entry_operation_callback, service, "alpha" );
1097
+ expect_value( mock_event_forward_entry_operation_callback, user_data, 0x12345678 );
1098
+
1099
+ handle_efi_reply( MESSENGER_MANAGEMENT_REPLY, &input_data, sizeof( struct input_data ), user_data );
1100
+ }
1101
+
1102
+
1103
+ /********************************************************************************
1104
+ * create_event_forward_op_reply() tests.
1105
+ ********************************************************************************/
1106
+
1107
+ static void
1108
+ test_create_event_forward_operation_reply_with_null_service_list() {
1109
+ struct expected_data {
1110
+ event_forward_operation_reply efi;
1111
+ } __attribute__( ( packed ) ) expected_data = {
1112
+ .efi = {
1113
+ .type = EVENT_FORWARD_TYPE_PACKET_IN,
1114
+ .result = EFI_OPERATION_SUCCEEDED,
1115
+ .n_services = 0
1116
+ }
1117
+ };
1118
+ buffer *buf = create_event_forward_operation_reply( EVENT_FORWARD_TYPE_PACKET_IN, EFI_OPERATION_SUCCEEDED, NULL );
1119
+
1120
+ assert_memory_equal( buf->data, &expected_data, sizeof( struct expected_data ) );
1121
+ free_buffer( buf );
1122
+ }
1123
+
1124
+
1125
+ static void
1126
+ test_create_event_forward_operation_reply_with_empty_service_list() {
1127
+ struct expected_data {
1128
+ event_forward_operation_reply efi;
1129
+ } __attribute__( ( packed ) ) expected_data = {
1130
+ .efi = {
1131
+ .type = EVENT_FORWARD_TYPE_PACKET_IN,
1132
+ .result = EFI_OPERATION_SUCCEEDED,
1133
+ .n_services = 0
1134
+ }
1135
+ };
1136
+ list_element *head;
1137
+ create_list( &head );
1138
+ buffer *buf = create_event_forward_operation_reply( EVENT_FORWARD_TYPE_PACKET_IN, EFI_OPERATION_SUCCEEDED, head );
1139
+
1140
+ assert_memory_equal( buf->data, &expected_data, sizeof( struct expected_data ) );
1141
+ free_buffer( buf );
1142
+ delete_list( head );
1143
+ }
1144
+
1145
+
1146
+ static void
1147
+ test_create_event_forward_operation_reply_with_one_service_list() {
1148
+ char alpha[] = "alpha";
1149
+ struct expected_data {
1150
+ event_forward_operation_reply efi;
1151
+ const char service[ 6 ];
1152
+ } __attribute__( ( packed ) ) expected_data = {
1153
+ .efi = {
1154
+ .type = EVENT_FORWARD_TYPE_PACKET_IN,
1155
+ .result = EFI_OPERATION_SUCCEEDED,
1156
+ .n_services = htonl( 1 )
1157
+ },
1158
+ .service = "alpha"
1159
+ };
1160
+ list_element *head;
1161
+ create_list( &head );
1162
+ append_to_tail( &head, alpha );
1163
+ buffer *buf = create_event_forward_operation_reply( EVENT_FORWARD_TYPE_PACKET_IN, EFI_OPERATION_SUCCEEDED, head );
1164
+
1165
+ assert_memory_equal( buf->data, &expected_data, sizeof( struct expected_data ) );
1166
+ free_buffer( buf );
1167
+ delete_list( head );
1168
+ }
1169
+
1170
+
1171
+ static void
1172
+ test_create_event_forward_operation_reply_with_multi_service_list() {
1173
+ char alpha[] = "alpha-12345678901234567890";
1174
+ char bravo[] = "bravo-12345678901234567890";
1175
+ char charlie[] = "charlie-12345678901234567890";
1176
+ struct expected_data {
1177
+ event_forward_operation_reply efi;
1178
+ const char alpha[ 6 + 21 ];
1179
+ const char bravo[ 6 + 21 ];
1180
+ const char charlie[ 8 + 21 ];
1181
+ } __attribute__( ( packed ) ) expected_data = {
1182
+ .efi = {
1183
+ .type = EVENT_FORWARD_TYPE_PACKET_IN,
1184
+ .result = EFI_OPERATION_SUCCEEDED,
1185
+ .n_services = htonl( 3 )
1186
+ },
1187
+ .alpha = "alpha-12345678901234567890",
1188
+ .bravo = "bravo-12345678901234567890",
1189
+ .charlie = "charlie-12345678901234567890"
1190
+ };
1191
+ list_element *head;
1192
+ create_list( &head );
1193
+ append_to_tail( &head, alpha );
1194
+ append_to_tail( &head, bravo );
1195
+ append_to_tail( &head, charlie );
1196
+ buffer *buf = create_event_forward_operation_reply( EVENT_FORWARD_TYPE_PACKET_IN, EFI_OPERATION_SUCCEEDED, head );
1197
+
1198
+ assert_memory_equal( buf->data, &expected_data, sizeof( struct expected_data ) );
1199
+ free_buffer( buf );
1200
+ delete_list( head );
1201
+ }
1202
+
1203
+
1204
+ /********************************************************************************
1205
+ * send_efi_switch_list_request() tests.
1206
+ ********************************************************************************/
1207
+
1208
+ static void
1209
+ test_send_efi_switch_list_request_succeeds() {
1210
+
1211
+ switch_list_request_callback callback = ( switch_list_request_callback ) 0x12345678;
1212
+ void *user_data = ( void * ) 0xABCDEF;
1213
+
1214
+ struct expected_data {
1215
+ management_application_request mgmt;
1216
+ } __attribute__( ( packed ) ) expected_data = {
1217
+ .mgmt = {
1218
+ .header = {
1219
+ .type = htons( MANAGEMENT_APPLICATION_REQUEST ),
1220
+ .length = htonl( sizeof( struct expected_data ) ),
1221
+ },
1222
+ .application_id = htonl( EFI_GET_SWLIST ),
1223
+ },
1224
+ };
1225
+
1226
+ expect_string( mock_send_request_message, to_service_name, "switch_manager.m" );
1227
+ expect_string( mock_send_request_message, from_service_name, "tetris-efic-1234" );
1228
+ expect_value( mock_send_request_message, tag32, MESSENGER_MANAGEMENT_REQUEST );
1229
+ expect_memory( mock_send_request_message, data, &expected_data, sizeof( struct expected_data ) );
1230
+ expect_value( mock_send_request_message, len, sizeof( struct expected_data ) );
1231
+ expect_value( mock_send_request_message, hd->callback, callback );
1232
+ expect_value( mock_send_request_message, hd->user_data, user_data );
1233
+ will_return( mock_send_request_message, true );
1234
+
1235
+ assert_true( send_efi_switch_list_request( callback, user_data ) );
1236
+ }
1237
+
1238
+
1239
+ static void
1240
+ test_handle_efi_reply_succeeds_with_switch_list_reply() {
1241
+
1242
+ const uint64_t dpids_host[] = { 0x12345678, 0xabcdef00 };
1243
+ struct input_data {
1244
+ management_application_reply mgmt;
1245
+ uint64_t dpids[ 2 ];
1246
+ } __attribute__( ( packed ) ) input_data = {
1247
+ .mgmt = {
1248
+ .header = {
1249
+ .type = htons( MANAGEMENT_APPLICATION_REPLY ),
1250
+ .status = MANAGEMENT_REQUEST_SUCCEEDED,
1251
+ .length = htonl( sizeof( struct input_data ) ),
1252
+ },
1253
+ .application_id = htonl( EFI_GET_SWLIST ),
1254
+ },
1255
+ .dpids = {
1256
+ htonll( dpids_host[ 0 ] ),
1257
+ htonll( dpids_host[ 1 ] )
1258
+ }
1259
+ };
1260
+
1261
+ struct callback_info *user_data = xcalloc( 1, sizeof( struct callback_info ) );
1262
+ user_data->callback = mock_switch_list_request_callback;
1263
+ user_data->user_data = ( void * ) 0x12345678;
1264
+
1265
+ expect_value( mock_switch_list_request_callback, n_dpids, 2 );
1266
+ expect_memory( mock_switch_list_request_callback, dpids, dpids_host, 2 * sizeof( uint64_t ) );
1267
+ expect_value( mock_switch_list_request_callback, user_data, 0x12345678 );
1268
+
1269
+ handle_efi_reply( MESSENGER_MANAGEMENT_REPLY, &input_data, sizeof( struct input_data ), user_data );
1270
+ }
1271
+
1272
+
1273
+ static void
1274
+ test_handle_efi_reply_succeeds_with_management_failure_on_switch_list_reply() {
1275
+
1276
+ struct input_data {
1277
+ management_application_reply mgmt;
1278
+ } __attribute__( ( packed ) ) input_data = {
1279
+ .mgmt = {
1280
+ .header = {
1281
+ .type = htons( MANAGEMENT_APPLICATION_REPLY ),
1282
+ .status = MANAGEMENT_REQUEST_FAILED,
1283
+ .length = htonl( sizeof( struct input_data ) ),
1284
+ },
1285
+ .application_id = htonl( EFI_GET_SWLIST ),
1286
+ },
1287
+ };
1288
+
1289
+ struct callback_info *user_data = xcalloc( 1, sizeof( struct callback_info ) );
1290
+ user_data->callback = mock_switch_list_request_callback;
1291
+ user_data->user_data = ( void * ) 0x12345678;
1292
+
1293
+ expect_string( mock_warn, message, "Management request failed." );
1294
+
1295
+ expect_value( mock_switch_list_request_callback, n_dpids, 0 );
1296
+ expect_value( mock_switch_list_request_callback, dpids, NULL );
1297
+ expect_value( mock_switch_list_request_callback, user_data, 0x12345678 );
1298
+
1299
+ handle_efi_reply( MESSENGER_MANAGEMENT_REPLY, &input_data, sizeof( struct input_data ), user_data );
1300
+ }
1301
+
1302
+
1303
+ /********************************************************************************
1304
+ * add_event_forward_to_all_switches() tests.
1305
+ ********************************************************************************/
1306
+
1307
+
1308
+ static void
1309
+ test_add_event_forward_entry_to_all_switches_succeeds() {
1310
+
1311
+ event_forward_entry_to_all_callback callback = ( event_forward_entry_to_all_callback ) 0x12345678;
1312
+ void *user_data = ( void * ) 0xABCDEF;
1313
+
1314
+ struct expected_data {
1315
+ management_application_request mgmt;
1316
+ event_forward_operation_request efi;
1317
+ char alpha[ 6 ];
1318
+ } __attribute__( ( packed ) ) expected_data = {
1319
+ .mgmt = {
1320
+ .header = {
1321
+ .type = htons( MANAGEMENT_APPLICATION_REQUEST ),
1322
+ .length = htonl( sizeof( struct expected_data ) ),
1323
+ },
1324
+ .application_id = htonl( EVENT_FORWARD_ENTRY_ADD ),
1325
+ },
1326
+ .efi = {
1327
+ .type = EVENT_FORWARD_TYPE_PACKET_IN,
1328
+ .n_services = htonl( 1 ),
1329
+ },
1330
+ .alpha = "alpha",
1331
+ };
1332
+
1333
+ expect_string( mock_send_request_message, to_service_name, "switch_manager.m" );
1334
+ expect_string( mock_send_request_message, from_service_name, "tetris-efic-1234" );
1335
+ expect_value( mock_send_request_message, tag32, MESSENGER_MANAGEMENT_REQUEST );
1336
+ expect_memory( mock_send_request_message, data, &expected_data, sizeof( struct expected_data ) );
1337
+ expect_value( mock_send_request_message, len, sizeof( struct expected_data ) );
1338
+ expect_value( mock_send_request_message, hd->callback, _get_switch_list_after_swm_succ );
1339
+ expect_any( mock_send_request_message, hd->user_data );
1340
+
1341
+ // using send fail pattern to avoid all_request_param leak warning
1342
+ will_return( mock_send_request_message, false );
1343
+ assert_false( add_event_forward_entry_to_all_switches( EVENT_FORWARD_TYPE_PACKET_IN, "alpha", callback, user_data ) );
1344
+ }
1345
+
1346
+
1347
+ static void
1348
+ test_delete_event_forward_entry_to_all_switches_succeeds() {
1349
+
1350
+ event_forward_entry_to_all_callback callback = ( event_forward_entry_to_all_callback ) 0x12345678;
1351
+ void *user_data = ( void * ) 0xABCDEF;
1352
+
1353
+ struct expected_data {
1354
+ management_application_request mgmt;
1355
+ event_forward_operation_request efi;
1356
+ char alpha[ 6 ];
1357
+ } __attribute__( ( packed ) ) expected_data = {
1358
+ .mgmt = {
1359
+ .header = {
1360
+ .type = htons( MANAGEMENT_APPLICATION_REQUEST ),
1361
+ .length = htonl( sizeof( struct expected_data ) ),
1362
+ },
1363
+ .application_id = htonl( EVENT_FORWARD_ENTRY_DELETE ),
1364
+ },
1365
+ .efi = {
1366
+ .type = EVENT_FORWARD_TYPE_PACKET_IN,
1367
+ .n_services = htonl( 1 ),
1368
+ },
1369
+ .alpha = "alpha",
1370
+ };
1371
+
1372
+ expect_string( mock_send_request_message, to_service_name, "switch_manager.m" );
1373
+ expect_string( mock_send_request_message, from_service_name, "tetris-efic-1234" );
1374
+ expect_value( mock_send_request_message, tag32, MESSENGER_MANAGEMENT_REQUEST );
1375
+ expect_memory( mock_send_request_message, data, &expected_data, sizeof( struct expected_data ) );
1376
+ expect_value( mock_send_request_message, len, sizeof( struct expected_data ) );
1377
+ expect_value( mock_send_request_message, hd->callback, _get_switch_list_after_swm_succ );
1378
+ expect_any( mock_send_request_message, hd->user_data );
1379
+
1380
+ // using send fail pattern to avoid all_request_param leak warning
1381
+ will_return( mock_send_request_message, false );
1382
+ assert_false( delete_event_forward_entry_to_all_switches( EVENT_FORWARD_TYPE_PACKET_IN, "alpha", callback, user_data ) );
1383
+ }
1384
+
1385
+
1386
+ static void
1387
+ test__get_switch_list_after_swm_succ_succeeds() {
1388
+
1389
+ void *user_data = ( void * ) 0xABCDEF;
1390
+
1391
+ struct expected_data {
1392
+ management_application_request mgmt;
1393
+ } __attribute__( ( packed ) ) expected_data = {
1394
+ .mgmt = {
1395
+ .header = {
1396
+ .type = htons( MANAGEMENT_APPLICATION_REQUEST ),
1397
+ .length = htonl( sizeof( struct expected_data ) ),
1398
+ },
1399
+ .application_id = htonl( EFI_GET_SWLIST ),
1400
+ },
1401
+ };
1402
+
1403
+ struct event_forward_operation_to_all_request_param *param = xcalloc( 1, sizeof( struct event_forward_operation_to_all_request_param ) );
1404
+ param->add = true;
1405
+ param->type = EVENT_FORWARD_TYPE_PACKET_IN;
1406
+ param->service_name = xstrdup( "alpha" );
1407
+ param->callback = mock_event_forward_entry_to_all_callback;
1408
+ param->user_data = user_data;
1409
+
1410
+ event_forward_operation_result result;
1411
+ result.result = EFI_OPERATION_SUCCEEDED;
1412
+ result.n_services = 0;
1413
+ result.services = NULL;
1414
+
1415
+ expect_string( mock_send_request_message, to_service_name, "switch_manager.m" );
1416
+ expect_string( mock_send_request_message, from_service_name, "tetris-efic-1234" );
1417
+ expect_value( mock_send_request_message, tag32, MESSENGER_MANAGEMENT_REQUEST );
1418
+ expect_memory( mock_send_request_message, data, &expected_data, sizeof( struct expected_data ) );
1419
+ expect_value( mock_send_request_message, len, sizeof( struct expected_data ) );
1420
+ expect_value( mock_send_request_message, hd->callback, _dispatch_to_all_switch );
1421
+ expect_value( mock_send_request_message, hd->user_data, param );
1422
+ will_return( mock_send_request_message, true );
1423
+
1424
+ _get_switch_list_after_swm_succ( result, param );
1425
+
1426
+ xfree( param->service_name );
1427
+ xfree( param );
1428
+ }
1429
+
1430
+
1431
+ static void
1432
+ test__dispatch_to_all_switch_succeeds() {
1433
+ init_timer();
1434
+ uint64_t dpids[] = { 0x12345678 };
1435
+ const size_t n_dpids = 1;
1436
+
1437
+ void *user_data = ( void * ) 0xABCDEF;
1438
+
1439
+ struct event_forward_operation_to_all_request_param *param = xcalloc( 1, sizeof( struct event_forward_operation_to_all_request_param ) );
1440
+ param->add = true;
1441
+ param->type = EVENT_FORWARD_TYPE_PACKET_IN;
1442
+ param->service_name = xstrdup( "alpha" );
1443
+ param->callback = mock_event_forward_entry_to_all_callback;
1444
+ param->user_data = user_data;
1445
+
1446
+
1447
+ struct expected_data {
1448
+ management_application_request mgmt;
1449
+ event_forward_operation_request efi;
1450
+ char alpha[ 6 ];
1451
+ } __attribute__( ( packed ) ) expected_data = {
1452
+ .mgmt = {
1453
+ .header = {
1454
+ .type = htons( MANAGEMENT_APPLICATION_REQUEST ),
1455
+ .length = htonl( sizeof( struct expected_data ) ),
1456
+ },
1457
+ .application_id = htonl( EVENT_FORWARD_ENTRY_ADD ),
1458
+ },
1459
+ .efi = {
1460
+ .type = EVENT_FORWARD_TYPE_PACKET_IN,
1461
+ .n_services = htonl( 1 ),
1462
+ },
1463
+ .alpha = "alpha",
1464
+ };
1465
+
1466
+ expect_string( mock_send_request_message, to_service_name, "switch.0x12345678.m" );
1467
+ expect_string( mock_send_request_message, from_service_name, "tetris-efic-1234" );
1468
+ expect_value( mock_send_request_message, tag32, MESSENGER_MANAGEMENT_REQUEST );
1469
+ expect_memory( mock_send_request_message, data, &expected_data, sizeof( struct expected_data ) );
1470
+ expect_value( mock_send_request_message, len, sizeof( struct expected_data ) );
1471
+ expect_value( mock_send_request_message, hd->callback, _switch_response_handler );
1472
+ expect_any( mock_send_request_message, hd->user_data ); // txinfo
1473
+ will_return( mock_send_request_message, true );
1474
+
1475
+ free_user_data_member = true;
1476
+ _dispatch_to_all_switch( dpids, n_dpids, param );
1477
+
1478
+ // free all_sw_tx, param
1479
+ expect_string( mock_warn, message, "txid:0x1 was left behind." );
1480
+ _cleanup_tx_table();
1481
+
1482
+ finalize_timer();
1483
+ }
1484
+
1485
+
1486
+ static void
1487
+ test__switch_response_handler_succeeds_when_last_one_standing() {
1488
+
1489
+ void *user_data = ( void * ) 0x1234;
1490
+
1491
+ struct event_forward_operation_to_all_request_param *param = xcalloc( 1, sizeof( struct event_forward_operation_to_all_request_param ) );
1492
+ param->add = true;
1493
+ param->type = EVENT_FORWARD_TYPE_PACKET_IN;
1494
+ param->service_name = xstrdup( "alpha" );
1495
+ param->callback = mock_event_forward_entry_to_all_callback;
1496
+ param->user_data = user_data;
1497
+
1498
+ all_sw_tx *tx = _insert_tx( 1, param );
1499
+ uint64_t *dpid = xmalloc( sizeof( uint64_t ) );
1500
+ *dpid = 0x12345678;
1501
+ insert_hash_entry( tx->waiting_dpid, dpid, dpid );
1502
+
1503
+ event_forward_operation_result result;
1504
+ result.result = EFI_OPERATION_SUCCEEDED;
1505
+ result.n_services = 0;
1506
+ result.services = NULL;
1507
+
1508
+ struct txinfo *txinfo = xmalloc( sizeof( struct txinfo ) );
1509
+ txinfo->dpid = 0x12345678;
1510
+ txinfo->txid = tx->txid;
1511
+
1512
+ expect_value( mock_event_forward_entry_to_all_callback, result, EFI_OPERATION_SUCCEEDED );
1513
+ expect_value( mock_event_forward_entry_to_all_callback, user_data, user_data );
1514
+
1515
+ _switch_response_handler( result, txinfo );
1516
+ }
1517
+
1518
+
1519
+ static void
1520
+ test__switch_response_timeout_then_fails() {
1521
+
1522
+ void *user_data = ( void * ) 0x1234;
1523
+
1524
+ struct event_forward_operation_to_all_request_param *param = xcalloc( 1, sizeof( struct event_forward_operation_to_all_request_param ) );
1525
+ param->add = true;
1526
+ param->type = EVENT_FORWARD_TYPE_PACKET_IN;
1527
+ param->service_name = xstrdup( "alpha" );
1528
+ param->callback = mock_event_forward_entry_to_all_callback;
1529
+ param->user_data = user_data;
1530
+
1531
+ all_sw_tx *tx = _insert_tx( 1, param );
1532
+ uint64_t *dpid = xmalloc( sizeof( uint64_t ) );
1533
+ *dpid = 0x12345678;
1534
+ insert_hash_entry( tx->waiting_dpid, dpid, dpid );
1535
+
1536
+ struct txinfo *txinfo = xmalloc( sizeof( struct txinfo ) );
1537
+ txinfo->dpid = 0x12345678;
1538
+ txinfo->txid = tx->txid;
1539
+
1540
+ expect_value( mock_event_forward_entry_to_all_callback, result, EFI_OPERATION_FAILED );
1541
+ expect_value( mock_event_forward_entry_to_all_callback, user_data, user_data );
1542
+
1543
+ _switch_response_timeout( txinfo );
1544
+ xfree( txinfo );
1545
+ }
1546
+
1547
+
1548
+ /********************************************************************************
1549
+ * Run tests.
1550
+ ********************************************************************************/
1551
+
1552
+ int
1553
+ main() {
1554
+ const UnitTest tests[] = {
1555
+ unit_test_setup_teardown( test_init_event_forward_interface_succeeds,
1556
+ setup, teardown ),
1557
+ unit_test_setup_teardown( test_init_event_forward_interface_succeeds_even_with_long_name,
1558
+ setup, teardown ),
1559
+ unit_test_setup_teardown( test_init_event_forward_interface_fails_if_already_initialized,
1560
+ setup, teardown ),
1561
+
1562
+ unit_test_setup_teardown( test_finalize_event_forward_interface_succeeds,
1563
+ setup, teardown ),
1564
+ unit_test_setup_teardown( test_finalize_event_forward_interface_fails_if_not_initialized,
1565
+ setup, teardown ),
1566
+
1567
+ unit_test_setup_teardown( test_set_switch_manager_event_forward_entries_succeeds,
1568
+ setup_init_efi, teardown_finl_efi ),
1569
+ unit_test_setup_teardown( test_add_switch_manager_event_forward_entry_succeeds,
1570
+ setup_init_efi, teardown_finl_efi ),
1571
+ unit_test_setup_teardown( test_delete_switch_manager_event_forward_entry_succeeds,
1572
+ setup_init_efi, teardown_finl_efi ),
1573
+ unit_test_setup_teardown( test_dump_switch_manager_event_forward_entries_succeeds,
1574
+ setup_init_efi, teardown_finl_efi ),
1575
+
1576
+ unit_test_setup_teardown( test_set_switch_event_forward_entries_succeeds,
1577
+ setup_init_efi, teardown_finl_efi ),
1578
+ unit_test_setup_teardown( test_add_switch_event_forward_entry_succeeds,
1579
+ setup_init_efi, teardown_finl_efi ),
1580
+ unit_test_setup_teardown( test_delete_switch_event_forward_entry_succeeds,
1581
+ setup_init_efi, teardown_finl_efi ),
1582
+ unit_test_setup_teardown( test_dump_switch_event_forward_entries_succeeds,
1583
+ setup_init_efi, teardown_finl_efi ),
1584
+
1585
+ unit_test_setup_teardown( test_handle_efi_reply_succeeds_with_success_reply,
1586
+ setup_init_efi, teardown_finl_efi ),
1587
+ unit_test_setup_teardown( test_handle_efi_reply_succeeds_with_event_forward_entry_operation_failure_reply,
1588
+ setup_init_efi, teardown_finl_efi ),
1589
+ unit_test_setup_teardown( test_handle_efi_reply_succeeds_with_management_failure_reply,
1590
+ setup_init_efi, teardown_finl_efi ),
1591
+ unit_test_setup_teardown( test_handle_efi_reply_ignores_wrong_message_tag_reply,
1592
+ setup_init_efi, teardown_finl_efi ),
1593
+ unit_test_setup_teardown( test_handle_efi_reply_ignores_wrong_message_length_reply,
1594
+ setup_init_efi, teardown_finl_efi ),
1595
+ unit_test_setup_teardown( test_handle_efi_reply_ignores_empty_reply,
1596
+ setup_init_efi, teardown_finl_efi ),
1597
+ unit_test_setup_teardown( test_handle_efi_reply_ignores_wrong_event_forward_operation_command_reply,
1598
+ setup_init_efi, teardown_finl_efi ),
1599
+ unit_test_setup_teardown( test_handle_efi_reply_succeeds_with_wrong_event_forward_operation_result_reply,
1600
+ setup_init_efi, teardown_finl_efi ),
1601
+ unit_test_setup_teardown( test_handle_efi_reply_succeeds_with_more_service_found_then_expected_reply,
1602
+ setup_init_efi, teardown_finl_efi ),
1603
+ unit_test_setup_teardown( test_handle_efi_reply_succeeds_with_empty_service_name_reply,
1604
+ setup_init_efi, teardown_finl_efi ),
1605
+
1606
+ unit_test_setup_teardown( test_create_event_forward_operation_reply_with_null_service_list,
1607
+ setup, teardown ),
1608
+ unit_test_setup_teardown( test_create_event_forward_operation_reply_with_empty_service_list,
1609
+ setup, teardown ),
1610
+ unit_test_setup_teardown( test_create_event_forward_operation_reply_with_one_service_list,
1611
+ setup, teardown ),
1612
+ unit_test_setup_teardown( test_create_event_forward_operation_reply_with_multi_service_list,
1613
+ setup, teardown ),
1614
+
1615
+ unit_test_setup_teardown( test_send_efi_switch_list_request_succeeds,
1616
+ setup_init_efi, teardown_finl_efi ),
1617
+ unit_test_setup_teardown( test_handle_efi_reply_succeeds_with_switch_list_reply,
1618
+ setup_init_efi, teardown_finl_efi ),
1619
+ unit_test_setup_teardown( test_handle_efi_reply_succeeds_with_management_failure_on_switch_list_reply,
1620
+ setup_init_efi, teardown_finl_efi ),
1621
+
1622
+
1623
+ unit_test_setup_teardown( test_add_event_forward_entry_to_all_switches_succeeds,
1624
+ setup_init_efi, teardown_finl_efi ),
1625
+ unit_test_setup_teardown( test_delete_event_forward_entry_to_all_switches_succeeds,
1626
+ setup_init_efi, teardown_finl_efi ),
1627
+ unit_test_setup_teardown( test__get_switch_list_after_swm_succ_succeeds,
1628
+ setup_init_efi, teardown_finl_efi ),
1629
+ unit_test_setup_teardown( test__dispatch_to_all_switch_succeeds,
1630
+ setup_init_efi, teardown_finl_efi ),
1631
+ unit_test_setup_teardown( test__switch_response_handler_succeeds_when_last_one_standing,
1632
+ setup_init_efi, teardown_finl_efi ),
1633
+ unit_test_setup_teardown( test__switch_response_timeout_then_fails,
1634
+ setup_init_efi, teardown_finl_efi ),
1635
+ };
1636
+ setup_leak_detector();
1637
+ return run_tests( tests );
1638
+ }
1639
+
1640
+
1641
+ /*
1642
+ * Local variables:
1643
+ * c-basic-offset: 2
1644
+ * indent-tabs-mode: nil
1645
+ * End:
1646
+ */