loolwsd/Makefile.am         |    2 
 loolwsd/test/Makefile.am    |    2 
 loolwsd/test/httpwstest.cpp |  122 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 124 insertions(+), 2 deletions(-)

New commits:
commit 575e09307675c68f95ccea17dacfe04894601606
Author: Ashod Nakashian <ashod.nakash...@collabora.co.uk>
Date:   Thu Apr 28 17:02:45 2016 -0400

    loolwsd: editlock and takeedit tests
    
    Change-Id: Ie2458aed1da0624f1769b6b75f134cb0fed0db75
    Reviewed-on: https://gerrit.libreoffice.org/24475
    Reviewed-by: Ashod Nakashian <ashnak...@gmail.com>
    Tested-by: Ashod Nakashian <ashnak...@gmail.com>

diff --git a/loolwsd/Makefile.am b/loolwsd/Makefile.am
index 8c34c85..5ba1681 100644
--- a/loolwsd/Makefile.am
+++ b/loolwsd/Makefile.am
@@ -49,7 +49,7 @@ loolwsd_SOURCES = Admin.cpp \
 
 noinst_PROGRAMS = connect \
                   lokitclient \
-                 loolforkit-nocaps
+                  loolforkit-nocaps
 
 connect_SOURCES = Connect.cpp \
                   Log.cpp \
diff --git a/loolwsd/test/Makefile.am b/loolwsd/test/Makefile.am
index 4a7663b..7c26f38 100644
--- a/loolwsd/test/Makefile.am
+++ b/loolwsd/test/Makefile.am
@@ -10,7 +10,7 @@ noinst_LTLIBRARIES = \
         unit-admin.la
 
 MAGIC_TO_FORCE_SHLIB_CREATION = -rpath /dummy
-AM_LDFLAGS = -module $(MAGIC_TO_FORCE_SHLIB_CREATION)
+AM_LDFLAGS = -pthread -module $(MAGIC_TO_FORCE_SHLIB_CREATION)
 AM_CPPFLAGS = -pthread -I$(top_srcdir)
 
 test_CPPFLAGS = -DTDOC=\"$(top_srcdir)/test/data\"
diff --git a/loolwsd/test/httpwstest.cpp b/loolwsd/test/httpwstest.cpp
index 9f9d9b0..c594c0d 100644
--- a/loolwsd/test/httpwstest.cpp
+++ b/loolwsd/test/httpwstest.cpp
@@ -10,6 +10,9 @@
 #include "config.h"
 
 #include <algorithm>
+#include <condition_variable>
+#include <mutex>
+#include <thread>
 #include <regex>
 
 #include <Poco/DirectoryIterator.h>
@@ -71,6 +74,7 @@ class HTTPWSTest : public CPPUNIT_NS::TestFixture
     CPPUNIT_TEST(testPasswordProtectedDocumentWithCorrectPassword);
     CPPUNIT_TEST(testPasswordProtectedDocumentWithCorrectPasswordAgain);
     CPPUNIT_TEST(testInsertDelete);
+    CPPUNIT_TEST(testEditLock);
     CPPUNIT_TEST(testClientPartImpress);
     CPPUNIT_TEST(testClientPartCalc);
 #if ENABLE_DEBUG
@@ -104,6 +108,7 @@ class HTTPWSTest : public CPPUNIT_NS::TestFixture
     void testClientPartCalc();
     void testSimultaneousTilesRenderedJustOnce();
     void testNoExtraLoolKitsLeft();
+    void testEditLock();
 
     void loadDoc(const std::string& documentURL);
 
@@ -1130,6 +1135,123 @@ void HTTPWSTest::testSimultaneousTilesRenderedJustOnce()
     socket2.shutdown();
 }
 
