<commit_before>/*
 * Copyright (c) 2010-2012 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Ali Saidi
 */

#include "base/intmath.hh"
#include "base/time.hh"
#include "base/trace.hh"
#include "debug/Checkpoint.hh"
#include "debug/Timer.hh"
#include "dev/arm/amba_device.hh"
#include "dev/arm/rtc_pl031.hh"
#include "dev/mc146818.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh"

using namespace AmbaDev;

PL031::PL031(Params *p)
    : AmbaIntDevice(p), timeVal(mkutctime(&p->time)), lastWrittenTick(0),
            loadVal(0), matchVal(0), rawInt(false), pendingInt(false),
            matchEvent(this)
{
    pioSize = 0xfff;
}

Tick
PL031::read(PacketPtr pkt)
{
    assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
    assert(pkt->getSize() == 4);
    Addr daddr = pkt->getAddr() - pioAddr;
    pkt->allocate();
    uint32_t data;

    DPRINTF(Timer, "Reading from RTC at offset: %#x\n", daddr);

    switch (daddr) {
      case DataReg:
        data = timeVal + ((curTick() - lastWrittenTick) / SimClock::Int::s);
        break;
      case MatchReg:
        data = matchVal;
        break;
      case LoadReg:
        data = loadVal;
        break;
      case ControlReg:
        data = 1; // Always enabled otherwise there is no point
        break;
      case IntMask:
        data = maskInt;
        break;
      case RawISR:
        data = rawInt;
        break;
      case MaskedISR:
        data = pendingInt;
        break;
      default:
        if (AmbaDev::readId(pkt, ambaId, pioAddr)) {
            // Hack for variable sized access
            data = pkt->get<uint32_t>();
            break;
        }
        panic("Tried to read PL031 at offset %#x that doesn't exist\n", daddr);
        break;
    }

    switch(pkt->getSize()) {
      case 1:
        pkt->set<uint8_t>(data);
        break;
      case 2:
        pkt->set<uint16_t>(data);
        break;
      case 4:
        pkt->set<uint32_t>(data);
        break;
      default:
        panic("Uart read size too big?\n");
        break;
    }

    pkt->makeAtomicResponse();
    return pioDelay;
}

Tick
PL031::write(PacketPtr pkt)
{
    assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
    assert(pkt->getSize() == 4);
    Addr daddr = pkt->getAddr() - pioAddr;
    pkt->allocate();
    DPRINTF(Timer, "Writing to RTC at offset: %#x\n", daddr);

    switch (daddr) {
      case DataReg:
        break;
      case MatchReg:
        matchVal = pkt->get<uint32_t>();
        resyncMatch();
        break;
      case LoadReg:
        lastWrittenTick = curTick();
        timeVal = pkt->get<uint32_t>();
        loadVal = timeVal;
        resyncMatch();
        break;
      case ControlReg:
        break; // Can't stop when started
      case IntMask:
        maskInt = pkt->get<uint32_t>();
        break;
      case IntClear:
        if (pkt->get<uint32_t>()) {
            rawInt = false;
            pendingInt = false;
        }
        break;
      default:
        if (AmbaDev::readId(pkt, ambaId, pioAddr))
            break;
        panic("Tried to read PL031 at offset %#x that doesn't exist\n", daddr);
        break;
    }

    pkt->makeAtomicResponse();
    return pioDelay;
}

void
PL031::resyncMatch()
{
    DPRINTF(Timer, "Setting up new match event match=%d time=%d\n", matchVal,
            timeVal);

    uint32_t seconds_until = matchVal - timeVal;
    Tick ticks_until = SimClock::Int::s * seconds_until;

    if (matchEvent.scheduled()) {
        DPRINTF(Timer, "-- Event was already schedule, de-scheduling\n");
        deschedule(matchEvent);
    }
    schedule(matchEvent, curTick() + ticks_until);
    DPRINTF(Timer, "-- Scheduling new event for: %d\n", curTick() + ticks_until);
}

void
PL031::counterMatch()
{
    DPRINTF(Timer, "Counter reached zero\n");

    rawInt = true;
    bool old_pending = pendingInt;
    pendingInt = maskInt & rawInt;
    if (pendingInt && ~old_pending) {
        DPRINTF(Timer, "-- Causing interrupt\n");
        gic->sendInt(intNum);
    }
}

void
PL031::serialize(std::ostream &os)
{
    DPRINTF(Checkpoint, "Serializing Arm PL031\n");
    SERIALIZE_SCALAR(timeVal);
    SERIALIZE_SCALAR(lastWrittenTick);
    SERIALIZE_SCALAR(loadVal);
    SERIALIZE_SCALAR(matchVal);
    SERIALIZE_SCALAR(rawInt);
    SERIALIZE_SCALAR(maskInt);
    SERIALIZE_SCALAR(pendingInt);

    bool is_in_event = matchEvent.scheduled();
    SERIALIZE_SCALAR(is_in_event);

    Tick event_time;
    if (is_in_event){
        event_time = matchEvent.when();
        SERIALIZE_SCALAR(event_time);
    }
}

void
PL031::unserialize(Checkpoint *cp, const std::string &section)
{
    DPRINTF(Checkpoint, "Unserializing Arm PL031\n");

    UNSERIALIZE_SCALAR(timeVal);
    UNSERIALIZE_SCALAR(lastWrittenTick);
    UNSERIALIZE_SCALAR(loadVal);
    UNSERIALIZE_SCALAR(matchVal);
    UNSERIALIZE_SCALAR(rawInt);
    UNSERIALIZE_SCALAR(maskInt);
    UNSERIALIZE_SCALAR(pendingInt);

    bool is_in_event;
    UNSERIALIZE_SCALAR(is_in_event);

    Tick event_time;
    if (is_in_event){
        UNSERIALIZE_SCALAR(event_time);
        schedule(matchEvent, event_time);
    }
}

PL031 *
PL031Params::create()
{
    return new PL031(this);
}
<commit_msg>ARM: Fix uninitialized value in ARM RTC model.<commit_after>/*
 * Copyright (c) 2010-2012 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Ali Saidi
 */

#include "base/intmath.hh"
#include "base/time.hh"
#include "base/trace.hh"
#include "debug/Checkpoint.hh"
#include "debug/Timer.hh"
#include "dev/arm/amba_device.hh"
#include "dev/arm/rtc_pl031.hh"
#include "dev/mc146818.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh"

using namespace AmbaDev;

PL031::PL031(Params *p)
    : AmbaIntDevice(p), timeVal(mkutctime(&p->time)), lastWrittenTick(0),
            loadVal(0), matchVal(0), rawInt(false), maskInt(false),
            pendingInt(false), matchEvent(this)
{
    pioSize = 0xfff;
}

Tick
PL031::read(PacketPtr pkt)
{
    assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
    assert(pkt->getSize() == 4);
    Addr daddr = pkt->getAddr() - pioAddr;
    pkt->allocate();
    uint32_t data;

    DPRINTF(Timer, "Reading from RTC at offset: %#x\n", daddr);

    switch (daddr) {
      case DataReg:
        data = timeVal + ((curTick() - lastWrittenTick) / SimClock::Int::s);
        break;
      case MatchReg:
        data = matchVal;
        break;
      case LoadReg:
        data = loadVal;
        break;
      case ControlReg:
        data = 1; // Always enabled otherwise there is no point
        break;
      case IntMask:
        data = maskInt;
        break;
      case RawISR:
        data = rawInt;
        break;
      case MaskedISR:
        data = pendingInt;
        break;
      default:
        if (AmbaDev::readId(pkt, ambaId, pioAddr)) {
            // Hack for variable sized access
            data = pkt->get<uint32_t>();
            break;
        }
        panic("Tried to read PL031 at offset %#x that doesn't exist\n", daddr);
        break;
    }

    switch(pkt->getSize()) {
      case 1:
        pkt->set<uint8_t>(data);
        break;
      case 2:
        pkt->set<uint16_t>(data);
        break;
      case 4:
        pkt->set<uint32_t>(data);
        break;
      default:
        panic("Uart read size too big?\n");
        break;
    }

    pkt->makeAtomicResponse();
    return pioDelay;
}

Tick
PL031::write(PacketPtr pkt)
{
    assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
    assert(pkt->getSize() == 4);
    Addr daddr = pkt->getAddr() - pioAddr;
    pkt->allocate();
    DPRINTF(Timer, "Writing to RTC at offset: %#x\n", daddr);

    switch (daddr) {
      case DataReg:
        break;
      case MatchReg:
        matchVal = pkt->get<uint32_t>();
        resyncMatch();
        break;
      case LoadReg:
        lastWrittenTick = curTick();
        timeVal = pkt->get<uint32_t>();
        loadVal = timeVal;
        resyncMatch();
        break;
      case ControlReg:
        break; // Can't stop when started
      case IntMask:
        maskInt = pkt->get<uint32_t>();
        break;
      case IntClear:
        if (pkt->get<uint32_t>()) {
            rawInt = false;
            pendingInt = false;
        }
        break;
      default:
        if (AmbaDev::readId(pkt, ambaId, pioAddr))
            break;
        panic("Tried to read PL031 at offset %#x that doesn't exist\n", daddr);
        break;
    }

    pkt->makeAtomicResponse();
    return pioDelay;
}

void
PL031::resyncMatch()
{
    DPRINTF(Timer, "Setting up new match event match=%d time=%d\n", matchVal,
            timeVal);

    uint32_t seconds_until = matchVal - timeVal;
    Tick ticks_until = SimClock::Int::s * seconds_until;

    if (matchEvent.scheduled()) {
        DPRINTF(Timer, "-- Event was already schedule, de-scheduling\n");
        deschedule(matchEvent);
    }
    schedule(matchEvent, curTick() + ticks_until);
    DPRINTF(Timer, "-- Scheduling new event for: %d\n", curTick() + ticks_until);
}

void
PL031::counterMatch()
{
    DPRINTF(Timer, "Counter reached zero\n");

    rawInt = true;
    bool old_pending = pendingInt;
    pendingInt = maskInt & rawInt;
    if (pendingInt && ~old_pending) {
        DPRINTF(Timer, "-- Causing interrupt\n");
        gic->sendInt(intNum);
    }
}

void
PL031::serialize(std::ostream &os)
{
    DPRINTF(Checkpoint, "Serializing Arm PL031\n");
    SERIALIZE_SCALAR(timeVal);
    SERIALIZE_SCALAR(lastWrittenTick);
    SERIALIZE_SCALAR(loadVal);
    SERIALIZE_SCALAR(matchVal);
    SERIALIZE_SCALAR(rawInt);
    SERIALIZE_SCALAR(maskInt);
    SERIALIZE_SCALAR(pendingInt);

    bool is_in_event = matchEvent.scheduled();
    SERIALIZE_SCALAR(is_in_event);

    Tick event_time;
    if (is_in_event){
        event_time = matchEvent.when();
        SERIALIZE_SCALAR(event_time);
    }
}

void
PL031::unserialize(Checkpoint *cp, const std::string &section)
{
    DPRINTF(Checkpoint, "Unserializing Arm PL031\n");

    UNSERIALIZE_SCALAR(timeVal);
    UNSERIALIZE_SCALAR(lastWrittenTick);
    UNSERIALIZE_SCALAR(loadVal);
    UNSERIALIZE_SCALAR(matchVal);
    UNSERIALIZE_SCALAR(rawInt);
    UNSERIALIZE_SCALAR(maskInt);
    UNSERIALIZE_SCALAR(pendingInt);

    bool is_in_event;
    UNSERIALIZE_SCALAR(is_in_event);

    Tick event_time;
    if (is_in_event){
        UNSERIALIZE_SCALAR(event_time);
        schedule(matchEvent, event_time);
    }
}

PL031 *
PL031Params::create()
{
    return new PL031(this);
}
<|endoftext|>


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

/** @file
 * This device acts as a disk similar to the memory mapped disk device
 * in legion. Any access is translated to an offset in the disk image.
 */

#include <cstring>

#include "base/trace.hh"
#include "debug/IdeDisk.hh"
#include "dev/sparc/mm_disk.hh"
#include "dev/platform.hh"
#include "mem/packet_access.hh"
#include "mem/port.hh"
#include "sim/byteswap.hh"
#include "sim/system.hh"

MmDisk::MmDisk(const Params *p)
    : BasicPioDevice(p), image(p->image), curSector((off_t)-1), dirty(false)
{
    std::memset(&diskData, 0, SectorSize);
    pioSize = image->size() * SectorSize;
}

Tick
MmDisk::read(PacketPtr pkt)
{
    Addr accessAddr;
    off_t sector;
    off_t bytes_read;
    uint16_t d16;
    uint32_t d32;
    uint64_t d64;

    assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
    accessAddr = pkt->getAddr() - pioAddr;

    sector = accessAddr / SectorSize;

    if (sector != curSector) {
        if (dirty) {
            bytes_read = image->write(diskData, curSector);
            assert(bytes_read == SectorSize);
        }
        bytes_read = image->read(diskData,  sector);
        assert(bytes_read == SectorSize);
        curSector = sector;
    }
    switch (pkt->getSize()) {
      case sizeof(uint8_t):
        pkt->set(diskData[accessAddr % SectorSize]);
        DPRINTF(IdeDisk, "reading byte %#x value= %#x\n", accessAddr, diskData[accessAddr %
                SectorSize]);
        break;
      case sizeof(uint16_t):
        memcpy(&d16, diskData + (accessAddr % SectorSize), 2);
        pkt->set(htobe(d32));
        DPRINTF(IdeDisk, "reading word %#x value= %#x\n", accessAddr, d16);
        break;
      case sizeof(uint32_t):
        memcpy(&d32, diskData + (accessAddr % SectorSize), 4);
        pkt->set(htobe(d32));
        DPRINTF(IdeDisk, "reading dword %#x value= %#x\n", accessAddr, d32);
        break;
      case sizeof(uint64_t):
        memcpy(&d64, diskData + (accessAddr % SectorSize), 8);
        pkt->set(htobe(d64));
        DPRINTF(IdeDisk, "reading qword %#x value= %#x\n", accessAddr, d64);
        break;
      default:
        panic("Invalid access size\n");
    }

    pkt->makeAtomicResponse();
    return pioDelay;
}

Tick
MmDisk::write(PacketPtr pkt)
{
    Addr accessAddr;
    off_t sector;
    off_t bytes_read;
    uint16_t d16;
    uint32_t d32;
    uint64_t d64;

    assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
    accessAddr = pkt->getAddr() - pioAddr;

    sector = accessAddr / SectorSize;

    if (sector != curSector) {
        if (dirty) {
            bytes_read = image->write(diskData, curSector);
            assert(bytes_read == SectorSize);
        }
        bytes_read = image->read(diskData,  sector);
        assert(bytes_read == SectorSize);
        curSector = sector;
    }
    dirty = true;

    switch (pkt->getSize()) {
      case sizeof(uint8_t):
        diskData[accessAddr % SectorSize] = htobe(pkt->get<uint8_t>());
        DPRINTF(IdeDisk, "writing byte %#x value= %#x\n", accessAddr, diskData[accessAddr %
                SectorSize]);
        break;
      case sizeof(uint16_t):
        d16 = htobe(pkt->get<uint16_t>());
        memcpy(diskData + (accessAddr % SectorSize), &d16, 2);
        DPRINTF(IdeDisk, "writing word %#x value= %#x\n", accessAddr, d16);
        break;
      case sizeof(uint32_t):
        d32 = htobe(pkt->get<uint32_t>());
        memcpy(diskData + (accessAddr % SectorSize), &d32, 4);
        DPRINTF(IdeDisk, "writing dword %#x value= %#x\n", accessAddr, d32);
        break;
      case sizeof(uint64_t):
        d64 = htobe(pkt->get<uint64_t>());
        memcpy(diskData + (accessAddr % SectorSize), &d64, 8);
        DPRINTF(IdeDisk, "writing qword %#x value= %#x\n", accessAddr, d64);
        break;
      default:
        panic("Invalid access size\n");
    }

    pkt->makeAtomicResponse();
    return pioDelay;
}

void
MmDisk::serialize(std::ostream &os)
{
    // just write any dirty changes to the cow layer it will take care of
    // serialization
    int bytes_read;
    if (dirty) {
        bytes_read = image->write(diskData, curSector);
        assert(bytes_read == SectorSize);
    }
}

MmDisk *
MmDiskParams::create()
{
    return new MmDisk(this);
}
<commit_msg>SPARC: Fixing a minor copy-paste bug using the wrong variable<commit_after>/*
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Ali Saidi
 */

/** @file
 * This device acts as a disk similar to the memory mapped disk device
 * in legion. Any access is translated to an offset in the disk image.
 */

#include <cstring>

#include "base/trace.hh"
#include "debug/IdeDisk.hh"
#include "dev/sparc/mm_disk.hh"
#include "dev/platform.hh"
#include "mem/packet_access.hh"
#include "mem/port.hh"
#include "sim/byteswap.hh"
#include "sim/system.hh"

MmDisk::MmDisk(const Params *p)
    : BasicPioDevice(p), image(p->image), curSector((off_t)-1), dirty(false)
{
    std::memset(&diskData, 0, SectorSize);
    pioSize = image->size() * SectorSize;
}

Tick
MmDisk::read(PacketPtr pkt)
{
    Addr accessAddr;
    off_t sector;
    off_t bytes_read;
    uint16_t d16;
    uint32_t d32;
    uint64_t d64;

    assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
    accessAddr = pkt->getAddr() - pioAddr;

    sector = accessAddr / SectorSize;

    if (sector != curSector) {
        if (dirty) {
            bytes_read = image->write(diskData, curSector);
            assert(bytes_read == SectorSize);
        }
        bytes_read = image->read(diskData,  sector);
        assert(bytes_read == SectorSize);
        curSector = sector;
    }
    switch (pkt->getSize()) {
      case sizeof(uint8_t):
        pkt->set(diskData[accessAddr % SectorSize]);
        DPRINTF(IdeDisk, "reading byte %#x value= %#x\n", accessAddr, diskData[accessAddr %
                SectorSize]);
        break;
      case sizeof(uint16_t):
        memcpy(&d16, diskData + (accessAddr % SectorSize), 2);
        pkt->set(htobe(d16));
        DPRINTF(IdeDisk, "reading word %#x value= %#x\n", accessAddr, d16);
        break;
      case sizeof(uint32_t):
        memcpy(&d32, diskData + (accessAddr % SectorSize), 4);
        pkt->set(htobe(d32));
        DPRINTF(IdeDisk, "reading dword %#x value= %#x\n", accessAddr, d32);
        break;
      case sizeof(uint64_t):
        memcpy(&d64, diskData + (accessAddr % SectorSize), 8);
        pkt->set(htobe(d64));
        DPRINTF(IdeDisk, "reading qword %#x value= %#x\n", accessAddr, d64);
        break;
      default:
        panic("Invalid access size\n");
    }

    pkt->makeAtomicResponse();
    return pioDelay;
}

Tick
MmDisk::write(PacketPtr pkt)
{
    Addr accessAddr;
    off_t sector;
    off_t bytes_read;
    uint16_t d16;
    uint32_t d32;
    uint64_t d64;

    assert(pkt->getAddr() >= pioAddr && pkt->getAddr() < pioAddr + pioSize);
    accessAddr = pkt->getAddr() - pioAddr;

    sector = accessAddr / SectorSize;

    if (sector != curSector) {
        if (dirty) {
            bytes_read = image->write(diskData, curSector);
            assert(bytes_read == SectorSize);
        }
        bytes_read = image->read(diskData,  sector);
        assert(bytes_read == SectorSize);
        curSector = sector;
    }
    dirty = true;

    switch (pkt->getSize()) {
      case sizeof(uint8_t):
        diskData[accessAddr % SectorSize] = htobe(pkt->get<uint8_t>());
        DPRINTF(IdeDisk, "writing byte %#x value= %#x\n", accessAddr, diskData[accessAddr %
                SectorSize]);
        break;
      case sizeof(uint16_t):
        d16 = htobe(pkt->get<uint16_t>());
        memcpy(diskData + (accessAddr % SectorSize), &d16, 2);
        DPRINTF(IdeDisk, "writing word %#x value= %#x\n", accessAddr, d16);
        break;
      case sizeof(uint32_t):
        d32 = htobe(pkt->get<uint32_t>());
        memcpy(diskData + (accessAddr % SectorSize), &d32, 4);
        DPRINTF(IdeDisk, "writing dword %#x value= %#x\n", accessAddr, d32);
        break;
      case sizeof(uint64_t):
        d64 = htobe(pkt->get<uint64_t>());
        memcpy(diskData + (accessAddr % SectorSize), &d64, 8);
        DPRINTF(IdeDisk, "writing qword %#x value= %#x\n", accessAddr, d64);
        break;
      default:
        panic("Invalid access size\n");
    }

    pkt->makeAtomicResponse();
    return pioDelay;
}

void
MmDisk::serialize(std::ostream &os)
{
    // just write any dirty changes to the cow layer it will take care of
    // serialization
    int bytes_read;
    if (dirty) {
        bytes_read = image->write(diskData, curSector);
        assert(bytes_read == SectorSize);
    }
}

MmDisk *
MmDiskParams::create()
{
    return new MmDisk(this);
}
<|endoftext|>


<commit_before><commit_msg>sigh...<commit_after><|endoftext|>


<commit_before><commit_msg>[SfM/export] adapt cubic images to the size of spherical images (#1895)<commit_after><|endoftext|>


<commit_before><commit_msg>backup<commit_after><|endoftext|>


<commit_before>#include "test.hpp"
#include "setup_transfer.hpp"
#include "libtorrent/socket.hpp"
#include "libtorrent/io.hpp"
#include <cstring>
#include <asio/read.hpp>
#include <asio/write.hpp>
#include <boost/bind.hpp>

using namespace libtorrent;

int read_message(stream_socket& s, char* buffer)
{
	using namespace libtorrent::detail;
	asio::error_code ec;
	asio::read(s, asio::buffer(buffer, 4), asio::transfer_all(), ec);
	TEST_CHECK(!ec);
	char* ptr = buffer;
	int length = read_int32(ptr);

	asio::read(s, asio::buffer(buffer, length), asio::transfer_all(), ec);
	TEST_CHECK(!ec);
	return length;
}

char const* message_name[] = {"choke", "unchoke", "interested", "not_interested"
	, "have", "bitfield", "request", "piece", "cancel", "dht_port", "", "", ""
	, "suggest_piece", "have_all", "have_none", "reject_request", "allowed_fast"};

void send_allow_fast(stream_socket& s, int piece)
{
	using namespace libtorrent::detail;
	char msg[] = "\0\0\0\x05\x11\0\0\0\0";
	char* ptr = msg + 5;
	write_int32(piece, ptr);
	asio::error_code ec;
	asio::write(s, asio::buffer(msg, 9), asio::transfer_all(), ec);
	TEST_CHECK(!ec);
}

void send_suggest_piece(stream_socket& s, int piece)
{
	using namespace libtorrent::detail;
	char msg[] = "\0\0\0\x05\x0d\0\0\0\0";
	char* ptr = msg + 5;
	write_int32(piece, ptr);
	asio::error_code ec;
	asio::write(s, asio::buffer(msg, 9), asio::transfer_all(), ec);
	TEST_CHECK(!ec);
}

void send_unchoke(stream_socket& s)
{
	char msg[] = "\0\0\0\x01\x01";
	asio::error_code ec;
	asio::write(s, asio::buffer(msg, 5), asio::transfer_all(), ec);
	TEST_CHECK(!ec);
}

void do_handshake(stream_socket& s, sha1_hash const& ih, char* buffer)
{
	char handshake[] = "\x13" "BitTorrent protocol\0\0\0\0\0\0\0\x04"
		"                    " // space for info-hash
		"aaaaaaaaaaaaaaaaaaaa" // peer-id
		"\0\0\0\x01\x0e"; // have_all
	asio::error_code ec;
	std::memcpy(handshake + 28, ih.begin(), 20);
	asio::write(s, asio::buffer(handshake, sizeof(handshake) - 1), asio::transfer_all(), ec);
	TEST_CHECK(!ec);

	// read handshake
	asio::read(s, asio::buffer(buffer, 68), asio::transfer_all(), ec);
	TEST_CHECK(!ec);

	TEST_CHECK(buffer[0] == 19);
	TEST_CHECK(std::memcmp(buffer + 1, "BitTorrent protocol", 19) == 0);

	char* extensions = buffer + 20;
	// check for fast extension support
	TEST_CHECK(extensions[7] & 0x4);

#ifndef TORRENT_DISABLE_EXTENSIONS
	// check for extension protocol support
	TEST_CHECK(extensions[5] & 0x10);
#endif

#ifndef TORRENT_DISABLE_DHT
	// check for DHT support
	TEST_CHECK(extensions[7] & 0x1);
#endif

	TEST_CHECK(std::memcmp(buffer + 28, ih.begin(), 20) == 0);
}

// makes sure that pieces that are allowed and then
// rejected aren't requested again
void test_reject_fast()
{
	boost::intrusive_ptr<torrent_info> t = create_torrent();
	sha1_hash ih = t->info_hash();
	session ses1(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48900, 49000));
	ses1.add_torrent(t, "./tmp1");

	test_sleep(2000);

	io_service ios;
	stream_socket s(ios);
	s.connect(tcp::endpoint(address::from_string("127.0.0.1"), ses1.listen_port()));

	char recv_buffer[1000];
	do_handshake(s, ih, recv_buffer);

	std::vector<int> allowed_fast;
	allowed_fast.push_back(0);
	allowed_fast.push_back(1);
	allowed_fast.push_back(2);
	allowed_fast.push_back(3);

	std::for_each(allowed_fast.begin(), allowed_fast.end()
		, bind(&send_allow_fast, boost::ref(s), _1));

	while (!allowed_fast.empty())
	{
		read_message(s, recv_buffer);
		int msg = recv_buffer[0];
		if (msg >= 0 && msg < int(sizeof(message_name)/sizeof(message_name[0])))
			std::cerr << message_name[msg] << std::endl;
		else
			std::cerr << msg << std::endl;
		if (recv_buffer[0] != 0x6) continue;

		using namespace libtorrent::detail;
		char* ptr = recv_buffer + 1;
		int piece = read_int32(ptr);

		std::vector<int>::iterator i = std::find(allowed_fast.begin()
			, allowed_fast.end(), piece);
		TEST_CHECK(i != allowed_fast.end());
		if (i != allowed_fast.end())
			allowed_fast.erase(i);
		// send reject request
		recv_buffer[0] = 0x10;
		asio::error_code ec;
		asio::write(s, asio::buffer("\0\0\0\x0d", 4), asio::transfer_all(), ec);
		TEST_CHECK(!ec);
		asio::write(s, asio::buffer(recv_buffer, 13), asio::transfer_all(), ec);
		TEST_CHECK(!ec);
	}
}

void test_respect_suggest()
{
	boost::intrusive_ptr<torrent_info> t = create_torrent();
	sha1_hash ih = t->info_hash();
	session ses1(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48900, 49000));
	ses1.add_torrent(t, "./tmp1");

	test_sleep(2000);

	io_service ios;
	stream_socket s(ios);
	s.connect(tcp::endpoint(address::from_string("127.0.0.1"), ses1.listen_port()));

	char recv_buffer[1000];
	do_handshake(s, ih, recv_buffer);

	std::vector<int> suggested;
	suggested.push_back(0);
	suggested.push_back(1);
	suggested.push_back(2);
	suggested.push_back(3);

	std::for_each(suggested.begin(), suggested.end()
		, bind(&send_suggest_piece, boost::ref(s), _1));

	send_unchoke(s);

	int fail_counter = 100;
	while (!suggested.empty() && fail_counter > 0)
	{
		read_message(s, recv_buffer);
		std::cerr << "msg: ";
		int msg = recv_buffer[0];
		if (msg >= 0 && msg < int(sizeof(message_name)/sizeof(message_name[0])))
			std::cerr << message_name[msg] << std::endl;
		else
			std::cerr << msg << std::endl;
		fail_counter--;
		if (recv_buffer[0] != 0x6) continue;

		using namespace libtorrent::detail;
		char* ptr = recv_buffer + 1;
		int piece = read_int32(ptr);

		std::vector<int>::iterator i = std::find(suggested.begin()
			, suggested.end(), piece);
		TEST_CHECK(i != suggested.end());
		if (i != suggested.end())
			suggested.erase(i);
		// send reject request
		recv_buffer[0] = 0x10;
		asio::error_code ec;
		asio::write(s, asio::buffer("\0\0\0\x0d", 4), asio::transfer_all(), ec);
		TEST_CHECK(!ec);
		asio::write(s, asio::buffer(recv_buffer, 13), asio::transfer_all(), ec);
		TEST_CHECK(!ec);
	}
	TEST_CHECK(fail_counter > 0);
}

int test_main()
{
	test_reject_fast();
	test_respect_suggest();
	return 0;
}

<commit_msg>more verbose logging in test_fast_extension and avoids infinite loops in case of failures<commit_after>#include "test.hpp"
#include "setup_transfer.hpp"
#include "libtorrent/socket.hpp"
#include "libtorrent/io.hpp"
#include <cstring>
#include <asio/read.hpp>
#include <asio/write.hpp>
#include <boost/bind.hpp>

using namespace libtorrent;

int read_message(stream_socket& s, char* buffer)
{
	using namespace libtorrent::detail;
	asio::error_code ec;
	asio::read(s, asio::buffer(buffer, 4), asio::transfer_all(), ec);
	if (ec)
	{
		std::cout << ec.message() << std::endl;
		exit(1);
	}
	char* ptr = buffer;
	int length = read_int32(ptr);

	asio::read(s, asio::buffer(buffer, length), asio::transfer_all(), ec);
	if (ec)
	{
		std::cout << ec.message() << std::endl;
		exit(1);
	}
	return length;
}

char const* message_name[] = {"choke", "unchoke", "interested", "not_interested"
	, "have", "bitfield", "request", "piece", "cancel", "dht_port", "", "", ""
	, "suggest_piece", "have_all", "have_none", "reject_request", "allowed_fast"};

void send_allow_fast(stream_socket& s, int piece)
{
	std::cout << "send allow fast: " << piece << std::endl;
	using namespace libtorrent::detail;
	char msg[] = "\0\0\0\x05\x11\0\0\0\0";
	char* ptr = msg + 5;
	write_int32(piece, ptr);
	asio::error_code ec;
	asio::write(s, asio::buffer(msg, 9), asio::transfer_all(), ec);
	if (ec)
	{
		std::cout << ec.message() << std::endl;
		exit(1);
	}
}

void send_suggest_piece(stream_socket& s, int piece)
{
	std::cout << "send suggest piece: " << piece << std::endl;
	using namespace libtorrent::detail;
	char msg[] = "\0\0\0\x05\x0d\0\0\0\0";
	char* ptr = msg + 5;
	write_int32(piece, ptr);
	asio::error_code ec;
	asio::write(s, asio::buffer(msg, 9), asio::transfer_all(), ec);
	if (ec)
	{
		std::cout << ec.message() << std::endl;
		exit(1);
	}
}

void send_unchoke(stream_socket& s)
{
	std::cout << "send unchoke" << std::endl;
	char msg[] = "\0\0\0\x01\x01";
	asio::error_code ec;
	asio::write(s, asio::buffer(msg, 5), asio::transfer_all(), ec);
	if (ec)
	{
		std::cout << ec.message() << std::endl;
		exit(1);
	}
}

void do_handshake(stream_socket& s, sha1_hash const& ih, char* buffer)
{
	char handshake[] = "\x13" "BitTorrent protocol\0\0\0\0\0\0\0\x04"
		"                    " // space for info-hash
		"aaaaaaaaaaaaaaaaaaaa" // peer-id
		"\0\0\0\x01\x0e"; // have_all
	std::cout << "send handshake" << std::endl;
	asio::error_code ec;
	std::memcpy(handshake + 28, ih.begin(), 20);
	asio::write(s, asio::buffer(handshake, sizeof(handshake) - 1), asio::transfer_all(), ec);
	if (ec)
	{
		std::cout << ec.message() << std::endl;
		exit(1);
	}

	// read handshake
	asio::read(s, asio::buffer(buffer, 68), asio::transfer_all(), ec);
	if (ec)
	{
		std::cout << ec.message() << std::endl;
		exit(1);
	}
	std::cout << "received handshake" << std::endl;

	TEST_CHECK(buffer[0] == 19);
	TEST_CHECK(std::memcmp(buffer + 1, "BitTorrent protocol", 19) == 0);

	char* extensions = buffer + 20;
	// check for fast extension support
	TEST_CHECK(extensions[7] & 0x4);

#ifndef TORRENT_DISABLE_EXTENSIONS
	// check for extension protocol support
	TEST_CHECK(extensions[5] & 0x10);
#endif

#ifndef TORRENT_DISABLE_DHT
	// check for DHT support
	TEST_CHECK(extensions[7] & 0x1);
#endif

	TEST_CHECK(std::memcmp(buffer + 28, ih.begin(), 20) == 0);
}

// makes sure that pieces that are allowed and then
// rejected aren't requested again
void test_reject_fast()
{
	boost::intrusive_ptr<torrent_info> t = create_torrent();
	sha1_hash ih = t->info_hash();
	session ses1(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48900, 49000));
	ses1.add_torrent(t, "./tmp1");

	test_sleep(1000000);

	io_service ios;
	stream_socket s(ios);
	s.connect(tcp::endpoint(address::from_string("127.0.0.1"), ses1.listen_port()));

	char recv_buffer[1000];
	do_handshake(s, ih, recv_buffer);

	std::vector<int> allowed_fast;
	allowed_fast.push_back(0);
	allowed_fast.push_back(1);
	allowed_fast.push_back(2);
	allowed_fast.push_back(3);

	std::for_each(allowed_fast.begin(), allowed_fast.end()
		, bind(&send_allow_fast, boost::ref(s), _1));

	while (!allowed_fast.empty())
	{
		read_message(s, recv_buffer);
		int msg = recv_buffer[0];
		if (msg >= 0 && msg < int(sizeof(message_name)/sizeof(message_name[0])))
			std::cerr << message_name[msg] << std::endl;
		else
			std::cerr << msg << std::endl;
		if (recv_buffer[0] != 0x6) continue;

		using namespace libtorrent::detail;
		char* ptr = recv_buffer + 1;
		int piece = read_int32(ptr);

		std::vector<int>::iterator i = std::find(allowed_fast.begin()
			, allowed_fast.end(), piece);
		TEST_CHECK(i != allowed_fast.end());
		if (i != allowed_fast.end())
			allowed_fast.erase(i);
		// send reject request
		recv_buffer[0] = 0x10;
		asio::error_code ec;
		asio::write(s, asio::buffer("\0\0\0\x0d", 4), asio::transfer_all(), ec);
		if (ec)
		{
			std::cout << ec.message() << std::endl;
			exit(1);
		}
		asio::write(s, asio::buffer(recv_buffer, 13), asio::transfer_all(), ec);
		std::cout << ec.message() << std::endl;
		if (ec)
		{
			std::cout << ec.message() << std::endl;
			exit(1);
		}
	}
}

void test_respect_suggest()
{
	boost::intrusive_ptr<torrent_info> t = create_torrent();
	sha1_hash ih = t->info_hash();
	session ses1(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48900, 49000));
	ses1.add_torrent(t, "./tmp1");

	test_sleep(2000);

	io_service ios;
	stream_socket s(ios);
	s.connect(tcp::endpoint(address::from_string("127.0.0.1"), ses1.listen_port()));

	char recv_buffer[1000];
	do_handshake(s, ih, recv_buffer);

	std::vector<int> suggested;
	suggested.push_back(0);
	suggested.push_back(1);
	suggested.push_back(2);
	suggested.push_back(3);

	std::for_each(suggested.begin(), suggested.end()
		, bind(&send_suggest_piece, boost::ref(s), _1));

	send_unchoke(s);

	int fail_counter = 100;
	while (!suggested.empty() && fail_counter > 0)
	{
		read_message(s, recv_buffer);
		std::cerr << "msg: ";
		int msg = recv_buffer[0];
		if (msg >= 0 && msg < int(sizeof(message_name)/sizeof(message_name[0])))
			std::cerr << message_name[msg] << std::endl;
		else
			std::cerr << msg << std::endl;
		fail_counter--;
		if (recv_buffer[0] != 0x6) continue;

		using namespace libtorrent::detail;
		char* ptr = recv_buffer + 1;
		int piece = read_int32(ptr);

		std::vector<int>::iterator i = std::find(suggested.begin()
			, suggested.end(), piece);
		TEST_CHECK(i != suggested.end());
		if (i != suggested.end())
			suggested.erase(i);
		// send reject request
		recv_buffer[0] = 0x10;
		asio::error_code ec;
		asio::write(s, asio::buffer("\0\0\0\x0d", 4), asio::transfer_all(), ec);
		if (ec)
		{
			std::cout << ec.message() << std::endl;
			exit(1);
		}
		asio::write(s, asio::buffer(recv_buffer, 13), asio::transfer_all(), ec);
		if (ec)
		{
			std::cout << ec.message() << std::endl;
			exit(1);
		}
	}
	TEST_CHECK(fail_counter > 0);
}

int test_main()
{
	test_reject_fast();
	test_respect_suggest();
	return 0;
}

<|endoftext|>


<commit_before>#include "mongo/db/json.h"
#include "mongo/client/dbclient.h"
#include "mongo/client/dbclientcursor.h"

#include "parseArgs.h"
#include "logMsg.h"

/* ****************************************************************************
*
* global vars -
*/
mongo::DBClientConnection*  mdbConnection;
std::string                 dbAndColl;

/* ****************************************************************************
*
* Option variables
*/
bool  location;
bool  mobility;
bool  upload;
char  server[256];
char  db[256];
char  collection[256];
int   kvs;
int   secs;
bool  bulk;
int   bulksize;
bool  indexed;
bool  ipt;
bool  burst;
int   qps;
int   maxUserId;
int   minUserId;
int   userId;
int   days;

#define M512 (512 * 1024 * 1024)
/* ****************************************************************************
*
* parse arguments
*/
PaArgument paArgs[] =
{
	{ "-location", &location,   "LOCATION",    PaBool,    PaOpt,  false,                    false, true,  "user location query"        },
	{ "-mobility", &mobility,   "MOBILITY",    PaBool,    PaOpt,  false,                    false, true,  "user mobility query"        },
	{ "-upload",   &upload,     "UPLOAD",      PaBool,    PaOpt,  false,                    false, true,  "upload data to mongodb"     },
	{ "-server",   server,      "SERVER",      PaString,  PaOpt,  (long) "localhost:27017", PaNL,  PaNL,  "data base server:port"      },
	{ "-db",       db,          "DB_PATH",     PaString,  PaReq,  PaND,                     PaNL,  PaNL,  "name of data base"          },
	{ "-coll",     collection,  "COLLECTION",  PaString,  PaReq,  PaND,                     PaNL,  PaNL,  "name of collection"         },
	{ "-kvs",      &kvs,        "KEYVALUES",   PaInt,     PaOpt,  40000,                    1,     M512,  "no of keyvalues per second" },
	{ "-secs",     &secs,       "SECS",        PaInt,     PaOpt,  1,                        1,     PaNL,  "seconds"                    },
	{ "-bulk",     &bulk,       "BULK",        PaBool,    PaOpt,  false,                    false, true,  "bulk load"                  },
	{ "-bulksize", &bulksize,   "BULKSIZE",    PaInt,     PaOpt,  30000,                    PaNL,  PaNL,  "bulk size"                  },
	{ "-indexed",  &indexed,    "INDEXED",     PaBool,    PaOpt,  false,                    false, true,  "create index"               },
	{ "-ipt",      &ipt,        "UK_DATA",     PaBool,    PaOpt,  false,                    false, true,  "UK Pilot-like data"         },
	{ "-burst",    &burst,      "BURST",       PaBool,    PaOpt,  false,                    false, true,  "burst data send"            },
	{ "-qps",      &qps,        "QPS",         PaInt,     PaOpt,  10000,                    1,     M512,  "no of queries per second"   },
	{ "-maxuid",   &maxUserId,  "MAXUSERID",   PaInt,     PaOpt,  0,                        0,     M512,  "max user id"                },
	{ "-minuid",   &minUserId,  "MINUSERID",   PaInt,     PaOpt,  0,                        0,     M512,  "min user id"                },
	{ "-uid",      &userId,     "USERID",      PaInt,     PaOpt,  -1,                      -1,     M512,  "user id"                    },
	{ "-days",     &days,       "DAYS",        PaInt,     PaOpt,  0,                        0,     M512,  "days"                       },

	PA_END_OF_ARGS
};

/* ****************************************************************************
*
* timediff -
*/
void timediff(struct timeval* start, struct timeval* stop, struct timeval* diff)
{
	diff->tv_sec  = stop->tv_sec  - start->tv_sec;
	diff->tv_usec = stop->tv_usec - start->tv_usec;

	if (diff->tv_usec < 0)
	{
		diff->tv_usec += 1000000;
		diff->tv_sec  -= 1;
	}
}

/* ****************************************************************************
*
* uploadData -
*/
void uploadData(void)
{
	if (bulk)
		LM_M(("Bulk-mode-inserting %d kvs/second to server %s during %d seconds in DB %s, collection %s", kvs, server, secs, db, collection));
	else
		LM_M(("Slow-inserting %d kvs/second to server %s during %d seconds in DB %s, collection %s", kvs, server, secs, db, collection));

	while (secs-- > 0)
	{
		mongo::BSONObj      bo;
		long long           key     = 1;
		long long           value   = 1;
		struct timeval      start;
		struct timeval      stop;
		struct timeval      diff;
		long long int       key2        = 0;
		long long int       position    = 1234560;
		long long int       timestamp   = (long long int) time(NULL);

		gettimeofday(&start, NULL);

		if (bulk)
		{
			std::vector<mongo::BSONObj>  bulk_data;
			int                          inserts = 0;

			for (int ix = 0; ix < kvs; ix++)
			{
				mongo::BSONObj  record;

				if (ipt)
				{
					LM_M(("I:%d, P:%d, T:%d", key2, position, timestamp));
					record =  BSON("I" << key2 << "P" << position << "T" << timestamp);
					++key2;
					++position;
					++timestamp;
				}
				else
				{
					record = BSON("K" << key << "V" << value);
					++value;
					++key;
				}

				bulk_data.push_back(record);

				++inserts;
				if ((inserts % bulksize) == 0)
				{
					LM_V(("Bulk-inserting ..."));
					mdbConnection->insert(dbAndColl, bulk_data);
					LM_V(("... Bulk-insert finished"));
					bulk_data.clear();
					inserts = 0;
				}
			}

			if (inserts != 0)
			{
				mdbConnection->insert(dbAndColl, bulk_data);
				bulk_data.clear();
			}
		}
		else
		{
			for (int ix = 0; ix < kvs; ix++)
			{
				if (ipt)
				{
					bo =  BSON("I" << key2 << "P" << position << "T" << timestamp);
					++key2;
					++position;
					++timestamp;
				}
				else
				{
					bo = BSON("K" << key << "V" << value);
					value += 1;
					key   += 1;
				}

				mdbConnection->insert(dbAndColl, bo);
			}
		}

		if (burst == false)
		{
			gettimeofday(&stop, NULL);

			timediff(&start, &stop, &diff);

			if (diff.tv_sec != 0)
				LM_X(1, ("Sorry, this operation takes too long (%d.%06d seconds)."
						 "Please lower the number of keyvalues per 'burst' (using option '-kvs')",
						 diff.tv_sec, diff.tv_usec));
			LM_M(("sleeping 0.%06d seconds", 1000000 - diff.tv_usec));
			usleep(1000000 - diff.tv_usec);
		}
	}

	if (indexed)
	{
		if (ipt)
			mdbConnection->ensureIndex(dbAndColl, mongo::fromjson("{I:1}"));
		else
			mdbConnection->ensureIndex(dbAndColl, mongo::fromjson("{K:1}"));
	}
}

/* ****************************************************************************
*
* locationQuery -
*/
void locationQuery(void)
{
	int                 times  = 0;
	long long int       userId = minUserId;
	struct timeval      start;
	struct timeval      stop;
	struct timeval      diff;

	gettimeofday(&start, NULL);

	while (secs-- > 0)
	{
		for (int ix = 0; ix < qps; ix++)
		{
			std::auto_ptr<mongo::DBClientCursor> cursor = mdbConnection->query(dbAndColl, QUERY("I" << userId));
			++times;
			++userId;
			if (userId > maxUserId)
				userId = minUserId;

			if (cursor->more() == false)
				LM_X(1, ("No user with id %u found", userId));
			else
			{
				int hits = 0;

				while (cursor->more() != false)
				{
					cursor->next();
					++hits;
				}

				LM_V(("Found %d hits for user %d (%d times)", hits, userId, times));
			}
		}

		if (burst == false)
		{
			gettimeofday(&stop, NULL);

			timediff(&start, &stop, &diff);

			if (diff.tv_sec != 0)
				LM_X(1, ("Sorry, this operation takes too long (%d.%06d seconds)."
						 "Please lower the number of keyvalues per 'burst' (using option '-kvs')",
						 diff.tv_sec, diff.tv_usec));
			LM_M(("sleeping 0.%06d seconds", 1000000 - diff.tv_usec));
			usleep(1000000 - diff.tv_usec);
		}
	}
}

/* ****************************************************************************
*
* mobilityQuery -
*/
void mobilityQuery(void)
{
	struct timeval   start;
	struct timeval   stop;
	struct timeval   diff;
	time_t           now = time(NULL);

	if (userId == -1)
		LM_X(1, ("please indicate a user identifier, using the '-uid' option"));

	if (days == 0)
		LM_X(1, ("please indicate number of days, using the '-days' option"));

	while (secs-- > 0)
	{
		int times;

		gettimeofday(&start, NULL);

		times = 0;
		for (int ix = 0; ix < qps; ix++)
		{
			std::auto_ptr<mongo::DBClientCursor> cursor = mdbConnection->query(dbAndColl, QUERY("I" << (long long int) userId));

			if (cursor->more() == false)
				LM_X(1, ("No user with id %u found", userId));
			else
			{
				int hits = 0;

				while (cursor->more() != false)
				{
					mongo::BSONObj bo;

					int ts;

					bo = cursor->next();

					ts = bo.getIntField("T");
					if (ts + days * 3600 * 24 < now)
						continue;
					++hits;
				}

				++times;
				LM_V(("Found %d hits for user %d the last %d days (%d times)", hits, userId, days, times));
			}
		}

		if (burst == false)
		{
			gettimeofday(&stop, NULL);

			timediff(&start, &stop, &diff);

			if (diff.tv_sec != 0)
				LM_X(1, ("Sorry, this operation takes too long (%d.%06d seconds)."
						 "Please lower the number of keyvalues per 'burst' (using option '-kvs')",
						 diff.tv_sec, diff.tv_usec));
			LM_M(("sleeping 0.%06d seconds", 1000000 - diff.tv_usec));
			usleep(1000000 - diff.tv_usec);
		}
	}
}

/* ****************************************************************************
*
* main -
*/
int main(int argC, char* argV[])
{
	paConfig("prefix",                        (void*) "MONGO");
	paConfig("usage and exit on any warning", (void*) true);
    paConfig("log to screen",                 (void*) "only errors");
    paConfig("log file line format",          (void*) "TYPE:DATE:EXEC/FILE[LINE] FUNC: TEXT");
    paConfig("screen line format",            (void*) "TYPE@TIME  EXEC: TEXT");
    paConfig("log to file",                   (void*) true);

	paParse(paArgs, argC, (char**) argV, 1, false);

	if (!location && !mobility && !upload)
	{
		printf("Please pick one if the operating modes: '-location', '-mobility', or '-upload'\n");
		exit(1);
	}

	mdbConnection = new mongo::DBClientConnection();
	LM_M(("Connecting to mongo at '%s'", server));
	mdbConnection->connect(server);

	dbAndColl = (std::string) db + "." + (std::string) collection;

	if (location)
		locationQuery();
	else if (mobility)
		mobilityQuery();
	else if (upload)
		uploadData();

	return 0;
}
<commit_msg>adedd an empty line<commit_after>#include "mongo/db/json.h"
#include "mongo/client/dbclient.h"
#include "mongo/client/dbclientcursor.h"

#include "parseArgs.h"
#include "logMsg.h"

/* ****************************************************************************
*
* global vars -
*/
mongo::DBClientConnection*  mdbConnection;
std::string                 dbAndColl;

/* ****************************************************************************
*
* Option variables
*/
bool  location;
bool  mobility;
bool  upload;
char  server[256];
char  db[256];
char  collection[256];
int   kvs;
int   secs;
bool  bulk;
int   bulksize;
bool  indexed;
bool  ipt;
bool  burst;
int   qps;
int   maxUserId;
int   minUserId;
int   userId;
int   days;

#define M512 (512 * 1024 * 1024)
/* ****************************************************************************
*
* parse arguments
*/
PaArgument paArgs[] =
{
	{ "-location", &location,   "LOCATION",    PaBool,    PaOpt,  false,                    false, true,  "user location query"        },
	{ "-mobility", &mobility,   "MOBILITY",    PaBool,    PaOpt,  false,                    false, true,  "user mobility query"        },
	{ "-upload",   &upload,     "UPLOAD",      PaBool,    PaOpt,  false,                    false, true,  "upload data to mongodb"     },
	{ "-server",   server,      "SERVER",      PaString,  PaOpt,  (long) "localhost:27017", PaNL,  PaNL,  "data base server:port"      },
	{ "-db",       db,          "DB_PATH",     PaString,  PaReq,  PaND,                     PaNL,  PaNL,  "name of data base"          },
	{ "-coll",     collection,  "COLLECTION",  PaString,  PaReq,  PaND,                     PaNL,  PaNL,  "name of collection"         },
	{ "-kvs",      &kvs,        "KEYVALUES",   PaInt,     PaOpt,  40000,                    1,     M512,  "no of keyvalues per second" },
	{ "-secs",     &secs,       "SECS",        PaInt,     PaOpt,  1,                        1,     PaNL,  "seconds"                    },
	{ "-bulk",     &bulk,       "BULK",        PaBool,    PaOpt,  false,                    false, true,  "bulk load"                  },
	{ "-bulksize", &bulksize,   "BULKSIZE",    PaInt,     PaOpt,  30000,                    PaNL,  PaNL,  "bulk size"                  },
	{ "-indexed",  &indexed,    "INDEXED",     PaBool,    PaOpt,  false,                    false, true,  "create index"               },
	{ "-ipt",      &ipt,        "UK_DATA",     PaBool,    PaOpt,  false,                    false, true,  "UK Pilot-like data"         },
	{ "-burst",    &burst,      "BURST",       PaBool,    PaOpt,  false,                    false, true,  "burst data send"            },
	{ "-qps",      &qps,        "QPS",         PaInt,     PaOpt,  10000,                    1,     M512,  "no of queries per second"   },
	{ "-maxuid",   &maxUserId,  "MAXUSERID",   PaInt,     PaOpt,  0,                        0,     M512,  "max user id"                },
	{ "-minuid",   &minUserId,  "MINUSERID",   PaInt,     PaOpt,  0,                        0,     M512,  "min user id"                },
	{ "-uid",      &userId,     "USERID",      PaInt,     PaOpt,  -1,                      -1,     M512,  "user id"                    },
	{ "-days",     &days,       "DAYS",        PaInt,     PaOpt,  0,                        0,     M512,  "days"                       },

	PA_END_OF_ARGS
};

/* ****************************************************************************
*
* timediff -
*/
void timediff(struct timeval* start, struct timeval* stop, struct timeval* diff)
{
	diff->tv_sec  = stop->tv_sec  - start->tv_sec;
	diff->tv_usec = stop->tv_usec - start->tv_usec;

	if (diff->tv_usec < 0)
	{
		diff->tv_usec += 1000000;
		diff->tv_sec  -= 1;
	}
}

/* ****************************************************************************
*
* uploadData -
*/
void uploadData(void)
{
	if (bulk)
		LM_M(("Bulk-mode-inserting %d kvs/second to server %s during %d seconds in DB %s, collection %s", kvs, server, secs, db, collection));
	else
		LM_M(("Slow-inserting %d kvs/second to server %s during %d seconds in DB %s, collection %s", kvs, server, secs, db, collection));

	while (secs-- > 0)
	{
		mongo::BSONObj      bo;
		long long           key     = 1;
		long long           value   = 1;
		struct timeval      start;
		struct timeval      stop;
		struct timeval      diff;
		long long int       key2        = 0;
		long long int       position    = 1234560;
		long long int       timestamp   = (long long int) time(NULL);

		gettimeofday(&start, NULL);

		if (bulk)
		{
			std::vector<mongo::BSONObj>  bulk_data;
			int                          inserts = 0;

			for (int ix = 0; ix < kvs; ix++)
			{
				mongo::BSONObj  record;

				if (ipt)
				{
					LM_M(("I:%d, P:%d, T:%d", key2, position, timestamp));
					record =  BSON("I" << key2 << "P" << position << "T" << timestamp);
					++key2;
					++position;
					++timestamp;
				}
				else
				{
					record = BSON("K" << key << "V" << value);
					++value;
					++key;
				}

				bulk_data.push_back(record);

				++inserts;
				if ((inserts % bulksize) == 0)
				{
					LM_V(("Bulk-inserting ..."));
					mdbConnection->insert(dbAndColl, bulk_data);
					LM_V(("... Bulk-insert finished"));
					bulk_data.clear();
					inserts = 0;
				}
			}

			if (inserts != 0)
			{
				mdbConnection->insert(dbAndColl, bulk_data);
				bulk_data.clear();
			}
		}
		else
		{
			for (int ix = 0; ix < kvs; ix++)
			{
				if (ipt)
				{
					bo =  BSON("I" << key2 << "P" << position << "T" << timestamp);
					++key2;
					++position;
					++timestamp;
				}
				else
				{
					bo = BSON("K" << key << "V" << value);
					value += 1;
					key   += 1;
				}

				mdbConnection->insert(dbAndColl, bo);
			}
		}

		if (burst == false)
		{
			gettimeofday(&stop, NULL);

			timediff(&start, &stop, &diff);

			if (diff.tv_sec != 0)
				LM_X(1, ("Sorry, this operation takes too long (%d.%06d seconds)."
						 "Please lower the number of keyvalues per 'burst' (using option '-kvs')",
						 diff.tv_sec, diff.tv_usec));
			LM_M(("sleeping 0.%06d seconds", 1000000 - diff.tv_usec));
			usleep(1000000 - diff.tv_usec);
		}
	}

	if (indexed)
	{
		if (ipt)
			mdbConnection->ensureIndex(dbAndColl, mongo::fromjson("{I:1}"));
		else
			mdbConnection->ensureIndex(dbAndColl, mongo::fromjson("{K:1}"));
	}
}

/* ****************************************************************************
*
* locationQuery -
*/
void locationQuery(void)
{
	int                 times  = 0;
	long long int       userId = minUserId;
	struct timeval      start;
	struct timeval      stop;
	struct timeval      diff;

	gettimeofday(&start, NULL);

	while (secs-- > 0)
	{
		for (int ix = 0; ix < qps; ix++)
		{
			std::auto_ptr<mongo::DBClientCursor> cursor = mdbConnection->query(dbAndColl, QUERY("I" << userId));
			++times;
			++userId;
			if (userId > maxUserId)
				userId = minUserId;

			if (cursor->more() == false)
				LM_X(1, ("No user with id %u found", userId));
			else
			{
				int hits = 0;

				while (cursor->more() != false)
				{
					cursor->next();
					++hits;
				}

				LM_V(("Found %d hits for user %d (%d times)", hits, userId, times));
			}
		}

		if (burst == false)
		{
			gettimeofday(&stop, NULL);

			timediff(&start, &stop, &diff);

			if (diff.tv_sec != 0)
				LM_X(1, ("Sorry, this operation takes too long (%d.%06d seconds)."
						 "Please lower the number of keyvalues per 'burst' (using option '-kvs')",
						 diff.tv_sec, diff.tv_usec));
			LM_M(("sleeping 0.%06d seconds", 1000000 - diff.tv_usec));
			usleep(1000000 - diff.tv_usec);
		}
	}
}

/* ****************************************************************************
*
* mobilityQuery -
*/
void mobilityQuery(void)
{
	struct timeval   start;
	struct timeval   stop;
	struct timeval   diff;
	time_t           now = time(NULL);

	if (userId == -1)
		LM_X(1, ("please indicate a user identifier, using the '-uid' option"));

	if (days == 0)
		LM_X(1, ("please indicate number of days, using the '-days' option"));

	while (secs-- > 0)
	{
		int times;

		gettimeofday(&start, NULL);

		times = 0;
		for (int ix = 0; ix < qps; ix++)
		{
			std::auto_ptr<mongo::DBClientCursor> cursor = mdbConnection->query(dbAndColl, QUERY("I" << (long long int) userId));

			if (cursor->more() == false)
				LM_X(1, ("No user with id %u found", userId));
			else
			{
				int hits = 0;

				while (cursor->more() != false)
				{
					mongo::BSONObj bo;

					int ts;

					bo = cursor->next();

					ts = bo.getIntField("T");
					if (ts + days * 3600 * 24 < now)
						continue;
					++hits;
				}

				++times;
				LM_V(("Found %d hits for user %d the last %d days (%d times)", hits, userId, days, times));
			}
		}

		if (burst == false)
		{
			gettimeofday(&stop, NULL);

			timediff(&start, &stop, &diff);

			if (diff.tv_sec != 0)
				LM_X(1, ("Sorry, this operation takes too long (%d.%06d seconds)."
						 "Please lower the number of keyvalues per 'burst' (using option '-kvs')",
						 diff.tv_sec, diff.tv_usec));
			LM_M(("sleeping 0.%06d seconds", 1000000 - diff.tv_usec));
			usleep(1000000 - diff.tv_usec);
		}
	}
}

/* ****************************************************************************
*
* main -
*/
int main(int argC, char* argV[])
{
	paConfig("prefix",                        (void*) "MONGO");
	paConfig("usage and exit on any warning", (void*) true);
    paConfig("log to screen",                 (void*) "only errors");
    paConfig("log file line format",          (void*) "TYPE:DATE:EXEC/FILE[LINE] FUNC: TEXT");
    paConfig("screen line format",            (void*) "TYPE@TIME  EXEC: TEXT");
    paConfig("log to file",                   (void*) true);

	paParse(paArgs, argC, (char**) argV, 1, false);

	if (!location && !mobility && !upload)
	{
		printf("Please pick one if the operating modes: '-location', '-mobility', or '-upload'\n");
		exit(1);
	}

	mdbConnection = new mongo::DBClientConnection();
	LM_M(("Connecting to mongo at '%s'", server));
	mdbConnection->connect(server);

	dbAndColl = (std::string) db + "." + (std::string) collection;

	if (location)
		locationQuery();
	else if (mobility)
		mobilityQuery();
	else if (upload)
		uploadData();

	return 0;
}
<|endoftext|>


<commit_before>/**
 * \ file RLSFilter.cpp
 */

#include <ATK/Adaptive/RLSFilter.h>

#include <ATK/Core/InPointerFilter.h>
#include <ATK/Core/OutPointerFilter.h>

#include <ATK/Mock/SimpleSinusGeneratorFilter.h>
#include <ATK/Mock/TriangleCheckerFilter.h>

#include <ATK/Tools/SumFilter.h>

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_NO_MAIN
#include <boost/test/unit_test.hpp>

#include <boost/math/constants/constants.hpp>

#define PROCESSSIZE (1024*64)

BOOST_AUTO_TEST_CASE( RLSFilter_memory_negative_test )
{
  ATK::RLSFilter<float> filter(100);
  BOOST_CHECK_THROW(filter.set_memory(0), std::out_of_range);
}

BOOST_AUTO_TEST_CASE( RLSFilter_memory_positive1_test )
{
  ATK::RLSFilter<float> filter(100);
  BOOST_CHECK_THROW(filter.set_memory(1), std::out_of_range);
}

BOOST_AUTO_TEST_CASE( RLSFilter_memory_99_test )
{
  ATK::SimpleSinusGeneratorFilter<float> generator;
  generator.set_output_sampling_rate(48000);
  generator.set_amplitude(1);
  generator.set_frequency(1000);

  ATK::RLSFilter<float> filter(10);
  filter.set_input_sampling_rate(48000);
  filter.set_output_sampling_rate(48000);
  filter.set_memory(.99);

  ATK::TriangleCheckerFilter<float> checker;
  checker.set_input_sampling_rate(48000);
  checker.set_amplitude(0);
  checker.set_frequency(1000);

  filter.set_input_port(0, &generator, 0);
  checker.set_input_port(0, &filter, 0);

  checker.process(PROCESSSIZE);
}

BOOST_AUTO_TEST_CASE( RLSFilter_constant_test )
{
  ATK::SimpleSinusGeneratorFilter<float> generator;
  generator.set_output_sampling_rate(48000);
  generator.set_amplitude(1);
  generator.set_frequency(1000);

  ATK::SimpleSinusGeneratorFilter<float> reference;
  reference.set_output_sampling_rate(48000);
  reference.set_amplitude(-1);
  reference.set_frequency(1000);

  ATK::RLSFilter<float> filter(1);
  filter.set_input_sampling_rate(48000);
  filter.set_output_sampling_rate(48000);
  filter.set_memory(.99);
  Eigen::Matrix<float, Eigen::Dynamic, 1> w(1);
  w << 1;
  filter.set_w(w);

  ATK::SumFilter<float> sum;
  sum.set_input_sampling_rate(48000);
  sum.set_output_sampling_rate(48000);

  ATK::TriangleCheckerFilter<float> checker;
  checker.set_input_sampling_rate(48000);
  checker.set_amplitude(0);
  checker.set_frequency(1000);

  filter.set_input_port(0, &generator, 0);
  sum.set_input_port(0, &reference, 0);
  sum.set_input_port(1, &filter, 0);
  checker.set_input_port(0, &sum, 0);

  filter.process(1); // to start everything, the filter is supposed to be one sample late
  checker.process(PROCESSSIZE);
}

BOOST_AUTO_TEST_CASE( RLSFilter_learning_test )
{
  ATK::SimpleSinusGeneratorFilter<float> generator;
  generator.set_output_sampling_rate(48000);
  generator.set_amplitude(1);
  generator.set_frequency(1000);

  ATK::SimpleSinusGeneratorFilter<float> reference;
  reference.set_output_sampling_rate(48000);
  reference.set_amplitude(-1);
  reference.set_frequency(1000);

  ATK::RLSFilter<float> filter(10);
  filter.set_input_sampling_rate(48000);
  filter.set_output_sampling_rate(48000);
  filter.set_memory(0.9999);
  filter.set_learning(true);

  ATK::SumFilter<float> sum;
  sum.set_input_sampling_rate(48000);
  sum.set_output_sampling_rate(48000);

  std::array<float, PROCESSSIZE> outdata;
  ATK::OutPointerFilter<float> output(outdata.data(), 1, PROCESSSIZE, false);
  output.set_input_sampling_rate(48000);

  filter.set_input_port(0, &generator, 0);
  sum.set_input_port(0, &reference, 0);
  sum.set_input_port(1, &filter, 0);
  output.set_input_port(0, &sum, 0);

  output.process(PROCESSSIZE);

  for(std::int64_t i = 100; i < PROCESSSIZE; ++i) // let the RLS filter start learning first
  {
    BOOST_REQUIRE_SMALL(std::abs(outdata[i]), 0.1f);
  }

}
<commit_msg>New test<commit_after>/**
 * \ file RLSFilter.cpp
 */

#include <ATK/Adaptive/RLSFilter.h>

#include <ATK/Core/InPointerFilter.h>
#include <ATK/Core/OutPointerFilter.h>

#include <ATK/Mock/SimpleSinusGeneratorFilter.h>
#include <ATK/Mock/TriangleCheckerFilter.h>

#include <ATK/Tools/SumFilter.h>

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_NO_MAIN
#include <boost/test/unit_test.hpp>

#include <boost/math/constants/constants.hpp>

#define PROCESSSIZE (1024*64)

BOOST_AUTO_TEST_CASE(RLSFilter_size_negative_test)
{
  ATK::RLSFilter<float> filter(100);
  BOOST_CHECK_THROW(filter.set_size(0), std::out_of_range);
}

BOOST_AUTO_TEST_CASE(RLSFilter_size_set_test)
{
  ATK::RLSFilter<float> filter(100);
  filter.set_size(10);
}

BOOST_AUTO_TEST_CASE(RLSFilter_memory_negative_test)
{
  ATK::RLSFilter<float> filter(100);
  BOOST_CHECK_THROW(filter.set_memory(0), std::out_of_range);
}

BOOST_AUTO_TEST_CASE( RLSFilter_memory_positive1_test )
{
  ATK::RLSFilter<float> filter(100);
  BOOST_CHECK_THROW(filter.set_memory(1), std::out_of_range);
}

