I spent some time browsing the Store code to figure out how to handle
prerequisite versioning. I found a lot of string hacking and ad-hoc functionality surrounding the version strings. Isn't a version actually a kind of Magnitude? I believe it would make much sense to implement the behavior of versions in a class: Magnitude AbstractVersion TwoLevelVersion (e.g. "1.8") ThreeLevelVersion (e.g. "1.8.44") MyCustomVersion (e.g. "Stable 1.8.23 Beta - Build# 22441") ... Store should only rely on AbstractVersion's protocols. There's a lot of benefit in having appropriate methods for comparison (#<, #=, #>), incrementing (#nextMinor, #nextMajor) and more specific testers and operators, for example #inSameStreamWith: aVersion. Versions could have textual prefixes and suffixes attached, convert to and from Strings, etc. I'm not sure if adding more attributes would be clean, but it's possible. The most important functionality, IMHO, is a clean database mapping (Store, or a customer's product database). Handling complex version numbers in SQL can be hell in that queries blow up with complicated expressions handling the numeric versioning components individually. I love the idea. There's much arbitrariness in how versions are currently handled. This would definately clean it up. Moreover, it'd be a nice place to start from for customers that need to implement some kind of software engineering management (= all customers). What do you think? Any volunteers? Andre |
Hallo Herr Schnoor,
ich finde die Idee klasse und werde sie intern weiterleiten und unterstützen. Allerdings möchte ich nicht auf die Liste posten, damit das nicht als Cincom-Commitment mißverstanden wird. Herzliche Grüße Helge Nowak -----Ursprüngliche Nachricht----- Von: [hidden email] [mailto:[hidden email]] Gesendet: Dienstag, 9. Mai 2006 08:24 An: vwnc-list Betreff: Suggestion: Versions = Magnitudes I spent some time browsing the Store code to figure out how to handle prerequisite versioning. I found a lot of string hacking and ad-hoc functionality surrounding the version strings. Isn't a version actually a kind of Magnitude? I believe it would make much sense to implement the behavior of versions in a class: Magnitude AbstractVersion TwoLevelVersion (e.g. "1.8") ThreeLevelVersion (e.g. "1.8.44") MyCustomVersion (e.g. "Stable 1.8.23 Beta - Build# 22441") ... Store should only rely on AbstractVersion's protocols. There's a lot of benefit in having appropriate methods for comparison (#<, #=, #>), incrementing (#nextMinor, #nextMajor) and more specific testers and operators, for example #inSameStreamWith: aVersion. Versions could have textual prefixes and suffixes attached, convert to and from Strings, etc. I'm not sure if adding more attributes would be clean, but it's possible. The most important functionality, IMHO, is a clean database mapping (Store, or a customer's product database). Handling complex version numbers in SQL can be hell in that queries blow up with complicated expressions handling the numeric versioning components individually. I love the idea. There's much arbitrariness in how versions are currently handled. This would definately clean it up. Moreover, it'd be a nice place to start from for customers that need to implement some kind of software engineering management (= all customers). What do you think? Any volunteers? Andre |
In reply to this post by Andre Schnoor
Hi Andre,
Even though I don't use store, I agree it's a good idea. Please find attached a simple Version class that I use. With the addition of a prefix instance variable, it would cater for your example without the need for subclassing. I didn't subclass Magnitude, but feel free to do so! HTH, Stewart >-----Original Message----- >From: [hidden email] [mailto:[hidden email]] >Sent: Tuesday, 9 May 2006 6:24 p.m. >To: vwnc-list >Subject: Suggestion: Versions = Magnitudes > >I spent some time browsing the Store code to figure out how to handle >prerequisite versioning. I found a lot of string hacking and ad-hoc >functionality surrounding the version strings. Isn't a version actually >a kind of Magnitude? I believe it would make much sense to implement >behavior of versions in a class: > >Magnitude > AbstractVersion > TwoLevelVersion (e.g. "1.8") > ThreeLevelVersion (e.g. "1.8.44") > MyCustomVersion (e.g. "Stable 1.8.23 Beta - Build# > ... > >Store should only rely on AbstractVersion's protocols. There's a lot of >benefit in having appropriate methods for comparison (#<, #=, #>), >incrementing (#nextMinor, #nextMajor) and more specific testers and >operators, for example #inSameStreamWith: aVersion. Versions could have >textual prefixes and suffixes attached, convert to and from Strings, >etc. I'm not sure if adding more attributes would be clean, but it's >possible. > >The most important functionality, IMHO, is a clean database mapping >(Store, or a customer's product database). Handling complex version >numbers in SQL can be hell in that queries blow up with complicated >expressions handling the numeric versioning components individually. > >I love the idea. There's much arbitrariness in how versions are >currently handled. This would definately clean it up. Moreover, it'd be >a nice place to start from for customers that need to implement some >kind of software engineering management (= all customers). > >What do you think? Any volunteers? > >Andre > > Version.st (4K) Download Attachment |
In reply to this post by Andre Schnoor
Andre Schnoor wrote:
> I spent some time browsing the Store code to figure out how to handle > prerequisite versioning. I found a lot of string hacking and ad-hoc > functionality surrounding the version strings. Isn't a version actually > a kind of Magnitude? short answer: no. being a magnitude implies that versions have a linear order, which is not true, with regard to branching / merging. Branching implies that versions constitute a tree, and merging implies that versions constitute a graph. regards, Holger |
In reply to this post by Andre Schnoor
I have previously created such a class. My class assumes versions
consisting of numbers only, for example 123.22 and 1.2.3.4. The class is named NumericSoftwareVersion and is in package "Epigent Store Configuration Support". The package also includes a test class. Please refer to these links for more information about this package: http://www.cincomsmalltalk.com/publicRepository/Epigent%20Store%20Configuration%20Support.html and http://www.cincomsmalltalk.com/userblogs/runarj/blogView?showComments=true&entry=3321184256 The class comment says: "Represents a software version by storing the individual 'numerical identifiers' of the version. Subclasses Magnitude to support the Smalltalk comparison protocol. Comparison ignores tailing zeros; Version '1.0' = version '1'." When using the magnitude protocol one has to make a few decisions. For example, consider the two versions 1 and 1.0.0. Are they equal or not, and which one is greater? I choose to append trailing zeros to the version with fewest digits. In the example, 1.0.0 and 1.0.0 would be compared -- they are equal. For the application my class is used in, this choice makes perfect sense. Runar Jordahl |
In reply to this post by Holger Kleinsorgen-4
Holger Kleinsorgen wrote:
> Andre Schnoor wrote: > >> I spent some time browsing the Store code to figure out how to handle >> prerequisite versioning. I found a lot of string hacking and ad-hoc >> functionality surrounding the version strings. Isn't a version >> actually a kind of Magnitude? > > > short answer: no. > > being a magnitude implies that versions have a linear order, which is > not true, with regard to branching / merging. Branching implies that > versions constitute a tree, and merging implies that versions constitute > a graph. ps: of course you could define some kind of linear order, but I can't think of any order that makes sense. if I have version 1.1 and branches 1.1.dev1 and 1.1.dev2, how would you compare these branches? they are both direct successors of 1.1, and there's no justification for 1.1.dev1 being "less than" 1.1.dev2 or 1.1.dev2 being "less than" 1.1.dev1 . Holger |
> if I have version 1.1 and branches 1.1.dev1 and 1.1.dev2, how would you
> compare these branches? they are both direct successors of 1.1, and > there's no justification for 1.1.dev1 being "less than" 1.1.dev2 or > 1.1.dev2 being "less than" 1.1.dev1 . My view is that there is an order between at least parts of the version for a component. Clearly, we expect version 1.0 of a product to be "earlier" than version 2.0. So 1.0 < 2.0. Also, version 2.1 appeared after version 2.0. We need this functionality in lists, when finding the latest version of a component etc. The simplest way to support ordering components is to only use groups of number in the version (for example 1.2.3), and let comparison be based on all groups. If one decides not to follow this pattern, one must make more complicated rules, like ignoring the last group etc. To follow your example, there might be two 1.1.1 versions, (and not a 1.1.dev1 and a 1.1.dev2 version), but this is not a problem. It only signals a conflict, which must be merged to a new 1.1.2 version. Runar Jordahl |
Runar Jordahl wrote:
>> if I have version 1.1 and branches 1.1.dev1 and 1.1.dev2, how would you >> compare these branches? they are both direct successors of 1.1, and >> there's no justification for 1.1.dev1 being "less than" 1.1.dev2 or >> 1.1.dev2 being "less than" 1.1.dev1 . > > > My view is that there is an order between at least parts of the > version for a component. Sure, but being a Magnitude forces you to specify an order for *all* versions, which is what I object to. Therefore I would not subclass Magnitude. The Version class could define a partial order, which is perfectly ok. |
In reply to this post by Andre Schnoor
I would agree that version would be best represented by a
Version class than a string. However, I also agree with other responders that it should not be a subclass of Magnitude. Furthermore, Version should include the blessing level and version date, and possibly the version creator. Basically, everything you need to determine if this is the version you want to load. The decision of what version to load is often specified contextually and Version should support this. For examples; load the latest trunk version, load the latest featureX version, or load the latest patchQ version. In these examples, latest version also implies a blessing level of at least Development. Terry =========================================================== Terry Raymond Smalltalk Professional Debug Package Crafted Smalltalk 80 Lazywood Ln. Tiverton, RI 02878 (401) 624-4517 [hidden email] <http://www.craftedsmalltalk.com> =========================================================== > -----Original Message----- > From: [hidden email] [mailto:[hidden email]] > Sent: Tuesday, May 09, 2006 2:24 AM > To: vwnc-list > Subject: Suggestion: Versions = Magnitudes > > I spent some time browsing the Store code to figure out how to handle > prerequisite versioning. I found a lot of string hacking and ad-hoc > functionality surrounding the version strings. Isn't a version actually > a kind of Magnitude? I believe it would make much sense to implement the > behavior of versions in a class: > > Magnitude > AbstractVersion > TwoLevelVersion (e.g. "1.8") > ThreeLevelVersion (e.g. "1.8.44") > MyCustomVersion (e.g. "Stable 1.8.23 Beta - Build# 22441") > ... > > Store should only rely on AbstractVersion's protocols. There's a lot of > benefit in having appropriate methods for comparison (#<, #=, #>), > incrementing (#nextMinor, #nextMajor) and more specific testers and > operators, for example #inSameStreamWith: aVersion. Versions could have > textual prefixes and suffixes attached, convert to and from Strings, > etc. I'm not sure if adding more attributes would be clean, but it's > possible. > > The most important functionality, IMHO, is a clean database mapping > (Store, or a customer's product database). Handling complex version > numbers in SQL can be hell in that queries blow up with complicated > expressions handling the numeric versioning components individually. > > I love the idea. There's much arbitrariness in how versions are > currently handled. This would definately clean it up. Moreover, it'd be > a nice place to start from for customers that need to implement some > kind of software engineering management (= all customers). > > What do you think? Any volunteers? > > Andre > |
In reply to this post by Holger Kleinsorgen-4
Holger Kleinsorgen wrote:
>> Andre Schnoor wrote: >> >>> I spent some time browsing the Store code to figure out how to >>> handle prerequisite versioning. I found a lot of string hacking and >>> ad-hoc functionality surrounding the version strings. Isn't a >>> version actually a kind of Magnitude? >> >> >> short answer: no. >> >> being a magnitude implies that versions have a linear order, which is >> not true, with regard to branching / merging. Branching implies that >> versions constitute a tree, and merging implies that versions >> constitute a graph. > > > ps: of course you could define some kind of linear order, but I can't > think of any order that makes sense. > > if I have version 1.1 and branches 1.1.dev1 and 1.1.dev2, how would > you compare these branches? they are both direct successors of 1.1, > and there's no justification for 1.1.dev1 being "less than" 1.1.dev2 > or 1.1.dev2 being "less than" 1.1.dev1 . > Holger, you are right. It's not a Magnitude, it's a tree. Anyway, a tree structure demands even more a proper handling through behavior instead of "string handling". Andre |
In reply to this post by Runar Jordahl
Runar Jordahl wrote: > The class comment says: "Represents a software version by storing the > individual 'numerical identifiers' of the version. Subclasses > Magnitude to support the Smalltalk comparison protocol. Comparison > ignores tailing zeros; Version '1.0' = version '1'." I suggest not to rely on printed string representation at all. It's nice to print versions and to be able convert them back to objects, but it's much easier to figure out the protocol and attributes of such a class when thinking of it as a composed object (like complex numbers for example). > > When using the magnitude protocol one has to make a few decisions. For > example, consider the two versions 1 and 1.0.0. Are they equal or not, > and which one is greater? I choose to append trailing zeros to the > version with fewest digits. In the example, 1.0.0 and 1.0.0 would be > compared -- they are equal. For the application my class is used in, > this choice makes perfect sense. Absoluetly. Decisions over decisions until one is blue in the face. I'm afraid a cool and re-useable implementation of "Version" will require a good deal of philosophy and meditation before its design will be bullet-proof ;-) Versioning is one of those lovely wheels that get re-invented every day. Bad enough. Andre |
In reply to this post by Terry Raymond
Terry Raymond schrieb: > I would agree that version would be best represented by a > Version class than a string. However, I also agree with > other responders that it should not be a subclass of Magnitude. > > Furthermore, Version should include the blessing level and > version date, and possibly the version creator. Basically, > everything you need to determine if this is the version you > want to load. The decision of what version to load is often > specified contextually and Version should support this. For > examples; load the latest trunk version, load the latest > featureX version, or load the latest patchQ version. In these > examples, latest version also implies a blessing level of > at least Development. > I doubt it'd be good to attach too many administrative attributes to a version. While that is useful in a broader scope, the version itself is not really affected by it. The blessing, for example, can be changed while the versions stays the same. Author/editor and date are also not actually components of the version, but rather administrative details that could be part of some other object which "version" is a component of (amongst others). Andre |
In reply to this post by Andre Schnoor
Actually, as Holger pointed out, it's not even a tree, it's graph...
ricardo On 5/9/06, Andre Schnoor <[hidden email]> wrote: Holger Kleinsorgen wrote: |
Andre -- Ricardo Birmann wrote: Actually, as Holger pointed out, it's not even a tree, it's graph... |
Andre Schnoor wrote:
> AFAIK, merged versions simply become new nodes in a tree, while the > "links" representing the merge operation are kept for informational > purposes only (i.e. to explain from which versions a merged version was > built). This is meta-information ("log file"). Or do I miss something > important? If you are thinking in terms of a tree one of those links will be given special status, it points to some special 'parent'. This is a lobsided view of merging which at it's heart is a symmetric operation. As you probably know it is usually a bad idea to favor one element in a collection above all others (e.g. by sticking it into a special ivar like 'parent') since nearly all the code around it will need two cases to consider which are not different in essence. Hence I would prefer to model ancestry as a DAG, not as a tree with extra parent links stuffed into annotations. Now this is only the view 'from within', in practice we typically assign the merged code to a branch that happens to derive from one of the ancestor versions (we merge some code 'into' a branch) but this is usually only convention. Hence it may help to separate the notions of ancestry (the DAG I suggest above) and version 'streams' which model what gets released into various development stages. Where the ancestry DAG records where code 'came form' the version streams record what is your product, even if there is a wholesale 'burn the disc pack' rewrite going on. R - |
In reply to this post by Andre Schnoor
Andre
I guess it depends on what the version represents. If you mean versionID then ok. If you mean published version the logic still applies. This same distinction must be made with respect to the discussion about the version graph. As Reinout pointed out that a published version may have multiple parents. Furthermore, a published version, with a particular ID, may not clearly follow the actual version graph because the developer adjusted the version number to indicate where he decided it actually belonged. A developer may load an old version then manually make some changes and then publish it as a new version with an ID that jumps ahead. Terry =========================================================== Terry Raymond Smalltalk Professional Debug Package Crafted Smalltalk 80 Lazywood Ln. Tiverton, RI 02878 (401) 624-4517 [hidden email] <http://www.craftedsmalltalk.com> =========================================================== > -----Original Message----- > From: [hidden email] [mailto:[hidden email]] > Sent: Tuesday, May 09, 2006 10:21 AM > To: Terry Raymond > Cc: 'vwnc-list' > Subject: Re: Suggestion: Versions = Magnitudes > > > > Terry Raymond schrieb: > > I would agree that version would be best represented by a > > Version class than a string. However, I also agree with > > other responders that it should not be a subclass of Magnitude. > > > > Furthermore, Version should include the blessing level and > > version date, and possibly the version creator. Basically, > > everything you need to determine if this is the version you > > want to load. The decision of what version to load is often > > specified contextually and Version should support this. For > > examples; load the latest trunk version, load the latest > > featureX version, or load the latest patchQ version. In these > > examples, latest version also implies a blessing level of > > at least Development. > > > > I doubt it'd be good to attach too many administrative attributes to a > version. While that is useful in a broader scope, the version itself is > not really affected by it. The blessing, for example, can be changed > while the versions stays the same. Author/editor and date are also not > actually components of the version, but rather administrative details > that could be part of some other object which "version" is a component > of (amongst others). > > Andre |
Symptom:
I have a set of tests for OmniBase which seem to work fine in the TestRunner but produce a random number of failures in RBSUnitExtensions. Once in a while, the tests pass, but usually there are errors. Each time I run the tests, I get a different number of errors. Sometimes the tests run very fast, giving more errors, and other times the tests run slowly, giving fewer. This seems completely random. If, after I get a bunch of failures in RBSUnitExtensions, I select "Run Defects", they all pass. "Debug" (whatever that actually does) also passes all of the tests. Running anything from the defects list also passes. Again, in all cases, I can use the TestRunner against my test class and everything works as expected. No failures. Questions: So, which one is correct? Do my tests actually work or is there a problem with one of the SUnit UIs? Has anybody else seen this kind of problem? And -- noob question here -- what, exactly, is the difference between an error and a failure, anyway? I know there are some issues with RBSUnitExtensions (multiple select of methods in the browser throws an exception), but I thought they were only UI glitches. Since I am testing a database, I use a TestResource. The test class is written such that each test method is expected to be run alone. If two of these methods are run concurrently (e.g., from two different processes), there could be a locking conflict against the DB. I am *assuming* that SUnit will run the tests one at a time (order doesn't matter). Fair assumption? Set-up: For the curious, the components in question are in the public repository: OmniBase psql_public_cst(2.1 rc 54,markr)= OmniBase-Tests psql_public_cst(1.3,markr)* Testing under Windows XP, same behavior in both VW 7.4 nov05.2 and VW 7.4.1 mar06.2. I have not tried any other builds or platforms. M |
Hi Mark,
ok, let's start with the easy one... "what, exactly, is the difference between an error and a failure, anyway?"a test fails when one of your assertion expressions return false, i.e., if you have something like this in one of your test methods: self assert: a = b. and a is not equal to b, the test will fail. Errors, on the other hand are... well.... errors! If an error is raised while executing the test method, it will be captured by the SUnit framework and the overall error counted will be incremented. "Once in a while, the tests pass, but usually there are errors. Each time I Do all test fail with the same error?? From what you are saying I would guess your tests are failing during setup and the test methods themselves never even get executed or maybe the setup if fine and the test methods are raising an error on one of their first lines (that would explain why it is so fast when it all goes wrong). You've mentioned your tests have to connect to the database. Maybe this is it... check if you are setting up and tearing down properly. I have no idea as to what would cause different behaviour between TestRunner and the RBSUnitExtensions, as I do not use the later. Maybe someone else has an idea.... Hope it helps, Ricardo On 5/10/06, Mark D. Roberts <[hidden email]> wrote:
Symptom: |
In reply to this post by Mark Roberts
Addendum... Alan Knight suggested that this might be a problem of test
isolation, i.e. one test fouling the others, and after some debugging I discovered that was indeed the case. More significantly, it appears that while RBSUnitExtensions runs tests in a quasi-random order, the TestRunner does not. Instead, TestRunner seems to always run the test methods in a class in alphabetical order (and of course the one test of mine that was broken was the last on the list :D). Something to keep in mind, if you use TestRunner. M |
Free forum by Nabble | Edit this page |