Skip to content

Commit

Permalink
fix: add tests (#48)
Browse files Browse the repository at this point in the history
  • Loading branch information
felixfbecker authored Sep 21, 2019
1 parent 36fbdb5 commit bc7af61
Show file tree
Hide file tree
Showing 9 changed files with 145 additions and 43 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ before_install:

install:
- dotnet tool install -g dotnet-format --version 3.1.37601
- pwsh ./ci/Install-Minikube.ps1 -MinikubeVersion v1.2.0 -KubernetesVersion v1.15.0
- pwsh ./ci/Install-Minikube.ps1 -MinikubeVersion v1.2.0 -KubernetesVersion v1.16.0
- pwsh -c 'Install-Module -Force -Scope CurrentUser PSScriptAnalyzer'

script:
Expand Down
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@
"powershell.codeFormatting.alignPropertyValuePairs": false,
"powershell.codeFormatting.newLineAfterCloseBrace": false,
"editor.formatOnSave": true,
"[yaml]": {
"editor.formatOnSave": false
}
}
5 changes: 3 additions & 2 deletions Tests/Initialize-TestNamespace.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ function Initialize-TestNamespace {
throw "Kube context is '$context', expected 'docker-for-desktop' or 'minikube'. Aborting for safety reasons."
}
Write-Information 'Setting up Kubernetes cluster'
Invoke-Executable { kubectl apply -f $PSScriptRoot/test.Namespace.yml --experimental-server-side --experimental-force-conflicts } | Out-Stream -SuccessTarget 6
Invoke-Executable { kubectl apply -f $PSScriptRoot/test.Namespace.yml --server-side --force-conflicts } | Out-Stream -SuccessTarget 6
}

function Initialize-TestDeployment {
Invoke-Executable { kubectl apply -f $PSScriptRoot/test.Deployment.yml --force --experimental-server-side --experimental-force-conflicts --wait } | Out-Stream -SuccessTarget 6
Invoke-Executable { kubectl apply -f $PSScriptRoot/test.Deployment.yml --force --server-side --force-conflicts --wait } | Out-Stream -SuccessTarget 6
Invoke-Executable { kubectl apply -f $PSScriptRoot/log.Deployment.yml --force --server-side --force-conflicts --wait } | Out-Stream -SuccessTarget 6
Invoke-Executable { kubectl rollout status --namespace pskubectltest deploy/hello-world } | Out-Stream -SuccessTarget 6
}
118 changes: 104 additions & 14 deletions Tests/PSKubectl.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@ Describe Get-KubePod {

It 'Should return the pods that exist in a namespace' {
$pods = Get-KubePod -Namespace pskubectltest
$pods.Count | Should -Not -BeNullOrEmpty
$pods | Should -Not -BeNullOrEmpty
$pods | ForEach-Object {
$_ | Should -BeOfType KubeClient.Models.PodV1
$_.Name | Should -BeLike 'hello-world-*'
$_.Namespace | Should -Be 'pskubectltest'
$_.Status.Phase | Should -Be 'Running'
}
}
}
Expand Down Expand Up @@ -92,6 +91,12 @@ Describe Get-KubeResource {
$_.Status.Phase | Should -Be 'Running'
}
}

It 'Should return deployment by name' {
$deploy = Get-KubeResource Deployment -Namespace pskubectltest -Name hello-world
$deploy | Should -HaveCount 1
$deploy.Metadata.Name | Should -Be 'hello-world'
}
}


Expand All @@ -101,12 +106,12 @@ Describe Get-KubeDeployment {

It 'Should return the deployments that exist in a namespace' {
$deploy = Get-KubeDeployment -Namespace pskubectltest
$deploy | Should -HaveCount 1
$deploy | Should -Not -BeNullOrEmpty
$deploy | Should -BeOfType KubeClient.Models.DeploymentV1
$deploy.Name | Should -Be 'hello-world'
$deploy.Namespace | Should -Be 'pskubectltest'
$deploy.Desired | Should -Be 2
$deploy.Current | Should -Be 2
$helloWorld = $deploy | Where-Object { $_.Name -eq 'hello-world' }
$helloWorld | Should -Not -BeNullOrEmpty
$helloWorld.Name | Should -Be 'hello-world'
$helloWorld.Namespace | Should -Be 'pskubectltest'
}
}

Expand Down Expand Up @@ -135,7 +140,7 @@ Describe Publish-KubeResource {
}

