synapse 2.175.0__py311-none-any.whl → 2.177.0__py311-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of synapse might be problematic. Click here for more details.

Files changed (73) hide show
  1. synapse/axon.py +24 -9
  2. synapse/cortex.py +330 -168
  3. synapse/cryotank.py +46 -37
  4. synapse/datamodel.py +17 -4
  5. synapse/exc.py +19 -0
  6. synapse/lib/agenda.py +7 -13
  7. synapse/lib/ast.py +6 -5
  8. synapse/lib/auth.py +1520 -0
  9. synapse/lib/cell.py +255 -53
  10. synapse/lib/grammar.py +5 -0
  11. synapse/lib/hive.py +24 -3
  12. synapse/lib/hiveauth.py +6 -32
  13. synapse/lib/layer.py +7 -4
  14. synapse/lib/link.py +21 -17
  15. synapse/lib/lmdbslab.py +149 -0
  16. synapse/lib/modelrev.py +1 -1
  17. synapse/lib/schemas.py +136 -0
  18. synapse/lib/storm.py +70 -33
  19. synapse/lib/stormlib/aha.py +1 -1
  20. synapse/lib/stormlib/auth.py +185 -10
  21. synapse/lib/stormlib/cortex.py +16 -5
  22. synapse/lib/stormlib/gen.py +80 -0
  23. synapse/lib/stormlib/model.py +55 -0
  24. synapse/lib/stormlib/modelext.py +60 -0
  25. synapse/lib/stormlib/storm.py +117 -5
  26. synapse/lib/stormlib/tabular.py +212 -0
  27. synapse/lib/stormtypes.py +14 -1
  28. synapse/lib/trigger.py +1 -1
  29. synapse/lib/version.py +2 -2
  30. synapse/lib/view.py +55 -28
  31. synapse/models/base.py +7 -0
  32. synapse/models/biz.py +4 -0
  33. synapse/models/files.py +8 -1
  34. synapse/models/inet.py +31 -0
  35. synapse/tests/files/changelog/model_2.176.0_16ee721a6b7221344eaf946c3ab4602dda546b1a.yaml.gz +0 -0
  36. synapse/tests/files/changelog/model_2.176.0_2a25c58bbd344716cd7cbc3f4304d8925b0f4ef2.yaml.gz +0 -0
  37. synapse/tests/test_axon.py +7 -4
  38. synapse/tests/test_cortex.py +127 -82
  39. synapse/tests/test_cryotank.py +4 -4
  40. synapse/tests/test_datamodel.py +7 -0
  41. synapse/tests/test_lib_agenda.py +7 -0
  42. synapse/tests/{test_lib_hiveauth.py → test_lib_auth.py} +314 -11
  43. synapse/tests/test_lib_cell.py +161 -8
  44. synapse/tests/test_lib_httpapi.py +18 -14
  45. synapse/tests/test_lib_layer.py +33 -33
  46. synapse/tests/test_lib_link.py +42 -1
  47. synapse/tests/test_lib_lmdbslab.py +68 -0
  48. synapse/tests/test_lib_nexus.py +4 -4
  49. synapse/tests/test_lib_node.py +0 -7
  50. synapse/tests/test_lib_storm.py +45 -0
  51. synapse/tests/test_lib_stormlib_aha.py +1 -2
  52. synapse/tests/test_lib_stormlib_auth.py +21 -0
  53. synapse/tests/test_lib_stormlib_cortex.py +12 -12
  54. synapse/tests/test_lib_stormlib_gen.py +99 -0
  55. synapse/tests/test_lib_stormlib_model.py +108 -0
  56. synapse/tests/test_lib_stormlib_modelext.py +64 -0
  57. synapse/tests/test_lib_stormlib_storm.py +82 -1
  58. synapse/tests/test_lib_stormlib_tabular.py +226 -0
  59. synapse/tests/test_lib_stormsvc.py +4 -1
  60. synapse/tests/test_lib_stormtypes.py +10 -0
  61. synapse/tests/test_model_base.py +3 -0
  62. synapse/tests/test_model_biz.py +3 -0
  63. synapse/tests/test_model_files.py +12 -2
  64. synapse/tests/test_model_inet.py +55 -0
  65. synapse/tests/test_tools_changelog.py +196 -0
  66. synapse/tests/test_tools_healthcheck.py +4 -3
  67. synapse/tests/utils.py +1 -1
  68. synapse/tools/changelog.py +774 -15
  69. {synapse-2.175.0.dist-info → synapse-2.177.0.dist-info}/METADATA +3 -3
  70. {synapse-2.175.0.dist-info → synapse-2.177.0.dist-info}/RECORD +73 -67
  71. {synapse-2.175.0.dist-info → synapse-2.177.0.dist-info}/WHEEL +1 -1
  72. {synapse-2.175.0.dist-info → synapse-2.177.0.dist-info}/LICENSE +0 -0
  73. {synapse-2.175.0.dist-info → synapse-2.177.0.dist-info}/top_level.txt +0 -0
