func TestDirectorySymbolicLink(t *testing.T) { var tests []dirLinkTest output, _ := osexec.Command("cmd", "/c", "mklink", "/?").Output() mklinkSupportsDirectorySymbolicLinks := strings.Contains(string(output), " /D ") if mklinkSupportsDirectorySymbolicLinks { tests = append(tests, dirLinkTest{ name: "use_mklink_cmd", mklink: func(link, target string) error { output, err := osexec.Command("cmd", "/c", "mklink", "/D", link, target).CombinedOutput() if err != nil { t.Errorf("failed to run mklink %v %v: %v %q", link, target, err, output) } return nil }, }, ) } else { t.Log(`skipping "use_mklink_cmd" test, mklink does not supports directory symbolic links`) } // The rest of these test requires SeCreateSymbolicLinkPrivilege to be held. runtime.LockOSThread() defer runtime.UnlockOSThread() err := windows.ImpersonateSelf(windows.SecurityImpersonation) if err != nil { t.Fatal(err) } defer windows.RevertToSelf() err = enableCurrentThreadPrivilege("SeCreateSymbolicLinkPrivilege") if err != nil { t.Skipf(`skipping some tests, could not enable "SeCreateSymbolicLinkPrivilege": %v`, err) } tests = append(tests, dirLinkTest{ name: "use_os_pkg", mklink: func(link, target string) error { return os.Symlink(target, link) }, }, dirLinkTest{ // Create link similar to what mklink does, by inserting \??\ at the front of absolute target. name: "standard", mklink: func(link, target string) error { var t reparseData t.addPrintName(target) t.addSubstituteName(`\??\` + target) return createSymbolicLink(link, &t, false) }, }, dirLinkTest{ name: "relative", mklink: func(link, target string) error { var t reparseData t.addSubstituteNameNoNUL(filepath.Base(target)) t.addPrintNameNoNUL(filepath.Base(target)) return createSymbolicLink(link, &t, true) }, }, ) testDirLinks(t, tests) }