netatalk  4.4.0dev
Free and Open Source Apple Filing Protocol (AFP) Server
Loading...
Searching...
No Matches
lantest.c File Reference
#include <errno.h>
#include <getopt.h>
#include <inttypes.h>
#include <limits.h>
#include <math.h>
#include <pthread.h>
#include <pwd.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include "afp.h"
#include "afpclient.h"
#include "afpcmd.h"
#include "afphelper.h"
#include "testhelper.h"

Data Structures

struct  async_io_req

Macros

#define MEASURE_TIME_MS   0
#define MEASURE_AFPD_READ_IO   1
#define MEASURE_AFPD_WRITE_IO   2
#define MEASURE_CNID_READ_IO   3
#define MEASURE_CNID_WRITE_IO   4
#define NUM_MEASUREMENTS   5
#define FPWRITE_RPLY_SIZE   24
#define FPWRITE_RQST_SIZE   36
#define TEST_OPENSTATREAD   0
#define TEST_WRITE100MB   1
#define TEST_READ100MB   2
#define TEST_LOCKUNLOCK   3
#define TEST_CREATE2000FILES   4
#define TEST_ENUM2000FILES   5
#define TEST_DELETE2000FILES   6
#define TEST_DIRTREE   7
#define TEST_CACHE_HITS   8
#define TEST_MIXED_CACHE_OPS   9
#define TEST_DEEP_TRAVERSAL   10
#define TEST_CACHE_VALIDATION   11
#define LASTTEST   TEST_CACHE_VALIDATION
#define NUMTESTS   (LASTTEST+1)
#define TOTAL_AFP_OPS   80686
#define ERROR_MEMORY_ALLOCATION   2
#define ERROR_FILE_DIRECTORY_OPS   3
#define ERROR_FORK_OPERATIONS   4
#define ERROR_NETWORK_PROTOCOL   5
#define ERROR_THREAD_OPERATIONS   6
#define ERROR_VALIDATION_TEST   7
#define ERROR_CONFIGURATION   8
#define ERROR_VOLUME_OPERATIONS   9
#define ERROR_LOGIN   10
#define DIRNUM   10 /* 1000 nested dirs */
#define TEST_NAME_DISPLAY_WIDTH   66

Functions

void clean_exit (int exit_code)
static int cleanup_test_directory (CONN *conn, uint16_t volume, char *dirname)
 Clean up a test directory (main entry point)
int32_t is_there (CONN *conn, uint16_t volume, int32_t did, char *name)
int delete_directory_tree (CONN *conn, uint16_t volume, uint32_t parent_did, char *dirname)
 depth-first recursively delete a directory tree
static void starttimer (void)
static void stoptimer (void)
static uint64_t timediff (void)
static void format_padded_test_name (char *dest, const char *src, size_t width)
static void addresult (int32_t test, uint8_t iteration)
static int32_t should_skip_measurement (int32_t measure_type)
static void results_calc_stats (uint64_t averages[NUMTESTS][NUM_MEASUREMENTS], double std_devs[NUMTESTS][NUM_MEASUREMENTS], char tests_enabled[NUMTESTS])
static void results_print_headers (bool is_csv)
static void results_print_row (int32_t test, bool is_csv, uint64_t averages[NUMTESTS][NUM_MEASUREMENTS], double std_devs[NUMTESTS][NUM_MEASUREMENTS])
static void result_print_summary (uint64_t averages[NUMTESTS][NUM_MEASUREMENTS], bool is_csv, char tests_enabled[NUMTESTS])
static void displayresults (void)
static int32_t safe_atoi (const char *str, const char *param_name, int32_t min_val, int32_t max_val)
static void * rply_thread (void *p)
void run_test (const int32_t dir)
void usage (char *av0)
int main (int32_t ac, char **av)

Variables

bool Debug = false
bool lantest_Quiet = false
CONNConn
int ExitCode = 0
int Version = 34
int Mac = 0
int EmptyVol = 0
char Data [300000] = ""
char * Vol = ""
char * User = ""
char * Path
char * Test = NULL
static uint16_t vol
static DSIdsi
static char * Server = "localhost"
static int32_t Port = DSI_AFPOVERTCP_PORT
static char * Password = ""
static uint8_t Iterations = 2
static uint8_t Iterations_save
static uint8_t iteration_counter = 0
static struct timeval tv_start
static struct timeval tv_end
static struct timeval tv_dif
static pthread_t tid
static bool active_thread = false
CONNConn2
uint16_t VolID
int PassCount = 0
int FailCount = 0
int SkipCount = 0
int NotTestedCount = 0
char FailedTests [1024][256] = {{0}}
char NotTestedTests [1024][256] = {{0}}
char SkippedTests [1024][256] = {{0}}
static int32_t smallfiles = 1000
static off_t rwsize = 100 * 1024 * 1024
static int32_t locking = 10000 / 40
static int32_t create_enum_files = 2000
static int32_t cache_dirs = 10
static int32_t cache_files_per_dir = 10
static int32_t cache_lookup_iterations = 100
static int32_t mixed_cache_files = 200
static int32_t deep_dir_levels = 20
static int32_t deep_test_files = 50
static int32_t deep_traversals = 50
static int32_t validation_files = 100
static int32_t validation_iterations = 100
static uint64_t numrw
static char teststorun [NUMTESTS]
static uint64_t(* results )[][NUMTESTS][NUM_MEASUREMENTS]
static char * bigfilename
static bool csv_output = false
static const char * test_names [NUMTESTS]

