<commit_before>#include "ConfigActivationManager.h"
#include "System/Events/EventLoop.h"
#include "Application/Common/ContextTransport.h"
#include "ConfigServer.h"
#include "ConfigQuorumProcessor.h"

void ConfigActivationManager::Init(ConfigServer* configServer_)
{
    configServer = configServer_;

    activationTimeout.SetCallable(MFUNC(ConfigActivationManager, OnActivationTimeout));
}

void ConfigActivationManager::TryDeactivateShardServer(uint64_t nodeID)
{
    ConfigState*        configState;
    ConfigQuorum*       itQuorum;
    ConfigShardServer*  shardServer;

    configState = configServer->GetDatabaseManager()->GetConfigState();

    FOREACH(itQuorum, configState->quorums)
    {
        // don't deactivate the last node due to TotalPaxos semantics
        // otherwise, we wouldn't know which one to bring back, which is up-to-date
        if (itQuorum->activeNodes.GetLength() <= 1)
            continue;

        if (itQuorum->isActivatingNode && itQuorum->activatingNodeID == nodeID)
        {
            shardServer = configState->GetShardServer(itQuorum->activatingNodeID);
            assert(shardServer != NULL);

            itQuorum->ClearActivation();
            UpdateTimeout();

            Log_Message("Activation failed for shard server %U and quorum %U...",
             itQuorum->quorumID, itQuorum->activatingNodeID);
        }

        if (itQuorum->IsActiveMember(nodeID))
        {
            // if this node was part of an activation process, cancel it
            if (itQuorum->isActivatingNode)
            {
                shardServer = configState->GetShardServer(itQuorum->activatingNodeID);
                assert(shardServer != NULL);

                itQuorum->ClearActivation();
                UpdateTimeout();

                Log_Message("Activation failed for shard server %U and quorum %U...",
                 itQuorum->activatingNodeID, itQuorum->quorumID);
            }

            Log_Message("Deactivating shard server %U...", nodeID);
            configServer->GetQuorumProcessor()->DeactivateNode(itQuorum->quorumID, nodeID);
        }
    }
}

void ConfigActivationManager::TryActivateShardServer(uint64_t nodeID)
{
    uint64_t            paxosID;
    ConfigState*        configState;
    ConfigQuorum*       itQuorum;
    ConfigShardServer*  shardServer;
    uint64_t            now;

    now = EventLoop::Now();

    Log_Trace();

    configState = configServer->GetDatabaseManager()->GetConfigState();
    shardServer = configState->GetShardServer(nodeID);

    FOREACH(itQuorum, configState->quorums)
    {
        Log_Trace("itQuorum->isActivatingNode: %b", itQuorum->isActivatingNode);
        if (itQuorum->isActivatingNode)
            continue;

        Log_Trace("itQuorum->hasPrimary: %b", itQuorum->hasPrimary);
        if (!itQuorum->hasPrimary)
            continue;

        if (itQuorum->IsInactiveMember(nodeID))
        {
            paxosID = QuorumInfo::GetQuorumInfo(shardServer->quorumInfos, itQuorum->quorumID)->paxosID;
            if (paxosID >= (itQuorum->paxosID - RLOG_REACTIVATION_DIFF) ||
             itQuorum->paxosID <= RLOG_REACTIVATION_DIFF)
            {
                // the shard server is "almost caught up", start the activation process
                itQuorum->OnActivationStart(nodeID, now + 3*PAXOSLEASE_MAX_LEASE_TIME);
                UpdateTimeout();

                Log_Message("Activation started for shard server %U and quorum %U...",
                 itQuorum->activatingNodeID, itQuorum->quorumID);
            }
        }
    }
}

void ConfigActivationManager::OnExtendLease(ConfigQuorum& quorum, ClusterMessage& message)
{
    Log_Trace();

    if (!quorum.isActivatingNode || quorum.isReplicatingActivation ||
     message.configID != quorum.configID)
    {
        Log_Trace("ExtendLease condition: %b %b %U %U", quorum.isActivatingNode,
        quorum.isReplicatingActivation,
        message.configID,
        quorum.configID);
        return;
    }

    if (!quorum.isWatchingPaxosID)
    {
        Log_Message("Activating shard server %U in quorum %U: Starting to monitor the primary's paxosID",
         quorum.quorumID, quorum.activatingNodeID);

        quorum.OnActivationMonitoring(message.paxosID);
        configServer->OnConfigStateChanged();
    }
    else
    {
        Log_Trace();

        // if the primary was able to increase its paxosID, the new shardserver joined successfully
        if (message.paxosID > quorum.activationPaxosID)
        {
            Log_Message("Activating shard server %U in quorum %U: The primary was able to increase its paxosID!",
             quorum.quorumID, quorum.activatingNodeID);

            quorum.OnActivationReplication();
            configServer->OnConfigStateChanged();
            configServer->GetQuorumProcessor()->ActivateNode(quorum.quorumID, quorum.activatingNodeID);
        }
        else
        {
            Log_Message("Activating shard server %U in quorum %U: The primary was not able to increase its paxosID so far...",
             quorum.quorumID, quorum.activatingNodeID);
        }
    }
}

void ConfigActivationManager::OnActivationTimeout()
{
    uint64_t            now;
    ConfigState*        configState;
    ConfigQuorum*       itQuorum;
    ConfigShardServer*  shardServer;

    Log_Trace();

    now = EventLoop::Now();
    configState = configServer->GetDatabaseManager()->GetConfigState();

    FOREACH(itQuorum, configState->quorums)
    {
        if (itQuorum->activationExpireTime > 0 && itQuorum->activationExpireTime < now)
        {
            // stop activation

            assert(itQuorum->isActivatingNode == true);
            assert(itQuorum->isReplicatingActivation == false);

            shardServer = configState->GetShardServer(itQuorum->activatingNodeID);
            assert(shardServer != NULL);

            Log_Message("Activating shard server %U in quorum %U: Activation failed...",
             itQuorum->activatingNodeID, itQuorum->quorumID);

            itQuorum->ClearActivation();

            configServer->OnConfigStateChanged();
        }
    }

    UpdateTimeout();
}

void ConfigActivationManager::UpdateTimeout()
{
    ConfigQuorum*   it;
    uint64_t        activationExpireTime;

    Log_Trace();

    activationExpireTime = 0;
    FOREACH(it, configServer->GetDatabaseManager()->GetConfigState()->quorums)
    {
        if (it->isActivatingNode && !it->isReplicatingActivation)
        {
            if (activationExpireTime == 0 || it->activationExpireTime < activationExpireTime)
                activationExpireTime = it->activationExpireTime;
        }
    }

    if (activationExpireTime > 0)
    {
        activationTimeout.SetExpireTime(activationExpireTime);
        EventLoop::Reset(&activationTimeout);
    }
}
<commit_msg>Fixed activation bug where the non-primary's paxosID would trigger activation.<commit_after>#include "ConfigActivationManager.h"
#include "System/Events/EventLoop.h"
#include "Application/Common/ContextTransport.h"
#include "ConfigServer.h"
#include "ConfigQuorumProcessor.h"

void ConfigActivationManager::Init(ConfigServer* configServer_)
{
    configServer = configServer_;

    activationTimeout.SetCallable(MFUNC(ConfigActivationManager, OnActivationTimeout));
}

void ConfigActivationManager::TryDeactivateShardServer(uint64_t nodeID)
{
    ConfigState*        configState;
    ConfigQuorum*       itQuorum;
    ConfigShardServer*  shardServer;

    configState = configServer->GetDatabaseManager()->GetConfigState();

    FOREACH(itQuorum, configState->quorums)
    {
        // don't deactivate the last node due to TotalPaxos semantics
        // otherwise, we wouldn't know which one to bring back, which is up-to-date
        if (itQuorum->activeNodes.GetLength() <= 1)
            continue;

        if (itQuorum->isActivatingNode && itQuorum->activatingNodeID == nodeID)
        {
            shardServer = configState->GetShardServer(itQuorum->activatingNodeID);
            assert(shardServer != NULL);

            itQuorum->ClearActivation();
            UpdateTimeout();

            Log_Message("Activation failed for shard server %U and quorum %U...",
             itQuorum->quorumID, itQuorum->activatingNodeID);
        }

        if (itQuorum->IsActiveMember(nodeID))
        {
            // if this node was part of an activation process, cancel it
            if (itQuorum->isActivatingNode)
            {
                shardServer = configState->GetShardServer(itQuorum->activatingNodeID);
                assert(shardServer != NULL);

                itQuorum->ClearActivation();
                UpdateTimeout();

                Log_Message("Activation failed for shard server %U and quorum %U...",
                 itQuorum->activatingNodeID, itQuorum->quorumID);
            }

            Log_Message("Deactivating shard server %U...", nodeID);
            configServer->GetQuorumProcessor()->DeactivateNode(itQuorum->quorumID, nodeID);
        }
    }
}

void ConfigActivationManager::TryActivateShardServer(uint64_t nodeID)
{
    uint64_t            paxosID;
    ConfigState*        configState;
    ConfigQuorum*       itQuorum;
    ConfigShardServer*  shardServer;
    uint64_t            now;

    now = EventLoop::Now();

    Log_Trace();

    configState = configServer->GetDatabaseManager()->GetConfigState();
    shardServer = configState->GetShardServer(nodeID);

    FOREACH(itQuorum, configState->quorums)
    {
        Log_Trace("itQuorum->isActivatingNode: %b", itQuorum->isActivatingNode);
        if (itQuorum->isActivatingNode)
            continue;

        Log_Trace("itQuorum->hasPrimary: %b", itQuorum->hasPrimary);
        if (!itQuorum->hasPrimary)
            continue;

        if (itQuorum->IsInactiveMember(nodeID))
        {
            paxosID = QuorumInfo::GetQuorumInfo(shardServer->quorumInfos, itQuorum->quorumID)->paxosID;
            if (paxosID >= (itQuorum->paxosID - RLOG_REACTIVATION_DIFF) ||
             itQuorum->paxosID <= RLOG_REACTIVATION_DIFF)
            {
                // the shard server is "almost caught up", start the activation process
                itQuorum->OnActivationStart(nodeID, now + 3*PAXOSLEASE_MAX_LEASE_TIME);
                UpdateTimeout();

                Log_Message("Activation started for shard server %U and quorum %U...",
                 itQuorum->activatingNodeID, itQuorum->quorumID);
            }
        }
    }
}

void ConfigActivationManager::OnExtendLease(ConfigQuorum& quorum, ClusterMessage& message)
{
    Log_Trace();

    if (!quorum.hasPrimary || message.nodeID != quorum.primaryID)
        return;

    if (!quorum.isActivatingNode || quorum.isReplicatingActivation ||
     message.configID != quorum.configID)
    {
        Log_Trace("ExtendLease condition: %b %b %U %U", quorum.isActivatingNode,
        quorum.isReplicatingActivation,
        message.configID,
        quorum.configID);
        return;
    }

    if (!quorum.isWatchingPaxosID)
    {
        Log_Message("Activating shard server %U in quorum %U: Starting to monitor the primary's paxosID",
         quorum.quorumID, quorum.activatingNodeID);

        quorum.OnActivationMonitoring(message.paxosID);
        configServer->OnConfigStateChanged();
    }
    else
    {
        Log_Trace();

        // if the primary was able to increase its paxosID, the new shardserver joined successfully
        if (message.paxosID > quorum.activationPaxosID)
        {
            Log_Message("Activating shard server %U in quorum %U: The primary was able to increase its paxosID!",
             quorum.quorumID, quorum.activatingNodeID);

            quorum.OnActivationReplication();
            configServer->OnConfigStateChanged();
            configServer->GetQuorumProcessor()->ActivateNode(quorum.quorumID, quorum.activatingNodeID);
        }
        else
        {
            Log_Message("Activating shard server %U in quorum %U: The primary was not able to increase its paxosID so far...",
             quorum.quorumID, quorum.activatingNodeID);
        }
    }
}

void ConfigActivationManager::OnActivationTimeout()
{
    uint64_t            now;
    ConfigState*        configState;
    ConfigQuorum*       itQuorum;
    ConfigShardServer*  shardServer;

    Log_Trace();

    now = EventLoop::Now();
    configState = configServer->GetDatabaseManager()->GetConfigState();

    FOREACH(itQuorum, configState->quorums)
    {
        if (itQuorum->activationExpireTime > 0 && itQuorum->activationExpireTime < now)
        {
            // stop activation

            assert(itQuorum->isActivatingNode == true);
            assert(itQuorum->isReplicatingActivation == false);

            shardServer = configState->GetShardServer(itQuorum->activatingNodeID);
            assert(shardServer != NULL);

            Log_Message("Activating shard server %U in quorum %U: Activation failed...",
             itQuorum->activatingNodeID, itQuorum->quorumID);

            itQuorum->ClearActivation();

            configServer->OnConfigStateChanged();
        }
    }

    UpdateTimeout();
}

void ConfigActivationManager::UpdateTimeout()
{
    ConfigQuorum*   it;
    uint64_t        activationExpireTime;

    Log_Trace();

    activationExpireTime = 0;
    FOREACH(it, configServer->GetDatabaseManager()->GetConfigState()->quorums)
    {
        if (it->isActivatingNode && !it->isReplicatingActivation)
        {
            if (activationExpireTime == 0 || it->activationExpireTime < activationExpireTime)
                activationExpireTime = it->activationExpireTime;
        }
    }

    if (activationExpireTime > 0)
    {
        activationTimeout.SetExpireTime(activationExpireTime);
        EventLoop::Reset(&activationTimeout);
    }
}
<|endoftext|>


<commit_before>#include "itkPNGImageIO.h"
#include "itkRawImageIO.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkCannySegmentationLevelSetImageFilter.h"
#include "itkCastImageFilter.h"
#include <iostream>

extern "C" {
#include <stdio.h>
}

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

  // Test for command line arguments.
  if (argc != 14)
    {
      std::cerr << "Usage: " << argv[0]
                << " input_image input_model output_model output_features iterations max_rms_change threshold variance propagation_scaling advection_scaling curvature_scaling isovalue negative_features"
                << std::endl;
      return 1;
    }

  // Grab the number of iterations and conductance term
  int iterations;
  int negative_features=0;
  float max_rms_change, threshold, outside_value, variance;
  float propagation_scaling, advection_scaling, curvature_scaling, isovalue;
  ::sscanf(argv[5], "%d", &iterations);
  ::sscanf(argv[6], "%f", &max_rms_change);
  ::sscanf(argv[7], "%f", &threshold);
  ::sscanf(argv[8], "%f", &variance);
  ::sscanf(argv[9], "%f", &propagation_scaling);
    ::sscanf(argv[10], "%f", &advection_scaling);
  ::sscanf(argv[11], "%f", &curvature_scaling);
  ::sscanf(argv[12], "%f", &isovalue);
  ::sscanf(argv[13], "%d", &negative_features);

  // Convenient typedefs
  typedef itk::Image<float, 2> RealImageType;
  typedef itk::Image<unsigned char, 2>  CharImageType;
  typedef itk::CastImageFilter<CharImageType, RealImageType> CastToRealFilterType;
    typedef itk::CannySegmentationLevelSetImageFilter<CharImageType, RealImageType>
      SegmentationFilterType;
    typedef SegmentationFilterType::VectorImageType VectorImageType;

  // Create a file IO object for reading PNG.
  itk::PNGImageIO::Pointer io = itk::PNGImageIO::New();
  io->SetNumberOfDimensions(2);

  // Create a file IO object for writing raw floats
  itk::RawImageIO<float, 2>::Pointer raw_io = itk::RawImageIO<float,2>::New();
  raw_io->SetFileDimensionality(2);
  raw_io->SetByteOrderToBigEndian();

  // Create two file readers
  itk::ImageFileReader<CharImageType>::Pointer seed_reader
    = itk::ImageFileReader<CharImageType>::New();
  itk::ImageFileReader<CharImageType>::Pointer feature_reader
    = itk::ImageFileReader<CharImageType>::New();
  seed_reader->SetImageIO(io);
  seed_reader->SetFileName(argv[2]);
  feature_reader->SetImageIO(io);
  feature_reader->SetFileName(argv[1]);

  // Create two file writers
  itk::ImageFileWriter<RealImageType>::Pointer model_writer
    = itk::ImageFileWriter<RealImageType>::New();
  itk::ImageFileWriter<RealImageType>::Pointer feature_writer
    = itk::ImageFileWriter<RealImageType>::New();
  feature_writer->SetImageIO(raw_io);
  feature_writer->SetFileName(argv[4]);
  model_writer->SetImageIO(raw_io);
  model_writer->SetFileName(argv[3]);

  // Create the casting filters
  CastToRealFilterType::Pointer to_real = CastToRealFilterType::New();

  // Create the segmentation filter
  SegmentationFilterType::Pointer segmentation = SegmentationFilterType::New();
  segmentation->SetMaximumIterations(iterations);
  segmentation->SetMaximumRMSError(max_rms_change);
  segmentation->SetPropagationScaling(propagation_scaling);
  segmentation->SetAdvectionScaling(advection_scaling);
  segmentation->SetCurvatureScaling(curvature_scaling);
  segmentation->SetIsoSurfaceValue(isovalue);
  segmentation->SetThreshold(threshold);
  segmentation->SetVariance(variance);
  if (negative_features != 0)
    {
      segmentation->SetUseNegativeFeatures(true);
    }
  // Connect the pipeline
  to_real->SetInput(feature_reader->GetOutput());
  segmentation->SetInput(seed_reader->GetOutput());
  model_writer->SetInput(segmentation->GetOutput());

  // Execute the pipeline
  try {
    //    to_real->Update(); // In the future, the feature image will be a proper
                       // input to the segmenation filter and this step will
                       // not be necessary.

    segmentation->SetFeatureImage(to_real->GetOutput());

    model_writer->Write();

        feature_writer->SetInput(segmentation->GetSpeedImage());
        feature_writer->Write();
  }
  catch(itk::ExceptionObject &e)
    {
      std::cerr << "Caught ITK exception: " << e << std::endl;
      return 1;
    }

  return 0;
}
<commit_msg>FIX: Warning fix on IRIX and Solaris<commit_after>#include "itkPNGImageIO.h"
#include "itkRawImageIO.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkCannySegmentationLevelSetImageFilter.h"
#include "itkCastImageFilter.h"
#include <iostream>

extern "C" {
#include <stdio.h>
}

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

  // Test for command line arguments.
  if (argc != 14)
    {
      std::cerr << "Usage: " << argv[0]
                << " input_image input_model output_model output_features iterations max_rms_change threshold variance propagation_scaling advection_scaling curvature_scaling isovalue negative_features"
                << std::endl;
      return 1;
    }

  // Grab the number of iterations and conductance term
  int iterations;
  int negative_features=0;
  float max_rms_change, threshold, variance;
  float propagation_scaling, advection_scaling, curvature_scaling, isovalue;
  ::sscanf(argv[5], "%d", &iterations);
  ::sscanf(argv[6], "%f", &max_rms_change);
  ::sscanf(argv[7], "%f", &threshold);
  ::sscanf(argv[8], "%f", &variance);
  ::sscanf(argv[9], "%f", &propagation_scaling);
    ::sscanf(argv[10], "%f", &advection_scaling);
  ::sscanf(argv[11], "%f", &curvature_scaling);
  ::sscanf(argv[12], "%f", &isovalue);
  ::sscanf(argv[13], "%d", &negative_features);

  // Convenient typedefs
  typedef itk::Image<float, 2> RealImageType;
  typedef itk::Image<unsigned char, 2>  CharImageType;
  typedef itk::CastImageFilter<CharImageType, RealImageType> CastToRealFilterType;
    typedef itk::CannySegmentationLevelSetImageFilter<CharImageType, RealImageType>
      SegmentationFilterType;
    typedef SegmentationFilterType::VectorImageType VectorImageType;

  // Create a file IO object for reading PNG.
  itk::PNGImageIO::Pointer io = itk::PNGImageIO::New();
  io->SetNumberOfDimensions(2);

  // Create a file IO object for writing raw floats
  itk::RawImageIO<float, 2>::Pointer raw_io = itk::RawImageIO<float,2>::New();
  raw_io->SetFileDimensionality(2);
  raw_io->SetByteOrderToBigEndian();

  // Create two file readers
  itk::ImageFileReader<CharImageType>::Pointer seed_reader
    = itk::ImageFileReader<CharImageType>::New();
  itk::ImageFileReader<CharImageType>::Pointer feature_reader
    = itk::ImageFileReader<CharImageType>::New();
  seed_reader->SetImageIO(io);
  seed_reader->SetFileName(argv[2]);
  feature_reader->SetImageIO(io);
  feature_reader->SetFileName(argv[1]);

  // Create two file writers
  itk::ImageFileWriter<RealImageType>::Pointer model_writer
    = itk::ImageFileWriter<RealImageType>::New();
  itk::ImageFileWriter<RealImageType>::Pointer feature_writer
    = itk::ImageFileWriter<RealImageType>::New();
  feature_writer->SetImageIO(raw_io);
  feature_writer->SetFileName(argv[4]);
  model_writer->SetImageIO(raw_io);
  model_writer->SetFileName(argv[3]);

  // Create the casting filters
  CastToRealFilterType::Pointer to_real = CastToRealFilterType::New();

  // Create the segmentation filter
  SegmentationFilterType::Pointer segmentation = SegmentationFilterType::New();
  segmentation->SetMaximumIterations(iterations);
  segmentation->SetMaximumRMSError(max_rms_change);
  segmentation->SetPropagationScaling(propagation_scaling);
  segmentation->SetAdvectionScaling(advection_scaling);
  segmentation->SetCurvatureScaling(curvature_scaling);
  segmentation->SetIsoSurfaceValue(isovalue);
  segmentation->SetThreshold(threshold);
  segmentation->SetVariance(variance);
  if (negative_features != 0)
    {
      segmentation->SetUseNegativeFeatures(true);
    }
  // Connect the pipeline
  to_real->SetInput(feature_reader->GetOutput());
  segmentation->SetInput(seed_reader->GetOutput());
  model_writer->SetInput(segmentation->GetOutput());

  // Execute the pipeline
  try {
    //    to_real->Update(); // In the future, the feature image will be a proper
                       // input to the segmenation filter and this step will
                       // not be necessary.

    segmentation->SetFeatureImage(to_real->GetOutput());

    model_writer->Write();

        feature_writer->SetInput(segmentation->GetSpeedImage());
        feature_writer->Write();
  }
  catch(itk::ExceptionObject &e)
    {
      std::cerr << "Caught ITK exception: " << e << std::endl;
      return 1;
    }

  return 0;
}
<|endoftext|>


<commit_before>#ifndef _EXAMPLES__BORIS__BORIS_SWEEPER__HPP_
#define _EXAMPLES__BORIS__BORIS_SWEEPER__HPP_

#include <cstdlib>
#include <map>
#include <cassert>

#include <pfasst/encap/encap_sweeper.hpp>

#include "particle_2d.hpp"
#include "physics.hpp"

using namespace std;
using namespace pfasst;
using namespace pfasst::encap;

typedef map<pair<size_t, size_t>, double> error_map;

template<
  typename scalar,
  typename time = time_precision
>
class BorisSweeper
  : public EncapSweeper<time>
{
  public:
    typedef Particle2DEncapsulation<scalar, time> encap_type;
    typedef Particle2DFactory<scalar, time> factory_type;
    typedef ElectricField<scalar, time, Particle2DEncapsulation> e_field_type;
    typedef MagneticField<scalar, time, Particle2DEncapsulation> b_field_type;

  private:
    shared_ptr<e_field_type> e_field;
    shared_ptr<b_field_type> b_field;
    error_map errors;

  protected:
    vector<shared_ptr<encap_type>> particles;

  public:
    //! @{
    BorisSweeper()
      :   e_field(nullptr)
        , b_field(nullptr)
        , errors()
    {}

    BorisSweeper(const BorisSweeper<scalar, time>& other) = delete;
    BorisSweeper(BorisSweeper<scalar, time>&& other) = delete;

    virtual ~BorisSweeper()
    {}
    //! @}

    //! @{
    virtual void set_state(shared_ptr<const Encapsulation<time>> u0, size_t m) override
    {
      shared_ptr<const encap_type> u0_cast = dynamic_pointer_cast<const encap_type>(u0);
      assert(u0_cast);
      this->set_state(u0_cast, m);
    }
    virtual void set_state(shared_ptr<const encap_type> u0, size_t m)
    {
      UNUSED(u0); UNUSED(m);
      // TODO: implement set_state for BorisSweeper
    }
    virtual shared_ptr<Encapsulation<time>> get_state(size_t m) const override
    {
      UNUSED(m);
      // TODO: implement get_state for BorisSweeper
      return NULL;
    }

    virtual shared_ptr<Encapsulation<time>> get_tau(size_t m) const override
    {
      UNUSED(m);
      // TODO: implement get_tau for BorisSweeper
      return NULL;
    }

    virtual shared_ptr<Encapsulation<time>> get_saved_state(size_t m) const override
    {
      UNUSED(m);
      // TODO: implement get_saved_state for BorisSweeper
      return NULL;
    }
    //! @}

    //! @{
    virtual void set_e_field(shared_ptr<const e_field_type> e_field)
    {
      this->e_field = const_pointer_cast<e_field_type>(e_field);
    }
    virtual shared_ptr<e_field_type> get_e_field()
    {
      return this->e_field;
    }
    virtual void set_b_field(shared_ptr<const b_field_type> b_field)
    {
      this->b_field = const_pointer_cast<b_field_type>(b_field);
    }
    virtual shared_ptr<b_field_type> get_b_field()
    {
      return this->b_field;
    }
    //! @}

    //! @{
    virtual void exact(shared_ptr<Encapsulation<time>> q, time t)
    {
      shared_ptr<encap_type> q_cast = dynamic_pointer_cast<encap_type>(q);
      assert(q_cast);
      this->exact(q_cast, t);
    }
    virtual void exact(shared_ptr<encap_type> q, time t)
    {
      UNUSED(q); UNUSED(t);
      // TODO: implement exact solution for Boris
    }

    virtual void echo_error(time t, bool predict = false) const
    {
      UNUSED(t); UNUSED(predict);
      // TODO: implement echo_error
    }

    virtual error_map get_errors() const
    {
      return this->errors;
    }
    //! @}

    //! @{
    virtual void setup(bool coarse = false) override
    {
      UNUSED(coarse);
      // TODO: implement setup for BorisSweeper
    }
    virtual void advance() override
    {
      // TODO: implement advance for BorisSweeper
    }
    virtual void evaluate(size_t m) override
    {
      UNUSED(m);
      // TODO: implement evaluate for BorisSweeper
    }
    virtual void predict(bool initial) override
    {
      UNUSED(initial);
      // TODO: implement predict for BorisSweeper
    }

    virtual void sweep() override
    {
      // TODO: implement sweep for BorisSweeper
    }

    virtual void save(bool initial_only=false) override
    {
      UNUSED(initial_only);
      // TODO: implement save for BorisSweeper
    }
    virtual void spread() override
    {
      // TODO: implement spread for BorisSweeper
    }
    //! @}

    //! @{
      virtual void post(ICommunicator* comm, int tag) override
      {
        UNUSED(comm); UNUSED(tag);
      };

      virtual void send(ICommunicator* comm, int tag, bool blocking) override
      {
        UNUSED(comm); UNUSED(tag); UNUSED(blocking);
        NotImplementedYet("pfasst");
      }

      virtual void recv(ICommunicator* comm, int tag, bool blocking) override
      {
        UNUSED(comm); UNUSED(tag); UNUSED(blocking);
        NotImplementedYet("pfasst");
      }

      virtual void broadcast(ICommunicator* comm) override
      {
        UNUSED(comm);
        NotImplementedYet("pfasst");
      }
    //! @}
};

#endif  // _EXAMPLES__BORIS__BORIS_SWEEPER__HPP_
<commit_msg>examples: boris: first compiling version of Boris impl_solve<commit_after>#ifndef _EXAMPLES__BORIS__BORIS_SWEEPER__HPP_
#define _EXAMPLES__BORIS__BORIS_SWEEPER__HPP_

#include <cstdlib>
#include <vector>
#include <map>
#include <cassert>

#include <boost/numeric/ublas/matrix.hpp>
using boost::numeric::ublas::matrix;

#include <pfasst/encap/encap_sweeper.hpp>

#include "particle.hpp"
#include "particle_3d.hpp"
#include "physics.hpp"

using namespace std;
using namespace pfasst;
using namespace pfasst::encap;

typedef map<pair<size_t, size_t>, double> error_map;

template<
  typename scalar,
  typename time = time_precision
>
class BorisSweeper
  : public EncapSweeper<time>
{
  public:
    typedef Particle3DEncapsulation<scalar, time> encap_type;
    typedef typename encap_type::position_type position_type;
    typedef typename encap_type::velocity_type velocity_type;
    typedef typename encap_type::acceleration_type acceleration_type;
    typedef Particle3DFactory<scalar, time> factory_type;
    typedef ElectricField<scalar, time, Particle3DEncapsulation> e_field_type;
    typedef MagneticField<scalar, time, Particle3DEncapsulation> b_field_type;

  private:
    shared_ptr<e_field_type> e_field;
    shared_ptr<b_field_type> b_field;
    error_map errors;

  protected:
    vector<shared_ptr<encap_type>> particles;
    vector<shared_ptr<encap_type>> previous_particles;
    vector<shared_ptr<encap_type>> tau_corrections;

    vector<shared_ptr<velocity_type>> s_integrals;
    vector<shared_ptr<position_type>> ss_integrals;

    //! delta_nodes[m] = nodes[m] - nodes[m-1]
    vector<time> delta_nodes;

    matrix<time> s_mat;
    matrix<time> ss_mat;
    matrix<time> qx_mat;
    matrix<time> qt_mat;

  public:
    //! @{
    BorisSweeper()
      :   e_field(nullptr)
        , b_field(nullptr)
        , errors()
    {}

    BorisSweeper(const BorisSweeper<scalar, time>& other) = delete;
    BorisSweeper(BorisSweeper<scalar, time>&& other) = delete;

    virtual ~BorisSweeper()
    {}
    //! @}

    //! @{
    virtual void set_nodes(vector<time> nodes) override
    {
      EncapSweeper<time>::set_nodes(nodes);

      // compute delta nodes
      size_t nnodes = this->nodes.size();
      this->delta_nodes = vector<time>(nnodes, time(0.0));
      for (size_t m = 1; m < nnodes; m++) {
        delta_nodes[m] = nodes[m] - nodes[m - 1];
      }
    }

    virtual void set_state(shared_ptr<const Encapsulation<time>> u0, size_t m) override
    {
      shared_ptr<const encap_type> u0_cast = dynamic_pointer_cast<const encap_type>(u0);
      assert(u0_cast);
      this->set_state(u0_cast, m);
    }

    virtual void set_state(shared_ptr<const encap_type> u0, size_t m)
    {
      this->particles[m]->copy(u0);
    }

    virtual shared_ptr<Encapsulation<time>> get_state(size_t m) const override
    {
      return this->particles[m];
    }

    virtual shared_ptr<Encapsulation<time>> get_tau(size_t m) const override
    {
      return this->tau_corrections[m];
    }

    virtual shared_ptr<Encapsulation<time>> get_saved_state(size_t m) const override
    {
      return this->previous_particles[m];
    }
    //! @}

    //! @{
    virtual void set_e_field(shared_ptr<const e_field_type> e_field)
    {
      this->e_field = const_pointer_cast<e_field_type>(e_field);
    }

    virtual shared_ptr<e_field_type> get_e_field()
    {
      return this->e_field;
    }

    virtual void set_b_field(shared_ptr<const b_field_type> b_field)
    {
      this->b_field = const_pointer_cast<b_field_type>(b_field);
    }

    virtual shared_ptr<b_field_type> get_b_field()
    {
      return this->b_field;
    }
    //! @}

    //! @{
    virtual void exact(shared_ptr<Encapsulation<time>> q, time t)
    {
      shared_ptr<encap_type> q_cast = dynamic_pointer_cast<encap_type>(q);
      assert(q_cast);
      this->exact(q_cast, t);
    }

    virtual void exact(shared_ptr<encap_type> q, time t)
    {
      UNUSED(q); UNUSED(t);
      // TODO: implement exact solution for Boris
    }

    virtual void echo_error(time t, bool predict = false) const
    {
      UNUSED(t); UNUSED(predict);
      // TODO: implement echo_error
    }

    virtual error_map get_errors() const
    {
      return this->errors;
    }
    //! @}

    //! @{
    virtual void setup(bool coarse = false) override
    {
      vector<time> nodes = this->get_nodes();
      auto is_proper = this->get_is_proper();
      assert(nodes.size() >= 1);
      size_t nnodes = nodes.size();

      matrix<time> q_mat = compute_quadrature(nodes, nodes, is_proper, QuadratureMatrix::Q);
      assert(q_mat.size1() == q_mat.size2());
      matrix<time> qq_mat = matrix<time>(nnodes, nnodes, time(0.0));
      this->s_mat = matrix<time>(nnodes, nnodes, time(0.0));
      this->qt_mat = matrix<time>(nnodes, nnodes, time(0.0));
      this->qx_mat = matrix<time>(nnodes, nnodes, time(0.0));
      this->ss_mat = matrix<time>(nnodes, nnodes, time(0.0));

      // compute QQ, S, SS, Q_T, Q_x
      // building rules for Q_E and Q_I:
      //  Q_E is striclty lower diagonal matrix with delta nodes of column index
      //  Q_I is lower diagonal matrix with first row and column all zero and delta nodes of
      //      column index minus one
      // TODO: should use Boost's matrix product function here sometime
      for (size_t i = 0; i < nnodes; i++) {
        for (size_t j = 0; i < nnodes; j++) {
          // Q_T = 0.5 * (Q_E + Q_I)
          this->s_mat(i, j) = q_mat(i, j) - ((i > 0) ? q_mat(i - 1, j) : time(0.0));

          this->qt_mat(i, j) = time(0.5) * (((j < i) ? delta_nodes[j + 1] : time(0.0)) +
                                            ((j > 0 && j <= i) ? delta_nodes[j + 1] : time(0.0)));

          for (size_t k = 0; k < nnodes; k++) {
            qq_mat(i, j) += q_mat(i, k) * q_mat(k, j);

            // Q_x = Q_E * Q_T + 0.5 * (Q_E ∘ Q_E)
            //  (only first term, i.e. matrix product)
            this->qx_mat(i, j) += ((k < i) ? delta_nodes[k + 1] : time(0.0)) * this->qt_mat(k, j);
          }
          // continuation of Q_x
          //  (i.e. Hadamard product of Q_E)
          this->qx_mat(i, j) += 0.5 * ((j < i) ? delta_nodes[j + 1] * delta_nodes[j + 1] : time(0.0));

          this->ss_mat(i, j) = qq_mat(i, j) - ((i > 0) ? qq_mat(i - 1, j) : time(0.0));
        }
      }

      UNUSED(coarse);
      // TODO: implement setup for BorisSweeper
    }

    virtual void advance() override
    {
      this->particles[0]->copy(const_pointer_cast<const encap_type>(this->particles.back()));
    }

    virtual void evaluate(size_t m) override
    {
      UNUSED(m);
      // TODO: implement evaluate for BorisSweeper
    }

    virtual void predict(bool initial) override
    {
      UNUSED(initial);
      // TODO: implement predict for BorisSweeper
    }

    virtual void sweep() override
    {
      const auto   nodes  = this->get_nodes();
      const size_t nnodes = nodes.size();
      assert(nnodes >= 1);
      velocity_type c_k_term;

      // compute integrals
      for (size_t m = 1; m < nnodes; m++) {
        this->s_integrals[m]->zero();
        this->ss_integrals[m]->zero();
        for (size_t l = 1; l < nnodes; l++) {
          *(this->s_integrals[l].get()) += this->previous_particles[l]
                                               ->accel->convert(dt<time>(this->s_mat(m, l)));
          *(this->ss_integrals[l].get()) += this->previous_particles[l]
                                               ->accel->convert(dtdt<time>(this->ss_mat(m, l)));
        }
      }

      for (size_t m = 0; m < nnodes - 1; m++) {
        ::dt<time> dt(this->delta_nodes[m+1]);

        //// Update Position (explicit)
        //
        // x_{m+1}^{k+1} = x_{m}^{k}
        this->particles[m+1]->pos->copy(this->particles[m]->const_pos());
        //               + delta_nodes_{m} * v_{0}
        *(this->particles[m+1]->pos.get()) += this->particles[0]->vel->convert(dt);
        //               + \sum_{l=1}^{m} s_{m+1,l}^{x} (f_{l}^{k+1} - f_{l}^{k})
        for (size_t l = 1; l < m; l++) {
          *(this->particles[m+1]->pos.get()) += this->particles[l]->accel
                                                    ->convert(dtdt<time>(this->qx_mat(m+1, l)));
          this->particles[m+1]->pos->saxpy(-1.0,
                                           this->previous_particles[l]->accel
                                               ->convert(dtdt<time>(this->qx_mat(m+1,l))));
        }
        //               + ss_integral[m]
        for (size_t l = 1; l < nnodes; l++) {
          *(this->particles[m+1]->pos.get()) += this->ss_integrals[l];
        }

        //// Update Velocity (semi-implicit)
        //
        c_k_term.zero();  // reset
        //                 - delta_nodes_{m} / 2 * f_{m+1}^{k}
        c_k_term.saxpy(-0.5, this->previous_particles[m+1]->accel->convert(dt));
        //                 - delta_nodes_{m} / 2 * f_{m}^{k}
        c_k_term.saxpy(-0.5, this->previous_particles[m]->accel->convert(dt));
        //                 + s_integral[m]
        for (size_t l = 1; l < nnodes; l++) {
          c_k_term += this->s_integrals[l];
        }

        // doing Boris' magic
        this->boris_solve(nodes[m], nodes[m+1], dt, m, c_k_term);
      }
    }

    virtual void save(bool initial_only=false) override
    {
      if (initial_only) {
        this->previous_particles[0]->copy(const_pointer_cast<const encap_type>(this->particles[0]));
      } else {
        for (size_t m = 0; m < this->previous_particles.size(); m++) {
          this->previous_particles[m]->copy(const_pointer_cast<const encap_type>(this->particles[m]));
        }
      }
    }

    virtual void spread() override
    {
      // TODO: implement spread for BorisSweeper
    }
    //! @}

    //! @{
      virtual void post(ICommunicator* comm, int tag) override
      {
        UNUSED(comm); UNUSED(tag);
      };

      virtual void send(ICommunicator* comm, int tag, bool blocking) override
      {
        UNUSED(comm); UNUSED(tag); UNUSED(blocking);
        NotImplementedYet("pfasst");
      }

      virtual void recv(ICommunicator* comm, int tag, bool blocking) override
      {
        UNUSED(comm); UNUSED(tag); UNUSED(blocking);
        NotImplementedYet("pfasst");
      }

      virtual void broadcast(ICommunicator* comm) override
      {
        UNUSED(comm);
        NotImplementedYet("pfasst");
      }
    //! @}

    //! @{
    virtual void boris_solve(const time tm, const time t_next, const ::dt<time> dt, const size_t m,
                             const velocity_type& c_k_term)
    {
      velocity_type c_k_term_half(scalar(0.5) * c_k_term);
      ::dt<time> beta(this->particles[m]->charge * dt.v / (scalar(2.0) * this->particles[m]->mass));
      acceleration_type e_mean = (this->e_field->evaluate(this->particles[m], tm)
                                  - this->e_field->evaluate(this->particles[m+1], tm))
                                 * scalar(0.5);

      // v^{-} = v^{k}
      velocity_type v_minus(this->particles[m]->const_vel());

      // first Boris' drift
      //         + \beta * E_{mean} + c^{k} / 2
      v_minus += e_mean.convert(beta) + c_k_term_half;

      // Boris' kick
      velocity_type boris_t = this->b_field->evaluate(this->particles[m], t_next).convert(beta);
      velocity_type boris_s = (scalar(2.0) * boris_t) / (scalar(1.0) + (boris_t * boris_t));
      velocity_type v_prime(v_minus + boris_t * v_minus);

      // final Boris' drift
      velocity_type v_plus(v_minus + v_prime * boris_s);

      this->particles[m+1]->vel->copy(v_plus + e_mean.convert(beta) + c_k_term_half);
    }
    //! @}
};

#endif  // _EXAMPLES__BORIS__BORIS_SWEEPER__HPP_
<|endoftext|>


<commit_before>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2010-2013 Francois Beaune, Jupiter Jazz Limited
// Copyright (c) 2014 Francois Beaune, The appleseedhq Organization
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

// Interface header.
#include "xercesc.h"

using namespace std;
using namespace xercesc;

namespace foundation
{

//
// XercesCManager class implementation.
//

boost::mutex XercesCManager::s_mutex;

bool XercesCManager::initialize()
{
    boost::mutex::scoped_lock lock(s_mutex);

    try
    {
        XMLPlatformUtils::Initialize();
    }
    catch (const XMLException&)
    {
        return false;
    }

    return true;
}

bool XercesCManager::initialize(Logger& logger)
{
    boost::mutex::scoped_lock lock(s_mutex);

    try
    {
        XMLPlatformUtils::Initialize();
    }
    catch (const XMLException& e)
    {
        LOG_ERROR(
            logger,
            "failed to initialize Xerces-C++ library: %s.",
            transcode(e.getMessage()).c_str());

        return false;
    }

    return true;
}

void XercesCManager::terminate()
{
    boost::mutex::scoped_lock lock(s_mutex);

    XMLPlatformUtils::Terminate();
}

//
// XercesCContext class implementation.
//

XercesCContext::XercesCContext()
{
    m_initialized = XercesCManager::initialize();
}

XercesCContext::XercesCContext(Logger& logger)
{
    m_initialized = XercesCManager::initialize(logger);
}

XercesCContext::~XercesCContext()
{
    XercesCManager::terminate();
}

bool XercesCContext::is_initialized() const
{
    return m_initialized;
}

//
// ErrorLogger class implementation.
//

ErrorLogger::ErrorLogger(
    Logger&         logger,
    const string&   input_filename)
  : m_logger(logger)
  , m_input_filename(input_filename)
{
    resetErrors();
}

void ErrorLogger::resetErrors()
{
    m_warning_count = 0;
    m_error_count = 0;
    m_fatal_error_count = 0;
}

void ErrorLogger::warning(const SAXParseException& e)
{
    ++m_warning_count;

    print(LogMessage::Warning, e);
}

void ErrorLogger::error(const SAXParseException& e)
{
    ++m_error_count;

    print(LogMessage::Error, e);
}

void ErrorLogger::fatalError(const SAXParseException& e)
{
    ++m_fatal_error_count;

    #ifndef WITH_EXTERNAL_XERCES
        switch (e.getOriginalExceptionCode())
        {
          // Using our modified version of Xerces-C++, we can catch the case where
          // it failed to open the input file, and print a reasonable error message.
          case XMLExcepts::Scan_CouldNotOpenSource:
            LOG_ERROR(
                m_logger,
                "failed to open %s for reading.",
                m_input_filename.c_str());
            break;

          // For now, all other errors will be reported as is.
          default:
            print(LogMessage::Error, e);
            break;
        }
    #else
        print(LogMessage::Error, e);
    #endif
}

size_t ErrorLogger::get_warning_count() const
{
    return m_warning_count;
}

size_t ErrorLogger::get_error_count() const
{
    return m_error_count;
}

size_t ErrorLogger::get_fatal_error_count() const
{
    return m_fatal_error_count;
}

void ErrorLogger::print(
    const LogMessage::Category  category,
    const SAXParseException&    e) const
{
    LOG(
        m_logger,
        category,
        "while reading %s: %s.",
        m_input_filename.c_str(),
        transcode(e.getMessage()).c_str());
}

}   // namespace foundation
<commit_msg>fixed formatting.<commit_after>
//
// This source file is part of appleseed.
// Visit http://appleseedhq.net/ for additional information and resources.
//
// This software is released under the MIT license.
//
// Copyright (c) 2010-2013 Francois Beaune, Jupiter Jazz Limited
// Copyright (c) 2014 Francois Beaune, The appleseedhq Organization
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//

// Interface header.
#include "xercesc.h"

using namespace std;
using namespace xercesc;

