int readFromPipe(int inputPipe, char * buffer, int * terminalPid, TerminalList * termlist) { int len; int op; int statsPipe; double totalTime; TESTTRUE((read(inputPipe, &op, sizeof(int))==sizeof(int)), "Erro no formato do pipe (" _AT_ ")\n"); printf("\nNew operation:\n"); printf("op: %d\n", op); if (op==0) { TESTTRUE((read(inputPipe, &len, sizeof(int)) == sizeof(int)), "Erro no formato do pipe (" _AT_ ")\n"); printf("len: %d\n", len); TESTTRUE((read(inputPipe, terminalPid, sizeof(int)) == sizeof(int)), "Erro no formato do pipe (" _AT_ ")\n"); printf("pid: %d\n", *terminalPid); TESTTRUE((read(inputPipe, buffer, len) == len), "Erro no formato do pipe (" _AT_ ")\n"); buffer[len]=0; return 0; } else if (op==1) { //informacao que foi criado um novo terminal TESTTRUE((read(inputPipe, terminalPid, sizeof(int)) == sizeof(int)), "Erro no formato do pipe (" _AT_ ")\n"); lst_insert(termlist, *terminalPid); printf("pid: %d\n", *terminalPid); return 1; } else if (op==2) { //informacao que foi fechado um terminal TESTTRUE((read(inputPipe, terminalPid, sizeof(int)) == sizeof(int)), "Erro no formato do pipe (" _AT_ ")\n"); lst_remove(termlist, *terminalPid); printf("pid: %d\n", *terminalPid); return 2; } else if (op==3) { //informacao que e para se fechar a par-shell exitCalled = 1; return 3; } else if (op==4) {//recebeu um stats TESTTRUE((read(inputPipe, &len, sizeof(int)) == sizeof(int)), "Erro no formato do pipe (" _AT_ ")\n"); printf("len: %d\n", len); TESTTRUE((read(inputPipe, terminalPid, sizeof(int)) == sizeof(int)), "Erro no formato do pipe (" _AT_ ")\n"); printf("pid: %d\n", *terminalPid); TESTTRUE((read(inputPipe, buffer, len) == len), "Erro no formato do pipe (" _AT_ ")\n"); buffer[len]=0; if ((statsPipe = open(buffer, O_WRONLY)) < 0) { fprintf(stderr, "Erro ao abrir o ficheiro de output " INPUT_FILE "\n"); exit(EXIT_FAILURE); } totalTime = getTotalTime(); if (write(statsPipe, (char*)&runningProcesses, sizeof(int)) != sizeof(int)) { fprintf(stderr, "Warning: erro a escrever para um pipe\n"); } if (write(statsPipe, (char*)&totalTime, sizeof(double)) != sizeof(double)) { fprintf(stderr, "Warning: erro a escrever para um pipe \n"); } if (close(statsPipe)) { fprintf(stderr, "Warning: erro ao fechar um pipe \n"); } return 4; } fprintf(stderr,"Warning: Unknown operator!\n"); return -1; }
void CTestMachine::CheckViewOrderL(const CContactViewBase* aView, TBool aPrint, TBool aReverseOrder) { ASSERT(aView); const TInt numOfCont = aView->CountL(); TInt prevOrder = aReverseOrder ? 99 : -1; //used for first comparison //99 - More than items in database, -1 less than an index of first item for (TInt i=0; i < numOfCont; ++i) { const CViewContact& theContact = aView->ContactAtL(i); const TPtrC& theNum = theContact.Field(2); const TPtrC& theFamilyName = theContact.Field(0); if (aPrint) { //Print only if we asked to const TPtrC& theGivenName = theContact.Field(1); test.Printf(_L("%S %S, %S\n"), &theNum, &theFamilyName, &theGivenName); } //Order checking //The number of contact in alphabetically sorted list is given in MiddleName field TLex16 strOrder(theNum); TInt currOrder; TESTNOERRL(strOrder.Val(currOrder)) //Convert string to integer if (aReverseOrder) TESTTRUE(prevOrder > currOrder) //Descending order for reverse sorting else TESTTRUE(prevOrder < currOrder) //Ascending order for forward sorting prevOrder = currOrder; } }
int main(int argc, char** argv) { int outfileid; char * c; char buffer[BUFFER_LEN]; char * buffer_aux; char mktemp_filename[PATH_MAX]; char mktemp_dir[PATH_MAX]; int len, pid, mode; char * orig; int inputPipe; int totalProc; double totalTime; pid = getpid(); if (argc!=2) { fprintf(stderr, "Modo de utilizacao: %s <pathname para o pipe>", argv[0]); exit(EXIT_FAILURE); } if ((outfileid = open(argv[1], O_WRONLY)) < 0) { fprintf(stderr, "Could not create fifo %s\n", argv[1]); exit(EXIT_FAILURE); } mode = 1; orig = (char*)&mode; memcpy(buffer, orig, sizeof(int)); orig = (char*)&pid; memcpy(buffer+sizeof(int), orig, sizeof(int)); TESTTRUE(write(outfileid, buffer, 2*sizeof(int))==2*sizeof(int), "Erro na escrite para o pipe (" _AT_ ")\n"); showPrompt(); buffer_aux = buffer + 3*sizeof(int); while ((c = fgets(buffer_aux, BUFFER_LEN - 3*sizeof(int), stdin)) > 0) { //printf("\"%s\"\n", buffer_aux); if (c == NULL || *c == EOF) { break; } if (strcmp("exit\n", buffer_aux)==0) { break; } if (strcmp("exit-global\n", buffer_aux)==0) { mode = 3; orig = (char*)&mode; memcpy(buffer, orig, sizeof(int)); TESTTRUE(write(outfileid, buffer, sizeof(int))==sizeof(int), "Erro na escrite para o pipe (" _AT_ ")\n"); pause(); //o processo vai morrer, mas ate la pausamos exit(EXIT_FAILURE); } if (strcmp("stats\n", buffer_aux)==0) { strcpy(mktemp_dir, MKTEMP_TEMPLATE); TESTTRUE(mkdtemp(mktemp_dir)!=NULL, "Erro na criação do diretorio temporário (" _AT_ "\n"); strncpy(mktemp_filename, mktemp_dir, PATH_MAX); strncpy(mktemp_filename+strlen(mktemp_filename), "/out", PATH_MAX-strlen(mktemp_filename)); if (mkfifo(mktemp_filename, 0660) <0) { fprintf(stderr, "Could not create fifo " INPUT_FILE "\n"); exit(EXIT_FAILURE); } len = strlen(mktemp_filename); strncpy(buffer_aux, mktemp_filename, BUFFER_LEN - 3*sizeof(int)); mode = 4; orig = (char*)&mode; memcpy(buffer, orig, sizeof(int)); orig = (char*)&len; memcpy(buffer+sizeof(int), orig, sizeof(int)); orig = (char*)&pid; memcpy(buffer+2*sizeof(int), orig, sizeof(int)); TESTTRUE(write(outfileid, buffer, 3*sizeof(int) + len)==3*sizeof(int) + len, "Erro na escrita para o pipe (" _AT_ ")\n"); if ((inputPipe = open(mktemp_filename, O_RDONLY)) < 0) { fprintf(stderr, "Could not create fifo " INPUT_FILE "\n"); exit(EXIT_FAILURE); } TESTTRUE((read(inputPipe, &totalProc, sizeof(int))==sizeof(int)), "Erro no formato do pipe (" _AT_ ")\n"); TESTTRUE((read(inputPipe, &totalTime, sizeof(double))==sizeof(double)), "Erro no formato do pipe (" _AT_ ")\n"); printf("Numero total de processos: %d\n" "Tempo total: %f\n", totalProc, totalTime); close(inputPipe);//nao faz sentido testarmos isto, pois e um ficheiro temporario unlink(mktemp_filename);//nao faz sentido testarmos isto, pois e um ficheiro temporario unlink(mktemp_dir);//nao faz sentido testarmos isto, pois e um ficheiro temporario showPrompt(); continue; } //Caso comando normal: len = strlen(buffer_aux); len++; mode = 0; orig = (char*)&mode; memcpy(buffer, orig, sizeof(int)); orig = (char*)&len; memcpy(buffer+sizeof(int), orig, sizeof(int)); orig = (char*)&pid; memcpy(buffer+2*sizeof(int), orig, sizeof(int)); TESTTRUE(write(outfileid, buffer, 3*sizeof(int) + len)==3*sizeof(int) + len, "Erro na escrite para o pipe (" _AT_ ")\n"); showPrompt(); } mode = 2; orig = (char*)&mode; memcpy(buffer, orig, sizeof(int)); orig = (char*)&pid; memcpy(buffer+sizeof(int), orig, sizeof(int)); TESTTRUE(write(outfileid, buffer, 2*sizeof(int))==2*sizeof(int), "Erro na escrite para o pipe (" _AT_ ")\n"); return close(outfileid); }
void CTestMachine::StepFindViewsL() { const TContactViewPreferences viewPrefs = TContactViewPreferences(EUnSortedAtEnd | EContactsOnly); _LIT(KMansell, "Mansell"); BEGIN_ASYNC_TEST ///////////////////////////////////////// //Actions: Create a local view with reverse sort plugin TESTTRAP(iLocalView = CContactLocalView::NewL(*this, *iDb, iSurnNameSortOrder, viewPrefs, KReverseSortPlugin)); WAIT_EVENT(1) //Expected Result: Check the order of entries in the view - it must be reverse. test.Printf(_L("Local View created:\n")); CheckViewOrderL(iLocalView); test.Printf(_L("\n\n")); ///////////////////////////////////////// //Actions: Create a remote view with reverse sort plugin TESTTRAP(iRemoteViewReverse = CContactRemoteView::NewL(*this, *iDb, iSurnNameSortOrder, viewPrefs, KReverseSortPlugin)); WAIT_EVENT(2) //Expected Result: Check the order of entries in the view - it must be reverse. test.Printf(_L("Remote View created:\n")); CheckViewOrderL(iRemoteViewReverse); test.Printf(_L("\n\n")); ///////////////////////////////////////// //Actions: Create a remote view with default sorting behaviour TESTTRAP(iRemoteViewForward = CContactRemoteView::NewL(*this, *iDb, iSurnNameSortOrder, viewPrefs)); WAIT_EVENT(3) //Expected Result: Check the order of entries in the view - it must be forward test.Printf(_L("Remote View created:\n")); CheckViewOrderL(iRemoteViewForward, EFalse, EFalse); //do not Print, forward order test.Printf(_L("\n\n")); ///////////////////////////////////////// //Actions: Create a Find view on top of the local view, using "Ma" search string iFindDesArray =new(ELeave)CPtrC16Array(1); _LIT(KMa,"Ma"); iFindDesArray->AppendL(TPtrC(KMa)); iLocalFindView= CContactFindView::NewL(*iDb,*iLocalView,*this,iFindDesArray); WAIT_EVENT(4) //Expected Result: Check the order of entries in the find view - it must be reverse test.Printf(_L("LocalFind View created:\n")); CheckViewOrderL(iLocalFindView); test.Printf(_L("\n\n")); ///////////////////////////////////////// //Actions: Create a Find view on top of the reverse remote view, using "el" search string iFindDesArray->Reset(); _LIT(Kel,"el"); iFindDesArray->AppendL(TPtrC(Kel)); iRemoteFindView = CContactFindView::NewL(*iDb,*iRemoteViewReverse,*this,iFindDesArray); WAIT_EVENT(5) //Expected Result: Check the order of entries in the find view - it must be reverse test.Printf(_L("RemoteFind View created:\n")); CheckViewOrderL(iRemoteFindView); test.Printf(_L("\n\n")); ///////////////// //Actions: Add a new contact to the database, it must have "ma" and "el" substrings in it // to appear in either find view. Check the sorting in every view. _LIT8(KIrvVCard, "BEGIN:VCARD\r\nVERSION:2.1\r\nN:Mansell;Nigel;11\r\nPensioner\r\nEND:VCARD"); RDesReadStream stream(KIrvVCard); stream.PushL(); TBool success(EFalse); CArrayPtr<CContactItem>* contactItems=iDb->ImportContactsL(TUid::Uid(KUidVCardConvDefaultImpl), stream, success, NULL); CleanupStack::PopAndDestroy(); // stream PUSH(contactItems); TESTTRUE(success); test.Printf(_L("%d entry was added created\n"), contactItems->Count()); contactItems->ResetAndDestroy(); //Potential memory leak - must be pushed onto the stack with ResetAndDestroy POPD(contactItems); WAIT_EVENTS(6,5) //Waiting for 5 events to arrive (one from each view) //Note, that if all 5 events won't arrive the code will stuck here //It can be solved with another "timeout" active object, but not yet implemented //Expected Result: Every view must send an event (5 events in total). //Sort order for all the views except for RemoteForward view must be reverse. //New entry must be inserted in every view. test.Printf(_L("Local View:\n")); CheckViewOrderL(iLocalView); test.Printf(_L("\n\n")); test.Printf(_L("Remote View Reverse:\n")); CheckViewOrderL(iRemoteViewReverse); test.Printf(_L("\n\n")); test.Printf(_L("Remote View Forward:\n")); CheckViewOrderL(iRemoteViewForward, EFalse, EFalse); //do not Print, forward order test.Printf(_L("\n\n")); test.Printf(_L("Local Find View:\n")); CheckViewOrderL(iLocalFindView); test.Printf(_L("\n\n")); test.Printf(_L("Remote Find View:\n")); CheckViewOrderL(iRemoteFindView); test.Printf(_L("\n\n")); //Searching for Mansell in the DB. TContactItemId manselId = SearchInViewL(iLocalFindView, KMansell); TESTTRUEL(manselId != 0); //Have we found it? //Actions: Change a newly added contact from "Nigel Mansell" to "Ayrton Senna". CContactItem* mansContact = iDb->OpenContactLX(manselId); PUSH(mansContact); CContactItemFieldSet& fieldSet = mansContact->CardFields(); CContactItemField& givenNameField = fieldSet[fieldSet.Find(KUidContactFieldGivenName)]; givenNameField.TextStorage()->SetTextL(_L("Ayrton")); CContactItemField& familyNameField = fieldSet[fieldSet.Find(KUidContactFieldFamilyName)]; familyNameField.TextStorage()->SetTextL(_L("Senna")); CContactItemField& ordinalNumField = fieldSet[fieldSet.Find(KUidContactFieldAdditionalName)]; ordinalNumField.TextStorage()->SetTextL(_L("20")); //Number is used for sorting checking iDb->CommitContactL(*mansContact); POPD(mansContact); CleanupStack::PopAndDestroy(); //record lock WAIT_EVENTS(7,10) //Waiting for 10 events to arrive (delele and insert event from each view) //Actions: Check the sorting in every view. //Expected Result: 10 events should arrive - 5 deletes and 5 inserts. //Sort order for all the views except for RemoteForward view must be reverse. //The entry must be updated in local and remote views and should disappear //from Find views because it doesn't contain substrings "Ma" or "el" anymore. test.Printf(_L("Local View:\n")); CheckViewOrderL(iLocalView, ETrue); test.Printf(_L("\n\n")); test.Printf(_L("Remote View Reverse:\n")); CheckViewOrderL(iRemoteViewReverse, ETrue); test.Printf(_L("\n\n")); test.Printf(_L("Remote View Forward:\n")); CheckViewOrderL(iRemoteViewForward, EFalse, EFalse); //do not Print, forward order test.Printf(_L("\n\n")); test.Printf(_L("Local Find View:\n")); CheckViewOrderL(iLocalFindView, ETrue); test.Printf(_L("\n\n")); test.Printf(_L("Remote Find View:\n")); CheckViewOrderL(iRemoteFindView, ETrue); test.Printf(_L("\n\n")); //We changed Mansell to Senna - the entry shouldn't appear in either find views TContactItemId manselId = SearchInViewL(iLocalFindView, KMansell); TESTTRUE(manselId == 0); manselId = SearchInViewL(iRemoteFindView, KMansell); TESTTRUE(manselId == 0); CloseView(iLocalFindView); CloseView(iLocalView); CloseView(iRemoteFindView); CloseView(iRemoteViewReverse); CloseView(iRemoteViewForward); iFindDesArray->Reset(); delete iFindDesArray; iFindDesArray = NULL; END_ASYNC_TEST }
int main() { int inputPipe; char buffer[BUFFER_LEN]; char mktemp_filename[PATH_MAX]; char mktemp_dir[PATH_MAX]; int ret; int terminalPid; TerminalList * termlist = lst_new(); pthread_t threadMonitor; char *args[N_ARGS]; if (signal(SIGINT, handleSIGINT)) { fprintf(stderr, "Could not set sigint handler!\n"); exit(EXIT_FAILURE); } if (pthread_mutex_init(&mutexRunningProcesses, NULL)) { fprintf(stderr, "Could not create runningProcesses mutex\n"); exit(EXIT_FAILURE); } if (pthread_cond_init(&condRunningProcesses, NULL)) { fprintf(stderr, "Could not create runningProcesses cond\n"); exit(EXIT_FAILURE); } if (pthread_cond_init(&condFreeSlots, NULL)) { fprintf(stderr, "Could not create FreeSlots cond\n"); exit(EXIT_FAILURE); } strcpy(mktemp_dir, MKTEMP_TEMPLATE); TESTTRUE(mkdtemp(mktemp_dir)!=NULL, "Erro na criação do diretorio temporário (" _AT_ ")\n"); strncpy(mktemp_filename, mktemp_dir, PATH_MAX); strncpy(mktemp_filename+strlen(mktemp_filename), "/" INPUT_FILE, PATH_MAX-strlen(mktemp_filename)); fprintf(stdin, "Ficheiro de input: '%s'\n", mktemp_filename); if (mkfifo(mktemp_filename, 0660) <0) { fprintf(stderr, "Could not create fifo %s\n", mktemp_filename); exit(EXIT_FAILURE); } printf("A abrir o pipe %s para leitura...\n", mktemp_filename); if ((inputPipe = open(mktemp_filename, O_RDONLY)) < 0) { fprintf(stderr, "Could not create fifo " INPUT_FILE "\n"); exit(EXIT_FAILURE); } printf("A abrir o pipe %s para escrita...\n", mktemp_filename); if ((outPipe = open(mktemp_filename, O_WRONLY|O_NONBLOCK)) < 0) { fprintf(stderr, "Erro ao abrir o ficheiro de output" INPUT_FILE "\n"); exit(EXIT_FAILURE); } initProcessList(); if(pthread_create(&threadMonitor, 0,processMonitor, NULL)!= 0) { printf("Erro na criação da tarefa\n"); exit(EXIT_FAILURE); } while(1) { if (exitCalled) break; if (readFromPipe(inputPipe, buffer, &terminalPid, termlist)!=0) continue; printf("Comando: %s\n", buffer); ret = readLineArguments(args, N_ARGS, buffer, BUFFER_LEN); if (!ret) continue; processesWaitingToRun++; newProcess(args, terminalPid); } //Mata todos os processos de terminal lst_destroy(termlist); C_SIGNAL(&condRunningProcesses); pthread_join(threadMonitor, NULL); //The following function is called after all threads have joined, therefore there aren't used any mutexes exitParShell(); endProcessList(); pthread_mutex_destroy(&mutexRunningProcesses); pthread_cond_destroy(&condRunningProcesses); pthread_cond_destroy(&condFreeSlots); close(inputPipe); //aqui nao faz sentido testar o return destas funcoes close(outPipe); //aqui nao faz sentido testar o return destas funcoes unlink(INPUT_FILE); //aqui nao faz sentido testar o return destas funcoes return EXIT_SUCCESS; }