github.com/khulnasoft/cli@v0.0.0-20240402070845-01bcad7beefa/cli/command/service/inspect_test.go (about)

     1  // FIXME(thaJeztah): remove once we are a module; the go:build directive prevents go from downgrading language version to go1.16:
     2  //go:build go1.19
     3  
     4  package service
     5  
     6  import (
     7  	"bytes"
     8  	"encoding/json"
     9  	"strings"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/docker/docker/api/types"
    14  	"github.com/docker/docker/api/types/container"
    15  	"github.com/docker/docker/api/types/swarm"
    16  	"github.com/khulnasoft/cli/cli/command/formatter"
    17  	"gotest.tools/v3/assert"
    18  	is "gotest.tools/v3/assert/cmp"
    19  	"gotest.tools/v3/golden"
    20  )
    21  
    22  func formatServiceInspect(t *testing.T, format formatter.Format, now time.Time) string {
    23  	t.Helper()
    24  	b := new(bytes.Buffer)
    25  
    26  	endpointSpec := &swarm.EndpointSpec{
    27  		Mode: "vip",
    28  		Ports: []swarm.PortConfig{
    29  			{
    30  				Protocol:   swarm.PortConfigProtocolTCP,
    31  				TargetPort: 5000,
    32  			},
    33  		},
    34  	}
    35  
    36  	two := uint64(2)
    37  
    38  	s := swarm.Service{
    39  		ID: "de179gar9d0o7ltdybungplod",
    40  		Meta: swarm.Meta{
    41  			Version:   swarm.Version{Index: 315},
    42  			CreatedAt: now,
    43  			UpdatedAt: now,
    44  		},
    45  		Spec: swarm.ServiceSpec{
    46  			Annotations: swarm.Annotations{
    47  				Name:   "my_service",
    48  				Labels: map[string]string{"com.label": "foo"},
    49  			},
    50  			TaskTemplate: swarm.TaskSpec{
    51  				LogDriver: &swarm.Driver{
    52  					Name: "driver",
    53  					Options: map[string]string{
    54  						"max-file": "5",
    55  					},
    56  				},
    57  				ContainerSpec: &swarm.ContainerSpec{
    58  					Image: "foo/bar@sha256:this_is_a_test",
    59  					Configs: []*swarm.ConfigReference{
    60  						{
    61  							ConfigID:   "mtc3i44r1awdoziy2iceg73z8",
    62  							ConfigName: "configtest.conf",
    63  							File: &swarm.ConfigReferenceFileTarget{
    64  								Name: "/configtest.conf",
    65  							},
    66  						},
    67  					},
    68  					Secrets: []*swarm.SecretReference{
    69  						{
    70  							SecretID:   "3hv39ehbbb4hdozo7spod9ftn",
    71  							SecretName: "secrettest.conf",
    72  							File: &swarm.SecretReferenceFileTarget{
    73  								Name: "/secrettest.conf",
    74  							},
    75  						},
    76  					},
    77  
    78  					Healthcheck: &container.HealthConfig{
    79  						Test:        []string{"CMD-SHELL", "curl"},
    80  						Interval:    4,
    81  						Retries:     3,
    82  						StartPeriod: 2,
    83  						Timeout:     1,
    84  					},
    85  				},
    86  				Resources: &swarm.ResourceRequirements{
    87  					Limits: &swarm.Limit{
    88  						NanoCPUs:    100000000000,
    89  						MemoryBytes: 10490000,
    90  						Pids:        20,
    91  					},
    92  				},
    93  				Networks: []swarm.NetworkAttachmentConfig{
    94  					{
    95  						Target:  "5vpyomhb6ievnk0i0o60gcnei",
    96  						Aliases: []string{"web"},
    97  					},
    98  				},
    99  			},
   100  			Mode: swarm.ServiceMode{
   101  				Replicated: &swarm.ReplicatedService{
   102  					Replicas: &two,
   103  				},
   104  			},
   105  			EndpointSpec: endpointSpec,
   106  		},
   107  		Endpoint: swarm.Endpoint{
   108  			Spec: *endpointSpec,
   109  			Ports: []swarm.PortConfig{
   110  				{
   111  					Protocol:      swarm.PortConfigProtocolTCP,
   112  					TargetPort:    5000,
   113  					PublishedPort: 30000,
   114  				},
   115  			},
   116  			VirtualIPs: []swarm.EndpointVirtualIP{
   117  				{
   118  					NetworkID: "6o4107cj2jx9tihgb0jyts6pj",
   119  					Addr:      "10.255.0.4/16",
   120  				},
   121  			},
   122  		},
   123  		UpdateStatus: &swarm.UpdateStatus{
   124  			StartedAt:   &now,
   125  			CompletedAt: &now,
   126  		},
   127  	}
   128  
   129  	ctx := formatter.Context{
   130  		Output: b,
   131  		Format: format,
   132  	}
   133  
   134  	err := InspectFormatWrite(ctx, []string{"de179gar9d0o7ltdybungplod"},
   135  		func(ref string) (any, []byte, error) {
   136  			return s, nil, nil
   137  		},
   138  		func(ref string) (any, []byte, error) {
   139  			return types.NetworkResource{
   140  				ID:   "5vpyomhb6ievnk0i0o60gcnei",
   141  				Name: "mynetwork",
   142  			}, nil, nil
   143  		},
   144  	)
   145  	if err != nil {
   146  		t.Fatal(err)
   147  	}
   148  	return b.String()
   149  }
   150  
   151  func TestPrettyPrint(t *testing.T) {
   152  	s := formatServiceInspect(t, NewFormat("pretty"), time.Now())
   153  	golden.Assert(t, s, "service-inspect-pretty.golden")
   154  }
   155  
   156  func TestPrettyPrintWithNoUpdateConfig(t *testing.T) {
   157  	s := formatServiceInspect(t, NewFormat("pretty"), time.Now())
   158  	if strings.Contains(s, "UpdateStatus") {
   159  		t.Fatal("Pretty print failed before parsing UpdateStatus")
   160  	}
   161  	if !strings.Contains(s, "mynetwork") {
   162  		t.Fatal("network name not found in inspect output")
   163  	}
   164  }
   165  
   166  func TestJSONFormatWithNoUpdateConfig(t *testing.T) {
   167  	now := time.Now()
   168  	// s1: [{"ID":..}]
   169  	// s2: {"ID":..}
   170  	s1 := formatServiceInspect(t, NewFormat(""), now)
   171  	s2 := formatServiceInspect(t, NewFormat("{{json .}}"), now)
   172  	var m1Wrap []map[string]any
   173  	if err := json.Unmarshal([]byte(s1), &m1Wrap); err != nil {
   174  		t.Fatal(err)
   175  	}
   176  	if len(m1Wrap) != 1 {
   177  		t.Fatalf("strange s1=%s", s1)
   178  	}
   179  	m1 := m1Wrap[0]
   180  	var m2 map[string]any
   181  	if err := json.Unmarshal([]byte(s2), &m2); err != nil {
   182  		t.Fatal(err)
   183  	}
   184  	assert.Check(t, is.DeepEqual(m1, m2))
   185  }
   186  
   187  func TestPrettyPrintWithConfigsAndSecrets(t *testing.T) {
   188  	s := formatServiceInspect(t, NewFormat("pretty"), time.Now())
   189  	assert.Check(t, is.Contains(s, "Log Driver:"), "Pretty print missing Log Driver")
   190  	assert.Check(t, is.Contains(s, "Configs:"), "Pretty print missing configs")
   191  	assert.Check(t, is.Contains(s, "Secrets:"), "Pretty print missing secrets")
   192  	assert.Check(t, is.Contains(s, "Healthcheck:"), "Pretty print missing healthcheck")
   193  }