|
13 | 13 | // limitations under the License. |
14 | 14 |
|
15 | 15 | #include "google/cloud/bigtable/emulator/filter.h" |
| 16 | +#include "google/cloud/bigtable/emulator/range_set.h" |
| 17 | +#include "google/cloud/bigtable/emulator/table.h" |
| 18 | +#include "google/cloud/bigtable/emulator/test_util.h" |
16 | 19 | #include "google/cloud/testing_util/chrono_literals.h" |
17 | 20 | #include "google/cloud/testing_util/status_matchers.h" |
18 | 21 | #include "gmock/gmock.h" |
| 22 | +#include <gtest/gtest.h> |
19 | 23 | #include <re2/re2.h> |
| 24 | +#include <algorithm> |
| 25 | +#include <chrono> |
20 | 26 | #include <memory> |
| 27 | +#include <string> |
| 28 | +#include <vector> |
21 | 29 |
|
22 | 30 | namespace google { |
23 | 31 | namespace cloud { |
@@ -1883,6 +1891,71 @@ TEST_F(FilterWorkTest, ConditionBranchFilterNextDifferentThanCell) { |
1883 | 1891 | EXPECT_EQ(expected, *maybe_output); |
1884 | 1892 | } |
1885 | 1893 |
|
| 1894 | +// Test our implementation of the ColumnRange filter, by actually |
| 1895 | +// streaming cells from actual table data (hence end to end). |
| 1896 | +TEST(FiltersEndToEnd, ColumnRange) { |
| 1897 | + std::vector<std::string> column_families = {"family1", "family2", "family3"}; |
| 1898 | + auto maybe_table = CreateTable("table", column_families); |
| 1899 | + ASSERT_STATUS_OK(maybe_table); |
| 1900 | + auto& table = maybe_table.value(); |
| 1901 | + |
| 1902 | + std::vector<SetCellParams> created = { |
| 1903 | + {"family1", "a00", 0, "bar"}, {"family1", "b00", 0, "bar"}, |
| 1904 | + {"family1", "b01", 0, "bar"}, {"family1", "b02", 0, "bar"}, |
| 1905 | + {"family2", "a00", 0, "bar"}, {"family2", "b01", 0, "bar"}, |
| 1906 | + {"family2", "b00", 0, "bar"}, {"family3", "a00", 0, "bar"}, |
| 1907 | + }; |
| 1908 | + |
| 1909 | + std::string row_key = "column-range-row-key"; |
| 1910 | + |
| 1911 | + auto status = SetCells(table, "table", row_key, created); |
| 1912 | + ASSERT_STATUS_OK(status); |
| 1913 | + |
| 1914 | + auto all_rows_set = std::make_shared<StringRangeSet>(StringRangeSet::All()); |
| 1915 | + |
| 1916 | + RowFilter filter; |
| 1917 | + filter.mutable_column_range_filter()->set_family_name("family1"); |
| 1918 | + filter.mutable_column_range_filter()->set_start_qualifier_closed("b00"); |
| 1919 | + filter.mutable_column_range_filter()->set_end_qualifier_open("b02"); |
| 1920 | + |
| 1921 | + struct Cell { |
| 1922 | + std::string row_key; |
| 1923 | + std::string column_family; |
| 1924 | + std::string column_qualifier; |
| 1925 | + std::int64_t timestamp_micros; |
| 1926 | + std::string value; |
| 1927 | + |
| 1928 | + bool operator==(Cell const& other) const { |
| 1929 | + return this->row_key == other.row_key && |
| 1930 | + this->column_family == other.column_family && |
| 1931 | + this->column_qualifier == other.column_qualifier && |
| 1932 | + this->timestamp_micros == other.timestamp_micros && |
| 1933 | + this->value == other.value; |
| 1934 | + } |
| 1935 | + }; |
| 1936 | + |
| 1937 | + auto maybe_stream = table->CreateCellStream(all_rows_set, filter); |
| 1938 | + ASSERT_STATUS_OK(maybe_stream); |
| 1939 | + |
| 1940 | + std::vector<Cell> expected = { |
| 1941 | + {row_key, "family1", "b00", 0, "bar"}, |
| 1942 | + {row_key, "family1", "b01", 0, "bar"}, |
| 1943 | + }; |
| 1944 | + |
| 1945 | + std::vector<Cell> actual; |
| 1946 | + auto& stream = *maybe_stream; |
| 1947 | + for (; stream; ++stream) { |
| 1948 | + actual.push_back({stream->row_key(), stream->column_family(), |
| 1949 | + stream->column_qualifier(), |
| 1950 | + stream->timestamp().count() * 1000, stream->value()}); |
| 1951 | + } |
| 1952 | + |
| 1953 | + ASSERT_EQ(expected.size(), actual.size()); |
| 1954 | + |
| 1955 | + ASSERT_TRUE( |
| 1956 | + std::is_permutation(expected.begin(), expected.end(), actual.begin())); |
| 1957 | +} |
| 1958 | + |
1886 | 1959 | } // namespace emulator |
1887 | 1960 | } // namespace bigtable |
1888 | 1961 | } // namespace cloud |
|
0 commit comments