<commit_before>// Copyright 2017 The TensorFlow Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// =============================================================================
#include "tensorflow/core/framework/common_shape_fns.h"
#include "tensorflow/core/framework/op.h"
#include "tensorflow/core/framework/resource_mgr.h"
#include "tensorflow/core/framework/shape_inference.h"

namespace tensorflow {
namespace boosted_trees {
using shape_inference::DimensionHandle;
using shape_inference::InferenceContext;
using shape_inference::ShapeHandle;

REGISTER_RESOURCE_HANDLE_OP(QuantileStreamResource);

REGISTER_OP("QuantileAccumulatorIsInitialized")
    .Input("quantile_accumulator_handle: resource")
    .Output("is_initialized: bool")
    .SetShapeFn(shape_inference::ScalarShape)
    .Doc(R"doc(
Checks whether a quantile accumulator has been initialized.
)doc");

REGISTER_OP("CreateQuantileAccumulator")
    .Attr("container: string = ''")
    .Attr("shared_name: string = ''")
    .Attr("max_elements: int = 1099511627776")  // 1 << 40
    .Attr("epsilon: float")
    .Attr("num_quantiles: int")
    .Attr("generate_quantiles: bool=False")
    .Input("quantile_accumulator_handle: resource")
    .Input("stamp_token: int64")
    .SetShapeFn([](shape_inference::InferenceContext* c) {
      shape_inference::ShapeHandle unused_input;
      TF_RETURN_IF_ERROR(c->WithRank(c->input(0), 0, &unused_input));
      TF_RETURN_IF_ERROR(c->WithRank(c->input(1), 0, &unused_input));
      return Status::OK();
    })
    .Doc(R"doc(
Creates a stateful accumulator for quantile summaries.

epsilon: Error bound on the quantile summary.
num_quantiles: Number of buckets that we create from the data.
stamp_token: Token to use as the initial value of the resource stamp.
quantile_accumulator_handle: The handle to the accumulator.
)doc");

REGISTER_OP("QuantileAccumulatorAddSummaries")
    .Attr("num_resource_handles: int >= 1")
    .Input("quantile_accumulator_handles: num_resource_handles * resource")
    .Input("stamp_token: int64")
    .Input("summaries: num_resource_handles * string")
    .SetShapeFn([](InferenceContext* c) {
      int num_resource_handles;
      TF_RETURN_IF_ERROR(
          c->GetAttr("num_resource_handles", &num_resource_handles));
      // All the inputs are scalars.
      shape_inference::ShapeHandle unused_input;
      for (int i = 0; i < 2 * num_resource_handles + 1; ++i) {
        TF_RETURN_IF_ERROR(c->WithRank(c->input(i), 0, &unused_input));
      }
      return Status::OK();
    })
    .Doc(R"doc(
Adds each quantile summary to its stream.

quantile_accumulator_handles: The handles to the quantile stream resources.
stamp_token: Stamp token to validate the Read/Write operation.
summaries: A list of serialized QuantileSummaryState.
)doc");

REGISTER_OP("QuantileAccumulatorGetBuckets")
    .Attr("num_resource_handles: int >= 1")
    .Input("quantile_accumulator_handles: num_resource_handles * resource")
    .Input("stamp_token: int64")
    .Output("are_buckets_ready: num_resource_handles * bool")
    .Output("buckets: num_resource_handles * float")
    .SetShapeFn([](InferenceContext* c) {
      int num_resource_handles;
      TF_RETURN_IF_ERROR(
          c->GetAttr("num_resource_handles", &num_resource_handles));
      for (int i = 0; i < num_resource_handles; ++i) {
        c->set_output(i, c->Scalar());
        c->set_output(i + num_resource_handles, c->Vector(c->UnknownDim()));
      }
      return Status::OK();
    })

    .Doc(R"doc(
Returns quantile buckets created during previous flush of the accumulator.

quantile_accumulator_handles: The handles to the quantile stream resources.
stamp_token: Stamp token to validate the Read/Write operation.
are_buckets_ready: Whether the buckets are ready or not.
buckets: Output quantile summary representing boundaries with "num_quantile"
    elements.
)doc");

REGISTER_OP("QuantileAccumulatorFlush")
    .Input("quantile_accumulator_handle: resource")
    .Input("stamp_token: int64")
    .Input("next_stamp_token: int64")
    .Doc(R"doc(
Resets quantile summary streams for each column with a new token.

quantile_accumulator_handle: The handle to the accumulator.
stamp_token: Stamp token for Read/Write operations.
             Any operation with a mismatching token will be dropped.
next_stamp_token: Stamp token to be used for the next iteration.
)doc");

REGISTER_OP("QuantileAccumulatorFlushSummary")
    .Input("quantile_accumulator_handle: resource")
    .Input("stamp_token: int64")
    .Input("next_stamp_token: int64")
    .Output("output: string")
    .Doc(R"doc(
Resets quantile summary stream and returns the summary.

quantile_accumulator_handle: The handle to the accumulator.
stamp_token: Stamp token for Read/Write operations.
             Any operation with a mismatching token will be dropped.
next_stamp_token: Stamp token to be used for the next iteration.
output: A scalar string that is the a summary of the accumulator.
)doc");

REGISTER_OP("QuantileAccumulatorSerialize")
    .Input("quantile_accumulator_handle: resource")
    .Output("stamp_token: int64")
    .Output("stream_state: string")
    .Output("are_buckets_ready: bool")
    .Output("buckets: float")
    .Doc(R"doc(
Serializes the state of the given resource.

quantile_accumulator_handle: The handle to the accumulator.
stamp_token: Stamp token for Read/Write operations.
             Any operation with a mismatching token will be dropped.
stream_state: A serialized QuantileStreamState.
are_buckets_ready: Whether the buckets are ready or not.
buckets: Output quantile buckets representing boundaries with "num_quantile"
    elements.
)doc");

REGISTER_OP("QuantileAccumulatorDeserialize")
    .Input("quantile_accumulator_handle: resource")
    .Input("stamp_token: int64")
    .Input("stream_state: string")
    .Input("are_buckets_ready: bool")
    .Input("buckets: float")
    .Doc(R"doc(
Serializes the state of the given resource.

quantile_accumulator_handle: The handle to the accumulator.
stamp_token: Stamp token for Read/Write operations.
             Any operation with a mismatching token will be dropped.
stream_state: A serialized QuantileStreamState.
are_buckets_ready: Whether the buckets are ready or not.
buckets: Output quantile summary representing boundaries with "num_quantile"
    elements.
)doc");

REGISTER_OP("MakeQuantileSummaries")
    .Attr("num_dense_features: int >= 0")
    .Attr("num_sparse_features: int >= 0")
    .Attr("epsilon: float")
    .Input("dense_float_features: num_dense_features * float")
    .Input("sparse_float_feature_indices: num_sparse_features * int64")
    .Input("sparse_float_feature_values: num_sparse_features * float")
    .Input("sparse_float_feature_shapes: num_sparse_features * int64")
    .Input("example_weights: float")
    .Output("dense_summaries: num_dense_features * string")
    .Output("sparse_summaries: num_sparse_features * string")
    .SetShapeFn([](InferenceContext* c) {
      int num_dense_features;
      TF_RETURN_IF_ERROR(c->GetAttr("num_dense_features", &num_dense_features));
      int num_sparse_features;
      TF_RETURN_IF_ERROR(
          c->GetAttr("num_sparse_features", &num_sparse_features));
      ShapeHandle example_weights_shape;
      int example_weights_index = num_dense_features + num_sparse_features * 3;
      TF_RETURN_IF_ERROR(c->WithRank(c->input(example_weights_index), 2,
                                     &example_weights_shape));
      for (int i = 0; i < num_dense_features; ++i) {
        ShapeHandle dense_feature_shape;
        DimensionHandle unused_dim;
        TF_RETURN_IF_ERROR(c->WithRank(c->input(i), 2, &dense_feature_shape));
        TF_RETURN_IF_ERROR(c->Merge(c->Dim(dense_feature_shape, 0),
                                    c->Dim(example_weights_shape, 0),
                                    &unused_dim));
        c->set_output(i, c->Scalar());
      }
      for (int i = 0; i < num_sparse_features; ++i) {
        c->set_output(i + num_dense_features, c->Scalar());
      }
      return Status::OK();
    })
    .Doc(R"doc(
Creates a summary for the given features.

num_dense_features: Number of dense feature groups to compute quantiles on.
num_sparse_features: Number of sparse feature groups to compute quantiles on.
epsilon: Error bound on the computed summary.
dense_float_features: A list of vectors which contains dense values.
sparse_float_feature_indices: List of rank 2 tensors containing the sparse float
feature indices.
sparse_float_feature_values: List of rank 1 tensors containing the sparse float
feature values.
sparse_float_feature_shapes: List of rank 1 tensors containing the shape of the
float feature.
example_weights: Rank 2 (N, 1) tensor of per-example weights. Should match
    dense and sparse features shape.
dense_summaries: A list of serialized QuantileSummaryState for dense columns.
sparse_summaries: A list of serialized QuantileSummaryState for sparse columns.
)doc");

REGISTER_OP("QuantileBuckets")
    .Attr("num_dense_features: int >= 0")
    .Attr("num_sparse_features: int >= 0")
    .Attr("dense_config: list(string)")
    .Attr("sparse_config: list(string)")
    .Input("dense_float_features: num_dense_features * float")
    .Input("sparse_float_feature_indices: num_sparse_features * int64")
    .Input("sparse_float_feature_values: num_sparse_features * float")
    .Input("sparse_float_feature_shapes: num_sparse_features * int64")
    .Input("example_weights: float")
    .Output("dense_buckets: num_dense_features * float")
    .Output("sparse_buckets: num_sparse_features * float")
    .Doc(R"doc(
Computes quantile buckets for a given list of dense and sparse features with
given example weights.

num_dense_features: Number of dense feature groups to compute quantiles on.
num_sparse_features: Number of sparse feature groups to compute quantiles on.
dense_config: Config for computing buckets for dense values.
Each entry is QuantileConfig proto.
sparse_config: Config for computing buckets for sparse feature values.
Each entry is QuantileConfig proto.
dense_float_features: A list of vectors which contains dense values.
sparse_float_feature_indices: List of rank 2 tensors containing the sparse float
feature indices.
sparse_float_feature_values: List of rank 1 tensors containing the sparse float
feature values.
sparse_float_feature_shapes: List of rank 1 tensors containing the shape of the
float feature.
example_weights: Rank 1 tensor containing the example weight tensor.
dense_buckets: Output quantile summary for each dense float tensor
representing boundaries each with "num_quantile" elements.
sparse_buckets: Output quantile summary for each sparse float value tensor
representing boundaries each with "num_quantile" elements.
)doc");

REGISTER_OP("Quantiles")
    .Attr("num_dense_features: int >= 0")
    .Attr("num_sparse_features: int >= 0")
    .Input("dense_values: num_dense_features * float")
    .Input("sparse_values: num_sparse_features * float")
    .Input("dense_buckets: num_dense_features * float")
    .Input("sparse_buckets: num_sparse_features * float")
    .Input("sparse_indices: num_sparse_features * int64")
    .Output("dense_quantiles: num_dense_features * int32")
    .Output("sparse_quantiles: num_sparse_features * int32")
    .Doc(R"doc(
Computes quantile for each a given list of dense and sparse feature values using
the given buckets.

num_dense_features: Number of dense feature groups to generate quantiles for.
num_sparse_features: Number of sparse feature groups to generate quantiles for.
dense_values: List of rank 1 tensors containing the dense values.
sparse_values: List of rank 1 tensors containing the sparse feature values.
dense_buckets: Quantile summary for each of the dense float tensor.
sparse_buckets: Quantile summary for each of the sparse feature float tensor.
sparse_indices: List of rank 2 tensors with indices for sparse float
tensors.
dense_quantiles: Rank 2 tensors representing associated quantiles for each of
dense float tensors and the dimension.
sparse_quantiles: Rank 2 tensors representing associated quantiles for each of
the sparse feature tensors for each of sparse feature dimensions:
[quantile id, dimension id].
)doc");

REGISTER_OP("BucketizeWithInputBoundaries")
    .Input("input: T")
    .Input("boundaries: float")
    .Output("output: int32")
    .Attr("T: {int32, int64, float, double}")
    .SetShapeFn(shape_inference::UnchangedShape)
    .Doc(R"doc(
Bucketizes 'input' based on 'boundaries'. This function is similar to Bucketize
op in core math_ops, except that boundaries are specified using an input tensor,
as compared with a fixed attribute in Bucketize().

For example, if the inputs are
    boundaries = [0, 10, 100]
    input = [[-5, 10000]
             [150,   10]
             [5,    100]]

then the output will be
    output = [[0, 3]
              [3, 2]
              [1, 3]]

input: Any shape of Tensor contains with numeric type.
boundaries: A vector Tensor of sorted floats specifies the boundaries
of the buckets.
output: Same shape as 'input', where each value of input is replaced with its corresponding bucket index.
)doc");

}  // namespace boosted_trees
}  // namespace tensorflow
<commit_msg>boosted_trees: infer the output shapes of Quantiles Op from the input shapes.<commit_after>// Copyright 2017 The TensorFlow Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// =============================================================================
#include "tensorflow/core/framework/common_shape_fns.h"
#include "tensorflow/core/framework/op.h"
#include "tensorflow/core/framework/resource_mgr.h"
#include "tensorflow/core/framework/shape_inference.h"