synapse/lib/view.py CHANGED
@@ -79,18 +79,17 @@ class View(s_nexus.Pusher): # type: ignore
79
79
  '''
80
80
  snapctor = s_snap.Snap.anit
81
81
 
82
- async def __anit__(self, core, node):
82
+ async def __anit__(self, core, vdef):
83
83
  '''
84
84
  Async init the view.
85
85
 
86
86
  Args:
87
87
  core (Cortex): The cortex that owns the view.
88
- node (HiveNode): The hive node containing the view info.
88
+ vdef (dict): The dictionary containing the view definition.
89
89
  '''
90
- self.node = node
91
- self.iden = node.name()
90
+ self.iden = vdef.get('iden')
92
91
  self.bidn = s_common.uhex(self.iden)
93
- self.info = await node.dict()
92
+ self.info = vdef
94
93
 
95
94
  self.core = core
96
95
  self.dirn = s_common.gendir(core.dirn, 'views', self.iden)
@@ -101,11 +100,10 @@ class View(s_nexus.Pusher): # type: ignore
101
100
 
102
101
  self.trigqueue = self.viewslab.getSeqn('trigqueue')
103
102
 
104
- trignode = await node.open(('triggers',))
105
- self.trigdict = await trignode.dict()
103
+ self.trigdict = self.core.cortexdata.getSubKeyVal(f'view:{self.iden}:trigger:')
106
104
 
107
105
  self.triggers = s_trigger.Triggers(self)
108
- for _, tdef in self.trigdict.items():
106
+ for tdef in self.trigdict.values():
109
107
  try:
110
108
  await self.triggers.load(tdef)
111
109
 
@@ -268,12 +266,14 @@ class View(s_nexus.Pusher): # type: ignore
268
266
  return
269
267
 
270
268
  self.merging = True
271
- await self.info.set('merging', True)
269
+ self.info['merging'] = True
270
+ self.core.viewdefs.set(self.iden, self.info)
272
271
 
273
272
  layr = self.layers[0]
274
273
 
275
274
  layr.readonly = True
276
- await layr.layrinfo.set('readonly', True)
275
+ layr.layrinfo['readonly'] = True
276
+ self.core.layerdefs.set(layr.iden, layr.layrinfo)
277
277
 
278
278
  merge = self.getMergeRequest()
279
279
  votes = [vote async for vote in self.getMergeVotes()]
@@ -490,10 +490,11 @@ class View(s_nexus.Pusher): # type: ignore
490
490
  await self._delMergeMeta()
491
491
 
492
492
  self.parent = None
493
- await self.info.pop('parent')
493
+ if self.info.pop('parent', None) is not None:
494
+ self.core.viewdefs.set(self.iden, self.info)
494
495
 
495
- await self.core.feedBeholder('view:set', {'iden': self.iden, 'name': 'parent', 'valu': None},
496
- gates=[self.iden, self.layers[0].iden])
496
+ await self.core.feedBeholder('view:set', {'iden': self.iden, 'name': 'parent', 'valu': None},
497
+ gates=[self.iden, self.layers[0].iden])
497
498
 
498
499
  async def mergeStormIface(self, name, todo):
499
500
  '''
@@ -707,15 +708,17 @@ class View(s_nexus.Pusher): # type: ignore
707
708
  # Add all of the bottom view's layers.
708
709
  layers.extend(view.layers)
709
710
 
710
- self.layers = layers
711
711
  layridens = [layr.iden for layr in layers]
712
- await self.info.set('layers', layridens)
713
712
 
714
- await self.core.feedBeholder('view:setlayers', {'iden': self.iden, 'layers': layridens}, gates=[self.iden, layridens[0]])
713
+ self.layers = layers
714
+ self.info['layers'] = layridens
715
+ self.core.viewdefs.set(self.iden, self.info)
716
+
717
+ await self.core.feedBeholder('view:setlayers', {'iden': self.iden, 'layers': layridens}, gates=[self.iden, self.layers[0].iden])
715
718
 
716
719
  async def pack(self):
717
720
  d = {'iden': self.iden}
718
- d.update(self.info.pack())
721
+ d.update(self.info)
719
722
 
720
723
  layrinfo = [await lyr.pack() for lyr in self.layers]
721
724
  d['layers'] = layrinfo
@@ -855,6 +858,7 @@ class View(s_nexus.Pusher): # type: ignore
855
858
 
856
859
  async def _initViewLayers(self):
857
860
 
861
+ self.layers = []
858
862
  for iden in self.info.get('layers'):
859
863
 
860
864
  layr = self.core.layers.get(iden)
@@ -1121,7 +1125,8 @@ class View(s_nexus.Pusher): # type: ignore
1121
1125
  raise s_exc.BadArg(mesg=mesg)
1122
1126
 
1123
1127
  self.parent = parent
1124
- await self.info.set(name, valu)
1128
+ self.info[name] = valu
1129
+ self.core.viewdefs.set(self.iden, self.info)
1125
1130
 
1126
1131
  await self._calcForkLayers()
1127
1132
 
@@ -1137,7 +1142,7 @@ class View(s_nexus.Pusher): # type: ignore
1137
1142
  # enforce ( which will need to be done very carefully to prevent
1138
1143
  # existing non-compliant values from causing issues with existing views )
1139
1144
  if valu is not None:
1140
- vdef = self.info.pack()
1145
+ vdef = s_msgpack.deepcopy(self.info)
1141
1146
  vdef['quorum'] = s_msgpack.deepcopy(valu)
1142
1147
  s_schemas.reqValidView(vdef)
1143
1148
  else:
@@ -1148,14 +1153,24 @@ class View(s_nexus.Pusher): # type: ignore
1148
1153
  await view._delMergeRequest()
1149
1154
 
1150
1155
  if valu is None:
1151
- await self.info.pop(name)
1156
+ self.info.pop(name, None)
1152
1157
  else:
1153
- await self.info.set(name, valu)
1158
+ self.info[name] = valu
1159
+
1160
+ self.core.viewdefs.set(self.iden, self.info)
1154
1161
 
1155
1162
  await self.core.feedBeholder('view:set', {'iden': self.iden, 'name': name, 'valu': valu},
1156
1163
  gates=[self.iden, self.layers[0].iden])
1157
1164
  return valu
1158
1165
 
1166
+ async def _setLayerIdens(self, idens):
1167
+ # this may only be called from within a nexus handler...
1168
+ self.info['layers'] = idens
1169
+ self.core.viewdefs.set(self.iden, self.info)
1170
+ await self._initViewLayers()
1171
+ await self.core.feedBeholder('view:set', {'iden': self.iden, 'name': 'layers', 'valu': idens},
1172
+ gates=[self.iden, self.layers[0].iden])
1173
+
1159
1174
  async def addLayer(self, layriden, indx=None):
