Exemplo n.º 1
0
Arquivo: test.c Projeto: bibhas2/Cute
int
main() {
	List *list = newList();

	listAddLast(list, "One");
	listAddLast(list, "Two");
	listAddLast(list, "Three");
	listAddFirst(list, "One");
	listAddFirst(list, "Two");
	listAddFirst(list, "Three");

	print_list(list);

	listRemoveFirst(list);
	print_list(list);
	listRemoveLast(list);
	print_list(list);

	listClear(list);
	listAddLast(list, "One");
	listRemoveFirst(list);
	print_list(list);

	listAddFirst(list, "One");
	listAddLast(list, "One");
	listAddFirst(list, "Two");
	listAddLast(list, "Two");
	listAddFirst(list, "Three");
	listAddLast(list, "Three");
	print_list(list);

	deleteList(list);

	return 0;
}
Exemplo n.º 2
0
void listRemoveNode(List *L, NodeList *p){
    if(!listNodeExists(L, p)) return ;
    if(p == L->last) listRemoveLast(L);
    else if(p == L->header) listRemoveFirst(L);
    else{
        NodeList *ant = listGetPrevious(L, p);
        ant->next = p->next;
        p->next = NULL;
        }
    return;
} 
Exemplo n.º 3
0
static int connectionSubmitRequests(externalServer_t* pServer, connectionContext_t* pCContext) {
	//we have a free connection
	int  count = MAX_MULTI_GET_REQUESTS;
	while (count-- > 0) {
		request_t* pRequest = listRemoveFirst(pServer->unassignedRequests);
		if (!pRequest) {
			break;
		}
		listAddLast(pCContext->currentRequests, pRequest);
	}
	if (listGetSize(pCContext->currentRequests) > 0) {
		listAddLast(pServer->activeConnections, pCContext);
		int bytesWritten = connectionMakeGetRequest(pCContext);
		if (bytesWritten > 0) {
			int err = completeWrite(pCContext);
			if (err == 0) {
				pCContext->status = status_waiting_read;
				connectionWaitForRead(pCContext->connection, getGlobalEventBase());
			}else {
				if (err == 1) {
					pCContext->status = status_waiting_write;
					connectionWaitForWrite(pCContext->connection, getGlobalEventBase());
				}else {
					// error writing to server/ connection closed ?
					listRemove(pServer->activeConnections, pCContext);
					connectionContextDelete(pCContext, 1);
				}
			}
		}
	}else {
		//pooled connections also wait for read, incase they are close by the server
		pCContext->status = status_pooled;
		listAddLast(pServer->freeConnections, pCContext);
		connectionWaitForRead(pCContext->connection, getGlobalEventBase());
	}
	return 0;
}
Exemplo n.º 4
0
static int externalServerSubmit(externalServer_t* pServer, request_t* pRequest) {
	int                  returnValue   = 0;
	connectionContext_t* pCContext     = 0;
	connection_t         newConnection = 0;

	listAddLast(pServer->unassignedRequests, pRequest);
	pCContext = listRemoveFirst(pServer->freeConnections);

	if (pCContext) {
		connectionWaitCancel(pCContext->connection, getGlobalEventBase());
	}

	if (!pCContext) {
		//check if we have reached max concurrent connections limit
		// if not, create a new connection
		if (listGetSize(pServer->activeConnections) < MAX_CONCURRENT_CONNECTIONS) {
			LOG(DEBUG, "creating new external connection");
			newConnection = connectionClientCreate(pServer->serverIP,
												pServer->serverPort,
												createConnectionHandler());
			IfTrue(newConnection, ERR, "Error creating new connection to %s", pServer->serverName);
			//got a new connection
			pCContext = connectionContextCreate(newConnection, pServer);
			IfTrue(pCContext, ERR, "Error allocting memory for connection context");
			connectionSetContext(newConnection, pCContext);
			newConnection = 0;

			int err = connectionConnect(pCContext->connection);
			IfTrue(err >= 0, ERR, "connect failed");

			if (err == 1) {
				LOG(DEBUG, "waiting for connect to complete");
				pCContext->status = status_connecting;
				connectionWaitForConnect(pCContext->connection, getGlobalEventBase());
				goto OnSuccess;
			}
		}else {
			//if we have reached max connection limit, we will let the request rest
			//in the queue. Whenever one of the current connections get free, we will
			//use that to send the request.
			returnValue = 1;
			goto OnSuccess;
		}
	}

	if (pCContext) {
		pCContext->status = status_active;
		connectionSubmitRequests(pServer, pCContext);
	}
	goto OnSuccess;
OnError:
	if (newConnection) {
		connectionClose(newConnection);
	}
	if (pCContext) {
		connectionContextDelete(pCContext, 0);
	}
	returnValue = 1;
OnSuccess:
	return returnValue;
}
Exemplo n.º 5
0
static void readAvailableImpl(connection_t connection){
	connectionContext_t* pCContext    = connectionGetContext(connection);
	u_int32_t            bytesRead   = 0;
	int                  returnValue = 0;

	LOG(DEBUG, "got something to read on socket");

	//if it is one of the pooled connections
	if (pCContext->status == status_pooled) {
		LOG(DEBUG, "socket was pooled..closing on read");
		//socket is closed
		externalServer_t* pServer = pCContext->pExternalServer;
		listRemove(pServer->freeConnections, pCContext);
		connectionContextDelete(pCContext, 0);
		goto OnSuccess;
	}

	if (pCContext->status == status_waiting_read) {
		pCContext->status = status_active;
	}else {
		LOG(ERR, "Invalid connection state");
		goto OnError;
	}

	returnValue = connectionRead(pCContext->connection, pCContext->fallocator,
			                   pCContext->readStream, 8 * 1024 , &bytesRead);
	LOG(DEBUG, "connection read status %d bytesRead %d", returnValue, bytesRead);
	IfTrue(returnValue >= 0, INFO, "Socket closed");

doParseMore:

	returnValue = responseParserParse(pCContext->parser, pCContext->readStream);
	LOG(DEBUG, "response parser status %d", returnValue);
	IfTrue(returnValue >= 0, INFO, "Parsing Error %d", returnValue);

	if (returnValue == 1) {
		LOG(DEBUG, "need to wait for read");
		pCContext->status = status_waiting_read;
		connectionWaitForRead(pCContext->connection, getGlobalEventBase());
		goto OnSuccess;
	}

	char*         key   = 0;
	dataStream_t  value = 0;
	u_int32_t     flags = 0;

	returnValue = responseParserGetResponse(pCContext->parser, pCContext->readStream,
			                                &key, &value, &flags);
	LOG(DEBUG, "got resposonse %d key %s", returnValue, key);

	if (returnValue == 0) {
		externalServer_t* pServer  = pCContext->pExternalServer;
		clusterMapImpl_t* pCM      = pServer->pClusterMap;
		request_t*        pRequest = 0;

tryNext:
	    pRequest = listRemoveFirst(pCContext->currentRequests);
	    if (pRequest) {
			if (0 == strcmp(pRequest->key, key)) {
				//we got the response for the key
				LOG(DEBUG, "giving callback for success result");
				pCM->resultHandler(pRequest->luaContext, pRequest->keyContext, 0, value);
				dataStreamDelete(value);
				value    = 0;
				fallocatorFree(pCContext->fallocator, key);
				key      = 0;
				deleteRequest(pRequest);
				pRequest = 0;
				goto doParseMore;
			}else {
				//this key is different from the key we expected
				//the request for current key failed, so notify
				LOG(DEBUG, "giving callback for fail result");

				pCM->resultHandler(pRequest->luaContext, pRequest->keyContext,  -1, NULL);
				deleteRequest(pRequest);
				pRequest = 0;
				//move on to the next key, may be its her response
				goto tryNext;
			}
	    }else {
	    	// no more request in the currentRequests list?
            // what this means is that we got a response for a key
	    	// which we didn't asked for...
	    	// that is strange.., some server issue..we can't do much
	    	dataStreamDelete(value);
	    	value = 0;
	        fallocatorFree(pCContext->fallocator, key);
	    	key   = 0;
	    	// now so just close this connection

	    	externalServer_t* pServer = pCContext->pExternalServer;
			listRemove(pServer->activeConnections, pCContext);
			connectionContextDelete(pCContext, 0);
			pCContext = 0;
	    }
	}else {
		LOG(DEBUG, "end of results from response parser");
		// we go END response from parser
		externalServer_t* pServer = pCContext->pExternalServer;
		clusterMapImpl_t* pCM      = pServer->pClusterMap;
		request_t*        pRequest = 0;
		//anything pending in the currentRequests..not found
		while ((pRequest = listRemoveLast(pCContext->currentRequests)) != 0) {
			//report error
			pCM->resultHandler(pRequest->luaContext, pRequest->keyContext, -1,  NULL);
			deleteRequest(pRequest);
		}
		// add this connections to free connections list
	    listRemove(pServer->activeConnections, pCContext);
	    connectionSubmitRequests(pServer, pCContext);
	}
	goto OnSuccess;
OnError:
	if (pCContext) {
		externalServer_t* pServer = pCContext->pExternalServer;
		listRemove(pServer->activeConnections, pCContext);
		connectionContextDelete(pCContext, 1);
		pCContext = 0;
	}
OnSuccess:
	return;
}
Exemplo n.º 6
0
/**
	Add first element into linkedlist
	  HEAD            HEAD
	-------         --------      -------
   |  NULL | ---->  | ele1 |-----| NULL |
    -------         --------      -------
**/
void test_listAddFirst_should_add_first_element_into_linkedList() {
    LinkedList *list = createLinkedList();
    Element ele1 = {.next = (Element *)NULL, .data = (Element *)1};

    listAddFirst(&ele1,list);
    TEST_ASSERT_EQUAL(1,ele1.data);
    TEST_ASSERT_EQUAL(1,list->head->data);
    TEST_ASSERT_EQUAL(1,list->tail->data);
    TEST_ASSERT_EQUAL(list->head,list->tail);
    TEST_ASSERT_EQUAL(1,list->length);
    TEST_ASSERT_NULL(list->head->next);

}

