1# 2# Copyright (c) 2000, 2005 Oracle and/or its affiliates. All rights reserved. 3# 4 5# 6# test script for Sun::Solaris::Project 7# 8 9use warnings; 10use strict; 11use Data::Dumper; 12$Data::Dumper::Terse = 1; 13$Data::Dumper::Indent = 0; 14 15sub cleanup { 16 unlink("/tmp/project.$$.1"); 17 unlink("/tmp/project.$$.2"); 18 unlink("/tmp/project.$$.3"); 19 unlink("/tmp/project.$$.4"); 20 unlink("/tmp/project.$$.5"); 21 unlink("/tmp/project.$$.1.w"); 22 unlink("/tmp/project.$$.2.w"); 23 unlink("/tmp/project.$$.3.w"); 24 unlink("/tmp/project.$$.4.w"); 25 unlink("/tmp/project.$$.5.w"); 26 unlink("/tmp/projent.$$"); 27} 28 29# 'use Sun::Solaris::Project;' counts as test 1 30our $test = 1; 31our $intest = 1; 32our $loaded = 0; 33 34# 35# Status reporting utils 36# 37# Expected calling sequence is: 38# start() 39# pass() or fail() 40# start() 41# pass() or fail() 42# ... 43# ... 44# 45# Calling start() twice in a row will fail test. 46# Calling start() and then exiting will fail test. 47# 48sub start 49{ 50 if ($intest != 0) { 51 fatal("Started new test before finishing previous."); 52 } 53 $test++; 54 $intest = 1; 55 print "# Starting Test $test: @_\n" if (@_); 56} 57 58sub pass 59{ 60 if ($intest == 0) { 61 fatal("pass() without start()"); 62 } 63 print("ok $test @_\n"); 64 $intest = 0; 65} 66 67sub fail 68{ 69 if ($intest == 0) { 70 fatal("fail() without start()"); 71 } 72 print("not ok $test @_\n"); 73 $intest = 0; 74} 75 76sub fatal 77{ 78 print(STDERR "FATAL!\n"); 79 print("not ok $test @_\n"); 80 exit(1); 81} 82 83sub comment 84{ 85 print("# @_\n"); 86} 87 88# 89# Read in a project file and build into the same data structure that we will 90# get if we do the same with the getXXX functions 91# 92 93sub read_pfile 94{ 95 my ($fh) = @_; 96 my ($line, @a1, @a2); 97 while (defined($line = <$fh>)) { 98 chomp($line); 99 @a2 = split(/:/, $line, 6); 100 $a2[2] = '' if (! defined($a2[2])); 101 $a2[3] = defined($a2[3]) ? [ split(/,/, $a2[3]) ] : []; 102 $a2[4] = defined($a2[4]) ? [ split(/,/, $a2[4]) ] : []; 103 $a2[5] = '' if (! defined($a2[5])); 104 push(@a1, [ @a2 ]); 105 } 106 return(\@a1); 107} 108 109# 110# Compare two arrays of project structures & check for equivalence. 111# Converts each into a string using Data::Dumper and then does a string 112# comparison. Dirty but effective :-) 113# 114 115sub cmp_recs 116{ 117 my ($a1, $a2) = @_; 118 my $s1 = Dumper($a1); 119 my $s2 = Dumper($a2); 120 121 # Make sure numbers and quoted numbers compare the same 122 $s1 =~ s/'([+-]?[\d.]+)'/$1/g; 123 $s2 =~ s/'([+-]?[\d.]+)'/$1/g; 124 125 return($s1 eq $s2); 126} 127 128sub hash2string 129{ 130 my ($key, $value); 131 my @strings; 132 my $string; 133 my $hash = $_[0]; 134 foreach $key (keys(%$hash)) { 135 push(@strings, "$key => $hash->{$key}"); 136 } 137 $string = "{ " . join(", ", @strings) . " }"; 138 return ($string); 139} 140 141# 142# Main body of tests starts here. 143# 144 145# Check the module loads. 146BEGIN { 147 $| = 1; 148 print "1..548\n"; 149} 150 151END { 152 fail("not ok 1") unless ($loaded); 153 fail("Exited during test!") if ($intest == 1); 154 cleanup(); 155} 156 157use Sun::Solaris::Project qw(:ALL :PRIVATE); 158$loaded = 1; 159pass(); 160 161start("Check the constants."); 162my ($fh, $line, $n1, $n2, $n3, $s); 163open($fh, "</usr/include/project.h") || fatal($!); 164while (defined($line = <$fh>)) { 165 $n1 = $1 if ($line =~ /#define\s+PROJNAME_MAX\s+(\d+)/); 166 $n2 = $1 if ($line =~ /#define\s+PROJECT_BUFSZ\s+(\d+)/); 167 $s = $1 if ($line =~ /#define\s+PROJF_PATH\s+"([^"]+)"/); 168} 169close($fh); 170open($fh, "</usr/include/sys/param.h") || fatal($!); 171while (defined($line = <$fh>)) { 172 $n3 = $1 if ($line =~ /#define\s+MAXUID\s+(\d+)/); 173} 174close($fh); 175if (! defined($s) || ! defined($n1) || ! defined($n2)) { 176 fail(); 177} else { 178 if ($n1 == &PROJNAME_MAX && $n2 == &PROJECT_BUFSZ && 179 $n3 == &MAXPROJID && $s eq &PROJF_PATH) { 180 pass(); 181 } else { 182 fail(); 183 } 184} 185 186# 187# projf_read on various files with various flags. 188# 189# This table represents when projf_read should fail given a file 190# and flags. 191# 192# file/flags # {} validate validate,res validate,dup 193# ################################################################### 194# parse error # no no no no 195# dup names # yes no no no 196# dup ids # yes no no yes 197# system ids # yes no yes no 198# all user # yes yes yes yes 199# 200 201my $flags1 = {}; 202my $flags2 = { "validate" => "true" }; 203my $flags3 = { "validate" => "true", "res" => 1 }; 204my $flags4 = { "validate" => "true", "dup" => 1 }; 205 206# Make a temporary project files. 207my ($ret, $file1, $file2, $file3, $file4, $file5, $pass); 208 209# file1, parse error (extra ":") on group.staff project. 210open($file1, "+>/tmp/project.$$.1") || fatal($!); 211print $file1 <<EOF; 212test1:123:project one:root,bin:adm:attr1=a;attr2=b 213user.test2:456:project two:adm,uucp:staff:attr1=p;attr2=q 214group.test3:678:project three::root,nobody:root,lp:attr1=y;attr2=z 215test4:678:project four:root:root: 216test5:679:project five::sys: 217test6:690:::: 218EOF 219 220# file2, duplicate project names. 221open($file2, "+>/tmp/project.$$.2") || fatal($!); 222print $file2 <<EOF; 223test1:123:project one:root,bin:adm:attr1=a;attr2=b 224user.test2:456:project two:adm,uucp:staff:attr1=p;attr2=q 225group.test3:677:project three:root,nobody:root,lp:attr1=y;attr2=z 226test1:678:project four:root:root: 227test5:679:project five::sys: 228test6:690:::: 229EOF 230 231# file3, duplicate project ids. 232open($file3, "+>/tmp/project.$$.3") || fatal($!); 233print $file3 <<EOF; 234test1:123:project one:root,bin:adm:attr1=a;attr2=b 235user.test2:456:project two:adm,uucp:staff:attr1=p;attr2=q 236group.test3:677:project three:root,nobody:root,lp:attr1=y;attr2=z 237test4:678:project four:root:root: 238test5:678:project five::sys: 239test6:690:::: 240EOF 241 242# file4, system project ids. 243open($file4, "+>/tmp/project.$$.4") || fatal($!); 244print $file4 <<EOF; 245system:0:::: 246user.root:1:::: 247noproject:2:::: 248default:3:::: 249group.staff:10:::: 250test1:123:project one:root,bin:adm:attr1=a;attr2=b 251user.test2:456:project two:adm,uucp:staff:attr1=p;attr2=q 252group.test3:677:project three:root,nobody:root,lp:attr1=y;attr2=z 253test4:678:project four:root:root: 254test5:679:project five::sys: 255test6:690:::: 256EOF 257 258# file5, all unique user projects. 259open($file5, "+>/tmp/project.$$.5") || fatal($!); 260print $file5 <<EOF; 261test1:123:project one:root,bin:adm:attr1=a;attr2=b 262user.test2:456:project two:adm,uucp:staff:attr1=p;attr2=q 263group.test3:677:project three:root,nobody:root,lp:attr1=y;attr2=z 264test4:678:project four:root:root: 265test5:679:project five::sys: 266test6:690:::: 267EOF 268 269# 270# Each test is the file description, input file, filename, flags, and the expected 271# return value. 272# 273my @read_tests = ( 274 [ "parse error", $file1, "/tmp/project.$$.1", $flags1, 1 ], 275 [ "parse error", $file1, "/tmp/project.$$.1", $flags2, 1 ], 276 [ "parse error", $file1, "/tmp/project.$$.1", $flags3, 1 ], 277 [ "parse error", $file1, "/tmp/project.$$.1", $flags4, 1 ], 278 [ "dup names", $file2, "/tmp/project.$$.2", $flags1, 0 ], 279 [ "dup names", $file2, "/tmp/project.$$.2", $flags2, 1 ], 280 [ "dup names", $file2, "/tmp/project.$$.2", $flags3, 1 ], 281 [ "dup names", $file2, "/tmp/project.$$.2", $flags4, 1 ], 282 [ "dup ids", $file3, "/tmp/project.$$.3", $flags1, 0 ], 283 [ "dup ids", $file3, "/tmp/project.$$.3", $flags2, 1 ], 284 [ "dup ids", $file3, "/tmp/project.$$.3", $flags3, 1 ], 285 [ "dup ids", $file3, "/tmp/project.$$.3", $flags4, 0 ], 286 [ "sys ids", $file4, "/tmp/project.$$.4", $flags1, 0 ], 287 [ "sys ids", $file4, "/tmp/project.$$.4", $flags2, 1 ], 288 [ "sys ids", $file4, "/tmp/project.$$.4", $flags3, 0 ], 289 [ "sys ids", $file4, "/tmp/project.$$.4", $flags4, 1 ], 290 [ "unique users", $file5, "/tmp/project.$$.5", $flags1, 0 ], 291 [ "unique users", $file5, "/tmp/project.$$.5", $flags2, 0 ], 292 [ "unique users", $file5, "/tmp/project.$$.5", $flags3, 0 ], 293 [ "unique users", $file5, "/tmp/project.$$.5", $flags4, 0 ] 294); 295 296my $projents; 297my @goodprojents; 298my $read_test; 299my $desc; 300my $file; 301my $filename; 302my $flags; 303my $flagstring; 304my $exp; 305my $error; 306 307# Do projf_read tests. 308foreach $read_test (@read_tests) { 309 310 ($desc, $file, $filename, $flags, $exp) = @$read_test; 311 $flagstring = hash2string($flags); 312 start("projf_read(): $desc, flags: $flagstring, file: $filename"); 313 314 seek($file, 0, 0); 315 316 ($ret, $projents) = projf_read($file, $flags); 317 # check return is expected result 318 if ($ret != $exp) { 319 fail("Expected $exp, Returned $ret"); 320 if ($ret) { 321 foreach $error (@$projents) { 322 comment("# " . join(", ", @$error));; 323 } 324 } 325 next; 326 } 327 # verify either projents or error messages were returned 328 if (!(@$projents)) { 329 fail("Missing projents or error messages"); 330 next; 331 } 332 pass(); 333 334 # Save projents from successful reads for testing projf_write. 335 if ($ret == 0) { 336 push(@goodprojents, [$desc, $flags, $projents, $filename]); 337 } 338} 339 340close($file1); 341close($file2); 342close($file3); 343close($file4); 344close($file5); 345 346# Test projf_write, write each successfully read file. 347 348my @write_tests; 349my $write_test; 350 351foreach $write_test (@goodprojents) { 352 353 ($desc, $flags, $projents, $filename) = @$write_test; 354 $flagstring = hash2string($flags); 355 start("projf_write(): $desc, flags: $flagstring, file: $filename"); 356 357 open($fh, ">$filename.w") || fatal($!); 358 359 projf_write($fh, $projents); 360 close($fh); 361 system("cmp -s $filename $filename.w") == 0 ? pass() : 362 fail("Written file $filename.w does not match file $filename"); 363} 364 365# Tests for projent_parse and projent_validate. 366 367my @projent_tests; 368my $projent_test; 369 370# 371# Tests, in format: 372# 373# [ parse_result_expected, validate_result_expected, flags, project-line ] 374# 375@projent_tests = ( 376 377# positive 378 379 [ 0, 0, { "res" => 1 }, "system:0::::" ], 380 [ 0, 0, { "res" => 1 }, "user.root:1::::" ], 381 [ 0, 0, { "res" => 1 }, "noproject:2::::" ], 382 [ 0, 0, { "res" => 1 }, "default:3::::" ], 383 [ 0, 0, { "res" => 1 }, "group.staff:10::::" ], 384 [ 0, 0, {}, "long:100::::" . "a" x 2048 ], 385 [ 0, 0, {}, "Validname:101::::" ], 386 [ 0, 0, {}, "Validname2:102::::" ], 387 [ 0, 0, {}, "valid3name:103::::" ], 388 [ 0, 0, {}, "VALIDNAME:104::::" ], 389 [ 0, 0, {}, "VALIDNAME5:105::::" ], 390 [ 0, 0, {}, "vAlid5name:106::::" ], 391 [ 0, 0, {}, "valid.name:107::::" ], 392 [ 0, 0, {}, "valid8.NAME:108::::" ], 393 [ 0, 0, {}, "Valid_name9:109::::" ], 394 [ 0, 0, {}, "V_alid.name10:110::::" ], 395 [ 0, 0, {}, "valid12345678901234567890123456789012345678901234567890123456789:111::::" ], 396 [ 0, 0, {}, "projid:2147483647::::" ], 397 [ 0, 0, {}, "comment:111: this is ! & my crazy !@#$%^&*()_+|~`\=-][ 0, 0, {},}{';\"/.,?>< comment:::" ], 398 [ 0, 0, {}, "user1:112::*::" ], 399 [ 0, 0, {}, "user2:113::!*::" ], 400 [ 0, 0, {}, "user3:114::root::" ], 401 [ 0, 0, {}, "user4:115::!root::" ], 402 [ 0, 0, {}, "user5:116::*,!sys::" ], 403 [ 0, 0, {}, "user6:117::!*,daemon::" ], 404 [ 0, 0, {}, "user7:118::root,sys,daemon,bin::" ], 405 [ 0, 0, {}, "user8:119::root,!sys,daemon,!bin::" ], 406 [ 0, 0, { "allowspaces" => 1 }, "user9:116::*, !sys::" ], 407 [ 0, 0, { "allowspaces" => 1 }, "user10:117::!* ,daemon::" ], 408 [ 0, 0, { "allowspaces" => 1 }, "user11:118::root ,sys ,daemon, bin::" ], 409 [ 0, 0, { "allowspaces" => 1 }, "user12:119::root, !sys, daemon ,!bin::" ], 410 [ 0, 0, {}, "group1:120:::*:" ], 411 [ 0, 0, {}, "group2:121:::!*:" ], 412 [ 0, 0, {}, "group3:122:::root:" ], 413 [ 0, 0, {}, "group4:123:::!root:" ], 414 [ 0, 0, {}, "group5:124:::*,!sys:" ], 415 [ 0, 0, {}, "group6:125:::!*,daemon:" ], 416 [ 0, 0, {}, "group7:126:::root,sys,daemon,bin:" ], 417 [ 0, 0, {}, "group8:127:::root,!sys,daemon,!bin:" ], 418 [ 0, 0, { "allowspaces" => 1 }, "group9:124:::*, !sys:" ], 419 [ 0, 0, { "allowspaces" => 1 }, "group10:125:::!* ,daemon:" ], 420 [ 0, 0, { "allowspaces" => 1 }, "group11:126:::root, sys ,daemon, bin:" ], 421 [ 0, 0, { "allowspaces" => 1 }, "group12:127:::root ,!sys, daemon ,!bin:" ], 422 [ 0, 0, {}, "group9:128:::sys:" ], 423 [ 0, 0, {}, "attrib1:129::::one" ], 424 [ 0, 0, {}, "attrib2:130::::One" ], 425 [ 0, 0, {}, "attrib3:131::::ONE" ], 426 [ 0, 0, {}, "attrib4:132::::attrib10" ], 427 [ 0, 0, {}, "attrib5:133::::attrib.attrib=" ], 428 [ 0, 0, {}, "attrib6:134::::attib_" ], 429 [ 0, 0, {}, "attrib7:135::::a10-._attib" ], 430 [ 0, 0, {}, "attrib8:136::::SUNW,attrib" ], 431 [ 0, 0, {}, "attrib9:137::::A,A10=" ], 432 [ 0, 0, {}, "attrib10:138::::FIVEE,name" ], 433 [ 0, 0, {}, "attrib11:139::::one;two" ], 434 [ 0, 0, {}, "attrib12:140::::one=1;two=four" ], 435 [ 0, 0, {}, "attrib13:141::::one;two=;three=four" ], 436 [ 0, 0, {}, "value1:142::::one=foo,bar" ], 437 [ 0, 0, {}, "value2:143::::one=,bar," ], 438 [ 0, 0, {}, "value3:144::::one=(foo,bar)" ], 439 [ 0, 0, {}, "value4:145::::one=(foo,bar,baz),boo" ], 440 [ 0, 0, {}, "value5:146::::one;two=bar,(baz),foo,((baz)),(,)" ], 441 [ 0, 0, {}, "value6:147::::one=100/200" ], 442 [ 0, 0, {}, "value7:148::::two=.-_/=" ], 443 [ 0, 0, {}, "value8:149::::name=one=two" ], 444 [ 0, 0, { "allowunits" => 1 }, "value9:150::::task.max-lwps=(priv,1000M,deny,signal=SIGHUP),(priv,1000k,deny,signal=SIGKILL)" ], 445 [ 0, 0, {}, "comma1:151::,::" ], 446 [ 0, 0, {}, "comma2:152::,,::" ], 447 [ 0, 0, {}, "comma3:153::root,::" ], 448 [ 0, 0, {}, "comma4:154::bin,root,,::" ], 449 [ 0, 0, {}, "comma5:155:::,:" ], 450 [ 0, 0, {}, "comma6:156:::,,:" ], 451 [ 0, 0, {}, "comma7:157:::bin,root,:" ], 452 [ 0, 0, {}, "comma8:158:::root,,:" ], 453 [ 0, 0, {}, "semi1:159::::;" ], 454 [ 0, 0, {}, "semi2:160::::;;" ], 455 [ 0, 0, {}, "semi3:161::::foo=(one,two);" ], 456 [ 0, 0, {}, "semi4:162::::foo;;" ], 457 [ 0, 0, { "allowunits" => 1 }, "rctl1:163::::task.max-lwps=(priv,1000,deny,signal=HUP),(priv,1000k,deny,signal=15)" ], 458 [ 0, 0, {}, "rctl1:163::::task.max-lwps=(priv,1000,deny,signal=HUP),(priv,10001,deny,signal=15)" ], 459 [ 0, 0, {}, "rctl2:164::::process.max-port-events=(basic,1000,deny)" ], 460 [ 0, 0, { "allowunits" => 1 }, "rctl3:165::::project.max-crypto-memory=(priv,2.2gb,deny)" ], 461 [ 0, 0, {}, "rctl3:165::::project.max-crypto-memory=(priv,10,deny)" ], 462 [ 0, 0, { "allowunits" => 1 }, "rctl4:166::::project.max-crypto-memory=(privileged,100m,deny)" ], 463 [ 0, 0, {}, "rctl4:166::::project.max-crypto-memory=(privileged,100,deny)" ], 464 [ 0, 0, { "allowunits" => 1 }, "rctl5:167::::project.max-crypto-memory=(priv,1000m,deny)" ], 465 [ 0, 0, {}, "rctl5:167::::project.max-crypto-memory=(priv,1000,deny)" ], 466 [ 0, 0, { "allowunits" => 1 }, "rctl6:168::::project.max-crypto-memory=(priv,1000k,deny)" ], 467 [ 0, 0, { "allowunits" => 1 }, "rctl6:168::::project.max-crypto-memory=(priv,1000m,deny)" ], 468 [ 0, 0, {}, "rctl7:169::::process.max-msg-messages=(priv,10,deny)" ], 469 [ 0, 0, { "allowunits" => 1 }, "rctl8:170::::process.max-msg-qbytes=(priv,10000kb,deny)" ], 470 [ 0, 0, {}, "rctl8:170::::process.max-msg-qbytes=(priv,10000,deny)" ], 471 [ 0, 0, {}, "rctl9:171::::process.max-sem-ops=(priv,10000000,deny)" ], 472 [ 0, 0, {}, "rctl10:172::::process.max-sem-nsems=(basic,1,deny)" ], 473 [ 0, 0, { "allowunits" => 1 }, "rctl11:173::::process.max-address-space=(priv,2GB,deny)" ], 474 [ 0, 0, { "allowunits" => 1 }, "rctl12:174::::process.max-file-descriptor=(basic,1K,deny),(basic,2K,deny)" ], 475 [ 0, 0, { "allowunits" => 1 }, "rctl13:175::::process.max-core-size=(priv,10Mb,deny),(priv,2GB,deny)" ], 476 [ 0, 0, { "allowunits" => 1 }, "rctl14:176::::process.max-stack-size=(priv,1.8Gb,deny),(priv,100MB,deny)" ], 477 [ 0, 0, {}, "rctl15:177::::process.max-data-size=(priv,1010100101,deny)" ], 478 [ 0, 0, { "allowunits" => 1 }, "rctl16:178::::process.max-file-size=(priv,100mb,deny,signal=SIGXFSZ),(priv,1000mb,deny,signal=31)" ], 479 [ 0, 0, { "allowunits" => 1 }, "rctl17:179::::process.max-cpu-time=(priv,1t,signal=XCPU),(priv,100ms,sig=30)" ], 480 [ 0, 0, { "allowunits" => 1 }, "rctl18:180::::task.max-cpu-time=(priv,1M,sig=SIGKILL)" ], 481 [ 0, 0, { "allowunits" => 1 }, "rctl19:181::::task.max-lwps=(basic,10,signal=1),(priv,100,deny,signal=KILL)" ], 482 [ 0, 0, {}, "rctl20:182::::project.max-device-locked-memory=(priv,1000,deny,sig=TERM)" ], 483 [ 0, 0, {}, "rctl21:183::::project.max-port-ids=(priv,100,deny)" ], 484 [ 0, 0, { "allowunits" => 1 }, "rctl22:184::::project.max-shm-memory=(priv,1000mb,deny)" ], 485 [ 0, 0, { "allowunits" => 1 }, "rctl23:185::::project.max-shm-ids=(priv,1k,deny,signal=SIGSTOP)" ], 486 [ 0, 0, { "allowunits" => 1 }, "rctl24:186::::project.max-msg-ids=(priv,1m,deny,signal=XRES)" ], 487 [ 0, 0, {}, "rctl25:187::::project.max-sem-ids=(priv,10,deny,signal=ABRT)" ], 488 [ 0, 0, { "allowunits" => 1 }, "rctl26:188::::project.cpu-shares=(priv,63k,none)" ], 489 [ 0, 0, { "allowunits" => 1 }, "rctl27:189::::zone.cpu-shares=(priv,20k,none)" ], 490 [ 0, 0, {}, "rctl28:190::::zone.cpu-shares=(priv,100,none)" ], 491 [ 0, 0, { "allowunits" => 1 }, "rctl29:191::::project.max-shm-memory=(priv,200G,deny)" ], 492 [ 0, 0, { "allowunits" => 1 }, "rctl30:192::::project.max-shm-memory=(priv,200Gb,deny)" ], 493 [ 0, 0, { "allowunits" => 1 }, "rctl31:193::::project.max-shm-memory=(priv,2000B,deny)" ], 494 [ 0, 0, {}, "rctl32:194::::project.max-shm-memory=(priv,2000,deny)" ], 495 [ 0, 0, {}, "rctl33:195::::task.max-cpu-time=(priv,2000,none)" ], 496 [ 0, 0, { "allowunits" => 1 }, "rctl34:196::::task.max-cpu-time=(priv,2000s,none)" ], 497 [ 0, 0, { "allowunits" => 1 }, "rctl35:197::::task.max-cpu-time=(priv,20.1ps,none)" ], 498 [ 0, 0, { "allowunits" => 1 }, "rctl36:198::::task.max-cpu-time=(priv,20T,none)" ], 499 500# negative 501 502 [ 0, 1, {}, "system:0::::" ], 503 [ 0, 1, {}, "user.root:1::::" ], 504 [ 0, 1, {}, "noproject:2::::" ], 505 [ 0, 1, {}, "default:3::::" ], 506 [ 0, 1, {}, "group.staff:10::::" ], 507 [ 0, 1, {}, "long:100::::" . "a" x 4096 ], 508 [ 1, 0, {}, "extrafields:101:::::" ], 509 [ 1, 0, {}, "missingfields:102:::" ], 510 [ 1, 0, {}, "_invalidname:103::::" ], 511 [ 1, 0, {}, "10invlidname:104::::" ], 512 [ 1, 0, {}, "invalid%name:105::::" ], 513 [ 1, 0, {}, "invalid/name:106::::" ], 514 [ 1, 0, {}, ".invalidname:107::::" ], 515 [ 1, 0, {}, "=invalidName:108::::" ], 516 [ 1, 0, {}, "invalid=name:109::::" ], 517 [ 1, 0, {}, "invalid/name:110::::" ], 518 [ 1, 0, {}, "/invalidname:111::::" ], 519 [ 1, 0, {}, "/invalidname:112::::" ], 520 [ 1, 0, {}, "invalidname*:113::::" ], 521 [ 1, 0, {}, "invalid?name:114::::" ], 522 [ 1, 0, {}, ":115:invalid name comment:::" ], 523 [ 1, 0, {}, "invalid!name:116::::" ], 524 [ 1, 0, {}, "invalidname!:117::::" ], 525 [ 1, 0, {}, "invalid12345678901234567890123456789012345678901234567890123456789:118::::" ], 526 [ 1, 0, {}, "projid:-1::::" ], 527 [ 1, 0, {}, "projid:abc::::" ], 528 [ 1, 0, {}, "projid:2147483648::::" ], 529 [ 1, 0, {}, "projid:::::" ], 530 [ 1, 0, {}, "user1:118::*!::" ], 531 [ 1, 0, {}, "user2:119::10user::" ], 532 [ 0, 1, {}, "user3:120::NOLOWER::" ], 533 [ 0, 1, {}, "user4:121::toooolong::" ], 534 [ 1, 0, {}, "user5:122::root!::" ], 535 [ 1, 0, {}, "user6:123::root;sys::" ], 536 [ 0, 1, {}, "user7:124::sys,NOLOWER::" ], 537 [ 1, 0, {}, "user8:125::sys/bin,root::" ], 538 [ 1, 0, {}, "user9:116::*, !sys::" ], 539 [ 1, 0, {}, "user10:117::!* ,daemon::" ], 540 [ 1, 0, {}, "user11:118::root ,sys ,daemon, bin::" ], 541 [ 1, 0, {}, "user12:119::root, !sys, daemon ,!bin::" ], 542 [ 1, 0, {}, "group1:126:::*!:" ], 543 [ 0, 1, {}, "group2:127:::oneUpper:" ], 544 [ 0, 1, {}, "group3:128:::NOLOWER:" ], 545 [ 0, 1, {}, "group4:129:::toooolong:" ], 546 [ 1, 0, {}, "group5:130:::root!:" ], 547 [ 1, 0, {}, "group6:131:::root;sys:" ], 548 [ 0, 1, {}, "group7:132:::sys,NOLOWER:" ], 549 [ 1, 0, {}, "group8:133:::sys-bin,root:" ], 550 [ 1, 0, {}, "group9:124:::*, !sys:" ], 551 [ 1, 0, {}, "group10:125:::!* ,daemon:" ], 552 [ 1, 0, {}, "group11:126:::root, sys ,daemon, bin:" ], 553 [ 1, 0, {}, "group12:127:::root ,!sys, daemon ,!bin:" ], 554 [ 1, 0, {}, "attrib1:134::::10" ], 555 [ 1, 0, {}, "attrib2:135::::_foo=" ], 556 [ 1, 0, {}, "attrib3:136::::,foo" ], 557 [ 1, 0, {}, "attrib4:137::::sun,foo" ], 558 [ 1, 0, {}, "attrib6:139::::!attrib" ], 559 [ 1, 0, {}, "attrib7:140::::_attrib" ], 560 [ 1, 0, {}, "attrib8:141::::attib,attrib" ], 561 [ 1, 0, {}, "attrib9:142::::attrib/attrib" ], 562 [ 1, 0, {}, "attrib10:143::::one;two,three" ], 563 [ 1, 0, {}, "attrib11:144::::one=two;three/" ], 564 [ 1, 0, {}, "value1:145::::one=foo%" ], 565 [ 1, 0, {}, "value2:146::::one= two" ], 566 [ 1, 0, {}, "value3:147::::var=foo?" ], 567 [ 1, 0, {}, "value4:148::::name=value;name=value2)" ], 568 [ 1, 0, {}, "value5:149::::(foo)" ], 569 [ 1, 0, {}, "value6:150::::name=(foo,bar" ], 570 [ 1, 0, {}, "value7:151::::name=(value)(value)" ], 571 [ 1, 0, {}, "value8:152::::name=)" ], 572 [ 1, 0, {}, "value9:153::::name=value,(value value)" ], 573 [ 1, 0, {}, "value10:154::::name=(value(value))" ], 574 [ 1, 0, {}, "value11:155::::name=(value)value" ], 575 [ 1, 0, {}, "value11:156::::name=va?lue" ], 576 [ 1, 0, {}, "value12:157::::name=(value,value))" ], 577 [ 1, 0, {}, "value13:158::::name=(value),value)" ], 578 [ 1, 0, {}, "space1 :159::::" ], 579 [ 1, 0, {}, " space2:160::::" ], 580 [ 1, 0, {}, "space3: 161::::" ], 581 [ 1, 0, {}, "space4:162 ::::" ], 582 [ 1, 0, {}, "space 5:163::::" ], 583 [ 1, 0, {}, "space6:1 64::::" ], 584 [ 1, 0, {}, "space7:165:: root::" ], 585 [ 1, 0, {}, "space8:166::root ::" ], 586 [ 1, 0, {}, "space9:167::daemon, root::" ], 587 [ 1, 0, {}, "space10:168::bin root::" ], 588 [ 1, 0, {}, "space11:169::daemon ,root::" ], 589 [ 1, 0, {}, "space12 :170::::" ], 590 [ 1, 0, {}, " space13:171::::" ], 591 [ 1, 0, {}, "space14: 172::::" ], 592 [ 1, 0, {}, "space15:173 ::::" ], 593 [ 1, 0, {}, "space 16:174::::" ], 594 [ 1, 0, {}, "space17:1 75::::" ], 595 [ 1, 0, {}, "space18:176::: root:" ], 596 [ 1, 0, {}, "space19:177:::root :" ], 597 [ 1, 0, {}, "space20:178:::daemon, root:" ], 598 [ 1, 0, {}, "space21:179:::bin root:" ], 599 [ 1, 0, {}, "space22:180:::daemon ,root:" ], 600 [ 1, 0, {}, "space23:181:::: foo" ], 601 [ 1, 0, {}, "space34:182::::foo =one" ], 602 [ 1, 0, {}, "space35:183::::foo= (one)" ], 603 [ 1, 0, {}, "space36:184::::foo=(one, two)" ], 604 [ 1, 0, {}, "space37:185::::foo=(one ,two)" ], 605 [ 1, 0, {}, "space38:186::::foo=( one)" ], 606 [ 1, 0, {}, "space39:187::::foo=(one )" ], 607 [ 1, 0, {}, "space40:188::::foo=(one) ,two" ], 608 [ 1, 0, {}, "space41:189::::foo=one, (two)" ], 609 [ 1, 0, {}, "comma1:190::,root,bin::" ], 610 [ 1, 0, {}, "comma2:191::root,,bin::" ], 611 [ 1, 0, {}, "comma3:192::,,root,bin::" ], 612 [ 1, 0, {}, "comma4:193:::,root,bin:" ], 613 [ 1, 0, {}, "comma5:194:::root,,bin:" ], 614 [ 1, 0, {}, "comma6:195:::,,root,bin:" ], 615 [ 1, 0, {}, "semi1:196::::;foo" ], 616 [ 1, 0, {}, "semi2:197::::foo;;bar=1" ], 617 [ 1, 0, {}, "semi3:198::::;;bar=(10)" ], 618 [ 0, 1, {}, "rctl1:199::::task.max-lwps=," ], 619 [ 0, 1, {}, "rctl2:200::::task.max-lwps=" ], 620 [ 0, 1, {}, "rctl3:201::::task.max-lwps=priv" ], 621 [ 0, 1, {}, "rctl4:202::::task.max-lwps=priv,1000" ], 622 [ 0, 1, {}, "rctl5:203::::task.max-lwps=priv,1000,deny" ], 623 [ 0, 1, {}, "rctl6:204::::task.max-lwps=(priv)" ], 624 [ 0, 1, {}, "rctl7:205::::task.max-lwps=(priv,1000)" ], 625 [ 0, 1, {}, "rctl8:206::::task.max-lwps=(foo,100,deny)" ], 626 [ 0, 1, {}, "rctl9:207::::task.max-lwps=(priv,foo,none)" ], 627 [ 1, 0, { "allowunits" => 1 }, "rctl9:207::::task.max-lwps=(priv,foo,none)" ], 628 [ 1, 0, { "allowunits" => 1 }, "rctl10:208::::task.max-lwps=(priv,100foo,none)" ], 629 [ 0, 1, {}, "rctl11:209::::task.max-lwps=(priv,1000,foo)" ], 630 [ 0, 1, { "allowunits" => 1 }, "rctl12:210::::task.max-lwps=(priv,1000k,deny,signal)" ], 631 [ 0, 1, {}, "rctl13:211::::task.max-lwps=(priv,1000,deny,signal=)" ], 632 [ 0, 1, {}, "rctl14:212::::task.max-lwps=(priv,1000,deny,signal=foo)" ], 633 [ 0, 1, {}, "rctl15:213::::task.max-lwps=(priv,1000,deny,signal=1fo)" ], 634 [ 0, 1, {}, "rctl16:214::::task.max-lwps=(priv,1000,deny,signal=100)" ], 635 [ 0, 1, {}, "rctl17:215::::task.max-lwps=(priv,1000,deny,signal=SIG)" ], 636 [ 0, 1, {}, "rctl18:216::::task.max-lwps=(priv,1000,deny,signal=SIG1)" ], 637 [ 0, 1, {}, "rctl19:217::::task.max-lwps=(priv,1000,deny,signal=SIGhup)" ], 638 [ 0, 1, {}, "rctl20:218::::task.max-lwps=(priv,1000,deny,signal=SIGHU)" ], 639 [ 0, 1, {}, "rctl21:219::::task.max-lwps=(priv,1000,deny,signal=SIGHUPP)" ], 640 [ 0, 1, {}, "rctl22:220::::task.max-lwps=(priv,1000,deny,signal=SIGURG)" ], 641 [ 0, 1, {}, "rctl23:221::::task.max-lwps=(priv,1000,deny,signal=SIGXCPU)" ], 642 [ 0, 1, {}, "rctl24:222::::task.max-lwps=(priv,1000,deny,signal=SIGKILL,10)" ], 643 [ 0, 1, {}, "rctl25:223::::task.max-lwps=(priv,1000,deny,signal=SIGKILL,foo)" ], 644 [ 0, 1, {}, "rctl26:224::::process.max-port-events=(priv,1000,none)" ], 645 [ 0, 1, { "allowunits" => 1 }, "rctl27:225::::process.max-address-space=(basic,1024mb,deny,signal=TERM)" ], 646 [ 0, 1, {}, "rctl28:226::::process.max-cpu-time=(basic,3600,deny)" ], 647 [ 0, 1, {}, "rctl29:227::::task.max-lwps=()" ], 648 [ 0, 1, {}, "rctl30:228::::task.max-lwps=((priv),deny)" ], 649 [ 0, 1, {}, "rctl31:229::::task.max-lwps=((priv,1000,deny))" ], 650 [ 0, 1, {}, "rctl32:230::::task.max-lwps=(priv,((1000,2000,1000)),deny)" ], 651 [ 0, 1, {}, "rctl33:231::::task.max-lwps=(,,,)" ], 652 [ 0, 1, {}, "rctl34:232::::task.max-lwps=(priv,1000,(deny))" ], 653 [ 0, 1, {}, "rctl35:233::::task.max-lwps=(priv,1000,deny),foo" ], 654 [ 0, 1, {}, "rctl36:234::::task.max-lwps=(priv,1000,deny),(priv,1000)" ], 655 [ 1, 0, { "allowunits" => 1 }, "rctl37:235::::project.max-msg-ids=(priv,15EB,deny)" ], 656 [ 1, 0, { "allowunits" => 1 }, "rctl38:236::::process.max-address-space=(priv,16.1EB,deny)" ], 657 [ 1, 0, { "allowunits" => 1 }, "rctl39:237::::process.max-address-space=(priv,18000000000gb,deny)" ], 658 [ 1, 0, { "allowunits" => 1 }, "rctl40:238::::zone.cpu-shares=(priv,10kb,none)" ], 659 [ 1, 0, { "allowunits" => 1 }, "rctl41:239::::zone.cpu-shares=(priv,10Ks,none)" ], 660 [ 1, 0, { "allowunits" => 1 }, "rctl42:240::::zone.cpu-shares=(priv,10s,none)" ], 661 [ 1, 0, { "allowunits" => 1 }, "rctl43:241::::zone.cpu-shares=(priv,100000b,none)" ], 662 [ 1, 0, { "allowunits" => 1 }, "rctl44:242::::project.max-shm-memory=(priv,200Ts,deny)" ], 663 [ 1, 0, { "allowunits" => 1 }, "rctl45:243::::project.max-shm-memory=(priv,200s,deny)" ], 664 [ 1, 0, { "allowunits" => 1 }, "rctl46:244::::task.max-cpu-time=(priv,20B,none)" ], 665 [ 1, 0, { "allowunits" => 1 }, "rctl47:245::::task.max-cpu-time=(priv,20Kb,none)" ], 666 [ 0, 1, { "allowunits" => 1 }, "rctl48:246::::project.cpu-shares=(priv,100k,none)" ], 667 [ 0, 1, {}, "rctl147:150::::task.max-lwps=(priv,1000M,deny,signal=SIGHUP),(priv,1000k,deny,signal=SIGKILL)" ], 668 [ 0, 1, {}, "rctl148:163::::task.max-lwps=(priv,1000,deny,signal=HUP),(priv,1000k,deny,signal=15)" ], 669 [ 0, 1, {}, "rctl3:165::::project.max-crypto-memory=(priv,10eb,deny)" ], 670 [ 0, 1, {}, "rctl4:166::::project.max-crypto-memory=(privileged,100p,deny)" ], 671 [ 0, 1, {}, "rctl5:167::::project.max-crypto-memory=(priv,1000t,deny)" ], 672 [ 0, 1, {}, "rctl6:168::::project.max-crypto-memory=(priv,1000g,deny)" ], 673 [ 0, 1, {}, "rctl7:169::::process.max-msg-messages=(priv,10m,deny)" ], 674 [ 0, 1, {}, "rctl8:170::::process.max-msg-qbytes=(priv,10000kb,deny)" ], 675 [ 0, 1, {}, "rctl11:173::::process.max-address-space=(priv,10EB,deny)" ], 676 [ 0, 1, {}, "rctl12:174::::process.max-file-descriptor=(basic,1K,deny),(basic,2K,deny)" ], 677 [ 0, 1, {}, "rctl13:175::::process.max-core-size=(priv,1Eb,deny),(priv,10PB,deny)" ], 678 [ 0, 1, {}, "rctl14:176::::process.max-stack-size=(priv,10Tb,deny),(priv,10TB,deny)" ], 679 [ 0, 1, {}, "rctl16:178::::process.max-file-size=(priv,100mb,deny,signal=SIGXFSZ),(priv,1000mb,deny,signal=31)" ], 680 [ 0, 1, {}, "rctl17:179::::process.max-cpu-time=(priv,1t,signal=XCPU),(priv,100ms,sig=30)" ], 681 [ 0, 1, {}, "rctl18:180::::task.max-cpu-time=(priv,1M,sig=SIGKILL)" ], 682 [ 0, 1, {}, "rctl22:184::::project.max-shm-memory=(priv,1000mb,deny)" ], 683 [ 0, 1, {}, "rctl23:185::::project.max-shm-ids=(priv,1k,deny,signal=SIGSTOP)" ], 684 [ 0, 1, {}, "rctl24:186::::project.max-msg-ids=(priv,1m,deny,signal=XRES)" ], 685 [ 0, 1, {}, "rctl26:188::::project.cpu-shares=(priv,63k,none)" ], 686 [ 0, 1, {}, "rctl27:189::::zone.cpu-shares=(priv,20k,none)" ], 687 [ 0, 1, {}, "rctl29:191::::project.max-shm-memory=(priv,200G,deny)" ], 688 [ 0, 1, {}, "rctl30:192::::project.max-shm-memory=(priv,200Gb,deny)" ], 689 [ 0, 1, {}, "rctl31:193::::project.max-shm-memory=(priv,2000B,deny)" ], 690 [ 0, 1, {}, "rctl34:196::::task.max-cpu-time=(priv,2000s,none)" ], 691 [ 0, 1, {}, "rctl35:197::::task.max-cpu-time=(priv,20.1ps,none)" ], 692 [ 0, 1, {}, "rctl36:198::::task.max-cpu-time=(priv,20T,none)" ], 693); 694 695my $parse_exp; 696my $parse_ret; 697my $validate_exp; 698my $validate_ret; 699my $project; 700my $projent; 701my $errors; 702 703foreach $projent_test ( @projent_tests) { 704 705 ($parse_exp, $validate_exp, $flags, $project) = @$projent_test; 706 $flagstring = hash2string($flags); 707 start("projent_parse(): flags: $flagstring, project: $project"); 708 ($ret, $projent) = projent_parse($project, $flags); 709 if ($ret != $parse_exp) { 710 fail("Expected $parse_exp, Returned $ret"); 711 if ($ret) { 712 foreach $error (@$projent) { 713 comment("# " . join(", ", @$error)); 714 } 715 } 716 next; 717 } 718 pass(); 719 720 # projent_validate() can only be successfully parsed projents 721 if ($ret) { 722 next; 723 } 724 725 start("projent_validate(): flags: $flagstring, project: $project"); 726 ($ret, $errors) = projent_validate($projent, $flags); 727 if ($ret != $validate_exp) { 728 fail("Expected $validate_exp, Returned $ret"); 729 if ($ret) { 730 foreach $error (@$errors) { 731 comment("# " . join(", ", @$error)); 732 } 733 } 734 next; 735 } 736 pass(); 737} 738 739my $pf1; 740my $pf2; 741my $fh1; 742my $fh2; 743my @lines; 744 745# get projects and make local copy 746open($fh1, "/usr/bin/getent project |") || fatal($!); 747open($fh2, ">/tmp/projent.$$") || fatal($!); 748@lines = <$fh1>; 749print $fh2 @lines; 750close($fh1); 751close($fh2); 752 753open($fh1, "</tmp/projent.$$") || fatal($!); 754$pf1 = read_pfile($fh1); 755close($fh1); 756 757 758start("Test getprojid"); 759($s) = `/usr/xpg4/bin/id -p` =~ /projid=(\d+)/; 760defined($s) && $s == getprojid() ? pass() : fail(); 761 762start("Test fgetprojent"); 763$pf2 = []; 764open($fh, "</tmp/projent.$$") || fatal($!); 765while (my @proj = fgetprojent($fh)) { 766 push(@$pf2, [ @proj ]); 767} 768close($fh); 769cmp_recs($pf1, $pf2) ? pass() : fail(); 770 771my %pf_byname = map({ $_->[0] => $_} @$pf1); 772my %pf_byid = map({ $_->[1] => $_} @$pf1); 773my (%h, @a1, @a2, $k, $v); 774 775start("Test getprojent. Don't assume anything about the order it returns stuff in"); 776%h = %pf_byname; 777$pass = 1; 778@a2 = (); 779while (@a1 = getprojent()) { 780 @a2 = @a1 if (! scalar(@a2)); 781 if (exists($h{$a1[0]})) { 782 $pass = 0 if (! cmp_recs(\@a1, $h{$a1[0]})); 783 delete($h{$a1[0]}); 784 } else { 785 $pass = 0; 786 } 787} 788$pass && ! %h ? pass() : fail(); 789 790start("Test getprojent when at end"); 791@a1 = getprojent(); 792cmp_recs(\@a1, []) ? pass() : fail(); 793 794 795start("Test endprojent/getprojent"); 796endprojent(); 797@a1 = getprojent(); 798cmp_recs(\@a1, \@a2) ? pass() : fail(); 799 800start("Test setprojent/getprojent"); 801setprojent(); 802@a1 = getprojent(); 803cmp_recs(\@a1, \@a2) ? pass() : fail(); 804setprojent(); 805 806start("Test getprojbyname"); 807$pass = 1; 808while (($k, $v) = each(%pf_byname)) { 809 @a1 = getprojbyname($k); 810 $pass = 0 if (! cmp_recs(\@a1, $v)); 811} 812$pass ? pass() : fail(); 813 814start("Test getprojbyid"); 815$pass = 1; 816while (($k, $v) = each(%pf_byid)) { 817 @a1 = getprojbyid($k); 818 $pass = 0 if (! cmp_recs(\@a1, $v)); 819} 820$pass ? pass() : fail(); 821 822start("Test getprojidbyname"); 823$pass = 1; 824while (($k, $v) = each(%pf_byname)) { 825 $pass = 0 if (getprojidbyname($k) != $v->[1]); 826} 827$pass ? pass() : fail(); 828 829start("Test getdefaultproj"); 830my $username = getpwuid($>); 831my $projid; 832$s = `/usr/bin/id -p` ; 833($projid) = $s =~ /projid=\d+\(([^)]+)\)/; 834defined($projid) && $projid eq getdefaultproj($username) ? pass() : fail(); 835 836start("test inproj"); 837$s = `/usr/bin/projects`; 838($s) = split(/\s+/, $s); 839inproj($username, $s) ? pass() : fail(); 840 841exit(0); 842