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

Update harness to use single robust virtual file system for tests. #20763

Merged
merged 73 commits into from
May 3, 2018
Merged

Conversation

rbuckton
Copy link
Member

@rbuckton rbuckton commented Dec 18, 2017

To better support the lib reference PR (#15780) and the ES3 lib PR (#16077) we needed to make a number of changes to our test harness to improve and consolidate our various approaches to emulating a file system. To that end, this PR introduces a much more robust virtual file system implementation that supports additional features needed by our various test runners including:

  • Symbolic links
  • File/Directory watching
  • File stats
  • Resolving paths/files to the real file system
  • File/Directory metadata
  • VFS shadowing (allows the use of a shared VFS where changes in a shadowed VFS do not affect the real VFS)

As of this PR, the Compiler/Conformance, Project, and FourSlash runners all now use the VFS. In addition all existing unit tests that used "virtualFileSystemWithWatch" have been migrated over to the single VFS implementation.

@RyanCavanaugh
Copy link
Member

Can we do a one-time hack to make the 1,400ish baseline diffs go away, then do a separate PR to un-hack that so we can be sure no baselines are changing unexpectedly due to the VFS?

@@ -200,7 +196,7 @@ function handleTestConfig() {

// TODO: project tests don"t work in the browser yet
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this still the case? Both the projects runner and browser IO impl got major overhauls.

programFileNames,
options);

// const fileOutputs = compilation.outputs.map(output => output.asGeneratedFile());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the commented-out code here required in some way?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not anymore, I'll remove it.

@@ -0,0 +1,256 @@
/// <reference path="./harness.ts" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we are removing all triple-slash references currently in favor of tsconfig.josn file list

return a < b ? -1 : +1;
}

export function compareStrings(a: string, b: string, ignoreCase: boolean): number {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how are these diffrent from the ones in src\compiler\core?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They aren't. Originally I intended to attempt to divorce the harness from the compiler to improve time-to-test by reducing compilation time, but with @RyanCavanaugh's forthcoming changes for project references this is no longer an issue. I am in the process of switching over to using existing functions, which should show up in the next few commits.

@@ -0,0 +1,3 @@
namespace core {
export function identity<T>(v: T): T { return v; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think we have this in core already.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Planning to remove. See #20763 (comment) for more information.

break;

// WhiteSpace
case 0x0009: // <TAB> tab
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isWhiteSpaceSingleLine?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function will be removed. See #20763 (comment) for more information.

return lines;
}

export function computeLineStarts(text: string): LineStarts {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should already have this in scanner?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Planning to remove. See #20763 (comment) for more information.

@@ -0,0 +1,4 @@
/// <reference path="./core/functions.ts" />
/// <reference path="./core/comparers.ts" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i would put these in tsconfig.json instead.

/**
* Combines two or more paths. If a path is absolute, it replaces any previous path.
*/
export function combine(path: string, ...paths: string[]) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

many of the helpers here have counterparts in core, can we reuse?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, where possible. I like the logical grouping of path-related functionality in the vpath namespace (along with the more concise naming), and wonder if it would make sense to similarly consolidate related functionality in the compiler to reduce the volume of functions that show up in completions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that is fine, but as we chatted offline, i think this restructuring should be done in the core, and not in the tests, and not by introducing a set of duplicate implementations.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've removed most of the strict duplications already. What remains are places where the implementations are divergent. When you say "core", are you speaking of a new src/core folder for those shared dependencies or refactoring existing functions in src/compiler/core.ts to support the needs of both compiler and harness? I haven't made this change yet as I didn't want to bloat compiler with harness-specific functionality unnecessarily.

}
}

export class SortedSet<T> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i am not seeing this used anywhere.. is it needed?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was originally used as part of the file watcher functionality.

@rbuckton
Copy link
Member Author

@mhegazy, can you take another look?

private readonly _executingFilePath: string | undefined;
private readonly _env: Record<string, string> | undefined;

constructor(vfs: vfs.FileSystem, { executingFilePath, newLine = "\r\n", env }: SystemOptions = {}) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you have this another layer? Why not make vfs.FileSystem implement ts.System ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather keep them separate so that FileSystem is purely a file system abstraction. Breaking things down into multiple components is more maintainable and better delineates functionality. We already have too many monolithic dependencies in the compiler, and we don't always need a full System implementation (which is why we have so many independent *Host types).

* A fake `ts.CompilerHost` that leverages a virtual file system.
*/
export class CompilerHost implements ts.CompilerHost {
public readonly sys: System;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also this one.. Seems like this should just use createCompilerHost API on system instead of having another abstraction.

Copy link
Member Author

@rbuckton rbuckton Apr 27, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Except we need to customize the compiler host for certain operations:

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly, it'd be nice if fakes.CompilerHost could inherit from fakes.System except they differ in their definitions of useCaseSensitiveFileNames.

@rbuckton
Copy link
Member Author

rbuckton commented May 1, 2018

I have a few more changes pending, as I've almost finished unifying the path logic between vpath and core.

@rbuckton
Copy link
Member Author

rbuckton commented May 2, 2018

@mhegazy can you take one more look after the last set of changes. I've cleaned up our path handling logic and was able to unify most of the path handling features in vpath and core.

@rbuckton rbuckton merged commit 56648ad into master May 3, 2018
@rbuckton rbuckton deleted the vfs branch May 3, 2018 17:25
@ghost ghost mentioned this pull request May 3, 2018
@microsoft microsoft locked and limited conversation to collaborators Jul 31, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants