<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */

#include "cppu/helper/purpenv/Mapping.hxx"

#include "Proxy.hxx"

#include "osl/interlck.h"
#include "uno/environment.hxx"
#include "uno/dispatcher.h"
#include "typelib/typedescription.h"

#ifdef debug
# define LOG_LIFECYCLE_cppu_helper_purpenv_Mapping
#endif

#ifdef LOG_LIFECYCLE_cppu_helper_purpenv_Mapping
#  include <iostream>
#  define LOG_LIFECYCLE_cppu_helper_purpenv_Mapping_emit(x) x

#else
#  define LOG_LIFECYCLE_cppu_helper_purpenv_Mapping_emit(x)

#endif

using namespace com::sun::star;

class Mapping : public uno_Mapping
{
    uno::Environment   m_from;
    uno::Environment   m_to;

    oslInterlockedCount m_nCount;

    cppu::helper::purpenv::ProbeFun * m_probeFun;
    void                            * m_pContext;

public:
    explicit  Mapping(uno_Environment                 * pFrom,
                      uno_Environment                 * pTo,
                      cppu::helper::purpenv::ProbeFun * probeFun,
                      void                            * pProbeContext);
    virtual  ~Mapping(void);

    void mapInterface(
        uno_Interface                    ** ppOut,
        uno_Interface                     * pUnoI,
        typelib_InterfaceTypeDescription  * pTypeDescr);

    void acquire(void);
    void release(void);
};

static void SAL_CALL s_mapInterface(
    uno_Mapping                       * puno_Mapping,
    uno_Interface                    ** ppOut,
    uno_Interface                     * pUnoI,
    typelib_InterfaceTypeDescription  * pTypeDescr )
    SAL_THROW_EXTERN_C()
{
    Mapping * pMapping = static_cast<Mapping *>(puno_Mapping);
    pMapping->mapInterface(ppOut, pUnoI, pTypeDescr);
}

extern "C" {
static void SAL_CALL s_acquire(uno_Mapping * puno_Mapping)
    SAL_THROW_EXTERN_C()
{
    Mapping * pMapping = static_cast<Mapping *>(puno_Mapping);
    pMapping->acquire();
}

static void SAL_CALL s_release(uno_Mapping * puno_Mapping)
    SAL_THROW_EXTERN_C()
{
    Mapping * pMapping = static_cast<Mapping * >(puno_Mapping);
    pMapping->release();
}

static void s_getIdentifier_v(va_list * pParam)
{
    uno_ExtEnvironment *  pEnv  = va_arg(*pParam, uno_ExtEnvironment *);
    rtl_uString        ** ppOid = va_arg(*pParam, rtl_uString **);
    uno_Interface      *  pUnoI = va_arg(*pParam, uno_Interface *);

    pEnv->getObjectIdentifier(pEnv, ppOid, pUnoI);
}

static void SAL_CALL s_free(uno_Mapping * puno_Mapping)
    SAL_THROW_EXTERN_C()
{
    Mapping * pMapping = static_cast<Mapping *>(puno_Mapping);
    delete pMapping;
}
}

Mapping::Mapping(uno_Environment                 * pFrom,
                 uno_Environment                 * pTo,
                 cppu::helper::purpenv::ProbeFun * probeFun,
                 void                            * pProbeContext
)
    : m_from    (pFrom),
      m_to      (pTo),
      m_nCount  (1),
      m_probeFun(probeFun),
      m_pContext(pProbeContext)
{
    LOG_LIFECYCLE_cppu_helper_purpenv_Mapping_emit(fprintf(stderr, "LIFE: %s -> %p\n", "Mapping::Mapping(uno_Environment * pFrom, uno_Environment * pTo)", this));

    uno_Mapping::acquire      = s_acquire;
    uno_Mapping::release      = s_release;
    uno_Mapping::mapInterface = (uno_MapInterfaceFunc)s_mapInterface;
}

Mapping::~Mapping(void)
{
    LOG_LIFECYCLE_cppu_helper_purpenv_Mapping_emit(fprintf(stderr, "LIFE: %s -> %p\n", "Mapping::~Mapping(void)", this));
}

void Mapping::mapInterface(
    uno_Interface                    ** ppOut,
    uno_Interface                     * pUnoI,
    typelib_InterfaceTypeDescription  * pTypeDescr)
{
    OSL_ASSERT(ppOut && pTypeDescr);
    if (*ppOut)
    {
        (*ppOut)->release(*ppOut);
        *ppOut = 0;
    }

    if (!pUnoI)
        return;

    // get object id of uno interface to be wrapped
    // need to enter environment because of potential "queryInterface" call
    rtl_uString * pOId = 0;
    uno_Environment_invoke(m_from.get(), s_getIdentifier_v, m_from.get(), &pOId, pUnoI);
    OSL_ASSERT(pOId);

     // try to get any known interface from target environment
    m_to.get()->pExtEnv->getRegisteredInterface(m_to.get()->pExtEnv, (void **)ppOut, pOId, pTypeDescr);

    if (!*ppOut) // not yet there, register new proxy interface
    {
        // try to publish a new proxy (ref count initially 1)
        uno_Interface * pProxy = new Proxy(this,
                                           m_from.get(),
                                           m_to.get(),
                                           pUnoI,
                                           pTypeDescr,
                                           pOId,
                                           m_probeFun,
                                           m_pContext);

        // proxy may be exchanged during registration
        m_to.get()->pExtEnv->registerProxyInterface(m_to.get()->pExtEnv,
                                                    (void **)&pProxy,
                                                    Proxy_free,
                                                    pOId,
                                                    pTypeDescr);

        *ppOut = pProxy;
    }

    rtl_uString_release(pOId);
}

void Mapping::acquire()
{
    if (osl_atomic_increment(&m_nCount) == 1)
    {
        uno_Mapping * pMapping = this;

        ::uno_registerMapping(&pMapping, s_free, m_from.get(), m_to.get(), NULL);
    }
}

void Mapping::release()
{
    if (osl_atomic_decrement(&m_nCount) == 0)
        ::uno_revokeMapping(this);
}

namespace cppu { namespace helper { namespace purpenv {

void createMapping(uno_Mapping     ** ppMapping,
                   uno_Environment  * pFrom,
                   uno_Environment  * pTo,
                   ProbeFun         * probeFun,
                   void             * pContext
 )
{
    *ppMapping = new Mapping(pFrom, pTo, probeFun, pContext);

    ::uno_registerMapping(ppMapping, s_free, pFrom, pTo, NULL);
}

}}}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>s_mapInterface must match uno_MapInterfaceFunc<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */

#include "cppu/helper/purpenv/Mapping.hxx"

#include "Proxy.hxx"

#include "osl/interlck.h"
#include "uno/environment.hxx"
#include "uno/dispatcher.h"
#include "typelib/typedescription.h"

#ifdef debug
# define LOG_LIFECYCLE_cppu_helper_purpenv_Mapping
#endif

#ifdef LOG_LIFECYCLE_cppu_helper_purpenv_Mapping
#  include <iostream>
#  define LOG_LIFECYCLE_cppu_helper_purpenv_Mapping_emit(x) x

#else
#  define LOG_LIFECYCLE_cppu_helper_purpenv_Mapping_emit(x)

#endif

using namespace com::sun::star;

class Mapping : public uno_Mapping
{
    uno::Environment   m_from;
    uno::Environment   m_to;

    oslInterlockedCount m_nCount;

    cppu::helper::purpenv::ProbeFun * m_probeFun;
    void                            * m_pContext;

public:
    explicit  Mapping(uno_Environment                 * pFrom,
                      uno_Environment                 * pTo,
                      cppu::helper::purpenv::ProbeFun * probeFun,
                      void                            * pProbeContext);
    virtual  ~Mapping(void);

    void mapInterface(
        uno_Interface                    ** ppOut,
        uno_Interface                     * pUnoI,
        typelib_InterfaceTypeDescription  * pTypeDescr);

    void acquire(void);
    void release(void);
};

static void SAL_CALL s_mapInterface(
    uno_Mapping                       * puno_Mapping,
    void                             ** ppOut,
    void                              * pUnoI,
    typelib_InterfaceTypeDescription  * pTypeDescr )
    SAL_THROW_EXTERN_C()
{
    Mapping * pMapping = static_cast<Mapping *>(puno_Mapping);
    pMapping->mapInterface(
        reinterpret_cast<uno_Interface **>(ppOut),
        static_cast<uno_Interface *>(pUnoI), pTypeDescr);
}

extern "C" {
static void SAL_CALL s_acquire(uno_Mapping * puno_Mapping)
    SAL_THROW_EXTERN_C()
{
    Mapping * pMapping = static_cast<Mapping *>(puno_Mapping);
    pMapping->acquire();
}

static void SAL_CALL s_release(uno_Mapping * puno_Mapping)
    SAL_THROW_EXTERN_C()
{
    Mapping * pMapping = static_cast<Mapping * >(puno_Mapping);
    pMapping->release();
}

static void s_getIdentifier_v(va_list * pParam)
{
    uno_ExtEnvironment *  pEnv  = va_arg(*pParam, uno_ExtEnvironment *);
    rtl_uString        ** ppOid = va_arg(*pParam, rtl_uString **);
    uno_Interface      *  pUnoI = va_arg(*pParam, uno_Interface *);

    pEnv->getObjectIdentifier(pEnv, ppOid, pUnoI);
}

static void SAL_CALL s_free(uno_Mapping * puno_Mapping)
    SAL_THROW_EXTERN_C()
{
    Mapping * pMapping = static_cast<Mapping *>(puno_Mapping);
    delete pMapping;
}
}

Mapping::Mapping(uno_Environment                 * pFrom,
                 uno_Environment                 * pTo,
                 cppu::helper::purpenv::ProbeFun * probeFun,
                 void                            * pProbeContext
)
    : m_from    (pFrom),
      m_to      (pTo),
      m_nCount  (1),
      m_probeFun(probeFun),
      m_pContext(pProbeContext)
{
    LOG_LIFECYCLE_cppu_helper_purpenv_Mapping_emit(fprintf(stderr, "LIFE: %s -> %p\n", "Mapping::Mapping(uno_Environment * pFrom, uno_Environment * pTo)", this));

    uno_Mapping::acquire      = s_acquire;
    uno_Mapping::release      = s_release;
    uno_Mapping::mapInterface = (uno_MapInterfaceFunc)s_mapInterface;
}

Mapping::~Mapping(void)
{
    LOG_LIFECYCLE_cppu_helper_purpenv_Mapping_emit(fprintf(stderr, "LIFE: %s -> %p\n", "Mapping::~Mapping(void)", this));
}

void Mapping::mapInterface(
    uno_Interface                    ** ppOut,
    uno_Interface                     * pUnoI,
    typelib_InterfaceTypeDescription  * pTypeDescr)
{
    OSL_ASSERT(ppOut && pTypeDescr);
    if (*ppOut)
    {
        (*ppOut)->release(*ppOut);
        *ppOut = 0;
    }

    if (!pUnoI)
        return;

    // get object id of uno interface to be wrapped
    // need to enter environment because of potential "queryInterface" call
    rtl_uString * pOId = 0;
    uno_Environment_invoke(m_from.get(), s_getIdentifier_v, m_from.get(), &pOId, pUnoI);
    OSL_ASSERT(pOId);

     // try to get any known interface from target environment
    m_to.get()->pExtEnv->getRegisteredInterface(m_to.get()->pExtEnv, (void **)ppOut, pOId, pTypeDescr);

    if (!*ppOut) // not yet there, register new proxy interface
    {
        // try to publish a new proxy (ref count initially 1)
        uno_Interface * pProxy = new Proxy(this,
                                           m_from.get(),
                                           m_to.get(),
                                           pUnoI,
                                           pTypeDescr,
                                           pOId,
                                           m_probeFun,
                                           m_pContext);

        // proxy may be exchanged during registration
        m_to.get()->pExtEnv->registerProxyInterface(m_to.get()->pExtEnv,
                                                    (void **)&pProxy,
                                                    Proxy_free,
                                                    pOId,
                                                    pTypeDescr);

        *ppOut = pProxy;
    }

    rtl_uString_release(pOId);
}

void Mapping::acquire()
{
    if (osl_atomic_increment(&m_nCount) == 1)
    {
        uno_Mapping * pMapping = this;

        ::uno_registerMapping(&pMapping, s_free, m_from.get(), m_to.get(), NULL);
    }
}

void Mapping::release()
{
    if (osl_atomic_decrement(&m_nCount) == 0)
        ::uno_revokeMapping(this);
}

namespace cppu { namespace helper { namespace purpenv {

void createMapping(uno_Mapping     ** ppMapping,
                   uno_Environment  * pFrom,
                   uno_Environment  * pTo,
                   ProbeFun         * probeFun,
                   void             * pContext
 )
{
    *ppMapping = new Mapping(pFrom, pTo, probeFun, pContext);

    ::uno_registerMapping(ppMapping, s_free, pFrom, pTo, NULL);
}

}}}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>/*******************************************************************************
 * c7a/data/stream_block_header.hpp
 *
 * Part of Project c7a.
 *
 *
 * This file has no license. Only Chuck Norris can compile it.
 ******************************************************************************/

#pragma once
#ifndef C7A_DATA_STREAM_BLOCK_HEADER_HEADER
#define C7A_DATA_STREAM_BLOCK_HEADER_HEADER

#include <c7a/net/buffer_builder.hpp>
#include <c7a/net/buffer_reader.hpp>
#include <c7a/net/connection.hpp>

#include <cstdio>
#include <cstdlib>
#include <string>

namespace c7a {
namespace data {

//! \addtogroup data Data Subsystem
//! \{

//! Block header is sent before a sequence of blocks
//! it indicates the number of elements and their
//! boundaries
//!
//! Provides a serializer and two partial deserializers
//! A StreamBlockHeader with num_elements = 0 marks the end of a stream
struct StreamBlockHeader {
    size_t      channel_id;
    size_t      size;
    size_t      first_item;
    size_t      nitems;
    size_t      sender_rank;

    //! Reads the channel id and the number of elements in this block
    void        ParseHeader(const net::Buffer& buffer) {
        assert(buffer.size() == sizeof(StreamBlockHeader));
        net::BufferReader br(buffer);
        channel_id = br.Get<size_t>();
        size = br.Get<size_t>();
        first_item = br.Get<size_t>();
        nitems = br.Get<size_t>();
        sender_rank = br.Get<size_t>();
    }

    //! Serializes the whole block struct into a buffer
    net::Buffer Serialize() {
        net::BufferBuilder bb;
        bb.Reserve(4 * sizeof(size_t));
        bb.Put<size_t>(channel_id);
        bb.Put<size_t>(size);
        bb.Put<size_t>(first_item);
        bb.Put<size_t>(nitems);
        bb.Put<size_t>(sender_rank);
        return bb.ToBuffer();
    }

    //! Indicates if this is the end-of-stream block header
    bool        IsStreamEnd() const {
        return size == 0;
    }
};

//! \}

} // namespace data
} // namespace c7a

#endif // !C7A_DATA_STREAM_BLOCK_HEADER_HEADER

/******************************************************************************/
<commit_msg>add copyright to stream_block_header.hpp<commit_after>/*******************************************************************************
 * c7a/data/stream_block_header.hpp
 *
 * Part of Project c7a.
 *
 * Copyright (C) 2015 Tobias Sturm <mail@tobiassturm.de>
 *
 * This file has no license. Only Chuck Norris can compile it.
 ******************************************************************************/

#pragma once
#ifndef C7A_DATA_STREAM_BLOCK_HEADER_HEADER
#define C7A_DATA_STREAM_BLOCK_HEADER_HEADER

#include <c7a/net/buffer_builder.hpp>
#include <c7a/net/buffer_reader.hpp>
#include <c7a/net/connection.hpp>

#include <cstdio>
#include <cstdlib>
#include <string>

namespace c7a {
namespace data {

//! \addtogroup data Data Subsystem
//! \{

//! Block header is sent before a sequence of blocks
//! it indicates the number of elements and their
//! boundaries
//!
//! Provides a serializer and two partial deserializers
//! A StreamBlockHeader with num_elements = 0 marks the end of a stream
struct StreamBlockHeader {
    size_t      channel_id;
    size_t      size;
    size_t      first_item;
    size_t      nitems;
    size_t      sender_rank;

    //! Reads the channel id and the number of elements in this block
    void        ParseHeader(const net::Buffer& buffer) {
        assert(buffer.size() == sizeof(StreamBlockHeader));
        net::BufferReader br(buffer);
        channel_id = br.Get<size_t>();
        size = br.Get<size_t>();
        first_item = br.Get<size_t>();
        nitems = br.Get<size_t>();
        sender_rank = br.Get<size_t>();
    }

    //! Serializes the whole block struct into a buffer
    net::Buffer Serialize() {
        net::BufferBuilder bb;
        bb.Reserve(4 * sizeof(size_t));
        bb.Put<size_t>(channel_id);
        bb.Put<size_t>(size);
        bb.Put<size_t>(first_item);
        bb.Put<size_t>(nitems);
        bb.Put<size_t>(sender_rank);
        return bb.ToBuffer();
    }

    //! Indicates if this is the end-of-stream block header
    bool        IsStreamEnd() const {
        return size == 0;
    }
};

//! \}

} // namespace data
} // namespace c7a

#endif // !C7A_DATA_STREAM_BLOCK_HEADER_HEADER

/******************************************************************************/
<|endoftext|>


<commit_before>#include <test/unit/mcmc/hmc/mock_hmc.hpp>
#include <stan/mcmc/hmc/base_hmc.hpp>

#include <boost/random/additive_combine.hpp>
#include <boost/algorithm/string/split.hpp>

#include <gtest/gtest.h>
#include <test/models/utility.hpp>

typedef boost::ecuyer1988 rng_t;

namespace stan {

  namespace mcmc {

    class mock_hmc: public base_hmc<mock_model,
                                    ps_point,
                                    mock_hamiltonian,
                                    mock_integrator,
                                    rng_t> {

    public:

      mock_hmc(mock_model& m, rng_t& rng, std::ostream* o, std::ostream* e) :
        base_hmc<mock_model,ps_point,mock_hamiltonian,mock_integrator,rng_t>
        (m, rng, o, e)
      { this->_name = "Mock HMC"; }

      sample transition(sample& init_sample) {
        this->seed(init_sample.cont_params());
        return sample(this->_z.q, - this->_hamiltonian.V(this->_z), 0);
      }

      void write_sampler_param_names(std::ostream& o) {};

      void write_sampler_params(std::ostream& o) {};

      void get_sampler_param_names(std::vector<std::string>& names) {};

      void get_sampler_params(std::vector<double>& values) {};

    };

  }

}

TEST(McmcBaseHMC, point_construction) {

  rng_t base_rng(0);

  Eigen::VectorXd q(2);
  q(0) = 5;
  q(1) = 1;

  stan::mcmc::mock_model model(q.size());

  stan::mcmc::mock_hmc sampler(model, base_rng, &std::cout, &std::cerr);

  EXPECT_EQ(q.size(), sampler.z().q.size());
  EXPECT_EQ(static_cast<int>(q.size()), sampler.z().g.size());
}

TEST(McmcBaseHMC, seed) {

  rng_t base_rng(0);

  Eigen::VectorXd q(2);
  q(0) = 5;
  q(1) = 1;

  stan::mcmc::mock_model model(q.size());

  stan::mcmc::mock_hmc sampler(model, base_rng, &std::cout, &std::cerr);

  sampler.seed(q);

  for (Eigen::VectorXd::size_type i = 0; i < q.size(); ++i)
    EXPECT_EQ(q(i), sampler.z().q(i));

}

TEST(McmcBaseHMC, set_nominal_stepsize) {

  rng_t base_rng(0);

  Eigen::VectorXd q(2);
  q(0) = 5;
  q(1) = 1;

  stan::mcmc::mock_model model(q.size());

  stan::mcmc::mock_hmc sampler(model, base_rng, &std::cout, &std::cerr);

  double old_epsilon = 1.0;
  sampler.set_nominal_stepsize(old_epsilon);
  EXPECT_EQ(old_epsilon, sampler.get_nominal_stepsize());

  sampler.set_nominal_stepsize(-0.1);
  EXPECT_EQ(old_epsilon, sampler.get_nominal_stepsize());

}

TEST(McmcBaseHMC, set_stepsize_jitter) {

  rng_t base_rng(0);

  Eigen::VectorXd q(2);
  q(0) = 5;
  q(1) = 1;

  stan::mcmc::mock_model model(q.size());

  stan::mcmc::mock_hmc sampler(model, base_rng, &std::cout, &std::cerr);

  double old_jitter = 0.1;
  sampler.set_stepsize_jitter(old_jitter);
  EXPECT_EQ(old_jitter, sampler.get_stepsize_jitter());

  sampler.set_nominal_stepsize(-0.1);
  EXPECT_EQ(old_jitter, sampler.get_stepsize_jitter());

}

<commit_msg>fixed base_hmc_test.cpp<commit_after>#include <test/unit/mcmc/hmc/mock_hmc.hpp>
#include <stan/mcmc/hmc/base_hmc.hpp>

#include <boost/random/additive_combine.hpp>
#include <boost/algorithm/string/split.hpp>

#include <gtest/gtest.h>

typedef boost::ecuyer1988 rng_t;

namespace stan {

  namespace mcmc {

    class mock_hmc: public base_hmc<mock_model,
                                    ps_point,
                                    mock_hamiltonian,
                                    mock_integrator,
                                    rng_t> {

    public:

      mock_hmc(mock_model& m, rng_t& rng, std::ostream* o, std::ostream* e) :
        base_hmc<mock_model,ps_point,mock_hamiltonian,mock_integrator,rng_t>
        (m, rng, o, e)
      { this->_name = "Mock HMC"; }

      sample transition(sample& init_sample) {
        this->seed(init_sample.cont_params());
        return sample(this->_z.q, - this->_hamiltonian.V(this->_z), 0);
      }

      void write_sampler_param_names(std::ostream& o) {};

      void write_sampler_params(std::ostream& o) {};

      void get_sampler_param_names(std::vector<std::string>& names) {};

      void get_sampler_params(std::vector<double>& values) {};

    };

  }

}

TEST(McmcBaseHMC, point_construction) {

  rng_t base_rng(0);

  Eigen::VectorXd q(2);
  q(0) = 5;
  q(1) = 1;

  stan::mcmc::mock_model model(q.size());

  stan::mcmc::mock_hmc sampler(model, base_rng, &std::cout, &std::cerr);

  EXPECT_EQ(q.size(), sampler.z().q.size());
  EXPECT_EQ(static_cast<int>(q.size()), sampler.z().g.size());
}

TEST(McmcBaseHMC, seed) {

  rng_t base_rng(0);

  Eigen::VectorXd q(2);
  q(0) = 5;
  q(1) = 1;

  stan::mcmc::mock_model model(q.size());

  stan::mcmc::mock_hmc sampler(model, base_rng, &std::cout, &std::cerr);

  sampler.seed(q);

  for (Eigen::VectorXd::size_type i = 0; i < q.size(); ++i)
    EXPECT_EQ(q(i), sampler.z().q(i));

}

TEST(McmcBaseHMC, set_nominal_stepsize) {

  rng_t base_rng(0);

  Eigen::VectorXd q(2);
  q(0) = 5;
  q(1) = 1;

  stan::mcmc::mock_model model(q.size());

  stan::mcmc::mock_hmc sampler(model, base_rng, &std::cout, &std::cerr);

  double old_epsilon = 1.0;
  sampler.set_nominal_stepsize(old_epsilon);
  EXPECT_EQ(old_epsilon, sampler.get_nominal_stepsize());

  sampler.set_nominal_stepsize(-0.1);
  EXPECT_EQ(old_epsilon, sampler.get_nominal_stepsize());

}

TEST(McmcBaseHMC, set_stepsize_jitter) {

  rng_t base_rng(0);

  Eigen::VectorXd q(2);
  q(0) = 5;
  q(1) = 1;

  stan::mcmc::mock_model model(q.size());

  stan::mcmc::mock_hmc sampler(model, base_rng, &std::cout, &std::cerr);

  double old_jitter = 0.1;
  sampler.set_stepsize_jitter(old_jitter);
  EXPECT_EQ(old_jitter, sampler.get_stepsize_jitter());

  sampler.set_nominal_stepsize(-0.1);
  EXPECT_EQ(old_jitter, sampler.get_stepsize_jitter());

}

<|endoftext|>


<commit_before>/**
 * Ported from mdaReverb.h
 * Created by Arne Scheffler on 6/13/08.
 *
 * mda VST Plug-ins
 *
 * Copyright (c) 2008 Paul Kellett
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to the following conditions:
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of
 * the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
 * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */
#include "reverb.h"
#include <algorithm>
#include <cstring>
#include <utilities/utils.h>

