Add more unit tests for Transform

This commit is contained in:
Janet Kuo 2016-08-15 16:02:01 -07:00
parent 08488f8fdc
commit c18288a023
9 changed files with 122 additions and 190 deletions

View File

@ -45,14 +45,12 @@ func InitRC(name string, service kobject.ServiceConfig, replicas int) *api.Repli
},
ObjectMeta: api.ObjectMeta{
Name: name,
//Labels: map[string]string{"service": name},
},
Spec: api.ReplicationControllerSpec{
Selector: map[string]string{"service": name},
Replicas: int32(replicas),
Template: &api.PodTemplateSpec{
ObjectMeta: api.ObjectMeta{
//Labels: map[string]string{"service": name},
Labels: transformer.ConfigLabels(name),
},
Spec: api.PodSpec{
Containers: []api.Container{
@ -68,45 +66,37 @@ func InitRC(name string, service kobject.ServiceConfig, replicas int) *api.Repli
return rc
}
// Init SC object
func InitSC(name string, service kobject.ServiceConfig) *api.Service {
sc := &api.Service{
// Init Svc object
func InitSvc(name string, service kobject.ServiceConfig) *api.Service {
svc := &api.Service{
TypeMeta: unversioned.TypeMeta{
Kind: "Service",
APIVersion: "v1",
},
ObjectMeta: api.ObjectMeta{
Name: name,
//Labels: map[string]string{"service": name},
Name: name,
Labels: transformer.ConfigLabels(name),
},
Spec: api.ServiceSpec{
Selector: map[string]string{"service": name},
Selector: transformer.ConfigLabels(name),
},
}
return sc
return svc
}
// Init DC object
func InitDC(name string, service kobject.ServiceConfig, replicas int) *extensions.Deployment {
// Init Deployment
func InitD(name string, service kobject.ServiceConfig, replicas int) *extensions.Deployment {
dc := &extensions.Deployment{
TypeMeta: unversioned.TypeMeta{
Kind: "Deployment",
APIVersion: "extensions/v1beta1",
},
ObjectMeta: api.ObjectMeta{
Name: name,
Labels: map[string]string{"service": name},
Name: name,
},
Spec: extensions.DeploymentSpec{
Replicas: int32(replicas),
Selector: &unversioned.LabelSelector{
MatchLabels: map[string]string{"service": name},
},
//UniqueLabelKey: p.Name,
Template: api.PodTemplateSpec{
ObjectMeta: api.ObjectMeta{
Labels: map[string]string{"service": name},
},
Spec: api.PodSpec{
Containers: []api.Container{
{
@ -133,9 +123,6 @@ func InitDS(name string, service kobject.ServiceConfig) *extensions.DaemonSet {
},
Spec: extensions.DaemonSetSpec{
Template: api.PodTemplateSpec{
ObjectMeta: api.ObjectMeta{
Name: name,
},
Spec: api.PodSpec{
Containers: []api.Container{
{
@ -238,10 +225,10 @@ func (k *Kubernetes) Transform(komposeObject kobject.KomposeObject, opt kobject.
var objects []runtime.Object
svcnames = append(svcnames, name)
sc := InitSC(name, service)
svc := InitSvc(name, service)
if opt.CreateD {
objects = append(objects, InitDC(name, service, opt.Replicas))
objects = append(objects, InitD(name, service, opt.Replicas))
}
if opt.CreateDS {
objects = append(objects, InitDS(name, service))
@ -264,15 +251,11 @@ func (k *Kubernetes) Transform(komposeObject kobject.KomposeObject, opt kobject.
// Configure the service ports.
servicePorts := ConfigServicePorts(name, service)
sc.Spec.Ports = servicePorts
// Configure label
labels := transformer.ConfigLabels(name)
sc.ObjectMeta.Labels = labels
svc.Spec.Ports = servicePorts
// Configure annotations
annotations := transformer.ConfigAnnotations(service)
sc.ObjectMeta.Annotations = annotations
svc.ObjectMeta.Annotations = annotations
// fillTemplate fills the pod template with the value calculated from config
fillTemplate := func(template *api.PodTemplateSpec) {
@ -288,7 +271,7 @@ func (k *Kubernetes) Transform(komposeObject kobject.KomposeObject, opt kobject.
}
}
template.Spec.Containers[0].Ports = ports
template.ObjectMeta.Labels = labels
template.ObjectMeta.Labels = transformer.ConfigLabels(name)
// Configure the container restart policy.
switch service.Restart {
case "", "always":
@ -304,7 +287,6 @@ func (k *Kubernetes) Transform(komposeObject kobject.KomposeObject, opt kobject.
// fillObjectMeta fills the metadata with the value calculated from config
fillObjectMeta := func(meta *api.ObjectMeta) {
meta.Labels = labels
meta.Annotations = annotations
}
@ -315,7 +297,7 @@ func (k *Kubernetes) Transform(komposeObject kobject.KomposeObject, opt kobject.
// If ports not provided in configuration we will not make service
if PortsExist(name, service) {
objects = append(objects, sc)
objects = append(objects, svc)
}
allobjects = append(allobjects, objects...)

View File

@ -23,6 +23,7 @@ import (
deployapi "github.com/openshift/origin/pkg/deploy/api"
"github.com/skippbox/kompose/pkg/kobject"
"github.com/skippbox/kompose/pkg/transformer"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/extensions"
@ -38,19 +39,19 @@ func newServiceConfig() kobject.ServiceConfig {
WorkingDir: "dir",
Args: []string{"arg1", "arg2"},
Volumes: []string{"/tmp/volume"},
Network: []string{"network1", "network2"},
Labels: map[string]string{"service": "app"},
Network: []string{"network1", "network2"}, // not supported
Labels: nil,
Annotations: map[string]string{"abc": "def"},
CPUSet: "cpu_set",
CPUShares: 1,
CPUQuota: 1,
CapAdd: []string{"cap_add"},
CapDrop: []string{"cap_drop"},
Entrypoint: []string{"entrypoint"},
Expose: []string{"expose"},
CPUSet: "cpu_set", // not supported
CPUShares: 1, // not supported
CPUQuota: 1, // not supported
CapAdd: []string{"cap_add"}, // not supported
CapDrop: []string{"cap_drop"}, // not supported
Entrypoint: []string{"entrypoint"}, // not supported
Expose: []string{"expose"}, // not supported
Privileged: true,
Restart: "always",
User: "user",
User: "user", // not supported
}
}
@ -114,7 +115,22 @@ func equalPorts(kPorts []kobject.Ports, k8sPorts []api.ContainerPort) bool {
return true
}
func checkPodTemplate(config kobject.ServiceConfig, template api.PodTemplateSpec) error {
func equalStringMaps(map1 map[string]string, map2 map[string]string) bool {
if len(map1) != len(map2) {
return false
}
for k, v := range map1 {
if map2[k] != v {
return false
}
}
return true
}
func checkPodTemplate(config kobject.ServiceConfig, template api.PodTemplateSpec, expectedLabels map[string]string) error {
if len(template.Spec.Containers) == 0 {
return fmt.Errorf("Failed to set container: %#v vs. %#v", config, template)
}
container := template.Spec.Containers[0]
// FIXME: we should support container name and uncomment this test
//if config.ContainerName != container.Name {
@ -143,19 +159,43 @@ func checkPodTemplate(config kobject.ServiceConfig, template api.PodTemplateSpec
(template.Spec.Volumes[0].VolumeSource.HostPath == nil && template.Spec.Volumes[0].VolumeSource.EmptyDir == nil) {
return fmt.Errorf("Found incorrect volumes: %v vs. %#v", config.Volumes, template.Spec.Volumes)
}
// We only set controller labels here and k8s server will take care of other defaults, such as selectors
if !equalStringMaps(expectedLabels, template.Labels) {
return fmt.Errorf("Found different template labels: %#v vs. %#v", expectedLabels, template.Labels)
}
restartPolicyMapping := map[string]api.RestartPolicy{"always": api.RestartPolicyAlways}
if restartPolicyMapping[config.Restart] != template.Spec.RestartPolicy {
return fmt.Errorf("Found incorrect restart policy: %v vs. %v", config.Restart, template.Spec.RestartPolicy)
}
if len(template.Labels) != 1 || len(template.Labels["service"]) == 0 {
return fmt.Errorf("Found incorrect labels: %#v", template.Labels)
if config.Privileged == privilegedNilOrFalse(template) {
return fmt.Errorf("Found different template privileged: %#v vs. %#v", config.Privileged, template.Spec.Containers[0].SecurityContext)
}
return nil
}
func privilegedNilOrFalse(template api.PodTemplateSpec) bool {
return len(template.Spec.Containers) == 0 || template.Spec.Containers[0].SecurityContext == nil ||
template.Spec.Containers[0].SecurityContext.Privileged == nil || *template.Spec.Containers[0].SecurityContext.Privileged == false
}
func checkService(config kobject.ServiceConfig, svc *api.Service, expectedLabels map[string]string) error {
if !equalStringMaps(expectedLabels, svc.Spec.Selector) {
return fmt.Errorf("Found unexpected selector: %#v vs. %#v", expectedLabels, svc.Spec.Selector)
}
// TODO: finish this
return nil
}
func checkService(config kobject.ServiceConfig, svc *api.Service) error {
// TODO: finish this
func checkMeta(config kobject.ServiceConfig, meta api.ObjectMeta, expectedName string, shouldSetLabels bool) error {
if expectedName != meta.Name {
return fmt.Errorf("Found unexpected name: %s vs. %s", expectedName, meta.Name)
}
if !equalStringMaps(config.Annotations, meta.Annotations) {
return fmt.Errorf("Found different annotations: %#v vs. %#v", config.Annotations, meta.Annotations)
}
if shouldSetLabels != (len(meta.Labels) > 0) {
return fmt.Errorf("Unexpected labels: %#v", meta.Labels)
}
return nil
}
@ -166,62 +206,100 @@ func TestKomposeConvert(t *testing.T) {
opt kobject.ConvertOptions
expectedNumObjs int
}{
"Convert to Deployments": {newKomposeObject(), kobject.ConvertOptions{CreateD: true, Replicas: replicas}, 2},
"Convert to Deployments (D)": {newKomposeObject(), kobject.ConvertOptions{CreateD: true, Replicas: replicas}, 2},
"Convert to DaemonSets (DS)": {newKomposeObject(), kobject.ConvertOptions{CreateDS: true}, 2},
"Convert to ReplicationController (RC)": {newKomposeObject(), kobject.ConvertOptions{CreateRC: true, Replicas: replicas}, 2},
"Convert to D, DS, and RC": {newKomposeObject(), kobject.ConvertOptions{CreateD: true, CreateDS: true, CreateRC: true, Replicas: replicas}, 4},
// TODO: add more tests
}
for name, test := range testCases {
t.Log("Test case:", name)
k := Kubernetes{}
// Run Transform
objs := k.Transform(test.komposeObject, test.opt)
if len(objs) != test.expectedNumObjs {
t.Errorf("Expected %d objects returned, got %d", test.expectedNumObjs, len(objs))
}
var foundSVC, foundD, foundDS, foundRC, foundDC bool
name := "app"
labels := transformer.ConfigLabels(name)
config := test.komposeObject.ServiceConfigs[name]
// Check results
for _, obj := range objs {
if svc, ok := obj.(*api.Service); ok {
if err := checkService(test.komposeObject.ServiceConfigs["app"], svc); err != nil {
if err := checkService(config, svc, labels); err != nil {
t.Errorf("%v", err)
}
if err := checkMeta(config, svc.ObjectMeta, name, true); err != nil {
t.Errorf("%v", err)
}
foundSVC = true
}
if test.opt.CreateD {
if d, ok := obj.(*extensions.Deployment); ok {
if err := checkPodTemplate(test.komposeObject.ServiceConfigs["app"], d.Spec.Template); err != nil {
if err := checkPodTemplate(config, d.Spec.Template, labels); err != nil {
t.Errorf("%v", err)
}
if err := checkMeta(config, d.ObjectMeta, name, false); err != nil {
t.Errorf("%v", err)
}
if (int)(d.Spec.Replicas) != replicas {
t.Errorf("Expected %d replicas, got %d", replicas, d.Spec.Replicas)
}
if d.Spec.Selector != nil && len(d.Spec.Selector.MatchLabels) > 0 {
t.Errorf("Expect selector be unset, got: %#v", d.Spec.Selector)
}
foundD = true
}
}
if test.opt.CreateDS {
if ds, ok := obj.(*extensions.DaemonSet); ok {
if err := checkPodTemplate(test.komposeObject.ServiceConfigs["app"], ds.Spec.Template); err != nil {
if err := checkPodTemplate(config, ds.Spec.Template, labels); err != nil {
t.Errorf("%v", err)
}
if err := checkMeta(config, ds.ObjectMeta, name, false); err != nil {
t.Errorf("%v", err)
}
if ds.Spec.Selector != nil && len(ds.Spec.Selector.MatchLabels) > 0 {
t.Errorf("Expect selector be unset, got: %#v", ds.Spec.Selector)
}
foundDS = true
}
}
if test.opt.CreateRC {
if rc, ok := obj.(*api.ReplicationController); ok {
if err := checkPodTemplate(test.komposeObject.ServiceConfigs["app"], *rc.Spec.Template); err != nil {
if err := checkPodTemplate(config, *rc.Spec.Template, labels); err != nil {
t.Errorf("%v", err)
}
if err := checkMeta(config, rc.ObjectMeta, name, false); err != nil {
t.Errorf("%v", err)
}
if (int)(rc.Spec.Replicas) != replicas {
t.Errorf("Expected %d replicas, got %d", replicas, rc.Spec.Replicas)
}
if len(rc.Spec.Selector) > 0 {
t.Errorf("Expect selector be unset, got: %#v", rc.Spec.Selector)
}
foundRC = true
}
}
// TODO: k8s & openshift transformer is now separated; either separate the test or combine the transformer
if test.opt.CreateDeploymentConfig {
if dc, ok := obj.(*deployapi.DeploymentConfig); ok {
if err := checkPodTemplate(test.komposeObject.ServiceConfigs["app"], *dc.Spec.Template); err != nil {
if err := checkPodTemplate(config, *dc.Spec.Template, labels); err != nil {
t.Errorf("%v", err)
}
if err := checkMeta(config, dc.ObjectMeta, name, false); err != nil {
t.Errorf("%v", err)
}
if (int)(dc.Spec.Replicas) != replicas {
t.Errorf("Expected %d replicas, got %d", replicas, dc.Spec.Replicas)
}
if len(dc.Spec.Selector) > 0 {
t.Errorf("Expect selector be unset, got: %#v", dc.Spec.Selector)
}
foundDC = true
}
}

View File

@ -74,10 +74,10 @@ func (k *OpenShift) Transform(komposeObject kobject.KomposeObject, opt kobject.C
var objects []runtime.Object
svcnames = append(svcnames, name)
sc := kubernetes.InitSC(name, service)
svc := kubernetes.InitSvc(name, service)
if opt.CreateD {
objects = append(objects, kubernetes.InitDC(name, service, opt.Replicas))
objects = append(objects, kubernetes.InitD(name, service, opt.Replicas))
}
if opt.CreateDS {
objects = append(objects, kubernetes.InitDS(name, service))
@ -103,15 +103,15 @@ func (k *OpenShift) Transform(komposeObject kobject.KomposeObject, opt kobject.C
// Configure the service ports.
servicePorts := kubernetes.ConfigServicePorts(name, service)
sc.Spec.Ports = servicePorts
svc.Spec.Ports = servicePorts
// Configure label
labels := transformer.ConfigLabels(name)
sc.ObjectMeta.Labels = labels
svc.ObjectMeta.Labels = labels
// Configure annotations
annotations := transformer.ConfigAnnotations(service)
sc.ObjectMeta.Annotations = annotations
svc.ObjectMeta.Annotations = annotations
// fillTemplate fills the pod template with the value calculated from config
fillTemplate := func(template *api.PodTemplateSpec) {
@ -154,7 +154,7 @@ func (k *OpenShift) Transform(komposeObject kobject.KomposeObject, opt kobject.C
// If ports not provided in configuration we will not make service
if kubernetes.PortsExist(name, service) {
objects = append(objects, sc)
objects = append(objects, svc)
}
allobjects = append(allobjects, objects...)
}

View File

@ -9,17 +9,9 @@
"metadata": {
"name": "etherpad",
"creationTimestamp": null,
"labels": {
"service": "etherpad"
}
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"service": "etherpad"
}
},
"template": {
"metadata": {
"creationTimestamp": null,
@ -103,17 +95,9 @@
"metadata": {
"name": "mariadb",
"creationTimestamp": null,
"labels": {
"service": "mariadb"
}
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"service": "mariadb"
}
},
"template": {
"metadata": {
"creationTimestamp": null,

View File

@ -9,17 +9,9 @@
"metadata": {
"name": "flask",
"creationTimestamp": null,
"labels": {
"service": "flask"
}
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"service": "flask"
}
},
"template": {
"metadata": {
"creationTimestamp": null,
@ -91,17 +83,9 @@
"metadata": {
"name": "redis",
"creationTimestamp": null,
"labels": {
"service": "redis"
}
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"service": "redis"
}
},
"template": {
"metadata": {
"creationTimestamp": null,

View File

@ -9,17 +9,9 @@
"metadata": {
"name": "gitlab",
"creationTimestamp": null,
"labels": {
"service": "gitlab"
}
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"service": "gitlab"
}
},
"template": {
"metadata": {
"creationTimestamp": null,
@ -135,17 +127,9 @@
"metadata": {
"name": "postgresql",
"creationTimestamp": null,
"labels": {
"service": "postgresql"
}
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"service": "postgresql"
}
},
"template": {
"metadata": {
"creationTimestamp": null,
@ -221,17 +205,9 @@
"metadata": {
"name": "redis",
"creationTimestamp": null,
"labels": {
"service": "redis"
}
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"service": "redis"
}
},
"template": {
"metadata": {
"creationTimestamp": null,

View File

@ -9,17 +9,9 @@
"metadata": {
"name": "node2",
"creationTimestamp": null,
"labels": {
"service": "node2"
}
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"service": "node2"
}
},
"template": {
"metadata": {
"creationTimestamp": null,
@ -80,17 +72,9 @@
"metadata": {
"name": "node3",
"creationTimestamp": null,
"labels": {
"service": "node3"
}
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"service": "node3"
}
},
"template": {
"metadata": {
"creationTimestamp": null,
@ -151,17 +135,9 @@
"metadata": {
"name": "redis",
"creationTimestamp": null,
"labels": {
"service": "redis"
}
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"service": "redis"
}
},
"template": {
"metadata": {
"creationTimestamp": null,
@ -223,17 +199,9 @@
"metadata": {
"name": "nginx",
"creationTimestamp": null,
"labels": {
"service": "nginx"
}
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"service": "nginx"
}
},
"template": {
"metadata": {
"creationTimestamp": null,
@ -294,17 +262,9 @@
"metadata": {
"name": "node1",
"creationTimestamp": null,
"labels": {
"service": "node1"
}
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"service": "node1"
}
},
"template": {
"metadata": {
"creationTimestamp": null,

View File

@ -9,17 +9,9 @@
"metadata": {
"name": "mariadb",
"creationTimestamp": null,
"labels": {
"service": "mariadb"
}
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"service": "mariadb"
}
},
"template": {
"metadata": {
"creationTimestamp": null,
@ -99,17 +91,9 @@
"metadata": {
"name": "wordpress",
"creationTimestamp": null,
"labels": {
"service": "wordpress"
}
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"service": "wordpress"
}
},
"template": {
"metadata": {
"creationTimestamp": null,

View File

@ -9,17 +9,9 @@
"metadata": {
"name": "mariadb",
"creationTimestamp": null,
"labels": {
"service": "mariadb"
}
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"service": "mariadb"
}
},
"template": {
"metadata": {
"creationTimestamp": null,
@ -99,17 +91,9 @@
"metadata": {
"name": "wordpress",
"creationTimestamp": null,
"labels": {
"service": "wordpress"
}
},
"spec": {
"replicas": 1,
"selector": {
"matchLabels": {
"service": "wordpress"
}
},
"template": {
"metadata": {
"creationTimestamp": null,