Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Testing for saveOnStart PR #2564

Draft
wants to merge 41 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
7a46bac
Save dirty documents before evaluating queries
dbartol Jun 21, 2023
de38b1f
Stop overriding saveBeforeStart for `ql` language
dbartol Jun 21, 2023
1da96c5
Allow `languageId:` scopes in tests
dbartol Jun 21, 2023
b182d7a
Fix PR feedback
dbartol Jun 21, 2023
0bd0bf1
_Correctly_ emulate VS Code's `saveBeforeStart`
dbartol Jun 22, 2023
2397ead
Fix test failure
dbartol Jun 22, 2023
6bdc095
Fix test failure
dbartol Jun 22, 2023
ec71f53
Fix more test failures
dbartol Jun 22, 2023
ff2d67d
Merge remote-tracking branch 'origin/main' into dbartol/save-before-s…
dbartol Jun 22, 2023
3705464
Seriously, I think they'll pass for reals this time.
dbartol Jun 22, 2023
d9a1aa8
Just kidding, _this_ time it's fixed for reals
dbartol Jun 22, 2023
8ff1db1
Fix bad diff
dbartol Jun 28, 2023
d27efb3
Merge remote-tracking branch 'origin/main' into dbartol/save-before-s…
dbartol Jun 29, 2023
adf0ccb
Disable workspace trust for CLI integration tests
dbartol Jun 29, 2023
9fd0697
Fix format
dbartol Jun 29, 2023
dbd257e
More logging
dbartol Jun 29, 2023
bf36051
Increase timeout
dbartol Jun 29, 2023
9f077b0
Run Jest in verbose mode
dbartol Jun 29, 2023
53a51ab
More logging
dbartol Jun 29, 2023
b859bca
Even more logging
dbartol Jun 30, 2023
1f5b391
Dump dirty documents
dbartol Jun 30, 2023
81b2407
Log content of untitled docs
dbartol Jun 30, 2023
c25410e
Log config settings
dbartol Jun 30, 2023
c70ec71
Try different default for saveBeforeStart
dbartol Jun 30, 2023
e80a06c
Try grabbing screenshot
dbartol Jun 30, 2023
6fc0a03
Always upload screenshots
dbartol Jun 30, 2023
eb3c0a2
Set default saveBeforeStart for QL
dbartol Jun 30, 2023
84d40fe
Log active language ID
dbartol Jun 30, 2023
2c69a31
More screenshots
dbartol Jun 30, 2023
53a0778
Back to previous timeout
dbartol Jun 30, 2023
cb3939e
Only create dirty files for commands that don't go through the VS Cod…
dbartol Jul 3, 2023
97715dc
Periodic screenshots
dbartol Jul 7, 2023
f17954f
Better periodic screenshots
dbartol Jul 7, 2023
a22a950
Fix unused
dbartol Jul 7, 2023
b18b3e5
Periodic screenshots step
dbartol Jul 7, 2023
e2e11cc
Screenshots
dbartol Jul 7, 2023
6d9a0e1
Use runner temp directory
dbartol Jul 11, 2023
e5dee84
Screenshots on Windows only
dbartol Jul 11, 2023
800f818
Add explanatory comment
dbartol Jul 11, 2023
6e17fda
Comment about temp directory
dbartol Jul 11, 2023
6b2373d
Delete unneeded files
dbartol Jul 11, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -273,3 +273,10 @@ jobs:
if: matrix.os == 'windows-latest'
run: |
npm run test:cli-integration

