| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 | 
							- /*
 
-    Copyright 2020 Docker Compose CLI authors
 
-    Licensed under the Apache License, Version 2.0 (the "License");
 
-    you may not use this file except in compliance with the License.
 
-    You may obtain a copy of the License at
 
-        http://www.apache.org/licenses/LICENSE-2.0
 
-    Unless required by applicable law or agreed to in writing, software
 
-    distributed under the License is distributed on an "AS IS" BASIS,
 
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
-    See the License for the specific language governing permissions and
 
-    limitations under the License.
 
- */
 
- package compose
 
- import (
 
- 	"context"
 
- 	"strconv"
 
- 	"testing"
 
- 	"github.com/compose-spec/compose-go/types"
 
- 	"github.com/golang/mock/gomock"
 
- 	"github.com/stretchr/testify/assert"
 
- 	compose "github.com/docker/compose/v2/pkg/api"
 
- 	"github.com/docker/compose/v2/pkg/mocks"
 
- )
 
- func TestViz(t *testing.T) {
 
- 	project := types.Project{
 
- 		Name:       "viz-test",
 
- 		WorkingDir: "/home",
 
- 		Services: []types.ServiceConfig{
 
- 			{
 
- 				Name:  "service1",
 
- 				Image: "image-for-service1",
 
- 				Ports: []types.ServicePortConfig{
 
- 					{
 
- 						Published: "80",
 
- 						Target:    80,
 
- 						Protocol:  "tcp",
 
- 					},
 
- 					{
 
- 						Published: "53",
 
- 						Target:    533,
 
- 						Protocol:  "udp",
 
- 					},
 
- 				},
 
- 				Networks: map[string]*types.ServiceNetworkConfig{
 
- 					"internal": nil,
 
- 				},
 
- 			},
 
- 			{
 
- 				Name:  "service2",
 
- 				Image: "image-for-service2",
 
- 				Ports: []types.ServicePortConfig{},
 
- 			},
 
- 			{
 
- 				Name:  "service3",
 
- 				Image: "some-image",
 
- 				DependsOn: map[string]types.ServiceDependency{
 
- 					"service2": {},
 
- 					"service1": {},
 
- 				},
 
- 			},
 
- 			{
 
- 				Name:  "service4",
 
- 				Image: "another-image",
 
- 				DependsOn: map[string]types.ServiceDependency{
 
- 					"service3": {},
 
- 				},
 
- 				Ports: []types.ServicePortConfig{
 
- 					{
 
- 						Published: "8080",
 
- 						Target:    80,
 
- 					},
 
- 				},
 
- 				Networks: map[string]*types.ServiceNetworkConfig{
 
- 					"external": nil,
 
- 				},
 
- 			},
 
- 			{
 
- 				Name:  "With host IP",
 
- 				Image: "user/image-name",
 
- 				DependsOn: map[string]types.ServiceDependency{
 
- 					"service1": {},
 
- 				},
 
- 				Ports: []types.ServicePortConfig{
 
- 					{
 
- 						Published: "8888",
 
- 						Target:    8080,
 
- 						HostIP:    "127.0.0.1",
 
- 					},
 
- 				},
 
- 			},
 
- 		},
 
- 		Networks: types.Networks{
 
- 			"internal": types.NetworkConfig{},
 
- 			"external": types.NetworkConfig{},
 
- 			"not-used": types.NetworkConfig{},
 
- 		},
 
- 		Volumes:          nil,
 
- 		Secrets:          nil,
 
- 		Configs:          nil,
 
- 		Extensions:       nil,
 
- 		ComposeFiles:     nil,
 
- 		Environment:      nil,
 
- 		DisabledServices: nil,
 
- 		Profiles:         nil,
 
- 	}
 
- 	mockCtrl := gomock.NewController(t)
 
- 	defer mockCtrl.Finish()
 
- 	cli := mocks.NewMockCli(mockCtrl)
 
- 	tested := composeService{
 
- 		dockerCli: cli,
 
- 	}
 
- 	ctx := context.Background()
 
- 	t.Run("viz (no ports, networks or image)", func(t *testing.T) {
 
- 		graphStr, err := tested.Viz(ctx, &project, compose.VizOptions{
 
- 			Indentation:      "  ",
 
- 			IncludePorts:     false,
 
- 			IncludeImageName: false,
 
- 			IncludeNetworks:  false,
 
- 		})
 
- 		assert.NoError(t, err, "viz command failed")
 
- 		// check indentation
 
- 		assert.Contains(t, graphStr, "\n  ", graphStr)
 
- 		assert.NotContains(t, graphStr, "\n   ", graphStr)
 
- 		// check digraph name
 
- 		assert.Contains(t, graphStr, "digraph \""+project.Name+"\"", graphStr)
 
- 		// check nodes
 
- 		for _, service := range project.Services {
 
- 			assert.Contains(t, graphStr, "\""+service.Name+"\" [style=\"filled\"", graphStr)
 
- 		}
 
- 		// check node attributes
 
- 		assert.NotContains(t, graphStr, "Networks", graphStr)
 
- 		assert.NotContains(t, graphStr, "Image", graphStr)
 
- 		assert.NotContains(t, graphStr, "Ports", graphStr)
 
- 		// check edges that SHOULD exist in the generated graph
 
- 		allowedEdges := make(map[string][]string)
 
- 		for _, service := range project.Services {
 
- 			allowedEdges[service.Name] = make([]string, 0, len(service.DependsOn))
 
- 			for depName := range service.DependsOn {
 
- 				allowedEdges[service.Name] = append(allowedEdges[service.Name], depName)
 
- 			}
 
- 		}
 
- 		for serviceName, dependencies := range allowedEdges {
 
- 			for _, dependencyName := range dependencies {
 
- 				assert.Contains(t, graphStr, "\""+serviceName+"\" -> \""+dependencyName+"\"", graphStr)
 
- 			}
 
- 		}
 
- 		// check edges that SHOULD NOT exist in the generated graph
 
- 		forbiddenEdges := make(map[string][]string)
 
- 		for _, service := range project.Services {
 
- 			forbiddenEdges[service.Name] = make([]string, 0, len(project.ServiceNames())-len(service.DependsOn))
 
- 			for _, serviceName := range project.ServiceNames() {
 
- 				_, edgeExists := service.DependsOn[serviceName]
 
- 				if !edgeExists {
 
- 					forbiddenEdges[service.Name] = append(forbiddenEdges[service.Name], serviceName)
 
- 				}
 
- 			}
 
- 		}
 
- 		for serviceName, forbiddenDeps := range forbiddenEdges {
 
- 			for _, forbiddenDep := range forbiddenDeps {
 
- 				assert.NotContains(t, graphStr, "\""+serviceName+"\" -> \""+forbiddenDep+"\"")
 
- 			}
 
- 		}
 
- 	})
 
- 	t.Run("viz (with ports, networks and image)", func(t *testing.T) {
 
- 		graphStr, err := tested.Viz(ctx, &project, compose.VizOptions{
 
- 			Indentation:      "\t",
 
- 			IncludePorts:     true,
 
- 			IncludeImageName: true,
 
- 			IncludeNetworks:  true,
 
- 		})
 
- 		assert.NoError(t, err, "viz command failed")
 
- 		// check indentation
 
- 		assert.Contains(t, graphStr, "\n\t", graphStr)
 
- 		assert.NotContains(t, graphStr, "\n\t\t", graphStr)
 
- 		// check digraph name
 
- 		assert.Contains(t, graphStr, "digraph \""+project.Name+"\"", graphStr)
 
- 		// check nodes
 
- 		for _, service := range project.Services {
 
- 			assert.Contains(t, graphStr, "\""+service.Name+"\" [style=\"filled\"", graphStr)
 
- 		}
 
- 		// check node attributes
 
- 		assert.Contains(t, graphStr, "Networks", graphStr)
 
- 		assert.Contains(t, graphStr, ">internal<", graphStr)
 
- 		assert.Contains(t, graphStr, ">external<", graphStr)
 
- 		assert.Contains(t, graphStr, "Image", graphStr)
 
- 		for _, service := range project.Services {
 
- 			assert.Contains(t, graphStr, ">"+service.Image+"<", graphStr)
 
- 		}
 
- 		assert.Contains(t, graphStr, "Ports", graphStr)
 
- 		for _, service := range project.Services {
 
- 			for _, portConfig := range service.Ports {
 
- 				assert.NotContains(t, graphStr, ">"+portConfig.Published+":"+strconv.Itoa(int(portConfig.Target))+"<", graphStr)
 
- 			}
 
- 		}
 
- 	})
 
- }
 
 
  |