blob: b97cef5abaee553eaf6f8994a1b09e8e2de03774 [file] [log] [blame]
/*
* 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.
*/
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include "cmockery.h"
#include "c.h"
#include "../pxfuriparser.c"
/*
* Test parsing of valid uri as given in LOCATION in a PXF external table.
*/
void
test__parseGPHDUri__ValidURI(void **state)
{
char* uri = "pxf://1.2.3.4:5678/some/path/and/table.tbl?FRAGMENTER=SomeFragmenter&ACCESSOR=SomeAccessor&RESOLVER=SomeResolver&ANALYZER=SomeAnalyzer";
List* options = NIL;
ListCell* cell = NULL;
OptionData* option = NULL;
GPHDUri* parsed = parseGPHDUri(uri);
assert_true(parsed != NULL);
assert_string_equal(parsed->uri, uri);
assert_string_equal(parsed->protocol, "pxf");
assert_string_equal(parsed->host, "1.2.3.4");
assert_string_equal(parsed->port, "5678");
assert_true(parsed->ha_nodes == NULL);
assert_string_equal(parsed->data, "some/path/and/table.tbl");
options = parsed->options;
assert_int_equal(list_length(options), 4);
cell = list_nth_cell(options, 0);
option = lfirst(cell);
assert_string_equal(option->key, "FRAGMENTER");
assert_string_equal(option->value, "SomeFragmenter");
cell = list_nth_cell(options, 1);
option = lfirst(cell);
assert_string_equal(option->key, "ACCESSOR");
assert_string_equal(option->value, "SomeAccessor");
cell = list_nth_cell(options, 2);
option = lfirst(cell);
assert_string_equal(option->key, "RESOLVER");
assert_string_equal(option->value, "SomeResolver");
cell = list_nth_cell(options, 3);
option = lfirst(cell);
assert_string_equal(option->key, "ANALYZER");
assert_string_equal(option->value, "SomeAnalyzer");
assert_true(parsed->fragments == NULL);
freeGPHDUri(parsed);
}
/*
* Test parsing of valid uri with with nameservice instead of host and port
* as given in LOCATION in a PXF external table.
*/
void
test__parseGPHDUri__ValidURI_HA(void **state)
{
char* uri = "pxf://hanameservice/some/path/and/table.tbl?FRAGMENTER=SomeFragmenter&ACCESSOR=SomeAccessor&RESOLVER=SomeResolver&ANALYZER=SomeAnalyzer";
List* options = NIL;
ListCell* cell = NULL;
OptionData* option = NULL;
/* mock GPHD_HA_load_nodes */
NNHAConf* ha_conf = (NNHAConf *)palloc0(sizeof(NNHAConf));
ha_conf->nameservice = "hanameservice";
ha_conf->numn = 2;
ha_conf->nodes = ((char**)palloc0(sizeof(char*) * 2));
ha_conf->nodes[0] = "node1";
ha_conf->restports = ((char**)palloc0(sizeof(char*) * 2));
ha_conf->restports[0] = "1001";
expect_string(GPHD_HA_load_nodes, nameservice, "hanameservice");
will_return(GPHD_HA_load_nodes, ha_conf);
/* mock GPHD_HA_release_nodes */
expect_value(GPHD_HA_release_nodes, conf, ha_conf);
will_be_called(GPHD_HA_release_nodes);
GPHDUri* parsed = parseGPHDUri(uri);
assert_true(parsed != NULL);
assert_string_equal(parsed->uri, uri);
assert_string_equal(parsed->protocol, "pxf");
assert_string_equal(parsed->host, "node1"); /* value should be taken from ha_nodes */
assert_string_equal(parsed->port, "1001"); /* it should be taken from ha_nodes */
assert_false(parsed->ha_nodes == NULL);
assert_string_equal(parsed->data, "some/path/and/table.tbl");
freeGPHDUri(parsed);
/* free NNHAConf */
if (ha_conf)
{
pfree(ha_conf->nodes);
pfree(ha_conf->restports);
pfree(ha_conf);
}
}
/*
* Test parsing of valid uri as given in LOCATION in a PXF external table,
* with pxf_isilon set to true.
*/
void
test__parseGPHDUri__ValidURI_Isilon(void **state)
{
char* uri = "pxf://servername:5000/some/path/and/table.tbl?FRAGMENTER=SomeFragmenter&ACCESSOR=SomeAccessor&RESOLVER=SomeResolver&ANALYZER=SomeAnalyzer";
List* options = NIL;
ListCell* cell = NULL;
OptionData* option = NULL;
/* set pxf_isilon to true */
pxf_isilon = true;
GPHDUri* parsed = parseGPHDUri(uri);
assert_true(parsed != NULL);
assert_string_equal(parsed->uri, uri);
assert_string_equal(parsed->protocol, "pxf");
assert_string_equal(parsed->host, "servername");
assert_int_equal(atoi(parsed->port), pxf_service_port); /* it should be pxf_service_port */
assert_true(parsed->ha_nodes == NULL);
assert_string_equal(parsed->data, "some/path/and/table.tbl");
freeGPHDUri(parsed);
/* set pxf_isilon back to false */
pxf_isilon = false;
}
/*
* Negative test: parsing of uri without protocol delimiter "://"
*/
void
test__parseGPHDUri__NegativeTestNoProtocol(void **state)
{
char* uri_no_protocol = "pxf:/1.2.3.4:5678/some/path/and/table.tbl?FRAGMENTER=HdfsDataFragmenter";
/* Setting the test -- code omitted -- */
PG_TRY();
{
/* This will throw a ereport(ERROR).*/
GPHDUri* parsed = parseGPHDUri(uri_no_protocol);
}
PG_CATCH();
{
CurrentMemoryContext = 1;
ErrorData *edata = CopyErrorData();
/*Validate the type of expected error */
assert_true(edata->sqlerrcode == ERRCODE_SYNTAX_ERROR);
assert_true(edata->elevel == ERROR);
assert_string_equal(edata->message, "Invalid URI pxf:/1.2.3.4:5678/some/path/and/table.tbl?FRAGMENTER=HdfsDataFragmenter");
return;
}
PG_END_TRY();
assert_true(false);
}
/*
* Negative test: parsing of uri without options part
*/
void
test__parseGPHDUri__NegativeTestNoOptions(void **state)
{
char* uri_no_options = "pxf://1.2.3.4:5678/some/path/and/table.tbl";
/* Setting the test -- code omitted -- */
PG_TRY();
{
/* This will throw a ereport(ERROR).*/
GPHDUri* parsed = parseGPHDUri(uri_no_options);
}
PG_CATCH();
{
CurrentMemoryContext = 1;
ErrorData *edata = CopyErrorData();
/*Validate the type of expected error */
assert_true(edata->sqlerrcode == ERRCODE_SYNTAX_ERROR);
assert_true(edata->elevel == ERROR);
assert_string_equal(edata->message, "Invalid URI pxf://1.2.3.4:5678/some/path/and/table.tbl: missing options section");
return;
}
PG_END_TRY();
assert_true(false);
}
/*
* Negative test: parsing of a uri with a missing equal
*/
void
test__parseGPHDUri__NegativeTestMissingEqual(void **state)
{
char* uri_missing_equal = "pxf://1.2.3.4:5678/some/path/and/table.tbl?FRAGMENTER";
/* Setting the test -- code omitted -- */
PG_TRY();
{
/* This will throw a ereport(ERROR).*/
GPHDUri* parsed = parseGPHDUri(uri_missing_equal);
}
PG_CATCH();
{
CurrentMemoryContext = 1;
ErrorData *edata = CopyErrorData();
/*Validate the type of expected error */
assert_true(edata->sqlerrcode == ERRCODE_SYNTAX_ERROR);
assert_true(edata->elevel == ERROR);
assert_string_equal(edata->message, "Invalid URI pxf://1.2.3.4:5678/some/path/and/table.tbl?FRAGMENTER: option 'FRAGMENTER' missing '='");
return;
}
PG_END_TRY();
assert_true(false);
}
/*
* Negative test: parsing of a uri with duplicate equals
*/
void
test__parseGPHDUri__NegativeTestDuplicateEquals(void **state)
{
char* uri_duplicate_equals = "pxf://1.2.3.4:5678/some/path/and/table.tbl?FRAGMENTER=HdfsDataFragmenter=DuplicateFragmenter";
/* Setting the test -- code omitted -- */
PG_TRY();
{
/* This will throw a ereport(ERROR).*/
GPHDUri* parsed = parseGPHDUri(uri_duplicate_equals);
}
PG_CATCH();
{
CurrentMemoryContext = 1;
ErrorData *edata = CopyErrorData();
/*Validate the type of expected error */
assert_true(edata->sqlerrcode == ERRCODE_SYNTAX_ERROR);
assert_true(edata->elevel == ERROR);
assert_string_equal(edata->message, "Invalid URI pxf://1.2.3.4:5678/some/path/and/table.tbl?FRAGMENTER=HdfsDataFragmenter=DuplicateFragmenter: option 'FRAGMENTER=HdfsDataFragmenter=DuplicateFragmenter' contains duplicate '='");
return;
}
PG_END_TRY();
assert_true(false);
}
/*
* Negative test: parsing of a uri with a missing key
*/
void
test__parseGPHDUri__NegativeTestMissingKey(void **state)
{
char* uri_missing_key = "pxf://1.2.3.4:5678/some/path/and/table.tbl?=HdfsDataFragmenter";
/* Setting the test -- code omitted -- */
PG_TRY();
{
/* This will throw a ereport(ERROR).*/
GPHDUri* parsed = parseGPHDUri(uri_missing_key);
}
PG_CATCH();
{
CurrentMemoryContext = 1;
ErrorData *edata = CopyErrorData();
/*Validate the type of expected error */
assert_true(edata->sqlerrcode == ERRCODE_SYNTAX_ERROR);
assert_true(edata->elevel == ERROR);
assert_string_equal(edata->message, "Invalid URI pxf://1.2.3.4:5678/some/path/and/table.tbl?=HdfsDataFragmenter: option '=HdfsDataFragmenter' missing key before '='");
return;
}
PG_END_TRY();
assert_true(false);
}
/*
* Negative test: parsing of a uri with a missing value
*/
void
test__parseGPHDUri__NegativeTestMissingValue(void **state)
{
char* uri_missing_value = "pxf://1.2.3.4:5678/some/path/and/table.tbl?FRAGMENTER=";
/* Setting the test -- code omitted -- */
PG_TRY();
{
/* This will throw a ereport(ERROR).*/
GPHDUri* parsed = parseGPHDUri(uri_missing_value);
}
PG_CATCH();
{
CurrentMemoryContext = 1;
ErrorData *edata = CopyErrorData();
/*Validate the type of expected error */
assert_true(edata->sqlerrcode == ERRCODE_SYNTAX_ERROR);
assert_true(edata->elevel == ERROR);
assert_string_equal(edata->message, "Invalid URI pxf://1.2.3.4:5678/some/path/and/table.tbl?FRAGMENTER=: option 'FRAGMENTER=' missing value after '='");
return;
}
PG_END_TRY();
assert_true(false);
}
/*
* Test GPHDUri_verify_no_duplicate_options: valid uri
*/
void
test__GPHDUri_verify_no_duplicate_options__ValidURI(void **state)
{
char* valid_uri = "pxf://1.2.3.4:5678/some/path/and/table.tbl?Profile=a&Analyzer=b";
/* Setting the test -- code omitted -- */
GPHDUri* parsed = parseGPHDUri(valid_uri);
GPHDUri_verify_no_duplicate_options(parsed);
freeGPHDUri(parsed);
}
/*
* Negative test of GPHDUri_verify_no_duplicate_options: parsing of a uri with duplicate options
*/
void
test__GPHDUri_verify_no_duplicate_options__NegativeTestDuplicateOpts(void **state)
{
char* uri_duplicate_opts = "pxf://1.2.3.4:5678/some/path/and/table.tbl?Profile=a&Analyzer=b&PROFILE=c";
/* Setting the test -- code omitted -- */
PG_TRY();
{
GPHDUri* parsed = parseGPHDUri(uri_duplicate_opts);
/* This will throw a ereport(ERROR).*/
GPHDUri_verify_no_duplicate_options(parsed);
}
PG_CATCH();
{
CurrentMemoryContext = 1;
ErrorData *edata = CopyErrorData();
/*Validate the type of expected error */
assert_true(edata->sqlerrcode == ERRCODE_SYNTAX_ERROR);
assert_true(edata->elevel == ERROR);
assert_string_equal(edata->message, "Invalid URI pxf://1.2.3.4:5678/some/path/and/table.tbl?Profile=a&Analyzer=b&PROFILE=c: Duplicate option(s): PROFILE");
return;
}
PG_END_TRY();
assert_true(false);
}
/*
* Test GPHDUri_verify_core_options_exist with a valid uri
*/
void
test__GPHDUri_verify_core_options_exist__ValidURI(void **state)
{
char* valid_uri = "pxf://1.2.3.4:5678/some/path/and/table.tbl?Fragmenter=1&Accessor=2&Resolver=3";
/* Setting the test -- code omitted -- */
GPHDUri* parsed = parseGPHDUri(valid_uri);
List *coreOptions = list_make3("FRAGMENTER", "ACCESSOR", "RESOLVER");
GPHDUri_verify_core_options_exist(parsed, coreOptions);
freeGPHDUri(parsed);
list_free(coreOptions);
}
/*
* Negative test of GPHDUri_verify_core_options_exist: Missing core options
*/
void
test__GPHDUri_verify_core_options_exist__NegativeTestMissingCoreOpts(void **state)
{
char* missing_core_opts = "pxf://1.2.3.4:5678/some/path/and/table.tbl?FRAGMENTER=a";
List *coreOptions;
/* Setting the test -- code omitted -- */
PG_TRY();
{
GPHDUri* parsed = parseGPHDUri(missing_core_opts);
coreOptions = list_make3("FRAGMENTER", "ACCESSOR", "RESOLVER");
/* This will throw a ereport(ERROR).*/
GPHDUri_verify_core_options_exist(parsed, coreOptions);
}
PG_CATCH();
{
CurrentMemoryContext = 1;
ErrorData *edata = CopyErrorData();
/*Validate the type of expected error */
assert_true(edata->sqlerrcode == ERRCODE_SYNTAX_ERROR);
assert_true(edata->elevel == ERROR);
assert_string_equal(edata->message, "Invalid URI pxf://1.2.3.4:5678/some/path/and/table.tbl?FRAGMENTER=a: PROFILE or ACCESSOR and RESOLVER option(s) missing");
list_free(coreOptions);
return;
}
PG_END_TRY();
assert_true(false);
}
int
main(int argc, char* argv[])
{
cmockery_parse_arguments(argc, argv);
const UnitTest tests[] = {
unit_test(test__parseGPHDUri__ValidURI),
unit_test(test__parseGPHDUri__ValidURI_HA),
unit_test(test__parseGPHDUri__ValidURI_Isilon),
unit_test(test__parseGPHDUri__NegativeTestNoProtocol),
unit_test(test__parseGPHDUri__NegativeTestNoOptions),
unit_test(test__parseGPHDUri__NegativeTestMissingEqual),
unit_test(test__parseGPHDUri__NegativeTestDuplicateEquals),
unit_test(test__parseGPHDUri__NegativeTestMissingKey),
unit_test(test__parseGPHDUri__NegativeTestMissingValue),
unit_test(test__GPHDUri_verify_no_duplicate_options__ValidURI),
unit_test(test__GPHDUri_verify_no_duplicate_options__NegativeTestDuplicateOpts),
unit_test(test__GPHDUri_verify_core_options_exist__ValidURI),
unit_test(test__GPHDUri_verify_core_options_exist__NegativeTestMissingCoreOpts)
};
return run_tests(tests);
}