From 74d9baf2d00b8f8073e5662f1a94267a366a5810 Mon Sep 17 00:00:00 2001 From: Steve Singer Date: Fri, 25 Jul 2014 11:35:59 -0400 Subject: [PATCH] Bug 345 The strtok_r on the node list was adding replacing the comma with a NULL causing only 1 node to get inserted into sl_event. This mean any nodes that where cascaded only saw 1 of the nodes in the drop node list. Call strtok_r on a copy of the list so it can safely be munged. Also add in a DropNode cluster test to demonstrate test this issue --- clustertest/disorder/tests/DropNode.js | 86 ++++++++++++++++++++++++++ clustertest/disorder/tests/disorder_tests.js | 2 + src/slon/remote_worker.c | 5 +- 3 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 clustertest/disorder/tests/DropNode.js diff --git a/clustertest/disorder/tests/DropNode.js b/clustertest/disorder/tests/DropNode.js new file mode 100644 index 0000000..f8f094c --- /dev/null +++ b/clustertest/disorder/tests/DropNode.js @@ -0,0 +1,86 @@ +/** + * Some tests of the DROP PATH command. + * + */ + +coordinator.includeFile('disorder/tests/BasicTest.js'); + +DropNode=function(coordinator,testResults) { + BasicTest.call(this,coordinator,testResults); + this.testDescription='This test exercises the DROP Node command\n'; +} +DropNode.prototype = new BasicTest(); +DropNode.prototype.constructor = DropNode; + +DropNode.prototype.runTest = function() { + this.testResults.newGroup("Drop Node"); + //this.prepareDb(['db1','db2','db3','db4','db5']); + this.setupReplication(); + + /** + * Start the slons. + */ + var slonArray=[]; + for(var idx=1; idx <= this.getNodeCount(); idx++) { + slonArray[idx-1] = this.coordinator.createSlonLauncher('db' + idx); + slonArray[idx-1].run(); + } + + this.addTables(); + this.subscribeSet(1,1,1,[2,3]); + if(this.testResults.getFailureCount()== 0) { + //No apparent errors. + this.subscribeSet(1,1,3,[4,5]); + + } + this.dropNode(1); + this.checkNodeDeleted(4,2); + this.checkNodeDeleted(4,5); + for(var idx=0; idx < this.getNodeCount(); idx++) { + + slonArray[idx].stop(); + this.coordinator.join(slonArray[idx]); + } + + + + +} + +DropNode.prototype.dropNode=function(event_node) { + this.coordinator.log('dropNode ' + event_node); + var slonikPreamble = this.getSlonikPreamble(); + var slonikScript='echo \'DropNode.prototype.dropNode\';\n'; + slonikScript += "drop node(id='2,5',event node=" + event_node +");\n" + + 'wait for event(origin=' + event_node + ',wait on=' + event_node + + ',confirmed=all);\n'; + var slonik = this.coordinator.createSlonik('drop path', slonikPreamble, slonikScript); + slonik.run(); + this.coordinator.join(slonik); + this.testResults.assertCheck('drop path returned as expected',slonik.getReturnCode(), + 0); + +} + + +DropNode.prototype.checkNodeDeleted=function(client,droppedNode) { + var connection = this.coordinator.createJdbcConnection('db' + client); + + var stat = connection.createStatement(); + var rs=undefined; + try { + rs = stat.executeQuery("SELECT COUNT(*) FROM _" + this.getClusterName() + + '.sl_node where no_id=' + droppedNode ); + rs.next(); + var count = rs.getInt(1); + this.testResults.assertCheck('node still exists' + droppedNode + ' on ' + client + ,count, 0); + } + finally { + if(rs != undefined) { + rs.close(); + } + stat.close(); + connection.close(); + } +} \ No newline at end of file diff --git a/clustertest/disorder/tests/disorder_tests.js b/clustertest/disorder/tests/disorder_tests.js index 976cd21..6941a00 100644 --- a/clustertest/disorder/tests/disorder_tests.js +++ b/clustertest/disorder/tests/disorder_tests.js @@ -28,6 +28,7 @@ coordinator.includeFile('disorder/tests/WaitForTest.js'); coordinator.includeFile('disorder/tests/MultinodeFailover.js'); coordinator.includeFile('disorder/tests/Resubscribe.js'); coordinator.includeFile('disorder/tests/SiteFailover.js'); +coordinator.includeFile('disorder/tests/DropNode.js'); var tests = [new EmptySet(coordinator,results) @@ -57,6 +58,7 @@ var tests = ,new MultinodeFailover(coordinator,results) ,new Resubscribe(coordinator,results) ,new SiteFailover(coordinator,results) + ,new DropNode(coordinator,results) //Below tests are known to fail. //,new UnsubscribeBeforeEnable(coordinator,results) //,new DropSet(coordinator,results) //fails bug 133 diff --git a/src/slon/remote_worker.c b/src/slon/remote_worker.c index d9c340a..48e86fc 100644 --- a/src/slon/remote_worker.c +++ b/src/slon/remote_worker.c @@ -754,10 +754,10 @@ remoteWorkerThread_main(void *cdata) } else if (strcmp(event->ev_type, "DROP_NODE") == 0) { - char * node_list = event->ev_data1; + char * node_list = strdup(event->ev_data1); char * saveptr=NULL; char * node_id=NULL; - + while((node_id=strtok_r(node_id==NULL ? node_list : NULL ,",",&saveptr))!=NULL) { int no_id = (int) strtol(node_id, NULL, 10); @@ -798,6 +798,7 @@ remoteWorkerThread_main(void *cdata) slon_retry(); } } + free(node_list); /* * this is a remote node. Arrange for daemon restart. -- 1.7.10.4