Skip to content

Commit bc7af61

Browse files
authored
fix: add tests (#48)
1 parent 36fbdb5 commit bc7af61

9 files changed

+145
-43
lines changed

.travis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ before_install:
2626

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

3232
script:

.vscode/settings.json

+3
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,7 @@
33
"powershell.codeFormatting.alignPropertyValuePairs": false,
44
"powershell.codeFormatting.newLineAfterCloseBrace": false,
55
"editor.formatOnSave": true,
6+
"[yaml]": {
7+
"editor.formatOnSave": false
8+
}
69
}

Tests/Initialize-TestNamespace.psm1

+3-2
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ function Initialize-TestNamespace {
77
throw "Kube context is '$context', expected 'docker-for-desktop' or 'minikube'. Aborting for safety reasons."
88
}
99
Write-Information 'Setting up Kubernetes cluster'
10-
Invoke-Executable { kubectl apply -f $PSScriptRoot/test.Namespace.yml --experimental-server-side --experimental-force-conflicts } | Out-Stream -SuccessTarget 6
10+
Invoke-Executable { kubectl apply -f $PSScriptRoot/test.Namespace.yml --server-side --force-conflicts } | Out-Stream -SuccessTarget 6
1111
}
1212

1313
function Initialize-TestDeployment {
14-
Invoke-Executable { kubectl apply -f $PSScriptRoot/test.Deployment.yml --force --experimental-server-side --experimental-force-conflicts --wait } | Out-Stream -SuccessTarget 6
14+
Invoke-Executable { kubectl apply -f $PSScriptRoot/test.Deployment.yml --force --server-side --force-conflicts --wait } | Out-Stream -SuccessTarget 6
15+
Invoke-Executable { kubectl apply -f $PSScriptRoot/log.Deployment.yml --force --server-side --force-conflicts --wait } | Out-Stream -SuccessTarget 6
1516
Invoke-Executable { kubectl rollout status --namespace pskubectltest deploy/hello-world } | Out-Stream -SuccessTarget 6
1617
}

Tests/PSKubectl.Tests.ps1

+104-14
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,11 @@ Describe Get-KubePod {
88

99
It 'Should return the pods that exist in a namespace' {
1010
$pods = Get-KubePod -Namespace pskubectltest
11-
$pods.Count | Should -Not -BeNullOrEmpty
11+
$pods | Should -Not -BeNullOrEmpty
1212
$pods | ForEach-Object {
1313
$_ | Should -BeOfType KubeClient.Models.PodV1
1414
$_.Name | Should -BeLike 'hello-world-*'
1515
$_.Namespace | Should -Be 'pskubectltest'
16-
$_.Status.Phase | Should -Be 'Running'
1716
}
1817
}
1918
}
@@ -92,6 +91,12 @@ Describe Get-KubeResource {
9291
$_.Status.Phase | Should -Be 'Running'
9392
}
9493
}
94+
95+
It 'Should return deployment by name' {
96+
$deploy = Get-KubeResource Deployment -Namespace pskubectltest -Name hello-world
97+
$deploy | Should -HaveCount 1
98+
$deploy.Metadata.Name | Should -Be 'hello-world'
99+
}
95100
}
96101

97102

@@ -101,12 +106,12 @@ Describe Get-KubeDeployment {
101106

102107
It 'Should return the deployments that exist in a namespace' {
103108
$deploy = Get-KubeDeployment -Namespace pskubectltest
104-
$deploy | Should -HaveCount 1
109+
$deploy | Should -Not -BeNullOrEmpty
105110
$deploy | Should -BeOfType KubeClient.Models.DeploymentV1
106-
$deploy.Name | Should -Be 'hello-world'
107-
$deploy.Namespace | Should -Be 'pskubectltest'
108-
$deploy.Desired | Should -Be 2
109-
$deploy.Current | Should -Be 2
111+
$helloWorld = $deploy | Where-Object { $_.Name -eq 'hello-world' }
112+
$helloWorld | Should -Not -BeNullOrEmpty
113+
$helloWorld.Name | Should -Be 'hello-world'
114+
$helloWorld.Namespace | Should -Be 'pskubectltest'
110115
}
111116
}
112117

@@ -135,7 +140,7 @@ Describe Publish-KubeResource {
135140
}
136141

