aboutsummaryrefslogtreecommitdiff
path: root/tests/fs-tests/stress/atoms/rndrm00.c
blob: 724b1c3adb7ae24ac74359d0d801fb5fad3f0425 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/*
 * Copyright (C) 2007 Nokia Corporation.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 * Author: Adrian Hunter
 */

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

#include "tests.h"

void rndrm00(void)
{
	int64_t repeat;
	int64_t size, this_size;
	pid_t pid;
	char dir_name[256];

	/* Create a directory to test in */
	pid = getpid();
	tests_cat_pid(dir_name, "rndrm00_test_dir_", pid);
	if (chdir(dir_name) == -1)
		CHECK(mkdir(dir_name, 0777) != -1);
	CHECK(chdir(dir_name) != -1);
	/* Repeat loop */
	repeat = tests_repeat_parameter;
	size = 0;
	for (;;) {
		/* Create and remove sub-dirs and small files, */
		/* but tending to grow */
		do {
			if (tests_random_no(3)) {
				this_size = tests_create_entry(NULL);
				if (!this_size)
					break;
				size += this_size;
			} else {
				this_size = tests_remove_entry();
				size -= this_size;
				if (size < 0)
					size = 0;
				if (!this_size)
					this_size = 1;
			}
		} while (this_size &&
			(tests_size_parameter == 0 ||
			size < tests_size_parameter));
		/* Create and remove sub-dirs and small files, but */
		/* but tending to shrink */
		do {
			if (!tests_random_no(3)) {
				this_size = tests_create_entry(NULL);
				size += this_size;
			} else {
				this_size = tests_remove_entry();
				size -= this_size;
				if (size < 0)
					size = 0;
			}
		} while ((tests_size_parameter != 0 &&
			size > tests_size_parameter / 10) ||
			(tests_size_parameter == 0 && size > 100000));
		/* Break if repeat count exceeded */
		if (tests_repeat_parameter > 0 && --repeat <= 0)
			break;
		/* Sleep */
		if (tests_sleep_parameter > 0) {
			unsigned us = tests_sleep_parameter * 1000;
			unsigned rand_divisor = RAND_MAX / us;
			unsigned s = (us / 2) + (rand() / rand_divisor);
			usleep(s);
		}
	}
	/* Tidy up by removing everything */
	tests_clear_dir(".");
	CHECK(chdir("..") != -1);
	CHECK(rmdir(dir_name) != -1);
}

/* Title of this test */

const char *rndrm00_get_title(void)
{
	return "Randomly create and remove directories and files";
}

/* Description of this test */

const char *rndrm00_get_description(void)
{
	return
		"Create a directory named rndrm00_test_dir_pid, where " \
		"pid is the process id.  Within that directory, " \
		"randomly create and remove " \
		"a number of sub-directories and small files, " \
		"but do more creates than removes. " \
		"When the total size of all sub-directories and files " \
		"is greater than the size specified by the size parameter, " \
		"start to do more removes than creates. " \
		"The size parameter is given by the -z or --size option, " \
		"otherwise it defaults to 1000000. " \
		"A size of zero fills the file system until there is no "
		"space left. " \
		"The task repeats, sleeping in between each iteration. " \
		"The repeat count is set by the -n or --repeat option, " \
		"otherwise it defaults to 1. " \
		"A repeat count of zero repeats forever. " \
		"The sleep value is given by the -p or --sleep option, " \
		"otherwise it defaults to 0. "
		"Sleep is specified in milliseconds.";
}

int main(int argc, char *argv[])
{
	int run_test;

	/* Set default test size */
	tests_size_parameter = 1000000;

	/* Set default test repetition */
	tests_repeat_parameter = 1;

	/* Set default test sleep */
	tests_sleep_parameter = 0;

	/* Handle common arguments */
	run_test = tests_get_args(argc, argv, rndrm00_get_title(),
			rndrm00_get_description(), "znp");
	if (!run_test)
		return 1;
	/* Change directory to the file system and check it is ok for testing */
	tests_check_test_file_system();
	/* Do the actual test */
	rndrm00();
	return 0;
}