// Copyright 2022 Google LLC.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Code generated file. DO NOT EDIT.

// Package testing provides access to the Cloud Testing API.
//
// For product documentation, see: https://developers.google.com/cloud-test-lab/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/testing/v1"
//   ...
//   ctx := context.Background()
//   testingService, err := testing.NewService(ctx)
//
// In this example, Google Application Default Credentials are used for authentication.
//
// For information on how to create and obtain Application Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials.
//
// Other authentication options
//
// By default, all available scopes (see "Constants") are used to authenticate. To restrict scopes, use option.WithScopes:
//
//   testingService, err := testing.NewService(ctx, option.WithScopes(testing.CloudPlatformReadOnlyScope))
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   testingService, err := testing.NewService(ctx, option.WithAPIKey("AIza..."))
//
// To use an OAuth token (e.g., a user token obtained via a three-legged OAuth flow), use option.WithTokenSource:
//
//   config := &oauth2.Config{...}
//   // ...
//   token, err := config.Exchange(ctx, ...)
//   testingService, err := testing.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package testing // import "google.golang.org/api/testing/v1"

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"strings"

	googleapi "google.golang.org/api/googleapi"
	internal "google.golang.org/api/internal"
	gensupport "google.golang.org/api/internal/gensupport"
	option "google.golang.org/api/option"
	internaloption "google.golang.org/api/option/internaloption"
	htransport "google.golang.org/api/transport/http"
)

// Always reference these packages, just in case the auto-generated code
// below doesn't.
var _ = bytes.NewBuffer
var _ = strconv.Itoa
var _ = fmt.Sprintf
var _ = json.NewDecoder
var _ = io.Copy
var _ = url.Parse
var _ = gensupport.MarshalJSON
var _ = googleapi.Version
var _ = errors.New
var _ = strings.Replace
var _ = context.Canceled
var _ = internaloption.WithDefaultEndpoint

const apiId = "testing:v1"
const apiName = "testing"
const apiVersion = "v1"
const basePath = "https://testing.googleapis.com/"
const mtlsBasePath = "https://testing.mtls.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// See, edit, configure, and delete your Google Cloud data and see the
	// email address for your Google Account.
	CloudPlatformScope = "https://www.googleapis.com/auth/cloud-platform"

	// View your data across Google Cloud services and see the email address
	// of your Google Account
	CloudPlatformReadOnlyScope = "https://www.googleapis.com/auth/cloud-platform.read-only"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := internaloption.WithDefaultScopes(
		"https://www.googleapis.com/auth/cloud-platform",
		"https://www.googleapis.com/auth/cloud-platform.read-only",
	)
	// NOTE: prepend, so we don't override user-specified scopes.
	opts = append([]option.ClientOption{scopesOption}, opts...)
	opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
	opts = append(opts, internaloption.WithDefaultMTLSEndpoint(mtlsBasePath))
	client, endpoint, err := htransport.NewClient(ctx, opts...)
	if err != nil {
		return nil, err
	}
	s, err := New(client)
	if err != nil {
		return nil, err
	}
	if endpoint != "" {
		s.BasePath = endpoint
	}
	return s, nil
}

// New creates a new Service. It uses the provided http.Client for requests.
//
// Deprecated: please use NewService instead.
// To provide a custom HTTP client, use option.WithHTTPClient.
// If you are using google.golang.org/api/googleapis/transport.APIKey, use option.WithAPIKey with NewService instead.
func New(client *http.Client) (*Service, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	s := &Service{client: client, BasePath: basePath}
	s.ApplicationDetailService = NewApplicationDetailServiceService(s)
	s.Projects = NewProjectsService(s)
	s.TestEnvironmentCatalog = NewTestEnvironmentCatalogService(s)
	return s, nil
}

type Service struct {
	client    *http.Client
	BasePath  string // API endpoint base URL
	UserAgent string // optional additional User-Agent fragment

	ApplicationDetailService *ApplicationDetailServiceService

	Projects *ProjectsService

	TestEnvironmentCatalog *TestEnvironmentCatalogService
}

func (s *Service) userAgent() string {
	if s.UserAgent == "" {
		return googleapi.UserAgent
	}
	return googleapi.UserAgent + " " + s.UserAgent
}

func NewApplicationDetailServiceService(s *Service) *ApplicationDetailServiceService {
	rs := &ApplicationDetailServiceService{s: s}
	return rs
}

type ApplicationDetailServiceService struct {
	s *Service
}

func NewProjectsService(s *Service) *ProjectsService {
	rs := &ProjectsService{s: s}
	rs.TestMatrices = NewProjectsTestMatricesService(s)
	return rs
}

type ProjectsService struct {
	s *Service

	TestMatrices *ProjectsTestMatricesService
}

func NewProjectsTestMatricesService(s *Service) *ProjectsTestMatricesService {
	rs := &ProjectsTestMatricesService{s: s}
	return rs
}

type ProjectsTestMatricesService struct {
	s *Service
}

func NewTestEnvironmentCatalogService(s *Service) *TestEnvironmentCatalogService {
	rs := &TestEnvironmentCatalogService{s: s}
	return rs
}

type TestEnvironmentCatalogService struct {
	s *Service
}

