YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/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
149
    std::initializer_list<std::pair<const std::string, std::string>> l) {
47
149
  return stl_wrappers::KVMap(l, stl_wrappers::LessOfComparator(&icmp_));
48
149
}
49
50
InternalIterator* MockTableReader::NewIterator(const ReadOptions&, Arena* arena,
51
179
                                               bool skip_filters) {
52
179
  return new MockTableIterator(table_);
53
179
}
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()0
) {
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
89
    const {
73
89
  return std::shared_ptr<const TableProperties>(new TableProperties());
74
89
}
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
124
    unique_ptr<TableReader>* table_reader) const {
82
124
  uint32_t id = GetIDFromFile(file.get());
83
84
124
  MutexLock lock_guard(&file_system_.mutex);
85
86
124
  auto it = file_system_.files.find(id);
87
124
  if (it == file_system_.files.end()) {
88
0
    return STATUS(IOError, "Mock file not found");
89
0
  }
90
91
124
  table_reader->reset(new MockTableReader(it->second));
92
93
124
  return Status::OK();
94
124
}
95
96
TableBuilder* MockTableFactory::NewTableBuilder(
97
    const TableBuilderOptions& table_builder_options, uint32_t column_family_id,
98
88
    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
88
  assert(data_file == nullptr);
103
104
0
  uint32_t id = GetAndWriteNextID(base_file);
105
106
88
  return new MockTableBuilder(id, &file_system_);
107
88
}
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
131
uint32_t MockTableFactory::GetAndWriteNextID(WritableFileWriter* file) const {
125
131
  uint32_t next_id = next_id_.fetch_add(1);
126
131
  char buf[4];
127
131
  EncodeFixed32(buf, next_id);
128
131
  CHECK_OK(file->Append(Slice(buf, 4)));
129
131
  return next_id;
130
131
}
131
132
124
uint32_t MockTableFactory::GetIDFromFile(RandomAccessFileReader* file) const {
133
124
  char buf[4];
134
124
  Slice result;
135
124
  CHECK_OK(file->Read(0, 4, &result, buf));
136
124
  assert(result.size() == 4);
137
0
  return DecodeFixed32(buf);
138
124
}
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