mirror of
https://github.com/OPM/ResInsight.git
synced 2026-10-26 23:20:29 -05:00
Removing a source case makes a delta ensemble recreate and delete its derived cases. Those cases are part of the list being removed, leaving dangling pointers that crash in PdmObjectHandle::prepareForDelete(). Use guarded pointers and return only the surviving cases.
89 lines
3.0 KiB
C++
89 lines
3.0 KiB
C++
#include "gtest/gtest.h"
|
|
|
|
#include "Summary/RiaSummaryTools.h"
|
|
|
|
#include "RigCaseRealizationParameters.h"
|
|
|
|
#include "RimDeltaSummaryEnsemble.h"
|
|
#include "RimMockSummaryCase.h"
|
|
#include "RimSummaryCaseMainCollection.h"
|
|
#include "RimSummaryEnsemble.h"
|
|
|
|
#include "cafPdmPointer.h"
|
|
|
|
#include <algorithm>
|
|
#include <memory>
|
|
#include <vector>
|
|
|
|
namespace
|
|
{
|
|
RimSummaryCase* createMockCase( int realizationNumber )
|
|
{
|
|
auto* summaryCase = new RimMockSummaryCase();
|
|
|
|
auto parameters = std::make_shared<RigCaseRealizationParameters>();
|
|
parameters->setRealizationNumber( realizationNumber );
|
|
summaryCase->setCaseRealizationParameters( parameters );
|
|
|
|
return summaryCase;
|
|
}
|
|
} // namespace
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
/// Removing a source case makes a delta ensemble recreate and delete derived cases. The derived cases
|
|
/// are part of the list of cases to remove, and must not be left as dangling pointers in that list.
|
|
//--------------------------------------------------------------------------------------------------
|
|
TEST( RimSummaryCaseMainCollection, RemoveCasesReferredByDeltaEnsemble )
|
|
{
|
|
RimSummaryCaseMainCollection* mainCollection = RiaSummaryTools::summaryCaseMainCollection();
|
|
|
|
auto* ensemble1 = mainCollection->addEnsemble( { createMockCase( 0 ), createMockCase( 1 ) }, "Ensemble 1", true );
|
|
auto* ensemble2 = mainCollection->addEnsemble( { createMockCase( 0 ), createMockCase( 1 ) }, "Ensemble 2", true );
|
|
|
|
auto* deltaEnsemble = new RimDeltaSummaryEnsemble();
|
|
mainCollection->addEnsemble( deltaEnsemble );
|
|
deltaEnsemble->setEnsemble1( ensemble1 );
|
|
deltaEnsemble->setEnsemble2( ensemble2 );
|
|
deltaEnsemble->createDerivedEnsembleCases();
|
|
|
|
EXPECT_EQ( size_t( 2 ), deltaEnsemble->allSummaryCases().size() );
|
|
|
|
auto cases = mainCollection->allSummaryCases();
|
|
EXPECT_EQ( size_t( 6 ), cases.size() );
|
|
|
|
// Guarded pointers are set to null when the object is deleted
|
|
std::vector<caf::PdmPointer<RimSummaryCase>> guardedCases( cases.begin(), cases.end() );
|
|
|
|
mainCollection->removeCases( cases );
|
|
|
|
size_t aliveCount = 0;
|
|
for ( const auto& guardedCase : guardedCases )
|
|
{
|
|
if ( guardedCase.notNull() ) aliveCount++;
|
|
}
|
|
|
|
// The two derived cases are deleted by the delta ensemble during removal
|
|
EXPECT_EQ( size_t( 4 ), aliveCount );
|
|
EXPECT_EQ( aliveCount, cases.size() );
|
|
|
|
// No deleted case is left behind in the list
|
|
for ( auto* summaryCase : cases )
|
|
{
|
|
auto isAlive = [summaryCase]( const caf::PdmPointer<RimSummaryCase>& guardedCase )
|
|
{ return guardedCase.notNull() && guardedCase.p() == summaryCase; };
|
|
EXPECT_TRUE( std::any_of( guardedCases.begin(), guardedCases.end(), isAlive ) );
|
|
}
|
|
|
|
for ( auto* summaryCase : cases )
|
|
{
|
|
delete summaryCase;
|
|
}
|
|
|
|
mainCollection->removeEnsemble( deltaEnsemble );
|
|
mainCollection->removeEnsemble( ensemble1 );
|
|
mainCollection->removeEnsemble( ensemble2 );
|
|
delete deltaEnsemble;
|
|
delete ensemble1;
|
|
delete ensemble2;
|
|
}
|