1160
1175
  if any(layriden == layr.iden for layr in self.layers):
1161
1176
  raise s_exc.DupIden(mesg='May not have the same layer in a view twice')
@@ -1184,7 +1199,9 @@ class View(s_nexus.Pusher): # type: ignore
1184
1199
  else:
1185
1200
  self.layers.insert(indx, layr)
1186
1201
 
1187
- await self.info.set('layers', [lyr.iden for lyr in self.layers])
1202
+ self.info['layers'] = [lyr.iden for lyr in self.layers]
1203
+ self.core.viewdefs.set(self.iden, self.info)
1204
+
1188
1205
  await self.core.feedBeholder('view:addlayer', {'iden': self.iden, 'layer': layriden, 'indx': indx}, gates=[self.iden, layriden])
1189
1206
  self.core._calcViewsByLayer()
1190
1207
 
@@ -1212,7 +1229,9 @@ class View(s_nexus.Pusher): # type: ignore
1212
1229
  self.invalid = None
1213
1230
  self.layers = layrs
1214
1231
 
1215
- await self.info.set('layers', layers)
1232
+ self.info['layers'] = layers
1233
+ self.core.viewdefs.set(self.iden, self.info)
1234
+
1216
1235
  await self.core.feedBeholder('view:setlayers', {'iden': self.iden, 'layers': layers}, gates=[self.iden, layers[0]])
1217
1236
 
1218
1237
  await self._calcChildViews()
@@ -1242,7 +1261,8 @@ class View(s_nexus.Pusher): # type: ignore
1242
1261
 
1243
1262
  # convert layers to a list of idens...
1244
1263
  lids = [layr.iden for layr in layers]
1245
- await child.info.set('layers', lids)
1264
+ child.info['layers'] = lids
1265
+ self.core.viewdefs.set(child.iden, child.info)
1246
1266
 
1247
1267
  await self.core.feedBeholder('view:setlayers', {'iden': child.iden, 'layers': lids}, gates=[child.iden, lids[0]])
1248
1268
 
@@ -1300,8 +1320,9 @@ class View(s_nexus.Pusher): # type: ignore
1300
1320
  await self.core._addView(vdef)
1301
1321
 
1302
1322
  forkiden = vdef.get('iden')
1323
+ self.info['parent'] = forkiden
1303
1324
  self.parent = self.core.reqView(forkiden)
1304
- await self.info.set('parent', forkiden)
1325
+ self.core.viewdefs.set(self.iden, self.info)
1305
1326
 
1306
1327
  mesg = {'iden': self.iden, 'name': 'parent', 'valu': forkiden}
1307
1328
  await self.core.feedBeholder('view:set', mesg, gates=[self.iden, self.layers[0].iden])
@@ -1386,6 +1407,12 @@ class View(s_nexus.Pusher): # type: ignore
1386
1407
  async for nodeedits in fromlayr.iterLayerNodeEdits():
1387
1408
  await self.parent.storNodeEdits([nodeedits], meta)
1388
1409
 
1410
+ async def swapLayer(self):
1411
+ oldlayr = self.layers[0]
1412
+ newlayr = await self.core._twinLayer(oldlayr)
1413
+ await self.core.swapLayer(oldlayr.iden, newlayr.iden)
1414
+ await self.core.delLayer(oldlayr.iden)
1415
+
1389
1416
  async def wipeLayer(self, useriden=None):
