@@ -25,7 +25,6 @@ suite() ->
2525 [{timetrap ,{minutes ,10 }}].
2626
2727init_per_suite (Config ) ->
28- mock_flow_table_identifiers (),
2928 start_applications (),
3029 case is_dobby_server_running () of
3130 false ->
@@ -35,8 +34,22 @@ init_per_suite(Config) ->
3534 Config
3635 end .
3736
37+ init_per_testcase (should_find_flow_table_identifers , Config ) ->
38+ TopFilename = ? config (data_dir , Config ) ++ " topo.json" ,
39+ dby_bulk :import (json0 , TopFilename ),
40+ Config ;
41+ init_per_testcase (_ , Config ) ->
42+ mock_flow_table_identifiers (),
43+ Config .
44+
45+ end_per_testcase (_ , Config ) ->
46+ meck :unload (),
47+ Config .
48+
3849all () ->
39- [should_publish_net_flow ].
50+ [should_publish_net_flow ,
51+ should_find_flow_table_identifers ,
52+ should_publish_flow_path ].
4053
4154% %%=============================================================================
4255% %% Testcases
@@ -45,19 +58,43 @@ all() ->
4558should_publish_net_flow (_Config ) ->
4659 % % GIVEN
4760 FlowPath = dofl_test_utils :flow_path (),
48- FlowPathIds = dofl_test_utils :flow_path_to_identifiers (FlowPath ),
4961 publish_endpoints (),
5062
5163 % % WHEN
5264 {ok , NetFlowId } = dobby_oflib :publish_new_flow (? PUBLISHER_ID , ? SRC_EP , ? DST_EP , FlowPath ),
53- Expected = lists :flatten (
54- [? SRC_EP , NetFlowId , FlowPathIds , NetFlowId , ? DST_EP ]),
65+ Expected = [? SRC_EP , NetFlowId , ? DST_EP ],
5566
5667 % % %% THEN
57- Fun = mk_net_flow_with_flow_path_fun (? DST_EP ),
68+ Fun = mk_net_flow_fun (? DST_EP ),
5869 Actual = dby :search (Fun , [], ? SRC_EP , [depth , {max_depth , 10 }, {loop , link }]),
5970 ? assertEqual (Expected , Actual ).
6071
72+ should_publish_flow_path (_Config ) ->
73+ % % GIVEN
74+ FlowPath = dofl_test_utils :flow_path (),
75+ FlowPathIds = dofl_test_utils :flow_path_to_identifiers (FlowPath ),
76+ publish_endpoints (),
77+
78+ % % WHEN
79+ {ok , NetFlowId } = dobby_oflib :publish_new_flow (? PUBLISHER_ID , ? SRC_EP , ? DST_EP , FlowPath ),
80+ Expected = lists :flatten ([NetFlowId , FlowPathIds , NetFlowId ]),
81+
82+ % % %% THEN
83+ Fun = mk_flow_path_fun (NetFlowId ),
84+ Actual = dby :search (Fun , [], NetFlowId , [breadth , {max_depth , 10 }, {loop , link }]),
85+ ? assertEqual (Expected , Actual ).
86+
87+ should_find_flow_table_identifers (_Config ) ->
88+ % % GIVEN
89+ Dpid = <<" OFS1" >>,
90+ FlowMod = {_Matches = [], _Actions = [], [{table_id , 0 }]},
91+
92+ % % WHEN
93+ Id = dofl_identifier :flow_table (Dpid , FlowMod ),
94+
95+ % % THEN
96+ ? assertEqual (<<" OFS1-table-0" >>, Id ).
97+
6198% %%=============================================================================
6299% %% Internal functions
63100% %%=============================================================================
@@ -82,45 +119,65 @@ publish_endpoints() ->
82119 ? PUBLISHER_ID , {EP , [{<<" type" >>, <<" endpoint" >>}]}, [persistent ])
83120 || EP <- [? SRC_EP , ? DST_EP ]].
84121
85- mk_net_flow_with_flow_path_fun (DstEndpoint ) ->
122+ mk_net_flow_fun (DstEndpoint ) ->
86123 fun (Identifier , _IdMetadataInfo , [], _ ) ->
87- {continue , [allowed_transitions (init , []), [Identifier ]]};
88- (Identifier , IdMetadataInfo , [{_ , PrevIdMetadataInfo , _ } | _ ], Acc ) ->
89- [AllowedT , IdentifiersAcc ] = Acc ,
90- T = transition (PrevIdMetadataInfo , IdMetadataInfo ),
91- case is_transition_allowed (T , AllowedT ) of
124+ {continue , {net_flow_next_trasitions (init ), [Identifier ]}};
125+ (Identifier , IdMetadataInfo , [PrevPathElement | _ ], Acc ) ->
126+ {NextTs , IdAcc } = Acc ,
127+ T = transition (PrevPathElement , IdMetadataInfo ),
128+ case transition_allowed (T , NextTs ) of
129+ true when Identifier =:= DstEndpoint ->
130+ {stop , lists :reverse ([Identifier | IdAcc ])};
131+ true ->
132+ {continue , {net_flow_next_trasitions (IdMetadataInfo ),
133+ [Identifier | IdAcc ]}};
92134 false ->
93- {skip , Acc };
94- true when Identifier == DstEndpoint ->
95- {stop , [Identifier | IdentifiersAcc ]};
135+ {skip , Acc }
136+ end
137+ end .
138+
139+ mk_flow_path_fun (NetFlowId ) ->
140+ fun (Identifier , _IdMetadataInfo , [], _ ) ->
141+ {continue , {flow_path_next_trasitions (init ), [Identifier ]}};
142+ (Identifier , IdMetadataInfo , [PrevPathElement | _ ], Acc ) ->
143+ {NextTs , IdAcc } = Acc ,
144+ T = transition (PrevPathElement , IdMetadataInfo ),
145+ case transition_allowed (T , NextTs ) of
146+ true when Identifier =:= NetFlowId ->
147+ {stop , lists :reverse ([Identifier | IdAcc ])};
96148 true ->
97- NewAllowedT = allowed_transitions (T , AllowedT ),
98- {continue , [NewAllowedT , [Identifier | IdentifiersAcc ]]}
149+ {continue , {flow_path_next_trasitions (IdMetadataInfo ),
150+ [Identifier | IdAcc ]}};
151+ false ->
152+ {skip , Acc }
99153 end
100154 end .
101155
102- transition (PrevIdMetadataInfo , IdMetadataInfo ) ->
103- [PrevT , T ] = [begin
104- TypeMap = maps :get (<<" type" >>, MetadataInfo ),
105- maps :get (<<" value" >>, TypeMap )
106- end || MetadataInfo <- [PrevIdMetadataInfo , IdMetadataInfo ]],
107- {binary_to_atom (PrevT , utf8 ), binary_to_atom (T , utf8 )}.
108-
109- is_transition_allowed (Transition , AllowedTransitions ) ->
110- lists :member (Transition , AllowedTransitions ).
111-
112- allowed_transitions ({endpoint , of_net_flow }, _CurrentAllowedT ) ->
113- [{of_net_flow , of_flow_mod },
114- {of_flow_mod , of_flow_mod },
115- {of_flow_mod , of_net_flow }];
116- allowed_transitions ({of_flow_mod , net_flow }, _CurrentAllowedT ) ->
117- [{net_flow , endpoint }];
118- allowed_transitions (init , _CurrentAllowedT ) ->
119- [{endpoint , of_net_flow }];
120- allowed_transitions (_ , CurrentAllowedT ) ->
121- CurrentAllowedT .
156+ net_flow_next_trasitions (init ) ->
157+ [{ep_to_nf , of_net_flow }];
158+ net_flow_next_trasitions (#{<<" type" >> := IdType }) ->
159+ net_flow_next_trasitions (binary_to_atom (maps :get (value , IdType ), utf8 ));
160+ net_flow_next_trasitions (of_net_flow ) ->
161+ [{ep_to_nf , endpoint }].
162+
163+ flow_path_next_trasitions (init ) ->
164+ [{LinkT , of_flow_mod } || LinkT <- [of_path_starts_at , of_path_ends_at ]];
165+ flow_path_next_trasitions (#{<<" type" >> := IdType }) ->
166+ flow_path_next_trasitions (binary_to_atom (maps :get (value , IdType ), utf8 ));
167+ flow_path_next_trasitions (of_flow_mod ) ->
168+ [{of_path_forwards_to , of_flow_mod } |
169+ [{LinkT , of_net_flow } || LinkT <- [of_path_starts_at , of_path_ends_at ]]].
170+
171+ transition_allowed (T , AllowedTs ) ->
172+ lists :member (T , AllowedTs ).
173+
174+ transition ({_ , _ , #{<<" type" >> := LinkType }}, #{<<" type" >> := IdType }) ->
175+ F = fun (T ) -> binary_to_atom (maps :get (value , T ), utf8 ) end ,
176+ {F (LinkType ), F (IdType )};
177+ transition (_ , _ ) ->
178+ unknown .
122179
123180trace_dby_publish () ->
124181 {module , M } = code :ensure_loaded (M = dby ),
125182 ct :pal (" Matched traces: ~p~n " ,
126- [recon_trace :calls ({dby , publish , '_' }, 10 , [{pid , all }])]).
183+ [recon_trace :calls ({dby , publish , '_' }, 20 , [{pid , all }])]).
0 commit comments