- name: Upload screenshots (Windows)
if: always()
uses: actions/upload-artifact@v2
with:
name: screenshots
path: extensions/ql-vscode/*.png
11 changes: 8 additions & 3 deletions extensions/ql-vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,12 @@
],
"contributes": {
"configurationDefaults": {
"[codeql]": {
"debug.saveBeforeStart": "nonUntitledEditorsInActiveGroup",
"editor.wordBasedSuggestions": false
},
"[ql]": {
"debug.saveBeforeStart": "nonUntitledEditorsInActiveGroup",
"editor.wordBasedSuggestions": false
},
"[dbscheme]": {
Expand Down Expand Up @@ -246,8 +251,8 @@
},
"codeQL.runningQueries.autoSave": {
"type": "boolean",
"default": false,
"description": "Enable automatically saving a modified query file when running a query."
"description": "Enable automatically saving a modified query file when running a query.",
"markdownDeprecationMessage": "This property is deprecated and no longer has any effect. To control automatic saving of documents before running queries, use the `debug.saveBeforeStart` setting."
},
"codeQL.runningQueries.maxQueries": {
"type": "integer",
Expand Down Expand Up @@ -1726,7 +1731,7 @@
"test:vscode-integration:activated-extension": "jest --projects test/vscode-tests/activated-extension",
"test:vscode-integration:no-workspace": "jest --projects test/vscode-tests/no-workspace",
"test:vscode-integration:minimal-workspace": "jest --projects test/vscode-tests/minimal-workspace",
"test:cli-integration": "jest --projects test/vscode-tests/cli-integration",
"test:cli-integration": "jest --projects test/vscode-tests/cli-integration --verbose",
"update-vscode": "node ./node_modules/vscode/bin/install",
"format": "prettier --write **/*.{ts,tsx} && eslint . --ext .ts,.tsx --fix",
"lint": "eslint . --ext .js,.ts,.tsx --max-warnings=0",
Expand Down
8 changes: 8 additions & 0 deletions extensions/ql-vscode/screenlog.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Write-Host "Starting to take periodic screenshots..."
for ($Elapsed = 0; $Elapsed -lt (20 * 60); $Elapsed += 30)
{
Write-Host "Taking screenshot at ${Elapsed} seconds ('elapsed_${Elapsed}.png')"
.\screenshot.bat "elapsed_${Elapsed}.png"
Write-Host "Sleeping for 30 seconds..."
Start-Sleep -Seconds 30
}
275 changes: 275 additions & 0 deletions extensions/ql-vscode/screenshot.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,275 @@
// 2>nul||@goto :batch
/*
:batch
@echo off
setlocal

:: find csc.exe
set "csc="
for /r "%SystemRoot%\Microsoft.NET\Framework\" %%# in ("*csc.exe") do set "csc=%%#"

if not exist "%csc%" (
echo no .net framework installed
exit /b 10
)

if not exist "%~n0.exe" (
call %csc% /nologo /r:"Microsoft.VisualBasic.dll" /out:"%~n0.exe" "%~dpsfnx0" || (
exit /b %errorlevel%
)
)
%~n0.exe %*
endlocal & exit /b %errorlevel%

*/

// reference
// https://gallery.technet.microsoft.com/scriptcenter/eeff544a-f690-4f6b-a586-11eea6fc5eb8

using System;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Drawing.Imaging;
using System.Collections.Generic;
using Microsoft.VisualBasic;


/// Provides functions to capture the entire screen, or a particular window, and save it to a file.

public class ScreenCapture
{

/// Creates an Image object containing a screen shot the active window

public Image CaptureActiveWindow()
{
return CaptureWindow(User32.GetForegroundWindow());
}

/// Creates an Image object containing a screen shot of the entire desktop

public Image CaptureScreen()
{
return CaptureWindow(User32.GetDesktopWindow());
}

/// Creates an Image object containing a screen shot of a specific window

private Image CaptureWindow(IntPtr handle)
{
// get te hDC of the target window
IntPtr hdcSrc = User32.GetWindowDC(handle);
// get the size
User32.RECT windowRect = new User32.RECT();
User32.GetWindowRect(handle, ref windowRect);
int width = windowRect.right - windowRect.left;
int height = windowRect.bottom - windowRect.top;
// create a device context we can copy to
IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
// create a bitmap we can copy it to,
// using GetDeviceCaps to get the width/height
IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height);
// select the bitmap object
IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap);
// bitblt over
GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, GDI32.SRCCOPY);
// restore selection
GDI32.SelectObject(hdcDest, hOld);
// clean up
GDI32.DeleteDC(hdcDest);
User32.ReleaseDC(handle, hdcSrc);
// get a .NET image object for it
Image img = Image.FromHbitmap(hBitmap);
// free up the Bitmap object
GDI32.DeleteObject(hBitmap);
return img;
}

