From c5e38155e14d7b2fb04220c32219ae9852ddf469 Mon Sep 17 00:00:00 2001 From: Eishun Kondoh Date: Mon, 29 Apr 2019 03:07:31 +0900 Subject: [PATCH] quality: Add test cases for meter_mod message --- lib/openflow/meter_band/drop.ex | 22 ++++++++-------- lib/openflow/meter_band/remark.ex | 32 +++++++++++++++------- lib/openflow/meter_mod.ex | 25 ++++++++++++++++++ test/ofp_meter_mod_test.exs | 44 +++++++++++++++++++++++++++++++ 4 files changed, 102 insertions(+), 21 deletions(-) create mode 100644 test/ofp_meter_mod_test.exs diff --git a/lib/openflow/meter_band/drop.ex b/lib/openflow/meter_band/drop.ex index bacd01d..4728bb4 100644 --- a/lib/openflow/meter_band/drop.ex +++ b/lib/openflow/meter_band/drop.ex @@ -6,17 +6,17 @@ defmodule Openflow.MeterBand.Drop do alias __MODULE__ - def new(options) do - rate = Keyword.get(options, :rate, 0) - burst_size = Keyword.get(options, :burst_size, 0) - %Drop{rate: rate, burst_size: burst_size} - end + @type t :: %Drop{rate: 0..0xFFFFFFFF, burst_size: 0..0xFFFFFFFF} - def read(<<1::16, 16::16, rate::32, burst_size::32, _::size(4)-unit(8)>>) do - %Drop{rate: rate, burst_size: burst_size} - end + @spec new(rate: 0..0xFFFFFFFF, burst_size: 0..0xFFFFFFFF) :: t() + def new(options), + do: %Drop{rate: options[:rate] || 0, burst_size: options[:burst_size] || 0} - def to_binary(%Drop{rate: rate, burst_size: burst_size}) do - <<1::16, 16::16, rate::32, burst_size::32, 0::size(4)-unit(8)>> - end + @spec read(<<_::128>>) :: t() + def read(<<1::16, 16::16, rate::32, burst_size::32, _::size(4)-unit(8)>>), + do: %Drop{rate: rate, burst_size: burst_size} + + @spec to_binary(t()) :: <<_::128>> + def to_binary(%Drop{rate: rate, burst_size: burst_size}), + do: <<1::16, 16::16, rate::32, burst_size::32, 0::size(4)-unit(8)>> end diff --git a/lib/openflow/meter_band/remark.ex b/lib/openflow/meter_band/remark.ex index 1bb3f93..a6d0102 100644 --- a/lib/openflow/meter_band/remark.ex +++ b/lib/openflow/meter_band/remark.ex @@ -7,18 +7,30 @@ defmodule Openflow.MeterBand.Remark do alias __MODULE__ + @type t :: %Remark{ + rate: 0..0xFFFFFFFF, + burst_size: 0..0xFFFFFFFF, + prec_level: 0..0xFF + } + + @spec new( + rate: 0..0xFFFFFFFF, + burst_size: 0..0xFFFFFFFF, + prec_level: 0..0xFF + ) :: t() def new(options) do - rate = Keyword.get(options, :rate, 0) - burst_size = Keyword.get(options, :burst_size, 0) - prec_level = Keyword.get(options, :prec_level, 0) - %Remark{rate: rate, burst_size: burst_size, prec_level: prec_level} + %Remark{ + rate: options[:rate] || 0, + burst_size: options[:burst_size] || 0, + prec_level: options[:prec_level] || 0 + } end - def read(<<2::16, 16::16, rate::32, burst_size::32, prec_level::8, _::size(3)-unit(8)>>) do - %Remark{rate: rate, burst_size: burst_size, prec_level: prec_level} - end + @spec read(<<_::128>>) :: t() + def read(<<2::16, 16::16, rate::32, burst_size::32, prec_level::8, _::size(3)-unit(8)>>), + do: %Remark{rate: rate, burst_size: burst_size, prec_level: prec_level} - def to_binary(%Remark{rate: rate, burst_size: burst_size, prec_level: prec_level}) do - <<2::16, 16::16, rate::32, burst_size::32, prec_level::8, 0::size(3)-unit(8)>> - end + @spec to_binary(t()) :: <<_::128>> + def to_binary(%Remark{rate: rate, burst_size: burst_size, prec_level: prec_level}), + do: <<2::16, 16::16, rate::32, burst_size::32, prec_level::8, 0::size(3)-unit(8)>> end diff --git a/lib/openflow/meter_mod.ex b/lib/openflow/meter_mod.ex index d361e6e..bce7a74 100644 --- a/lib/openflow/meter_mod.ex +++ b/lib/openflow/meter_mod.ex @@ -12,10 +12,33 @@ defmodule Openflow.MeterMod do alias __MODULE__ + @type command :: :add | :modify | :delete + + @type t :: %MeterMod{ + version: 4, + xid: 0..0xFFFFFFFF, + datapath_id: String.t() | nil, + aux_id: 0..0xFF | nil, + command: command(), + flags: [:kbps | :pktps | :burst | :stats], + bands: [Openflow.MeterBand.Drop.t() | Openflow.MeterBand.Remark.t()] + } + + @spec ofp_type() :: 29 def ofp_type, do: 29 + @spec new( + version: 4, + xid: 0..0xFFFFFFFF, + datapath_id: String.t() | nil, + aux_id: 0..0xFF | nil, + command: command(), + flags: [:kbps | :pktps | :burst | :stats], + bands: [Openflow.MeterBand.Drop.t() | Openflow.MeterBand.Remark.t()] + ) :: t() def new(options \\ []) do %MeterMod{ + xid: options[:xid] || 0, command: options[:command] || :add, flags: options[:flags] || [], meter_id: options[:meter_id] || 0, @@ -23,6 +46,7 @@ defmodule Openflow.MeterMod do } end + @spec read(<<_::64, _::_*128>>) :: t() def read(<>) do command = Openflow.Enums.to_atom(command_int, :meter_mod_command) flags = Openflow.Enums.int_to_flags(flags_int, :meter_flags) @@ -31,6 +55,7 @@ defmodule Openflow.MeterMod do %MeterMod{command: command, flags: flags, meter_id: meter_id, bands: bands} end + @spec to_binary(t()) :: <<_::64, _::_*128>> def to_binary(%MeterMod{command: command, flags: flags, meter_id: meter_id, bands: bands}) do command_int = Openflow.Enums.to_int(command, :meter_mod_command) flags_int = Openflow.Enums.flags_to_int(flags, :meter_flags) diff --git a/test/ofp_meter_mod_test.exs b/test/ofp_meter_mod_test.exs new file mode 100644 index 0000000..685836e --- /dev/null +++ b/test/ofp_meter_mod_test.exs @@ -0,0 +1,44 @@ +defmodule OfpMeterModTest do + use ExUnit.Case + doctest Openflow + + describe "Openflow.MeterMod" do + test "with packet_data" do + meter_mod = + "test/packet_data/libofproto-OFP13-meter_mod.packet" + |> File.read!() + |> Openflow.read() + |> Kernel.elem(1) + |> Map.to_list() + |> Openflow.MeterMod.new() + |> Openflow.to_binary() + |> Openflow.read() + |> Kernel.elem(1) + + expect = + Openflow.MeterMod.new( + xid: 0, + meter_id: 100, + command: :add, + flags: [:pktps, :burst, :stats], + bands: [ + Openflow.MeterBand.Drop.new( + burst_size: 10, + rate: 1000 + ), + Openflow.MeterBand.Remark.new( + burst_size: 10, + prec_level: 1, + rate: 1000 + ) + ] + ) + + assert expect.xid == meter_mod.xid + assert expect.meter_id == meter_mod.meter_id + assert expect.command == meter_mod.command + assert expect.flags == meter_mod.flags + assert expect.bands == meter_mod.bands + end + end +end