<commit_before>#include "ostree.h"

#include <stdio.h>
#include <unistd.h>
#include <fstream>

#include <gio/gio.h>
#include <json/json.h>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/filesystem.hpp>
#include <boost/make_shared.hpp>

#include "logging.h"
#include "utils.h"

data::InstallOutcome OstreeManager::pull(const Config &config, const KeyManager &keys, const std::string &refhash) {
  OstreeRepo *repo = NULL;
  const char *const commit_ids[] = {refhash.c_str()};
  GCancellable *cancellable = NULL;
  GError *error = NULL;
  GVariantBuilder builder;
  GVariant *options;

  boost::shared_ptr<OstreeSysroot> sysroot = OstreeManager::LoadSysroot(config.pacman.sysroot);
  if (!ostree_sysroot_get_repo(sysroot.get(), &repo, cancellable, &error)) {
    LOG_ERROR << "Could not get OSTree repo";
    g_error_free(error);
    return data::InstallOutcome(data::INSTALL_FAILED, "Could not get OSTree repo");
  }

  if (!OstreeManager::addRemote(repo, config.pacman.ostree_server, keys)) {
    g_object_unref(repo);
    return data::InstallOutcome(data::INSTALL_FAILED, "Error adding OSTree remote");
  }

  g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}"));
  g_variant_builder_add(&builder, "{s@v}", "flags", g_variant_new_variant(g_variant_new_int32(0)));

  g_variant_builder_add(&builder, "{s@v}", "refs", g_variant_new_variant(g_variant_new_strv(commit_ids, 1)));

  options = g_variant_builder_end(&builder);

  if (!ostree_repo_pull_with_options(repo, remote, options, NULL, cancellable, &error)) {
    LOG_ERROR << "Error of pulling image: " << error->message;
    data::InstallOutcome install_outcome(data::INSTALL_FAILED, error->message);
    g_error_free(error);
    g_object_unref(repo);
    g_variant_unref(options);
    return install_outcome;
  }
  g_object_unref(repo);
  g_variant_unref(options);
  return data::InstallOutcome(data::OK, "Pulling ostree image was successful");
}

data::InstallOutcome OstreeManager::install(const Uptane::Target &target) const {
  const char *opt_osname = NULL;
  OstreeRepo *repo = NULL;
  GCancellable *cancellable = NULL;
  GError *error = NULL;
  char *revision;

  if (config.os.size()) {
    opt_osname = config.os.c_str();
  }

  boost::shared_ptr<OstreeSysroot> sysroot = OstreeManager::LoadSysroot(config.sysroot);

  if (!ostree_sysroot_get_repo(sysroot.get(), &repo, cancellable, &error)) {
    LOG_ERROR << "could not get repo";
    g_error_free(error);
    return data::InstallOutcome(data::INSTALL_FAILED, "could not get repo");
  }

  GKeyFile *origin = ostree_sysroot_origin_new_from_refspec(sysroot.get(), target.sha256Hash().c_str());
  if (!ostree_repo_resolve_rev(repo, target.sha256Hash().c_str(), FALSE, &revision, &error)) {
    LOG_ERROR << error->message;
    data::InstallOutcome install_outcome(data::INSTALL_FAILED, error->message);
    g_error_free(error);
    return install_outcome;
  }

  OstreeDeployment *merge_deployment = ostree_sysroot_get_merge_deployment(sysroot.get(), opt_osname);
  if (merge_deployment == NULL) {
    LOG_ERROR << "No merge deployment";
    return data::InstallOutcome(data::INSTALL_FAILED, "No merge deployment");
  }

  if (!ostree_sysroot_prepare_cleanup(sysroot.get(), cancellable, &error)) {
    LOG_ERROR << error->message;
    data::InstallOutcome install_outcome(data::INSTALL_FAILED, error->message);
    g_error_free(error);
    return install_outcome;
  }

  std::string args_content =
      std::string(ostree_bootconfig_parser_get(ostree_deployment_get_bootconfig(merge_deployment), "options"));
  std::vector<std::string> args_vector;
  boost::split(args_vector, args_content, boost::is_any_of(" "));

  std::vector<const char *> kargs_strv_vector;
  kargs_strv_vector.reserve(args_vector.size() + 1);

  for (std::vector<std::string>::iterator it = args_vector.begin(); it != args_vector.end(); ++it) {
    kargs_strv_vector.push_back((*it).c_str());
  }
  kargs_strv_vector[args_vector.size()] = 0;
  GStrv kargs_strv = const_cast<char **>(&kargs_strv_vector[0]);

  OstreeDeployment *new_deployment = NULL;
  if (!ostree_sysroot_deploy_tree(sysroot.get(), opt_osname, revision, origin, merge_deployment, kargs_strv,
                                  &new_deployment, cancellable, &error)) {
    LOG_ERROR << "ostree_sysroot_deploy_tree: " << error->message;
    data::InstallOutcome install_outcome(data::INSTALL_FAILED, error->message);
    g_error_free(error);
    return install_outcome;
  }

  if (!ostree_sysroot_simple_write_deployment(sysroot.get(), NULL, new_deployment, merge_deployment,
                                              OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NONE, cancellable, &error)) {
    LOG_ERROR << "ostree_sysroot_simple_write_deployment:" << error->message;
    data::InstallOutcome install_outcome(data::INSTALL_FAILED, error->message);
    g_error_free(error);
    return install_outcome;
  }
  LOG_INFO << "Performing sync()";
  sync();
  return data::InstallOutcome(data::OK, "Installation successful");
}

OstreeManager::OstreeManager(const PackageConfig &pconfig) : config(pconfig) {
  try {
    getCurrent();
  } catch (...) {
    throw std::runtime_error("Could not find OSTree sysroot at: " + config.sysroot.string());
  }
}

Json::Value OstreeManager::getInstalledPackages() {
  std::string packages_str = Utils::readFile(config.packages_file);
  std::vector<std::string> package_lines;
  boost::split(package_lines, packages_str, boost::is_any_of("\n"));
  Json::Value packages(Json::arrayValue);
  for (std::vector<std::string>::iterator it = package_lines.begin(); it != package_lines.end(); ++it) {
    if (it->empty()) {
      continue;
    }
    size_t pos = it->find(" ");
    if (pos == std::string::npos) {
      throw std::runtime_error("Wrong packages file format");
    }
    Json::Value package;
    package["name"] = it->substr(0, pos);
    package["version"] = it->substr(pos + 1);
    packages.append(package);
  }
  return packages;
}

std::string OstreeManager::getCurrent() {
  boost::shared_ptr<OstreeDeployment> staged_deployment = getStagedDeployment();
  if (!staged_deployment) {
    throw std::runtime_error("No deployments found in OSTree sysroot at: " + config.sysroot.string());
  }
  return ostree_deployment_get_csum(staged_deployment.get());
}

boost::shared_ptr<OstreeDeployment> OstreeManager::getStagedDeployment() {
  boost::shared_ptr<OstreeSysroot> sysroot_smart = OstreeManager::LoadSysroot(config.sysroot);

  GPtrArray *deployments = NULL;
  boost::shared_ptr<OstreeDeployment> res;

  deployments = ostree_sysroot_get_deployments(sysroot_smart.get());

  if (deployments->len > 0) {
    OstreeDeployment *d = static_cast<OstreeDeployment *>(deployments->pdata[0]);
    OstreeDeployment *d2 = static_cast<OstreeDeployment *>(g_object_ref(d));
    res = boost::shared_ptr<OstreeDeployment>(d2, g_object_unref);
  }

  g_ptr_array_unref(deployments);
  return res;
}

boost::shared_ptr<OstreeSysroot> OstreeManager::LoadSysroot(const boost::filesystem::path &path) {
  OstreeSysroot *sysroot = NULL;

  if (!path.empty()) {
    GFile *fl = g_file_new_for_path(path.c_str());
    sysroot = ostree_sysroot_new(fl);
    g_object_unref(fl);
  } else {
    sysroot = ostree_sysroot_new_default();
  }
  GError *error = NULL;
  if (!ostree_sysroot_load(sysroot, NULL, &error)) {
    if (error != NULL) {
      g_error_free(error);
    }
    g_object_unref(sysroot);
    throw std::runtime_error("could not load sysroot");
  }
  return boost::shared_ptr<OstreeSysroot>(sysroot, g_object_unref);
}

bool OstreeManager::addRemote(OstreeRepo *repo, const std::string &url, const KeyManager &keys) {
  GCancellable *cancellable = NULL;
  GError *error = NULL;
  GVariantBuilder b;
  GVariant *options;

  g_variant_builder_init(&b, G_VARIANT_TYPE("a{sv}"));
  g_variant_builder_add(&b, "{s@v}", "gpg-verify", g_variant_new_variant(g_variant_new_boolean(FALSE)));

  std::string cert_file = keys.getCertFile();
  std::string pkey_file = keys.getPkeyFile();
  std::string ca_file = keys.getCaFile();
  if (!cert_file.empty() && !pkey_file.empty() && !ca_file.empty()) {
    g_variant_builder_add(&b, "{s@v}", "tls-client-cert-path",
                          g_variant_new_variant(g_variant_new_string(cert_file.c_str())));
    g_variant_builder_add(&b, "{s@v}", "tls-client-key-path",
                          g_variant_new_variant(g_variant_new_string(pkey_file.c_str())));
    g_variant_builder_add(&b, "{s@v}", "tls-ca-path", g_variant_new_variant(g_variant_new_string(ca_file.c_str())));
  }
  options = g_variant_builder_end(&b);

  if (!ostree_repo_remote_change(repo, NULL, OSTREE_REPO_REMOTE_CHANGE_DELETE_IF_EXISTS, remote, url.c_str(), options,
                                 cancellable, &error)) {
    LOG_ERROR << "Error of adding remote: " << error->message;
    g_error_free(error);
    g_variant_unref(options);
    return false;
  }
  if (!ostree_repo_remote_change(repo, NULL, OSTREE_REPO_REMOTE_CHANGE_ADD_IF_NOT_EXISTS, remote, url.c_str(), options,
                                 cancellable, &error)) {
    LOG_ERROR << "Error of adding remote: " << error->message;
    g_error_free(error);
    g_variant_unref(options);
    return false;
  }
  g_variant_unref(options);
  return true;
}
<commit_msg>Don't pull OSTree ref if it is already in repo<commit_after>#include "ostree.h"

#include <stdio.h>
#include <unistd.h>
#include <fstream>

#include <gio/gio.h>
#include <json/json.h>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/filesystem.hpp>
#include <boost/make_shared.hpp>

#include "logging.h"
#include "utils.h"

data::InstallOutcome OstreeManager::pull(const Config &config, const KeyManager &keys, const std::string &refhash) {
  OstreeRepo *repo = NULL;
  const char *const commit_ids[] = {refhash.c_str()};
  GCancellable *cancellable = NULL;
  GError *error = NULL;
  GVariantBuilder builder;
  GVariant *options;

  boost::shared_ptr<OstreeSysroot> sysroot = OstreeManager::LoadSysroot(config.pacman.sysroot);
  if (!ostree_sysroot_get_repo(sysroot.get(), &repo, cancellable, &error)) {
    LOG_ERROR << "Could not get OSTree repo";
    g_error_free(error);
    return data::InstallOutcome(data::INSTALL_FAILED, "Could not get OSTree repo");
  }

  GHashTable *ref_list = NULL;
  if (ostree_repo_list_commit_objects_starting_with(repo, refhash.c_str(), &ref_list, nullptr, &error)) {
    guint length = g_hash_table_size(ref_list);
    g_hash_table_destroy(ref_list);  // OSTree creates the table with destroy notifiers, so no memory leaks expected
    // should never be greater than 1, but use >= for robustness
    if (length >= 1) {
      return data::InstallOutcome(data::ALREADY_PROCESSED, "Refhash was already pulled");
    }
  }
  if (error) {
    g_error_free(error);
    error = NULL;
  }

  if (!OstreeManager::addRemote(repo, config.pacman.ostree_server, keys)) {
    g_object_unref(repo);
    return data::InstallOutcome(data::INSTALL_FAILED, "Error adding OSTree remote");
  }

  g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sv}"));
  g_variant_builder_add(&builder, "{s@v}", "flags", g_variant_new_variant(g_variant_new_int32(0)));

  g_variant_builder_add(&builder, "{s@v}", "refs", g_variant_new_variant(g_variant_new_strv(commit_ids, 1)));

  options = g_variant_builder_end(&builder);

  if (!ostree_repo_pull_with_options(repo, remote, options, NULL, cancellable, &error)) {
    LOG_ERROR << "Error of pulling image: " << error->message;
    data::InstallOutcome install_outcome(data::INSTALL_FAILED, error->message);
    g_error_free(error);
    g_object_unref(repo);
    g_variant_unref(options);
    return install_outcome;
  }
  g_object_unref(repo);
  g_variant_unref(options);
  return data::InstallOutcome(data::OK, "Pulling ostree image was successful");
}

