Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.89) (envelope-from ) id 1evUnQ-0002rS-TC for pgadmin-hackers@arkaria.postgresql.org; Mon, 12 Mar 2018 21:15:53 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1evUnP-00053I-Ga for pgadmin-hackers@arkaria.postgresql.org; Mon, 12 Mar 2018 21:15:51 +0000 Received: from makus.postgresql.org ([2001:4800:1501:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.89) (envelope-from ) id 1evUnO-000538-OD for pgadmin-hackers@lists.postgresql.org; Mon, 12 Mar 2018 21:15:51 +0000 Received: from mail-io0-x241.google.com ([2607:f8b0:4001:c06::241]) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1evUnJ-0005OC-Dh for pgadmin-hackers@postgresql.org; Mon, 12 Mar 2018 21:15:48 +0000 Received: by mail-io0-x241.google.com with SMTP id h23so13157401iob.11 for ; Mon, 12 Mar 2018 14:15:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pivotal-io.20150623.gappssmtp.com; s=20150623; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=4Vs5JFUIU4abzCkMrFc2jTup2n2TqNcU5S71utAyWNQ=; b=mQpAe7gQU0qLSk2ye6JLMhm8znfXCrVzIZP9klTnljuwm/e7I0QGh4z4jDNlF2IqRX cyfG+XUX/Vo9rYV94csEUTURFB7fBbI5sq5lOiwOnj/911PhPcMr7t8h9ixZBtHRMjCV h3XzmLXOXkfquSg5ygx1X16HGvI48twLZIBBMyEmrDsVGp+SMJlvWPFA2JqGFbmsnmaV 69vBVH+erO+aSzczB2jLJeHGTs7OS1FMQceml5HoX7NlogXgiMUPhckAVbmUMumKmura iRzCSevpnj2y+x5UMc/xk2QQFyPmA+7koqIzkNafdBQiDkpICL3Qitb3SnbULqYih4Pj zj2w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=4Vs5JFUIU4abzCkMrFc2jTup2n2TqNcU5S71utAyWNQ=; b=o0bXHw/YeaCiOsNw1nCmeGPIkvKIXSJ0pig40R/iam6jP17jKy3YMMXPDgx3jvwz63 OPvMQyr9NrNQAPOfiFKfkCy4BC/3VgnLoXQgKsf5PzCOcDtXX7t6cQPhl90AltutXpmo S6SUwKxBkJDMJ3uGYoatasTVZwtVaSqNH1igcGQiV0XWOSMJghieyGYc2kM5Ly5ne6Jy LNvfyBBhs/W5BkxIgU7zl0i0oXGnWPZexzt/Rxf7voGWMQE/JizdMgoXE4oSipKET4+q vC2o5Y320zxxuJlSeAivJ1ZokqcW1YnfhD+YZIkn7/x1NogPM1apU53IHGNDKhrDLPcO ZiSA== X-Gm-Message-State: AElRT7EumG5O5toEo3xvxWcMo/EoXcj6loWIYNAXJar8pgKEXWRrSUOT vC0TFLKhlRRTvwWhHQ2rg8g/1AeXXM4bvD1JqbHWXw== X-Google-Smtp-Source: AG47ELsM0zudkf0T6kuXixGj+FVtNBYOVzFtV0B+237GILTo3JBupWHrOW8fh0ZXsTkZeEIcihlOYU97XVJ3WlcFtaM= X-Received: by 10.107.200.69 with SMTP id y66mr10146582iof.116.1520889343454; Mon, 12 Mar 2018 14:15:43 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Joao De Almeida Pereira Date: Mon, 12 Mar 2018 21:15:32 +0000 Message-ID: Subject: Re: pgAdmin 4 commit: Support for external tables in GPDB. Fixes #3168 To: Murtuza Zabuawala Cc: Neel Patel , pgadmin-hackers , Dave Page Content-Type: multipart/alternative; boundary="94eb2c0b9ace0f719005673da58d" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk --94eb2c0b9ace0f719005673da58d Content-Type: text/plain; charset="UTF-8" Hello Murtuza, Yes I think it makes sense Thanks Joao On Mon, Mar 12, 2018 at 10:40 AM Murtuza Zabuawala < murtuza.zabuawala@enterprisedb.com> wrote: > Hi Joao, > > Can we make tests to skip if db is not greenplum? > Like we are doing for resource group > "..web/pgadmin/browser/server_groups/servers/resource_groups/tests". > > > On Mon, Mar 12, 2018 at 7:52 PM, Murtuza Zabuawala < > murtuza.zabuawala@enterprisedb.com> wrote: > >> Hi Dave, >> >> Joao's patch is pending, would you please do the needful? >> I also encounter similar issue on Windows while running tests. >> >> -- >> Regards, >> Murtuza Zabuawala >> EnterpriseDB: http://www.enterprisedb.com >> The Enterprise PostgreSQL Company >> >> >> On Tue, Mar 6, 2018 at 8:25 PM, Joao De Almeida Pereira < >> jdealmeidapereira@pivotal.io> wrote: >> >>> Hello Neel, >>> >>> You can find attached the corrections of the path's needed for windows. >>> The fix should correct TestExternalTablesView and TestTemplateCreate >>> but for the ChangePasswordTestCase I need more information to help you out. >>> We need to understand what is the response that the endpoint >>> /user_management/user is returning. >>> >>> Thanks >>> Joao >>> >>> On Tue, Mar 6, 2018 at 2:29 AM Neel Patel >>> wrote: >>> >>>> Hi Joao, >>>> >>>> I ran the testsuite in windows 10 with Python 3.4 and it fails for >>>> external tables. Linux it is working fine. Let me know if I miss >>>> anything. >>>> >>>> Please check the below logs. >>>> >>>> python runtests.py --pkg browser --exclude feature_tests >>>> >>>> ######## >>>> >>>> ====================================================================== >>>> ERROR: runTest >>>> (pgadmin.browser.server_groups.servers.databases.schemas.tables.tests.test_template_create.TestTemplateCreate) >>>> When rendering GreenPlum 5.3 template, when no distribution is present, >>>> when no primary key is present, it returns "DISTRIBUTED RANDOMLY" >>>> ---------------------------------------------------------------------- >>>> Traceback (most recent call last): >>>> File >>>> "C:\Projects\pgadmin4\web\pgadmin\browser\server_groups\servers\databases\schemas\tables\tests\test_template_create.py", >>>> line 99, in runTest >>>> self.template_path, **self.input_parameters) >>>> File >>>> "C:\Projects\venv_pgadmin4_py_3_4\lib\site-packages\flask\templating.py", >>>> line 133, in render_template >>>> return >>>> _render(ctx.app.jinja_env.get_or_select_template(template_name_or_list), >>>> File >>>> "C:\Projects\venv_pgadmin4_py_3_4\lib\site-packages\jinja2\environment.py", >>>> line 830, in get_or_select_template >>>> return self.get_template(template_name_or_list, parent, globals) >>>> File >>>> "C:\Projects\venv_pgadmin4_py_3_4\lib\site-packages\jinja2\environment.py", >>>> line 791, in get_template >>>> return self._load_template(name, self.make_globals(globals)) >>>> File >>>> "C:\Projects\venv_pgadmin4_py_3_4\lib\site-packages\jinja2\environment.py", >>>> line 765, in _load_template >>>> template = self.loader.load(self, name, globals) >>>> File >>>> "C:\Projects\venv_pgadmin4_py_3_4\lib\site-packages\jinja2\loaders.py", >>>> line 113, in load >>>> source, filename, uptodate = self.get_source(environment, name) >>>> File >>>> "C:\Projects\venv_pgadmin4_py_3_4\lib\site-packages\flask\templating.py", >>>> line 57, in get_source >>>> return self._get_source_fast(environment, template) >>>> File >>>> "C:\Projects\venv_pgadmin4_py_3_4\lib\site-packages\flask\templating.py", >>>> line 85, in _get_source_fast >>>> raise TemplateNotFound(template) >>>> jinja2.exceptions.TemplateNotFound: table\sql\gpdb_5.0_plus\create.sql >>>> >>>> ====================================================================== >>>> ERROR: runTest >>>> (pgadmin.browser.server_groups.servers.databases.schemas.tables.tests.test_template_create.TestTemplateCreate) >>>> When rendering GreenPlum 5.3 template, when no distribution is present, >>>> when primary key is present, it returns "DISTRIBUTED BY (attr_primary_key)" >>>> ---------------------------------------------------------------------- >>>> Traceback (most recent call last): >>>> File >>>> "C:\Projects\pgadmin4\web\pgadmin\browser\server_groups\servers\databases\schemas\tables\tests\test_template_create.py", >>>> line 99, in runTest >>>> self.template_path, **self.input_parameters) >>>> File >>>> "C:\Projects\venv_pgadmin4_py_3_4\lib\site-packages\flask\templating.py", >>>> line 133, in render_template >>>> return >>>> _render(ctx.app.jinja_env.get_or_select_template(template_name_or_list), >>>> File >>>> "C:\Projects\venv_pgadmin4_py_3_4\lib\site-packages\jinja2\environment.py", >>>> line 830, in get_or_select_template >>>> return self.get_template(template_name_or_list, parent, globals) >>>> File >>>> "C:\Projects\venv_pgadmin4_py_3_4\lib\site-packages\jinja2\environment.py", >>>> line 791, in get_template >>>> return self._load_template(name, self.make_globals(globals)) >>>> File >>>> "C:\Projects\venv_pgadmin4_py_3_4\lib\site-packages\jinja2\environment.py", >>>> line 765, in _load_template >>>> template = self.loader.load(self, name, globals) >>>> File >>>> "C:\Projects\venv_pgadmin4_py_3_4\lib\site-packages\jinja2\loaders.py", >>>> line 113, in load >>>> source, filename, uptodate = self.get_source(environment, name) >>>> File >>>> "C:\Projects\venv_pgadmin4_py_3_4\lib\site-packages\flask\templating.py", >>>> line 57, in get_source >>>> return self._get_source_fast(environment, template) >>>> File >>>> "C:\Projects\venv_pgadmin4_py_3_4\lib\site-packages\flask\templating.py", >>>> line 85, in _get_source_fast >>>> raise TemplateNotFound(template) >>>> jinja2.exceptions.TemplateNotFound: table\sql\gpdb_5.0_plus\create.sql >>>> >>>> ====================================================================== >>>> ERROR: runTest >>>> (pgadmin.browser.server_groups.servers.databases.schemas.tables.tests.test_template_create.TestTemplateCreate) >>>> When rendering GreenPlum 5.3 template, when distribution is present, it >>>> returns "DISTRIBUTED BY (attr1, attr2, attr4)" >>>> ---------------------------------------------------------------------- >>>> Traceback (most recent call last): >>>> File >>>> "C:\Projects\pgadmin4\web\pgadmin\browser\server_groups\servers\databases\schemas\tables\tests\test_template_create.py", >>>> line 99, in runTest >>>> self.template_path, **self.input_parameters) >>>> File >>>> "C:\Projects\venv_pgadmin4_py_3_4\lib\site-packages\flask\templating.py", >>>> line 133, in render_template >>>> return >>>> _render(ctx.app.jinja_env.get_or_select_template(template_name_or_list), >>>> File >>>> "C:\Projects\venv_pgadmin4_py_3_4\lib\site-packages\jinja2\environment.py", >>>> line 830, in get_or_select_template >>>> return self.get_template(template_name_or_list, parent, globals) >>>> File >>>> "C:\Projects\venv_pgadmin4_py_3_4\lib\site-packages\jinja2\environment.py", >>>> line 791, in get_template >>>> return self._load_template(name, self.make_globals(globals)) >>>> File >>>> "C:\Projects\venv_pgadmin4_py_3_4\lib\site-packages\jinja2\environment.py", >>>> line 765, in _load_template >>>> template = self.loader.load(self, name, globals) >>>> File >>>> "C:\Projects\venv_pgadmin4_py_3_4\lib\site-packages\jinja2\loaders.py", >>>> line 113, in load >>>> source, filename, uptodate = self.get_source(environment, name) >>>> File >>>> "C:\Projects\venv_pgadmin4_py_3_4\lib\site-packages\flask\templating.py", >>>> line 57, in get_source >>>> return self._get_source_fast(environment, template) >>>> File >>>> "C:\Projects\venv_pgadmin4_py_3_4\lib\site-packages\flask\templating.py", >>>> line 85, in _get_source_fast >>>> raise TemplateNotFound(template) >>>> jinja2.exceptions.TemplateNotFound: table\sql\gpdb_5.0_plus\create.sql >>>> >>>> ====================================================================== >>>> ERROR: runTest >>>> (pgadmin.browser.tests.test_change_password.ChangePasswordTestCase) >>>> TestCase for Changing Valid_Password >>>> ---------------------------------------------------------------------- >>>> Traceback (most recent call last): >>>> File >>>> "C:\Projects\pgadmin4\web\pgadmin\browser\tests\test_change_password.py", >>>> line 91, in runTest >>>> user_id = json.loads(response.data.decode('utf-8'))['id'] >>>> KeyError: 'id' >>>> >>>> ====================================================================== >>>> FAIL: runTest >>>> (pgadmin.browser.server_groups.servers.databases.external_tables.tests.test_external_tables_view.TestExternalTablesView) >>>> #nodes When retrieving the nodes and the database does not have >>>> external tables, it return no child nodes and status 200 >>>> ---------------------------------------------------------------------- >>>> Traceback (most recent call last): >>>> File "C:\Python34\Lib\unittest\mock.py", line 1142, in patched >>>> return func(*args, **keywargs) >>>> File >>>> "C:\Projects\pgadmin4\web\pgadmin\browser\server_groups\servers\databases\external_tables\tests\test_external_tables_view.py", >>>> line 314, in runTest >>>> self.__test_nodes() >>>> File "C:\Python34\Lib\unittest\mock.py", line 1142, in patched >>>> return func(*args, **keywargs) >>>> File >>>> "C:\Projects\pgadmin4\web\pgadmin\browser\server_groups\servers\databases\external_tables\tests\test_external_tables_view.py", >>>> line 367, in __test_nodes >>>> self.expect_render_template_called_with >>>> File "C:\Python34\Lib\unittest\mock.py", line 777, in >>>> assert_called_with >>>> raise AssertionError(_error_message()) from cause >>>> AssertionError: Expected call: >>>> render_template('sql/#gpdb#80323#/list.sql') >>>> Actual call: render_template('sql/#gpdb#80323#\\list.sql') >>>> >>>> ====================================================================== >>>> FAIL: runTest >>>> (pgadmin.browser.server_groups.servers.databases.external_tables.tests.test_external_tables_view.TestExternalTablesView) >>>> #nodes When retrieving the nodes and an error happens while executing >>>> the query, it return an internal server error and status 500 >>>> ---------------------------------------------------------------------- >>>> Traceback (most recent call last): >>>> File "C:\Python34\Lib\unittest\mock.py", line 1142, in patched >>>> return func(*args, **keywargs) >>>> File >>>> "C:\Projects\pgadmin4\web\pgadmin\browser\server_groups\servers\databases\external_tables\tests\test_external_tables_view.py", >>>> line 314, in runTest >>>> self.__test_nodes() >>>> File "C:\Python34\Lib\unittest\mock.py", line 1142, in patched >>>> return func(*args, **keywargs) >>>> File >>>> "C:\Projects\pgadmin4\web\pgadmin\browser\server_groups\servers\databases\external_tables\tests\test_external_tables_view.py", >>>> line 367, in __test_nodes >>>> self.expect_render_template_called_with >>>> File "C:\Python34\Lib\unittest\mock.py", line 777, in >>>> assert_called_with >>>> raise AssertionError(_error_message()) from cause >>>> AssertionError: Expected call: >>>> render_template('sql/#gpdb#80323#/list.sql') >>>> Actual call: render_template('sql/#gpdb#80323#\\list.sql') >>>> >>>> ====================================================================== >>>> FAIL: runTest >>>> (pgadmin.browser.server_groups.servers.databases.external_tables.tests.test_external_tables_view.TestExternalTablesView) >>>> #nodes When retrieving the nodes and the database has 2 external >>>> tables, it return 2 child nodes and status 200 >>>> ---------------------------------------------------------------------- >>>> Traceback (most recent call last): >>>> File "C:\Python34\Lib\unittest\mock.py", line 1142, in patched >>>> return func(*args, **keywargs) >>>> File >>>> "C:\Projects\pgadmin4\web\pgadmin\browser\server_groups\servers\databases\external_tables\tests\test_external_tables_view.py", >>>> line 314, in runTest >>>> self.__test_nodes() >>>> File "C:\Python34\Lib\unittest\mock.py", line 1142, in patched >>>> return func(*args, **keywargs) >>>> File >>>> "C:\Projects\pgadmin4\web\pgadmin\browser\server_groups\servers\databases\external_tables\tests\test_external_tables_view.py", >>>> line 367, in __test_nodes >>>> self.expect_render_template_called_with >>>> File "C:\Python34\Lib\unittest\mock.py", line 777, in >>>> assert_called_with >>>> raise AssertionError(_error_message()) from cause >>>> AssertionError: Expected call: >>>> render_template('sql/#gpdb#80323#/list.sql') >>>> Actual call: render_template('sql/#gpdb#80323#\\list.sql') >>>> >>>> ====================================================================== >>>> FAIL: runTest >>>> (pgadmin.browser.server_groups.servers.databases.external_tables.tests.test_external_tables_view.TestExternalTablesView) >>>> #node When retrieving the information about 1 external table and an >>>> error happens while executing the query, it return an internal server error >>>> and status 500 >>>> ---------------------------------------------------------------------- >>>> Traceback (most recent call last): >>>> File "C:\Python34\Lib\unittest\mock.py", line 1142, in patched >>>> return func(*args, **keywargs) >>>> File >>>> "C:\Projects\pgadmin4\web\pgadmin\browser\server_groups\servers\databases\external_tables\tests\test_external_tables_view.py", >>>> line 316, in runTest >>>> self.__test_node() >>>> File "C:\Python34\Lib\unittest\mock.py", line 1142, in patched >>>> return func(*args, **keywargs) >>>> File >>>> "C:\Projects\pgadmin4\web\pgadmin\browser\server_groups\servers\databases\external_tables\tests\test_external_tables_view.py", >>>> line 393, in __test_node >>>> **self.expect_render_template_called_with >>>> File "C:\Python34\Lib\unittest\mock.py", line 777, in >>>> assert_called_with >>>> raise AssertionError(_error_message()) from cause >>>> AssertionError: Expected call: render_template(external_table_id=11, >>>> template_name_or_list='sql/#gpdb#80323#/node.sql') >>>> Actual call: render_template(external_table_id=11, >>>> template_name_or_list='sql/#gpdb#80323#\\node.sql') >>>> >>>> ====================================================================== >>>> FAIL: runTest >>>> (pgadmin.browser.server_groups.servers.databases.external_tables.tests.test_external_tables_view.TestExternalTablesView) >>>> #node When retrieving the information about 1 external table and table >>>> does not exist, it return an error message and status 404 >>>> ---------------------------------------------------------------------- >>>> Traceback (most recent call last): >>>> File "C:\Python34\Lib\unittest\mock.py", line 1142, in patched >>>> return func(*args, **keywargs) >>>> File >>>> "C:\Projects\pgadmin4\web\pgadmin\browser\server_groups\servers\databases\external_tables\tests\test_external_tables_view.py", >>>> line 316, in runTest >>>> self.__test_node() >>>> File "C:\Python34\Lib\unittest\mock.py", line 1142, in patched >>>> return func(*args, **keywargs) >>>> File >>>> "C:\Projects\pgadmin4\web\pgadmin\browser\server_groups\servers\databases\external_tables\tests\test_external_tables_view.py", >>>> line 393, in __test_node >>>> **self.expect_render_template_called_with >>>> File "C:\Python34\Lib\unittest\mock.py", line 777, in >>>> assert_called_with >>>> raise AssertionError(_error_message()) from cause >>>> AssertionError: Expected call: render_template(external_table_id=11, >>>> template_name_or_list='sql/#gpdb#80323#/node.sql') >>>> Actual call: render_template(external_table_id=11, >>>> template_name_or_list='sql/#gpdb#80323#\\node.sql') >>>> >>>> ====================================================================== >>>> FAIL: runTest >>>> (pgadmin.browser.server_groups.servers.databases.external_tables.tests.test_external_tables_view.TestExternalTablesView) >>>> #nodes When retrieving the information about 1 external table and the >>>> table exists, it return external node information and status 200 >>>> ---------------------------------------------------------------------- >>>> Traceback (most recent call last): >>>> File "C:\Python34\Lib\unittest\mock.py", line 1142, in patched >>>> return func(*args, **keywargs) >>>> File >>>> "C:\Projects\pgadmin4\web\pgadmin\browser\server_groups\servers\databases\external_tables\tests\test_external_tables_view.py", >>>> line 316, in runTest >>>> self.__test_node() >>>> File "C:\Python34\Lib\unittest\mock.py", line 1142, in patched >>>> return func(*args, **keywargs) >>>> File >>>> "C:\Projects\pgadmin4\web\pgadmin\browser\server_groups\servers\databases\external_tables\tests\test_external_tables_view.py", >>>> line 393, in __test_node >>>> **self.expect_render_template_called_with >>>> File "C:\Python34\Lib\unittest\mock.py", line 777, in >>>> assert_called_with >>>> raise AssertionError(_error_message()) from cause >>>> AssertionError: Expected call: render_template(external_table_id=11, >>>> template_name_or_list='sql/#gpdb#80323#/node.sql') >>>> Actual call: render_template(external_table_id=11, >>>> template_name_or_list='sql/#gpdb#80323#\\node.sql') >>>> >>>> ====================================================================== >>>> FAIL: runTest >>>> (pgadmin.browser.server_groups.servers.databases.external_tables.tests.test_external_tables_view.TestExternalTablesView) >>>> #properties When retrieving the properties of a external table and the >>>> table exists, it return the properties and status 200 >>>> ---------------------------------------------------------------------- >>>> Traceback (most recent call last): >>>> File "C:\Python34\Lib\unittest\mock.py", line 1142, in patched >>>> return func(*args, **keywargs) >>>> File >>>> "C:\Projects\pgadmin4\web\pgadmin\browser\server_groups\servers\databases\external_tables\tests\test_external_tables_view.py", >>>> line 320, in runTest >>>> self.__test_properties() >>>> File "C:\Python34\Lib\unittest\mock.py", line 1142, in patched >>>> return func(*args, **keywargs) >>>> File >>>> "C:\Projects\pgadmin4\web\pgadmin\browser\server_groups\servers\databases\external_tables\tests\test_external_tables_view.py", >>>> line 419, in __test_properties >>>> **self.expect_render_template_called_with >>>> File "C:\Python34\Lib\unittest\mock.py", line 777, in >>>> assert_called_with >>>> raise AssertionError(_error_message()) from cause >>>> AssertionError: Expected call: >>>> render_template(template_name_or_list='sql/#gpdb#80323#/get_table_information.sql', >>>> table_oid=11) >>>> Actual call: >>>> render_template(template_name_or_list='sql/#gpdb#80323#\\get_table_information.sql', >>>> table_oid=11) >>>> >>>> ---------------------------------------------------------------------- >>>> Ran 256 tests in 77.123s >>>> >>>> FAILED (failures=7, errors=4, skipped=25) >>>> >>>> ====================================================================== >>>> Test Result Summary >>>> ====================================================================== >>>> >>>> PostgreSQL 9.6: >>>> >>>> 234 tests passed >>>> 3 tests failed: >>>> TestExternalTablesView (#node When retrieving the >>>> information about 1 external table and table does not exist, it return an >>>> error message and status 404, >>>> #node When retrieving the >>>> information about 1 external table and an error happens while executing the >>>> query, it return an internal server error and status 500, >>>> #nodes When retrieving the >>>> nodes and the database has 2 external tables, it return 2 child nodes and >>>> status 200, >>>> #nodes When retrieving the >>>> information about 1 external table and the table exists, it return external >>>> node information and status 200, >>>> #nodes When retrieving the >>>> nodes and an error happens while executing the query, it return an internal >>>> server error and status 500, >>>> #properties When retrieving the >>>> properties of a external table and the table exists, it return the >>>> properties and status 200, >>>> #nodes When retrieving the >>>> nodes and the database does not have external tables, it return no child >>>> nodes and status 200) >>>> ChangePasswordTestCase (TestCase for Changing >>>> Valid_Password) >>>> TestTemplateCreate (When rendering GreenPlum 5.3 >>>> template, when no distribution is present, when no primary key is present, >>>> it returns "DISTRIBUTED RANDOMLY", >>>> When rendering GreenPlum 5.3 >>>> template, when distribution is present, it returns "DISTRIBUTED BY (attr1, >>>> attr2, attr4)", >>>> When rendering GreenPlum 5.3 >>>> template, when no distribution is present, when primary key is present, it >>>> returns "DISTRIBUTED BY (attr_primary_key)") >>>> 19 tests skipped: >>>> ResourceGroupsGetTestCase (Get resource groups) >>>> TableSpaceDeleteTestCase (Check Tablespace Node) >>>> ResourceGroupsDeleteTestCase (Delete resource groups) >>>> SynonymDeleteTestCase (Fetch synonym Node URL) >>>> TestSSLConnection (Test for SSL connection) >>>> PackageAddTestCase (Fetch Package Node URL) >>>> SynonymPutTestCase (Fetch synonym Node URL) >>>> TablespaceGetTestCase (Check Tablespace Node) >>>> SynonymAddTestCase (Default Node URL) >>>> PackagePutTestCase (Fetch Package Node URL) >>>> TableAddTestCase (Create Range partitioned table with 2 >>>> partitions, >>>> Create List partitioned table >>>> with 2 partitions) >>>> PackageGetTestCase (Fetch Package Node URL) >>>> PackageDeleteTestCase (Fetch Package Node URL) >>>> TableSpaceAddTestCase (Check Tablespace Node) >>>> ResourceGroupsAddTestCase (Add resource groups) >>>> SynonymGetTestCase (Fetch synonym Node URL) >>>> ResourceGroupsPutTestCase (Put resource groups) >>>> TableSpaceUpdateTestCase (Check Tablespace Node) >>>> TableUpdateTestCase (Attach partition to existing range >>>> partitioned table, >>>> Detach partition from existing >>>> range partitioned table, >>>> Create partitions of existing >>>> range partitioned table, >>>> Detach partition from existing >>>> list partitioned table, >>>> Create partitions of existing >>>> list partitioned table, >>>> Attach partition to existing >>>> list partitioned table) >>>> >>>> ====================================================================== >>>> >>>> ######## >>>> >>>> >>>> Thanks, >>>> Neel Patel >>>> >>>> On Fri, Mar 2, 2018 at 10:19 PM, Dave Page wrote: >>>> >>>>> Support for external tables in GPDB. Fixes #3168 >>>>> >>>>> Branch >>>>> ------ >>>>> master >>>>> >>>>> Details >>>>> ------- >>>>> >>>>> https://git.postgresql.org/gitweb?p=pgadmin4.git;a=commitdiff;h=427314cfdfeb96c3a7835eab5a4d638903bc6dc3 >>>>> Author: Joao Pedro De Almeida Pereira >>>>> >>>>> Modified Files >>>>> -------------- >>>>> .../servers/databases/external_tables/__init__.py | 275 +++++++++++++ >>>>> .../databases/external_tables/actions/__init__.py | 0 >>>>> .../external_tables/actions/get_all_nodes.py | 4 + >>>>> .../databases/external_tables/mapping_utils.py | 165 ++++++++ >>>>> .../databases/external_tables/properties.py | 78 ++++ >>>>> .../external_tables/reverse_engineer_ddl.py | 69 ++++ >>>>> .../static/img/coll-external_table.svg | 1 + >>>>> .../external_tables/static/img/external_table.svg | 1 + >>>>> .../templates/sql/gpdb_5.0_plus/create.sql | 60 +++ >>>>> .../templates/sql/gpdb_5.0_plus/get_columns.sql | 12 + >>>>> .../sql/gpdb_5.0_plus/get_table_information.sql | 22 ++ >>>>> .../templates/sql/gpdb_5.0_plus/list.sql | 6 + >>>>> .../templates/sql/gpdb_5.0_plus/node.sql | 5 + >>>>> .../databases/external_tables/tests/__init__.py | 0 >>>>> .../tests/test_external_tables_module.py | 99 +++++ >>>>> .../tests/test_external_tables_view.py | 428 >>>>> +++++++++++++++++++++ >>>>> .../external_tables/tests/test_mapping_utils.py | 375 >>>>> ++++++++++++++++++ >>>>> .../external_tables/tests/test_properties.py | 156 ++++++++ >>>>> .../tests/test_reverse_engineer_ddl.py | 261 +++++++++++++ >>>>> .../tests/test_sql_template_create_integration.py | 0 >>>>> .../templates/table/sql/gpdb_5.0_plus/nodes.sql | 1 + >>>>> web/pgadmin/static/bundle/browser.js | 1 + >>>>> .../databases/external_tables/external_tables.js | 88 +++++ >>>>> .../servers/databases/external_tables/index.js | 18 + >>>>> web/pgadmin/tools/sqleditor/__init__.py | 1 + >>>>> .../external_tables/external_tables_spec.js | 56 +++ >>>>> web/webpack.config.js | 9 + >>>>> web/webpack.shim.js | 3 + >>>>> 28 files changed, 2194 insertions(+) >>>>> >>>>> >>>> >> > --94eb2c0b9ace0f719005673da58d Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hello Murtuza,
Yes I think it makes sense
Thanks
Joao

On Mon, Mar 12, 2018 at 10:40 AM Murtuza Zabuawala <<= a href=3D"mailto:murtuza.zabuawala@enterprisedb.com">murtuza.zabuawala@ente= rprisedb.com> wrote:
Hi Joao,

Can we make tests to skip if db is not greenplum?
Like we are doing for resource group "..web/pgadmin/browser/server_gr= oups/servers/resource_groups/tests".


On Mon, Mar 12, 2018 at 7:52 PM, Murtuza Zab= uawala <murtuza.zabuawala@enterprisedb.com>= wrote:
Hi Dav= e,
<= br>
= Joao's patch is pending, would you please do the needful?
I also encounter similar issue on Windows while running tests.

--
Regards,
Murtuza Zabuaw= ala
EnterpriseDB:=C2=A0http://www.enterprisedb.com
The Enterpr= ise PostgreSQL Company


On Tue, Mar 6, 2018 at 8:25 PM, Joao De Alme= ida Pereira <jdealmeidapereira@pivotal.io> wrote:=
Hell= o Neel,

You can find attached the corrections of the pat= h's needed for windows. The fix should correct=C2=A0TestExternalTablesView and=C2=A0TestTemplateCreate but f= or the ChangePasswordTestCase I need more information to help you out. We n= eed to understand what is the response that the endpoint /user_management/u= ser is returning.

Thanks
Joao
On Tue, Mar 6, 2018 at 2:= 29 AM Neel Patel <neel.patel@enterprisedb.com> wrote:
Hi=C2=A0Joao,

I ran the testsuite in windows 10 with Py= thon 3.4 and it fails for external tables. Linux it is working fine. Let me know if I miss anything.

Please check the below logs.

python runt= ests.py --pkg browser --exclude feature_tests

= ########

=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
ERROR: run= Test (pgadmin.browser.server_groups.servers.databases.schemas.tables.tests.= test_template_create.TestTemplateCreate)
When rendering GreenPlum= 5.3 template, when no distribution is present, when no primary key is pres= ent, it returns "DISTRIBUTED RANDOMLY"
----------------= ------------------------------------------------------
Traceback = (most recent call last):
=C2=A0 File "C:\Projects\pgadmin4\w= eb\pgadmin\browser\server_groups\servers\databases\schemas\tables\tests\tes= t_template_create.py", line 99, in runTest
=C2=A0 =C2=A0 sel= f.template_path, **self.input_parameters)
=C2=A0 File "C:\Pr= ojects\venv_pgadmin4_py_3_4\lib\site-packages\flask\templating.py", li= ne 133, in render_template
=C2=A0 =C2=A0 return _render(ctx.app.j= inja_env.get_or_select_template(template_name_or_list),
=C2=A0 Fi= le "C:\Projects\venv_pgadmin4_py_3_4\lib\site-packages\jinja2\environm= ent.py", line 830, in get_or_select_template
=C2=A0 =C2=A0 r= eturn self.get_template(template_name_or_list, parent, globals)
= =C2=A0 File "C:\Projects\venv_pgadmin4_py_3_4\lib\site-packages\jinja2= \environment.py", line 791, in get_template
=C2=A0 =C2=A0 re= turn self._load_template(name, self.make_globals(globals))
=C2=A0= File "C:\Projects\venv_pgadmin4_py_3_4\lib\site-packages\jinja2\envir= onment.py", line 765, in _load_template
=C2=A0 =C2=A0 templa= te =3D self.loader.load(self, name, globals)
=C2=A0 File "C:= \Projects\venv_pgadmin4_py_3_4\lib\site-packages\jinja2\loaders.py", l= ine 113, in load
=C2=A0 =C2=A0 source, filename, uptodate =3D sel= f.get_source(environment, name)
=C2=A0 File "C:\Projects\ven= v_pgadmin4_py_3_4\lib\site-packages\flask\templating.py", line 57, in = get_source
=C2=A0 =C2=A0 return self._get_source_fast(environment= , template)
=C2=A0 File "C:\Projects\venv_pgadmin4_py_3_4\li= b\site-packages\flask\templating.py", line 85, in _get_source_fast
=C2=A0 =C2=A0 raise TemplateNotFound(template)
jinja2.exce= ptions.TemplateNotFound: table\sql\gpdb_5.0_plus\create.sql

<= /div>
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
ERROR: runTest (pgadmin.browser.server_groups.servers.databases.sch= emas.tables.tests.test_template_create.TestTemplateCreate)
When r= endering GreenPlum 5.3 template, when no distribution is present, when prim= ary key is present, it returns "DISTRIBUTED BY (attr_primary_key)"= ;
---------------------------------------------------------------= -------
Traceback (most recent call last):
=C2=A0 File = "C:\Projects\pgadmin4\web\pgadmin\browser\server_groups\servers\databa= ses\schemas\tables\tests\test_template_create.py", line 99, in runTest=
=C2=A0 =C2=A0 self.template_path, **self.input_parameters)
=
=C2=A0 File "C:\Projects\venv_pgadmin4_py_3_4\lib\site-packages\f= lask\templating.py", line 133, in render_template
=C2=A0 =C2= =A0 return _render(ctx.app.jinja_env.get_or_select_template(template_name_o= r_list),
=C2=A0 File "C:\Projects\venv_pgadmin4_py_3_4\lib\s= ite-packages\jinja2\environment.py", line 830, in get_or_select_templa= te
=C2=A0 =C2=A0 return self.get_template(template_name_or_list, = parent, globals)
=C2=A0 File "C:\Projects\venv_pgadmin4_py_3= _4\lib\site-packages\jinja2\environment.py", line 791, in get_template=
=C2=A0 =C2=A0 return self._load_template(name, self.make_globals= (globals))
=C2=A0 File "C:\Projects\venv_pgadmin4_py_3_4\lib= \site-packages\jinja2\environment.py", line 765, in _load_template
=C2=A0 =C2=A0 template =3D self.loader.load(self, name, globals)
=C2=A0 File "C:\Projects\venv_pgadmin4_py_3_4\lib\site-packages= \jinja2\loaders.py", line 113, in load
=C2=A0 =C2=A0 source,= filename, uptodate =3D self.get_source(environment, name)
=C2=A0= File "C:\Projects\venv_pgadmin4_py_3_4\lib\site-packages\flask\templa= ting.py", line 57, in get_source
=C2=A0 =C2=A0 return self._= get_source_fast(environment, template)
=C2=A0 File "C:\Proje= cts\venv_pgadmin4_py_3_4\lib\site-packages\flask\templating.py", line = 85, in _get_source_fast
=C2=A0 =C2=A0 raise TemplateNotFound(temp= late)
jinja2.exceptions.TemplateNotFound: table\sql\gpdb_5.0_plus= \create.sql

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D
ERROR: runTest (pgadmin.browser.server_g= roups.servers.databases.schemas.tables.tests.test_template_create.TestTempl= ateCreate)
When rendering GreenPlum 5.3 template, when distributi= on is present, it returns "DISTRIBUTED BY (attr1, attr2, attr4)"<= /div>
-----------------------------------------------------------------= -----
Traceback (most recent call last):
=C2=A0 File &q= uot;C:\Projects\pgadmin4\web\pgadmin\browser\server_groups\servers\database= s\schemas\tables\tests\test_template_create.py", line 99, in runTest
=C2=A0 =C2=A0 self.template_path, **self.input_parameters)
=C2=A0 File "C:\Projects\venv_pgadmin4_py_3_4\lib\site-packages\fla= sk\templating.py", line 133, in render_template
=C2=A0 =C2= =A0 return _render(ctx.app.jinja_env.get_or_select_template(template_name_o= r_list),
=C2=A0 File "C:\Projects\venv_pgadmin4_py_3_4\lib\s= ite-packages\jinja2\environment.py", line 830, in get_or_select_templa= te
=C2=A0 =C2=A0 return self.get_template(template_name_or_list, = parent, globals)
=C2=A0 File "C:\Projects\venv_pgadmin4_py_3= _4\lib\site-packages\jinja2\environment.py", line 791, in get_template=
=C2=A0 =C2=A0 return self._load_template(name, self.make_globals= (globals))
=C2=A0 File "C:\Projects\venv_pgadmin4_py_3_4\lib= \site-packages\jinja2\environment.py", line 765, in _load_template
=C2=A0 =C2=A0 template =3D self.loader.load(self, name, globals)
=C2=A0 File "C:\Projects\venv_pgadmin4_py_3_4\lib\site-packages= \jinja2\loaders.py", line 113, in load
=C2=A0 =C2=A0 source,= filename, uptodate =3D self.get_source(environment, name)
=C2=A0= File "C:\Projects\venv_pgadmin4_py_3_4\lib\site-packages\flask\templa= ting.py", line 57, in get_source
=C2=A0 =C2=A0 return self._= get_source_fast(environment, template)
=C2=A0 File "C:\Proje= cts\venv_pgadmin4_py_3_4\lib\site-packages\flask\templating.py", line = 85, in _get_source_fast
=C2=A0 =C2=A0 raise TemplateNotFound(temp= late)
jinja2.exceptions.TemplateNotFound: table\sql\gpdb_5.0_plus= \create.sql

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D
ERROR: runTest (pgadmin.browser.tests.te= st_change_password.ChangePasswordTestCase)
TestCase for Changing = Valid_Password
--------------------------------------------------= --------------------
Traceback (most recent call last):
=C2=A0 File "C:\Projects\pgadmin4\web\pgadmin\browser\tests\test_chan= ge_password.py", line 91, in runTest
=C2=A0 =C2=A0 user_id = =3D json.loads(response.data.decode('utf-8'))['id']
KeyError: 'id'

=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
FAIL: runTest (pgadmin.brows= er.server_groups.servers.databases.external_tables.tests.test_external_tabl= es_view.TestExternalTablesView)
#nodes When retrieving the nodes = and the database does not have external tables, it return no child nodes an= d status 200
----------------------------------------------------= ------------------
Traceback (most recent call last):
= =C2=A0 File "C:\Python34\Lib\unittest\mock.py", line 1142, in pat= ched
=C2=A0 =C2=A0 return func(*args, **keywargs)
=C2= =A0 File "C:\Projects\pgadmin4\web\pgadmin\browser\server_groups\serve= rs\databases\external_tables\tests\test_external_tables_view.py", line= 314, in runTest
=C2=A0 =C2=A0 self.__test_nodes()
=C2= =A0 File "C:\Python34\Lib\unittest\mock.py", line 1142, in patche= d
=C2=A0 =C2=A0 return func(*args, **keywargs)
=C2=A0 F= ile "C:\Projects\pgadmin4\web\pgadmin\browser\server_groups\servers\da= tabases\external_tables\tests\test_external_tables_view.py", line 367,= in __test_nodes
=C2=A0 =C2=A0 self.expect_render_template_called= _with
=C2=A0 File "C:\Python34\Lib\unittest\mock.py", l= ine 777, in assert_called_with
=C2=A0 =C2=A0 raise AssertionError= (_error_message()) from cause
AssertionError: Expected call: rend= er_template('sql/#gpdb#80323#/list.sql')
Actual call: ren= der_template('sql/#gpdb#80323#\\list.sql')

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
F= AIL: runTest (pgadmin.browser.server_groups.servers.databases.external_tabl= es.tests.test_external_tables_view.TestExternalTablesView)
#nodes= When retrieving the nodes and an error happens while executing the query, = it return an internal server error and status 500
---------------= -------------------------------------------------------
Traceback= (most recent call last):
=C2=A0 File "C:\Python34\Lib\unitt= est\mock.py", line 1142, in patched
=C2=A0 =C2=A0 return fun= c(*args, **keywargs)
=C2=A0 File "C:\Projects\pgadmin4\web\p= gadmin\browser\server_groups\servers\databases\external_tables\tests\test_e= xternal_tables_view.py", line 314, in runTest
=C2=A0 =C2=A0 = self.__test_nodes()
=C2=A0 File "C:\Python34\Lib\unittest\mo= ck.py", line 1142, in patched
=C2=A0 =C2=A0 return func(*arg= s, **keywargs)
=C2=A0 File "C:\Projects\pgadmin4\web\pgadmin= \browser\server_groups\servers\databases\external_tables\tests\test_externa= l_tables_view.py", line 367, in __test_nodes
=C2=A0 =C2=A0 s= elf.expect_render_template_called_with
=C2=A0 File "C:\Pytho= n34\Lib\unittest\mock.py", line 777, in assert_called_with
= =C2=A0 =C2=A0 raise AssertionError(_error_message()) from cause
A= ssertionError: Expected call: render_template('sql/#gpdb#80323#/list.sq= l')
Actual call: render_template('sql/#gpdb#80323#\\list.= sql')

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D
FAIL: runTest (pgadmin.browser.server_group= s.servers.databases.external_tables.tests.test_external_tables_view.TestExt= ernalTablesView)
#nodes When retrieving the nodes and the databas= e has 2 external tables, it return 2 child nodes and status 200
-= ---------------------------------------------------------------------
=
Traceback (most recent call last):
=C2=A0 File "C:\Pyth= on34\Lib\unittest\mock.py", line 1142, in patched
=C2=A0 =C2= =A0 return func(*args, **keywargs)
=C2=A0 File "C:\Projects\= pgadmin4\web\pgadmin\browser\server_groups\servers\databases\external_table= s\tests\test_external_tables_view.py", line 314, in runTest
= =C2=A0 =C2=A0 self.__test_nodes()
=C2=A0 File "C:\Python34\L= ib\unittest\mock.py", line 1142, in patched
=C2=A0 =C2=A0 re= turn func(*args, **keywargs)
=C2=A0 File "C:\Projects\pgadmi= n4\web\pgadmin\browser\server_groups\servers\databases\external_tables\test= s\test_external_tables_view.py", line 367, in __test_nodes
= =C2=A0 =C2=A0 self.expect_render_template_called_with
=C2=A0 File= "C:\Python34\Lib\unittest\mock.py", line 777, in assert_called_w= ith
=C2=A0 =C2=A0 raise AssertionError(_error_message()) from cau= se
AssertionError: Expected call: render_template('sql/#gpdb#= 80323#/list.sql')
Actual call: render_template('sql/#gpdb= #80323#\\list.sql')

=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
FAIL: runTest (pgadmin.brows= er.server_groups.servers.databases.external_tables.tests.test_external_tabl= es_view.TestExternalTablesView)
#node When retrieving the informa= tion about 1 external table and an error happens while executing the query,= it return an internal server error and status 500
--------------= --------------------------------------------------------
Tracebac= k (most recent call last):
=C2=A0 File "C:\Python34\Lib\unit= test\mock.py", line 1142, in patched
=C2=A0 =C2=A0 return fu= nc(*args, **keywargs)
=C2=A0 File "C:\Projects\pgadmin4\web\= pgadmin\browser\server_groups\servers\databases\external_tables\tests\test_= external_tables_view.py", line 316, in runTest
=C2=A0 =C2=A0= self.__test_node()
=C2=A0 File "C:\Python34\Lib\unittest\mo= ck.py", line 1142, in patched
=C2=A0 =C2=A0 return func(*arg= s, **keywargs)
=C2=A0 File "C:\Projects\pgadmin4\web\pgadmin= \browser\server_groups\servers\databases\external_tables\tests\test_externa= l_tables_view.py", line 393, in __test_node
=C2=A0 =C2=A0 **= self.expect_render_template_called_with
=C2=A0 File "C:\Pyth= on34\Lib\unittest\mock.py", line 777, in assert_called_with
= =C2=A0 =C2=A0 raise AssertionError(_error_message()) from cause
A= ssertionError: Expected call: render_template(external_table_id=3D11, templ= ate_name_or_list=3D'sql/#gpdb#80323#/node.sql')
Actual ca= ll: render_template(external_table_id=3D11, template_name_or_list=3D'sq= l/#gpdb#80323#\\node.sql')

=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
FAIL: runTest (pgadmin= .browser.server_groups.servers.databases.external_tables.tests.test_externa= l_tables_view.TestExternalTablesView)
#node When retrieving the i= nformation about 1 external table and table does not exist, it return an er= ror message and status 404
--------------------------------------= --------------------------------
Traceback (most recent call last= ):
=C2=A0 File "C:\Python34\Lib\unittest\mock.py", line= 1142, in patched
=C2=A0 =C2=A0 return func(*args, **keywargs)
=C2=A0 File "C:\Projects\pgadmin4\web\pgadmin\browser\server_g= roups\servers\databases\external_tables\tests\test_external_tables_view.py&= quot;, line 316, in runTest
=C2=A0 =C2=A0 self.__test_node()
=C2=A0 File "C:\Python34\Lib\unittest\mock.py", line 1142, = in patched
=C2=A0 =C2=A0 return func(*args, **keywargs)
=C2=A0 File "C:\Projects\pgadmin4\web\pgadmin\browser\server_groups\s= ervers\databases\external_tables\tests\test_external_tables_view.py", = line 393, in __test_node
=C2=A0 =C2=A0 **self.expect_render_templ= ate_called_with
=C2=A0 File "C:\Python34\Lib\unittest\mock.p= y", line 777, in assert_called_with
=C2=A0 =C2=A0 raise Asse= rtionError(_error_message()) from cause
AssertionError: Expected = call: render_template(external_table_id=3D11, template_name_or_list=3D'= sql/#gpdb#80323#/node.sql')
Actual call: render_template(exte= rnal_table_id=3D11, template_name_or_list=3D'sql/#gpdb#80323#\\node.sql= ')

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D
FAIL: runTest (pgadmin.browser.server_groups.s= ervers.databases.external_tables.tests.test_external_tables_view.TestExtern= alTablesView)
#nodes When retrieving the information about 1 exte= rnal table and the table exists, it return external node information and st= atus 200
--------------------------------------------------------= --------------
Traceback (most recent call last):
=C2= =A0 File "C:\Python34\Lib\unittest\mock.py", line 1142, in patche= d
=C2=A0 =C2=A0 return func(*args, **keywargs)
=C2=A0 F= ile "C:\Projects\pgadmin4\web\pgadmin\browser\server_groups\servers\da= tabases\external_tables\tests\test_external_tables_view.py", line 316,= in runTest
=C2=A0 =C2=A0 self.__test_node()
=C2=A0 Fil= e "C:\Python34\Lib\unittest\mock.py", line 1142, in patched
=
=C2=A0 =C2=A0 return func(*args, **keywargs)
=C2=A0 File &qu= ot;C:\Projects\pgadmin4\web\pgadmin\browser\server_groups\servers\databases= \external_tables\tests\test_external_tables_view.py", line 393, in __t= est_node
=C2=A0 =C2=A0 **self.expect_render_template_called_with<= /div>
=C2=A0 File "C:\Python34\Lib\unittest\mock.py", line 77= 7, in assert_called_with
=C2=A0 =C2=A0 raise AssertionError(_erro= r_message()) from cause
AssertionError: Expected call: render_tem= plate(external_table_id=3D11, template_name_or_list=3D'sql/#gpdb#80323#= /node.sql')
Actual call: render_template(external_table_id=3D= 11, template_name_or_list=3D'sql/#gpdb#80323#\\node.sql')

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D
FAIL: runTest (pgadmin.browser.server_groups.servers.database= s.external_tables.tests.test_external_tables_view.TestExternalTablesView)
#properties When retrieving the properties of a external table and= the table exists, it return the properties and status 200
------= ----------------------------------------------------------------
= Traceback (most recent call last):
=C2=A0 File "C:\Python34\= Lib\unittest\mock.py", line 1142, in patched
=C2=A0 =C2=A0 r= eturn func(*args, **keywargs)
=C2=A0 File "C:\Projects\pgadm= in4\web\pgadmin\browser\server_groups\servers\databases\external_tables\tes= ts\test_external_tables_view.py", line 320, in runTest
=C2= =A0 =C2=A0 self.__test_properties()
=C2=A0 File "C:\Python34= \Lib\unittest\mock.py", line 1142, in patched
=C2=A0 =C2=A0 = return func(*args, **keywargs)
=C2=A0 File "C:\Projects\pgad= min4\web\pgadmin\browser\server_groups\servers\databases\external_tables\te= sts\test_external_tables_view.py", line 419, in __test_properties
=C2=A0 =C2=A0 **self.expect_render_template_called_with
=C2= =A0 File "C:\Python34\Lib\unittest\mock.py", line 777, in assert_= called_with
=C2=A0 =C2=A0 raise AssertionError(_error_message()) = from cause
AssertionError: Expected call: render_template(templat= e_name_or_list=3D'sql/#gpdb#80323#/get_table_information.sql', tabl= e_oid=3D11)
Actual call: render_template(template_name_or_list=3D= 'sql/#gpdb#80323#\\get_table_information.sql', table_oid=3D11)

------------------------------------------------------= ----------------
Ran 256 tests in 77.123s

FAILED (failures=3D7, errors=3D4, skipped=3D25)

= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
Test= Result Summary
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D

PostgreSQL 9.6:

<= div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 234 tests passed
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 3 tests failed:
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 TestExternalTablesView (#node When retrieving the info= rmation about 1 external table and table does not exist, it return an error= message and status 404,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 #node When retrieving the information about 1 e= xternal table and an error happens while executing the query, it return an = internal server error and status 500,
=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 #nodes When retrieving the nodes and= the database has 2 external tables, it return 2 child nodes and status 200= ,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 #nodes When retrieving the information about 1 external table and the t= able exists, it return external node information and status 200,
= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 #nodes W= hen retrieving the nodes and an error happens while executing the query, it= return an internal server error and status 500,
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 #properties When retri= eving the properties of a external table and the table exists, it return th= e properties and status 200,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 #nodes When retrieving the nodes and the da= tabase does not have external tables, it return no child nodes and status 2= 00)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Chang= ePasswordTestCase (TestCase for Changing Valid_Password)
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 TestTemplateCreate (When r= endering GreenPlum 5.3 template, when no distribution is present, when no p= rimary key is present, it returns "DISTRIBUTED RANDOMLY",
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 When = rendering GreenPlum 5.3 template, when distribution is present, it returns = "DISTRIBUTED BY (attr1, attr2, attr4)",
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 When rendering GreenPl= um 5.3 template, when no distribution is present, when primary key is prese= nt, it returns "DISTRIBUTED BY (attr_primary_key)")
=C2= =A0 =C2=A0 =C2=A0 =C2=A0 19 tests skipped:
=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ResourceGroupsGetTestCase (Get resource = groups)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 T= ableSpaceDeleteTestCase (Check Tablespace Node)
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ResourceGroupsDeleteTestCase (Delete= resource groups)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 SynonymDeleteTestCase (Fetch synonym Node URL)
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 TestSSLConnection (Test fo= r SSL connection)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 PackageAddTestCase (Fetch Package Node URL)
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 SynonymPutTestCase (Fetch syn= onym Node URL)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 TablespaceGetTestCase (Check Tablespace Node)
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 SynonymAddTestCase (Default N= ode URL)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = PackagePutTestCase (Fetch Package Node URL)
=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 TableAddTestCase (Create Range partition= ed table with 2 partitions,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Create List partitioned table with 2 partit= ions)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Pac= kageGetTestCase (Fetch Package Node URL)
=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 PackageDeleteTestCase (Fetch Package Node U= RL)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Table= SpaceAddTestCase (Check Tablespace Node)
=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ResourceGroupsAddTestCase (Add resource gro= ups)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Syno= nymGetTestCase (Fetch synonym Node URL)
=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ResourceGroupsPutTestCase (Put resource gro= ups)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Tabl= eSpaceUpdateTestCase (Check Tablespace Node)
=C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 TableUpdateTestCase (Attach partition t= o existing range partitioned table,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Detach partition from existing range= partitioned table,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 Create partitions of existing range partitioned table,=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 Detach partition from existing list partitioned table,
=C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Create partitio= ns of existing list partitioned table,
=C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 Attach partition to existing list= partitioned table)

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D

########


Thanks,
N= eel Patel

On Fri, Mar 2, 2018 at 10:19 PM, Dave Page <= ;dpage@pgadmin.org> wrote:
S= upport for external tables in GPDB. Fixes #3168

Branch
------
master

Details
-------
https://git.postgresql.org/gitweb?p=3Dpgadmin4.git;a=3Dcommitdi= ff;h=3D427314cfdfeb96c3a7835eab5a4d638903bc6dc3
Author: Joao Pedro De Almeida Pereira <jdealmeidapereira@pivotal.io>

Modified Files
--------------
.../servers/databases/external_tables/__init__.py=C2=A0 | 275 +++++++++++++=
.../databases/external_tables/actions/__init__.py=C2=A0 |=C2=A0 =C2=A00
.../external_tables/actions/get_all_nodes.py=C2=A0 =C2=A0 =C2=A0 =C2=A0|=C2= =A0 =C2=A04 +
.../databases/external_tables/mapping_utils.py=C2=A0 =C2=A0 =C2=A0| 165 +++= +++++
.../databases/external_tables/properties.py=C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2= =A0 78 ++++
.../external_tables/reverse_engineer_ddl.py=C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2= =A0 69 ++++
.../static/img/coll-external_table.svg=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0|=C2=A0 =C2=A01 +
.../external_tables/static/img/external_table.svg=C2=A0 |=C2=A0 =C2=A01 + .../templates/sql/gpdb_5.0_plus/create.sql=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0|=C2=A0 60 +++
.../templates/sql/gpdb_5.0_plus/get_columns.sql=C2=A0 =C2=A0 |=C2=A0 12 + .../sql/gpdb_5.0_plus/get_table_information.sql=C2=A0 =C2=A0 |=C2=A0 22 ++<= br> .../templates/sql/gpdb_5.0_plus/list.sql=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0|=C2=A0 =C2=A06 +
.../templates/sql/gpdb_5.0_plus/node.sql=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0|=C2=A0 =C2=A05 +
.../databases/external_tables/tests/__init__.py=C2=A0 =C2=A0 |=C2=A0 =C2=A0= 0
.../tests/test_external_tables_module.py=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0|=C2=A0 99 +++++
.../tests/test_external_tables_view.py=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0| 428 +++++++++++++++++++++
.../external_tables/tests/test_mapping_utils.py=C2=A0 =C2=A0 | 375 ++++++++= ++++++++++
.../external_tables/tests/test_properties.py=C2=A0 =C2=A0 =C2=A0 =C2=A0| 15= 6 ++++++++
.../tests/test_reverse_engineer_ddl.py=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0| 261 +++++++++++++
.../tests/test_sql_template_create_integration.py=C2=A0 |=C2=A0 =C2=A00
.../templates/table/sql/gpdb_5.0_plus/nodes.sql=C2=A0 =C2=A0 |=C2=A0 =C2=A0= 1 +
web/pgadmin/static/bundle/browser.js=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0|=C2=A0 =C2=A01 +
.../databases/external_tables/external_tables.js=C2=A0 =C2=A0|=C2=A0 88 +++= ++
.../servers/databases/external_tables/index.js=C2=A0 =C2=A0 =C2=A0|=C2=A0 1= 8 +
web/pgadmin/tools/sqleditor/__init__.py=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 |=C2=A0 =C2=A01 +
.../external_tables/external_tables_spec.js=C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2= =A0 56 +++
web/webpack.config.js=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2=A0 =C2=A09 +
web/webpack.shim.js=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2=A0 =C2=A03 + 28 files changed, 2194 insertions(+)




--94eb2c0b9ace0f719005673da58d--