TestEnvironmentTest.C 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /*
  2. * Copyright (C) 2011 Emweb bvba, Kessel-Lo, Belgium.
  3. *
  4. * See the LICENSE file for terms of use.
  5. */
  6. #include <Wt/WConfig.h>
  7. #ifdef WT_THREADED
  8. #include <boost/test/unit_test.hpp>
  9. #include <boost/thread.hpp>
  10. #include <boost/thread/condition.hpp>
  11. #include <Wt/WApplication>
  12. #include <Wt/WContainerWidget>
  13. #include <Wt/WPushButton>
  14. #include <Wt/WProgressBar>
  15. #include <Wt/Test/WTestEnvironment>
  16. using namespace Wt;
  17. namespace {
  18. class BigWorkWidget : public Wt::WContainerWidget
  19. {
  20. public:
  21. BigWorkWidget(Wt::WContainerWidget *parent)
  22. : WContainerWidget(parent)
  23. {
  24. startButton_ = new Wt::WPushButton("Start", this);
  25. startButton_->setObjectName("startbutton");
  26. startButton_->clicked().connect(startButton_, &Wt::WPushButton::disable);
  27. startButton_->clicked().connect(this, &BigWorkWidget::startBigWork);
  28. startButton_->setMargin(2);
  29. progress_ = new Wt::WProgressBar(this);
  30. progress_->setObjectName("progress");
  31. progress_->setInline(false);
  32. progress_->setMinimum(0);
  33. progress_->setMaximum(20);
  34. progress_->setMargin(2);
  35. }
  36. virtual ~BigWorkWidget() {
  37. workThread_.join();
  38. }
  39. private:
  40. Wt::WPushButton *startButton_;
  41. Wt::WProgressBar *progress_;
  42. boost::thread workThread_;
  43. void startBigWork() {
  44. Wt::WApplication *app = Wt::WApplication::instance();
  45. // Enable server push
  46. app->enableUpdates(true);
  47. workThread_
  48. = boost::thread(boost::bind(&BigWorkWidget::doBigWork, this, app));
  49. progress_->setValue(0);
  50. startButton_->setText("Busy...");
  51. }
  52. /*
  53. * This function runs from another thread.
  54. *
  55. * From within this thread, we cannot use WApplication::instance(),
  56. * since that use thread-local storage. We can only access
  57. * WApplication::instance() after we have grabbed its update-lock.
  58. */
  59. void doBigWork(Wt::WApplication *app)
  60. {
  61. for (unsigned i = 0; i < 20; ++i) {
  62. // Do 50 ms of hard work.
  63. boost::this_thread::sleep(boost::posix_time::milliseconds(50));
  64. // Get the application update lock to update the user-interface
  65. // with a progress indication.
  66. Wt::WApplication::UpdateLock uiLock(app);
  67. if (uiLock) {
  68. progress_->setValue(i + 1);
  69. app->triggerUpdate();
  70. }
  71. }
  72. Wt::WApplication::UpdateLock uiLock(app);
  73. if (uiLock) {
  74. startButton_->enable();
  75. startButton_->setText("Again!");
  76. app->triggerUpdate();
  77. // Disable server push
  78. app->enableUpdates(false);
  79. }
  80. }
  81. };
  82. }
  83. BOOST_AUTO_TEST_CASE( test_serverpush_test )
  84. {
  85. Wt::Test::WTestEnvironment environment;
  86. Wt::WApplication app(environment);
  87. BigWorkWidget *bw = new BigWorkWidget(app.root());
  88. Wt::WPushButton *b
  89. = dynamic_cast<Wt::WPushButton *>(app.findWidget("startbutton"));
  90. Wt::WProgressBar *bar
  91. = dynamic_cast<Wt::WProgressBar *>(app.findWidget("progress"));
  92. b->clicked().emit(Wt::WMouseEvent());
  93. environment.endRequest();
  94. for (;;) {
  95. boost::this_thread::sleep(boost::posix_time::milliseconds(50));
  96. std::cerr << "Progress: " << bar->value() << std::endl;
  97. if (b->isEnabled())
  98. break;
  99. }
  100. environment.startRequest();
  101. }
  102. #endif // WT_THREADED