<commit_before>#ifndef TEST_UNIT_MATH_TEST_EXPECT_NEAR_REL_HPP
#define TEST_UNIT_MATH_TEST_EXPECT_NEAR_REL_HPP

#include <stan/math.hpp>
#include <gtest/gtest.h>
#include <string>
#include <vector>

namespace stan {
namespace test {

namespace internal {

/**
 * Test that the specified values are within the specified tolerance
 * on relative error, and if not, fail the embedded google test.
 *
 *
Relative error is defined to be the error `u - v` rescaled by the
 * average absolute value,
 * `rel_err(u, v) = (u - v) / (0.5 * (abs(u) * + abs(v))).`
 *
 *
If at least one of `u` or `v` is zero, the absolute error is
 * tested at the specified tolerance, because the relative error
 * reduces to a constant.
 *
 * @tparam T1 type of first argument
 * @tparam T2 type of second argument
 * @param msg failure message for reporting
 * @param x1 first argument
 * @param x2 second argument
 * @param tol relative tolerance
 */
template <typename T1, typename T2, require_all_stan_scalar_t<T1, T2>...>
void expect_near_rel_finite(const std::string& msg, const T1& x1, const T2& x2,
                            double tol = 1e-8) {
  using stan::math::fabs;
  // if either arg near zero, must use absolute tolerance as rel tol -> 2
  if (fabs(x1) < tol || fabs(x2) < tol) {
    EXPECT_NEAR(x1, x2, tol) << "expect_near_rel_finite(" << x1 << ", " << x2
                             << ", absolute tolerance = " << tol << ")"
                             << "; absolute diff = " << fabs(x1 - x2)
                             << "    in: " << msg << std::endl;
    return;
  }
  auto avg = 0.5 * (fabs(x1) + fabs(x2));
  auto relative_diff = (x1 - x2) / avg;
  EXPECT_NEAR(0, relative_diff, tol)
      << "expect_near_rel_finite(" << x1 << ", " << x2
      << ", relative tolerance = " << tol << ")"
      << "; relative diff = " << relative_diff << std::endl
      << "    in: " << msg << std::endl;
}

template <typename EigMat1, typename EigMat2,
          require_all_eigen_t<EigMat1, EigMat2>...>
void expect_near_rel_finite(const std::string& msg, const EigMat1& x1,
                            const EigMat2& x2) {
  EXPECT_EQ(x1.rows(), x2.rows());
  EXPECT_EQ(x1.cols(), x2.cols());
  auto x1_eval = x1.eval();
  auto x2_eval = x2.eval();
  for (int i = 0; i < x1.size(); ++i)
    expect_near_rel_finite(msg, x1_eval(i), x2_eval(i));
}

template <typename T1, typename T2>
void expect_near_rel_finite(const std::string& msg, const std::vector<T1>& x1,
                            const std::vector<T2>& x2) {
  EXPECT_EQ(x1.size(), x2.size());
  for (size_t i = 0; i < x1.size(); ++i)
    expect_near_rel_finite(x1[i], x2[i]);
}

}  // namespace internal

/**
 * Test that scalars x1 and x2 are within the specified relative
 * tolerance, with identity behavior for infinite and NaN values.
 * Relative tolerance is defined in the documentation for
 * `expect_near_rel_finite`.
 *
 * @tparam T1 type of first argument
 * @tparam T2 type of second argument
 * @param msg message indicating what is being tested to print in case
 * of error
 * @param x1 first argument to test
 * @param x2 second argument to test
 * @param tol relative tolerance
 */
template <typename T1, typename T2, require_all_stan_scalar_t<T1, T2>...>
void expect_near_rel(const std::string& msg, const T1& x1, const T2& x2,
                     double tol = 1e-8) {
  if (stan::math::is_nan(x1) || stan::math::is_nan(x2))
    EXPECT_TRUE(stan::math::is_nan(x1) && stan::math::is_nan(x2))
        << "expect_near_rel(" << x1 << ", " << x2 << ")" << std::endl
        << msg << std::endl;
  else if (stan::math::is_inf(x1) || stan::math::is_inf(x2))
    EXPECT_EQ(x1, x2) << "expect_near_rel(" << x1 << ", " << x2 << ")"
                      << std::endl
                      << msg << std::endl;
  else
    internal::expect_near_rel_finite(msg, x1, x2, tol);
}

/**
 * Tests that matrices (or vectors) x1 and x2 are same size and
 * have near values up to specified relative tolerance, accounting for
 * infinite, not-a-number, and zero values as specified in
 * `expect_near_rel_finite`.
 *
 * @tparam T1 type of scalars in first matrix
 * @tparam T2 type of scalars in second matrix
 * @tparam R row specification of matrix
 * @tparam C column specification of the matrix
 * @param msg failure message
 * @param x1 first matrix to test
 * @param x2 second matrix to test
 * @param tol relative tolerance
 */
template <typename EigMat1, typename EigMat2,
          require_all_eigen_t<EigMat1, EigMat2>...>
void expect_near_rel(const std::string& msg, EigMat1&& x1, EigMat2&& x2,
                     double tol = 1e-8) {
  EXPECT_EQ(x1.rows(), x2.rows()) << "expect_near_rel (Eigen::Matrix)"
                                  << " rows must be same size."
                                  << " x1.rows() = " << x1.rows()
                                  << "; x2.rows() = " << x2.rows() << std::endl
                                  << msg << std::endl;
  EXPECT_EQ(x1.cols(), x2.cols())
      << "expect_near_rel:"
      << "cols must be same size."
      << "x1.cols() = " << x1.cols() << "x2.cols() = " << x2.cols() << ")"
      << std::endl
      << msg << std::endl;
  std::string msg2 = "expect_near_rel; require items x1(i) = x2(i): " + msg;
  auto x1_eval = x1.eval();
  auto x2_eval = x2.eval();
  for (int i = 0; i < x1.size(); ++i)
    expect_near_rel(msg2, x1_eval(i), x2_eval(i), tol);
}

template <typename T1, typename T2>
void expect_near_rel(const std::string& msg, const std::vector<T1>& x1,
                     const std::vector<T2>& x2, double tol = 1e-8) {
  EXPECT_EQ(x1.size(), x2.size()) << "expect_near_rel (std::vector):"
                                  << " vectors must be same size."
                                  << " x1.size() = " << x1.size()
                                  << "; x2.size() = " << x2.size() << std::endl
                                  << msg << std::endl;
  std::string msg2 = "expect_near_rel; requite items x1[i] = x2[i]: " + msg;
  for (size_t i = 0; i < x1.size(); ++i)
    expect_near_rel(msg2, x1[i], x2[i], tol);
}

}  // namespace test
}  // namespace stan
#endif<commit_msg>Line end<commit_after>#ifndef TEST_UNIT_MATH_TEST_EXPECT_NEAR_REL_HPP
#define TEST_UNIT_MATH_TEST_EXPECT_NEAR_REL_HPP

#include <stan/math.hpp>
#include <gtest/gtest.h>
#include <string>
#include <vector>

namespace stan {
namespace test {

namespace internal {

/**
 * Test that the specified values are within the specified tolerance
 * on relative error, and if not, fail the embedded google test.
 *
 *
Relative error is defined to be the error `u - v` rescaled by the
 * average absolute value,
 * `rel_err(u, v) = (u - v) / (0.5 * (abs(u) * + abs(v))).`
 *
 *
If at least one of `u` or `v` is zero, the absolute error is
 * tested at the specified tolerance, because the relative error
 * reduces to a constant.
 *
 * @tparam T1 type of first argument
 * @tparam T2 type of second argument
 * @param msg failure message for reporting
 * @param x1 first argument
 * @param x2 second argument
 * @param tol relative tolerance
 */
template <typename T1, typename T2, require_all_stan_scalar_t<T1, T2>...>
void expect_near_rel_finite(const std::string& msg, const T1& x1, const T2& x2,
                            double tol = 1e-8) {
  using stan::math::fabs;
  // if either arg near zero, must use absolute tolerance as rel tol -> 2
  if (fabs(x1) < tol || fabs(x2) < tol) {
    EXPECT_NEAR(x1, x2, tol) << "expect_near_rel_finite(" << x1 << ", " << x2
                             << ", absolute tolerance = " << tol << ")"
                             << "; absolute diff = " << fabs(x1 - x2)
                             << "    in: " << msg << std::endl;
    return;
  }
  auto avg = 0.5 * (fabs(x1) + fabs(x2));
  auto relative_diff = (x1 - x2) / avg;
  EXPECT_NEAR(0, relative_diff, tol)
      << "expect_near_rel_finite(" << x1 << ", " << x2
      << ", relative tolerance = " << tol << ")"
      << "; relative diff = " << relative_diff << std::endl
      << "    in: " << msg << std::endl;
}

template <typename EigMat1, typename EigMat2,
          require_all_eigen_t<EigMat1, EigMat2>...>
void expect_near_rel_finite(const std::string& msg, const EigMat1& x1,
                            const EigMat2& x2) {
  EXPECT_EQ(x1.rows(), x2.rows());
  EXPECT_EQ(x1.cols(), x2.cols());
  auto x1_eval = x1.eval();
  auto x2_eval = x2.eval();
  for (int i = 0; i < x1.size(); ++i)
    expect_near_rel_finite(msg, x1_eval(i), x2_eval(i));
}

template <typename T1, typename T2>
void expect_near_rel_finite(const std::string& msg, const std::vector<T1>& x1,
                            const std::vector<T2>& x2) {
  EXPECT_EQ(x1.size(), x2.size());
  for (size_t i = 0; i < x1.size(); ++i)
    expect_near_rel_finite(x1[i], x2[i]);
}

}  // namespace internal

/**
 * Test that scalars x1 and x2 are within the specified relative
 * tolerance, with identity behavior for infinite and NaN values.
 * Relative tolerance is defined in the documentation for
 * `expect_near_rel_finite`.
 *
 * @tparam T1 type of first argument
 * @tparam T2 type of second argument
 * @param msg message indicating what is being tested to print in case
 * of error
 * @param x1 first argument to test
 * @param x2 second argument to test
 * @param tol relative tolerance
 */
template <typename T1, typename T2, require_all_stan_scalar_t<T1, T2>...>
void expect_near_rel(const std::string& msg, const T1& x1, const T2& x2,
                     double tol = 1e-8) {
  if (stan::math::is_nan(x1) || stan::math::is_nan(x2))
    EXPECT_TRUE(stan::math::is_nan(x1) && stan::math::is_nan(x2))
        << "expect_near_rel(" << x1 << ", " << x2 << ")" << std::endl
        << msg << std::endl;
  else if (stan::math::is_inf(x1) || stan::math::is_inf(x2))
    EXPECT_EQ(x1, x2) << "expect_near_rel(" << x1 << ", " << x2 << ")"
                      << std::endl
                      << msg << std::endl;
  else
    internal::expect_near_rel_finite(msg, x1, x2, tol);
}

/**
 * Tests that matrices (or vectors) x1 and x2 are same size and
 * have near values up to specified relative tolerance, accounting for
 * infinite, not-a-number, and zero values as specified in
 * `expect_near_rel_finite`.
 *
 * @tparam T1 type of scalars in first matrix
 * @tparam T2 type of scalars in second matrix
 * @tparam R row specification of matrix
 * @tparam C column specification of the matrix
 * @param msg failure message
 * @param x1 first matrix to test
 * @param x2 second matrix to test
 * @param tol relative tolerance
 */
template <typename EigMat1, typename EigMat2,
          require_all_eigen_t<EigMat1, EigMat2>...>
void expect_near_rel(const std::string& msg, EigMat1&& x1, EigMat2&& x2,
                     double tol = 1e-8) {
  EXPECT_EQ(x1.rows(), x2.rows()) << "expect_near_rel (Eigen::Matrix)"
                                  << " rows must be same size."
                                  << " x1.rows() = " << x1.rows()
                                  << "; x2.rows() = " << x2.rows() << std::endl
                                  << msg << std::endl;
  EXPECT_EQ(x1.cols(), x2.cols())
      << "expect_near_rel:"
      << "cols must be same size."
      << "x1.cols() = " << x1.cols() << "x2.cols() = " << x2.cols() << ")"
      << std::endl
      << msg << std::endl;
  std::string msg2 = "expect_near_rel; require items x1(i) = x2(i): " + msg;
  auto x1_eval = x1.eval();
  auto x2_eval = x2.eval();
  for (int i = 0; i < x1.size(); ++i)
    expect_near_rel(msg2, x1_eval(i), x2_eval(i), tol);
}

template <typename T1, typename T2>
void expect_near_rel(const std::string& msg, const std::vector<T1>& x1,
                     const std::vector<T2>& x2, double tol = 1e-8) {
  EXPECT_EQ(x1.size(), x2.size()) << "expect_near_rel (std::vector):"
                                  << " vectors must be same size."
                                  << " x1.size() = " << x1.size()
                                  << "; x2.size() = " << x2.size() << std::endl
                                  << msg << std::endl;
  std::string msg2 = "expect_near_rel; requite items x1[i] = x2[i]: " + msg;
  for (size_t i = 0; i < x1.size(); ++i)
    expect_near_rel(msg2, x1[i], x2[i], tol);
}

}  // namespace test
}  // namespace stan
#endif
<|endoftext|>


<commit_before><commit_msg>no issue #<commit_after><|endoftext|>


