Add CyadCommandlineParser 82/32182/6
authorAleksander Zdyb <a.zdyb@samsung.com>
Mon, 15 Dec 2014 09:26:12 +0000 (10:26 +0100)
committerPawel Wieczorek <p.wieczorek2@samsung.com>
Mon, 29 Dec 2014 14:50:01 +0000 (15:50 +0100)
Only --help option is currently supported.
There is also errors handling implemented.

Change-Id: I81b9aae457c49518e42582653b8c29a84b4870ac

src/cyad/CMakeLists.txt
src/cyad/CommandlineParser/CyadCommandlineParser.cpp [new file with mode: 0644]
src/cyad/CommandlineParser/CyadCommandlineParser.h [new file with mode: 0644]
test/CMakeLists.txt
test/cyad/CyadCommandlineTest.h [new file with mode: 0644]
test/cyad/commandline.cpp [new file with mode: 0644]
test/cyad/commandline_errors.cpp [new file with mode: 0644]

index 1ce4d1e..2a53be4 100644 (file)
@@ -23,6 +23,7 @@ SET(CYAD_SOURCES
     ${CYAD_PATH}/AdminPolicyParser.cpp
     ${CYAD_PATH}/CynaraAdminPolicies.cpp
     ${CYAD_PATH}/CommandlineParser/CyadCommand.cpp
+    ${CYAD_PATH}/CommandlineParser/CyadCommandlineParser.cpp
     ${CYAD_PATH}/CommandsDispatcher.cpp
     ${CYAD_PATH}/DispatcherIO.cpp
     ${CYAD_PATH}/main.cpp
diff --git a/src/cyad/CommandlineParser/CyadCommandlineParser.cpp b/src/cyad/CommandlineParser/CyadCommandlineParser.cpp
new file mode 100644 (file)
index 0000000..845f1ef
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed 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.
+ */
+/**
+ * @file        src/cyad/CommandlineParser/CyadCommandlineParser.cpp
+ * @author      Aleksander Zdyb <a.zdyb@samsung.com>
+ * @version     1.0
+ * @brief       Commandline parser for Cyad
+ */
+
+#include <cstring>
+#include <getopt.h>
+#include <map>
+#include <sstream>
+
+#include "CyadCommandlineParser.h"
+
+namespace Cynara {
+
+namespace CyadCmdlineArgs {
+    const char HELP = 'h';
+    const char * const HELP_LONG = "help";
+}
+
+namespace CyadCmdlineErrors {
+    const char * const UNKNOWN_ERROR = "Unknown error";
+    const char * const NO_OPTION = "No option specified";
+    const char * const UNKNOWN_OPTION = "Unknown option";
+}
+
+CyadCommandlineParser::CyadCommandlineParser(int argc, char * const *argv)
+    : m_argc(argc), m_argv(argv) {}
+
+CyadCommandlineParser::~CyadCommandlineParser() {}
+
+std::shared_ptr<CyadCommand> CyadCommandlineParser::parseMain(void) {
+    namespace Args = CyadCmdlineArgs;
+
+    const struct option long_options[] = {
+        { Args::HELP_LONG, no_argument, nullptr, Args::HELP },
+        { nullptr, 0, nullptr, 0 }
+    };
+
+    optind = 0; // On entry to `getopt', zero means this is the first call; initialize.
+    int opt;
+    std::stringstream optstr;
+    optstr << ":" << Args::HELP;
+
+    while ((opt = getopt_long(m_argc, m_argv, optstr.str().c_str(), long_options, nullptr)) != -1) {
+        switch (opt) {
+        case Args::HELP:
+            return std::make_shared<HelpCyadCommand>();
+
+        case '?': // Unknown option
+            return std::make_shared<ErrorCyadCommand>(CyadCmdlineErrors::UNKNOWN_OPTION);
+
+        case ':': // Missing argument
+            // Shall never happen, but let's just make compiler happy.
+            return std::make_shared<ErrorCyadCommand>(CyadCmdlineErrors::UNKNOWN_ERROR);
+
+        default:
+            return std::make_shared<ErrorCyadCommand>(CyadCmdlineErrors::UNKNOWN_OPTION);
+        }
+    }
+
+    return std::make_shared<ErrorCyadCommand>(CyadCmdlineErrors::NO_OPTION);
+}
+
+} /* namespace Cynara */
diff --git a/src/cyad/CommandlineParser/CyadCommandlineParser.h b/src/cyad/CommandlineParser/CyadCommandlineParser.h
new file mode 100644 (file)
index 0000000..7b30348
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed 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.
+ */
+/**
+ * @file        src/cyad/CommandlineParser/CyadCommandlineParser.h
+ * @author      Aleksander Zdyb <a.zdybsamsung.com>
+ * @version     1.0
+ * @brief       Commandline parser for Cyad
+ */
+
+#ifndef SRC_CYAD_COMMANDLINEPARSER_CYADCOMMANDLINEPARSER_H_
+#define SRC_CYAD_COMMANDLINEPARSER_CYADCOMMANDLINEPARSER_H_
+
+#include <memory>
+
+#include <cyad/CommandlineParser/CyadCommand.h>
+
+namespace Cynara {
+
+namespace CyadCmdlineArgs {
+    extern const char HELP;
+    extern const char * const HELP_LONG;
+}
+
+namespace CyadCmdlineErrors {
+    extern const char * const UNKNOWN_ERROR;
+    extern const char * const NO_OPTION;
+    extern const char * const UNKNOWN_OPTION;
+}
+
+class CyadCommandlineParser {
+public:
+    CyadCommandlineParser(int argc, char * const *argv);
+    virtual ~CyadCommandlineParser();
+
+    std::shared_ptr<CyadCommand> parseMain(void);
+
+private:
+    int m_argc;
+    char * const *m_argv;
+};
+
+} /* namespace Cynara */
+
+#endif /* SRC_CYAD_COMMANDLINEPARSER_CYADCOMMANDLINEPARSER_H_ */
index f99d555..5ab37d2 100644 (file)
@@ -50,6 +50,7 @@ SET(CYNARA_SOURCES_FOR_TESTS
     ${CYNARA_SRC}/common/types/PolicyType.cpp
     ${CYNARA_SRC}/cyad/AdminPolicyParser.cpp
     ${CYNARA_SRC}/cyad/CommandlineParser/CyadCommand.cpp
+    ${CYNARA_SRC}/cyad/CommandlineParser/CyadCommandlineParser.cpp
     ${CYNARA_SRC}/cyad/CommandsDispatcher.cpp
     ${CYNARA_SRC}/cyad/CynaraAdminPolicies.cpp
     ${CYNARA_SRC}/helpers/creds-commons/CredsCommonsInner.cpp
@@ -74,6 +75,8 @@ SET(CYNARA_TESTS_SOURCES
     common/protocols/admin/listresponse.cpp
     common/types/policybucket.cpp
     credsCommons/parser/Parser.cpp
+    cyad/commandline.cpp
+    cyad/commandline_errors.cpp
     cyad/commands_dispatcher.cpp
     cyad/helpers.cpp
     cyad/policy_collection.cpp
diff --git a/test/cyad/CyadCommandlineTest.h b/test/cyad/CyadCommandlineTest.h
new file mode 100644 (file)
index 0000000..d45fe3d
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed 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.
+ */
+/**
+ * @file        test/cyad/CyadCommandlineTest.h
+ * @author      Aleksander Zdyb <a.zdyb@samsung.com>
+ * @version     1.0
+ * @brief       Fixture for CyadCommandlineParser tests
+ */
+
+#ifndef TEST_CYAD_CYADCOMMANDLINETEST_H_
+#define TEST_CYAD_CYADCOMMANDLINETEST_H_
+
+#include <cstdlib>
+#include <cstring>
+#include <memory>
+#include <new>
+#include <string>
+#include <vector>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <cyad/CommandlineParser/CyadCommand.h>
+#include <cyad/CommandlineParser/CyadCommandlineParser.h>
+
+class CyadCommandlineTest : public ::testing::Test {
+public:
+    typedef std::vector<std::string> Args;
+
+    void prepare_argv(const Args &args) {
+        destroy_argv();
+
+        m_argc = args.size();
+        m_argv = new char *[m_argc];
+
+        for (auto i = 0; i < m_argc; ++i) {
+            m_argv[i] = strdup(args.at(i).c_str());
+            if (m_argv[i] == nullptr)
+                throw std::bad_alloc();
+        }
+    }
+
+    int argc(void) const {
+        return m_argc;
+    }
+
+    char * const *argv(void) const {
+        return m_argv;
+    }
+
+protected:
+    virtual void TearDown(void) {
+        destroy_argv();
+    }
+
+    void destroy_argv(void) {
+        for (auto i = 0; i < m_argc; ++i) {
+            free(m_argv[i]);
+        }
+        delete[] m_argv;
+
+        m_argc = 0;
+        m_argv = nullptr;
+    }
+
+private:
+    int m_argc = 0;
+    char **m_argv = nullptr;
+};
+
+#endif /* TEST_CYAD_CYADCOMMANDLINETEST_H_ */
diff --git a/test/cyad/commandline.cpp b/test/cyad/commandline.cpp
new file mode 100644 (file)
index 0000000..620cf28
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed 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.
+ */
+/**
+ * @file        test/cyad/commandline.cpp
+ * @author      Aleksander Zdyb <a.zdyb@samsung.com>
+ * @version     1.0
+ * @brief       Tests for CyadCommandlineParser
+ */
+
+#include <memory>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <common/types/PolicyKey.h>
+#include <cyad/CommandlineParser/CyadCommand.h>
+#include <cyad/CommandlineParser/CyadCommandlineParser.h>
+
+#include "CyadCommandlineTest.h"
+
+TEST_F(CyadCommandlineTest, help) {
+    prepare_argv({ "./cyad", "--help" });
+    Cynara::CyadCommandlineParser parser(this->argc(), this->argv());
+
+    auto result = std::dynamic_pointer_cast<Cynara::HelpCyadCommand>(parser.parseMain());
+    ASSERT_NE(nullptr, result);
+}
diff --git a/test/cyad/commandline_errors.cpp b/test/cyad/commandline_errors.cpp
new file mode 100644 (file)
index 0000000..5326119
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed 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.
+ */
+/**
+ * @file        test/cyad/commandline.cpp
+ * @author      Aleksander Zdyb <a.zdyb@samsung.com>
+ * @version     1.0
+ * @brief       Tests for CyadCommandlineParser (errors)
+ */
+
+#include <memory>
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <cyad/CommandlineParser/CyadCommand.h>
+#include <cyad/CommandlineParser/CyadCommandlineParser.h>
+
+#include "CyadCommandlineTest.h"
+
+#define ASSERT_ERROR_MSG(msg,rawResult) { \
+    auto result = std::dynamic_pointer_cast<Cynara::ErrorCyadCommand>(rawResult); \
+    ASSERT_NE(nullptr, result); \
+    ASSERT_TRUE(result->isError()); \
+    ASSERT_EQ(msg, result->message()); \
+}
+
+TEST_F(CyadCommandlineTest, noOption) {
+    prepare_argv({ "./cyad" });
+    Cynara::CyadCommandlineParser parser(this->argc(), this->argv());
+    ASSERT_ERROR_MSG(Cynara::CyadCmdlineErrors::NO_OPTION, parser.parseMain());
+}
+
+TEST_F(CyadCommandlineTest, unknownOption) {
+    prepare_argv({ "./cyad", "--unknown-option" });
+    Cynara::CyadCommandlineParser parser(this->argc(), this->argv());
+    ASSERT_ERROR_MSG(Cynara::CyadCmdlineErrors::UNKNOWN_OPTION, parser.parseMain());
+}