mirror of
https://github.com/OPM/ResInsight.git
synced 2026-08-26 21:27:15 -05:00
Fix crashes reported by crash telemetry
* Use guarded pointer for delayed plot updates The cached result definition can be deleted before the delayed update is executed, causing a crash in the PVT and relative permeability plot panels. * Guard against fracture definition without conductivity result The list of conductivity result names is empty for some fracture definitions, causing an out of range access when computing statistics. * Guard against missing data source in custom VFP plot The data source of a VFP table can be null, and the VFP tables are not available until the data has been imported.
This commit is contained in:
@@ -646,10 +646,11 @@ void RimCustomVfpPlot::onLoadDataAndUpdate()
|
||||
|
||||
for ( const auto& table : tables )
|
||||
{
|
||||
if ( !table ) continue;
|
||||
if ( !table || !table->dataSource() ) continue;
|
||||
|
||||
int tableNumber = table->tableNumber();
|
||||
auto vfpTables = table->dataSource()->vfpTables();
|
||||
if ( !vfpTables ) continue;
|
||||
|
||||
if ( table->tableType() == RimVfpDefines::TableType::INJECTION )
|
||||
{
|
||||
@@ -1445,7 +1446,8 @@ void RimCustomVfpPlot::scheduleReplot()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimCustomVfpPlot::familyValuesForTable( RimVfpTable* table ) const
|
||||
{
|
||||
if ( !table || !m_mainDataSource || !m_mainDataSource->dataSource() || !m_mainDataSource->dataSource()->vfpTables() ) return {};
|
||||
if ( !table || !table->dataSource() || !table->dataSource()->vfpTables() ) return {};
|
||||
if ( !m_mainDataSource || !m_mainDataSource->dataSource() || !m_mainDataSource->dataSource()->vfpTables() ) return {};
|
||||
|
||||
std::vector<double> mainTableFamilyValues = valuesForProductionType( m_familyVariable() );
|
||||
|
||||
|
||||
@@ -157,6 +157,7 @@ std::vector<double> RigEnsembleFractureStatisticsCalculator::calculateGridStatis
|
||||
{
|
||||
std::vector<double> samples;
|
||||
if ( fractureDefinitions.empty() ) return samples;
|
||||
if ( fractureDefinitions[0]->conductivityResultNames().isEmpty() ) return samples;
|
||||
|
||||
// TODO: heuristic to find conductivity name?
|
||||
QString conductivityResultName = fractureDefinitions[0]->conductivityResultNames()[0];
|
||||
@@ -255,6 +256,7 @@ std::vector<double> RigEnsembleFractureStatisticsCalculator::calculateAreaWeight
|
||||
{
|
||||
std::vector<double> samples;
|
||||
if ( fractureDefinitions.empty() ) return samples;
|
||||
if ( fractureDefinitions[0]->conductivityResultNames().isEmpty() ) return samples;
|
||||
|
||||
// TODO: heuristic to find conductivity name?
|
||||
QString conductivityResultName = fractureDefinitions[0]->conductivityResultNames()[0];
|
||||
|
||||
@@ -22,6 +22,7 @@ set(SOURCE_UNITTEST_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigEclipseCaseDataTools-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigEclipseCrossPlotDataExtractor-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigEclipseResultTools-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigEnsembleFractureStatisticsCalculator-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigMobilePoreVolumeResultCalculator-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigReservoir-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigResdataGridConverter-Test.cpp
|
||||
@@ -47,6 +48,7 @@ set(SOURCE_UNITTEST_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RigHexIntersectionTools-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/ObservedDataParser-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RicExpressionParser-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuPlotUpdater-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuQwtLinearScaleEngine-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RiuSummaryVectorDescriptionMap-Test.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/FixedWidthDataParser-Test.cpp
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "RigEnsembleFractureStatisticsCalculator.h"
|
||||
#include "RigStimPlanFractureDefinition.h"
|
||||
|
||||
#include <QStringList>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// A fracture definition without any conductivity result must not be indexed out of range
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST( RigEnsembleFractureStatisticsCalculatorTest, NoConductivityResultNames )
|
||||
{
|
||||
cvf::ref<RigStimPlanFractureDefinition> definition = new RigStimPlanFractureDefinition;
|
||||
EXPECT_TRUE( definition->conductivityResultNames().isEmpty() );
|
||||
|
||||
std::vector<cvf::ref<RigStimPlanFractureDefinition>> definitions = { definition };
|
||||
|
||||
for ( auto propertyType : RigEnsembleFractureStatisticsCalculator::propertyTypes() )
|
||||
{
|
||||
if ( propertyType == RigEnsembleFractureStatisticsCalculator::PropertyType::FORMATION_DIP ) continue;
|
||||
|
||||
auto values = RigEnsembleFractureStatisticsCalculator::calculateProperty( definitions, propertyType );
|
||||
EXPECT_TRUE( values.empty() );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "RimEclipseResultDefinition.h"
|
||||
|
||||
#include "Riu3dSelectionManager.h"
|
||||
#include "RiuPlotUpdater.h"
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
class TestPlotUpdater : public RiuPlotUpdater
|
||||
{
|
||||
public:
|
||||
void storeSelection( const RiuEclipseSelectionItem* selectionItem ) { storeDelayedInformation( selectionItem ); }
|
||||
|
||||
int queryCount() const { return m_queryCount; }
|
||||
|
||||
protected:
|
||||
void clearPlot() override {}
|
||||
QWidget* plotPanel() override { return nullptr; }
|
||||
|
||||
bool queryDataAndUpdatePlot( const RimEclipseResultDefinition* eclipseResDef, size_t, size_t, size_t ) override
|
||||
{
|
||||
m_queryCount++;
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
int m_queryCount = 0;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
/// The result definition can be deleted between the selection change and the delayed update
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST( RiuPlotUpdaterTest, DelayedUpdateAfterResultDefinitionIsDeleted )
|
||||
{
|
||||
auto* resultDefinition = new RimEclipseResultDefinition;
|
||||
|
||||
RiuEclipseSelectionItem selectionItem( nullptr,
|
||||
resultDefinition,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
cvf::Color3f( 1.0f, 0.0f, 0.0f ),
|
||||
cvf::StructGridInterface::NO_FACE,
|
||||
cvf::Vec3d::ZERO );
|
||||
|
||||
TestPlotUpdater plotUpdater;
|
||||
plotUpdater.storeSelection( &selectionItem );
|
||||
|
||||
delete resultDefinition;
|
||||
|
||||
plotUpdater.doDelayedUpdate();
|
||||
|
||||
EXPECT_EQ( 0, plotUpdater.queryCount() );
|
||||
}
|
||||
@@ -81,7 +81,7 @@ RiuEclipseSelectionItem* RiuPlotUpdater::extractEclipseSelectionItem( const RiuS
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuPlotUpdater::doDelayedUpdate()
|
||||
{
|
||||
if ( m_eclipseResultDef != nullptr )
|
||||
if ( m_eclipseResultDef.notNull() )
|
||||
{
|
||||
if ( !queryDataAndUpdatePlot( m_eclipseResultDef, m_timeStepIndex, m_gridIndex, m_gridLocalCellIndex ) )
|
||||
{
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "cafPdmPointer.h"
|
||||
|
||||
#include <QPointer>
|
||||
#include <QString>
|
||||
|
||||
@@ -61,8 +63,9 @@ protected:
|
||||
const Rim3dView* m_viewToFollowAnimationFrom;
|
||||
|
||||
// cached values for delayed plot updates
|
||||
const RimEclipseResultDefinition* m_eclipseResultDef;
|
||||
size_t m_timeStepIndex;
|
||||
size_t m_gridIndex;
|
||||
size_t m_gridLocalCellIndex;
|
||||
// Use a guarded pointer, as the result definition can be deleted before the delayed update is executed
|
||||
caf::PdmPointer<RimEclipseResultDefinition> m_eclipseResultDef;
|
||||
size_t m_timeStepIndex;
|
||||
size_t m_gridIndex;
|
||||
size_t m_gridLocalCellIndex;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user