/** * This function resets the test environment by logging the user out, * deleting the database, and then logging the user back into the node. * * @param node the node to use when logging into and out of the node. */ static void resetTestEnvironment(Node& node) { // get the path to the database file, dear sir Config config = node.getConfigManager()->getModuleUserConfig( "bitmunk.medialibrary.MediaLibrary", TEST_USER_ID); const char* url = config["database"]["url"]->getString(); // assert that the translation happened correctly string fullDbPath; assert(node.getConfigManager()->translateUrlToUserFilePath( TEST_USER_ID, url, fullDbPath)); // log the user out node.logout(TEST_USER_ID); assertNoExceptionSet(); // remove the file from the filesystem File file(fullDbPath.c_str()); if(file->exists()) { assertNoException( file->remove()); } // log the user in assertNoException( node.login("devuser", "password")); }
/** * Check a GET to a url returns a certain code and data. */ static void _checkUrlText( TestRunner& tr, Url* url, int code, const char* expected, int length) { // create client HttpClient client; // connect assertNoException(client.connect(url)); if(tr.getVerbosityLevel() > 1) { printf("Connected to: %s\n", url->toString().c_str()); InternetAddress address(url->getHost().c_str(), url->getPort()); printf("%s\n", address.toString().c_str()); } // do get HttpResponse* response = client.get(url); assert(response != NULL); if(tr.getVerbosityLevel() > 1) { printf("Response header:\n%s\n", response->getHeader()->toString().c_str()); } if(response->getHeader()->getStatusCode() != code) { printf("Expecting response status code: %d, got %d\n", response->getHeader()->getStatusCode(), code); } assert(response->getHeader()->getStatusCode() == code); // receive content HttpTrailer trailer; ByteBuffer b; ByteArrayOutputStream baos(&b); assertNoException(client.receiveContent(&baos, &trailer)); // put data in strings for strcmp since it may not be NULL terminated string strexpected; strexpected.assign(expected, length); string strdata; strdata.assign(b.data(), b.length()); if(tr.getVerbosityLevel() > 1) { printf("Response content (%d bytes):\n%s\n", b.length(), strdata.c_str()); printf("Response trailers:\n%s\n", trailer.toString().c_str()); } // check content assertStrCmp(strdata.c_str(), strexpected.c_str()); assert(b.length() == length); client.disconnect(); assertNoExceptionSet(); }
static void contributorGetTest(Node& node, TestRunner& tr) { tr.group("contributors"); Messenger* messenger = node.getMessenger(); tr.test("id"); { Url url("/api/3.0/contributors/1"); // get contributor DynamicObject contributor; assertNoException( messenger->getFromBitmunk(&url, contributor)); printf("\nContributor:\n"); dumpDynamicObject(contributor, false); } tr.passIfNoException(); tr.test("owner"); { Url url("/api/3.0/contributors/?owner=900"); // get contributor DynamicObject contributors; assertNoException( messenger->getFromBitmunk(&url, contributors)); printf("\nContributors:\n"); dumpDynamicObject(contributors, false); } tr.passIfNoException(); tr.test("media"); { Url url("/api/3.0/contributors/?media=1"); // get contributor DynamicObject contributors; assertNoException( messenger->getFromBitmunk(&url, contributors)); printf("\nContributors:\n"); dumpDynamicObject(contributors, false); } tr.passIfNoException(); tr.ungroup(); }
static void userAddTest(Node& node, TestRunner& tr) { tr.group("user add"); Messenger* messenger = node.getMessenger(); tr.test("add (valid)"); { Url url("/api/3.0/users"); // password update User user; user["email"] = "*****@*****.**"; user["username"] = "******"; user["password"] = "******"; user["confirm"] = "password"; user["tosAgree"] = "agree"; assertNoException( messenger->postSecureToBitmunk( &url, &user, NULL, node.getDefaultUserId())); printf("\nUser added.\n"); } tr.passIfNoException(); tr.ungroup(); }
JNIEXPORT jobject JNICALL Java_node_NodeDynamicProxyClass_callJs(JNIEnv *env, jobject src, jlong ptr, jobject method, jobjectArray args) { threadId myThreadId = my_getThreadId(); bool hasArgsGlobalRef = false; // args needs to be global, you can't send env across thread boundaries DynamicProxyData* dynamicProxyData = (DynamicProxyData*)ptr; dynamicProxyData->args = args; dynamicProxyData->done = false; dynamicProxyData->result = NULL; dynamicProxyData->throwableClass = ""; dynamicProxyData->throwableMessage = ""; jclass methodClazz = env->FindClass("java/lang/reflect/Method"); jmethodID method_getName = env->GetMethodID(methodClazz, "getName", "()Ljava/lang/String;"); dynamicProxyData->methodName = javaObjectToString(env, env->CallObjectMethod(method, method_getName)); assertNoException(env); uv_work_t* req = new uv_work_t(); req->data = dynamicProxyData; if(v8ThreadIdEquals(myThreadId, v8ThreadId)) { #if NODE_MINOR_VERSION >= 10 EIO_AfterCallJs(req, 0); #else EIO_AfterCallJs(req); #endif } else { if (args) { // if args is not null and we have to kick this across the thread boundary, make it a global ref dynamicProxyData->args = (jobjectArray) env->NewGlobalRef(args); hasArgsGlobalRef = true; } uv_queue_work(uv_default_loop(), req, EIO_CallJs, (uv_after_work_cb)EIO_AfterCallJs); while(!dynamicProxyData->done) { my_sleep(100); } } if(!dynamicProxyDataVerify(dynamicProxyData)) { throwNewThrowable(env, "java/lang/IllegalStateException", "dynamicProxyData was corrupted"); } if(hasArgsGlobalRef) { env->DeleteGlobalRef(dynamicProxyData->args); } if (dynamicProxyData->done == DYNAMIC_PROXY_JS_ERROR) { throwNewThrowable(env, dynamicProxyData->throwableClass.c_str(), dynamicProxyData->throwableMessage); } jobject result = NULL; if(dynamicProxyData->result) { // need to retain a local ref so that we can return it, otherwise the returned object gets corrupted result = env->NewLocalRef(dynamicProxyData->result); env->DeleteGlobalRef(dynamicProxyData->result); } return result; }
static bool run(TestRunner& tr) { if(tr.isTestEnabled("fixme")) { // load and start node Node* node = Tester::loadNode(tr, "test-services-customcatalog"); assertNoException( node->start()); Config cfg = tr.getApp()->getConfig(); sTestDataDir = cfg["test"]["dataPath"]->getString(); //config["node"]["modulePath"] = append BPE_MODULES_DIRECTORY; //config["bitmunk.catalog.CustomCatalog"]["uploadListings"] = false; // run tests customCatalogTests(*node, tr); // stop and unload node node->stop(); Tester::unloadNode(tr); } if(tr.isTestEnabled("fixme")) { // load and start node Node* node = Tester::loadNode(tr, "test-services-customcatalog"); assertNoException( node->start()); Config cfg = tr.getApp()->getConfig(); sTestDataDir = cfg["test"]["dataPath"]->getString(); //config["node"]["modulePath"] = BPE_MODULES_DIRECTORY; //config["bitmunk.catalog.CustomCatalog"]["uploadListings"] = true; // run tests interactiveCustomCatalogTests(*node, tr); // stop and unload node node->stop(); Tester::unloadNode(tr); } return true; };
static inline JSC::JSValue callFunction(JSC::ExecState& state, JSC::JSValue jsFunction, JSC::JSValue thisValue, const JSC::ArgList& arguments) { VM& vm = state.vm(); auto scope = DECLARE_CATCH_SCOPE(vm); JSC::CallData callData; auto callType = JSC::getCallData(vm, jsFunction, callData); ASSERT(callType != JSC::CallType::None); auto result = call(&state, jsFunction, callType, callData, thisValue, arguments); scope.assertNoException(); return result; }
static void reviewGetTest(Node& node, TestRunner& tr) { tr.group("reviews"); Messenger* messenger = node.getMessenger(); tr.test("user get"); { // create url for obtaining user reviews Url url("/api/3.0/reviews/user/900"); // get account DynamicObject reviews; assertNoException( messenger->getSecureFromBitmunk( &url, reviews, node.getDefaultUserId())); printf("\nReviews:\n"); dumpDynamicObject(reviews, false); } tr.passIfNoException(); tr.test("media get"); { // create url for obtaining media reviews Url url("/api/3.0/reviews/media/1"); // get account DynamicObject reviews; assertNoException( messenger->getSecureFromBitmunk( &url, reviews, node.getDefaultUserId())); printf("\nReviews:\n"); dumpDynamicObject(reviews, false); } tr.passIfNoException(); tr.ungroup(); }
static void accountGetTest(Node& node, TestRunner& tr) { tr.group("accounts"); Messenger* messenger = node.getMessenger(); tr.test("get"); { Url url("/api/3.0/accounts/?owner=900"); // get all accounts User user; messenger->getSecureFromBitmunk(&url, user, node.getDefaultUserId()); printf("\nAccounts:\n"); dumpDynamicObject(user); } tr.passIfNoException(); tr.ungroup(); tr.group("account"); tr.test("get"); { // create url for obtaining users Url url("/api/3.0/accounts/9000"); // get account Account account; assertNoException( messenger->getSecureFromBitmunk( &url, account, node.getDefaultUserId())); printf("\nAccount:\n"); dumpDynamicObject(account, false); } tr.passIfNoException(); tr.ungroup(); }
JSObject* IntlNumberFormat::resolvedOptions(ExecState& state) { VM& vm = state.vm(); auto scope = DECLARE_THROW_SCOPE(vm); // 11.3.5 Intl.NumberFormat.prototype.resolvedOptions() (ECMA-402 2.0) // The function returns a new object whose properties and attributes are set as if // constructed by an object literal assigning to each of the following properties the // value of the corresponding internal slot of this NumberFormat object (see 11.4): // locale, numberingSystem, style, currency, currencyDisplay, minimumIntegerDigits, // minimumFractionDigits, maximumFractionDigits, minimumSignificantDigits, // maximumSignificantDigits, and useGrouping. Properties whose corresponding internal // slots are not present are not assigned. if (!m_initializedNumberFormat) { initializeNumberFormat(state, jsUndefined(), jsUndefined()); scope.assertNoException(); } JSObject* options = constructEmptyObject(&state); options->putDirect(vm, vm.propertyNames->locale, jsString(&state, m_locale)); options->putDirect(vm, Identifier::fromString(&vm, "numberingSystem"), jsString(&state, m_numberingSystem)); options->putDirect(vm, Identifier::fromString(&vm, "style"), jsNontrivialString(&state, styleString(m_style))); if (m_style == Style::Currency) { options->putDirect(vm, Identifier::fromString(&vm, "currency"), jsNontrivialString(&state, m_currency)); options->putDirect(vm, Identifier::fromString(&vm, "currencyDisplay"), jsNontrivialString(&state, currencyDisplayString(m_currencyDisplay))); } options->putDirect(vm, Identifier::fromString(&vm, "minimumIntegerDigits"), jsNumber(m_minimumIntegerDigits)); options->putDirect(vm, Identifier::fromString(&vm, "minimumFractionDigits"), jsNumber(m_minimumFractionDigits)); options->putDirect(vm, Identifier::fromString(&vm, "maximumFractionDigits"), jsNumber(m_maximumFractionDigits)); if (m_minimumSignificantDigits) { ASSERT(m_maximumSignificantDigits); options->putDirect(vm, Identifier::fromString(&vm, "minimumSignificantDigits"), jsNumber(m_minimumSignificantDigits)); options->putDirect(vm, Identifier::fromString(&vm, "maximumSignificantDigits"), jsNumber(m_maximumSignificantDigits)); } options->putDirect(vm, Identifier::fromString(&vm, "useGrouping"), jsBoolean(m_useGrouping)); return options; }
static void permissionGetTest(Node& node, TestRunner& tr) { tr.group("permissions"); Messenger* messenger = node.getMessenger(); tr.test("group get"); { // create url for obtaining permission group information Url url("/api/3.0/permissions/100"); // get permission group PermissionGroup group; assertNoException( messenger->getFromBitmunk(&url, group)); printf("\nGroup:\n"); dumpDynamicObject(group, false); } tr.passIfNoException(); tr.ungroup(); }
static void acquireLicenseTest(Node& node, TestRunner& tr) { tr.group("media license"); Messenger* messenger = node.getMessenger(); tr.test("acquire signed media"); { // create url for obtaining media license Url url("/api/3.0/sva/contracts/media/2"); // get signed media Media media; assertNoException( messenger->postSecureToBitmunk( &url, NULL, &media, node.getDefaultUserId())); printf("\nSigned Media:\n"); dumpDynamicObject(media, false); } tr.passIfNoException(); tr.ungroup(); }
static void userGetTest(Node& node, TestRunner& tr) { tr.group("user"); Messenger* messenger = node.getMessenger(); tr.test("get self (valid)"); { // create url for obtaining users Url url("/api/3.0/users/900"); // get user User user; assertNoException( messenger->getSecureFromBitmunk(&url, user, node.getDefaultUserId())); printf("\nUser:\n"); dumpDynamicObject(user, false); } tr.passIfNoException(); /* tr.test("get non-self (valid)"); { // create url for obtaining users Url url("/api/3.0/users/900"); // get user User user; messenger->getSecureFromBitmunk(&url, user, node.getDefaultUserId()); assertNoException(); printf("\nUser:\n"); dumpDynamicObject(user, false); } tr.passIfNoException(); */ tr.test("get identity (valid)"); { // create url for obtaining identity Url url("/api/3.0/users/identity/900"); // get identity Identity identity; assertNoException( messenger->getSecureFromBitmunk( &url, identity, node.getDefaultUserId())); printf("\nIdentity:\n"); dumpDynamicObject(identity, false); } tr.passIfNoException(); /* tr.test("get identity (invalid)"); { // create url for obtaining identity Url url("/api/3.0/users/identity/69766"); // get identity Identity identity; messenger->getSecureFromBitmunk(( &url, identity, node.getDefaultUserId()); assertException(); printf("\nIdentity:\n"); dumpDynamicObject(identity, false); } tr.passIfException(); */ /* tr.test("sellerKey"); { // create url for obtaining users Url url("/api/3.0/users/keys/seller/900"); // get user DynamicObject sellerKey; messenger->getFromBitmunk(&url, sellerKey); assertNoException(); printf("\nSeller Key:\n"); dumpDynamicObject(sellerKey, false); } tr.passIfNoException(); tr.test("friends"); { Url url("/api/3.0/friends/?user=900"); // get friends User user; messenger->getSecureFromBitmunk(&url, user, node.getDefaultUserId()); assertNoException(); printf("\nUser Friends:\n"); dumpDynamicObject(user, false); } tr.passIfNoException(); */ tr.ungroup(); }
static bool run(TestRunner& tr) { if(tr.isTestEnabled("fixme")) { // load and start node Node* node = Tester::loadNode(tr/*, "test-node-services"*/); assertNoException( node->start()); //cout << "You may need to remove testuser5.profile from /tmp/ to " // "run the password update test." << endl; // login the devuser //node.login("devuser", "password"); //node.login("testuser5", "password"); assertNoExceptionSet(); // run tests //mediaGetTest(node, tr); //userGetTest(node, tr); //userAddTest(node, tr); //userUpdateTest(node, tr); //accountGetTest(node, tr); //contributorGetTest(node, tr); //permissionGetTest(node, tr); //reviewGetTest(node, tr); //acquireLicenseTest(node, tr); // performance tests //accountGetPerfTest(node, tr); // stop and unload node node->stop(); Tester::unloadNode(tr); } if(tr.isTestEnabled("fixme")) { // load and start node Node* node = Tester::loadNode(tr/*, "test-node-services"*/); assertNoException( node->start()); // login the devuser //node.login("devuser", "password"); //node.login("testuser5", "password"); assertNoExceptionSet(); Config cfg = tr.getApp()->getConfig(); const char* test = cfg["monarch.test.Tester"]["test"]->getString(); bool all = (strcmp(test, "all") == 0); if(all || (strcmp(test, "ping") == 0)) { pingPerfTest(*node, tr); } // stop and unload node node->stop(); Tester::unloadNode(tr); } return true; };
static void interactiveCustomCatalogTests(Node& node, TestRunner& tr) { Messenger* messenger = node.getMessenger(); tr.group("customcatalog+listing updater"); // generate the ware URLs that will be used throughout the test. Url waresUrl; waresUrl.format("%s/api/3.0/catalog/wares?nodeuser=%" PRIu64, messenger->getSelfUrl(true).c_str(), TEST_USER_ID); Url wareUrl; wareUrl.format("%s/api/3.0/catalog/wares/%s?nodeuser=%" PRIu64, messenger->getSelfUrl(true).c_str(), TEST_WARE_ID_2, TEST_USER_ID); // generate the files URL that will be used to prime the medialibrary Url filesUrl; filesUrl.format("%s/api/3.2/medialibrary/files?nodeuser=%" PRIu64, messenger->getSelfUrl(true).c_str(), TEST_USER_ID); Url removeUrl; removeUrl.format( "%s/api/3.2/medialibrary/files/%s?nodeuser=%" PRIu64, messenger->getSelfUrl(true).c_str(), TEST_FILE_ID_2, TEST_USER_ID); // remove any previous files from the media library messenger->deleteResource(&removeUrl, NULL, node.getDefaultUserId()); // pass even if there is an exception - this is meant to just clear any // previous entries in the medialibrary database if they existed. Exception::clear(); tr.test("add file to medialibrary (valid)"); { DynamicObject in; DynamicObject out; // create a FileInfo object string normalizedPath; File::normalizePath( (sTestDataDir + TEST_FILENAME_2).c_str(), normalizedPath); out["path"] = normalizedPath.c_str(); out["mediaId"] = 2; // prepare event waiter EventWaiter ew(node.getEventController()); ew.start("bitmunk.medialibrary.File.updated"); ew.start("bitmunk.medialibrary.File.exception"); // add the file to the media library assertNoException( messenger->post(&filesUrl, &out, &in, node.getDefaultUserId())); // wait for file ID set event assert(ew.waitForEvent(5*1000)); // ensure it has an exception Event e = ew.popEvent(); //dumpDynamicObject(e); if(e["details"]->hasMember("exception")) { ExceptionRef ex = Exception::convertToException( e["details"]["exception"]); Exception::set(ex); } } tr.passIfNoException(); tr.test("add ware without payee-scheme (valid)"); { DynamicObject in; DynamicObject out; // create the outgoing ware object FileInfo fi; fi["id"] = TEST_FILE_ID_2; out["id"] = TEST_WARE_ID_2; out["mediaId"] = 2; out["description"] = "This ware was added by test-services-customcatalog"; out["fileInfo"] = fi; out["payees"]->setType(Array); Payee p1 = out["payees"]->append(); Payee p2 = out["payees"]->append(); p1["id"] = 900; p1["amountType"] = PAYEE_AMOUNT_TYPE_FLATFEE; p1["amount"] = "0.10"; p1["description"] = "This payee is for media ID 2"; p2["id"] = 900; p2["amountType"] = PAYEE_AMOUNT_TYPE_PTOTAL; p2["percentage"] = "0.10"; p2["description"] = "This payee is for media ID 2"; // add the ware to the custom catalog messenger->post(&waresUrl, &out, &in, node.getDefaultUserId()); } tr.passIfNoException(); printf("\nWaiting for server info to update...\n"); Thread::sleep(2*1000); while(true) { tr.test("get server info"); { Url serverUrl; serverUrl.format("%s/api/3.0/catalog/server?nodeuser=%" PRIu64, messenger->getSelfUrl(true).c_str(), TEST_USER_ID); DynamicObject in; messenger->get(&serverUrl, in, node.getDefaultUserId()); dumpDynamicObject(in); } tr.passIfNoException(); printf( "\nSleeping to allow listing updater to run. Hit CTRL+C to quit.\n"); Thread::sleep(30*1000); } tr.ungroup(); }
static void customCatalogTests(Node& node, TestRunner& tr) { resetTestEnvironment(node); Messenger* messenger = node.getMessenger(); // generate the ware URLs that will be used throughout the test. Url waresUrl; waresUrl.format( "%s/api/3.0/catalog/wares?nodeuser=%" PRIu64, messenger->getSelfUrl(true).c_str(), TEST_USER_ID); Url waresNonDefaultListUrl; waresNonDefaultListUrl.format( "%s/api/3.0/catalog/wares?nodeuser=%" PRIu64 "&id=%s&default=false", messenger->getSelfUrl(true).c_str(), TEST_USER_ID, TEST_WARE_ID_2); Url wareUrl; wareUrl.format( "%s/api/3.0/catalog/wares/%s?nodeuser=%" PRIu64, messenger->getSelfUrl(true).c_str(), TEST_WARE_ID_2, TEST_USER_ID); // generate the files URL that will be used to prime the medialibrary Url filesUrl; filesUrl.format("%s/api/3.2/medialibrary/files?nodeuser=%" PRIu64, messenger->getSelfUrl(true).c_str(), TEST_USER_ID); Url removeUrl; removeUrl.format( "%s/api/3.2/medialibrary/files/%s?nodeuser=%" PRIu64, messenger->getSelfUrl(true).c_str(), TEST_FILE_ID_2, TEST_USER_ID); // Create basic and detailed test ware with id=2 Ware basicWare2; Ware detailedWare2; { basicWare2["id"] = TEST_WARE_ID_2; basicWare2["description"] = "This ware was added by test-services-customcatalog"; detailedWare2 = basicWare2.clone(); detailedWare2["mediaId"] = 2; detailedWare2["fileInfos"]->setType(Array); FileInfo fi = detailedWare2["fileInfos"]->append(); fi["id"] = TEST_FILE_ID_2; fi["mediaId"] = 2; File file((sTestDataDir + TEST_FILENAME_2).c_str()); fi["extension"] = file->getExtension() + 1; fi["contentType"] = "audio/mpeg"; fi["contentSize"] = TEST_CONTENT_SIZE_2; fi["size"] = (uint64_t)file->getLength(); fi["path"] = file->getAbsolutePath(); detailedWare2["payees"]->setType(Array); Payee p1 = detailedWare2["payees"]->append(); Payee p2 = detailedWare2["payees"]->append(); p1["id"] = 900; p1["amountType"] = PAYEE_AMOUNT_TYPE_FLATFEE; p1["amount"] = "0.10"; p1["description"] = "This payee is for media ID 2"; p2["id"] = 900; p2["amountType"] = PAYEE_AMOUNT_TYPE_PTOTAL; p2["percentage"] = "0.10"; p2["description"] = "This payee is for media ID 2"; } // remove any previous files from the media library messenger->deleteResource(&removeUrl, NULL, node.getDefaultUserId()); // pass even if there is an exception - this is meant to just clear any // previous entries in the medialibrary database if they existed. Exception::clear(); tr.group("customcatalog"); tr.test("add file to medialibrary (valid)"); { DynamicObject in; DynamicObject out; // create a FileInfo object string normalizedPath; File::normalizePath( (sTestDataDir + TEST_FILENAME_2).c_str(), normalizedPath); out["path"] = normalizedPath.c_str(); out["mediaId"] = 2; // prepare event waiter EventWaiter ew(node.getEventController()); ew.start("bitmunk.medialibrary.File.updated"); ew.start("bitmunk.medialibrary.File.exception"); // add the file to the media library assertNoException( messenger->post(&filesUrl, &out, &in, node.getDefaultUserId())); // wait for file ID set event assert(ew.waitForEvent(5*1000)); // ensure it has an exception Event e = ew.popEvent(); //dumpDynamicObject(e); if(e["details"]->hasMember("exception")) { ExceptionRef ex = Exception::convertToException( e["details"]["exception"]); Exception::set(ex); } else if(strcmp( e["type"]->getString(), "bitmunk.medialibrary.File.updated") == 0) { // add new mediaLibraryId to the basic and detailed wares basicWare2["mediaLibraryId"] = e["details"]["mediaLibraryId"]; detailedWare2["mediaLibraryId"] = e["details"]["mediaLibraryId"]; } } tr.passIfNoException(); tr.test("add ware without payee-scheme (valid)"); { DynamicObject in; DynamicObject out; // create the outgoing ware object FileInfo fi; fi["id"] = TEST_FILE_ID_2; out["id"] = TEST_WARE_ID_2; out["mediaId"] = 2; out["description"] = "This ware was added by test-services-customcatalog"; out["fileInfo"] = fi; out["payees"]->setType(Array); Payee p1 = out["payees"]->append(); Payee p2 = out["payees"]->append(); p1["id"] = 900; p1["amountType"] = PAYEE_AMOUNT_TYPE_FLATFEE; p1["amount"] = "0.10"; p1["description"] = "This payee is for media ID 2"; p2["id"] = 900; p2["amountType"] = PAYEE_AMOUNT_TYPE_PTOTAL; p2["percentage"] = "0.10"; p2["description"] = "This payee is for media ID 2"; // add the ware to the custom catalog messenger->post(&waresUrl, &out, &in, node.getDefaultUserId()); // set ware payeeSchemeIds basicWare2["payeeSchemeId"] = in["payeeSchemeId"]; detailedWare2["payeeSchemeId"] = in["payeeSchemeId"]; } tr.passIfNoException(); tr.test("get ware (valid)"); { // get a specific ware from the custom catalog Ware receivedWare; assertNoException( messenger->get(&wareUrl, receivedWare, node.getDefaultUserId())); // remove format details for comparison if(receivedWare->hasMember("fileInfos") && receivedWare["fileInfos"]->getType() == Array && receivedWare["fileInfos"]->length() == 1) { receivedWare["fileInfos"][0]->removeMember("formatDetails"); } // check to make sure that the wares match assertNamedDynoCmp( "Expected ware ResourceSet", detailedWare2, "Received ware ResourceSet", receivedWare); } tr.passIfNoException(); tr.test("get wares"); { // get a specific ware from the custom catalog Ware receivedWareSet; Url url; url.format( "%s/api/3.0/catalog/wares?nodeuser=%" PRIu64 "&id=%s", messenger->getSelfUrl(true).c_str(), TEST_USER_ID, TEST_WARE_ID_2); assertNoException( messenger->get(&url, receivedWareSet, node.getDefaultUserId())); // check ware set Ware expectedWareSet; expectedWareSet["resources"][0] = basicWare2.clone(); expectedWareSet["total"] = 1; expectedWareSet["num"] = 1; expectedWareSet["start"] = 0; assertNamedDynoCmp( "Expected ware ResourceSet", expectedWareSet, "Received ware ResourceSet", receivedWareSet); } tr.passIfNoException(); tr.test("get wares by fileId"); { // get a specific ware from the custom catalog Ware receivedWareSet; Url url; url.format( "%s/api/3.0/catalog/wares?nodeuser=%" PRIu64 "&fileId=%s", messenger->getSelfUrl(true).c_str(), TEST_USER_ID, TEST_FILE_ID_2); assertNoException( messenger->get(&url, receivedWareSet, node.getDefaultUserId())); // check ware set Ware expectedWareSet; expectedWareSet["resources"][0] = basicWare2.clone(); expectedWareSet["total"] = 1; expectedWareSet["num"] = 1; expectedWareSet["start"] = 0; assertNamedDynoCmp( "Expected ware ResourceSet", expectedWareSet, "Received ware ResourceSet", receivedWareSet); } tr.passIfNoException(); tr.test("get specific unknown wares"); { // get a specific ware from the custom catalog Ware receivedWareSet; Url url; url.format( "%s/api/3.0/catalog/wares?nodeuser=%" PRIu64 "&id=%s&id=INVALID", messenger->getSelfUrl(true).c_str(), TEST_USER_ID, TEST_WARE_ID_2); messenger->get(&url, receivedWareSet, node.getDefaultUserId()); // check ware set Ware expectedWareSet; expectedWareSet["resources"][0] = basicWare2.clone(); expectedWareSet["total"] = 1; expectedWareSet["num"] = 2; expectedWareSet["start"] = 0; assertNamedDynoCmp( "Expected ware ResourceSet", expectedWareSet, "Received ware ResourceSet", receivedWareSet); } tr.passIfNoException(); tr.test("get wares by dup ware+file ids"); { // This test gets the same ware by both ware id and file id and returns // duplicate results. // get a specific ware from the custom catalog Ware receivedWareSet; Url url; url.format( "%s/api/3.0/catalog/wares?nodeuser=%" PRIu64 "&id=%s&fileId=%s", messenger->getSelfUrl(true).c_str(), TEST_USER_ID, TEST_WARE_ID_2, TEST_FILE_ID_2); messenger->get(&url, receivedWareSet, node.getDefaultUserId()); // check ware set Ware expectedWareSet; expectedWareSet["resources"][0] = basicWare2.clone(); expectedWareSet["total"] = 1; expectedWareSet["num"] = 2; expectedWareSet["start"] = 0; assertNamedDynoCmp( "Expected ware ResourceSet", expectedWareSet, "Received ware ResourceSet", receivedWareSet); } tr.passIfNoException(); tr.test("remove ware (valid)"); { // remove the ware messenger->deleteResource(&wareUrl, NULL, node.getDefaultUserId()); } tr.passIfNoException(); /*************************** Payee Scheme tests **************************/ // generate the payee schemes URL Url payeeSchemesUrl; payeeSchemesUrl.format("%s/api/3.0/catalog/payees/schemes?nodeuser=%" PRIu64, messenger->getSelfUrl(true).c_str(), TEST_USER_ID); PayeeSchemeId psId = 0; tr.test("add payee scheme (valid)"); { DynamicObject in; DynamicObject out; // create the outgoing list of payees to organize into a payee scheme out["description"] = "Payee scheme description 1"; out["payees"]->setType(Array); PayeeList payees = out["payees"]; Payee p1 = payees->append(); Payee p2 = payees->append(); p1["id"] = 900; p1["amountType"] = PAYEE_AMOUNT_TYPE_FLATFEE; p1["amount"] = "0.10"; p1["description"] = "test-services-customcatalog test payee 1"; p2["id"] = 900; p2["amountType"] = PAYEE_AMOUNT_TYPE_PTOTAL; p2["percentage"] = "0.10"; p2["description"] = "test-services-customcatalog test payee 2"; // add the ware to the custom catalog messenger->post(&payeeSchemesUrl, &out, &in, node.getDefaultUserId()); if(in->hasMember("payeeSchemeId")) { psId = in["payeeSchemeId"]->getUInt32(); } } tr.passIfNoException(); // generate the payee scheme URL Url payeeSchemeIdUrl; payeeSchemeIdUrl.format("%s/api/3.0/catalog/payees/schemes/%u?nodeuser=%" PRIu64, messenger->getSelfUrl(true).c_str(), psId, TEST_USER_ID); tr.test("get payee scheme (valid)"); { // Create the expected payee scheme PayeeScheme expectedPayeeScheme; expectedPayeeScheme["id"] = psId; expectedPayeeScheme["userId"] = node.getDefaultUserId(); expectedPayeeScheme["description"] = "Payee scheme description 1"; expectedPayeeScheme["payees"]->setType(Array); Payee p1 = expectedPayeeScheme["payees"]->append(); Payee p2 = expectedPayeeScheme["payees"]->append(); p1["id"] = 900; p1["amountType"] = PAYEE_AMOUNT_TYPE_FLATFEE; p1["amount"] = "0.10"; p1["description"] = "test-services-customcatalog test payee 1"; p2["id"] = 900; p2["amountType"] = PAYEE_AMOUNT_TYPE_PTOTAL; p2["percentage"] = "0.10"; p2["description"] = "test-services-customcatalog test payee 2"; // get a specific payee scheme from the custom catalog PayeeScheme receivedPayeeScheme; messenger->get( &payeeSchemeIdUrl, receivedPayeeScheme, node.getDefaultUserId()); // check payee schemes assertNamedDynoCmp( "Expected payee scheme", expectedPayeeScheme, "Received payee scheme", receivedPayeeScheme); } tr.passIfNoException(); tr.test("get all payee schemes (valid)"); { // Create the result set ResourceSet expectedResults; expectedResults["total"] = 2; expectedResults["start"] = 0; expectedResults["num"] = 2; PayeeScheme ps = expectedResults["resources"]->append(); ps["id"] = 1; ps["userId"] = node.getDefaultUserId(); ps["description"] = "This ware was added by test-services-customcatalog"; ps["payees"]->setType(Array); Payee p1 = ps["payees"]->append(); Payee p2 = ps["payees"]->append(); p1["id"] = 900; p1["amountType"] = PAYEE_AMOUNT_TYPE_FLATFEE; p1["amount"] = "0.10"; p1["description"] = "This payee is for media ID 2"; p2["id"] = 900; p2["amountType"] = PAYEE_AMOUNT_TYPE_PTOTAL; p2["percentage"] = "0.10"; p2["description"] = "This payee is for media ID 2"; ps = expectedResults["resources"]->append(); ps["id"] = 2; ps["userId"] = node.getDefaultUserId(); ps["description"] = "Payee scheme description 1"; ps["payees"]->setType(Array); Payee p3 = ps["payees"]->append(); Payee p4 = ps["payees"]->append(); p3["id"] = 900; p3["amountType"] = PAYEE_AMOUNT_TYPE_FLATFEE; p3["amount"] = "0.10"; p3["description"] = "test-services-customcatalog test payee 1"; p4["id"] = 900; p4["amountType"] = PAYEE_AMOUNT_TYPE_PTOTAL; p4["percentage"] = "0.10"; p4["description"] = "test-services-customcatalog test payee 2"; // get all payee schemes from the custom catalog ResourceSet receivedResults; messenger->get( &payeeSchemesUrl, receivedResults, node.getDefaultUserId()); // check payee schemes assertNamedDynoCmp( "Expected payee scheme ResourceSet", expectedResults, "Received payee scheme ResourceSet", receivedResults); } tr.passIfNoException(); tr.test("update payee scheme (valid)"); { DynamicObject in; DynamicObject out; // create the outgoing list of payees to organize into a payee scheme out["description"] = "Payee scheme description 2"; Payee p1 = out["payees"]->append(); Payee p2 = out["payees"]->append(); p1["id"] = 900; p1["amountType"] = PAYEE_AMOUNT_TYPE_FLATFEE; p1["amount"] = "0.15"; p1["description"] = "test-services-customcatalog test payee 1 (updated)"; p2["id"] = 900; p2["amountType"] = PAYEE_AMOUNT_TYPE_PTOTAL; p2["percentage"] = "0.14"; p2["description"] = "test-services-customcatalog test payee 2 (updated)"; // update a pre-existing payee scheme assertNoException( messenger->post( &payeeSchemeIdUrl, &out, &in, node.getDefaultUserId())); // ensure that the payee scheme was updated assert(in["payeeSchemeId"]->getUInt32() == 2); if(in->hasMember("payeeSchemeId")) { psId = in["payeeSchemeId"]->getUInt32(); } } tr.passIfNoException(); tr.test("add ware with payee scheme (valid)"); { DynamicObject in; DynamicObject out; // create the outgoing ware object FileInfo fi; fi["id"] = TEST_FILE_ID_2; out["id"] = TEST_WARE_ID_2; out["mediaId"] = 2; out["description"] = "This ware was added by test-services-customcatalog"; out["fileInfo"] = fi; out["payeeSchemeId"] = psId; // add the ware to the custom catalog messenger->post(&waresUrl, &out, &in, node.getDefaultUserId()); } tr.passIfNoException(); tr.test("remove associated payee scheme (invalid)"); { messenger->deleteResource( &payeeSchemeIdUrl, NULL, node.getDefaultUserId()); } tr.passIfException(); tr.test("remove ware associated w/ payee scheme (valid)"); { messenger->deleteResource( &wareUrl, NULL, node.getDefaultUserId()); } tr.passIfNoException(); tr.test("remove payee scheme (valid)"); { messenger->deleteResource( &payeeSchemeIdUrl, NULL, node.getDefaultUserId()); } tr.passIfNoException(); tr.test("create ware w/ invalid payee scheme (invalid)"); { DynamicObject in; DynamicObject out; // create the outgoing ware object FileInfo fi; fi["id"] = TEST_FILE_ID_2; PayeeScheme ps; ps["id"] = psId; out["id"] = TEST_WARE_ID_2; out["mediaId"] = 2; out["description"] = "This ware was added by test-services-customcatalog"; out["fileInfo"] = fi; out["payeeScheme"] = ps; // add the ware to the custom catalog messenger->post(&waresUrl, &out, &in, node.getDefaultUserId()); } tr.passIfException(); tr.test("remove ware (invalid)"); { // remove a ware that doesn't exist messenger->deleteResource(&wareUrl, NULL, node.getDefaultUserId()); } tr.passIfException(); tr.ungroup(); }
static void runNodeMonitorTest(TestRunner& tr) { tr.group("NodeMonitor"); tr.test("empty"); { NodeMonitor nm; DynamicObject expect; expect->setType(Map); DynamicObject all = nm.getAll(); assertDynoCmp(expect, all); } tr.passIfNoException(); tr.test("add1 init"); { bool r; NodeMonitor nm; DynamicObject si; si["init"] = "foo"; r = nm.addState("s", si); assert(r); DynamicObject expect; expect["s"] = "foo"; DynamicObject all = nm.getAll(); assertDynoCmp(expect, all); } tr.passIfNoException(); tr.test("addN init"); { bool r; NodeMonitor nm; DynamicObject si; si["s"]["init"] = "foo"; si["u"]["init"] = (uint64_t)0; si["i"]["init"] = (int64_t)0; si["d"]["init"] = 0.; r = nm.addStates(si); assert(r); DynamicObject expect; expect["s"] = "foo"; expect["u"] = (uint64_t)0; expect["i"] = (int64_t)0; expect["d"] = 0.; DynamicObject all = nm.getAll(); assertDynoCmp(expect, all); } tr.passIfNoException(); tr.test("remove"); { bool r; NodeMonitor nm; DynamicObject si; si["n"]["init"] = (uint64_t)0; si["rem"]["init"] = (uint64_t)0; r = nm.addStates(si); assert(r); DynamicObject s; s["rem"].setNull(); r = nm.removeStates(s); assert(r); DynamicObject expect; expect["n"] = (uint64_t)0; DynamicObject all = nm.getAll(); assertDynoCmp(expect, all); } tr.passIfNoException(); tr.test("set"); { bool r; NodeMonitor nm; DynamicObject si; si["n"]["init"] = (uint64_t)0; r = nm.addStates(si); assert(r); DynamicObject s; s["n"] = (uint64_t)123; r = nm.setStates(s); assert(r); DynamicObject expect; expect["n"] = (uint64_t)123; DynamicObject all = nm.getAll(); assertDynoCmp(expect, all); } tr.passIfNoException(); tr.test("adj"); { bool r; NodeMonitor nm; DynamicObject si; si["n"]["init"] = (uint64_t)0; r = nm.addStates(si); assert(r); DynamicObject s; s["n"] = (uint64_t)1; r = nm.adjustStates(s); assert(r); r = nm.adjustStates(s); assert(r); r = nm.adjustStates(s); assert(r); DynamicObject expect; expect["n"] = (uint64_t)3; DynamicObject all = nm.getAll(); assertDynoCmp(expect, all); } tr.passIfNoException(); tr.test("reset"); { bool r; NodeMonitor nm; DynamicObject si; si["n"]["init"] = (uint64_t)100; r = nm.addStates(si); assert(r); DynamicObject s; s["n"] = (uint64_t)123; r = nm.setStates(s); assert(r); r = nm.resetStates(s); assert(r); DynamicObject expect; expect["n"] = (uint64_t)100; DynamicObject all = nm.getAll(); assertDynoCmp(expect, all); } tr.passIfNoException(); tr.test("adj neg"); { bool r; NodeMonitor nm; DynamicObject si; si["n"]["init"] = (uint64_t)100; r = nm.addStates(si); assert(r); DynamicObject s; s["n"] = (int64_t)-1; r = nm.adjustStates(s); assert(r); DynamicObject expect; expect["n"] = (uint64_t)99; DynamicObject all = nm.getAll(); assertDynoCmp(expect, all); } tr.passIfNoException(); tr.test("getN"); { bool r; NodeMonitor nm; DynamicObject si; si["a"]["init"] = "a"; si["b"]["init"] = "b"; si["c"]["init"] = "c"; r = nm.addStates(si); assert(r); DynamicObject s; s["b"].setNull(); s["c"].setNull(); r = nm.getStates(s); assert(r); DynamicObject expect; expect["b"] = "b"; expect["c"] = "c"; assertDynoCmp(expect, s); } tr.passIfNoException(); tr.test("add ex"); { NodeMonitor nm; DynamicObject si; si["bad"] = 0; assertException(nm.addStates(si)); Exception::clear(); } tr.passIfNoException(); tr.test("rem ex"); { NodeMonitor nm; DynamicObject s; s["a"] = 0; assertException(nm.removeStates(s)); Exception::clear(); } tr.passIfNoException(); // Not for use with async StateMonitor implementation. /* tr.test("set ex"); { bool r; NodeMonitor nm; DynamicObject s; s["a"] = 0; assertException(nm.setStates(s)); Exception::clear(); } tr.passIfNoException(); */ tr.test("get ex"); { NodeMonitor nm; DynamicObject s; s["a"] = 0; assertException(nm.getStates(s)); Exception::clear(); } tr.passIfNoException(); tr.test("adj ex"); { NodeMonitor nm; DynamicObject s; s["a"] = 1; assertException(nm.adjustStates(s)); Exception::clear(); } tr.passIfNoException(); tr.test("adj type ex"); { NodeMonitor nm; DynamicObject si; si["a"]["init"] = (uint64_t)0; assertNoException( nm.addStates(si)); // Not for use with async StateMonitor implementation. /* DynamicObject s; s["a"] = 0.; assertException(nm.adjustStates(s)); Exception::clear(); */ } tr.passIfNoException(); tr.test("txn adj ex"); { // check bad transaction doesn't change values NodeMonitor nm; DynamicObject si; si["a"]["init"] = (uint64_t)10; si["b"]["init"] = (uint64_t)10; assertNoException( nm.addStates(si)); // Not for use with async StateMonitor implementation. /* DynamicObject s; s["a"] = (int64_t)-1; s["b"] = -1.; assertException(nm.adjustStates(s)); Exception::clear(); */ DynamicObject expect; expect["a"] = (uint64_t)10; expect["b"] = (uint64_t)10; DynamicObject all = nm.getAll(); assertDynoCmp(expect, all); } tr.passIfNoException(); tr.test("no ex"); { NodeMonitor nm; DynamicObject si; si["a"]["init"] = (uint64_t)10; assertNoException( nm.addStates(si)); DynamicObject s; s["bad"] = (int64_t)-1; assertException(nm.adjustStates(s)); Exception::clear(); DynamicObject expect; expect["a"] = (uint64_t)10; DynamicObject all = nm.getAll(); assertDynoCmp(expect, all); } tr.passIfNoException(); tr.ungroup(); }
static void mediaGetTest(Node& node, TestRunner& tr) { tr.group("media"); Messenger* messenger = node.getMessenger(); tr.test("get"); { // create url for obtaining media Url url("/api/3.0/media/2"); // get media Media media; assertNoException( messenger->getFromBitmunk(&url, media)); printf("\nMedia:\n"); dumpDynamicObject(media, false); } tr.passIfNoException(); tr.test("invalid get"); { // create url for obtaining media Url url("/api/3.0/media/invalidMediaId"); // get media Media media; messenger->getFromBitmunk(&url, media); } tr.passIfException(); tr.test("all"); { // create url for getting media Url url("/api/3.0/media/?start=0&num=5"); // get results DynamicObject results; //assertNoException( // messenger->getFromBitmunk(&url, results)); printf("\nDISABLED FOR PERFORMANCE\n"); /* printf("\nGetting 5 media starting at #0\n(of %" PRIu32 " found)\n", results["total"]->getUInt32()); dumpDynamicObject(results, false); */ } tr.passIfNoException(); tr.test("owned"); { // create url for searching media Url url("/api/3.0/media?owner=900"); // get results DynamicObject results; assertNoException( messenger->getFromBitmunk(&url, results)); printf("\nMedia owned by user 900\n"); printf("Results %" PRIu32 "-%" PRIu32 " of %" PRIu32 "\n", results["start"]->getUInt32(), results["start"]->getUInt32() + results["num"]->getUInt32(), results["total"]->getUInt32()); dumpDynamicObject(results, false); } tr.passIfNoException(); tr.test("search"); { // create url for searching media Url url("/api/3.0/media/?query=test&start=0&num=10"); // get results DynamicObject results; assertNoException( messenger->getFromBitmunk(&url, results)); printf("\nSearching media & contributors for 'test'\n"); printf("Results %" PRIu32 "-%" PRIu32 " of %" PRIu32 "\n", results["start"]->getUInt32(), results["start"]->getUInt32() + results["num"]->getUInt32(), results["total"]->getUInt32()); dumpDynamicObject(results, false); } tr.passIfNoException(); tr.test("genre media"); { // create url for searching media Url url("/api/3.0/media?type=audio&genre=165&start=4&num=5"); // get results DynamicObject results; assertNoException( messenger->getFromBitmunk(&url, results)); printf("\nAudio from genre 165\n"); printf("Results %" PRIu32 "-%" PRIu32 " of %" PRIu32 "\n", results["start"]->getUInt32(), results["start"]->getUInt32() + results["num"]->getUInt32(), results["total"]->getUInt32()); dumpDynamicObject(results, false); } tr.passIfNoException(); tr.test("media list"); { // create url for searching media Url url("/api/3.0/media?owner=1&list=1"); // get results DynamicObject results; assertNoException( messenger->getFromBitmunk(&url, results)); printf("\nMedia list %s\n", results["name"]->getString()); printf("\"%s\"\n", results["description"]->getString()); dumpDynamicObject(results, false); } tr.passIfNoException(); tr.ungroup(); }
static void runConfigManagerTest(TestRunner& tr) { tr.group("ConfigManager"); tr.test("init"); { DynamicObject expect; expect->setType(Map); ConfigManager cm; Config cfg; cfg[ConfigManager::ID] = "config"; cfg[ConfigManager::MERGE]->setType(Map); assert(cm.addConfig(cfg)); assertDynoCmp(cm.getConfig("config", true), cfg); assertDynoCmp(cm.getConfig("config", false), expect); assertDynoCmp(cm.getConfig("config"), expect); } tr.passIfNoException(); tr.test("init & clear"); { DynamicObject expect; expect->setType(Map); ConfigManager cm; Config cfg; cfg[ConfigManager::ID] = "config"; cfg[ConfigManager::MERGE]->setType(Map); assert(cm.addConfig(cfg)); cm.clear(); Config cfg2 = cm.getConfig("config"); assert(cfg2.isNull()); } tr.passIfException(); tr.test("1 config"); { DynamicObject expect; expect->setType(Map); expect["a"] = 0; ConfigManager cm; Config cfg; cfg[ConfigManager::ID] = "config"; cfg[ConfigManager::MERGE]["a"] = 0; assert(cm.addConfig(cfg)); assertNoExceptionSet(); assertDynoCmp(cm.getConfig("config"), expect); } tr.passIfNoException(); tr.test("config change"); { ConfigManager cm; Config cfg; cfg[ConfigManager::ID] = "config"; cfg[ConfigManager::MERGE]["a"] = 0; assert(cm.addConfig(cfg)); DynamicObject a; a["a"] = 0; assertDynoCmp(cm.getConfig("config"), a); Config change = cm.getConfig("config", true); change[ConfigManager::MERGE]["a"] = 1; assert(cm.setConfig(change)); DynamicObject expect; expect["a"] = 1; assert(cm.getConfig("config") != a); assertDynoCmp(cm.getConfig("config"), expect); } tr.passIfNoException(); tr.test("invalid set config"); { ConfigManager cm; Config cfg; cfg[ConfigManager::ID] = "config"; cfg[ConfigManager::MERGE]["a"] = 0; assert(!cm.setConfig(cfg)); } tr.passIfException(); tr.test("double add config"); { ConfigManager cm; Config cfg; cfg[ConfigManager::ID] = "config"; cfg[ConfigManager::MERGE]["a"] = 0; assert(cm.addConfig(cfg)); cfg[ConfigManager::MERGE]["a"] = 1; assert(cm.addConfig(cfg)); DynamicObject expect; expect["a"] = 1; assertDynoCmp(cm.getConfig("config"), expect); } tr.passIfNoException(); tr.test("add"); { DynamicObject expect; expect["a"] = 0; expect["b"] = 1; expect["c"] = 2; ConfigManager cm; Config a; a[ConfigManager::ID] = "config"; a[ConfigManager::MERGE]["a"] = 0; Config b; b[ConfigManager::ID] = "config"; b[ConfigManager::MERGE]["b"] = 1; Config c; c[ConfigManager::ID] = "config"; c[ConfigManager::MERGE]["c"] = 2; assert(cm.addConfig(a)); assertNoExceptionSet(); assert(cm.addConfig(b)); assertNoExceptionSet(); assert(cm.addConfig(c)); assertNoExceptionSet(); assertDynoCmp(cm.getConfig("config"), expect); } tr.passIfNoException(); tr.test("bad remove"); { ConfigManager cm; assert(!cm.removeConfig("error")); assertExceptionSet(); Exception::clear(); } tr.passIfNoException(); tr.test("remove"); { DynamicObject expect; expect["a"] = 0; expect["b"] = 1; expect["c"] = 2; ConfigManager cm; Config a; a[ConfigManager::ID] = "config a"; a[ConfigManager::GROUP] = "group"; a[ConfigManager::MERGE]["a"] = 0; Config b; b[ConfigManager::ID] = "config b"; b[ConfigManager::GROUP] = "group"; b[ConfigManager::MERGE]["b"] = 1; Config c; c[ConfigManager::ID] = "config c"; c[ConfigManager::GROUP] = "group"; c[ConfigManager::MERGE]["c"] = 2; assert(cm.addConfig(a)); assertNoExceptionSet(); assert(cm.addConfig(b)); assertNoExceptionSet(); assert(cm.addConfig(c)); assertNoExceptionSet(); assertDynoCmp(cm.getConfig("group"), expect); DynamicObject expect2; expect2["a"] = 0; expect2["c"] = 2; assert(cm.removeConfig("config b")); assertDynoCmp(cm.getConfig("group"), expect2); } tr.passIfNoException(); tr.test("default value"); { ConfigManager cm; Config a; a[ConfigManager::ID] = "config a"; a[ConfigManager::MERGE] = 1; assert(cm.addConfig(a)); assertNoExceptionSet(); Config b; b[ConfigManager::ID] = "config b"; b[ConfigManager::PARENT] = "config a"; b[ConfigManager::MERGE] = ConfigManager::DEFAULT_VALUE; assert(cm.addConfig(b)); assertNoExceptionSet(); DynamicObject expect; expect = 1; assertDynoCmp(cm.getConfig("config b"), expect); } tr.passIfNoException(); tr.test("default values"); { ConfigManager cm; Config cfga; cfga[ConfigManager::ID] = "config a"; Config& a = cfga[ConfigManager::MERGE]; a[0] = 10; a[1] = 11; a[2]["0"] = 120; a[2]["1"] = 121; assert(cm.addConfig(cfga)); assertNoExceptionSet(); Config cfgb; cfgb[ConfigManager::ID] = "config b"; cfgb[ConfigManager::PARENT] = "config a"; Config& b = cfgb[ConfigManager::MERGE]; b[0] = ConfigManager::DEFAULT_VALUE; b[1] = 21; b[2]["0"] = ConfigManager::DEFAULT_VALUE; b[2]["1"] = 221; assert(cm.addConfig(cfgb)); assertNoExceptionSet(); DynamicObject expect; expect[0] = 10; expect[1] = 21; expect[2]["0"] = 120; expect[2]["1"] = 221; assertDynoCmp(cm.getConfig("config b"), expect); } tr.passIfNoException(); tr.test("keyword substitution {RESOURCE_DIR}"); { DynamicObject expect; expect["dir"] = "/the/real/dir"; expect["dir-plus"] = "/the/real/dir/plus/more"; //expect["name"] = "Digital Bazaar, Inc."; ConfigManager cm; Config a; a[ConfigManager::ID] = "config"; a[ConfigManager::MERGE]["dir"] = "{RESOURCE_DIR}"; a[ConfigManager::MERGE]["dir-plus"] = "{RESOURCE_DIR}/plus/more"; // FIXME: only supports "{RESOURCE_DIR}" now //a[ConfigManager::MERGE]["other"] = "{DB}"; cm.setKeyword("RESOURCE_DIR", "/the/real/dir"); //cm.setKeyword("DB", "Digital Bazaar, Inc."); assert(cm.addConfig(a)); assertNoExceptionSet(); assertDynoCmp(cm.getConfig("config"), expect); } tr.passIfNoException(); tr.test("keyword substitution {CURRENT_DIR}"); { DynamicObject expect; string cwd; string cwdPlusMore; string absoluteDir; File configFile = File::createTempFile("test-config-file"); FileOutputStream fos(configFile); // create and populate the config file string configFileText = "{\n" "\"_id_\": \"config\",\n" "\"_merge_\": {\n" " \"dir\": \"{CURRENT_DIR}\",\n" " \"dir-plus\": \"{CURRENT_DIR}/plus/more\" }\n" "}\n"; fos.write(configFileText.c_str(), configFileText.length()); fos.close(); // modify the current working directory to the expected value absoluteDir = File::dirname(configFile->getAbsolutePath()); cwd = absoluteDir.c_str(); cwdPlusMore = cwd.c_str(); cwdPlusMore.append("/plus/more"); // set the expected values expect["dir"] = cwd.c_str(); expect["dir-plus"] = cwdPlusMore.c_str(); // create the configuration ConfigManager cm; assert(cm.addConfigFile(configFile->getAbsolutePath(), true, absoluteDir.c_str(), true, false)); assertNoExceptionSet(); assertDynoCmp(cm.getConfig("config"), expect); } tr.passIfNoException(); #if 0 tr.test("user preferences"); { ConfigManager cm; // node // built in or loaded defaults DynamicObject nodec; nodec["node"]["host"] = "localhost"; nodec["node"]["port"] = 19100; nodec["node"]["modulePath"]->append("/usr/lib/bitmunk/modules"); nodec["node"]["userModulePath"] = "~/.bitmunk/modules"; assert(cm.addConfig(nodec)); assertNoExceptionSet(); // user // loaded defaults DynamicObject userc; userc["node"]["port"] = 19100; userc["node"]["comment"] = "My precious..."; assert(cm.addConfig(userc, ConfigManager::Custom)); assertNoExceptionSet(); // user makes changes during runtime DynamicObject c = cm.getConfig(); c["node"]["port"] = 19200; c["node"]["userModulePath"] = "~/.bitmunk/modules:~/.bitmunk/modules-dev"; c["node"][ConfigManager::TMP]["not in changes"] = true; // get the changes from defaults to current config // serialize this to disk as needed DynamicObject changes; cm.getChanges(changes); // check it's correct DynamicObject expect; expect["node"]["port"] = 19200; expect["node"]["comment"] = "My precious..."; expect["node"]["userModulePath"] = "~/.bitmunk/modules:~/.bitmunk/modules-dev"; // NOTE: will not have TMP var assertDynoCmp(changes, expect); } tr.passIfNoException(); #endif tr.test("versioning"); { ConfigManager cm; cm.getVersions()->clear(); Config c; c[ConfigManager::ID] = "config"; assert(cm.addConfig(c)); assertNoExceptionSet(); // config has no version - no check done - pass cm.addVersion("1"); assert(cm.addConfig(c)); assertNoExceptionSet(); // config has known version - pass c[ConfigManager::VERSION] = "1"; assert(cm.addConfig(c)); assertNoExceptionSet(); assert(cm.removeConfig("config")); // config has unknown version - fail c[ConfigManager::VERSION] = "2"; assert(!cm.addConfig(c)); assertExceptionSet(); Exception::clear(); } tr.passIfNoException(); tr.test("empty array & map"); { ConfigManager cm; DynamicObject a; a[ConfigManager::ID] = "config"; a[ConfigManager::MERGE][0]->setType(Array); a[ConfigManager::MERGE][1]->setType(Map); assert(cm.addConfig(a)); assertNoExceptionSet(); DynamicObject expect; expect[0]->setType(Array); expect[1]->setType(Map); assertDynoCmp(cm.getConfig("config"), expect); } tr.passIfNoException(); tr.test("empty group ids"); { ConfigManager cm; DynamicObject expect; expect->setType(Array); assertDynoCmp(cm.getIdsInGroup("Not-A-Group"), expect); } tr.passIfNoException(); tr.test("group ids"); { ConfigManager cm; DynamicObject c; c[ConfigManager::ID] = "c0"; c[ConfigManager::GROUP] = "c"; assert(cm.addConfig(c)); assertNoExceptionSet(); c[ConfigManager::ID] = "c1"; c[ConfigManager::GROUP] = "c"; assert(cm.addConfig(c)); assertNoExceptionSet(); DynamicObject expect; expect->setType(Array); expect[0] = "c0"; expect[1] = "c1"; assertDynoCmp(cm.getIdsInGroup("c"), expect); } tr.passIfNoException(); tr.test("replace keywords"); { ConfigManager cm; DynamicObject c; c[ConfigManager::ID] = "c"; c[ConfigManager::MERGE]["test"] = "{A}"; DynamicObject vars; vars["A"] = "a"; assertNoException(ConfigManager::replaceKeywords(c, vars)); DynamicObject expect; expect[ConfigManager::ID] = "c"; expect[ConfigManager::MERGE]["test"] = "a"; assertDynoCmp(c, expect); } tr.passIfNoException(); tr.test("replace keywords (invalid keyword)"); { ConfigManager cm; DynamicObject c; c[ConfigManager::ID] = "c"; c[ConfigManager::MERGE]["test"] = "{UNKNOWN}"; DynamicObject vars; vars["A"] = "a"; assertException(ConfigManager::replaceKeywords(c, vars)); } tr.passIfException(); tr.ungroup(); }
static void runWebServerTest(TestRunner& tr) { const char* path = "/test"; const char* content = "web server test"; const char* regexPath = "/test/dumplings/regextest/turkey"; const char* regexPath2 = "/test/dumplings/regextest2/turkey"; const char* regexPath3 = "/test/dumplings/regextest3/turkey"; const char* regexContent = "web server test (regex)"; // create kernel Kernel k; // set thread stack size in engine (128k) k.getEngine()->getThreadPool()->setThreadStackSize(131072); // optional for testing -- // limit threads to 2: one for accepting, 1 for handling //k.getEngine()->getThreadPool()->setPoolSize(2); // start engine k.getEngine()->start(); // create server Server server; WebServer ws; Config cfg; cfg["host"] = "localhost"; cfg["port"] = 0; cfg["security"] = "off"; WebServiceContainerRef wsc = new WebServiceContainer(); ws.setContainer(wsc); ws.initialize(cfg); WebServiceRef tws = new TestWebService(path, content, regexContent); wsc->addService(tws, WebService::Both); ws.enable(&server); // start server assertNoException(server.start(&k)); // get server port int port = ws.getHostAddress()->getPort(); // check the regular path and data tr.test("WebServer - regular path handler"); { Url url; url.format("http://%s:%d%s", cfg["host"]->getString(), port, path); _checkUrlText(tr, &url, 200, content, strlen(content)); } tr.passIfNoException(); // check the regex path and data tr.test("WebServer - regex path handler"); { Url url; url.format("http://%s:%d%s", cfg["host"]->getString(), port, regexPath); _checkUrlText(tr, &url, 200, regexContent, strlen(regexContent)); } tr.passIfNoException(); // check the regex path and data tr.test("WebServer - regex path handler matches"); { DynamicObject info; info["type"] = "monarch.ws.RestfulHandler"; DynamicObject& matches = info["matches"]; matches[0] = "dumplings"; matches[1] = "turkey"; string expect = JsonWriter::writeToString(info); Url url; url.format("http://%s:%d%s", cfg["host"]->getString(), port, regexPath2); _checkUrlText(tr, &url, 200, expect.c_str(), expect.length()); } tr.passIfNoException(); // check the web service authentication exception tr.test("WebServer - authentication exception"); { DynamicObject ex; ex["message"] = "WebService authentication failed. Access denied."; ex["type"] = "monarch.ws.AccessDenied"; ex["details"]["httpStatusCode"] = 403; ex["details"]["path"] = "/test/dumplings/regextest3/turkey"; ex["details"]["public"] = true; DynamicObject& cause = ex["cause"]; cause["message"] = "Tried to authenticate but failed."; cause["type"] = "tests.ws.Exception"; string expect = JsonWriter::writeToString(ex, true); Url url; url.format("http://%s:%d%s", cfg["host"]->getString(), port, regexPath3); _checkUrlText(tr, &url, 400, expect.c_str(), expect.length()); } tr.passIfNoException(); server.stop(); // stop kernel engine k.getEngine()->stop(); }