data::InstallOutcome OstreeManager::install(const Uptane::Target &target) const {
  const char *opt_osname = NULL;
  OstreeRepo *repo = NULL;
  GCancellable *cancellable = NULL;
  GError *error = NULL;
  char *revision;

  if (config.os.size()) {
    opt_osname = config.os.c_str();
  }

  boost::shared_ptr<OstreeSysroot> sysroot = OstreeManager::LoadSysroot(config.sysroot);

  if (!ostree_sysroot_get_repo(sysroot.get(), &repo, cancellable, &error)) {
    LOG_ERROR << "could not get repo";
    g_error_free(error);
    return data::InstallOutcome(data::INSTALL_FAILED, "could not get repo");
  }

  GKeyFile *origin = ostree_sysroot_origin_new_from_refspec(sysroot.get(), target.sha256Hash().c_str());
  if (!ostree_repo_resolve_rev(repo, target.sha256Hash().c_str(), FALSE, &revision, &error)) {
    LOG_ERROR << error->message;
    data::InstallOutcome install_outcome(data::INSTALL_FAILED, error->message);
    g_error_free(error);
    return install_outcome;
  }

  OstreeDeployment *merge_deployment = ostree_sysroot_get_merge_deployment(sysroot.get(), opt_osname);
  if (merge_deployment == NULL) {
    LOG_ERROR << "No merge deployment";
    return data::InstallOutcome(data::INSTALL_FAILED, "No merge deployment");
  }

  if (!ostree_sysroot_prepare_cleanup(sysroot.get(), cancellable, &error)) {
    LOG_ERROR << error->message;
    data::InstallOutcome install_outcome(data::INSTALL_FAILED, error->message);
    g_error_free(error);
    return install_outcome;
  }

  std::string args_content =
      std::string(ostree_bootconfig_parser_get(ostree_deployment_get_bootconfig(merge_deployment), "options"));
  std::vector<std::string> args_vector;
  boost::split(args_vector, args_content, boost::is_any_of(" "));

  std::vector<const char *> kargs_strv_vector;
  kargs_strv_vector.reserve(args_vector.size() + 1);

  for (std::vector<std::string>::iterator it = args_vector.begin(); it != args_vector.end(); ++it) {
    kargs_strv_vector.push_back((*it).c_str());
  }
  kargs_strv_vector[args_vector.size()] = 0;
  GStrv kargs_strv = const_cast<char **>(&kargs_strv_vector[0]);

  OstreeDeployment *new_deployment = NULL;
  if (!ostree_sysroot_deploy_tree(sysroot.get(), opt_osname, revision, origin, merge_deployment, kargs_strv,
                                  &new_deployment, cancellable, &error)) {
    LOG_ERROR << "ostree_sysroot_deploy_tree: " << error->message;
    data::InstallOutcome install_outcome(data::INSTALL_FAILED, error->message);
    g_error_free(error);
    return install_outcome;
  }

  if (!ostree_sysroot_simple_write_deployment(sysroot.get(), NULL, new_deployment, merge_deployment,
                                              OSTREE_SYSROOT_SIMPLE_WRITE_DEPLOYMENT_FLAGS_NONE, cancellable, &error)) {
    LOG_ERROR << "ostree_sysroot_simple_write_deployment:" << error->message;
    data::InstallOutcome install_outcome(data::INSTALL_FAILED, error->message);
    g_error_free(error);
    return install_outcome;
  }
  LOG_INFO << "Performing sync()";
  sync();
  return data::InstallOutcome(data::OK, "Installation successful");
}

OstreeManager::OstreeManager(const PackageConfig &pconfig) : config(pconfig) {
  try {
    getCurrent();
  } catch (...) {
    throw std::runtime_error("Could not find OSTree sysroot at: " + config.sysroot.string());
  }
}

Json::Value OstreeManager::getInstalledPackages() {
  std::string packages_str = Utils::readFile(config.packages_file);
  std::vector<std::string> package_lines;
  boost::split(package_lines, packages_str, boost::is_any_of("\n"));
  Json::Value packages(Json::arrayValue);
  for (std::vector<std::string>::iterator it = package_lines.begin(); it != package_lines.end(); ++it) {
    if (it->empty()) {
      continue;
    }
    size_t pos = it->find(" ");
    if (pos == std::string::npos) {
      throw std::runtime_error("Wrong packages file format");
    }
    Json::Value package;
    package["name"] = it->substr(0, pos);
    package["version"] = it->substr(pos + 1);
    packages.append(package);
  }
  return packages;
}

std::string OstreeManager::getCurrent() {
  boost::shared_ptr<OstreeDeployment> staged_deployment = getStagedDeployment();
  if (!staged_deployment) {
    throw std::runtime_error("No deployments found in OSTree sysroot at: " + config.sysroot.string());
  }
  return ostree_deployment_get_csum(staged_deployment.get());
}

boost::shared_ptr<OstreeDeployment> OstreeManager::getStagedDeployment() {
  boost::shared_ptr<OstreeSysroot> sysroot_smart = OstreeManager::LoadSysroot(config.sysroot);

  GPtrArray *deployments = NULL;
  boost::shared_ptr<OstreeDeployment> res;

  deployments = ostree_sysroot_get_deployments(sysroot_smart.get());

  if (deployments->len > 0) {
    OstreeDeployment *d = static_cast<OstreeDeployment *>(deployments->pdata[0]);
    OstreeDeployment *d2 = static_cast<OstreeDeployment *>(g_object_ref(d));
    res = boost::shared_ptr<OstreeDeployment>(d2, g_object_unref);
  }

  g_ptr_array_unref(deployments);
  return res;
}

boost::shared_ptr<OstreeSysroot> OstreeManager::LoadSysroot(const boost::filesystem::path &path) {
  OstreeSysroot *sysroot = NULL;

  if (!path.empty()) {
    GFile *fl = g_file_new_for_path(path.c_str());
    sysroot = ostree_sysroot_new(fl);
    g_object_unref(fl);
  } else {
    sysroot = ostree_sysroot_new_default();
  }
  GError *error = NULL;
  if (!ostree_sysroot_load(sysroot, NULL, &error)) {
    if (error != NULL) {
      g_error_free(error);
    }
    g_object_unref(sysroot);
    throw std::runtime_error("could not load sysroot");
  }
  return boost::shared_ptr<OstreeSysroot>(sysroot, g_object_unref);
}

bool OstreeManager::addRemote(OstreeRepo *repo, const std::string &url, const KeyManager &keys) {
  GCancellable *cancellable = NULL;
  GError *error = NULL;
  GVariantBuilder b;
  GVariant *options;

  g_variant_builder_init(&b, G_VARIANT_TYPE("a{sv}"));
  g_variant_builder_add(&b, "{s@v}", "gpg-verify", g_variant_new_variant(g_variant_new_boolean(FALSE)));

  std::string cert_file = keys.getCertFile();
  std::string pkey_file = keys.getPkeyFile();
  std::string ca_file = keys.getCaFile();
  if (!cert_file.empty() && !pkey_file.empty() && !ca_file.empty()) {
    g_variant_builder_add(&b, "{s@v}", "tls-client-cert-path",
                          g_variant_new_variant(g_variant_new_string(cert_file.c_str())));
    g_variant_builder_add(&b, "{s@v}", "tls-client-key-path",
                          g_variant_new_variant(g_variant_new_string(pkey_file.c_str())));
    g_variant_builder_add(&b, "{s@v}", "tls-ca-path", g_variant_new_variant(g_variant_new_string(ca_file.c_str())));
  }
  options = g_variant_builder_end(&b);

  if (!ostree_repo_remote_change(repo, NULL, OSTREE_REPO_REMOTE_CHANGE_DELETE_IF_EXISTS, remote, url.c_str(), options,
                                 cancellable, &error)) {
    LOG_ERROR << "Error of adding remote: " << error->message;
    g_error_free(error);
    g_variant_unref(options);
    return false;
  }
  if (!ostree_repo_remote_change(repo, NULL, OSTREE_REPO_REMOTE_CHANGE_ADD_IF_NOT_EXISTS, remote, url.c_str(), options,
                                 cancellable, &error)) {
    LOG_ERROR << "Error of adding remote: " << error->message;
    g_error_free(error);
    g_variant_unref(options);
    return false;
  }
  g_variant_unref(options);
  return true;
}
<|endoftext|>


<commit_before>//*****************************************************************************
// Copyright 2017-2019 Intel Corporation
//
// 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.
//*****************************************************************************

#include "gtest/gtest.h"
#include "ngraph/ngraph.hpp"
#include "util/all_close.hpp"
#include "util/all_close_f.hpp"
#include "util/known_element_types.hpp"
#include "util/ndarray.hpp"
#include "util/random.hpp"
#include "util/test_control.hpp"
#include "util/test_tools.hpp"

using namespace std;
using namespace ngraph;

static string s_manifest = "${MANIFEST}";

// This test operates against the INTERPRETER backend as a reference, so it is
// disabled if INTERPRETER is disabled.
#if NGRAPH_INTERPRETER_ENABLE
NGRAPH_TEST(${BACKEND_NAME}, batch_mat_mul_forward)
{
    auto make_dot = [](ParameterVector& a_params, ParameterVector& b_params) {
        Shape shape_a{2, 3};
        Shape shape_b{3, 2};
        auto A = make_shared<op::Parameter>(element::f32, shape_a);
        auto B = make_shared<op::Parameter>(element::f32, shape_b);
        a_params.push_back(A);
        b_params.push_back(B);
        return make_shared<op::Dot>(A, B);
    };

    ParameterVector dot_a_params;
    ParameterVector dot_b_params;
    auto dot1 = make_dot(dot_a_params, dot_b_params);
    auto dot2 = make_dot(dot_a_params, dot_b_params);
    auto dot3 = make_dot(dot_a_params, dot_b_params);
    auto dot_concat = make_shared<op::Concat>(NodeVector{dot1, dot2, dot3}, 0);
    ParameterVector dot_params(dot_a_params);
    dot_params.insert(dot_params.end(), dot_b_params.begin(), dot_b_params.end());
    auto ref_f = make_shared<Function>(dot_concat, dot_params);

    auto make_batchmatmul = [](ParameterVector& params) {
        Shape shape_a{3, 2, 3};
        Shape shape_b{3, 3, 2};
        auto A = make_shared<op::Parameter>(element::f32, shape_a);
        auto B = make_shared<op::Parameter>(element::f32, shape_b);
        params.push_back(A);
        params.push_back(B);
        return make_shared<op::BatchMatMul>(A, B);
    };

    ParameterVector batchmatmul_params;
    auto batchmatmul = make_batchmatmul(batchmatmul_params);
    auto backend_f = make_shared<Function>(batchmatmul, batchmatmul_params);

    test::Uniform<float> dot_rng(-1.0f, 1.0f);
    vector<vector<float>> dot_args;
    for (shared_ptr<op::Parameter> param : dot_params)
    {
        vector<float> tensor_val(shape_size(param->get_shape()));
        dot_rng.initialize(tensor_val);
        dot_args.push_back(tensor_val);
    }

    test::Uniform<float> batchmatmul_rng(-1.0f, 1.0f);
    vector<vector<float>> batchmatmul_args;
    for (shared_ptr<op::Parameter> param : batchmatmul_params)
    {
        vector<float> tensor_val(shape_size(param->get_shape()));
        batchmatmul_rng.initialize(tensor_val);
        batchmatmul_args.push_back(tensor_val);
    }
    auto ref_results = execute(ref_f, dot_args, "INTERPRETER");
    auto backend_results = execute(backend_f, batchmatmul_args, "${BACKEND_NAME}");
    for (size_t i = 0; i < ref_results.size(); i++)
    {
        EXPECT_TRUE(test::all_close_f(ref_results.at(i), backend_results.at(i),
                    DEFAULT_FLOAT_TOLERANCE_BITS + 3));
    }
}
#endif
<commit_msg>style<commit_after>//*****************************************************************************
// Copyright 2017-2019 Intel Corporation
//
// 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.
//*****************************************************************************

#include "gtest/gtest.h"
#include "ngraph/ngraph.hpp"
#include "util/all_close.hpp"
#include "util/all_close_f.hpp"
#include "util/known_element_types.hpp"
#include "util/ndarray.hpp"
#include "util/random.hpp"
#include "util/test_control.hpp"
#include "util/test_tools.hpp"

using namespace std;
using namespace ngraph;

static string s_manifest = "${MANIFEST}";

