Quantcast

[PATCH 1 of 4] runtests: add a function to test if IPv6 is available

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 1 of 4] runtests: add a function to test if IPv6 is available

Jun Wu
# HG changeset patch
# User Jun Wu <[hidden email]>
# Date 1487204311 28800
#      Wed Feb 15 16:18:31 2017 -0800
# Node ID a70fa1e0fcdb11980338d72dde33dfe047bda7c2
# Parent  e5363cb96233861fc99f7e9b85d7884d3121558c
# Available At https://bitbucket.org/quark-zju/hg-draft
#              hg pull https://bitbucket.org/quark-zju/hg-draft -r a70fa1e0fcdb
runtests: add a function to test if IPv6 is available

Previously, checkportisavailable returns True if the port is free either on
IPv4 or IPv6, but the hg server only uses IPv4 by default. That leads to
issues when IPv4 port is not free but the IPv6 one is.

To address that, run-tests should stick with either IPv4 or IPv6. This patch
adds a function similar to checkportisavailable to test if IPv6 is
available, and assigns the result to a variable.

The new function was tested in a Linux system script with the following
steps:

  1. Run "ip addr del ::1/128 dev lo" to delete lo's IPv6 address,
     Confirm checkipv6available() returns False.
  2. Run "ip addr add ::1/128 dev lo" to add back lo's IPv6 address.
     Confirm checkipv6available() returns True.
  3. Start a web server taking the 8000 port.
     Confirm checkipv6available(8000) is still True.

diff --git a/tests/run-tests.py b/tests/run-tests.py
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -113,4 +113,27 @@ else:
 wifexited = getattr(os, "WIFEXITED", lambda x: False)
 
+# Whether to use IPv6
+def checkipv6available(port=20058):
+    """return true if we can listen on localhost's IPv6 ports"""
+    family = getattr(socket, 'AF_INET6', None)
+    if family is None:
+        return False
+    try:
+        s = socket.socket(family, socket.SOCK_STREAM)
+        s.bind(('localhost', port))
+        s.close()
+        return True
+    except socket.error as exc:
+        if exc.errno == errno.EADDRINUSE:
+            return True
+        elif exc.errno in (errno.EADDRNOTAVAIL, errno.EPROTONOSUPPORT):
+            return False
+        else:
+            raise
+    else:
+        return False
+
+useipv6 = checkipv6available()
+
 def checkportisavailable(port):
     """return true if a port seems free to bind on localhost"""
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 2 of 4] runtests: checkportisavailable should only check one family

Jun Wu
# HG changeset patch
# User Jun Wu <[hidden email]>
# Date 1487204542 28800
#      Wed Feb 15 16:22:22 2017 -0800
# Node ID d223c3d57e14f22c18030166b83e2da9143fdf67
# Parent  a70fa1e0fcdb11980338d72dde33dfe047bda7c2
# Available At https://bitbucket.org/quark-zju/hg-draft
#              hg pull https://bitbucket.org/quark-zju/hg-draft -r d223c3d57e14
runtests: checkportisavailable should only check one family

As explained by the previous patch, checkportisavailable() should only check
the preferred family - either IPv4 or IPv6, not both.

This patch makes it so.

diff --git a/tests/run-tests.py b/tests/run-tests.py
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -138,8 +138,9 @@ useipv6 = checkipv6available()
 def checkportisavailable(port):
     """return true if a port seems free to bind on localhost"""
-    families = [getattr(socket, i, None)
-                for i in ('AF_INET', 'AF_INET6')
-                if getattr(socket, i, None) is not None]
-    for family in families:
+    if useipv6:
+        family = socket.AF_INET6
+    else:
+        family = socket.AF_INET
+    if True:
         try:
             s = socket.socket(family, socket.SOCK_STREAM)
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 3 of 4] runtests: set web.ipv6 if we use IPv6

Jun Wu
In reply to this post by Jun Wu
# HG changeset patch
# User Jun Wu <[hidden email]>
# Date 1487205807 28800
#      Wed Feb 15 16:43:27 2017 -0800
# Node ID bacc5256a49b34d07616c1e60e119a74ac721b7a
# Parent  d223c3d57e14f22c18030166b83e2da9143fdf67
# Available At https://bitbucket.org/quark-zju/hg-draft
#              hg pull https://bitbucket.org/quark-zju/hg-draft -r bacc5256a49b
runtests: set web.ipv6 if we use IPv6

As explained by the previous patch, we need to set "web.ipv6=True" if we
decide to use IPv6. Otherwise "hg serve" will still try to listen on IPv4.

This patch makes it so by appending web.ipv6 to "extra configs".

