github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/cli/tests/test_genesis.py (about) 1 # Copyright 2017 Intel Corporation 2 # 3 # Licensed under the Apache License, Version 2.0 (the "License"); 4 # you may not use this file except in compliance with the License. 5 # You may obtain a copy of the License at 6 # 7 # http://www.apache.org/licenses/LICENSE-2.0 8 # 9 # Unless required by applicable law or agreed to in writing, software 10 # distributed under the License is distributed on an "AS IS" BASIS, 11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 # See the License for the specific language governing permissions and 13 # limitations under the License. 14 # ------------------------------------------------------------------------------ 15 16 import argparse 17 import os 18 import tempfile 19 import shutil 20 import unittest 21 22 from sawtooth_cli.protobuf.batch_pb2 import BatchHeader 23 from sawtooth_cli.protobuf.batch_pb2 import Batch 24 from sawtooth_cli.protobuf.batch_pb2 import BatchList 25 from sawtooth_cli.protobuf.genesis_pb2 import GenesisData 26 from sawtooth_cli.protobuf.transaction_pb2 import TransactionHeader 27 from sawtooth_cli.protobuf.transaction_pb2 import Transaction 28 29 from sawtooth_cli.admin_command import genesis 30 from sawtooth_cli.exceptions import CliException 31 32 33 class TestGenesisDependencyValidation(unittest.TestCase): 34 def __init__(self, test_name): 35 super().__init__(test_name) 36 self._temp_dir = None 37 self._temp_data_dir = None 38 self._parser = None 39 40 def setUp(self): 41 self._temp_dir = tempfile.mkdtemp() 42 self._temp_data_dir = tempfile.mkdtemp() 43 44 parent_parser = argparse.ArgumentParser(prog='test_genesis', 45 add_help=False) 46 47 self._parser = argparse.ArgumentParser(add_help=False) 48 subparsers = self._parser.add_subparsers(title='subcommands', 49 dest='command') 50 51 genesis.add_genesis_parser(subparsers, parent_parser) 52 53 def tearDown(self): 54 shutil.rmtree(self._temp_dir) 55 shutil.rmtree(self._temp_data_dir) 56 57 def _parse_command(self, batch_filenames, with_default_output=False): 58 cmd_args = ['genesis'] 59 60 if not with_default_output: 61 cmd_args += ['-o', os.path.join(self._temp_dir, 'genesis.batch')] 62 63 cmd_args += batch_filenames 64 65 return self._parser.parse_args(cmd_args) 66 67 def _result_data(self, target_dir=None): 68 target_dir = target_dir if target_dir else self._temp_dir 69 with open(os.path.join(target_dir, "genesis.batch"), "rb") as f: 70 output = GenesisData() 71 output.ParseFromString(f.read()) 72 return output 73 74 def test_validate_with_no_input_batches(self): 75 args = self._parse_command([]) 76 genesis.do_genesis(args, self._temp_data_dir) 77 78 output = self._result_data() 79 self.assertEqual(0, len(output.batches)) 80 81 def test_validate_with_default_output(self): 82 """Tests that the genesis batch is created and placed in the data dir, 83 which is the default location, when no output file is specified in the 84 command args.. 85 """ 86 args = self._parse_command([], with_default_output=True) 87 genesis.do_genesis(args, self._temp_data_dir) 88 89 output = self._result_data(target_dir=self._temp_data_dir) 90 self.assertEqual(0, len(output.batches)) 91 92 def test_validate_with_no_deps(self): 93 batches = [self.make_batch('batch1', 94 transaction('id1', []), 95 transaction('id2', []), 96 transaction('id3', [])), 97 self.make_batch('batch2', 98 transaction('id4', []))] 99 100 args = self._parse_command(batches) 101 genesis.do_genesis(args, self._temp_data_dir) 102 103 output = self._result_data() 104 self.assertEqual(2, len(output.batches)) 105 106 def test_validate_with_deps_in_same_batch(self): 107 batches = [self.make_batch('batch1', 108 transaction('id1', []), 109 transaction('id2', ['id1'])), 110 self.make_batch('batch2', 111 transaction('id3', [])), 112 self.make_batch('batch3', 113 transaction('id4', []))] 114 115 args = self._parse_command(batches) 116 genesis.do_genesis(args, self._temp_data_dir) 117 118 output = self._result_data() 119 self.assertEqual(3, len(output.batches)) 120 121 def test_validate_with_deps_in_across_batches(self): 122 batches = [self.make_batch('batch1', 123 transaction('id1', []), 124 transaction('id2', []), 125 transaction('id3', [])), 126 self.make_batch('batch2', 127 transaction('id4', ['id1', 'id2']))] 128 129 args = self._parse_command(batches) 130 genesis.do_genesis(args, self._temp_data_dir) 131 132 output = self._result_data() 133 self.assertEqual(2, len(output.batches)) 134 135 def test_validation_fails_missing_dep(self): 136 batches = [self.make_batch('batch1', 137 transaction('id1', []), 138 transaction('id2', []), 139 transaction('id3', [])), 140 self.make_batch('batch2', 141 transaction('id4', ['id11']))] 142 143 args = self._parse_command(batches) 144 with self.assertRaises(CliException): 145 genesis.do_genesis(args, self._temp_data_dir) 146 147 def test_validation_fails_self_dep(self): 148 batches = [self.make_batch('batch1', 149 transaction('id1', []), 150 transaction('id2', ['id2']), 151 transaction('id3', [])), 152 self.make_batch('batch2', 153 transaction('id4', ['id1']))] 154 155 args = self._parse_command(batches) 156 with self.assertRaises(CliException): 157 genesis.do_genesis(args, self._temp_data_dir) 158 159 def test_validation_fails_out_of_order(self): 160 batches = [self.make_batch('batch1', 161 transaction('id1', []), 162 transaction('id2', ['id4']), 163 transaction('id3', [])), 164 self.make_batch('batch2', 165 transaction('id4', ['id1']))] 166 167 args = self._parse_command(batches) 168 with self.assertRaises(CliException): 169 genesis.do_genesis(args, self._temp_data_dir) 170 171 def make_batch(self, batch_sig, *txns): 172 txn_ids = [txn.header_signature for txn in txns] 173 batch_header = BatchHeader(signer_public_key='test_public_key', 174 transaction_ids=txn_ids).SerializeToString() 175 176 batch = Batch( 177 header=batch_header, 178 header_signature=batch_sig, 179 transactions=txns 180 ) 181 182 batch_list = BatchList(batches=[batch]) 183 target_path = os.path.join(self._temp_dir, batch_sig + ".batch") 184 with open(target_path, "wb") as f: 185 filename = f.name 186 f.write(batch_list.SerializeToString()) 187 188 return filename 189 190 191 def transaction(txn_sig, dependencies): 192 header = TransactionHeader( 193 signer_public_key='test_public_key', 194 family_name='test_family', 195 family_version='1.0', 196 inputs=[], 197 outputs=[], 198 dependencies=dependencies, 199 payload_sha512='some_sha512', 200 batcher_public_key='test_public_key' 201 ).SerializeToString() 202 203 return Transaction( 204 header=header, 205 header_signature=txn_sig, 206 payload=b'')