]> git.localhorst.tv Git - blank.git/commitdiff
test for invoking with unknown argument
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Fri, 18 Nov 2016 15:39:53 +0000 (16:39 +0100)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Fri, 18 Nov 2016 15:39:53 +0000 (16:39 +0100)
src/app/Process.hpp
src/app/proc.cpp
tst/integration/InvocationTest.cpp [new file with mode: 0644]
tst/integration/InvocationTest.hpp [new file with mode: 0644]
tst/integration/ServerTest.cpp
tst/integration/TestInstance.cpp [new file with mode: 0644]
tst/integration/TestInstance.hpp [new file with mode: 0644]
tst/integration/TestServer.cpp [deleted file]
tst/integration/TestServer.hpp [deleted file]

index 3efe96383ef36bae5956c18754a26ba3d7385447..490cf07103a7c2338ca1e170168042bb2ad2e933 100644 (file)
@@ -10,13 +10,17 @@ namespace blank {
 
 class Process {
 
+public:
+       using Arguments = std::vector<std::string>;
+       using Environment = std::vector<std::string>;
+
 public:
        /// launch process executing the file at given path with
        /// given arguments and environment
        Process(
                const std::string &path,
-               const std::vector<std::string> &args,
-               const std::vector<std::string> &env);
+               const Arguments &args,
+               const Environment &env);
        ~Process();
 
 public:
index 3137b0433a990e839a691a3d59f5d023e1c22cf7..f30c0cb2dcab508be7ee480fb63955f8fef721ff 100644 (file)
@@ -22,8 +22,8 @@ struct Process::Impl {
 
        Impl(
                const string &path_in,
-               const vector<string> &args,
-               const vector<string> &env);
+               const Arguments &args,
+               const Environment &env);
        ~Impl();
 
        size_t WriteIn(const void *buffer, size_t max_len);
@@ -50,8 +50,8 @@ struct Process::Impl {
 
 Process::Process(
        const string &path,
-       const vector<string> &args,
-       const vector<string> &env)
+       const Arguments &args,
+       const Environment &env)
 : impl(new Impl(path, args, env))
 , joined(false)
 , status(0) {
@@ -94,8 +94,8 @@ int Process::Join() {
 
 Process::Impl::Impl(
        const string &path_in,
-       const vector<string> &args,
-       const vector<string> &env
+       const Arguments &args,
+       const Environment &env
 ) {
        const char *path = path_in.c_str();
        char *envp[env.size() + 1];
diff --git a/tst/integration/InvocationTest.cpp b/tst/integration/InvocationTest.cpp
new file mode 100644 (file)
index 0000000..0d4c52c
--- /dev/null
@@ -0,0 +1,27 @@
+#include "InvocationTest.hpp"
+
+#include "TestInstance.hpp"
+
+CPPUNIT_TEST_SUITE_REGISTRATION(blank::test::InvocationTest);
+
+
+namespace blank {
+namespace test {
+
+void InvocationTest::setUp() {
+
+}
+
+void InvocationTest::tearDown() {
+
+}
+
+
+void InvocationTest::testUnknownArg() {
+       TestInstance prog({ "--worscht" });
+       prog.AssertErrorLine("unknown option --worscht");
+       prog.AssertExitStatus(1);
+}
+
+}
+}
diff --git a/tst/integration/InvocationTest.hpp b/tst/integration/InvocationTest.hpp
new file mode 100644 (file)
index 0000000..cca53dd
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef BLANK_TEST_INTEGRATION_INVOCATIONTEST_HPP_
+#define BLANK_TEST_INTEGRATION_INVOCATIONTEST_HPP_
+
+#include <cppunit/extensions/HelperMacros.h>
+
+
+namespace blank {
+namespace test {
+
+class InvocationTest
+: public CppUnit::TestFixture {
+
+CPPUNIT_TEST_SUITE(InvocationTest);
+
+CPPUNIT_TEST(testUnknownArg);
+
+CPPUNIT_TEST_SUITE_END();
+
+public:
+       void setUp();
+       void tearDown();
+
+       void testUnknownArg();
+
+};
+
+}
+}
+
+#endif
index fbec21a70f7cd7d9fe96929c1f717129816f61ee..9cee9ee1b90bd2024ba8d7d0e9820dd3c7a40b9a 100644 (file)
@@ -1,6 +1,6 @@
 #include "ServerTest.hpp"
 
-#include "TestServer.hpp"
+#include "TestInstance.hpp"
 
 CPPUNIT_TEST_SUITE_REGISTRATION(blank::test::ServerTest);
 
@@ -18,7 +18,7 @@ void ServerTest::tearDown() {
 
 
 void ServerTest::testStartup() {
-       TestServer server;
+       TestInstance server({ "--server" }, true);
 }
 
 }
diff --git a/tst/integration/TestInstance.cpp b/tst/integration/TestInstance.cpp
new file mode 100644 (file)
index 0000000..f9bc727
--- /dev/null
@@ -0,0 +1,147 @@
+#include "TestInstance.hpp"
+
+#include <cppunit/extensions/HelperMacros.h>
+
+using namespace std;
+
+
+namespace blank {
+namespace test {
+
+namespace {
+
+Process::Arguments combine_args(const TempDir &dir, const Process::Arguments &in, bool cmd) {
+       Process::Arguments out;
+       out.reserve(in.size() + (cmd ? 5 : 3));
+       out.emplace_back("blank");
+       out.insert(out.end(), in.begin(), in.end());
+       out.emplace_back("--save-path");
+       out.emplace_back(dir.Path());
+       if (cmd) {
+               out.emplace_back("--cmd-port");
+               out.emplace_back("12354");
+       }
+       return out;
+}
+
+}
+
+TestInstance::TestInstance(const Process::Arguments &args, bool cmd)
+: dir()
+, proc(
+       "./blank" BLANK_SUFFIX,
+       combine_args(dir, args, cmd),
+       { })
+, conn()
+, out_buf()
+, err_buf()
+, cmd_buf() {
+       if (cmd) {
+               // wait for command service startup
+               // TODO: timeouts for reading from process
+               WaitOutputLine("listening on TCP port 12354");
+               // connect to command service
+               conn = tcp::Socket("localhost", 12354);
+       }
+}
+
+TestInstance::~TestInstance() {
+       proc.Terminate();
+}
+
+
+void TestInstance::WriteInput(const string &data) {
+       const char *i = data.c_str();
+       const char *end = i + data.length();
+       while (i != end) {
+               size_t len = proc.WriteIn(i, end - i);
+               i += len;
+       }
+}
+
+void TestInstance::ReadOutputLine(string &line) {
+       while (!out_buf.Extract(line)) {
+               // buffer exhausted, fetch more data
+               out_buf.Update(proc.ReadOut(out_buf.WriteHead(), out_buf.Remain()));
+       }
+}
+
+void TestInstance::AssertOutputLine(const string &expected) {
+       string line;
+       ReadOutputLine(line);
+       CPPUNIT_ASSERT_EQUAL_MESSAGE(
+               "unexpected line in stdout",
+               expected, line);
+}
+
+void TestInstance::WaitOutputLine(const string &expected) {
+       string line;
+       while (true) {
+               ReadOutputLine(line);
+               if (line == expected) {
+                       return;
+               }
+       }
+}
+
+void TestInstance::ReadErrorLine(string &line) {
+       while (!err_buf.Extract(line)) {
+               // buffer exhausted, fetch more data
+               err_buf.Update(proc.ReadErr(err_buf.WriteHead(), err_buf.Remain()));
+       }
+}
+
+void TestInstance::AssertErrorLine(const string &expected) {
+       string line;
+       ReadErrorLine(line);
+       CPPUNIT_ASSERT_EQUAL_MESSAGE(
+               "unexpected line in stderr",
+               expected, line);
+}
+
+void TestInstance::WaitErrorLine(const string &expected) {
+       string line;
+       while (true) {
+               ReadErrorLine(line);
+               if (line == expected) {
+                       return;
+               }
+       }
+}
+
+
+void TestInstance::AssertExitStatus(int expected) {
+       CPPUNIT_ASSERT_EQUAL_MESSAGE(
+               "unexpected line in stderr",
+               expected, proc.Join());
+}
+
+
+void TestInstance::WaitCommandMessage(const string &line) {
+       WaitCommandLine(" > " + line);
+}
+
+void TestInstance::WaitCommandError(const string &line) {
+       WaitCommandLine(" ! " + line);
+}
+
+void TestInstance::WaitCommandBroadcast(const string &line) {
+       WaitCommandLine(" @ " + line);
+}
+
+void TestInstance::WaitCommandLine(const string &expected) {
+       string line;
+       while (true) {
+               if (!cmd_buf.Extract(line)) {
+                       // buffer exhausted, fetch more data
+                       cmd_buf.Update(conn.Recv(cmd_buf.WriteHead(), cmd_buf.Remain()));
+                       continue;
+               }
+               if (line == expected) {
+                       return;
+               }
+       }
+}
+
+}
+}
diff --git a/tst/integration/TestInstance.hpp b/tst/integration/TestInstance.hpp
new file mode 100644 (file)
index 0000000..3bd23d4
--- /dev/null
@@ -0,0 +1,76 @@
+#ifndef BLANK_TEST_INTEGRATION_TESTINSTANCE_HPP_
+#define BLANK_TEST_INTEGRATION_TESTINSTANCE_HPP_
+
+#include "app/Process.hpp"
+#include "io/filesystem.hpp"
+#include "io/LineBuffer.hpp"
+#include "net/tcp.hpp"
+
+
+namespace blank {
+namespace test {
+
+class TestInstance {
+
+public:
+       /// Launch a blank instance with given arguments (program name
+       /// will be prepended by the constructor).
+       /// If connect is true, a command service connection will be
+       /// established during construction.
+       explicit TestInstance(const Process::Arguments &args, bool connect = false);
+       ~TestInstance();
+
+public:
+       /// Write given text to program's stdin.
+       /// Data is not modified, so if you want to push a line, be
+       /// sure to include a newline character.
+       void WriteInput(const std::string &data);
+
+       /// read next line from programs stdout
+       void ReadOutputLine(std::string &line);
+       /// assert that the next line the program writes to stdout will
+       /// be the given one (without a trailing newline character)
+       void AssertOutputLine(const std::string &line);
+       /// wait until program writes given line to stdout
+       void WaitOutputLine(const std::string &line);
+
+       /// read next line from programs stderr
+       void ReadErrorLine(std::string &line);
+       /// assert that the next line the program writes to stderr will
+       /// be the given one (without a trailing newline character)
+       void AssertErrorLine(const std::string &line);
+       /// wait until program writes given line to stderr
+       void WaitErrorLine(const std::string &line);
+
+       /// make sure the process terminated with given status
+       void AssertExitStatus(int expected);
+
+       // the following methods are only valid when a command service is connected
+
+       /// wait for given message on the command service
+       void WaitCommandMessage(const std::string &line);
+       /// wait for given error on the command service
+       void WaitCommandError(const std::string &line);
+       /// wait for given broadcast on the command service
+       void WaitCommandBroadcast(const std::string &line);
+       /// wait for given line on the command service
+       void WaitCommandLine(const std::string &line);
+
+       /// send command line to program
+       void SendCommand(const std::string &);
+
+private:
+       TempDir dir;
+       Process proc;
+       tcp::Socket conn;
+       size_t head;
+       LineBuffer<BUFSIZ> out_buf;
+       LineBuffer<BUFSIZ> err_buf;
+       LineBuffer<BUFSIZ> cmd_buf;
+
+};
+
+}
+}
+
+#endif
diff --git a/tst/integration/TestServer.cpp b/tst/integration/TestServer.cpp
deleted file mode 100644 (file)
index cb5819d..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-#include "TestServer.hpp"
-
-#include <iostream>
-
-
-namespace blank {
-namespace test {
-
-TestServer::TestServer()
-: dir()
-, proc(
-       "./blank" BLANK_SUFFIX,
-       { "blank", "--server", "--save-path", dir.Path(), "--cmd-port", "12354" },
-       { })
-, conn()
-, serv_buf()
-, sock_buf() {
-       // wait for command service startup
-       // TODO: timeouts for reading from process
-       WaitOutputLine("listening on TCP port 12354");
-       // connect to command service
-       conn = tcp::Socket("localhost", 12354);
-}
-
-TestServer::~TestServer() {
-       proc.Terminate();
-}
-
-
-void TestServer::WaitOutputLine(const std::string &expected) {
-       std::string line;
-       while (true) {
-               if (!serv_buf.Extract(line)) {
-                       // buffer exhausted, fetch more data
-                       serv_buf.Update(proc.ReadOut(serv_buf.WriteHead(), serv_buf.Remain()));
-                       continue;
-               }
-               if (line == expected) {
-                       return;
-               } else {
-                       std::cerr << "ignoring line: " << line << std::endl;
-               }
-       }
-}
-
-void TestServer::WaitCommandMessage(const std::string &line) {
-       WaitCommandLine(" > " + line);
-}
-
-void TestServer::WaitCommandError(const std::string &line) {
-       WaitCommandLine(" ! " + line);
-}
-
-void TestServer::WaitCommandBroadcast(const std::string &line) {
-       WaitCommandLine(" @ " + line);
-}
-
-void TestServer::WaitCommandLine(const std::string &expected) {
-       std::string line;
-       while (true) {
-               if (!serv_buf.Extract(line)) {
-                       // buffer exhausted, fetch more data
-                       serv_buf.Update(conn.Recv(serv_buf.WriteHead(), serv_buf.Remain()));
-                       continue;
-               }
-               if (line == expected) {
-                       return;
-               }
-       }
-}
-
-}
-}
diff --git a/tst/integration/TestServer.hpp b/tst/integration/TestServer.hpp
deleted file mode 100644 (file)
index 9ac31d7..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-#ifndef BLANK_TEST_INTEGRATION_TESTSERVER_HPP_
-#define BLANK_TEST_INTEGRATION_TESTSERVER_HPP_
-
-#include "app/Process.hpp"
-#include "io/filesystem.hpp"
-#include "io/LineBuffer.hpp"
-#include "net/tcp.hpp"
-
-
-namespace blank {
-namespace test {
-
-class TestServer {
-
-public:
-       TestServer();
-       ~TestServer();
-
-public:
-       /// wait until server writes given line to stdout
-       void WaitOutputLine(const std::string &line);
-
-       /// wait for given message on the command service
-       void WaitCommandMessage(const std::string &line);
-       /// wait for given error on the command service
-       void WaitCommandError(const std::string &line);
-       /// wait for given broadcast on the command service
-       void WaitCommandBroadcast(const std::string &line);
-       /// wait for given line on the command service
-       void WaitCommandLine(const std::string &line);
-
-       /// send command line to server
-       void SendCommand(const std::string &);
-
-private:
-       TempDir dir;
-       Process proc;
-       tcp::Socket conn;
-       size_t head;
-       LineBuffer<BUFSIZ> serv_buf;
-       LineBuffer<BUFSIZ> sock_buf;
-
-};
-
-}
-}
-
-#endif