137142
It 'Should update the resource from PSCustomObject pipeline input' {
138-
$before = (Invoke-Executable { kubectl get deploy -n pskubectltest -o json } | ConvertFrom-Json).Items
143+
$before = (Invoke-Executable { kubectl get deploy hello-world -n pskubectltest -o json } | ConvertFrom-Json)
139144
$before.Metadata.Annotations.hello | Should -Be 'world'
140145
$modified = [PSCustomObject]@{
141146
Kind = 'Deployment'
@@ -182,18 +187,31 @@ Describe Publish-KubeResource {
182187
$result | Should -Not -BeNullOrEmpty
183188
$result | Should -BeOfType KubeClient.Models.DeploymentV1
184189
$result.Metadata.Annotations['hello'] | Should -Be 'changed'
185-
$after = (Invoke-Executable { kubectl get deploy -n pskubectltest -o json } | ConvertFrom-Json).Items
190+
$after = (Invoke-Executable { kubectl get deploy hello-world -n pskubectltest -o json } | ConvertFrom-Json)
191+
$after.Metadata.Annotations.hello | Should -Be 'changed'
192+
}
193+
194+
It -Skip 'Should update the resource from modified Get-KubeResource pipeline input' {
195+
$before = (Invoke-Executable { kubectl get deploy hello-world -n pskubectltest -o json } | ConvertFrom-Json)
196+
$before.Metadata.Annotations.hello | Should -Be 'world'
197+
$modified = Get-KubeResource -Kind Deployment -Namespace pskubectltest -Name hello-world
198+
$modified.Metadata.Annotations['hello'] = 'changed'
199+
$result = $modified | Publish-KubeResource
200+
$result | Should -Not -BeNullOrEmpty
201+
$result | Should -BeOfType KubeClient.Models.DeploymentV1
202+
$result.Metadata.Annotations['hello'] | Should -Be 'changed'
203+
$after = (Invoke-Executable { kubectl get deploy hello-world -n pskubectltest -o json } | ConvertFrom-Json)
186204
$after.Metadata.Annotations.hello | Should -Be 'changed'
187205
}
188206

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

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

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

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

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

271+
Describe Get-KubeResourceKinds {
272+
It 'Should return resource kinds' {
273+
$kinds = Get-KubeResourceKinds | ForEach-Object Kind
274+
$kinds | Should -Contain 'Deployment'
275+
$kinds | Should -Contain 'Pod'
276+
}
277+
}
278+
279+
Describe Get-KubeLog {
280+
BeforeEach {
281+
Initialize-TestNamespace
282+
Initialize-TestDeployment
283+
}
284+
285+
It 'Should return the logs of a given pod' {
286+
$logs = Get-KubeResource Pod -Namespace pskubectltest -Name hello-world-log-* | Get-KubeLog
287+
$logs -split "`n" | Should -Contain 'Hello from Docker!'
288+
}
289+
}
290+
253291
Describe Get-KubeConfig {
254292

255293
It 'Should return kube configuration' {
@@ -260,3 +298,55 @@ Describe Get-KubeConfig {
260298
$config.Contexts | Should -Not -BeNullOrEmpty
261299
}
262300
}
301+
302+
Describe Convert-KubeYaml {
303+
It 'Should read in YAML' {
304+
$parsed = Get-Content -Raw $PSScriptRoot/test.Deployment.yml | ConvertFrom-KubeYaml
305+
$parsed.PSObject.TypeNames | Should -Contain 'KubeClient.Models.DeploymentV1'
306+
$parsed.Metadata.Name | Should -Be 'hello-world'
307+
$parsed.Spec.Replicas | Should -Be 2
308+
}
309+
It 'Should round-trip' {
310+
$yaml = Get-Content -Raw $PSScriptRoot/test.Deployment.yml
311+
$yaml | ConvertFrom-KubeYaml | ConvertTo-KubeYaml | Should -Be $yaml
312+
}
313+
}
314+
315+
Describe ConvertTo-KubeYaml {
316+
BeforeAll {
317+
Initialize-TestNamespace
318+
Initialize-TestDeployment
319+
}
320+
321+
It 'Should encode PSCustomObjects' {
322+
$deploy = [PSCustomObject]@{
323+
Kind = 'Deployment'
324+
ApiVersion = 'apps/v1'
325+
Metadata = [PSCustomObject]@{
326+
Name = 'hello-world'
327+
Namespace = 'pskubectltest'
328+
Annotations = @{
329+
'hello' = 'changed'
330+
}
331+
}
332+
}
333+
$yaml = @(
334+
'kind: Deployment',
335+
'apiVersion: apps/v1',
336+
'metadata:',
337+
' name: hello-world',
338+
' namespace: pskubectltest',
339+
' annotations:',
340+
' hello: changed',
341+
''
342+
) -join "`n"
343+
$deploy | ConvertTo-KubeYaml | Should -Be $yaml
344+
}
345+
346+
It 'Should encode Get-KubeResource output to YAML' {
347+
$parsed = Get-KubeResource -Kind Deployment -Namespace pskubectltest -Name hello-world | ConvertTo-KubeYaml | ConvertFrom-KubeYaml
348+
$parsed.Metadata.Name | Should -Be 'hello-world'
349+
$parsed.Spec.Replicas | Should -Be 2
350+
$parsed.Status.Replicas | Should -Be 2
351+
}
352+
}

Tests/log.Deployment.yml

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: hello-world-log
5+
namespace: pskubectltest
6+
annotations:
7+
hello: world
8+
spec:
9+
selector:
10+
matchLabels:
11+
app: hello-world-log
12+
replicas: 1
13+
template:
14+
metadata:
15+
labels:
16+
app: hello-world-log
17+
spec:
18+
containers:
19+
- name: hello-world-log
20+
image: hello-world@sha256:b8ba256769a0ac28dd126d584e0a2011cd2877f3f76e093a7ae560f2a5301c00
21+
imagePullPolicy: IfNotPresent
22+
ports:
23+
- containerPort: 80
24+
protocol: TCP

Tests/test.Deployment.yml

+6-6
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ spec:
1616
app: hello-world
1717
spec:
1818
containers:
19-
- name: hello-world
20-
image: strm/helloworld-http@sha256:bd44b0ca80c26b5eba984bf498a9c3bab0eb1c59d30d8df3cb2c073937ee4e45
21-
imagePullPolicy: IfNotPresent
22-
ports:
23-
- containerPort: 80
24-
protocol: TCP
19+
- name: hello-world
20+
image: strm/helloworld-http@sha256:bd44b0ca80c26b5eba984bf498a9c3bab0eb1c59d30d8df3cb2c073937ee4e45
21+
imagePullPolicy: IfNotPresent
22+
ports:
23+
- containerPort: 80
24+
protocol: TCP

src/Cmdlets/ConvertFromKubeYamlCmdlet.cs

-11
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,7 @@
11
using System.Threading.Tasks;
2-
using System.IO;
32
using System.Management.Automation;
4-
using YamlDotNet.Serialization;
5-
using YamlDotNet.Serialization.NamingConventions;
6-
using System;
7-
using Microsoft.Extensions.Logging;
83
using System.Threading;
9-
using YamlDotNet.Core.Events;
10-
using YamlDotNet.Core;
114
using KubeClient.Models;
12-
using System.Collections.Generic;
13-
using System.Linq;
14-
using System.Collections;
15-
using System.Reflection;
165

176
namespace Kubectl.Cmdlets {
187
[Cmdlet(VerbsData.ConvertFrom, "KubeYaml")]

src/Cmdlets/GetKubeResourceKindsCmdlet.cs

+3-7
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
1-
using System;
2-
using System.Collections.Generic;
31
using System.Linq;
42
using System.Management.Automation;
53
using System.Threading;
64
using System.Threading.Tasks;
7-
using KubeClient;
8-
using KubeClient.Models;
9-
using KubeClient.ResourceClients;
10-
using Microsoft.Extensions.Logging;
115

126
namespace Kubectl.Cmdlets {
137
[Cmdlet(VerbsCommon.Get, "KubeResourceKinds")]
@@ -24,7 +18,9 @@ protected override async Task ProcessRecordAsync(CancellationToken cancellationT
2418
Kind = pair.kind,
2519
ApiVersion = pair.apiVersion
2620
});
27-
WriteObject(kinds);
21+
foreach (var kind in kinds) {
22+
WriteObject(kind);
23+
}
2824
}
2925
}
3026
}

src/Cmdlets/DeployKubeResourceCmdlet.cs src/Cmdlets/PublishKubeResourceCmdlet.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ public sealed class DeployKubeResourceCmdlet : KubeApiCmdlet {
2323
[ValidateNotNull()]
2424
public object Resource { get; set; }
2525

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

3029
private KubeYamlDeserializer deserializer;

0 commit comments

Comments
 (0)