namespace foundation
{

//
// XercesCManager class implementation.
//

boost::mutex XercesCManager::s_mutex;

bool XercesCManager::initialize()
{
    boost::mutex::scoped_lock lock(s_mutex);

    try
    {
        XMLPlatformUtils::Initialize();
    }
    catch (const XMLException&)
    {
        return false;
    }

    return true;
}

bool XercesCManager::initialize(Logger& logger)
{
    boost::mutex::scoped_lock lock(s_mutex);

    try
    {
        XMLPlatformUtils::Initialize();
    }
    catch (const XMLException& e)
    {
        LOG_ERROR(
            logger,
            "failed to initialize Xerces-C++ library: %s.",
            transcode(e.getMessage()).c_str());

        return false;
    }

    return true;
}

void XercesCManager::terminate()
{
    boost::mutex::scoped_lock lock(s_mutex);

    XMLPlatformUtils::Terminate();
}

//
// XercesCContext class implementation.
//

XercesCContext::XercesCContext()
{
    m_initialized = XercesCManager::initialize();
}

XercesCContext::XercesCContext(Logger& logger)
{
    m_initialized = XercesCManager::initialize(logger);
}

XercesCContext::~XercesCContext()
{
    XercesCManager::terminate();
}

bool XercesCContext::is_initialized() const
{
    return m_initialized;
}

//
// ErrorLogger class implementation.
//

ErrorLogger::ErrorLogger(
    Logger&         logger,
    const string&   input_filename)
  : m_logger(logger)
  , m_input_filename(input_filename)
{
    resetErrors();
}

void ErrorLogger::resetErrors()
{
    m_warning_count = 0;
    m_error_count = 0;
    m_fatal_error_count = 0;
}

void ErrorLogger::warning(const SAXParseException& e)
{
    ++m_warning_count;

    print(LogMessage::Warning, e);
}

void ErrorLogger::error(const SAXParseException& e)
{
    ++m_error_count;

    print(LogMessage::Error, e);
}

void ErrorLogger::fatalError(const SAXParseException& e)
{
    ++m_fatal_error_count;

#ifndef WITH_EXTERNAL_XERCES
    switch (e.getOriginalExceptionCode())
    {
      // Using our modified version of Xerces-C++, we can catch the case where
      // it failed to open the input file, and print a reasonable error message.
      case XMLExcepts::Scan_CouldNotOpenSource:
        LOG_ERROR(
            m_logger,
            "failed to open %s for reading.",
            m_input_filename.c_str());
        break;

      // For now, all other errors will be reported as is.
      default:
        print(LogMessage::Error, e);
        break;
    }
#else
    print(LogMessage::Error, e);
#endif
}

size_t ErrorLogger::get_warning_count() const
{
    return m_warning_count;
}

size_t ErrorLogger::get_error_count() const
{
    return m_error_count;
}

size_t ErrorLogger::get_fatal_error_count() const
{
    return m_fatal_error_count;
}

void ErrorLogger::print(
    const LogMessage::Category  category,
    const SAXParseException&    e) const
{
    LOG(
        m_logger,
        category,
        "while reading %s: %s.",
        m_input_filename.c_str(),
        transcode(e.getMessage()).c_str());
}

}   // namespace foundation
<|endoftext|>


