1package connect
2
3import (
4	"strings"
5	"testing"
6
7	"github.com/stretchr/testify/require"
8)
9
10func TestServiceAndNamespaceTruncation(t *testing.T) {
11	type tcase struct {
12		service   string
13		namespace string
14		// if left as "" then its expected to not be truncated
15		expectedService string
16		// if left as "" then its expected to not be truncated
17		expectedNamespace string
18	}
19
20	cases := map[string]tcase{
21		"short-no-truncation": tcase{
22			service:   "foo",
23			namespace: "bar",
24		},
25		"long-service-no-truncation": tcase{
26			// -3 because thats the length of the namespace
27			service:   strings.Repeat("a", maxServiceAndNamespaceLen-3),
28			namespace: "bar",
29		},
30		"long-namespace-no-truncation": tcase{
31			service: "foo",
32			// -3 because thats the length of the service name
33			namespace: strings.Repeat("b", maxServiceAndNamespaceLen-3),
34		},
35		"truncate-service-only": tcase{
36			// this should force the service name to be truncated
37			service:         strings.Repeat("a", maxServiceAndNamespaceLen-minNamespaceNameLen+5),
38			expectedService: strings.Repeat("a", maxServiceAndNamespaceLen-minNamespaceNameLen),
39			// this is the maximum length that will never be truncated for a namespace
40			namespace: strings.Repeat("b", minNamespaceNameLen),
41		},
42		"truncate-namespace-only": tcase{
43			// this is the maximum length that will never be truncated for a service name
44			service: strings.Repeat("a", minServiceNameLen),
45			// this should force the namespace name to be truncated
46			namespace:         strings.Repeat("b", maxServiceAndNamespaceLen-minServiceNameLen+5),
47			expectedNamespace: strings.Repeat("b", maxServiceAndNamespaceLen-minServiceNameLen),
48		},
49		"truncate-both-even": tcase{
50			// this test would need to be update if the maxServiceAndNamespaceLen variable is updated
51			// I could put some more complex logic into here to prevent that but it would be mostly
52			// duplicating the logic in the function itself and thus not really be testing anything
53			//
54			// The original lengths of 50 / 51 were chose when maxServiceAndNamespaceLen would be 43
55			// Therefore a total of 58 characters must be removed. This was chose so that the value
56			// could be evenly split between the two strings.
57			service:           strings.Repeat("a", 50),
58			expectedService:   strings.Repeat("a", 21),
59			namespace:         strings.Repeat("b", 51),
60			expectedNamespace: strings.Repeat("b", 22),
61		},
62		"truncate-both-odd": tcase{
63			// this test would need to be update if the maxServiceAndNamespaceLen variable is updated
64			// I could put some more complex logic into here to prevent that but it would be mostly
65			// duplicating the logic in the function itself and thus not really be testing anything
66			//
67			// The original lengths of 50 / 57 were chose when maxServiceAndNamespaceLen would be 43
68			// Therefore a total of 57 characters must be removed. This was chose so that the value
69			// could not be evenly removed from both so the namespace should be truncated to a length
70			// 1 character more than the service.
71			service:           strings.Repeat("a", 50),
72			expectedService:   strings.Repeat("a", 21),
73			namespace:         strings.Repeat("b", 50),
74			expectedNamespace: strings.Repeat("b", 22),
75		},
76		"truncate-both-min-svc": tcase{
77			service:           strings.Repeat("a", minServiceNameLen+1),
78			expectedService:   strings.Repeat("a", minServiceNameLen),
79			namespace:         strings.Repeat("b", maxServiceAndNamespaceLen),
80			expectedNamespace: strings.Repeat("b", maxServiceAndNamespaceLen-minServiceNameLen),
81		},
82		"truncate-both-min-ns": tcase{
83			service:           strings.Repeat("a", maxServiceAndNamespaceLen),
84			expectedService:   strings.Repeat("a", maxServiceAndNamespaceLen-minNamespaceNameLen),
85			namespace:         strings.Repeat("b", minNamespaceNameLen+1),
86			expectedNamespace: strings.Repeat("b", minNamespaceNameLen),
87		},
88	}
89
90	for name, tc := range cases {
91		t.Run(name, func(t *testing.T) {
92			actualSvc, actualNamespace := truncateServiceAndNamespace(tc.service, tc.namespace)
93
94			expectedLen := len(tc.service) + len(tc.namespace)
95			if tc.expectedService != "" || tc.expectedNamespace != "" {
96				expectedLen = maxServiceAndNamespaceLen
97			}
98
99			actualLen := len(actualSvc) + len(actualNamespace)
100
101			require.Equal(t, expectedLen, actualLen, "Combined length of %d (svc: %d, ns: %d) does not match expected value of %d", actualLen, len(actualSvc), len(actualNamespace), expectedLen)
102
103			if tc.expectedService != "" {
104				require.Equal(t, tc.expectedService, actualSvc)
105			} else {
106				require.Equal(t, tc.service, actualSvc)
107			}
108			if tc.expectedNamespace != "" {
109				require.Equal(t, tc.expectedNamespace, actualNamespace)
110			} else {
111				require.Equal(t, tc.namespace, actualNamespace)
112			}
113		})
114	}
115}
116