1 #include "blob_mock.hpp"
2 #include "manager.hpp"
3 
4 #include <vector>
5 
6 #include <gtest/gtest.h>
7 
8 namespace blobs
9 {
10 
11 using ::testing::_;
12 using ::testing::Return;
13 
14 TEST(ManagerReadTest, ReadNoSessionReturnsFalse)
15 {
16     // Calling Read on a session that doesn't exist should return false.
17 
18     BlobManager mgr;
19     uint16_t sess = 1;
20     uint32_t ofs = 0x54;
21     uint32_t requested = 0x100;
22 
23     std::vector<uint8_t> result = mgr.read(sess, ofs, requested);
24     EXPECT_EQ(0, result.size());
25 }
26 
27 TEST(ManagerReadTest, ReadFromWriteOnlyFails)
28 {
29     // The session manager will not route a Read call to a blob if the session
30     // was opened as write-only.
31 
32     BlobManager mgr;
33     std::unique_ptr<BlobMock> m1 = std::make_unique<BlobMock>();
34     auto m1ptr = m1.get();
35     EXPECT_TRUE(mgr.registerHandler(std::move(m1)));
36 
37     uint16_t sess = 1;
38     uint32_t ofs = 0x54;
39     uint32_t requested = 0x100;
40     uint16_t flags = OpenFlags::write;
41     std::string path = "/asdf/asdf";
42 
43     EXPECT_CALL(*m1ptr, canHandleBlob(path)).WillOnce(Return(true));
44     EXPECT_CALL(*m1ptr, open(_, flags, path)).WillOnce(Return(true));
45     EXPECT_TRUE(mgr.open(flags, path, &sess));
46 
47     std::vector<uint8_t> result = mgr.read(sess, ofs, requested);
48     EXPECT_EQ(0, result.size());
49 }
50 
51 TEST(ManagerReadTest, ReadFromHandlerReturnsData)
52 {
53     // There is no logic in this as it's just as a pass-thru command, however
54     // we want to verify this behavior doesn't change.
55 
56     BlobManager mgr;
57     std::unique_ptr<BlobMock> m1 = std::make_unique<BlobMock>();
58     auto m1ptr = m1.get();
59     EXPECT_TRUE(mgr.registerHandler(std::move(m1)));
60 
61     uint16_t sess = 1;
62     uint32_t ofs = 0x54;
63     uint32_t requested = 0x10;
64     uint16_t flags = OpenFlags::read;
65     std::string path = "/asdf/asdf";
66     std::vector<uint8_t> data = {0x12, 0x14, 0x15, 0x16};
67 
68     EXPECT_CALL(*m1ptr, canHandleBlob(path)).WillOnce(Return(true));
69     EXPECT_CALL(*m1ptr, open(_, flags, path)).WillOnce(Return(true));
70     EXPECT_TRUE(mgr.open(flags, path, &sess));
71 
72     EXPECT_CALL(*m1ptr, read(sess, ofs, requested)).WillOnce(Return(data));
73 
74     std::vector<uint8_t> result = mgr.read(sess, ofs, requested);
75     EXPECT_EQ(data.size(), result.size());
76     EXPECT_EQ(result, data);
77 }
78 
79 TEST(ManagerReadTest, ReadTooManyBytesTruncates)
80 {
81     // For now, the hard-coded maximum transfer size is 64 bytes on read
82     // commands, due to a hard-coded buffer in ipmid among other future
83     // challenges.
84 
85     BlobManager mgr;
86     std::unique_ptr<BlobMock> m1 = std::make_unique<BlobMock>();
87     auto m1ptr = m1.get();
88     EXPECT_TRUE(mgr.registerHandler(std::move(m1)));
89 
90     uint16_t sess = 1;
91     uint32_t ofs = 0x54;
92     uint32_t requested = 0x100;
93     uint16_t flags = OpenFlags::read;
94     std::string path = "/asdf/asdf";
95     std::vector<uint8_t> data = {0x12, 0x14, 0x15, 0x16};
96 
97     EXPECT_CALL(*m1ptr, canHandleBlob(path)).WillOnce(Return(true));
98     EXPECT_CALL(*m1ptr, open(_, flags, path)).WillOnce(Return(true));
99     EXPECT_TRUE(mgr.open(flags, path, &sess));
100 
101     EXPECT_CALL(*m1ptr, read(sess, ofs, maximumReadSize))
102         .WillOnce(Return(data));
103 
104     std::vector<uint8_t> result = mgr.read(sess, ofs, requested);
105     EXPECT_EQ(data.size(), result.size());
106     EXPECT_EQ(result, data);
107 }
108 
109 } // namespace blobs
110