<commit_before>#include "lm/read_arpa.hh"

#include "lm/blank.hh"
#include "util/file.hh"

#include <cmath>
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <vector>

#include <cctype>
#include <cstring>
#include <stdint.h>

#ifdef WIN32
#include <float.h>
#endif

namespace lm {

// 1 for '\t', '\n', and ' '.  This is stricter than isspace.
const bool kARPASpaces[256] = {0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

namespace {

bool IsEntirelyWhiteSpace(const StringPiece &line) {
  for (size_t i = 0; i < static_cast<size_t>(line.size()); ++i) {
    if (!isspace(line.data()[i])) return false;
  }
  return true;
}

const char kBinaryMagic[] = "mmap lm http://kheafield.com/code";

// strtoull isn't portable enough :-(
uint64_t ReadCount(const std::string &from) {
  std::stringstream stream(from);
  uint64_t ret;
  stream >> ret;
  UTIL_THROW_IF(!stream, FormatLoadException, "Bad count " << from);
  return ret;
}

} // namespace

void ReadARPACounts(util::FilePiece &in, std::vector<uint64_t> &number) {
  number.clear();
  StringPiece line = in.ReadLine();
  // In general, ARPA files can have arbitrary text before "\data\"
  // But in KenLM, we require such lines to start with "#", so that
  // we can do stricter error checking
  while (IsEntirelyWhiteSpace(line) || starts_with(line, "#")) {
    line = in.ReadLine();
  }

  if (line != "\\data\\") {
    if ((line.size() >= 2) && (line.data()[0] == 0x1f) && (static_cast<unsigned char>(line.data()[1]) == 0x8b)) {
      UTIL_THROW(FormatLoadException, "Looks like a gzip file.  If this is an ARPA file, pipe " << in.FileName() << " through zcat.  If this already in binary format, you need to decompress it because mmap doesn't work on top of gzip.");
    }
    if (static_cast<size_t>(line.size()) >= strlen(kBinaryMagic) && StringPiece(line.data(), strlen(kBinaryMagic)) == kBinaryMagic)
      UTIL_THROW(FormatLoadException, "This looks like a binary file but got sent to the ARPA parser.  Did you compress the binary file or pass a binary file where only ARPA files are accepted?");
    UTIL_THROW_IF(line.size() >= 4 && StringPiece(line.data(), 4) == "blmt", FormatLoadException, "This looks like an IRSTLM binary file.  Did you forget to pass --text yes to compile-lm?");
    UTIL_THROW_IF(line == "iARPA", FormatLoadException, "This looks like an IRSTLM iARPA file.  You need an ARPA file.  Run\n  compile-lm --text yes " << in.FileName() << " " << in.FileName() << ".arpa\nfirst.");
    UTIL_THROW(FormatLoadException, "first non-empty line was \"" << line << "\" not \\data\\.");
  }
  while (!IsEntirelyWhiteSpace(line = in.ReadLine())) {
    if (line.size() < 6 || strncmp(line.data(), "ngram ", 6)) UTIL_THROW(FormatLoadException, "count line \"" << line << "\"doesn't begin with \"ngram \"");
    // So strtol doesn't go off the end of line.
    std::string remaining(line.data() + 6, line.size() - 6);
    char *end_ptr;
    unsigned int length = std::strtol(remaining.c_str(), &end_ptr, 10);
    if ((end_ptr == remaining.c_str()) || (length - 1 != number.size())) UTIL_THROW(FormatLoadException, "ngram count lengths should be consecutive starting with 1: " << line);
    if (*end_ptr != '=') UTIL_THROW(FormatLoadException, "Expected = immediately following the first number in the count line " << line);
    ++end_ptr;
    number.push_back(ReadCount(end_ptr));
  }
}

void ReadNGramHeader(util::FilePiece &in, unsigned int length) {
   StringPiece line;
  while (IsEntirelyWhiteSpace(line = in.ReadLine())) {}
  std::stringstream expected;
  expected << '\\' << length << "-grams:";
  if (line != expected.str()) UTIL_THROW(FormatLoadException, "Was expecting n-gram header " << expected.str() << " but got " << line << " instead");
}

void ReadBackoff(util::FilePiece &in, Prob &/*weights*/) {
  switch (in.get()) {
    case '\t':
      {
        float got = in.ReadFloat();
        if (got != 0.0)
          UTIL_THROW(FormatLoadException, "Non-zero backoff " << got << " provided for an n-gram that should have no backoff");
      }
      break;
    case '\n':
      break;
    default:
      UTIL_THROW(FormatLoadException, "Expected tab or newline for backoff");
  }
}

void ReadBackoff(util::FilePiece &in, float &backoff) {
  // Always make zero negative.
  // Negative zero means that no (n+1)-gram has this n-gram as context.
  // Therefore the hypothesis state can be shorter.  Of course, many n-grams
  // are context for (n+1)-grams.  An algorithm in the data structure will go
  // back and set the backoff to positive zero in these cases.
  switch (in.get()) {
    case '\t':
      backoff = in.ReadFloat();
      if (backoff == ngram::kExtensionBackoff) backoff = ngram::kNoExtensionBackoff;
      {
#ifdef WIN32
		int float_class = _fpclass(backoff);
        UTIL_THROW_IF(float_class == _FPCLASS_SNAN || float_class == _FPCLASS_QNAN || float_class == _FPCLASS_NINF || float_class == _FPCLASS_PINF, FormatLoadException, "Bad backoff " << backoff);
#else
        int float_class = std::fpclassify(backoff);
        UTIL_THROW_IF(float_class == FP_NAN || float_class == FP_INFINITE, FormatLoadException, "Bad backoff " << backoff);
#endif
      }
      UTIL_THROW_IF(in.get() != '\n', FormatLoadException, "Expected newline after backoff");
      break;
    case '\n':
      backoff = ngram::kNoExtensionBackoff;
      break;
    default:
      UTIL_THROW(FormatLoadException, "Expected tab or newline for backoff");
  }
}

void ReadEnd(util::FilePiece &in) {
  StringPiece line;
  do {
    line = in.ReadLine();
  } while (IsEntirelyWhiteSpace(line));
  if (line != "\\end\\") UTIL_THROW(FormatLoadException, "Expected \\end\\ but the ARPA file has " << line);

  try {
    while (true) {
      line = in.ReadLine();
      if (!IsEntirelyWhiteSpace(line)) UTIL_THROW(FormatLoadException, "Trailing line " << line);
    }
  } catch (const util::EndOfFileException &e) {}
}

void PositiveProbWarn::Warn(float prob) {
  switch (action_) {
    case THROW_UP:
      UTIL_THROW(FormatLoadException, "Positive log probability " << prob << " in the model.  This is a bug in IRSTLM; you can set config.positive_log_probability = SILENT or pass -i to build_binary to substitute 0.0 for the log probability.  Error");
    case COMPLAIN:
      std::cerr << "There's a positive log probability " << prob << " in the APRA file, probably because of a bug in IRSTLM.  This and subsequent entires will be mapped to 0 log probability." << std::endl;
      action_ = SILENT;
      break;
    case SILENT:
      break;
  }
}

} // namespace lm
<commit_msg>Fix _fpclass build failure on MinGW.<commit_after>#include "lm/read_arpa.hh"

#include "lm/blank.hh"
#include "util/file.hh"

#include <cmath>
#include <cstdlib>
#include <iostream>
#include <sstream>
#include <vector>

#include <cctype>
#include <cstring>
#include <stdint.h>

#ifdef WIN32
#include <float.h>
#endif

namespace lm {

// 1 for '\t', '\n', and ' '.  This is stricter than isspace.
const bool kARPASpaces[256] = {0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

namespace {

bool IsEntirelyWhiteSpace(const StringPiece &line) {
  for (size_t i = 0; i < static_cast<size_t>(line.size()); ++i) {
    if (!isspace(line.data()[i])) return false;
  }
  return true;
}

const char kBinaryMagic[] = "mmap lm http://kheafield.com/code";

// strtoull isn't portable enough :-(
uint64_t ReadCount(const std::string &from) {
  std::stringstream stream(from);
  uint64_t ret;
  stream >> ret;
  UTIL_THROW_IF(!stream, FormatLoadException, "Bad count " << from);
  return ret;
}

} // namespace

void ReadARPACounts(util::FilePiece &in, std::vector<uint64_t> &number) {
  number.clear();
  StringPiece line = in.ReadLine();
  // In general, ARPA files can have arbitrary text before "\data\"
  // But in KenLM, we require such lines to start with "#", so that
  // we can do stricter error checking
  while (IsEntirelyWhiteSpace(line) || starts_with(line, "#")) {
    line = in.ReadLine();
  }

  if (line != "\\data\\") {
    if ((line.size() >= 2) && (line.data()[0] == 0x1f) && (static_cast<unsigned char>(line.data()[1]) == 0x8b)) {
      UTIL_THROW(FormatLoadException, "Looks like a gzip file.  If this is an ARPA file, pipe " << in.FileName() << " through zcat.  If this already in binary format, you need to decompress it because mmap doesn't work on top of gzip.");
    }
    if (static_cast<size_t>(line.size()) >= strlen(kBinaryMagic) && StringPiece(line.data(), strlen(kBinaryMagic)) == kBinaryMagic)
      UTIL_THROW(FormatLoadException, "This looks like a binary file but got sent to the ARPA parser.  Did you compress the binary file or pass a binary file where only ARPA files are accepted?");
    UTIL_THROW_IF(line.size() >= 4 && StringPiece(line.data(), 4) == "blmt", FormatLoadException, "This looks like an IRSTLM binary file.  Did you forget to pass --text yes to compile-lm?");
    UTIL_THROW_IF(line == "iARPA", FormatLoadException, "This looks like an IRSTLM iARPA file.  You need an ARPA file.  Run\n  compile-lm --text yes " << in.FileName() << " " << in.FileName() << ".arpa\nfirst.");
    UTIL_THROW(FormatLoadException, "first non-empty line was \"" << line << "\" not \\data\\.");
  }
  while (!IsEntirelyWhiteSpace(line = in.ReadLine())) {
    if (line.size() < 6 || strncmp(line.data(), "ngram ", 6)) UTIL_THROW(FormatLoadException, "count line \"" << line << "\"doesn't begin with \"ngram \"");
    // So strtol doesn't go off the end of line.
    std::string remaining(line.data() + 6, line.size() - 6);
    char *end_ptr;
    unsigned int length = std::strtol(remaining.c_str(), &end_ptr, 10);
    if ((end_ptr == remaining.c_str()) || (length - 1 != number.size())) UTIL_THROW(FormatLoadException, "ngram count lengths should be consecutive starting with 1: " << line);
    if (*end_ptr != '=') UTIL_THROW(FormatLoadException, "Expected = immediately following the first number in the count line " << line);
    ++end_ptr;
    number.push_back(ReadCount(end_ptr));
  }
}

void ReadNGramHeader(util::FilePiece &in, unsigned int length) {
   StringPiece line;
  while (IsEntirelyWhiteSpace(line = in.ReadLine())) {}
  std::stringstream expected;
  expected << '\\' << length << "-grams:";
  if (line != expected.str()) UTIL_THROW(FormatLoadException, "Was expecting n-gram header " << expected.str() << " but got " << line << " instead");
}

void ReadBackoff(util::FilePiece &in, Prob &/*weights*/) {
  switch (in.get()) {
    case '\t':
      {
        float got = in.ReadFloat();
        if (got != 0.0)
          UTIL_THROW(FormatLoadException, "Non-zero backoff " << got << " provided for an n-gram that should have no backoff");
      }
      break;
    case '\n':
      break;
    default:
      UTIL_THROW(FormatLoadException, "Expected tab or newline for backoff");
  }
}

void ReadBackoff(util::FilePiece &in, float &backoff) {
  // Always make zero negative.
  // Negative zero means that no (n+1)-gram has this n-gram as context.
  // Therefore the hypothesis state can be shorter.  Of course, many n-grams
  // are context for (n+1)-grams.  An algorithm in the data structure will go
  // back and set the backoff to positive zero in these cases.
  switch (in.get()) {
    case '\t':
      backoff = in.ReadFloat();
      if (backoff == ngram::kExtensionBackoff) backoff = ngram::kNoExtensionBackoff;
      {
#if defined(WIN32) && !defined(__MINGW32__)
		int float_class = _fpclass(backoff);
        UTIL_THROW_IF(float_class == _FPCLASS_SNAN || float_class == _FPCLASS_QNAN || float_class == _FPCLASS_NINF || float_class == _FPCLASS_PINF, FormatLoadException, "Bad backoff " << backoff);
#else
        int float_class = std::fpclassify(backoff);
        UTIL_THROW_IF(float_class == FP_NAN || float_class == FP_INFINITE, FormatLoadException, "Bad backoff " << backoff);
#endif
      }
      UTIL_THROW_IF(in.get() != '\n', FormatLoadException, "Expected newline after backoff");
      break;
    case '\n':
      backoff = ngram::kNoExtensionBackoff;
      break;
    default:
      UTIL_THROW(FormatLoadException, "Expected tab or newline for backoff");
  }
}

void ReadEnd(util::FilePiece &in) {
  StringPiece line;
  do {
    line = in.ReadLine();
  } while (IsEntirelyWhiteSpace(line));
  if (line != "\\end\\") UTIL_THROW(FormatLoadException, "Expected \\end\\ but the ARPA file has " << line);

  try {
    while (true) {
      line = in.ReadLine();
      if (!IsEntirelyWhiteSpace(line)) UTIL_THROW(FormatLoadException, "Trailing line " << line);
    }
  } catch (const util::EndOfFileException &e) {}
}

void PositiveProbWarn::Warn(float prob) {
  switch (action_) {
    case THROW_UP:
      UTIL_THROW(FormatLoadException, "Positive log probability " << prob << " in the model.  This is a bug in IRSTLM; you can set config.positive_log_probability = SILENT or pass -i to build_binary to substitute 0.0 for the log probability.  Error");
    case COMPLAIN:
      std::cerr << "There's a positive log probability " << prob << " in the APRA file, probably because of a bug in IRSTLM.  This and subsequent entires will be mapped to 0 log probability." << std::endl;
      action_ = SILENT;
      break;
    case SILENT:
      break;
  }
}

} // namespace lm
<|endoftext|>


<commit_before>
void GetSampleName( TString inputFile="") {

  string ret;
  ret = inputFile;

  //Drell Yan
  if (inputFile.Contains("DYJetsToLL_M-50_TuneZ2Star_8TeV-madgraph"))        ret = "ZJets"   ;
  if (inputFile.Contains("DYJetsToLL_HT-200To400_TuneZ2Star_8TeV-madgraph")) ret = "ZJets200";
  if (inputFile.Contains("DYJetsToLL_HT-400ToInf_TuneZ2Star_8TeV-madgraph")) ret = "ZJets400";
  //Pythia QCD - all LO PREP
  if (inputFile.Contains("QCD_Pt-1000to1400"))  ret = "QCD1000";
  if (inputFile.Contains("QCD_Pt-120to170"))    ret = "QCD120" ;
  if (inputFile.Contains("QCD_Pt-1400to1800"))  ret = "QCD1400";
  if (inputFile.Contains("QCD_Pt-170to300"))    ret = "QCD170" ;
  if (inputFile.Contains("QCD_Pt-1800"))        ret = "QCD1800";
  if (inputFile.Contains("QCD_Pt-300to470"))    ret = "QCD300" ;
  if (inputFile.Contains("QCD30"))              ret = "QCD30"  ;
  if (inputFile.Contains("QCD_Pt-470to600"))    ret = "QCD470" ;
  if (inputFile.Contains("QCD_Pt-600to800"))    ret = "QCD600" ;
  if (inputFile.Contains("QCD_Pt-800to1000"))   ret = "QCD800" ;
  if (inputFile.Contains("QCD80"))              ret = "QCD80"  ;
  //B-jets
  if (inputFile.Contains("BJets_HT-250To500_8TeV-madgraph"))  ret = "B250" ;
  if (inputFile.Contains("BJets_HT-500To1000_8TeV-madgraph")) ret = "B500" ;
  if (inputFile.Contains("BJets_HT-1000ToInf_8TeV-madgraph")) ret = "B1000";
  //single top
  if (inputFile.Contains("_tW-channel-DR_TuneZ2star_8TeV-powheg-tauola")) ret = "t_tW";
  if (inputFile.Contains("_t-channel-DR_TuneZ2star_8TeV-powheg-tauola"))  ret = "t_t" ;
  if (inputFile.Contains("_s-channel-DR_TuneZ2star_8TeV-powheg-tauola"))  ret = "t_s" ;
  if (inputFile.Contains("_tW-channel_TuneZ2star_8TeV-powheg-tauola")) ret = "t_tW";
  if (inputFile.Contains("_t-channel_TuneZ2star_8TeV-powheg-tauola"))  ret = "t_t" ;
  if (inputFile.Contains("_s-channel_TuneZ2star_8TeV-powheg-tauola"))  ret = "t_s" ;
  //W+Jets
  if (inputFile.Contains("WJetsToLNu_HT-400ToInf_8TeV-madgraph")) 			  ret = "WJets400";
  if (inputFile.Contains("WJetsToLNu_HT-250To300_8TeV-madgraph"))			  ret = "WJets250";
  if (inputFile.Contains("WJetsToLNu_HT-300To400_8TeV-madgraph")) 			  ret = "WJets300";
  if (inputFile.Contains("WJetsToLNu_TuneZ2Star_8TeV-madgraph")) 			  ret = "WJets"   ;
  if (inputFile.Contains("W2JetsToLNu_TuneZ2Star_8TeV-madgraph")) 			  ret = "W2Jets"  ;
  if (inputFile.Contains("W3JetsToLNu_TuneZ2Star_8TeV-madgraph")) 			  ret = "W3Jets"  ;
  if (inputFile.Contains("W4JetsToLNu_TuneZ2Star_8TeV-madgraph")) 			  ret = "W4Jets"  ;
  if (inputFile.Contains("WbbJetsToLNu_Massive_TuneZ2star_8TeV-madgraph-pythia6_tauola")) ret = "Wbb";
  //diboson
  if (inputFile.Contains("WZ_TuneZ2star_8TeV_pythia6_tauola")) ret = "WZ";
  if (inputFile.Contains("WW_TuneZ2star_8TeV_pythia6_tauola")) ret = "WW";
  if (inputFile.Contains("ZZ_TuneZ2star_8TeV_pythia6_tauola")) ret = "ZZ";
  //Z -> nu nu
  if (inputFile.Contains("ZJetsToNuNu_100_HT_200_TuneZ2Star_8TeV_madgraph")) ret = "Zinv100";
  if (inputFile.Contains("ZJetsToNuNu_200_HT_400_TuneZ2Star_8TeV_madgraph")) ret = "Zinv200";
  if (inputFile.Contains("ZJetsToNuNu_400_HT_inf_TuneZ2Star_8TeV_madgraph")) ret = "Zinv400";
  if (inputFile.Contains("ZJetsToNuNu_50_HT_100_TuneZ2Star_8TeV_madgraph"))  ret = "Zinv50" ;
  //LM
  if (inputFile.Contains("SUSY_LM9_sftsht_8TeV"))          ret = "LM9";
  //ttbar
  if (inputFile.Contains("TTJets") && inputFile.Contains("madgraph")) ret = "TTJetsMG"    ;
  if (inputFile.Contains("TTJets") && inputFile.Contains("sherpa"))   ret = "TTJetsSherpa";
  if (inputFile.Contains("TTJets") ) 				      ret = "TTJets"      ;
  if (inputFile.Contains("TT") && inputFile.Contains("mcatnlo"))      ret = "TTJets"      ;
  if (inputFile.Contains("TT") && inputFile.Contains("powheg"))       ret = "TTJets"      ;
  //
  if (inputFile.Contains("WH_WToLNu_HToBB_M-125_8TeV-powheg-herwigpp")) ret = "WH";
  if (inputFile.Contains("ZH_ZToBB_HToBB_M-125_8TeV-powheg-herwigpp"))  ret = "ZH";
  if (inputFile.Contains("TTH_HToBB_M-125_8TeV-pythia6")) ret = "TTH";
  if (inputFile.Contains("TTZJets_8TeV-madgraph_v2"))     ret = "TTZ";
  if (inputFile.Contains("TTWJets_8TeV-madgraph"))        ret = "TTW";
  //SMS
  if (inputFile.Contains("MadGraph_T1bbbb"))  ret = "T1bbbbMG";
  if (inputFile.Contains("MadGraph_T1tttt"))  ret = "T1ttttMG";
  if (inputFile.Contains("T1bbbb"))           ret = "T1bbbb"  ;
  if (inputFile.Contains("T1tttt"))           ret = "T1tttt"  ;
  if (inputFile.Contains("T2tt"))             ret = "T2tt"    ;
  if (inputFile.Contains("T2bb"))             ret = "T2bb"    ;
  if (inputFile.Contains("T5tttt"))           ret = "T5tttt"  ;
  if (inputFile.Contains("T1t1t"))            ret = "T1t1t"   ;
  if (inputFile.Contains("T1ttcc"))           ret = "T1ttcc"  ;
  if (inputFile.Contains("T7btw"))            ret = "T7btw"   ;
  if (inputFile.Contains("TChiZH"))           ret = "TChiZH"  ;
  if (inputFile.Contains("TChiHH"))           ret = "TChiHH"  ;
  if (inputFile.Contains("T6bbHH"))           ret = "T6bbHH"  ;
  if (inputFile.Contains("T6ttHH"))           ret = "T6ttHH"  ;
  if (inputFile.Contains("T5Wh"))             ret = "T5Wh"    ;
  //pMSSM
  if (inputFile.Contains("pMSSM")) {
    if ( inputFile.Contains("batch1") )     ret = "pMSSM_b1";
    if ( inputFile.Contains("batch2") )     ret = "pMSSM_b2";
    if ( inputFile.Contains("batch3") )     ret = "pMSSM_b3";
    if ( inputFile.Contains("batch4") )     ret = "pMSSM_b4";
  }
  if (inputFile.Contains("HbbHbb") ) ret = "hbbhbb";
  if (inputFile.Contains("TChihh") ) ret = "TChihh";
  //Otherwise not found--be careful..

  cout << ret << endl;
  return;
}
<commit_msg>add sample names<commit_after>
void GetSampleName( TString inputFile="") {

  string ret;
  ret = inputFile;

  //Drell Yan
  if (inputFile.Contains("DYJetsToLL_M-50_TuneZ2Star_8TeV-madgraph"))        ret = "ZJets"   ;
  if (inputFile.Contains("DYJetsToLL_HT-200To400_TuneZ2Star_8TeV-madgraph")) ret = "ZJets200";
  if (inputFile.Contains("DYJetsToLL_HT-400ToInf_TuneZ2Star_8TeV-madgraph")) ret = "ZJets400";
  //Pythia QCD - all LO PREP
  if (inputFile.Contains("QCD_Pt-1000to1400"))  ret = "QCD1000";
  if (inputFile.Contains("QCD_Pt-120to170"))    ret = "QCD120" ;
  if (inputFile.Contains("QCD_Pt-1400to1800"))  ret = "QCD1400";
  if (inputFile.Contains("QCD_Pt-170to300"))    ret = "QCD170" ;
  if (inputFile.Contains("QCD_Pt-1800"))        ret = "QCD1800";
  if (inputFile.Contains("QCD_Pt-300to470"))    ret = "QCD300" ;
  if (inputFile.Contains("QCD30"))              ret = "QCD30"  ;
  if (inputFile.Contains("QCD_Pt-470to600"))    ret = "QCD470" ;
  if (inputFile.Contains("QCD_Pt-600to800"))    ret = "QCD600" ;
  if (inputFile.Contains("QCD_Pt-800to1000"))   ret = "QCD800" ;
  if (inputFile.Contains("QCD80"))              ret = "QCD80"  ;
  //B-jets
  if (inputFile.Contains("BJets_HT-250To500_8TeV-madgraph"))  ret = "B250" ;
  if (inputFile.Contains("BJets_HT-500To1000_8TeV-madgraph")) ret = "B500" ;
  if (inputFile.Contains("BJets_HT-1000ToInf_8TeV-madgraph")) ret = "B1000";
  //single top
  if (inputFile.Contains("_tW-channel-DR_TuneZ2star_8TeV-powheg-tauola")) ret = "t_tW";
  if (inputFile.Contains("_t-channel-DR_TuneZ2star_8TeV-powheg-tauola"))  ret = "t_t" ;
  if (inputFile.Contains("_s-channel-DR_TuneZ2star_8TeV-powheg-tauola"))  ret = "t_s" ;
  if (inputFile.Contains("_tW-channel_TuneZ2star_8TeV-powheg-tauola")) ret = "t_tW";
  if (inputFile.Contains("_t-channel_TuneZ2star_8TeV-powheg-tauola"))  ret = "t_t" ;
  if (inputFile.Contains("_s-channel_TuneZ2star_8TeV-powheg-tauola"))  ret = "t_s" ;
  //W+Jets
  if (inputFile.Contains("WJetsToLNu_HT-400ToInf_8TeV-madgraph")) 			  ret = "WJets400";
  if (inputFile.Contains("WJetsToLNu_HT-250To300_8TeV-madgraph"))			  ret = "WJets250";
  if (inputFile.Contains("WJetsToLNu_HT-300To400_8TeV-madgraph")) 			  ret = "WJets300";
  if (inputFile.Contains("WJetsToLNu_TuneZ2Star_8TeV-madgraph")) 			  ret = "WJets"   ;
  if (inputFile.Contains("W2JetsToLNu_TuneZ2Star_8TeV-madgraph")) 			  ret = "W2Jets"  ;
  if (inputFile.Contains("W3JetsToLNu_TuneZ2Star_8TeV-madgraph")) 			  ret = "W3Jets"  ;
  if (inputFile.Contains("W4JetsToLNu_TuneZ2Star_8TeV-madgraph")) 			  ret = "W4Jets"  ;
  if (inputFile.Contains("WbbJetsToLNu_Massive_TuneZ2star_8TeV-madgraph-pythia6_tauola")) ret = "Wbb";
  //diboson
  if (inputFile.Contains("WZ_TuneZ2star_8TeV_pythia6_tauola")) ret = "WZ";
  if (inputFile.Contains("WW_TuneZ2star_8TeV_pythia6_tauola")) ret = "WW";
  if (inputFile.Contains("ZZ_TuneZ2star_8TeV_pythia6_tauola")) ret = "ZZ";
  //Z -> nu nu
  if (inputFile.Contains("ZJetsToNuNu_100_HT_200_TuneZ2Star_8TeV_madgraph")) ret = "Zinv100";
  if (inputFile.Contains("ZJetsToNuNu_200_HT_400_TuneZ2Star_8TeV_madgraph")) ret = "Zinv200";
  if (inputFile.Contains("ZJetsToNuNu_400_HT_inf_TuneZ2Star_8TeV_madgraph")) ret = "Zinv400";
  if (inputFile.Contains("ZJetsToNuNu_50_HT_100_TuneZ2Star_8TeV_madgraph"))  ret = "Zinv50" ;
  //LM
  if (inputFile.Contains("SUSY_LM9_sftsht_8TeV"))          ret = "LM9";
  //ttbar
  if (inputFile.Contains("TTJets") && inputFile.Contains("madgraph")) ret = "TTJetsMG"    ;
  if (inputFile.Contains("TTJets") && inputFile.Contains("sherpa"))   ret = "TTJetsSherpa";
  if (inputFile.Contains("TTJets") ) 				      ret = "TTJets"      ;
  if (inputFile.Contains("TT") && inputFile.Contains("mcatnlo"))      ret = "TTJets"      ;
  if (inputFile.Contains("TT") && inputFile.Contains("powheg"))       ret = "TTJets"      ;
  //
  if (inputFile.Contains("WH_WToLNu_HToBB_M-125_8TeV-powheg-herwigpp")) ret = "WH";
  if (inputFile.Contains("ZH_ZToBB_HToBB_M-125_8TeV-powheg-herwigpp"))  ret = "ZH";
  if (inputFile.Contains("TTH_HToBB_M-125_8TeV-pythia6")) ret = "TTH";
  if (inputFile.Contains("TTZJets_8TeV-madgraph_v2"))     ret = "TTZ";
  if (inputFile.Contains("TTWJets_8TeV-madgraph"))        ret = "TTW";
  //SMS
  if (inputFile.Contains("MadGraph_T1bbbb"))  ret = "T1bbbbMG";
  if (inputFile.Contains("MadGraph_T1tttt"))  ret = "T1ttttMG";
  if (inputFile.Contains("T1bbbb"))           ret = "T1bbbb"  ;
  if (inputFile.Contains("T1tttt"))           ret = "T1tttt"  ;
  if (inputFile.Contains("T2tt"))             ret = "T2tt"    ;
  if (inputFile.Contains("T2bb"))             ret = "T2bb"    ;
  if (inputFile.Contains("T5tttt"))           ret = "T5tttt"  ;
  if (inputFile.Contains("T1t1t"))            ret = "T1t1t"   ;
  if (inputFile.Contains("T1ttcc"))           ret = "T1ttcc"  ;
  if (inputFile.Contains("T7btw"))            ret = "T7btw"   ;
  if (inputFile.Contains("TChiZH"))           ret = "TChiZH"  ;
  if (inputFile.Contains("TChiHH"))           ret = "TChiHH"  ;
  if (inputFile.Contains("T6bbHH"))           ret = "T6bbHH"  ;
  if (inputFile.Contains("T6ttHH"))           ret = "T6ttHH"  ;
  if (inputFile.Contains("T5Wh"))             ret = "T5Wh"    ;
  if (inputFile.Contains("T1tbbb"))           ret = "T1tbbb"  ;
  if (inputFile.Contains("T1tttb"))           ret = "T1tttb"  ;
  if (inputFile.Contains("T2tb"))             ret = "T2tb"    ;
  //pMSSM
  if (inputFile.Contains("pMSSM")) {
    if ( inputFile.Contains("batch1") )     ret = "pMSSM_b1";
    if ( inputFile.Contains("batch2") )     ret = "pMSSM_b2";
    if ( inputFile.Contains("batch3") )     ret = "pMSSM_b3";
    if ( inputFile.Contains("batch4") )     ret = "pMSSM_b4";
  }
  if (inputFile.Contains("HbbHbb") ) ret = "hbbhbb";
  if (inputFile.Contains("TChihh") ) ret = "TChihh";
  //Otherwise not found--be careful..

  cout << ret << endl;
  return;
}
<|endoftext|>


<commit_before>/*M///////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2015, Youssef Kashef
// Copyright (c) 2015, ELM Library Project
// 3-clause BSD License
//
//M*/
#include "elm/core/graph/graphmap.h"

#include "gtest/gtest.h"

#include <opencv2/core/core.hpp>

#include "elm/core/debug_utils.h"
#include "elm/core/exception.h"
#include "elm/core/cv/mat_utils_inl.h"
#include "elm/ts/ts.h"

using namespace cv;
using namespace elm;

namespace {

class GraphMapConstructTest : public ::testing::Test
{
protected:
};

TEST_F(GraphMapConstructTest, Destruct)
{
    GraphMap *to = new GraphMap();
    EXPECT_NO_THROW(delete to);
}

TEST_F(GraphMapConstructTest, EmptyMap)
{
    Mat1f x;
    GraphMap to(x, Mat());
    EXPECT_EQ(static_cast<size_t>(0), to.num_vertices());
}

TEST_F(GraphMapConstructTest, SingleElementMap)
{
    Mat1i x(1, 1, 0);
    EXPECT_THROW(GraphMap to(x, Mat()), ExceptionBadDims);
    EXPECT_THROW(GraphMap to(x+1, Mat()), ExceptionBadDims);
}

TEST_F(GraphMapConstructTest, Max_num_vertices)
{
    for(int n=2; n<11; n++) {

        Mat1i m(n, n);
        for(size_t i=0; i<m.total(); i++) {

            m(i) = i;
        }

        GraphMap to(m, Mat());
        EXPECT_EQ(static_cast<size_t>(n*n), to.num_vertices());
        EXPECT_EQ(m.total(), to.num_vertices());
    }
}

TEST_F(GraphMapConstructTest, AdjacencyDense_dims_all_unique)
{
    for(int n=2; n<11; n++) {

        Mat1i m(n, n);
        for(size_t i=0; i<m.total(); i++) {

            m(i) = i;
        }

        GraphMap to(m, Mat());
        EXPECT_EQ(static_cast<size_t>(n*n), to.num_vertices());
        EXPECT_EQ(m.total(), to.num_vertices());

        Mat1f adj;
        to.AdjacencyMat(adj);
        EXPECT_MAT_DIMS_EQ(adj, Size2i(m.total(), m.total()));
    }
}

/**
 * @brief Test adjacency matrix from graph constructed from
 * map initialized as row matrix.
 *
 * We expect:
 * connections to preceeding and succeeding elements
 */
TEST_F(GraphMapConstructTest, AdjacencyDense_row_mat)
{
    Mat1i m(1, 5);
    for(size_t i=0; i<m.total(); i++) {

        m(i) = i;
    }

    GraphMap to(m, Mat());
    EXPECT_EQ(m.total(), to.num_vertices());

    Mat1f adj;
    to.AdjacencyMat(adj);
    EXPECT_MAT_EQ(adj, adj.t()) << "Expecting adj. matrix symmetric around diagonal";

    // verify we have no self-connections
    for(int r=0; r<adj.rows; r++) {
        EXPECT_EQ(0.f, adj(r, r)) << "Unexpected self-connection.";
    }

    // verify that each vertex is only connected to left and right neighbors
    for(int r=0; r<adj.rows; r++) {

        if(r>0 && r<adj.rows-1) {

            EXPECT_FLOAT_EQ(2.f, cv::sum(adj.row(r))[0]) << "Only expecting edges with left and right neighbor";
            EXPECT_FLOAT_EQ(2.f, cv::sum(adj.col(r))[0]) << "Only expecting edges with left and right neighbor";

            // identify neighbors
            EXPECT_FLOAT_EQ(1.f, adj(r-1, r)) << "Missing connection to preceeding neighbor";
            EXPECT_FLOAT_EQ(1.f, adj(r+1, r)) << "Missing connection to succeeding neighbor";
        }
        else {
            // border elements
            EXPECT_FLOAT_EQ(1.f, cv::sum(adj.row(r))[0]) << "Only expecting edges with one neighbor";
            EXPECT_FLOAT_EQ(1.f, cv::sum(adj.col(r))[0]) << "Only expecting edges with one neighbor";

            if(r==0) {
                // first vertex
                EXPECT_FLOAT_EQ(1.f, adj(1)) << "Missing connection to succeeding element";
            }
            else {
                // last vertex
                EXPECT_FLOAT_EQ(1.f, adj(adj.total()-2)) << "Missing connection to preceeding element";
            }
        }
    }
}

TEST_F(GraphMapConstructTest, AdjacencyDense)
{
    const int ROWS=2;
    const int COLS=3;
    int data[ROWS*COLS] = {1, 1, 2,
                           3, 6, 6};
    Mat1i m = Mat1i(ROWS, COLS, data).clone();

    GraphMap to(m, Mat());
    const int nb_vertices = static_cast<int>(to.num_vertices());
    EXPECT_EQ(4, nb_vertices);

    Mat1f adj;
    to.AdjacencyMat(adj);
    EXPECT_MAT_DIMS_EQ(adj, Size2i(nb_vertices, nb_vertices));
    EXPECT_MAT_EQ(adj, adj.t()) << "Expecting adj. matrix symmetric around diagonal";

    // verify we have no self-connections
    for(int r=0; r<adj.rows; r++) {
        EXPECT_EQ(0.f, adj(r, r)) << "Unexpected self-connection.";
    }

    // verify individual connections
    EXPECT_FLOAT_EQ(1.f, adj(0, 1));
    EXPECT_FLOAT_EQ(1.f, adj(0, 2));
    EXPECT_FLOAT_EQ(1.f, adj(0, 3));
    EXPECT_FLOAT_EQ(1.f, adj(1, 3));
    EXPECT_FLOAT_EQ(1.f, adj(2, 3));
    EXPECT_FLOAT_EQ(0.f, adj(1, 2));

    // verify vertices vector
    VecF vtx_ids = to.VerticesIds();
    EXPECT_SIZE(nb_vertices, vtx_ids);

    // verify vertex ids and their order
    EXPECT_FLOAT_EQ(1.f, vtx_ids[0]);
    EXPECT_FLOAT_EQ(3.f, vtx_ids[1]);
    EXPECT_FLOAT_EQ(2.f, vtx_ids[2]);
    EXPECT_FLOAT_EQ(6.f, vtx_ids[3]);
}

TEST_F(GraphMapConstructTest, VerticesIds_size)
{
    for(int n=2; n<11; n++) {

        Mat1i m(n, n);
        for(size_t i=0; i<m.total(); i++) {

            m(i) = i;
        }

        GraphMap to(m, Mat());
        EXPECT_EQ(static_cast<size_t>(n*n), to.num_vertices());
        EXPECT_EQ(m.total(), to.num_vertices());
        EXPECT_SIZE(n*n, to.VerticesIds());
        EXPECT_SIZE(m.total(), to.VerticesIds());
    }
}

/**
 * @brief verify vertex ids reflect order in adjacency matrix
 */
TEST_F(GraphMapConstructTest, VerticesIds)
{
    const int ROWS=3;
    const int COLS=3;
    int data[ROWS*COLS] = {1, 1, 2,
                           3, 6, 6,
                           9, 9, 11};
    Mat1i m = Mat1i(ROWS, COLS, data).clone();

    ELM_COUT_VAR(m);

    GraphMap to(m, Mat());
    const int nb_vertices = static_cast<int>(to.num_vertices());
    EXPECT_EQ(6, nb_vertices);

    Mat1f adj;
    to.AdjacencyMat(adj);

    ELM_COUT_VAR(adj);

    EXPECT_MAT_DIMS_EQ(adj, Size2i(nb_vertices, nb_vertices));
    EXPECT_MAT_EQ(adj, adj.t()) << "Expecting adj. matrix symmetric around diagonal";

    // verify we have no self-connections
    for(int r=0; r<adj.rows; r++) {
        EXPECT_EQ(0.f, adj(r, r)) << "Unexpected self-connection.";
    }

    // verify vertices vector
    VecF vtx_ids = to.VerticesIds();
    EXPECT_SIZE(nb_vertices, vtx_ids);

    // verify vertex ids and their order
    EXPECT_FLOAT_EQ(1.f, vtx_ids[0]);
    EXPECT_FLOAT_EQ(3.f, vtx_ids[1]);
    EXPECT_FLOAT_EQ(2.f, vtx_ids[2]);
    EXPECT_FLOAT_EQ(6.f, vtx_ids[3]);

    // verify individual connections
    EXPECT_FLOAT_EQ(1.f, adj(0, 1));
    EXPECT_FLOAT_EQ(1.f, adj(0, 2));
    EXPECT_FLOAT_EQ(1.f, adj(0, 3));
    EXPECT_FLOAT_EQ(1.f, adj(1, 3));
    EXPECT_FLOAT_EQ(1.f, adj(2, 3));
    EXPECT_FLOAT_EQ(0.f, adj(1, 2));

    EXPECT_FLOAT_EQ(3.f, cv::sum(adj.row(4))[0]);
    EXPECT_FLOAT_EQ(1.f, adj(1, 4));
    EXPECT_FLOAT_EQ(1.f, adj(3, 4));
    EXPECT_FLOAT_EQ(1.f, adj(5, 4));

    EXPECT_FLOAT_EQ(2.f, cv::sum(adj.row(5))[0]);
    EXPECT_FLOAT_EQ(1.f, adj(3, 5));
    EXPECT_FLOAT_EQ(1.f, adj(4, 5));
}

TEST_F(GraphMapConstructTest, Mask)
{
    const int ROWS=2;
    const int COLS=3;
    int data[ROWS*COLS] = {1, 1, 2,
                           3, 6, 6};
    Mat1i m = Mat1i(ROWS, COLS, data).clone();

    {
        Mat mask;
        EXPECT_NO_THROW(GraphMap to(m, mask));
    }
    {
        Mat mask = m >= 0; // all true
        EXPECT_NO_THROW(GraphMap to(m, mask));
    }
    {
        Mat mask = m < 0; // all false
        EXPECT_NO_THROW(GraphMap to(m, mask));
    }
    {
        Mat mask = m.t() < 0; // all false
        EXPECT_THROW(GraphMap to(m, mask), ExceptionBadDims);
    }
    {
        Mat mask = m.t() >= 0; // all true
        EXPECT_THROW(GraphMap to(m, mask), ExceptionBadDims);
    }
    {
        Mat1b mask(1, 1);
        EXPECT_THROW(GraphMap to(m, mask), ExceptionBadDims);
    }
    {
        Mat1b mask(ROWS/2, COLS);
        EXPECT_THROW(GraphMap to(m, mask), ExceptionBadDims);
    }
    {
        Mat1b mask(ROWS/2, COLS, true);
        EXPECT_THROW(GraphMap to(m, mask), ExceptionBadDims);
    }
    {
        Mat1b mask(ROWS, COLS/2);
        EXPECT_THROW(GraphMap to(m, mask), ExceptionBadDims);
    }
    {
        Mat1b mask(ROWS, COLS/2, true);
        EXPECT_THROW(GraphMap to(m, mask), ExceptionBadDims);
    }
}

TEST_F(GraphMapConstructTest, VerticesIds_masked)
{
    const int ROWS=3;
    const int COLS=3;
    int data[ROWS*COLS] = {1, 1, 2,
                           3, 6, 6,
                           9, 9, 11};
    Mat1i m = Mat1i(ROWS, COLS, data).clone();

    Mat exclude, mask;
    cv::bitwise_or(m < 2, m == 9, exclude);
    cv::bitwise_not(exclude, mask);

    GraphMap to(m, mask);
    const int nb_vertices = static_cast<int>(to.num_vertices());
    EXPECT_EQ(4, nb_vertices);

    Mat1f adj;
    to.AdjacencyMat(adj);

    EXPECT_MAT_DIMS_EQ(adj, Size2i(nb_vertices, nb_vertices));
    EXPECT_MAT_EQ(adj, adj.t()) << "Expecting adj. matrix symmetric around diagonal";

    // verify we have no self-connections
    for(int r=0; r<adj.rows; r++) {
        EXPECT_EQ(0.f, adj(r, r)) << "Unexpected self-connection.";
    }

    // verify vertices vector
    VecF vtx_ids = to.VerticesIds();
    EXPECT_SIZE(nb_vertices, vtx_ids);

    // verify vertex ids and their order
    EXPECT_FLOAT_EQ(2, vtx_ids[0]);
    EXPECT_FLOAT_EQ(6, vtx_ids[1]);
    EXPECT_FLOAT_EQ(3, vtx_ids[2]);
    EXPECT_FLOAT_EQ(11, vtx_ids[3]);

    // verify individual connections

    EXPECT_FLOAT_EQ(1.f, cv::sum(adj.row(0))[0]);
    EXPECT_FLOAT_EQ(1.f, adj(2, 1));

    EXPECT_FLOAT_EQ(3.f, cv::sum(adj.row(1))[0]);
    EXPECT_FLOAT_EQ(1.f, adj(0, 1));
    EXPECT_FLOAT_EQ(1.f, adj(2, 1));
    EXPECT_FLOAT_EQ(1.f, adj(3, 1));

    EXPECT_FLOAT_EQ(1.f, cv::sum(adj.row(2))[0]);
    EXPECT_FLOAT_EQ(1.f, adj(1, 2));

    EXPECT_FLOAT_EQ(1.f, cv::sum(adj.row(3))[0]);
    EXPECT_FLOAT_EQ(1.f, adj(1, 3));
}

} // annonymous namespace for test cases and fixtures
<commit_msg>remove some more debug messages from tests<commit_after>/*M///////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2015, Youssef Kashef
// Copyright (c) 2015, ELM Library Project
// 3-clause BSD License
//
//M*/
#include "elm/core/graph/graphmap.h"

#include "gtest/gtest.h"

#include <opencv2/core/core.hpp>

#include "elm/core/debug_utils.h"
#include "elm/core/exception.h"
#include "elm/core/cv/mat_utils_inl.h"
#include "elm/ts/ts.h"

using namespace cv;
using namespace elm;

namespace {

class GraphMapConstructTest : public ::testing::Test
{
protected:
};

TEST_F(GraphMapConstructTest, Destruct)
{
    GraphMap *to = new GraphMap();
    EXPECT_NO_THROW(delete to);
}

TEST_F(GraphMapConstructTest, EmptyMap)
{
    Mat1f x;
    GraphMap to(x, Mat());
    EXPECT_EQ(static_cast<size_t>(0), to.num_vertices());
}

TEST_F(GraphMapConstructTest, SingleElementMap)
{
    Mat1i x(1, 1, 0);
    EXPECT_THROW(GraphMap to(x, Mat()), ExceptionBadDims);
    EXPECT_THROW(GraphMap to(x+1, Mat()), ExceptionBadDims);
}

TEST_F(GraphMapConstructTest, Max_num_vertices)
{
    for(int n=2; n<11; n++) {

        Mat1i m(n, n);
        for(size_t i=0; i<m.total(); i++) {

            m(i) = i;
        }

        GraphMap to(m, Mat());
        EXPECT_EQ(static_cast<size_t>(n*n), to.num_vertices());
        EXPECT_EQ(m.total(), to.num_vertices());
    }
}

TEST_F(GraphMapConstructTest, AdjacencyDense_dims_all_unique)
{
    for(int n=2; n<11; n++) {

        Mat1i m(n, n);
        for(size_t i=0; i<m.total(); i++) {

            m(i) = i;
        }

        GraphMap to(m, Mat());
        EXPECT_EQ(static_cast<size_t>(n*n), to.num_vertices());
        EXPECT_EQ(m.total(), to.num_vertices());

        Mat1f adj;
        to.AdjacencyMat(adj);
        EXPECT_MAT_DIMS_EQ(adj, Size2i(m.total(), m.total()));
    }
}

/**
 * @brief Test adjacency matrix from graph constructed from
 * map initialized as row matrix.
 *
 * We expect:
 * connections to preceeding and succeeding elements
 */
TEST_F(GraphMapConstructTest, AdjacencyDense_row_mat)
{
    Mat1i m(1, 5);
    for(size_t i=0; i<m.total(); i++) {

        m(i) = i;
    }

    GraphMap to(m, Mat());
    EXPECT_EQ(m.total(), to.num_vertices());

    Mat1f adj;
    to.AdjacencyMat(adj);
    EXPECT_MAT_EQ(adj, adj.t()) << "Expecting adj. matrix symmetric around diagonal";

    // verify we have no self-connections
    for(int r=0; r<adj.rows; r++) {
        EXPECT_EQ(0.f, adj(r, r)) << "Unexpected self-connection.";
    }

    // verify that each vertex is only connected to left and right neighbors
    for(int r=0; r<adj.rows; r++) {

        if(r>0 && r<adj.rows-1) {

            EXPECT_FLOAT_EQ(2.f, cv::sum(adj.row(r))[0]) << "Only expecting edges with left and right neighbor";
            EXPECT_FLOAT_EQ(2.f, cv::sum(adj.col(r))[0]) << "Only expecting edges with left and right neighbor";

            // identify neighbors
            EXPECT_FLOAT_EQ(1.f, adj(r-1, r)) << "Missing connection to preceeding neighbor";
            EXPECT_FLOAT_EQ(1.f, adj(r+1, r)) << "Missing connection to succeeding neighbor";
        }
        else {
            // border elements
            EXPECT_FLOAT_EQ(1.f, cv::sum(adj.row(r))[0]) << "Only expecting edges with one neighbor";
            EXPECT_FLOAT_EQ(1.f, cv::sum(adj.col(r))[0]) << "Only expecting edges with one neighbor";

            if(r==0) {
                // first vertex
                EXPECT_FLOAT_EQ(1.f, adj(1)) << "Missing connection to succeeding element";
            }
            else {
                // last vertex
                EXPECT_FLOAT_EQ(1.f, adj(adj.total()-2)) << "Missing connection to preceeding element";
            }
        }
    }
}

TEST_F(GraphMapConstructTest, AdjacencyDense)
{
    const int ROWS=2;
    const int COLS=3;
    int data[ROWS*COLS] = {1, 1, 2,
                           3, 6, 6};
    Mat1i m = Mat1i(ROWS, COLS, data).clone();

    GraphMap to(m, Mat());
    const int nb_vertices = static_cast<int>(to.num_vertices());
    EXPECT_EQ(4, nb_vertices);

    Mat1f adj;
    to.AdjacencyMat(adj);
    EXPECT_MAT_DIMS_EQ(adj, Size2i(nb_vertices, nb_vertices));
    EXPECT_MAT_EQ(adj, adj.t()) << "Expecting adj. matrix symmetric around diagonal";

    // verify we have no self-connections
    for(int r=0; r<adj.rows; r++) {
        EXPECT_EQ(0.f, adj(r, r)) << "Unexpected self-connection.";
    }

    // verify individual connections
    EXPECT_FLOAT_EQ(1.f, adj(0, 1));
    EXPECT_FLOAT_EQ(1.f, adj(0, 2));
    EXPECT_FLOAT_EQ(1.f, adj(0, 3));
    EXPECT_FLOAT_EQ(1.f, adj(1, 3));
    EXPECT_FLOAT_EQ(1.f, adj(2, 3));
    EXPECT_FLOAT_EQ(0.f, adj(1, 2));

    // verify vertices vector
    VecF vtx_ids = to.VerticesIds();
    EXPECT_SIZE(nb_vertices, vtx_ids);

    // verify vertex ids and their order
    EXPECT_FLOAT_EQ(1.f, vtx_ids[0]);
    EXPECT_FLOAT_EQ(3.f, vtx_ids[1]);
    EXPECT_FLOAT_EQ(2.f, vtx_ids[2]);
    EXPECT_FLOAT_EQ(6.f, vtx_ids[3]);
}

TEST_F(GraphMapConstructTest, VerticesIds_size)
{
    for(int n=2; n<11; n++) {

        Mat1i m(n, n);
        for(size_t i=0; i<m.total(); i++) {

            m(i) = i;
        }

        GraphMap to(m, Mat());
        EXPECT_EQ(static_cast<size_t>(n*n), to.num_vertices());
        EXPECT_EQ(m.total(), to.num_vertices());
        EXPECT_SIZE(n*n, to.VerticesIds());
        EXPECT_SIZE(m.total(), to.VerticesIds());
    }
}

/**
 * @brief verify vertex ids reflect order in adjacency matrix
 */
TEST_F(GraphMapConstructTest, VerticesIds)
{
    const int ROWS=3;
    const int COLS=3;
    int data[ROWS*COLS] = {1, 1, 2,
                           3, 6, 6,
                           9, 9, 11};
    Mat1i m = Mat1i(ROWS, COLS, data).clone();

    GraphMap to(m, Mat());
    const int nb_vertices = static_cast<int>(to.num_vertices());
    EXPECT_EQ(6, nb_vertices);

    Mat1f adj;
    to.AdjacencyMat(adj);

    EXPECT_MAT_DIMS_EQ(adj, Size2i(nb_vertices, nb_vertices));
    EXPECT_MAT_EQ(adj, adj.t()) << "Expecting adj. matrix symmetric around diagonal";

    // verify we have no self-connections
    for(int r=0; r<adj.rows; r++) {
        EXPECT_EQ(0.f, adj(r, r)) << "Unexpected self-connection.";
    }

    // verify vertices vector
    VecF vtx_ids = to.VerticesIds();
    EXPECT_SIZE(nb_vertices, vtx_ids);

    // verify vertex ids and their order
    EXPECT_FLOAT_EQ(1.f, vtx_ids[0]);
    EXPECT_FLOAT_EQ(3.f, vtx_ids[1]);
    EXPECT_FLOAT_EQ(2.f, vtx_ids[2]);
    EXPECT_FLOAT_EQ(6.f, vtx_ids[3]);

    // verify individual connections
    EXPECT_FLOAT_EQ(1.f, adj(0, 1));
    EXPECT_FLOAT_EQ(1.f, adj(0, 2));
    EXPECT_FLOAT_EQ(1.f, adj(0, 3));
    EXPECT_FLOAT_EQ(1.f, adj(1, 3));
    EXPECT_FLOAT_EQ(1.f, adj(2, 3));
    EXPECT_FLOAT_EQ(0.f, adj(1, 2));

    EXPECT_FLOAT_EQ(3.f, cv::sum(adj.row(4))[0]);
    EXPECT_FLOAT_EQ(1.f, adj(1, 4));
    EXPECT_FLOAT_EQ(1.f, adj(3, 4));
    EXPECT_FLOAT_EQ(1.f, adj(5, 4));

    EXPECT_FLOAT_EQ(2.f, cv::sum(adj.row(5))[0]);
    EXPECT_FLOAT_EQ(1.f, adj(3, 5));
    EXPECT_FLOAT_EQ(1.f, adj(4, 5));
}

TEST_F(GraphMapConstructTest, Mask)
{
    const int ROWS=2;
    const int COLS=3;
    int data[ROWS*COLS] = {1, 1, 2,
                           3, 6, 6};
    Mat1i m = Mat1i(ROWS, COLS, data).clone();

    {
        Mat mask;
        EXPECT_NO_THROW(GraphMap to(m, mask));
    }
    {
        Mat mask = m >= 0; // all true
        EXPECT_NO_THROW(GraphMap to(m, mask));
    }
    {
        Mat mask = m < 0; // all false
        EXPECT_NO_THROW(GraphMap to(m, mask));
    }
    {
        Mat mask = m.t() < 0; // all false
        EXPECT_THROW(GraphMap to(m, mask), ExceptionBadDims);
    }
    {
        Mat mask = m.t() >= 0; // all true
        EXPECT_THROW(GraphMap to(m, mask), ExceptionBadDims);
    }
    {
        Mat1b mask(1, 1);
        EXPECT_THROW(GraphMap to(m, mask), ExceptionBadDims);
    }
    {
        Mat1b mask(ROWS/2, COLS);
        EXPECT_THROW(GraphMap to(m, mask), ExceptionBadDims);
    }
    {
        Mat1b mask(ROWS/2, COLS, true);
        EXPECT_THROW(GraphMap to(m, mask), ExceptionBadDims);
    }
    {
        Mat1b mask(ROWS, COLS/2);
        EXPECT_THROW(GraphMap to(m, mask), ExceptionBadDims);
    }
    {
        Mat1b mask(ROWS, COLS/2, true);
        EXPECT_THROW(GraphMap to(m, mask), ExceptionBadDims);
    }
}

TEST_F(GraphMapConstructTest, VerticesIds_masked)
{
    const int ROWS=3;
    const int COLS=3;
    int data[ROWS*COLS] = {1, 1, 2,
                           3, 6, 6,
                           9, 9, 11};
    Mat1i m = Mat1i(ROWS, COLS, data).clone();

    Mat exclude, mask;
    cv::bitwise_or(m < 2, m == 9, exclude);
    cv::bitwise_not(exclude, mask);

    GraphMap to(m, mask);
    const int nb_vertices = static_cast<int>(to.num_vertices());
    EXPECT_EQ(4, nb_vertices);

    Mat1f adj;
    to.AdjacencyMat(adj);

    EXPECT_MAT_DIMS_EQ(adj, Size2i(nb_vertices, nb_vertices));
    EXPECT_MAT_EQ(adj, adj.t()) << "Expecting adj. matrix symmetric around diagonal";

    // verify we have no self-connections
    for(int r=0; r<adj.rows; r++) {
        EXPECT_EQ(0.f, adj(r, r)) << "Unexpected self-connection.";
    }

    // verify vertices vector
    VecF vtx_ids = to.VerticesIds();
    EXPECT_SIZE(nb_vertices, vtx_ids);

    // verify vertex ids and their order
    EXPECT_FLOAT_EQ(2, vtx_ids[0]);
    EXPECT_FLOAT_EQ(6, vtx_ids[1]);
    EXPECT_FLOAT_EQ(3, vtx_ids[2]);
    EXPECT_FLOAT_EQ(11, vtx_ids[3]);

    // verify individual connections

    EXPECT_FLOAT_EQ(1.f, cv::sum(adj.row(0))[0]);
    EXPECT_FLOAT_EQ(1.f, adj(2, 1));

    EXPECT_FLOAT_EQ(3.f, cv::sum(adj.row(1))[0]);
    EXPECT_FLOAT_EQ(1.f, adj(0, 1));
    EXPECT_FLOAT_EQ(1.f, adj(2, 1));
    EXPECT_FLOAT_EQ(1.f, adj(3, 1));

    EXPECT_FLOAT_EQ(1.f, cv::sum(adj.row(2))[0]);
    EXPECT_FLOAT_EQ(1.f, adj(1, 2));

    EXPECT_FLOAT_EQ(1.f, cv::sum(adj.row(3))[0]);
    EXPECT_FLOAT_EQ(1.f, adj(1, 3));
}

} // annonymous namespace for test cases and fixtures
<|endoftext|>


<commit_before><commit_msg>Prediction: rename to avoid conflict in obstacle.cc<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/find_in_page_controller.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/window_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "net/url_request/url_request_unittest.h"

class FindInPageControllerTest : public UITest {
 public:
  FindInPageControllerTest() {
    show_window_ = true;
  }
};

const std::wstring kFramePage = L"files/find_in_page/frames.html";
const std::wstring kUserSelectPage = L"files/find_in_page/user-select.html";
const std::wstring kCrashPage = L"files/find_in_page/crash_1341577.html";
const std::wstring kTooFewMatchesPage = L"files/find_in_page/bug_1155639.html";

// This test loads a page with frames and starts FindInPage requests
TEST_F(FindInPageControllerTest, FindInPageFrames) {
  TestServer server(L"chrome/test/data");

  // First we navigate to our frames page.
  GURL url = server.TestServerPageW(kFramePage);
  scoped_ptr<TabProxy> tab(GetActiveTab());
  ASSERT_TRUE(tab->NavigateToURL(url));
  WaitUntilTabCount(1);

  // Try incremental search (mimicking user typing in).
  EXPECT_EQ(18, tab->FindInPage(L"g",       FWD, IGNORE_CASE, false));
  EXPECT_EQ(11, tab->FindInPage(L"go",      FWD, IGNORE_CASE, false));
  EXPECT_EQ(04, tab->FindInPage(L"goo",     FWD, IGNORE_CASE, false));
  EXPECT_EQ(03, tab->FindInPage(L"goog",    FWD, IGNORE_CASE, false));
  EXPECT_EQ(02, tab->FindInPage(L"googl",   FWD, IGNORE_CASE, false));
  EXPECT_EQ(01, tab->FindInPage(L"google",  FWD, IGNORE_CASE, false));
  EXPECT_EQ(00, tab->FindInPage(L"google!", FWD, IGNORE_CASE, false));

  // Negative test (no matches should be found).
  EXPECT_EQ(0, tab->FindInPage(L"Non-existing string", FWD, IGNORE_CASE,
                               false));

  // 'horse' only exists in the three right frames.
  EXPECT_EQ(3, tab->FindInPage(L"horse", FWD, IGNORE_CASE, false));

  // 'cat' only exists in the first frame.
  EXPECT_EQ(1, tab->FindInPage(L"cat", FWD, IGNORE_CASE, false));

  // Try searching again, should still come up with 1 match.
  EXPECT_EQ(1, tab->FindInPage(L"cat", FWD, IGNORE_CASE, false));

  // Try searching backwards, ignoring case, should still come up with 1 match.
  EXPECT_EQ(1, tab->FindInPage(L"CAT", BACK, IGNORE_CASE, false));

  // Try case sensitive, should NOT find it.
  EXPECT_EQ(0, tab->FindInPage(L"CAT", FWD, CASE_SENSITIVE, false));

  // Try again case sensitive, but this time with right case.
  EXPECT_EQ(1, tab->FindInPage(L"dog", FWD, CASE_SENSITIVE, false));

  // Try non-Latin characters ('Hreggvidur' with 'eth' for 'd' in left frame).
  EXPECT_EQ(1, tab->FindInPage(L"Hreggvi\u00F0ur", FWD, IGNORE_CASE, false));
  EXPECT_EQ(1, tab->FindInPage(L"Hreggvi\u00F0ur", FWD, CASE_SENSITIVE, false));
  EXPECT_EQ(0, tab->FindInPage(L"hreggvi\u00F0ur", FWD, CASE_SENSITIVE, false));
}

// Load a page with no selectable text and make sure we don't crash.
TEST_F(FindInPageControllerTest, FindUnSelectableText) {
  TestServer server(L"chrome/test/data");

  GURL url = server.TestServerPageW(kUserSelectPage);
  scoped_ptr<TabProxy> tab(GetActiveTab());
  ASSERT_TRUE(tab->NavigateToURL(url));
  WaitUntilTabCount(1);

  EXPECT_EQ(0, tab->FindInPage(L"text", FWD, IGNORE_CASE, false));
  EXPECT_EQ(0, tab->FindInPage(L"Non-existing string", FWD, IGNORE_CASE,
                               false));
}

// Try to reproduce the crash seen in issue 1341577.
TEST_F(FindInPageControllerTest, DISABLED_FindCrash_Issue1341577) {
  TestServer server(L"chrome/test/data");

  GURL url = server.TestServerPageW(kCrashPage);
  scoped_ptr<TabProxy> tab(GetActiveTab());
  ASSERT_TRUE(tab->NavigateToURL(url));
  WaitUntilTabCount(1);

  // This would crash the tab. These must be the first two find requests issued
  // against the frame, otherwise an active frame pointer is set and it wont
  // produce the crash.
  EXPECT_EQ(1, tab->FindInPage(L"\u0D4C", FWD, IGNORE_CASE, false));
  EXPECT_EQ(1, tab->FindInPage(L"\u0D4C", FWD, IGNORE_CASE, true));  // FindNext

  // This should work fine.
  EXPECT_EQ(1, tab->FindInPage(L"\u0D24\u0D46", FWD, IGNORE_CASE, false));
  EXPECT_EQ(0, tab->FindInPage(L"nostring", FWD, IGNORE_CASE, false));
}

// Test to make sure Find does the right thing when restarting from a timeout.
// We used to have a problem where we'd stop finding matches when all of the
// following conditions were true:
// 1) The page has a lot of text to search.
// 2) The page contains more than one match.
// 3) It takes longer than the time-slice given to each Find operation (100
//    ms) to find one or more of those matches (so Find times out and has to try
//    again from where it left off).
TEST_F(FindInPageControllerTest, FindEnoughMatches_Issue1155639) {
  TestServer server(L"chrome/test/data");

  GURL url = server.TestServerPageW(kTooFewMatchesPage);
  scoped_ptr<TabProxy> tab(GetActiveTab());
  ASSERT_TRUE(tab->NavigateToURL(url));
  WaitUntilTabCount(1);

  // This string appears 5 times at the bottom of a long page. If Find restarts
  // properly after a timeout, it will find 5 matches, not just 1.
  EXPECT_EQ(5, tab->FindInPage(L"008.xml", FWD, IGNORE_CASE, false));
}

// The find window should not change its location just because we open and close
// a new tab.
TEST_F(FindInPageControllerTest, FindMovesOnTabClose_Issue1343052) {
  TestServer server(L"chrome/test/data");

  GURL url = server.TestServerPageW(kFramePage);
  scoped_ptr<TabProxy> tabA(GetActiveTab());
  ASSERT_TRUE(tabA->NavigateToURL(url));
  WaitUntilTabCount(1);

  scoped_ptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get() != NULL);

