1// 2// ListTMethodsTest.m 3// Tests 4// 5// Copyright (c) 2020 Apple Inc. All rights reserved. 6// 7 8#import <XCTest/XCTest.h> 9#include "list.h" 10#include "mDNSEmbeddedAPI.h" 11#if MDNSRESPONDER_SUPPORTS(APPLE, DNSSECv2) 12 13typedef struct test_struct_t { 14 mDNSu8 field_one; 15 mDNSu32 field_two; 16} test_struct_t; 17 18@interface ListTMethodsTest : XCTestCase 19 20@end 21 22@implementation ListTMethodsTest 23 24- (void)testListInitAndUninit{ 25 list_t list; 26 27 list_init(&list, sizeof(test_struct_t)); 28 XCTAssertEqual(list.head_ptr, &list.head, @"list.head_ptr should point to list.head"); 29 XCTAssertEqual(list.tail_ptr, &list.tail, @"list.tail_ptr should point to list.tail"); 30 XCTAssertEqual(list.head_ptr->next, list.tail_ptr, @"The next node of head should be tail"); 31 XCTAssertEqual(list.tail_ptr->prev, list.head_ptr, @"The previous node of tail should be head"); 32 XCTAssertEqual(list.data_size, sizeof(test_struct_t), @"The data size should be sizeof(test_struct_t)"); 33 34 list_uninit(&list); 35 XCTAssertEqual(list.data_size, 0, @"The data size should be 0"); 36 XCTAssertNil((__bridge id)list.head.next, @"The next node of head should be NULL"); 37 XCTAssertNil((__bridge id)list.tail.prev, @"The previous node of tail should be NULL"); 38 XCTAssertNil((__bridge id)list.head_ptr, @"The head pointer should point to NULL"); 39 XCTAssertNil((__bridge id)list.tail_ptr, @"The tail pointer should point to NULL"); 40} 41 42- (void)testListGeneralOperation{ 43 mStatus error; 44 list_t list; 45 mDNSBool empty; 46 mDNSu8 count; 47 test_struct_t *append_node_data_1, *append_node_data_2, *prepend_node_data_1, *prepend_node_data_2; 48 list_node_t *first_node, *second_node, *third_node, *fourth_node; 49 50 // Initialize 51 list_init(&list, sizeof(test_struct_t)); 52 53 // Get first and last for empty list 54 XCTAssertNil((__bridge id)list_get_first(&list)); 55 XCTAssertNil((__bridge id)list_get_last(&list)); 56 57 // Append succeeds 58 error = list_append_uinitialized(&list, sizeof(test_struct_t), (void **)&append_node_data_1); 59 XCTAssertEqual(error, mStatus_NoError, @"list_append_uinitialized failed; error_description='%s'", mStatusDescription(error)); 60 first_node = list.head_ptr->next; 61 XCTAssertEqual(first_node->prev, list.head_ptr, @"The first node should point to head"); 62 XCTAssertEqual(first_node->next, list.tail_ptr, @"The next of first node should point to tail"); 63 XCTAssertEqual(list.tail_ptr->prev, first_node, @"The previous of tail should point to first node"); 64 XCTAssertEqual((void *)first_node->data, (void *)append_node_data_1, @"The data field should be equal to the returned data pointer"); 65 66 // Get first and last 67 XCTAssertEqual(list_get_first(&list), first_node); 68 XCTAssertEqual(list_get_last(&list), first_node); 69 70 // Append fails 71 error = list_append_uinitialized(&list, sizeof(test_struct_t) - 1, (void **)&append_node_data_2); 72 XCTAssertEqual(error, mStatus_BadParamErr, @"List should not add new node since the type of embedded data does not match"); 73 74 // Empty test 75 empty = list_empty(&list); 76 XCTAssertFalse(empty, @"List should not be empty"); 77 78 // Count test 79 count = list_count_node(&list); 80 XCTAssertEqual(count, 1, @"There should be only 1 node"); 81 82 // Append 2nd succeeds 83 error = list_append_uinitialized(&list, sizeof(test_struct_t), (void **)&append_node_data_2); 84 XCTAssertEqual(error, mStatus_NoError, @"list_append_uinitialized failed; error_description='%s'", mStatusDescription(error)); 85 second_node = list.tail_ptr->prev; 86 XCTAssertEqual(first_node->next, second_node); 87 XCTAssertEqual(first_node->prev, list.head_ptr); 88 XCTAssertEqual(first_node->next, second_node); 89 XCTAssertEqual(second_node->next, list.tail_ptr); 90 XCTAssertEqual(second_node->prev, first_node); 91 XCTAssertEqual((void *)second_node->data, (void *)append_node_data_2); 92 93 // Count test 94 count = list_count_node(&list); 95 XCTAssertEqual(count, 2); 96 97 // Get first and last 98 XCTAssertEqual(list_get_first(&list), first_node); 99 XCTAssertEqual(list_get_last(&list), second_node); 100 101 // Prepend 3rd succeeds 102 error = list_prepend_uinitialized(&list, sizeof(test_struct_t), (void **)&prepend_node_data_1); 103 XCTAssertEqual(error, mStatus_NoError); 104 third_node = list.head_ptr->next; 105 XCTAssertEqual(third_node->next, first_node); 106 XCTAssertEqual(third_node->prev, list.head_ptr); 107 XCTAssertEqual(first_node->prev, third_node); 108 XCTAssertEqual((void *)third_node->data, (void *)prepend_node_data_1); 109 110 // Count test 111 count = list_count_node(&list); 112 XCTAssertEqual(count, 3); 113 114 // Get first and last 115 XCTAssertEqual(list_get_first(&list), third_node); 116 XCTAssertEqual(list_get_last(&list), second_node); 117 118 // Prepend fails 119 error = list_prepend_uinitialized(&list, sizeof(test_struct_t) - 1, (void **)&prepend_node_data_2); 120 XCTAssertEqual(error, mStatus_BadParamErr); 121 122 // Preopend 4th succeeds 123 error = list_prepend_uinitialized(&list, sizeof(test_struct_t), (void **)&prepend_node_data_2); 124 XCTAssertEqual(error, mStatus_NoError); 125 fourth_node = list.head_ptr->next; 126 XCTAssertEqual(fourth_node->next, third_node); 127 XCTAssertEqual(fourth_node->prev, list.head_ptr); 128 XCTAssertEqual(third_node->prev, fourth_node); 129 XCTAssertEqual((void *)fourth_node->data, (void *)prepend_node_data_2); 130 131 // Count test 132 count = list_count_node(&list); 133 XCTAssertEqual(count, 4); 134 135 // Get first and last 136 XCTAssertEqual(list_get_first(&list), fourth_node); 137 XCTAssertEqual(list_get_last(&list), second_node); 138 139 // Iteration test 140 for (list_node_t *node = list_get_first(&list); !list_has_ended(&list, node); node = list_next(node)) { 141 if (node == first_node) { 142 XCTAssertEqual((void *)node->data, (void *)append_node_data_1); 143 } else if (node == second_node) { 144 XCTAssertEqual((void *)node->data, (void *)append_node_data_2); 145 } else if (node == third_node) { 146 XCTAssertEqual((void *)node->data, (void *)prepend_node_data_1); 147 } else if (node == fourth_node) { 148 XCTAssertEqual((void *)node->data, (void *)prepend_node_data_2); 149 } else { 150 XCTAssertTrue(mDNSfalse, @"Unknown node added into the list"); 151 } 152 } 153 154 // Delete one node with node pointer 155 list_node_delete(first_node); 156 XCTAssertEqual(third_node->next, second_node); 157 XCTAssertEqual(third_node->prev, fourth_node); 158 XCTAssertEqual(second_node->prev, third_node); 159 XCTAssertEqual(list_count_node(&list), 3); 160 XCTAssertFalse(list_empty(&list)); 161 162 // Delete one node with data pointer that exists 163 error = list_delete_node_with_data_ptr(&list, prepend_node_data_2); 164 XCTAssertEqual(error, mStatus_NoError); 165 XCTAssertEqual(list_get_first(&list), third_node); 166 XCTAssertEqual(list_get_last(&list), second_node); 167 XCTAssertEqual(third_node->next, second_node); 168 XCTAssertEqual(third_node->prev, list.head_ptr); 169 XCTAssertEqual(second_node->next, list.tail_ptr); 170 XCTAssertEqual(list_count_node(&list), 2); 171 XCTAssertFalse(list_empty(&list)); 172 173 // Delete one node with data pointer that does not exist 174 error = list_delete_node_with_data_ptr(&list, prepend_node_data_2 + 1); 175 XCTAssertEqual(error, mStatus_NoSuchKey); 176 XCTAssertEqual(list_get_first(&list), third_node); 177 XCTAssertEqual(list_get_last(&list), second_node); 178 XCTAssertEqual(third_node->next, second_node); 179 XCTAssertEqual(third_node->prev, list.head_ptr); 180 XCTAssertEqual(second_node->next, list.tail_ptr); 181 XCTAssertEqual(list_count_node(&list), 2); 182 XCTAssertFalse(list_empty(&list)); 183 184 // Delete all the nodes 185 list_node_delete_all(&list); 186 187 // Count test 188 count = list_count_node(&list); 189 XCTAssertEqual(count, 0); 190 191 // Empty test 192 empty = list_empty(&list); 193 XCTAssertTrue(empty); 194 195 // Iterate through the empty list 196 for (list_node_t *node = list_get_first(&list); !list_has_ended(&list, node); node = list_next(node)) { 197 XCTAssertFalse(mDNStrue, @"Should never excute this line if the line is empty"); 198 } 199 200 // uninitialize the list 201 list_uninit(&list); 202 XCTAssertEqual(list.data_size, 0); 203 XCTAssertNil((__bridge id)list.head.next); 204 XCTAssertNil((__bridge id)list.tail.prev); 205 XCTAssertNil((__bridge id)list.head_ptr); 206 XCTAssertNil((__bridge id)list.tail_ptr); 207} 208@end 209 210#endif // MDNSRESPONDER_SUPPORTS(APPLE, DNSSECv2) 211