Feature Proposal: Simplify The Store - Meta Semantics

T

Motivation

The current legacy Foswiki::Meta and Foswiki::Store maze of classes are not sufficiently well understood, and are quite error prone - as you're expected to know the right way to call them, and any other use is undefined or worse, a security leak.

In my MongoDBPlugin performance work, I've begin trying to use the exiting classes to add a more persistent cache of parsed topic objects, and there is no good place to add it - we're needing to break abstractions too often.

Description and Documentation

These are new classes that should allow the old ones to become wrappers that over time become less used because they are harder to use

Try to define a new API set for talking about, passing around and manipulating stored items - with the intent to deprecate the older methods without breaking them.

I expect this DOCCO will be developed/changed during the discussion

High level interface ideal

User POV

I want to create a Foswiki::Store2 service from which we can request Foswiki::Meta2 objects, and to which we can 'post' change-requests on those objects.
Store Developer POV

Make it easer to implement just the portions of the Store backend API that are needed - ie, a 'Listener API' like interface for insert, update, remove should actually be able to be defined without needing to create a new API (as Crawford did to show a desperate need for a simplified API), instead, we can implement an ordered Foswiki::Listener style MultiStoreRefactor

Simplify the responsibilities of classes

Foswiki::Meta is a very complex things at the moment, it encapsulates the following responsibilities:
  1. Address object (an unloaded Meta object)
  2. Representation of the stored Object - a mix of both API get&set and nestable/pushable key->{hash} 'pair/triple/somethings' that require complex find & query semantics to use
  3. Session (user&permission&group) specific evaluated information
  4. Representation of a change-request to the Stored object
  5. Factory or Meta Object creator AND change-request request & submission (eg, load, save, saveAs, move, , lock etc all are Store services, not Meta methods)
  6. New Stored object factory (eg populateNewWeb)
  7. Container object - Webs are containers of topics, Topics are containers of attachments - and yet a topic object still has invalid eachTopic and EachWeb methods
  8. eachChange - log iterator??? this one is really weird as it is doccoed to only work per web, even though we have versioning on topics and attachments (it works per web because .changes were stored per web)
  9. Versioning API sort of missing and sort of muddled - the API suggests the user can take a previously loaded meta object, and ask it to loadVersion, but the new reality is that will now return an error - instead, if all requests to load database info is made of a seperate class - the factory, this API simplifies
    1. setRevisionInfo???? huh - we allow the plugin author to tell the store what version number to use?
  10. serialisation and deserialisation
    1. (g|s)etEmbeddedStoreForm
  11. copy and merge meta objects into an existing object, rather than creating a new merged ojbject so that the destination object remains cacheable.
  12. rendering ?????? we still have a Meta::renderFormForDisplay...
  13. ACL evaluation - which is session specific, anc caches in the Meta object - preventing its reuse even for the same user - as in future a user might be in a different set of Groups.
  14. legacy-ifyer - Sven - we could create MultiStore listeners that are only activated if one of the plugins defines the legacy beforeSaveHandler and afterSavehandler, and extract that code into Storebackend::Legacy::save 'listener' - which goes to show that there needs to be an order for Multi-store, and a concept of 'writer' and 'notifier' stores
  15. Preferences!
Ok, I'm a little scared now, I hope you are too.

New Classes

Please ignore the specific names - I'm working on getting down the concepts first

Func and most Core user Exposed

Foswiki::Store2
  • get(address)
  • query(query)
  • create(address) - separated so we have the possibilty to 'get' a read only object that is cacheable, and a writeable object
  • put(meta2) or put(change)
  • copy(address, address)
  • move(address, address)
  • lock(address) / lease(address)
I am Still to work out how the Store2 factory only returns Meta objects that the current User has permission to interact with. IMO this is an important security feature - allowing Plugin writers to simply trust that they will only be given what that user is allowed.

Right now, I'm thinking that Store2 will have a 'filter' mixin that normally includes a Foswiki::Prefs / Foswiki:ACL's filter - which hard core store developers can also over-ride to allow for in database fast query based permissions.

Foswiki::Address

can be a text TOM address - 'System.WebHome', a {web=>'System', topic=>'WebChanges'} hash, or if an address transform has been used on it, an Address object containing this information
Foswiki::Meta2

derived from the Foswiki::Address class, essentially a getter and setter object wrapper

This Might become the Foswiki::Meta class - bringing together all the other classes in a legacy way, but I hope not.

it would be ideal to reduce the use of the get(type, name, hash) style usages where users of this accessors have too much detail about internal TMLText representations - and replace it with a more Query/TOM style

_don't store the Foswiki::Preference object in the Meta as {_preferences), rather make it possible to call Foswiki::Prefs::Get(address) or Get(address, key..)
Internal or inner Developer
Foswiki::Meta2::Web
Foswiki::Meta2::Topic
Foswiki::Meta2::Attachment
Foswiki::Meta2::Change

mmm, maybe not - I'm not sure if we shoudl haev a 'diff' object, but it could be useful in the idea of a read only Meta object.
Foswiki::Meta2::EvaluatedInformation

where we put somewhat expensive to calculate derived information - rather than pollution the actual Meta2 objects.
Foswiki::Meta2::ACL

need Crawford to remind me what went wrong with the ACL code extraction he originally did (or i think he tried..)

Foswiki::Serialise::TMLText
Foswiki::Store::Backend

