class_docstr: DistGraphTest
      
code: def test_slot_feat(self):
      g_feat = [
          "",
          "23:0,23:1,24:10,24:3",
          "23:0,23:1,24:13,24:9",
          "23:0,23:1,24:14,24:9",
      ]
      nodes = [98, 7, 333, 247]
      feat_names = "d"
  
      nfeat_list = []
      for ntype in self.c1.node_type_list:
          nfeat_list.append(
              self.c1.get_node_feat(nodes, ntype, feat_names)
          )
  
      res = []
      for all_type_feat in zip(*nfeat_list):
          f = ""
          for feat in all_type_feat:
              if len(feat) > 0:
                  f = feat
                  break
          res.append(f)
  
      #  print(res)
      for req, gf in zip(res, g_feat):
          self.assertEqual(req, gf)
  
      NODE_FEAT_PATTERN = re.compile(r"[:,]")
      nfeat_dict = defaultdict(lambda: defaultdict(list))
      for nid, feat in zip(nodes, res):
          slot_feat = re.split(NODE_FEAT_PATTERN, feat)
          for k, v in zip(slot_feat[0::2], slot_feat[1::2]):
              try:
                  v = int(v)
                  nfeat_dict[nid][k].append(v)
              except Exception as e:
                  continue
  
imports: import os
  import sys
  import re
  import time
  import tqdm
  import argparse
  import unittest
  import shutil
  import numpy
  from collections import defaultdict
  from pgl.utils.logger import log
  from pgl.distributed import DistGraphClient, DistGraphServer
label_desc: Use image node_id 5 for calling the DistGraphTest obj's underlying member method code with example usage: obj.test_slot_feat() without return types