8123: Aim 5% below GiB memory size boundaries.
[arvados.git] / tools / crunchstat-summary / tests / test_examples.py
1 import arvados
2 import collections
3 import crunchstat_summary.command
4 import crunchstat_summary.summarizer
5 import difflib
6 import glob
7 import gzip
8 import mock
9 import os
10 import unittest
11
12
13 TESTS_DIR = os.path.dirname(os.path.abspath(__file__))
14
15 class ReportDiff(unittest.TestCase):
16     def diff_known_report(self, logfile, summarizer):
17         expectfile = logfile+'.report'
18         expect = open(expectfile).readlines()
19         self.diff_report(summarizer, expect, expectfile=expectfile)
20
21     def diff_report(self, summarizer, expect, expectfile=None):
22         got = [x+"\n" for x in summarizer.report().strip("\n").split("\n")]
23         self.assertEqual(got, expect, "\n"+"".join(difflib.context_diff(
24             expect, got, fromfile=expectfile, tofile="(generated)")))
25
26
27 class SummarizeFile(ReportDiff):
28     def test_example_files(self):
29         for fnm in glob.glob(os.path.join(TESTS_DIR, '*.txt.gz')):
30             logfile = os.path.join(TESTS_DIR, fnm)
31             args = crunchstat_summary.command.ArgumentParser().parse_args(
32                 ['--log-file', logfile])
33             summarizer = crunchstat_summary.command.Command(args).summarizer()
34             summarizer.run()
35             self.diff_known_report(logfile, summarizer)
36
37
38 class SummarizeJob(ReportDiff):
39     fake_job_uuid = 'zzzzz-8i9sb-jjjjjjjjjjjjjjj'
40     fake_log_id = 'fake-log-collection-id'
41     fake_job = {
42         'uuid': fake_job_uuid,
43         'log': fake_log_id,
44     }
45     logfile = os.path.join(TESTS_DIR, 'logfile_20151204190335.txt.gz')
46
47     @mock.patch('arvados.collection.CollectionReader')
48     @mock.patch('arvados.api')
49     def test_job_report(self, mock_api, mock_cr):
50         mock_api().jobs().get().execute.return_value = self.fake_job
51         mock_cr().__iter__.return_value = ['fake-logfile.txt']
52         mock_cr().open.return_value = gzip.open(self.logfile)
53         args = crunchstat_summary.command.ArgumentParser().parse_args(
54             ['--job', self.fake_job_uuid])
55         summarizer = crunchstat_summary.command.Command(args).summarizer()
56         summarizer.run()
57         self.diff_known_report(self.logfile, summarizer)
58         mock_api().jobs().get.assert_called_with(uuid=self.fake_job_uuid)
59         mock_cr.assert_called_with(self.fake_log_id)
60         mock_cr().open.assert_called_with('fake-logfile.txt')
61
62
63 class SummarizePipeline(ReportDiff):
64     fake_instance = {
65         'uuid': 'zzzzz-d1hrv-i3e77t9z5y8j9cc',
66         'owner_uuid': 'zzzzz-tpzed-xurymjxw79nv3jz',
67         'components': collections.OrderedDict([
68             ['foo', {
69                 'job': {
70                     'uuid': 'zzzzz-8i9sb-000000000000000',
71                     'log': 'fake-log-pdh-0',
72                     'runtime_constraints': {
73                         'min_ram_mb_per_node': 900,
74                         'min_cores_per_node': 1,
75                     },
76                 },
77             }],
78             ['bar', {
79                 'job': {
80                     'uuid': 'zzzzz-8i9sb-000000000000001',
81                     'log': 'fake-log-pdh-1',
82                     'runtime_constraints': {
83                         'min_ram_mb_per_node': 900,
84                         'min_cores_per_node': 1,
85                     },
86                 },
87             }],
88             ['no-job-assigned', {}],
89             ['unfinished-job', {
90                 'job': {
91                     'uuid': 'zzzzz-8i9sb-xxxxxxxxxxxxxxx',
92                 },
93             }],
94             ['baz', {
95                 'job': {
96                     'uuid': 'zzzzz-8i9sb-000000000000002',
97                     'log': 'fake-log-pdh-2',
98                     'runtime_constraints': {
99                         'min_ram_mb_per_node': 900,
100                         'min_cores_per_node': 1,
101                     },
102                 },
103             }]]),
104     }
105
106     @mock.patch('arvados.collection.CollectionReader')
107     @mock.patch('arvados.api')
108     def test_pipeline(self, mock_api, mock_cr):
109         logfile = os.path.join(TESTS_DIR, 'logfile_20151204190335.txt.gz')
110         mock_api().pipeline_instances().get().execute. \
111             return_value = self.fake_instance
112         mock_cr().__iter__.return_value = ['fake-logfile.txt']
113         mock_cr().open.side_effect = [gzip.open(logfile) for _ in range(3)]
114         args = crunchstat_summary.command.ArgumentParser().parse_args(
115             ['--pipeline-instance', self.fake_instance['uuid']])
116         summarizer = crunchstat_summary.command.Command(args).summarizer()
117         summarizer.run()
118
119         job_report = [
120             line for line in open(logfile+'.report').readlines()
121             if not line.startswith('#!! ')]
122         expect = (
123             ['### Summary for foo (zzzzz-8i9sb-000000000000000)\n'] +
124             job_report + ['\n'] +
125             ['### Summary for bar (zzzzz-8i9sb-000000000000001)\n'] +
126             job_report + ['\n'] +
127             ['### Summary for baz (zzzzz-8i9sb-000000000000002)\n'] +
128             job_report)
129         self.diff_report(summarizer, expect)
130         mock_cr.assert_has_calls(
131             [
132                 mock.call('fake-log-pdh-0'),
133                 mock.call('fake-log-pdh-1'),
134                 mock.call('fake-log-pdh-2'),
135             ], any_order=True)
136         mock_cr().open.assert_called_with('fake-logfile.txt')