// Copyright 2018 The Chromium OS 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 <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <base/bind.h>
#include <base/check_op.h>
#include <base/containers/flat_map.h>
#include <base/macros.h>
#include <base/run_loop.h>
#include <base/callback_helpers.h>
#include <brillo/test_helpers.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <mojo/public/cpp/bindings/remote.h>
#include <tensorflow/lite/context.h>
#include <tensorflow/lite/interpreter.h>

#include "ml/graph_executor_impl.h"
#include "ml/mojom/graph_executor.mojom.h"
#include "ml/mojom/tensor.mojom.h"
#include "ml/tensor_view.h"
#include "ml/test_utils.h"

namespace ml {
namespace {

using ::chromeos::machine_learning::mojom::ExecuteResult;
using ::chromeos::machine_learning::mojom::GraphExecutor;
using ::chromeos::machine_learning::mojom::Int64List;
using ::chromeos::machine_learning::mojom::StringList;
using ::chromeos::machine_learning::mojom::Tensor;
using ::chromeos::machine_learning::mojom::TensorPtr;
using ::chromeos::machine_learning::mojom::ValueList;
using ::testing::ElementsAre;

// Make the simplest possible model: one that copies its input to its output.
std::unique_ptr<tflite::Interpreter> IdentityInterpreter() {
  auto interpreter = std::make_unique<tflite::Interpreter>();

  // Add the input and output tensors.
  CHECK_EQ(interpreter->AddTensors(2), kTfLiteOk);
  CHECK_EQ(interpreter->SetInputs({0}), kTfLiteOk);
  CHECK_EQ(interpreter->SetOutputs({1}), kTfLiteOk);

  // Set the types of the tensors.
  TfLiteQuantizationParams quantized;
  CHECK_EQ(interpreter->SetTensorParametersReadWrite(
               0 /*tensor_index*/, kTfLiteFloat32 /*type*/,
               "in_tensor" /*name*/, {1} /*dims*/, quantized),
           kTfLiteOk);
  CHECK_EQ(interpreter->SetTensorParametersReadWrite(
               1 /*tensor_index*/, kTfLiteFloat32 /*type*/,
               "out_tensor" /*name*/, {1} /*dims*/, quantized),
           kTfLiteOk);

  // Add the copy node.
  TfLiteRegistration reg_copy = {nullptr, nullptr, nullptr, nullptr};
  reg_copy.invoke = [](TfLiteContext* const context, TfLiteNode* const node) {
    TfLiteTensor* const input = &context->tensors[node->inputs->data[0]];
    TfLiteTensor* const output = &context->tensors[node->outputs->data[0]];
    *output->data.f = *input->data.f;
    return kTfLiteOk;
  };

  CHECK_EQ(interpreter->AddNodeWithParameters(
               {0} /*inputs*/, {1} /*outputs*/, nullptr /*init_data*/,
               0 /*init_data_size*/, nullptr /*builtin_data*/, &reg_copy),
           kTfLiteOk);

  CHECK_EQ(interpreter->AllocateTensors(), kTfLiteOk);

  return interpreter;
}

// Test two normal executions of a graph.
TEST(GraphExecutorTest, TestOk) {
  // Create GraphExecutor.
  mojo::Remote<GraphExecutor> graph_executor;
  const std::map<std::string, int> input_names = {{"in_tensor", 0}};
  const std::map<std::string, int> output_names = {{"out_tensor", 1}};
  std::unique_ptr<GraphExecutorDelegate> graph_executor_delegate =
      std::make_unique<GraphExecutorDelegate>(
          input_names, output_names, IdentityInterpreter(), "TestModel");
  const GraphExecutorImpl graph_executor_impl(
      std::move(graph_executor_delegate),
      graph_executor.BindNewPipeAndPassReceiver());
  ASSERT_TRUE(graph_executor.is_bound());

  // Execute once.
  {
    base::flat_map<std::string, TensorPtr> inputs;
    inputs.emplace("in_tensor", NewTensor<double>({1}, {0.5}));
    std::vector<std::string> outputs({"out_tensor"});

    bool callback_done = false;
    graph_executor->Execute(
        std::move(inputs), std::move(outputs),
        base::BindOnce(
            [](bool* callback_done, const ExecuteResult result,
               base::Optional<std::vector<TensorPtr>> outputs) {
              // Check that the inference succeeded and gives the expected
              // number of outputs.
              EXPECT_EQ(result, ExecuteResult::OK);
              ASSERT_TRUE(outputs.has_value());
              ASSERT_EQ(outputs->size(), 1);

              // Check that the output tensor has the right type and format.
              const TensorView<double> out_tensor((*outputs)[0]);
              EXPECT_TRUE(out_tensor.IsValidType());
              EXPECT_TRUE(out_tensor.IsValidFormat());

              // Check the output tensor has the expected shape and values.
              EXPECT_THAT(out_tensor.GetShape(), ElementsAre(1));
              EXPECT_THAT(out_tensor.GetValues(), ElementsAre(0.5));

              *callback_done = true;
            },
            &callback_done));

    base::RunLoop().RunUntilIdle();
    EXPECT_TRUE(callback_done);
  }

  // Execute again with different input.
  {
    base::flat_map<std::string, TensorPtr> inputs;
    inputs.emplace("in_tensor", NewTensor<double>({1}, {0.75}));
    std::vector<std::string> outputs({"out_tensor"});

    bool callback_done = false;
    graph_executor->Execute(
        std::move(inputs), std::move(outputs),
        base::BindOnce(
            [](bool* callback_done, const ExecuteResult result,
               base::Optional<std::vector<TensorPtr>> outputs) {
              // Check that the inference succeeded and gives the expected
              // number of outputs.
              EXPECT_EQ(result, ExecuteResult::OK);
              ASSERT_TRUE(outputs.has_value());
              ASSERT_EQ(outputs->size(), 1);

              // Check that the output tensor has the right type and format.
              const TensorView<double> out_tensor((*outputs)[0]);
              EXPECT_TRUE(out_tensor.IsValidType());
              EXPECT_TRUE(out_tensor.IsValidFormat());

              // Check the output tensor has the expected shape and values.
              EXPECT_THAT(out_tensor.GetShape(), ElementsAre(1));
              EXPECT_THAT(out_tensor.GetValues(), ElementsAre(0.75));

              *callback_done = true;
            },
            &callback_done));

    base::RunLoop().RunUntilIdle();
    EXPECT_TRUE(callback_done);
  }
}

// Test execution of a graph that requires int narrowing from input tensors.
TEST(GraphExecutorTest, TestNarrowing) {
  // Create a model that copies a bool into a uint8.
  auto interpreter = std::make_unique<tflite::Interpreter>();

  // Add the input and output tensors.
  CHECK_EQ(interpreter->AddTensors(2), kTfLiteOk);
  CHECK_EQ(interpreter->SetInputs({0}), kTfLiteOk);
  CHECK_EQ(interpreter->SetOutputs({1}), kTfLiteOk);

  // Set the types of the tensors.
  TfLiteQuantizationParams quantized;
  CHECK_EQ(interpreter->SetTensorParametersReadWrite(
               0 /*tensor_index*/, kTfLiteBool /*type*/, "in_tensor" /*name*/,
               {1} /*dims*/, quantized),
           kTfLiteOk);
  CHECK_EQ(interpreter->SetTensorParametersReadWrite(
               1 /*tensor_index*/, kTfLiteUInt8 /*type*/, "out_tensor" /*name*/,
               {1} /*dims*/, quantized),
           kTfLiteOk);

  // Add the copy node.
  TfLiteRegistration reg_copy = {nullptr, nullptr, nullptr, nullptr};
  reg_copy.invoke = [](TfLiteContext* const context, TfLiteNode* const node) {
    TfLiteTensor* const input = &context->tensors[node->inputs->data[0]];
    TfLiteTensor* const output = &context->tensors[node->outputs->data[0]];
    *output->data.uint8 = *input->data.b;
    return kTfLiteOk;
  };

  CHECK_EQ(interpreter->AddNodeWithParameters(
               {0} /*inputs*/, {1} /*outputs*/, nullptr /*init_data*/,
               0 /*init_data_size*/, nullptr /*builtin_data*/, &reg_copy),
           kTfLiteOk);

  CHECK_EQ(interpreter->AllocateTensors(), kTfLiteOk);

  // Create GraphExecutor.
  mojo::Remote<GraphExecutor> graph_executor;
  const std::map<std::string, int> input_names = {{"in_tensor", 0}};
  const std::map<std::string, int> output_names = {{"out_tensor", 1}};
  std::unique_ptr<GraphExecutorDelegate> graph_executor_delegate =
      std::make_unique<GraphExecutorDelegate>(
          input_names, output_names, std::move(interpreter), "TestModel");
  const GraphExecutorImpl graph_executor_impl(
      std::move(graph_executor_delegate),
      graph_executor.BindNewPipeAndPassReceiver());
  ASSERT_TRUE(graph_executor.is_bound());

  // We represent bools with int64 tensors.
  base::flat_map<std::string, TensorPtr> inputs;
  inputs.emplace("in_tensor", NewTensor<int64_t>({1}, {true}));
  std::vector<std::string> outputs({"out_tensor"});

  bool callback_done = false;
  graph_executor->Execute(
      std::move(inputs), std::move(outputs),
      base::BindOnce(
          [](bool* callback_done, const ExecuteResult result,
             base::Optional<std::vector<TensorPtr>> outputs) {
            // Check that the inference succeeded and gives the expected number
            // of outputs.
            EXPECT_EQ(result, ExecuteResult::OK);
            ASSERT_TRUE(outputs.has_value());
            ASSERT_EQ(outputs->size(), 1);

            // Check that the output tensor has the right type and format.
            const TensorView<int64_t> out_tensor((*outputs)[0]);
            EXPECT_TRUE(out_tensor.IsValidType());
            EXPECT_TRUE(out_tensor.IsValidFormat());

            // Check the output tensor has the expected shape and values.
            EXPECT_THAT(out_tensor.GetShape(), ElementsAre(1));
            EXPECT_THAT(out_tensor.GetValues(), ElementsAre(1));

            *callback_done = true;
          },
          &callback_done));

  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(callback_done);
}

// Test graph execution where the client requests a bad output tensor name.
TEST(GraphExecutorTest, TestInvalidOutputName) {
  // Create GraphExecutor.
  mojo::Remote<GraphExecutor> graph_executor;
  const std::map<std::string, int> input_names = {{"in_tensor", 0}};
  const std::map<std::string, int> output_names = {{"out_tensor", 1}};
  std::unique_ptr<GraphExecutorDelegate> graph_executor_delegate =
      std::make_unique<GraphExecutorDelegate>(
          input_names, output_names, IdentityInterpreter(), "TestModel");
  const GraphExecutorImpl graph_executor_impl(
      std::move(graph_executor_delegate),
      graph_executor.BindNewPipeAndPassReceiver());
  ASSERT_TRUE(graph_executor.is_bound());

  base::flat_map<std::string, TensorPtr> inputs;
  inputs.emplace("in_tensor", NewTensor<double>({1}, {0.5}));
  // Ask for the input tensor (which isn't in our "outputs" list).
  std::vector<std::string> outputs({"in_tensor"});

  bool callback_done = false;
  graph_executor->Execute(
      std::move(inputs), std::move(outputs),
      base::BindOnce(
          [](bool* callback_done, const ExecuteResult result,
             base::Optional<std::vector<TensorPtr>> outputs) {
            EXPECT_EQ(result, ExecuteResult::UNKNOWN_OUTPUT_ERROR);
            EXPECT_FALSE(outputs.has_value());

            *callback_done = true;
          },
          &callback_done));

  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(callback_done);
}

// Test graph execution where the client does not request an output.
TEST(GraphExecutorTest, TestMissingOutputName) {
  // Create GraphExecutor.
  mojo::Remote<GraphExecutor> graph_executor;
  const std::map<std::string, int> input_names = {{"in_tensor", 0}};
  const std::map<std::string, int> output_names = {{"out_tensor", 1}};
  std::unique_ptr<GraphExecutorDelegate> graph_executor_delegate =
      std::make_unique<GraphExecutorDelegate>(
          input_names, output_names, IdentityInterpreter(), "TestModel");
  const GraphExecutorImpl graph_executor_impl(
      std::move(graph_executor_delegate),
      graph_executor.BindNewPipeAndPassReceiver());
  ASSERT_TRUE(graph_executor.is_bound());

  base::flat_map<std::string, TensorPtr> inputs;
  inputs.emplace("in_tensor", NewTensor<double>({1}, {0.5}));

  bool callback_done = false;
  graph_executor->Execute(
      std::move(inputs), {},
      base::BindOnce(
          [](bool* callback_done, const ExecuteResult result,
             base::Optional<std::vector<TensorPtr>> outputs) {
            EXPECT_EQ(result, ExecuteResult::OUTPUT_MISSING_ERROR);
            EXPECT_FALSE(outputs.has_value());

            *callback_done = true;
          },
          &callback_done));

  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(callback_done);
}

// Test graph execution where the client requests the same output name twice.
TEST(GraphExecutorTest, TestDuplicateOutputName) {
  // Create GraphExecutor.
  mojo::Remote<GraphExecutor> graph_executor;
  const std::map<std::string, int> input_names = {{"in_tensor", 0}};
  const std::map<std::string, int> output_names = {{"out_tensor", 1}};
  std::unique_ptr<GraphExecutorDelegate> graph_executor_delegate =
      std::make_unique<GraphExecutorDelegate>(
          input_names, output_names, IdentityInterpreter(), "TestModel");
  const GraphExecutorImpl graph_executor_impl(
      std::move(graph_executor_delegate),
      graph_executor.BindNewPipeAndPassReceiver());
  ASSERT_TRUE(graph_executor.is_bound());

  base::flat_map<std::string, TensorPtr> inputs;
  inputs.emplace("in_tensor", NewTensor<double>({1}, {0.5}));
  // Ask for two copies of the output tensor.
  std::vector<std::string> outputs({"out_tensor", "out_tensor"});

  bool callback_done = false;
  graph_executor->Execute(
      std::move(inputs), std::move(outputs),
      base::BindOnce(
          [](bool* callback_done, const ExecuteResult result,
             base::Optional<std::vector<TensorPtr>> outputs) {
            EXPECT_EQ(result, ExecuteResult::DUPLICATE_OUTPUT_ERROR);
            EXPECT_FALSE(outputs.has_value());

            *callback_done = true;
          },
          &callback_done));

  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(callback_done);
}

// Test graph execution where the client supplies a bad input tensor name.
TEST(GraphExecutorTest, TestInvalidInputName) {
  // Create GraphExecutor.
  mojo::Remote<GraphExecutor> graph_executor;
  const std::map<std::string, int> input_names = {{"in_tensor", 0}};
  const std::map<std::string, int> output_names = {{"out_tensor", 1}};
  std::unique_ptr<GraphExecutorDelegate> graph_executor_delegate =
      std::make_unique<GraphExecutorDelegate>(
          input_names, output_names, IdentityInterpreter(), "TestModel");
  const GraphExecutorImpl graph_executor_impl(
      std::move(graph_executor_delegate),
      graph_executor.BindNewPipeAndPassReceiver());
  ASSERT_TRUE(graph_executor.is_bound());

  // Specify a value for the output tensor (which isn't in our "inputs" list).
  base::flat_map<std::string, TensorPtr> inputs;
  inputs.emplace("out_tensor", NewTensor<double>({1}, {0.5}));
  std::vector<std::string> outputs({"out_tensor"});

  bool callback_done = false;
  graph_executor->Execute(
      std::move(inputs), std::move(outputs),
      base::BindOnce(
          [](bool* callback_done, const ExecuteResult result,
             base::Optional<std::vector<TensorPtr>> outputs) {
            EXPECT_EQ(result, ExecuteResult::UNKNOWN_INPUT_ERROR);
            EXPECT_FALSE(outputs.has_value());

            *callback_done = true;
          },
          &callback_done));

  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(callback_done);
}

// Test graph execution where the client does not supply an input.
TEST(GraphExecutorTest, TestMissingInputName) {
  // Create GraphExecutor.
  mojo::Remote<GraphExecutor> graph_executor;
  const std::map<std::string, int> input_names = {{"in_tensor", 0}};
  const std::map<std::string, int> output_names = {{"out_tensor", 1}};
  std::unique_ptr<GraphExecutorDelegate> graph_executor_delegate =
      std::make_unique<GraphExecutorDelegate>(
          input_names, output_names, IdentityInterpreter(), "TestModel");
  const GraphExecutorImpl graph_executor_impl(
      std::move(graph_executor_delegate),
      graph_executor.BindNewPipeAndPassReceiver());
  ASSERT_TRUE(graph_executor.is_bound());

  // Specify a value for the output tensor (which isn't in our "inputs" list).
  std::vector<std::string> outputs({"out_tensor"});

  bool callback_done = false;
  graph_executor->Execute(
      {}, std::move(outputs),
      base::BindOnce(
          [](bool* callback_done, const ExecuteResult result,
             base::Optional<std::vector<TensorPtr>> outputs) {
            EXPECT_EQ(result, ExecuteResult::INPUT_MISSING_ERROR);
            EXPECT_FALSE(outputs.has_value());

            *callback_done = true;
          },
          &callback_done));

  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(callback_done);
}

// Test graph execution where the client supplies input of incorrect type.
TEST(GraphExecutorTest, TestWrongInputType) {
  // Create GraphExecutor.
  mojo::Remote<GraphExecutor> graph_executor;
  const std::map<std::string, int> input_names = {{"in_tensor", 0}};
  const std::map<std::string, int> output_names = {{"out_tensor", 1}};
  std::unique_ptr<GraphExecutorDelegate> graph_executor_delegate =
      std::make_unique<GraphExecutorDelegate>(
          input_names, output_names, IdentityInterpreter(), "TestModel");
  const GraphExecutorImpl graph_executor_impl(
      std::move(graph_executor_delegate),
      graph_executor.BindNewPipeAndPassReceiver());
  ASSERT_TRUE(graph_executor.is_bound());

  // Give an int tensor when a float tensor is expected.
  base::flat_map<std::string, TensorPtr> inputs;
  inputs.emplace("in_tensor", NewTensor<int64_t>({1}, {123}));
  std::vector<std::string> outputs({"out_tensor"});

  bool callback_done = false;
  graph_executor->Execute(
      std::move(inputs), std::move(outputs),
      base::BindOnce(
          [](bool* callback_done, const ExecuteResult result,
             base::Optional<std::vector<TensorPtr>> outputs) {
            EXPECT_EQ(result, ExecuteResult::INPUT_TYPE_ERROR);
            EXPECT_FALSE(outputs.has_value());

            *callback_done = true;
          },
          &callback_done));

  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(callback_done);
}

// Test graph execution where the client supplies input of incorrect shape.
TEST(GraphExecutorTest, TestWrongInputShape) {
  // Create GraphExecutor.
  mojo::Remote<GraphExecutor> graph_executor;
  const std::map<std::string, int> input_names = {{"in_tensor", 0}};
  const std::map<std::string, int> output_names = {{"out_tensor", 1}};
  std::unique_ptr<GraphExecutorDelegate> graph_executor_delegate =
      std::make_unique<GraphExecutorDelegate>(
          input_names, output_names, IdentityInterpreter(), "TestModel");
  const GraphExecutorImpl graph_executor_impl(
      std::move(graph_executor_delegate),
      graph_executor.BindNewPipeAndPassReceiver());
  ASSERT_TRUE(graph_executor.is_bound());

  // Give a 1x1 tensor when a scalar is expected.
  base::flat_map<std::string, TensorPtr> inputs;
  inputs.emplace("in_tensor", NewTensor<double>({1, 1}, {0.5}));
  std::vector<std::string> outputs({"out_tensor"});

  bool callback_done = false;
  graph_executor->Execute(
      std::move(inputs), std::move(outputs),
      base::BindOnce(
          [](bool* callback_done, const ExecuteResult result,
             base::Optional<std::vector<TensorPtr>> outputs) {
            EXPECT_EQ(result, ExecuteResult::INPUT_SHAPE_ERROR);
            EXPECT_FALSE(outputs.has_value());

            *callback_done = true;
          },
          &callback_done));

  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(callback_done);
}

// Test graph execution where the user supplies input in a bad format (i.e. with
// mismatched shape and values).
TEST(GraphExecutorTest, TestInvalidInputFormat) {
  // Create GraphExecutor.
  mojo::Remote<GraphExecutor> graph_executor;
  const std::map<std::string, int> input_names = {{"in_tensor", 0}};
  const std::map<std::string, int> output_names = {{"out_tensor", 1}};
  std::unique_ptr<GraphExecutorDelegate> graph_executor_delegate =
      std::make_unique<GraphExecutorDelegate>(
          input_names, output_names, IdentityInterpreter(), "TestModel");
  const GraphExecutorImpl graph_executor_impl(
      std::move(graph_executor_delegate),
      graph_executor.BindNewPipeAndPassReceiver());
  ASSERT_TRUE(graph_executor.is_bound());

  // Give a tensor with scalar shape but multiple values.
  base::flat_map<std::string, TensorPtr> inputs;
  inputs.emplace("in_tensor", NewTensor<double>({1}, {0.5, 0.5}));
  std::vector<std::string> outputs({"out_tensor"});

  bool callback_done = false;
  graph_executor->Execute(
      std::move(inputs), std::move(outputs),
      base::BindOnce(
          [](bool* callback_done, const ExecuteResult result,
             base::Optional<std::vector<TensorPtr>> outputs) {
            EXPECT_EQ(result, ExecuteResult::INPUT_FORMAT_ERROR);
            EXPECT_FALSE(outputs.has_value());

            *callback_done = true;
          },
          &callback_done));

  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(callback_done);
}

// Test graph execution where the graph accepts tensors of an unsupported type.
TEST(GraphExecutorTest, TestInvalidInputNodeType) {
  // Define an interpreter that accepts strings (which are not yet supported).
  auto interpreter = std::make_unique<tflite::Interpreter>();

  // Add the input and output tensors.
  ASSERT_EQ(interpreter->AddTensors(2), kTfLiteOk);
  ASSERT_EQ(interpreter->SetInputs({0}), kTfLiteOk);
  ASSERT_EQ(interpreter->SetOutputs({1}), kTfLiteOk);

  // Set the type of the input tensor to string.
  TfLiteQuantizationParams quantized;
  ASSERT_EQ(interpreter->SetTensorParametersReadWrite(
                0 /*tensor_index*/, kTfLiteString /*type*/,
                "in_tensor" /*name*/, {1} /*dims*/, quantized),
            kTfLiteOk);
  ASSERT_EQ(interpreter->SetTensorParametersReadWrite(
                1 /*tensor_index*/, kTfLiteFloat32 /*type*/,
                "out_tensor" /*name*/, {1} /*dims*/, quantized),
            kTfLiteOk);

  ASSERT_EQ(interpreter->AllocateTensors(), kTfLiteOk);

  // Create GraphExecutor.
  mojo::Remote<GraphExecutor> graph_executor;
  const std::map<std::string, int> input_names = {{"in_tensor", 0}};
  const std::map<std::string, int> output_names = {{"out_tensor", 1}};
  std::unique_ptr<GraphExecutorDelegate> graph_executor_delegate =
      std::make_unique<GraphExecutorDelegate>(
          input_names, output_names, std::move(interpreter), "TestModel");
  const GraphExecutorImpl graph_executor_impl(
      std::move(graph_executor_delegate),
      graph_executor.BindNewPipeAndPassReceiver());
  ASSERT_TRUE(graph_executor.is_bound());

  // Graph execution should fail before we get to input type checking.
  base::flat_map<std::string, TensorPtr> inputs;
  inputs.emplace("in_tensor", NewTensor<double>({}, {}));
  std::vector<std::string> outputs({"out_tensor"});

  bool callback_done = false;
  graph_executor->Execute(
      std::move(inputs), std::move(outputs),
      base::BindOnce(
          [](bool* callback_done, const ExecuteResult result,
             base::Optional<std::vector<TensorPtr>> outputs) {
            EXPECT_EQ(result, ExecuteResult::EXECUTION_ERROR);
            EXPECT_FALSE(outputs.has_value());

            *callback_done = true;
          },
          &callback_done));

  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(callback_done);
}

// Test graph execution where TF lite invocation fails.
TEST(GraphExecutorTest, TestExecutionFailure) {
  // Use an uninitialized interpreter, which induces an execution failure.
  mojo::Remote<GraphExecutor> graph_executor;
  const std::map<std::string, int> inputs_outputs;
  std::unique_ptr<GraphExecutorDelegate> graph_executor_delegate =
      std::make_unique<GraphExecutorDelegate>(
          inputs_outputs, inputs_outputs,
          std::make_unique<tflite::Interpreter>(), "TestModel");
  const GraphExecutorImpl graph_executor_impl(
      std::move(graph_executor_delegate),
      graph_executor.BindNewPipeAndPassReceiver());
  ASSERT_TRUE(graph_executor.is_bound());

  bool callback_done = false;
  graph_executor->Execute(
      {}, {},
      base::BindOnce(
          [](bool* callback_done, const ExecuteResult result,
             base::Optional<std::vector<TensorPtr>> outputs) {
            EXPECT_EQ(result, ExecuteResult::EXECUTION_ERROR);
            EXPECT_FALSE(outputs.has_value());

            *callback_done = true;
          },
          &callback_done));

  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(callback_done);
}

// Test graph execution where the graph produces tensors of an unsupported type.
TEST(GraphExecutorTest, TestInvalidOutputNodeType) {
  // Define an interpreter that produces strings (which are not yet supported).
  auto interpreter = std::make_unique<tflite::Interpreter>();

  // Add the input and output tensors.
  ASSERT_EQ(interpreter->AddTensors(2), kTfLiteOk);
  ASSERT_EQ(interpreter->SetInputs({0}), kTfLiteOk);
  ASSERT_EQ(interpreter->SetOutputs({1}), kTfLiteOk);

  // Set the type of the output tensor to string.
  TfLiteQuantizationParams quantized;
  ASSERT_EQ(interpreter->SetTensorParametersReadWrite(
                0 /*tensor_index*/, kTfLiteFloat32 /*type*/,
                "in_tensor" /*name*/, {1} /*dims*/, quantized),
            kTfLiteOk);
  ASSERT_EQ(interpreter->SetTensorParametersReadWrite(
                1 /*tensor_index*/, kTfLiteString /*type*/,
                "out_tensor" /*name*/, {1} /*dims*/, quantized),
            kTfLiteOk);

  ASSERT_EQ(interpreter->AllocateTensors(), kTfLiteOk);

  // Create GraphExecutor.
  mojo::Remote<GraphExecutor> graph_executor;
  const std::map<std::string, int> input_names = {{"in_tensor", 0}};
  const std::map<std::string, int> output_names = {{"out_tensor", 1}};
  std::unique_ptr<GraphExecutorDelegate> graph_executor_delegate =
      std::make_unique<GraphExecutorDelegate>(
          input_names, output_names, std::move(interpreter), "TestModel");
  const GraphExecutorImpl graph_executor_impl(
      std::move(graph_executor_delegate),
      graph_executor.BindNewPipeAndPassReceiver());
  ASSERT_TRUE(graph_executor.is_bound());

  // Populate input.
  base::flat_map<std::string, TensorPtr> inputs;
  inputs.emplace("in_tensor", NewTensor<double>({1}, {0.5}));
  std::vector<std::string> outputs({"out_tensor"});

  bool callback_done = false;
  graph_executor->Execute(
      std::move(inputs), std::move(outputs),
      base::BindOnce(
          [](bool* callback_done, const ExecuteResult result,
             base::Optional<std::vector<TensorPtr>> outputs) {
            EXPECT_EQ(result, ExecuteResult::EXECUTION_ERROR);
            EXPECT_FALSE(outputs.has_value());

            *callback_done = true;
          },
          &callback_done));

  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(callback_done);
}

// Test graph execution where the graph produces output of invalid shape.
TEST(GraphExecutorTest, TestInvalidOutputNodeShape) {
  // Define an interpreter that produces an empty output (i.e. simulates an
  // internal model error).
  auto interpreter = std::make_unique<tflite::Interpreter>();

  // Add the input and output tensors.
  ASSERT_EQ(interpreter->AddTensors(2), kTfLiteOk);
  ASSERT_EQ(interpreter->SetInputs({0}), kTfLiteOk);
  ASSERT_EQ(interpreter->SetOutputs({1}), kTfLiteOk);

  // Set the shape of the output tensor to be empty.
  TfLiteQuantizationParams quantized;
  ASSERT_EQ(interpreter->SetTensorParametersReadWrite(
                0 /*tensor_index*/, kTfLiteFloat32 /*type*/,
                "in_tensor" /*name*/, {1} /*dims*/, quantized),
            kTfLiteOk);
  ASSERT_EQ(interpreter->SetTensorParametersReadWrite(
                1 /*tensor_index*/, kTfLiteFloat32 /*type*/,
                "out_tensor" /*name*/, {} /*dims*/, quantized),
            kTfLiteOk);

  ASSERT_EQ(interpreter->AllocateTensors(), kTfLiteOk);

  // Create GraphExecutor.
  mojo::Remote<GraphExecutor> graph_executor;
  const std::map<std::string, int> input_names = {{"in_tensor", 0}};
  const std::map<std::string, int> output_names = {{"out_tensor", 1}};
  std::unique_ptr<GraphExecutorDelegate> graph_executor_delegate =
      std::make_unique<GraphExecutorDelegate>(
          input_names, output_names, std::move(interpreter), "TestModel");
  const GraphExecutorImpl graph_executor_impl(
      std::move(graph_executor_delegate),
      graph_executor.BindNewPipeAndPassReceiver());
  ASSERT_TRUE(graph_executor.is_bound());

  // Populate input.
  base::flat_map<std::string, TensorPtr> inputs;
  inputs.emplace("in_tensor", NewTensor<double>({1}, {0.5}));
  std::vector<std::string> outputs({"out_tensor"});

  bool callback_done = false;
  graph_executor->Execute(
      std::move(inputs), std::move(outputs),
      base::BindOnce(
          [](bool* callback_done, const ExecuteResult result,
             base::Optional<std::vector<TensorPtr>> outputs) {
            EXPECT_EQ(result, ExecuteResult::EXECUTION_ERROR);
            EXPECT_FALSE(outputs.has_value());

            *callback_done = true;
          },
          &callback_done));

  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(callback_done);
}

}  // namespace
}  // namespace ml
