TestUtil.hpp
2.85 KB
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
///
/// \file TestUtil.hpp
/// \author Geoffrey Hunter <gbmhunter@gmail.com> (www.mbedded.ninja)
/// \created 2017-11-24
/// \last-modified 2017-11-24
/// \brief Contains utility methods to help with testing.
/// \details
/// See README.rst in repo root dir for more info.
#ifndef MN_CPP_LINUX_SERIAL_TEST_UTIL_H_
#define MN_CPP_LINUX_SERIAL_TEST_UTIL_H_
// System includes
#include <string>
#include <array>
#include <memory>
#include <iostream>
#include <thread>
#include <chrono>
// 3rd party includes
using namespace std::literals;
namespace mn {
namespace CppLinuxSerial {
class TestUtil {
public:
static TestUtil& GetInstance() {
static TestUtil testUtil;
return testUtil;
}
/// \brief Executes a command on the Linux command-line.
/// \details Blocks until command is complete.
/// \throws std::runtime_error is popen() fails.
std::string Exec(const std::string &cmd) {
std::array<char, 128> buffer;
std::string result;
std::shared_ptr<FILE> pipe(popen(cmd.c_str(), "r"), pclose);
if (!pipe) throw std::runtime_error("popen() failed!");
while (!feof(pipe.get())) {
if (fgets(buffer.data(), 128, pipe.get()) != nullptr)
result += buffer.data();
}
return result;
}
void CreateVirtualSerialPortPair() {
std::cout << "Creating virtual serial port pair..." << std::endl;
std::system((std::string("nohup sudo socat -d -d pty,raw,echo=0,link=")
+ device0Name_ + " pty,raw,echo=0,link="
+ device1Name_ + " &").c_str());
// Hacky! Since socat is detached, we have no idea at what point it has created
// ttyS10 and ttyS11. Assume 1 second is long enough...
std::this_thread::sleep_for(1s);
std::system((std::string("sudo chmod a+rw ") + GetDevice0Name()).c_str());
std::system((std::string("sudo chmod a+rw ") + GetDevice1Name()).c_str());
}
void CloseSerialPorts() {
// Dangerous! Kills all socat processes running
// on computer
std::system("sudo pkill socat");
}
std::string GetDevice0Name() {
return device0Name_;
}
std::string GetDevice1Name() {
return device1Name_;
}
std::string device0Name_ = "/dev/ttyS31";
std::string device1Name_ = "/dev/ttyS32";
protected:
TestUtil() {
}
};
} // namespace CppLinuxSerial
} // namespace mn
#endif // #ifndef MN_CPP_LINUX_SERIAL_TEST_UTIL_H_