mirror of
https://git.jami.net/savoirfairelinux/jami-daemon.git
synced 2025-08-12 22:09:25 +08:00
swarm: add a method to get a range of commits
This patch introduces ConversationRepository::log(last, n) to get the commits from [last-n, last], where last (if not specified) is current HEAD. Change-Id: Ia6b8eb96b8a4a0de3614d4e422c1179f976d2ab0
This commit is contained in:
@ -157,17 +157,17 @@ add_initial_files(GitRepository& repo, const std::shared_ptr<JamiAccount>& accou
|
||||
}
|
||||
|
||||
// git add -A
|
||||
git_index* index;
|
||||
git_index* index_ptr = nullptr;
|
||||
git_strarray array = {0};
|
||||
|
||||
if (git_repository_index(&index, repo.get()) < 0) {
|
||||
if (git_repository_index(&index_ptr, repo.get()) < 0) {
|
||||
JAMI_ERR("Could not open repository index");
|
||||
return false;
|
||||
}
|
||||
|
||||
git_index_add_all(index, &array, 0, nullptr, nullptr);
|
||||
git_index_write(index);
|
||||
git_index_free(index);
|
||||
GitIndex index {index_ptr, git_index_free};
|
||||
git_index_add_all(index.get(), &array, 0, nullptr, nullptr);
|
||||
git_index_write(index.get());
|
||||
|
||||
JAMI_INFO("Initial files added in %s", repoPath.c_str());
|
||||
return true;
|
||||
@ -187,41 +187,47 @@ initial_commit(GitRepository& repo, const std::shared_ptr<JamiAccount>& account)
|
||||
if (name.empty())
|
||||
name = deviceId;
|
||||
|
||||
git_signature* sig;
|
||||
git_index* index;
|
||||
git_signature* sig_ptr = nullptr;
|
||||
git_index* index_ptr = nullptr;
|
||||
git_oid tree_id, commit_id;
|
||||
git_tree* tree;
|
||||
git_tree* tree_ptr = nullptr;
|
||||
git_buf to_sign = {};
|
||||
|
||||
// Sign commit's buffer
|
||||
if (git_signature_new(&sig, name.c_str(), deviceId.c_str(), std::time(nullptr), 0) < 0) {
|
||||
if (git_signature_new(&sig_ptr, name.c_str(), deviceId.c_str(), std::time(nullptr), 0) < 0) {
|
||||
JAMI_ERR("Unable to create a commit signature.");
|
||||
return {};
|
||||
}
|
||||
GitSignature sig {sig_ptr, git_signature_free};
|
||||
|
||||
if (git_repository_index(&index, repo.get()) < 0) {
|
||||
if (git_repository_index(&index_ptr, repo.get()) < 0) {
|
||||
JAMI_ERR("Could not open repository index");
|
||||
return {};
|
||||
}
|
||||
GitIndex index {index_ptr, git_index_free};
|
||||
|
||||
if (git_index_write_tree(&tree_id, index) < 0) {
|
||||
if (git_index_write_tree(&tree_id, index.get()) < 0) {
|
||||
JAMI_ERR("Unable to write initial tree from index");
|
||||
return {};
|
||||
}
|
||||
|
||||
git_index_free(index);
|
||||
|
||||
if (git_tree_lookup(&tree, repo.get(), &tree_id) < 0) {
|
||||
if (git_tree_lookup(&tree_ptr, repo.get(), &tree_id) < 0) {
|
||||
JAMI_ERR("Could not look up initial tree");
|
||||
git_tree_free(tree);
|
||||
return {};
|
||||
}
|
||||
GitTree tree = {tree_ptr, git_tree_free};
|
||||
|
||||
if (git_commit_create_buffer(
|
||||
&to_sign, repo.get(), sig, sig, nullptr, "Initial commit", tree, 0, nullptr)
|
||||
if (git_commit_create_buffer(&to_sign,
|
||||
repo.get(),
|
||||
sig.get(),
|
||||
sig.get(),
|
||||
nullptr,
|
||||
"Initial commit",
|
||||
tree.get(),
|
||||
0,
|
||||
nullptr)
|
||||
< 0) {
|
||||
JAMI_ERR("Could not create initial buffer");
|
||||
git_tree_free(tree);
|
||||
return {};
|
||||
}
|
||||
|
||||
@ -237,22 +243,18 @@ initial_commit(GitRepository& repo, const std::shared_ptr<JamiAccount>& account)
|
||||
"signature")
|
||||
< 0) {
|
||||
JAMI_ERR("Could not sign initial commit");
|
||||
git_tree_free(tree);
|
||||
return {};
|
||||
}
|
||||
|
||||
// Move commit to master branch
|
||||
git_commit* commit;
|
||||
git_commit* commit = nullptr;
|
||||
if (git_commit_lookup(&commit, repo.get(), &commit_id) == 0) {
|
||||
git_reference* ref;
|
||||
git_reference* ref = nullptr;
|
||||
git_branch_create(&ref, repo.get(), "master", commit, true);
|
||||
git_reference_free(ref);
|
||||
git_commit_free(commit);
|
||||
git_reference_free(ref);
|
||||
}
|
||||
|
||||
git_tree_free(tree);
|
||||
git_signature_free(sig);
|
||||
|
||||
auto commit_str = git_oid_tostr_s(&commit_id);
|
||||
if (commit_str)
|
||||
return commit_str;
|
||||
@ -332,8 +334,8 @@ ConversationRepository::cloneConversation(const std::weak_ptr<JamiAccount>& acco
|
||||
JAMI_ERR("Error when retrieving remote conversation: %s", err->message);
|
||||
return nullptr;
|
||||
}
|
||||
JAMI_INFO("New conversation cloned in %s", path.c_str());
|
||||
git_repository_free(rep);
|
||||
JAMI_INFO("New conversation cloned in %s", path.c_str());
|
||||
return std::make_unique<ConversationRepository>(account, conversationId);
|
||||
}
|
||||
|
||||
@ -356,12 +358,11 @@ bool
|
||||
ConversationRepository::fetch(const std::string& remoteDeviceId)
|
||||
{
|
||||
// Fetch distant repository
|
||||
git_remote* remote = nullptr;
|
||||
git_remote* remote_ptr = nullptr;
|
||||
git_fetch_options fetch_opts = GIT_FETCH_OPTIONS_INIT;
|
||||
|
||||
// Assert that repository exists
|
||||
std::string channelName = "git://" + remoteDeviceId + '/' + pimpl_->id_;
|
||||
git_remote* remote_ptr = nullptr;
|
||||
auto res = git_remote_lookup(&remote_ptr, pimpl_->repository_.get(), remoteDeviceId.c_str());
|
||||
if (res != 0) {
|
||||
if (res != GIT_ENOTFOUND) {
|
||||
@ -378,14 +379,17 @@ ConversationRepository::fetch(const std::string& remoteDeviceId)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
GitRemote remote {remote_ptr, git_remote_free};
|
||||
|
||||
if (git_remote_fetch(remote, nullptr, &fetch_opts, "fetch") < 0) {
|
||||
JAMI_ERR("Could not fetch remote repository for conversation %s", pimpl_->id_.c_str());
|
||||
git_remote_free(remote);
|
||||
if (git_remote_fetch(remote.get(), nullptr, &fetch_opts, "fetch") < 0) {
|
||||
const git_error* err = giterr_last();
|
||||
if (err)
|
||||
JAMI_ERR("Could not fetch remote repository for conversation %s: %s",
|
||||
pimpl_->id_.c_str(),
|
||||
err->message);
|
||||
return false;
|
||||
}
|
||||
|
||||
git_remote_free(remote);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -443,69 +447,62 @@ ConversationRepository::sendMessage(const std::string& msg)
|
||||
file.close();
|
||||
|
||||
// git add
|
||||
git_index* index;
|
||||
|
||||
if (git_repository_index(&index, pimpl_->repository_.get()) < 0) {
|
||||
git_index* index_ptr = nullptr;
|
||||
if (git_repository_index(&index_ptr, pimpl_->repository_.get()) < 0) {
|
||||
JAMI_ERR("Could not open repository index");
|
||||
return {};
|
||||
}
|
||||
GitIndex index {index_ptr, git_index_free};
|
||||
|
||||
git_index_add_bypath(index, devicePath.c_str());
|
||||
git_index_write(index);
|
||||
git_index_free(index);
|
||||
git_index_add_bypath(index.get(), devicePath.c_str());
|
||||
git_index_write(index.get());
|
||||
}
|
||||
|
||||
git_signature* sig;
|
||||
git_signature* sig_ptr = nullptr;
|
||||
// Sign commit's buffer
|
||||
if (git_signature_new(&sig, name.c_str(), deviceId.c_str(), std::time(nullptr), 0) < 0) {
|
||||
if (git_signature_new(&sig_ptr, name.c_str(), deviceId.c_str(), std::time(nullptr), 0) < 0) {
|
||||
JAMI_ERR("Unable to create a commit signature.");
|
||||
return {};
|
||||
}
|
||||
GitSignature sig {sig_ptr, git_signature_free};
|
||||
|
||||
// Retrieve current HEAD
|
||||
git_oid commit_id;
|
||||
if (git_reference_name_to_id(&commit_id, pimpl_->repository_.get(), "HEAD") < 0) {
|
||||
JAMI_ERR("Cannot get reference for HEAD");
|
||||
git_signature_free(sig);
|
||||
return {};
|
||||
}
|
||||
|
||||
git_commit* head_commit;
|
||||
if (git_commit_lookup(&head_commit, pimpl_->repository_.get(), &commit_id) < 0) {
|
||||
git_commit* head_ptr = nullptr;
|
||||
if (git_commit_lookup(&head_ptr, pimpl_->repository_.get(), &commit_id) < 0) {
|
||||
JAMI_ERR("Could not look up HEAD commit");
|
||||
git_signature_free(sig);
|
||||
return {};
|
||||
}
|
||||
GitCommit head_commit {head_ptr, git_commit_free};
|
||||
|
||||
git_tree* tree;
|
||||
if (git_commit_tree(&tree, head_commit) < 0) {
|
||||
git_tree* tree_ptr = nullptr;
|
||||
if (git_commit_tree(&tree_ptr, head_commit.get()) < 0) {
|
||||
JAMI_ERR("Could not look up initial tree");
|
||||
git_signature_free(sig);
|
||||
return {};
|
||||
}
|
||||
GitTree tree {tree_ptr, git_tree_free};
|
||||
|
||||
git_buf to_sign = {};
|
||||
const git_commit* head_ref[1] = {head_commit};
|
||||
const git_commit* head_ref[1] = {head_commit.get()};
|
||||
if (git_commit_create_buffer(&to_sign,
|
||||
pimpl_->repository_.get(),
|
||||
sig,
|
||||
sig,
|
||||
sig.get(),
|
||||
sig.get(),
|
||||
nullptr,
|
||||
msg.c_str(),
|
||||
tree,
|
||||
tree.get(),
|
||||
1,
|
||||
&head_ref[0])
|
||||
< 0) {
|
||||
JAMI_ERR("Could not create commit buffer");
|
||||
git_commit_free(head_commit);
|
||||
git_tree_free(tree);
|
||||
git_signature_free(sig);
|
||||
return {};
|
||||
}
|
||||
|
||||
git_tree_free(tree);
|
||||
git_commit_free(head_commit);
|
||||
|
||||
// git commit -S
|
||||
auto to_sign_vec = std::vector<uint8_t>(to_sign.ptr, to_sign.ptr + to_sign.size);
|
||||
auto signed_buf = account->identity().first->sign(to_sign_vec);
|
||||
@ -520,11 +517,9 @@ ConversationRepository::sendMessage(const std::string& msg)
|
||||
return {};
|
||||
}
|
||||
|
||||
git_signature_free(sig);
|
||||
|
||||
// Move commit to master branch
|
||||
git_reference* ref;
|
||||
if (git_reference_create(&ref,
|
||||
git_reference* ref_ptr = nullptr;
|
||||
if (git_reference_create(&ref_ptr,
|
||||
pimpl_->repository_.get(),
|
||||
"refs/heads/master",
|
||||
&commit_id,
|
||||
@ -533,7 +528,7 @@ ConversationRepository::sendMessage(const std::string& msg)
|
||||
< 0) {
|
||||
JAMI_WARN("Could not move commit to master");
|
||||
}
|
||||
git_reference_free(ref);
|
||||
git_reference_free(ref_ptr);
|
||||
|
||||
auto commit_str = git_oid_tostr_s(&commit_id);
|
||||
if (commit_str) {
|
||||
@ -542,4 +537,79 @@ ConversationRepository::sendMessage(const std::string& msg)
|
||||
return commit_str ? commit_str : "";
|
||||
}
|
||||
|
||||
} // namespace jami
|
||||
std::vector<ConversationCommit>
|
||||
ConversationRepository::log(const std::string& last, unsigned n)
|
||||
{
|
||||
std::vector<ConversationCommit> commits {};
|
||||
|
||||
git_oid oid;
|
||||
if (last.empty()) {
|
||||
if (git_reference_name_to_id(&oid, pimpl_->repository_.get(), "HEAD") < 0) {
|
||||
JAMI_ERR("Cannot get reference for HEAD");
|
||||
return commits;
|
||||
}
|
||||
} else {
|
||||
if (git_oid_fromstr(&oid, last.c_str()) < 0) {
|
||||
JAMI_ERR("Cannot get reference for commit %s", last.c_str());
|
||||
return commits;
|
||||
}
|
||||
}
|
||||
|
||||
git_revwalk* walker_ptr = nullptr;
|
||||
if (git_revwalk_new(&walker_ptr, pimpl_->repository_.get()) < 0
|
||||
|| git_revwalk_push(walker_ptr, &oid) < 0) {
|
||||
JAMI_ERR("Couldn't init revwalker for conversation %s", pimpl_->id_.c_str());
|
||||
return commits;
|
||||
}
|
||||
GitRevWalker walker {walker_ptr, git_revwalk_free};
|
||||
git_revwalk_sorting(walker.get(), GIT_SORT_TOPOLOGICAL);
|
||||
|
||||
auto x = git_oid_tostr_s(&oid);
|
||||
for (auto idx = 0; !git_revwalk_next(&oid, walker.get()); ++idx) {
|
||||
if (n != 0 && idx == n) {
|
||||
break;
|
||||
}
|
||||
git_commit* commit_ptr = nullptr;
|
||||
std::string id = git_oid_tostr_s(&oid);
|
||||
if (git_commit_lookup(&commit_ptr, pimpl_->repository_.get(), &oid) < 0) {
|
||||
JAMI_WARN("Failed to look up commit %s", id.c_str());
|
||||
break;
|
||||
}
|
||||
GitCommit commit {commit_ptr, git_commit_free};
|
||||
|
||||
const git_signature* sig = git_commit_author(commit.get());
|
||||
GitAuthor author;
|
||||
author.name = sig->name;
|
||||
author.email = sig->email;
|
||||
std::string parent {};
|
||||
const git_oid* pid = git_commit_parent_id(commit.get(), 0);
|
||||
if (pid) {
|
||||
parent = git_oid_tostr_s(pid);
|
||||
}
|
||||
|
||||
auto cc = commits.emplace(commits.end(), ConversationCommit {});
|
||||
cc->id = std::move(id);
|
||||
cc->commit_msg = git_commit_message(commit.get());
|
||||
cc->author = std::move(author);
|
||||
cc->parent = std::move(parent);
|
||||
git_buf signature = {}, signed_data = {};
|
||||
if (git_commit_extract_signature(&signature,
|
||||
&signed_data,
|
||||
pimpl_->repository_.get(),
|
||||
&oid,
|
||||
"signature")
|
||||
< 0) {
|
||||
JAMI_WARN("Could not extract signature for commit %s", id.c_str());
|
||||
} else {
|
||||
cc->signature = base64::decode(
|
||||
std::string(signature.ptr, signature.ptr + signature.size));
|
||||
cc->signed_content = std::vector<uint8_t>(signed_data.ptr,
|
||||
signed_data.ptr + signed_data.size);
|
||||
}
|
||||
cc->timestamp = git_commit_time(commit.get());
|
||||
}
|
||||
|
||||
return commits;
|
||||
}
|
||||
|
||||
} // namespace jami
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <git2.h>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "def.h"
|
||||
|
||||
@ -46,6 +47,23 @@ namespace jami {
|
||||
class JamiAccount;
|
||||
class ChannelSocket;
|
||||
|
||||
struct GitAuthor
|
||||
{
|
||||
std::string name {};
|
||||
std::string email {};
|
||||
};
|
||||
|
||||
struct ConversationCommit
|
||||
{
|
||||
std::string id {};
|
||||
std::string parent {};
|
||||
GitAuthor author {};
|
||||
std::vector<uint8_t> signed_content {};
|
||||
std::vector<uint8_t> signature {};
|
||||
std::string commit_msg {};
|
||||
int64_t timestamp {0};
|
||||
};
|
||||
|
||||
/**
|
||||
* This class gives access to the git repository that represents the conversation
|
||||
*/
|
||||
@ -110,6 +128,14 @@ public:
|
||||
*/
|
||||
std::string sendMessage(const std::string& msg);
|
||||
|
||||
/**
|
||||
* Get commits from [last-n, last]
|
||||
* @param last last commit (default empty)
|
||||
* @param n Max commits number to get (default: 0)
|
||||
* @return a list of commits
|
||||
*/
|
||||
std::vector<ConversationCommit> log(const std::string& last = "", unsigned n = 0);
|
||||
|
||||
private:
|
||||
ConversationRepository() = delete;
|
||||
class Impl;
|
||||
|
@ -36,7 +36,8 @@ constexpr auto NAK_PKT = "0008NAK\n"sv;
|
||||
constexpr auto DONE_PKT = "0009done\n"sv;
|
||||
constexpr auto WANT_CMD = "want"sv;
|
||||
constexpr auto HAVE_CMD = "have"sv;
|
||||
constexpr auto SERVER_CAPABILITIES = " HEAD\0side-band side-band-64k shallow no-progress include-tag"sv;
|
||||
constexpr auto SERVER_CAPABILITIES
|
||||
= " HEAD\0side-band side-band-64k shallow no-progress include-tag"sv;
|
||||
|
||||
namespace jami {
|
||||
|
||||
@ -106,7 +107,7 @@ GitServer::Impl::parseOrder(const uint8_t* buf, std::size_t len)
|
||||
// The first four bytes define the length of the packet and 0000 is a FLUSH pkt
|
||||
|
||||
unsigned int pkt_len;
|
||||
std::from_chars(pkt.data(), pkt.data()+4, pkt_len, 16);
|
||||
std::from_chars(pkt.data(), pkt.data() + 4, pkt_len, 16);
|
||||
if (pkt_len != pkt.size()) {
|
||||
// Store next packet part
|
||||
if (pkt_len == 0) {
|
||||
@ -234,8 +235,7 @@ GitServer::Impl::sendReferenceCapabilities(bool sendVersion)
|
||||
|
||||
// Send references
|
||||
std::stringstream capabilities;
|
||||
capabilities << currentHead
|
||||
<< SERVER_CAPABILITIES;
|
||||
capabilities << currentHead << SERVER_CAPABILITIES;
|
||||
std::string capStr = capabilities.str();
|
||||
|
||||
packet.str("");
|
||||
@ -401,7 +401,7 @@ GitServer::Impl::sendPackData()
|
||||
// cf https://github.com/git/git/blob/master/Documentation/technical/pack-protocol.txt#L166
|
||||
// In 'side-band-64k' mode it will send up to 65519 data bytes plus 1 control code, for a
|
||||
// total of up to 65520 bytes in a pkt-line.
|
||||
std::size_t pkt_size = std::min(static_cast<std::size_t>(65519), len - sent);
|
||||
std::size_t pkt_size = std::min(static_cast<std::size_t>(65515), len - sent);
|
||||
std::stringstream toSend;
|
||||
toSend << std::setw(4) << std::setfill('0') << std::hex << ((pkt_size + 5) & 0x0FFFF);
|
||||
toSend << "\x1" << std::string_view(data.ptr + sent, pkt_size);
|
||||
|
@ -59,12 +59,14 @@ private:
|
||||
void testCreateRepository();
|
||||
void testCloneViaChannelSocket();
|
||||
void testAddSomeMessages();
|
||||
void testLogMessages();
|
||||
void testFetch();
|
||||
|
||||
CPPUNIT_TEST_SUITE(ConversationRepositoryTest);
|
||||
CPPUNIT_TEST(testCreateRepository);
|
||||
CPPUNIT_TEST(testCloneViaChannelSocket);
|
||||
CPPUNIT_TEST(testAddSomeMessages);
|
||||
CPPUNIT_TEST(testLogMessages);
|
||||
CPPUNIT_TEST(testFetch);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
};
|
||||
@ -303,6 +305,14 @@ ConversationRepositoryTest::testCloneViaChannelSocket()
|
||||
std::istreambuf_iterator<char>());
|
||||
|
||||
CPPUNIT_ASSERT(deviceCrtStr == deviceCert);
|
||||
|
||||
// Check cloned messages
|
||||
auto messages = cloned->log();
|
||||
CPPUNIT_ASSERT(messages.size() == 1);
|
||||
CPPUNIT_ASSERT(messages[0].id == repository->id());
|
||||
CPPUNIT_ASSERT(
|
||||
aliceAccount->identity().second->getPublicKey().checkSignature(messages[0].signed_content,
|
||||
messages[0].signature));
|
||||
}
|
||||
|
||||
void
|
||||
@ -311,10 +321,59 @@ ConversationRepositoryTest::testAddSomeMessages()
|
||||
auto aliceAccount = Manager::instance().getAccount<JamiAccount>(aliceId);
|
||||
auto repository = ConversationRepository::createConversation(aliceAccount->weak());
|
||||
|
||||
repository->sendMessage("Commit 1");
|
||||
repository->sendMessage("Commit 2");
|
||||
repository->sendMessage("Commit 3");
|
||||
// TODO check commits => needs something to get messages
|
||||
auto id1 = repository->sendMessage("Commit 1");
|
||||
auto id2 = repository->sendMessage("Commit 2");
|
||||
auto id3 = repository->sendMessage("Commit 3");
|
||||
|
||||
auto messages = repository->log();
|
||||
CPPUNIT_ASSERT(messages.size() == 4 /* 3 + initial */);
|
||||
CPPUNIT_ASSERT(messages[0].id == id3);
|
||||
CPPUNIT_ASSERT(messages[0].parent == id2);
|
||||
CPPUNIT_ASSERT(messages[0].commit_msg == "Commit 3");
|
||||
CPPUNIT_ASSERT(messages[0].author.name == messages[3].author.name);
|
||||
CPPUNIT_ASSERT(messages[0].author.email == messages[3].author.email);
|
||||
CPPUNIT_ASSERT(messages[1].id == id2);
|
||||
CPPUNIT_ASSERT(messages[1].parent == id1);
|
||||
CPPUNIT_ASSERT(messages[1].commit_msg == "Commit 2");
|
||||
CPPUNIT_ASSERT(messages[1].author.name == messages[3].author.name);
|
||||
CPPUNIT_ASSERT(messages[1].author.email == messages[3].author.email);
|
||||
CPPUNIT_ASSERT(messages[2].id == id1);
|
||||
CPPUNIT_ASSERT(messages[2].commit_msg == "Commit 1");
|
||||
CPPUNIT_ASSERT(messages[2].author.name == messages[3].author.name);
|
||||
CPPUNIT_ASSERT(messages[2].author.email == messages[3].author.email);
|
||||
CPPUNIT_ASSERT(messages[2].parent == repository->id());
|
||||
// Check sig
|
||||
CPPUNIT_ASSERT(
|
||||
aliceAccount->identity().second->getPublicKey().checkSignature(messages[0].signed_content,
|
||||
messages[0].signature));
|
||||
CPPUNIT_ASSERT(
|
||||
aliceAccount->identity().second->getPublicKey().checkSignature(messages[1].signed_content,
|
||||
messages[1].signature));
|
||||
CPPUNIT_ASSERT(
|
||||
aliceAccount->identity().second->getPublicKey().checkSignature(messages[2].signed_content,
|
||||
messages[2].signature));
|
||||
}
|
||||
|
||||
void
|
||||
ConversationRepositoryTest::testLogMessages()
|
||||
{
|
||||
auto aliceAccount = Manager::instance().getAccount<JamiAccount>(aliceId);
|
||||
auto repository = ConversationRepository::createConversation(aliceAccount->weak());
|
||||
|
||||
auto id1 = repository->sendMessage("Commit 1");
|
||||
auto id2 = repository->sendMessage("Commit 2");
|
||||
auto id3 = repository->sendMessage("Commit 3");
|
||||
|
||||
auto messages = repository->log(repository->id(), 1);
|
||||
CPPUNIT_ASSERT(messages.size() == 1);
|
||||
CPPUNIT_ASSERT(messages[0].id == repository->id());
|
||||
messages = repository->log(id2, 2);
|
||||
CPPUNIT_ASSERT(messages.size() == 2);
|
||||
CPPUNIT_ASSERT(messages[0].id == id2);
|
||||
CPPUNIT_ASSERT(messages[1].id == id1);
|
||||
messages = repository->log(repository->id(), 3);
|
||||
CPPUNIT_ASSERT(messages.size() == 1);
|
||||
CPPUNIT_ASSERT(messages[0].id == repository->id());
|
||||
}
|
||||
|
||||
void
|
||||
@ -350,7 +409,7 @@ ConversationRepositoryTest::testFetch()
|
||||
});
|
||||
|
||||
aliceAccount->connectionManager().onChannelRequest(
|
||||
[&](const DeviceId&, const std::string& name) { return true; });
|
||||
[&](const DeviceId&, const std::string&) { return true; });
|
||||
|
||||
bobAccount->connectionManager().onConnectionReady(
|
||||
[&](const DeviceId&, const std::string& name, std::shared_ptr<ChannelSocket> socket) {
|
||||
@ -381,7 +440,7 @@ ConversationRepositoryTest::testFetch()
|
||||
std::thread sendT = std::thread([&]() { gs.run(); });
|
||||
|
||||
// Clone repository
|
||||
repository->sendMessage("Commit 1");
|
||||
auto id1 = repository->sendMessage("Commit 1");
|
||||
auto cloned = ConversationRepository::cloneConversation(bobAccount->weak(),
|
||||
aliceDeviceId,
|
||||
repository->id());
|
||||
@ -390,7 +449,7 @@ ConversationRepositoryTest::testFetch()
|
||||
bobAccount->removeGitSocket(aliceDeviceId, repository->id());
|
||||
|
||||
// Add some new messages to fetch
|
||||
repository->sendMessage("Commit 2");
|
||||
auto id2 = repository->sendMessage("Commit 2");
|
||||
auto id3 = repository->sendMessage("Commit 3");
|
||||
|
||||
// Open a new channel to simulate the fact that we are later
|
||||
@ -418,7 +477,33 @@ ConversationRepositoryTest::testFetch()
|
||||
bobAccount->removeGitSocket(aliceDeviceId, repository->id());
|
||||
sendT2.join();
|
||||
|
||||
// TODO check commits => needs something to get messages
|
||||
auto messages = cloned->log(id3);
|
||||
CPPUNIT_ASSERT(messages.size() == 4 /* 3 + initial */);
|
||||
CPPUNIT_ASSERT(messages[0].id == id3);
|
||||
CPPUNIT_ASSERT(messages[0].parent == id2);
|
||||
CPPUNIT_ASSERT(messages[0].commit_msg == "Commit 3");
|
||||
CPPUNIT_ASSERT(messages[0].author.name == messages[3].author.name);
|
||||
CPPUNIT_ASSERT(messages[0].author.email == messages[3].author.email);
|
||||
CPPUNIT_ASSERT(messages[1].id == id2);
|
||||
CPPUNIT_ASSERT(messages[1].parent == id1);
|
||||
CPPUNIT_ASSERT(messages[1].commit_msg == "Commit 2");
|
||||
CPPUNIT_ASSERT(messages[1].author.name == messages[3].author.name);
|
||||
CPPUNIT_ASSERT(messages[1].author.email == messages[3].author.email);
|
||||
CPPUNIT_ASSERT(messages[2].id == id1);
|
||||
CPPUNIT_ASSERT(messages[2].commit_msg == "Commit 1");
|
||||
CPPUNIT_ASSERT(messages[2].author.name == messages[3].author.name);
|
||||
CPPUNIT_ASSERT(messages[2].author.email == messages[3].author.email);
|
||||
CPPUNIT_ASSERT(messages[2].parent == repository->id());
|
||||
// Check sig
|
||||
CPPUNIT_ASSERT(
|
||||
aliceAccount->identity().second->getPublicKey().checkSignature(messages[0].signed_content,
|
||||
messages[0].signature));
|
||||
CPPUNIT_ASSERT(
|
||||
aliceAccount->identity().second->getPublicKey().checkSignature(messages[1].signed_content,
|
||||
messages[1].signature));
|
||||
CPPUNIT_ASSERT(
|
||||
aliceAccount->identity().second->getPublicKey().checkSignature(messages[2].signed_content,
|
||||
messages[2].signature));
|
||||
}
|
||||
|
||||
} // namespace test
|
||||
|
Reference in New Issue
Block a user