-
Notifications
You must be signed in to change notification settings - Fork 201
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Michael Maurer <[email protected]>
- Loading branch information
Showing
4 changed files
with
263 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
// Copyright (c) 2021 MIT Digital Currency Initiative, | ||
// Federal Reserve Bank of Boston | ||
// Distributed under the MIT software license, see the accompanying | ||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||
|
||
#include "../../../util.hpp" | ||
#include "crypto/sha256.h" | ||
#include "parsec/agent/impl.hpp" | ||
#include "parsec/agent/runners/lua/impl.hpp" | ||
#include "parsec/broker/impl.hpp" | ||
#include "parsec/directory/impl.hpp" | ||
#include "parsec/runtime_locking_shard/impl.hpp" | ||
#include "parsec/ticket_machine/impl.hpp" | ||
#include "parsec/util.hpp" | ||
#include "util/common/keys.hpp" | ||
#include "util/serialization/buffer_serializer.hpp" | ||
#include "util/serialization/format.hpp" | ||
|
||
#include <future> | ||
#include <gtest/gtest.h> | ||
#include <lua.hpp> | ||
#include <secp256k1.h> | ||
#include <secp256k1_schnorrsig.h> | ||
#include <thread> | ||
|
||
TEST(lua_runner_test, lua_write_lock_test) { | ||
auto log = std::make_shared<cbdc::logging::log>( | ||
cbdc::logging::log_level::trace); | ||
lua_State* L = luaL_newstate(); | ||
luaL_openlibs(L); | ||
luaL_dofile(L, | ||
"../tests/unit/parsec/agent/runners/lua/test_write_locks.lua"); | ||
lua_getglobal(L, "gen_bytecode"); | ||
ASSERT_EQ(lua_pcall(L, 0, 1, 0), 0); | ||
auto contract = cbdc::buffer::from_hex(lua_tostring(L, -1)).value(); | ||
auto func = cbdc::buffer::from_hex(contract.to_hex()).value(); | ||
auto param = cbdc::buffer(); | ||
auto cfg = cbdc::parsec::config(); | ||
|
||
auto result_cb = [&](cbdc::parsec::agent::runner::interface:: | ||
run_return_type /* value */) { | ||
return; | ||
}; | ||
|
||
std::promise<void> write_lock_promise; | ||
auto write_lock_future = write_lock_promise.get_future(); | ||
auto try_lock_cb | ||
= [&](const cbdc::parsec::broker::key_type& key, | ||
cbdc::parsec::broker::lock_type locktype, | ||
const cbdc::parsec::broker::interface::try_lock_callback_type& | ||
/* res_cb */) -> bool { | ||
// Cannot use ASSERT here because it does not satisfy return | ||
// requirements so we use expect | ||
if(std::string("W").compare(key.c_str()) == 0) { | ||
EXPECT_TRUE(locktype == cbdc::parsec::broker::lock_type::write); | ||
write_lock_promise.set_value(); | ||
} else { | ||
// Cannot use FAIL() here because it expands to a return statement | ||
// which does not satisfy the requirements of a try_lock_callback | ||
// so we improvise | ||
EXPECT_FALSE(true); | ||
} | ||
return true; | ||
}; | ||
|
||
auto runner | ||
= cbdc::parsec::agent::runner::lua_runner(log, | ||
cfg, | ||
std::move(func), | ||
std::move(param), | ||
false, | ||
std::move(result_cb), | ||
std::move(try_lock_cb), | ||
nullptr, | ||
nullptr, | ||
0); | ||
auto res = runner.run(); | ||
write_lock_future.get(); | ||
ASSERT_TRUE(res); | ||
} | ||
|
||
TEST(lua_runner_test, lua_read_lock_test) { | ||
auto log = std::make_shared<cbdc::logging::log>( | ||
cbdc::logging::log_level::trace); | ||
lua_State* L = luaL_newstate(); | ||
luaL_openlibs(L); | ||
luaL_dofile(L, | ||
"../tests/unit/parsec/agent/runners/lua/test_read_locks.lua"); | ||
lua_getglobal(L, "gen_bytecode"); | ||
ASSERT_EQ(lua_pcall(L, 0, 1, 0), 0); | ||
auto contract = cbdc::buffer::from_hex(lua_tostring(L, -1)).value(); | ||
auto func = cbdc::buffer::from_hex(contract.to_hex()).value(); | ||
auto param = cbdc::buffer(); | ||
auto cfg = cbdc::parsec::config(); | ||
|
||
auto result_cb = [&](cbdc::parsec::agent::runner::interface:: | ||
run_return_type /* value */) { | ||
return; | ||
}; | ||
|
||
std::promise<void> read_lock_promise; | ||
auto read_lock_future = read_lock_promise.get_future(); | ||
auto try_lock_cb | ||
= [&](const cbdc::parsec::broker::key_type& key, | ||
cbdc::parsec::broker::lock_type locktype, | ||
const cbdc::parsec::broker::interface::try_lock_callback_type& | ||
/* res_cb */) -> bool { | ||
// Cannot use ASSERT here because it does not satisfy return | ||
// requirements so we use expect | ||
if(std::string("R").compare(key.c_str()) == 0) { | ||
EXPECT_TRUE(locktype == cbdc::parsec::broker::lock_type::read); | ||
read_lock_promise.set_value(); | ||
} else { | ||
// Cannot use FAIL() here because it expands to a return statement | ||
// which does not satisfy the requirements of a try_lock_callback | ||
// so we improvise | ||
EXPECT_FALSE(true); | ||
} | ||
return true; | ||
}; | ||
|
||
auto runner | ||
= cbdc::parsec::agent::runner::lua_runner(log, | ||
cfg, | ||
std::move(func), | ||
std::move(param), | ||
false, | ||
std::move(result_cb), | ||
std::move(try_lock_cb), | ||
nullptr, | ||
nullptr, | ||
0); | ||
auto res = runner.run(); | ||
read_lock_future.get(); | ||
ASSERT_TRUE(res); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
function gen_bytecode() | ||
pay_contract = function(param) | ||
Locks = { | ||
READ = 0, | ||
WRITE = 1, | ||
} | ||
data = coroutine.yield("R", Locks.READ) | ||
return "Done" | ||
end | ||
c = string.dump(pay_contract, true) | ||
t = {} | ||
for i = 1, #c do | ||
t[#t + 1] = string.format("%02x", string.byte(c, i)) | ||
end | ||
|
||
return table.concat(t) | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
function gen_bytecode() | ||
pay_contract = function(param) | ||
Locks = { | ||
READ = 0, | ||
WRITE = 1, | ||
} | ||
data2 = coroutine.yield("W", Locks.WRITE) | ||
return "Done" | ||
end | ||
c = string.dump(pay_contract, true) | ||
t = {} | ||
for i = 1, #c do | ||
t[#t + 1] = string.format("%02x", string.byte(c, i)) | ||
end | ||
|
||
return table.concat(t) | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
// Copyright (c) 2021 MIT Digital Currency Initiative, | ||
// Federal Reserve Bank of Boston | ||
// Distributed under the MIT software license, see the accompanying | ||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||
|
||
#include "../../../util.hpp" | ||
#include "crypto/sha256.h" | ||
#include "parsec/agent/impl.hpp" | ||
#include "parsec/agent/runners/lua/impl.hpp" | ||
#include "parsec/broker/impl.hpp" | ||
#include "parsec/directory/impl.hpp" | ||
#include "parsec/runtime_locking_shard/impl.hpp" | ||
#include "parsec/ticket_machine/impl.hpp" | ||
#include "parsec/util.hpp" | ||
#include "util/common/keys.hpp" | ||
#include "util/serialization/buffer_serializer.hpp" | ||
#include "util/serialization/format.hpp" | ||
|
||
#include <future> | ||
#include <gtest/gtest.h> | ||
#include <lua.hpp> | ||
#include <secp256k1.h> | ||
#include <secp256k1_schnorrsig.h> | ||
#include <thread> | ||
|
||
TEST(lua_runner_test, lua_read_lock_test) { | ||
auto log = std::make_shared<cbdc::logging::log>( | ||
cbdc::logging::log_level::trace); | ||
lua_State* L = luaL_newstate(); | ||
luaL_openlibs(L); | ||
luaL_dofile(L, | ||
"../tests/unit/parsec/agent/runners/lua/test_write_locks.lua"); | ||
lua_getglobal(L, "gen_bytecode"); | ||
ASSERT_EQ(lua_pcall(L, 0, 1, 0), 0); | ||
auto contract = cbdc::buffer::from_hex(lua_tostring(L, -1)).value(); | ||
auto func = cbdc::buffer::from_hex(contract.to_hex()).value(); | ||
auto param = cbdc::buffer(); | ||
auto cfg = cbdc::parsec::config(); | ||
|
||
auto result_cb = [&](cbdc::parsec::agent::runner::interface:: | ||
run_return_type /* value */) { | ||
return; | ||
}; | ||
|
||
std::atomic<int> lock_count = 0; | ||
std::promise<void> write_lock_promise; | ||
std::promise<void> read_lock_promise; | ||
auto write_lock_future = write_lock_promise.get_future(); | ||
auto read_lock_future = read_lock_promise.get_future(); | ||
auto try_lock_cb | ||
= [&](const cbdc::parsec::broker::key_type& key, | ||
cbdc::parsec::broker::lock_type locktype, | ||
const cbdc::parsec::broker::interface::try_lock_callback_type& | ||
/* res_cb */) -> bool { | ||
// Cannot use ASSERT here because it does not satisfy return requirements | ||
// so we use expect | ||
log->trace("Got lock for key:", key.c_str()); | ||
if(std::string("W").compare(key.c_str()) == 0) { | ||
log->trace("Got write lock"); | ||
EXPECT_TRUE(locktype == cbdc::parsec::broker::lock_type::write); | ||
lock_count++; | ||
write_lock_promise.set_value(); | ||
} else if(std::string("R").compare(key.c_str()) == 0) { | ||
log->trace("Got read lock"); | ||
EXPECT_TRUE(locktype == cbdc::parsec::broker::lock_type::read); | ||
lock_count++; | ||
read_lock_promise.set_value(); | ||
} else { | ||
// Cannot use FAIL() here because it expands to a return statement | ||
// which does not satisfy the requirements of a try_lock_callback | ||
// so we improvise | ||
EXPECT_FALSE(true); | ||
} | ||
return true; | ||
}; | ||
|
||
auto runner | ||
= cbdc::parsec::agent::runner::lua_runner(log, | ||
cfg, | ||
std::move(func), | ||
std::move(param), | ||
false, | ||
std::move(result_cb), | ||
std::move(try_lock_cb), | ||
nullptr, | ||
nullptr, | ||
0); | ||
auto res = runner.run(); | ||
write_lock_future.get(); | ||
read_lock_future.get(); | ||
ASSERT_EQ(lock_count, 2); | ||
ASSERT_TRUE(res); | ||
} |