9a46fee006c583aabc6f1f2c4aa9ad19e9558a68
[debian/amanda] / device-src / tests / device_test.c
1 #include <device.h>
2 #include <amanda.h>
3 #include <timestamp.h>
4
5 int blocksize;
6 unsigned int seed = 0;
7
8 static char * make_rand_buf(int size) {
9     char * rval;
10     unsigned int i;
11
12     rval = malloc(size);
13     i = size;
14     while (i > sizeof(int)) {
15         int rand;
16         rand = rand_r(&seed);
17         memcpy(rval + size - i, &rand, sizeof(int));
18         i -= sizeof(int);
19     }
20     
21     if (size > 0) {
22         int rand;
23         rand = rand_r(&seed);
24         memcpy(rval + size - i, &rand, i);
25     }
26
27     return rval;
28 }
29
30 static gboolean write_whole_file(Device * device) {
31     dumpfile_t dumpfile;
32     char * tmp;
33     int i;
34
35     fh_init(&dumpfile);
36     dumpfile.type = F_DUMPFILE;
37     tmp = get_timestamp_from_time(time(NULL));
38     strcpy(dumpfile.datestamp, tmp);
39     amfree(tmp);
40     strcpy(dumpfile.name, "localhost");
41     tmp = g_get_current_dir();
42     strcpy(dumpfile.disk, tmp);
43     amfree(tmp);
44     strcpy(dumpfile.program, "TESTER");
45     strcpy(dumpfile.recover_cmd, "recover_cmd");
46
47     blocksize = device_write_max_size(device);
48     
49     g_return_val_if_fail(device_start_file(device, &dumpfile), FALSE);
50     
51     for (i = 0; i < 1000; i ++) {
52         int size;
53         char * buf;
54         if (i == 999)
55             size = blocksize / 2;
56         else
57             size = blocksize;
58         buf = make_rand_buf(size);
59         g_return_val_if_fail(device_write_block(device, size, buf, i == 999),
60                              FALSE);
61         amfree(buf);
62     }
63     
64     g_return_val_if_fail(device->in_file == FALSE, FALSE);
65
66     return TRUE;
67 }
68
69 static gboolean read_whole_file(Device * device, int fileno) {
70     int size = 0;
71     dumpfile_t * file = device_seek_file(device, fileno + 1);
72     int i;
73     char *buf;
74
75     if (file == NULL)
76         g_assert_not_reached();
77     else
78         amfree(file);
79
80     g_return_val_if_fail(device_seek_block(device, 0), FALSE);
81     
82     g_return_val_if_fail(0 == device_read_block(device, NULL, &size),
83                          FALSE);
84     g_assert(size >= blocksize);
85         
86     for (i = 0; i < 1000; i ++) {
87         int size, size2;
88         char buf2[blocksize];
89         size2 = blocksize;
90         if (i == 999)
91             size = blocksize/2;
92         else
93             size = blocksize;
94         buf = make_rand_buf(size);
95         
96         g_return_val_if_fail(device_read_block(device, buf2, &size2),
97                              FALSE);
98         g_assert(size2 == size || size2 == blocksize);
99         g_assert(memcmp(buf, buf2, size) == 0);
100         amfree(buf);
101     }
102     
103     size = blocksize;
104     buf = malloc(blocksize);
105     g_assert(-1 == device_read_block(device, &buf, &size));
106     g_return_val_if_fail(device->is_eof, FALSE);
107     free(buf);
108
109     return TRUE;
110 }
111
112 static MediaAccessMode get_medium_type(Device * device) {
113     GValue value;
114     MediaAccessMode rval;
115     
116     bzero(&value, sizeof(value));
117
118     g_return_val_if_fail(device_property_get(device, PROPERTY_MEDIUM_TYPE,
119                                              &value), 0);
120
121     rval = g_value_get_enum(&value);
122     g_value_unset(&value);
123     return rval;
124 }
125
126 int main(int argc, char ** argv) {
127     Device * device;
128     int h;
129     MediaAccessMode medium_type;
130     
131     g_return_val_if_fail(argc == 2, 1);
132
133     device_api_init();
134
135     device = device_open(argv[1]);
136     g_return_val_if_fail(device != NULL, 2);
137
138     medium_type = get_medium_type(device);
139
140     if (device->volume_label) {
141         printf("Last header: %s %s\n", device->volume_label,
142                device->volume_time);
143     }
144
145     if (medium_type != MEDIA_ACCESS_MODE_READ_ONLY) {
146         g_return_val_if_fail(device_start(device, ACCESS_WRITE, 
147                                           "foo", NULL),
148                              2);
149         
150         for (h = 0; h < 10; h ++) {
151             gboolean appendable;
152             GValue value;
153             g_return_val_if_fail(write_whole_file(device), 3);
154             
155             bzero(&value, sizeof(value));
156             g_return_val_if_fail(device_property_get(device,
157                                                      PROPERTY_APPENDABLE,
158                                                      &value), 4);
159             appendable = g_value_get_boolean(&value);
160             g_value_unset(&value);
161             
162             if (appendable && h == 5) {
163                 g_object_unref(device);
164                 
165                 device = device_open(argv[1]);
166                 g_return_val_if_fail(device != NULL, 6);
167                 
168                 g_return_val_if_fail(device_start(device, ACCESS_APPEND, 
169                                                   "foo", NULL),
170                                      2);
171             }
172         }
173         
174         g_object_unref(device);    
175         
176         device = device_open(argv[1]);
177         g_return_val_if_fail(device != NULL, 6);
178     }
179
180     /* Fixme: check for readable access mode. */
181     if (medium_type != MEDIA_ACCESS_MODE_WRITE_ONLY) {
182         g_return_val_if_fail(device->volume_label, 7);
183         printf("This header: %s %s\n", device->volume_label,
184                device->volume_time);    
185         
186         g_return_val_if_fail(device_start(device, ACCESS_READ, 
187                                           "foo", NULL),
188                              2);
189         seed = 0;
190         for (h = 0; h < 10; h ++) {
191             g_return_val_if_fail(read_whole_file(device, h), 8);
192         }
193     }
194
195     g_object_unref(device);    
196
197     return 0;
198 }