/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* $Rev$ $Date$ */ /** * Test HTTP client functions. */ #include #include #include #include #include "stream.hpp" #include "string.hpp" #include "parallel.hpp" #include "perf.hpp" #include "../http/http.hpp" namespace tuscany { namespace server { string testURI = "http://localhost:8090/test"; bool testBlobs = true; ostream* curlWriter(const string& s, ostream* os) { (*os) << s; return os; } const bool testGet() { gc_scoped_pool pool; http::CURLSession ch; { ostringstream os; const failable > r = http::get(curlWriter, &os, "http://localhost:8090/index.html", ch); assert(hasContent(r)); assert(contains(str(os), "HTTP/1.1 200") || contains(str(os), "HTTP/1.0 200")); assert(contains(str(os), "It works")); } { const failable r = http::getcontent("http://localhost:8090/index.html", ch); assert(hasContent(r)); assert(contains(car(reverse(list(content(r)))), "It works")); } return true; } struct getLoop { http::CURLSession ch; getLoop(http::CURLSession& ch) : ch(ch) { } const bool operator()() const { const failable r = http::getcontent("http://localhost:8090/index.html", ch); assert(hasContent(r)); assert(contains(car(reverse(list(content(r)))), "It works")); return true; } }; const bool testGetPerf() { gc_scoped_pool pool; http::CURLSession ch; const lambda gl = getLoop(ch); cout << "Static GET test " << time(gl, 5, 200) << " ms" << endl; return true; } const bool testEval() { gc_scoped_pool pool; http::CURLSession ch; const value val = content(http::evalExpr(mklist(string("echo"), string("Hello")), testURI, ch)); assert(val == string("Hello")); return true; } struct evalLoop { const string uri; http::CURLSession ch; evalLoop(const string& uri, http::CURLSession& ch) : uri(uri), ch(ch) { } const bool operator()() const { const value val = content(http::evalExpr(mklist(string("echo"), string("Hello")), uri, ch)); assert(val == string("Hello")); return true; } }; const value blob(string(2048, 'A')); const list blobs = mklist(blob, blob); struct blobEvalLoop { const string uri; http::CURLSession ch; blobEvalLoop(const string& uri, http::CURLSession& ch) : uri(uri), ch(ch) { } const bool operator()() const { const value val = content(http::evalExpr(mklist(string("echo"), blobs), uri, ch)); assert(val == blobs); return true; } }; const bool testEvalPerf() { gc_scoped_pool pool; http::CURLSession ch; const lambda el = evalLoop(testURI, ch); cout << "JSON-RPC eval echo test " << time(el, 5, 200) << " ms" << endl; if (testBlobs) { const lambda bel = blobEvalLoop(testURI, ch); cout << "JSON-RPC eval blob test " << time(bel, 5, 200) << " ms" << endl; } return true; } bool testPost() { gc_scoped_pool pool; const list i = list() + (list() + "name" + string("Apple")) + (list() + "price" + string("$2.99")); const list a = mklist(string("item"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i); http::CURLSession ch; const failable id = http::post(a, testURI, ch); assert(hasContent(id)); return true; } struct postLoop { const string uri; const value val; http::CURLSession ch; postLoop(const string& uri, const value& val, http::CURLSession& ch) : uri(uri), val(val), ch(ch) { } const bool operator()() const { const failable id = http::post(val, uri, ch); assert(hasContent(id)); return true; } }; struct postBlobLoop { const string uri; const value val; http::CURLSession ch; postBlobLoop(const string& uri, const value& val, http::CURLSession& ch) : uri(uri), val(val), ch(ch) { } const bool operator()() const { gc_scoped_pool pool; const failable id = http::post(val, uri, ch); assert(hasContent(id)); return true; } }; const bool testPostPerf() { gc_scoped_pool pool; http::CURLSession ch; { const list i = list() + (list() + "name" + string("Apple")) + (list() + "price" + string("$2.99")); const list val = mklist(string("item"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i); const lambda pl = postLoop(testURI, val, ch); cout << "ATOMPub POST small test " << time(pl, 5, 200) << " ms" << endl; } if (testBlobs) { const list i = list() + (list() + "name" + string("Apple")) + (list() + "blob1" + blob) + (list() + "blob2" + blob) + (list() + "price" + string("$2.99")); const list val = mklist(string("item"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i); const lambda pl = postBlobLoop(testURI, val, ch); cout << "ATOMPub POST blob test " << time(pl, 5, 200) << " ms" << endl; } return true; } #ifdef WANT_THREADS const bool postThread(const string& uri, const int count, const value& val) { gc_scoped_pool pool; http::CURLSession ch; const lambda pl = postLoop(uri, val, ch); time(pl, 0, count); return true; } const list > startPost(worker& w, const int threads, const lambda& l) { if (threads == 0) return list >(); return cons(submit(w, l), startPost(w, threads - 1, l)); } const bool checkPost(const list >& r) { if (isNil(r)) return true; assert(car(r) == true); return checkPost(cdr(r)); } struct postThreadLoop { const lambda l; const int threads; const gc_ptr w; postThreadLoop(const lambda& l, const int threads) : l(l), threads(threads), w(new (gc_new()) worker(threads)) { } const bool operator()() const { list > r = startPost(*w, threads, l); checkPost(r); return true; } }; const bool testPostThreadPerf() { gc_scoped_pool pool; const int count = 50; const int threads = 10; const list i = list() + (list() + "name" + string("Apple")) + (list() + "price" + string("$2.99")); const value val = mklist(string("item"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i); const lambda pl= curry(lambda(postThread), testURI, count, val); const lambda ptl = postThreadLoop(pl, threads); double t = time(ptl, 0, 1) / (threads * count); cout << "ATOMPub POST thread test " << t << " ms" << endl; return true; } #else const bool postProc(const string& uri, const int count, const value& val) { gc_scoped_pool pool; http::CURLSession ch; const lambda pl = postLoop(uri, val, ch); time(pl, 0, count); return true; } const list startPost(const int procs, const lambda& l) { if (procs == 0) return list(); pid_t pid = fork(); if (pid == 0) { assert(l() == true); exit(0); } return cons(pid, startPost(procs - 1, l)); } const bool checkPost(const list& r) { if (isNil(r)) return true; int status; waitpid(car(r), &status, 0); assert(status == 0); return checkPost(cdr(r)); } struct postForkLoop { const lambda l; const int procs; postForkLoop(const lambda& l, const int procs) : l(l), procs(procs) { } const bool operator()() const { list r = startPost(procs, l); checkPost(r); return true; } }; const bool testPostForkPerf() { gc_scoped_pool pool; const int count = 50; const int procs = 10; const list i = list() + (list() + "name" + string("Apple")) + (list() + "price" + string("$2.99")); const value val = mklist(string("item"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i); const lambda pl= curry(lambda(postProc), testURI, count, val); const lambda ptl = postForkLoop(pl, procs); double t = time(ptl, 0, 1) / (procs * count); cout << "ATOMPub POST fork test " << t << " ms" << endl; return true; } #endif const bool testPut() { gc_scoped_pool pool; const list i = list() + (list() + "name" + string("Apple")) + (list() + "price" + string("$2.99")); const list a = mklist(string("item"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i); http::CURLSession ch; value rc = content(http::put(a, testURI + "/111", ch)); assert(rc == value(true)); return true; } const bool testDel() { gc_scoped_pool pool; http::CURLSession ch; value rc = content(http::del(testURI + "/111", ch)); assert(rc == value(true)); return true; } const bool testServer() { tuscany::server::testGet(); tuscany::server::testPost(); tuscany::server::testPut(); tuscany::server::testDel(); tuscany::server::testEval(); tuscany::server::testGetPerf(); tuscany::server::testPostPerf(); #ifdef WANT_THREADS tuscany::server::testPostThreadPerf(); #else tuscany::server::testPostForkPerf(); #endif tuscany::server::testEvalPerf(); return true; } } }