<commit_before>/******************************************************************************
 *                       ____    _    _____                                   *
 *                      / ___|  / \  |  ___|    C++                           *
 *                     | |     / _ \ | |_       Actor                         *
 *                     | |___ / ___ \|  _|      Framework                     *
 *                      \____/_/   \_|_|                                      *
 *                                                                            *
 * Copyright 2011-2018 Dominik Charousset                                     *
 *                                                                            *
 * Distributed under the terms and conditions of the BSD 3-Clause License or  *
 * (at your option) under the terms and conditions of the Boost Software      *
 * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE.       *
 *                                                                            *
 * If you did not receive a copy of the license files, see                    *
 * http://opensource.org/licenses/BSD-3-Clause and                            *
 * http://www.boost.org/LICENSE_1_0.txt.                                      *
 ******************************************************************************/

#include "caf/config.hpp"

#define CAF_SUITE streambuf
#include "caf/test/unit_test.hpp"

#include "caf/streambuf.hpp"

using namespace caf;

CAF_TEST(signed_arraybuf) {
  auto data = std::string{"The quick brown fox jumps over the lazy dog"};
  arraybuf<char> ab{data};
  // Let's read some.
  CAF_CHECK_EQUAL(static_cast<size_t>(ab.in_avail()), data.size());
  CAF_CHECK_EQUAL(ab.sgetc(), 'T');
  std::string buf;
  buf.resize(3);
  auto got = ab.sgetn(&buf[0], 3);
  CAF_CHECK_EQUAL(got, 3);
  CAF_CHECK_EQUAL(buf, "The");
  CAF_CHECK_EQUAL(ab.sgetc(), ' ');
  // Exhaust the stream.
  buf.resize(data.size());
  got = ab.sgetn(&buf[0] + 3, static_cast<std::streamsize>(data.size() - 3));
  CAF_CHECK_EQUAL(static_cast<size_t>(got), data.size() - 3);
  CAF_CHECK_EQUAL(data, buf);
  CAF_CHECK_EQUAL(ab.in_avail(), 0);
  // No more.
  auto c = ab.sgetc();
  CAF_CHECK_EQUAL(c, charbuf::traits_type::eof());
  // Reset the stream and write into it.
  ab.pubsetbuf(&data[0], static_cast<std::streamsize>(data.size()));
  CAF_CHECK_EQUAL(static_cast<size_t>(ab.in_avail()), data.size());
  auto put = ab.sputn("One", 3);
  CAF_CHECK_EQUAL(put, 3);
  CAF_CHECK(data.compare(0, 3, "One") == 0);
}

CAF_TEST(unsigned_arraybuf) {
  std::vector<uint8_t> data = {0x0a, 0x0b, 0x0c, 0x0d};
  arraybuf<uint8_t> ab{data};
  decltype(data) buf;
  std::copy(std::istreambuf_iterator<uint8_t>{&ab},
            std::istreambuf_iterator<uint8_t>{},
            std::back_inserter(buf));
  CAF_CHECK_EQUAL(data, buf);
  // Relative positioning.
  using pos = arraybuf<uint8_t>::pos_type;
  CAF_CHECK_EQUAL(ab.pubseekoff(2, std::ios::beg, std::ios::in), pos{2});
  CAF_CHECK_EQUAL(ab.sbumpc(), static_cast<int>(0x0c));
  CAF_CHECK_EQUAL(ab.sgetc(), 0x0d);
  CAF_CHECK_EQUAL(ab.pubseekoff(0, std::ios::cur, std::ios::in), pos{3});
  CAF_CHECK_EQUAL(ab.pubseekoff(-2, std::ios::cur, std::ios::in), pos{1});
  CAF_CHECK_EQUAL(ab.sgetc(), 0x0b);
  CAF_CHECK_EQUAL(ab.pubseekoff(-4, std::ios::end, std::ios::in), pos{0});
  CAF_CHECK_EQUAL(ab.sgetc(), 0x0a);
  // Absolute positioning.
  CAF_CHECK_EQUAL(ab.pubseekpos(1, std::ios::in), pos{1});
  CAF_CHECK_EQUAL(ab.sgetc(), 0x0b);
  CAF_CHECK_EQUAL(ab.pubseekpos(3, std::ios::in), pos{3});
  CAF_CHECK_EQUAL(ab.sbumpc(), 0x0d);
  CAF_CHECK_EQUAL(ab.in_avail(), 0);
}

CAF_TEST(containerbuf) {
  std::string data{
    "Habe nun, ach! Philosophie,\n"
    "Juristerei und Medizin,\n"
    "Und leider auch Theologie\n"
    "Durchaus studiert, mit heißem Bemühn.\n"
    "Da steh ich nun, ich armer Tor!\n"
    "Und bin so klug als wie zuvor"
  };
  // Write some data.
  std::vector<char> buf;
  vectorbuf vb{buf};
  auto put = vb.sputn(data.data(), static_cast<std::streamsize>(data.size()));
  CAF_CHECK_EQUAL(static_cast<size_t>(put), data.size());
  put = vb.sputn(";", 1);
  CAF_CHECK_EQUAL(put, 1);
  std::string target;
  std::copy(buf.begin(), buf.end(), std::back_inserter(target));
  CAF_CHECK_EQUAL(data + ';', target);
  // Check "overflow" on a new stream.
  buf.clear();
  vectorbuf vb2{buf};
  auto chr = vb2.sputc('x');
  CAF_CHECK_EQUAL(chr, 'x');
  // Let's read some data into a stream.
  buf.clear();
  containerbuf<std::string> scb{data};
  std::copy(std::istreambuf_iterator<char>{&scb},
            std::istreambuf_iterator<char>{},
            std::back_inserter(buf));
  CAF_CHECK_EQUAL(buf.size(), data.size());
  CAF_CHECK(std::equal(buf.begin(), buf.end(), data.begin() /*, data.end() */));
  // We're done, nothing to see here, please move along.
  CAF_CHECK_EQUAL(scb.sgetc(), containerbuf<std::string>::traits_type::eof());
  // Let's read again, but now in one big block.
  buf.clear();
  containerbuf<std::string> sib2{data};
  buf.resize(data.size());
  auto got = sib2.sgetn(&buf[0], static_cast<std::streamsize>(buf.size()));
  CAF_CHECK_EQUAL(static_cast<size_t>(got), data.size());
  CAF_CHECK_EQUAL(buf.size(), data.size());
  CAF_CHECK(std::equal(buf.begin(), buf.end(), data.begin() /*, data.end() */));
}
<commit_msg>Fix sign warnings<commit_after>/******************************************************************************
 *                       ____    _    _____                                   *
 *                      / ___|  / \  |  ___|    C++                           *
 *                     | |     / _ \ | |_       Actor                         *
 *                     | |___ / ___ \|  _|      Framework                     *
 *                      \____/_/   \_|_|                                      *
 *                                                                            *
 * Copyright 2011-2018 Dominik Charousset                                     *
 *                                                                            *
 * Distributed under the terms and conditions of the BSD 3-Clause License or  *
 * (at your option) under the terms and conditions of the Boost Software      *
 * License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE.       *
 *                                                                            *
 * If you did not receive a copy of the license files, see                    *
 * http://opensource.org/licenses/BSD-3-Clause and                            *
 * http://www.boost.org/LICENSE_1_0.txt.                                      *
 ******************************************************************************/

#include "caf/config.hpp"

#define CAF_SUITE streambuf
#include "caf/test/unit_test.hpp"

#include "caf/streambuf.hpp"

using namespace caf;

CAF_TEST(signed_arraybuf) {
  auto data = std::string{"The quick brown fox jumps over the lazy dog"};
  arraybuf<char> ab{data};
  // Let's read some.
  CAF_CHECK_EQUAL(static_cast<size_t>(ab.in_avail()), data.size());
  CAF_CHECK_EQUAL(ab.sgetc(), 'T');
  std::string buf;
  buf.resize(3);
  auto got = ab.sgetn(&buf[0], 3);
  CAF_CHECK_EQUAL(got, 3);
  CAF_CHECK_EQUAL(buf, "The");
  CAF_CHECK_EQUAL(ab.sgetc(), ' ');
  // Exhaust the stream.
  buf.resize(data.size());
  got = ab.sgetn(&buf[0] + 3, static_cast<std::streamsize>(data.size() - 3));
  CAF_CHECK_EQUAL(static_cast<size_t>(got), data.size() - 3);
  CAF_CHECK_EQUAL(data, buf);
  CAF_CHECK_EQUAL(ab.in_avail(), 0);
  // No more.
  auto c = ab.sgetc();
  CAF_CHECK_EQUAL(c, charbuf::traits_type::eof());
  // Reset the stream and write into it.
  ab.pubsetbuf(&data[0], static_cast<std::streamsize>(data.size()));
  CAF_CHECK_EQUAL(static_cast<size_t>(ab.in_avail()), data.size());
  auto put = ab.sputn("One", 3);
  CAF_CHECK_EQUAL(put, 3);
  CAF_CHECK(data.compare(0, 3, "One") == 0);
}

CAF_TEST(unsigned_arraybuf) {
  using buf_type = arraybuf<uint8_t>;
  std::vector<uint8_t> data = {0x0a, 0x0b, 0x0c, 0x0d};
  buf_type ab{data};
  decltype(data) buf;
  std::copy(std::istreambuf_iterator<uint8_t>{&ab},
            std::istreambuf_iterator<uint8_t>{},
            std::back_inserter(buf));
  CAF_CHECK_EQUAL(data, buf);
  // Relative positioning.
  using pos_type = buf_type::pos_type;
  using int_type = buf_type::int_type;
  CAF_CHECK_EQUAL(ab.pubseekoff(2, std::ios::beg, std::ios::in), pos_type{2});
  CAF_CHECK_EQUAL(ab.sbumpc(), int_type{0x0c});
  CAF_CHECK_EQUAL(ab.sgetc(), int_type{0x0d});
  CAF_CHECK_EQUAL(ab.pubseekoff(0, std::ios::cur, std::ios::in), pos_type{3});
  CAF_CHECK_EQUAL(ab.pubseekoff(-2, std::ios::cur, std::ios::in), pos_type{1});
  CAF_CHECK_EQUAL(ab.sgetc(), int_type{0x0b});
  CAF_CHECK_EQUAL(ab.pubseekoff(-4, std::ios::end, std::ios::in), pos_type{0});
  CAF_CHECK_EQUAL(ab.sgetc(), int_type{0x0a});
  // Absolute positioning.
  CAF_CHECK_EQUAL(ab.pubseekpos(1, std::ios::in), pos_type{1});
  CAF_CHECK_EQUAL(ab.sgetc(), int_type{0x0b});
  CAF_CHECK_EQUAL(ab.pubseekpos(3, std::ios::in), pos_type{3});
  CAF_CHECK_EQUAL(ab.sbumpc(), int_type{0x0d});
  CAF_CHECK_EQUAL(ab.in_avail(), std::streamsize{0});
}

CAF_TEST(containerbuf) {
  std::string data{
    "Habe nun, ach! Philosophie,\n"
    "Juristerei und Medizin,\n"
    "Und leider auch Theologie\n"
    "Durchaus studiert, mit heißem Bemühn.\n"
    "Da steh ich nun, ich armer Tor!\n"
    "Und bin so klug als wie zuvor"
  };
  // Write some data.
  std::vector<char> buf;
  vectorbuf vb{buf};
  auto put = vb.sputn(data.data(), static_cast<std::streamsize>(data.size()));
  CAF_CHECK_EQUAL(static_cast<size_t>(put), data.size());
  put = vb.sputn(";", 1);
  CAF_CHECK_EQUAL(put, 1);
  std::string target;
  std::copy(buf.begin(), buf.end(), std::back_inserter(target));
  CAF_CHECK_EQUAL(data + ';', target);
  // Check "overflow" on a new stream.
  buf.clear();
  vectorbuf vb2{buf};
  auto chr = vb2.sputc('x');
  CAF_CHECK_EQUAL(chr, 'x');
  // Let's read some data into a stream.
  buf.clear();
  containerbuf<std::string> scb{data};
  std::copy(std::istreambuf_iterator<char>{&scb},
            std::istreambuf_iterator<char>{},
            std::back_inserter(buf));
  CAF_CHECK_EQUAL(buf.size(), data.size());
  CAF_CHECK(std::equal(buf.begin(), buf.end(), data.begin() /*, data.end() */));
  // We're done, nothing to see here, please move along.
  CAF_CHECK_EQUAL(scb.sgetc(), containerbuf<std::string>::traits_type::eof());
  // Let's read again, but now in one big block.
  buf.clear();
  containerbuf<std::string> sib2{data};
  buf.resize(data.size());
  auto got = sib2.sgetn(&buf[0], static_cast<std::streamsize>(buf.size()));
  CAF_CHECK_EQUAL(static_cast<size_t>(got), data.size());
  CAF_CHECK_EQUAL(buf.size(), data.size());
  CAF_CHECK(std::equal(buf.begin(), buf.end(), data.begin() /*, data.end() */));
}
<|endoftext|>


