Code Monkey home page Code Monkey logo

zerodsc's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

zerodsc's Issues

Stacktrace should include resource files when a resource throws an exception

Consider this document:

$document = {
    Get-DscResource TestStub | Import-DscResource

    TestStub a @{
        Key = 'a'
        ThrowOnSet = 'always'
    }
}

Pester

The follow code creates instructions and invokes them using Pester:

Describe 'resource stack trace' {
    $h = @{}

    It 'create instructions' {
        $h.Instructions = ConfigInstructions Name $document
    }
    foreach ( $step in $h.Instructions )
    {
        It $step.Message {
            $step | Invoke-ConfigStep
        }
    }
}

Executing that code yields

Describing resource stack trace
 [+] create instructions 4.02s
 [+] Pretest: Test resource [TestStub]a 851ms
 [-] Configure: Set resource [TestStub]a 124ms
   RuntimeException: TestStub forced exception because ThrowOnSet=always
   RuntimeException: TestStub forced exception because ThrowOnSet=always
   MethodInvocationException: Exception calling "InvokeWithContext" with "2" arg
ument(s): "TestStub forced exception because ThrowOnSet=always"
   at Invoke-ConfigStep<Process>, C:\Program Files\WindowsPowerShell\Modules\Zer
oDSC\0.2.0\Functions\configInstructionsType.ps1: line 324
   at <ScriptBlock>, <No file>: line 20
 [+] Configure: Test resource [TestStub]a 294ms

Simple Command

The following code creates instructions and invokes them:

$instructions = ConfigInstructions Name $document
$instructions | Invoke-ConfigStep

Executing that code yields

    Phase Verb ResourceName  Progress
    ----- ---- ------------  --------
  Pretest Test [TestStub]a    Pending
Exception calling "InvokeWithContext" with "2" argument(s): "TestStub forced 
exception because ThrowOnSet=always"
At C:\Program Files\WindowsPowerShell\Modules\ZeroDSC\0.2.0\Functions\configIns
tructionsType.ps1:324 char:13
+             $result = $ConfigStep.Action.InvokeWithContext($functions ...
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : RuntimeException
 
Configure  Set [TestStub]a  Exception
Configure Test [TestStub]a     Failed

The Shortcoming

Note that in the above outputs the stacktrace does not mention the resource file from where the exception originated. In this case the originating file is C:\Program Files\WindowsPowerShell\Modules\ZeroDSC\0.2.0\DSCResources\TestStub\TestStub.psm1).

A resource invocation that throws an exception can cause endless loop.

Currently the config instructions enumerable does not catch exceptions that invoking a resource might throw. This can lead to an endless loop.

Repro

Running this code causes an endless loop.

$document = {
    Get-DscResource TestStub | Import-DscResource

    TestStub a @{
        Key = 'a'
        ThrowOnSet = 'always'
    }
}

$instructions = ConfigInstructions Name $document
$instructions |
    Invoke-ConfigStep

The above code results in an endless loop.

Solution

Exceptions thrown by resources should be caught, the resource marked as "failed" (or maybe "ExceptionThrown"), and then the exception re-thrown. If the resource is marked with a new value like "ExceptionThrown", the state machines should also be altered to raise and handle 'AtExceptionThrown' events.

Importing Multiple Versions of the Same DSC Resource should be Tested

I'm not sure whether ZeroDSC resource invokers behave correctly when multiple resource invokers of the same resource but with different versions are created. It should be confirmed that each resource invoker indeed imports the correct version. This should be tested for both MOF- and class-based resources. I think there is already an appropriate class-based test stub resource with multiple versions. Likely a new MOF-based test stub resource with multiple versions needs to be created for testing.

ConfigInstructions should throw an exception when DependsOn points to itself

Consider the following:

$document = {
    Get-DscResource TestStub | Import-DscResource

    TestStub a @{
        Key = 'a'
        DependsOn = '[TestStub]a'
    }
}

$instructions = ConfigInstructions Name $document

[TestStub]a depends on itself. I can't see any meaning to a normal resource depending on itself. A normal resource depending on itself almost certainly indicates a user error. Processing of [TestStub]a should throw an exception because it points to itself.

It's worth noting that an aggregate resource could depend on itself because it could count itself in whatever aggregation logic it is applying.

A test for this behavior is already mentioned in configDocumentType.Tests.ps1.

Earlier testing of parameter compatibility

Currently parameters specified in configuration documents are not checked for compatibility with the corresponding resource if and when the resource is invoked. Basic checking for parameter compatibility should be performed when the parameters are bound to the resource. That way parameter errors in configuration documents are detected as early as possible.

Add the AppVeyor badge

AppVeyor builds ZeroDSC but that is not obvious. The AppVeyor badge should be added to the root readme.md.

Recommend using latest release

The "Installing ZeroDSC" section currently recommends switching to the master branch. Instead it should recommend switching to the latest release tag.

Test-MofResourceType Inadvertently Unloads Module

This invokation of Import-Module in New-ClassResourceObject seems to re-import the module of the class resource on each invokation even if it has already been loaded. It seems to happen once per bound resource, so the bigger the configuration document the slower the creation of the instructions. Some resource modules are large enough that they take seconds to load. The modules should probably remain cached as they are imported, but they don't currently seem to be.

Should ZeroDSC export `Import-DscResource`?

PowerShell implements Import-DscResource as a dynamic keyword. ZeroDSC implements its own Import-DscResource as a function. It looks like either Import-DscResource is only available within the respective configuration scriptblocks where it is used. This means that ZeroDSC does not have to export its Import-DscResource to operate correctly. However, if Import-DscResource is not exported, neither help nor intellisense works for Import-DscResource.