<commit_before>// includes, Qwt
#include <qwt_plot.h>
#include <qwt_plot_curve.h>
#include <qwt_scale_engine.h>

// System Includes
#include <iostream>

// include local
#include "plotgapwidget.h"

// QT
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QSpacerItem>

namespace iu {

//-----------------------------------------------------------------------------
PlotGapWidget::PlotGapWidget(QWidget* parent, bool x_log_scale, bool y_log_scale)
  :QWidget(parent)
{
  myPlot_ = new QwtPlot(0);
  int numDecimals = 2;

  myPlot_->setCanvasBackground(QColor(255,255,255));
  if (x_log_scale)
    myPlot_->setAxisScaleEngine(QwtPlot::xBottom, new QwtLog10ScaleEngine);
  if (y_log_scale)
    myPlot_->setAxisScaleEngine(QwtPlot::yLeft, new QwtLog10ScaleEngine);

  QHBoxLayout* controlLayout = new QHBoxLayout(NULL);

  QLabel* yMinLabel = new QLabel;
  yMinLabel->setText("Y-Axis");
  controlLayout->addWidget(yMinLabel);
  yMin_ = new QScienceSpinBox;
  yMin_->setDecimals(numDecimals);
  controlLayout->addWidget(yMin_);

  yMax_ = new QScienceSpinBox;
  yMax_->setDecimals(numDecimals);
  controlLayout->addWidget(yMax_);

  yLog_ = new QCheckBox();
  yLog_->setText("Log scale");
  if (y_log_scale)
    yLog_->setChecked(true);
  else
    yLog_->setChecked(false);
  controlLayout->addWidget(yLog_);

  controlLayout->insertStretch(4);

  QLabel* xMinLabel = new QLabel;
  xMinLabel->setText("X-Axis");
  controlLayout->addWidget(xMinLabel);
  xMin_ = new QScienceSpinBox;
  xMin_->setDecimals(numDecimals);
  controlLayout->addWidget(xMin_);

  xMax_ = new QScienceSpinBox;
  xMax_->setDecimals(numDecimals);
  controlLayout->addWidget(xMax_);

  xLog_ = new QCheckBox;
  xLog_->setText("Log scale");
  if (x_log_scale)
    xLog_->setChecked(true);
  else
    xLog_->setChecked(false);
  controlLayout->addWidget(xLog_);

  QVBoxLayout* mainLayout = new QVBoxLayout(this);
  mainLayout->addLayout(controlLayout);
  mainLayout->addWidget(myPlot_);
  this->setLayout(mainLayout);

  myPlot_->replot();

  // make some connections
  connect(xMin_, SIGNAL(valueChanged(double)), this, SLOT(updateXMin(double)));
  connect(xMax_, SIGNAL(valueChanged(double)), this, SLOT(updateXMax(double)));
  connect(xLog_, SIGNAL(toggled(bool)), this, SLOT(updateXLog(bool)));
  connect(yMin_, SIGNAL(valueChanged(double)), this, SLOT(updateYMin(double)));
  connect(yMax_, SIGNAL(valueChanged(double)), this, SLOT(updateYMax(double)));
  connect(yLog_, SIGNAL(toggled(bool)), this, SLOT(updateYLog(bool)));
}

//-----------------------------------------------------------------------------
PlotGapWidget::~PlotGapWidget()
{

}

//-----------------------------------------------------------------------------
void PlotGapWidget::addCurve(std::list<int> x_values, std::list<double> y_values,
                             QString name, QColor color)
{
  int elements_list = x_values.size();
  double* x_values_array = new double[elements_list];
  double* y_values_array = new double[elements_list];

//  // skip first element
//  if (*(x_values.begin()) == 0)
//  {
//    x_values.pop_front();
//    y_values.pop_front();
//  }

  // copy
  std::list<int>::iterator itx;
  int count = 1;
  for ( itx=x_values.begin() ; itx != x_values.end(); itx++ )
  {
    x_values_array[elements_list-count] = *itx;
    count++;
  }
  count = 1;

 std::list<double>::iterator ity;
  for ( ity=y_values.begin() ; ity != y_values.end(); ity++ )
  {
    y_values_array[elements_list-count] = *ity;
    count++;
  }

  printf("OOOOOOOOOOOOOOOOOOOOOOOOO\n");
  for (int i=0; i<count-1; i++)
  {
    printf("(x,y): %f, %f\n", x_values_array[i], y_values_array[i]);
  }
  printf("OOOOOOOOOOOOOOOOOOOOOOOOO\n");

  addCurve(x_values_array, y_values_array, elements_list, name, color);

  delete x_values_array;
  delete y_values_array;
}

//-----------------------------------------------------------------------------
void PlotGapWidget::addCurve(std::list<double> x_values, std::list<double> y_values,
                             QString name, QColor color)
{
  int elements_list = x_values.size();
  double* x_values_array = new double[elements_list];
  double* y_values_array = new double[elements_list];

//  // skip first element
//  if (*(x_values.begin()) == 0)
//  {
//    x_values.pop_front();
//    y_values.pop_front();
//  }

  std::list<double>::iterator it;
  int count = 1;
  for ( it=x_values.begin() ; it != x_values.end(); it++ )
  {
    x_values_array[elements_list-count] = *it;
    count++;
  }
  count = 1;

  for ( it=y_values.begin() ; it != y_values.end(); it++ )
  {
    y_values_array[elements_list-count] = *it;
    count++;
  }

  printf("########################\n");
  for (int i=0; i<count-1; i++)
  {
    printf("(x,y): %f, %f\n", x_values_array[i], y_values_array[i]);
  }
  printf("########################\n");

  addCurve(x_values_array, y_values_array, elements_list, name, color);

  delete x_values_array;
  delete y_values_array;
}

//-----------------------------------------------------------------------------
void PlotGapWidget::addCurve(double* x_values_array, double* y_values_array,
                             int elements_list, QString name, QColor color)
{
  QwtPlotCurve *curveDual = new QwtPlotCurve(name);
  curveDual->setPen(QPen(color));
  curveDual->setSamples(x_values_array, y_values_array, elements_list);
  curveDual->attach(myPlot_);

  myPlot_->setAxisAutoScale(QwtPlot::xBottom);
  myPlot_->setAxisAutoScale(QwtPlot::yLeft);

  myPlot_->replot();

#if (QWT_VERSION >= 0x050200)
  double xmin = myPlot_->axisScaleDiv(QwtPlot::xBottom)->lowerBound();
  double xmax = myPlot_->axisScaleDiv(QwtPlot::xBottom)->upperBound();
  double ymin = myPlot_->axisScaleDiv(QwtPlot::yLeft)->lowerBound();
  double ymax = myPlot_->axisScaleDiv(QwtPlot::yLeft)->upperBound();
#else
  double xmin = myPlot_->axisScaleDiv(QwtPlot::xBottom)->lBound();
  double xmax = myPlot_->axisScaleDiv(QwtPlot::xBottom)->hBound();
  double ymin = myPlot_->axisScaleDiv(QwtPlot::yLeft)->lBound();
  double ymax = myPlot_->axisScaleDiv(QwtPlot::yLeft)->hBound();
#endif
//  xMin_->setMinimum(xmin/10.0);
//  xMin_->setMaximum(xmax*10.0);
//  xMax_->setMinimum(xmin/10.0);
//  xMax_->setMaximum(xmax*10.0);
//  yMin_->setMinimum(ymin-abs(ymax-ymin));
//  yMin_->setMaximum(ymax+abs(ymax-ymin));
//  yMax_->setMinimum(ymin-abs(ymax-ymin));
//  yMax_->setMaximum(ymax+abs(ymax-ymin));
  xMin_->setValue(xmin);
  xMax_->setValue(xmax);
  yMin_->setValue(ymin);
  yMax_->setValue(ymax);

}

//-----------------------------------------------------------------------------
void PlotGapWidget::updateXMin(double value)
{
  myPlot_->setAxisScale(QwtPlot::xBottom, xMin_->value(), xMax_->value(), 0);
  myPlot_->replot();
}

//-----------------------------------------------------------------------------
void PlotGapWidget::updateXMax(double value)
{
  myPlot_->setAxisScale(QwtPlot::xBottom, xMin_->value(), xMax_->value(), 0);
  myPlot_->replot();
}

//-----------------------------------------------------------------------------
void PlotGapWidget::updateXLog(bool value)
{
  if (value)
    myPlot_->setAxisScaleEngine(QwtPlot::xBottom, new QwtLog10ScaleEngine);
  else
    myPlot_->setAxisScaleEngine(QwtPlot::xBottom, new QwtLinearScaleEngine);
  myPlot_->replot();
}

//-----------------------------------------------------------------------------
void PlotGapWidget::updateYMin(double value)
{
  myPlot_->setAxisScale(QwtPlot::yLeft, yMin_->value(), yMax_->value(), 0);
  myPlot_->replot();
}

//-----------------------------------------------------------------------------
void PlotGapWidget::updateYMax(double value)
{
  myPlot_->setAxisScale(QwtPlot::yLeft, yMin_->value(), yMax_->value(), 0);
  myPlot_->replot();
}

//-----------------------------------------------------------------------------
void PlotGapWidget::updateYLog(bool value)
{
  if (value)
    myPlot_->setAxisScaleEngine(QwtPlot::yLeft, new QwtLog10ScaleEngine);
  else
    myPlot_->setAxisScaleEngine(QwtPlot::yLeft, new QwtLinearScaleEngine);
  myPlot_->replot();
}

} // namespace iu

<commit_msg><commit_after>// includes, Qwt
#include <qwt_plot.h>
#include <qwt_plot_curve.h>
#include <qwt_scale_engine.h>

// System Includes
#include <iostream>

// include local
#include "plotgapwidget.h"

// QT
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QSpacerItem>

