Skip to content

Testing And Debugging

Vasu Bhog edited this page Sep 12, 2022 · 7 revisions

How to debug the extension and its components is covered below. This doc is a work-in-progress, please update as needed.

As discussed in Architecture, the extension is split into a few separate parts (core extension, backing service, and UI front end). Right now this means that debugging and testing instructions vary for each section. We've covered each below, but in summary:

Extension code

Anything to do with command palette integration, routing, initialization is in the core extension. Start with this before looking in other areas

UI Code

Anything in the UI will likely be the Results View section

Service code

When you need to dig into complex behavior (e.g. why is there an issue in Connectivity, Intellisense, Query Execution) this code is all in the service layer.

Debugging

Debugging extension-side code

Debugging our extension code is fairly straightforward:

  • Follow the Contributing steps to set up the project, restore dependencies and build.
  • Once this is working, in VSCode navigate to the Debug tab. Choose Launch Extension and it will open a new VSCode instance with the extension available. You can set breakpoints and capture events easily.
    • A good place to start is src/controllers/mainController.ts. The activate() function sets up all command routing so you can find relevant entry points to the code from there

Debugging results view code

The results view actually runs as a WebView component, meaning it's basically hosted in its own web page. Debugging requires use of a browser such as Chrome, or potentially the Chrome Debugger extension for VSCode (not yet explored).

You'll need the URL for our WebView to attach and debug. This is in the format localhost:{port}/root?uri={uri}. Right now, setting breakpoints is the only supported way to break in and debug.

Prerequisite: Setting breakpoints

  • For port number, open ssrc/controllers/localWebService.ts, add breakpoint to the start() method and note the port. This value will change each time you launch the extension
  • For uri, open src/models/SqlOutputContentProvider.ts. Add breakpoint to the provideTextDOcumentContent method and capture the encodedUri value. This value is constant so long as you use the same file for testing.

Debugging results in the browser

To step through, you need to:

  • Launch the extension in debug mode as mentioned above
  • Open a .sql file, connect and execute a query using ctrl+shift+e.
  • You should hit the breakpoints you set to capture the port and URI.
  • Combine these in the format localhost:{port}/root?uri={uri}, and paste this address into your browser
  • Open the developer tools in the browser, and you can see your Sources and even navigate to the Typescript thanks to source mapping
  • Set breakpoints as you would for any application

Making changes while debugging

Changes can be make inside the browser or in VS Code. To see the changes, reload the web page and interact with the view

  • You can even change the backing source code and reload to see changes for a quick debug loop. Do remember that you'll be debugging TypeScript so you might need to change the contents in a .js file in the out directory, or run gulp html:compile-src to update just the source code.

Launching the extension & capturing the URL

Debugging SQL Tools Service code

The SQL Tools Service is the backing application use to handle most requests (e.g. Connection, Intellisense, Query Execution & Results processing). For anything more than simple extension-side changes, you may need to start testing this project. We recommend you primarily debug this by launching relevant unit tests and stepping through the code from them, since this is by far the simplest method. If it's an integration issue you might need to debug both the mssql extension and the sqltoolsservice at once - the instructions below cover this scenario, but please consider just writing a unit test for your new scenarios.

To debug, you need to

  • Build your own service and copy to the extension:
    • Follow the instructions at https://github.com/Microsoft/sqltoolsservice/wiki to build the source code for the extension.
    • Copy the contents of the <root>/bin/debug/netcoreapp1.0/<OSVersion> folder.
    • Paste these contents into the MSSQL Extensions's sqltoolsservice/<version>/<OSVersion> folder.
      • Note: these are a subset of the DLLs used in the application. However since your dependencies should be the same, this is mostly fine. In the small set of cases where you are making bigger changes, with new SMO dependencies, you'll need to run dotnet publish, copy the contents of the publish folder instead, and then copy over the .pdb files to aid in debugging
  • Launch the mssql extension in debug mode, then attach to the backing service
    • You should have 1 VSCode open with the vscode-mssql extension code ready for launch, and another VSCode or Visual Studio instance with the sqltoolsservice code ready to be debugged. We will first launch the extension, then attach the sqltoolsservice instance to the backing executable.
    • Go to the debug tab in VSCode and click Launch Extension to launch an instance of VSCode with the extension ready for use
    • Launch and activate the extension by opening a SQL file. This will in turn launch our Microsoft.SqlTools.ServiceLayer.exe application
    • Find the PID of the process by opening Task Manager (Windows), Activity Monitor (macOS), etc. and
    • In the other VSCode/Visual Studio instance with the sqltoolsservice code, Go to Debug -> Attach to Process and select the application, or for VSCode choose PID for the Microsoft.SqlTools.ServiceLayer.exe application
    • Set breakpoints as desired, and run VSCode scenarios. You should see your breakpoints getting hit as usual

Testing

Before committing code we require all tests to pass. There are 3 main sections to the MSSQL plugin, all with separate tests.

Command line testing

Testing Extension and UI code

Using gulp test from the command line will run all tests for the extension and the HTML Results View.

Notes:

  1. For VSCode tests to run from a commandline all VSCode instances must be closed.
  2. There is a problem at times when running the html tests can fail if you have a chrome session open. If you have problems with the karma tests close any chrome sessions you have open.
  3. If you continue to have problems with the html tests you can change the single run variable in the karma conf to false, comment out the browsers field and from gulp html:test. This will launch the karma server but not launch the browser to run the tests. Then open a chrome session and navigate to the url karma prints in console. This will run the tests.

Testing SQL Tools Service code

The majority of our code is actually in the SQL Tools Service service application. This is a .Net Core-based application running on each platform. It has a full set of xUnit tests runnable using dotnet test against that repository. Check out instructions in that repository for full information.

Test in VSCode

Testing Extension inside VSCode

  • Build the project
  • Go to the debug section, and choose the Launch Tests option
  • Results are shown in the Debug Console (ctrl+shift+y to view)

Breakpoints inside tests

For some reason, breakpoints inside the product code will only work from test if you:

  • Add a breakpoint into the relevant test that call product code
  • Step into product code once. After this, it will work for all product code - it seems that it hooks the require command after this but otherwise the source isn't instrumented for breakpoints.

Test failures if breakpoints are used

Tests have a 200ms timeout. Therefore if you add a breakpoint, the test will fail. To verify the test passes again, remove the breakpoint and re-run the test.

Results View / Angular tests

Currently, there is no support for running these tests integrated with debugging in VSCode. Mostly the current process is command-line-based, with some limited support for debugging inside Chrome.

SQL Tools Service Tests

Debugging is supported in VSCode so long as you have the C# extension installed. Usually, this is on a per-test basis

Stubbing vscode/azdata/library APIs

Further information can be found here.