Conditions | 17 |
Total Lines | 115 |
Code Lines | 83 |
Lines | 0 |
Ratio | 0 % |
Changes | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like exabgp.configuration.check.check_generation() often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | # encoding: utf-8 |
||
50 | def check_generation(neighbors): |
||
51 | log._option['parser'] = True |
||
52 | |||
53 | for name in neighbors.keys(): |
||
54 | neighbor = copy.deepcopy(neighbors[name]) |
||
55 | neighbor.local_as = neighbor.peer_as |
||
56 | |||
57 | path = {} |
||
58 | for f in NLRI.known_families(): |
||
59 | if neighbor.add_path: |
||
60 | path[f] = neighbor.add_path |
||
61 | |||
62 | capa = Capabilities().new(neighbor, False) |
||
63 | if path: |
||
64 | capa[Capability.CODE.ADD_PATH] = path |
||
65 | capa[Capability.CODE.MULTIPROTOCOL] = neighbor.families() |
||
66 | |||
67 | routerid_1 = str(neighbor.router_id) |
||
68 | routerid_2 = '.'.join(str((int(_) + 1) % 250) for _ in str(neighbor.router_id).split('.', -1)) |
||
69 | |||
70 | o1 = Open(Version(4), ASN(neighbor.local_as), HoldTime(180), RouterID(routerid_1), capa) |
||
71 | o2 = Open(Version(4), ASN(neighbor.peer_as), HoldTime(180), RouterID(routerid_2), capa) |
||
72 | negotiated = Negotiated(neighbor) |
||
73 | negotiated.sent(o1) |
||
74 | negotiated.received(o2) |
||
75 | # grouped = False |
||
76 | |||
77 | for _ in neighbor.rib.outgoing.updates(False): |
||
78 | pass |
||
79 | |||
80 | for change1 in neighbor.rib.outgoing.cached_changes(): |
||
81 | str1 = change1.extensive() |
||
82 | packed = list(Update([change1.nlri], change1.attributes).messages(negotiated)) |
||
83 | pack1 = packed[0] |
||
84 | |||
85 | log.debug('parsed route requires %d updates' % len(packed), 'parser') |
||
86 | log.debug('update size is %d' % len(pack1), 'parser') |
||
87 | |||
88 | log.debug('parsed route %s' % str1, 'parser') |
||
89 | log.debug('parsed hex %s' % od(pack1), 'parser') |
||
90 | |||
91 | # This does not take the BGP header - let's assume we will not break that :) |
||
92 | try: |
||
93 | log.debug('') # new line |
||
94 | |||
95 | pack1s = pack1[19:] if pack1.startswith(b'\xFF' * 16) else pack1 |
||
96 | update = Update.unpack_message(pack1s, negotiated) |
||
97 | |||
98 | change2 = Change(update.nlris[0], update.attributes) |
||
99 | str2 = change2.extensive() |
||
100 | pack2 = list(Update([update.nlris[0]], update.attributes).messages(negotiated))[0] |
||
101 | |||
102 | log.debug('recoded route %s' % str2, 'parser') |
||
103 | log.debug('recoded hex %s' % od(pack2), 'parser') |
||
104 | |||
105 | str1 = str1.replace('attribute [ 0x04 0x80 0x00000064 ]', 'med 100') |
||
106 | str1r = ( |
||
107 | str1.lower().replace(' med 100', '').replace(' local-preference 100', '').replace(' origin igp', '') |
||
108 | ) |
||
109 | str2r = ( |
||
110 | str2.lower().replace(' med 100', '').replace(' local-preference 100', '').replace(' origin igp', '') |
||
111 | ) |
||
112 | str2r = str2r.replace( |
||
113 | 'large-community [ 1:2:3 10:11:12 ]', |
||
114 | 'attribute [ 0x20 0xc0 0x0000000100000002000000030000000a0000000b0000000c ]', |
||
115 | ) |
||
116 | |||
117 | if 'next-hop self' in str1r: |
||
118 | if ':' in str1r: |
||
119 | str1r = str1r.replace('next-hop self', 'next-hop ::1') |
||
120 | else: |
||
121 | str1r = str1r.replace('next-hop self', 'next-hop %s' % neighbor.local_address) |
||
122 | |||
123 | if ' name ' in str1r: |
||
124 | parts = str1r.split(' ') |
||
125 | pos = parts.index('name') |
||
126 | str1r = ' '.join(parts[:pos] + parts[pos + 2 :]) |
||
127 | |||
128 | skip = False |
||
129 | |||
130 | if str1r != str2r: |
||
131 | if 'attribute [' in str1r and ' 0x00 ' in str1r: |
||
132 | # we do not decode non-transitive attributes |
||
133 | log.debug('skipping string check on update with non-transitive attribute(s)', 'parser') |
||
134 | skip = True |
||
135 | else: |
||
136 | log.debug('strings are different:', 'parser') |
||
137 | log.debug('[%s]' % (str1r), 'parser') |
||
138 | log.debug('[%s]' % (str2r), 'parser') |
||
139 | return False |
||
140 | else: |
||
141 | log.debug('strings are fine', 'parser') |
||
142 | |||
143 | if skip: |
||
144 | log.debug('skipping encoding for update with non-transitive attribute(s)', 'parser') |
||
145 | elif pack1 != pack2: |
||
146 | log.debug('encoding are different', 'parser') |
||
147 | log.debug('[%s]' % (od(pack1)), 'parser') |
||
148 | log.debug('[%s]' % (od(pack2)), 'parser') |
||
149 | return False |
||
150 | else: |
||
151 | log.debug('encoding is fine', 'parser') |
||
152 | log.debug('----------------------------------------', 'parser') |
||
153 | |||
154 | log.debug('JSON nlri %s' % change1.nlri.json(), 'parser') |
||
155 | log.debug('JSON attr %s' % change1.attributes.json(), 'parser') |
||
156 | |||
157 | except Notify as exc: |
||
158 | log.debug('----------------------------------------', 'parser') |
||
159 | log.debug(str(exc), 'parser') |
||
160 | log.debug('----------------------------------------', 'parser') |
||
161 | return False |
||
162 | neighbor.rib.clear() |
||
163 | |||
164 | return True |
||
165 | |||
280 |