Class: Kitchen::Verifier::Pester

Inherits:
Base
  • Object
show all
Defined in:
lib/kitchen/verifier/pester.rb

Instance Method Summary collapse

Constructor Details

#initialize(config = {}) ⇒ Pester

Creates a new Verifier object using the provided configuration data which will be merged with any default configuration.

Parameters:

  • config (Hash) (defaults to: {})

    provided verifier configuration



75
76
77
78
# File 'lib/kitchen/verifier/pester.rb', line 75

def initialize(config = {})
  init_config(config)
  raise ClientError.new "Environment Variables must be specified as a hash, not a #{config[:environment].class}" unless config[:environment].is_a?(Hash)
end

Instance Method Details

#absolute_test_folderObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

returns the absolute path of the relative folders containing the test suites, use default i not set.



718
719
720
721
722
# File 'lib/kitchen/verifier/pester.rb', line 718

def absolute_test_folder
  path = (Pathname.new config[:test_folder]).realpath
  integration_path = File.join(path, "integration")
  Dir.exist?(integration_path) ? integration_path : path
end

#call(state) ⇒ Object



218
219
220
221
222
223
224
# File 'lib/kitchen/verifier/pester.rb', line 218

def call(state)
  super
ensure
  info("Ensure download test files.")
  download_test_files(state) unless config[:downloads].nil?
  info("Download complete.")
end

#copy_if_src_exists(src_to_validate, destination) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Copies a folder recursively preserving its layers, mostly used to copy to the sandbox.



691
692
693
694
695
696
697
698
699
700
701
702
703
704
# File 'lib/kitchen/verifier/pester.rb', line 691

def copy_if_src_exists(src_to_validate, destination)
  unless Dir.exist?(src_to_validate)
    info("The path #{src_to_validate} was not found. Not copying to #{destination}.")
    return
  end

  info("Moving #{src_to_validate} to #{destination}")
  unless Dir.exist?(destination)
    FileUtils.mkdir_p(destination)
    debug("Folder '#{destination}' created.")
  end
  FileUtils.mkdir_p(File.join(destination, "__bugfix"))
  FileUtils.cp_r(src_to_validate, destination, preserve: true)
end

#create_sandboxObject

Creates a temporary directory on the local workstation into which verifier related files and directories can be copied or created. The contents of this directory will be copied over to the instance before invoking the verifier’s run command. After this method completes, it is expected that the contents of the sandbox is complete and ready for copy to the remote instance.

Note: any subclasses would be well advised to call super first when overriding this method, for example:

Examples:

overriding ‘#create_sandbox`


class MyVerifier < Kitchen::Verifier::Base
  def create_sandbox
    super
    # any further file copies, preparations, etc.
  end
end


98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/kitchen/verifier/pester.rb', line 98

def create_sandbox
  super
  prepare_supporting_psmodules
  prepare_copy_folders
  prepare_pester_tests
  prepare_helpers

  debug("\n\n")
  debug("Sandbox content:\n")
  list_files(sandbox_path).each do |f|
    debug("    #{f}")
  end
end

#download_test_files(state) ⇒ Object



529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
# File 'lib/kitchen/verifier/pester.rb', line 529

def download_test_files(state)
  if config[:downloads].nil?
    info("Skipped downloading test result file from #{instance.to_str}; 'downloads' hash is empty.")
    return
  end

  info("Downloading test result files from #{instance.to_str}")
  instance.transport.connection(state) do |conn|
    config[:downloads].each do |remotes, local|
      debug("downloading #{Array(remotes).join(", ")} to #{local}")
      conn.download(remotes, local)
    end
  end

  debug("Finished downloading test result files from #{instance.to_str}")
end

#get_powershell_modules_from_nugetapiObject



321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
# File 'lib/kitchen/verifier/pester.rb', line 321

