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#include <vector>
19
20#include <gmock/gmock.h>
21#include <gtest/gtest.h>
22
23#include "phosphor/trace_config.h"
24
25using namespace phosphor;
26
27#ifdef _WIN32
28int setenv(const char* name, const char* value, int overwrite);
29#endif
30
31TEST(TraceLogConfigTest, chunk_lock_count) {
32    TraceLogConfig config;
33    EXPECT_EQ(88, config.setChunkLockCount(88).getChunkLockCount());
34    EXPECT_EQ(33, config.setChunkLockCount(33).getChunkLockCount());
35}
36
37TEST(TraceLogConfigTest, startup_trace) {
38    TraceLogConfig config;
39    TraceConfig trace_config(BufferMode::fixed, 10000);
40    EXPECT_EQ(10000,
41              config.setStartupTrace(trace_config)
42                      .getStartupTrace()
43                      ->getBufferSize());
44    EXPECT_EQ(nullptr,
45              config.setStartupTrace(trace_config)
46                      .clearStartupTrace()
47                      .getStartupTrace());
48}
49
50TEST(TraceLogConfigTest, from_environment) {
51    setenv("PHOSPHOR_CHUNK_LOCK_COUNT", "5", true);
52    TraceLogConfig config;
53    config.fromEnvironment();
54    EXPECT_EQ(5, config.getChunkLockCount());
55
56    for (const auto& str : {"abdc", "99999999999999999", "-1"}) {
57        setenv("PHOSPHOR_CHUNK_LOCK_COUNT", str, true);
58        EXPECT_THROW(config.fromEnvironment(), std::invalid_argument);
59    }
60    setenv("PHOSPHOR_CHUNK_LOCK_COUNT", "", true);
61    EXPECT_NO_THROW(config.fromEnvironment());
62}
63
64TEST(TraceConfigTest, defaultConstructor) {
65    TraceConfig config;
66}
67
68TEST(TraceConfigTest, createFixed) {
69    TraceConfig config(BufferMode::fixed, 1337);
70
71    /* Check that we get a fixed buffer factory */
72    auto bufferA = make_fixed_buffer(0, 0);
73    auto& bufferARef = *bufferA;
74    auto bufferB = config.getBufferFactory()(0, 0);
75    auto& bufferBRef = *bufferB;
76
77    if (typeid(bufferARef) != typeid(bufferBRef)) {
78        FAIL();
79    }
80
81    EXPECT_EQ(1337, config.getBufferSize());
82    EXPECT_EQ(BufferMode::fixed, config.getBufferMode());
83}
84
85TEST(TraceConfigTest, createRing) {
86    TraceConfig config(BufferMode::ring, 1337);
87
88    /* Check that we get a ring buffer factory */
89    auto bufferA = make_ring_buffer(0, 1);
90    auto& bufferARef = *bufferA;
91    auto bufferB = config.getBufferFactory()(0, 1);
92    auto& bufferBRef = *bufferB;
93
94    if (typeid(bufferARef) != typeid(bufferBRef)) {
95        FAIL();
96    }
97
98    EXPECT_EQ(1337, config.getBufferSize());
99    EXPECT_EQ(BufferMode::ring, config.getBufferMode());
100}
101
102TEST(TraceConfigTest, createCustom) {
103    TraceConfig config(make_fixed_buffer, 1337);
104
105    /* Check that we get a fixed buffer factory */
106    auto bufferA = make_fixed_buffer(0, 0);
107    auto& bufferARef = *bufferA;
108    auto bufferB = config.getBufferFactory()(0, 0);
109    auto& bufferBRef = *bufferB;
110
111    if (typeid(bufferARef) != typeid(bufferBRef)) {
112        FAIL();
113    }
114
115    EXPECT_EQ(BufferMode::custom, config.getBufferMode());
116}
117
118TEST(TraceConfigTest, createModeErrors) {
119    EXPECT_THROW(TraceConfig(BufferMode::custom, 1337), std::invalid_argument);
120    EXPECT_THROW(TraceConfig(static_cast<BufferMode>(0xFF), 1337),
121                 std::invalid_argument);
122}
123
124TEST(TraceConfigTest, CategoryConfig) {
125    TraceConfig config(BufferMode::fixed, 1337);
126    config.setCategories({{"hello"}}, {{"world"}});
127    EXPECT_THAT(config.getEnabledCategories(), testing::ElementsAre("hello"));
128    EXPECT_THAT(config.getDisabledCategories(), testing::ElementsAre("world"));
129}
130
131TEST(TraceConfigTest, fromString) {
132    TraceConfig config = TraceConfig::fromString(
133            "buffer-mode:ring;"
134                    "buffer-size:1024;"
135                    "save-on-stop:out.json;"
136                    "enabled-categories:hello,world;"
137                    "disabled-categories:*rld");
138
139    EXPECT_EQ(BufferMode::ring, config.getBufferMode());
140    EXPECT_EQ(1024, config.getBufferSize());
141    EXPECT_TRUE(config.getStoppedCallback());
142    EXPECT_TRUE(config.getStopTracingOnDestruct());
143    EXPECT_THAT(config.getEnabledCategories(),
144                testing::ElementsAre("hello", "world"));
145    EXPECT_THAT(config.getDisabledCategories(), testing::ElementsAre("*rld"));
146
147    EXPECT_FALSE(TraceConfig::fromString("buffer-mode:fixed;"
148                                                 "buffer-size:1024;")
149                         .getStopTracingOnDestruct());
150
151    EXPECT_THROW(TraceConfig::fromString("buffer-mode:other"),
152                 std::invalid_argument);
153    EXPECT_THROW(TraceConfig::fromString("buffer-size:-1"),
154                 std::invalid_argument);
155    EXPECT_THROW(TraceConfig::fromString("buffer-size:999999999999999999"),
156                 std::invalid_argument);
157    EXPECT_THROW(TraceConfig::fromString("buffer-size:abcd"),
158                 std::invalid_argument);
159}
160
161TEST(TraceConfigTest, toString) {
162    TraceConfig config(BufferMode::fixed, 1337);
163    config.setCategories({{"hello"}}, {{"world"}});
164    EXPECT_EQ("buffer-mode:fixed;buffer-size:1337;"
165                      "enabled-categories:hello;disabled-categories:world",
166              *config.toString());
167
168    TraceConfig config2(BufferMode::ring, 0);
169    EXPECT_EQ("buffer-mode:ring;buffer-size:0;"
170                      "enabled-categories:*;disabled-categories:",
171              *config2.toString());
172
173    TraceConfig config3(make_fixed_buffer, 1337);
174    EXPECT_EQ("buffer-mode:custom;buffer-size:1337;"
175                      "enabled-categories:*;disabled-categories:",
176              *config3.toString());
177}
178