namespace iu {

//-----------------------------------------------------------------------------
PlotGapWidget::PlotGapWidget(QWidget* parent, bool x_log_scale, bool y_log_scale)
  :QWidget(parent)
{
  myPlot_ = new QwtPlot(0);
  int numDecimals = 2;

  myPlot_->setCanvasBackground(QColor(255,255,255));
  if (x_log_scale)
    myPlot_->setAxisScaleEngine(QwtPlot::xBottom, new QwtLog10ScaleEngine);
  if (y_log_scale)
    myPlot_->setAxisScaleEngine(QwtPlot::yLeft, new QwtLog10ScaleEngine);

  QHBoxLayout* controlLayout = new QHBoxLayout(NULL);

  QLabel* yMinLabel = new QLabel;
  yMinLabel->setText("Y-Axis");
  controlLayout->addWidget(yMinLabel);
  yMin_ = new QScienceSpinBox;
  yMin_->setDecimals(numDecimals);
  controlLayout->addWidget(yMin_);

  yMax_ = new QScienceSpinBox;
  yMax_->setDecimals(numDecimals);
  controlLayout->addWidget(yMax_);

  yLog_ = new QCheckBox();
  yLog_->setText("Log scale");
  if (y_log_scale)
    yLog_->setChecked(true);
  else
    yLog_->setChecked(false);
  controlLayout->addWidget(yLog_);

  controlLayout->insertStretch(4);

  QLabel* xMinLabel = new QLabel;
  xMinLabel->setText("X-Axis");
  controlLayout->addWidget(xMinLabel);
  xMin_ = new QScienceSpinBox;
  xMin_->setDecimals(numDecimals);
  controlLayout->addWidget(xMin_);

  xMax_ = new QScienceSpinBox;
  xMax_->setDecimals(numDecimals);
  controlLayout->addWidget(xMax_);

  xLog_ = new QCheckBox;
  xLog_->setText("Log scale");
  if (x_log_scale)
    xLog_->setChecked(true);
  else
    xLog_->setChecked(false);
  controlLayout->addWidget(xLog_);

  QVBoxLayout* mainLayout = new QVBoxLayout(this);
  mainLayout->addLayout(controlLayout);
  mainLayout->addWidget(myPlot_);
  this->setLayout(mainLayout);

  myPlot_->replot();

  // make some connections
  connect(xMin_, SIGNAL(valueChanged(double)), this, SLOT(updateXMin(double)));
  connect(xMax_, SIGNAL(valueChanged(double)), this, SLOT(updateXMax(double)));
  connect(xLog_, SIGNAL(toggled(bool)), this, SLOT(updateXLog(bool)));
  connect(yMin_, SIGNAL(valueChanged(double)), this, SLOT(updateYMin(double)));
  connect(yMax_, SIGNAL(valueChanged(double)), this, SLOT(updateYMax(double)));
  connect(yLog_, SIGNAL(toggled(bool)), this, SLOT(updateYLog(bool)));
}

//-----------------------------------------------------------------------------
PlotGapWidget::~PlotGapWidget()
{

}

//-----------------------------------------------------------------------------
void PlotGapWidget::addCurve(std::list<int> x_values, std::list<double> y_values,
                             QString name, QColor color)
{
  int elements_list = x_values.size();
  double* x_values_array = new double[elements_list];
  double* y_values_array = new double[elements_list];

//  // skip first element
//  if (*(x_values.begin()) == 0)
//  {
//    x_values.pop_front();
//    y_values.pop_front();
//  }

  // copy
  std::list<int>::iterator itx;
  int count = 1;
  for ( itx=x_values.begin() ; itx != x_values.end(); itx++ )
  {
    x_values_array[elements_list-count] = *itx;
    count++;
  }
  count = 1;

 std::list<double>::iterator ity;
  for ( ity=y_values.begin() ; ity != y_values.end(); ity++ )
  {
    y_values_array[elements_list-count] = *ity;
    count++;
  }

  printf("OOOOOOOOOOOOOOOOOOOOOOOOO\n");
  for (int i=0; i<count-1; i++)
  {
    printf("(x,y): %f, %f\n", x_values_array[i], y_values_array[i]);
  }
  printf("OOOOOOOOOOOOOOOOOOOOOOOOO\n");

  addCurve(x_values_array, y_values_array, elements_list, name, color);

  delete x_values_array;
  delete y_values_array;
}

//-----------------------------------------------------------------------------
void PlotGapWidget::addCurve(std::list<double> x_values, std::list<double> y_values,
                             QString name, QColor color)
{
  int elements_list = x_values.size();
  double* x_values_array = new double[elements_list];
  double* y_values_array = new double[elements_list];

//  // skip first element
//  if (*(x_values.begin()) == 0)
//  {
//    x_values.pop_front();
//    y_values.pop_front();
//  }

  std::list<double>::iterator it;
  int count = 1;
  for ( it=x_values.begin() ; it != x_values.end(); it++ )
  {
    x_values_array[elements_list-count] = *it;
    count++;
  }
  count = 1;

  for ( it=y_values.begin() ; it != y_values.end(); it++ )
  {
    y_values_array[elements_list-count] = *it;
    count++;
  }

  printf("########################\n");
  for (int i=0; i<count-1; i++)
  {
    printf("(x,y): %f, %f\n", x_values_array[i], y_values_array[i]);
  }
  printf("########################\n");

  addCurve(x_values_array, y_values_array, elements_list, name, color);

  delete x_values_array;
  delete y_values_array;
}

//-----------------------------------------------------------------------------
void PlotGapWidget::addCurve(double* x_values_array, double* y_values_array,
                             int elements_list, QString name, QColor color)
{
  QwtPlotCurve *curveDual = new QwtPlotCurve(name);
  curveDual->setPen(QPen(color));

#if QWT_VERSION < 0x060000
    curveDual->setData(x_values_array, y_values_array, elements_list);
#else
    curveDual->setSamples(x_values_array, y_values_array, elements_list);
#endif

  curveDual->attach(myPlot_);

  myPlot_->setAxisAutoScale(QwtPlot::xBottom);
  myPlot_->setAxisAutoScale(QwtPlot::yLeft);

  myPlot_->replot();

#if (QWT_VERSION >= 0x050200)
  double xmin = myPlot_->axisScaleDiv(QwtPlot::xBottom)->lowerBound();
  double xmax = myPlot_->axisScaleDiv(QwtPlot::xBottom)->upperBound();
  double ymin = myPlot_->axisScaleDiv(QwtPlot::yLeft)->lowerBound();
  double ymax = myPlot_->axisScaleDiv(QwtPlot::yLeft)->upperBound();
#else
  double xmin = myPlot_->axisScaleDiv(QwtPlot::xBottom)->lBound();
  double xmax = myPlot_->axisScaleDiv(QwtPlot::xBottom)->hBound();
  double ymin = myPlot_->axisScaleDiv(QwtPlot::yLeft)->lBound();
  double ymax = myPlot_->axisScaleDiv(QwtPlot::yLeft)->hBound();
#endif
//  xMin_->setMinimum(xmin/10.0);
//  xMin_->setMaximum(xmax*10.0);
//  xMax_->setMinimum(xmin/10.0);
//  xMax_->setMaximum(xmax*10.0);
//  yMin_->setMinimum(ymin-abs(ymax-ymin));
//  yMin_->setMaximum(ymax+abs(ymax-ymin));
//  yMax_->setMinimum(ymin-abs(ymax-ymin));
//  yMax_->setMaximum(ymax+abs(ymax-ymin));
  xMin_->setValue(xmin);
  xMax_->setValue(xmax);
  yMin_->setValue(ymin);
  yMax_->setValue(ymax);

}

//-----------------------------------------------------------------------------
void PlotGapWidget::updateXMin(double value)
{
  myPlot_->setAxisScale(QwtPlot::xBottom, xMin_->value(), xMax_->value(), 0);
  myPlot_->replot();
}

//-----------------------------------------------------------------------------
void PlotGapWidget::updateXMax(double value)
{
  myPlot_->setAxisScale(QwtPlot::xBottom, xMin_->value(), xMax_->value(), 0);
  myPlot_->replot();
}

//-----------------------------------------------------------------------------
void PlotGapWidget::updateXLog(bool value)
{
  if (value)
    myPlot_->setAxisScaleEngine(QwtPlot::xBottom, new QwtLog10ScaleEngine);
  else
    myPlot_->setAxisScaleEngine(QwtPlot::xBottom, new QwtLinearScaleEngine);
  myPlot_->replot();
}

//-----------------------------------------------------------------------------
void PlotGapWidget::updateYMin(double value)
{
  myPlot_->setAxisScale(QwtPlot::yLeft, yMin_->value(), yMax_->value(), 0);
  myPlot_->replot();
}

//-----------------------------------------------------------------------------
void PlotGapWidget::updateYMax(double value)
{
  myPlot_->setAxisScale(QwtPlot::yLeft, yMin_->value(), yMax_->value(), 0);
  myPlot_->replot();
}

//-----------------------------------------------------------------------------
void PlotGapWidget::updateYLog(bool value)
{
  if (value)
    myPlot_->setAxisScaleEngine(QwtPlot::yLeft, new QwtLog10ScaleEngine);
  else
    myPlot_->setAxisScaleEngine(QwtPlot::yLeft, new QwtLinearScaleEngine);
  myPlot_->replot();
}

} // namespace iu

<|endoftext|>


<commit_before><commit_msg>Add a support to NPN_PostUrl[Notify] using files<commit_after><|endoftext|>


<commit_before>
#define BOOST_TEST_MAIN
#define BOOST_TEST_MODULE DemuxerTest
#include <boost/test/unit_test.hpp>
#include <iostream>
#include "Demuxer.hpp"
#include "Timer.hpp"
#include "Utilities.hpp"
#include <SFML/Audio.hpp>

class DummyDelegate : public sfe::VideoStream::Delegate, public sfe::SubtitleStream::Delegate {
	void didUpdateVideo(const sfe::VideoStream& sender, const sf::Texture& image)
	{
	}

    void didUpdateSubtitle(const sfe::SubtitleStream& sender,
                           const std::list<sf::Sprite>& subimages,
                           const std::list<sf::Vector2i>& positions)
    {
    }

    void didWipeOutSubtitles(const sfe::SubtitleStream& sender)
    {
    }

};

static DummyDelegate delegate;

BOOST_AUTO_TEST_CASE(DemuxerAvailableCodecsTest)
{
	BOOST_CHECK(!sfe::Demuxer::getAvailableDemuxers().empty());
	BOOST_CHECK(!sfe::Demuxer::getAvailableDecoders().empty());
}

BOOST_AUTO_TEST_CASE(DemuxerLoadingTest)
{
	sfe::Demuxer *demuxer = NULL;
	sfe::Timer timer;
	BOOST_CHECK_THROW(demuxer = new sfe::Demuxer("non-existing-file.ogv", timer, delegate, delegate), std::runtime_error);
	BOOST_CHECK_NO_THROW(demuxer = new sfe::Demuxer("small_1.ogv", timer, delegate, delegate));
	BOOST_REQUIRE(demuxer != NULL);

	const std::map<int, sfe::Stream*>& streams = demuxer->getStreams();

	BOOST_CHECK(streams.size() > 0);

	unsigned videoStreamCount = 0;
	unsigned audioStreamCount = 0;

	std::map<int, sfe::Stream*>::const_iterator it;

	// Check found streams
	for (it = streams.begin(); it != streams.end(); it++) {
		sfe::Stream* stream = it->second;

		switch (stream->getStreamKind()) {
			case sfe::Video:
				videoStreamCount++;
				break;
			case sfe::Audio:
				audioStreamCount++;
				break;
			default:
				std::cout << "unknown stream kind" << std::endl;
		}
	}

	BOOST_CHECK(videoStreamCount == 1);
	BOOST_CHECK(audioStreamCount == 1);

	// Check stream feeding
	for (it = streams.begin(); it != streams.end(); it++) {
		BOOST_CHECK(it->second->needsMoreData());
		BOOST_CHECK(demuxer->didReachEndOfFile() == false);
		demuxer->feedStream(*it->second);
		BOOST_CHECK(demuxer->didReachEndOfFile() == false);
		BOOST_CHECK(it->second->needsMoreData() == false);
	}
}

BOOST_AUTO_TEST_CASE(DemuxerShortOGVTest)
{
	sfe::Demuxer *demuxer = NULL;
	sfe::Timer timer;
	sf::Clock clock;
	demuxer = new sfe::Demuxer("small_1.ogv", timer, delegate, delegate);
	demuxer->selectFirstVideoStream();
	demuxer->selectFirstAudioStream();

	sfe::Stream* videoStream = *demuxer->getStreamsOfType(sfe::Video).begin();
	sfe::Stream* audioStream = *demuxer->getStreamsOfType(sfe::Audio).begin();

	BOOST_CHECK(demuxer->didReachEndOfFile() == false);
	BOOST_CHECK(videoStream->getStatus() == sfe::Stopped);
	BOOST_CHECK(audioStream->getStatus() == sfe::Stopped);
	timer.play();
	demuxer->update();
	BOOST_CHECK(demuxer->didReachEndOfFile() == false);
	BOOST_CHECK(videoStream->getStatus() == sfe::Playing);
	BOOST_CHECK(audioStream->getStatus() == sfe::Playing);

	clock.restart();
	while (clock.getElapsedTime() < sf::seconds(8)) {
		demuxer->update();
		sf::sleep(sf::milliseconds(10));
	}

	BOOST_CHECK(demuxer->didReachEndOfFile() == true);
	BOOST_CHECK(videoStream->getStatus() == sfe::Stopped);
	BOOST_CHECK(audioStream->getStatus() == sfe::Stopped);
}

BOOST_AUTO_TEST_CASE(DemuxerShortWAVTest)
{
	sfe::Demuxer *demuxer = NULL;
	sfe::Timer timer;
	demuxer = new sfe::Demuxer("small_4.wav", timer, delegate, delegate);
	demuxer->selectFirstVideoStream();
	demuxer->selectFirstAudioStream();

	sfe::Stream* audioStream = *demuxer->getStreamsOfType(sfe::Audio).begin();

	BOOST_CHECK(demuxer->didReachEndOfFile() == false);
	BOOST_CHECK(audioStream->getStatus() == sfe::Stopped);
	timer.play();
	demuxer->update();
	BOOST_CHECK(demuxer->didReachEndOfFile() == false);
	BOOST_CHECK(audioStream->getStatus() == sfe::Playing);
	sf::sleep(sf::seconds(4));
	demuxer->update();
	BOOST_CHECK(demuxer->didReachEndOfFile() == true);
	BOOST_CHECK(audioStream->getStatus() == sfe::Stopped);
}

BOOST_AUTO_TEST_CASE(DemuxerLongWAVTest)
{
	sfe::Demuxer *demuxer = NULL;
	sfe::Timer timer;
	demuxer = new sfe::Demuxer("long_1.wav", timer, delegate, delegate);
	demuxer->selectFirstVideoStream();
	demuxer->selectFirstAudioStream();

	sfe::Stream* audioStream = *demuxer->getStreamsOfType(sfe::Audio).begin();

	BOOST_CHECK(demuxer->didReachEndOfFile() == false);
	BOOST_CHECK(audioStream->getStatus() == sfe::Stopped);
	timer.play();
	demuxer->update();
	BOOST_CHECK(demuxer->didReachEndOfFile() == false);
	BOOST_CHECK(audioStream->getStatus() == sfe::Playing);
	sf::sleep(sf::seconds(30));
	demuxer->update();
	BOOST_CHECK(demuxer->didReachEndOfFile() == true);
	BOOST_CHECK(audioStream->getStatus() == sfe::Stopped);
}

BOOST_AUTO_TEST_CASE(DemuxerShortMP3Test)
{
	sfe::Demuxer *demuxer = NULL;
	sfe::Timer timer;
	// With free codecs only, the demuxer is not supposed to be able to load MP3 medias

	BOOST_CHECK_THROW(demuxer = new sfe::Demuxer("small_2.mp3", timer, delegate, delegate), std::runtime_error);
}

BOOST_AUTO_TEST_CASE(DemuxerShortFLACTest)
{
	sfe::Demuxer *demuxer = NULL;
	sfe::Timer timer;
	demuxer = new sfe::Demuxer("small_3.flac", timer, delegate, delegate);
	demuxer->selectFirstVideoStream();
	demuxer->selectFirstAudioStream();

	sfe::Stream* audioStream = *demuxer->getStreamsOfType(sfe::Audio).begin();

	BOOST_CHECK(demuxer->didReachEndOfFile() == false);
	BOOST_CHECK(audioStream->getStatus() == sfe::Stopped);
	timer.play();
	demuxer->update();
	BOOST_CHECK(demuxer->didReachEndOfFile() == false);
	BOOST_CHECK(audioStream->getStatus() == sfe::Playing);
	sf::sleep(sf::seconds(5));
	demuxer->update();
	BOOST_CHECK(demuxer->didReachEndOfFile() == true);
	BOOST_CHECK(audioStream->getStatus() == sfe::Stopped);
}
<commit_msg>#65 Fix test with move to shared_ptr<commit_after>
#define BOOST_TEST_MAIN
#define BOOST_TEST_MODULE DemuxerTest
#include <boost/test/unit_test.hpp>
#include <iostream>
#include "Demuxer.hpp"
#include "Timer.hpp"
#include "Utilities.hpp"
#include <SFML/Audio.hpp>