/**
	Add elements into linkedlist
	  HEAD            HEAD                                       TAIL
	-------         ------     -----      -----      ------     ------     -----
   |  NULL | ---->  |ele5|-----|ele4|-----|ele3|-----|ele2|-----|ele1|-----|NULL|
    -------         ------     -----      ------     ------     ------     ------
**/
void test_listAddFirst_should_add_elements_into_linkedList() {
    LinkedList *list = createLinkedList();
    Element ele1 = {.next = (Element *)NULL, .data = (Element *)1};
    Element ele2 = {.next = (Element *)NULL, .data = (Element *)5};
    Element ele3 = {.next = (Element *)NULL, .data = (Element *)10};
    Element ele4 = {.next = (Element *)NULL, .data = (Element *)15};
    Element ele5 = {.next = (Element *)NULL, .data = (Element *)20};

    listAddFirst(&ele1,list);
    TEST_ASSERT_EQUAL(1,ele1.data);
    TEST_ASSERT_EQUAL(1,list->head->data);
    TEST_ASSERT_EQUAL(1,list->tail->data);
    TEST_ASSERT_EQUAL(list->head,list->tail);
    TEST_ASSERT_EQUAL(1,list->length);
    TEST_ASSERT_NULL(list->head->next);
    TEST_ASSERT_NULL(list->tail->next);

    listAddFirst(&ele2,list);
    TEST_ASSERT_EQUAL(5,ele2.data);
    TEST_ASSERT_EQUAL(5,list->head->data);
    TEST_ASSERT_EQUAL(1,list->tail->data);
    TEST_ASSERT_NOT_EQUAL(list->head,list->tail);
    TEST_ASSERT_EQUAL(2,list->length);
    TEST_ASSERT_NOT_NULL(list->head->next);
    TEST_ASSERT_NULL(list->tail->next);

    listAddFirst(&ele3,list);
    TEST_ASSERT_EQUAL(10,ele3.data);
    TEST_ASSERT_EQUAL(10,list->head->data);
    TEST_ASSERT_EQUAL(1,list->tail->data);
    TEST_ASSERT_NOT_EQUAL(list->head,list->tail);
    TEST_ASSERT_EQUAL(3,list->length);
    TEST_ASSERT_NOT_NULL(list->head->next);
    TEST_ASSERT_NULL(list->tail->next);

    listAddFirst(&ele4,list);
    TEST_ASSERT_EQUAL(15,ele4.data);
    TEST_ASSERT_EQUAL(15,list->head->data);
    TEST_ASSERT_EQUAL(1,list->tail->data);
    TEST_ASSERT_NOT_EQUAL(list->head,list->tail);
    TEST_ASSERT_EQUAL(4,list->length);
    TEST_ASSERT_NOT_NULL(list->head->next);
    TEST_ASSERT_NULL(list->tail->next);

    listAddFirst(&ele5,list);
    TEST_ASSERT_EQUAL(20,ele5.data);
    TEST_ASSERT_EQUAL(20,list->head->data);
    TEST_ASSERT_EQUAL(15,list->head->next->data);
    TEST_ASSERT_EQUAL(10,list->head->next->next->data);
    TEST_ASSERT_EQUAL(5,list->head->next->next->next->data);
    TEST_ASSERT_EQUAL(1,list->head->next->next->next->next->data);
    TEST_ASSERT_EQUAL(1,list->tail->data);
    TEST_ASSERT_NOT_EQUAL(list->head->data,list->tail->data);
    TEST_ASSERT_EQUAL(list->head->next->next->next->next->data,list->tail->data);
    TEST_ASSERT_EQUAL(5,list->length);
    TEST_ASSERT_NOT_NULL(list->head->next);
    TEST_ASSERT_NULL(list->tail->next);
}