1390
1417
  '''
1391
1418
  Delete the data in the write layer by generating del nodeedits.
@@ -1549,7 +1576,7 @@ class View(s_nexus.Pusher): # type: ignore
1549
1576
 
1550
1577
  trig = await self.triggers.load(tdef)
1551
1578
 
1552
- await self.trigdict.set(trig.iden, tdef)
1579
+ self.trigdict.set(trig.iden, tdef)
1553
1580
  await self.core.auth.addAuthGate(trig.iden, 'trigger')
1554
1581
  await user.setAdmin(True, gateiden=tdef.get('iden'), logged=False)
1555
1582
 
@@ -1581,7 +1608,7 @@ class View(s_nexus.Pusher): # type: ignore
1581
1608
  return
1582
1609
 
1583
1610
  await self.core.feedBeholder('trigger:del', {'iden': trig.iden, 'view': trig.view.iden}, gates=[trig.iden])
1584
- await self.trigdict.pop(trig.iden)
1611
+ self.trigdict.pop(trig.iden)
1585
1612
  await self.core.auth.delAuthGate(trig.iden)
1586
1613
 
1587
1614
  @s_nexus.Pusher.onPushAuto('trigger:set')
@@ -1607,7 +1634,7 @@ class View(s_nexus.Pusher): # type: ignore
1607
1634
  Note: this does not delete any layer storage.
1608
1635
  '''
1609
1636
  await self.fini()
1610
- await self.node.pop()
1637
+ await self.trigdict.truncate()
1611
1638
  await self._wipeViewMeta()
1612
1639
  shutil.rmtree(self.dirn, ignore_errors=True)
1613
1640
 
synapse/models/base.py CHANGED
@@ -59,6 +59,10 @@ class BaseModule(s_module.CoreModule):
59
59
  ('meta:ruleset', ('guid', {}), {
60
60
  'doc': 'A set of rules linked with -(has)> edges.'}),
61
61
 
62
+ ('meta:rule:type:taxonomy', ('taxonomy', {}), {
63
+ 'interfaces': ('meta:taxonomy',),
64
+ 'doc': 'A taxonomy for meta:rule types.'}),
65
+
62
66
  ('meta:rule', ('guid', {}), {
63
67
  'doc': 'A generic rule linked to matches with -(matches)> edges.'}),
64
68
 
@@ -257,9 +261,12 @@ class BaseModule(s_module.CoreModule):
257
261
  'doc': 'The time the ruleset was most recently modified.'}),
258
262
  )),
259
263
 
264
+ ('meta:rule:type:taxonomy', {}, ()),
260
265
  ('meta:rule', {}, (
261
266
  ('name', ('str', {'lower': True, 'onespace': True}), {
262
267
  'doc': 'A name for the rule.'}),
268
+ ('type', ('meta:rule:type:taxonomy', {}), {
269
+ 'doc': 'The rule type.'}),
263
270
  ('desc', ('str', {}), {
264
271
  'disp': {'hint': 'text'},
265
272
  'doc': 'A description of the rule.'}),
synapse/models/biz.py CHANGED
@@ -89,6 +89,10 @@ class BizModule(s_module.CoreModule):
89
89
  ('requirements', ('array', {'type': 'ou:goal', 'uniq': True, 'sorted': True}), {}),
90
90
  )),
91
91
  ('biz:deal', {}, (
92
+ ('id', ('str', {'strip': True}), {
93
+ 'doc': 'An identifier for the deal.',
94
+ }),
95
+
92
96
  ('title', ('str', {}), {
93
97
  'doc': 'A title for the deal.',
94
98
  }),
synapse/models/files.py CHANGED
@@ -715,13 +715,15 @@ class FileModule(s_module.CoreModule):
715
715
  ('entry:extended', ('file:path', {}), {
716
716
  'doc': 'The extended file path contained within the extended FileEntry structure of the LNK file.'}),
717
717
  ('entry:localized', ('file:path', {}), {
718
- 'doc': 'The localized file path contained within the extended FileEntry structure of the LNK file.'}),
718
+ 'doc': 'The localized file path reconstructed from references within the extended FileEntry structure of the LNK file.'}),
719
719
  ('entry:icon', ('file:path', {}), {
720
720
  'doc': 'The icon file path contained within the StringData structure of the LNK file.'}),
721
721
  ('environment:path', ('file:path', {}), {
722
722
  'doc': 'The target file path contained within the EnvironmentVariableDataBlock structure of the LNK file.'}),