namespace tensorflow {
namespace boosted_trees {
using shape_inference::DimensionHandle;
using shape_inference::InferenceContext;
using shape_inference::ShapeHandle;

REGISTER_RESOURCE_HANDLE_OP(QuantileStreamResource);

REGISTER_OP("QuantileAccumulatorIsInitialized")
    .Input("quantile_accumulator_handle: resource")
    .Output("is_initialized: bool")
    .SetShapeFn(shape_inference::ScalarShape)
    .Doc(R"doc(
Checks whether a quantile accumulator has been initialized.
)doc");

REGISTER_OP("CreateQuantileAccumulator")
    .Attr("container: string = ''")
    .Attr("shared_name: string = ''")
    .Attr("max_elements: int = 1099511627776")  // 1 << 40
    .Attr("epsilon: float")
    .Attr("num_quantiles: int")
    .Attr("generate_quantiles: bool=False")
    .Input("quantile_accumulator_handle: resource")
    .Input("stamp_token: int64")
    .SetShapeFn([](shape_inference::InferenceContext* c) {
      shape_inference::ShapeHandle unused_input;
      TF_RETURN_IF_ERROR(c->WithRank(c->input(0), 0, &unused_input));
      TF_RETURN_IF_ERROR(c->WithRank(c->input(1), 0, &unused_input));
      return Status::OK();
    })
    .Doc(R"doc(
Creates a stateful accumulator for quantile summaries.

epsilon: Error bound on the quantile summary.
num_quantiles: Number of buckets that we create from the data.
stamp_token: Token to use as the initial value of the resource stamp.
quantile_accumulator_handle: The handle to the accumulator.
)doc");

REGISTER_OP("QuantileAccumulatorAddSummaries")
    .Attr("num_resource_handles: int >= 1")
    .Input("quantile_accumulator_handles: num_resource_handles * resource")
    .Input("stamp_token: int64")
    .Input("summaries: num_resource_handles * string")
    .SetShapeFn([](InferenceContext* c) {
      int num_resource_handles;
      TF_RETURN_IF_ERROR(
          c->GetAttr("num_resource_handles", &num_resource_handles));
      // All the inputs are scalars.
      shape_inference::ShapeHandle unused_input;
      for (int i = 0; i < 2 * num_resource_handles + 1; ++i) {
        TF_RETURN_IF_ERROR(c->WithRank(c->input(i), 0, &unused_input));
      }
      return Status::OK();
    })
    .Doc(R"doc(
Adds each quantile summary to its stream.

quantile_accumulator_handles: The handles to the quantile stream resources.
stamp_token: Stamp token to validate the Read/Write operation.
summaries: A list of serialized QuantileSummaryState.
)doc");

REGISTER_OP("QuantileAccumulatorGetBuckets")
    .Attr("num_resource_handles: int >= 1")
    .Input("quantile_accumulator_handles: num_resource_handles * resource")
    .Input("stamp_token: int64")
    .Output("are_buckets_ready: num_resource_handles * bool")
    .Output("buckets: num_resource_handles * float")
    .SetShapeFn([](InferenceContext* c) {
      int num_resource_handles;
      TF_RETURN_IF_ERROR(
          c->GetAttr("num_resource_handles", &num_resource_handles));
      for (int i = 0; i < num_resource_handles; ++i) {
        c->set_output(i, c->Scalar());
        c->set_output(i + num_resource_handles, c->Vector(c->UnknownDim()));
      }
      return Status::OK();
    })

    .Doc(R"doc(
Returns quantile buckets created during previous flush of the accumulator.

quantile_accumulator_handles: The handles to the quantile stream resources.
stamp_token: Stamp token to validate the Read/Write operation.
are_buckets_ready: Whether the buckets are ready or not.
buckets: Output quantile summary representing boundaries with "num_quantile"
    elements.
)doc");

REGISTER_OP("QuantileAccumulatorFlush")
    .Input("quantile_accumulator_handle: resource")
    .Input("stamp_token: int64")
    .Input("next_stamp_token: int64")
    .Doc(R"doc(
Resets quantile summary streams for each column with a new token.

quantile_accumulator_handle: The handle to the accumulator.
stamp_token: Stamp token for Read/Write operations.
             Any operation with a mismatching token will be dropped.
next_stamp_token: Stamp token to be used for the next iteration.
)doc");

REGISTER_OP("QuantileAccumulatorFlushSummary")
    .Input("quantile_accumulator_handle: resource")
    .Input("stamp_token: int64")
    .Input("next_stamp_token: int64")
    .Output("output: string")
    .Doc(R"doc(
Resets quantile summary stream and returns the summary.

quantile_accumulator_handle: The handle to the accumulator.
stamp_token: Stamp token for Read/Write operations.
             Any operation with a mismatching token will be dropped.
next_stamp_token: Stamp token to be used for the next iteration.
output: A scalar string that is the a summary of the accumulator.
)doc");

REGISTER_OP("QuantileAccumulatorSerialize")
    .Input("quantile_accumulator_handle: resource")
    .Output("stamp_token: int64")
    .Output("stream_state: string")
    .Output("are_buckets_ready: bool")
    .Output("buckets: float")
    .Doc(R"doc(
Serializes the state of the given resource.

quantile_accumulator_handle: The handle to the accumulator.
stamp_token: Stamp token for Read/Write operations.
             Any operation with a mismatching token will be dropped.
stream_state: A serialized QuantileStreamState.
are_buckets_ready: Whether the buckets are ready or not.
buckets: Output quantile buckets representing boundaries with "num_quantile"
    elements.
)doc");

REGISTER_OP("QuantileAccumulatorDeserialize")
    .Input("quantile_accumulator_handle: resource")
    .Input("stamp_token: int64")
    .Input("stream_state: string")
    .Input("are_buckets_ready: bool")
    .Input("buckets: float")
    .Doc(R"doc(
Serializes the state of the given resource.

quantile_accumulator_handle: The handle to the accumulator.
stamp_token: Stamp token for Read/Write operations.
             Any operation with a mismatching token will be dropped.
stream_state: A serialized QuantileStreamState.
are_buckets_ready: Whether the buckets are ready or not.
buckets: Output quantile summary representing boundaries with "num_quantile"
    elements.
)doc");

REGISTER_OP("MakeQuantileSummaries")
    .Attr("num_dense_features: int >= 0")
    .Attr("num_sparse_features: int >= 0")
    .Attr("epsilon: float")
    .Input("dense_float_features: num_dense_features * float")
    .Input("sparse_float_feature_indices: num_sparse_features * int64")
    .Input("sparse_float_feature_values: num_sparse_features * float")
    .Input("sparse_float_feature_shapes: num_sparse_features * int64")
    .Input("example_weights: float")
    .Output("dense_summaries: num_dense_features * string")
    .Output("sparse_summaries: num_sparse_features * string")
    .SetShapeFn([](InferenceContext* c) {
      int num_dense_features;
      TF_RETURN_IF_ERROR(c->GetAttr("num_dense_features", &num_dense_features));
      int num_sparse_features;
      TF_RETURN_IF_ERROR(
          c->GetAttr("num_sparse_features", &num_sparse_features));
      ShapeHandle example_weights_shape;
      int example_weights_index = num_dense_features + num_sparse_features * 3;
      TF_RETURN_IF_ERROR(c->WithRank(c->input(example_weights_index), 2,
                                     &example_weights_shape));
      for (int i = 0; i < num_dense_features; ++i) {
        ShapeHandle dense_feature_shape;
        DimensionHandle unused_dim;
        TF_RETURN_IF_ERROR(c->WithRank(c->input(i), 2, &dense_feature_shape));
        TF_RETURN_IF_ERROR(c->Merge(c->Dim(dense_feature_shape, 0),
                                    c->Dim(example_weights_shape, 0),
                                    &unused_dim));
        c->set_output(i, c->Scalar());
      }
      for (int i = 0; i < num_sparse_features; ++i) {
        c->set_output(i + num_dense_features, c->Scalar());
      }
      return Status::OK();
    })
    .Doc(R"doc(
Creates a summary for the given features.

num_dense_features: Number of dense feature groups to compute quantiles on.
num_sparse_features: Number of sparse feature groups to compute quantiles on.
epsilon: Error bound on the computed summary.
dense_float_features: A list of vectors which contains dense values.
sparse_float_feature_indices: List of rank 2 tensors containing the sparse float
feature indices.
sparse_float_feature_values: List of rank 1 tensors containing the sparse float
feature values.
sparse_float_feature_shapes: List of rank 1 tensors containing the shape of the
float feature.
example_weights: Rank 2 (N, 1) tensor of per-example weights. Should match
    dense and sparse features shape.
dense_summaries: A list of serialized QuantileSummaryState for dense columns.
sparse_summaries: A list of serialized QuantileSummaryState for sparse columns.
)doc");

REGISTER_OP("QuantileBuckets")
    .Attr("num_dense_features: int >= 0")
    .Attr("num_sparse_features: int >= 0")
    .Attr("dense_config: list(string)")
    .Attr("sparse_config: list(string)")
    .Input("dense_float_features: num_dense_features * float")
    .Input("sparse_float_feature_indices: num_sparse_features * int64")
    .Input("sparse_float_feature_values: num_sparse_features * float")
    .Input("sparse_float_feature_shapes: num_sparse_features * int64")
    .Input("example_weights: float")
    .Output("dense_buckets: num_dense_features * float")
    .Output("sparse_buckets: num_sparse_features * float")
    .Doc(R"doc(
Computes quantile buckets for a given list of dense and sparse features with
given example weights.

num_dense_features: Number of dense feature groups to compute quantiles on.
num_sparse_features: Number of sparse feature groups to compute quantiles on.
dense_config: Config for computing buckets for dense values.
Each entry is QuantileConfig proto.
sparse_config: Config for computing buckets for sparse feature values.
Each entry is QuantileConfig proto.
dense_float_features: A list of vectors which contains dense values.
sparse_float_feature_indices: List of rank 2 tensors containing the sparse float
feature indices.
sparse_float_feature_values: List of rank 1 tensors containing the sparse float
feature values.
sparse_float_feature_shapes: List of rank 1 tensors containing the shape of the
float feature.
example_weights: Rank 1 tensor containing the example weight tensor.
dense_buckets: Output quantile summary for each dense float tensor
representing boundaries each with "num_quantile" elements.
sparse_buckets: Output quantile summary for each sparse float value tensor
representing boundaries each with "num_quantile" elements.
)doc");

REGISTER_OP("Quantiles")
    .Attr("num_dense_features: int >= 0")
    .Attr("num_sparse_features: int >= 0")
    .Input("dense_values: num_dense_features * float")
    .Input("sparse_values: num_sparse_features * float")
    .Input("dense_buckets: num_dense_features * float")
    .Input("sparse_buckets: num_sparse_features * float")
    .Input("sparse_indices: num_sparse_features * int64")
    .Output("dense_quantiles: num_dense_features * int32")
    .Output("sparse_quantiles: num_sparse_features * int32")
    .SetShapeFn([](InferenceContext* c) {
      int num_dense_features;
      TF_RETURN_IF_ERROR(c->GetAttr("num_dense_features", &num_dense_features));
      int num_sparse_features;
      TF_RETURN_IF_ERROR(
          c->GetAttr("num_sparse_features", &num_sparse_features));
      // Set output shapes (dense_quantiles and sparse_quantiles) by the
      // relevant inputs (dense_values and sparse_values). Note that the output
      // has an additional dimension for dimension_ids.
      for (int i = 0; i < num_dense_features + num_sparse_features; ++i) {
        c->set_output(i, c->MakeShape({c->Dim(c->input(i), 0), 2}));
      }
      return Status::OK();
    })
    .Doc(R"doc(
Computes quantile for each a given list of dense and sparse feature values using
the given buckets.

num_dense_features: Number of dense feature groups to generate quantiles for.
num_sparse_features: Number of sparse feature groups to generate quantiles for.
dense_values: List of rank 1 tensors containing the dense values.
sparse_values: List of rank 1 tensors containing the sparse feature values.
dense_buckets: Quantile summary for each of the dense float tensor.
sparse_buckets: Quantile summary for each of the sparse feature float tensor.
sparse_indices: List of rank 2 tensors with indices for sparse float
tensors.
dense_quantiles: Rank 2 tensors representing associated quantiles for each of
dense float tensors and the dimension.
sparse_quantiles: Rank 2 tensors representing associated quantiles for each of
the sparse feature tensors for each of sparse feature dimensions:
[quantile id, dimension id].
)doc");

REGISTER_OP("BucketizeWithInputBoundaries")
    .Input("input: T")
    .Input("boundaries: float")
    .Output("output: int32")
    .Attr("T: {int32, int64, float, double}")
    .SetShapeFn(shape_inference::UnchangedShape)
    .Doc(R"doc(
Bucketizes 'input' based on 'boundaries'. This function is similar to Bucketize
op in core math_ops, except that boundaries are specified using an input tensor,
as compared with a fixed attribute in Bucketize().

For example, if the inputs are
    boundaries = [0, 10, 100]
    input = [[-5, 10000]
             [150,   10]
             [5,    100]]

then the output will be
    output = [[0, 3]
              [3, 2]
              [1, 3]]

input: Any shape of Tensor contains with numeric type.
boundaries: A vector Tensor of sorted floats specifies the boundaries
of the buckets.
output: Same shape as 'input', where each value of input is replaced with its corresponding bucket index.
)doc");

}  // namespace boosted_trees
}  // namespace tensorflow
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/command_line.h"
#include "base/path_service.h"
#include "base/stringprintf.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/debugger/devtools_window.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "content/browser/content_browser_client.h"
#include "content/browser/debugger/devtools_client_host.h"
#include "content/browser/debugger/devtools_manager.h"
#include "content/browser/debugger/worker_devtools_manager_io.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/browser/worker_host/worker_process_host.h"
#include "content/common/notification_registrar.h"
#include "content/common/notification_service.h"
#include "net/test/test_server.h"