// This test operates against the INTERPRETER backend as a reference, so it is
// disabled if INTERPRETER is disabled.
#if NGRAPH_INTERPRETER_ENABLE
NGRAPH_TEST(${BACKEND_NAME}, batch_mat_mul_forward)
{
    auto make_dot = [](ParameterVector& a_params, ParameterVector& b_params) {
        Shape shape_a{2, 3};
        Shape shape_b{3, 2};
        auto A = make_shared<op::Parameter>(element::f32, shape_a);
        auto B = make_shared<op::Parameter>(element::f32, shape_b);
        a_params.push_back(A);
        b_params.push_back(B);
        return make_shared<op::Dot>(A, B);
    };

    ParameterVector dot_a_params;
    ParameterVector dot_b_params;
    auto dot1 = make_dot(dot_a_params, dot_b_params);
    auto dot2 = make_dot(dot_a_params, dot_b_params);
    auto dot3 = make_dot(dot_a_params, dot_b_params);
    auto dot_concat = make_shared<op::Concat>(NodeVector{dot1, dot2, dot3}, 0);
    ParameterVector dot_params(dot_a_params);
    dot_params.insert(dot_params.end(), dot_b_params.begin(), dot_b_params.end());
    auto ref_f = make_shared<Function>(dot_concat, dot_params);

    auto make_batchmatmul = [](ParameterVector& params) {
        Shape shape_a{3, 2, 3};
        Shape shape_b{3, 3, 2};
        auto A = make_shared<op::Parameter>(element::f32, shape_a);
        auto B = make_shared<op::Parameter>(element::f32, shape_b);
        params.push_back(A);
        params.push_back(B);
        return make_shared<op::BatchMatMul>(A, B);
    };

    ParameterVector batchmatmul_params;
    auto batchmatmul = make_batchmatmul(batchmatmul_params);
    auto backend_f = make_shared<Function>(batchmatmul, batchmatmul_params);

    test::Uniform<float> dot_rng(-1.0f, 1.0f);
    vector<vector<float>> dot_args;
    for (shared_ptr<op::Parameter> param : dot_params)
    {
        vector<float> tensor_val(shape_size(param->get_shape()));
        dot_rng.initialize(tensor_val);
        dot_args.push_back(tensor_val);
    }

    test::Uniform<float> batchmatmul_rng(-1.0f, 1.0f);
    vector<vector<float>> batchmatmul_args;
    for (shared_ptr<op::Parameter> param : batchmatmul_params)
    {
        vector<float> tensor_val(shape_size(param->get_shape()));
        batchmatmul_rng.initialize(tensor_val);
        batchmatmul_args.push_back(tensor_val);
    }
    auto ref_results = execute(ref_f, dot_args, "INTERPRETER");
    auto backend_results = execute(backend_f, batchmatmul_args, "${BACKEND_NAME}");
    for (size_t i = 0; i < ref_results.size(); i++)
    {
        EXPECT_TRUE(test::all_close_f(
            ref_results.at(i), backend_results.at(i), DEFAULT_FLOAT_TOLERANCE_BITS + 3));
    }
}
#endif
<|endoftext|>


<commit_before>#include <pwd.h>
#include <iostream>
#include <unistd.h>
#include <sys/stat.h>
#include <stdio.h>
#include <vector>
#include <sstream>
#include <dirent.h>
#include <errno.h>
#include <sys/types.h>
using namespace std;

bool isDirectory(char* directoryName) {

	struct stat directoryInCurrent;

	if (-1 == (stat(directoryName, &directoryInCurrent))) {

		return false;
	}

	if (directoryInCurrent.st_mode & S_IFDIR) {
		return true;
	}
	else {
		return false;
	}
}

int ls(char* directoryName) {

		char const *dirName = directoryName;
		DIR *dirp;
		if (!(dirp = opendir(dirName))) {
			cerr << "Error(" << errno << ") opening " << dirName << endl;
		}

		dirent *direntp;
		while ((direntp = readdir(dirp))) {
			if (direntp->d_name[0] != '.') {

				//cout << direntp->d_name << endl; // use stat here to find attributes of a file
				printf(direntp->d_name, 8);
				cout << " ";
			}
		}
		cout << endl;
		closedir(dirp);
		return 0;
}

int lsWithFlags(char* directoryName, vector<string> flags) {

	bool isA = false;
	bool isL = false;
	bool isR = false;
	for (unsigned i = 0; i < flags.size(); ++i) {
		for (unsigned k = 0; k < flags.at(i).size(); ++k) {
			if (flags.at(i).at(k) == 'a')
				isA = true;
			else if (flags.at(i).at(k) == 'l')
				isL = true;
			else if (flags.at(i).at(k) == 'R')
				isR = true;
		}

	}
	char const *dirName = directoryName;
	DIR *dirp;
	if (!(dirp = opendir(dirName))) {
		cerr << "Error(" << errno << ") opening " << dirName << endl;
		return errno;
	}

	dirent *direntp;
	if (isL) {

		cout << 78 << endl;
		struct stat current;

		while ((direntp = readdir(dirp))) {

			//cout << "direntp: " << direntp << endl;
			if (-1 == (stat(direntp->d_name, &current))) {

				perror("stat failed");
				return -1;
			}
			if (direntp->d_name[0] == '-' && !isA)
				continue;
			else {

				if (current.st_mode & S_IFDIR)
					cout << "d";

				if (current.st_mode & S_IFLNK)
					cout << "l";

				if (!(current.st_mode & S_IFDIR) && !(current.st_mode & S_IFLNK))
					cout << "-";

				if (current.st_mode & S_IRUSR)
					cout << "r";
				else
					cout << "-";

				if (current.st_mode & S_IWUSR)
					cout << "w";
				else
					cout << "-";

				if (current.st_mode & S_IXUSR)
					cout << "x";
				else
					cout << "-";

				if (current.st_mode & S_IRGRP)
					cout << "r";
				else
					cout << "-";

				if (current.st_mode & S_IWGRP)
					cout << "w";
				else
					cout << "-";

				if (current.st_mode & S_IXGRP)
					cout << "x";
				else
					cout << "-";

				if (current.st_mode & S_IROTH)
					cout << "r";
				else
					cout << "-";

				if (current.st_mode & S_IWOTH)
					cout << "w";
				else
					cout << "-";

				if (current.st_mode & S_IXOTH)
					cout << "x";
				else
					cout << "-";

				cout << " ";

				cout << current.st_nlink << " ";

				cout << current.st_uid << " ";

				cout << current.st_gid << " ";

				cout << current.st_size << " ";

				char buff[20];
				struct tm * timeinfo;
				timeinfo = localtime(&(current.st_mtime));
				strftime(buff, 20, "%b %d %H:%M", timeinfo);
				printf("%s",buff);

				cout << direntp->d_name;
			}
			cout << endl;

		}
		closedir(dirp);

	}

	else if (isA) {
		while ((direntp = readdir(dirp))) {

			//cout << direntp->d_name << endl; // use stat here to find attributes of a file
			printf(direntp->d_name, 8);
			cout << " ";

		}
		closedir(dirp);
	}
	return 0;
}

int main(int argc, char* argv[]) {

	if (argc == 1) {

		if (errno == ls(".")) {

			return errno;
		}
	}

	else {

		vector<string> directories;
		vector<string> flags;
		vector<int> directoryIndex;
		bool directoryInArgv = false;
		for (int i = 1; i < argc; ++i) {

			if (isDirectory(argv[i])) {
				directoryInArgv = true;

			}
			else {

				if (argv[i][0] == '-') {

					flags.push_back(argv[i]);
				}
			}
		}
		if (!directoryInArgv) {

			if (errno == lsWithFlags(".", flags)) {

				return errno;
			}
		}
		else {

			for (int i = 1; i < argc; ++i) {

				if (isDirectory(argv[i])) {
					directories.push_back(argv[i]);
					directoryIndex.push_back(i);
				}
			}

			//cout << "directories: ";
			//for (unsigned i = 0; i < directories.size(); ++i)
				//cout << directories.at(i) << " ";
			//cout << endl;

			for (unsigned int i = 0; i < directories.size(); ++i) {
				//cout << 145 << endl;
				flags.clear();

				for (int k = directoryIndex.at(i) + 1; k < argc && !isDirectory(argv[k]); ++k) {
					if (argv[k][0] == '-')
						flags.push_back(argv[k]);
				}

				char* directoryName = new char[directories.at(i).size() + 1];
				strcpy(directoryName, directories.at(i).c_str());

				if (flags.size() == 0 && directories.size() == 1) {
					//cout << 152 << endl;
					//cout << directories.at(i) << ":" << endl;
					ls(directoryName);
					cout << endl;
				}
				else if (flags.size() == 0) {
					//cout << 152 << endl;
					cout << directories.at(i) << ":" << endl;
					ls(directoryName);
					cout << endl;
				}
				else {
					cout << directories.at(i) << ":" << endl;
			   	if	(errno == lsWithFlags(directoryName, flags)) {

						return errno;
					}
					cout << endl;
				}

				delete [] directoryName;
			}
		}
	}

}

<commit_msg>added -l protection functionality<commit_after>#include <pwd.h>
#include <iostream>
#include <unistd.h>
#include <sys/stat.h>
#include <stdio.h>
#include <vector>
#include <sstream>
#include <dirent.h>
#include <errno.h>
#include <sys/types.h>
using namespace std;

bool isDirectory(char* directoryName) {

	struct stat directoryInCurrent;

	if (-1 == (stat(directoryName, &directoryInCurrent))) {

		return false;
	}

	if (directoryInCurrent.st_mode & S_IFDIR) {
		return true;
	}
	else {
		return false;
	}
}

int ls(char* directoryName) {

		char const *dirName = directoryName;
		DIR *dirp;
		if (!(dirp = opendir(dirName))) {
			cerr << "Error(" << errno << ") opening " << dirName << endl;
		}

		dirent *direntp;
		while ((direntp = readdir(dirp))) {
			if (direntp->d_name[0] != '.') {

				//cout << direntp->d_name << endl; // use stat here to find attributes of a file
				printf(direntp->d_name, 8);
				cout << " ";
			}
		}
		cout << endl;
		closedir(dirp);
		return 0;
}

int lsWithFlags(char* directoryName, vector<string> flags) {

	bool isA = false;
	bool isL = false;
	bool isR = false;
	for (unsigned i = 0; i < flags.size(); ++i) {
		for (unsigned k = 0; k < flags.at(i).size(); ++k) {
			if (flags.at(i).at(k) == 'a')
				isA = true;
			else if (flags.at(i).at(k) == 'l')
				isL = true;
			else if (flags.at(i).at(k) == 'R')
				isR = true;
		}

	}
	char const *dirName = directoryName;
	DIR *dirp;
	if (!(dirp = opendir(dirName))) {
		cerr << "Error(" << errno << ") opening " << dirName << endl;
		return errno;
	}

	dirent *direntp;
	if (isL) {

		cout << 78 << endl;
		struct stat current;

		while ((direntp = readdir(dirp))) {

			//cout << "direntp: " << direntp << endl;
			if (-1 == (stat(direntp->d_name, &current))) {

				perror("stat failed");
				return -1;
			}
			if (direntp->d_name[0] == '-' && !isA)
				continue;
			else {

				if (current.st_mode & S_IFDIR)
					cout << "d";

				if (current.st_mode & S_IFLNK)
					cout << "l";

				if (!(current.st_mode & S_IFDIR) && !(current.st_mode & S_IFLNK))
					cout << "-";

				if (current.st_mode & S_IRUSR)
					cout << "r";
				else
					cout << "-";

				if (current.st_mode & S_IWUSR)
					cout << "w";
				else
					cout << "-";

				if (current.st_mode & S_IXUSR)
					cout << "x";
				else
					cout << "-";

				if (current.st_mode & S_IRGRP)
					cout << "r";
				else
					cout << "-";

				if (current.st_mode & S_IWGRP)
					cout << "w";
				else
					cout << "-";

				if (current.st_mode & S_IXGRP)
					cout << "x";
				else
					cout << "-";

				if (current.st_mode & S_IROTH)
					cout << "r";
				else
					cout << "-";

				if (current.st_mode & S_IWOTH)
					cout << "w";
				else
					cout << "-";

				if (current.st_mode & S_IXOTH)
					cout << "x";
				else
					cout << "-";

				cout << " ";

				cout << current.st_nlink << " ";

				cout << current.st_uid << " ";

				cout << current.st_gid << " ";

				cout << current.st_size << " ";

				char buff[20];
				struct tm * timeinfo;
				timeinfo = localtime(&(current.st_mtime));
				strftime(buff, 20, "%b %d %H:%M", timeinfo);
				printf("%s",buff);

				cout << " " << direntp->d_name;
			}
			cout << endl;

		}
		closedir(dirp);

	}

	else if (isA) {
		while ((direntp = readdir(dirp))) {

			//cout << direntp->d_name << endl; // use stat here to find attributes of a file
			printf(direntp->d_name, 8);
			cout << " ";

		}
		closedir(dirp);
	}
	return 0;
}

int main(int argc, char* argv[]) {

	if (argc == 1) {

		if (errno == ls(".")) {

			return errno;
		}
	}

	else {

		vector<string> directories;
		vector<string> flags;
		vector<int> directoryIndex;
		bool directoryInArgv = false;
		for (int i = 1; i < argc; ++i) {

			if (isDirectory(argv[i])) {
				directoryInArgv = true;

			}
			else {

				if (argv[i][0] == '-') {

					flags.push_back(argv[i]);
				}
			}
		}
		if (!directoryInArgv) {

			if (errno == lsWithFlags(".", flags)) {

				return errno;
			}
		}
		else {

			for (int i = 1; i < argc; ++i) {

				if (isDirectory(argv[i])) {
					directories.push_back(argv[i]);
					directoryIndex.push_back(i);
				}
			}

			//cout << "directories: ";
			//for (unsigned i = 0; i < directories.size(); ++i)
				//cout << directories.at(i) << " ";
			//cout << endl;

			for (unsigned int i = 0; i < directories.size(); ++i) {
				//cout << 145 << endl;
				flags.clear();

				for (int k = directoryIndex.at(i) + 1; k < argc && !isDirectory(argv[k]); ++k) {
					if (argv[k][0] == '-')
						flags.push_back(argv[k]);
				}

				char* directoryName = new char[directories.at(i).size() + 1];
				strcpy(directoryName, directories.at(i).c_str());

				if (flags.size() == 0 && directories.size() == 1) {
					//cout << 152 << endl;
					//cout << directories.at(i) << ":" << endl;
					ls(directoryName);
					cout << endl;
				}
				else if (flags.size() == 0) {
					//cout << 152 << endl;
					cout << directories.at(i) << ":" << endl;
					ls(directoryName);
					cout << endl;
				}
				else {
					cout << directories.at(i) << ":" << endl;
			   	if	(errno == lsWithFlags(directoryName, flags)) {

						return errno;
					}
					cout << endl;
				}

				delete [] directoryName;
			}
		}
	}

}