Macro Definition Documentation

◆ DIRNUM

#define DIRNUM   10 /* 1000 nested dirs */

◆ ERROR_CONFIGURATION

#define ERROR_CONFIGURATION   8

◆ ERROR_FILE_DIRECTORY_OPS

#define ERROR_FILE_DIRECTORY_OPS   3

◆ ERROR_FORK_OPERATIONS

#define ERROR_FORK_OPERATIONS   4

◆ ERROR_LOGIN

#define ERROR_LOGIN   10

◆ ERROR_MEMORY_ALLOCATION

#define ERROR_MEMORY_ALLOCATION   2

◆ ERROR_NETWORK_PROTOCOL

#define ERROR_NETWORK_PROTOCOL   5

◆ ERROR_THREAD_OPERATIONS

#define ERROR_THREAD_OPERATIONS   6

◆ ERROR_VALIDATION_TEST

#define ERROR_VALIDATION_TEST   7

◆ ERROR_VOLUME_OPERATIONS

#define ERROR_VOLUME_OPERATIONS   9

◆ FPWRITE_RPLY_SIZE

#define FPWRITE_RPLY_SIZE   24

◆ FPWRITE_RQST_SIZE

#define FPWRITE_RQST_SIZE   36

◆ LASTTEST

#define LASTTEST   TEST_CACHE_VALIDATION

◆ MEASURE_AFPD_READ_IO

#define MEASURE_AFPD_READ_IO   1

◆ MEASURE_AFPD_WRITE_IO

#define MEASURE_AFPD_WRITE_IO   2

◆ MEASURE_CNID_READ_IO

#define MEASURE_CNID_READ_IO   3

◆ MEASURE_CNID_WRITE_IO

#define MEASURE_CNID_WRITE_IO   4

◆ MEASURE_TIME_MS

#define MEASURE_TIME_MS   0

◆ NUM_MEASUREMENTS

#define NUM_MEASUREMENTS   5

◆ NUMTESTS

#define NUMTESTS   (LASTTEST+1)

◆ TEST_CACHE_HITS

#define TEST_CACHE_HITS   8

◆ TEST_CACHE_VALIDATION

#define TEST_CACHE_VALIDATION   11

◆ TEST_CREATE2000FILES

#define TEST_CREATE2000FILES   4

◆ TEST_DEEP_TRAVERSAL

#define TEST_DEEP_TRAVERSAL   10

◆ TEST_DELETE2000FILES

#define TEST_DELETE2000FILES   6

◆ TEST_DIRTREE

#define TEST_DIRTREE   7

◆ TEST_ENUM2000FILES

#define TEST_ENUM2000FILES   5

◆ TEST_LOCKUNLOCK

#define TEST_LOCKUNLOCK   3

◆ TEST_MIXED_CACHE_OPS

#define TEST_MIXED_CACHE_OPS   9

◆ TEST_NAME_DISPLAY_WIDTH

#define TEST_NAME_DISPLAY_WIDTH   66

◆ TEST_OPENSTATREAD

#define TEST_OPENSTATREAD   0

◆ TEST_READ100MB

#define TEST_READ100MB   2

◆ TEST_WRITE100MB

#define TEST_WRITE100MB   1

◆ TOTAL_AFP_OPS

#define TOTAL_AFP_OPS   80686

Function Documentation

◆ addresult()

void addresult ( int32_t test,
uint8_t iteration )
static

◆ clean_exit()

void clean_exit ( int exit_code)

◆ cleanup_test_directory()

int cleanup_test_directory ( CONN * conn,
uint16_t volume,
char * dirname )
static

Clean up a test directory (main entry point)

Parameters
connAFP connection
volumeVolume ID
dirnameDirectory name to delete
Returns
0 on success, -1 on failure

◆ delete_directory_tree()

int delete_directory_tree ( CONN * conn,
uint16_t volume,
uint32_t parent_did,
char * dirname )
extern

depth-first recursively delete a directory tree

Algorithm:

  1. Try simple delete (works if directory is empty)
  2. If not empty, get directory ID
  3. Enumerate contents and for each entry:
    • If it's a file: delete it immediately
    • If it's a directory: recurse into it
  4. After all contents are deleted, delete the now-empty directory
Parameters
connAFP connection
volumeVolume ID
parent_didParent directory ID
dirnameDirectory name to delete
Returns
0 on success, -1 on failure

◆ displayresults()

void displayresults ( void )
static

◆ format_padded_test_name()

void format_padded_test_name ( char * dest,
const char * src,
size_t width )
static

◆ is_there()

int32_t is_there ( CONN * conn,
uint16_t volume,
int32_t did,
char * name )

◆ main()

int main ( int32_t ac,
char ** av )

◆ result_print_summary()

