Skip to content

Unable to run \Magento\Downloadable\Test\Unit\Helper\DownloadTest without internet connection / dns resolution #23521

Closed
@adrian-martinez-interactiv4

Description

Preconditions (*)

  1. Magento 2.3.2, just created project, no setup:install
  2. PHP 7.2.19

Steps to reproduce (*)

  1. Create Magento 2.3.2 project
  2. Run unit tests (at least \Magento\Downloadable\Test\Unit\Helper\DownloadTest) without internet connection

Expected result (*)

  1. Test should pass (image below shows test execution with internet connection):

Captura de pantalla 2019-07-01 a las 13 04 04

Actual result (*)

  1. Test fails with message (image below shows test execution without internet connection): PHPUnit\Framework\Exception: Warning: get_headers(): php_network_getaddresses: getaddrinfo failed: nodename nor servname provided, or not known in /Users/adrianmartinez/Sites/2.3/magento/vendor/magento/module-downloadable/Helper/Download.php:264.

Captura de pantalla 2019-07-01 a las 13 04 58

Extended description

This behaviour cannot be reproduced in 2.2.8, test passes even if there is no internet connection. Comparing code both versions, I've seen this snippet of code has been added in new version of tested class \Magento\Downloadable\Helper\Download:

    public function setResource($resourceFile, $linkType = self::LINK_TYPE_FILE)
    {
        (...)
        
        /**
        * check header for urls
        */
        if ($linkType === self::LINK_TYPE_URL) {
            $headers = array_change_key_case(get_headers($this->_resourceFile, 1), CASE_LOWER);
            if (isset($headers['location'])) {
                $this->_resourceFile  = is_array($headers['location']) ? current($headers['location'])
                    : $headers['location'];
            }
        }
        
        (...)
    }

This new code looks quite risky and not safe, I mean, even if problem is the test not passing, this piece of code has some assumptions that can break execution at any time.

First of all, test relies on a test url: \Magento\Downloadable\Test\Unit\Helper\DownloadTest::URL = 'http://example.com', that may exist or not, or could be down at any time. This means this test could even fail with internet connection if that site is down or DNS servers are not available.

In second place, it tries to extract headers using get_headers php built-in function, and passes the result directly to array_change_key_case, without any kind of check. get_headers may emit a warning if it is not able to get header of supplied url, but even if silenced with @get_headers, execution throws another warning due to get_headers returning false instead of an array, and array_change_key_case complaining about receiving a boolean parameter instead of an array:

1) Magento\Downloadable\Test\Unit\Helper\DownloadTest::testGetFileSizeUrl
PHPUnit\Framework\Exception: Warning: array_change_key_case() expects parameter 1 to be array, boolean given in /Users/adrianmartinez/Sites/2.3/magento/vendor/magento/module-downloadable/Helper/Download.php:264.

I think that piece of code should be refactored through a HeadersResolver (or another more appropriate name), responsible of returning always a consistent return value when requested for some headers (always return an array), and use this new class in \Magento\Downloadable\Helper\Download, so it can be mocked for testing.

Metadata

Metadata

Assignees

Labels

Component: TestFixed in 2.4.xThe issue has been fixed in 2.4-develop branchIssue: Clear DescriptionGate 2 Passed. Manual verification of the issue description passedIssue: ConfirmedGate 3 Passed. Manual verification of the issue completed. Issue is confirmedIssue: Format is validGate 1 Passed. Automatic verification of issue format passedIssue: Ready for WorkGate 4. Acknowledged. Issue is added to backlog and ready for developmentReproduced on 2.3.xThe issue has been reproduced on latest 2.3 release

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions