Эх сурвалжийг харах

Add support for uploading metrics to the database (#2900)

* Add support for uploading metrics to the database

* Update the README to describe the database config

* Add comments to methods in Uploader

* Add copyright
Corrob 7 жил өмнө
parent
commit
a5a459e87f

+ 14 - 4
Metrics/README.md

@@ -3,15 +3,25 @@
 A swift utility for collecting project health metrics on Travis and uploading to a database. It
 currently only supports parsing a Code Coverage report generated from XCov.
 
-## Run the coverage parser
+## Run the metrics uploader
+
+Make sure that a valid database.config is in the current directory.
+
+```
+host:<Cloud SQL IP address>
+database:<Database Name>
+user:<Username>
+password:<Password>
+```
+
+Use the following commands to build and run.  This will parse the example coverage report and
+upload the results to the database.
 
 ```
 swift build
-.build/debug/Metrics -c=example_report.json -o=database.json -p=99
+.build/debug/Metrics -c Tests/MetricsTests/example_report.json -p 99
 ```
 
-This generates a database.json file that can be executed through a pre-existing Java uploader that
-will push the data to a Cloud SQL database.
 
 ## Run the unit tests
 

+ 2 - 12
Metrics/Sources/Metrics/main.swift

@@ -22,9 +22,6 @@ var flags = Flags()
 let coveragePath = flags.string("c",
                                 "coverage",
                                 description: "Required - The path of the JSON coverage report generated by XCov.")
-let outputPath = flags.string("o",
-                              "output",
-                              description: "Required - The path to write the database JSON info.")
 let pullRequest = flags.int("p",
                             "pull_request",
                             description: "Required - The number of the pull request that corresponds to this coverage run.")
@@ -34,10 +31,6 @@ do {
     print("Please specify the path of the JSON coverage report from XCov. -c or --coverage")
     exit(1)
   }
-  if !outputPath.wasSet {
-    print("Please specify output location for the database JSON file. -o or --output")
-    exit(1)
-  }
   if !pullRequest.wasSet {
     print("Please specify the corresponding pull request number. -p or --pull_request")
     exit(1)
@@ -48,11 +41,8 @@ do {
   let coverageReport = try CoverageReport.load(path: coveragePath.value!)
   let coverageTable = TableUpdate.createFrom(coverage: coverageReport,
                                              pullRequest: pullRequest.value!)
-  let json = try UploadMetrics(tables: [pullRequestTable, coverageTable]).json()
-  try json.write(to: NSURL(fileURLWithPath: outputPath.value!) as URL,
-                 atomically: false,
-                 encoding: .utf8)
-  print("Successfully created \(outputPath.value!)")
+  let metrics = UploadMetrics(tables: [pullRequestTable, coverageTable])
+  try Uploader.upload(metrics: metrics)
 } catch {
   print("Error occurred: \(error)")
   exit(1)

+ 66 - 0
Metrics/Sources/MetricsLib/Uploader.swift

@@ -0,0 +1,66 @@
+/*
+ * Copyright 2019 Google
+ *
+ * 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.
+ */
+
+import Foundation
+
+let JAR_URL = "https://storage.googleapis.com/firebase-engprod-metrics/upload_tool.jar"
+let JAR_LOCAL_PATH = "upload.jar"
+let DATABASE_CONFIG = "database.config"
+let JSON_PATH = "database.json"
+
+/// Uploads metrics to the Cloud SQL database.
+public class Uploader {
+  /// Uploads the provided metrics to the Cloud SQL database.
+  public class func upload(metrics: UploadMetrics) throws {
+    let jar = try downloadJar()
+    let json = try writeJson(metrics: metrics)
+
+    let returnCode = runJar(jar: jar, json: json, config: DATABASE_CONFIG)
+    if returnCode == 0 {
+      print("Successfully uploaded metrics!")
+    } else {
+      print("Failed to upload metrics... return code is \(returnCode).")
+    }
+
+    try FileManager.default.removeItem(atPath: jar)
+    try FileManager.default.removeItem(atPath: json)
+  }
+
+  /// Writes the metrics to a local file in a JSON format and returns that path.
+  private class func writeJson(metrics: UploadMetrics) throws -> String {
+    try metrics.json().write(to: NSURL(fileURLWithPath: JSON_PATH) as URL,
+                             atomically: false,
+                             encoding: .utf8)
+    return JSON_PATH
+  }
+
+  /// Downloads the uploader JAR and returns the path to it.
+  private class func downloadJar() throws -> String {
+    let jarData = try Data(contentsOf: URL(string: JAR_URL)!)
+    try jarData.write(to: NSURL(fileURLWithPath: JAR_LOCAL_PATH) as URL)
+    return JAR_LOCAL_PATH
+  }
+
+  /// Executes the uploader jar and returns the exit code.
+  private class func runJar(jar: String, json: String, config: String) -> Int32 {
+    let task = Process()
+    task.launchPath = "/usr/bin/java"
+    task.arguments = ["-jar", jar, "--json_path=\(json)", "--config_path=\(config)"]
+    task.launch()
+    task.waitUntilExit()
+    return task.terminationStatus
+  }
+}