BOOST_AUTO_TEST_CASE( RLSFilter_memory_99_test )
{
  ATK::SimpleSinusGeneratorFilter<float> generator;
  generator.set_output_sampling_rate(48000);
  generator.set_amplitude(1);
  generator.set_frequency(1000);

  ATK::RLSFilter<float> filter(10);
  filter.set_input_sampling_rate(48000);
  filter.set_output_sampling_rate(48000);
  filter.set_memory(.99);

  ATK::TriangleCheckerFilter<float> checker;
  checker.set_input_sampling_rate(48000);
  checker.set_amplitude(0);
  checker.set_frequency(1000);

  filter.set_input_port(0, &generator, 0);
  checker.set_input_port(0, &filter, 0);

  checker.process(PROCESSSIZE);
}

BOOST_AUTO_TEST_CASE( RLSFilter_constant_test )
{
  ATK::SimpleSinusGeneratorFilter<float> generator;
  generator.set_output_sampling_rate(48000);
  generator.set_amplitude(1);
  generator.set_frequency(1000);

  ATK::SimpleSinusGeneratorFilter<float> reference;
  reference.set_output_sampling_rate(48000);
  reference.set_amplitude(-1);
  reference.set_frequency(1000);

  ATK::RLSFilter<float> filter(1);
  filter.set_input_sampling_rate(48000);
  filter.set_output_sampling_rate(48000);
  filter.set_memory(.99);
  Eigen::Matrix<float, Eigen::Dynamic, 1> w(1);
  w << 1;
  filter.set_w(w);

  ATK::SumFilter<float> sum;
  sum.set_input_sampling_rate(48000);
  sum.set_output_sampling_rate(48000);

  ATK::TriangleCheckerFilter<float> checker;
  checker.set_input_sampling_rate(48000);
  checker.set_amplitude(0);
  checker.set_frequency(1000);

  filter.set_input_port(0, &generator, 0);
  sum.set_input_port(0, &reference, 0);
  sum.set_input_port(1, &filter, 0);
  checker.set_input_port(0, &sum, 0);

  filter.process(1); // to start everything, the filter is supposed to be one sample late
  checker.process(PROCESSSIZE);
}

BOOST_AUTO_TEST_CASE( RLSFilter_learning_test )
{
  ATK::SimpleSinusGeneratorFilter<float> generator;
  generator.set_output_sampling_rate(48000);
  generator.set_amplitude(1);
  generator.set_frequency(1000);

  ATK::SimpleSinusGeneratorFilter<float> reference;
  reference.set_output_sampling_rate(48000);
  reference.set_amplitude(-1);
  reference.set_frequency(1000);

  ATK::RLSFilter<float> filter(10);
  filter.set_input_sampling_rate(48000);
  filter.set_output_sampling_rate(48000);
  filter.set_memory(0.9999);
  filter.set_learning(true);

  ATK::SumFilter<float> sum;
  sum.set_input_sampling_rate(48000);
  sum.set_output_sampling_rate(48000);

  std::array<float, PROCESSSIZE> outdata;
  ATK::OutPointerFilter<float> output(outdata.data(), 1, PROCESSSIZE, false);
  output.set_input_sampling_rate(48000);

  filter.set_input_port(0, &generator, 0);
  sum.set_input_port(0, &reference, 0);
  sum.set_input_port(1, &filter, 0);
  output.set_input_port(0, &sum, 0);

  output.process(PROCESSSIZE);

  for(std::int64_t i = 100; i < PROCESSSIZE; ++i) // let the RLS filter start learning first
  {
    BOOST_REQUIRE_SMALL(std::abs(outdata[i]), 0.1f);
  }
}

BOOST_AUTO_TEST_CASE(RLSFilter_learning_training_test)
{
  ATK::SimpleSinusGeneratorFilter<float> generator;
  generator.set_output_sampling_rate(48000);
  generator.set_amplitude(1);
  generator.set_frequency(1000);

  ATK::SimpleSinusGeneratorFilter<float> reference;
  reference.set_output_sampling_rate(48000);
  reference.set_amplitude(-1);
  reference.set_frequency(1000);

  ATK::RLSFilter<float> filter(10);
  filter.set_input_sampling_rate(48000);
  filter.set_output_sampling_rate(48000);
  filter.set_memory(0.9999);
  filter.set_learning(true);

  ATK::SumFilter<float> sum;
  sum.set_input_sampling_rate(48000);
  sum.set_output_sampling_rate(48000);

  std::array<float, PROCESSSIZE> outdata;
  ATK::OutPointerFilter<float> output(outdata.data(), 1, PROCESSSIZE, false);
  output.set_input_sampling_rate(48000);

  filter.set_input_port(0, &generator, 0);
  sum.set_input_port(0, &reference, 0);
  sum.set_input_port(1, &filter, 0);
  output.set_input_port(0, &sum, 0);

  output.process(1000);
  filter.set_learning(false);
  output.process(PROCESSSIZE - 1000);

  for (std::int64_t i = 100; i < PROCESSSIZE; ++i) // let the RLS filter start learning first
  {
    BOOST_REQUIRE_SMALL(std::abs(outdata[i]), 0.1f);
  }

}
<|endoftext|>


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

#include "CppUTest/TestHarness.h"
#include "CppUTest/TestOutput.h"
#include "CppUTest/PlatformSpecificFunctions.h"

namespace
{
const int failLineNumber = 2;
const char* failFileName = "fail.cpp";
}

static double zero = 0.0;
static double one = 1.0;
static const double not_a_number = zero / zero;
static const double infinity = one / zero;

extern "C" {
    static int IsNanForSystemsWithoutNan(double d) { return (0.0 == d); }
    static int IsInfForSystemsWithoutInf(double d) { return ((long)infinity == (long)d); }
}

TEST_GROUP(TestFailureNanAndInf)
{
    UtestShell*  test;

    void setup() _override
    {
        test = new UtestShell("groupname", "testname", failFileName, failLineNumber-1);
        if(PlatformSpecificIsNan(not_a_number) == false)
            UT_PTR_SET(PlatformSpecificIsNan, IsNanForSystemsWithoutNan);
        if(PlatformSpecificIsInf(infinity) == false)
            UT_PTR_SET(PlatformSpecificIsInf, IsInfForSystemsWithoutInf);
    }
    void teardown()
    {
        delete test;
    }
};

#define FAILURE_EQUAL(a, b) STRCMP_EQUAL_LOCATION(a, b.getMessage().asCharString(), __FILE__, __LINE__)

TEST(TestFailureNanAndInf, DoublesEqualExpectedIsNaN)
{
    DoublesEqualFailure f(test, failFileName, failLineNumber, not_a_number, 2.0, 3.0);
    FAILURE_EQUAL("expected <Nan - Not a number>\n"
                "\tbut was  <2> threshold used was <3>\n"
                "\tCannot make comparisons with Nan", f);
}

TEST(TestFailureNanAndInf, DoublesEqualActualIsNaN)
{
    DoublesEqualFailure f(test, failFileName, failLineNumber, 1.0, not_a_number, 3.0);
    FAILURE_EQUAL("expected <1>\n"
                "\tbut was  <Nan - Not a number> threshold used was <3>\n"
                "\tCannot make comparisons with Nan", f);
}

TEST(TestFailureNanAndInf, DoublesEqualThresholdIsNaN)
{
    DoublesEqualFailure f(test, failFileName, failLineNumber, 1.0, 2.0, not_a_number);
    FAILURE_EQUAL("expected <1>\n"
                "\tbut was  <2> threshold used was <Nan - Not a number>\n"
                "\tCannot make comparisons with Nan", f);
}

TEST(TestFailureNanAndInf, DoublesEqualExpectedIsInf)
{
    DoublesEqualFailure f(test, failFileName, failLineNumber, infinity, 2.0, 3.0);
    FAILURE_EQUAL("expected <Inf - Infinity>\n"
                "\tbut was  <2> threshold used was <3>", f);
}

TEST(TestFailureNanAndInf, DoublesEqualActualIsInf)
{
    DoublesEqualFailure f(test, failFileName, failLineNumber, 1.0, infinity, 3.0);
    FAILURE_EQUAL("expected <1>\n"
                "\tbut was  <Inf - Infinity> threshold used was <3>", f);
}

