pio 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/README.md +56 -22
- data/examples/dhcp_new.rb +22 -18
- data/examples/features_new.rb +14 -0
- data/examples/features_read.rb +4 -0
- data/features/arp_read.feature +4 -4
- data/features/dhcp_read.feature +2 -2
- data/features/echo_read.feature +5 -0
- data/features/features_read.feature +10 -0
- data/features/hello_read.feature +5 -0
- data/features/icmp_read.feature +2 -2
- data/features/lldp_read.feature +4 -4
- data/features/{pcap → packet_data}/arp-storm.pcap +0 -0
- data/features/{pcap → packet_data}/arp.pcap +0 -0
- data/features/{pcap → packet_data}/dhcp.pcap +0 -0
- data/features/packet_data/echo.raw +0 -0
- data/features/packet_data/features_reply.raw +0 -0
- data/features/packet_data/features_request.raw +0 -0
- data/features/packet_data/hello.raw +0 -0
- data/features/{pcap → packet_data}/icmp.pcap +0 -0
- data/features/{pcap → packet_data}/lldp.detailed.pcap +0 -0
- data/features/{pcap → packet_data}/lldp.minimal.pcap +0 -0
- data/features/step_definitions/packet_data_steps.rb +32 -0
- data/features/step_definitions/pending_steps.rb +5 -0
- data/lib/pio.rb +1 -0
- data/lib/pio/arp.rb +1 -1
- data/lib/pio/arp/{frame.rb → format.rb} +2 -2
- data/lib/pio/arp/message.rb +2 -2
- data/lib/pio/dhcp/dhcp_field.rb +3 -3
- data/lib/pio/dhcp/frame.rb +6 -6
- data/lib/pio/dhcp/optional_tlv.rb +3 -3
- data/lib/pio/echo.rb +4 -11
- data/lib/pio/echo/format.rb +5 -5
- data/lib/pio/echo/message.rb +13 -4
- data/lib/pio/echo/reply.rb +29 -0
- data/lib/pio/echo/request.rb +29 -0
- data/lib/pio/features.rb +18 -0
- data/lib/pio/features/format.rb +18 -0
- data/lib/pio/features/message.rb +14 -0
- data/lib/pio/features/reply.rb +73 -0
- data/lib/pio/features/request.rb +63 -0
- data/lib/pio/hello.rb +40 -9
- data/lib/pio/icmp.rb +1 -1
- data/lib/pio/icmp/{frame.rb → format.rb} +2 -2
- data/lib/pio/icmp/message.rb +2 -2
- data/lib/pio/icmp/request.rb +30 -14
- data/lib/pio/message_type_selector.rb +4 -7
- data/lib/pio/type/ethernet_header.rb +0 -2
- data/lib/pio/type/ipv4_header.rb +0 -1
- data/lib/pio/type/open_flow.rb +34 -0
- data/lib/pio/type/udp_header.rb +0 -1
- data/lib/pio/version.rb +1 -1
- data/pio.gemspec +2 -2
- data/spec/pio/dhcp/ack_spec.rb +1 -1
- data/spec/pio/dhcp_spec.rb +2 -2
- data/spec/pio/echo/reply_spec.rb +69 -4
- data/spec/pio/echo/request_spec.rb +48 -10
- data/spec/pio/echo_spec.rb +8 -0
- data/spec/pio/features/reply_spec.rb +30 -0
- data/spec/pio/features/request_spec.rb +70 -0
- data/spec/pio/features_spec.rb +78 -0
- data/spec/pio/hello_spec.rb +35 -6
- data/spec/spec_helper.rb +3 -0
- metadata +70 -40
- data/features/step_definitions/pcap_steps.rb +0 -18
data/lib/pio/icmp/request.rb
CHANGED
@@ -24,29 +24,45 @@ module Pio
|
|
24
24
|
option :sequence_number
|
25
25
|
option :echo_data
|
26
26
|
|
27
|
-
|
28
|
-
|
29
|
-
def initialize(options)
|
30
|
-
validate options
|
27
|
+
def initialize(user_options)
|
31
28
|
@type = TYPE
|
32
|
-
|
33
|
-
@
|
29
|
+
|
30
|
+
@options = user_options.dup
|
31
|
+
validate @options
|
32
|
+
set_mac_and_ip_address_options
|
33
|
+
set_identifier_option
|
34
|
+
set_sequence_number_option
|
35
|
+
set_echo_data_option
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def set_mac_and_ip_address_options
|
41
|
+
@source_mac = Mac.new(@options[:source_mac]).freeze
|
42
|
+
@destination_mac = Mac.new(@options[:destination_mac]).freeze
|
34
43
|
@ip_source_address =
|
35
|
-
IPv4Address.new(options[:ip_source_address]).freeze
|
44
|
+
IPv4Address.new(@options[:ip_source_address]).freeze
|
36
45
|
@ip_destination_address =
|
37
|
-
IPv4Address.new(options[:ip_destination_address]).freeze
|
46
|
+
IPv4Address.new(@options[:ip_destination_address]).freeze
|
47
|
+
end
|
48
|
+
|
49
|
+
def set_identifier_option
|
38
50
|
@identifier =
|
39
|
-
options[:icmp_identifier] ||
|
40
|
-
options[:identifier] ||
|
51
|
+
@options[:icmp_identifier] ||
|
52
|
+
@options[:identifier] ||
|
41
53
|
DEFAULT_IDENTIFIER
|
54
|
+
end
|
55
|
+
|
56
|
+
def set_sequence_number_option
|
42
57
|
@sequence_number =
|
43
|
-
options[:icmp_sequence_number] ||
|
44
|
-
options[:sequence_number] ||
|
58
|
+
@options[:icmp_sequence_number] ||
|
59
|
+
@options[:sequence_number] ||
|
45
60
|
DEFAULT_SEQUENCE_NUMBER
|
46
|
-
@echo_data = options[:echo_data] || DEFAULT_ECHO_DATA
|
47
61
|
end
|
48
62
|
|
49
|
-
|
63
|
+
def set_echo_data_option
|
64
|
+
@echo_data = (@options[:echo_data] || DEFAULT_ECHO_DATA).freeze
|
65
|
+
end
|
50
66
|
end
|
51
67
|
end
|
52
68
|
end
|
@@ -10,13 +10,10 @@ module Pio
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def read(raw_data)
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
end
|
18
|
-
|
19
|
-
const_get(:MESSAGE_TYPE)[frame.message_type].create_from frame
|
13
|
+
parsed = const_get(:Format).read(raw_data)
|
14
|
+
const_get(:MESSAGE_TYPE)[parsed.message_type].create_from parsed
|
15
|
+
rescue
|
16
|
+
raise Pio::ParseError, $ERROR_INFO.message
|
20
17
|
end
|
21
18
|
end
|
22
19
|
end
|
data/lib/pio/type/ipv4_header.rb
CHANGED
@@ -0,0 +1,34 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'bindata'
|
4
|
+
|
5
|
+
module Pio
|
6
|
+
module Type
|
7
|
+
# OpenFlow 1.0 format.
|
8
|
+
module OpenFlow
|
9
|
+
def openflow_header
|
10
|
+
class_eval do
|
11
|
+
uint8 :version, value: 1
|
12
|
+
uint8 :message_type
|
13
|
+
uint16 :message_length, initial_value: -> { 8 + body.length }
|
14
|
+
uint32 :transaction_id, initial_value: 0
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Description of a physical port
|
19
|
+
class PhyPort < BinData::Record
|
20
|
+
endian :big
|
21
|
+
|
22
|
+
uint16 :port_no
|
23
|
+
uint8 :hw_addr
|
24
|
+
stringz :name, read_length: 16
|
25
|
+
uint32 :config
|
26
|
+
uint32 :state
|
27
|
+
uint32 :curr
|
28
|
+
uint32 :advertised
|
29
|
+
uint32 :supported
|
30
|
+
uint32 :peer
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/pio/type/udp_header.rb
CHANGED
data/lib/pio/version.rb
CHANGED
data/pio.gemspec
CHANGED
@@ -35,6 +35,6 @@ Gem::Specification.new do |gem|
|
|
35
35
|
gem.test_files += Dir.glob('features/**/*')
|
36
36
|
|
37
37
|
gem.required_ruby_version = '>= 1.9.3'
|
38
|
-
gem.add_dependency 'bindata', '~> 2.
|
39
|
-
gem.add_development_dependency 'bundler', '~> 1.6.
|
38
|
+
gem.add_dependency 'bindata', '~> 2.1.0'
|
39
|
+
gem.add_development_dependency 'bundler', '~> 1.6.2'
|
40
40
|
end
|
data/spec/pio/dhcp/ack_spec.rb
CHANGED
@@ -151,7 +151,7 @@ describe Pio::Dhcp::Ack, '.new' do
|
|
151
151
|
end
|
152
152
|
end
|
153
153
|
|
154
|
-
context
|
154
|
+
context 'with String MAC Address' do
|
155
155
|
let(:source_mac) { 'aa:bb:cc:dd:ee:ff' }
|
156
156
|
let(:destination_mac) { '11:22:33:44:55:66' }
|
157
157
|
let(:ip_source_address) { '192.168.0.10' }
|
data/spec/pio/dhcp_spec.rb
CHANGED
@@ -152,7 +152,7 @@ describe Pio::Dhcp, '.read' do
|
|
152
152
|
its('client_mac_address.to_s') { should eq '24:db:ac:41:e5:5b' }
|
153
153
|
its('client_identifier.to_s') { should eq '24:db:ac:41:e5:5b' }
|
154
154
|
its('requested_ip_address.to_s') { should eq '0.0.0.0' }
|
155
|
-
its(:parameters_list) { should eq
|
155
|
+
its(:parameters_list) { should eq [0x01, 0x03, 0x06, 0x2a] }
|
156
156
|
end
|
157
157
|
|
158
158
|
context 'with DHCP offer frame' do
|
@@ -452,7 +452,7 @@ describe Pio::Dhcp, '.read' do
|
|
452
452
|
its('client_mac_address.to_s') { should eq '24:db:ac:41:e5:5b' }
|
453
453
|
its('client_identifier.to_s') { should eq '24:db:ac:41:e5:5b' }
|
454
454
|
its('requested_ip_address.to_s') { should eq '192.168.0.10' }
|
455
|
-
its(:parameters_list) { should eq
|
455
|
+
its(:parameters_list) { should eq [0x01, 0x03, 0x06, 0x2a] }
|
456
456
|
end
|
457
457
|
|
458
458
|
context 'with DHCP ACK frame' do
|
data/spec/pio/echo/reply_spec.rb
CHANGED
@@ -4,17 +4,82 @@ require 'pio'
|
|
4
4
|
|
5
5
|
describe Pio::Echo::Reply do
|
6
6
|
describe '.new' do
|
7
|
-
context 'with no
|
8
|
-
When(:echo_reply)
|
9
|
-
|
7
|
+
context 'with no arguments' do
|
8
|
+
When(:echo_reply) { Pio::Echo::Reply.new }
|
9
|
+
|
10
|
+
Then { echo_reply.version == 1 }
|
11
|
+
Then { echo_reply.message_type == Pio::Echo::REPLY }
|
12
|
+
Then { echo_reply.message_length == 8 }
|
13
|
+
Then { echo_reply.transaction_id == 0 }
|
14
|
+
Then { echo_reply.xid == 0 }
|
15
|
+
Then { echo_reply.data == '' }
|
16
|
+
Then { echo_reply.to_binary == [1, 3, 0, 8, 0, 0, 0, 0].pack('C*') }
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'with 123' do
|
20
|
+
When(:echo_reply) { Pio::Echo::Reply.new(123) }
|
21
|
+
|
22
|
+
Then { echo_reply.version == 1 }
|
23
|
+
Then { echo_reply.message_type == Pio::Echo::REPLY }
|
24
|
+
Then { echo_reply.message_length == 8 }
|
25
|
+
Then { echo_reply.transaction_id == 123 }
|
26
|
+
Then { echo_reply.xid == 123 }
|
27
|
+
Then { echo_reply.data == '' }
|
28
|
+
Then { echo_reply.to_binary == [1, 3, 0, 8, 0, 0, 0, 123].pack('C*') }
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'with 2**32' do
|
32
|
+
When(:result) { Pio::Echo::Reply.new(2**32) }
|
33
|
+
|
34
|
+
Then do
|
35
|
+
pending 'check if xid is within 32bit range.'
|
36
|
+
result == Failure(ArgumentError)
|
10
37
|
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'with transaction_id: 123' do
|
41
|
+
When(:echo_reply) { Pio::Echo::Reply.new(transaction_id: 123) }
|
11
42
|
|
12
|
-
Then { echo_reply.class == Pio::Echo::Reply }
|
13
43
|
Then { echo_reply.version == 1 }
|
14
44
|
Then { echo_reply.message_type == Pio::Echo::REPLY }
|
15
45
|
Then { echo_reply.message_length == 8 }
|
46
|
+
Then { echo_reply.transaction_id == 123 }
|
16
47
|
Then { echo_reply.xid == 123 }
|
17
48
|
Then { echo_reply.data == '' }
|
49
|
+
Then { echo_reply.to_binary == [1, 3, 0, 8, 0, 0, 0, 123].pack('C*') }
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'with xid: 123' do
|
53
|
+
When(:echo_reply) { Pio::Echo::Reply.new(xid: 123) }
|
54
|
+
|
55
|
+
Then { echo_reply.version == 1 }
|
56
|
+
Then { echo_reply.message_type == Pio::Echo::REPLY }
|
57
|
+
Then { echo_reply.message_length == 8 }
|
58
|
+
Then { echo_reply.transaction_id == 123 }
|
59
|
+
Then { echo_reply.xid == 123 }
|
60
|
+
Then { echo_reply.data == '' }
|
61
|
+
Then { echo_reply.to_binary == [1, 3, 0, 8, 0, 0, 0, 123].pack('C*') }
|
62
|
+
end
|
63
|
+
|
64
|
+
context "with transaction_id: 123, data: 'foobar'" do
|
65
|
+
When(:echo_reply) { Pio::Echo::Reply.new(xid: 123, data: 'foobar') }
|
66
|
+
|
67
|
+
Then { echo_reply.version == 1 }
|
68
|
+
Then { echo_reply.message_type == Pio::Echo::REPLY }
|
69
|
+
Then { echo_reply.message_length == 14 }
|
70
|
+
Then { echo_reply.transaction_id == 123 }
|
71
|
+
Then { echo_reply.xid == 123 }
|
72
|
+
Then { echo_reply.data == 'foobar' }
|
73
|
+
Then do
|
74
|
+
echo_reply.to_binary ==
|
75
|
+
[1, 3, 0, 14, 0, 0, 0, 123, 102, 111, 111, 98, 97, 114].pack('C*')
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context 'with :INVALID_ARGUMENT' do
|
80
|
+
When(:result) { Pio::Echo::Reply.new(:INVALID_ARGUMENT) }
|
81
|
+
|
82
|
+
Then { result == Failure(TypeError) }
|
18
83
|
end
|
19
84
|
end
|
20
85
|
end
|
@@ -4,44 +4,82 @@ require 'pio'
|
|
4
4
|
|
5
5
|
describe Pio::Echo::Request do
|
6
6
|
describe '.new' do
|
7
|
-
Given(:echo_request) do
|
8
|
-
Pio::Echo::Request.new(user_options)
|
9
|
-
end
|
10
|
-
|
11
7
|
context 'with no arguments' do
|
12
|
-
When(:
|
8
|
+
When(:echo_request) { Pio::Echo::Request.new }
|
13
9
|
|
14
|
-
Then { echo_request.class == Pio::Echo::Request }
|
15
10
|
Then { echo_request.version == 1 }
|
16
11
|
Then { echo_request.message_type == Pio::Echo::REQUEST }
|
17
12
|
Then { echo_request.message_length == 8 }
|
18
13
|
Then { echo_request.transaction_id == 0 }
|
19
14
|
Then { echo_request.xid == 0 }
|
20
15
|
Then { echo_request.data == '' }
|
16
|
+
Then { echo_request.to_binary == [1, 2, 0, 8, 0, 0, 0, 0].pack('C*') }
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'with 123' do
|
20
|
+
When(:echo_request) { Pio::Echo::Request.new(123) }
|
21
|
+
|
22
|
+
Then { echo_request.version == 1 }
|
23
|
+
Then { echo_request.message_type == Pio::Echo::REQUEST }
|
24
|
+
Then { echo_request.message_length == 8 }
|
25
|
+
Then { echo_request.transaction_id == 123 }
|
26
|
+
Then { echo_request.xid == 123 }
|
27
|
+
Then { echo_request.data == '' }
|
28
|
+
Then { echo_request.to_binary == [1, 2, 0, 8, 0, 0, 0, 123].pack('C*') }
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'with 2**32' do
|
32
|
+
When(:result) { Pio::Echo::Request.new(2**32) }
|
33
|
+
|
34
|
+
Then do
|
35
|
+
pending 'check if xid is within 32bit range.'
|
36
|
+
result == Failure(ArgumentError)
|
37
|
+
end
|
21
38
|
end
|
22
39
|
|
23
40
|
context 'with transaction_id: 123' do
|
24
|
-
When(:
|
41
|
+
When(:echo_request) { Pio::Echo::Request.new(transaction_id: 123) }
|
25
42
|
|
26
|
-
Then { echo_request.class == Pio::Echo::Request }
|
27
43
|
Then { echo_request.version == 1 }
|
28
44
|
Then { echo_request.message_type == Pio::Echo::REQUEST }
|
29
45
|
Then { echo_request.message_length == 8 }
|
30
46
|
Then { echo_request.transaction_id == 123 }
|
31
47
|
Then { echo_request.xid == 123 }
|
32
48
|
Then { echo_request.data == '' }
|
49
|
+
Then { echo_request.to_binary == [1, 2, 0, 8, 0, 0, 0, 123].pack('C*') }
|
33
50
|
end
|
34
51
|
|
35
52
|
context 'with xid: 123' do
|
36
|
-
When(:
|
53
|
+
When(:echo_request) { Pio::Echo::Request.new(xid: 123) }
|
37
54
|
|
38
|
-
Then { echo_request.class == Pio::Echo::Request }
|
39
55
|
Then { echo_request.version == 1 }
|
40
56
|
Then { echo_request.message_type == Pio::Echo::REQUEST }
|
41
57
|
Then { echo_request.message_length == 8 }
|
42
58
|
Then { echo_request.transaction_id == 123 }
|
43
59
|
Then { echo_request.xid == 123 }
|
44
60
|
Then { echo_request.data == '' }
|
61
|
+
Then { echo_request.to_binary == [1, 2, 0, 8, 0, 0, 0, 123].pack('C*') }
|
62
|
+
end
|
63
|
+
|
64
|
+
context "with transaction_id: 123, data: 'foobar'" do
|
65
|
+
When(:echo_request) { Pio::Echo::Request.new(xid: 123, data: 'foobar') }
|
66
|
+
|
67
|
+
Then { echo_request.version == 1 }
|
68
|
+
Then { echo_request.message_type == Pio::Echo::REQUEST }
|
69
|
+
Then { echo_request.message_length == 14 }
|
70
|
+
Then { echo_request.transaction_id == 123 }
|
71
|
+
Then { echo_request.xid == 123 }
|
72
|
+
Then { echo_request.data == 'foobar' }
|
73
|
+
Then do
|
74
|
+
echo_request.to_binary ==
|
75
|
+
[1, 2, 0, 14, 0, 0, 0, 123, 102, 111, 111, 98, 97, 114].pack('C*')
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context 'with :INVALID_ARGUMENT' do
|
80
|
+
When(:result) { Pio::Echo::Request.new(:INVALID_ARGUMENT) }
|
81
|
+
|
82
|
+
Then { result == Failure(TypeError) }
|
45
83
|
end
|
46
84
|
end
|
47
85
|
end
|
data/spec/pio/echo_spec.rb
CHANGED
@@ -39,5 +39,13 @@ describe Pio::Echo do
|
|
39
39
|
Then { echo_reply.data == '' }
|
40
40
|
Then { echo_reply.to_binary == echo_reply_dump }
|
41
41
|
end
|
42
|
+
|
43
|
+
context 'with a Features Request message' do
|
44
|
+
Given(:features_request_dump) { [1, 5, 0, 8, 0, 0, 0, 0].pack('C*') }
|
45
|
+
|
46
|
+
When(:result) { Pio::Echo.read(features_request_dump) }
|
47
|
+
|
48
|
+
Then { result == Failure(Pio::ParseError) }
|
49
|
+
end
|
42
50
|
end
|
43
51
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'pio'
|
4
|
+
|
5
|
+
describe Pio::Features::Reply do
|
6
|
+
describe '.new' do
|
7
|
+
Given(:options) do
|
8
|
+
{
|
9
|
+
dpid: 0x123,
|
10
|
+
n_buffers: 0x100,
|
11
|
+
n_tables: 0xfe,
|
12
|
+
capabilities: 0xc7,
|
13
|
+
actions: 0xfff
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
When(:features_reply) { Pio::Features::Reply.new(options) }
|
18
|
+
|
19
|
+
Then { features_reply.version == 1 }
|
20
|
+
Then { features_reply.message_type == Pio::Features::REPLY }
|
21
|
+
Then { features_reply.transaction_id == 0 }
|
22
|
+
Then { features_reply.xid == 0 }
|
23
|
+
Then { features_reply.dpid == 0x123 }
|
24
|
+
Then { features_reply.n_buffers == 0x100 }
|
25
|
+
Then { features_reply.n_tables == 0xfe }
|
26
|
+
Then { features_reply.capabilities == 0xc7 }
|
27
|
+
Then { features_reply.actions == 0xfff }
|
28
|
+
Then { features_reply.ports == [] }
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'pio'
|
4
|
+
|
5
|
+
describe Pio::Features::Request do
|
6
|
+
describe '.new' do
|
7
|
+
context 'with no arguments' do
|
8
|
+
When(:request) { Pio::Features::Request.new }
|
9
|
+
|
10
|
+
Then { request.version == 1 }
|
11
|
+
Then { request.message_type == Pio::Features::REQUEST }
|
12
|
+
Then { request.message_length == 8 }
|
13
|
+
Then { request.transaction_id == 0 }
|
14
|
+
Then { request.xid == 0 }
|
15
|
+
Then { request.body == '' }
|
16
|
+
Then { request.to_binary == [1, 5, 0, 8, 0, 0, 0, 0].pack('C*') }
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'with 123' do
|
20
|
+
When(:request) { Pio::Features::Request.new(123) }
|
21
|
+
|
22
|
+
Then { request.version == 1 }
|
23
|
+
Then { request.message_type == Pio::Features::REQUEST }
|
24
|
+
Then { request.message_length == 8 }
|
25
|
+
Then { request.transaction_id == 123 }
|
26
|
+
Then { request.xid == 123 }
|
27
|
+
Then { request.body == '' }
|
28
|
+
Then { request.to_binary == [1, 5, 0, 8, 0, 0, 0, 123].pack('C*') }
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'with 2**32' do
|
32
|
+
When(:result) { Pio::Features::Request.new(2**32) }
|
33
|
+
|
34
|
+
Then do
|
35
|
+
pending 'check if xid is within 32bit range.'
|
36
|
+
result == Failure(ArgumentError)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'with transaction_id: 123' do
|
41
|
+
When(:request) { Pio::Features::Request.new(transaction_id: 123) }
|
42
|
+
|
43
|
+
Then { request.version == 1 }
|
44
|
+
Then { request.message_type == Pio::Features::REQUEST }
|
45
|
+
Then { request.message_length == 8 }
|
46
|
+
Then { request.transaction_id == 123 }
|
47
|
+
Then { request.xid == 123 }
|
48
|
+
Then { request.body == '' }
|
49
|
+
Then { request.to_binary == [1, 5, 0, 8, 0, 0, 0, 123].pack('C*') }
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'with xid: 123' do
|
53
|
+
When(:request) { Pio::Features::Request.new(xid: 123) }
|
54
|
+
|
55
|
+
Then { request.version == 1 }
|
56
|
+
Then { request.message_type == Pio::Features::REQUEST }
|
57
|
+
Then { request.message_length == 8 }
|
58
|
+
Then { request.transaction_id == 123 }
|
59
|
+
Then { request.xid == 123 }
|
60
|
+
Then { request.body == '' }
|
61
|
+
Then { request.to_binary == [1, 5, 0, 8, 0, 0, 0, 123].pack('C*') }
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'with :INVALID_ARGUMENT' do
|
65
|
+
When(:result) { Pio::Features::Request.new(:INVALID_ARGUMENT) }
|
66
|
+
|
67
|
+
Then { result == Failure(TypeError) }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|