2016-04-28 20:41:00 -05:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
|
|
|
|
/*
|
|
|
|
* This file is part of the LibreOffice project.
|
|
|
|
*
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
*/
|
|
|
|
|
2017-02-07 10:16:59 -06:00
|
|
|
#ifndef INCLUDED_TEST_HELPERS_HPP
|
|
|
|
#define INCLUDED_TEST_HELPERS_HPP
|
|
|
|
|
2017-04-16 22:31:03 -05:00
|
|
|
#include <iterator>
|
2016-04-28 20:41:00 -05:00
|
|
|
|
2016-09-28 15:04:51 -05:00
|
|
|
#include <Poco/BinaryReader.h>
|
2017-05-01 23:01:28 -05:00
|
|
|
#include <Poco/Dynamic/Var.h>
|
|
|
|
#include <Poco/JSON/JSON.h>
|
|
|
|
#include <Poco/JSON/Parser.h>
|
2016-04-28 20:41:00 -05:00
|
|
|
#include <Poco/Net/HTTPClientSession.h>
|
|
|
|
#include <Poco/Net/HTTPRequest.h>
|
|
|
|
#include <Poco/Net/HTTPResponse.h>
|
|
|
|
#include <Poco/Net/HTTPSClientSession.h>
|
|
|
|
#include <Poco/Net/NetException.h>
|
2019-05-22 04:54:36 -05:00
|
|
|
#include <Poco/Net/StreamSocket.h>
|
|
|
|
#include <Poco/Net/SecureStreamSocket.h>
|
2016-04-28 20:41:00 -05:00
|
|
|
#include <Poco/Net/Socket.h>
|
|
|
|
#include <Poco/Path.h>
|
|
|
|
#include <Poco/URI.h>
|
2017-04-16 22:31:03 -05:00
|
|
|
|
2016-05-01 10:20:41 -05:00
|
|
|
#include <cppunit/extensions/HelperMacros.h>
|
2016-04-28 20:41:00 -05:00
|
|
|
|
|
|
|
#include <Common.hpp>
|
2016-11-12 15:38:13 -06:00
|
|
|
#include "common/FileUtil.hpp"
|
2016-11-10 02:47:25 -06:00
|
|
|
#include <LOOLWebSocket.hpp>
|
2016-04-28 20:41:00 -05:00
|
|
|
#include <Util.hpp>
|
|
|
|
|
2016-07-31 10:17:06 -05:00
|
|
|
#ifndef TDOC
|
2016-09-15 13:02:32 -05:00
|
|
|
#error TDOC must be defined (see Makefile.am)
|
2016-07-31 10:17:06 -05:00
|
|
|
#endif
|
|
|
|
|
2019-03-04 15:02:59 -06:00
|
|
|
// Oh dear std::cerr and/or its re-direction is not
|
|
|
|
// necessarily thread safe on Linux
|
|
|
|
#ifdef TST_LOG_REDIRECT
|
|
|
|
void tstLog(const std::ostringstream &stream);
|
|
|
|
#else
|
|
|
|
inline void tstLog(const std::ostringstream &stream)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "%s", stream.str().c_str());
|
|
|
|
}
|
|
|
|
#endif
|
2019-10-12 12:51:56 -05:00
|
|
|
#define TST_LOG_NAME_BEGIN(NAME, X) do { \
|
|
|
|
char t[64]; Poco::DateTime time; snprintf(t, sizeof(t), "%.2u:%.2u:%.2u.%.6u (@%lums) ", \
|
|
|
|
time.hour(), time.minute(), time.second(), time.millisecond() * 1000 + time.microsecond(), helpers::timeSinceTestStartMs()); \
|
|
|
|
std::ostringstream str; str << NAME << t << X; tstLog(str); } while (false)
|
2018-01-22 08:11:43 -06:00
|
|
|
#define TST_LOG_BEGIN(X) TST_LOG_NAME_BEGIN(testname, X)
|
2019-03-04 15:02:59 -06:00
|
|
|
#define TST_LOG_APPEND(X) do { std::ostringstream str; str << X; tstLog(str); } while (false)
|
|
|
|
#define TST_LOG_END do { std::ostringstream str; str << "| " << __FILE__ << ':' << __LINE__ << std::endl; tstLog(str); } while (false)
|
2018-01-22 08:11:43 -06:00
|
|
|
#define TST_LOG_NAME(NAME, X) TST_LOG_NAME_BEGIN(NAME, X); TST_LOG_END
|
|
|
|
#define TST_LOG(X) TST_LOG_NAME(testname, X)
|
|
|
|
|
test: improve stability of a number of tests
There are numerous race conditions between issuing
action and getting the events. This causes a
mismatch, such that the events from SelectAll
is received when waiting for the events for a
subsequent action (say, Delete).
To make matters worse, sometimes Core issues
an invalidation whilst sending the events for
an action, and this completely messes our
accounting of what events we expect.
This latter could also be an issue with real
clients, however it's less likely to be
disruptive. Still, it is possible that
the client doesn't get key events
because Core had a hiccup, which breaks
the tests.
For the tests at least, the solution is to
re-issue the last action, such that we make
sure that we move forward only when the correct
event is received, or we timeout waiting.
The end results is that tests now don't fail
nearly as often as they used to.
Reviewed-on: https://gerrit.libreoffice.org/80894
Reviewed-by: Andras Timar <andras.timar@collabora.com>
Tested-by: Andras Timar <andras.timar@collabora.com>
(cherry picked from commit 050403daf04d6b36ef850006ba4a15eab6be9afc)
Change-Id: Ib1a658846061990649987ca083915a49c1fb092a
Reviewed-on: https://gerrit.libreoffice.org/81565
Reviewed-by: Ashod Nakashian <ashnakash@gmail.com>
Tested-by: Ashod Nakashian <ashnakash@gmail.com>
2019-10-12 12:47:38 -05:00
|
|
|
// Sometimes we need to retry some commands as they can (due to timing or load) soft-fail.
|
|
|
|
constexpr int COMMAND_RETRY_COUNT = 5;
|
|
|
|
|
2016-04-28 20:41:00 -05:00
|
|
|
/// Common helper testing functions.
|
|
|
|
/// Avoid the temptation to reuse from LOOL code!
|
|
|
|
/// These are supposed to be testing the latter.
|
|
|
|
namespace helpers
|
|
|
|
{
|
2018-01-22 08:11:43 -06:00
|
|
|
inline
|
|
|
|
std::chrono::time_point<std::chrono::steady_clock>& getTestStartTime()
|
|
|
|
{
|
|
|
|
static auto TestStartTime = std::chrono::steady_clock::now();
|
|
|
|
|
|
|
|
return TestStartTime;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline
|
|
|
|
void resetTestStartTime()
|
|
|
|
{
|
|
|
|
getTestStartTime() = std::chrono::steady_clock::now();
|
|
|
|
}
|
|
|
|
|
|
|
|
inline
|
|
|
|
size_t timeSinceTestStartMs()
|
|
|
|
{
|
|
|
|
return std::chrono::duration_cast<std::chrono::milliseconds>(
|
|
|
|
std::chrono::steady_clock::now() - getTestStartTime()).count();
|
|
|
|
}
|
|
|
|
|
2016-11-05 16:25:39 -05:00
|
|
|
inline
|
|
|
|
std::vector<char> genRandomData(const size_t size)
|
|
|
|
{
|
|
|
|
std::vector<char> v(size);
|
|
|
|
v.resize(size);
|
2018-02-07 03:17:42 -06:00
|
|
|
char* data = v.data();
|
2016-11-05 16:25:39 -05:00
|
|
|
for (size_t i = 0; i < size; ++i)
|
|
|
|
{
|
|
|
|
data[i] = static_cast<char>(Util::rng::getNext());
|
|
|
|
}
|
|
|
|
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
2016-11-05 16:26:39 -05:00
|
|
|
inline
|
|
|
|
std::string genRandomString(const size_t size)
|
|
|
|
{
|
|
|
|
std::string text;
|
|
|
|
text.reserve(size);
|
|
|
|
for (size_t i = 0; i < size; ++i)
|
|
|
|
{
|
|
|
|
text += static_cast<char>('!' + Util::rng::getNext() % 95);
|
|
|
|
}
|
|
|
|
|
|
|
|
return text;
|
|
|
|
}
|
|
|
|
|
2016-06-13 19:31:14 -05:00
|
|
|
inline
|
|
|
|
std::vector<char> readDataFromFile(const std::string& filename)
|
|
|
|
{
|
2016-07-06 22:23:43 -05:00
|
|
|
std::ifstream ifs(Poco::Path(TDOC, filename).toString(), std::ios::binary);
|
|
|
|
|
|
|
|
// Apparently std::ios::binary is not good
|
|
|
|
// enough to stop eating new-line chars!
|
|
|
|
ifs.unsetf(std::ios::skipws);
|
2016-06-13 19:31:14 -05:00
|
|
|
|
|
|
|
std::istream_iterator<char> start(ifs);
|
|
|
|
std::istream_iterator<char> end;
|
|
|
|
return std::vector<char>(start, end);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline
|
|
|
|
std::vector<char> readDataFromFile(std::unique_ptr<std::fstream>& file)
|
|
|
|
{
|
|
|
|
file->seekg(0, std::ios_base::end);
|
|
|
|
const std::streamsize size = file->tellg();
|
|
|
|
|
|
|
|
std::vector<char> v;
|
|
|
|
v.resize(size);
|
|
|
|
|
|
|
|
file->seekg(0, std::ios_base::beg);
|
|
|
|
file->read(v.data(), size);
|
|
|
|
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
test: thread-safe common shared test data
This protects against memory corruptions,
and a cascade of issues, such as the following:
Attaching to process 56245
[New LWP 56246]
[New LWP 56252]
[New LWP 56253]
[New LWP 56254]
[New LWP 56362]
[New LWP 56364]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
0x00007fda228f7d2d in __GI___pthread_timedjoin_ex (threadid=140574279595776, thread_return=0x0, abstime=0x0, block=<optimized out>) at pthread_join_common.c:89
89 pthread_join_common.c: No such file or directory.
Thread 7 (Thread 0x7fda197fa700 (LWP 56364)):
#0 __lll_lock_wait () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
#1 0x00007fda228f9023 in __GI___pthread_mutex_lock (mutex=0x55e9937567e0 <SigHandlerTrap>) at ../nptl/pthread_mutex_lock.c:78
#2 0x000055e9934cd4fe in __gthread_mutex_lock (__mutex=0x55e9937567e0 <SigHandlerTrap>) at /usr/include/x86_64-linux-gnu/c++/7/bits/gthr-default.h:748
#3 std::mutex::lock (this=0x55e9937567e0 <SigHandlerTrap>) at /usr/include/c++/7/bits/std_mutex.h:103
#4 std::unique_lock<std::mutex>::lock (this=<synthetic pointer>) at /usr/include/c++/7/bits/std_mutex.h:267
#5 std::unique_lock<std::mutex>::unique_lock (__m=..., this=<synthetic pointer>) at /usr/include/c++/7/bits/std_mutex.h:197
#6 SigUtil::handleFatalSignal (signal=11) at common/SigUtil.cpp:214
#7 <signal handler called>
#8 std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_capacity (this=<optimized out>, __capacity=0) at /usr/include/c++/7/bits/basic_string.h:200
#9 std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string (__str=..., this=<optimized out>) at /usr/include/c++/7/bits/basic_string.h:542
#10 std::_Construct<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > (
__p=<optimized out>) at /usr/include/c++/7/bits/stl_construct.h:75
#11 std::__uninitialized_copy<false>::__uninit_copy<std::move_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*> (__result=0x7fd9f40017b0, __last=..., __first=...) at /usr/include/c++/7/bits/stl_uninitialized.h:83
#12 std::uninitialized_copy<std::move_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*> (__result=<optimized out>, __last=..., __first=...) at /usr/include/c++/7/bits/stl_uninitialized.h:134
#13 std::__uninitialized_copy_a<std::move_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > (__result=<optimized out>, __last=..., __first=...)
at /usr/include/c++/7/bits/stl_uninitialized.h:289
#14 std::__uninitialized_move_if_noexcept_a<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > (__alloc=..., __result=<optimized out>, __last=0x55e995662850,
__first=<optimized out>) at /usr/include/c++/7/bits/stl_uninitialized.h:312
#15 std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::_M_realloc_insert<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&> (
this=this@entry=0x55e9937566f0 <FileUtil::getTempFilePath(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::fileDeleter>,
__position=<error: Cannot access memory at address 0x3735003238323a>, __args#0="/tmp/loadTorture_viewcursor.odp_725a6013_viewcursor.odp") at /usr/include/c++/7/bits/vector.tcc:424
#16 0x000055e9934aa829 in std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::push_back (__x="/tmp/loadTorture_viewcursor.odp_725a6013_viewcursor.odp",
this=0x55e9937566f0 <FileUtil::getTempFilePath(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::fileDeleter>) at /usr/include/c++/7/bits/stl_vector.h:948
#17 (anonymous namespace)::FileDeleter::registerForDeletion (file="/tmp/loadTorture_viewcursor.odp_725a6013_viewcursor.odp",
this=0x55e9937566f0 <FileUtil::getTempFilePath(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::fileDeleter>) at common/FileUtil.cpp:69
#18 FileUtil::getTempFilePath (srcDir=..., srcFilename=..., dstFilenamePrefix=...) at common/FileUtil.cpp:97
#19 0x00007fda216b51c9 in helpers::getDocumentPathAndURL (docFilename="viewcursor.odp", documentPath="", documentURL="", prefix="loadTorture_viewcursor.odp_") at ./helpers.hpp:151
#20 0x00007fda216ad007 in UnitLoadTorture::loadTorture (this=<optimized out>, testname="loadTorture_viewcursor.odp ", docName="viewcursor.odp", thread_count=thread_count@entry=3,
max_jitter_ms=<optimized out>, max_jitter_ms@entry=75) at UnitLoadTorture.cpp:41
#21 0x00007fda216ad7dd in UnitLoadTorture::<lambda()>::operator() (__closure=0x55e994dbc758) at UnitLoadTorture.cpp:186
#22 std::__invoke_impl<void, UnitLoadTorture::testLoadTorture()::<lambda()> > (__f=...) at /usr/include/c++/7/bits/invoke.h:60
#23 std::__invoke<UnitLoadTorture::testLoadTorture()::<lambda()> > (__fn=...) at /usr/include/c++/7/bits/invoke.h:95
#24 std::thread::_Invoker<std::tuple<UnitLoadTorture::testLoadTorture()::<lambda()> > >::_M_invoke<0> (this=0x55e994dbc758) at /usr/include/c++/7/thread:234
#25 std::thread::_Invoker<std::tuple<UnitLoadTorture::testLoadTorture()::<lambda()> > >::operator() (this=0x55e994dbc758) at /usr/include/c++/7/thread:243
#26 std::thread::_State_impl<std::thread::_Invoker<std::tuple<UnitLoadTorture::testLoadTorture()::<lambda()> > > >::_M_run(void) (this=0x55e994dbc750) at /usr/include/c++/7/thread:186
#27 0x00007fda22de366f in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#28 0x00007fda228f66db in start_thread (arg=0x7fda197fa700) at pthread_create.c:463
#29 0x00007fda2261f88f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
Thread 6 (Thread 0x7fd9fffff700 (LWP 56362)):
#0 __lll_lock_wait_private () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:95
#1 0x00007fda225952db in __GI___libc_malloc (bytes=bytes@entry=3635) at malloc.c:3063
#2 0x00007fda2262f364 in __backtrace_symbols (array=array@entry=0x7fd9ffffc540, size=size@entry=26) at backtracesyms.c:69
#3 0x000055e9934cc439 in SigUtil::dumpBacktrace () at common/SigUtil.cpp:253
#4 0x000055e9934cd5ae in SigUtil::handleFatalSignal (signal=6) at common/SigUtil.cpp:236
#5 <signal handler called>
#6 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#7 0x00007fda2253e801 in __GI_abort () at abort.c:79
#8 0x00007fda22587897 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7fda226b4b9a "%s
") at ../sysdeps/posix/libc_fatal.c:181
#9 0x00007fda2258e90a in malloc_printerr (str=str@entry=0x7fda226b2e0e "malloc(): memory corruption") at malloc.c:5350
#10 0x00007fda22592994 in _int_malloc (av=av@entry=0x7fda00000020, bytes=bytes@entry=32) at malloc.c:3738
#11 0x00007fda225952ed in __GI___libc_malloc (bytes=32) at malloc.c:3065
#12 0x00007fda22db9258 in operator new(unsigned long) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#13 0x00007fda244adaae in __gnu_cxx::new_allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::allocate (this=0x7fd9ffffe740, __n=1)
at /usr/include/c++/5/ext/new_allocator.h:104
#14 0x00007fda244ad300 in __gnu_cxx::__alloc_traits<std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::allocate (__a=..., __n=1)
at /usr/include/c++/5/ext/alloc_traits.h:182
#15 0x00007fda244ac858 in std::_Vector_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::_M_allocate (this=0x7fd9ffffe740, __n=1) at /usr/include/c++/5/bits/stl_vector.h:170
#16 0x00007fda244ab7c7 in std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::_M_insert_aux (this=0x7fd9ffffe740, __position=non-dereferenceable iterator for std::vector, __x="home") at /usr/include/c++/5/bits/vector.tcc:353
#17 0x00007fda244aada2 in std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::push_back (this=0x7fd9ffffe740, __x="home") at /usr/include/c++/5/bits/stl_vector.h:925
#18 0x00007fda2350ddcb in Poco::Path::pushDirectory (this=0x7fd9ffffe6c0, dir="home") at src/Path.cpp:471
#19 0x00007fda2350ea27 in Poco::Path::parseUnix (this=0x7fd9ffffe6c0, path="/home/ash/prj/lo/online/test/") at src/Path.cpp:671
#20 0x00007fda2350cd6b in Poco::Path::assign (this=0x7fd9ffffe6c0, path="/home/ash/prj/lo/online/test/") at src/Path.cpp:182
#21 0x00007fda2350c1be in Poco::Path::Path (this=0x7fd9ffffe6c0, path="/home/ash/prj/lo/online/test/") at src/Path.cpp:54
#22 0x00007fda2350d33a in Poco::Path::makeAbsolute (this=0x7fd9ffffe8f0) at src/Path.cpp:318
#23 0x00007fda216b52ca in helpers::getDocumentPathAndURL (docFilename="setclientpart.ods", documentPath="/tmp/loadTorture_setclientpart.ods_ae70d2e_setclientpart.ods", documentURL="",
prefix="loadTorture_setclientpart.ods_") at ./helpers.hpp:153
#24 0x00007fda216ad007 in UnitLoadTorture::loadTorture (this=<optimized out>, testname="loadTorture_setclientpart.ods ", docName="setclientpart.ods", thread_count=thread_count@entry=3,
max_jitter_ms=<optimized out>, max_jitter_ms@entry=75) at UnitLoadTorture.cpp:41
#25 0x00007fda216ad7dd in UnitLoadTorture::<lambda()>::operator() (__closure=0x55e994cffe18) at UnitLoadTorture.cpp:186
#26 std::__invoke_impl<void, UnitLoadTorture::testLoadTorture()::<lambda()> > (__f=...) at /usr/include/c++/7/bits/invoke.h:60
#27 std::__invoke<UnitLoadTorture::testLoadTorture()::<lambda()> > (__fn=...) at /usr/include/c++/7/bits/invoke.h:95
#28 std::thread::_Invoker<std::tuple<UnitLoadTorture::testLoadTorture()::<lambda()> > >::_M_invoke<0> (this=0x55e994cffe18) at /usr/include/c++/7/thread:234
#29 std::thread::_Invoker<std::tuple<UnitLoadTorture::testLoadTorture()::<lambda()> > >::operator() (this=0x55e994cffe18) at /usr/include/c++/7/thread:243
#30 std::thread::_State_impl<std::thread::_Invoker<std::tuple<UnitLoadTorture::testLoadTorture()::<lambda()> > > >::_M_run(void) (this=0x55e994cffe10) at /usr/include/c++/7/thread:186
#31 0x00007fda22de366f in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#32 0x00007fda228f66db in start_thread (arg=0x7fd9fffff700) at pthread_create.c:463
#33 0x00007fda2261f88f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
Change-Id: Ib60954e49e692082e686cb3fdc5fc9d5cfbc83c9
Reviewed-on: https://gerrit.libreoffice.org/83047
Reviewed-by: Michael Meeks <michael.meeks@collabora.com>
Tested-by: Michael Meeks <michael.meeks@collabora.com>
2019-11-17 19:32:54 -06:00
|
|
|
inline void getDocumentPathAndURL(const std::string& docFilename, std::string& documentPath,
|
|
|
|
std::string& documentURL, std::string prefix)
|
2016-04-28 20:41:00 -05:00
|
|
|
{
|
test: thread-safe common shared test data
This protects against memory corruptions,
and a cascade of issues, such as the following:
Attaching to process 56245
[New LWP 56246]
[New LWP 56252]
[New LWP 56253]
[New LWP 56254]
[New LWP 56362]
[New LWP 56364]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
0x00007fda228f7d2d in __GI___pthread_timedjoin_ex (threadid=140574279595776, thread_return=0x0, abstime=0x0, block=<optimized out>) at pthread_join_common.c:89
89 pthread_join_common.c: No such file or directory.
Thread 7 (Thread 0x7fda197fa700 (LWP 56364)):
#0 __lll_lock_wait () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
#1 0x00007fda228f9023 in __GI___pthread_mutex_lock (mutex=0x55e9937567e0 <SigHandlerTrap>) at ../nptl/pthread_mutex_lock.c:78
#2 0x000055e9934cd4fe in __gthread_mutex_lock (__mutex=0x55e9937567e0 <SigHandlerTrap>) at /usr/include/x86_64-linux-gnu/c++/7/bits/gthr-default.h:748
#3 std::mutex::lock (this=0x55e9937567e0 <SigHandlerTrap>) at /usr/include/c++/7/bits/std_mutex.h:103
#4 std::unique_lock<std::mutex>::lock (this=<synthetic pointer>) at /usr/include/c++/7/bits/std_mutex.h:267
#5 std::unique_lock<std::mutex>::unique_lock (__m=..., this=<synthetic pointer>) at /usr/include/c++/7/bits/std_mutex.h:197
#6 SigUtil::handleFatalSignal (signal=11) at common/SigUtil.cpp:214
#7 <signal handler called>
#8 std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_capacity (this=<optimized out>, __capacity=0) at /usr/include/c++/7/bits/basic_string.h:200
#9 std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string (__str=..., this=<optimized out>) at /usr/include/c++/7/bits/basic_string.h:542
#10 std::_Construct<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > (
__p=<optimized out>) at /usr/include/c++/7/bits/stl_construct.h:75
#11 std::__uninitialized_copy<false>::__uninit_copy<std::move_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*> (__result=0x7fd9f40017b0, __last=..., __first=...) at /usr/include/c++/7/bits/stl_uninitialized.h:83
#12 std::uninitialized_copy<std::move_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*> (__result=<optimized out>, __last=..., __first=...) at /usr/include/c++/7/bits/stl_uninitialized.h:134
#13 std::__uninitialized_copy_a<std::move_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > (__result=<optimized out>, __last=..., __first=...)
at /usr/include/c++/7/bits/stl_uninitialized.h:289
#14 std::__uninitialized_move_if_noexcept_a<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > (__alloc=..., __result=<optimized out>, __last=0x55e995662850,
__first=<optimized out>) at /usr/include/c++/7/bits/stl_uninitialized.h:312
#15 std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::_M_realloc_insert<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&> (
this=this@entry=0x55e9937566f0 <FileUtil::getTempFilePath(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::fileDeleter>,
__position=<error: Cannot access memory at address 0x3735003238323a>, __args#0="/tmp/loadTorture_viewcursor.odp_725a6013_viewcursor.odp") at /usr/include/c++/7/bits/vector.tcc:424
#16 0x000055e9934aa829 in std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::push_back (__x="/tmp/loadTorture_viewcursor.odp_725a6013_viewcursor.odp",
this=0x55e9937566f0 <FileUtil::getTempFilePath(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::fileDeleter>) at /usr/include/c++/7/bits/stl_vector.h:948
#17 (anonymous namespace)::FileDeleter::registerForDeletion (file="/tmp/loadTorture_viewcursor.odp_725a6013_viewcursor.odp",
this=0x55e9937566f0 <FileUtil::getTempFilePath(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::fileDeleter>) at common/FileUtil.cpp:69
#18 FileUtil::getTempFilePath (srcDir=..., srcFilename=..., dstFilenamePrefix=...) at common/FileUtil.cpp:97
#19 0x00007fda216b51c9 in helpers::getDocumentPathAndURL (docFilename="viewcursor.odp", documentPath="", documentURL="", prefix="loadTorture_viewcursor.odp_") at ./helpers.hpp:151
#20 0x00007fda216ad007 in UnitLoadTorture::loadTorture (this=<optimized out>, testname="loadTorture_viewcursor.odp ", docName="viewcursor.odp", thread_count=thread_count@entry=3,
max_jitter_ms=<optimized out>, max_jitter_ms@entry=75) at UnitLoadTorture.cpp:41
#21 0x00007fda216ad7dd in UnitLoadTorture::<lambda()>::operator() (__closure=0x55e994dbc758) at UnitLoadTorture.cpp:186
#22 std::__invoke_impl<void, UnitLoadTorture::testLoadTorture()::<lambda()> > (__f=...) at /usr/include/c++/7/bits/invoke.h:60
#23 std::__invoke<UnitLoadTorture::testLoadTorture()::<lambda()> > (__fn=...) at /usr/include/c++/7/bits/invoke.h:95
#24 std::thread::_Invoker<std::tuple<UnitLoadTorture::testLoadTorture()::<lambda()> > >::_M_invoke<0> (this=0x55e994dbc758) at /usr/include/c++/7/thread:234
#25 std::thread::_Invoker<std::tuple<UnitLoadTorture::testLoadTorture()::<lambda()> > >::operator() (this=0x55e994dbc758) at /usr/include/c++/7/thread:243
#26 std::thread::_State_impl<std::thread::_Invoker<std::tuple<UnitLoadTorture::testLoadTorture()::<lambda()> > > >::_M_run(void) (this=0x55e994dbc750) at /usr/include/c++/7/thread:186
#27 0x00007fda22de366f in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#28 0x00007fda228f66db in start_thread (arg=0x7fda197fa700) at pthread_create.c:463
#29 0x00007fda2261f88f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
Thread 6 (Thread 0x7fd9fffff700 (LWP 56362)):
#0 __lll_lock_wait_private () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:95
#1 0x00007fda225952db in __GI___libc_malloc (bytes=bytes@entry=3635) at malloc.c:3063
#2 0x00007fda2262f364 in __backtrace_symbols (array=array@entry=0x7fd9ffffc540, size=size@entry=26) at backtracesyms.c:69
#3 0x000055e9934cc439 in SigUtil::dumpBacktrace () at common/SigUtil.cpp:253
#4 0x000055e9934cd5ae in SigUtil::handleFatalSignal (signal=6) at common/SigUtil.cpp:236
#5 <signal handler called>
#6 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#7 0x00007fda2253e801 in __GI_abort () at abort.c:79
#8 0x00007fda22587897 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7fda226b4b9a "%s
") at ../sysdeps/posix/libc_fatal.c:181
#9 0x00007fda2258e90a in malloc_printerr (str=str@entry=0x7fda226b2e0e "malloc(): memory corruption") at malloc.c:5350
#10 0x00007fda22592994 in _int_malloc (av=av@entry=0x7fda00000020, bytes=bytes@entry=32) at malloc.c:3738
#11 0x00007fda225952ed in __GI___libc_malloc (bytes=32) at malloc.c:3065
#12 0x00007fda22db9258 in operator new(unsigned long) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#13 0x00007fda244adaae in __gnu_cxx::new_allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::allocate (this=0x7fd9ffffe740, __n=1)
at /usr/include/c++/5/ext/new_allocator.h:104
#14 0x00007fda244ad300 in __gnu_cxx::__alloc_traits<std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::allocate (__a=..., __n=1)
at /usr/include/c++/5/ext/alloc_traits.h:182
#15 0x00007fda244ac858 in std::_Vector_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::_M_allocate (this=0x7fd9ffffe740, __n=1) at /usr/include/c++/5/bits/stl_vector.h:170
#16 0x00007fda244ab7c7 in std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::_M_insert_aux (this=0x7fd9ffffe740, __position=non-dereferenceable iterator for std::vector, __x="home") at /usr/include/c++/5/bits/vector.tcc:353
#17 0x00007fda244aada2 in std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::push_back (this=0x7fd9ffffe740, __x="home") at /usr/include/c++/5/bits/stl_vector.h:925
#18 0x00007fda2350ddcb in Poco::Path::pushDirectory (this=0x7fd9ffffe6c0, dir="home") at src/Path.cpp:471
#19 0x00007fda2350ea27 in Poco::Path::parseUnix (this=0x7fd9ffffe6c0, path="/home/ash/prj/lo/online/test/") at src/Path.cpp:671
#20 0x00007fda2350cd6b in Poco::Path::assign (this=0x7fd9ffffe6c0, path="/home/ash/prj/lo/online/test/") at src/Path.cpp:182
#21 0x00007fda2350c1be in Poco::Path::Path (this=0x7fd9ffffe6c0, path="/home/ash/prj/lo/online/test/") at src/Path.cpp:54
#22 0x00007fda2350d33a in Poco::Path::makeAbsolute (this=0x7fd9ffffe8f0) at src/Path.cpp:318
#23 0x00007fda216b52ca in helpers::getDocumentPathAndURL (docFilename="setclientpart.ods", documentPath="/tmp/loadTorture_setclientpart.ods_ae70d2e_setclientpart.ods", documentURL="",
prefix="loadTorture_setclientpart.ods_") at ./helpers.hpp:153
#24 0x00007fda216ad007 in UnitLoadTorture::loadTorture (this=<optimized out>, testname="loadTorture_setclientpart.ods ", docName="setclientpart.ods", thread_count=thread_count@entry=3,
max_jitter_ms=<optimized out>, max_jitter_ms@entry=75) at UnitLoadTorture.cpp:41
#25 0x00007fda216ad7dd in UnitLoadTorture::<lambda()>::operator() (__closure=0x55e994cffe18) at UnitLoadTorture.cpp:186
#26 std::__invoke_impl<void, UnitLoadTorture::testLoadTorture()::<lambda()> > (__f=...) at /usr/include/c++/7/bits/invoke.h:60
#27 std::__invoke<UnitLoadTorture::testLoadTorture()::<lambda()> > (__fn=...) at /usr/include/c++/7/bits/invoke.h:95
#28 std::thread::_Invoker<std::tuple<UnitLoadTorture::testLoadTorture()::<lambda()> > >::_M_invoke<0> (this=0x55e994cffe18) at /usr/include/c++/7/thread:234
#29 std::thread::_Invoker<std::tuple<UnitLoadTorture::testLoadTorture()::<lambda()> > >::operator() (this=0x55e994cffe18) at /usr/include/c++/7/thread:243
#30 std::thread::_State_impl<std::thread::_Invoker<std::tuple<UnitLoadTorture::testLoadTorture()::<lambda()> > > >::_M_run(void) (this=0x55e994cffe10) at /usr/include/c++/7/thread:186
#31 0x00007fda22de366f in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#32 0x00007fda228f66db in start_thread (arg=0x7fd9fffff700) at pthread_create.c:463
#33 0x00007fda2261f88f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
Change-Id: Ib60954e49e692082e686cb3fdc5fc9d5cfbc83c9
Reviewed-on: https://gerrit.libreoffice.org/83047
Reviewed-by: Michael Meeks <michael.meeks@collabora.com>
Tested-by: Michael Meeks <michael.meeks@collabora.com>
2019-11-17 19:32:54 -06:00
|
|
|
const std::string testname = prefix;
|
|
|
|
|
|
|
|
static std::mutex lock;
|
|
|
|
std::unique_lock<std::mutex> guard(lock);
|
|
|
|
|
2017-01-05 21:46:00 -06:00
|
|
|
std::replace(prefix.begin(), prefix.end(), ' ', '_');
|
|
|
|
documentPath = FileUtil::getTempFilePath(TDOC, docFilename, prefix);
|
2016-09-29 12:20:52 -05:00
|
|
|
std::string encodedUri;
|
test: thread-safe common shared test data
This protects against memory corruptions,
and a cascade of issues, such as the following:
Attaching to process 56245
[New LWP 56246]
[New LWP 56252]
[New LWP 56253]
[New LWP 56254]
[New LWP 56362]
[New LWP 56364]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
0x00007fda228f7d2d in __GI___pthread_timedjoin_ex (threadid=140574279595776, thread_return=0x0, abstime=0x0, block=<optimized out>) at pthread_join_common.c:89
89 pthread_join_common.c: No such file or directory.
Thread 7 (Thread 0x7fda197fa700 (LWP 56364)):
#0 __lll_lock_wait () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
#1 0x00007fda228f9023 in __GI___pthread_mutex_lock (mutex=0x55e9937567e0 <SigHandlerTrap>) at ../nptl/pthread_mutex_lock.c:78
#2 0x000055e9934cd4fe in __gthread_mutex_lock (__mutex=0x55e9937567e0 <SigHandlerTrap>) at /usr/include/x86_64-linux-gnu/c++/7/bits/gthr-default.h:748
#3 std::mutex::lock (this=0x55e9937567e0 <SigHandlerTrap>) at /usr/include/c++/7/bits/std_mutex.h:103
#4 std::unique_lock<std::mutex>::lock (this=<synthetic pointer>) at /usr/include/c++/7/bits/std_mutex.h:267
#5 std::unique_lock<std::mutex>::unique_lock (__m=..., this=<synthetic pointer>) at /usr/include/c++/7/bits/std_mutex.h:197
#6 SigUtil::handleFatalSignal (signal=11) at common/SigUtil.cpp:214
#7 <signal handler called>
#8 std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_capacity (this=<optimized out>, __capacity=0) at /usr/include/c++/7/bits/basic_string.h:200
#9 std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string (__str=..., this=<optimized out>) at /usr/include/c++/7/bits/basic_string.h:542
#10 std::_Construct<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > (
__p=<optimized out>) at /usr/include/c++/7/bits/stl_construct.h:75
#11 std::__uninitialized_copy<false>::__uninit_copy<std::move_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*> (__result=0x7fd9f40017b0, __last=..., __first=...) at /usr/include/c++/7/bits/stl_uninitialized.h:83
#12 std::uninitialized_copy<std::move_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*> (__result=<optimized out>, __last=..., __first=...) at /usr/include/c++/7/bits/stl_uninitialized.h:134
#13 std::__uninitialized_copy_a<std::move_iterator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > (__result=<optimized out>, __last=..., __first=...)
at /usr/include/c++/7/bits/stl_uninitialized.h:289
#14 std::__uninitialized_move_if_noexcept_a<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > (__alloc=..., __result=<optimized out>, __last=0x55e995662850,
__first=<optimized out>) at /usr/include/c++/7/bits/stl_uninitialized.h:312
#15 std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::_M_realloc_insert<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&> (
this=this@entry=0x55e9937566f0 <FileUtil::getTempFilePath(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::fileDeleter>,
__position=<error: Cannot access memory at address 0x3735003238323a>, __args#0="/tmp/loadTorture_viewcursor.odp_725a6013_viewcursor.odp") at /usr/include/c++/7/bits/vector.tcc:424
#16 0x000055e9934aa829 in std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::push_back (__x="/tmp/loadTorture_viewcursor.odp_725a6013_viewcursor.odp",
this=0x55e9937566f0 <FileUtil::getTempFilePath(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::fileDeleter>) at /usr/include/c++/7/bits/stl_vector.h:948
#17 (anonymous namespace)::FileDeleter::registerForDeletion (file="/tmp/loadTorture_viewcursor.odp_725a6013_viewcursor.odp",
this=0x55e9937566f0 <FileUtil::getTempFilePath(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)::fileDeleter>) at common/FileUtil.cpp:69
#18 FileUtil::getTempFilePath (srcDir=..., srcFilename=..., dstFilenamePrefix=...) at common/FileUtil.cpp:97
#19 0x00007fda216b51c9 in helpers::getDocumentPathAndURL (docFilename="viewcursor.odp", documentPath="", documentURL="", prefix="loadTorture_viewcursor.odp_") at ./helpers.hpp:151
#20 0x00007fda216ad007 in UnitLoadTorture::loadTorture (this=<optimized out>, testname="loadTorture_viewcursor.odp ", docName="viewcursor.odp", thread_count=thread_count@entry=3,
max_jitter_ms=<optimized out>, max_jitter_ms@entry=75) at UnitLoadTorture.cpp:41
#21 0x00007fda216ad7dd in UnitLoadTorture::<lambda()>::operator() (__closure=0x55e994dbc758) at UnitLoadTorture.cpp:186
#22 std::__invoke_impl<void, UnitLoadTorture::testLoadTorture()::<lambda()> > (__f=...) at /usr/include/c++/7/bits/invoke.h:60
#23 std::__invoke<UnitLoadTorture::testLoadTorture()::<lambda()> > (__fn=...) at /usr/include/c++/7/bits/invoke.h:95
#24 std::thread::_Invoker<std::tuple<UnitLoadTorture::testLoadTorture()::<lambda()> > >::_M_invoke<0> (this=0x55e994dbc758) at /usr/include/c++/7/thread:234
#25 std::thread::_Invoker<std::tuple<UnitLoadTorture::testLoadTorture()::<lambda()> > >::operator() (this=0x55e994dbc758) at /usr/include/c++/7/thread:243
#26 std::thread::_State_impl<std::thread::_Invoker<std::tuple<UnitLoadTorture::testLoadTorture()::<lambda()> > > >::_M_run(void) (this=0x55e994dbc750) at /usr/include/c++/7/thread:186
#27 0x00007fda22de366f in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#28 0x00007fda228f66db in start_thread (arg=0x7fda197fa700) at pthread_create.c:463
#29 0x00007fda2261f88f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
Thread 6 (Thread 0x7fd9fffff700 (LWP 56362)):
#0 __lll_lock_wait_private () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:95
#1 0x00007fda225952db in __GI___libc_malloc (bytes=bytes@entry=3635) at malloc.c:3063
#2 0x00007fda2262f364 in __backtrace_symbols (array=array@entry=0x7fd9ffffc540, size=size@entry=26) at backtracesyms.c:69
#3 0x000055e9934cc439 in SigUtil::dumpBacktrace () at common/SigUtil.cpp:253
#4 0x000055e9934cd5ae in SigUtil::handleFatalSignal (signal=6) at common/SigUtil.cpp:236
#5 <signal handler called>
#6 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#7 0x00007fda2253e801 in __GI_abort () at abort.c:79
#8 0x00007fda22587897 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7fda226b4b9a "%s
") at ../sysdeps/posix/libc_fatal.c:181
#9 0x00007fda2258e90a in malloc_printerr (str=str@entry=0x7fda226b2e0e "malloc(): memory corruption") at malloc.c:5350
#10 0x00007fda22592994 in _int_malloc (av=av@entry=0x7fda00000020, bytes=bytes@entry=32) at malloc.c:3738
#11 0x00007fda225952ed in __GI___libc_malloc (bytes=32) at malloc.c:3065
#12 0x00007fda22db9258 in operator new(unsigned long) () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#13 0x00007fda244adaae in __gnu_cxx::new_allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::allocate (this=0x7fd9ffffe740, __n=1)
at /usr/include/c++/5/ext/new_allocator.h:104
#14 0x00007fda244ad300 in __gnu_cxx::__alloc_traits<std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::allocate (__a=..., __n=1)
at /usr/include/c++/5/ext/alloc_traits.h:182
#15 0x00007fda244ac858 in std::_Vector_base<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::_M_allocate (this=0x7fd9ffffe740, __n=1) at /usr/include/c++/5/bits/stl_vector.h:170
#16 0x00007fda244ab7c7 in std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::_M_insert_aux (this=0x7fd9ffffe740, __position=non-dereferenceable iterator for std::vector, __x="home") at /usr/include/c++/5/bits/vector.tcc:353
#17 0x00007fda244aada2 in std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::push_back (this=0x7fd9ffffe740, __x="home") at /usr/include/c++/5/bits/stl_vector.h:925
#18 0x00007fda2350ddcb in Poco::Path::pushDirectory (this=0x7fd9ffffe6c0, dir="home") at src/Path.cpp:471
#19 0x00007fda2350ea27 in Poco::Path::parseUnix (this=0x7fd9ffffe6c0, path="/home/ash/prj/lo/online/test/") at src/Path.cpp:671
#20 0x00007fda2350cd6b in Poco::Path::assign (this=0x7fd9ffffe6c0, path="/home/ash/prj/lo/online/test/") at src/Path.cpp:182
#21 0x00007fda2350c1be in Poco::Path::Path (this=0x7fd9ffffe6c0, path="/home/ash/prj/lo/online/test/") at src/Path.cpp:54
#22 0x00007fda2350d33a in Poco::Path::makeAbsolute (this=0x7fd9ffffe8f0) at src/Path.cpp:318
#23 0x00007fda216b52ca in helpers::getDocumentPathAndURL (docFilename="setclientpart.ods", documentPath="/tmp/loadTorture_setclientpart.ods_ae70d2e_setclientpart.ods", documentURL="",
prefix="loadTorture_setclientpart.ods_") at ./helpers.hpp:153
#24 0x00007fda216ad007 in UnitLoadTorture::loadTorture (this=<optimized out>, testname="loadTorture_setclientpart.ods ", docName="setclientpart.ods", thread_count=thread_count@entry=3,
max_jitter_ms=<optimized out>, max_jitter_ms@entry=75) at UnitLoadTorture.cpp:41
#25 0x00007fda216ad7dd in UnitLoadTorture::<lambda()>::operator() (__closure=0x55e994cffe18) at UnitLoadTorture.cpp:186
#26 std::__invoke_impl<void, UnitLoadTorture::testLoadTorture()::<lambda()> > (__f=...) at /usr/include/c++/7/bits/invoke.h:60
#27 std::__invoke<UnitLoadTorture::testLoadTorture()::<lambda()> > (__fn=...) at /usr/include/c++/7/bits/invoke.h:95
#28 std::thread::_Invoker<std::tuple<UnitLoadTorture::testLoadTorture()::<lambda()> > >::_M_invoke<0> (this=0x55e994cffe18) at /usr/include/c++/7/thread:234
#29 std::thread::_Invoker<std::tuple<UnitLoadTorture::testLoadTorture()::<lambda()> > >::operator() (this=0x55e994cffe18) at /usr/include/c++/7/thread:243
#30 std::thread::_State_impl<std::thread::_Invoker<std::tuple<UnitLoadTorture::testLoadTorture()::<lambda()> > > >::_M_run(void) (this=0x55e994cffe10) at /usr/include/c++/7/thread:186
#31 0x00007fda22de366f in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#32 0x00007fda228f66db in start_thread (arg=0x7fd9fffff700) at pthread_create.c:463
#33 0x00007fda2261f88f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
Change-Id: Ib60954e49e692082e686cb3fdc5fc9d5cfbc83c9
Reviewed-on: https://gerrit.libreoffice.org/83047
Reviewed-by: Michael Meeks <michael.meeks@collabora.com>
Tested-by: Michael Meeks <michael.meeks@collabora.com>
2019-11-17 19:32:54 -06:00
|
|
|
Poco::URI::encode("file://" + Poco::Path(documentPath).makeAbsolute().toString(), ":/?",
|
|
|
|
encodedUri);
|
2016-09-29 12:20:52 -05:00
|
|
|
documentURL = "lool/" + encodedUri + "/ws";
|
2018-01-22 08:11:43 -06:00
|
|
|
TST_LOG("Test file: " << documentPath);
|
2016-04-28 20:41:00 -05:00
|
|
|
}
|
|
|
|
|
2016-04-28 21:44:40 -05:00
|
|
|
inline
|
2018-02-11 12:16:42 -06:00
|
|
|
void sendTextFrame(LOOLWebSocket& socket, const std::string& string, const std::string& testname)
|
2016-04-28 20:41:00 -05:00
|
|
|
{
|
2017-02-08 04:46:11 -06:00
|
|
|
#ifndef FUZZER
|
2018-01-22 08:11:43 -06:00
|
|
|
TST_LOG("Sending " << string.size() << " bytes: " << LOOLProtocol::getAbbreviatedMessage(string));
|
2017-02-08 04:46:11 -06:00
|
|
|
#else
|
2018-01-22 08:11:43 -06:00
|
|
|
(void) testname;
|
2017-02-08 04:46:11 -06:00
|
|
|
#endif
|
2016-04-28 20:41:00 -05:00
|
|
|
socket.sendFrame(string.data(), string.size());
|
|
|
|
}
|
|
|
|
|
2016-05-08 23:39:01 -05:00
|
|
|
inline
|
2016-11-10 02:47:25 -06:00
|
|
|
void sendTextFrame(const std::shared_ptr<LOOLWebSocket>& socket, const std::string& string, const std::string& name = "")
|
2016-05-08 23:39:01 -05:00
|
|
|
{
|
2016-05-13 07:46:39 -05:00
|
|
|
sendTextFrame(*socket, string, name);
|
2016-05-08 23:39:01 -05:00
|
|
|
}
|
|
|
|
|
2016-05-02 05:26:48 -05:00
|
|
|
inline
|
|
|
|
Poco::Net::HTTPClientSession* createSession(const Poco::URI& uri)
|
|
|
|
{
|
|
|
|
#if ENABLE_SSL
|
2019-02-13 11:01:08 -06:00
|
|
|
if (uri.getScheme() == "https")
|
|
|
|
return new Poco::Net::HTTPSClientSession(uri.getHost(), uri.getPort());
|
2016-05-02 05:26:48 -05:00
|
|
|
#endif
|
2019-02-13 11:01:08 -06:00
|
|
|
return new Poco::Net::HTTPClientSession(uri.getHost(), uri.getPort());
|
2016-05-02 05:26:48 -05:00
|
|
|
}
|
2016-04-28 20:41:00 -05:00
|
|
|
|
2019-05-22 04:54:36 -05:00
|
|
|
inline int getClientPort()
|
2016-05-03 02:40:25 -05:00
|
|
|
{
|
2016-10-12 03:47:26 -05:00
|
|
|
static const char* clientPort = std::getenv("LOOL_TEST_CLIENT_PORT");
|
2019-05-22 04:54:36 -05:00
|
|
|
return clientPort? atoi(clientPort) : DEFAULT_CLIENT_PORT_NUMBER;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline std::shared_ptr<Poco::Net::StreamSocket> createRawSocket()
|
|
|
|
{
|
|
|
|
return
|
|
|
|
#if ENABLE_SSL
|
|
|
|
std::make_shared<Poco::Net::SecureStreamSocket>
|
|
|
|
#else
|
|
|
|
std::make_shared<Poco::Net::StreamSocket>
|
|
|
|
#endif
|
|
|
|
(Poco::Net::SocketAddress("127.0.0.1", getClientPort()));
|
|
|
|
}
|
2016-05-03 02:40:25 -05:00
|
|
|
|
2019-05-22 04:54:36 -05:00
|
|
|
inline
|
|
|
|
std::string const & getTestServerURI()
|
|
|
|
{
|
2016-05-03 02:40:25 -05:00
|
|
|
static std::string serverURI(
|
|
|
|
#if ENABLE_SSL
|
|
|
|
"https://127.0.0.1:"
|
|
|
|
#else
|
|
|
|
"http://127.0.0.1:"
|
|
|
|
#endif
|
2019-05-22 04:54:36 -05:00
|
|
|
+ std::to_string(getClientPort()));
|
2016-05-03 02:40:25 -05:00
|
|
|
|
|
|
|
return serverURI;
|
|
|
|
}
|
|
|
|
|
2016-09-28 15:04:51 -05:00
|
|
|
inline
|
2018-02-11 12:16:42 -06:00
|
|
|
int getErrorCode(LOOLWebSocket& ws, std::string& message, const std::string& testname)
|
2016-09-28 15:04:51 -05:00
|
|
|
{
|
|
|
|
int flags = 0;
|
|
|
|
int bytes = 0;
|
|
|
|
Poco::UInt16 statusCode = -1;
|
|
|
|
Poco::Buffer<char> buffer(READ_BUFFER_SIZE);
|
|
|
|
|
|
|
|
message.clear();
|
2017-01-15 11:15:11 -06:00
|
|
|
ws.setReceiveTimeout(Poco::Timespan(5000000));
|
2016-09-28 15:04:51 -05:00
|
|
|
do
|
|
|
|
{
|
2016-11-25 03:46:01 -06:00
|
|
|
bytes = ws.receiveFrame(buffer.begin(), READ_BUFFER_SIZE, flags);
|
2018-01-22 08:11:43 -06:00
|
|
|
TST_LOG("Got " << LOOLProtocol::getAbbreviatedFrameDump(buffer.begin(), bytes, flags));
|
2017-06-15 14:03:09 -05:00
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(POLL_TIMEOUT_MS));
|
2016-09-28 15:04:51 -05:00
|
|
|
}
|
2017-02-28 21:31:36 -06:00
|
|
|
while (bytes > 0 && (flags & Poco::Net::WebSocket::FRAME_OP_BITMASK) != Poco::Net::WebSocket::FRAME_OP_CLOSE);
|
2016-09-28 15:04:51 -05:00
|
|
|
|
|
|
|
if (bytes > 0)
|
|
|
|
{
|
|
|
|
Poco::MemoryBinaryReader reader(buffer, Poco::BinaryReader::NETWORK_BYTE_ORDER);
|
|
|
|
reader >> statusCode;
|
|
|
|
message.append(buffer.begin() + 2, bytes - 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
return statusCode;
|
|
|
|
}
|
|
|
|
|
2017-01-03 16:02:53 -06:00
|
|
|
inline
|
2018-02-11 12:16:42 -06:00
|
|
|
int getErrorCode(const std::shared_ptr<LOOLWebSocket>& ws, std::string& message, const std::string& testname)
|
2017-01-03 16:02:53 -06:00
|
|
|
{
|
2017-01-15 11:15:11 -06:00
|
|
|
return getErrorCode(*ws, message, testname);
|
2017-01-03 16:02:53 -06:00
|
|
|
}
|
|
|
|
|
2016-05-08 23:39:01 -05:00
|
|
|
inline
|
2018-02-11 12:16:42 -06:00
|
|
|
std::vector<char> getResponseMessage(LOOLWebSocket& ws, const std::string& prefix, const std::string& testname, const size_t timeoutMs = 10000)
|
2016-05-08 23:39:01 -05:00
|
|
|
{
|
2016-05-03 22:35:34 -05:00
|
|
|
try
|
|
|
|
{
|
2016-05-10 20:38:03 -05:00
|
|
|
int flags = 0;
|
2016-09-20 19:41:30 -05:00
|
|
|
int retries = timeoutMs / 500;
|
|
|
|
const Poco::Timespan waitTime(retries ? timeoutMs * 1000 / retries : timeoutMs * 1000);
|
2016-05-03 22:35:34 -05:00
|
|
|
std::vector<char> response;
|
|
|
|
|
2016-09-20 19:41:30 -05:00
|
|
|
bool timedout = false;
|
2016-05-03 22:35:34 -05:00
|
|
|
ws.setReceiveTimeout(0);
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if (ws.poll(waitTime, Poco::Net::Socket::SELECT_READ))
|
|
|
|
{
|
2016-09-20 19:41:30 -05:00
|
|
|
if (timedout)
|
|
|
|
{
|
2018-01-22 08:11:43 -06:00
|
|
|
TST_LOG_END;
|
2016-09-20 19:41:30 -05:00
|
|
|
timedout = false;
|
|
|
|
}
|
|
|
|
|
2017-04-02 23:45:40 -05:00
|
|
|
response.resize(READ_BUFFER_SIZE * 8);
|
2019-10-19 11:33:22 -05:00
|
|
|
const int bytes = ws.receiveFrame(response.data(), response.size(), flags);
|
2016-11-26 21:28:48 -06:00
|
|
|
response.resize(std::max(bytes, 0));
|
2016-10-21 11:59:03 -05:00
|
|
|
const auto message = LOOLProtocol::getFirstLine(response);
|
2016-05-03 22:35:34 -05:00
|
|
|
if (bytes > 0 && (flags & Poco::Net::WebSocket::FRAME_OP_BITMASK) != Poco::Net::WebSocket::FRAME_OP_CLOSE)
|
|
|
|
{
|
2016-10-21 11:59:03 -05:00
|
|
|
if (LOOLProtocol::matchPrefix(prefix, message))
|
2016-05-03 22:35:34 -05:00
|
|
|
{
|
2018-01-22 08:11:43 -06:00
|
|
|
TST_LOG("[" << prefix << "] Matched " <<
|
|
|
|
LOOLProtocol::getAbbreviatedFrameDump(response.data(), bytes, flags));
|
2016-05-03 22:35:34 -05:00
|
|
|
return response;
|
|
|
|
}
|
2016-11-25 03:48:59 -06:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
response.resize(0);
|
2016-05-03 22:35:34 -05:00
|
|
|
}
|
|
|
|
|
2016-05-12 09:54:21 -05:00
|
|
|
if (bytes <= 0)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
2016-09-11 13:29:09 -05:00
|
|
|
|
2016-09-19 05:53:14 -05:00
|
|
|
if ((flags & Poco::Net::WebSocket::FRAME_OP_BITMASK) != Poco::Net::WebSocket::FRAME_OP_CLOSE)
|
2016-09-20 19:41:30 -05:00
|
|
|
{
|
2016-10-21 21:02:15 -05:00
|
|
|
// Don't ignore errors.
|
|
|
|
if (LOOLProtocol::matchPrefix("error:", message))
|
|
|
|
{
|
|
|
|
throw std::runtime_error(message);
|
|
|
|
}
|
|
|
|
|
2018-01-22 08:11:43 -06:00
|
|
|
TST_LOG("[" << prefix << "] Ignored " <<
|
|
|
|
LOOLProtocol::getAbbreviatedFrameDump(response.data(), bytes, flags));
|
2016-09-20 19:41:30 -05:00
|
|
|
}
|
2016-05-03 22:35:34 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-09-20 19:41:30 -05:00
|
|
|
if (!timedout)
|
|
|
|
{
|
2018-01-22 08:11:43 -06:00
|
|
|
TST_LOG_BEGIN("Timeout (" << (retries > 1 ? "retrying" : "giving up") << ") ");
|
2016-09-20 19:41:30 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-01-22 08:11:43 -06:00
|
|
|
TST_LOG_APPEND(retries << ' ');
|
2016-09-20 19:41:30 -05:00
|
|
|
}
|
|
|
|
|
2016-05-03 22:35:34 -05:00
|
|
|
--retries;
|
2016-09-20 19:41:30 -05:00
|
|
|
timedout = true;
|
2016-05-03 22:35:34 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
while (retries > 0 && (flags & Poco::Net::WebSocket::FRAME_OP_BITMASK) != Poco::Net::WebSocket::FRAME_OP_CLOSE);
|
2016-10-21 11:59:03 -05:00
|
|
|
|
|
|
|
if (timedout)
|
|
|
|
{
|
2018-01-22 08:11:43 -06:00
|
|
|
TST_LOG_END;
|
2016-10-21 11:59:03 -05:00
|
|
|
}
|
2016-05-03 22:35:34 -05:00
|
|
|
}
|
|
|
|
catch (const Poco::Net::WebSocketException& exc)
|
|
|
|
{
|
2018-01-22 08:11:43 -06:00
|
|
|
TST_LOG_END;
|
|
|
|
TST_LOG(exc.message());
|
2016-05-03 22:35:34 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return std::vector<char>();
|
|
|
|
}
|
|
|
|
|
2016-05-08 23:39:01 -05:00
|
|
|
inline
|
2018-02-11 12:16:42 -06:00
|
|
|
std::vector<char> getResponseMessage(const std::shared_ptr<LOOLWebSocket>& ws, const std::string& prefix, const std::string& testname, const size_t timeoutMs = 10000)
|
2016-05-10 20:38:03 -05:00
|
|
|
{
|
2018-01-22 08:11:43 -06:00
|
|
|
return getResponseMessage(*ws, prefix, testname, timeoutMs);
|
2016-05-10 20:38:03 -05:00
|
|
|
}
|
|
|
|
|
2016-10-08 20:24:45 -05:00
|
|
|
template <typename T>
|
2018-02-11 12:16:42 -06:00
|
|
|
std::string getResponseString(T& ws, const std::string& prefix, const std::string& testname, const size_t timeoutMs = 10000)
|
2016-10-08 18:40:49 -05:00
|
|
|
{
|
2018-01-22 08:11:43 -06:00
|
|
|
const auto response = getResponseMessage(ws, prefix, testname, timeoutMs);
|
2016-10-08 18:40:49 -05:00
|
|
|
return std::string(response.data(), response.size());
|
|
|
|
}
|
|
|
|
|
2016-05-10 20:38:03 -05:00
|
|
|
template <typename T>
|
2018-08-13 02:26:09 -05:00
|
|
|
std::string assertResponseString(T& ws, const std::string& prefix, const std::string& testname)
|
2016-05-10 20:38:03 -05:00
|
|
|
{
|
2018-01-22 08:11:43 -06:00
|
|
|
const auto res = getResponseString(ws, prefix, testname);
|
2016-07-06 22:23:43 -05:00
|
|
|
CPPUNIT_ASSERT_EQUAL(prefix, res.substr(0, prefix.length()));
|
2016-05-13 12:46:13 -05:00
|
|
|
return res;
|
2016-05-10 20:38:03 -05:00
|
|
|
}
|
|
|
|
|
2016-08-30 22:15:44 -05:00
|
|
|
/// Assert that we don't get a response with the given prefix.
|
|
|
|
template <typename T>
|
2018-08-27 02:10:01 -05:00
|
|
|
std::string assertNotInResponse(T& ws, const std::string& prefix, const std::string& testname)
|
2016-08-30 22:15:44 -05:00
|
|
|
{
|
2018-01-22 08:11:43 -06:00
|
|
|
const auto res = getResponseString(ws, prefix, testname, 1000);
|
|
|
|
CPPUNIT_ASSERT_MESSAGE(testname + "Did not expect getting message [" + res + "].", res.empty());
|
2016-08-30 22:15:44 -05:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2019-10-19 11:33:22 -05:00
|
|
|
inline
|
|
|
|
int countMessages(LOOLWebSocket& ws, const std::string& prefix, const std::string& testname, const size_t timeoutMs = 10000)
|
|
|
|
{
|
|
|
|
int count = 0;
|
|
|
|
while (!getResponseMessage(ws, prefix, testname, timeoutMs).empty())
|
|
|
|
++count;
|
|
|
|
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline
|
|
|
|
int countMessages(const std::shared_ptr<LOOLWebSocket>& ws, const std::string& prefix, const std::string& testname, const size_t timeoutMs = 10000)
|
|
|
|
{
|
|
|
|
return countMessages(*ws, prefix, testname, timeoutMs);
|
|
|
|
}
|
|
|
|
|
2016-10-08 20:48:41 -05:00
|
|
|
inline
|
2018-02-11 12:16:42 -06:00
|
|
|
bool isDocumentLoaded(LOOLWebSocket& ws, const std::string& testname, bool isView = true)
|
2016-10-08 20:48:41 -05:00
|
|
|
{
|
|
|
|
const std::string prefix = isView ? "status:" : "statusindicatorfinish:";
|
2018-01-22 08:11:43 -06:00
|
|
|
const auto message = getResponseString(ws, prefix, testname);
|
2016-11-26 21:24:35 -06:00
|
|
|
return LOOLProtocol::matchPrefix(prefix, message);
|
2016-10-08 20:48:41 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
inline
|
2018-02-11 12:16:42 -06:00
|
|
|
bool isDocumentLoaded(std::shared_ptr<LOOLWebSocket>& ws, const std::string& testname, bool isView = true)
|
2016-10-08 20:48:41 -05:00
|
|
|
{
|
2018-01-22 08:11:43 -06:00
|
|
|
return isDocumentLoaded(*ws, testname, isView);
|
2016-10-08 20:48:41 -05:00
|
|
|
}
|
|
|
|
|
2016-05-10 20:38:03 -05:00
|
|
|
// Connecting to a Kit process is managed by document broker, that it does several
|
|
|
|
// jobs to establish the bridge connection between the Client and Kit process,
|
|
|
|
// The result, it is mostly time outs to get messages in the unit test and it could fail.
|
|
|
|
// connectLOKit ensures the websocket is connected to a kit process.
|
|
|
|
inline
|
2016-11-10 02:47:25 -06:00
|
|
|
std::shared_ptr<LOOLWebSocket>
|
2016-09-15 03:33:18 -05:00
|
|
|
connectLOKit(const Poco::URI& uri,
|
2016-05-10 20:38:03 -05:00
|
|
|
Poco::Net::HTTPRequest& request,
|
2016-05-13 07:46:39 -05:00
|
|
|
Poco::Net::HTTPResponse& response,
|
2018-02-11 12:16:42 -06:00
|
|
|
const std::string& testname)
|
2016-05-10 20:38:03 -05:00
|
|
|
{
|
2018-01-22 08:11:43 -06:00
|
|
|
TST_LOG_BEGIN("Connecting... ");
|
2016-05-10 20:38:03 -05:00
|
|
|
int retries = 10;
|
|
|
|
do
|
|
|
|
{
|
2016-11-15 15:22:02 -06:00
|
|
|
try
|
2016-11-12 12:25:35 -06:00
|
|
|
{
|
2016-11-15 15:22:02 -06:00
|
|
|
std::unique_ptr<Poco::Net::HTTPClientSession> session(createSession(uri));
|
|
|
|
auto ws = std::make_shared<LOOLWebSocket>(*session, request, response);
|
2018-02-07 03:17:42 -06:00
|
|
|
const char* expected_response = "statusindicator: ready";
|
2019-10-19 11:33:22 -05:00
|
|
|
TST_LOG_END;
|
2018-01-22 08:11:43 -06:00
|
|
|
if (getResponseString(ws, expected_response, testname) == expected_response)
|
2016-11-15 15:22:02 -06:00
|
|
|
{
|
|
|
|
return ws;
|
|
|
|
}
|
|
|
|
|
2019-10-19 11:33:22 -05:00
|
|
|
TST_LOG_BEGIN("Connecting... ");
|
2018-01-22 08:11:43 -06:00
|
|
|
TST_LOG_APPEND(11 - retries);
|
2016-11-15 15:22:02 -06:00
|
|
|
}
|
|
|
|
catch (const std::exception& ex)
|
|
|
|
{
|
2018-01-22 08:11:43 -06:00
|
|
|
TST_LOG_END;
|
2018-06-15 08:14:14 -05:00
|
|
|
TST_LOG("Connection problem: " << ex.what());
|
2016-11-12 12:25:35 -06:00
|
|
|
}
|
2016-05-10 20:38:03 -05:00
|
|
|
|
2016-11-15 15:22:02 -06:00
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(POLL_TIMEOUT_MS));
|
2016-05-10 20:38:03 -05:00
|
|
|
}
|
|
|
|
while (retries--);
|
|
|
|
|
2018-01-22 08:11:43 -06:00
|
|
|
TST_LOG_END;
|
2016-11-12 12:25:35 -06:00
|
|
|
throw std::runtime_error("Cannot connect to [" + uri.toString() + "].");
|
2016-05-08 23:39:01 -05:00
|
|
|
}
|
2016-05-03 22:35:34 -05:00
|
|
|
|
2016-04-28 21:44:40 -05:00
|
|
|
inline
|
2019-08-30 05:22:04 -05:00
|
|
|
std::shared_ptr<LOOLWebSocket> loadDocAndGetSocket(const Poco::URI& uri, const std::string& documentURL, const std::string& testname, bool isView = true, bool isAssert = true)
|
2016-04-28 20:41:00 -05:00
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
// Load a document and get its status.
|
|
|
|
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, documentURL);
|
|
|
|
Poco::Net::HTTPResponse response;
|
2018-01-22 08:11:43 -06:00
|
|
|
std::shared_ptr<LOOLWebSocket> socket = connectLOKit(uri, request, response, testname);
|
2016-04-28 20:41:00 -05:00
|
|
|
|
2018-01-22 08:11:43 -06:00
|
|
|
sendTextFrame(socket, "load url=" + documentURL, testname);
|
2019-08-30 05:22:04 -05:00
|
|
|
bool isLoaded = isDocumentLoaded(*socket, testname, isView);
|
|
|
|
if (!isLoaded && !isAssert)
|
|
|
|
{
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
CPPUNIT_ASSERT_MESSAGE("cannot load the document " + documentURL, isLoaded);
|
2016-04-28 20:41:00 -05:00
|
|
|
|
2018-01-22 08:11:43 -06:00
|
|
|
TST_LOG("Loaded document [" << documentURL << "].");
|
2016-04-28 20:41:00 -05:00
|
|
|
return socket;
|
|
|
|
}
|
|
|
|
catch (const Poco::Exception& exc)
|
|
|
|
{
|
|
|
|
CPPUNIT_FAIL(exc.displayText());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Really couldn't reach here, but the compiler doesn't know any better.
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2016-08-28 11:25:40 -05:00
|
|
|
inline
|
2019-08-30 05:22:04 -05:00
|
|
|
std::shared_ptr<LOOLWebSocket> loadDocAndGetSocket(const std::string& docFilename, const Poco::URI& uri, const std::string& testname, bool isView = true, bool isAssert = true)
|
2016-08-28 11:25:40 -05:00
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
std::string documentPath, documentURL;
|
2018-01-22 08:11:43 -06:00
|
|
|
getDocumentPathAndURL(docFilename, documentPath, documentURL, testname);
|
2019-08-30 05:22:04 -05:00
|
|
|
return loadDocAndGetSocket(uri, documentURL, testname, isView, isAssert);
|
2016-08-28 11:25:40 -05:00
|
|
|
}
|
|
|
|
catch (const Poco::Exception& exc)
|
|
|
|
{
|
|
|
|
CPPUNIT_FAIL(exc.displayText());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Really couldn't reach here, but the compiler doesn't know any better.
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2016-04-28 21:43:59 -05:00
|
|
|
inline
|
2018-01-22 08:11:43 -06:00
|
|
|
void SocketProcessor(const std::string& testname,
|
2016-11-10 02:47:25 -06:00
|
|
|
const std::shared_ptr<LOOLWebSocket>& socket,
|
2016-09-15 03:33:18 -05:00
|
|
|
const std::function<bool(const std::string& msg)>& handler,
|
2016-04-28 21:43:59 -05:00
|
|
|
const size_t timeoutMs = 10000)
|
2016-04-28 20:41:00 -05:00
|
|
|
{
|
2016-04-28 21:43:59 -05:00
|
|
|
socket->setReceiveTimeout(0);
|
|
|
|
|
|
|
|
const Poco::Timespan waitTime(timeoutMs * 1000);
|
2016-05-13 07:46:39 -05:00
|
|
|
int flags = 0;
|
|
|
|
int n = 0;
|
2016-11-25 03:46:01 -06:00
|
|
|
char buffer[READ_BUFFER_SIZE];
|
2016-04-28 20:41:00 -05:00
|
|
|
do
|
|
|
|
{
|
2016-04-28 21:43:59 -05:00
|
|
|
if (!socket->poll(waitTime, Poco::Net::Socket::SELECT_READ))
|
|
|
|
{
|
2018-01-22 08:11:43 -06:00
|
|
|
TST_LOG("Timeout polling.");
|
2016-04-28 21:43:59 -05:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2016-11-25 03:46:01 -06:00
|
|
|
n = socket->receiveFrame(buffer, sizeof(buffer), flags);
|
2018-01-22 08:11:43 -06:00
|
|
|
TST_LOG("Got " << LOOLProtocol::getAbbreviatedFrameDump(buffer, n, flags));
|
2016-04-28 20:41:00 -05:00
|
|
|
if (n > 0 && (flags & Poco::Net::WebSocket::FRAME_OP_BITMASK) != Poco::Net::WebSocket::FRAME_OP_CLOSE)
|
|
|
|
{
|
2016-11-25 03:46:01 -06:00
|
|
|
if (!handler(std::string(buffer, n)))
|
2016-04-28 20:41:00 -05:00
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (n > 0 && (flags & Poco::Net::WebSocket::FRAME_OP_BITMASK) != Poco::Net::WebSocket::FRAME_OP_CLOSE);
|
|
|
|
}
|
|
|
|
|
2016-05-22 17:52:36 -05:00
|
|
|
inline
|
2016-08-30 17:19:05 -05:00
|
|
|
void parseDocSize(const std::string& message, const std::string& type,
|
|
|
|
int& part, int& parts, int& width, int& height, int& viewid)
|
2016-05-22 17:52:36 -05:00
|
|
|
{
|
2019-11-13 00:48:30 -06:00
|
|
|
std::vector<std::string> tokens(LOOLProtocol::tokenize(message, ' '));
|
2016-05-22 17:52:36 -05:00
|
|
|
|
|
|
|
// Expected format is something like 'type= parts= current= width= height='.
|
|
|
|
const std::string text = tokens[0].substr(std::string("type=").size());
|
|
|
|
parts = std::stoi(tokens[1].substr(std::string("parts=").size()));
|
|
|
|
part = std::stoi(tokens[2].substr(std::string("current=").size()));
|
|
|
|
width = std::stoi(tokens[3].substr(std::string("width=").size()));
|
|
|
|
height = std::stoi(tokens[4].substr(std::string("height=").size()));
|
2016-07-26 07:03:46 -05:00
|
|
|
viewid = std::stoi(tokens[5].substr(std::string("viewid=").size()));
|
2016-05-22 17:52:36 -05:00
|
|
|
CPPUNIT_ASSERT_EQUAL(type, text);
|
|
|
|
CPPUNIT_ASSERT(parts > 0);
|
|
|
|
CPPUNIT_ASSERT(part >= 0);
|
|
|
|
CPPUNIT_ASSERT(width > 0);
|
|
|
|
CPPUNIT_ASSERT(height > 0);
|
2016-07-26 07:03:46 -05:00
|
|
|
CPPUNIT_ASSERT(viewid >= 0);
|
2016-05-22 17:52:36 -05:00
|
|
|
}
|
|
|
|
|
2016-05-22 18:53:24 -05:00
|
|
|
inline
|
2018-02-11 12:16:42 -06:00
|
|
|
std::vector<char> getTileMessage(LOOLWebSocket& ws, const std::string& testname)
|
2016-05-22 18:53:24 -05:00
|
|
|
{
|
2018-01-22 08:11:43 -06:00
|
|
|
return getResponseMessage(ws, "tile", testname);
|
2016-05-22 18:53:24 -05:00
|
|
|
}
|
|
|
|
|
2016-08-21 19:16:56 -05:00
|
|
|
inline
|
2018-02-11 12:16:42 -06:00
|
|
|
std::vector<char> assertTileMessage(LOOLWebSocket& ws, const std::string& testname)
|
2016-08-21 19:16:56 -05:00
|
|
|
{
|
2018-01-22 08:11:43 -06:00
|
|
|
const std::vector<char> response = getTileMessage(ws, testname);
|
2016-08-21 19:16:56 -05:00
|
|
|
|
|
|
|
const std::string firstLine = LOOLProtocol::getFirstLine(response);
|
2019-11-13 00:48:30 -06:00
|
|
|
std::vector<std::string> tileTokens(LOOLProtocol::tokenize(firstLine, ' '));
|
2016-08-21 19:16:56 -05:00
|
|
|
CPPUNIT_ASSERT_EQUAL(std::string("tile:"), tileTokens[0]);
|
|
|
|
CPPUNIT_ASSERT_EQUAL(std::string("part="), tileTokens[1].substr(0, std::string("part=").size()));
|
|
|
|
CPPUNIT_ASSERT_EQUAL(std::string("width="), tileTokens[2].substr(0, std::string("width=").size()));
|
|
|
|
CPPUNIT_ASSERT_EQUAL(std::string("height="), tileTokens[3].substr(0, std::string("height=").size()));
|
|
|
|
CPPUNIT_ASSERT_EQUAL(std::string("tileposx="), tileTokens[4].substr(0, std::string("tileposx=").size()));
|
|
|
|
CPPUNIT_ASSERT_EQUAL(std::string("tileposy="), tileTokens[5].substr(0, std::string("tileposy=").size()));
|
|
|
|
CPPUNIT_ASSERT_EQUAL(std::string("tilewidth="), tileTokens[6].substr(0, std::string("tilewidth=").size()));
|
|
|
|
CPPUNIT_ASSERT_EQUAL(std::string("tileheight="), tileTokens[7].substr(0, std::string("tileheight=").size()));
|
|
|
|
|
|
|
|
return response;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline
|
2018-02-11 12:16:42 -06:00
|
|
|
std::vector<char> assertTileMessage(const std::shared_ptr<LOOLWebSocket>& ws, const std::string& testname)
|
2016-08-21 19:16:56 -05:00
|
|
|
{
|
2018-01-22 08:11:43 -06:00
|
|
|
return assertTileMessage(*ws, testname);
|
2016-08-21 19:16:56 -05:00
|
|
|
}
|
|
|
|
|
2016-05-12 04:23:37 -05:00
|
|
|
enum SpecialKey { skNone=0, skShift=0x1000, skCtrl=0x2000, skAlt=0x4000 };
|
|
|
|
|
|
|
|
inline int getCharChar(char ch, SpecialKey specialKeys)
|
|
|
|
{
|
|
|
|
// Some primitive code just suitable to basic needs of specific test.
|
|
|
|
// TODO: improve as appropriate.
|
|
|
|
if (specialKeys & (skCtrl | skAlt))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
switch (ch)
|
|
|
|
{
|
|
|
|
case '\x0a': // Enter
|
|
|
|
return 13;
|
|
|
|
default:
|
|
|
|
return ch;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
inline int getCharKey(char ch, SpecialKey specialKeys)
|
|
|
|
{
|
|
|
|
// Some primitive code just suitable to basic needs of specific test.
|
|
|
|
// TODO: improve as appropriate.
|
|
|
|
int result;
|
|
|
|
switch (ch)
|
|
|
|
{
|
|
|
|
case '\x0a': // Enter
|
|
|
|
result = 1280;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
result = ch;
|
|
|
|
}
|
|
|
|
return result | specialKeys;
|
|
|
|
}
|
|
|
|
|
2018-02-11 12:16:42 -06:00
|
|
|
inline void sendKeyEvent(std::shared_ptr<LOOLWebSocket>& socket, const char* type, int chr, int key, const std::string& testname)
|
2016-05-12 04:23:37 -05:00
|
|
|
{
|
|
|
|
std::ostringstream ssIn;
|
|
|
|
ssIn << "key type=" << type << " char=" << chr << " key=" << key;
|
2016-10-07 22:38:11 -05:00
|
|
|
sendTextFrame(socket, ssIn.str(), testname);
|
2016-05-12 04:23:37 -05:00
|
|
|
}
|
|
|
|
|
2016-11-10 02:47:25 -06:00
|
|
|
inline void sendKeyPress(std::shared_ptr<LOOLWebSocket>& socket, int chr, int key, const std::string& testname)
|
2016-05-12 04:23:37 -05:00
|
|
|
{
|
2016-10-07 22:38:11 -05:00
|
|
|
sendKeyEvent(socket, "input", chr, key, testname);
|
|
|
|
sendKeyEvent(socket, "up", chr, key, testname);
|
2016-05-12 04:23:37 -05:00
|
|
|
}
|
|
|
|
|
2018-02-11 12:16:42 -06:00
|
|
|
inline void sendChar(std::shared_ptr<LOOLWebSocket>& socket, char ch, SpecialKey specialKeys, const std::string& testname)
|
2016-05-12 04:23:37 -05:00
|
|
|
{
|
2016-10-07 22:38:11 -05:00
|
|
|
sendKeyPress(socket, getCharChar(ch, specialKeys), getCharKey(ch, specialKeys), testname);
|
2016-05-12 04:23:37 -05:00
|
|
|
}
|
|
|
|
|
2018-02-11 12:16:42 -06:00
|
|
|
inline void sendText(std::shared_ptr<LOOLWebSocket>& socket, const std::string& text, const std::string& testname)
|
2016-05-12 04:23:37 -05:00
|
|
|
{
|
|
|
|
for (char ch : text)
|
|
|
|
{
|
2016-10-07 22:38:11 -05:00
|
|
|
sendChar(socket, ch, skNone, testname);
|
2016-05-12 04:23:37 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-06 14:02:52 -05:00
|
|
|
inline void saveTileAs(const std::vector<char> &tileResponse,
|
|
|
|
const std::string &filename,
|
|
|
|
const std::string &testname)
|
|
|
|
{
|
|
|
|
const std::string firstLine = LOOLProtocol::getFirstLine(tileResponse);
|
|
|
|
std::vector<char> res(tileResponse.begin() + firstLine.size() + 1, tileResponse.end());
|
|
|
|
std::stringstream streamRes;
|
|
|
|
std::copy(res.begin(), res.end(), std::ostream_iterator<char>(streamRes));
|
|
|
|
std::fstream outStream(filename, std::ios::out);
|
|
|
|
outStream.write(res.data(), res.size());
|
|
|
|
outStream.close();
|
|
|
|
TST_LOG("Saved [" << firstLine << "] to [" << filename << "]");
|
|
|
|
}
|
|
|
|
|
2017-04-30 20:54:38 -05:00
|
|
|
inline std::vector<char> getTileAndSave(std::shared_ptr<LOOLWebSocket>& socket,
|
|
|
|
const std::string& req,
|
|
|
|
const std::string& filename,
|
|
|
|
const std::string& testname)
|
|
|
|
{
|
2018-01-22 08:11:43 -06:00
|
|
|
TST_LOG("Requesting: " << req);
|
2017-04-30 20:54:38 -05:00
|
|
|
sendTextFrame(socket, req, testname);
|
|
|
|
|
2018-02-07 03:17:42 -06:00
|
|
|
const std::vector<char> tile = getResponseMessage(socket, "tile:", testname);
|
2018-01-22 08:11:43 -06:00
|
|
|
TST_LOG(" Tile PNG size: " << tile.size());
|
2017-04-30 20:54:38 -05:00
|
|
|
|
|
|
|
const std::string firstLine = LOOLProtocol::getFirstLine(tile);
|
|
|
|
std::vector<char> res(tile.begin() + firstLine.size() + 1, tile.end());
|
|
|
|
std::stringstream streamRes;
|
|
|
|
std::copy(res.begin(), res.end(), std::ostream_iterator<char>(streamRes));
|
|
|
|
|
|
|
|
if (!filename.empty())
|
2019-05-06 14:02:52 -05:00
|
|
|
saveTileAs(tile, filename, testname);
|
2017-04-30 20:54:38 -05:00
|
|
|
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2017-05-01 23:01:28 -05:00
|
|
|
inline void getServerVersion(LOOLWebSocket& socket,
|
|
|
|
int& major, int& minor,
|
|
|
|
const std::string& testname)
|
|
|
|
{
|
|
|
|
const std::string clientVersion = "loolclient 0.1";
|
2018-02-11 12:16:42 -06:00
|
|
|
sendTextFrame(socket, clientVersion, testname);
|
2017-05-01 23:01:28 -05:00
|
|
|
std::vector<char> loVersion = getResponseMessage(socket, "lokitversion", testname);
|
|
|
|
std::string line = LOOLProtocol::getFirstLine(loVersion.data(), loVersion.size());
|
|
|
|
line = line.substr(strlen("lokitversion "));
|
|
|
|
Poco::JSON::Parser parser;
|
|
|
|
Poco::Dynamic::Var loVersionVar = parser.parse(line);
|
|
|
|
const Poco::SharedPtr<Poco::JSON::Object>& loVersionObject = loVersionVar.extract<Poco::JSON::Object::Ptr>();
|
|
|
|
std::string loProductVersion = loVersionObject->get("ProductVersion").toString();
|
|
|
|
std::istringstream stream(loProductVersion);
|
|
|
|
stream >> major;
|
|
|
|
assert(stream.get() == '.');
|
|
|
|
stream >> minor;
|
|
|
|
|
2018-01-22 08:11:43 -06:00
|
|
|
TST_LOG("Client [" << major << '.' << minor << "].");
|
2017-05-01 23:01:28 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
inline void getServerVersion(std::shared_ptr<LOOLWebSocket>& socket,
|
|
|
|
int& major, int& minor,
|
|
|
|
const std::string& testname)
|
|
|
|
{
|
|
|
|
getServerVersion(*socket, major, minor, testname);
|
|
|
|
}
|
|
|
|
|
2019-05-02 10:14:12 -05:00
|
|
|
inline bool svgMatch(const char *testname, const std::vector<char> &response, const char *templateFile)
|
|
|
|
{
|
|
|
|
const std::vector<char> expectedSVG = helpers::readDataFromFile(templateFile);
|
|
|
|
if (expectedSVG != response)
|
|
|
|
{
|
|
|
|
TST_LOG_BEGIN("Svg mismatch: response is\n");
|
|
|
|
if(response.empty())
|
|
|
|
TST_LOG_APPEND("<empty>");
|
|
|
|
else
|
|
|
|
TST_LOG_APPEND(std::string(response.data(), response.size()));
|
|
|
|
TST_LOG_APPEND("\nvs. expected (from '" << templateFile << "' :\n");
|
|
|
|
TST_LOG_APPEND(std::string(expectedSVG.data(), expectedSVG.size()));
|
|
|
|
std::string newName = templateFile;
|
|
|
|
newName += ".new";
|
|
|
|
TST_LOG_APPEND("Updated template writing to: " << newName << "\n");
|
|
|
|
TST_LOG_END;
|
2019-10-13 20:27:53 -05:00
|
|
|
|
2019-05-02 10:14:12 -05:00
|
|
|
FILE *of = fopen(Poco::Path(TDOC, newName).toString().c_str(), "w");
|
2019-10-13 20:27:53 -05:00
|
|
|
CPPUNIT_ASSERT(fwrite(response.data(), response.size(), 1, of) == response.size());
|
2019-05-02 10:14:12 -05:00
|
|
|
fclose(of);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
test: improve stability of a number of tests
There are numerous race conditions between issuing
action and getting the events. This causes a
mismatch, such that the events from SelectAll
is received when waiting for the events for a
subsequent action (say, Delete).
To make matters worse, sometimes Core issues
an invalidation whilst sending the events for
an action, and this completely messes our
accounting of what events we expect.
This latter could also be an issue with real
clients, however it's less likely to be
disruptive. Still, it is possible that
the client doesn't get key events
because Core had a hiccup, which breaks
the tests.
For the tests at least, the solution is to
re-issue the last action, such that we make
sure that we move forward only when the correct
event is received, or we timeout waiting.
The end results is that tests now don't fail
nearly as often as they used to.
Reviewed-on: https://gerrit.libreoffice.org/80894
Reviewed-by: Andras Timar <andras.timar@collabora.com>
Tested-by: Andras Timar <andras.timar@collabora.com>
(cherry picked from commit 050403daf04d6b36ef850006ba4a15eab6be9afc)
Change-Id: Ib1a658846061990649987ca083915a49c1fb092a
Reviewed-on: https://gerrit.libreoffice.org/81565
Reviewed-by: Ashod Nakashian <ashnakash@gmail.com>
Tested-by: Ashod Nakashian <ashnakash@gmail.com>
2019-10-12 12:47:38 -05:00
|
|
|
/// Select all and wait for the text selection update.
|
|
|
|
inline void selectAll(const std::shared_ptr<LOOLWebSocket>& socket, const std::string& testname, int repeat = COMMAND_RETRY_COUNT)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < repeat; ++i)
|
|
|
|
{
|
|
|
|
sendTextFrame(socket, "uno .uno:SelectAll", testname);
|
|
|
|
if (!getResponseString(socket, "textselection:", testname).empty())
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// Delete all and wait for the text selection update.
|
|
|
|
inline void deleteAll(const std::shared_ptr<LOOLWebSocket>& socket, const std::string& testname, int repeat = COMMAND_RETRY_COUNT)
|
|
|
|
{
|
|
|
|
selectAll(socket, testname);
|
|
|
|
|
|
|
|
for (int i = 0; i < repeat; ++i)
|
|
|
|
{
|
|
|
|
sendTextFrame(socket, "uno .uno:Delete", testname);
|
|
|
|
if (!getResponseString(socket, "textselection:", testname).empty())
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
inline std::string getAllText(const std::shared_ptr<LOOLWebSocket>& socket,
|
2019-10-19 11:32:43 -05:00
|
|
|
const std::string& testname,
|
|
|
|
const std::string expected = std::string(),
|
|
|
|
int retry = COMMAND_RETRY_COUNT)
|
test: improve stability of a number of tests
There are numerous race conditions between issuing
action and getting the events. This causes a
mismatch, such that the events from SelectAll
is received when waiting for the events for a
subsequent action (say, Delete).
To make matters worse, sometimes Core issues
an invalidation whilst sending the events for
an action, and this completely messes our
accounting of what events we expect.
This latter could also be an issue with real
clients, however it's less likely to be
disruptive. Still, it is possible that
the client doesn't get key events
because Core had a hiccup, which breaks
the tests.
For the tests at least, the solution is to
re-issue the last action, such that we make
sure that we move forward only when the correct
event is received, or we timeout waiting.
The end results is that tests now don't fail
nearly as often as they used to.
Reviewed-on: https://gerrit.libreoffice.org/80894
Reviewed-by: Andras Timar <andras.timar@collabora.com>
Tested-by: Andras Timar <andras.timar@collabora.com>
(cherry picked from commit 050403daf04d6b36ef850006ba4a15eab6be9afc)
Change-Id: Ib1a658846061990649987ca083915a49c1fb092a
Reviewed-on: https://gerrit.libreoffice.org/81565
Reviewed-by: Ashod Nakashian <ashnakash@gmail.com>
Tested-by: Ashod Nakashian <ashnakash@gmail.com>
2019-10-12 12:47:38 -05:00
|
|
|
{
|
2019-10-19 11:32:43 -05:00
|
|
|
static const std::string prefix = "textselectioncontent: ";
|
|
|
|
|
test: improve stability of a number of tests
There are numerous race conditions between issuing
action and getting the events. This causes a
mismatch, such that the events from SelectAll
is received when waiting for the events for a
subsequent action (say, Delete).
To make matters worse, sometimes Core issues
an invalidation whilst sending the events for
an action, and this completely messes our
accounting of what events we expect.
This latter could also be an issue with real
clients, however it's less likely to be
disruptive. Still, it is possible that
the client doesn't get key events
because Core had a hiccup, which breaks
the tests.
For the tests at least, the solution is to
re-issue the last action, such that we make
sure that we move forward only when the correct
event is received, or we timeout waiting.
The end results is that tests now don't fail
nearly as often as they used to.
Reviewed-on: https://gerrit.libreoffice.org/80894
Reviewed-by: Andras Timar <andras.timar@collabora.com>
Tested-by: Andras Timar <andras.timar@collabora.com>
(cherry picked from commit 050403daf04d6b36ef850006ba4a15eab6be9afc)
Change-Id: Ib1a658846061990649987ca083915a49c1fb092a
Reviewed-on: https://gerrit.libreoffice.org/81565
Reviewed-by: Ashod Nakashian <ashnakash@gmail.com>
Tested-by: Ashod Nakashian <ashnakash@gmail.com>
2019-10-12 12:47:38 -05:00
|
|
|
for (int i = 0; i < retry; ++i)
|
|
|
|
{
|
|
|
|
selectAll(socket, testname);
|
|
|
|
|
|
|
|
sendTextFrame(socket, "gettextselection mimetype=text/plain;charset=utf-8", testname);
|
2019-10-19 11:32:43 -05:00
|
|
|
const std::string text = getResponseString(socket, prefix, testname);
|
test: improve stability of a number of tests
There are numerous race conditions between issuing
action and getting the events. This causes a
mismatch, such that the events from SelectAll
is received when waiting for the events for a
subsequent action (say, Delete).
To make matters worse, sometimes Core issues
an invalidation whilst sending the events for
an action, and this completely messes our
accounting of what events we expect.
This latter could also be an issue with real
clients, however it's less likely to be
disruptive. Still, it is possible that
the client doesn't get key events
because Core had a hiccup, which breaks
the tests.
For the tests at least, the solution is to
re-issue the last action, such that we make
sure that we move forward only when the correct
event is received, or we timeout waiting.
The end results is that tests now don't fail
nearly as often as they used to.
Reviewed-on: https://gerrit.libreoffice.org/80894
Reviewed-by: Andras Timar <andras.timar@collabora.com>
Tested-by: Andras Timar <andras.timar@collabora.com>
(cherry picked from commit 050403daf04d6b36ef850006ba4a15eab6be9afc)
Change-Id: Ib1a658846061990649987ca083915a49c1fb092a
Reviewed-on: https://gerrit.libreoffice.org/81565
Reviewed-by: Ashod Nakashian <ashnakash@gmail.com>
Tested-by: Ashod Nakashian <ashnakash@gmail.com>
2019-10-12 12:47:38 -05:00
|
|
|
if (!text.empty())
|
2019-10-19 11:32:43 -05:00
|
|
|
{
|
|
|
|
if (expected.empty() || (prefix + expected) == text)
|
|
|
|
return text;
|
|
|
|
}
|
test: improve stability of a number of tests
There are numerous race conditions between issuing
action and getting the events. This causes a
mismatch, such that the events from SelectAll
is received when waiting for the events for a
subsequent action (say, Delete).
To make matters worse, sometimes Core issues
an invalidation whilst sending the events for
an action, and this completely messes our
accounting of what events we expect.
This latter could also be an issue with real
clients, however it's less likely to be
disruptive. Still, it is possible that
the client doesn't get key events
because Core had a hiccup, which breaks
the tests.
For the tests at least, the solution is to
re-issue the last action, such that we make
sure that we move forward only when the correct
event is received, or we timeout waiting.
The end results is that tests now don't fail
nearly as often as they used to.
Reviewed-on: https://gerrit.libreoffice.org/80894
Reviewed-by: Andras Timar <andras.timar@collabora.com>
Tested-by: Andras Timar <andras.timar@collabora.com>
(cherry picked from commit 050403daf04d6b36ef850006ba4a15eab6be9afc)
Change-Id: Ib1a658846061990649987ca083915a49c1fb092a
Reviewed-on: https://gerrit.libreoffice.org/81565
Reviewed-by: Ashod Nakashian <ashnakash@gmail.com>
Tested-by: Ashod Nakashian <ashnakash@gmail.com>
2019-10-12 12:47:38 -05:00
|
|
|
}
|
|
|
|
|
2019-10-19 11:32:43 -05:00
|
|
|
return std::string();
|
test: improve stability of a number of tests
There are numerous race conditions between issuing
action and getting the events. This causes a
mismatch, such that the events from SelectAll
is received when waiting for the events for a
subsequent action (say, Delete).
To make matters worse, sometimes Core issues
an invalidation whilst sending the events for
an action, and this completely messes our
accounting of what events we expect.
This latter could also be an issue with real
clients, however it's less likely to be
disruptive. Still, it is possible that
the client doesn't get key events
because Core had a hiccup, which breaks
the tests.
For the tests at least, the solution is to
re-issue the last action, such that we make
sure that we move forward only when the correct
event is received, or we timeout waiting.
The end results is that tests now don't fail
nearly as often as they used to.
Reviewed-on: https://gerrit.libreoffice.org/80894
Reviewed-by: Andras Timar <andras.timar@collabora.com>
Tested-by: Andras Timar <andras.timar@collabora.com>
(cherry picked from commit 050403daf04d6b36ef850006ba4a15eab6be9afc)
Change-Id: Ib1a658846061990649987ca083915a49c1fb092a
Reviewed-on: https://gerrit.libreoffice.org/81565
Reviewed-by: Ashod Nakashian <ashnakash@gmail.com>
Tested-by: Ashod Nakashian <ashnakash@gmail.com>
2019-10-12 12:47:38 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2017-02-07 10:16:59 -06:00
|
|
|
#endif
|
|
|
|
|
2016-04-28 20:41:00 -05:00
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|