예제 #1
0
파일: test.c 프로젝트: 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;
}
예제 #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;
} 
예제 #3
0
static void connectionContextDelete(connectionContext_t* pContext, int move) {
	if (pContext) {
		externalServer_t* pServer  = pContext->pExternalServer;
		clusterMapImpl_t* pCMap    = pServer->pClusterMap;
		request_t*        pRequest = 0;

		LOG(DEBUG, "deleting connection context");

		while ((pRequest = listRemoveLast(pContext->currentRequests)) != 0) {
			if (move) {
				//move the existing requests to another socket
				listAddFirst(pServer->unassignedRequests, pRequest);
			}else {
				//report error
				pCMap->resultHandler(pRequest->luaContext, pRequest->keyContext,  -1,  NULL);
				deleteRequest(pRequest);
			}
		}
		if (pContext->connection) {
			connectionClose(pContext->connection);
		}
		if (pContext->readStream) {
			dataStreamDelete(pContext->readStream);
			pContext->readStream = 0;
		}
		if (pContext->writeStream) {
			dataStreamDelete(pContext->writeStream);
			pContext->writeStream = 0;
		}
		if (pContext->parser) {
			responseParserDelete(pContext->parser);
			pContext->parser = 0;
		}
		if (pContext->currentRequests) {
			listFree(pContext->currentRequests);
			pContext->currentRequests = 0;
		}
		if (pContext->fallocator) {
			fallocatorDelete(pContext->fallocator);
		}
		FREE(pContext);
	}
}
예제 #4
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;
}
예제 #5
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);
}