After building a custom install profile (example), I attempted to create a test for the profile, similar to StandardTest.

The test failed due to Drupal's inability to write the file to the desired folder in drupal_generate_test_ua() (sample output below). I've been unable to determine why this predictably happens with my install profile, but not with the Minimal profile (for example).

There is nothing that leads me to believe this has to do with environmental factors, but colleagues have had trouble reproducing, so I'm providing as much detail as possible here.

Environment details

  • OSX 10.9.2
  • Clean install of latest Acquia DevDesktop 2 Beta (2014-04-10).
  • Drush 7.x

Steps to reproduce

1. Clone Drupal 8.x: git clone --branch 8.x http://git.drupal.org/project/drupal.git

2. Clone the test profile: In the /profiles folder, git clone --branch spelunky-profile git@github.com:jrbeeman/spelunky.git

3. Setup this code base as a site in DevDesktop: See Getting started and some Drupal 8-related notes.

4. Install the site, enable Testing, and run the simple install profile test:

drush si -v spelunky;
drush en simpletest;
drush test-run -v "Drupal\spelunky\Tests\SpelunkyTest";

You should be presented with a list of errors, all resulting from this first one:

Test drupal_generate_test_ua() failed: file_put_contents(/Users/jbeeman/Sites/spelunky/sites/simpletest/271652/.htkey): failed to open stream: Permission     [error]
denied<pre class="backtrace">file_put_contents('/Users/jbeeman/Sites/spelunky/sites/simpletest/271652/.htkey',
'd3otdkJNnBNi3wRj9FKKdEk1lPFEym6jyWs2_SCM4hMsOrWmpxe-IKjDlRAO8uzXVYgzavWORQ')
drupal_generate_test_ua('simpletest271652')

Issue fork drupal-2246725

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

jrbeeman’s picture

The attached patch modifies drupal_generate_test_ua() to add a call to file_prepare_directory(), which ensures that the destination folder for the htkey file exists before it attempts to write the file.

jrbeeman’s picture

Assigned: jrbeeman » Unassigned
Status: Active » Needs review
jrbeeman’s picture

Issue summary: View changes

Updated issue description with environmental details and steps to reproduce.

jrbeeman’s picture

sun’s picture

Status: Needs review » Postponed (maintainer needs more info)
       // Consumed by drupal_valid_test_ua() before settings.php is loaded.
+      file_prepare_directory($key_file_directory);

file_prepare_directory() cannot be used, because it requires a fully booted Drupal environment.

The comment in the line directly above clearly states that Settings and settings.php is not available yet.


Curious, could you repeat + redo your steps to reproduce, but remove Drush entirely from the equation, please?

Unless your installation profile causes the regular Drupal installation procedure to prematurely end, Drush is really the only aspect here that could cause a misbehavior. There are many similar problems with Drush on D8, so that wouldn't be a surprise.

jrbeeman’s picture

Status: Postponed (maintainer needs more info) » Needs review

I re-ran the tests this morning using the UI (not Drush) and recreated the failure.

  1. Updated to latest 8.x as of this morning (removed patch from this issue).
  2. Re-installed the site and enabled Testing module.
  3. Using the Testing UI, ran only the Spelunky profile test.
  4. The test fails with the same error.
  5. Re-added my patch, ran the test via the UI, and it passed.

To help me better understand: Can you explain why you're concerned file_prepare_directory() won't be available in this case? Is file.inc not loaded, or are you indicating that it depends on some other method or variable that may not exist yet?

The key issue I'm encountering is that file_put_contents() fails because the directory into which it's attempting to put the file doesn't exist yet. What I'm struggling to see is how this works in any other instances, because file_put_contents() needs the directory to exist before it can put the file there.

Interestingly, the Standard profile tests still pass just fine. So, I wonder if the issue may be related to the content architecture created by the profile I've built. It contains several content types with fields of various types (file, entity reference, etc.). That's the only clear distinction I can note between my profile and the Standard profile.

TravisCarden’s picture

To eliminate other variables, I was able to follow @jrbeeman's steps to reproduce on Ubuntu 14.04 with a standard, current AMP stack. So the problem seems dependent neither on any of the environment details listed in the summary nor on Drush.

clemens.tolboom’s picture

fwiw in #2272879: Can not run a WebTestBase or KernelTest base tests from inside a simpletest the .htkey file is written without checking for the existing of the directory.

@jrbeeman what I think @sun is trying to say is calling file_prepare_directory() assumes a fully bootstrapped Drupal which is normally the case but simpletest runs its tests in a 'child site'.

You could try to test from the commandline like

cd ~/Sites/drupal/d8/www/core/scripts
php run-tests.sh --list
# choose a group name like simpletest.
php run-tests.sh --url http://drupal.d8 simpletest