namespace MWEngine {

/* constructor / destructor */

Reverb::Reverb( float size, float hfDamp, float mix, float output )
{
    _size   = size;
    _hfDamp = hfDamp;
    _mix    = mix;
    _output = output;

    buf1 = new SAMPLE_TYPE[ 1024 ];
    buf2 = new SAMPLE_TYPE[ 1024 ];
    buf3 = new SAMPLE_TYPE[ 1024 ];
    buf4 = new SAMPLE_TYPE[ 1024 ];

    fil = 0.0f;
    den = pos = 0;

    recalculate();
}

Reverb::~Reverb()
{
    if ( buf1 )
        delete[] buf1;

    if ( buf2 )
        delete[] buf2;

    if ( buf3 )
        delete[] buf3;

    if ( buf4 )
        delete[] buf4;

    buf1 = buf2 = buf3 = buf4 = nullptr;
}

/* public methods */

float Reverb::getSize()
{
    return _size;
}

void Reverb::setSize( float value )
{
    value = capParam( value );

    if ( _size != value ) {
        _size = value;
        recalculate();
    }
}

float Reverb::getHFDamp()
{
    return _hfDamp;
}

void Reverb::setHFDamp( float value )
{
    value = capParam( value );

    if ( _hfDamp != value ) {
        _hfDamp = value;
        recalculate();
    }
}

float Reverb::getMix()
{
    return _mix;
}

void Reverb::setMix( float value )
{
    value = capParam( value );

    if ( _mix != value ) {
        _mix = value;
        recalculate();
    }
}

float Reverb::getOutput()
{
    return _output;
}

void Reverb::setOutput( float value )
{
    value = capParam( value );

    if ( _output != value ) {
        _output = value;
        recalculate();
    }
}

void Reverb::process( AudioBuffer* audioBuffer, bool isMonosource )
{
    int sampleFrames = audioBuffer->bufferSize;

    SAMPLE_TYPE* in1  = audioBuffer->getBufferForChannel( 0 );
    SAMPLE_TYPE* in2  = audioBuffer->getBufferForChannel( 1 );
    SAMPLE_TYPE* out1 = audioBuffer->getBufferForChannel( 0 );
    SAMPLE_TYPE* out2 = audioBuffer->getBufferForChannel( 1 );

    SAMPLE_TYPE a, b, r;
    SAMPLE_TYPE t, f = fil, fb = fbak, dmp = damp, y = dry, w = wet;
    int  p = pos, d1, d2, d3, d4;

    if ( rdy == 0 )
        clearBuffers();

    d1 = ( p + ( int )( 107 * size )) & 1023;
    d2 = ( p + ( int )( 142 * size )) & 1023;
    d3 = ( p + ( int )( 277 * size )) & 1023;
    d4 = ( p + ( int )( 379 * size )) & 1023;

    --in1;
    --in2;
    --out1;
    --out2;

    while ( --sampleFrames >= 0 )
    {
        a = *++in1;
        b = *++in2;

        f += dmp * (w * (a + b) - f); // HF damping
        r = f;

        t = *(buf1 + p);
        r -= fb * t;
        *(buf1 + d1) = r; // allpass
        r += t;

        t = *(buf2 + p);
        r -= fb * t;
        *(buf2 + d2) = r; // allpass
        r += t;

        t = *(buf3 + p);
        r -= fb * t;
        *(buf3 + d3) = r; // allpass
        r += t;
        a = y * a + r - f; // left output

        t = *(buf4 + p);
        r -= fb * t;
        *(buf4 + d4) = r; // allpass
        r += t;
        b = y * b + r - f; // right output

        ++p  &= 1023;
        ++d1 &= 1023;
        ++d2 &= 1023;
        ++d3 &= 1023;
        ++d4 &= 1023;

        *++out1 = a;
        *++out2 = b;
    }
    pos = p;

    // catch denormals

    if ( fabs( f ) > 1.0e-10 ) {
        fil = f;
        den = 0;
    }
    else {
        fil = 0.0f;
        if ( den == 0 ) {
            den = 1;
            clearBuffers();
        }
    }
}

/* protected methods */

void Reverb::clearBuffers()
{
    memset( buf1, 0, 1024 * sizeof( SAMPLE_TYPE ));
    memset( buf2, 0, 1024 * sizeof( SAMPLE_TYPE ));
    memset( buf3, 0, 1024 * sizeof( SAMPLE_TYPE ));
    memset( buf4, 0, 1024 * sizeof( SAMPLE_TYPE ));

    rdy = 1;
}

void Reverb::recalculate()
{
    SAMPLE_TYPE tmp;

    fbak = 0.8f;
    damp = 0.05f + 0.9f * _hfDamp;
    tmp = ( SAMPLE_TYPE ) powf( 10.0f, 2.0f * _output - 1.0f );
    dry = tmp - _mix * _mix * tmp;
    wet = ( 0.4f + 0.4f ) * _mix * tmp;

    tmp = 0.025f + 2.665f * _size;

    if ( size != tmp )
        rdy = 0; // need to flush buffer

    size = tmp;
}

} // E.O namespace MWEngine
<commit_msg>Make legacy reverb processor mono compatible<commit_after>/**
 * Ported from mdaReverb.h
 * Created by Arne Scheffler on 6/13/08.
 *
 * mda VST Plug-ins
 *
 * Copyright (c) 2008 Paul Kellett
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to the following conditions:
 * The above copyright notice and this permission notice shall be included in all copies or substantial portions of
 * the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
 * SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */
#include "reverb.h"
#include <algorithm>
#include <cstring>
#include <utilities/utils.h>

namespace MWEngine {

/* constructor / destructor */

Reverb::Reverb( float size, float hfDamp, float mix, float output )
{
    _size   = size;
    _hfDamp = hfDamp;
    _mix    = mix;
    _output = output;

    buf1 = new SAMPLE_TYPE[ 1024 ];
    buf2 = new SAMPLE_TYPE[ 1024 ];
    buf3 = new SAMPLE_TYPE[ 1024 ];
    buf4 = new SAMPLE_TYPE[ 1024 ];

    fil = 0.0f;
    den = pos = 0;

    recalculate();
}

Reverb::~Reverb()
{
    if ( buf1 )
        delete[] buf1;

    if ( buf2 )
        delete[] buf2;

    if ( buf3 )
        delete[] buf3;

    if ( buf4 )
        delete[] buf4;

    buf1 = buf2 = buf3 = buf4 = nullptr;
}

/* public methods */

float Reverb::getSize()
{
    return _size;
}

void Reverb::setSize( float value )
{
    value = capParam( value );

    if ( _size != value ) {
        _size = value;
        recalculate();
    }
}

float Reverb::getHFDamp()
{
    return _hfDamp;
}

void Reverb::setHFDamp( float value )
{
    value = capParam( value );

    if ( _hfDamp != value ) {
        _hfDamp = value;
        recalculate();
    }
}

float Reverb::getMix()
{
    return _mix;
}

void Reverb::setMix( float value )
{
    value = capParam( value );

    if ( _mix != value ) {
        _mix = value;
        recalculate();
    }
}

float Reverb::getOutput()
{
    return _output;
}

void Reverb::setOutput( float value )
{
    value = capParam( value );

    if ( _output != value ) {
        _output = value;
        recalculate();
    }
}

void Reverb::process( AudioBuffer* audioBuffer, bool isMonoSource )
{
    int sampleFrames = audioBuffer->bufferSize;

    SAMPLE_TYPE* inL  = audioBuffer->getBufferForChannel(0 );
    SAMPLE_TYPE* outL = audioBuffer->getBufferForChannel(0 );
    SAMPLE_TYPE* inR  = !isMonoSource ? audioBuffer->getBufferForChannel(1 ) : nullptr;
    SAMPLE_TYPE* outR = !isMonoSource ? audioBuffer->getBufferForChannel(1 ) : nullptr;

    SAMPLE_TYPE a, b, r;
    SAMPLE_TYPE t, f = fil, fb = fbak, dmp = damp, y = dry, w = wet;
    int p = pos, d1, d2, d3, d4;

    if ( rdy == 0 )
        clearBuffers();

    d1 = ( p + ( int )( 107 * size )) & 1023;
    d2 = ( p + ( int )( 142 * size )) & 1023;
    d3 = ( p + ( int )( 277 * size )) & 1023;
    d4 = ( p + ( int )( 379 * size )) & 1023;

    --inL;
    --outL;

    if ( !isMonoSource ) {
        --inR;
        --outR;
    }

    while ( --sampleFrames >= 0 )
    {
        a = *++inL;
        b = !isMonoSource ? ( *++inR ) : SILENCE;

        f += dmp * (w * (a + b) - f); // HF damping
        r = f;

        t = *( buf1 + p );
        r -= fb * t;
        *( buf1 + d1 ) = r; // allpass
        r += t;

        t = *( buf2 + p );
        r -= fb * t;
        *( buf2 + d2 ) = r; // allpass
        r += t;

        t = *( buf3 + p );
        r -= fb * t;
        *( buf3 + d3 ) = r; // allpass
        r += t;
        a = y * a + r - f; // left output

        t = *( buf4 + p );
        r -= fb * t;
        *( buf4 + d4 ) = r; // allpass
        r += t;
        b = y * b + r - f; // right output

        ++p  &= 1023;
        ++d1 &= 1023;
        ++d2 &= 1023;
        ++d3 &= 1023;
        ++d4 &= 1023;

        *++outL = a;

        if ( !isMonoSource ) {
            *++outR = b;
        }
    }
    pos = p;

    // catch denormals

    if ( fabs( f ) > 1.0e-10 ) {
        fil = f;
        den = 0;
    }
    else {
        fil = 0.0f;
        if ( den == 0 ) {
            den = 1;
            clearBuffers();
        }
    }
}

/* protected methods */

void Reverb::clearBuffers()
{
    memset( buf1, 0, 1024 * sizeof( SAMPLE_TYPE ));
    memset( buf2, 0, 1024 * sizeof( SAMPLE_TYPE ));
    memset( buf3, 0, 1024 * sizeof( SAMPLE_TYPE ));
    memset( buf4, 0, 1024 * sizeof( SAMPLE_TYPE ));

    rdy = 1;
}

void Reverb::recalculate()
{
    SAMPLE_TYPE tmp;

    fbak = 0.8f;
    damp = 0.05f + 0.9f * _hfDamp;
    tmp = ( SAMPLE_TYPE ) powf( 10.0f, 2.0f * _output - 1.0f );
    dry = tmp - _mix * _mix * tmp;
    wet = ( 0.4f + 0.4f ) * _mix * tmp;

    tmp = 0.025f + 2.665f * _size;

    if ( size != tmp )
        rdy = 0; // need to flush buffer

    size = tmp;
}

} // E.O namespace MWEngine
<|endoftext|>


<commit_before>// Time:  O(logn), pow is O(logn).
// Space: O(logn)

class Solution {
public:
    int integerBreak(int n) {
        if (n < 4) {
            return n - 1;
        }

        // Proof.
        // 1. Let n = a1 + a2 + ... + ak, product = a1 * a2 * ... * ak
        //     - For each ai >= 4, we can always maximize the product by:
        //       ai <= 2 * (ai - 2)
        //     - For each aj >= 5, we can always maximize the product by:
        //       aj <= 3 * (aj - 3)
        //
        //    Conclusion 1:
        //     - For n >= 4, the max of the product must be in the form of
        //       3^a * 2^b, s.t. 3a + 2b = n
        //
        // 2. To maximize the product = 3^a * 2^b s.t. 3a + 2b = n
        //     - For each b >= 3,  we can always maximize the product by:
        //       3^a * 2^b <= 3^(a+2) * 2^(b-3) s.t. 3(a+2) + 2(b-3) = n
        //
        //    Conclusion 2:
        //     - For n >= 4, the max of the product must be in the form of
        //       3^Q * 2^R, 0 <= R < 3 s.t. 3Q + 2R = n
        //       i.e.
        //         if n = 3Q + 0,   the max of the product = 3^Q * 2^0
        //         if n = 3Q + 2,   the max of the product = 3^Q * 2^1
        //         if n = 3Q + 2*2, the max of the product = 3^Q * 2^2

        int res = 0;
        if (n % 3 == 0) {         // n = 3Q + 0, the max is 3^Q * 2^0
            res = pow(3, n / 3);
        } else if (n % 3 == 2) {  // n = 3Q + 2, the max is 3^Q * 2^1
            res =  pow(3, n / 3) * 2;
        } else {                  // n = 3Q + 4, the max is 3^Q * 2^2
            res = pow(3, n / 3 - 1) * 4;
        }
        return res;
    }
};
<commit_msg>Update integer-break.cpp<commit_after>// Time:  O(logn), pow is O(logn).
// Space: O(logn)

class Solution {
public:
    int integerBreak(int n) {
        if (n < 4) {
            return n - 1;
        }

        // Proof.
        // 1. Let n = a1 + a2 + ... + ak, product = a1 * a2 * ... * ak
        //     - For each ai >= 4, we can always maximize the product by:
        //       ai <= 2 * (ai - 2)
        //     - For each aj >= 5, we can always maximize the product by:
        //       aj <= 3 * (aj - 3)
        //
        //    Conclusion 1:
        //     - For n >= 4, the max of the product must be in the form of
        //       3^a * 2^b, s.t. 3a + 2b = n
        //
        // 2. To maximize the product = 3^a * 2^b s.t. 3a + 2b = n
        //     - For each b >= 3,  we can always maximize the product by:
        //       3^a * 2^b <= 3^(a+2) * 2^(b-3) s.t. 3(a+2) + 2(b-3) = n
        //
        //    Conclusion 2:
        //     - For n >= 4, the max of the product must be in the form of
        //       3^Q * 2^R, 0 <= R < 3 s.t. 3Q + 2R = n
        //       i.e.
        //         if n = 3Q + 0,   the max of the product = 3^Q * 2^0
        //         if n = 3Q + 2,   the max of the product = 3^Q * 2^1
        //         if n = 3Q + 2*2, the max of the product = 3^Q * 2^2

        int res = 0;
        if (n % 3 == 0) {         // n = 3Q + 0, the max is 3^Q * 2^0
            res = pow(3, n / 3);
        } else if (n % 3 == 2) {  // n = 3Q + 2, the max is 3^Q * 2^1
            res = pow(3, n / 3) * 2;
        } else {                  // n = 3Q + 4, the max is 3^Q * 2^2
            res = pow(3, n / 3 - 1) * 4;
        }
        return res;
    }
};
<|endoftext|>


<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 <gmock/gmock.h>
#include <gtest/gtest.h>

#include <process/future.hpp>

#include "tests/mesos.hpp"

#include "slave/slave.hpp"
#include "slave/containerizer/docker.hpp"

using namespace mesos;
using namespace mesos::internal;
using namespace mesos::internal::tests;

using mesos::internal::master::Master;

using mesos::internal::slave::Slave;
using mesos::internal::slave::DockerContainerizer;

using process::Future;
using process::PID;

using std::vector;
using std::list;
using std::string;

using testing::_;
using testing::DoDefault;
using testing::Eq;
using testing::Return;

class DockerContainerizerTest : public MesosTest {};

class MockDockerContainerizer : public slave::DockerContainerizer {
public:
  MockDockerContainerizer(
    const slave::Flags& flags,
    bool local,
    const Docker& docker) : DockerContainerizer(flags, local, docker) {}

  process::Future<bool> launch(
    const ContainerID& containerId,
    const TaskInfo& taskInfo,
    const ExecutorInfo& executorInfo,
    const std::string& directory,
    const Option<std::string>& user,
    const SlaveID& slaveId,
    const process::PID<Slave>& slavePid,
    bool checkpoint)
  {
    // Keeping the last launched container id
    lastContainerId = containerId;
    return slave::DockerContainerizer::launch(
             containerId,
             taskInfo,
             executorInfo,
             directory,
             user,
             slaveId,
             slavePid,
             checkpoint);
  }

  ContainerID lastContainerId;
};

TEST_F(DockerContainerizerTest, DOCKER_Launch)
{
  Try<PID<Master> > master = StartMaster();
  ASSERT_SOME(master);

  slave::Flags flags = CreateSlaveFlags();

  Docker docker("docker");

  MockDockerContainerizer dockerContainer(flags, true, docker);

  Try<PID<Slave> > slave = StartSlave((slave::Containerizer*) &dockerContainer);
  ASSERT_SOME(slave);

  MockScheduler sched;
  MesosSchedulerDriver driver(
    &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL);

  Future<FrameworkID> frameworkId;
  EXPECT_CALL(sched, registered(&driver, _, _))
    .WillOnce(FutureArg<1>(&frameworkId));

  Future<vector<Offer> > offers;
  EXPECT_CALL(sched, resourceOffers(&driver, _))
    .WillOnce(FutureArg<1>(&offers))
    .WillRepeatedly(Return()); // Ignore subsequent offers.

  driver.start();

  AWAIT_READY(frameworkId);

  AWAIT_READY(offers);
  EXPECT_NE(0u, offers.get().size());

  const Offer& offer = offers.get()[0];

  TaskInfo task;
  task.set_name("");
  task.mutable_task_id()->set_value("1");
  task.mutable_slave_id()->CopyFrom(offer.slave_id());
  task.mutable_resources()->CopyFrom(offer.resources());

  CommandInfo command;
  CommandInfo::ContainerInfo* containerInfo = command.mutable_container();
  containerInfo->set_image("docker://busybox");
  command.set_value("sleep 120");

  task.mutable_command()->CopyFrom(command);

  Future<TaskStatus> statusRunning;

  vector<TaskInfo> tasks;
  tasks.push_back(task);

  EXPECT_CALL(sched, statusUpdate(&driver, _))
    .WillOnce(FutureArg<1>(&statusRunning))
    .WillRepeatedly(DoDefault());

  driver.launchTasks(offers.get()[0].id(), tasks);

  AWAIT_READY_FOR(statusRunning, Seconds(60));
  EXPECT_EQ(TASK_RUNNING, statusRunning.get().state());

  Future<list<Docker::Container> > containers = docker.ps();

  AWAIT_READY(containers);

  ASSERT_TRUE(containers.get().size() > 0);

  bool foundContainer = false;
  string expectedName = "mesos-" + dockerContainer.lastContainerId.value();

  foreach(const Docker::Container& container, containers.get()) {
    // Docker inspect name contains an extra slash in the beginning
    if (strings::contains(container.name(), expectedName)) {
      foundContainer = true;
      break;
    }
  }

  ASSERT_TRUE(foundContainer);

  dockerContainer.destroy(dockerContainer.lastContainerId);

  driver.stop();
  driver.join();

  Shutdown();
}

// This test tests DockerContainerizer::usage()
TEST_F(DockerContainerizerTest, DOCKER_Usage)
{
  Try<PID<Master> > master = StartMaster();
  ASSERT_SOME(master);

  slave::Flags flags = CreateSlaveFlags();

  Docker docker("docker");

  MockDockerContainerizer dockerContainer(flags, true, docker);

  Try<PID<Slave> > slave = StartSlave((slave::Containerizer*) &dockerContainer);
  ASSERT_SOME(slave);

  MockScheduler sched;
  MesosSchedulerDriver driver(
    &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL);

  Future<FrameworkID> frameworkId;
  EXPECT_CALL(sched, registered(&driver, _, _))
    .WillOnce(FutureArg<1>(&frameworkId));

  Future<vector<Offer> > offers;
  EXPECT_CALL(sched, resourceOffers(&driver, _))
    .WillOnce(FutureArg<1>(&offers))
    .WillRepeatedly(Return()); // Ignore subsequent offers.

  driver.start();

  AWAIT_READY(frameworkId);

  AWAIT_READY(offers);
  EXPECT_NE(0u, offers.get().size());

  const Offer& offer = offers.get()[0];

  TaskInfo task;
  task.set_name("");
  task.mutable_task_id()->set_value("1");
  task.mutable_slave_id()->CopyFrom(offer.slave_id());
  task.mutable_resources()->CopyFrom(offer.resources());

  CommandInfo command;
  CommandInfo::ContainerInfo* containerInfo = command.mutable_container();
  containerInfo->set_image("docker://busybox");
  command.set_value("sleep 120");

  task.mutable_command()->CopyFrom(command);

  Future<TaskStatus> statusRunning;

  vector<TaskInfo> tasks;
  tasks.push_back(task);

  EXPECT_CALL(sched, statusUpdate(&driver, _))
    .WillOnce(FutureArg<1>(&statusRunning))
    .WillRepeatedly(DoDefault());

  // Usage() should fail since the container is not launched.
  Future<ResourceStatistics> usage =
    dockerContainer.usage(dockerContainer.lastContainerId);

  AWAIT_FAILED(usage);

  driver.launchTasks(offers.get()[0].id(), tasks);

  AWAIT_READY_FOR(statusRunning, Seconds(60));
  EXPECT_EQ(TASK_RUNNING, statusRunning.get().state());

  usage = dockerContainer.usage(dockerContainer.lastContainerId);
  AWAIT_READY(usage);
  // TODO(yifan): Verify the usage.

  dockerContainer.destroy(dockerContainer.lastContainerId);

  // Usage() should fail again since the container is destroyed
  usage = dockerContainer.usage(dockerContainer.lastContainerId);
  AWAIT_FAILED(usage);

  driver.stop();
  driver.join();

  Shutdown();
}
<commit_msg>Used 'flags.docker' in tests.<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 <gmock/gmock.h>
#include <gtest/gtest.h>

#include <process/future.hpp>

#include "tests/flags.hpp"
#include "tests/mesos.hpp"

#include "slave/slave.hpp"
#include "slave/containerizer/docker.hpp"

using namespace mesos;
using namespace mesos::internal;
using namespace mesos::internal::tests;

using mesos::internal::master::Master;

using mesos::internal::slave::Slave;
using mesos::internal::slave::DockerContainerizer;

using process::Future;
using process::PID;

using std::vector;
using std::list;
using std::string;

using testing::_;
using testing::DoDefault;
using testing::Eq;
using testing::Return;

class DockerContainerizerTest : public MesosTest {};

class MockDockerContainerizer : public slave::DockerContainerizer {
public:
  MockDockerContainerizer(
    const slave::Flags& flags,
    bool local,
    const Docker& docker) : DockerContainerizer(flags, local, docker) {}

  process::Future<bool> launch(
    const ContainerID& containerId,
    const TaskInfo& taskInfo,
    const ExecutorInfo& executorInfo,
    const std::string& directory,
    const Option<std::string>& user,
    const SlaveID& slaveId,
    const process::PID<Slave>& slavePid,
    bool checkpoint)
  {
    // Keeping the last launched container id.
    lastContainerId = containerId;
    return slave::DockerContainerizer::launch(
             containerId,
             taskInfo,
             executorInfo,
             directory,
             user,
             slaveId,
             slavePid,
             checkpoint);
  }

  ContainerID lastContainerId;
};

TEST_F(DockerContainerizerTest, DOCKER_Launch)
{
  Try<PID<Master> > master = StartMaster();
  ASSERT_SOME(master);

  slave::Flags flags = CreateSlaveFlags();

  Docker docker(tests::flags.docker);

  MockDockerContainerizer dockerContainer(flags, true, docker);

  Try<PID<Slave> > slave = StartSlave((slave::Containerizer*) &dockerContainer);
  ASSERT_SOME(slave);

  MockScheduler sched;
  MesosSchedulerDriver driver(
    &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL);

  Future<FrameworkID> frameworkId;
  EXPECT_CALL(sched, registered(&driver, _, _))
    .WillOnce(FutureArg<1>(&frameworkId));

  Future<vector<Offer> > offers;
  EXPECT_CALL(sched, resourceOffers(&driver, _))
    .WillOnce(FutureArg<1>(&offers))
    .WillRepeatedly(Return()); // Ignore subsequent offers.

  driver.start();

  AWAIT_READY(frameworkId);

  AWAIT_READY(offers);
  EXPECT_NE(0u, offers.get().size());

  const Offer& offer = offers.get()[0];

  TaskInfo task;
  task.set_name("");
  task.mutable_task_id()->set_value("1");
  task.mutable_slave_id()->CopyFrom(offer.slave_id());
  task.mutable_resources()->CopyFrom(offer.resources());

  CommandInfo command;
  CommandInfo::ContainerInfo* containerInfo = command.mutable_container();
  containerInfo->set_image("docker://busybox");
  command.set_value("sleep 120");

  task.mutable_command()->CopyFrom(command);

  Future<TaskStatus> statusRunning;

  vector<TaskInfo> tasks;
  tasks.push_back(task);

  EXPECT_CALL(sched, statusUpdate(&driver, _))
    .WillOnce(FutureArg<1>(&statusRunning))
    .WillRepeatedly(DoDefault());

  driver.launchTasks(offers.get()[0].id(), tasks);

  AWAIT_READY_FOR(statusRunning, Seconds(60));
  EXPECT_EQ(TASK_RUNNING, statusRunning.get().state());

  Future<list<Docker::Container> > containers = docker.ps();

  AWAIT_READY(containers);

  ASSERT_TRUE(containers.get().size() > 0);

  bool foundContainer = false;
  string expectedName = "mesos-" + dockerContainer.lastContainerId.value();

  foreach (const Docker::Container& container, containers.get()) {
    // Docker inspect name contains an extra slash in the beginning.
    if (strings::contains(container.name(), expectedName)) {
      foundContainer = true;
      break;
    }
  }

  ASSERT_TRUE(foundContainer);

  dockerContainer.destroy(dockerContainer.lastContainerId);

  driver.stop();
  driver.join();

  Shutdown();
}

