vts sysfuzzer common lib - spec parser

Change-Id: I48946f8578d2841ddc202464a169f10baed95baf
diff --git a/sysfuzzer/common/specification_parser/InterfaceSpecificationParser.cpp b/sysfuzzer/common/specification_parser/InterfaceSpecificationParser.cpp
new file mode 100644
index 0000000..dc72420
--- /dev/null
+++ b/sysfuzzer/common/specification_parser/InterfaceSpecificationParser.cpp
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "specification_parser/InterfaceSpecificationParser.h"
+
+#include <stdio.h>
+
+#include <iostream>
+
+#include <google/protobuf/message.h>
+#include <google/protobuf/text_format.h>
+
+#include "test/vts/sysfuzzer/common/proto/InterfaceSpecificationMessage.pb.h"
+
+using namespace std;
+
+namespace android {
+namespace vts {
+
+
+bool InterfaceSpecificationParser::parse(
+    const char* file_path, InterfaceSpecificationMessage* is_message) {
+  cout << __FUNCTION__ << " " << file_path << endl;
+
+  ifstream in_file(file_path);
+  stringstream str_stream;
+  if (!in_file.is_open()) {
+    cerr << "Unable to open file. " << file_path << endl;
+    return false;
+  }
+  str_stream << in_file.rdbuf();
+  in_file.close();
+const string data = str_stream.str();
+
+  if (!google::protobuf::TextFormat::MergeFromString(data, is_message)) {
+    cerr << __FUNCTION__ << ": Can't parse a given proto file "
+        << file_path << "." << endl;
+    cerr << data << endl;
+    return false;
+  }
+
+  return true;
+}
+
+}  // namespace vts
+}  // namespace android
diff --git a/sysfuzzer/common/specification_parser/InterfaceSpecificationParser.h b/sysfuzzer/common/specification_parser/InterfaceSpecificationParser.h
new file mode 100644
index 0000000..1b71707
--- /dev/null
+++ b/sysfuzzer/common/specification_parser/InterfaceSpecificationParser.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __VTS_SYSFUZZER_COMMON_SPECPARSER_IFSPECPARSER_H__
+#define __VTS_SYSFUZZER_COMMON_SPECPARSER_IFSPECPARSER_H__
+
+#include <string>
+
+#include "test/vts/sysfuzzer/common/proto/InterfaceSpecificationMessage.pb.h"
+
+using namespace std;
+
+namespace android {
+namespace vts {
+
+
+// Main class to parse an interface specification from a file.
+class InterfaceSpecificationParser {
+ public:
+  InterfaceSpecificationParser() {}
+
+  // Parses the given proto text file (1st arg). The parsed result is stored in
+  // the 2nd arg. Returns true iff successful.
+  static bool parse(
+      const char* file_path, InterfaceSpecificationMessage* is_message);
+};
+
+}  // namespace vts
+}  // namespace android
+
+#endif  // __VTS_SYSFUZZER_COMMON_SPECPARSER_IFSPECPARSER_H__
diff --git a/sysfuzzer/common/specification_parser/SpecificationBuilder.cpp b/sysfuzzer/common/specification_parser/SpecificationBuilder.cpp
new file mode 100644
index 0000000..8fe5a40
--- /dev/null
+++ b/sysfuzzer/common/specification_parser/SpecificationBuilder.cpp
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "specification_parser/SpecificationBuilder.h"
+
+#include <dirent.h>
+
+#include <iostream>
+#include <string>
+
+#include "fuzz_tester/FuzzerBase.h"
+#include "fuzz_tester/FuzzerWrapper.h"
+#include "specification_parser/InterfaceSpecificationParser.h"
+
+#include "test/vts/sysfuzzer/common/proto/InterfaceSpecificationMessage.pb.h"
+
+namespace android {
+namespace vts {
+
+SpecificationBuilder::SpecificationBuilder(const string dir_path)
+    : dir_path_(dir_path) {}
+
+
+vts::InterfaceSpecificationMessage*
+SpecificationBuilder::FindInterfaceSpecification(
+    const int target_class,
+    const int target_type,
+    const float target_version) {
+  DIR* dir;
+  struct dirent* ent;
+
+  if (!(dir = opendir(dir_path_.c_str()))) {
+    cerr << __FUNCTION__ << ": Can't opendir " << dir_path_ << endl;
+    return NULL;
+  }
+
+  while ((ent = readdir(dir))) {
+    if (string(ent->d_name).find(SPEC_FILE_EXT) != std::string::npos) {
+      cout << __FUNCTION__ << ": Checking a file " << ent->d_name << endl;
+      const string file_path = string(dir_path_) + "/" + string(ent->d_name);
+      vts::InterfaceSpecificationMessage* message =
+          new vts::InterfaceSpecificationMessage();
+      if (InterfaceSpecificationParser::parse(file_path.c_str(), message)) {
+        if (message->component_class() == target_class
+            && message->component_type() == target_type
+            && message->component_type_version() == target_version) {
+          closedir(dir);
+          return message;
+        }
+      }
+      delete message;
+    }
+  }
+  closedir(dir);
+  return NULL;
+}
+
+
+bool SpecificationBuilder::Process(
+    const char* dll_file_name,
+    const char* spec_lib_file_path,
+    int target_class,
+    int target_type,
+    float target_version) {
+  vts::InterfaceSpecificationMessage* interface_specification_message =
+      FindInterfaceSpecification(target_class, target_type, target_version);
+  if (!interface_specification_message) {
+    cerr << __FUNCTION__ <<
+        ": no interface specification file found for "
+        << "class " << target_class
+        << " type " << target_type
+        << " version " << target_version << endl;
+    return false;
+  }
+  FuzzerWrapper wrapper = FuzzerWrapper();
+
+  if (!wrapper.LoadInterfaceSpecificationLibrary(spec_lib_file_path)) {
+    return false;
+  }
+  FuzzerBase* fuzzer = wrapper.GetFuzzer(*interface_specification_message);
+  if (!fuzzer) {
+    cerr << __FUNCTION__ << ": coult't get a fuzzer base class" << endl;
+    return false;
+  }
+  if (!fuzzer->LoadTargetComponent(dll_file_name)) return -1;
+  // TODO: make 10 configurable.
+  for (int i = 0; i < 10; i++) {
+    fuzzer->Fuzz(*interface_specification_message);
+  }
+  return true;
+}
+
+
+}  // namespace vts
+}  // namespace android
diff --git a/sysfuzzer/common/specification_parser/SpecificationBuilder.h b/sysfuzzer/common/specification_parser/SpecificationBuilder.h
new file mode 100644
index 0000000..edeee13
--- /dev/null
+++ b/sysfuzzer/common/specification_parser/SpecificationBuilder.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __VTS_SYSFUZZER_COMMON_SPECPARSER_SPECBUILDER_H__
+#define __VTS_SYSFUZZER_COMMON_SPECPARSER_SPECBUILDER_H__
+
+#include <string>
+
+#include "test/vts/sysfuzzer/common/proto/InterfaceSpecificationMessage.pb.h"
+
+
+using namespace std;
+
+
+#define DEFAULT_SPEC_DIR_PATH "/system/etc/"
+#define SPEC_FILE_EXT ".vts"
+
+
+namespace android {
+namespace vts {
+
+class InterfaceSpecification;
+
+// Builder of an interface specification.
+class SpecificationBuilder {
+ public:
+  // Constructor where the first argument is the path of a dir which contains
+  // all available interface specification files.
+  SpecificationBuilder(const string dir_path);
+
+  // scans the dir and returns an interface specification for a requested
+  // component.
+  vts::InterfaceSpecificationMessage* FindInterfaceSpecification(
+      const int target_class, const int target_type, const float target_version);
+
+  // Main function for the VTS system fuzzer where dll_file_name is the path of
+  // a target component, spec_lib_file_path is the path of a specification
+  // library file, and the rest three arguments are the basic information of
+  // the target component.
+  bool Process(
+      const char* dll_file_name, const char* spec_lib_file_path,
+      int target_class, int target_type, float target_version);
+
+ private:
+  // the path of a dir which contains interface specification ASCII proto files.
+  const string dir_path_;
+};
+
+}  // namespace vts
+}  // namespace android
+
+#endif  // __VTS_SYSFUZZER_COMMON_SPECPARSER_SPECBUILDER_H__