def test_negative_update_unknown_field(dhcp_version): # bug: #229, FIXED # add new class ipxe if dhcp_version == 'v4': exp_class = { 'boot-file-name': '/dev/null', 'name': 'voip', 'next-server': '192.0.2.254', 'option-data': [], 'option-def': [], 'server-hostname': 'hal9000', 'test': "option[93].hex == 0x0009" } else: exp_class = { 'name': 'voip', 'option-data': [], 'test': "option[93].hex == 0x0009" } cmd = dict(command='class-add', arguments={"client-classes": [exp_class]}) response = srv_msg.send_ctrl_cmd(cmd) assert response == {'result': 0, 'text': "Class 'voip' added"} # update unknown field cmd = dict( command='class-update', arguments={"client-classes": [{ "name": 'voip', "unknown": "123" }]}) response = srv_msg.send_ctrl_cmd(cmd, exp_result=1) assert response['text'] == "unsupported client class parameter 'unknown'"
def test_remote_option_def_remove_server_tag_and_data(): _add_server_tag("abc") _optdef_set(server_tags=["abc"]) resp = _optdef_get(command="remote-option-def6-get", server_tags=["abc"], option_def_parameter={"code": 222}) _check_optdef_result(resp, server_tags=["abc"]) cmd = dict(command="remote-server6-del", arguments={ "remote": { "type": "mysql" }, "servers": [{ "server-tag": "abc" }] }) srv_msg.send_ctrl_cmd(cmd) # after removing tag all option definition should be removed with it _optdef_get(command="remote-option-def6-get", server_tags=["abc"], option_def_parameter={"code": 222}, exp_result=3)
def test_remote_option_remove_server_tag_and_data(): _add_server_tag("abc") _option_set(server_tags=["abc"]) resp = _option_get(command="remote-option6-global-get", server_tags=["abc"], opt_code=23) _check_option_result(resp, server_tags=["abc"], opt_name="dns-servers", opt_data="2001::1") cmd = dict(command="remote-server6-del", arguments={ "remote": { "type": "mysql" }, "servers": [{ "server-tag": "abc" }] }) srv_msg.send_ctrl_cmd(cmd) # after removing tag all options should be removed with it _option_get(command="remote-option6-global-get", server_tags=["abc"], opt_code=23, exp_result=3)
def test_remote_subnet4_server_tags_delete_server_tag_keep_data(): _add_server_tag("abc") _add_server_tag("xyz") _subnet_set(server_tags=["abc"], subnet_id=5, pool="2001:db8:1::1-2001:db8:1::100") _subnet_set(server_tags=["xyz"], subnet_id=6, pool="2001:db8:3::1-2001:db8:3::10", subnet="2001:db8:3::/64") resp = _subnet_get(command="remote-subnet6-get-by-id", subnet_parameter={"id": 5}) _check_subnet_result(resp, server_tags=["abc"], subnet_id=5) resp = _subnet_get(command="remote-subnet6-get-by-id", subnet_parameter={"id": 6}) _check_subnet_result(resp, server_tags=["xyz"], subnet_id=6, subnet="2001:db8:3::/64") cmd = dict(command="remote-server6-del", arguments={ "remote": { "type": "mysql" }, "servers": [{ "server-tag": "abc" }] }) srv_msg.send_ctrl_cmd(cmd) resp = _subnet_get(command="remote-subnet6-get-by-id", subnet_parameter={"id": 5}) _check_subnet_result(resp, server_tags=[], subnet_id=5, subnet="2001:db8:1::/64") _add_server_tag("abc") resp = _subnet_get(command="remote-subnet6-get-by-id", subnet_parameter={"id": 5}) _check_subnet_result(resp, server_tags=[], subnet_id=5, subnet="2001:db8:1::/64") resp = _subnet_get(command="remote-subnet6-get-by-id", subnet_parameter={"id": 6}) _check_subnet_result(resp, server_tags=["xyz"], subnet_id=6, subnet="2001:db8:3::/64")
def _add_server_tag(server_tag=None): cmd = dict(command="remote-server6-set", arguments={ "remote": { "type": "mysql" }, "servers": [{ "server-tag": server_tag }] }) srv_msg.send_ctrl_cmd(cmd, exp_result=0)
def test_server_tag_network(): cfg = setup_server_for_config_backend_cmds(server_tag="abc") _set_server_tag("xyz") _set_server_tag("abc") cfg.add_network(server_tags=["abc"], name="flor1") cfg.add_subnet(shared_network_name="flor1", server_tags=["abc"], subnet="2001:db8:1::/64", id=1, pools=[{'pool': "2001:db8:1::1-2001:db8:1::1"}]) xyz = _get_server_config() assert len(xyz["arguments"]["Dhcp6"]["shared-networks"][0]["subnet6"]) == 1 assert xyz["arguments"]["Dhcp6"]["shared-networks"][0]["subnet6"][0]["subnet"] == "2001:db8:1::/64" get_address(mac_addr='00:00:00:00:00:03', exp_addr='2001:db8:1::1') cfg.add_network(server_tags=["xyz"], name="flor2") cfg.add_subnet(shared_network_name="flor2", server_tags=["xyz"], subnet="2001:db8:2::/64", id=2, pools=[{'pool': "2001:db8:2::5-2001:db8:2::5"}]) # we still want just one network with one subnet xyz = _get_server_config() assert len(xyz["arguments"]["Dhcp6"]["shared-networks"]) == 1 assert len(xyz["arguments"]["Dhcp6"]["shared-networks"][0]["subnet6"]) == 1 assert xyz["arguments"]["Dhcp6"]["shared-networks"][0]["subnet6"][0]["subnet"] == "2001:db8:1::/64" get_rejected(mac_addr='00:00:00:00:00:10') srv_control.start_srv('DHCP', 'stopped') setup_server_for_config_backend_cmds(server_tag="xyz") get_address(mac_addr='00:00:00:00:00:04', exp_addr='2001:db8:2::5') # we still want just one network with one subnet but different subnet, from xyz xyz = _get_server_config() assert len(xyz["arguments"]["Dhcp6"]["shared-networks"]) == 1 assert len(xyz["arguments"]["Dhcp6"]["shared-networks"][0]["subnet6"]) == 1 assert xyz["arguments"]["Dhcp6"]["shared-networks"][0]["subnet6"][0]["subnet"] == "2001:db8:2::/64" cfg.add_subnet(shared_network_name="flor2", server_tags=["all"], subnet="2001:db8:3::/64", id=3, pools=[{'pool': "2001:db8:3::5-2001:db8:3::5"}]) # model was incomplete on previous step so I can't use del_subnet method because it's again # forcing checking cmd = dict(command="remote-subnet6-del-by-prefix", arguments={"remote": {"type": "mysql"}, "subnets": [{"subnet": "2001:db8:2::/64"}]}) srv_msg.send_ctrl_cmd(cmd, exp_result=0) xyz = _get_server_config(reload_kea=True) assert len(xyz["arguments"]["Dhcp6"]["shared-networks"][0]["subnet6"]) == 1 assert xyz["arguments"]["Dhcp6"]["shared-networks"][0]["subnet6"][0]["subnet"] == "2001:db8:3::/64" # this time we expect address from "all" get_address(mac_addr='00:00:00:00:00:05', exp_addr='2001:db8:3::5')
def run_around_tests(): setup_server_for_config_backend_cmds( config_control={"config-fetch-wait-time": 1}, force_reload=False) cmd = dict(command="remote-server6-set", arguments={ "remote": { "type": "mysql" }, "servers": [{ "server-tag": "abc" }] }) srv_msg.send_ctrl_cmd(cmd, exp_result=0)
def test_stress_1(iters_factor, dhcp_version): iterations = 1 * iters_factor for idx in range(iterations): name = 'ipxe-%d' % idx if dhcp_version == 'v4': cmd = dict(command='class-add', arguments={ "client-classes": [{ "name": name, "test": "option[93].hex == 0x0009", "next-server": "192.0.2.254", "server-hostname": "hal9000", "boot-file-name": "/dev/null" }] }) else: cmd = dict(command='class-add', arguments={ "client-classes": [{ "name": name, "test": "option[93].hex == 0x0009" }] }) response = srv_msg.send_ctrl_cmd(cmd) assert response == {'result': 0, 'text': "Class '%s' added" % name} cmd = dict(command='class-update', arguments={"client-classes": [{ "name": name }]}) response = srv_msg.send_ctrl_cmd(cmd) assert response == {'result': 0, 'text': "Class '%s' updated" % name} cmd = dict(command='class-list') response = srv_msg.send_ctrl_cmd(cmd) assert len(response['arguments']['client-classes']) == idx + 1 for idx in range(iterations): name = 'ipxe-%d' % idx cmd = dict(command='class-del', arguments=dict(name=name)) response = srv_msg.send_ctrl_cmd(cmd) assert response == {'result': 0, 'text': "Class '%s' deleted" % name} cmd = dict(command='class-list') response = srv_msg.send_ctrl_cmd(cmd, exp_result=3) assert len( response['arguments']['client-classes']) == iterations - idx - 1
def test_negative_wrong_command_2(dhcp_version): # pylint: disable=unused-argument cmd = dict(command='class-wrong', arguments={"client-classes": [{ "name": "ipxe" }]}) response = srv_msg.send_ctrl_cmd(cmd, exp_result=2) assert response['text'] == "'class-wrong' command not supported."
def test_negative_missing_dependency(dhcp_version): if dhcp_version == 'v4': cmd = dict(command='class-add', arguments={ "client-classes": [{ "name": "ipxe_efi_x64", "test": "member('missing_class')", "next-server": "192.0.2.254", "server-hostname": "hal9000", "boot-file-name": "/dev/null" }] }) else: cmd = dict(command='class-add', arguments={ "client-classes": [{ "name": "ipxe_efi_x64", "test": "member('missing_class')" }] }) response = srv_msg.send_ctrl_cmd(cmd, exp_result=1) assert re.search( r"expression: \[member\('missing_class'\)\] error: <string>:1.8-22: " r"Not defined client class 'missing_class' at \(<wire>:0:\d+\)", response['text'])
def test_negative_redundant_args_in_other(class_cmd, dhcp_version): # pylint: disable=unused-argument # bug: #253, FIXED # bug: #432, FIXED cmd = dict(command=class_cmd, arguments=dict(name='voip'), extra_arg={}) response = srv_msg.send_ctrl_cmd(cmd, exp_result=1) expected = "Error during command processing: Received command contains unsupported parameter 'extra_arg'" assert response['text'] == expected
def _optdef_set(server_tags, exp_result=0, opt_code=222, opt_name="foo", opt_type="uint32"): cmd = dict(command="remote-option-def6-set", arguments={ "remote": { "type": "mysql" }, "server-tags": server_tags, "option-defs": [{ "name": opt_name, "code": opt_code, "type": opt_type }] }) response = srv_msg.send_ctrl_cmd(cmd, exp_result=exp_result) assert response == { "arguments": { "option-defs": [{ "code": opt_code, "space": "dhcp6" }] }, "result": 0, "text": "DHCPv6 option definition successfully set." }
def _subnet_set(): cmd = dict(command="remote-subnet6-set", arguments={ "remote": { "type": "mysql" }, "server-tags": ["abc"], "subnets": [{ "subnet": "2001:db8:1::/64", "id": 5, "interface": "$(SERVER_IFACE)", "shared-network-name": "", "pools": [{ "pool": "2001:db8:1::1-2001:db8:1::10" }] }] }) response = srv_msg.send_ctrl_cmd(cmd) assert response == { "arguments": { "subnets": [{ "id": 5, "subnet": "2001:db8:1::/64" }] }, "result": 0, "text": "IPv6 subnet successfully set." }
def test_subnet_in_network_option(): _set_network() cmd = dict(command="remote-subnet6-set", arguments={ "remote": { "type": "mysql" }, "server-tags": ["abc"], "subnets": [{ "subnet": "2001:db8:1::/64", "id": 5, "interface": "$(SERVER_IFACE)", "shared-network-name": "floor13", "pools": [{ "pool": "2001:db8:1::1-2001:db8:1::10" }] }] }) srv_msg.send_ctrl_cmd(cmd, exp_result=0) cmd = dict(command="remote-option6-subnet-set", arguments={ "subnets": [{ "id": 5 }], "options": [{ "always-send": False, "code": 23, "csv-format": True, "data": "2001:db8:1::1", "name": "dns-servers", "space": "dhcp6" }], "remote": { "type": "mysql" } }) srv_msg.send_ctrl_cmd(cmd, exp_result=0) srv_msg.forge_sleep(2, "seconds") cfg = _get_server_config() assert cfg["arguments"]["Dhcp6"]["shared-networks"][0]["subnet6"][0][ "option-data"] == cmd["arguments"]["options"]
def test_pool_option(): _subnet_set() cmd = dict(command="remote-option6-pool-set", arguments={ "pools": [{ "pool": "2001:db8:1::1-2001:db8:1::10" }], "options": [{ "always-send": False, "code": 23, "csv-format": True, "data": "2001:db8:1::1", "name": "dns-servers", "space": "dhcp6" }], "remote": { "type": "mysql" } }) srv_msg.send_ctrl_cmd(cmd, exp_result=0) srv_msg.forge_sleep(3, "seconds") cfg = _get_server_config() assert cfg["arguments"]["Dhcp6"]["subnet6"][0]["pools"][0][ "option-data"] == cmd["arguments"]["options"] cmd = dict(command="remote-option6-pool-del", arguments={ "pools": [{ "pool": "2001:db8:1::1-2001:db8:1::10" }], "options": [{ "code": 23, "space": "dhcp6" }], "remote": { "type": "mysql" } }) srv_msg.send_ctrl_cmd(cmd, exp_result=0) srv_msg.forge_sleep(4, "seconds") cfg = _get_server_config() assert cfg["arguments"]["Dhcp6"]["subnet6"][0]["pools"][0][ "option-data"] == []
def test_negative_wrong_args_3a(class_cmd, dhcp_version): # pylint: disable=unused-argument cmd = dict(command=class_cmd, arguments={"client-classes": { "name": "ipxe" }}) response = srv_msg.send_ctrl_cmd(cmd, exp_result=1) assert response[ 'text'] == "'client-classes' argument specified for the '%s' command is not a list" % class_cmd
def test_negative_wrong_args_2a(class_cmd, dhcp_version): # pylint: disable=unused-argument cmd = dict(command=class_cmd, arguments={"client-classes-wrong": [{ "name": "ipxe" }]}) response = srv_msg.send_ctrl_cmd(cmd, exp_result=1) assert response[ 'text'] == "missing 'client-classes' argument for the '%s' command" % class_cmd
def test_negative_wrong_args_1(class_cmd, dhcp_version): # pylint: disable=unused-argument cmd = dict(command=class_cmd, wrong_arg={"client-classes": [{ "name": "ipxe" }]}) response = srv_msg.send_ctrl_cmd(cmd, exp_result=1) expected = "Error during command processing: Received command contains unsupported parameter 'wrong_arg'" assert response['text'] == expected
def test_negative_wrong_args_6b(class_cmd, dhcp_version): # pylint: disable=unused-argument cmd = dict(command=class_cmd, arguments={ "name": "ipxe-1", "extra-wrong": 1 }) response = srv_msg.send_ctrl_cmd(cmd, exp_result=1) expected = "invalid number of arguments 2 for the '%s' command. Expecting 'name' string" % class_cmd assert response['text'] == expected
def _send_cmd(cmd, arg): if "remote" not in arg: arg.update({"remote": {"type": "mysql"}}) if "get" not in cmd: if "server-tags" not in arg: arg.update({"server-tags": ["abc"]}) cmd = dict(command=cmd, arguments=arg) return srv_msg.send_ctrl_cmd(cmd, exp_result=0)
def send_cmd(cmd, db_type='mysql', server_tags=None, **kwargs): if server_tags is None: server_tags = ["all"] cmd = {"command": cmd, "arguments": {"remote": {"type": db_type}}} if server_tags != "forbidden": cmd['arguments']['server-tags'] = server_tags cmd['arguments'].update(kwargs) response = srv_msg.send_ctrl_cmd(cmd) return response
def test_negative_break_dependency(dhcp_version): # add new class ipxe if dhcp_version == 'v4': cls = { 'boot-file-name': '/dev/null', 'name': 'voip', 'next-server': '192.0.2.254', 'option-data': [], 'option-def': [], 'server-hostname': 'hal9000', 'test': "option[93].hex == 0x0009" } else: cls = {'name': 'voip', 'test': "option[93].hex == 0x0009"} cmd = dict(command='class-add', arguments={"client-classes": [cls]}) response = srv_msg.send_ctrl_cmd(cmd) assert response == {'result': 0, 'text': "Class 'voip' added"} # add second class that refers voip class if dhcp_version == 'v4': cmd = dict(command='class-add', arguments={ "client-classes": [{ "name": "ipxe_efi_x64", "test": "member('voip')", "next-server": "192.0.2.254", "server-hostname": "hal9000", "boot-file-name": "/dev/null" }] }) else: cmd = dict(command='class-add', arguments={ "client-classes": [{ "name": "ipxe_efi_x64", "test": "member('voip')" }] }) response = srv_msg.send_ctrl_cmd(cmd) assert response == {'result': 0, 'text': "Class 'ipxe_efi_x64' added"} cmd = dict(command='class-del', arguments=dict(name='voip')) response = srv_msg.send_ctrl_cmd(cmd, exp_result=1) assert response['text'] == "Class 'voip' is used by class 'ipxe_efi_x64'"
def _network_list(command, server_tags, exp_result=0): cmd = dict(command=command, arguments={ "remote": { "type": "mysql" }, "server-tags": server_tags }) return srv_msg.send_ctrl_cmd(cmd, exp_result=exp_result)
def test_negative_add_unknown_field(dhcp_version): # pylint: disable=unused-argument # bug: #229, FIXED cmd = dict( command='class-add', arguments={"client-classes": [{ "name": 'ipxe', "unknown": "123" }]}) response = srv_msg.send_ctrl_cmd(cmd, exp_result=1) assert response['text'] == "unsupported client class parameter 'unknown'"
def test_negative_wrong_command_1(dhcp_version): # pylint: disable=unused-argument # bug: #432, FIXED cmd = dict(wrong_command='class-add', arguments={"client-classes": [{ "name": "ipxe" }]}) response = srv_msg.send_ctrl_cmd(cmd, exp_result=1) expected = ("Error during command processing: Invalid answer specified, " "does not contain mandatory 'command'") assert response['text'] == expected
def test_negative_update_wrong_args(dhcp_version): # pylint: disable=unused-argument cmd = dict(command='class-update', arguments={"client-classes": [{ 'name': 'missing-name' }]}) response = srv_msg.send_ctrl_cmd(cmd, exp_result=3) assert response == { 'result': 3, 'text': "Class 'missing-name' is not found" }
def _set_server_tag(tag="abc"): cmd = dict(command="remote-server6-set", arguments={ "remote": { "type": "mysql" }, "servers": [{ "server-tag": tag }] }) return srv_msg.send_ctrl_cmd(cmd, exp_result=0)
def test_negative_wrong_args_5(class_cmd, dhcp_version): # pylint: disable=unused-argument cmd = dict( command=class_cmd, arguments={"client-classes": [{ "name": "ipxe-1" }, { "name": "ipxe-2" }]}) response = srv_msg.send_ctrl_cmd(cmd, exp_result=1) expected = "invalid number of classes specified for the '%s' command. Expected one class" % class_cmd assert response['text'] == expected
def test_remote_server_tag_set_missing_servers(): cmd = dict(command="remote-server6-set", arguments={"remote": { "type": "mysql" }}) response = srv_msg.send_ctrl_cmd(cmd, exp_result=1) assert response == { "result": 1, "text": "'servers' parameter must be specified and must be a list" }
def test_negative_redundant_args_in_update(dhcp_version): # pylint: disable=unused-argument # bug: #253, FIXED # bug: #432, FIXED cmd = dict(command='class-update', arguments={"client-classes": [{ "name": "voip" }]}, extra_arg={}) response = srv_msg.send_ctrl_cmd(cmd, exp_result=1) expected = "Error during command processing: Received command contains unsupported parameter 'extra_arg'" assert response['text'] == expected