namespace {

// Used to block until a dev tools client window's browser is closed.
class BrowserClosedObserver : public NotificationObserver {
 public:
  explicit BrowserClosedObserver(Browser* browser) {
    registrar_.Add(this, chrome::NOTIFICATION_BROWSER_CLOSED,
                   Source<Browser>(browser));
    ui_test_utils::RunMessageLoop();
  }

  virtual void Observe(int type,
                       const NotificationSource& source,
                       const NotificationDetails& details) {
    MessageLoopForUI::current()->Quit();
  }

 private:
  NotificationRegistrar registrar_;
  DISALLOW_COPY_AND_ASSIGN(BrowserClosedObserver);
};

// The delay waited in some cases where we don't have a notifications for an
// action we take.
const int kActionDelayMs = 500;

const char kDebuggerTestPage[] = "files/devtools/debugger_test_page.html";
const char kPauseWhenLoadingDevTools[] =
    "files/devtools/pause_when_loading_devtools.html";
const char kPauseWhenScriptIsRunning[] =
    "files/devtools/pause_when_script_is_running.html";
const char kPageWithContentScript[] =
    "files/devtools/page_with_content_script.html";
const char kChunkedTestPage[] = "chunked";
const char kSlowTestPage[] =
    "chunked?waitBeforeHeaders=100&waitBetweenChunks=100&chunksNumber=2";
const char kSharedWorkerTestPage[] =
    "files/workers/workers_ui_shared_worker.html";

void RunTestFuntion(DevToolsWindow* window, const char* test_name) {
  std::string result;

  // At first check that JavaScript part of the front-end is loaded by
  // checking that global variable uiTests exists(it's created after all js
  // files have been loaded) and has runTest method.
  ASSERT_TRUE(
      ui_test_utils::ExecuteJavaScriptAndExtractString(
          window->GetRenderViewHost(),
          L"",
          L"window.domAutomationController.send("
          L"'' + (window.uiTests && (typeof uiTests.runTest)));",
          &result));

  if (result == "function") {
    ASSERT_TRUE(
        ui_test_utils::ExecuteJavaScriptAndExtractString(
            window->GetRenderViewHost(),
            L"",
            UTF8ToWide(base::StringPrintf("uiTests.runTest('%s')",
                                          test_name)),
            &result));
    EXPECT_EQ("[OK]", result);
  } else {
    FAIL() << "DevTools front-end is broken.";
  }
}

class DevToolsSanityTest : public InProcessBrowserTest {
 public:
  DevToolsSanityTest()
      : window_(NULL),
        inspected_rvh_(NULL) {
    set_show_window(true);
    EnableDOMAutomation();
  }

 protected:
  void RunTest(const std::string& test_name, const std::string& test_page) {
    OpenDevToolsWindow(test_page);
    RunTestFuntion(window_, test_name.c_str());
    CloseDevToolsWindow();
  }

  void OpenDevToolsWindow(const std::string& test_page) {
    ASSERT_TRUE(test_server()->Start());
    GURL url = test_server()->GetURL(test_page);
    ui_test_utils::NavigateToURL(browser(), url);

    inspected_rvh_ = GetInspectedTab()->render_view_host();
    window_ = DevToolsWindow::OpenDevToolsWindow(inspected_rvh_);
    RenderViewHost* client_rvh = window_->GetRenderViewHost();
    TabContents* client_contents = client_rvh->delegate()->GetAsTabContents();
    ui_test_utils::WaitForNavigation(&client_contents->controller());
  }

  TabContents* GetInspectedTab() {
    return browser()->GetTabContentsAt(0);
  }

  void CloseDevToolsWindow() {
    DevToolsManager* devtools_manager = DevToolsManager::GetInstance();
    // UnregisterDevToolsClientHostFor may destroy window_ so store the browser
    // first.
    Browser* browser = window_->browser();
    devtools_manager->UnregisterDevToolsClientHostFor(inspected_rvh_);

    // Wait only when DevToolsWindow has a browser. For docked DevTools, this
    // is NULL and we skip the wait.
    if (browser)
      BrowserClosedObserver close_observer(browser);
  }

  DevToolsWindow* window_;
  RenderViewHost* inspected_rvh_;
};

class CancelableQuitTask : public Task {
 public:
  explicit CancelableQuitTask(const std::string& timeout_message)
      : timeout_message_(timeout_message),
        cancelled_(false) {
  }

  void cancel() {
    cancelled_ = true;
  }

  virtual void Run() {
    if (cancelled_) {
      return;
    }
    FAIL() << timeout_message_;
    MessageLoop::current()->Quit();
  }

 private:
  std::string timeout_message_;
  bool cancelled_;
};

// Base class for DevTools tests that test devtools functionality for
// extensions and content scripts.
class DevToolsExtensionDebugTest : public DevToolsSanityTest,
                                   public NotificationObserver {
 public:
  DevToolsExtensionDebugTest() : DevToolsSanityTest() {
    PathService::Get(chrome::DIR_TEST_DATA, &test_extensions_dir_);
    test_extensions_dir_ = test_extensions_dir_.AppendASCII("devtools");
    test_extensions_dir_ = test_extensions_dir_.AppendASCII("extensions");
  }

 protected:
  // Load an extention from test\data\devtools\extensions\<extension_name>
  void LoadExtension(const char* extension_name) {
    FilePath path = test_extensions_dir_.AppendASCII(extension_name);
    ASSERT_TRUE(LoadExtensionFromPath(path)) << "Failed to load extension.";
  }

 private:
  bool LoadExtensionFromPath(const FilePath& path) {
    ExtensionService* service = browser()->profile()->GetExtensionService();
    size_t num_before = service->extensions()->size();
    {
      NotificationRegistrar registrar;
      registrar.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
                    NotificationService::AllSources());
      CancelableQuitTask* delayed_quit =
          new CancelableQuitTask("Extension load timed out.");
      MessageLoop::current()->PostDelayedTask(FROM_HERE, delayed_quit,
          4*1000);
      service->LoadExtension(path);
      ui_test_utils::RunMessageLoop();
      delayed_quit->cancel();
    }
    size_t num_after = service->extensions()->size();
    if (num_after != (num_before + 1))
      return false;

    return WaitForExtensionHostsToLoad();
  }

