using System; using System.Collections.Generic; using System.IO; using System.Linq; using k8s; using k8s.Models; using Xunit; namespace k8s.Tests { public class YamlTests { [Fact] public void LoadAllFromString() { var content = @"apiVersion: v1 kind: Pod metadata: name: foo --- apiVersion: v1 kind: Namespace metadata: name: ns"; var types = new Dictionary(); types.Add("v1/Pod", typeof(V1Pod)); types.Add("v1/Namespace", typeof(V1Namespace)); var objs = Yaml.LoadAllFromString(content, types); Assert.Equal(2, objs.Count); Assert.IsType(objs[0]); Assert.IsType(objs[1]); Assert.Equal("foo", ((V1Pod) objs[0]).Metadata.Name); Assert.Equal("ns", ((V1Namespace) objs[1]).Metadata.Name); } [Fact] public void LoadFromString() { var content = @"apiVersion: v1 kind: Pod metadata: name: foo "; var obj = Yaml.LoadFromString(content); Assert.Equal("foo", obj.Metadata.Name); } [Fact] public void LoadNamespacedFromString() { var content = @"apiVersion: v1 kind: Pod metadata: namespace: bar name: foo "; var obj = Yaml.LoadFromString(content); Assert.Equal("foo", obj.Metadata.Name); Assert.Equal("bar", obj.Metadata.NamespaceProperty); } [Fact] public void LoadPropertyNamedReadOnlyFromString() { var content = @"apiVersion: v1 kind: Pod metadata: namespace: bar name: foo spec: containers: - image: nginx volumeMounts: - name: vm1 mountPath: /vm1 readOnly: true - name: vm2 mountPath: /vm2 readOnly: false "; var obj = Yaml.LoadFromString(content); Assert.True(obj.Spec.Containers[0].VolumeMounts[0].ReadOnlyProperty); Assert.False(obj.Spec.Containers[0].VolumeMounts[1].ReadOnlyProperty); } [Fact] public void LoadFromStream() { var content = @"apiVersion: v1 kind: Pod metadata: name: foo "; using (MemoryStream stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(content))) { var obj = Yaml.LoadFromStreamAsync(stream).Result; Assert.Equal("foo", obj.Metadata.Name); } } [Fact] public void WriteToString() { var pod = new V1Pod() { ApiVersion = "v1", Kind = "Pod", Metadata = new V1ObjectMeta() { Name = "foo" } }; var yaml = Yaml.SaveToString(pod); Assert.True(ToLines(@"apiVersion: v1 kind: Pod metadata: name: foo").SequenceEqual(ToLines(yaml))); } [Fact] public void WriteNamespacedToString() { var pod = new V1Pod() { ApiVersion = "v1", Kind = "Pod", Metadata = new V1ObjectMeta() { Name = "foo", NamespaceProperty = "bar" } }; var yaml = Yaml.SaveToString(pod); Assert.True(ToLines(@"apiVersion: v1 kind: Pod metadata: name: foo namespace: bar").SequenceEqual(ToLines(yaml))); } [Fact] public void WritePropertyNamedReadOnlyToString() { var pod = new V1Pod() { ApiVersion = "v1", Kind = "Pod", Metadata = new V1ObjectMeta() { Name = "foo", NamespaceProperty = "bar" }, Spec = new V1PodSpec() { Containers = new[] { new V1Container() { Image = "nginx", VolumeMounts = new[] { new V1VolumeMount { Name = "vm1", MountPath = "/vm1", ReadOnlyProperty = true }, new V1VolumeMount { Name = "vm2", MountPath = "/vm2", ReadOnlyProperty = false }, } } } } }; var yaml = Yaml.SaveToString(pod); Assert.True(ToLines(@"apiVersion: v1 kind: Pod metadata: name: foo namespace: bar spec: containers: - image: nginx volumeMounts: - mountPath: /vm1 name: vm1 readOnly: true - mountPath: /vm2 name: vm2 readOnly: false").SequenceEqual(ToLines(yaml))); } private static IEnumerable ToLines(string s) { using (var reader = new StringReader(s)) { for (; ; ) { var line = reader.ReadLine(); if (line == null) { yield break; } yield return line; } } } [Fact] public void CpuRequestAndLimitFromString() { // Taken from https://raw.githubusercontent.com/kubernetes/website/master/docs/tasks/configure-pod-container/cpu-request-limit.yaml, although // the 'namespace' property on 'metadata' was removed since it was rejected by the C# client. var content = @"apiVersion: v1 kind: Pod metadata: name: cpu-demo spec: containers: - name: cpu-demo-ctr image: vish/stress resources: limits: cpu: ""1"" requests: cpu: ""0.5"" args: - -cpus - ""2"""; var obj = Yaml.LoadFromString(content); Assert.NotNull(obj?.Spec?.Containers); var container = Assert.Single(obj.Spec.Containers); Assert.NotNull(container.Resources); Assert.NotNull(container.Resources.Limits); Assert.NotNull(container.Resources.Requests); var cpuLimit = Assert.Single(container.Resources.Limits); var cpuRequest = Assert.Single(container.Resources.Requests); Assert.Equal("cpu", cpuLimit.Key); Assert.Equal("1", cpuLimit.Value.ToString()); Assert.Equal("cpu", cpuRequest.Key); Assert.Equal("500m", cpuRequest.Value.ToString()); } [Fact] public void LoadIntOrString() { var content = @"apiVersion: v1 kind: Service spec: ports: - port: 3000 targetPort: 3000 "; var obj = Yaml.LoadFromString(content); Assert.Equal(3000, obj.Spec.Ports[0].Port); Assert.Equal(3000, (int)obj.Spec.Ports[0].TargetPort); } [Fact] public void SerializeIntOrString() { var content = @"apiVersion: v1 kind: Service metadata: labels: app: test name: test-svc spec: ports: - port: 3000 targetPort: 3000"; Dictionary labels = new Dictionary { {"app", "test"} }; var obj = new V1Service { Kind = "Service", Metadata = new V1ObjectMeta(labels: labels, name: "test-svc"), ApiVersion = "v1", Spec = new V1ServiceSpec { Ports = new List { new V1ServicePort { Port = 3000, TargetPort = 3000 } } } }; var output = Yaml.SaveToString(obj); Assert.True(ToLines(output).SequenceEqual(ToLines(content))); } } }