]>
Commit | Line | Data |
---|---|---|
f67539c2 TL |
1 | #include <gtest/gtest.h> |
2 | #include "common/ceph_context.h" | |
3 | #include "rgw/rgw_common.h" | |
20effc67 | 4 | #include "rgw/rgw_auth.h" |
f67539c2 TL |
5 | #include "rgw/rgw_process.h" |
6 | #include "rgw/rgw_sal_rados.h" | |
7 | #include "rgw/rgw_lua_request.h" | |
8 | ||
20effc67 | 9 | using namespace std; |
f67539c2 | 10 | using namespace rgw; |
20effc67 TL |
11 | using boost::container::flat_set; |
12 | using rgw::auth::Identity; | |
13 | using rgw::auth::Principal; | |
f67539c2 TL |
14 | |
15 | class CctCleaner { | |
16 | CephContext* cct; | |
17 | public: | |
18 | CctCleaner(CephContext* _cct) : cct(_cct) {} | |
19 | ~CctCleaner() { | |
20 | #ifdef WITH_SEASTAR | |
21 | delete cct; | |
22 | #else | |
23 | cct->put(); | |
24 | #endif | |
25 | } | |
26 | }; | |
27 | ||
20effc67 | 28 | class FakeIdentity : public Identity { |
f67539c2 | 29 | public: |
20effc67 TL |
30 | FakeIdentity() = default; |
31 | ||
32 | uint32_t get_perms_from_aclspec(const DoutPrefixProvider* dpp, const aclspec_t& aclspec) const override { | |
33 | return 0; | |
34 | }; | |
35 | ||
36 | bool is_admin_of(const rgw_user& uid) const override { | |
37 | return false; | |
38 | } | |
39 | ||
40 | bool is_owner_of(const rgw_user& uid) const override { | |
41 | return false; | |
42 | } | |
43 | ||
44 | virtual uint32_t get_perm_mask() const override { | |
45 | return 0; | |
46 | } | |
47 | ||
48 | uint32_t get_identity_type() const override { | |
49 | return TYPE_RGW; | |
50 | } | |
51 | ||
52 | string get_acct_name() const override { | |
53 | return ""; | |
54 | } | |
55 | ||
56 | string get_subuser() const override { | |
57 | return ""; | |
58 | } | |
59 | ||
60 | void to_str(std::ostream& out) const override { | |
61 | return; | |
62 | } | |
63 | ||
64 | bool is_identity(const flat_set<Principal>& ids) const override { | |
65 | return false; | |
66 | } | |
67 | }; | |
68 | ||
69 | class TestUser : public sal::User { | |
70 | public: | |
71 | virtual std::unique_ptr<User> clone() override { | |
72 | return std::unique_ptr<User>(new TestUser(*this)); | |
73 | } | |
74 | ||
75 | virtual int list_buckets(const DoutPrefixProvider *dpp, const string&, const string&, uint64_t, bool, sal::BucketList&, optional_yield y) override { | |
76 | return 0; | |
77 | } | |
78 | ||
79 | virtual int create_bucket(const DoutPrefixProvider* dpp, const rgw_bucket& b, const std::string& zonegroup_id, rgw_placement_rule& placement_rule, std::string& swift_ver_location, const RGWQuotaInfo* pquota_info, const RGWAccessControlPolicy& policy, sal::Attrs& attrs, RGWBucketInfo& info, obj_version& ep_objv, bool exclusive, bool obj_lock_enabled, bool* existed, req_info& req_info, std::unique_ptr<sal::Bucket>* bucket, optional_yield y) override { | |
80 | return 0; | |
81 | } | |
82 | ||
83 | virtual int read_attrs(const DoutPrefixProvider *dpp, optional_yield y) override { | |
84 | return 0; | |
85 | } | |
86 | ||
87 | virtual int read_stats(const DoutPrefixProvider *dpp, optional_yield y, RGWStorageStats* stats, ceph::real_time *last_stats_sync, ceph::real_time *last_stats_update) override { | |
88 | return 0; | |
89 | } | |
90 | ||
91 | virtual int read_stats_async(const DoutPrefixProvider *dpp, RGWGetUserStats_CB *cb) override { | |
92 | return 0; | |
93 | } | |
94 | ||
95 | virtual int complete_flush_stats(const DoutPrefixProvider *dpp, optional_yield y) override { | |
f67539c2 TL |
96 | return 0; |
97 | } | |
98 | ||
20effc67 TL |
99 | virtual int read_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch, uint64_t end_epoch, uint32_t max_entries, bool *is_truncated, RGWUsageIter& usage_iter, map<rgw_user_bucket, rgw_usage_log_entry>& usage) override { |
100 | return 0; | |
101 | } | |
102 | ||
103 | virtual int trim_usage(const DoutPrefixProvider *dpp, uint64_t start_epoch, uint64_t end_epoch) override { | |
104 | return 0; | |
f67539c2 TL |
105 | } |
106 | ||
20effc67 | 107 | virtual int load_user(const DoutPrefixProvider *dpp, optional_yield y) override { |
f67539c2 TL |
108 | return 0; |
109 | } | |
110 | ||
20effc67 TL |
111 | virtual int store_user(const DoutPrefixProvider* dpp, optional_yield y, bool exclusive, RGWUserInfo* old_info) override { |
112 | return 0; | |
113 | } | |
114 | ||
115 | virtual int remove_user(const DoutPrefixProvider* dpp, optional_yield y) override { | |
116 | return 0; | |
117 | } | |
118 | virtual int merge_and_store_attrs(const DoutPrefixProvider *dpp, rgw::sal::Attrs& attrs, optional_yield y) override { | |
119 | return 0; | |
120 | } | |
121 | virtual ~TestUser() = default; | |
f67539c2 TL |
122 | }; |
123 | ||
124 | class TestAccounter : public io::Accounter, public io::BasicClient { | |
125 | RGWEnv env; | |
126 | ||
127 | protected: | |
128 | virtual int init_env(CephContext *cct) override { | |
129 | return 0; | |
130 | } | |
131 | ||
132 | public: | |
133 | ~TestAccounter() = default; | |
134 | ||
135 | virtual void set_account(bool enabled) override { | |
136 | } | |
137 | ||
138 | virtual uint64_t get_bytes_sent() const override { | |
139 | return 0; | |
140 | } | |
141 | ||
142 | virtual uint64_t get_bytes_received() const override { | |
143 | return 0; | |
144 | } | |
145 | ||
146 | virtual RGWEnv& get_env() noexcept override { | |
147 | return env; | |
148 | } | |
149 | ||
150 | virtual size_t complete_request() override { | |
151 | return 0; | |
152 | } | |
153 | }; | |
154 | ||
155 | auto cct = new CephContext(CEPH_ENTITY_TYPE_CLIENT); | |
156 | ||
157 | CctCleaner cleaner(cct); | |
158 | ||
159 | TEST(TestRGWLua, EmptyScript) | |
160 | { | |
161 | const std::string script; | |
162 | ||
163 | RGWEnv e; | |
164 | uint64_t id = 0; | |
165 | req_state s(cct, &e, id); | |
166 | ||
39ae355f | 167 | const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, script); |
f67539c2 TL |
168 | ASSERT_EQ(rc, 0); |
169 | } | |
170 | ||
171 | #define DEFINE_REQ_STATE RGWEnv e; req_state s(cct, &e, 0); | |
172 | ||
173 | TEST(TestRGWLua, SyntaxError) | |
174 | { | |
175 | const std::string script = R"( | |
176 | if 3 < 5 then | |
177 | RGWDebugLog("missing 'end'") | |
178 | )"; | |
179 | ||
180 | DEFINE_REQ_STATE; | |
181 | ||
39ae355f | 182 | const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, script); |
f67539c2 TL |
183 | ASSERT_EQ(rc, -1); |
184 | } | |
185 | ||
186 | TEST(TestRGWLua, Hello) | |
187 | { | |
188 | const std::string script = R"( | |
189 | RGWDebugLog("hello from lua") | |
190 | )"; | |
191 | ||
192 | DEFINE_REQ_STATE; | |
193 | ||
39ae355f | 194 | const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, script); |
f67539c2 TL |
195 | ASSERT_EQ(rc, 0); |
196 | } | |
197 | ||
198 | TEST(TestRGWLua, RGWDebugLogNumber) | |
199 | { | |
200 | const std::string script = R"( | |
201 | RGWDebugLog(1234567890) | |
202 | )"; | |
203 | ||
204 | DEFINE_REQ_STATE; | |
205 | ||
39ae355f | 206 | const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, script); |
f67539c2 TL |
207 | ASSERT_EQ(rc, 0); |
208 | } | |
209 | ||
210 | TEST(TestRGWLua, RGWDebugNil) | |
211 | { | |
212 | const std::string script = R"( | |
213 | RGWDebugLog(nil) | |
214 | )"; | |
215 | ||
216 | DEFINE_REQ_STATE; | |
217 | ||
39ae355f | 218 | const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, script); |
f67539c2 TL |
219 | ASSERT_EQ(rc, -1); |
220 | } | |
221 | ||
222 | TEST(TestRGWLua, URI) | |
223 | { | |
224 | const std::string script = R"( | |
225 | RGWDebugLog(Request.DecodedURI) | |
226 | assert(Request.DecodedURI == "http://hello.world/") | |
227 | )"; | |
228 | ||
229 | DEFINE_REQ_STATE; | |
230 | s.decoded_uri = "http://hello.world/"; | |
231 | ||
39ae355f | 232 | const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, script); |
f67539c2 TL |
233 | ASSERT_EQ(rc, 0); |
234 | } | |
235 | ||
236 | TEST(TestRGWLua, Response) | |
237 | { | |
238 | const std::string script = R"( | |
239 | assert(Request.Response.Message == "This is a bad request") | |
240 | assert(Request.Response.HTTPStatus == "Bad Request") | |
241 | assert(Request.Response.RGWCode == 4000) | |
242 | assert(Request.Response.HTTPStatusCode == 400) | |
243 | )"; | |
244 | ||
245 | DEFINE_REQ_STATE; | |
246 | s.err.http_ret = 400; | |
247 | s.err.ret = 4000; | |
248 | s.err.err_code = "Bad Request"; | |
249 | s.err.message = "This is a bad request"; | |
250 | ||
39ae355f | 251 | const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, script); |
f67539c2 TL |
252 | ASSERT_EQ(rc, 0); |
253 | } | |
254 | ||
255 | TEST(TestRGWLua, SetResponse) | |
256 | { | |
257 | const std::string script = R"( | |
258 | assert(Request.Response.Message == "this is a bad request") | |
259 | Request.Response.Message = "this is a good request" | |
260 | assert(Request.Response.Message == "this is a good request") | |
261 | )"; | |
262 | ||
263 | DEFINE_REQ_STATE; | |
264 | s.err.message = "this is a bad request"; | |
265 | ||
39ae355f | 266 | const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, script); |
f67539c2 TL |
267 | ASSERT_EQ(rc, 0); |
268 | } | |
269 | ||
270 | TEST(TestRGWLua, SetRGWId) | |
271 | { | |
272 | const std::string script = R"( | |
273 | assert(Request.RGWId == "foo") | |
274 | Request.RGWId = "bar" | |
275 | )"; | |
276 | ||
277 | DEFINE_REQ_STATE; | |
278 | s.host_id = "foo"; | |
279 | ||
39ae355f | 280 | const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, script); |
f67539c2 TL |
281 | ASSERT_NE(rc, 0); |
282 | } | |
283 | ||
284 | TEST(TestRGWLua, InvalidField) | |
285 | { | |
286 | const std::string script = R"( | |
287 | RGWDebugLog(Request.Kaboom) | |
288 | )"; | |
289 | ||
290 | DEFINE_REQ_STATE; | |
291 | s.host_id = "foo"; | |
292 | ||
39ae355f | 293 | const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, script); |
f67539c2 TL |
294 | ASSERT_EQ(rc, -1); |
295 | } | |
296 | ||
297 | TEST(TestRGWLua, InvalidSubField) | |
298 | { | |
299 | const std::string script = R"( | |
300 | RGWDebugLog(Request.Error.Kaboom) | |
301 | )"; | |
302 | ||
303 | DEFINE_REQ_STATE; | |
304 | ||
39ae355f | 305 | const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, script); |
f67539c2 TL |
306 | ASSERT_EQ(rc, -1); |
307 | } | |
308 | ||
309 | TEST(TestRGWLua, Bucket) | |
310 | { | |
311 | const std::string script = R"( | |
312 | assert(Request.Bucket) | |
313 | RGWDebugLog("Bucket Id: " .. Request.Bucket.Id) | |
314 | assert(Request.Bucket.Marker == "mymarker") | |
315 | assert(Request.Bucket.Name == "myname") | |
316 | assert(Request.Bucket.Tenant == "mytenant") | |
317 | assert(Request.Bucket.Count == 0) | |
318 | assert(Request.Bucket.Size == 0) | |
319 | assert(Request.Bucket.ZoneGroupId) | |
320 | assert(Request.Bucket.CreationTime) | |
321 | assert(Request.Bucket.MTime) | |
322 | assert(Request.Bucket.Quota.MaxSize == -1) | |
323 | assert(Request.Bucket.Quota.MaxObjects == -1) | |
324 | assert(tostring(Request.Bucket.Quota.Enabled)) | |
325 | assert(tostring(Request.Bucket.Quota.Rounded)) | |
326 | assert(Request.Bucket.User.Id) | |
327 | assert(Request.Bucket.User.Tenant) | |
328 | )"; | |
329 | ||
330 | DEFINE_REQ_STATE; | |
331 | ||
332 | rgw_bucket b; | |
333 | b.tenant = "mytenant"; | |
334 | b.name = "myname"; | |
335 | b.marker = "mymarker"; | |
336 | b.bucket_id = "myid"; | |
20effc67 | 337 | s.bucket.reset(new sal::RadosBucket(nullptr, b)); |
f67539c2 | 338 | |
39ae355f | 339 | const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, script); |
f67539c2 TL |
340 | ASSERT_EQ(rc, 0); |
341 | } | |
342 | ||
343 | TEST(TestRGWLua, GenericAttributes) | |
344 | { | |
345 | const std::string script = R"( | |
346 | assert(Request.GenericAttributes["hello"] == "world") | |
347 | assert(Request.GenericAttributes["foo"] == "bar") | |
348 | assert(Request.GenericAttributes["kaboom"] == nil) | |
349 | assert(#Request.GenericAttributes == 4) | |
350 | for k, v in pairs(Request.GenericAttributes) do | |
351 | assert(k) | |
352 | assert(v) | |
353 | end | |
354 | )"; | |
355 | ||
356 | DEFINE_REQ_STATE; | |
357 | s.generic_attrs["hello"] = "world"; | |
358 | s.generic_attrs["foo"] = "bar"; | |
359 | s.generic_attrs["goodbye"] = "cruel world"; | |
360 | s.generic_attrs["ka"] = "boom"; | |
361 | ||
39ae355f | 362 | const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, script); |
f67539c2 TL |
363 | ASSERT_EQ(rc, 0); |
364 | } | |
365 | ||
366 | TEST(TestRGWLua, Environment) | |
367 | { | |
368 | const std::string script = R"( | |
369 | assert(Request.Environment[""] == "bar") | |
370 | assert(Request.Environment["goodbye"] == "cruel world") | |
371 | assert(Request.Environment["ka"] == "boom") | |
372 | assert(#Request.Environment == 3, #Request.Environment) | |
373 | for k, v in pairs(Request.Environment) do | |
374 | assert(k) | |
375 | assert(v) | |
376 | end | |
377 | )"; | |
378 | ||
379 | DEFINE_REQ_STATE; | |
20effc67 TL |
380 | s.env.emplace("", "bar"); |
381 | s.env.emplace("goodbye", "cruel world"); | |
382 | s.env.emplace("ka", "boom"); | |
f67539c2 | 383 | |
39ae355f | 384 | const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, script); |
f67539c2 TL |
385 | ASSERT_EQ(rc, 0); |
386 | } | |
387 | ||
388 | TEST(TestRGWLua, Tags) | |
389 | { | |
390 | const std::string script = R"( | |
391 | assert(#Request.Tags == 4) | |
392 | assert(Request.Tags["foo"] == "bar") | |
393 | for k, v in pairs(Request.Tags) do | |
394 | assert(k) | |
395 | assert(v) | |
396 | end | |
397 | )"; | |
398 | ||
399 | DEFINE_REQ_STATE; | |
400 | s.tagset.add_tag("hello", "world"); | |
401 | s.tagset.add_tag("foo", "bar"); | |
402 | s.tagset.add_tag("goodbye", "cruel world"); | |
403 | s.tagset.add_tag("ka", "boom"); | |
404 | ||
39ae355f | 405 | const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, script); |
f67539c2 TL |
406 | ASSERT_EQ(rc, 0); |
407 | } | |
408 | ||
409 | TEST(TestRGWLua, TagsNotWriteable) | |
410 | { | |
411 | const std::string script = R"( | |
412 | Request.Tags["hello"] = "goodbye" | |
413 | )"; | |
414 | ||
415 | DEFINE_REQ_STATE; | |
416 | s.tagset.add_tag("hello", "world"); | |
417 | ||
39ae355f | 418 | const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, script); |
f67539c2 TL |
419 | ASSERT_NE(rc, 0); |
420 | } | |
421 | ||
422 | TEST(TestRGWLua, Metadata) | |
423 | { | |
424 | const std::string script = R"( | |
425 | assert(#Request.HTTP.Metadata == 3) | |
426 | for k, v in pairs(Request.HTTP.Metadata) do | |
427 | assert(k) | |
428 | assert(v) | |
429 | end | |
430 | assert(Request.HTTP.Metadata["hello"] == "world") | |
431 | assert(Request.HTTP.Metadata["kaboom"] == nil) | |
432 | Request.HTTP.Metadata["hello"] = "goodbye" | |
433 | Request.HTTP.Metadata["kaboom"] = "boom" | |
434 | assert(#Request.HTTP.Metadata == 4) | |
435 | assert(Request.HTTP.Metadata["hello"] == "goodbye") | |
436 | assert(Request.HTTP.Metadata["kaboom"] == "boom") | |
437 | )"; | |
438 | ||
439 | DEFINE_REQ_STATE; | |
440 | s.info.x_meta_map["hello"] = "world"; | |
441 | s.info.x_meta_map["foo"] = "bar"; | |
442 | s.info.x_meta_map["ka"] = "boom"; | |
443 | ||
39ae355f | 444 | const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, script); |
f67539c2 TL |
445 | ASSERT_EQ(rc, 0); |
446 | } | |
447 | ||
448 | TEST(TestRGWLua, Acl) | |
449 | { | |
450 | const std::string script = R"( | |
451 | function print_grant(g) | |
452 | print("Grant Type: " .. g.Type) | |
453 | print("Grant Group Type: " .. g.GroupType) | |
454 | print("Grant Referer: " .. g.Referer) | |
455 | if (g.User) then | |
456 | print("Grant User.Tenant: " .. g.User.Tenant) | |
457 | print("Grant User.Id: " .. g.User.Id) | |
458 | end | |
459 | end | |
460 | ||
461 | assert(Request.UserAcl.Owner.DisplayName == "jack black", Request.UserAcl.Owner.DisplayName) | |
462 | assert(Request.UserAcl.Owner.User.Id == "black", Request.UserAcl.Owner.User.Id) | |
463 | assert(Request.UserAcl.Owner.User.Tenant == "jack", Request.UserAcl.Owner.User.Tenant) | |
464 | assert(#Request.UserAcl.Grants == 5) | |
465 | print_grant(Request.UserAcl.Grants[""]) | |
466 | for k, v in pairs(Request.UserAcl.Grants) do | |
467 | print_grant(v) | |
468 | if k == "john$doe" then | |
469 | assert(v.Permission == 4) | |
470 | elseif k == "jane$doe" then | |
471 | assert(v.Permission == 1) | |
472 | else | |
473 | assert(false) | |
474 | end | |
475 | end | |
476 | )"; | |
477 | ||
478 | DEFINE_REQ_STATE; | |
479 | ACLOwner owner; | |
480 | owner.set_id(rgw_user("jack", "black")); | |
481 | owner.set_name("jack black"); | |
482 | s.user_acl.reset(new RGWAccessControlPolicy(cct)); | |
483 | s.user_acl->set_owner(owner); | |
484 | ACLGrant grant1, grant2, grant3, grant4, grant5; | |
485 | grant1.set_canon(rgw_user("jane", "doe"), "her grant", 1); | |
486 | grant2.set_group(ACL_GROUP_ALL_USERS ,2); | |
487 | grant3.set_referer("http://localhost/ref2", 3); | |
488 | grant4.set_canon(rgw_user("john", "doe"), "his grant", 4); | |
489 | grant5.set_group(ACL_GROUP_AUTHENTICATED_USERS, 5); | |
490 | s.user_acl->get_acl().add_grant(&grant1); | |
491 | s.user_acl->get_acl().add_grant(&grant2); | |
492 | s.user_acl->get_acl().add_grant(&grant3); | |
493 | s.user_acl->get_acl().add_grant(&grant4); | |
494 | s.user_acl->get_acl().add_grant(&grant5); | |
39ae355f | 495 | const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, script); |
f67539c2 TL |
496 | ASSERT_EQ(rc, 0); |
497 | } | |
498 | ||
20effc67 TL |
499 | TEST(TestRGWLua, User) |
500 | { | |
501 | const std::string script = R"( | |
502 | assert(Request.User) | |
503 | assert(Request.User.Id == "myid") | |
504 | assert(Request.User.Tenant == "mytenant") | |
505 | )"; | |
506 | ||
507 | DEFINE_REQ_STATE; | |
508 | ||
509 | rgw_user u; | |
510 | u.tenant = "mytenant"; | |
511 | u.id = "myid"; | |
512 | s.user.reset(new sal::RadosUser(nullptr, u)); | |
513 | ||
39ae355f | 514 | const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, script); |
20effc67 TL |
515 | ASSERT_EQ(rc, 0); |
516 | } | |
517 | ||
518 | ||
f67539c2 TL |
519 | TEST(TestRGWLua, UseFunction) |
520 | { | |
521 | const std::string script = R"( | |
522 | function print_owner(owner) | |
523 | print("Owner Dispaly Name: " .. owner.DisplayName) | |
524 | print("Owner Id: " .. owner.User.Id) | |
525 | print("Owner Tenanet: " .. owner.User.Tenant) | |
526 | end | |
527 | ||
528 | print_owner(Request.ObjectOwner) | |
529 | ||
530 | function print_acl(acl_type) | |
531 | index = acl_type .. "ACL" | |
532 | acl = Request[index] | |
533 | if acl then | |
534 | print(acl_type .. "ACL Owner") | |
535 | print_owner(acl.Owner) | |
536 | else | |
537 | print("no " .. acl_type .. " ACL in request: " .. Request.Id) | |
538 | end | |
539 | end | |
540 | ||
541 | print_acl("User") | |
542 | print_acl("Bucket") | |
543 | print_acl("Object") | |
544 | )"; | |
545 | ||
546 | DEFINE_REQ_STATE; | |
547 | s.owner.set_name("user two"); | |
548 | s.owner.set_id(rgw_user("tenant2", "user2")); | |
549 | s.user_acl.reset(new RGWAccessControlPolicy()); | |
550 | s.user_acl->get_owner().set_name("user three"); | |
551 | s.user_acl->get_owner().set_id(rgw_user("tenant3", "user3")); | |
552 | s.bucket_acl.reset(new RGWAccessControlPolicy()); | |
553 | s.bucket_acl->get_owner().set_name("user four"); | |
554 | s.bucket_acl->get_owner().set_id(rgw_user("tenant4", "user4")); | |
555 | s.object_acl.reset(new RGWAccessControlPolicy()); | |
556 | s.object_acl->get_owner().set_name("user five"); | |
557 | s.object_acl->get_owner().set_id(rgw_user("tenant5", "user5")); | |
558 | ||
39ae355f | 559 | const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, script); |
f67539c2 TL |
560 | ASSERT_EQ(rc, 0); |
561 | } | |
562 | ||
563 | TEST(TestRGWLua, WithLib) | |
564 | { | |
565 | const std::string script = R"( | |
566 | expected_result = {"my", "bucket", "name", "is", "fish"} | |
567 | i = 1 | |
568 | for p in string.gmatch(Request.Bucket.Name, "%a+") do | |
569 | assert(p == expected_result[i]) | |
570 | i = i + 1 | |
571 | end | |
572 | )"; | |
573 | ||
574 | DEFINE_REQ_STATE; | |
575 | ||
576 | rgw_bucket b; | |
577 | b.name = "my-bucket-name-is-fish"; | |
20effc67 | 578 | s.bucket.reset(new sal::RadosBucket(nullptr, b)); |
f67539c2 | 579 | |
39ae355f | 580 | const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, script); |
f67539c2 TL |
581 | ASSERT_EQ(rc, 0); |
582 | } | |
583 | ||
584 | TEST(TestRGWLua, NotAllowedInLib) | |
585 | { | |
586 | const std::string script = R"( | |
587 | os.clock() -- this should be ok | |
588 | os.exit() -- this should fail (os.exit() is removed) | |
589 | )"; | |
590 | ||
591 | DEFINE_REQ_STATE; | |
592 | ||
39ae355f | 593 | const auto rc = lua::request::execute(nullptr, nullptr, nullptr, &s, nullptr, script); |
f67539c2 TL |
594 | ASSERT_NE(rc, 0); |
595 | } | |
596 | #include <sys/socket.h> | |
597 | #include <stdlib.h> | |
598 | ||
599 | bool unix_socket_client_ended_ok = false; | |
600 | ||
601 | void unix_socket_client(const std::string& path) { | |
602 | int fd; | |
603 | // create the socket | |
604 | if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { | |
605 | std::cout << "unix socket error: " << errno << std::endl; | |
606 | return; | |
607 | } | |
608 | // set the path | |
609 | struct sockaddr_un addr; | |
610 | memset(&addr, 0, sizeof(addr)); | |
611 | addr.sun_family = AF_UNIX; | |
612 | strncpy(addr.sun_path, path.c_str(), sizeof(addr.sun_path)-1); | |
613 | ||
614 | // let the socket be created by the "rgw" side | |
615 | std::this_thread::sleep_for(std::chrono::seconds(2)); | |
616 | if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) { | |
617 | std::cout << "unix socket connect error: " << errno << std::endl; | |
618 | return; | |
619 | } | |
620 | ||
621 | char buff[256]; | |
622 | int rc; | |
623 | while((rc=read(fd, buff, sizeof(buff))) > 0) { | |
624 | std::cout << std::string(buff, rc); | |
625 | unix_socket_client_ended_ok = true; | |
626 | } | |
627 | } | |
628 | ||
629 | TEST(TestRGWLua, OpsLog) | |
630 | { | |
631 | const std::string unix_socket_path = "./aSocket.sock"; | |
632 | unlink(unix_socket_path.c_str()); | |
633 | ||
634 | std::thread unix_socket_thread(unix_socket_client, unix_socket_path); | |
635 | ||
636 | const std::string script = R"( | |
637 | if Request.Response.HTTPStatusCode == 200 then | |
638 | assert(Request.Response.Message == "Life is great") | |
639 | else | |
640 | assert(Request.Bucket) | |
641 | assert(Request.Log() == 0) | |
642 | end | |
643 | )"; | |
644 | ||
20effc67 | 645 | auto store = std::unique_ptr<sal::RadosStore>(new sal::RadosStore); |
f67539c2 TL |
646 | store->setRados(new RGWRados); |
647 | auto olog = std::unique_ptr<OpsLogSocket>(new OpsLogSocket(cct, 1024)); | |
648 | ASSERT_TRUE(olog->init(unix_socket_path)); | |
649 | ||
650 | DEFINE_REQ_STATE; | |
651 | s.err.http_ret = 200; | |
652 | s.err.ret = 0; | |
653 | s.err.err_code = "200OK"; | |
654 | s.err.message = "Life is great"; | |
655 | rgw_bucket b; | |
656 | b.tenant = "tenant"; | |
657 | b.name = "name"; | |
658 | b.marker = "marker"; | |
659 | b.bucket_id = "id"; | |
20effc67 | 660 | s.bucket.reset(new sal::RadosBucket(nullptr, b)); |
f67539c2 TL |
661 | s.bucket_name = "name"; |
662 | s.enable_ops_log = true; | |
663 | s.enable_usage_log = false; | |
20effc67 | 664 | s.user.reset(new TestUser()); |
f67539c2 TL |
665 | TestAccounter ac; |
666 | s.cio = ∾ | |
667 | s.cct->_conf->rgw_ops_log_rados = false; | |
668 | ||
20effc67 TL |
669 | s.auth.identity = std::unique_ptr<rgw::auth::Identity>( |
670 | new FakeIdentity()); | |
671 | ||
39ae355f | 672 | auto rc = lua::request::execute(store.get(), nullptr, olog.get(), &s, nullptr, script); |
f67539c2 TL |
673 | EXPECT_EQ(rc, 0); |
674 | ||
675 | s.err.http_ret = 400; | |
39ae355f | 676 | rc = lua::request::execute(store.get(), nullptr, olog.get(), &s, nullptr, script); |
f67539c2 TL |
677 | EXPECT_EQ(rc, 0); |
678 | ||
679 | // give the socket client time to read | |
680 | std::this_thread::sleep_for(std::chrono::seconds(5)); | |
681 | unix_socket_thread.detach(); // read is stuck there, so we cannot join | |
682 | EXPECT_TRUE(unix_socket_client_ended_ok); | |
683 | } | |
684 |