diff options
author | Ryan Campbell <ryanjcampbell@google.com> | 2017-06-19 11:17:10 -0700 |
---|---|---|
committer | Ryan Campbell <ryanjcampbell@google.com> | 2017-06-19 12:26:07 -0700 |
commit | 67c9a5397bd972a173cdf08aaccba44678f3aea0 (patch) | |
tree | e02d3fa1d9c91d8cfaaef276c2b3ffb4c064a4b5 | |
parent | 7054de7189ba17d6516861e437b8f50fc837191d (diff) | |
download | dashboard-67c9a5397bd972a173cdf08aaccba44678f3aea0.tar.gz |
Move dashboard to test/vti.
Copy code from test/vts/web to test/vti/.
Bug: 62339915
Test: none
Change-Id: I6e07fbaca77018f6d7bd24bd3da9e3bbbafab495
89 files changed, 30852 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9a94e36 --- /dev/null +++ b/.gitignore @@ -0,0 +1,45 @@ +# Google App Engine generated folder +appengine-generated/ + +# Java +*.class + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +# maven +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties + +service-account.json + +# intellij +.idea/ +*.iml + +# Eclipse files +.project +.classpath +.settings + +# vim +[._]*.s[a-w][a-z] +[._]s[a-w][a-z] +Session.vim +.netrwhist +*~ +tags
\ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..9b6ca36 --- /dev/null +++ b/README.md @@ -0,0 +1,151 @@ +# VTS Dashboard + +## Introduction + +The VTS Dashboard displays the summarized results of the Multi Device Tests along with graphs. + +## Installation + +### Steps to run locally: + +1. Google App Engine uses Java 8. Install Java 8 before running running locally: + 'sudo apt install openjdk-8-jdk' + + To use java 8: + Copy the following lines in ~/.bashrc : + +``` + function setup_jdk() { + # Remove the current JDK from PATH + if [ -n "$JAVA_HOME" ] ; then + PATH=${PATH/$JAVA_HOME\/bin:/} + fi + export JAVA_HOME=$1 + export PATH=$JAVA_HOME/bin:$PATH + } + + function use_java8() { + # setup_jdk /usr/java/jre1.8.0_73 + setup_jdk /usr/lib/jvm/java-8-openjdk-amd64 + } + + Then from cmd: + $ use_java8 +``` + +2. Maven is used for build. Install Maven 3.3.9: + Download maven from: + https://maven.apache.org/download.cgi + + Steps to Install Maven: + 1) Unzip the Binary tar: + tar -zxf apache-maven-3.3.3-bin.tar.gz + + 2) Move the application directory to /usr/local + sudo cp -R apache-maven-3.3.3 /usr/local + + 3) Make a soft link in /usr/bin for universal access of mvn + sudo ln -s /usr/local/apache-maven-3.3.3/bin/mvn /usr/bin/mvn + + 4) Verify maven installation: + $ mvn -v + + The output should resemble this: + + Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-10T08:41:47-08:00) + Maven home: /opt/apache-maven-3.3.9 + Java version: 1.8.0_45-internal, vendor: Oracle Corporation + Java home: /usr/lib/jvm/java-8-openjdk-amd64/jre + Default locale: en_US, platform encoding: UTF-8 + OS name: "linux", version: "3.13.0-88-generic", arch: "amd64", family: "unix" + +3. Install Google Cloud SDK. Follow the instructions listed on official source: + https://cloud.google.com/sdk/docs/quickstart-linux + + The default location where the application searches for a google-cloud-sdk is: + /usr/local/share/google/google-cloud-sdk + + Therefore move the extracted folder to this location: /usr/local/share/google/ + + Otherwise, to have a custom location, specify the location of + google-cloud-sdk in test/vti/dashboard/pom.xml by putting the configuration: + +``` + <configuration> + <gcloud_directory>PATH/TO/GCLOUD_DIRECTORY</gcloud_directory> + </configuration> +``` + within the 'com.google.appengine' plugin tag : + +## To run GAE on local machine: + +$ cd test/vti/dashboard +$ mvn appengine:devserver + +## To deploy to Google App Engine + +$ cd test/vti/dashboard +$ mvn appengine:update + +visit https://<YOUR-PROJECT-NAME>.appspot.com + +## Monitoring + +The following steps list how to create a monitoring service for the VTS Dashboard. + +### Create a Stackdriver account + +1. Go to Google Cloud Platform Console: + http://console.developers.google.com + +2. In the Google Cloud Platform Console, select Stackdriver > Monitoring. + If your project is not in a Stackdriver account you'll see a message to + create a new project. + +3. Click Create new Stackdriver account and then Continue. + +4. With your project shown, click Create account. + +5. In the page, "Add Google Cloud Platform projects to monitor", click Continue to skip ahead. + +6. In the page, "Monitor AWS accounts", click Done to skip ahead. + +7. In a few seconds you see the following message: + "Finished Initial collection" + Click Launch Monitoring. + +8. In the page, "Get reports by email", click No reports and Continue. + +9. You will see your Stackdriver account dashboard. + Close the "Welcome to Stackdriver" banner if you don't need it. + +### Steps to create an uptime check and an alerting policy + +1. Go to Stack Monitoring console: + https://app.google.stackdriver.com/ + +2. Go to Alerting > Uptime Checks in the top menu and then click Add Uptime Check. + You see the New Uptime Check panel. + +3. Fill in the following fields for the uptime check: + + Check type: HTTP + Resource Type: Instance + Applies To: Single, lamp-1-vm + Leave the other fields with their default values. + +4. Click Test to verify your uptime check is working. + +5. Click Save. After you click on save you'll see a panel to + 'Create Alerting Policy' + +6. Fill out the configuration for notifications and click save policy. + +### Test the check and alert + +This procedure can take up to fifteen minutes. + +To test the check and alert, go to the VM Instances page, select your instance, and click Stop from the top menu. +You'll have to wait up to five minutes for the next uptime check to fail. The alert and notification don't happen until the next failure occurs. + +To correct the "problem," return to the VM Instances page, select your instance, and click Start from the top menu. @@ -0,0 +1,187 @@ +<!-- + Copyright 2016 Google Inc. + + 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. +--> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <packaging>war</packaging> + <version>1.0-SNAPSHOT</version> + <groupId>com.android.vts</groupId> + <artifactId>vts-dashboard</artifactId> + + <properties> + <appengine.clientID></appengine.clientID> + <appengine.serviceClientID></appengine.serviceClientID> + <appengine.senderEmail></appengine.senderEmail> + <appengine.emailDomain></appengine.emailDomain> + <appengine.defaultEmail></appengine.defaultEmail> + <gerrit.uri></gerrit.uri> + <gerrit.scope></gerrit.scope> + <analytics.id></analytics.id> + + <maven.compiler.target>1.7</maven.compiler.target> + <maven.compiler.source>1.7</maven.compiler.source> + <maven.war.filteringDeploymentDescriptors>true</maven.war.filteringDeploymentDescriptors> + + <failOnMissingWebXml>false</failOnMissingWebXml> + </properties> + + + <dependencies> + + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>servlet-api</artifactId> + <version>2.5</version> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>jsp-api</artifactId> + <version>2.0</version> + </dependency> + + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + <version>2.6</version> + </dependency> + + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-math3</artifactId> + <version>3.6.1</version> + </dependency> + + <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + <version>1.9</version> + </dependency> + + <dependency> + <groupId>com.google.cloud</groupId> + <artifactId>google-cloud</artifactId> + <version>0.8.0</version> + </dependency> + + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + <version>2.7</version> + </dependency> + + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + <version>2.8.6</version> + </dependency> + + <dependency> + <groupId>com.google.api-client</groupId> + <artifactId>google-api-client</artifactId> + <version>1.22.0</version> + <exclusions> + <exclusion> + <groupId>com.google.guava</groupId> + <artifactId>guava-jdk5</artifactId> + </exclusion> + </exclusions> + </dependency> + + <dependency> + <groupId>com.google.appengine</groupId> + <artifactId>appengine-api-1.0-sdk</artifactId> + <version>1.9.50</version> + </dependency> + + <dependency> + <groupId>com.google.apis</groupId> + <artifactId>google-api-services-oauth2</artifactId> + <version>v1-rev131-1.22.0</version> + </dependency> + + <!-- Test Dependencies --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.12</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.google.appengine</groupId> + <artifactId>appengine-testing</artifactId> + <version>1.9.50</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.google.appengine</groupId> + <artifactId>appengine-api-stubs</artifactId> + <version>1.9.50</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.google.appengine</groupId> + <artifactId>appengine-tools-sdk</artifactId> + <version>1.9.50</version> + <scope>test</scope> + </dependency> + + </dependencies> + + + <build> + <outputDirectory>${project.build.directory}/${project.build.finalName}/WEB-INF/classes</outputDirectory> + + <plugins> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-war-plugin</artifactId> + <version>2.6</version> + <configuration> + <archiveClasses>true</archiveClasses> + <failOnMissingWebXml>false</failOnMissingWebXml> + <webResources> + <resource> + <directory>${basedir}/src/main/webapp/WEB-INF</directory> + <filtering>true</filtering> + <targetPath>WEB-INF</targetPath> + </resource> + </webResources> + </configuration> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <version>3.3</version> + <artifactId>maven-compiler-plugin</artifactId> + <configuration> + <source>1.7</source> + <target>1.7</target> + </configuration> + </plugin> + + <plugin> + <groupId>com.google.appengine</groupId> + <artifactId>appengine-maven-plugin</artifactId> + <version>1.9.51</version> + </plugin> + + </plugins> + </build> +</project> diff --git a/src/main/java/com/android/vts/api/BigtableLegacyJsonServlet.java b/src/main/java/com/android/vts/api/BigtableLegacyJsonServlet.java new file mode 100644 index 0000000..d2b4a61 --- /dev/null +++ b/src/main/java/com/android/vts/api/BigtableLegacyJsonServlet.java @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.api; + +import com.android.vts.proto.VtsReportMessage.TestReportMessage; +import com.android.vts.util.DatastoreHelper; +import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; +import com.google.api.client.http.javanet.NetHttpTransport; +import com.google.api.client.json.jackson.JacksonFactory; +import com.google.api.services.oauth2.Oauth2; +import com.google.api.services.oauth2.model.Tokeninfo; +import com.google.protobuf.InvalidProtocolBufferException; +import java.io.BufferedReader; +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.codec.binary.Base64; +import org.json.JSONException; +import org.json.JSONObject; + +/** REST endpoint for posting data JSON to the Dashboard. */ +@Deprecated +public class BigtableLegacyJsonServlet extends HttpServlet { + private static final String SERVICE_CLIENT_ID = System.getProperty("SERVICE_CLIENT_ID"); + private static final String SERVICE_NAME = "VTS Dashboard"; + private static final Logger logger = + Logger.getLogger(BigtableLegacyJsonServlet.class.getName()); + + @Override + public void doPost(HttpServletRequest request, HttpServletResponse response) + throws IOException { + // Retrieve the params + String payload = new String(); + JSONObject payloadJson; + try { + String line = null; + BufferedReader reader = request.getReader(); + while ((line = reader.readLine()) != null) { + payload += line; + } + payloadJson = new JSONObject(payload); + } catch (IOException | JSONException e) { + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + logger.log(Level.WARNING, "Invalid JSON: " + payload); + return; + } + + // Verify service account access token. + boolean authorized = false; + if (payloadJson.has("accessToken")) { + String accessToken = payloadJson.getString("accessToken").trim(); + GoogleCredential credential = new GoogleCredential().setAccessToken(accessToken); + Oauth2 oauth2 = + new Oauth2.Builder(new NetHttpTransport(), new JacksonFactory(), credential) + .setApplicationName(SERVICE_NAME) + .build(); + Tokeninfo tokenInfo = oauth2.tokeninfo().setAccessToken(accessToken).execute(); + if (tokenInfo.getIssuedTo().equals(SERVICE_CLIENT_ID)) { + authorized = true; + } + } + + if (!authorized) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + return; + } + + // Parse the desired action and execute the command + try { + if (payloadJson.has("verb")) { + switch (payloadJson.getString("verb")) { + case "createTable": + logger.log(Level.INFO, "Deprecated verb: createTable."); + break; + case "insertRow": + insertData(payloadJson); + break; + default: + logger.log(Level.WARNING, + "Invalid Datastore REST verb: " + payloadJson.getString("verb")); + throw new IOException("Unsupported POST verb."); + } + } + } catch (IOException e) { + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + return; + } + response.setStatus(HttpServletResponse.SC_OK); + } + + /** + * Inserts a data into the Cloud Datastore + * + * @param payloadJson The JSON object representing the row to be inserted. Of the form: { + * (deprecated) 'tableName' : 'table', (deprecated) 'rowKey' : 'row', (deprecated) 'family' + * : + * 'family', (deprecated) 'qualifier' : 'qualifier', 'value' : 'value' } + * @throws IOException + */ + private void insertData(JSONObject payloadJson) throws IOException { + if (!payloadJson.has("value")) { + logger.log(Level.WARNING, "Missing attributes for datastore api insertRow()."); + return; + } + try { + byte[] value = Base64.decodeBase64(payloadJson.getString("value")); + TestReportMessage testReportMessage = TestReportMessage.parseFrom(value); + DatastoreHelper.insertTestReport(testReportMessage); + } catch (InvalidProtocolBufferException e) { + logger.log(Level.WARNING, "Invalid report posted to dashboard."); + } + } +} diff --git a/src/main/java/com/android/vts/api/DatastoreRestServlet.java b/src/main/java/com/android/vts/api/DatastoreRestServlet.java new file mode 100644 index 0000000..761c292 --- /dev/null +++ b/src/main/java/com/android/vts/api/DatastoreRestServlet.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.api; + +import com.android.vts.proto.VtsReportMessage.DashboardPostMessage; +import com.android.vts.proto.VtsReportMessage.TestPlanReportMessage; +import com.android.vts.proto.VtsReportMessage.TestReportMessage; +import com.android.vts.util.DatastoreHelper; +import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; +import com.google.api.client.http.javanet.NetHttpTransport; +import com.google.api.client.json.jackson.JacksonFactory; +import com.google.api.services.oauth2.Oauth2; +import com.google.api.services.oauth2.model.Tokeninfo; +import java.io.BufferedReader; +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.codec.binary.Base64; + +/** REST endpoint for posting data to the Dashboard. */ +public class DatastoreRestServlet extends HttpServlet { + private static final String SERVICE_CLIENT_ID = System.getProperty("SERVICE_CLIENT_ID"); + private static final String SERVICE_NAME = "VTS Dashboard"; + private static final Logger logger = Logger.getLogger(DatastoreRestServlet.class.getName()); + + @Override + public void doPost(HttpServletRequest request, HttpServletResponse response) + throws IOException { + // Retrieve the params + String payload = new String(); + DashboardPostMessage postMessage; + try { + String line = null; + BufferedReader reader = request.getReader(); + while ((line = reader.readLine()) != null) { + payload += line; + } + byte[] value = Base64.decodeBase64(payload); + postMessage = DashboardPostMessage.parseFrom(value); + } catch (IOException e) { + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + logger.log(Level.WARNING, "Invalid proto: " + payload); + return; + } + + // Verify service account access token. + boolean authorized = false; + if (postMessage.hasAccessToken()) { + String accessToken = postMessage.getAccessToken(); + GoogleCredential credential = new GoogleCredential().setAccessToken(accessToken); + Oauth2 oauth2 = + new Oauth2.Builder(new NetHttpTransport(), new JacksonFactory(), credential) + .setApplicationName(SERVICE_NAME) + .build(); + Tokeninfo tokenInfo = oauth2.tokeninfo().setAccessToken(accessToken).execute(); + if (tokenInfo.getIssuedTo().equals(SERVICE_CLIENT_ID)) { + authorized = true; + } + } + + if (!authorized) { + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + return; + } + + for (TestReportMessage testReportMessage : postMessage.getTestReportList()) { + DatastoreHelper.insertTestReport(testReportMessage); + } + + for (TestPlanReportMessage planReportMessage : postMessage.getTestPlanReportList()) { + DatastoreHelper.insertTestPlanReport(planReportMessage); + } + + response.setStatus(HttpServletResponse.SC_OK); + } +} diff --git a/src/main/java/com/android/vts/api/TestRunRestServlet.java b/src/main/java/com/android/vts/api/TestRunRestServlet.java new file mode 100644 index 0000000..ac84a3b --- /dev/null +++ b/src/main/java/com/android/vts/api/TestRunRestServlet.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2017 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.api; + +import com.android.vts.entity.TestCaseRunEntity; +import com.android.vts.entity.TestEntity; +import com.android.vts.entity.TestRunEntity; +import com.android.vts.util.TestRunDetails; +import com.google.appengine.api.datastore.DatastoreService; +import com.google.appengine.api.datastore.DatastoreServiceFactory; +import com.google.appengine.api.datastore.Entity; +import com.google.appengine.api.datastore.EntityNotFoundException; +import com.google.appengine.api.datastore.Key; +import com.google.appengine.api.datastore.KeyFactory; +import com.google.gson.Gson; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** Servlet for handling requests to fetch test case results. */ +public class TestRunRestServlet extends HttpServlet { + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { + String test = request.getParameter("test"); + String timeString = request.getParameter("timestamp"); + DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); + + long timestamp; + try { + timestamp = Long.parseLong(timeString); + if (timestamp <= 0) + throw new NumberFormatException(); + timestamp = timestamp > 0 ? timestamp : null; + } catch (NumberFormatException e) { + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + return; + } + + Key testKey = KeyFactory.createKey(TestEntity.KIND, test); + Key testRunKey = KeyFactory.createKey(testKey, TestRunEntity.KIND, timestamp); + TestRunEntity testRunEntity; + try { + Entity testRun = datastore.get(testRunKey); + testRunEntity = TestRunEntity.fromEntity(testRun); + if (testRunEntity == null) { + throw new EntityNotFoundException(testRunKey); + } + } catch (EntityNotFoundException e) { + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + return; + } + TestRunDetails details = new TestRunDetails(); + List<Key> gets = new ArrayList<>(); + for (long testCaseId : testRunEntity.testCaseIds) { + gets.add(KeyFactory.createKey(TestCaseRunEntity.KIND, testCaseId)); + } + Map<Key, Entity> entityMap = datastore.get(gets); + for (Key key : entityMap.keySet()) { + TestCaseRunEntity testCaseRun = TestCaseRunEntity.fromEntity(entityMap.get(key)); + if (testCaseRun == null) { + continue; + } + details.addTestCase(testCaseRun); + } + response.setContentType("application/json"); + PrintWriter writer = response.getWriter(); + writer.print(new Gson().toJson(details.toJson())); + writer.flush(); + } +} diff --git a/src/main/java/com/android/vts/api/UserFavoriteRestServlet.java b/src/main/java/com/android/vts/api/UserFavoriteRestServlet.java new file mode 100644 index 0000000..f863051 --- /dev/null +++ b/src/main/java/com/android/vts/api/UserFavoriteRestServlet.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2017 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.api; + +import com.android.vts.entity.TestEntity; +import com.android.vts.entity.UserFavoriteEntity; +import com.google.appengine.api.datastore.DatastoreService; +import com.google.appengine.api.datastore.DatastoreServiceFactory; +import com.google.appengine.api.datastore.Entity; +import com.google.appengine.api.datastore.EntityNotFoundException; +import com.google.appengine.api.datastore.Key; +import com.google.appengine.api.datastore.KeyFactory; +import com.google.appengine.api.datastore.Query; +import com.google.appengine.api.datastore.Transaction; +import com.google.appengine.api.datastore.Query.CompositeFilterOperator; +import com.google.appengine.api.datastore.Query.Filter; +import com.google.appengine.api.datastore.Query.FilterOperator; +import com.google.appengine.api.datastore.Query.FilterPredicate; +import com.google.appengine.api.users.User; +import com.google.appengine.api.users.UserService; +import com.google.appengine.api.users.UserServiceFactory; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** Servlet for handling requests to add or remove subscriptions. */ +public class UserFavoriteRestServlet extends HttpServlet { + protected static final Logger logger = + Logger.getLogger(UserFavoriteRestServlet.class.getName()); + + /** + * Add a test to the user's favorites. + */ + @Override + public void doPost(HttpServletRequest request, HttpServletResponse response) + throws IOException { + UserService userService = UserServiceFactory.getUserService(); + User currentUser = userService.getCurrentUser(); + DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); + + // Retrieve the added tests from the request. + String test = request.getPathInfo(); + if (test == null) { + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + return; + } + if (test.startsWith("/")) { + test = test.substring(1); + } + Key addedTestKey = KeyFactory.createKey(TestEntity.KIND, test); + // Filter the tests that exist from the set of tests to add + try { + datastore.get(addedTestKey); + } catch (EntityNotFoundException e) { + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + return; + } + + Filter userFilter = + new FilterPredicate(UserFavoriteEntity.USER, FilterOperator.EQUAL, currentUser); + Filter testFilter = new FilterPredicate( + UserFavoriteEntity.TEST_KEY, FilterOperator.EQUAL, addedTestKey); + Query q = new Query(UserFavoriteEntity.KIND) + .setFilter(CompositeFilterOperator.and(userFilter, testFilter)) + .setKeysOnly(); + + Key favoriteKey = null; + + Transaction txn = datastore.beginTransaction(); + try { + for (Entity e : datastore.prepare(q).asIterable()) { + favoriteKey = e.getKey(); + break; + } + if (favoriteKey == null) { + UserFavoriteEntity favorite = new UserFavoriteEntity(currentUser, addedTestKey); + Entity entity = favorite.toEntity(); + datastore.put(entity); + favoriteKey = entity.getKey(); + } + txn.commit(); + } finally { + if (txn.isActive()) { + logger.log(Level.WARNING, + "Transaction rollback forced for favorite creation: " + test); + txn.rollback(); + } + } + + response.setContentType("application/json"); + PrintWriter writer = response.getWriter(); + JsonObject json = new JsonObject(); + json.add("key", new JsonPrimitive(KeyFactory.keyToString(favoriteKey))); + writer.print(new Gson().toJson(json)); + writer.flush(); + response.setStatus(HttpServletResponse.SC_OK); + } + + /** + * Remove a test from the user's favorites. + */ + @Override + public void doDelete(HttpServletRequest request, HttpServletResponse response) + throws IOException { + DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); + String stringKey = request.getPathInfo(); + if (stringKey == null) { + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + return; + } + if (stringKey.startsWith("/")) { + stringKey = stringKey.substring(1); + } + datastore.delete(KeyFactory.stringToKey(stringKey)); + response.setStatus(HttpServletResponse.SC_OK); + } +} diff --git a/src/main/java/com/android/vts/entity/CoverageEntity.java b/src/main/java/com/android/vts/entity/CoverageEntity.java new file mode 100644 index 0000000..a0f8cca --- /dev/null +++ b/src/main/java/com/android/vts/entity/CoverageEntity.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2017 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.entity; + +import com.android.vts.proto.VtsReportMessage.CoverageReportMessage; +import com.google.appengine.api.datastore.Entity; +import com.google.appengine.api.datastore.Key; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** Object describing coverage data gathered for a file. */ +public class CoverageEntity implements DashboardEntity { + protected static final Logger logger = Logger.getLogger(CoverageEntity.class.getName()); + + public static final String KIND = "Coverage"; + + // Property keys + public static final String GROUP = "group"; + public static final String COVERED_LINE_COUNT = "coveredCount"; + public static final String TOTAL_LINE_COUNT = "totalCount"; + public static final String FILE_PATH = "filePath"; + public static final String PROJECT_NAME = "projectName"; + public static final String PROJECT_VERSION = "projectVersion"; + public static final String LINE_COVERAGE = "lineCoverage"; + + private final Key parentKey; + + public final String group; + public final long coveredLineCount; + public final long totalLineCount; + public final String filePath; + public final String projectName; + public final String projectVersion; + public final List<Long> lineCoverage; + + /** + * Create a CoverageEntity object for a file. + * + * @param parentKey The key to the parent TestRunEntity object in the database. + * @param group The group within the test run describing the coverage. + * @param coveredLineCount The total number of covered lines in the file. + * @param totalLineCount The total number of uncovered executable lines in the file. + * @param filePath The path to the file. + * @param projectName The name of the git project. + * @param projectVersion The commit hash of the project at the time the test was executed. + * @param lineCoverage List of coverage counts per executable line in the file. + */ + public CoverageEntity(Key parentKey, String group, long coveredLineCount, long totalLineCount, + String filePath, String projectName, String projectVersion, List<Long> lineCoverage) { + this.parentKey = parentKey; + this.group = group; + this.coveredLineCount = coveredLineCount; + this.totalLineCount = totalLineCount; + this.filePath = filePath; + this.projectName = projectName; + this.projectVersion = projectVersion; + this.lineCoverage = lineCoverage; + } + + @Override + public Entity toEntity() { + Entity coverageEntity = new Entity(KIND, parentKey); + coverageEntity.setProperty(GROUP, group); + coverageEntity.setUnindexedProperty(COVERED_LINE_COUNT, coveredLineCount); + coverageEntity.setUnindexedProperty(TOTAL_LINE_COUNT, totalLineCount); + coverageEntity.setProperty(FILE_PATH, filePath); + coverageEntity.setUnindexedProperty(PROJECT_NAME, projectName); + coverageEntity.setUnindexedProperty(PROJECT_VERSION, projectVersion); + if (lineCoverage != null && lineCoverage.size() > 0) { + coverageEntity.setUnindexedProperty(LINE_COVERAGE, lineCoverage); + } + return coverageEntity; + } + + /** + * Convert an Entity object to a CoverageEntity. + * + * @param e The entity to process. + * @return CoverageEntity object with the properties from e, or null if incompatible. + */ + @SuppressWarnings("unchecked") + public static CoverageEntity fromEntity(Entity e) { + if (!e.getKind().equals(KIND) || !e.hasProperty(GROUP) || !e.hasProperty(COVERED_LINE_COUNT) + || !e.hasProperty(TOTAL_LINE_COUNT) || !e.hasProperty(FILE_PATH) + || !e.hasProperty(PROJECT_NAME) || !e.hasProperty(PROJECT_VERSION)) { + logger.log(Level.WARNING, "Missing coverage attributes in entity: " + e.toString()); + return null; + } + try { + String group = (String) e.getProperty(GROUP); + long coveredLineCount = (long) e.getProperty(COVERED_LINE_COUNT); + long totalLineCount = (long) e.getProperty(TOTAL_LINE_COUNT); + String filePath = (String) e.getProperty(FILE_PATH); + String projectName = (String) e.getProperty(PROJECT_NAME); + String projectVersion = (String) e.getProperty(PROJECT_VERSION); + List<Long> lineCoverage; + if (e.hasProperty(LINE_COVERAGE)) { + lineCoverage = (List<Long>) e.getProperty(LINE_COVERAGE); + } else { + lineCoverage = new ArrayList<>(); + } + return new CoverageEntity(e.getKey().getParent(), group, coveredLineCount, + totalLineCount, filePath, projectName, projectVersion, lineCoverage); + } catch (ClassCastException exception) { + // Invalid contents or null values + logger.log(Level.WARNING, "Error parsing coverage entity.", exception); + } + return null; + } + + /** + * Convert a coverage report to a CoverageEntity. + * + * @param parentKey The ancestor key for the coverage entity. + * @param group The group to display the coverage report with. + * @param coverage The coverage report containing coverage data. + * @return The CoverageEntity for the coverage report message, or null if not compatible. + */ + public static CoverageEntity fromCoverageReport( + Key parentKey, String group, CoverageReportMessage coverage) { + if (!coverage.hasFilePath() || !coverage.hasProjectName() || !coverage.hasRevision() + || !coverage.hasTotalLineCount() || !coverage.hasCoveredLineCount()) { + return null; // invalid coverage report; + } + long coveredLineCount = coverage.getCoveredLineCount(); + long totalLineCount = coverage.getTotalLineCount(); + String filePath = coverage.getFilePath().toStringUtf8(); + String projectName = coverage.getProjectName().toStringUtf8(); + String projectVersion = coverage.getRevision().toStringUtf8(); + List<Long> lineCoverage = null; + if (coverage.getLineCoverageVectorCount() > 0) { + lineCoverage = new ArrayList<>(); + for (int count : coverage.getLineCoverageVectorList()) { + lineCoverage.add((long) count); + } + } + return new CoverageEntity(parentKey, group, coveredLineCount, totalLineCount, filePath, + projectName, projectVersion, lineCoverage); + } +} diff --git a/src/main/java/com/android/vts/entity/DashboardEntity.java b/src/main/java/com/android/vts/entity/DashboardEntity.java new file mode 100644 index 0000000..402a1e5 --- /dev/null +++ b/src/main/java/com/android/vts/entity/DashboardEntity.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2017 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.entity; + +import com.google.appengine.api.datastore.Entity; + +/** Interface for interacting with VTS Dashboard entities in Cloud Datastore. */ +public interface DashboardEntity { + /** + * Serialize the DashboardEntity to an Entity object. + * + * @return Entity object representing the properties defined in the DashboardEntity. + */ + public Entity toEntity(); +} diff --git a/src/main/java/com/android/vts/entity/DeviceInfoEntity.java b/src/main/java/com/android/vts/entity/DeviceInfoEntity.java new file mode 100644 index 0000000..ad4e83b --- /dev/null +++ b/src/main/java/com/android/vts/entity/DeviceInfoEntity.java @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2017 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.entity; + +import com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage; +import com.google.appengine.api.datastore.Entity; +import com.google.appengine.api.datastore.Key; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** Class describing a device used for a test run. */ +public class DeviceInfoEntity implements DashboardEntity { + protected static final Logger logger = Logger.getLogger(DeviceInfoEntity.class.getName()); + + public static final String KIND = "DeviceInfo"; + + // Property keys + public static final String BRANCH = "branch"; + public static final String PRODUCT = "product"; + public static final String BUILD_FLAVOR = "buildFlavor"; + public static final String BUILD_ID = "buildId"; + public static final String ABI_BITNESS = "abiBitness"; + public static final String ABI_NAME = "abiName"; + + private final Key parentKey; + + public final String branch; + public final String product; + public final String buildFlavor; + public final String buildId; + public final String abiBitness; + public final String abiName; + + /** + * Create a DeviceInfoEntity object. + * + * @param parentKey The key for the parent entity in the database. + * @param branch The build branch. + * @param product The device product. + * @param buildFlavor The device build flavor. + * @param buildID The device build ID. + * @param abiBitness The abi bitness of the device. + * @param abiName The name of the abi. + */ + public DeviceInfoEntity(Key parentKey, String branch, String product, String buildFlavor, + String buildID, String abiBitness, String abiName) { + this.parentKey = parentKey; + this.branch = branch; + this.product = product; + this.buildFlavor = buildFlavor; + this.buildId = buildID; + this.abiBitness = abiBitness; + this.abiName = abiName; + } + + @Override + public Entity toEntity() { + Entity deviceEntity = new Entity(KIND, this.parentKey); + deviceEntity.setProperty(BRANCH, this.branch.toLowerCase()); + deviceEntity.setProperty(PRODUCT, this.product.toLowerCase()); + deviceEntity.setProperty(BUILD_FLAVOR, this.buildFlavor.toLowerCase()); + deviceEntity.setProperty(BUILD_ID, this.buildId.toLowerCase()); + if (this.abiBitness != null && this.abiName != null) { + deviceEntity.setUnindexedProperty(ABI_BITNESS, this.abiBitness.toLowerCase()); + deviceEntity.setUnindexedProperty(ABI_NAME, this.abiName.toLowerCase()); + } + + return deviceEntity; + } + + /** + * Convert an Entity object to a DeviceInfoEntity. + * + * @param e The entity to process. + * @return DeviceInfoEntity object with the properties from e, or null if incompatible. + */ + public static DeviceInfoEntity fromEntity(Entity e) { + if (!e.getKind().equals(KIND) || !e.hasProperty(BRANCH) || !e.hasProperty(PRODUCT) + || !e.hasProperty(BUILD_FLAVOR) || !e.hasProperty(BUILD_ID) + || !e.hasProperty(ABI_BITNESS) || !e.hasProperty(ABI_NAME)) { + logger.log(Level.WARNING, "Missing device info attributes in entity: " + e.toString()); + return null; + } + try { + Key parentKey = e.getKey().getParent(); + String branch = (String) e.getProperty(BRANCH); + String product = (String) e.getProperty(PRODUCT); + String buildFlavor = (String) e.getProperty(BUILD_FLAVOR); + String buildId = (String) e.getProperty(BUILD_ID); + String abiBitness = null; + String abiName = null; + if (e.hasProperty(ABI_BITNESS) && e.hasProperty(ABI_NAME)) { + abiBitness = (String) e.getProperty(ABI_BITNESS); + abiName = (String) e.getProperty(ABI_NAME); + } + return new DeviceInfoEntity( + parentKey, branch, product, buildFlavor, buildId, abiBitness, abiName); + } catch (ClassCastException exception) { + // Invalid cast + logger.log(Level.WARNING, "Error parsing device info entity.", exception); + } + return null; + } + + /** + * Convert a device info message to a DeviceInfoEntity. + * + * @param parentKey The ancestor key for the device entity. + * @param device The device info report describing the target Android device. + * @return The DeviceInfoEntity for the target device, or null if incompatible + */ + public static DeviceInfoEntity fromDeviceInfoMessage( + Key parentKey, AndroidDeviceInfoMessage device) { + if (!device.hasBuildAlias() || !device.hasBuildFlavor() || !device.hasProductVariant() + || !device.hasBuildId()) { + return null; + } + String branch = device.getBuildAlias().toStringUtf8(); + String buildFlavor = device.getBuildFlavor().toStringUtf8(); + String product = device.getProductVariant().toStringUtf8(); + String buildId = device.getBuildId().toStringUtf8(); + String abiBitness = device.getAbiBitness().toStringUtf8(); + String abiName = device.getAbiName().toStringUtf8(); + return new DeviceInfoEntity( + parentKey, branch, product, buildFlavor, buildId, abiBitness, abiName); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof DeviceInfoEntity)) { + return false; + } + DeviceInfoEntity device2 = (DeviceInfoEntity) obj; + if (!this.branch.equals(device2.branch) || !this.product.equals(device2.product) + || !this.buildFlavor.equals(device2.buildFlavor) + || !this.buildId.equals(device2.buildId)) { + return false; + } + return true; + } + + @Override + public int hashCode() { + String deviceId = this.branch + this.product + this.buildFlavor + this.buildId; + return deviceId.hashCode(); + } + + /** + * Create a copy of the device info under a near parent. + * @param parentKey The new parent key. + * @return A copy of the DeviceInfoEntity with the specified parent. + */ + public DeviceInfoEntity copyWithParent(Key parentKey) { + return new DeviceInfoEntity(parentKey, this.branch, this.product, this.buildFlavor, + this.buildId, this.abiBitness, this.abiName); + } +} diff --git a/src/main/java/com/android/vts/entity/ProfilingPointRunEntity.java b/src/main/java/com/android/vts/entity/ProfilingPointRunEntity.java new file mode 100644 index 0000000..fdbbb29 --- /dev/null +++ b/src/main/java/com/android/vts/entity/ProfilingPointRunEntity.java @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2017 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.entity; + +import com.android.vts.proto.VtsReportMessage.ProfilingReportMessage; +import com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode; +import com.android.vts.proto.VtsReportMessage.VtsProfilingType; +import com.google.appengine.api.datastore.Entity; +import com.google.appengine.api.datastore.Key; +import com.google.protobuf.ByteString; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** Entity describing a profiling point execution. */ +public class ProfilingPointRunEntity implements DashboardEntity { + protected static final Logger logger = + Logger.getLogger(ProfilingPointRunEntity.class.getName()); + + public static final String KIND = "ProfilingPointRun"; + + // Property keys + public static final String TYPE = "type"; + public static final String REGRESSION_MODE = "regressionMode"; + public static final String LABELS = "labels"; + public static final String VALUES = "values"; + public static final String X_LABEL = "xLabel"; + public static final String Y_LABEL = "yLabel"; + public static final String OPTIONS = "options"; + + private final Key parentKey; + + public final String name; + public final VtsProfilingType type; + public final VtsProfilingRegressionMode regressionMode; + public final List<String> labels; + public final List<Long> values; + public final String xLabel; + public final String yLabel; + public final List<String> options; + + /** + * Create a ProfilingPointRunEntity object. + * + * @param parentKey The Key object for the parent TestRunEntity in the database. + * @param name The name of the profiling point. + * @param type The (number) type of the profiling point data. + * @param regressionMode The (number) mode to use for detecting regression. + * @param labels List of data labels, or null if the data is unlabeled. + * @param values List of data values. + * @param xLabel The x axis label. + * @param yLabel The y axis label. + * @param options The list of key=value options for the profiling point run. + */ + public ProfilingPointRunEntity(Key parentKey, String name, int type, int regressionMode, + List<String> labels, List<Long> values, String xLabel, String yLabel, + List<String> options) { + this.parentKey = parentKey; + this.name = name; + this.type = VtsProfilingType.valueOf(type); + this.regressionMode = VtsProfilingRegressionMode.valueOf(regressionMode); + this.labels = labels == null ? null : new ArrayList<>(labels); + this.values = new ArrayList<>(values); + this.xLabel = xLabel; + this.yLabel = yLabel; + this.options = options; + } + + @Override + public Entity toEntity() { + Entity profilingRun = new Entity(KIND, this.name, this.parentKey); + profilingRun.setUnindexedProperty(TYPE, this.type.getNumber()); + profilingRun.setUnindexedProperty(REGRESSION_MODE, this.regressionMode.getNumber()); + if (this.labels != null) { + profilingRun.setUnindexedProperty(LABELS, this.labels); + } + profilingRun.setUnindexedProperty(VALUES, this.values); + profilingRun.setUnindexedProperty(X_LABEL, this.xLabel); + profilingRun.setUnindexedProperty(Y_LABEL, this.yLabel); + if (this.options != null) { + profilingRun.setUnindexedProperty(OPTIONS, this.options); + } + + return profilingRun; + } + + /** + * Convert an Entity object to a ProflilingPointRunEntity. + * + * @param e The entity to process. + * @return ProfilingPointRunEntity object with the properties from e, or null if incompatible. + */ + @SuppressWarnings("unchecked") + public static ProfilingPointRunEntity fromEntity(Entity e) { + if (!e.getKind().equals(KIND) || e.getKey().getName() == null || !e.hasProperty(TYPE) + || !e.hasProperty(REGRESSION_MODE) || !e.hasProperty(VALUES) + || !e.hasProperty(X_LABEL) || !e.hasProperty(Y_LABEL)) { + logger.log( + Level.WARNING, "Missing profiling point attributes in entity: " + e.toString()); + return null; + } + try { + Key parentKey = e.getParent(); + String name = e.getKey().getName(); + int type = (int) (long) e.getProperty(TYPE); + int regressionMode = (int) (long) e.getProperty(REGRESSION_MODE); + List<Long> values = (List<Long>) e.getProperty(VALUES); + String xLabel = (String) e.getProperty(X_LABEL); + String yLabel = (String) e.getProperty(Y_LABEL); + List<String> labels = null; + if (e.hasProperty(LABELS)) { + labels = (List<String>) e.getProperty(LABELS); + } + List<String> options = null; + if (e.hasProperty(OPTIONS)) { + options = (List<String>) e.getProperty(OPTIONS); + } + return new ProfilingPointRunEntity( + parentKey, name, type, regressionMode, labels, values, xLabel, yLabel, options); + } catch (ClassCastException exception) { + // Invalid cast + logger.log(Level.WARNING, "Error parsing profiling point run entity.", exception); + } + return null; + } + + /** + * Convert a coverage report to a CoverageEntity. + * + * @param parentKey The ancestor key for the coverage entity. + * @param profilingReport The profiling report containing profiling data. + * @return The ProfilingPointRunEntity for the profiling report message, or null if incompatible + */ + public static ProfilingPointRunEntity fromProfilingReport( + Key parentKey, ProfilingReportMessage profilingReport) { + if (!profilingReport.hasName() || !profilingReport.hasType() + || profilingReport.getType() == VtsProfilingType.UNKNOWN_VTS_PROFILING_TYPE + || !profilingReport.hasRegressionMode() || !profilingReport.hasXAxisLabel() + || !profilingReport.hasYAxisLabel()) { + return null; // invalid profiling report; + } + String name = profilingReport.getName().toStringUtf8(); + VtsProfilingType type = profilingReport.getType(); + VtsProfilingRegressionMode regressionMode = profilingReport.getRegressionMode(); + String xLabel = profilingReport.getXAxisLabel().toStringUtf8(); + String yLabel = profilingReport.getYAxisLabel().toStringUtf8(); + List<Long> values; + List<String> labels = null; + switch (type) { + case VTS_PROFILING_TYPE_TIMESTAMP: + if (!profilingReport.hasStartTimestamp() || !profilingReport.hasEndTimestamp() + || profilingReport.getEndTimestamp() + < profilingReport.getStartTimestamp()) { + return null; // missing timestamp + } + long value = + profilingReport.getEndTimestamp() - profilingReport.getStartTimestamp(); + values = new ArrayList<>(); + values.add(value); + break; + case VTS_PROFILING_TYPE_LABELED_VECTOR: + if (profilingReport.getValueCount() != profilingReport.getLabelCount()) { + return null; // jagged data + } + labels = new ArrayList<>(); + for (ByteString label : profilingReport.getLabelList()) { + labels.add(label.toStringUtf8()); + } + values = profilingReport.getValueList(); + break; + case VTS_PROFILING_TYPE_UNLABELED_VECTOR: + values = profilingReport.getValueList(); + break; + default: // should never happen + return null; + } + List<String> options = null; + if (profilingReport.getOptionsCount() > 0) { + options = new ArrayList<>(); + for (ByteString optionBytes : profilingReport.getOptionsList()) { + options.add(optionBytes.toStringUtf8()); + } + } + return new ProfilingPointRunEntity(parentKey, name, type.getNumber(), + regressionMode.getNumber(), labels, values, xLabel, yLabel, options); + } +} diff --git a/src/main/java/com/android/vts/entity/TestCaseRunEntity.java b/src/main/java/com/android/vts/entity/TestCaseRunEntity.java new file mode 100644 index 0000000..02fac2d --- /dev/null +++ b/src/main/java/com/android/vts/entity/TestCaseRunEntity.java @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2017 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.entity; + +import com.google.appengine.api.datastore.Entity; +import com.google.appengine.api.datastore.Key; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** Entity describing the execution of a test case. */ +public class TestCaseRunEntity implements DashboardEntity { + protected static final Logger logger = Logger.getLogger(TestCaseRunEntity.class.getName()); + + public static final String KIND = "TestCaseRun"; + + // Property keys + public static final String TEST_CASE_NAME = "testCaseName"; + public static final String RESULT = "result"; + public static final String TEST_CASE_NAMES = "testCaseNames"; + public static final String RESULTS = "results"; + public static final String SYSTRACE_URL = "systraceUrl"; + + // Maximum number of test cases in the entity. + private static final int SIZE_LIMIT = 500; + + public final Key key; + public final List<TestCase> testCases; + private String systraceUrl; + + /** + * Class describing an individual test case run. + */ + public static class TestCase { + public final long parentId; + public final int offset; + public final String name; + public final int result; + + /** + * Create a test case run. + * @param parentId The ID of the TestCaseRunEntity containing the test case. + * @param offset The offset of the TestCase into the TestCaseRunEntity. + * @param name The name of the test case. + * @param result The result of the test case. + */ + public TestCase(long parentId, int offset, String name, int result) { + this.parentId = parentId; + this.offset = offset; + this.name = name; + this.result = result; + } + } + + /** + * Create a TestCaseRunEntity with the specified key. + * @param key The key to use for the entity in Cloud Datastore. + */ + public TestCaseRunEntity(Key key) { + this.key = key; + this.testCases = new ArrayList<>(); + this.systraceUrl = null; + } + + /** + * Determine if the TestCaseRunEntity is full. + * @return True if the entity is full, false otherwise. + */ + public boolean isFull() { + return this.testCases.size() >= SIZE_LIMIT; + } + + /** + * Set the systrace url. + * @param url The systrace url, or null. + */ + public void setSystraceUrl(String url) { + this.systraceUrl = url; + } + + /** + * Get the systrace url. + * returns The systrace url, or null. + */ + public String getSystraceUrl() { + return this.systraceUrl; + } + + /** + * Add a test case to the test case run entity. + * @param name The name of the test case. + * @param result The result of the test case. + * @return true if added, false otherwise. + */ + public boolean addTestCase(String name, int result) { + if (isFull()) + return false; + long parentId = this.key.getId(); + this.testCases.add(new TestCase(parentId, this.testCases.size(), name, result)); + return true; + } + + @Override + public Entity toEntity() { + Entity testCaseRunEntity = new Entity(key); + if (this.testCases.size() > 0) { + List<String> testCaseNames = new ArrayList<>(); + List<Integer> results = new ArrayList<>(); + for (TestCase testCase : this.testCases) { + testCaseNames.add(testCase.name); + results.add(testCase.result); + } + testCaseRunEntity.setUnindexedProperty(TEST_CASE_NAMES, testCaseNames); + testCaseRunEntity.setUnindexedProperty(RESULTS, results); + } + if (systraceUrl != null) { + testCaseRunEntity.setUnindexedProperty(SYSTRACE_URL, this.systraceUrl); + } + + return testCaseRunEntity; + } + + /** + * Convert an Entity object to a TestCaseRunEntity. + * + * @param e The entity to process. + * @return TestCaseRunEntity object with the properties from e, or null if incompatible. + */ + @SuppressWarnings("unchecked") + public static TestCaseRunEntity fromEntity(Entity e) { + if (!e.getKind().equals(KIND)) { + logger.log(Level.WARNING, "Wrong kind: " + e.getKey()); + return null; + } + try { + TestCaseRunEntity testCaseRun = new TestCaseRunEntity(e.getKey()); + if (e.hasProperty(TEST_CASE_NAMES) && e.hasProperty(RESULTS)) { + List<String> testCaseNames = (List<String>) e.getProperty(TEST_CASE_NAMES); + List<Long> results = (List<Long>) e.getProperty(RESULTS); + if (testCaseNames.size() == results.size()) { + for (int i = 0; i < testCaseNames.size(); i++) { + testCaseRun.addTestCase(testCaseNames.get(i), results.get(i).intValue()); + } + } + } + if (e.hasProperty(TEST_CASE_NAME) && e.hasProperty(RESULT)) { + testCaseRun.addTestCase( + (String) e.getProperty(TEST_CASE_NAME), (int) (long) e.getProperty(RESULT)); + } + if (e.hasProperty(SYSTRACE_URL)) { + String systraceUrl = (String) e.getProperty(SYSTRACE_URL); + testCaseRun.setSystraceUrl(systraceUrl); + } + return testCaseRun; + } catch (ClassCastException exception) { + // Invalid cast + logger.log(Level.WARNING, "Error parsing test case run entity.", exception); + } + return null; + } +} diff --git a/src/main/java/com/android/vts/entity/TestEntity.java b/src/main/java/com/android/vts/entity/TestEntity.java new file mode 100644 index 0000000..a5664f4 --- /dev/null +++ b/src/main/java/com/android/vts/entity/TestEntity.java @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2017 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.entity; + +import com.android.vts.entity.TestCaseRunEntity.TestCase; +import com.google.appengine.api.datastore.Entity; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** Entity describing test metadata. */ +public class TestEntity implements DashboardEntity { + protected static final Logger logger = Logger.getLogger(TestEntity.class.getName()); + + public static final String KIND = "Test"; + + // Property keys + public static final String PASS_COUNT = "passCount"; + public static final String FAIL_COUNT = "failCount"; + public static final String UPDATED_TIMESTAMP = "updatedTimestamp"; + + protected static final String FAILING_IDS = "failingTestcaseIds"; + protected static final String FAILING_OFFSETS = "failingTestcaseOffsets"; + + public final String testName; + public final int passCount; + public final int failCount; + public final long timestamp; + public final List<TestCaseReference> failingTestCases; + + /** + * Object representing a reference to a test case. + */ + public static class TestCaseReference { + public final long parentId; + public final int offset; + + /** + * Create a test case reference. + * @param parentId The ID of the TestCaseRunEntity containing the test case. + * @param offset The offset of the test case into the TestCaseRunEntity. + */ + public TestCaseReference(long parentId, int offset) { + this.parentId = parentId; + this.offset = offset; + } + + /** + * Create a test case reference. + * @param testCase The TestCase to reference. + */ + public TestCaseReference(TestCase testCase) { + this(testCase.parentId, testCase.offset); + } + } + + /** + * Create a TestEntity object with status metadata. + * + * @param testName The name of the test. + * @param timestamp The timestamp indicating the most recent test run event in the test state. + * @param passCount The number of tests passing up to the timestamp specified. + * @param failCount The number of tests failing up to the timestamp specified. + * @param failingTestCases The TestCaseReferences of the last observed failing test cases. + */ + public TestEntity(String testName, long timestamp, int passCount, int failCount, + List<TestCaseReference> failingTestCases) { + this.testName = testName; + this.timestamp = timestamp; + this.passCount = passCount; + this.failCount = failCount; + this.failingTestCases = failingTestCases; + } + + /** + * Create a TestEntity object without metadata. + * + * @param testName The name of the test. + */ + public TestEntity(String testName) { + this(testName, 0, -1, -1, new ArrayList<TestCaseReference>()); + } + + @Override + public Entity toEntity() { + Entity testEntity = new Entity(KIND, this.testName); + if (this.timestamp >= 0 && this.passCount >= 0 && this.failCount >= 0) { + testEntity.setProperty(UPDATED_TIMESTAMP, this.timestamp); + testEntity.setProperty(PASS_COUNT, this.passCount); + testEntity.setProperty(FAIL_COUNT, this.failCount); + if (this.failingTestCases.size() > 0) { + List<Long> failingTestcaseIds = new ArrayList<>(); + List<Integer> failingTestcaseOffsets = new ArrayList<>(); + for (TestCaseReference testCase : this.failingTestCases) { + failingTestcaseIds.add(testCase.parentId); + failingTestcaseOffsets.add(testCase.offset); + } + testEntity.setUnindexedProperty(FAILING_IDS, failingTestcaseIds); + testEntity.setUnindexedProperty(FAILING_OFFSETS, failingTestcaseOffsets); + } + } + return testEntity; + } + + /** + * Convert an Entity object to a TestEntity. + * + * @param e The entity to process. + * @return TestEntity object with the properties from e processed, or null if incompatible. + */ + @SuppressWarnings("unchecked") + public static TestEntity fromEntity(Entity e) { + if (!e.getKind().equals(KIND) || e.getKey().getName() == null) { + logger.log(Level.WARNING, "Missing test attributes in entity: " + e.toString()); + return null; + } + String testName = e.getKey().getName(); + long timestamp = 0; + int passCount = -1; + int failCount = -1; + List<TestCaseReference> failingTestCases = new ArrayList<>(); + try { + if (e.hasProperty(UPDATED_TIMESTAMP)) { + timestamp = (long) e.getProperty(UPDATED_TIMESTAMP); + } + if (e.hasProperty(PASS_COUNT)) { + passCount = ((Long) e.getProperty(PASS_COUNT)).intValue(); + } + if (e.hasProperty(FAIL_COUNT)) { + failCount = ((Long) e.getProperty(FAIL_COUNT)).intValue(); + } + if (e.hasProperty(FAILING_IDS) && e.hasProperty(FAILING_OFFSETS)) { + List<Long> ids = (List<Long>) e.getProperty(FAILING_IDS); + List<Long> offsets = (List<Long>) e.getProperty(FAILING_OFFSETS); + if (ids.size() == offsets.size()) { + for (int i = 0; i < ids.size(); i++) { + failingTestCases.add( + new TestCaseReference(ids.get(i), offsets.get(i).intValue())); + } + } + } + } catch (ClassCastException exception) { + // Invalid contents or null values + logger.log(Level.WARNING, "Error parsing test entity.", exception); + } + return new TestEntity(testName, timestamp, passCount, failCount, failingTestCases); + } +} diff --git a/src/main/java/com/android/vts/entity/TestPlanEntity.java b/src/main/java/com/android/vts/entity/TestPlanEntity.java new file mode 100644 index 0000000..82d7e5e --- /dev/null +++ b/src/main/java/com/android/vts/entity/TestPlanEntity.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2017 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.entity; + +import com.google.appengine.api.datastore.Entity; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** Entity describing test plan metadata. */ +public class TestPlanEntity implements DashboardEntity { + protected static final Logger logger = Logger.getLogger(TestPlanEntity.class.getName()); + + public static final String KIND = "TestPlan"; + + // Property keys + public static final String TEST_PLAN_NAME = "testPlanName"; + + public final String testPlanName; + + /** + * Create a TestPlanEntity object. + * + * @param testPlanName The name of the test plan. + */ + public TestPlanEntity(String testPlanName) { + this.testPlanName = testPlanName; + } + + @Override + public Entity toEntity() { + Entity planEntity = new Entity(KIND, this.testPlanName); + return planEntity; + } + + /** + * Convert an Entity object to a TestEntity. + * + * @param e The entity to process. + * @return TestEntity object with the properties from e processed, or null if incompatible. + */ + @SuppressWarnings("unchecked") + public static TestPlanEntity fromEntity(Entity e) { + if (!e.getKind().equals(KIND) || e.getKey().getName() == null + || !e.hasProperty(TEST_PLAN_NAME)) { + logger.log(Level.WARNING, "Missing test plan attributes in entity: " + e.toString()); + return null; + } + String testPlanName = e.getKey().getName(); + return new TestPlanEntity(testPlanName); + } +} diff --git a/src/main/java/com/android/vts/entity/TestPlanRunEntity.java b/src/main/java/com/android/vts/entity/TestPlanRunEntity.java new file mode 100644 index 0000000..cc161ac --- /dev/null +++ b/src/main/java/com/android/vts/entity/TestPlanRunEntity.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2017 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.entity; + +import com.android.vts.entity.TestRunEntity.TestRunType; +import com.google.appengine.api.datastore.Entity; +import com.google.appengine.api.datastore.Key; +import com.google.appengine.api.datastore.KeyFactory; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** Entity describing test plan run information. */ +public class TestPlanRunEntity implements DashboardEntity { + protected static final Logger logger = Logger.getLogger(TestPlanRunEntity.class.getName()); + + public static final String KIND = "TestPlanRun"; + + // Property keys + public static final String TEST_PLAN_NAME = "testPlanName"; + public static final String TYPE = "type"; + public static final String START_TIMESTAMP = "startTimestamp"; + public static final String END_TIMESTAMP = "endTimestamp"; + public static final String TEST_BUILD_ID = "testBuildId"; + public static final String PASS_COUNT = "passCount"; + public static final String FAIL_COUNT = "failCount"; + public static final String TEST_RUNS = "testRuns"; + + public final Key key; + public final String testPlanName; + public final TestRunType type; + public final long startTimestamp; + public final long endTimestamp; + public final String testBuildId; + public final long passCount; + public final long failCount; + public final List<Key> testRuns; + + /** + * Create a TestPlanRunEntity object describing a test plan run. + * + * @param parentKey The key for the parent entity in the database. + * @param type The test run type (e.g. presubmit, postsubmit, other) + * @param startTimestamp The time in microseconds when the test plan run started. + * @param endTimestamp The time in microseconds when the test plan run ended. + * @param testBuildId The build ID of the VTS test build. + * @param passCount The number of passing test cases in the run. + * @param failCount The number of failing test cases in the run. + * @param testRuns A list of keys to the TestRunEntity objects for the plan run run. + */ + public TestPlanRunEntity(Key parentKey, String testPlanName, TestRunType type, + long startTimestamp, long endTimestamp, String testBuildId, long passCount, + long failCount, List<Key> testRuns) { + this.key = KeyFactory.createKey(parentKey, KIND, startTimestamp); + this.testPlanName = testPlanName; + this.type = type; + this.startTimestamp = startTimestamp; + this.endTimestamp = endTimestamp; + this.testBuildId = testBuildId; + this.passCount = passCount; + this.failCount = failCount; + this.testRuns = testRuns; + } + + @Override + public Entity toEntity() { + Entity planRun = new Entity(this.key); + planRun.setProperty(TEST_PLAN_NAME, this.testPlanName); + planRun.setProperty(TYPE, this.type.getNumber()); + planRun.setProperty(START_TIMESTAMP, this.startTimestamp); + planRun.setProperty(END_TIMESTAMP, this.endTimestamp); + planRun.setProperty(TEST_BUILD_ID, this.testBuildId.toLowerCase()); + planRun.setProperty(PASS_COUNT, this.passCount); + planRun.setProperty(FAIL_COUNT, this.failCount); + if (this.testRuns != null && this.testRuns.size() > 0) { + planRun.setUnindexedProperty(TEST_RUNS, this.testRuns); + } + return planRun; + } + + /** + * Convert an Entity object to a TestPlanRunEntity. + * + * @param e The entity to process. + * @return TestPlanRunEntity object with the properties from e processed, or null if + * incompatible. + */ + @SuppressWarnings("unchecked") + public static TestPlanRunEntity fromEntity(Entity e) { + if (!e.getKind().equals(KIND) || !e.hasProperty(TEST_PLAN_NAME) || !e.hasProperty(TYPE) + || !e.hasProperty(START_TIMESTAMP) || !e.hasProperty(END_TIMESTAMP) + || !e.hasProperty(TEST_BUILD_ID) || !e.hasProperty(PASS_COUNT) + || !e.hasProperty(FAIL_COUNT) || !e.hasProperty(TEST_RUNS)) { + logger.log(Level.WARNING, "Missing test run attributes in entity: " + e.toString()); + return null; + } + try { + String testPlanName = (String) e.getProperty(TEST_PLAN_NAME); + TestRunType type = TestRunType.fromNumber((int) (long) e.getProperty(TYPE)); + long startTimestamp = (long) e.getProperty(START_TIMESTAMP); + long endTimestamp = (long) e.getProperty(END_TIMESTAMP); + String testBuildId = (String) e.getProperty(TEST_BUILD_ID); + long passCount = (long) e.getProperty(PASS_COUNT); + long failCount = (long) e.getProperty(FAIL_COUNT); + List<Key> testRuns = (List<Key>) e.getProperty(TEST_RUNS); + return new TestPlanRunEntity(e.getKey().getParent(), testPlanName, type, startTimestamp, + endTimestamp, testBuildId, passCount, failCount, testRuns); + } catch (ClassCastException exception) { + // Invalid cast + logger.log(Level.WARNING, "Error parsing test plan run entity.", exception); + } + return null; + } + + public JsonObject toJson() { + JsonObject json = new JsonObject(); + json.add(TEST_PLAN_NAME, new JsonPrimitive(this.testPlanName)); + json.add(TEST_BUILD_ID, new JsonPrimitive(this.testBuildId)); + json.add(PASS_COUNT, new JsonPrimitive(this.passCount)); + json.add(FAIL_COUNT, new JsonPrimitive(this.failCount)); + json.add(START_TIMESTAMP, new JsonPrimitive(this.startTimestamp)); + json.add(END_TIMESTAMP, new JsonPrimitive(this.endTimestamp)); + return json; + } +} diff --git a/src/main/java/com/android/vts/entity/TestRunEntity.java b/src/main/java/com/android/vts/entity/TestRunEntity.java new file mode 100644 index 0000000..8bb94a8 --- /dev/null +++ b/src/main/java/com/android/vts/entity/TestRunEntity.java @@ -0,0 +1,287 @@ +/* + * Copyright (c) 2017 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.entity; + +import com.android.vts.util.UrlUtil; +import com.android.vts.util.UrlUtil.LinkDisplay; +import com.google.appengine.api.datastore.Entity; +import com.google.appengine.api.datastore.Key; +import com.google.appengine.api.datastore.KeyFactory; +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** Entity describing test run information. */ +public class TestRunEntity implements DashboardEntity { + protected static final Logger logger = Logger.getLogger(TestRunEntity.class.getName()); + + /** Enum for classifying test run types. */ + public enum TestRunType { + OTHER(0), + PRESUBMIT(1), + POSTSUBMIT(2); + + private final int value; + + private TestRunType(int value) { + this.value = value; + } + + /** + * Get the ordinal representation of the type. + * + * @return The value associated with the test run type. + */ + public int getNumber() { + return value; + } + + /** + * Convert an ordinal value to a TestRunType. + * + * @param value The orginal value to parse. + * @return a TestRunType value. + */ + public static TestRunType fromNumber(int value) { + if (value == 1) { + return TestRunType.PRESUBMIT; + } else if (value == 2) { + return TestRunType.POSTSUBMIT; + } else { + return TestRunType.OTHER; + } + } + + /** + * Determine the test run type based on the build ID. + * + * Postsubmit runs are expected to have integer build IDs, while presubmit runs are integers + * prefixed by the character P. All other runs (e.g. local builds) are classified as OTHER. + * + * @param buildId The build ID. + * @return the TestRunType. + */ + public static TestRunType fromBuildId(String buildId) { + try { + Integer.parseInt(buildId); + return TestRunType.POSTSUBMIT; + } catch (NumberFormatException e) { + // Not an integer + } + if (Character.toLowerCase(buildId.charAt(0)) == 'p') { + try { + Integer.parseInt(buildId.substring(1)); + return TestRunType.PRESUBMIT; + } catch (NumberFormatException e) { + // Not an integer + } + } + return TestRunType.OTHER; + } + } + + public static final String KIND = "TestRun"; + + // Property keys + public static final String TEST_NAME = "testName"; + public static final String TYPE = "type"; + public static final String START_TIMESTAMP = "startTimestamp"; + public static final String END_TIMESTAMP = "endTimestamp"; + public static final String TEST_BUILD_ID = "testBuildId"; + public static final String HOST_NAME = "hostName"; + public static final String PASS_COUNT = "passCount"; + public static final String FAIL_COUNT = "failCount"; + public static final String TEST_CASE_IDS = "testCaseIds"; + public static final String LOG_LINKS = "logLinks"; + public static final String HAS_COVERAGE = "hasCoverage"; + public static final String TOTAL_LINE_COUNT = "totalLineCount"; + public static final String COVERED_LINE_COUNT = "coveredLineCount"; + + public final Key key; + public final TestRunType type; + public final long startTimestamp; + public final long endTimestamp; + public final String testBuildId; + public final String hostName; + public final long passCount; + public final long failCount; + public final boolean hasCoverage; + public final long coveredLineCount; + public final long totalLineCount; + public final List<Long> testCaseIds; + public final List<String> logLinks; + + /** + * Create a TestRunEntity object describing a test run. + * + * @param parentKey The key to the parent TestEntity. + * @param type The test run type (e.g. presubmit, postsubmit, other) + * @param startTimestamp The time in microseconds when the test run started. + * @param endTimestamp The time in microseconds when the test run ended. + * @param testBuildId The build ID of the VTS test build. + * @param hostName The name of host machine. + * @param passCount The number of passing test cases in the run. + * @param failCount The number of failing test cases in the run. + * @param testCaseIds A list of key IDs to the TestCaseRunEntity objects for the test run. + * @param logLinks A list of links to log files for the test run, or null if there aren't any. + * @param coveredLineCount The number of lines covered by the test run. + * @param totalLineCount The total number of executable lines by the test in the test run. + */ + public TestRunEntity(Key parentKey, TestRunType type, long startTimestamp, long endTimestamp, + String testBuildId, String hostName, long passCount, long failCount, + List<Long> testCaseIds, List<String> logLinks, long coveredLineCount, + long totalLineCount) { + this.key = KeyFactory.createKey(parentKey, KIND, startTimestamp); + this.type = type; + this.startTimestamp = startTimestamp; + this.endTimestamp = endTimestamp; + this.testBuildId = testBuildId; + this.hostName = hostName; + this.passCount = passCount; + this.failCount = failCount; + this.testCaseIds = testCaseIds; + this.logLinks = logLinks; + this.coveredLineCount = coveredLineCount; + this.totalLineCount = totalLineCount; + this.hasCoverage = totalLineCount > 0; + } + + /** + * Create a TestRunEntity object describing a test run. + * + * @param parentKey The key to the parent TestEntity. + * @param type The test run type (e.g. presubmit, postsubmit, other) + * @param startTimestamp The time in microseconds when the test run started. + * @param endTimestamp The time in microseconds when the test run ended. + * @param testBuildId The build ID of the VTS test build. + * @param hostName The name of host machine. + * @param passCount The number of passing test cases in the run. + * @param failCount The number of failing test cases in the run. + * @param testCaseIds A list of key IDs to the TestCaseRunEntity objects for the test run. + * @param logLinks A list of links to log files for the test run, or null if there aren't any. + */ + public TestRunEntity(Key parentKey, TestRunType type, long startTimestamp, long endTimestamp, + String testBuildId, String hostName, long passCount, long failCount, + List<Long> testCaseIds, List<String> logLinks) { + this(parentKey, type, startTimestamp, endTimestamp, testBuildId, hostName, passCount, + failCount, testCaseIds, logLinks, 0, 0); + } + + @Override + public Entity toEntity() { + Entity testRunEntity = new Entity(this.key); + testRunEntity.setProperty(TEST_NAME, this.key.getParent().getName()); + testRunEntity.setProperty(TYPE, this.type.getNumber()); + testRunEntity.setProperty(START_TIMESTAMP, this.startTimestamp); + testRunEntity.setUnindexedProperty(END_TIMESTAMP, this.endTimestamp); + testRunEntity.setProperty(TEST_BUILD_ID, this.testBuildId.toLowerCase()); + testRunEntity.setProperty(HOST_NAME, this.hostName.toLowerCase()); + testRunEntity.setProperty(PASS_COUNT, this.passCount); + testRunEntity.setProperty(FAIL_COUNT, this.failCount); + testRunEntity.setUnindexedProperty(TEST_CASE_IDS, this.testCaseIds); + boolean hasCoverage = this.totalLineCount > 0 && this.coveredLineCount >= 0; + testRunEntity.setProperty(HAS_COVERAGE, hasCoverage); + if (hasCoverage) { + testRunEntity.setProperty(COVERED_LINE_COUNT, this.coveredLineCount); + testRunEntity.setProperty(TOTAL_LINE_COUNT, this.totalLineCount); + } + if (this.logLinks != null && this.logLinks.size() > 0) { + testRunEntity.setUnindexedProperty(LOG_LINKS, this.logLinks); + } + return testRunEntity; + } + + /** + * Convert an Entity object to a TestRunEntity. + * + * @param e The entity to process. + * @return TestRunEntity object with the properties from e processed, or null if incompatible. + */ + @SuppressWarnings("unchecked") + public static TestRunEntity fromEntity(Entity e) { + if (!e.getKind().equals(KIND) || !e.hasProperty(TYPE) || !e.hasProperty(START_TIMESTAMP) + || !e.hasProperty(END_TIMESTAMP) || !e.hasProperty(TEST_BUILD_ID) + || !e.hasProperty(HOST_NAME) || !e.hasProperty(PASS_COUNT) + || !e.hasProperty(FAIL_COUNT) || !e.hasProperty(TEST_CASE_IDS)) { + logger.log(Level.WARNING, "Missing test run attributes in entity: " + e.toString()); + return null; + } + try { + TestRunType type = TestRunType.fromNumber((int) (long) e.getProperty(TYPE)); + long startTimestamp = (long) e.getProperty(START_TIMESTAMP); + long endTimestamp = (long) e.getProperty(END_TIMESTAMP); + String testBuildId = (String) e.getProperty(TEST_BUILD_ID); + String hostName = (String) e.getProperty(HOST_NAME); + long passCount = (long) e.getProperty(PASS_COUNT); + long failCount = (long) e.getProperty(FAIL_COUNT); + List<Long> testCaseIds = (List<Long>) e.getProperty(TEST_CASE_IDS); + List<String> logLinks = null; + long coveredLineCount = 0; + long totalLineCount = 0; + if (e.hasProperty(TOTAL_LINE_COUNT) && e.hasProperty(COVERED_LINE_COUNT)) { + coveredLineCount = (long) e.getProperty(COVERED_LINE_COUNT); + totalLineCount = (long) e.getProperty(TOTAL_LINE_COUNT); + } + if (e.hasProperty(LOG_LINKS)) { + logLinks = (List<String>) e.getProperty(LOG_LINKS); + } + return new TestRunEntity(e.getKey().getParent(), type, startTimestamp, endTimestamp, + testBuildId, hostName, passCount, failCount, testCaseIds, logLinks, + coveredLineCount, totalLineCount); + } catch (ClassCastException exception) { + // Invalid cast + logger.log(Level.WARNING, "Error parsing test run entity.", exception); + } + return null; + } + + public JsonObject toJson() { + JsonObject json = new JsonObject(); + json.add(TEST_NAME, new JsonPrimitive(this.key.getParent().getName())); + json.add(TEST_BUILD_ID, new JsonPrimitive(this.testBuildId)); + json.add(HOST_NAME, new JsonPrimitive(this.hostName)); + json.add(PASS_COUNT, new JsonPrimitive(this.passCount)); + json.add(FAIL_COUNT, new JsonPrimitive(this.failCount)); + json.add(START_TIMESTAMP, new JsonPrimitive(this.startTimestamp)); + json.add(END_TIMESTAMP, new JsonPrimitive(this.endTimestamp)); + if (this.totalLineCount > 0 && this.coveredLineCount >= 0) { + json.add(COVERED_LINE_COUNT, new JsonPrimitive(this.coveredLineCount)); + json.add(TOTAL_LINE_COUNT, new JsonPrimitive(this.totalLineCount)); + } + if (this.logLinks != null && this.logLinks.size() > 0) { + List<JsonElement> links = new ArrayList<>(); + for (String rawUrl : this.logLinks) { + LinkDisplay validatedLink = UrlUtil.processUrl(rawUrl); + if (validatedLink == null) { + logger.log(Level.WARNING, "Invalid logging URL : " + rawUrl); + continue; + } + String[] logInfo = new String[] {validatedLink.name, validatedLink.url}; + links.add(new Gson().toJsonTree(logInfo)); + } + if (links.size() > 0) { + json.add(LOG_LINKS, new Gson().toJsonTree(links)); + } + } + return json; + } +} diff --git a/src/main/java/com/android/vts/entity/UserFavoriteEntity.java b/src/main/java/com/android/vts/entity/UserFavoriteEntity.java new file mode 100644 index 0000000..a2820a6 --- /dev/null +++ b/src/main/java/com/android/vts/entity/UserFavoriteEntity.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2017 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.entity; + +import com.google.appengine.api.datastore.Entity; +import com.google.appengine.api.datastore.Key; +import com.google.appengine.api.users.User; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** Entity describing subscriptions between a user and a test. */ +public class UserFavoriteEntity implements DashboardEntity { + protected static final Logger logger = Logger.getLogger(UserFavoriteEntity.class.getName()); + + public static final String KIND = "UserFavorite"; + + // Property keys + public static final String USER = "user"; + public static final String TEST_KEY = "testKey"; + + public final User user; + public final Key testKey; + + /** + * Create a user favorite relationship. + * + * @param user The User object for the subscribing user. + * @param testKey The key of the TestEntity object describing the test. + */ + public UserFavoriteEntity(User user, Key testKey) { + this.user = user; + this.testKey = testKey; + } + + @Override + public Entity toEntity() { + Entity favoriteEntity = new Entity(KIND); + favoriteEntity.setProperty(USER, this.user); + favoriteEntity.setProperty(TEST_KEY, this.testKey); + return favoriteEntity; + } + + /** + * Convert an Entity object to a UserFavoriteEntity. + * + * @param e The entity to process. + * @return UserFavoriteEntity object with the properties from e, or null if incompatible. + */ + public static UserFavoriteEntity fromEntity(Entity e) { + if (!e.getKind().equals(KIND) || !e.hasProperty(USER) || !e.hasProperty(TEST_KEY)) { + logger.log( + Level.WARNING, "Missing user favorite attributes in entity: " + e.toString()); + return null; + } + try { + User user = (User) e.getProperty(USER); + Key testKey = (Key) e.getProperty(TEST_KEY); + return new UserFavoriteEntity(user, testKey); + } catch (ClassCastException exception) { + // Invalid cast + logger.log(Level.WARNING, "Error parsing user favorite entity.", exception); + } + return null; + } +} diff --git a/src/main/java/com/android/vts/proto/VtsReportMessage.java b/src/main/java/com/android/vts/proto/VtsReportMessage.java new file mode 100644 index 0000000..ac80e86 --- /dev/null +++ b/src/main/java/com/android/vts/proto/VtsReportMessage.java @@ -0,0 +1,18604 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: proto/VtsReportMessage.proto + +package com.android.vts.proto; + +public final class VtsReportMessage { + private VtsReportMessage() {} + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistry registry) { + } + /** + * Protobuf enum {@code android.vts.TestCaseResult} + * + * <pre> + * To specify test case execution result. + * </pre> + */ + public enum TestCaseResult + implements com.google.protobuf.ProtocolMessageEnum { + /** + * <code>UNKNOWN_RESULT = 0;</code> + */ + UNKNOWN_RESULT(0, 0), + /** + * <code>TEST_CASE_RESULT_PASS = 1;</code> + */ + TEST_CASE_RESULT_PASS(1, 1), + /** + * <code>TEST_CASE_RESULT_FAIL = 2;</code> + */ + TEST_CASE_RESULT_FAIL(2, 2), + /** + * <code>TEST_CASE_RESULT_SKIP = 3;</code> + */ + TEST_CASE_RESULT_SKIP(3, 3), + /** + * <code>TEST_CASE_RESULT_EXCEPTION = 4;</code> + */ + TEST_CASE_RESULT_EXCEPTION(4, 4), + /** + * <code>TEST_CASE_RESULT_TIMEOUT = 5;</code> + */ + TEST_CASE_RESULT_TIMEOUT(5, 5), + ; + + /** + * <code>UNKNOWN_RESULT = 0;</code> + */ + public static final int UNKNOWN_RESULT_VALUE = 0; + /** + * <code>TEST_CASE_RESULT_PASS = 1;</code> + */ + public static final int TEST_CASE_RESULT_PASS_VALUE = 1; + /** + * <code>TEST_CASE_RESULT_FAIL = 2;</code> + */ + public static final int TEST_CASE_RESULT_FAIL_VALUE = 2; + /** + * <code>TEST_CASE_RESULT_SKIP = 3;</code> + */ + public static final int TEST_CASE_RESULT_SKIP_VALUE = 3; + /** + * <code>TEST_CASE_RESULT_EXCEPTION = 4;</code> + */ + public static final int TEST_CASE_RESULT_EXCEPTION_VALUE = 4; + /** + * <code>TEST_CASE_RESULT_TIMEOUT = 5;</code> + */ + public static final int TEST_CASE_RESULT_TIMEOUT_VALUE = 5; + + + public final int getNumber() { return value; } + + public static TestCaseResult valueOf(int value) { + switch (value) { + case 0: return UNKNOWN_RESULT; + case 1: return TEST_CASE_RESULT_PASS; + case 2: return TEST_CASE_RESULT_FAIL; + case 3: return TEST_CASE_RESULT_SKIP; + case 4: return TEST_CASE_RESULT_EXCEPTION; + case 5: return TEST_CASE_RESULT_TIMEOUT; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap<TestCaseResult> + internalGetValueMap() { + return internalValueMap; + } + private static com.google.protobuf.Internal.EnumLiteMap<TestCaseResult> + internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap<TestCaseResult>() { + public TestCaseResult findValueByNumber(int number) { + return TestCaseResult.valueOf(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(index); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return com.android.vts.proto.VtsReportMessage.getDescriptor().getEnumTypes().get(0); + } + + private static final TestCaseResult[] VALUES = values(); + + public static TestCaseResult valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + return VALUES[desc.getIndex()]; + } + + private final int index; + private final int value; + + private TestCaseResult(int index, int value) { + this.index = index; + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:android.vts.TestCaseResult) + } + + /** + * Protobuf enum {@code android.vts.VtsTestType} + * + * <pre> + * To specify the VTS test type. + * </pre> + */ + public enum VtsTestType + implements com.google.protobuf.ProtocolMessageEnum { + /** + * <code>UNKNOWN_VTS_TESTTYPE = 0;</code> + */ + UNKNOWN_VTS_TESTTYPE(0, 0), + /** + * <code>VTS_HOST_DRIVEN_STRUCTURAL = 1;</code> + */ + VTS_HOST_DRIVEN_STRUCTURAL(1, 1), + /** + * <code>VTS_HOST_DRIVEN_FUZZING = 2;</code> + */ + VTS_HOST_DRIVEN_FUZZING(2, 2), + /** + * <code>VTS_TARGET_SIDE_GTEST = 3;</code> + */ + VTS_TARGET_SIDE_GTEST(3, 3), + /** + * <code>VTS_TARGET_SIDE_FUZZING = 4;</code> + */ + VTS_TARGET_SIDE_FUZZING(4, 4), + ; + + /** + * <code>UNKNOWN_VTS_TESTTYPE = 0;</code> + */ + public static final int UNKNOWN_VTS_TESTTYPE_VALUE = 0; + /** + * <code>VTS_HOST_DRIVEN_STRUCTURAL = 1;</code> + */ + public static final int VTS_HOST_DRIVEN_STRUCTURAL_VALUE = 1; + /** + * <code>VTS_HOST_DRIVEN_FUZZING = 2;</code> + */ + public static final int VTS_HOST_DRIVEN_FUZZING_VALUE = 2; + /** + * <code>VTS_TARGET_SIDE_GTEST = 3;</code> + */ + public static final int VTS_TARGET_SIDE_GTEST_VALUE = 3; + /** + * <code>VTS_TARGET_SIDE_FUZZING = 4;</code> + */ + public static final int VTS_TARGET_SIDE_FUZZING_VALUE = 4; + + + public final int getNumber() { return value; } + + public static VtsTestType valueOf(int value) { + switch (value) { + case 0: return UNKNOWN_VTS_TESTTYPE; + case 1: return VTS_HOST_DRIVEN_STRUCTURAL; + case 2: return VTS_HOST_DRIVEN_FUZZING; + case 3: return VTS_TARGET_SIDE_GTEST; + case 4: return VTS_TARGET_SIDE_FUZZING; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap<VtsTestType> + internalGetValueMap() { + return internalValueMap; + } + private static com.google.protobuf.Internal.EnumLiteMap<VtsTestType> + internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap<VtsTestType>() { + public VtsTestType findValueByNumber(int number) { + return VtsTestType.valueOf(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(index); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return com.android.vts.proto.VtsReportMessage.getDescriptor().getEnumTypes().get(1); + } + + private static final VtsTestType[] VALUES = values(); + + public static VtsTestType valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + return VALUES[desc.getIndex()]; + } + + private final int index; + private final int value; + + private VtsTestType(int index, int value) { + this.index = index; + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:android.vts.VtsTestType) + } + + /** + * Protobuf enum {@code android.vts.VtsProfilingRegressionMode} + */ + public enum VtsProfilingRegressionMode + implements com.google.protobuf.ProtocolMessageEnum { + /** + * <code>UNKNOWN_REGRESSION_MODE = 0;</code> + */ + UNKNOWN_REGRESSION_MODE(0, 0), + /** + * <code>VTS_REGRESSION_MODE_DISABLED = 1;</code> + * + * <pre> + * disable analysis + * </pre> + */ + VTS_REGRESSION_MODE_DISABLED(1, 1), + /** + * <code>VTS_REGRESSION_MODE_INCREASING = 2;</code> + * + * <pre> + * interpret increases in values as regression + * </pre> + */ + VTS_REGRESSION_MODE_INCREASING(2, 2), + /** + * <code>VTS_REGRESSION_MODE_DECREASING = 3;</code> + * + * <pre> + * interpret decreases in values as regression + * </pre> + */ + VTS_REGRESSION_MODE_DECREASING(3, 3), + ; + + /** + * <code>UNKNOWN_REGRESSION_MODE = 0;</code> + */ + public static final int UNKNOWN_REGRESSION_MODE_VALUE = 0; + /** + * <code>VTS_REGRESSION_MODE_DISABLED = 1;</code> + * + * <pre> + * disable analysis + * </pre> + */ + public static final int VTS_REGRESSION_MODE_DISABLED_VALUE = 1; + /** + * <code>VTS_REGRESSION_MODE_INCREASING = 2;</code> + * + * <pre> + * interpret increases in values as regression + * </pre> + */ + public static final int VTS_REGRESSION_MODE_INCREASING_VALUE = 2; + /** + * <code>VTS_REGRESSION_MODE_DECREASING = 3;</code> + * + * <pre> + * interpret decreases in values as regression + * </pre> + */ + public static final int VTS_REGRESSION_MODE_DECREASING_VALUE = 3; + + + public final int getNumber() { return value; } + + public static VtsProfilingRegressionMode valueOf(int value) { + switch (value) { + case 0: return UNKNOWN_REGRESSION_MODE; + case 1: return VTS_REGRESSION_MODE_DISABLED; + case 2: return VTS_REGRESSION_MODE_INCREASING; + case 3: return VTS_REGRESSION_MODE_DECREASING; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap<VtsProfilingRegressionMode> + internalGetValueMap() { + return internalValueMap; + } + private static com.google.protobuf.Internal.EnumLiteMap<VtsProfilingRegressionMode> + internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap<VtsProfilingRegressionMode>() { + public VtsProfilingRegressionMode findValueByNumber(int number) { + return VtsProfilingRegressionMode.valueOf(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(index); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return com.android.vts.proto.VtsReportMessage.getDescriptor().getEnumTypes().get(2); + } + + private static final VtsProfilingRegressionMode[] VALUES = values(); + + public static VtsProfilingRegressionMode valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + return VALUES[desc.getIndex()]; + } + + private final int index; + private final int value; + + private VtsProfilingRegressionMode(int index, int value) { + this.index = index; + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:android.vts.VtsProfilingRegressionMode) + } + + /** + * Protobuf enum {@code android.vts.VtsProfilingType} + */ + public enum VtsProfilingType + implements com.google.protobuf.ProtocolMessageEnum { + /** + * <code>UNKNOWN_VTS_PROFILING_TYPE = 0;</code> + */ + UNKNOWN_VTS_PROFILING_TYPE(0, 0), + /** + * <code>VTS_PROFILING_TYPE_TIMESTAMP = 1;</code> + * + * <pre> + * for one sample which measures the time between two profiling points. + * </pre> + */ + VTS_PROFILING_TYPE_TIMESTAMP(1, 1), + /** + * <code>VTS_PROFILING_TYPE_LABELED_VECTOR = 2;</code> + * + * <pre> + * for multiple single-type samples with labels. + * </pre> + */ + VTS_PROFILING_TYPE_LABELED_VECTOR(2, 2), + /** + * <code>VTS_PROFILING_TYPE_UNLABELED_VECTOR = 3;</code> + * + * <pre> + * for multiple single-type samples without labels. + * </pre> + */ + VTS_PROFILING_TYPE_UNLABELED_VECTOR(3, 3), + ; + + /** + * <code>UNKNOWN_VTS_PROFILING_TYPE = 0;</code> + */ + public static final int UNKNOWN_VTS_PROFILING_TYPE_VALUE = 0; + /** + * <code>VTS_PROFILING_TYPE_TIMESTAMP = 1;</code> + * + * <pre> + * for one sample which measures the time between two profiling points. + * </pre> + */ + public static final int VTS_PROFILING_TYPE_TIMESTAMP_VALUE = 1; + /** + * <code>VTS_PROFILING_TYPE_LABELED_VECTOR = 2;</code> + * + * <pre> + * for multiple single-type samples with labels. + * </pre> + */ + public static final int VTS_PROFILING_TYPE_LABELED_VECTOR_VALUE = 2; + /** + * <code>VTS_PROFILING_TYPE_UNLABELED_VECTOR = 3;</code> + * + * <pre> + * for multiple single-type samples without labels. + * </pre> + */ + public static final int VTS_PROFILING_TYPE_UNLABELED_VECTOR_VALUE = 3; + + + public final int getNumber() { return value; } + + public static VtsProfilingType valueOf(int value) { + switch (value) { + case 0: return UNKNOWN_VTS_PROFILING_TYPE; + case 1: return VTS_PROFILING_TYPE_TIMESTAMP; + case 2: return VTS_PROFILING_TYPE_LABELED_VECTOR; + case 3: return VTS_PROFILING_TYPE_UNLABELED_VECTOR; + default: return null; + } + } + + public static com.google.protobuf.Internal.EnumLiteMap<VtsProfilingType> + internalGetValueMap() { + return internalValueMap; + } + private static com.google.protobuf.Internal.EnumLiteMap<VtsProfilingType> + internalValueMap = + new com.google.protobuf.Internal.EnumLiteMap<VtsProfilingType>() { + public VtsProfilingType findValueByNumber(int number) { + return VtsProfilingType.valueOf(number); + } + }; + + public final com.google.protobuf.Descriptors.EnumValueDescriptor + getValueDescriptor() { + return getDescriptor().getValues().get(index); + } + public final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptorForType() { + return getDescriptor(); + } + public static final com.google.protobuf.Descriptors.EnumDescriptor + getDescriptor() { + return com.android.vts.proto.VtsReportMessage.getDescriptor().getEnumTypes().get(3); + } + + private static final VtsProfilingType[] VALUES = values(); + + public static VtsProfilingType valueOf( + com.google.protobuf.Descriptors.EnumValueDescriptor desc) { + if (desc.getType() != getDescriptor()) { + throw new java.lang.IllegalArgumentException( + "EnumValueDescriptor is not for this type."); + } + return VALUES[desc.getIndex()]; + } + + private final int index; + private final int value; + + private VtsProfilingType(int index, int value) { + this.index = index; + this.value = value; + } + + // @@protoc_insertion_point(enum_scope:android.vts.VtsProfilingType) + } + + public interface AndroidDeviceInfoMessageOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // optional bytes product_type = 1; + /** + * <code>optional bytes product_type = 1;</code> + * + * <pre> + * product type (e.g., bullhead). + * </pre> + */ + boolean hasProductType(); + /** + * <code>optional bytes product_type = 1;</code> + * + * <pre> + * product type (e.g., bullhead). + * </pre> + */ + com.google.protobuf.ByteString getProductType(); + + // optional bytes product_variant = 2; + /** + * <code>optional bytes product_variant = 2;</code> + * + * <pre> + * product type variant (e.g., still bullhead or another name). + * </pre> + */ + boolean hasProductVariant(); + /** + * <code>optional bytes product_variant = 2;</code> + * + * <pre> + * product type variant (e.g., still bullhead or another name). + * </pre> + */ + com.google.protobuf.ByteString getProductVariant(); + + // optional bytes build_flavor = 11; + /** + * <code>optional bytes build_flavor = 11;</code> + * + * <pre> + * build type (e.g., userdebug). + * </pre> + */ + boolean hasBuildFlavor(); + /** + * <code>optional bytes build_flavor = 11;</code> + * + * <pre> + * build type (e.g., userdebug). + * </pre> + */ + com.google.protobuf.ByteString getBuildFlavor(); + + // optional bytes build_id = 12; + /** + * <code>optional bytes build_id = 12;</code> + * + * <pre> + * Android Build ID. + * </pre> + */ + boolean hasBuildId(); + /** + * <code>optional bytes build_id = 12;</code> + * + * <pre> + * Android Build ID. + * </pre> + */ + com.google.protobuf.ByteString getBuildId(); + + // optional bytes branch = 21; + /** + * <code>optional bytes branch = 21;</code> + * + * <pre> + * branch name (e.g., master or nyc-dev). + * </pre> + */ + boolean hasBranch(); + /** + * <code>optional bytes branch = 21;</code> + * + * <pre> + * branch name (e.g., master or nyc-dev). + * </pre> + */ + com.google.protobuf.ByteString getBranch(); + + // optional bytes build_alias = 22; + /** + * <code>optional bytes build_alias = 22;</code> + * + * <pre> + * build alias implies the branch name. + * </pre> + */ + boolean hasBuildAlias(); + /** + * <code>optional bytes build_alias = 22;</code> + * + * <pre> + * build alias implies the branch name. + * </pre> + */ + com.google.protobuf.ByteString getBuildAlias(); + + // optional bytes api_level = 31; + /** + * <code>optional bytes api_level = 31;</code> + * + * <pre> + * API level + * </pre> + */ + boolean hasApiLevel(); + /** + * <code>optional bytes api_level = 31;</code> + * + * <pre> + * API level + * </pre> + */ + com.google.protobuf.ByteString getApiLevel(); + + // optional bytes abi_name = 51; + /** + * <code>optional bytes abi_name = 51;</code> + * + * <pre> + * ABI name that is current in use for the test + * </pre> + */ + boolean hasAbiName(); + /** + * <code>optional bytes abi_name = 51;</code> + * + * <pre> + * ABI name that is current in use for the test + * </pre> + */ + com.google.protobuf.ByteString getAbiName(); + + // optional bytes abi_bitness = 52; + /** + * <code>optional bytes abi_bitness = 52;</code> + * + * <pre> + * ABI bitness that is current in use for the test. Example: '32', '64', + * </pre> + */ + boolean hasAbiBitness(); + /** + * <code>optional bytes abi_bitness = 52;</code> + * + * <pre> + * ABI bitness that is current in use for the test. Example: '32', '64', + * </pre> + */ + com.google.protobuf.ByteString getAbiBitness(); + + // optional bytes serial = 101; + /** + * <code>optional bytes serial = 101;</code> + * + * <pre> + * Device USB serial number + * </pre> + */ + boolean hasSerial(); + /** + * <code>optional bytes serial = 101;</code> + * + * <pre> + * Device USB serial number + * </pre> + */ + com.google.protobuf.ByteString getSerial(); + } + /** + * Protobuf type {@code android.vts.AndroidDeviceInfoMessage} + * + * <pre> + * To specify a call flow event. + * </pre> + */ + public static final class AndroidDeviceInfoMessage extends + com.google.protobuf.GeneratedMessage + implements AndroidDeviceInfoMessageOrBuilder { + // Use AndroidDeviceInfoMessage.newBuilder() to construct. + private AndroidDeviceInfoMessage(com.google.protobuf.GeneratedMessage.Builder<?> builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private AndroidDeviceInfoMessage(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final AndroidDeviceInfoMessage defaultInstance; + public static AndroidDeviceInfoMessage getDefaultInstance() { + return defaultInstance; + } + + public AndroidDeviceInfoMessage getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private AndroidDeviceInfoMessage( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + productType_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + productVariant_ = input.readBytes(); + break; + } + case 90: { + bitField0_ |= 0x00000004; + buildFlavor_ = input.readBytes(); + break; + } + case 98: { + bitField0_ |= 0x00000008; + buildId_ = input.readBytes(); + break; + } + case 170: { + bitField0_ |= 0x00000010; + branch_ = input.readBytes(); + break; + } + case 178: { + bitField0_ |= 0x00000020; + buildAlias_ = input.readBytes(); + break; + } + case 250: { + bitField0_ |= 0x00000040; + apiLevel_ = input.readBytes(); + break; + } + case 410: { + bitField0_ |= 0x00000080; + abiName_ = input.readBytes(); + break; + } + case 418: { + bitField0_ |= 0x00000100; + abiBitness_ = input.readBytes(); + break; + } + case 810: { + bitField0_ |= 0x00000200; + serial_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_AndroidDeviceInfoMessage_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_AndroidDeviceInfoMessage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.class, com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.Builder.class); + } + + public static com.google.protobuf.Parser<AndroidDeviceInfoMessage> PARSER = + new com.google.protobuf.AbstractParser<AndroidDeviceInfoMessage>() { + public AndroidDeviceInfoMessage parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new AndroidDeviceInfoMessage(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser<AndroidDeviceInfoMessage> getParserForType() { + return PARSER; + } + + private int bitField0_; + // optional bytes product_type = 1; + public static final int PRODUCT_TYPE_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString productType_; + /** + * <code>optional bytes product_type = 1;</code> + * + * <pre> + * product type (e.g., bullhead). + * </pre> + */ + public boolean hasProductType() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * <code>optional bytes product_type = 1;</code> + * + * <pre> + * product type (e.g., bullhead). + * </pre> + */ + public com.google.protobuf.ByteString getProductType() { + return productType_; + } + + // optional bytes product_variant = 2; + public static final int PRODUCT_VARIANT_FIELD_NUMBER = 2; + private com.google.protobuf.ByteString productVariant_; + /** + * <code>optional bytes product_variant = 2;</code> + * + * <pre> + * product type variant (e.g., still bullhead or another name). + * </pre> + */ + public boolean hasProductVariant() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * <code>optional bytes product_variant = 2;</code> + * + * <pre> + * product type variant (e.g., still bullhead or another name). + * </pre> + */ + public com.google.protobuf.ByteString getProductVariant() { + return productVariant_; + } + + // optional bytes build_flavor = 11; + public static final int BUILD_FLAVOR_FIELD_NUMBER = 11; + private com.google.protobuf.ByteString buildFlavor_; + /** + * <code>optional bytes build_flavor = 11;</code> + * + * <pre> + * build type (e.g., userdebug). + * </pre> + */ + public boolean hasBuildFlavor() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * <code>optional bytes build_flavor = 11;</code> + * + * <pre> + * build type (e.g., userdebug). + * </pre> + */ + public com.google.protobuf.ByteString getBuildFlavor() { + return buildFlavor_; + } + + // optional bytes build_id = 12; + public static final int BUILD_ID_FIELD_NUMBER = 12; + private com.google.protobuf.ByteString buildId_; + /** + * <code>optional bytes build_id = 12;</code> + * + * <pre> + * Android Build ID. + * </pre> + */ + public boolean hasBuildId() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * <code>optional bytes build_id = 12;</code> + * + * <pre> + * Android Build ID. + * </pre> + */ + public com.google.protobuf.ByteString getBuildId() { + return buildId_; + } + + // optional bytes branch = 21; + public static final int BRANCH_FIELD_NUMBER = 21; + private com.google.protobuf.ByteString branch_; + /** + * <code>optional bytes branch = 21;</code> + * + * <pre> + * branch name (e.g., master or nyc-dev). + * </pre> + */ + public boolean hasBranch() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * <code>optional bytes branch = 21;</code> + * + * <pre> + * branch name (e.g., master or nyc-dev). + * </pre> + */ + public com.google.protobuf.ByteString getBranch() { + return branch_; + } + + // optional bytes build_alias = 22; + public static final int BUILD_ALIAS_FIELD_NUMBER = 22; + private com.google.protobuf.ByteString buildAlias_; + /** + * <code>optional bytes build_alias = 22;</code> + * + * <pre> + * build alias implies the branch name. + * </pre> + */ + public boolean hasBuildAlias() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * <code>optional bytes build_alias = 22;</code> + * + * <pre> + * build alias implies the branch name. + * </pre> + */ + public com.google.protobuf.ByteString getBuildAlias() { + return buildAlias_; + } + + // optional bytes api_level = 31; + public static final int API_LEVEL_FIELD_NUMBER = 31; + private com.google.protobuf.ByteString apiLevel_; + /** + * <code>optional bytes api_level = 31;</code> + * + * <pre> + * API level + * </pre> + */ + public boolean hasApiLevel() { + return ((bitField0_ & 0x00000040) == 0x00000040); + } + /** + * <code>optional bytes api_level = 31;</code> + * + * <pre> + * API level + * </pre> + */ + public com.google.protobuf.ByteString getApiLevel() { + return apiLevel_; + } + + // optional bytes abi_name = 51; + public static final int ABI_NAME_FIELD_NUMBER = 51; + private com.google.protobuf.ByteString abiName_; + /** + * <code>optional bytes abi_name = 51;</code> + * + * <pre> + * ABI name that is current in use for the test + * </pre> + */ + public boolean hasAbiName() { + return ((bitField0_ & 0x00000080) == 0x00000080); + } + /** + * <code>optional bytes abi_name = 51;</code> + * + * <pre> + * ABI name that is current in use for the test + * </pre> + */ + public com.google.protobuf.ByteString getAbiName() { + return abiName_; + } + + // optional bytes abi_bitness = 52; + public static final int ABI_BITNESS_FIELD_NUMBER = 52; + private com.google.protobuf.ByteString abiBitness_; + /** + * <code>optional bytes abi_bitness = 52;</code> + * + * <pre> + * ABI bitness that is current in use for the test. Example: '32', '64', + * </pre> + */ + public boolean hasAbiBitness() { + return ((bitField0_ & 0x00000100) == 0x00000100); + } + /** + * <code>optional bytes abi_bitness = 52;</code> + * + * <pre> + * ABI bitness that is current in use for the test. Example: '32', '64', + * </pre> + */ + public com.google.protobuf.ByteString getAbiBitness() { + return abiBitness_; + } + + // optional bytes serial = 101; + public static final int SERIAL_FIELD_NUMBER = 101; + private com.google.protobuf.ByteString serial_; + /** + * <code>optional bytes serial = 101;</code> + * + * <pre> + * Device USB serial number + * </pre> + */ + public boolean hasSerial() { + return ((bitField0_ & 0x00000200) == 0x00000200); + } + /** + * <code>optional bytes serial = 101;</code> + * + * <pre> + * Device USB serial number + * </pre> + */ + public com.google.protobuf.ByteString getSerial() { + return serial_; + } + + private void initFields() { + productType_ = com.google.protobuf.ByteString.EMPTY; + productVariant_ = com.google.protobuf.ByteString.EMPTY; + buildFlavor_ = com.google.protobuf.ByteString.EMPTY; + buildId_ = com.google.protobuf.ByteString.EMPTY; + branch_ = com.google.protobuf.ByteString.EMPTY; + buildAlias_ = com.google.protobuf.ByteString.EMPTY; + apiLevel_ = com.google.protobuf.ByteString.EMPTY; + abiName_ = com.google.protobuf.ByteString.EMPTY; + abiBitness_ = com.google.protobuf.ByteString.EMPTY; + serial_ = com.google.protobuf.ByteString.EMPTY; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, productType_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, productVariant_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeBytes(11, buildFlavor_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeBytes(12, buildId_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + output.writeBytes(21, branch_); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + output.writeBytes(22, buildAlias_); + } + if (((bitField0_ & 0x00000040) == 0x00000040)) { + output.writeBytes(31, apiLevel_); + } + if (((bitField0_ & 0x00000080) == 0x00000080)) { + output.writeBytes(51, abiName_); + } + if (((bitField0_ & 0x00000100) == 0x00000100)) { + output.writeBytes(52, abiBitness_); + } + if (((bitField0_ & 0x00000200) == 0x00000200)) { + output.writeBytes(101, serial_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, productType_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, productVariant_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(11, buildFlavor_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(12, buildId_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(21, branch_); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(22, buildAlias_); + } + if (((bitField0_ & 0x00000040) == 0x00000040)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(31, apiLevel_); + } + if (((bitField0_ & 0x00000080) == 0x00000080)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(51, abiName_); + } + if (((bitField0_ & 0x00000100) == 0x00000100)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(52, abiBitness_); + } + if (((bitField0_ & 0x00000200) == 0x00000200)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(101, serial_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code android.vts.AndroidDeviceInfoMessage} + * + * <pre> + * To specify a call flow event. + * </pre> + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder<Builder> + implements com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessageOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_AndroidDeviceInfoMessage_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_AndroidDeviceInfoMessage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.class, com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.Builder.class); + } + + // Construct using com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + productType_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + productVariant_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000002); + buildFlavor_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000004); + buildId_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000008); + branch_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000010); + buildAlias_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000020); + apiLevel_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000040); + abiName_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000080); + abiBitness_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000100); + serial_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000200); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_AndroidDeviceInfoMessage_descriptor; + } + + public com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage getDefaultInstanceForType() { + return com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.getDefaultInstance(); + } + + public com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage build() { + com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage buildPartial() { + com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage result = new com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.productType_ = productType_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.productVariant_ = productVariant_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.buildFlavor_ = buildFlavor_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.buildId_ = buildId_; + if (((from_bitField0_ & 0x00000010) == 0x00000010)) { + to_bitField0_ |= 0x00000010; + } + result.branch_ = branch_; + if (((from_bitField0_ & 0x00000020) == 0x00000020)) { + to_bitField0_ |= 0x00000020; + } + result.buildAlias_ = buildAlias_; + if (((from_bitField0_ & 0x00000040) == 0x00000040)) { + to_bitField0_ |= 0x00000040; + } + result.apiLevel_ = apiLevel_; + if (((from_bitField0_ & 0x00000080) == 0x00000080)) { + to_bitField0_ |= 0x00000080; + } + result.abiName_ = abiName_; + if (((from_bitField0_ & 0x00000100) == 0x00000100)) { + to_bitField0_ |= 0x00000100; + } + result.abiBitness_ = abiBitness_; + if (((from_bitField0_ & 0x00000200) == 0x00000200)) { + to_bitField0_ |= 0x00000200; + } + result.serial_ = serial_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage) { + return mergeFrom((com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage other) { + if (other == com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.getDefaultInstance()) return this; + if (other.hasProductType()) { + setProductType(other.getProductType()); + } + if (other.hasProductVariant()) { + setProductVariant(other.getProductVariant()); + } + if (other.hasBuildFlavor()) { + setBuildFlavor(other.getBuildFlavor()); + } + if (other.hasBuildId()) { + setBuildId(other.getBuildId()); + } + if (other.hasBranch()) { + setBranch(other.getBranch()); + } + if (other.hasBuildAlias()) { + setBuildAlias(other.getBuildAlias()); + } + if (other.hasApiLevel()) { + setApiLevel(other.getApiLevel()); + } + if (other.hasAbiName()) { + setAbiName(other.getAbiName()); + } + if (other.hasAbiBitness()) { + setAbiBitness(other.getAbiBitness()); + } + if (other.hasSerial()) { + setSerial(other.getSerial()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // optional bytes product_type = 1; + private com.google.protobuf.ByteString productType_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes product_type = 1;</code> + * + * <pre> + * product type (e.g., bullhead). + * </pre> + */ + public boolean hasProductType() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * <code>optional bytes product_type = 1;</code> + * + * <pre> + * product type (e.g., bullhead). + * </pre> + */ + public com.google.protobuf.ByteString getProductType() { + return productType_; + } + /** + * <code>optional bytes product_type = 1;</code> + * + * <pre> + * product type (e.g., bullhead). + * </pre> + */ + public Builder setProductType(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + productType_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes product_type = 1;</code> + * + * <pre> + * product type (e.g., bullhead). + * </pre> + */ + public Builder clearProductType() { + bitField0_ = (bitField0_ & ~0x00000001); + productType_ = getDefaultInstance().getProductType(); + onChanged(); + return this; + } + + // optional bytes product_variant = 2; + private com.google.protobuf.ByteString productVariant_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes product_variant = 2;</code> + * + * <pre> + * product type variant (e.g., still bullhead or another name). + * </pre> + */ + public boolean hasProductVariant() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * <code>optional bytes product_variant = 2;</code> + * + * <pre> + * product type variant (e.g., still bullhead or another name). + * </pre> + */ + public com.google.protobuf.ByteString getProductVariant() { + return productVariant_; + } + /** + * <code>optional bytes product_variant = 2;</code> + * + * <pre> + * product type variant (e.g., still bullhead or another name). + * </pre> + */ + public Builder setProductVariant(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + productVariant_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes product_variant = 2;</code> + * + * <pre> + * product type variant (e.g., still bullhead or another name). + * </pre> + */ + public Builder clearProductVariant() { + bitField0_ = (bitField0_ & ~0x00000002); + productVariant_ = getDefaultInstance().getProductVariant(); + onChanged(); + return this; + } + + // optional bytes build_flavor = 11; + private com.google.protobuf.ByteString buildFlavor_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes build_flavor = 11;</code> + * + * <pre> + * build type (e.g., userdebug). + * </pre> + */ + public boolean hasBuildFlavor() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * <code>optional bytes build_flavor = 11;</code> + * + * <pre> + * build type (e.g., userdebug). + * </pre> + */ + public com.google.protobuf.ByteString getBuildFlavor() { + return buildFlavor_; + } + /** + * <code>optional bytes build_flavor = 11;</code> + * + * <pre> + * build type (e.g., userdebug). + * </pre> + */ + public Builder setBuildFlavor(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + buildFlavor_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes build_flavor = 11;</code> + * + * <pre> + * build type (e.g., userdebug). + * </pre> + */ + public Builder clearBuildFlavor() { + bitField0_ = (bitField0_ & ~0x00000004); + buildFlavor_ = getDefaultInstance().getBuildFlavor(); + onChanged(); + return this; + } + + // optional bytes build_id = 12; + private com.google.protobuf.ByteString buildId_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes build_id = 12;</code> + * + * <pre> + * Android Build ID. + * </pre> + */ + public boolean hasBuildId() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * <code>optional bytes build_id = 12;</code> + * + * <pre> + * Android Build ID. + * </pre> + */ + public com.google.protobuf.ByteString getBuildId() { + return buildId_; + } + /** + * <code>optional bytes build_id = 12;</code> + * + * <pre> + * Android Build ID. + * </pre> + */ + public Builder setBuildId(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000008; + buildId_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes build_id = 12;</code> + * + * <pre> + * Android Build ID. + * </pre> + */ + public Builder clearBuildId() { + bitField0_ = (bitField0_ & ~0x00000008); + buildId_ = getDefaultInstance().getBuildId(); + onChanged(); + return this; + } + + // optional bytes branch = 21; + private com.google.protobuf.ByteString branch_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes branch = 21;</code> + * + * <pre> + * branch name (e.g., master or nyc-dev). + * </pre> + */ + public boolean hasBranch() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * <code>optional bytes branch = 21;</code> + * + * <pre> + * branch name (e.g., master or nyc-dev). + * </pre> + */ + public com.google.protobuf.ByteString getBranch() { + return branch_; + } + /** + * <code>optional bytes branch = 21;</code> + * + * <pre> + * branch name (e.g., master or nyc-dev). + * </pre> + */ + public Builder setBranch(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000010; + branch_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes branch = 21;</code> + * + * <pre> + * branch name (e.g., master or nyc-dev). + * </pre> + */ + public Builder clearBranch() { + bitField0_ = (bitField0_ & ~0x00000010); + branch_ = getDefaultInstance().getBranch(); + onChanged(); + return this; + } + + // optional bytes build_alias = 22; + private com.google.protobuf.ByteString buildAlias_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes build_alias = 22;</code> + * + * <pre> + * build alias implies the branch name. + * </pre> + */ + public boolean hasBuildAlias() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * <code>optional bytes build_alias = 22;</code> + * + * <pre> + * build alias implies the branch name. + * </pre> + */ + public com.google.protobuf.ByteString getBuildAlias() { + return buildAlias_; + } + /** + * <code>optional bytes build_alias = 22;</code> + * + * <pre> + * build alias implies the branch name. + * </pre> + */ + public Builder setBuildAlias(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000020; + buildAlias_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes build_alias = 22;</code> + * + * <pre> + * build alias implies the branch name. + * </pre> + */ + public Builder clearBuildAlias() { + bitField0_ = (bitField0_ & ~0x00000020); + buildAlias_ = getDefaultInstance().getBuildAlias(); + onChanged(); + return this; + } + + // optional bytes api_level = 31; + private com.google.protobuf.ByteString apiLevel_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes api_level = 31;</code> + * + * <pre> + * API level + * </pre> + */ + public boolean hasApiLevel() { + return ((bitField0_ & 0x00000040) == 0x00000040); + } + /** + * <code>optional bytes api_level = 31;</code> + * + * <pre> + * API level + * </pre> + */ + public com.google.protobuf.ByteString getApiLevel() { + return apiLevel_; + } + /** + * <code>optional bytes api_level = 31;</code> + * + * <pre> + * API level + * </pre> + */ + public Builder setApiLevel(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000040; + apiLevel_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes api_level = 31;</code> + * + * <pre> + * API level + * </pre> + */ + public Builder clearApiLevel() { + bitField0_ = (bitField0_ & ~0x00000040); + apiLevel_ = getDefaultInstance().getApiLevel(); + onChanged(); + return this; + } + + // optional bytes abi_name = 51; + private com.google.protobuf.ByteString abiName_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes abi_name = 51;</code> + * + * <pre> + * ABI name that is current in use for the test + * </pre> + */ + public boolean hasAbiName() { + return ((bitField0_ & 0x00000080) == 0x00000080); + } + /** + * <code>optional bytes abi_name = 51;</code> + * + * <pre> + * ABI name that is current in use for the test + * </pre> + */ + public com.google.protobuf.ByteString getAbiName() { + return abiName_; + } + /** + * <code>optional bytes abi_name = 51;</code> + * + * <pre> + * ABI name that is current in use for the test + * </pre> + */ + public Builder setAbiName(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000080; + abiName_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes abi_name = 51;</code> + * + * <pre> + * ABI name that is current in use for the test + * </pre> + */ + public Builder clearAbiName() { + bitField0_ = (bitField0_ & ~0x00000080); + abiName_ = getDefaultInstance().getAbiName(); + onChanged(); + return this; + } + + // optional bytes abi_bitness = 52; + private com.google.protobuf.ByteString abiBitness_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes abi_bitness = 52;</code> + * + * <pre> + * ABI bitness that is current in use for the test. Example: '32', '64', + * </pre> + */ + public boolean hasAbiBitness() { + return ((bitField0_ & 0x00000100) == 0x00000100); + } + /** + * <code>optional bytes abi_bitness = 52;</code> + * + * <pre> + * ABI bitness that is current in use for the test. Example: '32', '64', + * </pre> + */ + public com.google.protobuf.ByteString getAbiBitness() { + return abiBitness_; + } + /** + * <code>optional bytes abi_bitness = 52;</code> + * + * <pre> + * ABI bitness that is current in use for the test. Example: '32', '64', + * </pre> + */ + public Builder setAbiBitness(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000100; + abiBitness_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes abi_bitness = 52;</code> + * + * <pre> + * ABI bitness that is current in use for the test. Example: '32', '64', + * </pre> + */ + public Builder clearAbiBitness() { + bitField0_ = (bitField0_ & ~0x00000100); + abiBitness_ = getDefaultInstance().getAbiBitness(); + onChanged(); + return this; + } + + // optional bytes serial = 101; + private com.google.protobuf.ByteString serial_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes serial = 101;</code> + * + * <pre> + * Device USB serial number + * </pre> + */ + public boolean hasSerial() { + return ((bitField0_ & 0x00000200) == 0x00000200); + } + /** + * <code>optional bytes serial = 101;</code> + * + * <pre> + * Device USB serial number + * </pre> + */ + public com.google.protobuf.ByteString getSerial() { + return serial_; + } + /** + * <code>optional bytes serial = 101;</code> + * + * <pre> + * Device USB serial number + * </pre> + */ + public Builder setSerial(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000200; + serial_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes serial = 101;</code> + * + * <pre> + * Device USB serial number + * </pre> + */ + public Builder clearSerial() { + bitField0_ = (bitField0_ & ~0x00000200); + serial_ = getDefaultInstance().getSerial(); + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:android.vts.AndroidDeviceInfoMessage) + } + + static { + defaultInstance = new AndroidDeviceInfoMessage(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:android.vts.AndroidDeviceInfoMessage) + } + + public interface AndroidBuildInfoOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // optional bytes id = 1; + /** + * <code>optional bytes id = 1;</code> + * + * <pre> + * build ID. + * </pre> + */ + boolean hasId(); + /** + * <code>optional bytes id = 1;</code> + * + * <pre> + * build ID. + * </pre> + */ + com.google.protobuf.ByteString getId(); + + // optional bytes name = 11; + /** + * <code>optional bytes name = 11;</code> + * + * <pre> + * device name (e.g., bullhead). + * </pre> + */ + boolean hasName(); + /** + * <code>optional bytes name = 11;</code> + * + * <pre> + * device name (e.g., bullhead). + * </pre> + */ + com.google.protobuf.ByteString getName(); + + // optional bytes build_type = 12; + /** + * <code>optional bytes build_type = 12;</code> + * + * <pre> + * build type (e.g., userdebug) + * </pre> + */ + boolean hasBuildType(); + /** + * <code>optional bytes build_type = 12;</code> + * + * <pre> + * build type (e.g., userdebug) + * </pre> + */ + com.google.protobuf.ByteString getBuildType(); + + // optional bytes branch = 13; + /** + * <code>optional bytes branch = 13;</code> + * + * <pre> + * branch name (e.g., master or nyc-dev) + * </pre> + */ + boolean hasBranch(); + /** + * <code>optional bytes branch = 13;</code> + * + * <pre> + * branch name (e.g., master or nyc-dev) + * </pre> + */ + com.google.protobuf.ByteString getBranch(); + + // optional bytes build_summary = 21; + /** + * <code>optional bytes build_summary = 21;</code> + * + * <pre> + * indicates the latest commit information of each branch (e.g., xml format). + * </pre> + */ + boolean hasBuildSummary(); + /** + * <code>optional bytes build_summary = 21;</code> + * + * <pre> + * indicates the latest commit information of each branch (e.g., xml format). + * </pre> + */ + com.google.protobuf.ByteString getBuildSummary(); + } + /** + * Protobuf type {@code android.vts.AndroidBuildInfo} + * + * <pre> + * To specify build info. + * </pre> + */ + public static final class AndroidBuildInfo extends + com.google.protobuf.GeneratedMessage + implements AndroidBuildInfoOrBuilder { + // Use AndroidBuildInfo.newBuilder() to construct. + private AndroidBuildInfo(com.google.protobuf.GeneratedMessage.Builder<?> builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private AndroidBuildInfo(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final AndroidBuildInfo defaultInstance; + public static AndroidBuildInfo getDefaultInstance() { + return defaultInstance; + } + + public AndroidBuildInfo getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private AndroidBuildInfo( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + id_ = input.readBytes(); + break; + } + case 90: { + bitField0_ |= 0x00000002; + name_ = input.readBytes(); + break; + } + case 98: { + bitField0_ |= 0x00000004; + buildType_ = input.readBytes(); + break; + } + case 106: { + bitField0_ |= 0x00000008; + branch_ = input.readBytes(); + break; + } + case 170: { + bitField0_ |= 0x00000010; + buildSummary_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_AndroidBuildInfo_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_AndroidBuildInfo_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.class, com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.Builder.class); + } + + public static com.google.protobuf.Parser<AndroidBuildInfo> PARSER = + new com.google.protobuf.AbstractParser<AndroidBuildInfo>() { + public AndroidBuildInfo parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new AndroidBuildInfo(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser<AndroidBuildInfo> getParserForType() { + return PARSER; + } + + private int bitField0_; + // optional bytes id = 1; + public static final int ID_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString id_; + /** + * <code>optional bytes id = 1;</code> + * + * <pre> + * build ID. + * </pre> + */ + public boolean hasId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * <code>optional bytes id = 1;</code> + * + * <pre> + * build ID. + * </pre> + */ + public com.google.protobuf.ByteString getId() { + return id_; + } + + // optional bytes name = 11; + public static final int NAME_FIELD_NUMBER = 11; + private com.google.protobuf.ByteString name_; + /** + * <code>optional bytes name = 11;</code> + * + * <pre> + * device name (e.g., bullhead). + * </pre> + */ + public boolean hasName() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * <code>optional bytes name = 11;</code> + * + * <pre> + * device name (e.g., bullhead). + * </pre> + */ + public com.google.protobuf.ByteString getName() { + return name_; + } + + // optional bytes build_type = 12; + public static final int BUILD_TYPE_FIELD_NUMBER = 12; + private com.google.protobuf.ByteString buildType_; + /** + * <code>optional bytes build_type = 12;</code> + * + * <pre> + * build type (e.g., userdebug) + * </pre> + */ + public boolean hasBuildType() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * <code>optional bytes build_type = 12;</code> + * + * <pre> + * build type (e.g., userdebug) + * </pre> + */ + public com.google.protobuf.ByteString getBuildType() { + return buildType_; + } + + // optional bytes branch = 13; + public static final int BRANCH_FIELD_NUMBER = 13; + private com.google.protobuf.ByteString branch_; + /** + * <code>optional bytes branch = 13;</code> + * + * <pre> + * branch name (e.g., master or nyc-dev) + * </pre> + */ + public boolean hasBranch() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * <code>optional bytes branch = 13;</code> + * + * <pre> + * branch name (e.g., master or nyc-dev) + * </pre> + */ + public com.google.protobuf.ByteString getBranch() { + return branch_; + } + + // optional bytes build_summary = 21; + public static final int BUILD_SUMMARY_FIELD_NUMBER = 21; + private com.google.protobuf.ByteString buildSummary_; + /** + * <code>optional bytes build_summary = 21;</code> + * + * <pre> + * indicates the latest commit information of each branch (e.g., xml format). + * </pre> + */ + public boolean hasBuildSummary() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * <code>optional bytes build_summary = 21;</code> + * + * <pre> + * indicates the latest commit information of each branch (e.g., xml format). + * </pre> + */ + public com.google.protobuf.ByteString getBuildSummary() { + return buildSummary_; + } + + private void initFields() { + id_ = com.google.protobuf.ByteString.EMPTY; + name_ = com.google.protobuf.ByteString.EMPTY; + buildType_ = com.google.protobuf.ByteString.EMPTY; + branch_ = com.google.protobuf.ByteString.EMPTY; + buildSummary_ = com.google.protobuf.ByteString.EMPTY; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, id_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(11, name_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeBytes(12, buildType_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeBytes(13, branch_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + output.writeBytes(21, buildSummary_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, id_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(11, name_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(12, buildType_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(13, branch_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(21, buildSummary_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static com.android.vts.proto.VtsReportMessage.AndroidBuildInfo parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.android.vts.proto.VtsReportMessage.AndroidBuildInfo parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.AndroidBuildInfo parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.android.vts.proto.VtsReportMessage.AndroidBuildInfo parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.AndroidBuildInfo parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.AndroidBuildInfo parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.AndroidBuildInfo parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.AndroidBuildInfo parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.AndroidBuildInfo parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.AndroidBuildInfo parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(com.android.vts.proto.VtsReportMessage.AndroidBuildInfo prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code android.vts.AndroidBuildInfo} + * + * <pre> + * To specify build info. + * </pre> + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder<Builder> + implements com.android.vts.proto.VtsReportMessage.AndroidBuildInfoOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_AndroidBuildInfo_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_AndroidBuildInfo_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.class, com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.Builder.class); + } + + // Construct using com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + id_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + name_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000002); + buildType_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000004); + branch_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000008); + buildSummary_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000010); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_AndroidBuildInfo_descriptor; + } + + public com.android.vts.proto.VtsReportMessage.AndroidBuildInfo getDefaultInstanceForType() { + return com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.getDefaultInstance(); + } + + public com.android.vts.proto.VtsReportMessage.AndroidBuildInfo build() { + com.android.vts.proto.VtsReportMessage.AndroidBuildInfo result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public com.android.vts.proto.VtsReportMessage.AndroidBuildInfo buildPartial() { + com.android.vts.proto.VtsReportMessage.AndroidBuildInfo result = new com.android.vts.proto.VtsReportMessage.AndroidBuildInfo(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.id_ = id_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.name_ = name_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.buildType_ = buildType_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.branch_ = branch_; + if (((from_bitField0_ & 0x00000010) == 0x00000010)) { + to_bitField0_ |= 0x00000010; + } + result.buildSummary_ = buildSummary_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.android.vts.proto.VtsReportMessage.AndroidBuildInfo) { + return mergeFrom((com.android.vts.proto.VtsReportMessage.AndroidBuildInfo)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.android.vts.proto.VtsReportMessage.AndroidBuildInfo other) { + if (other == com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.getDefaultInstance()) return this; + if (other.hasId()) { + setId(other.getId()); + } + if (other.hasName()) { + setName(other.getName()); + } + if (other.hasBuildType()) { + setBuildType(other.getBuildType()); + } + if (other.hasBranch()) { + setBranch(other.getBranch()); + } + if (other.hasBuildSummary()) { + setBuildSummary(other.getBuildSummary()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + com.android.vts.proto.VtsReportMessage.AndroidBuildInfo parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (com.android.vts.proto.VtsReportMessage.AndroidBuildInfo) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // optional bytes id = 1; + private com.google.protobuf.ByteString id_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes id = 1;</code> + * + * <pre> + * build ID. + * </pre> + */ + public boolean hasId() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * <code>optional bytes id = 1;</code> + * + * <pre> + * build ID. + * </pre> + */ + public com.google.protobuf.ByteString getId() { + return id_; + } + /** + * <code>optional bytes id = 1;</code> + * + * <pre> + * build ID. + * </pre> + */ + public Builder setId(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + id_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes id = 1;</code> + * + * <pre> + * build ID. + * </pre> + */ + public Builder clearId() { + bitField0_ = (bitField0_ & ~0x00000001); + id_ = getDefaultInstance().getId(); + onChanged(); + return this; + } + + // optional bytes name = 11; + private com.google.protobuf.ByteString name_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes name = 11;</code> + * + * <pre> + * device name (e.g., bullhead). + * </pre> + */ + public boolean hasName() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * <code>optional bytes name = 11;</code> + * + * <pre> + * device name (e.g., bullhead). + * </pre> + */ + public com.google.protobuf.ByteString getName() { + return name_; + } + /** + * <code>optional bytes name = 11;</code> + * + * <pre> + * device name (e.g., bullhead). + * </pre> + */ + public Builder setName(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + name_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes name = 11;</code> + * + * <pre> + * device name (e.g., bullhead). + * </pre> + */ + public Builder clearName() { + bitField0_ = (bitField0_ & ~0x00000002); + name_ = getDefaultInstance().getName(); + onChanged(); + return this; + } + + // optional bytes build_type = 12; + private com.google.protobuf.ByteString buildType_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes build_type = 12;</code> + * + * <pre> + * build type (e.g., userdebug) + * </pre> + */ + public boolean hasBuildType() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * <code>optional bytes build_type = 12;</code> + * + * <pre> + * build type (e.g., userdebug) + * </pre> + */ + public com.google.protobuf.ByteString getBuildType() { + return buildType_; + } + /** + * <code>optional bytes build_type = 12;</code> + * + * <pre> + * build type (e.g., userdebug) + * </pre> + */ + public Builder setBuildType(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + buildType_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes build_type = 12;</code> + * + * <pre> + * build type (e.g., userdebug) + * </pre> + */ + public Builder clearBuildType() { + bitField0_ = (bitField0_ & ~0x00000004); + buildType_ = getDefaultInstance().getBuildType(); + onChanged(); + return this; + } + + // optional bytes branch = 13; + private com.google.protobuf.ByteString branch_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes branch = 13;</code> + * + * <pre> + * branch name (e.g., master or nyc-dev) + * </pre> + */ + public boolean hasBranch() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * <code>optional bytes branch = 13;</code> + * + * <pre> + * branch name (e.g., master or nyc-dev) + * </pre> + */ + public com.google.protobuf.ByteString getBranch() { + return branch_; + } + /** + * <code>optional bytes branch = 13;</code> + * + * <pre> + * branch name (e.g., master or nyc-dev) + * </pre> + */ + public Builder setBranch(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000008; + branch_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes branch = 13;</code> + * + * <pre> + * branch name (e.g., master or nyc-dev) + * </pre> + */ + public Builder clearBranch() { + bitField0_ = (bitField0_ & ~0x00000008); + branch_ = getDefaultInstance().getBranch(); + onChanged(); + return this; + } + + // optional bytes build_summary = 21; + private com.google.protobuf.ByteString buildSummary_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes build_summary = 21;</code> + * + * <pre> + * indicates the latest commit information of each branch (e.g., xml format). + * </pre> + */ + public boolean hasBuildSummary() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * <code>optional bytes build_summary = 21;</code> + * + * <pre> + * indicates the latest commit information of each branch (e.g., xml format). + * </pre> + */ + public com.google.protobuf.ByteString getBuildSummary() { + return buildSummary_; + } + /** + * <code>optional bytes build_summary = 21;</code> + * + * <pre> + * indicates the latest commit information of each branch (e.g., xml format). + * </pre> + */ + public Builder setBuildSummary(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000010; + buildSummary_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes build_summary = 21;</code> + * + * <pre> + * indicates the latest commit information of each branch (e.g., xml format). + * </pre> + */ + public Builder clearBuildSummary() { + bitField0_ = (bitField0_ & ~0x00000010); + buildSummary_ = getDefaultInstance().getBuildSummary(); + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:android.vts.AndroidBuildInfo) + } + + static { + defaultInstance = new AndroidBuildInfo(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:android.vts.AndroidBuildInfo) + } + + public interface VtsHostInfoOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // optional bytes hostname = 1; + /** + * <code>optional bytes hostname = 1;</code> + * + * <pre> + * the host name (i.e., full domain name). + * </pre> + */ + boolean hasHostname(); + /** + * <code>optional bytes hostname = 1;</code> + * + * <pre> + * the host name (i.e., full domain name). + * </pre> + */ + com.google.protobuf.ByteString getHostname(); + } + /** + * Protobuf type {@code android.vts.VtsHostInfo} + * + * <pre> + * To specify the information about a host node. + * </pre> + */ + public static final class VtsHostInfo extends + com.google.protobuf.GeneratedMessage + implements VtsHostInfoOrBuilder { + // Use VtsHostInfo.newBuilder() to construct. + private VtsHostInfo(com.google.protobuf.GeneratedMessage.Builder<?> builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private VtsHostInfo(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final VtsHostInfo defaultInstance; + public static VtsHostInfo getDefaultInstance() { + return defaultInstance; + } + + public VtsHostInfo getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private VtsHostInfo( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + hostname_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_VtsHostInfo_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_VtsHostInfo_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.android.vts.proto.VtsReportMessage.VtsHostInfo.class, com.android.vts.proto.VtsReportMessage.VtsHostInfo.Builder.class); + } + + public static com.google.protobuf.Parser<VtsHostInfo> PARSER = + new com.google.protobuf.AbstractParser<VtsHostInfo>() { + public VtsHostInfo parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new VtsHostInfo(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser<VtsHostInfo> getParserForType() { + return PARSER; + } + + private int bitField0_; + // optional bytes hostname = 1; + public static final int HOSTNAME_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString hostname_; + /** + * <code>optional bytes hostname = 1;</code> + * + * <pre> + * the host name (i.e., full domain name). + * </pre> + */ + public boolean hasHostname() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * <code>optional bytes hostname = 1;</code> + * + * <pre> + * the host name (i.e., full domain name). + * </pre> + */ + public com.google.protobuf.ByteString getHostname() { + return hostname_; + } + + private void initFields() { + hostname_ = com.google.protobuf.ByteString.EMPTY; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, hostname_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, hostname_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static com.android.vts.proto.VtsReportMessage.VtsHostInfo parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.android.vts.proto.VtsReportMessage.VtsHostInfo parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.VtsHostInfo parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.android.vts.proto.VtsReportMessage.VtsHostInfo parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.VtsHostInfo parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.VtsHostInfo parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.VtsHostInfo parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.VtsHostInfo parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.VtsHostInfo parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.VtsHostInfo parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(com.android.vts.proto.VtsReportMessage.VtsHostInfo prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code android.vts.VtsHostInfo} + * + * <pre> + * To specify the information about a host node. + * </pre> + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder<Builder> + implements com.android.vts.proto.VtsReportMessage.VtsHostInfoOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_VtsHostInfo_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_VtsHostInfo_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.android.vts.proto.VtsReportMessage.VtsHostInfo.class, com.android.vts.proto.VtsReportMessage.VtsHostInfo.Builder.class); + } + + // Construct using com.android.vts.proto.VtsReportMessage.VtsHostInfo.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + hostname_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_VtsHostInfo_descriptor; + } + + public com.android.vts.proto.VtsReportMessage.VtsHostInfo getDefaultInstanceForType() { + return com.android.vts.proto.VtsReportMessage.VtsHostInfo.getDefaultInstance(); + } + + public com.android.vts.proto.VtsReportMessage.VtsHostInfo build() { + com.android.vts.proto.VtsReportMessage.VtsHostInfo result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public com.android.vts.proto.VtsReportMessage.VtsHostInfo buildPartial() { + com.android.vts.proto.VtsReportMessage.VtsHostInfo result = new com.android.vts.proto.VtsReportMessage.VtsHostInfo(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.hostname_ = hostname_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.android.vts.proto.VtsReportMessage.VtsHostInfo) { + return mergeFrom((com.android.vts.proto.VtsReportMessage.VtsHostInfo)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.android.vts.proto.VtsReportMessage.VtsHostInfo other) { + if (other == com.android.vts.proto.VtsReportMessage.VtsHostInfo.getDefaultInstance()) return this; + if (other.hasHostname()) { + setHostname(other.getHostname()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + com.android.vts.proto.VtsReportMessage.VtsHostInfo parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (com.android.vts.proto.VtsReportMessage.VtsHostInfo) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // optional bytes hostname = 1; + private com.google.protobuf.ByteString hostname_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes hostname = 1;</code> + * + * <pre> + * the host name (i.e., full domain name). + * </pre> + */ + public boolean hasHostname() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * <code>optional bytes hostname = 1;</code> + * + * <pre> + * the host name (i.e., full domain name). + * </pre> + */ + public com.google.protobuf.ByteString getHostname() { + return hostname_; + } + /** + * <code>optional bytes hostname = 1;</code> + * + * <pre> + * the host name (i.e., full domain name). + * </pre> + */ + public Builder setHostname(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + hostname_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes hostname = 1;</code> + * + * <pre> + * the host name (i.e., full domain name). + * </pre> + */ + public Builder clearHostname() { + bitField0_ = (bitField0_ & ~0x00000001); + hostname_ = getDefaultInstance().getHostname(); + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:android.vts.VtsHostInfo) + } + + static { + defaultInstance = new VtsHostInfo(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:android.vts.VtsHostInfo) + } + + public interface TestCaseReportMessageOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // optional bytes name = 1; + /** + * <code>optional bytes name = 1;</code> + * + * <pre> + * the test case name. + * </pre> + */ + boolean hasName(); + /** + * <code>optional bytes name = 1;</code> + * + * <pre> + * the test case name. + * </pre> + */ + com.google.protobuf.ByteString getName(); + + // optional .android.vts.TestCaseResult test_result = 11; + /** + * <code>optional .android.vts.TestCaseResult test_result = 11;</code> + * + * <pre> + * the test result. + * </pre> + */ + boolean hasTestResult(); + /** + * <code>optional .android.vts.TestCaseResult test_result = 11;</code> + * + * <pre> + * the test result. + * </pre> + */ + com.android.vts.proto.VtsReportMessage.TestCaseResult getTestResult(); + + // optional int64 start_timestamp = 21; + /** + * <code>optional int64 start_timestamp = 21;</code> + * + * <pre> + * execution start and end time stamp. + * </pre> + */ + boolean hasStartTimestamp(); + /** + * <code>optional int64 start_timestamp = 21;</code> + * + * <pre> + * execution start and end time stamp. + * </pre> + */ + long getStartTimestamp(); + + // optional int64 end_timestamp = 22; + /** + * <code>optional int64 end_timestamp = 22;</code> + */ + boolean hasEndTimestamp(); + /** + * <code>optional int64 end_timestamp = 22;</code> + */ + long getEndTimestamp(); + + // repeated .android.vts.CoverageReportMessage coverage = 31; + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code> + * + * <pre> + * coverage report per file + * </pre> + */ + java.util.List<com.android.vts.proto.VtsReportMessage.CoverageReportMessage> + getCoverageList(); + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code> + * + * <pre> + * coverage report per file + * </pre> + */ + com.android.vts.proto.VtsReportMessage.CoverageReportMessage getCoverage(int index); + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code> + * + * <pre> + * coverage report per file + * </pre> + */ + int getCoverageCount(); + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code> + * + * <pre> + * coverage report per file + * </pre> + */ + java.util.List<? extends com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder> + getCoverageOrBuilderList(); + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code> + * + * <pre> + * coverage report per file + * </pre> + */ + com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder getCoverageOrBuilder( + int index); + + // repeated .android.vts.ProfilingReportMessage profiling = 41; + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code> + * + * <pre> + * profiling reports + * </pre> + */ + java.util.List<com.android.vts.proto.VtsReportMessage.ProfilingReportMessage> + getProfilingList(); + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code> + * + * <pre> + * profiling reports + * </pre> + */ + com.android.vts.proto.VtsReportMessage.ProfilingReportMessage getProfiling(int index); + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code> + * + * <pre> + * profiling reports + * </pre> + */ + int getProfilingCount(); + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code> + * + * <pre> + * profiling reports + * </pre> + */ + java.util.List<? extends com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder> + getProfilingOrBuilderList(); + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code> + * + * <pre> + * profiling reports + * </pre> + */ + com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder getProfilingOrBuilder( + int index); + + // repeated .android.vts.SystraceReportMessage systrace = 42; + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code> + * + * <pre> + * systrace report message per file + * </pre> + */ + java.util.List<com.android.vts.proto.VtsReportMessage.SystraceReportMessage> + getSystraceList(); + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code> + * + * <pre> + * systrace report message per file + * </pre> + */ + com.android.vts.proto.VtsReportMessage.SystraceReportMessage getSystrace(int index); + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code> + * + * <pre> + * systrace report message per file + * </pre> + */ + int getSystraceCount(); + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code> + * + * <pre> + * systrace report message per file + * </pre> + */ + java.util.List<? extends com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder> + getSystraceOrBuilderList(); + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code> + * + * <pre> + * systrace report message per file + * </pre> + */ + com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder getSystraceOrBuilder( + int index); + + // repeated .android.vts.LogMessage log = 101; + /** + * <code>repeated .android.vts.LogMessage log = 101;</code> + * + * <pre> + * log for each test case. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + java.util.List<com.android.vts.proto.VtsReportMessage.LogMessage> + getLogList(); + /** + * <code>repeated .android.vts.LogMessage log = 101;</code> + * + * <pre> + * log for each test case. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + com.android.vts.proto.VtsReportMessage.LogMessage getLog(int index); + /** + * <code>repeated .android.vts.LogMessage log = 101;</code> + * + * <pre> + * log for each test case. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + int getLogCount(); + /** + * <code>repeated .android.vts.LogMessage log = 101;</code> + * + * <pre> + * log for each test case. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + java.util.List<? extends com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder> + getLogOrBuilderList(); + /** + * <code>repeated .android.vts.LogMessage log = 101;</code> + * + * <pre> + * log for each test case. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder getLogOrBuilder( + int index); + } + /** + * Protobuf type {@code android.vts.TestCaseReportMessage} + * + * <pre> + * To specify a test case execution report. + * </pre> + */ + public static final class TestCaseReportMessage extends + com.google.protobuf.GeneratedMessage + implements TestCaseReportMessageOrBuilder { + // Use TestCaseReportMessage.newBuilder() to construct. + private TestCaseReportMessage(com.google.protobuf.GeneratedMessage.Builder<?> builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private TestCaseReportMessage(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final TestCaseReportMessage defaultInstance; + public static TestCaseReportMessage getDefaultInstance() { + return defaultInstance; + } + + public TestCaseReportMessage getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private TestCaseReportMessage( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + name_ = input.readBytes(); + break; + } + case 88: { + int rawValue = input.readEnum(); + com.android.vts.proto.VtsReportMessage.TestCaseResult value = com.android.vts.proto.VtsReportMessage.TestCaseResult.valueOf(rawValue); + if (value == null) { + unknownFields.mergeVarintField(11, rawValue); + } else { + bitField0_ |= 0x00000002; + testResult_ = value; + } + break; + } + case 168: { + bitField0_ |= 0x00000004; + startTimestamp_ = input.readInt64(); + break; + } + case 176: { + bitField0_ |= 0x00000008; + endTimestamp_ = input.readInt64(); + break; + } + case 250: { + if (!((mutable_bitField0_ & 0x00000010) == 0x00000010)) { + coverage_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.CoverageReportMessage>(); + mutable_bitField0_ |= 0x00000010; + } + coverage_.add(input.readMessage(com.android.vts.proto.VtsReportMessage.CoverageReportMessage.PARSER, extensionRegistry)); + break; + } + case 330: { + if (!((mutable_bitField0_ & 0x00000020) == 0x00000020)) { + profiling_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.ProfilingReportMessage>(); + mutable_bitField0_ |= 0x00000020; + } + profiling_.add(input.readMessage(com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.PARSER, extensionRegistry)); + break; + } + case 338: { + if (!((mutable_bitField0_ & 0x00000040) == 0x00000040)) { + systrace_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.SystraceReportMessage>(); + mutable_bitField0_ |= 0x00000040; + } + systrace_.add(input.readMessage(com.android.vts.proto.VtsReportMessage.SystraceReportMessage.PARSER, extensionRegistry)); + break; + } + case 810: { + if (!((mutable_bitField0_ & 0x00000080) == 0x00000080)) { + log_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.LogMessage>(); + mutable_bitField0_ |= 0x00000080; + } + log_.add(input.readMessage(com.android.vts.proto.VtsReportMessage.LogMessage.PARSER, extensionRegistry)); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000010) == 0x00000010)) { + coverage_ = java.util.Collections.unmodifiableList(coverage_); + } + if (((mutable_bitField0_ & 0x00000020) == 0x00000020)) { + profiling_ = java.util.Collections.unmodifiableList(profiling_); + } + if (((mutable_bitField0_ & 0x00000040) == 0x00000040)) { + systrace_ = java.util.Collections.unmodifiableList(systrace_); + } + if (((mutable_bitField0_ & 0x00000080) == 0x00000080)) { + log_ = java.util.Collections.unmodifiableList(log_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_TestCaseReportMessage_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_TestCaseReportMessage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.class, com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.Builder.class); + } + + public static com.google.protobuf.Parser<TestCaseReportMessage> PARSER = + new com.google.protobuf.AbstractParser<TestCaseReportMessage>() { + public TestCaseReportMessage parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new TestCaseReportMessage(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser<TestCaseReportMessage> getParserForType() { + return PARSER; + } + + private int bitField0_; + // optional bytes name = 1; + public static final int NAME_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString name_; + /** + * <code>optional bytes name = 1;</code> + * + * <pre> + * the test case name. + * </pre> + */ + public boolean hasName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * <code>optional bytes name = 1;</code> + * + * <pre> + * the test case name. + * </pre> + */ + public com.google.protobuf.ByteString getName() { + return name_; + } + + // optional .android.vts.TestCaseResult test_result = 11; + public static final int TEST_RESULT_FIELD_NUMBER = 11; + private com.android.vts.proto.VtsReportMessage.TestCaseResult testResult_; + /** + * <code>optional .android.vts.TestCaseResult test_result = 11;</code> + * + * <pre> + * the test result. + * </pre> + */ + public boolean hasTestResult() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * <code>optional .android.vts.TestCaseResult test_result = 11;</code> + * + * <pre> + * the test result. + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.TestCaseResult getTestResult() { + return testResult_; + } + + // optional int64 start_timestamp = 21; + public static final int START_TIMESTAMP_FIELD_NUMBER = 21; + private long startTimestamp_; + /** + * <code>optional int64 start_timestamp = 21;</code> + * + * <pre> + * execution start and end time stamp. + * </pre> + */ + public boolean hasStartTimestamp() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * <code>optional int64 start_timestamp = 21;</code> + * + * <pre> + * execution start and end time stamp. + * </pre> + */ + public long getStartTimestamp() { + return startTimestamp_; + } + + // optional int64 end_timestamp = 22; + public static final int END_TIMESTAMP_FIELD_NUMBER = 22; + private long endTimestamp_; + /** + * <code>optional int64 end_timestamp = 22;</code> + */ + public boolean hasEndTimestamp() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * <code>optional int64 end_timestamp = 22;</code> + */ + public long getEndTimestamp() { + return endTimestamp_; + } + + // repeated .android.vts.CoverageReportMessage coverage = 31; + public static final int COVERAGE_FIELD_NUMBER = 31; + private java.util.List<com.android.vts.proto.VtsReportMessage.CoverageReportMessage> coverage_; + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code> + * + * <pre> + * coverage report per file + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.CoverageReportMessage> getCoverageList() { + return coverage_; + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code> + * + * <pre> + * coverage report per file + * </pre> + */ + public java.util.List<? extends com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder> + getCoverageOrBuilderList() { + return coverage_; + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code> + * + * <pre> + * coverage report per file + * </pre> + */ + public int getCoverageCount() { + return coverage_.size(); + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code> + * + * <pre> + * coverage report per file + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.CoverageReportMessage getCoverage(int index) { + return coverage_.get(index); + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code> + * + * <pre> + * coverage report per file + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder getCoverageOrBuilder( + int index) { + return coverage_.get(index); + } + + // repeated .android.vts.ProfilingReportMessage profiling = 41; + public static final int PROFILING_FIELD_NUMBER = 41; + private java.util.List<com.android.vts.proto.VtsReportMessage.ProfilingReportMessage> profiling_; + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code> + * + * <pre> + * profiling reports + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.ProfilingReportMessage> getProfilingList() { + return profiling_; + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code> + * + * <pre> + * profiling reports + * </pre> + */ + public java.util.List<? extends com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder> + getProfilingOrBuilderList() { + return profiling_; + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code> + * + * <pre> + * profiling reports + * </pre> + */ + public int getProfilingCount() { + return profiling_.size(); + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code> + * + * <pre> + * profiling reports + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.ProfilingReportMessage getProfiling(int index) { + return profiling_.get(index); + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code> + * + * <pre> + * profiling reports + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder getProfilingOrBuilder( + int index) { + return profiling_.get(index); + } + + // repeated .android.vts.SystraceReportMessage systrace = 42; + public static final int SYSTRACE_FIELD_NUMBER = 42; + private java.util.List<com.android.vts.proto.VtsReportMessage.SystraceReportMessage> systrace_; + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code> + * + * <pre> + * systrace report message per file + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.SystraceReportMessage> getSystraceList() { + return systrace_; + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code> + * + * <pre> + * systrace report message per file + * </pre> + */ + public java.util.List<? extends com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder> + getSystraceOrBuilderList() { + return systrace_; + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code> + * + * <pre> + * systrace report message per file + * </pre> + */ + public int getSystraceCount() { + return systrace_.size(); + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code> + * + * <pre> + * systrace report message per file + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.SystraceReportMessage getSystrace(int index) { + return systrace_.get(index); + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code> + * + * <pre> + * systrace report message per file + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder getSystraceOrBuilder( + int index) { + return systrace_.get(index); + } + + // repeated .android.vts.LogMessage log = 101; + public static final int LOG_FIELD_NUMBER = 101; + private java.util.List<com.android.vts.proto.VtsReportMessage.LogMessage> log_; + /** + * <code>repeated .android.vts.LogMessage log = 101;</code> + * + * <pre> + * log for each test case. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.LogMessage> getLogList() { + return log_; + } + /** + * <code>repeated .android.vts.LogMessage log = 101;</code> + * + * <pre> + * log for each test case. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public java.util.List<? extends com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder> + getLogOrBuilderList() { + return log_; + } + /** + * <code>repeated .android.vts.LogMessage log = 101;</code> + * + * <pre> + * log for each test case. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public int getLogCount() { + return log_.size(); + } + /** + * <code>repeated .android.vts.LogMessage log = 101;</code> + * + * <pre> + * log for each test case. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.LogMessage getLog(int index) { + return log_.get(index); + } + /** + * <code>repeated .android.vts.LogMessage log = 101;</code> + * + * <pre> + * log for each test case. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder getLogOrBuilder( + int index) { + return log_.get(index); + } + + private void initFields() { + name_ = com.google.protobuf.ByteString.EMPTY; + testResult_ = com.android.vts.proto.VtsReportMessage.TestCaseResult.UNKNOWN_RESULT; + startTimestamp_ = 0L; + endTimestamp_ = 0L; + coverage_ = java.util.Collections.emptyList(); + profiling_ = java.util.Collections.emptyList(); + systrace_ = java.util.Collections.emptyList(); + log_ = java.util.Collections.emptyList(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, name_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeEnum(11, testResult_.getNumber()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeInt64(21, startTimestamp_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeInt64(22, endTimestamp_); + } + for (int i = 0; i < coverage_.size(); i++) { + output.writeMessage(31, coverage_.get(i)); + } + for (int i = 0; i < profiling_.size(); i++) { + output.writeMessage(41, profiling_.get(i)); + } + for (int i = 0; i < systrace_.size(); i++) { + output.writeMessage(42, systrace_.get(i)); + } + for (int i = 0; i < log_.size(); i++) { + output.writeMessage(101, log_.get(i)); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, name_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeEnumSize(11, testResult_.getNumber()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeInt64Size(21, startTimestamp_); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeInt64Size(22, endTimestamp_); + } + for (int i = 0; i < coverage_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(31, coverage_.get(i)); + } + for (int i = 0; i < profiling_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(41, profiling_.get(i)); + } + for (int i = 0; i < systrace_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(42, systrace_.get(i)); + } + for (int i = 0; i < log_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(101, log_.get(i)); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static com.android.vts.proto.VtsReportMessage.TestCaseReportMessage parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.android.vts.proto.VtsReportMessage.TestCaseReportMessage parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.TestCaseReportMessage parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.android.vts.proto.VtsReportMessage.TestCaseReportMessage parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.TestCaseReportMessage parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.TestCaseReportMessage parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.TestCaseReportMessage parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.TestCaseReportMessage parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.TestCaseReportMessage parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.TestCaseReportMessage parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(com.android.vts.proto.VtsReportMessage.TestCaseReportMessage prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code android.vts.TestCaseReportMessage} + * + * <pre> + * To specify a test case execution report. + * </pre> + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder<Builder> + implements com.android.vts.proto.VtsReportMessage.TestCaseReportMessageOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_TestCaseReportMessage_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_TestCaseReportMessage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.class, com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.Builder.class); + } + + // Construct using com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getCoverageFieldBuilder(); + getProfilingFieldBuilder(); + getSystraceFieldBuilder(); + getLogFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + name_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + testResult_ = com.android.vts.proto.VtsReportMessage.TestCaseResult.UNKNOWN_RESULT; + bitField0_ = (bitField0_ & ~0x00000002); + startTimestamp_ = 0L; + bitField0_ = (bitField0_ & ~0x00000004); + endTimestamp_ = 0L; + bitField0_ = (bitField0_ & ~0x00000008); + if (coverageBuilder_ == null) { + coverage_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000010); + } else { + coverageBuilder_.clear(); + } + if (profilingBuilder_ == null) { + profiling_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000020); + } else { + profilingBuilder_.clear(); + } + if (systraceBuilder_ == null) { + systrace_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000040); + } else { + systraceBuilder_.clear(); + } + if (logBuilder_ == null) { + log_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000080); + } else { + logBuilder_.clear(); + } + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_TestCaseReportMessage_descriptor; + } + + public com.android.vts.proto.VtsReportMessage.TestCaseReportMessage getDefaultInstanceForType() { + return com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.getDefaultInstance(); + } + + public com.android.vts.proto.VtsReportMessage.TestCaseReportMessage build() { + com.android.vts.proto.VtsReportMessage.TestCaseReportMessage result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public com.android.vts.proto.VtsReportMessage.TestCaseReportMessage buildPartial() { + com.android.vts.proto.VtsReportMessage.TestCaseReportMessage result = new com.android.vts.proto.VtsReportMessage.TestCaseReportMessage(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.name_ = name_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.testResult_ = testResult_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.startTimestamp_ = startTimestamp_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.endTimestamp_ = endTimestamp_; + if (coverageBuilder_ == null) { + if (((bitField0_ & 0x00000010) == 0x00000010)) { + coverage_ = java.util.Collections.unmodifiableList(coverage_); + bitField0_ = (bitField0_ & ~0x00000010); + } + result.coverage_ = coverage_; + } else { + result.coverage_ = coverageBuilder_.build(); + } + if (profilingBuilder_ == null) { + if (((bitField0_ & 0x00000020) == 0x00000020)) { + profiling_ = java.util.Collections.unmodifiableList(profiling_); + bitField0_ = (bitField0_ & ~0x00000020); + } + result.profiling_ = profiling_; + } else { + result.profiling_ = profilingBuilder_.build(); + } + if (systraceBuilder_ == null) { + if (((bitField0_ & 0x00000040) == 0x00000040)) { + systrace_ = java.util.Collections.unmodifiableList(systrace_); + bitField0_ = (bitField0_ & ~0x00000040); + } + result.systrace_ = systrace_; + } else { + result.systrace_ = systraceBuilder_.build(); + } + if (logBuilder_ == null) { + if (((bitField0_ & 0x00000080) == 0x00000080)) { + log_ = java.util.Collections.unmodifiableList(log_); + bitField0_ = (bitField0_ & ~0x00000080); + } + result.log_ = log_; + } else { + result.log_ = logBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.android.vts.proto.VtsReportMessage.TestCaseReportMessage) { + return mergeFrom((com.android.vts.proto.VtsReportMessage.TestCaseReportMessage)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.android.vts.proto.VtsReportMessage.TestCaseReportMessage other) { + if (other == com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.getDefaultInstance()) return this; + if (other.hasName()) { + setName(other.getName()); + } + if (other.hasTestResult()) { + setTestResult(other.getTestResult()); + } + if (other.hasStartTimestamp()) { + setStartTimestamp(other.getStartTimestamp()); + } + if (other.hasEndTimestamp()) { + setEndTimestamp(other.getEndTimestamp()); + } + if (coverageBuilder_ == null) { + if (!other.coverage_.isEmpty()) { + if (coverage_.isEmpty()) { + coverage_ = other.coverage_; + bitField0_ = (bitField0_ & ~0x00000010); + } else { + ensureCoverageIsMutable(); + coverage_.addAll(other.coverage_); + } + onChanged(); + } + } else { + if (!other.coverage_.isEmpty()) { + if (coverageBuilder_.isEmpty()) { + coverageBuilder_.dispose(); + coverageBuilder_ = null; + coverage_ = other.coverage_; + bitField0_ = (bitField0_ & ~0x00000010); + coverageBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getCoverageFieldBuilder() : null; + } else { + coverageBuilder_.addAllMessages(other.coverage_); + } + } + } + if (profilingBuilder_ == null) { + if (!other.profiling_.isEmpty()) { + if (profiling_.isEmpty()) { + profiling_ = other.profiling_; + bitField0_ = (bitField0_ & ~0x00000020); + } else { + ensureProfilingIsMutable(); + profiling_.addAll(other.profiling_); + } + onChanged(); + } + } else { + if (!other.profiling_.isEmpty()) { + if (profilingBuilder_.isEmpty()) { + profilingBuilder_.dispose(); + profilingBuilder_ = null; + profiling_ = other.profiling_; + bitField0_ = (bitField0_ & ~0x00000020); + profilingBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getProfilingFieldBuilder() : null; + } else { + profilingBuilder_.addAllMessages(other.profiling_); + } + } + } + if (systraceBuilder_ == null) { + if (!other.systrace_.isEmpty()) { + if (systrace_.isEmpty()) { + systrace_ = other.systrace_; + bitField0_ = (bitField0_ & ~0x00000040); + } else { + ensureSystraceIsMutable(); + systrace_.addAll(other.systrace_); + } + onChanged(); + } + } else { + if (!other.systrace_.isEmpty()) { + if (systraceBuilder_.isEmpty()) { + systraceBuilder_.dispose(); + systraceBuilder_ = null; + systrace_ = other.systrace_; + bitField0_ = (bitField0_ & ~0x00000040); + systraceBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getSystraceFieldBuilder() : null; + } else { + systraceBuilder_.addAllMessages(other.systrace_); + } + } + } + if (logBuilder_ == null) { + if (!other.log_.isEmpty()) { + if (log_.isEmpty()) { + log_ = other.log_; + bitField0_ = (bitField0_ & ~0x00000080); + } else { + ensureLogIsMutable(); + log_.addAll(other.log_); + } + onChanged(); + } + } else { + if (!other.log_.isEmpty()) { + if (logBuilder_.isEmpty()) { + logBuilder_.dispose(); + logBuilder_ = null; + log_ = other.log_; + bitField0_ = (bitField0_ & ~0x00000080); + logBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getLogFieldBuilder() : null; + } else { + logBuilder_.addAllMessages(other.log_); + } + } + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + com.android.vts.proto.VtsReportMessage.TestCaseReportMessage parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (com.android.vts.proto.VtsReportMessage.TestCaseReportMessage) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // optional bytes name = 1; + private com.google.protobuf.ByteString name_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes name = 1;</code> + * + * <pre> + * the test case name. + * </pre> + */ + public boolean hasName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * <code>optional bytes name = 1;</code> + * + * <pre> + * the test case name. + * </pre> + */ + public com.google.protobuf.ByteString getName() { + return name_; + } + /** + * <code>optional bytes name = 1;</code> + * + * <pre> + * the test case name. + * </pre> + */ + public Builder setName(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + name_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes name = 1;</code> + * + * <pre> + * the test case name. + * </pre> + */ + public Builder clearName() { + bitField0_ = (bitField0_ & ~0x00000001); + name_ = getDefaultInstance().getName(); + onChanged(); + return this; + } + + // optional .android.vts.TestCaseResult test_result = 11; + private com.android.vts.proto.VtsReportMessage.TestCaseResult testResult_ = com.android.vts.proto.VtsReportMessage.TestCaseResult.UNKNOWN_RESULT; + /** + * <code>optional .android.vts.TestCaseResult test_result = 11;</code> + * + * <pre> + * the test result. + * </pre> + */ + public boolean hasTestResult() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * <code>optional .android.vts.TestCaseResult test_result = 11;</code> + * + * <pre> + * the test result. + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.TestCaseResult getTestResult() { + return testResult_; + } + /** + * <code>optional .android.vts.TestCaseResult test_result = 11;</code> + * + * <pre> + * the test result. + * </pre> + */ + public Builder setTestResult(com.android.vts.proto.VtsReportMessage.TestCaseResult value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + testResult_ = value; + onChanged(); + return this; + } + /** + * <code>optional .android.vts.TestCaseResult test_result = 11;</code> + * + * <pre> + * the test result. + * </pre> + */ + public Builder clearTestResult() { + bitField0_ = (bitField0_ & ~0x00000002); + testResult_ = com.android.vts.proto.VtsReportMessage.TestCaseResult.UNKNOWN_RESULT; + onChanged(); + return this; + } + + // optional int64 start_timestamp = 21; + private long startTimestamp_ ; + /** + * <code>optional int64 start_timestamp = 21;</code> + * + * <pre> + * execution start and end time stamp. + * </pre> + */ + public boolean hasStartTimestamp() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * <code>optional int64 start_timestamp = 21;</code> + * + * <pre> + * execution start and end time stamp. + * </pre> + */ + public long getStartTimestamp() { + return startTimestamp_; + } + /** + * <code>optional int64 start_timestamp = 21;</code> + * + * <pre> + * execution start and end time stamp. + * </pre> + */ + public Builder setStartTimestamp(long value) { + bitField0_ |= 0x00000004; + startTimestamp_ = value; + onChanged(); + return this; + } + /** + * <code>optional int64 start_timestamp = 21;</code> + * + * <pre> + * execution start and end time stamp. + * </pre> + */ + public Builder clearStartTimestamp() { + bitField0_ = (bitField0_ & ~0x00000004); + startTimestamp_ = 0L; + onChanged(); + return this; + } + + // optional int64 end_timestamp = 22; + private long endTimestamp_ ; + /** + * <code>optional int64 end_timestamp = 22;</code> + */ + public boolean hasEndTimestamp() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * <code>optional int64 end_timestamp = 22;</code> + */ + public long getEndTimestamp() { + return endTimestamp_; + } + /** + * <code>optional int64 end_timestamp = 22;</code> + */ + public Builder setEndTimestamp(long value) { + bitField0_ |= 0x00000008; + endTimestamp_ = value; + onChanged(); + return this; + } + /** + * <code>optional int64 end_timestamp = 22;</code> + */ + public Builder clearEndTimestamp() { + bitField0_ = (bitField0_ & ~0x00000008); + endTimestamp_ = 0L; + onChanged(); + return this; + } + + // repeated .android.vts.CoverageReportMessage coverage = 31; + private java.util.List<com.android.vts.proto.VtsReportMessage.CoverageReportMessage> coverage_ = + java.util.Collections.emptyList(); + private void ensureCoverageIsMutable() { + if (!((bitField0_ & 0x00000010) == 0x00000010)) { + coverage_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.CoverageReportMessage>(coverage_); + bitField0_ |= 0x00000010; + } + } + + private com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.CoverageReportMessage, com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder, com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder> coverageBuilder_; + + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code> + * + * <pre> + * coverage report per file + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.CoverageReportMessage> getCoverageList() { + if (coverageBuilder_ == null) { + return java.util.Collections.unmodifiableList(coverage_); + } else { + return coverageBuilder_.getMessageList(); + } + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code> + * + * <pre> + * coverage report per file + * </pre> + */ + public int getCoverageCount() { + if (coverageBuilder_ == null) { + return coverage_.size(); + } else { + return coverageBuilder_.getCount(); + } + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code> + * + * <pre> + * coverage report per file + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.CoverageReportMessage getCoverage(int index) { + if (coverageBuilder_ == null) { + return coverage_.get(index); + } else { + return coverageBuilder_.getMessage(index); + } + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code> + * + * <pre> + * coverage report per file + * </pre> + */ + public Builder setCoverage( + int index, com.android.vts.proto.VtsReportMessage.CoverageReportMessage value) { + if (coverageBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureCoverageIsMutable(); + coverage_.set(index, value); + onChanged(); + } else { + coverageBuilder_.setMessage(index, value); + } + return this; + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code> + * + * <pre> + * coverage report per file + * </pre> + */ + public Builder setCoverage( + int index, com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder builderForValue) { + if (coverageBuilder_ == null) { + ensureCoverageIsMutable(); + coverage_.set(index, builderForValue.build()); + onChanged(); + } else { + coverageBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code> + * + * <pre> + * coverage report per file + * </pre> + */ + public Builder addCoverage(com.android.vts.proto.VtsReportMessage.CoverageReportMessage value) { + if (coverageBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureCoverageIsMutable(); + coverage_.add(value); + onChanged(); + } else { + coverageBuilder_.addMessage(value); + } + return this; + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code> + * + * <pre> + * coverage report per file + * </pre> + */ + public Builder addCoverage( + int index, com.android.vts.proto.VtsReportMessage.CoverageReportMessage value) { + if (coverageBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureCoverageIsMutable(); + coverage_.add(index, value); + onChanged(); + } else { + coverageBuilder_.addMessage(index, value); + } + return this; + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code> + * + * <pre> + * coverage report per file + * </pre> + */ + public Builder addCoverage( + com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder builderForValue) { + if (coverageBuilder_ == null) { + ensureCoverageIsMutable(); + coverage_.add(builderForValue.build()); + onChanged(); + } else { + coverageBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code> + * + * <pre> + * coverage report per file + * </pre> + */ + public Builder addCoverage( + int index, com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder builderForValue) { + if (coverageBuilder_ == null) { + ensureCoverageIsMutable(); + coverage_.add(index, builderForValue.build()); + onChanged(); + } else { + coverageBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code> + * + * <pre> + * coverage report per file + * </pre> + */ + public Builder addAllCoverage( + java.lang.Iterable<? extends com.android.vts.proto.VtsReportMessage.CoverageReportMessage> values) { + if (coverageBuilder_ == null) { + ensureCoverageIsMutable(); + super.addAll(values, coverage_); + onChanged(); + } else { + coverageBuilder_.addAllMessages(values); + } + return this; + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code> + * + * <pre> + * coverage report per file + * </pre> + */ + public Builder clearCoverage() { + if (coverageBuilder_ == null) { + coverage_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000010); + onChanged(); + } else { + coverageBuilder_.clear(); + } + return this; + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code> + * + * <pre> + * coverage report per file + * </pre> + */ + public Builder removeCoverage(int index) { + if (coverageBuilder_ == null) { + ensureCoverageIsMutable(); + coverage_.remove(index); + onChanged(); + } else { + coverageBuilder_.remove(index); + } + return this; + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code> + * + * <pre> + * coverage report per file + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder getCoverageBuilder( + int index) { + return getCoverageFieldBuilder().getBuilder(index); + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code> + * + * <pre> + * coverage report per file + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder getCoverageOrBuilder( + int index) { + if (coverageBuilder_ == null) { + return coverage_.get(index); } else { + return coverageBuilder_.getMessageOrBuilder(index); + } + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code> + * + * <pre> + * coverage report per file + * </pre> + */ + public java.util.List<? extends com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder> + getCoverageOrBuilderList() { + if (coverageBuilder_ != null) { + return coverageBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(coverage_); + } + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code> + * + * <pre> + * coverage report per file + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder addCoverageBuilder() { + return getCoverageFieldBuilder().addBuilder( + com.android.vts.proto.VtsReportMessage.CoverageReportMessage.getDefaultInstance()); + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code> + * + * <pre> + * coverage report per file + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder addCoverageBuilder( + int index) { + return getCoverageFieldBuilder().addBuilder( + index, com.android.vts.proto.VtsReportMessage.CoverageReportMessage.getDefaultInstance()); + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 31;</code> + * + * <pre> + * coverage report per file + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder> + getCoverageBuilderList() { + return getCoverageFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.CoverageReportMessage, com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder, com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder> + getCoverageFieldBuilder() { + if (coverageBuilder_ == null) { + coverageBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.CoverageReportMessage, com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder, com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder>( + coverage_, + ((bitField0_ & 0x00000010) == 0x00000010), + getParentForChildren(), + isClean()); + coverage_ = null; + } + return coverageBuilder_; + } + + // repeated .android.vts.ProfilingReportMessage profiling = 41; + private java.util.List<com.android.vts.proto.VtsReportMessage.ProfilingReportMessage> profiling_ = + java.util.Collections.emptyList(); + private void ensureProfilingIsMutable() { + if (!((bitField0_ & 0x00000020) == 0x00000020)) { + profiling_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.ProfilingReportMessage>(profiling_); + bitField0_ |= 0x00000020; + } + } + + private com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.ProfilingReportMessage, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder, com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder> profilingBuilder_; + + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code> + * + * <pre> + * profiling reports + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.ProfilingReportMessage> getProfilingList() { + if (profilingBuilder_ == null) { + return java.util.Collections.unmodifiableList(profiling_); + } else { + return profilingBuilder_.getMessageList(); + } + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code> + * + * <pre> + * profiling reports + * </pre> + */ + public int getProfilingCount() { + if (profilingBuilder_ == null) { + return profiling_.size(); + } else { + return profilingBuilder_.getCount(); + } + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code> + * + * <pre> + * profiling reports + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.ProfilingReportMessage getProfiling(int index) { + if (profilingBuilder_ == null) { + return profiling_.get(index); + } else { + return profilingBuilder_.getMessage(index); + } + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code> + * + * <pre> + * profiling reports + * </pre> + */ + public Builder setProfiling( + int index, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage value) { + if (profilingBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureProfilingIsMutable(); + profiling_.set(index, value); + onChanged(); + } else { + profilingBuilder_.setMessage(index, value); + } + return this; + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code> + * + * <pre> + * profiling reports + * </pre> + */ + public Builder setProfiling( + int index, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder builderForValue) { + if (profilingBuilder_ == null) { + ensureProfilingIsMutable(); + profiling_.set(index, builderForValue.build()); + onChanged(); + } else { + profilingBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code> + * + * <pre> + * profiling reports + * </pre> + */ + public Builder addProfiling(com.android.vts.proto.VtsReportMessage.ProfilingReportMessage value) { + if (profilingBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureProfilingIsMutable(); + profiling_.add(value); + onChanged(); + } else { + profilingBuilder_.addMessage(value); + } + return this; + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code> + * + * <pre> + * profiling reports + * </pre> + */ + public Builder addProfiling( + int index, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage value) { + if (profilingBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureProfilingIsMutable(); + profiling_.add(index, value); + onChanged(); + } else { + profilingBuilder_.addMessage(index, value); + } + return this; + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code> + * + * <pre> + * profiling reports + * </pre> + */ + public Builder addProfiling( + com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder builderForValue) { + if (profilingBuilder_ == null) { + ensureProfilingIsMutable(); + profiling_.add(builderForValue.build()); + onChanged(); + } else { + profilingBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code> + * + * <pre> + * profiling reports + * </pre> + */ + public Builder addProfiling( + int index, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder builderForValue) { + if (profilingBuilder_ == null) { + ensureProfilingIsMutable(); + profiling_.add(index, builderForValue.build()); + onChanged(); + } else { + profilingBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code> + * + * <pre> + * profiling reports + * </pre> + */ + public Builder addAllProfiling( + java.lang.Iterable<? extends com.android.vts.proto.VtsReportMessage.ProfilingReportMessage> values) { + if (profilingBuilder_ == null) { + ensureProfilingIsMutable(); + super.addAll(values, profiling_); + onChanged(); + } else { + profilingBuilder_.addAllMessages(values); + } + return this; + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code> + * + * <pre> + * profiling reports + * </pre> + */ + public Builder clearProfiling() { + if (profilingBuilder_ == null) { + profiling_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000020); + onChanged(); + } else { + profilingBuilder_.clear(); + } + return this; + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code> + * + * <pre> + * profiling reports + * </pre> + */ + public Builder removeProfiling(int index) { + if (profilingBuilder_ == null) { + ensureProfilingIsMutable(); + profiling_.remove(index); + onChanged(); + } else { + profilingBuilder_.remove(index); + } + return this; + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code> + * + * <pre> + * profiling reports + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder getProfilingBuilder( + int index) { + return getProfilingFieldBuilder().getBuilder(index); + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code> + * + * <pre> + * profiling reports + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder getProfilingOrBuilder( + int index) { + if (profilingBuilder_ == null) { + return profiling_.get(index); } else { + return profilingBuilder_.getMessageOrBuilder(index); + } + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code> + * + * <pre> + * profiling reports + * </pre> + */ + public java.util.List<? extends com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder> + getProfilingOrBuilderList() { + if (profilingBuilder_ != null) { + return profilingBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(profiling_); + } + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code> + * + * <pre> + * profiling reports + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder addProfilingBuilder() { + return getProfilingFieldBuilder().addBuilder( + com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.getDefaultInstance()); + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code> + * + * <pre> + * profiling reports + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder addProfilingBuilder( + int index) { + return getProfilingFieldBuilder().addBuilder( + index, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.getDefaultInstance()); + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 41;</code> + * + * <pre> + * profiling reports + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder> + getProfilingBuilderList() { + return getProfilingFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.ProfilingReportMessage, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder, com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder> + getProfilingFieldBuilder() { + if (profilingBuilder_ == null) { + profilingBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.ProfilingReportMessage, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder, com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder>( + profiling_, + ((bitField0_ & 0x00000020) == 0x00000020), + getParentForChildren(), + isClean()); + profiling_ = null; + } + return profilingBuilder_; + } + + // repeated .android.vts.SystraceReportMessage systrace = 42; + private java.util.List<com.android.vts.proto.VtsReportMessage.SystraceReportMessage> systrace_ = + java.util.Collections.emptyList(); + private void ensureSystraceIsMutable() { + if (!((bitField0_ & 0x00000040) == 0x00000040)) { + systrace_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.SystraceReportMessage>(systrace_); + bitField0_ |= 0x00000040; + } + } + + private com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.SystraceReportMessage, com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder, com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder> systraceBuilder_; + + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code> + * + * <pre> + * systrace report message per file + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.SystraceReportMessage> getSystraceList() { + if (systraceBuilder_ == null) { + return java.util.Collections.unmodifiableList(systrace_); + } else { + return systraceBuilder_.getMessageList(); + } + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code> + * + * <pre> + * systrace report message per file + * </pre> + */ + public int getSystraceCount() { + if (systraceBuilder_ == null) { + return systrace_.size(); + } else { + return systraceBuilder_.getCount(); + } + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code> + * + * <pre> + * systrace report message per file + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.SystraceReportMessage getSystrace(int index) { + if (systraceBuilder_ == null) { + return systrace_.get(index); + } else { + return systraceBuilder_.getMessage(index); + } + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code> + * + * <pre> + * systrace report message per file + * </pre> + */ + public Builder setSystrace( + int index, com.android.vts.proto.VtsReportMessage.SystraceReportMessage value) { + if (systraceBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureSystraceIsMutable(); + systrace_.set(index, value); + onChanged(); + } else { + systraceBuilder_.setMessage(index, value); + } + return this; + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code> + * + * <pre> + * systrace report message per file + * </pre> + */ + public Builder setSystrace( + int index, com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder builderForValue) { + if (systraceBuilder_ == null) { + ensureSystraceIsMutable(); + systrace_.set(index, builderForValue.build()); + onChanged(); + } else { + systraceBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code> + * + * <pre> + * systrace report message per file + * </pre> + */ + public Builder addSystrace(com.android.vts.proto.VtsReportMessage.SystraceReportMessage value) { + if (systraceBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureSystraceIsMutable(); + systrace_.add(value); + onChanged(); + } else { + systraceBuilder_.addMessage(value); + } + return this; + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code> + * + * <pre> + * systrace report message per file + * </pre> + */ + public Builder addSystrace( + int index, com.android.vts.proto.VtsReportMessage.SystraceReportMessage value) { + if (systraceBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureSystraceIsMutable(); + systrace_.add(index, value); + onChanged(); + } else { + systraceBuilder_.addMessage(index, value); + } + return this; + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code> + * + * <pre> + * systrace report message per file + * </pre> + */ + public Builder addSystrace( + com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder builderForValue) { + if (systraceBuilder_ == null) { + ensureSystraceIsMutable(); + systrace_.add(builderForValue.build()); + onChanged(); + } else { + systraceBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code> + * + * <pre> + * systrace report message per file + * </pre> + */ + public Builder addSystrace( + int index, com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder builderForValue) { + if (systraceBuilder_ == null) { + ensureSystraceIsMutable(); + systrace_.add(index, builderForValue.build()); + onChanged(); + } else { + systraceBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code> + * + * <pre> + * systrace report message per file + * </pre> + */ + public Builder addAllSystrace( + java.lang.Iterable<? extends com.android.vts.proto.VtsReportMessage.SystraceReportMessage> values) { + if (systraceBuilder_ == null) { + ensureSystraceIsMutable(); + super.addAll(values, systrace_); + onChanged(); + } else { + systraceBuilder_.addAllMessages(values); + } + return this; + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code> + * + * <pre> + * systrace report message per file + * </pre> + */ + public Builder clearSystrace() { + if (systraceBuilder_ == null) { + systrace_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000040); + onChanged(); + } else { + systraceBuilder_.clear(); + } + return this; + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code> + * + * <pre> + * systrace report message per file + * </pre> + */ + public Builder removeSystrace(int index) { + if (systraceBuilder_ == null) { + ensureSystraceIsMutable(); + systrace_.remove(index); + onChanged(); + } else { + systraceBuilder_.remove(index); + } + return this; + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code> + * + * <pre> + * systrace report message per file + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder getSystraceBuilder( + int index) { + return getSystraceFieldBuilder().getBuilder(index); + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code> + * + * <pre> + * systrace report message per file + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder getSystraceOrBuilder( + int index) { + if (systraceBuilder_ == null) { + return systrace_.get(index); } else { + return systraceBuilder_.getMessageOrBuilder(index); + } + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code> + * + * <pre> + * systrace report message per file + * </pre> + */ + public java.util.List<? extends com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder> + getSystraceOrBuilderList() { + if (systraceBuilder_ != null) { + return systraceBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(systrace_); + } + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code> + * + * <pre> + * systrace report message per file + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder addSystraceBuilder() { + return getSystraceFieldBuilder().addBuilder( + com.android.vts.proto.VtsReportMessage.SystraceReportMessage.getDefaultInstance()); + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code> + * + * <pre> + * systrace report message per file + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder addSystraceBuilder( + int index) { + return getSystraceFieldBuilder().addBuilder( + index, com.android.vts.proto.VtsReportMessage.SystraceReportMessage.getDefaultInstance()); + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 42;</code> + * + * <pre> + * systrace report message per file + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder> + getSystraceBuilderList() { + return getSystraceFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.SystraceReportMessage, com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder, com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder> + getSystraceFieldBuilder() { + if (systraceBuilder_ == null) { + systraceBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.SystraceReportMessage, com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder, com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder>( + systrace_, + ((bitField0_ & 0x00000040) == 0x00000040), + getParentForChildren(), + isClean()); + systrace_ = null; + } + return systraceBuilder_; + } + + // repeated .android.vts.LogMessage log = 101; + private java.util.List<com.android.vts.proto.VtsReportMessage.LogMessage> log_ = + java.util.Collections.emptyList(); + private void ensureLogIsMutable() { + if (!((bitField0_ & 0x00000080) == 0x00000080)) { + log_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.LogMessage>(log_); + bitField0_ |= 0x00000080; + } + } + + private com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.LogMessage, com.android.vts.proto.VtsReportMessage.LogMessage.Builder, com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder> logBuilder_; + + /** + * <code>repeated .android.vts.LogMessage log = 101;</code> + * + * <pre> + * log for each test case. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.LogMessage> getLogList() { + if (logBuilder_ == null) { + return java.util.Collections.unmodifiableList(log_); + } else { + return logBuilder_.getMessageList(); + } + } + /** + * <code>repeated .android.vts.LogMessage log = 101;</code> + * + * <pre> + * log for each test case. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public int getLogCount() { + if (logBuilder_ == null) { + return log_.size(); + } else { + return logBuilder_.getCount(); + } + } + /** + * <code>repeated .android.vts.LogMessage log = 101;</code> + * + * <pre> + * log for each test case. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.LogMessage getLog(int index) { + if (logBuilder_ == null) { + return log_.get(index); + } else { + return logBuilder_.getMessage(index); + } + } + /** + * <code>repeated .android.vts.LogMessage log = 101;</code> + * + * <pre> + * log for each test case. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public Builder setLog( + int index, com.android.vts.proto.VtsReportMessage.LogMessage value) { + if (logBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureLogIsMutable(); + log_.set(index, value); + onChanged(); + } else { + logBuilder_.setMessage(index, value); + } + return this; + } + /** + * <code>repeated .android.vts.LogMessage log = 101;</code> + * + * <pre> + * log for each test case. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public Builder setLog( + int index, com.android.vts.proto.VtsReportMessage.LogMessage.Builder builderForValue) { + if (logBuilder_ == null) { + ensureLogIsMutable(); + log_.set(index, builderForValue.build()); + onChanged(); + } else { + logBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.LogMessage log = 101;</code> + * + * <pre> + * log for each test case. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public Builder addLog(com.android.vts.proto.VtsReportMessage.LogMessage value) { + if (logBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureLogIsMutable(); + log_.add(value); + onChanged(); + } else { + logBuilder_.addMessage(value); + } + return this; + } + /** + * <code>repeated .android.vts.LogMessage log = 101;</code> + * + * <pre> + * log for each test case. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public Builder addLog( + int index, com.android.vts.proto.VtsReportMessage.LogMessage value) { + if (logBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureLogIsMutable(); + log_.add(index, value); + onChanged(); + } else { + logBuilder_.addMessage(index, value); + } + return this; + } + /** + * <code>repeated .android.vts.LogMessage log = 101;</code> + * + * <pre> + * log for each test case. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public Builder addLog( + com.android.vts.proto.VtsReportMessage.LogMessage.Builder builderForValue) { + if (logBuilder_ == null) { + ensureLogIsMutable(); + log_.add(builderForValue.build()); + onChanged(); + } else { + logBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.LogMessage log = 101;</code> + * + * <pre> + * log for each test case. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public Builder addLog( + int index, com.android.vts.proto.VtsReportMessage.LogMessage.Builder builderForValue) { + if (logBuilder_ == null) { + ensureLogIsMutable(); + log_.add(index, builderForValue.build()); + onChanged(); + } else { + logBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.LogMessage log = 101;</code> + * + * <pre> + * log for each test case. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public Builder addAllLog( + java.lang.Iterable<? extends com.android.vts.proto.VtsReportMessage.LogMessage> values) { + if (logBuilder_ == null) { + ensureLogIsMutable(); + super.addAll(values, log_); + onChanged(); + } else { + logBuilder_.addAllMessages(values); + } + return this; + } + /** + * <code>repeated .android.vts.LogMessage log = 101;</code> + * + * <pre> + * log for each test case. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public Builder clearLog() { + if (logBuilder_ == null) { + log_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000080); + onChanged(); + } else { + logBuilder_.clear(); + } + return this; + } + /** + * <code>repeated .android.vts.LogMessage log = 101;</code> + * + * <pre> + * log for each test case. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public Builder removeLog(int index) { + if (logBuilder_ == null) { + ensureLogIsMutable(); + log_.remove(index); + onChanged(); + } else { + logBuilder_.remove(index); + } + return this; + } + /** + * <code>repeated .android.vts.LogMessage log = 101;</code> + * + * <pre> + * log for each test case. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.LogMessage.Builder getLogBuilder( + int index) { + return getLogFieldBuilder().getBuilder(index); + } + /** + * <code>repeated .android.vts.LogMessage log = 101;</code> + * + * <pre> + * log for each test case. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder getLogOrBuilder( + int index) { + if (logBuilder_ == null) { + return log_.get(index); } else { + return logBuilder_.getMessageOrBuilder(index); + } + } + /** + * <code>repeated .android.vts.LogMessage log = 101;</code> + * + * <pre> + * log for each test case. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public java.util.List<? extends com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder> + getLogOrBuilderList() { + if (logBuilder_ != null) { + return logBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(log_); + } + } + /** + * <code>repeated .android.vts.LogMessage log = 101;</code> + * + * <pre> + * log for each test case. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.LogMessage.Builder addLogBuilder() { + return getLogFieldBuilder().addBuilder( + com.android.vts.proto.VtsReportMessage.LogMessage.getDefaultInstance()); + } + /** + * <code>repeated .android.vts.LogMessage log = 101;</code> + * + * <pre> + * log for each test case. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.LogMessage.Builder addLogBuilder( + int index) { + return getLogFieldBuilder().addBuilder( + index, com.android.vts.proto.VtsReportMessage.LogMessage.getDefaultInstance()); + } + /** + * <code>repeated .android.vts.LogMessage log = 101;</code> + * + * <pre> + * log for each test case. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.LogMessage.Builder> + getLogBuilderList() { + return getLogFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.LogMessage, com.android.vts.proto.VtsReportMessage.LogMessage.Builder, com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder> + getLogFieldBuilder() { + if (logBuilder_ == null) { + logBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.LogMessage, com.android.vts.proto.VtsReportMessage.LogMessage.Builder, com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder>( + log_, + ((bitField0_ & 0x00000080) == 0x00000080), + getParentForChildren(), + isClean()); + log_ = null; + } + return logBuilder_; + } + + // @@protoc_insertion_point(builder_scope:android.vts.TestCaseReportMessage) + } + + static { + defaultInstance = new TestCaseReportMessage(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:android.vts.TestCaseReportMessage) + } + + public interface ProfilingReportMessageOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // optional bytes name = 1; + /** + * <code>optional bytes name = 1;</code> + * + * <pre> + * the instrumentation point name. + * </pre> + */ + boolean hasName(); + /** + * <code>optional bytes name = 1;</code> + * + * <pre> + * the instrumentation point name. + * </pre> + */ + com.google.protobuf.ByteString getName(); + + // optional .android.vts.VtsProfilingType type = 2; + /** + * <code>optional .android.vts.VtsProfilingType type = 2;</code> + */ + boolean hasType(); + /** + * <code>optional .android.vts.VtsProfilingType type = 2;</code> + */ + com.android.vts.proto.VtsReportMessage.VtsProfilingType getType(); + + // optional .android.vts.VtsProfilingRegressionMode regression_mode = 3; + /** + * <code>optional .android.vts.VtsProfilingRegressionMode regression_mode = 3;</code> + */ + boolean hasRegressionMode(); + /** + * <code>optional .android.vts.VtsProfilingRegressionMode regression_mode = 3;</code> + */ + com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode getRegressionMode(); + + // optional int64 start_timestamp = 11; + /** + * <code>optional int64 start_timestamp = 11;</code> + * + * <pre> + * profiling start and end time stamp (for performance). + * </pre> + */ + boolean hasStartTimestamp(); + /** + * <code>optional int64 start_timestamp = 11;</code> + * + * <pre> + * profiling start and end time stamp (for performance). + * </pre> + */ + long getStartTimestamp(); + + // optional int64 end_timestamp = 12; + /** + * <code>optional int64 end_timestamp = 12;</code> + */ + boolean hasEndTimestamp(); + /** + * <code>optional int64 end_timestamp = 12;</code> + */ + long getEndTimestamp(); + + // repeated bytes label = 21; + /** + * <code>repeated bytes label = 21;</code> + */ + java.util.List<com.google.protobuf.ByteString> getLabelList(); + /** + * <code>repeated bytes label = 21;</code> + */ + int getLabelCount(); + /** + * <code>repeated bytes label = 21;</code> + */ + com.google.protobuf.ByteString getLabel(int index); + + // repeated int64 value = 22; + /** + * <code>repeated int64 value = 22;</code> + */ + java.util.List<java.lang.Long> getValueList(); + /** + * <code>repeated int64 value = 22;</code> + */ + int getValueCount(); + /** + * <code>repeated int64 value = 22;</code> + */ + long getValue(int index); + + // optional bytes x_axis_label = 31; + /** + * <code>optional bytes x_axis_label = 31;</code> + * + * <pre> + * x-axis and y-axis title labels when displaying the data as a graph + * </pre> + */ + boolean hasXAxisLabel(); + /** + * <code>optional bytes x_axis_label = 31;</code> + * + * <pre> + * x-axis and y-axis title labels when displaying the data as a graph + * </pre> + */ + com.google.protobuf.ByteString getXAxisLabel(); + + // optional bytes y_axis_label = 32; + /** + * <code>optional bytes y_axis_label = 32;</code> + */ + boolean hasYAxisLabel(); + /** + * <code>optional bytes y_axis_label = 32;</code> + */ + com.google.protobuf.ByteString getYAxisLabel(); + + // repeated bytes options = 41; + /** + * <code>repeated bytes options = 41;</code> + * + * <pre> + * a list of strings where each string has the form of 'key=value'. + * used to tell certain properties of the data (e.g., passthrough vs. + * binderized). + * </pre> + */ + java.util.List<com.google.protobuf.ByteString> getOptionsList(); + /** + * <code>repeated bytes options = 41;</code> + * + * <pre> + * a list of strings where each string has the form of 'key=value'. + * used to tell certain properties of the data (e.g., passthrough vs. + * binderized). + * </pre> + */ + int getOptionsCount(); + /** + * <code>repeated bytes options = 41;</code> + * + * <pre> + * a list of strings where each string has the form of 'key=value'. + * used to tell certain properties of the data (e.g., passthrough vs. + * binderized). + * </pre> + */ + com.google.protobuf.ByteString getOptions(int index); + } + /** + * Protobuf type {@code android.vts.ProfilingReportMessage} + * + * <pre> + * To specify a profiling report. + * </pre> + */ + public static final class ProfilingReportMessage extends + com.google.protobuf.GeneratedMessage + implements ProfilingReportMessageOrBuilder { + // Use ProfilingReportMessage.newBuilder() to construct. + private ProfilingReportMessage(com.google.protobuf.GeneratedMessage.Builder<?> builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private ProfilingReportMessage(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final ProfilingReportMessage defaultInstance; + public static ProfilingReportMessage getDefaultInstance() { + return defaultInstance; + } + + public ProfilingReportMessage getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private ProfilingReportMessage( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + name_ = input.readBytes(); + break; + } + case 16: { + int rawValue = input.readEnum(); + com.android.vts.proto.VtsReportMessage.VtsProfilingType value = com.android.vts.proto.VtsReportMessage.VtsProfilingType.valueOf(rawValue); + if (value == null) { + unknownFields.mergeVarintField(2, rawValue); + } else { + bitField0_ |= 0x00000002; + type_ = value; + } + break; + } + case 24: { + int rawValue = input.readEnum(); + com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode value = com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode.valueOf(rawValue); + if (value == null) { + unknownFields.mergeVarintField(3, rawValue); + } else { + bitField0_ |= 0x00000004; + regressionMode_ = value; + } + break; + } + case 88: { + bitField0_ |= 0x00000008; + startTimestamp_ = input.readInt64(); + break; + } + case 96: { + bitField0_ |= 0x00000010; + endTimestamp_ = input.readInt64(); + break; + } + case 170: { + if (!((mutable_bitField0_ & 0x00000020) == 0x00000020)) { + label_ = new java.util.ArrayList<com.google.protobuf.ByteString>(); + mutable_bitField0_ |= 0x00000020; + } + label_.add(input.readBytes()); + break; + } + case 176: { + if (!((mutable_bitField0_ & 0x00000040) == 0x00000040)) { + value_ = new java.util.ArrayList<java.lang.Long>(); + mutable_bitField0_ |= 0x00000040; + } + value_.add(input.readInt64()); + break; + } + case 178: { + int length = input.readRawVarint32(); + int limit = input.pushLimit(length); + if (!((mutable_bitField0_ & 0x00000040) == 0x00000040) && input.getBytesUntilLimit() > 0) { + value_ = new java.util.ArrayList<java.lang.Long>(); + mutable_bitField0_ |= 0x00000040; + } + while (input.getBytesUntilLimit() > 0) { + value_.add(input.readInt64()); + } + input.popLimit(limit); + break; + } + case 250: { + bitField0_ |= 0x00000020; + xAxisLabel_ = input.readBytes(); + break; + } + case 258: { + bitField0_ |= 0x00000040; + yAxisLabel_ = input.readBytes(); + break; + } + case 330: { + if (!((mutable_bitField0_ & 0x00000200) == 0x00000200)) { + options_ = new java.util.ArrayList<com.google.protobuf.ByteString>(); + mutable_bitField0_ |= 0x00000200; + } + options_.add(input.readBytes()); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000020) == 0x00000020)) { + label_ = java.util.Collections.unmodifiableList(label_); + } + if (((mutable_bitField0_ & 0x00000040) == 0x00000040)) { + value_ = java.util.Collections.unmodifiableList(value_); + } + if (((mutable_bitField0_ & 0x00000200) == 0x00000200)) { + options_ = java.util.Collections.unmodifiableList(options_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_ProfilingReportMessage_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_ProfilingReportMessage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.class, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder.class); + } + + public static com.google.protobuf.Parser<ProfilingReportMessage> PARSER = + new com.google.protobuf.AbstractParser<ProfilingReportMessage>() { + public ProfilingReportMessage parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new ProfilingReportMessage(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser<ProfilingReportMessage> getParserForType() { + return PARSER; + } + + private int bitField0_; + // optional bytes name = 1; + public static final int NAME_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString name_; + /** + * <code>optional bytes name = 1;</code> + * + * <pre> + * the instrumentation point name. + * </pre> + */ + public boolean hasName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * <code>optional bytes name = 1;</code> + * + * <pre> + * the instrumentation point name. + * </pre> + */ + public com.google.protobuf.ByteString getName() { + return name_; + } + + // optional .android.vts.VtsProfilingType type = 2; + public static final int TYPE_FIELD_NUMBER = 2; + private com.android.vts.proto.VtsReportMessage.VtsProfilingType type_; + /** + * <code>optional .android.vts.VtsProfilingType type = 2;</code> + */ + public boolean hasType() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * <code>optional .android.vts.VtsProfilingType type = 2;</code> + */ + public com.android.vts.proto.VtsReportMessage.VtsProfilingType getType() { + return type_; + } + + // optional .android.vts.VtsProfilingRegressionMode regression_mode = 3; + public static final int REGRESSION_MODE_FIELD_NUMBER = 3; + private com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode regressionMode_; + /** + * <code>optional .android.vts.VtsProfilingRegressionMode regression_mode = 3;</code> + */ + public boolean hasRegressionMode() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * <code>optional .android.vts.VtsProfilingRegressionMode regression_mode = 3;</code> + */ + public com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode getRegressionMode() { + return regressionMode_; + } + + // optional int64 start_timestamp = 11; + public static final int START_TIMESTAMP_FIELD_NUMBER = 11; + private long startTimestamp_; + /** + * <code>optional int64 start_timestamp = 11;</code> + * + * <pre> + * profiling start and end time stamp (for performance). + * </pre> + */ + public boolean hasStartTimestamp() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * <code>optional int64 start_timestamp = 11;</code> + * + * <pre> + * profiling start and end time stamp (for performance). + * </pre> + */ + public long getStartTimestamp() { + return startTimestamp_; + } + + // optional int64 end_timestamp = 12; + public static final int END_TIMESTAMP_FIELD_NUMBER = 12; + private long endTimestamp_; + /** + * <code>optional int64 end_timestamp = 12;</code> + */ + public boolean hasEndTimestamp() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * <code>optional int64 end_timestamp = 12;</code> + */ + public long getEndTimestamp() { + return endTimestamp_; + } + + // repeated bytes label = 21; + public static final int LABEL_FIELD_NUMBER = 21; + private java.util.List<com.google.protobuf.ByteString> label_; + /** + * <code>repeated bytes label = 21;</code> + */ + public java.util.List<com.google.protobuf.ByteString> + getLabelList() { + return label_; + } + /** + * <code>repeated bytes label = 21;</code> + */ + public int getLabelCount() { + return label_.size(); + } + /** + * <code>repeated bytes label = 21;</code> + */ + public com.google.protobuf.ByteString getLabel(int index) { + return label_.get(index); + } + + // repeated int64 value = 22; + public static final int VALUE_FIELD_NUMBER = 22; + private java.util.List<java.lang.Long> value_; + /** + * <code>repeated int64 value = 22;</code> + */ + public java.util.List<java.lang.Long> + getValueList() { + return value_; + } + /** + * <code>repeated int64 value = 22;</code> + */ + public int getValueCount() { + return value_.size(); + } + /** + * <code>repeated int64 value = 22;</code> + */ + public long getValue(int index) { + return value_.get(index); + } + + // optional bytes x_axis_label = 31; + public static final int X_AXIS_LABEL_FIELD_NUMBER = 31; + private com.google.protobuf.ByteString xAxisLabel_; + /** + * <code>optional bytes x_axis_label = 31;</code> + * + * <pre> + * x-axis and y-axis title labels when displaying the data as a graph + * </pre> + */ + public boolean hasXAxisLabel() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * <code>optional bytes x_axis_label = 31;</code> + * + * <pre> + * x-axis and y-axis title labels when displaying the data as a graph + * </pre> + */ + public com.google.protobuf.ByteString getXAxisLabel() { + return xAxisLabel_; + } + + // optional bytes y_axis_label = 32; + public static final int Y_AXIS_LABEL_FIELD_NUMBER = 32; + private com.google.protobuf.ByteString yAxisLabel_; + /** + * <code>optional bytes y_axis_label = 32;</code> + */ + public boolean hasYAxisLabel() { + return ((bitField0_ & 0x00000040) == 0x00000040); + } + /** + * <code>optional bytes y_axis_label = 32;</code> + */ + public com.google.protobuf.ByteString getYAxisLabel() { + return yAxisLabel_; + } + + // repeated bytes options = 41; + public static final int OPTIONS_FIELD_NUMBER = 41; + private java.util.List<com.google.protobuf.ByteString> options_; + /** + * <code>repeated bytes options = 41;</code> + * + * <pre> + * a list of strings where each string has the form of 'key=value'. + * used to tell certain properties of the data (e.g., passthrough vs. + * binderized). + * </pre> + */ + public java.util.List<com.google.protobuf.ByteString> + getOptionsList() { + return options_; + } + /** + * <code>repeated bytes options = 41;</code> + * + * <pre> + * a list of strings where each string has the form of 'key=value'. + * used to tell certain properties of the data (e.g., passthrough vs. + * binderized). + * </pre> + */ + public int getOptionsCount() { + return options_.size(); + } + /** + * <code>repeated bytes options = 41;</code> + * + * <pre> + * a list of strings where each string has the form of 'key=value'. + * used to tell certain properties of the data (e.g., passthrough vs. + * binderized). + * </pre> + */ + public com.google.protobuf.ByteString getOptions(int index) { + return options_.get(index); + } + + private void initFields() { + name_ = com.google.protobuf.ByteString.EMPTY; + type_ = com.android.vts.proto.VtsReportMessage.VtsProfilingType.UNKNOWN_VTS_PROFILING_TYPE; + regressionMode_ = com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode.UNKNOWN_REGRESSION_MODE; + startTimestamp_ = 0L; + endTimestamp_ = 0L; + label_ = java.util.Collections.emptyList(); + value_ = java.util.Collections.emptyList(); + xAxisLabel_ = com.google.protobuf.ByteString.EMPTY; + yAxisLabel_ = com.google.protobuf.ByteString.EMPTY; + options_ = java.util.Collections.emptyList(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, name_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeEnum(2, type_.getNumber()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeEnum(3, regressionMode_.getNumber()); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeInt64(11, startTimestamp_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + output.writeInt64(12, endTimestamp_); + } + for (int i = 0; i < label_.size(); i++) { + output.writeBytes(21, label_.get(i)); + } + for (int i = 0; i < value_.size(); i++) { + output.writeInt64(22, value_.get(i)); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + output.writeBytes(31, xAxisLabel_); + } + if (((bitField0_ & 0x00000040) == 0x00000040)) { + output.writeBytes(32, yAxisLabel_); + } + for (int i = 0; i < options_.size(); i++) { + output.writeBytes(41, options_.get(i)); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, name_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeEnumSize(2, type_.getNumber()); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeEnumSize(3, regressionMode_.getNumber()); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeInt64Size(11, startTimestamp_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + size += com.google.protobuf.CodedOutputStream + .computeInt64Size(12, endTimestamp_); + } + { + int dataSize = 0; + for (int i = 0; i < label_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeBytesSizeNoTag(label_.get(i)); + } + size += dataSize; + size += 2 * getLabelList().size(); + } + { + int dataSize = 0; + for (int i = 0; i < value_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeInt64SizeNoTag(value_.get(i)); + } + size += dataSize; + size += 2 * getValueList().size(); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(31, xAxisLabel_); + } + if (((bitField0_ & 0x00000040) == 0x00000040)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(32, yAxisLabel_); + } + { + int dataSize = 0; + for (int i = 0; i < options_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeBytesSizeNoTag(options_.get(i)); + } + size += dataSize; + size += 2 * getOptionsList().size(); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static com.android.vts.proto.VtsReportMessage.ProfilingReportMessage parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.android.vts.proto.VtsReportMessage.ProfilingReportMessage parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.ProfilingReportMessage parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.android.vts.proto.VtsReportMessage.ProfilingReportMessage parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.ProfilingReportMessage parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.ProfilingReportMessage parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.ProfilingReportMessage parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.ProfilingReportMessage parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.ProfilingReportMessage parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.ProfilingReportMessage parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(com.android.vts.proto.VtsReportMessage.ProfilingReportMessage prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code android.vts.ProfilingReportMessage} + * + * <pre> + * To specify a profiling report. + * </pre> + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder<Builder> + implements com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_ProfilingReportMessage_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_ProfilingReportMessage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.class, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder.class); + } + + // Construct using com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + name_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + type_ = com.android.vts.proto.VtsReportMessage.VtsProfilingType.UNKNOWN_VTS_PROFILING_TYPE; + bitField0_ = (bitField0_ & ~0x00000002); + regressionMode_ = com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode.UNKNOWN_REGRESSION_MODE; + bitField0_ = (bitField0_ & ~0x00000004); + startTimestamp_ = 0L; + bitField0_ = (bitField0_ & ~0x00000008); + endTimestamp_ = 0L; + bitField0_ = (bitField0_ & ~0x00000010); + label_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000020); + value_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000040); + xAxisLabel_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000080); + yAxisLabel_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000100); + options_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000200); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_ProfilingReportMessage_descriptor; + } + + public com.android.vts.proto.VtsReportMessage.ProfilingReportMessage getDefaultInstanceForType() { + return com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.getDefaultInstance(); + } + + public com.android.vts.proto.VtsReportMessage.ProfilingReportMessage build() { + com.android.vts.proto.VtsReportMessage.ProfilingReportMessage result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public com.android.vts.proto.VtsReportMessage.ProfilingReportMessage buildPartial() { + com.android.vts.proto.VtsReportMessage.ProfilingReportMessage result = new com.android.vts.proto.VtsReportMessage.ProfilingReportMessage(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.name_ = name_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.type_ = type_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.regressionMode_ = regressionMode_; + if (((from_bitField0_ & 0x00000008) == 0x00000008)) { + to_bitField0_ |= 0x00000008; + } + result.startTimestamp_ = startTimestamp_; + if (((from_bitField0_ & 0x00000010) == 0x00000010)) { + to_bitField0_ |= 0x00000010; + } + result.endTimestamp_ = endTimestamp_; + if (((bitField0_ & 0x00000020) == 0x00000020)) { + label_ = java.util.Collections.unmodifiableList(label_); + bitField0_ = (bitField0_ & ~0x00000020); + } + result.label_ = label_; + if (((bitField0_ & 0x00000040) == 0x00000040)) { + value_ = java.util.Collections.unmodifiableList(value_); + bitField0_ = (bitField0_ & ~0x00000040); + } + result.value_ = value_; + if (((from_bitField0_ & 0x00000080) == 0x00000080)) { + to_bitField0_ |= 0x00000020; + } + result.xAxisLabel_ = xAxisLabel_; + if (((from_bitField0_ & 0x00000100) == 0x00000100)) { + to_bitField0_ |= 0x00000040; + } + result.yAxisLabel_ = yAxisLabel_; + if (((bitField0_ & 0x00000200) == 0x00000200)) { + options_ = java.util.Collections.unmodifiableList(options_); + bitField0_ = (bitField0_ & ~0x00000200); + } + result.options_ = options_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.android.vts.proto.VtsReportMessage.ProfilingReportMessage) { + return mergeFrom((com.android.vts.proto.VtsReportMessage.ProfilingReportMessage)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.android.vts.proto.VtsReportMessage.ProfilingReportMessage other) { + if (other == com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.getDefaultInstance()) return this; + if (other.hasName()) { + setName(other.getName()); + } + if (other.hasType()) { + setType(other.getType()); + } + if (other.hasRegressionMode()) { + setRegressionMode(other.getRegressionMode()); + } + if (other.hasStartTimestamp()) { + setStartTimestamp(other.getStartTimestamp()); + } + if (other.hasEndTimestamp()) { + setEndTimestamp(other.getEndTimestamp()); + } + if (!other.label_.isEmpty()) { + if (label_.isEmpty()) { + label_ = other.label_; + bitField0_ = (bitField0_ & ~0x00000020); + } else { + ensureLabelIsMutable(); + label_.addAll(other.label_); + } + onChanged(); + } + if (!other.value_.isEmpty()) { + if (value_.isEmpty()) { + value_ = other.value_; + bitField0_ = (bitField0_ & ~0x00000040); + } else { + ensureValueIsMutable(); + value_.addAll(other.value_); + } + onChanged(); + } + if (other.hasXAxisLabel()) { + setXAxisLabel(other.getXAxisLabel()); + } + if (other.hasYAxisLabel()) { + setYAxisLabel(other.getYAxisLabel()); + } + if (!other.options_.isEmpty()) { + if (options_.isEmpty()) { + options_ = other.options_; + bitField0_ = (bitField0_ & ~0x00000200); + } else { + ensureOptionsIsMutable(); + options_.addAll(other.options_); + } + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + com.android.vts.proto.VtsReportMessage.ProfilingReportMessage parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (com.android.vts.proto.VtsReportMessage.ProfilingReportMessage) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // optional bytes name = 1; + private com.google.protobuf.ByteString name_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes name = 1;</code> + * + * <pre> + * the instrumentation point name. + * </pre> + */ + public boolean hasName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * <code>optional bytes name = 1;</code> + * + * <pre> + * the instrumentation point name. + * </pre> + */ + public com.google.protobuf.ByteString getName() { + return name_; + } + /** + * <code>optional bytes name = 1;</code> + * + * <pre> + * the instrumentation point name. + * </pre> + */ + public Builder setName(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + name_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes name = 1;</code> + * + * <pre> + * the instrumentation point name. + * </pre> + */ + public Builder clearName() { + bitField0_ = (bitField0_ & ~0x00000001); + name_ = getDefaultInstance().getName(); + onChanged(); + return this; + } + + // optional .android.vts.VtsProfilingType type = 2; + private com.android.vts.proto.VtsReportMessage.VtsProfilingType type_ = com.android.vts.proto.VtsReportMessage.VtsProfilingType.UNKNOWN_VTS_PROFILING_TYPE; + /** + * <code>optional .android.vts.VtsProfilingType type = 2;</code> + */ + public boolean hasType() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * <code>optional .android.vts.VtsProfilingType type = 2;</code> + */ + public com.android.vts.proto.VtsReportMessage.VtsProfilingType getType() { + return type_; + } + /** + * <code>optional .android.vts.VtsProfilingType type = 2;</code> + */ + public Builder setType(com.android.vts.proto.VtsReportMessage.VtsProfilingType value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + type_ = value; + onChanged(); + return this; + } + /** + * <code>optional .android.vts.VtsProfilingType type = 2;</code> + */ + public Builder clearType() { + bitField0_ = (bitField0_ & ~0x00000002); + type_ = com.android.vts.proto.VtsReportMessage.VtsProfilingType.UNKNOWN_VTS_PROFILING_TYPE; + onChanged(); + return this; + } + + // optional .android.vts.VtsProfilingRegressionMode regression_mode = 3; + private com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode regressionMode_ = com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode.UNKNOWN_REGRESSION_MODE; + /** + * <code>optional .android.vts.VtsProfilingRegressionMode regression_mode = 3;</code> + */ + public boolean hasRegressionMode() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * <code>optional .android.vts.VtsProfilingRegressionMode regression_mode = 3;</code> + */ + public com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode getRegressionMode() { + return regressionMode_; + } + /** + * <code>optional .android.vts.VtsProfilingRegressionMode regression_mode = 3;</code> + */ + public Builder setRegressionMode(com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + regressionMode_ = value; + onChanged(); + return this; + } + /** + * <code>optional .android.vts.VtsProfilingRegressionMode regression_mode = 3;</code> + */ + public Builder clearRegressionMode() { + bitField0_ = (bitField0_ & ~0x00000004); + regressionMode_ = com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode.UNKNOWN_REGRESSION_MODE; + onChanged(); + return this; + } + + // optional int64 start_timestamp = 11; + private long startTimestamp_ ; + /** + * <code>optional int64 start_timestamp = 11;</code> + * + * <pre> + * profiling start and end time stamp (for performance). + * </pre> + */ + public boolean hasStartTimestamp() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * <code>optional int64 start_timestamp = 11;</code> + * + * <pre> + * profiling start and end time stamp (for performance). + * </pre> + */ + public long getStartTimestamp() { + return startTimestamp_; + } + /** + * <code>optional int64 start_timestamp = 11;</code> + * + * <pre> + * profiling start and end time stamp (for performance). + * </pre> + */ + public Builder setStartTimestamp(long value) { + bitField0_ |= 0x00000008; + startTimestamp_ = value; + onChanged(); + return this; + } + /** + * <code>optional int64 start_timestamp = 11;</code> + * + * <pre> + * profiling start and end time stamp (for performance). + * </pre> + */ + public Builder clearStartTimestamp() { + bitField0_ = (bitField0_ & ~0x00000008); + startTimestamp_ = 0L; + onChanged(); + return this; + } + + // optional int64 end_timestamp = 12; + private long endTimestamp_ ; + /** + * <code>optional int64 end_timestamp = 12;</code> + */ + public boolean hasEndTimestamp() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * <code>optional int64 end_timestamp = 12;</code> + */ + public long getEndTimestamp() { + return endTimestamp_; + } + /** + * <code>optional int64 end_timestamp = 12;</code> + */ + public Builder setEndTimestamp(long value) { + bitField0_ |= 0x00000010; + endTimestamp_ = value; + onChanged(); + return this; + } + /** + * <code>optional int64 end_timestamp = 12;</code> + */ + public Builder clearEndTimestamp() { + bitField0_ = (bitField0_ & ~0x00000010); + endTimestamp_ = 0L; + onChanged(); + return this; + } + + // repeated bytes label = 21; + private java.util.List<com.google.protobuf.ByteString> label_ = java.util.Collections.emptyList(); + private void ensureLabelIsMutable() { + if (!((bitField0_ & 0x00000020) == 0x00000020)) { + label_ = new java.util.ArrayList<com.google.protobuf.ByteString>(label_); + bitField0_ |= 0x00000020; + } + } + /** + * <code>repeated bytes label = 21;</code> + */ + public java.util.List<com.google.protobuf.ByteString> + getLabelList() { + return java.util.Collections.unmodifiableList(label_); + } + /** + * <code>repeated bytes label = 21;</code> + */ + public int getLabelCount() { + return label_.size(); + } + /** + * <code>repeated bytes label = 21;</code> + */ + public com.google.protobuf.ByteString getLabel(int index) { + return label_.get(index); + } + /** + * <code>repeated bytes label = 21;</code> + */ + public Builder setLabel( + int index, com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureLabelIsMutable(); + label_.set(index, value); + onChanged(); + return this; + } + /** + * <code>repeated bytes label = 21;</code> + */ + public Builder addLabel(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureLabelIsMutable(); + label_.add(value); + onChanged(); + return this; + } + /** + * <code>repeated bytes label = 21;</code> + */ + public Builder addAllLabel( + java.lang.Iterable<? extends com.google.protobuf.ByteString> values) { + ensureLabelIsMutable(); + super.addAll(values, label_); + onChanged(); + return this; + } + /** + * <code>repeated bytes label = 21;</code> + */ + public Builder clearLabel() { + label_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000020); + onChanged(); + return this; + } + + // repeated int64 value = 22; + private java.util.List<java.lang.Long> value_ = java.util.Collections.emptyList(); + private void ensureValueIsMutable() { + if (!((bitField0_ & 0x00000040) == 0x00000040)) { + value_ = new java.util.ArrayList<java.lang.Long>(value_); + bitField0_ |= 0x00000040; + } + } + /** + * <code>repeated int64 value = 22;</code> + */ + public java.util.List<java.lang.Long> + getValueList() { + return java.util.Collections.unmodifiableList(value_); + } + /** + * <code>repeated int64 value = 22;</code> + */ + public int getValueCount() { + return value_.size(); + } + /** + * <code>repeated int64 value = 22;</code> + */ + public long getValue(int index) { + return value_.get(index); + } + /** + * <code>repeated int64 value = 22;</code> + */ + public Builder setValue( + int index, long value) { + ensureValueIsMutable(); + value_.set(index, value); + onChanged(); + return this; + } + /** + * <code>repeated int64 value = 22;</code> + */ + public Builder addValue(long value) { + ensureValueIsMutable(); + value_.add(value); + onChanged(); + return this; + } + /** + * <code>repeated int64 value = 22;</code> + */ + public Builder addAllValue( + java.lang.Iterable<? extends java.lang.Long> values) { + ensureValueIsMutable(); + super.addAll(values, value_); + onChanged(); + return this; + } + /** + * <code>repeated int64 value = 22;</code> + */ + public Builder clearValue() { + value_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000040); + onChanged(); + return this; + } + + // optional bytes x_axis_label = 31; + private com.google.protobuf.ByteString xAxisLabel_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes x_axis_label = 31;</code> + * + * <pre> + * x-axis and y-axis title labels when displaying the data as a graph + * </pre> + */ + public boolean hasXAxisLabel() { + return ((bitField0_ & 0x00000080) == 0x00000080); + } + /** + * <code>optional bytes x_axis_label = 31;</code> + * + * <pre> + * x-axis and y-axis title labels when displaying the data as a graph + * </pre> + */ + public com.google.protobuf.ByteString getXAxisLabel() { + return xAxisLabel_; + } + /** + * <code>optional bytes x_axis_label = 31;</code> + * + * <pre> + * x-axis and y-axis title labels when displaying the data as a graph + * </pre> + */ + public Builder setXAxisLabel(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000080; + xAxisLabel_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes x_axis_label = 31;</code> + * + * <pre> + * x-axis and y-axis title labels when displaying the data as a graph + * </pre> + */ + public Builder clearXAxisLabel() { + bitField0_ = (bitField0_ & ~0x00000080); + xAxisLabel_ = getDefaultInstance().getXAxisLabel(); + onChanged(); + return this; + } + + // optional bytes y_axis_label = 32; + private com.google.protobuf.ByteString yAxisLabel_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes y_axis_label = 32;</code> + */ + public boolean hasYAxisLabel() { + return ((bitField0_ & 0x00000100) == 0x00000100); + } + /** + * <code>optional bytes y_axis_label = 32;</code> + */ + public com.google.protobuf.ByteString getYAxisLabel() { + return yAxisLabel_; + } + /** + * <code>optional bytes y_axis_label = 32;</code> + */ + public Builder setYAxisLabel(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000100; + yAxisLabel_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes y_axis_label = 32;</code> + */ + public Builder clearYAxisLabel() { + bitField0_ = (bitField0_ & ~0x00000100); + yAxisLabel_ = getDefaultInstance().getYAxisLabel(); + onChanged(); + return this; + } + + // repeated bytes options = 41; + private java.util.List<com.google.protobuf.ByteString> options_ = java.util.Collections.emptyList(); + private void ensureOptionsIsMutable() { + if (!((bitField0_ & 0x00000200) == 0x00000200)) { + options_ = new java.util.ArrayList<com.google.protobuf.ByteString>(options_); + bitField0_ |= 0x00000200; + } + } + /** + * <code>repeated bytes options = 41;</code> + * + * <pre> + * a list of strings where each string has the form of 'key=value'. + * used to tell certain properties of the data (e.g., passthrough vs. + * binderized). + * </pre> + */ + public java.util.List<com.google.protobuf.ByteString> + getOptionsList() { + return java.util.Collections.unmodifiableList(options_); + } + /** + * <code>repeated bytes options = 41;</code> + * + * <pre> + * a list of strings where each string has the form of 'key=value'. + * used to tell certain properties of the data (e.g., passthrough vs. + * binderized). + * </pre> + */ + public int getOptionsCount() { + return options_.size(); + } + /** + * <code>repeated bytes options = 41;</code> + * + * <pre> + * a list of strings where each string has the form of 'key=value'. + * used to tell certain properties of the data (e.g., passthrough vs. + * binderized). + * </pre> + */ + public com.google.protobuf.ByteString getOptions(int index) { + return options_.get(index); + } + /** + * <code>repeated bytes options = 41;</code> + * + * <pre> + * a list of strings where each string has the form of 'key=value'. + * used to tell certain properties of the data (e.g., passthrough vs. + * binderized). + * </pre> + */ + public Builder setOptions( + int index, com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureOptionsIsMutable(); + options_.set(index, value); + onChanged(); + return this; + } + /** + * <code>repeated bytes options = 41;</code> + * + * <pre> + * a list of strings where each string has the form of 'key=value'. + * used to tell certain properties of the data (e.g., passthrough vs. + * binderized). + * </pre> + */ + public Builder addOptions(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureOptionsIsMutable(); + options_.add(value); + onChanged(); + return this; + } + /** + * <code>repeated bytes options = 41;</code> + * + * <pre> + * a list of strings where each string has the form of 'key=value'. + * used to tell certain properties of the data (e.g., passthrough vs. + * binderized). + * </pre> + */ + public Builder addAllOptions( + java.lang.Iterable<? extends com.google.protobuf.ByteString> values) { + ensureOptionsIsMutable(); + super.addAll(values, options_); + onChanged(); + return this; + } + /** + * <code>repeated bytes options = 41;</code> + * + * <pre> + * a list of strings where each string has the form of 'key=value'. + * used to tell certain properties of the data (e.g., passthrough vs. + * binderized). + * </pre> + */ + public Builder clearOptions() { + options_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000200); + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:android.vts.ProfilingReportMessage) + } + + static { + defaultInstance = new ProfilingReportMessage(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:android.vts.ProfilingReportMessage) + } + + public interface SystraceReportMessageOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // optional bytes process_name = 1; + /** + * <code>optional bytes process_name = 1;</code> + * + * <pre> + * the target process name used by systrace + * </pre> + */ + boolean hasProcessName(); + /** + * <code>optional bytes process_name = 1;</code> + * + * <pre> + * the target process name used by systrace + * </pre> + */ + com.google.protobuf.ByteString getProcessName(); + + // repeated bytes html = 11; + /** + * <code>repeated bytes html = 11;</code> + * + * <pre> + * the produced html report + * </pre> + */ + java.util.List<com.google.protobuf.ByteString> getHtmlList(); + /** + * <code>repeated bytes html = 11;</code> + * + * <pre> + * the produced html report + * </pre> + */ + int getHtmlCount(); + /** + * <code>repeated bytes html = 11;</code> + * + * <pre> + * the produced html report + * </pre> + */ + com.google.protobuf.ByteString getHtml(int index); + + // repeated bytes url = 21; + /** + * <code>repeated bytes url = 21;</code> + * + * <pre> + * URLs of the produced html reports + * </pre> + */ + java.util.List<com.google.protobuf.ByteString> getUrlList(); + /** + * <code>repeated bytes url = 21;</code> + * + * <pre> + * URLs of the produced html reports + * </pre> + */ + int getUrlCount(); + /** + * <code>repeated bytes url = 21;</code> + * + * <pre> + * URLs of the produced html reports + * </pre> + */ + com.google.protobuf.ByteString getUrl(int index); + } + /** + * Protobuf type {@code android.vts.SystraceReportMessage} + * + * <pre> + * To specify a systrace report. + * </pre> + */ + public static final class SystraceReportMessage extends + com.google.protobuf.GeneratedMessage + implements SystraceReportMessageOrBuilder { + // Use SystraceReportMessage.newBuilder() to construct. + private SystraceReportMessage(com.google.protobuf.GeneratedMessage.Builder<?> builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private SystraceReportMessage(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final SystraceReportMessage defaultInstance; + public static SystraceReportMessage getDefaultInstance() { + return defaultInstance; + } + + public SystraceReportMessage getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private SystraceReportMessage( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + processName_ = input.readBytes(); + break; + } + case 90: { + if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) { + html_ = new java.util.ArrayList<com.google.protobuf.ByteString>(); + mutable_bitField0_ |= 0x00000002; + } + html_.add(input.readBytes()); + break; + } + case 170: { + if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) { + url_ = new java.util.ArrayList<com.google.protobuf.ByteString>(); + mutable_bitField0_ |= 0x00000004; + } + url_.add(input.readBytes()); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) { + html_ = java.util.Collections.unmodifiableList(html_); + } + if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) { + url_ = java.util.Collections.unmodifiableList(url_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_SystraceReportMessage_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_SystraceReportMessage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.android.vts.proto.VtsReportMessage.SystraceReportMessage.class, com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder.class); + } + + public static com.google.protobuf.Parser<SystraceReportMessage> PARSER = + new com.google.protobuf.AbstractParser<SystraceReportMessage>() { + public SystraceReportMessage parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new SystraceReportMessage(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser<SystraceReportMessage> getParserForType() { + return PARSER; + } + + private int bitField0_; + // optional bytes process_name = 1; + public static final int PROCESS_NAME_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString processName_; + /** + * <code>optional bytes process_name = 1;</code> + * + * <pre> + * the target process name used by systrace + * </pre> + */ + public boolean hasProcessName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * <code>optional bytes process_name = 1;</code> + * + * <pre> + * the target process name used by systrace + * </pre> + */ + public com.google.protobuf.ByteString getProcessName() { + return processName_; + } + + // repeated bytes html = 11; + public static final int HTML_FIELD_NUMBER = 11; + private java.util.List<com.google.protobuf.ByteString> html_; + /** + * <code>repeated bytes html = 11;</code> + * + * <pre> + * the produced html report + * </pre> + */ + public java.util.List<com.google.protobuf.ByteString> + getHtmlList() { + return html_; + } + /** + * <code>repeated bytes html = 11;</code> + * + * <pre> + * the produced html report + * </pre> + */ + public int getHtmlCount() { + return html_.size(); + } + /** + * <code>repeated bytes html = 11;</code> + * + * <pre> + * the produced html report + * </pre> + */ + public com.google.protobuf.ByteString getHtml(int index) { + return html_.get(index); + } + + // repeated bytes url = 21; + public static final int URL_FIELD_NUMBER = 21; + private java.util.List<com.google.protobuf.ByteString> url_; + /** + * <code>repeated bytes url = 21;</code> + * + * <pre> + * URLs of the produced html reports + * </pre> + */ + public java.util.List<com.google.protobuf.ByteString> + getUrlList() { + return url_; + } + /** + * <code>repeated bytes url = 21;</code> + * + * <pre> + * URLs of the produced html reports + * </pre> + */ + public int getUrlCount() { + return url_.size(); + } + /** + * <code>repeated bytes url = 21;</code> + * + * <pre> + * URLs of the produced html reports + * </pre> + */ + public com.google.protobuf.ByteString getUrl(int index) { + return url_.get(index); + } + + private void initFields() { + processName_ = com.google.protobuf.ByteString.EMPTY; + html_ = java.util.Collections.emptyList(); + url_ = java.util.Collections.emptyList(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, processName_); + } + for (int i = 0; i < html_.size(); i++) { + output.writeBytes(11, html_.get(i)); + } + for (int i = 0; i < url_.size(); i++) { + output.writeBytes(21, url_.get(i)); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, processName_); + } + { + int dataSize = 0; + for (int i = 0; i < html_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeBytesSizeNoTag(html_.get(i)); + } + size += dataSize; + size += 1 * getHtmlList().size(); + } + { + int dataSize = 0; + for (int i = 0; i < url_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeBytesSizeNoTag(url_.get(i)); + } + size += dataSize; + size += 2 * getUrlList().size(); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static com.android.vts.proto.VtsReportMessage.SystraceReportMessage parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.android.vts.proto.VtsReportMessage.SystraceReportMessage parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.SystraceReportMessage parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.android.vts.proto.VtsReportMessage.SystraceReportMessage parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.SystraceReportMessage parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.SystraceReportMessage parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.SystraceReportMessage parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.SystraceReportMessage parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.SystraceReportMessage parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.SystraceReportMessage parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(com.android.vts.proto.VtsReportMessage.SystraceReportMessage prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code android.vts.SystraceReportMessage} + * + * <pre> + * To specify a systrace report. + * </pre> + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder<Builder> + implements com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_SystraceReportMessage_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_SystraceReportMessage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.android.vts.proto.VtsReportMessage.SystraceReportMessage.class, com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder.class); + } + + // Construct using com.android.vts.proto.VtsReportMessage.SystraceReportMessage.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + processName_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + html_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + url_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_SystraceReportMessage_descriptor; + } + + public com.android.vts.proto.VtsReportMessage.SystraceReportMessage getDefaultInstanceForType() { + return com.android.vts.proto.VtsReportMessage.SystraceReportMessage.getDefaultInstance(); + } + + public com.android.vts.proto.VtsReportMessage.SystraceReportMessage build() { + com.android.vts.proto.VtsReportMessage.SystraceReportMessage result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public com.android.vts.proto.VtsReportMessage.SystraceReportMessage buildPartial() { + com.android.vts.proto.VtsReportMessage.SystraceReportMessage result = new com.android.vts.proto.VtsReportMessage.SystraceReportMessage(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.processName_ = processName_; + if (((bitField0_ & 0x00000002) == 0x00000002)) { + html_ = java.util.Collections.unmodifiableList(html_); + bitField0_ = (bitField0_ & ~0x00000002); + } + result.html_ = html_; + if (((bitField0_ & 0x00000004) == 0x00000004)) { + url_ = java.util.Collections.unmodifiableList(url_); + bitField0_ = (bitField0_ & ~0x00000004); + } + result.url_ = url_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.android.vts.proto.VtsReportMessage.SystraceReportMessage) { + return mergeFrom((com.android.vts.proto.VtsReportMessage.SystraceReportMessage)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.android.vts.proto.VtsReportMessage.SystraceReportMessage other) { + if (other == com.android.vts.proto.VtsReportMessage.SystraceReportMessage.getDefaultInstance()) return this; + if (other.hasProcessName()) { + setProcessName(other.getProcessName()); + } + if (!other.html_.isEmpty()) { + if (html_.isEmpty()) { + html_ = other.html_; + bitField0_ = (bitField0_ & ~0x00000002); + } else { + ensureHtmlIsMutable(); + html_.addAll(other.html_); + } + onChanged(); + } + if (!other.url_.isEmpty()) { + if (url_.isEmpty()) { + url_ = other.url_; + bitField0_ = (bitField0_ & ~0x00000004); + } else { + ensureUrlIsMutable(); + url_.addAll(other.url_); + } + onChanged(); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + com.android.vts.proto.VtsReportMessage.SystraceReportMessage parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (com.android.vts.proto.VtsReportMessage.SystraceReportMessage) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // optional bytes process_name = 1; + private com.google.protobuf.ByteString processName_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes process_name = 1;</code> + * + * <pre> + * the target process name used by systrace + * </pre> + */ + public boolean hasProcessName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * <code>optional bytes process_name = 1;</code> + * + * <pre> + * the target process name used by systrace + * </pre> + */ + public com.google.protobuf.ByteString getProcessName() { + return processName_; + } + /** + * <code>optional bytes process_name = 1;</code> + * + * <pre> + * the target process name used by systrace + * </pre> + */ + public Builder setProcessName(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + processName_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes process_name = 1;</code> + * + * <pre> + * the target process name used by systrace + * </pre> + */ + public Builder clearProcessName() { + bitField0_ = (bitField0_ & ~0x00000001); + processName_ = getDefaultInstance().getProcessName(); + onChanged(); + return this; + } + + // repeated bytes html = 11; + private java.util.List<com.google.protobuf.ByteString> html_ = java.util.Collections.emptyList(); + private void ensureHtmlIsMutable() { + if (!((bitField0_ & 0x00000002) == 0x00000002)) { + html_ = new java.util.ArrayList<com.google.protobuf.ByteString>(html_); + bitField0_ |= 0x00000002; + } + } + /** + * <code>repeated bytes html = 11;</code> + * + * <pre> + * the produced html report + * </pre> + */ + public java.util.List<com.google.protobuf.ByteString> + getHtmlList() { + return java.util.Collections.unmodifiableList(html_); + } + /** + * <code>repeated bytes html = 11;</code> + * + * <pre> + * the produced html report + * </pre> + */ + public int getHtmlCount() { + return html_.size(); + } + /** + * <code>repeated bytes html = 11;</code> + * + * <pre> + * the produced html report + * </pre> + */ + public com.google.protobuf.ByteString getHtml(int index) { + return html_.get(index); + } + /** + * <code>repeated bytes html = 11;</code> + * + * <pre> + * the produced html report + * </pre> + */ + public Builder setHtml( + int index, com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureHtmlIsMutable(); + html_.set(index, value); + onChanged(); + return this; + } + /** + * <code>repeated bytes html = 11;</code> + * + * <pre> + * the produced html report + * </pre> + */ + public Builder addHtml(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureHtmlIsMutable(); + html_.add(value); + onChanged(); + return this; + } + /** + * <code>repeated bytes html = 11;</code> + * + * <pre> + * the produced html report + * </pre> + */ + public Builder addAllHtml( + java.lang.Iterable<? extends com.google.protobuf.ByteString> values) { + ensureHtmlIsMutable(); + super.addAll(values, html_); + onChanged(); + return this; + } + /** + * <code>repeated bytes html = 11;</code> + * + * <pre> + * the produced html report + * </pre> + */ + public Builder clearHtml() { + html_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + onChanged(); + return this; + } + + // repeated bytes url = 21; + private java.util.List<com.google.protobuf.ByteString> url_ = java.util.Collections.emptyList(); + private void ensureUrlIsMutable() { + if (!((bitField0_ & 0x00000004) == 0x00000004)) { + url_ = new java.util.ArrayList<com.google.protobuf.ByteString>(url_); + bitField0_ |= 0x00000004; + } + } + /** + * <code>repeated bytes url = 21;</code> + * + * <pre> + * URLs of the produced html reports + * </pre> + */ + public java.util.List<com.google.protobuf.ByteString> + getUrlList() { + return java.util.Collections.unmodifiableList(url_); + } + /** + * <code>repeated bytes url = 21;</code> + * + * <pre> + * URLs of the produced html reports + * </pre> + */ + public int getUrlCount() { + return url_.size(); + } + /** + * <code>repeated bytes url = 21;</code> + * + * <pre> + * URLs of the produced html reports + * </pre> + */ + public com.google.protobuf.ByteString getUrl(int index) { + return url_.get(index); + } + /** + * <code>repeated bytes url = 21;</code> + * + * <pre> + * URLs of the produced html reports + * </pre> + */ + public Builder setUrl( + int index, com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureUrlIsMutable(); + url_.set(index, value); + onChanged(); + return this; + } + /** + * <code>repeated bytes url = 21;</code> + * + * <pre> + * URLs of the produced html reports + * </pre> + */ + public Builder addUrl(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureUrlIsMutable(); + url_.add(value); + onChanged(); + return this; + } + /** + * <code>repeated bytes url = 21;</code> + * + * <pre> + * URLs of the produced html reports + * </pre> + */ + public Builder addAllUrl( + java.lang.Iterable<? extends com.google.protobuf.ByteString> values) { + ensureUrlIsMutable(); + super.addAll(values, url_); + onChanged(); + return this; + } + /** + * <code>repeated bytes url = 21;</code> + * + * <pre> + * URLs of the produced html reports + * </pre> + */ + public Builder clearUrl() { + url_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000004); + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:android.vts.SystraceReportMessage) + } + + static { + defaultInstance = new SystraceReportMessage(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:android.vts.SystraceReportMessage) + } + + public interface CoverageReportMessageOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // optional bytes file_path = 11; + /** + * <code>optional bytes file_path = 11;</code> + * + * <pre> + * the path to the source file from the project root. + * </pre> + */ + boolean hasFilePath(); + /** + * <code>optional bytes file_path = 11;</code> + * + * <pre> + * the path to the source file from the project root. + * </pre> + */ + com.google.protobuf.ByteString getFilePath(); + + // optional bytes project_name = 12; + /** + * <code>optional bytes project_name = 12;</code> + * + * <pre> + * the name of the project where the file can be found + * </pre> + */ + boolean hasProjectName(); + /** + * <code>optional bytes project_name = 12;</code> + * + * <pre> + * the name of the project where the file can be found + * </pre> + */ + com.google.protobuf.ByteString getProjectName(); + + // optional bytes revision = 13; + /** + * <code>optional bytes revision = 13;</code> + * + * <pre> + * the commit ID identifying the code revision + * </pre> + */ + boolean hasRevision(); + /** + * <code>optional bytes revision = 13;</code> + * + * <pre> + * the commit ID identifying the code revision + * </pre> + */ + com.google.protobuf.ByteString getRevision(); + + // repeated int32 line_coverage_vector = 23; + /** + * <code>repeated int32 line_coverage_vector = 23;</code> + * + * <pre> + * i-th element gives the number of times i-th line is executed. + * </pre> + */ + java.util.List<java.lang.Integer> getLineCoverageVectorList(); + /** + * <code>repeated int32 line_coverage_vector = 23;</code> + * + * <pre> + * i-th element gives the number of times i-th line is executed. + * </pre> + */ + int getLineCoverageVectorCount(); + /** + * <code>repeated int32 line_coverage_vector = 23;</code> + * + * <pre> + * i-th element gives the number of times i-th line is executed. + * </pre> + */ + int getLineCoverageVector(int index); + + // optional int32 total_line_count = 101; + /** + * <code>optional int32 total_line_count = 101;</code> + * + * <pre> + * the number of source code lines that are instrumented for code coverage + * measurement. + * </pre> + */ + boolean hasTotalLineCount(); + /** + * <code>optional int32 total_line_count = 101;</code> + * + * <pre> + * the number of source code lines that are instrumented for code coverage + * measurement. + * </pre> + */ + int getTotalLineCount(); + + // optional int32 covered_line_count = 102; + /** + * <code>optional int32 covered_line_count = 102;</code> + * + * <pre> + * the number of source code lines that are executed. + * </pre> + */ + boolean hasCoveredLineCount(); + /** + * <code>optional int32 covered_line_count = 102;</code> + * + * <pre> + * the number of source code lines that are executed. + * </pre> + */ + int getCoveredLineCount(); + + // optional bytes dir_path = 1 [deprecated = true]; + /** + * <code>optional bytes dir_path = 1 [deprecated = true];</code> + * + * <pre> + * TODO(ryanjcampbell@) delete deprecated field + * the directory path of a source file. + * </pre> + */ + @java.lang.Deprecated boolean hasDirPath(); + /** + * <code>optional bytes dir_path = 1 [deprecated = true];</code> + * + * <pre> + * TODO(ryanjcampbell@) delete deprecated field + * the directory path of a source file. + * </pre> + */ + @java.lang.Deprecated com.google.protobuf.ByteString getDirPath(); + + // optional bytes file_name = 2 [deprecated = true]; + /** + * <code>optional bytes file_name = 2 [deprecated = true];</code> + * + * <pre> + * TODO(ryanjcampbell@) delete deprecated field + * the name of the source file. + * </pre> + */ + @java.lang.Deprecated boolean hasFileName(); + /** + * <code>optional bytes file_name = 2 [deprecated = true];</code> + * + * <pre> + * TODO(ryanjcampbell@) delete deprecated field + * the name of the source file. + * </pre> + */ + @java.lang.Deprecated com.google.protobuf.ByteString getFileName(); + + // optional bytes html = 3 [deprecated = true]; + /** + * <code>optional bytes html = 3 [deprecated = true];</code> + * + * <pre> + * TODO(ryanjcampbell@) delete deprecated field + * produced html report. + * </pre> + */ + @java.lang.Deprecated boolean hasHtml(); + /** + * <code>optional bytes html = 3 [deprecated = true];</code> + * + * <pre> + * TODO(ryanjcampbell@) delete deprecated field + * produced html report. + * </pre> + */ + @java.lang.Deprecated com.google.protobuf.ByteString getHtml(); + } + /** + * Protobuf type {@code android.vts.CoverageReportMessage} + * + * <pre> + * To specify a coverage report. + * </pre> + */ + public static final class CoverageReportMessage extends + com.google.protobuf.GeneratedMessage + implements CoverageReportMessageOrBuilder { + // Use CoverageReportMessage.newBuilder() to construct. + private CoverageReportMessage(com.google.protobuf.GeneratedMessage.Builder<?> builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private CoverageReportMessage(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final CoverageReportMessage defaultInstance; + public static CoverageReportMessage getDefaultInstance() { + return defaultInstance; + } + + public CoverageReportMessage getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private CoverageReportMessage( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000020; + dirPath_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000040; + fileName_ = input.readBytes(); + break; + } + case 26: { + bitField0_ |= 0x00000080; + html_ = input.readBytes(); + break; + } + case 90: { + bitField0_ |= 0x00000001; + filePath_ = input.readBytes(); + break; + } + case 98: { + bitField0_ |= 0x00000002; + projectName_ = input.readBytes(); + break; + } + case 106: { + bitField0_ |= 0x00000004; + revision_ = input.readBytes(); + break; + } + case 184: { + if (!((mutable_bitField0_ & 0x00000008) == 0x00000008)) { + lineCoverageVector_ = new java.util.ArrayList<java.lang.Integer>(); + mutable_bitField0_ |= 0x00000008; + } + lineCoverageVector_.add(input.readInt32()); + break; + } + case 186: { + int length = input.readRawVarint32(); + int limit = input.pushLimit(length); + if (!((mutable_bitField0_ & 0x00000008) == 0x00000008) && input.getBytesUntilLimit() > 0) { + lineCoverageVector_ = new java.util.ArrayList<java.lang.Integer>(); + mutable_bitField0_ |= 0x00000008; + } + while (input.getBytesUntilLimit() > 0) { + lineCoverageVector_.add(input.readInt32()); + } + input.popLimit(limit); + break; + } + case 808: { + bitField0_ |= 0x00000008; + totalLineCount_ = input.readInt32(); + break; + } + case 816: { + bitField0_ |= 0x00000010; + coveredLineCount_ = input.readInt32(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000008) == 0x00000008)) { + lineCoverageVector_ = java.util.Collections.unmodifiableList(lineCoverageVector_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_CoverageReportMessage_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_CoverageReportMessage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.android.vts.proto.VtsReportMessage.CoverageReportMessage.class, com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder.class); + } + + public static com.google.protobuf.Parser<CoverageReportMessage> PARSER = + new com.google.protobuf.AbstractParser<CoverageReportMessage>() { + public CoverageReportMessage parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new CoverageReportMessage(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser<CoverageReportMessage> getParserForType() { + return PARSER; + } + + private int bitField0_; + // optional bytes file_path = 11; + public static final int FILE_PATH_FIELD_NUMBER = 11; + private com.google.protobuf.ByteString filePath_; + /** + * <code>optional bytes file_path = 11;</code> + * + * <pre> + * the path to the source file from the project root. + * </pre> + */ + public boolean hasFilePath() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * <code>optional bytes file_path = 11;</code> + * + * <pre> + * the path to the source file from the project root. + * </pre> + */ + public com.google.protobuf.ByteString getFilePath() { + return filePath_; + } + + // optional bytes project_name = 12; + public static final int PROJECT_NAME_FIELD_NUMBER = 12; + private com.google.protobuf.ByteString projectName_; + /** + * <code>optional bytes project_name = 12;</code> + * + * <pre> + * the name of the project where the file can be found + * </pre> + */ + public boolean hasProjectName() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * <code>optional bytes project_name = 12;</code> + * + * <pre> + * the name of the project where the file can be found + * </pre> + */ + public com.google.protobuf.ByteString getProjectName() { + return projectName_; + } + + // optional bytes revision = 13; + public static final int REVISION_FIELD_NUMBER = 13; + private com.google.protobuf.ByteString revision_; + /** + * <code>optional bytes revision = 13;</code> + * + * <pre> + * the commit ID identifying the code revision + * </pre> + */ + public boolean hasRevision() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * <code>optional bytes revision = 13;</code> + * + * <pre> + * the commit ID identifying the code revision + * </pre> + */ + public com.google.protobuf.ByteString getRevision() { + return revision_; + } + + // repeated int32 line_coverage_vector = 23; + public static final int LINE_COVERAGE_VECTOR_FIELD_NUMBER = 23; + private java.util.List<java.lang.Integer> lineCoverageVector_; + /** + * <code>repeated int32 line_coverage_vector = 23;</code> + * + * <pre> + * i-th element gives the number of times i-th line is executed. + * </pre> + */ + public java.util.List<java.lang.Integer> + getLineCoverageVectorList() { + return lineCoverageVector_; + } + /** + * <code>repeated int32 line_coverage_vector = 23;</code> + * + * <pre> + * i-th element gives the number of times i-th line is executed. + * </pre> + */ + public int getLineCoverageVectorCount() { + return lineCoverageVector_.size(); + } + /** + * <code>repeated int32 line_coverage_vector = 23;</code> + * + * <pre> + * i-th element gives the number of times i-th line is executed. + * </pre> + */ + public int getLineCoverageVector(int index) { + return lineCoverageVector_.get(index); + } + + // optional int32 total_line_count = 101; + public static final int TOTAL_LINE_COUNT_FIELD_NUMBER = 101; + private int totalLineCount_; + /** + * <code>optional int32 total_line_count = 101;</code> + * + * <pre> + * the number of source code lines that are instrumented for code coverage + * measurement. + * </pre> + */ + public boolean hasTotalLineCount() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * <code>optional int32 total_line_count = 101;</code> + * + * <pre> + * the number of source code lines that are instrumented for code coverage + * measurement. + * </pre> + */ + public int getTotalLineCount() { + return totalLineCount_; + } + + // optional int32 covered_line_count = 102; + public static final int COVERED_LINE_COUNT_FIELD_NUMBER = 102; + private int coveredLineCount_; + /** + * <code>optional int32 covered_line_count = 102;</code> + * + * <pre> + * the number of source code lines that are executed. + * </pre> + */ + public boolean hasCoveredLineCount() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * <code>optional int32 covered_line_count = 102;</code> + * + * <pre> + * the number of source code lines that are executed. + * </pre> + */ + public int getCoveredLineCount() { + return coveredLineCount_; + } + + // optional bytes dir_path = 1 [deprecated = true]; + public static final int DIR_PATH_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString dirPath_; + /** + * <code>optional bytes dir_path = 1 [deprecated = true];</code> + * + * <pre> + * TODO(ryanjcampbell@) delete deprecated field + * the directory path of a source file. + * </pre> + */ + @java.lang.Deprecated public boolean hasDirPath() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * <code>optional bytes dir_path = 1 [deprecated = true];</code> + * + * <pre> + * TODO(ryanjcampbell@) delete deprecated field + * the directory path of a source file. + * </pre> + */ + @java.lang.Deprecated public com.google.protobuf.ByteString getDirPath() { + return dirPath_; + } + + // optional bytes file_name = 2 [deprecated = true]; + public static final int FILE_NAME_FIELD_NUMBER = 2; + private com.google.protobuf.ByteString fileName_; + /** + * <code>optional bytes file_name = 2 [deprecated = true];</code> + * + * <pre> + * TODO(ryanjcampbell@) delete deprecated field + * the name of the source file. + * </pre> + */ + @java.lang.Deprecated public boolean hasFileName() { + return ((bitField0_ & 0x00000040) == 0x00000040); + } + /** + * <code>optional bytes file_name = 2 [deprecated = true];</code> + * + * <pre> + * TODO(ryanjcampbell@) delete deprecated field + * the name of the source file. + * </pre> + */ + @java.lang.Deprecated public com.google.protobuf.ByteString getFileName() { + return fileName_; + } + + // optional bytes html = 3 [deprecated = true]; + public static final int HTML_FIELD_NUMBER = 3; + private com.google.protobuf.ByteString html_; + /** + * <code>optional bytes html = 3 [deprecated = true];</code> + * + * <pre> + * TODO(ryanjcampbell@) delete deprecated field + * produced html report. + * </pre> + */ + @java.lang.Deprecated public boolean hasHtml() { + return ((bitField0_ & 0x00000080) == 0x00000080); + } + /** + * <code>optional bytes html = 3 [deprecated = true];</code> + * + * <pre> + * TODO(ryanjcampbell@) delete deprecated field + * produced html report. + * </pre> + */ + @java.lang.Deprecated public com.google.protobuf.ByteString getHtml() { + return html_; + } + + private void initFields() { + filePath_ = com.google.protobuf.ByteString.EMPTY; + projectName_ = com.google.protobuf.ByteString.EMPTY; + revision_ = com.google.protobuf.ByteString.EMPTY; + lineCoverageVector_ = java.util.Collections.emptyList(); + totalLineCount_ = 0; + coveredLineCount_ = 0; + dirPath_ = com.google.protobuf.ByteString.EMPTY; + fileName_ = com.google.protobuf.ByteString.EMPTY; + html_ = com.google.protobuf.ByteString.EMPTY; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000020) == 0x00000020)) { + output.writeBytes(1, dirPath_); + } + if (((bitField0_ & 0x00000040) == 0x00000040)) { + output.writeBytes(2, fileName_); + } + if (((bitField0_ & 0x00000080) == 0x00000080)) { + output.writeBytes(3, html_); + } + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(11, filePath_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(12, projectName_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeBytes(13, revision_); + } + for (int i = 0; i < lineCoverageVector_.size(); i++) { + output.writeInt32(23, lineCoverageVector_.get(i)); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeInt32(101, totalLineCount_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + output.writeInt32(102, coveredLineCount_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000020) == 0x00000020)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, dirPath_); + } + if (((bitField0_ & 0x00000040) == 0x00000040)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, fileName_); + } + if (((bitField0_ & 0x00000080) == 0x00000080)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(3, html_); + } + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(11, filePath_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(12, projectName_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(13, revision_); + } + { + int dataSize = 0; + for (int i = 0; i < lineCoverageVector_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeInt32SizeNoTag(lineCoverageVector_.get(i)); + } + size += dataSize; + size += 2 * getLineCoverageVectorList().size(); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(101, totalLineCount_); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(102, coveredLineCount_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static com.android.vts.proto.VtsReportMessage.CoverageReportMessage parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.android.vts.proto.VtsReportMessage.CoverageReportMessage parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.CoverageReportMessage parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.android.vts.proto.VtsReportMessage.CoverageReportMessage parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.CoverageReportMessage parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.CoverageReportMessage parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.CoverageReportMessage parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.CoverageReportMessage parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.CoverageReportMessage parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.CoverageReportMessage parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(com.android.vts.proto.VtsReportMessage.CoverageReportMessage prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code android.vts.CoverageReportMessage} + * + * <pre> + * To specify a coverage report. + * </pre> + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder<Builder> + implements com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_CoverageReportMessage_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_CoverageReportMessage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.android.vts.proto.VtsReportMessage.CoverageReportMessage.class, com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder.class); + } + + // Construct using com.android.vts.proto.VtsReportMessage.CoverageReportMessage.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + filePath_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + projectName_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000002); + revision_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000004); + lineCoverageVector_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000008); + totalLineCount_ = 0; + bitField0_ = (bitField0_ & ~0x00000010); + coveredLineCount_ = 0; + bitField0_ = (bitField0_ & ~0x00000020); + dirPath_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000040); + fileName_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000080); + html_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000100); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_CoverageReportMessage_descriptor; + } + + public com.android.vts.proto.VtsReportMessage.CoverageReportMessage getDefaultInstanceForType() { + return com.android.vts.proto.VtsReportMessage.CoverageReportMessage.getDefaultInstance(); + } + + public com.android.vts.proto.VtsReportMessage.CoverageReportMessage build() { + com.android.vts.proto.VtsReportMessage.CoverageReportMessage result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public com.android.vts.proto.VtsReportMessage.CoverageReportMessage buildPartial() { + com.android.vts.proto.VtsReportMessage.CoverageReportMessage result = new com.android.vts.proto.VtsReportMessage.CoverageReportMessage(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.filePath_ = filePath_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.projectName_ = projectName_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.revision_ = revision_; + if (((bitField0_ & 0x00000008) == 0x00000008)) { + lineCoverageVector_ = java.util.Collections.unmodifiableList(lineCoverageVector_); + bitField0_ = (bitField0_ & ~0x00000008); + } + result.lineCoverageVector_ = lineCoverageVector_; + if (((from_bitField0_ & 0x00000010) == 0x00000010)) { + to_bitField0_ |= 0x00000008; + } + result.totalLineCount_ = totalLineCount_; + if (((from_bitField0_ & 0x00000020) == 0x00000020)) { + to_bitField0_ |= 0x00000010; + } + result.coveredLineCount_ = coveredLineCount_; + if (((from_bitField0_ & 0x00000040) == 0x00000040)) { + to_bitField0_ |= 0x00000020; + } + result.dirPath_ = dirPath_; + if (((from_bitField0_ & 0x00000080) == 0x00000080)) { + to_bitField0_ |= 0x00000040; + } + result.fileName_ = fileName_; + if (((from_bitField0_ & 0x00000100) == 0x00000100)) { + to_bitField0_ |= 0x00000080; + } + result.html_ = html_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.android.vts.proto.VtsReportMessage.CoverageReportMessage) { + return mergeFrom((com.android.vts.proto.VtsReportMessage.CoverageReportMessage)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.android.vts.proto.VtsReportMessage.CoverageReportMessage other) { + if (other == com.android.vts.proto.VtsReportMessage.CoverageReportMessage.getDefaultInstance()) return this; + if (other.hasFilePath()) { + setFilePath(other.getFilePath()); + } + if (other.hasProjectName()) { + setProjectName(other.getProjectName()); + } + if (other.hasRevision()) { + setRevision(other.getRevision()); + } + if (!other.lineCoverageVector_.isEmpty()) { + if (lineCoverageVector_.isEmpty()) { + lineCoverageVector_ = other.lineCoverageVector_; + bitField0_ = (bitField0_ & ~0x00000008); + } else { + ensureLineCoverageVectorIsMutable(); + lineCoverageVector_.addAll(other.lineCoverageVector_); + } + onChanged(); + } + if (other.hasTotalLineCount()) { + setTotalLineCount(other.getTotalLineCount()); + } + if (other.hasCoveredLineCount()) { + setCoveredLineCount(other.getCoveredLineCount()); + } + if (other.hasDirPath()) { + setDirPath(other.getDirPath()); + } + if (other.hasFileName()) { + setFileName(other.getFileName()); + } + if (other.hasHtml()) { + setHtml(other.getHtml()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + com.android.vts.proto.VtsReportMessage.CoverageReportMessage parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (com.android.vts.proto.VtsReportMessage.CoverageReportMessage) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // optional bytes file_path = 11; + private com.google.protobuf.ByteString filePath_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes file_path = 11;</code> + * + * <pre> + * the path to the source file from the project root. + * </pre> + */ + public boolean hasFilePath() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * <code>optional bytes file_path = 11;</code> + * + * <pre> + * the path to the source file from the project root. + * </pre> + */ + public com.google.protobuf.ByteString getFilePath() { + return filePath_; + } + /** + * <code>optional bytes file_path = 11;</code> + * + * <pre> + * the path to the source file from the project root. + * </pre> + */ + public Builder setFilePath(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + filePath_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes file_path = 11;</code> + * + * <pre> + * the path to the source file from the project root. + * </pre> + */ + public Builder clearFilePath() { + bitField0_ = (bitField0_ & ~0x00000001); + filePath_ = getDefaultInstance().getFilePath(); + onChanged(); + return this; + } + + // optional bytes project_name = 12; + private com.google.protobuf.ByteString projectName_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes project_name = 12;</code> + * + * <pre> + * the name of the project where the file can be found + * </pre> + */ + public boolean hasProjectName() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * <code>optional bytes project_name = 12;</code> + * + * <pre> + * the name of the project where the file can be found + * </pre> + */ + public com.google.protobuf.ByteString getProjectName() { + return projectName_; + } + /** + * <code>optional bytes project_name = 12;</code> + * + * <pre> + * the name of the project where the file can be found + * </pre> + */ + public Builder setProjectName(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + projectName_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes project_name = 12;</code> + * + * <pre> + * the name of the project where the file can be found + * </pre> + */ + public Builder clearProjectName() { + bitField0_ = (bitField0_ & ~0x00000002); + projectName_ = getDefaultInstance().getProjectName(); + onChanged(); + return this; + } + + // optional bytes revision = 13; + private com.google.protobuf.ByteString revision_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes revision = 13;</code> + * + * <pre> + * the commit ID identifying the code revision + * </pre> + */ + public boolean hasRevision() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * <code>optional bytes revision = 13;</code> + * + * <pre> + * the commit ID identifying the code revision + * </pre> + */ + public com.google.protobuf.ByteString getRevision() { + return revision_; + } + /** + * <code>optional bytes revision = 13;</code> + * + * <pre> + * the commit ID identifying the code revision + * </pre> + */ + public Builder setRevision(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + revision_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes revision = 13;</code> + * + * <pre> + * the commit ID identifying the code revision + * </pre> + */ + public Builder clearRevision() { + bitField0_ = (bitField0_ & ~0x00000004); + revision_ = getDefaultInstance().getRevision(); + onChanged(); + return this; + } + + // repeated int32 line_coverage_vector = 23; + private java.util.List<java.lang.Integer> lineCoverageVector_ = java.util.Collections.emptyList(); + private void ensureLineCoverageVectorIsMutable() { + if (!((bitField0_ & 0x00000008) == 0x00000008)) { + lineCoverageVector_ = new java.util.ArrayList<java.lang.Integer>(lineCoverageVector_); + bitField0_ |= 0x00000008; + } + } + /** + * <code>repeated int32 line_coverage_vector = 23;</code> + * + * <pre> + * i-th element gives the number of times i-th line is executed. + * </pre> + */ + public java.util.List<java.lang.Integer> + getLineCoverageVectorList() { + return java.util.Collections.unmodifiableList(lineCoverageVector_); + } + /** + * <code>repeated int32 line_coverage_vector = 23;</code> + * + * <pre> + * i-th element gives the number of times i-th line is executed. + * </pre> + */ + public int getLineCoverageVectorCount() { + return lineCoverageVector_.size(); + } + /** + * <code>repeated int32 line_coverage_vector = 23;</code> + * + * <pre> + * i-th element gives the number of times i-th line is executed. + * </pre> + */ + public int getLineCoverageVector(int index) { + return lineCoverageVector_.get(index); + } + /** + * <code>repeated int32 line_coverage_vector = 23;</code> + * + * <pre> + * i-th element gives the number of times i-th line is executed. + * </pre> + */ + public Builder setLineCoverageVector( + int index, int value) { + ensureLineCoverageVectorIsMutable(); + lineCoverageVector_.set(index, value); + onChanged(); + return this; + } + /** + * <code>repeated int32 line_coverage_vector = 23;</code> + * + * <pre> + * i-th element gives the number of times i-th line is executed. + * </pre> + */ + public Builder addLineCoverageVector(int value) { + ensureLineCoverageVectorIsMutable(); + lineCoverageVector_.add(value); + onChanged(); + return this; + } + /** + * <code>repeated int32 line_coverage_vector = 23;</code> + * + * <pre> + * i-th element gives the number of times i-th line is executed. + * </pre> + */ + public Builder addAllLineCoverageVector( + java.lang.Iterable<? extends java.lang.Integer> values) { + ensureLineCoverageVectorIsMutable(); + super.addAll(values, lineCoverageVector_); + onChanged(); + return this; + } + /** + * <code>repeated int32 line_coverage_vector = 23;</code> + * + * <pre> + * i-th element gives the number of times i-th line is executed. + * </pre> + */ + public Builder clearLineCoverageVector() { + lineCoverageVector_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000008); + onChanged(); + return this; + } + + // optional int32 total_line_count = 101; + private int totalLineCount_ ; + /** + * <code>optional int32 total_line_count = 101;</code> + * + * <pre> + * the number of source code lines that are instrumented for code coverage + * measurement. + * </pre> + */ + public boolean hasTotalLineCount() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * <code>optional int32 total_line_count = 101;</code> + * + * <pre> + * the number of source code lines that are instrumented for code coverage + * measurement. + * </pre> + */ + public int getTotalLineCount() { + return totalLineCount_; + } + /** + * <code>optional int32 total_line_count = 101;</code> + * + * <pre> + * the number of source code lines that are instrumented for code coverage + * measurement. + * </pre> + */ + public Builder setTotalLineCount(int value) { + bitField0_ |= 0x00000010; + totalLineCount_ = value; + onChanged(); + return this; + } + /** + * <code>optional int32 total_line_count = 101;</code> + * + * <pre> + * the number of source code lines that are instrumented for code coverage + * measurement. + * </pre> + */ + public Builder clearTotalLineCount() { + bitField0_ = (bitField0_ & ~0x00000010); + totalLineCount_ = 0; + onChanged(); + return this; + } + + // optional int32 covered_line_count = 102; + private int coveredLineCount_ ; + /** + * <code>optional int32 covered_line_count = 102;</code> + * + * <pre> + * the number of source code lines that are executed. + * </pre> + */ + public boolean hasCoveredLineCount() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * <code>optional int32 covered_line_count = 102;</code> + * + * <pre> + * the number of source code lines that are executed. + * </pre> + */ + public int getCoveredLineCount() { + return coveredLineCount_; + } + /** + * <code>optional int32 covered_line_count = 102;</code> + * + * <pre> + * the number of source code lines that are executed. + * </pre> + */ + public Builder setCoveredLineCount(int value) { + bitField0_ |= 0x00000020; + coveredLineCount_ = value; + onChanged(); + return this; + } + /** + * <code>optional int32 covered_line_count = 102;</code> + * + * <pre> + * the number of source code lines that are executed. + * </pre> + */ + public Builder clearCoveredLineCount() { + bitField0_ = (bitField0_ & ~0x00000020); + coveredLineCount_ = 0; + onChanged(); + return this; + } + + // optional bytes dir_path = 1 [deprecated = true]; + private com.google.protobuf.ByteString dirPath_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes dir_path = 1 [deprecated = true];</code> + * + * <pre> + * TODO(ryanjcampbell@) delete deprecated field + * the directory path of a source file. + * </pre> + */ + @java.lang.Deprecated public boolean hasDirPath() { + return ((bitField0_ & 0x00000040) == 0x00000040); + } + /** + * <code>optional bytes dir_path = 1 [deprecated = true];</code> + * + * <pre> + * TODO(ryanjcampbell@) delete deprecated field + * the directory path of a source file. + * </pre> + */ + @java.lang.Deprecated public com.google.protobuf.ByteString getDirPath() { + return dirPath_; + } + /** + * <code>optional bytes dir_path = 1 [deprecated = true];</code> + * + * <pre> + * TODO(ryanjcampbell@) delete deprecated field + * the directory path of a source file. + * </pre> + */ + @java.lang.Deprecated public Builder setDirPath(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000040; + dirPath_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes dir_path = 1 [deprecated = true];</code> + * + * <pre> + * TODO(ryanjcampbell@) delete deprecated field + * the directory path of a source file. + * </pre> + */ + @java.lang.Deprecated public Builder clearDirPath() { + bitField0_ = (bitField0_ & ~0x00000040); + dirPath_ = getDefaultInstance().getDirPath(); + onChanged(); + return this; + } + + // optional bytes file_name = 2 [deprecated = true]; + private com.google.protobuf.ByteString fileName_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes file_name = 2 [deprecated = true];</code> + * + * <pre> + * TODO(ryanjcampbell@) delete deprecated field + * the name of the source file. + * </pre> + */ + @java.lang.Deprecated public boolean hasFileName() { + return ((bitField0_ & 0x00000080) == 0x00000080); + } + /** + * <code>optional bytes file_name = 2 [deprecated = true];</code> + * + * <pre> + * TODO(ryanjcampbell@) delete deprecated field + * the name of the source file. + * </pre> + */ + @java.lang.Deprecated public com.google.protobuf.ByteString getFileName() { + return fileName_; + } + /** + * <code>optional bytes file_name = 2 [deprecated = true];</code> + * + * <pre> + * TODO(ryanjcampbell@) delete deprecated field + * the name of the source file. + * </pre> + */ + @java.lang.Deprecated public Builder setFileName(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000080; + fileName_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes file_name = 2 [deprecated = true];</code> + * + * <pre> + * TODO(ryanjcampbell@) delete deprecated field + * the name of the source file. + * </pre> + */ + @java.lang.Deprecated public Builder clearFileName() { + bitField0_ = (bitField0_ & ~0x00000080); + fileName_ = getDefaultInstance().getFileName(); + onChanged(); + return this; + } + + // optional bytes html = 3 [deprecated = true]; + private com.google.protobuf.ByteString html_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes html = 3 [deprecated = true];</code> + * + * <pre> + * TODO(ryanjcampbell@) delete deprecated field + * produced html report. + * </pre> + */ + @java.lang.Deprecated public boolean hasHtml() { + return ((bitField0_ & 0x00000100) == 0x00000100); + } + /** + * <code>optional bytes html = 3 [deprecated = true];</code> + * + * <pre> + * TODO(ryanjcampbell@) delete deprecated field + * produced html report. + * </pre> + */ + @java.lang.Deprecated public com.google.protobuf.ByteString getHtml() { + return html_; + } + /** + * <code>optional bytes html = 3 [deprecated = true];</code> + * + * <pre> + * TODO(ryanjcampbell@) delete deprecated field + * produced html report. + * </pre> + */ + @java.lang.Deprecated public Builder setHtml(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000100; + html_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes html = 3 [deprecated = true];</code> + * + * <pre> + * TODO(ryanjcampbell@) delete deprecated field + * produced html report. + * </pre> + */ + @java.lang.Deprecated public Builder clearHtml() { + bitField0_ = (bitField0_ & ~0x00000100); + html_ = getDefaultInstance().getHtml(); + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:android.vts.CoverageReportMessage) + } + + static { + defaultInstance = new CoverageReportMessage(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:android.vts.CoverageReportMessage) + } + + public interface LogMessageOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // optional bytes url = 1; + /** + * <code>optional bytes url = 1;</code> + * + * <pre> + * URL of a produced log file (e.g., stdout, stderr). + * </pre> + */ + boolean hasUrl(); + /** + * <code>optional bytes url = 1;</code> + * + * <pre> + * URL of a produced log file (e.g., stdout, stderr). + * </pre> + */ + com.google.protobuf.ByteString getUrl(); + + // optional bytes name = 2; + /** + * <code>optional bytes name = 2;</code> + * + * <pre> + * Name of a log file. + * </pre> + */ + boolean hasName(); + /** + * <code>optional bytes name = 2;</code> + * + * <pre> + * Name of a log file. + * </pre> + */ + com.google.protobuf.ByteString getName(); + + // optional bytes content = 3; + /** + * <code>optional bytes content = 3;</code> + * + * <pre> + * Content of log. Caution: do not put too much log in protobuf message, + * as BigTable for example recommends < 10 MB for each record cell. + * </pre> + */ + boolean hasContent(); + /** + * <code>optional bytes content = 3;</code> + * + * <pre> + * Content of log. Caution: do not put too much log in protobuf message, + * as BigTable for example recommends < 10 MB for each record cell. + * </pre> + */ + com.google.protobuf.ByteString getContent(); + } + /** + * Protobuf type {@code android.vts.LogMessage} + * + * <pre> + * To specify log report. This can be used either for per-test-module + * log message or per-test-case log message. + * </pre> + */ + public static final class LogMessage extends + com.google.protobuf.GeneratedMessage + implements LogMessageOrBuilder { + // Use LogMessage.newBuilder() to construct. + private LogMessage(com.google.protobuf.GeneratedMessage.Builder<?> builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private LogMessage(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final LogMessage defaultInstance; + public static LogMessage getDefaultInstance() { + return defaultInstance; + } + + public LogMessage getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private LogMessage( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + url_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + name_ = input.readBytes(); + break; + } + case 26: { + bitField0_ |= 0x00000004; + content_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_LogMessage_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_LogMessage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.android.vts.proto.VtsReportMessage.LogMessage.class, com.android.vts.proto.VtsReportMessage.LogMessage.Builder.class); + } + + public static com.google.protobuf.Parser<LogMessage> PARSER = + new com.google.protobuf.AbstractParser<LogMessage>() { + public LogMessage parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new LogMessage(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser<LogMessage> getParserForType() { + return PARSER; + } + + private int bitField0_; + // optional bytes url = 1; + public static final int URL_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString url_; + /** + * <code>optional bytes url = 1;</code> + * + * <pre> + * URL of a produced log file (e.g., stdout, stderr). + * </pre> + */ + public boolean hasUrl() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * <code>optional bytes url = 1;</code> + * + * <pre> + * URL of a produced log file (e.g., stdout, stderr). + * </pre> + */ + public com.google.protobuf.ByteString getUrl() { + return url_; + } + + // optional bytes name = 2; + public static final int NAME_FIELD_NUMBER = 2; + private com.google.protobuf.ByteString name_; + /** + * <code>optional bytes name = 2;</code> + * + * <pre> + * Name of a log file. + * </pre> + */ + public boolean hasName() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * <code>optional bytes name = 2;</code> + * + * <pre> + * Name of a log file. + * </pre> + */ + public com.google.protobuf.ByteString getName() { + return name_; + } + + // optional bytes content = 3; + public static final int CONTENT_FIELD_NUMBER = 3; + private com.google.protobuf.ByteString content_; + /** + * <code>optional bytes content = 3;</code> + * + * <pre> + * Content of log. Caution: do not put too much log in protobuf message, + * as BigTable for example recommends < 10 MB for each record cell. + * </pre> + */ + public boolean hasContent() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * <code>optional bytes content = 3;</code> + * + * <pre> + * Content of log. Caution: do not put too much log in protobuf message, + * as BigTable for example recommends < 10 MB for each record cell. + * </pre> + */ + public com.google.protobuf.ByteString getContent() { + return content_; + } + + private void initFields() { + url_ = com.google.protobuf.ByteString.EMPTY; + name_ = com.google.protobuf.ByteString.EMPTY; + content_ = com.google.protobuf.ByteString.EMPTY; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, url_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, name_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeBytes(3, content_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, url_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, name_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(3, content_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static com.android.vts.proto.VtsReportMessage.LogMessage parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.android.vts.proto.VtsReportMessage.LogMessage parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.LogMessage parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.android.vts.proto.VtsReportMessage.LogMessage parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.LogMessage parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.LogMessage parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.LogMessage parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.LogMessage parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.LogMessage parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.LogMessage parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(com.android.vts.proto.VtsReportMessage.LogMessage prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code android.vts.LogMessage} + * + * <pre> + * To specify log report. This can be used either for per-test-module + * log message or per-test-case log message. + * </pre> + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder<Builder> + implements com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_LogMessage_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_LogMessage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.android.vts.proto.VtsReportMessage.LogMessage.class, com.android.vts.proto.VtsReportMessage.LogMessage.Builder.class); + } + + // Construct using com.android.vts.proto.VtsReportMessage.LogMessage.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + url_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + name_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000002); + content_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_LogMessage_descriptor; + } + + public com.android.vts.proto.VtsReportMessage.LogMessage getDefaultInstanceForType() { + return com.android.vts.proto.VtsReportMessage.LogMessage.getDefaultInstance(); + } + + public com.android.vts.proto.VtsReportMessage.LogMessage build() { + com.android.vts.proto.VtsReportMessage.LogMessage result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public com.android.vts.proto.VtsReportMessage.LogMessage buildPartial() { + com.android.vts.proto.VtsReportMessage.LogMessage result = new com.android.vts.proto.VtsReportMessage.LogMessage(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.url_ = url_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.name_ = name_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.content_ = content_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.android.vts.proto.VtsReportMessage.LogMessage) { + return mergeFrom((com.android.vts.proto.VtsReportMessage.LogMessage)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.android.vts.proto.VtsReportMessage.LogMessage other) { + if (other == com.android.vts.proto.VtsReportMessage.LogMessage.getDefaultInstance()) return this; + if (other.hasUrl()) { + setUrl(other.getUrl()); + } + if (other.hasName()) { + setName(other.getName()); + } + if (other.hasContent()) { + setContent(other.getContent()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + com.android.vts.proto.VtsReportMessage.LogMessage parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (com.android.vts.proto.VtsReportMessage.LogMessage) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // optional bytes url = 1; + private com.google.protobuf.ByteString url_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes url = 1;</code> + * + * <pre> + * URL of a produced log file (e.g., stdout, stderr). + * </pre> + */ + public boolean hasUrl() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * <code>optional bytes url = 1;</code> + * + * <pre> + * URL of a produced log file (e.g., stdout, stderr). + * </pre> + */ + public com.google.protobuf.ByteString getUrl() { + return url_; + } + /** + * <code>optional bytes url = 1;</code> + * + * <pre> + * URL of a produced log file (e.g., stdout, stderr). + * </pre> + */ + public Builder setUrl(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + url_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes url = 1;</code> + * + * <pre> + * URL of a produced log file (e.g., stdout, stderr). + * </pre> + */ + public Builder clearUrl() { + bitField0_ = (bitField0_ & ~0x00000001); + url_ = getDefaultInstance().getUrl(); + onChanged(); + return this; + } + + // optional bytes name = 2; + private com.google.protobuf.ByteString name_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes name = 2;</code> + * + * <pre> + * Name of a log file. + * </pre> + */ + public boolean hasName() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * <code>optional bytes name = 2;</code> + * + * <pre> + * Name of a log file. + * </pre> + */ + public com.google.protobuf.ByteString getName() { + return name_; + } + /** + * <code>optional bytes name = 2;</code> + * + * <pre> + * Name of a log file. + * </pre> + */ + public Builder setName(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + name_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes name = 2;</code> + * + * <pre> + * Name of a log file. + * </pre> + */ + public Builder clearName() { + bitField0_ = (bitField0_ & ~0x00000002); + name_ = getDefaultInstance().getName(); + onChanged(); + return this; + } + + // optional bytes content = 3; + private com.google.protobuf.ByteString content_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes content = 3;</code> + * + * <pre> + * Content of log. Caution: do not put too much log in protobuf message, + * as BigTable for example recommends < 10 MB for each record cell. + * </pre> + */ + public boolean hasContent() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * <code>optional bytes content = 3;</code> + * + * <pre> + * Content of log. Caution: do not put too much log in protobuf message, + * as BigTable for example recommends < 10 MB for each record cell. + * </pre> + */ + public com.google.protobuf.ByteString getContent() { + return content_; + } + /** + * <code>optional bytes content = 3;</code> + * + * <pre> + * Content of log. Caution: do not put too much log in protobuf message, + * as BigTable for example recommends < 10 MB for each record cell. + * </pre> + */ + public Builder setContent(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + content_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes content = 3;</code> + * + * <pre> + * Content of log. Caution: do not put too much log in protobuf message, + * as BigTable for example recommends < 10 MB for each record cell. + * </pre> + */ + public Builder clearContent() { + bitField0_ = (bitField0_ & ~0x00000004); + content_ = getDefaultInstance().getContent(); + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:android.vts.LogMessage) + } + + static { + defaultInstance = new LogMessage(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:android.vts.LogMessage) + } + + public interface UrlResourceMessageOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // optional bytes url = 1; + /** + * <code>optional bytes url = 1;</code> + * + * <pre> + * URL of a resource file. + * </pre> + */ + boolean hasUrl(); + /** + * <code>optional bytes url = 1;</code> + * + * <pre> + * URL of a resource file. + * </pre> + */ + com.google.protobuf.ByteString getUrl(); + + // optional bytes name = 2; + /** + * <code>optional bytes name = 2;</code> + * + * <pre> + * Name of a resource file representing its type and does not have to be + * the same as the exact file name. + * </pre> + */ + boolean hasName(); + /** + * <code>optional bytes name = 2;</code> + * + * <pre> + * Name of a resource file representing its type and does not have to be + * the same as the exact file name. + * </pre> + */ + com.google.protobuf.ByteString getName(); + + // optional bytes content = 3; + /** + * <code>optional bytes content = 3;</code> + * + * <pre> + * Raw content of a resource file. Used if the file is small. + * </pre> + */ + boolean hasContent(); + /** + * <code>optional bytes content = 3;</code> + * + * <pre> + * Raw content of a resource file. Used if the file is small. + * </pre> + */ + com.google.protobuf.ByteString getContent(); + } + /** + * Protobuf type {@code android.vts.UrlResourceMessage} + * + * <pre> + * To specify a resource object (reachable via a URL or contained in the + * message). This can be used to store a log file or an XML (or HTML) report + * file kept in a Google Cloud Storage (GCS) bucket or partner's network file + * system, or hosted by a HTTP server. + * </pre> + */ + public static final class UrlResourceMessage extends + com.google.protobuf.GeneratedMessage + implements UrlResourceMessageOrBuilder { + // Use UrlResourceMessage.newBuilder() to construct. + private UrlResourceMessage(com.google.protobuf.GeneratedMessage.Builder<?> builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private UrlResourceMessage(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final UrlResourceMessage defaultInstance; + public static UrlResourceMessage getDefaultInstance() { + return defaultInstance; + } + + public UrlResourceMessage getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private UrlResourceMessage( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + url_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + name_ = input.readBytes(); + break; + } + case 26: { + bitField0_ |= 0x00000004; + content_ = input.readBytes(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_UrlResourceMessage_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_UrlResourceMessage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.android.vts.proto.VtsReportMessage.UrlResourceMessage.class, com.android.vts.proto.VtsReportMessage.UrlResourceMessage.Builder.class); + } + + public static com.google.protobuf.Parser<UrlResourceMessage> PARSER = + new com.google.protobuf.AbstractParser<UrlResourceMessage>() { + public UrlResourceMessage parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new UrlResourceMessage(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser<UrlResourceMessage> getParserForType() { + return PARSER; + } + + private int bitField0_; + // optional bytes url = 1; + public static final int URL_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString url_; + /** + * <code>optional bytes url = 1;</code> + * + * <pre> + * URL of a resource file. + * </pre> + */ + public boolean hasUrl() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * <code>optional bytes url = 1;</code> + * + * <pre> + * URL of a resource file. + * </pre> + */ + public com.google.protobuf.ByteString getUrl() { + return url_; + } + + // optional bytes name = 2; + public static final int NAME_FIELD_NUMBER = 2; + private com.google.protobuf.ByteString name_; + /** + * <code>optional bytes name = 2;</code> + * + * <pre> + * Name of a resource file representing its type and does not have to be + * the same as the exact file name. + * </pre> + */ + public boolean hasName() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * <code>optional bytes name = 2;</code> + * + * <pre> + * Name of a resource file representing its type and does not have to be + * the same as the exact file name. + * </pre> + */ + public com.google.protobuf.ByteString getName() { + return name_; + } + + // optional bytes content = 3; + public static final int CONTENT_FIELD_NUMBER = 3; + private com.google.protobuf.ByteString content_; + /** + * <code>optional bytes content = 3;</code> + * + * <pre> + * Raw content of a resource file. Used if the file is small. + * </pre> + */ + public boolean hasContent() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * <code>optional bytes content = 3;</code> + * + * <pre> + * Raw content of a resource file. Used if the file is small. + * </pre> + */ + public com.google.protobuf.ByteString getContent() { + return content_; + } + + private void initFields() { + url_ = com.google.protobuf.ByteString.EMPTY; + name_ = com.google.protobuf.ByteString.EMPTY; + content_ = com.google.protobuf.ByteString.EMPTY; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, url_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, name_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeBytes(3, content_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, url_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, name_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(3, content_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static com.android.vts.proto.VtsReportMessage.UrlResourceMessage parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.android.vts.proto.VtsReportMessage.UrlResourceMessage parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.UrlResourceMessage parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.android.vts.proto.VtsReportMessage.UrlResourceMessage parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.UrlResourceMessage parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.UrlResourceMessage parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.UrlResourceMessage parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.UrlResourceMessage parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.UrlResourceMessage parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.UrlResourceMessage parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(com.android.vts.proto.VtsReportMessage.UrlResourceMessage prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code android.vts.UrlResourceMessage} + * + * <pre> + * To specify a resource object (reachable via a URL or contained in the + * message). This can be used to store a log file or an XML (or HTML) report + * file kept in a Google Cloud Storage (GCS) bucket or partner's network file + * system, or hosted by a HTTP server. + * </pre> + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder<Builder> + implements com.android.vts.proto.VtsReportMessage.UrlResourceMessageOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_UrlResourceMessage_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_UrlResourceMessage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.android.vts.proto.VtsReportMessage.UrlResourceMessage.class, com.android.vts.proto.VtsReportMessage.UrlResourceMessage.Builder.class); + } + + // Construct using com.android.vts.proto.VtsReportMessage.UrlResourceMessage.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + url_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + name_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000002); + content_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000004); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_UrlResourceMessage_descriptor; + } + + public com.android.vts.proto.VtsReportMessage.UrlResourceMessage getDefaultInstanceForType() { + return com.android.vts.proto.VtsReportMessage.UrlResourceMessage.getDefaultInstance(); + } + + public com.android.vts.proto.VtsReportMessage.UrlResourceMessage build() { + com.android.vts.proto.VtsReportMessage.UrlResourceMessage result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public com.android.vts.proto.VtsReportMessage.UrlResourceMessage buildPartial() { + com.android.vts.proto.VtsReportMessage.UrlResourceMessage result = new com.android.vts.proto.VtsReportMessage.UrlResourceMessage(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.url_ = url_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.name_ = name_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.content_ = content_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.android.vts.proto.VtsReportMessage.UrlResourceMessage) { + return mergeFrom((com.android.vts.proto.VtsReportMessage.UrlResourceMessage)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.android.vts.proto.VtsReportMessage.UrlResourceMessage other) { + if (other == com.android.vts.proto.VtsReportMessage.UrlResourceMessage.getDefaultInstance()) return this; + if (other.hasUrl()) { + setUrl(other.getUrl()); + } + if (other.hasName()) { + setName(other.getName()); + } + if (other.hasContent()) { + setContent(other.getContent()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + com.android.vts.proto.VtsReportMessage.UrlResourceMessage parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (com.android.vts.proto.VtsReportMessage.UrlResourceMessage) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // optional bytes url = 1; + private com.google.protobuf.ByteString url_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes url = 1;</code> + * + * <pre> + * URL of a resource file. + * </pre> + */ + public boolean hasUrl() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * <code>optional bytes url = 1;</code> + * + * <pre> + * URL of a resource file. + * </pre> + */ + public com.google.protobuf.ByteString getUrl() { + return url_; + } + /** + * <code>optional bytes url = 1;</code> + * + * <pre> + * URL of a resource file. + * </pre> + */ + public Builder setUrl(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + url_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes url = 1;</code> + * + * <pre> + * URL of a resource file. + * </pre> + */ + public Builder clearUrl() { + bitField0_ = (bitField0_ & ~0x00000001); + url_ = getDefaultInstance().getUrl(); + onChanged(); + return this; + } + + // optional bytes name = 2; + private com.google.protobuf.ByteString name_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes name = 2;</code> + * + * <pre> + * Name of a resource file representing its type and does not have to be + * the same as the exact file name. + * </pre> + */ + public boolean hasName() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * <code>optional bytes name = 2;</code> + * + * <pre> + * Name of a resource file representing its type and does not have to be + * the same as the exact file name. + * </pre> + */ + public com.google.protobuf.ByteString getName() { + return name_; + } + /** + * <code>optional bytes name = 2;</code> + * + * <pre> + * Name of a resource file representing its type and does not have to be + * the same as the exact file name. + * </pre> + */ + public Builder setName(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + name_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes name = 2;</code> + * + * <pre> + * Name of a resource file representing its type and does not have to be + * the same as the exact file name. + * </pre> + */ + public Builder clearName() { + bitField0_ = (bitField0_ & ~0x00000002); + name_ = getDefaultInstance().getName(); + onChanged(); + return this; + } + + // optional bytes content = 3; + private com.google.protobuf.ByteString content_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes content = 3;</code> + * + * <pre> + * Raw content of a resource file. Used if the file is small. + * </pre> + */ + public boolean hasContent() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * <code>optional bytes content = 3;</code> + * + * <pre> + * Raw content of a resource file. Used if the file is small. + * </pre> + */ + public com.google.protobuf.ByteString getContent() { + return content_; + } + /** + * <code>optional bytes content = 3;</code> + * + * <pre> + * Raw content of a resource file. Used if the file is small. + * </pre> + */ + public Builder setContent(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + content_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes content = 3;</code> + * + * <pre> + * Raw content of a resource file. Used if the file is small. + * </pre> + */ + public Builder clearContent() { + bitField0_ = (bitField0_ & ~0x00000004); + content_ = getDefaultInstance().getContent(); + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:android.vts.UrlResourceMessage) + } + + static { + defaultInstance = new UrlResourceMessage(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:android.vts.UrlResourceMessage) + } + + public interface TestReportMessageOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // optional bytes test_suite = 1 [deprecated = true]; + /** + * <code>optional bytes test_suite = 1 [deprecated = true];</code> + * + * <pre> + * The test suite name.. + * </pre> + */ + @java.lang.Deprecated boolean hasTestSuite(); + /** + * <code>optional bytes test_suite = 1 [deprecated = true];</code> + * + * <pre> + * The test suite name.. + * </pre> + */ + @java.lang.Deprecated com.google.protobuf.ByteString getTestSuite(); + + // optional bytes test = 2; + /** + * <code>optional bytes test = 2;</code> + * + * <pre> + * The test name. + * </pre> + */ + boolean hasTest(); + /** + * <code>optional bytes test = 2;</code> + * + * <pre> + * The test name. + * </pre> + */ + com.google.protobuf.ByteString getTest(); + + // optional .android.vts.VtsTestType test_type = 3; + /** + * <code>optional .android.vts.VtsTestType test_type = 3;</code> + * + * <pre> + * The test type + * </pre> + */ + boolean hasTestType(); + /** + * <code>optional .android.vts.VtsTestType test_type = 3;</code> + * + * <pre> + * The test type + * </pre> + */ + com.android.vts.proto.VtsReportMessage.VtsTestType getTestType(); + + // repeated .android.vts.AndroidDeviceInfoMessage device_info = 4; + /** + * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code> + * + * <pre> + * Target device info + * </pre> + */ + java.util.List<com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage> + getDeviceInfoList(); + /** + * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code> + * + * <pre> + * Target device info + * </pre> + */ + com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage getDeviceInfo(int index); + /** + * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code> + * + * <pre> + * Target device info + * </pre> + */ + int getDeviceInfoCount(); + /** + * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code> + * + * <pre> + * Target device info + * </pre> + */ + java.util.List<? extends com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessageOrBuilder> + getDeviceInfoOrBuilderList(); + /** + * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code> + * + * <pre> + * Target device info + * </pre> + */ + com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessageOrBuilder getDeviceInfoOrBuilder( + int index); + + // optional .android.vts.AndroidBuildInfo build_info = 5; + /** + * <code>optional .android.vts.AndroidBuildInfo build_info = 5;</code> + * + * <pre> + * Build info + * </pre> + */ + boolean hasBuildInfo(); + /** + * <code>optional .android.vts.AndroidBuildInfo build_info = 5;</code> + * + * <pre> + * Build info + * </pre> + */ + com.android.vts.proto.VtsReportMessage.AndroidBuildInfo getBuildInfo(); + /** + * <code>optional .android.vts.AndroidBuildInfo build_info = 5;</code> + * + * <pre> + * Build info + * </pre> + */ + com.android.vts.proto.VtsReportMessage.AndroidBuildInfoOrBuilder getBuildInfoOrBuilder(); + + // repeated bytes subscriber_email = 6; + /** + * <code>repeated bytes subscriber_email = 6;</code> + * + * <pre> + * Email addresses of subscribers to the test results + * </pre> + */ + java.util.List<com.google.protobuf.ByteString> getSubscriberEmailList(); + /** + * <code>repeated bytes subscriber_email = 6;</code> + * + * <pre> + * Email addresses of subscribers to the test results + * </pre> + */ + int getSubscriberEmailCount(); + /** + * <code>repeated bytes subscriber_email = 6;</code> + * + * <pre> + * Email addresses of subscribers to the test results + * </pre> + */ + com.google.protobuf.ByteString getSubscriberEmail(int index); + + // optional .android.vts.VtsHostInfo host_info = 7; + /** + * <code>optional .android.vts.VtsHostInfo host_info = 7;</code> + * + * <pre> + * Info about the host computer + * </pre> + */ + boolean hasHostInfo(); + /** + * <code>optional .android.vts.VtsHostInfo host_info = 7;</code> + * + * <pre> + * Info about the host computer + * </pre> + */ + com.android.vts.proto.VtsReportMessage.VtsHostInfo getHostInfo(); + /** + * <code>optional .android.vts.VtsHostInfo host_info = 7;</code> + * + * <pre> + * Info about the host computer + * </pre> + */ + com.android.vts.proto.VtsReportMessage.VtsHostInfoOrBuilder getHostInfoOrBuilder(); + + // repeated .android.vts.TestCaseReportMessage test_case = 11; + /** + * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code> + * + * <pre> + * Test case reports + * </pre> + */ + java.util.List<com.android.vts.proto.VtsReportMessage.TestCaseReportMessage> + getTestCaseList(); + /** + * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code> + * + * <pre> + * Test case reports + * </pre> + */ + com.android.vts.proto.VtsReportMessage.TestCaseReportMessage getTestCase(int index); + /** + * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code> + * + * <pre> + * Test case reports + * </pre> + */ + int getTestCaseCount(); + /** + * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code> + * + * <pre> + * Test case reports + * </pre> + */ + java.util.List<? extends com.android.vts.proto.VtsReportMessage.TestCaseReportMessageOrBuilder> + getTestCaseOrBuilderList(); + /** + * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code> + * + * <pre> + * Test case reports + * </pre> + */ + com.android.vts.proto.VtsReportMessage.TestCaseReportMessageOrBuilder getTestCaseOrBuilder( + int index); + + // repeated .android.vts.ProfilingReportMessage profiling = 21; + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code> + * + * <pre> + * Profiling reports + * </pre> + */ + java.util.List<com.android.vts.proto.VtsReportMessage.ProfilingReportMessage> + getProfilingList(); + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code> + * + * <pre> + * Profiling reports + * </pre> + */ + com.android.vts.proto.VtsReportMessage.ProfilingReportMessage getProfiling(int index); + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code> + * + * <pre> + * Profiling reports + * </pre> + */ + int getProfilingCount(); + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code> + * + * <pre> + * Profiling reports + * </pre> + */ + java.util.List<? extends com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder> + getProfilingOrBuilderList(); + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code> + * + * <pre> + * Profiling reports + * </pre> + */ + com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder getProfilingOrBuilder( + int index); + + // repeated .android.vts.SystraceReportMessage systrace = 22; + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code> + * + * <pre> + * Systrace report per file + * </pre> + */ + java.util.List<com.android.vts.proto.VtsReportMessage.SystraceReportMessage> + getSystraceList(); + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code> + * + * <pre> + * Systrace report per file + * </pre> + */ + com.android.vts.proto.VtsReportMessage.SystraceReportMessage getSystrace(int index); + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code> + * + * <pre> + * Systrace report per file + * </pre> + */ + int getSystraceCount(); + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code> + * + * <pre> + * Systrace report per file + * </pre> + */ + java.util.List<? extends com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder> + getSystraceOrBuilderList(); + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code> + * + * <pre> + * Systrace report per file + * </pre> + */ + com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder getSystraceOrBuilder( + int index); + + // optional int64 start_timestamp = 101; + /** + * <code>optional int64 start_timestamp = 101;</code> + * + * <pre> + * Execution start and end time stamp. + * </pre> + */ + boolean hasStartTimestamp(); + /** + * <code>optional int64 start_timestamp = 101;</code> + * + * <pre> + * Execution start and end time stamp. + * </pre> + */ + long getStartTimestamp(); + + // optional int64 end_timestamp = 102; + /** + * <code>optional int64 end_timestamp = 102;</code> + */ + boolean hasEndTimestamp(); + /** + * <code>optional int64 end_timestamp = 102;</code> + */ + long getEndTimestamp(); + + // repeated .android.vts.CoverageReportMessage coverage = 103; + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code> + * + * <pre> + * Coverage report per file + * </pre> + */ + java.util.List<com.android.vts.proto.VtsReportMessage.CoverageReportMessage> + getCoverageList(); + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code> + * + * <pre> + * Coverage report per file + * </pre> + */ + com.android.vts.proto.VtsReportMessage.CoverageReportMessage getCoverage(int index); + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code> + * + * <pre> + * Coverage report per file + * </pre> + */ + int getCoverageCount(); + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code> + * + * <pre> + * Coverage report per file + * </pre> + */ + java.util.List<? extends com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder> + getCoverageOrBuilderList(); + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code> + * + * <pre> + * Coverage report per file + * </pre> + */ + com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder getCoverageOrBuilder( + int index); + + // repeated .android.vts.LogMessage log = 1001; + /** + * <code>repeated .android.vts.LogMessage log = 1001;</code> + * + * <pre> + * Log for a test module. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + java.util.List<com.android.vts.proto.VtsReportMessage.LogMessage> + getLogList(); + /** + * <code>repeated .android.vts.LogMessage log = 1001;</code> + * + * <pre> + * Log for a test module. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + com.android.vts.proto.VtsReportMessage.LogMessage getLog(int index); + /** + * <code>repeated .android.vts.LogMessage log = 1001;</code> + * + * <pre> + * Log for a test module. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + int getLogCount(); + /** + * <code>repeated .android.vts.LogMessage log = 1001;</code> + * + * <pre> + * Log for a test module. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + java.util.List<? extends com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder> + getLogOrBuilderList(); + /** + * <code>repeated .android.vts.LogMessage log = 1001;</code> + * + * <pre> + * Log for a test module. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder getLogOrBuilder( + int index); + } + /** + * Protobuf type {@code android.vts.TestReportMessage} + * + * <pre> + * To specify a test execution report. + * </pre> + */ + public static final class TestReportMessage extends + com.google.protobuf.GeneratedMessage + implements TestReportMessageOrBuilder { + // Use TestReportMessage.newBuilder() to construct. + private TestReportMessage(com.google.protobuf.GeneratedMessage.Builder<?> builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private TestReportMessage(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final TestReportMessage defaultInstance; + public static TestReportMessage getDefaultInstance() { + return defaultInstance; + } + + public TestReportMessage getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private TestReportMessage( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + testSuite_ = input.readBytes(); + break; + } + case 18: { + bitField0_ |= 0x00000002; + test_ = input.readBytes(); + break; + } + case 24: { + int rawValue = input.readEnum(); + com.android.vts.proto.VtsReportMessage.VtsTestType value = com.android.vts.proto.VtsReportMessage.VtsTestType.valueOf(rawValue); + if (value == null) { + unknownFields.mergeVarintField(3, rawValue); + } else { + bitField0_ |= 0x00000004; + testType_ = value; + } + break; + } + case 34: { + if (!((mutable_bitField0_ & 0x00000008) == 0x00000008)) { + deviceInfo_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage>(); + mutable_bitField0_ |= 0x00000008; + } + deviceInfo_.add(input.readMessage(com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.PARSER, extensionRegistry)); + break; + } + case 42: { + com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.Builder subBuilder = null; + if (((bitField0_ & 0x00000008) == 0x00000008)) { + subBuilder = buildInfo_.toBuilder(); + } + buildInfo_ = input.readMessage(com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(buildInfo_); + buildInfo_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000008; + break; + } + case 50: { + if (!((mutable_bitField0_ & 0x00000020) == 0x00000020)) { + subscriberEmail_ = new java.util.ArrayList<com.google.protobuf.ByteString>(); + mutable_bitField0_ |= 0x00000020; + } + subscriberEmail_.add(input.readBytes()); + break; + } + case 58: { + com.android.vts.proto.VtsReportMessage.VtsHostInfo.Builder subBuilder = null; + if (((bitField0_ & 0x00000010) == 0x00000010)) { + subBuilder = hostInfo_.toBuilder(); + } + hostInfo_ = input.readMessage(com.android.vts.proto.VtsReportMessage.VtsHostInfo.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(hostInfo_); + hostInfo_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000010; + break; + } + case 90: { + if (!((mutable_bitField0_ & 0x00000080) == 0x00000080)) { + testCase_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.TestCaseReportMessage>(); + mutable_bitField0_ |= 0x00000080; + } + testCase_.add(input.readMessage(com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.PARSER, extensionRegistry)); + break; + } + case 170: { + if (!((mutable_bitField0_ & 0x00000100) == 0x00000100)) { + profiling_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.ProfilingReportMessage>(); + mutable_bitField0_ |= 0x00000100; + } + profiling_.add(input.readMessage(com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.PARSER, extensionRegistry)); + break; + } + case 178: { + if (!((mutable_bitField0_ & 0x00000200) == 0x00000200)) { + systrace_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.SystraceReportMessage>(); + mutable_bitField0_ |= 0x00000200; + } + systrace_.add(input.readMessage(com.android.vts.proto.VtsReportMessage.SystraceReportMessage.PARSER, extensionRegistry)); + break; + } + case 808: { + bitField0_ |= 0x00000020; + startTimestamp_ = input.readInt64(); + break; + } + case 816: { + bitField0_ |= 0x00000040; + endTimestamp_ = input.readInt64(); + break; + } + case 826: { + if (!((mutable_bitField0_ & 0x00001000) == 0x00001000)) { + coverage_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.CoverageReportMessage>(); + mutable_bitField0_ |= 0x00001000; + } + coverage_.add(input.readMessage(com.android.vts.proto.VtsReportMessage.CoverageReportMessage.PARSER, extensionRegistry)); + break; + } + case 8010: { + if (!((mutable_bitField0_ & 0x00002000) == 0x00002000)) { + log_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.LogMessage>(); + mutable_bitField0_ |= 0x00002000; + } + log_.add(input.readMessage(com.android.vts.proto.VtsReportMessage.LogMessage.PARSER, extensionRegistry)); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000008) == 0x00000008)) { + deviceInfo_ = java.util.Collections.unmodifiableList(deviceInfo_); + } + if (((mutable_bitField0_ & 0x00000020) == 0x00000020)) { + subscriberEmail_ = java.util.Collections.unmodifiableList(subscriberEmail_); + } + if (((mutable_bitField0_ & 0x00000080) == 0x00000080)) { + testCase_ = java.util.Collections.unmodifiableList(testCase_); + } + if (((mutable_bitField0_ & 0x00000100) == 0x00000100)) { + profiling_ = java.util.Collections.unmodifiableList(profiling_); + } + if (((mutable_bitField0_ & 0x00000200) == 0x00000200)) { + systrace_ = java.util.Collections.unmodifiableList(systrace_); + } + if (((mutable_bitField0_ & 0x00001000) == 0x00001000)) { + coverage_ = java.util.Collections.unmodifiableList(coverage_); + } + if (((mutable_bitField0_ & 0x00002000) == 0x00002000)) { + log_ = java.util.Collections.unmodifiableList(log_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_TestReportMessage_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_TestReportMessage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.android.vts.proto.VtsReportMessage.TestReportMessage.class, com.android.vts.proto.VtsReportMessage.TestReportMessage.Builder.class); + } + + public static com.google.protobuf.Parser<TestReportMessage> PARSER = + new com.google.protobuf.AbstractParser<TestReportMessage>() { + public TestReportMessage parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new TestReportMessage(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser<TestReportMessage> getParserForType() { + return PARSER; + } + + private int bitField0_; + // optional bytes test_suite = 1 [deprecated = true]; + public static final int TEST_SUITE_FIELD_NUMBER = 1; + private com.google.protobuf.ByteString testSuite_; + /** + * <code>optional bytes test_suite = 1 [deprecated = true];</code> + * + * <pre> + * The test suite name.. + * </pre> + */ + @java.lang.Deprecated public boolean hasTestSuite() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * <code>optional bytes test_suite = 1 [deprecated = true];</code> + * + * <pre> + * The test suite name.. + * </pre> + */ + @java.lang.Deprecated public com.google.protobuf.ByteString getTestSuite() { + return testSuite_; + } + + // optional bytes test = 2; + public static final int TEST_FIELD_NUMBER = 2; + private com.google.protobuf.ByteString test_; + /** + * <code>optional bytes test = 2;</code> + * + * <pre> + * The test name. + * </pre> + */ + public boolean hasTest() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * <code>optional bytes test = 2;</code> + * + * <pre> + * The test name. + * </pre> + */ + public com.google.protobuf.ByteString getTest() { + return test_; + } + + // optional .android.vts.VtsTestType test_type = 3; + public static final int TEST_TYPE_FIELD_NUMBER = 3; + private com.android.vts.proto.VtsReportMessage.VtsTestType testType_; + /** + * <code>optional .android.vts.VtsTestType test_type = 3;</code> + * + * <pre> + * The test type + * </pre> + */ + public boolean hasTestType() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * <code>optional .android.vts.VtsTestType test_type = 3;</code> + * + * <pre> + * The test type + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.VtsTestType getTestType() { + return testType_; + } + + // repeated .android.vts.AndroidDeviceInfoMessage device_info = 4; + public static final int DEVICE_INFO_FIELD_NUMBER = 4; + private java.util.List<com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage> deviceInfo_; + /** + * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code> + * + * <pre> + * Target device info + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage> getDeviceInfoList() { + return deviceInfo_; + } + /** + * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code> + * + * <pre> + * Target device info + * </pre> + */ + public java.util.List<? extends com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessageOrBuilder> + getDeviceInfoOrBuilderList() { + return deviceInfo_; + } + /** + * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code> + * + * <pre> + * Target device info + * </pre> + */ + public int getDeviceInfoCount() { + return deviceInfo_.size(); + } + /** + * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code> + * + * <pre> + * Target device info + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage getDeviceInfo(int index) { + return deviceInfo_.get(index); + } + /** + * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code> + * + * <pre> + * Target device info + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessageOrBuilder getDeviceInfoOrBuilder( + int index) { + return deviceInfo_.get(index); + } + + // optional .android.vts.AndroidBuildInfo build_info = 5; + public static final int BUILD_INFO_FIELD_NUMBER = 5; + private com.android.vts.proto.VtsReportMessage.AndroidBuildInfo buildInfo_; + /** + * <code>optional .android.vts.AndroidBuildInfo build_info = 5;</code> + * + * <pre> + * Build info + * </pre> + */ + public boolean hasBuildInfo() { + return ((bitField0_ & 0x00000008) == 0x00000008); + } + /** + * <code>optional .android.vts.AndroidBuildInfo build_info = 5;</code> + * + * <pre> + * Build info + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.AndroidBuildInfo getBuildInfo() { + return buildInfo_; + } + /** + * <code>optional .android.vts.AndroidBuildInfo build_info = 5;</code> + * + * <pre> + * Build info + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.AndroidBuildInfoOrBuilder getBuildInfoOrBuilder() { + return buildInfo_; + } + + // repeated bytes subscriber_email = 6; + public static final int SUBSCRIBER_EMAIL_FIELD_NUMBER = 6; + private java.util.List<com.google.protobuf.ByteString> subscriberEmail_; + /** + * <code>repeated bytes subscriber_email = 6;</code> + * + * <pre> + * Email addresses of subscribers to the test results + * </pre> + */ + public java.util.List<com.google.protobuf.ByteString> + getSubscriberEmailList() { + return subscriberEmail_; + } + /** + * <code>repeated bytes subscriber_email = 6;</code> + * + * <pre> + * Email addresses of subscribers to the test results + * </pre> + */ + public int getSubscriberEmailCount() { + return subscriberEmail_.size(); + } + /** + * <code>repeated bytes subscriber_email = 6;</code> + * + * <pre> + * Email addresses of subscribers to the test results + * </pre> + */ + public com.google.protobuf.ByteString getSubscriberEmail(int index) { + return subscriberEmail_.get(index); + } + + // optional .android.vts.VtsHostInfo host_info = 7; + public static final int HOST_INFO_FIELD_NUMBER = 7; + private com.android.vts.proto.VtsReportMessage.VtsHostInfo hostInfo_; + /** + * <code>optional .android.vts.VtsHostInfo host_info = 7;</code> + * + * <pre> + * Info about the host computer + * </pre> + */ + public boolean hasHostInfo() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * <code>optional .android.vts.VtsHostInfo host_info = 7;</code> + * + * <pre> + * Info about the host computer + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.VtsHostInfo getHostInfo() { + return hostInfo_; + } + /** + * <code>optional .android.vts.VtsHostInfo host_info = 7;</code> + * + * <pre> + * Info about the host computer + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.VtsHostInfoOrBuilder getHostInfoOrBuilder() { + return hostInfo_; + } + + // repeated .android.vts.TestCaseReportMessage test_case = 11; + public static final int TEST_CASE_FIELD_NUMBER = 11; + private java.util.List<com.android.vts.proto.VtsReportMessage.TestCaseReportMessage> testCase_; + /** + * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code> + * + * <pre> + * Test case reports + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.TestCaseReportMessage> getTestCaseList() { + return testCase_; + } + /** + * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code> + * + * <pre> + * Test case reports + * </pre> + */ + public java.util.List<? extends com.android.vts.proto.VtsReportMessage.TestCaseReportMessageOrBuilder> + getTestCaseOrBuilderList() { + return testCase_; + } + /** + * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code> + * + * <pre> + * Test case reports + * </pre> + */ + public int getTestCaseCount() { + return testCase_.size(); + } + /** + * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code> + * + * <pre> + * Test case reports + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.TestCaseReportMessage getTestCase(int index) { + return testCase_.get(index); + } + /** + * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code> + * + * <pre> + * Test case reports + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.TestCaseReportMessageOrBuilder getTestCaseOrBuilder( + int index) { + return testCase_.get(index); + } + + // repeated .android.vts.ProfilingReportMessage profiling = 21; + public static final int PROFILING_FIELD_NUMBER = 21; + private java.util.List<com.android.vts.proto.VtsReportMessage.ProfilingReportMessage> profiling_; + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code> + * + * <pre> + * Profiling reports + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.ProfilingReportMessage> getProfilingList() { + return profiling_; + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code> + * + * <pre> + * Profiling reports + * </pre> + */ + public java.util.List<? extends com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder> + getProfilingOrBuilderList() { + return profiling_; + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code> + * + * <pre> + * Profiling reports + * </pre> + */ + public int getProfilingCount() { + return profiling_.size(); + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code> + * + * <pre> + * Profiling reports + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.ProfilingReportMessage getProfiling(int index) { + return profiling_.get(index); + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code> + * + * <pre> + * Profiling reports + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder getProfilingOrBuilder( + int index) { + return profiling_.get(index); + } + + // repeated .android.vts.SystraceReportMessage systrace = 22; + public static final int SYSTRACE_FIELD_NUMBER = 22; + private java.util.List<com.android.vts.proto.VtsReportMessage.SystraceReportMessage> systrace_; + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code> + * + * <pre> + * Systrace report per file + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.SystraceReportMessage> getSystraceList() { + return systrace_; + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code> + * + * <pre> + * Systrace report per file + * </pre> + */ + public java.util.List<? extends com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder> + getSystraceOrBuilderList() { + return systrace_; + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code> + * + * <pre> + * Systrace report per file + * </pre> + */ + public int getSystraceCount() { + return systrace_.size(); + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code> + * + * <pre> + * Systrace report per file + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.SystraceReportMessage getSystrace(int index) { + return systrace_.get(index); + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code> + * + * <pre> + * Systrace report per file + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder getSystraceOrBuilder( + int index) { + return systrace_.get(index); + } + + // optional int64 start_timestamp = 101; + public static final int START_TIMESTAMP_FIELD_NUMBER = 101; + private long startTimestamp_; + /** + * <code>optional int64 start_timestamp = 101;</code> + * + * <pre> + * Execution start and end time stamp. + * </pre> + */ + public boolean hasStartTimestamp() { + return ((bitField0_ & 0x00000020) == 0x00000020); + } + /** + * <code>optional int64 start_timestamp = 101;</code> + * + * <pre> + * Execution start and end time stamp. + * </pre> + */ + public long getStartTimestamp() { + return startTimestamp_; + } + + // optional int64 end_timestamp = 102; + public static final int END_TIMESTAMP_FIELD_NUMBER = 102; + private long endTimestamp_; + /** + * <code>optional int64 end_timestamp = 102;</code> + */ + public boolean hasEndTimestamp() { + return ((bitField0_ & 0x00000040) == 0x00000040); + } + /** + * <code>optional int64 end_timestamp = 102;</code> + */ + public long getEndTimestamp() { + return endTimestamp_; + } + + // repeated .android.vts.CoverageReportMessage coverage = 103; + public static final int COVERAGE_FIELD_NUMBER = 103; + private java.util.List<com.android.vts.proto.VtsReportMessage.CoverageReportMessage> coverage_; + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code> + * + * <pre> + * Coverage report per file + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.CoverageReportMessage> getCoverageList() { + return coverage_; + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code> + * + * <pre> + * Coverage report per file + * </pre> + */ + public java.util.List<? extends com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder> + getCoverageOrBuilderList() { + return coverage_; + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code> + * + * <pre> + * Coverage report per file + * </pre> + */ + public int getCoverageCount() { + return coverage_.size(); + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code> + * + * <pre> + * Coverage report per file + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.CoverageReportMessage getCoverage(int index) { + return coverage_.get(index); + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code> + * + * <pre> + * Coverage report per file + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder getCoverageOrBuilder( + int index) { + return coverage_.get(index); + } + + // repeated .android.vts.LogMessage log = 1001; + public static final int LOG_FIELD_NUMBER = 1001; + private java.util.List<com.android.vts.proto.VtsReportMessage.LogMessage> log_; + /** + * <code>repeated .android.vts.LogMessage log = 1001;</code> + * + * <pre> + * Log for a test module. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.LogMessage> getLogList() { + return log_; + } + /** + * <code>repeated .android.vts.LogMessage log = 1001;</code> + * + * <pre> + * Log for a test module. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public java.util.List<? extends com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder> + getLogOrBuilderList() { + return log_; + } + /** + * <code>repeated .android.vts.LogMessage log = 1001;</code> + * + * <pre> + * Log for a test module. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public int getLogCount() { + return log_.size(); + } + /** + * <code>repeated .android.vts.LogMessage log = 1001;</code> + * + * <pre> + * Log for a test module. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.LogMessage getLog(int index) { + return log_.get(index); + } + /** + * <code>repeated .android.vts.LogMessage log = 1001;</code> + * + * <pre> + * Log for a test module. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder getLogOrBuilder( + int index) { + return log_.get(index); + } + + private void initFields() { + testSuite_ = com.google.protobuf.ByteString.EMPTY; + test_ = com.google.protobuf.ByteString.EMPTY; + testType_ = com.android.vts.proto.VtsReportMessage.VtsTestType.UNKNOWN_VTS_TESTTYPE; + deviceInfo_ = java.util.Collections.emptyList(); + buildInfo_ = com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.getDefaultInstance(); + subscriberEmail_ = java.util.Collections.emptyList(); + hostInfo_ = com.android.vts.proto.VtsReportMessage.VtsHostInfo.getDefaultInstance(); + testCase_ = java.util.Collections.emptyList(); + profiling_ = java.util.Collections.emptyList(); + systrace_ = java.util.Collections.emptyList(); + startTimestamp_ = 0L; + endTimestamp_ = 0L; + coverage_ = java.util.Collections.emptyList(); + log_ = java.util.Collections.emptyList(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, testSuite_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeBytes(2, test_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + output.writeEnum(3, testType_.getNumber()); + } + for (int i = 0; i < deviceInfo_.size(); i++) { + output.writeMessage(4, deviceInfo_.get(i)); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + output.writeMessage(5, buildInfo_); + } + for (int i = 0; i < subscriberEmail_.size(); i++) { + output.writeBytes(6, subscriberEmail_.get(i)); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + output.writeMessage(7, hostInfo_); + } + for (int i = 0; i < testCase_.size(); i++) { + output.writeMessage(11, testCase_.get(i)); + } + for (int i = 0; i < profiling_.size(); i++) { + output.writeMessage(21, profiling_.get(i)); + } + for (int i = 0; i < systrace_.size(); i++) { + output.writeMessage(22, systrace_.get(i)); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + output.writeInt64(101, startTimestamp_); + } + if (((bitField0_ & 0x00000040) == 0x00000040)) { + output.writeInt64(102, endTimestamp_); + } + for (int i = 0; i < coverage_.size(); i++) { + output.writeMessage(103, coverage_.get(i)); + } + for (int i = 0; i < log_.size(); i++) { + output.writeMessage(1001, log_.get(i)); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, testSuite_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(2, test_); + } + if (((bitField0_ & 0x00000004) == 0x00000004)) { + size += com.google.protobuf.CodedOutputStream + .computeEnumSize(3, testType_.getNumber()); + } + for (int i = 0; i < deviceInfo_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(4, deviceInfo_.get(i)); + } + if (((bitField0_ & 0x00000008) == 0x00000008)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(5, buildInfo_); + } + { + int dataSize = 0; + for (int i = 0; i < subscriberEmail_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeBytesSizeNoTag(subscriberEmail_.get(i)); + } + size += dataSize; + size += 1 * getSubscriberEmailList().size(); + } + if (((bitField0_ & 0x00000010) == 0x00000010)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(7, hostInfo_); + } + for (int i = 0; i < testCase_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(11, testCase_.get(i)); + } + for (int i = 0; i < profiling_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(21, profiling_.get(i)); + } + for (int i = 0; i < systrace_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(22, systrace_.get(i)); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + size += com.google.protobuf.CodedOutputStream + .computeInt64Size(101, startTimestamp_); + } + if (((bitField0_ & 0x00000040) == 0x00000040)) { + size += com.google.protobuf.CodedOutputStream + .computeInt64Size(102, endTimestamp_); + } + for (int i = 0; i < coverage_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(103, coverage_.get(i)); + } + for (int i = 0; i < log_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(1001, log_.get(i)); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static com.android.vts.proto.VtsReportMessage.TestReportMessage parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.android.vts.proto.VtsReportMessage.TestReportMessage parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.TestReportMessage parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.android.vts.proto.VtsReportMessage.TestReportMessage parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.TestReportMessage parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.TestReportMessage parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.TestReportMessage parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.TestReportMessage parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.TestReportMessage parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.TestReportMessage parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(com.android.vts.proto.VtsReportMessage.TestReportMessage prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code android.vts.TestReportMessage} + * + * <pre> + * To specify a test execution report. + * </pre> + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder<Builder> + implements com.android.vts.proto.VtsReportMessage.TestReportMessageOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_TestReportMessage_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_TestReportMessage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.android.vts.proto.VtsReportMessage.TestReportMessage.class, com.android.vts.proto.VtsReportMessage.TestReportMessage.Builder.class); + } + + // Construct using com.android.vts.proto.VtsReportMessage.TestReportMessage.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getDeviceInfoFieldBuilder(); + getBuildInfoFieldBuilder(); + getHostInfoFieldBuilder(); + getTestCaseFieldBuilder(); + getProfilingFieldBuilder(); + getSystraceFieldBuilder(); + getCoverageFieldBuilder(); + getLogFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + testSuite_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + test_ = com.google.protobuf.ByteString.EMPTY; + bitField0_ = (bitField0_ & ~0x00000002); + testType_ = com.android.vts.proto.VtsReportMessage.VtsTestType.UNKNOWN_VTS_TESTTYPE; + bitField0_ = (bitField0_ & ~0x00000004); + if (deviceInfoBuilder_ == null) { + deviceInfo_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000008); + } else { + deviceInfoBuilder_.clear(); + } + if (buildInfoBuilder_ == null) { + buildInfo_ = com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.getDefaultInstance(); + } else { + buildInfoBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000010); + subscriberEmail_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000020); + if (hostInfoBuilder_ == null) { + hostInfo_ = com.android.vts.proto.VtsReportMessage.VtsHostInfo.getDefaultInstance(); + } else { + hostInfoBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000040); + if (testCaseBuilder_ == null) { + testCase_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000080); + } else { + testCaseBuilder_.clear(); + } + if (profilingBuilder_ == null) { + profiling_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000100); + } else { + profilingBuilder_.clear(); + } + if (systraceBuilder_ == null) { + systrace_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000200); + } else { + systraceBuilder_.clear(); + } + startTimestamp_ = 0L; + bitField0_ = (bitField0_ & ~0x00000400); + endTimestamp_ = 0L; + bitField0_ = (bitField0_ & ~0x00000800); + if (coverageBuilder_ == null) { + coverage_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00001000); + } else { + coverageBuilder_.clear(); + } + if (logBuilder_ == null) { + log_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00002000); + } else { + logBuilder_.clear(); + } + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_TestReportMessage_descriptor; + } + + public com.android.vts.proto.VtsReportMessage.TestReportMessage getDefaultInstanceForType() { + return com.android.vts.proto.VtsReportMessage.TestReportMessage.getDefaultInstance(); + } + + public com.android.vts.proto.VtsReportMessage.TestReportMessage build() { + com.android.vts.proto.VtsReportMessage.TestReportMessage result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public com.android.vts.proto.VtsReportMessage.TestReportMessage buildPartial() { + com.android.vts.proto.VtsReportMessage.TestReportMessage result = new com.android.vts.proto.VtsReportMessage.TestReportMessage(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.testSuite_ = testSuite_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.test_ = test_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000004; + } + result.testType_ = testType_; + if (deviceInfoBuilder_ == null) { + if (((bitField0_ & 0x00000008) == 0x00000008)) { + deviceInfo_ = java.util.Collections.unmodifiableList(deviceInfo_); + bitField0_ = (bitField0_ & ~0x00000008); + } + result.deviceInfo_ = deviceInfo_; + } else { + result.deviceInfo_ = deviceInfoBuilder_.build(); + } + if (((from_bitField0_ & 0x00000010) == 0x00000010)) { + to_bitField0_ |= 0x00000008; + } + if (buildInfoBuilder_ == null) { + result.buildInfo_ = buildInfo_; + } else { + result.buildInfo_ = buildInfoBuilder_.build(); + } + if (((bitField0_ & 0x00000020) == 0x00000020)) { + subscriberEmail_ = java.util.Collections.unmodifiableList(subscriberEmail_); + bitField0_ = (bitField0_ & ~0x00000020); + } + result.subscriberEmail_ = subscriberEmail_; + if (((from_bitField0_ & 0x00000040) == 0x00000040)) { + to_bitField0_ |= 0x00000010; + } + if (hostInfoBuilder_ == null) { + result.hostInfo_ = hostInfo_; + } else { + result.hostInfo_ = hostInfoBuilder_.build(); + } + if (testCaseBuilder_ == null) { + if (((bitField0_ & 0x00000080) == 0x00000080)) { + testCase_ = java.util.Collections.unmodifiableList(testCase_); + bitField0_ = (bitField0_ & ~0x00000080); + } + result.testCase_ = testCase_; + } else { + result.testCase_ = testCaseBuilder_.build(); + } + if (profilingBuilder_ == null) { + if (((bitField0_ & 0x00000100) == 0x00000100)) { + profiling_ = java.util.Collections.unmodifiableList(profiling_); + bitField0_ = (bitField0_ & ~0x00000100); + } + result.profiling_ = profiling_; + } else { + result.profiling_ = profilingBuilder_.build(); + } + if (systraceBuilder_ == null) { + if (((bitField0_ & 0x00000200) == 0x00000200)) { + systrace_ = java.util.Collections.unmodifiableList(systrace_); + bitField0_ = (bitField0_ & ~0x00000200); + } + result.systrace_ = systrace_; + } else { + result.systrace_ = systraceBuilder_.build(); + } + if (((from_bitField0_ & 0x00000400) == 0x00000400)) { + to_bitField0_ |= 0x00000020; + } + result.startTimestamp_ = startTimestamp_; + if (((from_bitField0_ & 0x00000800) == 0x00000800)) { + to_bitField0_ |= 0x00000040; + } + result.endTimestamp_ = endTimestamp_; + if (coverageBuilder_ == null) { + if (((bitField0_ & 0x00001000) == 0x00001000)) { + coverage_ = java.util.Collections.unmodifiableList(coverage_); + bitField0_ = (bitField0_ & ~0x00001000); + } + result.coverage_ = coverage_; + } else { + result.coverage_ = coverageBuilder_.build(); + } + if (logBuilder_ == null) { + if (((bitField0_ & 0x00002000) == 0x00002000)) { + log_ = java.util.Collections.unmodifiableList(log_); + bitField0_ = (bitField0_ & ~0x00002000); + } + result.log_ = log_; + } else { + result.log_ = logBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.android.vts.proto.VtsReportMessage.TestReportMessage) { + return mergeFrom((com.android.vts.proto.VtsReportMessage.TestReportMessage)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.android.vts.proto.VtsReportMessage.TestReportMessage other) { + if (other == com.android.vts.proto.VtsReportMessage.TestReportMessage.getDefaultInstance()) return this; + if (other.hasTestSuite()) { + setTestSuite(other.getTestSuite()); + } + if (other.hasTest()) { + setTest(other.getTest()); + } + if (other.hasTestType()) { + setTestType(other.getTestType()); + } + if (deviceInfoBuilder_ == null) { + if (!other.deviceInfo_.isEmpty()) { + if (deviceInfo_.isEmpty()) { + deviceInfo_ = other.deviceInfo_; + bitField0_ = (bitField0_ & ~0x00000008); + } else { + ensureDeviceInfoIsMutable(); + deviceInfo_.addAll(other.deviceInfo_); + } + onChanged(); + } + } else { + if (!other.deviceInfo_.isEmpty()) { + if (deviceInfoBuilder_.isEmpty()) { + deviceInfoBuilder_.dispose(); + deviceInfoBuilder_ = null; + deviceInfo_ = other.deviceInfo_; + bitField0_ = (bitField0_ & ~0x00000008); + deviceInfoBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getDeviceInfoFieldBuilder() : null; + } else { + deviceInfoBuilder_.addAllMessages(other.deviceInfo_); + } + } + } + if (other.hasBuildInfo()) { + mergeBuildInfo(other.getBuildInfo()); + } + if (!other.subscriberEmail_.isEmpty()) { + if (subscriberEmail_.isEmpty()) { + subscriberEmail_ = other.subscriberEmail_; + bitField0_ = (bitField0_ & ~0x00000020); + } else { + ensureSubscriberEmailIsMutable(); + subscriberEmail_.addAll(other.subscriberEmail_); + } + onChanged(); + } + if (other.hasHostInfo()) { + mergeHostInfo(other.getHostInfo()); + } + if (testCaseBuilder_ == null) { + if (!other.testCase_.isEmpty()) { + if (testCase_.isEmpty()) { + testCase_ = other.testCase_; + bitField0_ = (bitField0_ & ~0x00000080); + } else { + ensureTestCaseIsMutable(); + testCase_.addAll(other.testCase_); + } + onChanged(); + } + } else { + if (!other.testCase_.isEmpty()) { + if (testCaseBuilder_.isEmpty()) { + testCaseBuilder_.dispose(); + testCaseBuilder_ = null; + testCase_ = other.testCase_; + bitField0_ = (bitField0_ & ~0x00000080); + testCaseBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getTestCaseFieldBuilder() : null; + } else { + testCaseBuilder_.addAllMessages(other.testCase_); + } + } + } + if (profilingBuilder_ == null) { + if (!other.profiling_.isEmpty()) { + if (profiling_.isEmpty()) { + profiling_ = other.profiling_; + bitField0_ = (bitField0_ & ~0x00000100); + } else { + ensureProfilingIsMutable(); + profiling_.addAll(other.profiling_); + } + onChanged(); + } + } else { + if (!other.profiling_.isEmpty()) { + if (profilingBuilder_.isEmpty()) { + profilingBuilder_.dispose(); + profilingBuilder_ = null; + profiling_ = other.profiling_; + bitField0_ = (bitField0_ & ~0x00000100); + profilingBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getProfilingFieldBuilder() : null; + } else { + profilingBuilder_.addAllMessages(other.profiling_); + } + } + } + if (systraceBuilder_ == null) { + if (!other.systrace_.isEmpty()) { + if (systrace_.isEmpty()) { + systrace_ = other.systrace_; + bitField0_ = (bitField0_ & ~0x00000200); + } else { + ensureSystraceIsMutable(); + systrace_.addAll(other.systrace_); + } + onChanged(); + } + } else { + if (!other.systrace_.isEmpty()) { + if (systraceBuilder_.isEmpty()) { + systraceBuilder_.dispose(); + systraceBuilder_ = null; + systrace_ = other.systrace_; + bitField0_ = (bitField0_ & ~0x00000200); + systraceBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getSystraceFieldBuilder() : null; + } else { + systraceBuilder_.addAllMessages(other.systrace_); + } + } + } + if (other.hasStartTimestamp()) { + setStartTimestamp(other.getStartTimestamp()); + } + if (other.hasEndTimestamp()) { + setEndTimestamp(other.getEndTimestamp()); + } + if (coverageBuilder_ == null) { + if (!other.coverage_.isEmpty()) { + if (coverage_.isEmpty()) { + coverage_ = other.coverage_; + bitField0_ = (bitField0_ & ~0x00001000); + } else { + ensureCoverageIsMutable(); + coverage_.addAll(other.coverage_); + } + onChanged(); + } + } else { + if (!other.coverage_.isEmpty()) { + if (coverageBuilder_.isEmpty()) { + coverageBuilder_.dispose(); + coverageBuilder_ = null; + coverage_ = other.coverage_; + bitField0_ = (bitField0_ & ~0x00001000); + coverageBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getCoverageFieldBuilder() : null; + } else { + coverageBuilder_.addAllMessages(other.coverage_); + } + } + } + if (logBuilder_ == null) { + if (!other.log_.isEmpty()) { + if (log_.isEmpty()) { + log_ = other.log_; + bitField0_ = (bitField0_ & ~0x00002000); + } else { + ensureLogIsMutable(); + log_.addAll(other.log_); + } + onChanged(); + } + } else { + if (!other.log_.isEmpty()) { + if (logBuilder_.isEmpty()) { + logBuilder_.dispose(); + logBuilder_ = null; + log_ = other.log_; + bitField0_ = (bitField0_ & ~0x00002000); + logBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getLogFieldBuilder() : null; + } else { + logBuilder_.addAllMessages(other.log_); + } + } + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + com.android.vts.proto.VtsReportMessage.TestReportMessage parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (com.android.vts.proto.VtsReportMessage.TestReportMessage) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // optional bytes test_suite = 1 [deprecated = true]; + private com.google.protobuf.ByteString testSuite_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes test_suite = 1 [deprecated = true];</code> + * + * <pre> + * The test suite name.. + * </pre> + */ + @java.lang.Deprecated public boolean hasTestSuite() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * <code>optional bytes test_suite = 1 [deprecated = true];</code> + * + * <pre> + * The test suite name.. + * </pre> + */ + @java.lang.Deprecated public com.google.protobuf.ByteString getTestSuite() { + return testSuite_; + } + /** + * <code>optional bytes test_suite = 1 [deprecated = true];</code> + * + * <pre> + * The test suite name.. + * </pre> + */ + @java.lang.Deprecated public Builder setTestSuite(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + testSuite_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes test_suite = 1 [deprecated = true];</code> + * + * <pre> + * The test suite name.. + * </pre> + */ + @java.lang.Deprecated public Builder clearTestSuite() { + bitField0_ = (bitField0_ & ~0x00000001); + testSuite_ = getDefaultInstance().getTestSuite(); + onChanged(); + return this; + } + + // optional bytes test = 2; + private com.google.protobuf.ByteString test_ = com.google.protobuf.ByteString.EMPTY; + /** + * <code>optional bytes test = 2;</code> + * + * <pre> + * The test name. + * </pre> + */ + public boolean hasTest() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * <code>optional bytes test = 2;</code> + * + * <pre> + * The test name. + * </pre> + */ + public com.google.protobuf.ByteString getTest() { + return test_; + } + /** + * <code>optional bytes test = 2;</code> + * + * <pre> + * The test name. + * </pre> + */ + public Builder setTest(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000002; + test_ = value; + onChanged(); + return this; + } + /** + * <code>optional bytes test = 2;</code> + * + * <pre> + * The test name. + * </pre> + */ + public Builder clearTest() { + bitField0_ = (bitField0_ & ~0x00000002); + test_ = getDefaultInstance().getTest(); + onChanged(); + return this; + } + + // optional .android.vts.VtsTestType test_type = 3; + private com.android.vts.proto.VtsReportMessage.VtsTestType testType_ = com.android.vts.proto.VtsReportMessage.VtsTestType.UNKNOWN_VTS_TESTTYPE; + /** + * <code>optional .android.vts.VtsTestType test_type = 3;</code> + * + * <pre> + * The test type + * </pre> + */ + public boolean hasTestType() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * <code>optional .android.vts.VtsTestType test_type = 3;</code> + * + * <pre> + * The test type + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.VtsTestType getTestType() { + return testType_; + } + /** + * <code>optional .android.vts.VtsTestType test_type = 3;</code> + * + * <pre> + * The test type + * </pre> + */ + public Builder setTestType(com.android.vts.proto.VtsReportMessage.VtsTestType value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + testType_ = value; + onChanged(); + return this; + } + /** + * <code>optional .android.vts.VtsTestType test_type = 3;</code> + * + * <pre> + * The test type + * </pre> + */ + public Builder clearTestType() { + bitField0_ = (bitField0_ & ~0x00000004); + testType_ = com.android.vts.proto.VtsReportMessage.VtsTestType.UNKNOWN_VTS_TESTTYPE; + onChanged(); + return this; + } + + // repeated .android.vts.AndroidDeviceInfoMessage device_info = 4; + private java.util.List<com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage> deviceInfo_ = + java.util.Collections.emptyList(); + private void ensureDeviceInfoIsMutable() { + if (!((bitField0_ & 0x00000008) == 0x00000008)) { + deviceInfo_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage>(deviceInfo_); + bitField0_ |= 0x00000008; + } + } + + private com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage, com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.Builder, com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessageOrBuilder> deviceInfoBuilder_; + + /** + * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code> + * + * <pre> + * Target device info + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage> getDeviceInfoList() { + if (deviceInfoBuilder_ == null) { + return java.util.Collections.unmodifiableList(deviceInfo_); + } else { + return deviceInfoBuilder_.getMessageList(); + } + } + /** + * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code> + * + * <pre> + * Target device info + * </pre> + */ + public int getDeviceInfoCount() { + if (deviceInfoBuilder_ == null) { + return deviceInfo_.size(); + } else { + return deviceInfoBuilder_.getCount(); + } + } + /** + * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code> + * + * <pre> + * Target device info + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage getDeviceInfo(int index) { + if (deviceInfoBuilder_ == null) { + return deviceInfo_.get(index); + } else { + return deviceInfoBuilder_.getMessage(index); + } + } + /** + * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code> + * + * <pre> + * Target device info + * </pre> + */ + public Builder setDeviceInfo( + int index, com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage value) { + if (deviceInfoBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureDeviceInfoIsMutable(); + deviceInfo_.set(index, value); + onChanged(); + } else { + deviceInfoBuilder_.setMessage(index, value); + } + return this; + } + /** + * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code> + * + * <pre> + * Target device info + * </pre> + */ + public Builder setDeviceInfo( + int index, com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.Builder builderForValue) { + if (deviceInfoBuilder_ == null) { + ensureDeviceInfoIsMutable(); + deviceInfo_.set(index, builderForValue.build()); + onChanged(); + } else { + deviceInfoBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code> + * + * <pre> + * Target device info + * </pre> + */ + public Builder addDeviceInfo(com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage value) { + if (deviceInfoBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureDeviceInfoIsMutable(); + deviceInfo_.add(value); + onChanged(); + } else { + deviceInfoBuilder_.addMessage(value); + } + return this; + } + /** + * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code> + * + * <pre> + * Target device info + * </pre> + */ + public Builder addDeviceInfo( + int index, com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage value) { + if (deviceInfoBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureDeviceInfoIsMutable(); + deviceInfo_.add(index, value); + onChanged(); + } else { + deviceInfoBuilder_.addMessage(index, value); + } + return this; + } + /** + * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code> + * + * <pre> + * Target device info + * </pre> + */ + public Builder addDeviceInfo( + com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.Builder builderForValue) { + if (deviceInfoBuilder_ == null) { + ensureDeviceInfoIsMutable(); + deviceInfo_.add(builderForValue.build()); + onChanged(); + } else { + deviceInfoBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code> + * + * <pre> + * Target device info + * </pre> + */ + public Builder addDeviceInfo( + int index, com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.Builder builderForValue) { + if (deviceInfoBuilder_ == null) { + ensureDeviceInfoIsMutable(); + deviceInfo_.add(index, builderForValue.build()); + onChanged(); + } else { + deviceInfoBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code> + * + * <pre> + * Target device info + * </pre> + */ + public Builder addAllDeviceInfo( + java.lang.Iterable<? extends com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage> values) { + if (deviceInfoBuilder_ == null) { + ensureDeviceInfoIsMutable(); + super.addAll(values, deviceInfo_); + onChanged(); + } else { + deviceInfoBuilder_.addAllMessages(values); + } + return this; + } + /** + * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code> + * + * <pre> + * Target device info + * </pre> + */ + public Builder clearDeviceInfo() { + if (deviceInfoBuilder_ == null) { + deviceInfo_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000008); + onChanged(); + } else { + deviceInfoBuilder_.clear(); + } + return this; + } + /** + * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code> + * + * <pre> + * Target device info + * </pre> + */ + public Builder removeDeviceInfo(int index) { + if (deviceInfoBuilder_ == null) { + ensureDeviceInfoIsMutable(); + deviceInfo_.remove(index); + onChanged(); + } else { + deviceInfoBuilder_.remove(index); + } + return this; + } + /** + * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code> + * + * <pre> + * Target device info + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.Builder getDeviceInfoBuilder( + int index) { + return getDeviceInfoFieldBuilder().getBuilder(index); + } + /** + * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code> + * + * <pre> + * Target device info + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessageOrBuilder getDeviceInfoOrBuilder( + int index) { + if (deviceInfoBuilder_ == null) { + return deviceInfo_.get(index); } else { + return deviceInfoBuilder_.getMessageOrBuilder(index); + } + } + /** + * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code> + * + * <pre> + * Target device info + * </pre> + */ + public java.util.List<? extends com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessageOrBuilder> + getDeviceInfoOrBuilderList() { + if (deviceInfoBuilder_ != null) { + return deviceInfoBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(deviceInfo_); + } + } + /** + * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code> + * + * <pre> + * Target device info + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.Builder addDeviceInfoBuilder() { + return getDeviceInfoFieldBuilder().addBuilder( + com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.getDefaultInstance()); + } + /** + * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code> + * + * <pre> + * Target device info + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.Builder addDeviceInfoBuilder( + int index) { + return getDeviceInfoFieldBuilder().addBuilder( + index, com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.getDefaultInstance()); + } + /** + * <code>repeated .android.vts.AndroidDeviceInfoMessage device_info = 4;</code> + * + * <pre> + * Target device info + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.Builder> + getDeviceInfoBuilderList() { + return getDeviceInfoFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage, com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.Builder, com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessageOrBuilder> + getDeviceInfoFieldBuilder() { + if (deviceInfoBuilder_ == null) { + deviceInfoBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage, com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage.Builder, com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessageOrBuilder>( + deviceInfo_, + ((bitField0_ & 0x00000008) == 0x00000008), + getParentForChildren(), + isClean()); + deviceInfo_ = null; + } + return deviceInfoBuilder_; + } + + // optional .android.vts.AndroidBuildInfo build_info = 5; + private com.android.vts.proto.VtsReportMessage.AndroidBuildInfo buildInfo_ = com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + com.android.vts.proto.VtsReportMessage.AndroidBuildInfo, com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.Builder, com.android.vts.proto.VtsReportMessage.AndroidBuildInfoOrBuilder> buildInfoBuilder_; + /** + * <code>optional .android.vts.AndroidBuildInfo build_info = 5;</code> + * + * <pre> + * Build info + * </pre> + */ + public boolean hasBuildInfo() { + return ((bitField0_ & 0x00000010) == 0x00000010); + } + /** + * <code>optional .android.vts.AndroidBuildInfo build_info = 5;</code> + * + * <pre> + * Build info + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.AndroidBuildInfo getBuildInfo() { + if (buildInfoBuilder_ == null) { + return buildInfo_; + } else { + return buildInfoBuilder_.getMessage(); + } + } + /** + * <code>optional .android.vts.AndroidBuildInfo build_info = 5;</code> + * + * <pre> + * Build info + * </pre> + */ + public Builder setBuildInfo(com.android.vts.proto.VtsReportMessage.AndroidBuildInfo value) { + if (buildInfoBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + buildInfo_ = value; + onChanged(); + } else { + buildInfoBuilder_.setMessage(value); + } + bitField0_ |= 0x00000010; + return this; + } + /** + * <code>optional .android.vts.AndroidBuildInfo build_info = 5;</code> + * + * <pre> + * Build info + * </pre> + */ + public Builder setBuildInfo( + com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.Builder builderForValue) { + if (buildInfoBuilder_ == null) { + buildInfo_ = builderForValue.build(); + onChanged(); + } else { + buildInfoBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000010; + return this; + } + /** + * <code>optional .android.vts.AndroidBuildInfo build_info = 5;</code> + * + * <pre> + * Build info + * </pre> + */ + public Builder mergeBuildInfo(com.android.vts.proto.VtsReportMessage.AndroidBuildInfo value) { + if (buildInfoBuilder_ == null) { + if (((bitField0_ & 0x00000010) == 0x00000010) && + buildInfo_ != com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.getDefaultInstance()) { + buildInfo_ = + com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.newBuilder(buildInfo_).mergeFrom(value).buildPartial(); + } else { + buildInfo_ = value; + } + onChanged(); + } else { + buildInfoBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000010; + return this; + } + /** + * <code>optional .android.vts.AndroidBuildInfo build_info = 5;</code> + * + * <pre> + * Build info + * </pre> + */ + public Builder clearBuildInfo() { + if (buildInfoBuilder_ == null) { + buildInfo_ = com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.getDefaultInstance(); + onChanged(); + } else { + buildInfoBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000010); + return this; + } + /** + * <code>optional .android.vts.AndroidBuildInfo build_info = 5;</code> + * + * <pre> + * Build info + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.Builder getBuildInfoBuilder() { + bitField0_ |= 0x00000010; + onChanged(); + return getBuildInfoFieldBuilder().getBuilder(); + } + /** + * <code>optional .android.vts.AndroidBuildInfo build_info = 5;</code> + * + * <pre> + * Build info + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.AndroidBuildInfoOrBuilder getBuildInfoOrBuilder() { + if (buildInfoBuilder_ != null) { + return buildInfoBuilder_.getMessageOrBuilder(); + } else { + return buildInfo_; + } + } + /** + * <code>optional .android.vts.AndroidBuildInfo build_info = 5;</code> + * + * <pre> + * Build info + * </pre> + */ + private com.google.protobuf.SingleFieldBuilder< + com.android.vts.proto.VtsReportMessage.AndroidBuildInfo, com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.Builder, com.android.vts.proto.VtsReportMessage.AndroidBuildInfoOrBuilder> + getBuildInfoFieldBuilder() { + if (buildInfoBuilder_ == null) { + buildInfoBuilder_ = new com.google.protobuf.SingleFieldBuilder< + com.android.vts.proto.VtsReportMessage.AndroidBuildInfo, com.android.vts.proto.VtsReportMessage.AndroidBuildInfo.Builder, com.android.vts.proto.VtsReportMessage.AndroidBuildInfoOrBuilder>( + buildInfo_, + getParentForChildren(), + isClean()); + buildInfo_ = null; + } + return buildInfoBuilder_; + } + + // repeated bytes subscriber_email = 6; + private java.util.List<com.google.protobuf.ByteString> subscriberEmail_ = java.util.Collections.emptyList(); + private void ensureSubscriberEmailIsMutable() { + if (!((bitField0_ & 0x00000020) == 0x00000020)) { + subscriberEmail_ = new java.util.ArrayList<com.google.protobuf.ByteString>(subscriberEmail_); + bitField0_ |= 0x00000020; + } + } + /** + * <code>repeated bytes subscriber_email = 6;</code> + * + * <pre> + * Email addresses of subscribers to the test results + * </pre> + */ + public java.util.List<com.google.protobuf.ByteString> + getSubscriberEmailList() { + return java.util.Collections.unmodifiableList(subscriberEmail_); + } + /** + * <code>repeated bytes subscriber_email = 6;</code> + * + * <pre> + * Email addresses of subscribers to the test results + * </pre> + */ + public int getSubscriberEmailCount() { + return subscriberEmail_.size(); + } + /** + * <code>repeated bytes subscriber_email = 6;</code> + * + * <pre> + * Email addresses of subscribers to the test results + * </pre> + */ + public com.google.protobuf.ByteString getSubscriberEmail(int index) { + return subscriberEmail_.get(index); + } + /** + * <code>repeated bytes subscriber_email = 6;</code> + * + * <pre> + * Email addresses of subscribers to the test results + * </pre> + */ + public Builder setSubscriberEmail( + int index, com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureSubscriberEmailIsMutable(); + subscriberEmail_.set(index, value); + onChanged(); + return this; + } + /** + * <code>repeated bytes subscriber_email = 6;</code> + * + * <pre> + * Email addresses of subscribers to the test results + * </pre> + */ + public Builder addSubscriberEmail(com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureSubscriberEmailIsMutable(); + subscriberEmail_.add(value); + onChanged(); + return this; + } + /** + * <code>repeated bytes subscriber_email = 6;</code> + * + * <pre> + * Email addresses of subscribers to the test results + * </pre> + */ + public Builder addAllSubscriberEmail( + java.lang.Iterable<? extends com.google.protobuf.ByteString> values) { + ensureSubscriberEmailIsMutable(); + super.addAll(values, subscriberEmail_); + onChanged(); + return this; + } + /** + * <code>repeated bytes subscriber_email = 6;</code> + * + * <pre> + * Email addresses of subscribers to the test results + * </pre> + */ + public Builder clearSubscriberEmail() { + subscriberEmail_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000020); + onChanged(); + return this; + } + + // optional .android.vts.VtsHostInfo host_info = 7; + private com.android.vts.proto.VtsReportMessage.VtsHostInfo hostInfo_ = com.android.vts.proto.VtsReportMessage.VtsHostInfo.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + com.android.vts.proto.VtsReportMessage.VtsHostInfo, com.android.vts.proto.VtsReportMessage.VtsHostInfo.Builder, com.android.vts.proto.VtsReportMessage.VtsHostInfoOrBuilder> hostInfoBuilder_; + /** + * <code>optional .android.vts.VtsHostInfo host_info = 7;</code> + * + * <pre> + * Info about the host computer + * </pre> + */ + public boolean hasHostInfo() { + return ((bitField0_ & 0x00000040) == 0x00000040); + } + /** + * <code>optional .android.vts.VtsHostInfo host_info = 7;</code> + * + * <pre> + * Info about the host computer + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.VtsHostInfo getHostInfo() { + if (hostInfoBuilder_ == null) { + return hostInfo_; + } else { + return hostInfoBuilder_.getMessage(); + } + } + /** + * <code>optional .android.vts.VtsHostInfo host_info = 7;</code> + * + * <pre> + * Info about the host computer + * </pre> + */ + public Builder setHostInfo(com.android.vts.proto.VtsReportMessage.VtsHostInfo value) { + if (hostInfoBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + hostInfo_ = value; + onChanged(); + } else { + hostInfoBuilder_.setMessage(value); + } + bitField0_ |= 0x00000040; + return this; + } + /** + * <code>optional .android.vts.VtsHostInfo host_info = 7;</code> + * + * <pre> + * Info about the host computer + * </pre> + */ + public Builder setHostInfo( + com.android.vts.proto.VtsReportMessage.VtsHostInfo.Builder builderForValue) { + if (hostInfoBuilder_ == null) { + hostInfo_ = builderForValue.build(); + onChanged(); + } else { + hostInfoBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000040; + return this; + } + /** + * <code>optional .android.vts.VtsHostInfo host_info = 7;</code> + * + * <pre> + * Info about the host computer + * </pre> + */ + public Builder mergeHostInfo(com.android.vts.proto.VtsReportMessage.VtsHostInfo value) { + if (hostInfoBuilder_ == null) { + if (((bitField0_ & 0x00000040) == 0x00000040) && + hostInfo_ != com.android.vts.proto.VtsReportMessage.VtsHostInfo.getDefaultInstance()) { + hostInfo_ = + com.android.vts.proto.VtsReportMessage.VtsHostInfo.newBuilder(hostInfo_).mergeFrom(value).buildPartial(); + } else { + hostInfo_ = value; + } + onChanged(); + } else { + hostInfoBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000040; + return this; + } + /** + * <code>optional .android.vts.VtsHostInfo host_info = 7;</code> + * + * <pre> + * Info about the host computer + * </pre> + */ + public Builder clearHostInfo() { + if (hostInfoBuilder_ == null) { + hostInfo_ = com.android.vts.proto.VtsReportMessage.VtsHostInfo.getDefaultInstance(); + onChanged(); + } else { + hostInfoBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000040); + return this; + } + /** + * <code>optional .android.vts.VtsHostInfo host_info = 7;</code> + * + * <pre> + * Info about the host computer + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.VtsHostInfo.Builder getHostInfoBuilder() { + bitField0_ |= 0x00000040; + onChanged(); + return getHostInfoFieldBuilder().getBuilder(); + } + /** + * <code>optional .android.vts.VtsHostInfo host_info = 7;</code> + * + * <pre> + * Info about the host computer + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.VtsHostInfoOrBuilder getHostInfoOrBuilder() { + if (hostInfoBuilder_ != null) { + return hostInfoBuilder_.getMessageOrBuilder(); + } else { + return hostInfo_; + } + } + /** + * <code>optional .android.vts.VtsHostInfo host_info = 7;</code> + * + * <pre> + * Info about the host computer + * </pre> + */ + private com.google.protobuf.SingleFieldBuilder< + com.android.vts.proto.VtsReportMessage.VtsHostInfo, com.android.vts.proto.VtsReportMessage.VtsHostInfo.Builder, com.android.vts.proto.VtsReportMessage.VtsHostInfoOrBuilder> + getHostInfoFieldBuilder() { + if (hostInfoBuilder_ == null) { + hostInfoBuilder_ = new com.google.protobuf.SingleFieldBuilder< + com.android.vts.proto.VtsReportMessage.VtsHostInfo, com.android.vts.proto.VtsReportMessage.VtsHostInfo.Builder, com.android.vts.proto.VtsReportMessage.VtsHostInfoOrBuilder>( + hostInfo_, + getParentForChildren(), + isClean()); + hostInfo_ = null; + } + return hostInfoBuilder_; + } + + // repeated .android.vts.TestCaseReportMessage test_case = 11; + private java.util.List<com.android.vts.proto.VtsReportMessage.TestCaseReportMessage> testCase_ = + java.util.Collections.emptyList(); + private void ensureTestCaseIsMutable() { + if (!((bitField0_ & 0x00000080) == 0x00000080)) { + testCase_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.TestCaseReportMessage>(testCase_); + bitField0_ |= 0x00000080; + } + } + + private com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.TestCaseReportMessage, com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.Builder, com.android.vts.proto.VtsReportMessage.TestCaseReportMessageOrBuilder> testCaseBuilder_; + + /** + * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code> + * + * <pre> + * Test case reports + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.TestCaseReportMessage> getTestCaseList() { + if (testCaseBuilder_ == null) { + return java.util.Collections.unmodifiableList(testCase_); + } else { + return testCaseBuilder_.getMessageList(); + } + } + /** + * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code> + * + * <pre> + * Test case reports + * </pre> + */ + public int getTestCaseCount() { + if (testCaseBuilder_ == null) { + return testCase_.size(); + } else { + return testCaseBuilder_.getCount(); + } + } + /** + * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code> + * + * <pre> + * Test case reports + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.TestCaseReportMessage getTestCase(int index) { + if (testCaseBuilder_ == null) { + return testCase_.get(index); + } else { + return testCaseBuilder_.getMessage(index); + } + } + /** + * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code> + * + * <pre> + * Test case reports + * </pre> + */ + public Builder setTestCase( + int index, com.android.vts.proto.VtsReportMessage.TestCaseReportMessage value) { + if (testCaseBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureTestCaseIsMutable(); + testCase_.set(index, value); + onChanged(); + } else { + testCaseBuilder_.setMessage(index, value); + } + return this; + } + /** + * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code> + * + * <pre> + * Test case reports + * </pre> + */ + public Builder setTestCase( + int index, com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.Builder builderForValue) { + if (testCaseBuilder_ == null) { + ensureTestCaseIsMutable(); + testCase_.set(index, builderForValue.build()); + onChanged(); + } else { + testCaseBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code> + * + * <pre> + * Test case reports + * </pre> + */ + public Builder addTestCase(com.android.vts.proto.VtsReportMessage.TestCaseReportMessage value) { + if (testCaseBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureTestCaseIsMutable(); + testCase_.add(value); + onChanged(); + } else { + testCaseBuilder_.addMessage(value); + } + return this; + } + /** + * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code> + * + * <pre> + * Test case reports + * </pre> + */ + public Builder addTestCase( + int index, com.android.vts.proto.VtsReportMessage.TestCaseReportMessage value) { + if (testCaseBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureTestCaseIsMutable(); + testCase_.add(index, value); + onChanged(); + } else { + testCaseBuilder_.addMessage(index, value); + } + return this; + } + /** + * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code> + * + * <pre> + * Test case reports + * </pre> + */ + public Builder addTestCase( + com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.Builder builderForValue) { + if (testCaseBuilder_ == null) { + ensureTestCaseIsMutable(); + testCase_.add(builderForValue.build()); + onChanged(); + } else { + testCaseBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code> + * + * <pre> + * Test case reports + * </pre> + */ + public Builder addTestCase( + int index, com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.Builder builderForValue) { + if (testCaseBuilder_ == null) { + ensureTestCaseIsMutable(); + testCase_.add(index, builderForValue.build()); + onChanged(); + } else { + testCaseBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code> + * + * <pre> + * Test case reports + * </pre> + */ + public Builder addAllTestCase( + java.lang.Iterable<? extends com.android.vts.proto.VtsReportMessage.TestCaseReportMessage> values) { + if (testCaseBuilder_ == null) { + ensureTestCaseIsMutable(); + super.addAll(values, testCase_); + onChanged(); + } else { + testCaseBuilder_.addAllMessages(values); + } + return this; + } + /** + * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code> + * + * <pre> + * Test case reports + * </pre> + */ + public Builder clearTestCase() { + if (testCaseBuilder_ == null) { + testCase_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000080); + onChanged(); + } else { + testCaseBuilder_.clear(); + } + return this; + } + /** + * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code> + * + * <pre> + * Test case reports + * </pre> + */ + public Builder removeTestCase(int index) { + if (testCaseBuilder_ == null) { + ensureTestCaseIsMutable(); + testCase_.remove(index); + onChanged(); + } else { + testCaseBuilder_.remove(index); + } + return this; + } + /** + * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code> + * + * <pre> + * Test case reports + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.Builder getTestCaseBuilder( + int index) { + return getTestCaseFieldBuilder().getBuilder(index); + } + /** + * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code> + * + * <pre> + * Test case reports + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.TestCaseReportMessageOrBuilder getTestCaseOrBuilder( + int index) { + if (testCaseBuilder_ == null) { + return testCase_.get(index); } else { + return testCaseBuilder_.getMessageOrBuilder(index); + } + } + /** + * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code> + * + * <pre> + * Test case reports + * </pre> + */ + public java.util.List<? extends com.android.vts.proto.VtsReportMessage.TestCaseReportMessageOrBuilder> + getTestCaseOrBuilderList() { + if (testCaseBuilder_ != null) { + return testCaseBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(testCase_); + } + } + /** + * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code> + * + * <pre> + * Test case reports + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.Builder addTestCaseBuilder() { + return getTestCaseFieldBuilder().addBuilder( + com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.getDefaultInstance()); + } + /** + * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code> + * + * <pre> + * Test case reports + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.Builder addTestCaseBuilder( + int index) { + return getTestCaseFieldBuilder().addBuilder( + index, com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.getDefaultInstance()); + } + /** + * <code>repeated .android.vts.TestCaseReportMessage test_case = 11;</code> + * + * <pre> + * Test case reports + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.Builder> + getTestCaseBuilderList() { + return getTestCaseFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.TestCaseReportMessage, com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.Builder, com.android.vts.proto.VtsReportMessage.TestCaseReportMessageOrBuilder> + getTestCaseFieldBuilder() { + if (testCaseBuilder_ == null) { + testCaseBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.TestCaseReportMessage, com.android.vts.proto.VtsReportMessage.TestCaseReportMessage.Builder, com.android.vts.proto.VtsReportMessage.TestCaseReportMessageOrBuilder>( + testCase_, + ((bitField0_ & 0x00000080) == 0x00000080), + getParentForChildren(), + isClean()); + testCase_ = null; + } + return testCaseBuilder_; + } + + // repeated .android.vts.ProfilingReportMessage profiling = 21; + private java.util.List<com.android.vts.proto.VtsReportMessage.ProfilingReportMessage> profiling_ = + java.util.Collections.emptyList(); + private void ensureProfilingIsMutable() { + if (!((bitField0_ & 0x00000100) == 0x00000100)) { + profiling_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.ProfilingReportMessage>(profiling_); + bitField0_ |= 0x00000100; + } + } + + private com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.ProfilingReportMessage, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder, com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder> profilingBuilder_; + + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code> + * + * <pre> + * Profiling reports + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.ProfilingReportMessage> getProfilingList() { + if (profilingBuilder_ == null) { + return java.util.Collections.unmodifiableList(profiling_); + } else { + return profilingBuilder_.getMessageList(); + } + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code> + * + * <pre> + * Profiling reports + * </pre> + */ + public int getProfilingCount() { + if (profilingBuilder_ == null) { + return profiling_.size(); + } else { + return profilingBuilder_.getCount(); + } + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code> + * + * <pre> + * Profiling reports + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.ProfilingReportMessage getProfiling(int index) { + if (profilingBuilder_ == null) { + return profiling_.get(index); + } else { + return profilingBuilder_.getMessage(index); + } + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code> + * + * <pre> + * Profiling reports + * </pre> + */ + public Builder setProfiling( + int index, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage value) { + if (profilingBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureProfilingIsMutable(); + profiling_.set(index, value); + onChanged(); + } else { + profilingBuilder_.setMessage(index, value); + } + return this; + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code> + * + * <pre> + * Profiling reports + * </pre> + */ + public Builder setProfiling( + int index, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder builderForValue) { + if (profilingBuilder_ == null) { + ensureProfilingIsMutable(); + profiling_.set(index, builderForValue.build()); + onChanged(); + } else { + profilingBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code> + * + * <pre> + * Profiling reports + * </pre> + */ + public Builder addProfiling(com.android.vts.proto.VtsReportMessage.ProfilingReportMessage value) { + if (profilingBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureProfilingIsMutable(); + profiling_.add(value); + onChanged(); + } else { + profilingBuilder_.addMessage(value); + } + return this; + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code> + * + * <pre> + * Profiling reports + * </pre> + */ + public Builder addProfiling( + int index, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage value) { + if (profilingBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureProfilingIsMutable(); + profiling_.add(index, value); + onChanged(); + } else { + profilingBuilder_.addMessage(index, value); + } + return this; + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code> + * + * <pre> + * Profiling reports + * </pre> + */ + public Builder addProfiling( + com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder builderForValue) { + if (profilingBuilder_ == null) { + ensureProfilingIsMutable(); + profiling_.add(builderForValue.build()); + onChanged(); + } else { + profilingBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code> + * + * <pre> + * Profiling reports + * </pre> + */ + public Builder addProfiling( + int index, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder builderForValue) { + if (profilingBuilder_ == null) { + ensureProfilingIsMutable(); + profiling_.add(index, builderForValue.build()); + onChanged(); + } else { + profilingBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code> + * + * <pre> + * Profiling reports + * </pre> + */ + public Builder addAllProfiling( + java.lang.Iterable<? extends com.android.vts.proto.VtsReportMessage.ProfilingReportMessage> values) { + if (profilingBuilder_ == null) { + ensureProfilingIsMutable(); + super.addAll(values, profiling_); + onChanged(); + } else { + profilingBuilder_.addAllMessages(values); + } + return this; + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code> + * + * <pre> + * Profiling reports + * </pre> + */ + public Builder clearProfiling() { + if (profilingBuilder_ == null) { + profiling_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000100); + onChanged(); + } else { + profilingBuilder_.clear(); + } + return this; + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code> + * + * <pre> + * Profiling reports + * </pre> + */ + public Builder removeProfiling(int index) { + if (profilingBuilder_ == null) { + ensureProfilingIsMutable(); + profiling_.remove(index); + onChanged(); + } else { + profilingBuilder_.remove(index); + } + return this; + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code> + * + * <pre> + * Profiling reports + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder getProfilingBuilder( + int index) { + return getProfilingFieldBuilder().getBuilder(index); + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code> + * + * <pre> + * Profiling reports + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder getProfilingOrBuilder( + int index) { + if (profilingBuilder_ == null) { + return profiling_.get(index); } else { + return profilingBuilder_.getMessageOrBuilder(index); + } + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code> + * + * <pre> + * Profiling reports + * </pre> + */ + public java.util.List<? extends com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder> + getProfilingOrBuilderList() { + if (profilingBuilder_ != null) { + return profilingBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(profiling_); + } + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code> + * + * <pre> + * Profiling reports + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder addProfilingBuilder() { + return getProfilingFieldBuilder().addBuilder( + com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.getDefaultInstance()); + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code> + * + * <pre> + * Profiling reports + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder addProfilingBuilder( + int index) { + return getProfilingFieldBuilder().addBuilder( + index, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.getDefaultInstance()); + } + /** + * <code>repeated .android.vts.ProfilingReportMessage profiling = 21;</code> + * + * <pre> + * Profiling reports + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder> + getProfilingBuilderList() { + return getProfilingFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.ProfilingReportMessage, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder, com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder> + getProfilingFieldBuilder() { + if (profilingBuilder_ == null) { + profilingBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.ProfilingReportMessage, com.android.vts.proto.VtsReportMessage.ProfilingReportMessage.Builder, com.android.vts.proto.VtsReportMessage.ProfilingReportMessageOrBuilder>( + profiling_, + ((bitField0_ & 0x00000100) == 0x00000100), + getParentForChildren(), + isClean()); + profiling_ = null; + } + return profilingBuilder_; + } + + // repeated .android.vts.SystraceReportMessage systrace = 22; + private java.util.List<com.android.vts.proto.VtsReportMessage.SystraceReportMessage> systrace_ = + java.util.Collections.emptyList(); + private void ensureSystraceIsMutable() { + if (!((bitField0_ & 0x00000200) == 0x00000200)) { + systrace_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.SystraceReportMessage>(systrace_); + bitField0_ |= 0x00000200; + } + } + + private com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.SystraceReportMessage, com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder, com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder> systraceBuilder_; + + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code> + * + * <pre> + * Systrace report per file + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.SystraceReportMessage> getSystraceList() { + if (systraceBuilder_ == null) { + return java.util.Collections.unmodifiableList(systrace_); + } else { + return systraceBuilder_.getMessageList(); + } + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code> + * + * <pre> + * Systrace report per file + * </pre> + */ + public int getSystraceCount() { + if (systraceBuilder_ == null) { + return systrace_.size(); + } else { + return systraceBuilder_.getCount(); + } + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code> + * + * <pre> + * Systrace report per file + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.SystraceReportMessage getSystrace(int index) { + if (systraceBuilder_ == null) { + return systrace_.get(index); + } else { + return systraceBuilder_.getMessage(index); + } + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code> + * + * <pre> + * Systrace report per file + * </pre> + */ + public Builder setSystrace( + int index, com.android.vts.proto.VtsReportMessage.SystraceReportMessage value) { + if (systraceBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureSystraceIsMutable(); + systrace_.set(index, value); + onChanged(); + } else { + systraceBuilder_.setMessage(index, value); + } + return this; + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code> + * + * <pre> + * Systrace report per file + * </pre> + */ + public Builder setSystrace( + int index, com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder builderForValue) { + if (systraceBuilder_ == null) { + ensureSystraceIsMutable(); + systrace_.set(index, builderForValue.build()); + onChanged(); + } else { + systraceBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code> + * + * <pre> + * Systrace report per file + * </pre> + */ + public Builder addSystrace(com.android.vts.proto.VtsReportMessage.SystraceReportMessage value) { + if (systraceBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureSystraceIsMutable(); + systrace_.add(value); + onChanged(); + } else { + systraceBuilder_.addMessage(value); + } + return this; + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code> + * + * <pre> + * Systrace report per file + * </pre> + */ + public Builder addSystrace( + int index, com.android.vts.proto.VtsReportMessage.SystraceReportMessage value) { + if (systraceBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureSystraceIsMutable(); + systrace_.add(index, value); + onChanged(); + } else { + systraceBuilder_.addMessage(index, value); + } + return this; + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code> + * + * <pre> + * Systrace report per file + * </pre> + */ + public Builder addSystrace( + com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder builderForValue) { + if (systraceBuilder_ == null) { + ensureSystraceIsMutable(); + systrace_.add(builderForValue.build()); + onChanged(); + } else { + systraceBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code> + * + * <pre> + * Systrace report per file + * </pre> + */ + public Builder addSystrace( + int index, com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder builderForValue) { + if (systraceBuilder_ == null) { + ensureSystraceIsMutable(); + systrace_.add(index, builderForValue.build()); + onChanged(); + } else { + systraceBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code> + * + * <pre> + * Systrace report per file + * </pre> + */ + public Builder addAllSystrace( + java.lang.Iterable<? extends com.android.vts.proto.VtsReportMessage.SystraceReportMessage> values) { + if (systraceBuilder_ == null) { + ensureSystraceIsMutable(); + super.addAll(values, systrace_); + onChanged(); + } else { + systraceBuilder_.addAllMessages(values); + } + return this; + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code> + * + * <pre> + * Systrace report per file + * </pre> + */ + public Builder clearSystrace() { + if (systraceBuilder_ == null) { + systrace_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000200); + onChanged(); + } else { + systraceBuilder_.clear(); + } + return this; + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code> + * + * <pre> + * Systrace report per file + * </pre> + */ + public Builder removeSystrace(int index) { + if (systraceBuilder_ == null) { + ensureSystraceIsMutable(); + systrace_.remove(index); + onChanged(); + } else { + systraceBuilder_.remove(index); + } + return this; + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code> + * + * <pre> + * Systrace report per file + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder getSystraceBuilder( + int index) { + return getSystraceFieldBuilder().getBuilder(index); + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code> + * + * <pre> + * Systrace report per file + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder getSystraceOrBuilder( + int index) { + if (systraceBuilder_ == null) { + return systrace_.get(index); } else { + return systraceBuilder_.getMessageOrBuilder(index); + } + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code> + * + * <pre> + * Systrace report per file + * </pre> + */ + public java.util.List<? extends com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder> + getSystraceOrBuilderList() { + if (systraceBuilder_ != null) { + return systraceBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(systrace_); + } + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code> + * + * <pre> + * Systrace report per file + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder addSystraceBuilder() { + return getSystraceFieldBuilder().addBuilder( + com.android.vts.proto.VtsReportMessage.SystraceReportMessage.getDefaultInstance()); + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code> + * + * <pre> + * Systrace report per file + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder addSystraceBuilder( + int index) { + return getSystraceFieldBuilder().addBuilder( + index, com.android.vts.proto.VtsReportMessage.SystraceReportMessage.getDefaultInstance()); + } + /** + * <code>repeated .android.vts.SystraceReportMessage systrace = 22;</code> + * + * <pre> + * Systrace report per file + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder> + getSystraceBuilderList() { + return getSystraceFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.SystraceReportMessage, com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder, com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder> + getSystraceFieldBuilder() { + if (systraceBuilder_ == null) { + systraceBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.SystraceReportMessage, com.android.vts.proto.VtsReportMessage.SystraceReportMessage.Builder, com.android.vts.proto.VtsReportMessage.SystraceReportMessageOrBuilder>( + systrace_, + ((bitField0_ & 0x00000200) == 0x00000200), + getParentForChildren(), + isClean()); + systrace_ = null; + } + return systraceBuilder_; + } + + // optional int64 start_timestamp = 101; + private long startTimestamp_ ; + /** + * <code>optional int64 start_timestamp = 101;</code> + * + * <pre> + * Execution start and end time stamp. + * </pre> + */ + public boolean hasStartTimestamp() { + return ((bitField0_ & 0x00000400) == 0x00000400); + } + /** + * <code>optional int64 start_timestamp = 101;</code> + * + * <pre> + * Execution start and end time stamp. + * </pre> + */ + public long getStartTimestamp() { + return startTimestamp_; + } + /** + * <code>optional int64 start_timestamp = 101;</code> + * + * <pre> + * Execution start and end time stamp. + * </pre> + */ + public Builder setStartTimestamp(long value) { + bitField0_ |= 0x00000400; + startTimestamp_ = value; + onChanged(); + return this; + } + /** + * <code>optional int64 start_timestamp = 101;</code> + * + * <pre> + * Execution start and end time stamp. + * </pre> + */ + public Builder clearStartTimestamp() { + bitField0_ = (bitField0_ & ~0x00000400); + startTimestamp_ = 0L; + onChanged(); + return this; + } + + // optional int64 end_timestamp = 102; + private long endTimestamp_ ; + /** + * <code>optional int64 end_timestamp = 102;</code> + */ + public boolean hasEndTimestamp() { + return ((bitField0_ & 0x00000800) == 0x00000800); + } + /** + * <code>optional int64 end_timestamp = 102;</code> + */ + public long getEndTimestamp() { + return endTimestamp_; + } + /** + * <code>optional int64 end_timestamp = 102;</code> + */ + public Builder setEndTimestamp(long value) { + bitField0_ |= 0x00000800; + endTimestamp_ = value; + onChanged(); + return this; + } + /** + * <code>optional int64 end_timestamp = 102;</code> + */ + public Builder clearEndTimestamp() { + bitField0_ = (bitField0_ & ~0x00000800); + endTimestamp_ = 0L; + onChanged(); + return this; + } + + // repeated .android.vts.CoverageReportMessage coverage = 103; + private java.util.List<com.android.vts.proto.VtsReportMessage.CoverageReportMessage> coverage_ = + java.util.Collections.emptyList(); + private void ensureCoverageIsMutable() { + if (!((bitField0_ & 0x00001000) == 0x00001000)) { + coverage_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.CoverageReportMessage>(coverage_); + bitField0_ |= 0x00001000; + } + } + + private com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.CoverageReportMessage, com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder, com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder> coverageBuilder_; + + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code> + * + * <pre> + * Coverage report per file + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.CoverageReportMessage> getCoverageList() { + if (coverageBuilder_ == null) { + return java.util.Collections.unmodifiableList(coverage_); + } else { + return coverageBuilder_.getMessageList(); + } + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code> + * + * <pre> + * Coverage report per file + * </pre> + */ + public int getCoverageCount() { + if (coverageBuilder_ == null) { + return coverage_.size(); + } else { + return coverageBuilder_.getCount(); + } + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code> + * + * <pre> + * Coverage report per file + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.CoverageReportMessage getCoverage(int index) { + if (coverageBuilder_ == null) { + return coverage_.get(index); + } else { + return coverageBuilder_.getMessage(index); + } + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code> + * + * <pre> + * Coverage report per file + * </pre> + */ + public Builder setCoverage( + int index, com.android.vts.proto.VtsReportMessage.CoverageReportMessage value) { + if (coverageBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureCoverageIsMutable(); + coverage_.set(index, value); + onChanged(); + } else { + coverageBuilder_.setMessage(index, value); + } + return this; + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code> + * + * <pre> + * Coverage report per file + * </pre> + */ + public Builder setCoverage( + int index, com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder builderForValue) { + if (coverageBuilder_ == null) { + ensureCoverageIsMutable(); + coverage_.set(index, builderForValue.build()); + onChanged(); + } else { + coverageBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code> + * + * <pre> + * Coverage report per file + * </pre> + */ + public Builder addCoverage(com.android.vts.proto.VtsReportMessage.CoverageReportMessage value) { + if (coverageBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureCoverageIsMutable(); + coverage_.add(value); + onChanged(); + } else { + coverageBuilder_.addMessage(value); + } + return this; + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code> + * + * <pre> + * Coverage report per file + * </pre> + */ + public Builder addCoverage( + int index, com.android.vts.proto.VtsReportMessage.CoverageReportMessage value) { + if (coverageBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureCoverageIsMutable(); + coverage_.add(index, value); + onChanged(); + } else { + coverageBuilder_.addMessage(index, value); + } + return this; + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code> + * + * <pre> + * Coverage report per file + * </pre> + */ + public Builder addCoverage( + com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder builderForValue) { + if (coverageBuilder_ == null) { + ensureCoverageIsMutable(); + coverage_.add(builderForValue.build()); + onChanged(); + } else { + coverageBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code> + * + * <pre> + * Coverage report per file + * </pre> + */ + public Builder addCoverage( + int index, com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder builderForValue) { + if (coverageBuilder_ == null) { + ensureCoverageIsMutable(); + coverage_.add(index, builderForValue.build()); + onChanged(); + } else { + coverageBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code> + * + * <pre> + * Coverage report per file + * </pre> + */ + public Builder addAllCoverage( + java.lang.Iterable<? extends com.android.vts.proto.VtsReportMessage.CoverageReportMessage> values) { + if (coverageBuilder_ == null) { + ensureCoverageIsMutable(); + super.addAll(values, coverage_); + onChanged(); + } else { + coverageBuilder_.addAllMessages(values); + } + return this; + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code> + * + * <pre> + * Coverage report per file + * </pre> + */ + public Builder clearCoverage() { + if (coverageBuilder_ == null) { + coverage_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00001000); + onChanged(); + } else { + coverageBuilder_.clear(); + } + return this; + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code> + * + * <pre> + * Coverage report per file + * </pre> + */ + public Builder removeCoverage(int index) { + if (coverageBuilder_ == null) { + ensureCoverageIsMutable(); + coverage_.remove(index); + onChanged(); + } else { + coverageBuilder_.remove(index); + } + return this; + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code> + * + * <pre> + * Coverage report per file + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder getCoverageBuilder( + int index) { + return getCoverageFieldBuilder().getBuilder(index); + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code> + * + * <pre> + * Coverage report per file + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder getCoverageOrBuilder( + int index) { + if (coverageBuilder_ == null) { + return coverage_.get(index); } else { + return coverageBuilder_.getMessageOrBuilder(index); + } + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code> + * + * <pre> + * Coverage report per file + * </pre> + */ + public java.util.List<? extends com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder> + getCoverageOrBuilderList() { + if (coverageBuilder_ != null) { + return coverageBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(coverage_); + } + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code> + * + * <pre> + * Coverage report per file + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder addCoverageBuilder() { + return getCoverageFieldBuilder().addBuilder( + com.android.vts.proto.VtsReportMessage.CoverageReportMessage.getDefaultInstance()); + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code> + * + * <pre> + * Coverage report per file + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder addCoverageBuilder( + int index) { + return getCoverageFieldBuilder().addBuilder( + index, com.android.vts.proto.VtsReportMessage.CoverageReportMessage.getDefaultInstance()); + } + /** + * <code>repeated .android.vts.CoverageReportMessage coverage = 103;</code> + * + * <pre> + * Coverage report per file + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder> + getCoverageBuilderList() { + return getCoverageFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.CoverageReportMessage, com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder, com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder> + getCoverageFieldBuilder() { + if (coverageBuilder_ == null) { + coverageBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.CoverageReportMessage, com.android.vts.proto.VtsReportMessage.CoverageReportMessage.Builder, com.android.vts.proto.VtsReportMessage.CoverageReportMessageOrBuilder>( + coverage_, + ((bitField0_ & 0x00001000) == 0x00001000), + getParentForChildren(), + isClean()); + coverage_ = null; + } + return coverageBuilder_; + } + + // repeated .android.vts.LogMessage log = 1001; + private java.util.List<com.android.vts.proto.VtsReportMessage.LogMessage> log_ = + java.util.Collections.emptyList(); + private void ensureLogIsMutable() { + if (!((bitField0_ & 0x00002000) == 0x00002000)) { + log_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.LogMessage>(log_); + bitField0_ |= 0x00002000; + } + } + + private com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.LogMessage, com.android.vts.proto.VtsReportMessage.LogMessage.Builder, com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder> logBuilder_; + + /** + * <code>repeated .android.vts.LogMessage log = 1001;</code> + * + * <pre> + * Log for a test module. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.LogMessage> getLogList() { + if (logBuilder_ == null) { + return java.util.Collections.unmodifiableList(log_); + } else { + return logBuilder_.getMessageList(); + } + } + /** + * <code>repeated .android.vts.LogMessage log = 1001;</code> + * + * <pre> + * Log for a test module. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public int getLogCount() { + if (logBuilder_ == null) { + return log_.size(); + } else { + return logBuilder_.getCount(); + } + } + /** + * <code>repeated .android.vts.LogMessage log = 1001;</code> + * + * <pre> + * Log for a test module. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.LogMessage getLog(int index) { + if (logBuilder_ == null) { + return log_.get(index); + } else { + return logBuilder_.getMessage(index); + } + } + /** + * <code>repeated .android.vts.LogMessage log = 1001;</code> + * + * <pre> + * Log for a test module. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public Builder setLog( + int index, com.android.vts.proto.VtsReportMessage.LogMessage value) { + if (logBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureLogIsMutable(); + log_.set(index, value); + onChanged(); + } else { + logBuilder_.setMessage(index, value); + } + return this; + } + /** + * <code>repeated .android.vts.LogMessage log = 1001;</code> + * + * <pre> + * Log for a test module. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public Builder setLog( + int index, com.android.vts.proto.VtsReportMessage.LogMessage.Builder builderForValue) { + if (logBuilder_ == null) { + ensureLogIsMutable(); + log_.set(index, builderForValue.build()); + onChanged(); + } else { + logBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.LogMessage log = 1001;</code> + * + * <pre> + * Log for a test module. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public Builder addLog(com.android.vts.proto.VtsReportMessage.LogMessage value) { + if (logBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureLogIsMutable(); + log_.add(value); + onChanged(); + } else { + logBuilder_.addMessage(value); + } + return this; + } + /** + * <code>repeated .android.vts.LogMessage log = 1001;</code> + * + * <pre> + * Log for a test module. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public Builder addLog( + int index, com.android.vts.proto.VtsReportMessage.LogMessage value) { + if (logBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureLogIsMutable(); + log_.add(index, value); + onChanged(); + } else { + logBuilder_.addMessage(index, value); + } + return this; + } + /** + * <code>repeated .android.vts.LogMessage log = 1001;</code> + * + * <pre> + * Log for a test module. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public Builder addLog( + com.android.vts.proto.VtsReportMessage.LogMessage.Builder builderForValue) { + if (logBuilder_ == null) { + ensureLogIsMutable(); + log_.add(builderForValue.build()); + onChanged(); + } else { + logBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.LogMessage log = 1001;</code> + * + * <pre> + * Log for a test module. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public Builder addLog( + int index, com.android.vts.proto.VtsReportMessage.LogMessage.Builder builderForValue) { + if (logBuilder_ == null) { + ensureLogIsMutable(); + log_.add(index, builderForValue.build()); + onChanged(); + } else { + logBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.LogMessage log = 1001;</code> + * + * <pre> + * Log for a test module. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public Builder addAllLog( + java.lang.Iterable<? extends com.android.vts.proto.VtsReportMessage.LogMessage> values) { + if (logBuilder_ == null) { + ensureLogIsMutable(); + super.addAll(values, log_); + onChanged(); + } else { + logBuilder_.addAllMessages(values); + } + return this; + } + /** + * <code>repeated .android.vts.LogMessage log = 1001;</code> + * + * <pre> + * Log for a test module. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public Builder clearLog() { + if (logBuilder_ == null) { + log_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00002000); + onChanged(); + } else { + logBuilder_.clear(); + } + return this; + } + /** + * <code>repeated .android.vts.LogMessage log = 1001;</code> + * + * <pre> + * Log for a test module. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public Builder removeLog(int index) { + if (logBuilder_ == null) { + ensureLogIsMutable(); + log_.remove(index); + onChanged(); + } else { + logBuilder_.remove(index); + } + return this; + } + /** + * <code>repeated .android.vts.LogMessage log = 1001;</code> + * + * <pre> + * Log for a test module. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.LogMessage.Builder getLogBuilder( + int index) { + return getLogFieldBuilder().getBuilder(index); + } + /** + * <code>repeated .android.vts.LogMessage log = 1001;</code> + * + * <pre> + * Log for a test module. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder getLogOrBuilder( + int index) { + if (logBuilder_ == null) { + return log_.get(index); } else { + return logBuilder_.getMessageOrBuilder(index); + } + } + /** + * <code>repeated .android.vts.LogMessage log = 1001;</code> + * + * <pre> + * Log for a test module. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public java.util.List<? extends com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder> + getLogOrBuilderList() { + if (logBuilder_ != null) { + return logBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(log_); + } + } + /** + * <code>repeated .android.vts.LogMessage log = 1001;</code> + * + * <pre> + * Log for a test module. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.LogMessage.Builder addLogBuilder() { + return getLogFieldBuilder().addBuilder( + com.android.vts.proto.VtsReportMessage.LogMessage.getDefaultInstance()); + } + /** + * <code>repeated .android.vts.LogMessage log = 1001;</code> + * + * <pre> + * Log for a test module. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.LogMessage.Builder addLogBuilder( + int index) { + return getLogFieldBuilder().addBuilder( + index, com.android.vts.proto.VtsReportMessage.LogMessage.getDefaultInstance()); + } + /** + * <code>repeated .android.vts.LogMessage log = 1001;</code> + * + * <pre> + * Log for a test module. May contain multiple logs such as logcat, host log, + * etc. + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.LogMessage.Builder> + getLogBuilderList() { + return getLogFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.LogMessage, com.android.vts.proto.VtsReportMessage.LogMessage.Builder, com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder> + getLogFieldBuilder() { + if (logBuilder_ == null) { + logBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.LogMessage, com.android.vts.proto.VtsReportMessage.LogMessage.Builder, com.android.vts.proto.VtsReportMessage.LogMessageOrBuilder>( + log_, + ((bitField0_ & 0x00002000) == 0x00002000), + getParentForChildren(), + isClean()); + log_ = null; + } + return logBuilder_; + } + + // @@protoc_insertion_point(builder_scope:android.vts.TestReportMessage) + } + + static { + defaultInstance = new TestReportMessage(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:android.vts.TestReportMessage) + } + + public interface TestPlanReportMessageOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // repeated string test_module_name = 11; + /** + * <code>repeated string test_module_name = 11;</code> + * + * <pre> + * Keys used to find all TestReportMessage messages of test modules in + * this plan. + * </pre> + */ + java.util.List<java.lang.String> + getTestModuleNameList(); + /** + * <code>repeated string test_module_name = 11;</code> + * + * <pre> + * Keys used to find all TestReportMessage messages of test modules in + * this plan. + * </pre> + */ + int getTestModuleNameCount(); + /** + * <code>repeated string test_module_name = 11;</code> + * + * <pre> + * Keys used to find all TestReportMessage messages of test modules in + * this plan. + * </pre> + */ + java.lang.String getTestModuleName(int index); + /** + * <code>repeated string test_module_name = 11;</code> + * + * <pre> + * Keys used to find all TestReportMessage messages of test modules in + * this plan. + * </pre> + */ + com.google.protobuf.ByteString + getTestModuleNameBytes(int index); + + // repeated int64 test_module_start_timestamp = 12; + /** + * <code>repeated int64 test_module_start_timestamp = 12;</code> + */ + java.util.List<java.lang.Long> getTestModuleStartTimestampList(); + /** + * <code>repeated int64 test_module_start_timestamp = 12;</code> + */ + int getTestModuleStartTimestampCount(); + /** + * <code>repeated int64 test_module_start_timestamp = 12;</code> + */ + long getTestModuleStartTimestamp(int index); + + // optional string test_plan_name = 21; + /** + * <code>optional string test_plan_name = 21;</code> + * + * <pre> + * The test plan name. + * </pre> + */ + boolean hasTestPlanName(); + /** + * <code>optional string test_plan_name = 21;</code> + * + * <pre> + * The test plan name. + * </pre> + */ + java.lang.String getTestPlanName(); + /** + * <code>optional string test_plan_name = 21;</code> + * + * <pre> + * The test plan name. + * </pre> + */ + com.google.protobuf.ByteString + getTestPlanNameBytes(); + + // repeated .android.vts.UrlResourceMessage partner_report = 31; + /** + * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code> + * + * <pre> + * Report resource flies. + * </pre> + */ + java.util.List<com.android.vts.proto.VtsReportMessage.UrlResourceMessage> + getPartnerReportList(); + /** + * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code> + * + * <pre> + * Report resource flies. + * </pre> + */ + com.android.vts.proto.VtsReportMessage.UrlResourceMessage getPartnerReport(int index); + /** + * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code> + * + * <pre> + * Report resource flies. + * </pre> + */ + int getPartnerReportCount(); + /** + * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code> + * + * <pre> + * Report resource flies. + * </pre> + */ + java.util.List<? extends com.android.vts.proto.VtsReportMessage.UrlResourceMessageOrBuilder> + getPartnerReportOrBuilderList(); + /** + * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code> + * + * <pre> + * Report resource flies. + * </pre> + */ + com.android.vts.proto.VtsReportMessage.UrlResourceMessageOrBuilder getPartnerReportOrBuilder( + int index); + } + /** + * Protobuf type {@code android.vts.TestPlanReportMessage} + * + * <pre> + * To specify a test execution report. + * </pre> + */ + public static final class TestPlanReportMessage extends + com.google.protobuf.GeneratedMessage + implements TestPlanReportMessageOrBuilder { + // Use TestPlanReportMessage.newBuilder() to construct. + private TestPlanReportMessage(com.google.protobuf.GeneratedMessage.Builder<?> builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private TestPlanReportMessage(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final TestPlanReportMessage defaultInstance; + public static TestPlanReportMessage getDefaultInstance() { + return defaultInstance; + } + + public TestPlanReportMessage getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private TestPlanReportMessage( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 90: { + if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + testModuleName_ = new com.google.protobuf.LazyStringArrayList(); + mutable_bitField0_ |= 0x00000001; + } + testModuleName_.add(input.readBytes()); + break; + } + case 96: { + if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) { + testModuleStartTimestamp_ = new java.util.ArrayList<java.lang.Long>(); + mutable_bitField0_ |= 0x00000002; + } + testModuleStartTimestamp_.add(input.readInt64()); + break; + } + case 98: { + int length = input.readRawVarint32(); + int limit = input.pushLimit(length); + if (!((mutable_bitField0_ & 0x00000002) == 0x00000002) && input.getBytesUntilLimit() > 0) { + testModuleStartTimestamp_ = new java.util.ArrayList<java.lang.Long>(); + mutable_bitField0_ |= 0x00000002; + } + while (input.getBytesUntilLimit() > 0) { + testModuleStartTimestamp_.add(input.readInt64()); + } + input.popLimit(limit); + break; + } + case 170: { + bitField0_ |= 0x00000001; + testPlanName_ = input.readBytes(); + break; + } + case 250: { + if (!((mutable_bitField0_ & 0x00000008) == 0x00000008)) { + partnerReport_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.UrlResourceMessage>(); + mutable_bitField0_ |= 0x00000008; + } + partnerReport_.add(input.readMessage(com.android.vts.proto.VtsReportMessage.UrlResourceMessage.PARSER, extensionRegistry)); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + testModuleName_ = new com.google.protobuf.UnmodifiableLazyStringList(testModuleName_); + } + if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) { + testModuleStartTimestamp_ = java.util.Collections.unmodifiableList(testModuleStartTimestamp_); + } + if (((mutable_bitField0_ & 0x00000008) == 0x00000008)) { + partnerReport_ = java.util.Collections.unmodifiableList(partnerReport_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_TestPlanReportMessage_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_TestPlanReportMessage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.class, com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.Builder.class); + } + + public static com.google.protobuf.Parser<TestPlanReportMessage> PARSER = + new com.google.protobuf.AbstractParser<TestPlanReportMessage>() { + public TestPlanReportMessage parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new TestPlanReportMessage(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser<TestPlanReportMessage> getParserForType() { + return PARSER; + } + + private int bitField0_; + // repeated string test_module_name = 11; + public static final int TEST_MODULE_NAME_FIELD_NUMBER = 11; + private com.google.protobuf.LazyStringList testModuleName_; + /** + * <code>repeated string test_module_name = 11;</code> + * + * <pre> + * Keys used to find all TestReportMessage messages of test modules in + * this plan. + * </pre> + */ + public java.util.List<java.lang.String> + getTestModuleNameList() { + return testModuleName_; + } + /** + * <code>repeated string test_module_name = 11;</code> + * + * <pre> + * Keys used to find all TestReportMessage messages of test modules in + * this plan. + * </pre> + */ + public int getTestModuleNameCount() { + return testModuleName_.size(); + } + /** + * <code>repeated string test_module_name = 11;</code> + * + * <pre> + * Keys used to find all TestReportMessage messages of test modules in + * this plan. + * </pre> + */ + public java.lang.String getTestModuleName(int index) { + return testModuleName_.get(index); + } + /** + * <code>repeated string test_module_name = 11;</code> + * + * <pre> + * Keys used to find all TestReportMessage messages of test modules in + * this plan. + * </pre> + */ + public com.google.protobuf.ByteString + getTestModuleNameBytes(int index) { + return testModuleName_.getByteString(index); + } + + // repeated int64 test_module_start_timestamp = 12; + public static final int TEST_MODULE_START_TIMESTAMP_FIELD_NUMBER = 12; + private java.util.List<java.lang.Long> testModuleStartTimestamp_; + /** + * <code>repeated int64 test_module_start_timestamp = 12;</code> + */ + public java.util.List<java.lang.Long> + getTestModuleStartTimestampList() { + return testModuleStartTimestamp_; + } + /** + * <code>repeated int64 test_module_start_timestamp = 12;</code> + */ + public int getTestModuleStartTimestampCount() { + return testModuleStartTimestamp_.size(); + } + /** + * <code>repeated int64 test_module_start_timestamp = 12;</code> + */ + public long getTestModuleStartTimestamp(int index) { + return testModuleStartTimestamp_.get(index); + } + + // optional string test_plan_name = 21; + public static final int TEST_PLAN_NAME_FIELD_NUMBER = 21; + private java.lang.Object testPlanName_; + /** + * <code>optional string test_plan_name = 21;</code> + * + * <pre> + * The test plan name. + * </pre> + */ + public boolean hasTestPlanName() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * <code>optional string test_plan_name = 21;</code> + * + * <pre> + * The test plan name. + * </pre> + */ + public java.lang.String getTestPlanName() { + java.lang.Object ref = testPlanName_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + testPlanName_ = s; + } + return s; + } + } + /** + * <code>optional string test_plan_name = 21;</code> + * + * <pre> + * The test plan name. + * </pre> + */ + public com.google.protobuf.ByteString + getTestPlanNameBytes() { + java.lang.Object ref = testPlanName_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + testPlanName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // repeated .android.vts.UrlResourceMessage partner_report = 31; + public static final int PARTNER_REPORT_FIELD_NUMBER = 31; + private java.util.List<com.android.vts.proto.VtsReportMessage.UrlResourceMessage> partnerReport_; + /** + * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code> + * + * <pre> + * Report resource flies. + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.UrlResourceMessage> getPartnerReportList() { + return partnerReport_; + } + /** + * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code> + * + * <pre> + * Report resource flies. + * </pre> + */ + public java.util.List<? extends com.android.vts.proto.VtsReportMessage.UrlResourceMessageOrBuilder> + getPartnerReportOrBuilderList() { + return partnerReport_; + } + /** + * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code> + * + * <pre> + * Report resource flies. + * </pre> + */ + public int getPartnerReportCount() { + return partnerReport_.size(); + } + /** + * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code> + * + * <pre> + * Report resource flies. + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.UrlResourceMessage getPartnerReport(int index) { + return partnerReport_.get(index); + } + /** + * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code> + * + * <pre> + * Report resource flies. + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.UrlResourceMessageOrBuilder getPartnerReportOrBuilder( + int index) { + return partnerReport_.get(index); + } + + private void initFields() { + testModuleName_ = com.google.protobuf.LazyStringArrayList.EMPTY; + testModuleStartTimestamp_ = java.util.Collections.emptyList(); + testPlanName_ = ""; + partnerReport_ = java.util.Collections.emptyList(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + for (int i = 0; i < testModuleName_.size(); i++) { + output.writeBytes(11, testModuleName_.getByteString(i)); + } + for (int i = 0; i < testModuleStartTimestamp_.size(); i++) { + output.writeInt64(12, testModuleStartTimestamp_.get(i)); + } + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(21, getTestPlanNameBytes()); + } + for (int i = 0; i < partnerReport_.size(); i++) { + output.writeMessage(31, partnerReport_.get(i)); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + { + int dataSize = 0; + for (int i = 0; i < testModuleName_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeBytesSizeNoTag(testModuleName_.getByteString(i)); + } + size += dataSize; + size += 1 * getTestModuleNameList().size(); + } + { + int dataSize = 0; + for (int i = 0; i < testModuleStartTimestamp_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeInt64SizeNoTag(testModuleStartTimestamp_.get(i)); + } + size += dataSize; + size += 1 * getTestModuleStartTimestampList().size(); + } + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(21, getTestPlanNameBytes()); + } + for (int i = 0; i < partnerReport_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(31, partnerReport_.get(i)); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static com.android.vts.proto.VtsReportMessage.TestPlanReportMessage parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.android.vts.proto.VtsReportMessage.TestPlanReportMessage parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.TestPlanReportMessage parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.android.vts.proto.VtsReportMessage.TestPlanReportMessage parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.TestPlanReportMessage parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.TestPlanReportMessage parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.TestPlanReportMessage parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.TestPlanReportMessage parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.TestPlanReportMessage parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.TestPlanReportMessage parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(com.android.vts.proto.VtsReportMessage.TestPlanReportMessage prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code android.vts.TestPlanReportMessage} + * + * <pre> + * To specify a test execution report. + * </pre> + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder<Builder> + implements com.android.vts.proto.VtsReportMessage.TestPlanReportMessageOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_TestPlanReportMessage_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_TestPlanReportMessage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.class, com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.Builder.class); + } + + // Construct using com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getPartnerReportFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + testModuleName_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + testModuleStartTimestamp_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + testPlanName_ = ""; + bitField0_ = (bitField0_ & ~0x00000004); + if (partnerReportBuilder_ == null) { + partnerReport_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000008); + } else { + partnerReportBuilder_.clear(); + } + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_TestPlanReportMessage_descriptor; + } + + public com.android.vts.proto.VtsReportMessage.TestPlanReportMessage getDefaultInstanceForType() { + return com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.getDefaultInstance(); + } + + public com.android.vts.proto.VtsReportMessage.TestPlanReportMessage build() { + com.android.vts.proto.VtsReportMessage.TestPlanReportMessage result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public com.android.vts.proto.VtsReportMessage.TestPlanReportMessage buildPartial() { + com.android.vts.proto.VtsReportMessage.TestPlanReportMessage result = new com.android.vts.proto.VtsReportMessage.TestPlanReportMessage(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + testModuleName_ = new com.google.protobuf.UnmodifiableLazyStringList( + testModuleName_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.testModuleName_ = testModuleName_; + if (((bitField0_ & 0x00000002) == 0x00000002)) { + testModuleStartTimestamp_ = java.util.Collections.unmodifiableList(testModuleStartTimestamp_); + bitField0_ = (bitField0_ & ~0x00000002); + } + result.testModuleStartTimestamp_ = testModuleStartTimestamp_; + if (((from_bitField0_ & 0x00000004) == 0x00000004)) { + to_bitField0_ |= 0x00000001; + } + result.testPlanName_ = testPlanName_; + if (partnerReportBuilder_ == null) { + if (((bitField0_ & 0x00000008) == 0x00000008)) { + partnerReport_ = java.util.Collections.unmodifiableList(partnerReport_); + bitField0_ = (bitField0_ & ~0x00000008); + } + result.partnerReport_ = partnerReport_; + } else { + result.partnerReport_ = partnerReportBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.android.vts.proto.VtsReportMessage.TestPlanReportMessage) { + return mergeFrom((com.android.vts.proto.VtsReportMessage.TestPlanReportMessage)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.android.vts.proto.VtsReportMessage.TestPlanReportMessage other) { + if (other == com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.getDefaultInstance()) return this; + if (!other.testModuleName_.isEmpty()) { + if (testModuleName_.isEmpty()) { + testModuleName_ = other.testModuleName_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureTestModuleNameIsMutable(); + testModuleName_.addAll(other.testModuleName_); + } + onChanged(); + } + if (!other.testModuleStartTimestamp_.isEmpty()) { + if (testModuleStartTimestamp_.isEmpty()) { + testModuleStartTimestamp_ = other.testModuleStartTimestamp_; + bitField0_ = (bitField0_ & ~0x00000002); + } else { + ensureTestModuleStartTimestampIsMutable(); + testModuleStartTimestamp_.addAll(other.testModuleStartTimestamp_); + } + onChanged(); + } + if (other.hasTestPlanName()) { + bitField0_ |= 0x00000004; + testPlanName_ = other.testPlanName_; + onChanged(); + } + if (partnerReportBuilder_ == null) { + if (!other.partnerReport_.isEmpty()) { + if (partnerReport_.isEmpty()) { + partnerReport_ = other.partnerReport_; + bitField0_ = (bitField0_ & ~0x00000008); + } else { + ensurePartnerReportIsMutable(); + partnerReport_.addAll(other.partnerReport_); + } + onChanged(); + } + } else { + if (!other.partnerReport_.isEmpty()) { + if (partnerReportBuilder_.isEmpty()) { + partnerReportBuilder_.dispose(); + partnerReportBuilder_ = null; + partnerReport_ = other.partnerReport_; + bitField0_ = (bitField0_ & ~0x00000008); + partnerReportBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getPartnerReportFieldBuilder() : null; + } else { + partnerReportBuilder_.addAllMessages(other.partnerReport_); + } + } + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + com.android.vts.proto.VtsReportMessage.TestPlanReportMessage parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (com.android.vts.proto.VtsReportMessage.TestPlanReportMessage) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // repeated string test_module_name = 11; + private com.google.protobuf.LazyStringList testModuleName_ = com.google.protobuf.LazyStringArrayList.EMPTY; + private void ensureTestModuleNameIsMutable() { + if (!((bitField0_ & 0x00000001) == 0x00000001)) { + testModuleName_ = new com.google.protobuf.LazyStringArrayList(testModuleName_); + bitField0_ |= 0x00000001; + } + } + /** + * <code>repeated string test_module_name = 11;</code> + * + * <pre> + * Keys used to find all TestReportMessage messages of test modules in + * this plan. + * </pre> + */ + public java.util.List<java.lang.String> + getTestModuleNameList() { + return java.util.Collections.unmodifiableList(testModuleName_); + } + /** + * <code>repeated string test_module_name = 11;</code> + * + * <pre> + * Keys used to find all TestReportMessage messages of test modules in + * this plan. + * </pre> + */ + public int getTestModuleNameCount() { + return testModuleName_.size(); + } + /** + * <code>repeated string test_module_name = 11;</code> + * + * <pre> + * Keys used to find all TestReportMessage messages of test modules in + * this plan. + * </pre> + */ + public java.lang.String getTestModuleName(int index) { + return testModuleName_.get(index); + } + /** + * <code>repeated string test_module_name = 11;</code> + * + * <pre> + * Keys used to find all TestReportMessage messages of test modules in + * this plan. + * </pre> + */ + public com.google.protobuf.ByteString + getTestModuleNameBytes(int index) { + return testModuleName_.getByteString(index); + } + /** + * <code>repeated string test_module_name = 11;</code> + * + * <pre> + * Keys used to find all TestReportMessage messages of test modules in + * this plan. + * </pre> + */ + public Builder setTestModuleName( + int index, java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureTestModuleNameIsMutable(); + testModuleName_.set(index, value); + onChanged(); + return this; + } + /** + * <code>repeated string test_module_name = 11;</code> + * + * <pre> + * Keys used to find all TestReportMessage messages of test modules in + * this plan. + * </pre> + */ + public Builder addTestModuleName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureTestModuleNameIsMutable(); + testModuleName_.add(value); + onChanged(); + return this; + } + /** + * <code>repeated string test_module_name = 11;</code> + * + * <pre> + * Keys used to find all TestReportMessage messages of test modules in + * this plan. + * </pre> + */ + public Builder addAllTestModuleName( + java.lang.Iterable<java.lang.String> values) { + ensureTestModuleNameIsMutable(); + super.addAll(values, testModuleName_); + onChanged(); + return this; + } + /** + * <code>repeated string test_module_name = 11;</code> + * + * <pre> + * Keys used to find all TestReportMessage messages of test modules in + * this plan. + * </pre> + */ + public Builder clearTestModuleName() { + testModuleName_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000001); + onChanged(); + return this; + } + /** + * <code>repeated string test_module_name = 11;</code> + * + * <pre> + * Keys used to find all TestReportMessage messages of test modules in + * this plan. + * </pre> + */ + public Builder addTestModuleNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureTestModuleNameIsMutable(); + testModuleName_.add(value); + onChanged(); + return this; + } + + // repeated int64 test_module_start_timestamp = 12; + private java.util.List<java.lang.Long> testModuleStartTimestamp_ = java.util.Collections.emptyList(); + private void ensureTestModuleStartTimestampIsMutable() { + if (!((bitField0_ & 0x00000002) == 0x00000002)) { + testModuleStartTimestamp_ = new java.util.ArrayList<java.lang.Long>(testModuleStartTimestamp_); + bitField0_ |= 0x00000002; + } + } + /** + * <code>repeated int64 test_module_start_timestamp = 12;</code> + */ + public java.util.List<java.lang.Long> + getTestModuleStartTimestampList() { + return java.util.Collections.unmodifiableList(testModuleStartTimestamp_); + } + /** + * <code>repeated int64 test_module_start_timestamp = 12;</code> + */ + public int getTestModuleStartTimestampCount() { + return testModuleStartTimestamp_.size(); + } + /** + * <code>repeated int64 test_module_start_timestamp = 12;</code> + */ + public long getTestModuleStartTimestamp(int index) { + return testModuleStartTimestamp_.get(index); + } + /** + * <code>repeated int64 test_module_start_timestamp = 12;</code> + */ + public Builder setTestModuleStartTimestamp( + int index, long value) { + ensureTestModuleStartTimestampIsMutable(); + testModuleStartTimestamp_.set(index, value); + onChanged(); + return this; + } + /** + * <code>repeated int64 test_module_start_timestamp = 12;</code> + */ + public Builder addTestModuleStartTimestamp(long value) { + ensureTestModuleStartTimestampIsMutable(); + testModuleStartTimestamp_.add(value); + onChanged(); + return this; + } + /** + * <code>repeated int64 test_module_start_timestamp = 12;</code> + */ + public Builder addAllTestModuleStartTimestamp( + java.lang.Iterable<? extends java.lang.Long> values) { + ensureTestModuleStartTimestampIsMutable(); + super.addAll(values, testModuleStartTimestamp_); + onChanged(); + return this; + } + /** + * <code>repeated int64 test_module_start_timestamp = 12;</code> + */ + public Builder clearTestModuleStartTimestamp() { + testModuleStartTimestamp_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + onChanged(); + return this; + } + + // optional string test_plan_name = 21; + private java.lang.Object testPlanName_ = ""; + /** + * <code>optional string test_plan_name = 21;</code> + * + * <pre> + * The test plan name. + * </pre> + */ + public boolean hasTestPlanName() { + return ((bitField0_ & 0x00000004) == 0x00000004); + } + /** + * <code>optional string test_plan_name = 21;</code> + * + * <pre> + * The test plan name. + * </pre> + */ + public java.lang.String getTestPlanName() { + java.lang.Object ref = testPlanName_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + testPlanName_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * <code>optional string test_plan_name = 21;</code> + * + * <pre> + * The test plan name. + * </pre> + */ + public com.google.protobuf.ByteString + getTestPlanNameBytes() { + java.lang.Object ref = testPlanName_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + testPlanName_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * <code>optional string test_plan_name = 21;</code> + * + * <pre> + * The test plan name. + * </pre> + */ + public Builder setTestPlanName( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + testPlanName_ = value; + onChanged(); + return this; + } + /** + * <code>optional string test_plan_name = 21;</code> + * + * <pre> + * The test plan name. + * </pre> + */ + public Builder clearTestPlanName() { + bitField0_ = (bitField0_ & ~0x00000004); + testPlanName_ = getDefaultInstance().getTestPlanName(); + onChanged(); + return this; + } + /** + * <code>optional string test_plan_name = 21;</code> + * + * <pre> + * The test plan name. + * </pre> + */ + public Builder setTestPlanNameBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000004; + testPlanName_ = value; + onChanged(); + return this; + } + + // repeated .android.vts.UrlResourceMessage partner_report = 31; + private java.util.List<com.android.vts.proto.VtsReportMessage.UrlResourceMessage> partnerReport_ = + java.util.Collections.emptyList(); + private void ensurePartnerReportIsMutable() { + if (!((bitField0_ & 0x00000008) == 0x00000008)) { + partnerReport_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.UrlResourceMessage>(partnerReport_); + bitField0_ |= 0x00000008; + } + } + + private com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.UrlResourceMessage, com.android.vts.proto.VtsReportMessage.UrlResourceMessage.Builder, com.android.vts.proto.VtsReportMessage.UrlResourceMessageOrBuilder> partnerReportBuilder_; + + /** + * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code> + * + * <pre> + * Report resource flies. + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.UrlResourceMessage> getPartnerReportList() { + if (partnerReportBuilder_ == null) { + return java.util.Collections.unmodifiableList(partnerReport_); + } else { + return partnerReportBuilder_.getMessageList(); + } + } + /** + * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code> + * + * <pre> + * Report resource flies. + * </pre> + */ + public int getPartnerReportCount() { + if (partnerReportBuilder_ == null) { + return partnerReport_.size(); + } else { + return partnerReportBuilder_.getCount(); + } + } + /** + * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code> + * + * <pre> + * Report resource flies. + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.UrlResourceMessage getPartnerReport(int index) { + if (partnerReportBuilder_ == null) { + return partnerReport_.get(index); + } else { + return partnerReportBuilder_.getMessage(index); + } + } + /** + * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code> + * + * <pre> + * Report resource flies. + * </pre> + */ + public Builder setPartnerReport( + int index, com.android.vts.proto.VtsReportMessage.UrlResourceMessage value) { + if (partnerReportBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensurePartnerReportIsMutable(); + partnerReport_.set(index, value); + onChanged(); + } else { + partnerReportBuilder_.setMessage(index, value); + } + return this; + } + /** + * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code> + * + * <pre> + * Report resource flies. + * </pre> + */ + public Builder setPartnerReport( + int index, com.android.vts.proto.VtsReportMessage.UrlResourceMessage.Builder builderForValue) { + if (partnerReportBuilder_ == null) { + ensurePartnerReportIsMutable(); + partnerReport_.set(index, builderForValue.build()); + onChanged(); + } else { + partnerReportBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code> + * + * <pre> + * Report resource flies. + * </pre> + */ + public Builder addPartnerReport(com.android.vts.proto.VtsReportMessage.UrlResourceMessage value) { + if (partnerReportBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensurePartnerReportIsMutable(); + partnerReport_.add(value); + onChanged(); + } else { + partnerReportBuilder_.addMessage(value); + } + return this; + } + /** + * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code> + * + * <pre> + * Report resource flies. + * </pre> + */ + public Builder addPartnerReport( + int index, com.android.vts.proto.VtsReportMessage.UrlResourceMessage value) { + if (partnerReportBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensurePartnerReportIsMutable(); + partnerReport_.add(index, value); + onChanged(); + } else { + partnerReportBuilder_.addMessage(index, value); + } + return this; + } + /** + * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code> + * + * <pre> + * Report resource flies. + * </pre> + */ + public Builder addPartnerReport( + com.android.vts.proto.VtsReportMessage.UrlResourceMessage.Builder builderForValue) { + if (partnerReportBuilder_ == null) { + ensurePartnerReportIsMutable(); + partnerReport_.add(builderForValue.build()); + onChanged(); + } else { + partnerReportBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code> + * + * <pre> + * Report resource flies. + * </pre> + */ + public Builder addPartnerReport( + int index, com.android.vts.proto.VtsReportMessage.UrlResourceMessage.Builder builderForValue) { + if (partnerReportBuilder_ == null) { + ensurePartnerReportIsMutable(); + partnerReport_.add(index, builderForValue.build()); + onChanged(); + } else { + partnerReportBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code> + * + * <pre> + * Report resource flies. + * </pre> + */ + public Builder addAllPartnerReport( + java.lang.Iterable<? extends com.android.vts.proto.VtsReportMessage.UrlResourceMessage> values) { + if (partnerReportBuilder_ == null) { + ensurePartnerReportIsMutable(); + super.addAll(values, partnerReport_); + onChanged(); + } else { + partnerReportBuilder_.addAllMessages(values); + } + return this; + } + /** + * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code> + * + * <pre> + * Report resource flies. + * </pre> + */ + public Builder clearPartnerReport() { + if (partnerReportBuilder_ == null) { + partnerReport_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000008); + onChanged(); + } else { + partnerReportBuilder_.clear(); + } + return this; + } + /** + * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code> + * + * <pre> + * Report resource flies. + * </pre> + */ + public Builder removePartnerReport(int index) { + if (partnerReportBuilder_ == null) { + ensurePartnerReportIsMutable(); + partnerReport_.remove(index); + onChanged(); + } else { + partnerReportBuilder_.remove(index); + } + return this; + } + /** + * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code> + * + * <pre> + * Report resource flies. + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.UrlResourceMessage.Builder getPartnerReportBuilder( + int index) { + return getPartnerReportFieldBuilder().getBuilder(index); + } + /** + * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code> + * + * <pre> + * Report resource flies. + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.UrlResourceMessageOrBuilder getPartnerReportOrBuilder( + int index) { + if (partnerReportBuilder_ == null) { + return partnerReport_.get(index); } else { + return partnerReportBuilder_.getMessageOrBuilder(index); + } + } + /** + * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code> + * + * <pre> + * Report resource flies. + * </pre> + */ + public java.util.List<? extends com.android.vts.proto.VtsReportMessage.UrlResourceMessageOrBuilder> + getPartnerReportOrBuilderList() { + if (partnerReportBuilder_ != null) { + return partnerReportBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(partnerReport_); + } + } + /** + * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code> + * + * <pre> + * Report resource flies. + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.UrlResourceMessage.Builder addPartnerReportBuilder() { + return getPartnerReportFieldBuilder().addBuilder( + com.android.vts.proto.VtsReportMessage.UrlResourceMessage.getDefaultInstance()); + } + /** + * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code> + * + * <pre> + * Report resource flies. + * </pre> + */ + public com.android.vts.proto.VtsReportMessage.UrlResourceMessage.Builder addPartnerReportBuilder( + int index) { + return getPartnerReportFieldBuilder().addBuilder( + index, com.android.vts.proto.VtsReportMessage.UrlResourceMessage.getDefaultInstance()); + } + /** + * <code>repeated .android.vts.UrlResourceMessage partner_report = 31;</code> + * + * <pre> + * Report resource flies. + * </pre> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.UrlResourceMessage.Builder> + getPartnerReportBuilderList() { + return getPartnerReportFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.UrlResourceMessage, com.android.vts.proto.VtsReportMessage.UrlResourceMessage.Builder, com.android.vts.proto.VtsReportMessage.UrlResourceMessageOrBuilder> + getPartnerReportFieldBuilder() { + if (partnerReportBuilder_ == null) { + partnerReportBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.UrlResourceMessage, com.android.vts.proto.VtsReportMessage.UrlResourceMessage.Builder, com.android.vts.proto.VtsReportMessage.UrlResourceMessageOrBuilder>( + partnerReport_, + ((bitField0_ & 0x00000008) == 0x00000008), + getParentForChildren(), + isClean()); + partnerReport_ = null; + } + return partnerReportBuilder_; + } + + // @@protoc_insertion_point(builder_scope:android.vts.TestPlanReportMessage) + } + + static { + defaultInstance = new TestPlanReportMessage(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:android.vts.TestPlanReportMessage) + } + + public interface DashboardPostMessageOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // optional string access_token = 1; + /** + * <code>optional string access_token = 1;</code> + * + * <pre> + * oauth2.0 access token + * </pre> + */ + boolean hasAccessToken(); + /** + * <code>optional string access_token = 1;</code> + * + * <pre> + * oauth2.0 access token + * </pre> + */ + java.lang.String getAccessToken(); + /** + * <code>optional string access_token = 1;</code> + * + * <pre> + * oauth2.0 access token + * </pre> + */ + com.google.protobuf.ByteString + getAccessTokenBytes(); + + // repeated .android.vts.TestReportMessage test_report = 2; + /** + * <code>repeated .android.vts.TestReportMessage test_report = 2;</code> + */ + java.util.List<com.android.vts.proto.VtsReportMessage.TestReportMessage> + getTestReportList(); + /** + * <code>repeated .android.vts.TestReportMessage test_report = 2;</code> + */ + com.android.vts.proto.VtsReportMessage.TestReportMessage getTestReport(int index); + /** + * <code>repeated .android.vts.TestReportMessage test_report = 2;</code> + */ + int getTestReportCount(); + /** + * <code>repeated .android.vts.TestReportMessage test_report = 2;</code> + */ + java.util.List<? extends com.android.vts.proto.VtsReportMessage.TestReportMessageOrBuilder> + getTestReportOrBuilderList(); + /** + * <code>repeated .android.vts.TestReportMessage test_report = 2;</code> + */ + com.android.vts.proto.VtsReportMessage.TestReportMessageOrBuilder getTestReportOrBuilder( + int index); + + // repeated .android.vts.TestPlanReportMessage test_plan_report = 3; + /** + * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code> + */ + java.util.List<com.android.vts.proto.VtsReportMessage.TestPlanReportMessage> + getTestPlanReportList(); + /** + * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code> + */ + com.android.vts.proto.VtsReportMessage.TestPlanReportMessage getTestPlanReport(int index); + /** + * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code> + */ + int getTestPlanReportCount(); + /** + * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code> + */ + java.util.List<? extends com.android.vts.proto.VtsReportMessage.TestPlanReportMessageOrBuilder> + getTestPlanReportOrBuilderList(); + /** + * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code> + */ + com.android.vts.proto.VtsReportMessage.TestPlanReportMessageOrBuilder getTestPlanReportOrBuilder( + int index); + } + /** + * Protobuf type {@code android.vts.DashboardPostMessage} + * + * <pre> + * Proto wrapper for posting data to the VTS Dashboard + * </pre> + */ + public static final class DashboardPostMessage extends + com.google.protobuf.GeneratedMessage + implements DashboardPostMessageOrBuilder { + // Use DashboardPostMessage.newBuilder() to construct. + private DashboardPostMessage(com.google.protobuf.GeneratedMessage.Builder<?> builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private DashboardPostMessage(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final DashboardPostMessage defaultInstance; + public static DashboardPostMessage getDefaultInstance() { + return defaultInstance; + } + + public DashboardPostMessage getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private DashboardPostMessage( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + accessToken_ = input.readBytes(); + break; + } + case 18: { + if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) { + testReport_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.TestReportMessage>(); + mutable_bitField0_ |= 0x00000002; + } + testReport_.add(input.readMessage(com.android.vts.proto.VtsReportMessage.TestReportMessage.PARSER, extensionRegistry)); + break; + } + case 26: { + if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) { + testPlanReport_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.TestPlanReportMessage>(); + mutable_bitField0_ |= 0x00000004; + } + testPlanReport_.add(input.readMessage(com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.PARSER, extensionRegistry)); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) { + testReport_ = java.util.Collections.unmodifiableList(testReport_); + } + if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) { + testPlanReport_ = java.util.Collections.unmodifiableList(testPlanReport_); + } + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_DashboardPostMessage_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_DashboardPostMessage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.android.vts.proto.VtsReportMessage.DashboardPostMessage.class, com.android.vts.proto.VtsReportMessage.DashboardPostMessage.Builder.class); + } + + public static com.google.protobuf.Parser<DashboardPostMessage> PARSER = + new com.google.protobuf.AbstractParser<DashboardPostMessage>() { + public DashboardPostMessage parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new DashboardPostMessage(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser<DashboardPostMessage> getParserForType() { + return PARSER; + } + + private int bitField0_; + // optional string access_token = 1; + public static final int ACCESS_TOKEN_FIELD_NUMBER = 1; + private java.lang.Object accessToken_; + /** + * <code>optional string access_token = 1;</code> + * + * <pre> + * oauth2.0 access token + * </pre> + */ + public boolean hasAccessToken() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * <code>optional string access_token = 1;</code> + * + * <pre> + * oauth2.0 access token + * </pre> + */ + public java.lang.String getAccessToken() { + java.lang.Object ref = accessToken_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + accessToken_ = s; + } + return s; + } + } + /** + * <code>optional string access_token = 1;</code> + * + * <pre> + * oauth2.0 access token + * </pre> + */ + public com.google.protobuf.ByteString + getAccessTokenBytes() { + java.lang.Object ref = accessToken_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + accessToken_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // repeated .android.vts.TestReportMessage test_report = 2; + public static final int TEST_REPORT_FIELD_NUMBER = 2; + private java.util.List<com.android.vts.proto.VtsReportMessage.TestReportMessage> testReport_; + /** + * <code>repeated .android.vts.TestReportMessage test_report = 2;</code> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.TestReportMessage> getTestReportList() { + return testReport_; + } + /** + * <code>repeated .android.vts.TestReportMessage test_report = 2;</code> + */ + public java.util.List<? extends com.android.vts.proto.VtsReportMessage.TestReportMessageOrBuilder> + getTestReportOrBuilderList() { + return testReport_; + } + /** + * <code>repeated .android.vts.TestReportMessage test_report = 2;</code> + */ + public int getTestReportCount() { + return testReport_.size(); + } + /** + * <code>repeated .android.vts.TestReportMessage test_report = 2;</code> + */ + public com.android.vts.proto.VtsReportMessage.TestReportMessage getTestReport(int index) { + return testReport_.get(index); + } + /** + * <code>repeated .android.vts.TestReportMessage test_report = 2;</code> + */ + public com.android.vts.proto.VtsReportMessage.TestReportMessageOrBuilder getTestReportOrBuilder( + int index) { + return testReport_.get(index); + } + + // repeated .android.vts.TestPlanReportMessage test_plan_report = 3; + public static final int TEST_PLAN_REPORT_FIELD_NUMBER = 3; + private java.util.List<com.android.vts.proto.VtsReportMessage.TestPlanReportMessage> testPlanReport_; + /** + * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.TestPlanReportMessage> getTestPlanReportList() { + return testPlanReport_; + } + /** + * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code> + */ + public java.util.List<? extends com.android.vts.proto.VtsReportMessage.TestPlanReportMessageOrBuilder> + getTestPlanReportOrBuilderList() { + return testPlanReport_; + } + /** + * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code> + */ + public int getTestPlanReportCount() { + return testPlanReport_.size(); + } + /** + * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code> + */ + public com.android.vts.proto.VtsReportMessage.TestPlanReportMessage getTestPlanReport(int index) { + return testPlanReport_.get(index); + } + /** + * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code> + */ + public com.android.vts.proto.VtsReportMessage.TestPlanReportMessageOrBuilder getTestPlanReportOrBuilder( + int index) { + return testPlanReport_.get(index); + } + + private void initFields() { + accessToken_ = ""; + testReport_ = java.util.Collections.emptyList(); + testPlanReport_ = java.util.Collections.emptyList(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getAccessTokenBytes()); + } + for (int i = 0; i < testReport_.size(); i++) { + output.writeMessage(2, testReport_.get(i)); + } + for (int i = 0; i < testPlanReport_.size(); i++) { + output.writeMessage(3, testPlanReport_.get(i)); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getAccessTokenBytes()); + } + for (int i = 0; i < testReport_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, testReport_.get(i)); + } + for (int i = 0; i < testPlanReport_.size(); i++) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(3, testPlanReport_.get(i)); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static com.android.vts.proto.VtsReportMessage.DashboardPostMessage parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.android.vts.proto.VtsReportMessage.DashboardPostMessage parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.DashboardPostMessage parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static com.android.vts.proto.VtsReportMessage.DashboardPostMessage parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.DashboardPostMessage parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.DashboardPostMessage parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.DashboardPostMessage parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.DashboardPostMessage parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static com.android.vts.proto.VtsReportMessage.DashboardPostMessage parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static com.android.vts.proto.VtsReportMessage.DashboardPostMessage parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(com.android.vts.proto.VtsReportMessage.DashboardPostMessage prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code android.vts.DashboardPostMessage} + * + * <pre> + * Proto wrapper for posting data to the VTS Dashboard + * </pre> + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder<Builder> + implements com.android.vts.proto.VtsReportMessage.DashboardPostMessageOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_DashboardPostMessage_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_DashboardPostMessage_fieldAccessorTable + .ensureFieldAccessorsInitialized( + com.android.vts.proto.VtsReportMessage.DashboardPostMessage.class, com.android.vts.proto.VtsReportMessage.DashboardPostMessage.Builder.class); + } + + // Construct using com.android.vts.proto.VtsReportMessage.DashboardPostMessage.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getTestReportFieldBuilder(); + getTestPlanReportFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + accessToken_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + if (testReportBuilder_ == null) { + testReport_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + } else { + testReportBuilder_.clear(); + } + if (testPlanReportBuilder_ == null) { + testPlanReport_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000004); + } else { + testPlanReportBuilder_.clear(); + } + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return com.android.vts.proto.VtsReportMessage.internal_static_android_vts_DashboardPostMessage_descriptor; + } + + public com.android.vts.proto.VtsReportMessage.DashboardPostMessage getDefaultInstanceForType() { + return com.android.vts.proto.VtsReportMessage.DashboardPostMessage.getDefaultInstance(); + } + + public com.android.vts.proto.VtsReportMessage.DashboardPostMessage build() { + com.android.vts.proto.VtsReportMessage.DashboardPostMessage result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public com.android.vts.proto.VtsReportMessage.DashboardPostMessage buildPartial() { + com.android.vts.proto.VtsReportMessage.DashboardPostMessage result = new com.android.vts.proto.VtsReportMessage.DashboardPostMessage(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.accessToken_ = accessToken_; + if (testReportBuilder_ == null) { + if (((bitField0_ & 0x00000002) == 0x00000002)) { + testReport_ = java.util.Collections.unmodifiableList(testReport_); + bitField0_ = (bitField0_ & ~0x00000002); + } + result.testReport_ = testReport_; + } else { + result.testReport_ = testReportBuilder_.build(); + } + if (testPlanReportBuilder_ == null) { + if (((bitField0_ & 0x00000004) == 0x00000004)) { + testPlanReport_ = java.util.Collections.unmodifiableList(testPlanReport_); + bitField0_ = (bitField0_ & ~0x00000004); + } + result.testPlanReport_ = testPlanReport_; + } else { + result.testPlanReport_ = testPlanReportBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof com.android.vts.proto.VtsReportMessage.DashboardPostMessage) { + return mergeFrom((com.android.vts.proto.VtsReportMessage.DashboardPostMessage)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(com.android.vts.proto.VtsReportMessage.DashboardPostMessage other) { + if (other == com.android.vts.proto.VtsReportMessage.DashboardPostMessage.getDefaultInstance()) return this; + if (other.hasAccessToken()) { + bitField0_ |= 0x00000001; + accessToken_ = other.accessToken_; + onChanged(); + } + if (testReportBuilder_ == null) { + if (!other.testReport_.isEmpty()) { + if (testReport_.isEmpty()) { + testReport_ = other.testReport_; + bitField0_ = (bitField0_ & ~0x00000002); + } else { + ensureTestReportIsMutable(); + testReport_.addAll(other.testReport_); + } + onChanged(); + } + } else { + if (!other.testReport_.isEmpty()) { + if (testReportBuilder_.isEmpty()) { + testReportBuilder_.dispose(); + testReportBuilder_ = null; + testReport_ = other.testReport_; + bitField0_ = (bitField0_ & ~0x00000002); + testReportBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getTestReportFieldBuilder() : null; + } else { + testReportBuilder_.addAllMessages(other.testReport_); + } + } + } + if (testPlanReportBuilder_ == null) { + if (!other.testPlanReport_.isEmpty()) { + if (testPlanReport_.isEmpty()) { + testPlanReport_ = other.testPlanReport_; + bitField0_ = (bitField0_ & ~0x00000004); + } else { + ensureTestPlanReportIsMutable(); + testPlanReport_.addAll(other.testPlanReport_); + } + onChanged(); + } + } else { + if (!other.testPlanReport_.isEmpty()) { + if (testPlanReportBuilder_.isEmpty()) { + testPlanReportBuilder_.dispose(); + testPlanReportBuilder_ = null; + testPlanReport_ = other.testPlanReport_; + bitField0_ = (bitField0_ & ~0x00000004); + testPlanReportBuilder_ = + com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? + getTestPlanReportFieldBuilder() : null; + } else { + testPlanReportBuilder_.addAllMessages(other.testPlanReport_); + } + } + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + com.android.vts.proto.VtsReportMessage.DashboardPostMessage parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (com.android.vts.proto.VtsReportMessage.DashboardPostMessage) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // optional string access_token = 1; + private java.lang.Object accessToken_ = ""; + /** + * <code>optional string access_token = 1;</code> + * + * <pre> + * oauth2.0 access token + * </pre> + */ + public boolean hasAccessToken() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * <code>optional string access_token = 1;</code> + * + * <pre> + * oauth2.0 access token + * </pre> + */ + public java.lang.String getAccessToken() { + java.lang.Object ref = accessToken_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + accessToken_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * <code>optional string access_token = 1;</code> + * + * <pre> + * oauth2.0 access token + * </pre> + */ + public com.google.protobuf.ByteString + getAccessTokenBytes() { + java.lang.Object ref = accessToken_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + accessToken_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * <code>optional string access_token = 1;</code> + * + * <pre> + * oauth2.0 access token + * </pre> + */ + public Builder setAccessToken( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + accessToken_ = value; + onChanged(); + return this; + } + /** + * <code>optional string access_token = 1;</code> + * + * <pre> + * oauth2.0 access token + * </pre> + */ + public Builder clearAccessToken() { + bitField0_ = (bitField0_ & ~0x00000001); + accessToken_ = getDefaultInstance().getAccessToken(); + onChanged(); + return this; + } + /** + * <code>optional string access_token = 1;</code> + * + * <pre> + * oauth2.0 access token + * </pre> + */ + public Builder setAccessTokenBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + accessToken_ = value; + onChanged(); + return this; + } + + // repeated .android.vts.TestReportMessage test_report = 2; + private java.util.List<com.android.vts.proto.VtsReportMessage.TestReportMessage> testReport_ = + java.util.Collections.emptyList(); + private void ensureTestReportIsMutable() { + if (!((bitField0_ & 0x00000002) == 0x00000002)) { + testReport_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.TestReportMessage>(testReport_); + bitField0_ |= 0x00000002; + } + } + + private com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.TestReportMessage, com.android.vts.proto.VtsReportMessage.TestReportMessage.Builder, com.android.vts.proto.VtsReportMessage.TestReportMessageOrBuilder> testReportBuilder_; + + /** + * <code>repeated .android.vts.TestReportMessage test_report = 2;</code> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.TestReportMessage> getTestReportList() { + if (testReportBuilder_ == null) { + return java.util.Collections.unmodifiableList(testReport_); + } else { + return testReportBuilder_.getMessageList(); + } + } + /** + * <code>repeated .android.vts.TestReportMessage test_report = 2;</code> + */ + public int getTestReportCount() { + if (testReportBuilder_ == null) { + return testReport_.size(); + } else { + return testReportBuilder_.getCount(); + } + } + /** + * <code>repeated .android.vts.TestReportMessage test_report = 2;</code> + */ + public com.android.vts.proto.VtsReportMessage.TestReportMessage getTestReport(int index) { + if (testReportBuilder_ == null) { + return testReport_.get(index); + } else { + return testReportBuilder_.getMessage(index); + } + } + /** + * <code>repeated .android.vts.TestReportMessage test_report = 2;</code> + */ + public Builder setTestReport( + int index, com.android.vts.proto.VtsReportMessage.TestReportMessage value) { + if (testReportBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureTestReportIsMutable(); + testReport_.set(index, value); + onChanged(); + } else { + testReportBuilder_.setMessage(index, value); + } + return this; + } + /** + * <code>repeated .android.vts.TestReportMessage test_report = 2;</code> + */ + public Builder setTestReport( + int index, com.android.vts.proto.VtsReportMessage.TestReportMessage.Builder builderForValue) { + if (testReportBuilder_ == null) { + ensureTestReportIsMutable(); + testReport_.set(index, builderForValue.build()); + onChanged(); + } else { + testReportBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.TestReportMessage test_report = 2;</code> + */ + public Builder addTestReport(com.android.vts.proto.VtsReportMessage.TestReportMessage value) { + if (testReportBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureTestReportIsMutable(); + testReport_.add(value); + onChanged(); + } else { + testReportBuilder_.addMessage(value); + } + return this; + } + /** + * <code>repeated .android.vts.TestReportMessage test_report = 2;</code> + */ + public Builder addTestReport( + int index, com.android.vts.proto.VtsReportMessage.TestReportMessage value) { + if (testReportBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureTestReportIsMutable(); + testReport_.add(index, value); + onChanged(); + } else { + testReportBuilder_.addMessage(index, value); + } + return this; + } + /** + * <code>repeated .android.vts.TestReportMessage test_report = 2;</code> + */ + public Builder addTestReport( + com.android.vts.proto.VtsReportMessage.TestReportMessage.Builder builderForValue) { + if (testReportBuilder_ == null) { + ensureTestReportIsMutable(); + testReport_.add(builderForValue.build()); + onChanged(); + } else { + testReportBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.TestReportMessage test_report = 2;</code> + */ + public Builder addTestReport( + int index, com.android.vts.proto.VtsReportMessage.TestReportMessage.Builder builderForValue) { + if (testReportBuilder_ == null) { + ensureTestReportIsMutable(); + testReport_.add(index, builderForValue.build()); + onChanged(); + } else { + testReportBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.TestReportMessage test_report = 2;</code> + */ + public Builder addAllTestReport( + java.lang.Iterable<? extends com.android.vts.proto.VtsReportMessage.TestReportMessage> values) { + if (testReportBuilder_ == null) { + ensureTestReportIsMutable(); + super.addAll(values, testReport_); + onChanged(); + } else { + testReportBuilder_.addAllMessages(values); + } + return this; + } + /** + * <code>repeated .android.vts.TestReportMessage test_report = 2;</code> + */ + public Builder clearTestReport() { + if (testReportBuilder_ == null) { + testReport_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000002); + onChanged(); + } else { + testReportBuilder_.clear(); + } + return this; + } + /** + * <code>repeated .android.vts.TestReportMessage test_report = 2;</code> + */ + public Builder removeTestReport(int index) { + if (testReportBuilder_ == null) { + ensureTestReportIsMutable(); + testReport_.remove(index); + onChanged(); + } else { + testReportBuilder_.remove(index); + } + return this; + } + /** + * <code>repeated .android.vts.TestReportMessage test_report = 2;</code> + */ + public com.android.vts.proto.VtsReportMessage.TestReportMessage.Builder getTestReportBuilder( + int index) { + return getTestReportFieldBuilder().getBuilder(index); + } + /** + * <code>repeated .android.vts.TestReportMessage test_report = 2;</code> + */ + public com.android.vts.proto.VtsReportMessage.TestReportMessageOrBuilder getTestReportOrBuilder( + int index) { + if (testReportBuilder_ == null) { + return testReport_.get(index); } else { + return testReportBuilder_.getMessageOrBuilder(index); + } + } + /** + * <code>repeated .android.vts.TestReportMessage test_report = 2;</code> + */ + public java.util.List<? extends com.android.vts.proto.VtsReportMessage.TestReportMessageOrBuilder> + getTestReportOrBuilderList() { + if (testReportBuilder_ != null) { + return testReportBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(testReport_); + } + } + /** + * <code>repeated .android.vts.TestReportMessage test_report = 2;</code> + */ + public com.android.vts.proto.VtsReportMessage.TestReportMessage.Builder addTestReportBuilder() { + return getTestReportFieldBuilder().addBuilder( + com.android.vts.proto.VtsReportMessage.TestReportMessage.getDefaultInstance()); + } + /** + * <code>repeated .android.vts.TestReportMessage test_report = 2;</code> + */ + public com.android.vts.proto.VtsReportMessage.TestReportMessage.Builder addTestReportBuilder( + int index) { + return getTestReportFieldBuilder().addBuilder( + index, com.android.vts.proto.VtsReportMessage.TestReportMessage.getDefaultInstance()); + } + /** + * <code>repeated .android.vts.TestReportMessage test_report = 2;</code> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.TestReportMessage.Builder> + getTestReportBuilderList() { + return getTestReportFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.TestReportMessage, com.android.vts.proto.VtsReportMessage.TestReportMessage.Builder, com.android.vts.proto.VtsReportMessage.TestReportMessageOrBuilder> + getTestReportFieldBuilder() { + if (testReportBuilder_ == null) { + testReportBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.TestReportMessage, com.android.vts.proto.VtsReportMessage.TestReportMessage.Builder, com.android.vts.proto.VtsReportMessage.TestReportMessageOrBuilder>( + testReport_, + ((bitField0_ & 0x00000002) == 0x00000002), + getParentForChildren(), + isClean()); + testReport_ = null; + } + return testReportBuilder_; + } + + // repeated .android.vts.TestPlanReportMessage test_plan_report = 3; + private java.util.List<com.android.vts.proto.VtsReportMessage.TestPlanReportMessage> testPlanReport_ = + java.util.Collections.emptyList(); + private void ensureTestPlanReportIsMutable() { + if (!((bitField0_ & 0x00000004) == 0x00000004)) { + testPlanReport_ = new java.util.ArrayList<com.android.vts.proto.VtsReportMessage.TestPlanReportMessage>(testPlanReport_); + bitField0_ |= 0x00000004; + } + } + + private com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.TestPlanReportMessage, com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.Builder, com.android.vts.proto.VtsReportMessage.TestPlanReportMessageOrBuilder> testPlanReportBuilder_; + + /** + * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.TestPlanReportMessage> getTestPlanReportList() { + if (testPlanReportBuilder_ == null) { + return java.util.Collections.unmodifiableList(testPlanReport_); + } else { + return testPlanReportBuilder_.getMessageList(); + } + } + /** + * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code> + */ + public int getTestPlanReportCount() { + if (testPlanReportBuilder_ == null) { + return testPlanReport_.size(); + } else { + return testPlanReportBuilder_.getCount(); + } + } + /** + * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code> + */ + public com.android.vts.proto.VtsReportMessage.TestPlanReportMessage getTestPlanReport(int index) { + if (testPlanReportBuilder_ == null) { + return testPlanReport_.get(index); + } else { + return testPlanReportBuilder_.getMessage(index); + } + } + /** + * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code> + */ + public Builder setTestPlanReport( + int index, com.android.vts.proto.VtsReportMessage.TestPlanReportMessage value) { + if (testPlanReportBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureTestPlanReportIsMutable(); + testPlanReport_.set(index, value); + onChanged(); + } else { + testPlanReportBuilder_.setMessage(index, value); + } + return this; + } + /** + * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code> + */ + public Builder setTestPlanReport( + int index, com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.Builder builderForValue) { + if (testPlanReportBuilder_ == null) { + ensureTestPlanReportIsMutable(); + testPlanReport_.set(index, builderForValue.build()); + onChanged(); + } else { + testPlanReportBuilder_.setMessage(index, builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code> + */ + public Builder addTestPlanReport(com.android.vts.proto.VtsReportMessage.TestPlanReportMessage value) { + if (testPlanReportBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureTestPlanReportIsMutable(); + testPlanReport_.add(value); + onChanged(); + } else { + testPlanReportBuilder_.addMessage(value); + } + return this; + } + /** + * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code> + */ + public Builder addTestPlanReport( + int index, com.android.vts.proto.VtsReportMessage.TestPlanReportMessage value) { + if (testPlanReportBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + ensureTestPlanReportIsMutable(); + testPlanReport_.add(index, value); + onChanged(); + } else { + testPlanReportBuilder_.addMessage(index, value); + } + return this; + } + /** + * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code> + */ + public Builder addTestPlanReport( + com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.Builder builderForValue) { + if (testPlanReportBuilder_ == null) { + ensureTestPlanReportIsMutable(); + testPlanReport_.add(builderForValue.build()); + onChanged(); + } else { + testPlanReportBuilder_.addMessage(builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code> + */ + public Builder addTestPlanReport( + int index, com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.Builder builderForValue) { + if (testPlanReportBuilder_ == null) { + ensureTestPlanReportIsMutable(); + testPlanReport_.add(index, builderForValue.build()); + onChanged(); + } else { + testPlanReportBuilder_.addMessage(index, builderForValue.build()); + } + return this; + } + /** + * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code> + */ + public Builder addAllTestPlanReport( + java.lang.Iterable<? extends com.android.vts.proto.VtsReportMessage.TestPlanReportMessage> values) { + if (testPlanReportBuilder_ == null) { + ensureTestPlanReportIsMutable(); + super.addAll(values, testPlanReport_); + onChanged(); + } else { + testPlanReportBuilder_.addAllMessages(values); + } + return this; + } + /** + * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code> + */ + public Builder clearTestPlanReport() { + if (testPlanReportBuilder_ == null) { + testPlanReport_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000004); + onChanged(); + } else { + testPlanReportBuilder_.clear(); + } + return this; + } + /** + * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code> + */ + public Builder removeTestPlanReport(int index) { + if (testPlanReportBuilder_ == null) { + ensureTestPlanReportIsMutable(); + testPlanReport_.remove(index); + onChanged(); + } else { + testPlanReportBuilder_.remove(index); + } + return this; + } + /** + * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code> + */ + public com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.Builder getTestPlanReportBuilder( + int index) { + return getTestPlanReportFieldBuilder().getBuilder(index); + } + /** + * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code> + */ + public com.android.vts.proto.VtsReportMessage.TestPlanReportMessageOrBuilder getTestPlanReportOrBuilder( + int index) { + if (testPlanReportBuilder_ == null) { + return testPlanReport_.get(index); } else { + return testPlanReportBuilder_.getMessageOrBuilder(index); + } + } + /** + * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code> + */ + public java.util.List<? extends com.android.vts.proto.VtsReportMessage.TestPlanReportMessageOrBuilder> + getTestPlanReportOrBuilderList() { + if (testPlanReportBuilder_ != null) { + return testPlanReportBuilder_.getMessageOrBuilderList(); + } else { + return java.util.Collections.unmodifiableList(testPlanReport_); + } + } + /** + * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code> + */ + public com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.Builder addTestPlanReportBuilder() { + return getTestPlanReportFieldBuilder().addBuilder( + com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.getDefaultInstance()); + } + /** + * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code> + */ + public com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.Builder addTestPlanReportBuilder( + int index) { + return getTestPlanReportFieldBuilder().addBuilder( + index, com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.getDefaultInstance()); + } + /** + * <code>repeated .android.vts.TestPlanReportMessage test_plan_report = 3;</code> + */ + public java.util.List<com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.Builder> + getTestPlanReportBuilderList() { + return getTestPlanReportFieldBuilder().getBuilderList(); + } + private com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.TestPlanReportMessage, com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.Builder, com.android.vts.proto.VtsReportMessage.TestPlanReportMessageOrBuilder> + getTestPlanReportFieldBuilder() { + if (testPlanReportBuilder_ == null) { + testPlanReportBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< + com.android.vts.proto.VtsReportMessage.TestPlanReportMessage, com.android.vts.proto.VtsReportMessage.TestPlanReportMessage.Builder, com.android.vts.proto.VtsReportMessage.TestPlanReportMessageOrBuilder>( + testPlanReport_, + ((bitField0_ & 0x00000004) == 0x00000004), + getParentForChildren(), + isClean()); + testPlanReport_ = null; + } + return testPlanReportBuilder_; + } + + // @@protoc_insertion_point(builder_scope:android.vts.DashboardPostMessage) + } + + static { + defaultInstance = new DashboardPostMessage(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:android.vts.DashboardPostMessage) + } + + private static com.google.protobuf.Descriptors.Descriptor + internal_static_android_vts_AndroidDeviceInfoMessage_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_android_vts_AndroidDeviceInfoMessage_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_android_vts_AndroidBuildInfo_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_android_vts_AndroidBuildInfo_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_android_vts_VtsHostInfo_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_android_vts_VtsHostInfo_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_android_vts_TestCaseReportMessage_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_android_vts_TestCaseReportMessage_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_android_vts_ProfilingReportMessage_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_android_vts_ProfilingReportMessage_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_android_vts_SystraceReportMessage_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_android_vts_SystraceReportMessage_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_android_vts_CoverageReportMessage_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_android_vts_CoverageReportMessage_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_android_vts_LogMessage_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_android_vts_LogMessage_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_android_vts_UrlResourceMessage_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_android_vts_UrlResourceMessage_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_android_vts_TestReportMessage_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_android_vts_TestReportMessage_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_android_vts_TestPlanReportMessage_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_android_vts_TestPlanReportMessage_fieldAccessorTable; + private static com.google.protobuf.Descriptors.Descriptor + internal_static_android_vts_DashboardPostMessage_descriptor; + private static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_android_vts_DashboardPostMessage_fieldAccessorTable; + + public static com.google.protobuf.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + private static com.google.protobuf.Descriptors.FileDescriptor + descriptor; + static { + java.lang.String[] descriptorData = { + "\n\034proto/VtsReportMessage.proto\022\013android." + + "vts\"\340\001\n\030AndroidDeviceInfoMessage\022\024\n\014prod" + + "uct_type\030\001 \001(\014\022\027\n\017product_variant\030\002 \001(\014\022" + + "\024\n\014build_flavor\030\013 \001(\014\022\020\n\010build_id\030\014 \001(\014\022" + + "\016\n\006branch\030\025 \001(\014\022\023\n\013build_alias\030\026 \001(\014\022\021\n\t" + + "api_level\030\037 \001(\014\022\020\n\010abi_name\0303 \001(\014\022\023\n\013abi" + + "_bitness\0304 \001(\014\022\016\n\006serial\030e \001(\014\"g\n\020Androi" + + "dBuildInfo\022\n\n\002id\030\001 \001(\014\022\014\n\004name\030\013 \001(\014\022\022\n\n" + + "build_type\030\014 \001(\014\022\016\n\006branch\030\r \001(\014\022\025\n\rbuil" + + "d_summary\030\025 \001(\014\"\037\n\013VtsHostInfo\022\020\n\010hostna", + "me\030\001 \001(\014\"\321\002\n\025TestCaseReportMessage\022\014\n\004na" + + "me\030\001 \001(\014\0220\n\013test_result\030\013 \001(\0162\033.android." + + "vts.TestCaseResult\022\027\n\017start_timestamp\030\025 " + + "\001(\003\022\025\n\rend_timestamp\030\026 \001(\003\0224\n\010coverage\030\037" + + " \003(\0132\".android.vts.CoverageReportMessage" + + "\0226\n\tprofiling\030) \003(\0132#.android.vts.Profil" + + "ingReportMessage\0224\n\010systrace\030* \003(\0132\".and" + + "roid.vts.SystraceReportMessage\022$\n\003log\030e " + + "\003(\0132\027.android.vts.LogMessage\"\240\002\n\026Profili" + + "ngReportMessage\022\014\n\004name\030\001 \001(\014\022+\n\004type\030\002 ", + "\001(\0162\035.android.vts.VtsProfilingType\022@\n\017re" + + "gression_mode\030\003 \001(\0162\'.android.vts.VtsPro" + + "filingRegressionMode\022\027\n\017start_timestamp\030" + + "\013 \001(\003\022\025\n\rend_timestamp\030\014 \001(\003\022\r\n\005label\030\025 " + + "\003(\014\022\r\n\005value\030\026 \003(\003\022\024\n\014x_axis_label\030\037 \001(\014" + + "\022\024\n\014y_axis_label\030 \001(\014\022\017\n\007options\030) \003(\014\"" + + "H\n\025SystraceReportMessage\022\024\n\014process_name" + + "\030\001 \001(\014\022\014\n\004html\030\013 \003(\014\022\013\n\003url\030\025 \003(\014\"\345\001\n\025Co" + + "verageReportMessage\022\021\n\tfile_path\030\013 \001(\014\022\024" + + "\n\014project_name\030\014 \001(\014\022\020\n\010revision\030\r \001(\014\022\034", + "\n\024line_coverage_vector\030\027 \003(\005\022\030\n\020total_li" + + "ne_count\030e \001(\005\022\032\n\022covered_line_count\030f \001" + + "(\005\022\024\n\010dir_path\030\001 \001(\014B\002\030\001\022\025\n\tfile_name\030\002 " + + "\001(\014B\002\030\001\022\020\n\004html\030\003 \001(\014B\002\030\001\"8\n\nLogMessage\022" + + "\013\n\003url\030\001 \001(\014\022\014\n\004name\030\002 \001(\014\022\017\n\007content\030\003 " + + "\001(\014\"@\n\022UrlResourceMessage\022\013\n\003url\030\001 \001(\014\022\014" + + "\n\004name\030\002 \001(\014\022\017\n\007content\030\003 \001(\014\"\316\004\n\021TestRe" + + "portMessage\022\026\n\ntest_suite\030\001 \001(\014B\002\030\001\022\014\n\004t" + + "est\030\002 \001(\014\022+\n\ttest_type\030\003 \001(\0162\030.android.v" + + "ts.VtsTestType\022:\n\013device_info\030\004 \003(\0132%.an", + "droid.vts.AndroidDeviceInfoMessage\0221\n\nbu" + + "ild_info\030\005 \001(\0132\035.android.vts.AndroidBuil" + + "dInfo\022\030\n\020subscriber_email\030\006 \003(\014\022+\n\thost_" + + "info\030\007 \001(\0132\030.android.vts.VtsHostInfo\0225\n\t" + + "test_case\030\013 \003(\0132\".android.vts.TestCaseRe" + + "portMessage\0226\n\tprofiling\030\025 \003(\0132#.android" + + ".vts.ProfilingReportMessage\0224\n\010systrace\030" + + "\026 \003(\0132\".android.vts.SystraceReportMessag" + + "e\022\027\n\017start_timestamp\030e \001(\003\022\025\n\rend_timest" + + "amp\030f \001(\003\0224\n\010coverage\030g \003(\0132\".android.vt", + "s.CoverageReportMessage\022%\n\003log\030\351\007 \003(\0132\027." + + "android.vts.LogMessage\"\247\001\n\025TestPlanRepor" + + "tMessage\022\030\n\020test_module_name\030\013 \003(\t\022#\n\033te" + + "st_module_start_timestamp\030\014 \003(\003\022\026\n\016test_" + + "plan_name\030\025 \001(\t\0227\n\016partner_report\030\037 \003(\0132" + + "\037.android.vts.UrlResourceMessage\"\237\001\n\024Das" + + "hboardPostMessage\022\024\n\014access_token\030\001 \001(\t\022" + + "3\n\013test_report\030\002 \003(\0132\036.android.vts.TestR" + + "eportMessage\022<\n\020test_plan_report\030\003 \003(\0132\"" + + ".android.vts.TestPlanReportMessage*\263\001\n\016T", + "estCaseResult\022\022\n\016UNKNOWN_RESULT\020\000\022\031\n\025TES" + + "T_CASE_RESULT_PASS\020\001\022\031\n\025TEST_CASE_RESULT" + + "_FAIL\020\002\022\031\n\025TEST_CASE_RESULT_SKIP\020\003\022\036\n\032TE" + + "ST_CASE_RESULT_EXCEPTION\020\004\022\034\n\030TEST_CASE_" + + "RESULT_TIMEOUT\020\005*\234\001\n\013VtsTestType\022\030\n\024UNKN" + + "OWN_VTS_TESTTYPE\020\000\022\036\n\032VTS_HOST_DRIVEN_ST" + + "RUCTURAL\020\001\022\033\n\027VTS_HOST_DRIVEN_FUZZING\020\002\022" + + "\031\n\025VTS_TARGET_SIDE_GTEST\020\003\022\033\n\027VTS_TARGET" + + "_SIDE_FUZZING\020\004*\243\001\n\032VtsProfilingRegressi" + + "onMode\022\033\n\027UNKNOWN_REGRESSION_MODE\020\000\022 \n\034V", + "TS_REGRESSION_MODE_DISABLED\020\001\022\"\n\036VTS_REG" + + "RESSION_MODE_INCREASING\020\002\022\"\n\036VTS_REGRESS" + + "ION_MODE_DECREASING\020\003*\244\001\n\020VtsProfilingTy" + + "pe\022\036\n\032UNKNOWN_VTS_PROFILING_TYPE\020\000\022 \n\034VT" + + "S_PROFILING_TYPE_TIMESTAMP\020\001\022%\n!VTS_PROF" + + "ILING_TYPE_LABELED_VECTOR\020\002\022\'\n#VTS_PROFI" + + "LING_TYPE_UNLABELED_VECTOR\020\003B+\n\025com.andr" + + "oid.vts.protoB\020VtsReportMessageP\000" + }; + com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = + new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { + public com.google.protobuf.ExtensionRegistry assignDescriptors( + com.google.protobuf.Descriptors.FileDescriptor root) { + descriptor = root; + internal_static_android_vts_AndroidDeviceInfoMessage_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_android_vts_AndroidDeviceInfoMessage_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_android_vts_AndroidDeviceInfoMessage_descriptor, + new java.lang.String[] { "ProductType", "ProductVariant", "BuildFlavor", "BuildId", "Branch", "BuildAlias", "ApiLevel", "AbiName", "AbiBitness", "Serial", }); + internal_static_android_vts_AndroidBuildInfo_descriptor = + getDescriptor().getMessageTypes().get(1); + internal_static_android_vts_AndroidBuildInfo_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_android_vts_AndroidBuildInfo_descriptor, + new java.lang.String[] { "Id", "Name", "BuildType", "Branch", "BuildSummary", }); + internal_static_android_vts_VtsHostInfo_descriptor = + getDescriptor().getMessageTypes().get(2); + internal_static_android_vts_VtsHostInfo_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_android_vts_VtsHostInfo_descriptor, + new java.lang.String[] { "Hostname", }); + internal_static_android_vts_TestCaseReportMessage_descriptor = + getDescriptor().getMessageTypes().get(3); + internal_static_android_vts_TestCaseReportMessage_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_android_vts_TestCaseReportMessage_descriptor, + new java.lang.String[] { "Name", "TestResult", "StartTimestamp", "EndTimestamp", "Coverage", "Profiling", "Systrace", "Log", }); + internal_static_android_vts_ProfilingReportMessage_descriptor = + getDescriptor().getMessageTypes().get(4); + internal_static_android_vts_ProfilingReportMessage_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_android_vts_ProfilingReportMessage_descriptor, + new java.lang.String[] { "Name", "Type", "RegressionMode", "StartTimestamp", "EndTimestamp", "Label", "Value", "XAxisLabel", "YAxisLabel", "Options", }); + internal_static_android_vts_SystraceReportMessage_descriptor = + getDescriptor().getMessageTypes().get(5); + internal_static_android_vts_SystraceReportMessage_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_android_vts_SystraceReportMessage_descriptor, + new java.lang.String[] { "ProcessName", "Html", "Url", }); + internal_static_android_vts_CoverageReportMessage_descriptor = + getDescriptor().getMessageTypes().get(6); + internal_static_android_vts_CoverageReportMessage_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_android_vts_CoverageReportMessage_descriptor, + new java.lang.String[] { "FilePath", "ProjectName", "Revision", "LineCoverageVector", "TotalLineCount", "CoveredLineCount", "DirPath", "FileName", "Html", }); + internal_static_android_vts_LogMessage_descriptor = + getDescriptor().getMessageTypes().get(7); + internal_static_android_vts_LogMessage_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_android_vts_LogMessage_descriptor, + new java.lang.String[] { "Url", "Name", "Content", }); + internal_static_android_vts_UrlResourceMessage_descriptor = + getDescriptor().getMessageTypes().get(8); + internal_static_android_vts_UrlResourceMessage_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_android_vts_UrlResourceMessage_descriptor, + new java.lang.String[] { "Url", "Name", "Content", }); + internal_static_android_vts_TestReportMessage_descriptor = + getDescriptor().getMessageTypes().get(9); + internal_static_android_vts_TestReportMessage_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_android_vts_TestReportMessage_descriptor, + new java.lang.String[] { "TestSuite", "Test", "TestType", "DeviceInfo", "BuildInfo", "SubscriberEmail", "HostInfo", "TestCase", "Profiling", "Systrace", "StartTimestamp", "EndTimestamp", "Coverage", "Log", }); + internal_static_android_vts_TestPlanReportMessage_descriptor = + getDescriptor().getMessageTypes().get(10); + internal_static_android_vts_TestPlanReportMessage_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_android_vts_TestPlanReportMessage_descriptor, + new java.lang.String[] { "TestModuleName", "TestModuleStartTimestamp", "TestPlanName", "PartnerReport", }); + internal_static_android_vts_DashboardPostMessage_descriptor = + getDescriptor().getMessageTypes().get(11); + internal_static_android_vts_DashboardPostMessage_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_android_vts_DashboardPostMessage_descriptor, + new java.lang.String[] { "AccessToken", "TestReport", "TestPlanReport", }); + return null; + } + }; + com.google.protobuf.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + }, assigner); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/src/main/java/com/android/vts/servlet/BaseServlet.java b/src/main/java/com/android/vts/servlet/BaseServlet.java new file mode 100644 index 0000000..3fdca0a --- /dev/null +++ b/src/main/java/com/android/vts/servlet/BaseServlet.java @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.servlet; + +import com.google.appengine.api.users.User; +import com.google.appengine.api.users.UserService; +import com.google.appengine.api.users.UserServiceFactory; +import com.google.gson.Gson; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Logger; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public abstract class BaseServlet extends HttpServlet { + protected final Logger logger = Logger.getLogger(getClass().getName()); + + // Environment variables + protected static final String GERRIT_URI = System.getProperty("GERRIT_URI"); + protected static final String GERRIT_SCOPE = System.getProperty("GERRIT_SCOPE"); + protected static final String CLIENT_ID = System.getProperty("CLIENT_ID"); + protected static final String ANALYTICS_ID = System.getProperty("ANALYTICS_ID"); + + public enum PageType { + TOT("ToT", "/"), + RELEASE("Release", "/show_release"), + COVERAGE_OVERVIEW("Coverage", "/show_coverage_overview"), + TABLE("", "/show_table"), + TREE("", "/show_tree"), + GRAPH("Profiling", "/show_graph"), + COVERAGE("Coverage", "/show_coverage"), + PERFORMANCE("Performance Digest", "/show_performance_digest"), + PLAN_RELEASE("", "/show_plan_release"), + PLAN_RUN("Plan Run", "/show_plan_run"); + + public final String defaultName; + public final String defaultUrl; + + PageType(String defaultName, String defaultUrl) { + this.defaultName = defaultName; + this.defaultUrl = defaultUrl; + } + } + + public static class Page { + private final PageType type; + private final String name; + private final String url; + + public Page(PageType type) { + this.type = type; + this.name = type.defaultName; + this.url = type.defaultUrl; + } + + public Page(PageType type, String name, String url) { + this.type = type; + this.name = type.defaultName + name; + this.url = type.defaultUrl + url; + } + + public Page(PageType type, String url) { + this.type = type; + this.name = type.defaultName; + this.url = type.defaultUrl + url; + } + + public String getName() { + return name; + } + + public String getUrl() { + return url; + } + } + + public static final List<Page> navbarLinks; + + static { + List<Page> links = new ArrayList<>(); + links.add(new Page(PageType.TOT)); + links.add(new Page(PageType.RELEASE)); + links.add(new Page(PageType.COVERAGE_OVERVIEW)); + navbarLinks = links; + } + + public abstract PageType getNavParentType(); + + /** + * Get a list of URL/Display name pairs for the breadcrumb hierarchy. + * + * @param request The HttpServletRequest object for the page request. + * @return a list of Page entries. + */ + public abstract List<Page> getBreadcrumbLinks(HttpServletRequest request); + + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { + // If the user is logged out, allow them to log back in and return to the page. + // Set the logout URL to direct back to a login page that directs to the current request. + UserService userService = UserServiceFactory.getUserService(); + User currentUser = userService.getCurrentUser(); + String requestUri = request.getRequestURI(); + String requestArgs = request.getQueryString(); + String loginURI = userService.createLoginURL(requestUri + '?' + requestArgs); + String logoutURI = userService.createLogoutURL(loginURI); + if (currentUser == null || currentUser.getEmail() == null) { + response.sendRedirect(loginURI); + return; + } + PageType parentType = getNavParentType(); + int activeIndex; + switch (getNavParentType()) { + case COVERAGE_OVERVIEW: + activeIndex = 2; + break; + case RELEASE: + activeIndex = 1; + break; + default: + activeIndex = 0; + break; + } + request.setAttribute("logoutURL", logoutURI); + request.setAttribute("email", currentUser.getEmail()); + request.setAttribute("analyticsID", new Gson().toJson(ANALYTICS_ID)); + request.setAttribute("breadcrumbLinks", getBreadcrumbLinks(request)); + request.setAttribute("navbarLinks", navbarLinks); + request.setAttribute("activeIndex", activeIndex); + response.setContentType("text/html"); + doGetHandler(request, response); + } + + /** + * Implementation of the doGet method to be executed by servlet subclasses. + * + * @param request The HttpServletRequest object. + * @param response The HttpServletResponse object. + * @throws IOException + */ + public abstract void doGetHandler(HttpServletRequest request, HttpServletResponse response) + throws IOException; +} diff --git a/src/main/java/com/android/vts/servlet/DashboardMainServlet.java b/src/main/java/com/android/vts/servlet/DashboardMainServlet.java new file mode 100644 index 0000000..3766664 --- /dev/null +++ b/src/main/java/com/android/vts/servlet/DashboardMainServlet.java @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.servlet; + +import com.android.vts.entity.TestEntity; +import com.android.vts.entity.UserFavoriteEntity; +import com.google.appengine.api.datastore.DatastoreService; +import com.google.appengine.api.datastore.DatastoreServiceFactory; +import com.google.appengine.api.datastore.Entity; +import com.google.appengine.api.datastore.Key; +import com.google.appengine.api.datastore.KeyFactory; +import com.google.appengine.api.datastore.PropertyProjection; +import com.google.appengine.api.datastore.Query; +import com.google.appengine.api.datastore.Query.Filter; +import com.google.appengine.api.datastore.Query.FilterOperator; +import com.google.appengine.api.datastore.Query.FilterPredicate; +import com.google.appengine.api.users.User; +import com.google.appengine.api.users.UserService; +import com.google.appengine.api.users.UserServiceFactory; +import com.google.gson.Gson; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** Represents the servlet that is invoked on loading the first page of dashboard. */ +public class DashboardMainServlet extends BaseServlet { + private static final String DASHBOARD_MAIN_JSP = "WEB-INF/jsp/dashboard_main.jsp"; + private static final String DASHBOARD_ALL_LINK = "/?showAll=true"; + private static final String DASHBOARD_FAVORITES_LINK = "/"; + private static final String ALL_HEADER = "All Tests"; + private static final String FAVORITES_HEADER = "Favorites"; + private static final String NO_TESTS_ERROR = "No test results available."; + private static final String FAVORITES_BUTTON = "Show Favorites"; + private static final String ALL_BUTTON = "Show All"; + private static final String UP_ARROW = "keyboard_arrow_up"; + private static final String DOWN_ARROW = "keyboard_arrow_down"; + + @Override + public PageType getNavParentType() { + return PageType.TOT; + } + + @Override + public List<Page> getBreadcrumbLinks(HttpServletRequest request) { + return null; + } + + /** Helper class for displaying test entries on the main dashboard. */ + public class TestDisplay implements Comparable<TestDisplay> { + private final Key testKey; + private final int passCount; + private final int failCount; + + /** + * Test display constructor. + * + * @param testKey The key of the test. + * @param passCount The number of tests passing. + * @param failCount The number of tests failing. + */ + public TestDisplay(Key testKey, int passCount, int failCount) { + this.testKey = testKey; + this.passCount = passCount; + this.failCount = failCount; + } + + /** + * Get the key of the test. + * + * @return The key of the test. + */ + public String getName() { + return this.testKey.getName(); + } + + /** + * Get the number of passing test cases. + * + * @return The number of passing test cases. + */ + public int getPassCount() { + return this.passCount; + } + + /** + * Get the number of failing test cases. + * + * @return The number of failing test cases. + */ + public int getFailCount() { + return this.failCount; + } + + @Override + public int compareTo(TestDisplay test) { + return this.testKey.getName().compareTo(test.getName()); + } + } + + @Override + public void doGetHandler(HttpServletRequest request, HttpServletResponse response) + throws IOException { + UserService userService = UserServiceFactory.getUserService(); + User currentUser = userService.getCurrentUser(); + RequestDispatcher dispatcher = null; + DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); + + List<TestDisplay> displayedTests = new ArrayList<>(); + List<String> allTests = new ArrayList<>(); + + Map<Key, TestDisplay> testMap = new HashMap<>(); // map from table key to TestDisplay + Map<String, String> subscriptionMap = new HashMap<>(); + + boolean showAll = request.getParameter("showAll") != null; + String header; + String buttonLabel; + String buttonIcon; + String buttonLink; + String error = null; + + Query q = new Query(TestEntity.KIND) + .addProjection(new PropertyProjection(TestEntity.PASS_COUNT, Long.class)) + .addProjection(new PropertyProjection(TestEntity.FAIL_COUNT, Long.class)); + for (Entity test : datastore.prepare(q).asIterable()) { + TestEntity testEntity = TestEntity.fromEntity(test); + if (test != null) { + TestDisplay display = + new TestDisplay(test.getKey(), testEntity.passCount, testEntity.failCount); + testMap.put(test.getKey(), display); + allTests.add(test.getKey().getName()); + } + } + + if (testMap.size() == 0) { + error = NO_TESTS_ERROR; + } + + if (showAll) { + for (Key testKey : testMap.keySet()) { + displayedTests.add(testMap.get(testKey)); + } + header = ALL_HEADER; + buttonLabel = FAVORITES_BUTTON; + buttonIcon = UP_ARROW; + buttonLink = DASHBOARD_FAVORITES_LINK; + } else { + if (testMap.size() > 0) { + Filter userFilter = new FilterPredicate( + UserFavoriteEntity.USER, FilterOperator.EQUAL, currentUser); + q = new Query(UserFavoriteEntity.KIND).setFilter(userFilter); + + for (Entity favorite : datastore.prepare(q).asIterable()) { + Key testKey = (Key) favorite.getProperty(UserFavoriteEntity.TEST_KEY); + if (!testMap.containsKey(testKey)) { + continue; + } + displayedTests.add(testMap.get(testKey)); + subscriptionMap.put( + testKey.getName(), KeyFactory.keyToString(favorite.getKey())); + } + } + header = FAVORITES_HEADER; + buttonLabel = ALL_BUTTON; + buttonIcon = DOWN_ARROW; + buttonLink = DASHBOARD_ALL_LINK; + } + Collections.sort(displayedTests); + + response.setStatus(HttpServletResponse.SC_OK); + request.setAttribute("allTestsJson", new Gson().toJson(allTests)); + request.setAttribute("subscriptionMapJson", new Gson().toJson(subscriptionMap)); + request.setAttribute("testNames", displayedTests); + request.setAttribute("headerLabel", header); + request.setAttribute("showAll", showAll); + request.setAttribute("buttonLabel", buttonLabel); + request.setAttribute("buttonIcon", buttonIcon); + request.setAttribute("buttonLink", buttonLink); + request.setAttribute("error", error); + dispatcher = request.getRequestDispatcher(DASHBOARD_MAIN_JSP); + try { + dispatcher.forward(request, response); + } catch (ServletException e) { + logger.log(Level.SEVERE, "Servlet Excpetion caught : ", e); + } + } +} diff --git a/src/main/java/com/android/vts/servlet/ShowCoverageOverviewServlet.java b/src/main/java/com/android/vts/servlet/ShowCoverageOverviewServlet.java new file mode 100644 index 0000000..dac864f --- /dev/null +++ b/src/main/java/com/android/vts/servlet/ShowCoverageOverviewServlet.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2017 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.servlet; + +import com.android.vts.entity.TestEntity; +import com.android.vts.entity.TestRunEntity; +import com.android.vts.proto.VtsReportMessage; +import com.android.vts.util.TestRunMetadata; +import com.google.appengine.api.datastore.DatastoreService; +import com.google.appengine.api.datastore.DatastoreServiceFactory; +import com.google.appengine.api.datastore.Entity; +import com.google.appengine.api.datastore.FetchOptions; +import com.google.appengine.api.datastore.Key; +import com.google.appengine.api.datastore.Query; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** Represents the servlet that is invoked on loading the coverage overview page. */ +public class ShowCoverageOverviewServlet extends BaseServlet { + private static final String COVERAGE_OVERVIEW_JSP = "WEB-INF/jsp/show_coverage_overview.jsp"; + + @Override + public PageType getNavParentType() { + return PageType.COVERAGE_OVERVIEW; + } + + @Override + public List<Page> getBreadcrumbLinks(HttpServletRequest request) { + return null; + } + + @Override + public void doGetHandler(HttpServletRequest request, HttpServletResponse response) + throws IOException { + RequestDispatcher dispatcher = null; + DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); + + Query q = new Query(TestEntity.KIND).setKeysOnly(); + List<Key> allTests = new ArrayList<>(); + for (Entity test : datastore.prepare(q).asIterable()) { + allTests.add(test.getKey()); + } + + // Add test names to list + List<String> resultNames = new ArrayList<>(); + for (VtsReportMessage.TestCaseResult r : VtsReportMessage.TestCaseResult.values()) { + resultNames.add(r.name()); + } + + List<JsonObject> testRunObjects = new ArrayList<>(); + + Query.Filter coverageFilter = new Query.FilterPredicate( + TestRunEntity.HAS_COVERAGE, Query.FilterOperator.EQUAL, true); + int coveredLines = 0; + int uncoveredLines = 0; + int passCount = 0; + int failCount = 0; + for (Key key : allTests) { + Query testRunQuery = + new Query(TestRunEntity.KIND) + .setAncestor(key) + .setFilter(coverageFilter) + .addSort(Entity.KEY_RESERVED_PROPERTY, Query.SortDirection.DESCENDING); + for (Entity testRunEntity : + datastore.prepare(testRunQuery).asIterable(FetchOptions.Builder.withLimit(1))) { + TestRunEntity testRun = TestRunEntity.fromEntity(testRunEntity); + if (testRun == null) + continue; + TestRunMetadata metadata = new TestRunMetadata(key.getName(), testRun); + testRunObjects.add(metadata.toJson()); + coveredLines += testRun.coveredLineCount; + uncoveredLines += testRun.totalLineCount - testRun.coveredLineCount; + passCount += testRun.passCount; + failCount += testRun.failCount; + } + } + + int[] testStats = new int[VtsReportMessage.TestCaseResult.values().length]; + testStats[VtsReportMessage.TestCaseResult.TEST_CASE_RESULT_PASS.getNumber()] = passCount; + testStats[VtsReportMessage.TestCaseResult.TEST_CASE_RESULT_FAIL.getNumber()] = failCount; + + response.setStatus(HttpServletResponse.SC_OK); + request.setAttribute("resultNames", resultNames); + request.setAttribute("resultNamesJson", new Gson().toJson(resultNames)); + request.setAttribute("testRuns", new Gson().toJson(testRunObjects)); + request.setAttribute("coveredLines", new Gson().toJson(coveredLines)); + request.setAttribute("uncoveredLines", new Gson().toJson(uncoveredLines)); + request.setAttribute("testStats", new Gson().toJson(testStats)); + dispatcher = request.getRequestDispatcher(COVERAGE_OVERVIEW_JSP); + try { + dispatcher.forward(request, response); + } catch (ServletException e) { + logger.log(Level.SEVERE, "Servlet Exception caught : ", e); + } + } +} diff --git a/src/main/java/com/android/vts/servlet/ShowCoverageServlet.java b/src/main/java/com/android/vts/servlet/ShowCoverageServlet.java new file mode 100644 index 0000000..9efe7f8 --- /dev/null +++ b/src/main/java/com/android/vts/servlet/ShowCoverageServlet.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.servlet; + +import com.android.vts.entity.CoverageEntity; +import com.android.vts.entity.TestEntity; +import com.android.vts.entity.TestRunEntity; +import com.google.appengine.api.datastore.DatastoreService; +import com.google.appengine.api.datastore.DatastoreServiceFactory; +import com.google.appengine.api.datastore.Entity; +import com.google.appengine.api.datastore.Key; +import com.google.appengine.api.datastore.KeyFactory; +import com.google.appengine.api.datastore.Query; +import com.google.gson.Gson; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** Servlet for handling requests to show code coverage. */ +public class ShowCoverageServlet extends BaseServlet { + private static final String COVERAGE_JSP = "WEB-INF/jsp/show_coverage.jsp"; + + @Override + public PageType getNavParentType() { + return PageType.TOT; + } + + @Override + public List<Page> getBreadcrumbLinks(HttpServletRequest request) { + List<Page> links = new ArrayList<>(); + String testName = request.getParameter("testName"); + links.add(new Page(PageType.TABLE, testName, "?testName=" + testName)); + + String startTime = request.getParameter("startTime"); + links.add(new Page(PageType.COVERAGE, "?testName=" + testName + "&startTime=" + startTime)); + return links; + } + + @Override + public void doGetHandler(HttpServletRequest request, HttpServletResponse response) + throws IOException { + RequestDispatcher dispatcher = null; + DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); + String test = request.getParameter("testName"); + String timeString = request.getParameter("startTime"); + + // Process the time key requested + long time = -1; + try { + time = Long.parseLong(timeString); + } catch (NumberFormatException e) { + request.setAttribute("testName", test); + dispatcher = request.getRequestDispatcher("/show_table.jsp"); + return; + } + + // Compute the parent test run key based off of the test and time + Key testKey = KeyFactory.createKey(TestEntity.KIND, test); + Key testRunKey = KeyFactory.createKey(testKey, TestRunEntity.KIND, time); + + // Create a query for coverage entities + Query coverageQuery = new Query(CoverageEntity.KIND).setAncestor(testRunKey); + + List<String> sourceFiles = new ArrayList<>(); // list of source files + List<List<Long>> coverageVectors = new ArrayList<>(); // list of line coverage vectors + List<String> projects = new ArrayList<>(); // list of project names + List<String> commits = new ArrayList<>(); // list of project commit hashes + List<String> indicators = new ArrayList<>(); // list of HTML indicates to display + + /* + * Map from section name to a list of indexes into the above lists where each coverage + * report's data is located. + */ + Map<String, List<Integer>> sectionMap = new HashMap<>(); + for (Entity e : datastore.prepare(coverageQuery).asIterable()) { + CoverageEntity coverageEntity = CoverageEntity.fromEntity(e); + if (coverageEntity == null) { + logger.log(Level.WARNING, "Invalid coverage entity: " + e.getKey()); + continue; + } + if (!sectionMap.containsKey(coverageEntity.group)) { + sectionMap.put(coverageEntity.group, new ArrayList<Integer>()); + } + sectionMap.get(coverageEntity.group).add(coverageVectors.size()); + coverageVectors.add(coverageEntity.lineCoverage); + sourceFiles.add(coverageEntity.filePath); + projects.add(coverageEntity.projectName); + commits.add(coverageEntity.projectVersion); + String indicator = ""; + long total = coverageEntity.totalLineCount; + long covered = coverageEntity.coveredLineCount; + if (total > 0) { + double pct = Math.round(covered * 10000d / total) / 100d; + String color = pct >= 70 ? "green" : "red"; + indicator = "<div class=\"right indicator " + color + "\">" + pct + "%</div>" + + "<span class=\"right total-count\">" + covered + "/" + total + "</span>"; + } + indicators.add(indicator); + } + + request.setAttribute("testName", request.getParameter("testName")); + request.setAttribute("gerritURI", new Gson().toJson(GERRIT_URI)); + request.setAttribute("gerritScope", new Gson().toJson(GERRIT_SCOPE)); + request.setAttribute("clientId", new Gson().toJson(CLIENT_ID)); + request.setAttribute("coverageVectors", new Gson().toJson(coverageVectors)); + request.setAttribute("sourceFiles", new Gson().toJson(sourceFiles)); + request.setAttribute("projects", new Gson().toJson(projects)); + request.setAttribute("commits", new Gson().toJson(commits)); + request.setAttribute("indicators", new Gson().toJson(indicators)); + request.setAttribute("sectionMap", new Gson().toJson(sectionMap)); + request.setAttribute("startTime", request.getParameter("startTime")); + dispatcher = request.getRequestDispatcher(COVERAGE_JSP); + + try { + dispatcher.forward(request, response); + } catch (ServletException e) { + logger.log(Level.SEVERE, "Servlet Exception caught : ", e); + } + } +} diff --git a/src/main/java/com/android/vts/servlet/ShowGraphServlet.java b/src/main/java/com/android/vts/servlet/ShowGraphServlet.java new file mode 100644 index 0000000..8144ecf --- /dev/null +++ b/src/main/java/com/android/vts/servlet/ShowGraphServlet.java @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.servlet; + +import com.android.vts.entity.DeviceInfoEntity; +import com.android.vts.entity.ProfilingPointRunEntity; +import com.android.vts.entity.TestEntity; +import com.android.vts.entity.TestRunEntity; +import com.android.vts.util.DatastoreHelper; +import com.android.vts.util.FilterUtil; +import com.android.vts.util.Graph; +import com.android.vts.util.GraphSerializer; +import com.android.vts.util.Histogram; +import com.android.vts.util.LineGraph; +import com.android.vts.util.PerformanceUtil; +import com.google.appengine.api.datastore.DatastoreService; +import com.google.appengine.api.datastore.DatastoreServiceFactory; +import com.google.appengine.api.datastore.Entity; +import com.google.appengine.api.datastore.EntityNotFoundException; +import com.google.appengine.api.datastore.Key; +import com.google.appengine.api.datastore.KeyFactory; +import com.google.appengine.api.datastore.Query; +import com.google.appengine.api.datastore.Query.Filter; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.lang.StringUtils; + +/** Servlet for handling requests to load graphs. */ +public class ShowGraphServlet extends BaseServlet { + private static final String GRAPH_JSP = "WEB-INF/jsp/show_graph.jsp"; + private static final long DEFAULT_FILTER_OPTION = -1; + + private static final String HIDL_HAL_OPTION = "hidl_hal_mode"; + private static final String[] splitKeysArray = new String[] {HIDL_HAL_OPTION}; + private static final Set<String> splitKeySet = new HashSet<>(Arrays.asList(splitKeysArray)); + private static final String PROFILING_DATA_ALERT = "No profiling data was found."; + + @Override + public PageType getNavParentType() { + return PageType.TOT; + } + + @Override + public List<Page> getBreadcrumbLinks(HttpServletRequest request) { + List<Page> links = new ArrayList<>(); + String testName = request.getParameter("testName"); + links.add(new Page(PageType.TABLE, testName, "?testName=" + testName)); + + String profilingPointName = request.getParameter("profilingPoint"); + links.add(new Page( + PageType.GRAPH, "?testName=" + testName + "&profilingPoint=" + profilingPointName)); + return links; + } + + /** + * Process a profiling report message and add it to the map of graphs. + * + * @param profilingRun The Entity of a profiling point run to process. + * @param idString The ID derived from the test run to identify the profiling report. + * @param graphMap A map from graph name to Graph object. + */ + private static void processProfilingRun( + Entity profilingRun, String idString, Map<String, Graph> graphMap) { + ProfilingPointRunEntity pt = ProfilingPointRunEntity.fromEntity(profilingRun); + if (pt == null) + return; + String name = PerformanceUtil.getOptionAlias(pt, splitKeySet); + Graph g = null; + if (pt.labels != null && pt.labels.size() == pt.values.size()) { + g = new LineGraph(name); + } else if (pt.labels == null && pt.values.size() > 0) { + g = new Histogram(name); + } else { + return; + } + if (!graphMap.containsKey(name)) { + graphMap.put(name, g); + } + graphMap.get(name).addData(idString, pt); + } + + /** + * Get a summary string describing the devices in the test run. + * + * @param testRun The entity storing test run information. + * @param selectedDevice The name of the selected device. + * @return A string describing the devices in the test run, or null if it doesn't match filter. + */ + private static String getDeviceSummary(Entity testRun, String selectedDevice) { + DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); + List<String> buildInfos = new ArrayList<>(); + Query deviceQuery = new Query(DeviceInfoEntity.KIND).setAncestor(testRun.getKey()); + boolean isSelectedDevice = selectedDevice == null; + for (Entity device : datastore.prepare(deviceQuery).asIterable()) { + String product = (String) device.getProperty(DeviceInfoEntity.PRODUCT); + if (selectedDevice != null && product.equals(selectedDevice)) { + isSelectedDevice = true; + } + String buildId = (String) device.getProperty(DeviceInfoEntity.BUILD_ID); + buildInfos.add(product + " (" + buildId + ")"); + } + return isSelectedDevice ? StringUtils.join(buildInfos, ", ") : null; + } + + @Override + public void doGetHandler(HttpServletRequest request, HttpServletResponse response) + throws IOException { + RequestDispatcher dispatcher = null; + DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); + String testName = request.getParameter("testName"); + String profilingPointName = request.getParameter("profilingPoint"); + String selectedDevice = request.getParameter("device"); + Long endTime = null; + if (request.getParameter("endTime") != null) { + String time = request.getParameter("endTime"); + try { + endTime = Long.parseLong(time); + } catch (NumberFormatException e) { + } + } + if (endTime == null) { + endTime = TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis()); + } + Long startTime = endTime - TimeUnit.DAYS.toMicros(1); + + // Set of device names + List<String> devices = DatastoreHelper.getAllProducts(); + if (!devices.contains(selectedDevice)) + selectedDevice = null; + + Map<String, Graph> graphMap = new HashMap<>(); + + // Create a query for test runs matching the time window filter + Key parentKey = KeyFactory.createKey(TestEntity.KIND, testName); + Filter timeFilter = + FilterUtil.getTimeFilter(parentKey, TestRunEntity.KIND, startTime, endTime); + Query testRunQuery = new Query(TestRunEntity.KIND) + .setAncestor(parentKey) + .setFilter(timeFilter) + .setKeysOnly(); + + // Process the test runs in the query + for (Entity testRun : datastore.prepare(testRunQuery).asIterable()) { + String buildInfoString = getDeviceSummary(testRun, selectedDevice); + if (buildInfoString == null) { + continue; + } + + try { + Entity profilingRun = datastore.get(KeyFactory.createKey( + testRun.getKey(), ProfilingPointRunEntity.KIND, profilingPointName)); + processProfilingRun(profilingRun, buildInfoString, graphMap); + } catch (EntityNotFoundException e) { + // Profiling point not collected during this test run + continue; + } + } + // Get the names of the graphs to render + String[] names = graphMap.keySet().toArray(new String[graphMap.size()]); + Arrays.sort(names); + + List<Graph> graphList = new ArrayList<>(); + boolean hasHistogram = false; + for (String name : names) { + Graph g = graphMap.get(name); + if (g.size() > 0) { + graphList.add(g); + if (g instanceof Histogram) + hasHistogram = true; + } + } + + String filterVal = request.getParameter("filterVal"); + try { + Long.parseLong(filterVal); + } catch (NumberFormatException e) { + filterVal = Long.toString(DEFAULT_FILTER_OPTION); + } + request.setAttribute("testName", request.getParameter("testName")); + request.setAttribute("filterVal", filterVal); + request.setAttribute("endTime", new Gson().toJson(endTime)); + request.setAttribute("devices", devices); + request.setAttribute("selectedDevice", selectedDevice); + request.setAttribute("showFilterDropdown", hasHistogram); + if (graphList.size() == 0) + request.setAttribute("error", PROFILING_DATA_ALERT); + + Gson gson = new GsonBuilder() + .registerTypeHierarchyAdapter(Graph.class, new GraphSerializer()) + .create(); + request.setAttribute("graphs", gson.toJson(graphList)); + + request.setAttribute("profilingPointName", profilingPointName); + dispatcher = request.getRequestDispatcher(GRAPH_JSP); + try { + dispatcher.forward(request, response); + } catch (ServletException e) { + logger.log(Level.SEVERE, "Servlet Excpetion caught : ", e); + } + } +} diff --git a/src/main/java/com/android/vts/servlet/ShowPerformanceDigestServlet.java b/src/main/java/com/android/vts/servlet/ShowPerformanceDigestServlet.java new file mode 100644 index 0000000..51b0127 --- /dev/null +++ b/src/main/java/com/android/vts/servlet/ShowPerformanceDigestServlet.java @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.servlet; + +import com.android.vts.util.DatastoreHelper; +import com.android.vts.util.PerformanceSummary; +import com.android.vts.util.PerformanceUtil; +import com.android.vts.util.PerformanceUtil.TimeInterval; +import com.android.vts.util.ProfilingPointSummary; +import com.android.vts.util.StatSummary; +import java.io.IOException; +import java.math.RoundingMode; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** Servlet for producing tabular performance summaries. */ +public class ShowPerformanceDigestServlet extends BaseServlet { + private static final String PERF_DIGEST_JSP = "WEB-INF/jsp/show_performance_digest.jsp"; + private static final String HIDL_HAL_OPTION = "hidl_hal_mode"; + private static final String[] splitKeysArray = new String[] {HIDL_HAL_OPTION}; + private static final Set<String> splitKeySet = + new HashSet<String>(Arrays.asList(splitKeysArray)); + + private static final String MEAN = "Mean"; + private static final String MIN = "Min"; + private static final String MAX = "Max"; + private static final String MEAN_DELTA = "ΔMean (%)"; + private static final String HIGHER_IS_BETTER = + "Note: Higher values are better. Maximum is the best-case performance."; + private static final String LOWER_IS_BETTER = + "Note: Lower values are better. Minimum is the best-case performance."; + private static final String STD = "Std"; + + private static final DecimalFormat FORMATTER; + + /** + * Initialize the decimal formatter. + */ + static { + FORMATTER = new DecimalFormat("#.##"); + FORMATTER.setRoundingMode(RoundingMode.HALF_UP); + } + + @Override + public PageType getNavParentType() { + return PageType.TOT; + } + + @Override + public List<Page> getBreadcrumbLinks(HttpServletRequest request) { + List<Page> links = new ArrayList<>(); + String testName = request.getParameter("testName"); + links.add(new Page(PageType.TABLE, testName, "?testName=" + testName)); + links.add(new Page(PageType.PERFORMANCE, "?testName=" + testName)); + return links; + } + + /** + * Generates an HTML summary of the performance changes for the profiling results in the + * specified + * table. + * + * <p>Retrieves the past 24 hours of profiling data and compares it to the 24 hours that + * preceded + * it. Creates a table representation of the mean and standard deviation for each profiling + * point. + * When performance degrades, the cell is shaded red. + * + * @param profilingPoint The name of the profiling point to summarize. + * @param testSummary The ProfilingPointSummary object to compare against. + * @param perfSummaries List of PerformanceSummary objects for each profiling run (in reverse + * chronological order). + * @param sectionLabels HTML string for the section labels (i.e. for each time interval). + * @returns An HTML string for a table comparing the profiling point results across time + * intervals. + */ + public static String getPeformanceSummary(String profilingPoint, + ProfilingPointSummary testSummary, List<PerformanceSummary> perfSummaries, + String sectionLabels) { + String tableHTML = "<table>"; + + // Format section labels + tableHTML += "<tr>"; + tableHTML += "<th class='section-label grey lighten-2'>"; + tableHTML += testSummary.yLabel + "</th>"; + tableHTML += sectionLabels; + tableHTML += "</tr>"; + + String bestCaseString; + switch (testSummary.getRegressionMode()) { + case VTS_REGRESSION_MODE_DECREASING: + bestCaseString = MAX; + break; + default: + bestCaseString = MIN; + break; + } + + // Format column labels + tableHTML += "<tr>"; + for (int i = 0; i <= perfSummaries.size() + 1; i++) { + if (i > 1) { + tableHTML += "<th class='section-label grey lighten-2'>" + MEAN_DELTA + "</th>"; + } + if (i == 0) { + tableHTML += "<th class='section-label grey lighten-2'>"; + tableHTML += testSummary.xLabel + "</th>"; + } else if (i > 0) { + tableHTML += "<th class='section-label grey lighten-2'>" + bestCaseString + "</th>"; + tableHTML += "<th class='section-label grey lighten-2'>" + MEAN + "</th>"; + tableHTML += "<th class='section-label grey lighten-2'>" + STD + "</th>"; + } + } + tableHTML += "</tr>"; + + // Populate data cells + for (StatSummary stats : testSummary) { + String label = stats.getLabel(); + tableHTML += "<tr><td class='axis-label grey lighten-2'>" + label; + tableHTML += "</td><td class='cell inner-cell'>"; + tableHTML += FORMATTER.format(stats.getBestCase()) + "</td>"; + tableHTML += "<td class='cell inner-cell'>"; + tableHTML += FORMATTER.format(stats.getMean()) + "</td>"; + tableHTML += "<td class='cell outer-cell'>"; + tableHTML += FORMATTER.format(stats.getStd()) + "</td>"; + for (PerformanceSummary prevPerformance : perfSummaries) { + if (prevPerformance.hasProfilingPoint(profilingPoint)) { + StatSummary baseline = prevPerformance.getProfilingPointSummary(profilingPoint) + .getStatSummary(label); + tableHTML += PerformanceUtil.getAvgCasePerformanceComparisonHTML( + baseline, stats, "cell inner-cell", "cell outer-cell", "", ""); + } else { + tableHTML += "<td></td><td></td><td></td><td></td>"; + } + } + tableHTML += "</tr>"; + } + tableHTML += "</table>"; + return tableHTML; + } + + @Override + public void doGetHandler(HttpServletRequest request, HttpServletResponse response) + throws IOException { + RequestDispatcher dispatcher = null; + String testName = request.getParameter("testName"); + String selectedDevice = request.getParameter("device"); + Long startTime = null; + if (request.getParameter("startTime") != null) { + String time = request.getParameter("startTime"); + try { + startTime = Long.parseLong(time); + } catch (NumberFormatException e) { + logger.log(Level.WARNING, "Invalid start time passed to digest servlet: " + time); + } + } + if (startTime == null) { + startTime = TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis()); + } + + // Add today to the list of time intervals to analyze + List<TimeInterval> timeIntervals = new ArrayList<>(); + TimeInterval today = new TimeInterval(startTime - TimeUnit.DAYS.toMicros(1), startTime); + timeIntervals.add(today); + + // Add yesterday as a baseline time interval for analysis + long oneDayAgo = startTime - TimeUnit.DAYS.toMicros(1); + TimeInterval yesterday = new TimeInterval(oneDayAgo - TimeUnit.DAYS.toMicros(1), oneDayAgo); + timeIntervals.add(yesterday); + + // Add last week as a baseline time interval for analysis + long oneWeek = TimeUnit.DAYS.toMicros(7); + long oneWeekAgo = startTime - oneWeek; + String spanString = "<span class='date-label'>"; + String label = + spanString + TimeUnit.MICROSECONDS.toMillis(oneWeekAgo - oneWeek) + "</span>"; + label += " - " + spanString + TimeUnit.MICROSECONDS.toMillis(oneWeekAgo) + "</span>"; + TimeInterval lastWeek = new TimeInterval(oneWeekAgo - oneWeek, oneWeekAgo, label); + timeIntervals.add(lastWeek); + + List<PerformanceSummary> perfSummaries = new ArrayList<>(); + + String sectionLabels = ""; + int i = 0; + for (TimeInterval interval : timeIntervals) { + PerformanceSummary perfSummary = new PerformanceSummary(splitKeySet); + PerformanceUtil.updatePerformanceSummary( + testName, interval.start, interval.end, selectedDevice, perfSummary); + if (perfSummary.size() == 0) { + continue; + } + perfSummaries.add(perfSummary); + String content = interval.label; + sectionLabels += "<th class='section-label grey lighten-2 center' "; + if (i++ == 0) + sectionLabels += "colspan='3'"; + else + sectionLabels += "colspan='4'"; + sectionLabels += ">" + content + "</th>"; + } + + List<String> tables = new ArrayList<>(); + List<String> tableTitles = new ArrayList<>(); + List<String> tableSubtitles = new ArrayList<>(); + if (perfSummaries.size() != 0) { + PerformanceSummary todayPerformance = perfSummaries.remove(0); + String[] profilingNames = todayPerformance.getProfilingPointNames(); + + for (String profilingPointName : profilingNames) { + ProfilingPointSummary baselinePerformance = + todayPerformance.getProfilingPointSummary(profilingPointName); + String table = getPeformanceSummary( + profilingPointName, baselinePerformance, perfSummaries, sectionLabels); + if (table != null) { + tables.add(table); + tableTitles.add(profilingPointName); + switch (baselinePerformance.getRegressionMode()) { + case VTS_REGRESSION_MODE_DECREASING: + tableSubtitles.add(HIGHER_IS_BETTER); + break; + default: + tableSubtitles.add(LOWER_IS_BETTER); + break; + } + } + } + } + + request.setAttribute("testName", testName); + request.setAttribute("tables", tables); + request.setAttribute("tableTitles", tableTitles); + request.setAttribute("tableSubtitles", tableSubtitles); + request.setAttribute("startTime", Long.toString(startTime)); + request.setAttribute("selectedDevice", selectedDevice); + request.setAttribute("devices", DatastoreHelper.getAllProducts()); + + dispatcher = request.getRequestDispatcher(PERF_DIGEST_JSP); + try { + dispatcher.forward(request, response); + } catch (ServletException e) { + logger.log(Level.SEVERE, "Servlet Exception caught : " + e.toString()); + } + } +} diff --git a/src/main/java/com/android/vts/servlet/ShowPlanReleaseServlet.java b/src/main/java/com/android/vts/servlet/ShowPlanReleaseServlet.java new file mode 100644 index 0000000..4e88bcc --- /dev/null +++ b/src/main/java/com/android/vts/servlet/ShowPlanReleaseServlet.java @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2017 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.servlet; + +import com.android.vts.entity.DeviceInfoEntity; +import com.android.vts.entity.TestPlanEntity; +import com.android.vts.entity.TestPlanRunEntity; +import com.android.vts.entity.TestRunEntity; +import com.android.vts.util.DatastoreHelper; +import com.android.vts.util.FilterUtil; +import com.google.appengine.api.datastore.DatastoreService; +import com.google.appengine.api.datastore.DatastoreServiceFactory; +import com.google.appengine.api.datastore.Entity; +import com.google.appengine.api.datastore.FetchOptions; +import com.google.appengine.api.datastore.Key; +import com.google.appengine.api.datastore.KeyFactory; +import com.google.appengine.api.datastore.Query; +import com.google.appengine.api.datastore.Query.CompositeFilterOperator; +import com.google.appengine.api.datastore.Query.Filter; +import com.google.appengine.api.datastore.Query.SortDirection; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import java.util.Set; +import java.util.HashSet; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.lang.StringUtils; + +public class ShowPlanReleaseServlet extends BaseServlet { + private static final String PLAN_RELEASE_JSP = "WEB-INF/jsp/show_plan_release.jsp"; + private static final int MAX_RUNS_PER_PAGE = 90; + + @Override + public PageType getNavParentType() { + return PageType.RELEASE; + } + + @Override + public List<Page> getBreadcrumbLinks(HttpServletRequest request) { + List<Page> links = new ArrayList<>(); + String planName = request.getParameter("plan"); + links.add(new Page(PageType.PLAN_RELEASE, planName.toUpperCase(), "?plan=" + planName)); + return links; + } + + /** + * Model to describe each test plan run . + */ + private class TestPlanRunMetadata implements Comparable<TestPlanRunMetadata> { + public final TestPlanRunEntity testPlanRun; + public final List<String> devices; + public final Set<DeviceInfoEntity> deviceSet; + + public TestPlanRunMetadata(TestPlanRunEntity testPlanRun) { + this.testPlanRun = testPlanRun; + this.devices = new ArrayList<>(); + this.deviceSet = new HashSet<>(); + } + + public void addDevice(DeviceInfoEntity device) { + if (device == null || deviceSet.contains(device)) + return; + devices.add(device.branch + "/" + device.buildFlavor + " (" + device.buildId + ")"); + deviceSet.add(device); + } + + public JsonObject toJson() { + JsonObject obj = new JsonObject(); + obj.add("testPlanRun", testPlanRun.toJson()); + obj.add("deviceInfo", new JsonPrimitive(StringUtils.join(devices, ", "))); + return obj; + } + + @Override + public int compareTo(TestPlanRunMetadata o) { + return new Long(o.testPlanRun.startTimestamp) + .compareTo(this.testPlanRun.startTimestamp); + } + } + + @Override + public void doGetHandler(HttpServletRequest request, HttpServletResponse response) + throws IOException { + DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); + Long startTime = null; // time in microseconds + Long endTime = null; // time in microseconds + if (request.getParameter("startTime") != null) { + String time = request.getParameter("startTime"); + try { + startTime = Long.parseLong(time); + startTime = startTime > 0 ? startTime : null; + } catch (NumberFormatException e) { + startTime = null; + } + } + if (request.getParameter("endTime") != null) { + String time = request.getParameter("endTime"); + try { + endTime = Long.parseLong(time); + endTime = endTime > 0 ? endTime : null; + } catch (NumberFormatException e) { + endTime = null; + } + } + SortDirection dir = SortDirection.DESCENDING; + if (startTime != null && endTime == null) { + dir = SortDirection.ASCENDING; + } + boolean unfiltered = request.getParameter("unfiltered") != null; + boolean showPresubmit = request.getParameter("showPresubmit") != null; + boolean showPostsubmit = request.getParameter("showPostsubmit") != null; + // If no params are specified, set to default of postsubmit-only. + if (!(showPresubmit || showPostsubmit)) { + showPostsubmit = true; + } + + // If unfiltered, set showPre- and Post-submit to true for accurate UI. + if (unfiltered) { + showPostsubmit = true; + showPresubmit = true; + } + Filter typeFilter = FilterUtil.getTestTypeFilter(showPresubmit, showPostsubmit, unfiltered); + String testPlan = request.getParameter("plan"); + Key testPlanKey = KeyFactory.createKey(TestPlanEntity.KIND, testPlan); + Filter testPlanRunFilter = FilterUtil.getTimeFilter( + testPlanKey, TestPlanRunEntity.KIND, startTime, endTime, typeFilter); + Map<String, Object> parameterMap = request.getParameterMap(); + Filter userDeviceFilter = FilterUtil.getUserDeviceFilter(parameterMap); + + List<TestPlanRunMetadata> testPlanRuns = new ArrayList<>(); + if (userDeviceFilter == null) { + Query testPlanRunQuery = new Query(TestPlanRunEntity.KIND) + .setAncestor(testPlanKey) + .setFilter(testPlanRunFilter) + .addSort(Entity.KEY_RESERVED_PROPERTY, dir); + for (Entity testPlanRunEntity : + datastore.prepare(testPlanRunQuery) + .asIterable(FetchOptions.Builder.withLimit(MAX_RUNS_PER_PAGE))) { + TestPlanRunEntity testPlanRun = TestPlanRunEntity.fromEntity(testPlanRunEntity); + if (testPlanRun == null) { + logger.log( + Level.WARNING, "Invalid test plan run: " + testPlanRunEntity.getKey()); + continue; + } + TestPlanRunMetadata metadata = new TestPlanRunMetadata(testPlanRun); + testPlanRuns.add(metadata); + Query deviceInfoQuery = + new Query(DeviceInfoEntity.KIND).setAncestor(testPlanRun.key); + for (Entity deviceInfoEntity : datastore.prepare(deviceInfoQuery).asIterable()) { + DeviceInfoEntity deviceInfo = DeviceInfoEntity.fromEntity(deviceInfoEntity); + metadata.addDevice(deviceInfo); + } + } + } else { + List<Key> gets = FilterUtil.getMatchingKeys(testPlanKey, TestPlanRunEntity.KIND, + testPlanRunFilter, userDeviceFilter, dir, MAX_RUNS_PER_PAGE); + Map<Key, Entity> entityMap = datastore.get(gets); + for (Key key : gets) { + if (!entityMap.containsKey(key)) { + continue; + } + TestPlanRunEntity testPlanRun = TestPlanRunEntity.fromEntity(entityMap.get(key)); + if (testPlanRun == null) { + continue; + } + TestPlanRunMetadata metadata = new TestPlanRunMetadata(testPlanRun); + testPlanRuns.add(metadata); + Query deviceInfoQuery = + new Query(DeviceInfoEntity.KIND).setAncestor(testPlanRun.key); + for (Entity deviceInfoEntity : datastore.prepare(deviceInfoQuery).asIterable()) { + DeviceInfoEntity deviceInfo = DeviceInfoEntity.fromEntity(deviceInfoEntity); + metadata.addDevice(deviceInfo); + } + } + } + + Collections.sort(testPlanRuns); + + if (testPlanRuns.size() > 0) { + TestPlanRunMetadata firstRun = testPlanRuns.get(0); + endTime = firstRun.testPlanRun.startTimestamp; + + TestPlanRunMetadata lastRun = testPlanRuns.get(testPlanRuns.size() - 1); + startTime = lastRun.testPlanRun.startTimestamp; + } + + List<JsonObject> testPlanRunObjects = new ArrayList<>(); + for (TestPlanRunMetadata metadata : testPlanRuns) { + testPlanRunObjects.add(metadata.toJson()); + } + + FilterUtil.setAttributes(request, parameterMap); + + request.setAttribute("plan", request.getParameter("plan")); + request.setAttribute("hasNewer", new Gson().toJson(DatastoreHelper.hasNewer( + testPlanKey, TestPlanRunEntity.KIND, endTime))); + request.setAttribute("hasOlder", new Gson().toJson(DatastoreHelper.hasOlder( + testPlanKey, TestPlanRunEntity.KIND, startTime))); + request.setAttribute("planRuns", new Gson().toJson(testPlanRunObjects)); + + request.setAttribute("unfiltered", unfiltered); + request.setAttribute("showPresubmit", showPresubmit); + request.setAttribute("showPostsubmit", showPostsubmit); + request.setAttribute("startTime", new Gson().toJson(startTime)); + request.setAttribute("endTime", new Gson().toJson(endTime)); + request.setAttribute("branches", new Gson().toJson(DatastoreHelper.getAllBranches())); + request.setAttribute("devices", new Gson().toJson(DatastoreHelper.getAllBuildFlavors())); + response.setStatus(HttpServletResponse.SC_OK); + RequestDispatcher dispatcher = request.getRequestDispatcher(PLAN_RELEASE_JSP); + try { + dispatcher.forward(request, response); + } catch (ServletException e) { + logger.log(Level.SEVERE, "Servlet Excpetion caught : ", e); + } + } +} diff --git a/src/main/java/com/android/vts/servlet/ShowPlanRunServlet.java b/src/main/java/com/android/vts/servlet/ShowPlanRunServlet.java new file mode 100644 index 0000000..32b3ec4 --- /dev/null +++ b/src/main/java/com/android/vts/servlet/ShowPlanRunServlet.java @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2017 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.servlet; + +import com.android.vts.entity.TestPlanEntity; +import com.android.vts.entity.TestPlanRunEntity; +import com.android.vts.entity.TestRunEntity; +import com.android.vts.proto.VtsReportMessage.TestCaseResult; +import com.android.vts.util.TestRunMetadata; +import com.google.appengine.api.datastore.DatastoreService; +import com.google.appengine.api.datastore.DatastoreServiceFactory; +import com.google.appengine.api.datastore.Entity; +import com.google.appengine.api.datastore.EntityNotFoundException; +import com.google.appengine.api.datastore.Key; +import com.google.appengine.api.datastore.KeyFactory; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** Servlet for handling requests to load individual plan runs. */ +public class ShowPlanRunServlet extends BaseServlet { + private static final String PLAN_RUN_JSP = "WEB-INF/jsp/show_plan_run.jsp"; + private static final String PROFILING_DATA_ALERT = "No profiling data was found."; + + @Override + public PageType getNavParentType() { + return PageType.RELEASE; + } + + @Override + public List<Page> getBreadcrumbLinks(HttpServletRequest request) { + List<Page> links = new ArrayList<>(); + String planName = request.getParameter("plan"); + links.add(new Page(PageType.PLAN_RELEASE, planName.toUpperCase(), "?plan=" + planName)); + + String time = request.getParameter("time"); + links.add(new Page(PageType.PLAN_RUN, "?plan=" + planName + "&time=" + time)); + return links; + } + + @Override + public void doGetHandler(HttpServletRequest request, HttpServletResponse response) + throws IOException { + Long startTime = null; // time in microseconds + DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); + RequestDispatcher dispatcher = null; + + String plan = request.getParameter("plan"); + + if (request.getParameter("time") != null) { + String time = request.getParameter("time"); + try { + startTime = Long.parseLong(time); + startTime = startTime > 0 ? startTime : null; + } catch (NumberFormatException e) { + startTime = null; + } + } + + // Add result names to list + List<String> resultNames = new ArrayList<>(); + for (TestCaseResult r : TestCaseResult.values()) { + resultNames.add(r.name()); + } + + List<TestRunMetadata> testRunMetadata = new ArrayList<>(); + List<JsonObject> testRunObjects = new ArrayList<>(); + + Key planKey = KeyFactory.createKey(TestPlanEntity.KIND, plan); + Key planRunKey = KeyFactory.createKey(planKey, TestPlanRunEntity.KIND, startTime); + int passCount = 0; + int failCount = 0; + try { + Entity testPlanRunEntity = datastore.get(planRunKey); + TestPlanRunEntity testPlanRun = TestPlanRunEntity.fromEntity(testPlanRunEntity); + Map<Key, Entity> testRuns = datastore.get(testPlanRun.testRuns); + passCount = (int) testPlanRun.passCount; + failCount = (int) testPlanRun.failCount; + + for (Key key : testPlanRun.testRuns) { + if (!testRuns.containsKey(key)) + continue; + TestRunEntity testRunEntity = TestRunEntity.fromEntity(testRuns.get(key)); + if (testRunEntity == null) + continue; + TestRunMetadata metadata = + new TestRunMetadata(key.getParent().getName(), testRunEntity); + testRunMetadata.add(metadata); + testRunObjects.add(metadata.toJson()); + } + } catch (EntityNotFoundException e) { + // Invalid parameters + } + + int[] topBuildResultCounts = new int[TestCaseResult.values().length]; + topBuildResultCounts = new int[TestCaseResult.values().length]; + topBuildResultCounts[TestCaseResult.TEST_CASE_RESULT_PASS.getNumber()] = passCount; + topBuildResultCounts[TestCaseResult.TEST_CASE_RESULT_FAIL.getNumber()] = failCount; + + Set<String> profilingPoints = new HashSet<>(); + + String profilingDataAlert = ""; + if (profilingPoints.size() == 0) { + profilingDataAlert = PROFILING_DATA_ALERT; + } + List<String> profilingPointNames = new ArrayList<>(profilingPoints); + Collections.sort(profilingPointNames); + + request.setAttribute("plan", request.getParameter("plan")); + request.setAttribute("time", request.getParameter("time")); + + request.setAttribute("error", profilingDataAlert); + + request.setAttribute("profilingPointNames", profilingPointNames); + request.setAttribute("resultNames", resultNames); + request.setAttribute("resultNamesJson", new Gson().toJson(resultNames)); + request.setAttribute("testRuns", new Gson().toJson(testRunObjects)); + + // data for pie chart + request.setAttribute("topBuildResultCounts", new Gson().toJson(topBuildResultCounts)); + + dispatcher = request.getRequestDispatcher(PLAN_RUN_JSP); + try { + dispatcher.forward(request, response); + } catch (ServletException e) { + logger.log(Level.SEVERE, "Servlet Exception caught : " + e.toString()); + } + } +} diff --git a/src/main/java/com/android/vts/servlet/ShowReleaseServlet.java b/src/main/java/com/android/vts/servlet/ShowReleaseServlet.java new file mode 100644 index 0000000..35f1af2 --- /dev/null +++ b/src/main/java/com/android/vts/servlet/ShowReleaseServlet.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.servlet; + +import com.android.vts.entity.TestEntity; +import com.android.vts.entity.TestPlanEntity; +import com.android.vts.entity.UserFavoriteEntity; +import com.google.appengine.api.datastore.DatastoreService; +import com.google.appengine.api.datastore.DatastoreServiceFactory; +import com.google.appengine.api.datastore.Entity; +import com.google.appengine.api.datastore.Key; +import com.google.appengine.api.datastore.KeyFactory; +import com.google.appengine.api.datastore.PropertyProjection; +import com.google.appengine.api.datastore.Query; +import com.google.appengine.api.datastore.Query.Filter; +import com.google.appengine.api.datastore.Query.FilterOperator; +import com.google.appengine.api.datastore.Query.FilterPredicate; +import com.google.appengine.api.users.User; +import com.google.appengine.api.users.UserService; +import com.google.appengine.api.users.UserServiceFactory; +import com.google.gson.Gson; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** Represents the servlet that is invoked on loading the release page. */ +public class ShowReleaseServlet extends BaseServlet { + private static final String RELEASE_JSP = "WEB-INF/jsp/show_release.jsp"; + + @Override + public PageType getNavParentType() { + return PageType.RELEASE; + } + + @Override + public List<Page> getBreadcrumbLinks(HttpServletRequest request) { + return null; + } + + @Override + public void doGetHandler(HttpServletRequest request, HttpServletResponse response) + throws IOException { + UserService userService = UserServiceFactory.getUserService(); + User currentUser = userService.getCurrentUser(); + RequestDispatcher dispatcher = null; + DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); + + Set<String> planSet = new HashSet<>(); + + Query q = new Query(TestPlanEntity.KIND).setKeysOnly(); + for (Entity testPlanEntity : datastore.prepare(q).asIterable()) { + planSet.add(testPlanEntity.getKey().getName()); + } + + List<String> plans = new ArrayList<>(planSet); + Collections.sort(plans); + + response.setStatus(HttpServletResponse.SC_OK); + request.setAttribute("planNames", plans); + dispatcher = request.getRequestDispatcher(RELEASE_JSP); + try { + dispatcher.forward(request, response); + } catch (ServletException e) { + logger.log(Level.SEVERE, "Servlet Excpetion caught : ", e); + } + } +} diff --git a/src/main/java/com/android/vts/servlet/ShowTableServlet.java b/src/main/java/com/android/vts/servlet/ShowTableServlet.java new file mode 100644 index 0000000..b525c3d --- /dev/null +++ b/src/main/java/com/android/vts/servlet/ShowTableServlet.java @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.servlet; + +import com.android.vts.entity.DeviceInfoEntity; +import com.android.vts.entity.ProfilingPointRunEntity; +import com.android.vts.entity.TestCaseRunEntity; +import com.android.vts.entity.TestEntity; +import com.android.vts.entity.TestRunEntity; +import com.android.vts.proto.VtsReportMessage.TestCaseResult; +import com.android.vts.util.DatastoreHelper; +import com.android.vts.util.FilterUtil; +import com.android.vts.util.TestResults; +import com.google.appengine.api.datastore.DatastoreService; +import com.google.appengine.api.datastore.DatastoreServiceFactory; +import com.google.appengine.api.datastore.Entity; +import com.google.appengine.api.datastore.FetchOptions; +import com.google.appengine.api.datastore.Key; +import com.google.appengine.api.datastore.KeyFactory; +import com.google.appengine.api.datastore.Query; +import com.google.appengine.api.datastore.Query.CompositeFilterOperator; +import com.google.appengine.api.datastore.Query.Filter; +import com.google.appengine.api.datastore.Query.SortDirection; +import com.google.gson.Gson; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.lang.StringUtils; + +/** Servlet for handling requests to load individual tables. */ +public class ShowTableServlet extends BaseServlet { + private static final String TABLE_JSP = "WEB-INF/jsp/show_table.jsp"; + // Error message displayed on the webpage is tableName passed is null. + private static final String TABLE_NAME_ERROR = "Error : Table name must be passed!"; + private static final String PROFILING_DATA_ALERT = "No profiling data was found."; + private static final int MAX_BUILD_IDS_PER_PAGE = 10; + + @Override + public PageType getNavParentType() { + return PageType.TOT; + } + + @Override + public List<Page> getBreadcrumbLinks(HttpServletRequest request) { + List<Page> links = new ArrayList<>(); + String testName = request.getParameter("testName"); + links.add(new Page(PageType.TABLE, testName, "?testName=" + testName)); + return links; + } + + public static void processTestRun(TestResults testResults, Entity testRun) { + TestRunEntity testRunEntity = TestRunEntity.fromEntity(testRun); + if (testRunEntity == null) { + return; + } + + DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); + List<Key> gets = new ArrayList<>(); + for (long testCaseId : testRunEntity.testCaseIds) { + gets.add(KeyFactory.createKey(TestCaseRunEntity.KIND, testCaseId)); + } + + List<Entity> testCases = new ArrayList<>(); + Map<Key, Entity> entityMap = datastore.get(gets); + for (Key key : gets) { + if (entityMap.containsKey(key)) { + testCases.add(entityMap.get(key)); + } + } + + Query deviceInfoQuery = new Query(DeviceInfoEntity.KIND).setAncestor(testRun.getKey()); + Iterable<Entity> deviceInfos = datastore.prepare(deviceInfoQuery).asIterable(); + + Query profilingPointQuery = + new Query(ProfilingPointRunEntity.KIND).setAncestor(testRun.getKey()).setKeysOnly(); + Iterable<Entity> profilingPoints = datastore.prepare(profilingPointQuery).asIterable(); + + testResults.addTestRun(testRun, testCases, deviceInfos, profilingPoints); + } + + @Override + public void doGetHandler(HttpServletRequest request, HttpServletResponse response) + throws IOException { + boolean unfiltered = request.getParameter("unfiltered") != null; + boolean showPresubmit = request.getParameter("showPresubmit") != null; + boolean showPostsubmit = request.getParameter("showPostsubmit") != null; + String searchString = request.getParameter("search"); + Long startTime = null; // time in microseconds + Long endTime = null; // time in microseconds + DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); + RequestDispatcher dispatcher = null; + + // message to display if profiling point data is not available + String profilingDataAlert = ""; + + if (request.getParameter("testName") == null) { + request.setAttribute("testName", TABLE_NAME_ERROR); + return; + } + String testName = request.getParameter("testName"); + + if (request.getParameter("startTime") != null) { + String time = request.getParameter("startTime"); + try { + startTime = Long.parseLong(time); + startTime = startTime > 0 ? startTime : null; + } catch (NumberFormatException e) { + startTime = null; + } + } + if (request.getParameter("endTime") != null) { + String time = request.getParameter("endTime"); + try { + endTime = Long.parseLong(time); + endTime = endTime > 0 ? endTime : null; + } catch (NumberFormatException e) { + endTime = null; + } + } + + // If no params are specified, set to default of postsubmit-only. + if (!(showPresubmit || showPostsubmit)) { + showPostsubmit = true; + } + + // If unfiltered, set showPre- and Post-submit to true for accurate UI. + if (unfiltered) { + showPostsubmit = true; + showPresubmit = true; + } + + // Add result names to list + List<String> resultNames = new ArrayList<>(); + for (TestCaseResult r : TestCaseResult.values()) { + resultNames.add(r.name()); + } + + TestResults testResults = new TestResults(testName); + + SortDirection dir = SortDirection.DESCENDING; + if (startTime != null && endTime == null) { + dir = SortDirection.ASCENDING; + } + Key testKey = KeyFactory.createKey(TestEntity.KIND, testName); + Map<String, Object> parameterMap = request.getParameterMap(); + Filter userTestFilter = FilterUtil.getUserTestFilter(parameterMap); + Filter userDeviceFilter = FilterUtil.getUserDeviceFilter(parameterMap); + + Filter typeFilter = FilterUtil.getTestTypeFilter(showPresubmit, showPostsubmit, unfiltered); + Filter testFilter = FilterUtil.getTimeFilter( + testKey, TestRunEntity.KIND, startTime, endTime, typeFilter); + if (userTestFilter == null && userDeviceFilter == null) { + Query testRunQuery = new Query(TestRunEntity.KIND) + .setAncestor(testKey) + .setFilter(testFilter) + .addSort(Entity.KEY_RESERVED_PROPERTY, dir); + for (Entity testRun : + datastore.prepare(testRunQuery) + .asIterable(FetchOptions.Builder.withLimit(MAX_BUILD_IDS_PER_PAGE))) { + processTestRun(testResults, testRun); + } + } else { + if (userTestFilter != null) { + testFilter = CompositeFilterOperator.and(userTestFilter, testFilter); + } + List<Key> gets = FilterUtil.getMatchingKeys(testKey, TestRunEntity.KIND, testFilter, + userDeviceFilter, dir, MAX_BUILD_IDS_PER_PAGE); + Map<Key, Entity> entityMap = datastore.get(gets); + for (Key key : gets) { + if (!entityMap.containsKey(key)) { + continue; + } + processTestRun(testResults, entityMap.get(key)); + } + } + + testResults.processReport(); + + if (testResults.profilingPointNames.length == 0) { + profilingDataAlert = PROFILING_DATA_ALERT; + } + + FilterUtil.setAttributes(request, parameterMap); + + request.setAttribute("testName", request.getParameter("testName")); + + request.setAttribute("error", profilingDataAlert); + + // pass values by converting to JSON + request.setAttribute("headerRow", new Gson().toJson(testResults.headerRow)); + request.setAttribute("timeGrid", new Gson().toJson(testResults.timeGrid)); + request.setAttribute("durationGrid", new Gson().toJson(testResults.durationGrid)); + request.setAttribute("summaryGrid", new Gson().toJson(testResults.summaryGrid)); + request.setAttribute("resultsGrid", new Gson().toJson(testResults.resultsGrid)); + request.setAttribute("profilingPointNames", testResults.profilingPointNames); + request.setAttribute("resultNames", resultNames); + request.setAttribute("resultNamesJson", new Gson().toJson(resultNames)); + request.setAttribute("logInfoMap", new Gson().toJson(testResults.logInfoMap)); + + // data for pie chart + request.setAttribute( + "topBuildResultCounts", new Gson().toJson(testResults.totResultCounts)); + request.setAttribute("topBuildId", testResults.totBuildId); + request.setAttribute("startTime", new Gson().toJson(testResults.startTime)); + request.setAttribute("endTime", new Gson().toJson(testResults.endTime)); + request.setAttribute("hasNewer", new Gson().toJson(DatastoreHelper.hasNewer(testKey, + TestRunEntity.KIND, testResults.endTime))); + request.setAttribute("hasOlder", new Gson().toJson(DatastoreHelper.hasOlder(testKey, + TestRunEntity.KIND, testResults.startTime))); + request.setAttribute("unfiltered", unfiltered); + request.setAttribute("showPresubmit", showPresubmit); + request.setAttribute("showPostsubmit", showPostsubmit); + + request.setAttribute("branches", new Gson().toJson(DatastoreHelper.getAllBranches())); + request.setAttribute("devices", new Gson().toJson(DatastoreHelper.getAllBuildFlavors())); + + dispatcher = request.getRequestDispatcher(TABLE_JSP); + try { + dispatcher.forward(request, response); + } catch (ServletException e) { + logger.log(Level.SEVERE, "Servlet Exception caught : " + e.toString()); + } + } +} diff --git a/src/main/java/com/android/vts/servlet/ShowTreeServlet.java b/src/main/java/com/android/vts/servlet/ShowTreeServlet.java new file mode 100644 index 0000000..d6e759e --- /dev/null +++ b/src/main/java/com/android/vts/servlet/ShowTreeServlet.java @@ -0,0 +1,290 @@ +/* + * Copyright (c) 2017 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.servlet; + +import com.android.vts.entity.DeviceInfoEntity; +import com.android.vts.entity.ProfilingPointRunEntity; +import com.android.vts.entity.TestCaseRunEntity; +import com.android.vts.entity.TestEntity; +import com.android.vts.entity.TestRunEntity; +import com.android.vts.proto.VtsReportMessage.TestCaseResult; +import com.android.vts.util.DatastoreHelper; +import com.android.vts.util.FilterUtil; +import com.android.vts.util.TestRunDetails; +import com.android.vts.util.TestRunMetadata; +import com.google.appengine.api.datastore.DatastoreService; +import com.google.appengine.api.datastore.DatastoreServiceFactory; +import com.google.appengine.api.datastore.Entity; +import com.google.appengine.api.datastore.FetchOptions; +import com.google.appengine.api.datastore.Key; +import com.google.appengine.api.datastore.KeyFactory; +import com.google.appengine.api.datastore.Query; +import com.google.appengine.api.datastore.Query.Filter; +import com.google.appengine.api.datastore.Query.SortDirection; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.lang.StringUtils; + +/** Servlet for handling requests to load individual tables. */ +public class ShowTreeServlet extends BaseServlet { + private static final String TABLE_JSP = "WEB-INF/jsp/show_tree.jsp"; + // Error message displayed on the webpage is tableName passed is null. + private static final String TABLE_NAME_ERROR = "Error : Table name must be passed!"; + private static final String PROFILING_DATA_ALERT = "No profiling data was found."; + private static final int MAX_BUILD_IDS_PER_PAGE = 20; + private static final int MAX_PREFETCH_COUNT = 10; + + @Override + public PageType getNavParentType() { + return PageType.TOT; + } + + @Override + public List<Page> getBreadcrumbLinks(HttpServletRequest request) { + List<Page> links = new ArrayList<>(); + String testName = request.getParameter("testName"); + links.add(new Page(PageType.TREE, testName, "?testName=" + testName)); + return links; + } + + /** + * Get the test run details for a test run. + * @param metadata The metadata for the test run whose details will be fetched. + * @return The TestRunDetails object for the provided test run. + */ + public static TestRunDetails processTestDetails(TestRunMetadata metadata) { + DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); + TestRunDetails details = new TestRunDetails(); + List<Key> gets = new ArrayList<>(); + for (long testCaseId : metadata.testRun.testCaseIds) { + gets.add(KeyFactory.createKey(TestCaseRunEntity.KIND, testCaseId)); + } + Map<Key, Entity> entityMap = datastore.get(gets); + for (int i = 0; i < 1; i++) { + for (Key key : entityMap.keySet()) { + TestCaseRunEntity testCaseRun = TestCaseRunEntity.fromEntity(entityMap.get(key)); + if (testCaseRun == null) { + continue; + } + details.addTestCase(testCaseRun); + } + } + return details; + } + + @Override + public void doGetHandler(HttpServletRequest request, HttpServletResponse response) + throws IOException { + boolean unfiltered = request.getParameter("unfiltered") != null; + boolean showPresubmit = request.getParameter("showPresubmit") != null; + boolean showPostsubmit = request.getParameter("showPostsubmit") != null; + String searchString = request.getParameter("search"); + Long startTime = null; // time in microseconds + Long endTime = null; // time in microseconds + DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); + RequestDispatcher dispatcher = null; + + // message to display if profiling point data is not available + String profilingDataAlert = ""; + + if (request.getParameter("testName") == null) { + request.setAttribute("testName", TABLE_NAME_ERROR); + return; + } + String testName = request.getParameter("testName"); + + if (request.getParameter("startTime") != null) { + String time = request.getParameter("startTime"); + try { + startTime = Long.parseLong(time); + startTime = startTime > 0 ? startTime : null; + } catch (NumberFormatException e) { + startTime = null; + } + } + if (request.getParameter("endTime") != null) { + String time = request.getParameter("endTime"); + try { + endTime = Long.parseLong(time); + endTime = endTime > 0 ? endTime : null; + } catch (NumberFormatException e) { + endTime = null; + } + } + + // If no params are specified, set to default of postsubmit-only. + if (!(showPresubmit || showPostsubmit)) { + showPostsubmit = true; + } + + // If unfiltered, set showPre- and Post-submit to true for accurate UI. + if (unfiltered) { + showPostsubmit = true; + showPresubmit = true; + } + + // Add result names to list + List<String> resultNames = new ArrayList<>(); + for (TestCaseResult r : TestCaseResult.values()) { + resultNames.add(r.name()); + } + + SortDirection dir = SortDirection.DESCENDING; + if (startTime != null && endTime == null) { + dir = SortDirection.ASCENDING; + } + Key testKey = KeyFactory.createKey(TestEntity.KIND, testName); + Map<String, Object> parameterMap = request.getParameterMap(); + Filter userTestFilter = FilterUtil.getUserTestFilter(parameterMap); + Filter userDeviceFilter = FilterUtil.getUserDeviceFilter(parameterMap); + + Filter typeFilter = FilterUtil.getTestTypeFilter(showPresubmit, showPostsubmit, unfiltered); + Filter testFilter = FilterUtil.getTimeFilter( + testKey, TestRunEntity.KIND, startTime, endTime, typeFilter); + + List<TestRunMetadata> testRunMetadata = new ArrayList<>(); + if (userTestFilter == null && userDeviceFilter == null) { + Query testRunQuery = new Query(TestRunEntity.KIND) + .setAncestor(testKey) + .setFilter(testFilter) + .addSort(Entity.KEY_RESERVED_PROPERTY, dir); + for (Entity testRun : + datastore.prepare(testRunQuery) + .asIterable(FetchOptions.Builder.withLimit(MAX_BUILD_IDS_PER_PAGE))) { + TestRunEntity testRunEntity = TestRunEntity.fromEntity(testRun); + if (testRunEntity == null) { + continue; + } + TestRunMetadata metadata = new TestRunMetadata(testName, testRunEntity); + testRunMetadata.add(metadata); + } + } else { + if (userTestFilter != null) { + testFilter = Query.CompositeFilterOperator.and(userTestFilter, testFilter); + } + List<Key> gets = FilterUtil.getMatchingKeys(testKey, TestRunEntity.KIND, testFilter, + userDeviceFilter, dir, MAX_BUILD_IDS_PER_PAGE); + Map<Key, Entity> entityMap = datastore.get(gets); + for (Key key : gets) { + if (!entityMap.containsKey(key)) { + continue; + } + TestRunEntity testRunEntity = TestRunEntity.fromEntity(entityMap.get(key)); + if (testRunEntity == null) { + continue; + } + TestRunMetadata metadata = new TestRunMetadata(testName, testRunEntity); + testRunMetadata.add(metadata); + } + } + + Comparator<TestRunMetadata> comparator = new Comparator<TestRunMetadata>() { + @Override + public int compare(TestRunMetadata t1, TestRunMetadata t2) { + return new Long(t2.testRun.startTimestamp).compareTo(t1.testRun.startTimestamp); + } + }; + Collections.sort(testRunMetadata, comparator); + List<JsonObject> testRunObjects = new ArrayList<>(); + + int prefetchCount = 0; + for (TestRunMetadata metadata : testRunMetadata) { + if (metadata.testRun.failCount > 0 && prefetchCount < MAX_PREFETCH_COUNT) { + // process + metadata.addDetails(processTestDetails(metadata)); + ++prefetchCount; + } + testRunObjects.add(metadata.toJson()); + } + + int[] topBuildResultCounts = null; + String topBuild = ""; + if (testRunMetadata.size() > 0) { + TestRunMetadata firstRun = testRunMetadata.get(0); + topBuild = firstRun.getDeviceInfo(); + endTime = firstRun.testRun.startTimestamp; + TestRunDetails topDetails = firstRun.getDetails(); + if (topDetails == null) { + topDetails = processTestDetails(firstRun); + } + topBuildResultCounts = topDetails.resultCounts; + + TestRunMetadata lastRun = testRunMetadata.get(testRunMetadata.size() - 1); + startTime = lastRun.testRun.startTimestamp; + } + + Set<String> profilingPoints = new HashSet<>(); + Query profilingPointQuery = + new Query(ProfilingPointRunEntity.KIND).setAncestor(testKey).setKeysOnly(); + for (Entity e : datastore.prepare(profilingPointQuery).asIterable()) { + profilingPoints.add(e.getKey().getName()); + } + + if (profilingPoints.size() == 0) { + profilingDataAlert = PROFILING_DATA_ALERT; + } + List<String> profilingPointNames = new ArrayList<>(profilingPoints); + Collections.sort(profilingPointNames); + + FilterUtil.setAttributes(request, parameterMap); + + request.setAttribute("testName", request.getParameter("testName")); + + request.setAttribute("error", profilingDataAlert); + + request.setAttribute("profilingPointNames", profilingPointNames); + request.setAttribute("resultNames", resultNames); + request.setAttribute("resultNamesJson", new Gson().toJson(resultNames)); + request.setAttribute("testRuns", new Gson().toJson(testRunObjects)); + + // data for pie chart + request.setAttribute("topBuildResultCounts", new Gson().toJson(topBuildResultCounts)); + request.setAttribute("topBuildId", topBuild); + request.setAttribute("startTime", new Gson().toJson(startTime)); + request.setAttribute("endTime", new Gson().toJson(endTime)); + request.setAttribute("hasNewer", + new Gson().toJson(DatastoreHelper.hasNewer(testKey, TestRunEntity.KIND, endTime))); + request.setAttribute("hasOlder", new Gson().toJson(DatastoreHelper.hasOlder( + testKey, TestRunEntity.KIND, startTime))); + request.setAttribute("unfiltered", unfiltered); + request.setAttribute("showPresubmit", showPresubmit); + request.setAttribute("showPostsubmit", showPostsubmit); + + request.setAttribute("branches", new Gson().toJson(DatastoreHelper.getAllBranches())); + request.setAttribute("devices", new Gson().toJson(DatastoreHelper.getAllBuildFlavors())); + + dispatcher = request.getRequestDispatcher(TABLE_JSP); + try { + dispatcher.forward(request, response); + } catch (ServletException e) { + logger.log(Level.SEVERE, "Servlet Exception caught : " + e.toString()); + } + } +} diff --git a/src/main/java/com/android/vts/servlet/VtsAlertJobServlet.java b/src/main/java/com/android/vts/servlet/VtsAlertJobServlet.java new file mode 100644 index 0000000..9e48108 --- /dev/null +++ b/src/main/java/com/android/vts/servlet/VtsAlertJobServlet.java @@ -0,0 +1,447 @@ +/* + * Copyright (c) 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.servlet; + +import com.android.vts.entity.DeviceInfoEntity; +import com.android.vts.entity.TestCaseRunEntity; +import com.android.vts.entity.TestCaseRunEntity.TestCase; +import com.android.vts.entity.TestEntity; +import com.android.vts.entity.TestEntity.TestCaseReference; +import com.android.vts.entity.TestRunEntity; +import com.android.vts.proto.VtsReportMessage.TestCaseResult; +import com.android.vts.util.DatastoreHelper; +import com.android.vts.util.EmailHelper; +import com.android.vts.util.FilterUtil; +import com.google.appengine.api.datastore.DatastoreFailureException; +import com.google.appengine.api.datastore.DatastoreService; +import com.google.appengine.api.datastore.DatastoreServiceFactory; +import com.google.appengine.api.datastore.DatastoreTimeoutException; +import com.google.appengine.api.datastore.Entity; +import com.google.appengine.api.datastore.EntityNotFoundException; +import com.google.appengine.api.datastore.Key; +import com.google.appengine.api.datastore.KeyFactory; +import com.google.appengine.api.datastore.Query; +import com.google.appengine.api.datastore.Query.Filter; +import com.google.appengine.api.datastore.Query.SortDirection; +import com.google.appengine.api.datastore.Transaction; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.ConcurrentModificationException; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.mail.Message; +import javax.mail.MessagingException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.math3.analysis.function.Add; + +/** Represents the notifications service which is automatically called on a fixed schedule. */ +public class VtsAlertJobServlet extends HttpServlet { + protected final Logger logger = Logger.getLogger(getClass().getName()); + + /** + * Creates an email footer with the provided link. + * + * @param link The (string) link to provide in the footer. + * @return The full HTML email footer. + */ + private String getFooter(String link) { + return "<br><br>For details, visit the" + + " <a href='" + link + "'>" + + "VTS dashboard.</a>"; + } + + /** + * Compose an email if the test is inactive. + * + * @param test The TestEntity document storing the test status. + * @param link Fully specified link to the test's status page. + * @param emails The list of email addresses to send the email. + * @param messages The message list in which to insert the inactivity notification email. + * @return True if the test is inactive, false otherwise. + */ + private boolean notifyIfInactive( + TestEntity test, String link, List<String> emails, List<Message> messages) { + long now = TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis()); + long diff = now - test.timestamp; + // Send an email daily to notify that the test hasn't been running. + // After 7 full days have passed, notifications will no longer be sent (i.e. the + // test is assumed to be deprecated). + if (diff > TimeUnit.DAYS.toMicros(1) && diff < TimeUnit.DAYS.toMicros(8) + && diff % TimeUnit.DAYS.toMicros(1) < TimeUnit.MINUTES.toMicros(3)) { + Date lastUpload = new Date(TimeUnit.MICROSECONDS.toMillis(test.timestamp)); + String uploadTimeString = + new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(lastUpload); + String subject = "Warning! Inactive test: " + test.testName; + String body = "Hello,<br><br>Test \"" + test.testName + "\" is inactive. " + + "No new data has been uploaded since " + uploadTimeString + "." + + getFooter(link); + try { + messages.add(EmailHelper.composeEmail(emails, subject, body)); + return true; + } catch (MessagingException | UnsupportedEncodingException e) { + logger.log(Level.WARNING, "Error composing email : ", e); + } + } + return false; + } + + /** + * Checks whether any new failures have occurred beginning since (and including) startTime. + * + * @param test The TestEntity object for the test. + * @param link The string URL linking to the test's status table. + * @param failedTestCaseMap The map of test case names to TestCase for those failing in the + * last status update. + * @param emailAddresses The list of email addresses to send notifications to. + * @param messages The email Message queue. + * @returns latest TestStatusMessage or null if no update is available. + * @throws IOException + */ + public TestEntity getTestStatus(TestEntity test, String link, + Map<String, TestCase> failedTestCaseMap, List<String> emailAddresses, + List<Message> messages) throws IOException { + DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); + String footer = getFooter(link); + + TestRunEntity mostRecentRun = null; + Map<String, TestCaseResult> mostRecentTestCaseResults = new HashMap<>(); + Map<String, TestCase> testCaseBreakageMap = new HashMap<>(); + int passingTestcaseCount = 0; + List<TestCaseReference> failingTestCases = new ArrayList<>(); + Set<String> fixedTestcases = new HashSet<>(); + Set<String> newTestcaseFailures = new HashSet<>(); + Set<String> continuedTestcaseFailures = new HashSet<>(); + Set<String> skippedTestcaseFailures = new HashSet<>(); + Set<String> transientTestcaseFailures = new HashSet<>(); + + String testName = test.testName; + Key testKey = KeyFactory.createKey(TestEntity.KIND, testName); + Filter testTypeFilter = FilterUtil.getTestTypeFilter(false, true, false); + Filter runFilter = FilterUtil.getTimeFilter( + testKey, TestRunEntity.KIND, test.timestamp + 1, null, testTypeFilter); + Query q = new Query(TestRunEntity.KIND) + .setAncestor(testKey) + .setFilter(runFilter) + .addSort(Entity.KEY_RESERVED_PROPERTY, SortDirection.DESCENDING); + + for (Entity testRun : datastore.prepare(q).asIterable()) { + TestRunEntity testRunEntity = TestRunEntity.fromEntity(testRun); + if (testRunEntity == null) { + logger.log(Level.WARNING, "Invalid test run detected: " + testRun.getKey()); + } + if (mostRecentRun == null) { + mostRecentRun = testRunEntity; + } + List<Key> testCaseKeys = new ArrayList<>(); + for (long testCaseId : testRunEntity.testCaseIds) { + testCaseKeys.add(KeyFactory.createKey(TestCaseRunEntity.KIND, testCaseId)); + } + Map<Key, Entity> entityMap = datastore.get(testCaseKeys); + for (Key testCaseKey : testCaseKeys) { + if (!entityMap.containsKey(testCaseKey)) { + logger.log(Level.WARNING, "Test case entity missing: " + testCaseKey); + continue; + } + Entity testCaseRun = entityMap.get(testCaseKey); + TestCaseRunEntity testCaseRunEntity = TestCaseRunEntity.fromEntity(testCaseRun); + if (testCaseRunEntity == null) { + logger.log(Level.WARNING, "Invalid test case run: " + testCaseRun.getKey()); + continue; + } + for (TestCase testCase : testCaseRunEntity.testCases) { + String testCaseName = testCase.name; + TestCaseResult result = TestCaseResult.valueOf(testCase.result); + + if (mostRecentRun == testRunEntity) { + mostRecentTestCaseResults.put(testCaseName, result); + } else { + if (!mostRecentTestCaseResults.containsKey(testCaseName)) { + // Deprecate notifications for tests that are not present on newer runs + continue; + } + TestCaseResult mostRecentRes = mostRecentTestCaseResults.get(testCaseName); + if (mostRecentRes == TestCaseResult.TEST_CASE_RESULT_SKIP) { + mostRecentTestCaseResults.put(testCaseName, result); + } else if (mostRecentRes == TestCaseResult.TEST_CASE_RESULT_PASS) { + // Test is passing now, witnessed a transient failure + if (result != TestCaseResult.TEST_CASE_RESULT_PASS + && result != TestCaseResult.TEST_CASE_RESULT_SKIP) { + transientTestcaseFailures.add(testCaseName); + } + } + } + + // Record test case breakages + if (result != TestCaseResult.TEST_CASE_RESULT_PASS + && result != TestCaseResult.TEST_CASE_RESULT_SKIP) { + testCaseBreakageMap.put(testCaseName, testCase); + } + } + } + } + + if (mostRecentRun == null) { + notifyIfInactive(test, link, emailAddresses, messages); + return null; + } + + for (String testCaseName : mostRecentTestCaseResults.keySet()) { + TestCaseResult mostRecentResult = mostRecentTestCaseResults.get(testCaseName); + boolean previouslyFailed = failedTestCaseMap.containsKey(testCaseName); + if (mostRecentResult == TestCaseResult.TEST_CASE_RESULT_SKIP) { + // persist previous status + if (previouslyFailed) { + failingTestCases.add( + new TestCaseReference(failedTestCaseMap.get(testCaseName))); + } else { + ++passingTestcaseCount; + } + } else if (mostRecentResult == TestCaseResult.TEST_CASE_RESULT_PASS) { + ++passingTestcaseCount; + if (previouslyFailed && !transientTestcaseFailures.contains(testCaseName)) { + fixedTestcases.add(testCaseName); + } + } else { + if (!previouslyFailed) { + newTestcaseFailures.add(testCaseName); + failingTestCases.add( + new TestCaseReference(testCaseBreakageMap.get(testCaseName))); + } else { + continuedTestcaseFailures.add(testCaseName); + failingTestCases.add( + new TestCaseReference(failedTestCaseMap.get(testCaseName))); + } + } + } + + Set<String> buildIdList = new HashSet<>(); + Query deviceQuery = new Query(DeviceInfoEntity.KIND).setAncestor(mostRecentRun.key); + for (Entity device : datastore.prepare(deviceQuery).asIterable()) { + DeviceInfoEntity deviceEntity = DeviceInfoEntity.fromEntity(device); + if (deviceEntity == null) { + continue; + } + buildIdList.add(deviceEntity.buildId); + } + String buildId = StringUtils.join(buildIdList, ","); + String summary = new String(); + if (newTestcaseFailures.size() + continuedTestcaseFailures.size() > 0) { + summary += "The following test cases failed in the latest test run:<br>"; + + // Add new test case failures to top of summary in bold font. + List<String> sortedNewTestcaseFailures = new ArrayList<>(newTestcaseFailures); + Collections.sort(sortedNewTestcaseFailures); + for (String testcaseName : sortedNewTestcaseFailures) { + summary += "- " + + "<b>" + testcaseName + "</b><br>"; + } + + // Add continued test case failures to summary. + List<String> sortedContinuedTestcaseFailures = + new ArrayList<>(continuedTestcaseFailures); + Collections.sort(sortedContinuedTestcaseFailures); + for (String testcaseName : sortedContinuedTestcaseFailures) { + summary += "- " + testcaseName + "<br>"; + } + } + if (fixedTestcases.size() > 0) { + // Add fixed test cases to summary. + summary += "<br><br>The following test cases were fixed in the latest test run:<br>"; + List<String> sortedFixedTestcases = new ArrayList<>(fixedTestcases); + Collections.sort(sortedFixedTestcases); + for (String testcaseName : sortedFixedTestcases) { + summary += "- <i>" + testcaseName + "</i><br>"; + } + } + if (transientTestcaseFailures.size() > 0) { + // Add transient test case failures to summary. + summary += "<br><br>The following transient test case failures occured:<br>"; + List<String> sortedTransientTestcaseFailures = + new ArrayList<>(transientTestcaseFailures); + Collections.sort(sortedTransientTestcaseFailures); + for (String testcaseName : sortedTransientTestcaseFailures) { + summary += "- " + testcaseName + "<br>"; + } + } + if (skippedTestcaseFailures.size() > 0) { + // Add skipped test case failures to summary. + summary += "<br><br>The following test cases have not been run since failing:<br>"; + List<String> sortedSkippedTestcaseFailures = new ArrayList<>(skippedTestcaseFailures); + Collections.sort(sortedSkippedTestcaseFailures); + for (String testcaseName : sortedSkippedTestcaseFailures) { + summary += "- " + testcaseName + "<br>"; + } + } + + if (newTestcaseFailures.size() > 0) { + String subject = "New test failures in " + testName + " @ " + buildId; + String body = "Hello,<br><br>Test cases are failing in " + testName + + " for device build ID(s): " + buildId + ".<br><br>" + summary + footer; + try { + messages.add(EmailHelper.composeEmail(emailAddresses, subject, body)); + } catch (MessagingException | UnsupportedEncodingException e) { + logger.log(Level.WARNING, "Error composing email : ", e); + } + } else if (continuedTestcaseFailures.size() > 0) { + String subject = "Continued test failures in " + testName + " @ " + buildId; + String body = "Hello,<br><br>Test cases are failing in " + testName + + " for device build ID(s): " + buildId + ".<br><br>" + summary + footer; + try { + messages.add(EmailHelper.composeEmail(emailAddresses, subject, body)); + } catch (MessagingException | UnsupportedEncodingException e) { + logger.log(Level.WARNING, "Error composing email : ", e); + } + } else if (transientTestcaseFailures.size() > 0) { + String subject = "Transient test failure in " + testName + " @ " + buildId; + String body = "Hello,<br><br>Some test cases failed in " + testName + " but tests all " + + "are passing in the latest device build(s): " + buildId + ".<br><br>" + + summary + footer; + try { + messages.add(EmailHelper.composeEmail(emailAddresses, subject, body)); + } catch (MessagingException | UnsupportedEncodingException e) { + logger.log(Level.WARNING, "Error composing email : ", e); + } + } else if (fixedTestcases.size() > 0) { + String subject = "All test cases passing in " + testName + " @ " + buildId; + String body = "Hello,<br><br>All test cases passed in " + testName + + " for device build ID(s): " + buildId + "!<br><br>" + summary + footer; + try { + messages.add(EmailHelper.composeEmail(emailAddresses, subject, body)); + } catch (MessagingException | UnsupportedEncodingException e) { + logger.log(Level.WARNING, "Error composing email : ", e); + } + } + return new TestEntity(test.testName, mostRecentRun.startTimestamp, passingTestcaseCount, + failingTestCases.size(), failingTestCases); + } + + /** + * Process the current test case failures for a test. + * + * @param testEntity The TestEntity object for the test. + * @returns a map from test case name to the test case run ID for which the test case failed. + */ + public static Map<String, TestCase> getCurrentFailures(TestEntity testEntity) { + if (testEntity.failingTestCases == null || testEntity.failingTestCases.size() == 0) { + return new HashMap<>(); + } + DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); + Map<String, TestCase> failingTestcases = new HashMap<>(); + Set<Key> gets = new HashSet<>(); + for (TestCaseReference testCaseRef : testEntity.failingTestCases) { + gets.add(KeyFactory.createKey(TestCaseRunEntity.KIND, testCaseRef.parentId)); + } + if (gets.size() == 0) { + return failingTestcases; + } + Map<Key, Entity> testCaseMap = datastore.get(gets); + + for (TestCaseReference testCaseRef : testEntity.failingTestCases) { + Key key = KeyFactory.createKey(TestCaseRunEntity.KIND, testCaseRef.parentId); + if (!testCaseMap.containsKey(key)) { + continue; + } + Entity testCaseRun = testCaseMap.get(key); + TestCaseRunEntity testCaseRunEntity = TestCaseRunEntity.fromEntity(testCaseRun); + if (testCaseRunEntity.testCases.size() <= testCaseRef.offset) { + continue; + } + TestCase testCase = testCaseRunEntity.testCases.get(testCaseRef.offset); + failingTestcases.put(testCase.name, testCase); + } + return failingTestcases; + } + + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { + DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); + Query q = new Query(TestEntity.KIND); + for (Entity test : datastore.prepare(q).asIterable()) { + TestEntity testEntity = TestEntity.fromEntity(test); + if (testEntity == null) { + logger.log(Level.WARNING, "Corrupted test entity: " + test.getKey().getName()); + continue; + } + List<String> emails = EmailHelper.getSubscriberEmails(test.getKey()); + + StringBuffer fullUrl = request.getRequestURL(); + String baseUrl = fullUrl.substring(0, fullUrl.indexOf(request.getRequestURI())); + String link = baseUrl + "/show_table?testName=" + testEntity.testName; + + List<Message> messageQueue = new ArrayList<>(); + Map<String, TestCase> failedTestcaseMap = getCurrentFailures(testEntity); + + TestEntity newTestEntity = + getTestStatus(testEntity, link, failedTestcaseMap, emails, messageQueue); + + // Send any inactivity notifications + if (newTestEntity == null) { + if (messageQueue.size() > 0) { + EmailHelper.sendAll(messageQueue); + } + continue; + } + + int retries = 0; + while (true) { + Transaction txn = datastore.beginTransaction(); + try { + try { + testEntity = TestEntity.fromEntity(datastore.get(test.getKey())); + + // Another job updated the test entity + if (testEntity == null || testEntity.timestamp >= newTestEntity.timestamp) { + txn.rollback(); + } else { // This update is most recent. + datastore.put(newTestEntity.toEntity()); + txn.commit(); + EmailHelper.sendAll(messageQueue); + } + } catch (EntityNotFoundException e) { + logger.log(Level.INFO, + "Test disappeared during updated: " + newTestEntity.testName); + } + break; + } catch (ConcurrentModificationException | DatastoreFailureException + | DatastoreTimeoutException e) { + logger.log(Level.WARNING, "Retrying alert job insert: " + test.getKey()); + if (retries++ >= DatastoreHelper.MAX_WRITE_RETRIES) { + logger.log(Level.SEVERE, "Exceeded alert job retries: " + test.getKey()); + throw e; + } + } finally { + if (txn.isActive()) { + txn.rollback(); + } + } + } + } + } +} diff --git a/src/main/java/com/android/vts/servlet/VtsPerformanceJobServlet.java b/src/main/java/com/android/vts/servlet/VtsPerformanceJobServlet.java new file mode 100644 index 0000000..616f5c7 --- /dev/null +++ b/src/main/java/com/android/vts/servlet/VtsPerformanceJobServlet.java @@ -0,0 +1,258 @@ +/* + * Copyright (c) 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.servlet; + +import com.android.vts.entity.TestEntity; +import com.android.vts.util.EmailHelper; +import com.android.vts.util.PerformanceSummary; +import com.android.vts.util.PerformanceUtil; +import com.android.vts.util.PerformanceUtil.TimeInterval; +import com.android.vts.util.ProfilingPointSummary; +import com.android.vts.util.StatSummary; +import com.google.appengine.api.datastore.DatastoreService; +import com.google.appengine.api.datastore.DatastoreServiceFactory; +import com.google.appengine.api.datastore.Entity; +import com.google.appengine.api.datastore.Key; +import com.google.appengine.api.datastore.Query; +import java.io.IOException; +import java.math.RoundingMode; +import java.text.DecimalFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** Represents the notifications service which is automatically called on a fixed schedule. */ +public class VtsPerformanceJobServlet extends HttpServlet { + private static final String MEAN = "Mean"; + private static final String MAX = "Max"; + private static final String MIN = "Min"; + private static final String MIN_DELTA = "ΔMin (%)"; + private static final String MAX_DELTA = "ΔMax (%)"; + private static final String HIGHER_IS_BETTER = + "Note: Higher values are better. Maximum is the best-case performance."; + private static final String LOWER_IS_BETTER = + "Note: Lower values are better. Minimum is the best-case performance."; + private static final String STD = "Std"; + private static final String SUBJECT_PREFIX = "Daily Performance Digest: "; + private static final String LAST_WEEK = "Last Week"; + private static final String LABEL_STYLE = "font-family: arial"; + private static final String SUBTEXT_STYLE = "font-family: arial; font-size: 12px"; + private static final String TABLE_STYLE = + "width: 100%; border-collapse: collapse; border: 1px solid black; font-size: 12px; font-family: arial;"; + private static final String SECTION_LABEL_STYLE = + "border: 1px solid black; border-bottom: none; background-color: lightgray;"; + private static final String COL_LABEL_STYLE = + "border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;"; + private static final String HEADER_COL_STYLE = + "border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;"; + private static final String INNER_CELL_STYLE = + "border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;"; + private static final String OUTER_CELL_STYLE = + "border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;"; + + private static final DecimalFormat FORMATTER; + + /** + * Initialize the decimal formatter. + */ + static { + FORMATTER = new DecimalFormat("#.##"); + FORMATTER.setRoundingMode(RoundingMode.HALF_UP); + } + + /** + * Generates an HTML summary of the performance changes for the profiling results in the + * specified + * table. + * + * <p>Retrieves the past 24 hours of profiling data and compares it to the 24 hours that + * preceded + * it. Creates a table representation of the mean and standard deviation for each profiling + * point. + * When performance degrades, the cell is shaded red. + * + * @param testName The name of the test whose profiling data to summarize. + * @param perfSummaries List of PerformanceSummary objects for each profiling run (in reverse + * chronological order). + * @param labels List of string labels for use as the column headers. + * @returns An HTML string containing labeled table summaries. + */ + public static String getPeformanceSummary( + String testName, List<PerformanceSummary> perfSummaries, List<String> labels) { + if (perfSummaries.size() == 0) + return ""; + PerformanceSummary now = perfSummaries.get(0); + String tableHTML = "<p style='" + LABEL_STYLE + "'><b>"; + tableHTML += testName + "</b></p>"; + for (String profilingPoint : now.getProfilingPointNames()) { + ProfilingPointSummary summary = now.getProfilingPointSummary(profilingPoint); + tableHTML += "<table cellpadding='2' style='" + TABLE_STYLE + "'>"; + + // Format header rows + String[] headerRows = new String[] {profilingPoint, summary.yLabel}; + int colspan = labels.size() * 4; + for (String content : headerRows) { + tableHTML += "<tr><td colspan='" + colspan + "'>" + content + "</td></tr>"; + } + + // Format section labels + tableHTML += "<tr>"; + for (int i = 0; i < labels.size(); i++) { + String content = labels.get(i); + tableHTML += "<th style='" + SECTION_LABEL_STYLE + "' "; + if (i == 0) + tableHTML += "colspan='1'"; + else if (i == 1) + tableHTML += "colspan='3'"; + else + tableHTML += "colspan='4'"; + tableHTML += ">" + content + "</th>"; + } + tableHTML += "</tr>"; + + String deltaString; + String bestCaseString; + String subtext; + switch (now.getProfilingPointSummary(profilingPoint).getRegressionMode()) { + case VTS_REGRESSION_MODE_DECREASING: + deltaString = MAX_DELTA; + bestCaseString = MAX; + subtext = HIGHER_IS_BETTER; + break; + default: + deltaString = MIN_DELTA; + bestCaseString = MIN; + subtext = LOWER_IS_BETTER; + break; + } + + // Format column labels + tableHTML += "<tr>"; + for (int i = 0; i < labels.size(); i++) { + if (i > 1) { + tableHTML += "<th style='" + COL_LABEL_STYLE + "'>" + deltaString + "</th>"; + } + if (i == 0) { + tableHTML += "<th style='" + COL_LABEL_STYLE + "'>"; + tableHTML += summary.xLabel + "</th>"; + } else if (i > 0) { + tableHTML += "<th style='" + COL_LABEL_STYLE + "'>" + bestCaseString + "</th>"; + tableHTML += "<th style='" + COL_LABEL_STYLE + "'>" + MEAN + "</th>"; + tableHTML += "<th style='" + COL_LABEL_STYLE + "'>" + STD + "</th>"; + } + } + tableHTML += "</tr>"; + + // Populate data cells + for (StatSummary stats : summary) { + String label = stats.getLabel(); + tableHTML += "<tr><td style='" + HEADER_COL_STYLE + "'>" + label; + tableHTML += "</td><td style='" + INNER_CELL_STYLE + "'>"; + tableHTML += FORMATTER.format(stats.getBestCase()) + "</td>"; + tableHTML += "<td style='" + INNER_CELL_STYLE + "'>"; + tableHTML += FORMATTER.format(stats.getMean()) + "</td>"; + tableHTML += "<td style='" + OUTER_CELL_STYLE + "'>"; + tableHTML += FORMATTER.format(stats.getStd()) + "</td>"; + for (int i = 1; i < perfSummaries.size(); i++) { + PerformanceSummary oldPerfSummary = perfSummaries.get(i); + if (oldPerfSummary.hasProfilingPoint(profilingPoint)) { + StatSummary baseline = + oldPerfSummary.getProfilingPointSummary(profilingPoint) + .getStatSummary(label); + tableHTML += PerformanceUtil.getBestCasePerformanceComparisonHTML( + baseline, stats, "", "", INNER_CELL_STYLE, OUTER_CELL_STYLE); + } else + tableHTML += "<td></td><td></td><td></td><td></td>"; + } + tableHTML += "</tr>"; + } + tableHTML += "</table>"; + tableHTML += "<i style='" + SUBTEXT_STYLE + "'>" + subtext + "</i><br><br>"; + } + return tableHTML; + } + + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { + DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); + Set<Key> allTestKeys = new HashSet<>(); + + Query q = new Query(TestEntity.KIND).setKeysOnly(); + for (Entity test : datastore.prepare(q).asIterable()) { + if (test.getKey().getName() == null) { + continue; + } + allTestKeys.add(test.getKey()); + } + + // Add today to the list of time intervals to analyze + List<TimeInterval> timeIntervals = new ArrayList<>(); + long nowMilli = System.currentTimeMillis(); + long nowMicro = TimeUnit.MILLISECONDS.toMicros(nowMilli); + String dateString = new SimpleDateFormat("MM-dd-yyyy").format(new Date(nowMilli)); + TimeInterval today = + new TimeInterval(nowMicro - TimeUnit.DAYS.toMicros(1), nowMicro, dateString); + timeIntervals.add(today); + + // Add yesterday as a baseline time interval for analysis + long oneDayAgo = nowMicro - TimeUnit.DAYS.toMicros(1); + String dateStringYesterday = new SimpleDateFormat( + "MM-dd-yyyy").format(new Date(TimeUnit.MICROSECONDS.toMillis(oneDayAgo))); + TimeInterval yesterday = new TimeInterval( + oneDayAgo - TimeUnit.DAYS.toMicros(1), oneDayAgo, dateStringYesterday); + timeIntervals.add(yesterday); + + // Add last week as a baseline time interval for analysis + long oneWeek = TimeUnit.DAYS.toMicros(7); + long oneWeekAgo = nowMicro - oneWeek; + TimeInterval lastWeek = new TimeInterval(oneWeekAgo - oneWeek, oneWeekAgo, LAST_WEEK); + timeIntervals.add(lastWeek); + + for (Key testKey : allTestKeys) { + List<PerformanceSummary> perfSummaries = new ArrayList<>(); + List<String> labels = new ArrayList<>(); + labels.add(""); + for (TimeInterval interval : timeIntervals) { + PerformanceSummary perfSummary = new PerformanceSummary(); + PerformanceUtil.updatePerformanceSummary( + testKey.getName(), interval.start, interval.end, null, perfSummary); + if (perfSummary.size() == 0) { + continue; + } + perfSummaries.add(perfSummary); + labels.add(interval.label); + } + String body = getPeformanceSummary(testKey.getName(), perfSummaries, labels); + if (body == null || body.equals("")) { + continue; + } + List<String> emails = EmailHelper.getSubscriberEmails(testKey); + if (emails.size() == 0) { + continue; + } + String subject = SUBJECT_PREFIX + testKey.getName(); + EmailHelper.send(emails, subject, body); + } + } +} diff --git a/src/main/java/com/android/vts/util/DatastoreHelper.java b/src/main/java/com/android/vts/util/DatastoreHelper.java new file mode 100644 index 0000000..4710b88 --- /dev/null +++ b/src/main/java/com/android/vts/util/DatastoreHelper.java @@ -0,0 +1,457 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * <p>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 + * + * <p>http://www.apache.org/licenses/LICENSE-2.0 + * + * <p>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. + */ +package com.android.vts.util; + +import com.android.vts.entity.CoverageEntity; +import com.android.vts.entity.DeviceInfoEntity; +import com.android.vts.entity.ProfilingPointRunEntity; +import com.android.vts.entity.TestCaseRunEntity; +import com.android.vts.entity.TestEntity; +import com.android.vts.entity.TestPlanEntity; +import com.android.vts.entity.TestPlanRunEntity; +import com.android.vts.entity.TestRunEntity; +import com.android.vts.entity.TestRunEntity.TestRunType; +import com.android.vts.proto.VtsReportMessage.AndroidDeviceInfoMessage; +import com.android.vts.proto.VtsReportMessage.CoverageReportMessage; +import com.android.vts.proto.VtsReportMessage.LogMessage; +import com.android.vts.proto.VtsReportMessage.ProfilingReportMessage; +import com.android.vts.proto.VtsReportMessage.TestCaseReportMessage; +import com.android.vts.proto.VtsReportMessage.TestCaseResult; +import com.android.vts.proto.VtsReportMessage.TestPlanReportMessage; +import com.android.vts.proto.VtsReportMessage.TestReportMessage; +import com.google.appengine.api.datastore.DatastoreFailureException; +import com.google.appengine.api.datastore.DatastoreService; +import com.google.appengine.api.datastore.DatastoreServiceFactory; +import com.google.appengine.api.datastore.DatastoreTimeoutException; +import com.google.appengine.api.datastore.Entity; +import com.google.appengine.api.datastore.EntityNotFoundException; +import com.google.appengine.api.datastore.FetchOptions; +import com.google.appengine.api.datastore.Key; +import com.google.appengine.api.datastore.KeyFactory; +import com.google.appengine.api.datastore.KeyRange; +import com.google.appengine.api.datastore.PropertyProjection; +import com.google.appengine.api.datastore.Query; +import com.google.appengine.api.datastore.Query.Filter; +import com.google.appengine.api.datastore.Query.FilterOperator; +import com.google.appengine.api.datastore.Query.FilterPredicate; +import com.google.appengine.api.datastore.Transaction; +import java.io.IOException; +import java.util.ArrayList; +import java.util.ConcurrentModificationException; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** DatastoreHelper, a helper class for interacting with Cloud Datastore. */ +public class DatastoreHelper { + protected static final Logger logger = Logger.getLogger(DatastoreHelper.class.getName()); + public static final int MAX_WRITE_RETRIES = 5; + + /** + * Returns true if there are data points newer than lowerBound in the results table. + * + * @param parentKey The parent key to use in the query. + * @param kind The query entity kind. + * @param lowerBound The (exclusive) lower time bound, long, microseconds. + * @return boolean True if there are newer data points. + * @throws IOException + */ + public static boolean hasNewer(Key parentKey, String kind, Long lowerBound) throws IOException { + if (lowerBound == null || lowerBound <= 0) + return false; + DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); + Key startKey = KeyFactory.createKey(parentKey, kind, lowerBound); + Filter startFilter = new FilterPredicate( + Entity.KEY_RESERVED_PROPERTY, FilterOperator.GREATER_THAN, startKey); + Query q = new Query(kind).setAncestor(parentKey).setFilter(startFilter).setKeysOnly(); + return datastore.prepare(q).countEntities(FetchOptions.Builder.withLimit(1)) > 0; + } + + /** + * Returns true if there are data points older than upperBound in the table. + * + * @param parentKey The parent key to use in the query. + * @param kind The query entity kind. + * @param upperBound The (exclusive) upper time bound, long, microseconds. + * @return boolean True if there are older data points. + * @throws IOException + */ + public static boolean hasOlder(Key parentKey, String kind, Long upperBound) throws IOException { + if (upperBound == null || upperBound <= 0) + return false; + DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); + Key endKey = KeyFactory.createKey(parentKey, kind, upperBound); + Filter endFilter = + new FilterPredicate(Entity.KEY_RESERVED_PROPERTY, FilterOperator.LESS_THAN, endKey); + Query q = new Query(kind).setAncestor(parentKey).setFilter(endFilter).setKeysOnly(); + return datastore.prepare(q).countEntities(FetchOptions.Builder.withLimit(1)) > 0; + } + + /** + * Determines if any entities match the provided query. + * + * @param query The query to test. + * @return true if entities match the query. + */ + public static boolean hasEntities(Query query) { + DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); + FetchOptions limitOne = FetchOptions.Builder.withLimit(1); + return datastore.prepare(query).countEntities(limitOne) > 0; + } + + /** + * Get all of the target product names. + * + * @return a list of all device product names. + */ + public static List<String> getAllProducts() { + DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); + Query query = new Query(DeviceInfoEntity.KIND) + .addProjection(new PropertyProjection( + DeviceInfoEntity.PRODUCT, String.class)) + .setDistinct(true); + List<String> devices = new ArrayList<>(); + for (Entity e : datastore.prepare(query).asIterable()) { + devices.add((String) e.getProperty(DeviceInfoEntity.PRODUCT)); + } + return devices; + } + + /** + * Get all of the devices branches. + * + * @return a list of all branches. + */ + public static List<String> getAllBranches() { + DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); + Query query = new Query(DeviceInfoEntity.KIND) + .addProjection( + new PropertyProjection(DeviceInfoEntity.BRANCH, String.class)) + .setDistinct(true); + List<String> devices = new ArrayList<>(); + for (Entity e : datastore.prepare(query).asIterable()) { + devices.add((String) e.getProperty(DeviceInfoEntity.BRANCH)); + } + return devices; + } + + /** + * Get all of the device build flavors. + * + * @return a list of all device build flavors. + */ + public static List<String> getAllBuildFlavors() { + DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); + Query query = new Query(DeviceInfoEntity.KIND) + .addProjection(new PropertyProjection( + DeviceInfoEntity.BUILD_FLAVOR, String.class)) + .setDistinct(true); + List<String> devices = new ArrayList<>(); + for (Entity e : datastore.prepare(query).asIterable()) { + devices.add((String) e.getProperty(DeviceInfoEntity.BUILD_FLAVOR)); + } + return devices; + } + + /** + * Upload data from a test report message + * + * @param report The test report containing data to upload. + */ + public static void insertTestReport(TestReportMessage report) { + DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); + Set<Entity> puts = new HashSet<>(); + + if (!report.hasStartTimestamp() || !report.hasEndTimestamp() || !report.hasTest() + || !report.hasHostInfo() || !report.hasBuildInfo()) { + // missing information + return; + } + long startTimestamp = report.getStartTimestamp(); + long endTimestamp = report.getEndTimestamp(); + String testName = report.getTest().toStringUtf8(); + String testBuildId = report.getBuildInfo().getId().toStringUtf8(); + String hostName = report.getHostInfo().getHostname().toStringUtf8(); + + Entity testEntity = new TestEntity(testName).toEntity(); + List<Long> testCaseIds = new ArrayList<>(); + + Key testRunKey = KeyFactory.createKey( + testEntity.getKey(), TestRunEntity.KIND, report.getStartTimestamp()); + + long passCount = 0; + long failCount = 0; + long coveredLineCount = 0; + long totalLineCount = 0; + + List<TestCaseRunEntity> testCases = new ArrayList<>(); + + // Process test cases + for (TestCaseReportMessage testCase : report.getTestCaseList()) { + String testCaseName = testCase.getName().toStringUtf8(); + TestCaseResult result = testCase.getTestResult(); + // Track global pass/fail counts + if (result == TestCaseResult.TEST_CASE_RESULT_PASS) { + ++passCount; + } else if (result != TestCaseResult.TEST_CASE_RESULT_SKIP) { + ++failCount; + } + String systraceLink = null; + if (testCase.getSystraceCount() > 0 + && testCase.getSystraceList().get(0).getUrlCount() > 0) { + systraceLink = testCase.getSystraceList().get(0).getUrl(0).toStringUtf8(); + } + // Process coverage data for test case + for (CoverageReportMessage coverage : testCase.getCoverageList()) { + CoverageEntity coverageEntity = + CoverageEntity.fromCoverageReport(testRunKey, testCaseName, coverage); + if (coverageEntity == null) { + logger.log(Level.WARNING, "Invalid coverage report in test run " + testRunKey); + continue; + } + coveredLineCount += coverageEntity.coveredLineCount; + totalLineCount += coverageEntity.totalLineCount; + puts.add(coverageEntity.toEntity()); + } + // Process profiling data for test case + for (ProfilingReportMessage profiling : testCase.getProfilingList()) { + ProfilingPointRunEntity profilingEntity = + ProfilingPointRunEntity.fromProfilingReport(testRunKey, profiling); + if (profilingEntity == null) { + logger.log(Level.WARNING, "Invalid profiling report in test run " + testRunKey); + } + puts.add(profilingEntity.toEntity()); + } + + int lastIndex = testCases.size() - 1; + if (lastIndex < 0 || testCases.get(lastIndex).isFull()) { + KeyRange keys = datastore.allocateIds(TestCaseRunEntity.KIND, 1); + testCaseIds.add(keys.getStart().getId()); + testCases.add(new TestCaseRunEntity(keys.getStart())); + ++lastIndex; + } + TestCaseRunEntity testCaseEntity = testCases.get(lastIndex); + testCaseEntity.addTestCase(testCaseName, result.getNumber()); + testCaseEntity.setSystraceUrl(systraceLink); + } + List<Entity> testCasePuts = new ArrayList<>(); + for (TestCaseRunEntity testCaseEntity : testCases) { + testCasePuts.add(testCaseEntity.toEntity()); + } + datastore.put(testCasePuts); + + // Process device information + TestRunType testRunType = null; + for (AndroidDeviceInfoMessage device : report.getDeviceInfoList()) { + DeviceInfoEntity deviceInfoEntity = + DeviceInfoEntity.fromDeviceInfoMessage(testRunKey, device); + if (deviceInfoEntity == null) { + logger.log(Level.WARNING, "Invalid device info in test run " + testRunKey); + } + + // Run type on devices must be the same, else set to OTHER + TestRunType runType = TestRunType.fromBuildId(deviceInfoEntity.buildId); + if (testRunType == null) { + testRunType = runType; + } else if (runType != testRunType) { + testRunType = TestRunType.OTHER; + } + puts.add(deviceInfoEntity.toEntity()); + } + + // Overall run type should be determined by the device builds unless test build is OTHER + if (testRunType == null) { + testRunType = TestRunType.fromBuildId(testBuildId); + } else if (TestRunType.fromBuildId(testBuildId) == TestRunType.OTHER) { + testRunType = TestRunType.OTHER; + } + + // Process global coverage data + for (CoverageReportMessage coverage : report.getCoverageList()) { + CoverageEntity coverageEntity = + CoverageEntity.fromCoverageReport(testRunKey, new String(), coverage); + if (coverageEntity == null) { + logger.log(Level.WARNING, "Invalid coverage report in test run " + testRunKey); + continue; + } + coveredLineCount += coverageEntity.coveredLineCount; + totalLineCount += coverageEntity.totalLineCount; + puts.add(coverageEntity.toEntity()); + } + + // Process global profiling data + for (ProfilingReportMessage profiling : report.getProfilingList()) { + ProfilingPointRunEntity profilingEntity = + ProfilingPointRunEntity.fromProfilingReport(testRunKey, profiling); + if (profilingEntity == null) { + logger.log(Level.WARNING, "Invalid profiling report in test run " + testRunKey); + } + puts.add(profilingEntity.toEntity()); + } + + List<String> logLinks = new ArrayList<>(); + // Process log data + for (LogMessage log : report.getLogList()) { + if (!log.hasUrl()) + continue; + logLinks.add(log.getUrl().toStringUtf8()); + } + + TestRunEntity testRunEntity = new TestRunEntity(testEntity.getKey(), testRunType, + startTimestamp, endTimestamp, testBuildId, hostName, passCount, failCount, + testCaseIds, logLinks, coveredLineCount, totalLineCount); + puts.add(testRunEntity.toEntity()); + + int retries = 0; + while (true) { + Transaction txn = datastore.beginTransaction(); + try { + // Check if test already exists in the database + try { + datastore.get(testEntity.getKey()); + } catch (EntityNotFoundException e) { + puts.add(testEntity); + } + datastore.put(puts); + txn.commit(); + break; + } catch (ConcurrentModificationException | DatastoreFailureException + | DatastoreTimeoutException e) { + puts.remove(testEntity); + logger.log(Level.WARNING, "Retrying test run insert: " + testEntity.getKey()); + if (retries++ >= MAX_WRITE_RETRIES) { + logger.log(Level.SEVERE, + "Exceeded maximum test run retries: " + testEntity.getKey()); + throw e; + } + } finally { + if (txn.isActive()) { + logger.log(Level.WARNING, + "Transaction rollback forced for run: " + testRunEntity.key); + txn.rollback(); + } + } + } + } + + /** + * Upload data from a test plan report message + * + * @param report The test plan report containing data to upload. + */ + public static void insertTestPlanReport(TestPlanReportMessage report) { + DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); + List<Entity> puts = new ArrayList<>(); + + List<String> testModules = report.getTestModuleNameList(); + List<Long> testTimes = report.getTestModuleStartTimestampList(); + if (testModules.size() != testTimes.size() || !report.hasTestPlanName()) { + logger.log(Level.WARNING, "TestPlanReportMessage is missing information."); + return; + } + + String testPlanName = report.getTestPlanName(); + Entity testPlanEntity = new TestPlanEntity(testPlanName).toEntity(); + List<Key> testRunKeys = new ArrayList<>(); + for (int i = 0; i < testModules.size(); i++) { + String test = testModules.get(i); + long time = testTimes.get(i); + Key parentKey = KeyFactory.createKey(TestEntity.KIND, test); + Key testRunKey = KeyFactory.createKey(parentKey, TestRunEntity.KIND, time); + testRunKeys.add(testRunKey); + } + Map<Key, Entity> testRuns = datastore.get(testRunKeys); + long passCount = 0; + long failCount = 0; + long startTimestamp = -1; + long endTimestamp = -1; + String testBuildId = null; + TestRunType type = null; + Set<DeviceInfoEntity> devices = new HashSet<>(); + for (Key testRunKey : testRuns.keySet()) { + TestRunEntity testRun = TestRunEntity.fromEntity(testRuns.get(testRunKey)); + if (testRun == null) { + continue; // not a valid test run + } + passCount += testRun.passCount; + failCount += testRun.failCount; + if (startTimestamp < 0 || testRunKey.getId() < startTimestamp) { + startTimestamp = testRunKey.getId(); + } + if (endTimestamp < 0 || testRun.endTimestamp > endTimestamp) { + endTimestamp = testRun.endTimestamp; + } + if (type == null) { + type = testRun.type; + } else if (type != testRun.type) { + type = TestRunType.OTHER; + } + testBuildId = testRun.testBuildId; + Query deviceInfoQuery = new Query(DeviceInfoEntity.KIND).setAncestor(testRunKey); + for (Entity deviceInfoEntity : datastore.prepare(deviceInfoQuery).asIterable()) { + DeviceInfoEntity device = DeviceInfoEntity.fromEntity(deviceInfoEntity); + if (device == null) { + continue; // invalid entity + } + devices.add(device); + } + } + if (startTimestamp < 0 || testBuildId == null || type == null) { + logger.log(Level.WARNING, "Couldn't infer test run information from runs."); + return; + } + TestPlanRunEntity testPlanRun = new TestPlanRunEntity(testPlanEntity.getKey(), testPlanName, + type, startTimestamp, endTimestamp, testBuildId, passCount, failCount, testRunKeys); + + // Create the device infos. + for (DeviceInfoEntity device : devices) { + puts.add(device.copyWithParent(testPlanRun.key).toEntity()); + } + puts.add(testPlanRun.toEntity()); + + int retries = 0; + while (true) { + Transaction txn = datastore.beginTransaction(); + try { + // Check if test already exists in the database + try { + datastore.get(testPlanEntity.getKey()); + } catch (EntityNotFoundException e) { + puts.add(testPlanEntity); + } + datastore.put(puts); + txn.commit(); + break; + } catch (ConcurrentModificationException | DatastoreFailureException + | DatastoreTimeoutException e) { + puts.remove(testPlanEntity); + logger.log(Level.WARNING, "Retrying test plan insert: " + testPlanEntity.getKey()); + if (retries++ >= MAX_WRITE_RETRIES) { + logger.log(Level.SEVERE, + "Exceeded maximum test plan retries: " + testPlanEntity.getKey()); + throw e; + } + } finally { + if (txn.isActive()) { + logger.log(Level.WARNING, + "Transaction rollback forced for plan run: " + testPlanRun.key); + txn.rollback(); + } + } + } + } +} diff --git a/src/main/java/com/android/vts/util/EmailHelper.java b/src/main/java/com/android/vts/util/EmailHelper.java new file mode 100644 index 0000000..dd14d19 --- /dev/null +++ b/src/main/java/com/android/vts/util/EmailHelper.java @@ -0,0 +1,152 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * <p>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 + * + * <p>http://www.apache.org/licenses/LICENSE-2.0 + * + * <p>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. + */ +package com.android.vts.util; + +import com.android.vts.entity.UserFavoriteEntity; +import com.google.appengine.api.datastore.DatastoreService; +import com.google.appengine.api.datastore.DatastoreServiceFactory; +import com.google.appengine.api.datastore.Entity; +import com.google.appengine.api.datastore.Key; +import com.google.appengine.api.datastore.Query; +import com.google.appengine.api.datastore.Query.Filter; +import com.google.appengine.api.datastore.Query.FilterOperator; +import com.google.appengine.api.datastore.Query.FilterPredicate; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Properties; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.mail.Message; +import javax.mail.MessagingException; +import javax.mail.Session; +import javax.mail.Transport; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeMessage; +import org.apache.commons.lang.StringUtils; + +/** EmailHelper, a helper class for building and sending emails. */ +public class EmailHelper { + protected static final Logger logger = Logger.getLogger(EmailHelper.class.getName()); + protected static final String DEFAULT_EMAIL = System.getProperty("DEFAULT_EMAIL"); + protected static final String EMAIL_DOMAIN = System.getProperty("EMAIL_DOMAIN"); + protected static final String SENDER_EMAIL = System.getProperty("SENDER_EMAIL"); + private static final String VTS_EMAIL_NAME = "VTS Alert Bot"; + + /** + * Fetches the list of subscriber email addresses for a test. + * + * @param testKey The key for the test for which to fetch the email addresses. + * @returns List of email addresses (String). + * @throws IOException + */ + public static List<String> getSubscriberEmails(Key testKey) throws IOException { + DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); + Filter testFilter = + new FilterPredicate(UserFavoriteEntity.TEST_KEY, FilterOperator.EQUAL, testKey); + Query favoritesQuery = new Query(UserFavoriteEntity.KIND).setFilter(testFilter); + Set<String> emailSet = new HashSet<>(); + if (!StringUtils.isBlank(DEFAULT_EMAIL)) { + emailSet.add(DEFAULT_EMAIL); + } + for (Entity favorite : datastore.prepare(favoritesQuery).asIterable()) { + UserFavoriteEntity favoriteEntity = UserFavoriteEntity.fromEntity(favorite); + if (favoriteEntity != null && favoriteEntity.user != null + && favoriteEntity.user.getEmail().endsWith(EMAIL_DOMAIN)) { + emailSet.add(favoriteEntity.user.getEmail()); + } + } + return new ArrayList<>(emailSet); + } + + /** + * Sends an email to the specified email address to notify of a test status change. + * + * @param emails List of subscriber email addresses (byte[]) to which the email should be sent. + * @param subject The email subject field, string. + * @param body The html (string) body to send in the email. + * @returns The Message object to be sent. + * @throws MessagingException, UnsupportedEncodingException + */ + public static Message composeEmail(List<String> emails, String subject, String body) + throws MessagingException, UnsupportedEncodingException { + if (emails.size() == 0) { + throw new MessagingException("No subscriber email addresses provided"); + } + Properties props = new Properties(); + Session session = Session.getDefaultInstance(props, null); + + Message msg = new MimeMessage(session); + for (String email : emails) { + try { + msg.addRecipient(Message.RecipientType.TO, new InternetAddress(email, email)); + } catch (MessagingException | UnsupportedEncodingException e) { + // Gracefully continue when a subscriber email is invalid. + logger.log(Level.WARNING, "Error sending email to recipient " + email + " : ", e); + } + } + msg.setFrom(new InternetAddress(SENDER_EMAIL, VTS_EMAIL_NAME)); + msg.setSubject(subject); + msg.setContent(body, "text/html; charset=utf-8"); + return msg; + } + + /** + * Sends an email. + * + * @param msg Message object to send. + * @returns true if the message sends successfully, false otherwise + */ + public static boolean send(Message msg) { + try { + Transport.send(msg); + } catch (MessagingException e) { + logger.log(Level.WARNING, "Error sending email : ", e); + return false; + } + return true; + } + + /** + * Sends a list of emails and logs any failures. + * + * @param messages List of Message objects to be sent. + */ + public static void sendAll(List<Message> messages) { + for (Message msg : messages) { + send(msg); + } + } + + /** + * Sends an email. + * + * @param recipients List of email address strings to which an email will be sent. + * @param subject The subject of the email. + * @param body The body of the email. + * @returns true if the message sends successfully, false otherwise + */ + public static boolean send(List<String> recipients, String subject, String body) { + try { + Message msg = composeEmail(recipients, subject, body); + return send(msg); + } catch (MessagingException | UnsupportedEncodingException e) { + logger.log(Level.WARNING, "Error composing email : ", e); + return false; + } + } +} diff --git a/src/main/java/com/android/vts/util/FilterUtil.java b/src/main/java/com/android/vts/util/FilterUtil.java new file mode 100644 index 0000000..5ca1bbb --- /dev/null +++ b/src/main/java/com/android/vts/util/FilterUtil.java @@ -0,0 +1,321 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * <p>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 + * + * <p>http://www.apache.org/licenses/LICENSE-2.0 + * + * <p>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. + */ +package com.android.vts.util; + +import com.android.vts.entity.DeviceInfoEntity; +import com.android.vts.entity.TestRunEntity; +import com.google.appengine.api.datastore.DatastoreService; +import com.google.appengine.api.datastore.DatastoreServiceFactory; +import com.google.appengine.api.datastore.Entity; +import com.google.appengine.api.datastore.Key; +import com.google.appengine.api.datastore.KeyFactory; +import com.google.appengine.api.datastore.Query; +import com.google.appengine.api.datastore.Query.CompositeFilterOperator; +import com.google.appengine.api.datastore.Query.Filter; +import com.google.appengine.api.datastore.Query.FilterOperator; +import com.google.appengine.api.datastore.Query.FilterPredicate; +import com.google.gson.Gson; +import java.util.ArrayList; +import java.util.Collections; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; +import javax.servlet.http.HttpServletRequest; + +/** FilterUtil, a helper class for parsing and matching search queries to data. */ +public class FilterUtil { + protected static final Logger logger = Logger.getLogger(FilterUtil.class.getName()); + /** Key class to represent a filter token. */ + public enum FilterKey { + DEVICE_BUILD_ID("deviceBuildId", DeviceInfoEntity.BUILD_ID, true), + BRANCH("branch", DeviceInfoEntity.BRANCH, true), + TARGET("device", DeviceInfoEntity.BUILD_FLAVOR, true), + VTS_BUILD_ID("testBuildId", TestRunEntity.TEST_BUILD_ID, false), + HOSTNAME("hostname", TestRunEntity.HOST_NAME, false), + PASSING("passing", TestRunEntity.PASS_COUNT, false), + NONPASSING("nonpassing", TestRunEntity.FAIL_COUNT, false); + + private static final Map<String, FilterKey> keyMap; + + static { + keyMap = new HashMap<>(); + for (FilterKey k : EnumSet.allOf(FilterKey.class)) { + keyMap.put(k.keyString, k); + } + } + + /** + * Test if a string is a valid device key. + * + * @param keyString The key string. + * @return True if they key string matches a key and the key is a device filter. + */ + public static boolean isDeviceKey(String keyString) { + return keyMap.containsKey(keyString) && keyMap.get(keyString).isDevice; + } + + /** + * Test if a string is a valid test key. + * + * @param keyString The key string. + * @return True if they key string matches a key and the key is a test filter. + */ + public static boolean isTestKey(String keyString) { + return keyMap.containsKey(keyString) && !keyMap.get(keyString).isDevice; + } + + /** + * Parses a key string into a key. + * + * @param keyString The key string. + * @return The key matching the key string. + */ + public static FilterKey parse(String keyString) { + return keyMap.get(keyString); + } + + private final String keyString; + private final String property; + private final boolean isDevice; + + /** + * Constructs a key with the specified key string. + * + * @param keyString The identifying key string. + * @param propertyName The name of the property to match. + */ + private FilterKey(String keyString, String propertyName, boolean isDevice) { + this.keyString = keyString; + this.property = propertyName; + this.isDevice = isDevice; + } + + public Filter getFilterForString(String matchString) { + return new FilterPredicate(this.property, FilterOperator.EQUAL, matchString); + } + + public Filter getFilterForNumber(long matchNumber) { + return new FilterPredicate(this.property, FilterOperator.EQUAL, matchNumber); + } + } + + /** + * Get a filter on devices from a user search query. + * + * @param parameterMap The key-value map of url parameters. + * @return A filter with the values from the user search parameters. + */ + public static Filter getUserDeviceFilter(Map<String, Object> parameterMap) { + Filter deviceFilter = null; + for (String key : parameterMap.keySet()) { + if (!FilterKey.isDeviceKey(key)) + continue; + String[] values = (String[]) parameterMap.get(key); + if (values.length == 0) + continue; + String value = values[0]; + FilterKey filterKey = FilterKey.parse(key); + Filter f = filterKey.getFilterForString(value); + if (deviceFilter == null) { + deviceFilter = f; + } else { + deviceFilter = CompositeFilterOperator.and(deviceFilter, f); + } + } + return deviceFilter; + } + + /** + * Get a filter on test runs from a user search query. + * + * @param parameterMap The key-value map of url parameters. + * @return A filter with the values from the user search parameters. + */ + public static Filter getUserTestFilter(Map<String, Object> parameterMap) { + Filter testFilter = null; + for (String key : parameterMap.keySet()) { + if (!FilterKey.isTestKey(key)) + continue; + String[] values = (String[]) parameterMap.get(key); + if (values.length == 0) + continue; + String stringValue = values[0]; + FilterKey filterKey = FilterKey.parse(key); + Filter f = null; + switch (filterKey) { + case NONPASSING: + case PASSING: + try { + Long value = Long.parseLong(stringValue); + f = filterKey.getFilterForNumber(value); + } catch (NumberFormatException e) { + // invalid number + } + break; + case HOSTNAME: + case VTS_BUILD_ID: + f = filterKey.getFilterForString(stringValue.toLowerCase()); + break; + default: + break; + } + if (testFilter == null) { + testFilter = f; + } else if (f != null) { + testFilter = CompositeFilterOperator.and(testFilter, f); + } + } + return testFilter; + } + + /** + * Get a filter on the test run type. + * + * @param showPresubmit True to display presubmit tests. + * @param showPostsubmit True to display postsubmit tests. + * @param unfiltered True if no filtering should be applied. + * @return A filter on the test type. + */ + public static Filter getTestTypeFilter( + boolean showPresubmit, boolean showPostsubmit, boolean unfiltered) { + if (unfiltered) { + return null; + } else if (showPresubmit && !showPostsubmit) { + return new FilterPredicate(TestRunEntity.TYPE, FilterOperator.EQUAL, + TestRunEntity.TestRunType.PRESUBMIT.getNumber()); + } else if (showPostsubmit && !showPresubmit) { + return new FilterPredicate(TestRunEntity.TYPE, FilterOperator.EQUAL, + TestRunEntity.TestRunType.POSTSUBMIT.getNumber()); + } else { + List<Integer> types = new ArrayList<>(); + types.add(TestRunEntity.TestRunType.PRESUBMIT.getNumber()); + types.add(TestRunEntity.TestRunType.POSTSUBMIT.getNumber()); + return new FilterPredicate(TestRunEntity.TYPE, FilterOperator.IN, types); + } + } + + /** + * Get the time range filter to apply to a query. + * + * @param testKey The key of the parent TestEntity object. + * @param kind The kind to use for the filters. + * @param startTime The start time in microseconds, or null if unbounded. + * @param endTime The end time in microseconds, or null if unbounded. + * @param testRunFilter The existing filter on test runs to apply, or null. + * @return A filter to apply on test runs. + */ + public static Filter getTimeFilter( + Key testKey, String kind, Long startTime, Long endTime, Filter testRunFilter) { + if (startTime == null && endTime == null) { + endTime = TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis()); + } + + Filter startFilter = null; + Filter endFilter = null; + Filter filter = null; + if (startTime != null) { + Key startKey = KeyFactory.createKey(testKey, kind, startTime); + startFilter = new FilterPredicate( + Entity.KEY_RESERVED_PROPERTY, FilterOperator.GREATER_THAN_OR_EQUAL, startKey); + filter = startFilter; + } + if (endTime != null) { + Key endKey = KeyFactory.createKey(testKey, kind, endTime); + endFilter = new FilterPredicate( + Entity.KEY_RESERVED_PROPERTY, FilterOperator.LESS_THAN_OR_EQUAL, endKey); + filter = endFilter; + } + if (startFilter != null && endFilter != null) { + filter = CompositeFilterOperator.and(startFilter, endFilter); + } + if (testRunFilter != null) { + filter = CompositeFilterOperator.and(filter, testRunFilter); + } + return filter; + } + + public static Filter getTimeFilter(Key testKey, String kind, Long startTime, Long endTime) { + return getTimeFilter(testKey, kind, startTime, endTime, null); + } + + /** + * Get the list of keys matching the provided test filter and device filter. + * + * @param ancestorKey The ancestor key to use in the query. + * @param kind The entity kind to use in the test query. + * @param testFilter The filter to apply to the test runs. + * @param deviceFilter The filter to apply to associated devices. + * @param dir The sort direction of the returned list. + * @param maxSize The maximum number of entities to return. + * @return a list of keys matching the provided test and device filters. + */ + public static List<Key> getMatchingKeys(Key ancestorKey, String kind, Filter testFilter, + Filter deviceFilter, Query.SortDirection dir, int maxSize) { + DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); + Set<Key> matchingTestKeys = new HashSet<>(); + Query testQuery = + new Query(kind).setAncestor(ancestorKey).setFilter(testFilter).setKeysOnly(); + for (Entity testRunKey : datastore.prepare(testQuery).asIterable()) { + matchingTestKeys.add(testRunKey.getKey()); + } + + Set<Key> allMatchingKeys; + if (deviceFilter == null) { + allMatchingKeys = matchingTestKeys; + } else { + allMatchingKeys = new HashSet<>(); + Query deviceQuery = new Query(DeviceInfoEntity.KIND) + .setAncestor(ancestorKey) + .setFilter(deviceFilter) + .setKeysOnly(); + for (Entity device : datastore.prepare(deviceQuery).asIterable()) { + if (matchingTestKeys.contains(device.getKey().getParent())) { + allMatchingKeys.add(device.getKey().getParent()); + } + } + } + List<Key> gets = new ArrayList<>(allMatchingKeys); + if (dir == Query.SortDirection.DESCENDING) { + Collections.sort(gets, Collections.reverseOrder()); + } else { + Collections.sort(gets); + } + gets = gets.subList(0, Math.min(gets.size(), maxSize)); + return gets; + } + + /** + * Set the request with the provided key/value attribute map. + * @param request The request whose attributes to set. + * @param parameterMap The map from key to (Object) String[] value whose entries to parse. + */ + public static void setAttributes(HttpServletRequest request, Map<String, Object> parameterMap) { + for (String key : parameterMap.keySet()) { + if (!FilterKey.isDeviceKey(key) && !FilterKey.isTestKey(key)) + continue; + FilterKey filterKey = FilterKey.parse(key); + String[] values = (String[]) parameterMap.get(key); + if (values.length == 0) + continue; + String stringValue = values[0]; + request.setAttribute(filterKey.keyString, new Gson().toJson(stringValue)); + } + } +} diff --git a/src/main/java/com/android/vts/util/Graph.java b/src/main/java/com/android/vts/util/Graph.java new file mode 100644 index 0000000..2fe98bb --- /dev/null +++ b/src/main/java/com/android/vts/util/Graph.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.util; + +import com.android.vts.entity.ProfilingPointRunEntity; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; + +/** Helper object for describing graph data. */ +public abstract class Graph { + public static final String VALUE_KEY = "values"; + public static final String X_LABEL_KEY = "x_label"; + public static final String Y_LABEL_KEY = "y_label"; + public static final String IDS_KEY = "ids"; + public static final String NAME_KEY = "name"; + public static final String TYPE_KEY = "type"; + + public static enum GraphType { LINE_GRAPH, HISTOGRAM } + + /** + * Get the graph type. + * + * @return The graph type. + */ + public abstract GraphType getType(); + + /** + * Get the x axis label. + * + * @return The x axis label. + */ + public abstract String getXLabel(); + + /** + * Get the y axis label. + * + * @return The y axis label. + */ + public abstract String getYLabel(); + + /** + * Get the name of the graph. + * + * @return The name of the graph. + */ + public abstract String getName(); + + /** + * Get the number of data points stored in the graph. + * + * @return The number of data points stored in the graph. + */ + public abstract int size(); + + /** + * Add data to the graph. + * + * @param id The name of the graph. + * @param profilingPoint The ProfilingPointEntity containing data to add. + */ + public abstract void addData(String id, ProfilingPointRunEntity profilingPoint); + + /** + * Serializes the graph to json format. + * + * @return A JsonElement object representing the graph object. + */ + public JsonObject toJson() { + JsonObject json = new JsonObject(); + json.add(X_LABEL_KEY, new JsonPrimitive(getXLabel())); + json.add(Y_LABEL_KEY, new JsonPrimitive(getYLabel())); + json.add(NAME_KEY, new JsonPrimitive(getName())); + json.add(TYPE_KEY, new JsonPrimitive(getType().toString())); + return json; + } +} diff --git a/src/main/java/com/android/vts/util/GraphSerializer.java b/src/main/java/com/android/vts/util/GraphSerializer.java new file mode 100644 index 0000000..722b511 --- /dev/null +++ b/src/main/java/com/android/vts/util/GraphSerializer.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.util; + +import com.google.gson.JsonElement; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; +import java.lang.reflect.Type; + +/** Serializer class for Graph objects. */ +public class GraphSerializer implements JsonSerializer<Graph> { + @Override + public JsonElement serialize(Graph src, Type typeOfSrc, JsonSerializationContext context) { + return src.toJson(); + } +} diff --git a/src/main/java/com/android/vts/util/Histogram.java b/src/main/java/com/android/vts/util/Histogram.java new file mode 100644 index 0000000..450714b --- /dev/null +++ b/src/main/java/com/android/vts/util/Histogram.java @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.util; + +import com.android.vts.entity.ProfilingPointRunEntity; +import com.google.common.primitives.Doubles; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import java.util.ArrayList; +import java.util.List; +import org.apache.commons.math3.stat.descriptive.rank.Percentile; + +/** Helper object for describing graph data. */ +public class Histogram extends Graph { + public static final String PERCENTILES_KEY = "percentiles"; + public static final String PERCENTILE_VALUES_KEY = "percentile_values"; + public static final String MIN_KEY = "min"; + public static final String MAX_KEY = "max"; + + private List<Double> values; + private List<String> ids; + private String xLabel; + private String yLabel; + private String name; + private GraphType type = GraphType.HISTOGRAM; + private Double min = null; + private Double max = null; + + public Histogram(String name) { + this.name = name; + this.values = new ArrayList<>(); + this.ids = new ArrayList<>(); + } + + /** + * Get the x axis label. + * + * @return The x axis label. + */ + @Override + public String getXLabel() { + return xLabel; + } + + /** + * Get the graph type. + * + * @return The graph type. + */ + @Override + public GraphType getType() { + return type; + } + + /** + * Get the name of the graph. + * + * @return The name of the graph. + */ + @Override + public String getName() { + return name; + } + + /** + * Get the y axis label. + * + * @return The y axis label. + */ + @Override + public String getYLabel() { + return yLabel; + } + + /** + * Get the number of data points stored in the graph. + * + * @return The number of data points stored in the graph. + */ + @Override + public int size() { + return values.size(); + } + + /** + * Get the minimum value. + * + * @return The minimum value. + */ + public Double getMin() { + return min; + } + + /** + * Get the maximum value. + * + * @return The maximum value. + */ + public Double getMax() { + return max; + } + + /** + * Add data to the graph. + * + * @param id The name of the graph. + * @param profilingPoint The ProfilingPointRunEntity containing data to add. + */ + @Override + public void addData(String id, ProfilingPointRunEntity profilingPoint) { + if (profilingPoint.values.size() == 0) + return; + xLabel = profilingPoint.xLabel; + yLabel = profilingPoint.yLabel; + for (long v : profilingPoint.values) { + double value = v; + values.add(value); + ids.add(id); + if (max == null || value > max) + max = value; + if (min == null || value < min) + min = value; + } + } + + /** + * Serializes the graph to json format. + * + * @return A JsonElement object representing the graph object. + */ + @Override + public JsonObject toJson() { + int[] percentiles = {1, 2, 5, 10, 25, 50, 75, 90, 95, 98, 99}; + double[] percentileValues = new double[percentiles.length]; + double[] valueList = Doubles.toArray(values); + for (int i = 0; i < percentiles.length; i++) { + percentileValues[i] = + Math.round(new Percentile().evaluate(valueList, percentiles[i]) * 1000d) + / 1000d; + } + JsonObject json = super.toJson(); + json.add(VALUE_KEY, new Gson().toJsonTree(values).getAsJsonArray()); + json.add(PERCENTILES_KEY, new Gson().toJsonTree(percentiles).getAsJsonArray()); + json.add(PERCENTILE_VALUES_KEY, new Gson().toJsonTree(percentileValues).getAsJsonArray()); + json.add(IDS_KEY, new Gson().toJsonTree(ids).getAsJsonArray()); + json.add(MIN_KEY, new JsonPrimitive(min)); + json.add(MAX_KEY, new JsonPrimitive(max)); + return json; + } +} diff --git a/src/main/java/com/android/vts/util/LineGraph.java b/src/main/java/com/android/vts/util/LineGraph.java new file mode 100644 index 0000000..22c64da --- /dev/null +++ b/src/main/java/com/android/vts/util/LineGraph.java @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.util; + +import com.android.vts.entity.ProfilingPointRunEntity; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** Helper object for describing graph data. */ +public class LineGraph extends Graph { + public static final String TICKS_KEY = "ticks"; + + private List<ProfilingPointRunEntity> profilingRuns; + private List<String> ids; + private String xLabel; + private String yLabel; + private String name; + private GraphType type = GraphType.LINE_GRAPH; + + public LineGraph(String name) { + this.name = name; + profilingRuns = new ArrayList<>(); + ids = new ArrayList<>(); + } + + /** + * Get the x axis label. + * + * @return The x axis label. + */ + @Override + public String getXLabel() { + return xLabel; + } + + /** + * Get the graph type. + * + * @return The graph type. + */ + @Override + public GraphType getType() { + return type; + } + + /** + * Get the name of the graph. + * + * @return The name of the graph. + */ + @Override + public String getName() { + return name; + } + + /** + * Get the y axis label. + * + * @return The y axis label. + */ + @Override + public String getYLabel() { + return yLabel; + } + + /** + * Get the number of data points stored in the graph. + * + * @return The number of data points stored in the graph. + */ + @Override + public int size() { + return profilingRuns.size(); + } + + /** + * Add data to the graph. + * + * @param id The name of the graph. + * @param profilingPoint The ProfilingPointRunEntity containing data to add. + */ + @Override + public void addData(String id, ProfilingPointRunEntity profilingPoint) { + if (profilingPoint.values.size() == 0 + || profilingPoint.values.size() != profilingPoint.labels.size()) + return; + ids.add(id); + profilingRuns.add(profilingPoint); + xLabel = profilingPoint.xLabel; + yLabel = profilingPoint.yLabel; + } + + /** + * Serializes the graph to json format. + * + * @return A JsonElement object representing the graph object. + */ + @Override + public JsonObject toJson() { + JsonObject json = super.toJson(); + // Use the most recent profiling vector to generate the labels + ProfilingPointRunEntity profilingRun = profilingRuns.get(profilingRuns.size() - 1); + + List<String> axisTicks = new ArrayList<>(); + Map<String, Integer> tickIndexMap = new HashMap<>(); + for (int i = 0; i < profilingRun.labels.size(); i++) { + String label = profilingRun.labels.get(i); + axisTicks.add(label); + tickIndexMap.put(label, i); + } + + long[][] lineGraphValues = new long[axisTicks.size()][profilingRuns.size()]; + for (int reportIndex = 0; reportIndex < profilingRuns.size(); reportIndex++) { + ProfilingPointRunEntity pt = profilingRuns.get(reportIndex); + for (int i = 0; i < pt.labels.size(); i++) { + String label = pt.labels.get(i); + + // Skip value if its label is not present + if (!tickIndexMap.containsKey(label)) + continue; + int labelIndex = tickIndexMap.get(label); + + lineGraphValues[labelIndex][reportIndex] = pt.values.get(i); + } + } + json.add(VALUE_KEY, new Gson().toJsonTree(lineGraphValues).getAsJsonArray()); + json.add(IDS_KEY, new Gson().toJsonTree(ids).getAsJsonArray()); + json.add(TICKS_KEY, new Gson().toJsonTree(axisTicks)); + return json; + } +} diff --git a/src/main/java/com/android/vts/util/PerformanceSummary.java b/src/main/java/com/android/vts/util/PerformanceSummary.java new file mode 100644 index 0000000..05ed0b7 --- /dev/null +++ b/src/main/java/com/android/vts/util/PerformanceSummary.java @@ -0,0 +1,143 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * <p>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 + * + * <p>http://www.apache.org/licenses/LICENSE-2.0 + * + * <p>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. + */ +package com.android.vts.util; + +import com.android.vts.entity.ProfilingPointRunEntity; +import com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode; +import com.google.appengine.api.datastore.Entity; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** PerformanceSummary, an object summarizing performance across profiling points for a test run. */ +public class PerformanceSummary { + protected static Logger logger = Logger.getLogger(PerformanceSummary.class.getName()); + private Map<String, ProfilingPointSummary> summaryMap; + private Set<String> optionSplitKeys; + + /** Creates a performance summary object. */ + public PerformanceSummary() { + this.summaryMap = new HashMap<>(); + this.optionSplitKeys = new HashSet<>(); + } + + /** + * Creates a performance summary object with the specified device name filter. If the specified + * name is null, then use no filter. + * + * @param optionSplitKeys A set of option keys to split on (i.e. profiling data with different + * values corresponding to the option key will be analyzed as different profiling points). + */ + public PerformanceSummary(Set<String> optionSplitKeys) { + this(); + this.optionSplitKeys = optionSplitKeys; + } + + /** + * Add the profiling data from a ProfilingPointRunEntity to the performance summary. + * + * @param profilingRun The Entity object whose data to add. + */ + public void addData(Entity profilingRun) { + ProfilingPointRunEntity pt = ProfilingPointRunEntity.fromEntity(profilingRun); + if (pt == null) + return; + if (pt.regressionMode == VtsProfilingRegressionMode.VTS_REGRESSION_MODE_DISABLED) { + return; + } + + String name = pt.name; + String optionSuffix = PerformanceUtil.getOptionAlias(pt, optionSplitKeys); + + if (pt.labels != null) { + if (pt.labels.size() != pt.values.size()) { + logger.log(Level.WARNING, "Labels and values are different sizes."); + return; + } + if (!optionSuffix.equals("")) { + name += " (" + optionSuffix + ")"; + } + if (!summaryMap.containsKey(name)) { + summaryMap.put(name, new ProfilingPointSummary()); + } + summaryMap.get(name).update(pt); + } else { + // Use the option suffix as the table name. + // Group all profiling points together into one table + if (!summaryMap.containsKey(optionSuffix)) { + summaryMap.put(optionSuffix, new ProfilingPointSummary()); + } + summaryMap.get(optionSuffix).updateLabel(pt, pt.name); + } + } + + /** + * Adds a ProfilingPointSummary object into the summary map only if the key doesn't exist. + * + * @param key The name of the profiling point. + * @param summary The ProfilingPointSummary object to add into the summary map. + * @return True if the data was inserted into the performance summary, false otherwise. + */ + public boolean insertProfilingPointSummary(String key, ProfilingPointSummary summary) { + if (!summaryMap.containsKey(key)) { + summaryMap.put(key, summary); + return true; + } + return false; + } + + /** + * Gets the number of profiling points. + * + * @return The number of profiling points in the performance summary. + */ + public int size() { + return summaryMap.size(); + } + + /** + * Gets the names of the profiling points. + * + * @return A string array of profiling point names. + */ + public String[] getProfilingPointNames() { + String[] profilingNames = summaryMap.keySet().toArray(new String[summaryMap.size()]); + Arrays.sort(profilingNames); + return profilingNames; + } + + /** + * Determines if a profiling point is described by the performance summary. + * + * @param profilingPointName The name of the profiling point. + * @return True if the profiling point is contained in the performance summary, else false. + */ + public boolean hasProfilingPoint(String profilingPointName) { + return summaryMap.containsKey(profilingPointName); + } + + /** + * Gets the profiling point summary by name. + * + * @param profilingPointName The name of the profiling point to fetch. + * @return The ProfilingPointSummary object describing the specified profiling point. + */ + public ProfilingPointSummary getProfilingPointSummary(String profilingPointName) { + return summaryMap.get(profilingPointName); + } +} diff --git a/src/main/java/com/android/vts/util/PerformanceUtil.java b/src/main/java/com/android/vts/util/PerformanceUtil.java new file mode 100644 index 0000000..02c2afa --- /dev/null +++ b/src/main/java/com/android/vts/util/PerformanceUtil.java @@ -0,0 +1,246 @@ +/** + * Copyright 2016 Google Inc. All Rights Reserved. + * + * <p>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 + * + * <p>http://www.apache.org/licenses/LICENSE-2.0 + * + * <p>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. + */ +package com.android.vts.util; + +import com.android.vts.entity.DeviceInfoEntity; +import com.android.vts.entity.ProfilingPointRunEntity; +import com.android.vts.entity.TestEntity; +import com.android.vts.entity.TestRunEntity; +import com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode; +import com.google.appengine.api.datastore.DatastoreService; +import com.google.appengine.api.datastore.DatastoreServiceFactory; +import com.google.appengine.api.datastore.Entity; +import com.google.appengine.api.datastore.Key; +import com.google.appengine.api.datastore.KeyFactory; +import com.google.appengine.api.datastore.Query; +import com.google.appengine.api.datastore.Query.Filter; +import com.google.appengine.api.datastore.Query.FilterOperator; +import com.google.appengine.api.datastore.Query.FilterPredicate; +import java.io.IOException; +import java.math.RoundingMode; +import java.text.DecimalFormat; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; +import org.apache.commons.lang.StringUtils; + +/** PerformanceUtil, a helper class for analyzing profiling and performance data. */ +public class PerformanceUtil { + protected static Logger logger = Logger.getLogger(PerformanceUtil.class.getName()); + + private static final DecimalFormat FORMATTER; + private static final String NAME_DELIMITER = ", "; + private static final String OPTION_DELIMITER = "="; + + /** + * Initialize the decimal formatter. + */ + static { + FORMATTER = new DecimalFormat("#.##"); + FORMATTER.setRoundingMode(RoundingMode.HALF_UP); + } + + public static class TimeInterval { + public final long start; + public final long end; + public final String label; + + public TimeInterval(long start, long end, String label) { + this.start = start; + this.end = end; + this.label = label; + } + + public TimeInterval(long start, long end) { + this(start, end, "<span class='date-label'>" + + Long.toString(TimeUnit.MICROSECONDS.toMillis(end)) + "</span>"); + } + } + + /** + * Creates the HTML for a table cell representing the percent change between two numbers. + * + * <p>Computes the percent change (after - before)/before * 100 and inserts it into a table cell + * with the specified style. The color of the cell is white if 'after' is less than before. + * Otherwise, the cell is colored red with opacity according to the percent change (100%+ delta + * means 100% opacity). If the before value is 0 and the after value is positive, then the color + * of the cell is 100% red to indicate an increase of undefined magnitude. + * + * @param baseline The baseline value observed. + * @param test The value to compare against the baseline. + * @param classNames A string containing HTML classes to apply to the table cell. + * @param style A string containing additional CSS styles. + * @returns An HTML string for a colored table cell containing the percent change. + */ + public static String getPercentChangeHTML(double baseline, double test, String classNames, + String style, VtsProfilingRegressionMode mode) { + String pctChangeString = "0 %"; + double alpha = 0; + double delta = test - baseline; + if (baseline != 0) { + double pctChange = delta / baseline; + alpha = pctChange * 2; + pctChangeString = FORMATTER.format(pctChange * 100) + " %"; + } else if (delta != 0) { + // If the percent change is undefined, the cell will be solid red or white + alpha = (int) Math.signum(delta); // get the sign of the delta (+1, 0, -1) + pctChangeString = ""; + } + if (mode == VtsProfilingRegressionMode.VTS_REGRESSION_MODE_DECREASING) { + alpha = -alpha; + } + String color = "background-color: rgba(255, 0, 0, " + alpha + "); "; + String html = "<td class='" + classNames + "' style='" + color + style + "'>"; + html += pctChangeString + "</td>"; + return html; + } + + /** + * Compares a test StatSummary to a baseline StatSummary using best-case performance. + * + * @param baseline The StatSummary object containing initial values to compare against + * @param test The StatSummary object containing test values to be compared against the baseline + * @param innerClasses Class names to apply to cells on the inside of the grid + * @param outerClasses Class names to apply to cells on the outside of the grid + * @param innerStyles CSS styles to apply to cells on the inside of the grid + * @param outerStyles CSS styles to apply to cells on the outside of the grid + * @return HTML string representing the performance of the test versus the baseline + */ + public static String getBestCasePerformanceComparisonHTML(StatSummary baseline, + StatSummary test, String innerClasses, String outerClasses, String innerStyles, + String outerStyles) { + if (test == null || baseline == null) { + return "<td></td><td></td><td></td><td></td>"; + } + String row = ""; + // Intensity of red color is a function of the relative (percent) change + // in the new value compared to the previous day's. Intensity is a linear function + // of percentage change, reaching a ceiling at 100% change (e.g. a doubling). + row += getPercentChangeHTML(baseline.getBestCase(), test.getBestCase(), innerClasses, + innerStyles, test.getRegressionMode()); + row += "<td class='" + innerClasses + "' style='" + innerStyles + "'>"; + row += FORMATTER.format(baseline.getBestCase()); + row += "<td class='" + innerClasses + "' style='" + innerStyles + "'>"; + row += FORMATTER.format(baseline.getMean()); + row += "<td class='" + outerClasses + "' style='" + outerStyles + "'>"; + row += FORMATTER.format(baseline.getStd()) + "</td>"; + return row; + } + + /** + * Compares a test StatSummary to a baseline StatSummary using average-case performance. + * + * @param baseline The StatSummary object containing initial values to compare against + * @param test The StatSummary object containing test values to be compared against the baseline + * @param innerClasses Class names to apply to cells on the inside of the grid + * @param outerClasses Class names to apply to cells on the outside of the grid + * @param innerStyles CSS styles to apply to cells on the inside of the grid + * @param outerStyles CSS styles to apply to cells on the outside of the grid + * @return HTML string representing the performance of the test versus the baseline + */ + public static String getAvgCasePerformanceComparisonHTML(StatSummary baseline, StatSummary test, + String innerClasses, String outerClasses, String innerStyles, String outerStyles) { + if (test == null || baseline == null) { + return "<td></td><td></td><td></td><td></td>"; + } + String row = ""; + // Intensity of red color is a function of the relative (percent) change + // in the new value compared to the previous day's. Intensity is a linear function + // of percentage change, reaching a ceiling at 100% change (e.g. a doubling). + row += getPercentChangeHTML(baseline.getMean(), test.getMean(), innerClasses, innerStyles, + test.getRegressionMode()); + row += "<td class='" + innerClasses + "' style='" + innerStyles + "'>"; + row += FORMATTER.format(baseline.getBestCase()); + row += "<td class='" + innerClasses + "' style='" + innerStyles + "'>"; + row += FORMATTER.format(baseline.getMean()); + row += "<td class='" + outerClasses + "' style='" + outerStyles + "'>"; + row += FORMATTER.format(baseline.getStd()) + "</td>"; + return row; + } + + /** + * Updates a PerformanceSummary object with data in the specified window. + * + * @param testName The name of the table whose profiling vectors to retrieve. + * @param startTime The (inclusive) start time in microseconds to scan from. + * @param endTime The (inclusive) end time in microseconds at which to stop scanning. + * @param selectedDevice The name of the device whose data to query for, or null for unfiltered. + * @param perfSummary The PerformanceSummary object to update with data. + * @throws IOException + */ + public static void updatePerformanceSummary(String testName, long startTime, long endTime, + String selectedDevice, PerformanceSummary perfSummary) throws IOException { + DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); + Key testKey = KeyFactory.createKey(TestEntity.KIND, testName); + Filter testTypeFilter = FilterUtil.getTestTypeFilter(false, true, false); + Filter runFilter = FilterUtil.getTimeFilter( + testKey, TestRunEntity.KIND, startTime, endTime, testTypeFilter); + + Filter deviceFilter = null; + if (selectedDevice != null) { + deviceFilter = new FilterPredicate( + DeviceInfoEntity.PRODUCT, FilterOperator.EQUAL, selectedDevice); + } + Query testRunQuery = new Query(TestRunEntity.KIND) + .setAncestor(testKey) + .setFilter(runFilter) + .setKeysOnly(); + for (Entity testRun : datastore.prepare(testRunQuery).asIterable()) { + if (deviceFilter != null) { + Query deviceQuery = new Query(DeviceInfoEntity.KIND) + .setAncestor(testRun.getKey()) + .setFilter(deviceFilter) + .setKeysOnly(); + if (!DatastoreHelper.hasEntities(deviceQuery)) + continue; + } + Query q = new Query(ProfilingPointRunEntity.KIND).setAncestor(testRun.getKey()); + + for (Entity profilingRun : datastore.prepare(q).asIterable()) { + perfSummary.addData(profilingRun); + } + } + } + + /** + * Generates a string of the values in optionsList which have matches in the profiling entity. + * + * @param profilingRun The entity for a profiling point run. + * @param optionKeys A list of keys to match against the optionsList key value pairs. + * @return The values in optionsList whose key match a key in optionKeys. + */ + public static String getOptionAlias( + ProfilingPointRunEntity profilingRun, Set<String> optionKeys) { + String name = ""; + List<String> nameSuffixes = new ArrayList<>(); + if (profilingRun.options != null) { + for (String optionString : profilingRun.options) { + String[] optionParts = optionString.split(OPTION_DELIMITER); + if (optionParts.length != 2) { + continue; + } + if (optionKeys.contains(optionParts[0].trim().toLowerCase())) { + nameSuffixes.add(optionParts[1].trim().toLowerCase()); + } + } + if (nameSuffixes.size() > 0) { + StringUtils.join(nameSuffixes, NAME_DELIMITER); + name += StringUtils.join(nameSuffixes, NAME_DELIMITER); + } + } + return name; + } +} diff --git a/src/main/java/com/android/vts/util/ProfilingPointSummary.java b/src/main/java/com/android/vts/util/ProfilingPointSummary.java new file mode 100644 index 0000000..6e3e8c9 --- /dev/null +++ b/src/main/java/com/android/vts/util/ProfilingPointSummary.java @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.util; + +import com.android.vts.entity.ProfilingPointRunEntity; +import com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** Represents statistical summaries of each profiling point. */ +public class ProfilingPointSummary implements Iterable<StatSummary> { + private List<StatSummary> statSummaries; + private Map<String, Integer> labelIndices; + private List<String> labels; + private VtsProfilingRegressionMode regressionMode; + public String xLabel; + public String yLabel; + + /** Initializes the summary with empty arrays. */ + public ProfilingPointSummary() { + statSummaries = new ArrayList<>(); + labelIndices = new HashMap<>(); + labels = new ArrayList<>(); + } + + /** + * Determines if a data label is present in the profiling point. + * + * @param label The name of the label. + * @return true if the label is present, false otherwise. + */ + public boolean hasLabel(String label) { + return labelIndices.containsKey(label); + } + + /** + * Gets the statistical summary for a specified data label. + * + * @param label The name of the label. + * @return The StatSummary object if it exists, or null otherwise. + */ + public StatSummary getStatSummary(String label) { + if (!hasLabel(label)) + return null; + return statSummaries.get(labelIndices.get(label)); + } + + /** + * Gets the last-seen regression mode. + * + * @return The VtsProfilingRegressionMode value. + */ + public VtsProfilingRegressionMode getRegressionMode() { + return regressionMode; + } + + /** + * Updates the profiling summary with the data from a new profiling report. + * + * @param profilingRun The profiling point run entity object containing profiling data. + */ + public void update(ProfilingPointRunEntity profilingRun) { + for (int i = 0; i < profilingRun.labels.size(); i++) { + String label = profilingRun.labels.get(i); + if (!labelIndices.containsKey(label)) { + StatSummary summary = new StatSummary(label, profilingRun.regressionMode); + labelIndices.put(label, statSummaries.size()); + statSummaries.add(summary); + } + StatSummary summary = getStatSummary(label); + summary.updateStats(profilingRun.values.get(i)); + } + this.regressionMode = profilingRun.regressionMode; + this.labels = profilingRun.labels; + this.xLabel = profilingRun.xLabel; + this.yLabel = profilingRun.yLabel; + } + + /** + * Updates the profiling summary at a label with the data from a new profiling report. + * + * <p>Updates the summary specified by the label with all values provided in the report. If + * labels + * are provided in the report, they will be ignored -- all values are updated only to the + * provided + * label. + * + * @param profilingEntity The ProfilingPointRunEntity object containing profiling data. + * @param label The ByteString label for which all values in the report will be updated. + */ + public void updateLabel(ProfilingPointRunEntity profilingEntity, String label) { + if (!labelIndices.containsKey(label)) { + StatSummary summary = new StatSummary(label, profilingEntity.regressionMode); + labelIndices.put(label, labels.size()); + labels.add(label); + statSummaries.add(summary); + } + StatSummary summary = getStatSummary(label); + for (long value : profilingEntity.values) { + summary.updateStats(value); + } + this.regressionMode = profilingEntity.regressionMode; + this.xLabel = profilingEntity.xLabel; + this.yLabel = profilingEntity.yLabel; + } + + /** + * Gets an iterator that returns stat summaries in the ordered the labels were specified in the + * ProfilingReportMessage objects. + */ + @Override + public Iterator<StatSummary> iterator() { + Iterator<StatSummary> it = new Iterator<StatSummary>() { + private int currentIndex = 0; + + @Override + public boolean hasNext() { + return labels != null && currentIndex < labels.size(); + } + + @Override + public StatSummary next() { + String label = labels.get(currentIndex++); + return statSummaries.get(labelIndices.get(label)); + } + }; + return it; + } +} diff --git a/src/main/java/com/android/vts/util/StatSummary.java b/src/main/java/com/android/vts/util/StatSummary.java new file mode 100644 index 0000000..04db7c4 --- /dev/null +++ b/src/main/java/com/android/vts/util/StatSummary.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.util; + +import com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode; + +/** Helper object for storing statistics. */ +public class StatSummary { + private String label; + private double min; + private double max; + private double mean; + private double var; + private int n; + private VtsProfilingRegressionMode regression_mode; + + /** + * Initializes the statistical summary. + * + * <p>Sets the label as provided. Initializes the mean, variance, and n (number of values seen) + * to + * 0. + * + * @param label The (String) label to assign to the summary. + * @param mode The VtsProfilingRegressionMode to use when analyzing performance. + */ + public StatSummary(String label, VtsProfilingRegressionMode mode) { + this.label = label; + this.min = Double.MAX_VALUE; + this.max = Double.MIN_VALUE; + this.mean = 0; + this.var = 0; + this.n = 0; + this.regression_mode = mode; + } + + /** + * Update the mean and variance using Welford's single-pass method. + * + * @param value The observed value in the stream. + */ + public void updateStats(double value) { + n += 1; + double oldMean = mean; + mean = oldMean + (value - oldMean) / n; + var = var + (value - mean) * (value - oldMean); + if (value < min) + min = value; + if (value > max) + max = value; + } + + /** + * Gets the best case of the stream. + * + * @return The min or max. + */ + public double getBestCase() { + switch (regression_mode) { + case VTS_REGRESSION_MODE_DECREASING: + return getMax(); + default: + return getMin(); + } + } + + /** + * Gets the calculated min of the stream. + * + * @return The min. + */ + public double getMin() { + return min; + } + + /** + * Gets the calculated max of the stream. + * + * @return The max. + */ + public double getMax() { + return max; + } + + /** + * Gets the calculated mean of the stream. + * + * @return The mean. + */ + public double getMean() { + return mean; + } + + /** + * Gets the calculated standard deviation of the stream. + * + * @return The standard deviation. + */ + public double getStd() { + return Math.sqrt(var / (n - 1)); + } + + /** + * Gets the number of elements that have passed through the stream. + * + * @return Number of elements. + */ + public int getCount() { + return n; + } + + /** + * Gets the label for the summarized statistics. + * + * @return The (string) label. + */ + public String getLabel() { + return label; + } + + /** + * Gets the regression mode. + * + * @return The VtsProfilingRegressionMode value. + */ + public VtsProfilingRegressionMode getRegressionMode() { + return regression_mode; + } +} diff --git a/src/main/java/com/android/vts/util/TestResults.java b/src/main/java/com/android/vts/util/TestResults.java new file mode 100644 index 0000000..0591bb6 --- /dev/null +++ b/src/main/java/com/android/vts/util/TestResults.java @@ -0,0 +1,387 @@ +/* + * Copyright (c) 2017 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.util; + +import com.android.vts.entity.DeviceInfoEntity; +import com.android.vts.entity.TestCaseRunEntity; +import com.android.vts.entity.TestCaseRunEntity.TestCase; +import com.android.vts.entity.TestRunEntity; +import com.android.vts.proto.VtsReportMessage.TestCaseResult; +import com.android.vts.util.UrlUtil.LinkDisplay; +import com.google.appengine.api.datastore.Entity; +import com.google.appengine.api.datastore.Key; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; +import org.apache.commons.lang.StringUtils; + +/** Helper object for describing test results data. */ +public class TestResults { + private final Logger logger = Logger.getLogger(getClass().getName()); + + private List<TestRunEntity> testRuns; // list of all test runs + private Map<Key, List<TestCaseRunEntity>> + testCaseRunMap; // map from test run key to the test run information + private Map<Key, List<DeviceInfoEntity>> deviceInfoMap; // map from test run key to device info + private Map<String, Integer> testCaseNameMap; // map from test case name to its order + private Set<String> profilingPointNameSet; // set of profiling point names + + public String testName; + public String[] headerRow; // row to display above the test results table + public String[][] timeGrid; // grid of data storing timestamps to render as dates + public String[][] durationGrid; // grid of data storing timestamps to render as time intervals + public String[][] summaryGrid; // grid of data displaying a summary of the test run + public String[][] resultsGrid; // grid of data displaying test case results + public String[] profilingPointNames; // list of profiling point names in the test run + public Map<String, List<String[]>> logInfoMap; // map from test run index to url/display pairs + public int[] totResultCounts; // array of test result counts for the tip-of-tree runs + public String totBuildId = ""; // build ID of tip-of-tree run + public long startTime = Long.MAX_VALUE; // oldest timestamp displayed in the results table + public long endTime = Long.MIN_VALUE; // newest timestamp displayed in the results table + + // Row labels for the test time-formatted information. + private static final String[] TIME_INFO_NAMES = {"Test Start", "Test End"}; + + // Row labels for the test duration information. + private static final String[] DURATION_INFO_NAMES = {"<b>Test Duration</b>"}; + + // Row labels for the test summary grid. + private static final String[] SUMMARY_NAMES = {"Total", "Passing #", "Non-Passing #", + "Passing %", "Covered Lines", "Coverage %", "Logs"}; + + // Row labels for the device summary information in the table header. + private static final String[] HEADER_NAMES = {"<b>Stats Type \\ Device Build ID</b>", "Branch", + "Build Target", "Device", "ABI Target", "VTS Build ID", "Hostname"}; + + /** + * Create a test results object. + * + * @param testName The name of the test. + */ + public TestResults(String testName) { + this.testName = testName; + this.testRuns = new ArrayList<>(); + this.deviceInfoMap = new HashMap<>(); + this.testCaseRunMap = new HashMap<>(); + this.testCaseNameMap = new HashMap<>(); + this.logInfoMap = new HashMap<>(); + this.profilingPointNameSet = new HashSet<>(); + } + + /** + * Add a test run to the test results. + * + * @param testRun The Entity containing the test run information. + * @param testCaseRuns The collection of test case executions within the test run. + * @param deviceInfos The collection of device information entities for the test run. + * @param profilingPoints The collection of profiling point names for the test run. + */ + public void addTestRun(Entity testRun, Iterable<Entity> testCaseRuns, + Iterable<Entity> deviceInfos, Iterable<Entity> profilingPoints) { + // Process the devices in the test run + List<DeviceInfoEntity> devices = new ArrayList<>(); + for (Entity e : deviceInfos) { + DeviceInfoEntity deviceInfoEntity = DeviceInfoEntity.fromEntity(e); + if (deviceInfoEntity == null) + continue; + devices.add(deviceInfoEntity); + } + + // Filter out test runs lacking device information + if (devices.size() == 0) { + logger.log(Level.WARNING, "No device info found for run: " + testRun.getKey()); + return; + } + deviceInfoMap.put(testRun.getKey(), devices); + + TestRunEntity testRunEntity = TestRunEntity.fromEntity(testRun); + if (testRunEntity == null) + return; + if (testRunEntity.startTimestamp < startTime) { + startTime = testRunEntity.startTimestamp; + } + if (testRunEntity.endTimestamp > endTime) { + endTime = testRunEntity.endTimestamp; + } + testRuns.add(testRunEntity); + testCaseRunMap.put(testRun.getKey(), new ArrayList<TestCaseRunEntity>()); + + // Process the test cases in the test run + for (Entity e : testCaseRuns) { + TestCaseRunEntity testCaseRunEntity = TestCaseRunEntity.fromEntity(e); + if (testCaseRunEntity == null) + continue; + testCaseRunMap.get(testRun.getKey()).add(testCaseRunEntity); + for (TestCase testCase : testCaseRunEntity.testCases) { + if (!testCaseNameMap.containsKey(testCase.name)) { + testCaseNameMap.put(testCase.name, testCaseNameMap.size()); + } + } + } + + // Process the profiling point observations in the test run + for (Entity e : profilingPoints) { + if (e.getKey().getName() != null) { + profilingPointNameSet.add(e.getKey().getName()); + } + } + } + + /** Creates a test case breakdown of the most recent test run. */ + private void generateToTBreakdown() { + totResultCounts = new int[TestCaseResult.values().length]; + if (testRuns.size() == 0) + return; + + TestRunEntity mostRecentRun = testRuns.get(0); + List<TestCaseRunEntity> testCaseResults = testCaseRunMap.get(mostRecentRun.key); + List<DeviceInfoEntity> deviceInfos = deviceInfoMap.get(mostRecentRun.key); + if (deviceInfos.size() > 0) { + DeviceInfoEntity totDevice = deviceInfos.get(0); + totBuildId = totDevice.buildId; + } + // Count array for each test result + for (TestCaseRunEntity testCaseRunEntity : testCaseResults) { + for (TestCase testCase : testCaseRunEntity.testCases) { + totResultCounts[testCase.result]++; + } + } + } + + /** + * Get the number of test runs observed. + * + * @return The number of test runs observed. + */ + public int getSize() { + return testRuns.size(); + } + + /** Post-process the test runs to generate reports of the results. */ + public void processReport() { + Comparator<TestRunEntity> comparator = new Comparator<TestRunEntity>() { + @Override + public int compare(TestRunEntity t1, TestRunEntity t2) { + return new Long(t2.startTimestamp).compareTo(t1.startTimestamp); + } + }; + Collections.sort(testRuns, comparator); + generateToTBreakdown(); + + headerRow = new String[testRuns.size() + 1]; + headerRow[0] = StringUtils.join(HEADER_NAMES, "<br>"); + + summaryGrid = new String[SUMMARY_NAMES.length][testRuns.size() + 1]; + for (int i = 0; i < SUMMARY_NAMES.length; i++) { + summaryGrid[i][0] = "<b>" + SUMMARY_NAMES[i] + "</b>"; + } + + timeGrid = new String[TIME_INFO_NAMES.length][testRuns.size() + 1]; + for (int i = 0; i < TIME_INFO_NAMES.length; i++) { + timeGrid[i][0] = "<b>" + TIME_INFO_NAMES[i] + "</b>"; + } + + durationGrid = new String[DURATION_INFO_NAMES.length][testRuns.size() + 1]; + for (int i = 0; i < DURATION_INFO_NAMES.length; i++) { + durationGrid[i][0] = "<b>" + DURATION_INFO_NAMES[i] + "</b>"; + } + + resultsGrid = new String[testCaseNameMap.size()][testRuns.size() + 1]; + // first column for results grid + for (String testCaseName : testCaseNameMap.keySet()) { + resultsGrid[testCaseNameMap.get(testCaseName)][0] = testCaseName; + } + + // Iterate through the test runs + for (int col = 0; col < testRuns.size(); col++) { + TestRunEntity testRun = testRuns.get(col); + + // Process the device information + List<DeviceInfoEntity> devices = deviceInfoMap.get(testRun.key); + List<String> buildIdList = new ArrayList<>(); + List<String> buildAliasList = new ArrayList<>(); + List<String> buildFlavorList = new ArrayList<>(); + List<String> productVariantList = new ArrayList<>(); + List<String> abiInfoList = new ArrayList<>(); + for (DeviceInfoEntity deviceInfoEntity : devices) { + buildAliasList.add(deviceInfoEntity.branch); + buildFlavorList.add(deviceInfoEntity.buildFlavor); + productVariantList.add(deviceInfoEntity.product); + buildIdList.add(deviceInfoEntity.buildId); + String abi = ""; + String abiName = deviceInfoEntity.abiName; + String abiBitness = deviceInfoEntity.abiBitness; + if (abiName.length() > 0) { + abi += abiName; + if (abiBitness.length() > 0) { + abi += " (" + abiBitness + " bit)"; + } + } + abiInfoList.add(abi); + } + + String buildAlias = StringUtils.join(buildAliasList, ","); + String buildFlavor = StringUtils.join(buildFlavorList, ","); + String productVariant = StringUtils.join(productVariantList, ","); + String buildIds = StringUtils.join(buildIdList, ","); + String abiInfo = StringUtils.join(abiInfoList, ","); + String vtsBuildId = testRun.testBuildId; + + int totalCount = 0; + int passCount = (int) testRun.passCount; + int nonpassCount = (int) testRun.failCount; + TestCaseResult aggregateStatus = TestCaseResult.UNKNOWN_RESULT; + long totalLineCount = testRun.totalLineCount; + long coveredLineCount = testRun.coveredLineCount; + + // Process test case results + for (TestCaseRunEntity testCaseEntity : testCaseRunMap.get(testRun.key)) { + // Update the aggregated test run status + totalCount += testCaseEntity.testCases.size(); + for (TestCase testCase : testCaseEntity.testCases) { + int result = testCase.result; + String name = testCase.name; + if (result == TestCaseResult.TEST_CASE_RESULT_PASS.getNumber()) { + if (aggregateStatus == TestCaseResult.UNKNOWN_RESULT) { + aggregateStatus = TestCaseResult.TEST_CASE_RESULT_PASS; + } + } else if (result != TestCaseResult.TEST_CASE_RESULT_SKIP.getNumber()) { + aggregateStatus = TestCaseResult.TEST_CASE_RESULT_FAIL; + } + + String systraceUrl = null; + + if (testCaseEntity.getSystraceUrl() != null) { + String url = testCaseEntity.getSystraceUrl(); + LinkDisplay validatedLink = UrlUtil.processUrl(url); + if (validatedLink != null) { + systraceUrl = validatedLink.url; + } else { + logger.log(Level.WARNING, "Invalid systrace URL : " + url); + } + } + + int index = testCaseNameMap.get(name); + String classNames = "test-case-status "; + String glyph = ""; + TestCaseResult testCaseResult = TestCaseResult.valueOf(result); + if (testCaseResult != null) + classNames += testCaseResult.toString(); + else + classNames += TestCaseResult.UNKNOWN_RESULT.toString(); + + if (systraceUrl != null) { + classNames += " width-1"; + glyph += "<a href=\"" + systraceUrl + "\" " + + "class=\"waves-effect waves-light btn red right inline-btn\">" + + "<i class=\"material-icons inline-icon\">info_outline</i></a>"; + } + resultsGrid[index][col + 1] = + "<div class=\"" + classNames + "\"> </div>" + glyph; + } + } + String passInfo; + try { + double passPct = + Math.round((100 * passCount / (passCount + nonpassCount)) * 100f) / 100f; + passInfo = Double.toString(passPct) + "%"; + } catch (ArithmeticException e) { + passInfo = " - "; + } + + // Process coverage metadata + String coverageInfo; + String coveragePctInfo; + try { + double coveragePct = + Math.round((100 * coveredLineCount / totalLineCount) * 100f) / 100f; + coveragePctInfo = Double.toString(coveragePct) + "%" + + "<a href=\"/show_coverage?testName=" + testName + "&startTime=" + + testRun.startTimestamp + + "\" class=\"waves-effect waves-light btn red right inline-btn\">" + + "<i class=\"material-icons inline-icon\">menu</i></a>"; + coverageInfo = coveredLineCount + "/" + totalLineCount; + } catch (ArithmeticException e) { + coveragePctInfo = " - "; + coverageInfo = " - "; + } + + // Process log information + String logSummary = " - "; + List<String[]> logEntries = new ArrayList<>(); + logInfoMap.put(Integer.toString(col), logEntries); + + if (testRun.logLinks != null) { + for (String rawUrl : testRun.logLinks) { + LinkDisplay validatedLink = UrlUtil.processUrl(rawUrl); + if (validatedLink == null) { + logger.log(Level.WARNING, "Invalid logging URL : " + rawUrl); + continue; + } + String[] logInfo = new String[] { + validatedLink.name, + validatedLink.url // TODO: process the name from the URL + }; + logEntries.add(logInfo); + } + } + if (logEntries.size() > 0) { + logSummary = Integer.toString(logEntries.size()); + logSummary += "<i class=\"waves-effect waves-light btn red right inline-btn" + + " info-btn material-icons inline-icon\"" + + " data-col=\"" + Integer.toString(col) + "\"" + + ">launch</i>"; + } + + String icon = "<div class='status-icon " + aggregateStatus.toString() + "'> </div>"; + String hostname = testRun.hostName; + + // Populate the header row + headerRow[col + 1] = "<span class='valign-wrapper'><b>" + buildIds + "</b>" + icon + + "</span>" + buildAlias + "<br>" + buildFlavor + "<br>" + productVariant + + "<br>" + abiInfo + "<br>" + vtsBuildId + "<br>" + hostname; + + // Populate the test summary grid + summaryGrid[0][col + 1] = Integer.toString(totalCount); + summaryGrid[1][col + 1] = Integer.toString(passCount); + summaryGrid[2][col + 1] = Integer.toString(nonpassCount); + summaryGrid[3][col + 1] = passInfo; + summaryGrid[4][col + 1] = coverageInfo; + summaryGrid[5][col + 1] = coveragePctInfo; + summaryGrid[6][col + 1] = logSummary; + + // Populate the test time info grid + timeGrid[0][col + 1] = Long.toString(testRun.startTimestamp); + timeGrid[1][col + 1] = Long.toString(testRun.endTimestamp); + + // Populate the test duration info grid + durationGrid[0][col + 1] = Long.toString(testRun.endTimestamp - testRun.startTimestamp); + } + + profilingPointNames = + profilingPointNameSet.toArray(new String[profilingPointNameSet.size()]); + Arrays.sort(profilingPointNames); + } +} diff --git a/src/main/java/com/android/vts/util/TestRunDetails.java b/src/main/java/com/android/vts/util/TestRunDetails.java new file mode 100644 index 0000000..41e20c4 --- /dev/null +++ b/src/main/java/com/android/vts/util/TestRunDetails.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2017 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.util; + +import com.android.vts.entity.TestCaseRunEntity; +import com.android.vts.entity.TestCaseRunEntity.TestCase; +import com.android.vts.proto.VtsReportMessage.TestCaseResult; +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** Helper object for describing test results data. */ +public class TestRunDetails { + private static final String NAME_KEY = "name"; + private static final String DATA_KEY = "data"; + + private class ResultColumn { + private final String name; + private final List<String> testCases; + + public ResultColumn(String name) { + this.name = name; + this.testCases = new ArrayList<>(); + } + + public void add(String testCase) { + this.testCases.add(testCase); + } + + public int size() { + return this.testCases.size(); + } + + public JsonObject toJson() { + Collections.sort(testCases); + JsonObject json = new JsonObject(); + json.add(NAME_KEY, new JsonPrimitive(name)); + json.add(DATA_KEY, new Gson().toJsonTree(testCases)); + return json; + } + } + + private final ResultColumn[] columns; + public final int[] resultCounts = new int[TestCaseResult.values().length]; + + public TestRunDetails() { + columns = new ResultColumn[TestCaseResult.values().length]; + for (TestCaseResult r : TestCaseResult.values()) { + columns[r.getNumber()] = new ResultColumn(r.name()); + } + } + + /** + * Add a test case entity to the details object. + * @param testCaseEntity The TestCaseRunEntity object storing test case results. + */ + public void addTestCase(TestCaseRunEntity testCaseEntity) { + for (TestCase testCase : testCaseEntity.testCases) { + int result = testCase.result; + if (result > resultCounts.length) + continue; + ++resultCounts[result]; + ResultColumn column = columns[result]; + column.add(testCase.name); + } + } + + /** + * Serializes the test run details to json format. + * + * @return A JsonObject object representing the details object. + */ + public JsonElement toJson() { + List<JsonObject> jsonColumns = new ArrayList<>(); + for (ResultColumn column : columns) { + if (column.size() > 0) { + jsonColumns.add(column.toJson()); + } + } + return new Gson().toJsonTree(jsonColumns); + } +} diff --git a/src/main/java/com/android/vts/util/TestRunMetadata.java b/src/main/java/com/android/vts/util/TestRunMetadata.java new file mode 100644 index 0000000..0cc375c --- /dev/null +++ b/src/main/java/com/android/vts/util/TestRunMetadata.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2017 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.util; + +import com.android.vts.entity.DeviceInfoEntity; +import com.android.vts.entity.TestRunEntity; +import com.google.appengine.api.datastore.DatastoreService; +import com.google.appengine.api.datastore.DatastoreServiceFactory; +import com.google.appengine.api.datastore.Entity; +import com.google.appengine.api.datastore.Query; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import java.util.ArrayList; +import java.util.List; +import org.apache.commons.lang.StringUtils; + +/** Helper object for describing test results data. */ +public class TestRunMetadata { + private static final String TEST_RUN = "testRun"; + private static final String TEST_DETAILS = "testDetails"; + private static final String DEVICE_INFO = "deviceInfo"; + private static final String ABI_INFO = "abiInfo"; + + public final TestRunEntity testRun; + + private String deviceInfo; + private String abiInfo; + private TestRunDetails details; + + /** + * Create a test metadata object. + * + * @param testName The name of the test. + */ + public TestRunMetadata(String testName, TestRunEntity testRun) { + this.testRun = testRun; + this.deviceInfo = ""; + this.abiInfo = ""; + this.details = null; + processDeviceInfo(); + } + + /** + * Get device information for the test run and add it to the metadata message. + */ + private void processDeviceInfo() { + DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); + Query deviceInfoQuery = new Query(DeviceInfoEntity.KIND).setAncestor(testRun.key); + List<String> deviceInfoList = new ArrayList<>(); + List<String> abiInfoList = new ArrayList<>(); + + for (Entity device : datastore.prepare(deviceInfoQuery).asIterable()) { + DeviceInfoEntity deviceInfoEntity = DeviceInfoEntity.fromEntity(device); + if (deviceInfoEntity == null) { + continue; + } + String abi = ""; + String abiName = deviceInfoEntity.abiName; + String abiBitness = deviceInfoEntity.abiBitness; + if (abiName.length() > 0) { + abi += abiName; + if (abiBitness.length() > 0) { + abi += " (" + abiBitness + " bit)"; + } + } + abiInfoList.add(abi); + deviceInfoList.add(deviceInfoEntity.branch + "/" + deviceInfoEntity.buildFlavor + " (" + + deviceInfoEntity.buildId + ")"); + } + this.abiInfo = StringUtils.join(abiInfoList, ", "); + this.deviceInfo = StringUtils.join(deviceInfoList, ", "); + } + + /** + * Get the device info string in the test metadata. + * @return The string descriptor of the devices used in the test run. + */ + public String getDeviceInfo() { + return this.deviceInfo; + } + + /** + * Get the test run details (e.g. test case information) for the test run. + * @return The TestRunDetails object stored in the metadata, or null if not set. + */ + public TestRunDetails getDetails() { + return this.details; + } + + /** + * Add test case details to the metadata object. + * + * Used for prefetching details on initial page load. + * @param details The TestRunDetails object storing test case results for the test run. + */ + public void addDetails(TestRunDetails details) { + this.details = details; + } + + /** + * Serializes the test run metadata to json format. + * + * @return A JsonElement object representing the details object. + */ + public JsonObject toJson() { + JsonObject json = new JsonObject(); + json.add(DEVICE_INFO, new JsonPrimitive(this.deviceInfo)); + json.add(ABI_INFO, new JsonPrimitive(this.abiInfo)); + json.add(TEST_RUN, this.testRun.toJson()); + if (this.details != null) { + json.add(TEST_DETAILS, this.details.toJson()); + } + return json; + } +} diff --git a/src/main/java/com/android/vts/util/UrlUtil.java b/src/main/java/com/android/vts/util/UrlUtil.java new file mode 100644 index 0000000..03c23eb --- /dev/null +++ b/src/main/java/com/android/vts/util/UrlUtil.java @@ -0,0 +1,74 @@ +/** + * Copyright 2017 Google Inc. All Rights Reserved. + * + * <p>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 + * + * <p>http://www.apache.org/licenses/LICENSE-2.0 + * + * <p>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. + */ +package com.android.vts.util; + +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; + +/** UrlUtil, a helper class for formatting and validating URLs. */ +public class UrlUtil { + private static final String HTTPS = "https"; + + public static class LinkDisplay { + public final String name; + public final String url; + + /** + * Create a link display object. + * + * @param uri The hyperlink URI. + */ + public LinkDisplay(URI uri) { + this.url = uri.toString(); + + // Parse the name from the URI path + int lastSeparator = uri.getPath().lastIndexOf('/'); + if (lastSeparator < 0) { + this.name = uri.toString(); + } else { + this.name = uri.getPath().substring(lastSeparator + 1); + } + } + } + + /** + * Validates and formats a URL. + * + * <p>Ensures that the protocol is HTTPs and the URL is properly formatted. This avoids link + * issues in the UI and possible vulnerabilities due to embedded JS in URLs. + * + * @param urlString The url string to validate. + * @returns The validated LinkDisplay object. + */ + public static LinkDisplay processUrl(String urlString) { + try { + URL url = new URL(urlString); + String scheme = url.getProtocol(); + String userInfo = url.getUserInfo(); + String host = url.getHost(); + int port = url.getPort(); + String path = url.getPath(); + String query = url.getQuery(); + String fragment = url.getRef(); + if (!url.getProtocol().equals(HTTPS)) + throw new MalformedURLException(); + URI uri = new URI(scheme, userInfo, host, port, path, query, fragment); + return new LinkDisplay(uri); + } catch (MalformedURLException | URISyntaxException e) { + return null; + } + } +} diff --git a/src/main/webapp/WEB-INF/appengine-web.xml b/src/main/webapp/WEB-INF/appengine-web.xml new file mode 100644 index 0000000..6c7632c --- /dev/null +++ b/src/main/webapp/WEB-INF/appengine-web.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright 2016 Google Inc. + 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. +--> + +<appengine-web-app xmlns="http://appengine.google.com/ns/1.0"> + <application>s~google.com:android-vts-staging</application> + <version>4</version> + <threadsafe>true</threadsafe> + + <system-properties> + <property name="EMAIL_DOMAIN" value="${appengine.emailDomain}" /> + <property name="SENDER_EMAIL" value="${appengine.senderEmail}" /> + <property name="DEFAULT_EMAIL" value="${appengine.defaultEmail}" /> + <property name="SERVICE_CLIENT_ID" value="${appengine.serviceClientID}" /> + <property name="CLIENT_ID" value="${appengine.clientID}" /> + <property name="GERRIT_URI" value="${gerrit.uri}" /> + <property name="GERRIT_SCOPE" value="${gerrit.scope}" /> + <property name="ANALYTICS_ID" value="${analytics.id}" /> + </system-properties> + +</appengine-web-app>
\ No newline at end of file diff --git a/src/main/webapp/WEB-INF/cron.xml b/src/main/webapp/WEB-INF/cron.xml new file mode 100644 index 0000000..d8dc49e --- /dev/null +++ b/src/main/webapp/WEB-INF/cron.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Copyright 2016 Google Inc. All Rights Reserved. + + 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. +--> +<cronentries> + <cron> + <url>/cron/vts_alert_job</url> + <description>Send test failure emails.</description> + <schedule>every 2 minutes</schedule> + </cron> + <cron> + <url>/cron/vts_performance_job</url> + <description>Send daily performance digests.</description> + <schedule>every day 07:30</schedule> + <timezone>America/Los_Angeles</timezone> + </cron> +</cronentries>
\ No newline at end of file diff --git a/src/main/webapp/WEB-INF/datastore-indexes.xml b/src/main/webapp/WEB-INF/datastore-indexes.xml new file mode 100644 index 0000000..01983f5 --- /dev/null +++ b/src/main/webapp/WEB-INF/datastore-indexes.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright 2017 Google Inc. + 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. +--> + +<datastore-indexes autoGenerate="true"> + + <datastore-index kind="TestPlanRun" ancestor="true" source="manual"> + <property name="type" direction="asc"/> + <property name="__key__" direction="desc"/> + </datastore-index> + + <datastore-index kind="TestPlanRun" ancestor="true" source="manual"> + <property name="type" direction="asc"/> + <property name="__key__" direction="asc"/> + </datastore-index> + + <datastore-index kind="TestPlanRun" ancestor="true" source="manual"> + <property name="__key__" direction="desc"/> + </datastore-index> + + <datastore-index kind="Test" ancestor="false" source="manual"> + <property name="failCount" direction="asc"/> + <property name="passCount" direction="asc"/> + </datastore-index> + + <datastore-index kind="TestRun" ancestor="true" source="manual"> + <property name="type" direction="asc"/> + <property name="__key__" direction="desc"/> + </datastore-index> + + <datastore-index kind="TestRun" ancestor="true" source="manual"> + <property name="type" direction="asc"/> + <property name="__key__" direction="asc"/> + </datastore-index> + + <datastore-index kind="TestRun" ancestor="true" source="manual"> + <property name="__key__" direction="desc"/> + </datastore-index> + + <datastore-index kind="TestRun" ancestor="true" source="manual"> + <property name="hasCoverage" direction="asc"/> + <property name="__key__" direction="desc"/> + </datastore-index> + + <datastore-index kind="TestRun" ancestor="false" source="manual"> + <property name="testName" direction="asc"/> + <property name="startTimestamp" direction="asc"/> + </datastore-index> + + <datastore-index kind="TestRun" ancestor="false" source="manual"> + <property name="testName" direction="asc"/> + <property name="startTimestamp" direction="desc"/> + </datastore-index> + + <datastore-index kind="TestRun" ancestor="false" source="manual"> + <property name="testName" direction="asc"/> + <property name="type" direction="asc"/> + <property name="startTimestamp" direction="asc"/> + </datastore-index> + + <datastore-index kind="TestRun" ancestor="false" source="manual"> + <property name="testName" direction="asc"/> + <property name="type" direction="asc"/> + <property name="startTimestamp" direction="desc"/> + </datastore-index> + +</datastore-indexes>
\ No newline at end of file diff --git a/src/main/webapp/WEB-INF/jsp/dashboard_main.jsp b/src/main/webapp/WEB-INF/jsp/dashboard_main.jsp new file mode 100644 index 0000000..3b72110 --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/dashboard_main.jsp @@ -0,0 +1,177 @@ +<%-- + ~ Copyright (c) 2016 Google Inc. All Rights Reserved. + ~ + ~ 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. + --%> +<%@ page contentType='text/html;charset=UTF-8' language='java' %> +<%@ taglib prefix='fn' uri='http://java.sun.com/jsp/jstl/functions' %> +<%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core'%> + +<html> + <link rel='stylesheet' href='/css/dashboard_main.css'> + <%@ include file='header.jsp' %> + <script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.0/jquery-ui.min.js'></script> + <body> + <script> + var allTests = ${allTestsJson}; + var testSet = new Set(allTests); + var subscriptionMap = ${subscriptionMapJson}; + + var addFavorite = function() { + if ($(this).hasClass('disabled')) { + return; + } + var test = $('#input-box').val(); + if (!testSet.has(test) || test in subscriptionMap) { + return; + } + $('#add-button').addClass('disabled'); + $.post('/api/favorites/' + test).then(function(data) { + if (!data.key) { + return; + } + subscriptionMap[test] = data.key; + var wrapper = $('<div></div>'); + var a = $('<a></a>') + .attr('href', '/show_table?testName=' + test); + var div = $('<div class="col s11 card hoverable option"></div>'); + div.addClass('valign-wrapper waves-effect'); + div.appendTo(a); + var span = $('<span class="entry valign"></span>').text(test); + span.appendTo(div); + a.appendTo(wrapper); + var clear = $('<a class="col s1 btn-flat center"></a>'); + clear.addClass('clear-button'); + clear.append('<i class="material-icons">clear</i>'); + clear.attr('test', test); + clear.appendTo(wrapper); + clear.click(removeFavorite); + wrapper.prependTo('#options').hide() + .slideDown(150); + $('#input-box').val(null); + Materialize.updateTextFields(); + }).always(function() { + $('#add-button').removeClass('disabled'); + }); + } + + var removeFavorite = function() { + var self = $(this); + if (self.hasClass('disabled')) { + return; + } + var test = self.attr('test'); + if (!(test in subscriptionMap)) { + return; + } + self.addClass('disabled'); + $.ajax({ + url: '/api/favorites/' + subscriptionMap[test], + type: 'DELETE' + }).always(function() { + self.removeClass('disabled'); + }).then(function() { + delete subscriptionMap[test]; + self.parent().slideUp(150, function() { + self.remove(); + }); + }); + } + + $.widget('custom.sizedAutocomplete', $.ui.autocomplete, { + _resizeMenu: function() { + this.menu.element.outerWidth($('#input-box').width()); + } + }); + + $(function() { + $('#input-box').sizedAutocomplete({ + source: allTests, + classes: { + 'ui-autocomplete': 'card' + } + }); + + $('#input-box').keyup(function(event) { + if (event.keyCode == 13) { // return button + $('#add-button').click(); + } + }); + + $('.clear-button').click(removeFavorite); + $('#add-button').click(addFavorite); + }); + </script> + <div class='container'> + <c:choose> + <c:when test='${not empty error}'> + <div id='error-container' class='row card'> + <div class='col s12 center-align'> + <h5>${error}</h5> + </div> + </div> + </c:when> + <c:otherwise> + <c:set var='width' value='${showAll ? 12 : 11}' /> + <c:if test='${not showAll}'> + <div class='row'> + <div class='input-field col s8'> + <input type='text' id='input-box'></input> + <label for='input-box'>Search for tests to add to favorites</label> + </div> + <div id='add-button-wrapper' class='col s1 valign-wrapper'> + <a id='add-button' class='btn-floating btn waves-effect waves-light red valign'><i class='material-icons'>add</i></a> + </div> + </div> + </c:if> + <div class='row'> + <div class='col s12'> + <h4 id='section-header'>${headerLabel}</h4> + </div> + </div> + <div class='row' id='options'> + <c:forEach items='${testNames}' var='test'> + <div> + <a href='/show_table?testName=${test.name}'> + <div class='col s${width} card hoverable option valign-wrapper waves-effect'> + <span class='entry valign'>${test.name} + <c:if test='${test.failCount >= 0 && test.passCount >= 0}'> + <c:set var='color' value='${test.failCount > 0 ? "red" : (test.passCount > 0 ? "green" : "grey")}' /> + <span class='indicator center ${color}'> + ${test.passCount} / ${test.passCount + test.failCount} + </span> + </c:if> + </span> + </div> + </a> + <c:if test='${not showAll}'> + <a class='col s1 btn-flat center clear-button' test='${test.name}'> + <i class='material-icons'>clear</i> + </a> + </c:if> + </div> + </c:forEach> + </div> + </c:otherwise> + </c:choose> + </div> + <c:if test='${empty error}'> + <div class='center'> + <a href='${buttonLink}' id='show-button' class='btn waves-effect red'>${buttonLabel} + <i id='show-button-arrow' class='material-icons right'>${buttonIcon}</i> + </a> + </div> + </c:if> + <%@ include file='footer.jsp' %> + </body> +</html> diff --git a/src/main/webapp/WEB-INF/jsp/footer.jsp b/src/main/webapp/WEB-INF/jsp/footer.jsp new file mode 100644 index 0000000..ed2d950 --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/footer.jsp @@ -0,0 +1,25 @@ +<%-- + ~ Copyright (c) 2017 Google Inc. All Rights Reserved. + ~ + ~ 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. + --%> +<%@ page contentType="text/html;charset=UTF-8" language="java" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + +<footer class='page-footer'> + <div class='footer-copyright'> + <div class='container'> + © 2017 - The Android Open Source Project + </div> + </div> +</footer> diff --git a/src/main/webapp/WEB-INF/jsp/header.jsp b/src/main/webapp/WEB-INF/jsp/header.jsp new file mode 100644 index 0000000..77ec600 --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/header.jsp @@ -0,0 +1,70 @@ +<%-- + ~ Copyright (c) 2017 Google Inc. All Rights Reserved. + ~ + ~ 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. + --%> +<%@ page contentType='text/html;charset=UTF-8' language='java' %> +<%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core'%> + +<head> + <link rel='stylesheet' href='https://www.gstatic.com/external_hosted/materialize/all_styles-bundle.css'> + <link rel='icon' href='https://www.gstatic.com/images/branding/googleg/1x/googleg_standard_color_32dp.png' sizes='32x32'> + <link rel='stylesheet' href='https://fonts.googleapis.com/icon?family=Material+Icons'> + <link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700'> + <link rel='stylesheet' href='/css/navbar.css'> + <link rel='stylesheet' href='/css/common.css'> + <script src='https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js'></script> + <script src='https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.0/jquery-ui.min.js'></script> + <script src='https://www.gstatic.com/external_hosted/materialize/materialize.min.js'></script> + <script type='text/javascript'> + if (${analyticsID}) { + // Autogenerated from Google Analytics + (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ + (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), + m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) + })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); + ga('create', ${analyticsID}, 'auto'); + ga('send', 'pageview'); + } + </script> + <title>VTS Dashboard</title> +</head> +<body> + <nav id='navbar'> + <div class='nav-wrapper'> + <a href='#' class='brand-logo center'>VTS Dashboard</a> + <ul class='nav-list'> + <c:forEach items='${navbarLinks}' var='link' varStatus='loop'> + <li class='${loop.index == activeIndex ? "active" : ""}'> + <a class='nav-list-item' href='${link.url}'>${link.name}</a> + </li> + </c:forEach> + </ul> + <ul class='right'><li> + <a id='dropdown-button' class='dropdown-button btn red lighten-3' href='#' data-activates='dropdown'> + ${email} + </a> + </li></ul> + <ul id='dropdown' class='dropdown-content'> + <li><a href='${logoutURL}'>Log out</a></li> + </ul> + <c:if test='${breadcrumbLinks != null}'> + <div id='nav-sublist'> + <c:forEach items='${breadcrumbLinks}' var='link'> + <a href='${link.url}' class='nav-sublist-item breadcrumb'>${link.name}</a> + </c:forEach> + </div> + </c:if> + </div> + </nav> +</body> diff --git a/src/main/webapp/WEB-INF/jsp/show_coverage.jsp b/src/main/webapp/WEB-INF/jsp/show_coverage.jsp new file mode 100644 index 0000000..790590d --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/show_coverage.jsp @@ -0,0 +1,171 @@ +<%-- + ~ Copyright (c) 2016 Google Inc. All Rights Reserved. + ~ + ~ 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. + --%> +<%@ page contentType='text/html;charset=UTF-8' language='java' %> +<%@ taglib prefix='fn' uri='http://java.sun.com/jsp/jstl/functions' %> +<%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core'%> + +<html> + <%@ include file="header.jsp" %> + <link rel="stylesheet" href="/css/show_coverage.css"> + <script src="https://apis.google.com/js/api.js" type="text/javascript"></script> + <body> + <script type="text/javascript"> + var coverageVectors = ${coverageVectors}; + $(document).ready(function() { + // Initialize AJAX for CORS + $.ajaxSetup({ + xhrFields : { + withCredentials: true + } + }); + + // Initialize auth2 client and scope for requests to Gerrit + gapi.load('auth2', function() { + var auth2 = gapi.auth2.init({ + client_id: ${clientId}, + scope: ${gerritScope} + }); + auth2.then(displayEntries); + }); + }); + + /* Open a window to Gerrit so that user can login. + Minimize the previously clicked entry. + */ + var gerritLogin = function(element) { + window.open(${gerritURI}, "Ratting", "toolbar=0,status=0"); + element.click(); + } + + /* Loads source code for a particular entry and displays it with + coverage information as the accordion entry expands. + */ + var onClick = function() { + // Remove source code from the accordion entry that was open before + var self = $(this); + var prev = self.parent().siblings('li.active'); + if (prev.length > 0) { + prev.find('.table-container').empty(); + } + var url = self.parent().attr('url'); + var i = self.parent().attr('index'); + var container = self.parent().find('.table-container'); + container.html('<div class="center-align">Loading...</div>'); + if (self.parent().hasClass('active')) { + // Remove the code from display + container.empty(); + } else { + /* Fetch and display the code. + Note: a coverageVector may be shorter than sourceContents due + to non-executable (i.e. comments or language-specific syntax) + lines in the code. Trailing source lines that have no + coverage information are assumed to be non-executable. + */ + $.ajax({ + url: url, + dataType: 'text' + }).promise().done(function(src) { + src = atob(src); + if (!src) return; + srcLines = src.split('\n'); + covered = 0; + total = 0; + var table = $('<table class="table"></table>'); + var rows = srcLines.forEach(function(line, j) { + var count = coverageVectors[i][j]; + var row = $('<tr></tr>'); + if (typeof count == 'undefined' || count < 0) { + count = "--"; + } else if (count == 0) { + row.addClass('uncovered'); + total += 1; + } else { + row.addClass('covered'); + total += 1; + } + row.append('<td class="count">' + String(count) + '</td>'); + row.append('<td class="line_no">' + String(j+1) + '</td>'); + code = $('<td class="code"></td>'); + code.text(String(line)); + code.appendTo(row); + row.appendTo(table); + }); + container.empty(); + container.append(table); + }).fail(function(error) { + if (error.status == 0) { // origin error, refresh cookie + container.empty(); + container.html('<div class="center-align">' + + '<span class="login-button">' + + 'Click to authorize Gerrit access' + + '</span></div>'); + container.find('.login-button').click(function() { + gerritLogin(self); + }); + } else { + container.html('<div class="center-align">' + + 'Not found.</div>'); + } + }); + } + } + + /* Appends a row to the display with test name and aggregated coverage + information. On expansion, source code is loaded with coverage + highlighted by calling 'onClick'. + */ + var displayEntries = function() { + var sourceFilenames = ${sourceFiles}; + var sectionMap = ${sectionMap}; + var gerritURI = ${gerritURI}; + var projects = ${projects}; + var commits = ${commits}; + var indicators = ${indicators}; + Object.keys(sectionMap).forEach(function(section) { + var indices = sectionMap[section]; + var html = String(); + indices.forEach(function(i) { + var url = gerritURI + '/projects/' + + encodeURIComponent(projects[i]) + '/commits/' + + encodeURIComponent(commits[i]) + '/files/' + + encodeURIComponent(sourceFilenames[i]) + + '/content'; + html += '<li url="' + url + '" index="' + i + '">' + + '<div class="collapsible-header">' + + '<i class="material-icons">library_books</i>' + + sourceFilenames[i] + indicators[i] + '</div>'; + html += '<div class="collapsible-body row">' + + '<div class="html-container">' + + '<div class="table-container"></div>' + + '</div></div></li>'; + }); + if (html) { + html = '<h4 class="section-title"><b>Coverage:</b> ' + + section + '</h4><ul class="collapsible popout" ' + + 'data-collapsible="accordion">' + html + '</ul>'; + $('#coverage-container').append(html); + } + }); + $('.collapsible.popout').collapsible({ + accordion : true + }).find('.collapsible-header').click(onClick); + } + </script> + <div id='coverage-container' class='wide container'> + </div> + <%@ include file="footer.jsp" %> + </body> +</html> diff --git a/src/main/webapp/WEB-INF/jsp/show_coverage_overview.jsp b/src/main/webapp/WEB-INF/jsp/show_coverage_overview.jsp new file mode 100644 index 0000000..b06e9df --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/show_coverage_overview.jsp @@ -0,0 +1,168 @@ +<%-- + ~ Copyright (c) 2017 Google Inc. All Rights Reserved. + ~ + ~ 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. + --%> +<%@ page contentType='text/html;charset=UTF-8' language='java' %> +<%@ taglib prefix='fn' uri='http://java.sun.com/jsp/jstl/functions' %> +<%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core'%> + +<html> + <!-- <link rel='stylesheet' href='/css/dashboard_main.css'> --> + <%@ include file='header.jsp' %> + <link type='text/css' href='/css/show_test_runs_common.css' rel='stylesheet'> + <link type='text/css' href='/css/test_results.css' rel='stylesheet'> + <script type='text/javascript' src='https://www.gstatic.com/charts/loader.js'></script> + <script src='https://www.gstatic.com/external_hosted/moment/min/moment-with-locales.min.js'></script> + <script src='js/time.js'></script> + <script src='js/test_results.js'></script> + <script type='text/javascript'> + google.charts.load('current', {'packages':['table', 'corechart']}); + google.charts.setOnLoadCallback(drawStatsChart); + google.charts.setOnLoadCallback(drawCoverageCharts); + + $(document).ready(function() { + $('#test-results-container').showTests(${testRuns}, true); + }); + + // draw test statistics chart + function drawStatsChart() { + var testStats = ${testStats}; + if (testStats.length < 1) { + return; + } + var resultNames = ${resultNamesJson}; + var rows = resultNames.map(function(res, i) { + nickname = res.replace('TEST_CASE_RESULT_', '').replace('_', ' ') + .trim().toLowerCase(); + return [nickname, parseInt(testStats[i])]; + }); + rows.unshift(['Result', 'Count']); + + // Get CSS color definitions (or default to white) + var colors = resultNames.map(function(res) { + return $('.' + res).css('background-color') || 'white'; + }); + + var data = google.visualization.arrayToDataTable(rows); + var options = { + is3D: false, + colors: colors, + fontName: 'Roboto', + fontSize: '14px', + legend: {position: 'labeled'}, + tooltip: {showColorCode: true, ignoreBounds: false}, + chartArea: {height: '80%', width: '90%'}, + pieHole: 0.4 + }; + + var chart = new google.visualization.PieChart(document.getElementById('pie-chart-stats')); + chart.draw(data, options); + } + + // draw the coverage pie charts + function drawCoverageCharts() { + var coveredLines = ${coveredLines}; + var uncoveredLines = ${uncoveredLines}; + var rows = [ + ["Result", "Count"], + ["Covered Lines", coveredLines], + ["Uncovered Lines", uncoveredLines] + ]; + + // Get CSS color definitions (or default to white) + var colors = [ + $('.TEST_CASE_RESULT_PASS').css('background-color') || 'white', + $('.TEST_CASE_RESULT_FAIL').css('background-color') || 'white' + ] + + var data = google.visualization.arrayToDataTable(rows); + + + var optionsRaw = { + is3D: false, + colors: colors, + fontName: 'Roboto', + fontSize: '14px', + pieSliceText: 'value', + legend: {position: 'bottom'}, + chartArea: {height: '80%', width: '90%'}, + tooltip: {showColorCode: true, ignoreBounds: false, text: 'value'}, + pieHole: 0.4 + }; + + var optionsNormalized = { + is3D: false, + colors: colors, + fontName: 'Roboto', + fontSize: '14px', + legend: {position: 'bottom'}, + tooltip: {showColorCode: true, ignoreBounds: false, text: 'percentage'}, + chartArea: {height: '80%', width: '90%'}, + pieHole: 0.4 + }; + + var chart = new google.visualization.PieChart(document.getElementById('pie-chart-coverage-raw')); + chart.draw(data, optionsRaw); + + chart = new google.visualization.PieChart(document.getElementById('pie-chart-coverage-normalized')); + chart.draw(data, optionsNormalized); + } + + </script> + + <body> + <div class='wide container'> + <div class='row'> + <div class='col s12'> + <div class='col s12 card center-align'> + <div id='legend-wrapper'> + <c:forEach items='${resultNames}' var='res'> + <div class='center-align legend-entry'> + <c:set var='trimmed' value='${fn:replace(res, "TEST_CASE_RESULT_", "")}'/> + <c:set var='nickname' value='${fn:replace(trimmed, "_", " ")}'/> + <label for='${res}'>${nickname}</label> + <div id='${res}' class='${res} legend-bubble'></div> + </div> + </c:forEach> + </div> + </div> + </div> + <div class='col s4 valign-wrapper'> + <!-- pie chart --> + <div class='pie-chart-wrapper col s12 valign center-align card'> + <h6 class='pie-chart-title'>Test Statistics</h6> + <div id='pie-chart-stats' class='pie-chart-div'></div> + </div> + </div> + <div class='col s4 valign-wrapper'> + <!-- pie chart --> + <div class='pie-chart-wrapper col s12 valign center-align card'> + <h6 class='pie-chart-title'>Coverage (Raw)</h6> + <div id='pie-chart-coverage-raw' class='pie-chart-div'></div> + </div> + </div> + <div class='col s4 valign-wrapper'> + <!-- pie chart --> + <div class='pie-chart-wrapper col s12 valign center-align card'> + <h6 class='pie-chart-title'>Coverage (Normalized)</h6> + <div id='pie-chart-coverage-normalized' class='pie-chart-div'></div> + </div> + </div> + </div> + <div class='col s12' id='test-results-container'> + </div> + </div> + <%@ include file="footer.jsp" %> + </body> +</html> diff --git a/src/main/webapp/WEB-INF/jsp/show_graph.jsp b/src/main/webapp/WEB-INF/jsp/show_graph.jsp new file mode 100644 index 0000000..7111f58 --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/show_graph.jsp @@ -0,0 +1,292 @@ +<%-- + ~ Copyright (c) 2016 Google Inc. All Rights Reserved. + ~ + ~ 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. + --%> +<%@ page contentType='text/html;charset=UTF-8' language='java' %> +<%@ taglib prefix='fn' uri='http://java.sun.com/jsp/jstl/functions' %> +<%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core'%> + +<html> + <%@ include file="header.jsp" %> + <link type='text/css' href='/css/datepicker.css' rel='stylesheet'> + <link type='text/css' href='/css/show_graph.css' rel='stylesheet'> + <link rel='stylesheet' href='https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.0/jquery-ui.css'> + <script type='text/javascript' src='https://www.gstatic.com/charts/loader.js'></script> + <script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js'></script> + <body> + <script type='text/javascript'> + google.charts.load('current', {packages:['corechart', 'table', 'line']}); + google.charts.setOnLoadCallback(drawAllGraphs); + + ONE_DAY = 86400000000; + MICRO_PER_MILLI = 1000; + N_BUCKETS = 200; + + var graphs = ${graphs}; + + $(function() { + $('select').material_select(); + var date = $('#date').datepicker({ + showAnim: 'slideDown', + maxDate: new Date() + }); + date.datepicker('setDate', new Date(${endTime} / MICRO_PER_MILLI)); + $('#load').click(load); + $('#outlier-select').change(drawAllGraphs); + }); + + // Draw all graphs. + function drawAllGraphs() { + $('#profiling-container').empty(); + var percentileIndex = Number($('#outlier-select').val()); + + // Get histogram extrema + var histMin = null; + var histMax = null; + graphs.forEach(function(g) { + if (g.type != 'HISTOGRAM') return; + var minVal; + var maxVal; + if (percentileIndex == -1) { + minVal = g.min; + maxVal = g.max; + } else { + minVal = g.percentile_values[percentileIndex]; + var endIndex = g.percentiles.length - percentileIndex - 1 + maxVal = g.percentile_values[endIndex]; + } + if (!histMin || minVal < histMin) histMin = minVal; + if (!histMax || maxVal > histMax) histMax = maxVal; + }); + + graphs.forEach(function(graph) { + if (graph.type == 'LINE_GRAPH') drawLineGraph(graph); + else if (graph.type == 'HISTOGRAM') + drawHistogram(graph, histMin, histMax); + }); + } + + /** + * Draw a line graph. + * + * Args: + * lineGraph: a JSON object containing the following fields: + * - name: the name of the graph + * - values: an array of numbers + * - ticks: an array of strings to use as x-axis labels + * - ids: an array of string labels for each point (e.g. the + * build info for the run that produced the point) + * - x_label: the string label for the x axis + * - y_label: the string label for the y axis + */ + function drawLineGraph(lineGraph) { + if (!lineGraph.ticks || lineGraph.ticks.length < 1) { + return; + } + var title = 'Performance'; + if (lineGraph.name) title += ' (' + lineGraph.name + ')'; + lineGraph.ticks.forEach(function (label, i) { + lineGraph.values[i].unshift(label); + }); + var data = new google.visualization.DataTable(); + data.addColumn('string', lineGraph.x_label); + lineGraph.ids.forEach(function(id) { + data.addColumn('number', id); + }); + data.addRows(lineGraph.values); + var options = { + chart: { + title: title, + subtitle: lineGraph.y_label + }, + legend: { position: 'none' } + }; + var container = $('<div class="row card center-align col s12 graph-wrapper"></div>'); + container.appendTo('#profiling-container'); + var chartDiv = $('<div class="col s12 graph"></div>'); + chartDiv.appendTo(container); + var chart = new google.charts.Line(chartDiv[0]); + chart.draw(data, options); + } + + /** + * Draw a histogram. + * + * Args: + * hist: a JSON object containing the following fields: + * - name: the name of the graph + * - values: an array of numbers + * - ids: an array of string labels for each point (e.g. the + * build info for the run that produced the point) + * - x_label: the string label for the x axis + * - y_label: the string label for the y axis + * min: the minimum value to display + * max: the maximum value to display + */ + function drawHistogram(hist, min, max) { + if (!hist.values || hist.values.length == 0) return; + var title = 'Performance'; + if (hist.name) title += ' (' + hist.name + ')'; + var values = hist.values; + var histogramData = values.reduce(function(result, d, i) { + if (d <= max && d >= min) result.push([hist.ids[i], d]); + return result; + }, []); + + var data = google.visualization.arrayToDataTable(histogramData, true); + var bucketSize = (max - min) / N_BUCKETS; + + var options = { + title: title, + titleTextStyle: { + color: '#757575', + fontSize: 16, + bold: false + }, + legend: { position: 'none' }, + colors: ['#4285F4'], + fontName: 'Roboto', + vAxis:{ + title: hist.y_label, + titleTextStyle: { + color: '#424242', + fontSize: 12, + italic: false + }, + textStyle: { + fontSize: 12, + color: '#757575' + }, + }, + hAxis: { + title: hist.x_label, + textStyle: { + fontSize: 12, + color: '#757575' + }, + titleTextStyle: { + color: '#424242', + fontSize: 12, + italic: false + } + }, + bar: { gap: 0 }, + histogram: { + minValue: min, + maxValue: max, + maxNumBuckets: N_BUCKETS, + bucketSize: bucketSize + }, + chartArea: { + width: '100%', + top: 40, + left: 60, + height: 375 + } + }; + var container = $('<div class="row card col s12 graph-wrapper"></div>'); + container.appendTo('#profiling-container'); + + var chartDiv = $('<div class="col s12 graph"></div>'); + chartDiv.appendTo(container); + var chart = new google.visualization.Histogram(chartDiv[0]); + chart.draw(data, options); + + var tableDiv = $('<div class="col s12"></div>'); + tableDiv.appendTo(container); + + var tableHtml = '<table class="percentile-table"><thead><tr>'; + hist.percentiles.forEach(function(p) { + tableHtml += '<th data-field="id">' + p + '%</th>'; + }); + tableHtml += '</tr></thead><tbody><tr>'; + hist.percentile_values.forEach(function(v) { + tableHtml += '<td>' + v + '</td>'; + }); + tableHtml += '</tbody></table>'; + $(tableHtml).appendTo(tableDiv); + } + + // Reload the page. + function load() { + var endTime = $('#date').datepicker('getDate').getTime(); + endTime = endTime + (ONE_DAY / MICRO_PER_MILLI) - 1; + var filterVal = $('#outlier-select').val(); + var ctx = '${pageContext.request.contextPath}'; + var link = ctx + '/show_graph?profilingPoint=${profilingPointName}' + + '&testName=${testName}' + + '&endTime=' + (endTime * MICRO_PER_MILLI) + + '&filterVal=' + filterVal; + if ($('#device-select').prop('selectedIndex') > 1) { + link += '&device=' + $('#device-select').val(); + } + window.open(link,'_self'); + } + </script> + <div id='download' class='fixed-action-btn'> + <a id='b' class='btn-floating btn-large red waves-effect waves-light'> + <i class='large material-icons'>file_download</i> + </a> + </div> + <div class='container wide'> + <div class='row card'> + <div id='header-container' class='valign-wrapper col s12'> + <div class='col s3 valign'> + <h5>Profiling Point:</h5> + </div> + <div class='col s9 right-align valign'> + <h5 class='profiling-name truncate'>${profilingPointName}</h5> + </div> + </div> + <div id='date-container' class='col s12'> + <c:set var='offset' value='${showFilterDropdown ? 0 : 2}' /> + <c:if test='${showFilterDropdown}'> + <div id='outlier-select-wrapper' class='col s2'> + <select id='outlier-select'> + <option value='-1' ${filterVal eq -1 ? 'selected' : ''}>Show outliers</option> + <option value='0' ${filterVal eq 0 ? 'selected' : ''}>Filter outliers (1%)</option> + <option value='1' ${filterVal eq 1 ? 'selected' : ''}>Filter outliers (2%)</option> + <option value='2' ${filterVal eq 2 ? 'selected' : ''}>Filter outliers (5%)</option> + </select> + </div> + </c:if> + <div id='device-select-wrapper' class='input-field col s5 m3 offset-m${offset + 4} offset-s${offset}'> + <select id='device-select'> + <option value='' disabled>Select device</option> + <option value='0' ${empty selectedDevice ? 'selected' : ''}>All Devices</option> + <c:forEach items='${devices}' var='device' varStatus='loop'> + <option value=${device} ${selectedDevice eq device ? 'selected' : ''}>${device}</option> + </c:forEach> + </select> + </div> + <input type='text' id='date' name='date' class='col s4 m2'> + <a id='load' class='btn-floating btn-medium red right waves-effect waves-light'> + <i class='medium material-icons'>cached</i> + </a> + </div> + </div> + <div id='profiling-container'> + </div> + <c:if test='${not empty error}'> + <div id='error-container' class='row card'> + <div class='col s10 offset-s1 center-align'> + <!-- Error in case of profiling data is missing --> + <h5>${error}</h5> + </div> + </div> + </c:if> + </div> + <%@ include file="footer.jsp" %> + </body> +</html> diff --git a/src/main/webapp/WEB-INF/jsp/show_performance_digest.jsp b/src/main/webapp/WEB-INF/jsp/show_performance_digest.jsp new file mode 100644 index 0000000..224d847 --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/show_performance_digest.jsp @@ -0,0 +1,100 @@ +<%-- + ~ Copyright (c) 2016 Google Inc. All Rights Reserved. + ~ + ~ 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. + --%> +<%@ page contentType='text/html;charset=UTF-8' language='java' %> +<%@ taglib prefix='fn' uri='http://java.sun.com/jsp/jstl/functions' %> +<%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core'%> + +<html> + <%@ include file="header.jsp" %> + <link type='text/css' href='/css/datepicker.css' rel='stylesheet'> + <link type='text/css' href='/css/show_performance_digest.css' rel='stylesheet'> + <link rel='stylesheet' href='https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.0/jquery-ui.css'> + <script src='https://www.gstatic.com/external_hosted/moment/min/moment-with-locales.min.js'></script> + <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script> + <body> + <script type='text/javascript'> + ONE_DAY = 86400000000; + MICRO_PER_MILLI = 1000; + + function load() { + var time = $('#date').datepicker('getDate').getTime() - 1; + time = time * MICRO_PER_MILLI + ONE_DAY; // end of day + var ctx = '${pageContext.request.contextPath}'; + var link = ctx + '/show_performance_digest?profilingPoint=${profilingPointName}' + + '&testName=${testName}' + + '&startTime=' + time; + if ($('#device-select').prop('selectedIndex') > 1) { + link += '&device=' + $('#device-select').val(); + } + window.open(link,'_self'); + } + + $(function() { + var date = $('#date').datepicker({ + showAnim: "slideDown", + maxDate: new Date() + }); + date.datepicker('setDate', new Date(${startTime} / MICRO_PER_MILLI)); + $('#load').click(load); + + $('.date-label').each(function(i) { + var label = $(this); + label.html(moment(parseInt(label.html())).format('M/D/YY')); + }); + $('select').material_select(); + }); + </script> + <div class='wide container'> + <div class='row card'> + <div id='header-container' class='col s12'> + <div class='col s12'> + <h4>Daily Performance Digest</h4> + </div> + <div id='device-select-wrapper' class='input-field col s6 m3 offset-m6'> + <select id='device-select'> + <option value='' disabled>Select device</option> + <option value='0' ${empty selectedDevice ? 'selected' : ''}>All Devices</option> + <c:forEach items='${devices}' var='device' varStatus='loop'> + <option value=${device} ${selectedDevice eq device ? 'selected' : ''}>${device}</option> + </c:forEach> + </select> + </div> + <input type='text' id='date' name='date' class='col s5 m2'> + <a id='load' class='btn-floating btn-medium red right waves-effect waves-light'> + <i class='medium material-icons'>cached</i> + </a> + </div> + </div> + <div class='row'> + <c:forEach items='${tables}' var='table' varStatus='loop'> + <div class='col s12 card summary'> + <div class='col s3 valign'> + <h5>Profiling Point:</h5> + </div> + <div class='col s9 right-align valign'> + <h5 class="profiling-name truncate">${tableTitles[loop.index]}</h5> + </div> + ${table} + <span class='profiling-subtitle'> + ${tableSubtitles[loop.index]} + </span> + </div> + </c:forEach> + </div> + </div> + <%@ include file="footer.jsp" %> + </body> +</html> diff --git a/src/main/webapp/WEB-INF/jsp/show_plan_release.jsp b/src/main/webapp/WEB-INF/jsp/show_plan_release.jsp new file mode 100644 index 0000000..b202d04 --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/show_plan_release.jsp @@ -0,0 +1,109 @@ +<%-- + ~ Copyright (c) 2017 Google Inc. All Rights Reserved. + ~ + ~ 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. + --%> +<%@ page contentType='text/html;charset=UTF-8' language='java' %> +<%@ taglib prefix='fn' uri='http://java.sun.com/jsp/jstl/functions' %> +<%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core'%> + +<html> + <%@ include file="header.jsp" %> + <link rel='stylesheet' href='/css/show_plan_release.css'> + <link rel='stylesheet' href='/css/plan_runs.css'> + <link rel='stylesheet' href='/css/search_header.css'> + <script src='https://www.gstatic.com/external_hosted/moment/min/moment-with-locales.min.js'></script> + <script src='js/time.js'></script> + <script src='js/plan_runs.js'></script> + <script src='js/search_header.js'></script> + <script type='text/javascript'> + var search; + $(document).ready(function() { + // disable buttons on load + if (!${hasNewer}) { + $('#newer-button').toggleClass('disabled'); + } + if (!${hasOlder}) { + $('#older-button').toggleClass('disabled'); + } + + $('#newer-button').click(prev); + $('#older-button').click(next); + search = $('#filter-bar').createSearchHeader('Plan: ', '${plan}', refresh); + search.addFilter('Branch', 'branch', { + corpus: ${branches} + }, ${branch}); + search.addFilter('Device', 'device', { + corpus: ${devices} + }, ${device}); + search.addFilter('Device Build ID', 'deviceBuildId', {}, ${deviceBuildId}); + search.addRunTypeCheckboxes(${showPresubmit}, ${showPostsubmit}); + search.display(); + $('#release-container').showPlanRuns(${planRuns}); + }); + + // view older data + function next() { + if($(this).hasClass('disabled')) return; + var endTime = ${startTime}; + var link = '${pageContext.request.contextPath}' + + '/show_plan_release?plan=${plan}&endTime=' + endTime + + search.args(); + if (${unfiltered}) { + link += '&unfiltered='; + } + window.open(link,'_self'); + } + + // view newer data + function prev() { + if($(this).hasClass('disabled')) return; + var startTime = ${endTime}; + var link = '${pageContext.request.contextPath}' + + '/show_plan_release?plan=${plan}&startTime=' + startTime + + search.args(); + if (${unfiltered}) { + link += '&unfiltered='; + } + window.open(link,'_self'); + } + + // refresh the page to see the runs matching the specified filter + function refresh() { + var link = '${pageContext.request.contextPath}' + + '/show_plan_release?plan=${plan}' + search.args(); + if (${unfiltered}) { + link += '&unfiltered='; + } + window.open(link,'_self'); + } + </script> + + <body> + <div class='wide container'> + <div id='filter-bar'></div> + <div class='row' id='release-container'></div> + <div id='newer-wrapper' class='page-button-wrapper fixed-action-btn'> + <a id='newer-button' class='btn-floating btn red waves-effect'> + <i class='large material-icons'>keyboard_arrow_left</i> + </a> + </div> + <div id='older-wrapper' class='page-button-wrapper fixed-action-btn'> + <a id='older-button' class='btn-floating btn red waves-effect'> + <i class='large material-icons'>keyboard_arrow_right</i> + </a> + </div> + </div> + <%@ include file="footer.jsp" %> + </body> +</html> diff --git a/src/main/webapp/WEB-INF/jsp/show_plan_run.jsp b/src/main/webapp/WEB-INF/jsp/show_plan_run.jsp new file mode 100644 index 0000000..491703a --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/show_plan_run.jsp @@ -0,0 +1,131 @@ +<%-- + ~ Copyright (c) 2017 Google Inc. All Rights Reserved. + ~ + ~ 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. + --%> +<%@ page contentType='text/html;charset=UTF-8' language='java' %> +<%@ taglib prefix='fn' uri='http://java.sun.com/jsp/jstl/functions' %> +<%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core'%> + +<html> + <%@ include file="header.jsp" %> + <link type='text/css' href='/css/show_test_runs_common.css' rel='stylesheet'> + <link type='text/css' href='/css/test_results.css' rel='stylesheet'> + <script type='text/javascript' src='https://www.gstatic.com/charts/loader.js'></script> + <script src='https://www.gstatic.com/external_hosted/moment/min/moment-with-locales.min.js'></script> + <script src='js/time.js'></script> + <script src='js/test_results.js'></script> + <script type='text/javascript'> + google.charts.load('current', {'packages':['table', 'corechart']}); + google.charts.setOnLoadCallback(drawPieChart); + + $(document).ready(function() { + $('#test-results-container').showTests(${testRuns}, true); + }); + + // to draw pie chart + function drawPieChart() { + var topBuildResultCounts = ${topBuildResultCounts}; + if (topBuildResultCounts.length < 1) { + return; + } + var resultNames = ${resultNamesJson}; + var rows = resultNames.map(function(res, i) { + nickname = res.replace('TEST_CASE_RESULT_', '').replace('_', ' ') + .trim().toLowerCase(); + return [nickname, parseInt(topBuildResultCounts[i])]; + }); + rows.unshift(['Result', 'Count']); + + // Get CSS color definitions (or default to white) + var colors = resultNames.map(function(res) { + return $('.' + res).css('background-color') || 'white'; + }); + + var data = google.visualization.arrayToDataTable(rows); + var options = { + is3D: false, + colors: colors, + fontName: 'Roboto', + fontSize: '14px', + legend: 'none', + tooltip: {showColorCode: true, ignoreBounds: true}, + chartArea: {height: '90%'} + }; + + var chart = new google.visualization.PieChart(document.getElementById('pie-chart-div')); + chart.draw(data, options); + } + </script> + + <body> + <div class='wide container'> + <div class='row'> + <div class='col s7'> + <div class='col s12 card center-align'> + <div id='legend-wrapper'> + <c:forEach items='${resultNames}' var='res'> + <div class='center-align legend-entry'> + <c:set var='trimmed' value='${fn:replace(res, "TEST_CASE_RESULT_", "")}'/> + <c:set var='nickname' value='${fn:replace(trimmed, "_", " ")}'/> + <label for='${res}'>${nickname}</label> + <div id='${res}' class='${res} legend-bubble'></div> + </div> + </c:forEach> + </div> + </div> + <div id='profiling-container' class='col s12'> + <c:choose> + <c:when test='${empty profilingPointNames}'> + <div id='error-div' class='center-align card'><h5>${error}</h5></div> + </c:when> + <c:otherwise> + <ul id='profiling-body' class='collapsible' data-collapsible='accordion'> + <li> + <div class='collapsible-header'><i class='material-icons'>timeline</i>Profiling Graphs</div> + <div class='collapsible-body'> + <ul id='profiling-list' class='collection'> + <c:forEach items='${profilingPointNames}' var='pt'> + <c:set var='profPointArgs' value='testName=${testName}&profilingPoint=${pt}'/> + <c:set var='timeArgs' value='endTime=${endTime}'/> + <a href='/show_graph?${profPointArgs}&${timeArgs}' + class='collection-item profiling-point-name'>${pt} + </a> + </c:forEach> + </ul> + </div> + </li> + <li> + <a class='collapsible-link' href='/show_performance_digest?testName=${testName}'> + <div class='collapsible-header'><i class='material-icons'>toc</i>Performance Digest</div> + </a> + </li> + </ul> + </c:otherwise> + </c:choose> + </div> + </div> + <div class='col s5 valign-wrapper'> + <!-- pie chart --> + <div id='pie-chart-wrapper' class='col s12 valign center-align card'> + <div id='pie-chart-div'></div> + </div> + </div> + </div> + + <div class='col s12' id='test-results-container'> + </div> + </div> + <%@ include file="footer.jsp" %> + </body> +</html> diff --git a/src/main/webapp/WEB-INF/jsp/show_release.jsp b/src/main/webapp/WEB-INF/jsp/show_release.jsp new file mode 100644 index 0000000..b3da353 --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/show_release.jsp @@ -0,0 +1,45 @@ +<%-- + ~ Copyright (c) 2017 Google Inc. All Rights Reserved. + ~ + ~ 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. + --%> +<%@ page contentType='text/html;charset=UTF-8' language='java' %> +<%@ taglib prefix='fn' uri='http://java.sun.com/jsp/jstl/functions' %> +<%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core'%> + +<html> + <link rel='stylesheet' href='/css/show_release.css'> + <%@ include file='header.jsp' %> + <script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.0/jquery-ui.min.js'></script> + <body> + <div class='container'> + <div class='row'> + <div class='col s12'> + <h4 id='section-header'>Test Plans</h4> + </div> + </div> + <div class='row' id='options'> + <c:forEach items='${planNames}' var='plan'> + <div> + <a href='/show_plan_release?plan=${plan}'> + <div class='col s12 card hoverable option valign-wrapper waves-effect'> + <span class='entry valign'>${plan}</span> + </div> + </a> + </div> + </c:forEach> + </div> + </div> + <%@ include file='footer.jsp' %> + </body> +</html> diff --git a/src/main/webapp/WEB-INF/jsp/show_table.jsp b/src/main/webapp/WEB-INF/jsp/show_table.jsp new file mode 100644 index 0000000..be71ee8 --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/show_table.jsp @@ -0,0 +1,340 @@ +<%-- + ~ Copyright (c) 2016 Google Inc. All Rights Reserved. + ~ + ~ 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. + --%> +<%@ page contentType='text/html;charset=UTF-8' language='java' %> +<%@ taglib prefix='fn' uri='http://java.sun.com/jsp/jstl/functions' %> +<%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core'%> + +<html> + <%@ include file="header.jsp" %> + <link type='text/css' href='/css/show_table.css' rel='stylesheet'> + <link type='text/css' href='/css/show_test_runs_common.css' rel='stylesheet'> + <link type='text/css' href='/css/search_header.css' rel='stylesheet'> + <script type='text/javascript' src='https://www.gstatic.com/charts/loader.js'></script> + <script src='https://www.gstatic.com/external_hosted/moment/min/moment-with-locales.min.js'></script> + <script src='js/search_header.js'></script> + <script type='text/javascript'> + google.charts.load('current', {'packages':['table', 'corechart']}); + google.charts.setOnLoadCallback(drawGridTable); + google.charts.setOnLoadCallback(activateLogLinks); + google.charts.setOnLoadCallback(drawPieChart); + google.charts.setOnLoadCallback(function() { + $('.gradient').removeClass('gradient'); + }); + + var search; + + $(document).ready(function() { + search = $('#filter-bar').createSearchHeader('Module: ', '${testName}', refresh); + search.addFilter('Branch', 'branch', { + corpus: ${branches} + }, ${branch}); + search.addFilter('Device', 'device', { + corpus: ${devices} + }, ${device}); + search.addFilter('Device Build ID', 'deviceBuildId', {}, ${deviceBuildId}); + search.addFilter('Test Build ID', 'testBuildId', {}, ${testBuildId}); + search.addFilter('Host', 'hostname', {}, ${hostname}); + search.addFilter('Passing Count', 'passing', { + type: 'number', + width: 's2' + }, ${passing}); + search.addFilter('Non-Passing Count', 'nonpassing', { + type: 'number', + width: 's2' + }, ${nonpassing}); + search.addRunTypeCheckboxes(${showPresubmit}, ${showPostsubmit}); + search.display(); + + // disable buttons on load + if (!${hasNewer}) { + $('#newer-button').toggleClass('disabled'); + } + if (!${hasOlder}) { + $('#older-button').toggleClass('disabled'); + } + $('#treeLink').click(function() { + window.open('/show_tree?testName=${testName}', '_self'); + }); + $('#newer-button').click(prev); + $('#older-button').click(next); + }); + + // Actives the log links to display the log info modal when clicked. + function activateLogLinks() { + $('.info-btn').click(function(e) { + showLog(${logInfoMap}[$(this).data('col')]); + }); + } + + /** Displays a modal window with the specified log entries. + * + * @param logEntries Array of string arrays. Each entry in the outer array + * must contain (1) name string, and (2) url string. + */ + function showLog(logEntries) { + if (!logEntries || logEntries.length == 0) return; + + var logList = $('<ul class="collection"></ul>'); + var entries = logEntries.reduce(function(acc, entry) { + if (!entry || entry.length == 0) return acc; + var link = '<a href="' + entry[1] + '"'; + link += 'class="collection-item">' + entry[0] + '</li>'; + return acc + link; + }, ''); + logList.html(entries); + var infoContainer = $('#info-modal>.modal-content>.info-container'); + infoContainer.empty(); + logList.appendTo(infoContainer); + $('#info-modal').openModal(); + } + + // refresh the page to see the selected test types (pre-/post-submit) + function refresh() { + if($(this).hasClass('disabled')) return; + var link = '${pageContext.request.contextPath}' + + '/show_table?testName=${testName}' + search.args(); + if (${unfiltered}) { + link += '&unfiltered='; + } + window.open(link,'_self'); + } + + // view older data + function next() { + if($(this).hasClass('disabled')) return; + var endTime = ${startTime}; + var link = '${pageContext.request.contextPath}' + + '/show_table?testName=${testName}&endTime=' + endTime + + search.args(); + if (${unfiltered}) { + link += '&unfiltered='; + } + window.open(link,'_self'); + } + + // view newer data + function prev() { + if($(this).hasClass('disabled')) return; + var startTime = ${endTime}; + var link = '${pageContext.request.contextPath}' + + '/show_table?testName=${testName}&startTime=' + startTime + + search.args(); + if (${unfiltered}) { + link += '&unfiltered='; + } + window.open(link,'_self'); + } + + // to draw pie chart + function drawPieChart() { + var topBuildResultCounts = ${topBuildResultCounts}; + if (topBuildResultCounts.length < 1) { + return; + } + var resultNames = ${resultNamesJson}; + var rows = resultNames.map(function(res, i) { + nickname = res.replace('TEST_CASE_RESULT_', '').replace('_', ' ') + .trim().toLowerCase(); + return [nickname, parseInt(topBuildResultCounts[i])]; + }); + rows.unshift(['Result', 'Count']); + + // Get CSS color definitions (or default to white) + var colors = resultNames.map(function(res) { + return $('.' + res).css('background-color') || 'white'; + }); + + var data = google.visualization.arrayToDataTable(rows); + var options = { + is3D: false, + colors: colors, + fontName: 'Roboto', + fontSize: '14px', + legend: 'none', + tooltip: {showColorCode: true, ignoreBounds: true}, + chartArea: {height: '90%'} + }; + + var chart = new google.visualization.PieChart(document.getElementById('pie-chart-div')); + chart.draw(data, options); + } + + // table for grid data + function drawGridTable() { + var data = new google.visualization.DataTable(); + + // Add column headers. + headerRow = ${headerRow}; + headerRow.forEach(function(d, i) { + var classNames = 'table-header-content'; + if (i == 0) classNames += ' table-header-legend'; + data.addColumn('string', '<span class="' + classNames + '">' + + d + '</span>'); + }); + + var timeGrid = ${timeGrid}; + var durationGrid = ${durationGrid}; + var summaryGrid = ${summaryGrid}; + var resultsGrid = ${resultsGrid}; + + // Format time grid to a formatted date + timeGrid = timeGrid.map(function(row) { + return row.map(function(cell, j) { + if (j == 0) return cell; + var time = moment(cell/1000); + // If today, don't display the date + if (time.isSame(moment(), 'd')) { + return time.format('H:mm:ssZZ'); + } else { + return time.format('M/D/YY H:mm:ssZZ'); + } + }); + }); + + // Format duration grid to HH:mm:ss.SSS + durationGrid = durationGrid.map(function(row) { + return row.map(function(cell, j) { + if (j == 0) return cell; + return moment.utc(cell/1000).format("HH:mm:ss.SSS"); + }); + }); + + // add rows to the data. + data.addRows(timeGrid); + data.addRows(durationGrid); + data.addRows(summaryGrid); + data.addRows(resultsGrid); + + var table = new google.visualization.Table(document.getElementById('grid-table-div')); + var classNames = { + headerRow : 'table-header', + headerCell : 'table-header-cell' + }; + var options = { + showRowNumber: false, + alternatingRowStyle: true, + allowHtml: true, + frozenColumns: 1, + cssClassNames: classNames, + sort: 'disable' + }; + table.draw(data, options); + } + </script> + + <body> + <div class='wide container'> + <div class='row'> + <div class='col s12'> + <div class='card'> + <ul class='tabs'> + <li class='tab col s6'><a class='active'>Table</a></li> + <li class='tab col s6' id='treeLink'><a>Tree</a></li> + </ul> + </div> + <div id='filter-bar'></div> + </div> + <div class='col s7'> + <div class='col s12 card center-align'> + <div id='legend-wrapper'> + <c:forEach items='${resultNames}' var='res'> + <div class='center-align legend-entry'> + <c:set var='trimmed' value='${fn:replace(res, "TEST_CASE_RESULT_", "")}'/> + <c:set var='nickname' value='${fn:replace(trimmed, "_", " ")}'/> + <label for='${res}'>${nickname}</label> + <div id='${res}' class='${res} legend-bubble'></div> + </div> + </c:forEach> + </div> + </div> + <div id='profiling-container' class='col s12'> + <c:choose> + <c:when test='${empty profilingPointNames}'> + <div id='error-div' class='center-align card'><h5>${error}</h5></div> + </c:when> + <c:otherwise> + <ul id='profiling-body' class='collapsible' data-collapsible='accordion'> + <li> + <div class='collapsible-header'><i class='material-icons'>timeline</i>Profiling Graphs</div> + <div class='collapsible-body'> + <ul id='profiling-list' class='collection'> + <c:forEach items='${profilingPointNames}' var='pt'> + <c:set var='profPointArgs' value='testName=${testName}&profilingPoint=${pt}'/> + <c:set var='timeArgs' value='endTime=${endTime}'/> + <a href='/show_graph?${profPointArgs}&${timeArgs}' + class='collection-item profiling-point-name'>${pt} + </a> + </c:forEach> + </ul> + </div> + </li> + <li> + <a class='collapsible-link' href='/show_performance_digest?testName=${testName}'> + <div class='collapsible-header'><i class='material-icons'>toc</i>Performance Digest</div> + </a> + </li> + </ul> + </c:otherwise> + </c:choose> + </div> + </div> + <div class='col s5 valign-wrapper'> + <!-- pie chart --> + <div id='pie-chart-wrapper' class='col s12 valign center-align card'> + <h6 class='pie-chart-title'>Test Status for Device Build ID: ${topBuildId}</h6> + <div id='pie-chart-div'></div> + </div> + </div> + </div> + + <div class='col s12'> + <div id='chart-holder' class='col s12 card'> + <!-- Grid tables--> + <div id='grid-table-div'></div> + </div> + </div> + <div id='newer-wrapper' class='page-button-wrapper fixed-action-btn'> + <a id='newer-button' class='btn-floating btn red waves-effect'> + <i class='large material-icons'>keyboard_arrow_left</i> + </a> + </div> + <div id='older-wrapper' class='page-button-wrapper fixed-action-btn'> + <a id='older-button' class='btn-floating btn red waves-effect'> + <i class='large material-icons'>keyboard_arrow_right</i> + </a> + </div> + </div> + <div id="help-modal" class="modal"> + <div class="modal-content"> + <h4>${searchHelpHeader}</h4> + <p>${searchHelpBody}</p> + </div> + <div class="modal-footer"> + <a href="#!" class="modal-action modal-close waves-effect btn-flat">Close</a> + </div> + </div> + <div id="info-modal" class="modal"> + <div class="modal-content"> + <h4>Logs</h4> + <div class="info-container"></div> + </div> + <div class="modal-footer"> + <a href="#!" class="modal-action modal-close waves-effect btn-flat">Close</a> + </div> + </div> + <%@ include file="footer.jsp" %> + </body> +</html> diff --git a/src/main/webapp/WEB-INF/jsp/show_tree.jsp b/src/main/webapp/WEB-INF/jsp/show_tree.jsp new file mode 100644 index 0000000..8d237a3 --- /dev/null +++ b/src/main/webapp/WEB-INF/jsp/show_tree.jsp @@ -0,0 +1,225 @@ +<%-- + ~ Copyright (c) 2016 Google Inc. All Rights Reserved. + ~ + ~ 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. + --%> +<%@ page contentType='text/html;charset=UTF-8' language='java' %> +<%@ taglib prefix='fn' uri='http://java.sun.com/jsp/jstl/functions' %> +<%@ taglib prefix='c' uri='http://java.sun.com/jsp/jstl/core'%> + +<html> + <%@ include file="header.jsp" %> + <link type='text/css' href='/css/show_test_runs_common.css' rel='stylesheet'> + <link type='text/css' href='/css/test_results.css' rel='stylesheet'> + <link rel='stylesheet' href='/css/search_header.css'> + <script type='text/javascript' src='https://www.gstatic.com/charts/loader.js'></script> + <script src='https://www.gstatic.com/external_hosted/moment/min/moment-with-locales.min.js'></script> + <script src='js/search_header.js'></script> + <script src='js/time.js'></script> + <script src='js/test_results.js'></script> + <script type='text/javascript'> + google.charts.load('current', {'packages':['table', 'corechart']}); + google.charts.setOnLoadCallback(drawPieChart); + + var search; + + $(document).ready(function() { + search = $('#filter-bar').createSearchHeader('Module: ', '${testName}', refresh); + search.addFilter('Branch', 'branch', { + corpus: ${branches} + }, ${branch}); + search.addFilter('Device', 'device', { + corpus: ${devices} + }, ${device}); + search.addFilter('Device Build ID', 'deviceBuildId', {}, ${deviceBuildId}); + search.addFilter('Test Build ID', 'testBuildId', {}, ${testBuildId}); + search.addFilter('Host', 'hostname', {}, ${hostname}); + search.addFilter('Passing Count', 'passing', { + type: 'number', + width: 's2' + }, ${passing}); + search.addFilter('Non-Passing Count', 'nonpassing', { + type: 'number', + width: 's2' + }, ${nonpassing}); + search.addRunTypeCheckboxes(${showPresubmit}, ${showPostsubmit}); + search.display(); + + // disable buttons on load + if (!${hasNewer}) { + $('#newer-button').toggleClass('disabled'); + } + if (!${hasOlder}) { + $('#older-button').toggleClass('disabled'); + } + $('#tableLink').click(function() { + window.open('/show_table?testName=${testName}', '_self'); + }); + $('#newer-button').click(prev); + $('#older-button').click(next); + $('#test-results-container').showTests(${testRuns}); + }); + + // refresh the page to see the selected test types (pre-/post-submit) + function refresh() { + if($(this).hasClass('disabled')) return; + var link = '${pageContext.request.contextPath}' + + '/show_tree?testName=${testName}' + search.args(); + if (${unfiltered}) { + link += '&unfiltered='; + } + window.open(link,'_self'); + } + + // view older data + function next() { + if($(this).hasClass('disabled')) return; + var endTime = ${startTime}; + var link = '${pageContext.request.contextPath}' + + '/show_tree?testName=${testName}&endTime=' + endTime + + search.args(); + if (${unfiltered}) { + link += '&unfiltered='; + } + window.open(link,'_self'); + } + + // view newer data + function prev() { + if($(this).hasClass('disabled')) return; + var startTime = ${endTime}; + var link = '${pageContext.request.contextPath}' + + '/show_tree?testName=${testName}&startTime=' + startTime + + search.args(); + if (${unfiltered}) { + link += '&unfiltered='; + } + window.open(link,'_self'); + } + + // to draw pie chart + function drawPieChart() { + var topBuildResultCounts = ${topBuildResultCounts}; + if (topBuildResultCounts.length < 1) { + return; + } + var resultNames = ${resultNamesJson}; + var rows = resultNames.map(function(res, i) { + nickname = res.replace('TEST_CASE_RESULT_', '').replace('_', ' ') + .trim().toLowerCase(); + return [nickname, parseInt(topBuildResultCounts[i])]; + }); + rows.unshift(['Result', 'Count']); + + // Get CSS color definitions (or default to white) + var colors = resultNames.map(function(res) { + return $('.' + res).css('background-color') || 'white'; + }); + + var data = google.visualization.arrayToDataTable(rows); + var options = { + is3D: false, + colors: colors, + fontName: 'Roboto', + fontSize: '14px', + legend: 'none', + tooltip: {showColorCode: true, ignoreBounds: true}, + chartArea: {height: '90%'} + }; + + var chart = new google.visualization.PieChart(document.getElementById('pie-chart-div')); + chart.draw(data, options); + } + </script> + + <body> + <div class='wide container'> + <div class='row'> + <div class='col s12'> + <div class='card'> + <ul class='tabs'> + <li class='tab col s6' id='tableLink'><a>Table</a></li> + <li class='tab col s6'><a class='active'>Tree</a></li> + </ul> + </div> + <div id='filter-bar'></div> + </div> + <div class='col s7'> + <div class='col s12 card center-align'> + <div id='legend-wrapper'> + <c:forEach items='${resultNames}' var='res'> + <div class='center-align legend-entry'> + <c:set var='trimmed' value='${fn:replace(res, "TEST_CASE_RESULT_", "")}'/> + <c:set var='nickname' value='${fn:replace(trimmed, "_", " ")}'/> + <label for='${res}'>${nickname}</label> + <div id='${res}' class='${res} legend-bubble'></div> + </div> + </c:forEach> + </div> + </div> + <div id='profiling-container' class='col s12'> + <c:choose> + <c:when test='${empty profilingPointNames}'> + <div id='error-div' class='center-align card'><h5>${error}</h5></div> + </c:when> + <c:otherwise> + <ul id='profiling-body' class='collapsible' data-collapsible='accordion'> + <li> + <div class='collapsible-header'><i class='material-icons'>timeline</i>Profiling Graphs</div> + <div class='collapsible-body'> + <ul id='profiling-list' class='collection'> + <c:forEach items='${profilingPointNames}' var='pt'> + <c:set var='profPointArgs' value='testName=${testName}&profilingPoint=${pt}'/> + <c:set var='timeArgs' value='endTime=${endTime}'/> + <a href='/show_graph?${profPointArgs}&${timeArgs}' + class='collection-item profiling-point-name'>${pt} + </a> + </c:forEach> + </ul> + </div> + </li> + <li> + <a class='collapsible-link' href='/show_performance_digest?testName=${testName}'> + <div class='collapsible-header'><i class='material-icons'>toc</i>Performance Digest</div> + </a> + </li> + </ul> + </c:otherwise> + </c:choose> + </div> + </div> + <div class='col s5 valign-wrapper'> + <!-- pie chart --> + <div id='pie-chart-wrapper' class='col s12 valign center-align card'> + <h6 class='pie-chart-title'>${topBuildId}</h6> + <div id='pie-chart-div'></div> + </div> + </div> + </div> + + <div class='col s12' id='test-results-container'> + </div> + <div id='newer-wrapper' class='page-button-wrapper fixed-action-btn'> + <a id='newer-button' class='btn-floating btn red waves-effect'> + <i class='large material-icons'>keyboard_arrow_left</i> + </a> + </div> + <div id='older-wrapper' class='page-button-wrapper fixed-action-btn'> + <a id='older-button' class='btn-floating btn red waves-effect'> + <i class='large material-icons'>keyboard_arrow_right</i> + </a> + </div> + </div> + <%@ include file="footer.jsp" %> + </body> +</html> diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..e5ed62c --- /dev/null +++ b/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,197 @@ +<web-app xmlns="http://java.sun.com/xml/ns/javaee" version="2.5"> +<!-- +Copyright 2016 Google Inc. All Rights Reserved. + + 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. +--> + +<servlet> + <servlet-name>dashboard_main</servlet-name> + <servlet-class>com.android.vts.servlet.DashboardMainServlet</servlet-class> +</servlet> + +<servlet> + <servlet-name>show_release</servlet-name> + <servlet-class>com.android.vts.servlet.ShowReleaseServlet</servlet-class> +</servlet> + +<servlet> + <servlet-name>show_coverage_overview</servlet-name> + <servlet-class>com.android.vts.servlet.ShowCoverageOverviewServlet</servlet-class> +</servlet> + +<servlet> + <servlet-name>show_tree</servlet-name> + <servlet-class>com.android.vts.servlet.ShowTreeServlet</servlet-class> +</servlet> + +<servlet> + <servlet-name>show_table</servlet-name> + <servlet-class>com.android.vts.servlet.ShowTableServlet</servlet-class> +</servlet> + +<servlet> + <servlet-name>show_graph</servlet-name> + <servlet-class>com.android.vts.servlet.ShowGraphServlet</servlet-class> +</servlet> + +<servlet> + <servlet-name>show_plan_release</servlet-name> + <servlet-class>com.android.vts.servlet.ShowPlanReleaseServlet</servlet-class> +</servlet> + +<servlet> + <servlet-name>show_plan_run</servlet-name> + <servlet-class>com.android.vts.servlet.ShowPlanRunServlet</servlet-class> +</servlet> + +<servlet> + <servlet-name>show_performance_digest</servlet-name> + <servlet-class>com.android.vts.servlet.ShowPerformanceDigestServlet</servlet-class> +</servlet> + +<servlet> + <servlet-name>show_coverage</servlet-name> + <servlet-class>com.android.vts.servlet.ShowCoverageServlet</servlet-class> +</servlet> + +<servlet> + <servlet-name>datastore</servlet-name> + <servlet-class>com.android.vts.api.DatastoreRestServlet</servlet-class> +</servlet> + +<servlet> + <servlet-name>test_run</servlet-name> + <servlet-class>com.android.vts.api.TestRunRestServlet</servlet-class> +</servlet> + +<servlet> + <servlet-name>favorites</servlet-name> + <servlet-class>com.android.vts.api.UserFavoriteRestServlet</servlet-class> +</servlet> + +<servlet> + <servlet-name>bigtable_legacy</servlet-name> + <servlet-class>com.android.vts.api.BigtableLegacyJsonServlet</servlet-class> +</servlet> + +<servlet> + <servlet-name>vts_alert_job</servlet-name> + <servlet-class>com.android.vts.servlet.VtsAlertJobServlet</servlet-class> +</servlet> + +<servlet> + <servlet-name>vts_performance_job</servlet-name> + <servlet-class>com.android.vts.servlet.VtsPerformanceJobServlet</servlet-class> +</servlet> + +<servlet-mapping> + <servlet-name>dashboard_main</servlet-name> + <url-pattern>/</url-pattern> +</servlet-mapping> + +<servlet-mapping> + <servlet-name>show_release</servlet-name> + <url-pattern>/show_release/*</url-pattern> +</servlet-mapping> + +<servlet-mapping> + <servlet-name>show_coverage_overview</servlet-name> + <url-pattern>/show_coverage_overview/*</url-pattern> +</servlet-mapping> + +<servlet-mapping> + <servlet-name>show_tree</servlet-name> + <url-pattern>/show_tree/*</url-pattern> +</servlet-mapping> + +<servlet-mapping> + <servlet-name>show_table</servlet-name> + <url-pattern>/show_table/*</url-pattern> +</servlet-mapping> + +<servlet-mapping> + <servlet-name>show_graph</servlet-name> + <url-pattern>/show_graph/*</url-pattern> +</servlet-mapping> + +<servlet-mapping> + <servlet-name>show_plan_release</servlet-name> + <url-pattern>/show_plan_release/*</url-pattern> +</servlet-mapping> + +<servlet-mapping> + <servlet-name>show_plan_run</servlet-name> + <url-pattern>/show_plan_run/*</url-pattern> +</servlet-mapping> + +<servlet-mapping> + <servlet-name>show_performance_digest</servlet-name> + <url-pattern>/show_performance_digest/*</url-pattern> +</servlet-mapping> + +<servlet-mapping> + <servlet-name>show_coverage</servlet-name> + <url-pattern>/show_coverage/*</url-pattern> +</servlet-mapping> + +<servlet-mapping> + <servlet-name>bigtable_legacy</servlet-name> + <url-pattern>/api/bigtable/*</url-pattern> +</servlet-mapping> + +<servlet-mapping> + <servlet-name>datastore</servlet-name> + <url-pattern>/api/datastore/*</url-pattern> +</servlet-mapping> + +<servlet-mapping> + <servlet-name>test_run</servlet-name> + <url-pattern>/api/test_run/*</url-pattern> +</servlet-mapping> + +<servlet-mapping> + <servlet-name>favorites</servlet-name> + <url-pattern>/api/favorites/*</url-pattern> +</servlet-mapping> + +<servlet-mapping> + <servlet-name>vts_alert_job</servlet-name> + <url-pattern>/cron/vts_alert_job/*</url-pattern> +</servlet-mapping> + +<servlet-mapping> + <servlet-name>vts_performance_job</servlet-name> + <url-pattern>/cron/vts_performance_job/*</url-pattern> +</servlet-mapping> + +<security-constraint> + <web-resource-collection> + <web-resource-name>cron</web-resource-name> + <url-pattern>/cron/*</url-pattern> + </web-resource-collection> + <auth-constraint> + <role-name>admin</role-name> + </auth-constraint> +</security-constraint> + +<security-constraint> + <web-resource-collection> + <web-resource-name>all</web-resource-name> + <url-pattern>/show_*</url-pattern> + </web-resource-collection> + <auth-constraint> + <role-name>*</role-name> + </auth-constraint> +</security-constraint> +</web-app> diff --git a/src/main/webapp/css/common.css b/src/main/webapp/css/common.css new file mode 100644 index 0000000..974f129 --- /dev/null +++ b/src/main/webapp/css/common.css @@ -0,0 +1,25 @@ +/* Copyright (C) 2017 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. +*/ + +.container { + min-height: 80%; +} + +@media only screen and (min-width: 993px) { + .wide.container { + width: 80%; + max-width: 1600px; + } +} diff --git a/src/main/webapp/css/dashboard_main.css b/src/main/webapp/css/dashboard_main.css new file mode 100644 index 0000000..e6e899f --- /dev/null +++ b/src/main/webapp/css/dashboard_main.css @@ -0,0 +1,109 @@ +/* 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. +*/ + +#edit-button-wrapper { + bottom: 25px; + right: 25px; +} + +.input-field { + margin-bottom: 50px; +} + +#add-button-wrapper { + margin-top: 10px; + height: 61px; +} + +.btn-flat.clear-button { + margin-top: 8px; + user-select: none; + color: grey; +} + +.row .col.card.option { + padding: 6px 15px 6px 15px; + margin: 5px 0; + border-radius: 25px; +} + +#error-container { + padding-top: 50px; + padding-bottom: 50px; +} + +.entry { + font-size: 20px; + font-weight: 300; + position: relative; +} + +.indicator { + color: white; + font-size: 12px; + font-weight: bold; + padding: 1px 6px; + position: absolute; + right: 0; + min-width: 40px; + border-radius: 10px; + margin-top: 5px; +} + +#show-button { + border-radius: 100px; +} + +#show-button-arrow { + margin-left: 3px; +} + +#section-header { + cursor: default; + user-select: none; + color: #ee6e73; +} + +#section-header:after { + border: 1px solid #ee6e73; + margin-top: 10px; + margin-bottom: 0; + display: block; + content: " "; +} + +.ui-menu { + overflow-y: auto; + z-index: 100; + max-height: 50%; +} + +.ui-menu-item { + font-size: 16px; + padding: 4px 10px; + transition: background-color .25s; +} + +.ui-menu-item:hover { + background-color: #e0f2f1; +} + +.ui-menu-item:active { + background-color: #b2dfdb; +} + +.ui-helper-hidden-accessible { + display: none; +} diff --git a/src/main/webapp/css/datepicker.css b/src/main/webapp/css/datepicker.css new file mode 100644 index 0000000..b98dd80 --- /dev/null +++ b/src/main/webapp/css/datepicker.css @@ -0,0 +1,70 @@ +/* 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. +*/ +.ui-datepicker table { + font-family: Roboto !important; + font-size: 13px !important; + white-space: nowrap !important; +} + +#ui-datepicker-div { + font-family: "Roboto", sans-serif; + padding: 0; +} + +.ui-corner-all { + border-bottom-right-radius: 0 !important; + border-bottom-left-radius: 0 !important; + border-top-right-radius: 0 !important; + border-top-left-radius: 0 !important; +} + +.ui-datepicker td span.ui-state-default, .ui-datepicker td a.ui-state-default { + text-align: center; + padding: 0.7em 0.4em; + border: none; + border-radius: 10em; + background: none; +} + +.ui-datepicker td span.ui-state-hover, .ui-datepicker td a.ui-state-hover { + background: #e0f2f1; +} + +.ui-datepicker td span.ui-state-active, .ui-datepicker td a.ui-state-active { + color: white; + font-weight: 600; + background: #009688; +} + +.ui-datepicker-header.ui-widget-header.ui-helper-clearfix.ui-corner-all { + background: #009688; + border: none; + color: white; +} + +.ui-datepicker-next.ui-state-hover.ui-datepicker-next-hover { + right: 2px; + top: 2px; +} + +.ui-datepicker-prev.ui-state-hover.ui-datepicker-prev-hover { + left: 2px; + top: 2px; +} + +.ui-datepicker-next.ui-corner-all.ui-state-hover, .ui-datepicker-prev.ui-corner-all.ui-state-hover { + background: none; + border: none; +} diff --git a/src/main/webapp/css/navbar.css b/src/main/webapp/css/navbar.css new file mode 100644 index 0000000..9395d1b --- /dev/null +++ b/src/main/webapp/css/navbar.css @@ -0,0 +1,69 @@ +/* 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. +*/ +nav#navbar { + height: auto; + margin-bottom: 30px; + user-select: none; +} +nav#navbar .nav-wrapper { + height: auto; +} +nav#navbar ul.nav-list { + display: inline-block; +} +nav#navbar ul li { + transition: background-color .3s; + float: left; + padding: 0; +} +nav#navbar ul li.active { + background-color: rgba(0,0,0,0.1); +} +nav#navbar ul li a:hover, nav#navbar ul li.active { + background-color: #ea454b; +} +nav#navbar ul a.nav-list-item { + font-size: 1.2rem; +} +nav#navbar #nav-sublist { + line-height: 35px; + background: white; + padding-left: 15px; + width: 100%; + display: inline-block; + position: relative; +} +nav#navbar #nav-sublist .breadcrumb.nav-sublist-item { + font-size: 15px; + font-weight: 400; + color: rgba(238, 110, 115, 0.85); + line-height: 35px; +} +nav#navbar #nav-sublist .breadcrumb.nav-sublist-item:last-child { + color: rgb(238, 110, 115); + font-weight: 500; +} +nav#navbar #nav-sublist .breadcrumb.nav-sublist-item::before { + font-size: 22px; + color: rgba(238, 110, 115, 0.85); + line-height: 35px; + margin: 0 5px; +} +nav#navbar #dropdown-button { + font-style: italic; + color: rgba(255, 255, 255, 0.75); + margin-left: 0; + margin-top: 0; +} diff --git a/src/main/webapp/css/plan_runs.css b/src/main/webapp/css/plan_runs.css new file mode 100644 index 0000000..3c9eeb9 --- /dev/null +++ b/src/main/webapp/css/plan_runs.css @@ -0,0 +1,30 @@ +/* Copyright (C) 2017 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. +*/ +.plan-run-metadata { + display: inline-block; + font-size: 13px; + line-height: 16px; + padding: 10px; +} +.release-entry { + border-radius: 5px 5px 10px 10px; +} +.counter { + color: white; + font-size: 12px; + font-weight: bold; + display: block; + border-radius: 0 0 10px 10px; +}
\ No newline at end of file diff --git a/src/main/webapp/css/search_header.css b/src/main/webapp/css/search_header.css new file mode 100644 index 0000000..90573e1 --- /dev/null +++ b/src/main/webapp/css/search_header.css @@ -0,0 +1,80 @@ +/* Copyright (C) 2017 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. +*/ +.row.card.search-bar { + margin-left: 0; + margin-right: 0; +} +.search-bar .header-wrapper { + border-bottom: 1px solid rgb(221, 221, 221);; +} +.search-bar .section-header { + color: rgb(97, 97, 97); + font-weight: 300; + padding: 15px 20px 15px; + margin: 0; + cursor: default; + user-select: none; + display: inline-block; +} +.search-bar .section-header b { + color: #ee6e73; +} +.search-bar .search-icon-wrapper { + text-align: center; + display: inline-block; + position: absolute; + right: 0; + height: 57px; + width: 57px; + cursor: pointer; + user-select: none; +} +.search-bar .search-icon-wrapper i { + line-height: 57px; + color: rgb(97, 97, 97); +} +.search-bar .search-wrapper .refresh-wrapper a { + float: right; + margin-top: 17px; +} +.search-bar .input-field input[type=text].invalid { + color: #F44336; +} +.search-bar .search-wrapper .run-type-wrapper { + margin: 20px 0; +} +.search-bar .search-wrapper .run-type-wrapper [type="checkbox"]+label { + margin-right: 35px; +} +.search-bar-menu .ui-menu { + overflow-y: auto; + z-index: 100; + max-height: 50%; +} +.search-bar-menu .ui-menu-item { + font-size: 16px; + padding: 4px 10px; + transition: background-color .25s; +} +.search-bar-menu .ui-menu-item:hover { + background-color: #e0f2f1; +} + +.search-bar-menu .ui-menu-item:active { + background-color: #b2dfdb; +} +.search-bar-menu .ui-helper-hidden-accessible { + display: none; +} diff --git a/src/main/webapp/css/show_coverage.css b/src/main/webapp/css/show_coverage.css new file mode 100644 index 0000000..c187fd3 --- /dev/null +++ b/src/main/webapp/css/show_coverage.css @@ -0,0 +1,104 @@ +/* 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. +*/ + +.collapsible.popout { + margin-bottom: 50px; +} + +.table { + font-size: 12px; + border: none; + width: 100%; + word-spacing: 4px; + font-family: monospace; + white-space: PRE; + border-collapse: collapse; +} + +.section-title { + margin-left: 24px; +} + +.html-container { + padding: 25px 25px; +} + +.login-button { + border: 1px solid gray; + color: gray; + border-radius: 15px; + padding: 4px 15px; + cursor: pointer; +} + +td { + padding: 0; +} + +.count { + white-space: nowrap; + text-align: right; + border-right: 1px solid black; + padding-right: 5px; +} + +.line_no { + padding-left: 35px; + white-space: nowrap; + padding-right: 5px; + border-right: 1px dotted gray; +} + +.code { + padding-left: 10px; + width: 99%; +} + +.indicator { + display: inline-block; + width: 50px; + margin-top: 12px; + line-height: 18px; + border-radius: 10px; + padding: 2px 5px; + text-align: center; + font-size: 12px; + font-weight: bold; + color: white; +} + +.total-count { + margin-top: 12px; + margin-right: 8px; + padding-right: 5px; + line-height: 22px; + border-right: 1px solid gray; + font-size: 12px; + font-weight: bold; + color: gray; +} + +.uncovered { + background-color: LightPink; +} + +.covered { + background-color: LightGreen; +} + +.source-name { + margin-top: -25px; + padding-left: 45px; +} diff --git a/src/main/webapp/css/show_graph.css b/src/main/webapp/css/show_graph.css new file mode 100644 index 0000000..51e4c04 --- /dev/null +++ b/src/main/webapp/css/show_graph.css @@ -0,0 +1,70 @@ +/* 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. +*/ + +#download { + bottom: 25px; + right: 25px; +} + +#header-container { + padding: 50px; + padding-bottom: 30px; +} + +#device-select-wrapper { + margin-top: 0; +} + +#date-container { + padding: 0 50px; + padding-bottom: 25px; +} + +#load { + margin-top: 5px; +} + +.profiling-name { + font-weight: 200; + font-style: italic; + font-size: 1.4rem +} + +#error-container { + padding-top: 25px; + padding-bottom: 25px; +} + +.graph-wrapper { + padding: 30px; +} + +.graph { + height: 500px; + padding-bottom: 30px; +} + +.percentile-table { + width: auto; + margin: auto; + margin-top: 20px; +} + +.percentile-table td, th{ + font-size: 11px; + text-align: center; + padding: 5px 10px; +} + diff --git a/src/main/webapp/css/show_performance_digest.css b/src/main/webapp/css/show_performance_digest.css new file mode 100644 index 0000000..5d0c0e6 --- /dev/null +++ b/src/main/webapp/css/show_performance_digest.css @@ -0,0 +1,82 @@ +/* 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. +*/ + +#header-container { + padding: 25px; +} + +#load { + margin-top: 15px; +} + +#device-select-wrapper { + margin-top: 9px; +} + +#date { + margin-bottom: 0; + margin-top: 10px; +} + +div.col.card.summary { + padding: 0 20px 20px; +} + +.profiling-name { + font-weight: 200; + font-style: italic; + font-size: 1.4rem +} + +.profiling-subtitle { + font-style: italic; + font-size: 12px; + margin-left: 2px; +} + +.summary table { + width: 100%; + border-collapse: collapse; + border: 1px solid black; + font-size: 12px; + font-family: Roboto !important; +} + +.summary table td, th { + padding: 2px; +} + +.section-label { + border: 1px solid black; +} + +.axis-label { + border-top: 1px solid lightgray; + border-right: 1px solid black; + text-align: right; +} + +.cell { + border-top: 1px solid lightgray; + text-align: right; +} + +.inner-cell { + border-right: 1px solid lightgray; +} + +.outer-cell { + border-right: 1px solid black; +} diff --git a/src/main/webapp/css/show_plan_release.css b/src/main/webapp/css/show_plan_release.css new file mode 100644 index 0000000..f55b8da --- /dev/null +++ b/src/main/webapp/css/show_plan_release.css @@ -0,0 +1,23 @@ +/* Copyright (C) 2017 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. +*/ +.page-button-wrapper { + top: 50%; + bottom: auto; + padding: 0; +} +#newer-wrapper { + left: 23px; + right: auto; +} diff --git a/src/main/webapp/css/show_release.css b/src/main/webapp/css/show_release.css new file mode 100644 index 0000000..1f1758b --- /dev/null +++ b/src/main/webapp/css/show_release.css @@ -0,0 +1,40 @@ +/* Copyright (C) 2017 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. +*/ + +.row .col.card.option { + padding: 10px 15px 10px 25px; + margin: 5px 0; + border-radius: 25px; +} +.entry { + font-size: 20px; + font-weight: 300; + position: relative; +} +#show-button-arrow { + margin-left: 3px; +} +#section-header { + cursor: default; + user-select: none; + color: #ee6e73; +} +#section-header:after { + border: 1px solid #ee6e73; + margin-top: 10px; + margin-bottom: 0; + display: block; + content: " "; +} diff --git a/src/main/webapp/css/show_table.css b/src/main/webapp/css/show_table.css new file mode 100644 index 0000000..76d4379 --- /dev/null +++ b/src/main/webapp/css/show_table.css @@ -0,0 +1,156 @@ +/* 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. +*/ + +table { + font-family: Roboto !important; + font-size: 13px !important; + white-space: nowrap !important; +} +.table-header-cell { + background-color: white; + transition: max-width 1s; + max-width: 150px; +} +.table-header-cell:hover { + transition-delay: 0.5s; + max-width: 1000px; +} +.table-header-content.table-header-legend { + max-width: none; +} +.table-header-content { + font-weight: initial; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + display: inline-block; + max-width: inherit; + width: 100%; +} +.page-button-wrapper { + top: 50%; + bottom: auto; + padding: 0; +} +#newer-wrapper { + left: 23px; + right: auto; +} +#chart-holder { + padding: 30px 5px; +} +#pie-chart-div { + width: 100%; + height: 300px; +} +#profiling-container { + padding: 0; +} +#error-div { + padding: 30px 25px; +} +#profiling-body { + border: none; +} +#profiling-list { + max-height: 200px; + overflow-y: scroll; +} +.collapsible-header { + user-select: none; +} +.collapsible-link { + color: inherit; +} +.collection a.collection-item.profiling-point-name { + color: #616161; + font-size: 13px; + padding: 2px 0 2px 25px; +} +#legend-wrapper { + display: inline-block; + padding: 10px 15px 12px; +} +.btn.inline-btn { + border-radius: 50px; + height: auto; + line-height: inherit; + padding: 1px; + margin-left: 2px; +} +i.material-icons.inline-icon { + font-size: inherit; +} +a.legend-circle { + width: 15px; + height: 15px; + padding: 0; + border-radius: 15px; +} +.legend-header-cell { + text-transform: capitalize; +} +.legend-entry { + display: inline-block; + margin: 0 5px; + min-width: 50px; +} +.legend-bubble { + border-radius: 20px; + height: 20px; + width: 20px; + margin: 0 auto; +} +#pie-chart-wrapper { + padding: 25px 0; +} +.pie-chart-title { + cursor: default; +} +div.status-icon { + width: 10px; + height: 10px; + border-radius: 10px; + display: inline-block; + margin-left: 5px; +} +.test-case-status { + border-radius: 50px; + display: inline-block; + height: 100%; + width: 100%; +} +.test-case-status.width-1 { + width: calc(100% - 18px); +} +.TEST_CASE_RESULT_PASS { + background-color: #7FFF00; +} +.TEST_CASE_RESULT_FAIL { + background-color: #ff4d4d; +} +.TEST_CASE_RESULT_SKIP { + background-color: #A8A8A8; +} +.TEST_CASE_RESULT_EXCEPTION { + background-color: black; +} +.TEST_CASE_RESULT_TIMEOUT { + background-color: #9900CC; +} +.UNKNOWN_RESULT { + background-color: white; + border: 1px #A8A8A8 solid; +} diff --git a/src/main/webapp/css/show_test_runs_common.css b/src/main/webapp/css/show_test_runs_common.css new file mode 100644 index 0000000..63d5301 --- /dev/null +++ b/src/main/webapp/css/show_test_runs_common.css @@ -0,0 +1,136 @@ +/* Copyright (C) 2017 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. +*/ +.page-button-wrapper { + top: 50%; + bottom: auto; + padding: 0; +} +#newer-wrapper { + left: 23px; + right: auto; +} +#chart-holder { + padding: 30px 5px; +} +#pie-chart-div { + width: 100%; + height: 300px; +} +.row .col div.pie-chart-div { + width: 100%; + height: 255px; +} +#profiling-container { + padding: 0; +} +#error-div { + padding: 30px 25px; +} +#profiling-body { + border: none; +} +#profiling-list { + max-height: 200px; + overflow-y: scroll; +} +.collapsible-header { + user-select: none; +} +.collapsible-link { + color: inherit; +} +.collection a.collection-item.profiling-point-name { + color: #616161; + font-size: 13px; + padding: 2px 0 2px 25px; +} +#legend-wrapper { + display: inline-block; + padding: 10px 15px 12px; +} +.btn.inline-btn { + border-radius: 50px; + height: auto; + line-height: inherit; + padding: 1px; + margin-left: 2px; +} +i.material-icons.inline-icon { + font-size: inherit; +} +a.legend-circle { + width: 15px; + height: 15px; + padding: 0; + border-radius: 15px; +} +.legend-header-cell { + text-transform: capitalize; +} +.legend-entry { + display: inline-block; + margin: 0 5px; + min-width: 50px; +} +.legend-bubble { + border-radius: 20px; + height: 20px; + width: 20px; + margin: 0 auto; +} +#pie-chart-wrapper, .row .col.pie-chart-wrapper { + padding: 25px 0; +} +.pie-chart-title { + cursor: default; +} +div.status-icon { + width: 10px; + height: 10px; + border-radius: 10px; + display: inline-block; + margin-left: 5px; +} +.test-case-status { + border-radius: 50px; + display: inline-block; + height: 100%; + width: 100%; +} +.test-case-status.width-1 { + width: calc(100% - 18px); +} +.TEST_CASE_RESULT_PASS { + background-color: #4CAF50; +} +.TEST_CASE_RESULT_FAIL { + background-color: #F44336; +} +.TEST_CASE_RESULT_SKIP { + background-color: #A8A8A8; +} +.TEST_CASE_RESULT_EXCEPTION { + background-color: black; +} +.TEST_CASE_RESULT_TIMEOUT { + background-color: #9900CC; +} +.UNKNOWN_RESULT { + background-color: white; + border: 1px #A8A8A8 solid; +} +.tabs > div.indicator { + height: 3px; +} diff --git a/src/main/webapp/css/test_results.css b/src/main/webapp/css/test_results.css new file mode 100644 index 0000000..f717e79 --- /dev/null +++ b/src/main/webapp/css/test_results.css @@ -0,0 +1,78 @@ +/* Copyright (C) 2017 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. +*/ +li.test-run-container.active { + border-radius: 0 0 10px 10px; +} +.collapsible-header { + user-select: none; +} +.collapsible-header.disabled { + pointer-events: none; +} +.collapsible-header.test-run { + position: relative; +} +.test-run-metadata { + font-size: 13px; + line-height: 15px; + padding-top: 10px; + padding-bottom: 10px; + position: relative; + display: inline-block; + cursor: text; + user-select: initial; +} +.test-results.row { + margin: 0; + border-radius: 0 0 10px 10px; +} +.test-case-container { + border: 1px solid lightgray; + background: white; + padding: 10px; + margin-bottom: 25px; + max-height: 80%; + overflow: auto; +} +.indicator { + color: white; + font-size: 12px; + line-height: 20px; + font-weight: bold; + padding: 1px 6px; + margin-top: 10px; + min-width: 40px; + border-radius: 10px; +} +.indicator.padded { + margin-right: 5px; +} +.material-icons.expand-arrow { + right: 3px; + bottom: 0px; + position: absolute; + transition: transform 0.2s; +} +.rotate { + transform: rotate(-180deg); +} +i.material-icons.inline-icon { + font-size: inherit; +} +.test-run-label { + font-size: 18px; + line-height: 35px; + font-weight: 300; +} diff --git a/src/main/webapp/js/plan_runs.js b/src/main/webapp/js/plan_runs.js new file mode 100644 index 0000000..6898389 --- /dev/null +++ b/src/main/webapp/js/plan_runs.js @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2017 Google Inc. All Rights Reserved. + * + * 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. + */ + +(function ($, moment) { + + /** + * Display test plan metadata in a vertical popout. + * @param container The jquery object in which to insert the plan metadata. + * @param metadataList The list of metadata objects to render on the display. + */ + function renderCard(container, entry) { + var card = $('<div class="col s12 m6 l4"></div>'); + card.appendTo(container); + var div = $('<div class="hoverable card release-entry"></div>'); + var startTime = entry.testPlanRun.startTimestamp; + var endTime = entry.testPlanRun.endTimestamp; + div.appendTo(card); + var span = $('<span></span>'); + span.addClass('plan-run-metadata'); + span.appendTo(div); + $('<b></b>').text(entry.deviceInfo).appendTo(span); + span.append('<br>'); + $('<b></b>').text('VTS Build: ').appendTo(span); + span.append(entry.testPlanRun.testBuildId).append('<br>'); + var timeString = ( + moment().renderTime(startTime, false) + ' - ' + + moment().renderTime(endTime, true) + ' (' + + moment().renderDuration(endTime - startTime) + ')'); + span.append(timeString); + var counter = $('<span></span>'); + var color = entry.testPlanRun.failCount > 0 ? 'red' : 'green'; + counter.addClass('counter center ' + color); + counter.append( + entry.testPlanRun.passCount + '/' + + (entry.testPlanRun.passCount + entry.testPlanRun.failCount)); + counter.appendTo(div); + div.click(function () { + window.location.href = ( + '/show_plan_run?plan=' + entry.testPlanRun.testPlanName + + '&time=' + entry.testPlanRun.startTimestamp); + }) + } + + $.fn.showPlanRuns = function(data) { + var self = $(this); + data.forEach(function (entry) { + renderCard(self, entry); + }) + } + +})(jQuery, moment); diff --git a/src/main/webapp/js/search_header.js b/src/main/webapp/js/search_header.js new file mode 100644 index 0000000..0244815 --- /dev/null +++ b/src/main/webapp/js/search_header.js @@ -0,0 +1,242 @@ +/** + * Copyright (c) 2017 Google Inc. All Rights Reserved. + * + * 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. + */ + +(function ($) { + + function _validate(input, valueSet) { + var value = input.val(); + if (valueSet.has(value) || !value) { + input.removeClass('invalid'); + } else { + input.addClass('invalid'); + } + } + + function _createInput(key, config) { + var value = config.value; + var values = config.options.corpus; + var displayName = config.displayName; + var width = config.options.width || 's4'; + var div = $('<div class="input-field col"></div>'); + div.addClass(width); + var input = $('<input class="filter-input"></input>'); + input.attr('type', config.options.type || 'text'); + input.appendTo(div); + var label = $('<label></label>').text(displayName).appendTo(div); + if (value) { + input.attr('value', value); + label.addClass('active'); + } + input.focusout(function() { + config.value = input.val(); + }); + if (values && values.length > 0) { + var valueSet = new Set(values); + input.sizedAutocomplete({ + source: values, + classes: { + 'ui-autocomplete': 'card search-bar-menu' + } + }); + input.focusout(function() { + _validate(input, valueSet); + }); + } + if (values && values.length > 0 && value) { + _validate(input, valueSet); + } + return div; + } + + function _verifyCheckboxes(checkboxes, refreshObject) { + var oneChecked = checkboxes.presubmit || checkboxes.postsubmit; + if (!oneChecked) { + refreshObject.addClass('disabled'); + } else { + refreshObject.removeClass('disabled'); + } + } + + function _createRunTypeBoxes(checkboxes, refreshObject) { + var container = $('<div class="run-type-wrapper col s12"></div>'); + var presubmit = $('<input type="checkbox" id="presubmit"></input>'); + presubmit.appendTo(container); + if (checkboxes.presubmit) { + presubmit.prop('checked', true); + } + container.append('<label for="presubmit">Presubmit</label>'); + var postsubmit = $('<input type="checkbox" id="postsubmit"></input>'); + postsubmit.appendTo(container); + if (checkboxes.postsubmit) { + postsubmit.prop('checked', true); + } + container.append('<label for="postsubmit">Postsubmit</label>'); + presubmit.change(function() { + checkboxes.presubmit = presubmit.prop('checked'); + _verifyCheckboxes(checkboxes, refreshObject); + }); + postsubmit.change(function() { + checkboxes.postsubmit = postsubmit.prop('checked'); + _verifyCheckboxes(checkboxes, refreshObject); + }); + return container; + } + + function _expand( + container, filters, checkboxes, onRefreshCallback, animate=true) { + var wrapper = $('<div class="search-wrapper"></div>'); + var col = $('<div class="col s9"></div>'); + col.appendTo(wrapper); + Object.keys(filters).forEach(function(key) { + col.append(_createInput(key, filters[key])); + }); + var refreshCol = $('<div class="col s3 refresh-wrapper"></div>'); + var refresh = $('<a class="btn-floating btn-medium red right waves-effect waves-light"></a>') + .append($('<i class="medium material-icons">cached</i>')) + .appendTo(refreshCol); + refresh.click(onRefreshCallback); + refreshCol.appendTo(wrapper); + if (Object.keys(checkboxes).length > 0) { + col.append(_createRunTypeBoxes(checkboxes, refresh)); + } + if (animate) { + wrapper.hide().appendTo(container).slideDown({ + duration: 350, + easing: "easeOutQuart", + queue: false + }); + } else { + wrapper.appendTo(container); + } + } + + function _renderHeader( + container, label, value, filters, checkboxes, expand, onRefreshCallback) { + var div = $('<div class="row card search-bar"></div>'); + var wrapper = $('<div class="header-wrapper"></div>'); + var header = $('<h5 class="section-header"></h5>'); + $('<b></b>').text(label).appendTo(header); + $('<span></span>').text(value).appendTo(header); + header.appendTo(wrapper); + var iconWrapper = $('<div class="search-icon-wrapper"></div>'); + $('<i class="material-icons">search</i>').appendTo(iconWrapper); + iconWrapper.appendTo(wrapper); + wrapper.appendTo(div); + if (expand) { + _expand(div, filters, checkboxes, onRefreshCallback, false); + } else { + var expanded = false; + iconWrapper.click(function() { + if (expanded) return; + expanded = true; + _expand(div, filters, checkboxes, onRefreshCallback); + }); + } + div.appendTo(container); + } + + function _addFilter(filters, displayName, keyName, options, defaultValue) { + filters[keyName] = {}; + filters[keyName].displayName = displayName; + filters[keyName].value = defaultValue; + filters[keyName].options = options; + } + + function _getOptionString(filters, checkboxes) { + var args = Object.keys(filters).reduce(function(acc, key) { + if (filters[key].value) { + return acc + '&' + key + '=' + encodeURIComponent(filters[key].value); + } + return acc; + }, ''); + if (checkboxes.presubmit != undefined && checkboxes.presubmit) { + args += '&showPresubmit=' + } + if (checkboxes.postsubmit != undefined && checkboxes.postsubmit) { + args += '&showPostsubmit=' + } + return args; + } + + /** + * Create a search header element. + * @param label The header label. + * @param value The value to display next to the label. + * @param onRefreshCallback The function to call on refresh. + */ + $.fn.createSearchHeader = function(label, value, onRefreshCallback) { + var self = $(this); + $.widget('custom.sizedAutocomplete', $.ui.autocomplete, { + _resizeMenu : function() { + this.menu.element.outerWidth($('.search-bar .filter-input').width()); + } + }); + var filters = {}; + var checkboxes = {}; + var expandOnRender = false; + var displayed = false; + return { + /** + * Add a filter to the display. + * @param displayName The input placeholder/label text. + * @param keyName The URL key to use for the filter options. + * @param options A dict of additional options (e.g. width, type). + * @param defaultValue A default filter value. + */ + addFilter : function(displayName, keyName, options, defaultValue) { + if (displayed) return; + _addFilter(filters, displayName, keyName, options, defaultValue); + if (defaultValue) expandOnRender = true; + }, + /** + * Enable run type checkboxes in the filter options. + * + * This will display two checkboxes for selecting pre-/postsubmit runs. + * @param showPresubmit True if presubmit runs are selected. + * @param showPostsubmit True if postsubmit runs are selected. + * + */ + addRunTypeCheckboxes: function(showPresubmit, showPostsubmit) { + if (displayed) return; + checkboxes['presubmit'] = showPresubmit; + checkboxes['postsubmit'] = showPostsubmit; + if (!showPostsubmit || showPresubmit) { + expandOnRender = true; + } + }, + /** + * Display the created search bar. + * + * This must be called after filters have been added. After displaying, no + * modifications to the filter options will take effect. + */ + display : function() { + displayed = true; + _renderHeader( + self, label, value, filters, checkboxes, expandOnRender, + onRefreshCallback); + }, + /** + * Get the URL arguments string for the current set of filters. + * @returns a URI-encoded component with the search bar keys and values. + */ + args : function () { + return _getOptionString(filters, checkboxes); + } + } + } + +})(jQuery); diff --git a/src/main/webapp/js/test_results.js b/src/main/webapp/js/test_results.js new file mode 100644 index 0000000..8f923fb --- /dev/null +++ b/src/main/webapp/js/test_results.js @@ -0,0 +1,272 @@ +/** + * Copyright (c) 2017 Google Inc. All Rights Reserved. + * + * 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. + */ + +(function ($, moment) { + + /** + * Display the log links in a modal window. + * @param logList A list of [name, url] tuples representing log links. + */ + function showLogs(container, logList) { + if (!logList || logList.length == 0) return; + + var logCollection = $('<ul class="collection"></ul>'); + var entries = logList.reduce(function(acc, entry) { + if (!entry || entry.length == 0) return acc; + var link = '<a href="' + entry[1] + '"'; + link += 'class="collection-item">' + entry[0] + '</li>'; + return acc + link; + }, ''); + logCollection.html(entries); + + if (container.find('#info-modal').length == 0) { + var modal = $('<div id="info-modal" class="modal"></div>'); + var content = $('<div class="modal-content"></div>'); + content.append('<h4>Logs</h4>'); + content.append('<div class="info-container"></div>'); + content.appendTo(modal); + modal.appendTo(container); + } + var infoContainer = $('#info-modal>.modal-content>.info-container'); + infoContainer.empty(); + logCollection.appendTo(infoContainer); + $('#info-modal').openModal(); + } + + /** + * Get the nickname for a test case result. + * + * Removes the result prefix and suffix, extracting only the result name. + * + * @param testCaseResult The string name of a VtsReportMessage.TestCaseResult. + * @returns the string nickname of the result. + */ + function getNickname(testCaseResult) { + return testCaseResult + .replace('TEST_CASE_RESULT_', '') + .replace('_RESULT', '') + .trim().toLowerCase(); + } + + /** + * Display test data in the body beneath a test run's metadata. + * @param container The jquery object in which to insert the test metadata. + * @param data The json object containing the columns to display. + * @param lineHeight The height of each list element. + */ + function displayTestDetails(container, data, lineHeight) { + var nCol = data.length; + var width = 12 / nCol; + test = container; + var maxLines = 0; + data.forEach(function (column) { + if (column.data == undefined || column.name == undefined) { + return; + } + var colContainer = + $('<div class="col s' + width + ' test-col"></div>'); + var col = $('<div class="test-case-container"></div>'); + colContainer.appendTo(container); + var count = column.data.length; + $('<h5>' + getNickname(column.name) + ' (' + count + ')' + '</h5>') + .appendTo(colContainer).css('text-transform', 'capitalize'); + col.appendTo(colContainer); + var list = $('<ul></ul>').appendTo(col); + column.data.forEach(function (testCase) { + $('<li></li>') + .text(testCase) + .addClass('test-case') + .css('font-size', lineHeight - 2) + .css('line-height', lineHeight + 'px') + .appendTo(list); + }); + if (count > maxLines) { + maxLines = count; + } + }); + var containers = container.find('.test-case-container'); + containers.height(maxLines * lineHeight); + } + + /** + * Click handler for displaying test run details. + * @param e The click event. + */ + function testRunClick(e) { + var header = $(this); + var icon = header.find('.material-icons.expand-arrow'); + var container = header.parent().find('.test-results'); + var test = header.attr('test'); + var time = header.attr('time'); + var url = '/api/test_run?test=' + test + '×tamp=' + time; + if (header.parent().hasClass('active')) { + header.parent().removeClass('active'); + header.removeClass('active'); + icon.removeClass('rotate'); + header.siblings('.collapsible-body').stop(true, false).slideUp({ + duration: 100, + easing: "easeOutQuart", + queue: false, + complete: function() { header.css('height', ''); } + }); + } else { + container.empty(); + header.parent().addClass('active'); + header.addClass('active'); + header.addClass('disabled'); + icon.addClass('rotate'); + $.get(url).done(function(data) { + displayTestDetails(container, data, 16); + header.siblings('.collapsible-body').stop(true, false).slideDown({ + duration: 100, + easing: "easeOutQuart", + queue: false, + complete: function() { header.css('height', ''); } + }); + }).fail(function() { + icon.removeClass('rotate'); + }).always(function() { + header.removeClass('disabled'); + }); + } + } + + /** + * Append a clickable indicator link to the container. + * @param container The jquery object to append the indicator to. + * @param content The text to display in the indicator. + * @param classes Additional space-delimited classes to add to the indicator. + * @param click The click handler to assign to the indicator. + * @returns The jquery object for the indicator. + */ + function createClickableIndicator(container, content, classes, click) { + var link = $('<a></a>'); + link.addClass('indicator right center padded hoverable waves-effect'); + link.addClass(classes) + link.append(content); + link.appendTo(container); + link.click(click); + return link; + } + + function displayTestMetadata(container, metadataList, showTestNames=false) { + var popout = $('<ul></ul>'); + popout.attr('data-collapsible', 'expandable'); + popout.addClass('collapsible popout test-runs'); + popout.appendTo(container); + popout.unbind(); + metadataList.forEach(function (metadata) { + var li = $('<li class="test-run-container"></li>'); + li.appendTo(popout); + var div = $('<div></div>'); + var test = metadata.testRun.testName; + var startTime = metadata.testRun.startTimestamp; + var endTime = metadata.testRun.endTimestamp; + div.attr('test', test); + div.attr('time', startTime); + div.addClass('collapsible-header test-run'); + div.appendTo(li); + div.unbind().click(testRunClick); + var span = $('<span></span>'); + span.addClass('test-run-metadata'); + span.appendTo(div); + span.click(function() { return false; }); + if (showTestNames) { + $('<span class="test-run-label"></span>').text(test).appendTo(span); + span.append('<br>'); + } + $('<b></b>').text(metadata.deviceInfo).appendTo(span); + span.append('<br>'); + $('<b></b>').text('ABI: ') + .appendTo(span) + span.append(metadata.abiInfo).append('<br>'); + $('<b></b>').text('VTS Build: ') + .appendTo(span) + span.append(metadata.testRun.testBuildId).append('<br>'); + $('<b></b>').text('Host: ') + .appendTo(span) + span.append(metadata.testRun.hostName).append('<br>'); + var timeString = ( + moment().renderTime(startTime, false) + ' - ' + + moment().renderTime(endTime, true) + ' (' + + moment().renderDuration(endTime - startTime) + ')'); + span.append(timeString); + var indicator = $('<span></span>'); + var color = metadata.testRun.failCount > 0 ? 'red' : 'green'; + indicator.addClass('indicator right center ' + color); + indicator.append( + metadata.testRun.passCount + '/' + + (metadata.testRun.passCount + metadata.testRun.failCount)); + indicator.appendTo(div); + if (metadata.testRun.coveredLineCount != undefined && + metadata.testRun.totalLineCount != undefined) { + var url = ( + '/show_coverage?testName=' + test + '&startTime=' + startTime); + covered = metadata.testRun.coveredLineCount; + total = metadata.testRun.totalLineCount; + covPct = Math.round(covered / total * 1000) / 10; + var color = 'red'; + if (covPct > 20 && covPct < 70) { + color = 'orange'; + } else if (covPct >= 70) { + color = 'green'; + } + var coverage = ( + 'Coverage: ' + covered + '/' + total + ' (' + covPct + '%)'); + createClickableIndicator( + div, coverage, color, + function () { window.location.href = url; return false; }); + } + if (metadata.testRun.logLinks != undefined) { + createClickableIndicator( + div, 'Logs', 'grey lighten-1', + function () { + showLogs(popout, metadata.testRun.logLinks); + return false; + }); + } + var expand = $('<i></i>'); + expand.addClass('material-icons expand-arrow') + expand.text('expand_more'); + expand.appendTo(div); + var body = $('<div></div>') + .addClass('collapsible-body test-results row grey lighten-4') + .appendTo(li); + if (metadata.testDetails != undefined) { + expand.addClass('rotate'); + li.addClass('active'); + div.addClass('active'); + displayTestDetails(body, metadata.testDetails, 16); + div.siblings('.collapsible-body').stop(true, false).slideDown({ + duration: 0, + queue: false, + complete: function() { div.css('height', ''); } + }); + } + }); + } + + /** + * Display test metadata in a vertical popout. + * @param container The jquery object in which to insert the test metadata. + * @param metadataList The list of metadata objects to render on the display. + * @param showTestNames True to label each entry with the test module name. + */ + $.fn.showTests = function(metadataList, showTestNames=false) { + displayTestMetadata($(this), metadataList, showTestNames); + } + +})(jQuery, moment); diff --git a/src/main/webapp/js/time.js b/src/main/webapp/js/time.js new file mode 100644 index 0000000..c5fbef6 --- /dev/null +++ b/src/main/webapp/js/time.js @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2017 Google Inc. All Rights Reserved. + * + * 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. + */ + +(function (moment) { + + /** + * Renders a timestamp in the user timezone. + * @param timestamp The long timestamp to render (in microseconds). + * @param showTimezone True if the timezone should be rendered, false otherwise. + * @returns the string-formatted version of the provided timestamp. + */ + moment.prototype.renderTime = function (timestamp, showTimezone) { + var time = moment(timestamp / 1000); + var format = 'H:mm:ss'; + if (!time.isSame(moment(), 'd')) { + format = 'M/D/YY ' + format; + } + if (!!showTimezone) { + format = format + 'ZZ'; + } + return time.format(format); + } + + /** + * Renders a duration in the user timezone. + * @param durationTimestamp The long duration to render (in microseconds). + * @returns the string-formatted duration of the provided duration timestamp. + */ + moment.prototype.renderDuration = function (durationTimestamp) { + var fmt = 's[s]'; + var duration = moment.utc(durationTimestamp / 1000); + if (duration.hours() > 0) { + fmt = 'H[h], m[m], ' + fmt; + } else if (duration.minutes() > 0) { + fmt = 'm[m], ' + fmt; + } + return duration.format(fmt); + } + +})(moment); diff --git a/src/test/java/com/android/vts/servlet/VtsPerformanceJobServletTest.java b/src/test/java/com/android/vts/servlet/VtsPerformanceJobServletTest.java new file mode 100644 index 0000000..c8adb69 --- /dev/null +++ b/src/test/java/com/android/vts/servlet/VtsPerformanceJobServletTest.java @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.servlet; + +import static org.junit.Assert.*; + +import com.android.vts.entity.ProfilingPointRunEntity; +import com.android.vts.entity.TestEntity; +import com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode; +import com.android.vts.util.PerformanceSummary; +import com.android.vts.util.ProfilingPointSummary; +import com.google.appengine.api.datastore.KeyFactory; +import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig; +import com.google.appengine.tools.development.testing.LocalServiceTestHelper; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class VtsPerformanceJobServletTest { + private final LocalServiceTestHelper helper = + new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig()); + + private static final String LABEL = "testLabel"; + private static final String ROOT = "src/test/res/servlet"; + private static final String[] LABELS = new String[] {"label1", "label2", "label3"}; + private static final long[] HIGH_VALS = new long[] {10, 20, 30}; + private static final long[] LOW_VALS = new long[] {1, 2, 3}; + + List<PerformanceSummary> dailySummaries; + List<String> legendLabels; + + /** + * Helper method for creating ProfilingPointRunEntity objects. + * + * @param labels The list of data labels. + * @param values The list of data values. Must be equal in size to the labels list. + * @param regressionMode The regression mode. + * @return A ProfilingPointRunEntity with specified arguments. + */ + private static ProfilingPointRunEntity createProfilingReport( + String[] labels, long[] values, VtsProfilingRegressionMode regressionMode) { + List<String> labelList = Arrays.asList(labels); + List<Long> valueList = new ArrayList<>(); + for (long value : values) { + valueList.add(value); + } + return new ProfilingPointRunEntity(KeyFactory.createKey(TestEntity.KIND, "test"), "name", 0, + regressionMode.getNumber(), labelList, valueList, "", "", null); + } + + /** Asserts whether text is the same as the contents in the baseline file specified. */ + private static void compareToBaseline(String text, String baselineFilename) + throws FileNotFoundException, IOException { + File f = new File(ROOT, baselineFilename); + String baseline = ""; + try (BufferedReader br = new BufferedReader(new FileReader(f))) { + StringBuilder sb = new StringBuilder(); + String line = br.readLine(); + + while (line != null) { + sb.append(line); + line = br.readLine(); + } + baseline = sb.toString(); + } + assertEquals(baseline, text); + } + + @Before + public void setUp() { + helper.setUp(); + } + + @After + public void tearDown() { + helper.tearDown(); + } + + public void setUp(boolean grouped) { + dailySummaries = new ArrayList<>(); + legendLabels = new ArrayList<>(); + legendLabels.add(""); + + // Add today's data + PerformanceSummary today = new PerformanceSummary(); + ProfilingPointSummary summary = new ProfilingPointSummary(); + VtsProfilingRegressionMode mode = VtsProfilingRegressionMode.VTS_REGRESSION_MODE_INCREASING; + ProfilingPointRunEntity pt = createProfilingReport(LABELS, HIGH_VALS, mode); + if (grouped) { + summary.updateLabel(pt, LABEL); + summary.updateLabel(pt, LABEL); + } else { + summary.update(pt); + summary.update(pt); + } + today.insertProfilingPointSummary("p1", summary); + + summary = new ProfilingPointSummary(); + mode = VtsProfilingRegressionMode.VTS_REGRESSION_MODE_DECREASING; + pt = createProfilingReport(LABELS, LOW_VALS, mode); + if (grouped) { + summary.updateLabel(pt, LABEL); + summary.updateLabel(pt, LABEL); + } else { + summary.update(pt); + summary.update(pt); + } + today.insertProfilingPointSummary("p2", summary); + dailySummaries.add(today); + legendLabels.add("today"); + + // Add yesterday data with regressions + PerformanceSummary yesterday = new PerformanceSummary(); + summary = new ProfilingPointSummary(); + mode = VtsProfilingRegressionMode.VTS_REGRESSION_MODE_INCREASING; + pt = createProfilingReport(LABELS, LOW_VALS, mode); + if (grouped) { + summary.updateLabel(pt, LABEL); + summary.updateLabel(pt, LABEL); + } else { + summary.update(pt); + summary.update(pt); + } + yesterday.insertProfilingPointSummary("p1", summary); + + summary = new ProfilingPointSummary(); + mode = VtsProfilingRegressionMode.VTS_REGRESSION_MODE_DECREASING; + pt = createProfilingReport(LABELS, HIGH_VALS, mode); + if (grouped) { + summary.updateLabel(pt, LABEL); + summary.updateLabel(pt, LABEL); + } else { + summary.update(pt); + summary.update(pt); + } + yesterday.insertProfilingPointSummary("p2", summary); + dailySummaries.add(yesterday); + legendLabels.add("yesterday"); + + // Add last week data without regressions + PerformanceSummary lastWeek = new PerformanceSummary(); + summary = new ProfilingPointSummary(); + mode = VtsProfilingRegressionMode.VTS_REGRESSION_MODE_INCREASING; + pt = createProfilingReport(LABELS, HIGH_VALS, mode); + summary.update(pt); + summary.update(pt); + lastWeek.insertProfilingPointSummary("p1", summary); + + summary = new ProfilingPointSummary(); + mode = VtsProfilingRegressionMode.VTS_REGRESSION_MODE_DECREASING; + pt = createProfilingReport(LABELS, LOW_VALS, mode); + summary.update(pt); + summary.update(pt); + lastWeek.insertProfilingPointSummary("p2", summary); + dailySummaries.add(lastWeek); + legendLabels.add("last week"); + } + + /** + * End-to-end test of performance report in the normal case. The normal case is when a profiling + * point is added or removed from the test. + */ + @Test + public void testPerformanceSummaryNormal() throws FileNotFoundException, IOException { + setUp(false); + String output = + VtsPerformanceJobServlet.getPeformanceSummary("test", dailySummaries, legendLabels); + compareToBaseline(output, "performanceSummary1.html"); + } + + /** End-to-end test of performance report when a profiling point was removed in the latest run. + */ + @Test + public void testPerformanceSummaryDroppedProfilingPoint() + throws FileNotFoundException, IOException { + setUp(false); + PerformanceSummary yesterday = dailySummaries.get(dailySummaries.size() - 1); + ProfilingPointSummary summary = new ProfilingPointSummary(); + VtsProfilingRegressionMode mode = VtsProfilingRegressionMode.VTS_REGRESSION_MODE_INCREASING; + ProfilingPointRunEntity pt = createProfilingReport(LABELS, HIGH_VALS, mode); + summary.update(pt); + summary.update(pt); + yesterday.insertProfilingPointSummary("p3", summary); + String output = + VtsPerformanceJobServlet.getPeformanceSummary("test", dailySummaries, legendLabels); + compareToBaseline(output, "performanceSummary2.html"); + } + + /** End-to-end test of performance report when a profiling point was added in the latest run. */ + @Test + public void testPerformanceSummaryAddedProfilingPoint() + throws FileNotFoundException, IOException { + setUp(false); + PerformanceSummary today = dailySummaries.get(0); + ProfilingPointSummary summary = new ProfilingPointSummary(); + VtsProfilingRegressionMode mode = VtsProfilingRegressionMode.VTS_REGRESSION_MODE_INCREASING; + ProfilingPointRunEntity pt = createProfilingReport(LABELS, HIGH_VALS, mode); + summary.update(pt); + summary.update(pt); + today.insertProfilingPointSummary("p3", summary); + String output = + VtsPerformanceJobServlet.getPeformanceSummary("test", dailySummaries, legendLabels); + compareToBaseline(output, "performanceSummary3.html"); + } + + /** End-to-end test of performance report labels are grouped (e.g. as if using unlabeled data) + */ + @Test + public void testPerformanceSummaryGroupedNormal() throws FileNotFoundException, IOException { + setUp(true); + String output = + VtsPerformanceJobServlet.getPeformanceSummary("test", dailySummaries, legendLabels); + compareToBaseline(output, "performanceSummary4.html"); + } +} diff --git a/src/test/java/com/android/vts/util/ProfilingPointSummaryTest.java b/src/test/java/com/android/vts/util/ProfilingPointSummaryTest.java new file mode 100644 index 0000000..cc529be --- /dev/null +++ b/src/test/java/com/android/vts/util/ProfilingPointSummaryTest.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.util; + +import static org.junit.Assert.*; + +import com.android.vts.entity.ProfilingPointRunEntity; +import com.android.vts.entity.TestEntity; +import com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode; +import com.google.appengine.api.datastore.KeyFactory; +import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig; +import com.google.appengine.tools.development.testing.LocalServiceTestHelper; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class ProfilingPointSummaryTest { + private final LocalServiceTestHelper helper = + new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig()); + private static String[] labels = new String[] {"label1", "label2", "label3"}; + private static long[] values = new long[] {1, 2, 3}; + private static ProfilingPointSummary summary; + + /** + * Helper method for creating ProfilingPointRunEntity objects. + * + * @param labels The list of data labels. + * @param values The list of data values. Must be equal in size to the labels list. + * @param regressionMode The regression mode. + * @return A ProfilingPointRunEntity with specified arguments. + */ + private static ProfilingPointRunEntity createProfilingReport( + String[] labels, long[] values, VtsProfilingRegressionMode regressionMode) { + List<String> labelList = Arrays.asList(labels); + List<Long> valueList = new ArrayList<>(); + for (long value : values) { + valueList.add(value); + } + return new ProfilingPointRunEntity(KeyFactory.createKey(TestEntity.KIND, "test"), "name", 0, + regressionMode.getNumber(), labelList, valueList, "x", "y", null); + } + + @Before + public void setUp() { + helper.setUp(); + summary = new ProfilingPointSummary(); + VtsProfilingRegressionMode mode = VtsProfilingRegressionMode.VTS_REGRESSION_MODE_INCREASING; + ProfilingPointRunEntity pt = createProfilingReport(labels, values, mode); + summary.update(pt); + } + + @After + public void tearDown() { + helper.tearDown(); + } + + /** Test that all labels are found by hasLabel. */ + @Test + public void testHasLabel() { + for (String label : labels) { + assertTrue(summary.hasLabel(label)); + } + } + + /** Test that invalid labels are not found by hasLabel. */ + @Test + public void testInvalidHasLabel() { + assertFalse(summary.hasLabel("bad label")); + } + + /** Test that all stat summaries can be retrieved by profiling point label. */ + @Test + public void testGetStatSummary() { + for (String label : labels) { + StatSummary stats = summary.getStatSummary(label); + assertNotNull(stats); + assertEquals(label, stats.getLabel()); + } + } + + /** Test that the getStatSummary method returns null when the label is not present. */ + @Test + public void testInvalidGetStatSummary() { + StatSummary stats = summary.getStatSummary("bad label"); + assertNull(stats); + } + + /** Test that StatSummary objects are iterated in the order that the labels were provided. */ + @Test + public void testIterator() { + VtsProfilingRegressionMode mode = VtsProfilingRegressionMode.VTS_REGRESSION_MODE_INCREASING; + ProfilingPointRunEntity pt = createProfilingReport(labels, values, mode); + summary.update(pt); + + int i = 0; + for (StatSummary stats : summary) { + assertEquals(labels[i++], stats.getLabel()); + } + } + + /** Test that the updateLabel method updates the StatSummary for just the label provided. */ + @Test + public void testUpdateLabelGrouped() { + summary = new ProfilingPointSummary(); + VtsProfilingRegressionMode mode = VtsProfilingRegressionMode.VTS_REGRESSION_MODE_INCREASING; + ProfilingPointRunEntity pt = createProfilingReport(labels, values, mode); + summary.updateLabel(pt, labels[0]); + + // Ensure the label specified is present and has been updated for each data point. + assertTrue(summary.hasLabel(labels[0])); + assertNotNull(summary.getStatSummary(labels[0])); + assertEquals(summary.getStatSummary(labels[0]).getCount(), labels.length); + + // Check that the other labels were not updated. + for (int i = 1; i < labels.length; i++) { + assertFalse(summary.hasLabel(labels[i])); + } + } +} diff --git a/src/test/java/com/android/vts/util/StatSummaryTest.java b/src/test/java/com/android/vts/util/StatSummaryTest.java new file mode 100644 index 0000000..333e3b5 --- /dev/null +++ b/src/test/java/com/android/vts/util/StatSummaryTest.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2016 Google Inc. All Rights Reserved. + * + * 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. + */ + +package com.android.vts.util; + +import static org.junit.Assert.*; + +import com.android.vts.proto.VtsReportMessage.VtsProfilingRegressionMode; +import java.util.Random; +import org.junit.Before; +import org.junit.Test; + +public class StatSummaryTest { + private static double threshold = 0.0000000001; + private StatSummary test; + + @Before + public void setUp() { + test = new StatSummary("label", VtsProfilingRegressionMode.VTS_REGRESSION_MODE_DECREASING); + } + + /** Test computation of average. */ + @Test + public void testAverage() { + int n = 1000; + double mean = (n - 1) / 2.0; + for (int i = 0; i < n; i++) { + test.updateStats(i); + } + assertEquals(n, test.getCount(), threshold); + assertEquals(mean, test.getMean(), threshold); + } + + /** Test computation of minimum. */ + @Test + public void testMin() { + double min = Double.MAX_VALUE; + int n = 1000; + Random rand = new Random(); + for (int i = 0; i < n; i++) { + double value = rand.nextInt(1000); + if (value < min) + min = value; + test.updateStats(value); + } + assertEquals(n, test.getCount(), threshold); + assertEquals(min, test.getMin(), threshold); + } + + /** Test computation of maximum. */ + @Test + public void testMax() { + double max = Double.MIN_VALUE; + int n = 1000; + Random rand = new Random(); + for (int i = 0; i < n; i++) { + double value = rand.nextInt(1000); + if (value > max) + max = value; + test.updateStats(value); + } + assertEquals(max, test.getMax(), threshold); + } + + /** Test computation of standard deviation. */ + @Test + public void testStd() { + int n = 1000; + double[] values = new double[n]; + Random rand = new Random(); + double sum = 0.0; + for (int i = 0; i < n; i++) { + values[i] = rand.nextInt(1000); + sum += values[i]; + test.updateStats(values[i]); + } + double mean = sum / n; + double sumSq = 0; + for (int i = 0; i < n; i++) { + sumSq += (values[i] - mean) * (values[i] - mean); + } + double std = Math.sqrt(sumSq / (n - 1)); + assertEquals(std, test.getStd(), threshold); + } +} diff --git a/src/test/res/driver/chromedriver b/src/test/res/driver/chromedriver Binary files differnew file mode 100755 index 0000000..bbb06c3 --- /dev/null +++ b/src/test/res/driver/chromedriver diff --git a/src/test/res/driver/config.properties b/src/test/res/driver/config.properties new file mode 100644 index 0000000..939fa90 --- /dev/null +++ b/src/test/res/driver/config.properties @@ -0,0 +1 @@ +LOCALHOST=localhost:8080
\ No newline at end of file diff --git a/src/test/res/servlet/performanceSummary1.html b/src/test/res/servlet/performanceSummary1.html new file mode 100644 index 0000000..3b01593 --- /dev/null +++ b/src/test/res/servlet/performanceSummary1.html @@ -0,0 +1 @@ +<p style='font-family: arial'><b>test</b></p><table cellpadding='2' style='width: 100%; border-collapse: collapse; border: 1px solid black; font-size: 12px; font-family: arial;'><tr><td colspan='16'>p1</td></tr><tr><td colspan='16'></td></tr><tr><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='1'></th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='3'>today</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>yesterday</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>last week</th></tr><tr><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'></th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Min</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>ΔMin (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Min</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>ΔMin (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Min</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label1</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 18.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>900 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label2</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 18.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>900 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label3</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 18.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>900 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr></table><i style='font-family: arial; font-size: 12px'>Note: Lower values are better. Minimum is the best-case performance.</i><br><br><table cellpadding='2' style='width: 100%; border-collapse: collapse; border: 1px solid black; font-size: 12px; font-family: arial;'><tr><td colspan='16'>p2</td></tr><tr><td colspan='16'></td></tr><tr><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='1'></th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='3'>today</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>yesterday</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>last week</th></tr><tr><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'></th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Max</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>ΔMax (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Max</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>ΔMax (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Max</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label1</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 1.8); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>-90 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, -0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label2</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 1.8); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>-90 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, -0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label3</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 1.8); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>-90 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, -0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr></table><i style='font-family: arial; font-size: 12px'>Note: Higher values are better. Maximum is the best-case performance.</i><br><br>
\ No newline at end of file diff --git a/src/test/res/servlet/performanceSummary2.html b/src/test/res/servlet/performanceSummary2.html new file mode 100644 index 0000000..3b01593 --- /dev/null +++ b/src/test/res/servlet/performanceSummary2.html @@ -0,0 +1 @@ +<p style='font-family: arial'><b>test</b></p><table cellpadding='2' style='width: 100%; border-collapse: collapse; border: 1px solid black; font-size: 12px; font-family: arial;'><tr><td colspan='16'>p1</td></tr><tr><td colspan='16'></td></tr><tr><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='1'></th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='3'>today</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>yesterday</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>last week</th></tr><tr><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'></th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Min</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>ΔMin (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Min</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>ΔMin (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Min</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label1</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 18.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>900 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label2</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 18.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>900 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label3</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 18.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>900 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr></table><i style='font-family: arial; font-size: 12px'>Note: Lower values are better. Minimum is the best-case performance.</i><br><br><table cellpadding='2' style='width: 100%; border-collapse: collapse; border: 1px solid black; font-size: 12px; font-family: arial;'><tr><td colspan='16'>p2</td></tr><tr><td colspan='16'></td></tr><tr><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='1'></th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='3'>today</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>yesterday</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>last week</th></tr><tr><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'></th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Max</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>ΔMax (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Max</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>ΔMax (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Max</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label1</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 1.8); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>-90 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, -0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label2</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 1.8); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>-90 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, -0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label3</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 1.8); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>-90 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, -0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr></table><i style='font-family: arial; font-size: 12px'>Note: Higher values are better. Maximum is the best-case performance.</i><br><br>
\ No newline at end of file diff --git a/src/test/res/servlet/performanceSummary3.html b/src/test/res/servlet/performanceSummary3.html new file mode 100644 index 0000000..1ff1028 --- /dev/null +++ b/src/test/res/servlet/performanceSummary3.html @@ -0,0 +1 @@ +<p style='font-family: arial'><b>test</b></p><table cellpadding='2' style='width: 100%; border-collapse: collapse; border: 1px solid black; font-size: 12px; font-family: arial;'><tr><td colspan='16'>p1</td></tr><tr><td colspan='16'></td></tr><tr><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='1'></th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='3'>today</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>yesterday</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>last week</th></tr><tr><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'></th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Min</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>ΔMin (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Min</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>ΔMin (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Min</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label1</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 18.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>900 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label2</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 18.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>900 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label3</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 18.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>900 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr></table><i style='font-family: arial; font-size: 12px'>Note: Lower values are better. Minimum is the best-case performance.</i><br><br><table cellpadding='2' style='width: 100%; border-collapse: collapse; border: 1px solid black; font-size: 12px; font-family: arial;'><tr><td colspan='16'>p2</td></tr><tr><td colspan='16'></td></tr><tr><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='1'></th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='3'>today</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>yesterday</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>last week</th></tr><tr><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'></th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Max</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>ΔMax (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Max</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>ΔMax (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Max</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label1</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 1.8); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>-90 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, -0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label2</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 1.8); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>-90 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, -0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label3</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, 1.8); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>-90 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td class='' style='background-color: rgba(255, 0, 0, -0.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>0 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td></tr></table><i style='font-family: arial; font-size: 12px'>Note: Higher values are better. Maximum is the best-case performance.</i><br><br><table cellpadding='2' style='width: 100%; border-collapse: collapse; border: 1px solid black; font-size: 12px; font-family: arial;'><tr><td colspan='16'>p3</td></tr><tr><td colspan='16'></td></tr><tr><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='1'></th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='3'>today</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>yesterday</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>last week</th></tr><tr><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'></th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Min</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>ΔMin (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Min</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>ΔMin (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Min</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label1</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label2</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>label3</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0</td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr></table><i style='font-family: arial; font-size: 12px'>Note: Lower values are better. Minimum is the best-case performance.</i><br><br>
\ No newline at end of file diff --git a/src/test/res/servlet/performanceSummary4.html b/src/test/res/servlet/performanceSummary4.html new file mode 100644 index 0000000..8fc8997 --- /dev/null +++ b/src/test/res/servlet/performanceSummary4.html @@ -0,0 +1 @@ +<p style='font-family: arial'><b>test</b></p><table cellpadding='2' style='width: 100%; border-collapse: collapse; border: 1px solid black; font-size: 12px; font-family: arial;'><tr><td colspan='16'>p1</td></tr><tr><td colspan='16'></td></tr><tr><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='1'></th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='3'>today</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>yesterday</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>last week</th></tr><tr><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'></th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Min</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>ΔMin (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Min</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>ΔMin (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Min</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>testLabel</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>10</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>8.94</td><td class='' style='background-color: rgba(255, 0, 0, 18.0); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>900 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>1<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0.89</td><td></td><td></td><td></td><td></td></tr></table><i style='font-family: arial; font-size: 12px'>Note: Lower values are better. Minimum is the best-case performance.</i><br><br><table cellpadding='2' style='width: 100%; border-collapse: collapse; border: 1px solid black; font-size: 12px; font-family: arial;'><tr><td colspan='16'>p2</td></tr><tr><td colspan='16'></td></tr><tr><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='1'></th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='3'>today</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>yesterday</th><th style='border: 1px solid black; border-bottom: none; background-color: lightgray;' colspan='4'>last week</th></tr><tr><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'></th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Max</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>ΔMax (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Max</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>ΔMax (%)</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Max</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Mean</th><th style='border: 1px solid black; border-bottom-width: 2px; border-top: 1px dotted gray; background-color: lightgray;'>Std</th></tr><tr><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right; background-color: lightgray;'>testLabel</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>3</td><td style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>2</td><td style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>0.89</td><td class='' style='background-color: rgba(255, 0, 0, 1.8); border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>-90 %</td><td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>30<td class='' style='border-top: 1px dotted gray; border-right: 1px dotted gray; text-align: right;'>20<td class='' style='border-top: 1px dotted gray; border-right: 2px solid black; text-align: right;'>8.94</td><td></td><td></td><td></td><td></td></tr></table><i style='font-family: arial; font-size: 12px'>Note: Higher values are better. Maximum is the best-case performance.</i><br><br>
\ No newline at end of file |