  // Toggle the bookmark bar state.
  browser->ApplyAccelerator(IDC_SHOW_BOOKMARKS_BAR);
  EXPECT_TRUE(WaitForBookmarkBarVisibilityChange(browser.get(), true));

  // Open the Find window and wait for it to animate.
  EXPECT_TRUE(tabA->OpenFindInPage());
  EXPECT_TRUE(WaitForFindWindowFullyVisible(tabA.get()));

  // Find its location.
  int x = -1, y = -1;
  EXPECT_TRUE(tabA->GetFindWindowLocation(&x, &y));

  // Open another tab (tab B).
  EXPECT_TRUE(browser->AppendTab(url));
  scoped_ptr<TabProxy> tabB(GetActiveTab());

  // Close tab B.
  EXPECT_TRUE(tabB->Close(true));

  // See if the Find window has moved.
  int new_x = -1, new_y = -1;
  EXPECT_TRUE(tabA->GetFindWindowLocation(&new_x, &new_y));

  EXPECT_EQ(x, new_x);
  EXPECT_EQ(y, new_y);

  // Now reset the bookmarks bar state and try the same again.
  browser->ApplyAccelerator(IDC_SHOW_BOOKMARKS_BAR);
  EXPECT_TRUE(WaitForBookmarkBarVisibilityChange(browser.get(), false));

  // Bookmark bar has moved, reset our coordinates.
  EXPECT_TRUE(tabA->GetFindWindowLocation(&x, &y));

  // Open another tab (tab C).
  EXPECT_TRUE(browser->AppendTab(url));
  scoped_ptr<TabProxy> tabC(GetActiveTab());

  // Close it.
  EXPECT_TRUE(tabC->Close(true));

  // See if the Find window has moved.
  EXPECT_TRUE(tabA->GetFindWindowLocation(&new_x, &new_y));

  EXPECT_EQ(x, new_x);
  EXPECT_EQ(y, new_y);
}
<commit_msg>Enabling test I wrote for Find to catch crash described in issue 1341577.<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/find_in_page_controller.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/automation/window_proxy.h"
#include "chrome/test/ui/ui_test.h"
#include "net/url_request/url_request_unittest.h"

class FindInPageControllerTest : public UITest {
 public:
  FindInPageControllerTest() {
    show_window_ = true;
  }
};

const std::wstring kFramePage = L"files/find_in_page/frames.html";
const std::wstring kUserSelectPage = L"files/find_in_page/user-select.html";
const std::wstring kCrashPage = L"files/find_in_page/crash_1341577.html";
const std::wstring kTooFewMatchesPage = L"files/find_in_page/bug_1155639.html";

// This test loads a page with frames and starts FindInPage requests
TEST_F(FindInPageControllerTest, FindInPageFrames) {
  TestServer server(L"chrome/test/data");

  // First we navigate to our frames page.
  GURL url = server.TestServerPageW(kFramePage);
  scoped_ptr<TabProxy> tab(GetActiveTab());
  ASSERT_TRUE(tab->NavigateToURL(url));
  WaitUntilTabCount(1);

  // Try incremental search (mimicking user typing in).
  EXPECT_EQ(18, tab->FindInPage(L"g",       FWD, IGNORE_CASE, false));
  EXPECT_EQ(11, tab->FindInPage(L"go",      FWD, IGNORE_CASE, false));
  EXPECT_EQ(04, tab->FindInPage(L"goo",     FWD, IGNORE_CASE, false));
  EXPECT_EQ(03, tab->FindInPage(L"goog",    FWD, IGNORE_CASE, false));
  EXPECT_EQ(02, tab->FindInPage(L"googl",   FWD, IGNORE_CASE, false));
  EXPECT_EQ(01, tab->FindInPage(L"google",  FWD, IGNORE_CASE, false));
  EXPECT_EQ(00, tab->FindInPage(L"google!", FWD, IGNORE_CASE, false));

  // Negative test (no matches should be found).
  EXPECT_EQ(0, tab->FindInPage(L"Non-existing string", FWD, IGNORE_CASE,
                               false));

  // 'horse' only exists in the three right frames.
  EXPECT_EQ(3, tab->FindInPage(L"horse", FWD, IGNORE_CASE, false));

  // 'cat' only exists in the first frame.
  EXPECT_EQ(1, tab->FindInPage(L"cat", FWD, IGNORE_CASE, false));

  // Try searching again, should still come up with 1 match.
  EXPECT_EQ(1, tab->FindInPage(L"cat", FWD, IGNORE_CASE, false));

  // Try searching backwards, ignoring case, should still come up with 1 match.
  EXPECT_EQ(1, tab->FindInPage(L"CAT", BACK, IGNORE_CASE, false));

  // Try case sensitive, should NOT find it.
  EXPECT_EQ(0, tab->FindInPage(L"CAT", FWD, CASE_SENSITIVE, false));

  // Try again case sensitive, but this time with right case.
  EXPECT_EQ(1, tab->FindInPage(L"dog", FWD, CASE_SENSITIVE, false));

  // Try non-Latin characters ('Hreggvidur' with 'eth' for 'd' in left frame).
  EXPECT_EQ(1, tab->FindInPage(L"Hreggvi\u00F0ur", FWD, IGNORE_CASE, false));
  EXPECT_EQ(1, tab->FindInPage(L"Hreggvi\u00F0ur", FWD, CASE_SENSITIVE, false));
  EXPECT_EQ(0, tab->FindInPage(L"hreggvi\u00F0ur", FWD, CASE_SENSITIVE, false));
}

// Load a page with no selectable text and make sure we don't crash.
TEST_F(FindInPageControllerTest, FindUnSelectableText) {
  TestServer server(L"chrome/test/data");

  GURL url = server.TestServerPageW(kUserSelectPage);
  scoped_ptr<TabProxy> tab(GetActiveTab());
  ASSERT_TRUE(tab->NavigateToURL(url));
  WaitUntilTabCount(1);

  EXPECT_EQ(0, tab->FindInPage(L"text", FWD, IGNORE_CASE, false));
  EXPECT_EQ(0, tab->FindInPage(L"Non-existing string", FWD, IGNORE_CASE,
                               false));
}

// Try to reproduce the crash seen in issue 1341577.
TEST_F(FindInPageControllerTest, FindCrash_Issue1341577) {
  TestServer server(L"chrome/test/data");

  GURL url = server.TestServerPageW(kCrashPage);
  scoped_ptr<TabProxy> tab(GetActiveTab());
  ASSERT_TRUE(tab->NavigateToURL(url));
  WaitUntilTabCount(1);

  // This would crash the tab. These must be the first two find requests issued
  // against the frame, otherwise an active frame pointer is set and it wont
  // produce the crash.
  EXPECT_EQ(1, tab->FindInPage(L"\u0D4C", FWD, IGNORE_CASE, false));
  // FindNext returns -1 for match count because it doesn't bother with
  // recounting the number of matches. We don't care about the match count
  // anyway in this case, we just want to make sure it doesn't crash.
  EXPECT_EQ(-1, tab->FindInPage(L"\u0D4C", FWD, IGNORE_CASE, true));

  // This should work fine.
  EXPECT_EQ(1, tab->FindInPage(L"\u0D24\u0D46", FWD, IGNORE_CASE, false));
  EXPECT_EQ(0, tab->FindInPage(L"nostring", FWD, IGNORE_CASE, false));
}

// Test to make sure Find does the right thing when restarting from a timeout.
// We used to have a problem where we'd stop finding matches when all of the
// following conditions were true:
// 1) The page has a lot of text to search.
// 2) The page contains more than one match.
// 3) It takes longer than the time-slice given to each Find operation (100
//    ms) to find one or more of those matches (so Find times out and has to try
//    again from where it left off).
TEST_F(FindInPageControllerTest, FindEnoughMatches_Issue1155639) {
  TestServer server(L"chrome/test/data");

  GURL url = server.TestServerPageW(kTooFewMatchesPage);
  scoped_ptr<TabProxy> tab(GetActiveTab());
  ASSERT_TRUE(tab->NavigateToURL(url));
  WaitUntilTabCount(1);

  // This string appears 5 times at the bottom of a long page. If Find restarts
  // properly after a timeout, it will find 5 matches, not just 1.
  EXPECT_EQ(5, tab->FindInPage(L"008.xml", FWD, IGNORE_CASE, false));
}

// The find window should not change its location just because we open and close
// a new tab.
TEST_F(FindInPageControllerTest, FindMovesOnTabClose_Issue1343052) {
  TestServer server(L"chrome/test/data");

  GURL url = server.TestServerPageW(kFramePage);
  scoped_ptr<TabProxy> tabA(GetActiveTab());
  ASSERT_TRUE(tabA->NavigateToURL(url));
  WaitUntilTabCount(1);

  scoped_ptr<BrowserProxy> browser(automation()->GetBrowserWindow(0));
  ASSERT_TRUE(browser.get() != NULL);

  // Toggle the bookmark bar state.
  browser->ApplyAccelerator(IDC_SHOW_BOOKMARKS_BAR);
  EXPECT_TRUE(WaitForBookmarkBarVisibilityChange(browser.get(), true));

  // Open the Find window and wait for it to animate.
  EXPECT_TRUE(tabA->OpenFindInPage());
  EXPECT_TRUE(WaitForFindWindowFullyVisible(tabA.get()));

  // Find its location.
  int x = -1, y = -1;
  EXPECT_TRUE(tabA->GetFindWindowLocation(&x, &y));

  // Open another tab (tab B).
  EXPECT_TRUE(browser->AppendTab(url));
  scoped_ptr<TabProxy> tabB(GetActiveTab());

  // Close tab B.
  EXPECT_TRUE(tabB->Close(true));

  // See if the Find window has moved.
  int new_x = -1, new_y = -1;
  EXPECT_TRUE(tabA->GetFindWindowLocation(&new_x, &new_y));

  EXPECT_EQ(x, new_x);
  EXPECT_EQ(y, new_y);

  // Now reset the bookmarks bar state and try the same again.
  browser->ApplyAccelerator(IDC_SHOW_BOOKMARKS_BAR);
  EXPECT_TRUE(WaitForBookmarkBarVisibilityChange(browser.get(), false));

  // Bookmark bar has moved, reset our coordinates.
  EXPECT_TRUE(tabA->GetFindWindowLocation(&x, &y));

  // Open another tab (tab C).
  EXPECT_TRUE(browser->AppendTab(url));
  scoped_ptr<TabProxy> tabC(GetActiveTab());

  // Close it.
  EXPECT_TRUE(tabC->Close(true));

  // See if the Find window has moved.
  EXPECT_TRUE(tabA->GetFindWindowLocation(&new_x, &new_y));

  EXPECT_EQ(x, new_x);
  EXPECT_EQ(y, new_y);
}
<|endoftext|>


<commit_before>// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <gtk/gtk.h>

#include "chrome/browser/options_window.h"

#include "app/l10n_util.h"
#include "base/message_loop.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profile.h"
#include "chrome/common/pref_member.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
#ifdef CHROME_PERSONALIZATION
#include "chrome/personalization/personalization.h"
#endif
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"

///////////////////////////////////////////////////////////////////////////////
// OptionsWindowGtk
//
//  The contents of the Options dialog window.

class OptionsWindowGtk {
 public:
  explicit OptionsWindowGtk(Profile* profile);
  ~OptionsWindowGtk();

