Make Most Unit Tests Independent of LibECL

This commit switches a set of OPM-Common's unit tests away from
using direct calls to libecl functions and into using base types
from OPM-Common itself (along with Boost.Filesystem).

In particular summary related queries are replaced by calls to ESmry
member functions (wrapped in libecl-like interfaces to minimise code
changes).  We disable checks on unit strings since ESmry currently
does not have a way of associating those with individual variables.
This commit is contained in:
Bård Skaflestad 2019-10-11 01:16:22 -05:00
parent bcfe700461
commit c013639b51
7 changed files with 157 additions and 82 deletions

66
tests/WorkArea.cpp Normal file
View File

@ -0,0 +1,66 @@
/*
Copyright 2019 Equinor ASA.
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
// NOTE: This file is inteded to be copy-pasted into user code
// through an #include statement.
#include <string>
#include <boost/filesystem.hpp>
namespace {
class WorkArea
{
public:
explicit WorkArea(const std::string& subdir = "")
: root_(boost::filesystem::temp_directory_path() /
boost::filesystem::unique_path("wrk-%%%%"))
, area_(root_)
, orig_(boost::filesystem::current_path())
{
if (! subdir.empty())
this->area_ /= subdir;
boost::filesystem::create_directories(this->area_);
boost::filesystem::current_path(this->area_);
}
void copyIn(const std::string& filename) const
{
boost::filesystem::copy_file(this->orig_ / filename,
this->area_ / filename);
}
void makeSubDir(const std::string& dirname)
{
boost::filesystem::create_directories(this->area_ / dirname);
}
~WorkArea()
{
boost::filesystem::current_path(this->orig_);
boost::filesystem::remove_all(this->root_);
}
private:
boost::filesystem::path root_;
boost::filesystem::path area_;
boost::filesystem::path orig_;
};
} // Anonymous

View File

@ -17,22 +17,19 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdexcept>
#include <iostream>
#include <boost/filesystem.hpp>
#define BOOST_TEST_MODULE WTEST
#define BOOST_TEST_MODULE MSIM_BASIC
#include <boost/test/unit_test.hpp>
#include <ert/util/test_work_area.h>
#include <ert/util/util.h>
#include <ert/ecl/ecl_sum.hpp>
#include <ert/ecl/ecl_file.hpp>
#include <ert/ecl/ecl_file_view.hpp>
#include <ert/ecl/ecl_rsthead.hpp>
#include <opm/msim/msim.hpp>
#include <stdexcept>
#include <iostream>
#include <boost/filesystem.hpp>
#include <opm/io/eclipse/ERst.hpp>
#include <opm/io/eclipse/ESmry.hpp>
#include <opm/output/data/Wells.hpp>
#include <opm/output/eclipse/EclipseIO.hpp>
#include <opm/parser/eclipse/Units/Units.hpp>
@ -41,8 +38,11 @@
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>
#include <opm/parser/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
#include <tests/WorkArea.cpp>
using namespace Opm;
namespace {
double prod_opr(const EclipseState& es, const Schedule& /* sched */, const SummaryState&, const data::Solution& /* sol */, size_t /* report_step */, double seconds_elapsed) {
const auto& units = es.getUnits();
@ -59,6 +59,13 @@ void pressure(const EclipseState& es, const Schedule& /* sched */, data::Solutio
std::fill(data.begin(), data.end(), units.to_si(UnitSystem::measure::pressure, seconds_elapsed));
}
bool is_file(const boost::filesystem::path& name)
{
return boost::filesystem::exists(name)
&& boost::filesystem::is_regular_file(name);
}
}
BOOST_AUTO_TEST_CASE(RUN) {
Parser parser;
@ -71,45 +78,35 @@ BOOST_AUTO_TEST_CASE(RUN) {
msim.well_rate("PROD", data::Rates::opt::oil, prod_opr);
msim.solution("PRESSURE", pressure);
{
test_work_area_type * work_area = test_work_area_alloc("test_msim");
const WorkArea work_area("test_msim");
EclipseIO io(state, state.getInputGrid(), schedule, summary_config);
msim.run(schedule, io, false);
for (const auto& fname : {"SPE1CASE1.INIT", "SPE1CASE1.UNRST", "SPE1CASE1.EGRID", "SPE1CASE1.SMSPEC", "SPE1CASE1.UNSMRY"})
BOOST_CHECK( util_is_file( fname ));
BOOST_CHECK( is_file( fname ));
{
ecl_sum_type * ecl_sum = ecl_sum_fread_alloc_case("SPE1CASE1", ":");
int param_index = ecl_sum_get_general_var_params_index(ecl_sum, "WOPR:PROD");
for (int time_index=0; time_index < ecl_sum_get_data_length(ecl_sum); time_index++) {
double seconds_elapsed = ecl_sum_iget_sim_days(ecl_sum, time_index) * 86400;
double opr = ecl_sum_iget(ecl_sum, time_index, param_index);
BOOST_CHECK_CLOSE(seconds_elapsed, opr, 1e-3);
const auto smry = EclIO::ESmry("SPE1CASE1");
const auto& time = smry.get("TIME");
const auto& press = smry.get("WOPR:PROD");
for (auto nstep = time.size(), time_index=0*nstep; time_index < nstep; time_index++) {
double seconds_elapsed = time[time_index] * 86400;
BOOST_CHECK_CLOSE(seconds_elapsed, press[time_index], 1e-3);
}
ecl_sum_free( ecl_sum );
}
{
int report_step = 1;
ecl_file_type * rst_file = ecl_file_open("SPE1CASE1.UNRST", 0);
ecl_file_view_type * global_view = ecl_file_get_global_view( rst_file );
while (true) {
ecl_file_view_type * rst_view = ecl_file_view_add_restart_view( global_view, -1, report_step, -1, -1);
if (!rst_view)
break;
auto rst = EclIO::ERst("SPE1CASE1.UNRST");
{
ecl_rsthead_type * rst_head = ecl_rsthead_alloc( rst_view, report_step);
const ecl_kw_type * p = ecl_file_view_iget_named_kw(rst_view, "PRESSURE", 0);
BOOST_CHECK_CLOSE( ecl_kw_iget_float(p, 0), rst_head->sim_days * 86400, 1e-3 );
ecl_rsthead_free( rst_head );
}
report_step++;
for (const auto& step : rst.listOfReportStepNumbers()) {
const auto& dh = rst.getRst<double>("DOUBHEAD", step);
const auto& press = rst.getRst<float>("PRESSURE", step);
// DOUBHEAD[0] is elapsed time in days since start of simulation.
BOOST_CHECK_CLOSE( press[0], dh[0] * 86400, 1e-3 );
}
ecl_file_close(rst_file);
}
test_work_area_free( work_area );
}
}

View File

@ -17,16 +17,14 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdexcept>
#include <iostream>
#define BOOST_TEST_MODULE ACTIONX_SIM
#include <boost/test/unit_test.hpp>
#include <ert/util/test_work_area.h>
#include <ert/ecl/ecl_sum.hpp>
#include <opm/msim/msim.hpp>
#include <stdexcept>
#include <iostream>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
@ -40,13 +38,15 @@
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
#include <opm/parser/eclipse/Parser/ErrorGuard.hpp>
#include <opm/io/eclipse/ESmry.hpp>
#include <opm/output/eclipse/EclipseIO.hpp>
#include <opm/msim/msim.hpp>
#include <tests/WorkArea.cpp>
using namespace Opm;
namespace {
struct test_data {
Deck deck;
@ -118,6 +118,33 @@ double inj_wir_INJ(const EclipseState& , const Schedule& sched, const SummarySta
return -99;
}
bool ecl_sum_has_general_var(const EclIO::ESmry& smry, const std::string& var)
{
return smry.hasKey(var);
}
float ecl_sum_get_general_var(const EclIO::ESmry& smry, const int timeIdx, const std::string& var)
{
return smry.get(var)[timeIdx];
}
int ecl_sum_get_data_length(const EclIO::ESmry& smry)
{
return static_cast<int>(smry.get("TIME").size());
}
int ecl_sum_get_last_report_step(const EclIO::ESmry& smry)
{
return static_cast<int>(smry.get_at_rstep("TIME").size());
}
int ecl_sum_iget_report_end(const EclIO::ESmry& smry, const int reportStep)
{
return smry.timestepIdxAtReportstepStart(reportStep + 1) - 1;
}
}
/*
The deck tested here has a UDQ DEFINE statement which sorts the wells after
oil production rate, and then subsequently closes the well with lowest OPR
@ -130,7 +157,7 @@ BOOST_AUTO_TEST_CASE(UDQ_SORTA_EXAMPLE) {
test_data td( actionx );
msim sim(td.state);
{
test_work_area_type * work_area = test_work_area_alloc("test_msim");
WorkArea work_area("test_msim");
EclipseIO io(td.state, td.state.getInputGrid(), td.schedule, td.summary_config);
sim.well_rate("P1", data::Rates::opt::oil, prod_opr);
@ -151,8 +178,6 @@ BOOST_AUTO_TEST_CASE(UDQ_SORTA_EXAMPLE) {
BOOST_CHECK(w1.getStatus() == Well2::Status::OPEN );
BOOST_CHECK(w4.getStatus() == Well2::Status::SHUT );
}
test_work_area_free(work_area);
}
}
@ -163,7 +188,7 @@ BOOST_AUTO_TEST_CASE(WELL_CLOSE_EXAMPLE) {
test_data td( actionx1 );
msim sim(td.state);
{
test_work_area_type * work_area = test_work_area_alloc("test_msim");
WorkArea work_area("test_msim");
EclipseIO io(td.state, td.state.getInputGrid(), td.schedule, td.summary_config);
sim.well_rate("P1", data::Rates::opt::oil, prod_opr);
@ -208,8 +233,6 @@ BOOST_AUTO_TEST_CASE(WELL_CLOSE_EXAMPLE) {
BOOST_CHECK(w4_10.getStatus() == Well2::Status::OPEN );
BOOST_CHECK(w4_11.getStatus() == Well2::Status::SHUT );
}
test_work_area_free(work_area);
}
}
@ -219,7 +242,7 @@ BOOST_AUTO_TEST_CASE(UDQ_ASSIGN) {
test_data td( actionx1 );
msim sim(td.state);
{
test_work_area_type * work_area = test_work_area_alloc("test_msim");
WorkArea work_area("test_msim");
EclipseIO io(td.state, td.state.getInputGrid(), td.schedule, td.summary_config);
sim.well_rate("P1", data::Rates::opt::oil, prod_opr);
@ -236,14 +259,16 @@ BOOST_AUTO_TEST_CASE(UDQ_ASSIGN) {
const auto& base_name = td.state.getIOConfig().getBaseName();
ecl_sum_type * ecl_sum = ecl_sum_fread_alloc_case( base_name.c_str(), ":");
const EclIO::ESmry ecl_sum(base_name + ".SMSPEC");
BOOST_CHECK( ecl_sum_has_general_var(ecl_sum, "WUBHP:P1") );
BOOST_CHECK( ecl_sum_has_general_var(ecl_sum, "WUBHP:P2") );
BOOST_CHECK( ecl_sum_has_general_var(ecl_sum, "WUOPRL:P3") );
BOOST_CHECK( ecl_sum_has_general_var(ecl_sum, "WUOPRL:P4") );
#if 0
BOOST_CHECK_EQUAL( ecl_sum_get_unit(ecl_sum, "WUBHP:P1"), "BARSA");
BOOST_CHECK_EQUAL( ecl_sum_get_unit(ecl_sum, "WUOPRL:P1"), "SM3/DAY");
#endif
BOOST_CHECK_EQUAL( ecl_sum_get_general_var(ecl_sum, 1, "WUBHP:P1"), 11);
BOOST_CHECK_EQUAL( ecl_sum_get_general_var(ecl_sum, 1, "WUBHP:P2"), 12);
@ -254,9 +279,6 @@ BOOST_AUTO_TEST_CASE(UDQ_ASSIGN) {
BOOST_CHECK_EQUAL( ecl_sum_get_general_var(ecl_sum, 1, "WUOPRL:P2"), 20);
BOOST_CHECK_EQUAL( ecl_sum_get_general_var(ecl_sum, 1, "WUOPRL:P3"), 20);
BOOST_CHECK_EQUAL( ecl_sum_get_general_var(ecl_sum, 1, "WUOPRL:P4"), 20);
ecl_sum_free( ecl_sum );
test_work_area_free(work_area);
}
}
@ -266,7 +288,7 @@ BOOST_AUTO_TEST_CASE(UDQ_WUWCT) {
test_data td( actionx1 );
msim sim(td.state);
{
test_work_area_type * work_area = test_work_area_alloc("test_msim");
WorkArea work_area("test_msim");
EclipseIO io(td.state, td.state.getInputGrid(), td.schedule, td.summary_config);
sim.well_rate("P1", data::Rates::opt::oil, prod_opr);
@ -282,7 +304,7 @@ BOOST_AUTO_TEST_CASE(UDQ_WUWCT) {
sim.run(td.schedule, io, false);
const auto& base_name = td.state.getIOConfig().getBaseName();
ecl_sum_type * ecl_sum = ecl_sum_fread_alloc_case( base_name.c_str(), ":");
const EclIO::ESmry ecl_sum(base_name + ".SMSPEC");
for (int step = 0; step < ecl_sum_get_data_length(ecl_sum); step++) {
double wopr_sum = 0;
@ -300,9 +322,6 @@ BOOST_AUTO_TEST_CASE(UDQ_WUWCT) {
ecl_sum_get_general_var(ecl_sum, step, "FUOPR"));
BOOST_CHECK_EQUAL( wopr_sum, ecl_sum_get_general_var(ecl_sum, step, "FOPR"));
}
test_work_area_free(work_area);
}
}
@ -319,15 +338,16 @@ BOOST_AUTO_TEST_CASE(UDA) {
sim.well_rate("P4", data::Rates::opt::wat, prod_wpr_P4);
sim.well_rate("INJ", data::Rates::opt::wat, inj_wir_INJ);
{
ecl::util::TestArea ta("uda_sim");
WorkArea work_area("uda_sim");
sim.run(td.schedule, io, true);
const auto& base_name = td.state.getIOConfig().getBaseName();
ecl_sum_type * ecl_sum = ecl_sum_fread_alloc_case( base_name.c_str(), ":");
const EclIO::ESmry ecl_sum(base_name + ".SMSPEC");
// Should only get at report steps
for (int report_step = 2; report_step < ecl_sum_get_last_report_step(ecl_sum); report_step++) {
const auto last_report = ecl_sum_get_last_report_step(ecl_sum);
for (int report_step = 2; report_step < last_report; report_step++) {
double wwpr_sum = 0;
{
int prev_tstep = ecl_sum_iget_report_end(ecl_sum, report_step - 1);
@ -338,7 +358,5 @@ BOOST_AUTO_TEST_CASE(UDA) {
}
BOOST_CHECK_CLOSE( 0.90 * wwpr_sum, ecl_sum_get_general_var(ecl_sum, ecl_sum_iget_report_end(ecl_sum, report_step), "WWIR:INJ"), 1e-3);
}
ecl_sum_free( ecl_sum );
}
}

View File

@ -26,8 +26,6 @@
#include <boost/test/unit_test.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <ert/util/util.h>
#include <opm/parser/eclipse/EclipseState/Grid/EclipseGrid.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/SummaryState.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Schedule.hpp>

View File

@ -30,8 +30,6 @@
#include <boost/test/unit_test.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
//#include <ert/util/test_work_area.h>
#include <opm/parser/eclipse/Units/UnitSystem.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>

View File

@ -17,11 +17,7 @@
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#define BOOST_TEST_MODULE InitConfigTests
#include <sys/stat.h>
#include <sys/types.h>
#include <boost/test/unit_test.hpp>
@ -31,7 +27,7 @@
#include <opm/parser/eclipse/EclipseState/InitConfig/InitConfig.hpp>
#include <opm/parser/eclipse/Units/Units.hpp>
#include <ert/util/test_work_area.hpp>
#include <tests/WorkArea.cpp>
using namespace Opm;
@ -188,8 +184,10 @@ BOOST_AUTO_TEST_CASE( EquilOperations ) {
}
BOOST_AUTO_TEST_CASE(RestartCWD) {
test_work_area_type * work_area = test_work_area_alloc("restart_cwd");
mkdir("simulation", 0777);
WorkArea output_area;
output_area.makeSubDir("simulation");
{
std::fstream fs;
fs.open ("simulation/CASE.DATA", std::fstream::out);
@ -229,8 +227,6 @@ BOOST_AUTO_TEST_CASE(RestartCWD) {
Opm::InitConfig init_config(deck);
BOOST_CHECK_EQUAL(init_config.getRestartRootName(), "/abs/path/BASE");
}
test_work_area_free(work_area);
}
// --------------------------------------------------------------------

View File

@ -21,8 +21,6 @@ along with OPM. If not, see <http://www.gnu.org/licenses/>.
#include <boost/test/unit_test.hpp>
#include <ert/ecl/ecl_util.h>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/EclipseState/Runspec.hpp>
#include <opm/parser/eclipse/Parser/Parser.hpp>
@ -60,6 +58,10 @@ BOOST_AUTO_TEST_CASE(TwoPhase) {
BOOST_CHECK( !phases.active( Phase::GAS ) );
BOOST_CHECK( phases.active( Phase::WATER ) );
BOOST_CHECK( !phases.active( Phase::POLYMW ) );
const auto ECL_OIL_PHASE = 1 << 0;
const auto ECL_WATER_PHASE = 1 << 2;
BOOST_CHECK_EQUAL( ECL_OIL_PHASE + ECL_WATER_PHASE , runspec.eclPhaseMask( ));
}