Handle invalid requests. (#1222)

FIXES=#1221
master
gaschler 2018-07-02 13:05:28 +02:00 committed by GitHub
parent eed07d2f80
commit 22ea782fad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 72 additions and 4 deletions

View File

@ -84,7 +84,11 @@ int MapBuilderStub::AddTrajectoryForDeserialization(
mapping::TrajectoryBuilderInterface* MapBuilderStub::GetTrajectoryBuilder( mapping::TrajectoryBuilderInterface* MapBuilderStub::GetTrajectoryBuilder(
int trajectory_id) const { int trajectory_id) const {
return trajectory_builder_stubs_.at(trajectory_id).get(); auto it = trajectory_builder_stubs_.find(trajectory_id);
if (it == trajectory_builder_stubs_.end()) {
return nullptr;
}
return it->second.get();
} }
void MapBuilderStub::FinishTrajectory(int trajectory_id) { void MapBuilderStub::FinishTrajectory(int trajectory_id) {

View File

@ -106,6 +106,8 @@ class ClientServerTest : public ::testing::Test {
mapping::testing::ResolveLuaParameters(kUploadingMapBuilderServerLua); mapping::testing::ResolveLuaParameters(kUploadingMapBuilderServerLua);
uploading_map_builder_server_options_ = CreateMapBuilderServerOptions( uploading_map_builder_server_options_ = CreateMapBuilderServerOptions(
uploading_map_builder_server_parameters.get()); uploading_map_builder_server_parameters.get());
EXPECT_NE(map_builder_server_options_.server_address(),
uploading_map_builder_server_options_.server_address());
const std::string kTrajectoryBuilderLua = R"text( const std::string kTrajectoryBuilderLua = R"text(
include "trajectory_builder.lua" include "trajectory_builder.lua"
@ -491,6 +493,56 @@ TEST_F(ClientServerTest, LoadState) {
// TODO(gaschler): Test-cover LoadStateFromFile. // TODO(gaschler): Test-cover LoadStateFromFile.
TEST_F(ClientServerTest, LocalSlam2DHandlesInvalidRequests) {
InitializeRealServer();
server_->Start();
InitializeStub();
int trajectory_id =
stub_->AddTrajectoryBuilder({kRangeSensorId}, trajectory_builder_options_,
local_slam_result_callback_);
TrajectoryBuilderInterface* trajectory_stub =
stub_->GetTrajectoryBuilder(trajectory_id);
const auto measurements = mapping::testing::GenerateFakeRangeMeasurements(
kTravelDistance, kDuration, kTimeStep);
for (const auto& measurement : measurements) {
trajectory_stub->AddSensorData(kRangeSensorId.id, measurement);
}
WaitForLocalSlamResults(measurements.size());
stub_->pose_graph()->RunFinalOptimization();
const int kInvalidTrajectoryId = 7;
stub_->pose_graph()->DeleteTrajectory(kInvalidTrajectoryId);
EXPECT_FALSE(stub_->pose_graph()->IsTrajectoryFinished(kInvalidTrajectoryId));
EXPECT_FALSE(stub_->pose_graph()->IsTrajectoryFrozen(kInvalidTrajectoryId));
EXPECT_EQ(nullptr, stub_->GetTrajectoryBuilder(kInvalidTrajectoryId));
stub_->FinishTrajectory(kInvalidTrajectoryId);
const mapping::SubmapId kInvalidSubmapId0{kInvalidTrajectoryId, 0},
kInvalidSubmapId1{trajectory_id, 424242};
mapping::proto::SubmapQuery::Response submap_query_response;
// Expect that it returns non-empty error string.
EXPECT_NE("",
stub_->SubmapToProto(kInvalidSubmapId0, &submap_query_response));
EXPECT_NE("",
stub_->SubmapToProto(kInvalidSubmapId1, &submap_query_response));
EXPECT_EQ(stub_->pose_graph()->GetTrajectoryStates().at(trajectory_id),
PoseGraphInterface::TrajectoryState::ACTIVE);
auto submap_poses = stub_->pose_graph()->GetAllSubmapPoses();
EXPECT_GT(submap_poses.size(), 0);
EXPECT_GT(stub_->pose_graph()->GetTrajectoryNodePoses().size(), 0);
stub_->FinishTrajectory(trajectory_id);
stub_->pose_graph()->DeleteTrajectory(trajectory_id);
stub_->pose_graph()->RunFinalOptimization();
mapping::SubmapId deleted_submap_id = submap_poses.begin()->id;
EXPECT_NE("",
stub_->SubmapToProto(deleted_submap_id, &submap_query_response));
EXPECT_EQ(stub_->pose_graph()->GetTrajectoryStates().at(trajectory_id),
PoseGraphInterface::TrajectoryState::DELETED);
// Make sure optimization runs with a deleted trajectory.
stub_->pose_graph()->RunFinalOptimization();
server_->Shutdown();
}
} // namespace } // namespace
} // namespace cloud } // namespace cloud
} // namespace cartographer } // namespace cartographer

View File

@ -289,7 +289,7 @@ class MapById {
void Trim(const IdType& id) { void Trim(const IdType& id) {
auto& trajectory = trajectories_.at(id.trajectory_id); auto& trajectory = trajectories_.at(id.trajectory_id);
const auto it = trajectory.data_.find(GetIndex(id)); const auto it = trajectory.data_.find(GetIndex(id));
CHECK(it != trajectory.data_.end()); CHECK(it != trajectory.data_.end()) << id;
if (std::next(it) == trajectory.data_.end()) { if (std::next(it) == trajectory.data_.end()) {
// We are removing the data with the highest index from this trajectory. // We are removing the data with the highest index from this trajectory.
// We assume that we will never append to it anymore. If we did, we would // We assume that we will never append to it anymore. If we did, we would

View File

@ -467,7 +467,13 @@ void PoseGraph2D::WaitForAllComputations() {
void PoseGraph2D::DeleteTrajectory(const int trajectory_id) { void PoseGraph2D::DeleteTrajectory(const int trajectory_id) {
common::MutexLocker locker(&mutex_); common::MutexLocker locker(&mutex_);
data_.trajectories_state.at(trajectory_id).deletion_state = auto it = data_.trajectories_state.find(trajectory_id);
if (it == data_.trajectories_state.end()) {
LOG(WARNING) << "Skipping request to delete non-existing trajectory_id: "
<< trajectory_id;
return;
}
it->second.deletion_state =
InternalTrajectoryState::DeletionState::SCHEDULED_FOR_DELETION; InternalTrajectoryState::DeletionState::SCHEDULED_FOR_DELETION;
AddWorkItem([this, trajectory_id]() REQUIRES(mutex_) { AddWorkItem([this, trajectory_id]() REQUIRES(mutex_) {
CHECK(data_.trajectories_state.at(trajectory_id).state != CHECK(data_.trajectories_state.at(trajectory_id).state !=

View File

@ -484,7 +484,13 @@ void PoseGraph3D::WaitForAllComputations() {
void PoseGraph3D::DeleteTrajectory(const int trajectory_id) { void PoseGraph3D::DeleteTrajectory(const int trajectory_id) {
common::MutexLocker locker(&mutex_); common::MutexLocker locker(&mutex_);
data_.trajectories_state.at(trajectory_id).deletion_state = auto it = data_.trajectories_state.find(trajectory_id);
if (it == data_.trajectories_state.end()) {
LOG(WARNING) << "Skipping request to delete non-existing trajectory_id: "
<< trajectory_id;
return;
}
it->second.deletion_state =
InternalTrajectoryState::DeletionState::SCHEDULED_FOR_DELETION; InternalTrajectoryState::DeletionState::SCHEDULED_FOR_DELETION;
AddWorkItem([this, trajectory_id]() REQUIRES(mutex_) { AddWorkItem([this, trajectory_id]() REQUIRES(mutex_) {
CHECK(data_.trajectories_state.at(trajectory_id).state != CHECK(data_.trajectories_state.at(trajectory_id).state !=