<commit_before>// RUN: mkdir -p %T/read-file-config/
// RUN: cp %s %T/read-file-config/test.cpp
// RUN: echo 'Checks: "-*,modernize-use-nullptr"' > %T/read-file-config/.clang-tidy
// RUN: echo '[{"command": "cc -c -o test.o test.cpp", "directory": "%T/read-file-config", "file": "%T/read-file-config/test.cpp"}]' > %T/read-file-config/compile_commands.json
// RUN: clang-tidy %T/read-file-config/test.cpp | not grep "warning: .*\[clang-analyzer-deadcode.DeadStores\]$"
// RUN: clang-tidy -checks="-*,clang-analyzer-*" %T/read-file-config/test.cpp | grep "warning: .*\[clang-analyzer-deadcode.DeadStores\]$"

void f() {
  int x;
  x = 1;
  x = 2;
}
<commit_msg>Fix test from r330245 on Windows.<commit_after>// RUN: mkdir -p %T/read-file-config/
// RUN: cp %s %T/read-file-config/test.cpp
// RUN: echo 'Checks: "-*,modernize-use-nullptr"' > %T/read-file-config/.clang-tidy
// RUN: echo '[{"command": "cc -c -o test.o test.cpp", "directory": "%/T/read-file-config", "file": "%/T/read-file-config/test.cpp"}]' > %T/read-file-config/compile_commands.json
// RUN: clang-tidy %T/read-file-config/test.cpp | not grep "warning: .*\[clang-analyzer-deadcode.DeadStores\]$"
// RUN: clang-tidy -checks="-*,clang-analyzer-*" %T/read-file-config/test.cpp | grep "warning: .*\[clang-analyzer-deadcode.DeadStores\]$"

void f() {
  int x;
  x = 1;
  x = 2;
}
<|endoftext|>


<commit_before>//
// pLSI (probabilistic latent semantic indexing)
//
// Copyright(C) 2009  Mizuki Fujisawa <mfujisa@gmail.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
//

#include <getopt.h>
#include <cmath>
#include <fstream>
#include <iostream>
#include <map>
#include <string>
#include "bayon.h"

/********************************************************************
 * Typedef
 *******************************************************************/
typedef enum {
  OPT_NUMBER = 'n',
  OPT_ITER   = 'i',
  OPT_BETA   = 'b',
} plsi_options;

typedef std::map<plsi_options, std::string> Option;
typedef bayon::HashMap<std::string, double>::type Feature;
typedef bayon::HashMap<bayon::DocumentId, std::string>::type DocId2Str;
typedef bayon::HashMap<bayon::VecKey, std::string>::type VecKey2Str;
typedef bayon::HashMap<std::string, bayon::VecKey>::type Str2VecKey;

/********************************************************************
 * constants
 *******************************************************************/
const size_t DEFAULT_NUM_ITER   = 50;
const double DEFAULT_BETA       = 0.75;
const unsigned int DEFAULT_SEED = 12345;

/********************************************************************
 * global variables
 *******************************************************************/
struct option longopts[] = {
  {"number", required_argument, NULL, OPT_NUMBER},
  {"iter",   required_argument, NULL, OPT_ITER  },
  {"beta",   required_argument, NULL, OPT_BETA  },
  {0, 0, 0, 0}
};

/********************************************************************
 * class
 *******************************************************************/
namespace bayon {

class PLSI {
 private:
  size_t num_cluster_;
  size_t num_doc_;
  size_t num_word_;
  double beta_;
  unsigned int seed_;
  std::vector<Document *> documents_;
  double **pdz_, **pdz_new_;
  double **pwz_, **pwz_new_;
  double *pz_,   *pz_new_;
  double ***scores_;

  void set_random_probabilities(size_t row, size_t col, double **array) {
    for (size_t i = 0; i < row; i++) {
      array[i] = new double[col];
      double sum = 0.0;
      for (size_t j = 0; j < col; j++) {
        array[i][j] = myrand(&seed_);
        sum += array[i][j];
      }
      for (size_t j = 0; j < col; j++) {
        array[i][j] /= sum;
      }
    }
  }

  void expect() {
    for (size_t id = 0; id < num_doc_; id++) {
      VecHashMap *hmap = documents_[id]->feature()->hash_map();
      for (VecHashMap::iterator it = hmap->begin(); it != hmap->end(); ++it) {
        double denominator = 0.0;
        for (size_t iz = 0; iz < num_cluster_; iz++) {
          denominator += pz_[iz]
                         * pow(pwz_[it->first][iz] * pdz_[id][iz], beta_);
        }
        for (size_t iz = 0; iz < num_cluster_; iz++) {
          double numerator = pz_[iz]
                             * pow(pwz_[it->first][iz] * pdz_[id][iz], beta_);
          scores_[id][it->first][iz] = denominator ?
            numerator / denominator : 0.0;
        }
      }
    }
  }

  void maximize() {
    double denominators[num_cluster_];
    double denom_sum = 0.0;

    for (size_t iz = 0; iz < num_cluster_; iz++) {
      denominators[iz] = 0.0;
      for (size_t id = 0; id < num_doc_; id++) {
        VecHashMap *hmap = documents_[id]->feature()->hash_map();
        for (VecHashMap::iterator it = hmap->begin(); it != hmap->end(); ++it) {
          double val = it->second * scores_[id][it->first][iz];
          denominators[iz] += val;
          pdz_new_[id][iz] += val;
          pwz_new_[it->first][iz] += val;
        }
      }
      denom_sum += denominators[iz];

      for (size_t id = 0; id < num_doc_; id++) {
        pdz_[id][iz] = pdz_new_[id][iz] / denominators[iz];
        pdz_new_[id][iz] = 0.0;
      }
      for (size_t iw = 0; iw < num_word_; iw++) {
        pwz_[iw][iz] = pwz_new_[iw][iz] / denominators[iz];
        pwz_new_[iw][iz] = 0.0;
      }
    }
    for (size_t iz = 0; iz < num_cluster_; iz++)
      pz_[iz] = denominators[iz] / denom_sum;
  }

 public:
  PLSI(size_t num_cluster, double beta, unsigned int seed)
    : num_cluster_(num_cluster), num_doc_(0), num_word_(0),
      beta_(beta), seed_(seed) { }

  ~PLSI() {
    for (size_t i = 0; i < num_doc_; i ++) {
      delete pdz_[i];
      delete pdz_new_[i];
    }
    for (size_t i = 0; i < num_word_; i ++) {
      delete pwz_[i];
      delete pwz_new_[i];
    }
    delete [] pdz_;
    delete [] pwz_;
    delete [] pz_;
    delete [] pdz_new_;
    delete [] pwz_new_;
    delete [] pz_new_;
  }

  void init_probabilities() {
    pdz_ = new double*[num_doc_];
    set_random_probabilities(num_doc_, num_cluster_, pdz_);
    pwz_ = new double*[num_word_];
    set_random_probabilities(num_word_, num_cluster_, pwz_);
    pz_ = new double[num_cluster_];
    for (size_t i = 0; i < num_cluster_; i++) pz_[i] = 1.0 / num_cluster_;

    pdz_new_ = new double*[num_doc_];
    for (size_t id = 0; id < num_doc_; id++) {
      pdz_new_[id] = new double[num_cluster_];
      for (size_t iz = 0; iz < num_cluster_; iz++) pdz_new_[id][iz] = 0.0;
    }
    pwz_new_ = new double*[num_word_];
    for (size_t iw = 0; iw < num_word_; iw++) {
      pwz_new_[iw] = new double[num_cluster_];
      for (size_t iz = 0; iz < num_cluster_; iz++) pwz_new_[iw][iz] = 0.0;
    }
    pz_new_ = new double[num_cluster_];
    for (size_t iz = 0; iz < num_cluster_; iz++) pz_new_[iz] = 0.0;

    scores_ = new double**[num_doc_];
    for (size_t i = 0; i < num_doc_; i++) {
      scores_[i] = new double*[num_word_];
      for (size_t j = 0; j < num_word_; j++) {
        scores_[i][j] = new double[num_cluster_];
      }
    }
  }

  void add_document(Document &doc) {
    Document *ptr = new Document(doc.id(), doc.feature());
    doc.set_features(NULL);
    documents_.push_back(ptr);
    num_doc_++;
    VecHashMap *hmap = ptr->feature()->hash_map();
    for (VecHashMap::iterator it = hmap->begin();
         it != hmap->end(); ++it) {
      if ((it->first+1) > static_cast<int>(num_word_)) num_word_ = it->first+1;
    }
  }

  void em(size_t num_iter) {
    for (size_t i = 0; i < num_iter; i++) {
      expect();
      maximize();
    }
  }

  void show_pdz() {
    for (size_t i = 0; i < num_doc_; i++) {
      for (size_t j = 0; j < num_cluster_; j++) {
        if (j != 0) std::cout << "\t";
        std::cout << pdz_[i][j];
      }
      std::cout << std::endl;
    }
  }

  void show_pwz() {
    for (size_t i = 0; i < num_word_; i++) {
      for (size_t j = 0; j < num_cluster_; j++) {
        if (j != 0) std::cout << "\t";
        std::cout << pwz_[i][j];
      }
      std::cout << std::endl;
    }
  }

  void show_pz() {
    for (size_t i = 0; i < num_cluster_; i++) {
      if (i != 0) std::cout << "\t";
      std::cout << pz_[i];
    }
    std::cout << std::endl;
  }

  double **pdz() { return pdz_; }
  double **pwz() { return pwz_; }
  double *pz()   { return pz_; }
  const std::vector<Document *> &documents() { return documents_; }
};

} // namespace bayon

/********************************************************************
 * function prototypes
 *******************************************************************/
int main(int argc, char **argv);
static void usage(std::string progname);
static int parse_options(int argc, char **argv, Option &option);
static size_t parse_tsv(std::string &tsv, Feature &feature);
static size_t read_documents(std::ifstream &ifs, bayon::PLSI &plsi,
                      bayon::VecKey &veckey, DocId2Str &docid2str,
                      VecKey2Str &veckey2str, Str2VecKey &str2veckey);

/* main function */
int main(int argc, char **argv) {
  std::string progname(argv[0]);
  Option option;
  int optind = parse_options(argc, argv, option);
  argc -= optind;
  argv += optind;
  if (argc != 1 || option.find(OPT_NUMBER) == option.end()) {
    usage(progname);
    return EXIT_FAILURE;
  }

  std::ifstream ifs_doc(argv[0]);
  if (!ifs_doc) {
    std::cerr << "[ERROR]File not found: " << argv[0] << std::endl;
    return EXIT_FAILURE;
  }

  DocId2Str docid2str;
  bayon::init_hash_map(bayon::DOC_EMPTY_KEY, docid2str);
  VecKey2Str veckey2str;
  bayon::init_hash_map(bayon::VECTOR_EMPTY_KEY, veckey2str);
  Str2VecKey str2veckey;
  bayon::init_hash_map("", str2veckey);
  bayon::VecKey veckey = 0;

  size_t num_cluster = static_cast<size_t>(atoi(option[OPT_NUMBER].c_str()));
  size_t num_iter = option.find(OPT_ITER) != option.end() ?
    static_cast<size_t>(atoi(option[OPT_ITER].c_str())) : DEFAULT_NUM_ITER;
  double beta = option.find(OPT_ITER) != option.end() ?
    atof(option[OPT_BETA].c_str()) : DEFAULT_BETA;
  bayon::PLSI plsi(num_cluster, beta, DEFAULT_SEED);;
  size_t num_doc = read_documents(ifs_doc, plsi, veckey,
                                  docid2str, veckey2str, str2veckey);
  plsi.init_probabilities();
  plsi.em(num_iter);

  double **pdz = plsi.pdz();
  for (size_t i = 0; i < num_doc; i++) {
    std::cout << docid2str[plsi.documents()[i]->id()];
    for (size_t j = 0; j < num_cluster; j++) {
      std::cout << "\t" << pdz[i][j];
    }
    std::cout << std::endl;
  }

  return EXIT_SUCCESS;
}

/* show usage */
static void usage(std::string progname) {
  std::cerr
    << progname << ": Clustering tool by probabilistic latent semantic indexing"
    << std::endl
    << "Usage:" << std::endl
    << " % " << progname << " -n num [-b beta | -i niter] file" << std::endl
    << "    -n, --number=num      number of clusters" << std::endl
    << "    -i, --iter=num        number of iteration" << std::endl
    << "    -b, --beta=double     parameter of tempered EM" << std::endl;
}

/* parse command line options */
static int parse_options(int argc, char **argv, Option &option) {
  int opt;
  extern char *optarg;
  extern int optind;
  while ((opt = getopt_long(argc, argv, "n:i:b:", longopts, NULL))
         != -1) {
    switch (opt) {
    case OPT_NUMBER:
      option[OPT_NUMBER] = optarg;
      break;
    case OPT_ITER:
      option[OPT_ITER] = optarg;
      break;
    case OPT_BETA:
      option[OPT_BETA] = optarg;
      break;
    default:
      break;
    }
  }
  return optind;
}

/* parse tsv format string */
static size_t parse_tsv(std::string &tsv, Feature &feature) {
  std::string key;
  int cnt = 0;
  size_t keycnt = 0;

  size_t p = tsv.find(bayon::DELIMITER);
  while (true) {
    std::string s = tsv.substr(0, p);
    if (cnt % 2 == 0) {
      key = s;
    } else {
      double point = 0.0;
      point = atof(s.c_str());
      if (!key.empty() && point != 0) {
        feature[key] = point;
        keycnt++;
      }
    }
    if (p == tsv.npos) break;
    cnt++;
    tsv = tsv.substr(p + bayon::DELIMITER.size());
    p = tsv.find(bayon::DELIMITER);
  }
  return keycnt;
}

/* read input file and add documents to PLSI object */
static size_t read_documents(std::ifstream &ifs, bayon::PLSI &plsi,
                             bayon::VecKey &veckey, DocId2Str &docid2str,
                             VecKey2Str &veckey2str, Str2VecKey &str2veckey) {
  bayon::DocumentId docid = 0;
  std::string line;
  while (std::getline(ifs, line)) {
    if (!line.empty()) {
      size_t p = line.find(bayon::DELIMITER);
      std::string doc_name = line.substr(0, p);
      line = line.substr(p + bayon::DELIMITER.size());

      bayon::Document doc(docid);
      docid2str[docid] = doc_name;
      docid++;
      Feature feature;
      bayon::init_hash_map("", feature);
      parse_tsv(line, feature);

      for (Feature::iterator it = feature.begin(); it != feature.end(); ++it) {
        if (str2veckey.find(it->first) == str2veckey.end()) {
          str2veckey[it->first] = veckey;
          veckey2str[veckey] = it->first;
          veckey++;
        }
        doc.add_feature(str2veckey[it->first], it->second);
      }
      plsi.add_document(doc);
    }
  }
  return docid;
}

<commit_msg>[trunk] speed up plsi<commit_after>//
// pLSI (probabilistic latent semantic indexing)
//
// Copyright(C) 2009  Mizuki Fujisawa <mfujisa@gmail.com>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; version 2 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
//

#include <getopt.h>
#include <cmath>
#include <fstream>
#include <iostream>
#include <map>
#include <string>
#include "bayon.h"

/********************************************************************
 * Typedef
 *******************************************************************/
typedef enum {
  OPT_NUMBER = 'n',
  OPT_ITER   = 'i',
  OPT_BETA   = 'b',
} plsi_options;

typedef std::map<plsi_options, std::string> Option;
typedef bayon::HashMap<std::string, double>::type Feature;
typedef bayon::HashMap<bayon::DocumentId, std::string>::type DocId2Str;
typedef bayon::HashMap<bayon::VecKey, std::string>::type VecKey2Str;
typedef bayon::HashMap<std::string, bayon::VecKey>::type Str2VecKey;

/********************************************************************
 * constants
 *******************************************************************/
const size_t DEFAULT_NUM_ITER   = 50;
const double DEFAULT_BETA       = 0.75;
const unsigned int DEFAULT_SEED = 12345;

/********************************************************************
 * global variables
 *******************************************************************/
struct option longopts[] = {
  {"number", required_argument, NULL, OPT_NUMBER},
  {"iter",   required_argument, NULL, OPT_ITER  },
  {"beta",   required_argument, NULL, OPT_BETA  },
  {0, 0, 0, 0}
};

/********************************************************************
 * class
 *******************************************************************/
namespace bayon {

class PLSI {
 private:
  size_t num_cluster_;
  size_t num_doc_;
  size_t num_word_;
  double beta_;
  double sum_weight_;
  unsigned int seed_;
  std::vector<Document *> documents_;
  double **pdz_, **pdz_new_;
  double **pwz_, **pwz_new_;
  double *pz_,   *pz_new_;

  void set_random_prob(size_t row, size_t col, double **array, double **array2) {
    for (size_t i = 0; i < row; i++) {
      array[i] = new double[col];
      array2[i] = new double[col];
      double sum = 0.0;
      for (size_t j = 0; j < col; j++) {
        array[i][j] = myrand(&seed_);
        array2[i][j] = 0.0;
        sum += array[i][j];
      }
      for (size_t j = 0; j < col; j++) {
        array[i][j] /= sum;
      }
    }
  }

  void em_loop() {
    for (size_t id = 0; id < num_doc_; id++) {
      VecHashMap *hmap = documents_[id]->feature()->hash_map();
      for (VecHashMap::iterator it = hmap->begin(); it != hmap->end(); ++it) {
        double denom = 0.0;
        for (size_t iz = 0; iz < num_cluster_; iz++) {
          denom += pz_[iz] * pow(pwz_[it->first][iz] * pdz_[id][iz], beta_);
        }
        if (!denom) continue;
        for (size_t iz = 0; iz < num_cluster_; iz++) {
          double numer = pz_[iz] * pow(pwz_[it->first][iz] * pdz_[id][iz], beta_);
          double score = it->second * numer / denom;
          pdz_new_[id][iz]        += score;
          pwz_new_[it->first][iz] += score;
          pz_new_[iz]             += score;
        }
      }
    }

    for (size_t iz = 0; iz < num_cluster_; iz++) {
      for (size_t id = 0; id < num_doc_; id++) {
        pdz_[id][iz] = pdz_new_[id][iz] / pz_new_[iz];
        pdz_new_[id][iz] = 0.0;
      }
      for (size_t iw = 0; iw < num_word_; iw++) {
        pwz_[iw][iz] = pwz_new_[iw][iz] / pz_new_[iz];
        pwz_new_[iw][iz] = 0.0;
      }
    }
    for (size_t iz = 0; iz < num_cluster_; iz++) {
      pz_[iz] = pz_new_[iz] / sum_weight_;
      pz_new_[iz] = 0.0;
    }
  }

 public:
  PLSI(size_t num_cluster, double beta, unsigned int seed)
    : num_cluster_(num_cluster), num_doc_(0), num_word_(0),
      beta_(beta), seed_(seed) { }

  ~PLSI() {
    for (size_t i = 0; i < num_doc_; i ++) {
      delete pdz_[i];
      delete pdz_new_[i];
    }
    for (size_t i = 0; i < num_word_; i ++) {
      delete pwz_[i];
      delete pwz_new_[i];
    }
    delete [] pdz_;
    delete [] pwz_;
    delete [] pz_;
    delete [] pdz_new_;
    delete [] pwz_new_;
    delete [] pz_new_;
  }

  void init_probabilities() {
    pdz_ = new double*[num_doc_];
    pdz_new_ = new double*[num_doc_];
    set_random_prob(num_doc_, num_cluster_, pdz_, pdz_new_);

    pwz_ = new double*[num_word_];
    pwz_new_ = new double*[num_word_];
    set_random_prob(num_word_, num_cluster_, pwz_, pwz_new_);

    pz_ = new double[num_cluster_];
    pz_new_ = new double[num_cluster_];
    for (size_t iz = 0; iz < num_cluster_; iz++) {
      pz_[iz] = 1.0 / num_cluster_;
      pz_new_[iz] = 0.0;
    }
  }

  void add_document(Document &doc) {
    Document *ptr = new Document(doc.id(), doc.feature());
    doc.set_features(NULL);
    documents_.push_back(ptr);
    num_doc_++;
    VecHashMap *hmap = ptr->feature()->hash_map();
    for (VecHashMap::iterator it = hmap->begin();
         it != hmap->end(); ++it) {
      if ((it->first+1) > static_cast<int>(num_word_)) num_word_ = it->first+1;
      sum_weight_ += it->second;
    }
  }

  void em(size_t num_iter) {
    for (size_t i = 0; i < num_iter; i++) em_loop();
  }

  void show_pdz() {
    for (size_t i = 0; i < num_doc_; i++) {
      for (size_t j = 0; j < num_cluster_; j++) {
        if (j != 0) std::cout << "\t";
        std::cout << pdz_[i][j];
      }
      std::cout << std::endl;
    }
  }

  void show_pwz() {
    for (size_t i = 0; i < num_word_; i++) {
      for (size_t j = 0; j < num_cluster_; j++) {
        if (j != 0) std::cout << "\t";
        std::cout << pwz_[i][j];
      }
      std::cout << std::endl;
    }
  }

  void show_pz() {
    for (size_t i = 0; i < num_cluster_; i++) {
      if (i != 0) std::cout << "\t";
      std::cout << pz_[i];
    }
    std::cout << std::endl;
  }

  double **pdz() { return pdz_; }
  double **pwz() { return pwz_; }
  double *pz()   { return pz_; }
  const std::vector<Document *> &documents() { return documents_; }
};

} // namespace bayon

/********************************************************************
 * function prototypes
 *******************************************************************/
int main(int argc, char **argv);
static void usage(std::string progname);
static int parse_options(int argc, char **argv, Option &option);
static size_t parse_tsv(std::string &tsv, Feature &feature);
static size_t read_documents(std::ifstream &ifs, bayon::PLSI &plsi,
                      bayon::VecKey &veckey, DocId2Str &docid2str,
                      VecKey2Str &veckey2str, Str2VecKey &str2veckey);

