mirror of https://github.com/mongodb/mongo
84 lines
3.5 KiB
JavaScript
84 lines
3.5 KiB
JavaScript
/**
|
|
* Test the $hash expression for generating hashes of string or binary inputs.
|
|
*
|
|
* @tags: [
|
|
* requires_fcv_83
|
|
* ]
|
|
*/
|
|
import {beforeEach, describe, it} from "jstests/libs/mochalite.js";
|
|
import {assertDropCollection} from "jstests/libs/collection_drop_recreate.js";
|
|
import {assertErrorCode} from "jstests/aggregation/extras/utils.js";
|
|
|
|
const collName = jsTestName();
|
|
const coll = db[collName];
|
|
|
|
const successTests = [
|
|
// Normal strings
|
|
{
|
|
expressionInput: {input: {$concat: ["Hello", " ", "World"]}, algorithm: "xxh64"},
|
|
expectedHash: BinData(0, "YzTSBxkkW8I="),
|
|
},
|
|
{
|
|
expressionInput: {input: "[1, 2, 3]", algorithm: {$concat: ["xxh", "64"]}},
|
|
expectedHash: BinData(0, "wkwP8yqWE2o="),
|
|
},
|
|
{expressionInput: {input: "🧐🤓😎", algorithm: "xxh64"}, expectedHash: BinData(0, "tWWU4BmD+Z4=")},
|
|
|
|
// Empty
|
|
{expressionInput: {input: "", algorithm: "xxh64"}, expectedHash: BinData(0, "70bbN1HY6Zk=")},
|
|
{expressionInput: {input: BinData(0, ""), algorithm: "xxh64"}, expectedHash: BinData(0, "70bbN1HY6Zk=")},
|
|
|
|
// Binary input
|
|
{expressionInput: {input: BinData(0, "aGV5"), algorithm: "xxh64"}, expectedHash: BinData(0, "Wv5M8jFeEv4=")},
|
|
{expressionInput: {input: BinData(4, "aGV5"), algorithm: "xxh64"}, expectedHash: BinData(0, "Wv5M8jFeEv4=")},
|
|
|
|
// Nested
|
|
{
|
|
expressionInput: {input: {$hash: {input: "hey", algorithm: "xxh64"}}, algorithm: "xxh64"},
|
|
expectedHash: BinData(0, "B+qrIpasjj4="),
|
|
},
|
|
|
|
// Nullish input
|
|
{expressionInput: {input: null, algorithm: "xxh64"}, expectedHash: null},
|
|
{expressionInput: {input: undefined, algorithm: "xxh64"}, expectedHash: null},
|
|
{expressionInput: {input: "$missing", algorithm: "xxh64"}, expectedHash: null},
|
|
];
|
|
|
|
const failureTests = [
|
|
{expressionInput: {}, expectedCode: ErrorCodes.FailedToParse},
|
|
{expressionInput: {input: "string"}, expectedCode: ErrorCodes.FailedToParse},
|
|
{expressionInput: {algorithm: "xxh64"}, expectedCode: ErrorCodes.FailedToParse},
|
|
{expressionInput: {input: "string", algorithm: "xxh64", extra: 1}, expectedCode: ErrorCodes.FailedToParse},
|
|
{expressionInput: {input: [1, 2, 3], algorithm: "xxh64"}, expectedCode: 10754000},
|
|
{expressionInput: {input: "string", algorithm: [5]}, expectedCode: 10754001},
|
|
{expressionInput: {input: "string", algorithm: null}, expectedCode: 10754001},
|
|
{expressionInput: {input: "string", algorithm: "sha1"}, expectedCode: 10754002},
|
|
{expressionInput: {input: "string", algorithm: "XXH64"}, expectedCode: 10754002},
|
|
|
|
{expressionInput: {input: "string", algorithm: "md5"}, expectedCode: ErrorCodes.NotImplemented},
|
|
{expressionInput: {input: "string", algorithm: "sha256"}, expectedCode: ErrorCodes.NotImplemented},
|
|
];
|
|
|
|
describe("$hash", () => {
|
|
beforeEach(() => {
|
|
assertDropCollection(db, collName);
|
|
assert.commandWorked(coll.insert({_id: 0}));
|
|
});
|
|
|
|
it("works with various inputs", () => {
|
|
for (const {expressionInput, expectedHash} of successTests) {
|
|
const actualHash = coll.aggregate([{$project: {hash: {$hash: expressionInput}}}]).toArray()[0].hash;
|
|
assert(
|
|
bsonBinaryEqual(actualHash, expectedHash),
|
|
`input=${tojson(expressionInput)}, expected=${expectedHash}, actual=${actualHash}`,
|
|
);
|
|
}
|
|
});
|
|
|
|
it("fails for various inputs", () => {
|
|
for (const {expressionInput, expectedCode} of failureTests) {
|
|
assertErrorCode(coll, [{$project: {hash: {$hash: expressionInput}}}], expectedCode);
|
|
}
|
|
});
|
|
});
|