quality: Add test cases for table_features messages
This commit is contained in:
parent
344c00d31d
commit
ad1a441239
4 changed files with 58 additions and 34 deletions
|
|
@ -18,7 +18,9 @@ defmodule Openflow.Multipart.TableFeatures.Body do
|
||||||
write_setfield: nil,
|
write_setfield: nil,
|
||||||
write_setfield_miss: nil,
|
write_setfield_miss: nil,
|
||||||
apply_setfield: nil,
|
apply_setfield: nil,
|
||||||
apply_setfield_miss: nil
|
apply_setfield_miss: nil,
|
||||||
|
experimenter: nil,
|
||||||
|
experimenter_miss: nil
|
||||||
|
|
||||||
alias __MODULE__
|
alias __MODULE__
|
||||||
|
|
||||||
|
|
@ -40,6 +42,8 @@ defmodule Openflow.Multipart.TableFeatures.Body do
|
||||||
@write_setfield_miss 13
|
@write_setfield_miss 13
|
||||||
@apply_setfield 14
|
@apply_setfield 14
|
||||||
@apply_setfield_miss 15
|
@apply_setfield_miss 15
|
||||||
|
@experimenter 0xFFFE
|
||||||
|
@experimenter_miss 0xFFFF
|
||||||
|
|
||||||
@prop_keys [
|
@prop_keys [
|
||||||
:instructions,
|
:instructions,
|
||||||
|
|
@ -55,7 +59,9 @@ defmodule Openflow.Multipart.TableFeatures.Body do
|
||||||
:write_setfield,
|
:write_setfield,
|
||||||
:write_setfield_miss,
|
:write_setfield_miss,
|
||||||
:apply_setfield,
|
:apply_setfield,
|
||||||
:apply_setfield_miss
|
:apply_setfield_miss,
|
||||||
|
:experimenter,
|
||||||
|
:experimenter_miss
|
||||||
]
|
]
|
||||||
|
|
||||||
def new(options) do
|
def new(options) do
|
||||||
|
|
@ -79,7 +85,9 @@ defmodule Openflow.Multipart.TableFeatures.Body do
|
||||||
write_setfield: options[:write_setfield],
|
write_setfield: options[:write_setfield],
|
||||||
write_setfield_miss: options[:write_setfield_miss],
|
write_setfield_miss: options[:write_setfield_miss],
|
||||||
apply_setfield: options[:apply_setfield],
|
apply_setfield: options[:apply_setfield],
|
||||||
apply_setfield_miss: options[:apply_setfield_miss]
|
apply_setfield_miss: options[:apply_setfield_miss],
|
||||||
|
experimenter: options[:experimenter],
|
||||||
|
experimenter_miss: options[:experimenter_miss]
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -111,7 +119,7 @@ defmodule Openflow.Multipart.TableFeatures.Body do
|
||||||
name_bin::size(@max_table_name_len)-bytes, metadata_match::64, metadata_write::64,
|
name_bin::size(@max_table_name_len)-bytes, metadata_match::64, metadata_write::64,
|
||||||
config_int::32, max_entries::32, props_bin::bytes>>
|
config_int::32, max_entries::32, props_bin::bytes>>
|
||||||
) do
|
) do
|
||||||
name = Openflow.Utils.decode_string(name_bin)
|
name = hd(String.split(name_bin, <<0>>, parts: 2))
|
||||||
config = Openflow.Enums.int_to_flags(config_int, :table_config)
|
config = Openflow.Enums.int_to_flags(config_int, :table_config)
|
||||||
|
|
||||||
body = %Body{
|
body = %Body{
|
||||||
|
|
@ -142,7 +150,7 @@ defmodule Openflow.Multipart.TableFeatures.Body do
|
||||||
} = table
|
} = table
|
||||||
|
|
||||||
config_int = Openflow.Enums.flags_to_int(config, :table_config)
|
config_int = Openflow.Enums.flags_to_int(config, :table_config)
|
||||||
name_bin = Openflow.Utils.encode_string(name, @max_table_name_len)
|
name_bin = String.pad_trailing(name, @max_table_name_len, <<0>>)
|
||||||
|
|
||||||
<<length::16, table_id::8, 0::size(5)-unit(8), name_bin::bytes, metadata_match::64,
|
<<length::16, table_id::8, 0::size(5)-unit(8), name_bin::bytes, metadata_match::64,
|
||||||
metadata_write::64, config_int::32, max_entries::32, props_bin::bytes>>
|
metadata_write::64, config_int::32, max_entries::32, props_bin::bytes>>
|
||||||
|
|
@ -171,7 +179,7 @@ defmodule Openflow.Multipart.TableFeatures.Body do
|
||||||
pad_length = Openflow.Utils.pad_length(length, 8)
|
pad_length = Openflow.Utils.pad_length(length, 8)
|
||||||
value_length = length - @prop_header_length
|
value_length = length - @prop_header_length
|
||||||
<<next_tables_bin::size(value_length)-bytes, _::size(pad_length)-unit(8), rest::bytes>> = tail
|
<<next_tables_bin::size(value_length)-bytes, _::size(pad_length)-unit(8), rest::bytes>> = tail
|
||||||
next_tables = for <<table_id::8 <- next_tables_bin>>, do: table_id
|
next_tables = :erlang.binary_to_list(next_tables_bin)
|
||||||
type = Openflow.Enums.to_atom(type_int, :table_feature_prop_type)
|
type = Openflow.Enums.to_atom(type_int, :table_feature_prop_type)
|
||||||
|
|
||||||
body
|
body
|
||||||
|
|
@ -208,9 +216,13 @@ defmodule Openflow.Multipart.TableFeatures.Body do
|
||||||
|> decode_props(rest)
|
|> decode_props(rest)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp decode_props(body, <<_type_int::16, length::16, tail::bytes>>) do
|
defp decode_props(
|
||||||
|
body,
|
||||||
|
<<type_int::16, length::16, _experimenter::32, _exp_type::32, tail::bytes>>
|
||||||
|
)
|
||||||
|
when type_int == @experimenter or type_int == @experimenter_miss do
|
||||||
pad_length = Openflow.Utils.pad_length(length, 8)
|
pad_length = Openflow.Utils.pad_length(length, 8)
|
||||||
value_length = length - @prop_header_length
|
value_length = length - 12
|
||||||
<<_::size(value_length)-bytes, _::size(pad_length)-unit(8), rest::bytes>> = tail
|
<<_::size(value_length)-bytes, _::size(pad_length)-unit(8), rest::bytes>> = tail
|
||||||
decode_props(body, rest)
|
decode_props(body, rest)
|
||||||
end
|
end
|
||||||
|
|
@ -230,7 +242,7 @@ defmodule Openflow.Multipart.TableFeatures.Body do
|
||||||
defp encode_props(acc, table, [type | rest])
|
defp encode_props(acc, table, [type | rest])
|
||||||
when type == :next_tables or type == :next_tables_miss do
|
when type == :next_tables or type == :next_tables_miss do
|
||||||
type_int = Openflow.Enums.to_int(type, :table_feature_prop_type)
|
type_int = Openflow.Enums.to_int(type, :table_feature_prop_type)
|
||||||
next_tables_bin = to_string(Map.get(table, type))
|
next_tables_bin = :erlang.list_to_binary(Map.get(table, type))
|
||||||
length = @prop_header_length + byte_size(next_tables_bin)
|
length = @prop_header_length + byte_size(next_tables_bin)
|
||||||
pad_length = Openflow.Utils.pad_length(length, 8)
|
pad_length = Openflow.Utils.pad_length(length, 8)
|
||||||
body = <<next_tables_bin::bytes, 0::size(pad_length)-unit(8)>>
|
body = <<next_tables_bin::bytes, 0::size(pad_length)-unit(8)>>
|
||||||
|
|
@ -260,6 +272,10 @@ defmodule Openflow.Multipart.TableFeatures.Body do
|
||||||
encode_props(<<acc::bytes, type_int::16, length::16, body::bytes>>, table, rest)
|
encode_props(<<acc::bytes, type_int::16, length::16, body::bytes>>, table, rest)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp encode_props(acc, table, [_type | rest]) do
|
||||||
|
encode_props(acc, table, rest)
|
||||||
|
end
|
||||||
|
|
||||||
defp decode_instructions(acc, ""), do: Enum.reverse(acc)
|
defp decode_instructions(acc, ""), do: Enum.reverse(acc)
|
||||||
|
|
||||||
defp decode_instructions(acc, <<0xFFFF::16, _::16, exp_id::32, rest::bytes>>) do
|
defp decode_instructions(acc, <<0xFFFF::16, _::16, exp_id::32, rest::bytes>>) do
|
||||||
|
|
|
||||||
|
|
@ -12,24 +12,13 @@ defmodule Openflow.Multipart.TableFeatures.Reply do
|
||||||
alias __MODULE__
|
alias __MODULE__
|
||||||
alias Openflow.Multipart.TableFeatures.Body
|
alias Openflow.Multipart.TableFeatures.Body
|
||||||
|
|
||||||
def ofp_type, do: 18
|
def ofp_type, do: 19
|
||||||
|
|
||||||
def new(tables \\ []) do
|
|
||||||
%Reply{tables: tables}
|
|
||||||
end
|
|
||||||
|
|
||||||
def read(<<tables_bin::bytes>>) do
|
def read(<<tables_bin::bytes>>) do
|
||||||
tables = Body.read(tables_bin)
|
tables = Body.read(tables_bin)
|
||||||
%Reply{tables: tables}
|
%Reply{tables: tables}
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_binary(msg) do
|
|
||||||
header_bin = Openflow.Multipart.Reply.header(msg)
|
|
||||||
%Reply{tables: tables} = msg
|
|
||||||
tables_bin = Openflow.Multipart.TableFeatures.Body.to_binary(tables)
|
|
||||||
<<header_bin::bytes, tables_bin::bytes>>
|
|
||||||
end
|
|
||||||
|
|
||||||
def append_body(%Reply{tables: tables} = message, %Reply{flags: [:more], tables: continue}) do
|
def append_body(%Reply{tables: tables} = message, %Reply{flags: [:more], tables: continue}) do
|
||||||
%{message | tables: [continue | tables]}
|
%{message | tables: [continue | tables]}
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ defmodule Openflow.Multipart.TableFeatures.Request do
|
||||||
|
|
||||||
def new(options \\ []) do
|
def new(options \\ []) do
|
||||||
%Request{
|
%Request{
|
||||||
|
flags: options[:flags] || [],
|
||||||
xid: options[:xid] || 0,
|
xid: options[:xid] || 0,
|
||||||
tables: options[:tables] || []
|
tables: options[:tables] || []
|
||||||
}
|
}
|
||||||
|
|
@ -32,17 +33,4 @@ defmodule Openflow.Multipart.TableFeatures.Request do
|
||||||
tables_bin = Openflow.Multipart.TableFeatures.Body.to_binary(tables)
|
tables_bin = Openflow.Multipart.TableFeatures.Body.to_binary(tables)
|
||||||
<<header_bin::bytes, tables_bin::bytes>>
|
<<header_bin::bytes, tables_bin::bytes>>
|
||||||
end
|
end
|
||||||
|
|
||||||
def append_body(%Request{tables: tables} = message, %Request{flags: [:more], tables: continue}) do
|
|
||||||
%{message | tables: [continue | tables]}
|
|
||||||
end
|
|
||||||
|
|
||||||
def append_body(%Request{tables: tables} = message, %Request{flags: [], tables: continue}) do
|
|
||||||
new_tables =
|
|
||||||
[continue | tables]
|
|
||||||
|> Enum.reverse()
|
|
||||||
|> List.flatten()
|
|
||||||
|
|
||||||
%{message | tables: new_tables}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
31
test/lib/openflow/ofp_tables_features_test.exs
Normal file
31
test/lib/openflow/ofp_tables_features_test.exs
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
defmodule OfpTableFeaturesTest do
|
||||||
|
use ExUnit.Case
|
||||||
|
|
||||||
|
describe "Openflow.Multipart.Table.Request" do
|
||||||
|
test "with default values" do
|
||||||
|
table_features =
|
||||||
|
"test/packet_data/4-55-ofp_table_features_request.packet"
|
||||||
|
|> File.read!()
|
||||||
|
|> Openflow.read()
|
||||||
|
|> Kernel.elem(1)
|
||||||
|
|
||||||
|
table_features
|
||||||
|
|> Map.to_list()
|
||||||
|
|> Openflow.Multipart.TableFeatures.Request.new()
|
||||||
|
|> Openflow.to_binary()
|
||||||
|
|> Openflow.read()
|
||||||
|
|> Kernel.elem(1)
|
||||||
|
|> Kernel.==(table_features)
|
||||||
|
|> assert()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "Openflow.Multipart.Table.Reply" do
|
||||||
|
test "with default values" do
|
||||||
|
"test/packet_data/4-56-ofp_table_features_reply.packet"
|
||||||
|
|> File.read!()
|
||||||
|
|> Openflow.read()
|
||||||
|
|> Kernel.elem(1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
Add table
Add a link
Reference in a new issue