Skip to content

Fixing JSON property accessor to attempt user settings directory creation on the first write operation - #2387

Merged
Dongbo Wang (daxian-dbw) merged 1 commit into
PowerShell:masterfrom
mirichmo:mirichmo/delayed-creation-of-json-properties
Oct 8, 2016
Merged

Dongbo Wang (daxian-dbw) merged 1 commit into
PowerShell:masterfrom
mirichmo:mirichmo/delayed-creation-of-json-properties

Conversation

@mirichmo

@mirichmo Mike Richmond (mirichmo) commented Sep 29, 2016 •

Copy link
Copy Markdown
Member

Fixes #2037 and #2205
I addressed the issue by delaying user settings directory creation until a write operation takes place. At that point, the console should be up and running, so it is safe to let errors propagate for eventual display to the user. This should address all startup scenarios regardless of hosting technique.

I also wrote some new tests to validate basic file operations on the user settings PowerShellProperties.json file.

@msftclas

Hi Mike Richmond (@mirichmo), I'm your friendly neighborhood Microsoft Pull Request Bot (You can call me MSBOT). Thanks for your contribution!


It looks like you're a Microsoft contributor (Mike Richmond). If you're full-time, we DON'T require a Contribution License Agreement. If you are a vendor, please DO sign the electronic Contribution License Agreement. It will take 2 minutes and there's no faxing! https://cla.microsoft.com.

TTYL, MSBOT;

@msftclas

Hi Mike Richmond (@mirichmo), I'm your friendly neighborhood Microsoft Pull Request Bot (You can call me MSBOT). Thanks for your contribution!


It looks like you're a Microsoft contributor (Mike Richmond). If you're full-time, we DON'T require a Contribution License Agreement. If you are a vendor, please DO sign the electronic Contribution License Agreement. It will take 2 minutes and there's no faxing! https://cla.microsoft.com.

TTYL, MSBOT;

@mirichmo
Mike Richmond (mirichmo) force-pushed the mirichmo/delayed-creation-of-json-properties branch 6 times, most recently from 41b2fe9 to 79a50e2 Compare October 3, 2016 22:33
@mirichmo

Copy link
Copy Markdown
Member Author

Dongbo Wang (@daxian-dbw) and Andy Jordan (@andschwa) Please review

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks good to me, thanks!

@lzybkr Jason Shirk (lzybkr) left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The filename PropertyAccessor.Tests.ps1 is too generic, I'd assume that tests something else.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

There is a race condition here - another process could create the directory after the Exists test fails. You should probably catch the appropriate exception from CreateDirectory and ignore it if that happens.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

CreateDirectory doesn't throw an exception if it already exists. It just returns the directory.
https://msdn.microsoft.com/en-us/library/54a0at6s(v=vs.110).aspx

Now the question becomes... is the check if it exists necessary? It feels like it is slightly faster to check first in scenarios where the directory already exists.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Indeed - CreateDirectory will check if the directory exists, so we can remove our redundant check.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Maybe $IsNotSkipped = $IsWindows?
Or even better, why not just use $IsWindows without $IsNotSkipped? I don't feel this variable helps readability.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

#Closed

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

$shouldSkipTest is not used in this test.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

fixed

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

#Closed

@daxian-dbw Dongbo Wang (daxian-dbw) Oct 4, 2016 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Assuming the first module path is the user module path is fragile. This may not work when a dev is running the test with a profile. I think it's safer to construct the path to the user property.json file. That should be easy given that the test only runs on win-platform.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

#Closed

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Minor question: is it really necessary to create the file when it's requested to remove a property? If the file doesn't exist, then no action needed, and the removal will be sure successful.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Good point. I removed it

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

#Closed

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

$originalDefaultParameterValues = $PSDefaultParameterValues.Clone()
$IsNotSkipped = ($IsWindows -eq $true);
$PSDefaultParameterValues["it:skip"] = !$IsNotSkipped
$ShouldSkipTest = !$IsNotSkipped

I think all these can be moved to BeforeAll { } and $global:PSDefaultParameterValues = $originalDefaultParameterValues can be moved to AfterAll { }.
Some examples:
PowerShell\test\powershell\Language\Scripting\I18n.Tests.ps1
PowerShell\test\powershell\Modules\Microsoft.PowerShell.Diagnostics\Get-WinEvent.Tests.ps1

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This is the preferred technique because it results in less duplication when there are multiple Describe blocks within the try-finally.
For background, see the discussion in PR #2335

@daxian-dbw Dongbo Wang (daxian-dbw) Oct 5, 2016 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for the link to the discussion. I think it depends on how many Describe sections you expect to be in a file. If there is just one Describe, then it's cleaner to have it in BeforeAlll and AfterAll. But I'm fine keep the try/finally as it's possible that we will add more Describe sections later. #Closed

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

original the
Should be the original

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

#Closed

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Use the powershell way to do it: if (-not $backupPropertiesFile)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

#Closed

@daxian-dbw Dongbo Wang (daxian-dbw) Oct 4, 2016 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we want to create the directory C:\Users\dongbow\Documents when it already exists?
Probably it should be

elseif (-not (Test-Path $userSettingsDir))
{
    $null = New-Item -Type Directory -Path $userSettingsDir -Force -ErrorAction SilentlyContinue
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Fixed

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

#Closed

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Maybe add one more check to verify that read operation should not create the file.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Added

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

#Closed

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this line seems not needed given the same command will run in BeforeEach { }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

#Closed

@mirichmo
Mike Richmond (mirichmo) force-pushed the mirichmo/delayed-creation-of-json-properties branch 2 times, most recently from 8e36415 to a82ec2b Compare October 5, 2016 20:57

@daxian-dbw Dongbo Wang (daxian-dbw) Oct 5, 2016 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for taking Nano/IoT PS into account. Now it makes sense to have $skipTest = !$IsWindows -or $IsInbox, because the if ($IsWindows) below should actually be if (!skipTest).

@daxian-dbw Dongbo Wang (daxian-dbw) Oct 5, 2016 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You know what, we should exclude the FullCLR powershell as well 😄 Ah, I guess $isInbox already covers that.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

#Closed

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It should be if (!skipTest)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

#Closed

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It should be if (!skipTest)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

#Closed

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It should be if (!skipTest)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

#Closed

@mirichmo
Mike Richmond (mirichmo) force-pushed the mirichmo/delayed-creation-of-json-properties branch from a82ec2b to e7030dc Compare October 5, 2016 23:55

@daxian-dbw Dongbo Wang (daxian-dbw) left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM.

@daxian-dbw

Copy link
Copy Markdown
Member

Jason Shirk (@lzybkr) do you still have concerns on this PR? If not, I will merge it.

@daxian-dbw
Dongbo Wang (daxian-dbw) merged commit e188c99 into PowerShell:master Oct 8, 2016
@mirichmo
Mike Richmond (mirichmo) deleted the mirichmo/delayed-creation-of-json-properties branch October 10, 2016 16:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants