void GlTexture:: reset(unsigned short width, unsigned short height, unsigned int pixelFormat, unsigned int internalFormat, unsigned type, void* data) { if (0==textureId) { GlException_SAFE_CALL( glGenTextures(1, &ownTextureId) ); textureId = ownTextureId; } this->width = width; this->height = height; if (0==width) return; bindTexture2D(); GlException_SAFE_CALL( glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) ); GlException_SAFE_CALL( glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) ); //GlException_SAFE_CALL( glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR) ); GlException_SAFE_CALL( glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) ); GlException_SAFE_CALL( glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) ); int gl_max_texture_size = 0; glGetIntegerv (GL_MAX_TEXTURE_SIZE, &gl_max_texture_size); EXCEPTION_ASSERT_LESS(width, gl_max_texture_size); EXCEPTION_ASSERT_LESS(height, gl_max_texture_size); GlException_SAFE_CALL( glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, pixelFormat, type, data) ); unbindTexture2D(); }
void QtEventWorkerFactory:: test() { std::string name = "QtEventWorkers"; int argc = 1; char * argv = &name[0]; QApplication a(argc,&argv); // takes 0.4 s if this is the first instantiation of QApplication Workers::test ([](ISchedule::ptr schedule){ Bedroom::ptr bedroom(new Bedroom); return IWorkerFactory::ptr(new QtEventWorkerFactory(schedule, bedroom)); }); { UNITTEST_STEPS TaskInfo("It should terminate all threads when it's closed"); ISchedule::ptr schedule[] = { ISchedule::ptr(new SleepScheduleMock), ISchedule::ptr(new LockScheduleMock), ISchedule::ptr(new BusyScheduleMock) }; for (unsigned i=0; i<sizeof(schedule)/sizeof(schedule[0]); i++) { Timer t; { ISchedule::ptr s = schedule[i]; //TaskInfo ti(boost::format("%s") % vartype(*s)); Bedroom::ptr bedroom(new Bedroom); Processing::Workers workers(IWorkerFactory::ptr(new QtEventWorkerFactory(s, bedroom))); Bedroom::Bed bed = dynamic_cast<BlockScheduleMock*>(s.get ())->bedroom.getBed(); workers.addComputingEngine(Signal::ComputingEngine::ptr()); // Wait until the schedule has been called (Bedroom supports // that the wakeup in schedule is called even before this sleep call // as long as 'bed' is allocated before the wakeup call) bed.sleep (); EXCEPTION_ASSERT_EQUALS(false, workers.remove_all_engines (10)); EXCEPTION_ASSERT_EQUALS(true, QtEventWorkerFactory::terminate_workers (workers, 0)); EXCEPTION_ASSERT_EQUALS(workers.n_workers(), 0u); EXPECT_EXCEPTION(QtEventWorker::TerminatedException, workers.rethrow_any_worker_exception ()); workers.clean_dead_workers (); } float elapsed = t.elapsed (); float n = (i+1)*0.00001; EXCEPTION_ASSERT_LESS(0.01+n, elapsed); EXCEPTION_ASSERT_LESS(elapsed, 0.04+n); // +n makes it possible to see in the test log which iteration that failed } } // It should wake up sleeping workers when any work is done to see if they can // help out on what's left. { } }
void WaveformBlockFilter:: test() { // It should update a block with cwt transform data. { Timer t; // Tfr::DrawnWaveform waveformdesc; // Signal::Interval data = waveformdesc.requiredInterval (Signal::Interval(0,4), 0); Signal::Interval data(0,4); // Create some data to plot into the block Signal::pMonoBuffer buffer(new Signal::MonoBuffer(data, data.count ()/4)); float *p = buffer->waveform_data()->getCpuMemory (); srand(0); for (unsigned i=0; i<buffer->getInterval ().count (); ++i) { p[i] = -1.f + 2.f*rand()/RAND_MAX; } // Create a block to plot into BlockLayout bl(4,4, buffer->sample_rate ()); VisualizationParams::ptr vp(new VisualizationParams); Reference ref = [&]() { Reference ref; Position max_sample_size; max_sample_size.time = 2.f*max(1.f, buffer->length ())/bl.texels_per_row (); max_sample_size.scale = 1.f/bl.texels_per_column (); ref.log2_samples_size = Reference::Scale( floor_log2( max_sample_size.time ), floor_log2( max_sample_size.scale )); ref.block_index = Reference::Index(0,0); return ref; }(); Heightmap::pBlock block( new Heightmap::Block(ref, bl, vp)); // Create some data to plot into the block Tfr::ChunkAndInverse cai; cai.input = buffer; // Do the merge Heightmap::MergeChunk::ptr mc( new WaveformBlockFilter ); Update::IUpdateJob::ptr job = mc->prepareUpdate (cai)[0]; EXCEPTION_ASSERT(dynamic_cast<WaveformBlockUpdater::Job*>(job.get ())); std::queue<Heightmap::Update::UpdateQueue::Job> jobs; Heightmap::Update::UpdateQueue::Job j; j.updatejob = job; j.intersecting_blocks = vector<pBlock>{block}; jobs.push (std::move(j)); WaveformBlockUpdater().processJobs(jobs); float T = t.elapsed (); EXCEPTION_ASSERT_LESS(T, 1.0); // this is ridiculously slow } }
GlTexture::GlTexture(unsigned int textureId) : width( 0 ), height( 0 ), textureId( textureId ), ownTextureId( 0 ) { EXCEPTION_ASSERT_LESS(0u, textureId); int width=0, height=0; glBindTexture (GL_TEXTURE_2D, textureId); GlException_SAFE_CALL( glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width) ); GlException_SAFE_CALL( glGetTexLevelParameteriv (GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height) ); glBindTexture (GL_TEXTURE_2D, 0); this->width = width; this->height = height; EXCEPTION_ASSERT_LESS(0, width); EXCEPTION_ASSERT_LESS(0, height); EXCEPTION_ASSERT_EQUALS(this->width, width); EXCEPTION_ASSERT_EQUALS(this->height, height); }
void blocking_queue_test:: test () { // It should provide a thread safe solution to the multiple consumer-multiple producer pattern. { typedef blocking_queue<function<int()>> queue; queue q; auto producer = [&q](int a, int b) { for (int i=a; i<b; i++) q.push ([i]() { return i; }); }; auto consumer = [&q]() { int S = 0; try { while (true) S += q.pop ()(); } catch (queue::abort_exception) {} return S; }; vector<thread> producers; vector<future<int>> consumers; for (int i=0; i<10; i++) { producers.push_back (thread(producer, 100*i, 100*i + 100)); consumers.push_back (async(launch::async, consumer)); } for (thread& t : producers) t.join (); q.close (); int S = 0; for (future<int>& f : consumers) { int v = f.get (); EXCEPTION_ASSERT_LESS(1000, v); S += v; } EXCEPTION_ASSERT_EQUALS(S, (999-0)/2.0 * 1000); } // pop_for { typedef blocking_queue<int> queue; queue q; auto a = async(launch::async, [&q]() { EXCEPTION_ASSERT_EQUALS(q.pop_for (chrono::duration<double>(0.0001)), 0); EXCEPTION_ASSERT_EQUALS(q.pop_for (chrono::duration<double>(0.1)), 2); EXCEPTION_ASSERT_EQUALS(q.pop_for (chrono::duration<double>(0.0001)), 0); }); this_thread::sleep_for (chrono::duration<double>(0.001)); q.push (2); a.get(); } // clear { typedef blocking_queue<int> queue; queue q; q.push (2); q.push (4); EXCEPTION_ASSERT(!q.empty ()); auto q2 = q.clear (); EXCEPTION_ASSERT(q.empty ()); EXCEPTION_ASSERT_EQUALS(q2.size (), 2u); } }
void Bedroom:: test() { // It should allow different threads to sleep on this object until another thread calls wakeup() for (int j=0;j<2; j++) { Bedroom::ptr bedroom(new Bedroom); int snoozes = 10; SleepyFaceMock sleepyface1(bedroom, snoozes); SleepyFaceMock sleepyface2(bedroom, snoozes); sleepyface1.start (); sleepyface2.start (); for (int i=snoozes; i>=0; i--) { EXCEPTION_ASSERT_EQUALS(sleepyface1.wait (1), i>0?false:true); EXCEPTION_ASSERT_EQUALS(sleepyface2.wait (1), i>0?false:true); // sleepyface1 and sleepyface2 shoule be sleeping now EXCEPTION_ASSERT_EQUALS(bedroom->sleepers(), i>0?2:0); // they should have 'i' times left to snooze EXCEPTION_ASSERTX(sleepyface1.snooze () == i && sleepyface2.snooze () == i, (boost::format("sleepyface1=%d, sleepyface2=%d, i=%d") % sleepyface1.snooze () % sleepyface2.snooze () % i)); // should wake up both bedroom->wakeup(); } EXCEPTION_ASSERT(sleepyface1.isFinished ()); EXCEPTION_ASSERT(sleepyface2.isFinished ()); EXCEPTION_ASSERT_EQUALS(bedroom->sleepers(), 0); } // It should throw a BedroomClosed exception if someone tries to go to // sleep when the bedroom is closed. { Bedroom b; b.close (); EXPECT_EXCEPTION(BedroomClosed, b.getBed().sleep ()); } // It should just sleep until the given timeout has elapsed { Bedroom b; Timer t; bool woken_up_by_wakeup_call = b.getBed ().sleep (2); // The thread was sleeping in its bed for 2 ms. So the elapsed 'Timer' // time should be more than 2 ms but less than 3 ms. EXCEPTION_ASSERT_LESS(t.elapsed (), 3e-3); EXCEPTION_ASSERT_LESS(2e-3, t.elapsed ()); EXCEPTION_ASSERT(!woken_up_by_wakeup_call); // timeout } // It should just sleep until the given timeout has elapsed for (int i=0; i<40; i++) { //TaskTimer tt("It should just sleep until the given timeout has elapsed"); Bedroom::ptr bedroom(new Bedroom); SleepingBeautyMock sbm(bedroom, 1); EXCEPTION_ASSERT_EQUALS(0,bedroom->sleepers ()); sbm.start (); // wait for the thread to go to sleep and then timeout for (int j=0; j<100 && 0==sbm.timeoutCount (); j++) EXCEPTION_ASSERT( !sbm.wait (1) ); // wakeup bedroom->wakeup(); // the thread should finish soon EXCEPTION_ASSERT( sbm.wait (128) ); EXCEPTION_ASSERT_EQUALS(0,bedroom->sleepers ()); } // It should just sleep until the given timeout has elapsed for (int i=0; i<40; i++) { //TaskTimer tt("It should just sleep until the given timeout has elapsed"); Bedroom::ptr bedroom(new Bedroom); SleepingBeautyMock sbm(bedroom, 1000); EXCEPTION_ASSERT_EQUALS(0,bedroom->sleepers ()); sbm.start (); // wait for the thread to go to sleep for (int j=0; j<100 && 0==bedroom->sleepers (); j++) EXCEPTION_ASSERT( !sbm.wait (1) ); EXCEPTION_ASSERT_EQUALS(1,bedroom->sleepers ()); // wakeup bedroom->wakeup(); // the thread should finish soon EXCEPTION_ASSERT( sbm.wait (128) ); EXCEPTION_ASSERT_EQUALS(0,bedroom->sleepers ()); // with such a long timeout the number of timeouts should be 0 EXCEPTION_ASSERT_EQUALS(0,sbm.timeoutCount ()); } }