Fix cloneIndex tests

This commit is contained in:
Rudolf Meijering 2022-07-19 15:14:39 +02:00
parent ad781e67dc
commit c8c48cf732
2 changed files with 212 additions and 6 deletions

View file

@ -38,6 +38,7 @@ import {
transformDocs,
waitForIndexStatus,
initAction,
cloneIndex,
} from '..';
import type { DocumentsTransformFailed, DocumentsTransformSuccess } from '../../core';
@ -455,6 +456,212 @@ describe('migration actions', () => {
});
});
describe('cloneIndex', () => {
afterAll(async () => {
try {
// Restore the default setting of 1000 shards per node
await client.cluster.putSettings({
persistent: { cluster: { max_shards_per_node: null } },
});
await client.indices.delete({ index: 'clone_*' });
} catch (e) {
/** ignore */
}
});
it('resolves right if cloning into a new target index', async () => {
const task = cloneIndex({
client,
source: 'existing_index_with_write_block',
target: 'clone_target_1',
});
expect.assertions(1);
await expect(task()).resolves.toMatchInlineSnapshot(`
Object {
"_tag": "Right",
"right": Object {
"acknowledged": true,
"shardsAcknowledged": true,
},
}
`);
});
it('resolves right if clone target already existed after waiting for index status to be green ', async () => {
expect.assertions(2);
// Create a red index that we later turn into green
await client.indices
.create({
index: 'clone_red_then_green_index',
timeout: '5s',
body: {
mappings: { properties: {} },
settings: {
// Allocate 1 replica so that this index can go to green
number_of_replicas: '0',
// Disable all shard allocation so that the index status is red
index: { routing: { allocation: { enable: 'none' } } },
},
},
})
.catch((e) => {});
// Call clone even though the index already exists
const cloneIndexPromise = cloneIndex({
client,
source: 'existing_index_with_write_block',
target: 'clone_red_then_green_index',
})();
let indexGreen = false;
setTimeout(() => {
client.indices.putSettings({
index: 'clone_red_then_green_index',
body: {
// Enable all shard allocation so that the index status goes green
routing: { allocation: { enable: 'all' } },
},
});
indexGreen = true;
}, 10);
await cloneIndexPromise.then((res) => {
// Assert that the promise didn't resolve before the index became green
expect(indexGreen).toBe(true);
expect(res).toMatchInlineSnapshot(`
Object {
"_tag": "Right",
"right": Object {
"acknowledged": true,
"shardsAcknowledged": true,
},
}
`);
});
});
it('resolves left with a index_not_green_timeout if clone target already exists but takes longer than the specified timeout before turning green', async () => {
// Create a red index
await client.indices
.create({
index: 'clone_red_index',
timeout: '5s',
body: {
mappings: { properties: {} },
settings: {
// Allocate 1 replica so that this index stays yellow
number_of_replicas: '1',
// Disable all shard allocation so that the index status is red
index: { routing: { allocation: { enable: 'none' } } },
},
},
})
.catch((e) => {});
// Call clone even though the index already exists
let cloneIndexPromise = cloneIndex({
client,
source: 'existing_index_with_write_block',
target: 'clone_red_index',
timeout: '1s',
})();
await expect(cloneIndexPromise).resolves.toMatchInlineSnapshot(`
Object {
"_tag": "Left",
"left": Object {
"message": "[index_not_green_timeout] Timeout waiting for the status of the [clone_red_index] index to become 'green'",
"type": "index_not_green_timeout",
},
}
`);
// Now make the index yellow and repeat
await client.indices.putSettings({
index: 'clone_red_index',
body: {
// Enable all shard allocation so that the index status goes yellow
routing: { allocation: { enable: 'all' } },
},
});
// Call clone even though the index already exists
cloneIndexPromise = cloneIndex({
client,
source: 'existing_index_with_write_block',
target: 'clone_red_index',
timeout: '1s',
})();
await expect(cloneIndexPromise).resolves.toMatchInlineSnapshot(`
Object {
"_tag": "Left",
"left": Object {
"message": "[index_not_green_timeout] Timeout waiting for the status of the [clone_red_index] index to become 'green'",
"type": "index_not_green_timeout",
},
}
`);
// Now make the index green and it should succeed
await client.indices.putSettings({
index: 'clone_red_index',
body: {
// Set zero replicas so status goes green
number_of_replicas: 0,
},
});
// Call clone even though the index already exists
cloneIndexPromise = cloneIndex({
client,
source: 'existing_index_with_write_block',
target: 'clone_red_index',
timeout: '30s',
})();
await expect(cloneIndexPromise).resolves.toMatchInlineSnapshot(`
Object {
"_tag": "Right",
"right": Object {
"acknowledged": true,
"shardsAcknowledged": true,
},
}
`);
});
it('resolves left index_not_found_exception if the source index does not exist', async () => {
expect.assertions(1);
const task = cloneIndex({ client, source: 'no_such_index', target: 'clone_target_3' });
await expect(task()).resolves.toMatchInlineSnapshot(`
Object {
"_tag": "Left",
"left": Object {
"index": "no_such_index",
"type": "index_not_found_exception",
},
}
`);
});
it('resolves left cluster_shard_limit_exceeded when the action would exceed the maximum normal open shards', async () => {
// Set the max shards per node really low so that any new index that's created would exceed the maximum open shards for this cluster
await client.cluster.putSettings({ persistent: { cluster: { max_shards_per_node: 1 } } });
const cloneIndexPromise = cloneIndex({
client,
source: 'existing_index_with_write_block',
target: 'clone_target_4',
})();
await expect(cloneIndexPromise).resolves.toMatchInlineSnapshot(`
Object {
"_tag": "Left",
"left": Object {
"type": "cluster_shard_limit_exceeded",
},
}
`);
});
});
// Reindex doesn't return any errors on it's own, so we have to test
// together with waitForReindexTask
describe('reindex & waitForReindexTask', () => {
@ -1391,7 +1598,7 @@ describe('migration actions', () => {
await client.indices.delete({ index: 'red_then_yellow_index' }).catch();
await client.indices.delete({ index: 'yellow_then_green_index' }).catch();
});
it('resolves left if an existing index status does not become yellow', async () => {
it('resolves left if an existing index status does not become green', async () => {
expect.assertions(2);
// Create a red index
await client.indices
@ -1441,15 +1648,14 @@ describe('migration actions', () => {
Object {
"_tag": "Left",
"left": Object {
"error": [TimeoutError: Request timed out],
"message": "Request timed out",
"type": "retryable_es_client_error",
"message": "[index_not_green_timeout] Timeout waiting for the status of the [red_then_yellow_index] index to become 'green'",
"type": "index_not_green_timeout",
},
}
`);
});
});
it('resolves right after waiting for an existing index status to be green', async () => {
it('resolves right after waiting for an existing index status to become green', async () => {
expect.assertions(2);
// Create a red index
await client.indices

View file

@ -59,7 +59,7 @@ export const readWithPit =
// Sort fields are required to use searchAfter so we sort by the
// natural order of the index which is the most efficient option
// as order is not important for the migration
sort: ['_shard_doc:asc'],
sort: '_shard_doc:asc',
pit: { id: pitId, keep_alive: PIT_KEEP_ALIVE_10MINS },
size: batchSize,
search_after: searchAfter,