123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- <!--#
- Test 3: Multiple database queries
- This test is a variation of Test #2 and also uses the World table. Multiple rows are fetched to more dramatically
- punish the database driver and connection pool. At the highest queries-per-request tested (20), this test demonstrates
- all frameworks' convergence toward zero requests-per-second as database activity increases.
- Requirements
- 1. For every request, an integer query string parameter named queries must be retrieved from the request.
- The parameter specifies the number of database queries to execute in preparing the HTTP response (see below).
- 2. The recommended URI is /queries.
- 3. The queries parameter must be bounded to between 1 and 500. If the parameter is missing, is not an integer,
- or is an integer less than 1, the value should be interpreted as 1; if greater than 500, the value should be interpreted as 500.
- 3. The schema for World is id (int, primary key) and randomNumber (int).
- 4. The request handler must retrieve a set of World objects, equal in count to the queries parameter, from the World database table.
- 5. Each row must be selected randomly in the same fashion as the single database query test (Test #2 above).
- 6. Since this test is designed to exercise multiple queries, each row must be selected individually by a query.
- It is not acceptable to retrieve all required rows using a SELECT ... WHERE id IN (...) clause.
- 7. Each World object must be added to a list or array.
- 8. The list or array must be serialized to JSON and sent as a response.
- 9. The response content type must be set to application/json.
- 10. The response headers must include either Content-Length or Transfer-Encoding.
- 11. The response headers must include Server and Date.
- 12. Use of an in-memory cache of World objects or rows by the application is not permitted.
- 13. Use of prepared statements for SQL database tests (e.g., for MySQL) is encouraged but not required.
- 14. gzip compression is not permitted.
- 15. Server support for HTTP Keep-Alive is strongly encouraged but not required.
- 16. If HTTP Keep-Alive is enabled, no maximum Keep-Alive timeout is specified by this test.
- 17. The request handler will be exercised at 256 concurrency only.
- 18. The request handler will be exercised with query counts of 1, 5, 10, 15, and 20.
- 19. The request handler will be exercised using GET requests.
- Example request:
- GET /queries?queries=10 HTTP/1.1
- Host: server
- User-Agent: Mozilla/5.0 (X11; Linux x86_64) Gecko/20130501 Firefox/30.0 AppleWebKit/600.00 Chrome/30.0.0000.0 Trident/10.0 Safari/600.00
- Cookie: uid=12345678901234567890; __utma=1.1234567890.1234567890.1234567890.1234567890.12; wd=2560x1600
- Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
- Accept-Language: en-US,en;q=0.5
- Connection: keep-alive
- Example response:
- HTTP/1.1 200 OK
- Content-Type: application/json; charset=UTF-8
- Content-Length: 315
- Server: Example
- Date: Wed, 17 Apr 2013 12:00:00 GMT
- [{"id":4174,"randomNumber":331},{"id":51,"randomNumber":6544},{"id":4462,"randomNumber":952},{"id":2221,"randomNumber":532},{"id":9276,"randomNumber":3097},{"id":3056,"randomNumber":7293},{"id":6964,"randomNumber":620},{"id":675,"randomNumber":6601},{"id":8414,"randomNumber":6569},{"id":2753,"randomNumber":4065}]
- -->
- <!--#declaration
- #include "world.h"
- #define AS_cpoll_cppsp_DO
- #ifndef AS_cpoll_cppsp_DO
- static UValue* pvalue;
- #endif
- static UOrmSession* psql_queries;
- static UOrmStatement* pstmt_queries;
- static World* pworld_queries;
- static UVector<World*>* pvworld_queries;
- static void usp_init_queries()
- {
- U_TRACE(5, "::usp_init_queries()")
- psql_queries = U_NEW(UOrmSession(U_CONSTANT_TO_PARAM("hello_world")));
- pstmt_queries = U_NEW(UOrmStatement(*psql_queries, U_CONSTANT_TO_PARAM("SELECT randomNumber FROM World WHERE id = ?")));
- if (pstmt_queries == 0) U_ERROR("usp_init_queries(): we cound't connect to db, exiting...");
- pworld_queries = U_NEW(World);
- pvworld_queries = U_NEW(UVector<World*>(500));
- pstmt_queries->use( pworld_queries->id);
- pstmt_queries->into(pworld_queries->randomNumber);
- #ifndef AS_cpoll_cppsp_DO
- pvalue = U_NEW(UValue(ARRAY_VALUE));
- #endif
- }
- static void usp_end_queries()
- {
- U_TRACE(5, "::usp_end_queries()")
- delete pstmt_queries;
- delete psql_queries;
- delete pvworld_queries;
- delete pworld_queries;
- #ifndef AS_cpoll_cppsp_DO
- delete pvalue;
- #endif
- }
- -->
- <!--#args
- queries;
- -->
- <!--#header
- Content-Type: application/json; charset=UTF-8
- -->
- <!--#code
- int i = 0, num_queries = queries.strtol();
- if (num_queries < 1) num_queries = 1;
- else if (num_queries > 500) num_queries = 500;
- #ifdef AS_cpoll_cppsp_DO
- USP_PUTS_CHAR('[');
- #endif
- while (true)
- {
- pworld_queries->id = u_get_num_random(10000);
- pstmt_queries->execute();
- #ifdef AS_cpoll_cppsp_DO
- USP_PRINTF("{\"id\":%d,\"randomNumber\":%d}", pworld_queries->id, pworld_queries->randomNumber);
- #endif
- pvworld_queries->push_back(U_NEW(World(*pworld_queries)));
- if (++i == num_queries) break;
- #ifdef AS_cpoll_cppsp_DO
- USP_PUTS_CHAR(',');
- #endif
- }
- #ifdef AS_cpoll_cppsp_DO
- USP_PUTS_CHAR(']');
- #else
- USP_JSON_stringify(*pvalue, UVector<World*>, *pvworld_queries);
- #endif
- pvworld_queries->clear();
- -->
|