10 #include <gmock/gmock.h> 
   11 #include <gtest/gtest.h> 
   12 #include <log4cplus/logger.h> 
   21 using namespace ::testing;
 
   25 class RecStatusFake : 
public recif::RecStatus {
 
   27     RecStatusFake(std::string 
id, recif::RecStatusNames status, std::vector<std::string> files)
 
   28         : m_id(std::move(id)), m_status(status), m_files(std::move(files)) {
 
   30     virtual std::vector<std::string> getDpFiles()
 const override {
 
   33     virtual void setDpFiles(
const std::vector<std::string>& dp_files)
 override {
 
   37     virtual double getEndTime()
 const override {
 
   40     virtual void setEndTime(
double end_time)
 override {
 
   43     virtual int32_t getFilesGenerated()
 const override {
 
   44         return m_files.size();
 
   46     virtual void setFilesGenerated(int32_t files_generated)
 override {
 
   49     virtual int32_t getFramesProcessed()
 const override {
 
   52     virtual void setFramesProcessed(int32_t frames_processed)
 override {
 
   55     virtual int32_t getFramesRemaining()
 const override {
 
   58     virtual void setFramesRemaining(int32_t frames_remaining)
 override {
 
   61     virtual std::string getId()
 const override {
 
   64     virtual void setId(
const std::string& 
id)
 override {
 
   68     virtual std::string getInfo()
 const override {
 
   71     virtual void setInfo(
const std::string& info)
 override {
 
   74     virtual double getRemainingTime()
 const override {
 
   77     virtual void setRemainingTime(
double remaining_time)
 override {
 
   80     virtual int32_t getSizeRecorded()
 const override {
 
   83     virtual void setSizeRecorded(int32_t size_recorded)
 override {
 
   86     virtual double getStartTime()
 const override {
 
   89     virtual void setStartTime(
double start_time)
 override {
 
   92     virtual ::recif::RecStatusNames getStatus()
 const override {
 
   95     virtual void setStatus(::recif::RecStatusNames status)
 override {
 
   99     virtual double getTimeElapsed()
 const override {
 
  102     virtual void setTimeElapsed(
double time_elapsed)
 override {
 
  104     bool hasKey()
 const override {
 
  107     std::unique_ptr<recif::RecStatus> cloneKey()
 const override {
 
  108         throw std::runtime_error(
"not clonable");
 
  110     std::unique_ptr<recif::RecStatus> clone()
 const override {
 
  111         throw std::runtime_error(
"not clonable");
 
  113     bool keyEquals(
const recif::RecStatus& other)
 const override {
 
  119     recif::RecStatusNames m_status;
 
  120     std::vector<std::string> m_files;
 
  123 class RecWaitStatusFake : 
public recif::RecWaitStatus {
 
  125     RecWaitStatusFake(recif::RecWaitStatusNames wait_status, std::shared_ptr<recif::RecStatus> rec_status)
 
  126         : m_wait_status{wait_status}, m_rec_status{std::move(rec_status)} {
 
  128     std::shared_ptr<recif::RecStatus> getRecStatus()
 const override {
 
  132     recif::RecWaitStatusNames getStatus()
 const override {
 
  133         return m_wait_status;
 
  135     void setStatus(recif::RecWaitStatusNames wait_status)
 override {
 
  136         m_wait_status = wait_status;
 
  138     bool hasKey()
 const override {
 
  141     std::unique_ptr<recif::RecWaitStatus> cloneKey()
 const override {
 
  142         throw std::runtime_error(
"not clonable");
 
  144     std::unique_ptr<recif::RecWaitStatus> clone()
 const override {
 
  145         throw std::runtime_error(
"not clonable");
 
  147     bool keyEquals(
const recif::RecWaitStatus& other)
 const override {
 
  152     recif::RecWaitStatusNames m_wait_status;
 
  153     std::shared_ptr<recif::RecStatus> m_rec_status;
 
  162         auto status = std::make_shared<RecWaitStatusFake>(
 
  164             std::make_shared<RecStatusFake>(
 
  165                 m_id, recif::RecStatusNames::Active, std::vector<std::string>()));
 
  169         auto status = std::make_shared<RecWaitStatusFake>(
 
  171             std::make_shared<RecStatusFake>(
 
  172                 m_id, recif::RecStatusNames::Completed, std::vector<std::string>{
"/file1.fits", 
"/file2.fits"}));
 
  182     boost::promise<std::shared_ptr<recif::RecWaitStatus>> prim_promise_1;
 
  183     boost::promise<std::shared_ptr<recif::RecWaitStatus>> prim_promise_2;
 
  184     auto reply_1 = MakeWaitCompletedStatus();
 
  185     auto reply_2 = MakeWaitCompletedStatus();
 
  186     EXPECT_CALL(*m_prim_rr_client, RecWait(_))
 
  187         .WillOnce(Return(ByMove(prim_promise_1.get_future())));
 
  188     EXPECT_CALL(*m_prim_rr_client2, RecWait(_))
 
  189         .WillOnce(Return(ByMove(prim_promise_2.get_future())));
 
  192     auto fut = op::InitiateOperation<op::AwaitPrimAsync>(MakeAwaitOpParams());
 
  194     prim_promise_1.set_value(reply_1);
 
  195     prim_promise_2.set_value(reply_2);
 
  200     ASSERT_TRUE(fut.is_ready());
 
  201     ASSERT_FALSE(fut.has_exception()) << 
"Future has unexpected exception!";
 
  202     auto result = fut.get();
 
  203     EXPECT_FALSE(result.error) << 
"There should have been no errors as each request was successful";
 
  204     EXPECT_EQ(result.result.size(), 4u) << 
"Each primary source returned two files by default";
 
  209     boost::promise<std::shared_ptr<recif::RecWaitStatus>> prim_promise_1;
 
  210     boost::promise<std::shared_ptr<recif::RecWaitStatus>> prim_promise_2_1;
 
  211     boost::promise<std::shared_ptr<recif::RecWaitStatus>> prim_promise_2_2;
 
  212     auto reply_1 = MakeWaitCompletedStatus();
 
  213     auto reply_2_1 = MakeWaitNotCompletedStatus();
 
  214     auto reply_2_2 = MakeWaitCompletedStatus();
 
  215     EXPECT_CALL(*m_prim_rr_client, RecWait(_))
 
  216         .WillOnce(Return(ByMove(prim_promise_1.get_future())));
 
  217     EXPECT_CALL(*m_prim_rr_client2, RecWait(_))
 
  218         .WillOnce(Return(ByMove(prim_promise_2_1.get_future())))
 
  219         .WillOnce(Return(ByMove(prim_promise_2_2.get_future())));
 
  222     auto fut = op::InitiateOperation<op::AwaitPrimAsync>(MakeAwaitOpParams());
 
  224     prim_promise_1.set_value(reply_1);
 
  225     prim_promise_2_1.set_value(reply_2_1);
 
  229     ASSERT_FALSE(fut.is_ready());
 
  231     prim_promise_2_2.set_value(reply_2_2);
 
  236     ASSERT_TRUE(fut.is_ready());
 
  237     ASSERT_FALSE(fut.has_exception()) << 
"Future has unexpected exception!";
 
  238     auto result = fut.get();
 
  239     EXPECT_FALSE(result.error) << 
"There should have been no errors as each request was successful";
 
  240     EXPECT_EQ(result.result.size(), 4u) << 
"Each primary source returned two files by default";
 
  244     boost::promise<std::shared_ptr<recif::RecWaitStatus>> prim_promise_1;
 
  245     boost::promise<std::shared_ptr<recif::RecWaitStatus>> prim_promise_2_1;
 
  246     boost::promise<std::shared_ptr<recif::RecWaitStatus>> prim_promise_2_2;
 
  247     auto reply_1 = MakeWaitCompletedStatus();
 
  248     auto reply_2_2 = MakeWaitCompletedStatus();
 
  249     EXPECT_CALL(*m_prim_rr_client, RecWait(_))
 
  250         .WillOnce(Return(ByMove(prim_promise_1.get_future())));
 
  251     EXPECT_CALL(*m_prim_rr_client2, RecWait(_))
 
  252         .WillOnce(Return(ByMove(prim_promise_2_1.get_future())))
 
  253         .WillOnce(Return(ByMove(prim_promise_2_2.get_future())));
 
  256     auto fut = op::InitiateOperation<op::AwaitPrimAsync>(MakeAwaitOpParams());
 
  258     prim_promise_1.set_value(reply_1);
 
  259     prim_promise_2_1.set_exception(recif::ExceptionErr(
"random error", 1));
 
  263     ASSERT_FALSE(fut.is_ready());
 
  265     prim_promise_2_2.set_value(reply_2_2);
 
  270     ASSERT_TRUE(fut.is_ready());
 
  271     ASSERT_FALSE(fut.has_exception()) << 
"Future has unexpected exception!";
 
  272     auto result = fut.get();
 
  273     EXPECT_TRUE(result.error) << 
"A erors as each request was successful";
 
  274     EXPECT_EQ(result.result.size(), 4u) << 
"Each primary source returned two files by default";
 
  278     boost::promise<std::shared_ptr<recif::RecWaitStatus>> prim_promise_1;
 
  279     boost::promise<std::shared_ptr<recif::RecWaitStatus>> prim_promise_2_1;
 
  280     boost::promise<std::shared_ptr<recif::RecWaitStatus>> prim_promise_2_2;
 
  281     auto reply_1 = MakeWaitCompletedStatus();
 
  282     auto reply_2_2 = MakeWaitCompletedStatus();
 
  283     EXPECT_CALL(*m_prim_rr_client, RecWait(_))
 
  284         .WillOnce(Return(ByMove(prim_promise_1.get_future())));
 
  285     EXPECT_CALL(*m_prim_rr_client2, RecWait(_))
 
  286         .WillOnce(Return(ByMove(prim_promise_2_1.get_future())));
 
  289     auto [fut, abort] = op::InitiateAbortableOperation<op::AwaitPrimAsync>(MakeAwaitOpParams());
 
  291     prim_promise_1.set_value(reply_1);
 
  292     prim_promise_2_1.set_exception(recif::ExceptionErr(
"random error", 1));
 
  296     ASSERT_FALSE(fut.is_ready());
 
  300     EXPECT_TRUE(abort());
 
  303     EXPECT_TRUE(fut.is_ready()) << 
"aborting operation should immediately set operation result";
 
  305     ASSERT_FALSE(fut.has_exception()) << 
"Future has unexpected exception!";
 
  306     auto result = fut.get();
 
  307     EXPECT_TRUE(result.error) << 
"Operation was completed with error (exception from source)";
 
  308     EXPECT_EQ(result.result.size(), 2u) << 
"Only result from first source was received before " 
  312     prim_promise_2_2.set_value(reply_1);