/**
	Remove elements into linkedlist
    Add ele1
      HEAD           HEAD
	-------         ------    -----
   |  NULL | ---->  |ele1|----|NULL|
    -------         ------    ------
	Remove ele1
	 HEAD
	------
    |NULL|
    ------
**/
void test_listRemoveFirst_should_remove_first_element_from_linkedList() {
    LinkedList *list = createLinkedList();
    Element ele1 = {.next = (Element *)NULL, .data = (Element *)1};

    listAddFirst(&ele1,list);
    TEST_ASSERT_EQUAL(1,ele1.data);
    TEST_ASSERT_EQUAL(1,list->head->data);
    TEST_ASSERT_EQUAL(1,list->tail->data);
    TEST_ASSERT_EQUAL(list->head,list->tail);
    TEST_ASSERT_EQUAL(1,list->length);
    TEST_ASSERT_NULL(list->head->next);
    TEST_ASSERT_NULL(list->tail->next);

    listRemoveFirst(list);
    TEST_ASSERT_EQUAL(1,ele1.data);
    TEST_ASSERT_EQUAL(NULL,list->head);
    TEST_ASSERT_EQUAL(NULL,list->tail);
    TEST_ASSERT_EQUAL(list->head,list->tail);
    TEST_ASSERT_EQUAL(0,list->length);
    TEST_ASSERT_NULL(list->head);
    TEST_ASSERT_NULL(list->tail);
}

