YugabyteDB (2.13.0.0-b42, bfc6a6643e7399ac8a0e81d06a3ee6d6571b33ab)

Coverage Report

Created: 2022-03-09 17:30

/Users/deen/code/yugabyte-db/src/yb/rocksdb/table/mock_table.cc
Line
Count
Source (jump to first uncovered line)
1
// Use of this source code is governed by a BSD-style license that can be
2
// found in the LICENSE file. See the AUTHORS file for names of contributors.
3
//  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
4
//  This source code is licensed under the BSD-style license found in the
5
//  LICENSE file in the root directory of this source tree. An additional grant
6
//  of patent rights can be found in the PATENTS file in the same directory.
7
//
8
// The following only applies to changes made to this file as part of YugaByte development.
9
//
10
// Portions Copyright (c) YugaByte, Inc.
11
//
12
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
13
// in compliance with the License.  You may obtain a copy of the License at
14
//
15
// http://www.apache.org/licenses/LICENSE-2.0
16
//
17
// Unless required by applicable law or agreed to in writing, software distributed under the License
18
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
19
// or implied.  See the License for the specific language governing permissions and limitations
20
// under the License.
21
//
22
23
#include "yb/rocksdb/table/mock_table.h"
24
25
#include <gtest/gtest.h>
26
27
#include "yb/rocksdb/db/dbformat.h"
28
#include "yb/rocksdb/port/port.h"
29
#include "yb/rocksdb/table_properties.h"
30
#include "yb/rocksdb/table/get_context.h"
31
#include "yb/rocksdb/util/coding.h"
32
#include "yb/rocksdb/util/file_reader_writer.h"
33
34
#include "yb/util/status_log.h"
35
36
namespace rocksdb {
37
namespace mock {
38
39
namespace {
40
41
const InternalKeyComparator icmp_(BytewiseComparator());
42
43
}  // namespace
44
45
stl_wrappers::KVMap MakeMockFile(
46
148
    std::initializer_list<std::pair<const std::string, std::string>> l) {
47
148
  return stl_wrappers::KVMap(l, stl_wrappers::LessOfComparator(&icmp_));
48
148
}
49
50
InternalIterator* MockTableReader::NewIterator(const ReadOptions&, Arena* arena,
51
178
                                               bool skip_filters) {
52
178
  return new MockTableIterator(table_);
53
178
}
54
55
Status MockTableReader::Get(const ReadOptions&, const Slice& key,
56
10
                            GetContext* get_context, bool skip_filters) {
57
10
  std::unique_ptr<MockTableIterator> iter(new MockTableIterator(table_));
58
10
  for (iter->Seek(key); iter->Valid(); iter->Next()) {
59
10
    ParsedInternalKey parsed_key;
60
10
    if (!ParseInternalKey(iter->key(), &parsed_key)) {
61
0
      return STATUS(Corruption, Slice());
62
0
    }
63
64
10
    if (!get_context->SaveValue(parsed_key, iter->value())) {
65
10
      break;
66
10
    }
67
10
  }
68
10
  return Status::OK();
69
10
}
70
71
std::shared_ptr<const TableProperties> MockTableReader::GetTableProperties()
72
88
    const {
73
88
  return std::shared_ptr<const TableProperties>(new TableProperties());
74
88
}
75
76
23
MockTableFactory::MockTableFactory() : next_id_(1) {}
77
78
Status MockTableFactory::NewTableReader(
79
    const TableReaderOptions& table_reader_options,
80
    unique_ptr<RandomAccessFileReader>&& file, uint64_t file_size,
81
123
    unique_ptr<TableReader>* table_reader) const {
82
123
  uint32_t id = GetIDFromFile(file.get());
83
84
123
  MutexLock lock_guard(&file_system_.mutex);
85
86
123
  auto it = file_system_.files.find(id);
87
123
  if (it == file_system_.files.end()) {
88
0
    return STATUS(IOError, "Mock file not found");
89
0
  }
90
91
123
  table_reader->reset(new MockTableReader(it->second));
92
93
123
  return Status::OK();
94
123
}
95
96
TableBuilder* MockTableFactory::NewTableBuilder(
97
    const TableBuilderOptions& table_builder_options, uint32_t column_family_id,
98
87
    WritableFileWriter* base_file, WritableFileWriter* data_file) const {
99
  // This table factory doesn't support separate files for metadata and data, because tests using
100
  // mock tables don't assume separate data file since they are intended for unit testing features
101
  // which are independent of SST storage format.
102
87
  assert(data_file == nullptr);
103
104
87
  uint32_t id = GetAndWriteNextID(base_file);
105
106
87
  return new MockTableBuilder(id, &file_system_);
107
87
}
108
109
Status MockTableFactory::CreateMockTable(Env* env, const std::string& fname,
110
43
                                         stl_wrappers::KVMap file_contents) {
111
43
  std::unique_ptr<WritableFile> file;
112
43
  auto s = env->NewWritableFile(fname, &file, EnvOptions());
113
43
  if (!s.ok()) {
114
0
    return s;
115
0
  }
116
117
43
  WritableFileWriter file_writer(std::move(file), EnvOptions());
118
119
43
  uint32_t id = GetAndWriteNextID(&file_writer);
120
43
  file_system_.files.insert({id, std::move(file_contents)});
121
43
  return Status::OK();
122
43
}
123
124
130
uint32_t MockTableFactory::GetAndWriteNextID(WritableFileWriter* file) const {
125
130
  uint32_t next_id = next_id_.fetch_add(1);
126
130
  char buf[4];
127
130
  EncodeFixed32(buf, next_id);
128
130
  CHECK_OK(file->Append(Slice(buf, 4)));
129
130
  return next_id;
130
130
}
131
132
123
uint32_t MockTableFactory::GetIDFromFile(RandomAccessFileReader* file) const {
133
123
  char buf[4];
134
123
  Slice result;
135
123
  CHECK_OK(file->Read(0, 4, &result, buf));
136
123
  assert(result.size() == 4);
137
123
  return DecodeFixed32(buf);
138
123
}
139
140
void MockTableFactory::AssertSingleFile(
141
2
    const stl_wrappers::KVMap& file_contents) {
142
2
  ASSERT_EQ(file_system_.files.size(), 1U);
143
2
  ASSERT_TRUE(file_contents == file_system_.files.begin()->second);
144
2
}
145
146
void MockTableFactory::AssertLatestFile(
147
16
    const stl_wrappers::KVMap& file_contents) {
148
16
  ASSERT_GE(file_system_.files.size(), 1U);
149
16
  auto latest = file_system_.files.end();
150
16
  --latest;
151
152
16
  if (file_contents != latest->second) {
153
0
    std::cout << "Wrong content! Content of latest file:" << std::endl;
154
0
    for (const auto& kv : latest->second) {
155
0
      ParsedInternalKey ikey;
156
0
      std::string key, value;
157
0
      std::tie(key, value) = kv;
158
0
      ParseInternalKey(Slice(key), &ikey);
159
0
      std::cout << ikey.DebugString(false) << " -> " << value << std::endl;
160
0
    }
161
0
    ASSERT_TRUE(false);
162
0
  }
163
16
}
164
165
}  // namespace mock
166
}  // namespace rocksdb