Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | # ========== Copyright Header Begin ========================================== |
2 | # | |
3 | # OpenSPARC T2 Processor File: DiagList.pm | |
4 | # Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved | |
5 | # 4150 Network Circle, Santa Clara, California 95054, U.S.A. | |
6 | # | |
7 | # * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
8 | # | |
9 | # This program is free software; you can redistribute it and/or modify | |
10 | # it under the terms of the GNU General Public License as published by | |
11 | # the Free Software Foundation; version 2 of the License. | |
12 | # | |
13 | # This program is distributed in the hope that it will be useful, | |
14 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | # GNU General Public License for more details. | |
17 | # | |
18 | # You should have received a copy of the GNU General Public License | |
19 | # along with this program; if not, write to the Free Software | |
20 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 | # | |
22 | # For the avoidance of doubt, and except that if any non-GPL license | |
23 | # choice is available it will apply instead, Sun elects to use only | |
24 | # the General Public License version 2 (GPLv2) at this time for any | |
25 | # software where a choice of GPL license versions is made | |
26 | # available with the language indicating that GPLv2 or any later version | |
27 | # may be used, or where a choice of which version of the GPL is applied is | |
28 | # otherwise unspecified. | |
29 | # | |
30 | # Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
31 | # CA 95054 USA or visit www.sun.com if you need additional information or | |
32 | # have any questions. | |
33 | # | |
34 | # ========== Copyright Header End ============================================ | |
35 | package DiagList; | |
36 | ||
37 | use 5.008; | |
38 | use strict; | |
39 | use warnings; | |
40 | ||
41 | use IO::File; | |
42 | use Tie::IxHash; | |
43 | use File::Spec; | |
44 | use Carp; | |
45 | ||
46 | require Exporter; | |
47 | ||
48 | ||
49 | use DiagList::Objects; | |
50 | use DiagList::Output; | |
51 | use DiagList::Settings; | |
52 | use DiagList::Script; | |
53 | ||
54 | our @ISA = qw(Exporter); | |
55 | ||
56 | # Items to export into callers namespace by default. Note: do not export | |
57 | # names by default without a very good reason. Use EXPORT_OK instead. | |
58 | # Do not simply export all your public functions/methods/constants. | |
59 | ||
60 | # This allows declaration use DiagList ':all'; | |
61 | # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK | |
62 | # will save memory. | |
63 | ||
64 | our @script = qw(dlist); | |
65 | our @triage = qw(hookup_triage_interface); | |
66 | our @functions = qw(dlist construct_dlist get_diag_display build_tags); | |
67 | ||
68 | our %EXPORT_TAGS = ( all => [ @script, @triage, @functions ], | |
69 | func => [ @functions ], | |
70 | triage => [ @triage ], | |
71 | script => [ @script ], | |
72 | ); | |
73 | ||
74 | our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } ); | |
75 | ||
76 | our @EXPORT = qw( | |
77 | ); | |
78 | ||
79 | our $VERSION = '1.11'; | |
80 | ||
81 | ############################################################################## | |
82 | ||
83 | sub hookup_triage_interface { | |
84 | my $code = | |
85 | q{ | |
86 | use DiagList::TriageInterface; | |
87 | }; | |
88 | ||
89 | eval $code; | |
90 | die $@ if $@; | |
91 | } | |
92 | ||
93 | ############################################################################## | |
94 | ############################################################################## | |
95 | ############################################################################## | |
96 | 1; | |
97 | __END__ | |
98 | ||
99 | =head1 NAME | |
100 | ||
101 | DiagList - perl module for parsing diag lists | |
102 | ||
103 | =head1 SYNOPSIS | |
104 | ||
105 | use DiagList; | |
106 | ||
107 | my $dlist = DiagList->new('./master_diaglist'); | |
108 | my $group = $dlist->find_group('cmp_regr'); | |
109 | ||
110 | foreach my $buildtag ($group->build_tags) { | |
111 | ||
112 | my $buildargs = $dlist->build_args($buildtag); | |
113 | ||
114 | foreach my $diagname ($group->list_diags($buildtag)) { | |
115 | my $diag = $group->find_diag($buildtag, $diagname); | |
116 | my $runargs = $diag->get_cmdline(); | |
117 | } | |
118 | ||
119 | } | |
120 | ||
121 | ||
122 | =head1 ABSTRACT | |
123 | ||
124 | This is a perl module for parsing diag lists. It uses | |
125 | XML-like syntax to define regression arguments. | |
126 | ||
127 | =head1 DESCRIPTION | |
128 | ||
129 | This module exists to parse diaglists and return results in a usable | |
130 | format. The Synopsis section above describes common usage. This is | |
131 | an object module with no exported functions. The top-level object is | |
132 | of type DiagList. Sub-objects are returned of type DiagList::Group | |
133 | and DiagList::Diag. The public interface of each is described below. | |
134 | ||
135 | =head2 DiagList Object | |
136 | ||
137 | This is the only type of object the user will create explicitly. | |
138 | ||
139 | =over 4 | |
140 | ||
141 | =item new($file, [$fh]) E<lt>class methodE<gt> | |
142 | ||
143 | Parse the given diaglist file and return a new DiagList object. | |
144 | Throws an exception if it cannot parse the file. If an optional | |
145 | second argument is provided, it is treated as a file handle to read | |
146 | from. It can be either an IO::File object or a bare file handle. In | |
147 | this case the first argument, $file, is used purely for reporting | |
148 | errors. | |
149 | ||
150 | =item build_list() | |
151 | ||
152 | Returns a list of the build tags that were seen in the file. | |
153 | ||
154 | =item build_args($build_tag) | |
155 | ||
156 | Returns the build arguments for the specified build tag. Returns | |
157 | undef if a build tag called $build_tag was not seen in the file. The | |
158 | build arguments are the ones specified in the group tag defintion. | |
159 | The only processing done is that name=E<lt>...E<gt> is stripped out | |
160 | completely and sys=E<lt>...E<gt> is replaced by -sys=E<lt>...E<gt>. | |
161 | ||
162 | =item build_hash() | |
163 | ||
164 | Returns a reference to a hash where the keys are build tags and the | |
165 | values are the build args. Note that this is a reference into the | |
166 | internal state of the object, so modifying this hash will modify the | |
167 | DiagList object. | |
168 | ||
169 | =item group_list() | |
170 | ||
171 | Returns a list of group names that were seen in the file. | |
172 | ||
173 | =item find_group($groupname) | |
174 | ||
175 | Returns a DiagList::Group object for the specified $groupname. | |
176 | Returns undef if no such $groupname was seen in the file. | |
177 | ||
178 | =item group_hash() | |
179 | ||
180 | Returns a reference to a hash where keys are group names and values | |
181 | are DiagList::Group objects. Note that this is a reference into the | |
182 | internal state of the object, so modifying the hash will modify the | |
183 | DiagList object. | |
184 | ||
185 | =back | |
186 | ||
187 | =head2 DiagList::Group Object | |
188 | ||
189 | These objects are created by the DiagList object and can be returned | |
190 | to the user via the DiagList methods find_group and group_hash (both | |
191 | described above). The DiagList::Group objects support the following | |
192 | methods. | |
193 | ||
194 | =over 4 | |
195 | ||
196 | =item name([$name]) | |
197 | ||
198 | Accessor function for the group name. If an argument $name is | |
199 | provided, the name of the group is set to $name. The name of the | |
200 | group is returned, whether or not it has changed. Changing the name | |
201 | with this method is highly discouraged for user code, but it is | |
202 | perfectly acceptable to call name() with no arugments to get the name. | |
203 | ||
204 | =item build_tags() | |
205 | ||
206 | Returns a list of build_tags that are applicable to this group. | |
207 | ||
208 | =item list_diags($buildtag) | |
209 | ||
210 | Returns a list of diag names in this group that correspond to the | |
211 | given $buildtag. | |
212 | ||
213 | =item find_diag($buildtag, $diagname) | |
214 | ||
215 | Returns a DiagList::Diag object that corresponds the the given | |
216 | $diagname and the provided $buildtag. Returns undef if no such | |
217 | $buildtag or no such $diagname was found. | |
218 | ||
219 | =item diag_hash($buildtag) | |
220 | ||
221 | Returns a reference to a hash where the keys are diag names and the | |
222 | values are DiagList::Diag objects. Note tha this is a reference into | |
223 | the internal state of the object, so modifying the hash will modify | |
224 | the object. | |
225 | ||
226 | =back | |
227 | ||
228 | =head2 DiagList::Diag Object | |
229 | ||
230 | DiagList::Diag objects represent the state associated with a diag. | |
231 | They are returned by the DiagList::Group methods find_diag() and | |
232 | diag_hash(). DiagList::Diag objects support the following methods. | |
233 | ||
234 | =over 4 | |
235 | ||
236 | =item get_alias() | |
237 | ||
238 | Returns the diag alias, as provided in the diaglist file. | |
239 | ||
240 | =item get_nametag() | |
241 | ||
242 | Returns the diag nametag, as provided in the diaglist file. | |
243 | ||
244 | =item get_name() | |
245 | ||
246 | Returns the diag name which is the diag alias with :E<lt>nametagE<gt> | |
247 | appended. | |
248 | ||
249 | =item get_full_name() | |
250 | ||
251 | Returns the full diag name with alias, nametag, and group, separated | |
252 | by ':'. | |
253 | ||
254 | =item get_file() | |
255 | ||
256 | Returns the first file mentioned in the diag line. | |
257 | ||
258 | =item get_owner() | |
259 | ||
260 | Get debug owner form diag list. | |
261 | ||
262 | =item get_cmdline() | |
263 | ||
264 | Returns the command-line for the diag. This includes arguments | |
265 | specified in the DiagList::Group object that contains this object, | |
266 | followed by arguments specified on the diag command line. If the | |
267 | containing group happens to be a buildtag (i.e., has a | |
268 | sys=E<lt>somethingE<gt>), the sys=E<lt>somethingE<gt> is stripped out | |
269 | of the diag command-line. | |
270 | ||
271 | =item get_cmd_argv() | |
272 | ||
273 | This is the same as get_cmdline, except that it processes the | |
274 | command-line with a shell and returns a list that can be treated as an | |
275 | argv list. Using this instead of get_cmdline allows diaglist entries | |
276 | to be written the same way they would be on the command-line. | |
277 | ||
278 | =back | |
279 | ||
280 | =head2 Syntax of the Diaglist file | |
281 | ||
282 | The syntax of the Diaglist file is somewhat strange. It makes the | |
283 | most sense to describe how it evolved than to try to explain the | |
284 | entire syntax all at once. | |
285 | ||
286 | =head3 Diag Lines | |
287 | ||
288 | A diag line is a line in the diaglist that specifies a diag. Its syntax is: | |
289 | ||
290 | <alias> <args> | |
291 | ||
292 | Where E<lt>aliasE<gt> is a name for the diag, and E<lt>argsE<gt> are | |
293 | arguments to B<sims> used to run the diag. For instance: | |
294 | ||
295 | mydiag mydiag.s -max_cycle=300000 | |
296 | ||
297 | creates a diag alias "mydiag", which B<sims> will invoke as "mydiag.s | |
298 | -max_cycle=300000". One argument is special, however. If an argument | |
299 | is "debugowner=E<lt>usernameE<gt>", that argument is removed from the | |
300 | command-line before it is passed to B<sims>. The debugowner is | |
301 | available to clients of the DiagList module via the get_owner() | |
302 | function, but it is not part of the command line because there is | |
303 | nothing B<sims> to do with it at runtime. It is useful, however, for | |
304 | informing the B<diagstatus> database of who owns which diags. | |
305 | ||
306 | =head3 Groups | |
307 | ||
308 | The main organizational structure in the diaglist is a group. A group | |
309 | defines a list of diags for a regression and arguments to use for all | |
310 | diags in that regression. The syntax for a group is an XML-like tag. | |
311 | The definition can contain arguments. | |
312 | ||
313 | For example: | |
314 | ||
315 | <foo -foo1 -foo2> | |
316 | ||
317 | abc abc.s -abc | |
318 | def def.s -def | |
319 | ||
320 | </foo> | |
321 | ||
322 | This defines regression group named "foo". The arguments for the | |
323 | group are prepended to each diag command line. B<sims> uses | |
324 | Getopt::Long to parse its arguments, so if conflicting options are | |
325 | repeated on its command-line, the later option takes precedence. This | |
326 | means that diag-line options override group options if they are in | |
327 | conflict. If group foo were run in B<sims>, it would run a diag with | |
328 | alias "abc" and arguments "-foo1 -foo2 abc.s -abc" and an alias "def" | |
329 | with arguments "-foo1 -foo2 def.s -def". | |
330 | ||
331 | Groups can be opened multiple times, and they may have different | |
332 | arguments each time. Arguments are only used in the diags contained | |
333 | in that particular tag. For example: | |
334 | ||
335 | <foo -foo1 -foo2> | |
336 | ||
337 | abc abc.s -abc | |
338 | def def.s -def | |
339 | ||
340 | </foo> | |
341 | ||
342 | <foo -foo3> | |
343 | ||
344 | ghi ghi.s -ghi | |
345 | ||
346 | </foo> | |
347 | ||
348 | This would run "abc" and "def" exactly the same as before. The diag | |
349 | "ghi" would be run with "-foo3 ghi.s -ghi" and would not include | |
350 | "-foo1 or -foo2". | |
351 | ||
352 | Group definitions may nest, but this does B<not> imply any | |
353 | relationship between the groups. | |
354 | ||
355 | <foo -foo1> | |
356 | <bar -bar1> | |
357 | ||
358 | abc abc.s -abc | |
359 | ||
360 | </bar> | |
361 | </foo> | |
362 | ||
363 | This defines two different regressions, "foo" and "bar". In | |
364 | regression "foo", "abc" will have arguments "-foo1 abc.s -abc". In | |
365 | regression "bar", it will have arguments "-bar1 abc.s -abc". There is | |
366 | no notion of group "foo" containing group "bar" or anything like that. | |
367 | They just happen to have some diag lines in common. | |
368 | ||
369 | Note that this means that a diag alias by itself does not define a | |
370 | unique test (diag plus arguments). The alias/group combination is | |
371 | necessary, but not sufficient, to make a diag unique. More on that | |
372 | later. | |
373 | ||
374 | ||
375 | =head3 Nesting tags | |
376 | ||
377 | One special tag, E<lt>runargsE<gt> specifies arguments to all enclosed | |
378 | diags, regardless of their group. | |
379 | ||
380 | <runargs -runrun> | |
381 | <foo -foo1> | |
382 | <bar -bar1> | |
383 | ||
384 | abc abc.s -abc | |
385 | ||
386 | </bar> | |
387 | </foo> | |
388 | </runargs> | |
389 | ||
390 | This means that in group "foo", the diag "abc" will run as "-runrun | |
391 | -foo1 abc.s -abc" and in group "bar", it will be "-runrun -bar1 abc.s | |
392 | -abc". | |
393 | ||
394 | You can nest E<lt>runargsE<gt> tags. Inner tags will append to the | |
395 | argument list so inner E<lt>runargsE<gt> will override outer tags if | |
396 | any arguments are in conflict. Please note that a E<lt>runargsE<gt> | |
397 | tag does B<not> define a regression, so there is no group called | |
398 | "runargs". | |
399 | ||
400 | Another special tag that applies to all enclosed diags, regardless of | |
401 | their group, is E<lt>debugownerE<gt>. Just as described for the diag | |
402 | line, E<lt>debugownerE<gt> does not affect the command line at all, | |
403 | but it does provide information to the B<diagstatus> database about | |
404 | who owns which diags. | |
405 | ||
406 | <debugowner someuser> | |
407 | ||
408 | ... | |
409 | ||
410 | </debugowner> | |
411 | ||
412 | This is the same as having "debugowner=someuser" on every diag line in | |
413 | its scope. Note that if a diag line contains a "debugowner=..." and | |
414 | it is inside a E<lt>debugownerE<gt> tag, the diag line will take | |
415 | precedence. | |
416 | ||
417 | =head3 Special Groups | |
418 | ||
419 | There are two types of special groups, buildtags and nametags. They | |
420 | are syntacticaly just like any other groups, and they define | |
421 | regressions just like any other groups. They have special meanings | |
422 | and restrictions, however. | |
423 | ||
424 | =head4 Build Tags | |
425 | ||
426 | A buildtag is any group that has "sys=E<lt>sysnameE<gt>" in its | |
427 | argument list. (Note that all B<sims> options begin with '-', so any | |
428 | argument of the form "E<lt>nameE<gt>=E<lt>valueE<gt>" is an argument | |
429 | to the diaglist parser). | |
430 | ||
431 | A buildtag defines the model that should be built for the regression | |
432 | and the B<sims> options of how to build the model. | |
433 | ||
434 | <build1 sys=cmp -arg1 -arg2> | |
435 | ||
436 | ... | |
437 | ||
438 | </build1> | |
439 | ||
440 | This creates a buildtag called "build1" that specifies that all diags | |
441 | inside it should be run with the B<sims> "cmp" model, which can be | |
442 | built with "-arg1 -arg2". | |
443 | ||
444 | Unlike other groups, buildtags do B<not> nest. Each diag line must | |
445 | appear in B<exactly one> build tag. All diaglines in all groups | |
446 | inside the scope of the buildtag will be run on the specified model. | |
447 | ||
448 | <build1 sys=cmp -arg1 -arg2> | |
449 | <foo -foo1> | |
450 | <bar -bar1> | |
451 | mydiag mydiag.s -diag1 | |
452 | </bar> | |
453 | </foo> | |
454 | </build1> | |
455 | ||
456 | When you run regression "foo", it will build a cmp model with args | |
457 | "-arg1 -arg2". It will then run "mydiag" with arguments "-foo1 | |
458 | mydiag.s -diag1". Similarly, if you ran regression "bar", it would | |
459 | build the same cmp model and run "mydiag" with "-bar1 mydiag.s | |
460 | -diag1". Note that "-arg1" and "-arg2" are used at build time for | |
461 | groups "foo" and "bar", but they do not appear on the diag | |
462 | command-line during the run. | |
463 | ||
464 | A build tag also defines a regression, so you could run a regression | |
465 | "build1" with the above diaglist. It would build with "-arg1 -arg2" | |
466 | and would run "mydiag" with "-arg1 -arg2 mydiag.s -diag1". There is | |
467 | no way for the diaglist parser to tell build-time arguments from | |
468 | run-time arguments when a buildtag is used as a regression group. | |
469 | Fortunately, B<sims> will ignore run-time options at build time and | |
470 | vice-versa, so using buildtags as groups is perfectly legal. | |
471 | ||
472 | ||
473 | =head4 Name Tags | |
474 | ||
475 | An ambiguity is possible with multiple groups that contain diags with the same alias. For example: | |
476 | ||
477 | <both> | |
478 | ||
479 | <foo> | |
480 | <runargs -foo1> | |
481 | mydiag mydiag.s | |
482 | </runargs> | |
483 | </foo> | |
484 | ||
485 | ||
486 | <bar> | |
487 | <runargs -bar1> | |
488 | mydiag mydiag.s | |
489 | </runargs> | |
490 | </bar> | |
491 | ||
492 | </both> | |
493 | ||
494 | Note that we use E<lt>runargsE<gt> tags instead of putting them in the | |
495 | "foo" and "bar" regressions directly, since we want the "both" group | |
496 | to run "mydiag" once with "-foo1" and again with "-bar1". The problem | |
497 | with the above diaglist is that both runs of "mydiag" have the same | |
498 | alias/group combination when run in group "both". Some other | |
499 | identifier is needed to give each diag a unique name. | |
500 | ||
501 | Nametags are used for this purpose. A nametag is a group that has | |
502 | "name=E<lt>nameE<gt>" in its argument list. The name is appended to | |
503 | the alias do define a name that is unique within a group. The | |
504 | alias/nametag/group combination is enough to make a diag unique | |
505 | overall. As with buildtags, nametags do not nest, and each diag must | |
506 | appear in B<exactly one> nametag. We can rewrite the above diaglist | |
507 | as: | |
508 | ||
509 | ||
510 | <both> | |
511 | ||
512 | <foo_group name=foo> | |
513 | <runargs -foo1> | |
514 | mydiag mydiag.s | |
515 | </runargs> | |
516 | </foo> | |
517 | ||
518 | ||
519 | <bar_group name=bar> | |
520 | <runargs -bar1> | |
521 | mydiag mydiag.s | |
522 | </runargs> | |
523 | </bar> | |
524 | ||
525 | </both> | |
526 | ||
527 | Group "foo_group" contains the diag "mydiag:foo" with args "-foo1 | |
528 | mydiag.s". Group "bar_group" contains the diag "mydiag:bar" with args | |
529 | "-bar1 mydiag.s". Group "both" contains two diags: "mydiag:foo" with | |
530 | "-foo1 mydiag.s" and "mydiag:bar" with args "-bar1 mydiag.s". | |
531 | ||
532 | When B<sims> creates a directory to run a directory, it uses | |
533 | E<lt>aliasE<gt>:E<lt>nametagE<gt>:E<lt>groupE<gt> to get a unique | |
534 | directory name. In contexts where only a single group is relevant, | |
535 | then E<lt>aliasE<gt>:E<lt>nametagE<gt> is sufficent to name a diag. | |
536 | ||
537 | ||
538 | ||
539 | ||
540 | ||
541 | ||
542 | =head1 SEE ALSO | |
543 | ||
544 | sims(1). |