/**
	Add elements into linkedlist
	  HEAD            HEAD                                       TAIL
	-------         ------     -----      -----      ------     ------     -----
   |  NULL | ---->  |ele5|-----|ele4|-----|ele3|-----|ele2|-----|ele1|-----|NULL|
    -------         ------     -----      ------     ------     ------     ------

	Remove element 5 from head
	HEAD                             TAIL
   ------     -----      -----      ------     -----
   |ele4|-----|ele3|-----|ele2|-----|ele1|-----|NULL|
   ------     -----      ------     ------     ------

	Remove element 4 from head
	HEAD                  TAIL
   ------     -----      -----      -----
   |ele3|-----|ele2|-----|ele1|-----|NULL|
   ------     -----      ------     ------

	Remove element 3 from head
	HEAD      TAIL
   ------     -----      -----
   |ele2|-----|ele1|-----|NULL|
   ------     -----      ------

   Remove element 2 from head
	HEAD
   ------     -----
   |ele1|-----|NULL|
   ------     ------

   Remove element 1 from head
	HEAD
   ------
   |NULL|
   ------
**/

void test_listRemoveFirst_should_remove_elements_from_linkedList() {
    LinkedList *list = createLinkedList();
    Element ele1 = {.next = (Element *)NULL, .data = (Element *)1};
    Element ele2 = {.next = (Element *)NULL, .data = (Element *)5};
    Element ele3 = {.next = (Element *)NULL, .data = (Element *)10};
    Element ele4 = {.next = (Element *)NULL, .data = (Element *)15};
    Element ele5 = {.next = (Element *)NULL, .data = (Element *)20};

    listAddFirst(&ele1,list);
    TEST_ASSERT_EQUAL(1,ele1.data);
    TEST_ASSERT_EQUAL(1,list->head->data);
    TEST_ASSERT_EQUAL(1,list->tail->data);
    TEST_ASSERT_EQUAL(list->head,list->tail);
    TEST_ASSERT_EQUAL(1,list->length);
    TEST_ASSERT_NULL(list->head->next);
    TEST_ASSERT_NULL(list->tail->next);

    listAddFirst(&ele2,list);
    TEST_ASSERT_EQUAL(5,ele2.data);
    TEST_ASSERT_EQUAL(5,list->head->data);
    TEST_ASSERT_EQUAL(1,list->tail->data);
    TEST_ASSERT_NOT_EQUAL(list->head,list->tail);
    TEST_ASSERT_EQUAL(2,list->length);
    TEST_ASSERT_NOT_NULL(list->head->next);
    TEST_ASSERT_NULL(list->tail->next);

    listAddFirst(&ele3,list);
    TEST_ASSERT_EQUAL(10,ele3.data);
    TEST_ASSERT_EQUAL(10,list->head->data);
    TEST_ASSERT_EQUAL(1,list->tail->data);
    TEST_ASSERT_NOT_EQUAL(list->head,list->tail);
    TEST_ASSERT_EQUAL(3,list->length);
    TEST_ASSERT_NOT_NULL(list->head->next);
    TEST_ASSERT_NULL(list->tail->next);

    listAddFirst(&ele4,list);
    TEST_ASSERT_EQUAL(15,ele4.data);
    TEST_ASSERT_EQUAL(15,list->head->data);
    TEST_ASSERT_EQUAL(1,list->tail->data);
    TEST_ASSERT_NOT_EQUAL(list->head,list->tail);
    TEST_ASSERT_EQUAL(4,list->length);
    TEST_ASSERT_NOT_NULL(list->head->next);
    TEST_ASSERT_NULL(list->tail->next);

    listAddFirst(&ele5,list);
    TEST_ASSERT_EQUAL(20,ele5.data);
    TEST_ASSERT_EQUAL(20,list->head->data);
    TEST_ASSERT_EQUAL(15,list->head->next->data);
    TEST_ASSERT_EQUAL(10,list->head->next->next->data);
    TEST_ASSERT_EQUAL(5,list->head->next->next->next->data);
    TEST_ASSERT_EQUAL(1,list->head->next->next->next->next->data);
    TEST_ASSERT_EQUAL(1,list->tail->data);
    TEST_ASSERT_NOT_EQUAL(list->head->data,list->tail->data);
    TEST_ASSERT_EQUAL(list->head->next->next->next->next->data,list->tail->data);
    TEST_ASSERT_EQUAL(5,list->length);
    TEST_ASSERT_NOT_NULL(list->head->next);
    TEST_ASSERT_NULL(list->tail->next);

    listRemoveFirst(list); //Removed 20 from the head
    TEST_ASSERT_EQUAL(1,ele1.data);
    TEST_ASSERT_EQUAL(5,ele2.data);
    TEST_ASSERT_EQUAL(10,ele3.data);
    TEST_ASSERT_EQUAL(15,ele4.data);
    TEST_ASSERT_EQUAL(20,ele5.data);
    TEST_ASSERT_EQUAL(15,list->head->data);
    TEST_ASSERT_EQUAL(1,list->tail->data);
    TEST_ASSERT_EQUAL(4,list->length);
    TEST_ASSERT_NOT_NULL(list->head);
    TEST_ASSERT_NOT_NULL(list->tail);

    listRemoveFirst(list); //Removed 15 from the head
    TEST_ASSERT_EQUAL(1,ele1.data);
    TEST_ASSERT_EQUAL(5,ele2.data);
    TEST_ASSERT_EQUAL(10,ele3.data);
    TEST_ASSERT_EQUAL(15,ele4.data);
    TEST_ASSERT_EQUAL(20,ele5.data);
    TEST_ASSERT_EQUAL(10,list->head->data);
    TEST_ASSERT_EQUAL(1,list->tail->data);
    TEST_ASSERT_EQUAL(3,list->length);
    TEST_ASSERT_NOT_NULL(list->head);
    TEST_ASSERT_NOT_NULL(list->tail);

    listRemoveFirst(list); //Removed 10 from the head
    TEST_ASSERT_EQUAL(1,ele1.data);
    TEST_ASSERT_EQUAL(5,ele2.data);
    TEST_ASSERT_EQUAL(10,ele3.data);
    TEST_ASSERT_EQUAL(15,ele4.data);
    TEST_ASSERT_EQUAL(20,ele5.data);
    TEST_ASSERT_EQUAL(5,list->head->data);
    TEST_ASSERT_EQUAL(1,list->tail->data);
    TEST_ASSERT_EQUAL(2,list->length);
    TEST_ASSERT_NOT_NULL(list->head);
    TEST_ASSERT_NOT_NULL(list->tail);

    listRemoveFirst(list); //Removed 5 from the head
    TEST_ASSERT_EQUAL(1,ele1.data);
    TEST_ASSERT_EQUAL(5,ele2.data);
    TEST_ASSERT_EQUAL(10,ele3.data);
    TEST_ASSERT_EQUAL(15,ele4.data);
    TEST_ASSERT_EQUAL(20,ele5.data);
    TEST_ASSERT_EQUAL(1,list->head->data);
    TEST_ASSERT_EQUAL(1,list->tail->data);
    TEST_ASSERT_EQUAL(1,list->length);
    TEST_ASSERT_NOT_NULL(list->head);
    TEST_ASSERT_NOT_NULL(list->tail);

    listRemoveFirst(list); //Removed 1 from the head
    TEST_ASSERT_EQUAL(1,ele1.data);
    TEST_ASSERT_EQUAL(NULL,list->head);
    TEST_ASSERT_EQUAL(NULL,list->tail);
    TEST_ASSERT_EQUAL(list->head,list->tail);
    TEST_ASSERT_EQUAL(0,list->length);
    TEST_ASSERT_NULL(list->head);
    TEST_ASSERT_NULL(list->tail);
}

