Merge pull request #369 from fkautz/pr_out_updating_iodine_now_has_global_state

This commit is contained in:
Frederick F. Kautz IV 2015-03-25 10:40:08 -07:00
commit da89132def
6 changed files with 163 additions and 81 deletions

2
Godeps/Godeps.json generated
View File

@ -20,7 +20,7 @@
}, },
{ {
"ImportPath": "github.com/minio-io/iodine", "ImportPath": "github.com/minio-io/iodine",
"Rev": "d7c4850883ade19431e3808e9c712d3d3e69cdcc" "Rev": "b279ca8ea714fabc969883a4d1612a4e93d01611"
}, },
{ {
"ImportPath": "gopkg.in/check.v1", "ImportPath": "gopkg.in/check.v1",

View File

@ -23,6 +23,7 @@ import (
"os" "os"
"runtime" "runtime"
"strconv" "strconv"
"sync"
) )
// Error is the iodine error which contains a pointer to the original error // Error is the iodine error which contains a pointer to the original error
@ -42,6 +43,35 @@ type StackEntry struct {
Data map[string]string Data map[string]string
} }
var globalState = struct {
sync.RWMutex
m map[string]string
}{m: make(map[string]string)}
func SetGlobalState(key, value string) {
globalState.Lock()
globalState.m[key] = value
globalState.Unlock()
}
func ClearGlobalState() {
globalState.Lock()
for k, _ := range globalState.m {
delete(globalState.m, k)
}
globalState.Unlock()
}
func GetGlobalState() map[string]string {
result := make(map[string]string)
globalState.RLock()
for k, v := range globalState.m {
result[k] = v
}
globalState.RUnlock()
return result
}
// Wrap an error, turning it into an iodine error. // Wrap an error, turning it into an iodine error.
// Adds an initial stack trace. // Adds an initial stack trace.
func New(err error, data map[string]string) *Error { func New(err error, data map[string]string) *Error {
@ -63,18 +93,17 @@ func createStackEntry() StackEntry {
Host: host, Host: host,
File: file, File: file,
Line: line, Line: line,
Data: make(map[string]string), Data: GetGlobalState(),
} }
return entry return entry
} }
// Annotate an error with a stack entry and returns itself // Annotate an error with a stack entry and returns itself
func (err *Error) Annotate(info map[string]string) *Error { func (err *Error) Annotate(info map[string]string) *Error {
data := make(map[string]string)
for k, v := range info {
data[k] = v
}
entry := createStackEntry() entry := createStackEntry()
for k, v := range info {
entry.Data[k] = v
}
err.Stack = append(err.Stack, entry) err.Stack = append(err.Stack, entry)
return err return err
} }

View File

@ -38,6 +38,54 @@ func TestIodine(t *testing.T) {
} }
var prettyBuffer bytes.Buffer var prettyBuffer bytes.Buffer
json.Indent(&prettyBuffer, jsonResult, "", " ") json.Indent(&prettyBuffer, jsonResult, "", " ")
log.Println(string(prettyBuffer.Bytes())) }
log.Println(iodineError.EmitHumanReadable())
func TestState(t *testing.T) {
SetGlobalState("hello", "world")
state := GetGlobalState()
if res, ok := state["hello"]; ok {
if res != "world" {
t.Error("global state not set: hello->world")
}
} else {
t.Fail()
}
ClearGlobalState()
if len(GetGlobalState()) != 0 {
t.Fail()
}
SetGlobalState("foo", "bar")
err := New(errors.New("a simple error"), nil)
if res, ok := err.Stack[0].Data["foo"]; ok {
if res != "bar" {
t.Error("global state not set: foo->bar")
}
} else {
t.Fail()
}
err.Annotate(map[string]string{"foo2": "bar2"})
if res, ok := err.Stack[0].Data["foo"]; ok {
if res != "bar" {
t.Error("annotate should not modify previous data entries")
}
} else {
t.Error("annotate should not remove previous data entries")
}
if res, ok := err.Stack[1].Data["foo"]; ok {
if res != "bar" {
t.Error("global state should set value properly in annotate")
}
} else {
t.Error("global state should set key properly in annotate")
}
if res, ok := err.Stack[1].Data["foo2"]; ok {
if res != "bar2" {
err.Annotate(nil)
t.Error("foo2 -> bar should be set")
}
} else {
err.Annotate(nil)
log.Println(err.EmitHumanReadable())
t.Error("foo2 should be set")
}
} }

View File

@ -3,8 +3,8 @@
package check_test package check_test
import ( import (
"time"
. "gopkg.in/check.v1" . "gopkg.in/check.v1"
"time"
) )
var benchmarkS = Suite(&BenchmarkS{}) var benchmarkS = Suite(&BenchmarkS{})

View File