public void CaptureActiveWindowToFile(string filename, ImageFormat format)
{
Image img = CaptureActiveWindow();
img.Save(filename, format);
}

public void CaptureScreenToFile(string filename, ImageFormat format)
{
Image img = CaptureScreen();
img.Save(filename, format);
}

static bool fullscreen = true;
static String file = "screenshot.bmp";
static System.Drawing.Imaging.ImageFormat format = System.Drawing.Imaging.ImageFormat.Bmp;
static String windowTitle = "";

static void parseArguments()
{
String[] arguments = Environment.GetCommandLineArgs();
if (arguments.Length == 1)
{
printHelp();
Environment.Exit(0);
}
if (arguments[1].ToLower().Equals("/h") || arguments[1].ToLower().Equals("/help"))
{
printHelp();
Environment.Exit(0);
}

file = arguments[1];
Dictionary<String, System.Drawing.Imaging.ImageFormat> formats =
new Dictionary<String, System.Drawing.Imaging.ImageFormat>();

formats.Add("bmp", System.Drawing.Imaging.ImageFormat.Bmp);
formats.Add("emf", System.Drawing.Imaging.ImageFormat.Emf);
formats.Add("exif", System.Drawing.Imaging.ImageFormat.Exif);
formats.Add("jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
formats.Add("jpeg", System.Drawing.Imaging.ImageFormat.Jpeg);
formats.Add("gif", System.Drawing.Imaging.ImageFormat.Gif);
formats.Add("png", System.Drawing.Imaging.ImageFormat.Png);
formats.Add("tiff", System.Drawing.Imaging.ImageFormat.Tiff);
formats.Add("wmf", System.Drawing.Imaging.ImageFormat.Wmf);


String ext = "";
if (file.LastIndexOf('.') > -1)
{
ext = file.ToLower().Substring(file.LastIndexOf('.') + 1, file.Length - file.LastIndexOf('.') - 1);
}
else
{
Console.WriteLine("Invalid file name - no extension");
Environment.Exit(7);
}

try
{
format = formats[ext];
}
catch (Exception e)
{
Console.WriteLine("Probably wrong file format:" + ext);
Console.WriteLine(e.ToString());
Environment.Exit(8);
}


if (arguments.Length > 2)
{
windowTitle = arguments[2];
fullscreen = false;
}

}

static void printHelp()
{
//clears the extension from the script name
String scriptName = Environment.GetCommandLineArgs()[0];
scriptName = scriptName.Substring(0, scriptName.Length);
Console.WriteLine(scriptName + " captures the screen or the active window and saves it to a file.");
Console.WriteLine("");
Console.WriteLine("Usage:");
Console.WriteLine(" " + scriptName + " filename [WindowTitle]");
Console.WriteLine("");
Console.WriteLine("filename - the file where the screen capture will be saved");
Console.WriteLine(" allowed file extensions are - Bmp,Emf,Exif,Gif,Icon,Jpeg,Png,Tiff,Wmf.");
Console.WriteLine("WindowTitle - instead of capture whole screen you can point to a window ");
Console.WriteLine(" with a title which will put on focus and captuted.");
Console.WriteLine(" For WindowTitle you can pass only the first few characters.");
Console.WriteLine(" If don't want to change the current active window pass only \"\"");
}

public static void Main()
{
User32.SetProcessDPIAware();

parseArguments();
ScreenCapture sc = new ScreenCapture();
if (!fullscreen && !windowTitle.Equals(""))
{
try
{

Interaction.AppActivate(windowTitle);
Console.WriteLine("setting " + windowTitle + " on focus");
}
catch (Exception e)
{
Console.WriteLine("Probably there's no window like " + windowTitle);
Console.WriteLine(e.ToString());
Environment.Exit(9);
}


}
try
{
if (fullscreen)
{
Console.WriteLine("Taking a capture of the whole screen to " + file);
sc.CaptureScreenToFile(file, format);
}
else
{
Console.WriteLine("Taking a capture of the active window to " + file);
sc.CaptureActiveWindowToFile(file, format);
}
}
catch (Exception e)
{
Console.WriteLine("Check if file path is valid " + file);
Console.WriteLine(e.ToString());
}
}

/// Helper class containing Gdi32 API functions

private class GDI32
{

public const int SRCCOPY = 0x00CC0020; // BitBlt dwRop parameter
[DllImport("gdi32.dll")]
public static extern bool BitBlt(IntPtr hObject, int nXDest, int nYDest,
int nWidth, int nHeight, IntPtr hObjectSource,
int nXSrc, int nYSrc, int dwRop);
[DllImport("gdi32.dll")]
public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int nWidth,
int nHeight);
[DllImport("gdi32.dll")]
public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
[DllImport("gdi32.dll")]
public static extern bool DeleteDC(IntPtr hDC);
[DllImport("gdi32.dll")]
public static extern bool DeleteObject(IntPtr hObject);
[DllImport("gdi32.dll")]
public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
}