// This test tests DockerContainerizer::usage().
TEST_F(DockerContainerizerTest, DOCKER_Usage)
{
  Try<PID<Master> > master = StartMaster();
  ASSERT_SOME(master);

  slave::Flags flags = CreateSlaveFlags();

  Docker docker(tests::flags.docker);

  MockDockerContainerizer dockerContainer(flags, true, docker);

  Try<PID<Slave> > slave = StartSlave((slave::Containerizer*) &dockerContainer);
  ASSERT_SOME(slave);

  MockScheduler sched;
  MesosSchedulerDriver driver(
    &sched, DEFAULT_FRAMEWORK_INFO, master.get(), DEFAULT_CREDENTIAL);

  Future<FrameworkID> frameworkId;
  EXPECT_CALL(sched, registered(&driver, _, _))
    .WillOnce(FutureArg<1>(&frameworkId));

  Future<vector<Offer> > offers;
  EXPECT_CALL(sched, resourceOffers(&driver, _))
    .WillOnce(FutureArg<1>(&offers))
    .WillRepeatedly(Return()); // Ignore subsequent offers.

  driver.start();

  AWAIT_READY(frameworkId);

  AWAIT_READY(offers);
  EXPECT_NE(0u, offers.get().size());

  const Offer& offer = offers.get()[0];

  TaskInfo task;
  task.set_name("");
  task.mutable_task_id()->set_value("1");
  task.mutable_slave_id()->CopyFrom(offer.slave_id());
  task.mutable_resources()->CopyFrom(offer.resources());

  CommandInfo command;
  CommandInfo::ContainerInfo* containerInfo = command.mutable_container();
  containerInfo->set_image("docker://busybox");
  command.set_value("sleep 120");

  task.mutable_command()->CopyFrom(command);

  Future<TaskStatus> statusRunning;

  vector<TaskInfo> tasks;
  tasks.push_back(task);

  EXPECT_CALL(sched, statusUpdate(&driver, _))
    .WillOnce(FutureArg<1>(&statusRunning))
    .WillRepeatedly(DoDefault());

  // Usage() should fail since the container is not launched.
  Future<ResourceStatistics> usage =
    dockerContainer.usage(dockerContainer.lastContainerId);

  AWAIT_FAILED(usage);

  driver.launchTasks(offers.get()[0].id(), tasks);

  AWAIT_READY_FOR(statusRunning, Seconds(60));
  EXPECT_EQ(TASK_RUNNING, statusRunning.get().state());

  usage = dockerContainer.usage(dockerContainer.lastContainerId);
  AWAIT_READY(usage);
  // TODO(yifan): Verify the usage.

  dockerContainer.destroy(dockerContainer.lastContainerId);

  // Usage() should fail again since the container is destroyed.
  usage = dockerContainer.usage(dockerContainer.lastContainerId);
  AWAIT_FAILED(usage);

  driver.stop();
  driver.join();

  Shutdown();
}
<|endoftext|>


<commit_before>#include <blackhole/formatter/string.hpp>
#include <blackhole/formatter/json.hpp>
#include <blackhole/frontend.hpp>
#include <blackhole/frontend/files.hpp>
#include <blackhole/frontend/syslog.hpp>
#include <blackhole/repository.hpp>
#include <blackhole/sink/files.hpp>
#include <blackhole/sink/socket.hpp>
#include <blackhole/sink/stream.hpp>
#include <blackhole/sink/syslog.hpp>

#include "global.hpp"

using namespace blackhole;

namespace blackhole { namespace sink {

template<>
struct priority_traits<testing::level> {
    static inline
    priority_t map(testing::level lvl) {
        switch (lvl) {
        case testing::level::debug:
            return priority_t::debug;
        case testing::level::info:
            return priority_t::info;
        case testing::level::warn:
            return priority_t::warning;
        case testing::level::error:
            return priority_t::err;
        }

        return priority_t::debug;
    }
};

} } // namespace blackhole::sink

TEST(Factory, StreamStringsFrontend) {
    external_factory_t factory;
    factory.add<sink::stream_t, formatter::string_t>();

    formatter_config_t formatter("string");
    formatter["pattern"] = "[%(timestamp)s]: %(message)s";

    sink_config_t sink("stream");
    sink["output"] = "stdout";

    auto result = factory.create(formatter, sink);
    auto casted = dynamic_cast<
        frontend_t<formatter::string_t, sink::stream_t>*
    >(result.get());
    EXPECT_TRUE(casted != nullptr);
}

TEST(Factory, FileStringsFrontend) {
    external_factory_t factory;
    factory.add<sink::files_t<>, formatter::string_t>();

    formatter_config_t formatter("string");
    formatter["pattern"] = "[%(timestamp)s]: %(message)s";

    sink_config_t sink("files");
    sink["path"] = "/dev/stdout";
    sink["autoflush"] = true;

    auto result = factory.create(formatter, sink);
    auto casted = dynamic_cast<
        frontend_t<formatter::string_t, sink::files_t<>>*
    >(result.get());
    EXPECT_TRUE(casted != nullptr);
}

TEST(Repository, RotationFileStringsFrontendWithMoveWatcher) {
    typedef frontend_t<
        formatter::string_t,
        sink::files_t<
            sink::files::boost_backend_t,
            sink::rotator_t<
                sink::files::boost_backend_t,
                sink::rotation::watcher::move_t
            >
        >
    > frontend_type;

    external_factory_t factory;
    factory.add<
        frontend_type::sink_type,
        frontend_type::formatter_type
    >();

    formatter_config_t formatter("string");
    formatter["pattern"] = "[%(timestamp)s]: %(message)s";

    sink_config_t sink("files");
    sink["path"] = "/dev/stdout";
    sink["autoflush"] = true;
    sink["rotation"]["move"] = true;

    auto casted = dynamic_cast<frontend_type*>(
        factory.create(formatter, sink).get()
    );
    EXPECT_TRUE(casted != nullptr);
}

//!@todo: make traits required.
//!@todo: refactor this test.
//!@todo: drop unused stuff.
//!@todo: compile on lucid
TEST(Repository, SupportsMultipleFileRotationPolicies) {
    external_factory_t factory;
    factory.add<
        sink::files_t<
            sink::files::boost_backend_t,
            sink::rotator_t<
                sink::files::boost_backend_t,
                sink::rotation::watcher::move_t
            >
        >,
        formatter::string_t
    >();

    factory.add<
        sink::files_t<
            sink::files::boost_backend_t,
            sink::rotator_t<
                sink::files::boost_backend_t,
                sink::rotation::watcher::size_t
            >
        >,
        formatter::string_t
    >();

    formatter_config_t formatter("string");
    formatter["pattern"] = "[%(timestamp)s]: %(message)s";

    sink_config_t sink("files");
    sink["path"] = "/dev/stdout";
    sink["autoflush"] = true;
    sink["rotation"]["move"] = true;

    {
        auto result = factory.create(formatter, sink);
        auto casted = dynamic_cast<
            frontend_t<
                formatter::string_t,
                sink::files_t<
                    sink::files::boost_backend_t,
                    sink::rotator_t<
                        sink::files::boost_backend_t,
                        sink::rotation::watcher::move_t
                    >
                >
            >*
        >(result.get());
        EXPECT_TRUE(casted != nullptr);
    }

    sink = sink_config_t("files");
    sink["path"] = "/dev/stdout";
    sink["autoflush"] = true;
    sink["rotation"]["pattern"] = "%(filename)s.log.%N";
    sink["rotation"]["backups"] = 5;
    sink["rotation"]["size"] = 10 * 1024 * 1024;

    {
        auto result = factory.create(formatter, sink);
        auto casted = dynamic_cast<
            frontend_t<
                formatter::string_t,
                sink::files_t<
                    sink::files::boost_backend_t,
                    sink::rotator_t<
                        sink::files::boost_backend_t,
                        sink::rotation::watcher::size_t
                    >
                >
            >*
        >(result.get());
        EXPECT_TRUE(casted != nullptr);
    }
}

TEST(Repository, RotationFileStringsFrontendWithSizeWatcher) {
    external_factory_t factory;
    factory.add<
        sink::files_t<
            sink::files::boost_backend_t,
            sink::rotator_t<
                sink::files::boost_backend_t,
                sink::rotation::watcher::size_t
            >
        >,
        formatter::string_t
    >();

    formatter_config_t formatter("string");
    formatter["pattern"] = "[%(timestamp)s]: %(message)s";

    sink_config_t sink("files");
    sink["path"] = "/dev/stdout";
    sink["autoflush"] = true;
    sink["rotation"]["pattern"] = "%(filename)s.log.%N";
    sink["rotation"]["backups"] = 5;
    sink["rotation"]["size"] = 10 * 1024 * 1024;

    auto result = factory.create(formatter, sink);
    auto casted = dynamic_cast<
        frontend_t<
            formatter::string_t,
            sink::files_t<
                sink::files::boost_backend_t,
                sink::rotator_t<
                    sink::files::boost_backend_t,
                    sink::rotation::watcher::size_t
                >
            >
        >*
    >(result.get());
    EXPECT_TRUE(casted != nullptr);
}

TEST(Repository, RotationFileStringsFrontendWithDatetimeWatcher) {
    external_factory_t factory;
    factory.add<
        sink::files_t<
            sink::files::boost_backend_t,
            sink::rotator_t<
                sink::files::boost_backend_t,
                sink::rotation::watcher::datetime_t<>
            >
        >,
        formatter::string_t
    >();

    formatter_config_t formatter("string");
    formatter["pattern"] = "[%(timestamp)s]: %(message)s";

    sink_config_t sink("files");
    sink["path"] = "/dev/stdout";
    sink["autoflush"] = true;
    sink["rotation"]["pattern"] = "%(filename)s.log.%N";
    sink["rotation"]["backups"] = 5;
    sink["rotation"]["period"] = "d";

    auto result = factory.create(formatter, sink);
    auto casted = dynamic_cast<
        frontend_t<
            formatter::string_t,
            sink::files_t<
                sink::files::boost_backend_t,
                sink::rotator_t<
                    sink::files::boost_backend_t,
                    sink::rotation::watcher::datetime_t<>
                >
            >
        >*
    >(result.get());
    EXPECT_TRUE(casted != nullptr);
}

TEST(Repository, ThrowsExceptionIfRotationWatcherNotSpecified) {
    external_factory_t factory;
    factory.add<
        sink::files_t<
            sink::files::boost_backend_t,
            sink::rotator_t<
                sink::files::boost_backend_t,
                sink::rotation::watcher::datetime_t<>
            >
        >,
        formatter::string_t
    >();

    formatter_config_t formatter("string");
    formatter["pattern"] = "[%(timestamp)s]: %(message)s";

    sink_config_t sink("files");
    sink["path"] = "/dev/stdout";
    sink["autoflush"] = true;
    sink["rotation"]["pattern"] = "%(filename)s.log.%N";
    sink["rotation"]["backups"] = 5;

    EXPECT_THROW(factory.create(formatter, sink), blackhole::error_t);
}

TEST(Factory, SyslogStringsFrontend) {
    external_factory_t factory;
    factory.add<sink::syslog_t<level>, formatter::string_t>();

    formatter_config_t formatter("string");
    formatter["pattern"] = "[%(timestamp)s]: %(message)s";

    sink_config_t sink("syslog");
    sink["identity"] = "AppIdentity";

    EXPECT_TRUE(bool(factory.create(formatter, sink)));
}

TEST(Factory, UdpSocketStringsFrontend) {
    external_factory_t factory;
    factory.add<sink::socket_t<boost::asio::ip::udp>, formatter::string_t>();

    formatter_config_t formatter("string");
    formatter["pattern"] = "[%(timestamp)s]: %(message)s";

    sink_config_t sink("udp");
    sink["host"] = "localhost";
    sink["port"] = 50030;

    EXPECT_TRUE(bool(factory.create(formatter, sink)));
}

TEST(Factory, TcpSocketStringsFrontend) {
    external_factory_t factory;
    factory.add<sink::socket_t<boost::asio::ip::tcp>, formatter::string_t>();

    formatter_config_t formatter("string");
    formatter["pattern"] = "[%(timestamp)s]: %(message)s";

    // Sink will try to connect to the specified port. So if it isn't available,
    // an exception will be thrown, it's ok.
    sink_config_t sink("tcp");
    sink["host"] = "localhost";
    sink["port"] = 22;

    EXPECT_TRUE(bool(factory.create(formatter, sink)));
}

log_config_t create_valid_config() {
    formatter_config_t formatter("string");
    formatter["pattern"] = "[%(timestamp)s]: %(message)s";

    sink_config_t sink("stream");
    sink["output"] = "stdout";

    frontend_config_t frontend = { formatter, sink };
    return log_config_t{ "root", { frontend } };
}

TEST(Repository, InitializationFromSettings) {
    repository_t repository;
    repository.add_config(create_valid_config());

    const bool condition = std::is_same<
        verbose_logger_t<testing::level>,
        decltype(repository.create<verbose_logger_t<testing::level>>("root"))
    >::value;
    static_assert(condition, "repository should return `verbose_logger_t` object");
}

TEST(Repository, ThrowsExceptionIfLoggerWithSpecifiedNameNotFound) {
    repository_t repository;
    repository.add_config(create_valid_config());
    EXPECT_THROW(repository.create<verbose_logger_t<testing::level>>("log"),
                 std::out_of_range);
}

TEST(Repository, CreatesDuplicateOfRootLoggerByDefault) {
    log_config_t config = create_valid_config();
    repository_t::instance().add_config(config);
    repository_t::instance().create<verbose_logger_t<testing::level>>("root");
}

TEST(Factory, ThrowsExceptionWhenRequestNotRegisteredSink) {
    external_factory_t factory;

    formatter_config_t formatter("string");
    formatter["pattern"] = "[%(timestamp)s]: %(message)s";

    sink_config_t sink("files");
    sink["path"] = "/dev/stdout";
    sink["autoflush"] = true;

    EXPECT_THROW(factory.create(formatter, sink), blackhole::error_t);
}

TEST(Factory, ThrowsExceptionWhenRequestNotRegisteredFormatter) {
    external_factory_t factory;
    factory.add<sink::socket_t<boost::asio::ip::udp>, boost::mpl::list<>>();

    formatter_config_t formatter("string");
    formatter["pattern"] = "[%(timestamp)s]: %(message)s";

    sink_config_t sink("files");
    sink["path"] = "/dev/stdout";
    sink["autoflush"] = true;

    EXPECT_THROW(factory.create(formatter, sink), blackhole::error_t);
}

TEST(Repository, StreamSinkWithStringFormatterIsAvailableByDefault) {
    repository_t repository;
    bool registered = repository.registered<
        sink::stream_t,
        formatter::string_t
    >();
    EXPECT_TRUE(registered);
}

TEST(Repository, PairConfiguring) {
    bool registered = false;
    repository_t repository;

    registered = repository.registered<
        sink::syslog_t<level>,
        formatter::string_t
    >();
    EXPECT_FALSE(registered);

    repository.registrate<sink::syslog_t<level>, formatter::string_t>();

    registered = repository.registered<
        sink::syslog_t<level>,
        formatter::string_t
    >();
    EXPECT_TRUE(registered);
}

TEST(Repository, ConfiguringWithMultipleFormatters) {
    typedef boost::mpl::list<
        formatter::string_t,
        formatter::json_t
    > formatters_t;

    bool registered = false;
    repository_t repository;

    registered = repository.registered<sink::files_t<>, formatter::json_t>();
    EXPECT_FALSE(registered);

    repository.registrate<sink::files_t<>, formatters_t>();

    registered = repository.registered<sink::files_t<>, formatter::json_t>();
    EXPECT_TRUE(registered);
}

TEST(Repository, CombinationConfiguring) {
    typedef boost::mpl::vector<
        sink::files_t<>,
        sink::syslog_t<level>
    > sinks_t;

    typedef boost::mpl::list<
        formatter::string_t,
        formatter::json_t
    > formatters_t;

    bool registered = false;
    repository_t repository;

    registered = repository.registered<sink::files_t<>, formatter::json_t>();
    ASSERT_FALSE(registered);
    registered = repository.registered<sink::syslog_t<level>, formatter::string_t>();
    ASSERT_FALSE(registered);
    registered = repository.registered<sink::syslog_t<level>, formatter::json_t>();
    ASSERT_FALSE(registered);

    repository.registrate<sinks_t, formatters_t>();

    registered = repository.registered<sink::files_t<>, formatter::json_t>();
    EXPECT_TRUE(registered);
    registered = repository.registered<sink::syslog_t<level>, formatter::string_t>();
    EXPECT_TRUE(registered);
    registered = repository.registered<sink::syslog_t<level>, formatter::json_t>();
    EXPECT_TRUE(registered);
}

TEST(Repository, ThrowsExceptionWhenSinkIsRegisteredButItsUniqueNameIsDifferent) {
    repository_t repository;

    formatter_config_t formatter("string");
    formatter["pattern"] = "[%(timestamp)s]: %(message)s";

    sink_config_t sink("files");
    sink["path"] = "/dev/stdout";
    sink["autoflush"] = true;
    sink["rotation"]["size"] = 1000;

    frontend_config_t frontend = { formatter, sink };
    log_config_t config = { "root", { frontend } };

    repository.registrate<
        sink::files_t<
            sink::files::boost_backend_t,
            sink::rotator_t<
                sink::files::boost_backend_t,
                sink::rotation::watcher::size_t
            >
        >,
        formatter::string_t
    >();
    repository.add_config(config);

    EXPECT_THROW(repository.create<verbose_logger_t<level>>("root"),
                 blackhole::error_t);
}
<commit_msg>[Unit Testing] Refactoring. One task less.<commit_after>#include <blackhole/formatter/string.hpp>
#include <blackhole/formatter/json.hpp>
#include <blackhole/frontend.hpp>
#include <blackhole/frontend/files.hpp>
#include <blackhole/frontend/syslog.hpp>
#include <blackhole/repository.hpp>
#include <blackhole/sink/files.hpp>
#include <blackhole/sink/socket.hpp>
#include <blackhole/sink/stream.hpp>
#include <blackhole/sink/syslog.hpp>

#include "global.hpp"

using namespace blackhole;

namespace blackhole { namespace sink {

template<>
struct priority_traits<testing::level> {
    static inline
    priority_t map(testing::level lvl) {
        switch (lvl) {
        case testing::level::debug:
            return priority_t::debug;
        case testing::level::info:
            return priority_t::info;
        case testing::level::warn:
            return priority_t::warning;
        case testing::level::error:
            return priority_t::err;
        }

        return priority_t::debug;
    }
};

} } // namespace blackhole::sink

TEST(Factory, StreamStringsFrontend) {
    external_factory_t factory;
    factory.add<sink::stream_t, formatter::string_t>();

    formatter_config_t formatter("string");
    formatter["pattern"] = "[%(timestamp)s]: %(message)s";

    sink_config_t sink("stream");
    sink["output"] = "stdout";

    auto result = factory.create(formatter, sink);
    auto casted = dynamic_cast<
        frontend_t<formatter::string_t, sink::stream_t>*
    >(result.get());
    EXPECT_TRUE(casted != nullptr);
}

TEST(Factory, FileStringsFrontend) {
    external_factory_t factory;
    factory.add<sink::files_t<>, formatter::string_t>();

    formatter_config_t formatter("string");
    formatter["pattern"] = "[%(timestamp)s]: %(message)s";

    sink_config_t sink("files");
    sink["path"] = "/dev/stdout";
    sink["autoflush"] = true;

    auto result = factory.create(formatter, sink);
    auto casted = dynamic_cast<
        frontend_t<formatter::string_t, sink::files_t<>>*
    >(result.get());
    EXPECT_TRUE(casted != nullptr);
}

TEST(Repository, RotationFileStringsFrontendWithMoveWatcher) {
    typedef frontend_t<
        formatter::string_t,
        sink::files_t<
            sink::files::boost_backend_t,
            sink::rotator_t<
                sink::files::boost_backend_t,
                sink::rotation::watcher::move_t
            >
        >
    > frontend_type;

    external_factory_t factory;
    factory.add<frontend_type::sink_type, frontend_type::formatter_type>();

    formatter_config_t formatter("string");
    formatter["pattern"] = "[%(timestamp)s]: %(message)s";

    sink_config_t sink("files");
    sink["path"] = "/dev/stdout";
    sink["autoflush"] = true;
    sink["rotation"]["move"] = true;

    auto casted = dynamic_cast<frontend_type*>(
        factory.create(formatter, sink).get()
    );
    EXPECT_TRUE(casted != nullptr);
}

//!@todo: make traits required.
//!@todo: drop unused stuff.
//!@todo: compile on lucid
TEST(Repository, SupportsMultipleFileRotationPolicies) {
    typedef frontend_t<
        formatter::string_t,
        sink::files_t<
            sink::files::boost_backend_t,
            sink::rotator_t<
                sink::files::boost_backend_t,
                sink::rotation::watcher::move_t
            >
        >
    > frontend1_type;

    typedef frontend_t<
        formatter::string_t,
        sink::files_t<
            sink::files::boost_backend_t,
            sink::rotator_t<
                sink::files::boost_backend_t,
                sink::rotation::watcher::size_t
            >
        >
    > frontend2_type;

    external_factory_t factory;
    factory.add<frontend1_type::sink_type, frontend1_type::formatter_type>();
    factory.add<frontend2_type::sink_type, frontend2_type::formatter_type>();

    formatter_config_t formatter("string");
    formatter["pattern"] = "[%(timestamp)s]: %(message)s";

    sink_config_t sink("files");
    sink["path"] = "/dev/stdout";
    sink["autoflush"] = true;
    sink["rotation"]["move"] = true;

    {
        auto casted = dynamic_cast<frontend1_type*>(
            factory.create(formatter, sink).get()
        );
        EXPECT_TRUE(casted != nullptr);
    }

    sink = sink_config_t("files");
    sink["path"] = "/dev/stdout";
    sink["autoflush"] = true;
    sink["rotation"]["pattern"] = "%(filename)s.log.%N";
    sink["rotation"]["backups"] = 5;
    sink["rotation"]["size"] = 10 * 1024 * 1024;

    {
        auto casted = dynamic_cast<frontend2_type*>(
            factory.create(formatter, sink).get()
        );
        EXPECT_TRUE(casted != nullptr);
    }
}

TEST(Repository, RotationFileStringsFrontendWithSizeWatcher) {
    typedef frontend_t<
        formatter::string_t,
        sink::files_t<
            sink::files::boost_backend_t,
            sink::rotator_t<
                sink::files::boost_backend_t,
                sink::rotation::watcher::size_t
            >
        >
    > frontend_type;

    external_factory_t factory;
    factory.add<frontend_type::sink_type, frontend_type::formatter_type>();

    formatter_config_t formatter("string");
    formatter["pattern"] = "[%(timestamp)s]: %(message)s";

    sink_config_t sink("files");
    sink["path"] = "/dev/stdout";
    sink["autoflush"] = true;
    sink["rotation"]["pattern"] = "%(filename)s.log.%N";
    sink["rotation"]["backups"] = 5;
    sink["rotation"]["size"] = 10 * 1024 * 1024;

    auto casted = dynamic_cast<frontend_type*>(
        factory.create(formatter, sink).get()
    );
    EXPECT_TRUE(casted != nullptr);
}

TEST(Repository, RotationFileStringsFrontendWithDatetimeWatcher) {
    typedef frontend_t<
        formatter::string_t,
        sink::files_t<
            sink::files::boost_backend_t,
            sink::rotator_t<
                sink::files::boost_backend_t,
                sink::rotation::watcher::datetime_t<>
            >
        >
    > frontend_type;
    external_factory_t factory;
    factory.add<frontend_type::sink_type, frontend_type::formatter_type>();

    formatter_config_t formatter("string");
    formatter["pattern"] = "[%(timestamp)s]: %(message)s";

    sink_config_t sink("files");
    sink["path"] = "/dev/stdout";
    sink["autoflush"] = true;
    sink["rotation"]["pattern"] = "%(filename)s.log.%N";
    sink["rotation"]["backups"] = 5;
    sink["rotation"]["period"] = "d";

    auto casted = dynamic_cast<frontend_type*>(
        factory.create(formatter, sink).get()
    );
    EXPECT_TRUE(casted != nullptr);
}

TEST(Repository, ThrowsExceptionIfRotationWatcherNotSpecified) {
    external_factory_t factory;
    factory.add<
        sink::files_t<
            sink::files::boost_backend_t,
            sink::rotator_t<
                sink::files::boost_backend_t,
                sink::rotation::watcher::datetime_t<>
            >
        >,
        formatter::string_t
    >();

    formatter_config_t formatter("string");
    formatter["pattern"] = "[%(timestamp)s]: %(message)s";

    sink_config_t sink("files");
    sink["path"] = "/dev/stdout";
    sink["autoflush"] = true;
    sink["rotation"]["pattern"] = "%(filename)s.log.%N";
    sink["rotation"]["backups"] = 5;

    EXPECT_THROW(factory.create(formatter, sink), blackhole::error_t);
}

TEST(Factory, SyslogStringsFrontend) {
    external_factory_t factory;
    factory.add<sink::syslog_t<level>, formatter::string_t>();

    formatter_config_t formatter("string");
    formatter["pattern"] = "[%(timestamp)s]: %(message)s";

    sink_config_t sink("syslog");
    sink["identity"] = "AppIdentity";

    EXPECT_TRUE(bool(factory.create(formatter, sink)));
}

TEST(Factory, UdpSocketStringsFrontend) {
    external_factory_t factory;
    factory.add<sink::socket_t<boost::asio::ip::udp>, formatter::string_t>();

    formatter_config_t formatter("string");
    formatter["pattern"] = "[%(timestamp)s]: %(message)s";

    sink_config_t sink("udp");
    sink["host"] = "localhost";
    sink["port"] = 50030;

    EXPECT_TRUE(bool(factory.create(formatter, sink)));
}

TEST(Factory, TcpSocketStringsFrontend) {
    external_factory_t factory;
    factory.add<sink::socket_t<boost::asio::ip::tcp>, formatter::string_t>();

    formatter_config_t formatter("string");
    formatter["pattern"] = "[%(timestamp)s]: %(message)s";

    // Sink will try to connect to the specified port. So if it isn't available,
    // an exception will be thrown, it's ok.
    sink_config_t sink("tcp");
    sink["host"] = "localhost";
    sink["port"] = 22;

    EXPECT_TRUE(bool(factory.create(formatter, sink)));
}

log_config_t create_valid_config() {
    formatter_config_t formatter("string");
    formatter["pattern"] = "[%(timestamp)s]: %(message)s";

    sink_config_t sink("stream");
    sink["output"] = "stdout";

    frontend_config_t frontend = { formatter, sink };
    return log_config_t{ "root", { frontend } };
}

TEST(Repository, InitializationFromSettings) {
    repository_t repository;
    repository.add_config(create_valid_config());

    const bool condition = std::is_same<
        verbose_logger_t<testing::level>,
        decltype(repository.create<verbose_logger_t<testing::level>>("root"))
    >::value;
    static_assert(condition, "repository should return `verbose_logger_t` object");
}

TEST(Repository, ThrowsExceptionIfLoggerWithSpecifiedNameNotFound) {
    repository_t repository;
    repository.add_config(create_valid_config());
    EXPECT_THROW(repository.create<verbose_logger_t<testing::level>>("log"),
                 std::out_of_range);
}

TEST(Repository, CreatesDuplicateOfRootLoggerByDefault) {
    repository_t repository;
    log_config_t config = create_valid_config();
    repository.add_config(config);
    repository.create<verbose_logger_t<testing::level>>("root");
}

TEST(Factory, ThrowsExceptionWhenRequestNotRegisteredSink) {
    external_factory_t factory;

    formatter_config_t formatter("string");
    formatter["pattern"] = "[%(timestamp)s]: %(message)s";

    sink_config_t sink("files");
    sink["path"] = "/dev/stdout";
    sink["autoflush"] = true;

    EXPECT_THROW(factory.create(formatter, sink), blackhole::error_t);
}

TEST(Factory, ThrowsExceptionWhenRequestNotRegisteredFormatter) {
    external_factory_t factory;
    factory.add<sink::socket_t<boost::asio::ip::udp>, boost::mpl::list<>>();

    formatter_config_t formatter("string");
    formatter["pattern"] = "[%(timestamp)s]: %(message)s";

    sink_config_t sink("files");
    sink["path"] = "/dev/stdout";
    sink["autoflush"] = true;

    EXPECT_THROW(factory.create(formatter, sink), blackhole::error_t);
}

TEST(Repository, StreamSinkWithStringFormatterIsAvailableByDefault) {
    repository_t repository;
    bool registered = repository.registered<
        sink::stream_t,
        formatter::string_t
    >();
    EXPECT_TRUE(registered);
}

TEST(Repository, PairConfiguring) {
    bool registered = false;
    repository_t repository;

    registered = repository.registered<
        sink::syslog_t<level>,
        formatter::string_t
    >();
    EXPECT_FALSE(registered);

    repository.registrate<sink::syslog_t<level>, formatter::string_t>();

    registered = repository.registered<
        sink::syslog_t<level>,
        formatter::string_t
    >();
    EXPECT_TRUE(registered);
}

TEST(Repository, ConfiguringWithMultipleFormatters) {
    typedef boost::mpl::list<
        formatter::string_t,
        formatter::json_t
    > formatters_t;

    bool registered = false;
    repository_t repository;

    registered = repository.registered<sink::files_t<>, formatter::json_t>();
    EXPECT_FALSE(registered);

    repository.registrate<sink::files_t<>, formatters_t>();

    registered = repository.registered<sink::files_t<>, formatter::json_t>();
    EXPECT_TRUE(registered);
}

TEST(Repository, CombinationConfiguring) {
    typedef boost::mpl::vector<
        sink::files_t<>,
        sink::syslog_t<level>
    > sinks_t;

    typedef boost::mpl::list<
        formatter::string_t,
        formatter::json_t
    > formatters_t;

    bool registered = false;
    repository_t repository;

    registered = repository.registered<sink::files_t<>, formatter::json_t>();
    ASSERT_FALSE(registered);
    registered = repository.registered<sink::syslog_t<level>, formatter::string_t>();
    ASSERT_FALSE(registered);
    registered = repository.registered<sink::syslog_t<level>, formatter::json_t>();
    ASSERT_FALSE(registered);

    repository.registrate<sinks_t, formatters_t>();

    registered = repository.registered<sink::files_t<>, formatter::json_t>();
    EXPECT_TRUE(registered);
    registered = repository.registered<sink::syslog_t<level>, formatter::string_t>();
    EXPECT_TRUE(registered);
    registered = repository.registered<sink::syslog_t<level>, formatter::json_t>();
    EXPECT_TRUE(registered);
}

TEST(Repository, ThrowsExceptionWhenSinkIsRegisteredButItsUniqueNameIsDifferent) {
    repository_t repository;

    formatter_config_t formatter("string");
    formatter["pattern"] = "[%(timestamp)s]: %(message)s";

    sink_config_t sink("files");
    sink["path"] = "/dev/stdout";
    sink["autoflush"] = true;
    sink["rotation"]["size"] = 1000;

    frontend_config_t frontend = { formatter, sink };
    log_config_t config = { "root", { frontend } };

    repository.registrate<
        sink::files_t<
            sink::files::boost_backend_t,
            sink::rotator_t<
                sink::files::boost_backend_t,
                sink::rotation::watcher::size_t
            >
        >,
        formatter::string_t
    >();
    repository.add_config(config);

    EXPECT_THROW(repository.create<verbose_logger_t<level>>("root"),
                 blackhole::error_t);
}
<|endoftext|>


<commit_before>#include "pydbc/descriptions/number_description.h"

#include <cppunit/extensions/HelperMacros.h>
#include <cppunit_toolbox/extensions/assert_equal_with_different_types.h>
#include <boost/variant/get.hpp>
#include <sqlext.h>
#include <limits.h>
#include <stdexcept>

class number_description_test : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE( number_description_test );

	CPPUNIT_TEST( positive_integer );
	CPPUNIT_TEST( negative_integer );
	CPPUNIT_TEST( max_positive_integer );
	CPPUNIT_TEST( min_negative_integer );
	CPPUNIT_TEST( larger_than_max_overflows );
	CPPUNIT_TEST( smaller_than_min_overflows );
	CPPUNIT_TEST( floating_point );

CPPUNIT_TEST_SUITE_END();

public:

	void positive_integer();
	void negative_integer();
	void max_positive_integer();
	void min_negative_integer();
	void larger_than_max_overflows();
	void smaller_than_min_overflows();
	void floating_point();

};

// Registers the fixture with the 'registry'
CPPUNIT_TEST_SUITE_REGISTRATION( number_description_test );

