This is an automated email from the ASF dual-hosted git repository.

janhoy pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr.git


The following commit(s) were added to refs/heads/main by this push:
     new 56d2ef6669b Smoketester now randomizes port used for tests (#4055)
56d2ef6669b is described below

commit 56d2ef6669b5d106b5c56fe349fe87ed3425849e
Author: Jan Høydahl <[email protected]>
AuthorDate: Wed Feb 4 19:21:47 2026 +0100

    Smoketester now randomizes port used for tests (#4055)
---
 dev-tools/scripts/smokeTestRelease.py | 89 ++++++++++++-----------------------
 1 file changed, 31 insertions(+), 58 deletions(-)

diff --git a/dev-tools/scripts/smokeTestRelease.py 
b/dev-tools/scripts/smokeTestRelease.py
index 7fbf3c3e47b..93c66d740a0 100755
--- a/dev-tools/scripts/smokeTestRelease.py
+++ b/dev-tools/scripts/smokeTestRelease.py
@@ -23,8 +23,10 @@ import hashlib
 import http.client
 import os
 import platform
+import random
 import re
 import shutil
+import socket
 import subprocess
 import sys
 import textwrap
@@ -716,48 +718,34 @@ def verifyUnpacked(java, artifact, unpackPath, 
gitRevision, version, testArgs):
   testChangelogMd('.', version)
 
 
-def readSolrOutput(p, startupEvent, failureEvent, logFile):
-  f = open(logFile, 'wb')
-  try:
-    while True:
-      line = p.stdout.readline()
-      if len(line) == 0:
-        p.poll()
-        if not startupEvent.isSet():
-          failureEvent.set()
-          startupEvent.set()
-        break
-      f.write(line)
-      f.flush()
-      #print('SOLR: %s' % line.strip())
-      if not startupEvent.isSet():
-        if line.find(b'Started ServerConnector@') != -1 and 
line.find(b'{HTTP/1.1}{0.0.0.0:8983}') != -1:
-          startupEvent.set()
-        elif p.poll() is not None:
-          failureEvent.set()
-          startupEvent.set()
-          break
-  except:
-    print()
-    print('Exception reading Solr output:')
-    traceback.print_exc()
-    failureEvent.set()
-    startupEvent.set()
-  finally:
-    f.close()
-
-def is_port_in_use(port):
-    import socket
+def find_available_port(max_attempts=100):
+  """Find an available port by randomly selecting from range 8901-8999.
+  Ensures both the port and port+1000 are available."""
+  for _ in range(max_attempts):
+    port = random.randint(8901, 8999)
     with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
-        return s.connect_ex(('localhost', port)) == 0
+      try:
+        s.bind(('localhost', port))
+        # Check if port+1000 is also available
+        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s2:
+          try:
+            s2.bind(('localhost', port + 1000))
+            return port
+          except OSError:
+            continue
+      except OSError:
+        continue
+  raise RuntimeError('Could not find an available port after %d attempts in 
range 8901-8999' % max_attempts)
+
 
 def testSolrExample(binaryDistPath, javaPath, isSlim):
   # test solr using some examples it comes with
+  port = find_available_port()
   logFile = '%s/solr-example.log' % binaryDistPath
   old_cwd = os.getcwd() # So we can back-track
   os.chdir(binaryDistPath)
 
-  print('      start Solr instance (log=%s)...' % logFile)
+  print('      start Solr instance on port %d (log=%s)...' % (port, logFile))
   env = {}
   env.update(os.environ)
   env['JAVA_HOME'] = javaPath
@@ -767,52 +755,39 @@ def testSolrExample(binaryDistPath, javaPath, isSlim):
   if isSlim:
     example = "films"
 
-  # Stop Solr running on port 8983 (in case a previous run didn't shutdown 
cleanly)
-  try:
-      if not cygwin:
-        subprocess.call(['bin/solr','stop','-p','8983'])
-      else:
-        subprocess.call('env "PATH=`cygpath -S -w`:$PATH" bin/solr.cmd stop -p 
8983', shell=True)
-  except:
-     print('      Stop failed due to: '+sys.exc_info()[0])
-
-  print('      Running %s example on port 8983 from %s' % (example, 
binaryDistPath))
+  print('      Running %s example on port %d from %s' % (example, port, 
binaryDistPath))
   try:
     if not cygwin:
-      runExampleStatus = subprocess.call(['bin/solr','start','-e',example])
+      runExampleStatus = 
subprocess.call(['bin/solr','start','-e',example,'-p',str(port)])
     else:
-      runExampleStatus = subprocess.call('env "PATH=`cygpath -S -w`:$PATH" 
bin/solr.cmd -e ' + example, shell=True)
+      runExampleStatus = subprocess.call('env "PATH=`cygpath -S -w`:$PATH" 
bin/solr.cmd start -e %s -p %d' % (example, port), shell=True)
 
     if runExampleStatus != 0:
       raise RuntimeError('Failed to run the %s example, check log for previous 
errors.' % example)
 
     os.chdir('example')
     print('      run query...')
-    s = load('http://localhost:8983/solr/%s/select/?q=video' % example)
+    s = load('http://localhost:%d/solr/%s/select/?q=video' % (port, example))
     if s.find('"numFound":%d,' % (8 if isSlim else 3)) == -1:
       print('FAILED: response is:\n%s' % s)
       raise RuntimeError('query on solr example instance failed')
-    s = load('http://localhost:8983/api/cores')
+    s = load('http://localhost:%d/api/cores' % port)
     if s.find('"status":0,') == -1:
       print('FAILED: response is:\n%s' % s)
       raise RuntimeError('query api v2 on solr example instance failed')
   finally:
     # Stop server:
-    print('      stop server using: bin/solr stop -p 8983')
+    print('      stop server using: bin/solr stop -p %d' % port)
     os.chdir(binaryDistPath)
 
     if not cygwin:
-      subprocess.call(['bin/solr','stop','-p','8983'])
+      subprocess.call(['bin/solr','stop','-p',str(port)])
     else:
-      subprocess.call('env "PATH=`cygpath -S -w`:$PATH" bin/solr.cmd stop -p 
8983', shell=True)
+      subprocess.call('env "PATH=`cygpath -S -w`:$PATH" bin/solr.cmd stop -p 
%d' % port, shell=True)
 
   os.chdir(old_cwd)
 
 
-def removeTrailingZeros(version):
-  return re.sub(r'(\.0)*$', '', version)
-
-
 def checkMaven(baseURL, tmpDir, gitRevision, version, isSigned, keysFile):
   print('    download artifacts')
   artifacts = []
@@ -1065,6 +1040,7 @@ def make_java_config(parser, alt_java_homes):
   jc = namedtuple('JavaConfig', 'run_java java_home run_alt_javas 
alt_java_homes alt_java_versions')
   return jc(run_java, java_home, run_alt_javas, alt_java_homes, 
alt_java_versions)
 
+
 version_re = re.compile(r'(\d+\.\d+\.\d+(-ALPHA|-BETA)?)')
 revision_re = re.compile(r'rev-([a-f\d]+)')
 def parse_config():
@@ -1195,9 +1171,6 @@ def smokeTest(java, baseURL, gitRevision, version, 
tmpDir, isSigned, local_keys,
     scriptutil.download('KEYS', keysFileURL, tmpDir, force_clean=FORCE_CLEAN)
     keysFile = '%s/KEYS' % (tmpDir)
 
-  if is_port_in_use(8983):
-    raise RuntimeError('Port 8983 is already in use. The smoketester needs it 
to test Solr')
-
   print()
   print('Test Solr...')
   checkSigs(solrPath, version, tmpDir, isSigned, keysFile)

Reply via email to