/* main function */
int main(int argc, char **argv) {
  std::string progname(argv[0]);
  Option option;
  int optind = parse_options(argc, argv, option);
  argc -= optind;
  argv += optind;
  if (argc != 1 || option.find(OPT_NUMBER) == option.end()) {
    usage(progname);
    return EXIT_FAILURE;
  }

  std::ifstream ifs_doc(argv[0]);
  if (!ifs_doc) {
    std::cerr << "[ERROR]File not found: " << argv[0] << std::endl;
    return EXIT_FAILURE;
  }

  DocId2Str docid2str;
  bayon::init_hash_map(bayon::DOC_EMPTY_KEY, docid2str);
  VecKey2Str veckey2str;
  bayon::init_hash_map(bayon::VECTOR_EMPTY_KEY, veckey2str);
  Str2VecKey str2veckey;
  bayon::init_hash_map("", str2veckey);
  bayon::VecKey veckey = 0;

  size_t num_cluster = static_cast<size_t>(atoi(option[OPT_NUMBER].c_str()));
  size_t num_iter = option.find(OPT_ITER) != option.end() ?
    static_cast<size_t>(atoi(option[OPT_ITER].c_str())) : DEFAULT_NUM_ITER;
  double beta = option.find(OPT_BETA) != option.end() ?
    atof(option[OPT_BETA].c_str()) : DEFAULT_BETA;
  bayon::PLSI plsi(num_cluster, beta, DEFAULT_SEED);;
  size_t num_doc = read_documents(ifs_doc, plsi, veckey,
                                  docid2str, veckey2str, str2veckey);
  plsi.init_probabilities();
  plsi.em(num_iter);

  double **pdz = plsi.pdz();
  for (size_t i = 0; i < num_doc; i++) {
    std::cout << docid2str[plsi.documents()[i]->id()];
    for (size_t j = 0; j < num_cluster; j++) {
      std::cout << "\t" << pdz[i][j];
    }
    std::cout << std::endl;
  }

  return EXIT_SUCCESS;
}

/* show usage */
static void usage(std::string progname) {
  std::cerr
    << progname << ": Clustering tool by probabilistic latent semantic indexing"
    << std::endl
    << "Usage:" << std::endl
    << " % " << progname << " -n num [-b beta | -i niter] file" << std::endl
    << "    -n, --number=num      number of clusters" << std::endl
    << "    -i, --iter=num        number of iteration" << std::endl
    << "    -b, --beta=double     parameter of tempered EM" << std::endl;
}

/* parse command line options */
static int parse_options(int argc, char **argv, Option &option) {
  int opt;
  extern char *optarg;
  extern int optind;
  while ((opt = getopt_long(argc, argv, "n:i:b:", longopts, NULL))
         != -1) {
    switch (opt) {
    case OPT_NUMBER:
      option[OPT_NUMBER] = optarg;
      break;
    case OPT_ITER:
      option[OPT_ITER] = optarg;
      break;
    case OPT_BETA:
      option[OPT_BETA] = optarg;
      break;
    default:
      break;
    }
  }
  return optind;
}

/* parse tsv format string */
static size_t parse_tsv(std::string &tsv, Feature &feature) {
  std::string key;
  int cnt = 0;
  size_t keycnt = 0;

  size_t p = tsv.find(bayon::DELIMITER);
  while (true) {
    std::string s = tsv.substr(0, p);
    if (cnt % 2 == 0) {
      key = s;
    } else {
      double point = 0.0;
      point = atof(s.c_str());
      if (!key.empty() && point != 0) {
        feature[key] = point;
        keycnt++;
      }
    }
    if (p == tsv.npos) break;
    cnt++;
    tsv = tsv.substr(p + bayon::DELIMITER.size());
    p = tsv.find(bayon::DELIMITER);
  }
  return keycnt;
}

/* read input file and add documents to PLSI object */
static size_t read_documents(std::ifstream &ifs, bayon::PLSI &plsi,
                             bayon::VecKey &veckey, DocId2Str &docid2str,
                             VecKey2Str &veckey2str, Str2VecKey &str2veckey) {
  bayon::DocumentId docid = 0;
  std::string line;
  while (std::getline(ifs, line)) {
    if (!line.empty()) {
      size_t p = line.find(bayon::DELIMITER);
      std::string doc_name = line.substr(0, p);
      line = line.substr(p + bayon::DELIMITER.size());

      bayon::Document doc(docid);
      docid2str[docid] = doc_name;
      docid++;
      Feature feature;
      bayon::init_hash_map("", feature);
      parse_tsv(line, feature);

      for (Feature::iterator it = feature.begin(); it != feature.end(); ++it) {
        if (str2veckey.find(it->first) == str2veckey.end()) {
          str2veckey[it->first] = veckey;
          veckey2str[veckey] = it->first;
          veckey++;
        }
        doc.add_feature(str2veckey[it->first], it->second);
      }
      plsi.add_document(doc);
    }
  }
  return docid;
}

<|endoftext|>


<commit_before>#include <string>

#include <gtest/gtest.h>

#include "fly/config/config.h"
#include "fly/config/config_manager.h"
#include "fly/path/path.h"
#include "fly/path/path_config.h"
#include "fly/task/task_manager.h"
#include "fly/types/string.h"

#include "test/util/path_util.h"
#include "test/util/waitable_task_runner.h"

namespace
{
    std::chrono::seconds s_waitTime(5);

    /**
     * Subclass of the path config to decrease the poll interval for faster
     * testing.
     */
    class TestPathConfig : public fly::PathConfig
    {
    public:
        TestPathConfig() : fly::PathConfig()
        {
            m_defaultPollInterval = I64(10);
        }
    };
}

//==============================================================================
class ConfigManagerTest : public ::testing::Test
{
public:
    ConfigManagerTest() :
        m_path(fly::PathUtil::GenerateTempDirectory()),
        m_file(fly::String::GenerateRandomString(10) + ".txt"),
        m_fullPath(fly::Path::Join(m_path, m_file)),

        m_spTaskManager(std::make_shared<fly::TaskManager>(1)),

        m_spTaskRunner(
            m_spTaskManager->CreateTaskRunner<fly::WaitableSequencedTaskRunner>()
        ),

        m_spConfigManager(std::make_shared<fly::ConfigManager>(
            m_spTaskRunner,
            fly::ConfigManager::ConfigFileType::Ini,
            m_path,
            m_file
        )),

        m_spPathConfig(m_spConfigManager->CreateConfig<TestPathConfig>())
    {
    }

    /**
     * Create the file directory and start the task and config managers.
     */
    void SetUp() override
    {
        ASSERT_TRUE(fly::Path::MakePath(m_path));
        ASSERT_TRUE(m_spTaskManager->Start());
        ASSERT_TRUE(m_spConfigManager->Start());

        m_initialSize = m_spConfigManager->GetSize();
    }

    /**
     * Delete the created directory and stop the task manager.
     */
    void TearDown() override
    {
        ASSERT_TRUE(m_spTaskManager->Stop());
        ASSERT_TRUE(fly::Path::RemovePath(m_path));
    }

protected:
    std::string m_path;
    std::string m_file;
    std::string m_fullPath;

    fly::TaskManagerPtr m_spTaskManager;
    fly::WaitableSequencedTaskRunnerPtr m_spTaskRunner;

    fly::ConfigManagerPtr m_spConfigManager;

    fly::PathConfigPtr m_spPathConfig;

    size_t m_initialSize;
};

//==============================================================================
class BadConfig : public fly::Config
{
    // Badly written config class which does not override the GetName() method.
    // It will have the same name as the base Config class.
};

//==============================================================================
TEST_F(ConfigManagerTest, AllFileTypesTest)
{
    {
        m_spConfigManager = std::make_shared<fly::ConfigManager>(
            m_spTaskRunner,
            fly::ConfigManager::ConfigFileType::Ini,
            m_path,
            m_file
        );
        m_spPathConfig = m_spConfigManager->CreateConfig<TestPathConfig>();

        EXPECT_TRUE(m_spConfigManager->Start());
    }
    {
        m_spConfigManager = std::make_shared<fly::ConfigManager>(
            m_spTaskRunner,
            fly::ConfigManager::ConfigFileType::Json,
            m_path,
            m_file
        );
        m_spPathConfig = m_spConfigManager->CreateConfig<TestPathConfig>();

        EXPECT_TRUE(m_spConfigManager->Start());
    }
}

//==============================================================================
TEST_F(ConfigManagerTest, BadFileTypeTest)
{
    m_spConfigManager = std::make_shared<fly::ConfigManager>(
        m_spTaskRunner,
        static_cast<fly::ConfigManager::ConfigFileType>(-1),
        m_path,
        m_file
    );
    m_spPathConfig = m_spConfigManager->CreateConfig<TestPathConfig>();

    EXPECT_FALSE(m_spConfigManager->Start());
}

//==============================================================================
TEST_F(ConfigManagerTest, CreateConfigTest)
{
    auto spConfig = m_spConfigManager->CreateConfig<fly::Config>();
    EXPECT_EQ(m_spConfigManager->GetSize(), m_initialSize + 1);
}

//==============================================================================
TEST_F(ConfigManagerTest, DuplicateConfigTest)
{
    auto spConfig1 = m_spConfigManager->CreateConfig<fly::Config>();
    EXPECT_EQ(m_spConfigManager->GetSize(), m_initialSize + 1);

    auto spConfig2 = m_spConfigManager->CreateConfig<fly::Config>();
    EXPECT_EQ(m_spConfigManager->GetSize(), m_initialSize + 1);
}

//==============================================================================
TEST_F(ConfigManagerTest, DeletedConfigTest)
{
    EXPECT_EQ(m_spConfigManager->GetSize(), m_initialSize);

    {
        auto spConfig = m_spConfigManager->CreateConfig<fly::Config>();
        EXPECT_EQ(m_spConfigManager->GetSize(), m_initialSize + 1);
    }

    EXPECT_EQ(m_spConfigManager->GetSize(), m_initialSize);

    {
        auto spConfig = m_spConfigManager->CreateConfig<fly::Config>();
        EXPECT_EQ(m_spConfigManager->GetSize(), m_initialSize + 1);
    }

    auto spConfig = m_spConfigManager->CreateConfig<fly::Config>();
    EXPECT_FALSE(spConfig.get() == NULL);
    spConfig.reset();

    spConfig = m_spConfigManager->CreateConfig<fly::Config>();
    EXPECT_FALSE(spConfig.get() == NULL);
}

//==============================================================================
TEST_F(ConfigManagerTest, DeletedConfigDetectedByPollerTest)
{
    EXPECT_EQ(m_spConfigManager->GetSize(), m_initialSize);

    const std::string contents(
        "[" + fly::Config::GetName() + "]\n"
        "name=John Doe\n"
        "address=USA"
    );

    ASSERT_TRUE(fly::PathUtil::WriteFile(m_fullPath, contents));
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();

    {
        auto spConfig = m_spConfigManager->CreateConfig<fly::Config>();
        EXPECT_EQ(m_spConfigManager->GetSize(), m_initialSize + 1);

        EXPECT_EQ(spConfig->GetValue<std::string>("name", ""), "John Doe");
        EXPECT_EQ(spConfig->GetValue<std::string>("address", ""), "USA");
    }

    ASSERT_TRUE(fly::PathUtil::WriteFile(m_fullPath, contents + "\n"));
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();

    EXPECT_EQ(m_spConfigManager->GetSize(), m_initialSize);
}

//==============================================================================
TEST_F(ConfigManagerTest, BadConfigTypeTest)
{
    EXPECT_EQ(m_spConfigManager->GetSize(), m_initialSize);

    auto spConfig = m_spConfigManager->CreateConfig<fly::Config>();
    EXPECT_EQ(m_spConfigManager->GetSize(), m_initialSize + 1);

    auto spConfig2 = m_spConfigManager->CreateConfig<BadConfig>();
    EXPECT_EQ(m_spConfigManager->GetSize(), m_initialSize + 1);
    EXPECT_FALSE(spConfig2);
}

//==============================================================================
TEST_F(ConfigManagerTest, InitialFileFirstTest)
{
    const std::string contents(
        "[" + fly::Config::GetName() + "]\n"
        "name=John Doe\n"
        "address=USA"
    );

    ASSERT_TRUE(fly::PathUtil::WriteFile(m_fullPath, contents));
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();

    auto spConfig = m_spConfigManager->CreateConfig<fly::Config>();

    EXPECT_EQ(spConfig->GetValue<std::string>("name", ""), "John Doe");
    EXPECT_EQ(spConfig->GetValue<std::string>("address", ""), "USA");
}

//==============================================================================
TEST_F(ConfigManagerTest, InitialFileSecondTest)
{
    auto spConfig = m_spConfigManager->CreateConfig<fly::Config>();

    const std::string contents(
        "[" + fly::Config::GetName() + "]\n"
        "name=John Doe\n"
        "address=USA"
    );

    ASSERT_TRUE(fly::PathUtil::WriteFile(m_fullPath, contents));
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();

    EXPECT_EQ(spConfig->GetValue<std::string>("name", ""), "John Doe");
    EXPECT_EQ(spConfig->GetValue<std::string>("address", ""), "USA");
}

