ooocon budapest 2010
TRANSCRIPT
-
7/29/2019 OOoCon Budapest 2010
1/34
Mathias BauerOpenOffice.org Writer Project Lead
The Taming of the Shrew
-
7/29/2019 OOoCon Budapest 2010
2/34
-
7/29/2019 OOoCon Budapest 2010
3/34
3
The Taming of the Shrew - Agenda
Introduction
Unit Testing
Refactoring activities
New build environment Q & A
-
7/29/2019 OOoCon Budapest 2010
4/34
4
Introduction
-
7/29/2019 OOoCon Budapest 2010
5/34
5
What makes code hard to change?
-
7/29/2019 OOoCon Budapest 2010
6/34
6
Spaghetti code?
-
7/29/2019 OOoCon Budapest 2010
7/347
Code that is hard to read or understand?
-
7/29/2019 OOoCon Budapest 2010
8/348
Undiscovered bugs?
-
7/29/2019 OOoCon Budapest 2010
9/349
From past experience
I have this terrible feeling of dj vu..Monty Python's Flying Circus Episode 16
-
7/29/2019 OOoCon Budapest 2010
10/3410
From past experience
I have this terrible feeling of dj vu..Monty Python's Flying Circus Episode 16
-
7/29/2019 OOoCon Budapest 2010
11/3411
Unit Tests
-
7/29/2019 OOoCon Budapest 2010
12/3412
What is a unit test?
It runs fast
This includes the whole compile/link/run cycle
If it takes too long, it is executed less often
Ideally a unit test can be executed after every code change
It is reliable
It helps to localize the root cause of a problem
Not only the test run time, but also the root cause detectionmust be fast
The higher the test level, the more time it will take to find theroot cause of test failures
The higher the level of the test, the harder it is to measuretheir code coverage
-
7/29/2019 OOoCon Budapest 2010
13/3413
What about our existing automated testing?
It's the best testing with some coverage we have
It doesn't help developers in their daily work
Turn around times are too large
They are too unspecific
They can't be executed reliably on any machine
It is hard to specify their code coverage
-
7/29/2019 OOoCon Budapest 2010
14/34
14
Why don't we have more unit tests in OOo?
Often units are big and contain many classes
Classes depend on other classes
Instantiation of particular concrete classes
Methods that require particular objects as parameters
Such dependencies tend to accumulate
Dependencies must be planned with testability in mind
Some classes have hidden prerequisites
Code that only works if something was initialized on startup
Code that requires configuration
-
7/29/2019 OOoCon Budapest 2010
15/34
15
Catch 22
You can't change code safely because it doesn't havetests, and you can't write tests without changing thecode to easily support testing
-
7/29/2019 OOoCon Budapest 2010
16/34
16
Improving the testability
Break dependencies
Separate code to make it run in a test environment
Impersonate classes to monitor the behavior of others
Techniques to change behavior without modifying code
Sub classing
Overwriting existing virtual methods
Adding new ones just to enable overwriting
Factories and interfaces
Fake and Mock Objects
Preprocessor macros
Linking different objects or libraries
-
7/29/2019 OOoCon Budapest 2010
17/34
17
Example I : dialog factory
// create dialog via factorySwAbstractDialogFactory* pFact = SwAbstractDialogFactory::Create();
SfxAbstractTabDialog* pDlg = pFact->CreateSwCharDlg(rWrtSh.GetView().GetWindow(),rWrtSh.GetView(), aCoreSet, DLG_CHAR );
// execute dialog and get data changed by userconst SfxItemSet* pSet = NULL;if( NULL != pDlg && pDlg->Execute() == RET_OK )
pSet = pDlg->GetOutputItemSet();
// apply changesif( pSet )
rWrtSh.SetAttr( *pSet );
Test environment gets its own SwAbstractDialogFactory class
This factory returns objects that do nothing in Execute(), butreturn test input data in OutputItemSet (fake objects)
Slow real GUI testing only for testing the dialog itself
-
7/29/2019 OOoCon Budapest 2010
18/34
18
Example II : text output in a control
void SvxPosSizeStatusBarControl::StateChanged( USHORT nSID,
SfxItemState eState, const SfxPoolItem* pState ){GetStatusBar().SetHelpText( GetId(), String() );switch ( nSID ){
// set help text, control text etc.// depending on input parameters// details omitted here
}
GetStatusBar().SetItemText( GetId(), aText );}
Change GetStatusBar() to return an interface
Pass interface instead of reference to statusbar instance in ctor Implement fake or mock object for test environment
-
7/29/2019 OOoCon Budapest 2010
19/34
19
In between: test code in a running office instance
Inject testing code in office startup
Helps to fill the gap
Enables faster testing even for those classes that willnever get real unit tests
Problem: Rebuild and test aren't fast and easy
Full re-build takes too long, at least on Windows
It requires to copy files to the install folder after the build
Testing in running office needs some fiddling about office
location, command line parameters etc.
-
7/29/2019 OOoCon Budapest 2010
20/34
20
Refactoring Activities
-
7/29/2019 OOoCon Budapest 2010
21/34
21
Refactoring
The refactoring goal is to create components:
Individual physical units where none of their parts can be usedindependently of the others
They don't have cyclic dependencies with other components
They are small enough to apply unit testing to them
Possible components may be
a complete library
a single object file or a certain number of them containing anynumber of C++ classes
a UNO service or UNO object
other code entities that are separated with pure C++ interfaces
-
7/29/2019 OOoCon Budapest 2010
22/34
22
Huge dependency attractor: class SwDoc
Very big
~50 private methods
~600(!) public methods
Covers nearly all aspects of a document in one class
Tightly coupled to other parts through direct interactions
Layout
Framework
UI
Cyclic dependency between SwDoc, UNO documentmodel and framework dispatch object (SwDocShell) fordocument related functionality
-
7/29/2019 OOoCon Budapest 2010
23/34
23
Decoupling through interfaces: class SwDoc
class SW_DLLPUBLIC SwDoc :public IInterface,public IDocumentSettingAccess,public IDocumentDeviceAccess,public IDocumentRedlineAccess,public IDocumentUndoRedo,public IDocumentLinksAdministration,public IDocumentFieldsAccess,public IDocumentContentOperations,public IDocumentStylePoolAccess,public IDocumentLineNumberAccess,public IDocumentStatistics,public IDocumentState,public IDocumentDrawModelAccess,public IDocumentLayoutAccess,public IDocumentTimerAccess,public IDocumentChartDataProviderAccess,public IDocumentListItems,public IDocumentOutlineNodes,public IDocumentListsAccess,public IDocumentExternalData
/* IDocumentLineNumberAccess */ virtual const SwLineNumberInfo& GetLineNumberInfo() const; virtual void SetLineNumberInfo(const SwLineNumberInfo& rInfo);
-
7/29/2019 OOoCon Budapest 2010
24/34
24
Cyclic vs. acyclic dependency
SwDoc SwDocShell
UNO model
SwDoc SwDocShell
UNO model
Currentdependencies
Desireddependencies
SwDoc : CoreUNO model: APISwDocShell: UI dispatching
-
7/29/2019 OOoCon Budapest 2010
25/34
25
Layout refactoring
Layout is hold by view object, not by document object
No direct access to layout classes from document coreobjects, view adds callback interfaces for definedactivities
Document doesn't not have the layout, every view mayhave an individual one
Refactoring currently stuck in form control layout
Idea is to emulate model/view separation by having one
drawing layer per view, sharing model related data
-
7/29/2019 OOoCon Budapest 2010
26/34
26
Removed dependencies through refactoring
Removed direct or indirect dependency on vcl in a lot of
libraries or modules:
split svtools module into svt and svl module
connectivity
shell
xmloff
linguistic, lingucomponent
embeddedobj
Split svx library and svx module
editeng (80 objects) msfilter (20 objects)
cui (120 objects)
svx and svxcore (490 objects)
-
7/29/2019 OOoCon Budapest 2010
27/34
27
Module dependencies
external:afms, agg, apache-commons, apple_remote, beanshell, berkeleydb, bitstream_vera_fonts, boost, cairo, cppunit, curl,
epm, expat, external, fondu, graphite, hsqldb, hunspell, hyphen, icc, icu, jfreereport, jpeg, libegg, libtextcat, libwpd,libxml2, libxmlsec, libxslt, lpsolve, lucene, MathMLDTD, moz, neon, np_sdk, nss, openssl, python, redland, rhino,
sane, saxon, stax, stlport, tomcat, twain, unixODBC, vigra, x11_extensions, xpdf, xsltml, zlib
GUI/system:a11y, canvas, cppcanvas, dtrans, goodies, padmin, psprint_config,
setup_native, svtools, sysui, toolkit, UnoControls, vcl
top level:basctl, chart2, desktop, extensions, forms,
scripting, starmath, xmlsecurity
base:dbaccess,
reportdesign
draw:animations,
slideshow, sd
calc:scaddins, sccomp,
sc
writer:hwpfilter, writerfilter,
writerperfect, sw
common:basebmp, basegfx, bean, comphelper, configmgr, connectivity, crashrep, embedserv, embeddedobj,
eventattacher, fileaccess, i18npool, i18nutil, javainstaller2, linguistic, lingucomponent, o3tl, officecfg, oovbaapi,package, pyuno, regexp, rsc, sax, shell, sot, svl, tools, transex3, ucb, ucbhelper, unotools, unoxml, vos,
xmerge, xmlhelp, xmloff, xmlscript, wizards
dmake, instsetoo_native, packimages, postprocess, root, scp2,smoketestoo_native, soldep, solenv, soltools, testtools
l10n
extensions:mediawiki,
migrationanalysis,minimizer, pdfimport,
presenter, reportbuilder
default_images, external_images,ooo_custom_images
testautomation
helpcontent2
extras dictionaries
odk:autodoc, cosv, odk,
readlicense_oo, udm,unodevtools
binfilter
framework:automation, avmedia, basic, drawinglayer,
filter, formula, fpicker, framework, idl, sfx2, oox,svx, uui
ure:bridges, cli_ure, codemaker, cppu, cppuhelper, cpputools, idlc, io, javaunohelper, jurt, jvmaccess, jvmfwk, offapi, offuh, qadevooo, rdbmaker,
registry, remotebridges, ridljar, sal, salhelper, stoc, store, testshl2, udkapi, unoil, ure, xml2cmp
-
7/29/2019 OOoCon Budapest 2010
28/34
28
Future refactoring goals
Proceed with activities in Writer Remove Writer's own code for shapes (drawing objects)
Load drawing layer code in Writer on demand
Reorganize libraries in common group
Combine related classes
Separate code used in startup
Startup relevant code should use as few libraries as possible
Libraries loaded on demand should be as small as possible
Recompose framework and GUI libraries svt, sfx2, svxby separating GUI, framework and drawing layer code
Reduce required application bootstrapping andmandatory prerequisites
-
7/29/2019 OOoCon Budapest 2010
29/34
29
New build environment
-
7/29/2019 OOoCon Budapest 2010
30/34
30
New requirements to the build environment
Tests may have runtime dependencies that don't matchthe build dependencies (e.g. a configuration manager)
We want to load libraries that have dependencies onlibraries in a different layer
We want to run an executable without installing it
instsetoo_native shouldn't do anything except creatingpackages
post processing of deliverables should be avoided
Re-builds must be a lot faster, at least on Windows
It must be possible to build single products
-
7/29/2019 OOoCon Budapest 2010
31/34
31
New Build environment
A lot of new stuff, some things are interesting for testingsupport:
It does not require manual specification of dependencies for allbuilt-in targets
It makes dependency evaluation much faster, especially onWindows:
Besides that: throw out unnecessary stuff and makethings simpler
Moving from split build to split repository
Already done: external tar balls moved out
First prepare build for external locations, then split
Repository split must be aligned with a code line branch
-
7/29/2019 OOoCon Budapest 2010
32/34
32
UNO service registration active or passive
Call exported function in the library that writes service info into a registry file
sal_Int32 nLen = s_pImplementationNames->getLength();
const ::rtl::OUString* pImplName = s_pImplementationNames->getConstArray();const uno::Sequence< ::rtl::OUString >* pServices = s_pSupportedServices->getConstArray();::rtl::OUString sRootKey("/", 1, RTL_TEXTENCODING_ASCII_US);for (sal_Int32 i=0; i xNewKey( _rxRootKey->createKey(aMainKeyName) );const ::rtl::OUString* pService = pServices->getConstArray();for (sal_Int32 j=0; jgetLength(); ++j, ++pService)
xNewKey->createKey(*pService);
}
Deliver xml snippet that is added to the registry file
-
7/29/2019 OOoCon Budapest 2010
33/34
33
File layout: solver and installed office
-
7/29/2019 OOoCon Budapest 2010
34/34