  bool WaitForExtensionHostsToLoad() {
    // Wait for all the extension hosts that exist to finish loading.
    // NOTE: This assumes that the extension host list is not changing while
    // this method is running.

    NotificationRegistrar registrar;
    registrar.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING,
                  NotificationService::AllSources());
    CancelableQuitTask* delayed_quit =
        new CancelableQuitTask("Extension host load timed out.");
    MessageLoop::current()->PostDelayedTask(FROM_HERE, delayed_quit,
        4*1000);

    ExtensionProcessManager* manager =
          browser()->profile()->GetExtensionProcessManager();
    for (ExtensionProcessManager::const_iterator iter = manager->begin();
         iter != manager->end();) {
      if ((*iter)->did_stop_loading())
        ++iter;
      else
        ui_test_utils::RunMessageLoop();
    }

    delayed_quit->cancel();
    return true;
  }

  void Observe(int type,
               const NotificationSource& source,
               const NotificationDetails& details) {
    switch (type) {
      case chrome::NOTIFICATION_EXTENSION_LOADED:
      case chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING:
        MessageLoopForUI::current()->Quit();
        break;
      default:
        NOTREACHED();
        break;
    }
  }

  FilePath test_extensions_dir_;
};

// Used to block until a navigation completes.
class LoadStopObserver : public NotificationObserver {
 public:
  explicit LoadStopObserver(const NotificationSource& source) : done_(false) {
    registrar_.Add(this, content::NOTIFICATION_LOAD_STOP, source);
    ui_test_utils::RunMessageLoop();
  }

 private:
  virtual void Observe(int type,
                       const NotificationSource& source,
                       const NotificationDetails& details) {
    if (type == content::NOTIFICATION_LOAD_STOP) {
      if (done_)
        return;
      done_ = true;
      MessageLoopForUI::current()->Quit();
    }
  }

  NotificationRegistrar registrar_;
  bool done_;
  DISALLOW_COPY_AND_ASSIGN(LoadStopObserver);
};

class WorkerDevToolsSanityTest : public InProcessBrowserTest {
 public:
  WorkerDevToolsSanityTest() : window_(NULL) {
    set_show_window(true);
    EnableDOMAutomation();
  }

 protected:
  void RunTest(const char* test_name, const char* test_page) {
    ASSERT_TRUE(test_server()->Start());
    GURL url = test_server()->GetURL(test_page);
    ui_test_utils::NavigateToURL(browser(), url);

    OpenDevToolsWindowForFirstSharedWorker();
    RunTestFuntion(window_, test_name);
    CloseDevToolsWindow();
  }

  static void OpenDevToolsWindowForFirstSharedWorkerOnIOThread(int attempt) {
    BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS);
    bool found = false;
    for (; !iter.Done(); ++iter) {
      WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter);
      const WorkerProcessHost::Instances& instances = worker->instances();
      for (WorkerProcessHost::Instances::const_iterator i = instances.begin();
           i != instances.end(); ++i) {
        if (!i->shared())
          continue;
        WorkerDevToolsManagerIO::GetInstance()->OpenDevToolsForWorker(
            worker->id(), i->worker_route_id());
        found = true;
        break;
      }
    }
    if (found) {
      BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
          new MessageLoop::QuitTask);
    } else if (attempt < 30) {
      MessageLoop::current()->PostDelayedTask(
          FROM_HERE,
          NewRunnableFunction(
              &OpenDevToolsWindowForFirstSharedWorkerOnIOThread, attempt + 1),
          100);
    } else {
      FAIL() << "Shared worker not found.";
    }

  }

  void OpenDevToolsWindowForFirstSharedWorker() {
    BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, NewRunnableFunction(
        &OpenDevToolsWindowForFirstSharedWorkerOnIOThread, 1));
    ui_test_utils::RunMessageLoop();
    window_ = static_cast<DevToolsWindow*>(
                  DevToolsClientHost::GetDevToolsClientHostForTest());
    ASSERT_TRUE(window_ != NULL);

    RenderViewHost* client_rvh = window_->GetRenderViewHost();
    TabContents* client_contents = client_rvh->delegate()->GetAsTabContents();
    if (client_contents->IsLoading()) {
      LoadStopObserver(
          Source<NavigationController>(&client_contents->controller()));
    }
  }

  void CloseDevToolsWindow() {
    Browser* browser = window_->browser();
    browser->CloseAllTabs();
    BrowserClosedObserver close_observer(browser);
  }

  DevToolsWindow* window_;
};

// Tests scripts panel showing.
IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestShowScriptsTab) {
  RunTest("testShowScriptsTab", kDebuggerTestPage);
}

// Tests that scripts tab is populated with inspected scripts even if it
// hadn't been shown by the moment inspected paged refreshed.
// @see http://crbug.com/26312
IN_PROC_BROWSER_TEST_F(DevToolsSanityTest,
                       TestScriptsTabIsPopulatedOnInspectedPageRefresh) {
  // Clear inspector settings to ensure that Elements will be
  // current panel when DevTools window is open.
  content::GetContentClient()->browser()->ClearInspectorSettings(
      GetInspectedTab()->render_view_host());
  RunTest("testScriptsTabIsPopulatedOnInspectedPageRefresh",
          kDebuggerTestPage);
}

// Tests that a content script is in the scripts list.
// This test is disabled, see bug 28961.
IN_PROC_BROWSER_TEST_F(DevToolsExtensionDebugTest,
                       TestContentScriptIsPresent) {
  LoadExtension("simple_content_script");
  RunTest("testContentScriptIsPresent", kPageWithContentScript);
}

// Tests that scripts are not duplicated after Scripts Panel switch.
IN_PROC_BROWSER_TEST_F(DevToolsSanityTest,
                       TestNoScriptDuplicatesOnPanelSwitch) {
  RunTest("testNoScriptDuplicatesOnPanelSwitch", kDebuggerTestPage);
}

// Tests that debugger works correctly if pause event occurs when DevTools
// frontend is being loaded.
// Flaky - http://crbug.com/69719.
IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, FLAKY_TestPauseWhenLoadingDevTools) {
  RunTest("testPauseWhenLoadingDevTools", kPauseWhenLoadingDevTools);
}

// Tests that pressing 'Pause' will pause script execution if the script
// is already running.
IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, FLAKY_TestPauseWhenScriptIsRunning) {
  RunTest("testPauseWhenScriptIsRunning", kPauseWhenScriptIsRunning);
}

// Tests network timing.
IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkTiming) {
  RunTest("testNetworkTiming", kSlowTestPage);
}

// Tests network size.
IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkSize) {
  RunTest("testNetworkSize", kChunkedTestPage);
}

// Tests raw headers text.
IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkSyncSize) {
  RunTest("testNetworkSyncSize", kChunkedTestPage);
}

// Tests raw headers text.
IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkRawHeadersText) {
  RunTest("testNetworkRawHeadersText", kChunkedTestPage);
}

IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestPageWithNoJavaScript) {
  OpenDevToolsWindow("about:blank");
  std::string result;
  ASSERT_TRUE(
      ui_test_utils::ExecuteJavaScriptAndExtractString(
          window_->GetRenderViewHost(),
          L"",
          L"window.domAutomationController.send("
          L"'' + (window.uiTests && (typeof uiTests.runTest)));",
          &result));
  ASSERT_EQ("function", result) << "DevTools front-end is broken.";
  CloseDevToolsWindow();
}

#if defined(OS_WINDOWS)
// Flakily fails: http://crbug.com/89845
#define MAYBE_InspectSharedWorker FLAKY_InspectSharedWorker
#else
#define MAYBE_InspectSharedWorker InspectSharedWorker
#endif
IN_PROC_BROWSER_TEST_F(WorkerDevToolsSanityTest, MAYBE_InspectSharedWorker) {
  RunTest("testSharedWorker", kSharedWorkerTestPage);
}

}  // namespace
<commit_msg>Extending the flaky test flag for the InspectSharedWorker interactive test to Linux and Chrome OS.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/command_line.h"
#include "base/path_service.h"
#include "base/stringprintf.h"
#include "base/utf_string_conversions.h"
#include "chrome/browser/debugger/devtools_window.h"
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "content/browser/content_browser_client.h"
#include "content/browser/debugger/devtools_client_host.h"
#include "content/browser/debugger/devtools_manager.h"
#include "content/browser/debugger/worker_devtools_manager_io.h"
#include "content/browser/renderer_host/render_view_host.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/browser/worker_host/worker_process_host.h"
#include "content/common/notification_registrar.h"
#include "content/common/notification_service.h"
#include "net/test/test_server.h"

namespace {

// Used to block until a dev tools client window's browser is closed.
class BrowserClosedObserver : public NotificationObserver {
 public:
  explicit BrowserClosedObserver(Browser* browser) {
    registrar_.Add(this, chrome::NOTIFICATION_BROWSER_CLOSED,
                   Source<Browser>(browser));
    ui_test_utils::RunMessageLoop();
  }

  virtual void Observe(int type,
                       const NotificationSource& source,
                       const NotificationDetails& details) {
    MessageLoopForUI::current()->Quit();
  }

 private:
  NotificationRegistrar registrar_;
  DISALLOW_COPY_AND_ASSIGN(BrowserClosedObserver);
};

// The delay waited in some cases where we don't have a notifications for an
// action we take.
const int kActionDelayMs = 500;

const char kDebuggerTestPage[] = "files/devtools/debugger_test_page.html";
const char kPauseWhenLoadingDevTools[] =
    "files/devtools/pause_when_loading_devtools.html";
const char kPauseWhenScriptIsRunning[] =
    "files/devtools/pause_when_script_is_running.html";
const char kPageWithContentScript[] =
    "files/devtools/page_with_content_script.html";
const char kChunkedTestPage[] = "chunked";
const char kSlowTestPage[] =
    "chunked?waitBeforeHeaders=100&waitBetweenChunks=100&chunksNumber=2";
const char kSharedWorkerTestPage[] =
    "files/workers/workers_ui_shared_worker.html";

void RunTestFuntion(DevToolsWindow* window, const char* test_name) {
  std::string result;

  // At first check that JavaScript part of the front-end is loaded by
  // checking that global variable uiTests exists(it's created after all js
  // files have been loaded) and has runTest method.
  ASSERT_TRUE(
      ui_test_utils::ExecuteJavaScriptAndExtractString(
          window->GetRenderViewHost(),
          L"",
          L"window.domAutomationController.send("
          L"'' + (window.uiTests && (typeof uiTests.runTest)));",
          &result));

  if (result == "function") {
    ASSERT_TRUE(
        ui_test_utils::ExecuteJavaScriptAndExtractString(
            window->GetRenderViewHost(),
            L"",
            UTF8ToWide(base::StringPrintf("uiTests.runTest('%s')",
                                          test_name)),
            &result));
    EXPECT_EQ("[OK]", result);
  } else {
    FAIL() << "DevTools front-end is broken.";
  }
}

class DevToolsSanityTest : public InProcessBrowserTest {
 public:
  DevToolsSanityTest()
      : window_(NULL),
        inspected_rvh_(NULL) {
    set_show_window(true);
    EnableDOMAutomation();
  }