  // Shows the Tab corresponding to the specified OptionsPage.
  void ShowOptionsPage(OptionsPage page, OptionsGroup highlight_group);

 private:
  static void OnSwitchPage(GtkNotebook* notebook, GtkNotebookPage* page,
                           guint page_num, OptionsWindowGtk* options_window);

  static void OnWindowDestroy(GtkWidget* widget, OptionsWindowGtk* window);

  // The options dialog
  GtkWidget *dialog_;

  // The container of the option pages
  GtkWidget *notebook_;

  // The Profile associated with these options.
  Profile* profile_;

  // The last page the user was on when they opened the Options window.
  IntegerPrefMember last_selected_page_;

  DISALLOW_COPY_AND_ASSIGN(OptionsWindowGtk);
};

static OptionsWindowGtk* instance_ = NULL;

///////////////////////////////////////////////////////////////////////////////
// OptionsWindowGtk, public:

OptionsWindowGtk::OptionsWindowGtk(Profile* profile)
      // Always show preferences for the original profile. Most state when off
      // the record comes from the original profile, but we explicitly use
      // the original profile to avoid potential problems.
    : profile_(profile->GetOriginalProfile()) {
  // The download manager needs to be initialized before the contents of the
  // Options Window are created.
  profile_->GetDownloadManager();
  // We don't need to observe changes in this value.
  last_selected_page_.Init(prefs::kOptionsWindowLastTabIndex,
                           g_browser_process->local_state(), NULL);

  dialog_ = gtk_dialog_new_with_buttons(
      l10n_util::GetStringFUTF8(IDS_OPTIONS_DIALOG_TITLE,
          WideToUTF16(l10n_util::GetString(IDS_PRODUCT_NAME))).c_str(),
      // Prefs window is shared between all browser windows.
      NULL,
      // Non-modal.
      GTK_DIALOG_NO_SEPARATOR,
      GTK_STOCK_CLOSE,
      GTK_RESPONSE_CLOSE,
      NULL);
  gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog_)->vbox), 18);

  notebook_ = gtk_notebook_new();

  gtk_notebook_append_page(
      GTK_NOTEBOOK(notebook_),
      gtk_label_new("TODO general"),
      gtk_label_new(
          l10n_util::GetStringUTF8(IDS_OPTIONS_GENERAL_TAB_LABEL).c_str()));

  gtk_notebook_append_page(
      GTK_NOTEBOOK(notebook_),
      gtk_label_new("TODO content"),
      gtk_label_new(
          l10n_util::GetStringUTF8(IDS_OPTIONS_CONTENT_TAB_LABEL).c_str()));