def get_powershell_modules_from_nugetapi
  # don't return anything is the modules subkey or bootstrap is null
  return if config.dig(:bootstrap, :modules).nil?

  bootstrap = config[:bootstrap]
  # if the repository url is set, use that as parameter to Install-ModuleFromNuget. Default is the PSGallery url
  gallery_url_param = bootstrap[:repository_url] ? "-GalleryUrl '#{bootstrap[:repository_url]}'" : ""

  info("Bootstrapping environment without PowerShellGet Provider...")
  Array(bootstrap[:modules]).map do |powershell_module|
    if powershell_module.is_a? Hash
      <<-PS1
        ${#{powershell_module[:Name]}} = #{ps_hash(powershell_module)}

        Install-ModuleFromNuget -Module ${#{powershell_module[:Name]}} #{gallery_url_param}
      PS1
    else
      <<-PS1
        Install-ModuleFromNuget -Module @{Name = '#{powershell_module}'} #{gallery_url_param}
      PS1
    end
  end
end

#helper_filesArray<String>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns an Array of common helper filenames currently residing on the local workstation.

Returns:

  • (Array<String>)

    array of helper files



578
579
580
581
# File 'lib/kitchen/verifier/pester.rb', line 578

def helper_files
  glob = Dir.glob(File.join(test_folder, "helpers", "*/**/*"))
  glob.reject { |f| File.directory?(f) }
end

#init_commandString

Generates a command string which will perform any data initialization or configuration required after the verifier software is installed but before the sandbox has been transferred to the instance. If no work is required, then ‘nil` will be returned.

Returns:

  • (String)

    a command string



158
159
160
# File 'lib/kitchen/verifier/pester.rb', line 158

def init_command
  restart_winrm_service if config[:restart_winrm]
end

#install_commandString

Generates a command string which will install and configure the verifier software on an instance. If no work is required, then ‘nil` will be returned. PowerShellGet & Pester Bootstrap are done in prepare_command (after sandbox is transferred) so that we can use the PesterUtil.psm1

Returns:

  • (String)

    a command string



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/kitchen/verifier/pester.rb', line 119

def install_command
  # the sandbox has not yet been copied to the SUT.
  install_command_string = <<-PS1
    Write-Verbose 'Running Install Command...'
    $modulesToRemove = @(
        if ($#{config[:remove_builtin_powershellget]}) {
            Get-module -ListAvailable -FullyQualifiedName @{ModuleName = 'PackageManagement'; RequiredVersion = '1.0.0.1'}
            Get-module -ListAvailable -FullyQualifiedName @{ModuleName = 'PowerShellGet'; RequiredVersion = '1.0.0.1'}
        }

        if ($#{config[:remove_builtin_pester]}) {
            Get-module -ListAvailable -FullyQualifiedName @{ModuleName = 'Pester'; RequiredVersion = '3.4.0'}
        }
    )

    if ($modulesToRemove.ModuleBase.Count -eq 0) {
      # for PS7 on linux
      return
    }

    $modulesToRemove.ModuleBase | Foreach-Object {
        $ModuleBaseLeaf = Split-Path -Path $_ -Leaf
        if ($ModuleBaseLeaf -as [System.version]) {
          Remove-Item -force -Recurse (Split-Path -Parent -Path $_) -ErrorAction SilentlyContinue
        }
        else {
          Remove-Item -force -Recurse $_ -ErrorAction SilentlyContinue
        }
    }
  PS1
  really_wrap_shell_code(Util.outdent!(install_command_string))
end

#install_command_scriptObject



500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
# File 'lib/kitchen/verifier/pester.rb', line 500

def install_command_script
  <<-PS1
    $PSModPathToPrepend = "#{config[:root_path]}"

    Import-Module -ErrorAction Stop PesterUtil

    #{get_powershell_modules_from_nugetapi.join("\n") unless config.dig(:bootstrap, :modules).nil?}

    #{register_psrepository_scriptblock.join("\n") unless config[:register_repository].nil?}

    #{install_pester}

    #{install_modules_from_gallery.join("\n") unless config[:install_modules].nil?}
  PS1
end

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

returns a piece of PS scriptblock for each Module to install from gallery that has been sepcified in install_modules config.

Returns:

  • (Array<String>)

    array of PS commands.



393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
# File 'lib/kitchen/verifier/pester.rb', line 393

def install_modules_from_gallery
  return if config[:install_modules].nil?

  Array(config[:install_modules]).map do |powershell_module|
    if powershell_module.is_a? Hash
      # Sanitize variable name so that $powershell-yaml becomes $powershell_yaml
      module_name = powershell_module[:Name].gsub(/[\W]/, "_")
      # so we can splat that variable to install module
      <<-PS1
        $#{module_name} = #{ps_hash(powershell_module)}
        Write-Host -NoNewline 'Installing #{module_name}'
        Install-Module @#{module_name}
        Write-host '... done.'
      PS1
    else
      <<-PS1
        Write-host -NoNewline 'Installing #{powershell_module} ...'
        Install-Module -Name '#{powershell_module}'
        Write-host '... done.'
      PS1
    end
  end
end

#install_pesterString

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the string command set the PSGallery as trusted, and Install Pester from gallery based on the params from Pester_install_params config

Returns:

  • (String)

    command to install Pester Module



370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
# File 'lib/kitchen/verifier/pester.rb', line 370

def install_pester
  return if config[:skip_pester_install]

  pester_install_params = config[:pester_install] || {}
  <<-PS1
    if ((Get-PSRepository -Name PSGallery).InstallationPolicy -ne 'Trusted') {
        Write-Host -Object "Trusting the PSGallery to install Pester without -Force"
        Set-PSRepository -Name PSGallery -InstallationPolicy Trusted -ErrorAction SilentlyContinue
    }

    Write-Host "Installing Pester..."
    $installPesterParams = #{ps_hash(pester_install_params)}
    $installPesterParams['Name'] = 'Pester'
    Install-module @installPesterParams
    Write-Host 'Pester Installed.'
  PS1
end

#invoke_pester_scriptblockObject

private



239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
# File 'lib/kitchen/verifier/pester.rb', line 239

def invoke_pester_scriptblock
  <<-PS1
    $PesterModule = Import-Module -Name Pester -Force -ErrorAction Stop -PassThru

    $TestPath = Join-Path "#{config[:root_path]}" -ChildPath "suites"
    $OutputFilePath = Join-Path "#{config[:root_path]}" -ChildPath 'PesterTestResults.xml'

    #{ps_environment(config[:environment])}
    if ($PesterModule.Version.Major -le 4)
    {
      Write-Host -Object "Invoke Pester with v$($PesterModule.Version) Options"
      $options = New-PesterOption -TestSuiteName "Pester - #{instance.to_str}"
      $defaultPesterParameters = @{
          Script        = $TestPath
          OutputFile    = $OutputFilePath
          OutputFormat  = 'NUnitXml'
          PassThru      = $true
          PesterOption  = $options
      }

      $pesterCmd = Get-Command -Name 'Invoke-Pester'
      $pesterConfig = #{ps_hash(config[:pester_configuration])}
      $invokePesterParams = @{}

      foreach ($paramName in $pesterCmd.Parameters.Keys)
      {
          $paramValue = $pesterConfig.($paramName)

          if ($paramValue) {
              Write-Host -Object "Using $paramName from Yaml config."
              $invokePesterParams[$paramName] = $paramValue
          }
          elseif ($defaultPesterParameters.ContainsKey($paramName))
          {
              Write-Host -Object "Using $paramName from Defaults: $($defaultPesterParameters[$paramName])."
              $invokePesterParams[$paramName] = $defaultPesterParameters[$paramName]
          }
      }

      $result = Invoke-Pester @invokePesterParams
    }
    else
    {
      Write-Host -Object "Invoke Pester with v$($PesterModule.Version) Configuration."
      $pesterConfigHash = #{ps_hash(config[:pester_configuration])}

      if (-not $pesterConfigHash.ContainsKey('run')) {
          $pesterConfigHash['run'] = @{}
      }

      if (-not $pesterConfigHash.ContainsKey('TestResult')) {
          $pesterConfigHash['TestResult'] = @{}
      }

      if (-not $pesterConfigHash.run.path) {
          $pesterConfigHash['run']['path'] = $TestPath
      }

      if (-not $pesterConfigHash.TestResult.TestSuiteName) {
          $pesterConfigHash['TestResult']['TestSuiteName'] = 'Pester - #{instance.to_str}'
      }

      if (-not $pesterConfigHash.TestResult.OutputPath) {
          $pesterConfigHash['TestResult']['OutputPath'] = $OutputFilePath
      }

      $PesterConfig = New-PesterConfiguration -Hashtable $pesterConfigHash
      $result = Invoke-Pester -Configuration $PesterConfig
    }

    $resultXmlPath = (Join-Path -Path $TestPath -ChildPath 'result.xml')
    if (Test-Path -Path $resultXmlPath) {
      $result | Export-CliXml -Path
    }

    $LASTEXITCODE = $result.FailedCount
    $host.SetShouldExit($LASTEXITCODE)

    exit $LASTEXITCODE
  PS1
end

#list_files(path) ⇒ Array<String>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

returns an array of string Creates a flat list of files contained in a folder. This is useful when trying to debug what has been copied to the sandbox.

Returns:

  • (Array<String>)

    array of files in a folder



666
667
668
669
670
# File 'lib/kitchen/verifier/pester.rb', line 666

def list_files(path)
  base_directory_content = Dir.glob(File.join(path, "*"))
  nested_directory_content = Dir.glob(File.join(path, "*/**/*"))
  [base_directory_content, nested_directory_content].flatten
end

#pad(depth = 0) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

returns a string of space of the specified depth. This is used to pad messages or when building PS hashtables.



728
729
730
# File 'lib/kitchen/verifier/pester.rb', line 728

def pad(depth = 0)
  " " * depth
end

#prepare_commandString

Generates a command string which will perform any commands or configuration required just before the main verifier run command but after the sandbox has been transferred to the instance. If no work is required, then ‘nil` will be returned.

Returns:

  • (String)

    a command string



168
169
170
171
172
# File 'lib/kitchen/verifier/pester.rb', line 168

def prepare_command
  info("Preparing the SUT and Pester dependencies...")
  resolve_downloads_paths!
  really_wrap_shell_code(install_command_script)
end

#prepare_copy_foldersObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

copy files into the ‘modules’ folder of the sandbox, so that copied folders can be discovered with the updated $Env:PSModulePath.



647
648
649
650
651
652
653
654
655
656
657
# File 'lib/kitchen/verifier/pester.rb', line 647

def prepare_copy_folders
  return if config[:copy_folders].nil?

  info("Preparing to copy specified folders to #{sandbox_module_path}.")
  kitchen_root_path = config[:kitchen_root]
  config[:copy_folders].each do |folder|
    debug("copying #{folder}")
    folder_to_copy = File.join(kitchen_root_path, folder)
    copy_if_src_exists(folder_to_copy, sandbox_module_path)
  end
end

#prepare_helpersObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Copies all common testing helper files into the suites directory in the sandbox.



587
588
589
590
591
592
593
594
595
596
# File 'lib/kitchen/verifier/pester.rb', line 587

def prepare_helpers
  base = File.join(test_folder, "helpers")

  helper_files.each do |src|
    dest = File.join(sandbox_path, src.sub("#{base}/", ""))
    debug("Copying #{src} to #{dest}")
    FileUtils.mkdir_p(File.dirname(dest))
    FileUtils.cp(src, dest, preserve: true)
  end
end

#prepare_pester_testsObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Copies all test suite files into the suites directory in the sandbox.



675
676
677
678
679
# File 'lib/kitchen/verifier/pester.rb', line 675

def prepare_pester_tests
  info("Preparing to copy files from  '#{suite_test_folder}' to the SUT.")
  sandboxed_suites_path = File.join(sandbox_path, "suites")
  copy_if_src_exists(suite_test_folder, sandboxed_suites_path)
end

#prepare_supporting_psmodulesObject



681
682
683
684
685
# File 'lib/kitchen/verifier/pester.rb', line 681

def prepare_supporting_psmodules
  info("Preparing to copy files from '#{support_psmodule_folder}' to the SUT.")
  sandbox_module_path = File.join(sandbox_path, "modules")
  copy_if_src_exists(support_psmodule_folder, sandbox_module_path)
end

#ps_environment(obj) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Creates environment variable assignments from a ruby map.



627
628
629
630
631
632
633
# File 'lib/kitchen/verifier/pester.rb', line 627

def ps_environment(obj)
  commands = obj.map do |k, v|
    "$env:#{k} = '#{v}'"
  end

  commands.join("\n")
end

#ps_hash(obj, depth = 0) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Creates a PowerShell hashtable from a ruby map. The only types supported for now are hash, array, string and Boolean.



602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
# File 'lib/kitchen/verifier/pester.rb', line 602

def ps_hash(obj, depth = 0)
  if [true, false].include? obj
    %{$#{obj}} # Return $true or $false when value is a bool
  elsif obj.is_a?(Hash)
    obj.map do |k, v|
      # Format "Key = Value" enabling recursion
      %{#{pad(depth + 2)}#{ps_hash(k)} = #{ps_hash(v, depth + 2)}}
    end
      .join("\n") # append \n to the key/value definitions
      .insert(0, "@{\n") # prepend @{\n
      .insert(-1, "\n#{pad(depth)}}\n") # append \n}\n

  elsif obj.is_a?(Array)
    array_string = obj.map { |v| ps_hash(v, depth + 4) }.join(",")
    "#{pad(depth)}@(\n#{array_string}\n)"
  else
    # When the object is not a string nor a hash or array, it will be quoted as a string.
    # In most cases, PS is smart enough to convert back to the type it needs.
    "'" + obj.to_s + "'"
  end
end

#really_wrap_posix_shell_code(code) ⇒ Object

Writing the command to a ps1 file, adding the pwsh shebang invoke the file



461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
# File 'lib/kitchen/verifier/pester.rb', line 461

def really_wrap_posix_shell_code(code)
  my_command = <<-BASH
    echo "Running as '$(whoami)'"
    # create the modules folder, making sure it's done as current user (not root)
    mkdir -p #{config[:root_path]}/modules
    cd #{config[:root_path]}
    # Send the bash heredoc 'EOF' to the file kitchen_cmd.ps1 using the tool cat
    cat << 'EOF' > kitchen_cmd.ps1
    #!/usr/bin/env pwsh
    #{Util.outdent!(use_local_powershell_modules(code))}
    EOF
    chmod +x kitchen_cmd.ps1
    # Invoke the created kitchen_cmd.ps1 file using pwsh
    #{shell_cmd} ./kitchen_cmd.ps1
  BASH

  debug(Util.outdent!(my_command))
  Util.outdent!(my_command)
end

#really_wrap_shell_code(code) ⇒ Object



417
418
419
# File 'lib/kitchen/verifier/pester.rb', line 417

def really_wrap_shell_code(code)
  windows_os? ? really_wrap_windows_shell_code(code) : really_wrap_posix_shell_code(code)
end

#really_wrap_windows_shell_code(code) ⇒ Object



434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
# File 'lib/kitchen/verifier/pester.rb', line 434

def really_wrap_windows_shell_code(code)
  my_command = <<-PWSH
    echo "Running as '$(whoami)'..."
    New-Item -ItemType Directory -Path '#{config[:root_path]}/modules' -Force -ErrorAction SilentlyContinue
    Set-Location -Path "#{config[:root_path]}"
    # Send the pwsh here string to the file kitchen_cmd.ps1
    @'
    try {
        if (@('Bypass', 'Unrestricted') -notcontains (Get-ExecutionPolicy)) {
            Set-ExecutionPolicy Unrestricted -Force -Scope Process
        }
    }
    catch {
        $_ | Out-String | Write-Warning
    }
    #{Util.outdent!(use_local_powershell_modules(code))}
    '@ | Set-Content -Path kitchen_cmd.ps1 -Encoding utf8 -Force -ErrorAction 'Stop'
    # create the modules folder, making sure it's done as current user (not root)
    #
    # Invoke the created kitchen_cmd.ps1 file using pwsh
    #{shell_cmd} ./kitchen_cmd.ps1
  PWSH
  wrap_shell_code(Util.outdent!(my_command))
end

#register_psrepository_scriptblockArray<String>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the string command to set a PS Repository for each PSRepo configured.

Returns:

  • (Array<String>)

    array of suite files



350
351
352
353
354
355
356
357
358
359
360
361
362
363
# File 'lib/kitchen/verifier/pester.rb', line 350

def register_psrepository_scriptblock
  return if config[:register_repository].nil?

  info("Registering a new PowerShellGet Repository")
  Array(config[:register_repository]).map do |psrepo|
    # Using Set-PSRepo from ../../*/*/*/PesterUtil.psm1
    debug("Command to set PSRepo #{psrepo[:Name]}.")
    <<-PS1
      Write-Host 'Registering psrepo #{psrepo[:Name]}...'
      ${#{psrepo[:Name]}} = #{ps_hash(psrepo)}
      Set-PSRepo -Repository ${#{psrepo[:Name]}}
    PS1
  end
end

#resolve_downloads_paths!nil

Resolves the remote Downloads path from the verifier root path, unless they’re absolute path (starts with / or C:) This updates the config, nothing (nil) is returned.

Returns:

  • (nil)

    updates config downloads



188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/kitchen/verifier/pester.rb', line 188

def resolve_downloads_paths!
  info("Resolving Downloads path from config.")
  config[:downloads] = config[:downloads]
    .map do |source, destination|
      source = source.to_s
      destination = destination.gsub("%{instance_name}", instance.name)
      info("  resolving remote source's absolute path.")
      unless source.match?('^/|^[a-zA-Z]:[\\/]') # is Absolute?
        info("  '#{source}' is a relative path, resolving to: #{File.join(config[:root_path], source)}")
        source = File.join(config[:root_path], source.to_s).to_s
      end

      if destination.match?('\\$|/$') # is Folder (ends with / or \)
        destination = File.join(destination, File.basename(source)).to_s
      end
      info("  Destination: #{destination}")
      if !File.directory?(File.dirname(destination))
        FileUtils.mkdir_p(File.dirname(destination))
      else
        info("  Directory #{File.dirname(destination)} seems to exist.")
      end

      [ source, destination ]
    end
  nil # make sure we do not return anything
end

#restart_winrm_serviceObject



516
517
518
519
520
521
522
523
524
525
526
527
# File 'lib/kitchen/verifier/pester.rb', line 516

def restart_winrm_service
  return unless verifier.windows_os?

  cmd = "schtasks /Create /TN restart_winrm /TR " \
        '"powershell -Command Restart-Service winrm" ' \
        "/SC ONCE /ST 00:00 "
  wrap_shell_code(Util.outdent!(<<-CMD
    #{cmd}
    schtasks /RUN /TN restart_winrm
  CMD
                               ))
end

#run_commandString

Generates a command string which will invoke the main verifier command on the prepared instance. If no work is required, then ‘nil` will be returned.

Returns:

  • (String)

    a command string



179
180
181
# File 'lib/kitchen/verifier/pester.rb', line 179

def run_command
  really_wrap_shell_code(invoke_pester_scriptblock)
end

#sandbox_module_pathObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

returns the path of the modules subfolder in the sandbox, where PS Modules and folders will be copied to.



639
640
641
# File 'lib/kitchen/verifier/pester.rb', line 639

def sandbox_module_path
  File.join(sandbox_path, "modules")
end

#script_rootstring

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the current file’s parent folder’s full path.

Returns:

  • (string)


560
561
562
# File 'lib/kitchen/verifier/pester.rb', line 560

def script_root
  @script_root ||= File.dirname(__FILE__)
end

#shell_cmdObject

Get the defined shell or fall back to pwsh, unless we’re on windows where we use powershell call via sudo if sudo is true. This allows to use pwsh-preview instead of pwsh, or a full path to a specific binary.



424
425
426
427
428
429
430
431
432
# File 'lib/kitchen/verifier/pester.rb', line 424

def shell_cmd
  if !config[:shell].nil?
    config[:sudo] ? "sudo #{config[:shell]}" : "#{config[:shell]}"
  elsif windows_os?
    "powershell"
  else
    config[:sudo] ? "sudo pwsh" : "pwsh"
  end
end

#suite_test_folderArray<String>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns an Array of test suite filenames for the related suite currently residing on the local workstation. Any special provisioner-specific directories (such as a Chef roles/ directory) are excluded.

Returns:

  • (Array<String>)

    array of suite files



552
553
554
# File 'lib/kitchen/verifier/pester.rb', line 552

def suite_test_folder
  @suite_test_folder ||= File.join(test_folder, config[:suite_name])
end

#support_psmodule_folderstring

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the absolute path of the Supporting PS module to be copied to the SUT via the Sandbox.

Returns:

  • (string)


569
570
571
# File 'lib/kitchen/verifier/pester.rb', line 569

def support_psmodule_folder
  @support_psmodule_folder ||= Pathname.new(File.join(script_root, "../../support/modules/PesterUtil")).cleanpath
end

#test_folderObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

returns the absolute path of the folders containing the test suites, use default if not set.



710
711
712
# File 'lib/kitchen/verifier/pester.rb', line 710

def test_folder
  config[:test_folder].nil? ? config[:test_base_path] : absolute_test_folder
end

#use_local_powershell_modules(script) ⇒ Object



481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
# File 'lib/kitchen/verifier/pester.rb', line 481

def use_local_powershell_modules(script)
  <<-PS1
    Write-Host -Object ("{0} - PowerShell {1}" -f $PSVersionTable.OS,$PSVersionTable.PSVersion)
    $global:ProgressPreference = 'SilentlyContinue'
    $PSModPathToPrepend = Join-Path "#{config[:root_path]}" -ChildPath 'modules'
    Write-Verbose "Adding '$PSModPathToPrepend' to `$Env:PSModulePath."
    if (!$isLinux -and -not (Test-Path -Path $PSModPathToPrepend)) {
      # if you create this folder now in Linux, it may run as root (via sudo).
      $null = New-Item -Path $PSModPathToPrepend -Force -ItemType Directory
    }

    if ($Env:PSModulePath.Split([io.path]::PathSeparator) -notcontains $PSModPathToPrepend) {
      $env:PSModulePath   = @($PSModPathToPrepend, $env:PSModulePath) -Join [io.path]::PathSeparator
    }

    #{script}
  PS1
end