github.com/r8d8/go-ethereum@v5.5.2+incompatible/logger/mlog_file_test.go (about)

     1  package logger
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  	"io/ioutil"
     8  	"os"
     9  	"strings"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/ethereumproject/go-ethereum/common"
    14  )
    15  
    16  var mlogExample1T = &MLogT{
    17  	Description: `Struct for testing mlog structs.`,
    18  	Receiver:    "TESTER",
    19  	Verb:        "TESTING",
    20  	Subject:     "MLOG",
    21  	Details: []MLogDetailT{
    22  		{"FROM", "UDP_ADDRESS", "STRING"},
    23  		{"FROM", "ID", "STRING"},
    24  		{"NEIGHBORS", "BYTES_TRANSFERRED", "INT"},
    25  	},
    26  }
    27  
    28  var mlogExample2T = &MLogT{
    29  	Description: `Yet another struct for testing mlog structs.`,
    30  	Receiver:    "TESTER",
    31  	Verb:        "TESTING",
    32  	Subject:     "MLOG",
    33  	Details: []MLogDetailT{
    34  		{"FROM", "UDP_ADDRESS", "STRING"},
    35  		{"FROM", "ID", "STRING"},
    36  		{"NEIGHBORS", "BYTES_TRANSFERRED", "INT"},
    37  	},
    38  }
    39  
    40  func BenchmarkSetDetailValues(b *testing.B) {
    41  	vals := []interface{}{"hello", "kitty", 42}
    42  	for i := 0; i < b.N; i++ {
    43  		mlogExample1T.AssignDetails(vals...)
    44  	}
    45  }
    46  
    47  func TestEnabling(t *testing.T) {
    48  	SetMlogEnabled(false)
    49  	if MlogEnabled() != false {
    50  		t.Error("expected: false, got: true")
    51  	}
    52  
    53  	SetMlogEnabled(true)
    54  	if MlogEnabled() != true {
    55  		t.Error("expected: true, got: false")
    56  	}
    57  }
    58  
    59  func TestRegisterAvailable(t *testing.T) {
    60  	MLogRegisterAvailable("example1", []*MLogT{mlogExample1T})
    61  
    62  	avail := GetMLogRegistryAvailable()
    63  	if len(avail) != 1 {
    64  		t.Errorf("expected: 1, got: %d", len(avail))
    65  	}
    66  	if _, ok := avail["example1"]; !ok {
    67  		t.Error("expected key 'example1' not found")
    68  	}
    69  	if l := len(avail["example1"]); l != 1 {
    70  		t.Errorf("expected: 1, got: %d", l)
    71  	}
    72  
    73  	MLogRegisterAvailable("example1", []*MLogT{mlogExample2T})
    74  	avail = GetMLogRegistryAvailable()
    75  	if len(avail) != 1 {
    76  		t.Errorf("expected: 1, got: %d", len(avail))
    77  	}
    78  	if _, ok := avail["example1"]; !ok {
    79  		t.Error("expected key 'example1' not found")
    80  	}
    81  	if l := len(avail["example1"]); l != 1 {
    82  		t.Errorf("expected: 1, got: %d", l)
    83  	}
    84  
    85  	MLogRegisterAvailable("example1", []*MLogT{mlogExample1T, mlogExample2T})
    86  	avail = GetMLogRegistryAvailable()
    87  	if len(avail) != 1 {
    88  		t.Errorf("expected: 1, got: %d", len(avail))
    89  	}
    90  	if _, ok := avail["example1"]; !ok {
    91  		t.Error("expected key 'example1' not found")
    92  	}
    93  	if l := len(avail["example1"]); l != 2 {
    94  		t.Errorf("expected: 2, got: %d", l)
    95  	}
    96  
    97  	MLogRegisterAvailable("example2", []*MLogT{mlogExample2T})
    98  	avail = GetMLogRegistryAvailable()
    99  	if len(avail) != 2 {
   100  		t.Errorf("expected: 2, got: %d", len(avail))
   101  	}
   102  	if _, ok := avail["example1"]; !ok {
   103  		t.Error("expected key 'example1' not found")
   104  	}
   105  	if l := len(avail["example1"]); l != 2 {
   106  		t.Errorf("expected: 2, got: %d", l)
   107  	}
   108  	if _, ok := avail["example2"]; !ok {
   109  		t.Error("expected key 'example1' not found")
   110  	}
   111  	if l := len(avail["example2"]); l != 1 {
   112  		t.Errorf("expected: 1, got: %d", l)
   113  	}
   114  }
   115  
   116  func TestRegisterFromContext(t *testing.T) {
   117  	setupRegister()
   118  
   119  	err := MLogRegisterComponentsFromContext("example1")
   120  	if err != nil {
   121  		t.Errorf("unexpected error: %v", err)
   122  	}
   123  
   124  	active := GetMLogRegistryActive()
   125  	if l := len(active); l != 1 {
   126  		t.Errorf("expected: 1, got: %d", l)
   127  	}
   128  	if _, ok := active["example1"]; !ok {
   129  		t.Error("expected key 'example1' not found")
   130  	}
   131  }
   132  
   133  func TestRegisterFromContextMany(t *testing.T) {
   134  	setupRegister()
   135  
   136  	err := MLogRegisterComponentsFromContext("example3,example2")
   137  	if err != nil {
   138  		t.Errorf("unexpected error: %v", err)
   139  	}
   140  
   141  	active := GetMLogRegistryActive()
   142  	if l := len(active); l != 2 {
   143  		t.Errorf("expected: 2, got: %d", l)
   144  	}
   145  	if _, ok := active["example2"]; !ok {
   146  		t.Error("expected key 'example2' not found")
   147  	}
   148  	if _, ok := active["example3"]; !ok {
   149  		t.Error("expected key 'example3' not found")
   150  	}
   151  }
   152  
   153  func TestRegisterFromNegativeContext(t *testing.T) {
   154  	setupRegister()
   155  
   156  	err := MLogRegisterComponentsFromContext("!example2")
   157  	if err != nil {
   158  		t.Errorf("unexpected error: %v", err)
   159  	}
   160  
   161  	active := GetMLogRegistryActive()
   162  	if l := len(active); l != 2 {
   163  		t.Errorf("expected: 2, got: %d", l)
   164  	}
   165  	if _, ok := active["example1"]; !ok {
   166  		t.Error("expected key 'example1' not found")
   167  	}
   168  	if _, ok := active["example3"]; !ok {
   169  		t.Error("expected key 'example3' not found")
   170  	}
   171  }
   172  
   173  func TestRegisterFromNegativeContextMany(t *testing.T) {
   174  	setupRegister()
   175  
   176  	err := MLogRegisterComponentsFromContext("!example2,example1")
   177  	if err != nil {
   178  		t.Errorf("unexpected error: %v", err)
   179  	}
   180  
   181  	active := GetMLogRegistryActive()
   182  	if l := len(active); l != 1 {
   183  		t.Errorf("expected: 1, got: %d", l)
   184  	}
   185  	if _, ok := active["example3"]; !ok {
   186  		t.Error("expected key 'example3' not found")
   187  	}
   188  }
   189  
   190  func TestRegisterFromWrongContext(t *testing.T) {
   191  	setupRegister()
   192  
   193  	err := MLogRegisterComponentsFromContext("wrongOne")
   194  	if err == nil {
   195  		t.Error("expected error, got nil")
   196  	}
   197  
   198  	err = MLogRegisterComponentsFromContext("example1,wrongOne")
   199  	if err == nil {
   200  		t.Error("expected error, got nil")
   201  	}
   202  }
   203  
   204  func setupRegister() {
   205  	MLogRegisterAvailable("example1", []*MLogT{mlogExample1T, mlogExample2T})
   206  	MLogRegisterAvailable("example2", []*MLogT{mlogExample1T, mlogExample2T})
   207  	MLogRegisterAvailable("example3", []*MLogT{mlogExample1T, mlogExample2T})
   208  
   209  	// clean the global state
   210  	MLogRegisterComponentsFromContext("!example1,example2,example3")
   211  }
   212  
   213  func TestAssignDetails(t *testing.T) {
   214  	addr := "sampleAddress"
   215  	id := "sampleId"
   216  	bytes := 123
   217  	mlogExample1T.AssignDetails(addr, id, bytes)
   218  
   219  	if mlogExample1T.Details[0].Value != addr {
   220  		t.Errorf("expected: '%s', got: '%s'", addr, mlogExample1T.Details[0].Value)
   221  	}
   222  	if mlogExample1T.Details[1].Value != id {
   223  		t.Errorf("expected: '%s', got: '%s'", id, mlogExample1T.Details[1].Value)
   224  	}
   225  	if mlogExample1T.Details[2].Value != bytes {
   226  		t.Errorf("expected: %d, got: %d", bytes, mlogExample1T.Details[2].Value)
   227  	}
   228  
   229  	// assign again...
   230  	addr2 := "anotherAddress"
   231  	id2 := "anotherId"
   232  	bytes2 := 321
   233  	mlogExample1T.AssignDetails(addr2, id2, bytes2)
   234  
   235  	if mlogExample1T.Details[0].Value != addr2 {
   236  		t.Errorf("expected: '%s', got: '%s'", addr2, mlogExample1T.Details[0].Value)
   237  	}
   238  	if mlogExample1T.Details[1].Value != id2 {
   239  		t.Errorf("expected: '%s', got: '%s'", id2, mlogExample1T.Details[1].Value)
   240  	}
   241  	if mlogExample1T.Details[2].Value != bytes2 {
   242  		t.Errorf("expected: %d, got: %d", bytes2, mlogExample1T.Details[2].Value)
   243  	}
   244  }
   245  
   246  func TestSend(t *testing.T) {
   247  	Reset()
   248  	// Set up a log sys with a local buffer instead of file
   249  	var b = new(bytes.Buffer)
   250  	sys := NewMLogSystem(b, 0, LogLevel(1), false)
   251  	AddLogSystem(sys)
   252  
   253  	testLogger := MLogRegisterAvailable("example1", []*MLogT{mlogExample1T, mlogExample2T})
   254  	MLogRegisterActive("example1")
   255  
   256  	addr := "sampleAddress"
   257  	id := "sampleId"
   258  	numBytesSent := 123
   259  	mlogExample1T.AssignDetails(addr, id, numBytesSent)
   260  
   261  	formats := []string{"plain", "kv", "json"}
   262  
   263  	for _, format := range formats {
   264  		SetMLogFormatFromString(format)
   265  		mlogExample1T.Send(testLogger)
   266  
   267  		Flush() // wait for messages to be delivered
   268  
   269  		if format == "plain" || format == "kv" {
   270  			var wantString string
   271  			if format == "plain" {
   272  				wantString = mlogExample1T.FormatPlain()
   273  			} else if format == "kv" {
   274  				wantString = mlogExample1T.FormatKV()
   275  			}
   276  
   277  			// basic sanity check for our expectations
   278  			if len(wantString) < 10 || !strings.Contains(wantString, common.SessionID) {
   279  				t.Fatalf("wantstring: got: %v, want: %v", wantString, "something sane")
   280  			}
   281  
   282  			if !strings.Contains(b.String(), wantString) {
   283  				t.Errorf("got: %v, want: %v", b.String(), wantString)
   284  			} else {
   285  				t.Logf("%s ok: %s", format, b.String())
   286  			}
   287  
   288  			b.Reset()
   289  			continue
   290  		}
   291  
   292  		// handle JSON differently, since we can show that values are OK as well as valid JSON format
   293  		//
   294  		// for decoding the JSON line for got/want comparison
   295  		type arbitraryJSON map[string]interface{}
   296  		arb := arbitraryJSON{}
   297  
   298  		if err := json.Unmarshal(b.Bytes(), &arb); err != nil {
   299  			t.Fatal(err)
   300  		}
   301  
   302  		wantMap := make(map[string]interface{})
   303  
   304  		wantMap["component"] = string(testLogger)
   305  		wantMap["session"] = common.SessionID
   306  
   307  		// eg. "event":"tester.testing.mlog"
   308  		wantMap["event"] = strings.Join([]string{
   309  			strings.ToLower(mlogExample1T.Receiver),
   310  			strings.ToLower(mlogExample1T.Verb),
   311  			strings.ToLower(mlogExample1T.Subject),
   312  		}, ".")
   313  
   314  		// eg. "from.udp_address":"sampleAddress"
   315  		for _, v := range mlogExample1T.Details {
   316  			wantMap[strings.Join(
   317  				[]string{
   318  					strings.ToLower(v.Owner),
   319  					strings.ToLower(v.Key),
   320  				}, ".")] = v.Value
   321  		}
   322  
   323  		var hasError bool
   324  		for k, v := range wantMap {
   325  			// fmtStringer comparison because 123 != 123...
   326  			if arb[k] != v && fmt.Sprintf("%v", arb[k]) != fmt.Sprintf("%v", v) {
   327  				hasError = true
   328  				t.Errorf("arb[k] != v, arb[k] = %v, v = %v", arb[k], v)
   329  				t.Errorf("got: %v, want: %v", b.String(), wantMap)
   330  			}
   331  		}
   332  
   333  		if !hasError {
   334  			t.Logf("%s ok: %s", format, b.String())
   335  		}
   336  
   337  		b.Reset()
   338  	}
   339  }
   340  
   341  func TestFormats(t *testing.T) {
   342  	formats := []struct {
   343  		name  string
   344  		valid bool
   345  	}{
   346  		{"plain", true},
   347  		{"kv", true},
   348  		{"json", true},
   349  		{"invalid", false},
   350  	}
   351  
   352  	for _, format := range formats {
   353  		t.Run(format.name, func(t *testing.T) {
   354  			err := SetMLogFormatFromString(format.name)
   355  			if format.valid {
   356  				if err != nil {
   357  					t.Error("unexpected error")
   358  				}
   359  				if fmt := GetMLogFormat().String(); fmt != format.name {
   360  					t.Errorf("expected: '%s', got: '%s'", format.name, fmt)
   361  				}
   362  			} else {
   363  				if err == nil {
   364  					t.Error("expected error, got nil")
   365  				}
   366  			}
   367  		})
   368  	}
   369  }
   370  
   371  func TestInit(t *testing.T) {
   372  	now := time.Now()
   373  
   374  	dir, err := ioutil.TempDir("", "mlog_test")
   375  	if err != nil {
   376  		t.Errorf("cannot create temp dir: %v", err)
   377  	}
   378  	defer os.RemoveAll(dir) // clean up
   379  
   380  	SetMLogDir(dir)
   381  	_, filename, err := CreateMLogFile(now)
   382  	if err != nil {
   383  		t.Errorf("unexpected error: %v", err)
   384  	}
   385  	if len(filename) == 0 {
   386  		t.Errorf("expected non-empty filename")
   387  	}
   388  	if !strings.HasPrefix(filename, dir) {
   389  		t.Errorf("file created in wrong directory, expected: %s, got: %s", dir, filename)
   390  	}
   391  }
   392  
   393  func TestDocumentation(t *testing.T) {
   394  	// reset structure to force valid type information and give some esoteric names
   395  	mlogExample1T.Details = []MLogDetailT{
   396  		{"FROM616", "UDP_ADDRESS911", "STRING"},
   397  		{"FROM666", "RANDOMIZED_ID", "STRING"},
   398  		{"NEIGHBORS", "BYTES_TRANSFERRED", "INT"},
   399  	}
   400  	logger := MLogRegisterAvailable("example1", []*MLogT{mlogExample1T})
   401  
   402  	docs := mlogExample1T.FormatDocumentation(logger)
   403  	if len(docs) == 0 {
   404  		t.Error("documentation is empty!")
   405  	}
   406  	if !strings.Contains(docs, mlogExample1T.Subject) {
   407  		t.Error("missing information about subject")
   408  	}
   409  	if !strings.Contains(docs, mlogExample1T.Receiver) {
   410  		t.Error("missing information about receiver")
   411  	}
   412  	if !strings.Contains(docs, mlogExample1T.Verb) {
   413  		t.Error("missing information about verb")
   414  	}
   415  	ldocs := strings.ToLower(docs)
   416  	for _, detail := range mlogExample1T.Details {
   417  		if !strings.Contains(ldocs, strings.ToLower(detail.Owner)) {
   418  			t.Error("missing information about detail owner")
   419  		}
   420  		if !strings.Contains(ldocs, strings.ToLower(detail.Key)) {
   421  			t.Error("missing information about detail key")
   422  		}
   423  	}
   424  }