blob: db38d4534e8dff303a76cb31baef58a424ba09f3 [file] [log] [blame]
Clint Byrumdc8a0902017-07-20 16:36:27 -07001# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
13import os
14import tempfile
15import time
16
17from tests.base import BaseTestCase
18
19from zuul.executor.server import DiskAccountant
20
21
22class FakeExecutor(object):
23 def __init__(self):
24 self.stopped_jobs = set()
25 self.used = {}
26
27 def stopJobByJobDir(self, jobdir):
28 self.stopped_jobs.add(jobdir)
29
30 def usage(self, dirname, used):
31 self.used[dirname] = used
32
33
34class TestDiskAccountant(BaseTestCase):
35 def test_disk_accountant(self):
Tobias Henkel683f10c2017-07-31 22:13:29 +020036 jobs_dir = tempfile.mkdtemp(
37 dir=os.environ.get("ZUUL_TEST_ROOT", None))
Clint Byrumdc8a0902017-07-20 16:36:27 -070038 cache_dir = tempfile.mkdtemp()
39 executor_server = FakeExecutor()
40 da = DiskAccountant(jobs_dir, 1, executor_server.stopJobByJobDir,
41 cache_dir)
42 da.start()
43
44 jobdir = os.path.join(jobs_dir, '012345')
45 os.mkdir(jobdir)
46 testfile = os.path.join(jobdir, 'tfile')
47 with open(testfile, 'w') as tf:
48 tf.write(2 * 1024 * 1024 * '.')
49
50 # da should catch over-limit dir within 5 seconds
51 for i in range(0, 50):
52 if jobdir in executor_server.stopped_jobs:
53 break
54 time.sleep(0.1)
Tobias Henkel227c5512017-07-31 21:44:40 +020055 try:
56 self.assertEqual(set([jobdir]), executor_server.stopped_jobs)
57 finally:
58 da.stop()
Clint Byrumdc8a0902017-07-20 16:36:27 -070059 self.assertFalse(da.thread.is_alive())
60
61 def test_cache_hard_links(self):
Tobias Henkel683f10c2017-07-31 22:13:29 +020062 root_dir = tempfile.mkdtemp(
63 dir=os.environ.get("ZUUL_TEST_ROOT", None))
Clint Byrumdc8a0902017-07-20 16:36:27 -070064 jobs_dir = os.path.join(root_dir, 'jobs')
65 os.mkdir(jobs_dir)
66 cache_dir = os.path.join(root_dir, 'cache')
67 os.mkdir(cache_dir)
68
69 executor_server = FakeExecutor()
70 da = DiskAccountant(jobs_dir, 1, executor_server.stopJobByJobDir,
71 cache_dir, executor_server.usage)
72 da.start()
73
74 jobdir = os.path.join(jobs_dir, '012345')
75 os.mkdir(jobdir)
76
77 repo_dir = os.path.join(cache_dir, 'a.repo')
78 os.mkdir(repo_dir)
79 source_file = os.path.join(repo_dir, 'big_file')
80 with open(source_file, 'w') as tf:
81 tf.write(2 * 1024 * 1024 * '.')
82 dest_link = os.path.join(jobdir, 'big_file')
83 os.link(source_file, dest_link)
84
85 # da should _not_ count this file. Wait for 5s to get noticed
86 for i in range(0, 50):
87 if jobdir in executor_server.used:
88 break
89 time.sleep(0.1)
Tobias Henkel227c5512017-07-31 21:44:40 +020090 try:
91 self.assertEqual(set(), executor_server.stopped_jobs)
92 self.assertIn(jobdir, executor_server.used)
Tobias Henkel683f10c2017-07-31 22:13:29 +020093 self.assertTrue(executor_server.used[jobdir] <= 1)
Tobias Henkel227c5512017-07-31 21:44:40 +020094 finally:
95 da.stop()