723
723
  ('environment:icon', ('file:path', {}), {
724
724
  'doc': 'The icon file path contained within the IconEnvironmentDataBlock structure of the LNK file.'}),
725
+ ('iconindex', ('int', {}), {
726
+ 'doc': 'A resource index for an icon within an icon location.'}),
725
727
  ('working', ('file:path', {}), {
726
728
  'doc': 'The working directory used when activating the link target.'}),
727
729
  ('relative', ('str', {'strip': True}), {
@@ -741,6 +743,11 @@ class FileModule(s_module.CoreModule):
741
743
  'doc': 'The access time of the target file according to the LNK header.'}),
742
744
  ('target:written', ('time', {}), {
743
745
  'doc': 'The write time of the target file according to the LNK header.'}),
746
+
747
+ ('driveserial', ('int', {}), {
748
+ 'doc': 'The drive serial number of the volume the link target is stored on.'}),
749
+ ('machineid', ('it:hostname', {}), {
750
+ 'doc': 'The NetBIOS name of the machine where the link target was last located.'}),
744
751
  )),
745
752
  ),
746
753
 
synapse/models/inet.py CHANGED
@@ -1519,6 +1519,7 @@ class InetModule(s_module.CoreModule):
1519
1519
  'doc': 'An object status enumeration.'}),
1520
1520
 
1521
1521
  ('inet:service:account', ('guid', {}), {
1522
+ 'interfaces': ('inet:service:object',),
1522
1523
  'doc': 'An account within a service platform. Accounts may be instance specific.'}),
1523
1524
 
1524
1525
  ('inet:service:permission:type:taxonomy', ('taxonomy', {}), {
@@ -1557,6 +1558,10 @@ class InetModule(s_module.CoreModule):
1557
1558
  'interfaces': ('inet:service:object',),
1558
1559
  'doc': 'A channel used to distribute messages.'}),
1559
1560
 
1561
+ ('inet:service:thread', ('guid', {}), {
1562
+ 'interfaces': ('inet:service:object',),
1563
+ 'doc': 'A message thread.'}),
1564
+
1560
1565
  ('inet:service:channel:member', ('guid', {}), {
1561
1566
  'interfaces': ('inet:service:object',),
1562
1567
  'doc': 'Represents a service account being a member of a channel.'}),
@@ -1571,6 +1576,10 @@ class InetModule(s_module.CoreModule):
1571
1576
  ('inet:service:message:attachment', ('guid', {}), {
1572
1577
  'doc': 'A file attachment included within a message.'}),
1573
1578
 
1579
+ ('inet:service:message:type:taxonomy', ('taxonomy', {}), {
1580
+ 'interfaces': ('meta:taxonomy',),
1581
+ 'doc': 'A message type taxonomy.'}),
1582
+
1574
1583
  ('inet:service:access', ('guid', {}), {
1575
1584
  'interfaces': ('inet:service:action',),
1576
1585
  'doc': 'Represents a user access request to a service resource.'}),
@@ -3640,6 +3649,7 @@ class InetModule(s_module.CoreModule):
3640
3649
  # TODO ndef based auth proto details
3641
3650
  )),
3642
3651
 