+void HTTPWSTest::testEditLock()
+{
+    const std::string documentPath = Util::getTempFilePath(TDOC, "hello.odt");
+    const std::string documentURL = "file://" + 
Poco::Path(documentPath).makeAbsolute().toString();
+
+    std::mutex mutex;
+    std::condition_variable cv;
+    volatile bool second_client_died = false;
+
+    // The first client loads the document and checks that it has the lock.
+    // It then waits until the lock is taken away.
+    std::thread first_client([&]()
+        {
+            try
+            {
+                std::cerr << "First client loading." << std::endl;
+                auto socket = loadDocAndGetSocket(documentURL);
+                std::string editlock1;
+                SocketProcessor("First", socket, [&](const std::string& msg)
+                        {
+                            if (msg.find("editlock") == 0)
+                            {
+                                if (editlock1.empty())
+                                {
+                                    std::cerr << "First client has the lock." 
<< std::endl;
+                                    
CPPUNIT_ASSERT_EQUAL(std::string("editlock: 1"), msg);
+                                    editlock1 = msg;
+
+                                    // Initial condition met, connect second 
client.
+                                    std::cerr << "Starting second client." << 
std::endl;
+                                    cv.notify_one();
+                                }
+                                else if (editlock1 == "editlock: 1")
+                                {
+                                    if (second_client_died)
+                                    {
+                                        // We had lost the lock to the second 
client,
+                                        // but we should get it back once they 
die.
+                                        std::cerr << "First client is given 
the lock." << std::endl;
+                                        
CPPUNIT_ASSERT_EQUAL(std::string("editlock: 1"), msg);
+                                        return false; // Done!
+                                    }
+                                    else
+                                    {
+                                        // Normal broadcast when the second 
client joins.
+                                        std::cerr << "First client still has 
the lock." << std::endl;
+                                    }
+                                }
+                                else
+                                {
+                                    // Another client took the lock.
+                                    std::cerr << "First client lost the lock." 
<< std::endl;
+                                    
CPPUNIT_ASSERT_EQUAL(std::string("editlock: 0"), msg);
+                                }
+                            }
+
+                            return true;
+                        });
+
+                std::cerr << "First client out." << std::endl;
+                socket->shutdown();
+            }
+            catch (const Poco::Exception& exc)
+            {
+                CPPUNIT_FAIL(exc.displayText());
+            }
+        });
+
+    std::unique_lock<std::mutex> lock(mutex);
+    cv.wait(lock);
+
+    // The second client loads the document and checks that it has no lock.
+    // It then takes the lock and breaks when it gets it.
+    try
+    {
+        std::cerr << "Second client loading." << std::endl;
+        auto socket = loadDocAndGetSocket(documentURL);
+        std::string editlock1;
+        SocketProcessor("Second", socket, [&](const std::string& msg)
+                {
+                    if (msg.find("editlock") == 0)
+                    {
+                        if (editlock1.empty())
+                        {
+                            // We shouldn't have it.
+                            std::cerr << "Second client doesn't have the 
lock." << std::endl;
+                            CPPUNIT_ASSERT_EQUAL(std::string("editlock: 0"), 
msg);
+                            editlock1 = msg;
+
+                            // But we will take it.
+                            std::cerr << "Second client taking lock." << 
std::endl;
+                            sendTextFrame(*socket, "takeedit");
+                        }
+                        else
+                        {
+                            // Now it should be ours.
+                            std::cerr << "Second client took the lock." << 
std::endl;
+                            CPPUNIT_ASSERT_EQUAL(std::string("editlock: 1"), 
msg);
+                            return false;
+                        }
+                    }
+
+                    return true;
+                });
+
+        std::cerr << "Second client out." << std::endl;
+        socket->shutdown();
+        second_client_died = true;
+
+        first_client.join();
+    }
+    catch (const Poco::Exception& exc)
+    {
+        CPPUNIT_FAIL(exc.displayText());
+    }
+}
+
 void HTTPWSTest::testNoExtraLoolKitsLeft()
 {
     int countNow = countLoolKitProcesses();
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to