1403e0c68096580135973c9240d561809e534f4e
[ep-engine.git] / tests / module_tests / evp_engine_test.cc
1 /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3  *     Copyright 2016 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 /*
19  * Unit tests for the EventuallyPersistentEngine class.
20  */
21
22 #include "evp_engine_test.h"
23
24 #include "ep_engine.h"
25 #include "programs/engine_testapp/mock_server.h"
26 #include "tests/module_tests/test_helpers.h"
27
28 #include <configuration_impl.h>
29 #include <platform/dirutils.h>
30
31 void EventuallyPersistentEngineTest::SetUp() {
32     // Paranoia - kill any existing files in case they are left over
33     // from a previous run.
34     cb::io::rmrf(test_dbname);
35
36     // Setup an engine with a single active vBucket.
37     EXPECT_EQ(ENGINE_SUCCESS,
38               create_instance(1, get_mock_server_api, &handle))
39         << "Failed to create ep engine instance";
40     EXPECT_EQ(1, handle->interface) << "Unexpected engine handle version";
41     engine_v1 = reinterpret_cast<ENGINE_HANDLE_V1*>(handle);
42
43     engine = reinterpret_cast<EventuallyPersistentEngine*>(handle);
44     ObjectRegistry::onSwitchThread(engine);
45
46     // Add dbname to config string.
47     std::string config = config_string;
48     if (config.size() > 0) {
49         config += ";";
50     }
51     config += "dbname=" + std::string(test_dbname);
52
53     // Set the bucketType
54     config += ";bucket_type=" + bucketType;
55
56     EXPECT_EQ(ENGINE_SUCCESS, engine->initialize(config.c_str()))
57         << "Failed to initialize engine.";
58
59     // Wait for warmup to complete.
60     while (engine->getKVBucket()->isWarmingUp()) {
61         usleep(10);
62     }
63
64     // Once warmup is complete, set VB to active.
65     engine->setVBucketState(vbid, vbucket_state_active, false);
66 }
67
68 void EventuallyPersistentEngineTest::TearDown() {
69     // Need to force the destroy (i.e. pass true) because
70     // NonIO threads may have been disabled (see DCPTest subclass).
71     engine_v1->destroy(handle, true);
72     destroy_mock_event_callbacks();
73     destroy_engine();
74     // Cleanup any files we created.
75     cb::io::rmrf(test_dbname);
76 }
77
78 void EventuallyPersistentEngineTest::store_item(uint16_t vbid,
79                                                 const std::string& key,
80                                                 const std::string& value) {
81     Item item(makeStoredDocKey(key), /*flags*/0, /*exp*/0, value.c_str(),
82               value.size(), nullptr/*extmeta*/, 0/*extlen*/, 0/*cas*/,
83               -1/*seqno*/, vbid);
84     uint64_t cas;
85     EXPECT_EQ(ENGINE_SUCCESS,
86               engine->store(NULL, &item, &cas, OPERATION_SET));
87 }
88
89 const char EventuallyPersistentEngineTest::test_dbname[] = "ep_engine_ep_unit_tests_db";
90
91
92 TEST_P(SetParamTest, requirements_bucket_type) {
93     std::string bucketType = engine->getConfiguration().getBucketType();
94
95     struct value_t {
96         std::string param;
97         std::string value;
98         std::string bucketType;
99     };
100
101     std::vector<value_t> values{
102             // Parameter, Example value, applicable bucket
103             {"access_scanner_enabled", "true", "persistent"},
104             {"alog_sleep_time", "1441", "persistent"},
105             {"alog_task_time", "3", "persistent"},
106             {"ephemeral_full_policy", "auto_delete", "ephemeral"},
107     };
108
109     std::string msg;
110
111     for (auto v : values) {
112         auto ret = engine->setFlushParam(v.param.c_str(), v.value.c_str(), msg);
113         if (bucketType == v.bucketType) {
114             EXPECT_EQ(PROTOCOL_BINARY_RESPONSE_SUCCESS, ret)
115                     << "Parameter " << v.param
116                     << "could not be set on bucket type \"" << bucketType
117                     << "\"";
118         } else {
119             EXPECT_EQ(PROTOCOL_BINARY_RESPONSE_EINVAL, ret)
120                     << "Setting parameter " << v.param
121                     << "should be invalid for bucket type \"" << bucketType
122                     << "\"";
123         }
124     }
125 }
126
127 TEST_F(EventuallyPersistentEngineTest, requirements_tap) {
128     Configuration& config = engine->getConfiguration();
129     config.setTap(true);
130
131     std::string msg;
132
133     EXPECT_EQ(PROTOCOL_BINARY_RESPONSE_SUCCESS,
134               engine->setTapParam("tap_keepalive", "0", msg))
135             << "tap is enabled but \"tap_keepalive\" could not be set";
136
137     config.setTap(false);
138
139     EXPECT_EQ(PROTOCOL_BINARY_RESPONSE_EINVAL,
140               engine->setTapParam("tap_keepalive", "0", msg))
141             << "Setting \"tap_keepalive\" should be invalid if tap is disabled";
142 }
143
144 // Test cases which run for persistent and ephemeral buckets
145 INSTANTIATE_TEST_CASE_P(EphemeralOrPersistent,
146                         SetParamTest,
147                         ::testing::Values("persistent", "ephemeral"),
148                         [](const ::testing::TestParamInfo<std::string>& info) {
149                             return info.param;
150                         });