@@ -69,32 +69,43 @@ def set_failing_nodes(failing_nodes, keyspace)
6969 # @test_category error_codes
7070 #
7171 def test_raise_error_on_write_failure
72- begin
73- skip ( "Client failure errors are only available in C* after 2.2" ) if CCM . cassandra_version < '2.2.0'
74-
75- cluster = Retry . with_attempts ( 5 , Cassandra ::Errors ::NoHostsAvailable ) { Cassandra . cluster }
76- session = cluster . connect
72+ skip ( "Client failure errors are only available in C* after 2.2" ) if CCM . cassandra_version < '2.2.0'
7773
78- session . execute ( "CREATE KEYSPACE testwritefail WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '3'}" ,
79- consistency : :all ) rescue nil
80- session . execute ( "CREATE TABLE testwritefail.test (k int PRIMARY KEY, v int)" , consistency : :all )
74+ # Create a cluster object that tries to use the beta protocol. If it succeeds, the write failure response
75+ # will have a map of <node-ip, failure-code> instead of num-failures. When v5 is officially released, we
76+ # can remove the allow_beta_protocol arg in this test.
77+ cluster = Retry . with_attempts ( 5 , Cassandra ::Errors ::NoHostsAvailable ) {
78+ Cassandra . cluster ( allow_beta_protocol : true )
79+ }
80+ session = cluster . connect
8181
82- # Disable one node
83- set_failing_nodes ( [ "node1" ] , "testwritefail" )
82+ session . execute ( "CREATE KEYSPACE testwritefail WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '3'}" ,
83+ consistency : :all ) rescue nil
84+ session . execute ( "CREATE TABLE IF NOT EXISTS testwritefail.test (k int PRIMARY KEY, v int)" , consistency : :all )
8485
85- # One node disabled should trigger a WriteFailure
86- assert_raises ( Cassandra ::Errors ::WriteError ) do
87- session . execute ( "INSERT INTO testwritefail.test (k, v) VALUES (1, 0)" , consistency : :all )
88- end
86+ # Disable one node
87+ set_failing_nodes ( [ "node1" ] , "testwritefail" )
8988
90- # Quorum should still work with two nodes
91- session . execute ( "INSERT INTO testwritefail.test (k, v) VALUES (1, 0)" , consistency : :quorum )
89+ # One node disabled should trigger a WriteFailure
90+ ex = assert_raises ( Cassandra ::Errors ::WriteError ) do
91+ session . execute ( "INSERT INTO testwritefail.test (k, v) VALUES (1, 0)" , consistency : :all )
92+ end
9293
93- # Restart the node to clear jvm settings
94- set_failing_nodes ( [ ] , "testwritefail" )
95- ensure
96- cluster && cluster . close
94+ # If we're speaking protocol version > 4, verify that we have a failure map in the exception.
95+ connection_options = cluster . instance_variable_get ( :@connection_options )
96+ assert_operator ( ex . failed , :>= , 1 )
97+ if connection_options . protocol_version > 4
98+ assert_equal ( ex . failed , ex . failures_by_node . size )
99+ assert_equal ( 0 , ex . failures_by_node . values . first )
97100 end
101+
102+ # Quorum should still work with two nodes
103+ session . execute ( "INSERT INTO testwritefail.test (k, v) VALUES (1, 0)" , consistency : :quorum )
104+
105+ # Restart the node to clear jvm settings
106+ set_failing_nodes ( [ ] , "testwritefail" )
107+ ensure
108+ cluster && cluster . close
98109 end
99110
100111 # Test for validating ReadError
@@ -117,33 +128,45 @@ def test_raise_error_on_write_failure
117128 def test_raise_error_on_read_failure
118129 skip ( "Client failure errors are only available in C* after 2.2" ) if CCM . cassandra_version < '2.2.0'
119130
120- begin
121- cluster = Retry . with_attempts ( 5 , Cassandra ::Errors ::NoHostsAvailable ) { Cassandra . cluster }
122- session = cluster . connect
123-
124- session . execute ( "CREATE KEYSPACE testreadfail WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '3'}" ,
125- consistency : :all ) rescue nil
126- session . execute ( "CREATE TABLE testreadfail.test2 (k int, v0 int, v1 int, PRIMARY KEY (k, v0))" , consistency : :all )
131+ # Create a cluster object that tries to use the beta protocol. If it succeeds, the write failure response
132+ # will have a map of <node-ip, failure-code> instead of num-failures. When v5 is officially released, we
133+ # can remove the allow_beta_protocol arg in this test.
134+ cluster = Retry . with_attempts ( 5 , Cassandra ::Errors ::NoHostsAvailable ) {
135+ Cassandra . cluster ( allow_beta_protocol : true )
136+ }
137+ session = cluster . connect
138+
139+ session . execute ( "CREATE KEYSPACE testreadfail WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '3'}" ,
140+ consistency : :all ) rescue nil
141+ session . execute ( "CREATE TABLE IF NOT EXISTS testreadfail.test2 (k int, v0 int, v1 int, PRIMARY KEY (k, v0))" ,
142+ consistency : :all )
143+
144+ # Insert wide rows
145+ insert = session . prepare ( "INSERT INTO testreadfail.test2 (k, v0, v1) VALUES (1, ?, 1)" )
146+ ( 0 ..3000 ) . each do |num |
147+ session . execute ( insert , arguments : [ num ] )
148+ end
127149
128- # Insert wide rows
129- insert = session . prepare ( "INSERT INTO testreadfail.test2 (k, v0, v1) VALUES (1, ?, 1) " )
130- ( 0 ..3000 ) . each do |num |
131- session . execute ( insert , arguments : [ num ] )
132- end
150+ # Delete wide rows
151+ delete = session . prepare ( "DELETE v1 FROM testreadfail.test2 WHERE k = 1 AND v0 =? " )
152+ ( 0 ..2001 ) . each do |num |
153+ session . execute ( delete , arguments : [ num ] )
154+ end
133155
134- # Delete wide rows
135- delete = session . prepare ( "DELETE v1 FROM testreadfail.test2 WHERE k = 1 AND v0 =?" )
136- ( 0 ..2001 ) . each do |num |
137- session . execute ( delete , arguments : [ num ] )
138- end
156+ # Tombstones should trigger ReadFailure
157+ ex = assert_raises ( Cassandra ::Errors ::ReadError ) do
158+ session . execute ( "SELECT * FROM testreadfail.test2 WHERE k = 1" )
159+ end
139160
140- # Tombstones should trigger ReadFailure
141- assert_raises ( Cassandra :: Errors :: ReadError ) do
142- session . execute ( "SELECT * FROM testreadfail.test2 WHERE k = 1" )
143- end
144- ensure
145- cluster && cluster . close
161+ # If we're speaking protocol version > 4, verify that we have a failure map in the exception.
162+ connection_options = cluster . instance_variable_get ( :@connection_options )
163+ assert_operator ( ex . failed , :>= , 1 )
164+ if connection_options . protocol_version > 4
165+ assert_equal ( ex . failed , ex . failures_by_node . size )
166+ assert_equal ( 1 , ex . failures_by_node . values . first )
146167 end
168+ ensure
169+ cluster && cluster . close
147170 end
148171
149172 # Test for validating FunctionCallError
@@ -165,30 +188,28 @@ def test_raise_error_on_read_failure
165188 def test_raise_error_on_function_failure
166189 skip ( "Client failure errors are only available in C* after 2.2" ) if CCM . cassandra_version < '2.2.0'
167190
168- begin
169- cluster = Retry . with_attempts ( 5 , Cassandra ::Errors ::NoHostsAvailable ) { Cassandra . cluster }
170- session = cluster . connect
191+ cluster = Retry . with_attempts ( 5 , Cassandra ::Errors ::NoHostsAvailable ) { Cassandra . cluster }
192+ session = cluster . connect
171193
172- session . execute ( "CREATE KEYSPACE testfunctionfail WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '3'}" ,
173- consistency : :all ) rescue nil
174- session . execute ( "CREATE TABLE testfunctionfail.d (k int PRIMARY KEY , d double)" , consistency : :all )
194+ session . execute ( "CREATE KEYSPACE testfunctionfail WITH replication = {'class': 'SimpleStrategy', 'replication_factor': '3'}" ,
195+ consistency : :all ) rescue nil
196+ session . execute ( "CREATE TABLE IF NOT EXISTS testfunctionfail.d (k int PRIMARY KEY , d double)" , consistency : :all )
175197
176- # Create a UDF that throws an exception
177- session . execute ( "CREATE FUNCTION testfunctionfail.test_failure(d double)
198+ # Create a UDF that throws an exception
199+ session . execute ( "CREATE FUNCTION IF NOT EXISTS testfunctionfail.test_failure(d double)
178200 RETURNS NULL ON NULL INPUT
179201 RETURNS double
180202 LANGUAGE java AS 'throw new RuntimeException(\" failure\" );'" ,
181- consistency : :all )
203+ consistency : :all )
182204
183- # Insert value to use for function
184- session . execute ( "INSERT INTO testfunctionfail.d (k, d) VALUES (0, 5.12)" )
205+ # Insert value to use for function
206+ session . execute ( "INSERT INTO testfunctionfail.d (k, d) VALUES (0, 5.12)" )
185207
186- # FunctionFailure should be triggered
187- assert_raises ( Cassandra ::Errors ::FunctionCallError ) do
188- session . execute ( "SELECT test_failure(d) FROM testfunctionfail.d WHERE k = 0" )
189- end
190- ensure
191- cluster && cluster . close
208+ # FunctionFailure should be triggered
209+ assert_raises ( Cassandra ::Errors ::FunctionCallError ) do
210+ session . execute ( "SELECT test_failure(d) FROM testfunctionfail.d WHERE k = 0" )
192211 end
212+ ensure
213+ cluster && cluster . close
193214 end
194215end
0 commit comments