ChipMaster's trial hacks on C++CMS starting with v1.2.1. Not sure I'll follow on with the v2 since it looks to be breaking and mostly frivolous.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

182 lines
4.7 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (C) 2008-2012 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com>
  4. //
  5. // See accompanying file COPYING.TXT file for licensing details.
  6. //
  7. ///////////////////////////////////////////////////////////////////////////////
  8. #include <cppcms/service.h>
  9. #include <cppcms/application.h>
  10. #include <cppcms/applications_pool.h>
  11. #include <cppcms/http_request.h>
  12. #include <cppcms/http_response.h>
  13. #include <cppcms/http_context.h>
  14. #include <cppcms/url_dispatcher.h>
  15. #include <cppcms/mount_point.h>
  16. #include <cppcms/json.h>
  17. #include <iostream>
  18. #include "client.h"
  19. #include "test.h"
  20. int bad_count = 0;
  21. int calls = 0;
  22. class unit_test : public cppcms::application {
  23. public:
  24. unit_test(cppcms::service &s) : cppcms::application(s)
  25. {
  26. }
  27. virtual void main(std::string /*unused*/)
  28. {
  29. calls ++;
  30. bool bad_found = false;
  31. std::ostream &out = response().out();
  32. for(unsigned i=0;i<10000000;i++) {
  33. if(!(out << i << '\n')) {
  34. bad_found = true;
  35. break;
  36. }
  37. }
  38. if(bad_found) {
  39. std::cout << "Disconned as expected" << std::endl;
  40. bad_count++;
  41. }
  42. else {
  43. std::cout << "Not disconnected!" << std::endl;
  44. }
  45. }
  46. };
  47. class async_unit_test : public cppcms::application {
  48. public:
  49. async_unit_test(cppcms::service &s) : cppcms::application(s)
  50. {
  51. dispatcher().assign("/single",&async_unit_test::single,this);
  52. dispatcher().assign("/multiple",&async_unit_test::multiple,this);
  53. }
  54. struct binder {
  55. booster::shared_ptr<cppcms::http::context> context;
  56. int counter;
  57. void operator()(cppcms::http::context::completion_type ct)
  58. {
  59. if(ct == cppcms::http::context::operation_aborted) {
  60. bad_count++;
  61. return;
  62. }
  63. if(counter > 0) {
  64. counter --;
  65. std::ostream &out = context->response().out();
  66. for(unsigned i=0;i<1000;i++) {
  67. out << i << '\n';
  68. }
  69. context->async_flush_output(*this);
  70. }
  71. else {
  72. context->async_complete_response();
  73. }
  74. }
  75. };
  76. void multiple()
  77. {
  78. calls ++;
  79. binder call;
  80. call.context = release_context();
  81. call.counter = 10000;
  82. call(cppcms::http::context::operation_completed);
  83. }
  84. void single()
  85. {
  86. calls ++;
  87. std::ostream &out = response().out();
  88. for(unsigned i=0;i<100000;i++) {
  89. out << i << '\n';
  90. }
  91. release_context()->async_complete_response();
  92. }
  93. };
  94. class nonblocking_unit_test : public cppcms::application {
  95. public:
  96. nonblocking_unit_test(cppcms::service &s) : cppcms::application(s)
  97. {
  98. }
  99. struct binder : public booster::callable<void(cppcms::http::context::completion_type ct)> {
  100. typedef booster::intrusive_ptr<binder> self_ptr;
  101. booster::shared_ptr<cppcms::http::context> context;
  102. int counter;
  103. binder(booster::shared_ptr<cppcms::http::context> ctx) :
  104. context(ctx),
  105. counter(0)
  106. {
  107. }
  108. void run()
  109. {
  110. (*this)(cppcms::http::context::operation_completed);
  111. }
  112. void operator()(cppcms::http::context::completion_type ct)
  113. {
  114. if(ct == cppcms::http::context::operation_aborted) {
  115. std::cout << "Error on completion detected" << std::endl;
  116. bad_count++;
  117. return;
  118. }
  119. std::ostream &out = context->response().out();
  120. for(;counter < 100000;counter++) {
  121. out << counter << '\n';
  122. if(!out) {
  123. std::cout << "Error on stream detected" << std::endl;
  124. bad_count++;
  125. return;
  126. }
  127. if(context->response().pending_blocked_output()) {
  128. std::cout << "Got blocking status at" << counter << std::endl;
  129. context->async_flush_output(self_ptr(this));
  130. return;
  131. }
  132. }
  133. std::cout << "No error detected" << std::endl;
  134. context->async_complete_response();
  135. }
  136. };
  137. void main(std::string)
  138. {
  139. response().setbuf(0);
  140. response().full_asynchronous_buffering(false);
  141. calls ++;
  142. binder::self_ptr p(new binder(release_context()));
  143. p->run();
  144. }
  145. };
  146. int main(int argc,char **argv)
  147. {
  148. try {
  149. cppcms::service srv(argc,argv);
  150. booster::intrusive_ptr<cppcms::application> async = new async_unit_test(srv);
  151. booster::intrusive_ptr<cppcms::application> nb = new nonblocking_unit_test(srv);
  152. srv.applications_pool().mount( async, cppcms::mount_point("/async") );
  153. srv.applications_pool().mount( nb, cppcms::mount_point("/nonblocking") );
  154. srv.applications_pool().mount( cppcms::applications_factory<unit_test>(), cppcms::mount_point("/sync"));
  155. srv.after_fork(submitter(srv));
  156. srv.run();
  157. }
  158. catch(std::exception const &e) {
  159. std::cerr << e.what() << std::endl;
  160. return EXIT_FAILURE;
  161. }
  162. if(bad_count != 4 || calls != 5) {
  163. std::cerr << "Failed bad_count = " << bad_count << " (exp 4) calls = " << calls << " (exp 5)"<< std::endl;
  164. return EXIT_FAILURE;
  165. }
  166. std::cout << "Ok" << std::endl;
  167. return EXIT_SUCCESS;
  168. }