<|endoftext|>


<commit_before>#include <pwd.h>
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <string>
#include <errno.h>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <time.h>
#include <stdlib.h>

using namespace std;

//PRINTING OUT VECTOR OF FILES
void print_files(vector<string>& x) {
	unsigned z = 0;
	for(unsigned i = 0; i < x.size(); ++i) {
		if(z == 5)
			cout << endl;
		cout << setw(16) << left << x.at(i) << "  ";
			++z;
	}
	cout << endl;
	return;
}

void print_l(vector<string>& x) {
	struct stat club;
	int intake;
	string cow;
	string now;
	ssize_t g = 0;
	for(unsigned i = 0; i < x.size(); ++i) {
		now = x[i];
		if(stat(now.c_str(), &club) == -1) {
			perror("stat");
			exit(1);
		}
		g += club.st_size;
	}
	cout << "total " << g << endl;
	for(unsigned i = 0; i < x.size(); ++i) {
		cow = x[i];
		if(stat(cow.c_str(), &club) == -1) {
			perror("stat");
			exit(-1);
		}

		if(S_ISDIR(club.st_mode))
			cout << "d";
		else
			cout << "-";
		if((intake = access(cow.c_str(), R_OK)) == 0)
			cout << "r";
		else
			cout << "-";

		if((intake = access(cow.c_str(), W_OK)) == 0)
			cout << "w";
		else
			cout << "-";

		if((intake = access(cow.c_str(), X_OK)) == 0)
			cout << "x";
		else
			cout << "-";

		cout << "------" << " ";

		cout << club.st_nlink << " ";
		cout << club.st_uid << " ";
		cout << club.st_gid << " ";
		cout << setw(5) << club.st_size << " ";
		cout << setw(5) << club.st_mtime << "sec ";
		cout << left << setw(0) << x[i] << endl;
	}

}

//-a
void alphabetize2(vector<string>& x) {
	unsigned i;
	vector<string> ad;
	vector<string> qw;
	unsigned j;
	unsigned k;
	for(i = 0; i < x.size(); i++)
	{
		if(x[i][0] >= 65 && x[i][0] <= 90){
			x[i][0] += 32;
			qw.push_back(x[i]);
		}

		if(x[i][0] == '.' && x[i][1] != '.'){
 			x[i].erase(0,1);
			ad.push_back(x[i]);
		}

	}
	sort(x.begin(), x.end());
	for(i = 0; i < x.size(); i++)
	{
		for(j = 0; j < qw.size(); j++)
		{
			if(qw[j] == x[i])
				x[i][0] -= 32;
		}
		for(k = 0; k < ad.size(); k++)
		{
			if(ad[k] == x[i])
				x[i].insert(0, ".");

		}
	}
}

//default alphabetize
void alphabetize(vector<string>& x) {
	unsigned i;
	vector<string> qw;
	unsigned j;
	for(i = 0; i < x.size(); i++)
	{
		if(x[i][0] >= 65 && x[i][0] <= 90){
			x[i][0] += 32;
			qw.push_back(x[i]);
		}
	}
	sort(x.begin(), x.end());
	for(i = 0; i < x.size(); i++)
	{
		for(j = 0; j < qw.size(); j++)
		{
			if(qw[j] == x[i])
				x[i][0] -= 32;
		}
	}
}

//default
static void lookup()//const char *arg) //ls (no flags)
{
	vector<string> temp;
	DIR *start;
	struct dirent *entry;
	char* x;
	if((start=opendir(".")) == NULL)
	{
		perror("opendir");
		return;
	}

	do {
		errno = 0;
		if((entry = readdir(start)) != NULL)
		{
			x = entry->d_name;

			if(x[0] == '.')
				continue;

			temp.push_back(entry->d_name);
		}

	} while(entry != NULL);

	alphabetize(temp);
	print_files(temp);

	if(errno != 0)
		perror("error reading directory");

	closedir(start);
	return;
}

//-a
static void lookup2()//const char *arg)
{
	vector<string> temp;
	DIR *start;
	struct dirent *entry;
//	char* x;
	if((start=opendir(".")) == NULL) {
		perror("opendir");
		return;
	}

	do {
		errno = 0;
		if((entry = readdir(start)) != NULL) {

//			x = entry->d_name;

			temp.push_back(entry->d_name);
		}

	} while(entry != NULL);

	alphabetize2(temp);
	print_files(temp);

	if(errno != 0)
		perror("error reading directory");

	closedir(start);
	return;
}

//-la
static void lookup31()//const char *arg)
{
	vector<string> temp;
	DIR *start;
	struct dirent *entry;
	//char* x;
	if((start=opendir(".")) == NULL)
	{
		perror("opendir");
		return;
	}

	do {
		errno = 0;
		if((entry = readdir(start)) != NULL)
		{
			//x = entry->d_name;

			//if(x[0] == '.')
			//	continue;

			temp.push_back(entry->d_name);
		}

	} while(entry != NULL);

	alphabetize(temp);
	print_l(temp);

	if(errno != 0)
		perror("error reading directory");

	closedir(start);
	return;
}

//-l
static void lookup3()//const char *arg)
{
	vector<string> temp;
	DIR *start;
	struct dirent *entry;
	char* x;
	if((start=opendir(".")) == NULL)
	{
		perror("opendir");
		return;
	}

	do {
		errno = 0;
		if((entry = readdir(start)) != NULL)
		{
			x = entry->d_name;

			if(x[0] == '.')
				continue;

			temp.push_back(entry->d_name);
		}

	} while(entry != NULL);

	alphabetize(temp);
	print_l(temp);

	if(errno != 0)
		perror("error reading directory");

	closedir(start);
	return;
}

//ls (passed in directory
static void lookup_d1(char* q)//const char *arg)
{
	vector<string> temp;
	DIR *start;
	struct dirent *entry;
	//char* x;
	if((start=opendir(q)) == NULL)
	{
		perror("opendir");
		return;
	}

	do {
		errno = 0;
		if((entry = readdir(start)) != NULL)
		{
			//x = entry->d_name;

			//if(x[0] == '.')
			//	continue;

			temp.push_back(entry->d_name);
		}

	} while(entry != NULL);

	alphabetize(temp);
	print_files(temp);

	if(errno != 0)
		perror("error reading directory");

	closedir(start);
	return;
}

//ls (passed in directory
static void lookup_d(char* q)//const char *arg)
{
	vector<string> temp;
	DIR *start;
	struct dirent *entry;
	char* x;
	if((start=opendir(q)) == NULL)
	{
		perror("opendir");
		return;
	}

	do {
		errno = 0;
		if((entry = readdir(start)) != NULL)
		{
			x = entry->d_name;

			if(x[0] == '.')
				continue;

			temp.push_back(entry->d_name);
		}

	} while(entry != NULL);

	alphabetize(temp);
	print_files(temp);

	if(errno != 0)
		perror("error reading directory");

	closedir(start);
	return;
}

//-Ra
static void lookup41()//const char *arg)
{

	vector<string> temp;
	DIR *start;
	struct dirent *entry;
	char* x;
	//char jk[2] = {'.','.'};
	if((start=opendir(".")) == NULL)
	{
		perror("opendir");
		closedir(start);
		return;
	}

	do {
		errno = 0;
		if((entry = readdir(start)) != NULL)
		{
			if(entry->d_type == DT_DIR)
			{
				//if(entry->d_name == jk)

				//cout << entry->d_name << ":" << endl;
				x = entry->d_name;
				if(x[0] == '.' && x[1] == '.')
					continue;
				cout << x << ":" << endl;
				lookup_d1(x);

			}
		//	x = entry->d_name;

		//	if(x[0] == '.')
		//		continue;

			//temp.push_back(entry->d_name);
		}

	} while(entry != NULL);

	//do {
	//	errno = 0;
	//	if((entry = readdir(start)) != NULL)
	//	{
	//		x = entry->d_name;
	//
	//		if(x[0] == '.')
	//			continue;
//
//			temp.push_back(entry->d_name);
//		}
//	} while (entry != NULL);

	if(errno != 0)
	{
		perror("error reading directory");
		closedir(start);
		return;
	}
//	cout << entry->d_name << ":" << endl;
//
//	alphabetize(temp);
//	print_files(temp);

	closedir(start);
	return;
}

//-R
static void lookup4()//const char *arg)
{

	vector<string> temp;
	DIR *start;
	struct dirent *entry;
	char* x;
	//char jk[2] = {'.','.'};
	if((start=opendir(".")) == NULL)
	{
		perror("opendir");
		closedir(start);
		return;
	}

	do {
		errno = 0;
		if((entry = readdir(start)) != NULL)
		{
			if(entry->d_type == DT_DIR)
			{
				//if(entry->d_name == jk)

				//cout << entry->d_name << ":" << endl;
				x = entry->d_name;
				if(x[0] == '.' && x[1] == '.')
					continue;
				cout << x << ":" << endl;
				lookup_d(x);

			}
		//	x = entry->d_name;

		//	if(x[0] == '.')
		//		continue;

			//temp.push_back(entry->d_name);
		}

	} while(entry != NULL);

	//do {
	//	errno = 0;
	//	if((entry = readdir(start)) != NULL)
	//	{
	//		x = entry->d_name;
	//
	//		if(x[0] == '.')
	//			continue;
//
//			temp.push_back(entry->d_name);
//		}
//	} while (entry != NULL);

	if(errno != 0)
	{
		perror("error reading directory");
		closedir(start);
		return;
	}
//	cout << entry->d_name << ":" << endl;
//
//	alphabetize(temp);
//	print_files(temp);

	closedir(start);
	return;
}

int main( int argc, char *argv[]) {
	string flag = "-a";
	string flag2 = "-l";
	string flag3 = "-R";
//	string flag4 = "-aR";
//	string flag5 = "-al";
//	string flag6 = "-lR";
//	string flag7 = "-Rl";
//	string flag8 = "-Ra";
//	string flag9 = "-la";

	if(argc == 1)
	{
		lookup();
		return 0;
	}
	int i = 1;
	for(; i < argc; ++i) {
		if(argv[i][0] != '-'){
			lookup_d(argv[i]);
			break;
		}
		if(argv[i] == flag)
			lookup2();

		if(argv[i] == flag2)
			lookup3();

		if(argv[i] == flag3)
			lookup4();

		if(strstr(argv[i], "a") != NULL)
		{
			if(strstr(argv[i], "l") != NULL)
				lookup31();
			if(strstr(argv[i], "R") != NULL)
				lookup41();
		}

	}

	return 0;
}
<commit_msg>updated ls.cpp<commit_after>#include <pwd.h>
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <string>
#include <errno.h>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <time.h>
#include <stdlib.h>
#include <fcntl.h>

using namespace std;

//PRINTING OUT VECTOR OF FILES
void print_files(vector<string>& x) {
	unsigned z = 0;
	for(unsigned i = 0; i < x.size(); ++i) {
		if(z == 5)
			cout << endl;
		cout << setw(16) << left << x.at(i) << "  ";
			++z;
	}
	cout << endl;
	return;
}

void print_l(vector<string>& x) {
	struct stat club;
	int intake;
	string cow;
	string now;
	ssize_t g = 0;
	for(unsigned i = 0; i < x.size(); ++i) {
		now = x[i];
		int fd = open(now.c_str(), O_RDONLY);
		if(fd == -1)
		{
			perror("open");
			exit(1);
		}
		if(stat(now.c_str(), &club) == -1) {
			perror("stat");
			exit(1);
		}
		g += club.st_size;
		int fo = close(fd);
		if(fo == -1)
		{
			perror("close");
			exit(1);
		}

	}
	cout << "total " << g << endl;
	for(unsigned e = 0; e < x.size(); ++e) {
		cow = x[e];
		int fd = open(now.c_str(), O_RDONLY);
		if(fd == -1)
		{
			perror("open");
			exit(1);
		}

		if(stat(cow.c_str(), &club) == -1) {
			perror("stat");
			exit(-1);
		}

		if(S_ISDIR(club.st_mode))
			cout << "d";
		else
			cout << "-";
		if((intake = access(cow.c_str(), R_OK)) == 0)
			cout << "r";
		else
			cout << "-";

		if((intake = access(cow.c_str(), W_OK)) == 0)
			cout << "w";
		else
			cout << "-";

		if((intake = access(cow.c_str(), X_OK)) == 0)
			cout << "x";
		else
			cout << "-";

		cout << "------" << " ";

		cout << club.st_nlink << " ";
		cout << club.st_uid << " ";
		cout << club.st_gid << " ";
		cout << setw(5) << club.st_size << " ";
		cout << setw(5) << club.st_mtime << "sec ";
		cout << left << setw(0) << x[e] << endl;
		int fo = close(fd);
		if(fo == -1)
		{
			perror("close");
			exit(1);
		}

	}
//	cerr << "yas" << endl;
	return;

}

