|
1 | 1 | /*jshint strict: false */
|
2 |
| -/*global arango, db */ |
| 2 | +/*global arango, db, assertTrue */ |
3 | 3 |
|
4 | 4 | // //////////////////////////////////////////////////////////////////////////////
|
5 | 5 | // / @brief Helper for JavaScript Tests
|
|
42 | 42 | isEqual,
|
43 | 43 | compareStringIds,
|
44 | 44 | } = require('@arangodb/test-helper-common');
|
| 45 | +const clusterInfo = global.ArangoClusterInfo; |
45 | 46 |
|
46 | 47 | exports.getServerById = getServerById;
|
47 | 48 | exports.getServersByType = getServersByType;
|
@@ -122,3 +123,51 @@ exports.getMetric = function (endpoint, name) {
|
122 | 123 | }
|
123 | 124 | return Number(matches[0].replace(/^.* (\d+)$/, '$1'));
|
124 | 125 | };
|
| 126 | + |
| 127 | +exports.waitForShardsInSync = function(cn, timeout) { |
| 128 | + if (!timeout) { |
| 129 | + timeout = 300; |
| 130 | + } |
| 131 | + // The client variant has the database name inside it's scope. |
| 132 | + // TODO: Need to figure out how to get that done on server api. As soon as |
| 133 | + // this is necessary. We can always hand it in as parameter, but then we have |
| 134 | + // differences for client / server on this helper methods api ;( |
| 135 | + let dbName = "_system"; |
| 136 | + let start = internal.time(); |
| 137 | + const setsAreEqual = (left, right) => { |
| 138 | + // Sets have to be equal in size |
| 139 | + if (left.size !== right.size) { |
| 140 | + return false; |
| 141 | + } |
| 142 | + // Every entry in left, needs to be in right. |
| 143 | + // THere can be no duplicates in a set, so this |
| 144 | + // is equivalent to left and right having exactly the |
| 145 | + // same entries. |
| 146 | + for (const entry of left) { |
| 147 | + if (!right.has(entry)) { |
| 148 | + return false; |
| 149 | + } |
| 150 | + } |
| 151 | + return true; |
| 152 | + }; |
| 153 | + |
| 154 | + while (internal.time() - start < timeout) { |
| 155 | + let insync = 0; |
| 156 | + const { shards } = clusterInfo.getCollectionInfo(dbName, cn); |
| 157 | + for (const [shard, plannedServers] of Object.entries(shards)) { |
| 158 | + const { servers } = clusterInfo.getCollectionInfoCurrent(dbName, cn, shard); |
| 159 | + if (setsAreEqual(new Set(servers), new Set(plannedServers))) { |
| 160 | + ++insync; |
| 161 | + } |
| 162 | + } |
| 163 | + if (insync === Object.keys(shards).length) { |
| 164 | + return; |
| 165 | + } |
| 166 | + if ((internal.time() - start) * 2 > timeout) { |
| 167 | + console.warn(`Only ${insync} in-sync out of ${Object.keys(shards).length} after ${internal.time() - start}, waiting until ${timeout}`); |
| 168 | + } |
| 169 | + internal.wait(1); |
| 170 | + } |
| 171 | + assertTrue(false, "Shards were not getting in sync in time, giving up!"); |
| 172 | + return; |
| 173 | +}; |
0 commit comments