Merge branch '21773-keep-service-discovery'
[arvados.git] / sdk / python / tests / test_benchmark_collections.py
1 # Copyright (C) The Arvados Authors. All rights reserved.
2 #
3 # SPDX-License-Identifier: Apache-2.0
4
5 import arvados
6 import sys
7
8 from . import run_test_server
9 from . import arvados_testutil as tutil
10 from . import manifest_examples
11 from .performance.performance_profiler import profiled
12
13 class CollectionBenchmark(run_test_server.TestCaseWithServers,
14                           tutil.ArvadosBaseTestCase,
15                           manifest_examples.ManifestExamples):
16     MAIN_SERVER = {}
17     TEST_BLOCK_SIZE = 0
18
19     @classmethod
20     def list_recursive(cls, coll, parent_name=None):
21         if parent_name is None:
22             current_name = coll.stream_name()
23         else:
24             current_name = '{}/{}'.format(parent_name, coll.name)
25         try:
26             for name in coll:
27                 for item in cls.list_recursive(coll[name], current_name):
28                     yield item
29         except TypeError:
30             yield current_name
31
32     @classmethod
33     def setUpClass(cls):
34         super(CollectionBenchmark, cls).setUpClass()
35         run_test_server.authorize_with('active')
36         cls.api_client = arvados.api('v1')
37         cls.keep_client = arvados.KeepClient(api_client=cls.api_client,
38                                              local_store=cls.local_store)
39
40     @profiled
41     def profile_new_collection_from_manifest(self, manifest_text):
42         return arvados.collection.Collection(manifest_text)
43
44     @profiled
45     def profile_new_collection_from_server(self, uuid):
46         return arvados.collection.Collection(uuid)
47
48     @profiled
49     def profile_new_collection_copying_bytes_from_collection(self, src):
50         dst = arvados.collection.Collection()
51         with tutil.mock_keep_responses('x'*self.TEST_BLOCK_SIZE, 200):
52             for name in self.list_recursive(src):
53                 with src.open(name, 'rb') as srcfile, dst.open(name, 'wb') as dstfile:
54                     dstfile.write(srcfile.read())
55             dst.save_new()
56
57     @profiled
58     def profile_new_collection_copying_files_from_collection(self, src):
59         dst = arvados.collection.Collection()
60         with tutil.mock_keep_responses('x'*self.TEST_BLOCK_SIZE, 200):
61             for name in self.list_recursive(src):
62                 dst.copy(name, name, src)
63             dst.save_new()
64
65     @profiled
66     def profile_collection_list_files(self, coll):
67         return sum(1 for name in self.list_recursive(coll))
68
69     def test_medium_sized_manifest(self):
70         """Exercise manifest-handling code.
71
72         Currently, this test puts undue emphasis on some code paths
73         that don't reflect typical use because the contrived example
74         manifest has some unusual characteristics:
75
76         * Block size is zero.
77
78         * Every block is identical, so block caching patterns are
79           unrealistic.
80
81         * Every file begins and ends at a block boundary.
82         """
83         specs = {
84             'streams': 100,
85             'files_per_stream': 100,
86             'blocks_per_file': 20,
87             'bytes_per_block': self.TEST_BLOCK_SIZE,
88         }
89         my_manifest = self.make_manifest(**specs)
90
91         coll = self.profile_new_collection_from_manifest(my_manifest)
92
93         coll.save_new()
94         self.profile_new_collection_from_server(coll.manifest_locator())
95
96         num_items = self.profile_collection_list_files(coll)
97         self.assertEqual(num_items, specs['streams'] * specs['files_per_stream'])
98
99         self.profile_new_collection_copying_bytes_from_collection(coll)
100
101         self.profile_new_collection_copying_files_from_collection(coll)