/**
	Add first element into linkedlist
	  HEAD            HEAD
	-------         --------      -------
   |  NULL | ---->  | ele1 |-----| NULL |
    -------         --------      -------
**/
void test_listAddLast_should_add_first_element_into_linkedList() {
    LinkedList *list = createLinkedList();
    Element ele1 = {.next = (Element *)NULL, .data = (Element *)1};

    listAddLast(&ele1,list);
    TEST_ASSERT_EQUAL(1,ele1.data);
    TEST_ASSERT_EQUAL(1,list->head->data);
    TEST_ASSERT_EQUAL(1,list->tail->data);
    TEST_ASSERT_EQUAL(list->head,list->tail);
    TEST_ASSERT_EQUAL(1,list->length);
    TEST_ASSERT_NULL(list->head->next);
    TEST_ASSERT_NULL(list->tail->next);
}

/**
	Add elements into linkedlist
	  HEAD            HEAD                                       TAIL
	-------         ------     -----      -----      ------     ------     -----
   |  NULL | ---->  |ele1|-----|ele2|-----|ele3|-----|ele4|-----|ele5|-----|NULL|
    -------         ------     -----      ------     ------     ------     ------
**/
void test_listAddLast_should_add_elements_into_linkedList() {
    LinkedList *list = createLinkedList();
    Element ele1 = {.next = (Element *)NULL, .data = (Element *)1};
    Element ele2 = {.next = (Element *)NULL, .data = (Element *)5};
    Element ele3 = {.next = (Element *)NULL, .data = (Element *)10};
    Element ele4 = {.next = (Element *)NULL, .data = (Element *)15};
    Element ele5 = {.next = (Element *)NULL, .data = (Element *)20};

    listAddLast(&ele1,list);
    TEST_ASSERT_EQUAL(1,ele1.data);
    TEST_ASSERT_EQUAL(1,list->head->data);
    TEST_ASSERT_EQUAL(1,list->tail->data);
    TEST_ASSERT_EQUAL(list->head,list->tail);
    TEST_ASSERT_EQUAL(1,list->length);
    TEST_ASSERT_NULL(list->head->next);
    TEST_ASSERT_NULL(list->tail->next);

    listAddLast(&ele2,list);
    TEST_ASSERT_EQUAL(5,ele2.data);
    TEST_ASSERT_EQUAL(1,list->head->data);
    TEST_ASSERT_EQUAL(5,list->tail->data);
    TEST_ASSERT_NOT_EQUAL(list->head,list->tail);
    TEST_ASSERT_EQUAL(2,list->length);
    TEST_ASSERT_NULL(list->head->next);
    TEST_ASSERT_NOT_NULL(list->tail->next);

    listAddLast(&ele3,list);
    TEST_ASSERT_EQUAL(10,ele3.data);
    TEST_ASSERT_EQUAL(1,list->head->data);
    TEST_ASSERT_EQUAL(10,list->tail->data);
    TEST_ASSERT_NOT_EQUAL(list->head,list->tail);
    TEST_ASSERT_EQUAL(3,list->length);
    TEST_ASSERT_NULL(list->head->next);
    TEST_ASSERT_NOT_NULL(list->tail->next);

    listAddLast(&ele4,list);
    TEST_ASSERT_EQUAL(15,ele4.data);
    TEST_ASSERT_EQUAL(1,list->head->data);
    TEST_ASSERT_EQUAL(15,list->tail->data);
    TEST_ASSERT_NOT_EQUAL(list->head,list->tail);
    TEST_ASSERT_EQUAL(4,list->length);
    TEST_ASSERT_NULL(list->head->next);
    TEST_ASSERT_NOT_NULL(list->tail->next);

    listAddLast(&ele5,list);
    TEST_ASSERT_EQUAL(20,ele5.data);
    TEST_ASSERT_EQUAL(1,list->head->data);
    TEST_ASSERT_EQUAL(20,list->tail->data);
    TEST_ASSERT_EQUAL(15,list->tail->next->data);
    TEST_ASSERT_EQUAL(10,list->tail->next->next->data);
    TEST_ASSERT_EQUAL(5,list->tail->next->next->next->data);
    TEST_ASSERT_EQUAL(1,list->tail->next->next->next->next->data);
    TEST_ASSERT_NOT_EQUAL(list->head->data,list->tail->data);
    TEST_ASSERT_EQUAL(list->head->data,list->tail->next->next->next->next->data);
    TEST_ASSERT_EQUAL(5,list->length);
    TEST_ASSERT_NULL(list->head->next);
    TEST_ASSERT_NOT_NULL(list->tail->next);
}