3652
+ ('inet:service:message:type:taxonomy', {}, ()),
3643
3653
  ('inet:service:message', {}, (
3644
3654
 
3645
3655
  ('account', ('inet:service:account', {}), {
@@ -3657,9 +3667,15 @@ class InetModule(s_module.CoreModule):
3657
3667
  ('channel', ('inet:service:channel', {}), {
3658
3668
  'doc': 'The channel that the message was sent to.'}),
3659
3669
 
3670
+ ('thread', ('inet:service:thread', {}), {
3671
+ 'doc': 'The thread which contains the message.'}),
3672
+
3660
3673
  ('public', ('bool', {}), {
3661
3674
  'doc': 'Set to true if the message is publicly visible.'}),
3662
3675
 
3676
+ ('title', ('str', {'lower': True, 'onespace': True}), {
3677
+ 'doc': 'The message title.'}),
3678
+
3663
3679
  ('text', ('str', {}), {
3664
3680
  'disp': {'hint': 'text'},
3665
3681
  'doc': 'The text body of the message.'}),
@@ -3693,6 +3709,9 @@ class InetModule(s_module.CoreModule):
3693
3709
 
3694
3710
  ('file', ('file:bytes', {}), {
3695
3711
  'doc': 'The raw file that the message was extracted from.'}),
3712
+
3713
+ ('type', ('inet:service:message:type:taxonomy', {}), {
3714
+ 'doc': 'The type of message.'}),
3696
3715
  )),
3697
3716
 
3698
3717
  ('inet:service:message:link', {}, (
@@ -3725,6 +3744,18 @@ class InetModule(s_module.CoreModule):
3725
3744
  'doc': 'The time period where the channel was available.'}),
3726
3745
  )),
3727
3746
 
3747
+ ('inet:service:thread', {}, (
3748
+
3749
+ ('title', ('str', {'lower': True, 'onespace': True}), {
3750
+ 'doc': 'The title of the thread.'}),
3751
+
3752
+ ('channel', ('inet:service:channel', {}), {
3753
+ 'doc': 'The channel that contains the thread.'}),
3754
+
3755
+ ('message', ('inet:service:message', {}), {
3756
+ 'doc': 'The message which initiated the thread.'}),
3757
+ )),
3758
+
3728
3759
  ('inet:service:channel:member', {}, (
3729
3760
 
3730
3761
  ('channel', ('inet:service:channel', {}), {
@@ -941,13 +941,13 @@ bar baz",vv
941
941
  conf = {'http:proxy': 'socks5://user:pass@127.0.0.1:1'}
942
942
  async with self.getTestAxon(conf=conf) as axon:
943
943
  async with axon.getLocalProxy() as proxy:
944
- resp = await proxy.wget('http://vertex.link')
944
+ resp = await proxy.wget('http://vertex.link/')
945
945
  self.false(resp.get('ok'))
946
946
  self.isin('connect to proxy 127.0.0.1:1', resp.get('mesg', ''))
947
947
 
948
948
  resp = await proxy.wget('vertex.link')
949
949
  self.false(resp.get('ok'))
950
- self.isin('InvalidURL: vertex.link', resp.get('mesg', ''))
950
+ self.isin('InvalidUrlClientError: vertex.link', resp.get('mesg', ''))
951
951
 
952
952
  async def test_axon_wput(self):
953
953
 
@@ -1027,11 +1027,11 @@ bar baz",vv
1027
1027
 
1028
1028
  resp = await proxy.wput(sha256, 'vertex.link')
1029
1029
  self.false(resp.get('ok'))
1030
- self.isin('InvalidURL: vertex.link', resp.get('mesg', ''))
1030
+ self.isin('InvalidUrlClientError: vertex.link', resp.get('mesg', ''))
1031
1031
 
1032
1032
  resp = await proxy.postfiles(fields, 'vertex.link')
1033
1033
  self.false(resp.get('ok'))
1034
- self.isin('InvalidURL: vertex.link', resp.get('reason'))
1034
+ self.isin('InvalidUrlClientError: vertex.link', resp.get('reason'))
1035
1035
 
1036
1036
  # Bypass the Axon proxy configuration from Storm
1037
1037
  url = axon.getLocalUrl()
@@ -1131,6 +1131,9 @@ bar baz",vv
1131
1131
  bytslist = [b async for b in axon.get(sha256, 2, size=6)]
1132
1132
  self.eq(b'dfqwer', b''.join(bytslist))
1133
1133
 
1134
+ metrics = await axon.metrics()
1135
+ self.eq(metrics, {'size:bytes': 12, 'file:count': 1})
1136
+
1134
1137
  async def test_axon_mirror(self):
1135
1138
 
1136
1139
  async with self.getTestAhaProv() as aha: