// Before each test void SubscriptionTests::init() { // Create the services service1 = new Service(QDBusConnection::SessionBus, SERVICE_NAME1); test_int = new Property(*service1, "Test.Int"); test_double = new Property(*service1, "Test.Double"); service2 = new Service(QDBusConnection::SessionBus, SERVICE_NAME2); test_string = new Property (*service2, "Test.String"); test_bool = new Property(*service2, "Test.Bool"); // Nullify the values (we create the same Properties over and // over, and they will keep their old values. test_int->unsetValue(); test_double->unsetValue(); test_string->unsetValue(); test_bool->unsetValue(); // Initialize test program state isReadyToRead = false; // Start the client client = new QProcess(); sconnect(client, SIGNAL(readyReadStandardOutput()), this, SLOT(readStandardOutput())); client->start("client"); // Record whether the client was successfully started clientStarted = client->waitForStarted(); // Associate shorter names for the test services when communicating with the client if (clientStarted) { writeToClient("assign session " SERVICE_NAME1 " service1\n"); writeToClient("assign session " SERVICE_NAME2 " service2\n"); } }
void ServiceTest::defaultService() { // Check that the initialization went well. // Doing this only in init() is not enough; doesn't stop the test case. QVERIFY(clientStarted); // Use a different service name in each test; this way the ServiceBackends QString serviceName = QString::number(serviceNameIx).prepend(SERVICE_NAME); writeToClient(("assign session " + serviceName + " service\n").toStdString().c_str()); ++serviceNameIx; // Test: create a Service. Set the Service as default. Then create // a Property without a Service. Service* service = new Service(QDBusConnection::SessionBus, serviceName); service->setAsDefault(); Property* property = new Property("Test.Property"); // Expected result: the Property got associated with the default // Service. // Test: command client to subscribe QString actual = writeToClient("subscribe service Test.Property\n"); // Expected result: Subscribe works QString expected = "Subscribe returned: Unknown"; QCOMPARE(actual.simplified(), expected.simplified()); delete service; delete property; }
void SubscriptionTests::clientExits() { // Check that the initialization went well. // Doing this only in init() is not enough; doesn't stop the test case. QVERIFY(clientStarted); QSignalSpy intItemFirst(test_int, SIGNAL(firstSubscriberAppeared(const QString&))); QSignalSpy intItemLast(test_int, SIGNAL(lastSubscriberDisappeared(const QString&))); // Test: ask the client to call Subscribe writeToClient("subscribe service1 Test.Int\n"); // Expected result: we get a notification that the key was subscribed QCOMPARE(intItemFirst.count(), 1); QCOMPARE(intItemLast.count(), 0); // Test: kill the client client->kill(); client->waitForFinished(); clientStarted = false; // It takes some time and event processing until we get the signal int i = 0; while (intItemLast.count() == 0 && i++ < 100) QCoreApplication::processEvents(QEventLoop::AllEvents); // Expected result: we get a notification that the key was unsubscribed QCOMPARE(intItemFirst.count(), 1); QCOMPARE(intItemLast.count(), 1); }
void ServiceTest::recreateProperty() { // Check that the initialization went well. // Doing this only in init() is not enough; doesn't stop the test case. QVERIFY(clientStarted); // Use a different service name in each test; this way the ServiceBackends QString serviceName = QString::number(serviceNameIx).prepend(SERVICE_NAME); writeToClient(("assign session " + serviceName + " service\n").toStdString().c_str()); ++serviceNameIx; // Test: create a Service and an associated Property. Set a value // to the property. Service* service = new Service(QDBusConnection::SessionBus, serviceName); Property* property = new Property(*service, "Test.Property"); property->setValue("keep this value"); // Test: delete the property and create it again delete property; property = new Property(*service, "Test.Property"); // Expeted result: the Property has kept its value QCOMPARE(property->value(), QVariant("keep this value")); delete property; delete service; }
int writeToAllClients(char *foo) { int c; for (c = 0; c < maxClients; c++) writeToClient(c, foo); return 0; }
/* * Handles opening request, parsing head/body and sending * appropriate response. */ void session_handler(Request* req){ int client_soc = req->fd; /* Parsing request */ char buf[4096]={0}; unsigned int buf_int=0; /* Calling function readn to read the client socket */ int reqst = readn(client_soc, buf, 4096); if(reqst == -1){ perror("Request Err: Failed to read from socket."); close(client_soc); return; }else{ buf_int += reqst; } buf[buf_int] = '\0'; //returns pointer to first instance of "GET" char * GET = strstr(buf, "GET"); if(GET){ char * filename = &GET[5]; char * filename_end = strchr(filename, ' '); filename_end[0] = '\0'; printf("Requesting file '%s'\n", filename); /* Check file */ FILE * fl = fopen(filename, "r"); if(fl){ writeToClient(&client_soc,filename,fl); fclose(fl); }else{ fprintf(stderr, "Failed to open file '%s'\n", filename); /* Display ERROR message on the browser */ char* no_file = "<html>\n<body>\n404 File Not Found." "\n</body>\n</html>\n"; /* Send the Header and Body of the ERROR message to the browser*/ sendHTTPheader(client_soc, 4); printf("Sending the following body to the browser:\n"); printf("%s\n",no_file); printf("^end of message^\n"); writen(client_soc, no_file, strlen(no_file)); } }else{ fprintf(stderr, "Invalid GET request\n"); /* Display ERROR message on the browser */ char* no_get = "<html>\n<body>\n Invalid Request. Must be GET." "\n</body>\n</html>\n"; /* Send the Header and Body of the ERROR message to the browser*/ sendHTTPheader(client_soc, 0); printf("Sending the following body to the browser:\n"); printf("%s\n",no_get); printf("^end of message^\n"); writen(client_soc,no_get, strlen(no_get)); } close(client_soc); fflush(stdout); }
void ServiceTest::multiStart() { // Check that the initialization went well. // Doing this only in init() is not enough; doesn't stop the test case. QVERIFY(clientStarted); // Use a different service name in each test; this way the ServiceBackends QString serviceName = QString::number(serviceNameIx).prepend(SERVICE_NAME); writeToClient(("assign session " + serviceName + " service\n").toStdString().c_str()); ++serviceNameIx; // Test: create a Service and an associated Property Service* service = new Service(QDBusConnection::SessionBus, serviceName); Property* property = new Property(*service, "Test.Property"); // Test: command client to subscribe QString actual = writeToClient("subscribe service Test.Property\n"); // Expected result: service is started automatically and Subscribe works QString expected = "Subscribe returned: Unknown"; QCOMPARE(actual.simplified(), expected.simplified()); // Start listening to signals (we already have one subscriber) QSignalSpy firstSpy(property, SIGNAL(firstSubscriberAppeared(const QString&))); QSignalSpy lastSpy(property, SIGNAL(firstSubscriberAppeared(const QString&))); // Test: start the service again (even though it's started) service->start(); // Expected result: the service is still there, and remembers the client actual = writeToClient("subscribe service Test.Property\n"); expected = "Subscribe returned: Unknown"; QCOMPARE(actual.simplified(), expected.simplified()); // (so we don't get a signal) QTest::qWait(1000); QCOMPARE(firstSpy.count(), 0); QCOMPARE(lastSpy.count(), 0); delete service; delete property; }
void ServiceTest::recreate() { // Check that the initialization went well. // Doing this only in init() is not enough; doesn't stop the test case. QVERIFY(clientStarted); // Use a different service name in each test; this way the ServiceBackends QString serviceName = QString::number(serviceNameIx).prepend(SERVICE_NAME); writeToClient(("assign session " + serviceName + " service\n").toStdString().c_str()); ++serviceNameIx; // Test: create a Service and an associated Property Service* service = new Service(QDBusConnection::SessionBus, serviceName); Property* property = new Property(*service, "Test.Property"); // Test: command client to subscribe QString actual = writeToClient("subscribe service Test.Property\n"); // Expected result: service is started automatically and Subscribe works QString expected = "Subscribe returned: Unknown"; QCOMPARE(actual.simplified(), expected.simplified()); // Test: delete the property and the service delete property; delete service; actual = writeToClient("subscribe service Test.Property\n"); // Expected result: the client can no more subscribe expected = "Subscribe error: org.freedesktop.DBus.Error.ServiceUnknown"; QCOMPARE(actual.simplified(), expected.simplified()); // Test: recreate the service and try to subscribe again service = new Service(QDBusConnection::SessionBus, serviceName); property = new Property(*service, "Test.Property"); actual = writeToClient("subscribe service Test.Property\n"); // Expected result: service is started and Subscribe works expected = "Subscribe returned: Unknown"; QCOMPARE(actual.simplified(), expected.simplified()); delete service; delete property; }
void SubscriptionTests::multiSubscribe() { // Check that the initialization went well. // Doing this only in init() is not enough; doesn't stop the test case. QVERIFY(clientStarted); test_int->setValue(567); // Ask the client to call Subscribe for a property twice. The // property exists and has a value. QString actual1 = writeToClient("subscribe service1 Test.Int\n"); QString actual2 = writeToClient("subscribe service1 Test.Int\n"); // Expected result: both Subscribes return the same value. QString expected("Subscribe returned: int:567"); QCOMPARE(actual1.simplified(), expected.simplified()); QCOMPARE(actual2.simplified(), expected.simplified()); }
void SubscriptionTests::subscribeReturnValueForUnknownProperty() { // Check that the initialization went well. // Doing this only in init() is not enough; doesn't stop the test case. QVERIFY(clientStarted); // Ask the client to call Subscribe with 1 valid key. The property // is currently unknown since we haven't set a value for it. QString actual = writeToClient("subscribe service1 Test.Int\n"); // Expected result: The return value of Subscribe contains the key as unknown. QString expected("Subscribe returned: Unknown"); QCOMPARE(actual.simplified(), expected.simplified()); }
void SubscriptionTests::illegalUnsubscribe() { // Check that the initialization went well. // Doing this only in init() is not enough; doesn't stop the test case. QVERIFY(clientStarted); // Ask the client to call Unubscribe for a property which we're // not subscribed to. The property exists and is currently unknown // since we haven't set a value for it. QString actual = writeToClient("unsubscribe service1 Test.Int\n"); // Expected result: Unsubscribe succeeds. QString expected("Unsubscribe called"); QCOMPARE(actual.simplified(), expected.simplified()); }
void SubscriptionTests::subscribeReturnValueForKnownProperty() { // Check that the initialization went well. // Doing this only in init() is not enough; doesn't stop the test case. QVERIFY(clientStarted); // Set a value for a property test_double->setValue(-8.22); // Ask the client to call Subscribe with 1 valid key. The property // has a value we just set. QString actual = writeToClient("subscribe service1 Test.Double\n"); // Expected result: The return value of Subscribe contains the key and its value. QString expected("Subscribe returned: double:-8.22"); QCOMPARE(actual.simplified(), expected.simplified()); }
static void cgiEvent(MaQueue *q, MprCmd *cmd, int channel) { MaConn *conn; MaResponse *resp; MprBuf *buf; int space, nbytes, err; mprLog(cmd, 6, "CGI callback channel %d", channel); buf = 0; conn = q->conn; resp = conn->response; mprAssert(resp); cmd->lastActivity = mprGetTime(cmd); switch (channel) { case MPR_CMD_STDIN: writeToCGI(q->pair); return; case MPR_CMD_STDOUT: buf = cmd->stdoutBuf; break; case MPR_CMD_STDERR: buf = cmd->stderrBuf; break; } mprAssert(buf); mprResetBufIfEmpty(buf); /* Come here for CGI stdout, stderr events. ie. reading data from the CGI program. */ while (mprGetCmdFd(cmd, channel) >= 0) { /* Read as much data from the CGI as possible */ do { if ((space = mprGetBufSpace(buf)) == 0) { mprGrowBuf(buf, MA_BUFSIZE); if ((space = mprGetBufSpace(buf)) == 0) { break; } } nbytes = mprReadCmdPipe(cmd, channel, mprGetBufEnd(buf), space); mprLog(q, 5, "CGI: read from gateway %d on channel %d. errno %d", nbytes, channel, nbytes >= 0 ? 0 : mprGetOsError()); if (nbytes < 0) { err = mprGetError(); if (err == EINTR) { continue; } else if (err == EAGAIN || err == EWOULDBLOCK) { break; } mprLog(cmd, 5, "CGI read error %d for %", mprGetError(), (channel == MPR_CMD_STDOUT) ? "stdout" : "stderr"); mprCloseCmdFd(cmd, channel); } else if (nbytes == 0) { /* This may reap the terminated child and thus clear cmd->process if both stderr and stdout are closed. */ mprLog(cmd, 5, "CGI EOF for %s", (channel == MPR_CMD_STDOUT) ? "stdout" : "stderr"); mprCloseCmdFd(cmd, channel); break; } else { mprLog(cmd, 5, "CGI read %d bytes from %s", nbytes, (channel == MPR_CMD_STDOUT) ? "stdout" : "stderr"); mprAdjustBufEnd(buf, nbytes); traceData(cmd, mprGetBufStart(buf), nbytes); } } while ((space = mprGetBufSpace(buf)) > 0); if (mprGetBufLength(buf) == 0) { return; } if (channel == MPR_CMD_STDERR) { /* If we have an error message, send that to the client */ if (mprGetBufLength(buf) > 0) { mprAddNullToBuf(buf); mprLog(conn, 4, mprGetBufStart(buf)); if (writeToClient(q, cmd, buf, channel) < 0) { return; } maSetResponseCode(conn, MPR_HTTP_CODE_SERVICE_UNAVAILABLE); cmd->userFlags |= MA_CGI_SEEN_HEADER; cmd->status = 0; } } else { if (!(cmd->userFlags & MA_CGI_SEEN_HEADER) && !parseHeader(conn, cmd)) { return; } if (cmd->userFlags & MA_CGI_SEEN_HEADER) { if (writeToClient(q, cmd, buf, channel) < 0) { return; } } } } }
void CallSetuptState::processRequest(const std::string &data, User &context) { std::cout << context.getUid() << " in CallSetuptState " << data.substr(0, 10) << std::endl; if (data.compare(0, 3, "cnr") == 0) { // client wants to dial a peer string encrypted = data.substr(4); //take data part auto elements = StringHelper::split(encrypted, ','); string dest_uid(elements->at(0)); string my_pub_key(elements->at(1)); std::replace(my_pub_key.begin(), my_pub_key.end(), ':', '\n'); context.setMypubKey(my_pub_key); try { if (context.getUid() == dest_uid) { throw Poco::InvalidAccessException("You cannot call yourself "); } auto receiver = LoggedUsersMap::getInstance().findUser(dest_uid); //throws out_of_range exception if (receiver != nullptr && receiver->getCurrentState()==&LoginState::getInstance()) { //this is not necessary. But checking it won't kill you shared_ptr <CallAggregator> session(new CallAggregator()); context.setSession(session); receiver->setSession(context.Session()); // receiver will register itself as a observer on 'kcs' event int bytes = receiver->writeToClientBlocking(CERT_REQUEST, 5000); if (bytes < 0) { throw IOException("write failed"); } receiver->setCurrent_state(CallSetuptState::getInstance()); context.Session()->registerAsCaller(context.shared_from_this()); cout << "registered as a caller" << endl; std::thread async_thread(std::function<void()>([&context]() -> void { //local variable should be copied auto caller = context.shared_from_this();//we can use 'context' reference but need to keep User object until thread ends string sessionKey = context.Session()->getSessionKey(); try { cout << "waiting for receiver TID :" << std::this_thread::get_id() << endl; bool timeoutReached = context.Session()->wait_for_receiver(10);//seconds //encrpt and send skey if (!timeoutReached && caller.use_count() > 1) { //if time out not reached and this is not the only reference caller->_behaviours->getCallInitializerBehaviour().sendSessionKey(sessionKey, *caller, false); //throws exceptions caller->setCurrent_state(CallingState::getInstance()); } else { throw Poco::NotFoundException("Receiver end failed"); } } catch (const Poco::Exception &e) { cerr << e.message() << endl; caller->writeToClient(REMOTE_USER_NOT_AVAILABLE); context.writeToClient(DISCONNECT);// DISCONNECT does not work if (caller->Session().get()) { caller->Session()->unregisterObserver(caller); caller->Session() = nullptr; cout << "session cleared" << endl; } caller->setCurrent_state(LoginState::getInstance()); } catch (exception &e) { cerr << "In async thread " << e.what() << endl; } })); /*std::this_thread::sleep_until(std::chrono::system_clock::now() + std::chrono::nanoseconds(1000));//wait till lambda func till copy args*/ async_thread.detach(); // now thread object can be deleted without affecting the running thread } else{ cout << "user " << dest_uid << " not available" << endl; //this_thread::__sleep_for(std::chrono::seconds(3),std::chrono::nanoseconds(0)); context.writeToClient(REMOTE_USER_NOT_AVAILABLE); context.setCurrent_state(LoginState::getInstance()); } } catch (const std::out_of_range &e) { // from find(uid) cout << "user " << dest_uid << " not available" << endl; //this_thread::__sleep_for(std::chrono::seconds(3),std::chrono::nanoseconds(0)); context.writeToClient(REMOTE_USER_NOT_AVAILABLE); context.setCurrent_state(LoginState::getInstance()); } catch (const Poco::InvalidAccessException &e) { //if caller==callie context.writeToClient(REMOTE_USER_NOT_AVAILABLE, 0); cerr << e.message() << endl; context.setCurrent_state(LoginState::getInstance()); } catch (const IOException &e) { //when writing to a closed Socket context.writeToClient(REMOTE_USER_NOT_AVAILABLE, 0); cerr << e.message() << endl; context.setCurrent_state(LoginState::getInstance()); } catch (const Poco::NullPointerException &e) { //when trying to write after SocketConnection is deleted; context.writeToClient(REMOTE_USER_NOT_AVAILABLE, 0); cerr << e.message() << endl; context.setCurrent_state(LoginState::getInstance()); } // my_pub_key.replace(':','',); }//this part has to be extracted to a seperte state. // unless receiver can process call request prior receiving cert request else if (data.compare(0, 3, "kcs") == 0) { //certificate response to server's request string my_pub_key = data.substr(4); //take data part std::replace(my_pub_key.begin(), my_pub_key.end(), ':', '\n'); context.setMypubKey(my_pub_key); if (context.Session().get()) {// session could have been ended by caller context.Session()->registerAsReceiver(context.shared_from_this()); string sKey(context.Session()->getSessionKey()); context.Session()->notify_caller(); //Notify waiting caller try { context._behaviours->getCallInitializerBehaviour().sendSessionKey(sKey, context, true); context.setCurrent_state(RingingState::getInstance()); } catch (const Poco::Exception &e) { context.writeToClient(DISCONNECT); context.setCurrent_state(LoginState::getInstance()); } } else { context.setCurrent_state(LoginState::getInstance()); } } else if (data.compare(0, 3, "rej") == 0) {//while caller is waiting itself can cancel the call if (context.Session().get()) { context.Session()->interrupt_caller(); } } }
int main(int argc, char *argv[]) { char str[50]; FILE *file; int i,numberTrueAnswer=0; char *clientFile="/home/user/workspace/server/registration.txt"; char numberTest='0'; char *name=(char*)malloc(50*sizeof(char)); int sockfd, newsockfd, portno, clilen; const int on = 1; char buffer[256]; struct sockaddr_in serv_addr, cli_addr; int n; sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { perror("ERROR opening socket"); exit(1); } setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); bzero((char *) &serv_addr, sizeof(serv_addr)); portno = 5001; serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(portno); if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { perror("ERROR on binding"); exit(1); } listen(sockfd, 5); clilen = sizeof(cli_addr); newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen); if (newsockfd < 0) { perror("ERROR on accept"); exit(1); } //Connect from client while(1){ bzero(buffer, 256); n = read(newsockfd, buffer, 255); if (n < 0) { perror("ERROR reading from socket"); exit(1); } if(buffer[0]=='!'){ n = write(newsockfd, "Login", 5); break; } n = write(newsockfd, "ERROR", 5); } /*//Registration int numberClient; int clientSize=sizeFile(clientFile); struct Client c[clientSize]; file = fopen(clientFile, "r"); for (i = 0; fgets(str, sizeof(str), file); i++) { writeSizeClient(&c[i], &str); } fclose(file); while(1){ numberClient=-1; bzero(buffer, 256); n = read(newsockfd, buffer, 255); for (i = 0; i<clientSize; i++) { if(strcmp(buffer, strcat(c[i].login,"\n"))==0){ numberClient=i; break; }} if(numberClient!=-1){ n = write(newsockfd, "Parol", 5); break; } n = write(newsockfd, "Login", 5); } //Enter Password while(1){ bzero(buffer, 256); n = read(newsockfd, buffer, 255); if(strcmp(buffer, strcat(c[numberClient].parol, "\n"))==0){ n = write(newsockfd, "OK", 2); break; } n = write(newsockfd, "Parol", 5); } //Enter last result char *string=writeLastResult(&c[numberClient]); printf("%s",string);*/ //Number test while (1){ bzero(buffer, 256); n = read(newsockfd, buffer, 255); numberTest = buffer[0]; name=(char*)malloc(50*sizeof(char)); sprintf(name, "%s%c%s", "/home/user/workspace/server/",numberTest, ".txt"); if((file = fopen(name, "r"))!=NULL){ n = write(newsockfd, "OK", 2); break; } n = write(newsockfd, "ERROR", 5); free(name); } int testSize = sizeFile(name); struct Line x[testSize]; file = fopen(name, "r"); for (i = 0; fgets(str, sizeof(str), file); i++) { writeSize(&x[i], &str); } fclose(file); for (i = 0; i < testSize; i++) { char *stringOut = writeToClient(&x[i]); n = write(newsockfd, stringOut, strlen(stringOut)); printf("%d", strlen(stringOut)); bzero(buffer, 256); n = read(newsockfd, buffer, 255); if (n < 0) { perror("ERROR reading from socket"); exit(1); } printf("Answer: %s\n", buffer); if (buffer[0] == x[i].trueAnswer){ n = write(newsockfd, "Right\n", 6); numberTrueAnswer=numberTrueAnswer+1; } else n = write(newsockfd, "Wrong\n", 6); if (n < 0) { perror("ERROR writing to socket"); exit(1); } } free(name); name=(char*)malloc(100*sizeof(char)); sprintf(name, "%s%d\n%s%d\n", "Number of question ",testSize, "Number of true answer is ",numberTrueAnswer); n = write(newsockfd, name, strlen(name)); if (n < 0) { perror("ERROR writing to socket"); exit(1); } n = write(newsockfd, "!\n", 2); for (i = 0; i < testSize; i++) freeLine(&x[i]); free(name); //for (i = 0; i < clientSize; i++) //freeClient(&c[i]); return 0; }
// Tell joke to client, which is already accepted at [(int) socket]. void tellJokeToClient(int socket) { // Read from socket. int checkRead; char request[MAX_MESSAGE_LENGTH]; bzero(request, MAX_MESSAGE_LENGTH); checkRead = read(socket, request, MAX_MESSAGE_LENGTH - 1); if (checkRead < 0) { perror("Could not read from socket.\n"); exit(1); } // Checking format correctness if (checkRead < 3 || request[0] != JOKER_REQUEST_TYPE || checkRead != 3 + (uint8_t)request[1] + (uint8_t)request[2]) { perror("Request format error.\n"); writeToClient(socket, "Malformed (wrong type)", 22); exit(1); } char outputInfo[MAX_MESSAGE_LENGTH]; sprintf(outputInfo, "Received following message: "); strncat(outputInfo, request + 3, (uint8_t)request[1] + (uint8_t)request[2]); printf("%s\n", outputInfo); // 2nd and 3rd byte have to be numbers in range of 0 - 255 (Firstname/Lastname length). // Every char is a number in this range, thus the check of 2nd and 3rd byte can be omitted. // Wrong numbers are not harmful (tested). // Receive length of firstname from request. uint8_t lengthFirstName = (int)request[1]; // Receive length of lastname from request. uint8_t lengthLastName = (int)request[2]; // Receive firstname from request. char firstName[lengthFirstName + 1]; strncpy(firstName, request + 3, lengthFirstName); firstName[lengthFirstName] = '\0'; // Receive lastname from request. char lastName[lengthLastName + 1]; strncpy(lastName, request + 3 + lengthFirstName, lengthLastName); lastName[lengthLastName] = '\0'; printf("First name: %s. %i characters.\n", firstName, lengthFirstName); printf("Last name: %s. %i characters.\n", lastName, lengthLastName); // Select a joke and concatenate it with user's name. char * text[] = { "how do you make a dog sound like a cat? You freeze the dog and cut it with a chainsaw. MEEEEEEOOOOOWWW.", "how do you make a cat sound like a dog? You dump gas over the cat and set it on fire. WOOOOOF." }; srand(time(NULL)); int random = rand() % 2; int jokeLength = strlen(text[random]) + lengthFirstName + lengthLastName + 9; char joke[jokeLength]; bzero(joke, jokeLength); strcat(joke, "Hello "); strcat(joke, firstName); strcat(joke, " "); strcat(joke, lastName); strcat(joke, ", "); strcat(joke, text[random]); // Create response. int responseLength = strlen(joke) + 5; char response[responseLength]; bzero(response, responseLength); // First byte is of JOKER_RESPONSE TYPE. response[0] = JOKER_RESPONSE_TYPE; // 2nd to 5th byte is the length of the joke. uint32_t lengthOfJoke = htonl(strlen(joke)); memcpy(response + 1, &lengthOfJoke, sizeof(lengthOfJoke)); // From 6th byte on, the joke occurs. memcpy(response + 5, joke, strlen(joke)+1); // Finally write joke to client with correct format. writeToClient(socket, response, responseLength); }
void SubscriptionTests::subscriberNotifications() { // Check that the initialization went well. // Doing this only in init() is not enough; doesn't stop the test case. QVERIFY(clientStarted); QSignalSpy intItemFirst(test_int, SIGNAL(firstSubscriberAppeared(const QString&))); QSignalSpy intItemLast(test_int, SIGNAL(lastSubscriberDisappeared(const QString&))); QSignalSpy doubleItemFirst(test_double, SIGNAL(firstSubscriberAppeared(const QString&))); QSignalSpy doubleItemLast(test_double, SIGNAL(lastSubscriberDisappeared(const QString&))); QSignalSpy stringItemFirst(test_string, SIGNAL(firstSubscriberAppeared(const QString&))); QSignalSpy stringItemLast(test_string, SIGNAL(lastSubscriberDisappeared(const QString&))); QSignalSpy boolItemFirst(test_bool, SIGNAL(firstSubscriberAppeared(const QString&))); QSignalSpy boolItemLast(test_bool, SIGNAL(lastSubscriberDisappeared(const QString&))); // Test: ask the client to call Subscribe to 2 keys writeToClient("subscribe service1 Test.Int\n"); writeToClient("subscribe service1 Test.Double\n"); // Expected result: we get the notifications for the subscribed keys QCOMPARE(intItemFirst.count(), 1); QCOMPARE(intItemLast.count(), 0); QCOMPARE(doubleItemFirst.count(), 1); QCOMPARE(doubleItemLast.count(), 0); // But not for the other ones QCOMPARE(stringItemFirst.count(), 0); QCOMPARE(stringItemLast.count(), 0); QCOMPARE(boolItemFirst.count(), 0); QCOMPARE(boolItemLast.count(), 0); // Clear the results intItemFirst.clear(); doubleItemFirst.clear(); // Test: subscribe to one more key (note different bus name) writeToClient("subscribe service2 Test.Bool\n"); // Expected result: a notification for the corresponding property, not for others QCOMPARE(intItemFirst.count(), 0); QCOMPARE(intItemLast.count(), 0); QCOMPARE(doubleItemFirst.count(), 0); QCOMPARE(doubleItemLast.count(), 0); QCOMPARE(boolItemFirst.count(), 1); QCOMPARE(boolItemLast.count(), 0); QCOMPARE(stringItemFirst.count(), 0); QCOMPARE(stringItemLast.count(), 0); // Clear the results boolItemFirst.clear(); // Test: Unsubscribe from one of the keys writeToClient("unsubscribe service1 Test.Double\n"); // Expected result: QCOMPARE(intItemFirst.count(), 0); QCOMPARE(intItemLast.count(), 0); QCOMPARE(doubleItemFirst.count(), 0); QCOMPARE(doubleItemLast.count(), 1); QCOMPARE(boolItemFirst.count(), 0); QCOMPARE(boolItemLast.count(), 0); QCOMPARE(stringItemFirst.count(), 0); QCOMPARE(stringItemLast.count(), 0); // Clear the results doubleItemLast.clear(); // Unsubscribe from the rest of the keys, too writeToClient("unsubscribe service1 Test.Int\n"); writeToClient("unsubscribe service2 Test.Bool\n"); // Expected result: QCOMPARE(intItemFirst.count(), 0); QCOMPARE(intItemLast.count(), 1); QCOMPARE(doubleItemFirst.count(), 0); QCOMPARE(doubleItemLast.count(), 0); QCOMPARE(boolItemFirst.count(), 0); QCOMPARE(boolItemLast.count(), 1); QCOMPARE(stringItemFirst.count(), 0); QCOMPARE(stringItemLast.count(), 0); // Clear the results intItemLast.clear(); boolItemLast.clear(); }