diff --git a/src/3 b/src/3 new file mode 100644 index 0000000..de8d478 --- /dev/null +++ b/src/3 @@ -0,0 +1,83 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "internal/internal.h" +#include "swift_net.h" + +static inline struct SwiftNetServer* const construct_server(const bool loopback, const uint16_t server_port, pcap_t* const pcap) { + struct SwiftNetServer* const new_server = allocator_allocate(&server_memory_allocator); + + struct ether_header eth_header = { + .ether_dhost = {0xff,0xff,0xff,0xff,0xff,0xff}, + .ether_type = htons(0x0800) + }; + + memcpy(eth_header.ether_shost, mac_address, sizeof(eth_header.ether_shost)); + + new_server->eth_header = eth_header; + new_server->server_port = server_port; + new_server->loopback = loopback; + new_server->pcap = pcap; + new_server->addr_type = pcap_datalink(pcap); + new_server->prepend_size = PACKET_PREPEND_SIZE(new_server->addr_type); + new_server->packet_queue = (struct PacketQueue){ + .first_node = NULL, + .last_node = NULL + }; + + memset(&new_server->packet_callback_queue, 0x00, sizeof(struct PacketCallbackQueue)); + + atomic_store_explicit(&new_server->packet_queue.owner, NONE, memory_order_release); + atomic_store_explicit(&new_server->packet_callback_queue.owner, NONE, memory_order_release); + atomic_store_explicit(&new_server->packet_handler, NULL, memory_order_release); + atomic_store_explicit(&new_server->packet_handler_user_arg, NULL, memory_order_release); + atomic_store_explicit(&new_server->closing, false, memory_order_release); + + new_server->pending_messages_memory_allocator = allocator_create(sizeof(struct SwiftNetPendingMessage), 100); + new_server->pending_messages = vector_create(100); + new_server->packets_sending_memory_allocator = allocator_create(sizeof(struct SwiftNetPacketSending), 100); + new_server->packets_sending = vector_create(100); + new_server->packets_completed_memory_allocator = allocator_create(sizeof(struct SwiftNetPacketCompleted), 100); + new_server->packets_completed = vector_create(100); + + return new_server; +} + +struct SwiftNetServer* swiftnet_create_server(const uint16_t port, const bool loopback) { + // Init pcap device + pcap_t* const pcap = swiftnet_pcap_open(loopback ? LOOPBACK_INTERFACE_NAME : default_network_interface); + if (unlikely(pcap == NULL)) { + PRINT_ERROR("Failed to open bpf"); + return NULL; + } + + struct SwiftNetServer* const new_server = construct_server(loopback, port, pcap); + + // Create a new thread that will handle all packets received + check_existing_listener(loopback ? LOOPBACK_INTERFACE_NAME : default_network_interface, new_server, CONNECTION_TYPE_SERVER, loopback); + + pthread_create(&new_server->process_packets_thread, NULL, swiftnet_server_process_packets, new_server); + pthread_create(&new_server->execute_callback_thread, NULL, execute_packet_callback_server, new_server); + + pthread_mutex_init(&new_server->process_packets_mtx, NULL); + pthread_mutex_init(&new_server->execute_callback_mtx, NULL); + + pthread_cond_init(&new_server->process_packets_cond, NULL); + + #ifdef SWIFT_NET_DEBUG + if (check_debug_flag(INITIALIZATION)) { + send_debug_message("Successfully initialized server\n"); + } + #endif + + return new_server; +} diff --git a/src/cleanup_connection.c b/src/cleanup_connection.c index fc52b3d..ea1eff8 100644 --- a/src/cleanup_connection.c +++ b/src/cleanup_connection.c @@ -2,6 +2,7 @@ #include "swift_net.h" #include #include +#include #include static inline void cleanup_connection_resources(const enum ConnectionType connection_type, void* const connection) { @@ -83,15 +84,43 @@ static inline void close_threads(const enum ConnectionType connection_type, void atomic_store_explicit(&client->closing, true, memory_order_release); + pthread_mutex_lock(&client->process_packets_mtx); + pthread_cond_signal(&client->process_packets_cond); + pthread_mutex_unlock(&client->process_packets_mtx); + + pthread_mutex_lock(&client->execute_callback_mtx); + pthread_cond_signal(&client->execute_callback_cond); + pthread_mutex_unlock(&client->execute_callback_mtx); + pthread_join(client->process_packets_thread, NULL); pthread_join(client->execute_callback_thread, NULL); + + pthread_mutex_destroy(&client->process_packets_mtx); + pthread_mutex_destroy(&client->execute_callback_mtx); + + pthread_cond_destroy(&client->process_packets_cond); + pthread_cond_destroy(&client->execute_callback_cond); } else { struct SwiftNetServer* const server = connection; atomic_store_explicit(&server->closing, true, memory_order_release); + pthread_mutex_lock(&server->process_packets_mtx); + pthread_cond_signal(&server->process_packets_cond); + pthread_mutex_unlock(&server->process_packets_mtx); + + pthread_mutex_lock(&server->execute_callback_mtx); + pthread_cond_signal(&server->execute_callback_cond); + pthread_mutex_unlock(&server->execute_callback_mtx); + pthread_join(server->process_packets_thread, NULL); pthread_join(server->execute_callback_thread, NULL); + + pthread_mutex_destroy(&server->process_packets_mtx); + pthread_mutex_destroy(&server->execute_callback_mtx); + + pthread_cond_destroy(&server->process_packets_cond); + pthread_cond_destroy(&server->execute_callback_cond); } } diff --git a/src/execute_packet_callback.c b/src/execute_packet_callback.c index bbe216b..28e2a16 100644 --- a/src/execute_packet_callback.c +++ b/src/execute_packet_callback.c @@ -53,17 +53,37 @@ static inline void remove_pending_message_from_vector(struct SwiftNetVector* con vector_unlock(pending_messages); } -void execute_packet_callback(struct PacketCallbackQueue* const queue, void (* const _Atomic * const packet_handler) (void* const, void* const), const enum ConnectionType connection_type, struct SwiftNetMemoryAllocator* const pending_message_memory_allocator, _Atomic bool* closing, void* const connection, struct SwiftNetVector* const pending_messages, _Atomic(void*)* user_data) { +void execute_packet_callback( + struct PacketCallbackQueue* const queue, + void (* const _Atomic * const packet_handler) (void* const, + void* const), + const enum ConnectionType connection_type, + struct SwiftNetMemoryAllocator* const pending_message_memory_allocator, + _Atomic bool* closing, + void* const connection, + struct SwiftNetVector* const pending_messages, + _Atomic(void*)* user_data, + pthread_mutex_t* const execute_callback_mtx, + pthread_cond_t* const execute_callback_cond +) { while (1) { if (atomic_load_explicit(closing, memory_order_acquire) == true) { break; } + pthread_mutex_lock(execute_callback_mtx); + const struct PacketCallbackQueueNode* const node = wait_for_next_packet_callback(queue); if(node == NULL) { + pthread_cond_wait(execute_callback_cond, execute_callback_mtx); + + pthread_mutex_unlock(execute_callback_mtx); + continue; } + pthread_mutex_unlock(execute_callback_mtx); + atomic_thread_fence(memory_order_acquire); if(node->packet_data == NULL) { @@ -97,7 +117,7 @@ void execute_packet_callback(struct PacketCallbackQueue* const queue, void (* co void* execute_packet_callback_client(void* const void_client) { struct SwiftNetClientConnection* const client = void_client; - execute_packet_callback(&client->packet_callback_queue, (void*)&client->packet_handler, CONNECTION_TYPE_CLIENT, &client->pending_messages_memory_allocator, &client->closing, void_client, &client->pending_messages, &client->packet_handler_user_arg); + execute_packet_callback(&client->packet_callback_queue, (void*)&client->packet_handler, CONNECTION_TYPE_CLIENT, &client->pending_messages_memory_allocator, &client->closing, void_client, &client->pending_messages, &client->packet_handler_user_arg, &client->execute_callback_mtx, &client->execute_callback_cond); return NULL; } @@ -105,7 +125,7 @@ void* execute_packet_callback_client(void* const void_client) { void* execute_packet_callback_server(void* const void_server) { struct SwiftNetServer* const server = void_server; - execute_packet_callback(&server->packet_callback_queue, (void*)&server->packet_handler, CONNECTION_TYPE_SERVER, &server->pending_messages_memory_allocator, &server->closing, void_server, &server->pending_messages, &server->packet_handler_user_arg); + execute_packet_callback(&server->packet_callback_queue, (void*)&server->packet_handler, CONNECTION_TYPE_SERVER, &server->pending_messages_memory_allocator, &server->closing, void_server, &server->pending_messages, &server->packet_handler_user_arg, &server->execute_callback_mtx, &server->execute_callback_cond); return NULL; } diff --git a/src/handle_packets.c b/src/handle_packets.c index 9771c65..440b94d 100644 --- a/src/handle_packets.c +++ b/src/handle_packets.c @@ -21,7 +21,12 @@ static inline void unlock_packet_queue(struct PacketQueue* const packet_queue) { atomic_store_explicit(&packet_queue->owner, NONE, memory_order_release); } -static inline void insert_queue_node(struct PacketQueueNode* const new_node, struct PacketQueue* const packet_queue, const enum ConnectionType contype) { +static inline void insert_queue_node( + struct PacketQueueNode* const new_node, + struct PacketQueue* const packet_queue, + const enum ConnectionType contype + +) { if(new_node == NULL) { return; } @@ -60,7 +65,21 @@ static inline struct PacketQueueNode* construct_node(const uint32_t data_read, v return node; } -static inline void swiftnet_handle_packets(const uint16_t source_port, pthread_t* const process_packets_thread, void* connection, const enum ConnectionType connection_type, struct PacketQueue* const packet_queue, const _Atomic bool* closing, const bool loopback, const uint16_t addr_type, const struct pcap_pkthdr* hdr, const uint8_t* packet) { +static inline void swiftnet_handle_packets( + const uint16_t source_port, + pthread_t* const process_packets_thread, + void* connection, + const enum ConnectionType connection_type, + struct PacketQueue* const packet_queue, + const _Atomic bool* closing, + const bool loopback, + const uint16_t addr_type, + const struct pcap_pkthdr* hdr, + const uint8_t* packet, + pthread_mutex_t* const process_packets_mtx, + pthread_cond_t* const process_packets_cond + +) { uint8_t* const packet_buffer = allocator_allocate(&packet_buffer_memory_allocator); if (unlikely(packet_buffer == NULL)) { return; @@ -94,7 +113,13 @@ static inline void swiftnet_handle_packets(const uint16_t source_port, pthread_t atomic_thread_fence(memory_order_release); + pthread_mutex_lock(process_packets_mtx); + insert_queue_node(node, packet_queue, connection_type); + + pthread_cond_signal(process_packets_cond); + + pthread_mutex_unlock(process_packets_mtx); } static void handle_client_init(struct SwiftNetClientConnection* user, const struct pcap_pkthdr* hdr, const uint8_t* buffer) { @@ -161,7 +186,7 @@ static inline void handle_correct_receiver(const enum ConnectionType connection_ if (client_connection->initialized == false) { handle_client_init(client_connection, hdr, packet); } else { - swiftnet_handle_packets(client_connection->port_info.source_port, &client_connection->process_packets_thread, client_connection, CONNECTION_TYPE_CLIENT, &client_connection->packet_queue, &client_connection->closing, client_connection->loopback, client_connection->addr_type, hdr, packet); + swiftnet_handle_packets(client_connection->port_info.source_port, &client_connection->process_packets_thread, client_connection, CONNECTION_TYPE_CLIENT, &client_connection->packet_queue, &client_connection->closing, client_connection->loopback, client_connection->addr_type, hdr, packet, &client_connection->process_packets_mtx, &client_connection->process_packets_cond); } return; @@ -177,7 +202,7 @@ static inline void handle_correct_receiver(const enum ConnectionType connection_ if (server->server_port == port_info->destination_port) { vector_unlock(&listener->servers); - swiftnet_handle_packets(server->server_port, &server->process_packets_thread, server, CONNECTION_TYPE_SERVER, &server->packet_queue, &server->closing, server->loopback, server->addr_type, hdr, packet); + swiftnet_handle_packets(server->server_port, &server->process_packets_thread, server, CONNECTION_TYPE_SERVER, &server->packet_queue, &server->closing, server->loopback, server->addr_type, hdr, packet, &server->process_packets_mtx, &server->process_packets_cond); return; } diff --git a/src/initialize_client_socket.c b/src/initialize_client_socket.c index 908ac89..c8ed22f 100644 --- a/src/initialize_client_socket.c +++ b/src/initialize_client_socket.c @@ -179,6 +179,12 @@ struct SwiftNetClientConnection* swiftnet_create_client(const char* const ip_add pthread_create(&new_connection->process_packets_thread, NULL, swiftnet_client_process_packets, new_connection); pthread_create(&new_connection->execute_callback_thread, NULL, execute_packet_callback_client, new_connection); + pthread_mutex_init(&new_connection->process_packets_mtx, NULL); + pthread_mutex_init(&new_connection->execute_callback_mtx, NULL); + + pthread_cond_init(&new_connection->process_packets_cond, NULL); + pthread_cond_init(&new_connection->execute_callback_cond, NULL); + #ifdef SWIFT_NET_DEBUG if (check_debug_flag(INITIALIZATION)) { send_debug_message("Successfully initialized client\n"); diff --git a/src/initialize_server_socket.c b/src/initialize_server_socket.c index 5b571d3..8540ef6 100644 --- a/src/initialize_server_socket.c +++ b/src/initialize_server_socket.c @@ -68,6 +68,12 @@ struct SwiftNetServer* swiftnet_create_server(const uint16_t port, const bool lo pthread_create(&new_server->process_packets_thread, NULL, swiftnet_server_process_packets, new_server); pthread_create(&new_server->execute_callback_thread, NULL, execute_packet_callback_server, new_server); + pthread_mutex_init(&new_server->process_packets_mtx, NULL); + pthread_mutex_init(&new_server->execute_callback_mtx, NULL); + + pthread_cond_init(&new_server->process_packets_cond, NULL); + pthread_cond_init(&new_server->execute_callback_cond, NULL); + #ifdef SWIFT_NET_DEBUG if (check_debug_flag(INITIALIZATION)) { send_debug_message("Successfully initialized server\n"); diff --git a/src/initialize_swift_net.c b/src/initialize_swift_net.c index 7fe8fef..5daf8eb 100644 --- a/src/initialize_swift_net.c +++ b/src/initialize_swift_net.c @@ -18,6 +18,8 @@ uint32_t items_leaked = 0; #endif +uint32_t semaphore_counter = 0x00; + uint32_t maximum_transmission_unit = 0x00; struct in_addr private_ip_address; uint8_t mac_address[6]; diff --git a/src/internal/internal.h b/src/internal/internal.h index 9787591..0410220 100644 --- a/src/internal/internal.h +++ b/src/internal/internal.h @@ -184,6 +184,8 @@ extern void* check_existing_listener(const char* interface_name, void* const con #define ALLOCATOR_STACK_OCCUPIED 1 #define ALLOCATOR_STACK_FREE 0 +extern uint32_t semaphore_counter; + extern struct SwiftNetMemoryAllocator allocator_create(const uint32_t item_size, const uint32_t chunk_item_amount); extern void* allocator_allocate(struct SwiftNetMemoryAllocator* const memory_allocator); extern void allocator_free(struct SwiftNetMemoryAllocator* const memory_allocator, void* const memory_location); diff --git a/src/process_packets.c b/src/process_packets.c index 265ac43..28f1586 100644 --- a/src/process_packets.c +++ b/src/process_packets.c @@ -204,7 +204,7 @@ static inline void handle_request_response(const uint16_t packet_id, struct Swif #endif -static inline void pass_callback_execution(void* const packet_data, struct PacketCallbackQueue* const queue, struct SwiftNetPendingMessage* const pending_message, const uint16_t packet_id) { +static inline void pass_callback_execution(void* const packet_data, struct PacketCallbackQueue* const queue, struct SwiftNetPendingMessage* const pending_message, const uint16_t packet_id, pthread_mutex_t* const execute_callback_mtx, pthread_cond_t* const execute_callback_cond) { struct PacketCallbackQueueNode* const node = allocator_allocate(&packet_callback_queue_node_memory_allocator); node->packet_data = packet_data; node->next = NULL; @@ -213,7 +213,13 @@ static inline void pass_callback_execution(void* const packet_data, struct Packe atomic_thread_fence(memory_order_release); + pthread_mutex_lock(execute_callback_mtx); + insert_callback_queue_node(node, queue); + + pthread_cond_signal(execute_callback_cond); + + pthread_mutex_unlock(execute_callback_mtx); } static inline bool chunk_already_received(uint8_t* const chunks_received, const uint32_t index) { @@ -325,18 +331,30 @@ static inline void swiftnet_process_packets( struct PacketCallbackQueue* const packet_callback_queue, void* const connection, _Atomic bool* closing, - const uint8_t prepend_size + const uint8_t prepend_size, + pthread_mutex_t* const process_packets_mtx, + pthread_cond_t* const process_packets_cond, + pthread_mutex_t* const execute_callback_mtx, + pthread_cond_t* const execute_callback_cond ) { while(1) { if (atomic_load(closing) == true) { break; } + pthread_mutex_lock(process_packets_mtx); + struct PacketQueueNode* const node = wait_for_next_packet(packet_queue); if(node == NULL) { + pthread_cond_wait(process_packets_cond, process_packets_mtx); + + pthread_mutex_unlock(process_packets_mtx); + continue; } + pthread_mutex_unlock(process_packets_mtx); + atomic_thread_fence(memory_order_acquire); uint8_t* const packet_buffer = node->data; @@ -592,10 +610,10 @@ static inline void swiftnet_process_packets( if (packet_info.packet_type == RESPONSE) { handle_request_response(ip_header.ip_id, NULL, new_packet_data, pending_messages, pending_messages_memory_allocator, connection_type, loopback); } else { - pass_callback_execution(new_packet_data, packet_callback_queue, NULL, ip_header.ip_id); + pass_callback_execution(new_packet_data, packet_callback_queue, NULL, ip_header.ip_id, execute_callback_mtx, execute_callback_cond); } #else - pass_callback_execution(new_packet_data, packet_callback_queue, NULL, ip_header.ip_id); + pass_callback_execution(new_packet_data, packet_callback_queue, NULL, ip_header.ip_id, execute_callback_mtx, execute_callback_cond); #endif } else { struct SwiftNetClientPacketData* const new_packet_data = allocator_allocate(&client_packet_data_memory_allocator) ; @@ -615,10 +633,10 @@ static inline void swiftnet_process_packets( if (packet_info.packet_type == RESPONSE) { handle_request_response(ip_header.ip_id, NULL, new_packet_data, pending_messages, pending_messages_memory_allocator, connection_type, loopback); } else { - pass_callback_execution(new_packet_data, packet_callback_queue, NULL, ip_header.ip_id); + pass_callback_execution(new_packet_data, packet_callback_queue, NULL, ip_header.ip_id, execute_callback_mtx, execute_callback_cond); } #else - pass_callback_execution(new_packet_data, packet_callback_queue, NULL, ip_header.ip_id); + pass_callback_execution(new_packet_data, packet_callback_queue, NULL, ip_header.ip_id, execute_callback_mtx, execute_callback_cond); #endif } @@ -676,10 +694,10 @@ static inline void swiftnet_process_packets( if (packet_info.packet_type == RESPONSE) { handle_request_response(ip_header.ip_id, pending_message, packet_data, pending_messages, pending_messages_memory_allocator, connection_type, loopback); } else { - pass_callback_execution(packet_data, packet_callback_queue, pending_message, ip_header.ip_id); + pass_callback_execution(packet_data, packet_callback_queue, pending_message, ip_header.ip_id, execute_callback_mtx, execute_callback_cond); } #else - pass_callback_execution(packet_data, packet_callback_queue, pending_message, ip_header.ip_id); + pass_callback_execution(packet_data, packet_callback_queue, pending_message, ip_header.ip_id, execute_callback_mtx, execute_callback_cond); #endif } else { uint8_t* const ptr = pending_message->packet_data_start; @@ -701,10 +719,10 @@ static inline void swiftnet_process_packets( if (packet_info.packet_type == RESPONSE) { handle_request_response(ip_header.ip_id, pending_message, packet_data, pending_messages, pending_messages_memory_allocator, connection_type, loopback); } else { - pass_callback_execution(packet_data, packet_callback_queue, pending_message, ip_header.ip_id); + pass_callback_execution(packet_data, packet_callback_queue, pending_message, ip_header.ip_id, execute_callback_mtx, execute_callback_cond); } #else - pass_callback_execution(packet_data, packet_callback_queue, pending_message, ip_header.ip_id); + pass_callback_execution(packet_data, packet_callback_queue, pending_message, ip_header.ip_id, execute_callback_mtx, execute_callback_cond); #endif } @@ -738,7 +756,7 @@ static inline void swiftnet_process_packets( void* swiftnet_server_process_packets(void* const void_server) { struct SwiftNetServer* const server = (struct SwiftNetServer*)void_server; - swiftnet_process_packets((void*)&server->packet_handler, server->pcap, server->eth_header, server->server_port, server->loopback, server->addr_type, &server->packets_sending, &server->packets_sending_memory_allocator, &server->pending_messages, &server->pending_messages_memory_allocator, &server->packets_completed, &server->packets_completed_memory_allocator, CONNECTION_TYPE_SERVER, &server->packet_queue, &server->packet_callback_queue, server, &server->closing, server->prepend_size); + swiftnet_process_packets((void*)&server->packet_handler, server->pcap, server->eth_header, server->server_port, server->loopback, server->addr_type, &server->packets_sending, &server->packets_sending_memory_allocator, &server->pending_messages, &server->pending_messages_memory_allocator, &server->packets_completed, &server->packets_completed_memory_allocator, CONNECTION_TYPE_SERVER, &server->packet_queue, &server->packet_callback_queue, server, &server->closing, server->prepend_size, &server->process_packets_mtx, &server->process_packets_cond, &server->execute_callback_mtx, &server->execute_callback_cond); return NULL; } @@ -746,7 +764,7 @@ void* swiftnet_server_process_packets(void* const void_server) { void* swiftnet_client_process_packets(void* const void_client) { struct SwiftNetClientConnection* const client = (struct SwiftNetClientConnection*)void_client; - swiftnet_process_packets((void*)&client->packet_handler, client->pcap, client->eth_header, client->port_info.source_port, client->loopback, client->addr_type, &client->packets_sending, &client->packets_sending_memory_allocator, &client->pending_messages, &client->pending_messages_memory_allocator, &client->packets_completed, &client->packets_completed_memory_allocator, CONNECTION_TYPE_CLIENT, &client->packet_queue, &client->packet_callback_queue, client, &client->closing, client->prepend_size); + swiftnet_process_packets((void*)&client->packet_handler, client->pcap, client->eth_header, client->port_info.source_port, client->loopback, client->addr_type, &client->packets_sending, &client->packets_sending_memory_allocator, &client->pending_messages, &client->pending_messages_memory_allocator, &client->packets_completed, &client->packets_completed_memory_allocator, CONNECTION_TYPE_CLIENT, &client->packet_queue, &client->packet_callback_queue, client, &client->closing, client->prepend_size, &client->process_packets_mtx, &client->process_packets_cond, &client->execute_callback_mtx, &client->execute_callback_cond); return NULL; } diff --git a/src/swift_net.h b/src/swift_net.h index d650cf6..d4d3fbd 100644 --- a/src/swift_net.h +++ b/src/swift_net.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -235,7 +236,11 @@ struct SwiftNetClientConnection { uint16_t addr_type; bool loopback; pthread_t process_packets_thread; + pthread_mutex_t process_packets_mtx; + pthread_cond_t process_packets_cond; pthread_t execute_callback_thread; + pthread_mutex_t execute_callback_mtx; + pthread_cond_t execute_callback_cond; uint32_t maximum_transmission_unit; struct SwiftNetVector pending_messages; struct SwiftNetMemoryAllocator pending_messages_memory_allocator; @@ -258,7 +263,11 @@ struct SwiftNetServer { uint16_t addr_type; bool loopback; pthread_t process_packets_thread; + pthread_mutex_t process_packets_mtx; + pthread_cond_t process_packets_cond; pthread_t execute_callback_thread; + pthread_mutex_t execute_callback_mtx; + pthread_cond_t execute_callback_cond; struct SwiftNetVector pending_messages; struct SwiftNetMemoryAllocator pending_messages_memory_allocator; struct SwiftNetVector packets_sending; diff --git a/tests/integration_tests/output/run_tests b/tests/integration_tests/output/run_tests index 18adf12..6f7240e 100755 Binary files a/tests/integration_tests/output/run_tests and b/tests/integration_tests/output/run_tests differ