class DummyDelegate : public sfe::VideoStream::Delegate, public sfe::SubtitleStream::Delegate {
	void didUpdateVideo(const sfe::VideoStream& sender, const sf::Texture& image)
	{
	}

    void didUpdateSubtitle(const sfe::SubtitleStream& sender,
                           const std::list<sf::Sprite>& subimages,
                           const std::list<sf::Vector2i>& positions)
    {
    }

    void didWipeOutSubtitles(const sfe::SubtitleStream& sender)
    {
    }

};

static DummyDelegate delegate;

BOOST_AUTO_TEST_CASE(DemuxerAvailableCodecsTest)
{
	BOOST_CHECK(!sfe::Demuxer::getAvailableDemuxers().empty());
	BOOST_CHECK(!sfe::Demuxer::getAvailableDecoders().empty());
}

BOOST_AUTO_TEST_CASE(DemuxerLoadingTest)
{
    std::shared_ptr<sfe::Demuxer> demuxer;
    std::shared_ptr<sfe::Timer> timer = std::make_shared<sfe::Timer>();
    BOOST_CHECK_THROW(demuxer = std::make_shared<sfe::Demuxer>("non-existing-file.ogv", timer, delegate, delegate), std::runtime_error);
    BOOST_CHECK_NO_THROW(demuxer = std::make_shared<sfe::Demuxer>("small_1.ogv", timer, delegate, delegate));
	BOOST_REQUIRE(demuxer != NULL);

	const std::map<int, std::shared_ptr<sfe::Stream> >& streams = demuxer->getStreams();

	BOOST_CHECK(streams.size() > 0);

	unsigned videoStreamCount = 0;
	unsigned audioStreamCount = 0;

	std::map<int, std::shared_ptr<sfe::Stream> >::const_iterator it;

	// Check found streams
	for (it = streams.begin(); it != streams.end(); it++) {
		std::shared_ptr<sfe::Stream> stream = it->second;

		switch (stream->getStreamKind()) {
			case sfe::Video:
				videoStreamCount++;
				break;
			case sfe::Audio:
				audioStreamCount++;
				break;
			default:
				std::cout << "unknown stream kind" << std::endl;
		}
	}

	BOOST_CHECK(videoStreamCount == 1);
	BOOST_CHECK(audioStreamCount == 1);

	// Check stream feeding
	for (it = streams.begin(); it != streams.end(); it++) {
		BOOST_CHECK(it->second->needsMoreData());
		BOOST_CHECK(demuxer->didReachEndOfFile() == false);
		demuxer->feedStream(*it->second);
		BOOST_CHECK(demuxer->didReachEndOfFile() == false);
		BOOST_CHECK(it->second->needsMoreData() == false);
	}
}

BOOST_AUTO_TEST_CASE(DemuxerShortOGVTest)
{
	std::shared_ptr<sfe::Demuxer> demuxer;
    std::shared_ptr<sfe::Timer> timer = std::make_shared<sfe::Timer>();
	sf::Clock clock;
    demuxer = std::make_shared<sfe::Demuxer>("small_1.ogv", timer, delegate, delegate);
	demuxer->selectFirstVideoStream();
	demuxer->selectFirstAudioStream();

	std::shared_ptr<sfe::Stream> videoStream = *demuxer->getStreamsOfType(sfe::Video).begin();
	std::shared_ptr<sfe::Stream> audioStream = *demuxer->getStreamsOfType(sfe::Audio).begin();

	BOOST_CHECK(demuxer->didReachEndOfFile() == false);
	BOOST_CHECK(videoStream->getStatus() == sfe::Stopped);
	BOOST_CHECK(audioStream->getStatus() == sfe::Stopped);
	timer->play();
	demuxer->update();
	BOOST_CHECK(demuxer->didReachEndOfFile() == false);
	BOOST_CHECK(videoStream->getStatus() == sfe::Playing);
	BOOST_CHECK(audioStream->getStatus() == sfe::Playing);

	clock.restart();
	while (clock.getElapsedTime() < sf::seconds(8)) {
		demuxer->update();
		sf::sleep(sf::milliseconds(10));
	}

	BOOST_CHECK(demuxer->didReachEndOfFile() == true);
	BOOST_CHECK(videoStream->getStatus() == sfe::Stopped);
	BOOST_CHECK(audioStream->getStatus() == sfe::Stopped);
}

BOOST_AUTO_TEST_CASE(DemuxerShortWAVTest)
{
	std::shared_ptr<sfe::Demuxer> demuxer;
    std::shared_ptr<sfe::Timer> timer = std::make_shared<sfe::Timer>();
    demuxer = std::make_shared<sfe::Demuxer>("small_4.wav", timer, delegate, delegate);
	demuxer->selectFirstVideoStream();
	demuxer->selectFirstAudioStream();

	std::shared_ptr<sfe::Stream> audioStream = *demuxer->getStreamsOfType(sfe::Audio).begin();

	BOOST_CHECK(demuxer->didReachEndOfFile() == false);
	BOOST_CHECK(audioStream->getStatus() == sfe::Stopped);
	timer->play();
	demuxer->update();
	BOOST_CHECK(demuxer->didReachEndOfFile() == false);
	BOOST_CHECK(audioStream->getStatus() == sfe::Playing);
	sf::sleep(sf::seconds(4));
	demuxer->update();
	BOOST_CHECK(demuxer->didReachEndOfFile() == true);
	BOOST_CHECK(audioStream->getStatus() == sfe::Stopped);
}

BOOST_AUTO_TEST_CASE(DemuxerLongWAVTest)
{
    std::shared_ptr<sfe::Demuxer> demuxer;
    std::shared_ptr<sfe::Timer> timer = std::make_shared<sfe::Timer>();
	demuxer = std::make_shared<sfe::Demuxer>("long_1.wav", timer, delegate, delegate);
	demuxer->selectFirstVideoStream();
	demuxer->selectFirstAudioStream();

	std::shared_ptr<sfe::Stream> audioStream = *demuxer->getStreamsOfType(sfe::Audio).begin();

	BOOST_CHECK(demuxer->didReachEndOfFile() == false);
	BOOST_CHECK(audioStream->getStatus() == sfe::Stopped);
	timer->play();
	demuxer->update();
	BOOST_CHECK(demuxer->didReachEndOfFile() == false);
	BOOST_CHECK(audioStream->getStatus() == sfe::Playing);
	sf::sleep(sf::seconds(30));
	demuxer->update();
	BOOST_CHECK(demuxer->didReachEndOfFile() == true);
	BOOST_CHECK(audioStream->getStatus() == sfe::Stopped);
}

BOOST_AUTO_TEST_CASE(DemuxerShortMP3Test)
{
    std::shared_ptr<sfe::Demuxer> demuxer;
    std::shared_ptr<sfe::Timer> timer = std::make_shared<sfe::Timer>();
	// With free codecs only, the demuxer is not supposed to be able to load MP3 medias

	BOOST_CHECK_THROW(demuxer = std::make_shared<sfe::Demuxer>("small_2.mp3", timer, delegate, delegate), std::runtime_error);
}

BOOST_AUTO_TEST_CASE(DemuxerShortFLACTest)
{
    std::shared_ptr<sfe::Demuxer> demuxer;
    std::shared_ptr<sfe::Timer> timer = std::make_shared<sfe::Timer>();
	demuxer = std::make_shared<sfe::Demuxer>("small_3.flac", timer, delegate, delegate);
	demuxer->selectFirstVideoStream();
	demuxer->selectFirstAudioStream();

	std::shared_ptr<sfe::Stream> audioStream = *demuxer->getStreamsOfType(sfe::Audio).begin();

	BOOST_CHECK(demuxer->didReachEndOfFile() == false);
	BOOST_CHECK(audioStream->getStatus() == sfe::Stopped);
	timer->play();
	demuxer->update();
	BOOST_CHECK(demuxer->didReachEndOfFile() == false);
	BOOST_CHECK(audioStream->getStatus() == sfe::Playing);
	sf::sleep(sf::seconds(5));
	demuxer->update();
	BOOST_CHECK(demuxer->didReachEndOfFile() == true);
	BOOST_CHECK(audioStream->getStatus() == sfe::Stopped);
}
<|endoftext|>


<commit_before>#include <iostream>
#include <chrono>
#include "higher-order-energy.hpp"
#include "QPBO.h"
#include "gen-random.hpp"
#include "submodular-flow.hpp"
#include "submodular-ibfs.hpp"
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include <fstream>

int main(int argc, char **argv) {
    if (argc != 2) {
        std::cout << "Usage: recover-crash crashfile\n";
        exit(-1);
    }

    SubmodularIBFS ibfs;
    std::ifstream ifs(argv[1]);
    boost::archive::binary_iarchive ar(ifs);
    ar & ibfs;
    ibfs.IBFS();
    ibfs.ComputeMinCut();
    std::cout << "IBFS Energy: " << ibfs.ComputeEnergy() << "\n";

    return 0;
}
<commit_msg>Removing recover-crash.cpp<commit_after><|endoftext|>


<commit_before>// Copyright (c) 2020 The Orbit 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 "absl/flags/flag.h"
#include "absl/flags/parse.h"

#include "ClientGgp.h"
#include "OrbitBase/ThreadPool.h"

ABSL_FLAG(uint64_t, grpc_port, 44765, "Grpc service's port");
ABSL_FLAG(int32_t, pid, 0, "pid to capture");
ABSL_FLAG(uint32_t, capture_length, 10, "duration of capture in seconds");
ABSL_FLAG(uint16_t, sampling_rate, 1000,
          "Frequency of callstack sampling in samples per second");
ABSL_FLAG(bool, frame_pointer_unwinding, false,
          "Use frame pointers for unwinding");

int main(int argc, char** argv) {
  absl::ParseCommandLine(argc, argv);
  uint64_t grpc_port_ = absl::GetFlag(FLAGS_grpc_port);
  uint32_t capture_length = absl::GetFlag(FLAGS_capture_length);

  if (!absl::GetFlag(FLAGS_pid)) {
    ERROR("pid to capture not provided; set using -pid");
    return -1;
  }

  ClientGgpOptions options;
  options.grpc_server_address =
        absl::StrFormat("127.0.0.1:%d", grpc_port_);
  options.capture_pid = absl::GetFlag(FLAGS_pid);

  ClientGgp client_ggp(std::move(options));
  if (!client_ggp.InitClient()){
    return -1;
  }

  LOG("Lets start the capture");

  if(!client_ggp.PrepareStartCapture()){
    return -1;
  }

  std::unique_ptr<ThreadPool> thread_pool = ThreadPool::Create(4 /*min_size*/, 256 /*max_size*/, absl::Seconds(1));

  // The request is done in a separate thread to avoid blocking main()
  thread_pool->Schedule([&]() {
    client_ggp.RequestStartCapture();
  });

  LOG("Go to sleep");
  // Captures for the period of time requested
  sleep(capture_length);
  LOG("Back from sleep");

  client_ggp.StopCapture();

  LOG("Shuting down the thread pool");
  thread_pool->ShutdownAndWait();

  //TODO: process/save capture data

  LOG("All done");
  return 0;
}<commit_msg>Fix OrbitClientGgp/main.cpp with suggestions<commit_after>// Copyright (c) 2020 The Orbit 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 "absl/flags/flag.h"
#include "absl/flags/parse.h"

#include "ClientGgp.h"

ABSL_FLAG(uint64_t, grpc_port, 44765, "Grpc service's port");
ABSL_FLAG(int32_t, pid, 0, "pid to capture");
ABSL_FLAG(uint32_t, capture_length, 10, "duration of capture in seconds");
ABSL_FLAG(uint16_t, sampling_rate, 1000,
          "Frequency of callstack sampling in samples per second");
ABSL_FLAG(bool, frame_pointer_unwinding, false,
          "Use frame pointers for unwinding");

int main(int argc, char** argv) {
  absl::ParseCommandLine(argc, argv);
  uint64_t grpc_port = absl::GetFlag(FLAGS_grpc_port);
  uint32_t capture_length = absl::GetFlag(FLAGS_capture_length);

  if (!absl::GetFlag(FLAGS_pid)) {
    FATAL("pid to capture not provided; set using -pid");
  }

  ClientGgpOptions options;
  options.grpc_server_address = absl::StrFormat("127.0.0.1:%d", grpc_port);
  options.capture_pid = absl::GetFlag(FLAGS_pid);

  ClientGgp client_ggp(std::move(options));
  if (!client_ggp.InitClient()){
    return -1;
  }

  LOG("Let's start the capture");

  if(!client_ggp.PrepareStartCapture()){
    return -1;
  }

  std::thread client_thread;

  // The request is done in a separate thread to avoid blocking main()
  client_thread = std::thread([&]() {
    client_ggp.RequestStartCapture();
  });

  LOG("Go to sleep");
  // Captures for the period of time requested
  absl::SleepFor(absl::Seconds(capture_length));
  LOG("Back from sleep");

  client_ggp.StopCapture();

  LOG("Shut down the thread and wait for it to finish");
  client_thread.join();

  //TODO: process/save capture data

  LOG("All done");
  return 0;
}<|endoftext|>