//-a
void alphabetize2(vector<string>& x) {
	unsigned i;
	vector<string> ad;
	vector<string> qw;
	unsigned j;
	unsigned k;
	for(i = 0; i < x.size(); i++)
	{
		if(x[i][0] >= 65 && x[i][0] <= 90){
			x[i][0] += 32;
			qw.push_back(x[i]);
		}

		if(x[i][0] == '.' && x[i][1] != '.'){
 			x[i].erase(0,1);
			ad.push_back(x[i]);
		}

	}
	sort(x.begin(), x.end());
	for(i = 0; i < x.size(); i++)
	{
		for(j = 0; j < qw.size(); j++)
		{
			if(qw[j] == x[i])
				x[i][0] -= 32;
		}
		for(k = 0; k < ad.size(); k++)
		{
			if(ad[k] == x[i])
				x[i].insert(0, ".");

		}
	}
}

//default alphabetize
void alphabetize(vector<string>& x) {
	unsigned i;
	vector<string> qw;
	unsigned j;
	for(i = 0; i < x.size(); i++)
	{
		if(x[i][0] >= 65 && x[i][0] <= 90){
			x[i][0] += 32;
			qw.push_back(x[i]);
		}
	}
	sort(x.begin(), x.end());
	for(i = 0; i < x.size(); i++)
	{
		for(j = 0; j < qw.size(); j++)
		{
			if(qw[j] == x[i])
				x[i][0] -= 32;
		}
	}
}

//default
static void lookup()//ls (no flags)
{
	vector<string> temp;
	DIR *start;
	struct dirent *entry;
	char* x;
	if((start=opendir(".")) == NULL)
	{
		perror("opendir");
		return;
	}

	do {
		errno = 0;
		if((entry = readdir(start)) != NULL)
		{
			x = entry->d_name;

			if(x[0] == '.')
				continue;

			temp.push_back(entry->d_name);
		}

	} while(entry != NULL);

	alphabetize(temp);
	print_files(temp);

	if(errno != 0)
		perror("error reading directory");

	closedir(start);
	return;
}

//-a
static void lookup2()
{
	vector<string> temp;
	DIR *start;
	struct dirent *entry;
	if((start=opendir(".")) == NULL) {
		perror("opendir");
		return;
	}

	do {
		errno = 0;
		if((entry = readdir(start)) != NULL) {
			temp.push_back(entry->d_name);
		}

	} while(entry != NULL);

	alphabetize2(temp);
	print_files(temp);

	if(errno != 0)
		perror("error reading directory");

	closedir(start);
	return;
}

//-la
static void lookup31()
{
	vector<string> temp;
	DIR *start;
	struct dirent *entry;

	if((start=opendir(".")) == NULL)
	{
		perror("opendir");
		return;
	}

	do {
		errno = 0;
		if((entry = readdir(start)) != NULL)
		{
			temp.push_back(entry->d_name);
		}

	} while(entry != NULL);

	alphabetize(temp);
	print_l(temp);

	if(errno != 0)
		perror("error reading directory");

	closedir(start);
	return;
}

//-l
static void lookup3()
{
	vector<string> temp;
	DIR *start;
	struct dirent *entry;
	char* x;
	if((start=opendir(".")) == NULL)
	{
		perror("opendir");
		return;
	}

	do {
		errno = 0;
		if((entry = readdir(start)) != NULL)
		{
			x = entry->d_name;

			if(x[0] == '.')
				continue;

			temp.push_back(entry->d_name);
		}

	} while(entry != NULL);

	alphabetize(temp);
	print_l(temp);

	if(errno != 0){
		cerr << "yas" << endl;
		perror("error reading directory");
	}
	closedir(start);
	return;
}

static void lookup_d1(char* q)
{
	vector<string> temp;
	DIR *start;
	struct dirent *entry;
	if((start=opendir(q)) == NULL)
	{
		perror("opendir");
		return;
	}

	do {
		errno = 0;
		if((entry = readdir(start)) != NULL)
		{
			temp.push_back(entry->d_name);
		}

	} while(entry != NULL);

	alphabetize(temp);
	print_files(temp);

	if(errno != 0)
		perror("error reading directory");

	closedir(start);
	return;
}

//-lR
static void dlookup_d(char* q)
{
	vector<string> temp;
	DIR *start;
	struct dirent *entry;
	char* x;
	if((start=opendir(q)) == NULL)
	{
		perror("opendir");
		return;
	}

	do {
		errno = 0;
		if((entry = readdir(start)) != NULL)
		{
			x = entry->d_name;

			if(x[0] == '.')
				continue;

			temp.push_back(entry->d_name);
		}

	} while(entry != NULL);

	alphabetize(temp);
	print_l(temp);

	if(errno != 0)
		perror("error reading directory");

	closedir(start);
	return;
}

//ls (passed in directory
static void lookup_d(char* q)
{
	vector<string> temp;
	DIR *start;
	struct dirent *entry;
	char* x;
	if((start=opendir(q)) == NULL)
	{
		perror("opendir");
		return;
	}

	do {
		errno = 0;
		if((entry = readdir(start)) != NULL)
		{
			x = entry->d_name;

			if(x[0] == '.')
				continue;

			temp.push_back(entry->d_name);
		}

	} while(entry != NULL);

	alphabetize(temp);
	print_files(temp);

	if(errno != 0)
		perror("error reading directory");

	closedir(start);
	return;
}

//-Ra
static void lookup41()
{

	vector<string> temp;
	DIR *start;
	struct dirent *entry;
	char* x;
	if((start=opendir(".")) == NULL)
	{
		perror("opendir");
		closedir(start);
		return;
	}

	do {
		errno = 0;
		if((entry = readdir(start)) != NULL)
		{
			if(entry->d_type == DT_DIR)
			{
				x = entry->d_name;
				if(x[0] == '.' && x[1] == '.')
					continue;
				cout << x << ":" << endl;
				lookup_d1(x);

			}

		}

	} while(entry != NULL);

	if(errno != 0)
	{
		perror("error reading directory");
		closedir(start);
		return;
	}

	closedir(start);
	return;
}

//-R
static void lookup4()
{

	vector<string> temp;
	DIR *start;
	struct dirent *entry;
	char* x;

	if((start=opendir(".")) == NULL)
	{
		perror("opendir");
		closedir(start);
		return;
	}

	do {
		errno = 0;
		if((entry = readdir(start)) != NULL)
		{
			if(entry->d_type == DT_DIR)
			{
				x = entry->d_name;
				if(x[0] == '.' && x[1] == '.')
					continue;
				cout << x << ":" << endl;
				lookup_d(x);

			}
		}

	} while(entry != NULL);

	if(errno != 0)
	{
		perror("error reading directory");
		closedir(start);
		return;
	}
	closedir(start);
	return;
}

//-Rl
static void lookup42()
{

	vector<string> temp;
	DIR *start;
	struct dirent *entry;
	char* x;

	if((start=opendir(".")) == NULL)
	{
		perror("opendir");
		closedir(start);
		return;
	}

	do {
		errno = 0;
		if((entry = readdir(start)) != NULL)
		{
			if(entry->d_type == DT_DIR)
			{
				x = entry->d_name;
				if(x[0] == '.' && x[1] == '.')
					continue;
				cout << x << ":" << endl;
				dlookup_d(x);

			}

		}

	} while(entry != NULL);

	if(errno != 0)
	{
		perror("error reading directory");
		closedir(start);
		return;
	}

	closedir(start);
	return;
}

int main( int argc, char *argv[]) {
	string flag = "-a";
	string flag2 = "-l";
	string flag3 = "-R";

	if(argc == 1)
	{
		lookup();
		return 0;
	}
	int i = 1;
	for(; i < argc; ++i) {
		if(argv[i][0] != '-'){
			lookup_d(argv[i]);
			break;
		}
		if(argv[i] == flag)
			lookup2();

		if(argv[i] == flag2)
			lookup3();

		if(argv[i] == flag3)
			lookup4();

		if(strstr(argv[i], "a") != NULL)
		{
			if(strstr(argv[i], "l") != NULL)
				lookup31();
			if(strstr(argv[i], "R") != NULL)
				lookup41();
		}

		if(strstr(argv[i], "l") != NULL)
		{
			if(strstr(argv[i], "R") != NULL)
				lookup42();
		}
	}

	return 0;
}
<|endoftext|>


<commit_before>/*
 *
 * Copyright 2019 The gRPC Authors
 *
 * 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.
 *
 */

#include "src/core/lib/iomgr/port.h"

#include <algorithm>
#include <memory>
#include <mutex>
#include <random>
#include <thread>

#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/atm.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/time.h>
#include <grpcpp/channel.h>
#include <grpcpp/client_context.h>
#include <grpcpp/create_channel.h>
#include <grpcpp/health_check_service_interface.h>
#include <grpcpp/server.h>
#include <grpcpp/server_builder.h>
#include <gtest/gtest.h>

#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/gpr/env.h"

#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
#include "test/cpp/end2end/test_service_impl.h"
#include "test/cpp/util/test_credentials_provider.h"

#ifdef GRPC_CFSTREAM
using grpc::ClientAsyncResponseReader;
using grpc::testing::EchoRequest;
using grpc::testing::EchoResponse;
using grpc::testing::RequestParams;
using std::chrono::system_clock;

namespace grpc {
namespace testing {
namespace {

struct TestScenario {
  TestScenario(const grpc::string& creds_type, const grpc::string& content)
      : credentials_type(creds_type), message_content(content) {}
  const grpc::string credentials_type;
  const grpc::string message_content;
};

class CFStreamTest : public ::testing::TestWithParam<TestScenario> {
 protected:
  CFStreamTest()
      : server_host_("grpctest"),
        interface_("lo0"),
        ipv4_address_("10.0.0.1") {}

  void DNSUp() {
    std::ostringstream cmd;
    // Add DNS entry for server_host_ in /etc/hosts
    cmd << "echo '" << ipv4_address_ << "      " << server_host_
        << "  ' | sudo tee -a /etc/hosts";
    std::system(cmd.str().c_str());
  }

  void DNSDown() {
    std::ostringstream cmd;
    // Remove DNS entry for server_host_ in /etc/hosts
    cmd << "sudo sed -i '.bak' '/" << server_host_ << "/d' /etc/hosts";
    std::system(cmd.str().c_str());
  }

  void InterfaceUp() {
    std::ostringstream cmd;
    cmd << "sudo /sbin/ifconfig " << interface_ << " alias " << ipv4_address_;
    std::system(cmd.str().c_str());
  }

  void InterfaceDown() {
    std::ostringstream cmd;
    cmd << "sudo /sbin/ifconfig " << interface_ << " -alias " << ipv4_address_;
    std::system(cmd.str().c_str());
  }

  void NetworkUp() {
    gpr_log(GPR_DEBUG, "Bringing network up");
    InterfaceUp();
    DNSUp();
  }

  void NetworkDown() {
    gpr_log(GPR_DEBUG, "Bringing network down");
    InterfaceDown();
    DNSDown();
  }

  void SetUp() override {
    NetworkUp();
    grpc_init();
    StartServer();
  }

  void TearDown() override {
    NetworkDown();
    StopServer();
    grpc_shutdown();
  }

  void StartServer() {
    port_ = grpc_pick_unused_port_or_die();
    server_.reset(new ServerData(port_, GetParam().credentials_type));
    server_->Start(server_host_);
  }
  void StopServer() { server_->Shutdown(); }

  std::unique_ptr<grpc::testing::EchoTestService::Stub> BuildStub(
      const std::shared_ptr<Channel>& channel) {
    return grpc::testing::EchoTestService::NewStub(channel);
  }

  std::shared_ptr<Channel> BuildChannel() {
    std::ostringstream server_address;
    server_address << server_host_ << ":" << port_;
    ChannelArguments args;
    auto channel_creds = GetCredentialsProvider()->GetChannelCredentials(
        GetParam().credentials_type, &args);
    return CreateCustomChannel(server_address.str(), channel_creds, args);
  }

  void SendRpc(
      const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub,
      bool expect_success = false) {
    auto response = std::unique_ptr<EchoResponse>(new EchoResponse());
    EchoRequest request;
    auto& msg = GetParam().message_content;
    request.set_message(msg);
    ClientContext context;
    Status status = stub->Echo(&context, request, response.get());
    if (status.ok()) {
      EXPECT_EQ(msg, response->message());
    } else {
      gpr_log(GPR_DEBUG, "RPC failed: %s", status.error_message().c_str());
    }
    if (expect_success) {
      EXPECT_TRUE(status.ok());
    }
  }
  void SendAsyncRpc(
      const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub,
      RequestParams param = RequestParams()) {
    EchoRequest request;
    request.set_message(GetParam().message_content);
    *request.mutable_param() = std::move(param);
    AsyncClientCall* call = new AsyncClientCall;

    call->response_reader =
        stub->PrepareAsyncEcho(&call->context, request, &cq_);

    call->response_reader->StartCall();
    call->response_reader->Finish(&call->reply, &call->status, (void*)call);
  }

  void ShutdownCQ() { cq_.Shutdown(); }

  bool CQNext(void** tag, bool* ok) { return cq_.Next(tag, ok); }

  bool WaitForChannelNotReady(Channel* channel, int timeout_seconds = 5) {
    const gpr_timespec deadline =
        grpc_timeout_seconds_to_deadline(timeout_seconds);
    grpc_connectivity_state state;
    while ((state = channel->GetState(false /* try_to_connect */)) ==
           GRPC_CHANNEL_READY) {
      if (!channel->WaitForStateChange(state, deadline)) return false;
    }
    return true;
  }

