package tor import ( "fmt" "git.openprivacy.ca/openprivacy/log" "os" path "path/filepath" "runtime" "runtime/pprof" "testing" "time" ) func getStatusCallback(progChan chan int) func(int, string) { return func(prog int, status string) { fmt.Printf("%v %v\n", prog, status) progChan <- prog } } func getVersionCallback(verChan chan string) func(string) { return func(version string) { fmt.Printf("version: %v\n", version) verChan <- version } } func TestTorProvider(t *testing.T) { goRoutineStart := runtime.NumGoroutine() progChan := make(chan int, 10) verChan := make(chan string, 10) log.SetLevel(log.LevelDebug) torpath := path.Join("..", "tmp/tor") NewTorrc().WithControlPort(9051).WithHashedPassword("examplehashedpassword").Build(path.Join("..", "testing", "tor", "torrc")) log.Debugf("setting tor path %v", torpath) dataDir := "" var err error if dataDir, err = os.MkdirTemp(path.Join("..", "testing"), "data-dir-"); err != nil { t.Fatalf("could not create data dir") } acn, err := NewTorACNWithAuth(path.Join("../testing/"), torpath, dataDir, 9051, HashedPasswordAuthenticator{"examplehashedpassword"}) if err != nil { t.Error(err) return } acn.SetStatusCallback(getStatusCallback(progChan)) acn.SetVersionCallback(getVersionCallback(verChan)) progress := 0 for progress < 100 { progress = <-progChan t.Logf("progress: %v", progress) } acn.Restart() progress = 0 for progress < 100 { progress = <-progChan t.Logf("progress: %v", progress) } log.Debugf("Pulling tor version from version callback chan...\n") version := <-verChan if version == "" { t.Errorf("failed to get tor version, got empty string\n") } else { log.Debugf("Tor version: %v\n", version) } // Test opening the OP Server _, _, err = acn.Open("isbr2t6bflul2zyi6hjtnuezb2xvfr42svzjg2q3gyqfgg3wmnrbkkqd") if err == nil { info, err := acn.GetInfo("isbr2t6bflul2zyi6hjtnuezb2xvfr42svzjg2q3gyqfgg3wmnrbkkqd") if err != nil { t.Fatalf("could not find info for OP server %v", err) } cinfo, exists := info["circuit"] if !exists || len(cinfo) == 0 { t.Fatalf("could not find circuit info for OP server %v", err) } _, err = acn.GetInfo("not_a_real_onion") if err == nil { t.Fatalf("GetInfo for non existent onion should have errored") } } else { t.Fatalf("could not connect to OP server %v", err) } // Should skip without blocking... acn.Restart() acn.Restart() acn.Restart() acn.Close() time.Sleep(time.Second * 10) goRoutineEnd := runtime.NumGoroutine() if goRoutineEnd != goRoutineStart { pprof.Lookup("goroutine").WriteTo(os.Stdout, 1) t.Fatalf("goroutine leak in ACN: %v %v", goRoutineStart, goRoutineEnd) } }