#ifdef CHROME_PERSONALIZATION
  if (!Personalization::IsP13NDisabled()) {
    gtk_notebook_append_page(
        GTK_NOTEBOOK(notebook_),
        gtk_label_new("TODO personalization"),
        gtk_label_new(
            l10n_util::GetStringUTF8(IDS_OPTIONS_USER_DATA_TAB_LABEL).c_str()));
  }
#endif

  gtk_notebook_append_page(
      GTK_NOTEBOOK(notebook_),
      gtk_label_new("TODO advanced"),
      gtk_label_new(
          l10n_util::GetStringUTF8(IDS_OPTIONS_ADVANCED_TAB_LABEL).c_str()));

  gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog_)->vbox), notebook_);

  DCHECK(
      gtk_notebook_get_n_pages(GTK_NOTEBOOK(notebook_)) == OPTIONS_PAGE_COUNT);

  // Need to show the notebook before connecting switch-page signal, otherwise
  // we'll immediately get a signal switching to page 0 and overwrite our
  // last_selected_page_ value.
  gtk_widget_show_all(dialog_);

  g_signal_connect(notebook_, "switch-page", G_CALLBACK(OnSwitchPage), this);

  // We only have one button and don't do any special handling, so just hook it
  // directly to gtk_widget_destroy.
  g_signal_connect_swapped(dialog_, "response", G_CALLBACK(gtk_widget_destroy),
                           dialog_);

  g_signal_connect(dialog_, "destroy", G_CALLBACK(OnWindowDestroy), this);
}

