From 2a23bce31c700eb76e867283b2fbd7f2aec51cf3 Mon Sep 17 00:00:00 2001 From: Shelly Belsky Date: Sun, 18 Aug 2024 19:09:21 -0400 Subject: [PATCH 1/5] add XML validation to all submissions --- app/Console/Commands/ValidateXml.php | 60 +++++++++--------- .../CDashXMLValidationException.php | 31 +++++++++ app/Jobs/ProcessSubmission.php | 2 +- app/Utils/SubmissionUtils.php | 63 ++++++++++++++++++- app/cdash/include/ctestparser.php | 25 +++++++- 5 files changed, 145 insertions(+), 36 deletions(-) create mode 100644 app/Exceptions/CDashXMLValidationException.php diff --git a/app/Console/Commands/ValidateXml.php b/app/Console/Commands/ValidateXml.php index 02278e609a..6ab7bd9994 100644 --- a/app/Console/Commands/ValidateXml.php +++ b/app/Console/Commands/ValidateXml.php @@ -4,7 +4,7 @@ use App\Utils\SubmissionUtils; use Illuminate\Console\Command; -use DOMDocument; +use App\Exceptions\CDashXMLValidationException; class ValidateXml extends Command { @@ -26,59 +26,54 @@ public function handle(): int { // parse all input files from command line $xml_files_args = $this->argument('xml_file'); - $schemas_dir = base_path()."/app/Validators/Schemas"; // process each of the input files $has_errors = false; + $has_skipped = false; foreach ($xml_files_args as $input_xml_file) { // determine the file type by peeking at its contents + if (!file_exists($input_xml_file)) { + $this->error("ERROR: Input file does not exist: '{$input_xml_file}'"); + $has_skipped = true; + continue; + } $xml_file_handle = fopen($input_xml_file, 'r'); if ($xml_file_handle === false) { $this->error("ERROR: Could not open file: '{$input_xml_file}'"); - $has_errors = true; + $has_skipped = true; continue; } - $xml_type = SubmissionUtils::get_xml_type($xml_file_handle)['xml_type']; - fclose($xml_file_handle); - // verify we identified a valid xml type - if ($xml_type === '') { - $this->error("ERROR: Could not determine submission" - ." file type for: '{$input_xml_file}'"); + try { + $xml_schema = SubmissionUtils::get_xml_type($xml_file_handle, $input_xml_file)['xml_schema']; + } catch (CDashXMLValidationException $e) { + foreach ($e->getDecodedMessage() as $error) { + $this->error($error); + } $has_errors = true; continue; + } finally { + fclose($xml_file_handle); } - // verify we can find a corresponding schema file - $schema_file = "{$schemas_dir}/{$xml_type}.xsd"; - if (!file_exists($schema_file)) { - $this->error("ERROR: Could not find schema file '{$schema_file}'" - ." corresonding to input: '{$input_xml_file}'"); - $has_errors = true; + if (!isset($xml_schema)) { + $this->warn("WARNING: Skipped input file '{$input_xml_file}' as validation" + ." of this file format is currently not supported."); + $has_skipped = true; continue; } - // let us control the failures so we can continue - // parsing all the files instead of crashing midway - libxml_use_internal_errors(true); - - // load the input file to be validated - $xml = new DOMDocument(); - $xml->load($input_xml_file, LIBXML_PARSEHUGE); - // run the validator and collect errors if there are any - if (!$xml->schemaValidate($schema_file)) { - $errors = libxml_get_errors(); - foreach ($errors as $error) { - if ($error->level > 2) { - $this->error("ERROR: {$error->message} in {$error->file}," - ." line: {$error->line}, column: {$error->column}"); - } + try { + SubmissionUtils::validate_xml($input_xml_file, $xml_schema); + } catch (CDashXMLValidationException $e) { + foreach ($e->getDecodedMessage() as $error) { + $this->error($error); } - libxml_clear_errors(); $has_errors = true; continue; } + $this->line("Validated file: {$input_xml_file}."); } @@ -86,6 +81,9 @@ public function handle(): int if ($has_errors) { $this->error("FAILED: Some XML file checks did not pass!"); return Command::FAILURE; + } elseif ($has_skipped) { + $this->error("FAILED: Some XML file checks were skipped!"); + return Command::FAILURE; } else { $this->line("SUCCESS: All XML file checks passed."); return Command::SUCCESS; diff --git a/app/Exceptions/CDashXMLValidationException.php b/app/Exceptions/CDashXMLValidationException.php new file mode 100644 index 0000000000..e8366fb02f --- /dev/null +++ b/app/Exceptions/CDashXMLValidationException.php @@ -0,0 +1,31 @@ + $message + */ + public function __construct(array $message = [], int $code = 0, Exception $previous = null) + { + $encoded_msg = json_encode($message); + $encoded_msg = $encoded_msg===false ? "" : $encoded_msg; + parent::__construct($encoded_msg, $code, $previous); + } + + /** + * @return array + */ + public function getDecodedMessage(bool $assoc = false): array + { + $decoded_msg = json_decode($this->getMessage(), $assoc); + if (!isset($decoded_msg) || is_bool($decoded_msg)) { + $decoded_msg = ["An XML validation error has occurred!"]; + } + return $decoded_msg; + } +} diff --git a/app/Jobs/ProcessSubmission.php b/app/Jobs/ProcessSubmission.php index 74b04b4420..d2a618cf03 100644 --- a/app/Jobs/ProcessSubmission.php +++ b/app/Jobs/ProcessSubmission.php @@ -204,7 +204,7 @@ private function doSubmit($filename, $projectid, $buildid = null, } // Parse the XML file - $handler = ctest_parse($filehandle, $projectid, $expected_md5); + $handler = ctest_parse($filehandle, $filename, $projectid, $expected_md5); fclose($filehandle); unset($filehandle); diff --git a/app/Utils/SubmissionUtils.php b/app/Utils/SubmissionUtils.php index d69a103e99..f596cf0d6a 100644 --- a/app/Utils/SubmissionUtils.php +++ b/app/Utils/SubmissionUtils.php @@ -7,18 +7,22 @@ use CDash\Database; use CDash\Model\Build; use CDash\Model\BuildUpdate; +use DOMDocument; +use App\Exceptions\CDashXMLValidationException; class SubmissionUtils { - /** * Figure out what type of XML file this is * @return array + * @throws CDashXMLValidationException */ - public static function get_xml_type(mixed $filehandle): array + public static function get_xml_type(mixed $filehandle, string $xml_file): array { $file = ''; $handler = null; + $schemas_dir = base_path()."/app/Validators/Schemas"; + $schema_file = null; // read file contents until we recognize its elements while ($file === '' && !feof($filehandle)) { $content = fread($filehandle, 8192); @@ -30,56 +34,111 @@ public static function get_xml_type(mixed $filehandle): array // Should be first otherwise confused with Build $handler = \UpdateHandler::class; $file = 'Update'; + $schema_file = "{$schemas_dir}/{$file}.xsd"; } elseif (str_contains($content, ' $filehandle, 'xml_handler' => $handler, 'xml_type' => $file, + 'xml_schema' => $schema_file, ]; } + /** + * Validate the given XML file based on its type + * @throws CDashXMLValidationException + */ + public static function validate_xml(string $xml_file, string $schema_file): void + { + $errors = []; + + // let us control the failures so we can continue + // parsing files instead of crashing midway + libxml_use_internal_errors(true); + + // load the input file to be validated + $xml = new DOMDocument(); + $xml->load($xml_file, LIBXML_PARSEHUGE); + + // run the validator and collect errors if there are any + if (!$xml->schemaValidate($schema_file)) { + $validation_errors = libxml_get_errors(); + foreach ($validation_errors as $error) { + if ($error->level === LIBXML_ERR_ERROR || $error->level === LIBXML_ERR_FATAL) { + $errors[] = "ERROR: {$error->message} in {$error->file}," + ." line: {$error->line}, column: {$error->column}"; + } + } + libxml_clear_errors(); + } + + if (count($errors) !== 0) { + throw new CDashXMLValidationException($errors); + } + } + /** Add a new build */ public static function add_build(Build $build) { diff --git a/app/cdash/include/ctestparser.php b/app/cdash/include/ctestparser.php index 730618f6b7..0a07c52bb0 100644 --- a/app/cdash/include/ctestparser.php +++ b/app/cdash/include/ctestparser.php @@ -20,6 +20,7 @@ use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Storage; use App\Utils\SubmissionUtils; +use App\Exceptions\CDashXMLValidationException; class CDashParseException extends RuntimeException { @@ -148,7 +149,7 @@ function parse_put_submission($filehandler, $projectid, $expected_md5) } /** Main function to parse the incoming xml from ctest */ -function ctest_parse($filehandle, $projectid, $expected_md5 = '') +function ctest_parse($filehandle, string $filename, $projectid, $expected_md5 = '') { // Check if this is a new style PUT submission. try { @@ -168,10 +169,30 @@ function ctest_parse($filehandle, $projectid, $expected_md5 = '') } // Figure out what type of XML file this is. - $xml_info = SubmissionUtils::get_xml_type($filehandle); + try { + $xml_info = SubmissionUtils::get_xml_type($filehandle, $filename); + } catch (CDashXMLValidationException $e) { + foreach ($e->getDecodedMessage() as $error) { + Log::error($error); + } + return false; + } $filehandle = $xml_info['file_handle']; $handler_ref = $xml_info['xml_handler']; $file = $xml_info['xml_type']; + $schema_file = $xml_info['xml_schema']; + + // Ensure the XML file is valid if the XML type has a schema defined + if (isset($schema_file)) { + try { + SubmissionUtils::validate_xml($filename, $schema_file); + } catch (CDashXMLValidationException $e) { + foreach ($e->getDecodedMessage() as $error) { + Log::error($error); + } + return false; + } + } $handler = isset($handler_ref) ? new $handler_ref($projectid) : null; From 1e536cf0ff473ed1c4c37215ae395648f0ae2587 Mon Sep 17 00:00:00 2001 From: Shelly Belsky Date: Sat, 7 Sep 2024 10:56:07 -0400 Subject: [PATCH 2/5] hide submission validation behind a feature flag --- .env.example | 5 +++++ app/cdash/include/ctestparser.php | 8 ++++---- config/cdash.php | 1 + docs/submissions.md | 4 ++++ 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/.env.example b/.env.example index 4d17b2f1cb..0620a1f4bf 100755 --- a/.env.example +++ b/.env.example @@ -125,6 +125,11 @@ DB_PASSWORD=secret # to some value other than 'sync'. #REMOTE_WORKERS=false +# Whether or not submission XML files are validated before being processed. +# Enabling this setting will trigger a scan through XML files uploaded in +# each submission in order to preemptively reject malformed files. +#VALIDATE_XML_SUBMISSIONS=true + # Should we show the most recent submission time for a project or subproject? # Disabling this feature can improve rendering performance of index.php # for projects with lots of subproject builds. diff --git a/app/cdash/include/ctestparser.php b/app/cdash/include/ctestparser.php index 0a07c52bb0..f7a9efba19 100644 --- a/app/cdash/include/ctestparser.php +++ b/app/cdash/include/ctestparser.php @@ -182,15 +182,15 @@ function ctest_parse($filehandle, string $filename, $projectid, $expected_md5 = $file = $xml_info['xml_type']; $schema_file = $xml_info['xml_schema']; - // Ensure the XML file is valid if the XML type has a schema defined - if (isset($schema_file)) { + // If validation is enabled and if this file has a corresponding schema, validate it + if (((bool) config('cdash.validate_xml_submissions')) === true && isset($schema_file)) { try { SubmissionUtils::validate_xml($filename, $schema_file); } catch (CDashXMLValidationException $e) { foreach ($e->getDecodedMessage() as $error) { - Log::error($error); + Log::error("Validating $filename: ".$error); } - return false; + abort(400, "Xml validation failed: rejected file $filename"); } } diff --git a/config/cdash.php b/config/cdash.php index 129d7a9e98..55ee147ab6 100755 --- a/config/cdash.php +++ b/config/cdash.php @@ -75,6 +75,7 @@ 'show_last_submission' => env('SHOW_LAST_SUBMISSION', true), 'slow_page_time' => env('SLOW_PAGE_TIME', 10), 'token_duration' => env('TOKEN_DURATION', 15811200), + 'validate_xml_submissions' => env('VALIDATE_XML_SUBMISSIONS', false), // Specify whether users are allowed to create "full access" authentication tokens 'allow_full_access_tokens' => env('ALLOW_FULL_ACCESS_TOKENS', true), // Specify whether users are allowed to create "submit only" tokens which are valid for all projects diff --git a/docs/submissions.md b/docs/submissions.md index 5e13c753a7..1a0c7a5c17 100644 --- a/docs/submissions.md +++ b/docs/submissions.md @@ -76,3 +76,7 @@ for both the CDash web service and the remote worker(s). ## Deferred submissions CDash automatically detects when its database is unavailable and stores submissions received during this outage. When database access is restored, CDash will attempt to parse the submissions that were received during the outage. This behavior is controlled by the presence of the file named `DB_WAS_DOWN` in the storage directory. + +## Submission files validation + +CDash can be configured to validate submitted XML files before attempting to process them, in order to preemptively reject malformed files. If enabled, once a submission is moved out of the queue, its XML files will be scanned for valid syntax and validated against the [XML schemas](../app/Validators/Schemas/) CDash supports. To use this feature, set `VALIDATE_XML_SUBMISSIONS=true` in your `.env` file. From cd8c55423b05f01c2d6f83fa70e0738f86586242 Mon Sep 17 00:00:00 2001 From: Shelly Belsky Date: Fri, 6 Sep 2024 11:08:37 -0400 Subject: [PATCH 3/5] add unit test for xml submission file validation --- app/cdash/tests/CMakeLists.txt | 2 + .../Command/ValidateXmlCommandTest.php | 145 ++++++++++++++++++ .../data/XmlValidation/invalid_Configure.xml | 12 ++ .../XmlValidation/invalid_syntax_Build.xml | 35 +++++ tests/data/XmlValidation/invalid_type.xml | 9 ++ tests/data/XmlValidation/valid_Build.xml | 34 ++++ tests/data/XmlValidation/valid_Test.xml | 26 ++++ 7 files changed, 263 insertions(+) create mode 100644 tests/Unit/app/Console/Command/ValidateXmlCommandTest.php create mode 100644 tests/data/XmlValidation/invalid_Configure.xml create mode 100644 tests/data/XmlValidation/invalid_syntax_Build.xml create mode 100644 tests/data/XmlValidation/invalid_type.xml create mode 100644 tests/data/XmlValidation/valid_Build.xml create mode 100644 tests/data/XmlValidation/valid_Test.xml diff --git a/app/cdash/tests/CMakeLists.txt b/app/cdash/tests/CMakeLists.txt index 3786f86ac0..fbfd7e01fb 100644 --- a/app/cdash/tests/CMakeLists.txt +++ b/app/cdash/tests/CMakeLists.txt @@ -605,5 +605,7 @@ set_tests_properties(misassignedconfigure PROPERTIES DEPENDS /Feature/SubProject add_laravel_test(/Feature/RemoteWorkers) set_tests_properties(/Feature/RemoteWorkers PROPERTIES DEPENDS install_3) +add_laravel_test(/Unit/app/Console/Command/ValidateXmlCommandTest) + add_subdirectory(ctest) add_subdirectory(autoremovebuilds) diff --git a/tests/Unit/app/Console/Command/ValidateXmlCommandTest.php b/tests/Unit/app/Console/Command/ValidateXmlCommandTest.php new file mode 100644 index 0000000000..e849d796ef --- /dev/null +++ b/tests/Unit/app/Console/Command/ValidateXmlCommandTest.php @@ -0,0 +1,145 @@ +> + */ + private function formatCommandParams() + { + $data_dir = base_path()."/tests/data/XmlValidation"; + $file_paths = []; + foreach (func_get_args() as $file) { + $file_paths[] = "{$data_dir}/{$file}"; + } + return [ + 'xml_file' => $file_paths, + ]; + } + + /** + * Handle common assertions for a 'success' validation outcome + * + * @param string $output, int $rc, string $msg + * @return void + */ + private function assertValidationSuccess(string $output, int $rc, string $msg): void + { + $this::assertMatchesRegularExpression("/All XML file checks passed./", $output, $msg); + $this::assertEquals(Command::SUCCESS, $rc, "Passing validation should return a SUCCESS return code"); + } + + /** + * Handle common assertions for a 'failure' validation outcome + * + * @param string $output, int $rc, string $msg, bool $skipped_files + * @return void + */ + private function assertValidationFailure(string $output, int $rc, string $msg, bool $skipped_files=false): void + { + $output_regex = $skipped_files ? "/Some XML file checks were skipped!/" : "/Some XML file checks did not pass!/"; + $this::assertMatchesRegularExpression($output_regex, $output, $msg); + $this::assertEquals(Command::FAILURE, $rc, "Failed validation should return a FAILURE return code"); + } + + /** + * Tests validating a single valid file + * + * @return void + */ + public function testSingleValidXml(): void + { + $params = $this->formatCommandParams("valid_Build.xml"); + $rc = Artisan::call('submission:validate', $params); + $output = trim(Artisan::output()); + $this->assertValidationSuccess($output, $rc, "A single valid Build XML file should pass."); + } + + /** + * Tests validating an invalid file path + * + * @return void + */ + public function testInvalidFilePath(): void + { + $params = $this->formatCommandParams("no_such_file.xml"); + $rc = Artisan::call('submission:validate', $params); + $output = trim(Artisan::output()); + $this->assertValidationFailure($output, $rc, "An invalid file path should fail.", $skipped=true); + } + + /** + * Tests validating a single file of unknown schema + * + * @return void + */ + public function testUnknownSchema(): void + { + $params = $this->formatCommandParams("invalid_type.xml"); + $rc = Artisan::call('submission:validate', $params); + $output = trim(Artisan::output()); + $this->assertValidationFailure($output, $rc, "An XML file that doesn't match any supported schemas should fail."); + } + + /** + * Tests validating a single file that does not adhere to its schema + * + * @return void + */ + public function testSingleInvalidXml(): void + { + $params = $this->formatCommandParams("invalid_Configure.xml"); + $rc = Artisan::call('submission:validate', $params); + $output = trim(Artisan::output()); + $this->assertValidationFailure($output, $rc, "An XML file that doesn't adhere to its corresponding schema should fail."); + } + + /** + * Tests validating a single file with invalid syntax + * + * @return void + */ + public function testSingleInvalidSyntaxXml(): void + { + $params = $this->formatCommandParams("invalid_syntax_Build.xml"); + $rc = Artisan::call('submission:validate', $params); + $output = trim(Artisan::output()); + $this->assertValidationFailure($output, $rc, "An XML file with syntax errors should fail."); + } + /** + * Tests validating multiple valid files + * + * @return void + */ + public function testMultipleValidXml(): void + { + $params = $this->formatCommandParams("valid_Build.xml", "valid_Test.xml"); + $rc = Artisan::call('submission:validate', $params); + $output = trim(Artisan::output()); + $this->assertValidationSuccess($output, $rc, "Multiple valid XML files should pass."); + } + + /** + * Tests validating multiple files where some are invalid + * + * @return void + */ + public function testMultipleFilesFailure(): void + { + $params = $this->formatCommandParams("valid_Build.xml", "invalid_Configure.xml", "valid_Test.xml"); + $rc = Artisan::call('submission:validate', $params); + $output = trim(Artisan::output()); + $this->assertValidationFailure($output, $rc, "Validation of a set of input files should fail when one or more errors occur."); + } +} diff --git a/tests/data/XmlValidation/invalid_Configure.xml b/tests/data/XmlValidation/invalid_Configure.xml new file mode 100644 index 0000000000..e299bb8523 --- /dev/null +++ b/tests/data/XmlValidation/invalid_Configure.xml @@ -0,0 +1,12 @@ + + + + "cmake" "/foo/bar/src" + + 0 + 0 + + diff --git a/tests/data/XmlValidation/invalid_syntax_Build.xml b/tests/data/XmlValidation/invalid_syntax_Build.xml new file mode 100644 index 0000000000..f564dad59a --- /dev/null +++ b/tests/data/XmlValidation/invalid_syntax_Build.xml @@ -0,0 +1,35 @@ + + + + Aug 13 09:24 EDT + 1439472247 + /opt/cmake/bin/cmake --build . --config "Debug" -- -i + + + foo + C++ + foo + executable + + + /foo/bar/bin + /usr/local/bin/c++ + CMakeFiles/foo.dir/foo.cxx.o + -o + foo + + + + c++: error: CMakeFiles/foo.dir/foo.cxx.o: No such file or directory + 1 + + + + Sep 1 09:24 EDT + 0 + + diff --git a/tests/data/XmlValidation/invalid_type.xml b/tests/data/XmlValidation/invalid_type.xml new file mode 100644 index 0000000000..6897922410 --- /dev/null +++ b/tests/data/XmlValidation/invalid_type.xml @@ -0,0 +1,9 @@ + + + + Hello World + + diff --git a/tests/data/XmlValidation/valid_Build.xml b/tests/data/XmlValidation/valid_Build.xml new file mode 100644 index 0000000000..acfb3b7cb1 --- /dev/null +++ b/tests/data/XmlValidation/valid_Build.xml @@ -0,0 +1,34 @@ + + + + Aug 13 09:24 EDT + 1439472247 + /opt/cmake/bin/cmake --build . --config "Debug" -- -i + + + foo + C++ + foo + executable + + + /foo/bar/bin + /usr/local/bin/c++ + CMakeFiles/foo.dir/foo.cxx.o + -o + foo + + + + c++: error: CMakeFiles/foo.dir/foo.cxx.o: No such file or directory + 1 + + + + Sep 1 09:24 EDT + 0 + + diff --git a/tests/data/XmlValidation/valid_Test.xml b/tests/data/XmlValidation/valid_Test.xml new file mode 100644 index 0000000000..434c48c5d8 --- /dev/null +++ b/tests/data/XmlValidation/valid_Test.xml @@ -0,0 +1,26 @@ + + + + + ./foo + + + foo + . + ./foo + /tmp/bin/foo + + + Failed + + + 1 + + + + 0 + + From 63bef62964502a84b1f3ae899c883470b3e18de9 Mon Sep 17 00:00:00 2001 From: Joseph Snyder Date: Wed, 25 Sep 2024 12:35:38 -0400 Subject: [PATCH 4/5] Use storage_path on ctest submit for validation When attempting to validate an HTTP submission use the `storage_path` helper to turn the filename which starts at the inproess folder, `inprocess/<>.xml`, to a full path. This should not affect the path given directly to the submission:validate artisan command. --- app/cdash/include/ctestparser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/cdash/include/ctestparser.php b/app/cdash/include/ctestparser.php index f7a9efba19..acac3e362d 100644 --- a/app/cdash/include/ctestparser.php +++ b/app/cdash/include/ctestparser.php @@ -185,7 +185,7 @@ function ctest_parse($filehandle, string $filename, $projectid, $expected_md5 = // If validation is enabled and if this file has a corresponding schema, validate it if (((bool) config('cdash.validate_xml_submissions')) === true && isset($schema_file)) { try { - SubmissionUtils::validate_xml($filename, $schema_file); + SubmissionUtils::validate_xml(storage_path("app/".$filename), $schema_file); } catch (CDashXMLValidationException $e) { foreach ($e->getDecodedMessage() as $error) { Log::error("Validating $filename: ".$error); From 4602d25d627f2bb6ff2ac03767c75da051e12218 Mon Sep 17 00:00:00 2001 From: Joseph Snyder Date: Mon, 7 Oct 2024 11:12:09 -0400 Subject: [PATCH 5/5] WIP: Add test for submission validation --- app/cdash/include/ctestparser.php | 4 +- app/cdash/tests/CMakeLists.txt | 3 ++ app/cdash/tests/test_submissionvalidation.php | 48 +++++++++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 app/cdash/tests/test_submissionvalidation.php diff --git a/app/cdash/include/ctestparser.php b/app/cdash/include/ctestparser.php index acac3e362d..72bb2579e4 100644 --- a/app/cdash/include/ctestparser.php +++ b/app/cdash/include/ctestparser.php @@ -183,9 +183,11 @@ function ctest_parse($filehandle, string $filename, $projectid, $expected_md5 = $schema_file = $xml_info['xml_schema']; // If validation is enabled and if this file has a corresponding schema, validate it + \Log::critical(((bool) config('cdash.validate_xml_submissions'))); + \Log::critical($schema_file); if (((bool) config('cdash.validate_xml_submissions')) === true && isset($schema_file)) { try { - SubmissionUtils::validate_xml(storage_path("app/".$filename), $schema_file); + SubmissionUtils::validate_xml($filename, $schema_file); } catch (CDashXMLValidationException $e) { foreach ($e->getDecodedMessage() as $error) { Log::error("Validating $filename: ".$error); diff --git a/app/cdash/tests/CMakeLists.txt b/app/cdash/tests/CMakeLists.txt index fbfd7e01fb..ca29b39883 100644 --- a/app/cdash/tests/CMakeLists.txt +++ b/app/cdash/tests/CMakeLists.txt @@ -607,5 +607,8 @@ set_tests_properties(/Feature/RemoteWorkers PROPERTIES DEPENDS install_3) add_laravel_test(/Unit/app/Console/Command/ValidateXmlCommandTest) +add_php_test(submissionvalidation) +set_tests_properties(submissionvalidation PROPERTIES DEPENDS install_3) + add_subdirectory(ctest) add_subdirectory(autoremovebuilds) diff --git a/app/cdash/tests/test_submissionvalidation.php b/app/cdash/tests/test_submissionvalidation.php new file mode 100644 index 0000000000..01aebb9b3c --- /dev/null +++ b/app/cdash/tests/test_submissionvalidation.php @@ -0,0 +1,48 @@ +submission('InsightExample', $file)); + if (false) { + return false; + } + + $this->assertTrue(true, "Submission of $file has succeeded"); + } + + public function testSubmissionValidation() + { + + $this->ConfigFile = dirname(__FILE__) . '/../../../.env'; + $this->Original = file_get_contents($this->ConfigFile); + #print_r($this->Original); + file_put_contents($this->ConfigFile, "VALIDATE_XML_SUBMISSIONS=true\n", FILE_APPEND | LOCK_EX); + + + $this->submit("invalid_Configure.xml"); + # $this->submit("valid_Build.xml"); + + + file_put_contents($this->ConfigFile, $this->Original); + } +} \ No newline at end of file