I am trying to run and test this code but the selenium is missing and i cant install it in my system, what should i do in that case please?
ERROR: while execute
test.go:8:2: import "bitbucket.org/tebeka/selenium": cannot find package
INSTALL the package i tried:
# apt-get install goisntall
Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package goisntall
# apt-cache search goinstall
golang-src - Go programming language compiler - source files
CODE: testing
/* Selenium example goinstall bitbucket.org/tebeka/selenium */
package yahoo
import (
"strings"
"testing"
"bitbucket.org/tebeka/selenium"
)
func TestYahoo(t *testing.T) {
/* We want firefox, don't care about version much */
caps := selenium.Capabilities {
"browserName": "firefox",
}
wd, _ := selenium.NewRemote(caps, "", "")
defer wd.Quit()
/* Navigate to Yahoo */
wd.Get("http://www.yahoo.com")
/* Fill the search box */
input, err := wd.FindElement(selenium.ByName, "p")
if err != nil {
t.Error(err.String())
}
err = input.SendKeys("golang")
if err != nil {
t.Error(err.String())
}
/* Hit the search button */
button, err := wd.FindElement(selenium.ById, "search-submit")
if err != nil {
t.Error(err.String())
}
err = button.Click()
if err != nil {
t.Error(err.String())
}
/* See that we get expected result */
source, err := wd.PageSource()
if err != nil {
t.Error(err.String())
}
if !strings.Contains(source, "The Go Programming Language") {
t.Error("Google can't find Go")
}
}
For example, with GOPATH set appropriately,
$ env | grep '^GOPATH'
GOPATH=/home/peter/gopath
$ go get -v bitbucket.org/tebeka/selenium
bitbucket.org/tebeka/selenium (download)
bitbucket.org/tebeka/selenium
$
References:
Command go
Download and install packages and dependencies
Related
I am a beginner and am currently playing with the pubsub example from libp2p given here https://github.com/libp2p/go-libp2p/tree/master/examples/pubsub/basic-chat-with-rendezvous
I have been able to build the code and run the binary in different terminals and it works.
I am trying to automate this process from the main.go program itself where I can create a few threads to spin up new agents where they
publish messages to the network and the rest of the peers subscribe to it.
I have provided the modified code I have built currently but it doesnt seem to work. The peers cannot discover each other.
func main() {
help := flag.Bool("help", false, "Display Help")
cfg := parseFlags()
if *help {
fmt.Printf("Simple example for peer discovery using mDNS. mDNS is great when you have multiple peers in local LAN.")
fmt.Printf("Usage: \n Run './chat-with-mdns'\nor Run './chat-with-mdns -host [host] -port [port] -rendezvous [string] -pid [proto ID]'\n")
os.Exit(0)
}
fmt.Printf("[*] Listening on: %s with port: %d\n", cfg.listenHost, cfg.listenPort)
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
// Spawn a thread for each iteration in the loop.
// Pass 'i' into the goroutine's function
// in order to make sure each goroutine
// uses a different value for 'i'.
wg.Add(5)
go func(i int) {
// At the end of the goroutine, tell the WaitGroup
// that another thread has completed.
defer wg.Done()
ctx := context.Background()
r := rand.Reader
// Creates a new RSA key pair for this host.
prvKey, _, err := crypto.GenerateKeyPairWithReader(crypto.RSA, 2048, r)
if err != nil {
panic(err)
}
// 0.0.0.0 will listen on any interface device.
sourceMultiAddr, _ := multiaddr.NewMultiaddr(fmt.Sprintf("/ip4/%s/tcp/%d", cfg.listenHost, cfg.listenPort))
// libp2p.New constructs a new libp2p Host.
// Other options can be added here.
host, err := libp2p.New(
libp2p.ListenAddrs(sourceMultiAddr),
libp2p.Identity(prvKey),
)
if err != nil {
panic(err)
}
// Set a function as stream handler.
// This function is called when a peer initiates a connection and starts a stream with this peer.
host.SetStreamHandler(protocol.ID(cfg.ProtocolID), handleStream)
fmt.Printf("\n[*] Your Multiaddress Is: /ip4/%s/tcp/%v/p2p/%s\n", cfg.listenHost, cfg.listenPort, host.ID().Pretty())
peerChan := initMDNS(host, cfg.RendezvousString)
for { // allows multiple peers to join
peer := <-peerChan // will block untill we discover a peer // the code currently hangs here
fmt.Println("Found peer:", peer, ", connecting")
if err := host.Connect(ctx, peer); err != nil {
fmt.Println("Connection failed:", err)
continue
}
//** this part of the code is experimental and is not accessed by any thread yet **//
stream, err := host.NewStream(ctx, peer.ID, protocol.ID(cfg.ProtocolID))
if err != nil {
fmt.Println("Stream open failed", err)
} else {
rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream))
go writeData(rw)
go readData(rw)
fmt.Println("Connected to:", peer)
}
//** this part of the code is experimental and is not accessed by any thread yet **//
}
}(i)
}
fmt.Println("exit")
wg.Wait()
fmt.Println("Finished for loop")
}
But this doesn't seem to work. Are there any examples I can look at currently for solving this error.
I have this function that logs the error in some cases:
func readByte(/*...*/){
// ...
if err != nil {
fmt.Println("ERROR")
log.Print("Couldn't read first byte")
return
}
// ...
}
Now, in the test file, I want to check the output error from this function:
c.Assert(OUTPUT, check.Matches, "teste")
How can I access the log? I tried to put a buffer but it didn't work. What is the right way to catch this log without change my readByte function code?
For example,
readbyte_test.go:
package main
import (
"bytes"
"fmt"
"io"
"log"
"os"
"testing"
)
func readByte( /*...*/ ) {
// ...
err := io.EOF // force an error
if err != nil {
fmt.Println("ERROR")
log.Print("Couldn't read first byte")
return
}
// ...
}
func TestReadByte(t *testing.T) {
var buf bytes.Buffer
log.SetOutput(&buf)
defer func() {
log.SetOutput(os.Stderr)
}()
readByte()
t.Log(buf.String())
}
Output:
$ go test -v readbyte_test.go
=== RUN TestReadByte
ERROR
--- PASS: TestReadByte (0.00s)
readbyte_test.go:30: 2017/05/22 16:41:00 Couldn't read first byte
PASS
ok command-line-arguments 0.004s
$
Answer for Concurrent Tests
If your test is running concurrently (for example, when testing an http Server or Client), you may encounter a race between writing to the buffer and reading from it. Instead of the buffer, we can redirect output to an os.Pipe and use a bufio.Scanner to block until output has been written by using the Scan() method.
Here is an example of creating an os.Pipe and setting the stdlib log package to use the pipe. Note my use of the testify/assert package here:
func mockLogger(t *testing.T) (*bufio.Scanner, *os.File, *os.File) {
reader, writer, err := os.Pipe()
if err != nil {
assert.Fail(t, "couldn't get os Pipe: %v", err)
}
log.SetOutput(writer)
return bufio.NewScanner(reader), reader, writer
}
The *os.File objects are returned so they can be properly closed with a deferred function. Here I'm just printing to stdout since if there was some strange error on close I personally wouldn't want to fail the test. However, this could easily be another call to t.Errorf or similar if you wanted:
func resetLogger(reader *os.File, writer *os.File) {
err := reader.Close()
if err != nil {
fmt.Println("error closing reader was ", err)
}
if err = writer.Close(); err != nil {
fmt.Println("error closing writer was ", err)
}
log.SetOutput(os.Stderr)
}
And then in your test you would have this pattern:
scanner, reader, writer := mockLogger(t) // turn this off when debugging or developing as you will miss output!
defer resetLogger(reader, writer)
// other setup as needed, getting some value for thing below
go concurrentAction()
scanner.Scan() // blocks until a new line is written to the pipe
got := scanner.Text() // the last line written to the scanner
msg := fmt.Sprintf("your log message with thing %v you care about", thing)
assert.Contains(t, got, msg)
And finally, the concurrentAction() function is calling a log function (or method if using a log.logger, the package actually behaves the same way with log.SetOutput() call above either way) like:
// doing something, getting value for thing
log.Printf("your log message with the thing %v you care about", thing)
I need to create pdf file in go with cyrillic symbols. I've started with https://github.com/jung-kurt/gofpdf but it needs 1251 symbols to produce correct cyrillic.
I've tried
package main
import (
"github.com/jung-kurt/gofpdf"
"fmt"
"os"
)
func main() {
pwd, err := os.Getwd()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
pdf := gofpdf.New("P", "mm", "A4", "")
pdf.AddFont("Helvetica", "", pwd + "/font/helvetica_1251.json")
pdf.AddPage()
pdf.SetFont("Helvetica", "", 16)
tr := pdf.UnicodeTranslatorFromDescriptor("cp1251")
pdf.Cell(15, 50, tr("русский текст"))
pdf.OutputFileAndClose("test.pdf")
}
but it produce only dots instead of text.
Then I've tried to use https://github.com/golang/freetype to create image with text and then insert it to pdf. So I've tried
package main
import (
"github.com/jung-kurt/gofpdf"
"github.com/golang/freetype"
"image"
"fmt"
"os"
"bytes"
"image/jpeg"
"io/ioutil"
"image/draw"
)
func main() {
pwd, err := os.Getwd()
if err != nil {
fmt.Println(err)
os.Exit(1)
}
dataFont, err := ioutil.ReadFile(pwd + "/font/luxisr.ttf")
if err != nil {
fmt.Printf("%v",err)
}
f, err := freetype.ParseFont(dataFont)
if err != nil {
fmt.Printf("%v",err)
}
dst := image.NewRGBA(image.Rect(0, 0, 800, 600))
draw.Draw(dst, dst.Bounds(), image.White, image.ZP, draw.Src)
c := freetype.NewContext()
c.SetDst(dst)
c.SetClip(dst.Bounds())
c.SetSrc(image.Black)
c.SetFont(f)
c.DrawString("русский текст", freetype.Pt(0, 16))
pdf := gofpdf.New("P", "mm", "A4", "")
pdf.AddPage()
buf := new(bytes.Buffer)
err = jpeg.Encode(buf, dst, nil)
if err != nil {
fmt.Printf("%v",err)
}
reader := bytes.NewReader(buf.Bytes())
textName := "text1"
pdf.RegisterImageReader(textName, "jpg", reader)
pdf.Image(textName, 15, 15, 0, 0, false, "jpg", 0, "")
pdf.OutputFileAndClose("test.pdf")
}
but as a result I receive squares instead of text because it seems that freetype needs unicode symbols for text.
Is it possible to convert strings which are generally in utf-8 to unicode? How can I create pdf or image with cyrillic text?
Thank you.
First, you are ignoring an error in the final line. pdf.OutputFileAndClose returns an error, so you should check it:
err := pdf.OutputFileAndClose("test.pdf")
if err != nil {
log.Fatal(err)
}
Other than that, your first example works for me. The generated output looks like this:
Here is the code I used, you'll see it's very similar to yours:
package main
import (
"log"
"github.com/jung-kurt/gofpdf"
)
func main() {
pdf := gofpdf.New("P", "mm", "A4", "")
pdf.AddFont("Helvetica", "", "helvetica_1251.json")
pdf.AddPage()
pdf.SetFont("Helvetica", "", 16)
tr := pdf.UnicodeTranslatorFromDescriptor("cp1251")
pdf.Cell(15, 50, tr("русский текст"))
err := pdf.OutputFileAndClose("test.pdf")
if err != nil {
log.Println(err)
}
}
With the above code, the important thing is to make sure helvetica_1251.z, helvetica_1251.json and cp1251.map (from $GOPATH/src/github.com/jung-kurt/gofpdf/font, or generated by the makefont tool) are all in the current directory. If you can confirm that this works for you, you can proceed to move them into the fonts directory and changing the code accordingly. My best guess is that you may be silently ignoring an error warning you about one of these files.
PS I'm running Mac OS X. If you are on another system, make sure you have a version of Helvetica with cyrillic character support installed.
Update
For others facing this problem in the future, I wanted to add the final solution here. From the comments below:
Thanks to jung-kurt I found solution. You can avoid this bug on Windows by adding pdf.SetCompression(true) – Timur Shahmuratov
Disclaimer: I wish you a merry XMas and I hope my question does not disturb you!
sample.go:
package main
import(
"fmt"
"os"
)
type sample struct {
value int64
}
func (s sample) useful() {
if s.value == 0 {
fmt.Println("Error: something is wrong!")
os.Exit(1)
} else {
fmt.Println("May the force be with you!")
}
}
func main() {
s := sample{42}
s.useful()
s.value = 0
s.useful()
}
// output:
// May the force be with you!
// Error: something is wrong!
// exit status 1
I did a lot of research on how to use interfaces in golang testing. But so far I was not able to wrap my head around this completely. At least I can not see how interfaces help me when I need to "mock" (apologies for using this word) golang std. library packages like "fmt".
I came up with two scenarios:
use os/exec to test the command line interface
wrap fmt package so I have control and am able to check the output strings
I do not like both scenarios:
I experience going through the actual command line a convoluted and not-performant (see below). Might have portability issues, too.
I believe this is the way to go but I fear that wrapping the fmt package might be a lot of work (at least wrapping the time package for testing turned out a non-trivial task (https://github.com/finklabs/ttime)).
Actual Question here: Is there another (better/simpler/idiomatic) way?
Note: I want to do this in pure golang, I am not interested in the next testing framework.
cli_test.go:
package main
import(
"os/exec"
"testing"
)
func TestCli(t *testing.T) {
out, err := exec.Command("go run sample.go").Output()
if err != nil {
t.Fatal(err)
}
if string(out) != "May the force be with you!\nError: this is broken and not useful!\nexit status 1" {
t.Fatal("There is something wrong with the CLI")
}
}
Chapter 11 of Kerningham's Book gives a good solution to this question.
The trick is to change the calls to fmt.Printline() to calls to
fmt.Fprint(out, ...) where out is initialised to os.Stdout
This can be overwritten in the test harness to new(bytes.Buffer) allowing the
test to capture the output.
See https://github.com/adonovan/gopl.io/blob/master/ch11/echo/echo.go and
https://github.com/adonovan/gopl.io/blob/master/ch11/echo/echo_test.go
edited by OP...
sample.go:
package main
import(
"fmt"
"os"
"io"
)
var out io.Writer = os.Stdout // modified during testing
var exit func(code int) = os.Exit
type sample struct {
value int64
}
func (s sample) useful() {
if s.value == 0 {
fmt.Fprint(out, "Error: something is wrong!\n")
exit(1)
} else {
fmt.Fprint(out, "May the force be with you!\n")
}
}
func main() {
s := sample{42}
s.useful()
s.value = 0
s.useful()
}
// output:
// May the force be with you!
// Error: this is broken and not useful!
// exit status 1
cli_test.go:
package main
import(
"bytes"
"testing"
)
func TestUsefulPositive(t *testing.T) {
bak := out
out = new(bytes.Buffer)
defer func() { out = bak }()
s := sample{42}
s.useful()
if out.(*bytes.Buffer).String() != "May the force be with you!\n" {
t.Fatal("There is something wrong with the CLI")
}
}
func TestUsefulNegative(t *testing.T) {
bak := out
out = new(bytes.Buffer)
defer func() { out = bak }()
code := 0
osexit := exit
exit = func(c int) { code = c }
defer func() { exit = osexit }()
s := sample{0}
s.useful()
if out.(*bytes.Buffer).String() != "Error: something is wrong!\n" {
t.Fatal("There is something wrong with the CLI")
}
if code != 1 {
t.Fatal("Wrong exit code!")
}
}
Am I missing something here or are you talking of testable examples?
Basically, it works like this: In a *_test.go file, you need to adhere to the convention Example[[T][_M]] where T is a placeholder for the type and M a placeholder for the method you want to display the testable example as example code in the Godoc. If the function is just called Example(), the code will be shown as a package example.
Below the last line of the code of your example, you can put a comment like this
// Output:
// Foo
Now go test will make sure that the testable example function either exactly puts out everything below // Output: (including whitespace) or it will make the test fail.
Here is an actual example for an testable example
func ExampleMongoStore_Get() {
sessionId := "ExampleGetSession"
data, err := ms.Get(sessionId)
if err == sessionmw.ErrSessionNotFound {
fmt.Printf("Session '%s' not found\n", sessionId)
data = make(map[string]interface{})
data["foo"] = "bar"
ms.Save(sessionId, data)
}
loaded, _ := ms.Get(sessionId)
fmt.Printf("Loaded value '%s' for key '%s' in session '%s'",
loaded["foo"],
"foo", sessionId)
// Output:
// Session 'ExampleGetSession' not found
// Loaded value 'bar' for key 'foo' in session 'ExampleGetSession'
}
Edit: Have a look at the output of above example at godoc.org
If I have the PID of a process, is os.FindProcess enough to test for the existing of the process? I mean if it returns err can I assume that it's terminated (or killed)?
Edit:
I've just wrote a wrapper function around kill -s 0 (old-style bash process testing). This works without any problem, but I'm still happy if there is other solutions (done with go libraries) to this problem.:
func checkPid(pid int) bool {
out, err := exec.Command("kill", "-s", "0", strconv.Itoa(pid)).CombinedOutput()
if err != nil {
log.Println(err)
}
if string(out) == "" {
return true // pid exist
}
return false
}
Here is the traditional unix way to see if a process is alive - send it a signal of 0 (like you did with your bash example).
From kill(2):
If sig is 0, then no signal is sent, but error checking is still per‐
formed; this can be used to check for the existence of a process ID or
process group ID.
And translated into Go
package main
import (
"fmt"
"log"
"os"
"strconv"
"syscall"
)
func main() {
for _, p := range os.Args[1:] {
pid, err := strconv.ParseInt(p, 10, 64)
if err != nil {
log.Fatal(err)
}
process, err := os.FindProcess(int(pid))
if err != nil {
fmt.Printf("Failed to find process: %s\n", err)
} else {
err := process.Signal(syscall.Signal(0))
fmt.Printf("process.Signal on pid %d returned: %v\n", pid, err)
}
}
}
When you run it you get this, showing that process 123 is dead, process 1 is alive but not owned by you and process 12606 is alive and owned by you.
$ ./kill 1 $$ 123
process.Signal on pid 1 returned: operation not permitted
process.Signal on pid 12606 returned: <nil>
process.Signal on pid 123 returned: no such process
On unix like systems (linux, freebsd, etc) os.FindProcess will never return an error. I don't know what happens on Windows. This means you won't know if the PID is correct until you try to use the *os.Process for something.
You can look at the code here.
You can also just use syscall.Kill. It amounts to less code.
killErr := syscall.Kill(pid, syscall.Signal(0))
procExists := killErr == nil
If a previously known pid is not found in the system (not sure of go functions), it means process has definitely terminated and has been joined (on Unix, with wait call) too.
But other way around is not necessarily true. Just because a pid exists, it does not quarantee it is same process as before. There are only 65535 valid pids in standard Linux for example, and they can get re-used when there is a wrap-around. However, if you check reasonably often, for practical purposes you don't need to care about this (as long as pid of wrong new process being found is not a security vulnerability or something else critical, which somebody might try to trigger intentionally for malicious purposes).
Related links (and Related questions on their right columns):
https://superuser.com/questions/135007/how-are-pids-generated
https://unix.stackexchange.com/questions/26677/will-process-ids-be-recycled-what-if-you-reach-the-maximal-id
All the answers so far are incomplete implementations. See https://github.com/shirou/gopsutil/blob/c141152a7b8f59b63e060fa8450f5cd5e7196dfb/process/process_posix.go#L73 for a more complete implementation (copied inline)
func PidExists(pid int32) (bool, error) {
if pid <= 0 {
return false, fmt.Errorf("invalid pid %v", pid)
}
proc, err := os.FindProcess(int(pid))
if err != nil {
return false, err
}
err = proc.Signal(syscall.Signal(0))
if err == nil {
return true, nil
}
if err.Error() == "os: process already finished" {
return false, nil
}
errno, ok := err.(syscall.Errno)
if !ok {
return false, err
}
switch errno {
case syscall.ESRCH:
return false, nil
case syscall.EPERM:
return true, nil
}
return false, err
}
Here is one way of how to check if a process exists/running with Golang on Windows.
We execute the command:
TASKLIST /V /NH /FI "PID eq 23232"
Which can return either:
INFO: No tasks are running which match the specified criteria.
Or if found:
Image Name PID Session Name Session# Mem Usage Status User Name CPU Time Window Title
========================= ======== ================ =========== ============ =============== ================================================== ============ ========================================================================
chrome.exe 23232 Console 1 42,472 K Unknown THANOS\MARVEL 0:00:00 N/A
Here is a function that takes advantage of this information.
func isProcessRunning(pid int) bool {
cmd := exec.Command("TASKLIST", "/FI", fmt.Sprintf("PID eq %d", pid))
result, err := cmd.Output()
if err != nil {
return false
}
return !bytes.Contains(result, []byte("No tasks are running"))
}
The best thing about this is you can find the process by other parameters too:
ImageName eq, ne Image Name String
PID eq, ne, gt, lt, ge, le Process ID, A Positive integer.
Session eq, ne, gt, lt, ge, le Any valid session number.
SessionName eq, ne String
Status eq, ne RUNNING | NOT RESPONDING | UNKNOWN
CPUTime eq, ne, gt, lt, ge, le Time hh:mm:ss
MemUsage eq, ne, gt, lt, ge, le Memory usage in KB, specify a valid integer.
Username eq, ne User name ([Domain\]User).
Services eq, ne Service Name String
Windowtitle eq, ne Window Title String
Modules eq, ne DLL Name String
On Windows checking the result of os.FindProcess() seems to be enough to check if process is running.
func isProcessRunning(pid int) bool {
_, err = os.FindProcess(pid)
if err != nil {
return false
}
if runtime.GOOS == "windows" {
return true
}
return false // further checking for other systems then Windows is not supported here
}
After searching for a few hours, the correct answer to know if a process is running on Windows is the following:
func CheckProcessLife(pid int){
cmd,_ := exec.Command("tasklist","/FI", "PID eq " + strconv.Itoa(pid)).Output()
output := string(cmd[:])
splitOutp := strings.Split(output, " ")
if !(splitOutp[1] == "no") {
time.Sleep(500 * time.Millisecond)
fmt.Println("Process is running...")
CheckProcessLife(pid)
}else{
fmt.Println("Process is no longer running.")
}
}
You can check if the process is running with his PID or directly with his name, only change this line:
cmd,_ := exec.Command("tasklist","/FI", "IMAGENAME eq yourprocessname.exe").Output()