Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: ngscopeclient/scopehal
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 771ccf85b973
Choose a base ref
...
head repository: ngscopeclient/scopehal
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: f6d9c69f884a
Choose a head ref
  • 2 commits
  • 8 files changed
  • 1 contributor

Commits on Oct 21, 2020

  1. Initial skeleton of TestCase. Refactored TestWaveformSource to take a…

    …n external mt19937 object to allow deterministic seeding.
    azonenberg committed Oct 21, 2020
    Copy the full SHA
    bc6b3d6 View commit details
  2. Copy the full SHA
    f6d9c69 View commit details
Showing with 190 additions and 14 deletions.
  1. +1 −0 scopehal/CMakeLists.txt
  2. +2 −0 scopehal/DemoOscilloscope.cpp
  3. +4 −0 scopehal/DemoOscilloscope.h
  4. +3 −0 scopehal/MockOscilloscope.h
  5. +110 −0 scopehal/TestCase.cpp
  6. +59 −0 scopehal/TestCase.h
  7. +6 −12 scopehal/TestWaveformSource.cpp
  8. +5 −2 scopehal/TestWaveformSource.h
1 change: 1 addition & 0 deletions scopehal/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -75,6 +75,7 @@ set(SCOPEHAL_SOURCES
Statistic.cpp
SpectrumChannel.cpp

TestCase.cpp
TestWaveformSource.cpp
)

