this repo has no description
at trunk 317 lines 11 kB view raw
1// Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) 2#include "under-imp-module.h" 3 4#include "cpython-types.h" 5#include "gtest/gtest.h" 6 7#include "builtins.h" 8#include "runtime.h" 9#include "test-utils.h" 10 11namespace py { 12namespace testing { 13 14using UnderImpModuleTest = RuntimeFixture; 15using ImportBuiltinsDeathTest = RuntimeFixture; 16using ImportBuiltinsTest = RuntimeFixture; 17 18TEST_F(UnderImpModuleTest, ModuleImporting) { 19 ASSERT_FALSE(runFromCStr(runtime_, R"( 20import _imp 21 )") 22 .isError()); 23 RawObject imp = mainModuleAt(runtime_, "_imp"); 24 EXPECT_TRUE(imp.isModule()); 25} 26 27TEST_F(ImportBuiltinsTest, AcquireLockAndReleaseLockWorks) { 28 runBuiltin(FUNC(_imp, acquire_lock)); 29 runBuiltin(FUNC(_imp, release_lock)); 30} 31 32TEST_F(ImportBuiltinsTest, CreateBuiltinWithoutArgsRaisesTypeError) { 33 EXPECT_TRUE(raised(runFromCStr(runtime_, R"( 34import _imp 35_imp.create_builtin() 36)"), 37 LayoutId::kTypeError)); 38} 39 40TEST_F(ImportBuiltinsTest, CreateBuiltinWithoutSpecNameRaisesTypeError) { 41 EXPECT_TRUE(raised(runFromCStr(runtime_, R"( 42import _imp 43_imp.create_builtin(123) 44)"), 45 LayoutId::kTypeError)); 46} 47 48TEST_F(ImportBuiltinsTest, CreateBuiltinWithNonStrSpecNameRaisesTypeError) { 49 // Mock of importlib._bootstrap.ModuleSpec 50 EXPECT_TRUE(raised(runFromCStr(runtime_, R"( 51import _imp 52class DummyModuleSpec: 53 def __init__(self, name): 54 self.name = name 55spec = DummyModuleSpec(5) 56_imp.create_builtin(spec) 57)"), 58 LayoutId::kTypeError)); 59} 60 61TEST_F(ImportBuiltinsTest, CreateBuiltinWithNonExistentModuleReturnsNone) { 62 // Mock of importlib._bootstrap.ModuleSpec 63 ASSERT_FALSE(runFromCStr(runtime_, R"( 64import _imp 65class DummyModuleSpec: 66 def __init__(self, name): 67 self.name = name 68spec = DummyModuleSpec("non_existent_module") 69result = _imp.create_builtin(spec) 70)") 71 .isError()); 72 HandleScope scope(thread_); 73 Object result(&scope, mainModuleAt(runtime_, "result")); 74 EXPECT_TRUE(result.isNoneType()); 75} 76 77TEST_F(ImportBuiltinsTest, CreateBuiltinReturnsModule) { 78 // Mock of importlib._bootstrap.ModuleSpec 79 ASSERT_FALSE(runFromCStr(runtime_, R"( 80import _imp 81class DummyModuleSpec: 82 def __init__(self, name): 83 self.name = name 84spec = DummyModuleSpec("errno") 85result = _imp.create_builtin(spec) 86)") 87 .isError()); 88 HandleScope scope(thread_); 89 Object result(&scope, mainModuleAt(runtime_, "result")); 90 ASSERT_TRUE(result.isModule()); 91 EXPECT_TRUE(isStrEqualsCStr(Module::cast(*result).name(), "errno")); 92} 93 94TEST_F(ImportBuiltinsTest, CreateBuiltinWithExArgsReturnsModule) { 95 // Mock of importlib._bootstrap.ModuleSpec 96 ASSERT_FALSE(runFromCStr(runtime_, R"( 97import _imp 98class DummyModuleSpec: 99 def __init__(self, name): 100 self.name = name 101spec = (DummyModuleSpec("errno"),) 102result = _imp.create_builtin(*spec) 103)") 104 .isError()); 105 HandleScope scope(thread_); 106 Object result(&scope, mainModuleAt(runtime_, "result")); 107 ASSERT_TRUE(result.isModule()); 108 EXPECT_TRUE(isStrEqualsCStr(Module::cast(*result).name(), "errno")); 109} 110 111TEST_F(ImportBuiltinsTest, ExecBuiltinWithNonModuleReturnsZero) { 112 HandleScope scope(thread_); 113 Int not_mod(&scope, runtime_->newInt(1)); 114 Object a(&scope, runBuiltin(FUNC(_imp, exec_builtin), not_mod)); 115 EXPECT_TRUE(isIntEqualsWord(*a, 0)); 116} 117 118TEST_F(ImportBuiltinsTest, ExecBuiltinWithModuleWithNoDefReturnsZero) { 119 ASSERT_FALSE(runFromCStr(runtime_, R"( 120class DummyModuleSpec(): 121 def __init__(self, name): 122 self.name = name 123spec = DummyModuleSpec("errno") 124)") 125 .isError()); 126 HandleScope scope(thread_); 127 Object spec(&scope, mainModuleAt(runtime_, "spec")); 128 Object module(&scope, runBuiltin(FUNC(_imp, create_builtin), spec)); 129 ASSERT_TRUE(module.isModule()); 130 131 Object a(&scope, runBuiltin(FUNC(_imp, exec_builtin), module)); 132 EXPECT_TRUE(isIntEqualsWord(*a, 0)); 133} 134 135TEST_F(ImportBuiltinsTest, ExecBuiltinWithSingleSlotExecutesCorrectly) { 136 using slot_func = int (*)(Module*); 137 slot_func mod_exec = [](Module* module) { 138 module->setName(Thread::current()->runtime()->newStrFromCStr("testing")); 139 return 0; 140 }; 141 142 static PyModuleDef_Slot slots[] = { 143 {Py_mod_exec, reinterpret_cast<void*>(mod_exec)}, 144 {0, nullptr}, 145 }; 146 static PyModuleDef def = { 147 // Empty header to mimic a PyModuleDef_HEAD_INIT 148 {{0, 0}, nullptr, 0, nullptr}, "mymodule", nullptr, 0, nullptr, slots, 149 }; 150 151 HandleScope scope(thread_); 152 Str name(&scope, runtime_->newStrFromCStr("mymodule")); 153 Module module(&scope, runtime_->newModule(name)); 154 module.setDef(runtime_->newIntFromCPtr(&def)); 155 156 Object a(&scope, runBuiltin(FUNC(_imp, exec_builtin), module)); 157 EXPECT_TRUE(isIntEqualsWord(*a, 0)); 158 159 Str mod_name(&scope, module.name()); 160 EXPECT_TRUE(mod_name.equalsCStr("testing")); 161} 162 163TEST_F(ImportBuiltinsTest, ExecDynamic) { 164 ASSERT_FALSE(runFromCStr(runtime_, R"( 165import _imp 166mod = _imp.exec_dynamic("foo") 167 )") 168 .isError()); 169 HandleScope scope(thread_); 170 Object mod(&scope, mainModuleAt(runtime_, "mod")); 171 ASSERT_TRUE(mod.isNoneType()); 172} 173 174TEST_F(ImportBuiltinsTest, IsBuiltinReturnsZero) { 175 HandleScope scope(thread_); 176 Object module_name(&scope, runtime_->newStrFromCStr("foo")); 177 Object result(&scope, runBuiltin(FUNC(_imp, is_builtin), module_name)); 178 EXPECT_TRUE(isIntEqualsWord(*result, 0)); 179} 180 181TEST_F(ImportBuiltinsTest, IsBuiltinReturnsOne) { 182 HandleScope scope(thread_); 183 Object module_name(&scope, runtime_->newStrFromCStr("errno")); 184 Object result(&scope, runBuiltin(FUNC(_imp, is_builtin), module_name)); 185 EXPECT_TRUE(isIntEqualsWord(*result, 1)); 186} 187 188TEST_F(ImportBuiltinsTest, IsBuiltinWithFrozenPackageReturnsZero) { 189 HandleScope scope(thread_); 190 Object module_name(&scope, runtime_->newStrFromCStr("compiler")); 191 Object result(&scope, runBuiltin(FUNC(_imp, is_builtin), module_name)); 192 EXPECT_TRUE(isIntEqualsWord(*result, 0)); 193} 194 195TEST_F(ImportBuiltinsTest, IsFrozenWithFrozenModuleReturnsTrue) { 196 HandleScope scope(thread_); 197 Object module_name(&scope, runtime_->newStrFromCStr("zipimport")); 198 Object result(&scope, runBuiltin(FUNC(_imp, is_frozen), module_name)); 199 ASSERT_TRUE(result.isBool()); 200 EXPECT_TRUE(Bool::cast(*result).value()); 201} 202 203TEST_F(ImportBuiltinsTest, IsFrozenWithNewModuleReturnsFalse) { 204 HandleScope scope(thread_); 205 Object module_name(&scope, runtime_->newStrFromCStr("foo")); 206 Object result(&scope, runBuiltin(FUNC(_imp, is_frozen), module_name)); 207 ASSERT_TRUE(result.isBool()); 208 EXPECT_FALSE(Bool::cast(*result).value()); 209} 210 211TEST_F(ImportBuiltinsTest, IsFrozenPackageWithNotFrozenModuleReturnsFalse) { 212 HandleScope scope(thread_); 213 Object module_name(&scope, runtime_->newStrFromCStr("foo")); 214 Object result(&scope, runBuiltin(FUNC(_imp, is_frozen_package), module_name)); 215 ASSERT_TRUE(result.isBool()); 216 EXPECT_FALSE(Bool::cast(*result).value()); 217} 218 219TEST_F(ImportBuiltinsTest, 220 IsFrozenPackageWithFrozenModuleNotAPackageReturnsFalse) { 221 HandleScope scope(thread_); 222 Object module_name(&scope, runtime_->newStrFromCStr("array")); 223 Object result(&scope, runBuiltin(FUNC(_imp, is_frozen_package), module_name)); 224 ASSERT_TRUE(result.isBool()); 225 EXPECT_FALSE(Bool::cast(*result).value()); 226} 227 228TEST_F(ImportBuiltinsTest, IsFrozenPackageWithFrozenPackageReturnsTrue) { 229 HandleScope scope(thread_); 230 Object module_name(&scope, runtime_->newStrFromCStr("compiler")); 231 Object result(&scope, runBuiltin(FUNC(_imp, is_frozen_package), module_name)); 232 ASSERT_TRUE(result.isBool()); 233 EXPECT_TRUE(Bool::cast(*result).value()); 234} 235 236TEST_F(ImportBuiltinsTest, GetFrozenObjectWithNonStrRaisesTypeError) { 237 HandleScope scope(thread_); 238 Object non_str(&scope, runtime_->newInt(5)); 239 EXPECT_TRUE(raisedWithStr(runBuiltin(FUNC(_imp, get_frozen_object), non_str), 240 LayoutId::kTypeError, 241 "get_frozen_object requires a str object")); 242} 243 244TEST_F(ImportBuiltinsTest, 245 GetFrozenObjectWithNonFrozenModuleRaisesImportError) { 246 HandleScope scope(thread_); 247 Object module_name(&scope, runtime_->newStrFromCStr("nonexistent")); 248 EXPECT_TRUE(raisedWithStr( 249 runBuiltin(FUNC(_imp, get_frozen_object), module_name), 250 LayoutId::kImportError, "No such frozen object named 'nonexistent'")); 251} 252 253TEST_F(ImportBuiltinsTest, GetFrozenObjectWithFrozenModuleReturnsCode) { 254 HandleScope scope(thread_); 255 Object module_name(&scope, runtime_->newStrFromCStr("zipimport")); 256 Object result(&scope, runBuiltin(FUNC(_imp, get_frozen_object), module_name)); 257 ASSERT_TRUE(result.isCode()); 258} 259 260TEST_F(ImportBuiltinsTest, LockHeldReturnsFalseInitially) { 261 EXPECT_EQ(runBuiltin(FUNC(_imp, lock_held)), Bool::falseObj()); 262} 263 264TEST_F(ImportBuiltinsTest, LockHeldReturnsTrueAfterAcquireLock) { 265 ASSERT_EQ(runBuiltin(FUNC(_imp, acquire_lock)), NoneType::object()); 266 EXPECT_EQ(runBuiltin(FUNC(_imp, lock_held)), Bool::trueObj()); 267 ASSERT_EQ(runBuiltin(FUNC(_imp, release_lock)), NoneType::object()); 268} 269 270TEST_F(ImportBuiltinsTest, LockHeldReturnsFalseAfterReleaseLock) { 271 ASSERT_EQ(runBuiltin(FUNC(_imp, acquire_lock)), NoneType::object()); 272 ASSERT_EQ(runBuiltin(FUNC(_imp, lock_held)), Bool::trueObj()); 273 ASSERT_EQ(runBuiltin(FUNC(_imp, release_lock)), NoneType::object()); 274 EXPECT_EQ(runBuiltin(FUNC(_imp, lock_held)), Bool::falseObj()); 275} 276 277TEST_F(ImportBuiltinsTest, ReleaseLockWithoutAcquireRaisesRuntimeError) { 278 HandleScope scope(thread_); 279 Object result(&scope, runBuiltin(FUNC(_imp, release_lock))); 280 EXPECT_TRUE(raised(*result, LayoutId::kRuntimeError)); 281} 282 283TEST_F(ImportBuiltinsTest, AcquireLockCheckRecursiveCallsWorks) { 284 HandleScope scope(thread_); 285 runBuiltin(FUNC(_imp, acquire_lock)); 286 runBuiltin(FUNC(_imp, acquire_lock)); 287 runBuiltin(FUNC(_imp, release_lock)); 288 runBuiltin(FUNC(_imp, release_lock)); 289 // Make sure that additional releases raise. 290 Object result(&scope, runBuiltin(FUNC(_imp, release_lock))); 291 EXPECT_TRUE(result.isError()); 292} 293 294TEST_F(ImportBuiltinsTest, CreateExistingBuiltinDoesNotOverride) { 295 // Mock of importlib._bootstrap.ModuleSpec 296 ASSERT_FALSE(runFromCStr(runtime_, R"( 297import _imp 298class DummyModuleSpec: 299 def __init__(self, name): 300 self.name = name 301spec = (DummyModuleSpec("errno"),) 302result1 = _imp.create_builtin(*spec) 303result2 = _imp.create_builtin(*spec) 304)") 305 .isError()); 306 HandleScope scope(thread_); 307 Object result1(&scope, mainModuleAt(runtime_, "result1")); 308 ASSERT_TRUE(result1.isModule()); 309 EXPECT_TRUE(isStrEqualsCStr(Module::cast(*result1).name(), "errno")); 310 Object result2(&scope, mainModuleAt(runtime_, "result2")); 311 ASSERT_TRUE(result2.isModule()); 312 EXPECT_TRUE(isStrEqualsCStr(Module::cast(*result2).name(), "errno")); 313 EXPECT_EQ(*result1, *result2); 314} 315 316} // namespace testing 317} // namespace py