<commit_before>#include <libport/unit-test.hh>
#include <libport/sysexits.hh>
using libport::test_suite;

#ifndef LIBPORT_NO_SSL
# define LIBPORT_NO_SSL
#endif

#include <libport/asio.hh>
#include <libport/utime.hh>
#include <libport/unistd.h>

bool abort_ctor = false;

const char* msg = "coincoin\n";

template<class T>
void
hold_for(T, libport::utime_t duration)
{
  usleep(duration);
  BOOST_TEST_MESSAGE("Done holding your T");
}

void
delayed_response(boost::shared_ptr<libport::UDPLink> l,
                 libport::utime_t duration)
{
  usleep(duration);
  l->reply("hop hop\n");
}

// Hack until we can kill listenig sockets.
static bool enable_delay = false;
void reply_delay(const void*, int,
                 boost::shared_ptr<libport::UDPLink> l,
                 libport::utime_t duration)
{
  libport::startThread(boost::bind(&delayed_response, l, duration));
}

void echo(const void* d, int s, boost::shared_ptr<libport::UDPLink> l)
{
  if (enable_delay)
    reply_delay(d, s, l, 500000);
  else
    l->reply(d, s);
}

class TestSocket: public libport::Socket
{
  public:
  TestSocket()
    : nRead(0), echo(false), dump(false)
    {
      BOOST_CHECK(!abort_ctor);
      nInstance++;
    }
  TestSocket(bool echo, bool dump)
    : nRead(0), echo(echo), dump(dump)
    {
      BOOST_CHECK(!abort_ctor);
      nInstance++;
    }
  virtual ~TestSocket()
  {
    nInstance--;
    //BOOST_TEST_MESSAGE(this <<" dying, in " << K_get() << " lasterror=" << lastError.message());
    //assert(false);
  }

  int onRead(const void* data, size_t size)
  {
    nRead++;
    //BOOST_TEST_MESSAGE(this << " read " << size);
    if (echo)
      write(data, size);
    if (dump)
      received += std::string((const char*)data, size);
    return size;
  }

  void onError(boost::system::error_code erc)
  {
    lastError = erc;
    destroy();
  }
  // Number of times read callback was called
  int nRead;
  // Echo back what is received.
  bool echo;
  // Store what is received in received.
  bool dump;
  std::string received;
  boost::system::error_code lastError;
  static TestSocket* factory()
    {
      return lastInstance = new TestSocket();
    }
  static TestSocket* factoryEx(bool echo, bool dump)
    {
      return lastInstance = new TestSocket(echo, dump);
    }
  static int nInstance;
  // Last factory-created instance.
  static TestSocket* lastInstance;
};

int TestSocket::nInstance = 0;
TestSocket* TestSocket::lastInstance = 0;

// Delay in microseconds used to sleep when something asynchronous
// is happening.
static const int delay = 200000;

static const int AVAIL_PORT = 7890;
static const std::string S_AVAIL_PORT = "7890";

void test_one(bool proto)
{
  TestSocket* client = new TestSocket(false, true);
  boost::system::error_code err
    = client->connect("localhost", S_AVAIL_PORT, proto);
  BOOST_CHECK_MESSAGE(!err, err.message());
  BOOST_CHECK_NO_THROW(client->send(msg));
  usleep(delay);
  BOOST_CHECK_EQUAL(TestSocket::nInstance, proto ? 1 : 2);
  BOOST_CHECK_EQUAL(client->received, msg);
  if (!proto)
    BOOST_CHECK_EQUAL(TestSocket::lastInstance->received,
                      msg);
  BOOST_CHECK_EQUAL(client->getRemotePort(), AVAIL_PORT);
  if (!proto)
    BOOST_CHECK_EQUAL(TestSocket::lastInstance->getLocalPort(),
                      AVAIL_PORT);
  if (!proto)
    BOOST_CHECK_EQUAL(TestSocket::lastInstance->getRemotePort(),
                      client->getLocalPort());
  // Close client-end. Should send error both ways and destroy all sockets.
  client->close();
  usleep(delay);
  BOOST_CHECK_EQUAL(TestSocket::nInstance, 0);
}

static
void
test()
{
  // Basic TCP
  BOOST_TEST_MESSAGE("##Safe destruction");
  boost::system::error_code err;
  TestSocket* s = new TestSocket(false, false);
  s->connect("localhost", S_AVAIL_PORT, false);
  s->destroy();
  usleep(delay);
  libport::resolve<boost::asio::ip::tcp>("localhost", S_AVAIL_PORT, err);
  libport::Socket* h = new libport::Socket();
  err = h->listen(
      boost::bind(&TestSocket::factoryEx, true, true), "", S_AVAIL_PORT, false);
  BOOST_CHECK_MESSAGE(!err, err.message());
  BOOST_CHECK_EQUAL(h->getLocalPort(), AVAIL_PORT);

  BOOST_TEST_MESSAGE("##One client");
  libport::resolve<boost::asio::ip::tcp>("localhost", S_AVAIL_PORT, err);
  libport::resolve<boost::asio::ip::tcp>("localhost", S_AVAIL_PORT, err);
  libport::resolve<boost::asio::ip::tcp>("localhost", S_AVAIL_PORT, err);
  libport::resolve<boost::asio::ip::tcp>("localhost", S_AVAIL_PORT, err);
  test_one(false);
  libport::resolve<boost::asio::ip::tcp>("localhost", S_AVAIL_PORT, err);
  test_one(false);
  libport::resolve<boost::asio::ip::tcp>("localhost", S_AVAIL_PORT, err);
  test_one(false);
  BOOST_TEST_MESSAGE("Socket on stack");
  {
    TestSocket s(false, true);
    err = s.connect("localhost", S_AVAIL_PORT, false);
    BOOST_CHECK_MESSAGE(!err, err.message());
    s.send(msg);
    usleep(delay);
  }
  usleep(delay*2);
  BOOST_CHECK_EQUAL(TestSocket::nInstance, 0);

  test_one(false);
  BOOST_TEST_MESSAGE("##many clients");
  std::vector<TestSocket*> clients;
  for (int i=0; i<10; i++)
  {
    TestSocket* client = new TestSocket(false, true);
    err = client->connect("localhost", S_AVAIL_PORT, false);
    BOOST_CHECK_MESSAGE(!err, err.message());
    client->send(msg);
    clients.push_back(client);
  }
  usleep(delay*3);
  BOOST_CHECK_EQUAL(TestSocket::nInstance, 20);
  foreach(TestSocket* s, clients)
  {
    BOOST_CHECK_EQUAL(s->received, msg);
    s->close();
  }
  usleep(delay*3);
  BOOST_CHECK_EQUAL(TestSocket::nInstance, 0);

  BOOST_TEST_MESSAGE("##Failing connections");
  {
    TestSocket* client = new TestSocket();
    err = client->connect("auunsinsr.nosuch.hostaufisgiu.com.", "20000", false);
    BOOST_CHECK_MESSAGE(err, err.message());

    err = client->connect("localhost", "nosuchport", false);
    BOOST_CHECK_MESSAGE(err, err.message());

    // Try to reuse that wasted socket.
    err = client->connect("localhost", S_AVAIL_PORT, false);
    BOOST_CHECK_MESSAGE(!err, err.message());
    // Destroy without closing.
    client->destroy();
    usleep(delay);
    BOOST_CHECK_EQUAL(TestSocket::nInstance, 0);
  }

  // Timeout
  BOOST_TEST_MESSAGE("##Timeout connect");
  {
    TestSocket* client = new TestSocket();
    libport::utime_t start = libport::utime();
    err = client->connect("1.1.1.1", "10000", false, 1000000);
    BOOST_CHECK_MESSAGE(err, err.message());
    libport::utime_t timeout = libport::utime() - start;
    // Give it a good margin.
    BOOST_CHECK_LT(timeout, 1400000);
    client->destroy();
  }

  BOOST_TEST_MESSAGE("##Destruction locking");
  {
    TestSocket* client = new TestSocket();
    err = client->connect("localhost", S_AVAIL_PORT, false);
    BOOST_CHECK_MESSAGE(!err, err.message());
    usleep(delay);
    libport::startThread(
      boost::bind(&hold_for<libport::Destructible::DestructionLock>,
                  client->getDestructionLock(),
                  1000000));
    client->destroy();
    usleep(500000);
    // There can be 1 or 2 sockets at this point. Client must be still alive because of the lock, but server might have died.
    BOOST_CHECK_MESSAGE(TestSocket::nInstance, TestSocket::nInstance);
    usleep(500000+delay);
    BOOST_CHECK_EQUAL(TestSocket::nInstance, 0);
  }

  BOOST_TEST_MESSAGE("Destroy listener");
  {
    h->close();
    usleep(delay);
    TestSocket* client = new TestSocket();
    abort_ctor = true;
    err = client->connect("localhost", S_AVAIL_PORT, false);
    BOOST_CHECK_MESSAGE(err, err.message());
    client->destroy();
    h->destroy();
    usleep(delay);
    abort_ctor = false;
  }

  BOOST_TEST_MESSAGE("##UDP");
  {
    libport::Socket::Handle hu =
      libport::Socket::listenUDP("", S_AVAIL_PORT, &echo, err);
    (void)hu;
    BOOST_CHECK_MESSAGE(!err, err.message());
    test_one(true);
    usleep(delay);
    test_one(true);

    TestSocket* client = new TestSocket();
    err = client->connect("auunsinsr.nosuch.hostaufisgiu.com.", "20000", true);
    BOOST_CHECK_MESSAGE(err, err.message());

    err = client->connect("localhost", "nosuchport", true);
    BOOST_CHECK_MESSAGE(err, err.message());

    // Try to reuse that wasted socket.
    err = client->connect("localhost", S_AVAIL_PORT, true);
    BOOST_CHECK_MESSAGE(!err, err.message());
    // Destroy without closing.
    client->destroy();
    usleep(delay);
    BOOST_CHECK_EQUAL(TestSocket::nInstance, 0);

    // Check one-write-one-packet semantic
    client = new TestSocket(false, true);
    err = client->connect("localhost", S_AVAIL_PORT, true);
    BOOST_CHECK_MESSAGE(!err, err.message());
    client->send("coin");
    client->send("pan");
    usleep(delay*2);
    BOOST_CHECK_EQUAL(client->received, "coinpan");
    BOOST_CHECK_EQUAL(client->nRead, 2);

    enable_delay = true;
    client = new TestSocket(false, true);
    err = client->connect("localhost", S_AVAIL_PORT, true);
    BOOST_CHECK_MESSAGE(!err, err.message());
    client->send("coin");
    usleep(500000+delay);
    BOOST_CHECK_EQUAL(client->received, "hop hop\n");
  }
}

test_suite*
init_test_suite()
{
  // This test cannot run properly with current versions of WineHQ,
  // because they only provide a stub for acceptex.
  const char* running_wine = getenv("RUNNING_WINE");
  if (running_wine && *running_wine)
    std::cerr << "running under Wine, skipping this test"
              << std::endl
              << libport::exit(EX_SKIP);

  test_suite* suite = BOOST_TEST_SUITE("libport::asio test suite");
  suite->add(BOOST_TEST_CASE(test));
  return suite;
}
<commit_msg>Skip asio test under QEmu.<commit_after>#include <libport/unit-test.hh>
#include <libport/sysexits.hh>
using libport::test_suite;

#ifndef LIBPORT_NO_SSL
# define LIBPORT_NO_SSL
#endif

#include <libport/asio.hh>
#include <libport/utime.hh>
#include <libport/unistd.h>

bool abort_ctor = false;

const char* msg = "coincoin\n";

template<class T>
void
hold_for(T, libport::utime_t duration)
{
  usleep(duration);
  BOOST_TEST_MESSAGE("Done holding your T");
}

void
delayed_response(boost::shared_ptr<libport::UDPLink> l,
                 libport::utime_t duration)
{
  usleep(duration);
  l->reply("hop hop\n");
}

// Hack until we can kill listenig sockets.
static bool enable_delay = false;
void reply_delay(const void*, int,
                 boost::shared_ptr<libport::UDPLink> l,
                 libport::utime_t duration)
{
  libport::startThread(boost::bind(&delayed_response, l, duration));
}

void echo(const void* d, int s, boost::shared_ptr<libport::UDPLink> l)
{
  if (enable_delay)
    reply_delay(d, s, l, 500000);
  else
    l->reply(d, s);
}

class TestSocket: public libport::Socket
{
  public:
  TestSocket()
    : nRead(0), echo(false), dump(false)
    {
      BOOST_CHECK(!abort_ctor);
      nInstance++;
    }
  TestSocket(bool echo, bool dump)
    : nRead(0), echo(echo), dump(dump)
    {
      BOOST_CHECK(!abort_ctor);
      nInstance++;
    }
  virtual ~TestSocket()
  {
    nInstance--;
    //BOOST_TEST_MESSAGE(this <<" dying, in " << K_get() << " lasterror=" << lastError.message());
    //assert(false);
  }