  bool WaitForChannelReady(Channel* channel, int timeout_seconds = 10) {
    const gpr_timespec deadline =
        grpc_timeout_seconds_to_deadline(timeout_seconds);
    grpc_connectivity_state state;
    while ((state = channel->GetState(true /* try_to_connect */)) !=
           GRPC_CHANNEL_READY) {
      if (!channel->WaitForStateChange(state, deadline)) return false;
    }
    return true;
  }

  struct AsyncClientCall {
    EchoResponse reply;
    ClientContext context;
    Status status;
    std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader;
  };

 private:
  struct ServerData {
    int port_;
    const grpc::string creds_;
    std::unique_ptr<Server> server_;
    TestServiceImpl service_;
    std::unique_ptr<std::thread> thread_;
    bool server_ready_ = false;

    ServerData(int port, const grpc::string& creds)
        : port_(port), creds_(creds) {}

    void Start(const grpc::string& server_host) {
      gpr_log(GPR_INFO, "starting server on port %d", port_);
      std::mutex mu;
      std::unique_lock<std::mutex> lock(mu);
      std::condition_variable cond;
      thread_.reset(new std::thread(
          std::bind(&ServerData::Serve, this, server_host, &mu, &cond)));
      cond.wait(lock, [this] { return server_ready_; });
      server_ready_ = false;
      gpr_log(GPR_INFO, "server startup complete");
    }

    void Serve(const grpc::string& server_host, std::mutex* mu,
               std::condition_variable* cond) {
      std::ostringstream server_address;
      server_address << server_host << ":" << port_;
      ServerBuilder builder;
      auto server_creds =
          GetCredentialsProvider()->GetServerCredentials(creds_);
      builder.AddListeningPort(server_address.str(), server_creds);
      builder.RegisterService(&service_);
      server_ = builder.BuildAndStart();
      std::lock_guard<std::mutex> lock(*mu);
      server_ready_ = true;
      cond->notify_one();
    }

    void Shutdown(bool join = true) {
      server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0));
      if (join) thread_->join();
    }
  };

  CompletionQueue cq_;
  const grpc::string server_host_;
  const grpc::string interface_;
  const grpc::string ipv4_address_;
  std::unique_ptr<ServerData> server_;
  int port_;
};

std::vector<TestScenario> CreateTestScenarios() {
  std::vector<TestScenario> scenarios;
  std::vector<grpc::string> credentials_types;
  std::vector<grpc::string> messages;

  credentials_types.push_back(kInsecureCredentialsType);
  auto sec_list = GetCredentialsProvider()->GetSecureCredentialsTypeList();
  for (auto sec = sec_list.begin(); sec != sec_list.end(); sec++) {
    credentials_types.push_back(*sec);
  }

  messages.push_back("🖖");
  for (size_t k = 1; k < GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH / 1024; k *= 32) {
    grpc::string big_msg;
    for (size_t i = 0; i < k * 1024; ++i) {
      char c = 'a' + (i % 26);
      big_msg += c;
    }
    messages.push_back(big_msg);
  }
  for (auto cred = credentials_types.begin(); cred != credentials_types.end();
       ++cred) {
    for (auto msg = messages.begin(); msg != messages.end(); msg++) {
      scenarios.emplace_back(*cred, *msg);
    }
  }

  return scenarios;
}

INSTANTIATE_TEST_CASE_P(CFStreamTest, CFStreamTest,
                        ::testing::ValuesIn(CreateTestScenarios()));

// gRPC should automatically detech network flaps (without enabling keepalives)
//  when CFStream is enabled
TEST_P(CFStreamTest, NetworkTransition) {
  auto channel = BuildChannel();
  auto stub = BuildStub(channel);
  // Channel should be in READY state after we send an RPC
  SendRpc(stub, /*expect_success=*/true);
  EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY);

  std::atomic_bool shutdown{false};
  std::thread sender = std::thread([this, &stub, &shutdown]() {
    while (true) {
      if (shutdown.load()) {
        return;
      }
      SendRpc(stub);
      std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }
  });

  // bring down network
  NetworkDown();

  // network going down should be detected by cfstream
  EXPECT_TRUE(WaitForChannelNotReady(channel.get()));

  // bring network interface back up
  std::this_thread::sleep_for(std::chrono::milliseconds(1000));
  NetworkUp();

  // channel should reconnect
  EXPECT_TRUE(WaitForChannelReady(channel.get()));
  EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY);
  shutdown.store(true);
  sender.join();
}

// Network flaps while RPCs are in flight
TEST_P(CFStreamTest, NetworkFlapRpcsInFlight) {
  auto channel = BuildChannel();
  auto stub = BuildStub(channel);
  std::atomic_int rpcs_sent{0};

  // Channel should be in READY state after we send some RPCs
  for (int i = 0; i < 10; ++i) {
    SendAsyncRpc(stub);
    ++rpcs_sent;
  }
  EXPECT_TRUE(WaitForChannelReady(channel.get()));

  // Bring down the network
  NetworkDown();

  std::thread thd = std::thread([this, &rpcs_sent]() {
    void* got_tag;
    bool ok = false;
    bool network_down = true;
    int total_completions = 0;

    while (CQNext(&got_tag, &ok)) {
      ++total_completions;
      GPR_ASSERT(ok);
      AsyncClientCall* call = static_cast<AsyncClientCall*>(got_tag);
      if (!call->status.ok()) {
        gpr_log(GPR_DEBUG, "RPC failed with error: %s",
                call->status.error_message().c_str());
        // Bring network up when RPCs start failing
        if (network_down) {
          NetworkUp();
          network_down = false;
        }
      }
      delete call;
    }
    EXPECT_EQ(total_completions, rpcs_sent);
  });

  for (int i = 0; i < 100; ++i) {
    SendAsyncRpc(stub);
    std::this_thread::sleep_for(std::chrono::milliseconds(10));
    ++rpcs_sent;
  }

  ShutdownCQ();

  thd.join();
}

// Send a bunch of RPCs, some of which are expected to fail.
// We should get back a response for all RPCs
TEST_P(CFStreamTest, ConcurrentRpc) {
  auto channel = BuildChannel();
  auto stub = BuildStub(channel);
  std::atomic_int rpcs_sent{0};
  std::thread thd = std::thread([this, &rpcs_sent]() {
    void* got_tag;
    bool ok = false;
    bool network_down = true;
    int total_completions = 0;

    while (CQNext(&got_tag, &ok)) {
      ++total_completions;
      GPR_ASSERT(ok);
      AsyncClientCall* call = static_cast<AsyncClientCall*>(got_tag);
      if (!call->status.ok()) {
        gpr_log(GPR_DEBUG, "RPC failed: %s",
                call->status.error_message().c_str());
        // Bring network up when RPCs start failing
        if (network_down) {
          NetworkUp();
          network_down = false;
        }
      }
      delete call;
    }
    EXPECT_EQ(total_completions, rpcs_sent);
  });

  for (int i = 0; i < 10; ++i) {
    if (i % 3 == 0) {
      RequestParams param;
      ErrorStatus* error = param.mutable_expected_error();
      error->set_code(StatusCode::INTERNAL);
      error->set_error_message("internal error");
      SendAsyncRpc(stub, param);
    } else if (i % 5 == 0) {
      RequestParams param;
      param.set_echo_metadata(true);
      DebugInfo* info = param.mutable_debug_info();
      info->add_stack_entries("stack_entry1");
      info->add_stack_entries("stack_entry2");
      info->set_detail("detailed debug info");
      SendAsyncRpc(stub, param);
    } else {
      SendAsyncRpc(stub);
    }
    ++rpcs_sent;
  }

  ShutdownCQ();

  thd.join();
}

}  // namespace
}  // namespace testing
}  // namespace grpc
#endif  // GRPC_CFSTREAM

int main(int argc, char** argv) {
  ::testing::InitGoogleTest(&argc, argv);
  grpc_test_init(argc, argv);
  gpr_setenv("grpc_cfstream", "1");
  const auto result = RUN_ALL_TESTS();
  return result;
}
<commit_msg>Fix cfstream_test flake<commit_after>/*
 *
 * Copyright 2019 The gRPC Authors
 *
 * 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.
 *
 */

#include "src/core/lib/iomgr/port.h"

#include <algorithm>
#include <memory>
#include <mutex>
#include <random>
#include <thread>

#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/atm.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
#include <grpc/support/time.h>
#include <grpcpp/channel.h>
#include <grpcpp/client_context.h>
#include <grpcpp/create_channel.h>
#include <grpcpp/health_check_service_interface.h>
#include <grpcpp/server.h>
#include <grpcpp/server_builder.h>
#include <gtest/gtest.h>

#include "src/core/lib/backoff/backoff.h"
#include "src/core/lib/gpr/env.h"

#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
#include "test/cpp/end2end/test_service_impl.h"
#include "test/cpp/util/test_credentials_provider.h"

#ifdef GRPC_CFSTREAM
using grpc::ClientAsyncResponseReader;
using grpc::testing::EchoRequest;
using grpc::testing::EchoResponse;
using grpc::testing::RequestParams;
using std::chrono::system_clock;

namespace grpc {
namespace testing {
namespace {

struct TestScenario {
  TestScenario(const grpc::string& creds_type, const grpc::string& content)
      : credentials_type(creds_type), message_content(content) {}
  const grpc::string credentials_type;
  const grpc::string message_content;
};

class CFStreamTest : public ::testing::TestWithParam<TestScenario> {
 protected:
  CFStreamTest()
      : server_host_("grpctest"),
        interface_("lo0"),
        ipv4_address_("10.0.0.1") {}

  void DNSUp() {
    std::ostringstream cmd;
    // Add DNS entry for server_host_ in /etc/hosts
    cmd << "echo '" << ipv4_address_ << "      " << server_host_
        << "  ' | sudo tee -a /etc/hosts";
    std::system(cmd.str().c_str());
  }

  void DNSDown() {
    std::ostringstream cmd;
    // Remove DNS entry for server_host_ in /etc/hosts
    cmd << "sudo sed -i '.bak' '/" << server_host_ << "/d' /etc/hosts";
    std::system(cmd.str().c_str());
  }

  void InterfaceUp() {
    std::ostringstream cmd;
    cmd << "sudo /sbin/ifconfig " << interface_ << " alias " << ipv4_address_;
    std::system(cmd.str().c_str());
  }

  void InterfaceDown() {
    std::ostringstream cmd;
    cmd << "sudo /sbin/ifconfig " << interface_ << " -alias " << ipv4_address_;
    std::system(cmd.str().c_str());
  }

  void NetworkUp() {
    gpr_log(GPR_DEBUG, "Bringing network up");
    InterfaceUp();
    DNSUp();
  }

  void NetworkDown() {
    gpr_log(GPR_DEBUG, "Bringing network down");
    InterfaceDown();
    DNSDown();
  }

  void SetUp() override {
    NetworkUp();
    grpc_init();
    StartServer();
  }

  void TearDown() override {
    NetworkDown();
    StopServer();
    grpc_shutdown();
  }

  void StartServer() {
    port_ = grpc_pick_unused_port_or_die();
    server_.reset(new ServerData(port_, GetParam().credentials_type));
    server_->Start(server_host_);
  }
  void StopServer() { server_->Shutdown(); }

  std::unique_ptr<grpc::testing::EchoTestService::Stub> BuildStub(
      const std::shared_ptr<Channel>& channel) {
    return grpc::testing::EchoTestService::NewStub(channel);
  }

  std::shared_ptr<Channel> BuildChannel() {
    std::ostringstream server_address;
    server_address << server_host_ << ":" << port_;
    ChannelArguments args;
    auto channel_creds = GetCredentialsProvider()->GetChannelCredentials(
        GetParam().credentials_type, &args);
    return CreateCustomChannel(server_address.str(), channel_creds, args);
  }

  void SendRpc(
      const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub,
      bool expect_success = false) {
    auto response = std::unique_ptr<EchoResponse>(new EchoResponse());
    EchoRequest request;
    auto& msg = GetParam().message_content;
    request.set_message(msg);
    ClientContext context;
    Status status = stub->Echo(&context, request, response.get());
    if (status.ok()) {
      EXPECT_EQ(msg, response->message());
    } else {
      gpr_log(GPR_DEBUG, "RPC failed: %s", status.error_message().c_str());
    }
    if (expect_success) {
      EXPECT_TRUE(status.ok());
    }
  }
  void SendAsyncRpc(
      const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub,
      RequestParams param = RequestParams()) {
    EchoRequest request;
    request.set_message(GetParam().message_content);
    *request.mutable_param() = std::move(param);
    AsyncClientCall* call = new AsyncClientCall;

    call->response_reader =
        stub->PrepareAsyncEcho(&call->context, request, &cq_);

    call->response_reader->StartCall();
    call->response_reader->Finish(&call->reply, &call->status, (void*)call);
  }

  void ShutdownCQ() { cq_.Shutdown(); }

  bool CQNext(void** tag, bool* ok) { return cq_.Next(tag, ok); }

  bool WaitForChannelNotReady(Channel* channel, int timeout_seconds = 5) {
    const gpr_timespec deadline =
        grpc_timeout_seconds_to_deadline(timeout_seconds);
    grpc_connectivity_state state;
    while ((state = channel->GetState(false /* try_to_connect */)) ==
           GRPC_CHANNEL_READY) {
      if (!channel->WaitForStateChange(state, deadline)) return false;
    }
    return true;
  }