<commit_before>/*=============================================================================

  Library: CTK

  Copyright (c) German Cancer Research Center,
    Division of Medical and Biological Informatics

  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 <ctkCmdLineModuleManager.h>
#include <ctkCmdLineModuleFrontendFactory.h>
#include <ctkCmdLineModuleFrontend.h>
#include <ctkCmdLineModuleReference.h>
#include <ctkCmdLineModuleDescription.h>
#include <ctkCmdLineModuleParameter.h>
#include <ctkCmdLineModuleRunException.h>
#include <ctkCmdLineModuleFuture.h>
#include <ctkCmdLineModuleFutureWatcher.h>

#include "ctkCmdLineModuleSignalTester.h"

#include "ctkCmdLineModuleBackendLocalProcess.h"

#include "ctkTest.h"

#include <QVariant>
#include <QCoreApplication>
#include <QDebug>
#include <QFutureWatcher>

//-----------------------------------------------------------------------------
class ctkCmdLineModuleFrontendMockupFactory : public ctkCmdLineModuleFrontendFactory
{
public:

  virtual ctkCmdLineModuleFrontend* create(const ctkCmdLineModuleReference& moduleRef)
  {
    struct ModuleFrontendMockup : public ctkCmdLineModuleFrontend
    {
      ModuleFrontendMockup(const ctkCmdLineModuleReference& moduleRef)
        : ctkCmdLineModuleFrontend(moduleRef) {}

      virtual QObject* guiHandle() const { return NULL; }

      virtual QVariant value(const QString& parameter, int role) const
      {
        Q_UNUSED(role)
        QVariant value = currentValues[parameter];
        if (!value.isValid())
          return this->moduleReference().description().parameter(parameter).defaultValue();
        return value;
      }

      virtual void setValue(const QString& parameter, const QVariant& value)
      {
        currentValues[parameter] = value;
      }

    private:

      QHash<QString, QVariant> currentValues;
    };

    return new ModuleFrontendMockup(moduleRef);
  }

  virtual QString name() const { return "Mock-up"; }
  virtual QString description() const { return "A mock-up factory for testing."; }
};

//-----------------------------------------------------------------------------
class ctkCmdLineModuleFutureTester : public QObject
{
  Q_OBJECT

public Q_SLOTS:

  void ouputDataReady();
  void errorDataReady();

private Q_SLOTS:

  void initTestCase();

  void init();
  void cleanup();

  void testStartFinish();
  void testProgress();
  void testPauseAndCancel();
  void testOutput();
  void testError();

private:

  QByteArray outputData;
  QByteArray errorData;

  ctkCmdLineModuleFutureWatcher* currentWatcher;

  ctkCmdLineModuleFrontendMockupFactory factory;
  ctkCmdLineModuleBackendLocalProcess backend;

  ctkCmdLineModuleManager manager;

  ctkCmdLineModuleReference moduleRef;
  ctkCmdLineModuleFrontend* frontend;
};

//-----------------------------------------------------------------------------
void ctkCmdLineModuleFutureTester::ouputDataReady()
{
  if (this->currentWatcher)
  {
    outputData.append(currentWatcher->readPendingOutputData());
  }
}

//-----------------------------------------------------------------------------
void ctkCmdLineModuleFutureTester::errorDataReady()
{
  if (this->currentWatcher)
  {
    errorData.append(currentWatcher->readPendingErrorData());
  }
}

//-----------------------------------------------------------------------------
void ctkCmdLineModuleFutureTester::initTestCase()
{
  manager.registerBackend(&backend);

  QUrl moduleUrl = QUrl::fromLocalFile(QCoreApplication::applicationDirPath() + "/ctkCmdLineModuleTestBed");
  moduleRef = manager.registerModule(moduleUrl);
}

//-----------------------------------------------------------------------------
void ctkCmdLineModuleFutureTester::init()
{
  currentWatcher = 0;
  frontend = factory.create(moduleRef);
}

//-----------------------------------------------------------------------------
void ctkCmdLineModuleFutureTester::cleanup()
{
  delete frontend;
  outputData.clear();
  errorData.clear();
}

//-----------------------------------------------------------------------------
void ctkCmdLineModuleFutureTester::testStartFinish()
{
  QList<QString> expectedSignals;
  expectedSignals << "module.started"
                  << "module.progressRangeChanged(0,0)"
                  << "module.progressValueChanged(0)"
                  << "module.progressRangeChanged(0,1000)"
                  << "module.errorReady"
                  << "module.progressValueChanged(1000)"
                  << "module.finished";

  ctkCmdLineModuleSignalTester signalTester;

  ctkCmdLineModuleFuture future = manager.run(frontend);
  signalTester.setFuture(future);
  future.waitForFinished();

  QCoreApplication::processEvents();
  QVERIFY(signalTester.checkSignals(expectedSignals));
}

//-----------------------------------------------------------------------------
void ctkCmdLineModuleFutureTester::testProgress()
{
  QList<QString> expectedSignals;
  expectedSignals << "module.started"
                     // the following signals are send when connecting a QFutureWatcher to
                     // an already started QFuture
                  << "module.progressRangeChanged(0,0)"
                  << "module.progressValueChanged(0)"
                  << "module.progressRangeChanged(0,1000)"

                     // the test module always reports error data when starting
                  << "module.errorReady"

                     // the following two signals are send when the module reports "filter start"
                  << "module.progressValueChanged(1)"
                  << "module.progressTextChanged(Test Filter)"

                     // this signal is send when the module reports progress for "output1"
                  << "module.progressValueChanged(999)"

                     // the output data (the order is not really deterministic here...)
                  << "module.outputReady"

                     // the following signal is sent at the end to report completion
                  << "module.progressValueChanged(1000)"
                  << "module.finished";

  ctkCmdLineModuleSignalTester signalTester;

  frontend->setValue("numOutputsVar", 1);
  ctkCmdLineModuleFuture future = manager.run(frontend);
  signalTester.setFuture(future);

  future.waitForFinished();

  // process pending events
  QCoreApplication::processEvents();

  QVERIFY(signalTester.checkSignals(expectedSignals));
}

//-----------------------------------------------------------------------------
void ctkCmdLineModuleFutureTester::testPauseAndCancel()
{
  ctkCmdLineModuleSignalTester signalTester;

  frontend->setValue("runtimeVar", 60);
  ctkCmdLineModuleFuture future = manager.run(frontend);
  signalTester.setFuture(future);

  QList<QString> expectedSignals;
  expectedSignals << "module.started"
                  << "module.progressRangeChanged(0,0)"
                  << "module.progressValueChanged(0)"
                  << "module.progressRangeChanged(0,1000)"
                  << "module.errorReady";

  if (future.canPause())
  {
    // Due to Qt bug 12152, these two signals are reversed
    expectedSignals.push_back("module.resumed");
    expectedSignals.push_back("module.paused");
  }

  if (future.canCancel())
  {
    expectedSignals.push_back("module.canceled");
  }
  expectedSignals.push_back("module.finished");

  QTest::qWait(100);

  future.pause();
  QTest::qWait(100);

  QVERIFY(future.isRunning());
  if (future.canPause())
  {
    QVERIFY(future.isPaused());
  }

  future.togglePaused();

  QTest::qWait(100);

  QVERIFY(!future.isPaused());
  QVERIFY(future.isRunning());

  future.cancel();
  future.waitForFinished();

  // process pending events
  QCoreApplication::processEvents();

  QVERIFY(future.isCanceled());
  QVERIFY(future.isFinished());

  QVERIFY(signalTester.checkSignals(expectedSignals));
}

//-----------------------------------------------------------------------------
void ctkCmdLineModuleFutureTester::testOutput()
{
  ctkCmdLineModuleSignalTester signalTester;

  connect(signalTester.watcher(), SIGNAL(outputDataReady()), SLOT(ouputDataReady()));
  connect(signalTester.watcher(), SIGNAL(errorDataReady()), SLOT(errorDataReady()));

  this->currentWatcher = signalTester.watcher();

  frontend->setValue("numOutputsVar", 2);
  frontend->setValue("errorTextVar", "Final error msg.");
  ctkCmdLineModuleFuture future = manager.run(frontend);
  signalTester.setFuture(future);

  future.waitForFinished();

  // process pending events
  QCoreApplication::processEvents();

  QVERIFY(future.isFinished());

  QList<QString> expectedSignals;
  expectedSignals << "module.started"
                  << "module.progressRangeChanged(0,0)"
                  << "module.progressValueChanged(0)"
                  << "module.progressRangeChanged(0,1000)"
                  << "module.errorReady"
                  << "module.progressValueChanged(1)"
                  << "module.progressTextChanged(Test Filter)"
                  << "module.progressValueChanged(500)"
                  << "module.outputReady"
                  << "module.progressValueChanged(999)"
                  << "module.outputReady"
                  << "module.errorReady"
                  << "module.progressValueChanged(1000)"
                  << "module.finished";

  QVERIFY(signalTester.checkSignals(expectedSignals));

  const char* expectedOutput = "Output 1\nOutput 2\n";
  const char* expectedError = "A superficial error message.\nFinal error msg.";

  QCOMPARE(this->outputData.data(), expectedOutput);
  QCOMPARE(this->errorData.data(), expectedError);

  QCOMPARE(future.readAllOutputData().data(), expectedOutput);
  QCOMPARE(future.readAllErrorData().data(), expectedError);
}

//-----------------------------------------------------------------------------
void ctkCmdLineModuleFutureTester::testError()
{
  frontend->setValue("fileVar", "output1");
  frontend->setValue("exitCodeVar", 24);
  frontend->setValue("errorTextVar", "Some error occured\n");

  ctkCmdLineModuleFuture future = manager.run(frontend);

  try
  {
    future.waitForFinished();
    QFAIL("Expected exception not thrown.");
  }
  catch (const ctkCmdLineModuleRunException& e)
  {
    QVERIFY2(e.errorCode() == 24, "Test matching error code");
    QCOMPARE(future.readAllErrorData().data(), "A superficial error message.\nSome error occured\n");
  }
}

// ----------------------------------------------------------------------------
CTK_TEST_MAIN(ctkCmdLineModuleFutureTest)
#include "moc_ctkCmdLineModuleFutureTest.cpp"
<commit_msg>Avoid sending pause/resume signals if the future does not support it.<commit_after>/*=============================================================================

  Library: CTK

  Copyright (c) German Cancer Research Center,
    Division of Medical and Biological Informatics

  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 <ctkCmdLineModuleManager.h>
#include <ctkCmdLineModuleFrontendFactory.h>
#include <ctkCmdLineModuleFrontend.h>
#include <ctkCmdLineModuleReference.h>
#include <ctkCmdLineModuleDescription.h>
#include <ctkCmdLineModuleParameter.h>
#include <ctkCmdLineModuleRunException.h>
#include <ctkCmdLineModuleFuture.h>
#include <ctkCmdLineModuleFutureWatcher.h>

#include "ctkCmdLineModuleSignalTester.h"

#include "ctkCmdLineModuleBackendLocalProcess.h"

#include "ctkTest.h"

#include <QVariant>
#include <QCoreApplication>
#include <QDebug>
#include <QFutureWatcher>

//-----------------------------------------------------------------------------
class ctkCmdLineModuleFrontendMockupFactory : public ctkCmdLineModuleFrontendFactory
{
public:

  virtual ctkCmdLineModuleFrontend* create(const ctkCmdLineModuleReference& moduleRef)
  {
    struct ModuleFrontendMockup : public ctkCmdLineModuleFrontend
    {
      ModuleFrontendMockup(const ctkCmdLineModuleReference& moduleRef)
        : ctkCmdLineModuleFrontend(moduleRef) {}

      virtual QObject* guiHandle() const { return NULL; }

      virtual QVariant value(const QString& parameter, int role) const
      {
        Q_UNUSED(role)
        QVariant value = currentValues[parameter];
        if (!value.isValid())
          return this->moduleReference().description().parameter(parameter).defaultValue();
        return value;
      }

      virtual void setValue(const QString& parameter, const QVariant& value)
      {
        currentValues[parameter] = value;
      }

    private:

      QHash<QString, QVariant> currentValues;
    };

    return new ModuleFrontendMockup(moduleRef);
  }

  virtual QString name() const { return "Mock-up"; }
  virtual QString description() const { return "A mock-up factory for testing."; }
};

//-----------------------------------------------------------------------------
class ctkCmdLineModuleFutureTester : public QObject
{
  Q_OBJECT

public Q_SLOTS:

  void ouputDataReady();
  void errorDataReady();

private Q_SLOTS:

  void initTestCase();

  void init();
  void cleanup();

  void testStartFinish();
  void testProgress();
  void testPauseAndCancel();
  void testOutput();
  void testError();

private:

  QByteArray outputData;
  QByteArray errorData;

  ctkCmdLineModuleFutureWatcher* currentWatcher;

  ctkCmdLineModuleFrontendMockupFactory factory;
  ctkCmdLineModuleBackendLocalProcess backend;

  ctkCmdLineModuleManager manager;

  ctkCmdLineModuleReference moduleRef;
  ctkCmdLineModuleFrontend* frontend;
};

//-----------------------------------------------------------------------------
void ctkCmdLineModuleFutureTester::ouputDataReady()
{
  if (this->currentWatcher)
  {
    outputData.append(currentWatcher->readPendingOutputData());
  }
}

//-----------------------------------------------------------------------------
void ctkCmdLineModuleFutureTester::errorDataReady()
{
  if (this->currentWatcher)
  {
    errorData.append(currentWatcher->readPendingErrorData());
  }
}

//-----------------------------------------------------------------------------
void ctkCmdLineModuleFutureTester::initTestCase()
{
  manager.registerBackend(&backend);

  QUrl moduleUrl = QUrl::fromLocalFile(QCoreApplication::applicationDirPath() + "/ctkCmdLineModuleTestBed");
  moduleRef = manager.registerModule(moduleUrl);
}

//-----------------------------------------------------------------------------
void ctkCmdLineModuleFutureTester::init()
{
  currentWatcher = 0;
  frontend = factory.create(moduleRef);
}

//-----------------------------------------------------------------------------
void ctkCmdLineModuleFutureTester::cleanup()
{
  delete frontend;
  outputData.clear();
  errorData.clear();
}

//-----------------------------------------------------------------------------
void ctkCmdLineModuleFutureTester::testStartFinish()
{
  QList<QString> expectedSignals;
  expectedSignals << "module.started"
                  << "module.progressRangeChanged(0,0)"
                  << "module.progressValueChanged(0)"
                  << "module.progressRangeChanged(0,1000)"
                  << "module.errorReady"
                  << "module.progressValueChanged(1000)"
                  << "module.finished";

  ctkCmdLineModuleSignalTester signalTester;

  ctkCmdLineModuleFuture future = manager.run(frontend);
  signalTester.setFuture(future);
  future.waitForFinished();

  QCoreApplication::processEvents();
  QVERIFY(signalTester.checkSignals(expectedSignals));
}

//-----------------------------------------------------------------------------
void ctkCmdLineModuleFutureTester::testProgress()
{
  QList<QString> expectedSignals;
  expectedSignals << "module.started"
                     // the following signals are send when connecting a QFutureWatcher to
                     // an already started QFuture
                  << "module.progressRangeChanged(0,0)"
                  << "module.progressValueChanged(0)"
                  << "module.progressRangeChanged(0,1000)"

                     // the test module always reports error data when starting
                  << "module.errorReady"

                     // the following two signals are send when the module reports "filter start"
                  << "module.progressValueChanged(1)"
                  << "module.progressTextChanged(Test Filter)"

                     // this signal is send when the module reports progress for "output1"
                  << "module.progressValueChanged(999)"

                     // the output data (the order is not really deterministic here...)
                  << "module.outputReady"

                     // the following signal is sent at the end to report completion
                  << "module.progressValueChanged(1000)"
                  << "module.finished";

  ctkCmdLineModuleSignalTester signalTester;

  frontend->setValue("numOutputsVar", 1);
  ctkCmdLineModuleFuture future = manager.run(frontend);
  signalTester.setFuture(future);

  future.waitForFinished();

  // process pending events
  QCoreApplication::processEvents();

  QVERIFY(signalTester.checkSignals(expectedSignals));
}

//-----------------------------------------------------------------------------
void ctkCmdLineModuleFutureTester::testPauseAndCancel()
{
  ctkCmdLineModuleSignalTester signalTester;

  frontend->setValue("runtimeVar", 60);
  ctkCmdLineModuleFuture future = manager.run(frontend);
  signalTester.setFuture(future);

  QList<QString> expectedSignals;
  expectedSignals << "module.started"
                  << "module.progressRangeChanged(0,0)"
                  << "module.progressValueChanged(0)"
                  << "module.progressRangeChanged(0,1000)"
                  << "module.errorReady";

  if (future.canPause())
  {
    // Due to Qt bug 12152, these two signals are reversed
    expectedSignals.push_back("module.resumed");
    expectedSignals.push_back("module.paused");
  }

  if (future.canCancel())
  {
    expectedSignals.push_back("module.canceled");
  }
  expectedSignals.push_back("module.finished");

  QTest::qWait(100);

  if (future.canPause())
  {
    future.pause();
    QTest::qWait(100);
    QVERIFY(future.isPaused());
  }

  QVERIFY(future.isRunning());

  if (future.canPause())
  {
    future.togglePaused();
    QTest::qWait(100);
  }

  QVERIFY(!future.isPaused());
  QVERIFY(future.isRunning());

  if (future.canCancel())
  {
    // give event processing a chance before killing the process
    QTest::qWait(200);
    future.cancel();
  }
  future.waitForFinished();

  // process pending events
  QCoreApplication::processEvents();

  QVERIFY(future.isCanceled());
  QVERIFY(future.isFinished());

  QVERIFY(signalTester.checkSignals(expectedSignals));
}

//-----------------------------------------------------------------------------
void ctkCmdLineModuleFutureTester::testOutput()
{
  ctkCmdLineModuleSignalTester signalTester;

  connect(signalTester.watcher(), SIGNAL(outputDataReady()), SLOT(ouputDataReady()));
  connect(signalTester.watcher(), SIGNAL(errorDataReady()), SLOT(errorDataReady()));

  this->currentWatcher = signalTester.watcher();

  frontend->setValue("numOutputsVar", 2);
  frontend->setValue("errorTextVar", "Final error msg.");
  ctkCmdLineModuleFuture future = manager.run(frontend);
  signalTester.setFuture(future);

  future.waitForFinished();

  // process pending events
  QCoreApplication::processEvents();

  QVERIFY(future.isFinished());

  QList<QString> expectedSignals;
  expectedSignals << "module.started"
                  << "module.progressRangeChanged(0,0)"
                  << "module.progressValueChanged(0)"
                  << "module.progressRangeChanged(0,1000)"
                  << "module.errorReady"
                  << "module.progressValueChanged(1)"
                  << "module.progressTextChanged(Test Filter)"
                  << "module.progressValueChanged(500)"
                  << "module.outputReady"
                  << "module.progressValueChanged(999)"
                  << "module.outputReady"
                  << "module.errorReady"
                  << "module.progressValueChanged(1000)"
                  << "module.finished";

  QVERIFY(signalTester.checkSignals(expectedSignals));

  const char* expectedOutput = "Output 1\nOutput 2\n";
  const char* expectedError = "A superficial error message.\nFinal error msg.";

  QCOMPARE(this->outputData.data(), expectedOutput);
  QCOMPARE(this->errorData.data(), expectedError);

  QCOMPARE(future.readAllOutputData().data(), expectedOutput);
  QCOMPARE(future.readAllErrorData().data(), expectedError);
}

//-----------------------------------------------------------------------------
void ctkCmdLineModuleFutureTester::testError()
{
  frontend->setValue("fileVar", "output1");
  frontend->setValue("exitCodeVar", 24);
  frontend->setValue("errorTextVar", "Some error occured\n");

  ctkCmdLineModuleFuture future = manager.run(frontend);

  try
  {
    future.waitForFinished();
    QFAIL("Expected exception not thrown.");
  }
  catch (const ctkCmdLineModuleRunException& e)
  {
    QVERIFY2(e.errorCode() == 24, "Test matching error code");
    QCOMPARE(future.readAllErrorData().data(), "A superficial error message.\nSome error occured\n");
  }
}

// ----------------------------------------------------------------------------
CTK_TEST_MAIN(ctkCmdLineModuleFutureTest)
#include "moc_ctkCmdLineModuleFutureTest.cpp"
<|endoftext|>


<commit_before>// Copyright (C) 2012-2015 Leap Motion, Inc. All rights reserved.
#include "stdafx.h"
#include "TestFixtures/SimpleObject.hpp"
#include <autowiring/AnySharedPointer.h>
#include <autowiring/autowiring.h>

class AnySharedPointerTest:
  public testing::Test
{};

class MyUnusedClass {};

template<>
struct SharedPointerSlotT<MyUnusedClass>:
  SharedPointerSlot
{
  SharedPointerSlotT(const std::shared_ptr<MyUnusedClass>& rhs)
  {
    dtorStrike() = false;
  }

  ~SharedPointerSlotT(void) {
    dtorStrike() = true;
  }

  bool& dtorStrike(void) {
    return (bool&) *m_space;
  }
};

TEST_F(AnySharedPointerTest, OperatorEq) {
  AutoRequired<SimpleObject> sobj;

  // Trivial equivalence of an AnySharedPointer based on an AutoFilter instance
  AnySharedPointer sobjAny1(sobj);
  ASSERT_TRUE((bool)sobjAny1);
  ASSERT_EQ(sobj, sobjAny1) << "An AnySharedPointer instance initialized by constructor violated an identity test";

  // Trivial equivalence of an AnySharedPointer based on an AutoFilter instance
  AnySharedPointer sobjAny2;
  sobjAny2 = sobj;
  ASSERT_TRUE((bool)sobjAny2);
  ASSERT_EQ(sobj, sobjAny2) << "An AnySharedPointer instance initialized by assignment violated an identity test";
}

TEST_F(AnySharedPointerTest, SimpleDestructorStrike)
{
  // We will need a buffer big enough for entire slot:
  unsigned char buf[sizeof(SharedPointerSlotT<MyUnusedClass>)];
  auto& mucSlot = *(SharedPointerSlotT<MyUnusedClass>*)buf;

  // Placement new a basic shared pointer slot in the buffer:
  SharedPointerSlot& slot = *new(buf) SharedPointerSlot;

  // In-place polymorphism on the slot:
  slot = std::make_shared<MyUnusedClass>();

  // Destructor shouldn't be hit until we call it:
  ASSERT_FALSE(mucSlot.dtorStrike()) << "Destructor was struck prematurely";

  // Direct destructor call:
  slot.~SharedPointerSlot();

  // Verify we hit our dtor in the specialization we declared above:
  ASSERT_TRUE(mucSlot.dtorStrike()) << "Virtual destructor on in-place polymorphic class was not hit as expected";
}

TEST_F(AnySharedPointerTest, AnySharedPointerRelease) {
  auto t = std::make_shared<int>(5);

  // Assign over, then reset
  {
    AnySharedPointer ptr;
    ptr = t;
  }

  // Verify the AnySharedPointer destructor worked correctly
  ASSERT_TRUE(t.unique()) << "AnySharedPointer instance did not properly release a reference when destroyed";
}

TEST_F(AnySharedPointerTest, SlotReassignment) {
  auto sharedPointerA = std::make_shared<bool>();
  auto sharedPointerB = std::make_shared<bool>();
  auto sharedPointerC = std::make_shared<int>();

  // Make our slot, and start off with a shared pointer of one type:
  AnySharedPointer slot;
  slot = sharedPointerA;

  // Verify that the assignment worked as anticipated:
  ASSERT_EQ(2, sharedPointerA.use_count()) << "Constructor did not properly addref a shared pointer on initialization";

  // Recast to another shared pointer, verify reference count goes down:
  slot = sharedPointerB;
  ASSERT_EQ(2, sharedPointerB.use_count()) << "Reference count was not incremented properly during a shared pointer hold";
  ASSERT_TRUE(sharedPointerA.unique()) << "Destructor was not properly invoked for a shared pointer slot";

  // Now change the type completely, verify proper release:
  slot = sharedPointerC;
  ASSERT_TRUE(sharedPointerB.unique()) << "Second assigned shared pointer was not released under type transformation";
}

TEST_F(AnySharedPointerTest, SlotsInVector) {
  auto sharedPtr = std::make_shared<bool>();

  {
    std::list<AnySharedPointer> slots;

    // Initialize with a lot of copies of sharedPtr
    for(size_t i = 0; i < 10; i++) {
      slots.push_back(AnySharedPointer(sharedPtr));
      ASSERT_EQ(1 + (long)slots.size(), sharedPtr.use_count()) << "Unexpected number of references to a slotted shared pointer";
    }
  }

  // Now verify that we're unique again:
  ASSERT_TRUE(sharedPtr.unique()) << "Slots in a vector did not properly release all local clones";
}

TEST_F(AnySharedPointerTest, SlotDuplication) {
  auto sharedPtr = std::make_shared<bool>();

  AnySharedPointer slot2;

  {
    // Create a base slot to hold the shared pointer:
    AnySharedPointer slot1(sharedPtr);
    ASSERT_FALSE(slot1->empty()) << "A slot initialized from a shared pointer was incorrectly marked as empty";

    // Verify the type came across:
    ASSERT_EQ(typeid(auto_id<bool>), slot1->type()) << "Dynamic initialization did not correctly adjust the dynamic type";

    // Now copy it over:
    slot2 = slot1;

    // Verify reference count was affected as expected
    ASSERT_EQ(3, sharedPtr.use_count()) << "A second-order slot copy didn't increment the reference count as expected";
  }

  // Verify that the slot still holds a reference and that the reference count is correct:
  ASSERT_FALSE(slot2->empty()) << "A slot should have continued to hold a shared pointer, but was prematurely cleared";
  ASSERT_EQ(2, sharedPtr.use_count()) << "A slot going out of scope did not correctly decrement a shared pointer reference";
}

TEST_F(AnySharedPointerTest, TrivialRelease) {
  auto a = std::make_shared<bool>();
  auto b = std::make_shared<int>();

  // Assign the slot to two different values, and make sure that they are released properly
  AnySharedPointer slot;
  slot = a;
  slot = b;

  ASSERT_TRUE(a.unique()) << "Expected reassignment of a slot to release a formerly held instance";
  ASSERT_FALSE(b.unique()) << "Expected slot to hold a reference to the second specified instance";

  // Now release, and verify that a release actually took place
  slot->reset();
  ASSERT_TRUE(b.unique()) << "Releasing a slot did not actually release the held value as expected";
}

TEST_F(AnySharedPointerTest, NoMultipleDelete) {
  auto a = std::make_shared<bool>();
  std::weak_ptr<bool> b = a;

  // Create a slot and validate the behavior of reset, and to ensure that the underlying
  // SharedPointerSlot is not multiply deleted.
  {
    AnySharedPointer slot;
    slot = a;
    slot->reset();
  }

  // Now verify that we didn't accidentally overdecrement the count:
  ASSERT_FALSE(b.expired()) << "Shared pointer prematurely expired; SharedPointerSlot dtor double-strike suspected";
}

TEST_F(AnySharedPointerTest, InitDerivesCorrectType) {
  AnySharedPointer slot;
  slot->init<int>();

  ASSERT_EQ(typeid(auto_id<int>), slot->type()) << "A manually initialized slot did not have the expected type";
}

TEST_F(AnySharedPointerTest, VoidReturnExpected) {
  // Fill out our slot:
  auto v = std::make_shared<int>(5);
  AnySharedPointer slot;
  slot = v;

  // Validate equivalence of the void operator:
  ASSERT_EQ(v.get(), slot->ptr()) << "Shared pointer slot did not return a void* with an expected value";
}

TEST_F(AnySharedPointerTest, CanHoldCoreObject) {
  auto co = std::make_shared<CoreObject>();

  AnySharedPointer x = co;
  ASSERT_EQ(co, x) << "Held CoreObject was not equivalent to constructed instance";
}

TEST_F(AnySharedPointerTest, CanFastCastToSelf) {
  (void)autowiring::fast_pointer_cast_initializer<CoreObject, CoreObject>::sc_init;

  auto co = std::make_shared<CoreObject>();
  ASSERT_EQ(
    co,
    autowiring::fast_pointer_cast<CoreObject>(co)
  ) << "Could not cast a CoreObject instance to itself";
}<commit_msg>Add representational equivalence check<commit_after>// Copyright (C) 2012-2015 Leap Motion, Inc. All rights reserved.
#include "stdafx.h"
#include "TestFixtures/SimpleObject.hpp"
#include <autowiring/AnySharedPointer.h>
#include <autowiring/autowiring.h>

class AnySharedPointerTest:
  public testing::Test
{};

// Autowiring takes advantage of the representational equivalence of instantiations of
// shared_ptr, and therefore requires that their layouts all be the same.
static_assert(
  sizeof(std::shared_ptr<void*>) == sizeof(std::shared_ptr<int>),
  "Shared pointer representations must be equivalent for casting to work correctly"
);

TEST_F(AnySharedPointerTest, CanReinterpretCastSharedPtr) {
  auto iShared = std::make_shared<int>(101);
  auto vShared = *reinterpret_cast<std::shared_ptr<void>*>(&iShared);

  ASSERT_EQ(2UL, iShared.use_count()) << "Reinterpretive assignment of a void pointer did not increment the use count";
  ASSERT_EQ(iShared.get(), vShared.get()) << "Reinterpreted shared pointer did not properly hold a member variable";
}

class MyUnusedClass {};

template<>
struct SharedPointerSlotT<MyUnusedClass>:
  SharedPointerSlot
{
  SharedPointerSlotT(const std::shared_ptr<MyUnusedClass>& rhs)
  {
    dtorStrike() = false;
  }

  ~SharedPointerSlotT(void) {
    dtorStrike() = true;
  }

  bool& dtorStrike(void) {
    return (bool&) *m_space;
  }
};

TEST_F(AnySharedPointerTest, OperatorEq) {
  AutoRequired<SimpleObject> sobj;

  // Trivial equivalence of an AnySharedPointer based on an AutoFilter instance
  AnySharedPointer sobjAny1(sobj);
  ASSERT_TRUE((bool)sobjAny1);
  ASSERT_EQ(sobj, sobjAny1) << "An AnySharedPointer instance initialized by constructor violated an identity test";

  // Trivial equivalence of an AnySharedPointer based on an AutoFilter instance
  AnySharedPointer sobjAny2;
  sobjAny2 = sobj;
  ASSERT_TRUE((bool)sobjAny2);
  ASSERT_EQ(sobj, sobjAny2) << "An AnySharedPointer instance initialized by assignment violated an identity test";
}

TEST_F(AnySharedPointerTest, SimpleDestructorStrike)
{
  // We will need a buffer big enough for entire slot:
  unsigned char buf[sizeof(SharedPointerSlotT<MyUnusedClass>)];
  auto& mucSlot = *(SharedPointerSlotT<MyUnusedClass>*)buf;

  // Placement new a basic shared pointer slot in the buffer:
  SharedPointerSlot& slot = *new(buf) SharedPointerSlot;

  // In-place polymorphism on the slot:
  slot = std::make_shared<MyUnusedClass>();

  // Destructor shouldn't be hit until we call it:
  ASSERT_FALSE(mucSlot.dtorStrike()) << "Destructor was struck prematurely";

  // Direct destructor call:
  slot.~SharedPointerSlot();

  // Verify we hit our dtor in the specialization we declared above:
  ASSERT_TRUE(mucSlot.dtorStrike()) << "Virtual destructor on in-place polymorphic class was not hit as expected";
}

TEST_F(AnySharedPointerTest, AnySharedPointerRelease) {
  auto t = std::make_shared<int>(5);

  // Assign over, then reset
  {
    AnySharedPointer ptr;
    ptr = t;
  }

  // Verify the AnySharedPointer destructor worked correctly
  ASSERT_TRUE(t.unique()) << "AnySharedPointer instance did not properly release a reference when destroyed";
}

TEST_F(AnySharedPointerTest, SlotReassignment) {
  auto sharedPointerA = std::make_shared<bool>();
  auto sharedPointerB = std::make_shared<bool>();
  auto sharedPointerC = std::make_shared<int>();

  // Make our slot, and start off with a shared pointer of one type:
  AnySharedPointer slot;
  slot = sharedPointerA;

  // Verify that the assignment worked as anticipated:
  ASSERT_EQ(2, sharedPointerA.use_count()) << "Constructor did not properly addref a shared pointer on initialization";

  // Recast to another shared pointer, verify reference count goes down:
  slot = sharedPointerB;
  ASSERT_EQ(2, sharedPointerB.use_count()) << "Reference count was not incremented properly during a shared pointer hold";
  ASSERT_TRUE(sharedPointerA.unique()) << "Destructor was not properly invoked for a shared pointer slot";

  // Now change the type completely, verify proper release:
  slot = sharedPointerC;
  ASSERT_TRUE(sharedPointerB.unique()) << "Second assigned shared pointer was not released under type transformation";
}

TEST_F(AnySharedPointerTest, SlotsInVector) {
  auto sharedPtr = std::make_shared<bool>();

  {
    std::list<AnySharedPointer> slots;

    // Initialize with a lot of copies of sharedPtr
    for(size_t i = 0; i < 10; i++) {
      slots.push_back(AnySharedPointer(sharedPtr));
      ASSERT_EQ(1 + (long)slots.size(), sharedPtr.use_count()) << "Unexpected number of references to a slotted shared pointer";
    }
  }

  // Now verify that we're unique again:
  ASSERT_TRUE(sharedPtr.unique()) << "Slots in a vector did not properly release all local clones";
}

TEST_F(AnySharedPointerTest, SlotDuplication) {
  auto sharedPtr = std::make_shared<bool>();

  AnySharedPointer slot2;

  {
    // Create a base slot to hold the shared pointer:
    AnySharedPointer slot1(sharedPtr);
    ASSERT_FALSE(slot1->empty()) << "A slot initialized from a shared pointer was incorrectly marked as empty";

    // Verify the type came across:
    ASSERT_EQ(typeid(auto_id<bool>), slot1->type()) << "Dynamic initialization did not correctly adjust the dynamic type";

    // Now copy it over:
    slot2 = slot1;

    // Verify reference count was affected as expected
    ASSERT_EQ(3, sharedPtr.use_count()) << "A second-order slot copy didn't increment the reference count as expected";
  }

  // Verify that the slot still holds a reference and that the reference count is correct:
  ASSERT_FALSE(slot2->empty()) << "A slot should have continued to hold a shared pointer, but was prematurely cleared";
  ASSERT_EQ(2, sharedPtr.use_count()) << "A slot going out of scope did not correctly decrement a shared pointer reference";
}

TEST_F(AnySharedPointerTest, TrivialRelease) {
  auto a = std::make_shared<bool>();
  auto b = std::make_shared<int>();

  // Assign the slot to two different values, and make sure that they are released properly
  AnySharedPointer slot;
  slot = a;
  slot = b;

  ASSERT_TRUE(a.unique()) << "Expected reassignment of a slot to release a formerly held instance";
  ASSERT_FALSE(b.unique()) << "Expected slot to hold a reference to the second specified instance";

  // Now release, and verify that a release actually took place
  slot->reset();
  ASSERT_TRUE(b.unique()) << "Releasing a slot did not actually release the held value as expected";
}

TEST_F(AnySharedPointerTest, NoMultipleDelete) {
  auto a = std::make_shared<bool>();
  std::weak_ptr<bool> b = a;

  // Create a slot and validate the behavior of reset, and to ensure that the underlying
  // SharedPointerSlot is not multiply deleted.
  {
    AnySharedPointer slot;
    slot = a;
    slot->reset();
  }

  // Now verify that we didn't accidentally overdecrement the count:
  ASSERT_FALSE(b.expired()) << "Shared pointer prematurely expired; SharedPointerSlot dtor double-strike suspected";
}

TEST_F(AnySharedPointerTest, InitDerivesCorrectType) {
  AnySharedPointer slot;
  slot->init<int>();

  ASSERT_EQ(typeid(auto_id<int>), slot->type()) << "A manually initialized slot did not have the expected type";
}

TEST_F(AnySharedPointerTest, VoidReturnExpected) {
  // Fill out our slot:
  auto v = std::make_shared<int>(5);
  AnySharedPointer slot;
  slot = v;

  // Validate equivalence of the void operator:
  ASSERT_EQ(v.get(), slot->ptr()) << "Shared pointer slot did not return a void* with an expected value";
}

TEST_F(AnySharedPointerTest, CanHoldCoreObject) {
  auto co = std::make_shared<CoreObject>();

  AnySharedPointer x = co;
  ASSERT_EQ(co, x) << "Held CoreObject was not equivalent to constructed instance";
}

TEST_F(AnySharedPointerTest, CanFastCastToSelf) {
  (void)autowiring::fast_pointer_cast_initializer<CoreObject, CoreObject>::sc_init;

  auto co = std::make_shared<CoreObject>();
  ASSERT_EQ(
    co,
    autowiring::fast_pointer_cast<CoreObject>(co)
  ) << "Could not cast a CoreObject instance to itself";
}<|endoftext|>


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

#include "base/command_line.h"
#include "base/file_path.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_init.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/test/in_process_browser_test.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

class BrowserInitTest : public InProcessBrowserTest {
};

class OpenURLsPopupObserver : public BrowserList::Observer {
 public:
  OpenURLsPopupObserver() : added_browser_(NULL) { }

  virtual void OnBrowserAdded(const Browser* browser) {
    added_browser_ = browser;
  }

  virtual void OnBrowserRemoved(const Browser* browser) { }

  const Browser* added_browser_;
};

// Test that when there is a popup as the active browser any requests to
// BrowserInit::LaunchWithProfile::OpenURLsInBrowser don't crash because
// there's no explicit profile given.
IN_PROC_BROWSER_TEST_F(BrowserInitTest, OpenURLsPopup) {
  std::vector<GURL> urls;
  urls.push_back(GURL("http://localhost"));

  // Note that in our testing we do not ever query the BrowserList for the "last
  // active" browser. That's because the browsers are set as "active" by
  // platform UI toolkit messages, and those messages are not sent during unit
  // testing sessions.

  OpenURLsPopupObserver observer;
  BrowserList::AddObserver(&observer);

  Browser* popup = Browser::CreateForType(Browser::TYPE_POPUP,
                                          browser()->profile());
  ASSERT_EQ(popup->type(), Browser::TYPE_POPUP);
  ASSERT_EQ(popup, observer.added_browser_);

  CommandLine dummy(CommandLine::NO_PROGRAM);
  BrowserInit::LaunchWithProfile launch(FilePath(), dummy);
  // This should create a new window, but re-use the profile from |popup|. If
  // it used a NULL or invalid profile, it would crash.
  launch.OpenURLsInBrowser(popup, false, urls);
  ASSERT_NE(popup, observer.added_browser_);
  BrowserList::RemoveObserver(&observer);
}

// Test that we prevent openning potentially dangerous schemes from the
// command line.
// TODO(jschuh): FLAKY because the process doesn't have sufficient time
// to start on most BuildBot runs and I don't want to add longer delays to
// the test. I'll circle back and make this work properly when i get a chance.
// See http://crbug.com/60026
IN_PROC_BROWSER_TEST_F(BrowserInitTest, FLAKY_BlockBadURLs) {
  const char* testurlstr = "http://localhost/";
  const GURL testurl(testurlstr);
  CommandLine cmdline(CommandLine::NO_PROGRAM);
  cmdline.AppendArg(testurlstr);
  cmdline.AppendArg("javascript:alert('boo')");
  cmdline.AppendArg(testurlstr);
  cmdline.AppendArg("view-source:http://localhost/");

  // This will pick up the current browser instance.
  BrowserInit::LaunchWithProfile launch(FilePath(), cmdline);
  launch.Launch(browser()->profile(), false);

  // TODO(jschuh): Give the browser a chance to start first.
  PlatformThread::Sleep(50);

  // Skip about:blank in the first tab
  for (int  i = 1; i < browser()->tab_count(); i++) {
    const GURL &url = browser()->GetTabContentsAt(i)->GetURL();
    ASSERT_EQ(url, testurl);
  }
  ASSERT_EQ(browser()->tab_count(), 3);
}

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

#include "base/command_line.h"
#include "base/file_path.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_init.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "chrome/test/in_process_browser_test.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

class BrowserInitTest : public InProcessBrowserTest {
};

class OpenURLsPopupObserver : public BrowserList::Observer {
 public:
  OpenURLsPopupObserver() : added_browser_(NULL) { }

  virtual void OnBrowserAdded(const Browser* browser) {
    added_browser_ = browser;
  }

  virtual void OnBrowserRemoved(const Browser* browser) { }

  const Browser* added_browser_;
};

// Test that when there is a popup as the active browser any requests to
// BrowserInit::LaunchWithProfile::OpenURLsInBrowser don't crash because
// there's no explicit profile given.
IN_PROC_BROWSER_TEST_F(BrowserInitTest, OpenURLsPopup) {
  std::vector<GURL> urls;
  urls.push_back(GURL("http://localhost"));

  // Note that in our testing we do not ever query the BrowserList for the "last
  // active" browser. That's because the browsers are set as "active" by
  // platform UI toolkit messages, and those messages are not sent during unit
  // testing sessions.

  OpenURLsPopupObserver observer;
  BrowserList::AddObserver(&observer);

  Browser* popup = Browser::CreateForType(Browser::TYPE_POPUP,
                                          browser()->profile());
  ASSERT_EQ(popup->type(), Browser::TYPE_POPUP);
  ASSERT_EQ(popup, observer.added_browser_);

  CommandLine dummy(CommandLine::NO_PROGRAM);
  BrowserInit::LaunchWithProfile launch(FilePath(), dummy);
  // This should create a new window, but re-use the profile from |popup|. If
  // it used a NULL or invalid profile, it would crash.
  launch.OpenURLsInBrowser(popup, false, urls);
  ASSERT_NE(popup, observer.added_browser_);
  BrowserList::RemoveObserver(&observer);
}

}  // namespace
<|endoftext|>