  int onRead(const void* data, size_t size)
  {
    nRead++;
    //BOOST_TEST_MESSAGE(this << " read " << size);
    if (echo)
      write(data, size);
    if (dump)
      received += std::string((const char*)data, size);
    return size;
  }

  void onError(boost::system::error_code erc)
  {
    lastError = erc;
    destroy();
  }
  // Number of times read callback was called
  int nRead;
  // Echo back what is received.
  bool echo;
  // Store what is received in received.
  bool dump;
  std::string received;
  boost::system::error_code lastError;
  static TestSocket* factory()
    {
      return lastInstance = new TestSocket();
    }
  static TestSocket* factoryEx(bool echo, bool dump)
    {
      return lastInstance = new TestSocket(echo, dump);
    }
  static int nInstance;
  // Last factory-created instance.
  static TestSocket* lastInstance;
};

int TestSocket::nInstance = 0;
TestSocket* TestSocket::lastInstance = 0;

// Delay in microseconds used to sleep when something asynchronous
// is happening.
static const int delay = 200000;

static const int AVAIL_PORT = 7890;
static const std::string S_AVAIL_PORT = "7890";

void test_one(bool proto)
{
  TestSocket* client = new TestSocket(false, true);
  boost::system::error_code err
    = client->connect("localhost", S_AVAIL_PORT, proto);
  BOOST_CHECK_MESSAGE(!err, err.message());
  BOOST_CHECK_NO_THROW(client->send(msg));
  usleep(delay);
  BOOST_CHECK_EQUAL(TestSocket::nInstance, proto ? 1 : 2);
  BOOST_CHECK_EQUAL(client->received, msg);
  if (!proto)
    BOOST_CHECK_EQUAL(TestSocket::lastInstance->received,
                      msg);
  BOOST_CHECK_EQUAL(client->getRemotePort(), AVAIL_PORT);
  if (!proto)
    BOOST_CHECK_EQUAL(TestSocket::lastInstance->getLocalPort(),
                      AVAIL_PORT);
  if (!proto)
    BOOST_CHECK_EQUAL(TestSocket::lastInstance->getRemotePort(),
                      client->getLocalPort());
  // Close client-end. Should send error both ways and destroy all sockets.
  client->close();
  usleep(delay);
  BOOST_CHECK_EQUAL(TestSocket::nInstance, 0);
}

static
void
test()
{
  // Basic TCP
  BOOST_TEST_MESSAGE("##Safe destruction");
  boost::system::error_code err;
  TestSocket* s = new TestSocket(false, false);
  s->connect("localhost", S_AVAIL_PORT, false);
  s->destroy();
  usleep(delay);
  libport::resolve<boost::asio::ip::tcp>("localhost", S_AVAIL_PORT, err);
  libport::Socket* h = new libport::Socket();
  err = h->listen(
      boost::bind(&TestSocket::factoryEx, true, true), "", S_AVAIL_PORT, false);
  BOOST_CHECK_MESSAGE(!err, err.message());
  BOOST_CHECK_EQUAL(h->getLocalPort(), AVAIL_PORT);

  BOOST_TEST_MESSAGE("##One client");
  libport::resolve<boost::asio::ip::tcp>("localhost", S_AVAIL_PORT, err);
  libport::resolve<boost::asio::ip::tcp>("localhost", S_AVAIL_PORT, err);
  libport::resolve<boost::asio::ip::tcp>("localhost", S_AVAIL_PORT, err);
  libport::resolve<boost::asio::ip::tcp>("localhost", S_AVAIL_PORT, err);
  test_one(false);
  libport::resolve<boost::asio::ip::tcp>("localhost", S_AVAIL_PORT, err);
  test_one(false);
  libport::resolve<boost::asio::ip::tcp>("localhost", S_AVAIL_PORT, err);
  test_one(false);
  BOOST_TEST_MESSAGE("Socket on stack");
  {
    TestSocket s(false, true);
    err = s.connect("localhost", S_AVAIL_PORT, false);
    BOOST_CHECK_MESSAGE(!err, err.message());
    s.send(msg);
    usleep(delay);
  }
  usleep(delay*2);
  BOOST_CHECK_EQUAL(TestSocket::nInstance, 0);

  test_one(false);
  BOOST_TEST_MESSAGE("##many clients");
  std::vector<TestSocket*> clients;
  for (int i=0; i<10; i++)
  {
    TestSocket* client = new TestSocket(false, true);
    err = client->connect("localhost", S_AVAIL_PORT, false);
    BOOST_CHECK_MESSAGE(!err, err.message());
    client->send(msg);
    clients.push_back(client);
  }
  usleep(delay*3);
  BOOST_CHECK_EQUAL(TestSocket::nInstance, 20);
  foreach(TestSocket* s, clients)
  {
    BOOST_CHECK_EQUAL(s->received, msg);
    s->close();
  }
  usleep(delay*3);
  BOOST_CHECK_EQUAL(TestSocket::nInstance, 0);

  BOOST_TEST_MESSAGE("##Failing connections");
  {
    TestSocket* client = new TestSocket();
    err = client->connect("auunsinsr.nosuch.hostaufisgiu.com.", "20000", false);
    BOOST_CHECK_MESSAGE(err, err.message());

    err = client->connect("localhost", "nosuchport", false);
    BOOST_CHECK_MESSAGE(err, err.message());

    // Try to reuse that wasted socket.
    err = client->connect("localhost", S_AVAIL_PORT, false);
    BOOST_CHECK_MESSAGE(!err, err.message());
    // Destroy without closing.
    client->destroy();
    usleep(delay);
    BOOST_CHECK_EQUAL(TestSocket::nInstance, 0);
  }

  // Timeout
  BOOST_TEST_MESSAGE("##Timeout connect");
  {
    TestSocket* client = new TestSocket();
    libport::utime_t start = libport::utime();
    err = client->connect("1.1.1.1", "10000", false, 1000000);
    BOOST_CHECK_MESSAGE(err, err.message());
    libport::utime_t timeout = libport::utime() - start;
    // Give it a good margin.
    BOOST_CHECK_LT(timeout, 1400000);
    client->destroy();
  }

  BOOST_TEST_MESSAGE("##Destruction locking");
  {
    TestSocket* client = new TestSocket();
    err = client->connect("localhost", S_AVAIL_PORT, false);
    BOOST_CHECK_MESSAGE(!err, err.message());
    usleep(delay);
    libport::startThread(
      boost::bind(&hold_for<libport::Destructible::DestructionLock>,
                  client->getDestructionLock(),
                  1000000));
    client->destroy();
    usleep(500000);
    // There can be 1 or 2 sockets at this point. Client must be still alive because of the lock, but server might have died.
    BOOST_CHECK_MESSAGE(TestSocket::nInstance, TestSocket::nInstance);
    usleep(500000+delay);
    BOOST_CHECK_EQUAL(TestSocket::nInstance, 0);
  }

  BOOST_TEST_MESSAGE("Destroy listener");
  {
    h->close();
    usleep(delay);
    TestSocket* client = new TestSocket();
    abort_ctor = true;
    err = client->connect("localhost", S_AVAIL_PORT, false);
    BOOST_CHECK_MESSAGE(err, err.message());
    client->destroy();
    h->destroy();
    usleep(delay);
    abort_ctor = false;
  }

  BOOST_TEST_MESSAGE("##UDP");
  {
    libport::Socket::Handle hu =
      libport::Socket::listenUDP("", S_AVAIL_PORT, &echo, err);
    (void)hu;
    BOOST_CHECK_MESSAGE(!err, err.message());
    test_one(true);
    usleep(delay);
    test_one(true);

    TestSocket* client = new TestSocket();
    err = client->connect("auunsinsr.nosuch.hostaufisgiu.com.", "20000", true);
    BOOST_CHECK_MESSAGE(err, err.message());

    err = client->connect("localhost", "nosuchport", true);
    BOOST_CHECK_MESSAGE(err, err.message());

    // Try to reuse that wasted socket.
    err = client->connect("localhost", S_AVAIL_PORT, true);
    BOOST_CHECK_MESSAGE(!err, err.message());
    // Destroy without closing.
    client->destroy();
    usleep(delay);
    BOOST_CHECK_EQUAL(TestSocket::nInstance, 0);

    // Check one-write-one-packet semantic
    client = new TestSocket(false, true);
    err = client->connect("localhost", S_AVAIL_PORT, true);
    BOOST_CHECK_MESSAGE(!err, err.message());
    client->send("coin");
    client->send("pan");
    usleep(delay*2);
    BOOST_CHECK_EQUAL(client->received, "coinpan");
    BOOST_CHECK_EQUAL(client->nRead, 2);

    enable_delay = true;
    client = new TestSocket(false, true);
    err = client->connect("localhost", S_AVAIL_PORT, true);
    BOOST_CHECK_MESSAGE(!err, err.message());
    client->send("coin");
    usleep(500000+delay);
    BOOST_CHECK_EQUAL(client->received, "hop hop\n");
  }
}

test_suite*
init_test_suite()
{
  // This test cannot run properly with current versions of WineHQ,
  // because they only provide a stub for acceptex.
  const char* running_wine = getenv("RUNNING_WINE");
  const char* running_qemu = getenv("RUNNING_QEMU");
  if ((running_wine && *running_wine) || (running_qemu && *running_qemu))
    std::cerr << "running under Wine, skipping this test"
              << std::endl
              << libport::exit(EX_SKIP);

  test_suite* suite = BOOST_TEST_SUITE("libport::asio test suite");
  suite->add(BOOST_TEST_CASE(test));
  return suite;
}
<|endoftext|>


<commit_before>#include <Matrix.hpp>
#include <catch.hpp>
#include <fstream>

TEST_CASE( "Factorials are computed", "[factorial]" ) {
    REQUIRE( Factorial(0) == 1 );
    REQUIRE( Factorial(1) == 1 );
    REQUIRE( Factorial(2) == 2 );
    REQUIRE( Factorial(3) == 6 );
    REQUIRE( Factorial(10) == 3628800 );
}

/*SCENARIO("Matrix init", "[init]") {

	GIVEN("The number of rows and columns") {

		auto rows = 3;
		auto columns = 3;

		WHEN("Create instansce of Matrix") {

			Matrix<int> matrix(rows, columns);

			THEN("The number of rows and columns must be preserved") {

				REQUIRE(matrix.rows() == rows);
				REQUIRE(matrix.columns() == columns);
			}
		}
	}
}

SCENARIO("Matrix >>", "[fill]") {
	std::ifstream input("A2x2.txt");
	Matrix<int> A = Matrix<int>(2, 2);
	REQUIRE( input >> A );
	REQUIRE( A[0][0] == 1 );
	REQUIRE( A[0][1] == 1 );
	REQUIRE( A[1][0] == 2 );
	REQUIRE( A[1][1] == 2 );
}

SCENARIO("Matrix +", "[addition]") {
	Matrix<int> A = Matrix<int>(2, 2);
	std::ifstream("A2x2.txt") >> A;
	Matrix<int> B = Matrix<int>(2, 2);
	std::ifstream("B2x2.txt") >> B;
	Matrix<int> expected = Matrix<int>(2, 2);
	std::ifstream("A+B2x2.txt") >> expected;

	Matrix<int> result = A + B;
	REQUIRE(result == expected);
}

SCENARIO("Matrix *", "[multiplication]") {
	Matrix<int> A = Matrix<int>(2, 2);
	std::ifstream("A2x2.txt") >> A;
	Matrix<int> B = Matrix<int>(2, 2);
	std::ifstream("B2x2.txt") >> B;
	Matrix<int> expected = Matrix<int>(2, 2);
	std::ifstream("A*B2x2.txt") >> expected;

	Matrix<int> result = A * B;
	REQUIRE(result == expected);
}
*/
<commit_msg>Update init.cpp<commit_after>#include <Matrix.hpp>
#include <catch.hpp>
#include <fstream>

SCENARIO("Matrix init", "[init]") {
	GIVEN("The number of rows and columns") {
		auto rows = 36;
		auto columns = 39;

		WHEN("Create instansce of Matrix") {
			Matrix matrix(rows, columns);
			THEN("The number of rows and columns must be preserved") {
				REQUIRE(matrix.rows() == rows);
				REQUIRE(matrix.columns() == columns);
			}
		}
	}
}
/*
SCENARIO("Matrix >>", "[fill]") {
	std::ifstream input("A2x2.txt");
	Matrix<int> A = Matrix<int>(2, 2);
	REQUIRE( input >> A );
	REQUIRE( A[0][0] == 1 );
	REQUIRE( A[0][1] == 1 );
	REQUIRE( A[1][0] == 2 );
	REQUIRE( A[1][1] == 2 );
}

SCENARIO("Matrix +", "[addition]") {
	Matrix<int> A = Matrix<int>(2, 2);
	std::ifstream("A2x2.txt") >> A;
	Matrix<int> B = Matrix<int>(2, 2);
	std::ifstream("B2x2.txt") >> B;
	Matrix<int> expected = Matrix<int>(2, 2);
	std::ifstream("A+B2x2.txt") >> expected;

	Matrix<int> result = A + B;
	REQUIRE(result == expected);
}

SCENARIO("Matrix *", "[multiplication]") {
	Matrix<int> A = Matrix<int>(2, 2);
	std::ifstream("A2x2.txt") >> A;
	Matrix<int> B = Matrix<int>(2, 2);
	std::ifstream("B2x2.txt") >> B;
	Matrix<int> expected = Matrix<int>(2, 2);
	std::ifstream("A*B2x2.txt") >> expected;

	Matrix<int> result = A * B;
	REQUIRE(result == expected);
}
*/
<|endoftext|>