It 'Should update the resource from PSCustomObject pipeline input' {
$before = (Invoke-Executable { kubectl get deploy -n pskubectltest -o json } | ConvertFrom-Json).Items
$before = (Invoke-Executable { kubectl get deploy hello-world -n pskubectltest -o json } | ConvertFrom-Json)
$before.Metadata.Annotations.hello | Should -Be 'world'
$modified = [PSCustomObject]@{
Kind = 'Deployment'
Expand Down Expand Up @@ -182,18 +187,31 @@ Describe Publish-KubeResource {
$result | Should -Not -BeNullOrEmpty
$result | Should -BeOfType KubeClient.Models.DeploymentV1
$result.Metadata.Annotations['hello'] | Should -Be 'changed'
$after = (Invoke-Executable { kubectl get deploy -n pskubectltest -o json } | ConvertFrom-Json).Items
$after = (Invoke-Executable { kubectl get deploy hello-world -n pskubectltest -o json } | ConvertFrom-Json)
$after.Metadata.Annotations.hello | Should -Be 'changed'
}

It -Skip 'Should update the resource from modified Get-KubeResource pipeline input' {
$before = (Invoke-Executable { kubectl get deploy hello-world -n pskubectltest -o json } | ConvertFrom-Json)
$before.Metadata.Annotations.hello | Should -Be 'world'
$modified = Get-KubeResource -Kind Deployment -Namespace pskubectltest -Name hello-world
$modified.Metadata.Annotations['hello'] = 'changed'
$result = $modified | Publish-KubeResource
$result | Should -Not -BeNullOrEmpty
$result | Should -BeOfType KubeClient.Models.DeploymentV1
$result.Metadata.Annotations['hello'] | Should -Be 'changed'
$after = (Invoke-Executable { kubectl get deploy hello-world -n pskubectltest -o json } | ConvertFrom-Json)
$after.Metadata.Annotations.hello | Should -Be 'changed'
}

It 'Should update the resource from a path to a YAML file' {
$before = (Invoke-Executable { kubectl get deploy -n pskubectltest -o json } | ConvertFrom-Json).Items
$before = (Invoke-Executable { kubectl get deploy hello-world -n pskubectltest -o json } | ConvertFrom-Json)
$before.Metadata.Annotations.hello | Should -Be 'world'
$result = Publish-KubeResource -Path $PSScriptRoot/modified.Deployment.yml
$result | Should -Not -BeNullOrEmpty
$result | Should -BeOfType KubeClient.Models.DeploymentV1
$result.Metadata.Annotations['hello'] | Should -Be 'changed'
$after = (Invoke-Executable { kubectl get deploy -n pskubectltest -o json } | ConvertFrom-Json).Items
$after = (Invoke-Executable { kubectl get deploy hello-world -n pskubectltest -o json } | ConvertFrom-Json)
$after.Metadata.Annotations.hello | Should -Be 'changed'
}
}
Expand All @@ -212,15 +230,15 @@ Describe Publish-KubeResource {
Invoke-Executable { kubectl create -f $PSScriptRoot/test.Deployment.yml }
Invoke-Executable { kubectl rollout status --namespace pskubectltest deploy/hello-world } | Out-Stream -SuccessTarget 6

$before = (Invoke-Executable { kubectl get deploy -n pskubectltest -o json } | ConvertFrom-Json).Items
$before = (Invoke-Executable { kubectl get deploy hello-world -n pskubectltest -o json } | ConvertFrom-Json)
$before.Metadata.Annotations.hello | Should -Be 'world'

$result = Publish-KubeResource -Path $PSScriptRoot/modified.Deployment.yml -Force
$result | Should -Not -BeNullOrEmpty
$result | Should -BeOfType KubeClient.Models.DeploymentV1
$result.Metadata.Annotations.hello | Should -Be 'changed'

$after = (Invoke-Executable { kubectl get deploy -n pskubectltest -o json } | ConvertFrom-Json).Items
$after = (Invoke-Executable { kubectl get deploy hello-world -n pskubectltest -o json } | ConvertFrom-Json)
$after.Metadata.Annotations.hello | Should -Be 'changed'
}
}
Expand All @@ -235,7 +253,7 @@ Describe Publish-KubeResource {
$result | Should -Not -BeNullOrEmpty
$result | Should -BeOfType KubeClient.Models.DeploymentV1

$after = (Invoke-Executable { kubectl get deploy -n pskubectltest -o json } | ConvertFrom-Json).Items
$after = (Invoke-Executable { kubectl get deploy -n pskubectltest -o json hello-world } | ConvertFrom-Json)
$after.metadata.name | Should -Be 'hello-world'
$after.metadata.annotations.hello | Should -Be 'world'
$after.spec.selector.matchLabels.app | Should -Be 'hello-world'
Expand All @@ -250,6 +268,26 @@ Describe Publish-KubeResource {
}
}

Describe Get-KubeResourceKinds {
It 'Should return resource kinds' {
$kinds = Get-KubeResourceKinds | ForEach-Object Kind
$kinds | Should -Contain 'Deployment'
$kinds | Should -Contain 'Pod'
}
}

Describe Get-KubeLog {
BeforeEach {
Initialize-TestNamespace
Initialize-TestDeployment
}

It 'Should return the logs of a given pod' {
$logs = Get-KubeResource Pod -Namespace pskubectltest -Name hello-world-log-* | Get-KubeLog
$logs -split "`n" | Should -Contain 'Hello from Docker!'
}
}