OptionsWindowGtk::~OptionsWindowGtk() {
}

void OptionsWindowGtk::ShowOptionsPage(OptionsPage page,
                                       OptionsGroup highlight_group) {
  // Bring options window to front if it already existed and isn't already
  // in front
  // TODO(mattm): docs say it's preferable to use gtk_window_present_with_time
  gtk_window_present(GTK_WINDOW(dialog_));

  if (page == OPTIONS_PAGE_DEFAULT) {
    // Remember the last visited page from local state.
    page = static_cast<OptionsPage>(last_selected_page_.GetValue());
    if (page == OPTIONS_PAGE_DEFAULT)
      page = OPTIONS_PAGE_GENERAL;
  }
  // If the page number is out of bounds, reset to the first tab.
  if (page < 0 || page >= gtk_notebook_get_n_pages(GTK_NOTEBOOK(notebook_)))
    page = OPTIONS_PAGE_GENERAL;

  gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook_), page);

  // TODO(mattm): set highlight_group
}

///////////////////////////////////////////////////////////////////////////////
// OptionsWindowGtk, private:

// static
void OptionsWindowGtk::OnSwitchPage(GtkNotebook* notebook,
                                    GtkNotebookPage* page,
                                    guint page_num,
                                    OptionsWindowGtk* options_window) {
  int index = page_num;
  DCHECK(index > OPTIONS_PAGE_DEFAULT && index < OPTIONS_PAGE_COUNT);
  options_window->last_selected_page_.SetValue(index);
}

