feat: fix proxy compatibility and establish TUI foundation
This commit is contained in:
@@ -37,7 +37,7 @@ func TestAvailabilityRequiresDebianMarkerAPTToolAndConfigurationDirectory(t *tes
|
||||
mustWrite(t, filepath.Join(root, "etc", "debian_version"), "12\n")
|
||||
}
|
||||
runner := &fakeRunner{available: tc.tool, outputError: !tc.dumpWorks}
|
||||
a := apt.New(apt.Configuration{DebianVersionFile: filepath.Join(root, "etc", "debian_version"), ConfigDirectory: configDir, OverlayFile: filepath.Join(configDir, "99proxyctl"), TrustedRoot: root}, nil, runner)
|
||||
a := apt.New(apt.Configuration{DebianVersionFile: filepath.Join(root, "etc", "debian_version"), ConfigDirectory: configDir, TrustedRoot: root}, nil, runner)
|
||||
got := a.Availability(context.Background())
|
||||
if got.Available != tc.want || got.Evidence == "" {
|
||||
t.Fatalf("availability = %#v", got)
|
||||
@@ -225,6 +225,59 @@ func TestOverlayNameCollisionNeverRewritesOrRemovesUnownedConfiguration(t *testi
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaultOverlayNameSortsAfterCommonAPTFragments(t *testing.T) {
|
||||
name := filepath.Base(apt.New(apt.Configuration{}, nil, nil).OverlayPath())
|
||||
if filepath.Ext(name) != ".conf" {
|
||||
t.Fatalf("default overlay name %q has no .conf extension; stricter APT versions ignore extensionless fragments", name)
|
||||
}
|
||||
for _, fragment := range []string{"proxy.conf", "99update-notifier", "01-vendor-ubuntu"} {
|
||||
if strings.Compare(name, fragment) <= 0 {
|
||||
t.Fatalf("default overlay name %q does not sort after common fragment %q; a later fragment shadows the overlay and enable can never become effective", name, fragment)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestOwnedLegacyOverlayIsRemovedOnEnableAndDisable(t *testing.T) {
|
||||
legacyContents := "// Generated by proxyctl. Do not edit.\nAcquire::http::Proxy \"http://stale.example:3128\";\n"
|
||||
|
||||
t.Run("enable", func(t *testing.T) {
|
||||
a, _ := newAdapter(t, nil)
|
||||
legacy := filepath.Join(filepath.Dir(a.OverlayPath()), "99proxyctl")
|
||||
mustWrite(t, legacy, legacyContents)
|
||||
if got := a.SetDesired(context.Background(), true, compatibleProfile()); got.Err != nil || got.Inspection.State != target.Enabled {
|
||||
t.Fatalf("enable = %#v", got)
|
||||
}
|
||||
if _, err := os.Stat(legacy); !errors.Is(err, os.ErrNotExist) {
|
||||
t.Fatalf("owned legacy overlay remains after enable: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("disable", func(t *testing.T) {
|
||||
a, _ := newAdapter(t, nil)
|
||||
legacy := filepath.Join(filepath.Dir(a.OverlayPath()), "99proxyctl")
|
||||
mustWrite(t, legacy, legacyContents)
|
||||
if got := a.SetDesired(context.Background(), false, nil); got.Err != nil {
|
||||
t.Fatalf("disable = %#v", got)
|
||||
}
|
||||
if _, err := os.Stat(legacy); !errors.Is(err, os.ErrNotExist) {
|
||||
t.Fatalf("owned legacy overlay remains after disable: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("unowned legacy is untouched", func(t *testing.T) {
|
||||
a, _ := newAdapter(t, nil)
|
||||
legacy := filepath.Join(filepath.Dir(a.OverlayPath()), "99proxyctl")
|
||||
original := "Acquire::http::Proxy \"http://user-owned.example:3128\";\n"
|
||||
mustWrite(t, legacy, original)
|
||||
if got := a.SetDesired(context.Background(), true, compatibleProfile()); got.Err != nil || got.Inspection.State != target.Enabled {
|
||||
t.Fatalf("enable = %#v", got)
|
||||
}
|
||||
if got := readFile(t, legacy); got != original {
|
||||
t.Fatalf("unowned legacy overlay changed: %q", got)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestDisablePermissionFailureReportsActualManagedState(t *testing.T) {
|
||||
files := &failingFS{}
|
||||
a, _ := newFailingAdapter(t, files)
|
||||
@@ -268,7 +321,7 @@ func TestIncompatibleProtocolOrBypassPreventsMutationAndNamesValue(t *testing.T)
|
||||
value string
|
||||
}{
|
||||
{"socks5 local DNS", func(p *profile.Profile) { p.HTTPURL = "socks5://unsupported.example:1080" }, "socks5://unsupported.example:1080"},
|
||||
{"incompatible overridden ALL", func(p *profile.Profile) { p.AllURL = "socks5://all.example:1080" }, "socks5://all.example:1080"},
|
||||
{"incompatible ALL fallback", func(p *profile.Profile) { p.HTTPURL = ""; p.AllURL = "socks5://all.example:1080" }, "socks5://all.example:1080"},
|
||||
{"domain suffix", func(p *profile.Profile) { p.Bypass = []string{".example.com"} }, ".example.com"},
|
||||
{"CIDR", func(p *profile.Profile) { p.Bypass = []string{"10.0.0.0/8"} }, "10.0.0.0/8"},
|
||||
{"IPv6", func(p *profile.Profile) { p.Bypass = []string{"2001:db8::1"} }, "2001:db8::1"},
|
||||
@@ -323,6 +376,22 @@ func TestManagedOverlayIsAtomicOwnerOnlyAndRejectsSymlinkVictims(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestCompleteHTTPProfileIgnoresAdditionalSOCKSProxy(t *testing.T) {
|
||||
a, _ := newAdapter(t, nil)
|
||||
p := &profile.Profile{
|
||||
Name: "dual", Mode: profile.AdvancedMode,
|
||||
HTTPURL: "http://localhost:7890", HTTPSURL: "http://localhost:7890", AllURL: "socks5://localhost:7890",
|
||||
}
|
||||
got := a.SetDesired(context.Background(), true, p)
|
||||
if got.Err != nil || got.Inspection.State != target.Enabled {
|
||||
t.Fatalf("enable = %#v", got)
|
||||
}
|
||||
contents := readFile(t, a.OverlayPath())
|
||||
if strings.Count(contents, `"http://localhost:7890"`) != 2 || strings.Contains(contents, "socks5") {
|
||||
t.Fatalf("dual-protocol translation:\n%s", contents)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAdvancedALLValueSuppliesMissingAPTProtocols(t *testing.T) {
|
||||
a, _ := newAdapter(t, nil)
|
||||
p := &profile.Profile{Name: "all", Mode: profile.AdvancedMode, AllURL: "socks5h://proxy.example:1080"}
|
||||
@@ -361,7 +430,7 @@ func newAdapter(t *testing.T, files apt.FileSystem) (*apt.Adapter, *fakeRunner)
|
||||
if failure, ok := files.(*failingFS); ok {
|
||||
failure.delegate = apt.NewOSFileSystem(root)
|
||||
}
|
||||
a := apt.New(apt.Configuration{DebianVersionFile: filepath.Join(root, "etc", "debian_version"), ConfigDirectory: dir, OverlayFile: filepath.Join(dir, "99proxyctl"), TrustedRoot: root}, files, runner)
|
||||
a := apt.New(apt.Configuration{DebianVersionFile: filepath.Join(root, "etc", "debian_version"), ConfigDirectory: dir, TrustedRoot: root}, files, runner)
|
||||
runner.overlay = a.OverlayPath()
|
||||
return a, runner
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user