@@ -14,6 +14,7 @@ const MongoUtils = require('../../../../../lib/storage/metadata/mongoclient/util
1414const ObjectMD = require ( '../../../../../lib/models/ObjectMD' ) . default ;
1515const { BucketVersioningKeyFormat } = require ( '../../../../../lib/versioning/constants' ) . VersioningConstants ;
1616const { formatMasterKey } = require ( '../../../../../lib/storage/metadata/mongoclient/utils' ) ;
17+ const { promisify } = require ( 'util' ) ;
1718
1819const dbName = 'metadata' ;
1920const baseBucket = BucketInfo . fromObj ( {
@@ -716,15 +717,27 @@ describe('MongoClientInterface, tests', () => {
716717 assert . ok ( retrievedCapacityInfo , 'VeeamSOSApi.CapacityInfo should exist' ) ;
717718
718719 assert . strictEqual ( typeof retrievedCapacityInfo . Capacity , 'bigint' , 'Capacity should be a bigint' ) ;
719- assert . strictEqual ( retrievedCapacityInfo . Capacity . toString ( ) , veeamCapacity . Capacity , 'Capacity value mismatch' ) ;
720+ assert . strictEqual (
721+ retrievedCapacityInfo . Capacity . toString ( ) ,
722+ veeamCapacity . Capacity ,
723+ 'Capacity value mismatch' ,
724+ ) ;
720725
721726 assert . strictEqual ( typeof retrievedCapacityInfo . Available , 'bigint' , 'Available should be a bigint' ) ;
722- assert . strictEqual ( retrievedCapacityInfo . Available . toString ( ) , veeamCapacity . Available , 'Available value mismatch' ) ;
727+ assert . strictEqual (
728+ retrievedCapacityInfo . Available . toString ( ) ,
729+ veeamCapacity . Available ,
730+ 'Available value mismatch' ,
731+ ) ;
723732
724733 assert . strictEqual ( typeof retrievedCapacityInfo . Used , 'bigint' , 'Used should be a bigint' ) ;
725734 assert . strictEqual ( retrievedCapacityInfo . Used . toString ( ) , veeamCapacity . Used , 'Used value mismatch' ) ;
726735
727- assert . strictEqual ( retrievedCapacityInfo . LastModified , veeamCapacity . LastModified , 'LastModified value mismatch' ) ;
736+ assert . strictEqual (
737+ retrievedCapacityInfo . LastModified ,
738+ veeamCapacity . LastModified ,
739+ 'LastModified value mismatch' ,
740+ ) ;
728741 done ( ) ;
729742 } ) ;
730743 } ) ;
@@ -895,6 +908,9 @@ describe('MongoClientInterface, putObjectVerCase4', () => {
895908 if ( err ) {
896909 return done ( err ) ;
897910 }
911+
912+ client . putObjectVerCase4Promised = promisify ( client . putObjectVerCase4 ) . bind ( client ) ;
913+
898914 return createBucket ( client , bucketName , true , err => {
899915 if ( err ) {
900916 return done ( err ) ;
@@ -1102,6 +1118,65 @@ describe('MongoClientInterface, putObjectVerCase4', () => {
11021118 } ,
11031119 ) ;
11041120 } ) ;
1121+
1122+ it ( 'should handle missing versionId ($exists: false) in putObjectVerCase4 to update master' , async ( ) => {
1123+ const objName = 'test-object' ;
1124+ const versionId = 'test-version-id' ;
1125+ const objMD = new ObjectMD ( )
1126+ . setKey ( objName )
1127+ . setDataStoreName ( 'us-east-1' )
1128+ . setContentLength ( 100 )
1129+ . setLastModified ( new Date ( ) ) ;
1130+
1131+ const updateOneStub = sandbox . stub ( collection , 'updateOne' ) . resolves ( { modifiedCount : 1 } ) ;
1132+
1133+ sandbox . stub ( client , 'getLatestVersion' ) . callsFake ( ( c , objName , vFormat , log , cb ) => {
1134+ cb ( null , objMD . getValue ( ) ) ;
1135+ } ) ;
1136+
1137+ const bulkWriteStub = sandbox . stub ( collection , 'bulkWrite' ) . resolves ( {
1138+ modifiedCount : 1 ,
1139+ upsertedCount : 1 ,
1140+ matchedCount : 1 ,
1141+ } ) ;
1142+
1143+ const params = {
1144+ vFormat : BucketVersioningKeyFormat . v1 ,
1145+ versionId,
1146+ repairMaster : true ,
1147+ versioning : true ,
1148+ needOplogUpdate : false ,
1149+ originOp : 'test' ,
1150+ conditions : { } ,
1151+ } ;
1152+
1153+ const result = await client . putObjectVerCase4Promised (
1154+ collection ,
1155+ bucketName ,
1156+ objName ,
1157+ objMD . getValue ( ) ,
1158+ params ,
1159+ logger ,
1160+ ) ;
1161+
1162+ assert ( result , 'Expected result on success' ) ;
1163+ assert . strictEqual (
1164+ result ,
1165+ `{"versionId": "undefined"}` ,
1166+ 'Expected versionId in result' ,
1167+ ) ;
1168+ assert ( updateOneStub . calledOnce , 'Expected updateOne to be called' ) ;
1169+ assert ( bulkWriteStub . calledOnce , 'Expected bulkWrite to be called' ) ;
1170+ const bulkOps = bulkWriteStub . firstCall . args [ 0 ] ;
1171+ const masterUpdateOp = bulkOps . find (
1172+ op => op . updateOne && op . updateOne . filter . _id === formatMasterKey ( objName , BucketVersioningKeyFormat . v1 )
1173+ ) ;
1174+ assert ( masterUpdateOp , 'Expected master update operation' ) ;
1175+ assert (
1176+ masterUpdateOp . updateOne . filter . $or [ 0 ] [ 'value.versionId' ] . $exists === false ,
1177+ 'Expected filter to check for non-existing versionId'
1178+ ) ;
1179+ } ) ;
11051180} ) ;
11061181
11071182describe ( 'MongoClientInterface, putObjectNoVer' , ( ) => {
@@ -1470,7 +1545,7 @@ describe('MongoClientInterface, writeUUIDIfNotExists', () => {
14701545
14711546 sandbox . stub ( client , 'getCollection' ) . returns ( mockCollection ) ;
14721547
1473- client . writeUUIDIfNotExists ( 'test-uuid' , logger , ( err ) => {
1548+ client . writeUUIDIfNotExists ( 'test-uuid' , logger , err => {
14741549 try {
14751550 assert ( err , 'Expected an error to be returned' ) ;
14761551 assert . strictEqual ( err . code , 500 , 'Expected 500 error code' ) ;
@@ -1491,7 +1566,7 @@ describe('MongoClientInterface, writeUUIDIfNotExists', () => {
14911566
14921567 sandbox . stub ( client , 'getCollection' ) . returns ( mockCollection ) ;
14931568
1494- client . writeUUIDIfNotExists ( 'test-uuid' , logger , ( err ) => {
1569+ client . writeUUIDIfNotExists ( 'test-uuid' , logger , err => {
14951570 try {
14961571 assert ( err , 'Expected an error to be returned' ) ;
14971572 assert . strictEqual ( err . code , 409 , 'Expected KeyAlreadyExists error' ) ;
0 commit comments