1 // record_store_test_insertrecord.cpp
2 
3 
4 /**
5  *    Copyright (C) 2018-present MongoDB, Inc.
6  *
7  *    This program is free software: you can redistribute it and/or modify
8  *    it under the terms of the Server Side Public License, version 1,
9  *    as published by MongoDB, Inc.
10  *
11  *    This program is distributed in the hope that it will be useful,
12  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *    Server Side Public License for more details.
15  *
16  *    You should have received a copy of the Server Side Public License
17  *    along with this program. If not, see
18  *    <http://www.mongodb.com/licensing/server-side-public-license>.
19  *
20  *    As a special exception, the copyright holders give permission to link the
21  *    code of portions of this program with the OpenSSL library under certain
22  *    conditions as described in each individual source file and distribute
23  *    linked combinations including the program with the OpenSSL library. You
24  *    must comply with the Server Side Public License in all respects for
25  *    all of the code used other than as permitted herein. If you modify file(s)
26  *    with this exception, you may extend this exception to your version of the
27  *    file(s), but you are not obligated to do so. If you do not wish to do so,
28  *    delete this exception statement from your version. If you delete this
29  *    exception statement from all source files in the program, then also delete
30  *    it in the license file.
31  */
32 
33 #include "mongo/platform/basic.h"
34 
35 #include "mongo/db/record_id.h"
36 #include "mongo/db/storage/record_data.h"
37 #include "mongo/db/storage/record_store.h"
38 #include "mongo/db/storage/record_store_test_docwriter.h"
39 #include "mongo/db/storage/record_store_test_harness.h"
40 #include "mongo/unittest/unittest.h"
41 
42 namespace mongo {
43 namespace {
44 
45 using std::string;
46 using std::stringstream;
47 using std::unique_ptr;
48 
49 // Insert a record and verify the number of entries in the collection is 1.
TEST(RecordStoreTestHarness,InsertRecord)50 TEST(RecordStoreTestHarness, InsertRecord) {
51     const auto harnessHelper(newRecordStoreHarnessHelper());
52     unique_ptr<RecordStore> rs(harnessHelper->newNonCappedRecordStore());
53 
54     {
55         ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext());
56         ASSERT_EQUALS(0, rs->numRecords(opCtx.get()));
57     }
58 
59     string data = "my record";
60     RecordId loc;
61     {
62         ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext());
63         {
64             WriteUnitOfWork uow(opCtx.get());
65             StatusWith<RecordId> res =
66                 rs->insertRecord(opCtx.get(), data.c_str(), data.size() + 1, Timestamp(), false);
67             ASSERT_OK(res.getStatus());
68             loc = res.getValue();
69             uow.commit();
70         }
71     }
72 
73     {
74         ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext());
75         ASSERT_EQUALS(1, rs->numRecords(opCtx.get()));
76     }
77 }
78 
79 // Insert multiple records and verify the number of entries in the collection
80 // equals the number that were inserted.
TEST(RecordStoreTestHarness,InsertMultipleRecords)81 TEST(RecordStoreTestHarness, InsertMultipleRecords) {
82     const auto harnessHelper(newRecordStoreHarnessHelper());
83     unique_ptr<RecordStore> rs(harnessHelper->newNonCappedRecordStore());
84 
85     {
86         ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext());
87         ASSERT_EQUALS(0, rs->numRecords(opCtx.get()));
88     }
89 
90     const int nToInsert = 10;
91     RecordId locs[nToInsert];
92     for (int i = 0; i < nToInsert; i++) {
93         ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext());
94         {
95             stringstream ss;
96             ss << "record " << i;
97             string data = ss.str();
98 
99             WriteUnitOfWork uow(opCtx.get());
100             StatusWith<RecordId> res =
101                 rs->insertRecord(opCtx.get(), data.c_str(), data.size() + 1, Timestamp(), false);
102             ASSERT_OK(res.getStatus());
103             locs[i] = res.getValue();
104             uow.commit();
105         }
106     }
107 
108     {
109         ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext());
110         ASSERT_EQUALS(nToInsert, rs->numRecords(opCtx.get()));
111     }
112 }
113 
114 // Insert a record using a DocWriter and verify the number of entries
115 // in the collection is 1.
TEST(RecordStoreTestHarness,InsertRecordUsingDocWriter)116 TEST(RecordStoreTestHarness, InsertRecordUsingDocWriter) {
117     const auto harnessHelper(newRecordStoreHarnessHelper());
118     unique_ptr<RecordStore> rs(harnessHelper->newNonCappedRecordStore());
119 
120     {
121         ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext());
122         ASSERT_EQUALS(0, rs->numRecords(opCtx.get()));
123     }
124 
125     RecordId loc;
126     {
127         ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext());
128         {
129             StringDocWriter docWriter("my record", false);
130 
131             WriteUnitOfWork uow(opCtx.get());
132             StatusWith<RecordId> res =
133                 rs->insertRecordWithDocWriter(opCtx.get(), &docWriter, Timestamp(1));
134             ASSERT_OK(res.getStatus());
135             loc = res.getValue();
136             uow.commit();
137         }
138     }
139 
140     {
141         ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext());
142         ASSERT_EQUALS(1, rs->numRecords(opCtx.get()));
143     }
144 }
145 
146 // Insert multiple records using a DocWriter and verify the number of entries
147 // in the collection equals the number that were inserted.
TEST(RecordStoreTestHarness,InsertMultipleRecordsUsingDocWriter)148 TEST(RecordStoreTestHarness, InsertMultipleRecordsUsingDocWriter) {
149     const auto harnessHelper(newRecordStoreHarnessHelper());
150     unique_ptr<RecordStore> rs(harnessHelper->newNonCappedRecordStore());
151 
152     {
153         ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext());
154         ASSERT_EQUALS(0, rs->numRecords(opCtx.get()));
155     }
156 
157     const int nToInsert = 10;
158     RecordId locs[nToInsert];
159     for (int i = 0; i < nToInsert; i++) {
160         ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext());
161         {
162             stringstream ss;
163             ss << "record " << i;
164             StringDocWriter docWriter(ss.str(), false);
165 
166             WriteUnitOfWork uow(opCtx.get());
167             StatusWith<RecordId> res =
168                 rs->insertRecordWithDocWriter(opCtx.get(), &docWriter, Timestamp(1));
169             ASSERT_OK(res.getStatus());
170             locs[i] = res.getValue();
171             uow.commit();
172         }
173     }
174 
175     {
176         ServiceContext::UniqueOperationContext opCtx(harnessHelper->newOperationContext());
177         ASSERT_EQUALS(nToInsert, rs->numRecords(opCtx.get()));
178     }
179 }
180 
181 }  // namespace
182 }  // namespace mongo
183