Skip to content

Commit

Permalink
Fix
Browse files Browse the repository at this point in the history
Signed-off-by: Tyler Gu <[email protected]>
  • Loading branch information
tylergu committed Nov 12, 2023
1 parent 8be402a commit 849f132
Show file tree
Hide file tree
Showing 4 changed files with 368 additions and 88 deletions.
95 changes: 95 additions & 0 deletions performance_measurement/check_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
from typing import List

import kubernetes.client.models as k8s_models
from deepdiff import DeepDiff


def check_resources(desired_resources: dict, sts_object: k8s_models.V1StatefulSet) -> bool:
# check if resources match
if desired_resources is not None:
resource_matched = True
if "limits" in desired_resources and desired_resources["limits"]:
if ("limits" not in sts_object["spec"]["template"]["spec"]["containers"][0]["resources"]
or not sts_object["spec"]["template"]["spec"]["containers"][0]["resources"]["limits"]):
resource_matched = False
else:
for resource in desired_resources["limits"]:
if (desired_resources["limits"][resource] !=
sts_object["spec"]["template"]["spec"]["containers"][0]["resources"]["limits"][resource]):
resource_matched = False
else:
if ("limits" in sts_object["spec"]["template"]["spec"]["containers"][0]["resources"]
and sts_object["spec"]["template"]["spec"]["containers"][0]["resources"]["limits"]):
resource_matched = False

if "requests" in desired_resources and desired_resources[
"requests"]:
if ("requests" not in sts_object["spec"]["template"]["spec"]["containers"][0]["resources"]
or not sts_object["spec"]["template"]["spec"]["containers"][0]["resources"]["requests"]):
resource_matched = False
else:
for resource in desired_resources["requests"]:
if desired_resources["requests"][resource] != sts_object[
"spec"]["template"]["spec"]["containers"][0]["resources"][
"requests"][resource]:
resource_matched = False
else:
if ("requests" in sts_object["spec"]["template"]["spec"]["containers"][0]["resources"]
and sts_object["spec"]["template"]["spec"]["containers"][0]["resources"]["requests"]):
resource_matched = False
return resource_matched
else:
if sts_object["spec"]["template"]["spec"]["containers"][0]["resources"]["claims"] is not None:
return False
if sts_object["spec"]["template"]["spec"]["containers"][0]["resources"]["limits"] is not None:
return False
if sts_object["spec"]["template"]["spec"]["containers"][0]["resources"]["requests"] is not None:
return False
return True


def check_tolerations(
desired_tolerations: List[dict],
sts_object: k8s_models.V1StatefulSet) -> bool:
# check if tolerations match
if desired_tolerations is None:
return sts_object["spec"]["template"]["spec"]["tolerations"] is None
toleration_matched = True
for toleration in desired_tolerations:
for toleration_in_sts in sts_object["spec"]["template"]["spec"]["tolerations"]:
if (("effect" not in toleration or toleration["effect"] == toleration_in_sts["effect"])
and ("key" not in toleration or toleration["key"] == toleration_in_sts["key"])
and ("operator" not in toleration or toleration["operator"] == toleration_in_sts["operator"])
and ("value" not in toleration or toleration["value"] == toleration_in_sts["value"])):
break
else:
toleration_matched = False
break

return toleration_matched


def check_affinity(desired_affinity: dict, sts_object: k8s_models.V1StatefulSet) -> bool:
# check if affinity match
current_affinity = sts_object["spec"]["template"]["spec"]["affinity"]
deepdiff = DeepDiff(desired_affinity, current_affinity, ignore_order=True)
if deepdiff:
return False
else:
return True


def check_persistent_volume_claim_retention_policy(
desired_policy: dict, sts_object: k8s_models.V1StatefulSet) -> bool:
# check if persistent volume claim retention policy match
current_policy = sts_object["spec"]["persistent_volume_claim_retention_policy"]
if desired_policy is not None:
if "whenDeleted" in desired_policy and desired_policy["whenDeleted"] and sts_object[
"when_deleted"] != desired_policy["whenDeleted"]:
return False

if "whenScaled" in desired_policy and desired_policy["whenScaled"] and sts_object[
"when_scaled"] != desired_policy["whenScaled"]:
return False

return True
91 changes: 60 additions & 31 deletions performance_measurement/measure_performance.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from datetime import datetime

import yaml
from performance_measurement.rabbitmq_inputs import RabbitMQInputGenerator
from zk_inputs import ZooKeeperInputGenerator

