Closed Bug 980788 Opened 10 years ago Closed 9 years ago

[manifestparser] Add greater-than/less-than (equal) support

Categories

(Testing :: Mozbase, defect)

defect
Not set
normal

Tracking

(firefox42 fixed)

RESOLVED FIXED
mozilla42
Tracking Status
firefox42 --- fixed

People

(Reporter: whimboo, Assigned: parkouss, Mentored)

References

()

Details

Attachments

(1 file, 2 obsolete files)

(In reply to Ted Mielczarek [:ted.mielczarek] from bug 964278 comment 3)
Note that the expression parser we use in manifestparser doesn't currently support greater-than/less-than comparisons:
http://mxr.mozilla.org/mozilla-central/source/testing/mozbase/manifestdestiny/manifestparser/manifestparser.py#36
Blocks: 964278
Hey, i am interested in taking this up. Please assign this to me.
Thanks Luv! I have assigned the bug to you. Andrew, would you mind to mentor this bug? Or is there someone else?
Assignee: nobody → luvagarwal1995su
Mentor: ahalberstadt
Henrick, at mxr i searched for the terms run-if, skip-if, fail-if tags but cannot find any of these tags using queries involving version numbers (as [:ahal] said in bug 964278 comment 4) or something which would require the use of ge, le, gt or lt, operators. can you please provide me with cases where you would use the above operators so that i can add them in re.Scanner (http://mxr.mozilla.org/mozilla-central/source/testing/mozbase/manifestparser/manifestparser/manifestparser.py#202) and write their token functions.
Yes, we don't have those terms yet, because we cannot make use of it. Maybe some cases you can find in our mozmill-tests repository (https://hg.mozilla.org/qa/mozmill-tests), where we workaround this problem by adding skip code inside the test itself. This is something we would like to get rid of.
:wlach recently pointed out to me that there's an undocumented builtin class that can compare version strings. It's distutils.version.StrictVersion, so e.g:

from distutils.version import StrictVersion
print StrictVersion('0.10') > StrictVersion('0.2')

The tricky part is knowing what type we are trying to compare. Manifestparser will either need to guess whether a token is a version string or not, or be explicitly told what constitutes a version string (e.g in the manifests we could say you need to put 'version()' around the version string).

Another question is whether this should be built-in to manifestparser, or whether individual harnesses can "plug in" types at runtime. I think I prefer the latter approach, though it is trickier to implement. For example the harness could do something like this:

class VersionString(object):
    def __init__(self, token):
        token = token[len('version('):-1]
        self.token = StrictVersion(token)

    @staticmethod
    def is_type(token):
        return token.startswith('version')

    def __eq__(self, other):
        return cmp(self.token, other)

    def __lt__(self, other):
        ...
    ...

manifest = TestManifest(..., custom_types=[VersionString])

Then when parsing, manifestparser would first check to see if a token belongs to a custom_type before proceeding as normal.
(In reply to Luv Agarwal(:lagarwal) from comment #3)
> Henrick, at mxr i searched for the terms run-if, skip-if, fail-if tags but
> cannot find any of these tags using queries involving version numbers (as
> [:ahal] said in bug 964278 comment 4) or something which would require the
> use of ge, le, gt or lt, operators. can you please provide me with cases
> where you would use the above operators so that i can add them in re.Scanner
> (http://mxr.mozilla.org/mozilla-central/source/testing/mozbase/
> manifestparser/manifestparser/manifestparser.py#202) and write their token
> functions.

Just to clarify, this bug has nothing to do with version strings (other than it blocks bug 964278). In this bug we need a way to compare "arbitrary things" one of which happens to be version strings.
StrictVersion() will raise ValueError if the argument can't be parsed into a version. FWIW, there's also LooseVersion for all your non-standard X.Y.Z version strings.
(In reply to Andrew Halberstadt [:ahal] from comment #5)
> :wlach recently pointed out to me that there's an undocumented builtin class
> that can compare version strings. It's distutils.version.StrictVersion, 

I discussed something like this in bug 964278. It should be fine to do this, since we can put arbitrary objects into the mozinfo dictionary, so we could do something like:

class MyVersion(StrictVersion):
  def __lt__(self, other):
    if isinstance(other, basestring):
      return self < StrictVersion(other)

mozinfo.info['version'] = MyVersion('1.0')

[test_foo]
skip-if = version < '2.0'
Oh good call, but if we go that route then doing:

[test_foo]
skip-if = '1.0' < version

wouldn't work. Not a huge problem, but we'd probably want to make sure we error out if anyone does write a manifest like that.
FYI, Python is actually pretty cool about this:
===================================
class Foo:
    def __lt__(self, other):
        if isinstance(other, str):
            return 5

    def __gt__(self, other):
        if isinstance(other, str):
            return 6

f = Foo()
print "f < 'a': %s" % (f < 'a')
print "'a' < f: %s" % ('a' < f)
===================================
$ python /tmp/test.py 
f < 'a': 5
'a' < f: 6
It seems that this bug is short of information, so i am not able to proceed.

Andrew, what are the arbitrary things other than version strings that i should take into account.
Flags: needinfo?
It should be possible to compare any classes that define rich comparison methods like __lt__ or __gt__ like in ted's example above (see https://docs.python.org/2/reference/datamodel.html#object.__lt__ for more info).

In practical terms, all that means is don't do any type checking. Just compare two objects with '<' or '>' and let python determine the result.
Flags: needinfo?
resetting the assigned to field as there has been no action on this bug.

Ahal, can you confirm that this is still a useful bug to fix?
Assignee: luvagarwal1995su → nobody
Yes, it is still valid.
Assignee: nobody → j.parkouss
Status: NEW → ASSIGNED
Summary: [manifestdestiny] Add greater-than/less-than (equal) support → [manifestparser] Add greater-than/less-than (equal) support
Attached patch 980788.patch (obsolete) — Splinter Review
Added support for >, <, >=, <= to manifest parser expressions.

Tests run fine locally.

I did'nt asked for review yet, as I can't choose :ahal and I'm not sure who else I can ask for that.
Attachment #8629239 - Flags: review?(ahalberstadt)
Comment on attachment 8629239 [details] [diff] [review]
980788.patch

Review of attachment 8629239 [details] [diff] [review]:
-----------------------------------------------------------------

Thanks, looks great! (get it?)

Just a few naming nits.

::: testing/mozbase/manifestparser/manifestparser/expression.py
@@ +81,5 @@
> +    "<="
> +    def led(self, parser, left):
> +        return left <= parser.expression(self.lbp)
> +
> +class get_op_token(object):

nit: I've never seen 'let' or 'get' before, usually it's 'le' and 'ge'. Please update the class names.

::: testing/mozbase/manifestparser/tests/test_expressionparser.py
@@ +90,5 @@
>          self.assertTrue(parse("true || !true)"))
>          self.assertFalse(parse("!true && true"))
>          self.assertFalse(parse("true && !true"))
>  
> +    def test_lower_than(self):

nit: the 'l' actually stands for 'less' or 'lesser'

@@ +118,5 @@
> +        self.assertTrue(parse("'def' > 'abc'"))
> +        self.assertFalse(parse("1 > 1"))
> +        self.assertFalse(parse("'abc' > 'abc'"))
> +
> +    def test_lower_or_equals_than(self):

ditto.
Attachment #8629239 - Flags: review?(ahalberstadt) → review+
Thanks Andrew!

I fixed the nits, and pushed to try:

https://treeherder.mozilla.org/#/jobs?repo=try&revision=31649211814c
Attached patch 980788_fixed.patch (obsolete) — Splinter Review
Try is green after the fixes, so carrying previsous r+ from :ahal and asking for checkin-needed.
Attachment #8629239 - Attachment is obsolete: true
Attachment #8633951 - Flags: review+
Keywords: checkin-needed
Comment on attachment 8629239 [details] [diff] [review]
980788.patch

Review of attachment 8629239 [details] [diff] [review]:
-----------------------------------------------------------------

::: testing/mozbase/manifestparser/manifestparser/expression.py
@@ +139,1 @@
>                (eq_op_token, neq_op_token),

I think you want these to be equal precedence with the existing eq / neq tokens, otherwise we could get surprising parse results.
Right, thanks Ted. :)
Keywords: checkin-needed
Blocks: 1184067
Fixed with :ted suggestion. I ran the tests locally with success, so I'm confident and another try push should not be needed here.

Carrying r+ from the original review by :ahal.
Attachment #8633951 - Attachment is obsolete: true
Attachment #8634030 - Flags: review+
Keywords: checkin-needed
https://hg.mozilla.org/mozilla-central/rev/9e9dd993c734
Status: ASSIGNED → RESOLVED
Closed: 9 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla42
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: