wxthread unit test synchronization.

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
rafae11
Experienced Solver
Experienced Solver
Posts: 85
Joined: Sat Jun 02, 2012 8:41 am

wxthread unit test synchronization.

Postby rafae11 » Wed Jul 04, 2018 11:07 am

I am trying to rewrite the unit test below so that it waits for the thread to finish and carry on the next test without a specified sleep time.
I was told to make the thread joinable, and remove the sleep.

I am currently struggling to synchronize the thread with the test suite. the program always crashes on CloseConnection(std::string("closing comports\n"));
because the thread is trying to post an event while the test has already moved on.

I was also advised to put a mutex, or a semaphore.
Would the mutex be a member of the test fixture or the thread?

Code: Select all

TEST_F(UserInterfaceTest, DownloadConfigurationVersion9)
{
   downloadconfigurationresponse = Response::GetDownloadConfigurationVersion9Response();

   downloadconfigurationcommand = commands.DownloadConfiguration(9);

   EXPECT_CALL(*m_View, SetNoteBookSelection(Display::SurveyPanel));
   EXPECT_CALL(*m_View, SaveFilePathDialog()).WillOnce(Return(wxID_OK));

   std::string val("C:\\Temp\\version9.bin");
   EXPECT_CALL(*m_View, GetSavePath()).WillOnce(Return(val));

   EXPECT_CALL(*m_Param, SetFunction(download_config));
   EXPECT_CALL(*m_Param, SetPathName(_));
   EXPECT_CALL(*m_Param, SetSurveyTimes(_));
   EXPECT_CALL(*m_Param, SetSurveyDelay(_));

   EXPECT_CALL(*m_Param, GetFunction()).WillOnce(Return(download_config));
   EXPECT_CALL(*m_Param, GetPathName()).WillOnce(Return(val));
   EXPECT_CALL(*m_Param, GetSurveyTimes()).WillOnce(Return(1));
   EXPECT_CALL(*m_Param, GetSurveyDelay()).WillOnce(Return(20));

   EXPECT_CALL(*m_View, CheckInstance(_, _));
   EXPECT_CALL(*m_View, GetSerialPortInstance()).WillRepeatedly(ReturnRef(serialport));
   EXPECT_CALL(*m_View, GetSerialPortAddress()).WillOnce(Return(port));

   EXPECT_CALL(*m_View, CustomEventDisplayData(_)).Times(AtLeast(1));

   EXPECT_CALL(serialport, Read(_))
      .WillOnce(DoAll(SetArgReferee<0>(downloadconfigurationresponse), Return(0)));

   EXPECT_CALL(masserialport, Write(_))
      .WillOnce(DoAll(SetArgReferee<0>(downloadconfigurationcommand), Return(0)));

   EXPECT_EQ(wxTHREAD_NO_ERROR, m_Controller->DownloadConfiguration());
   
   Sleep(1000);
   
}


Code: Select all

   CCThread(Iwxframeview* Parent,
              Iserial& Serial,
         IAdditionalParameters* AdditionalParameters)
      : wxThread(wxTHREAD_JOINABLE),
        m_Serial(Serial),
        m_AdditionalParameters(AdditionalParameters)

   {
      m_Parent = Parent;                                 // associated frame.
      m_Function = m_AdditionalParameters->GetFunction();         // function to be called      
      m_PathName = m_AdditionalParameters->GetPathName();         //pathname to download file.
      m_SurveyTime = m_AdditionalParameters->GetSurveyTimes();      // number of times to take survey
      m_SurveyDelay = m_AdditionalParameters->GetSurveyDelay();   // delay in seconds
   }


How do i make the test wait for this code to finish executing.

Code: Select all

wxThread::ExitCode CCThread::Entry()
{
   if (m_Function == download_config)
   {

      DownloadConfig(m_PathName);

      // program always crashes here without the Sleep.
      CloseConnection(std::string("closing comports\n"));

      return 0;
   }
}


I think i got it working now. Is this the correct approach?
I created a semaphore at the controller class which creates the thread.
I call semaphore.wait() in the unit test and call semaphore.post inside the thread.

Code: Select all

public:
   CCThread(Iwxframeview* Parent,
      Iserial& Serial,
      IAdditionalParameters* AdditionalParameters,
      wxSemaphore* Semaphore)

      : wxThread(wxTHREAD_JOINABLE),
        m_Serial(Serial),
        m_AdditionalParameters(AdditionalParameters),
        m_Semaphore(Semaphore)

   {
      m_Parent = Parent;                                 // associated frame.
      m_Function = m_AdditionalParameters->GetFunction();         // function to be called      
      m_PathName = m_AdditionalParameters->GetPathName();         //pathname to download file.
      m_SurveyTime = m_AdditionalParameters->GetSurveyTimes();      // number of times to take survey
      m_SurveyDelay = m_AdditionalParameters->GetSurveyDelay();   // delay in seconds
   }


Code: Select all

wxThread::ExitCode CCThread::Entry()
{
   if (m_Function == download_config)
   {

      DownloadConfig(m_PathName);

      CloseConnection(std::string("closing comports\n"));

      m_Semaphore->Post();

      return 0;
   }
}


Code: Select all

TEST_F(UserInterfaceTest, DownloadConfiguration)
{
       EXPECT_EQ(wxTHREAD_NO_ERROR, m_Controller->DownloadConfiguration());
   m_Controller->GetSemaphore()->Wait();
}

Return to “C++ Development”

Who is online

Users browsing this forum: Bing [Bot] and 26 guests