Merge branch '21666-provision-test-improvement'
[arvados.git] / services / fuse / tests / test_command_args.py
index e8488d7ff967179423f3732c8e6e56b05194ed58..a6a387789d65e25f4a4295485af1abd6bcc159ae 100644 (file)
@@ -1,21 +1,29 @@
+# Copyright (C) The Arvados Authors. All rights reserved.
+#
+# SPDX-License-Identifier: AGPL-3.0
+
 import arvados
 import arvados_fuse
 import arvados_fuse.command
 import contextlib
 import functools
+import io
 import json
 import llfuse
 import logging
-import mock
 import os
-import run_test_server
 import sys
 import tempfile
 import unittest
+import resource
+
+from unittest import mock
+
+from . import run_test_server
 
 def noexit(func):
     """If argparse or arvados_fuse tries to exit, fail the test instead"""
-    class SystemExitCaught(StandardError):
+    class SystemExitCaught(Exception):
         pass
     @functools.wraps(func)
     def wrapper(*args, **kwargs):
@@ -27,11 +35,12 @@ def noexit(func):
 
 @contextlib.contextmanager
 def nostderr():
-    orig, sys.stderr = sys.stderr, open(os.devnull, 'w')
-    try:
-        yield
-    finally:
-        sys.stderr = orig
+    with open(os.devnull, 'w') as dn:
+        orig, sys.stderr = sys.stderr, dn
+        try:
+            yield
+        finally:
+            sys.stderr = orig
 
 
 class MountArgsTest(unittest.TestCase):
@@ -48,6 +57,14 @@ class MountArgsTest(unittest.TestCase):
             ent = ent[p]
         return ent
 
+    @contextlib.contextmanager
+    def stderrMatches(self, stderr):
+        orig, sys.stderr = sys.stderr, stderr
+        try:
+            yield
+        finally:
+            sys.stderr = orig
+
     def check_ent_type(self, cls, *path):
         ent = self.lookup(self.mnt, *path)
         self.assertEqual(ent.__class__, cls)
@@ -65,14 +82,14 @@ class MountArgsTest(unittest.TestCase):
         e = self.check_ent_type(arvados_fuse.MagicDirectory, 'by_id')
 
         e = self.check_ent_type(arvados_fuse.StringFile, 'README')
-        readme = e.readfrom(0, -1)
-        self.assertRegexpMatches(readme, r'active-user@arvados\.local')
-        self.assertRegexpMatches(readme, r'\n$')
+        readme = e.readfrom(0, -1).decode()
+        self.assertRegex(readme, r'active-user@arvados\.local')
+        self.assertRegex(readme, r'\n$')
 
         e = self.check_ent_type(arvados_fuse.StringFile, 'by_id', 'README')
-        txt = e.readfrom(0, -1)
-        self.assertRegexpMatches(txt, r'portable data hash')
-        self.assertRegexpMatches(txt, r'\n$')
+        txt = e.readfrom(0, -1).decode()
+        self.assertRegex(txt, r'portable data hash')
+        self.assertRegex(txt, r'\n$')
 
     @noexit
     def test_by_id(self):
@@ -170,6 +187,22 @@ class MountArgsTest(unittest.TestCase):
                          run_test_server.fixture('users')['active']['uuid'])
         self.assertEqual(True, self.mnt.listen_for_events)
 
+    def test_version_argument(self):
+        # The argparse version action prints to stderr in Python 2 and stdout
+        # in Python 3.4 and up. Write both to the same stream so the test can pass
+        # in both cases.
+        origerr = sys.stderr
+        origout = sys.stdout
+        sys.stderr = io.StringIO()
+        sys.stdout = sys.stderr
+
+        with self.assertRaises(SystemExit):
+            args = arvados_fuse.command.ArgumentParser().parse_args(['--version'])
+        self.assertRegex(sys.stdout.getvalue(), "[0-9]+\.[0-9]+\.[0-9]+")
+        sys.stderr.close()
+        sys.stderr = origerr
+        sys.stdout = origout
+
     @noexit
     @mock.patch('arvados.events.subscribe')
     def test_disable_event_listening(self, mock_subscribe):
@@ -228,6 +261,50 @@ class MountArgsTest(unittest.TestCase):
                         '--foreground', self.mntdir])
                     arvados_fuse.command.Mount(args)
 
+    @noexit
+    @mock.patch('resource.setrlimit')
+    @mock.patch('resource.getrlimit')
+    def test_default_file_cache(self, getrlimit, setrlimit):
+        args = arvados_fuse.command.ArgumentParser().parse_args([
+            '--foreground', self.mntdir])
+        self.assertEqual(args.mode, None)
+        getrlimit.return_value = (1024, 1048576)
+        self.mnt = arvados_fuse.command.Mount(args)
+        setrlimit.assert_called_with(resource.RLIMIT_NOFILE, (10240, 1048576))
+
+    @noexit
+    @mock.patch('resource.setrlimit')
+    @mock.patch('resource.getrlimit')
+    def test_small_file_cache(self, getrlimit, setrlimit):
+        args = arvados_fuse.command.ArgumentParser().parse_args([
+            '--foreground', '--file-cache=256000000', self.mntdir])
+        self.assertEqual(args.mode, None)
+        getrlimit.return_value = (1024, 1048576)
+        self.mnt = arvados_fuse.command.Mount(args)
+        setrlimit.assert_not_called()
+
+    @noexit
+    @mock.patch('resource.setrlimit')
+    @mock.patch('resource.getrlimit')
+    def test_large_file_cache(self, getrlimit, setrlimit):
+        args = arvados_fuse.command.ArgumentParser().parse_args([
+            '--foreground', '--file-cache=256000000000', self.mntdir])
+        self.assertEqual(args.mode, None)
+        getrlimit.return_value = (1024, 1048576)
+        self.mnt = arvados_fuse.command.Mount(args)
+        setrlimit.assert_called_with(resource.RLIMIT_NOFILE, (30517, 1048576))
+
+    @noexit
+    @mock.patch('resource.setrlimit')
+    @mock.patch('resource.getrlimit')
+    def test_file_cache_hard_limit(self, getrlimit, setrlimit):
+        args = arvados_fuse.command.ArgumentParser().parse_args([
+            '--foreground', '--file-cache=256000000000', self.mntdir])
+        self.assertEqual(args.mode, None)
+        getrlimit.return_value = (1024, 2048)
+        self.mnt = arvados_fuse.command.Mount(args)
+        setrlimit.assert_called_with(resource.RLIMIT_NOFILE, (2048, 2048))
+
 class MountErrorTest(unittest.TestCase):
     def setUp(self):
         self.mntdir = tempfile.mkdtemp()
@@ -259,7 +336,7 @@ class MountErrorTest(unittest.TestCase):
 
     def test_bogus_host(self):
         arvados.config._settings["ARVADOS_API_HOST"] = "100::"
-        with self.assertRaises(SystemExit) as ex:
+        with self.assertRaises(SystemExit) as ex, mock.patch('time.sleep'):
             args = arvados_fuse.command.ArgumentParser().parse_args([self.mntdir])
             arvados_fuse.command.Mount(args, logger=self.logger).run()
         self.assertEqual(1, ex.exception.code)