/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

'use strict';

require('jasmine-expect');

const TestingHelper = require('../TestingHelper');
const {IgniteClient, ObjectType, MapObjectType, ComplexObjectType, CollectionObjectType, BinaryObject, ObjectArrayType, EnumItem, Timestamp, Decimal} = require('apache-ignite-client');

const CACHE_NAME = '__test_cache';

describe('cache put get test suite >', () => {
    let igniteClient = null;

    beforeAll((done) => {
        Promise.resolve().
            then(async () => {
                await TestingHelper.init();
                igniteClient = TestingHelper.igniteClient;
                await testSuiteCleanup(done);
                await igniteClient.getOrCreateCache(CACHE_NAME);
            }).
            then(done).
            catch(error => done.fail(error));
    }, TestingHelper.TIMEOUT);

    afterAll((done) => {
        Promise.resolve().
            then(async () => {
                await testSuiteCleanup(done);
                await TestingHelper.cleanUp();
            }).
            then(done).
            catch(error => done.fail(error));
    }, TestingHelper.TIMEOUT);

    it('put get primitive values of different types', (done) => {
        Promise.resolve().
            then(async () => {
                for (let type1 of Object.keys(TestingHelper.primitiveValues)) {
                    type1 = parseInt(type1);
                    const typeInfo1 = TestingHelper.primitiveValues[type1];
                    for (let type2 of Object.keys(TestingHelper.primitiveValues)) {
                        type2 = parseInt(type2);
                        const typeInfo2 = TestingHelper.primitiveValues[type2];
                        const modificator = typeInfo2.modificator;
                        for (let value1 of typeInfo1.values) {
                            for (let value2 of typeInfo2.values) {
                                await putGetPrimitiveValues(type1, type2, value1, value2, modificator);
                                if (typeInfo1.typeOptional) {
                                    await putGetPrimitiveValues(null, type2, value1, value2, modificator);
                                }
                                if (typeInfo2.typeOptional) {
                                    await putGetPrimitiveValues(type1, null, value1, value2, modificator);
                                }
                            }
                        }
                    }
                }
            }).
            then(done).
            catch(error => done.fail(error));
    });

    it('put get arrays of different types', (done) => {
        Promise.resolve().
            then(async () => {
                for (let type of Object.keys(TestingHelper.arrayValues)) {
                    type = parseInt(type);
                    const typeInfo = TestingHelper.arrayValues[type];
                    const primitiveType = typeInfo.elemType;
                    const values = TestingHelper.primitiveValues[primitiveType].values;
                    await putGetArrays(primitiveType, type, values[0], values);
                    await putGetArrays(primitiveType, type, values[0], []);
                    if (typeInfo.typeOptional) {
                        await putGetArrays(primitiveType, null, values[0], values);
                    }
                }
            }).
            then(done).
            catch(error => done.fail(error));
    });

    it('put get maps of different key/value types', (done) => {
        Promise.resolve().
            then(async () => {
                for (let type1 of Object.keys(TestingHelper.primitiveValues)) {
                    type1 = parseInt(type1);
                    const typeInfo1 = TestingHelper.primitiveValues[type1];
                    if (!typeInfo1.isMapKey) {
                        continue;
                    }
                    for (let type2 of Object.keys(TestingHelper.primitiveValues)) {
                        type2 = parseInt(type2);
                        const typeInfo2 = TestingHelper.primitiveValues[type2];
                        const map = new Map();
                        let index2 = 0;
                        for (let value1 of typeInfo1.values) {
                            let value2 = typeInfo2.values[index2];
                            index2++;
                            if (index2 >= typeInfo2.values.length) {
                                index2 = 0;
                            }
                            map.set(value1, value2);
                        }
                        await putGetMaps(
                            new MapObjectType(MapObjectType.MAP_SUBTYPE.HASH_MAP, type1, type2),
                            map);
                        await putGetMaps(
                            new MapObjectType(
                                MapObjectType.MAP_SUBTYPE.LINKED_HASH_MAP, type1, type2),
                            map);
                        if (typeInfo1.typeOptional) {
                            await putGetMaps(new MapObjectType(MapObjectType.MAP_SUBTYPE.HASH_MAP, null, type2),
                            map);
                        }
                        if (typeInfo2.typeOptional) {
                            await putGetMaps(new MapObjectType(MapObjectType.MAP_SUBTYPE.HASH_MAP, type1, null),
                            map);
                        }
                    }
                }
            }).
            then(done).
            catch(error => done.fail(error));
    });

    it('put get maps with arrays of different types', (done) => {
        Promise.resolve().
            then(async () => {
                for (let type1 of Object.keys(TestingHelper.primitiveValues)) {
                    type1 = parseInt(type1);
                    const typeInfo1 = TestingHelper.primitiveValues[type1];
                    if (!typeInfo1.isMapKey) {
                        continue;
                    }
                    for (let type2 of Object.keys(TestingHelper.arrayValues)) {
                        type2 = parseInt(type2);
                        const typeInfo2 = TestingHelper.arrayValues[type2];
                        const primitiveType2 = typeInfo2.elemType;
                        const values2 = TestingHelper.primitiveValues[primitiveType2].values;
                        const map = new Map();
                        let index2 = 0;
                        const arrayValues2 = [values2, null, values2.reverse()];
                        for (let value1 of typeInfo1.values) {
                            map.set(value1, arrayValues2[index2]);
                            index2++;
                            if (index2 >= arrayValues2.length) {
                                index2 = 0;
                            }
                        }
                        await putGetMaps(
                            new MapObjectType(MapObjectType.MAP_SUBTYPE.HASH_MAP, type1, type2),
                            map);
                        await putGetMaps(
                            new MapObjectType(MapObjectType.MAP_SUBTYPE.LINKED_HASH_MAP, type1, type2),
                            map);
                        if (typeInfo1.typeOptional) {
                            await putGetMaps(new MapObjectType(MapObjectType.MAP_SUBTYPE.HASH_MAP, null, type2),
                            map);
                        }
                        if (typeInfo2.typeOptional) {
                            await putGetMaps(new MapObjectType(MapObjectType.MAP_SUBTYPE.HASH_MAP, type1, null),
                            map);
                        }
                    }
                }
            }).
            then(done).
            catch(error => done.fail(error));
    });

    it('put get sets of different key/value types', (done) => {
        Promise.resolve().
            then(async () => {
                for (let type of Object.keys(TestingHelper.primitiveValues)) {
                    type = parseInt(type);
                    const typeInfo = TestingHelper.primitiveValues[type];
                    const set = new Set();
                    for (let value of typeInfo.values) {
                        set.add(value);
                    }
                    await putGetSets(
                        new CollectionObjectType(CollectionObjectType.COLLECTION_SUBTYPE.USER_SET, type),
                            set);
                    await putGetSets(
                        new CollectionObjectType(CollectionObjectType.COLLECTION_SUBTYPE.HASH_SET, type),
                            set);
                    await putGetSets(
                        new CollectionObjectType(CollectionObjectType.COLLECTION_SUBTYPE.LINKED_HASH_SET, type),
                            set);
                    if (typeInfo.typeOptional) {
                        await putGetSets(new CollectionObjectType(CollectionObjectType.COLLECTION_SUBTYPE.LINKED_HASH_SET),
                            set);
                        await putGetSets(null, set);
                    }
                }
            }).
            then(done).
            catch(error => done.fail(error));
    });

    it('put get lists of different key/value types', (done) => {
        Promise.resolve().
            then(async () => {
                for (let type of Object.keys(TestingHelper.primitiveValues)) {
                    type = parseInt(type);
                    const typeInfo = TestingHelper.primitiveValues[type];
                    const list = new Array();
                    for (let value of typeInfo.values) {
                        list.push(value);
                    }
                    await putGetLists(
                        new CollectionObjectType(CollectionObjectType.COLLECTION_SUBTYPE.USER_COL, type),
                            list);
                    await putGetLists(
                        new CollectionObjectType(CollectionObjectType.COLLECTION_SUBTYPE.ARRAY_LIST, type),
                            list);
                    await putGetLists(
                        new CollectionObjectType(CollectionObjectType.COLLECTION_SUBTYPE.LINKED_LIST, type),
                            list);
                    if (typeInfo.typeOptional) {
                        await putGetLists(new CollectionObjectType(CollectionObjectType.COLLECTION_SUBTYPE.ARRAY_LIST),
                            list);
                    }
                    // const singletonList = [typeInfo.values[0]];
                    // await putGetLists(
                    //     new CollectionObjectType(CollectionObjectType.COLLECTION_SUBTYPE.SINGLETON_LIST, type),
                    //         singletonList);
                }
            }).
            then(done).
            catch(error => done.fail(error));
    });

    it('put get object array of maps', (done) => {
        Promise.resolve().
            then(async () => {
                for (let type1 of Object.keys(TestingHelper.primitiveValues)) {
                    type1 = parseInt(type1);
                    const typeInfo1 = TestingHelper.primitiveValues[type1];
                    if (!typeInfo1.isMapKey) {
                        continue;
                    }
                    for (let type2 of Object.keys(TestingHelper.primitiveValues)) {
                        type2 = parseInt(type2);
                        const typeInfo2 = TestingHelper.primitiveValues[type2];
                        let map = new Map();
                        let index2 = 0;
                        for (let value1 of typeInfo1.values) {
                            let value2 = typeInfo2.values[index2];
                            index2++;
                            if (index2 >= typeInfo2.values.length) {
                                index2 = 0;
                            }
                            map.set(value1, value2);
                        }
                        const array = new Array();
                        for (let i = 0; i < 10; i++) {
                            map = new Map([...map.entries()].map(([key, value]) => [typeInfo1.modificator(key), typeInfo2.modificator(value)]));
                            array.push(map);
                        }
                        await putGetObjectArrays(new ObjectArrayType(new MapObjectType(MapObjectType.MAP_SUBTYPE.HASH_MAP, type1, type2)),
                            array);
                        if (typeInfo1.typeOptional) {
                            await putGetObjectArrays(new ObjectArrayType(new MapObjectType(MapObjectType.MAP_SUBTYPE.LINKED_HASH_MAP, null, type2)),
                                array);
                        }
                        if (typeInfo2.typeOptional) {
                            await putGetObjectArrays(new ObjectArrayType(new MapObjectType(MapObjectType.MAP_SUBTYPE.LINKED_HASH_MAP, type1)),
                                array);
                        }
                        if (typeInfo1.typeOptional && typeInfo2.typeOptional) {
                            await putGetObjectArrays(new ObjectArrayType(), array);
                            await putGetObjectArrays(null, array);
                        }
                    }
                }
            }).
            then(done).
            catch(error => done.fail(error));
    });

    it('put get object array of primitive types', (done) => {
        Promise.resolve().
            then(async () => {
                for (let type of Object.keys(TestingHelper.primitiveValues)) {
                    type = parseInt(type);
                    const typeInfo = TestingHelper.primitiveValues[type];
                    let value = typeInfo.values[0];
                    const array = new Array();
                    for (let i = 0; i < 10; i++) {
                        value = typeInfo.modificator(value);
                        array.push(value);
                    }
                    await putGetObjectArrays(
                        new ObjectArrayType(type),
                        array);
                    if (typeInfo.typeOptional) {
                        await putGetObjectArrays(new ObjectArrayType(), array);
                    }
                }
            }).
            then(done).
            catch(error => done.fail(error));
    });

    it('put get object array of primitive arrays', (done) => {
        Promise.resolve().
            then(async () => {
                for (let type of Object.keys(TestingHelper.arrayValues)) {
                    type = parseInt(type);
                    const typeInfo = TestingHelper.arrayValues[type];
                    const primitiveType = typeInfo.elemType;
                    const primitiveTypeInfo = TestingHelper.primitiveValues[primitiveType];
                    let values = primitiveTypeInfo.values;

                    const array = new Array();
                    for (let i = 0; i < 10; i++) {
                        values = values.map((value) => primitiveTypeInfo.modificator(value));
                        array.push(values);
                    }
                    await putGetObjectArrays(
                        new ObjectArrayType(type),
                        array);
                    if (typeInfo.typeOptional) {
                        await putGetObjectArrays(new ObjectArrayType(), array);
                    }
                }
            }).
            then(done).
            catch(error => done.fail(error));
    });

    it('put get object array of sets', (done) => {
        Promise.resolve().
            then(async () => {
                for (let type of Object.keys(TestingHelper.primitiveValues)) {
                    type = parseInt(type);
                    const typeInfo = TestingHelper.primitiveValues[type];
                    let set = new Set();
                    for (let value of typeInfo.values) {
                        set.add(value);
                    }
                    const array = new Array();
                    for (let i = 0; i < 10; i++) {
                        set = new Set([...set].map((value) => typeInfo.modificator(value)));
                        array.push(set);
                    }
                    await putGetObjectArrays(
                        new ObjectArrayType(new CollectionObjectType(CollectionObjectType.COLLECTION_SUBTYPE.USER_SET, type)),
                        array);
                    await putGetObjectArrays(
                        new ObjectArrayType(new CollectionObjectType(CollectionObjectType.COLLECTION_SUBTYPE.HASH_SET, type)),
                        array);
                    await putGetObjectArrays(
                        new ObjectArrayType(new CollectionObjectType(CollectionObjectType.COLLECTION_SUBTYPE.LINKED_HASH_SET, type)),
                        array);
                    if (typeInfo.typeOptional) {
                        await putGetObjectArrays(new ObjectArrayType(), array);
                        await putGetObjectArrays(null, array);
                    }
                }
            }).
            then(done).
            catch(error => done.fail(error));
    });

    it('put get object array of lists', (done) => {
        Promise.resolve().
            then(async () => {
                for (let type of Object.keys(TestingHelper.primitiveValues)) {
                    type = parseInt(type);
                    const typeInfo = TestingHelper.primitiveValues[type];
                    let list = new Array();
                    for (let value of typeInfo.values) {
                        list.push(value);
                    }
                    const array = new Array();
                    for (let i = 0; i < 10; i++) {
                        list = list.map((value) => typeInfo.modificator(value));
                        array.push(list);
                    }
                    await putGetObjectArrays(
                        new ObjectArrayType(new CollectionObjectType(CollectionObjectType.COLLECTION_SUBTYPE.USER_COL, type)),
                        array);
                    await putGetObjectArrays(
                        new ObjectArrayType(new CollectionObjectType(CollectionObjectType.COLLECTION_SUBTYPE.ARRAY_LIST, type)),
                        array);
                    await putGetObjectArrays(
                        new ObjectArrayType(new CollectionObjectType(CollectionObjectType.COLLECTION_SUBTYPE.LINKED_LIST, type)),
                        array);
                    if (typeInfo.typeOptional) {
                        await putGetObjectArrays(
                            new ObjectArrayType(new CollectionObjectType(CollectionObjectType.COLLECTION_SUBTYPE.ARRAY_LIST)),
                            array);
                    }
                }
            }).
            then(done).
            catch(error => done.fail(error));
    });

    it('put get object array of complex objects', (done) => {
        Promise.resolve().
            then(async () => {
                let object = {};
                for (let type of Object.keys(TestingHelper.primitiveValues)) {
                    type = parseInt(type);
                    const typeInfo = TestingHelper.primitiveValues[type];
                    object['field' + type] = typeInfo.values[0];
                }
                const objectType = new ComplexObjectType(object);
                for (let type of Object.keys(TestingHelper.primitiveValues)) {
                    type = parseInt(type);
                    objectType.setFieldType('field' + type, type);
                }

                let array = new Array();
                for (let i = 0; i < 5; i++) {
                    for (let field in object) {
                        const type = parseInt(field.substring(5));
                        object[field] = TestingHelper.primitiveValues[type].modificator(object[field]);
                    }
                    array.push(object);
                }
                await putGetObjectArrays(
                    new ObjectArrayType(objectType), array);
            }).
            then(done).
            catch(error => done.fail(error));
    });

    it('put get object array of complex objects with default field types', (done) => {
        Promise.resolve().
            then(async () => {
                let object = {};
                for (let type of Object.keys(TestingHelper.primitiveValues)) {
                    type = parseInt(type);
                    const typeInfo = TestingHelper.primitiveValues[type];
                    if (typeInfo.typeOptional) {
                        object['field' + type] = typeInfo.values[0];
                    }
                }
                const objectType = new ComplexObjectType(object, 'tstComplObjectWithDefaultFieldTypes');
                let array = new Array();
                for (let i = 0; i < 5; i++) {
                    for (let field in object) {
                        const type = parseInt(field.substring(5));
                        object[field] = TestingHelper.primitiveValues[type].modificator(object[field]);
                    }
                    array.push(object);
                }
                await putGetObjectArrays(
                    new ObjectArrayType(objectType), array);
            }).
            then(done).
            catch(error => done.fail(error));
    });

    it('put get object array of binary objects', (done) => {
        Promise.resolve().
            then(async () => {
                let binObject = new BinaryObject('tstBinaryObj');
                for (let type of Object.keys(TestingHelper.primitiveValues)) {
                    type = parseInt(type);
                    const typeInfo = TestingHelper.primitiveValues[type];
                    binObject.setField('field' + type, typeInfo.values[0], type);
                }
                let array = new Array();
                for (let i = 0; i < 5; i++) {
                    for (let field of binObject.getFieldNames()) {
                        const type = parseInt(field.substring(5));
                        binObject.setField(
                            'field' + type,
                            TestingHelper.primitiveValues[type].modificator(await binObject.getField('field' + type)),
                            type);
                    }
                    array.push(binObject);
                }
                await putGetObjectArrays(new ObjectArrayType(), array);
                await putGetObjectArrays(null, array);
            }).
            then(done).
            catch(error => done.fail(error));
    });

    it('put get object array of object arrays', (done) => {
        Promise.resolve().
            then(async () => {
                let object = {};
                for (let type of Object.keys(TestingHelper.primitiveValues)) {
                    type = parseInt(type);
                    const typeInfo = TestingHelper.primitiveValues[type];
                    object['field' + type] = typeInfo.values[0];
                }
                const objectType = new ComplexObjectType(object);
                for (let type of Object.keys(TestingHelper.primitiveValues)) {
                    type = parseInt(type);
                    objectType.setFieldType('field' + type, type);
                }

                let array = new Array();
                for (let i = 0; i < 2; i++) {
                    let innerArray = new Array();
                    for (let j = 0; j < 2; j++) {
                        for (let field in object) {
                            const type = parseInt(field.substring(5));
                            object[field] = TestingHelper.primitiveValues[type].modificator(object[field]);
                        }
                        innerArray.push(object);
                    }
                    array.push(innerArray);
                }
                await putGetObjectArrays(
                    new ObjectArrayType(new ObjectArrayType(objectType)), array);
            }).
            then(done).
            catch(error => done.fail(error));
    });

    it('put enum items', (done) => {
        Promise.resolve().
            then(async () => {
                const fakeTypeId = 12345;
                const enumItem1 = new EnumItem(fakeTypeId);
                enumItem1.setOrdinal(1);
                await putEnumItem(enumItem1, null, done);
                await putEnumItem(enumItem1, ObjectType.PRIMITIVE_TYPE.ENUM, done);
                const enumItem2 = new EnumItem(fakeTypeId);
                enumItem2.setName('name');
                await putEnumItem(enumItem2, null, done);
                await putEnumItem(enumItem2, ObjectType.PRIMITIVE_TYPE.ENUM, done);
                const enumItem3 = new EnumItem(fakeTypeId);
                enumItem3.setValue(2);
                await putEnumItem(enumItem3, null, done);
                await putEnumItem(enumItem3, ObjectType.PRIMITIVE_TYPE.ENUM, done);
            }).
            then(done).
            catch(error => done.fail(error));
    });

    async function putEnumItem(value, valueType, done) {
        const cache = igniteClient.getCache(CACHE_NAME).
            setKeyType(null).
            setValueType(valueType);
        const key = new Date();
        // Enums registration is not supported by the client, therefore put EnumItem must throw IgniteClientError
        try {
            await cache.put(key, value);
            done.fail('put EnumItem must throw IgniteClientError');
        }
        catch (err) {
            TestingHelper.checkEnumItemSerializationError(err, done);
        }
        finally {
            await cache.removeAll();
        }
    }

    async function putGetPrimitiveValues(keyType, valueType, key, value, modificator) {
        const cache = await igniteClient.getCache(CACHE_NAME).
            setKeyType(keyType).
            setValueType(valueType);
        try {
            await putGetPrimitive(cache, key, keyType, value, valueType);
            const newValue = modificator(value);
            await putGetPrimitive(cache, key, keyType, newValue, valueType);
        }
        finally {
            await cache.removeAll();
        }
    }

    async function putGetPrimitive(cache, key, keyType, value, valueType) {
        await cache.put(key, value);
        let result = await cache.get(key);
        expect(await TestingHelper.compare(value, result)).toBe(true,
            `values are not equal: keyType=${keyType}, key=${key}, valueType=${valueType}, put value=${value}, get value=${result}`);
    }

    async function putGetArrays(keyType, valueType, key, value) {
        const cache = await igniteClient.getCache(CACHE_NAME).
            setKeyType(keyType).
            setValueType(valueType);
        try {
            await cache.put(key, value);
            let result = await cache.get(key);
            await cache.clearKey(key);
            expect(result instanceof Array).toBe(true,
                `result is not Array: arrayType=${valueType}, result=${result}`);
            expect(await TestingHelper.compare(value, result)).toBe(true,
                `Arrays are not equal: arrayType=${valueType}, put array=${TestingHelper.printValue(value)
                }, get array=${TestingHelper.printValue(result)}`);
        }
        finally {
            await cache.removeAll();
        }
    }

    async function putGetMaps(mapType, value) {
        const key = new Date();
        const cache = await igniteClient.getCache(CACHE_NAME).
            setValueType(mapType);
        await cache.put(key, value);
        let result = await cache.get(key);
        expect(result instanceof Map).toBe(true,
            `result is not Map: mapType=${mapType}, result=${result}`);
        expect(await TestingHelper.compare(value, result)).toBe(true,
            `Maps are not equal: valueType=${mapType._valueType}, put value=${TestingHelper.printValue(value)
            }, get value=${TestingHelper.printValue(result)}`);
    }

    async function putGetSets(setType, value) {
        const key = new Date();
        const cache = await igniteClient.getCache(CACHE_NAME).
            setValueType(setType);
        await cache.put(key, value);
        let result = await cache.get(key);

        expect(result instanceof Set).toBe(true,
            `result is not Set: setType=${setType}, result=${result}`);
        if (!setType || setType._subType !== CollectionObjectType.COLLECTION_SUBTYPE.LINKED_HASH_SET) {
            const valueArr = [...value].sort();
            const resultArr = [...result].sort();
            expect(await TestingHelper.compare(valueArr, resultArr)).toBe(true, `Sets are not equal: valueType=${setType ? setType._elementType :
                            null}, put value=${TestingHelper.printValue(valueArr)}, get value=${TestingHelper.printValue(resultArr)}`);
        }
        else {
            expect(await TestingHelper.compare(value, result)).toBe(true, `Sets are not equal: valueType=${setType ? setType._elementType :
                            null}, put value=${TestingHelper.printValue(value)}, get value=${TestingHelper.printValue(result)}`);
        }
    }

    async function putGetLists(listType, value) {
        const key = new Date();
        const cache = await igniteClient.getCache(CACHE_NAME).
            setValueType(listType);
        await cache.put(key, value);
        let result = await cache.get(key);
        expect(result instanceof Array).toBe(true,
            `result is not Array: listType=${listType}, result=${result}`);
        expect(await TestingHelper.compare(value, result)).toBe(true, `Lists are not equal: valueType=${listType ? listType._elementType :
                        null}, put value=${TestingHelper.printValue(value)}, get value=${TestingHelper.printValue(result)}`);
    }

    async function putGetObjectArrays(arrayType, value) {
        const key = new Date();
        const cache = await igniteClient.getCache(CACHE_NAME).
            setValueType(arrayType);
        await cache.put(key, value);
        let result = await cache.get(key);
        expect(result instanceof Array).toBe(true,
            `result is not Array: arrayType=${arrayType}, result=${result}`);
        expect(await TestingHelper.compare(value, result)).toBe(true, `Arrays are not equal: valueType=${arrayType ? arrayType._elementType :
                        null}, put value=${TestingHelper.printValue(value)}, get value=${TestingHelper.printValue(result)}`);
    }

    async function testSuiteCleanup(done) {
        await TestingHelper.destroyCache(CACHE_NAME, done);
    }
});
