aboutsummaryrefslogtreecommitdiffstats
path: root/yt/cpp/mapreduce/tests/yt_unittest_lib/yt_unittest_lib.h
blob: 237fa0abbe47acf8ccba6cb9dfe79c0d3d501ddc (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#pragma once

#include <yt/cpp/mapreduce/interface/logging/logger.h>
#include <yt/cpp/mapreduce/interface/client.h>

#include <yt/cpp/mapreduce/interface/config.h>

#include <library/cpp/yson/node/node_io.h>

#include <util/generic/bt_exception.h>

#include <util/datetime/base.h>

////////////////////////////////////////////////////////////////////////////////

template<>
void Out<NYT::TNode>(IOutputStream& s, const NYT::TNode& node);

template<>
void Out<TGUID>(IOutputStream& s, const TGUID& guid);

////////////////////////////////////////////////////////////////////////////////

namespace NYT {
namespace NTesting {

////////////////////////////////////////////////////////////////////////////////

IClientPtr CreateTestClient(TString proxy = "", const TCreateClientOptions& options = {});

// Create map node by unique path in Cypress and return that path.
TYPath CreateTestDirectory(const IClientBasePtr& client);

TString GenerateRandomData(size_t size, ui64 seed = 42);

TVector<TNode> ReadTable(const IClientBasePtr& client, const TString& tablePath);
void WriteTable(const IClientBasePtr& client, const TString& tablePath, const std::vector<TNode>& rowList);

////////////////////////////////////////////////////////////////////////////////

// TODO: should be removed, usages should be replaced with TConfigSaverGuard
class TZeroWaitLockPollIntervalGuard
{
public:
    TZeroWaitLockPollIntervalGuard();

    ~TZeroWaitLockPollIntervalGuard();

private:
    TDuration OldWaitLockPollInterval_;
};

////////////////////////////////////////////////////////////////////////////////

class TConfigSaverGuard
{
public:
    TConfigSaverGuard();
    ~TConfigSaverGuard();

private:
    TConfig Config_;
};

////////////////////////////////////////////////////////////////////////////////

class TDebugMetricDiff
{
public:
    TDebugMetricDiff(TString name);
    ui64 GetTotal() const;

private:
    TString Name_;
    ui64 InitialValue_;
};

////////////////////////////////////////////////////////////////////////////////

struct TOwningYaMRRow
{
    TString Key;
    TString SubKey;
    TString Value;

    TOwningYaMRRow(const TYaMRRow& row = {});
    TOwningYaMRRow(TString key, TString subKey, TString value);

    operator TYaMRRow() const;
};

bool operator == (const TOwningYaMRRow& row1, const TOwningYaMRRow& row2);

////////////////////////////////////////////////////////////////////////////////

class TTestFixture
{
public:
    explicit TTestFixture(const TCreateClientOptions& options = {});
    ~TTestFixture();

    // Return precreated client.
    IClientPtr GetClient() const;

    // Return newly created client. Useful for cases:
    //  - when we want to have multiple clients objects;
    //  - when we want to control to control destruction of client object;
    IClientPtr CreateClient(const TCreateClientOptions& options = {}) const;

    IClientPtr CreateClientForUser(const TString& user, TCreateClientOptions options = {});

    TYPath GetWorkingDir() const;

    static TString GetYtProxy();

private:
    TConfigSaverGuard ConfigGuard_;
    IClientPtr Client_;
    TYPath WorkingDir_;
};

////////////////////////////////////////////////////////////////////////////////

class TTabletFixture
    : public TTestFixture
{
public:
    TTabletFixture();

private:
    void WaitForTabletCell();
};

////////////////////////////////////////////////////////////////////////////////

// Compares only columns and only "name" and "type" fields of columns.
bool AreSchemasEqual(const TTableSchema& lhs, const TTableSchema& rhs);

class TWaitFailedException
    : public TWithBackTrace<yexception>
{ };

void WaitForPredicate(const std::function<bool()>& predicate, TDuration timeout = TDuration::Seconds(60));

////////////////////////////////////////////////////////////////////////////////

// Redirects all the LOG_* calls with the corresponding level to `stream`.
// Moreover, the LOG_* calls are delegated to `oldLogger`.
class TStreamTeeLogger
    : public ILogger
{
public:
    TStreamTeeLogger(ELevel cutLevel, IOutputStream* stream, ILoggerPtr oldLogger);
    void Log(ELevel level, const ::TSourceLocation& sourceLocation, const char* format, va_list args) override;

private:
    ILoggerPtr OldLogger_;
    IOutputStream* Stream_;
    ELevel Level_;
};

////////////////////////////////////////////////////////////////////////////////

template <typename T>
TString ToYson(const T& x)
{
    TNode result;
    TNodeBuilder builder(&result);
    Serialize(x, &builder);
    return NodeToYsonString(result);
}

////////////////////////////////////////////////////////////////////////////////

} // namespace NTesting
} // namespace NYT

////////////////////////////////////////////////////////////////////////////////

template <>
void Out<NYT::NTesting::TOwningYaMRRow>(IOutputStream& out, const NYT::NTesting::TOwningYaMRRow& row);

////////////////////////////////////////////////////////////////////////////////

// for UNITTEST()
#define ASSERT_SERIALIZABLES_EQUAL(a, b) \
    UNIT_ASSERT_EQUAL_C(a, b, NYT::NTesting::ToYson(a) << " != " << NYT::NTesting::ToYson(b))

#define ASSERT_SERIALIZABLES_UNEQUAL(a, b) \
    UNIT_ASSERT_UNEQUAL_C(a, b, NYT::NTesting::ToYson(a) << " == " << NYT::NTesting::ToYson(b))

// for GTEST()
#define ASSERT_SERIALIZABLES_EQ(a, b) \
    ASSERT_EQ(a, b) << NYT::NTesting::ToYson(a) << " != " << NYT::NTesting::ToYson(b)

#define ASSERT_SERIALIZABLES_NE(a, b) \
    ASSERT_NE(a, b) << NYT::NTesting::ToYson(a) << " == " << NYT::NTesting::ToYson(b)