Project

General

Profile

Debugging CiviCRM cheatsheet » History » Version 46

Jon Goldberg, 05/17/2024 08:18 PM

1 7 Jon Goldberg
{{last_updated_at}} by {{last_updated_by}}
2
3 1 Jon Goldberg
# Debugging CiviCRM cheatsheet
4
5
### Command-line runs of PHPUnit:
6
7
From a buildkit civiroot, run a specific file's tests::
8
9 2 Jon Goldberg
```shell
10
CIVICRM_UF=UnitTests phpunit5 tests/phpunit/CRM/Core/BAO/AddressTest.php
11
```
12 1 Jon Goldberg
13
You can also limit to a single test by filtering on name:
14
15 2 Jon Goldberg
```shell
16
CIVICRM_UF=UnitTests phpunit5 tests/phpunit/CRM/Core/BAO/AddressTest.php --filter testShared
17
```
18 3 Jon Goldberg
19
### With XDebug
20 9 Jon Goldberg
21 14 Jon Goldberg
#### Web Browser
22 37 Brienne Kordis
* Install the xdebug extension (e.g. `sudo apt install php8.1-xdebug`).
23
* Configure xdebug by copying the values below to `/etc/php/8.1/fpm/conf.d/xdebug.ini`:
24 2 Jon Goldberg
25 1 Jon Goldberg
```
26 12 Jon Goldberg
xdebug.mode=debug,develop
27
xdebug.start_with_request=trigger
28 1 Jon Goldberg
xdebug.client_host = "127.0.0.1"
29 10 Jon Goldberg
xdebug.log=/var/log/xdebug.log
30 12 Jon Goldberg
#xdebug.mode=profile
31 1 Jon Goldberg
#xdebug.output_dir = "/home/jon/temp/xdebug"
32
```
33 14 Jon Goldberg
34 1 Jon Goldberg
* Install a plugin for your browser, like "XDebug Helper for Firefox".
35 14 Jon Goldberg
 * In the plugin's configuration, set the IDE key to `VSCODE`.
