1+ local cassandra = require " cassandra"
2+ local cql = require " cassandra.cql"
3+ local deque = require " util.deque"
4+
5+ describe (" _Host" , function ()
6+ describe (" new" , function ()
7+ it (" sets stream_ids to the right length" , function ()
8+ local host_v2 , err = cassandra .new ({protocol_version = 2 })
9+ assert .is_nil (err )
10+ assert .are .equal (2 ^ 7 - 1 , deque .length (host_v2 .stream_ids ))
11+
12+ local host_v2 , err = cassandra .new ({protocol_version = 3 })
13+ assert .is_nil (err )
14+ assert .are .equal (2 ^ 15 - 1 , deque .length (host_v2 .stream_ids ))
15+ end )
16+ end )
17+
18+ describe (" send" , function ()
19+
20+ local function mock_request ()
21+ local r = cql .requests .startup .new ()
22+ return mock (r )
23+ end
24+
25+ local function mock_host ()
26+ local host , err = cassandra .new ()
27+ assert .is_nil (err )
28+ stub (host .sock , " send" )
29+ stub (host .sock , " receive" )
30+ return host
31+ end
32+
33+ it (" sets stream_id without overriding existing opts" , function ()
34+ local req = mock_request ()
35+ local host = mock_host ()
36+ req .opts = {custom = " option" }
37+
38+ local _ , err = host :send (req )
39+ assert .is_nil (err )
40+ assert .are .same ({custom = " option" , stream_id = 1 }, req .opts )
41+ end )
42+
43+ it (" sets stream_id if there are no existing opts" , function ()
44+ local req = mock_request ()
45+ local host = mock_host ()
46+
47+ local _ , err = host :send (req )
48+ assert .is_nil (err )
49+ assert .are .same ({stream_id = 1 }, req .opts )
50+ end )
51+
52+ it (" doesn't crash if there are no stream_ids left" , function ()
53+ local req = mock_request ()
54+ local host = mock_host ()
55+ host .stream_ids [" last" ] = host .stream_ids [" first" ] - 1
56+
57+ local _ , err = host :send (req )
58+ assert .is_nil (err )
59+ assert .is_nil (req .opts )
60+ end )
61+
62+ it (" puts stream_id back if send fails" , function ()
63+ local req = mock_request ()
64+ local host = mock_host ()
65+ host .sock .send = function () return nil , " send failure" end
66+
67+ local _ , err = host :send (req )
68+ assert .are .equal (" send failure" , err )
69+ assert .are .equal (1 , deque .popright (host .stream_ids ))
70+ end )
71+
72+ it (" puts stream_id back if receive fails" , function ()
73+ local req = mock_request ()
74+ local host = mock_host ()
75+ host .sock .send = function () return true , nil end
76+ host .sock .receive = function () return nil , " receive failure" end
77+
78+ local _ , err = host :send (req )
79+ assert .are .equal (" receive failure" , err )
80+ assert .are .equal (1 , deque .popright (host .stream_ids ))
81+ end )
82+
83+ it (" retries if response stream_id doesn't match" , function ()
84+ local req = mock_request ()
85+ local host = mock_host ()
86+ host .sock .send = function () return true , nil end
87+ host .sock .receive = function () return " foobar" , nil end
88+ local stream_id = 4
89+ local read_header_count = 0
90+
91+ cql .frame_reader = {
92+ version = function (_ ) return 3 end ,
93+ read_header = function (_ )
94+ read_header_count = read_header_count + 1
95+ stream_id = stream_id - 1
96+ return {stream_id = stream_id , body_length = 0 }
97+ end ,
98+ read_body = function (_ , _ ) return " body" end
99+ }
100+
101+ local res , err = host :send (req )
102+ assert .is_nil (err )
103+ -- The first 2 times the stream_id doesn't match (3 & 2)
104+ -- The third time is 1 so the function should exit correctly
105+ assert .are .equal (3 , read_header_count )
106+ -- The stream_id should be back in the deque
107+ assert .are .equal (1 , deque .popright (host .stream_ids ))
108+ assert .are .equal (" body" , res )
109+ end )
110+ end )
111+ end )
0 commit comments