@ -1,7 +1,7 @@
package check_test package check_test
import ( import (
. "gopkg.in/check.v1" . "gopkg.in/check.v1"
) )
var _ = Suite(&PrinterS{}) var _ = Suite(&PrinterS{})
@ -9,96 +9,101 @@ var _ = Suite(&PrinterS{})
type PrinterS struct{} type PrinterS struct{}
func (s *PrinterS) TestCountSuite(c *C) { func (s *PrinterS) TestCountSuite(c *C) {
suitesRun += 1 suitesRun += 1
} }
var printTestFuncLine int var printTestFuncLine int
func init() { func init() {
printTestFuncLine = getMyLine() + 3 printTestFuncLine = getMyLine() + 3
} }
func printTestFunc() { func printTestFunc() {
println(1) // Comment1 println(1) // Comment1
if 2 == 2 { // Comment2 if 2 == 2 { // Comment2
println(3) // Comment3 println(3) // Comment3
} }
switch 5 { switch 5 {
case 6: println(6) // Comment6 case 6:
println(7) println(6) // Comment6
} println(7)
switch interface{}(9).(type) {// Comment9 }
case int: println(10) switch interface{}(9).(type) { // Comment9
println(11) case int:
} println(10)
select { println(11)
case <-(chan bool)(nil): println(14) }
println(15) select {
default: println(16) case <-(chan bool)(nil):
println(17) println(14)
} println(15)
println(19, default:
20) println(16)
_ = func() { println(21) println(17)
println(22) }
} println(19,
println(24, func() { 20)
println(25) _ = func() {
}) println(21)
// Leading comment println(22)
// with multiple lines. }
println(29) // Comment29 println(24, func() {
println(25)
})
// Leading comment
// with multiple lines.
println(29) // Comment29
} }
var printLineTests = []struct { var printLineTests = []struct {
line int line int
output string output string
}{ }{
{1, "println(1) // Comment1"}, {1, "println(1) // Comment1"},
{2, "if 2 == 2 { // Comment2\n ...\n}"}, {2, "if 2 == 2 { // Comment2\n ...\n}"},
{3, "println(3) // Comment3"}, {3, "println(3) // Comment3"},
{5, "switch 5 {\n...\n}"}, {5, "switch 5 {\n...\n}"},
{6, "case 6:\n println(6) // Comment6\n ..."}, {6, "case 6:\n println(6) // Comment6\n ..."},
{7, "println(7)"}, {7, "println(7)"},
{9, "switch interface{}(9).(type) { // Comment9\n...\n}"}, {9, "switch interface{}(9).(type) { // Comment9\n...\n}"},
{10, "case int:\n println(10)\n ..."}, {10, "case int:\n println(10)\n ..."},
{14, "case <-(chan bool)(nil):\n println(14)\n ..."}, {14, "case <-(chan bool)(nil):\n println(14)\n ..."},
{15, "println(15)"}, {15, "println(15)"},
{16, "default:\n println(16)\n ..."}, {16, "default:\n println(16)\n ..."},
{17, "println(17)"}, {17, "println(17)"},
{19, "println(19,\n 20)"}, {19, "println(19,\n 20)"},
{20, "println(19,\n 20)"}, {20, "println(19,\n 20)"},
{21, "_ = func() {\n println(21)\n println(22)\n}"}, {21, "_ = func() {\n println(21)\n println(22)\n}"},
{22, "println(22)"}, {22, "println(22)"},
{24, "println(24, func() {\n println(25)\n})"}, {24, "println(24, func() {\n println(25)\n})"},
{25, "println(25)"}, {25, "println(25)"},
{26, "println(24, func() {\n println(25)\n})"}, {26, "println(24, func() {\n println(25)\n})"},
{29, "// Leading comment\n// with multiple lines.\nprintln(29) // Comment29"}, {29, "// Leading comment\n// with multiple lines.\nprintln(29) // Comment29"},
} }
func (s *PrinterS) TestPrintLine(c *C) { func (s *PrinterS) TestPrintLine(c *C) {
for _, test := range printLineTests { for _, test := range printLineTests {
output, err := PrintLine("printer_test.go", printTestFuncLine+test.line) output, err := PrintLine("printer_test.go", printTestFuncLine+test.line)
c.Assert(err, IsNil) c.Assert(err, IsNil)
c.Assert(output, Equals, test.output) c.Assert(output, Equals, test.output)
} }
} }
var indentTests = []struct { var indentTests = []struct {
in, out string in, out string
}{ }{
{"", ""}, {"", ""},
{"\n", "\n"}, {"\n", "\n"},
{"a", ">>>a"}, {"a", ">>>a"},
{"a\n", ">>>a\n"}, {"a\n", ">>>a\n"},
{"a\nb", ">>>a\n>>>b"}, {"a\nb", ">>>a\n>>>b"},
{" ", ">>> "}, {" ", ">>> "},
} }
func (s *PrinterS) TestIndent(c *C) { func (s *PrinterS) TestIndent(c *C) {
for _, test := range indentTests { for _, test := range indentTests {
out := Indent(test.in, ">>>") out := Indent(test.in, ">>>")
c.Assert(out, Equals, test.out) c.Assert(out, Equals, test.out)
} }
} }

View File

@ -400,7 +400,7 @@ func (s *RunS) TestStreamModeWithMiss(c *C) {
// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// Verify that that the keep work dir request indeed does so. // Verify that that the keep work dir request indeed does so.
type WorkDirSuite struct {} type WorkDirSuite struct{}
func (s *WorkDirSuite) Test(c *C) { func (s *WorkDirSuite) Test(c *C) {
c.MkDir() c.MkDir()
@ -411,7 +411,7 @@ func (s *RunS) TestKeepWorkDir(c *C) {
runConf := RunConf{Output: &output, Verbose: true, KeepWorkDir: true} runConf := RunConf{Output: &output, Verbose: true, KeepWorkDir: true}
result := Run(&WorkDirSuite{}, &runConf) result := Run(&WorkDirSuite{}, &runConf)
c.Assert(result.String(), Matches, ".*\nWORK=" + result.WorkDir) c.Assert(result.String(), Matches, ".*\nWORK="+result.WorkDir)
stat, err := os.Stat(result.WorkDir) stat, err := os.Stat(result.WorkDir)
c.Assert(err, IsNil) c.Assert(err, IsNil)