Describe Get-KubeConfig {

It 'Should return kube configuration' {
Expand All @@ -260,3 +298,55 @@ Describe Get-KubeConfig {
$config.Contexts | Should -Not -BeNullOrEmpty
}
}

Describe Convert-KubeYaml {
It 'Should read in YAML' {
$parsed = Get-Content -Raw $PSScriptRoot/test.Deployment.yml | ConvertFrom-KubeYaml
$parsed.PSObject.TypeNames | Should -Contain 'KubeClient.Models.DeploymentV1'
$parsed.Metadata.Name | Should -Be 'hello-world'
$parsed.Spec.Replicas | Should -Be 2
}
It 'Should round-trip' {
$yaml = Get-Content -Raw $PSScriptRoot/test.Deployment.yml
$yaml | ConvertFrom-KubeYaml | ConvertTo-KubeYaml | Should -Be $yaml
}
}

Describe ConvertTo-KubeYaml {
BeforeAll {
Initialize-TestNamespace
Initialize-TestDeployment
}

It 'Should encode PSCustomObjects' {
$deploy = [PSCustomObject]@{
Kind = 'Deployment'
ApiVersion = 'apps/v1'
Metadata = [PSCustomObject]@{
Name = 'hello-world'
Namespace = 'pskubectltest'
Annotations = @{
'hello' = 'changed'
}
}
}
$yaml = @(
'kind: Deployment',
'apiVersion: apps/v1',
'metadata:',
' name: hello-world',
' namespace: pskubectltest',
' annotations:',
' hello: changed',
''
) -join "`n"
$deploy | ConvertTo-KubeYaml | Should -Be $yaml
}

It 'Should encode Get-KubeResource output to YAML' {
$parsed = Get-KubeResource -Kind Deployment -Namespace pskubectltest -Name hello-world | ConvertTo-KubeYaml | ConvertFrom-KubeYaml
$parsed.Metadata.Name | Should -Be 'hello-world'
$parsed.Spec.Replicas | Should -Be 2
$parsed.Status.Replicas | Should -Be 2
}
}
24 changes: 24 additions & 0 deletions Tests/log.Deployment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-world-log
namespace: pskubectltest
annotations:
hello: world
spec:
selector:
matchLabels:
app: hello-world-log
replicas: 1
template:
metadata:
labels:
app: hello-world-log
spec:
containers:
- name: hello-world-log
image: hello-world@sha256:b8ba256769a0ac28dd126d584e0a2011cd2877f3f76e093a7ae560f2a5301c00
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
protocol: TCP
12 changes: 6 additions & 6 deletions Tests/test.Deployment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ spec:
app: hello-world
spec:
containers:
- name: hello-world
image: strm/helloworld-http@sha256:bd44b0ca80c26b5eba984bf498a9c3bab0eb1c59d30d8df3cb2c073937ee4e45
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
protocol: TCP
- name: hello-world
image: strm/helloworld-http@sha256:bd44b0ca80c26b5eba984bf498a9c3bab0eb1c59d30d8df3cb2c073937ee4e45
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
protocol: TCP
11 changes: 0 additions & 11 deletions src/Cmdlets/ConvertFromKubeYamlCmdlet.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,7 @@
using System.Threading.Tasks;
using System.IO;
using System.Management.Automation;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
using System;
using Microsoft.Extensions.Logging;
using System.Threading;
using YamlDotNet.Core.Events;
using YamlDotNet.Core;
using KubeClient.Models;
using System.Collections.Generic;
using System.Linq;
using System.Collections;
using System.Reflection;

namespace Kubectl.Cmdlets {
[Cmdlet(VerbsData.ConvertFrom, "KubeYaml")]
Expand Down
10 changes: 3 additions & 7 deletions src/Cmdlets/GetKubeResourceKindsCmdlet.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management.Automation;
using System.Threading;
using System.Threading.Tasks;
using KubeClient;
using KubeClient.Models;
using KubeClient.ResourceClients;
using Microsoft.Extensions.Logging;

namespace Kubectl.Cmdlets {
[Cmdlet(VerbsCommon.Get, "KubeResourceKinds")]
Expand All @@ -24,7 +18,9 @@ protected override async Task ProcessRecordAsync(CancellationToken cancellationT
Kind = pair.kind,
ApiVersion = pair.apiVersion
});
WriteObject(kinds);
foreach (var kind in kinds) {
WriteObject(kind);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ public sealed class DeployKubeResourceCmdlet : KubeApiCmdlet {
[ValidateNotNull()]
public object Resource { get; set; }

// Needed to take ownership of a resource
[Parameter()]
[Parameter(HelpMessage = "If present, server-side apply will force the changes against conflicts.")]
public SwitchParameter Force { get; set; }

private KubeYamlDeserializer deserializer;
Expand Down

0 comments on commit bc7af61

Please sign in to comment.