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