this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

runtest in C++

+436 -1
+3
.gitmodules
··· 1 + [submodule "tests/libsshcxx"] 2 + path = tests/libsshcxx 3 + url = git://git.dolezel.info/libsshcxx.git
+1
CMakeLists.txt
··· 103 103 install(FILES etc/dylib.conf DESTINATION /etc/darling) 104 104 add_subdirectory(src/macbinary) 105 105 add_subdirectory(src/libmacarchive) 106 + add_subdirectory(tests) 106 107 endif(NOT DEFINED SUFFIX OR SUFFIX STREQUAL "64") 107 108 108 109 install(TARGETS mach-o DESTINATION "lib${SUFFIX}/darling")
+35
tests/exceptions.h
··· 1 + #ifndef __EXCEPTIONS_H 2 + #define __EXCEPTIONS_H 3 + #include <stdexcept> 4 + 5 + class compile_error : public std::runtime_error 6 + { 7 + public: 8 + compile_error(const std::string& err) 9 + : std::runtime_error(err) 10 + { 11 + } 12 + }; 13 + 14 + class different_output_error : public std::exception 15 + { 16 + public: 17 + different_output_error(const std::string& remote, const std::string& local) 18 + : m_remote(remote), m_local(local) 19 + { 20 + } 21 + 22 + virtual const char* what() const throw() override 23 + { 24 + return "different_output_error"; 25 + } 26 + 27 + const std::string& local() const { return m_local; } 28 + const std::string& remote() const { return m_remote; } 29 + private: 30 + std::string m_local, m_remote; 31 + }; 32 + 33 + #endif 34 + 35 +
+39
tests/pstream.cpp
··· 1 + #include "pstream.h" 2 + #include <cstdio> 3 + 4 + 5 + pstream::pstream(FILE* pipe) 6 + : m_pipe(pipe) 7 + { 8 + } 9 + 10 + pstream::~pstream() 11 + { 12 + if (m_pipe) 13 + wait(); 14 + } 15 + 16 + pstream* pstream::popen(const std::string& cmd) 17 + { 18 + FILE* pipe = ::popen(cmd.c_str(), "r"); 19 + if (!pipe) 20 + return nullptr; 21 + return new pstream(pipe); 22 + } 23 + 24 + std::istream* pstream::in() 25 + { 26 + return new std::istream(this); 27 + } 28 + 29 + int pstream::wait() 30 + { 31 + int rv = pclose(m_pipe); 32 + m_pipe = nullptr; 33 + return rv; 34 + } 35 + 36 + std::streamsize pstream::xsgetn(char* s, std::streamsize n) 37 + { 38 + return fread(s, 1, n, m_pipe); 39 + }
+20
tests/pstream.h
··· 1 + #include "libsshcxx/ssh_streambuf.h" 2 + #include <cstdio> 3 + #include <istream> 4 + #include <string> 5 + 6 + class pstream : public ssh_streambuf 7 + { 8 + public: 9 + pstream(FILE* pipe); 10 + ~pstream(); 11 + 12 + static pstream* popen(const std::string& cmd); 13 + 14 + std::istream* in(); 15 + int wait(); 16 + protected: 17 + virtual std::streamsize xsgetn(char* s, std::streamsize n) override; 18 + private: 19 + FILE* m_pipe; 20 + };
+1 -1
tests/runtest
··· 60 60 scp "$BUILDSERVER:/tmp/$$.$source_fn.bin" "/tmp" >/dev/null 61 61 ssh "$BUILDSERVER" "rm -f /tmp/$$.$source_fn*" 62 62 63 - echo "Running Darwin binary..." 63 + echo "Running Darwin binary locally..." 64 64 out_darwin=$($DYLD "/tmp/$$.$source_fn.bin") 65 65 rm -f "/tmp/$$.$source_fn.bin" 66 66
+292
tests/runtest.cpp
··· 1 + #include <iostream> 2 + #include "libsshcxx/SSH.h" 3 + #include "libsshcxx/SFTP.h" 4 + #include "libsshcxx/SSHChannel.h" 5 + #include "termcolor.h" 6 + #include "pstream.h" 7 + #include "exceptions.h" 8 + #include <memory> 9 + #include <stdexcept> 10 + #include <sstream> 11 + #include <cstring> 12 + #include <fstream> 13 + #include <unistd.h> 14 + 15 + const char* DYLD_COMMAND = "dyld"; 16 + const char* OSX_HOST = "osx"; 17 + std::unique_ptr<SSH> g_ssh; 18 + std::unique_ptr<SFTP> g_sftp; 19 + std::unique_ptr<SSHChannel> g_shell; 20 + 21 + void bits(const char* progname); 22 + void runTest(const char* path); 23 + std::string uniqueName(const std::string& path); 24 + std::string cflags(const char* path); 25 + const char* compiler(const char* path); 26 + std::string stripext(std::string file); 27 + 28 + int main(int argc, char** argv) 29 + { 30 + if (argc < 2) 31 + { 32 + std::cerr << "Specify the tests to run\n"; 33 + return 1; 34 + } 35 + 36 + bits(argv[0]); 37 + 38 + try 39 + { 40 + std::cout << "Opening SSH connection...\n"; 41 + g_ssh.reset(new SSH); 42 + g_ssh->setHost(OSX_HOST); 43 + g_ssh->connect(); 44 + g_ssh->login(); 45 + g_shell.reset(g_ssh->newChannel()); 46 + g_shell->openNonInteractive(); 47 + g_shell->startShell(); 48 + g_sftp.reset(g_ssh->sftpChannel()); 49 + 50 + int failures = 0; 51 + 52 + for (int i = 1; i < argc; i++) 53 + { 54 + try 55 + { 56 + termcolor::set(termcolor::WHITE, termcolor::BLACK, termcolor::BRIGHT); 57 + std::cout << "=======\n"; 58 + std::cout << "Running test (" << i << '/' << argc-1 << "): " << argv[i] << std::endl; 59 + std::cout << "=======\n"; 60 + termcolor::reset(); 61 + 62 + runTest(argv[i]); 63 + 64 + termcolor::set(termcolor::GREEN, termcolor::BLACK, termcolor::BRIGHT); 65 + std::cout << "*** Test OK!\n"; 66 + termcolor::reset(); 67 + } 68 + catch (const std::runtime_error& e) 69 + { 70 + termcolor::setBright(termcolor::RED); 71 + std::cerr << "*** Test failure!\n"; 72 + termcolor::reset(); 73 + 74 + std::cerr << e.what() << std::endl; 75 + 76 + failures++; 77 + } 78 + catch (const different_output_error& e) 79 + { 80 + termcolor::setBright(termcolor::RED); 81 + std::cerr << "*** Test failure!\n"; 82 + termcolor::reset(); 83 + 84 + termcolor::setBright(termcolor::WHITE); 85 + std::cerr << "Remote output:\n"; 86 + termcolor::reset(); 87 + std::cerr << e.remote(); 88 + 89 + termcolor::setBright(termcolor::WHITE); 90 + std::cerr << "Local output:\n"; 91 + termcolor::reset(); 92 + std::cerr << e.local(); 93 + 94 + failures++; 95 + } 96 + } 97 + 98 + if (!failures) 99 + { 100 + termcolor::setBright(termcolor::GREEN); 101 + std::cout << "ALL OK!"; 102 + } 103 + else 104 + { 105 + termcolor::setBright(termcolor::YELLOW); 106 + std::cerr << failures << " test failures\n"; 107 + } 108 + 109 + termcolor::reset(); 110 + } 111 + catch (const compile_error& e) 112 + { 113 + termcolor::setBright(termcolor::RED); 114 + std::cerr << "*** Error compiling:\n" << e.what(); 115 + termcolor::reset(); 116 + return 1; 117 + } 118 + catch (const std::exception& e) 119 + { 120 + termcolor::setBright(termcolor::RED); 121 + std::cerr << e.what() << std::endl; 122 + termcolor::reset(); 123 + return 1; 124 + } 125 + 126 + return 0; 127 + } 128 + 129 + void runTest(const char* path) 130 + { 131 + /* 132 + std::string line; 133 + g_shell->out() << "echo Hello world\n" << std::flush; 134 + std::getline(g_shell->in(), line); 135 + 136 + termcolor::set(termcolor::RED); 137 + std::cout << line << std::endl; 138 + termcolor::reset(); 139 + */ 140 + 141 + std::stringstream cmd; 142 + std::string binary; 143 + std::string out, err; 144 + std::string filename = "/tmp/"; 145 + int rv; 146 + 147 + filename += uniqueName(path); 148 + 149 + binary = stripext(filename); 150 + 151 + termcolor::set(termcolor::WHITE, termcolor::BLACK, termcolor::DIM); 152 + 153 + std::cout << "Uploading " << path << "...\n"; 154 + // upload the source code 155 + g_sftp->upload(path, filename); 156 + 157 + try 158 + { 159 + std::cout << "Compiling...\n"; 160 + // compile the code remotely 161 + cmd << compiler(path) << ' ' << cflags(path) << filename << " -o " << binary; 162 + rv = g_ssh->runCommand(cmd.str(), out, err); 163 + 164 + if (rv) 165 + throw compile_error(err); 166 + 167 + std::cout << "Running remotely...\n"; 168 + // run the program remotely 169 + rv = g_ssh->runCommand(binary, out, err); 170 + 171 + if (rv) 172 + throw std::runtime_error("Non-zero exit status from remotely run binary"); 173 + 174 + std::cout << "Downloading...\n"; 175 + // download the Mach-O executable 176 + g_sftp->download(binary, binary); 177 + 178 + std::cout << "Running locally...\n"; 179 + // run the executable via dyld 180 + std::stringstream locOut; 181 + pstream* loc = pstream::popen(std::string(DYLD_COMMAND) + " " + binary); 182 + 183 + locOut << loc; 184 + 185 + rv = loc->wait(); 186 + 187 + if (rv) 188 + throw std::runtime_error("Non-zero exit status from locally run binary"); 189 + 190 + if (locOut.str() != out) 191 + throw different_output_error(out, locOut.str()); 192 + } 193 + catch (...) 194 + { 195 + // clean up locally 196 + unlink(binary.c_str()); 197 + 198 + try 199 + { 200 + // clean up remotely 201 + g_sftp->unlink(binary); 202 + g_sftp->unlink(filename); 203 + } 204 + catch (...) {} 205 + 206 + throw; 207 + } 208 + } 209 + 210 + std::string cflags(const char* path) 211 + { 212 + std::string cflags; 213 + const char* suffix = strrchr(path, '.'); 214 + if (!suffix) 215 + throw std::runtime_error("Unsupported file name"); 216 + 217 + if (!strcmp(DYLD_COMMAND, "dyld32") || sizeof(void*) == 4) 218 + cflags += "-m32 "; 219 + 220 + if (!strcmp(suffix, ".m") || !strcmp(suffix, ".mm")) 221 + cflags += "-lobjc "; 222 + 223 + std::ifstream f(path); 224 + std::string first; 225 + 226 + std::getline(f, first); 227 + if (first.compare(0, 11, "// CFLAGS: ") == 0) 228 + { 229 + cflags += first.substr(11); 230 + cflags += ' '; 231 + } 232 + 233 + return cflags; 234 + } 235 + 236 + const char* compiler(const char* path) 237 + { 238 + const char* suffix = strrchr(path, '.'); 239 + if (!suffix) 240 + throw std::runtime_error("Unsupported file name"); 241 + 242 + if (!strcmp(suffix, ".c") || !strcmp(suffix, ".m")) 243 + return "gcc"; 244 + else if (!strcmp(suffix, ".cpp") || !strcmp(suffix, ".mm")) 245 + return "g++"; 246 + else 247 + throw std::runtime_error("Unsupported file name"); 248 + } 249 + 250 + 251 + std::string uniqueName(const std::string& path) 252 + { 253 + char* name = new char[path.size()+1]; 254 + strcpy(name, path.c_str()); 255 + 256 + std::stringstream out; 257 + out << getpid() << '.'; 258 + out << basename(name); 259 + 260 + delete [] name; 261 + return out.str(); 262 + } 263 + 264 + void bits(const char* progname) 265 + { 266 + char* arg0 = strdup(progname); 267 + char* cmd = basename(arg0); 268 + 269 + termcolor::set(termcolor::WHITE, termcolor::BLACK, termcolor::DIM); 270 + if (!strcmp(cmd, "runtest64")) 271 + { 272 + std::cout << "Running in 64-bit mode.\n"; 273 + DYLD_COMMAND = "dyld64"; 274 + } 275 + else if (!strcmp(cmd, "runtest32")) 276 + { 277 + std::cout << "Running in 32-bit mode.\n"; 278 + DYLD_COMMAND = "dyld32"; 279 + } 280 + termcolor::reset(); 281 + 282 + free(arg0); 283 + } 284 + 285 + std::string stripext(std::string file) 286 + { 287 + size_t pos = file.rfind('.'); 288 + if (pos == std::string::npos) 289 + return file; 290 + return file.substr(0, pos); 291 + } 292 +
+14
tests/termcolor.cpp
··· 1 + #include "termcolor.h" 2 + #include <unistd.h> 3 + #include <iostream> 4 + 5 + const bool isTty = isatty(1) != 0; 6 + 7 + void termcolor::set(int text, int bg, int attrib) 8 + { 9 + if (!isTty) 10 + return; 11 + 12 + std::cout << "\x1b[" << attrib << ';' << (text + 30) << ';' << (bg + 40) << 'm' << std::flush; 13 + } 14 +
+31
tests/termcolor.h
··· 1 + #ifndef TERMCOLOR_H 2 + #define TERMCOLOR_H 3 + 4 + namespace termcolor 5 + { 6 + 7 + const int RESET = 0; 8 + const int BRIGHT = 1; 9 + const int DIM = 2; 10 + const int UNDERLINE = 3; 11 + const int BLINK = 4; 12 + const int REVERSE = 7; 13 + const int HIDDEN = 8; 14 + 15 + const int BLACK = 0; 16 + const int RED = 1; 17 + const int GREEN = 2; 18 + const int YELLOW = 3; 19 + const int BLUE = 4; 20 + const int MAGENTA = 5; 21 + const int CYAN = 6; 22 + const int WHITE = 7; 23 + 24 + void set(int text, int bg = BLACK, int attrib = RESET); 25 + inline void setBright(int text, int bg = BLACK) { set(text, bg, BRIGHT); } 26 + inline void reset() { set(WHITE); } 27 + 28 + } 29 + 30 + #endif 31 +