regulators: Improve config file validator

Improve error checking in config file validator.

Add checking if config file does not exist, config file is not readable,
and config file is not a JSON file.
Add checking if schema file does not exist, schema file is not readable,
and schema file is not a JSON file.

Tested:
Run local CI with -Dlong-tests=enabled to enable tests for
validate-regulators-config.py.

1/7 phosphor-regulators-tests   OK             32.49s

Signed-off-by: Bob King <Bob_King@wistron.com>
Change-Id: I5a84949e89be004a20a04c00d16b49286cb42f37
diff --git a/phosphor-regulators/test/validate-regulators-config_tests.cpp b/phosphor-regulators/test/validate-regulators-config_tests.cpp
index e62a88c..42038d1 100644
--- a/phosphor-regulators/test/validate-regulators-config_tests.cpp
+++ b/phosphor-regulators/test/validate-regulators-config_tests.cpp
@@ -2914,17 +2914,17 @@
         expectCommandLineSyntax("Error: Schema file is required.",
                                 outputMessageHelp, command, 1);
     }
+    // Invalid: -c specified more than once
+    {
+        command = validateTool + schema + schemaFile + "-c -c " + fileName;
+        expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
+    }
     // Invalid: -s specified more than once
     {
         command =
             validateTool + "-s -s " + schemaFile + configuration + fileName;
         expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
     }
-    // Invalid: -c specified more than once
-    {
-        command = validateTool + schema + schemaFile + "-c -c " + fileName;
-        expectCommandLineSyntax(outputMessageHelp, outputMessage, command, 2);
-    }
     // Invalid: No file name specified after -c
     {
         command = validateTool + schema + schemaFile + configuration;
@@ -2939,15 +2939,28 @@
     {
         command = validateTool + schema + schemaFile + configuration +
                   "../notExistFile";
-        expectCommandLineSyntax(
-            "Traceback (most recent call last):", outputMessage, command, 1);
+        expectCommandLineSyntax("Error: Configuration file does not exist.",
+                                outputMessageHelp, command, 1);
     }
     // Invalid: File specified after -s does not exist
     {
         command = validateTool + schema + "../notExistFile " + configuration +
                   fileName;
+        expectCommandLineSyntax("Error: Schema file does not exist.",
+                                outputMessageHelp, command, 1);
+    }
+    // Invalid: File specified after -c is not right data format
+    {
+        TemporaryFile wrongFormatFile;
+        std::string wrongFormatFileName = wrongFormatFile.getPath().string();
+        std::ofstream out(wrongFormatFileName);
+        out << "foo";
+        out.close();
+        command = validateTool + schema + schemaFile + configuration +
+                  wrongFormatFileName;
         expectCommandLineSyntax(
-            "Traceback (most recent call last):", outputMessage, command, 1);
+            "Error: Configuration file is not in the JSON format.",
+            outputMessageHelp, command, 1);
     }
     // Invalid: File specified after -s is not right data format
     {
@@ -2958,8 +2971,8 @@
         out.close();
         command = validateTool + schema + wrongFormatFileName + configuration +
                   fileName;
-        expectCommandLineSyntax(
-            "Traceback (most recent call last):", outputMessage, command, 1);
+        expectCommandLineSyntax("Error: Schema file is not in the JSON format.",
+                                outputMessageHelp, command, 1);
     }
     // Invalid: File specified after -c is not readable
     {
@@ -2969,8 +2982,8 @@
         command = validateTool + schema + schemaFile + configuration +
                   notReadableFileName;
         chmod(notReadableFileName.c_str(), 0222);
-        expectCommandLineSyntax(
-            "Traceback (most recent call last):", outputMessage, command, 1);
+        expectCommandLineSyntax("Error: Configuration file is not readable.",
+                                outputMessageHelp, command, 1);
     }
     // Invalid: File specified after -s is not readable
     {
@@ -2980,8 +2993,8 @@
         command = validateTool + schema + notReadableFileName + configuration +
                   fileName;
         chmod(notReadableFileName.c_str(), 0222);
-        expectCommandLineSyntax(
-            "Traceback (most recent call last):", outputMessage, command, 1);
+        expectCommandLineSyntax("Error: Schema file is not readable.",
+                                outputMessageHelp, command, 1);
     }
     // Invalid: Unexpected parameter specified (like -g)
     {
diff --git a/phosphor-regulators/tools/validate-regulators-config.py b/phosphor-regulators/tools/validate-regulators-config.py
index 7b1cd6f..125bd0c 100755
--- a/phosphor-regulators/tools/validate-regulators-config.py
+++ b/phosphor-regulators/tools/validate-regulators-config.py
@@ -2,8 +2,9 @@
 
 import argparse
 import json
-import sys
 import jsonschema
+import os
+import sys
 
 r"""
 Validates the phosphor-regulators configuration file. Checks it against a JSON
@@ -283,6 +284,14 @@
 
     return config_json
 
+def validate_JSON_format(file):
+    with open(file) as json_data:
+        try:
+            return json.load(json_data)
+        except ValueError as err:
+            return False
+        return True
+
 if __name__ == '__main__':
 
     parser = argparse.ArgumentParser(
@@ -299,9 +308,27 @@
     if not args.schema_file:
         parser.print_help()
         sys.exit("Error: Schema file is required.")
+    if not os.path.exists(args.schema_file):
+        parser.print_help()
+        sys.exit("Error: Schema file does not exist.")
+    if not os.access(args.schema_file, os.R_OK):
+        parser.print_help()
+        sys.exit("Error: Schema file is not readable.")
+    if not validate_JSON_format(args.schema_file):
+        parser.print_help()
+        sys.exit("Error: Schema file is not in the JSON format.")
     if not args.configuration_file:
         parser.print_help()
         sys.exit("Error: Configuration file is required.")
+    if not os.path.exists(args.configuration_file):
+        parser.print_help()
+        sys.exit("Error: Configuration file does not exist.")
+    if not os.access(args.configuration_file, os.R_OK):
+        parser.print_help()
+        sys.exit("Error: Configuration file is not readable.")
+    if not validate_JSON_format(args.configuration_file):
+        parser.print_help()
+        sys.exit("Error: Configuration file is not in the JSON format.")
 
     config_json = validate_schema(args.configuration_file, args.schema_file)