 protected:
  void RunTest(const std::string& test_name, const std::string& test_page) {
    OpenDevToolsWindow(test_page);
    RunTestFuntion(window_, test_name.c_str());
    CloseDevToolsWindow();
  }

  void OpenDevToolsWindow(const std::string& test_page) {
    ASSERT_TRUE(test_server()->Start());
    GURL url = test_server()->GetURL(test_page);
    ui_test_utils::NavigateToURL(browser(), url);

    inspected_rvh_ = GetInspectedTab()->render_view_host();
    window_ = DevToolsWindow::OpenDevToolsWindow(inspected_rvh_);
    RenderViewHost* client_rvh = window_->GetRenderViewHost();
    TabContents* client_contents = client_rvh->delegate()->GetAsTabContents();
    ui_test_utils::WaitForNavigation(&client_contents->controller());
  }

  TabContents* GetInspectedTab() {
    return browser()->GetTabContentsAt(0);
  }

  void CloseDevToolsWindow() {
    DevToolsManager* devtools_manager = DevToolsManager::GetInstance();
    // UnregisterDevToolsClientHostFor may destroy window_ so store the browser
    // first.
    Browser* browser = window_->browser();
    devtools_manager->UnregisterDevToolsClientHostFor(inspected_rvh_);

    // Wait only when DevToolsWindow has a browser. For docked DevTools, this
    // is NULL and we skip the wait.
    if (browser)
      BrowserClosedObserver close_observer(browser);
  }

  DevToolsWindow* window_;
  RenderViewHost* inspected_rvh_;
};

class CancelableQuitTask : public Task {
 public:
  explicit CancelableQuitTask(const std::string& timeout_message)
      : timeout_message_(timeout_message),
        cancelled_(false) {
  }

  void cancel() {
    cancelled_ = true;
  }

  virtual void Run() {
    if (cancelled_) {
      return;
    }
    FAIL() << timeout_message_;
    MessageLoop::current()->Quit();
  }

 private:
  std::string timeout_message_;
  bool cancelled_;
};

// Base class for DevTools tests that test devtools functionality for
// extensions and content scripts.
class DevToolsExtensionDebugTest : public DevToolsSanityTest,
                                   public NotificationObserver {
 public:
  DevToolsExtensionDebugTest() : DevToolsSanityTest() {
    PathService::Get(chrome::DIR_TEST_DATA, &test_extensions_dir_);
    test_extensions_dir_ = test_extensions_dir_.AppendASCII("devtools");
    test_extensions_dir_ = test_extensions_dir_.AppendASCII("extensions");
  }

 protected:
  // Load an extention from test\data\devtools\extensions\<extension_name>
  void LoadExtension(const char* extension_name) {
    FilePath path = test_extensions_dir_.AppendASCII(extension_name);
    ASSERT_TRUE(LoadExtensionFromPath(path)) << "Failed to load extension.";
  }

 private:
  bool LoadExtensionFromPath(const FilePath& path) {
    ExtensionService* service = browser()->profile()->GetExtensionService();
    size_t num_before = service->extensions()->size();
    {
      NotificationRegistrar registrar;
      registrar.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
                    NotificationService::AllSources());
      CancelableQuitTask* delayed_quit =
          new CancelableQuitTask("Extension load timed out.");
      MessageLoop::current()->PostDelayedTask(FROM_HERE, delayed_quit,
          4*1000);
      service->LoadExtension(path);
      ui_test_utils::RunMessageLoop();
      delayed_quit->cancel();
    }
    size_t num_after = service->extensions()->size();
    if (num_after != (num_before + 1))
      return false;

    return WaitForExtensionHostsToLoad();
  }

  bool WaitForExtensionHostsToLoad() {
    // Wait for all the extension hosts that exist to finish loading.
    // NOTE: This assumes that the extension host list is not changing while
    // this method is running.

    NotificationRegistrar registrar;
    registrar.Add(this, chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING,
                  NotificationService::AllSources());
    CancelableQuitTask* delayed_quit =
        new CancelableQuitTask("Extension host load timed out.");
    MessageLoop::current()->PostDelayedTask(FROM_HERE, delayed_quit,
        4*1000);

    ExtensionProcessManager* manager =
          browser()->profile()->GetExtensionProcessManager();
    for (ExtensionProcessManager::const_iterator iter = manager->begin();
         iter != manager->end();) {
      if ((*iter)->did_stop_loading())
        ++iter;
      else
        ui_test_utils::RunMessageLoop();
    }

    delayed_quit->cancel();
    return true;
  }

  void Observe(int type,
               const NotificationSource& source,
               const NotificationDetails& details) {
    switch (type) {
      case chrome::NOTIFICATION_EXTENSION_LOADED:
      case chrome::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING:
        MessageLoopForUI::current()->Quit();
        break;
      default:
        NOTREACHED();
        break;
    }
  }

  FilePath test_extensions_dir_;
};

// Used to block until a navigation completes.
class LoadStopObserver : public NotificationObserver {
 public:
  explicit LoadStopObserver(const NotificationSource& source) : done_(false) {
    registrar_.Add(this, content::NOTIFICATION_LOAD_STOP, source);
    ui_test_utils::RunMessageLoop();
  }

 private:
  virtual void Observe(int type,
                       const NotificationSource& source,
                       const NotificationDetails& details) {
    if (type == content::NOTIFICATION_LOAD_STOP) {
      if (done_)
        return;
      done_ = true;
      MessageLoopForUI::current()->Quit();
    }
  }

  NotificationRegistrar registrar_;
  bool done_;
  DISALLOW_COPY_AND_ASSIGN(LoadStopObserver);
};

class WorkerDevToolsSanityTest : public InProcessBrowserTest {
 public:
  WorkerDevToolsSanityTest() : window_(NULL) {
    set_show_window(true);
    EnableDOMAutomation();
  }

 protected:
  void RunTest(const char* test_name, const char* test_page) {
    ASSERT_TRUE(test_server()->Start());
    GURL url = test_server()->GetURL(test_page);
    ui_test_utils::NavigateToURL(browser(), url);

    OpenDevToolsWindowForFirstSharedWorker();
    RunTestFuntion(window_, test_name);
    CloseDevToolsWindow();
  }

  static void OpenDevToolsWindowForFirstSharedWorkerOnIOThread(int attempt) {
    BrowserChildProcessHost::Iterator iter(ChildProcessInfo::WORKER_PROCESS);
    bool found = false;
    for (; !iter.Done(); ++iter) {
      WorkerProcessHost* worker = static_cast<WorkerProcessHost*>(*iter);
      const WorkerProcessHost::Instances& instances = worker->instances();
      for (WorkerProcessHost::Instances::const_iterator i = instances.begin();
           i != instances.end(); ++i) {
        if (!i->shared())
          continue;
        WorkerDevToolsManagerIO::GetInstance()->OpenDevToolsForWorker(
            worker->id(), i->worker_route_id());
        found = true;
        break;
      }
    }
    if (found) {
      BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
          new MessageLoop::QuitTask);
    } else if (attempt < 30) {
      MessageLoop::current()->PostDelayedTask(
          FROM_HERE,
          NewRunnableFunction(
              &OpenDevToolsWindowForFirstSharedWorkerOnIOThread, attempt + 1),
          100);
    } else {
      FAIL() << "Shared worker not found.";
    }

  }

  void OpenDevToolsWindowForFirstSharedWorker() {
    BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, NewRunnableFunction(
        &OpenDevToolsWindowForFirstSharedWorkerOnIOThread, 1));
    ui_test_utils::RunMessageLoop();
    window_ = static_cast<DevToolsWindow*>(
                  DevToolsClientHost::GetDevToolsClientHostForTest());
    ASSERT_TRUE(window_ != NULL);

    RenderViewHost* client_rvh = window_->GetRenderViewHost();
    TabContents* client_contents = client_rvh->delegate()->GetAsTabContents();
    if (client_contents->IsLoading()) {
      LoadStopObserver(
          Source<NavigationController>(&client_contents->controller()));
    }
  }

  void CloseDevToolsWindow() {
    Browser* browser = window_->browser();
    browser->CloseAllTabs();
    BrowserClosedObserver close_observer(browser);
  }

  DevToolsWindow* window_;
};

// Tests scripts panel showing.
IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestShowScriptsTab) {
  RunTest("testShowScriptsTab", kDebuggerTestPage);
}

// Tests that scripts tab is populated with inspected scripts even if it
// hadn't been shown by the moment inspected paged refreshed.
// @see http://crbug.com/26312
IN_PROC_BROWSER_TEST_F(DevToolsSanityTest,
                       TestScriptsTabIsPopulatedOnInspectedPageRefresh) {
  // Clear inspector settings to ensure that Elements will be
  // current panel when DevTools window is open.
  content::GetContentClient()->browser()->ClearInspectorSettings(
      GetInspectedTab()->render_view_host());
  RunTest("testScriptsTabIsPopulatedOnInspectedPageRefresh",
          kDebuggerTestPage);
}

// Tests that a content script is in the scripts list.
// This test is disabled, see bug 28961.
IN_PROC_BROWSER_TEST_F(DevToolsExtensionDebugTest,
                       TestContentScriptIsPresent) {
  LoadExtension("simple_content_script");
  RunTest("testContentScriptIsPresent", kPageWithContentScript);
}

// Tests that scripts are not duplicated after Scripts Panel switch.
IN_PROC_BROWSER_TEST_F(DevToolsSanityTest,
                       TestNoScriptDuplicatesOnPanelSwitch) {
  RunTest("testNoScriptDuplicatesOnPanelSwitch", kDebuggerTestPage);
}

// Tests that debugger works correctly if pause event occurs when DevTools
// frontend is being loaded.
// Flaky - http://crbug.com/69719.
IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, FLAKY_TestPauseWhenLoadingDevTools) {
  RunTest("testPauseWhenLoadingDevTools", kPauseWhenLoadingDevTools);
}

// Tests that pressing 'Pause' will pause script execution if the script
// is already running.
IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, FLAKY_TestPauseWhenScriptIsRunning) {
  RunTest("testPauseWhenScriptIsRunning", kPauseWhenScriptIsRunning);
}

// Tests network timing.
IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkTiming) {
  RunTest("testNetworkTiming", kSlowTestPage);
}

// Tests network size.
IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkSize) {
  RunTest("testNetworkSize", kChunkedTestPage);
}

// Tests raw headers text.
IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkSyncSize) {
  RunTest("testNetworkSyncSize", kChunkedTestPage);
}

// Tests raw headers text.
IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestNetworkRawHeadersText) {
  RunTest("testNetworkRawHeadersText", kChunkedTestPage);
}

IN_PROC_BROWSER_TEST_F(DevToolsSanityTest, TestPageWithNoJavaScript) {
  OpenDevToolsWindow("about:blank");
  std::string result;
  ASSERT_TRUE(
      ui_test_utils::ExecuteJavaScriptAndExtractString(
          window_->GetRenderViewHost(),
          L"",
          L"window.domAutomationController.send("
          L"'' + (window.uiTests && (typeof uiTests.runTest)));",
          &result));
  ASSERT_EQ("function", result) << "DevTools front-end is broken.";
  CloseDevToolsWindow();
}

