diff --git a/test/fuzzing/Makefile.am b/test/fuzzing/Makefile.am
index 230da0ea039227eb4dd8a0c7f9a142860f4bb04d..ed7a83c9c5632d8d6e1436917eddf1759680f56a 100644
--- a/test/fuzzing/Makefile.am
+++ b/test/fuzzing/Makefile.am
@@ -16,4 +16,8 @@ libfuzz_la_SOURCES = lib/utils.cpp lib/supervisor.cpp lib/gnutls.cpp lib/rand.cp
 check_PROGRAMS += fuzz_spam_channel_creation
 fuzz_spam_channel_creation_SOURCES = fuzz-spam-channel-creation.cpp
 fuzz_spam_channel_creation_LDADD = libfuzz.la
+
+check_PROGRAMS += fuzz_msgpack
+fuzz_msgpack_SOURCES = fuzz-msgpack.cpp
+fuzz_msgpack_LDADD = libfuzz.la
 endif
diff --git a/test/fuzzing/fuzz-msgpack.cpp b/test/fuzzing/fuzz-msgpack.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f01e4067d9830e68be7bade0d91505f9968731c6
--- /dev/null
+++ b/test/fuzzing/fuzz-msgpack.cpp
@@ -0,0 +1,47 @@
+/*
+ *  Copyright (C) 2021 Savoir-faire Linux Inc.
+ *
+ *  Author: Olivier Dion <olivier.dion>@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+#include "lib/gnutls.h"
+#include "lib/syslog.h"
+
+/*
+ * Reverse channel and data in packed message
+ */
+void
+pack_gnutls_record_recv(msgpack::sbuffer& buf, const ChanneledMessage& msg)
+{
+     msgpack::packer<msgpack::sbuffer> pk(&buf);
+
+     pk.pack_array(2);
+     pk.pack_bin(msg.data.size());
+     pk.pack_bin_body((const char*) msg.data.data(), msg.data.size());
+     pk.pack(msg.channel);
+}
+
+bool
+mutate_gnutls_record_recv(ChanneledMessage& msg)
+{
+    (void)msg;
+
+    return true;
+}
+
+
+#include "scenarios/classic-alice-and-bob.h"
diff --git a/test/fuzzing/fuzz-spam-channel-creation.cpp b/test/fuzzing/fuzz-spam-channel-creation.cpp
index c65791da1257a1c8fd8d1424f565acf504b9a159..2e18171d5c19818bb4bcc3d95bb3961c4aa22425 100644
--- a/test/fuzzing/fuzz-spam-channel-creation.cpp
+++ b/test/fuzzing/fuzz-spam-channel-creation.cpp
@@ -22,13 +22,9 @@
 #include <set>
 #include <atomic>
 #include <mutex>
-#include <condition_variable>
+#include <thread>
 
-#include "manager.h"
 #include "jamidht/connectionmanager.h"
-#include "jamidht/jamiaccount.h"
-#include "dring.h"
-#include "account_const.h"
 
 #include "lib/gnutls.h"
 #include "lib/utils.h"
@@ -99,48 +95,4 @@ void pre_gnutls_deinit_hook(gnutls_session_t session)
 }
 
 
-int main(void)
-{
-        DRing::init(DRing::InitFlag(DRing::DRING_FLAG_DEBUG | DRing::DRING_FLAG_CONSOLE_LOG));
-
-        if (not jami::Manager::instance().initialized) {
-            assert(DRing::start("dring-sample.yml"));
-        }
-
-        auto actors = load_actors_and_wait_for_announcement("actors/alice-bob.yml");
-
-        auto alice = actors["alice"];
-        auto bob   = actors["bob"];
-
-        auto aliceAccount = jami::Manager::instance().getAccount<jami::JamiAccount>(alice);
-        auto bobAccount   = jami::Manager::instance().getAccount<jami::JamiAccount>(bob);
-
-        auto aliceUri = aliceAccount->getUsername();
-        auto bobUri   = bobAccount->getUsername();
-
-        std::map<std::string, std::shared_ptr<DRing::CallbackWrapperBase>> confHandlers;
-        std::atomic_bool callReceived {false};
-        std::mutex mtx;
-        std::unique_lock<std::mutex> lk {mtx};
-        std::condition_variable cv;
-
-        confHandlers.insert(DRing::exportable_callback<DRing::CallSignal::IncomingCall>(
-                                    [&](const std::string&, const std::string&, const std::string&) {
-                                            callReceived = true;
-                                            cv.notify_one();
-                                    }));
-
-        DRing::registerSignalHandlers(confHandlers);
-
-        auto call = aliceAccount->newOutgoingCall(bobUri);
-
-        assert(cv.wait_for(lk, std::chrono::seconds(30), [&] { return callReceived.load(); }));
-
-        std::this_thread::sleep_for(std::chrono::seconds(60));
-
-        wait_for_removal_of({alice, bob});
-
-        DRing::fini();
-
-        return 0;
-}
+#include "scenarios/classic-alice-and-bob.h"
diff --git a/test/fuzzing/scenarios/classic-alice-and-bob.h b/test/fuzzing/scenarios/classic-alice-and-bob.h
new file mode 100644
index 0000000000000000000000000000000000000000..f94d9de6a81efaa48241003c89367dcbcef5eee6
--- /dev/null
+++ b/test/fuzzing/scenarios/classic-alice-and-bob.h
@@ -0,0 +1,75 @@
+/*
+ *  Copyright (C) 2021 Savoir-faire Linux Inc.
+ *
+ *  Author: Olivier Dion <olivier.dion>@savoirfairelinux.com>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
+ */
+
+#include <condition_variable>
+
+#include "manager.h"
+#include "jamidht/connectionmanager.h"
+#include "jamidht/jamiaccount.h"
+#include "dring.h"
+#include "account_const.h"
+
+#include "lib/utils.h"
+
+int main(void)
+{
+        DRing::init(DRing::InitFlag(DRing::DRING_FLAG_DEBUG | DRing::DRING_FLAG_CONSOLE_LOG));
+
+        if (not jami::Manager::instance().initialized) {
+            assert(DRing::start("dring-sample.yml"));
+        }
+
+        auto actors = load_actors_and_wait_for_announcement("actors/alice-bob.yml");
+
+        auto alice = actors["alice"];
+        auto bob   = actors["bob"];
+
+        auto aliceAccount = jami::Manager::instance().getAccount<jami::JamiAccount>(alice);
+        auto bobAccount   = jami::Manager::instance().getAccount<jami::JamiAccount>(bob);
+
+        auto aliceUri = aliceAccount->getUsername();
+        auto bobUri   = bobAccount->getUsername();
+
+        std::map<std::string, std::shared_ptr<DRing::CallbackWrapperBase>> confHandlers;
+        std::atomic_bool callReceived {false};
+        std::mutex mtx;
+        std::unique_lock<std::mutex> lk {mtx};
+        std::condition_variable cv;
+
+        confHandlers.insert(DRing::exportable_callback<DRing::CallSignal::IncomingCall>(
+                                    [&](const std::string&, const std::string&, const std::string&) {
+                                            callReceived = true;
+                                            cv.notify_one();
+                                    }));
+
+        DRing::registerSignalHandlers(confHandlers);
+
+        auto call = aliceAccount->newOutgoingCall(bobUri);
+
+        assert(cv.wait_for(lk, std::chrono::seconds(30), [&] { return callReceived.load(); }));
+
+        std::this_thread::sleep_for(std::chrono::seconds(60));
+
+        wait_for_removal_of({alice, bob});
+
+        DRing::fini();
+
+        return 0;
+}