void result_print_summary ( uint64_t averages[NUMTESTS][NUM_MEASUREMENTS],
bool is_csv,
char tests_enabled[NUMTESTS] )
static

◆ results_calc_stats()

void results_calc_stats ( uint64_t averages[NUMTESTS][NUM_MEASUREMENTS],
double std_devs[NUMTESTS][NUM_MEASUREMENTS],
char tests_enabled[NUMTESTS] )
static

◆ results_print_headers()

void results_print_headers ( bool is_csv)
static

◆ results_print_row()

void results_print_row ( int32_t test,
bool is_csv,
uint64_t averages[NUMTESTS][NUM_MEASUREMENTS],
double std_devs[NUMTESTS][NUM_MEASUREMENTS] )
static

◆ rply_thread()

void * rply_thread ( void * p)
static

◆ run_test()

void run_test ( const int32_t dir)

◆ safe_atoi()

int32_t safe_atoi ( const char * str,
const char * param_name,
int32_t min_val,
int32_t max_val )
static

◆ should_skip_measurement()

int32_t should_skip_measurement ( int32_t measure_type)
inlinestatic

◆ starttimer()

void starttimer ( void )
static

◆ stoptimer()

void stoptimer ( void )
static

◆ timediff()

uint64_t timediff ( void )
static

◆ usage()

void usage ( char * av0)

Variable Documentation

◆ active_thread

bool active_thread = false
static

◆ bigfilename

char* bigfilename
static

◆ cache_dirs

int32_t cache_dirs = 10
static

◆ cache_files_per_dir

int32_t cache_files_per_dir = 10
static

◆ cache_lookup_iterations

int32_t cache_lookup_iterations = 100
static

◆ Conn

CONN* Conn

◆ Conn2

CONN* Conn2

◆ create_enum_files

int32_t create_enum_files = 2000
static

◆ csv_output

bool csv_output = false
static

◆ Data

char Data[300000] = ""

◆ Debug

bool Debug = false

◆ deep_dir_levels

int32_t deep_dir_levels = 20
static

◆ deep_test_files

int32_t deep_test_files = 50
static

◆ deep_traversals

int32_t deep_traversals = 50
static

◆ dsi

DSI* dsi
static

◆ EmptyVol

int EmptyVol = 0

◆ ExitCode

int ExitCode = 0

◆ FailCount

int FailCount = 0

◆ FailedTests

char FailedTests[1024][256] = {{0}}

◆ iteration_counter

uint8_t iteration_counter = 0
static

◆ Iterations

uint8_t Iterations = 2
static

◆ Iterations_save

uint8_t Iterations_save
static

◆ lantest_Quiet

bool lantest_Quiet = false

◆ locking

int32_t locking = 10000 / 40
static

◆ Mac

int Mac = 0

◆ mixed_cache_files

int32_t mixed_cache_files = 200
static

◆ NotTestedCount

int NotTestedCount = 0

◆ NotTestedTests

char NotTestedTests[1024][256] = {{0}}

◆ numrw

uint64_t numrw
static

◆ PassCount

int PassCount = 0

◆ Password

char* Password = ""
static

◆ Path

char* Path

◆ Port

int32_t Port = DSI_AFPOVERTCP_PORT
static

◆ results

uint64_t(* results)[][NUMTESTS][NUM_MEASUREMENTS]
static

◆ rwsize

off_t rwsize = 100 * 1024 * 1024
static

◆ Server

char* Server = "localhost"
static

◆ SkipCount

int SkipCount = 0

◆ SkippedTests

char SkippedTests[1024][256] = {{0}}

◆ smallfiles

int32_t smallfiles = 1000
static

◆ Test

char* Test = NULL

◆ test_names

const char* test_names[NUMTESTS]
static
Initial value:
= {
"Open, stat and read 512 bytes from 1000 files [8,000 AFP ops]",
"Writing one large file [103 AFP ops]",
"Reading one large file [102 AFP ops]",
"Locking/Unlocking 10000 times each [20,000 AFP ops]",
"Creating dir with 2000 files [4,000 AFP ops]",
"Enumerate dir with 2000 files [~51 AFP ops]",
"Deleting dir with 2000 files [2,000 AFP ops]",
"Create directory tree with 1000 dirs [1,110 AFP ops]",
"Directory cache hits (100 dirs + 1000 files) [11,000 AFP ops]",
"Mixed cache operations (create/stat/enum/delete) [820 AFP ops]",
"Deep path traversal (nested directory navigation) [3,500 AFP ops]",
"Cache validation efficiency (metadata changes) [30,000 AFP ops]"
}

◆ teststorun

char teststorun[NUMTESTS]
static

◆ tid

pthread_t tid
static

◆ tv_dif

struct timeval tv_dif
static

◆ tv_end

struct timeval tv_end
static

◆ tv_start

struct timeval tv_start
static

◆ User

char* User = ""

◆ validation_files

int32_t validation_files = 100
static

◆ validation_iterations

int32_t validation_iterations = 100
static

◆ Version

int Version = 34

◆ Vol

char* Vol = ""

◆ vol

uint16_t vol
static

◆ VolID

uint16_t VolID