/* * 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 core utils. */ #include #include #include #include #include #include #include "function.hpp" #include "list.hpp" #include "slist.hpp" #include "parallel.hpp" #include "value.hpp" #include "element.hpp" #include "xml.hpp" #include "monad.hpp" namespace tuscany { struct inc { int i; inc(int i) : i(i) { } const int operator()(const int x) const { return x + i; } }; const int square(const int x) { return x * x; } int mapLambda(lambda f, int v) { return f(v); } bool testLambda() { const lambda sq(square); assert(sq(2) == 4); assert(mapLambda(sq, 2) == 4); assert(mapLambda(square, 2) == 4); const lambda incf(inc(10)); assert(incf(1) == 11); assert(mapLambda(incf, 1) == 11); assert(mapLambda(inc(10), 1) == 11); lambda l; l = incf; assert(l(1) == 11); l = square; assert(l(2) == 4); return true; } bool testLambdaGC() { resetLambdaCounters(); testLambda(); assert(countLambdas == 0); return true; } int countElements = 0; struct Element { int i; Element() : i(0) { countElements++; } Element(int i) : i(i) { countElements++; } Element(const Element& o) : i(o.i) { countElements++; } ~Element() { countElements--; } const bool operator==(const Element& o) const { return o.i == i; } }; bool testCons() { assert(car(cons(2, mklist(3))) == 2); assert(car(cdr(cons(2, mklist(3)))) == 3); assert(isNil(cdr(cdr(cons(2, mklist(3)))))); assert(cons(Element(1), mklist(Element(2))) == mklist(Element(1), Element(2))); return true; } bool testSet() { list l = mklist(1, 2, 3); setCar(l, 4); setCdr(l, mklist(5, 6)); assert(car(l) == 4); assert(cadr(l) == 5); assert(caddr(l) == 6); assert(isNil(cdddr(l))); return true; } bool testListGC() { resetLambdaCounters(); resetListCounters(); countElements = 0; testCons(); testSet(); assert(countLambdas == 0); assert(countlists == 0); assert(countElements == 0); return true; } bool testOut() { std::ostringstream os1; os1 << list (); assert(os1.str() == "()"); std::ostringstream os2; os2 << mklist(1, 2, 3); assert(os2.str() == "(1 2 3)"); return true; } bool testEquals() { assert(list() == list()); assert(mklist(1, 2) == mklist(1, 2)); assert(list() != mklist(1, 2)); assert(mklist(1, 2, 3) == mklist(1, 2, 3)); assert(mklist(1, 2) != mklist(1, 2, 3)); return true; } bool testLength() { assert(0 == length(list())); assert(1 == length(mklist(1))); assert(2 == length(cons(1, mklist(2)))); return true; } bool testAppend() { assert(car(append(mklist(1), mklist(2))) == 1); assert(car(cdr(append(mklist(1), mklist(2)))) == 2); assert(car(cdr(cdr(append(mklist(1), mklist(2, 3))))) == 3); assert(isNil(cdr(cdr(cdr(append(mklist(1), mklist(2, 3))))))); list l; l << 1 << 2 << 3; assert(l == mklist(1, 2, 3)); assert(list() << 1 << 2 << 3 == mklist(1, 2, 3)); return true; } struct Complex { int x; int y; Complex() { } Complex(int x, int y) : x(x), y(y) { } }; bool testComplex() { const list p = mklist(Complex(1, 2), Complex(3, 4)); assert(car(p).x == 1); assert(car(cdr(p)).x == 3); assert(isNil(cdr(cdr(p)))); return true; } bool testMap() { assert(isNil(map(square, list()))); const list m = map(square, mklist(2, 3)); assert(car(m) == 4); assert(car(cdr(m)) == 9); return true; } const int add(const int x, const int y) { return x + y; } bool testReduce() { const lambda r(add); assert(reduce(r, 0, mklist(1, 2, 3)) == 6); return true; } bool isPositive(int x) { if(x >= 0) return true; else return false; } bool testFilter() { assert(car(filter(isPositive, mklist(1, -1, 2, -2))) == 1); assert(cadr(filter(isPositive, mklist(1, -1, 2, -2))) == 2); return true; } bool testMember() { assert(isNil(member(4, mklist(1, 2, 3)))); assert(car(member(1, mklist(1, 2, 3))) == 1); assert(car(member(2, mklist(1, 2, 3))) == 2); assert(car(member(3, mklist(1, 2, 3))) == 3); return true; } bool testReverse() { assert(isNil(reverse(list()))); assert(car(reverse(mklist(1, 2, 3))) == 3); assert(cadr(reverse(mklist(1, 2, 3))) == 2); return true; } bool testListRef() { assert(listRef(mklist(1), 0) == 1); assert(listRef(mklist(1, 2, 3), 0) == 1); assert(listRef(mklist(1, 2, 3), 1) == 2); assert(listRef(mklist(1, 2, 3), 2) == 3); return true; } bool testAssoc() { const list > l = mklist(mklist("x", "X"), mklist("a", "A"), mklist("y", "Y"), mklist("a", "AA")); assert(assoc("a", l) == mklist("a", "A")); assert(isNil(assoc("z", l))); const list > u = mklist(mklist("x", "X"), mklist("a", "A"), mklist("y", "Y"), mklist("a", "AA")); assert(assoc("a", u) == mklist("a", "A")); const list v = mklist(mklist("x", "X"), mklist("a", "A"), mklist("y", "Y"), mklist("a", "AA")); assert(assoc("a", v) == mklist("a", "A")); return true; } bool testZip() { const list k = mklist("x", "a", "y", "a"); const list v = mklist("X", "A", "Y", "AA"); const list > z = mklist(k, v); const list > u = mklist(mklist("x", "X"), mklist("a", "A"), mklist("y", "Y"), mklist("a", "AA")); assert(zip(k, v) == u); assert(unzip(u) == z); return true; } bool testTokenize() { assert(tokenize("/", "aaa/bbb/ccc/ddd") == mklist("aaa", "bbb", "ccc", "ddd")); assert(tokenize("/", "/bbb/ccc/ddd") == mklist("", "bbb", "ccc", "ddd")); assert(tokenize("/", "/bbb/ccc/") == mklist("", "bbb", "ccc")); assert(tokenize("/", "/bbb//ccc/") == mklist("", "bbb", "", "ccc")); assert(tokenize("/", "abc/def/") == mklist("abc", "def")); return true; } double testSeqMap(double x) { return x; } double testSeqReduce(double v, double accum) { return accum + 1.0; } bool testSeq() { resetLambdaCounters(); resetListCounters(); list s = seq(0.0, 1000.0); assert(1001 == length(s)); //printLambdaCounters(); //printListCounters(); assert(1001 == length(map(testSeqMap, s))); assert(801 == length(member(200.0, s))); assert(201 == length(member(200.0, reverse(s)))); assert(1001 == (reduce(testSeqReduce, 0.0, s))); //printLambdaCounters(); //printListCounters(); return true; } value valueSquare(list x) { return (int)car(x) * (int)car(x); } bool testValue() { assert(value(true) == value(true)); assert(value(1) == value(1)); assert(value("abcd") == value("abcd")); lambda&)> vl(valueSquare); assert(value(vl) == value(vl)); assert(value(mklist(1, 2)) == value(mklist(1, 2))); const list v = mklist(mklist("x", "X"), mklist("a", "A"), mklist("y", "Y")); assert(cadr((list >)value(v)) == mklist("a", "A")); const value pv(gc_ptr(new value(1))); assert(*(gc_ptr)pv == value(1)); const list lpv = mklist(gc_ptr(new value(1)), gc_ptr(new value(2))); assert(*(gc_ptr)car(lpv) == value(1)); *(gc_ptr)cadr(lpv) = value(3); assert(*(gc_ptr)cadr(lpv) == value(3)); return true; } bool testValueGC() { resetLambdaCounters(); resetListCounters(); resetValueCounters(); testValue(); assert(countValues == 0); assert(countLambdas == 0); assert(countlists == 0); return true; } double fib_aux(double n, double a, double b) { if(n == 0.0) return a; return fib_aux(n - 1.0, b, a + b); } double fib(double n) { return fib_aux(n, 0.0, 1.0); } bool testCppPerf() { struct timeval start; struct timeval end; { gettimeofday(&start, NULL); list s = seq(0.0, 999.0); list r = map(fib, s); assert(1000 == length(r)); gettimeofday(&end, NULL); //long t = (end.tv_sec * 1000 + end.tv_usec / 1000) - (start.tv_sec * 1000 + start.tv_usec / 1000); //std::cout << "Fib cpp function map perf test " << t << " ms" << std::endl; } { struct nested { static double fib(double n) { struct nested { static double fib_aux(double n, double a, double b) { if(n == 0.0) return a; return fib_aux(n - 1.0, b, a + b); } }; return nested::fib_aux(n, 0.0, 1.0); } }; gettimeofday(&start, NULL); list s = seq(0.0, 999.0); list r = map(lambda(nested::fib), s); assert(1000 == length(r)); gettimeofday(&end, NULL); //long t = (end.tv_sec * 1000 + end.tv_usec / 1000) - (start.tv_sec * 1000 + start.tv_usec / 1000); //std::cout << "Fib cpp nested function map perf test " << t << " ms" << std::endl; } return true; } bool testAtomicPerf() { struct timeval start; struct timeval end; { gettimeofday(&start, NULL); for(int i = 0; i < 10000000;) i = i + 1; gettimeofday(&end, NULL); //long t = (end.tv_sec * 1000 + end.tv_usec / 1000) - (start.tv_sec * 1000 + start.tv_usec / 1000); //std::cout << "Loop test " << t << " ms" << std::endl; } { gettimeofday(&start, NULL); for(int i = 0; i < 10000000;) __sync_add_and_fetch(&i, 1); gettimeofday(&end, NULL); //long t = (end.tv_sec * 1000 + end.tv_usec / 1000) - (start.tv_sec * 1000 + start.tv_usec / 1000); //std::cout << "Loop atomic test " << t << " ms" << std::endl; } { pthread_mutex_t mutex; pthread_mutex_init(&mutex, NULL); gettimeofday(&start, NULL); for(int i = 0; i < 10000000;) { pthread_mutex_lock(&mutex); i = i + 1; pthread_mutex_unlock(&mutex); } gettimeofday(&end, NULL); pthread_mutex_destroy(&mutex); //long t = (end.tv_sec * 1000 + end.tv_usec / 1000) - (start.tv_sec * 1000 + start.tv_usec / 1000); //std::cout << "Loop mutex test " << t << " ms" << std::endl; } return true; } const int mtsquare(const int x) { //std::cout << "thread " << threadId() << " mtsquare(" << x << ")\n"; for(int i = 0; i < 10000000; i++) ; return x * x; } bool testWorker() { worker w(10); { const lambda func = curry(lambda (mtsquare), 2); assert(submit(w, func) == 4); } { const int max = 10; list > r; for(int i = 0; i < max; i++) { const lambda func = curry(lambda (mtsquare), i); r = cons(submit(w, func), r); } for(int i = max - 1; i >= 0; i--) { assert(car(r) == i * i); r = cdr(r); } } shutdown(w); return true; } const std::string currencyXML = "\n" "" "" "" "" "" "" "" "" "" "" "" "" "US" "" "" "\n"; const std::string customerXML = "\n" "" "jdoe" "
san franciscoca
" "12341000" "67892000" "45673000" "
" "\n"; const bool isName(const value& token) { return isTaggedList(token, attribute) && attributeName(token) == "name"; } bool testReadXML() { { std::istringstream is(customerXML); const list c = readXML(streamList(is)); } { std::istringstream is(currencyXML); const list c = readXML(streamList(is)); const value composite = car(c); assert(isTaggedList(composite, element)); assert(elementName(composite) == "composite"); assert(attributeValue(car(filter(isName, elementChildren(composite)))) == std::string("currency")); } return true; } std::ostringstream* xmlWriter(const std::string& s, std::ostringstream* os) { (*os) << s; return os; } bool testWriteXML() { { std::istringstream is(customerXML); const list c = readXML(streamList(is)); std::ostringstream os; writeXML(xmlWriter, &os, c); assert(os.str() == customerXML); } { std::istringstream is(currencyXML); const list c = readXML(streamList(is)); std::ostringstream os; writeXML(xmlWriter, &os, c); assert(os.str() == currencyXML); } return true; } bool testElement() { { const list ad = mklist(mklist("city", std::string("san francisco")), mklist("state", std::string("ca"))); const list ac1 = mklist(mklist("id", std::string("1234")), mklist("balance", 1000)); const list ac2 = mklist(mklist("id", std::string("6789")), mklist("balance", 2000)); const list ac3 = mklist(mklist("id", std::string("4567")), mklist("balance", 3000)); { const list c = mklist(mklist("customer", mklist("name", std::string("jdoe")), cons("address", ad), mklist("account", mklist(ac1, ac2, ac3)))); const list e = valuesToElements(c); const list v = elementsToValues(e); assert(v == c); std::ostringstream os; writeXML(xmlWriter, &os, e); assert(os.str() == customerXML); } { const list c = mklist(mklist("customer", mklist("name", std::string("jdoe")), cons("address", ad), cons("account", ac1), cons("account", ac2), cons("account", ac3))); const list e = valuesToElements(c); const list v = elementsToValues(e); std::ostringstream os; writeXML(xmlWriter, &os, e); assert(os.str() == customerXML); } } { std::istringstream is(customerXML); const list c = readXML(streamList(is)); const list v = elementsToValues(c); const list e = valuesToElements(v); std::ostringstream os; writeXML(xmlWriter, &os, e); assert(os.str() == customerXML); } return true; } const id idF(const int v) { return v * 2; } const id idG(const int v) { return v * 3; } const id idH(const int v) { return idF(v) >> idG; } bool testIdMonad() { const id m(2); assert(m >> idF == idF(2)); assert(m >> unit() == m); assert(m >> idF >> idG == m >> idH); return true; } const maybe maybeF(const int v) { return v * 2; } const maybe maybeG(const int v) { return v * 3; } const maybe maybeH(const int v) { return maybeF(v) >> maybeG; } bool testMaybeMonad() { const maybe m(2); assert(m >> maybeF == maybeF(2)); assert((m >> just()) == m); assert(m >> maybeF >> maybeG == m >> maybeH); assert(maybe() >> maybeF >> maybeG == maybe()); return true; } const failable failableF(const int v) { return v * 2; } const failable failableG(const int v) { return v * 3; } const failable failableH(const int v) { return failableF(v) >> failableG; } bool testFailableMonad() { const failable m(2); assert(m >> failableF == failableF(2)); assert((m >> success()) == m); assert(m >> failableF >> failableG == m >> failableH); failable ooops("ooops"); assert(ooops >> failableF >> failableG == ooops); return true; } struct tickInc { const double v; tickInc(const double v) : v(v) { } const svp operator()(int s) const { return svp(s + 1, v); } }; const state tick(const double v) { return transformer(tickInc(v)); } const state stateF(const double v) { return result(v * 2.0) >> tick; } const state stateG(const double v) { return result(v + 5); } const state stateH(const double v) { return stateF(v) >> stateG; } bool testStateMonad() { const lambda(double)> r(result); state m = result(2.0); assert((m >> stateF)(0) == stateF(2.0)(0)); assert(1 == (int)(m >> stateF)(0)); assert((m >> r)(0) == m(0)); assert((m >> stateF >> stateG)(0) == (m >> stateH)(0)); return true; } } int main() { std::cout << "Testing..." << std::endl; tuscany::testLambda(); tuscany::testLambdaGC(); tuscany::testCons(); tuscany::testSet(); tuscany::testListGC(); tuscany::testOut(); tuscany::testEquals(); tuscany::testLength(); tuscany::testAppend(); tuscany::testComplex(); tuscany::testMap(); tuscany::testReduce(); tuscany::testFilter(); tuscany::testMember(); tuscany::testReverse(); tuscany::testListRef(); tuscany::testAssoc(); tuscany::testZip(); tuscany::testTokenize(); tuscany::testSeq(); tuscany::testValue(); tuscany::testValueGC(); tuscany::testElement(); tuscany::testCppPerf(); tuscany::testAtomicPerf(); tuscany::testWorker(); tuscany::testReadXML(); tuscany::testWriteXML(); tuscany::testIdMonad(); tuscany::testMaybeMonad(); tuscany::testFailableMonad(); tuscany::testStateMonad(); std::cout << "OK" << std::endl; return 0; }