Skip to content

Commit

Permalink
Fix parsing of empty lines in config files
Browse files Browse the repository at this point in the history
  • Loading branch information
welpaolo committed Aug 7, 2023
1 parent 69a5e9c commit 95ba167
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 18 deletions.
3 changes: 3 additions & 0 deletions spark8t/domain.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ def _read_property_file_unsafe(cls, name: str) -> Dict:
defaults = dict()
with open(name) as f:
for line in f:
# skip empty line
if len(line.strip()) == 0:
continue
key, value = cls.parse_property_line(line)
defaults[key] = os.path.expandvars(value)
return defaults
Expand Down
9 changes: 8 additions & 1 deletion spark8t/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,9 @@ def get_service_accounts(
labels_to_pass = dict()
if labels:
for entry in labels:
# skip empty label
if len(entry.strip()) == 0:
continue
k, v = PropertyFile.parse_property_line(entry)
labels_to_pass[k] = v

Expand Down Expand Up @@ -1459,7 +1462,11 @@ def _generate_properties_file_from_arguments(confs: List[str]):
return PropertyFile({})

return PropertyFile(
dict(PropertyFile.parse_property_line(line) for line in confs)
dict(
PropertyFile.parse_property_line(line)
for line in confs
if len(line.strip()) != 0
)
)

def spark_submit(
Expand Down
69 changes: 52 additions & 17 deletions tests/unittest/test_domain.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging
import tempfile
import uuid

from spark8t.domain import Defaults, PropertyFile, ServiceAccount
Expand Down Expand Up @@ -72,36 +73,70 @@ def test_service_account():
assert sa.configurations.props.get("spark.dummy.property1") == spark_dummy_property1
assert sa.configurations.props.get("spark.dummy.property2") == spark_dummy_property2

def test_property_removing_conf(self):
confs = ["key1=value1", "key2=value2", "key3=value3"]

prop = PropertyFile(
dict(PropertyFile.parse_property_line(line) for line in confs)
)
def test_property_removing_conf():
"""
Validates removal of configuration options.
"""
confs = ["key1=value1", "key2=value2", "key3=value3"]

self.assertFalse("key1" in prop.remove(["key1"]).props)
prop = PropertyFile(dict(PropertyFile.parse_property_line(line) for line in confs))

self.assertTrue("key3" in prop.remove(["key1", "key2"]).props)
assert "key1" not in prop.remove(["key1"]).props

self.assertDictEqual(prop.props, prop.remove([]).props)
assert "key3" in prop.remove(["key1", "key2"]).props

def test_property_removing_conf_with_pairs(self):
confs = ["key1=value1", "key2=value2", "key3=value3"]
assert prop.props == prop.remove([]).props

prop = PropertyFile(
dict(PropertyFile.parse_property_line(line) for line in confs)
)

self.assertFalse("key1" in prop.remove(["key1=value1"]).props)
def test_property_removing_conf_with_pairs():
"""
Validates the correct removal of property pairs.
"""
confs = ["key1=value1", "key2=value2", "key3=value3"]

prop = PropertyFile(dict(PropertyFile.parse_property_line(line) for line in confs))

self.assertTrue("key1" in prop.remove(["key1=value2"]).props)
assert "key1" not in prop.remove(["key1=value1"]).props

self.assertFalse("key1" in prop.remove(["key1=value2", "key1=value1"]).props)
assert "key1" in prop.remove(["key1=value2"]).props

self.assertFalse("key1" in prop.remove(["key1", "key1=value2"]).props)
assert "key1" not in prop.remove(["key1=value2", "key1=value1"]).props

assert "key1" not in prop.remove(["key1", "key1=value2"]).props


def test_property_empty_lines():
"""
Validates that empty lines are skipped and configuration is parsed correctly.
"""
confs = ["key1=value1", "", "key2=value2", "key3=value3", ""]

with tempfile.NamedTemporaryFile(mode="w+t") as f:
# write conf file
for conf in confs:
f.write(f"{conf}\n")
f.flush()

with open(f.name, 'r') as fp:
assert len(fp.readlines()) == 5

# read property file from temporary file name
prop = PropertyFile.read(f.name)

assert "key1" not in prop.remove(["key1=value1"]).props

assert "key1" in prop.remove(["key1=value2"]).props

assert "key1" not in prop.remove(["key1=value2", "key1=value1"]).props

assert "key1" not in prop.remove(["key1", "key1=value2"]).props


def test_property_file_parsing_from_confs():
"""
Validates parsing of configuration from list.
"""
confs = ["key1=value1", "key2=value2"]

prop = PropertyFile(dict(PropertyFile.parse_property_line(line) for line in confs))
Expand Down

0 comments on commit 95ba167

Please sign in to comment.