You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

452 lines
23 KiB

// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2020 Intel Corporation. All Rights Reserved.
////////////////////////////////////////////////
// Regressions tests against the known issues //
////////////////////////////////////////////////
#include <cmath>
#include "unit-tests-common.h"
#include "../include/librealsense2/rs_advanced_mode.hpp"
#include <librealsense2/hpp/rs_types.hpp>
#include <librealsense2/hpp/rs_frame.hpp>
#include <iostream>
#include <chrono>
#include <ctime>
#include <algorithm>
#include <librealsense2/rsutil.h>
using namespace rs2;
TEST_CASE("DSO-14512", "[live]")
{
{
rs2::log_to_file(RS2_LOG_SEVERITY_DEBUG,"lrs_log.txt");
//rs2::log_to_console(RS2_LOG_SEVERITY_DEBUG);
rs2::context ctx = make_context( SECTION_FROM_TEST_NAME );
if( ctx )
{
for (size_t iter = 0; iter < 10; iter++)
{
std::vector<rs2::device> list;
REQUIRE_NOTHROW(list = ctx.query_devices());
REQUIRE(list.size());
auto dev = list[0];
CAPTURE(dev.get_info(RS2_CAMERA_INFO_NAME));
disable_sensitive_options_for(dev);
std::mutex m;
int fps = is_usb3(dev) ? 30 : 15; // In USB2 Mode the devices will switch to lower FPS rates
for (auto i = 0; i < 1000; i++)
{
std::map<std::string, size_t> frames_per_stream{};
std::map<std::string, size_t> frames_indx_per_stream{};
std::vector<std::string> drop_descriptions;
auto profiles = configure_all_supported_streams(dev, 640, 480, fps);
size_t drops_count=0;
for (auto s : profiles.first)
{
REQUIRE_NOTHROW(s.start([&m, &frames_per_stream,&frames_indx_per_stream,&drops_count,&drop_descriptions](rs2::frame f)
{
std::lock_guard<std::mutex> lock(m);
auto stream_name = f.get_profile().stream_name();
auto fn = f.get_frame_number();
if (frames_per_stream[stream_name])
{
auto prev_fn = frames_indx_per_stream[stream_name];
if ((fn = prev_fn) != 1)
{
drops_count++;
std::stringstream s;
s << "Frame drop was recognized for " << stream_name<< " jumped from " << prev_fn << " to " << fn;
drop_descriptions.emplace_back(s.str().c_str());
}
}
++frames_per_stream[stream_name];
frames_indx_per_stream[stream_name] = fn;
}));
}
std::this_thread::sleep_for(std::chrono::seconds(60));
// Stop & flush all active sensors. The separation is intended to semi-confirm the FPS
for (auto s : profiles.first)
REQUIRE_NOTHROW(s.stop());
for (auto s : profiles.first)
REQUIRE_NOTHROW(s.close());
// Verify frames arrived for all the profiles specified
std::stringstream active_profiles, streams_arrived;
active_profiles << "Profiles requested : " << profiles.second.size() << std::endl;
for (auto& pf : profiles.second)
active_profiles << pf << std::endl;
streams_arrived << "Streams recorded : " << frames_per_stream.size() << std::endl;
for (auto& frec : frames_per_stream)
streams_arrived << frec.first << ": frames = " << frec.second << std::endl;
CAPTURE(active_profiles.str().c_str());
CAPTURE(streams_arrived.str().c_str());
REQUIRE(profiles.second.size() == frames_per_stream.size());
std::stringstream s;
s << "Streaming cycle " << i << " iteration " << iter << " completed,\n"
<< active_profiles.str() << std::endl << streams_arrived.str() << std::endl;
WARN(s.str().c_str());
if (drops_count)
{
std::stringstream s;
for (auto& str : drop_descriptions)
{
s << str << std::endl;
}
WARN("\n\n\n!!!!!!!!!!!!!!!!!!!!!!!!!!! " << drops_count << " Drop were identified !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n");
WARN(s.str().c_str());
REQUIRE(false);
}
}
if (dev.is<rs400::advanced_mode>())
{
auto advanced = dev.as<rs400::advanced_mode>();
if (advanced.is_enabled())
{
std::cout << "Iteration " << iter << " ended, resetting device..." << std::endl;
advanced.hardware_reset();
std::this_thread::sleep_for(std::chrono::seconds(3));
}
}
else
{
FAIL("Device doesn't support AdvancedMode API");
}
}
}
}
}
TEST_CASE("Frame Drops", "[live]"){
{
rs2::context ctx = make_context( SECTION_FROM_TEST_NAME );
std::condition_variable cv;
std::mutex m;
if( ctx )
{
//rs2::log_to_console(RS2_LOG_SEVERITY_DEBUG);
rs2::log_to_file(RS2_LOG_SEVERITY_DEBUG,"lrs_frame_drops_repro.txt");
for (size_t iter = 0; iter < 1000; iter++)
{
std::vector<rs2::device> list;
REQUIRE_NOTHROW(list = ctx.query_devices(RS2_PRODUCT_LINE_ANY));
REQUIRE(list.size());
auto dev = list[0];
CAPTURE(dev.get_info(RS2_CAMERA_INFO_NAME));
disable_sensitive_options_for(dev);
std::mutex m;
size_t drops_count=0;
bool all_streams = true;
int fps = is_usb3(dev) ? 60 : 15; // In USB2 Mode the devices will switch to lower FPS rates
float interval_msec = 1000.f / fps;
for (auto i = 0; i < 200; i++)
{
std::map<std::string, size_t> frames_per_stream{};
std::map<std::string, size_t> last_frame_per_stream{};
std::map<std::string, double> last_frame_ts_per_stream{};
std::map<std::string, rs2_timestamp_domain> last_ts_domain_per_stream{};
std::vector<std::string> drop_descriptions;
bool iter_finished =false;
int width = 848;
int height = 480;
auto profiles = configure_all_supported_streams(dev, width, height, fps);
drops_count=0;
auto start_time = std::chrono::high_resolution_clock::now();
std::stringstream ss;
ss << "Iteration " << i << " started, time = " << std::dec << start_time.time_since_epoch().count() << std::endl;
std::string syscl = "echo \"timecheck: $(date +%s.%N) = $(date +%FT%T,%N)\" | sudo tee /dev/kmsg";
auto r = system(syscl.c_str());
ss << "sys call result = " << r;
rs2::log(RS2_LOG_SEVERITY_INFO,ss.str().c_str());
std::cout << ss.str().c_str() << std::endl;
for (auto s : profiles.first)
{
REQUIRE_NOTHROW(s.start([&m, &frames_per_stream,&last_frame_per_stream,&last_frame_ts_per_stream,&last_ts_domain_per_stream,&drops_count,
&drop_descriptions,&cv,&all_streams,&iter_finished,start_time,profiles,interval_msec,syscl](rs2::frame f)
{
auto time_elapsed = std::chrono::duration<double, std::milli>(std::chrono::high_resolution_clock::now() - start_time);
auto stream_name = f.get_profile().stream_name();
auto fn = f.get_frame_number();
auto ts = f.get_timestamp();
auto ts_dom = f.get_frame_timestamp_domain();
if (frames_per_stream[stream_name])
{
auto prev_fn = last_frame_per_stream[stream_name];
auto prev_ts = last_frame_ts_per_stream[stream_name];
auto prev_ts_dom = last_ts_domain_per_stream[stream_name];
auto delta_t = ts - prev_ts;
auto min_delay = interval_msec*3.5;
auto max_delay = interval_msec*20;
auto arrival_time = std::chrono::duration<double, std::milli>(std::chrono::high_resolution_clock::now() - start_time);
// Skip events during the first 2 second
if (time_elapsed.count() > 2000)
{
if (RS2_FORMAT_MOTION_XYZ32F != f.get_profile().format())
{
if (/*!(fn > prev_fn) ||*/
((delta_t >= min_delay) && (RS2_TIMESTAMP_DOMAIN_SYSTEM_TIME !=ts_dom) && (ts_dom ==prev_ts_dom)))
{
if ((fn - prev_fn) > 1)
drops_count++;
std::stringstream s;
s << "Frame drop was recognized for " << stream_name << " jump from fn " << prev_fn << " to fn " << fn
<< " from " << std::fixed << std::setprecision(3) << prev_ts << " to "
<< ts << " while expected ts = " << (prev_ts + interval_msec)
<< ", ts domain " << ts_dom
<< " time elapsed: " << time_elapsed.count()/1000.f << " sec, host time: "
<< std::chrono::high_resolution_clock::now().time_since_epoch().count();
if (f.supports_frame_metadata(RS2_FRAME_METADATA_FRAME_TIMESTAMP))
s << " hw ts: " << f.get_frame_metadata(RS2_FRAME_METADATA_FRAME_TIMESTAMP) << " = 0x"
<< std::hex << f.get_frame_metadata(RS2_FRAME_METADATA_FRAME_TIMESTAMP) << std::dec;
WARN(s.str().c_str());
if ((delta_t < max_delay) || (fabs(fn - prev_fn)< 20)) // Skip inconsistent frame numbers due to intermittent metadata
{
std::cout << "Frame interval = " << delta_t << ", max = " << max_delay << std::endl;
std::cout << "fn = " << fn << ", prev_fn = " << prev_fn << std::endl;
system(syscl.c_str());
exit(1);
}
drop_descriptions.emplace_back(s.str().c_str());
}
}
// if (profiles.second.size() != frames_per_stream.size()) // Some streams failed to start
// {
// all_streams = false;
// }
}
// Status prints
auto sec_now = int(arrival_time.count()) / 1000;
if (sec_now && (sec_now != (int(time_elapsed.count())/ 1000)) )
std::cout << "Test runs for " << int(arrival_time.count()) / 1000 << " seconds" << std::endl;
// Every 10th second print number of frames arrived
if ((int(arrival_time.count()) / 10000) != (int(time_elapsed.count())/ 10000) )
{
std::stringstream s;
s << "Frames arrived: ";
for (const auto& entry : frames_per_stream)
s << entry.first << " : " << entry.second << ", ";
s << std::endl;
std::cout << s.str().c_str();
}
// Stop test iteration after 20 sec
if (arrival_time.count() > 20000)
{
std::lock_guard<std::mutex> lock(m);
iter_finished = true;
cv.notify_all();
}
time_elapsed = arrival_time;
}
++frames_per_stream[stream_name];
last_frame_per_stream[stream_name] = fn;
last_frame_ts_per_stream[stream_name] = ts;
{
std::lock_guard<std::mutex> lock(m);
if (drops_count || (!all_streams))
cv.notify_all();
}
}));
}
// block till error is reproduced
{
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, [&drops_count,&all_streams,&iter_finished]{return (drops_count>0 || (!all_streams) || iter_finished);});
//std::this_thread::sleep_for(std::chrono::milliseconds(200)); // add some sleep to record additional errors, if any
}
std::cout << "Drops = " << drops_count << ", All streams valid = " << int(all_streams) << " iter completed = " << int(iter_finished) << std::endl;
// Stop & flush all active sensors. The separation is intended to semi-confirm the FPS
for (auto s : profiles.first)
REQUIRE_NOTHROW(s.stop());
for (auto s : profiles.first)
REQUIRE_NOTHROW(s.close());
// Verify frames arrived for all the profiles specified
std::stringstream active_profiles, streams_arrived;
active_profiles << "Profiles requested : " << profiles.second.size() << std::endl;
for (auto& pf : profiles.second)
active_profiles << pf << std::endl;
streams_arrived << "Streams recorded : " << frames_per_stream.size() << std::endl;
for (auto& frec : frames_per_stream)
streams_arrived << frec.first << ": frames = " << frec.second << std::endl;
CAPTURE(active_profiles.str().c_str());
CAPTURE(streams_arrived.str().c_str());
std::stringstream s;
s << "Streaming cycle " << i << " iteration " << iter << " completed,\n"
<< active_profiles.str() << std::endl << streams_arrived.str() << std::endl;
WARN(s.str().c_str());
if (drops_count)
{
std::stringstream s;
for (auto& str : drop_descriptions)
{
s << str << std::endl;
}
WARN("\n!!! " << drops_count << " Drop were identified !!!\n");
WARN(s.str().c_str());
}
REQUIRE(profiles.second.size() == frames_per_stream.size());
//REQUIRE( drops_count == 0);
REQUIRE( all_streams);
}
if (dev.is<rs400::advanced_mode>())
{
auto advanced = dev.as<rs400::advanced_mode>();
if (advanced.is_enabled())
{
std::cout << "Iteration " << iter << " ended, resetting device..." << std::endl;
advanced.hardware_reset();
std::this_thread::sleep_for(std::chrono::seconds(3));
}
}
else
{
FAIL("Device doesn't support AdvancedMode API");
}
}
}
}
}
TEST_CASE("DSO-15050", "[live]")
{
{
rs2::log_to_file(RS2_LOG_SEVERITY_DEBUG, "lrs_log.txt");
//rs2::log_to_console(RS2_LOG_SEVERITY_DEBUG);
rs2::context ctx = make_context( SECTION_FROM_TEST_NAME );
if( ctx )
{
for (size_t iter = 0; iter < 10000; iter++)
{
std::vector<rs2::device> list;
REQUIRE_NOTHROW(list = ctx.query_devices());
REQUIRE(list.size());
auto dev = std::make_shared<device>(list.front());
disable_sensitive_options_for(*dev);
CAPTURE(dev->get_info(RS2_CAMERA_INFO_NAME));
std::string serial;
REQUIRE_NOTHROW(serial = dev->get_info(RS2_CAMERA_INFO_SERIAL_NUMBER));
// Precausion
for (auto&& sensor : dev->query_sensors())
{
if (sensor.supports(RS2_OPTION_GLOBAL_TIME_ENABLED))
sensor.set_option(RS2_OPTION_GLOBAL_TIME_ENABLED, 0.f);
}
std::mutex m;
int fps = is_usb3(*dev) ? 30 : 6; // In USB2 Mode the devices will switch to lower FPS rates
for (auto i = 0; i < 1; i++)
{
std::map<std::string, size_t> frames_per_stream{};
std::map<std::string, size_t> frames_indx_per_stream{};
std::vector<std::string> drop_descriptions;
auto profiles = configure_all_supported_streams(*dev, 1280, 720, fps);
size_t drops_count = 0;
for (auto s : profiles.first)
{
REQUIRE_NOTHROW(s.start([&m, &frames_per_stream, &frames_indx_per_stream, &drops_count, &drop_descriptions](rs2::frame f)
{
std::lock_guard<std::mutex> lock(m);
auto stream_name = f.get_profile().stream_name();
auto fn = f.get_frame_number();
if (frames_per_stream[stream_name])
{
auto prev_fn = frames_indx_per_stream[stream_name];
if ((fn = prev_fn) != 1)
{
drops_count++;
std::stringstream s;
s << "Frame drop was recognized for " << stream_name << " jumped from " << prev_fn << " to " << fn;
drop_descriptions.emplace_back(s.str().c_str());
}
}
++frames_per_stream[stream_name];
frames_indx_per_stream[stream_name] = fn;
}));
}
std::this_thread::sleep_for(std::chrono::seconds(2));
// Stop & flush all active sensors. The separation is intended to semi-confirm the FPS
for (auto s : profiles.first)
REQUIRE_NOTHROW(s.stop());
for (auto s : profiles.first)
REQUIRE_NOTHROW(s.close());
// Verify frames arrived for all the profiles specified
std::stringstream active_profiles, streams_arrived;
active_profiles << "Profiles requested : " << profiles.second.size() << std::endl;
for (auto& pf : profiles.second)
active_profiles << pf << std::endl;
streams_arrived << "Streams recorded : " << frames_per_stream.size() << std::endl;
for (auto& frec : frames_per_stream)
streams_arrived << frec.first << ": frames = " << frec.second << std::endl;
CAPTURE(active_profiles.str().c_str());
CAPTURE(streams_arrived.str().c_str());
REQUIRE(profiles.second.size() == frames_per_stream.size());
std::stringstream s;
s << "Streaming cycle " << i << " iteration " << iter << " completed,\n"
<< active_profiles.str() << std::endl << streams_arrived.str() << std::endl;
WARN(s.str().c_str());
if (drops_count)
{
std::stringstream s;
for (auto& str : drop_descriptions)
{
s << str << std::endl;
}
WARN("\n\n\n!!!!!!!!!!!!!!!!!!!!!!!!!!! " << drops_count << " Drop were identified !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\n");
WARN(s.str().c_str());
//REQUIRE(false);
}
}
//forcing hardware reset to simulate device disconnection
do_with_waiting_for_camera_connection(ctx, dev, serial, [&]()
{
dev->hardware_reset();
std::cout << "Iteration " << iter << " ended, resetting device..." << std::endl;
});
}
}
}
}