1 #!/usr/bin/perl -w |
|
2 # Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 # All rights reserved. |
|
4 # This component and the accompanying materials are made available |
|
5 # under the terms of the License "Eclipse Public License v1.0" |
|
6 # which accompanies this distribution, and is available |
|
7 # at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 # |
|
9 # Initial Contributors: |
|
10 # Nokia Corporation - initial contribution. |
|
11 # |
|
12 # Contributors: |
|
13 # |
|
14 # Description: |
|
15 # This scipt automates the file operations that have to be performed by the user |
|
16 # See usage for more details |
|
17 # |
|
18 # |
|
19 |
|
20 use strict; |
|
21 use File::Copy; |
|
22 use FindBin qw($Bin); |
|
23 |
|
24 sub FormatCard($$) |
|
25 { |
|
26 my ($location, $hash) = @_; |
|
27 |
|
28 # Read files |
|
29 print "This script will now attempt to format the memory card. If you are using\n"; |
|
30 print "Windows, please press ENTER, otherwise Ctrl+C this script and format the card\n"; |
|
31 print "making sure the volume name is '".$hash->{VolumeName}."'.\n"; |
|
32 $/ = "\n"; |
|
33 <STDIN>; |
|
34 print "format $location /v:".$hash->{VolumeName}." /x\n"; |
|
35 system "format $location /v:".$hash->{VolumeName}." /x"; |
|
36 my @files = glob("$location/*"); |
|
37 if (@files != 0) |
|
38 { |
|
39 print "Files found on root directory\n"; |
|
40 return -1; |
|
41 } |
|
42 return 0; |
|
43 } |
|
44 |
|
45 sub ReadFiles1($$) |
|
46 { |
|
47 my ($location, $hash) = @_; |
|
48 # Check current volume name |
|
49 |
|
50 # Not supported... |
|
51 |
|
52 # Read files |
|
53 print "Check number of entries in root dir..."; |
|
54 my @files = glob("$location/*"); |
|
55 if (@files != $hash->{RootEntries} - $hash->{DeleteRootDirs}) |
|
56 { |
|
57 printf "Expected %d, got %d\n", $hash->{RootEntries} - $hash->{DeleteRootDirs}, @files; |
|
58 return -1; |
|
59 } |
|
60 else |
|
61 { |
|
62 print "OK!\n"; |
|
63 } |
|
64 # |
|
65 print "Check directories are all here..."; |
|
66 my $i; |
|
67 for ($i = $hash->{DeleteRootDirs}; $i < $hash->{RootEntries} / 2; $i++) |
|
68 { |
|
69 my $dirname = sprintf("$location/dir%03d", $i); |
|
70 if (not -d $dirname) |
|
71 { |
|
72 print "Cannot find $dirname\n"; |
|
73 return -1; |
|
74 } |
|
75 } |
|
76 print "OK!\n"; |
|
77 # |
|
78 print "Check files and size of expanded files..."; |
|
79 for ($i = $hash->{RootEntries} / 2; $i < $hash->{RootEntries}; $i++) |
|
80 { |
|
81 my $filename; |
|
82 if ($i - $hash->{RootEntries} / 2 == 0) |
|
83 { |
|
84 $filename = "$location/LONG FILE NAME"; |
|
85 } |
|
86 elsif ($i - $hash->{RootEntries} / 2 == 1) |
|
87 { |
|
88 $filename = "$location/Large File"; |
|
89 } |
|
90 else |
|
91 { |
|
92 $filename = sprintf("$location/file%03d", $i - $hash->{RootEntries} / 2); |
|
93 } |
|
94 if (not -f $filename) |
|
95 { |
|
96 print "Cannot find $filename\n"; |
|
97 return -1; |
|
98 } |
|
99 if ($i - $hash->{RootEntries} / 2 == 1) |
|
100 { |
|
101 if (-s $filename != $hash->{LargeFileSize} * (1 << 20)) |
|
102 { |
|
103 printf "$filename: expected size %d got %d", $hash->{ExpandRootFilesSize} * (1 << 20), -s $filename; |
|
104 return -1; |
|
105 } |
|
106 } |
|
107 elsif (($i - $hash->{RootEntries} / 2 > 1) and ($i - $hash->{RootEntries} / 2 - 2 < $hash->{ExpandRootFilesNumber})) |
|
108 { |
|
109 if (-s $filename != $hash->{ExpandRootFilesSize} * (1 << 20)) |
|
110 { |
|
111 printf "$filename: expected size %d got %d", $hash->{ExpandRootFilesSize} * (1 << 20), -s $filename; |
|
112 return -1; |
|
113 } |
|
114 } |
|
115 } |
|
116 print "OK!\n"; |
|
117 # |
|
118 print "Check subdir entries..."; |
|
119 @files = glob(sprintf("$location/dir%03d/*", $hash->{RootEntries} / 2 - 1)); |
|
120 if (@files != $hash->{SubDirEntries}) |
|
121 { |
|
122 printf "Expected %d entries in '$location/dir%03d', got %d", $hash->{SubDirEntries}, $hash->{RootEntries} / 2 - 1, @files; |
|
123 return -1; |
|
124 } |
|
125 for ($i = 0; $i < $hash->{SubDirEntries}; $i++) |
|
126 { |
|
127 my $filename = sprintf("$location/dir%03d/file%04d", $hash->{RootEntries} / 2 - 1, $i); |
|
128 if (not -f $filename) |
|
129 { |
|
130 print "Cannot find $filename\n"; |
|
131 return -1; |
|
132 } |
|
133 } |
|
134 print "OK!\n"; |
|
135 return 0; |
|
136 } |
|
137 |
|
138 sub FileOperations1($$) |
|
139 { |
|
140 |
|
141 my ($location, $hash) = @_; |
|
142 my $i; |
|
143 |
|
144 print "Create root directories..."; |
|
145 for ($i = 0; $i < $hash->{RootEntries} / 2; $i++) |
|
146 { |
|
147 my $dirname = sprintf("$location/dir%03d", $i); |
|
148 if (!mkdir($dirname)) |
|
149 { |
|
150 print "Error when making $dirname: $!\n"; |
|
151 return -1; |
|
152 } |
|
153 } |
|
154 print "OK!\n"; |
|
155 # |
|
156 print "Create root files..."; |
|
157 for ($i = $hash->{RootEntries} / 2; $i < $hash->{RootEntries}; $i++) |
|
158 { |
|
159 my $filename = sprintf("$location/file%03d", $i - $hash->{RootEntries} / 2); |
|
160 open ROOTFILE, ">$filename" or die "Cannot open $filename for output: $!"; |
|
161 print ROOTFILE "SD"; |
|
162 close ROOTFILE; |
|
163 } |
|
164 print "OK!\n"; |
|
165 # |
|
166 print "Expand root files..."; |
|
167 for ($i = 2; $i < $hash->{ExpandRootFilesNumber} + 2; $i++) |
|
168 { |
|
169 my $filename = sprintf("$location/file%03d", $i); |
|
170 open EXPANDROOTFILE, ">$filename" or die "Cannot open $filename for output: $!"; |
|
171 print EXPANDROOTFILE "A" x ($hash->{ExpandRootFilesSize} * (1 << 20)); |
|
172 close EXPANDROOTFILE; |
|
173 } |
|
174 print "OK!\n"; |
|
175 # |
|
176 print "Delete root directories..."; |
|
177 for ($i = $hash->{DeleteRootDirs} - 1; $i >= 0; $i--) |
|
178 { |
|
179 my $dirname = sprintf("$location/dir%03d", $i); |
|
180 if (!rmdir($dirname)) |
|
181 { |
|
182 print "Error when removing $dirname"; |
|
183 return -1; |
|
184 } |
|
185 } |
|
186 print "OK!\n"; |
|
187 # |
|
188 print "Rename 'file000' to 'LONG FILE NAME'..."; |
|
189 if (!rename("$location/file000", "$location/LONG FILE NAME")) |
|
190 { |
|
191 print "failed\n"; |
|
192 return -1; |
|
193 } |
|
194 print "OK!\n"; |
|
195 # |
|
196 print "Create subdir entries..."; |
|
197 for ($i = 0; $i < $hash->{SubDirEntries}; $i++) |
|
198 { |
|
199 my $filename = sprintf("$location/dir%03d/file%04d", $hash->{RootEntries} / 2 - 1, $i); |
|
200 open SUBDIRFILE, ">$filename" or die "Can't open $filename for output: $!\n"; |
|
201 print SUBDIRFILE "SD"; |
|
202 close SUBDIRFILE; |
|
203 } |
|
204 print "OK!\n"; |
|
205 # |
|
206 print "Rename 'file001' to 'Large File'..."; |
|
207 if (!rename("$location/file001", "$location/Large File")) |
|
208 { |
|
209 print "failed\n"; |
|
210 return -1; |
|
211 } |
|
212 print "OK!\n"; |
|
213 # |
|
214 print "Expand Large File..."; |
|
215 open EXPANDLARGEFILE, ">$location/Large File" or die "Cannot open '$location/Large File' for output: $!"; |
|
216 print EXPANDLARGEFILE "B" x ($hash->{LargeFileSize} * (1 << 20)); |
|
217 close EXPANDLARGEFILE; |
|
218 print "OK!\n"; |
|
219 # |
|
220 return 0; |
|
221 } |
|
222 |
|
223 sub FileOperations2($$) |
|
224 { |
|
225 my ($location, $hash) = @_; |
|
226 my $i; |
|
227 |
|
228 print "Change volume name...\n"; |
|
229 print "WARNING: If not under Windows, change the volume name manually to '".$hash->{VolumeName}."' afterwards.\n"; |
|
230 print "label $location ".$hash->{VolumeName}; |
|
231 system "label $location ".$hash->{VolumeName}; |
|
232 print "OK!\n"; |
|
233 # |
|
234 print "Delete subdir entries..."; |
|
235 for ($i = 0; $i < $hash->{SubDirEntries}; $i++) |
|
236 { |
|
237 my $filename = sprintf("$location/dir%03d/file%04d", $hash->{RootEntries} / 2 - 1, $i); |
|
238 if (!unlink($filename)) |
|
239 { |
|
240 print "Cannot delete $filename\n"; |
|
241 return -1; |
|
242 } |
|
243 } |
|
244 print "OK!\n"; |
|
245 # |
|
246 print "Create subdir entries..."; |
|
247 for ($i = 0; $i < $hash->{SubDirEntries}; $i++) |
|
248 { |
|
249 my $filename = sprintf("$location/dir%03d/file%04d", $hash->{RootEntries} / 2 - 2, $i); |
|
250 open SUBDIRFILE, ">$filename" or die "Can't open $filename for output: $!\n"; |
|
251 print SUBDIRFILE "SD"; |
|
252 close SUBDIRFILE; |
|
253 } |
|
254 print "OK!\n"; |
|
255 # |
|
256 print "Move 'LONG FILE NAME' to tmp dir..."; |
|
257 if (!move("$location/LONG FILE NAME", $ENV{TMP}."/")) |
|
258 { |
|
259 print "Cannot move '$location/LONG FILE NAME' to '".$ENV{TMP}."/'\n"; |
|
260 return -1; |
|
261 } |
|
262 print "OK!\n"; |
|
263 # |
|
264 print "Copy 'file002' to tmp dir..."; |
|
265 if (!copy("$location/file002", $ENV{TMP}."/")) |
|
266 { |
|
267 print "Cannot copy '$location/file002' to '".$ENV{TMP}."/'\n"; |
|
268 return -1; |
|
269 } |
|
270 print "OK!\n"; |
|
271 # |
|
272 print "Copy 'file002' back to card..."; |
|
273 if (!copy($ENV{TMP}."/file002", "$location/BACK")) |
|
274 { |
|
275 print "Cannot copy '".$ENV{TMP}."/file002' to '$location/BACK'\n"; |
|
276 return -1; |
|
277 } |
|
278 print "OK!\n"; |
|
279 return 0; |
|
280 } |
|
281 |
|
282 sub Usage() |
|
283 { |
|
284 print STDERR <<USAGE_END; |
|
285 fileoperations.pl |
|
286 Description: |
|
287 This script works in conjunction with the SD manual interoperability tests. |
|
288 When running these tests, the user will be invited to perform specific file |
|
289 operations from another device than the one under test. This Perl script |
|
290 automates the execution of those file operations. |
|
291 |
|
292 There are two sets of actions that can be performed by this Perl script, |
|
293 'INBOUND' and 'OUTBOUND'. The user will be clearly notified as to which set |
|
294 of actions to carry out. |
|
295 |
|
296 This script can be run from any directory, but should be left within the |
|
297 source code directory tree as it requires access to the test INI file. |
|
298 Usage: |
|
299 fileoperations.pl <type> <location> |
|
300 Where: |
|
301 type 'OUTBOUND' or 'INBOUND' |
|
302 location Memory card root directory |
|
303 E.g.: |
|
304 fileoperations.pl OUTBOUND M: |
|
305 fileoperations.pl INBOUND /mnt/sdcard |
|
306 USAGE_END |
|
307 } |
|
308 |
|
309 sub Main() |
|
310 { |
|
311 # Verify arguments |
|
312 if (@ARGV != 2) |
|
313 { |
|
314 print STDERR "ERROR: Wrong number of arguments\n"; |
|
315 Usage(); |
|
316 return -1; |
|
317 } |
|
318 my ($type, $location) = @ARGV; |
|
319 $type = uc($type); |
|
320 if ($type ne 'OUTBOUND' and $type ne 'INBOUND') |
|
321 { |
|
322 print STDERR "ERROR: Invalid type '$type'\n"; |
|
323 Usage(); |
|
324 return -1; |
|
325 } |
|
326 if (not -d "$location/") |
|
327 { |
|
328 print STDERR "ERROR: '$location/' is not a valid directory\n"; |
|
329 Usage(); |
|
330 return -1; |
|
331 } |
|
332 if (not -e "$Bin/../testdata/btsd.ini") |
|
333 { |
|
334 print STDERR "ERROR: Cannot find $Bin/../testdata/btsd.ini\n"; |
|
335 return -1; |
|
336 } |
|
337 |
|
338 # Get values from INI file |
|
339 my %inival = ( |
|
340 RootEntries => 0, |
|
341 ExpandRootFilesNumber => 0, |
|
342 ExpandRootFilesSize => 0, |
|
343 DeleteRootDirs => 0, |
|
344 SubDirEntries => 0, |
|
345 LargeFileSize => 0, |
|
346 VolumeName => ''); |
|
347 open INIFILE, "$Bin/../testdata/btsd.ini" or die "ERROR: Cannot open $Bin/../testdata/btsd.ini for read: $!\n"; |
|
348 while (<INIFILE>) |
|
349 { |
|
350 $/ = '['; |
|
351 next unless /INTEROP_$type\]/; |
|
352 |
|
353 if (not /FileOperationsRootEntries=(\d+)/) |
|
354 { |
|
355 print STDERR "ERROR: FileOperationsRootEntries entry not found in INI file\n"; |
|
356 return -1; |
|
357 } |
|
358 $inival{RootEntries} = $1; |
|
359 |
|
360 if (not /FileOperationsExpandRootFilesNumber=\s*(\d+)/) |
|
361 { |
|
362 print STDERR "ERROR: FileOperationsExpandRootFilesNumber entry not found in INI file\n"; |
|
363 return -1; |
|
364 } |
|
365 $inival{ExpandRootFilesNumber} = $1; |
|
366 |
|
367 if (not /FileOperationsExpandRootFilesSize=\s*(\d+)/) |
|
368 { |
|
369 print STDERR "ERROR: FileOperationsExpandRootFilesSize entry not found in INI file\n"; |
|
370 return -1; |
|
371 } |
|
372 $inival{ExpandRootFilesSize} = $1; |
|
373 |
|
374 if (not /FileOperationsDeleteRootDirs=\s*(\d+)/) |
|
375 { |
|
376 print STDERR "ERROR: FileOperationsDeleteRootDirs entry not found in INI file\n"; |
|
377 return -1; |
|
378 } |
|
379 $inival{DeleteRootDirs} = $1; |
|
380 |
|
381 if (not /FileOperationsSubDirEntries=\s*(\d+)/) |
|
382 { |
|
383 print STDERR "ERROR: FileOperationsSubDirEntries entry not found in INI file\n"; |
|
384 return -1; |
|
385 } |
|
386 $inival{SubDirEntries} = $1; |
|
387 |
|
388 if (not /FileOperationsLargeFileSize=\s*(\d+)/) |
|
389 { |
|
390 print STDERR "ERROR: FileOperationsLargeFileSize entry not found in INI file\n"; |
|
391 return -1; |
|
392 } |
|
393 $inival{LargeFileSize} = $1; |
|
394 |
|
395 if (not /FileOperationsVolumeName=\s*([^\n]+)/) |
|
396 { |
|
397 print STDERR "ERROR: FileOperationsVolumeName entry not found in INI file\n"; |
|
398 return -1; |
|
399 } |
|
400 $inival{VolumeName} = $1; |
|
401 $inival{VolumeName} =~ s/\s+$//; # Remove trailing whitespaces |
|
402 } |
|
403 close INIFILE; |
|
404 print "Values read from $Bin/../testdata/btsd.ini:\n"; |
|
405 print "FileOperationsRootEntries=${inival{RootEntries}}\n"; |
|
406 print "FileOperationsExpandRootFilesNumber=${inival{ExpandRootFilesNumber}}\n"; |
|
407 print "FileOperationsExpandRootFilesSize=${inival{ExpandRootFilesSize}}\n"; |
|
408 print "FileOperationsDeleteRootDirs=${inival{DeleteRootDirs}}\n"; |
|
409 print "FileOperationsSubDirEntries=${inival{SubDirEntries}}\n"; |
|
410 print "FileOperationsLargeFileSize=${inival{LargeFileSize}}\n"; |
|
411 print "FileOperationsVolumeName=${inival{VolumeName}}\n\n"; |
|
412 |
|
413 my $retval; |
|
414 print "READ CONTENTS OF MEMORY CARD\n"; |
|
415 if ($type eq 'INBOUND') |
|
416 { |
|
417 $retval = FormatCard($location, \%inival); |
|
418 } |
|
419 else |
|
420 { |
|
421 $retval = ReadFiles1($location, \%inival); |
|
422 } |
|
423 if ($retval) |
|
424 { |
|
425 return $retval; |
|
426 } |
|
427 print "PERFORM MORE FILE OPERATIONS\n"; |
|
428 if ($type eq 'INBOUND') |
|
429 { |
|
430 $retval = FileOperations1($location, \%inival); |
|
431 } |
|
432 else |
|
433 { |
|
434 $retval = FileOperations2($location, \%inival); |
|
435 } |
|
436 if (not $retval) |
|
437 { |
|
438 print "FILE OPERATIONS WERE SUCCESFUL\n"; |
|
439 print "Now insert card back into the device under test or disconnect USB cable.\n"; |
|
440 } |
|
441 return $retval; |
|
442 } |
|
443 |
|
444 exit Main(); |
|