Skip to content

Commit

Permalink
added migration test with C API]
Browse files Browse the repository at this point in the history
  • Loading branch information
mdorier committed Dec 1, 2023
1 parent 3d6b277 commit d5e2d01
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 4 deletions.
16 changes: 16 additions & 0 deletions include/warabi/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,22 @@ warabi_err_t warabi_provider_deregister(warabi_provider_t provider);
*/
char* warabi_provider_get_config(warabi_provider_t provider);

/**
* @brief Request that the provider migrate its target to another
* provider.
*
* @param provider Provider whose target to migrate.
* @param dest_addr Destination address.
* @param dest_provider_id Destination provider ID.
* @param migration_config Migration config.
*
* @return warabi_err_t handle.
*/
warabi_err_t warabi_provider_migrate(warabi_provider_t provider,
const char* dest_addr,
uint16_t dest_provider_id,
const char* migration_config);

#ifdef __cplusplus
}
#endif
Expand Down
3 changes: 1 addition & 2 deletions src/ProviderImpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -536,8 +536,7 @@ class ProviderImpl : public tl::provider<ProviderImpl> {
"new_root": {"type": "string"},
"transfer_size": {"type": "integer", "minimum": 0},
"merge_config": {"type": "object"},
"remove_source": {"type": "boolean"},
"remove_destination": {"type": "boolean"}
"remove_source": {"type": "boolean"}
}
})";
static const json migrationJsonSchema = json::parse(migrationJsonSchemaStr);
Expand Down
10 changes: 10 additions & 0 deletions src/c/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,13 @@ extern "C" warabi_err_t warabi_provider_deregister(
extern "C" char* warabi_provider_get_config(warabi_provider_t provider) {
return strdup(provider->getConfig().c_str());
}

extern "C" warabi_err_t warabi_provider_migrate(warabi_provider_t provider,
const char* dest_addr,
uint16_t dest_provider_id,
const char* migration_config) {
try {
provider->migrateTarget(
dest_addr, dest_provider_id, migration_config ? migration_config : "");
} HANDLE_WARABI_ERROR;
}
3 changes: 1 addition & 2 deletions tests/MigrationTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ TEST_CASE("Target migration test", "[migration]") {
"new_root": "/tmp/warabi-migrated-targets",
"transfer_size": 1024,
"merge_config": {},
"remove_source": true,
"remove_destination": false
"remove_source": true
})";
REQUIRE_NOTHROW(provider1.migrateTarget(addr, 2, migrationOptions));

Expand Down
118 changes: 118 additions & 0 deletions tests/MigrationTestC.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
* (C) 2020 The University of Chicago
*
* See COPYRIGHT in top-level directory.
*/
#include <catch2/catch_test_macros.hpp>
#include <catch2/catch_all.hpp>
#include <warabi/client.h>
#include <warabi/server.h>
#include <thallium.hpp>
#include <remi/remi-server.h>
#include <remi/remi-client.h>
#include "defer.hpp"
#include "configs.hpp"

TEST_CASE("Target migration test in C", "[migration]") {

auto target_type = GENERATE(as<std::string>{}, "pmdk", "abtio");
auto tm_type = std::string{"__default__"};

CAPTURE(target_type);

auto pr_config = makeConfigForProvider(target_type, tm_type);

auto engine = thallium::engine("na+sm", THALLIUM_SERVER_MODE);
DEFER(engine.finalize());

remi_client_t remi_client;
REQUIRE(REMI_SUCCESS == remi_client_init(engine.get_margo_instance(), ABT_IO_INSTANCE_NULL, &remi_client));
DEFER(remi_client_finalize(remi_client));

remi_provider_t remi_provider;
REQUIRE(REMI_SUCCESS == remi_provider_register(engine.get_margo_instance(),
ABT_IO_INSTANCE_NULL, 3, ABT_POOL_NULL, &remi_provider));

warabi_err_t err = WARABI_SUCCESS;
DEFER(warabi_err_free(err));

warabi_provider_t provider1, provider2;
warabi_provider_init_args args1 = {
ABT_POOL_NULL, remi_client, REMI_PROVIDER_NULL
};
warabi_provider_init_args args2 = {
ABT_POOL_NULL, REMI_CLIENT_NULL, remi_provider
};
err = warabi_provider_register(&provider1, engine.get_margo_instance(), 1, pr_config.c_str(), &args1);
REQUIRE(err == WARABI_SUCCESS);
DEFER(warabi_provider_deregister(provider1));
err = warabi_provider_register(&provider2, engine.get_margo_instance(), 2, "{}", &args2);
REQUIRE(err == WARABI_SUCCESS);
DEFER(warabi_provider_deregister(provider2));

std::string addr = engine.self();

SECTION("Fill target, migrate, and read") {

warabi_client_t client;
err = warabi_client_create(engine.get_margo_instance(), &client);
REQUIRE(err == WARABI_SUCCESS);
DEFER(warabi_client_free(client));

// check that we can already create a TargetHandle for
// provider 2 but that we cannot do anything with it yet
warabi_target_handle_t th2;
err = warabi_client_make_target_handle(client, addr.c_str(), 2, &th2);
REQUIRE(err == WARABI_SUCCESS);
DEFER(warabi_target_handle_free(th2));
warabi_region_t rid;
err = warabi_create_write(th2, "abcd", 4, true, &rid, nullptr);
REQUIRE(err != WARABI_SUCCESS);
warabi_err_free(err); err = WARABI_SUCCESS;

// create a target handle for provider 1
warabi_target_handle_t th1;
err = warabi_client_make_target_handle(client, addr.c_str(), 1, &th1);
REQUIRE(err == WARABI_SUCCESS);
DEFER(warabi_target_handle_free(th1));

// use provider 1 to create a bunch of regions
auto data_size = 196;
std::vector<warabi_region_t> regionIDs;
for(unsigned i=0; i < 16; ++i) {
std::vector<char> in(data_size);
for(size_t j = 0; j < in.size(); ++j) in[j] = 'A' + (i+j % 26);

warabi_region_t regionID;
warabi_create_write(th1, in.data(), in.size(), true, &regionID, nullptr);
REQUIRE(err == WARABI_SUCCESS);

regionIDs.push_back(regionID);
}

// issue a migration from provider 1 to provider 2
auto migrationOptions = R"({
"new_root": "/tmp/warabi-migrated-targets",
"transfer_size": 1024,
"merge_config": {},
"remove_source": true
})";
err = warabi_provider_migrate(provider1, addr.c_str(), 2, migrationOptions);
REQUIRE(err == WARABI_SUCCESS);

// check that we can read back all the regions from provider 2
for(unsigned i=0; i < 16; ++i) {
std::vector<char> out(data_size);
const warabi_region_t& regionID = regionIDs[i];
err = warabi_read(th2, regionID, 0, out.data(), out.size(), nullptr);
REQUIRE(err == WARABI_SUCCESS);
for(size_t j = 0; j < out.size(); ++j)
REQUIRE(out[j] == 'A' + (i+j % 26));
}

// check that we are now not allowed to access provider 1
err = warabi_create_write(th1, "abcd", 4, true, &rid, nullptr);
REQUIRE(err != WARABI_SUCCESS);
warabi_err_free(err); err = WARABI_SUCCESS;
}
}

0 comments on commit d5e2d01

Please sign in to comment.