// static
void OptionsWindowGtk::OnWindowDestroy(GtkWidget* widget,
                                       OptionsWindowGtk* options_window) {
  instance_ = NULL;
  MessageLoop::current()->DeleteSoon(FROM_HERE, options_window);
}

///////////////////////////////////////////////////////////////////////////////
// Factory/finder method:

void ShowOptionsWindow(OptionsPage page,
                       OptionsGroup highlight_group,
                       Profile* profile) {
  DCHECK(profile);
  // If there's already an existing options window, activate it and switch to
  // the specified page.
  if (!instance_) {
    instance_ = new OptionsWindowGtk(profile);
  }
  instance_->ShowOptionsPage(page, highlight_group);
}
<commit_msg>Add option to enable/disable reporting.<commit_after>// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <gtk/gtk.h>

#include "chrome/browser/options_window.h"

#include "app/l10n_util.h"
#include "base/message_loop.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/profile.h"
#include "chrome/common/pref_member.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
#ifdef CHROME_PERSONALIZATION
#include "chrome/personalization/personalization.h"
#endif
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"

///////////////////////////////////////////////////////////////////////////////
// OptionsWindowGtk
//
//  The contents of the Options dialog window.

class OptionsWindowGtk {
 public:
  explicit OptionsWindowGtk(Profile* profile);
  ~OptionsWindowGtk();

  // Shows the Tab corresponding to the specified OptionsPage.
  void ShowOptionsPage(OptionsPage page, OptionsGroup highlight_group);

 private:
  // This is the callback function for Stats reporting checkbox.
  static void OnLoggingChange(GtkWidget* widget,
                              OptionsWindowGtk* options_window);

  static void OnSwitchPage(GtkNotebook* notebook, GtkNotebookPage* page,
                           guint page_num, OptionsWindowGtk* options_window);

  static void OnWindowDestroy(GtkWidget* widget, OptionsWindowGtk* window);

  // This function gets called when stats reporting option is changed.
  void LoggingChanged(GtkWidget* widget);

  // The options dialog
  GtkWidget *dialog_;

  // The container of the option pages
  GtkWidget *notebook_;

  // The Profile associated with these options.
  Profile* profile_;

  // The last page the user was on when they opened the Options window.
  IntegerPrefMember last_selected_page_;

  DISALLOW_COPY_AND_ASSIGN(OptionsWindowGtk);
};

static OptionsWindowGtk* instance_ = NULL;

///////////////////////////////////////////////////////////////////////////////
// OptionsWindowGtk, public:

OptionsWindowGtk::OptionsWindowGtk(Profile* profile)
      // Always show preferences for the original profile. Most state when off
      // the record comes from the original profile, but we explicitly use
      // the original profile to avoid potential problems.
    : profile_(profile->GetOriginalProfile()) {
  // The download manager needs to be initialized before the contents of the
  // Options Window are created.
  profile_->GetDownloadManager();
  // We don't need to observe changes in this value.
  last_selected_page_.Init(prefs::kOptionsWindowLastTabIndex,
                           g_browser_process->local_state(), NULL);

  dialog_ = gtk_dialog_new_with_buttons(
      l10n_util::GetStringFUTF8(IDS_OPTIONS_DIALOG_TITLE,
          WideToUTF16(l10n_util::GetString(IDS_PRODUCT_NAME))).c_str(),
      // Prefs window is shared between all browser windows.
      NULL,
      // Non-modal.
      GTK_DIALOG_NO_SEPARATOR,
      GTK_STOCK_CLOSE,
      GTK_RESPONSE_CLOSE,
      NULL);
  gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog_)->vbox), 18);

  notebook_ = gtk_notebook_new();

  gtk_notebook_append_page(
      GTK_NOTEBOOK(notebook_),
      gtk_label_new("TODO general"),
      gtk_label_new(
          l10n_util::GetStringUTF8(IDS_OPTIONS_GENERAL_TAB_LABEL).c_str()));

  gtk_notebook_append_page(
      GTK_NOTEBOOK(notebook_),
      gtk_label_new("TODO content"),
      gtk_label_new(
          l10n_util::GetStringUTF8(IDS_OPTIONS_CONTENT_TAB_LABEL).c_str()));

#ifdef CHROME_PERSONALIZATION
  if (!Personalization::IsP13NDisabled()) {
    gtk_notebook_append_page(
        GTK_NOTEBOOK(notebook_),
        gtk_label_new("TODO personalization"),
        gtk_label_new(
            l10n_util::GetStringUTF8(IDS_OPTIONS_USER_DATA_TAB_LABEL).c_str()));
  }
#endif

  GtkWidget* metrics_vbox = gtk_vbox_new(FALSE, 5);
  GtkWidget* metrics = gtk_check_button_new_with_label(
      l10n_util::GetStringUTF8(IDS_OPTIONS_ENABLE_LOGGING).c_str());
  gtk_box_pack_start(GTK_BOX(metrics_vbox), metrics, FALSE, FALSE, 0);
  gtk_box_pack_start(GTK_BOX(metrics_vbox),
                     gtk_label_new("TODO rest of the advanced options"),
                     FALSE, FALSE, 0);
  g_signal_connect(metrics, "clicked", G_CALLBACK(OnLoggingChange), this);

  gtk_notebook_append_page(
      GTK_NOTEBOOK(notebook_),
      metrics_vbox,
      gtk_label_new(
          l10n_util::GetStringUTF8(IDS_OPTIONS_ADVANCED_TAB_LABEL).c_str()));

  gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog_)->vbox), notebook_);

  DCHECK(
      gtk_notebook_get_n_pages(GTK_NOTEBOOK(notebook_)) == OPTIONS_PAGE_COUNT);

  // Need to show the notebook before connecting switch-page signal, otherwise
  // we'll immediately get a signal switching to page 0 and overwrite our
  // last_selected_page_ value.
  gtk_widget_show_all(dialog_);

  g_signal_connect(notebook_, "switch-page", G_CALLBACK(OnSwitchPage), this);

  // We only have one button and don't do any special handling, so just hook it
  // directly to gtk_widget_destroy.
  g_signal_connect_swapped(dialog_, "response", G_CALLBACK(gtk_widget_destroy),
                           dialog_);

  g_signal_connect(dialog_, "destroy", G_CALLBACK(OnWindowDestroy), this);
}

OptionsWindowGtk::~OptionsWindowGtk() {
}

