C++程序  |  260行  |  7.53 KB

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

#include "request_tracker.h"

#include <gtest/gtest.h>

using testing::Test;

namespace default_camera_hal {

class RequestTrackerTest : public Test {
 protected:
  void SetUp() {
    stream1_.max_buffers = 3;
    stream2_.max_buffers = 3;
    dut_.reset(new RequestTracker());
    streams_ = {&stream1_, &stream2_};
    camera3_stream_configuration_t config{
        static_cast<uint32_t>(streams_.size()),
        streams_.data(),
        0,
        nullptr};
    dut_->SetStreamConfiguration(config);
  }

  std::shared_ptr<CaptureRequest> GenerateCaptureRequest(
      uint32_t frame, std::vector<camera3_stream_t*> streams) {
    std::shared_ptr<CaptureRequest> request =
        std::make_shared<CaptureRequest>();

    // Set the frame number and buffers.
    request->frame_number = frame;
    for (const auto stream : streams) {
      // All we really care about for the buffers is which stream they're for.
      camera3_stream_buffer_t buffer{stream, nullptr, 0, -1, -1};
      request->output_buffers.push_back(buffer);
    }

    return request;
  }

  void AddRequest(uint32_t frame,
                  std::vector<camera3_stream_t*> streams,
                  bool expected = true) {
    std::shared_ptr<CaptureRequest> request =
        GenerateCaptureRequest(frame, streams);
    EXPECT_EQ(dut_->CanAddRequest(*request), expected);
    if (expected) {
      EXPECT_FALSE(dut_->InFlight(frame));
    }
    EXPECT_EQ(dut_->Add(request), expected);
    if (expected) {
      EXPECT_TRUE(dut_->InFlight(frame));
    }
  }

