Repository: kubernetes/kubernetes
File: cmd/kubelet/app/server_test.go (Go)

Code before:
				kubeletConfFile := filepath.Join(tempDir, "kubelet.conf")
				yamlData, err := yaml.Marshal(test.kubeletConfig) // Convert struct to YAML
				require.NoError(t, err, "failed to convert kubelet config to YAML")
				err = os.WriteFile(kubeletConfFile, yamlData, 0644)
				require.NoError(t, err, "failed to create config from YAML data")
				kubeletFlags.KubeletConfigFile = kubeletConfFile
				kubeletConfig = test.kubeletConfig
			}
			if len(test.dropin1) > 0 || len(test.dropin2) > 0 {
				// Create kubelet.conf.d directory and drop-in configuration files
				kubeletConfDir := filepath.Join(tempDir, "kubelet.conf.d")
				err := os.Mkdir(kubeletConfDir, 0755)
				require.NoError(t, err, "Failed to create kubelet.conf.d directory")

				if len(test.dropin1) > 0 {
					err = os.WriteFile(filepath.Join(kubeletConfDir, "10-kubelet.conf"), []byte(test.dropin1), 0644)
					require.NoError(t, err, "failed to create config from a yaml file")
				}

				if len(test.dropin2) > 0 {
					err = os.WriteFile(filepath.Join(kubeletConfDir, "20-kubelet.conf"), []byte(test.dropin2), 0644)
					require.NoError(t, err, "failed to create config from a yaml file")
				}

				// Merge the kubelet configurations
				ctx := context.Background()
				err = mergeKubeletConfigurations(ctx, kubeletConfig, kubeletConfDir)
				if test.expectMergeError == "" {
					require.NoError(t, err, "failed to merge kubelet drop-in configs")
				} else {
					require.Error(t, err)
					require.ErrorContains(t, err, test.expectMergeError)
				}
			}

			// Use kubelet config flag precedence
			err := kubeletConfigFlagPrecedence(kubeletConfig, test.cliArgs)
			require.NoError(t, err, "failed to set the kubelet config flag precedence")

			// Verify the merged configuration fields
			for fieldName, expectedValue := range test.overwrittenConfigFields {
				value := reflect.ValueOf(kubeletConfig).Elem()
				field := value.FieldByName(fieldName)
				require.Equal(t, expectedValue, field.Interface(), "Field mismatch: "+fieldName)
			}
		})
	}

	// Additional test case for file extension filtering
	t.Run("yaml files are ignored, only .conf files are loaded", func(t *testing.T) {
		tempDir := t.TempDir()

Review comment (suggestion):
Please use test context instead of creating new context. Call ktesting.Init in the beginning of the test or test run to get it.

Code after:
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
port: 7777
`,
				"20-should-be-ignored.txt": "readme text",
				"30-valid.conf": `
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
readOnlyPort: 10255
`,
			},
			overwrittenConfigFields: map[string]interface{}{
				"Port":         int32(9090),  // Port should remain unchanged as .yaml file should be ignored
				"ReadOnlyPort": int32(10255), // ReadOnlyPort should be set from .conf file
			},
			expectedSkippedFiles: []string{"10-should-be-ignored.yaml", "20-should-be-ignored.txt"},
		},
		{
			name: "invalid YAML syntax in drop-in file causes merge to fail",
			kubeletConfig: &kubeletconfiginternal.KubeletConfiguration{
				TypeMeta: metav1.TypeMeta{
					Kind:       "KubeletConfiguration",
					APIVersion: "kubelet.config.k8s.io/v1beta1",
				},
				Port: int32(9090),
			},
			customDropins: map[string]string{
				"10-malformed.conf": `
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
port: [this is not valid
  indentation is wrong
    more indentation
`,
			},
			expectMergeError: "10-malformed.conf",
		},
	}

	for _, test := range testCases {
		t.Run(test.name, func(t *testing.T) {
			// Prepare a temporary directory for testing
			tempDir := t.TempDir()

			kubeletConfig := &kubeletconfiginternal.KubeletConfiguration{}
			kubeletFlags := &options.KubeletFlags{}

			if test.kubeletConfig != nil {
				// Create the Kubeletconfig
				kubeletConfFile := filepath.Join(tempDir, "kubelet.conf")
				yamlData, err := yaml.Marshal(test.kubeletConfig) // Convert struct to YAML