Skip to content

Commit

Permalink
Merge pull request ceph#5928 from ceph/wip-12819-infernalis
Browse files Browse the repository at this point in the history
Wip 12819 infernalis
  • Loading branch information
oritwas committed Sep 22, 2015
2 parents fb5f058 + d5f8c8e commit f1ead76
Show file tree
Hide file tree
Showing 6 changed files with 240 additions and 7 deletions.
41 changes: 38 additions & 3 deletions src/rgw/rgw_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -940,6 +940,10 @@ struct rgw_obj_key {
set(n, i);
}

rgw_obj_key(const cls_rgw_obj_key& k) {
set(k);
}

void set(const cls_rgw_obj_key& k) {
name = k.name;
instance = k.instance;
Expand Down Expand Up @@ -1191,8 +1195,7 @@ class rgw_obj {
init(b, o);
}
rgw_obj(rgw_bucket& b, const rgw_obj_key& k) : in_extra_data(false) {
init(b, k.name);
set_instance(k.instance);
from_index_key(b, k);
}
void init(rgw_bucket& b, const std::string& o) {
bucket = b;
Expand Down Expand Up @@ -1301,6 +1304,29 @@ class rgw_obj {
return string(buf) + orig_obj;
};

void from_index_key(rgw_bucket& b, const rgw_obj_key& key) {
if (key.name[0] != '_') {
init(b, key.name);
set_instance(key.instance);
return;
}
if (key.name[1] == '_') {
init(b, key.name.substr(1));
set_instance(key.instance);
return;
}
ssize_t pos = key.name.find('_', 1);
if (pos < 0) {
/* shouldn't happen, just use key */
init(b, key.name);
set_instance(key.instance);
return;
}

init_ns(b, key.name.substr(pos + 1), key.name.substr(1, pos -1));
set_instance(key.instance);
}

void get_index_key(rgw_obj_key *key) const {
key->name = get_index_key_name();
key->instance = instance;
Expand Down Expand Up @@ -1391,6 +1417,11 @@ class rgw_obj {
return false;
}

if (obj[1] == '_') {
obj = obj.substr(1);
return true;
}

size_t period_pos = obj.find('.');
if (period_pos < pos) {
return false;
Expand Down Expand Up @@ -1435,7 +1466,11 @@ class rgw_obj {
if (struct_v >= 4)
::decode(instance, bl);
if (ns.empty() && instance.empty()) {
orig_obj = object;
if (object[0] != '_') {
orig_obj = object;
} else {
orig_obj = object.substr(1);
}
} else {
if (struct_v >= 5) {
::decode(orig_obj, bl);
Expand Down
1 change: 1 addition & 0 deletions src/rgw/rgw_json_enc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,7 @@ void rgw_obj::dump(Formatter *f) const
encode_json("ns", ns, f);
encode_json("object", object, f);
encode_json("instance", instance, f);
encode_json("orig_obj", orig_obj, f);
}

void RGWZoneParams::dump(Formatter *f) const
Expand Down
7 changes: 3 additions & 4 deletions src/rgw/rgw_rados.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6831,6 +6831,7 @@ int RGWRados::apply_olh_log(RGWObjectCtx& obj_ctx, RGWObjState& state, RGWBucket
vector<rgw_bucket_olh_log_entry>::iterator viter = iter->second.begin();
for (; viter != iter->second.end(); ++viter) {
rgw_bucket_olh_log_entry& entry = *viter;

ldout(cct, 20) << "olh_log_entry: op=" << (int)entry.op
<< " key=" << entry.key.name << "[" << entry.key.instance << "] "
<< (entry.delete_marker ? "(delete)" : "") << dendl;
Expand Down Expand Up @@ -6866,8 +6867,7 @@ int RGWRados::apply_olh_log(RGWObjectCtx& obj_ctx, RGWObjState& state, RGWBucket
}

if (need_to_link) {
rgw_obj target(bucket, key.name);
target.set_instance(key.instance);
rgw_obj target(bucket, key);
RGWOLHInfo info;
info.target = target;
info.removed = delete_marker;
Expand All @@ -6880,8 +6880,7 @@ int RGWRados::apply_olh_log(RGWObjectCtx& obj_ctx, RGWObjState& state, RGWBucket
for (list<cls_rgw_obj_key>::iterator liter = remove_instances.begin();
liter != remove_instances.end(); ++liter) {
cls_rgw_obj_key& key = *liter;
rgw_obj obj_instance(bucket, key.name);
obj_instance.set_instance(key.instance);
rgw_obj obj_instance(bucket, key);
int ret = delete_obj(obj_ctx, bucket_info, obj_instance, 0, RGW_BILOG_FLAG_VERSIONED_OP);
if (ret < 0 && ret != -ENOENT) {
ldout(cct, 0) << "ERROR: delete_obj() returned " << ret << " obj_instance=" << obj_instance << dendl;
Expand Down
30 changes: 30 additions & 0 deletions src/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1463,6 +1463,36 @@ if(${WITH_RADOSGW})
set_target_properties(test_rgw_manifest PROPERTIES COMPILE_FLAGS
${UNITTEST_CXX_FLAGS})

# test_rgw_obj
set(test_rgw_obj_srcs rgw/test_rgw_obj.cc)
add_executable(test_rgw_obj
${test_rgw_obj_srcs}
$<TARGET_OBJECTS:heap_profiler_objs>
)
target_link_libraries(test_rgw_obj
rgw_a
cls_rgw_client
cls_lock_client
cls_refcount_client
cls_log_client
cls_statelog_client
cls_version_client
cls_replica_log_client
cls_kvs
cls_user_client
librados
global
curl
uuid
expat
${CMAKE_DL_LIBS}
${TCMALLOC_LIBS}
${UNITTEST_LIBS}
${CRYPTO_LIBS}
)
set_target_properties(test_rgw_obj PROPERTIES COMPILE_FLAGS
${UNITTEST_CXX_FLAGS})

# test_cls_rgw_meta
set(test_cls_rgw_meta_srcs test_rgw_admin_meta.cc)
add_executable(test_cls_rgw_meta
Expand Down
9 changes: 9 additions & 0 deletions src/test/Makefile-client.am
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,15 @@ ceph_test_rgw_manifest_LDADD = \
ceph_test_rgw_manifest_CXXFLAGS = $(UNITTEST_CXXFLAGS)
bin_DEBUGPROGRAMS += ceph_test_rgw_manifest

ceph_test_rgw_obj_SOURCES = test/rgw/test_rgw_obj.cc
ceph_test_rgw_obj_LDADD = \
$(LIBRADOS) $(LIBRGW) $(LIBRGW_DEPS) $(CEPH_GLOBAL) \
$(UNITTEST_LDADD) $(CRYPTO_LIBS) \
-lcurl -luuid -lexpat

ceph_test_rgw_obj_CXXFLAGS = $(UNITTEST_CXXFLAGS)
bin_DEBUGPROGRAMS += ceph_test_rgw_obj

ceph_test_cls_rgw_meta_SOURCES = test/test_rgw_admin_meta.cc
ceph_test_cls_rgw_meta_LDADD = \
$(LIBRADOS) $(LIBRGW) $(CEPH_GLOBAL) \
Expand Down
159 changes: 159 additions & 0 deletions src/test/rgw/test_rgw_obj.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
* Ceph - scalable distributed file system
*
* Copyright (C) 2013 eNovance SAS <[email protected]>
*
* This is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software
* Foundation. See file COPYING.
*
*/
#include <iostream>
#include "global/global_init.h"
#include "common/ceph_json.h"
#include "common/Formatter.h"
#include "rgw/rgw_common.h"
#define GTEST
#ifdef GTEST
#include <gtest/gtest.h>
#else
#define TEST(x, y) void y()
#define ASSERT_EQ(v, s) if(v != s)cout << "Error at " << __LINE__ << "(" << #v << "!= " << #s << "\n"; \
else cout << "(" << #v << "==" << #s << ") PASSED\n";
#define EXPECT_EQ(v, s) ASSERT_EQ(v, s)
#define ASSERT_TRUE(c) if(c)cout << "Error at " << __LINE__ << "(" << #c << ")" << "\n"; \
else cout << "(" << #c << ") PASSED\n";
#define EXPECT_TRUE(c) ASSERT_TRUE(c)
#endif
using namespace std;

static void init_bucket(rgw_bucket *bucket, const char *name)
{
*bucket = rgw_bucket(name, ".data-pool", ".index-pool", "marker", "bucket-id", NULL);
}

void check_parsed_correctly(rgw_obj& obj, const string& name, const string& ns, const string& instance)
{
/* parse_raw_oid() */
string parsed_name, parsed_ns, parsed_instance;
ASSERT_EQ(true, rgw_obj::parse_raw_oid(obj.get_object(), &parsed_name, &parsed_instance, &parsed_ns));

cout << "parsed: " << parsed_name << " ns=" << parsed_ns << " i=" << parsed_instance << std::endl;

ASSERT_EQ(name, parsed_name);
ASSERT_EQ(ns, parsed_ns);
ASSERT_EQ(instance, parsed_instance);

/* translate_raw_obj_to_obj_in_ns() */
string tname = obj.get_object();
string tns = ns + "foo";
string tinstance;
ASSERT_EQ(0, rgw_obj::translate_raw_obj_to_obj_in_ns(tname, tinstance, tns));
ASSERT_EQ(name, tname);
ASSERT_EQ(instance, tinstance);

tname = obj.get_object();
tns = ns;
ASSERT_EQ(true, rgw_obj::translate_raw_obj_to_obj_in_ns(tname, tinstance, tns));

cout << "parsed: " << parsed_name << " ns=" << parsed_ns << " i=" << parsed_instance << std::endl;

ASSERT_EQ(name, tname);
ASSERT_EQ(instance, tinstance);

/* strip_namespace_from_object() */

string strip_name = obj.get_object();
string strip_ns, strip_instance;

ASSERT_EQ(true, rgw_obj::strip_namespace_from_object(strip_name, strip_ns, strip_instance));

cout << "stripped: " << strip_name << " ns=" << strip_ns << " i=" << strip_instance << std::endl;

ASSERT_EQ(name, strip_name);
ASSERT_EQ(ns, strip_ns);
ASSERT_EQ(instance, strip_instance);
}

void test_obj(const string& name, const string& ns, const string& instance)
{
rgw_bucket b;
init_bucket(&b, "test");

JSONFormatter *formatter = new JSONFormatter(true);

formatter->open_object_section("test");
rgw_obj o(b, name);
rgw_obj obj1(o);

if (!instance.empty()) {
obj1.set_instance(instance);
}
if (!ns.empty()) {
obj1.set_ns(ns);
}

check_parsed_correctly(obj1, name, ns, instance);
encode_json("obj1", obj1, formatter);

bufferlist bl;
::encode(obj1, bl);

rgw_obj obj2;
::decode(obj2, bl);
check_parsed_correctly(obj2, name, ns, instance);

encode_json("obj2", obj2, formatter);

rgw_obj obj3(o);
bufferlist bl3;
::encode(obj3, bl3);
::decode(obj3, bl3);
encode_json("obj3", obj3, formatter);

if (!instance.empty()) {
obj3.set_instance(instance);
}
if (!ns.empty()) {
obj3.set_ns(ns);
}
check_parsed_correctly(obj3, name, ns, instance);

encode_json("obj3-2", obj3, formatter);

formatter->close_section();

formatter->flush(cout);

ASSERT_EQ(obj1, obj2);
ASSERT_EQ(obj1, obj3);


/* rgw_obj_key conversion */
rgw_obj_key k;
obj1.get_index_key(&k);

rgw_obj new_obj(b, k);

ASSERT_EQ(obj1, new_obj);

delete formatter;
}

TEST(TestRGWObj, underscore) {
test_obj("_obj", "", "");
test_obj("_obj", "ns", "");
test_obj("_obj", "", "v1");
test_obj("_obj", "ns", "v1");
}

TEST(TestRGWObj, no_underscore) {
test_obj("obj", "", "");
test_obj("obj", "ns", "");
test_obj("obj", "", "v1");
test_obj("obj", "ns", "v1");
}

0 comments on commit f1ead76

Please sign in to comment.