1+ <?php declare (strict_types=1 );
2+
3+ /**
4+ * validate all test data for a given version of CycloneDX.
5+ * call the script via `php -f <this-file> -- -v <CDX-version>`
6+ */
7+
8+ use Opis \JsonSchema ;
9+
10+ require_once __DIR__ . '/vendor/autoload.php ' ;
11+
12+ // region config
13+
14+ define ('TESTSCHEMA_VERSION ' , getopt ('v: ' )['v ' ]);
15+ define ('SCHEMA_DIR ' , realpath (__DIR__ . '/../../../../schema ' ));
16+ define ('SCHEMA_FILE ' , SCHEMA_DIR . '/bom- ' . TESTSCHEMA_VERSION . '.xsd ' );
17+ define ('TESTDATA_DIR ' , realpath (__DIR__ . '/../resources/ ' . TESTSCHEMA_VERSION ));
18+
19+ if (empty (TESTSCHEMA_VERSION )) {
20+ throw new Exception ('missing TESTSCHEMA_VERSION. expected via opt "-v" ' );
21+ }
22+ fwrite (STDOUT , 'DEBUG | TESTSCHEMA_VERSION = ' . TESTSCHEMA_VERSION . PHP_EOL );
23+
24+ if (!is_file (SCHEMA_FILE )) {
25+ throw new Exception ('missing SCHEMA_FILE: ' . SCHEMA_FILE );
26+ }
27+ fwrite (STDOUT , 'DEBUG | SCHEMA_FILE = ' . SCHEMA_FILE . PHP_EOL );
28+
29+ if (!is_dir (TESTDATA_DIR )) {
30+ throw new Exception ('missing TESTDATA_DIR: ' . TESTDATA_DIR );
31+ }
32+ fwrite (STDOUT , 'DEBUG | TESTDATA_DIR = ' . TESTDATA_DIR . PHP_EOL );
33+
34+ // endregion config
35+
36+ // region validator
37+
38+ $ xmlOptions = \LIBXML_NONET ;
39+ if (\defined ('LIBXML_COMPACT ' )) {
40+ $ xmlOptions |= \LIBXML_COMPACT ;
41+ }
42+ if (\defined ('LIBXML_PARSEHUGE ' )) {
43+ $ xmlOptions |= \LIBXML_PARSEHUGE ;
44+ }
45+
46+ /**
47+ * @param string $file file path to validate
48+ */
49+ function validateFile (string $ file ): ?LibXMLError
50+ {
51+ global $ xmlOptions ;
52+
53+ libxml_use_internal_errors (true );
54+ libxml_clear_errors ();
55+
56+ $ doc = new DOMDocument ();
57+ if (!$ doc ->loadXML (file_get_contents ($ file ), $ xmlOptions )) {
58+ throw new Exception ("failed loading file: $ file " . PHP_EOL . libxml_get_last_error ()->message );
59+ }
60+
61+ $ valid = $ doc ->schemaValidate (SCHEMA_FILE );
62+ return $ valid
63+ ? null
64+ : libxml_get_last_error ();
65+ }
66+
67+ // endregion validator
68+
69+ $ errCnt = 0 ;
70+
71+ foreach (glob (TESTDATA_DIR . '/valid-*.xml ' ) as $ file ) {
72+ fwrite (STDOUT , PHP_EOL . "test $ file ... " . PHP_EOL );
73+ $ validationError = validateFile ($ file );
74+ if ($ validationError === null ) {
75+ fwrite (STDOUT , 'OK. ' . PHP_EOL );
76+ } else {
77+ ++$ errCnt ;
78+ fwrite (STDERR , "ERROR: Unexpected validation error for file: $ file " . PHP_EOL );
79+ fwrite (STDERR , print_r ($ validationError , true ) . PHP_EOL );
80+ }
81+ unset($ validationError );
82+ }
83+
84+ foreach (glob (TESTDATA_DIR . '/invalid-*.xml ' ) as $ file ) {
85+ fwrite (STDOUT , PHP_EOL . "test $ file ... " . PHP_EOL );
86+ $ validationError = validateFile ($ file );
87+ if ($ validationError === null ) {
88+ ++$ errCnt ;
89+ fwrite (STDERR , "ERROR: Missing expected validation error for file: $ file " . PHP_EOL );
90+ } else {
91+ fwrite (STDOUT , 'OK. ' . PHP_EOL );
92+ }
93+ unset($ validationError );
94+ }
95+
96+
97+ // Exit statuses should be in the range 0 to 254, the exit status 255 is reserved by PHP and shall not be used.
98+ // The status 0 is used to terminate the program successfully.
99+ exit (min ($ errCnt , 254 ));
0 commit comments