  bool WaitForChannelReady(Channel* channel, int timeout_seconds = 10) {
    const gpr_timespec deadline =
        grpc_timeout_seconds_to_deadline(timeout_seconds);
    grpc_connectivity_state state;
    while ((state = channel->GetState(true /* try_to_connect */)) !=
           GRPC_CHANNEL_READY) {
      if (!channel->WaitForStateChange(state, deadline)) return false;
    }
    return true;
  }

  struct AsyncClientCall {
    EchoResponse reply;
    ClientContext context;
    Status status;
    std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader;
  };

 private:
  struct ServerData {
    int port_;
    const grpc::string creds_;
    std::unique_ptr<Server> server_;
    TestServiceImpl service_;
    std::unique_ptr<std::thread> thread_;
    bool server_ready_ = false;

    ServerData(int port, const grpc::string& creds)
        : port_(port), creds_(creds) {}

    void Start(const grpc::string& server_host) {
      gpr_log(GPR_INFO, "starting server on port %d", port_);
      std::mutex mu;
      std::unique_lock<std::mutex> lock(mu);
      std::condition_variable cond;
      thread_.reset(new std::thread(
          std::bind(&ServerData::Serve, this, server_host, &mu, &cond)));
      cond.wait(lock, [this] { return server_ready_; });
      server_ready_ = false;
      gpr_log(GPR_INFO, "server startup complete");
    }

    void Serve(const grpc::string& server_host, std::mutex* mu,
               std::condition_variable* cond) {
      std::ostringstream server_address;
      server_address << server_host << ":" << port_;
      ServerBuilder builder;
      auto server_creds =
          GetCredentialsProvider()->GetServerCredentials(creds_);
      builder.AddListeningPort(server_address.str(), server_creds);
      builder.RegisterService(&service_);
      server_ = builder.BuildAndStart();
      std::lock_guard<std::mutex> lock(*mu);
      server_ready_ = true;
      cond->notify_one();
    }

    void Shutdown(bool join = true) {
      server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0));
      if (join) thread_->join();
    }
  };

  CompletionQueue cq_;
  const grpc::string server_host_;
  const grpc::string interface_;
  const grpc::string ipv4_address_;
  std::unique_ptr<ServerData> server_;
  int port_;
};

std::vector<TestScenario> CreateTestScenarios() {
  std::vector<TestScenario> scenarios;
  std::vector<grpc::string> credentials_types;
  std::vector<grpc::string> messages;

  credentials_types.push_back(kInsecureCredentialsType);
  auto sec_list = GetCredentialsProvider()->GetSecureCredentialsTypeList();
  for (auto sec = sec_list.begin(); sec != sec_list.end(); sec++) {
    credentials_types.push_back(*sec);
  }

  messages.push_back("🖖");
  for (size_t k = 1; k < GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH / 1024; k *= 32) {
    grpc::string big_msg;
    for (size_t i = 0; i < k * 1024; ++i) {
      char c = 'a' + (i % 26);
      big_msg += c;
    }
    messages.push_back(big_msg);
  }
  for (auto cred = credentials_types.begin(); cred != credentials_types.end();
       ++cred) {
    for (auto msg = messages.begin(); msg != messages.end(); msg++) {
      scenarios.emplace_back(*cred, *msg);
    }
  }

  return scenarios;
}

INSTANTIATE_TEST_CASE_P(CFStreamTest, CFStreamTest,
                        ::testing::ValuesIn(CreateTestScenarios()));

// gRPC should automatically detech network flaps (without enabling keepalives)
//  when CFStream is enabled
TEST_P(CFStreamTest, NetworkTransition) {
  auto channel = BuildChannel();
  auto stub = BuildStub(channel);
  // Channel should be in READY state after we send an RPC
  SendRpc(stub, /*expect_success=*/true);
  EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY);

  std::atomic_bool shutdown{false};
  std::thread sender = std::thread([this, &stub, &shutdown]() {
    while (true) {
      if (shutdown.load()) {
        return;
      }
      SendRpc(stub);
      std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    }
  });

  // bring down network
  NetworkDown();

  // network going down should be detected by cfstream
  EXPECT_TRUE(WaitForChannelNotReady(channel.get()));

  // bring network interface back up
  std::this_thread::sleep_for(std::chrono::milliseconds(1000));
  NetworkUp();

  // channel should reconnect
  EXPECT_TRUE(WaitForChannelReady(channel.get()));
  EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY);
  shutdown.store(true);
  sender.join();
}

// Network flaps while RPCs are in flight
TEST_P(CFStreamTest, NetworkFlapRpcsInFlight) {
  auto channel = BuildChannel();
  auto stub = BuildStub(channel);
  std::atomic_int rpcs_sent{0};

  // Channel should be in READY state after we send some RPCs
  for (int i = 0; i < 10; ++i) {
    RequestParams param;
    param.set_skip_cancelled_check(true);
    SendAsyncRpc(stub, param);
    ++rpcs_sent;
  }
  EXPECT_TRUE(WaitForChannelReady(channel.get()));

  // Bring down the network
  NetworkDown();

  std::thread thd = std::thread([this, &rpcs_sent]() {
    void* got_tag;
    bool ok = false;
    bool network_down = true;
    int total_completions = 0;

    while (CQNext(&got_tag, &ok)) {
      ++total_completions;
      GPR_ASSERT(ok);
      AsyncClientCall* call = static_cast<AsyncClientCall*>(got_tag);
      if (!call->status.ok()) {
        gpr_log(GPR_DEBUG, "RPC failed with error: %s",
                call->status.error_message().c_str());
        // Bring network up when RPCs start failing
        if (network_down) {
          NetworkUp();
          network_down = false;
        }
      }
      delete call;
    }
    EXPECT_EQ(total_completions, rpcs_sent);
  });

  for (int i = 0; i < 100; ++i) {
    RequestParams param;
    param.set_skip_cancelled_check(true);
    SendAsyncRpc(stub, param);
    std::this_thread::sleep_for(std::chrono::milliseconds(10));
    ++rpcs_sent;
  }

  ShutdownCQ();

  thd.join();
}

// Send a bunch of RPCs, some of which are expected to fail.
// We should get back a response for all RPCs
TEST_P(CFStreamTest, ConcurrentRpc) {
  auto channel = BuildChannel();
  auto stub = BuildStub(channel);
  std::atomic_int rpcs_sent{0};
  std::thread thd = std::thread([this, &rpcs_sent]() {
    void* got_tag;
    bool ok = false;
    bool network_down = true;
    int total_completions = 0;

    while (CQNext(&got_tag, &ok)) {
      ++total_completions;
      GPR_ASSERT(ok);
      AsyncClientCall* call = static_cast<AsyncClientCall*>(got_tag);
      if (!call->status.ok()) {
        gpr_log(GPR_DEBUG, "RPC failed: %s",
                call->status.error_message().c_str());
        // Bring network up when RPCs start failing
        if (network_down) {
          NetworkUp();
          network_down = false;
        }
      }
      delete call;
    }
    EXPECT_EQ(total_completions, rpcs_sent);
  });

  for (int i = 0; i < 10; ++i) {
    if (i % 3 == 0) {
      RequestParams param;
      ErrorStatus* error = param.mutable_expected_error();
      error->set_code(StatusCode::INTERNAL);
      error->set_error_message("internal error");
      SendAsyncRpc(stub, param);
    } else if (i % 5 == 0) {
      RequestParams param;
      param.set_echo_metadata(true);
      DebugInfo* info = param.mutable_debug_info();
      info->add_stack_entries("stack_entry1");
      info->add_stack_entries("stack_entry2");
      info->set_detail("detailed debug info");
      SendAsyncRpc(stub, param);
    } else {
      SendAsyncRpc(stub);
    }
    ++rpcs_sent;
  }

  ShutdownCQ();

  thd.join();
}

}  // namespace
}  // namespace testing
}  // namespace grpc
#endif  // GRPC_CFSTREAM

int main(int argc, char** argv) {
  ::testing::InitGoogleTest(&argc, argv);
  grpc_test_init(argc, argv);
  gpr_setenv("grpc_cfstream", "1");
  const auto result = RUN_ALL_TESTS();
  return result;
}
<|endoftext|>


<commit_before>#define CATCH_CONFIG_MAIN

#include "Catch.hpp"
#include "ModbusConsts.hpp"
#include "ModbusTypes.hpp"
#include "ModbusEncoder.hpp"
#include "ModbusDecoder.hpp"
#include "OutputFormatter.hpp"
#include "VerboseStandardOutputFormatter.hpp"
#include "ModbusClient.hpp"
#include "ModbusCommand.hpp"
#include "ModbusReadCoilsCommand.hpp"

#include <thread>

TEST_CASE("readcoils", "[cli]") {
    ReadCoilsCommand cmd;
    std::unique_ptr<OutputFormatter> fmt(new VerboseStandardOutputFormatter());

    class MyServer {
    public:
        MyServer(boost::asio::io_service& io) :
            m_io(io)
        {}

        void start() {
            boost::asio::ip::tcp::acceptor acceptor(m_io);
            acceptor.open(boost::asio::ip::tcp::v4());
            acceptor.set_option(boost::asio::socket_base::reuse_address(true));
            acceptor.bind(boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 8502));
            acceptor.listen();

            std::cout << "waiting for connection" << std::endl;
            boost::asio::ip::tcp::socket client_socket(m_io);
            acceptor.accept(client_socket);
            std::cout << "received connection... waiting 12 bytes" << std::endl;

            std::vector<uint8_t> rx_buffer;
            rx_buffer.resize(12);
            boost::asio::read(client_socket, boost::asio::buffer(rx_buffer));
            std::cout << "received 12 bytes" << std::endl;
            REQUIRE(rx_buffer == (std::vector<uint8_t>{0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0xab, 0x01, 0x00, 0x14, 0x00, 0x08}));

            std::vector<uint8_t> tx_buffer{0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x01, 0x01, 0b01001100};
            boost::asio::write(client_socket, boost::asio::buffer(tx_buffer));
        }

    private:
        boost::asio::io_service &m_io;
    };

    boost::asio::io_service io;
    MyServer server(io);
    std::thread t([&server]() { server.start(); });
    usleep(5000);

    ModbusClient client(modbus::tcp::UnitId(0xab), std::move(fmt));
    client.connect(boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 8502));

    cmd.exec(client, std::vector<std::string>{"--startAddress", "20", "--numCoils", "8"});

    t.join();
}

<commit_msg>Test verbose output for readcoils<commit_after>#define CATCH_CONFIG_MAIN

#include "Catch.hpp"
#include "ModbusConsts.hpp"
#include "ModbusTypes.hpp"
#include "ModbusEncoder.hpp"
#include "ModbusDecoder.hpp"
#include "OutputFormatter.hpp"
#include "VerboseStandardOutputFormatter.hpp"
#include "ModbusClient.hpp"
#include "ModbusCommand.hpp"
#include "ModbusReadCoilsCommand.hpp"

#include <thread>

TEST_CASE("readcoils - normal case", "[cli]") {
    class MyServer {
    public:
        MyServer(boost::asio::io_service& io) :
            m_io(io)
        {}

        void start() {
            boost::asio::ip::tcp::acceptor acceptor(m_io);
            acceptor.open(boost::asio::ip::tcp::v4());
            acceptor.set_option(boost::asio::socket_base::reuse_address(true));
            acceptor.bind(boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 8502));
            acceptor.listen();

            std::cout << "waiting for connection" << std::endl;
            boost::asio::ip::tcp::socket client_socket(m_io);
            acceptor.accept(client_socket);
            std::cout << "received connection... waiting 12 bytes" << std::endl;

            std::vector<uint8_t> rx_buffer;
            rx_buffer.resize(12);
            boost::asio::read(client_socket, boost::asio::buffer(rx_buffer));
            std::cout << "received 12 bytes" << std::endl;
            REQUIRE(rx_buffer == (std::vector<uint8_t>{0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0xab, 0x01, 0x00, 0x14, 0x00, 0x08}));

            std::vector<uint8_t> tx_buffer{0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0xab, 0x01, 0x01, 0b01001100};
            boost::asio::write(client_socket, boost::asio::buffer(tx_buffer));
        }

    private:
        boost::asio::io_service &m_io;
    };

    // start dummy server
    boost::asio::io_service io;
    MyServer server(io);
    std::thread t([&server]() { server.start(); });
    usleep(5000);

    // Create a ModbusClient that sends verbose output to a stringstream
    std::stringstream out;
    ReadCoilsCommand cmd;
    std::unique_ptr<OutputFormatter> fmt(new VerboseStandardOutputFormatter(out));
    ModbusClient client(modbus::tcp::UnitId(0xab), std::move(fmt));

    // Connect to dummy server and execute readcoils command
    client.connect(boost::asio::ip::tcp::endpoint(boost::asio::ip::address::from_string("127.0.0.1"), 8502));
    cmd.exec(client, std::vector<std::string>{"--startAddress", "20", "--numCoils", "8"});

    // Dummy server is done now
    t.join();

    // Make sure that output printed by the command is correct
    std::stringstream expected_out;
    expected_out <<
           "          req: [00 01 00 00 00 06 ab 01 00 14 00 08 ]" << std::endl
        << "          rsp: [00 01 00 00 00 04 ab 01 01 4c ]" << std::endl
        << "       unitId: 0xab" << std::endl
        << "function code: 0x01" << std::endl
        << "transactionId: 0x0001" << std::endl
        << "         bits: 0 0 1 1 0 0 1 0 " << std::endl;

    REQUIRE(expected_out.str() == out.str());
}