#if defined(OS_WINDOWS) || defined(OS_LINUX) || defined(OS_CHROMEOS)
// Flakily fails: http://crbug.com/89845
#define MAYBE_InspectSharedWorker FLAKY_InspectSharedWorker
#else
#define MAYBE_InspectSharedWorker InspectSharedWorker
#endif
IN_PROC_BROWSER_TEST_F(WorkerDevToolsSanityTest, MAYBE_InspectSharedWorker) {
  RunTest("testSharedWorker", kSharedWorkerTestPage);
}

}  // namespace
<|endoftext|>


<commit_before>/*
 * Open Chinese Convert
 *
 * Copyright 2010-2014 BYVoid <byvoid@byvoid.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "CmdLineOutput.hpp"
#include "Config.hpp"
#include "Converter.hpp"
#include "UTF8Util.hpp"

using namespace opencc;

Optional<string> inputFileName = Optional<string>::Null();
Optional<string> outputFileName = Optional<string>::Null();
string configFileName;
bool noFlush;
Config config;
ConverterPtr converter;

FILE* GetOutputStream() {
  if (outputFileName.IsNull()) {
    return stdout;
  } else {
    FILE* fp = fopen(outputFileName.Get().c_str(), "w");
    if (!fp) {
      throw FileNotWritable(outputFileName.Get());
    }
    return fp;
  }
}

void ConvertLineByLine() {
  std::istream& inputStream = std::cin;
  FILE* fout = GetOutputStream();
  bool isFirstLine = true;
  while (!inputStream.eof()) {
    if (!isFirstLine) {
      fputs("\n", fout);
    } else {
      isFirstLine = false;
    }
    string line;
    std::getline(inputStream, line);
    const string& converted = converter->Convert(line);
    fputs(converted.c_str(), fout);
    if (!noFlush) {
      // Flush every line if the output stream is stdout.
      fflush(fout);
    }
  }
  fclose(fout);
}

void Convert() {
  const int BUFFER_SIZE = 1024 * 1024;
  static bool bufferInitialized = false;
  static string buffer;
  static char* bufferBegin;
  static const char* bufferEnd;
  static char* bufferPtr;
  static size_t bufferSizeAvailble;
  if (!bufferInitialized) {
    bufferInitialized = true;
    buffer.resize(BUFFER_SIZE + 1);
    bufferBegin = const_cast<char*>(buffer.c_str());
    bufferEnd = buffer.c_str() + BUFFER_SIZE;
    bufferPtr = bufferBegin;
    bufferSizeAvailble = BUFFER_SIZE;
  }

  FILE* fin = fopen(inputFileName.Get().c_str(), "r");
  if (!fin) {
    throw FileNotFound(inputFileName.Get());
  }
  FILE* fout = GetOutputStream();
  while (!feof(fin)) {
    size_t length = fread(bufferPtr, sizeof(char), bufferSizeAvailble, fin);
    bufferPtr[length] = '\0';
    size_t remainingLength = 0;
    string remainingTemp;
    if (length == bufferSizeAvailble) {
      // fread may breaks UTF8 character
      // Find the end of last character
      char* lastChPtr = bufferBegin;
      while (lastChPtr < bufferEnd) {
        size_t nextCharLen = UTF8Util::NextCharLength(lastChPtr);
        if (lastChPtr + nextCharLen > bufferEnd) {
          break;
        }
        lastChPtr += nextCharLen;
      }
      remainingLength = bufferEnd - lastChPtr;
      if (remainingLength > 0) {
        remainingTemp = UTF8Util::FromSubstr(lastChPtr, remainingLength);
        *lastChPtr = '\0';
      }
    }
    // Perform conversion
    const string& converted = converter->Convert(buffer);
    fputs(converted.c_str(), fout);
    if (!noFlush) {
      // Flush every line if the output stream is stdout.
      fflush(fout);
    }
    // Reset pointer
    bufferPtr = bufferBegin + remainingLength;
    bufferSizeAvailble = BUFFER_SIZE - remainingLength;
    if (remainingLength > 0) {
      strncpy(bufferBegin, remainingTemp.c_str(), remainingLength);
    }
  }
  fclose(fout);
}

int main(int argc, const char* argv[]) {
  try {
    TCLAP::CmdLine cmd("Open Chinese Convert (OpenCC) Command Line Tool", ' ',
                       VERSION);
    CmdLineOutput cmdLineOutput;
    cmd.setOutput(&cmdLineOutput);

    TCLAP::ValueArg<string> configArg(
        "c", "config", "Configuration file", false /* required */,
        "s2t.json" /* default */, "file" /* type */, cmd);
    TCLAP::ValueArg<string> outputArg("o", "output", "Write converted text to",
                                      false /* required */, "" /* default */,
                                      "file" /* type */, cmd);
    TCLAP::ValueArg<string> inputArg("i", "input", "Read original text from",
                                     false /* required */, "" /* default */,
                                     "file" /* type */, cmd);
    TCLAP::ValueArg<bool> noFlushArg(
        "", "noflush", "Disable flush for every line", false /* required */,
        false /* default */, "bool" /* type */, cmd);
    cmd.parse(argc, argv);
    configFileName = configArg.getValue();
    noFlush = noFlushArg.getValue();
    if (inputArg.isSet()) {
      inputFileName = Optional<string>(inputArg.getValue());
    }
    if (outputArg.isSet()) {
      outputFileName = Optional<string>(outputArg.getValue());
      noFlush = true;
    }
    converter = config.NewFromFile(configFileName);
    bool lineByLine = inputFileName.IsNull();
    if (lineByLine) {
      ConvertLineByLine();
    } else {
      Convert();
    }
  } catch (TCLAP::ArgException& e) {
    std::cerr << "error: " << e.error() << " for arg " << e.argId()
              << std::endl;
  } catch (Exception& e) {
    std::cerr << e.what() << std::endl;
  }
  return 0;
}
<commit_msg>OpenCC CLI: if -i and -o are *literally* the same, create a temporary file for input<commit_after>/*
 * Open Chinese Convert
 *
 * Copyright 2010-2014 BYVoid <byvoid@byvoid.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "CmdLineOutput.hpp"
#include "Config.hpp"
#include "Converter.hpp"
#include "UTF8Util.hpp"

using namespace opencc;

Optional<string> inputFileName = Optional<string>::Null();
Optional<string> outputFileName = Optional<string>::Null();
string configFileName;
bool noFlush;
Config config;
ConverterPtr converter;

FILE* GetOutputStream() {
  if (outputFileName.IsNull()) {
    return stdout;
  } else {
    FILE* fp = fopen(outputFileName.Get().c_str(), "w");
    if (!fp) {
      throw FileNotWritable(outputFileName.Get());
    }
    return fp;
  }
}

void ConvertLineByLine() {
  std::istream& inputStream = std::cin;
  FILE* fout = GetOutputStream();
  bool isFirstLine = true;
  while (!inputStream.eof()) {
    if (!isFirstLine) {
      fputs("\n", fout);
    } else {
      isFirstLine = false;
    }
    string line;
    std::getline(inputStream, line);
    const string& converted = converter->Convert(line);
    fputs(converted.c_str(), fout);
    if (!noFlush) {
      // Flush every line if the output stream is stdout.
      fflush(fout);
    }
  }
  fclose(fout);
}

void Convert(string inputFileName) {
  const int BUFFER_SIZE = 1024 * 1024;
  static bool bufferInitialized = false;
  static string buffer;
  static char* bufferBegin;
  static const char* bufferEnd;
  static char* bufferPtr;
  static size_t bufferSizeAvailble;
  if (!bufferInitialized) {
    bufferInitialized = true;
    buffer.resize(BUFFER_SIZE + 1);
    bufferBegin = const_cast<char*>(buffer.c_str());
    bufferEnd = buffer.c_str() + BUFFER_SIZE;
    bufferPtr = bufferBegin;
    bufferSizeAvailble = BUFFER_SIZE;
  }

  bool needToRemove = false;
  if (!outputFileName.IsNull() && inputFileName == outputFileName.Get()) {
    // Special case: input == output
    const string tempFileName = std::tmpnam(nullptr);
    std::ifstream src(inputFileName, std::ios::binary);
    std::ofstream dst(tempFileName, std::ios::binary);
    dst << src.rdbuf();
    dst.close();
    inputFileName = tempFileName;
    needToRemove = true;
  }

  FILE* fin = fopen(inputFileName.c_str(), "r");
  if (!fin) {
    throw FileNotFound(inputFileName);
  }
  FILE* fout = GetOutputStream();
  while (!feof(fin)) {
    size_t length = fread(bufferPtr, sizeof(char), bufferSizeAvailble, fin);
    bufferPtr[length] = '\0';
    size_t remainingLength = 0;
    string remainingTemp;
    if (length == bufferSizeAvailble) {
      // fread may breaks UTF8 character
      // Find the end of last character
      char* lastChPtr = bufferBegin;
      while (lastChPtr < bufferEnd) {
        size_t nextCharLen = UTF8Util::NextCharLength(lastChPtr);
        if (lastChPtr + nextCharLen > bufferEnd) {
          break;
        }
        lastChPtr += nextCharLen;
      }
      remainingLength = bufferEnd - lastChPtr;
      if (remainingLength > 0) {
        remainingTemp = UTF8Util::FromSubstr(lastChPtr, remainingLength);
        *lastChPtr = '\0';
      }
    }
    // Perform conversion
    const string& converted = converter->Convert(buffer);
    fputs(converted.c_str(), fout);
    if (!noFlush) {
      // Flush every line if the output stream is stdout.
      fflush(fout);
    }
    // Reset pointer
    bufferPtr = bufferBegin + remainingLength;
    bufferSizeAvailble = BUFFER_SIZE - remainingLength;
    if (remainingLength > 0) {
      strncpy(bufferBegin, remainingTemp.c_str(), remainingLength);
    }
  }
  fclose(fout);
  if (needToRemove) {
    // Remove temporary file.
    std::remove(inputFileName.c_str());
  }
}

int main(int argc, const char* argv[]) {
  try {
    TCLAP::CmdLine cmd("Open Chinese Convert (OpenCC) Command Line Tool", ' ',
                       VERSION);
    CmdLineOutput cmdLineOutput;
    cmd.setOutput(&cmdLineOutput);

    TCLAP::ValueArg<string> configArg(
        "c", "config", "Configuration file", false /* required */,
        "s2t.json" /* default */, "file" /* type */, cmd);
    TCLAP::ValueArg<string> outputArg(
        "o", "output", "Write converted text to <file>.", false /* required */,
        "" /* default */, "file" /* type */, cmd);
    TCLAP::ValueArg<string> inputArg(
        "i", "input", "Read original text from <file>.", false /* required */,
        "" /* default */, "file" /* type */, cmd);
    TCLAP::ValueArg<bool> noFlushArg(
        "", "noflush", "Disable flush for every line", false /* required */,
        false /* default */, "bool" /* type */, cmd);
    cmd.parse(argc, argv);
    configFileName = configArg.getValue();
    noFlush = noFlushArg.getValue();
    if (inputArg.isSet()) {
      inputFileName = Optional<string>(inputArg.getValue());
    }
    if (outputArg.isSet()) {
      outputFileName = Optional<string>(outputArg.getValue());
      noFlush = true;
    }
    converter = config.NewFromFile(configFileName);
    bool lineByLine = inputFileName.IsNull();
    if (lineByLine) {
      ConvertLineByLine();
    } else {
      Convert(inputFileName.Get());
    }
  } catch (TCLAP::ArgException& e) {
    std::cerr << "error: " << e.error() << " for arg " << e.argId()
              << std::endl;
  } catch (Exception& e) {
    std::cerr << e.what() << std::endl;
  }
  return 0;
}
<|endoftext|>


