UNPKG

couchbase-index-manager

Version:
1,195 lines 41.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const configuration_1 = require("../configuration"); const index_manager_1 = require("../index-manager"); const create_index_mutation_1 = require("../plan/create-index-mutation"); const move_index_mutation_1 = require("../plan/move-index-mutation"); const resize_index_mutation_1 = require("../plan/resize-index-mutation"); const update_index_mutation_1 = require("../plan/update-index-mutation"); const index_definition_1 = require("./index-definition"); const defaultFakeIndex = { id: 'fake', name: 'fake', scope: index_manager_1.DEFAULT_SCOPE, collection: index_manager_1.DEFAULT_COLLECTION, index_key: ['id'], num_replica: 0, num_partition: 0, nodes: ['127.0.0.1:8091'], retain_deleted_xattr: false, state: 'online', using: 'gsi', }; function fakeIndex(index) { return { ...defaultFakeIndex, ...index }; } describe('ctor', function () { it('applies name', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', }); expect(def.name).toBe('test'); }); it('applies index_key string', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', }); expect(def.index_key) .toStrictEqual(['key']); }); it('applies index_key array', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: ['key1', 'key2'], }); expect(def.index_key) .toStrictEqual(['key1', 'key2']); }); it('primary key with index_key throws error', function () { expect(() => new index_definition_1.IndexDefinition({ name: 'test', is_primary: true, index_key: ['key'], })).toThrowError(); }); it('primary key with condition throws error', function () { expect(() => new index_definition_1.IndexDefinition({ name: 'test', is_primary: true, condition: '(`type` = "predicate")', })).toThrowError(); }); it('secondary index without index_key throws error', function () { expect(() => new index_definition_1.IndexDefinition({ name: 'test', index_key: undefined, })).toThrowError(); }); it('secondary index with empty index_key throws error', function () { expect(() => new index_definition_1.IndexDefinition({ name: 'test', index_key: [], })).toThrowError(); }); it('manual replica with partition throws error', function () { expect(() => new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', manual_replica: true, partition: { exprs: ['type'], }, })).toThrowError(); }); it('node list sets num_replica', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', nodes: ['a', 'b'], }); expect(def.num_replica).toBe(1); }); it('no node list keeps num_replica', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', num_replica: 2, }); expect(def.num_replica).toBe(2); }); it('no num_replica is 0', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', }); expect(def.num_replica).toBe(0); }); it('no manual_replica is false', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', }); expect(def.manual_replica).toBe(false); }); it('manual_replica sets value', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', manual_replica: true, }); expect(def.manual_replica).toBe(true); }); it('lifecycle copies values', function () { const lifecycle = { drop: true, }; const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', lifecycle: lifecycle, }); expect(def.lifecycle).not.toBe(lifecycle); expect(def.lifecycle).toEqual(lifecycle); }); it('partition copies values', function () { const partition = { exprs: ['test'], strategy: configuration_1.PartitionStrategy.Hash, }; const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', partition: partition, }); expect(def.partition).not.toBe(partition); expect(def.partition).toEqual(partition); }); it('partition null is undefined', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', partition: null, }); expect(def.partition).toBeUndefined(); }); it('no retain_deleted_xattr is false', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', }); expect(def.retain_deleted_xattr).toBe(false); }); it('retain_deleted_xattr sets value', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', retain_deleted_xattr: true, }); expect(def.retain_deleted_xattr).toBe(true); }); }); describe('applyOverride', function () { it('applies index_key string', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', }); def.applyOverride({ index_key: 'key2', }); expect(def.index_key) .toStrictEqual(['key2']); }); it('applies index_key array', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: ['key1', 'key2'], }); def.applyOverride({ index_key: ['key3', 'key4'], }); expect(def.index_key) .toStrictEqual(['key3', 'key4']); }); it('primary key with index_key throws error', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', is_primary: true, }); expect(() => def.applyOverride({ name: 'test', index_key: ['key'], })).toThrowError(); }); it('primary key with condition throws error', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', is_primary: true, }); expect(() => def.applyOverride({ name: 'test', condition: '(`type` = "predicate")', })).toThrowError(); }); it('secondary index without index_key throws error', function () { expect(() => new index_definition_1.IndexDefinition({ name: 'test', index_key: undefined, })).toThrowError(); }); it('secondary index with empty index_key throws error', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', }); expect(() => def.applyOverride({ name: 'test', index_key: [], })).toThrowError(); }); it('manual replica with partition throws error', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', manual_replica: true, }); expect(() => def.applyOverride({ partition: { exprs: ['type'], }, })).toThrowError(); }); it('node list sets num_replica', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', }); def.applyOverride({ nodes: ['a', 'b'], }); expect(def.num_replica).toBe(1); }); it('no node list keeps num_replica', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', }); def.applyOverride({ num_replica: 2, }); expect(def.num_replica).toBe(2); }); it('nodes and num_replica mismatch throws', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', }); expect(() => def.applyOverride({ nodes: ['a'], num_replica: 2, })).toThrowError(); }); it('partitioned nodes and num_replica mismatch succeeds', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', partition: { exprs: ['type'], }, }); def.applyOverride({ nodes: ['a', 'b', 'c'], num_replica: 2, }); expect(def.nodes).toHaveLength(3); expect(def.num_replica).toBe(2); }); it('nodes and num_replica match succeeds', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', }); def.applyOverride({ nodes: ['a', 'b', 'c'], num_replica: 2, }); expect(def.nodes).toHaveLength(3); expect(def.num_replica).toBe(2); }); it('no manual_replica is unchanged', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', manual_replica: true, }); def.applyOverride({}); expect(def.manual_replica).toBe(true); }); it('manual_replica sets value', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', }); def.applyOverride({ manual_replica: true, }); expect(def.manual_replica).toBe(true); }); it('lifecycle copies values', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', lifecycle: { initial: 1, }, }); const lifecycle = { drop: true, }; def.applyOverride({ lifecycle: lifecycle, }); expect(def.lifecycle).not.toBe(lifecycle); expect(def.lifecycle).toHaveProperty('initial', 1); expect(def.lifecycle).toHaveProperty('drop', true); }); it('partition undefined leaves unmodified', function () { const partition = { exprs: ['test'], strategy: configuration_1.PartitionStrategy.Hash, }; const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', partition: partition, }); def.applyOverride({}); expect(def.partition).toEqual(partition); }); it('partition null clears', function () { const partition = { exprs: ['test'], strategy: configuration_1.PartitionStrategy.Hash, }; const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', partition: partition, }); def.applyOverride({ partition: null, }); expect(def.partition).toBeUndefined(); }); it('partition updates strategy', function () { var _a; const partition = { exprs: ['test'], strategy: configuration_1.PartitionStrategy.Hash, }; const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', partition: partition, }); def.applyOverride({ partition: { strategy: 'other', }, }); expect(def.partition).toHaveProperty('strategy', 'other'); expect((_a = def.partition) === null || _a === void 0 ? void 0 : _a.exprs) .toStrictEqual(partition.exprs); }); it('partition replaces exprs', function () { var _a; const partition = { exprs: ['test', 'test2'], strategy: configuration_1.PartitionStrategy.Hash, }; const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', partition: partition, }); def.applyOverride({ partition: { exprs: ['test3'], }, }); expect(def.partition).toHaveProperty('strategy', configuration_1.PartitionStrategy.Hash); expect((_a = def.partition) === null || _a === void 0 ? void 0 : _a.exprs) .toStrictEqual(['test3']); }); }); describe('getMutation partition change', function () { it('ignores matching partition', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: '`key`', partition: { exprs: ['`test`'], }, }); const mutations = [...def.getMutations({ currentIndexes: [ fakeIndex({ name: 'test', index_key: ['`key`'], partition: 'HASH(`test`)', nodes: ['a:8091'], }), ], })]; expect(mutations).toHaveLength(0); }); it('ignores matching num_partition', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: '`key`', partition: { exprs: ['`test`'], num_partition: 3, }, }); const mutations = [...def.getMutations({ currentIndexes: [ { name: 'test', index_key: ['`key`'], partition: 'HASH(`test`)', num_partition: 3, nodes: ['a:8091'], }, ].map(fakeIndex), })]; expect(mutations).toHaveLength(0); }); it('ignores missing num_partition', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: '`key`', partition: { exprs: ['`test`'], }, }); const mutations = [...def.getMutations({ currentIndexes: [ { name: 'test', index_key: ['`key`'], partition: 'HASH(`test`)', num_partition: 8, nodes: ['a:8091'], }, ].map(fakeIndex), })]; expect(mutations).toHaveLength(0); }); it('updates if partition does not match', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: '`key`', partition: { exprs: ['`test`'], }, }); const mutations = [...def.getMutations({ currentIndexes: [ { name: 'test', index_key: ['`key`'], partition: 'HASH(`test2`)', nodes: ['a:8091'], }, ].map(fakeIndex), })]; expect(mutations).toHaveLength(1); expect(mutations[0]).toBeInstanceOf(update_index_mutation_1.UpdateIndexMutation); }); it('updates if num_partition does not match', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: '`key`', partition: { exprs: ['`test`'], num_partition: 3, }, }); const mutations = [...def.getMutations({ currentIndexes: [ { name: 'test', index_key: ['`key`'], partition: 'HASH(`test2`)', num_partition: 8, nodes: ['a:8091'], }, ].map(fakeIndex), })]; expect(mutations).toHaveLength(1); expect(mutations[0]).toBeInstanceOf(update_index_mutation_1.UpdateIndexMutation); }); it('updates if partition removed', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: '`key`', }); const mutations = [...def.getMutations({ currentIndexes: [ { name: 'test', index_key: ['`key`'], partition: 'HASH(`test2`)', nodes: ['a:8091'], }, ].map(fakeIndex), })]; expect(mutations).toHaveLength(1); expect(mutations[0]).toBeInstanceOf(update_index_mutation_1.UpdateIndexMutation); }); it('updates if partition added', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: '`key`', partition: { exprs: ['`test`'], }, }); const mutations = [...def.getMutations({ currentIndexes: [ { name: 'test', index_key: ['`key`'], nodes: ['a:8091'], }, ].map(fakeIndex), })]; expect(mutations).toHaveLength(1); expect(mutations[0]).toBeInstanceOf(update_index_mutation_1.UpdateIndexMutation); }); }); describe('getMutation manual replica node changes', function () { it('performs node move as an update', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: '`key`', manual_replica: true, nodes: ['a', 'b'], }); const mutations = [...def.getMutations({ currentIndexes: [ { name: 'test', index_key: ['`key`'], nodes: ['a:8091'], }, { name: 'test_replica1', index_key: ['`key`'], nodes: ['c:8091'], }, ].map(fakeIndex), })]; expect(mutations).toHaveLength(1); expect(mutations[0]).toBeInstanceOf(update_index_mutation_1.UpdateIndexMutation); expect(mutations[0].isSafe()).toBe(true); expect(mutations[0]).toMatchObject({ name: 'test_replica1', phase: 1, }); }); it('ignores node swap', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: '`key`', manual_replica: true, nodes: ['a', 'b'], }); const mutations = [...def.getMutations({ currentIndexes: [ { name: 'test', index_key: ['`key`'], nodes: ['b:8091'], }, { name: 'test_replica1', index_key: ['`key`'], nodes: ['a:8091'], }, ].map(fakeIndex), })]; expect(mutations).toHaveLength(0); }); it('creates new replicas first', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: '`key`', manual_replica: true, nodes: ['a', 'b', 'c'], }); const mutations = [...def.getMutations({ currentIndexes: [ { name: 'test', index_key: ['`key`'], nodes: ['d:8091'], }, ].map(fakeIndex), })]; expect(mutations).toHaveLength(3); const updates = mutations.filter((m) => m instanceof update_index_mutation_1.UpdateIndexMutation); expect(updates).toHaveLength(1); expect(mutations[0].isSafe()).toBe(true); expect(mutations[0]).toMatchObject({ name: 'test', phase: 2, }); const creates = mutations.filter((m) => m instanceof create_index_mutation_1.CreateIndexMutation); expect(creates).toHaveLength(2); for (const create of creates) { expect(create).toMatchObject({ phase: 1, }); } }); }); describe('getMutation automatic replica node changes', function () { it('performs single move mutation', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: '`key`', nodes: ['a', 'b'], }); const mutations = [...def.getMutations({ currentIndexes: [ { name: 'test', index_key: ['`key`'], nodes: ['a:8091', 'c:8091'], num_replica: 1, }, ].map(fakeIndex), clusterVersion: { major: 5, minor: 5, }, })]; expect(mutations).toHaveLength(1); expect(mutations[0]).toBeInstanceOf(move_index_mutation_1.MoveIndexMutation); expect(mutations[0]).toMatchObject({ name: 'test', phase: 1 }); }); it('ignores node swap', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: '`key`', nodes: ['a', 'b'], }); const mutations = [...def.getMutations({ currentIndexes: [ { name: 'test', index_key: ['`key`'], nodes: ['b:8091', 'a:8091'], num_replica: 1, }, ].map(fakeIndex), clusterVersion: { major: 5, minor: 5, }, })]; expect(mutations).toHaveLength(0); }); it('num_replica change gives unsafe update', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: '`key`', num_replica: 2, }); const mutations = [...def.getMutations({ currentIndexes: [ { name: 'test', index_key: ['`key`'], nodes: ['a:8091', 'b:8091'], num_replica: 1, }, ].map(fakeIndex), clusterVersion: { major: 5, minor: 5, }, })]; expect(mutations).toHaveLength(1); expect(mutations[0]).toBeInstanceOf(update_index_mutation_1.UpdateIndexMutation); expect(mutations[0].isSafe()).toBe(false); expect(mutations[0]).toMatchObject({ name: 'test', phase: 1, }); }); it('num_replica addition from zero gives unsafe update', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: '`key`', num_replica: 1, }); const mutations = [...def.getMutations({ currentIndexes: [ { name: 'test', index_key: ['`key`'], nodes: ['a:8091', 'b:8091'], num_replica: 0, }, ].map(fakeIndex), clusterVersion: { major: 5, minor: 5, }, })]; expect(mutations).toHaveLength(1); expect(mutations[0]).toBeInstanceOf(update_index_mutation_1.UpdateIndexMutation); expect(mutations[0].isSafe()).toBe(false); expect(mutations[0]).toMatchObject({ name: 'test', phase: 1, }); }); it('num_replica change gives resize on 6.5', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: '`key`', num_replica: 2, }); const mutations = [...def.getMutations({ currentIndexes: [ { name: 'test', index_key: ['`key`'], nodes: ['a:8091', 'b:8091'], num_replica: 1, }, ].map(fakeIndex), clusterVersion: { major: 6, minor: 5, }, })]; expect(mutations).toHaveLength(1); expect(mutations[0]).toBeInstanceOf(resize_index_mutation_1.ResizeIndexMutation); expect(mutations[0].isSafe()).toBe(true); expect(mutations[0]).toMatchObject({ name: 'test', phase: 1, }); }); it('num_replica addition from zero gives resize on 6.5', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: '`key`', num_replica: 1, }); const mutations = [...def.getMutations({ currentIndexes: [ { name: 'test', index_key: ['`key`'], nodes: ['a:8091'], num_replica: 0, }, ].map(fakeIndex), clusterVersion: { major: 6, minor: 5, }, })]; expect(mutations).toHaveLength(1); expect(mutations[0]).toBeInstanceOf(resize_index_mutation_1.ResizeIndexMutation); expect(mutations[0].isSafe()).toBe(true); expect(mutations[0]).toMatchObject({ name: 'test', phase: 1, }); }); it('partitioned num_replica change gives unsafe update', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: '`key`', num_replica: 2, partition: { exprs: ['`type`'], }, }); const mutations = [...def.getMutations({ currentIndexes: [ { name: 'test', index_key: ['`key`'], nodes: ['a:8091', 'b:8091'], num_replica: 1, partition: 'HASH(`type`)', }, ].map(fakeIndex), clusterVersion: { major: 5, minor: 5, }, })]; expect(mutations).toHaveLength(1); expect(mutations[0]).toBeInstanceOf(update_index_mutation_1.UpdateIndexMutation); expect(mutations[0].isSafe()).toBe(false); expect(mutations[0]).toMatchObject({ name: 'test', phase: 1, }); }); it('node length change gives unsafe update', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: '`key`', nodes: ['a'], }); const mutations = [...def.getMutations({ currentIndexes: [ { name: 'test', index_key: ['`key`'], nodes: ['a:8091', 'b:8091'], num_replica: 1, }, ].map(fakeIndex), clusterVersion: { major: 5, minor: 5, }, })]; expect(mutations).toHaveLength(1); expect(mutations[0]).toBeInstanceOf(update_index_mutation_1.UpdateIndexMutation); expect(mutations[0].isSafe()).toBe(false); expect(mutations[0]).toMatchObject({ name: 'test', phase: 1, }); }); it('node length change gives resize on 6.5', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: '`key`', nodes: ['a'], }); const mutations = [...def.getMutations({ currentIndexes: [ { name: 'test', index_key: ['`key`'], nodes: ['a:8091', 'b:8091'], num_replica: 1, }, ].map(fakeIndex), clusterVersion: { major: 6, minor: 5, }, })]; expect(mutations).toHaveLength(1); expect(mutations[0]).toBeInstanceOf(resize_index_mutation_1.ResizeIndexMutation); expect(mutations[0].isSafe()).toBe(true); expect(mutations[0]).toMatchObject({ name: 'test', phase: 1, }); }); }); describe('getMutation scope/collection', function () { it('matches default scope/collection', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: '`key`', nodes: ['a:8091'], }); const mutations = [...def.getMutations({ currentIndexes: [ { name: 'test', index_key: ['`key`'], nodes: ['a:8091'] }, ].map(fakeIndex) })]; expect(mutations).toHaveLength(0); }); it('does not match specific scope/collection with the same name', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: '`key`', nodes: ['a:8091'], }); const mutations = [...def.getMutations({ currentIndexes: [ { name: 'test', scope: 'inventory', collection: 'hotel', index_key: ['`key`'], nodes: ['a:8091'] }, ].map(fakeIndex) })]; expect(mutations).toHaveLength(1); expect(mutations[0]).toBeInstanceOf(create_index_mutation_1.CreateIndexMutation); }); }); describe('normalizeNodeList', function () { describe('auto replica', function () { it('sorts node lists', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', nodes: ['b', 'c', 'a'], }); def.normalizeNodeList([]); expect(def.nodes) .toStrictEqual(['a:8091', 'b:8091', 'c:8091']); }); it('adds port numbers', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', nodes: ['a', 'b', 'c'], }); def.normalizeNodeList([]); expect(def.nodes) .toStrictEqual(['a:8091', 'b:8091', 'c:8091']); }); it('ignores defined port numbers', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', nodes: ['a:18091', 'b', 'c'], }); def.normalizeNodeList([]); expect(def.nodes) .toStrictEqual(['a:18091', 'b:8091', 'c:8091']); }); }); describe('manual replica', function () { it('sorts node lists', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', manual_replica: true, nodes: ['b', 'c', 'a'], }); def.normalizeNodeList([]); expect(def.nodes) .toStrictEqual(['a:8091', 'b:8091', 'c:8091']); }); it('adds port numbers', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', manual_replica: true, nodes: ['a', 'b', 'c'], }); def.normalizeNodeList([]); expect(def.nodes) .toStrictEqual(['a:8091', 'b:8091', 'c:8091']); }); it('ignores defined port numbers', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', manual_replica: true, nodes: ['a:18091', 'b', 'c'], }); def.normalizeNodeList([]); expect(def.nodes) .toStrictEqual(['a:18091', 'b:8091', 'c:8091']); }); it('sorts to match replicas', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', manual_replica: true, nodes: ['a', 'b', 'c'], }); def.normalizeNodeList([ { name: 'test', nodes: ['b:8091'], }, { name: 'test_replica1', nodes: ['c:8091'], }, { name: 'test_replica2', nodes: ['a:8091'], }, ].map(fakeIndex)); expect(def.nodes) .toStrictEqual(['b:8091', 'c:8091', 'a:8091']); }); it('missing replicas get remaining nodes', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', manual_replica: true, nodes: ['a', 'b', 'c'], }); def.normalizeNodeList([ { name: 'test', nodes: ['b:8091'], }, ].map(fakeIndex)); expect(def.nodes) .toStrictEqual(['b:8091', 'a:8091', 'c:8091']); }); it('missing replica in middle gets remaining node', function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', manual_replica: true, nodes: ['a', 'b', 'c'], }); def.normalizeNodeList([ { name: 'test', nodes: ['b:8091'], }, { name: 'test_replica2', nodes: ['a:8091'], }, ].map(fakeIndex)); expect(def.nodes) .toStrictEqual(['b:8091', 'c:8091', 'a:8091']); }); }); }); describe('normalize', function () { it('does nothing for primary index', async function () { const def = new index_definition_1.IndexDefinition({ name: 'test', is_primary: true, }); const getQueryPlan = jest.fn().mockResolvedValue({}); const manager = { bucketName: 'test', getQueryPlan: getQueryPlan, }; await def.normalize(manager); expect(getQueryPlan).not.toBeCalled(); }); it('replaces keys', async function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', condition: 'type = \'beer\'', }); const indexManager = jest.fn(() => ({ bucketName: 'test', getQueryPlan: jest.fn().mockResolvedValue({ keys: [ { expr: '`key`' }, ], where: '`type` = "beer"', }) })); await def.normalize(indexManager()); expect(def.index_key) .toStrictEqual(['`key`']); }); it('handles descending keys', async function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', condition: 'type = \'beer\'', }); const indexManager = jest.fn(() => ({ bucketName: 'test', getQueryPlan: jest.fn().mockResolvedValue({ keys: [ { expr: '`key`', desc: true }, ], where: '`type` = "beer"', }) })); await def.normalize(indexManager()); expect(def.index_key) .toStrictEqual(['`key` DESC']); }); it('replaces condition', async function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', condition: 'type = \'beer\'', }); const indexManager = jest.fn(() => ({ bucketName: 'test', getQueryPlan: jest.fn().mockResolvedValue({ keys: [ { expr: '`key`' }, ], where: '`type` = "beer"' }) })); await def.normalize(indexManager()); expect(def.condition).toBe('`type` = "beer"'); }); it('plan without condition leaves condition as empty string', async function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', condition: '', }); const indexManager = jest.fn(() => ({ bucketName: 'test', getQueryPlan: jest.fn().mockResolvedValue({ keys: [ { expr: '`key`' }, ], }) })); await def.normalize(indexManager()); expect(def.condition).toBe(''); }); it('replaces partition', async function () { var _a; const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', partition: { exprs: ['test'], }, }); const indexManager = jest.fn(() => ({ bucketName: 'test', getQueryPlan: jest.fn().mockResolvedValue({ keys: [ { expr: '`key`' }, ], partition: { exprs: ['test2'], strategy: 'HASH', }, }) })); await def.normalize(indexManager()); expect(def.partition).toHaveProperty('strategy', 'HASH'); expect((_a = def.partition) === null || _a === void 0 ? void 0 : _a.exprs) .toStrictEqual(['test2']); }); it('plan without partition leaves partition undefined', async function () { const def = new index_definition_1.IndexDefinition({ name: 'test', index_key: 'key', partition: { exprs: ['test'], }, }); const indexManager = jest.fn(() => ({ bucketName: 'test', getQueryPlan: jest.fn().mockResolvedValue({ keys: [ { expr: '`key`' }, ], }) })); await def.normalize(indexManager()); expect(def.partition).toBeUndefined(); }); }); //# sourceMappingURL=index-definition.spec.js.map