Hope that helps?

jhedstrom’s picture

Status: Needs review » Needs work

This is at needs work.

akalata’s picture

I'm also seeing this issue with a custom install profile. My error message is slightly different, but seems to be the same basic idea. I am able to run other tests locally (such as Drupal\standard\Tests\StandardTest) without issues.

System details:
OSX 10.10.3
Drupal 8.0.x-beta10

file_put_contents(/Users/Swan/Sites/locals/d8-profile.local/sites/simpletest/353164/.htkey): failed to open stream: Permission denied

file_put_contents('/Users/Swan/Sites/locals/d8-profile.local/sites/simpletest/353164/.htkey', '7pvNs8HEcBkyRzYErDvMnFkGciDQmemOHVRxDohKBGwTTCfUC3ZlE2a3BSzK3yJOfi198Y6bOw')
drupal_generate_test_ua('simpletest353164')
Drupal\Core\Test\EventSubscriber\HttpRequestSubscriber->onBeforeSendRequest(Object, 'before')
GuzzleHttp\Event\Emitter->emit('before', Object)
GuzzleHttp\RequestFsm->__invoke(Object)
GuzzleHttp\Client->send(Object)
GuzzleHttp\Client->get('http://updates.drupal.org/release-history/drupal/8.x?site_key=dn7hyUzY-tTG5jQ1vzEXRoImFx7Z-LIkO43kdrkLaOQ&version=8.0.0-beta10&list=block%2Cblock_content%2Cbreakpoint%2Cckeditor%2Cconfig%2Ccontextual%2Cdblog%2Ceditor%2Centity_reference%2Cfield%2Cfield_ui%2Cfile%2Cfilter%2Cimage%2Clink%2Cmenu_link_content%2Cmenu_ui%2Cnode%2Coptions%2Cpage_cache%2Cpath%2Cquickedit%2Crdf%2Cshortcut%2Csystem%2Ctext%2Ctoolbar%2Cupdate%2Cuser%2Cviews%2Cviews_ui%2Cclassy%2Cseven%2Cbartik', Array)
Drupal\update\UpdateFetcher->fetchProjectData(Array, 'dn7hyUzY-tTG5jQ1vzEXRoImFx7Z-LIkO43kdrkLaOQ')
Drupal\update\UpdateProcessor->processFetchTask(Array)
Drupal\update\UpdateProcessor->fetchData()
update_fetch_data()
update_cron()
call_user_func_array('update_cron', Array)
Drupal\Core\Extension\ModuleHandler->invoke('update', 'cron')
Drupal\Core\Cron->invokeCronHandlers()
Drupal\Core\Cron->run()
install_finished(Array)
install_run_task(Array, Array)
install_run_tasks(Array)
install_drupal(Object, Array)
Drupal\simpletest\WebTestBase->setUp()
Drupal\simpletest\TestBase->run()
_simpletest_batch_operation(Array, '9', Array)
call_user_func_array('_simpletest_batch_operation', Array)
_batch_process()
_batch_do()
_batch_page(Object)
Drupal\system\Controller\BatchController->batchPage(Object)
call_user_func_array(Array, Array)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1)
Stack\StackedHttpKernel->handle(Object, 1, 1)
Drupal\Core\DrupalKernel->handle(Object)
akalata’s picture

Looking into this a bit more. When I copy the "Standard" install profile, and rename everything to "Standard2", and run the test, and everything comes up green. So that's curious.

akalata’s picture

What I've found from investigating my install profile is that adding the Update Manager module (update) to the dependencies causes the exception in the test (even when the test has nothing to do with updates).

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Sam152’s picture

FWIW I am also running into this issue on an install profile. The tests run and once the simpletest browser is clicking around the website, a http request on the target page/thread is made which triggers the exact same permission denied error.

Sam152’s picture

Status: Needs work » Needs review
FileSize
1.12 KB

Possible solution without bootstrapping?

benjy’s picture

Issue tags: +Needs tests

Patch works as advertised, probably needs a test though.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

kim.pepper’s picture

Re-rolled for 8.2.x

Sam152’s picture

This is no longer an issue with BrowserTestBase as it sets the sites directory to be 777 after the installer completes. Test to demo the issue with the 777 commented out, but I think this can be closed.

Sam152’s picture

Status: Needs review » Closed (outdated)

Status: Closed (outdated) » Needs work

The last submitted patch, 19: 2246725-test-only-19.patch, failed testing.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

benjy’s picture

This is no longer an issue with BrowserTestBase as it sets the sites directory to be 777 after the installer completes

This issue still crops up using #2793445: Allow BTB to test an existing, already installed Drupal site instead of installing from scratch but you won't notice it unless you're sending PHP errors from the requests back to the tests :)

