package adapter import ( "context" "testing" "github.com/sagernet/sing-box/log" "github.com/stretchr/testify/require" mDNS "github.com/miekg/dns" ) type testDNSTransport struct { transportType string tag string } func (t *testDNSTransport) Start(stage StartStage) error { return nil } func (t *testDNSTransport) Close() error { return nil } func (t *testDNSTransport) Type() string { return t.transportType } func (t *testDNSTransport) Tag() string { return t.tag } func (t *testDNSTransport) Dependencies() []string { return nil } func (t *testDNSTransport) Reset() { } func (t *testDNSTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) { return nil, nil } type testDNSTransportManager struct { transports []DNSTransport transportByTag map[string]DNSTransport fakeIPTransport FakeIPTransport } func newTestDNSTransportManager(transports ...DNSTransport) *testDNSTransportManager { manager := &testDNSTransportManager{ transports: transports, transportByTag: make(map[string]DNSTransport), } for _, transport := range transports { manager.transportByTag[transport.Tag()] = transport } return manager } func (m *testDNSTransportManager) Start(stage StartStage) error { return nil } func (m *testDNSTransportManager) Close() error { return nil } func (m *testDNSTransportManager) Transports() []DNSTransport { return m.transports } func (m *testDNSTransportManager) Transport(tag string) (DNSTransport, bool) { transport, loaded := m.transportByTag[tag] return transport, loaded } func (m *testDNSTransportManager) Default() DNSTransport { return nil } func (m *testDNSTransportManager) FakeIP() FakeIPTransport { return m.fakeIPTransport } func (m *testDNSTransportManager) Remove(tag string) error { return nil } func (m *testDNSTransportManager) Create(ctx context.Context, logger log.ContextLogger, tag string, outboundType string, options any) error { return nil } func TestLookupDNSTransportLocalAlias(t *testing.T) { t.Parallel() localTransport := &testDNSTransport{ transportType: "local", tag: "dns-local", } manager := newTestDNSTransportManager(localTransport) transport, loaded, ambiguous := LookupDNSTransport(manager, "local") require.True(t, loaded) require.False(t, ambiguous) require.Same(t, localTransport, transport) } func TestLookupDNSTransportExactTagPreferred(t *testing.T) { t.Parallel() localTransport := &testDNSTransport{ transportType: "local", tag: "local", } manager := newTestDNSTransportManager(localTransport) transport, loaded, ambiguous := LookupDNSTransport(manager, "local") require.True(t, loaded) require.False(t, ambiguous) require.Same(t, localTransport, transport) } func TestLookupDNSTransportLocalAliasAmbiguous(t *testing.T) { t.Parallel() manager := newTestDNSTransportManager( &testDNSTransport{transportType: "local", tag: "dns-local-a"}, &testDNSTransport{transportType: "local", tag: "dns-local-b"}, ) transport, loaded, ambiguous := LookupDNSTransport(manager, "local") require.Nil(t, transport) require.False(t, loaded) require.True(t, ambiguous) }