1 
2 /**
3  *    Copyright (C) 2018-present MongoDB, Inc.
4  *
5  *    This program is free software: you can redistribute it and/or modify
6  *    it under the terms of the Server Side Public License, version 1,
7  *    as published by MongoDB, Inc.
8  *
9  *    This program is distributed in the hope that it will be useful,
10  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *    Server Side Public License for more details.
13  *
14  *    You should have received a copy of the Server Side Public License
15  *    along with this program. If not, see
16  *    <http://www.mongodb.com/licensing/server-side-public-license>.
17  *
18  *    As a special exception, the copyright holders give permission to link the
19  *    code of portions of this program with the OpenSSL library under certain
20  *    conditions as described in each individual source file and distribute
21  *    linked combinations including the program with the OpenSSL library. You
22  *    must comply with the Server Side Public License in all respects for
23  *    all of the code used other than as permitted herein. If you modify file(s)
24  *    with this exception, you may extend this exception to your version of the
25  *    file(s), but you are not obligated to do so. If you do not wish to do so,
26  *    delete this exception statement from your version. If you delete this
27  *    exception statement from all source files in the program, then also delete
28  *    it in the license file.
29  */
30 
31 #pragma once
32 
33 #include "mongo/db/logical_clock.h"
34 #include "mongo/db/service_context_noop.h"
35 #include "mongo/db/update/update_node.h"
36 #include "mongo/unittest/unittest.h"
37 
38 namespace mongo {
39 
40 class UpdateNodeTest : public mongo::unittest::Test {
41 public:
42     ~UpdateNodeTest() override = default;
43 
44 protected:
setUp()45     void setUp() override {
46         resetApplyParams();
47 
48         // Set up the logical clock needed by CurrentDateNode and ObjectReplaceNode.
49         auto service = mongo::getGlobalServiceContext();
50         auto logicalClock = mongo::stdx::make_unique<mongo::LogicalClock>(service);
51         mongo::LogicalClock::set(service, std::move(logicalClock));
52     }
53 
resetApplyParams()54     void resetApplyParams() {
55         _immutablePathsVector.clear();
56         _immutablePaths.clear();
57         _pathToCreate = std::make_shared<FieldRef>();
58         _pathTaken = std::make_shared<FieldRef>();
59         _matchedField = StringData();
60         _insert = false;
61         _fromOplogApplication = false;
62         _validateForStorage = true;
63         _indexData.reset();
64         _logDoc.reset();
65         _logBuilder = stdx::make_unique<LogBuilder>(_logDoc.root());
66     }
67 
getApplyParams(mutablebson::Element element)68     UpdateNode::ApplyParams getApplyParams(mutablebson::Element element) {
69         UpdateNode::ApplyParams applyParams(element, _immutablePaths);
70         applyParams.pathToCreate = _pathToCreate;
71         applyParams.pathTaken = _pathTaken;
72         applyParams.matchedField = _matchedField;
73         applyParams.insert = _insert;
74         applyParams.fromOplogApplication = _fromOplogApplication;
75         applyParams.validateForStorage = _validateForStorage;
76         applyParams.indexData = _indexData.get();
77         applyParams.logBuilder = _logBuilder.get();
78         return applyParams;
79     }
80 
addImmutablePath(StringData path)81     void addImmutablePath(StringData path) {
82         auto fieldRef = stdx::make_unique<FieldRef>(path);
83         _immutablePathsVector.push_back(std::move(fieldRef));
84         _immutablePaths.insert(_immutablePathsVector.back().get());
85     }
86 
setPathToCreate(StringData path)87     void setPathToCreate(StringData path) {
88         _pathToCreate->clear();
89         _pathToCreate->parse(path);
90     }
91 
setPathTaken(StringData path)92     void setPathTaken(StringData path) {
93         _pathTaken->clear();
94         _pathTaken->parse(path);
95     }
96 
setMatchedField(StringData matchedField)97     void setMatchedField(StringData matchedField) {
98         _matchedField = matchedField;
99     }
100 
setInsert(bool insert)101     void setInsert(bool insert) {
102         _insert = insert;
103     }
104 
setFromOplogApplication(bool fromOplogApplication)105     void setFromOplogApplication(bool fromOplogApplication) {
106         _fromOplogApplication = fromOplogApplication;
107     }
108 
setValidateForStorage(bool validateForStorage)109     void setValidateForStorage(bool validateForStorage) {
110         _validateForStorage = validateForStorage;
111     }
112 
addIndexedPath(StringData path)113     void addIndexedPath(StringData path) {
114         if (!_indexData) {
115             _indexData = stdx::make_unique<UpdateIndexData>();
116         }
117         _indexData->addPath(path);
118     }
119 
setLogBuilderToNull()120     void setLogBuilderToNull() {
121         _logBuilder.reset();
122     }
123 
getLogDoc()124     const mutablebson::Document& getLogDoc() {
125         return _logDoc;
126     }
127 
128 private:
129     std::vector<std::unique_ptr<FieldRef>> _immutablePathsVector;
130     FieldRefSet _immutablePaths;
131     std::shared_ptr<FieldRef> _pathToCreate;
132     std::shared_ptr<FieldRef> _pathTaken;
133     StringData _matchedField;
134     bool _insert;
135     bool _fromOplogApplication;
136     bool _validateForStorage;
137     std::unique_ptr<UpdateIndexData> _indexData;
138     mutablebson::Document _logDoc;
139     std::unique_ptr<LogBuilder> _logBuilder;
140 };
141 
142 }  // namespace mongo
143