diff options
Diffstat (limited to 'molecule/default/tests')
| -rw-r--r-- | molecule/default/tests/test_check_prometheus_targets.py | 90 | ||||
| -rw-r--r-- | molecule/default/tests/test_lineinfile_strategy.py | 94 | ||||
| -rw-r--r-- | molecule/default/tests/test_yaml_strategy.py | 139 |
3 files changed, 233 insertions, 90 deletions
diff --git a/molecule/default/tests/test_check_prometheus_targets.py b/molecule/default/tests/test_check_prometheus_targets.py deleted file mode 100644 index b9024b4..0000000 --- a/molecule/default/tests/test_check_prometheus_targets.py +++ /dev/null @@ -1,90 +0,0 @@ -testinfra_hosts = ["prometheus"] - -""" -Test functionality of defining exporters and default fallbacks -""" - - -def test_check_hosts_added_simple(host): - t1 = host.file("/opt/simple_target1.yml") - t2 = host.file("/opt/simple_target2.yml") - t3 = host.file("/opt/simple_target3.yml") - t4 = host.file("/opt/simple_target4.yml") - - assert t1.exists - assert t2.exists - assert t3.exists - assert t4.exists - - assert t1.content_string == " - application\n" - - assert t2.content_string == " - test1\n - test2\n" - - assert t3.content_string == " - application_AA\n" - - assert t4.content_string == " - exporter_without_id\n" - - -""" -Test prefix functionality -""" - - -def test_check_hosts_added_prefix(host): - t1 = host.file("/opt/prefix_target1.yml") - t2 = host.file("/opt/prefix_target2.yml") - t3 = host.file("/opt/prefix/prefix_target3.yml") - - assert t1.exists - assert t2.exists - assert t3.exists - - assert t1.content_string == " - application\n" - - assert t2.content_string == " - application\n" - - assert t3.content_string == " - application\n" - - -""" -Test hook functionality -""" - - -def test_check_hosts_added_hooks(host): - t1 = host.file("/opt/hook_target.yml") - t2 = host.file("/opt/hook1") - t3 = host.file("/opt/hook2") - - assert t1.exists - assert t2.exists - assert t3.exists - - assert ( - t1.content_string == " - application\n - application2\n" - or t1.content_string == " - application2\n - application\n" - ) - - assert t3.content_string == "hello\nhello\n" - - -""" -Test lineinfile strategy parameters -""" - - -def test_check_host_added_lineinfile(host): - t1 = host.file("/opt/lineinfile.yml") - - assert t1.user == "prometheus" - assert t1.group == "prometheus" - assert t1.mode == 0o600 - - assert ( - t1.content_string == "- labels:\n" - " my: label\n" - " targets:\n" - " - existing:9100\n" - " - application:9100\n" - ) - diff --git a/molecule/default/tests/test_lineinfile_strategy.py b/molecule/default/tests/test_lineinfile_strategy.py new file mode 100644 index 0000000..b75a656 --- /dev/null +++ b/molecule/default/tests/test_lineinfile_strategy.py @@ -0,0 +1,94 @@ +import yaml + + +testinfra_hosts = ["prometheus"] + + +def read_file(host, path): + target = host.file(path) + assert target.exists + return target + + +def read_yaml_file(host, path): + return yaml.safe_load(read_file(host, path).content_string) + + +def test_lineinfile_bootstrap_adds_first_host_without_breaking_yaml(host): + target = read_file(host, "/opt/lineinfile_first_host.yml") + + assert target.user == "prometheus" + assert target.group == "prometheus" + assert target.mode == 0o600 + assert read_yaml_file(host, "/opt/lineinfile_first_host.yml") == ["application:9100"] + + +def test_lineinfile_adds_subsequent_host_to_existing_yaml(host): + target = read_file(host, "/opt/lineinfile_bootstrap.yml") + + assert target.content_string == ( + "- labels:\n" + " my: label\n" + " targets:\n" + " - existing:9100\n" + " - application:9100\n" + ) + + assert read_yaml_file(host, "/opt/lineinfile_bootstrap.yml") == [ + {"labels": {"my": "label"}, "targets": ["existing:9100", "application:9100"]} + ] + + +def test_lineinfile_parallel_writes_keep_all_hosts_and_parse(host): + hosts = sorted(read_yaml_file(host, "/opt/lineinfile_parallel.yml")) + assert hosts == [ + "application2:9100", + "application3:9100", + "application4:9100", + "application:9100", + ] + + +def test_lineinfile_user_edited_file_stays_parseable(host): + target = read_file(host, "/opt/lineinfile_user_edited.yml") + + assert target.content_string == ( + "# user comment\n" + "- labels:\n" + " env: prod\n" + " targets:\n" + " - existing:9100\n" + " - application2:9100\n" + ) + + assert read_yaml_file(host, "/opt/lineinfile_user_edited.yml") == [ + {"labels": {"env": "prod"}, "targets": ["existing:9100", "application2:9100"]} + ] + + +def test_lineinfile_removing_last_host_still_leaves_parseable_yaml(host): + assert read_yaml_file(host, "/opt/lineinfile_remove_last.yml") == [ + {"labels": {"env": "stage"}, "targets": None} + ] + + +def test_lineinfile_compatibility_simple_and_prefix_cases(host): + assert read_yaml_file(host, "/opt/simple_target1.yml") == ["application"] + assert read_yaml_file(host, "/opt/simple_target2.yml") == ["test1", "test2"] + assert read_yaml_file(host, "/opt/simple_target3.yml") == ["application_AA"] + assert read_yaml_file(host, "/opt/simple_target4.yml") == ["exporter_without_id"] + assert read_yaml_file(host, "/opt/prefix_target1.yml") == ["application"] + assert read_yaml_file(host, "/opt/prefix_target2.yml") == ["application"] + assert read_yaml_file(host, "/opt/prefix/prefix_target3.yml") == ["application"] + + +def test_lineinfile_hooks_still_run(host): + assert sorted(read_yaml_file(host, "/opt/hook_target.yml")) == [ + "application", + "application2", + "application3", + "application4", + ] + + assert host.file("/opt/hook1").exists + assert host.file("/opt/hook2").content_string == "hello\nhello\nhello\nhello\n" diff --git a/molecule/default/tests/test_yaml_strategy.py b/molecule/default/tests/test_yaml_strategy.py new file mode 100644 index 0000000..89dbdeb --- /dev/null +++ b/molecule/default/tests/test_yaml_strategy.py @@ -0,0 +1,139 @@ +import yaml + + +testinfra_hosts = ["prometheus"] + + +def read_yaml_file(host, path): + target = host.file(path) + assert target.exists + return yaml.safe_load(target.content_string) + + +def get_group_by_labels(groups, labels): + for group in groups: + if group.get("labels", {}) == labels: + return group + raise AssertionError(f"Missing target group with labels {labels!r}") + + +def get_unlabeled_group(groups): + for group in groups: + if group.get("labels", {}) == {}: + return group + raise AssertionError("Missing unlabeled target group") + + +def has_group_with_labels(groups, labels): + return any(group.get("labels", {}) == labels for group in groups) + + +def test_yaml_bootstrap_adds_first_host_to_empty_file(host): + assert read_yaml_file(host, "/opt/yaml_bootstrap.yml") == [ + {"labels": {"job": "node"}, "targets": ["application:9100"]} + ] + + +def test_yaml_parallel_writes_keep_all_hosts_in_same_group(host): + groups = read_yaml_file(host, "/opt/yaml_parallel.yml") + assert get_group_by_labels(groups, {"job": "node"})["targets"] == [ + "existing:9100", + "application:9100", + "application2:9100", + "application3:9100", + "application4:9100", + ] + + +def test_yaml_user_edited_file_is_reparsed_and_keeps_expected_semantics(host): + groups = read_yaml_file(host, "/opt/yaml_user_edited.yml") + + assert get_group_by_labels(groups, {"severity": "warning", "job": "external"})[ + "targets" + ] == ["existing_host1:9100", "application2:9100"] + + assert get_group_by_labels(groups, {"severity": "critical", "team": "blue"})[ + "targets" + ] == ["application2:9200"] + + assert get_unlabeled_group(groups)["targets"] == ["unlabeled:9100", "standalone:9300"] + + +def test_yaml_moving_host_removes_last_host_from_old_group(host): + groups = read_yaml_file(host, "/opt/yaml_move_remove_last.yml") + + assert not has_group_with_labels(groups, {"job": "old"}) + assert get_group_by_labels(groups, {"job": "new"})["targets"] == ["application:9400"] + + +def test_yaml_output_remains_parseable_after_all_operations(host): + for path in [ + "/opt/yaml_bootstrap.yml", + "/opt/yaml_parallel.yml", + "/opt/yaml_user_edited.yml", + "/opt/yaml_move_remove_last.yml", + "/opt/yaml_branch_matrix.yml", + "/opt/yaml_missing_labeled.yml", + "/opt/yaml_missing_unlabeled.yml", + ]: + assert read_yaml_file(host, path) is not None + + +def test_yaml_branch_matrix_covers_exact_match_and_append(host): + groups = read_yaml_file(host, "/opt/yaml_branch_matrix.yml") + + assert get_group_by_labels(groups, {"job": "append", "env": "prod"})["targets"] == [ + "existing_append:9500", + "application3:9506", + ] + + assert get_group_by_labels(groups, {"job": "present", "env": "prod"})["targets"] == [ + "application3:9501" + ] + + +def test_yaml_branch_matrix_keeps_nonmatching_groups_for_both_label_mismatch_paths(host): + groups = read_yaml_file(host, "/opt/yaml_branch_matrix.yml") + + assert get_group_by_labels(groups, {"job": "wrong", "env": "prod"})["targets"] == [ + "keep_same_length:9500" + ] + + assert get_group_by_labels(groups, {"job": "short"})["targets"] == [ + "keep_length_mismatch:9500" + ] + + assert get_group_by_labels(groups, {"job": "foreign"})["targets"] == ["foreign:9505"] + + +def test_yaml_branch_matrix_moves_hosts_and_drops_emptied_groups(host): + groups = read_yaml_file(host, "/opt/yaml_branch_matrix.yml") + + assert not has_group_with_labels(groups, {"job": "move_source"}) + + assert get_group_by_labels(groups, {"job": "move_target"})["targets"] == [ + "application3:9502" + ] + + assert get_group_by_labels(groups, {"job": "promoted"})["targets"] == [ + "orphan_unlabeled:9503" + ] + + +def test_yaml_branch_matrix_preserves_unlabeled_group_when_targets_remain(host): + groups = read_yaml_file(host, "/opt/yaml_branch_matrix.yml") + + assert get_unlabeled_group(groups)["targets"] == [ + "shared_unlabeled:9504", + "standalone_branch:9504", + ] + + +def test_yaml_branch_matrix_creates_missing_file_groups_for_labeled_and_unlabeled_targets(host): + assert read_yaml_file(host, "/opt/yaml_missing_labeled.yml") == [ + {"labels": {"team": "infra"}, "targets": ["application4:9600"]} + ] + + assert read_yaml_file(host, "/opt/yaml_missing_unlabeled.yml") == [ + {"targets": ["application4:9601"]} + ] |