func TestPredicatesRegistered(t *testing.T) {
	var functionNames []string

	// Files and directories which predicates may be referenced
	targetFiles := []string{
		"./../../algorithmprovider/defaults/defaults.go", // Default algorithm
		"./../../factory/plugins.go",                     // Registered in init()
		"./../../../../../pkg/",                          // kubernetes/pkg, often used by kubelet or controller
	}

	// List all golang source files under ./predicates/, excluding test files and sub-directories.
	files, err := codeinspector.GetSourceCodeFiles(".")

	if err != nil {
		t.Errorf("unexpected error: %v when listing files in current directory", err)
	}

	// Get all public predicates in files.
	for _, filePath := range files {
		functions, err := codeinspector.GetPublicFunctions(filePath)
		if err == nil {
			functionNames = append(functionNames, functions...)
		} else {
			t.Errorf("unexpected error when parsing %s", filePath)
		}
	}

	// Check if all public predicates are referenced in target files.
	for _, functionName := range functionNames {
		args := []string{"-rl", functionName}
		args = append(args, targetFiles...)

		err := exec.Command("grep", args...).Run()
		if err != nil {
			switch err.Error() {
			case "exit status 2":
				t.Errorf("unexpected error when checking %s", functionName)
			case "exit status 1":
				t.Errorf("predicate %s is implemented as public but seems not registered or used in any other place",
					functionName)
			}
		}
	}
}
func TestPrioritiesRegistered(t *testing.T) {
	var functions []*types.Type

	// Files and directories which priorities may be referenced
	targetFiles := []string{
		"./../../algorithmprovider/defaults/defaults.go", // Default algorithm
		"./../../factory/plugins.go",                     // Registered in init()
	}

	// List all golang source files under ./priorities/, excluding test files and sub-directories.
	files, err := codeinspector.GetSourceCodeFiles(".")

	if err != nil {
		t.Errorf("unexpected error: %v when listing files in current directory", err)
	}

	// Get all public priorities in files.
	for _, filePath := range files {
		fileFunctions, err := codeinspector.GetPublicFunctions("k8s.io/kubernetes/plugin/pkg/scheduler/algorithm/priorities", filePath)
		if err == nil {
			functions = append(functions, fileFunctions...)
		} else {
			t.Errorf("unexpected error when parsing %s", filePath)
		}
	}

	prioritySignatures, err := getPrioritySignatures()
	if err != nil {
		t.Fatalf("Couldn't get priorities signatures")
	}

	// Check if all public priorities are referenced in target files.
	for _, function := range functions {
		// Ignore functions that don't match priorities signatures.
		signature := function.Underlying.Signature
		match := false
		for _, prioritySignature := range prioritySignatures {
			if len(prioritySignature.Parameters) != len(signature.Parameters) {
				continue
			}
			if len(prioritySignature.Results) != len(signature.Results) {
				continue
			}
			// TODO: Check exact types of parameters and results.
			match = true
		}
		if !match {
			continue
		}

		args := []string{"-rl", function.Name.Name}
		args = append(args, targetFiles...)

		err := exec.Command("grep", args...).Run()
		if err != nil {
			switch err.Error() {
			case "exit status 2":
				t.Errorf("unexpected error when checking %s", function.Name)
			case "exit status 1":
				t.Errorf("priority %s is implemented as public but seems not registered or used in any other place",
					function.Name)
			}
		}
	}
}