1
/* Copyright (C) 2008 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
17
#include <NDBT_Test.hpp>
18
#include <HugoTransactions.hpp>
19
#include <UtilTransactions.hpp>
20
#include <NdbRestarter.hpp>
24
runClearTable(NDBT_Context* ctx, NDBT_Step* step)
26
int records = ctx->getNumRecords();
28
UtilTransactions utilTrans(*ctx->getTab());
29
if (utilTrans.clearTable2(GETNDB(step), records) != 0){
37
create_index_on_pk(Ndb* pNdb, const char* tabName)
41
const NdbDictionary::Table * tab = NDBT_Table::discoverTableFromDb(pNdb,
44
const char* idxName = "IDX_ON_PK";
45
ndbout << "Create: " <<idxName << "( ";
46
NdbDictionary::Index pIdx(idxName);
47
pIdx.setTable(tabName);
48
pIdx.setType(NdbDictionary::Index::UniqueHashIndex);
49
for (int c = 0; c< tab->getNoOfPrimaryKeys(); c++){
50
pIdx.addIndexColumn(tab->getPrimaryKey(c));
51
ndbout << tab->getPrimaryKey(c)<<" ";
55
if (pNdb->getDictionary()->createIndex(pIdx) != 0){
56
ndbout << "FAILED!" << endl;
57
const NdbError err = pNdb->getDictionary()->getNdbError();
61
ndbout << "OK!" << endl;
68
drop_index_on_pk(Ndb* pNdb, const char* tabName)
71
const char* idxName = "IDX_ON_PK";
72
ndbout << "Drop: " << idxName;
73
if (pNdb->getDictionary()->dropIndex(idxName, tabName) != 0){
74
ndbout << "FAILED!" << endl;
75
const NdbError err = pNdb->getDictionary()->getNdbError();
79
ndbout << "OK!" << endl;
85
#define CHECK(b) if (!(b)) { \
86
g_err << "ERR: "<< step->getName() \
87
<< " failed on line " << __LINE__ << endl; \
88
result = NDBT_FAILED; \
93
runTestSingleUserMode(NDBT_Context* ctx, NDBT_Step* step)
96
int loops = ctx->getNumLoops();
97
int records = ctx->getNumRecords();
98
Ndb* pNdb = GETNDB(step);
99
NdbRestarter restarter;
101
strncpy(tabName, ctx->getTab()->getName(), 255);
102
ndbout << "tabName="<<tabName<<endl;
106
HugoTransactions hugoTrans(*ctx->getTab());
107
UtilTransactions utilTrans(*ctx->getTab());
108
while (i<loops && result == NDBT_OK) {
111
int nodeId = restarter.getMasterNodeId();
112
// Test that it's not possible to restart one node in single user mode
113
CHECK(restarter.enterSingleUserMode(pNdb->getNodeId()) == 0);
114
CHECK(restarter.waitClusterSingleUser(timeout) == 0);
115
CHECK(restarter.restartOneDbNode(nodeId) != 0)
116
CHECK(restarter.exitSingleUserMode() == 0);
117
CHECK(restarter.waitClusterStarted(timeout) == 0);
119
// Test that the single user mode api can do everything
120
CHECK(restarter.enterSingleUserMode(pNdb->getNodeId()) == 0);
121
CHECK(restarter.waitClusterSingleUser(timeout) == 0);
122
CHECK(hugoTrans.loadTable(pNdb, records, 128) == 0);
123
CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0);
124
CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0);
125
CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
126
CHECK(count == records);
127
CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0);
128
CHECK(hugoTrans.scanReadRecords(pNdb, records/2, 0, 64) == 0);
129
CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
130
CHECK(count == (records/2));
131
CHECK(utilTrans.clearTable(pNdb, records/2) == 0);
132
CHECK(restarter.exitSingleUserMode() == 0);
133
CHECK(restarter.waitClusterStarted(timeout) == 0);
135
// Test create index in single user mode
136
CHECK(restarter.enterSingleUserMode(pNdb->getNodeId()) == 0);
137
CHECK(restarter.waitClusterSingleUser(timeout) == 0);
138
CHECK(create_index_on_pk(pNdb, tabName) == 0);
139
CHECK(hugoTrans.loadTable(pNdb, records, 128) == 0);
140
CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0);
141
CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0);
142
CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
143
CHECK(count == records);
144
CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0);
145
CHECK(drop_index_on_pk(pNdb, tabName) == 0);
146
CHECK(restarter.exitSingleUserMode() == 0);
147
CHECK(restarter.waitClusterStarted(timeout) == 0);
149
// Test recreate index in single user mode
150
CHECK(create_index_on_pk(pNdb, tabName) == 0);
151
CHECK(hugoTrans.loadTable(pNdb, records, 128) == 0);
152
CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
153
CHECK(restarter.enterSingleUserMode(pNdb->getNodeId()) == 0);
154
CHECK(restarter.waitClusterSingleUser(timeout) == 0);
155
CHECK(drop_index_on_pk(pNdb, tabName) == 0);
156
CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
157
CHECK(create_index_on_pk(pNdb, tabName) == 0);
158
CHECK(restarter.exitSingleUserMode() == 0);
159
CHECK(restarter.waitClusterStarted(timeout) == 0);
160
CHECK(drop_index_on_pk(pNdb, tabName) == 0);
162
CHECK(utilTrans.clearTable(GETNDB(step), records) == 0);
164
ndbout << "Restarting cluster" << endl;
165
CHECK(restarter.restartAll() == 0);
166
CHECK(restarter.waitClusterStarted(timeout) == 0);
167
CHECK(pNdb->waitUntilReady(timeout) == 0);
176
NDBT_TESTSUITE(testSingleUserMode);
177
TESTCASE("SingleUserMode",
178
"Test single user mode"){
179
INITIALIZER(runTestSingleUserMode);
180
FINALIZER(runClearTable);
182
NDBT_TESTSUITE_END(testSingleUserMode);
185
int main(int argc, const char** argv){
187
NDBT_TESTSUITE_INSTANCE(testSingleUserMode);
188
return testSingleUserMode.execute(argc, argv);