This patch was tested in a Linux system with IPv6, by the following steps:

  1. Change hgweb/server.py temporarily to write a file if
     IPv6HTTPServer.__init__ is called.
  2. run-tests.py -l --keep-tmpdir test-serve.t
  3. Check the generated .hgrc, make sure it sets web.ipv6=1.
  4. Check the log file to make sure IPv6HTTPServer.__init__ is called.

diff --git a/tests/run-tests.py b/tests/run-tests.py
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -536,5 +536,6 @@ class Test(unittest.TestCase):
                  startport=defaults['port'], extraconfigopts=None,
                  py3kwarnings=False, shell=None, hgcommand=None,
-                 slowtimeout=defaults['slowtimeout'], usechg=False):
+                 slowtimeout=defaults['slowtimeout'], usechg=False,
+                 useipv6=False):
         """Create a test from parameters.
 
@@ -594,4 +595,9 @@ class Test(unittest.TestCase):
         self._chgsockdir = None
 
+        # If IPv6 is used, set web.ipv6=1 in hgrc so servers will use IPv6
+        if useipv6:
+            self._extraconfigopts = list(self._extraconfigopts)
+            self._extraconfigopts.append('web.ipv6 = True')
+
         # If we're not in --debug mode and reference output file exists,
         # check test output against it.
@@ -2318,5 +2324,6 @@ class TestRunner(object):
                     shell=self.options.shell,
                     hgcommand=self._hgcommand,
-                    usechg=bool(self.options.with_chg or self.options.chg))
+                    usechg=bool(self.options.with_chg or self.options.chg),
+                    useipv6=useipv6)
         t.should_reload = True
         return t
diff --git a/tests/test-basic.t b/tests/test-basic.t
--- a/tests/test-basic.t
+++ b/tests/test-basic.t
@@ -12,4 +12,5 @@ Create a repository:
   ui.mergemarkers=detailed
   ui.promptecho=True
+  web.ipv6=True (?)
   $ hg init t
   $ cd t
diff --git a/tests/test-commandserver.t b/tests/test-commandserver.t
--- a/tests/test-commandserver.t
+++ b/tests/test-commandserver.t
@@ -200,4 +200,5 @@ check that local configs for the cached
   ui.foo=bar
   ui.nontty=true
+  web.ipv6=True (?)
   *** runcommand init foo
   *** runcommand -R foo showconfig ui defaults
diff --git a/tests/test-config.t b/tests/test-config.t
--- a/tests/test-config.t
+++ b/tests/test-config.t
@@ -59,10 +59,10 @@ Test case sensitive configuration
    {
     "name": "Section.KeY",
-    "source": "*.hgrc:16", (glob)
+    "source": "*.hgrc:*", (glob)
     "value": "Case Sensitive"
    },
    {
     "name": "Section.key",
-    "source": "*.hgrc:17", (glob)
+    "source": "*.hgrc:*", (glob)
     "value": "lower case"
    }
@@ -72,5 +72,5 @@ Test case sensitive configuration
    {
     "name": "Section.KeY",
-    "source": "*.hgrc:16", (glob)
+    "source": "*.hgrc:*", (glob)
     "value": "Case Sensitive"
    }
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[PATCH 4 of 4] runtests: unindent an "if True" block

Jun Wu
In reply to this post by Jun Wu
# HG changeset patch
# User Jun Wu <[hidden email]>
# Date 1487204998 28800
#      Wed Feb 15 16:29:58 2017 -0800
# Node ID c5bdb942d324dcd732d277457d11eff7dc6aacc3
# Parent  bacc5256a49b34d07616c1e60e119a74ac721b7a
# Available At https://bitbucket.org/quark-zju/hg-draft
#              hg pull https://bitbucket.org/quark-zju/hg-draft -r c5bdb942d324
runtests: unindent an "if True" block

The block was left to make review easier. This patch unindents it.

diff --git a/tests/run-tests.py b/tests/run-tests.py
--- a/tests/run-tests.py
+++ b/tests/run-tests.py
@@ -142,14 +142,13 @@ def checkportisavailable(port):
     else:
         family = socket.AF_INET
-    if True:
-        try:
-            s = socket.socket(family, socket.SOCK_STREAM)
-            s.bind(('localhost', port))
-            s.close()
-            return True
-        except socket.error as exc:
-            if exc.errno not in (errno.EADDRINUSE, errno.EADDRNOTAVAIL,
-                                 errno.EPROTONOSUPPORT):
-                raise
+    try:
+        s = socket.socket(family, socket.SOCK_STREAM)
+        s.bind(('localhost', port))
+        s.close()
+        return True
+    except socket.error as exc:
+        if exc.errno not in (errno.EADDRINUSE, errno.EADDRNOTAVAIL,
+                             errno.EPROTONOSUPPORT):
+            raise
     return False
 
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH 1 of 4] runtests: add a function to test if IPv6 is available

Augie Fackler-2
In reply to this post by Jun Wu
On Wed, Feb 15, 2017 at 04:50:14PM -0800, Jun Wu wrote:

> # HG changeset patch
> # User Jun Wu <[hidden email]>
> # Date 1487204311 28800
> #      Wed Feb 15 16:18:31 2017 -0800
> # Node ID a70fa1e0fcdb11980338d72dde33dfe047bda7c2
> # Parent  e5363cb96233861fc99f7e9b85d7884d3121558c
> # Available At https://bitbucket.org/quark-zju/hg-draft
> #              hg pull https://bitbucket.org/quark-zju/hg-draft -r a70fa1e0fcdb
> runtests: add a function to test if IPv6 is available
>
> Previously, checkportisavailable returns True if the port is free either on
> IPv4 or IPv6, but the hg server only uses IPv4 by default. That leads to
> issues when IPv4 port is not free but the IPv6 one is.
>
> To address that, run-tests should stick with either IPv4 or IPv6. This patch
> adds a function similar to checkportisavailable to test if IPv6 is
> available, and assigns the result to a variable.
>
> The new function was tested in a Linux system script with the following
> steps:
>
>   1. Run "ip addr del ::1/128 dev lo" to delete lo's IPv6 address,
>      Confirm checkipv6available() returns False.
>   2. Run "ip addr add ::1/128 dev lo" to add back lo's IPv6 address.
>      Confirm checkipv6available() returns True.
>   3. Start a web server taking the 8000 port.
>      Confirm checkipv6available(8000) is still True.
>
> diff --git a/tests/run-tests.py b/tests/run-tests.py
> --- a/tests/run-tests.py
> +++ b/tests/run-tests.py
> @@ -113,4 +113,27 @@ else:
>  wifexited = getattr(os, "WIFEXITED", lambda x: False)
>
> +# Whether to use IPv6
> +def checkipv6available(port=20058):
> +    """return true if we can listen on localhost's IPv6 ports"""
> +    family = getattr(socket, 'AF_INET6', None)
> +    if family is None:
> +        return False
> +    try:
> +        s = socket.socket(family, socket.SOCK_STREAM)
> +        s.bind(('localhost', port))
> +        s.close()
> +        return True
> +    except socket.error as exc:
> +        if exc.errno == errno.EADDRINUSE:
> +            return True
> +        elif exc.errno in (errno.EADDRNOTAVAIL, errno.EPROTONOSUPPORT):
> +            return False
> +        else:
> +            raise
> +    else:
> +        return False
> +
> +useipv6 = checkipv6available()