//==============================================================================
TEST_F(ConfigManagerTest, FileChangeTest)
{
    auto spConfig = m_spConfigManager->CreateConfig<fly::Config>();

    const std::string contents1(
        "[" + fly::Config::GetName() + "]\n"
        "name=John Doe\n"
        "address=USA"
    );

    ASSERT_TRUE(fly::PathUtil::WriteFile(m_fullPath, contents1));
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();

    EXPECT_EQ(spConfig->GetValue<std::string>("name", ""), "John Doe");
    EXPECT_EQ(spConfig->GetValue<std::string>("address", ""), "USA");
    EXPECT_EQ(spConfig->GetValue<int>("age", -1), -1);

    const std::string contents2(
        "[" + fly::Config::GetName() + "]\n"
        "name=Jane Doe\n"
        "age=27"
    );

    ASSERT_TRUE(fly::PathUtil::WriteFile(m_fullPath, contents2));
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();

    EXPECT_EQ(spConfig->GetValue<std::string>("name", ""), "Jane Doe");
    EXPECT_EQ(spConfig->GetValue<std::string>("address", ""), "");
    EXPECT_EQ(spConfig->GetValue<int>("age", -1), 27);
}

//==============================================================================
TEST_F(ConfigManagerTest, DeleteFileTest)
{
    auto spConfig = m_spConfigManager->CreateConfig<fly::Config>();

    const std::string contents(
        "[" + fly::Config::GetName() + "]\n"
        "name=John Doe\n"
        "address=USA"
    );

    ASSERT_TRUE(fly::PathUtil::WriteFile(m_fullPath, contents));
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();

    EXPECT_EQ(spConfig->GetValue<std::string>("name", ""), "John Doe");
    EXPECT_EQ(spConfig->GetValue<std::string>("address", ""), "USA");

    std::remove(m_fullPath.c_str());
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();

    EXPECT_EQ(spConfig->GetValue<std::string>("name", ""), "");
    EXPECT_EQ(spConfig->GetValue<std::string>("address", ""), "");
}

//==============================================================================
TEST_F(ConfigManagerTest, BadUpdateTest)
{
    auto spConfig = m_spConfigManager->CreateConfig<fly::Config>();

    const std::string contents(
        "[" + fly::Config::GetName() + "]\n"
        "name"
    );

    ASSERT_TRUE(fly::PathUtil::WriteFile(m_fullPath, contents));
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();

    EXPECT_EQ(spConfig->GetValue<std::string>("name", ""), "");
    EXPECT_EQ(spConfig->GetValue<std::string>("address", ""), "");
}

//==============================================================================
TEST_F(ConfigManagerTest, BadObjectTest)
{
    m_spConfigManager = std::make_shared<fly::ConfigManager>(
        m_spTaskRunner,
        fly::ConfigManager::ConfigFileType::Json,
        m_path,
        m_file
    );
    m_spPathConfig = m_spConfigManager->CreateConfig<TestPathConfig>();

    EXPECT_TRUE(m_spConfigManager->Start());

    auto spConfig = m_spConfigManager->CreateConfig<fly::Config>();

    const std::string contents("[1, 2, 3]");

    ASSERT_TRUE(fly::PathUtil::WriteFile(m_fullPath, contents));
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();

    EXPECT_EQ(spConfig->GetValue<std::string>("name", ""), "");
    EXPECT_EQ(spConfig->GetValue<std::string>("address", ""), "");
}
<commit_msg>Unused var<commit_after>#include <string>

#include <gtest/gtest.h>

#include "fly/config/config.h"
#include "fly/config/config_manager.h"
#include "fly/path/path.h"
#include "fly/path/path_config.h"
#include "fly/task/task_manager.h"
#include "fly/types/string.h"

#include "test/util/path_util.h"
#include "test/util/waitable_task_runner.h"

namespace
{
    /**
     * Subclass of the path config to decrease the poll interval for faster
     * testing.
     */
    class TestPathConfig : public fly::PathConfig
    {
    public:
        TestPathConfig() : fly::PathConfig()
        {
            m_defaultPollInterval = I64(10);
        }
    };
}

//==============================================================================
class ConfigManagerTest : public ::testing::Test
{
public:
    ConfigManagerTest() :
        m_path(fly::PathUtil::GenerateTempDirectory()),
        m_file(fly::String::GenerateRandomString(10) + ".txt"),
        m_fullPath(fly::Path::Join(m_path, m_file)),

        m_spTaskManager(std::make_shared<fly::TaskManager>(1)),

        m_spTaskRunner(
            m_spTaskManager->CreateTaskRunner<fly::WaitableSequencedTaskRunner>()
        ),

        m_spConfigManager(std::make_shared<fly::ConfigManager>(
            m_spTaskRunner,
            fly::ConfigManager::ConfigFileType::Ini,
            m_path,
            m_file
        )),

        m_spPathConfig(m_spConfigManager->CreateConfig<TestPathConfig>())
    {
    }

    /**
     * Create the file directory and start the task and config managers.
     */
    void SetUp() override
    {
        ASSERT_TRUE(fly::Path::MakePath(m_path));
        ASSERT_TRUE(m_spTaskManager->Start());
        ASSERT_TRUE(m_spConfigManager->Start());

        m_initialSize = m_spConfigManager->GetSize();
    }

    /**
     * Delete the created directory and stop the task manager.
     */
    void TearDown() override
    {
        ASSERT_TRUE(m_spTaskManager->Stop());
        ASSERT_TRUE(fly::Path::RemovePath(m_path));
    }

protected:
    std::string m_path;
    std::string m_file;
    std::string m_fullPath;

    fly::TaskManagerPtr m_spTaskManager;
    fly::WaitableSequencedTaskRunnerPtr m_spTaskRunner;

    fly::ConfigManagerPtr m_spConfigManager;

    fly::PathConfigPtr m_spPathConfig;

    size_t m_initialSize;
};

//==============================================================================
class BadConfig : public fly::Config
{
    // Badly written config class which does not override the GetName() method.
    // It will have the same name as the base Config class.
};

//==============================================================================
TEST_F(ConfigManagerTest, AllFileTypesTest)
{
    {
        m_spConfigManager = std::make_shared<fly::ConfigManager>(
            m_spTaskRunner,
            fly::ConfigManager::ConfigFileType::Ini,
            m_path,
            m_file
        );
        m_spPathConfig = m_spConfigManager->CreateConfig<TestPathConfig>();

        EXPECT_TRUE(m_spConfigManager->Start());
    }
    {
        m_spConfigManager = std::make_shared<fly::ConfigManager>(
            m_spTaskRunner,
            fly::ConfigManager::ConfigFileType::Json,
            m_path,
            m_file
        );
        m_spPathConfig = m_spConfigManager->CreateConfig<TestPathConfig>();

        EXPECT_TRUE(m_spConfigManager->Start());
    }
}

//==============================================================================
TEST_F(ConfigManagerTest, BadFileTypeTest)
{
    m_spConfigManager = std::make_shared<fly::ConfigManager>(
        m_spTaskRunner,
        static_cast<fly::ConfigManager::ConfigFileType>(-1),
        m_path,
        m_file
    );

    EXPECT_FALSE(m_spConfigManager->Start());
}

//==============================================================================
TEST_F(ConfigManagerTest, CreateConfigTest)
{
    auto spConfig = m_spConfigManager->CreateConfig<fly::Config>();
    EXPECT_EQ(m_spConfigManager->GetSize(), m_initialSize + 1);
}

//==============================================================================
TEST_F(ConfigManagerTest, DuplicateConfigTest)
{
    auto spConfig1 = m_spConfigManager->CreateConfig<fly::Config>();
    EXPECT_EQ(m_spConfigManager->GetSize(), m_initialSize + 1);

    auto spConfig2 = m_spConfigManager->CreateConfig<fly::Config>();
    EXPECT_EQ(m_spConfigManager->GetSize(), m_initialSize + 1);
}

//==============================================================================
TEST_F(ConfigManagerTest, DeletedConfigTest)
{
    EXPECT_EQ(m_spConfigManager->GetSize(), m_initialSize);

    {
        auto spConfig = m_spConfigManager->CreateConfig<fly::Config>();
        EXPECT_EQ(m_spConfigManager->GetSize(), m_initialSize + 1);
    }

    EXPECT_EQ(m_spConfigManager->GetSize(), m_initialSize);

    {
        auto spConfig = m_spConfigManager->CreateConfig<fly::Config>();
        EXPECT_EQ(m_spConfigManager->GetSize(), m_initialSize + 1);
    }

    auto spConfig = m_spConfigManager->CreateConfig<fly::Config>();
    EXPECT_FALSE(spConfig.get() == NULL);
    spConfig.reset();

    spConfig = m_spConfigManager->CreateConfig<fly::Config>();
    EXPECT_FALSE(spConfig.get() == NULL);
}

//==============================================================================
TEST_F(ConfigManagerTest, DeletedConfigDetectedByPollerTest)
{
    EXPECT_EQ(m_spConfigManager->GetSize(), m_initialSize);

    const std::string contents(
        "[" + fly::Config::GetName() + "]\n"
        "name=John Doe\n"
        "address=USA"
    );

    ASSERT_TRUE(fly::PathUtil::WriteFile(m_fullPath, contents));
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();

    {
        auto spConfig = m_spConfigManager->CreateConfig<fly::Config>();
        EXPECT_EQ(m_spConfigManager->GetSize(), m_initialSize + 1);

        EXPECT_EQ(spConfig->GetValue<std::string>("name", ""), "John Doe");
        EXPECT_EQ(spConfig->GetValue<std::string>("address", ""), "USA");
    }

    ASSERT_TRUE(fly::PathUtil::WriteFile(m_fullPath, contents + "\n"));
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();

    EXPECT_EQ(m_spConfigManager->GetSize(), m_initialSize);
}

//==============================================================================
TEST_F(ConfigManagerTest, BadConfigTypeTest)
{
    EXPECT_EQ(m_spConfigManager->GetSize(), m_initialSize);

    auto spConfig = m_spConfigManager->CreateConfig<fly::Config>();
    EXPECT_EQ(m_spConfigManager->GetSize(), m_initialSize + 1);

    auto spConfig2 = m_spConfigManager->CreateConfig<BadConfig>();
    EXPECT_EQ(m_spConfigManager->GetSize(), m_initialSize + 1);
    EXPECT_FALSE(spConfig2);
}

//==============================================================================
TEST_F(ConfigManagerTest, InitialFileFirstTest)
{
    const std::string contents(
        "[" + fly::Config::GetName() + "]\n"
        "name=John Doe\n"
        "address=USA"
    );

    ASSERT_TRUE(fly::PathUtil::WriteFile(m_fullPath, contents));
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();

    auto spConfig = m_spConfigManager->CreateConfig<fly::Config>();

    EXPECT_EQ(spConfig->GetValue<std::string>("name", ""), "John Doe");
    EXPECT_EQ(spConfig->GetValue<std::string>("address", ""), "USA");
}

//==============================================================================
TEST_F(ConfigManagerTest, InitialFileSecondTest)
{
    auto spConfig = m_spConfigManager->CreateConfig<fly::Config>();

    const std::string contents(
        "[" + fly::Config::GetName() + "]\n"
        "name=John Doe\n"
        "address=USA"
    );

    ASSERT_TRUE(fly::PathUtil::WriteFile(m_fullPath, contents));
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();

    EXPECT_EQ(spConfig->GetValue<std::string>("name", ""), "John Doe");
    EXPECT_EQ(spConfig->GetValue<std::string>("address", ""), "USA");
}

//==============================================================================
TEST_F(ConfigManagerTest, FileChangeTest)
{
    auto spConfig = m_spConfigManager->CreateConfig<fly::Config>();

    const std::string contents1(
        "[" + fly::Config::GetName() + "]\n"
        "name=John Doe\n"
        "address=USA"
    );

    ASSERT_TRUE(fly::PathUtil::WriteFile(m_fullPath, contents1));
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();

    EXPECT_EQ(spConfig->GetValue<std::string>("name", ""), "John Doe");
    EXPECT_EQ(spConfig->GetValue<std::string>("address", ""), "USA");
    EXPECT_EQ(spConfig->GetValue<int>("age", -1), -1);

    const std::string contents2(
        "[" + fly::Config::GetName() + "]\n"
        "name=Jane Doe\n"
        "age=27"
    );

    ASSERT_TRUE(fly::PathUtil::WriteFile(m_fullPath, contents2));
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();

    EXPECT_EQ(spConfig->GetValue<std::string>("name", ""), "Jane Doe");
    EXPECT_EQ(spConfig->GetValue<std::string>("address", ""), "");
    EXPECT_EQ(spConfig->GetValue<int>("age", -1), 27);
}

//==============================================================================
TEST_F(ConfigManagerTest, DeleteFileTest)
{
    auto spConfig = m_spConfigManager->CreateConfig<fly::Config>();

    const std::string contents(
        "[" + fly::Config::GetName() + "]\n"
        "name=John Doe\n"
        "address=USA"
    );

    ASSERT_TRUE(fly::PathUtil::WriteFile(m_fullPath, contents));
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();

    EXPECT_EQ(spConfig->GetValue<std::string>("name", ""), "John Doe");
    EXPECT_EQ(spConfig->GetValue<std::string>("address", ""), "USA");

    std::remove(m_fullPath.c_str());
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();

    EXPECT_EQ(spConfig->GetValue<std::string>("name", ""), "");
    EXPECT_EQ(spConfig->GetValue<std::string>("address", ""), "");
}

//==============================================================================
TEST_F(ConfigManagerTest, BadUpdateTest)
{
    auto spConfig = m_spConfigManager->CreateConfig<fly::Config>();

    const std::string contents(
        "[" + fly::Config::GetName() + "]\n"
        "name"
    );

    ASSERT_TRUE(fly::PathUtil::WriteFile(m_fullPath, contents));
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();

    EXPECT_EQ(spConfig->GetValue<std::string>("name", ""), "");
    EXPECT_EQ(spConfig->GetValue<std::string>("address", ""), "");
}

//==============================================================================
TEST_F(ConfigManagerTest, BadObjectTest)
{
    m_spConfigManager = std::make_shared<fly::ConfigManager>(
        m_spTaskRunner,
        fly::ConfigManager::ConfigFileType::Json,
        m_path,
        m_file
    );
    m_spPathConfig = m_spConfigManager->CreateConfig<TestPathConfig>();

    EXPECT_TRUE(m_spConfigManager->Start());

    auto spConfig = m_spConfigManager->CreateConfig<fly::Config>();

    const std::string contents("[1, 2, 3]");

    ASSERT_TRUE(fly::PathUtil::WriteFile(m_fullPath, contents));
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();
    m_spTaskRunner->WaitForTaskTypeToComplete<fly::ConfigUpdateTask>();

    EXPECT_EQ(spConfig->GetValue<std::string>("name", ""), "");
    EXPECT_EQ(spConfig->GetValue<std::string>("address", ""), "");
}
<|endoftext|>


<commit_before>#include "interpreterTest.h"

#include <QtCore/QCoreApplication>

#include <qrtext/lua/luaToolbox.h>
#include "src/interpreter/interpreter.h"
#include "src/textLanguage/robotsBlockParser.h"

using namespace qrTest::robotsTests::interpreterCoreTests;

using namespace interpreterCore::interpreter;
using namespace ::testing;

void InterpreterTest::SetUp()
{
	/// @todo: Need to rewrite this shit with 'temp' setting manager value.
	/// It is used in serializer and innitialized in main window.
	/// So when we run tests outside of enviroment they fail!
	qReal::SettingsManager::setValue("temp", QCoreApplication::applicationDirPath() + "/unsaved");
	mQrguiFacade.reset(new QrguiFacade("unittests/basicTest.qrs"));
	mQrguiFacade->setActiveTab(qReal::Id::loadFromString(
			"qrm:/RobotsMetamodel/RobotsDiagram/RobotsDiagramNode/{f08fa823-e187-4755-87ba-e4269ae4e798}"));

	mFakeConnectToRobotAction.reset(new QAction(nullptr));

	ON_CALL(mConfigurationInterfaceMock, devices()).WillByDefault(
			Return(QList<interpreterBase::robotModel::robotParts::Device *>())
			);
	EXPECT_CALL(mConfigurationInterfaceMock, devices()).Times(AtLeast(1));

	/// @todo: Do we need this code in some common place? Why do we need to write
	/// it every time when we are going to use RobotModelManager mock?

	ON_CALL(mModel, name()).WillByDefault(Return("mockRobot"));
	EXPECT_CALL(mModel, name()).Times(AtLeast(1));

	ON_CALL(mModel, needsConnection()).WillByDefault(Return(false));
	EXPECT_CALL(mModel, needsConnection()).Times(AtLeast(0));

	ON_CALL(mModel, init()).WillByDefault(Return());
	EXPECT_CALL(mModel, init()).Times(AtLeast(0));

	ON_CALL(mModel, configuration()).WillByDefault(ReturnRef(mConfigurationInterfaceMock));
	EXPECT_CALL(mModel, configuration()).Times(AtLeast(0));

	ON_CALL(mModel, connectToRobot()).WillByDefault(
			Invoke(&mModelManager, &RobotModelManagerInterfaceMock::emitConnected)
			);
	EXPECT_CALL(mModel, connectToRobot()).Times(AtLeast(0));

	ON_CALL(mModel, disconnectFromRobot()).WillByDefault(
			Invoke(&mModelManager, &RobotModelManagerInterfaceMock::emitDisconnected)
			);
	EXPECT_CALL(mModel, disconnectFromRobot()).Times(AtLeast(0));

	ON_CALL(mModel, configurablePorts()).WillByDefault(Return(QList<interpreterBase::robotModel::PortInfo>()));
	EXPECT_CALL(mModel, configurablePorts()).Times(AtLeast(0));

	ON_CALL(mModel, availablePorts()).WillByDefault(Return(QList<interpreterBase::robotModel::PortInfo>()));
	EXPECT_CALL(mModel, availablePorts()).Times(AtLeast(0));

	ON_CALL(mModel, applyConfiguration()).WillByDefault(
			Invoke(&mModelManager, &RobotModelManagerInterfaceMock::emitAllDevicesConfigured)
			);
	EXPECT_CALL(mModel, applyConfiguration()).Times(1);

	ON_CALL(mModel, connectionState()).WillByDefault(Return(RobotModelInterfaceMock::connectedState));
	EXPECT_CALL(mModel, connectionState()).Times(2);

	ON_CALL(mModel, timeline()).WillByDefault(ReturnRef(mTimeline));
	EXPECT_CALL(mModel, timeline()).Times(AtLeast(1));

	ON_CALL(mModelManager, model()).WillByDefault(ReturnRef(mModel));
	EXPECT_CALL(mModelManager, model()).Times(AtLeast(1));

	ON_CALL(mBlocksFactoryManager, addFactory(_, _)).WillByDefault(Return());
	EXPECT_CALL(mBlocksFactoryManager, addFactory(_, _)).Times(0);

	/// @todo Don't like it.
	interpreterCore::textLanguage::RobotsBlockParser parser(
			mQrguiFacade->mainWindowInterpretersInterface().errorReporter()
			, mModelManager
			, []() { return 0; }
			);

	qrtext::lua::LuaToolbox luaToolbox;

	DummyBlockFactory *blocksFactory = new DummyBlockFactory;
	blocksFactory->configure(
			mQrguiFacade->graphicalModelAssistInterface()
			, mQrguiFacade->logicalModelAssistInterface()
			, mModelManager
			, *mQrguiFacade->mainWindowInterpretersInterface().errorReporter()
			, luaToolbox
			);

	ON_CALL(mBlocksFactoryManager, block(_, _)).WillByDefault(
			Invoke([=] (qReal::Id const &id, interpreterBase::robotModel::RobotModelInterface const &robotModel) {
					Q_UNUSED(robotModel)
					return blocksFactory->block(id);
			} )
			);
	EXPECT_CALL(mBlocksFactoryManager, block(_, _)).Times(AtLeast(0));

	ON_CALL(mBlocksFactoryManager, enabledBlocks(_)).WillByDefault(
			Invoke([=] (interpreterBase::robotModel::RobotModelInterface const &robotModel) {
					Q_UNUSED(robotModel)
					return blocksFactory->providedBlocks().toSet();
			} )
			);
	EXPECT_CALL(mBlocksFactoryManager, enabledBlocks(_)).Times(0);

	mInterpreter.reset(new Interpreter(
			mQrguiFacade->graphicalModelAssistInterface()
			, mQrguiFacade->logicalModelAssistInterface()
			, mQrguiFacade->mainWindowInterpretersInterface()
			, mQrguiFacade->projectManagementInterface()
			, mBlocksFactoryManager
			, mModelManager
			, luaToolbox
			, *mFakeConnectToRobotAction
			));
}

TEST_F(InterpreterTest, interpret)
{
	EXPECT_CALL(mModel, stopRobot()).Times(1);

	mInterpreter->interpret();
}

TEST_F(InterpreterTest, stopRobot)
{
	// It shall be called directly here and in destructor of a model.
	EXPECT_CALL(mModel, stopRobot()).Times(2);

	mInterpreter->interpret();
	mInterpreter->stopRobot();
}
<commit_msg>fixed unit tests<commit_after>#include "interpreterTest.h"

#include <QtCore/QCoreApplication>

#include <qrtext/lua/luaToolbox.h>
#include "src/interpreter/interpreter.h"
#include "src/textLanguage/robotsBlockParser.h"

using namespace qrTest::robotsTests::interpreterCoreTests;

using namespace interpreterCore::interpreter;
using namespace ::testing;