36 37 Brienne Kordis
* For buildkit sites, you'll need to cp the `xdebug.ini` into `apache2/fpm/conf.d` and `cli/fpm/conf.8`. Then restart apache and php
37 14 Jon Goldberg
38 22 Brienne Kordis
* If one does not already exist, create a launch.json file within the .vscode folder (make a new folder if it does not yet exist) at the root of your codebase. What goes into the launch.json file depends on whether you are debugging a a site created with the `civibuild` command or one that was not built with that command. Here are examples of a [civibuild launch.json](https://hq.megaphonetech.com/projects/commons/wiki/Launchjson_for_civibuild_sites) and a [non-civibuild launch.json](https://hq.megaphonetech.com/projects/commons/wiki/Launchjson_for_non-civibuild_sites). Note that the "max-depth" on the "Listen for XDebug" configuration can be changed to delve deeper into the values that are returned (i.e. a depth of 6 will return more levels of a nested array than a depth of 3).
39 19 Brienne Kordis
40 14 Jon Goldberg
To debug, you must turn on the debugger in VS Code, then enable debugging in the address bar for the requests in question.
41
42 28 Jon Goldberg
#### Web Browser - remote debugging
43
To debug on a remote server, ensure you have local debugging working first.
44
45
#### Server-side setup
46
* `sudo apt install php{{php_version}}-xdebug` (I should add this to `group_vars/all.yml` so it's everywhere).
47 39 Jon Goldberg
* Create a file `/etc/php/{{php_version}}/fpm/conf.d/xdebug.ini:
48 28 Jon Goldberg
49
```
50
xdebug.mode=debug
51
xdebug.start_with_request=trigger
52
```
53
* Restart PHP.
54
55
#### Client side setup
56 43 Jon Goldberg
##### First time ever remote debugging setup
57 40 Jon Goldberg
* In your VS Code plugins screen, install the "Remote - SSH" plugin.
58 43 Jon Goldberg
59 40 Jon Goldberg
##### Always
60 43 Jon Goldberg
* Using the new **Remote Explorer** sidebar icon in VS Code, select the server you'd like to connect to. Click the "Connect in current window" icon.
61 28 Jon Goldberg
* If you've already debugged on this site before, you should be able to expand the server and see a workspace file (see screenshot below).  Click one of the connect icons.
62
* If you haven't debugged on this site before, follow *First Time* instructions below. Otherwise, debug as normal (make sure your Firefox "debug" icon is turned on).
63 1 Jon Goldberg
64 28 Jon Goldberg
##### First Time
65
* Click **Open Folder** and navigate to the site's gitroot (usually the same as webroot, but for D8+ it's the folder above `web` so you can also debug in `vendor`).
66
* Select **File menu » Save Workspace As** and store a workspace file in your home directory.
67 43 Jon Goldberg
* In your VS Code plugins screen, you need to select `Install in SSH` for the `PHP Debug` and `PHP Intelephense` plugins. Make sure it's the "PHP Debug" by XDebug (should have 10M+ installs)
68 29 Jon Goldberg
 * For Drupal sites, also **Install in SSH** the *Drupal Syntax Highlighting* extension or you can't debug .module files.
69 41 Jon Goldberg
* Go to the VS Code "debug" sidebar.  Click **Add Configuration** and then select **workspace**, then **PHP**.
70 28 Jon Goldberg
* (Optional) in the **Remote Explorer** sidebar, under the server you're connected to, right-click the entry that doesn't say "Workspace" in it and select **Remove from Recent List** to only keep workspace entries.
71
72 18 Jon Goldberg
#### civicrm-buildkit (mod_php)
73
The instructions above assume php-fpm.  To also debug mod_php (e.g. civicrm-buildkit), do the following:
74
* Use the same configuration file as under "Web Browser", but at `/etc/php/7.4/apache2/conf.d/xdebug.ini`.
75
* Edit `/etc/php/7.4/apache2/conf.d/xdebug.ini` and change the client port from `9000` to `9001`.
76
77 14 Jon Goldberg
#### Command Line (phpunit)
78
79 1 Jon Goldberg
* You need to have XDebug otherwise configured for CLI.  Use the same configuration file as under "Web Browser", but at `/etc/php/7.4/cli/conf.d/xdebug.ini`.
80 15 Jon Goldberg
 * Also change `xdebug.mode=debug,develop` to avoid some unnecessary warning noise.
81 14 Jon Goldberg
82 5 Jon Goldberg
* You need to start a debugging session in VS Code with "Listen for XDebug".
83 1 Jon Goldberg
* Depending on your VS Code setup, you may need to listen on a different port (I can use the same port for FPM but not mod_php).
84 2 Jon Goldberg
85
Once you've got all that:
86 1 Jon Goldberg
```shell
87 15 Jon Goldberg
env CIVICRM_UF=UnitTests XDEBUG_SESSION=VSCODE phpunit7 /home/jon/local/civicrm-buildkit/build/dmaster/web/sites/all/modules/civicrm/tests/phpunit/CRM/Core/BAO/ActionScheduleTest.php --filter testMembershipJoinDateMinutesUnit
88 2 Jon Goldberg
```
89 6 Jon Goldberg
90 30 Jon Goldberg
#### phpunit for extensions:
91 46 Jon Goldberg
For core extensions:
92 30 Jon Goldberg
```shell
93
CIVICRM_UF=UnitTests phpunit8 --bootstrap ext/afform/mock/tests/phpunit/bootstrap.php ext/afform/mock/tests/phpunit/api/v4/AfformContactUsageTest.php 
94
```
95
96 31 Jon Goldberg
For non-core extensions, from the extension's root folder. Note the use of `env XDEBUG_SESSION=VSCODE` for step debugging, and `--filter` to limit the tests run.
97
```
98 1 Jon Goldberg
env XDEBUG_SESSION=VSCODE CIVICRM_UF=UnitTests phpunit8 --bootstrap tests/phpunit/bootstrap.php tests/phpunit/api/v3/Cdntaxreceipts/GenerateTest.php --filter testGenerate
99 46 Jon Goldberg
# If everything is in a default state, it could also be as easy as:
100
phpunit9 --filter testContributionCreate
101 31 Jon Goldberg
```
102
103 8 Jon Goldberg
### Command-line runs of standalone scripts
104 6 Jon Goldberg
```shell
105 13 Jon Goldberg
env XDEBUG_SESSION=VSCODE php myscript.php
106 6 Jon Goldberg
```
107 38 Jon Goldberg
Also works for `cv`, probably `drush` and `wp` too:
108
```shell
109
env XDEBUG_SESSION=VSCODE cv api NotificationLog.retry system_log_id=147597 
110
```
111 16 Jon Goldberg
112
### Debugging REST API calls in Ansible/curl
113 17 Jon Goldberg
Add an additional POST argument `XDEBUG_SESSION=VSCODE`.  In curl, just add `-d 'XDEBUG_SESSION=VSCODE'` anywhere in your command.
114
115
For Ansible, this might look like:
116 16 Jon Goldberg
117
```yaml
118
  - name: Shut up about Civi extensions (warnings only, 7 days)
119
    uri:
120
      url: "{{ primary_url }}/{{ endpoint }}"
121
      method: POST
122
      body:
123
        XDEBUG_SESSION: VSCODE
124
        entity: StatusPreference
125
        action: create
126
        json: "{{ {'name': 'checkExtensionsUpdates', 'ignore_severity': 3, 'hush_until': seven_days_hence } | to_json }}"
127
        api_key: "{{ crm_api_key }}"
128
        key: "{{ crm_site_key }}"
129
      body_format: form-urlencoded
130
      return_content: yes
131
```
132 23 Jon Goldberg
133
### Debugging in PHP `file_get_contents()` (e.g. `check_civicrm.php`)
134
Add `XDEBUG_SESSION=VSCODE` as a `GET` argument, it works even on a `POST` request. Pairs well with a remote debugging session.
135
e.g.:
136
```php
137
$url = "$prot://$host_address/$path/System/check?XDEBUG_SESSION=VSCODE";
138
```
139 24 Brienne Kordis
140
### Debugging JavaScript
141
142
While you can open up the Developer Tools on a browser  (by right clicking on the window and then clicking **Inspect**) and debug the code directly there, it might be preferable to set up a debugging environment within an IDE, i.e. Visual Studio Code.  To do so:
143
144 27 Brienne Kordis
1. Open up your launch.json file (Need to set one up? There are [non-civibuild](https://hq.megaphonetech.com/projects/commons/wiki/Launchjson_for_non-civibuild_sites) and [Civibuild](https://hq.megaphonetech.com/projects/commons/wiki/Launchjson_for_civibuild_sites) options)
145 24 Brienne Kordis
1. Within the  `”configurations:”` array, add a comma after the last curly brace and then paste in:
146
147
``` json
148
    {
149
      "type": "msedge",
150
      "request": "attach",
151
      "name": "Attach to browser",
152
      "port": 9222
153
    }
154
```
155
   * If you’d prefer to debug on chrome, use `”type”: “chrome”`
156
1. Within your terminal, run the following command:
157
158
```bash
159 26 Brienne Kordis
/usr/bin/google-chrome --remote-debugging-port=9222 –user-data-dir=remote-debug-profile
160 24 Brienne Kordis
```
161
  * `/usr/bin/google-chrome` is the path of the Google Chrome Binary on Linux. For other operating systems, check out this [comment](https://forum.katalon.com/t/unknown-error-cannot-find-chrome-binary/9008/5), but note that the exact name might be different (i.e. google-chrome1 vs google-chrome). You can always `cd`  through the path it recommends to find the exact match for either Chrome or MSEdge.
162
163
1. Within VS Code, go to the Run and Debug tab, and from the drop down menu at the top, select “Attach to browser” and start the debugger. 
164
   * Note that the command given in the previous step is configured to open up a new browser, but these arguments (and more) can be customized. See the [documentation](https://code.visualstudio.com/docs/nodejs/browser-debugging#_launch-configuration-attributes)
165
166
1. The new browser window (or tab, depending on your settings) is now configured to be the debuggee-yes, that’s the technical term- so you can set breakpoints and debug within VS Code!
167 32 Jon Goldberg
168
### Running Drupal 9+ tests
169
The [Mink setup](https://docs.civicrm.org/dev/en/latest/testing/mink/) instructions worked quite well.
170
I then also ran:
171
```
172
composer require drupal/webform
173
composer require drupal/webform_civicrm
174 33 Jon Goldberg
composer require drupal/token
175 32 Jon Goldberg
composer require semperit/minkcivicrmhelpers
176
```
177 33 Jon Goldberg
178
Looking at CiviCARROT logs on the Webform-CiviCRM Github was helpful to figure those out.
179 34 Jon Goldberg
180
For permissions reasons, you have to run as the www-data user (this is set up with `mod_php`, not `php-fpm`):
181
```shell
182 44 Jon Goldberg
zabuntu: ~/local/wfc-testing/web/core » sudo -u www-data ../../vendor/bin/phpunit -c $HOME/local/wfc-testing/phpunit.xml ../modules/contrib/webform_civicrm/tests/src/FunctionalJavascript/ContributionPayLaterTest.php --filter testSubmitContribution
183 45 Jon Goldberg
# with debugging:
184
sudo -u www-data env XDEBUG_SESSION=VSCODE ../../vendor/bin/phpunit -v -c $HOME/local/wfc-testing/phpunit.xml ../modules/contrib/webform_civicrm/tests/src/FunctionalJavascript/EventTest.php --filter testParticipantCount
185 34 Jon Goldberg
```
186 45 Jon Goldberg
187
#### Troubleshooting
188
* If you get `RuntimeException: The provided database connection in SIMPLETEST_DB contains CiviCRM tables, use a different database.` then drop and recreate the test database.  You can check it for sure in `<projectroot>/web/core/phpunit.xml.dist` but it should be `wfc-testing`.
189
* Is `chromedriver` a current version, and did you start it? `chromedriver --port=4444` (in whatever directory you downloaded `chromedriver`.)
190
* `phpunit -v` will tell you why a test is "risky".  Buuuuut it's probably because `chromedriver` isn't running.
191 35 Brienne Kordis
192
### Finding an entry point to debug 
193
If a better one can't be found in an error log/message, use these steps to start debugging:
194
1. ssh into the server
195
1. change to root user
196
1. `cd /var/log/apache2`
197 36 Brienne Kordis
1. `nano other_vhosts_access.log`
198 35 Brienne Kordis
1. search for your IP address ( you can type "What's my IP address?" into Google if you don't know it)
199
1. find the relevant line(s) with your IP address and grab the civicrm path from the url
200
1. open up mysql (`cv sql`) and run `select * from civicrm_menu where path = '[civicrm path]';`
201 36 Brienne Kordis
1. look at the access arguments, but we care most about the `page_callback` column which lists the civicrm class that is loaded at that path
202 35 Brienne Kordis
1. open up that class in the codebase and use the buildForm hook as the entry point for debugging