I'm not overjoyed at the static default. Is there a reason to use the
static default instead of checking HGPORT, so that multiple users on a
single box (such as the big compile farm machine several of us favor)
can run the tests without risk of stomping each other?

> +
>  def checkportisavailable(port):
>      """return true if a port seems free to bind on localhost"""
> _______________________________________________
> Mercurial-devel mailing list
> [hidden email]
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH 4 of 4] runtests: unindent an "if True" block

Augie Fackler-2
In reply to this post by Jun Wu
On Wed, Feb 15, 2017 at 04:50:17PM -0800, Jun Wu wrote:
> # HG changeset patch
> # User Jun Wu <[hidden email]>
> # Date 1487204998 28800
> #      Wed Feb 15 16:29:58 2017 -0800
> # Node ID c5bdb942d324dcd732d277457d11eff7dc6aacc3
> # Parent  bacc5256a49b34d07616c1e60e119a74ac721b7a
> # Available At https://bitbucket.org/quark-zju/hg-draft
> #              hg pull https://bitbucket.org/quark-zju/hg-draft -r c5bdb942d324
> runtests: unindent an "if True" block

Series looks fine, other than patch 1.

>
> The block was left to make review easier. This patch unindents it.
>
> diff --git a/tests/run-tests.py b/tests/run-tests.py
> --- a/tests/run-tests.py
> +++ b/tests/run-tests.py
> @@ -142,14 +142,13 @@ def checkportisavailable(port):
>      else:
>          family = socket.AF_INET
> -    if True:
> -        try:
> -            s = socket.socket(family, socket.SOCK_STREAM)
> -            s.bind(('localhost', port))
> -            s.close()
> -            return True
> -        except socket.error as exc:
> -            if exc.errno not in (errno.EADDRINUSE, errno.EADDRNOTAVAIL,
> -                                 errno.EPROTONOSUPPORT):
> -                raise
> +    try:
> +        s = socket.socket(family, socket.SOCK_STREAM)
> +        s.bind(('localhost', port))
> +        s.close()
> +        return True
> +    except socket.error as exc:
> +        if exc.errno not in (errno.EADDRINUSE, errno.EADDRNOTAVAIL,
> +                             errno.EPROTONOSUPPORT):
> +            raise
>      return False
>
> _______________________________________________
> Mercurial-devel mailing list
> [hidden email]
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH 1 of 4] runtests: add a function to test if IPv6 is available

