2017-03-22 22:53:30 +08:00
|
|
|
#include <array>
|
|
|
|
#include <cstring>
|
2017-10-17 20:05:08 +08:00
|
|
|
#include <functional>
|
2017-03-22 22:53:30 +08:00
|
|
|
#include <iostream>
|
2017-08-03 21:26:48 +08:00
|
|
|
#include <random>
|
2017-03-22 22:53:30 +08:00
|
|
|
#include <vector>
|
|
|
|
|
2017-06-21 17:29:13 +08:00
|
|
|
#include <glog/logging.h>
|
Extract communication to static library
Summary:
Session specifics have been move out of the Bolt `executing` state, and
are accessed via pure virtual Session type. Our server is templated on
the session and we are setting the concrete type, so there should be no
virtual call overhead. Abstract Session is used to indicate the
interface, this could have also been templated, but the explicit
interface definition makes it clearer.
Specific session implementation for running Memgraph is now implemented
in memgraph_bolt, which instantiates the concrete session type. This may
not be 100% appropriate place, but Memgraph specific session isn't
needed anywhere else.
Bolt/communication tests now use a dummy session and depend only on
communication, which significantly improves test run times.
All these changes make the communication a library which doesn't depend
on storage nor the database. Only shared connection points, which aren't
part of the base communication library are:
* glue/conversion -- which converts between storage and bolt types, and
* communication/result_stream_faker -- templated, but used in tests and query/repl
Depends on D1453
Reviewers: mferencevic, buda, mtomic, msantl
Reviewed By: mferencevic, mtomic
Subscribers: pullbot
Differential Revision: https://phabricator.memgraph.io/D1456
2018-07-10 22:18:19 +08:00
|
|
|
#include <gtest/gtest.h>
|
2017-03-22 22:53:30 +08:00
|
|
|
|
2017-03-28 18:42:04 +08:00
|
|
|
/**
|
|
|
|
* TODO (mferencevic): document
|
|
|
|
*/
|
2018-03-23 23:32:17 +08:00
|
|
|
class TestInputStream {
|
2017-03-22 22:53:30 +08:00
|
|
|
public:
|
2018-03-23 23:32:17 +08:00
|
|
|
uint8_t *data() { return data_.data(); }
|
2017-03-22 22:53:30 +08:00
|
|
|
|
2018-03-23 23:32:17 +08:00
|
|
|
size_t size() { return data_.size(); }
|
2017-03-22 22:53:30 +08:00
|
|
|
|
2018-03-23 23:32:17 +08:00
|
|
|
void Clear() { data_.clear(); }
|
|
|
|
|
|
|
|
void Write(const uint8_t *data, size_t len) {
|
|
|
|
for (size_t i = 0; i < len; ++i) {
|
|
|
|
data_.push_back(data[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Write(const char *data, size_t len) {
|
|
|
|
Write(reinterpret_cast<const uint8_t *>(data), len);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Shift(size_t count) {
|
|
|
|
CHECK(count <= data_.size());
|
|
|
|
data_.erase(data_.begin(), data_.begin() + count);
|
|
|
|
}
|
|
|
|
|
2018-07-12 17:44:59 +08:00
|
|
|
void Resize(size_t len) {}
|
|
|
|
|
2018-03-23 23:32:17 +08:00
|
|
|
private:
|
|
|
|
std::vector<uint8_t> data_;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* TODO (mferencevic): document
|
|
|
|
*/
|
|
|
|
class TestOutputStream {
|
|
|
|
public:
|
|
|
|
bool Write(const uint8_t *data, size_t len, bool have_more = false) {
|
2017-04-15 21:14:12 +08:00
|
|
|
if (!write_success_) return false;
|
2017-03-28 18:42:04 +08:00
|
|
|
for (size_t i = 0; i < len; ++i) output.push_back(data[i]);
|
2017-04-15 21:14:12 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2017-06-21 17:29:13 +08:00
|
|
|
void SetWriteSuccess(bool success) { write_success_ = success; }
|
2017-03-22 22:53:30 +08:00
|
|
|
|
|
|
|
std::vector<uint8_t> output;
|
|
|
|
|
|
|
|
protected:
|
2017-04-15 21:14:12 +08:00
|
|
|
bool write_success_{true};
|
2017-03-22 22:53:30 +08:00
|
|
|
};
|
|
|
|
|
2017-03-28 18:42:04 +08:00
|
|
|
/**
|
|
|
|
* TODO (mferencevic): document
|
|
|
|
*/
|
|
|
|
class TestBuffer {
|
|
|
|
public:
|
2018-04-22 14:31:09 +08:00
|
|
|
explicit TestBuffer(TestOutputStream &output_stream)
|
|
|
|
: output_stream_(output_stream) {}
|
2017-03-28 18:42:04 +08:00
|
|
|
|
2018-03-23 23:32:17 +08:00
|
|
|
void Write(const uint8_t *data, size_t n) { output_stream_.Write(data, n); }
|
2017-03-28 18:42:04 +08:00
|
|
|
void Chunk() {}
|
2017-04-15 21:14:12 +08:00
|
|
|
bool Flush() { return true; }
|
2017-03-28 18:42:04 +08:00
|
|
|
|
|
|
|
private:
|
2018-03-23 23:32:17 +08:00
|
|
|
TestOutputStream &output_stream_;
|
2017-03-28 18:42:04 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* TODO (mferencevic): document
|
|
|
|
*/
|
|
|
|
void PrintOutput(std::vector<uint8_t> &output) {
|
2017-03-22 22:53:30 +08:00
|
|
|
fprintf(stderr, "output: ");
|
2017-03-28 18:42:04 +08:00
|
|
|
for (size_t i = 0; i < output.size(); ++i) {
|
2017-03-22 22:53:30 +08:00
|
|
|
fprintf(stderr, "%02X ", output[i]);
|
|
|
|
}
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
}
|
|
|
|
|
2017-03-28 18:42:04 +08:00
|
|
|
/**
|
|
|
|
* TODO (mferencevic): document
|
|
|
|
*/
|
|
|
|
void CheckOutput(std::vector<uint8_t> &output, const uint8_t *data,
|
|
|
|
uint64_t len, bool clear = true) {
|
|
|
|
if (clear)
|
|
|
|
ASSERT_EQ(len, output.size());
|
|
|
|
else
|
|
|
|
ASSERT_LE(len, output.size());
|
|
|
|
for (size_t i = 0; i < len; ++i) EXPECT_EQ(output[i], data[i]);
|
|
|
|
if (clear)
|
|
|
|
output.clear();
|
|
|
|
else
|
|
|
|
output.erase(output.begin(), output.begin() + len);
|
2017-03-22 22:53:30 +08:00
|
|
|
}
|
|
|
|
|
2017-03-28 18:42:04 +08:00
|
|
|
/**
|
|
|
|
* TODO (mferencevic): document
|
|
|
|
*/
|
|
|
|
void InitializeData(uint8_t *data, size_t size) {
|
2017-03-22 22:53:30 +08:00
|
|
|
std::random_device rd;
|
|
|
|
std::mt19937 gen(rd());
|
|
|
|
std::uniform_int_distribution<> dis(0, 255);
|
2017-03-28 18:42:04 +08:00
|
|
|
for (size_t i = 0; i < size; ++i) {
|
2017-03-22 22:53:30 +08:00
|
|
|
data[i] = dis(gen);
|
|
|
|
}
|
|
|
|
}
|