Coverage Report

Created: 2023-12-11 06:17

/proc/self/cwd/src/ir/module_test.cc
Line
Count
Source (jump to first uncovered line)
1
//-----------------------------------------------------------------------------
2
// Copyright 2022 Google LLC
3
//
4
// Licensed under the Apache License, Version 2.0 (the "License");
5
// you may not use this file except in compliance with the License.
6
// You may obtain a copy of the License at
7
//
8
//     https://www.apache.org/licenses/LICENSE-2.0
9
//
10
// Unless required by applicable law or agreed to in writing, software
11
// distributed under the License is distributed on an "AS IS" BASIS,
12
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
// See the License for the specific language governing permissions and
14
// limitations under the License.
15
//----------------------------------------------------------------------------
16
#include "src/ir/module.h"
17
18
#include <string>
19
#include <vector>
20
21
#include "fuzztest/fuzztest.h"
22
#include "src/common/testing/gtest.h"
23
#include "src/ir/storage.h"
24
#include "src/ir/types/type_factory.h"
25
#include "src/ir/value.h"
26
27
namespace raksha::ir {
28
namespace {
29
30
using fuzztest::Arbitrary;
31
using fuzztest::NonEmpty;
32
using fuzztest::PrintableAsciiString;
33
using fuzztest::UniqueElementsVectorOf;
34
using raksha::ir::types::TypeFactory;
35
using raksha::ir::value::Any;
36
using testing::IsEmpty;
37
using testing::UnorderedElementsAreArray;
38
39
0
TEST(ModuleTest, DefaultConstructorCreatesEmptyBlocks) {
40
0
  Module module;
41
0
  EXPECT_EQ(module.blocks().size(), 0);
42
0
}
43
44
0
TEST(ModuleTest, AddBlockReturnsPassedInBlock) {
45
0
  Module module;
46
0
  auto block = std::make_unique<Block>();
47
0
  const Block* passed_in_block = block.get();
48
0
  const Block& returned_block = module.AddBlock(std::move(block));
49
0
  EXPECT_EQ(std::addressof(returned_block), passed_in_block);
50
0
  EXPECT_EQ(returned_block.parent_module(), &module);
51
0
}
52
53
0
TEST(ModuleTest, AddBlockUpdatesBlockList) {
54
0
  Module module;
55
0
  const Block* block1 =
56
0
      std::addressof(module.AddBlock(std::make_unique<Block>()));
57
0
  const Block* block2 =
58
0
      std::addressof(module.AddBlock(std::make_unique<Block>()));
59
0
  EXPECT_NE(block1, block2);
60
0
  EXPECT_THAT(module.blocks(), testing::UnorderedElementsAre(
61
0
                                   testing::Pointer(testing::Eq(block1)),
62
0
                                   testing::Pointer(testing::Eq(block2))));
63
0
}
64
65
class ModuleStorageTestFixture {
66
 public:
67
  explicit ModuleStorageTestFixture(std::vector<std::string> storage_names)
68
4.43k
      : module_(), type_factory_() {
69
4.43k
    bool first = true;
70
128k
    for (absl::string_view name : storage_names) {
71
128k
      if (first) {
72
4.37k
        name_not_in_storages_ = name;
73
4.37k
        first = false;
74
4.37k
        continue;
75
4.37k
      }
76
123k
      created_storages_.push_back(
77
123k
          &module_.CreateStorage(name, type_factory_.MakePrimitiveType()));
78
123k
    }
79
4.43k
  }
80
31.1k
  Module& module() { return module_; }
81
829
  TypeFactory& type_factory() { return type_factory_; }
82
6.97k
  const std::vector<const Storage*>& created_storages() {
83
6.97k
    return created_storages_;
84
6.97k
  }
85
829
  absl::string_view name_not_in_storages() { return name_not_in_storages_; }
86
87
 private:
88
  Module module_;
89
  TypeFactory type_factory_;
90
  std::vector<const Storage*> created_storages_;
91
  // A name that is not taken by any of the created storages. Useful for a
92
  // number of tests.
93
  std::string name_not_in_storages_;
94
};
95
96
std::vector<const Storage*> MakeNamedStorageMapIntoStorageVector(
97
1.65k
    const Module::NamedStorageMap& map) {
98
1.65k
  std::vector<const Storage*> storage_vector;
99
1.65k
  storage_vector.reserve(map.size());
100
79.1k
  for (const auto& name_storage_pair : map) {
101
79.1k
    CHECK(name_storage_pair.first == name_storage_pair.second->name());
102
79.1k
    storage_vector.push_back(name_storage_pair.second.get());
103
79.1k
  }
104
1.65k
  return storage_vector;
105
1.65k
}
106
107
829
void TestCreateStorages(std::vector<std::string> storage_names) {
108
829
  ModuleStorageTestFixture fixture(std::move(storage_names));
109
829
  EXPECT_THAT(MakeNamedStorageMapIntoStorageVector(
110
829
                  fixture.module().named_storage_map()),
111
829
              UnorderedElementsAreArray(fixture.created_storages()));
112
829
  const Storage& storage = fixture.module().CreateStorage(
113
829
      fixture.name_not_in_storages(),
114
829
      fixture.type_factory().MakePrimitiveType());
115
829
  std::vector<const Storage*> created_storages_plus_new_element;
116
829
  created_storages_plus_new_element.push_back(&storage);
117
829
  created_storages_plus_new_element.insert(
118
829
      created_storages_plus_new_element.end(),
119
829
      fixture.created_storages().begin(), fixture.created_storages().end());
120
829
  EXPECT_THAT(MakeNamedStorageMapIntoStorageVector(
121
829
                  fixture.module().named_storage_map()),
122
829
              UnorderedElementsAreArray(created_storages_plus_new_element));
123
829
}
124
125
FUZZ_TEST(ModuleStorageTest, TestCreateStorages)
126
    .WithDomains(NonEmpty(UniqueElementsVectorOf(PrintableAsciiString())));
127
128
940
void GetAddedStorageBehavesCorrectly(std::vector<std::string> storage_names) {
129
940
  ModuleStorageTestFixture fixture(std::move(storage_names));
130
26.7k
  for (const Storage* storage : fixture.created_storages()) {
131
26.7k
    EXPECT_EQ(&fixture.module().GetStorage(storage->name()), storage);
132
26.7k
  }
133
940
}
134
135
FUZZ_TEST(ModuleStorageTest, GetAddedStorageBehavesCorrectly)
136
    .WithDomains(NonEmpty(UniqueElementsVectorOf(PrintableAsciiString())));
137
138
889
void GetNotPresentStorageFails(std::vector<std::string> storage_names) {
139
889
  ModuleStorageTestFixture fixture(std::move(storage_names));
140
889
  EXPECT_DEATH(fixture.module().GetStorage(fixture.name_not_in_storages()),
141
889
               absl::StrCat(".*Could not find Storage with name.*"));
142
889
}
143
144
FUZZ_TEST(ModuleStorageTest, GetNotPresentStorageFails)
145
    .WithDomains(NonEmpty(UniqueElementsVectorOf(PrintableAsciiString())));
146
147
void CreateStorageSameNameDies(std::vector<std::string> storage_names,
148
827
                               uint64_t idx) {
149
827
  ModuleStorageTestFixture fixture(std::move(storage_names));
150
827
  absl::string_view name_to_duplicate =
151
827
      fixture.created_storages()
152
827
          .at(idx % fixture.created_storages().size())
153
827
          ->name();
154
827
  EXPECT_DEATH(
155
827
      fixture.module().CreateStorage(
156
827
          name_to_duplicate, fixture.type_factory().MakePrimitiveType()),
157
827
      ".*Multiple stores with name.*");
158
827
}
159
160
FUZZ_TEST(ModuleStorageTest, CreateStorageSameNameDies)
161
    .WithDomains(UniqueElementsVectorOf(PrintableAsciiString()).WithMinSize(2),
162
                 Arbitrary<uint64_t>());
163
164
947
void AddValueToStorage(std::vector<std::string> storage_names, uint64_t idx) {
165
947
  ModuleStorageTestFixture fixture(std::move(storage_names));
166
947
  absl::string_view name_to_add_value_to =
167
947
      fixture.created_storages()
168
947
          .at(idx % fixture.created_storages().size())
169
947
          ->name();
170
947
  Value value_to_add = Value(Any());
171
947
  fixture.module().AddInputValueToStorage(name_to_add_value_to, value_to_add);
172
20.9k
  for (const auto& [name, storage] : fixture.module().named_storage_map()) {
173
20.9k
    if (name == name_to_add_value_to) {
174
947
      EXPECT_THAT(storage->input_values(),
175
947
                  UnorderedElementsAreArray({value_to_add}));
176
19.9k
    } else {
177
19.9k
      EXPECT_THAT(storage->input_values(), IsEmpty());
178
19.9k
    }
179
20.9k
  }
180
947
}
181
182
FUZZ_TEST(ModuleStorageTest, AddValueToStorage)
183
    .WithDomains(UniqueElementsVectorOf(PrintableAsciiString()).WithMinSize(2),
184
                 Arbitrary<uint64_t>());
185
186
}  // namespace
187
}  // namespace raksha::ir