/// Helper class containing User32 API functions

private class User32
{
[StructLayout(LayoutKind.Sequential)]
public struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
[DllImport("user32.dll")]
public static extern IntPtr GetDesktopWindow();
[DllImport("user32.dll")]
public static extern IntPtr GetWindowDC(IntPtr hWnd);
[DllImport("user32.dll")]
public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
[DllImport("user32.dll")]
public static extern IntPtr GetWindowRect(IntPtr hWnd, ref RECT rect);
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
public static extern int SetProcessDPIAware();
}
}
10 changes: 6 additions & 4 deletions extensions/ql-vscode/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,12 @@ export interface InspectionResult<T> {
workspaceFolderValue?: T;
}

const VSCODE_DEBUG_SETTING = new Setting("debug", undefined);
export const VSCODE_SAVE_BEFORE_START_SETTING = new Setting(
"saveBeforeStart",
VSCODE_DEBUG_SETTING,
);

const ROOT_SETTING = new Setting("codeQL");

// Global configuration
Expand Down Expand Up @@ -161,10 +167,6 @@ export const NUMBER_OF_TEST_THREADS_SETTING = new Setting(
RUNNING_TESTS_SETTING,
);
export const MAX_QUERIES = new Setting("maxQueries", RUNNING_QUERIES_SETTING);
export const AUTOSAVE_SETTING = new Setting(
"autoSave",
RUNNING_QUERIES_SETTING,
);
export const PAGE_SIZE = new Setting("pageSize", RESULTS_DISPLAY_SETTING);
const CUSTOM_LOG_DIRECTORY_SETTING = new Setting(
"customLogDirectory",
Expand Down
4 changes: 4 additions & 0 deletions extensions/ql-vscode/src/debugger/debugger-ui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { CoreQueryResults } from "../query-server";
import {
getQuickEvalContext,
QueryOutputDir,
saveBeforeStart,
validateQueryUri,
} from "../run-queries-shared";
import { QLResolvedDebugConfiguration } from "./debug-configuration";
Expand Down Expand Up @@ -73,6 +74,9 @@ class QLDebugAdapterTracker
}

public async quickEval(): Promise<void> {
// Since we're not going through VS Code's launch path, we need to save dirty files ourselves.
await saveBeforeStart();

const args: CodeQLProtocol.QuickEvalRequest["arguments"] = {
quickEvalContext: await getQuickEvalContext(undefined, false),
};
Expand Down