<commit_before>/* Copyright 2013-present Barefoot Networks, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "bm_sim/dev_mgr.h"
#include "bm_sim/port_monitor.h"
#include "bm_apps/packet_pipe.h"

#include <algorithm>
#include <cassert>
#include <chrono>
#include <gtest/gtest.h>
#include <iostream>
#include <map>
#include <thread>
#include <mutex>
#include <thread>
#include <condition_variable>

class TestDevMgrImplementation : public DevMgrInterface {

public:
  TestDevMgrImplementation() { p_monitor.start(this); }

  bool port_is_up(port_t port) {
    auto it = port_status.find(port);
    bool exists = (it != port_status.end());

    return (exists && ((it->second == PortStatus::PORT_ADDED) ||
                       (it->second == PortStatus::PORT_UP)));
  }

   ~TestDevMgrImplementation() {
    p_monitor.stop();
    port_status.clear();
  }

  ReturnCode register_status_cb(const PortStatus &type,
                                const PortStatusCB &port_cb) {
    p_monitor.register_cb(type, port_cb);
    return ReturnCode::SUCCESS;
  }

  // Not part of public interface, just for testing
  void set_port_status(port_t port, const PortStatus &status) {
    auto it = port_status.find(port);
    bool exists = (it != port_status.end());
    std::string portname = "dummy";
    if (!exists && status == PortStatus::PORT_ADDED) {
      port_add(portname, port, NULL, NULL);
    } else if (exists && status == PortStatus::PORT_REMOVED) {
      port_remove(port);
    } else if (exists && ((it->second == PortStatus::PORT_ADDED) ||
                          (it->second == PortStatus::PORT_DOWN)) &&
               status == PortStatus::PORT_UP) {
      port_status[port] = PortStatus::PORT_UP;
    } else if (exists && ((it->second == PortStatus::PORT_ADDED ||
                           it->second == PortStatus::PORT_UP)) &&
               status == PortStatus::PORT_DOWN) {
      port_status[port] = PortStatus::PORT_DOWN;
    } else {
      ASSERT_TRUE(false) << "Incorrect op sequence on port: " << port
                         << std::endl;
    }
  }

private:
  ReturnCode port_add(const std::string &iface_name, port_t port_num,
                      const char *in_pcap, const char *out_pcap) {
    port_status.insert(
        std::pair<port_t, PortStatus>(port_num, PortStatus::PORT_ADDED));
    p_monitor.notify(port_num, PortStatus::PORT_ADDED);
    return ReturnCode::SUCCESS;
  }
  ReturnCode port_remove(port_t port_num) {
    auto it = port_status.find(port_num);
    port_status.erase(it);
    p_monitor.notify(port_num, PortStatus::PORT_REMOVED);
  }
  ReturnCode set_packet_handler(const PacketHandler &handler, void *cookie) {
    return ReturnCode::SUCCESS;
  }
  void transmit_fn(int port_num, const char *buffer, int len) {}
  void start() {}

  std::map<port_t, PortStatus> port_status;
  PortMonitor p_monitor;
};

class DevMgrTest : public ::testing::Test {
public:

  void port_status(DevMgrInterface::port_t port_num,
                   const DevMgrInterface::PortStatus &status) {
    cb_counts[status]++;
  }

protected:
  DevMgrTest() : g_mgr{new TestDevMgrImplementation()} {}
  void register_callback(void) {
    port_cb = std::bind(&DevMgrTest::port_status, this, std::placeholders::_1,
                        std::placeholders::_2);
    g_mgr->register_status_cb(DevMgrInterface::PortStatus::PORT_ADDED, port_cb);
    g_mgr->register_status_cb(DevMgrInterface::PortStatus::PORT_REMOVED,
                              port_cb);
    g_mgr->register_status_cb(DevMgrInterface::PortStatus::PORT_UP, port_cb);
    g_mgr->register_status_cb(DevMgrInterface::PortStatus::PORT_DOWN, port_cb);
  }

  void reset_counts(void) {
    for (auto &kv : cb_counts) {
      kv.second = 0;
    }
  }
  DevMgrInterface::PortStatusCB port_cb;
  std::map<DevMgrInterface::PortStatus, uint32_t> cb_counts;
  std::unique_ptr<TestDevMgrImplementation> g_mgr;
};

TEST_F(DevMgrTest, cb_test) {
  const unsigned int NPORTS = 10;

  register_callback();
  for (int i = 0; i < NPORTS; i++) {
    g_mgr->set_port_status(i, DevMgrInterface::PortStatus::PORT_ADDED);
  }
  std::this_thread::sleep_for(std::chrono::seconds(3));
  ASSERT_EQ(cb_counts[DevMgrInterface::PortStatus::PORT_ADDED], NPORTS) << "Port add callbacks incorrect"
                                    << std::endl;
  reset_counts();
  for (int i = 0; i < NPORTS; i++) {
    g_mgr->set_port_status(i, DevMgrInterface::PortStatus::PORT_DOWN);
  }
  std::this_thread::sleep_for(std::chrono::seconds(3));
  ASSERT_EQ(cb_counts[DevMgrInterface::PortStatus::PORT_DOWN], NPORTS) << "Port down callbacks incorrect"
                                    << std::endl;

  for (int i = 0; i < NPORTS; i++) {
    g_mgr->set_port_status(i, DevMgrInterface::PortStatus::PORT_UP);
  }
  std::this_thread::sleep_for(std::chrono::seconds(3));
  ASSERT_EQ(cb_counts[DevMgrInterface::PortStatus::PORT_UP], NPORTS) << "Port up callbacks incorrect"
                                    << std::endl;
  for (int i = 0; i < NPORTS; i++) {
    g_mgr->set_port_status(i, DevMgrInterface::PortStatus::PORT_REMOVED);
  }
  std::this_thread::sleep_for(std::chrono::seconds(3));
  ASSERT_EQ(NPORTS, cb_counts[DevMgrInterface::PortStatus::PORT_REMOVED])
      << "Number of port remove callbacks incorrect" << std::endl;
}

class PacketInReceiver {
 public:
  enum class Status { CAN_READ, CAN_RECEIVE };

  PacketInReceiver(size_t max_size)
      : max_size(max_size) {
    buffer_.reserve(max_size);
  }

  void receive(int port_num, const char *buffer, int len, void *cookie) {
    (void) cookie;
    if(len > max_size) return;
    std::unique_lock<std::mutex> lock(mutex);
    while (status != Status::CAN_RECEIVE) {
      can_receive.wait(lock);
    }
    buffer_.insert(buffer_.end(), buffer, buffer + len);
    port = port_num;
    status = Status::CAN_READ;
    can_read.notify_one();
  }

  void read(char *dst, size_t len, int *recv_port) {
    len = (len > max_size) ? max_size : len;
    std::unique_lock<std::mutex> lock(mutex);
    while(status != Status::CAN_READ) {
      can_read.wait(lock);
    }
    std::copy(buffer_.begin(), buffer_.begin() + len, dst);
    buffer_.clear();
    *recv_port = port;
    status = Status::CAN_RECEIVE;
    can_receive.notify_one();
  }

  Status check_status() {
    std::unique_lock<std::mutex> lock(mutex);
    return status;
  }

 private:
  size_t max_size;
  std::vector<char> buffer_;
  int port;
  Status status{Status::CAN_RECEIVE};
  mutable std::mutex mutex{};
  mutable std::condition_variable can_receive{};
  mutable std::condition_variable can_read{};
};

// is here because DevMgr has a protected destructor
class PacketInSwitch : public DevMgr {
 public:
  void set_handler(const PacketHandler &handler, void *cookie) {
    set_packet_handler(handler, cookie);
  }
};

class PacketInDevMgrTest : public ::testing::Test {
 protected:
  static constexpr size_t max_buffer_size = 512;

  PacketInDevMgrTest()
      : packet_inject(addr) { }

  virtual void SetUp() {
    sw.set_dev_mgr_packet_in(addr);
    sw.start();
    auto cb_switch = std::bind(&PacketInReceiver::receive, &recv_switch,
                               std::placeholders::_1, std::placeholders::_2,
                               std::placeholders::_3, std::placeholders::_4);
    sw.set_handler(cb_switch, nullptr);

    packet_inject.start();
    auto cb_lib = std::bind(&PacketInReceiver::receive, &recv_lib,
                            std::placeholders::_1, std::placeholders::_2,
                            std::placeholders::_3, std::placeholders::_4);
    packet_inject.set_packet_receiver(cb_lib, nullptr);
  }

  virtual void TearDown() {
  }

  bool check_recv(PacketInReceiver *receiver,
                  int send_port, const char *send_buffer, size_t size) {
    char recv_buffer[max_buffer_size];
    memset(recv_buffer, 0, sizeof(recv_buffer));
    if (size > sizeof(recv_buffer)) return false;
    int recv_port = -1;
    receiver->read(recv_buffer, size, &recv_port);
    if (recv_port != send_port) return false;
    return !memcmp(recv_buffer, send_buffer, size);
  }

  const std::string addr = "ipc:///tmp/test_packet_in_abc123";

  PacketInReceiver recv_switch{max_buffer_size};
  PacketInReceiver recv_lib{max_buffer_size};

  PacketInSwitch sw;

  bm_apps::PacketInject packet_inject;
};

TEST_F(PacketInDevMgrTest, PacketInTest) {
  constexpr int port = 2;
  const char pkt[] = {'\x0a', '\xba'};
  ASSERT_EQ(PacketInReceiver::Status::CAN_RECEIVE, recv_switch.check_status());
  ASSERT_EQ(PacketInReceiver::Status::CAN_RECEIVE, recv_lib.check_status());
  // switch -> lib
  sw.transmit_fn(port, pkt, sizeof(pkt));
  ASSERT_TRUE(check_recv(&recv_lib, port, pkt, sizeof(pkt)));
  ASSERT_EQ(PacketInReceiver::Status::CAN_RECEIVE, recv_switch.check_status());
  ASSERT_EQ(PacketInReceiver::Status::CAN_RECEIVE, recv_lib.check_status());
  // lib -> switch
  packet_inject.send(port, pkt, sizeof(pkt));
  ASSERT_TRUE(check_recv(&recv_switch, port, pkt, sizeof(pkt)));
}
<commit_msg>DevMgrTest fix<commit_after>/* Copyright 2013-present Barefoot Networks, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "bm_sim/dev_mgr.h"
#include "bm_sim/port_monitor.h"
#include "bm_apps/packet_pipe.h"

#include <algorithm>
#include <atomic>
#include <cassert>
#include <chrono>
#include <gtest/gtest.h>
#include <iostream>
#include <map>
#include <thread>
#include <mutex>
#include <condition_variable>

class TestDevMgrImplementation : public DevMgrInterface {

public:
  TestDevMgrImplementation() { p_monitor.start(this); }

  bool port_is_up(port_t port) {
    std::lock_guard<std::mutex> lock(status_mutex);
    auto it = port_status.find(port);
    bool exists = (it != port_status.end());

    return (exists && ((it->second == PortStatus::PORT_ADDED) ||
                       (it->second == PortStatus::PORT_UP)));
  }

   ~TestDevMgrImplementation() {
    p_monitor.stop();
    port_status.clear();
  }

  ReturnCode register_status_cb(const PortStatus &type,
                                const PortStatusCB &port_cb) {
    p_monitor.register_cb(type, port_cb);
    return ReturnCode::SUCCESS;
  }

  // Not part of public interface, just for testing
  void set_port_status(port_t port, const PortStatus &status) {
    {
      std::lock_guard<std::mutex> lock(status_mutex);
      auto it = port_status.find(port);
      bool exists = (it != port_status.end());
      std::string portname = "dummy";
      if (!exists && status == PortStatus::PORT_ADDED) {
        port_status.insert(
            std::pair<port_t, PortStatus>(port, PortStatus::PORT_ADDED));
      } else if (exists && status == PortStatus::PORT_REMOVED) {
        port_status.erase(it);
      } else if (exists && ((it->second == PortStatus::PORT_ADDED) ||
                            (it->second == PortStatus::PORT_DOWN)) &&
                 status == PortStatus::PORT_UP) {
        port_status[port] = PortStatus::PORT_UP;
      } else if (exists && ((it->second == PortStatus::PORT_ADDED ||
                             it->second == PortStatus::PORT_UP)) &&
                 status == PortStatus::PORT_DOWN) {
        port_status[port] = PortStatus::PORT_DOWN;
      } else {
        ASSERT_TRUE(false) << "Incorrect op sequence on port: " << port
                           << std::endl;
      }
    }
    if ((status == PortStatus::PORT_ADDED) ||
        (status == PortStatus::PORT_REMOVED)) {
      p_monitor.notify(port, status);
    }
  }

private:
  ReturnCode port_add(const std::string &iface_name, port_t port_num,
                      const char *in_pcap, const char *out_pcap) {
    return ReturnCode::SUCCESS;
  }
  ReturnCode port_remove(port_t port_num) {
    return ReturnCode::SUCCESS;
  }
  ReturnCode set_packet_handler(const PacketHandler &handler, void *cookie) {
    return ReturnCode::SUCCESS;
  }
  void transmit_fn(int port_num, const char *buffer, int len) {}
  void start() {}

  std::map<port_t, PortStatus> port_status;
  PortMonitor p_monitor;
  mutable std::mutex status_mutex;
};

class DevMgrTest : public ::testing::Test {
public:

  void port_status(DevMgrInterface::port_t port_num,
                   const DevMgrInterface::PortStatus &status) {
    cb_counts[status]++;
  }

protected:
  DevMgrTest() : g_mgr{new TestDevMgrImplementation()} {}
  void register_callback(void) {
    port_cb = std::bind(&DevMgrTest::port_status, this, std::placeholders::_1,
                        std::placeholders::_2);
    g_mgr->register_status_cb(DevMgrInterface::PortStatus::PORT_ADDED, port_cb);
    g_mgr->register_status_cb(DevMgrInterface::PortStatus::PORT_REMOVED,
                              port_cb);
    g_mgr->register_status_cb(DevMgrInterface::PortStatus::PORT_UP, port_cb);
    g_mgr->register_status_cb(DevMgrInterface::PortStatus::PORT_DOWN, port_cb);
  }

  void reset_counts(void) {
    for (auto &kv : cb_counts) {
      kv.second = 0;
    }
  }
  DevMgrInterface::PortStatusCB port_cb;
  std::map<DevMgrInterface::PortStatus, std::atomic_uint> cb_counts;
  std::unique_ptr<TestDevMgrImplementation> g_mgr;
};

TEST_F(DevMgrTest, cb_test) {
  const unsigned int NPORTS = 10;

  register_callback();
  for (int i = 0; i < NPORTS; i++) {
    g_mgr->set_port_status(i, DevMgrInterface::PortStatus::PORT_ADDED);
  }
  std::this_thread::sleep_for(std::chrono::seconds(3));
  ASSERT_EQ(cb_counts[DevMgrInterface::PortStatus::PORT_ADDED], NPORTS) << "Port add callbacks incorrect"
                                    << std::endl;
  reset_counts();
  for (int i = 0; i < NPORTS; i++) {
    g_mgr->set_port_status(i, DevMgrInterface::PortStatus::PORT_DOWN);
  }
  std::this_thread::sleep_for(std::chrono::seconds(3));
  ASSERT_EQ(cb_counts[DevMgrInterface::PortStatus::PORT_DOWN], NPORTS) << "Port down callbacks incorrect"
                                    << std::endl;

  for (int i = 0; i < NPORTS; i++) {
    g_mgr->set_port_status(i, DevMgrInterface::PortStatus::PORT_UP);
  }
  std::this_thread::sleep_for(std::chrono::seconds(3));
  ASSERT_EQ(cb_counts[DevMgrInterface::PortStatus::PORT_UP], NPORTS) << "Port up callbacks incorrect"
                                    << std::endl;
  for (int i = 0; i < NPORTS; i++) {
    g_mgr->set_port_status(i, DevMgrInterface::PortStatus::PORT_REMOVED);
  }
  std::this_thread::sleep_for(std::chrono::seconds(3));
  ASSERT_EQ(NPORTS, cb_counts[DevMgrInterface::PortStatus::PORT_REMOVED])
      << "Number of port remove callbacks incorrect" << std::endl;
}

class PacketInReceiver {
 public:
  enum class Status { CAN_READ, CAN_RECEIVE };

  PacketInReceiver(size_t max_size)
      : max_size(max_size) {
    buffer_.reserve(max_size);
  }

  void receive(int port_num, const char *buffer, int len, void *cookie) {
    (void) cookie;
    if(len > max_size) return;
    std::unique_lock<std::mutex> lock(mutex);
    while (status != Status::CAN_RECEIVE) {
      can_receive.wait(lock);
    }
    buffer_.insert(buffer_.end(), buffer, buffer + len);
    port = port_num;
    status = Status::CAN_READ;
    can_read.notify_one();
  }

  void read(char *dst, size_t len, int *recv_port) {
    len = (len > max_size) ? max_size : len;
    std::unique_lock<std::mutex> lock(mutex);
    while(status != Status::CAN_READ) {
      can_read.wait(lock);
    }
    std::copy(buffer_.begin(), buffer_.begin() + len, dst);
    buffer_.clear();
    *recv_port = port;
    status = Status::CAN_RECEIVE;
    can_receive.notify_one();
  }

  Status check_status() {
    std::unique_lock<std::mutex> lock(mutex);
    return status;
  }

 private:
  size_t max_size;
  std::vector<char> buffer_;
  int port;
  Status status{Status::CAN_RECEIVE};
  mutable std::mutex mutex{};
  mutable std::condition_variable can_receive{};
  mutable std::condition_variable can_read{};
};

// is here because DevMgr has a protected destructor
class PacketInSwitch : public DevMgr {
 public:
  void set_handler(const PacketHandler &handler, void *cookie) {
    set_packet_handler(handler, cookie);
  }
};

class PacketInDevMgrTest : public ::testing::Test {
 protected:
  static constexpr size_t max_buffer_size = 512;

  PacketInDevMgrTest()
      : packet_inject(addr) { }

  virtual void SetUp() {
    sw.set_dev_mgr_packet_in(addr);
    sw.start();
    auto cb_switch = std::bind(&PacketInReceiver::receive, &recv_switch,
                               std::placeholders::_1, std::placeholders::_2,
                               std::placeholders::_3, std::placeholders::_4);
    sw.set_handler(cb_switch, nullptr);

    packet_inject.start();
    auto cb_lib = std::bind(&PacketInReceiver::receive, &recv_lib,
                            std::placeholders::_1, std::placeholders::_2,
                            std::placeholders::_3, std::placeholders::_4);
    packet_inject.set_packet_receiver(cb_lib, nullptr);
  }

  virtual void TearDown() {
  }

  bool check_recv(PacketInReceiver *receiver,
                  int send_port, const char *send_buffer, size_t size) {
    char recv_buffer[max_buffer_size];
    memset(recv_buffer, 0, sizeof(recv_buffer));
    if (size > sizeof(recv_buffer)) return false;
    int recv_port = -1;
    receiver->read(recv_buffer, size, &recv_port);
    if (recv_port != send_port) return false;
    return !memcmp(recv_buffer, send_buffer, size);
  }

  const std::string addr = "ipc:///tmp/test_packet_in_abc123";

  PacketInReceiver recv_switch{max_buffer_size};
  PacketInReceiver recv_lib{max_buffer_size};

  PacketInSwitch sw;

  bm_apps::PacketInject packet_inject;
};

TEST_F(PacketInDevMgrTest, PacketInTest) {
  constexpr int port = 2;
  const char pkt[] = {'\x0a', '\xba'};
  ASSERT_EQ(PacketInReceiver::Status::CAN_RECEIVE, recv_switch.check_status());
  ASSERT_EQ(PacketInReceiver::Status::CAN_RECEIVE, recv_lib.check_status());
  // switch -> lib
  sw.transmit_fn(port, pkt, sizeof(pkt));
  ASSERT_TRUE(check_recv(&recv_lib, port, pkt, sizeof(pkt)));
  ASSERT_EQ(PacketInReceiver::Status::CAN_RECEIVE, recv_switch.check_status());
  ASSERT_EQ(PacketInReceiver::Status::CAN_RECEIVE, recv_lib.check_status());
  // lib -> switch
  packet_inject.send(port, pkt, sizeof(pkt));
  ASSERT_TRUE(check_recv(&recv_switch, port, pkt, sizeof(pkt)));
}
<|endoftext|>


<commit_before>/*  This file is part of the KDE project
    Copyright (C) 2006 Matthias Kretz <kretz@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License version 2
    as published by the Free Software Foundation.

    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 Street, Fifth Floor, Boston, MA
    02110-1301, USA.

*/

