Nir Soffer has posted comments on this change.

Change subject: VolumeMetadata: Add from_lines factory method
......................................................................


Patch Set 4: Code-Review-1

(11 comments)

https://gerrit.ovirt.org/#/c/52672/4/tests/storage_volume_metadata_test.py
File tests/storage_volume_metadata_test.py:

Line 107:         params = get_params()
Line 108:         params[param] = 'not_an_int'
Line 109:         self.assertRaises(AssertionError, volume.VolumeMetadata, 
**params)
Line 110: 
Line 111:     def test_from_lines_missing_param(self):
Missing POOL will not raise, but this test does not check this. I think that 
this test must be more specific about the required keys.
Line 112:         self.assertRaises(se.MetaDataKeyNotFoundError,
Line 113:                           volume.VolumeMetadata.from_lines, [])
Line 114: 
Line 115:     def test_from_lines_invalid_param(self):


Line 118:         lines.insert(0, "FOO=BAR")
Line 119:         self.assertNotIn("FOO",
Line 120:                          
volume.VolumeMetadata.from_lines(lines).legacy_info())
Line 121: 
Line 122:     def test_from_lines_invalid_format(self):
invalid_format is confusing, I was trying to understand whats wrong with 
"FORMAT=format".

test_from_lines_invalid_size?

Also FOO is less clear than NOT_AN_INT

This also does not test that invalid ctime or mtime raise. We should be more 
specific about the behavior of such infrastructure.
Line 123:         lines = ["DOMAIN=domain", "IMAGE=image", "PUUID=parent", 
"SIZE=FOO",
Line 124:                  "FORMAT=format", "TYPE=type", "VOLTYPE=voltype",
Line 125:                  "DISKTYPE=disktype", "EOF"]
Line 126:         self.assertRaises(ValueError,


Line 121: 
Line 122:     def test_from_lines_invalid_format(self):
Line 123:         lines = ["DOMAIN=domain", "IMAGE=image", "PUUID=parent", 
"SIZE=FOO",
Line 124:                  "FORMAT=format", "TYPE=type", "VOLTYPE=voltype",
Line 125:                  "DISKTYPE=disktype", "EOF"]
This is very hard to read, please use always one item per line, sorted.
Line 126:         self.assertRaises(ValueError,
Line 127:                           volume.VolumeMetadata.from_lines, lines)
Line 128: 
Line 129:     def test_from_lines(self):


Line 129:     def test_from_lines(self):
Line 130:         lines = ["DOMAIN=domain", "IMAGE=image", "PUUID=parent", 
"SIZE=0",
Line 131:                  "FORMAT=format", "TYPE=type", "VOLTYPE=voltype",
Line 132:                  "DISKTYPE=disktype", "DESCRIPTION=description", 
"MTIME=0",
Line 133:                  "CTIME=0", "LEGALITY=legality", "EOF"]
Same
Line 134:         md = volume.VolumeMetadata.from_lines(lines)
Line 135:         self.assertEqual('domain', md.sd_id)
Line 136:         self.assertEqual('image', md.img_id)
Line 137:         self.assertEqual('parent', md.parent_vol_id)


https://gerrit.ovirt.org/#/c/52672/4/vdsm/storage/volume.py
File vdsm/storage/volume.py:

Line 199
Line 200
Line 201
Line 202
Line 203
Lets use validate_description - this class is does not have any other legacy 
name.


Line 169:     TYPE_NETWORK = "network"
Line 170: 
Line 171: 
Line 172: class VolumeMetadata(object):
Line 173:     # metadata_key: (attribute, coercion_fn)
This is not coercion but validation - it convert the string to the correct 
value or raise ValueError if it cannot convert the string.
Line 174:     MD_FIELDS = {
Line 175:         DOMAIN: ('sd_id', None),
Line 176:         IMAGE:  ('img_id', None),
Line 177:         PUUID:  ('parent_vol_id', None),


Line 209: 
Line 210:     @classmethod
Line 211:     def from_lines(cls, lines):
Line 212:         kwargs = {}
Line 213:         found_md = []
We can use set() and name it found_keys
Line 214:         for l in lines:
Line 215:             if l.startswith("EOF"):
Line 216:                 break
Line 217:             if l.find("=") < 0:


Line 210:     @classmethod
Line 211:     def from_lines(cls, lines):
Line 212:         kwargs = {}
Line 213:         found_md = []
Line 214:         for l in lines:
Use "line" instead of "l".
Line 215:             if l.startswith("EOF"):
Line 216:                 break
Line 217:             if l.find("=") < 0:
Line 218:                 continue


Line 213:         found_md = []
Line 214:         for l in lines:
Line 215:             if l.startswith("EOF"):
Line 216:                 break
Line 217:             if l.find("=") < 0:
Better use:

    if "=" not in line:
        continue
Line 218:                 continue
Line 219:             key, value = [item.strip() for item in l.split("=", 1)]
Line 220: 
Line 221:             if key == POOL:  # POOL is deprecated


Line 230:             found_md.append(key)
Line 231: 
Line 232:         missing = set(cls.MD_FIELDS.keys()) - set(found_md)
Line 233:         if missing:
Line 234:             raise se.MetaDataKeyNotFoundError("Missing: %s" % 
list(missing))
Nice!
Line 235:         return cls(**kwargs)
Line 236: 
Line 237:     @property
Line 238:     def description(self):


Line 231: 
Line 232:         missing = set(cls.MD_FIELDS.keys()) - set(found_md)
Line 233:         if missing:
Line 234:             raise se.MetaDataKeyNotFoundError("Missing: %s" % 
list(missing))
Line 235:         return cls(**kwargs)
I think we can simplify this a lot like this:

    md = {}
    for line in lines:
        if line.startswith("EOF"):
            break
        if "=" not in line:
            continue
        key, value = line.split("=", 1)
        md[key.strip()] = value.strip()

    try:
        # Here we do the mapping and the validation
        return cls(sd_id = md[DOMAIN],
                   img_id = md[IMAGE],
                   parent_vol_id = md[PUUID],
                   size = int(md[SIZE]),
                   vol_format = md[FORMAT],
                   alloc_policy = md[PREALOCATE],
                   parental_status = md[VOLTYPE],
                   disk_type = md[DISKTYPE],
                   description = md[DESCRIPTION],
                   legality = md[LEGALITY],
                   ctime = int(md[CTIME]),
                   mtime = int(md[MTIME]))
    except KeyError as e:
        raise se.MetaDataKeyNotFoundError("Missing metadata key: %s: "
                                          "found: %s" % (e, md))

Notes:

- ignore POOL without writing any code for it
- don't warn about unknown keys, we don't care about it, and 
  it is less forward compatible
- don't show all missing keys, but do we care about it?
- MD_FIELDS not needed
Line 236: 
Line 237:     @property
Line 238:     def description(self):
Line 239:         return self._description


-- 
To view, visit https://gerrit.ovirt.org/52672
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: comment
Gerrit-Change-Id: Id7f63dce8e42e99d3240f4e916a9bd6ee5ee4b61
Gerrit-PatchSet: 4
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Adam Litke <ali...@redhat.com>
Gerrit-Reviewer: Adam Litke <ali...@redhat.com>
Gerrit-Reviewer: Jenkins CI
Gerrit-Reviewer: Nir Soffer <nsof...@redhat.com>
Gerrit-Reviewer: gerrit-hooks <automat...@ovirt.org>
Gerrit-HasComments: Yes
_______________________________________________
vdsm-patches mailing list
vdsm-patches@lists.fedorahosted.org
https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches

Reply via email to