from acto import utils
Expand Down Expand Up @@ -145,6 +146,54 @@ def test_normal(
gen += 1


def main(args):
input_generator: ChainInputs = None
condition_1_func: ConditionFuncType = None
condition_2_func: ConditionFuncType = None
if args.project == "rabbitmq-operator":
input_generator = RabbitMQInputGenerator
condition_1_func = MeasurementRunner.wait_for_rabbitmq_spec
condition_2_func = MeasurementRunner.wait_for_pod_ready
elif args.project == "zookeeper-operator":
input_generator = ZooKeeperInputGenerator
condition_1_func = MeasurementRunner.wait_for_zk_spec
reference_condition_1_func = MeasurementRunner.wait_for_reference_zk_spec
condition_2_func = MeasurementRunner.wait_for_pod_ready

# parse the inputs
with open(args.anvil_config, "r") as config_file:
config = json.load(config_file)
if "monkey_patch" in config:
del config["monkey_patch"]
config = OperatorConfig(**config)

chain_inputs = input_generator(testrun_dir=args.input_dir, config=config)
os.makedirs(f"{args.workdir_path}/inputs", exist_ok=True)
chain_inputs.serialize(f"{args.workdir_path}/inputs")

# Run the Anvil performance test
if "anvil" in args.phase:
anvil_workdir = f"{args.workdir_path}/anvil"
os.makedirs(anvil_workdir, exist_ok=True)
test_normal(
anvil_workdir,
f"{args.workdir_path}/inputs/anvil_inputs", config, condition_1_func,
MeasurementRunner.wait_for_pod_ready)

# Run the reference performance test
# reference_config = "data/zookeeper-operator/v0.2.15/config.json"
if "reference" in args.phase:
with open(args.reference_config, "r") as config_file:
config = json.load(config_file)
if "monkey_patch" in config:
del config["monkey_patch"]
config = OperatorConfig(**config)

reference_dir = f"{args.workdir_path}/reference"
test_normal(reference_dir, f"{args.workdir_path}/inputs/reference", config,
MeasurementRunner.wait_for_reference_zk_spec, MeasurementRunner.wait_for_pod_ready)


if __name__ == "__main__":
workdir_path = "testrun-%s" % datetime.now().strftime("%Y-%m-%d-%H-%M")

Expand All @@ -158,8 +207,16 @@ def test_normal(
parser.add_argument(
"--input-dir", dest="input_dir", required=True,
help="The directory of the trial folder to reproduce. CR files should have names starting with 'mutated-'")
parser.add_argument("--config", "-c", dest="config",
help="Operator port config path")
parser.add_argument("--anvil-config", "-c", dest="anvil_config",
help="Anvil operator port config path")
parser.add_argument("--reference-config", "-r", dest="reference_config",
help="Reference operator port config path")
parser.add_argument("--phase", "-p", dest="phase",
nargs="+",
default=["anvil", "reference"],
help="The phase of the trial to reproduce")
parser.add_argument("--project", "-j", dest="project",
help="The project name to use for the trial", required=True)
args = parser.parse_args()

os.makedirs(args.workdir_path, exist_ok=True)
Expand All @@ -171,32 +228,4 @@ def test_normal(
logging.getLogger("kubernetes").setLevel(logging.ERROR)
logging.getLogger("sh").setLevel(logging.ERROR)

# parse the inputs
with open(args.config, "r") as config_file:
config = json.load(config_file)
if "monkey_patch" in config:
del config["monkey_patch"]
config = OperatorConfig(**config)

gen = 0
chain_inputs = ZooKeeperInputGenerator(testrun_dir=args.input_dir, config=config)
os.makedirs(f"{args.workdir_path}/inputs", exist_ok=True)
chain_inputs.serialize(f"{args.workdir_path}/inputs")

anvil_workdir = f"{args.workdir_path}/anvil"
os.makedirs(anvil_workdir, exist_ok=True)
test_normal(
anvil_workdir,
f"{args.workdir_path}/inputs/anvil_inputs", config, MeasurementRunner.wait_for_zk_spec,
MeasurementRunner.wait_for_pod_ready)

reference_config = "data/zookeeper-operator/v0.2.15/config.json"
with open(reference_config, "r") as config_file:
config = json.load(config_file)
if "monkey_patch" in config:
del config["monkey_patch"]
config = OperatorConfig(**config)

reference_dir = f"{args.workdir_path}/reference"
test_normal(reference_dir, f"{args.workdir_path}/inputs/reference", config,
MeasurementRunner.wait_for_reference_zk_spec, MeasurementRunner.wait_for_pod_ready)
main(args)
Loading

0 comments on commit 849f132

Please sign in to comment.