#include "mediaplayer.h"
#include <QVBoxLayout>
#include <kcmdlineargs.h>
#include <kapplication.h>
#include <kaboutdata.h>
#include <cstdlib>
#include <QVBoxLayout>
#include <QPushButton>
#include "../../backendcapabilities.h"

using namespace Phonon;

MediaPlayer::MediaPlayer( QWidget* parent )
	: QWidget( parent )
	, m_effectWidget( 0 )
{
	QVBoxLayout* layout = new QVBoxLayout( this );

	m_vwidget = new VideoWidget( this );
	layout->addWidget( m_vwidget );
	//m_vwidget->hide();

	m_vpath = new VideoPath( this );

	m_aoutput = new AudioOutput( Phonon::VideoCategory, this );
	m_apath = new AudioPath( this );

	m_media = new MediaObject( this );
	m_media->addVideoPath( m_vpath );
	m_vpath->addOutput( m_vwidget );
	m_media->addAudioPath( m_apath );
	m_apath->addOutput( m_aoutput );

	m_controls = new MediaControls( this );
	layout->addWidget( m_controls );
	m_controls->setMediaProducer( m_media );
	m_controls->setAudioOutput( m_aoutput );

	m_effect = new AudioEffect( BackendCapabilities::availableAudioEffects().first(), m_apath );
	m_apath->insertEffect( m_effect );
	QPushButton* button = new QPushButton( this );
	layout->addWidget( button );
	button->setText( "configure effect" );
	connect( button, SIGNAL( clicked() ), SLOT( openEffectWidget() ) );
}

void MediaPlayer::openEffectWidget()
{
	if( !m_effectWidget )
		m_effectWidget = new EffectWidget( m_effect );
	m_effectWidget->show();
	m_effectWidget->raise();
}

void MediaPlayer::setUrl( const KUrl& url )
{
	m_media->setUrl( url );
	//m_vwidget->setVisible( m_media->hasVideo() );
}

int main( int argc, char ** argv )
{
	KAboutData about( "phononmediaplayer", "Phonon Media Player",
			"0.1", "Media Player",
			KAboutData::License_GPL, 0 );
	about.addAuthor( "Matthias Kretz", 0, "kretz@kde.org" );
	KCmdLineArgs::init( argc, argv, &about );
	KApplication app;
	MediaPlayer foo;
	foo.show();
	KUrl url( getenv( "PHONON_TESTURL" ) );
	if( url.isValid() )
	{
		foo.setUrl( url );
		return app.exec();
	}
	return 1;
}

// vim: sw=4 ts=4 noet
#include "mediaplayer.moc"
<commit_msg>only use an AudioEffect if the Backend lists one<commit_after>/*  This file is part of the KDE project
    Copyright (C) 2006 Matthias Kretz <kretz@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License version 2
    as published by the Free Software Foundation.

    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 Street, Fifth Floor, Boston, MA
    02110-1301, USA.

*/

#include "mediaplayer.h"
#include <QVBoxLayout>
#include <kcmdlineargs.h>
#include <kapplication.h>
#include <kaboutdata.h>
#include <cstdlib>
#include <QVBoxLayout>
#include <QPushButton>
#include "../../backendcapabilities.h"

using namespace Phonon;

MediaPlayer::MediaPlayer( QWidget* parent )
	: QWidget( parent )
	, m_effectWidget( 0 )
{
	QVBoxLayout* layout = new QVBoxLayout( this );

	m_vwidget = new VideoWidget( this );
	layout->addWidget( m_vwidget );
	//m_vwidget->hide();

	m_vpath = new VideoPath( this );

	m_aoutput = new AudioOutput( Phonon::VideoCategory, this );
	m_apath = new AudioPath( this );

	m_media = new MediaObject( this );
	m_media->addVideoPath( m_vpath );
	m_vpath->addOutput( m_vwidget );
	m_media->addAudioPath( m_apath );
	m_apath->addOutput( m_aoutput );

	m_controls = new MediaControls( this );
	layout->addWidget( m_controls );
	m_controls->setMediaProducer( m_media );
	m_controls->setAudioOutput( m_aoutput );

	QList<AudioEffectDescription> effectList = BackendCapabilities::availableAudioEffects();
	if( !effectList.isEmpty() )
	{
		m_effect = new AudioEffect( BackendCapabilities::availableAudioEffects().first(), m_apath );
		m_apath->insertEffect( m_effect );
		QPushButton* button = new QPushButton( this );
		layout->addWidget( button );
		button->setText( "configure effect" );
		connect( button, SIGNAL( clicked() ), SLOT( openEffectWidget() ) );
	}
}

void MediaPlayer::openEffectWidget()
{
	if( !m_effectWidget )
		m_effectWidget = new EffectWidget( m_effect );
	m_effectWidget->show();
	m_effectWidget->raise();
}

void MediaPlayer::setUrl( const KUrl& url )
{
	m_media->setUrl( url );
	//m_vwidget->setVisible( m_media->hasVideo() );
}

int main( int argc, char ** argv )
{
	KAboutData about( "phononmediaplayer", "Phonon Media Player",
			"0.1", "Media Player",
			KAboutData::License_GPL, 0 );
	about.addAuthor( "Matthias Kretz", 0, "kretz@kde.org" );
	KCmdLineArgs::init( argc, argv, &about );
	KApplication app;
	MediaPlayer foo;
	foo.show();
	KUrl url( getenv( "PHONON_TESTURL" ) );
	if( url.isValid() )
	{
		foo.setUrl( url );
		return app.exec();
	}
	return 1;
}

// vim: sw=4 ts=4 noet
#include "mediaplayer.moc"
<|endoftext|>