1#include "test_file_helper.h"
2#include "fail.h"
3#include <stdlib.h>
4#include <fcntl.h>
5#include <sys/param.h>
6#include <assert.h>
7#include <stdio.h>
8#include <strings.h>
9#include <unistd.h>
10#include <pthread.h>
11
12static char readbuff[4096];
13static char writebuff[4096];
14static int* fds = NULL;
15
16char* setup_tempdir(char* buf) {
17    strcpy(buf, "/tmp/perfindex.XXXXXX");
18    return mkdtemp(buf);
19}
20
21int cleanup_tempdir(char* path) {
22    return rmdir(path);
23}
24
25int test_file_create(char* path, int thread_id, int num_threads, long long length) {
26  long long i;
27  int fd;
28  int retval;
29  char filepath[MAXPATHLEN];
30
31  for(i=0; i<length; i++) {
32    snprintf(filepath, MAXPATHLEN, "%s/file_create-%d-%lld", path, thread_id, i);
33    fd = open(filepath, O_CREAT | O_EXCL | O_WRONLY, 0644);
34    VERIFY(fd >= 0, "open failed");
35
36    close(fd);
37  }
38
39  for(i=0; i<length; i++) {
40    snprintf(filepath, MAXPATHLEN, "%s/file_create-%d-%lld", path, thread_id, i);
41    retval = unlink(filepath);
42    VERIFY(retval == 0, "unlink failed");
43  }
44
45  return PERFINDEX_SUCCESS;
46}
47
48int test_file_read_setup(char* path, int num_threads, long long length, long long max_file_size) {
49    int fd;
50    char filepath[MAXPATHLEN];
51    long long left;
52    int retval;
53    size_t writelen;
54
55    if(max_file_size == 0)
56        max_file_size = MAXFILESIZE;
57
58    left = MIN(length, max_file_size/num_threads);
59
60    snprintf(filepath, sizeof(filepath), "%s/file_read", path);
61    fd = open(filepath, O_CREAT | O_EXCL | O_WRONLY, 0644);
62    printf("%d\n", fd);
63    VERIFY(fd >= 0, "open failed");
64
65    bzero(readbuff, sizeof(readbuff));
66
67    while(left > 0) {
68        writelen = sizeof(readbuff) < left ? sizeof(readbuff) : left;
69        retval = write(fd, readbuff, writelen);
70        VERIFY(retval == writelen, "write failed");
71        left -= writelen;
72    }
73
74    return PERFINDEX_SUCCESS;
75}
76
77int test_file_read(char* path, int thread_id, int num_threads, long long length, long long max_file_size) {
78    long long left;
79    size_t file_offset = 0;
80    int readlen;
81    int fd;
82    int retval;
83    char filepath[MAXPATHLEN];
84    long long filesize;
85
86
87    if(max_file_size == 0)
88        max_file_size = MAXFILESIZE;
89    filesize =  MIN(length, max_file_size/num_threads);
90
91    snprintf(filepath, sizeof(filepath), "%s/file_read", path);
92    fd = open(filepath, O_RDONLY);
93    VERIFY(fd >= 0, "open failed");
94
95    for(left=length; left>0;) {
96        readlen = sizeof(readbuff) < left ? sizeof(readbuff) : left;
97        if(file_offset+readlen > filesize) {
98            retval = lseek(fd, 0, SEEK_SET);
99
100
101            VERIFY(retval >= 0, "lseek failed");
102
103            file_offset = 0;
104            continue;
105        }
106        retval = read(fd, readbuff, readlen);
107        VERIFY(retval == readlen, "read failed");
108        left -= readlen;
109        file_offset += readlen;
110    }
111    return PERFINDEX_SUCCESS;
112}
113
114int test_file_read_cleanup(char* path, int num_threads, long long length) {
115    char filepath[MAXPATHLEN];
116    int retval;
117
118    snprintf(filepath, sizeof(filepath), "%s/file_read", path);
119    retval = unlink(filepath);
120    VERIFY(retval == 0, "unlink failed");
121
122    return PERFINDEX_SUCCESS;
123}
124
125int test_file_write_setup(char* path, int num_threads, long long length) {
126    int i;
127    char filepath[MAXPATHLEN];
128
129    if(fds == NULL) {
130        fds = (int*)malloc(sizeof(int)*num_threads);
131        VERIFY(fds, "malloc failed");
132    }
133
134    for(i=0; i<num_threads; i++) {
135        snprintf(filepath, sizeof(filepath), "%s/file_write-%d", path, i);
136        fds[i] = open(filepath, O_CREAT | O_EXCL | O_WRONLY, 0644);
137        if(fds[i] < 0) {
138            free(fds);
139            fds = NULL;
140            FAIL("open failed");
141        }
142    }
143
144    bzero(writebuff, sizeof(writebuff));
145
146    return PERFINDEX_SUCCESS;
147}
148
149int test_file_write(char* path, int thread_id, int num_threads, long long length, long long max_file_size) {
150    long long left;
151    size_t file_offset = 0;
152    int writelen;
153    int retval;
154    int fd = fds[thread_id];
155
156    if(max_file_size == 0)
157        max_file_size = MAXFILESIZE;
158
159    for(left=length; left>0;) {
160        writelen = sizeof(writebuff) < left ? sizeof(writebuff) : left;
161        retval = write(fd, writebuff, writelen);
162        VERIFY(retval == writelen, "write failed");
163
164        left -= writelen;
165        file_offset += writelen;
166        if(file_offset>max_file_size/num_threads) {
167            retval = lseek(fd, 0, SEEK_SET);
168            VERIFY(retval >= 0, "leeks failed");
169            file_offset = 0;
170        }
171    }
172
173    return PERFINDEX_SUCCESS;
174}
175
176
177int test_file_write_cleanup(char* path, int num_threads, long long length) {
178    int i;
179    char filepath[MAXPATHLEN];
180    int retval;
181
182    for(i=0; i<num_threads; i++) {
183        snprintf(filepath, sizeof(filepath), "%s/file_write-%d", path, i);
184        retval = unlink(filepath);
185        VERIFY(retval == 0, "unlink failed");
186    }
187
188    return PERFINDEX_SUCCESS;
189}
190