xref: /5.5.2/couchstore/tests/couchstoretest.cc (revision 21c74097)
1/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2/*
3 *     Copyright 2015 Couchbase, Inc
4 *
5 *   Licensed under the Apache License, Version 2.0 (the "License");
6 *   you may not use this file except in compliance with the License.
7 *   You may obtain a copy of the License at
8 *
9 *       http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *   Unless required by applicable law or agreed to in writing, software
12 *   distributed under the License is distributed on an "AS IS" BASIS,
13 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *   See the License for the specific language governing permissions and
15 *   limitations under the License.
16 */
17
18#include "couchstoretest.h"
19#include <libcouchstore/couch_db.h>
20#include <src/internal.h>
21
22/**
23 * Callback function for latency info.
24 * This is a simple example how to get latency info.
25 */
26int couchstore_test_latency_callback(const char* stat_name,
27                                     CouchLatencyHisto* latencies,
28                                     const CouchLatencyMicroSecRep elapsed_time,
29                                     void* ctx) {
30    (void)ctx;
31    size_t total = latencies->total();
32    std::cout << stat_name;
33    std::cout << ": " << total << " calls, ";
34    std::cout << "avg " << (elapsed_time / total);
35    std::cout << " us" << std::endl;
36    std::stringstream ss;
37    for (auto& itr_hist : *latencies) {
38        if (itr_hist->count()) {
39            ss << "  ";
40            ss << itr_hist->start() << " us";
41            ss << " -- ";
42            ss << itr_hist->end() << " us";
43            ss << ": ";
44            ss << itr_hist->count();
45            ss << std::endl;
46        }
47    }
48    std::cout << ss.str();
49    return 0;
50}
51
52CouchstoreTest::CouchstoreTest()
53    : CouchstoreTest("testfile.couch"){
54}
55
56CouchstoreTest::CouchstoreTest(const std::string& _filePath,
57                               const bool _display_latency_info)
58    : db(nullptr),
59      filePath(_filePath),
60      displayLatencyInfo(_display_latency_info) {
61    couchstore_latency_collector_start();
62    remove(filePath.c_str());
63}
64
65/**
66    Called after each test finishes.
67      - Closes db (if non-null)
68      - Removes testfile.couch
69**/
70CouchstoreTest::~CouchstoreTest() {
71    clean_up();
72    /* make sure os.c didn't accidentally call close(0): */
73#ifndef WIN32
74    EXPECT_TRUE(lseek(0, 0, SEEK_CUR) >= 0 || errno != EBADF);
75#endif
76}
77
78void CouchstoreTest::clean_up() {
79    if (db) {
80        couchstore_close_file(db);
81        couchstore_free_db(db);
82        db = nullptr;
83    }
84
85    if (displayLatencyInfo) {
86        couchstore_latency_dump_options options;
87        couchstore_get_latency_info(couchstore_test_latency_callback,
88                                    options,
89                                    nullptr);
90    }
91    couchstore_latency_collector_stop();
92
93    remove(filePath.c_str());
94}
95
96CouchstoreInternalTest::CouchstoreInternalTest()
97        : CouchstoreTest("testfile_internal.couch"),
98          compactPath("testfile_internal.couch.compact"),
99          documents(Documents(0)),
100          ops(create_default_file_ops()) {
101    remove(compactPath.c_str());
102}
103
104CouchstoreInternalTest::~CouchstoreInternalTest() {
105    // Destruct db here instead of parent so that ops isn't destructed
106    // when we try to destruct the db.
107    clean_up();
108    remove(compactPath.c_str());
109}
110
111couchstore_error_t CouchstoreInternalTest::open_db(couchstore_open_flags extra_flags) {
112    return couchstore_open_db_ex(filePath.c_str(),
113                                 extra_flags | COUCHSTORE_OPEN_FLAG_UNBUFFERED,
114                                 &ops, &db);
115}
116
117
118void CouchstoreInternalTest::open_db_and_populate(couchstore_open_flags extra_flags,
119                                                  size_t count) {
120    ASSERT_EQ(COUCHSTORE_SUCCESS, open_db(extra_flags));
121    documents = Documents(count);
122    documents.generateDocs();
123    ASSERT_EQ(COUCHSTORE_SUCCESS,
124              couchstore_save_documents(db, documents.getDocs(),
125                                        documents.getDocInfos(), count, 0));
126
127}
128
129LocalDoc CouchstoreInternalTest::create_local_doc(std::string& id,
130                                                  std::string& json) {
131    LocalDoc doc;
132    doc.id.buf = &id[0];
133    doc.id.size = strlen(doc.id.buf);
134    doc.json.buf = &json[0];
135    doc.json.size = strlen(doc.json.buf);
136    doc.deleted = 0;
137    return doc;
138}
139
140CouchstoreMTTest::CouchstoreMTTest()
141    : CouchstoreMTTest("testfile_mt.couch") {
142}
143
144CouchstoreMTTest::CouchstoreMTTest(const std::string& _filePath)
145    : numThreads(std::get<1>(GetParam())),
146      dbs(numThreads),
147      filePath(_filePath) {
148}
149
150void CouchstoreMTTest::TearDown() {
151    for (size_t ii=0; ii<numThreads; ++ii) {
152        std::string actual_file_path = filePath + std::to_string(ii);
153        remove(actual_file_path.c_str());
154
155        if (dbs[ii]) {
156            couchstore_close_file(dbs[ii]);
157            couchstore_free_db(dbs[ii]);
158            dbs[ii] = nullptr;
159        }
160    }
161}
162
163