+++ b/core/includes/bootstrap.inc
@@ -681,6 +682,7 @@ function drupal_generate_test_ua($prefix) {
+      chmod($key_file_directory, 0775);

I actually had to make this mkdir($key_file_directory, 0775);

benjy’s picture

FileSize
1.21 KB
649 bytes

A proper fix should probably be solved in the BTB issue but here it is for now anyway.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

jibran’s picture

Title: Test runs can throw exceptions due to missing .htkey file » Make sure TestSitePath exist before creating .htkey
Version: 8.5.x-dev » 8.7.x-dev
Component: simpletest.module » phpunit
Category: Bug report » Task
Status: Needs work » Reviewed & tested by the community
Issue tags: -Needs tests

The problem is when the tests are run on already installed site the TestSitePath doesn't exist so this can cause an issue. See #2793445-86: Allow BTB to test an existing, already installed Drupal site instead of installing from scratch or https://gitlab.com/weitzman/drupal-test-traits/merge_requests/36/diffs#3... so this is not a bug but a task.

alexpott’s picture

Status: Reviewed & tested by the community » Needs review

Hmmm.... so the use case is to run tests against an existing database. We're not installing a site all right? So the files directory that's being used is the same as the site too?

I'm worried because in \Drupal\Core\DrupalKernel::findSitePath() we use

    // Check for a simpletest override.
    if ($test_prefix = drupal_valid_test_ua()) {
      $test_db = new TestDatabase($test_prefix);
      return $test_db->getTestSitePath();
    }

to get the site path. Even if there should be a separate test path I'm not sure here is the right place to create it. Atm the directory is created in \Drupal\Core\Test\FunctionalTestSetupTrait::prepareEnvironment() and I'm not sure we should change that.

jibran’s picture

We're not installing a site all right?

Yes, that is right.

So the files directory that's being used is the same as the site too?

This is a really good question. If we go by this logic then we should need to update \Drupal\Core\Test\TestDatabase to accommodate that case.

Even if there should be a separate test path I'm not sure here is the right place to create it.

I think if we accommodate the case that testing DB is default DB in \Drupal\Core\Test\TestDatabase we can address that.

I'm +1 to make \Drupal\Core\Test\TestDatabase more usable when site is already installed. What do you think?

alexpott’s picture

I don't think we should change \Drupal\Core\Test\TestDatabase at all. But maybe we should make it easy to override.

jibran’s picture

Yeah, that makes sense.

jibran’s picture

Any ideas how to proceed?

alexpott’s picture

Status: Needs review » Needs work

It is tricky because the class is used both by the test runner and the site under test so it has to be overridable in both places. This is made even harder by the fact that in the site under test it is used before settings.php is loaded so overriding it there is not an option either. So we're going to need to be wrap drupal_valid_test_ua() to return one of these objects and to communicate the class to use in the SIMPLTEST_USER_AGENT.

lpeabody’s picture

jibran’s picture

In Drupal testing trait library, we have an open merge request https://gitlab.com/weitzman/drupal-test-traits/merge_requests/62 to fix this issue. Please try it or similar approach on your projects.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

alexverb made their first commit to this issue’s fork.

alexverb’s picture

Status: Needs work » Needs review

For me the patch was not sufficient because it was not able to create the sites/simpletest folder. So for that I created a merge request that creates the directory recursively. Not sure why the tests are failing though...

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Needs Review Queue Initiative, +Needs issue summary update

This issue is being reviewed by the kind folks in Slack, #needs-review-queue-initiative. We are working to keep the size of Needs Review queue [2700+ issues] to around 400 (1 month or less), following Review a patch or merge request as a guide.

MR should be updated for 10.1

Also IS should be updated as it references acquia dev desktop which support stopped in June 2021.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

dpagini’s picture

I've actually recently run into this issue, and I have some more details that affected me here I wanted to share...

The fix here still solves my problem, and I can explain why as well.

So I ran into this issue with the following scenario...
* I am installing a site that uses a custom cron job to make a call out to an RSS feed, download the file, and store it locally for processing by the feeds module.
* Drupal core runs through the INSTALL steps... but the install_configure_form step actually hardens the simpletest site directory, and sets the folder to 555 (not writeable).
* Drupal core at the end of the installation then triggers a cron. My job calls out to the internet. Drupal core has a custom testing middleware that intercepts that calls, and tries to add testing headers to the call, and ultimately calls drupal_generate_test_ua(), which tries to write the .htkey file to a hardened sites directory, and that fails... so my first cron run fails silently.

I actually came across this b/c by enabling the "locale" module, the call to drupal_generate_test_ua() was made earlier in the stack, before the hardening, and the .htkey file gets placed successfully, and there is no more failure.