Pros:

  • intellisense works
  • appears in Get-Command output
  • help Import-DscResource displays something

Cons:

  • pollutes the namespace
  • might cause problems with intellisense (although cursory tests seem to indicate that intellisense correctly distinguishes between the dynamic keyword and function)
  • users might mistake the help output as help for the dynamic keyword

One compromise is to put an explicit note about the dynamic keyword in the help output for the ZeroDSC Import-DscResource output. I'm leaning toward this option.

Invoking ConfigInstruction in two different runspaces cases ExceptionInGetEnumerator

Repro

  1. Open ISE
  2. Invoke ConfigInstructions Name {} in the REPL
  3. Open a second REPL tab in ISE.
  4. Invoke ConfigInstructions Name {} in the second REPL tab
  5. The following error is output:
format-default : The following exception occurred while trying to enumerate the collection: "The term 'New-ProgressNodes' is not recognized as the name of a cmdlet, 
function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.".
    + CategoryInfo          : NotSpecified: (:) [format-default], ExtendedTypeSystemException
    + FullyQualifiedErrorId : ExceptionInGetEnumerator,Microsoft.PowerShell.Commands.FormatDefaultCommand

Cause

The cause of this error seems to be PowerShell itself. When a module that implements an object that implements IEnumerator is loaded into two runspaces in the same process, then, in the second runspace no functions from the module are available from within .GetEnumerator().

There is a repro of this bug that is independent of ZeroDSC in the ToolFoundations repo.

Affected PowerShell Versions

Versions known to exhibit problem:

  • 5.0.10586.51
  • 5.0.10586.117

Versions known not to exhibit problem:

  • 5.1.14394.1000

Expected Resolution

It looks like PowerShell 5.0 has this problem but 5.1 does not. This issue should remain open until it has been confirmed that the GA version of PowerShell 5.1 indeed ships with this issue resolved.

Omit module-internal lines from stack trace when resource throws exception

This code

$document = {
    Get-DscResource TestStub | Import-DscResource

    TestStub a @{
        Key = 'a'
        ThrowOnSet = 'always'
    }
}

Describe 'resource stack trace' {
    $h = @{}

    It 'create instructions' {
        $h.Instructions = ConfigInstructions Name $document
    }
    foreach ( $step in $h.Instructions )
    {
        It $step.Message {
            $step | Invoke-ConfigStep
        }
    }
}

outputs

Describing resource stack trace
 [+] create instructions 14.46s
 [+] Pretest: Test resource [TestStub]a 1.28s
 [-] Configure: Set resource [TestStub]a 162ms
   RuntimeException: TestStub forced exception because ThrowOnSet=always
   at Set-TargetResource<Process>, C:\Users\un1\Documents\WindowsPowerShell\Modu
les\ZeroDSC\DSCResources\TestStub\TestStub.psm1: line 56
   at Invoke-MofResourceCommand<Process>, C:\Users\un1\Documents\WindowsPowerShe
ll\Modules\ZeroDSC\Functions\mofResourceInvokerType.ps1: line 105
   at _Invoke, C:\Users\un1\Documents\WindowsPowerShell\Modules\ZeroDSC\Function
s\mofResourceInvokerType.ps1: line 21
   at Invoke-ResourceCommand<Process>, C:\Users\un1\Documents\WindowsPowerShell\
Modules\ZeroDSC\Functions\resourceInvokerType.ps1: line 88
   at Invoke, C:\Users\un1\Documents\WindowsPowerShell\Modules\ZeroDSC\Functions
\resourceInvokerType.ps1: line 33
   at Invoke, C:\Users\un1\Documents\WindowsPowerShell\Modules\ZeroDSC\Functions
\boundResourceType.ps1: line 14
   at <ScriptBlock>, C:\Users\un1\Documents\WindowsPowerShell\Modules\ZeroDSC\Fu
nctions\configInstructionsType.ps1: line 285
   at Invoke-ConfigStep<Process>, C:\Users\un1\Documents\WindowsPowerShell\Modul
es\ZeroDSC\Functions\configInstructionsType.ps1: line 335
   at <ScriptBlock>, <No file>: line 19
 [+] Configure: Test resource [TestStub]a 320ms

Most of those lines are uninformative because they are just a record of the stack unwinding inside the ZeroDSC module. They should probably be omitted from the stack trace so that Pester shows only the helpful lines.

InModuleScope{} should be used instead of a module argument

It looks like all current versions of PowerShell don't consistently reload modules (ref, ref). Relying on Import-Module -Force to change which module members are exported should be avoided. The ZeroDSC module should not act on any arguments and the tests that rely on -Args 'ExportAll' should be changed to use InModuleScope{} instead.

This change shouldn't affect ZeroDSC users. But making the change will likely avoid some problems in development.

ConfigInstructions should include location of offending line in exception for duplicate resources

Executing

ConfigInstructions Name {
    Get-DscResource TestStub | Import-DscResource
    Get-DscResource TestStub | Import-DscResource
    TestStub a @{ Key = 'a' }
}

raises the exception

Duplicate resource named TestStub
At C:\Users\un1\Documents\WindowsPowerShell\Modules\ZeroDSC\Functions\configDocumentType.ps1:94 char:17
+                 throw [System.FormatException]::new(
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (:) [], FormatException
    + FullyQualifiedErrorId : Duplicate resource named TestStub

The file name and line number of the second Import-DscResource should be reported in the exception.

A test for this behavior is already mentioned in configDocumentType.Tests.ps1

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.