  camera3_stream_t stream1_;
  camera3_stream_t stream2_;
  std::vector<camera3_stream_t*> streams_;
  std::shared_ptr<RequestTracker> dut_;
};

TEST_F(RequestTrackerTest, AddValid) {
  uint32_t frame = 34;
  EXPECT_FALSE(dut_->InFlight(frame));
  AddRequest(frame, {&stream1_});
}

TEST_F(RequestTrackerTest, AddInput) {
  EXPECT_TRUE(dut_->Empty());

  // Add a request
  uint32_t frame = 42;
  std::shared_ptr<CaptureRequest> expected = GenerateCaptureRequest(frame, {});
  // Set the input buffer instead of any outputs.
  expected->input_buffer.reset(
      new camera3_stream_buffer_t{&stream1_, nullptr, 0, -1, -1});
  stream1_.max_buffers = 1;

  EXPECT_TRUE(dut_->Add(expected));
  EXPECT_TRUE(dut_->InFlight(frame));
  // Should have added to the count of buffers for stream 1.
  EXPECT_TRUE(dut_->StreamFull(&stream1_));
}

TEST_F(RequestTrackerTest, AddMultipleStreams) {
  stream1_.max_buffers = 1;
  stream2_.max_buffers = 1;

  EXPECT_FALSE(dut_->StreamFull(&stream1_));
  EXPECT_FALSE(dut_->StreamFull(&stream2_));

  // Add a request using both streams.
  AddRequest(99, {&stream1_, &stream2_});

  // Should both have been counted.
  EXPECT_TRUE(dut_->StreamFull(&stream1_));
  EXPECT_TRUE(dut_->StreamFull(&stream2_));
}

TEST_F(RequestTrackerTest, AddUnconfigured) {
  camera3_stream_t stream;
  // Unconfigured should be considered full.
  EXPECT_TRUE(dut_->StreamFull(&stream));
  AddRequest(1, {&stream}, false);
}

TEST_F(RequestTrackerTest, AddPastCapacity) {
  // Set the limit of stream 2 to 1.
  stream2_.max_buffers = 1;

  for (size_t i = 0; i < stream1_.max_buffers; ++i) {
    EXPECT_FALSE(dut_->StreamFull(&stream1_));
    EXPECT_FALSE(dut_->StreamFull(&stream2_));
    AddRequest(i, {&stream1_});
  }
  // Filled up stream 1.
  EXPECT_TRUE(dut_->StreamFull(&stream1_));
  // Stream 2 should still not be full since nothing was added.
  EXPECT_FALSE(dut_->StreamFull(&stream2_));

  // Limit has been hit, can't add more.
  AddRequest(stream1_.max_buffers, {&stream1_, &stream2_}, false);
  EXPECT_TRUE(dut_->StreamFull(&stream1_));
  // Should not have added to the count of stream 2.
  EXPECT_FALSE(dut_->StreamFull(&stream2_));
}

TEST_F(RequestTrackerTest, AddDuplicate) {
  uint32_t frame = 42;
  AddRequest(frame, {&stream1_});
  // Can't add a duplicate.
  AddRequest(frame, {&stream2_}, false);
}

TEST_F(RequestTrackerTest, RemoveValid) {
  EXPECT_TRUE(dut_->Empty());

  // Add a request
  uint32_t frame = 42;
  std::shared_ptr<CaptureRequest> request =
      GenerateCaptureRequest(frame, {&stream1_});
  EXPECT_TRUE(dut_->Add(request));
  EXPECT_TRUE(dut_->InFlight(frame));
  AddRequest(frame + 1, {&stream1_});
  EXPECT_FALSE(dut_->Empty());

  // Remove it.
  EXPECT_TRUE(dut_->Remove(request));
  // Should have removed only the desired request.
  EXPECT_FALSE(dut_->Empty());
}

TEST_F(RequestTrackerTest, RemoveInvalidFrame) {
  EXPECT_TRUE(dut_->Empty());

  // Add a request
  uint32_t frame = 42;
  AddRequest(frame, {&stream1_});
  EXPECT_FALSE(dut_->Empty());

  // Try to remove a different one.
  uint32_t bad_frame = frame + 1;
  std::shared_ptr<CaptureRequest> bad_request =
      GenerateCaptureRequest(bad_frame, {&stream1_});
  EXPECT_FALSE(dut_->InFlight(bad_frame));
  EXPECT_FALSE(dut_->Remove(bad_request));
  EXPECT_FALSE(dut_->Empty());
}

TEST_F(RequestTrackerTest, RemoveInvalidData) {
  EXPECT_TRUE(dut_->Empty());

  // Add a request
  uint32_t frame = 42;
  AddRequest(frame, {&stream1_});
  EXPECT_FALSE(dut_->Empty());

  // Try to remove a different one.
  // Even though this request looks the same, that fact that it is
  // a pointer to a different object means it should fail.
  std::shared_ptr<CaptureRequest> bad_request =
      GenerateCaptureRequest(frame, {&stream1_});
  EXPECT_TRUE(dut_->InFlight(frame));
  EXPECT_FALSE(dut_->Remove(bad_request));
  EXPECT_FALSE(dut_->Empty());
}

TEST_F(RequestTrackerTest, RemoveNull) {
  EXPECT_FALSE(dut_->Remove(nullptr));
}

TEST_F(RequestTrackerTest, ClearRequests) {
  // Create some requests.
  uint32_t frame1 = 42;
  uint32_t frame2 = frame1 + 1;
  std::shared_ptr<CaptureRequest> request1 =
      GenerateCaptureRequest(frame1, {&stream1_});
  std::shared_ptr<CaptureRequest> request2 =
      GenerateCaptureRequest(frame2, {&stream2_});
  std::set<std::shared_ptr<CaptureRequest>> expected;
  expected.insert(request1);
  expected.insert(request2);

  // Insert them.
  EXPECT_TRUE(dut_->Add(request1));
  EXPECT_TRUE(dut_->Add(request2));
  EXPECT_TRUE(dut_->InFlight(frame1));
  EXPECT_TRUE(dut_->InFlight(frame2));
  EXPECT_FALSE(dut_->Empty());
  std::set<std::shared_ptr<CaptureRequest>> actual;

  // Clear them out.
  dut_->Clear(&actual);
  EXPECT_TRUE(dut_->Empty());
  EXPECT_EQ(actual, expected);

  // Configuration (max values) should not have been cleared.
  EXPECT_TRUE(dut_->Add(request1));
}

TEST_F(RequestTrackerTest, ClearRequestsNoResult) {
  // Add some requests.
  EXPECT_TRUE(dut_->Empty());
  AddRequest(1, {&stream1_});
  AddRequest(2, {&stream2_});
  EXPECT_FALSE(dut_->Empty());
  // Don't bother getting the cleared requests.
  dut_->Clear();
  EXPECT_TRUE(dut_->Empty());
}

TEST_F(RequestTrackerTest, ClearConfiguration) {
  EXPECT_FALSE(dut_->StreamFull(&stream1_));
  EXPECT_FALSE(dut_->StreamFull(&stream2_));

  // Clear the configuration.
  dut_->ClearStreamConfiguration();

  // Both streams should be considered full now, since neither is configured.
  EXPECT_TRUE(dut_->StreamFull(&stream1_));
  EXPECT_TRUE(dut_->StreamFull(&stream2_));
}

}  // namespace default_camera_hal