Jun Wu
In reply to this post by Augie Fackler-2
Excerpts from Augie Fackler's message of 2017-02-15 21:23:37 -0500:
> I'm not overjoyed at the static default. Is there a reason to use the
> static default instead of checking HGPORT, so that multiple users on a
> single box (such as the big compile farm machine several of us favor)
> can run the tests without risk of stomping each other?

That's just a random default which must > 1024. If multiple users run this
in parallel - it'd be fine - one of them will get the error EADDRINUSE, and
that's considered "IPv6 is available".

_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH 1 of 4] runtests: add a function to test if IPv6 is available

Augie Fackler-2
On Wed, Feb 15, 2017 at 06:26:11PM -0800, Jun Wu wrote:
> Excerpts from Augie Fackler's message of 2017-02-15 21:23:37 -0500:
> > I'm not overjoyed at the static default. Is there a reason to use the
> > static default instead of checking HGPORT, so that multiple users on a
> > single box (such as the big compile farm machine several of us favor)
> > can run the tests without risk of stomping each other?
>
> That's just a random default which must > 1024. If multiple users run this
> in parallel - it'd be fine - one of them will get the error EADDRINUSE, and
> that's considered "IPv6 is available".

Oh, I misunderstood. This function is *only* for checking that IPv6 is
available, not also for checking if a specific port is available with
IPv6. Is that (revised) understanding correct on my part?
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH 1 of 4] runtests: add a function to test if IPv6 is available

Jun Wu
Excerpts from Augie Fackler's message of 2017-02-15 21:32:38 -0500:

> On Wed, Feb 15, 2017 at 06:26:11PM -0800, Jun Wu wrote:
> > Excerpts from Augie Fackler's message of 2017-02-15 21:23:37 -0500:
> > > I'm not overjoyed at the static default. Is there a reason to use the
> > > static default instead of checking HGPORT, so that multiple users on a
> > > single box (such as the big compile farm machine several of us favor)
> > > can run the tests without risk of stomping each other?
> >
> > That's just a random default which must > 1024. If multiple users run this
> > in parallel - it'd be fine - one of them will get the error EADDRINUSE, and
> > that's considered "IPv6 is available".
>
> Oh, I misunderstood. This function is *only* for checking that IPv6 is
> available, not also for checking if a specific port is available with
> IPv6. Is that (revised) understanding correct on my part?

Correct. run-tests.py will first decide whether to use IPv6 or not globally
by calling this function. If IPv6 is available, then all port checks will
be IPv6-only. Otherwise, they will be IPv4-only.
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [PATCH 1 of 4] runtests: add a function to test if IPv6 is available

Augie Fackler-2
On Wed, Feb 15, 2017 at 06:57:37PM -0800, Jun Wu wrote:

> Excerpts from Augie Fackler's message of 2017-02-15 21:32:38 -0500:
> > On Wed, Feb 15, 2017 at 06:26:11PM -0800, Jun Wu wrote:
> > > Excerpts from Augie Fackler's message of 2017-02-15 21:23:37 -0500:
> > > > I'm not overjoyed at the static default. Is there a reason to use the
> > > > static default instead of checking HGPORT, so that multiple users on a
> > > > single box (such as the big compile farm machine several of us favor)
> > > > can run the tests without risk of stomping each other?
> > >
> > > That's just a random default which must > 1024. If multiple users run this
> > > in parallel - it'd be fine - one of them will get the error EADDRINUSE, and
> > > that's considered "IPv6 is available".
> >
> > Oh, I misunderstood. This function is *only* for checking that IPv6 is
> > available, not also for checking if a specific port is available with
> > IPv6. Is that (revised) understanding correct on my part?
>
> Correct. run-tests.py will first decide whether to use IPv6 or not globally
> by calling this function. If IPv6 is available, then all port checks will
> be IPv6-only. Otherwise, they will be IPv4-only.

Okay, sure. Queued.
_______________________________________________
Mercurial-devel mailing list
[hidden email]
https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Loading...