// Account: Identifies an account and how to log into it.
type Account struct {
	// GoogleAuto: An automatic google login account.
	GoogleAuto *GoogleAuto `json:"googleAuto,omitempty"`

	// ForceSendFields is a list of field names (e.g. "GoogleAuto") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "GoogleAuto") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Account) MarshalJSON() ([]byte, error) {
	type NoMethod Account
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AndroidDevice: A single Android device.
type AndroidDevice struct {
	// AndroidModelId: Required. The id of the Android device to be used.
	// Use the TestEnvironmentDiscoveryService to get supported options.
	AndroidModelId string `json:"androidModelId,omitempty"`

	// AndroidVersionId: Required. The id of the Android OS version to be
	// used. Use the TestEnvironmentDiscoveryService to get supported
	// options.
	AndroidVersionId string `json:"androidVersionId,omitempty"`

	// Locale: Required. The locale the test device used for testing. Use
	// the TestEnvironmentDiscoveryService to get supported options.
	Locale string `json:"locale,omitempty"`

	// Orientation: Required. How the device is oriented during the test.
	// Use the TestEnvironmentDiscoveryService to get supported options.
	Orientation string `json:"orientation,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AndroidModelId") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AndroidModelId") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *AndroidDevice) MarshalJSON() ([]byte, error) {
	type NoMethod AndroidDevice
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AndroidDeviceCatalog: The currently supported Android devices.
type AndroidDeviceCatalog struct {
	// Models: The set of supported Android device models.
	Models []*AndroidModel `json:"models,omitempty"`

	// RuntimeConfiguration: The set of supported runtime configurations.
	RuntimeConfiguration *AndroidRuntimeConfiguration `json:"runtimeConfiguration,omitempty"`

	// Versions: The set of supported Android OS versions.
	Versions []*AndroidVersion `json:"versions,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Models") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Models") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AndroidDeviceCatalog) MarshalJSON() ([]byte, error) {
	type NoMethod AndroidDeviceCatalog
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AndroidDeviceList: A list of Android device configurations in which
// the test is to be executed.
type AndroidDeviceList struct {
	// AndroidDevices: Required. A list of Android devices.
	AndroidDevices []*AndroidDevice `json:"androidDevices,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AndroidDevices") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AndroidDevices") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *AndroidDeviceList) MarshalJSON() ([]byte, error) {
	type NoMethod AndroidDeviceList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AndroidInstrumentationTest: A test of an Android application that can
// control an Android component independently of its normal lifecycle.
// Android instrumentation tests run an application APK and test APK
// inside the same process on a virtual or physical AndroidDevice. They
// also specify a test runner class, such as
// com.google.GoogleTestRunner, which can vary on the specific
// instrumentation framework chosen. See for more information on types
// of Android tests.
type AndroidInstrumentationTest struct {
	// AppApk: The APK for the application under test.
	AppApk *FileReference `json:"appApk,omitempty"`

	// AppBundle: A multi-apk app bundle for the application under test.
	AppBundle *AppBundle `json:"appBundle,omitempty"`

	// AppPackageId: The java package for the application under test. The
	// default value is determined by examining the application's manifest.
	AppPackageId string `json:"appPackageId,omitempty"`

	// OrchestratorOption: The option of whether running each test within
	// its own invocation of instrumentation with Android Test Orchestrator
	// or not. ** Orchestrator is only compatible with AndroidJUnitRunner
	// version 1.1 or higher! ** Orchestrator offers the following benefits:
	// - No shared state - Crashes are isolated - Logs are scoped per test
	// See for more information about Android Test Orchestrator. If not set,
	// the test will be run without the orchestrator.
	//
	// Possible values:
	//   "ORCHESTRATOR_OPTION_UNSPECIFIED" - Default value: the server will
	// choose the mode. Currently implies that the test will run without the
	// orchestrator. In the future, all instrumentation tests will be run
	// with the orchestrator. Using the orchestrator is highly encouraged
	// because of all the benefits it offers.
	//   "USE_ORCHESTRATOR" - Run test using orchestrator. ** Only
	// compatible with AndroidJUnitRunner version 1.1 or higher! **
	// Recommended.
	//   "DO_NOT_USE_ORCHESTRATOR" - Run test without using orchestrator.
	OrchestratorOption string `json:"orchestratorOption,omitempty"`

	// ShardingOption: The option to run tests in multiple shards in
	// parallel.
	ShardingOption *ShardingOption `json:"shardingOption,omitempty"`

	// TestApk: Required. The APK containing the test code to be executed.
	TestApk *FileReference `json:"testApk,omitempty"`

	// TestPackageId: The java package for the test to be executed. The
	// default value is determined by examining the application's manifest.
	TestPackageId string `json:"testPackageId,omitempty"`

	// TestRunnerClass: The InstrumentationTestRunner class. The default
	// value is determined by examining the application's manifest.
	TestRunnerClass string `json:"testRunnerClass,omitempty"`

	// TestTargets: Each target must be fully qualified with the package
	// name or class name, in one of these formats: - "package package_name"
	// - "class package_name.class_name" - "class
	// package_name.class_name#method_name" If empty, all targets in the
	// module will be run.
	TestTargets []string `json:"testTargets,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AppApk") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AppApk") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AndroidInstrumentationTest) MarshalJSON() ([]byte, error) {
	type NoMethod AndroidInstrumentationTest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AndroidMatrix: A set of Android device configuration permutations is
// defined by the the cross-product of the given axes. Internally, the
// given AndroidMatrix will be expanded into a set of AndroidDevices.
// Only supported permutations will be instantiated. Invalid
// permutations (e.g., incompatible models/versions) are ignored.
type AndroidMatrix struct {
	// AndroidModelIds: Required. The ids of the set of Android device to be
	// used. Use the TestEnvironmentDiscoveryService to get supported
	// options.
	AndroidModelIds []string `json:"androidModelIds,omitempty"`

	// AndroidVersionIds: Required. The ids of the set of Android OS version
	// to be used. Use the TestEnvironmentDiscoveryService to get supported
	// options.
	AndroidVersionIds []string `json:"androidVersionIds,omitempty"`

	// Locales: Required. The set of locales the test device will enable for
	// testing. Use the TestEnvironmentDiscoveryService to get supported
	// options.
	Locales []string `json:"locales,omitempty"`

	// Orientations: Required. The set of orientations to test with. Use the
	// TestEnvironmentDiscoveryService to get supported options.
	Orientations []string `json:"orientations,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AndroidModelIds") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AndroidModelIds") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *AndroidMatrix) MarshalJSON() ([]byte, error) {
	type NoMethod AndroidMatrix
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AndroidModel: A description of an Android device tests may be run on.
type AndroidModel struct {
	// Brand: The company that this device is branded with. Example:
	// "Google", "Samsung".
	Brand string `json:"brand,omitempty"`

	// Codename: The name of the industrial design. This corresponds to
	// android.os.Build.DEVICE.
	Codename string `json:"codename,omitempty"`

	// Form: Whether this device is virtual or physical.
	//
	// Possible values:
	//   "DEVICE_FORM_UNSPECIFIED" - Do not use. For proto versioning only.
	//   "VIRTUAL" - Android virtual device using Compute Engine native
	// virtualization. Firebase Test Lab only.
	//   "PHYSICAL" - Actual hardware.
	//   "EMULATOR" - Android virtual device using emulator in nested
	// virtualization. Equivalent to Android Studio.
	Form string `json:"form,omitempty"`

	// FormFactor: Whether this device is a phone, tablet, wearable, etc.
	//
	// Possible values:
	//   "DEVICE_FORM_FACTOR_UNSPECIFIED" - Do not use. For proto versioning
	// only.
	//   "PHONE" - This device has the shape of a phone.
	//   "TABLET" - This device has the shape of a tablet.
	//   "WEARABLE" - This device has the shape of a watch or other
	// wearable.
	FormFactor string `json:"formFactor,omitempty"`

	// Id: The unique opaque id for this model. Use this for invoking the
	// TestExecutionService.
	Id string `json:"id,omitempty"`

	// LowFpsVideoRecording: True if and only if tests with this model are
	// recorded by stitching together screenshots. See
	// use_low_spec_video_recording in device config.
	LowFpsVideoRecording bool `json:"lowFpsVideoRecording,omitempty"`

	// Manufacturer: The manufacturer of this device.
	Manufacturer string `json:"manufacturer,omitempty"`

	// Name: The human-readable marketing name for this device model.
	// Examples: "Nexus 5", "Galaxy S5".
	Name string `json:"name,omitempty"`

	// ScreenDensity: Screen density in DPI. This corresponds to
	// ro.sf.lcd_density
	ScreenDensity int64 `json:"screenDensity,omitempty"`

	// ScreenX: Screen size in the horizontal (X) dimension measured in
	// pixels.
	ScreenX int64 `json:"screenX,omitempty"`

	// ScreenY: Screen size in the vertical (Y) dimension measured in
	// pixels.
	ScreenY int64 `json:"screenY,omitempty"`

	// SupportedAbis: The list of supported ABIs for this device. This
	// corresponds to either android.os.Build.SUPPORTED_ABIS (for API level
	// 21 and above) or android.os.Build.CPU_ABI/CPU_ABI2. The most
	// preferred ABI is the first element in the list. Elements are
	// optionally prefixed by "version_id:" (where version_id is the id of
	// an AndroidVersion), denoting an ABI that is supported only on a
	// particular version.
	SupportedAbis []string `json:"supportedAbis,omitempty"`

	// SupportedVersionIds: The set of Android versions this device
	// supports.
	SupportedVersionIds []string `json:"supportedVersionIds,omitempty"`

	// Tags: Tags for this dimension. Examples: "default", "preview",
	// "deprecated".
	Tags []string `json:"tags,omitempty"`

	// ThumbnailUrl: URL of a thumbnail image (photo) of the device.
	ThumbnailUrl string `json:"thumbnailUrl,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Brand") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Brand") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AndroidModel) MarshalJSON() ([]byte, error) {
	type NoMethod AndroidModel
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AndroidRoboTest: A test of an android application that explores the
// application on a virtual or physical Android Device, finding culprits
// and crashes as it goes.
type AndroidRoboTest struct {
	// AppApk: The APK for the application under test.
	AppApk *FileReference `json:"appApk,omitempty"`

	// AppBundle: A multi-apk app bundle for the application under test.
	AppBundle *AppBundle `json:"appBundle,omitempty"`

	// AppInitialActivity: The initial activity that should be used to start
	// the app.
	AppInitialActivity string `json:"appInitialActivity,omitempty"`

	// AppPackageId: The java package for the application under test. The
	// default value is determined by examining the application's manifest.
	AppPackageId string `json:"appPackageId,omitempty"`

	// MaxDepth: The max depth of the traversal stack Robo can explore.
	// Needs to be at least 2 to make Robo explore the app beyond the first
	// activity. Default is 50.
	MaxDepth int64 `json:"maxDepth,omitempty"`

	// MaxSteps: The max number of steps Robo can execute. Default is no
	// limit.
	MaxSteps int64 `json:"maxSteps,omitempty"`

	// RoboDirectives: A set of directives Robo should apply during the
	// crawl. This allows users to customize the crawl. For example, the
	// username and password for a test account can be provided.
	RoboDirectives []*RoboDirective `json:"roboDirectives,omitempty"`

	// RoboMode: The mode in which Robo should run. Most clients should
	// allow the server to populate this field automatically.
	//
	// Possible values:
	//   "ROBO_MODE_UNSPECIFIED" - This means that the server should choose
	// the mode. Recommended.
	//   "ROBO_VERSION_1" - Runs Robo in UIAutomator-only mode without app
	// resigning
	//   "ROBO_VERSION_2" - Runs Robo in standard Espresso with UIAutomator
	// fallback
	RoboMode string `json:"roboMode,omitempty"`

	// RoboScript: A JSON file with a sequence of actions Robo should
	// perform as a prologue for the crawl.
	RoboScript *FileReference `json:"roboScript,omitempty"`

	// StartingIntents: The intents used to launch the app for the crawl. If
	// none are provided, then the main launcher activity is launched. If
	// some are provided, then only those provided are launched (the main
	// launcher activity must be provided explicitly).
	StartingIntents []*RoboStartingIntent `json:"startingIntents,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AppApk") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AppApk") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AndroidRoboTest) MarshalJSON() ([]byte, error) {
	type NoMethod AndroidRoboTest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AndroidRuntimeConfiguration: Android configuration that can be
// selected at the time a test is run.
type AndroidRuntimeConfiguration struct {
	// Locales: The set of available locales.
	Locales []*Locale `json:"locales,omitempty"`

	// Orientations: The set of available orientations.
	Orientations []*Orientation `json:"orientations,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Locales") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Locales") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AndroidRuntimeConfiguration) MarshalJSON() ([]byte, error) {
	type NoMethod AndroidRuntimeConfiguration
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AndroidTestLoop: A test of an Android Application with a Test Loop.
// The intent \ will be implicitly added, since Games is the only user
// of this api, for the time being.
type AndroidTestLoop struct {
	// AppApk: The APK for the application under test.
	AppApk *FileReference `json:"appApk,omitempty"`

	// AppBundle: A multi-apk app bundle for the application under test.
	AppBundle *AppBundle `json:"appBundle,omitempty"`

	// AppPackageId: The java package for the application under test. The
	// default is determined by examining the application's manifest.
	AppPackageId string `json:"appPackageId,omitempty"`

	// ScenarioLabels: The list of scenario labels that should be run during
	// the test. The scenario labels should map to labels defined in the
	// application's manifest. For example, player_experience and
	// com.google.test.loops.player_experience add all of the loops labeled
	// in the manifest with the com.google.test.loops.player_experience name
	// to the execution. Scenarios can also be specified in the scenarios
	// field.
	ScenarioLabels []string `json:"scenarioLabels,omitempty"`

	// Scenarios: The list of scenarios that should be run during the test.
	// The default is all test loops, derived from the application's
	// manifest.
	Scenarios []int64 `json:"scenarios,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AppApk") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AppApk") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AndroidTestLoop) MarshalJSON() ([]byte, error) {
	type NoMethod AndroidTestLoop
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AndroidVersion: A version of the Android OS.
type AndroidVersion struct {
	// ApiLevel: The API level for this Android version. Examples: 18, 19.
	ApiLevel int64 `json:"apiLevel,omitempty"`

	// CodeName: The code name for this Android version. Examples:
	// "JellyBean", "KitKat".
	CodeName string `json:"codeName,omitempty"`

	// Distribution: Market share for this version.
	Distribution *Distribution `json:"distribution,omitempty"`

	// Id: An opaque id for this Android version. Use this id to invoke the
	// TestExecutionService.
	Id string `json:"id,omitempty"`

	// ReleaseDate: The date this Android version became available in the
	// market.
	ReleaseDate *Date `json:"releaseDate,omitempty"`

	// Tags: Tags for this dimension. Examples: "default", "preview",
	// "deprecated".
	Tags []string `json:"tags,omitempty"`

	// VersionString: A string representing this version of the Android OS.
	// Examples: "4.3", "4.4".
	VersionString string `json:"versionString,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ApiLevel") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ApiLevel") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *AndroidVersion) MarshalJSON() ([]byte, error) {
	type NoMethod AndroidVersion
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Apk: An Android package file to install.
type Apk struct {
	// Location: The path to an APK to be installed on the device before the
	// test begins.
	Location *FileReference `json:"location,omitempty"`

	// PackageName: The java package for the APK to be installed. Value is
	// determined by examining the application's manifest.
	PackageName string `json:"packageName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Location") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Location") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Apk) MarshalJSON() ([]byte, error) {
	type NoMethod Apk
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ApkDetail: Android application details based on application manifest
// and apk archive contents.
type ApkDetail struct {
	ApkManifest *ApkManifest `json:"apkManifest,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ApkManifest") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ApkManifest") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ApkDetail) MarshalJSON() ([]byte, error) {
	type NoMethod ApkDetail
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ApkManifest: An Android app manifest. See
// http://developer.android.com/guide/topics/manifest/manifest-intro.html
type ApkManifest struct {
	// ApplicationLabel: User-readable name for the application.
	ApplicationLabel string `json:"applicationLabel,omitempty"`

	IntentFilters []*IntentFilter `json:"intentFilters,omitempty"`

	// MaxSdkVersion: Maximum API level on which the application is designed
	// to run.
	MaxSdkVersion int64 `json:"maxSdkVersion,omitempty"`

	// MinSdkVersion: Minimum API level required for the application to run.
	MinSdkVersion int64 `json:"minSdkVersion,omitempty"`

	// PackageName: Full Java-style package name for this application, e.g.
	// "com.example.foo".
	PackageName string `json:"packageName,omitempty"`

	// TargetSdkVersion: Specifies the API Level on which the application is
	// designed to run.
	TargetSdkVersion int64 `json:"targetSdkVersion,omitempty"`

	// UsesPermission: Permissions declared to be used by the application
	UsesPermission []string `json:"usesPermission,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ApplicationLabel") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ApplicationLabel") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *ApkManifest) MarshalJSON() ([]byte, error) {
	type NoMethod ApkManifest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// AppBundle: An Android App Bundle file format, containing a
// BundleConfig.pb file, a base module directory, zero or more dynamic
// feature module directories. See
// https://developer.android.com/guide/app-bundle/build for guidance on
// building App Bundles.
type AppBundle struct {
	// BundleLocation: .aab file representing the app bundle under test.
	BundleLocation *FileReference `json:"bundleLocation,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BundleLocation") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "BundleLocation") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *AppBundle) MarshalJSON() ([]byte, error) {
	type NoMethod AppBundle
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// CancelTestMatrixResponse: Response containing the current state of
// the specified test matrix.
type CancelTestMatrixResponse struct {
	// TestState: The current rolled-up state of the test matrix. If this
	// state is already final, then the cancelation request will have no
	// effect.
	//
	// Possible values:
	//   "TEST_STATE_UNSPECIFIED" - Do not use. For proto versioning only.
	//   "VALIDATING" - The execution or matrix is being validated.
	//   "PENDING" - The execution or matrix is waiting for resources to
	// become available.
	//   "RUNNING" - The execution is currently being processed. Can only be
	// set on an execution.
	//   "FINISHED" - The execution or matrix has terminated normally. On a
	// matrix this means that the matrix level processing completed
	// normally, but individual executions may be in an ERROR state.
	//   "ERROR" - The execution or matrix has stopped because it
	// encountered an infrastructure failure.
	//   "UNSUPPORTED_ENVIRONMENT" - The execution was not run because it
	// corresponds to a unsupported environment. Can only be set on an
	// execution.
	//   "INCOMPATIBLE_ENVIRONMENT" - The execution was not run because the
	// provided inputs are incompatible with the requested environment.
	// Example: requested AndroidVersion is lower than APK's minSdkVersion
	// Can only be set on an execution.
	//   "INCOMPATIBLE_ARCHITECTURE" - The execution was not run because the
	// provided inputs are incompatible with the requested architecture.
	// Example: requested device does not support running the native code in
	// the supplied APK Can only be set on an execution.
	//   "CANCELLED" - The user cancelled the execution. Can only be set on
	// an execution.
	//   "INVALID" - The execution or matrix was not run because the
	// provided inputs are not valid. Examples: input file is not of the
	// expected type, is malformed/corrupt, or was flagged as malware
	TestState string `json:"testState,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "TestState") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "TestState") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *CancelTestMatrixResponse) MarshalJSON() ([]byte, error) {
	type NoMethod CancelTestMatrixResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ClientInfo: Information about the client which invoked the test.
type ClientInfo struct {
	// ClientInfoDetails: The list of detailed information about client.
	ClientInfoDetails []*ClientInfoDetail `json:"clientInfoDetails,omitempty"`

	// Name: Required. Client name, such as gcloud.
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ClientInfoDetails")
	// to unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ClientInfoDetails") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *ClientInfo) MarshalJSON() ([]byte, error) {
	type NoMethod ClientInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ClientInfoDetail: Key-value pair of detailed information about the
// client which invoked the test. Examples: {'Version', '1.0'},
// {'Release Track', 'BETA'}.
type ClientInfoDetail struct {
	// Key: Required. The key of detailed client information.
	Key string `json:"key,omitempty"`

	// Value: Required. The value of detailed client information.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ClientInfoDetail) MarshalJSON() ([]byte, error) {
	type NoMethod ClientInfoDetail
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Date: Represents a whole or partial calendar date, such as a
// birthday. The time of day and time zone are either specified
// elsewhere or are insignificant. The date is relative to the Gregorian
// Calendar. This can represent one of the following: * A full date,
// with non-zero year, month, and day values. * A month and day, with a
// zero year (for example, an anniversary). * A year on its own, with a
// zero month and a zero day. * A year and month, with a zero day (for
// example, a credit card expiration date). Related types: *
// google.type.TimeOfDay * google.type.DateTime *
// google.protobuf.Timestamp
type Date struct {
	// Day: Day of a month. Must be from 1 to 31 and valid for the year and
	// month, or 0 to specify a year by itself or a year and month where the
	// day isn't significant.
	Day int64 `json:"day,omitempty"`

	// Month: Month of a year. Must be from 1 to 12, or 0 to specify a year
	// without a month and day.
	Month int64 `json:"month,omitempty"`

	// Year: Year of the date. Must be from 1 to 9999, or 0 to specify a
	// date without a year.
	Year int64 `json:"year,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Day") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Day") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Date) MarshalJSON() ([]byte, error) {
	type NoMethod Date
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DeviceFile: A single device file description.
type DeviceFile struct {
	// ObbFile: A reference to an opaque binary blob file.
	ObbFile *ObbFile `json:"obbFile,omitempty"`

	// RegularFile: A reference to a regular file.
	RegularFile *RegularFile `json:"regularFile,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ObbFile") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ObbFile") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DeviceFile) MarshalJSON() ([]byte, error) {
	type NoMethod DeviceFile
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DeviceIpBlock: A single device IP block
type DeviceIpBlock struct {
	// AddedDate: The date this block was added to Firebase Test Lab
	AddedDate *Date `json:"addedDate,omitempty"`

	// Block: An IP address block in CIDR notation eg: 34.68.194.64/29
	Block string `json:"block,omitempty"`

	// Form: Whether this block is used by physical or virtual devices
	//
	// Possible values:
	//   "DEVICE_FORM_UNSPECIFIED" - Do not use. For proto versioning only.
	//   "VIRTUAL" - Android virtual device using Compute Engine native
	// virtualization. Firebase Test Lab only.
	//   "PHYSICAL" - Actual hardware.
	//   "EMULATOR" - Android virtual device using emulator in nested
	// virtualization. Equivalent to Android Studio.
	Form string `json:"form,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AddedDate") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AddedDate") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DeviceIpBlock) MarshalJSON() ([]byte, error) {
	type NoMethod DeviceIpBlock
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// DeviceIpBlockCatalog: List of IP blocks used by the Firebase Test Lab
type DeviceIpBlockCatalog struct {
	// IpBlocks: The device IP blocks used by Firebase Test Lab
	IpBlocks []*DeviceIpBlock `json:"ipBlocks,omitempty"`

	// ForceSendFields is a list of field names (e.g. "IpBlocks") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "IpBlocks") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *DeviceIpBlockCatalog) MarshalJSON() ([]byte, error) {
	type NoMethod DeviceIpBlockCatalog
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Distribution: Data about the relative number of devices running a
// given configuration of the Android platform.
type Distribution struct {
	// MarketShare: Output only. The estimated fraction (0-1) of the total
	// market with this configuration.
	MarketShare float64 `json:"marketShare,omitempty"`

	// MeasurementTime: Output only. The time this distribution was
	// measured.
	MeasurementTime string `json:"measurementTime,omitempty"`

	// ForceSendFields is a list of field names (e.g. "MarketShare") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "MarketShare") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Distribution) MarshalJSON() ([]byte, error) {
	type NoMethod Distribution
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *Distribution) UnmarshalJSON(data []byte) error {
	type NoMethod Distribution
	var s1 struct {
		MarketShare gensupport.JSONFloat64 `json:"marketShare"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.MarketShare = float64(s1.MarketShare)
	return nil
}

// Environment: The environment in which the test is run.
type Environment struct {
	// AndroidDevice: An Android device which must be used with an Android
	// test.
	AndroidDevice *AndroidDevice `json:"androidDevice,omitempty"`

	// IosDevice: An iOS device which must be used with an iOS test.
	IosDevice *IosDevice `json:"iosDevice,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AndroidDevice") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AndroidDevice") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Environment) MarshalJSON() ([]byte, error) {
	type NoMethod Environment
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// EnvironmentMatrix: The matrix of environments in which the test is to
// be executed.
type EnvironmentMatrix struct {
	// AndroidDeviceList: A list of Android devices; the test will be run
	// only on the specified devices.
	AndroidDeviceList *AndroidDeviceList `json:"androidDeviceList,omitempty"`

	// AndroidMatrix: A matrix of Android devices.
	AndroidMatrix *AndroidMatrix `json:"androidMatrix,omitempty"`

	// IosDeviceList: A list of iOS devices.
	IosDeviceList *IosDeviceList `json:"iosDeviceList,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AndroidDeviceList")
	// to unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AndroidDeviceList") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *EnvironmentMatrix) MarshalJSON() ([]byte, error) {
	type NoMethod EnvironmentMatrix
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// EnvironmentVariable: A key-value pair passed as an environment
// variable to the test.
type EnvironmentVariable struct {
	// Key: Key for the environment variable.
	Key string `json:"key,omitempty"`

	// Value: Value for the environment variable.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Key") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Key") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *EnvironmentVariable) MarshalJSON() ([]byte, error) {
	type NoMethod EnvironmentVariable
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// FileReference: A reference to a file, used for user inputs.
type FileReference struct {
	// GcsPath: A path to a file in Google Cloud Storage. Example:
	// gs://build-app-1414623860166/app%40debug-unaligned.apk These paths
	// are expected to be url encoded (percent encoding)
	GcsPath string `json:"gcsPath,omitempty"`

	// ForceSendFields is a list of field names (e.g. "GcsPath") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "GcsPath") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *FileReference) MarshalJSON() ([]byte, error) {
	type NoMethod FileReference
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GetApkDetailsResponse: Response containing the details of the
// specified Android application APK.
type GetApkDetailsResponse struct {
	// ApkDetail: Details of the Android APK.
	ApkDetail *ApkDetail `json:"apkDetail,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "ApkDetail") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ApkDetail") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GetApkDetailsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GetApkDetailsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleAuto: Enables automatic Google account login. If set, the
// service automatically generates a Google test account and adds it to
// the device, before executing the test. Note that test accounts might
// be reused. Many applications show their full set of functionalities
// when an account is present on the device. Logging into the device
// with these generated accounts allows testing more functionalities.
type GoogleAuto struct {
}

// GoogleCloudStorage: A storage location within Google cloud storage
// (GCS).
type GoogleCloudStorage struct {
	// GcsPath: Required. The path to a directory in GCS that will
	// eventually contain the results for this test. The requesting user
	// must have write access on the bucket in the supplied path.
	GcsPath string `json:"gcsPath,omitempty"`

	// ForceSendFields is a list of field names (e.g. "GcsPath") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "GcsPath") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleCloudStorage) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudStorage
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// IntentFilter: The section of an tag.
// https://developer.android.com/guide/topics/manifest/intent-filter-element.html
type IntentFilter struct {
	// ActionNames: The android:name value of the tag.
	ActionNames []string `json:"actionNames,omitempty"`

	// CategoryNames: The android:name value of the tag.
	CategoryNames []string `json:"categoryNames,omitempty"`

	// MimeType: The android:mimeType value of the tag.
	MimeType string `json:"mimeType,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ActionNames") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ActionNames") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *IntentFilter) MarshalJSON() ([]byte, error) {
	type NoMethod IntentFilter
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// IosDevice: A single iOS device.
type IosDevice struct {
	// IosModelId: Required. The id of the iOS device to be used. Use the
	// TestEnvironmentDiscoveryService to get supported options.
	IosModelId string `json:"iosModelId,omitempty"`

	// IosVersionId: Required. The id of the iOS major software version to
	// be used. Use the TestEnvironmentDiscoveryService to get supported
	// options.
	IosVersionId string `json:"iosVersionId,omitempty"`

	// Locale: Required. The locale the test device used for testing. Use
	// the TestEnvironmentDiscoveryService to get supported options.
	Locale string `json:"locale,omitempty"`

	// Orientation: Required. How the device is oriented during the test.
	// Use the TestEnvironmentDiscoveryService to get supported options.
	Orientation string `json:"orientation,omitempty"`

	// ForceSendFields is a list of field names (e.g. "IosModelId") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "IosModelId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *IosDevice) MarshalJSON() ([]byte, error) {
	type NoMethod IosDevice
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// IosDeviceCatalog: The currently supported iOS devices.
type IosDeviceCatalog struct {
	// Models: The set of supported iOS device models.
	Models []*IosModel `json:"models,omitempty"`

	// RuntimeConfiguration: The set of supported runtime configurations.
	RuntimeConfiguration *IosRuntimeConfiguration `json:"runtimeConfiguration,omitempty"`

	// Versions: The set of supported iOS software versions.
	Versions []*IosVersion `json:"versions,omitempty"`

	// XcodeVersions: The set of supported Xcode versions.
	XcodeVersions []*XcodeVersion `json:"xcodeVersions,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Models") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Models") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *IosDeviceCatalog) MarshalJSON() ([]byte, error) {
	type NoMethod IosDeviceCatalog
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// IosDeviceFile: A file or directory to install on the device before
// the test starts.
type IosDeviceFile struct {
	// BundleId: The bundle id of the app where this file lives. iOS apps
	// sandbox their own filesystem, so app files must specify which app
	// installed on the device.
	BundleId string `json:"bundleId,omitempty"`

	// Content: The source file
	Content *FileReference `json:"content,omitempty"`

	// DevicePath: Location of the file on the device, inside the app's
	// sandboxed filesystem
	DevicePath string `json:"devicePath,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BundleId") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "BundleId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *IosDeviceFile) MarshalJSON() ([]byte, error) {
	type NoMethod IosDeviceFile
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// IosDeviceList: A list of iOS device configurations in which the test
// is to be executed.
type IosDeviceList struct {
	// IosDevices: Required. A list of iOS devices.
	IosDevices []*IosDevice `json:"iosDevices,omitempty"`

	// ForceSendFields is a list of field names (e.g. "IosDevices") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "IosDevices") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *IosDeviceList) MarshalJSON() ([]byte, error) {
	type NoMethod IosDeviceList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// IosModel: A description of an iOS device tests may be run on.
type IosModel struct {
	// DeviceCapabilities: Device capabilities. Copied from
	// https://developer.apple.com/library/archive/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/DeviceCompatibilityMatrix/DeviceCompatibilityMatrix.html
	DeviceCapabilities []string `json:"deviceCapabilities,omitempty"`

	// FormFactor: Whether this device is a phone, tablet, wearable, etc.
	//
	// Possible values:
	//   "DEVICE_FORM_FACTOR_UNSPECIFIED" - Do not use. For proto versioning
	// only.
	//   "PHONE" - This device has the shape of a phone.
	//   "TABLET" - This device has the shape of a tablet.
	//   "WEARABLE" - This device has the shape of a watch or other
	// wearable.
	FormFactor string `json:"formFactor,omitempty"`

	// Id: The unique opaque id for this model. Use this for invoking the
	// TestExecutionService.
	Id string `json:"id,omitempty"`

	// Name: The human-readable name for this device model. Examples:
	// "iPhone 4s", "iPad Mini 2".
	Name string `json:"name,omitempty"`

	// ScreenDensity: Screen density in DPI.
	ScreenDensity int64 `json:"screenDensity,omitempty"`

	// ScreenX: Screen size in the horizontal (X) dimension measured in
	// pixels.
	ScreenX int64 `json:"screenX,omitempty"`

	// ScreenY: Screen size in the vertical (Y) dimension measured in
	// pixels.
	ScreenY int64 `json:"screenY,omitempty"`

	// SupportedVersionIds: The set of iOS major software versions this
	// device supports.
	SupportedVersionIds []string `json:"supportedVersionIds,omitempty"`

	// Tags: Tags for this dimension. Examples: "default", "preview",
	// "deprecated".
	Tags []string `json:"tags,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DeviceCapabilities")
	// to unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DeviceCapabilities") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *IosModel) MarshalJSON() ([]byte, error) {
	type NoMethod IosModel
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// IosRuntimeConfiguration: iOS configuration that can be selected at
// the time a test is run.
type IosRuntimeConfiguration struct {
	// Locales: The set of available locales.
	Locales []*Locale `json:"locales,omitempty"`

	// Orientations: The set of available orientations.
	Orientations []*Orientation `json:"orientations,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Locales") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Locales") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *IosRuntimeConfiguration) MarshalJSON() ([]byte, error) {
	type NoMethod IosRuntimeConfiguration
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// IosTestLoop: A test of an iOS application that implements one or more
// game loop scenarios. This test type accepts an archived application
// (.ipa file) and a list of integer scenarios that will be executed on
// the app sequentially.
type IosTestLoop struct {
	// AppBundleId: Output only. The bundle id for the application under
	// test.
	AppBundleId string `json:"appBundleId,omitempty"`

	// AppIpa: Required. The .ipa of the application to test.
	AppIpa *FileReference `json:"appIpa,omitempty"`

	// Scenarios: The list of scenarios that should be run during the test.
	// Defaults to the single scenario 0 if unspecified.
	Scenarios []int64 `json:"scenarios,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AppBundleId") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AppBundleId") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *IosTestLoop) MarshalJSON() ([]byte, error) {
	type NoMethod IosTestLoop
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// IosTestSetup: A description of how to set up an iOS device prior to
// running the test.
type IosTestSetup struct {
	// AdditionalIpas: iOS apps to install in addition to those being
	// directly tested.
	AdditionalIpas []*FileReference `json:"additionalIpas,omitempty"`

	// NetworkProfile: The network traffic profile used for running the
	// test. Available network profiles can be queried by using the
	// NETWORK_CONFIGURATION environment type when calling
	// TestEnvironmentDiscoveryService.GetTestEnvironmentCatalog.
	NetworkProfile string `json:"networkProfile,omitempty"`

	// PullDirectories: List of directories on the device to upload to Cloud
	// Storage at the end of the test. Directories should either be in a
	// shared directory (such as /private/var/mobile/Media) or within an
	// accessible directory inside the app's filesystem (such as /Documents)
	// by specifying the bundle ID.
	PullDirectories []*IosDeviceFile `json:"pullDirectories,omitempty"`

	// PushFiles: List of files to push to the device before starting the
	// test.
	PushFiles []*IosDeviceFile `json:"pushFiles,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AdditionalIpas") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AdditionalIpas") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *IosTestSetup) MarshalJSON() ([]byte, error) {
	type NoMethod IosTestSetup
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// IosVersion: An iOS version.
type IosVersion struct {
	// Id: An opaque id for this iOS version. Use this id to invoke the
	// TestExecutionService.
	Id string `json:"id,omitempty"`

	// MajorVersion: An integer representing the major iOS version.
	// Examples: "8", "9".
	MajorVersion int64 `json:"majorVersion,omitempty"`

	// MinorVersion: An integer representing the minor iOS version.
	// Examples: "1", "2".
	MinorVersion int64 `json:"minorVersion,omitempty"`

	// SupportedXcodeVersionIds: The available Xcode versions for this
	// version.
	SupportedXcodeVersionIds []string `json:"supportedXcodeVersionIds,omitempty"`

	// Tags: Tags for this dimension. Examples: "default", "preview",
	// "deprecated".
	Tags []string `json:"tags,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *IosVersion) MarshalJSON() ([]byte, error) {
	type NoMethod IosVersion
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// IosXcTest: A test of an iOS application that uses the XCTest
// framework. Xcode supports the option to "build for testing", which
// generates an .xctestrun file that contains a test specification
// (arguments, test methods, etc). This test type accepts a zip file
// containing the .xctestrun file and the corresponding contents of the
// Build/Products directory that contains all the binaries needed to run
// the tests.
type IosXcTest struct {
	// AppBundleId: Output only. The bundle id for the application under
	// test.
	AppBundleId string `json:"appBundleId,omitempty"`

	// TestSpecialEntitlements: The option to test special app entitlements.
	// Setting this would re-sign the app having special entitlements with
	// an explicit application-identifier. Currently supports testing
	// aps-environment entitlement.
	TestSpecialEntitlements bool `json:"testSpecialEntitlements,omitempty"`

	// TestsZip: Required. The .zip containing the .xctestrun file and the
	// contents of the DerivedData/Build/Products directory. The .xctestrun
	// file in this zip is ignored if the xctestrun field is specified.
	TestsZip *FileReference `json:"testsZip,omitempty"`

	// XcodeVersion: The Xcode version that should be used for the test. Use
	// the TestEnvironmentDiscoveryService to get supported options.
	// Defaults to the latest Xcode version Firebase Test Lab supports.
	XcodeVersion string `json:"xcodeVersion,omitempty"`

	// Xctestrun: An .xctestrun file that will override the .xctestrun file
	// in the tests zip. Because the .xctestrun file contains environment
	// variables along with test methods to run and/or ignore, this can be
	// useful for sharding tests. Default is taken from the tests zip.
	Xctestrun *FileReference `json:"xctestrun,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AppBundleId") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AppBundleId") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *IosXcTest) MarshalJSON() ([]byte, error) {
	type NoMethod IosXcTest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LauncherActivityIntent: Specifies an intent that starts the main
// launcher activity.
type LauncherActivityIntent struct {
}

// Locale: A location/region designation for language.
type Locale struct {
	// Id: The id for this locale. Example: "en_US".
	Id string `json:"id,omitempty"`

	// Name: A human-friendly name for this language/locale. Example:
	// "English".
	Name string `json:"name,omitempty"`

	// Region: A human-friendly string representing the region for this
	// locale. Example: "United States". Not present for every locale.
	Region string `json:"region,omitempty"`

	// Tags: Tags for this dimension. Example: "default".
	Tags []string `json:"tags,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Locale) MarshalJSON() ([]byte, error) {
	type NoMethod Locale
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ManualSharding: Shards test cases into the specified groups of
// packages, classes, and/or methods. With manual sharding enabled,
// specifying test targets via environment_variables or in
// InstrumentationTest is invalid.
type ManualSharding struct {
	// TestTargetsForShard: Required. Group of packages, classes, and/or
	// test methods to be run for each shard. When any physical devices are
	// selected, the number of test_targets_for_shard must be >= 1 and <=
	// 50. When no physical devices are selected, the number must be >= 1
	// and <= 500.
	TestTargetsForShard []*TestTargetsForShard `json:"testTargetsForShard,omitempty"`

	// ForceSendFields is a list of field names (e.g. "TestTargetsForShard")
	// to unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "TestTargetsForShard") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *ManualSharding) MarshalJSON() ([]byte, error) {
	type NoMethod ManualSharding
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NetworkConfiguration struct {
	// DownRule: The emulation rule applying to the download traffic.
	DownRule *TrafficRule `json:"downRule,omitempty"`

	// Id: The unique opaque id for this network traffic configuration.
	Id string `json:"id,omitempty"`

	// UpRule: The emulation rule applying to the upload traffic.
	UpRule *TrafficRule `json:"upRule,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DownRule") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DownRule") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *NetworkConfiguration) MarshalJSON() ([]byte, error) {
	type NoMethod NetworkConfiguration
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type NetworkConfigurationCatalog struct {
	Configurations []*NetworkConfiguration `json:"configurations,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Configurations") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Configurations") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *NetworkConfigurationCatalog) MarshalJSON() ([]byte, error) {
	type NoMethod NetworkConfigurationCatalog
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ObbFile: An opaque binary blob file to install on the device before
// the test starts.
type ObbFile struct {
	// Obb: Required. Opaque Binary Blob (OBB) file(s) to install on the
	// device.
	Obb *FileReference `json:"obb,omitempty"`

	// ObbFileName: Required. OBB file name which must conform to the format
	// as specified by Android e.g.
	// [main|patch].0300110.com.example.android.obb which will be installed
	// into \/Android/obb/\/ on the device.
	ObbFileName string `json:"obbFileName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Obb") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Obb") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ObbFile) MarshalJSON() ([]byte, error) {
	type NoMethod ObbFile
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Orientation: Screen orientation of the device.
type Orientation struct {
	// Id: The id for this orientation. Example: "portrait".
	Id string `json:"id,omitempty"`

	// Name: A human-friendly name for this orientation. Example:
	// "portrait".
	Name string `json:"name,omitempty"`

	// Tags: Tags for this dimension. Example: "default".
	Tags []string `json:"tags,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Orientation) MarshalJSON() ([]byte, error) {
	type NoMethod Orientation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ProvidedSoftwareCatalog: The currently provided software environment
// on the devices under test.
type ProvidedSoftwareCatalog struct {
	// AndroidxOrchestratorVersion: A string representing the current
	// version of AndroidX Test Orchestrator that is used in the
	// environment. The package is available at
	// https://maven.google.com/web/index.html#androidx.test:orchestrator.
	AndroidxOrchestratorVersion string `json:"androidxOrchestratorVersion,omitempty"`

	// OrchestratorVersion: Deprecated: Use AndroidX Test Orchestrator going
	// forward. A string representing the current version of Android Test
	// Orchestrator that is used in the environment. The package is
	// available at
	// https://maven.google.com/web/index.html#com.android.support.test:orchestrator.
	OrchestratorVersion string `json:"orchestratorVersion,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "AndroidxOrchestratorVersion") to unconditionally include in API
	// requests. By default, fields with empty or default values are omitted
	// from API requests. However, any non-pointer, non-interface field
	// appearing in ForceSendFields will be sent to the server regardless of
	// whether the field is empty or not. This may be used to include empty
	// fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g.
	// "AndroidxOrchestratorVersion") to include in API requests with the
	// JSON null value. By default, fields with empty values are omitted
	// from API requests. However, any field with an empty value appearing
	// in NullFields will be sent to the server as null. It is an error if a
	// field in this list has a non-empty value. This may be used to include
	// null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ProvidedSoftwareCatalog) MarshalJSON() ([]byte, error) {
	type NoMethod ProvidedSoftwareCatalog
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RegularFile: A file or directory to install on the device before the
// test starts.
type RegularFile struct {
	// Content: Required. The source file.
	Content *FileReference `json:"content,omitempty"`

	// DevicePath: Required. Where to put the content on the device. Must be
	// an absolute, allowlisted path. If the file exists, it will be
	// replaced. The following device-side directories and any of their
	// subdirectories are allowlisted: ${EXTERNAL_STORAGE}, /sdcard, or
	// /storage ${ANDROID_DATA}/local/tmp, or /data/local/tmp Specifying a
	// path outside of these directory trees is invalid. The paths /sdcard
	// and /data will be made available and treated as implicit path
	// substitutions. E.g. if /sdcard on a particular device does not map to
	// external storage, the system will replace it with the external
	// storage path prefix for that device and copy the file there. It is
	// strongly advised to use the Environment API in app and test code to
	// access files on the device in a portable way.
	DevicePath string `json:"devicePath,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Content") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Content") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RegularFile) MarshalJSON() ([]byte, error) {
	type NoMethod RegularFile
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ResultStorage: Locations where the results of running the test are
// stored.
type ResultStorage struct {
	// GoogleCloudStorage: Required.
	GoogleCloudStorage *GoogleCloudStorage `json:"googleCloudStorage,omitempty"`

	// ResultsUrl: Output only. URL to the results in the Firebase Web
	// Console.
	ResultsUrl string `json:"resultsUrl,omitempty"`

	// ToolResultsExecution: Output only. The tool results execution that
	// results are written to.
	ToolResultsExecution *ToolResultsExecution `json:"toolResultsExecution,omitempty"`

	// ToolResultsHistory: The tool results history that contains the tool
	// results execution that results are written to. If not provided, the
	// service will choose an appropriate value.
	ToolResultsHistory *ToolResultsHistory `json:"toolResultsHistory,omitempty"`

	// ForceSendFields is a list of field names (e.g. "GoogleCloudStorage")
	// to unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "GoogleCloudStorage") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *ResultStorage) MarshalJSON() ([]byte, error) {
	type NoMethod ResultStorage
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RoboDirective: Directs Robo to interact with a specific UI element if
// it is encountered during the crawl. Currently, Robo can perform text
// entry or element click.
type RoboDirective struct {
	// ActionType: Required. The type of action that Robo should perform on
	// the specified element.
	//
	// Possible values:
	//   "ACTION_TYPE_UNSPECIFIED" - DO NOT USE. For proto versioning only.
	//   "SINGLE_CLICK" - Direct Robo to click on the specified element.
	// No-op if specified element is not clickable.
	//   "ENTER_TEXT" - Direct Robo to enter text on the specified element.
	// No-op if specified element is not enabled or does not allow text
	// entry.
	//   "IGNORE" - Direct Robo to ignore interactions with a specific
	// element.
	ActionType string `json:"actionType,omitempty"`

	// InputText: The text that Robo is directed to set. If left empty, the
	// directive will be treated as a CLICK on the element matching the
	// resource_name.
	InputText string `json:"inputText,omitempty"`

	// ResourceName: Required. The android resource name of the target UI
	// element. For example, in Java: R.string.foo in xml: @string/foo Only
	// the "foo" part is needed. Reference doc:
	// https://developer.android.com/guide/topics/resources/accessing-resources.html
	ResourceName string `json:"resourceName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ActionType") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ActionType") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *RoboDirective) MarshalJSON() ([]byte, error) {
	type NoMethod RoboDirective
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// RoboStartingIntent: Message for specifying the start activities to
// crawl.
type RoboStartingIntent struct {
	// LauncherActivity: An intent that starts the main launcher activity.
	LauncherActivity *LauncherActivityIntent `json:"launcherActivity,omitempty"`

	// StartActivity: An intent that starts an activity with specific
	// details.
	StartActivity *StartActivityIntent `json:"startActivity,omitempty"`

	// Timeout: Timeout in seconds for each intent.
	Timeout string `json:"timeout,omitempty"`

	// ForceSendFields is a list of field names (e.g. "LauncherActivity") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "LauncherActivity") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *RoboStartingIntent) MarshalJSON() ([]byte, error) {
	type NoMethod RoboStartingIntent
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Shard: Output only. Details about the shard.
type Shard struct {
	// NumShards: Output only. The total number of shards.
	NumShards int64 `json:"numShards,omitempty"`

	// ShardIndex: Output only. The index of the shard among all the shards.
	ShardIndex int64 `json:"shardIndex,omitempty"`

	// TestTargetsForShard: Output only. Test targets for each shard. Only
	// set for manual sharding.
	TestTargetsForShard *TestTargetsForShard `json:"testTargetsForShard,omitempty"`

	// ForceSendFields is a list of field names (e.g. "NumShards") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "NumShards") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Shard) MarshalJSON() ([]byte, error) {
	type NoMethod Shard
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ShardingOption: Options for enabling sharding.
type ShardingOption struct {
	// ManualSharding: Shards test cases into the specified groups of
	// packages, classes, and/or methods.
	ManualSharding *ManualSharding `json:"manualSharding,omitempty"`

	// UniformSharding: Uniformly shards test cases given a total number of
	// shards.
	UniformSharding *UniformSharding `json:"uniformSharding,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ManualSharding") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ManualSharding") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *ShardingOption) MarshalJSON() ([]byte, error) {
	type NoMethod ShardingOption
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// StartActivityIntent: A starting intent specified by an action, uri,
// and categories.
type StartActivityIntent struct {
	// Action: Action name. Required for START_ACTIVITY.
	Action string `json:"action,omitempty"`

	// Categories: Intent categories to set on the intent.
	Categories []string `json:"categories,omitempty"`

	// Uri: URI for the action.
	Uri string `json:"uri,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Action") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Action") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *StartActivityIntent) MarshalJSON() ([]byte, error) {
	type NoMethod StartActivityIntent
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

type SystraceSetup struct {
	// DurationSeconds: Systrace duration in seconds. Should be between 1
	// and 30 seconds. 0 disables systrace.
	DurationSeconds int64 `json:"durationSeconds,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DurationSeconds") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "DurationSeconds") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *SystraceSetup) MarshalJSON() ([]byte, error) {
	type NoMethod SystraceSetup
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TestDetails: Additional details about the progress of the running
// test.
type TestDetails struct {
	// ErrorMessage: Output only. If the TestState is ERROR, then this
	// string will contain human-readable details about the error.
	ErrorMessage string `json:"errorMessage,omitempty"`

	// ProgressMessages: Output only. Human-readable, detailed descriptions
	// of the test's progress. For example: "Provisioning a device",
	// "Starting Test". During the course of execution new data may be
	// appended to the end of progress_messages.
	ProgressMessages []string `json:"progressMessages,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ErrorMessage") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ErrorMessage") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TestDetails) MarshalJSON() ([]byte, error) {
	type NoMethod TestDetails
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TestEnvironmentCatalog: A description of a test environment.
type TestEnvironmentCatalog struct {
	// AndroidDeviceCatalog: Supported Android devices.
	AndroidDeviceCatalog *AndroidDeviceCatalog `json:"androidDeviceCatalog,omitempty"`

	// DeviceIpBlockCatalog: The IP blocks used by devices in the test
	// environment.
	DeviceIpBlockCatalog *DeviceIpBlockCatalog `json:"deviceIpBlockCatalog,omitempty"`

	// IosDeviceCatalog: Supported iOS devices.
	IosDeviceCatalog *IosDeviceCatalog `json:"iosDeviceCatalog,omitempty"`

	// NetworkConfigurationCatalog: Supported network configurations.
	NetworkConfigurationCatalog *NetworkConfigurationCatalog `json:"networkConfigurationCatalog,omitempty"`

	// SoftwareCatalog: The software test environment provided by
	// TestExecutionService.
	SoftwareCatalog *ProvidedSoftwareCatalog `json:"softwareCatalog,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g.
	// "AndroidDeviceCatalog") to unconditionally include in API requests.
	// By default, fields with empty or default values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AndroidDeviceCatalog") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

func (s *TestEnvironmentCatalog) MarshalJSON() ([]byte, error) {
	type NoMethod TestEnvironmentCatalog
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TestExecution: A single test executed in a single environment.
type TestExecution struct {
	// Environment: Output only. How the host machine(s) are configured.
	Environment *Environment `json:"environment,omitempty"`

	// Id: Output only. Unique id set by the service.
	Id string `json:"id,omitempty"`

	// MatrixId: Output only. Id of the containing TestMatrix.
	MatrixId string `json:"matrixId,omitempty"`

	// ProjectId: Output only. The cloud project that owns the test
	// execution.
	ProjectId string `json:"projectId,omitempty"`

	// Shard: Output only. Details about the shard.
	Shard *Shard `json:"shard,omitempty"`

	// State: Output only. Indicates the current progress of the test
	// execution (e.g., FINISHED).
	//
	// Possible values:
	//   "TEST_STATE_UNSPECIFIED" - Do not use. For proto versioning only.
	//   "VALIDATING" - The execution or matrix is being validated.
	//   "PENDING" - The execution or matrix is waiting for resources to
	// become available.
	//   "RUNNING" - The execution is currently being processed. Can only be
	// set on an execution.
	//   "FINISHED" - The execution or matrix has terminated normally. On a
	// matrix this means that the matrix level processing completed
	// normally, but individual executions may be in an ERROR state.
	//   "ERROR" - The execution or matrix has stopped because it
	// encountered an infrastructure failure.
	//   "UNSUPPORTED_ENVIRONMENT" - The execution was not run because it
	// corresponds to a unsupported environment. Can only be set on an
	// execution.
	//   "INCOMPATIBLE_ENVIRONMENT" - The execution was not run because the
	// provided inputs are incompatible with the requested environment.
	// Example: requested AndroidVersion is lower than APK's minSdkVersion
	// Can only be set on an execution.
	//   "INCOMPATIBLE_ARCHITECTURE" - The execution was not run because the
	// provided inputs are incompatible with the requested architecture.
	// Example: requested device does not support running the native code in
	// the supplied APK Can only be set on an execution.
	//   "CANCELLED" - The user cancelled the execution. Can only be set on
	// an execution.
	//   "INVALID" - The execution or matrix was not run because the
	// provided inputs are not valid. Examples: input file is not of the
	// expected type, is malformed/corrupt, or was flagged as malware
	State string `json:"state,omitempty"`

	// TestDetails: Output only. Additional details about the running test.
	TestDetails *TestDetails `json:"testDetails,omitempty"`

	// TestSpecification: Output only. How to run the test.
	TestSpecification *TestSpecification `json:"testSpecification,omitempty"`

	// Timestamp: Output only. The time this test execution was initially
	// created.
	Timestamp string `json:"timestamp,omitempty"`

	// ToolResultsStep: Output only. Where the results for this execution
	// are written.
	ToolResultsStep *ToolResultsStep `json:"toolResultsStep,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Environment") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Environment") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TestExecution) MarshalJSON() ([]byte, error) {
	type NoMethod TestExecution
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TestMatrix: TestMatrix captures all details about a test. It contains
// the environment configuration, test specification, test executions
// and overall state and outcome.
type TestMatrix struct {
	// ClientInfo: Information about the client which invoked the test.
	ClientInfo *ClientInfo `json:"clientInfo,omitempty"`

	// EnvironmentMatrix: Required. The devices the tests are being executed
	// on.
	EnvironmentMatrix *EnvironmentMatrix `json:"environmentMatrix,omitempty"`

	// FailFast: If true, only a single attempt at most will be made to run
	// each execution/shard in the matrix. Flaky test attempts are not
	// affected. Normally, 2 or more attempts are made if a potential
	// infrastructure issue is detected. This feature is for latency
	// sensitive workloads. The incidence of execution failures may be
	// significantly greater for fail-fast matrices and support is more
	// limited because of that expectation.
	FailFast bool `json:"failFast,omitempty"`

	// FlakyTestAttempts: The number of times a TestExecution should be
	// re-attempted if one or more of its test cases fail for any reason.
	// The maximum number of reruns allowed is 10. Default is 0, which
	// implies no reruns.
	FlakyTestAttempts int64 `json:"flakyTestAttempts,omitempty"`

	// InvalidMatrixDetails: Output only. Describes why the matrix is
	// considered invalid. Only useful for matrices in the INVALID state.
	//
	// Possible values:
	//   "INVALID_MATRIX_DETAILS_UNSPECIFIED" - Do not use. For proto
	// versioning only.
	//   "DETAILS_UNAVAILABLE" - The matrix is INVALID, but there are no
	// further details available.
	//   "MALFORMED_APK" - The input app APK could not be parsed.
	//   "MALFORMED_TEST_APK" - The input test APK could not be parsed.
	//   "NO_MANIFEST" - The AndroidManifest.xml could not be found.
	//   "NO_PACKAGE_NAME" - The APK manifest does not declare a package
	// name.
	//   "INVALID_PACKAGE_NAME" - The APK application ID (aka package name)
	// is invalid. See also
	// https://developer.android.com/studio/build/application-id
	//   "TEST_SAME_AS_APP" - The test package and app package are the same.
	//   "NO_INSTRUMENTATION" - The test apk does not declare an
	// instrumentation.
	//   "NO_SIGNATURE" - The input app apk does not have a signature.
	//   "INSTRUMENTATION_ORCHESTRATOR_INCOMPATIBLE" - The test runner class
	// specified by user or in the test APK's manifest file is not
	// compatible with Android Test Orchestrator. Orchestrator is only
	// compatible with AndroidJUnitRunner version 1.1 or higher.
	// Orchestrator can be disabled by using DO_NOT_USE_ORCHESTRATOR
	// OrchestratorOption.
	//   "NO_TEST_RUNNER_CLASS" - The test APK does not contain the test
	// runner class specified by user or in the manifest file. This can be
	// caused by either of the following reasons: - the user provided a
	// runner class name that's incorrect, or - the test runner isn't built
	// into the test APK (might be in the app APK instead).
	//   "NO_LAUNCHER_ACTIVITY" - A main launcher activity could not be
	// found.
	//   "FORBIDDEN_PERMISSIONS" - The app declares one or more permissions
	// that are not allowed.
	//   "INVALID_ROBO_DIRECTIVES" - There is a conflict in the provided
	// robo_directives.
	//   "INVALID_RESOURCE_NAME" - There is at least one invalid resource
	// name in the provided robo directives
	//   "INVALID_DIRECTIVE_ACTION" - Invalid definition of action in the
	// robo directives (e.g. a click or ignore action includes an input text
	// field)
	//   "TEST_LOOP_INTENT_FILTER_NOT_FOUND" - There is no test loop intent
	// filter, or the one that is given is not formatted correctly.
	//   "SCENARIO_LABEL_NOT_DECLARED" - The request contains a scenario
	// label that was not declared in the manifest.
	//   "SCENARIO_LABEL_MALFORMED" - There was an error when parsing a
	// label's value.
	//   "SCENARIO_NOT_DECLARED" - The request contains a scenario number
	// that was not declared in the manifest.
	//   "DEVICE_ADMIN_RECEIVER" - Device administrator applications are not
	// allowed.
	//   "MALFORMED_XC_TEST_ZIP" - The zipped XCTest was malformed. The zip
	// did not contain a single .xctestrun file and the contents of the
	// DerivedData/Build/Products directory.
	//   "BUILT_FOR_IOS_SIMULATOR" - The zipped XCTest was built for the iOS
	// simulator rather than for a physical device.
	//   "NO_TESTS_IN_XC_TEST_ZIP" - The .xctestrun file did not specify any
	// test targets.
	//   "USE_DESTINATION_ARTIFACTS" - One or more of the test targets
	// defined in the .xctestrun file specifies "UseDestinationArtifacts",
	// which is disallowed.
	//   "TEST_NOT_APP_HOSTED" - XC tests which run on physical devices must
	// have "IsAppHostedTestBundle" == "true" in the xctestrun file.
	//   "PLIST_CANNOT_BE_PARSED" - An Info.plist file in the XCTest zip
	// could not be parsed.
	//   "TEST_ONLY_APK" - The APK is marked as "testOnly". Deprecated and
	// not currently used.
	//   "MALFORMED_IPA" - The input IPA could not be parsed.
	//   "MISSING_URL_SCHEME" - The application doesn't register the game
	// loop URL scheme.
	//   "MALFORMED_APP_BUNDLE" - The iOS application bundle (.app) couldn't
	// be processed.
	//   "NO_CODE_APK" - APK contains no code. See also
	// https://developer.android.com/guide/topics/manifest/application-element.html#code
	//   "INVALID_INPUT_APK" - Either the provided input APK path was
	// malformed, the APK file does not exist, or the user does not have
	// permission to access the APK file.
	//   "INVALID_APK_PREVIEW_SDK" - APK is built for a preview SDK which is
	// unsupported
	InvalidMatrixDetails string `json:"invalidMatrixDetails,omitempty"`

	// OutcomeSummary: Output Only. The overall outcome of the test. Only
	// set when the test matrix state is FINISHED.
	//
	// Possible values:
	//   "OUTCOME_SUMMARY_UNSPECIFIED" - Do not use. For proto versioning
	// only.
	//   "SUCCESS" - The test matrix run was successful, for instance: - All
	// the test cases passed. - Robo did not detect a crash of the
	// application under test.
	//   "FAILURE" - A run failed, for instance: - One or more test case
	// failed. - A test timed out. - The application under test crashed.
	//   "INCONCLUSIVE" - Something unexpected happened. The run should
	// still be considered unsuccessful but this is likely a transient
	// problem and re-running the test might be successful.
	//   "SKIPPED" - All tests were skipped, for instance: - All device
	// configurations were incompatible.
	OutcomeSummary string `json:"outcomeSummary,omitempty"`

	// ProjectId: The cloud project that owns the test matrix.
	ProjectId string `json:"projectId,omitempty"`

	// ResultStorage: Required. Where the results for the matrix are
	// written.
	ResultStorage *ResultStorage `json:"resultStorage,omitempty"`

	// State: Output only. Indicates the current progress of the test
	// matrix.
	//
	// Possible values:
	//   "TEST_STATE_UNSPECIFIED" - Do not use. For proto versioning only.
	//   "VALIDATING" - The execution or matrix is being validated.
	//   "PENDING" - The execution or matrix is waiting for resources to
	// become available.
	//   "RUNNING" - The execution is currently being processed. Can only be
	// set on an execution.
	//   "FINISHED" - The execution or matrix has terminated normally. On a
	// matrix this means that the matrix level processing completed
	// normally, but individual executions may be in an ERROR state.
	//   "ERROR" - The execution or matrix has stopped because it
	// encountered an infrastructure failure.
	//   "UNSUPPORTED_ENVIRONMENT" - The execution was not run because it
	// corresponds to a unsupported environment. Can only be set on an
	// execution.
	//   "INCOMPATIBLE_ENVIRONMENT" - The execution was not run because the
	// provided inputs are incompatible with the requested environment.
	// Example: requested AndroidVersion is lower than APK's minSdkVersion
	// Can only be set on an execution.
	//   "INCOMPATIBLE_ARCHITECTURE" - The execution was not run because the
	// provided inputs are incompatible with the requested architecture.
	// Example: requested device does not support running the native code in
	// the supplied APK Can only be set on an execution.
	//   "CANCELLED" - The user cancelled the execution. Can only be set on
	// an execution.
	//   "INVALID" - The execution or matrix was not run because the
	// provided inputs are not valid. Examples: input file is not of the
	// expected type, is malformed/corrupt, or was flagged as malware
	State string `json:"state,omitempty"`

	// TestExecutions: Output only. The list of test executions that the
	// service creates for this matrix.
	TestExecutions []*TestExecution `json:"testExecutions,omitempty"`

	// TestMatrixId: Output only. Unique id set by the service.
	TestMatrixId string `json:"testMatrixId,omitempty"`

	// TestSpecification: Required. How to run the test.
	TestSpecification *TestSpecification `json:"testSpecification,omitempty"`

	// Timestamp: Output only. The time this test matrix was initially
	// created.
	Timestamp string `json:"timestamp,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "ClientInfo") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ClientInfo") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TestMatrix) MarshalJSON() ([]byte, error) {
	type NoMethod TestMatrix
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TestSetup: A description of how to set up the Android device prior to
// running the test.
type TestSetup struct {
	// Account: The device will be logged in on this account for the
	// duration of the test.
	Account *Account `json:"account,omitempty"`

	// AdditionalApks: APKs to install in addition to those being directly
	// tested. Currently capped at 100.
	AdditionalApks []*Apk `json:"additionalApks,omitempty"`

	// DirectoriesToPull: List of directories on the device to upload to GCS
	// at the end of the test; they must be absolute paths under /sdcard,
	// /storage or /data/local/tmp. Path names are restricted to characters
	// a-z A-Z 0-9 _ - . + and / Note: The paths /sdcard and /data will be
	// made available and treated as implicit path substitutions. E.g. if
	// /sdcard on a particular device does not map to external storage, the
	// system will replace it with the external storage path prefix for that
	// device.
	DirectoriesToPull []string `json:"directoriesToPull,omitempty"`

	// DontAutograntPermissions: Whether to prevent all runtime permissions
	// to be granted at app install
	DontAutograntPermissions bool `json:"dontAutograntPermissions,omitempty"`

	// EnvironmentVariables: Environment variables to set for the test (only
	// applicable for instrumentation tests).
	EnvironmentVariables []*EnvironmentVariable `json:"environmentVariables,omitempty"`

	// FilesToPush: List of files to push to the device before starting the
	// test.
	FilesToPush []*DeviceFile `json:"filesToPush,omitempty"`

	// NetworkProfile: The network traffic profile used for running the
	// test. Available network profiles can be queried by using the
	// NETWORK_CONFIGURATION environment type when calling
	// TestEnvironmentDiscoveryService.GetTestEnvironmentCatalog.
	NetworkProfile string `json:"networkProfile,omitempty"`

	// Systrace: Deprecated: Systrace uses Python 2 which has been sunset
	// 2020-01-01. Support of Systrace may stop at any time, at which point
	// no Systrace file will be provided in the results. Systrace
	// configuration for the run. If set a systrace will be taken, starting
	// on test start and lasting for the configured duration. The systrace
	// file thus obtained is put in the results bucket together with the
	// other artifacts from the run.
	Systrace *SystraceSetup `json:"systrace,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Account") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Account") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TestSetup) MarshalJSON() ([]byte, error) {
	type NoMethod TestSetup
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TestSpecification: A description of how to run the test.
type TestSpecification struct {
	// AndroidInstrumentationTest: An Android instrumentation test.
	AndroidInstrumentationTest *AndroidInstrumentationTest `json:"androidInstrumentationTest,omitempty"`

	// AndroidRoboTest: An Android robo test.
	AndroidRoboTest *AndroidRoboTest `json:"androidRoboTest,omitempty"`

	// AndroidTestLoop: An Android Application with a Test Loop.
	AndroidTestLoop *AndroidTestLoop `json:"androidTestLoop,omitempty"`

	// DisablePerformanceMetrics: Disables performance metrics recording.
	// May reduce test latency.
	DisablePerformanceMetrics bool `json:"disablePerformanceMetrics,omitempty"`

	// DisableVideoRecording: Disables video recording. May reduce test
	// latency.
	DisableVideoRecording bool `json:"disableVideoRecording,omitempty"`

	// IosTestLoop: An iOS application with a test loop.
	IosTestLoop *IosTestLoop `json:"iosTestLoop,omitempty"`

	// IosTestSetup: Test setup requirements for iOS.
	IosTestSetup *IosTestSetup `json:"iosTestSetup,omitempty"`

	// IosXcTest: An iOS XCTest, via an .xctestrun file.
	IosXcTest *IosXcTest `json:"iosXcTest,omitempty"`

	// TestSetup: Test setup requirements for Android e.g. files to install,
	// bootstrap scripts.
	TestSetup *TestSetup `json:"testSetup,omitempty"`

	// TestTimeout: Max time a test execution is allowed to run before it is
	// automatically cancelled. The default value is 5 min.
	TestTimeout string `json:"testTimeout,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "AndroidInstrumentationTest") to unconditionally include in API
	// requests. By default, fields with empty or default values are omitted
	// from API requests. However, any non-pointer, non-interface field
	// appearing in ForceSendFields will be sent to the server regardless of
	// whether the field is empty or not. This may be used to include empty
	// fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g.
	// "AndroidInstrumentationTest") to include in API requests with the
	// JSON null value. By default, fields with empty values are omitted
	// from API requests. However, any field with an empty value appearing
	// in NullFields will be sent to the server as null. It is an error if a
	// field in this list has a non-empty value. This may be used to include
	// null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TestSpecification) MarshalJSON() ([]byte, error) {
	type NoMethod TestSpecification
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TestTargetsForShard: Test targets for a shard.
type TestTargetsForShard struct {
	// TestTargets: Group of packages, classes, and/or test methods to be
	// run for each shard. The targets need to be specified in
	// AndroidJUnitRunner argument format. For example, "package
	// com.my.packages" "class com.my.package.MyClass". The number of
	// test_targets must be greater than 0.
	TestTargets []string `json:"testTargets,omitempty"`

	// ForceSendFields is a list of field names (e.g. "TestTargets") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "TestTargets") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TestTargetsForShard) MarshalJSON() ([]byte, error) {
	type NoMethod TestTargetsForShard
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ToolResultsExecution: Represents a tool results execution resource.
// This has the results of a TestMatrix.
type ToolResultsExecution struct {
	// ExecutionId: Output only. A tool results execution ID.
	ExecutionId string `json:"executionId,omitempty"`

	// HistoryId: Output only. A tool results history ID.
	HistoryId string `json:"historyId,omitempty"`

	// ProjectId: Output only. The cloud project that owns the tool results
	// execution.
	ProjectId string `json:"projectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ExecutionId") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ExecutionId") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ToolResultsExecution) MarshalJSON() ([]byte, error) {
	type NoMethod ToolResultsExecution
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ToolResultsHistory: Represents a tool results history resource.
type ToolResultsHistory struct {
	// HistoryId: Required. A tool results history ID.
	HistoryId string `json:"historyId,omitempty"`

	// ProjectId: Required. The cloud project that owns the tool results
	// history.
	ProjectId string `json:"projectId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "HistoryId") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "HistoryId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ToolResultsHistory) MarshalJSON() ([]byte, error) {
	type NoMethod ToolResultsHistory
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ToolResultsStep: Represents a tool results step resource. This has
// the results of a TestExecution.
type ToolResultsStep struct {
	// ExecutionId: Output only. A tool results execution ID.
	ExecutionId string `json:"executionId,omitempty"`

	// HistoryId: Output only. A tool results history ID.
	HistoryId string `json:"historyId,omitempty"`

	// ProjectId: Output only. The cloud project that owns the tool results
	// step.
	ProjectId string `json:"projectId,omitempty"`

	// StepId: Output only. A tool results step ID.
	StepId string `json:"stepId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ExecutionId") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ExecutionId") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ToolResultsStep) MarshalJSON() ([]byte, error) {
	type NoMethod ToolResultsStep
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TrafficRule: Network emulation parameters.
type TrafficRule struct {
	// Bandwidth: Bandwidth in kbits/second.
	Bandwidth float64 `json:"bandwidth,omitempty"`

	// Burst: Burst size in kbits.
	Burst float64 `json:"burst,omitempty"`

	// Delay: Packet delay, must be >= 0.
	Delay string `json:"delay,omitempty"`

	// PacketDuplicationRatio: Packet duplication ratio (0.0 - 1.0).
	PacketDuplicationRatio float64 `json:"packetDuplicationRatio,omitempty"`

	// PacketLossRatio: Packet loss ratio (0.0 - 1.0).
	PacketLossRatio float64 `json:"packetLossRatio,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Bandwidth") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Bandwidth") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *TrafficRule) MarshalJSON() ([]byte, error) {
	type NoMethod TrafficRule
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *TrafficRule) UnmarshalJSON(data []byte) error {
	type NoMethod TrafficRule
	var s1 struct {
		Bandwidth              gensupport.JSONFloat64 `json:"bandwidth"`
		Burst                  gensupport.JSONFloat64 `json:"burst"`
		PacketDuplicationRatio gensupport.JSONFloat64 `json:"packetDuplicationRatio"`
		PacketLossRatio        gensupport.JSONFloat64 `json:"packetLossRatio"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Bandwidth = float64(s1.Bandwidth)
	s.Burst = float64(s1.Burst)
	s.PacketDuplicationRatio = float64(s1.PacketDuplicationRatio)
	s.PacketLossRatio = float64(s1.PacketLossRatio)
	return nil
}

// UniformSharding: Uniformly shards test cases given a total number of
// shards. For Instrumentation test, it will be translated to "-e
// numShard" "-e shardIndex" AndroidJUnitRunner arguments. Based on the
// sharding mechanism AndroidJUnitRunner uses, there is no guarantee
// that test cases will be distributed uniformly across all shards. With
// uniform sharding enabled, specifying these sharding arguments via
// environment_variables is invalid.
type UniformSharding struct {
	// NumShards: Required. Total number of shards. When any physical
	// devices are selected, the number must be >= 1 and <= 50. When no
	// physical devices are selected, the number must be >= 1 and <= 500.
	NumShards int64 `json:"numShards,omitempty"`

	// ForceSendFields is a list of field names (e.g. "NumShards") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "NumShards") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *UniformSharding) MarshalJSON() ([]byte, error) {
	type NoMethod UniformSharding
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// XcodeVersion: An Xcode version that an iOS version is compatible
// with.
type XcodeVersion struct {
	// Tags: Tags for this Xcode version. Example: "default".
	Tags []string `json:"tags,omitempty"`

	// Version: The id for this version. Example: "9.2".
	Version string `json:"version,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Tags") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Tags") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *XcodeVersion) MarshalJSON() ([]byte, error) {
	type NoMethod XcodeVersion
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// method id "testing.applicationDetailService.getApkDetails":

type ApplicationDetailServiceGetApkDetailsCall struct {
	s             *Service
	filereference *FileReference
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// GetApkDetails: Gets the details of an Android application APK.
func (r *ApplicationDetailServiceService) GetApkDetails(filereference *FileReference) *ApplicationDetailServiceGetApkDetailsCall {
	c := &ApplicationDetailServiceGetApkDetailsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.filereference = filereference
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ApplicationDetailServiceGetApkDetailsCall) Fields(s ...googleapi.Field) *ApplicationDetailServiceGetApkDetailsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ApplicationDetailServiceGetApkDetailsCall) Context(ctx context.Context) *ApplicationDetailServiceGetApkDetailsCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ApplicationDetailServiceGetApkDetailsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ApplicationDetailServiceGetApkDetailsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.filereference)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/applicationDetailService/getApkDetails")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "testing.applicationDetailService.getApkDetails" call.
// Exactly one of *GetApkDetailsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GetApkDetailsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ApplicationDetailServiceGetApkDetailsCall) Do(opts ...googleapi.CallOption) (*GetApkDetailsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &GetApkDetailsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the details of an Android application APK.",
	//   "flatPath": "v1/applicationDetailService/getApkDetails",
	//   "httpMethod": "POST",
	//   "id": "testing.applicationDetailService.getApkDetails",
	//   "parameterOrder": [],
	//   "parameters": {},
	//   "path": "v1/applicationDetailService/getApkDetails",
	//   "request": {
	//     "$ref": "FileReference"
	//   },
	//   "response": {
	//     "$ref": "GetApkDetailsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "testing.projects.testMatrices.cancel":

type ProjectsTestMatricesCancelCall struct {
	s            *Service
	projectId    string
	testMatrixId string
	urlParams_   gensupport.URLParams
	ctx_         context.Context
	header_      http.Header
}

// Cancel: Cancels unfinished test executions in a test matrix. This
// call returns immediately and cancellation proceeds asynchronously. If
// the matrix is already final, this operation will have no effect. May
// return any of the following canonical error codes: -
// PERMISSION_DENIED - if the user is not authorized to read project -
// INVALID_ARGUMENT - if the request is malformed - NOT_FOUND - if the
// Test Matrix does not exist
//
// - projectId: Cloud project that owns the test.
// - testMatrixId: Test matrix that will be canceled.
func (r *ProjectsTestMatricesService) Cancel(projectId string, testMatrixId string) *ProjectsTestMatricesCancelCall {
	c := &ProjectsTestMatricesCancelCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	c.testMatrixId = testMatrixId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ProjectsTestMatricesCancelCall) Fields(s ...googleapi.Field) *ProjectsTestMatricesCancelCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsTestMatricesCancelCall) Context(ctx context.Context) *ProjectsTestMatricesCancelCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ProjectsTestMatricesCancelCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsTestMatricesCancelCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/projects/{projectId}/testMatrices/{testMatrixId}:cancel")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"projectId":    c.projectId,
		"testMatrixId": c.testMatrixId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "testing.projects.testMatrices.cancel" call.
// Exactly one of *CancelTestMatrixResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *CancelTestMatrixResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ProjectsTestMatricesCancelCall) Do(opts ...googleapi.CallOption) (*CancelTestMatrixResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CancelTestMatrixResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Cancels unfinished test executions in a test matrix. This call returns immediately and cancellation proceeds asynchronously. If the matrix is already final, this operation will have no effect. May return any of the following canonical error codes: - PERMISSION_DENIED - if the user is not authorized to read project - INVALID_ARGUMENT - if the request is malformed - NOT_FOUND - if the Test Matrix does not exist",
	//   "flatPath": "v1/projects/{projectId}/testMatrices/{testMatrixId}:cancel",
	//   "httpMethod": "POST",
	//   "id": "testing.projects.testMatrices.cancel",
	//   "parameterOrder": [
	//     "projectId",
	//     "testMatrixId"
	//   ],
	//   "parameters": {
	//     "projectId": {
	//       "description": "Cloud project that owns the test.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "testMatrixId": {
	//       "description": "Test matrix that will be canceled.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/projects/{projectId}/testMatrices/{testMatrixId}:cancel",
	//   "response": {
	//     "$ref": "CancelTestMatrixResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "testing.projects.testMatrices.create":

type ProjectsTestMatricesCreateCall struct {
	s          *Service
	projectId  string
	testmatrix *TestMatrix
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Create: Creates and runs a matrix of tests according to the given
// specifications. Unsupported environments will be returned in the
// state UNSUPPORTED. A test matrix is limited to use at most 2000
// devices in parallel. May return any of the following canonical error
// codes: - PERMISSION_DENIED - if the user is not authorized to write
// to project - INVALID_ARGUMENT - if the request is malformed or if the
// matrix tries to use too many simultaneous devices.
//
// - projectId: The GCE project under which this job will run.
func (r *ProjectsTestMatricesService) Create(projectId string, testmatrix *TestMatrix) *ProjectsTestMatricesCreateCall {
	c := &ProjectsTestMatricesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	c.testmatrix = testmatrix
	return c
}

// RequestId sets the optional parameter "requestId": A string id used
// to detect duplicated requests. Ids are automatically scoped to a
// project, so users should ensure the ID is unique per-project. A UUID
// is recommended. Optional, but strongly recommended.
func (c *ProjectsTestMatricesCreateCall) RequestId(requestId string) *ProjectsTestMatricesCreateCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ProjectsTestMatricesCreateCall) Fields(s ...googleapi.Field) *ProjectsTestMatricesCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsTestMatricesCreateCall) Context(ctx context.Context) *ProjectsTestMatricesCreateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ProjectsTestMatricesCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsTestMatricesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.testmatrix)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/projects/{projectId}/testMatrices")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"projectId": c.projectId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "testing.projects.testMatrices.create" call.
// Exactly one of *TestMatrix or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *TestMatrix.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ProjectsTestMatricesCreateCall) Do(opts ...googleapi.CallOption) (*TestMatrix, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TestMatrix{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates and runs a matrix of tests according to the given specifications. Unsupported environments will be returned in the state UNSUPPORTED. A test matrix is limited to use at most 2000 devices in parallel. May return any of the following canonical error codes: - PERMISSION_DENIED - if the user is not authorized to write to project - INVALID_ARGUMENT - if the request is malformed or if the matrix tries to use too many simultaneous devices.",
	//   "flatPath": "v1/projects/{projectId}/testMatrices",
	//   "httpMethod": "POST",
	//   "id": "testing.projects.testMatrices.create",
	//   "parameterOrder": [
	//     "projectId"
	//   ],
	//   "parameters": {
	//     "projectId": {
	//       "description": "The GCE project under which this job will run.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "requestId": {
	//       "description": "A string id used to detect duplicated requests. Ids are automatically scoped to a project, so users should ensure the ID is unique per-project. A UUID is recommended. Optional, but strongly recommended.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/projects/{projectId}/testMatrices",
	//   "request": {
	//     "$ref": "TestMatrix"
	//   },
	//   "response": {
	//     "$ref": "TestMatrix"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "testing.projects.testMatrices.get":

type ProjectsTestMatricesGetCall struct {
	s            *Service
	projectId    string
	testMatrixId string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Checks the status of a test matrix. May return any of the
// following canonical error codes: - PERMISSION_DENIED - if the user is
// not authorized to read project - INVALID_ARGUMENT - if the request is
// malformed - NOT_FOUND - if the Test Matrix does not exist
//
// - projectId: Cloud project that owns the test matrix.
// - testMatrixId: Unique test matrix id which was assigned by the
//   service.
func (r *ProjectsTestMatricesService) Get(projectId string, testMatrixId string) *ProjectsTestMatricesGetCall {
	c := &ProjectsTestMatricesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.projectId = projectId
	c.testMatrixId = testMatrixId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ProjectsTestMatricesGetCall) Fields(s ...googleapi.Field) *ProjectsTestMatricesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ProjectsTestMatricesGetCall) IfNoneMatch(entityTag string) *ProjectsTestMatricesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ProjectsTestMatricesGetCall) Context(ctx context.Context) *ProjectsTestMatricesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ProjectsTestMatricesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsTestMatricesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/projects/{projectId}/testMatrices/{testMatrixId}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"projectId":    c.projectId,
		"testMatrixId": c.testMatrixId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "testing.projects.testMatrices.get" call.
// Exactly one of *TestMatrix or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *TestMatrix.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ProjectsTestMatricesGetCall) Do(opts ...googleapi.CallOption) (*TestMatrix, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TestMatrix{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Checks the status of a test matrix. May return any of the following canonical error codes: - PERMISSION_DENIED - if the user is not authorized to read project - INVALID_ARGUMENT - if the request is malformed - NOT_FOUND - if the Test Matrix does not exist",
	//   "flatPath": "v1/projects/{projectId}/testMatrices/{testMatrixId}",
	//   "httpMethod": "GET",
	//   "id": "testing.projects.testMatrices.get",
	//   "parameterOrder": [
	//     "projectId",
	//     "testMatrixId"
	//   ],
	//   "parameters": {
	//     "projectId": {
	//       "description": "Cloud project that owns the test matrix.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "testMatrixId": {
	//       "description": "Unique test matrix id which was assigned by the service.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/projects/{projectId}/testMatrices/{testMatrixId}",
	//   "response": {
	//     "$ref": "TestMatrix"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/cloud-platform.read-only"
	//   ]
	// }

}

// method id "testing.testEnvironmentCatalog.get":

type TestEnvironmentCatalogGetCall struct {
	s               *Service
	environmentType string
	urlParams_      gensupport.URLParams
	ifNoneMatch_    string
	ctx_            context.Context
	header_         http.Header
}

// Get: Gets the catalog of supported test environments. May return any
// of the following canonical error codes: - INVALID_ARGUMENT - if the
// request is malformed - NOT_FOUND - if the environment type does not
// exist - INTERNAL - if an internal error occurred
//
// - environmentType: The type of environment that should be listed.
func (r *TestEnvironmentCatalogService) Get(environmentType string) *TestEnvironmentCatalogGetCall {
	c := &TestEnvironmentCatalogGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.environmentType = environmentType
	return c
}

// ProjectId sets the optional parameter "projectId": For authorization,
// the cloud project requesting the TestEnvironmentCatalog.
func (c *TestEnvironmentCatalogGetCall) ProjectId(projectId string) *TestEnvironmentCatalogGetCall {
	c.urlParams_.Set("projectId", projectId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *TestEnvironmentCatalogGetCall) Fields(s ...googleapi.Field) *TestEnvironmentCatalogGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *TestEnvironmentCatalogGetCall) IfNoneMatch(entityTag string) *TestEnvironmentCatalogGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *TestEnvironmentCatalogGetCall) Context(ctx context.Context) *TestEnvironmentCatalogGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TestEnvironmentCatalogGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TestEnvironmentCatalogGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/testEnvironmentCatalog/{environmentType}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"environmentType": c.environmentType,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "testing.testEnvironmentCatalog.get" call.
// Exactly one of *TestEnvironmentCatalog or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TestEnvironmentCatalog.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *TestEnvironmentCatalogGetCall) Do(opts ...googleapi.CallOption) (*TestEnvironmentCatalog, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &TestEnvironmentCatalog{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the catalog of supported test environments. May return any of the following canonical error codes: - INVALID_ARGUMENT - if the request is malformed - NOT_FOUND - if the environment type does not exist - INTERNAL - if an internal error occurred",
	//   "flatPath": "v1/testEnvironmentCatalog/{environmentType}",
	//   "httpMethod": "GET",
	//   "id": "testing.testEnvironmentCatalog.get",
	//   "parameterOrder": [
	//     "environmentType"
	//   ],
	//   "parameters": {
	//     "environmentType": {
	//       "description": "Required. The type of environment that should be listed.",
	//       "enum": [
	//         "ENVIRONMENT_TYPE_UNSPECIFIED",
	//         "ANDROID",
	//         "IOS",
	//         "NETWORK_CONFIGURATION",
	//         "PROVIDED_SOFTWARE",
	//         "DEVICE_IP_BLOCKS"
	//       ],
	//       "enumDescriptions": [
	//         "Do not use. For proto versioning only.",
	//         "A device running a version of the Android OS.",
	//         "A device running a version of iOS.",
	//         "A network configuration to use when running a test.",
	//         "The software environment provided by TestExecutionService.",
	//         "The IP blocks used by devices in the test environment."
	//       ],
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "projectId": {
	//       "description": "For authorization, the cloud project requesting the TestEnvironmentCatalog.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/testEnvironmentCatalog/{environmentType}",
	//   "response": {
	//     "$ref": "TestEnvironmentCatalog"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-platform",
	//     "https://www.googleapis.com/auth/cloud-platform.read-only"
	//   ]
	// }

}