void test_listRemoveLast_should_remove_first_element_from_linkedList() {
    LinkedList *list = createLinkedList();
    Element ele1 = {.next = (Element *)NULL, .data = (Element *)1};

    listAddLast(&ele1,list);
    TEST_ASSERT_EQUAL(1,ele1.data);
    TEST_ASSERT_EQUAL(1,list->head->data);
    TEST_ASSERT_EQUAL(1,list->tail->data);
    TEST_ASSERT_EQUAL(list->head,list->tail);
    TEST_ASSERT_EQUAL(1,list->length);
    TEST_ASSERT_NULL(list->head->next);
    TEST_ASSERT_NULL(list->tail->next);

    listRemoveLast(list);
    TEST_ASSERT_EQUAL(1,ele1.data);
    TEST_ASSERT_EQUAL(NULL,list->head);
    TEST_ASSERT_EQUAL(NULL,list->tail);
    TEST_ASSERT_EQUAL(list->head,list->tail);
    TEST_ASSERT_EQUAL(0,list->length);
    TEST_ASSERT_NULL(list->head);
    TEST_ASSERT_NULL(list->tail);
}

/**
	Add elements into linkedlist
	  HEAD            HEAD                                       TAIL
	-------         ------     -----      -----      ------     ------     -----
   |  NULL | ---->  |ele1|-----|ele2|-----|ele3|-----|ele4|-----|ele5|-----|NULL|
    -------         ------     -----      ------     ------     ------     ------

	Remove element 5 from tail
	HEAD                             TAIL
   ------     -----      -----      ------     -----
   |ele1|-----|ele2|-----|ele3|-----|ele4|-----|NULL|
   ------     -----      ------     ------     ------

	Remove element 4 from tail
	HEAD                  TAIL
   ------     -----      -----      -----
   |ele1|-----|ele2|-----|ele3|-----|NULL|
   ------     -----      ------     ------

	Remove element 3 from tail
	HEAD      TAIL
   ------     -----      -----
   |ele1|-----|ele2|-----|NULL|
   ------     -----      ------

   Remove element 2 from tail
	HEAD
   ------     -----
   |ele1|-----|NULL|
   ------     ------

   Remove element 1 from tail
	HEAD
   ------
   |NULL|
   ------
**/
void test_listRemoveLast_should_remove_elements_from_linkedList() {
    LinkedList *list = createLinkedList();
    Element ele1 = {.next = (Element *)NULL, .data = (Element *)1};
    Element ele2 = {.next = (Element *)NULL, .data = (Element *)5};
    Element ele3 = {.next = (Element *)NULL, .data = (Element *)10};
    Element ele4 = {.next = (Element *)NULL, .data = (Element *)15};
    Element ele5 = {.next = (Element *)NULL, .data = (Element *)20};

    listAddLast(&ele1,list);
    TEST_ASSERT_EQUAL(1,ele1.data);
    TEST_ASSERT_EQUAL(1,list->head->data);
    TEST_ASSERT_EQUAL(1,list->tail->data);
    TEST_ASSERT_EQUAL(list->head,list->tail);
    TEST_ASSERT_EQUAL(1,list->length);
    TEST_ASSERT_NULL(list->head->next);
    TEST_ASSERT_NULL(list->tail->next);

    listAddLast(&ele2,list);
    TEST_ASSERT_EQUAL(5,ele2.data);
    TEST_ASSERT_EQUAL(1,list->head->data);
    TEST_ASSERT_EQUAL(5,list->tail->data);
    TEST_ASSERT_NOT_EQUAL(list->head,list->tail);
    TEST_ASSERT_EQUAL(2,list->length);
    TEST_ASSERT_NULL(list->head->next);
    TEST_ASSERT_NOT_NULL(list->tail->next);

    listAddLast(&ele3,list);
    TEST_ASSERT_EQUAL(10,ele3.data);
    TEST_ASSERT_EQUAL(1,list->head->data);
    TEST_ASSERT_EQUAL(10,list->tail->data);
    TEST_ASSERT_NOT_EQUAL(list->head,list->tail);
    TEST_ASSERT_EQUAL(3,list->length);
    TEST_ASSERT_NULL(list->head->next);
    TEST_ASSERT_NOT_NULL(list->tail->next);

    listAddLast(&ele4,list);
    TEST_ASSERT_EQUAL(15,ele4.data);
    TEST_ASSERT_EQUAL(1,list->head->data);
    TEST_ASSERT_EQUAL(15,list->tail->data);
    TEST_ASSERT_NOT_EQUAL(list->head,list->tail);
    TEST_ASSERT_EQUAL(4,list->length);
    TEST_ASSERT_NULL(list->head->next);
    TEST_ASSERT_NOT_NULL(list->tail->next);

    listAddLast(&ele5,list);
    TEST_ASSERT_EQUAL(20,ele5.data);
    TEST_ASSERT_EQUAL(1,list->head->data);
    TEST_ASSERT_EQUAL(20,list->tail->data);
    TEST_ASSERT_EQUAL(15,list->tail->next->data);
    TEST_ASSERT_EQUAL(10,list->tail->next->next->data);
    TEST_ASSERT_EQUAL(5,list->tail->next->next->next->data);
    TEST_ASSERT_EQUAL(1,list->tail->next->next->next->next->data);
    TEST_ASSERT_NOT_EQUAL(list->head->data,list->tail->data);
    TEST_ASSERT_EQUAL(list->head->data,list->tail->next->next->next->next->data);
    TEST_ASSERT_EQUAL(5,list->length);
    TEST_ASSERT_NULL(list->head->next);
    TEST_ASSERT_NOT_NULL(list->tail->next);

    listRemoveLast(list); //Removed 20 from the tail
    TEST_ASSERT_EQUAL(1,ele1.data);
    TEST_ASSERT_EQUAL(5,ele2.data);
    TEST_ASSERT_EQUAL(10,ele3.data);
    TEST_ASSERT_EQUAL(15,ele4.data);
    TEST_ASSERT_EQUAL(20,ele5.data);
    TEST_ASSERT_EQUAL(15,list->tail->data);
    TEST_ASSERT_EQUAL(10,list->tail->next->data);
    TEST_ASSERT_EQUAL(5,list->tail->next->next->data);
    TEST_ASSERT_EQUAL(1,list->tail->next->next->next->data);
    TEST_ASSERT_EQUAL(1,list->head->data);
    TEST_ASSERT_EQUAL(list->head->data,list->tail->next->next->next->data);
    TEST_ASSERT_EQUAL(4,list->length);
    TEST_ASSERT_NOT_NULL(list->head);
    TEST_ASSERT_NOT_NULL(list->tail);

    listRemoveLast(list); //Removed 15 from the tail
    TEST_ASSERT_EQUAL(1,ele1.data);
    TEST_ASSERT_EQUAL(5,ele2.data);
    TEST_ASSERT_EQUAL(10,ele3.data);
    TEST_ASSERT_EQUAL(15,ele4.data);
    TEST_ASSERT_EQUAL(20,ele5.data);
    TEST_ASSERT_EQUAL(10,list->tail->data);
    TEST_ASSERT_EQUAL(5,list->tail->next->data);
    TEST_ASSERT_EQUAL(1,list->tail->next->next->data);
    TEST_ASSERT_EQUAL(1,list->head->data);
    TEST_ASSERT_EQUAL(list->head->data,list->tail->next->next->data);
    TEST_ASSERT_EQUAL(3,list->length);
    TEST_ASSERT_NOT_NULL(list->head);
    TEST_ASSERT_NOT_NULL(list->tail);

    listRemoveLast(list); //Removed 10 from the tail
    TEST_ASSERT_EQUAL(1,ele1.data);
    TEST_ASSERT_EQUAL(5,ele2.data);
    TEST_ASSERT_EQUAL(10,ele3.data);
    TEST_ASSERT_EQUAL(15,ele4.data);
    TEST_ASSERT_EQUAL(20,ele5.data);
    TEST_ASSERT_EQUAL(5,list->tail->data);
    TEST_ASSERT_EQUAL(1,list->tail->next->data);
    TEST_ASSERT_EQUAL(1,list->head->data);
    TEST_ASSERT_EQUAL(list->head->data,list->tail->next->data);
    TEST_ASSERT_EQUAL(2,list->length);
    TEST_ASSERT_NOT_NULL(list->head);
    TEST_ASSERT_NOT_NULL(list->tail);

    listRemoveLast(list); //Removed 5 from the tail
    TEST_ASSERT_EQUAL(1,ele1.data);
    TEST_ASSERT_EQUAL(5,ele2.data);
    TEST_ASSERT_EQUAL(10,ele3.data);
    TEST_ASSERT_EQUAL(15,ele4.data);
    TEST_ASSERT_EQUAL(20,ele5.data);
    TEST_ASSERT_EQUAL(1,list->tail->data);
    TEST_ASSERT_EQUAL(1,list->head->data);
    TEST_ASSERT_EQUAL(list->head->data,list->tail->data);
    TEST_ASSERT_EQUAL(1,list->length);
    TEST_ASSERT_NOT_NULL(list->head);
    TEST_ASSERT_NOT_NULL(list->tail);

    listRemoveLast(list); //Removed 1 from the tail
    TEST_ASSERT_EQUAL(1,ele1.data);
    TEST_ASSERT_EQUAL(5,ele2.data);
    TEST_ASSERT_EQUAL(10,ele3.data);
    TEST_ASSERT_EQUAL(15,ele4.data);
    TEST_ASSERT_EQUAL(20,ele5.data);
    TEST_ASSERT_EQUAL(NULL,list->tail);
    TEST_ASSERT_EQUAL(NULL,list->head);
    TEST_ASSERT_EQUAL(list->head,list->tail);
    TEST_ASSERT_EQUAL(0,list->length);
    TEST_ASSERT_NULL(list->head);
    TEST_ASSERT_NULL(list->tail);
}