<commit_before>// Copyright (c) 20109 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/extensions/extension_apitest.h"
#include "net/base/mock_host_resolver.h"

// This test failed at times on the Vista dbg builder and has been marked as
// flaky for now. Bug http://code.google.com/p/chromium/issues/detail?id=28630
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, FLAKY_ExecuteScript) {
  // We need a.com to be a little bit slow to trigger a race condition.
  host_resolver()->AddRuleWithLatency("a.com", "127.0.0.1", 500);
  host_resolver()->AddRule("b.com", "127.0.0.1");
  host_resolver()->AddRule("c.com", "127.0.0.1");
  StartHTTPServer();

  ASSERT_TRUE(RunExtensionTest("executescript/basic")) << message_;
  ASSERT_TRUE(RunExtensionTest("executescript/in_frame")) << message_;
  ASSERT_TRUE(RunExtensionTest("executescript/permissions")) << message_;
}
<commit_msg>Mark ExtensionApiTest.ExecuteScript DISABLED because it's not only flaky, but crashy and it has been ignored for weeks!<commit_after>// Copyright (c) 20109 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/extensions/extension_apitest.h"
#include "net/base/mock_host_resolver.h"

// EXTREMELY flaky, crashy, and bad. See http://crbug.com/28630 and don't dare
// to re-enable without a real fix or at least adding more debugging info.
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_ExecuteScript) {
  // We need a.com to be a little bit slow to trigger a race condition.
  host_resolver()->AddRuleWithLatency("a.com", "127.0.0.1", 500);
  host_resolver()->AddRule("b.com", "127.0.0.1");
  host_resolver()->AddRule("c.com", "127.0.0.1");
  StartHTTPServer();

  ASSERT_TRUE(RunExtensionTest("executescript/basic")) << message_;
  ASSERT_TRUE(RunExtensionTest("executescript/in_frame")) << message_;
  ASSERT_TRUE(RunExtensionTest("executescript/permissions")) << message_;
}
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/extensions/extension_apitest.h"

#include "base/prefs/pref_service.h"
#include "chrome/browser/prefs/incognito_mode_prefs.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "net/dns/mock_host_resolver.h"

#if defined(OS_WIN)
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#endif

#if defined(USE_AURA) || defined(OS_MACOSX)
// Maximizing/fullscreen popup window doesn't work on aura's managed mode.
// See bug crbug.com/116305.
// Mac: http://crbug.com/103912
#define MAYBE_UpdateWindowShowState DISABLED_UpdateWindowShowState
#else
#define MAYBE_UpdateWindowShowState UpdateWindowShowState
#endif  // defined(USE_AURA) || defined(OS_MACOSX)

// http://crbug.com/145639
#if defined(OS_LINUX) || defined(OS_WIN)
#define MAYBE_TabEvents DISABLED_TabEvents
#else
#define MAYBE_TabEvents TabEvents
#endif

class ExtensionApiNewTabTest : public ExtensionApiTest {
 public:
  ExtensionApiNewTabTest() {}
  void SetUpCommandLine(base::CommandLine* command_line) override {
    ExtensionApiTest::SetUpCommandLine(command_line);
    // Override the default which InProcessBrowserTest adds if it doesn't see a
    // homepage.
    command_line->AppendSwitchASCII(
        switches::kHomePage, chrome::kChromeUINewTabURL);
  }
};

IN_PROC_BROWSER_TEST_F(ExtensionApiNewTabTest, Tabs) {
  // The test creates a tab and checks that the URL of the new tab
  // is that of the new tab page.  Make sure the pref that controls
  // this is set.
  browser()->profile()->GetPrefs()->SetBoolean(
      prefs::kHomePageIsNewTabPage, true);

  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "crud.html")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, TabAudible) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "audible.html")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, TabMuted) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "muted.html")) << message_;
}

// Flaky on windows: http://crbug.com/238667
#if defined(OS_WIN)
#define MAYBE_Tabs2 DISABLED_Tabs2
#else
#define MAYBE_Tabs2 Tabs2
#endif
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_Tabs2) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "crud2.html")) << message_;
}

// crbug.com/149924
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_TabDuplicate) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "duplicate.html")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, TabSize) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "tab_size.html")) << message_;
}

// Flaky on linux: http://crbug.com/396364
#if defined(OS_LINUX)
#define MAYBE_TabUpdate DISABLED_TabUpdate
#else
#define MAYBE_TabUpdate TabUpdate
#endif
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_TabUpdate) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "update.html")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, TabPinned) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "pinned.html")) << message_;
}

// Flaky on windows: http://crbug.com/238667
#if defined(OS_WIN)
#define MAYBE_TabMove DISABLED_TabMove
#else
#define MAYBE_TabMove TabMove
#endif
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_TabMove) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "move.html")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_TabEvents) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "events.html")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_TabRelativeURLs) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "relative_urls.html"))
      << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, TabQuery) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "query.html")) << message_;
}

// Flaky on windows: http://crbug.com/239022
#if defined(OS_WIN)
#define MAYBE_TabHighlight DISABLED_TabHighlight
#else
#define MAYBE_TabHighlight TabHighlight
#endif
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_TabHighlight) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "highlight.html")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, TabCrashBrowser) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "crash.html")) << message_;
}

// Flaky on windows: http://crbug.com/238667
#if defined(OS_WIN)
#define MAYBE_TabOpener DISABLED_TabOpener
#else
#define MAYBE_TabOpener TabOpener
#endif
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_TabOpener) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "opener.html")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_TabGetCurrent) {
  ASSERT_TRUE(RunExtensionTest("tabs/get_current")) << message_;
}

// Flaky on the trybots. See http://crbug.com/96725.
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_TabConnect) {
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(RunExtensionTest("tabs/connect")) << message_;
}

// Possible race in ChromeURLDataManager. http://crbug.com/59198
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_TabOnRemoved) {
  ASSERT_TRUE(RunExtensionTest("tabs/on_removed")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_TabReload) {
  ASSERT_TRUE(RunExtensionTest("tabs/reload")) << message_;
}

class ExtensionApiCaptureTest : public ExtensionApiTest {
 public:
  ExtensionApiCaptureTest() {}

  void SetUp() override {
    EnablePixelOutput();
    ExtensionApiTest::SetUp();
  }

  void SetUpCommandLine(base::CommandLine* command_line) override {
    ExtensionApiTest::SetUpCommandLine(command_line);
  }
};

IN_PROC_BROWSER_TEST_F(ExtensionApiCaptureTest,
                       DISABLED_CaptureVisibleTabJpeg) {
  host_resolver()->AddRule("a.com", "127.0.0.1");
  host_resolver()->AddRule("b.com", "127.0.0.1");
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(RunExtensionSubtest("tabs/capture_visible_tab",
                                  "test_jpeg.html")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiCaptureTest, DISABLED_CaptureVisibleTabPng) {
  host_resolver()->AddRule("a.com", "127.0.0.1");
  host_resolver()->AddRule("b.com", "127.0.0.1");
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(RunExtensionSubtest("tabs/capture_visible_tab",
                                  "test_png.html")) << message_;
}

// Times out on non-Windows.
// See http://crbug.com/80212
IN_PROC_BROWSER_TEST_F(ExtensionApiCaptureTest,
                       DISABLED_CaptureVisibleTabRace) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/capture_visible_tab",
                                  "test_race.html")) << message_;
}

// Disabled for being flaky, see http://crbug/367695.
IN_PROC_BROWSER_TEST_F(ExtensionApiCaptureTest,
                       DISABLED_CaptureVisibleFile) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/capture_visible_tab",
                                  "test_file.html")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiCaptureTest, CaptureVisibleDisabled) {
  browser()->profile()->GetPrefs()->SetBoolean(prefs::kDisableScreenshots,
                                               true);
  ASSERT_TRUE(RunExtensionSubtest("tabs/capture_visible_tab",
                                  "test_disabled.html")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, TabsOnUpdated) {
  ASSERT_TRUE(RunExtensionTest("tabs/on_updated")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, TabsNoPermissions) {
  ASSERT_TRUE(RunExtensionTest("tabs/no_permissions")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, UpdateWindowResize) {
  ASSERT_TRUE(RunExtensionTest("window_update/resize")) << message_;
}

#if defined(OS_WIN)
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, FocusWindowDoesNotUnmaximize) {
  HWND window =
      browser()->window()->GetNativeWindow()->GetHost()->GetAcceleratedWidget();
  ::SendMessage(window, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
  ASSERT_TRUE(RunExtensionTest("window_update/focus")) << message_;
  ASSERT_TRUE(::IsZoomed(window));
}
#endif  // OS_WIN

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_UpdateWindowShowState) {
  ASSERT_TRUE(RunExtensionTest("window_update/show_state")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, IncognitoDisabledByPref) {
  IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(),
                                      IncognitoModePrefs::DISABLED);

  // This makes sure that creating an incognito window fails due to pref
  // (policy) being set.
  ASSERT_TRUE(RunExtensionTest("tabs/incognito_disabled")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_GetViewsOfCreatedPopup) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "get_views_popup.html"))
      << message_;
}
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_GetViewsOfCreatedWindow) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "get_views_window.html"))
      << message_;
}

// Adding a new test? Awesome. But API tests are the old hotness. The new
// hotness is extension_function_test_utils. See tabs_test.cc for an example.
// We are trying to phase out many uses of API tests as they tend to be flaky.
<commit_msg>Disable ExtensionApiTest.TabMuted as it's flaky.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/extensions/extension_apitest.h"

#include "base/prefs/pref_service.h"
#include "chrome/browser/prefs/incognito_mode_prefs.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "net/dns/mock_host_resolver.h"

#if defined(OS_WIN)
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#endif

#if defined(USE_AURA) || defined(OS_MACOSX)
// Maximizing/fullscreen popup window doesn't work on aura's managed mode.
// See bug crbug.com/116305.
// Mac: http://crbug.com/103912
#define MAYBE_UpdateWindowShowState DISABLED_UpdateWindowShowState
#else
#define MAYBE_UpdateWindowShowState UpdateWindowShowState
#endif  // defined(USE_AURA) || defined(OS_MACOSX)

// http://crbug.com/145639
#if defined(OS_LINUX) || defined(OS_WIN)
#define MAYBE_TabEvents DISABLED_TabEvents
#else
#define MAYBE_TabEvents TabEvents
#endif

class ExtensionApiNewTabTest : public ExtensionApiTest {
 public:
  ExtensionApiNewTabTest() {}
  void SetUpCommandLine(base::CommandLine* command_line) override {
    ExtensionApiTest::SetUpCommandLine(command_line);
    // Override the default which InProcessBrowserTest adds if it doesn't see a
    // homepage.
    command_line->AppendSwitchASCII(
        switches::kHomePage, chrome::kChromeUINewTabURL);
  }
};

IN_PROC_BROWSER_TEST_F(ExtensionApiNewTabTest, Tabs) {
  // The test creates a tab and checks that the URL of the new tab
  // is that of the new tab page.  Make sure the pref that controls
  // this is set.
  browser()->profile()->GetPrefs()->SetBoolean(
      prefs::kHomePageIsNewTabPage, true);

  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "crud.html")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, TabAudible) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "audible.html")) << message_;
}

// http://crbug.com/521410
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_TabMuted) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "muted.html")) << message_;
}

// Flaky on windows: http://crbug.com/238667
#if defined(OS_WIN)
#define MAYBE_Tabs2 DISABLED_Tabs2
#else
#define MAYBE_Tabs2 Tabs2
#endif
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_Tabs2) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "crud2.html")) << message_;
}

// crbug.com/149924
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_TabDuplicate) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "duplicate.html")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, TabSize) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "tab_size.html")) << message_;
}

// Flaky on linux: http://crbug.com/396364
#if defined(OS_LINUX)
#define MAYBE_TabUpdate DISABLED_TabUpdate
#else
#define MAYBE_TabUpdate TabUpdate
#endif
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_TabUpdate) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "update.html")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, TabPinned) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "pinned.html")) << message_;
}

// Flaky on windows: http://crbug.com/238667
#if defined(OS_WIN)
#define MAYBE_TabMove DISABLED_TabMove
#else
#define MAYBE_TabMove TabMove
#endif
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_TabMove) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "move.html")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_TabEvents) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "events.html")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_TabRelativeURLs) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "relative_urls.html"))
      << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, TabQuery) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "query.html")) << message_;
}

// Flaky on windows: http://crbug.com/239022
#if defined(OS_WIN)
#define MAYBE_TabHighlight DISABLED_TabHighlight
#else
#define MAYBE_TabHighlight TabHighlight
#endif
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_TabHighlight) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "highlight.html")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, TabCrashBrowser) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "crash.html")) << message_;
}

// Flaky on windows: http://crbug.com/238667
#if defined(OS_WIN)
#define MAYBE_TabOpener DISABLED_TabOpener
#else
#define MAYBE_TabOpener TabOpener
#endif
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_TabOpener) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "opener.html")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_TabGetCurrent) {
  ASSERT_TRUE(RunExtensionTest("tabs/get_current")) << message_;
}

// Flaky on the trybots. See http://crbug.com/96725.
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_TabConnect) {
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(RunExtensionTest("tabs/connect")) << message_;
}

// Possible race in ChromeURLDataManager. http://crbug.com/59198
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_TabOnRemoved) {
  ASSERT_TRUE(RunExtensionTest("tabs/on_removed")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_TabReload) {
  ASSERT_TRUE(RunExtensionTest("tabs/reload")) << message_;
}

class ExtensionApiCaptureTest : public ExtensionApiTest {
 public:
  ExtensionApiCaptureTest() {}

  void SetUp() override {
    EnablePixelOutput();
    ExtensionApiTest::SetUp();
  }

  void SetUpCommandLine(base::CommandLine* command_line) override {
    ExtensionApiTest::SetUpCommandLine(command_line);
  }
};

IN_PROC_BROWSER_TEST_F(ExtensionApiCaptureTest,
                       DISABLED_CaptureVisibleTabJpeg) {
  host_resolver()->AddRule("a.com", "127.0.0.1");
  host_resolver()->AddRule("b.com", "127.0.0.1");
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(RunExtensionSubtest("tabs/capture_visible_tab",
                                  "test_jpeg.html")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiCaptureTest, DISABLED_CaptureVisibleTabPng) {
  host_resolver()->AddRule("a.com", "127.0.0.1");
  host_resolver()->AddRule("b.com", "127.0.0.1");
  ASSERT_TRUE(StartEmbeddedTestServer());
  ASSERT_TRUE(RunExtensionSubtest("tabs/capture_visible_tab",
                                  "test_png.html")) << message_;
}

// Times out on non-Windows.
// See http://crbug.com/80212
IN_PROC_BROWSER_TEST_F(ExtensionApiCaptureTest,
                       DISABLED_CaptureVisibleTabRace) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/capture_visible_tab",
                                  "test_race.html")) << message_;
}

// Disabled for being flaky, see http://crbug/367695.
IN_PROC_BROWSER_TEST_F(ExtensionApiCaptureTest,
                       DISABLED_CaptureVisibleFile) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/capture_visible_tab",
                                  "test_file.html")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiCaptureTest, CaptureVisibleDisabled) {
  browser()->profile()->GetPrefs()->SetBoolean(prefs::kDisableScreenshots,
                                               true);
  ASSERT_TRUE(RunExtensionSubtest("tabs/capture_visible_tab",
                                  "test_disabled.html")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, TabsOnUpdated) {
  ASSERT_TRUE(RunExtensionTest("tabs/on_updated")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, TabsNoPermissions) {
  ASSERT_TRUE(RunExtensionTest("tabs/no_permissions")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, UpdateWindowResize) {
  ASSERT_TRUE(RunExtensionTest("window_update/resize")) << message_;
}

#if defined(OS_WIN)
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, FocusWindowDoesNotUnmaximize) {
  HWND window =
      browser()->window()->GetNativeWindow()->GetHost()->GetAcceleratedWidget();
  ::SendMessage(window, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
  ASSERT_TRUE(RunExtensionTest("window_update/focus")) << message_;
  ASSERT_TRUE(::IsZoomed(window));
}
#endif  // OS_WIN

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_UpdateWindowShowState) {
  ASSERT_TRUE(RunExtensionTest("window_update/show_state")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, IncognitoDisabledByPref) {
  IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(),
                                      IncognitoModePrefs::DISABLED);

  // This makes sure that creating an incognito window fails due to pref
  // (policy) being set.
  ASSERT_TRUE(RunExtensionTest("tabs/incognito_disabled")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_GetViewsOfCreatedPopup) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "get_views_popup.html"))
      << message_;
}
IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_GetViewsOfCreatedWindow) {
  ASSERT_TRUE(RunExtensionSubtest("tabs/basics", "get_views_window.html"))
      << message_;
}

// Adding a new test? Awesome. But API tests are the old hotness. The new
// hotness is extension_function_test_utils. See tabs_test.cc for an example.
// We are trying to phase out many uses of API tests as they tend to be flaky.
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/extensions/extension_apitest.h"

#include "chrome/browser/browser.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profile.h"
#include "chrome/common/pref_names.h"

#if defined(OS_MACOSX)
// Tabs appears to timeout, or maybe crash on mac.
// http://crbug.com/53779
#define MAYBE_Tabs FAILS_Tabs
#else
#define MAYBE_Tabs Tabs
#endif

// TabOnRemoved is flaky on chromeos and linux views debug build.
// http://crbug.com/49258
#if defined(OS_LINUX) && defined(TOOLKIT_VIEWS) && !defined(NDEBUG)
#define MAYBE_TabOnRemoved FLAKY_TabOnRemoved
#else
#define MAYBE_TabOnRemoved TabOnRemoved
#endif

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_Tabs) {
  ASSERT_TRUE(test_server()->Start());

  // The test creates a tab and checks that the URL of the new tab
  // is that of the new tab page.  Make sure the pref that controls
  // this is set.
  browser()->profile()->GetPrefs()->SetBoolean(
      prefs::kHomePageIsNewTabPage, true);

  ASSERT_TRUE(RunExtensionTest("tabs/basics")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, TabGetCurrent) {
  ASSERT_TRUE(test_server()->Start());
  ASSERT_TRUE(RunExtensionTest("tabs/get_current")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, TabConnect) {
  ASSERT_TRUE(test_server()->Start());
  ASSERT_TRUE(RunExtensionTest("tabs/connect")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_TabOnRemoved) {
  ASSERT_TRUE(test_server()->Start());
  ASSERT_TRUE(RunExtensionTest("tabs/on_removed")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, CaptureVisibleTabJpeg) {
  ASSERT_TRUE(test_server()->Start());
  ASSERT_TRUE(RunExtensionSubtest("tabs/capture_visible_tab",
                                  "test_jpeg.html")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, CaptureVisibleTabPng) {
  ASSERT_TRUE(test_server()->Start());
  ASSERT_TRUE(RunExtensionSubtest("tabs/capture_visible_tab",
                                  "test_png.html")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, TabsOnUpdated) {
  ASSERT_TRUE(test_server()->Start());

  ASSERT_TRUE(RunExtensionTest("tabs/on_updated")) << message_;
}
<commit_msg>Mark ExtensionApiTest.Tabs flaky on win and linux.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/extensions/extension_apitest.h"

#include "chrome/browser/browser.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profile.h"
#include "chrome/common/pref_names.h"

#if defined(OS_MACOSX)
// Tabs appears to timeout, or maybe crash on mac.
// http://crbug.com/53779
#define MAYBE_Tabs FAILS_Tabs
#else
// It's flaky on win and linux.
// http://crbug.com/58269
#define MAYBE_Tabs FLAKY_Tabs
#endif

// TabOnRemoved is flaky on chromeos and linux views debug build.
// http://crbug.com/49258
#if defined(OS_LINUX) && defined(TOOLKIT_VIEWS) && !defined(NDEBUG)
#define MAYBE_TabOnRemoved FLAKY_TabOnRemoved
#else
#define MAYBE_TabOnRemoved TabOnRemoved
#endif

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_Tabs) {
  ASSERT_TRUE(test_server()->Start());

  // The test creates a tab and checks that the URL of the new tab
  // is that of the new tab page.  Make sure the pref that controls
  // this is set.
  browser()->profile()->GetPrefs()->SetBoolean(
      prefs::kHomePageIsNewTabPage, true);

  ASSERT_TRUE(RunExtensionTest("tabs/basics")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, TabGetCurrent) {
  ASSERT_TRUE(test_server()->Start());
  ASSERT_TRUE(RunExtensionTest("tabs/get_current")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, TabConnect) {
  ASSERT_TRUE(test_server()->Start());
  ASSERT_TRUE(RunExtensionTest("tabs/connect")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_TabOnRemoved) {
  ASSERT_TRUE(test_server()->Start());
  ASSERT_TRUE(RunExtensionTest("tabs/on_removed")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, CaptureVisibleTabJpeg) {
  ASSERT_TRUE(test_server()->Start());
  ASSERT_TRUE(RunExtensionSubtest("tabs/capture_visible_tab",
                                  "test_jpeg.html")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, CaptureVisibleTabPng) {
  ASSERT_TRUE(test_server()->Start());
  ASSERT_TRUE(RunExtensionSubtest("tabs/capture_visible_tab",
                                  "test_png.html")) << message_;
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, TabsOnUpdated) {
  ASSERT_TRUE(test_server()->Start());

  ASSERT_TRUE(RunExtensionTest("tabs/on_updated")) << message_;
}
<|endoftext|>