void InterpreterTest::SetUp()
{
	/// @todo: Need to rewrite this shit with 'temp' setting manager value.
	/// It is used in serializer and innitialized in main window.
	/// So when we run tests outside of enviroment they fail!
	qReal::SettingsManager::setValue("temp", QCoreApplication::applicationDirPath() + "/unsaved");
	mQrguiFacade.reset(new QrguiFacade("unittests/basicTest.qrs"));
	mQrguiFacade->setActiveTab(qReal::Id::loadFromString(
			"qrm:/RobotsMetamodel/RobotsDiagram/RobotsDiagramNode/{f08fa823-e187-4755-87ba-e4269ae4e798}"));

	mFakeConnectToRobotAction.reset(new QAction(nullptr));

	ON_CALL(mConfigurationInterfaceMock, devices()).WillByDefault(
			Return(QList<interpreterBase::robotModel::robotParts::Device *>())
			);
	EXPECT_CALL(mConfigurationInterfaceMock, devices()).Times(AtLeast(1));

	/// @todo: Do we need this code in some common place? Why do we need to write
	/// it every time when we are going to use RobotModelManager mock?

	ON_CALL(mModel, name()).WillByDefault(Return("mockRobot"));
	EXPECT_CALL(mModel, name()).Times(AtLeast(1));

	ON_CALL(mModel, needsConnection()).WillByDefault(Return(false));
	EXPECT_CALL(mModel, needsConnection()).Times(AtLeast(0));

	ON_CALL(mModel, init()).WillByDefault(Return());
	EXPECT_CALL(mModel, init()).Times(AtLeast(0));

	ON_CALL(mModel, configuration()).WillByDefault(ReturnRef(mConfigurationInterfaceMock));
	EXPECT_CALL(mModel, configuration()).Times(AtLeast(0));

	ON_CALL(mModel, connectToRobot()).WillByDefault(
			Invoke(&mModelManager, &RobotModelManagerInterfaceMock::emitConnected)
			);
	EXPECT_CALL(mModel, connectToRobot()).Times(AtLeast(0));

	ON_CALL(mModel, disconnectFromRobot()).WillByDefault(
			Invoke(&mModelManager, &RobotModelManagerInterfaceMock::emitDisconnected)
			);
	EXPECT_CALL(mModel, disconnectFromRobot()).Times(AtLeast(0));

	ON_CALL(mModel, configurablePorts()).WillByDefault(Return(QList<interpreterBase::robotModel::PortInfo>()));
	EXPECT_CALL(mModel, configurablePorts()).Times(AtLeast(0));

	ON_CALL(mModel, availablePorts()).WillByDefault(Return(QList<interpreterBase::robotModel::PortInfo>()));
	EXPECT_CALL(mModel, availablePorts()).Times(AtLeast(0));

	ON_CALL(mModel, applyConfiguration()).WillByDefault(
			Invoke(&mModelManager, &RobotModelManagerInterfaceMock::emitAllDevicesConfigured)
			);
	EXPECT_CALL(mModel, applyConfiguration()).Times(1);

	ON_CALL(mModel, connectionState()).WillByDefault(Return(RobotModelInterfaceMock::connectedState));
	EXPECT_CALL(mModel, connectionState()).Times(2);

	ON_CALL(mModel, timeline()).WillByDefault(ReturnRef(mTimeline));
	EXPECT_CALL(mModel, timeline()).Times(AtLeast(1));

	ON_CALL(mModelManager, model()).WillByDefault(ReturnRef(mModel));
	EXPECT_CALL(mModelManager, model()).Times(AtLeast(1));

	ON_CALL(mBlocksFactoryManager, addFactory(_, _)).WillByDefault(Return());
	EXPECT_CALL(mBlocksFactoryManager, addFactory(_, _)).Times(0);

	interpreterCore::textLanguage::RobotsBlockParser parser(mModelManager, []() { return 0; });

	DummyBlockFactory *blocksFactory = new DummyBlockFactory;
	blocksFactory->configure(
			mQrguiFacade->graphicalModelAssistInterface()
			, mQrguiFacade->logicalModelAssistInterface()
			, mModelManager
			, *mQrguiFacade->mainWindowInterpretersInterface().errorReporter()
			, parser
			);

	ON_CALL(mBlocksFactoryManager, block(_, _)).WillByDefault(
			Invoke([=] (qReal::Id const &id, interpreterBase::robotModel::RobotModelInterface const &robotModel) {
					Q_UNUSED(robotModel)
					return blocksFactory->block(id);
			} )
			);
	EXPECT_CALL(mBlocksFactoryManager, block(_, _)).Times(AtLeast(0));

	ON_CALL(mBlocksFactoryManager, enabledBlocks(_)).WillByDefault(
			Invoke([=] (interpreterBase::robotModel::RobotModelInterface const &robotModel) {
					Q_UNUSED(robotModel)
					return blocksFactory->providedBlocks().toSet();
			} )
			);
	EXPECT_CALL(mBlocksFactoryManager, enabledBlocks(_)).Times(0);

	mInterpreter.reset(new Interpreter(
			mQrguiFacade->graphicalModelAssistInterface()
			, mQrguiFacade->logicalModelAssistInterface()
			, mQrguiFacade->mainWindowInterpretersInterface()
			, mQrguiFacade->projectManagementInterface()
			, mBlocksFactoryManager
			, mModelManager
			, parser
			, *mFakeConnectToRobotAction
			));
}

TEST_F(InterpreterTest, interpret)
{
	EXPECT_CALL(mModel, stopRobot()).Times(1);

	mInterpreter->interpret();
}

TEST_F(InterpreterTest, stopRobot)
{
	// It shall be called directly here and in destructor of a model.
	EXPECT_CALL(mModel, stopRobot()).Times(2);

	mInterpreter->interpret();
	mInterpreter->stopRobot();
}
<|endoftext|>


<commit_before>//**********************************************************************;
// Copyright (c) 2015, Intel Corporation
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// 3. Neither the name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
//**********************************************************************;

#ifdef _WIN32
#include "stdafx.h"
#else
#include <stdarg.h>
#endif

#ifndef UNICODE
#define UNICODE 1
#endif

#ifdef _WIN32
// link with Ws2_32.lib
#pragma comment(lib,"Ws2_32.lib")

#include <winsock2.h>
#include <ws2tcpip.h>
#else
#define sprintf_s   snprintf
#define sscanf_s    sscanf
#endif

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <ctype.h>
#include <getopt.h>

#include <tss2/tpm20.h>
#include <tcti/tcti_socket.h>
#include "common.h"

int debugLevel = 0;
UINT32 nvIndex = 0;
UINT32 authHandle = TPM_RH_PLATFORM;
UINT16 dataSize = 0;
unsigned char nvBuffer[MAX_NV_BUFFER_SIZE];
char fileName[PATH_MAX];
char handlePasswd[sizeof(TPMU_HA)];

int nvWrite()
{
    UINT32 rval;
    TPMS_AUTH_COMMAND sessionData;
    TPMS_AUTH_RESPONSE sessionDataOut;
    TSS2_SYS_CMD_AUTHS sessionsData;
    TSS2_SYS_RSP_AUTHS sessionsDataOut;
    int i;
    TPM2B_MAX_NV_BUFFER nvWriteData;

    TPMS_AUTH_COMMAND *sessionDataArray[1] = { &sessionData };
    TPMS_AUTH_RESPONSE *sessionDataOutArray[1] = { &sessionDataOut };

    sessionsDataOut.rspAuths = &sessionDataOutArray[0];
    sessionsData.cmdAuths = &sessionDataArray[0];

    sessionsDataOut.rspAuthsCount = 1;
    sessionsData.cmdAuthsCount = 1;

    sessionData.sessionHandle = TPM_RS_PW;
    sessionData.nonce.t.size = 0;
    sessionData.hmac.t.size = 0;
    *( (UINT8 *)((void *)&sessionData.sessionAttributes ) ) = 0;

    if (strlen(handlePasswd) > 0)
    {
        sessionData.hmac.t.size = strlen(handlePasswd);
        memcpy( &sessionData.hmac.t.buffer[0], handlePasswd, sessionData.hmac.t.size );
    }

    nvWriteData.t.size = dataSize;
    printf("\nThe data(size=%d) to be written:\n", dataSize);
    for( i = 0; i<(int)dataSize; i++ )
    {
        nvWriteData.t.buffer[i] = nvBuffer[i];
        printf("%02x\t", nvBuffer[i]);
    }
    printf("\n\n");

    rval = Tss2_Sys_NV_Write( sysContext, authHandle, nvIndex, &sessionsData, &nvWriteData, 0, &sessionsDataOut );
    if(rval != TSS2_RC_SUCCESS)
    {
        printf( "Failed to write NV area at index 0x%x (%d).Error:0x%x\n", nvIndex, nvIndex, rval );
        return -1;
    }
    printf( "Success to write NV area at index 0x%x (%d).\n", nvIndex, nvIndex );

    return 0;
}

void showHelp(const char *name)
{
    printf("Usage: %s [-h/--help]\n"
           "   or: %s [-v/--version]\n"
           "   or: %s [-x/--index <nvIdx>] [-a/--authHandle <hexHandle>] [-P/--handlePasswd <string>] [-f/--file <filename>]\n"
           "   or: %s [-x/--index <nvIdx>] [-a/--authHandle <hexHandle>] [-P/--handlePasswd <string>] [-f/--file <filename>]\n"
           "                    [-p/--port <port>] [-d/--dbg <dbgLevel>]\n"
           "\nwhere:\n\n"
           "   -h/--help                       display this help and exit.\n"
           "   -v/--version                    display version information and exit.\n"
           "   -x/--index <nvIdx>              specifies the index of the NV area.\n"
           "   -a/--authHandle <hexHandle>     specifies the handle used to authorize:\n"
           "                                     0x40000001 (TPM_RH_OWNER)\n"
           "                                     0x4000000C (TPM_RH_PLATFORM)\n"
           "                                     {NV_INDEX_FIRST:NV_INDEX_LAST}\n"
           "   -P/--handlePasswd <string>      specifies the password of authHandle.\n"
           "   -f/--file <filename>            specifies the nv data file.\n"
           "   -p/--port <port>                specifies the port number, default:%d, optional\n"
           "   -d/--dbg <dbgLevel>             specifies level of debug messages, optional:\n"
           "                                     0 (high level test results)\n"
           "                                     1 (test app send/receive byte streams)\n"
           "                                     2 (resource manager send/receive byte streams)\n"
           "                                     3 (resource manager tables)\n"
           "\nexample:\n"
           "   %s -x 0x1500016 -a 0x40000001 -P passwd -f nv.data\n"
           , name, name, name, name, DEFAULT_RESMGR_TPM_PORT, name);
}

int main(int argc, char* argv[])
{
    int opt;
    char type[100] = "local";
    char hostName[200] = DEFAULT_HOSTNAME;
    int port = DEFAULT_RESMGR_TPM_PORT;
    int returnVal = 0;

    struct option sOpts[] = {
        { "index"       , required_argument, NULL, 'x' },
        { "authHandle"  , required_argument, NULL, 'a' },
        { "file"        , required_argument, NULL, 'f' },
        { "handlePasswd", required_argument, NULL, 'P' },
        { "port"        , required_argument, NULL, 'p' },
        { "dbg"         , required_argument, NULL, 'd' },
        { "help"        , no_argument,       NULL, 'h' },
        { "version"     , no_argument,       NULL, 'v' },
        { NULL          , no_argument,       NULL,  0  },
    };

    if(argc == 1)
    {
        showHelp(argv[0]);
        return 0;
    }

    if( argc > (int)(2*sizeof(sOpts)/sizeof(struct option)) )
    {
        showArgMismatch(argv[0]);
        return -1;
    }

    while ( ( opt = getopt_long( argc, argv, "x:a:f:P:p:d:hv", sOpts, NULL ) ) != -1 )
    {
        switch ( opt ) {
        case 'h':
        case '?':
            showHelp(argv[0]);
            return 0;
        case 'v':
            showVersion(argv[0]);
            return 0;

        case 'x':
            if( getSizeUint32Hex(optarg, &nvIndex) != 0 )
            {
                return -2;
            }
            break;

        case 'a':
            if( getSizeUint32Hex(optarg, &authHandle) != 0 )
            {
                return -3;
            }
            break;

        case 'P':
            if( optarg == NULL || (strlen(optarg) >= sizeof(TPMU_HA)) )
            {
                printf("\nPlease input the handle password(optional,no more than %d characters).\n", (int)sizeof(TPMU_HA)-1);
                return -4;
            }
            safeStrNCpy(&handlePasswd[0], optarg, sizeof(handlePasswd));
            break;

        case 'f':
            if( optarg == NULL )
            {
                printf("\nPlease input the nv data file.\n");
                return -5;
            }
            safeStrNCpy(&fileName[0], optarg, sizeof(fileName));
            break;

         case 'p':
            if( getPort(optarg, &port) )
            {
                printf("Incorrect port number.\n");
                return -6;
            }
            break;
        case 'd':
            if( getDebugLevel(optarg, &debugLevel) )
            {
                printf("Incorrect debug level.\n");
                return -7;
            }
            break;

        default:
            showArgMismatch(argv[0]);
            return -8;
        }
    }

    if( nvIndex == 0 )
    {
        printf("You must provide an index (!= 0) for the NVRAM area.\n");
        return -9;
    }

    if( authHandle == 0 )
    {
        printf("You must provide an right auth handle for this operation.\n");
        return -10;
    }

    dataSize = MAX_NV_BUFFER_SIZE;
    if(loadDataFromFile(fileName, nvBuffer, &dataSize))
    {
        printf("Failed to read data from %s\n", fileName);
        return -11;
    }

    prepareTest(hostName, port, debugLevel);

    returnVal = nvWrite();

    finishTest();

    if(returnVal)
        return -12;

    return 0;
}
<commit_msg>tpm2-nvwrite: fix for unable to write 1024B+ data<commit_after>//**********************************************************************;
// Copyright (c) 2015, Intel Corporation
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// 3. Neither the name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
//**********************************************************************;