void OptionsWindowGtk::ShowOptionsPage(OptionsPage page,
                                       OptionsGroup highlight_group) {
  // Bring options window to front if it already existed and isn't already
  // in front
  // TODO(mattm): docs say it's preferable to use gtk_window_present_with_time
  gtk_window_present(GTK_WINDOW(dialog_));

  if (page == OPTIONS_PAGE_DEFAULT) {
    // Remember the last visited page from local state.
    page = static_cast<OptionsPage>(last_selected_page_.GetValue());
    if (page == OPTIONS_PAGE_DEFAULT)
      page = OPTIONS_PAGE_GENERAL;
  }
  // If the page number is out of bounds, reset to the first tab.
  if (page < 0 || page >= gtk_notebook_get_n_pages(GTK_NOTEBOOK(notebook_)))
    page = OPTIONS_PAGE_GENERAL;

  gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook_), page);

  // TODO(mattm): set highlight_group
}

///////////////////////////////////////////////////////////////////////////////
// OptionsWindowGtk, private:

// static
void OptionsWindowGtk::OnLoggingChange(GtkWidget* widget,
                                       OptionsWindowGtk* options_window) {
  options_window->LoggingChanged(widget);
}

// static
void OptionsWindowGtk::OnSwitchPage(GtkNotebook* notebook,
                                    GtkNotebookPage* page,
                                    guint page_num,
                                    OptionsWindowGtk* options_window) {
  int index = page_num;
  DCHECK(index > OPTIONS_PAGE_DEFAULT && index < OPTIONS_PAGE_COUNT);
  options_window->last_selected_page_.SetValue(index);
}

// static
void OptionsWindowGtk::OnWindowDestroy(GtkWidget* widget,
                                       OptionsWindowGtk* options_window) {
  instance_ = NULL;
  MessageLoop::current()->DeleteSoon(FROM_HERE, options_window);
}

void OptionsWindowGtk::LoggingChanged(GtkWidget* metrics) {
  // TODO: Once crash reporting is working for Linux, make the actual call to
  // enable/disable it.
  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(metrics)))
    LOG(INFO) << "Reporting enabled";
  else
    LOG(INFO) << "Reporting disabled";
}

///////////////////////////////////////////////////////////////////////////////
// Factory/finder method:

void ShowOptionsWindow(OptionsPage page,
                       OptionsGroup highlight_group,
                       Profile* profile) {
  DCHECK(profile);
  // If there's already an existing options window, activate it and switch to
  // the specified page.
  if (!instance_) {
    instance_ = new OptionsWindowGtk(profile);
  }
  instance_->ShowOptionsPage(page, highlight_group);
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/net/connection_tester.h"

#include "chrome/browser/io_thread.h"
#include "chrome/test/testing_pref_service.h"
#include "net/base/mock_host_resolver.h"
#include "net/test/test_server.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"

namespace {

// This is a testing delegate which simply counts how many times each of
// the delegate's methods were invoked.
class ConnectionTesterDelegate : public ConnectionTester::Delegate {
 public:
  ConnectionTesterDelegate()
     : start_connection_test_suite_count_(0),
       start_connection_test_experiment_count_(0),
       completed_connection_test_experiment_count_(0),
       completed_connection_test_suite_count_(0) {
  }

  virtual void OnStartConnectionTestSuite() {
    start_connection_test_suite_count_++;
  }

  virtual void OnStartConnectionTestExperiment(
      const ConnectionTester::Experiment& experiment) {
    start_connection_test_experiment_count_++;
  }

  virtual void OnCompletedConnectionTestExperiment(
      const ConnectionTester::Experiment& experiment,
      int result) {
    completed_connection_test_experiment_count_++;
  }

  virtual void OnCompletedConnectionTestSuite() {
    completed_connection_test_suite_count_++;
    MessageLoop::current()->Quit();
  }

  int start_connection_test_suite_count() const {
    return start_connection_test_suite_count_;
  }

  int start_connection_test_experiment_count() const {
    return start_connection_test_experiment_count_;
  }

  int completed_connection_test_experiment_count() const {
    return completed_connection_test_experiment_count_;
  }

  int completed_connection_test_suite_count() const {
    return completed_connection_test_suite_count_;
  }

 private:
  int start_connection_test_suite_count_;
  int start_connection_test_experiment_count_;
  int completed_connection_test_experiment_count_;
  int completed_connection_test_suite_count_;
};

// The test fixture is responsible for:
//   - Making sure each test has an IO loop running
//   - Catching any host resolve requests and mapping them to localhost
//     (so the test doesn't use any external network dependencies).
class ConnectionTesterTest : public PlatformTest {
 public:
  ConnectionTesterTest()
      : test_server_(net::TestServer::TYPE_HTTP,
            FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))),
        message_loop_(MessageLoop::TYPE_IO),
        io_thread_(new TestingPrefService()) {
    scoped_refptr<net::RuleBasedHostResolverProc> catchall_resolver(
        new net::RuleBasedHostResolverProc(NULL));

    catchall_resolver->AddRule("*", "127.0.0.1");

    scoped_host_resolver_proc_.Init(catchall_resolver);
  }

 protected:
  net::ScopedDefaultHostResolverProc scoped_host_resolver_proc_;
  net::TestServer test_server_;
  ConnectionTesterDelegate test_delegate_;
  MessageLoop message_loop_;
  IOThread io_thread_;  // Needed for creating ProxyScriptFetchers.
};

TEST_F(ConnectionTesterTest, RunAllTests) {
  ASSERT_TRUE(test_server_.Start());

  ConnectionTester tester(&test_delegate_, &io_thread_);

  // Start the test suite on URL "echoall".
  // TODO(eroman): Is this URL right?
  tester.RunAllTests(test_server_.GetURL("echoall"));

  // Wait for all the tests to complete.
  MessageLoop::current()->Run();

  const int kNumExperiments =
      ConnectionTester::PROXY_EXPERIMENT_COUNT *
      ConnectionTester::HOST_RESOLVER_EXPERIMENT_COUNT;

  EXPECT_EQ(1, test_delegate_.start_connection_test_suite_count());
  EXPECT_EQ(kNumExperiments,
            test_delegate_.start_connection_test_experiment_count());
  EXPECT_EQ(kNumExperiments,
            test_delegate_.completed_connection_test_experiment_count());
  EXPECT_EQ(1, test_delegate_.completed_connection_test_suite_count());
}

TEST_F(ConnectionTesterTest, DeleteWhileInProgress) {
  ASSERT_TRUE(test_server_.Start());

  scoped_ptr<ConnectionTester> tester(
      new ConnectionTester(&test_delegate_, &io_thread_));

  // Start the test suite on URL "echoall".
  // TODO(eroman): Is this URL right?
  tester->RunAllTests(test_server_.GetURL("echoall"));

  MessageLoop::current()->RunAllPending();

  EXPECT_EQ(1, test_delegate_.start_connection_test_suite_count());
  EXPECT_EQ(1, test_delegate_.start_connection_test_experiment_count());
  EXPECT_EQ(0, test_delegate_.completed_connection_test_experiment_count());
  EXPECT_EQ(0, test_delegate_.completed_connection_test_suite_count());

  // Delete the ConnectionTester while it is in progress.
  tester.reset();

  // Drain the tasks on the message loop.
  //
  // Note that we cannot simply stop the message loop, since that will delete
  // any pending tasks instead of running them. This causes a problem with
  // net::ClientSocketPoolBaseHelper, since the "Group" holds a pointer
  // |backup_task| that it will try to deref during the destructor, but
  // depending on the order that pending tasks were deleted in, it might
  // already be invalid! See http://crbug.com/43291.
  MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
  MessageLoop::current()->Run();
}

}  // namespace

<commit_msg>Fix memory leak in connection_tester_unittest.cc<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/net/connection_tester.h"

#include "chrome/browser/io_thread.h"
#include "chrome/test/testing_pref_service.h"
#include "net/base/mock_host_resolver.h"
#include "net/test/test_server.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"

namespace {

// This is a testing delegate which simply counts how many times each of
// the delegate's methods were invoked.
class ConnectionTesterDelegate : public ConnectionTester::Delegate {
 public:
  ConnectionTesterDelegate()
     : start_connection_test_suite_count_(0),
       start_connection_test_experiment_count_(0),
       completed_connection_test_experiment_count_(0),
       completed_connection_test_suite_count_(0) {
  }

  virtual void OnStartConnectionTestSuite() {
    start_connection_test_suite_count_++;
  }

  virtual void OnStartConnectionTestExperiment(
      const ConnectionTester::Experiment& experiment) {
    start_connection_test_experiment_count_++;
  }

  virtual void OnCompletedConnectionTestExperiment(
      const ConnectionTester::Experiment& experiment,
      int result) {
    completed_connection_test_experiment_count_++;
  }

  virtual void OnCompletedConnectionTestSuite() {
    completed_connection_test_suite_count_++;
    MessageLoop::current()->Quit();
  }

  int start_connection_test_suite_count() const {
    return start_connection_test_suite_count_;
  }

  int start_connection_test_experiment_count() const {
    return start_connection_test_experiment_count_;
  }

  int completed_connection_test_experiment_count() const {
    return completed_connection_test_experiment_count_;
  }

  int completed_connection_test_suite_count() const {
    return completed_connection_test_suite_count_;
  }

 private:
  int start_connection_test_suite_count_;
  int start_connection_test_experiment_count_;
  int completed_connection_test_experiment_count_;
  int completed_connection_test_suite_count_;
};

// The test fixture is responsible for:
//   - Making sure each test has an IO loop running
//   - Catching any host resolve requests and mapping them to localhost
//     (so the test doesn't use any external network dependencies).
class ConnectionTesterTest : public PlatformTest {
 public:
  ConnectionTesterTest()
      : test_server_(net::TestServer::TYPE_HTTP,
            FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))),
        message_loop_(MessageLoop::TYPE_IO),
        pref_service(new TestingPrefService()),
        io_thread_(pref_service.get()) {
    scoped_refptr<net::RuleBasedHostResolverProc> catchall_resolver(
        new net::RuleBasedHostResolverProc(NULL));

    catchall_resolver->AddRule("*", "127.0.0.1");

    scoped_host_resolver_proc_.Init(catchall_resolver);
  }

 protected:
  net::ScopedDefaultHostResolverProc scoped_host_resolver_proc_;
  net::TestServer test_server_;
  ConnectionTesterDelegate test_delegate_;
  MessageLoop message_loop_;
  scoped_ptr<PrefService> pref_service;
  IOThread io_thread_;  // Needed for creating ProxyScriptFetchers.
};

TEST_F(ConnectionTesterTest, RunAllTests) {
  ASSERT_TRUE(test_server_.Start());

  ConnectionTester tester(&test_delegate_, &io_thread_);

  // Start the test suite on URL "echoall".
  // TODO(eroman): Is this URL right?
  tester.RunAllTests(test_server_.GetURL("echoall"));

  // Wait for all the tests to complete.
  MessageLoop::current()->Run();

  const int kNumExperiments =
      ConnectionTester::PROXY_EXPERIMENT_COUNT *
      ConnectionTester::HOST_RESOLVER_EXPERIMENT_COUNT;

  EXPECT_EQ(1, test_delegate_.start_connection_test_suite_count());
  EXPECT_EQ(kNumExperiments,
            test_delegate_.start_connection_test_experiment_count());
  EXPECT_EQ(kNumExperiments,
            test_delegate_.completed_connection_test_experiment_count());
  EXPECT_EQ(1, test_delegate_.completed_connection_test_suite_count());
}

TEST_F(ConnectionTesterTest, DeleteWhileInProgress) {
  ASSERT_TRUE(test_server_.Start());

  scoped_ptr<ConnectionTester> tester(
      new ConnectionTester(&test_delegate_, &io_thread_));

  // Start the test suite on URL "echoall".
  // TODO(eroman): Is this URL right?
  tester->RunAllTests(test_server_.GetURL("echoall"));

  MessageLoop::current()->RunAllPending();

  EXPECT_EQ(1, test_delegate_.start_connection_test_suite_count());
  EXPECT_EQ(1, test_delegate_.start_connection_test_experiment_count());
  EXPECT_EQ(0, test_delegate_.completed_connection_test_experiment_count());
  EXPECT_EQ(0, test_delegate_.completed_connection_test_suite_count());

  // Delete the ConnectionTester while it is in progress.
  tester.reset();

  // Drain the tasks on the message loop.
  //
  // Note that we cannot simply stop the message loop, since that will delete
  // any pending tasks instead of running them. This causes a problem with
  // net::ClientSocketPoolBaseHelper, since the "Group" holds a pointer
  // |backup_task| that it will try to deref during the destructor, but
  // depending on the order that pending tasks were deleted in, it might
  // already be invalid! See http://crbug.com/43291.
  MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
  MessageLoop::current()->Run();
}

}  // namespace

<|endoftext|>