diff --git a/src/backend/commands/resgroupcmds.c b/src/backend/commands/resgroupcmds.c index 384675edb7f..3b325ba729c 100644 --- a/src/backend/commands/resgroupcmds.c +++ b/src/backend/commands/resgroupcmds.c @@ -1632,17 +1632,21 @@ getCpuSetByRole(const char *cpuset) splitcpuset = (char *)cpuset; else { - char *scpu = first + 1; + char *second = first + 1; /* Get result cpuset by IS_QUERY_DISPATCHER(), on master or segment */ if (IS_QUERY_DISPATCHER()) - splitcpuset = scpu; - else { char *mcpu = (char *)palloc0(sizeof(char) * MaxCpuSetLength); strncpy(mcpu, cpuset, first - cpuset); splitcpuset = mcpu; } + else + { + char *scpu = (char *)palloc0(sizeof(char) * MaxCpuSetLength); + strlcpy(scpu, second, MaxCpuSetLength); + splitcpuset = scpu; + } } return splitcpuset; diff --git a/src/backend/commands/test/Makefile b/src/backend/commands/test/Makefile index 83bd803a23a..5ef9fed8894 100644 --- a/src/backend/commands/test/Makefile +++ b/src/backend/commands/test/Makefile @@ -2,7 +2,7 @@ subdir=src/backend/commands top_builddir=../../../.. include $(top_builddir)/src/Makefile.global -TARGETS=tablecmds +TARGETS=tablecmds resgroupcmds include $(top_srcdir)/src/backend/mock.mk @@ -10,3 +10,6 @@ tablecmds.t: \ $(MOCK_DIR)/backend/access/aocs/aocs_compaction_mock.o \ $(MOCK_DIR)/backend/access/hash/hash_mock.o \ $(MOCK_DIR)/backend/utils/fmgr/fmgr_mock.o + +resgroupcmds.t: \ + $(MOCK_DIR)/backend/utils/fmgr/fmgr_mock.o diff --git a/src/backend/commands/test/resgroupcmds_test.c b/src/backend/commands/test/resgroupcmds_test.c new file mode 100644 index 00000000000..2e7250104e4 --- /dev/null +++ b/src/backend/commands/test/resgroupcmds_test.c @@ -0,0 +1,135 @@ +/*------------------------------------------------------------------------- + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + * resgroupcmds_test.c + * + * IDENTIFICATION + * src/backend/commands/test/resgroupcmds_test.c + * + *------------------------------------------------------------------------- + */ + +#include +#include +#include +#include "cmockery.h" + +#include "../resgroupcmds.c" + +/* + * Helper: simulate running on the coordinator (dispatcher). + */ +static void +set_role_coordinator(void) +{ + GpIdentity.segindex = MASTER_CONTENT_ID; +} + +/* + * Helper: simulate running on a segment. + */ +static void +set_role_segment(void) +{ + GpIdentity.segindex = 0; +} + +/* + * NULL input must raise an ERROR. + */ +static void +test__getCpuSetByRole_null_input(void **state) +{ + PG_TRY(); + { + getCpuSetByRole(NULL); + fail_msg("expected ereport(ERROR) for NULL cpuset"); + } + PG_CATCH(); + { + FlushErrorState(); + } + PG_END_TRY(); +} + +/* + * cpuset without a separator: same value must be returned + * regardless of the role. + */ +static void +test__getCpuSetByRole_no_separator(void **state) +{ + const char *input = "0-7"; + char *result; + + set_role_coordinator(); + result = getCpuSetByRole(input); + assert_string_equal(result, "0-7"); + + set_role_segment(); + result = getCpuSetByRole(input); + assert_string_equal(result, "0-7"); +} + +/* + * cpuset with a separator, called as coordinator: + * must return the part BEFORE the ';'. + */ +static void +test__getCpuSetByRole_with_separator_as_coordinator(void **state) +{ + const char *input = "0-7;0-15"; + char *result; + + set_role_coordinator(); + result = getCpuSetByRole(input); + assert_string_equal(result, "0-7"); +} + +/* + * cpuset with a separator, called as segment: + * must return the part AFTER the ';'. + */ +static void +test__getCpuSetByRole_with_separator_as_segment(void **state) +{ + const char *input = "0-7;0-15"; + char *result; + + set_role_segment(); + result = getCpuSetByRole(input); + assert_string_equal(result, "0-15"); +} + +int +main(int argc, char *argv[]) +{ + cmockery_parse_arguments(argc, argv); + + const UnitTest tests[] = { + unit_test(test__getCpuSetByRole_null_input), + unit_test(test__getCpuSetByRole_no_separator), + unit_test(test__getCpuSetByRole_with_separator_as_coordinator), + unit_test(test__getCpuSetByRole_with_separator_as_segment) + }; + + MemoryContextInit(); + + return run_tests(tests); +}