2 changes: 2 additions & 0 deletions scopehal/DemoOscilloscope.cpp
Original file line number Diff line number Diff line change
@@ -47,6 +47,8 @@ DemoOscilloscope::DemoOscilloscope(SCPITransport* transport)
, m_extTrigger(NULL)
, m_triggerArmed(false)
, m_triggerOneShot(false)
, m_rng(m_rd())
, m_source(m_rng)
{
m_model = "Oscilloscope Simulator";
m_vendor = "Antikernel Labs";
4 changes: 4 additions & 0 deletions scopehal/DemoOscilloscope.h
Original file line number Diff line number Diff line change
@@ -37,6 +37,7 @@
#define DemoOscilloscope_h

#include "TestWaveformSource.h"
#include <random>

class DemoOscilloscope : public SCPIOscilloscope
{
@@ -115,6 +116,9 @@ class DemoOscilloscope : public SCPIOscilloscope
size_t m_depth;
size_t m_rate;

std::random_device m_rd;
std::mt19937 m_rng;

TestWaveformSource m_source;

public:
3 changes: 3 additions & 0 deletions scopehal/MockOscilloscope.h
Original file line number Diff line number Diff line change
@@ -46,6 +46,9 @@ class MockOscilloscope : public Oscilloscope
MockOscilloscope(const MockOscilloscope& rhs) =delete;
MockOscilloscope& operator=(const MockOscilloscope& rhs) =delete;

void AddChannel(OscilloscopeChannel* chan)
{ m_channels.push_back(chan); }

virtual std::string IDPing();

virtual std::string GetTransportConnectionString();
110 changes: 110 additions & 0 deletions scopehal/TestCase.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/***********************************************************************************************************************
* *
* ANTIKERNEL v0.1 *
* *
* Copyright (c) 2012-2020 Andrew D. Zonenberg *
* 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 author nor the names of any contributors may be used to endorse or promote products *
* derived from this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE 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 *
* THE AUTHORS BE HELD 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. *
* *
***********************************************************************************************************************/

/**
@file
@author Andrew D. Zonenberg
@brief Implementation of TestWaveformSource
*/

#include "scopehal.h"
#include "TestCase.h"

using namespace std;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Construction / destruction

TestCase::TestCase(int argc, char* argv[], string filter)
: m_scope("Test Scope", "Antikernel Labs", "12345")
{
//Global settings
//Default to debug since this is a test case
Severity console_verbosity = Severity::DEBUG;

//Parse command-line arguments
int64_t seed = 0;
for(int i=1; i<argc; i++)
{
string s(argv[i]);

//Let the logger eat its args first
if(ParseLoggerArguments(i, argc, argv, console_verbosity))
continue;

//TODO: parse arguments for random seed, number of iterations, etc
}

//Initialize the seed
m_rng.seed(seed);

//Set up logging
g_log_sinks.emplace(g_log_sinks.begin(), new ColoredSTDLogSink(console_verbosity));

//Global scopehal initialization
TransportStaticInit();
DriverStaticInit();
InitializePlugins();

//Create the filter
m_filter = Filter::CreateFilter(filter, "#ffffff");
m_filter->AddRef();

LogNotice("Testing \"%s\" filter\n", filter.c_str());
}

TestCase::~TestCase()
{
m_filter->Release();
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Test execution

/**
@brief Runs the test iteration in a loop
@return True if all test iterations are successful, false on failure
*/
bool TestCase::Run()
{
//TODO: get this from an argument
const size_t niter = 25;

for(size_t i=0; i<niter; i++)
{
if(!Iteration(i))
{
LogError("Test case FAILED at iteration %zu\n", i);
return false;
}
}

return true;
}
59 changes: 59 additions & 0 deletions scopehal/TestCase.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/***********************************************************************************************************************
* *
* ANTIKERNEL v0.1 *
* *
* Copyright (c) 2012-2020 Andrew D. Zonenberg *
* 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 author nor the names of any contributors may be used to endorse or promote products *
* derived from this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE 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 *
* THE AUTHORS BE HELD 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. *
* *
***********************************************************************************************************************/

/**
@file
@author Andrew D. Zonenberg
@brief Declaration of TestWaveformSource
*/

#ifndef TestCase_h
#define TestCase_h

#include <random>
#include "MockOscilloscope.h"

class TestCase
{
public:
TestCase(int argc, char* argv[], std::string filter);
virtual ~TestCase();

bool Run();
virtual bool Iteration(size_t i) =0;

protected:
std::mt19937 m_rng;

Filter* m_filter;
MockOscilloscope m_scope;
};


#endif
18 changes: 6 additions & 12 deletions scopehal/TestWaveformSource.cpp
Original file line number Diff line number Diff line change
@@ -34,15 +34,15 @@
*/
#include "scopehal.h"
#include "TestWaveformSource.h"
#include <random>
#include <complex>

using namespace std;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Construction / destruction

TestWaveformSource::TestWaveformSource()
TestWaveformSource::TestWaveformSource(mt19937& rng)
: m_rng(rng)
{
m_forwardPlan = NULL;
m_reversePlan = NULL;
@@ -82,7 +82,7 @@ TestWaveformSource::~TestWaveformSource()
WaveformBase* TestWaveformSource::GenerateNoisySinewave(
float amplitude,
float startphase,
int64_t period,
float period,
int64_t sampleperiod,
size_t depth,
float noise_amplitude)
@@ -91,8 +91,6 @@ WaveformBase* TestWaveformSource::GenerateNoisySinewave(
ret->m_timescale = sampleperiod;
ret->Resize(depth);

random_device rd;
mt19937 rng(rd());
normal_distribution<> noise(0, noise_amplitude);

float samples_per_cycle = period * 1.0 / sampleperiod;
@@ -106,7 +104,7 @@ WaveformBase* TestWaveformSource::GenerateNoisySinewave(
ret->m_offsets[i] = i;
ret->m_durations[i] = 1;

ret->m_samples[i] = scale * sinf(i*radians_per_sample + startphase) + noise(rng);
ret->m_samples[i] = scale * sinf(i*radians_per_sample + startphase) + noise(m_rng);
}

return ret;
@@ -129,8 +127,6 @@ WaveformBase* TestWaveformSource::GenerateNoisySinewaveMix(
ret->m_timescale = sampleperiod;
ret->Resize(depth);

random_device rd;
mt19937 rng(rd());
normal_distribution<> noise(0, noise_amplitude);

float radians_per_sample1 = 2 * M_PI * sampleperiod / period1;
@@ -147,7 +143,7 @@ WaveformBase* TestWaveformSource::GenerateNoisySinewaveMix(

ret->m_samples[i] = scale *
(sinf(i*radians_per_sample1 + startphase1) + sinf(i*radians_per_sample2 + startphase2))
+ noise(rng);
+ noise(m_rng);
}

return ret;
@@ -280,8 +276,6 @@ WaveformBase* TestWaveformSource::Generate8b10b(
void TestWaveformSource::DegradeSerialData(AnalogWaveform* cap, int64_t sampleperiod, size_t depth)
{
//RNGs
random_device rd;
mt19937 rng(rd());
normal_distribution<> noise(0, 0.01);

//Prepare for second pass: reallocate FFT buffer if sample depth changed
@@ -333,5 +327,5 @@ void TestWaveformSource::DegradeSerialData(AnalogWaveform* cap, int64_t samplepe
//Rescale the FFT output and copy to the output, then add noise
float fftscale = 1.0f / npoints;
for(size_t i=0; i<depth; i++)
cap->m_samples[i] = m_reverseOutBuf[i] * fftscale + noise(rng);
cap->m_samples[i] = m_reverseOutBuf[i] * fftscale + noise(m_rng);
}
7 changes: 5 additions & 2 deletions scopehal/TestWaveformSource.h
Original file line number Diff line number Diff line change
@@ -38,6 +38,7 @@

#include "../scopehal/AlignedAllocator.h"
#include <ffts.h>
#include <random>

/**
@brief Helper class for generating test waveforms
@@ -47,7 +48,7 @@
class TestWaveformSource
{
public:
TestWaveformSource();
TestWaveformSource(std::mt19937& rng);
virtual ~TestWaveformSource();

TestWaveformSource(const TestWaveformSource&) =delete;
@@ -56,7 +57,7 @@ class TestWaveformSource
WaveformBase* GenerateNoisySinewave(
float amplitude,
float startphase,
int64_t period,
float period,
int64_t sampleperiod,
size_t depth,
float noise_amplitude = 0.01);
@@ -86,6 +87,8 @@ class TestWaveformSource
void DegradeSerialData(AnalogWaveform* cap, int64_t sampleperiod, size_t depth);

protected:
std::mt19937& m_rng;

//FFT stuff
AlignedAllocator<float, 32> m_allocator;
ffts_plan_t* m_forwardPlan;