You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pn...@apache.org on 2019/01/07 20:12:05 UTC

[celix] 17/22: CELIX-438: Adds some shell tui gtests

This is an automated email from the ASF dual-hosted git repository.

pnoltes pushed a commit to branch feature/cxx
in repository https://gitbox.apache.org/repos/asf/celix.git

commit 7c425db376c8707ee7b80246ee6be7de1d0781e9
Author: Pepijn Noltes <pe...@gmail.com>
AuthorDate: Mon Jan 7 15:51:24 2019 +0100

    CELIX-438: Adds some shell tui gtests
---
 .travis.yml                                        |  10 +-
 bundles/pubsub/test/CMakeLists.txt                 |   1 +
 bundles/shell/cxx_shell_tui/CMakeLists.txt         |  18 ++--
 bundles/shell/cxx_shell_tui/gtest/CMakeLists.txt   |   9 +-
 .../cxx_shell_tui/gtest/src/ShellTui_tests.cc      |  65 ++++++++++++
 .../shell/cxx_shell_tui/include/celix/ShellTui.h   |  69 ++++++++++++
 bundles/shell/cxx_shell_tui/src/ShellTui.cc        | 116 +++++++++++++++++++++
 .../shell/cxx_shell_tui/src/ShellTuiActivator.cc   | 109 +------------------
 8 files changed, 277 insertions(+), 120 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index eb92e78..3c0f470 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -44,11 +44,11 @@ before_install:
   - if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew update && brew install lcov libffi zeromq czmq glog cpputest jansson && brew link --force libffi; fi
 
 before_script:
-  - wget https://github.com/cpputest/cpputest/releases/download/v3.8/cpputest-3.8.tar.gz -O /tmp/cpputest.tar.gz
-  - tar -xzvf /tmp/cpputest.tar.gz -C /tmp
-  - if [ "$CC" = "clang" ]; then export CXX="clang++"; fi && cd /tmp/cpputest-* && ./configure --prefix=/usr/local && make && sudo make install && cd -
-  - cd /tmp/cpputest-* && ./configure --prefix=/usr/local && make && sudo make install && cd -
-  - mkdir build install
+    - wget https://github.com/cpputest/cpputest/releases/download/v3.8/cpputest-3.8.tar.gz -O /tmp/cpputest.tar.gz
+    - tar -xzvf /tmp/cpputest.tar.gz -C /tmp
+    - if [ "$CC" = "clang" ]; then export CXX="clang++"; fi && cd /tmp/cpputest-* && ./configure --prefix=/usr/local && make && sudo make install && cd -
+    - cd /tmp/cpputest-* && ./configure --prefix=/usr/local && make && sudo make install && cd -
+    - mkdir build install
     - export BUILD_OPTIONS=" \
         -DBUILD_RSA_REMOTE_SERVICE_ADMIN_DFI=ON \
         -DBUILD_DEPLOYMENT_ADMIN=ON \
diff --git a/bundles/pubsub/test/CMakeLists.txt b/bundles/pubsub/test/CMakeLists.txt
index 39e5575..5f72d1f 100644
--- a/bundles/pubsub/test/CMakeLists.txt
+++ b/bundles/pubsub/test/CMakeLists.txt
@@ -86,6 +86,7 @@ add_celix_container(pubsub_udpmc_tst
     DIR ${PROJECT_BINARY_DIR}/runtimes/test/pubsub/udpmc
     LAUNCHER celix_test_runner
 )
+
 add_celix_container(pubsub_zmq_tst
     NAME deploy_tst
     BUNDLES
diff --git a/bundles/shell/cxx_shell_tui/CMakeLists.txt b/bundles/shell/cxx_shell_tui/CMakeLists.txt
index d5b65f7..97d98b5 100644
--- a/bundles/shell/cxx_shell_tui/CMakeLists.txt
+++ b/bundles/shell/cxx_shell_tui/CMakeLists.txt
@@ -15,19 +15,25 @@
 # specific language governing permissions and limitations
 # under the License.
 
-#TODO rename to celix::shell_tui
+add_library(shell_tui_static STATIC
+        src/ShellTui.cc
+)
+target_include_directories(shell_tui_static PUBLIC include)
+target_link_libraries(shell_tui_static PRIVATE celix_framework_cxx glog::glog celix_cxx_shell_api)
+target_compile_options(shell_tui_static PRIVATE -fPIC)
+
 
 #OR static lib, but then with all symbols to force constructor attribute
 add_library(celix_cxx_shell_tui SHARED
         src/ShellTuiActivator.cc
-        src/shell_test.cc)
+)
 target_include_directories(celix_cxx_shell_tui PRIVATE src)
