//go:build (linux && !android) || freebsd package dns import ( "context" "os" "path/filepath" "testing" "time" "github.com/netbirdio/netbird/client/internal/statemanager" "github.com/netbirdio/netbird/util" ) func TestMain(m *testing.M) { _ = util.InitLog("debug", "console") code := m.Run() os.Exit(code) } func Test_newRepairtmp(t *testing.T) { type args struct { resolvConfContent string touchedConfContent string wantChange bool } tests := []args{ { resolvConfContent: ` nameserver 10.0.0.1 nameserver 8.8.8.8 searchdomain netbird.cloud something`, touchedConfContent: ` nameserver 8.8.8.8 searchdomain netbird.cloud something`, wantChange: true, }, { resolvConfContent: ` nameserver 10.0.0.1 nameserver 8.8.8.8 searchdomain netbird.cloud something`, touchedConfContent: ` nameserver 10.0.0.1 nameserver 8.8.8.8 searchdomain netbird.cloud something somethingelse`, wantChange: false, }, { resolvConfContent: ` nameserver 10.0.0.1 nameserver 8.8.8.8 searchdomain netbird.cloud something`, touchedConfContent: ` nameserver 10.0.0.1 searchdomain netbird.cloud something`, wantChange: false, }, { resolvConfContent: ` nameserver 10.0.0.1 nameserver 8.8.8.8 searchdomain netbird.cloud something`, touchedConfContent: ` searchdomain something`, wantChange: true, }, { resolvConfContent: ` nameserver 10.0.0.1 nameserver 8.8.8.8 searchdomain netbird.cloud something`, touchedConfContent: ` nameserver 10.0.0.1`, wantChange: true, }, { resolvConfContent: ` nameserver 10.0.0.1 nameserver 8.8.8.8 searchdomain netbird.cloud something`, touchedConfContent: ` nameserver 8.8.8.8`, wantChange: true, }, } for _, tt := range tests { tt := tt t.Run("test", func(t *testing.T) { t.Parallel() workDir := t.TempDir() operationFile := workDir + "/resolv.conf" err := os.WriteFile(operationFile, []byte(tt.resolvConfContent), 0755) if err != nil { t.Fatalf("failed to write out resolv.conf: %s", err) } var changed bool ctx, cancel := context.WithTimeout(context.Background(), time.Second) updateFn := func([]string, string, *resolvConf, *statemanager.Manager) error { changed = true cancel() return nil } r := newRepair(operationFile, updateFn) r.watchFileChanges([]string{"netbird.cloud"}, "10.0.0.1", nil) err = os.WriteFile(operationFile, []byte(tt.touchedConfContent), 0755) if err != nil { t.Fatalf("failed to write out resolv.conf: %s", err) } <-ctx.Done() r.stopWatchFileChanges() if changed != tt.wantChange { t.Errorf("unexpected result: want: %v, got: %v", tt.wantChange, changed) } }) } } func Test_newRepairSymlink(t *testing.T) { resolvConfContent := ` nameserver 10.0.0.1 nameserver 8.8.8.8 searchdomain netbird.cloud something` modifyContent := `nameserver 8.8.8.8` tmpResolvConf := filepath.Join(t.TempDir(), "resolv.conf") err := os.WriteFile(tmpResolvConf, []byte(resolvConfContent), 0644) if err != nil { t.Fatal(err) } tmpLink := filepath.Join(t.TempDir(), "symlink") err = os.Symlink(tmpResolvConf, tmpLink) if err != nil { t.Fatal(err) } var changed bool ctx, cancel := context.WithTimeout(context.Background(), time.Second) updateFn := func([]string, string, *resolvConf, *statemanager.Manager) error { changed = true cancel() return nil } r := newRepair(tmpLink, updateFn) r.watchFileChanges([]string{"netbird.cloud"}, "10.0.0.1", nil) err = os.WriteFile(tmpLink, []byte(modifyContent), 0755) if err != nil { t.Fatalf("failed to write out resolv.conf: %s", err) } <-ctx.Done() r.stopWatchFileChanges() if changed != true { t.Errorf("unexpected result: want: %v, got: %v", true, false) } }