blob: 3857d7b60d28308535b889913ab863eaa0b1826b [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 <glog/logging.h>
#include <gtest/gtest.h>
#include <limits>
#include <memory>
#include <string>
#include <vector>
#include "hbase/client/cell.h"
#include "hbase/client/result.h"
#include "hbase/utils/optional.h"
using hbase::Cell;
using hbase::CellType;
using hbase::none;
using hbase::Result;
void PopulateCells(std::vector<std::shared_ptr<Cell> > &cells) {
// Populate some Results
// We assume that for a single Cell, the corresponding row, families and
// qualifiers are present.
// We have also considered different versions in the test for the same row.
std::string row = "row";
for (int i = 0; i < 10; i++) {
std::string family = "family-" + std::to_string(i);
std::string column = "column-" + std::to_string(i);
std::string value = "value-" + std::to_string(i);
switch (i) {
case 5: {
cells.push_back(
std::make_shared<Cell>(row, family, column, 1482113040506, "value-5", CellType::PUT));
cells.push_back(
std::make_shared<Cell>(row, family, column, 1482111803856, "value-X", CellType::PUT));
break;
}
case 8: {
cells.push_back(
std::make_shared<Cell>(row, family, column, 1482113040506, "value-8", CellType::PUT));
cells.push_back(
std::make_shared<Cell>(row, family, column, 1482111803856, "value-X", CellType::PUT));
cells.push_back(
std::make_shared<Cell>(row, family, column, 1482110969958, "value-Y", CellType::PUT));
break;
}
case 9: {
cells.push_back(
std::make_shared<Cell>(row, family, column, 1482113040506, "value-9", CellType::PUT));
cells.push_back(
std::make_shared<Cell>(row, family, column, 1482111803856, "value-X", CellType::PUT));
cells.push_back(
std::make_shared<Cell>(row, family, column, 1482110969958, "value-Y", CellType::PUT));
cells.push_back(
std::make_shared<Cell>(row, family, column, 1482110876075, "value-Z", CellType::PUT));
break;
}
default: {
cells.push_back(std::make_shared<Cell>(
row, family, column, std::numeric_limits<int64_t>::max(), value, CellType::PUT));
}
}
}
return;
}
TEST(Result, EmptyResult) {
std::vector<std::shared_ptr<Cell> > cells;
Result result(cells, true, false, false);
EXPECT_EQ(true, result.IsEmpty());
EXPECT_EQ(0, result.Size());
}
TEST(Result, FilledResult) {
std::vector<std::shared_ptr<Cell> > cells;
PopulateCells(cells);
Result result(cells, true, false, false);
EXPECT_EQ(false, result.IsEmpty());
EXPECT_EQ(16, result.Size());
// Get Latest Cell for the given family and qualifier.
auto latest_cell(result.ColumnLatestCell("family", "column"));
// Nothing of the above family/qualifier combo is present so it should be
// nullptr
ASSERT_FALSE(latest_cell.get());
// Try to get the latest cell for the given family and qualifier.
latest_cell = result.ColumnLatestCell("family-4", "column-4");
// Now shouldn't be a nullptr
ASSERT_TRUE(latest_cell.get());
// And Value must match too
EXPECT_EQ("value-4", latest_cell->Value());
// Value will be nullptr as no such family and qualifier is present
ASSERT_FALSE(result.Value("family-4", "qualifier"));
// Value will be present as family and qualifier is present
ASSERT_TRUE(result.Value("family-4", "column-4") != none);
// Value should be present and match.
EXPECT_EQ(latest_cell->Value(), (*result.ColumnLatestCell("family-4", "column-4")).Value());
EXPECT_EQ("value-5", (*result.ColumnLatestCell("family-5", "column-5")).Value());
EXPECT_EQ("value-8", (*result.ColumnLatestCell("family-8", "column-8")).Value());
EXPECT_EQ("value-7", *result.Value("family-7", "column-7"));
// Get cells for the given family and qualifier
auto column_cells = result.ColumnCells("family", "column");
// Size should be 0
EXPECT_EQ(0, column_cells.size());
// Size shouldn't be 0 and Row() and Value() must match
column_cells = result.ColumnCells("family-0", "column-0");
EXPECT_EQ(1, column_cells.size());
EXPECT_EQ("row", column_cells[0]->Row());
EXPECT_EQ("row", result.Row());
// Size shouldn't be 0 and Row() and Value() must match
column_cells = result.ColumnCells("family-5", "column-5");
EXPECT_EQ(2, column_cells.size());
EXPECT_EQ("row", column_cells[0]->Row());
EXPECT_EQ("row", column_cells[1]->Row());
EXPECT_EQ("value-5", column_cells[0]->Value());
EXPECT_EQ("value-X", column_cells[1]->Value());
EXPECT_EQ("row", result.Row());
// Size shouldn't be 0 and Row() and Value() must match
column_cells = result.ColumnCells("family-8", "column-8");
EXPECT_EQ(3, column_cells.size());
EXPECT_EQ("row", column_cells[0]->Row());
EXPECT_EQ("row", column_cells[1]->Row());
EXPECT_EQ("row", column_cells[2]->Row());
EXPECT_EQ("value-8", column_cells[0]->Value());
EXPECT_EQ("value-X", column_cells[1]->Value());
EXPECT_EQ("value-Y", column_cells[2]->Value());
EXPECT_EQ("row", result.Row());
// Size shouldn't be 0 and Row() and Value() must match
column_cells = result.ColumnCells("family-9", "column-9");
EXPECT_EQ(4, column_cells.size());
EXPECT_EQ("row", column_cells[0]->Row());
EXPECT_EQ("row", column_cells[1]->Row());
EXPECT_EQ("row", column_cells[2]->Row());
EXPECT_EQ("row", column_cells[3]->Row());
EXPECT_EQ("value-9", column_cells[0]->Value());
EXPECT_EQ("value-X", column_cells[1]->Value());
EXPECT_EQ("value-Y", column_cells[2]->Value());
EXPECT_EQ("value-Z", column_cells[3]->Value());
EXPECT_EQ("row", result.Row());
// Test all the Cell values
const auto &result_cells = result.Cells();
int i = 0, j = 0;
for (const auto &cell : result_cells) {
std::string row = "row";
std::string family = "family-" + std::to_string(i);
std::string column = "column-" + std::to_string(i);
std::string value = "value-" + std::to_string(i);
switch (j) {
case 6:
case 10:
case 13: {
EXPECT_EQ("value-X", cell->Value());
++j;
continue;
}
case 11:
case 14: {
EXPECT_EQ("value-Y", cell->Value());
++j;
continue;
}
case 15: {
EXPECT_EQ("value-Z", cell->Value());
++j;
continue;
}
}
EXPECT_EQ(row, cell->Row());
EXPECT_EQ(family, cell->Family());
EXPECT_EQ(column, cell->Qualifier());
EXPECT_EQ(value, cell->Value());
++i;
++j;
}
auto result_map_tmp = result.Map();
result_map_tmp["testf"]["testq"][1] = "value";
EXPECT_EQ(11, result_map_tmp.size());
auto result_map = result.Map();
EXPECT_EQ(10, result_map.size());
i = 0;
for (auto family_map : result_map) {
std::string family = "family-" + std::to_string(i);
std::string qualifier = "column-" + std::to_string(i);
std::string value = "value-" + std::to_string(i);
EXPECT_EQ(family, family_map.first);
for (auto qualifier_map : family_map.second) {
EXPECT_EQ(qualifier, qualifier_map.first);
j = 0;
for (auto version_map : qualifier_map.second) {
switch (i) {
case 5: {
if (1 == j) {
EXPECT_EQ(1482111803856, version_map.first);
EXPECT_EQ("value-X", version_map.second);
} else if (0 == j) {
EXPECT_EQ(1482113040506, version_map.first);
EXPECT_EQ("value-5", version_map.second);
}
break;
}
case 8: {
if (2 == j) {
EXPECT_EQ(1482110969958, version_map.first);
EXPECT_EQ("value-Y", version_map.second);
} else if (1 == j) {
EXPECT_EQ(1482111803856, version_map.first);
EXPECT_EQ("value-X", version_map.second);
} else if (0 == j) {
EXPECT_EQ(1482113040506, version_map.first);
EXPECT_EQ("value-8", version_map.second);
}
break;
}
case 9: {
if (3 == j) {
EXPECT_EQ(1482110876075, version_map.first);
EXPECT_EQ("value-Z", version_map.second);
} else if (2 == j) {
EXPECT_EQ(1482110969958, version_map.first);
EXPECT_EQ("value-Y", version_map.second);
} else if (1 == j) {
EXPECT_EQ(1482111803856, version_map.first);
EXPECT_EQ("value-X", version_map.second);
} else if (0 == j) {
EXPECT_EQ(1482113040506, version_map.first);
EXPECT_EQ("value-9", version_map.second);
}
break;
}
default: {
EXPECT_EQ(std::numeric_limits<int64_t>::max(), version_map.first);
EXPECT_EQ(value, version_map.second);
}
}
++j;
}
}
++i;
}
auto family_map = result.FamilyMap("family-0");
EXPECT_EQ(1, family_map.size());
i = 0;
for (auto qual_val_map : family_map) {
EXPECT_EQ("column-0", qual_val_map.first);
EXPECT_EQ("value-0", qual_val_map.second);
}
family_map = result.FamilyMap("family-1");
EXPECT_EQ(1, family_map.size());
i = 0;
for (auto qual_val_map : family_map) {
EXPECT_EQ("column-1", qual_val_map.first);
EXPECT_EQ("value-1", qual_val_map.second);
}
family_map = result.FamilyMap("family-5");
EXPECT_EQ(1, family_map.size());
i = 0;
for (auto qual_val_map : family_map) {
EXPECT_EQ("column-5", qual_val_map.first);
EXPECT_EQ("value-5", qual_val_map.second);
}
family_map = result.FamilyMap("family-9");
EXPECT_EQ(1, family_map.size());
i = 0;
for (auto qual_val_map : family_map) {
EXPECT_EQ("column-9", qual_val_map.first);
EXPECT_EQ("value-9", qual_val_map.second);
}
}
TEST(Result, ResultEstimatedSize) {
CellType cell_type = CellType::PUT;
int64_t timestamp = std::numeric_limits<int64_t>::max();
std::vector<std::shared_ptr<Cell> > cells;
Result empty(cells, true, false, false);
EXPECT_EQ(empty.EstimatedSize(), sizeof(Result));
cells.push_back(std::make_shared<Cell>("a", "a", "", timestamp, "", cell_type));
Result result1(cells, true, false, false);
EXPECT_TRUE(result1.EstimatedSize() > empty.EstimatedSize());
cells.push_back(std::make_shared<Cell>("a", "a", "", timestamp, "", cell_type));
Result result2(cells, true, false, false);
EXPECT_TRUE(result2.EstimatedSize() > result1.EstimatedSize());
LOG(INFO) << empty.EstimatedSize();
LOG(INFO) << result1.EstimatedSize();
LOG(INFO) << result2.EstimatedSize();
}