this repo has no description
at trunk 209 lines 7.8 kB view raw
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 2#include "byteslike.h" 3 4#include "gtest/gtest.h" 5 6#include "handles.h" 7#include "objects.h" 8#include "test-utils.h" 9#include "view.h" 10 11namespace py { 12namespace testing { 13 14using ByteslikeTest = RuntimeFixture; 15 16TEST_F(ByteslikeTest, ConstructWithSmallBytes) { 17 HandleScope scope(thread_); 18 View<byte> bytes(reinterpret_cast<const byte*>("hello"), 5); 19 Object value(&scope, SmallBytes::fromBytes(bytes)); 20 Byteslike byteslike(&scope, thread_, *value); 21 EXPECT_TRUE(byteslike.isValid()); 22 EXPECT_EQ(byteslike.length(), 5); 23 EXPECT_EQ(byteslike.byteAt(0), 'h'); 24 EXPECT_EQ(byteslike.byteAt(4), 'o'); 25 EXPECT_EQ(std::memcmp(reinterpret_cast<const byte*>(byteslike.address()), 26 "hello", 5), 27 0); 28} 29 30TEST_F(ByteslikeTest, ConstructWithLargeBytes) { 31 HandleScope scope(thread_); 32 byte bytes[] = "hello foo bar\0baz\n"; 33 Object value(&scope, runtime_->newBytesWithAll(bytes)); 34 EXPECT_TRUE(value.isLargeBytes()); 35 Byteslike byteslike(&scope, thread_, *value); 36 EXPECT_TRUE(byteslike.isValid()); 37 runtime_->collectGarbage(); 38 EXPECT_EQ(byteslike.length(), static_cast<word>(ARRAYSIZE(bytes))); 39 EXPECT_EQ(byteslike.byteAt(0), 'h'); 40 EXPECT_EQ(byteslike.byteAt(4), 'o'); 41 EXPECT_EQ(byteslike.byteAt(13), '\0'); 42 EXPECT_EQ(byteslike.byteAt(15), 'a'); 43 EXPECT_EQ(byteslike.byteAt(17), '\n'); 44 EXPECT_EQ(byteslike.address(), LargeBytes::cast(*value).address()); 45} 46 47TEST_F(ByteslikeTest, ConstructWithMutableBytes) { 48 HandleScope scope(thread_); 49 byte bytes[] = "hello foo bar\0baz\n"; 50 MutableBytes value(&scope, 51 runtime_->newMutableBytesUninitialized(ARRAYSIZE(bytes))); 52 value.replaceFromWithAll(0, {bytes, ARRAYSIZE(bytes)}); 53 Byteslike byteslike(&scope, thread_, *value); 54 EXPECT_TRUE(byteslike.isValid()); 55 runtime_->collectGarbage(); 56 EXPECT_EQ(byteslike.length(), static_cast<word>(ARRAYSIZE(bytes))); 57 EXPECT_EQ(byteslike.byteAt(0), 'h'); 58 EXPECT_EQ(byteslike.byteAt(4), 'o'); 59 EXPECT_EQ(byteslike.byteAt(13), '\0'); 60 EXPECT_EQ(byteslike.byteAt(15), 'a'); 61 EXPECT_EQ(byteslike.byteAt(17), '\n'); 62 EXPECT_EQ(byteslike.address(), value.address()); 63} 64 65TEST_F(ByteslikeTest, ConstructWithByteSubclassWithSmallBytes) { 66 HandleScope scope(thread_); 67 ASSERT_FALSE(runFromCStr(runtime_, R"( 68class C(bytes): pass 69value = C(b"hello") 70)") 71 .isError()); 72 Object value(&scope, mainModuleAt(runtime_, "value")); 73 EXPECT_TRUE(bytesUnderlying(*value).isSmallBytes()); 74 Byteslike byteslike(&scope, thread_, *value); 75 EXPECT_TRUE(byteslike.isValid()); 76 EXPECT_EQ(byteslike.length(), 5); 77 EXPECT_EQ(byteslike.byteAt(0), 'h'); 78 EXPECT_EQ(byteslike.byteAt(4), 'o'); 79 EXPECT_EQ(std::memcmp(reinterpret_cast<const byte*>(byteslike.address()), 80 "hello", 5), 81 0); 82} 83 84TEST_F(ByteslikeTest, ConstructWithByteSubclassWithLargeBytes) { 85 HandleScope scope(thread_); 86 ASSERT_FALSE(runFromCStr(runtime_, R"( 87class C(bytes): pass 88value = C(b"hello foo bar\0baz\n") 89)") 90 .isError()); 91 Object value(&scope, mainModuleAt(runtime_, "value")); 92 EXPECT_TRUE(bytesUnderlying(*value).isLargeBytes()); 93 Byteslike byteslike(&scope, thread_, *value); 94 EXPECT_TRUE(byteslike.isValid()); 95 runtime_->collectGarbage(); 96 EXPECT_EQ(byteslike.length(), 18); 97 EXPECT_EQ(byteslike.byteAt(0), 'h'); 98 EXPECT_EQ(byteslike.byteAt(4), 'o'); 99 EXPECT_EQ(byteslike.byteAt(13), '\0'); 100 EXPECT_EQ(byteslike.byteAt(15), 'a'); 101 EXPECT_EQ(byteslike.byteAt(17), '\n'); 102 EXPECT_EQ(byteslike.address(), 103 LargeBytes::cast(bytesUnderlying(*value)).address()); 104} 105 106TEST_F(ByteslikeTest, ConstructWithBytearray) { 107 HandleScope scope(thread_); 108 Bytearray value(&scope, runtime_->newBytearray()); 109 runtime_->bytearrayEnsureCapacity(thread_, value, 32); 110 byte bytes[] = "hello foo bar\0baz\n"; 111 runtime_->bytearrayExtend(thread_, value, bytes); 112 // We want to test the case where numItems() != items.length 113 EXPECT_NE(value.numItems(), MutableBytes::cast(value.items()).length()); 114 Byteslike byteslike(&scope, thread_, *value); 115 EXPECT_TRUE(byteslike.isValid()); 116 runtime_->collectGarbage(); 117 EXPECT_EQ(byteslike.length(), static_cast<word>(ARRAYSIZE(bytes))); 118 EXPECT_EQ(byteslike.byteAt(0), 'h'); 119 EXPECT_EQ(byteslike.byteAt(4), 'o'); 120 EXPECT_EQ(byteslike.byteAt(13), '\0'); 121 EXPECT_EQ(byteslike.byteAt(15), 'a'); 122 EXPECT_EQ(byteslike.byteAt(17), '\n'); 123 EXPECT_EQ(byteslike.address(), MutableBytes::cast(value.items()).address()); 124} 125 126TEST_F(ByteslikeTest, ConstructWithArray) { 127 HandleScope scope(thread_); 128 ASSERT_FALSE(runFromCStr(runtime_, R"( 129import array 130value = array.array("Q") 131value.append(0xcafebabe12345678) 132)") 133 .isError()); 134 Array value(&scope, mainModuleAt(runtime_, "value")); 135 ASSERT_EQ(value.length(), 1); 136 // We want to test the case where the array buffer is bigger than the 137 // contents. If this fails adjust test. 138 ASSERT_TRUE(MutableBytes::cast(value.buffer()).length() > 8); 139 140 static_assert(endian::native == endian::little, 141 "test designed for little endian systems"); 142 Byteslike byteslike(&scope, thread_, *value); 143 EXPECT_TRUE(byteslike.isValid()); 144 runtime_->collectGarbage(); 145 EXPECT_EQ(byteslike.length(), 8); 146 EXPECT_EQ(byteslike.byteAt(0), 0x78); 147 EXPECT_EQ(byteslike.byteAt(7), 0xca); 148 EXPECT_EQ(byteslike.byteAt(6), 0xfe); 149 EXPECT_EQ(byteslike.address(), MutableBytes::cast(value.buffer()).address()); 150} 151 152TEST_F(ByteslikeTest, ConstructWithMemoryviewWithSmallBytes) { 153 HandleScope scope(thread_); 154 byte bytes[] = "hello!"; 155 Object bytes_obj(&scope, SmallBytes::fromBytes(bytes)); 156 MemoryView value(&scope, 157 runtime_->newMemoryView(thread_, bytes_obj, bytes_obj, 3, 158 ReadOnly::ReadOnly)); 159 value.setStart(3); 160 Byteslike byteslike(&scope, thread_, *value); 161 EXPECT_TRUE(byteslike.isValid()); 162 EXPECT_EQ(byteslike.length(), 3); 163 EXPECT_EQ(byteslike.byteAt(0), 'l'); 164 EXPECT_EQ(byteslike.byteAt(1), 'o'); 165 EXPECT_EQ(byteslike.byteAt(2), '!'); 166} 167 168TEST_F(ByteslikeTest, ConstructWithMemoryviewWithLargeBytes) { 169 HandleScope scope(thread_); 170 byte bytes[] = "hello foo bar\0baz\n"; 171 LargeBytes bytes_obj(&scope, runtime_->newBytesWithAll(bytes)); 172 MemoryView value(&scope, 173 runtime_->newMemoryView(thread_, bytes_obj, bytes_obj, 11, 174 ReadOnly::ReadOnly)); 175 Byteslike byteslike(&scope, thread_, *value); 176 EXPECT_TRUE(byteslike.isValid()); 177 EXPECT_EQ(byteslike.length(), 11); 178 EXPECT_EQ(byteslike.byteAt(0), 'h'); 179 EXPECT_EQ(byteslike.byteAt(4), 'o'); 180 EXPECT_EQ(byteslike.address(), bytes_obj.address()); 181} 182 183TEST_F(ByteslikeTest, ConstructWithMemoryviewWithPointer) { 184 HandleScope scope(thread_); 185 byte bytes[] = "hello foo bar\0baz\n"; 186 Pointer pointer(&scope, runtime_->newPointer(bytes, sizeof(bytes))); 187 MemoryView value(&scope, runtime_->newMemoryView(thread_, pointer, pointer, 188 15, ReadOnly::ReadOnly)); 189 word start = 1; 190 value.setStart(start); 191 Byteslike byteslike(&scope, thread_, *value); 192 EXPECT_TRUE(byteslike.isValid()); 193 EXPECT_EQ(byteslike.length(), 15); 194 EXPECT_EQ(byteslike.byteAt(0), 'e'); 195 EXPECT_EQ(byteslike.byteAt(5), 'f'); 196 EXPECT_EQ(byteslike.byteAt(12), '\0'); 197 EXPECT_EQ(byteslike.byteAt(14), 'a'); 198 EXPECT_EQ(byteslike.address(), bit_cast<uword>(&bytes) + start); 199} 200 201TEST_F(ByteslikeTest, IsValidWithNonByteslikeReturnsFalse) { 202 HandleScope scope(thread_); 203 Object value(&scope, runtime_->newFloat(42.42)); 204 Byteslike byteslike(&scope, thread_, *value); 205 EXPECT_FALSE(byteslike.isValid()); 206} 207 208} // namespace testing 209} // namespace py