implements a lightweight listener style caller of registered backends (in the typical foswiki installation, it might request a get from memorycache, rcswrap, legacy, where the last only happens if there are plugins that use beforeSaveHandler style.
Foswiki::Store::Backend::RcsWrap
Foswiki::Store::Backend::RcsLite
Foswiki::Store::Backend::DBI
Foswiki::Store::Backend::Legacy
Foswiki::Store::Query

Query implementations register that they can evaluate to different SEARCH{type="" and can be called in a performance based order. (API == query(Query::Node), and can also refuse -
Foswiki::Store::Query::Grep
Foswiki::Store::Query::Solr
Foswiki::Store::Query::PurePerl
Foswiki::Store::Query::BruteForce
Foswiki::Store::Query::Xapian
Foswiki::Store::Query::MongoDB

Examples

Impact

%WHATDOESITAFFECT%
edit

Implementation

-- Contributors: SvenDowideit - 13 Feb 2011

TODO: Event Handling and Logging

Sven mentions in passing below on Aug. 19 update (also, I want to push the 'load' part of the the listener and store/meta cache concepts below the Store factory, so that that becomes a transparent multi-cache. And the event parts of the listeners could become part of the 'event' subscription system that the logger system could become.)

Currently events for loggin are issued in Meta - but they might be better triggered in store.
  • Need assurance that every store activity that changes something triggers an event
  • Need multiple event listeners - logging being one of them
  • Events can't be just store though - for example authentication events success and failure, need to be logged.

Discussion

You will notice that this API looks alot like a CRUD REST api to the storeage level. While I do want to make this (and using other CRUD REST API services possible) I'm not yet convinced that we want to put the ACL and UserID code into the Store (which is what we would have to do for this). Once we get to that point, we really do need to consider making the Store2 API WebDAV.

not finished - have to go look after the girls smile

-- SvenDowideit - 13 Feb 2011

I don't think lock should be exposed as it stands. It was intended as a "transaction lock", and I'd prefer to see a transaction factory or similar approach rather than a simplistic lock.

-- CrawfordCurrie - 13 Feb 2011

Hey Sven, small reminder on our short irc chat about this massive reorganizations of the foswiki guts. As you mentioned set logics, it would make sense to use set logic in the ACL module as well to facilitate an api like getAllowedUsers($action, $topic) -> $iterator Not sure where to stick it in to the above proposal...here it is, YAWI (yet another wishlist item) smile

-- MichaelDaum - 21 Feb 2011

Sven and Crawford had a chat about this, this morning. Here's a summary:

The problems:
  1. Folding together the concept of an address object with the existing Meta object has not worked.
  2. Pulling ACLs out of the store was a bad move; back end stores can do a good job of maintaining ACLs
  3. The core code still has to know far too much about how the store works - specifically, that there are "cached" topics and "histories".
  4. Not using a factory for Meta objects has made it impossible to subclass Meta.
The solutions:
  1. Kill off Meta (except as a compatibility interface). Introduce an address object and a loaded store thing object (web? attachment? or just topic?)
  2. move ACLs back under the store interface
  3. use a factory to create new objects.
  4. use exceptions to handle all error cases
Examples

$addr = new Foswiki::Address("System/WebHome@4");
$readonly_topic = Store::load($addr); #loads rev 4 of Sandbox.WebHome

$readonly_topic = Store::load("System/WebHome@4"); #loads rev 4 of Sandbox.WebHome and returns a _readonly_ topic object.

$nothing = Store::load("System/NoSuchTopic");  #throws an 'topic does not exist exception

$nothing = Store::load("System/NoTopicViewPerm");  #throws an 'permission denied

$sandboxtopic = Store::load("Sandbox.MyTest", create=>1); #loads the topic if it exists and returns a readonly topic object (including a non-modifyable new one based on the topic creation template. (ok, yes, weird, but exists for consistency) throws an exception if the user does not have permission to view topic / web

$writeabletopic = Store::load("Sandbox.MyTest", create=>1, writeable=>1); #loads the topic if it exists and returns a writeable topic object (including one based on the topic creation template IFF the user has permission to MODIFY else throws and exception

$writeabletopic = Store::load("Sandbox.MyTest", writeable=>1); #loads the topic if it exists and returns a witeable topic object IFF the topic exists and the user has permission to MODIFY _else_ throws an exception

$writeabletopic = Store::load($sandboxtopic, writeable=>1); #copies the loaded readonly topic and returns a witeable topic object IFF the topic exists (ie that $sandboxtopic != undef) and the user has permission to MODIFY _else_ throws an exception

__NOTE__ everywhere that "Web.Topic" can be used, it can be replaced by =$web, $topic=, =Foswiki::Address= or even =Foswiki::Object::*= - as all these are detectably equivalent.

-- CrawfordCurrie && SvenDowideit - 19 Aug 2011

The main fast path would be chosen as the one that is used the most, and thus requires the most speedup (and if this idea is too slow, we remove it smile )

This time I've made create and writeable flags on the Store::load() method - I'm really unsure if this, or separate methods make more sense - consider them conceptually similar, tho i grok how different they are wrt class or object method inheritance :/

(FWIW Crawford prefers the named param approach. They are conceptually similar, but I don't like interface bloat, as it makes the whole thing more fragile. Within the implementatio you will probably split into different methods, but that's an implementation choice)

Specifically, the topic (or Foswiki::Object) doesn't unmarshal the data, and the user of the factory (like the enter-er of the URL) doesn't care what Store implementation the data comes from.

Technically, there is a really important reason, learned through experience with the 1.1 code.

If a factory returns an unloaded object that is later loaded (into that same object), then a lot more work (and methods, and user code) needs to be written to test for object consistency. Instead, if the factory only returns valid loaded objects, the main code path can be cleaner and faster.

One very pertinent example is how Foswiki::Object::Topic::new would be coded
my $this = bless({}, 'Foswiki::Meta');

and then later in the load()

$this->copyMetaFrom(Store::readText($web, $topic)); #where copy is expensive recursive put method calls

VS
throw AccessException() if Foswiki::Permissions::hasAccess($web, $topic, 'VIEW',  $user, dontload=>1); #ie, see if we are _able_ to test permissions using just an unloaded topic, if not, fall through to the brute-load-perm-test?
my $data = Serialise::deserialise(Store::readData($web, $topic), 'tml2000'); #foswiki topic encoded
my $this = bless({data=>$data}, 'Foswiki::Meta');
throw AccessException() if Foswiki::Permissions::hasAccess($this, 'VIEW',  $user); #can't do any better with the __current__ ACL impl, but there should be a call before the readData for real store-fastening
$this->cleanupBookKeeping(); #fix up the {_index} elements IIF we can't get rid of that slowdown too

And in the above example tml2000 would become replaceable with a combination of autodetection for compatibility mode, and any one of the massively faster formats, including JSON and BSON.

One note about 'readonly': I want to utilise 2 things to implement this - perl 5.8.8's Hash::Util::lock_hashref which throws an exception if the hash is modified (ie, coder ignores the API methods), and by using separate classes, one which is the 'data' object/hash, and a wrapper that is either readonly, by virtue of not having put methods, and the writeable one. When a writeable object is requested, we do a deep copy of the otherwise cacheable data.

The benefit of this, is that we can then safely cache loaded topic data (if it works well, doesn't even have to be an obj!) in one place, with much less risk that one request in a persistent perl 'run' modifies, but does not save a topicref that it receives from one of the random local caches.

(also, I want to push the 'load' part of the the listener and store/meta cache concepts below the Store factory, so that that becomes a transparent multi-cache. And the event parts of the listeners could become part of the 'event' subscription system that the logger system could become.)

-- SvenDowideit - 19 Aug 2011

Just getting my head round the implications of this. The user (the rest of the code) sees an address object, and a resource object. The interface to the resource object varies according to the capabilities of the underlying store and the permissions of the resource. So, let's say I have a chunk of code that is passed a resource object, but doesn't know anything about it. The code has to be able to ask the object to find out (1) what kind of resource it refers to (collection or atom, web or topic or attachment etc) and (2) what it can do with it (readable, writable) and (3) why. It starts to feel like the division between "address" and "resource" is a bit arbitrary (which is how we ended up with unloaded meta objs)

-- CrawfordCurrie - 20 Aug 2011

FWIW, Foswiki::Address has ->type() and ->isA() methods. Although, I feel as if we haven't really thought through, either (comments welcome).

I know that I don't want Foswiki::Address to have any concern for resource interaction, traversal, manipulation or otherwise. It should purely be focused on addressing resources.

"Resource" objects need to provide the interface for actually doing the CRUDdy work. So in my mind, it's not arbitrary smile But actually what a resource object should do, and look like, ... doesn't seem obvious. Here's some old abandoned code I wrote as an experiment on GET/PUT of data with Foswiki::Address. It's abandoned because I'm not sure it really achieves what I wanted it to.

Seems like the Roles/Traits stuff in Moose would be useful here...

-- PaulHarvey - 20 Aug 2011

The separation between Address and Resource is important - in that you don't have to hand someone your house to tell them where it is smile I do hope it'll become a little less arbitrary next week - I'm prototyping the code atm smile

Yes, It'd be nice to use roles/traits/mixins, though initially I'm trying hard to stick with perl core (cos there's a lot of that we've not utilized yet either)

-- SvenDowideit - 20 Aug 2011

oh, and I'm going to push the prototype code to github - https://github.com/SvenDowideit/foswiki and if it works, we can push it to svn

-- SvenDowideit - 20 Aug 2011

Getting back to an analogy that is more software than real estate, a Foswiki::Resource is like a file handle. The ->text() method is the equivalent of a read of the filehandle.

An inefficient store (e.g. one with embedded meta-data) will read the topic in order to recover meta-attributes, but that should be a worst case. Other stores need to be able to hold meta-data separately from the topic content.

Having said that, I believe we still need setEmbeddedStoreForm - it's a concept that is too deeply ingrained in consumers of the store to simply ignore.

-- CrawfordCurrie - 21 Aug 2011

Sven,

Any chance you might consider using the separate git repos for this? It's much easier rebasing extensions or core separately, than having to do it against all the noise of all the checkins over ~500 things we have on trunk. And the workflow is exactly the same.

(deleted bogus instructions, see SimplifyTheStoreMetaSemantics)

Done! (This also git clones and git svn inits and wires them all up to their respective places on svn.foswiki.org, so dcommit and svn rebase will work as normal).

You might wish to put other git (or svn) repos in psuedo-install's repo "search" path. Just use

pseudo-install.pl -G

to update your ~/.buildcontrib file with the default repo settings, then add your own repositories as you see fit.

-- PaulHarvey - 21 Aug 2011

I'm working on duplicating your github work on scratch branch in svn (core and UnitTestContrib).

Sadly, github.com isn't tracking scratch branch for the repos-per-extension (or even the big fat foswiki.git repo?), so you have to svn fetch --all and create your own tracking branch, see below.

(deleted bogus instructions, see SimplifyTheStoreMetaSemantics)

-- PaulHarvey - 18 Sep 2011

Okay, as of today I think you've been working on the following tests:
  • AccessControlTests, I get 14 of 18
    • AccessControlTests::test_login_redirect_preserves_anchor
    • AccessControlTests::test_subweb_inherits_from_parent
    • AccessControlTests::test_subweb_controls_override_parent
    • AccessControlTests::test_finalised_parent_overrides_subweb
  • AddressTests, all pass
  • StoreTests, I get 33 of 36
    • StoreTests::verify_beforeSaveHandlerChangeBoth_StoreTests_RcsWrap
    • StoreTests::verify_beforeSaveHandlerChangeBoth_StoreTests_RcsLite
    • StoreTests::test_getRevisionInfoNoRcsFile
  • ClientTests, all pass
  • TopicUserMappingContrib, 38 of 54
  • PrefsTests, all pass
-- PaulHarvey - 11 Nov 2011

Update: Sven & I are working on github.com/SvenDowideit/foswiki, no need to play with repo-per-extension (I couldn't quite extract core from Sven's repo in a useful way that aligned with the svn equivalent, so I haven't bothered pursuing it. In case anybody is interested... the svn clone of a part of a branch seems to follow branch points around the place (outside of its path), this results in a slightly longer history (with different commit ids) than the git-subtree approach)

-- PaulHarvey - 13 Nov 2011

mmm, more todo
2826 of 3502 test cases passed
1..63942

---- later, after fixing RegisterTests.pm
2972 of 3502 test cases passed
1..67351

-- SvenDowideit - 02 Dec 2011

post Paul merge from trunk - 9 new unit tests, all passing thankfully. I added a count of tests per module failing, so I know which to work on next smile
---++ Module Failure summary
   * Fn_NOP has 1 unexpected results (of 1)
   * AutoAttachTests has 1 unexpected results (of 2)
   * VariableTests has 1 unexpected results (of 4)
   * ExceptionTests has 1 unexpected results (of 4)
   * Fn_INCLUDE has 1 unexpected results (of 9)
   * Fn_GROUPS has 1 unexpected results (of 1)
   * FormattingTests has 1 unexpected results (of 65)
   * FormDefTests has 1 unexpected results (of 10)
   * RobustnessTests has 1 unexpected results (of 8)
   * Fn_SECTION has 2 unexpected results (of 12)
   * Fn_FORMAT has 2 unexpected results (of 45)
   * VCMetaTests has 2 unexpected results (of 10)
   * TranslatorTests has 2 unexpected results (of 300)
   * EngineTests has 2 unexpected results (of 12)
   * Fn_IF has 2 unexpected results (of 138)
   * SaveScriptTests has 3 unexpected results (of 26)
   * TwistyPluginTests has 3 unexpected results (of 13)
   * Fn_ICON has 3 unexpected results (of 3)
   * Fn_FORMFIELD has 3 unexpected results (of 10)
   * LoadedRevTests has 3 unexpected results (of 5)
   * StoreTests has 3 unexpected results (of 36)
   * AccessControlTests has 3 unexpected results (of 18)
   * PreferencesPluginTests has 4 unexpected results (of 5)
   * RenderFormTests has 4 unexpected results (of 7)
   * RESTTests has 4 unexpected results (of 5)
   * ViewScriptTests has 4 unexpected results (of 4)
   * ManageDotPmTests has 6 unexpected results (of 19)
   * Fn_WEBLIST has 6 unexpected results (of 16)
   * ClientTests has 6 unexpected results (of 12)
   * TOCTests has 6 unexpected results (of 7)
   * MailerContribSuite has 7 unexpected results (of 9)
   * TWikiFuncTests has 7 unexpected results (of 24)
   * ViewFileScriptTests has 8 unexpected results (of 14)
   * VCStoreTests has 9 unexpected results (of 24)
   * InitFormTests has 10 unexpected results (of 10)
   * ExpandMacrosTests has 11 unexpected results (of 11)
   * HierarchicalWebsTests has 12 unexpected results (of 14)
   * MetaTests has 14 unexpected results (of 23)
   * CommentPluginTests has 14 unexpected results (of 17)
   * InterwikiPluginTests has 15 unexpected results (of 15)
   * FuncTests has 16 unexpected results (of 50)
   * TopicUserMappingContribTests has 16 unexpected results (of 18)
   * ZoneTests has 18 unexpected results (of 21)
   * PluginHandlerTests has 19 unexpected results (of 19)
   * CacheTests has 20 unexpected results (of 20)
   * RenameTests has 22 unexpected results (of 26)
   * UIFnCompileTests has 23 unexpected results (of 72)
   * SemiAutomaticTestCaseTests has 24 unexpected results (of 24)
   * Fn_SEARCH has 29 unexpected results (of 338)
   * EditTablePluginTests has 32 unexpected results (of 39)
   * HTMLValidationTests has 52 unexpected results (of 98)
   * FuncUsersTests has 66 unexpected results (of 288)
2981 of 3511 test cases passed
1..67695

-- SvenDowideit - 04 Dec 2011

wow, backtracking then removing the metacache has taken me the better part of a day to get working again, but
---++ Module Failure summary
   * AutoAttachTests has 1 unexpected results (of 2)
   * Fn_TOPICLIST has 1 unexpected results (of 9)
   * VariableTests has 1 unexpected results (of 4)
   * UploadScriptTests has 1 unexpected results (of 9)
   * TwistyPluginTests has 1 unexpected results (of 13)
   * ExceptionTests has 1 unexpected results (of 4)
   * Fn_INCLUDE has 1 unexpected results (of 9)
   * Fn_GROUPS has 1 unexpected results (of 1)
   * FormDefTests has 1 unexpected results (of 10)
   * RobustnessTests has 1 unexpected results (of 8)
   * EngineTests has 2 unexpected results (of 12)
   * Fn_IF has 2 unexpected results (of 138)
   * ExtendedTranslatorTests has 2 unexpected results (of 63)
   * Fn_FORMAT has 3 unexpected results (of 45)
   * Fn_ICON has 3 unexpected results (of 3)
   * Fn_FORMFIELD has 3 unexpected results (of 10)
   * LoadedRevTests has 3 unexpected results (of 5)
   * ViewScriptTests has 3 unexpected results (of 4)
   * AccessControlTests has 3 unexpected results (of 18)
   * PreferencesPluginTests has 4 unexpected results (of 5)
   * VCMetaTests has 4 unexpected results (of 10)
   * RenderFormTests has 4 unexpected results (of 7)
   * RESTTests has 4 unexpected results (of 5)
   * SaveScriptTests has 5 unexpected results (of 26)
   * VCStoreTests has 5 unexpected results (of 24)
   * ManageDotPmTests has 6 unexpected results (of 19)
   * ClientTests has 6 unexpected results (of 12)
   * SemiAutomaticTestCaseTests has 6 unexpected results (of 24)
   * TWikiFuncTests has 6 unexpected results (of 24)
   * TOCTests has 6 unexpected results (of 7)
   * MailerContribSuite has 7 unexpected results (of 9)
   * MetaTests has 10 unexpected results (of 23)
   * InitFormTests has 10 unexpected results (of 10)
   * ExpandMacrosTests has 11 unexpected results (of 11)
   * StoreTests has 11 unexpected results (of 36)
   * TranslatorTests has 12 unexpected results (of 300)
   * HierarchicalWebsTests has 12 unexpected results (of 14)
   * TopicUserMappingAsGuestTests has 12 unexpected results (of 20)
   * ViewFileScriptTests has 13 unexpected results (of 14)
   * CommentPluginTests has 14 unexpected results (of 17)
   * InterwikiPluginTests has 15 unexpected results (of 15)
   * FuncTests has 17 unexpected results (of 50)
   * PluginHandlerTests has 19 unexpected results (of 19)
   * CacheTests has 20 unexpected results (of 20)
   * RenameTests has 22 unexpected results (of 26)
   * UIFnCompileTests has 22 unexpected results (of 72)
   * Fn_SEARCH has 23 unexpected results (of 338)
   * FuncUsersTests has 24 unexpected results (of 288)
   * EditTablePluginTests has 33 unexpected results (of 39)
   * HTMLValidationTests has 34 unexpected results (of 98)
3076 of 3511 test cases passed
1..74521

-- SvenDowideit - 07 Dec 2011

---++ Module Failure summary
AutoAttachTests has 1 unexpected results (of 2):
   * F: AutoAttachTests::test_autoattach
Fn_TOPICLIST has 1 unexpected results (of 9):
   * F: Fn_TOPICLIST::test_hidden_web_list
VariableTests has 1 unexpected results (of 4):
   * F: VariableTests::test_macroParams
UploadScriptTests has 1 unexpected results (of 9):
   * F: UploadScriptTests::test_imagelink
TwistyPluginTests has 1 unexpected results (of 13):
   * F: TwistyPluginTests::test_twistyInSubWeb
ExceptionTests has 1 unexpected results (of 4):
   * F: ExceptionTests::test_oopsScript
Fn_INCLUDE has 1 unexpected results (of 9):
   * F: Fn_INCLUDE::test_webExpansion
Fn_GROUPS has 1 unexpected results (of 1):
   * F: Fn_GROUPS::test_basic
FormDefTests has 1 unexpected results (of 10):
   * F: FormDefTests::test_makeFromMeta
RobustnessTests has 1 unexpected results (of 8):
   * F: RobustnessTests::test_sanitizeAttachmentNama_unicode
EngineTests has 2 unexpected results (of 12):
   * F: EngineTests::test_path_info
   * F: EngineTests::test_simple_request
Fn_IF has 2 unexpected results (of 138):
   * F: Fn_IF::test_DOS
   * F: Fn_IF::test_ALLOWS_and_EXISTS
Fn_FORMAT has 3 unexpected results (of 45):
   * F: Fn_FORMAT::test_SEARCH_3860
   * F: Fn_FORMAT::test_subweb_web_token
   * F: Fn_FORMAT::test_not_topics
Fn_ICON has 3 unexpected results (of 3):
   * F: Fn_ICON::test_ICONURLPATH
   * F: Fn_ICON::test_ICON
   * F: Fn_ICON::test_ICONURL
Fn_FORMFIELD has 3 unexpected results (of 10):
   * F: Fn_FORMFIELD::test_FORMFIELD_topic
   * F: Fn_FORMFIELD::test_FORMFIELD_web
   * F: Fn_FORMFIELD::test_FORMFIELD_Item10398
HierarchicalWebsTests has 3 unexpected results (of 14):
   * F: HierarchicalWebsTests::test_squab_subweb
   * F: HierarchicalWebsTests::test_squab_subweb_full_path
   * F: HierarchicalWebsTests::test_squab_simple
RenderFormTests has 3 unexpected results (of 7):
   * F: RenderFormTests::test_nondefined_form
   * F: RenderFormTests::test_timing_static_multivalues
   * F: RenderFormTests::test_timing_dynamic_multivalues
LoadedRevTests has 3 unexpected results (of 5):
   * F: LoadedRevTests::test_no_comma_v
   * F: LoadedRevTests::test_phantom_topic
   * F: LoadedRevTests::test_good_topic
ViewScriptTests has 3 unexpected results (of 4):
   * F: ViewScriptTests::test_render_raw
   * F: ViewScriptTests::test_urlparsing
   * F: ViewScriptTests::test_prepostamble
AccessControlTests has 3 unexpected results (of 18):
   * F: AccessControlTests::test_subweb_inherits_from_parent
   * F: AccessControlTests::test_subweb_controls_override_parent
   * F: AccessControlTests::test_finalised_parent_overrides_subweb
PreferencesPluginTests has 4 unexpected results (of 5):
   * F: PreferencesPluginTests::test_edit_multiple_with_comments
   * F: PreferencesPluginTests::test_save
   * F: PreferencesPluginTests::test_edit_multiple_with_verbatim
   * F: PreferencesPluginTests::test_edit_simple
VCMetaTests has 4 unexpected results (of 10):
   * F: VCMetaTests::verify_rename_VCMetaTests_RcsWrap
   * F: VCMetaTests::verify_checkin_attachment_VCMetaTests_RcsWrap
   * F: VCMetaTests::verify_rename_VCMetaTests_RcsLite
   * F: VCMetaTests::verify_checkin_attachment_VCMetaTests_RcsLite
RESTTests has 4 unexpected results (of 5):
   * F: RESTTests::test_simple
   * F: RESTTests::test_validate
   * F: RESTTests::test_http_allow
   * F: RESTTests::test_authenticate
ExtendedTranslatorTests has 4 unexpected results (of 63):
   * F: ExtendedTranslatorTests::testROUNDTRIP_preserveNoExistingTags
   * F: ExtendedTranslatorTests::testROUNDTRIP_UnconvertableTextIsProtected
   * F: ExtendedTranslatorTests::testTML2HTML_UnconvertableTextIsProtected
   * F: ExtendedTranslatorTests::testROUNDTRIP_Item1798_NoTablePlugin
SaveScriptTests has 5 unexpected results (of 26):
   * F: SaveScriptTests::test_merge
   * F: SaveScriptTests::test_templateTopicWithAttachments
   * F: SaveScriptTests::test_simpleTextSaveDeniedWebCHANGE
   * F: SaveScriptTests::test_missingWebSave
   * F: SaveScriptTests::test_1897
VCStoreTests has 5 unexpected results (of 24):
   * F: VCStoreTests::verify_Inconsistent_implicitSave_VCStoreTests_RcsWrap
   * F: VCStoreTests::verify_Inconsistent_repRev_VCStoreTests_RcsWrap
   * F: VCStoreTests::verify_NoHistory_TOPICINFO_getRevisionInfo_VCStoreTests_RcsWrap
   * F: VCStoreTests::verify_Inconsistent_implicitSave_VCStoreTests_RcsLite
   * F: VCStoreTests::verify_NoHistory_TOPICINFO_getRevisionInfo_VCStoreTests_RcsLite
ManageDotPmTests has 6 unexpected results (of 19):
   * F: ManageDotPmTests::test_SingleAddToNewGroupCreate
   * F: ManageDotPmTests::test_createEmptyWeb
   * F: ManageDotPmTests::test_saveSettings_denied
   * F: ManageDotPmTests::test_TwiceAddToNewGroupCreate
   * F: ManageDotPmTests::test_DoubleAddToNewGroupCreate
   * F: ManageDotPmTests::test_createDefaultWeb
SemiAutomaticTestCaseTests has 6 unexpected results (of 24):
   * F: SemiAutomaticTestCaseTests::test_TestCaseAutoFormattedSearch
   * F: SemiAutomaticTestCaseTests::test_TestCaseAutoFormattedSearchDetails
   * F: SemiAutomaticTestCaseTests::test_TestCaseAutoIncludeAttachment
   * F: SemiAutomaticTestCaseTests::test_TestCaseAutoInternalTags
   * F: SemiAutomaticTestCaseTests::test_TestCaseAutoSearch
   * F: SemiAutomaticTestCaseTests::test_TestCaseAutoSearchOrder
TWikiFuncTests has 6 unexpected results (of 24):
   * F: TWikiFuncTests::test_checkAccessPermission
   * F: TWikiFuncTests::test_attachments
   * F: TWikiFuncTests::test_web
   * F: TWikiFuncTests::test_leases
   * F: TWikiFuncTests::test_moveAttachment
   * F: TWikiFuncTests::test_checkAccessPermission_421
TOCTests has 6 unexpected results (of 7):
   * F: TOCTests::test_Item2458
   * F: TOCTests::test_Item9009
   * F: TOCTests::test_no_parameters
   * F: TOCTests::test_TOC_SpecialCharacters
   * F: TOCTests::test_Item8592
   * F: TOCTests::test_parameters
MailerContribSuite has 7 unexpected results (of 9):
   * F: MailerContribSuite::testSubweb
   * F: MailerContribSuite::testExpansion
   * F: MailerContribSuite::testExpansion_1847
   * F: MailerContribSuite::test_changeSubscription_and_isSubScribedTo_API
   * F: MailerContribSuite::testExcluded
   * F: MailerContribSuite::testSimple
   * F: MailerContribSuite::test_5949
MetaTests has 10 unexpected results (of 23):
   * F: MetaTests::test_registerScalarMeta
   * F: MetaTests::test_attachmentStreams
   * F: MetaTests::test_testAttachment
   * F: MetaTests::test_registerArrayMeta
   * F: MetaTests::test_attach_stream
   * F: MetaTests::test_validateMetaTagsInText
   * F: MetaTests::test_registerMETA
   * F: MetaTests::test_attach_file_and_stream
   * F: MetaTests::test_attach_file
   * F: MetaTests::test_parent
ExpandMacrosTests has 11 unexpected results (of 11):
   * F: ExpandMacrosTests::test_inlineWithEmbeddedNewline
   * F: ExpandMacrosTests::test_simpleNestedMacrosInline
   * F: ExpandMacrosTests::test_nonDelayedExpansionInline
   * F: ExpandMacrosTests::test_delayedExpansionInlineTypeString
   * F: ExpandMacrosTests::test_delayedExpansionInline
   * F: ExpandMacrosTests::test_preferenceOverridesMacro
   * F: ExpandMacrosTests::test_makeSureDontCareWorks
   * F: ExpandMacrosTests::test_preferenceWithParameter
   * F: ExpandMacrosTests::test_plainInline
   * F: ExpandMacrosTests::test_EXPAND_bad
   * F: ExpandMacrosTests::test_inlineWithDoubleEscapedQuotes
StoreTests has 11 unexpected results (of 36):
   * F: StoreTests::test_getRevisionInfoNoRcsFile
   * F: StoreTests::verify_attachmentSaveHandlers_file_StoreTests_RcsWrap
   * F: StoreTests::verify_attachmentSaveHandlers_file_and_stream_StoreTests_RcsWrap
   * F: StoreTests::verify_beforeSaveHandlerChangeBoth_StoreTests_RcsWrap
   * F: StoreTests::verify_attachmentSaveHandlers_stream_StoreTests_RcsWrap
   * F: StoreTests::verify_eachAttachment_StoreTests_RcsWrap
   * F: StoreTests::verify_attachmentSaveHandlers_file_StoreTests_RcsLite
   * F: StoreTests::verify_attachmentSaveHandlers_file_and_stream_StoreTests_RcsLite
   * F: StoreTests::verify_beforeSaveHandlerChangeBoth_StoreTests_RcsLite
   * F: StoreTests::verify_attachmentSaveHandlers_stream_StoreTests_RcsLite
   * F: StoreTests::verify_eachAttachment_StoreTests_RcsLite
TopicUserMappingAsGuestTests has 12 unexpected results (of 20):
   * F: TopicUserMappingAsGuestTests::verify_getListOfGroups_useHtpasswdMgr_NormalTopicUserMapping
   * F: TopicUserMappingAsGuestTests::verify_eachGroupMemberGROUPINFO_useHtpasswdMgr_NormalTopicUserMapping
   * F: TopicUserMappingAsGuestTests::verify_eachGroupMember_useHtpasswdMgr_NormalTopicUserMapping
   * F: TopicUserMappingAsGuestTests::verify_getListOfGroups_useHtpasswdMgr_NamedTopicUserMapping
   * F: TopicUserMappingAsGuestTests::verify_eachGroupMemberGROUPINFO_useHtpasswdMgr_NamedTopicUserMapping
   * F: TopicUserMappingAsGuestTests::verify_eachGroupMember_useHtpasswdMgr_NamedTopicUserMapping
   * F: TopicUserMappingAsGuestTests::verify_getListOfGroups_noPasswdMgr_NormalTopicUserMapping
   * F: TopicUserMappingAsGuestTests::verify_eachGroupMemberGROUPINFO_noPasswdMgr_NormalTopicUserMapping
   * F: TopicUserMappingAsGuestTests::verify_eachGroupMember_noPasswdMgr_NormalTopicUserMapping
   * F: TopicUserMappingAsGuestTests::verify_getListOfGroups_noPasswdMgr_NamedTopicUserMapping
   * F: TopicUserMappingAsGuestTests::verify_eachGroupMemberGROUPINFO_noPasswdMgr_NamedTopicUserMapping
   * F: TopicUserMappingAsGuestTests::verify_eachGroupMember_noPasswdMgr_NamedTopicUserMapping
ViewFileScriptTests has 13 unexpected results (of 14):
   * F: ViewFileScriptTests::test_nested_web_secured_topic_direct_path
   * F: ViewFileScriptTests::test_simple_topic_filename_param
   * F: ViewFileScriptTests::test_simple_web_secured_topic_filename_param
   * F: ViewFileScriptTests::test_binary_contents
   * F: ViewFileScriptTests::test_nested_web_simple_topic_direct_path
   * F: ViewFileScriptTests::test_simple_textfile
   * F: ViewFileScriptTests::test_nested_web_simple_topic_filename_param
   * F: ViewFileScriptTests::test_case_sensitivity
   * F: ViewFileScriptTests::test_oddities
   * F: ViewFileScriptTests::test_simple_web_secured_topic_direct_path
   * F: ViewFileScriptTests::test_nasty_attachment_names
   * F: ViewFileScriptTests::test_simpleUrl
   * F: ViewFileScriptTests::test_nested_web_secured_topic_filename_param
CommentPluginTests has 14 unexpected results (of 17):
   * F: CommentPluginTests::test_targetWebTopicAnchorBottom
   * F: CommentPluginTests::test_targetWebTopicAboveAnchor_Missing_Item727
   * F: CommentPluginTests::test_above
   * F: CommentPluginTests::test_location
   * F: CommentPluginTests::test_targetWebTopic
   * F: CommentPluginTests::test_LocationRE
   * F: CommentPluginTests::test_targetWebTopicBelowAnchor_Missing_Item727
   * F: CommentPluginTests::test_below
   * F: CommentPluginTests::test_rest_control_modes
   * F: CommentPluginTests::test_targetWebTopicAnchorTop
   * F: CommentPluginTests::test_nopost
   * F: CommentPluginTests::test_acl_COMMENT
   * F: CommentPluginTests::test_remove
   * F: CommentPluginTests::test_targetTopic
HTMLValidationTests has 14 unexpected results (of 98):
   * F: HTMLValidationTests::test_edit_with_urlparam_presets
   * F: HTMLValidationTests::test_edit_without_urlparam_presets
   * F: HTMLValidationTests::verify_switchboard_function_edit_default
   * F: HTMLValidationTests::verify_switchboard_function_edit_pattern
   * F: HTMLValidationTests::verify_switchboard_function_edit_plain
   * F: HTMLValidationTests::verify_switchboard_function_edit_print
   * F: HTMLValidationTests::verify_switchboard_function_rename_default
   * F: HTMLValidationTests::verify_switchboard_function_rename_pattern
   * F: HTMLValidationTests::verify_switchboard_function_rename_plain
   * F: HTMLValidationTests::verify_switchboard_function_rename_print
   * F: HTMLValidationTests::verify_switchboard_function_changes_default
   * F: HTMLValidationTests::verify_switchboard_function_changes_pattern
   * F: HTMLValidationTests::verify_switchboard_function_changes_plain
   * F: HTMLValidationTests::verify_switchboard_function_changes_print
InterwikiPluginTests has 15 unexpected results (of 15):
   * F: InterwikiPluginTests::test_link_from_local_rules_topic
   * F: InterwikiPluginTests::test_link_with_parentheses
   * F: InterwikiPluginTests::test_link_with_topic_name
   * F: InterwikiPluginTests::test_bold_link
   * F: InterwikiPluginTests::test_italic_link
   * F: InterwikiPluginTests::test_link_from_default_rules_topic
   * F: InterwikiPluginTests::test_link_format
   * F: InterwikiPluginTests::test_strong_code_link
   * F: InterwikiPluginTests::test_link_from_inherted_rules_topic
   * F: InterwikiPluginTests::test_link_with_quoted_string
   * F: InterwikiPluginTests::test_link_in_parentheses
   * F: InterwikiPluginTests::test_link_with_url
   * F: InterwikiPluginTests::test_code_link
   * F: InterwikiPluginTests::test_cant_view_rules_topic
   * F: InterwikiPluginTests::test_link_with_complex_url
TranslatorTests has 16 unexpected results (of 301):
   * F: TranslatorTests::testROUNDTRIP_stickyInsideLiteral
   * F: TranslatorTests::testTML2HTML_Item9973_cp1251
   * F: TranslatorTests::testROUNDTRIP_Item1798
   * F: TranslatorTests::testROUNDTRIP_Item9973_cp1251
   * F: TranslatorTests::testTML2HTML_stuffInMacro
   * F: TranslatorTests::testROUNDTRIP_Item4855
   * F: TranslatorTests::testTML2HTML_Item5132
   * F: TranslatorTests::testROUNDTRIP_Item4789
   * F: TranslatorTests::testROUNDTRIP_sticky
   * F: TranslatorTests::testROUNDTRIP_verbatimInsideLiteralItem1980
   * F: TranslatorTests::testHTML2TML_Item9973_cp1251
   * F: TranslatorTests::testROUNDTRIP_Item1140
   * F: TranslatorTests::testROUNDTRIP_variableInIMGtag
   * F: TranslatorTests::testROUNDTRIP_stuffInMacro
   * F: TranslatorTests::testTML2HTML_variableInIMGtag
   * F: TranslatorTests::testHTML2TML_variableInIMGtag
UIFnCompileTests has 16 unexpected results (of 72):
   * F: UIFnCompileTests::verify_switchboard_function_nonExistantTopic_logon
   * F: UIFnCompileTests::verify_switchboard_function_nonExistantWeb_logon
   * F: UIFnCompileTests::verify_switchboard_function_nonExistantTopic_viewauth
   * F: UIFnCompileTests::verify_switchboard_function_nonExistantWeb_oops
   * F: UIFnCompileTests::verify_switchboard_function_rename
   * F: UIFnCompileTests::verify_switchboard_function_nonExistantWeb_save
   * F: UIFnCompileTests::verify_switchboard_function_nonExistantTopic_view
   * F: UIFnCompileTests::verify_switchboard_function_nonExistantTopic_previewauth
   * F: UIFnCompileTests::verify_switchboard_function_nonExistantWeb_previewauth
   * F: UIFnCompileTests::verify_switchboard_function_nonExistantTopic_login
   * F: UIFnCompileTests::verify_switchboard_function_nonExistantWeb_login
   * F: UIFnCompileTests::verify_switchboard_function_nonExistantTopic_changes
   * F: UIFnCompileTests::verify_switchboard_function_changes
   * F: UIFnCompileTests::verify_switchboard_function_nonExistantWeb_changes
   * F: UIFnCompileTests::verify_switchboard_function_nonExistantTopic_preview
   * F: UIFnCompileTests::verify_switchboard_function_nonExistantWeb_preview
FuncTests has 17 unexpected results (of 50):
   * F: FuncTests::test_CreateWebShouldFailIfWebExists
   * F: FuncTests::test_attachment_comment
   * F: FuncTests::test_moveWeb
   * F: FuncTests::test_checkAccessPermission
   * F: FuncTests::test_attachments
   * F: FuncTests::test_copyAttachment
   * F: FuncTests::test_checkWebAccessPermission
   * F: FuncTests::test_subweb_attachments
   * F: FuncTests::test_createWeb_permissions
   * F: FuncTests::test_leases
   * F: FuncTests::test_getAttachmentList
   * F: FuncTests::test_checkAccessPermission_login_name
   * F: FuncTests::test_unicode_attachment_utf8_encoded
   * F: FuncTests::test_eachChangeSince
   * F: FuncTests::test_getrevinfo
   * F: FuncTests::test_noauth_saveTopic
   * F: FuncTests::test_moveAttachment
PluginHandlerTests has 19 unexpected results (of 19):
   * F: PluginHandlerTests::test_afterAttachmentSaveHandler
   * F: PluginHandlerTests::test_redirectrequestHandler
   * F: PluginHandlerTests::test_earlyInit
   * F: PluginHandlerTests::test_saveHandlers
   * F: PluginHandlerTests::test_writeHeaderHandler
   * F: PluginHandlerTests::test_afterRenameHandler
   * F: PluginHandlerTests::test_renderWikiWordHandler
   * F: PluginHandlerTests::test_renderFormFieldForEditHandler
   * F: PluginHandlerTests::test_afterEditHandler
   * F: PluginHandlerTests::test_modifyHeaderHandler
   * F: PluginHandlerTests::test_registrationHandler
   * F: PluginHandlerTests::test_commonTagsHandlers
   * F: PluginHandlerTests::test_afterUploadHandler
   * F: PluginHandlerTests::test_beforeAttachmentSaveHandler
   * F: PluginHandlerTests::test_mergeHandler
   * F: PluginHandlerTests::test_renderingHandlers
   * F: PluginHandlerTests::test_beforeUploadHandler
   * F: PluginHandlerTests::test_beforeEditHandler
   * F: PluginHandlerTests::test_finishPlugin
CacheTests has 20 unexpected results (of 20):
   * F: CacheTests::verify_view_FileCache_DBFileMeta_NoCompress
   * F: CacheTests::verify_view_FileCache_DBFileMeta_Compress
   * F: CacheTests::verify_view_FileCache_BDBMeta_NoCompress
   * F: CacheTests::verify_view_FileCache_BDBMeta_Compress
   * F: CacheTests::verify_view_DB_File_DBFileMeta_NoCompress
   * F: CacheTests::verify_view_DB_File_DBFileMeta_Compress
   * F: CacheTests::verify_view_DB_File_BDBMeta_NoCompress
   * F: CacheTests::verify_view_DB_File_BDBMeta_Compress
   * F: CacheTests::verify_view_MemoryHash_DBFileMeta_NoCompress
   * F: CacheTests::verify_view_MemoryHash_DBFileMeta_Compress
   * F: CacheTests::verify_view_MemoryHash_BDBMeta_NoCompress
   * F: CacheTests::verify_view_MemoryHash_BDBMeta_Compress
   * F: CacheTests::verify_view_MemoryCache_DBFileMeta_NoCompress
   * F: CacheTests::verify_view_MemoryCache_DBFileMeta_Compress
   * F: CacheTests::verify_view_MemoryCache_BDBMeta_NoCompress
   * F: CacheTests::verify_view_MemoryCache_BDBMeta_Compress
   * F: CacheTests::verify_view_MemoryLRU_DBFileMeta_NoCompress
   * F: CacheTests::verify_view_MemoryLRU_DBFileMeta_Compress
   * F: CacheTests::verify_view_MemoryLRU_BDBMeta_NoCompress
   * F: CacheTests::verify_view_MemoryLRU_BDBMeta_Compress
RenameTests has 22 unexpected results (of 26):
   * F: RenameTests::test_renameWeb_1307a
   * F: RenameTests::test_rename_attachment_Rename_Allowed_Change_Denied
   * F: RenameTests::test_renameTopic_preserves_history
   * F: RenameTests::test_renameTopic_new_web_same_topic_name_no_access
   * F: RenameTests::test_renameWeb_10990
   * F: RenameTests::test_rename_topic_reference_in_denied_web
   * F: RenameTests::test_renameTopic_new_web_same_topic_name
   * F: RenameTests::test_renameTopic_same_web_new_topic_name
   * F: RenameTests::test_renameTopic_TOPICRENAME_access_denied
   * F: RenameTests::test_renameTopic_find_referring_topics_in_all_webs
   * F: RenameTests::test_rename_attachment_Rename_Denied_Change_Allowed
   * F: RenameTests::test_renameWeb_1307b
   * F: RenameTests::test_renameTopic_WEBRENAME_access_denied
   * F: RenameTests::test_renameTemplateThisWeb
   * F: RenameTests::test_rename_attachment_no_dest_topic
   * F: RenameTests::test_renameTopic_ensure_leases_are_released
   * F: RenameTests::test_renameSubWeb_10259
   * F: RenameTests::test_renameTopic_with_lowercase_first_letter
   * F: RenameTests::test_rename_attachment_not_in_meta
   * F: RenameTests::test_renameWeb_10259
   * F: RenameTests::test_rename_attachment
   * F: RenameTests::test_renameTopic_nonWikiWord_same_web_new_topic_name
Fn_SEARCH has 23 unexpected results (of 338):
   * F: Fn_SEARCH::test_pager_on_pagerformat
   * F: Fn_SEARCH::test_pager_on
   * F: Fn_SEARCH::test_orderTopic
   * F: Fn_SEARCH::test_groupby_none_using_subwebs
   * F: Fn_SEARCH::test_minus_scope_all
   * F: Fn_SEARCH::verify_likeQuery2_ForkingSearch
   * F: Fn_SEARCH::verify_scope_all_type_word_ForkingSearch
   * F: Fn_SEARCH::verify_crossweb_op_ref_ForkingSearch
   * F: Fn_SEARCH::verify_scope_all_type_keyword_ForkingSearch
   * F: Fn_SEARCH::verify_Item10398_ForkingSearch
   * F: Fn_SEARCH::verify_date_param_ForkingSearch
   * F: Fn_SEARCH::verify_likeQuery2_PurePerlSearch
   * F: Fn_SEARCH::verify_scope_all_type_word_PurePerlSearch
   * F: Fn_SEARCH::verify_crossweb_op_ref_PurePerlSearch
   * F: Fn_SEARCH::verify_scope_all_type_keyword_PurePerlSearch
   * F: Fn_SEARCH::verify_Item10398_PurePerlSearch
   * F: Fn_SEARCH::verify_date_param_PurePerlSearch
   * F: Fn_SEARCH::verify_likeQuery2_BruteForceQuery
   * F: Fn_SEARCH::verify_scope_all_type_word_BruteForceQuery
   * F: Fn_SEARCH::verify_crossweb_op_ref_BruteForceQuery
   * F: Fn_SEARCH::verify_scope_all_type_keyword_BruteForceQuery
   * F: Fn_SEARCH::verify_Item10398_BruteForceQuery
   * F: Fn_SEARCH::verify_date_param_BruteForceQuery
FuncUsersTests has 24 unexpected results (of 288):
   * F: FuncUsersTests::verify_topic_meta_usermapping_NoLoginManager_AllowLoginName_NonePasswordManager_TopicUserMapping
   * F: FuncUsersTests::verify_topic_meta_usermapping_NoLoginManager_AllowLoginName_HtPasswordPasswordManager_TopicUserMapping
   * F: FuncUsersTests::verify_removeFromGroup_NoLoginManager_AllowLoginName_HtPasswordPasswordManager_TopicUserMapping
   * F: FuncUsersTests::verify_NestedGroups_NoLoginManager_AllowLoginName_HtPasswordPasswordManager_TopicUserMapping
   * F: FuncUsersTests::verify_addToGroup_NoLoginManager_AllowLoginName_HtPasswordPasswordManager_TopicUserMapping
   * F: FuncUsersTests::verify_removeFromGroup_NoLoginManager_DontAllowLoginName_HtPasswordPasswordManager_TopicUserMapping
   * F: FuncUsersTests::verify_NestedGroups_NoLoginManager_DontAllowLoginName_HtPasswordPasswordManager_TopicUserMapping
   * F: FuncUsersTests::verify_addToGroup_NoLoginManager_DontAllowLoginName_HtPasswordPasswordManager_TopicUserMapping
   * F: FuncUsersTests::verify_topic_meta_usermapping_ApacheLoginManager_AllowLoginName_NonePasswordManager_TopicUserMapping
   * F: FuncUsersTests::verify_topic_meta_usermapping_ApacheLoginManager_AllowLoginName_HtPasswordPasswordManager_TopicUserMapping
   * F: FuncUsersTests::verify_removeFromGroup_ApacheLoginManager_AllowLoginName_HtPasswordPasswordManager_TopicUserMapping
   * F: FuncUsersTests::verify_NestedGroups_ApacheLoginManager_AllowLoginName_HtPasswordPasswordManager_TopicUserMapping
   * F: FuncUsersTests::verify_addToGroup_ApacheLoginManager_AllowLoginName_HtPasswordPasswordManager_TopicUserMapping
   * F: FuncUsersTests::verify_removeFromGroup_ApacheLoginManager_DontAllowLoginName_HtPasswordPasswordManager_TopicUserMapping
   * F: FuncUsersTests::verify_NestedGroups_ApacheLoginManager_DontAllowLoginName_HtPasswordPasswordManager_TopicUserMapping
   * F: FuncUsersTests::verify_addToGroup_ApacheLoginManager_DontAllowLoginName_HtPasswordPasswordManager_TopicUserMapping
   * F: FuncUsersTests::verify_topic_meta_usermapping_TemplateLoginManager_AllowLoginName_NonePasswordManager_TopicUserMapping
   * F: FuncUsersTests::verify_topic_meta_usermapping_TemplateLoginManager_AllowLoginName_HtPasswordPasswordManager_TopicUserMapping
   * F: FuncUsersTests::verify_removeFromGroup_TemplateLoginManager_AllowLoginName_HtPasswordPasswordManager_TopicUserMapping
   * F: FuncUsersTests::verify_NestedGroups_TemplateLoginManager_AllowLoginName_HtPasswordPasswordManager_TopicUserMapping
   * F: FuncUsersTests::verify_addToGroup_TemplateLoginManager_AllowLoginName_HtPasswordPasswordManager_TopicUserMapping
   * F: FuncUsersTests::verify_removeFromGroup_TemplateLoginManager_DontAllowLoginName_HtPasswordPasswordManager_TopicUserMapping
   * F: FuncUsersTests::verify_NestedGroups_TemplateLoginManager_DontAllowLoginName_HtPasswordPasswordManager_TopicUserMapping
   * F: FuncUsersTests::verify_addToGroup_TemplateLoginManager_DontAllowLoginName_HtPasswordPasswordManager_TopicUserMapping
EditTablePluginTests has 33 unexpected results (of 39):
   * F: EditTablePluginTests::test_TMLFormattingInsideCell_BR
   * F: EditTablePluginTests::test_param_format_with_variables
   * F: EditTablePluginTests::test_keepStars
   * F: EditTablePluginTests::test_render_simple_pre
   * F: EditTablePluginTests::test_TABLE_on_same_line_as_EDITTABLE_TABLE_last
   * F: EditTablePluginTests::test_do_not_add_newline
   * F: EditTablePluginTests::test_keepSpacesInEmptyCellsWithTexts
   * F: EditTablePluginTests::test_render_simple_with_verbatim_and_unfinished_table_rows
   * F: EditTablePluginTests::test_param_format_selectbox
   * F: EditTablePluginTests::test_lineBreaksInsideInputField
   * F: EditTablePluginTests::test_INCLUDE_include
   * F: EditTablePluginTests::test_INCLUDE_view
   * F: EditTablePluginTests::test_save
   * F: EditTablePluginTests::test_CALC_substitution
   * F: EditTablePluginTests::test_param_format_variable_expansion_in_checkbox_and_radio_buttons
   * F: EditTablePluginTests::test_CALC_in_table_other_than_EDITTABLE
   * F: EditTablePluginTests::test_param_format_edit
   * F: EditTablePluginTests::test_macro_EDITCELL_save
   * F: EditTablePluginTests::test_TABLE_on_same_line_as_EDITTABLE_TABLE_first
   * F: EditTablePluginTests::test_editAddRow
   * F: EditTablePluginTests::test_render_simple_before_after
   * F: EditTablePluginTests::test_save_with_verbatim_inside_table
   * F: EditTablePluginTests::test_TMLFormattingInsideCell_tag_br
   * F: EditTablePluginTests::test_delete_last_row
   * F: EditTablePluginTests::test_editSimple
   * F: EditTablePluginTests::test_render_simple
   * F: EditTablePluginTests::test_keepSpacesInEmptyCellsWithDates
   * F: EditTablePluginTests::test_param_buttonrow_top_edit
   * F: EditTablePluginTests::test_save_with_encode_param_and_footerrows
   * F: EditTablePluginTests::test_addSpacesToEmptyCells
   * F: EditTablePluginTests::test_param_changerows_off
   * F: EditTablePluginTests::test_save_with_verbatim_in_topic
   * F: EditTablePluginTests::test_param_format_with_macro_placeholders_edit
----------------------------
3124 of 3513 test cases passed (expected 3512 of 3513).
0 + 388 = 385 incorrect results from unexpected passes + failures
1..74962

real   26m6.273s
user   20m7.519s
sys   4m37.797s

-- SvenDowideit - 10 Dec 2011

In case we're wondering where we are with this, I think I've finished refactoring the tests in svn:
  1. trunk and Release01x01 now use exactly the same UnitTestContrib
  2. All usage of Foswiki::Meta in the tests has been purged, except where we're actually testing Foswiki::Meta itself:
    • Foswiki::Meta->new where topic $obj can be loaded -> Foswiki::Func::readTopic
    • Foswiki::Meta->new where topic $obj needs to be unloaded -> FoswikiTestCase ->getUnloadedTopicObject
    • Foswiki::Meta->new for web $obj -> FoswikiTestCase ->getWebObject
    • Foswiki::Meta->populateNewWeb -> FoswikiTestCase ->populateNewWeb
    • Foswiki::Meta->removeFromStore -> FoswikiTestCase ->removeFromStore
  3. Added check_dependency, skip, expect_failure('foo', with_dep => bar, using => cat) functionality

I regret the time it took to do all this, but I do feel it was the proper, less error-prone thing to do.

-- PaulHarvey - 12 Feb 2012

excellent, and thankyou again smile and now its all back to me again smile

-- SvenDowideit - 12 Feb 2012

Deferred to Foswiki 2.0

Update: the new 'unified' tests have problems on store2, I am working through those. So it's actually back to me.

-- PaulHarvey - 23 Feb 2012

see MultiStoreRefactor for a broader functional intention. this is more to do with developing the API to the rest of the core.

-- SvenDowideit - 31 May 2012

Item11135 has a large number of commits, but all are in unit tests. Some of the refactoring work is in the abandoned svn scratch branch. Changing to a Parked proposal. Needs a developer to adopt.

-- GeorgeClark - 19 Nov 2015
Topic revision: r31 - 19 Nov 2015, GeorgeClark
The copyright of the content on this website is held by the contributing authors, except where stated elsewhere. See Copyright Statement. Creative Commons License    Legal Imprint    Privacy Policy