-target_link_libraries(celix_cxx_shell_tui PRIVATE celix_cxx_shell_api glog::glog)
+target_link_libraries(celix_cxx_shell_tui PRIVATE shell_tui_static celix_cxx_shell_api glog::glog)
 target_link_libraries(celix_cxx_shell_tui PUBLIC celix_framework_cxx)
 
-#if (ENABLE_TESTING)
-#    add_subdirectory(gtest)
-#endif ()
+if (ENABLE_TESTING)
+    add_subdirectory(gtest)
+endif ()
 
 
 add_executable(shell_test
diff --git a/bundles/shell/cxx_shell_tui/gtest/CMakeLists.txt b/bundles/shell/cxx_shell_tui/gtest/CMakeLists.txt
index b4a7204..7626eb5 100644
--- a/bundles/shell/cxx_shell_tui/gtest/CMakeLists.txt
+++ b/bundles/shell/cxx_shell_tui/gtest/CMakeLists.txt
@@ -17,9 +17,10 @@
 
 set(SOURCES
         src/main.cc
+        src/ShellTui_tests.cc
 )
-add_executable(celix_shell_cxx_tests ${SOURCES})
-target_link_libraries(celix_shell_cxx_tests PRIVATE gtest celix_framework_cxx celix_shell_cxx)
+add_executable(celix_cxx_shell_tui_tests ${SOURCES})
+target_link_libraries(celix_cxx_shell_tui_tests PRIVATE gtest celix_framework_cxx shell_tui_static celix_cxx_shell_api)
 
-add_test(NAME celix_shell_cxx_tests COMMAND celix_shell_cxx_tests)
-SETUP_TARGET_FOR_COVERAGE(celix_shell_cxx_tests_cov celix_shell_cxx_tests ${CMAKE_BINARY_DIR}/coverage/celix_shell_cxx_tests/celix_shell_cxx_tests)
\ No newline at end of file
+add_test(NAME celix_cxx_shell_tui_tests COMMAND celix_cxx_shell_tui_tests)
+SETUP_TARGET_FOR_COVERAGE(celix_cxx_shell_tui_tests_cov celix_cxx_shell_tui_tests ${CMAKE_BINARY_DIR}/coverage/celix_cxx_shell_tui_tests/celix_cxx_shell_tui_tests ..)
\ No newline at end of file
diff --git a/bundles/shell/cxx_shell_tui/gtest/src/ShellTui_tests.cc b/bundles/shell/cxx_shell_tui/gtest/src/ShellTui_tests.cc
new file mode 100644
index 0000000..6989f27
--- /dev/null
+++ b/bundles/shell/cxx_shell_tui/gtest/src/ShellTui_tests.cc
@@ -0,0 +1,65 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#include <sstream>
+
+#include "gtest/gtest.h"
+
+#include "celix/api.h"
+#include "celix/ShellTui.h"
+
+class ShellTuiTest : public ::testing::Test {
+public:
+    ShellTuiTest() {}
+    ~ShellTuiTest(){}
+
+    celix::Framework& framework() { return fw; }
+private:
+    celix::Framework fw{};
+};
+
+
+
+
+TEST_F(ShellTuiTest, AcceptCommand) {
+    {
+        std::stringstream stream{};
+        celix::ShellTui tui{&stream, &stream};
+        usleep(100000);//IMPROVE, for now wait till stdin reading thread is started
+
+        stream.flush();
+        std::string output = stream.str();
+        size_t pos = output.find("->"); //prompt should be printed
+        EXPECT_LE(pos, output.size());
+    }
+
+    //TODO make working
+//    {
+//        std::stringstream stream{};
+//        celix::ShellTui tui{&stream, &stream};
+//        std::string cmd = "lb\n";
+//        write(STDIN_FILENO, cmd.c_str(), cmd.size());
+//        usleep(100000);//IMPROVE, for now wait till stdin command is processed on other thread.
+//        stream.flush();
+//        std::string output = stream.str();
+//        size_t pos = output.find("1: Framework"); //expect lb result
+//        EXPECT_LE(pos, output.size());
+//    }
+
+}
\ No newline at end of file
diff --git a/bundles/shell/cxx_shell_tui/include/celix/ShellTui.h b/bundles/shell/cxx_shell_tui/include/celix/ShellTui.h
new file mode 100644
index 0000000..67db882
--- /dev/null
+++ b/bundles/shell/cxx_shell_tui/include/celix/ShellTui.h
@@ -0,0 +1,69 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+#ifndef CELIX_SHELLTUI_H
+#define CELIX_SHELLTUI_H
+
+#include <sstream>
+#include <mutex>
+#include <thread>
+
+#include "celix/api.h"
+#include "celix/IShellCommand.h"
+#include "celix/IShell.h"
+
+
+
+
+namespace celix {
+    static constexpr int SHELL_TUI_LINE_SIZE = 256;
+
+    class ShellTui {
+    public:
+        ShellTui(std::ostream *_outStream, std::ostream *_errStream);
+        ~ShellTui();
+
+        ShellTui(const ShellTui&) = delete;
+        ShellTui& operator=(const ShellTui&) = delete;
+
+        void setShell(std::shared_ptr<celix::IShell> _shell);
+    private:
+        void runnable();
+        void writePrompt();
+        void parseInput();
+
+        std::ostream * const outStream;
+        std::ostream * const errStream;
+
+        std::mutex mutex{};
+        std::shared_ptr<celix::IShell> shell{};
+
+        std::thread readThread{};
+
+        int readPipeFd{};
+        int writePipeFd{};
+
+
+        char in[SHELL_TUI_LINE_SIZE+1]{};
+        char buffer[SHELL_TUI_LINE_SIZE+1]{};
+        int pos{};
+    };
+}
+
+#endif //CELIX_SHELLTUI_H
diff --git a/bundles/shell/cxx_shell_tui/src/ShellTui.cc b/bundles/shell/cxx_shell_tui/src/ShellTui.cc
new file mode 100644
index 0000000..d9358d3
--- /dev/null
+++ b/bundles/shell/cxx_shell_tui/src/ShellTui.cc
@@ -0,0 +1,116 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+
+
+#include "celix/ShellTui.h"
+
+#include <memory>
+#include <sstream>
+
+#include <thread>
+#include <cstdio>
+#include <unistd.h>
+#include <fcntl.h>
+#include <mutex>
+
+#include <glog/logging.h>
+
+#include "celix/api.h"
+#include "celix/IShellCommand.h"
+#include "celix/IShell.h"
+
+static constexpr const char * const PROMPT = "-> ";
+static constexpr int KEY_ENTER = '\n';
+
+celix::ShellTui::ShellTui(std::ostream *_outStream, std::ostream *_errStream) : outStream{_outStream}, errStream{_errStream} {
+    int fds[2];
+    int rc  = pipe(fds);
+    if (rc == 0) {
+        readPipeFd = fds[0];
+        writePipeFd = fds[1];
+    if(fcntl(writePipeFd, F_SETFL, O_NONBLOCK) == 0) {
+        readThread = std::thread{&ShellTui::runnable, this};
+    } else {
+        LOG(ERROR) << "fcntl on pipe failed" << std::endl;
+    }
+    } else {
+        LOG(ERROR) << "fcntl on pipe failed" << std::endl;
+    }
+}
+
+
+celix::ShellTui::~ShellTui() {
+    write(writePipeFd, "\0", 1); //trigger select to stop
+    readThread.join();
+}
+
+void celix::ShellTui::runnable() {
+    //setup file descriptors
+    fd_set rfds;
+    int nfds = writePipeFd > STDIN_FILENO ? (writePipeFd +1) : (STDIN_FILENO + 1);
+
+    for (;;) {
+        writePrompt();
+        FD_ZERO(&rfds);
+        FD_SET(STDIN_FILENO, &rfds);
+        FD_SET(readPipeFd, &rfds);
+
+        if (select(nfds, &rfds, NULL, NULL, NULL) > 0) {
+            if (FD_ISSET(readPipeFd, &rfds)) {
+                break; //something is written to the pipe -> exit thread
+            } else if (FD_ISSET(STDIN_FILENO, &rfds)) {
+                parseInput();
+            }
+        }
+    }
+}
+
+void celix::ShellTui::writePrompt() {
+    *outStream << PROMPT;
+    std::flush(*outStream);
+    outStream->flush();
+}
+
+void celix::ShellTui::parseInput() {
+    char* line = NULL;
+    int nr_chars = (int)read(STDIN_FILENO, buffer, SHELL_TUI_LINE_SIZE-pos-1);
+    for (int bufpos = 0; bufpos < nr_chars; bufpos++) {
+        if (buffer[bufpos] == KEY_ENTER) { //end of line -> forward command
+            line = in; // todo trim string
+            std::lock_guard<std::mutex> lck{mutex};
+            if (shell) {
+                shell->executeCommandLine(line, *outStream, *errStream);
+            } else {
+                *errStream << "Shell service not available\n";
+            }
+            pos = 0;
+            in[pos] = '\0';
+        } else { //text
+            in[pos] = buffer[bufpos];
+            in[pos + 1] = '\0';
+            pos++;
+            continue;
+        }
+    } //for
+}
+
+void celix::ShellTui::setShell(std::shared_ptr<celix::IShell> _shell) {
+    std::lock_guard<std::mutex> lck{mutex};
+    shell = std::move(_shell);
+}
\ No newline at end of file
diff --git a/bundles/shell/cxx_shell_tui/src/ShellTuiActivator.cc b/bundles/shell/cxx_shell_tui/src/ShellTuiActivator.cc
index 0958ab0..70b3cce 100644
--- a/bundles/shell/cxx_shell_tui/src/ShellTuiActivator.cc
+++ b/bundles/shell/cxx_shell_tui/src/ShellTuiActivator.cc
@@ -17,126 +17,25 @@
  *under the License.
  */
 
-#include <thread>
-#include <cstdio>
-#include <unistd.h>
-#include <fcntl.h>
-#include <mutex>
-
-#include <glog/logging.h>
+#include <iostream>
 
 #include "celix/api.h"
 #include "celix/IShellCommand.h"
 #include "celix/IShell.h"
 
-static constexpr int LINE_SIZE = 256;
-static constexpr const char * const PROMPT = "-> ";
-
-static constexpr int KEY_ENTER = '\n';
+#include "celix/ShellTui.h"
 
 namespace {
 
-    class ShellTui {
-    public:
-        ShellTui() {
-            int fds[2];
-            int rc  = pipe(fds);
-            if (rc == 0) {
-                readPipeFd = fds[0];
-                writePipeFd = fds[1];
-                if(fcntl(writePipeFd, F_SETFL, O_NONBLOCK) == 0) {
-                    readThread = std::thread{&ShellTui::runnable, this};
-                } else {
-                    LOG(ERROR) << "fcntl on pipe failed" << std::endl;
-                }
-            } else {
-                LOG(ERROR) << "fcntl on pipe failed" << std::endl;
-            }
-        }
-
-        ~ShellTui() {
-            write(writePipeFd, "\0", 1); //trigger select to stop
-            readThread.join();
-        }
-
-        void runnable() {
-            //setup file descriptors
-            fd_set rfds;
-            int nfds = writePipeFd > STDIN_FILENO ? (writePipeFd +1) : (STDIN_FILENO + 1);
-
-            for (;;) {
-                writePrompt();
-                FD_ZERO(&rfds);
-                FD_SET(STDIN_FILENO, &rfds);
-                FD_SET(readPipeFd, &rfds);
-
-                if (select(nfds, &rfds, NULL, NULL, NULL) > 0) {
-                    if (FD_ISSET(readPipeFd, &rfds)) {
-                        break; //something is written to the pipe -> exit thread
-                    } else if (FD_ISSET(STDIN_FILENO, &rfds)) {
-                       parseInput();
-                    }
-                }
-            }
-        }
-
-        void writePrompt() {
-            std::cout << PROMPT;
-            std::flush(std::cout);
-        }
-
-        void parseInput() {
-            char* line = NULL;
-            int nr_chars = (int)read(STDIN_FILENO, buffer, LINE_SIZE-pos-1);
-            for (int bufpos = 0; bufpos < nr_chars; bufpos++) {
-                if (buffer[bufpos] == KEY_ENTER) { //end of line -> forward command
-                    line = in; // todo trim string
-                    std::lock_guard<std::mutex> lck{mutex};
-                    if (shell) {
-                        shell->executeCommandLine(line, std::cout, std::cerr);
-                    } else {
-                        std::cerr << "Shell service not available\n";
-                    }
-                    pos = 0;
-                    in[pos] = '\0';
-                } else { //text
-                    in[pos] = buffer[bufpos];
-                    in[pos + 1] = '\0';
-                    pos++;
-                    continue;
-                }
-            } //for
-        }
-
-        void setShell(std::shared_ptr<celix::IShell> _shell) {
-           std::lock_guard<std::mutex> lck{mutex};
-           shell = _shell;
-        }
-    private:
-        std::mutex mutex{};
-        std::shared_ptr<celix::IShell> shell{};
-
-        std::thread readThread{};
-
-        int readPipeFd{};
-        int writePipeFd{};
-
-
-        char in[LINE_SIZE+1]{};
-        char buffer[LINE_SIZE+1]{};
-        int pos{};
-    };
-
-
     class ShellTuiBundleActivator : public celix::IBundleActivator {
     public:
         ShellTuiBundleActivator(std::shared_ptr<celix::BundleContext> ctx) {
             celix::ServiceTrackerOptions<celix::IShell> opts{};
-            opts.set = std::bind(&ShellTui::setShell, &tui, std::placeholders::_1);
+            opts.set = std::bind(&celix::ShellTui::setShell, &tui, std::placeholders::_1);
             trk = ctx->trackServices(opts);
         }
     private:
-        ShellTui tui{};
+        celix::ShellTui tui{&std::cout, &std::cerr};
         celix::ServiceTracker trk{};
     };