TEST(TestFailureNanAndInf, DoublesEqualThresholdIsInf)
{
    DoublesEqualFailure f(test, failFileName, failLineNumber, 1.0, not_a_number, infinity);
    FAILURE_EQUAL("expected <1>\n"
                "\tbut was  <Nan - Not a number> threshold used was <Inf - Infinity>\n"
                "\tCannot make comparisons with Nan", f);
}
<commit_msg>Missing override added.<commit_after>/*
 * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the <organization> nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "CppUTest/TestHarness.h"
#include "CppUTest/TestOutput.h"
#include "CppUTest/PlatformSpecificFunctions.h"

namespace
{
const int failLineNumber = 2;
const char* failFileName = "fail.cpp";
}

static double zero = 0.0;
static double one = 1.0;
static const double not_a_number = zero / zero;
static const double infinity = one / zero;

extern "C" {
    static int IsNanForSystemsWithoutNan(double d) { return (0.0 == d); }
    static int IsInfForSystemsWithoutInf(double d) { return ((long)infinity == (long)d); }
}

TEST_GROUP(TestFailureNanAndInf)
{
    UtestShell*  test;

    void setup() _override
    {
        test = new UtestShell("groupname", "testname", failFileName, failLineNumber-1);
        if(PlatformSpecificIsNan(not_a_number) == false)
            UT_PTR_SET(PlatformSpecificIsNan, IsNanForSystemsWithoutNan);
        if(PlatformSpecificIsInf(infinity) == false)
            UT_PTR_SET(PlatformSpecificIsInf, IsInfForSystemsWithoutInf);
    }
    void teardown() _override
    {
        delete test;
    }
};

#define FAILURE_EQUAL(a, b) STRCMP_EQUAL_LOCATION(a, b.getMessage().asCharString(), __FILE__, __LINE__)

TEST(TestFailureNanAndInf, DoublesEqualExpectedIsNaN)
{
    DoublesEqualFailure f(test, failFileName, failLineNumber, not_a_number, 2.0, 3.0);
    FAILURE_EQUAL("expected <Nan - Not a number>\n"
                "\tbut was  <2> threshold used was <3>\n"
                "\tCannot make comparisons with Nan", f);
}

TEST(TestFailureNanAndInf, DoublesEqualActualIsNaN)
{
    DoublesEqualFailure f(test, failFileName, failLineNumber, 1.0, not_a_number, 3.0);
    FAILURE_EQUAL("expected <1>\n"
                "\tbut was  <Nan - Not a number> threshold used was <3>\n"
                "\tCannot make comparisons with Nan", f);
}

TEST(TestFailureNanAndInf, DoublesEqualThresholdIsNaN)
{
    DoublesEqualFailure f(test, failFileName, failLineNumber, 1.0, 2.0, not_a_number);
    FAILURE_EQUAL("expected <1>\n"
                "\tbut was  <2> threshold used was <Nan - Not a number>\n"
                "\tCannot make comparisons with Nan", f);
}

TEST(TestFailureNanAndInf, DoublesEqualExpectedIsInf)
{
    DoublesEqualFailure f(test, failFileName, failLineNumber, infinity, 2.0, 3.0);
    FAILURE_EQUAL("expected <Inf - Infinity>\n"
                "\tbut was  <2> threshold used was <3>", f);
}

TEST(TestFailureNanAndInf, DoublesEqualActualIsInf)
{
    DoublesEqualFailure f(test, failFileName, failLineNumber, 1.0, infinity, 3.0);
    FAILURE_EQUAL("expected <1>\n"
                "\tbut was  <Inf - Infinity> threshold used was <3>", f);
}

TEST(TestFailureNanAndInf, DoublesEqualThresholdIsInf)
{
    DoublesEqualFailure f(test, failFileName, failLineNumber, 1.0, not_a_number, infinity);
    FAILURE_EQUAL("expected <1>\n"
                "\tbut was  <Nan - Not a number> threshold used was <Inf - Infinity>\n"
                "\tCannot make comparisons with Nan", f);
}
<|endoftext|>


<commit_before>#include <catch.hpp>
#include <cgo/base/state.hpp>

using namespace cgo::base;

void assertCapture(const Board& board, const Action& action,
 const Board& expected) {
   Board actual = State::applyAction(State(board), action).getBoard();
   REQUIRE(expected == actual);
}

TEST_CASE("base/state/capture/empty") {
   auto n = none;
   auto W = white;
   auto B = black;

   Board board = {{
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   Action action(white, Position(1, 1));

   Board expected = {{
      n, n, n, n, n, n, n, n, n,
      n, W, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   assertCapture(board, action, expected);
}

TEST_CASE("base/state/capture/empty/white") {
   auto n = none;
   auto W = white;
   auto B = black;

   Board board = {{
      n, n, W, n, n, n, n, n, n,
      n, W, n, W, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   Action action(white, Position(2, 2));

   Board expected = {{
      n, n, W, n, n, n, n, n, n,
      n, W, n, W, n, n, n, n, n,
      n, n, W, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   assertCapture(board, action, expected);
}

TEST_CASE("base/state/capture/empty/black") {
   auto n = none;
   auto W = white;
   auto B = black;

   Board board = {{
      n, n, B, n, n, n, n, n, n,
      n, B, n, B, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   Action action(black, Position(2, 2));

   Board expected = {{
      n, n, B, n, n, n, n, n, n,
      n, B, n, B, n, n, n, n, n,
      n, n, B, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   assertCapture(board, action, expected);
}

TEST_CASE("base/state/capture/white") {
   auto n = none;
   auto W = white;
   auto B = black;

   Board board = {{
      n, n, W, n, n, n, n, n, n,
      n, W, B, W, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   Action action(white, Position(2, 2));

   Board expected = {{
      n, n, W, n, n, n, n, n, n,
      n, W, n, W, n, n, n, n, n,
      n, n, W, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   assertCapture(board, action, expected);
}

TEST_CASE("base/state/capture/black") {
   auto n = none;
   auto W = white;
   auto B = black;

   Board board = {{
      n, n, B, n, n, n, n, n, n,
      n, B, W, B, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   Action action(black, Position(2, 2));

   Board expected = {{
      n, n, B, n, n, n, n, n, n,
      n, B, n, B, n, n, n, n, n,
      n, n, B, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   assertCapture(board, action, expected);
}

TEST_CASE("base/state/capture/contested") {
   auto n = none;
   auto W = white;
   auto B = black;

   Board board = {{
      n, n, W, n, n, n, n, n, n,
      n, W, B, n, W, n, n, n, n,
      n, n, W, W, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   Action action(white, Position(0, 3));

   Board expected = {{
      n, n, W, W, n, n, n, n, n,
      n, W, B, n, W, n, n, n, n,
      n, n, W, W, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   assertCapture(board, action, expected);
}

TEST_CASE("base/state/capture/surrounded") {
   auto n = none;
   auto W = white;
   auto B = black;

   Board board = {{
      n, n, W, n, n, n, n, n, n,
      n, W, B, B, W, n, n, n, n,
      n, n, W, W, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   Action action(white, Position(0, 3));

   Board expected = {{
      n, n, W, W, n, n, n, n, n,
      n, W, n, n, W, n, n, n, n,
      n, n, W, W, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   assertCapture(board, action, expected);
}

TEST_CASE("base/state/capture/one-eye") {
   auto n = none;
   auto W = white;
   auto B = black;

   Board board = {{
      n, n, B, n, n, n, n, n, n,
      n, B, W, B, n, n, n, n, n,
      B, W, n, W, B, n, n, n, n,
      n, B, W, B, n, n, n, n, n,
      n, n, B, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   Action action(black, Position(2, 2));

   Board expected = {{
      n, n, B, n, n, n, n, n, n,
      n, B, n, B, n, n, n, n, n,
      B, n, B, n, B, n, n, n, n,
      n, B, n, B, n, n, n, n, n,
      n, n, B, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   assertCapture(board, action, expected);
}

TEST_CASE("base/state/capture/two-eyes") {
   auto n = none;
   auto W = white;
   auto B = black;

   Board board = {{
      n, n, B, n, n, n, n, n, n,
      n, B, W, B, n, n, n, n, n,
      B, W, n, W, B, n, n, n, n,
      n, B, W, n, W, B, n, n, n,
      n, n, B, W, B, n, n, n, n,
      n, n, n, B, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   Action action1(black, Position(2, 2));
   Action action2(black, Position(3, 3));

   Board expected = {{
      n, n, B, n, n, n, n, n, n,
      n, B, W, B, n, n, n, n, n,
      B, W, n, W, B, n, n, n, n,
      n, B, W, n, W, B, n, n, n,
      n, n, B, W, B, n, n, n, n,
      n, n, n, B, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   assertCapture(board, action1, expected);
   assertCapture(board, action2, expected);
}
<commit_msg>Tests: correct capture tests<commit_after>#include <catch.hpp>
#include <cgo/base/state.hpp>

using namespace cgo::base;

void assertCapture(const Board& board, const Action& action,
 const Board& expected) {
   Board actual = State::applyAction(State(board), action).getBoard();
   REQUIRE(expected == actual);
}

TEST_CASE("base/state/capture/empty") {
   auto n = none;
   auto W = white;
   auto B = black;

   Board board = {{
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   Action action(white, Position(1, 1));

   Board expected = {{
      n, n, n, n, n, n, n, n, n,
      n, W, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   assertCapture(board, action, expected);
}

TEST_CASE("base/state/capture/empty/white") {
   auto n = none;
   auto W = white;
   auto B = black;

   Board board = {{
      n, n, W, n, n, n, n, n, n,
      n, W, n, W, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   Action action(white, Position(2, 2));

   Board expected = {{
      n, n, W, n, n, n, n, n, n,
      n, W, n, W, n, n, n, n, n,
      n, n, W, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   assertCapture(board, action, expected);
}

TEST_CASE("base/state/capture/empty/black") {
   auto n = none;
   auto W = white;
   auto B = black;

   Board board = {{
      n, n, B, n, n, n, n, n, n,
      n, B, n, B, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   Action action(black, Position(2, 2));

   Board expected = {{
      n, n, B, n, n, n, n, n, n,
      n, B, n, B, n, n, n, n, n,
      n, n, B, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   assertCapture(board, action, expected);
}

TEST_CASE("base/state/capture/white") {
   auto n = none;
   auto W = white;
   auto B = black;

   Board board = {{
      n, n, W, n, n, n, n, n, n,
      n, W, B, W, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   Action action(white, Position(2, 2));

   Board expected = {{
      n, n, W, n, n, n, n, n, n,
      n, W, n, W, n, n, n, n, n,
      n, n, W, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   assertCapture(board, action, expected);
}

TEST_CASE("base/state/capture/black") {
   auto n = none;
   auto W = white;
   auto B = black;

   Board board = {{
      n, n, B, n, n, n, n, n, n,
      n, B, W, B, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   Action action(black, Position(2, 2));

   Board expected = {{
      n, n, B, n, n, n, n, n, n,
      n, B, n, B, n, n, n, n, n,
      n, n, B, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   assertCapture(board, action, expected);
}

TEST_CASE("base/state/capture/corner") {
   auto n = none;
   auto W = white;
   auto B = black;

   Board board = {{
      W, B, n, n, n, n, n, n, n,
      n, W, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   Action action(black, Position(1, 0));

   Board expected = {{
      n, B, n, n, n, n, n, n, n,
      B, W, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   assertCapture(board, action, expected);
}

TEST_CASE("base/state/capture/contested") {
   auto n = none;
   auto W = white;
   auto B = black;

   Board board = {{
      n, n, W, n, n, n, n, n, n,
      n, W, B, n, W, n, n, n, n,
      n, n, W, W, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   Action action(white, Position(0, 3));

   Board expected = {{
      n, n, W, W, n, n, n, n, n,
      n, W, B, n, W, n, n, n, n,
      n, n, W, W, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   assertCapture(board, action, expected);
}

TEST_CASE("base/state/capture/surrounded") {
   auto n = none;
   auto W = white;
   auto B = black;

   Board board = {{
      n, n, W, n, n, n, n, n, n,
      n, W, B, B, W, n, n, n, n,
      n, n, W, W, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   Action action(white, Position(0, 3));

   Board expected = {{
      n, n, W, W, n, n, n, n, n,
      n, W, n, n, W, n, n, n, n,
      n, n, W, W, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   assertCapture(board, action, expected);
}

TEST_CASE("base/state/capture/one-eye") {
   auto n = none;
   auto W = white;
   auto B = black;

   Board board = {{
      n, n, B, n, n, n, n, n, n,
      n, B, W, B, n, n, n, n, n,
      B, W, n, W, B, n, n, n, n,
      n, B, W, B, n, n, n, n, n,
      n, n, B, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   Action action(black, Position(2, 2));

   Board expected = {{
      n, n, B, n, n, n, n, n, n,
      n, B, W, B, n, n, n, n, n,
      B, W, n, W, B, n, n, n, n,
      n, B, W, B, n, n, n, n, n,
      n, n, B, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   assertCapture(board, action, expected);
}

TEST_CASE("base/state/capture/two-eyes") {
   auto n = none;
   auto W = white;
   auto B = black;

   Board board = {{
      n, n, B, n, n, n, n, n, n,
      n, B, W, B, n, n, n, n, n,
      B, W, n, W, B, n, n, n, n,
      n, B, W, n, W, B, n, n, n,
      n, n, B, W, B, n, n, n, n,
      n, n, n, B, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   Action action1(black, Position(2, 2));
   Action action2(black, Position(3, 3));

   Board expected = {{
      n, n, B, n, n, n, n, n, n,
      n, B, W, B, n, n, n, n, n,
      B, W, n, W, B, n, n, n, n,
      n, B, W, n, W, B, n, n, n,
      n, n, B, W, B, n, n, n, n,
      n, n, n, B, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
      n, n, n, n, n, n, n, n, n,
   }};

   assertCapture(board, action1, expected);
   assertCapture(board, action2, expected);
}
<|endoftext|>