#ifdef _WIN32
#include "stdafx.h"
#else
#include <stdarg.h>
#endif

#ifndef UNICODE
#define UNICODE 1
#endif

#ifdef _WIN32
// link with Ws2_32.lib
#pragma comment(lib,"Ws2_32.lib")

#include <winsock2.h>
#include <ws2tcpip.h>
#else
#define sprintf_s   snprintf
#define sscanf_s    sscanf
#endif

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <ctype.h>
#include <getopt.h>

#include <tss2/tpm20.h>
#include <tcti/tcti_socket.h>
#include "common.h"

int debugLevel = 0;
UINT32 nvIndex = 0;
UINT32 authHandle = TPM_RH_PLATFORM;
UINT16 dataSize = 0;
unsigned char nvBuffer[MAX_NV_INDEX_SIZE];
char fileName[PATH_MAX];
char handlePasswd[sizeof(TPMU_HA)];

int nvWrite()
{
    UINT32 rval;
    TPMS_AUTH_COMMAND sessionData;
    TPMS_AUTH_RESPONSE sessionDataOut;
    TSS2_SYS_CMD_AUTHS sessionsData;
    TSS2_SYS_RSP_AUTHS sessionsDataOut;
    UINT16 i, offset = 0;
    TPM2B_MAX_NV_BUFFER nvWriteData;

    TPMS_AUTH_COMMAND *sessionDataArray[1] = { &sessionData };
    TPMS_AUTH_RESPONSE *sessionDataOutArray[1] = { &sessionDataOut };

    sessionsDataOut.rspAuths = &sessionDataOutArray[0];
    sessionsData.cmdAuths = &sessionDataArray[0];

    sessionsDataOut.rspAuthsCount = 1;
    sessionsData.cmdAuthsCount = 1;

    sessionData.sessionHandle = TPM_RS_PW;
    sessionData.nonce.t.size = 0;
    sessionData.hmac.t.size = 0;
    *( (UINT8 *)((void *)&sessionData.sessionAttributes ) ) = 0;

    if (strlen(handlePasswd) > 0)
    {
        sessionData.hmac.t.size = strlen(handlePasswd);
        memcpy( &sessionData.hmac.t.buffer[0], handlePasswd, sessionData.hmac.t.size );
    }

    while (dataSize > 0)
    {
        nvWriteData.t.size = dataSize > MAX_NV_BUFFER_SIZE ? MAX_NV_BUFFER_SIZE : dataSize;
        printf("\nThe data(size=%d) to be written:\n", nvWriteData.t.size);
        for( i = 0; i<(int)nvWriteData.t.size; i++ )
        {
            nvWriteData.t.buffer[i] = nvBuffer[offset+i];
            printf("%02x ", nvBuffer[offset+i]);
        }
        printf("\n\n");

        rval = Tss2_Sys_NV_Write( sysContext, authHandle, nvIndex, &sessionsData, &nvWriteData, offset, &sessionsDataOut );
        if(rval != TSS2_RC_SUCCESS)
        {
            printf( "Failed to write NV area at index 0x%x (%d) offset 0x%x. Error:0x%x\n", nvIndex, nvIndex, offset, rval );
            return -1;
        }
        printf( "Success to write NV area at index 0x%x (%d) offset 0x%x.\n", nvIndex, nvIndex, offset );

        dataSize -= nvWriteData.t.size;
        offset += nvWriteData.t.size;
    }

    return 0;
}

void showHelp(const char *name)
{
    printf("Usage: %s [-h/--help]\n"
           "   or: %s [-v/--version]\n"
           "   or: %s [-x/--index <nvIdx>] [-a/--authHandle <hexHandle>] [-P/--handlePasswd <string>] [-f/--file <filename>]\n"
           "   or: %s [-x/--index <nvIdx>] [-a/--authHandle <hexHandle>] [-P/--handlePasswd <string>] [-f/--file <filename>]\n"
           "                    [-p/--port <port>] [-d/--dbg <dbgLevel>]\n"
           "\nwhere:\n\n"
           "   -h/--help                       display this help and exit.\n"
           "   -v/--version                    display version information and exit.\n"
           "   -x/--index <nvIdx>              specifies the index of the NV area.\n"
           "   -a/--authHandle <hexHandle>     specifies the handle used to authorize:\n"
           "                                     0x40000001 (TPM_RH_OWNER)\n"
           "                                     0x4000000C (TPM_RH_PLATFORM)\n"
           "                                     {NV_INDEX_FIRST:NV_INDEX_LAST}\n"
           "   -P/--handlePasswd <string>      specifies the password of authHandle.\n"
           "   -f/--file <filename>            specifies the nv data file.\n"
           "   -p/--port <port>                specifies the port number, default:%d, optional\n"
           "   -d/--dbg <dbgLevel>             specifies level of debug messages, optional:\n"
           "                                     0 (high level test results)\n"
           "                                     1 (test app send/receive byte streams)\n"
           "                                     2 (resource manager send/receive byte streams)\n"
           "                                     3 (resource manager tables)\n"
           "\nexample:\n"
           "   %s -x 0x1500016 -a 0x40000001 -P passwd -f nv.data\n"
           , name, name, name, name, DEFAULT_RESMGR_TPM_PORT, name);
}

int main(int argc, char* argv[])
{
    int opt;
    char type[100] = "local";
    char hostName[200] = DEFAULT_HOSTNAME;
    int port = DEFAULT_RESMGR_TPM_PORT;
    int returnVal = 0;

    struct option sOpts[] = {
        { "index"       , required_argument, NULL, 'x' },
        { "authHandle"  , required_argument, NULL, 'a' },
        { "file"        , required_argument, NULL, 'f' },
        { "handlePasswd", required_argument, NULL, 'P' },
        { "port"        , required_argument, NULL, 'p' },
        { "dbg"         , required_argument, NULL, 'd' },
        { "help"        , no_argument,       NULL, 'h' },
        { "version"     , no_argument,       NULL, 'v' },
        { NULL          , no_argument,       NULL,  0  },
    };

    if(argc == 1)
    {
        showHelp(argv[0]);
        return 0;
    }

    if( argc > (int)(2*sizeof(sOpts)/sizeof(struct option)) )
    {
        showArgMismatch(argv[0]);
        return -1;
    }

    while ( ( opt = getopt_long( argc, argv, "x:a:f:P:p:d:hv", sOpts, NULL ) ) != -1 )
    {
        switch ( opt ) {
        case 'h':
        case '?':
            showHelp(argv[0]);
            return 0;
        case 'v':
            showVersion(argv[0]);
            return 0;

        case 'x':
            if( getSizeUint32Hex(optarg, &nvIndex) != 0 )
            {
                return -2;
            }
            break;

        case 'a':
            if( getSizeUint32Hex(optarg, &authHandle) != 0 )
            {
                return -3;
            }
            break;

        case 'P':
            if( optarg == NULL || (strlen(optarg) >= sizeof(TPMU_HA)) )
            {
                printf("\nPlease input the handle password(optional,no more than %d characters).\n", (int)sizeof(TPMU_HA)-1);
                return -4;
            }
            safeStrNCpy(&handlePasswd[0], optarg, sizeof(handlePasswd));
            break;

        case 'f':
            if( optarg == NULL )
            {
                printf("\nPlease input the nv data file.\n");
                return -5;
            }
            safeStrNCpy(&fileName[0], optarg, sizeof(fileName));
            break;

         case 'p':
            if( getPort(optarg, &port) )
            {
                printf("Incorrect port number.\n");
                return -6;
            }
            break;
        case 'd':
            if( getDebugLevel(optarg, &debugLevel) )
            {
                printf("Incorrect debug level.\n");
                return -7;
            }
            break;

        default:
            showArgMismatch(argv[0]);
            return -8;
        }
    }

    if( nvIndex == 0 )
    {
        printf("You must provide an index (!= 0) for the NVRAM area.\n");
        return -9;
    }

    if( authHandle == 0 )
    {
        printf("You must provide an right auth handle for this operation.\n");
        return -10;
    }

    dataSize = MAX_NV_INDEX_SIZE;
    if(loadDataFromFile(fileName, nvBuffer, &dataSize))
    {
        printf("Failed to read data from %s\n", fileName);
        return -11;
    }

    prepareTest(hostName, port, debugLevel);

    returnVal = nvWrite();

    finishTest();

    if(returnVal)
        return -12;

    return 0;
}
<|endoftext|>


<commit_before>// vim:ts=2:sw=2:expandtab:autoindent:filetype=cpp:
/*
Copyright (c) 2008 Ash Berlin, Aristid Breitkreuz

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include "flusspferd/object.hpp"
#include "flusspferd/string.hpp"
#include "flusspferd/evaluate.hpp"
#include "flusspferd/io/io.hpp"
#include "test_environment.hpp"

#include <iostream>
#include <string>

#ifdef FLUSSPFERD_HAVE_IO

BOOST_FIXTURE_TEST_SUITE( io, context_fixture )

BOOST_AUTO_TEST_CASE( test_have_IO ) {
  flusspferd::io::load_io();
  flusspferd::root_value v;
  BOOST_CHECK_NO_THROW( v = flusspferd::evaluate("IO", __FILE__, __LINE__) );
  BOOST_CHECK(v.is_object());
  BOOST_CHECK(!v.is_null());

  flusspferd::gc();
}

BOOST_AUTO_TEST_CASE( test_file_read ) {
  flusspferd::io::load_io();
  const char* js = "f = new IO.File('test/fixtures/file1'); f.readWhole()";
  flusspferd::root_value v;
  BOOST_CHECK_NO_THROW( v = flusspferd::evaluate(js, __FILE__, __LINE__) );
  BOOST_CHECK_EQUAL(v.to_string().c_str(), "foobar\nbaz\n");

  js = "f = new IO.File('test/fixtures/file1'); f.readWhole()";
  BOOST_CHECK_NO_THROW( v = flusspferd::evaluate(js, __FILE__, __LINE__) );
  BOOST_CHECK_EQUAL(v.to_string().c_str(), "foobar\nbaz\n");

  flusspferd::gc();
}

BOOST_AUTO_TEST_SUITE_END()

#endif
<commit_msg>Test: IO tests work again<commit_after>// vim:ts=2:sw=2:expandtab:autoindent:filetype=cpp:
/*
Copyright (c) 2008 Ash Berlin, Aristid Breitkreuz

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#include "flusspferd/object.hpp"
#include "flusspferd/string.hpp"
#include "flusspferd/evaluate.hpp"
#include "flusspferd/security.hpp"
#include "flusspferd/io/io.hpp"
#include "test_environment.hpp"

#include <iostream>
#include <string>

#ifdef FLUSSPFERD_HAVE_IO

BOOST_FIXTURE_TEST_SUITE( io, context_fixture )

BOOST_AUTO_TEST_CASE( test_have_IO ) {
  flusspferd::io::load_io();
  flusspferd::root_value v;
  BOOST_CHECK_NO_THROW( v = flusspferd::evaluate("IO", __FILE__, __LINE__) );
  BOOST_CHECK(v.is_object());
  BOOST_CHECK(!v.is_null());

  flusspferd::gc();
}

BOOST_AUTO_TEST_CASE( test_file_read ) {
  flusspferd::io::load_io();
  flusspferd::security::create(flusspferd::global());

  const char* js = "f = new IO.File('test/fixtures/file1'); f.readWhole()";
  flusspferd::root_value v;
  BOOST_CHECK_NO_THROW( v = flusspferd::evaluate(js, __FILE__, __LINE__) );
  BOOST_CHECK_EQUAL(v.to_string().c_str(), "foobar\nbaz\n");

  js = "f = new IO.File('test/fixtures/file1'); f.readWhole()";
  BOOST_CHECK_NO_THROW( v = flusspferd::evaluate(js, __FILE__, __LINE__) );
  BOOST_CHECK_EQUAL(v.to_string().c_str(), "foobar\nbaz\n");

  flusspferd::gc();
}

BOOST_AUTO_TEST_SUITE_END()

#endif
<|endoftext|>