<|endoftext|>


<commit_before>#include "polls.h"

#include <fastcgi2/stream.h>
#include <rapidjson/document.h>
#include <rapidjson/prettywriter.h>

#include <string>
#include <iostream>

namespace {

const size_t POLL_PREFIX_SIZE = sizeof("/polls/") - 1;

bool IsListPolls(const std::string& path, const std::string& method) {
    return path == "/polls" && method == "GET";
}

bool IsPollCreate(const std::string& path, const std::string& method) {
    return path == "/polls" && method == "POST";
}

bool IsPollInfo(const std::string& path, const std::string& method, std::string* pollId) {
    if (method == "GET" &&
        path.find("/polls/") == 0 && path.find('/', POLL_PREFIX_SIZE) == std::string::npos)
    {
        *pollId = path.substr(POLL_PREFIX_SIZE);
        return true;
    }
    return false;
}

bool IsPollVote(const std::string& path, const std::string& method,
                std::string* pollId, std::string* voteId)
{
    if (method == "POST" && path.find("/polls/") == 0) {
        auto slashLeftPos = path.find('/', POLL_PREFIX_SIZE);
        auto slashRightPos = path.rfind('/');
        if (slashRightPos == slashLeftPos && slashLeftPos > POLL_PREFIX_SIZE) {
            *pollId = path.substr(POLL_PREFIX_SIZE, slashLeftPos - POLL_PREFIX_SIZE);
            *voteId = path.substr(slashLeftPos + 1);
            return true;
        }
    }
    return false;
}

} // anonymous namespace

namespace NEPoll {

TPolls::TPolls() {

}

void TPolls::ScheduleRequest(fastcgi::Request *request, fastcgi::HandlerContext *context) {
    auto& path = request->getScriptName();
    auto& method = request->getRequestMethod();
    request->setContentType("application/json");
    std::string pollId;
    std::string voteId;
    if (IsListPolls(path, method)) {
        ListPolls(request, context);
    } else if (IsPollCreate(path, method)) {
        PollCreate(request, context);
    } else if (IsPollInfo(path, method, &pollId)) {
        PollInfo(request, context, pollId);
    } else if (IsPollVote(path, method, &pollId, &voteId)) {
        PollVote(request, context, pollId, voteId);
    } else {
        request->setStatus(404);
    }
}

void TPolls::ListPolls(fastcgi::Request *request, fastcgi::HandlerContext *context) {
    rapidjson::StringBuffer sb;
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb);
    writer.StartObject();
    writer.String("polls");
    writer.StartArray();
    for (size_t i = 0; i < 5; ++i) {
        writer.StartObject();
        writer.String("id");
        writer.String(std::to_string(i).c_str());
        writer.String("description");
        writer.String("Poll description");
        writer.String("created-at");
        writer.String("YYYY-MM-DD HH:MM:SS");
        writer.EndObject();
    }
    writer.EndArray();
    writer.EndObject();
    request->write(sb.GetString(), sb.GetSize());
}

void TPolls::PollCreate(fastcgi::Request *request, fastcgi::HandlerContext *context) {
    fastcgi::RequestStream stream(request);
    stream << "[\"Poll create\"]";
}

void TPolls::PollInfo(fastcgi::Request *request, fastcgi::HandlerContext *context,
                      const std::string& pollId)
{
    rapidjson::StringBuffer sb;
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb);
    writer.StartObject();
    writer.String("description");
    writer.String("What is the answer to life the universe and everything?");
    writer.String("created-at");
    writer.String("YYYY-MM-DD HH:MM:SS");
    writer.String("id");
    writer.String(pollId.c_str(), pollId.size());
    writer.String("options");
    writer.StartArray();
    for (size_t i = 0; i < 5; ++i) {
        writer.StartObject();
        writer.String("text");
        writer.String(std::to_string(i + 1).c_str());
        writer.String("votes");
        writer.Int64(1 + 5 * i);
        writer.EndObject();
    }
    writer.EndArray();
    writer.EndObject();
    request->write(sb.GetString(), sb.GetSize());
}

void TPolls::PollVote(fastcgi::Request *request, fastcgi::HandlerContext *context,
                      const std::string& pollId, const std::string& voteId)
{
    fastcgi::RequestStream stream(request);
    stream << "[\"Poll vote " << pollId << " for " << voteId << "\"]";
}

} // namespace NEPoll
<commit_msg>Implemented all methods in more realistick way.<commit_after>#include "polls.h"

#include <fastcgi2/stream.h>
#include <rapidjson/document.h>
#include <rapidjson/prettywriter.h>

#include <string>
#include <iostream>

namespace {

const size_t POLL_PREFIX_SIZE = sizeof("/polls/") - 1;

bool IsListPolls(const std::string& path, const std::string& method) {
    return path == "/polls" && method == "GET";
}

bool IsPollCreate(const std::string& path, const std::string& method) {
    return path == "/polls" && method == "POST";
}

bool IsPollInfo(const std::string& path, const std::string& method, std::string* pollId) {
    if (method == "GET" &&
        path.find("/polls/") == 0 && path.find('/', POLL_PREFIX_SIZE) == std::string::npos)
    {
        *pollId = path.substr(POLL_PREFIX_SIZE);
        return true;
    }
    return false;
}

bool IsPollVote(const std::string& path, const std::string& method,
                std::string* pollId, std::string* voteId)
{
    if (method == "POST" && path.find("/polls/") == 0) {
        auto slashLeftPos = path.find('/', POLL_PREFIX_SIZE);
        auto slashRightPos = path.rfind('/');
        if (slashRightPos == slashLeftPos && slashLeftPos > POLL_PREFIX_SIZE) {
            *pollId = path.substr(POLL_PREFIX_SIZE, slashLeftPos - POLL_PREFIX_SIZE);
            *voteId = path.substr(slashLeftPos + 1);
            return true;
        }
    }
    return false;
}

} // anonymous namespace

namespace NEPoll {

TPolls::TPolls() {

}

void TPolls::ScheduleRequest(fastcgi::Request *request, fastcgi::HandlerContext *context) {
    auto& path = request->getScriptName();
    auto& method = request->getRequestMethod();
    request->setContentType("application/json");
    std::string pollId;
    std::string voteId;
    if (IsListPolls(path, method)) {
        ListPolls(request, context);
    } else if (IsPollCreate(path, method)) {
        PollCreate(request, context);
    } else if (IsPollInfo(path, method, &pollId)) {
        PollInfo(request, context, pollId);
    } else if (IsPollVote(path, method, &pollId, &voteId)) {
        PollVote(request, context, pollId, voteId);
    } else {
        request->setStatus(404);
    }
}

void TPolls::ListPolls(fastcgi::Request *request, fastcgi::HandlerContext *context) {
    rapidjson::StringBuffer sb;
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb);
    writer.StartObject();
    writer.String("polls");
    writer.StartArray();
    for (size_t i = 0; i < 5; ++i) {
        writer.StartObject();
        writer.String("id");
        writer.String(std::to_string(i).c_str());
        writer.String("description");
        writer.String("Poll description");
        writer.String("created-at");
        writer.String("YYYY-MM-DD HH:MM:SS");
        writer.EndObject();
    }
    writer.EndArray();
    writer.EndObject();
    request->write(sb.GetString(), sb.GetSize());
}

void TPolls::PollCreate(fastcgi::Request *request, fastcgi::HandlerContext *context) {
    request->setStatus(201);
    request->setHeader("Location", "/polls/GUID");
}

void TPolls::PollInfo(fastcgi::Request *request, fastcgi::HandlerContext *context,
                      const std::string& pollId)
{
    rapidjson::StringBuffer sb;
    rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb);
    writer.StartObject();
    writer.String("description");
    writer.String("What is the answer to life the universe and everything?");
    writer.String("created-at");
    writer.String("YYYY-MM-DD HH:MM:SS");
    writer.String("id");
    writer.String(pollId.c_str(), pollId.size());
    writer.String("options");
    writer.StartArray();
    for (size_t i = 0; i < 5; ++i) {
        writer.StartObject();
        writer.String("text");
        writer.String(std::to_string(i + 1).c_str());
        writer.String("votes");
        writer.Int64(1 + 5 * i);
        writer.EndObject();
    }
    writer.EndArray();
    writer.EndObject();
    request->write(sb.GetString(), sb.GetSize());
}

void TPolls::PollVote(fastcgi::Request *request, fastcgi::HandlerContext *context,
                      const std::string& pollId, const std::string& voteId)
{
    long voteNum = -1;
    try {
        voteNum = std::stoi(voteId);
    } catch (...) { }

    if (voteNum < 0 || std::to_string(voteNum) != voteId) {
        request->setStatus(404);
        return;
    }
    fastcgi::RequestStream stream(request);
    stream << "[\"Poll vote " << pollId << " for " << voteId << " interpreted as " << voteNum  << "\"]";
}

} // namespace NEPoll
<|endoftext|>


<commit_before>
#include "ObjectStore.h"
#include "Configuration.h"

ObjectStore::ObjectStore()
{
  memset(this->functions, '\0', 10);
  this->first = NULL;
  this->last = NULL;
  this->basicObjectCount = 0;
}

void ObjectStore::addObject(BasicObject* bo)
{
  ObjectStoreNode* node = new ObjectStoreNode();
  node->prev = this->last;
  node->next = NULL;
  node->object = bo;
  if (this->first == NULL) {
    this->first = node;
  } else {
    this->last->next = node;
  }
  this->last = node;
  this->basicObjectCount++;
}

void ObjectStore::updateObjects()
{
  for (ObjectStoreNode* node = this->first; node != NULL; node = node->next)
  {
    node->object->update();
  }
}

void ObjectStore::handleOrder(IPOCS::Message* msg)
{
  for (ObjectStoreNode* node = this->first; node != NULL; node = node->next)
  {
    if (node->object->hasName(msg->RXID_OBJECT))
    {
      for (IPOCS::Message::PacketNode* pktNode = msg->firstPacket; pktNode != NULL; pktNode = pktNode->next)
      {
        node->object->handleOrder(pktNode->packet);
      }
    }
  }
}

void ObjectStore::loadSaved()
{
  byte sd[200];
  byte sdLength = Configuration::getSD(sd, 200);
  byte currPos = 0;
  int objNum = 0;
  while (sdLength > currPos)
  {
    byte sdObjectLength = sd[currPos];
    byte sdObjectType = sd[currPos + 1];
    if (sdObjectType < 10 && this->functions[sdObjectType] != NULL) {
      BasicObject* bo = this->functions[sdObjectType]();
      bo->init(String("Points " + String(objNum + 1)), sd + (currPos + 2), sdObjectLength - 1);
      ObjectStore::getInstance().addObject(bo);
    }
    currPos += sd[currPos] + 1;
    objNum++;
  }
}

void ObjectStore::registerType(int typeId, initObjectFunction fun)
{
  this->functions[typeId] = fun;
}

<commit_msg>Load site data fixed<commit_after>
#include "ObjectStore.h"
#include "Configuration.h"

ObjectStore::ObjectStore()
{
  memset(this->functions, '\0', 10);
  this->first = NULL;
  this->last = NULL;
  this->basicObjectCount = 0;
}

void ObjectStore::addObject(BasicObject* bo)
{
  ObjectStoreNode* node = new ObjectStoreNode();
  node->prev = this->last;
  node->next = NULL;
  node->object = bo;
  if (this->first == NULL) {
    this->first = node;
  } else {
    this->last->next = node;
  }
  this->last = node;
  this->basicObjectCount++;
}

void ObjectStore::updateObjects()
{
  for (ObjectStoreNode* node = this->first; node != NULL; node = node->next)
  {
    node->object->update();
  }
}

void ObjectStore::handleOrder(IPOCS::Message* msg)
{
  for (ObjectStoreNode* node = this->first; node != NULL; node = node->next)
  {
    if (node->object->hasName(msg->RXID_OBJECT))
    {
      for (IPOCS::Message::PacketNode* pktNode = msg->firstPacket; pktNode != NULL; pktNode = pktNode->next)
      {
        node->object->handleOrder(pktNode->packet);
      }
    }
  }
}

void ObjectStore::loadSaved()
{
  byte sd[200];
  byte sdLength = Configuration::getSD(sd, 200);
  byte currPos = 0;
  int objNum = 0;
  while (sdLength > currPos)
  {
    byte sdObjectType = sd[currPos];
    String objectName;
    for (uint8_t* firstChar = sd + 1; *firstChar != 0x00; firstChar++)
    {
      objectName += String((char)(*firstChar));
    }
    // 1 byte for object type + object length + object name + null byte
    uint8_t msgParsed = 1 + 1 + objectName.length() + 1;

    byte sdObjectLength = sd[msgParsed - 1];
    if (sdObjectType < 10 && this->functions[sdObjectType] != NULL) {

      BasicObject* bo = this->functions[sdObjectType]();

      bo->init(objectName, sd + msgParsed, sdObjectLength - 1);
      ObjectStore::getInstance().addObject(bo);
    }
    currPos += sd[currPos] + 1;
    objNum++;
  }
}

void ObjectStore::registerType(int typeId, initObjectFunction fun)
{
  this->functions[typeId] = fun;
}

<|endoftext|>