void number_description_test::positive_integer()
{
	SQL_NUMERIC_STRUCT data = {
				18,
				0,
				1, // + sign
				// binary representation of 1234567890 from low to high bytes
				{0xd2, 0x02, 0x96, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
			};

	long const expected = 1234567890;
	pydbc::number_description description;
	auto const actual = description.make_field(reinterpret_cast<char const *>(&data));

	CPPUNIT_ASSERT_EQUAL(pydbc::field{expected}, actual);
}

void number_description_test::negative_integer()
{
	SQL_NUMERIC_STRUCT data = {
				18,
				0,
				0, // - sign
				// binary representation of 1234567890 from low to high bytes
				{0xd2, 0x02, 0x96, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
			};

	long const expected = -1234567890;
	pydbc::number_description description;
	auto const actual = description.make_field(reinterpret_cast<char const *>(&data));

	CPPUNIT_ASSERT_EQUAL(pydbc::field{expected}, actual);
}

void number_description_test::max_positive_integer()
{
	SQL_NUMERIC_STRUCT data = {
				18,
				0,
				1, // + sign
				// binary representation of 2^63 - 1
				{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
			};

	long const expected = std::numeric_limits<long>::max();
	pydbc::number_description description;
	auto const actual = description.make_field(reinterpret_cast<char const *>(&data));

	CPPUNIT_ASSERT_EQUAL(pydbc::field{expected}, actual);
}

void number_description_test::min_negative_integer()
{
	SQL_NUMERIC_STRUCT data = {
				18,
				0,
				0, // + sign
				// binary representation of 2^63
				{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
			};

	long const expected = std::numeric_limits<long>::min();
	pydbc::number_description description;
	auto const actual = description.make_field(reinterpret_cast<char const *>(&data));

	CPPUNIT_ASSERT_EQUAL(pydbc::field{expected}, actual);
}

void number_description_test::larger_than_max_overflows()
{
	SQL_NUMERIC_STRUCT data = {
				18,
				0,
				1, // + sign
				// binary representation of 2^63 = maximum positive integer + 1
				{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
			};

	pydbc::number_description description;
	CPPUNIT_ASSERT_THROW(description.make_field(reinterpret_cast<char const *>(&data)), std::overflow_error);
}

void number_description_test::smaller_than_min_overflows()
{
	SQL_NUMERIC_STRUCT data = {
				18,
				0,
				0, // - sign
				// binary representation of 2^63 + 1
				{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
			};

	pydbc::number_description description;
	CPPUNIT_ASSERT_THROW(description.make_field(reinterpret_cast<char const *>(&data)), std::overflow_error);
}

void number_description_test::floating_point()
{
	SQL_NUMERIC_STRUCT data = {
				18,
				2, // 2 digits after decimal point
				1, // + sign
				// binary representation of 314
				{0x3a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
			};

	double const expected = 3.14;
	pydbc::number_description description;
	auto const actual = description.make_field(reinterpret_cast<char const *>(&data));

	CPPUNIT_ASSERT_DOUBLES_EQUAL(expected, boost::get<double>(actual), 1e-12);
}
<commit_msg>Add test for other number_description methods<commit_after>#include "pydbc/descriptions/number_description.h"

#include <cppunit/extensions/HelperMacros.h>
#include <cppunit_toolbox/extensions/assert_equal_with_different_types.h>
#include <boost/variant/get.hpp>
#include <sqlext.h>
#include <limits.h>
#include <stdexcept>

class number_description_test : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE( number_description_test );

	CPPUNIT_TEST( basic_properties );
	CPPUNIT_TEST( positive_integer );
	CPPUNIT_TEST( negative_integer );
	CPPUNIT_TEST( max_positive_integer );
	CPPUNIT_TEST( min_negative_integer );
	CPPUNIT_TEST( larger_than_max_overflows );
	CPPUNIT_TEST( smaller_than_min_overflows );
	CPPUNIT_TEST( floating_point );

CPPUNIT_TEST_SUITE_END();

public:

	void basic_properties();
	void positive_integer();
	void negative_integer();
	void max_positive_integer();
	void min_negative_integer();
	void larger_than_max_overflows();
	void smaller_than_min_overflows();
	void floating_point();

};

// Registers the fixture with the 'registry'
CPPUNIT_TEST_SUITE_REGISTRATION( number_description_test );

void number_description_test::basic_properties()
{
	pydbc::number_description description;
	CPPUNIT_ASSERT_EQUAL(sizeof(SQL_NUMERIC_STRUCT), description.element_size());
	CPPUNIT_ASSERT_EQUAL(SQL_NUMERIC, description.column_type());
}

void number_description_test::positive_integer()
{
	SQL_NUMERIC_STRUCT data = {
				18,
				0,
				1, // + sign
				// binary representation of 1234567890 from low to high bytes
				{0xd2, 0x02, 0x96, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
			};

	long const expected = 1234567890;
	pydbc::number_description description;
	auto const actual = description.make_field(reinterpret_cast<char const *>(&data));

	CPPUNIT_ASSERT_EQUAL(pydbc::field{expected}, actual);
}

void number_description_test::negative_integer()
{
	SQL_NUMERIC_STRUCT data = {
				18,
				0,
				0, // - sign
				// binary representation of 1234567890 from low to high bytes
				{0xd2, 0x02, 0x96, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
			};

	long const expected = -1234567890;
	pydbc::number_description description;
	auto const actual = description.make_field(reinterpret_cast<char const *>(&data));

	CPPUNIT_ASSERT_EQUAL(pydbc::field{expected}, actual);
}

void number_description_test::max_positive_integer()
{
	SQL_NUMERIC_STRUCT data = {
				18,
				0,
				1, // + sign
				// binary representation of 2^63 - 1
				{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
			};

	long const expected = std::numeric_limits<long>::max();
	pydbc::number_description description;
	auto const actual = description.make_field(reinterpret_cast<char const *>(&data));

	CPPUNIT_ASSERT_EQUAL(pydbc::field{expected}, actual);
}

void number_description_test::min_negative_integer()
{
	SQL_NUMERIC_STRUCT data = {
				18,
				0,
				0, // + sign
				// binary representation of 2^63
				{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
			};

	long const expected = std::numeric_limits<long>::min();
	pydbc::number_description description;
	auto const actual = description.make_field(reinterpret_cast<char const *>(&data));

	CPPUNIT_ASSERT_EQUAL(pydbc::field{expected}, actual);
}

void number_description_test::larger_than_max_overflows()
{
	SQL_NUMERIC_STRUCT data = {
				18,
				0,
				1, // + sign
				// binary representation of 2^63 = maximum positive integer + 1
				{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
			};

	pydbc::number_description description;
	CPPUNIT_ASSERT_THROW(description.make_field(reinterpret_cast<char const *>(&data)), std::overflow_error);
}

void number_description_test::smaller_than_min_overflows()
{
	SQL_NUMERIC_STRUCT data = {
				18,
				0,
				0, // - sign
				// binary representation of 2^63 + 1
				{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
			};

	pydbc::number_description description;
	CPPUNIT_ASSERT_THROW(description.make_field(reinterpret_cast<char const *>(&data)), std::overflow_error);
}

void number_description_test::floating_point()
{
	SQL_NUMERIC_STRUCT data = {
				18,
				2, // 2 digits after decimal point
				1, // + sign
				// binary representation of 314
				{0x3a, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
			};

	double const expected = 3.14;
	pydbc::number_description description;
	auto const actual = description.make_field(reinterpret_cast<char const *>(&data));

	CPPUNIT_ASSERT_DOUBLES_EQUAL(expected, boost::get<double>(actual), 1e-12);
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */

#include <osl/file.h>
#include <osl/process.h>
#include <rtl/ustring.hxx>
#ifdef SAL_UNX
#include <unistd.h>
#include <limits.h>
#include <string.h>
#include <sys/stat.h>
#define TEST_VOLUME ""
#else
// WINDOWS
#define TEST_VOLUME "c:/"
#endif

#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/plugin/TestPlugIn.h>

namespace osl_test_file
{

// -----------------------------------------------------------------------------

class oldtestfile : public CppUnit::TestFixture
{
public:
    void test_file_001();
    void test_file_002();
    void test_file_004();

    CPPUNIT_TEST_SUITE( oldtestfile );
    CPPUNIT_TEST( test_file_001 );
    CPPUNIT_TEST( test_file_002 );
    CPPUNIT_TEST( test_file_004 );
    CPPUNIT_TEST_SUITE_END( );
};

const char * const aSource1[] =
{
    "a"    , "file:///" TEST_VOLUME "bla/a",
    ///TODO: check if last slash must be omitted in resolved path.
//    "a/"   , "file:///" TEST_VOLUME "bla/a",
    "../a" , "file:///" TEST_VOLUME "a" ,
    "a/.." , "file:///" TEST_VOLUME "bla/",
    "a/../b" , "file:///" TEST_VOLUME "bla/b",
    ".."   , "file:///" TEST_VOLUME "",
    "a/b/c/d"   , "file:///" TEST_VOLUME "bla/a/b/c/d",
    "a/./c"   , "file:///" TEST_VOLUME "bla/a/c",
    "file:///bla/blub", "file:///"  "bla/blub",
    0 , 0
};

const char * const aSource2[ ] =
{
    "a" , "file:///" TEST_VOLUME "bla/blubs/schnubbel/a",
    ///TODO: check if last slash must be omitted in resolved path.
//    "a/", "file:///" TEST_VOLUME "bla/blubs/schnubbel/a",
    "../a", "file:///" TEST_VOLUME "bla/blubs/a",
    "../../a", "file:///" TEST_VOLUME "bla/a",
    "../../../a", "file:///" TEST_VOLUME "a",
    "../../../a/b/c/d", "file:///" TEST_VOLUME "a/b/c/d",
    0,0
};

const char * const aSource3[ ] =
{
    ".." , "/a",
    "../a" , "/a/a",
    "e/f" , "/c/e/f",
    "../..", "",
    0,0
};

using ::rtl::OUString;
using ::rtl::OUStringToOString;
using ::rtl::OString;

void oldtestfile::test_file_001()
{
#ifndef WIN32
    OUString base1( "file:///" TEST_VOLUME "bla" );
    int i;
    for( i = 0 ; aSource1[i] ; i +=2 )
    {
        OUString target;
        OUString rel = OUString::createFromAscii( aSource1[i] );
        oslFileError e = osl_getAbsoluteFileURL( base1.pData, rel.pData , &target.pData );
        CPPUNIT_ASSERT_MESSAGE("failure #1",  osl_File_E_None == e );
        if( osl_File_E_None == e )
        {
            CPPUNIT_ASSERT_MESSAGE("failure #1.1",  target.equalsAscii( aSource1[i+1] ) );
        }
    }
#endif
}

void oldtestfile::test_file_002()
{
#ifndef WIN32
    OUString base2( "file:///" TEST_VOLUME "bla/blubs/schnubbel" );
    int i;
    for(  i = 0 ; aSource2[i] ; i +=2 )
    {
        OUString target;
        OUString rel = OUString::createFromAscii( aSource2[i] );
        oslFileError e = osl_getAbsoluteFileURL( base2.pData, rel.pData , &target.pData );
        CPPUNIT_ASSERT_MESSAGE("failure #2",  osl_File_E_None == e );
        if( osl_File_E_None == e )
        {
            CPPUNIT_ASSERT_MESSAGE("failure #2.1",  target.equalsAscii( aSource2[i+1] ) );
        }
    }
#endif
}

void oldtestfile::test_file_004()
{
#ifndef WIN32
    OUString base4( "file:///" TEST_VOLUME "bla/" );
    int i;
    for( i = 0 ; aSource1[i] ; i +=2 )
    {
        OUString target;
        OUString rel = OUString::createFromAscii( aSource1[i] );
        oslFileError e = osl_getAbsoluteFileURL( base4.pData, rel.pData , &target.pData );
        CPPUNIT_ASSERT_MESSAGE("failure #10",  osl_File_E_None == e );
        if( osl_File_E_None == e )
        {
            CPPUNIT_ASSERT_MESSAGE("failure #10.1",  target.equalsAscii( aSource1[i+1] ) );
        }
    }
#endif
}

} // namespace osl_test_file

// -----------------------------------------------------------------------------
CPPUNIT_TEST_SUITE_REGISTRATION( osl_test_file::oldtestfile);

// -----------------------------------------------------------------------------
CPPUNIT_PLUGIN_IMPLEMENT();

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>-Werror,-Wunused-const-variable<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */

#include <osl/file.h>
#include <osl/process.h>
#include <rtl/ustring.hxx>
#ifdef SAL_UNX
#include <unistd.h>
#include <limits.h>
#include <string.h>
#include <sys/stat.h>
#define TEST_VOLUME ""
#else
// WINDOWS
#define TEST_VOLUME "c:/"
#endif

#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/plugin/TestPlugIn.h>

namespace osl_test_file
{

// -----------------------------------------------------------------------------

class oldtestfile : public CppUnit::TestFixture
{
public:
    void test_file_001();
    void test_file_002();
    void test_file_004();

    CPPUNIT_TEST_SUITE( oldtestfile );
    CPPUNIT_TEST( test_file_001 );
    CPPUNIT_TEST( test_file_002 );
    CPPUNIT_TEST( test_file_004 );
    CPPUNIT_TEST_SUITE_END( );
};

const char * const aSource1[] =
{
    "a"    , "file:///" TEST_VOLUME "bla/a",
    ///TODO: check if last slash must be omitted in resolved path.
//    "a/"   , "file:///" TEST_VOLUME "bla/a",
    "../a" , "file:///" TEST_VOLUME "a" ,
    "a/.." , "file:///" TEST_VOLUME "bla/",
    "a/../b" , "file:///" TEST_VOLUME "bla/b",
    ".."   , "file:///" TEST_VOLUME "",
    "a/b/c/d"   , "file:///" TEST_VOLUME "bla/a/b/c/d",
    "a/./c"   , "file:///" TEST_VOLUME "bla/a/c",
    "file:///bla/blub", "file:///"  "bla/blub",
    0 , 0
};

const char * const aSource2[ ] =
{
    "a" , "file:///" TEST_VOLUME "bla/blubs/schnubbel/a",
    ///TODO: check if last slash must be omitted in resolved path.
//    "a/", "file:///" TEST_VOLUME "bla/blubs/schnubbel/a",
    "../a", "file:///" TEST_VOLUME "bla/blubs/a",
    "../../a", "file:///" TEST_VOLUME "bla/a",
    "../../../a", "file:///" TEST_VOLUME "a",
    "../../../a/b/c/d", "file:///" TEST_VOLUME "a/b/c/d",
    0,0
};

using ::rtl::OUString;
using ::rtl::OUStringToOString;
using ::rtl::OString;

void oldtestfile::test_file_001()
{
#ifndef WIN32
    OUString base1( "file:///" TEST_VOLUME "bla" );
    int i;
    for( i = 0 ; aSource1[i] ; i +=2 )
    {
        OUString target;
        OUString rel = OUString::createFromAscii( aSource1[i] );
        oslFileError e = osl_getAbsoluteFileURL( base1.pData, rel.pData , &target.pData );
        CPPUNIT_ASSERT_MESSAGE("failure #1",  osl_File_E_None == e );
        if( osl_File_E_None == e )
        {
            CPPUNIT_ASSERT_MESSAGE("failure #1.1",  target.equalsAscii( aSource1[i+1] ) );
        }
    }
#endif
}

void oldtestfile::test_file_002()
{
#ifndef WIN32
    OUString base2( "file:///" TEST_VOLUME "bla/blubs/schnubbel" );
    int i;
    for(  i = 0 ; aSource2[i] ; i +=2 )
    {
        OUString target;
        OUString rel = OUString::createFromAscii( aSource2[i] );
        oslFileError e = osl_getAbsoluteFileURL( base2.pData, rel.pData , &target.pData );
        CPPUNIT_ASSERT_MESSAGE("failure #2",  osl_File_E_None == e );
        if( osl_File_E_None == e )
        {
            CPPUNIT_ASSERT_MESSAGE("failure #2.1",  target.equalsAscii( aSource2[i+1] ) );
        }
    }
#endif
}

void oldtestfile::test_file_004()
{
#ifndef WIN32
    OUString base4( "file:///" TEST_VOLUME "bla/" );
    int i;
    for( i = 0 ; aSource1[i] ; i +=2 )
    {
        OUString target;
        OUString rel = OUString::createFromAscii( aSource1[i] );
        oslFileError e = osl_getAbsoluteFileURL( base4.pData, rel.pData , &target.pData );
        CPPUNIT_ASSERT_MESSAGE("failure #10",  osl_File_E_None == e );
        if( osl_File_E_None == e )
        {
            CPPUNIT_ASSERT_MESSAGE("failure #10.1",  target.equalsAscii( aSource1[i+1] ) );
        }
    }
#endif
}

} // namespace osl_test_file

// -----------------------------------------------------------------------------
CPPUNIT_TEST_SUITE_REGISTRATION( osl_test_file::oldtestfile);

// -----------------------------------------------------------------------------
CPPUNIT_PLUGIN_IMPLEMENT();

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>