github.com/jiasir/docker@v1.3.3-0.20170609024000-252e610103e7/daemon/logger/splunk/splunk_test.go (about)

     1  package splunk
     2  
     3  import (
     4  	"compress/gzip"
     5  	"fmt"
     6  	"os"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/docker/docker/daemon/logger"
    11  )
    12  
    13  // Validate options
    14  func TestValidateLogOpt(t *testing.T) {
    15  	err := ValidateLogOpt(map[string]string{
    16  		splunkURLKey:                  "http://127.0.0.1",
    17  		splunkTokenKey:                "2160C7EF-2CE9-4307-A180-F852B99CF417",
    18  		splunkSourceKey:               "mysource",
    19  		splunkSourceTypeKey:           "mysourcetype",
    20  		splunkIndexKey:                "myindex",
    21  		splunkCAPathKey:               "/usr/cert.pem",
    22  		splunkCANameKey:               "ca_name",
    23  		splunkInsecureSkipVerifyKey:   "true",
    24  		splunkFormatKey:               "json",
    25  		splunkVerifyConnectionKey:     "true",
    26  		splunkGzipCompressionKey:      "true",
    27  		splunkGzipCompressionLevelKey: "1",
    28  		envKey:      "a",
    29  		envRegexKey: "^foo",
    30  		labelsKey:   "b",
    31  		tagKey:      "c",
    32  	})
    33  	if err != nil {
    34  		t.Fatal(err)
    35  	}
    36  
    37  	err = ValidateLogOpt(map[string]string{
    38  		"not-supported-option": "a",
    39  	})
    40  	if err == nil {
    41  		t.Fatal("Expecting error on unsupported options")
    42  	}
    43  }
    44  
    45  // Driver require user to specify required options
    46  func TestNewMissedConfig(t *testing.T) {
    47  	info := logger.Info{
    48  		Config: map[string]string{},
    49  	}
    50  	_, err := New(info)
    51  	if err == nil {
    52  		t.Fatal("Logger driver should fail when no required parameters specified")
    53  	}
    54  }
    55  
    56  // Driver require user to specify splunk-url
    57  func TestNewMissedUrl(t *testing.T) {
    58  	info := logger.Info{
    59  		Config: map[string]string{
    60  			splunkTokenKey: "4642492F-D8BD-47F1-A005-0C08AE4657DF",
    61  		},
    62  	}
    63  	_, err := New(info)
    64  	if err.Error() != "splunk: splunk-url is expected" {
    65  		t.Fatal("Logger driver should fail when no required parameters specified")
    66  	}
    67  }
    68  
    69  // Driver require user to specify splunk-token
    70  func TestNewMissedToken(t *testing.T) {
    71  	info := logger.Info{
    72  		Config: map[string]string{
    73  			splunkURLKey: "http://127.0.0.1:8088",
    74  		},
    75  	}
    76  	_, err := New(info)
    77  	if err.Error() != "splunk: splunk-token is expected" {
    78  		t.Fatal("Logger driver should fail when no required parameters specified")
    79  	}
    80  }
    81  
    82  // Test default settings
    83  func TestDefault(t *testing.T) {
    84  	hec := NewHTTPEventCollectorMock(t)
    85  
    86  	go hec.Serve()
    87  
    88  	info := logger.Info{
    89  		Config: map[string]string{
    90  			splunkURLKey:   hec.URL(),
    91  			splunkTokenKey: hec.token,
    92  		},
    93  		ContainerID:        "containeriid",
    94  		ContainerName:      "container_name",
    95  		ContainerImageID:   "contaimageid",
    96  		ContainerImageName: "container_image_name",
    97  	}
    98  
    99  	hostname, err := info.Hostname()
   100  	if err != nil {
   101  		t.Fatal(err)
   102  	}
   103  
   104  	loggerDriver, err := New(info)
   105  	if err != nil {
   106  		t.Fatal(err)
   107  	}
   108  
   109  	if loggerDriver.Name() != driverName {
   110  		t.Fatal("Unexpected logger driver name")
   111  	}
   112  
   113  	if !hec.connectionVerified {
   114  		t.Fatal("By default connection should be verified")
   115  	}
   116  
   117  	splunkLoggerDriver, ok := loggerDriver.(*splunkLoggerInline)
   118  	if !ok {
   119  		t.Fatal("Unexpected Splunk Logging Driver type")
   120  	}
   121  
   122  	if splunkLoggerDriver.url != hec.URL()+"/services/collector/event/1.0" ||
   123  		splunkLoggerDriver.auth != "Splunk "+hec.token ||
   124  		splunkLoggerDriver.nullMessage.Host != hostname ||
   125  		splunkLoggerDriver.nullMessage.Source != "" ||
   126  		splunkLoggerDriver.nullMessage.SourceType != "" ||
   127  		splunkLoggerDriver.nullMessage.Index != "" ||
   128  		splunkLoggerDriver.gzipCompression != false ||
   129  		splunkLoggerDriver.postMessagesFrequency != defaultPostMessagesFrequency ||
   130  		splunkLoggerDriver.postMessagesBatchSize != defaultPostMessagesBatchSize ||
   131  		splunkLoggerDriver.bufferMaximum != defaultBufferMaximum ||
   132  		cap(splunkLoggerDriver.stream) != defaultStreamChannelSize {
   133  		t.Fatal("Found not default values setup in Splunk Logging Driver.")
   134  	}
   135  
   136  	message1Time := time.Now()
   137  	if err := loggerDriver.Log(&logger.Message{Line: []byte("{\"a\":\"b\"}"), Source: "stdout", Timestamp: message1Time}); err != nil {
   138  		t.Fatal(err)
   139  	}
   140  	message2Time := time.Now()
   141  	if err := loggerDriver.Log(&logger.Message{Line: []byte("notajson"), Source: "stdout", Timestamp: message2Time}); err != nil {
   142  		t.Fatal(err)
   143  	}
   144  
   145  	err = loggerDriver.Close()
   146  	if err != nil {
   147  		t.Fatal(err)
   148  	}
   149  
   150  	if len(hec.messages) != 2 {
   151  		t.Fatal("Expected two messages")
   152  	}
   153  
   154  	if *hec.gzipEnabled {
   155  		t.Fatal("Gzip should not be used")
   156  	}
   157  
   158  	message1 := hec.messages[0]
   159  	if message1.Time != fmt.Sprintf("%f", float64(message1Time.UnixNano())/float64(time.Second)) ||
   160  		message1.Host != hostname ||
   161  		message1.Source != "" ||
   162  		message1.SourceType != "" ||
   163  		message1.Index != "" {
   164  		t.Fatalf("Unexpected values of message 1 %v", message1)
   165  	}
   166  
   167  	if event, err := message1.EventAsMap(); err != nil {
   168  		t.Fatal(err)
   169  	} else {
   170  		if event["line"] != "{\"a\":\"b\"}" ||
   171  			event["source"] != "stdout" ||
   172  			event["tag"] != "containeriid" ||
   173  			len(event) != 3 {
   174  			t.Fatalf("Unexpected event in message %v", event)
   175  		}
   176  	}
   177  
   178  	message2 := hec.messages[1]
   179  	if message2.Time != fmt.Sprintf("%f", float64(message2Time.UnixNano())/float64(time.Second)) ||
   180  		message2.Host != hostname ||
   181  		message2.Source != "" ||
   182  		message2.SourceType != "" ||
   183  		message2.Index != "" {
   184  		t.Fatalf("Unexpected values of message 1 %v", message2)
   185  	}
   186  
   187  	if event, err := message2.EventAsMap(); err != nil {
   188  		t.Fatal(err)
   189  	} else {
   190  		if event["line"] != "notajson" ||
   191  			event["source"] != "stdout" ||
   192  			event["tag"] != "containeriid" ||
   193  			len(event) != 3 {
   194  			t.Fatalf("Unexpected event in message %v", event)
   195  		}
   196  	}
   197  
   198  	err = hec.Close()
   199  	if err != nil {
   200  		t.Fatal(err)
   201  	}
   202  }
   203  
   204  // Verify inline format with a not default settings for most of options
   205  func TestInlineFormatWithNonDefaultOptions(t *testing.T) {
   206  	hec := NewHTTPEventCollectorMock(t)
   207  
   208  	go hec.Serve()
   209  
   210  	info := logger.Info{
   211  		Config: map[string]string{
   212  			splunkURLKey:             hec.URL(),
   213  			splunkTokenKey:           hec.token,
   214  			splunkSourceKey:          "mysource",
   215  			splunkSourceTypeKey:      "mysourcetype",
   216  			splunkIndexKey:           "myindex",
   217  			splunkFormatKey:          splunkFormatInline,
   218  			splunkGzipCompressionKey: "true",
   219  			tagKey:      "{{.ImageName}}/{{.Name}}",
   220  			labelsKey:   "a",
   221  			envRegexKey: "^foo",
   222  		},
   223  		ContainerID:        "containeriid",
   224  		ContainerName:      "/container_name",
   225  		ContainerImageID:   "contaimageid",
   226  		ContainerImageName: "container_image_name",
   227  		ContainerLabels: map[string]string{
   228  			"a": "b",
   229  		},
   230  		ContainerEnv: []string{"foo_finder=bar"},
   231  	}
   232  
   233  	hostname, err := info.Hostname()
   234  	if err != nil {
   235  		t.Fatal(err)
   236  	}
   237  
   238  	loggerDriver, err := New(info)
   239  	if err != nil {
   240  		t.Fatal(err)
   241  	}
   242  
   243  	if !hec.connectionVerified {
   244  		t.Fatal("By default connection should be verified")
   245  	}
   246  
   247  	splunkLoggerDriver, ok := loggerDriver.(*splunkLoggerInline)
   248  	if !ok {
   249  		t.Fatal("Unexpected Splunk Logging Driver type")
   250  	}
   251  
   252  	if splunkLoggerDriver.url != hec.URL()+"/services/collector/event/1.0" ||
   253  		splunkLoggerDriver.auth != "Splunk "+hec.token ||
   254  		splunkLoggerDriver.nullMessage.Host != hostname ||
   255  		splunkLoggerDriver.nullMessage.Source != "mysource" ||
   256  		splunkLoggerDriver.nullMessage.SourceType != "mysourcetype" ||
   257  		splunkLoggerDriver.nullMessage.Index != "myindex" ||
   258  		splunkLoggerDriver.gzipCompression != true ||
   259  		splunkLoggerDriver.gzipCompressionLevel != gzip.DefaultCompression ||
   260  		splunkLoggerDriver.postMessagesFrequency != defaultPostMessagesFrequency ||
   261  		splunkLoggerDriver.postMessagesBatchSize != defaultPostMessagesBatchSize ||
   262  		splunkLoggerDriver.bufferMaximum != defaultBufferMaximum ||
   263  		cap(splunkLoggerDriver.stream) != defaultStreamChannelSize {
   264  		t.Fatal("Values do not match configuration.")
   265  	}
   266  
   267  	messageTime := time.Now()
   268  	if err := loggerDriver.Log(&logger.Message{Line: []byte("1"), Source: "stdout", Timestamp: messageTime}); err != nil {
   269  		t.Fatal(err)
   270  	}
   271  
   272  	err = loggerDriver.Close()
   273  	if err != nil {
   274  		t.Fatal(err)
   275  	}
   276  
   277  	if len(hec.messages) != 1 {
   278  		t.Fatal("Expected one message")
   279  	}
   280  
   281  	if !*hec.gzipEnabled {
   282  		t.Fatal("Gzip should be used")
   283  	}
   284  
   285  	message := hec.messages[0]
   286  	if message.Time != fmt.Sprintf("%f", float64(messageTime.UnixNano())/float64(time.Second)) ||
   287  		message.Host != hostname ||
   288  		message.Source != "mysource" ||
   289  		message.SourceType != "mysourcetype" ||
   290  		message.Index != "myindex" {
   291  		t.Fatalf("Unexpected values of message %v", message)
   292  	}
   293  
   294  	if event, err := message.EventAsMap(); err != nil {
   295  		t.Fatal(err)
   296  	} else {
   297  		if event["line"] != "1" ||
   298  			event["source"] != "stdout" ||
   299  			event["tag"] != "container_image_name/container_name" ||
   300  			event["attrs"].(map[string]interface{})["a"] != "b" ||
   301  			event["attrs"].(map[string]interface{})["foo_finder"] != "bar" ||
   302  			len(event) != 4 {
   303  			t.Fatalf("Unexpected event in message %v", event)
   304  		}
   305  	}
   306  
   307  	err = hec.Close()
   308  	if err != nil {
   309  		t.Fatal(err)
   310  	}
   311  }
   312  
   313  // Verify JSON format
   314  func TestJsonFormat(t *testing.T) {
   315  	hec := NewHTTPEventCollectorMock(t)
   316  
   317  	go hec.Serve()
   318  
   319  	info := logger.Info{
   320  		Config: map[string]string{
   321  			splunkURLKey:                  hec.URL(),
   322  			splunkTokenKey:                hec.token,
   323  			splunkFormatKey:               splunkFormatJSON,
   324  			splunkGzipCompressionKey:      "true",
   325  			splunkGzipCompressionLevelKey: "1",
   326  		},
   327  		ContainerID:        "containeriid",
   328  		ContainerName:      "/container_name",
   329  		ContainerImageID:   "contaimageid",
   330  		ContainerImageName: "container_image_name",
   331  	}
   332  
   333  	hostname, err := info.Hostname()
   334  	if err != nil {
   335  		t.Fatal(err)
   336  	}
   337  
   338  	loggerDriver, err := New(info)
   339  	if err != nil {
   340  		t.Fatal(err)
   341  	}
   342  
   343  	if !hec.connectionVerified {
   344  		t.Fatal("By default connection should be verified")
   345  	}
   346  
   347  	splunkLoggerDriver, ok := loggerDriver.(*splunkLoggerJSON)
   348  	if !ok {
   349  		t.Fatal("Unexpected Splunk Logging Driver type")
   350  	}
   351  
   352  	if splunkLoggerDriver.url != hec.URL()+"/services/collector/event/1.0" ||
   353  		splunkLoggerDriver.auth != "Splunk "+hec.token ||
   354  		splunkLoggerDriver.nullMessage.Host != hostname ||
   355  		splunkLoggerDriver.nullMessage.Source != "" ||
   356  		splunkLoggerDriver.nullMessage.SourceType != "" ||
   357  		splunkLoggerDriver.nullMessage.Index != "" ||
   358  		splunkLoggerDriver.gzipCompression != true ||
   359  		splunkLoggerDriver.gzipCompressionLevel != gzip.BestSpeed ||
   360  		splunkLoggerDriver.postMessagesFrequency != defaultPostMessagesFrequency ||
   361  		splunkLoggerDriver.postMessagesBatchSize != defaultPostMessagesBatchSize ||
   362  		splunkLoggerDriver.bufferMaximum != defaultBufferMaximum ||
   363  		cap(splunkLoggerDriver.stream) != defaultStreamChannelSize {
   364  		t.Fatal("Values do not match configuration.")
   365  	}
   366  
   367  	message1Time := time.Now()
   368  	if err := loggerDriver.Log(&logger.Message{Line: []byte("{\"a\":\"b\"}"), Source: "stdout", Timestamp: message1Time}); err != nil {
   369  		t.Fatal(err)
   370  	}
   371  	message2Time := time.Now()
   372  	if err := loggerDriver.Log(&logger.Message{Line: []byte("notjson"), Source: "stdout", Timestamp: message2Time}); err != nil {
   373  		t.Fatal(err)
   374  	}
   375  
   376  	err = loggerDriver.Close()
   377  	if err != nil {
   378  		t.Fatal(err)
   379  	}
   380  
   381  	if len(hec.messages) != 2 {
   382  		t.Fatal("Expected two messages")
   383  	}
   384  
   385  	message1 := hec.messages[0]
   386  	if message1.Time != fmt.Sprintf("%f", float64(message1Time.UnixNano())/float64(time.Second)) ||
   387  		message1.Host != hostname ||
   388  		message1.Source != "" ||
   389  		message1.SourceType != "" ||
   390  		message1.Index != "" {
   391  		t.Fatalf("Unexpected values of message 1 %v", message1)
   392  	}
   393  
   394  	if event, err := message1.EventAsMap(); err != nil {
   395  		t.Fatal(err)
   396  	} else {
   397  		if event["line"].(map[string]interface{})["a"] != "b" ||
   398  			event["source"] != "stdout" ||
   399  			event["tag"] != "containeriid" ||
   400  			len(event) != 3 {
   401  			t.Fatalf("Unexpected event in message 1 %v", event)
   402  		}
   403  	}
   404  
   405  	message2 := hec.messages[1]
   406  	if message2.Time != fmt.Sprintf("%f", float64(message2Time.UnixNano())/float64(time.Second)) ||
   407  		message2.Host != hostname ||
   408  		message2.Source != "" ||
   409  		message2.SourceType != "" ||
   410  		message2.Index != "" {
   411  		t.Fatalf("Unexpected values of message 2 %v", message2)
   412  	}
   413  
   414  	// If message cannot be parsed as JSON - it should be sent as a line
   415  	if event, err := message2.EventAsMap(); err != nil {
   416  		t.Fatal(err)
   417  	} else {
   418  		if event["line"] != "notjson" ||
   419  			event["source"] != "stdout" ||
   420  			event["tag"] != "containeriid" ||
   421  			len(event) != 3 {
   422  			t.Fatalf("Unexpected event in message 2 %v", event)
   423  		}
   424  	}
   425  
   426  	err = hec.Close()
   427  	if err != nil {
   428  		t.Fatal(err)
   429  	}
   430  }
   431  
   432  // Verify raw format
   433  func TestRawFormat(t *testing.T) {
   434  	hec := NewHTTPEventCollectorMock(t)
   435  
   436  	go hec.Serve()
   437  
   438  	info := logger.Info{
   439  		Config: map[string]string{
   440  			splunkURLKey:    hec.URL(),
   441  			splunkTokenKey:  hec.token,
   442  			splunkFormatKey: splunkFormatRaw,
   443  		},
   444  		ContainerID:        "containeriid",
   445  		ContainerName:      "/container_name",
   446  		ContainerImageID:   "contaimageid",
   447  		ContainerImageName: "container_image_name",
   448  	}
   449  
   450  	hostname, err := info.Hostname()
   451  	if err != nil {
   452  		t.Fatal(err)
   453  	}
   454  
   455  	loggerDriver, err := New(info)
   456  	if err != nil {
   457  		t.Fatal(err)
   458  	}
   459  
   460  	if !hec.connectionVerified {
   461  		t.Fatal("By default connection should be verified")
   462  	}
   463  
   464  	splunkLoggerDriver, ok := loggerDriver.(*splunkLoggerRaw)
   465  	if !ok {
   466  		t.Fatal("Unexpected Splunk Logging Driver type")
   467  	}
   468  
   469  	if splunkLoggerDriver.url != hec.URL()+"/services/collector/event/1.0" ||
   470  		splunkLoggerDriver.auth != "Splunk "+hec.token ||
   471  		splunkLoggerDriver.nullMessage.Host != hostname ||
   472  		splunkLoggerDriver.nullMessage.Source != "" ||
   473  		splunkLoggerDriver.nullMessage.SourceType != "" ||
   474  		splunkLoggerDriver.nullMessage.Index != "" ||
   475  		splunkLoggerDriver.gzipCompression != false ||
   476  		splunkLoggerDriver.postMessagesFrequency != defaultPostMessagesFrequency ||
   477  		splunkLoggerDriver.postMessagesBatchSize != defaultPostMessagesBatchSize ||
   478  		splunkLoggerDriver.bufferMaximum != defaultBufferMaximum ||
   479  		cap(splunkLoggerDriver.stream) != defaultStreamChannelSize ||
   480  		string(splunkLoggerDriver.prefix) != "containeriid " {
   481  		t.Fatal("Values do not match configuration.")
   482  	}
   483  
   484  	message1Time := time.Now()
   485  	if err := loggerDriver.Log(&logger.Message{Line: []byte("{\"a\":\"b\"}"), Source: "stdout", Timestamp: message1Time}); err != nil {
   486  		t.Fatal(err)
   487  	}
   488  	message2Time := time.Now()
   489  	if err := loggerDriver.Log(&logger.Message{Line: []byte("notjson"), Source: "stdout", Timestamp: message2Time}); err != nil {
   490  		t.Fatal(err)
   491  	}
   492  
   493  	err = loggerDriver.Close()
   494  	if err != nil {
   495  		t.Fatal(err)
   496  	}
   497  
   498  	if len(hec.messages) != 2 {
   499  		t.Fatal("Expected two messages")
   500  	}
   501  
   502  	message1 := hec.messages[0]
   503  	if message1.Time != fmt.Sprintf("%f", float64(message1Time.UnixNano())/float64(time.Second)) ||
   504  		message1.Host != hostname ||
   505  		message1.Source != "" ||
   506  		message1.SourceType != "" ||
   507  		message1.Index != "" {
   508  		t.Fatalf("Unexpected values of message 1 %v", message1)
   509  	}
   510  
   511  	if event, err := message1.EventAsString(); err != nil {
   512  		t.Fatal(err)
   513  	} else {
   514  		if event != "containeriid {\"a\":\"b\"}" {
   515  			t.Fatalf("Unexpected event in message 1 %v", event)
   516  		}
   517  	}
   518  
   519  	message2 := hec.messages[1]
   520  	if message2.Time != fmt.Sprintf("%f", float64(message2Time.UnixNano())/float64(time.Second)) ||
   521  		message2.Host != hostname ||
   522  		message2.Source != "" ||
   523  		message2.SourceType != "" ||
   524  		message2.Index != "" {
   525  		t.Fatalf("Unexpected values of message 2 %v", message2)
   526  	}
   527  
   528  	if event, err := message2.EventAsString(); err != nil {
   529  		t.Fatal(err)
   530  	} else {
   531  		if event != "containeriid notjson" {
   532  			t.Fatalf("Unexpected event in message 1 %v", event)
   533  		}
   534  	}
   535  
   536  	err = hec.Close()
   537  	if err != nil {
   538  		t.Fatal(err)
   539  	}
   540  }
   541  
   542  // Verify raw format with labels
   543  func TestRawFormatWithLabels(t *testing.T) {
   544  	hec := NewHTTPEventCollectorMock(t)
   545  
   546  	go hec.Serve()
   547  
   548  	info := logger.Info{
   549  		Config: map[string]string{
   550  			splunkURLKey:    hec.URL(),
   551  			splunkTokenKey:  hec.token,
   552  			splunkFormatKey: splunkFormatRaw,
   553  			labelsKey:       "a",
   554  		},
   555  		ContainerID:        "containeriid",
   556  		ContainerName:      "/container_name",
   557  		ContainerImageID:   "contaimageid",
   558  		ContainerImageName: "container_image_name",
   559  		ContainerLabels: map[string]string{
   560  			"a": "b",
   561  		},
   562  	}
   563  
   564  	hostname, err := info.Hostname()
   565  	if err != nil {
   566  		t.Fatal(err)
   567  	}
   568  
   569  	loggerDriver, err := New(info)
   570  	if err != nil {
   571  		t.Fatal(err)
   572  	}
   573  
   574  	if !hec.connectionVerified {
   575  		t.Fatal("By default connection should be verified")
   576  	}
   577  
   578  	splunkLoggerDriver, ok := loggerDriver.(*splunkLoggerRaw)
   579  	if !ok {
   580  		t.Fatal("Unexpected Splunk Logging Driver type")
   581  	}
   582  
   583  	if splunkLoggerDriver.url != hec.URL()+"/services/collector/event/1.0" ||
   584  		splunkLoggerDriver.auth != "Splunk "+hec.token ||
   585  		splunkLoggerDriver.nullMessage.Host != hostname ||
   586  		splunkLoggerDriver.nullMessage.Source != "" ||
   587  		splunkLoggerDriver.nullMessage.SourceType != "" ||
   588  		splunkLoggerDriver.nullMessage.Index != "" ||
   589  		splunkLoggerDriver.gzipCompression != false ||
   590  		splunkLoggerDriver.postMessagesFrequency != defaultPostMessagesFrequency ||
   591  		splunkLoggerDriver.postMessagesBatchSize != defaultPostMessagesBatchSize ||
   592  		splunkLoggerDriver.bufferMaximum != defaultBufferMaximum ||
   593  		cap(splunkLoggerDriver.stream) != defaultStreamChannelSize ||
   594  		string(splunkLoggerDriver.prefix) != "containeriid a=b " {
   595  		t.Fatal("Values do not match configuration.")
   596  	}
   597  
   598  	message1Time := time.Now()
   599  	if err := loggerDriver.Log(&logger.Message{Line: []byte("{\"a\":\"b\"}"), Source: "stdout", Timestamp: message1Time}); err != nil {
   600  		t.Fatal(err)
   601  	}
   602  	message2Time := time.Now()
   603  	if err := loggerDriver.Log(&logger.Message{Line: []byte("notjson"), Source: "stdout", Timestamp: message2Time}); err != nil {
   604  		t.Fatal(err)
   605  	}
   606  
   607  	err = loggerDriver.Close()
   608  	if err != nil {
   609  		t.Fatal(err)
   610  	}
   611  
   612  	if len(hec.messages) != 2 {
   613  		t.Fatal("Expected two messages")
   614  	}
   615  
   616  	message1 := hec.messages[0]
   617  	if message1.Time != fmt.Sprintf("%f", float64(message1Time.UnixNano())/float64(time.Second)) ||
   618  		message1.Host != hostname ||
   619  		message1.Source != "" ||
   620  		message1.SourceType != "" ||
   621  		message1.Index != "" {
   622  		t.Fatalf("Unexpected values of message 1 %v", message1)
   623  	}
   624  
   625  	if event, err := message1.EventAsString(); err != nil {
   626  		t.Fatal(err)
   627  	} else {
   628  		if event != "containeriid a=b {\"a\":\"b\"}" {
   629  			t.Fatalf("Unexpected event in message 1 %v", event)
   630  		}
   631  	}
   632  
   633  	message2 := hec.messages[1]
   634  	if message2.Time != fmt.Sprintf("%f", float64(message2Time.UnixNano())/float64(time.Second)) ||
   635  		message2.Host != hostname ||
   636  		message2.Source != "" ||
   637  		message2.SourceType != "" ||
   638  		message2.Index != "" {
   639  		t.Fatalf("Unexpected values of message 2 %v", message2)
   640  	}
   641  
   642  	if event, err := message2.EventAsString(); err != nil {
   643  		t.Fatal(err)
   644  	} else {
   645  		if event != "containeriid a=b notjson" {
   646  			t.Fatalf("Unexpected event in message 2 %v", event)
   647  		}
   648  	}
   649  
   650  	err = hec.Close()
   651  	if err != nil {
   652  		t.Fatal(err)
   653  	}
   654  }
   655  
   656  // Verify that Splunk Logging Driver can accept tag="" which will allow to send raw messages
   657  // in the same way we get them in stdout/stderr
   658  func TestRawFormatWithoutTag(t *testing.T) {
   659  	hec := NewHTTPEventCollectorMock(t)
   660  
   661  	go hec.Serve()
   662  
   663  	info := logger.Info{
   664  		Config: map[string]string{
   665  			splunkURLKey:    hec.URL(),
   666  			splunkTokenKey:  hec.token,
   667  			splunkFormatKey: splunkFormatRaw,
   668  			tagKey:          "",
   669  		},
   670  		ContainerID:        "containeriid",
   671  		ContainerName:      "/container_name",
   672  		ContainerImageID:   "contaimageid",
   673  		ContainerImageName: "container_image_name",
   674  	}
   675  
   676  	hostname, err := info.Hostname()
   677  	if err != nil {
   678  		t.Fatal(err)
   679  	}
   680  
   681  	loggerDriver, err := New(info)
   682  	if err != nil {
   683  		t.Fatal(err)
   684  	}
   685  
   686  	if !hec.connectionVerified {
   687  		t.Fatal("By default connection should be verified")
   688  	}
   689  
   690  	splunkLoggerDriver, ok := loggerDriver.(*splunkLoggerRaw)
   691  	if !ok {
   692  		t.Fatal("Unexpected Splunk Logging Driver type")
   693  	}
   694  
   695  	if splunkLoggerDriver.url != hec.URL()+"/services/collector/event/1.0" ||
   696  		splunkLoggerDriver.auth != "Splunk "+hec.token ||
   697  		splunkLoggerDriver.nullMessage.Host != hostname ||
   698  		splunkLoggerDriver.nullMessage.Source != "" ||
   699  		splunkLoggerDriver.nullMessage.SourceType != "" ||
   700  		splunkLoggerDriver.nullMessage.Index != "" ||
   701  		splunkLoggerDriver.gzipCompression != false ||
   702  		splunkLoggerDriver.postMessagesFrequency != defaultPostMessagesFrequency ||
   703  		splunkLoggerDriver.postMessagesBatchSize != defaultPostMessagesBatchSize ||
   704  		splunkLoggerDriver.bufferMaximum != defaultBufferMaximum ||
   705  		cap(splunkLoggerDriver.stream) != defaultStreamChannelSize ||
   706  		string(splunkLoggerDriver.prefix) != "" {
   707  		t.Log(string(splunkLoggerDriver.prefix) + "a")
   708  		t.Fatal("Values do not match configuration.")
   709  	}
   710  
   711  	message1Time := time.Now()
   712  	if err := loggerDriver.Log(&logger.Message{Line: []byte("{\"a\":\"b\"}"), Source: "stdout", Timestamp: message1Time}); err != nil {
   713  		t.Fatal(err)
   714  	}
   715  	message2Time := time.Now()
   716  	if err := loggerDriver.Log(&logger.Message{Line: []byte("notjson"), Source: "stdout", Timestamp: message2Time}); err != nil {
   717  		t.Fatal(err)
   718  	}
   719  
   720  	err = loggerDriver.Close()
   721  	if err != nil {
   722  		t.Fatal(err)
   723  	}
   724  
   725  	if len(hec.messages) != 2 {
   726  		t.Fatal("Expected two messages")
   727  	}
   728  
   729  	message1 := hec.messages[0]
   730  	if message1.Time != fmt.Sprintf("%f", float64(message1Time.UnixNano())/float64(time.Second)) ||
   731  		message1.Host != hostname ||
   732  		message1.Source != "" ||
   733  		message1.SourceType != "" ||
   734  		message1.Index != "" {
   735  		t.Fatalf("Unexpected values of message 1 %v", message1)
   736  	}
   737  
   738  	if event, err := message1.EventAsString(); err != nil {
   739  		t.Fatal(err)
   740  	} else {
   741  		if event != "{\"a\":\"b\"}" {
   742  			t.Fatalf("Unexpected event in message 1 %v", event)
   743  		}
   744  	}
   745  
   746  	message2 := hec.messages[1]
   747  	if message2.Time != fmt.Sprintf("%f", float64(message2Time.UnixNano())/float64(time.Second)) ||
   748  		message2.Host != hostname ||
   749  		message2.Source != "" ||
   750  		message2.SourceType != "" ||
   751  		message2.Index != "" {
   752  		t.Fatalf("Unexpected values of message 2 %v", message2)
   753  	}
   754  
   755  	if event, err := message2.EventAsString(); err != nil {
   756  		t.Fatal(err)
   757  	} else {
   758  		if event != "notjson" {
   759  			t.Fatalf("Unexpected event in message 2 %v", event)
   760  		}
   761  	}
   762  
   763  	err = hec.Close()
   764  	if err != nil {
   765  		t.Fatal(err)
   766  	}
   767  }
   768  
   769  // Verify that we will send messages in batches with default batching parameters,
   770  // but change frequency to be sure that numOfRequests will match expected 17 requests
   771  func TestBatching(t *testing.T) {
   772  	if err := os.Setenv(envVarPostMessagesFrequency, "10h"); err != nil {
   773  		t.Fatal(err)
   774  	}
   775  
   776  	hec := NewHTTPEventCollectorMock(t)
   777  
   778  	go hec.Serve()
   779  
   780  	info := logger.Info{
   781  		Config: map[string]string{
   782  			splunkURLKey:   hec.URL(),
   783  			splunkTokenKey: hec.token,
   784  		},
   785  		ContainerID:        "containeriid",
   786  		ContainerName:      "/container_name",
   787  		ContainerImageID:   "contaimageid",
   788  		ContainerImageName: "container_image_name",
   789  	}
   790  
   791  	loggerDriver, err := New(info)
   792  	if err != nil {
   793  		t.Fatal(err)
   794  	}
   795  
   796  	for i := 0; i < defaultStreamChannelSize*4; i++ {
   797  		if err := loggerDriver.Log(&logger.Message{Line: []byte(fmt.Sprintf("%d", i)), Source: "stdout", Timestamp: time.Now()}); err != nil {
   798  			t.Fatal(err)
   799  		}
   800  	}
   801  
   802  	err = loggerDriver.Close()
   803  	if err != nil {
   804  		t.Fatal(err)
   805  	}
   806  
   807  	if len(hec.messages) != defaultStreamChannelSize*4 {
   808  		t.Fatal("Not all messages delivered")
   809  	}
   810  
   811  	for i, message := range hec.messages {
   812  		if event, err := message.EventAsMap(); err != nil {
   813  			t.Fatal(err)
   814  		} else {
   815  			if event["line"] != fmt.Sprintf("%d", i) {
   816  				t.Fatalf("Unexpected event in message %v", event)
   817  			}
   818  		}
   819  	}
   820  
   821  	// 1 to verify connection and 16 batches
   822  	if hec.numOfRequests != 17 {
   823  		t.Fatalf("Unexpected number of requests %d", hec.numOfRequests)
   824  	}
   825  
   826  	err = hec.Close()
   827  	if err != nil {
   828  		t.Fatal(err)
   829  	}
   830  
   831  	if err := os.Setenv(envVarPostMessagesFrequency, ""); err != nil {
   832  		t.Fatal(err)
   833  	}
   834  }
   835  
   836  // Verify that test is using time to fire events not rare than specified frequency
   837  func TestFrequency(t *testing.T) {
   838  	if err := os.Setenv(envVarPostMessagesFrequency, "5ms"); err != nil {
   839  		t.Fatal(err)
   840  	}
   841  
   842  	hec := NewHTTPEventCollectorMock(t)
   843  
   844  	go hec.Serve()
   845  
   846  	info := logger.Info{
   847  		Config: map[string]string{
   848  			splunkURLKey:   hec.URL(),
   849  			splunkTokenKey: hec.token,
   850  		},
   851  		ContainerID:        "containeriid",
   852  		ContainerName:      "/container_name",
   853  		ContainerImageID:   "contaimageid",
   854  		ContainerImageName: "container_image_name",
   855  	}
   856  
   857  	loggerDriver, err := New(info)
   858  	if err != nil {
   859  		t.Fatal(err)
   860  	}
   861  
   862  	for i := 0; i < 10; i++ {
   863  		if err := loggerDriver.Log(&logger.Message{Line: []byte(fmt.Sprintf("%d", i)), Source: "stdout", Timestamp: time.Now()}); err != nil {
   864  			t.Fatal(err)
   865  		}
   866  		time.Sleep(15 * time.Millisecond)
   867  	}
   868  
   869  	err = loggerDriver.Close()
   870  	if err != nil {
   871  		t.Fatal(err)
   872  	}
   873  
   874  	if len(hec.messages) != 10 {
   875  		t.Fatal("Not all messages delivered")
   876  	}
   877  
   878  	for i, message := range hec.messages {
   879  		if event, err := message.EventAsMap(); err != nil {
   880  			t.Fatal(err)
   881  		} else {
   882  			if event["line"] != fmt.Sprintf("%d", i) {
   883  				t.Fatalf("Unexpected event in message %v", event)
   884  			}
   885  		}
   886  	}
   887  
   888  	// 1 to verify connection and 10 to verify that we have sent messages with required frequency,
   889  	// but because frequency is too small (to keep test quick), instead of 11, use 9 if context switches will be slow
   890  	if hec.numOfRequests < 9 {
   891  		t.Fatalf("Unexpected number of requests %d", hec.numOfRequests)
   892  	}
   893  
   894  	err = hec.Close()
   895  	if err != nil {
   896  		t.Fatal(err)
   897  	}
   898  
   899  	if err := os.Setenv(envVarPostMessagesFrequency, ""); err != nil {
   900  		t.Fatal(err)
   901  	}
   902  }
   903  
   904  // Simulate behavior similar to first version of Splunk Logging Driver, when we were sending one message
   905  // per request
   906  func TestOneMessagePerRequest(t *testing.T) {
   907  	if err := os.Setenv(envVarPostMessagesFrequency, "10h"); err != nil {
   908  		t.Fatal(err)
   909  	}
   910  
   911  	if err := os.Setenv(envVarPostMessagesBatchSize, "1"); err != nil {
   912  		t.Fatal(err)
   913  	}
   914  
   915  	if err := os.Setenv(envVarBufferMaximum, "1"); err != nil {
   916  		t.Fatal(err)
   917  	}
   918  
   919  	if err := os.Setenv(envVarStreamChannelSize, "0"); err != nil {
   920  		t.Fatal(err)
   921  	}
   922  
   923  	hec := NewHTTPEventCollectorMock(t)
   924  
   925  	go hec.Serve()
   926  
   927  	info := logger.Info{
   928  		Config: map[string]string{
   929  			splunkURLKey:   hec.URL(),
   930  			splunkTokenKey: hec.token,
   931  		},
   932  		ContainerID:        "containeriid",
   933  		ContainerName:      "/container_name",
   934  		ContainerImageID:   "contaimageid",
   935  		ContainerImageName: "container_image_name",
   936  	}
   937  
   938  	loggerDriver, err := New(info)
   939  	if err != nil {
   940  		t.Fatal(err)
   941  	}
   942  
   943  	for i := 0; i < 10; i++ {
   944  		if err := loggerDriver.Log(&logger.Message{Line: []byte(fmt.Sprintf("%d", i)), Source: "stdout", Timestamp: time.Now()}); err != nil {
   945  			t.Fatal(err)
   946  		}
   947  	}
   948  
   949  	err = loggerDriver.Close()
   950  	if err != nil {
   951  		t.Fatal(err)
   952  	}
   953  
   954  	if len(hec.messages) != 10 {
   955  		t.Fatal("Not all messages delivered")
   956  	}
   957  
   958  	for i, message := range hec.messages {
   959  		if event, err := message.EventAsMap(); err != nil {
   960  			t.Fatal(err)
   961  		} else {
   962  			if event["line"] != fmt.Sprintf("%d", i) {
   963  				t.Fatalf("Unexpected event in message %v", event)
   964  			}
   965  		}
   966  	}
   967  
   968  	// 1 to verify connection and 10 messages
   969  	if hec.numOfRequests != 11 {
   970  		t.Fatalf("Unexpected number of requests %d", hec.numOfRequests)
   971  	}
   972  
   973  	err = hec.Close()
   974  	if err != nil {
   975  		t.Fatal(err)
   976  	}
   977  
   978  	if err := os.Setenv(envVarPostMessagesFrequency, ""); err != nil {
   979  		t.Fatal(err)
   980  	}
   981  
   982  	if err := os.Setenv(envVarPostMessagesBatchSize, ""); err != nil {
   983  		t.Fatal(err)
   984  	}
   985  
   986  	if err := os.Setenv(envVarBufferMaximum, ""); err != nil {
   987  		t.Fatal(err)
   988  	}
   989  
   990  	if err := os.Setenv(envVarStreamChannelSize, ""); err != nil {
   991  		t.Fatal(err)
   992  	}
   993  }
   994  
   995  // Driver should not be created when HEC is unresponsive
   996  func TestVerify(t *testing.T) {
   997  	hec := NewHTTPEventCollectorMock(t)
   998  	hec.simulateServerError = true
   999  	go hec.Serve()
  1000  
  1001  	info := logger.Info{
  1002  		Config: map[string]string{
  1003  			splunkURLKey:   hec.URL(),
  1004  			splunkTokenKey: hec.token,
  1005  		},
  1006  		ContainerID:        "containeriid",
  1007  		ContainerName:      "/container_name",
  1008  		ContainerImageID:   "contaimageid",
  1009  		ContainerImageName: "container_image_name",
  1010  	}
  1011  
  1012  	_, err := New(info)
  1013  	if err == nil {
  1014  		t.Fatal("Expecting driver to fail, when server is unresponsive")
  1015  	}
  1016  
  1017  	err = hec.Close()
  1018  	if err != nil {
  1019  		t.Fatal(err)
  1020  	}
  1021  }
  1022  
  1023  // Verify that user can specify to skip verification that Splunk HEC is working.
  1024  // Also in this test we verify retry logic.
  1025  func TestSkipVerify(t *testing.T) {
  1026  	hec := NewHTTPEventCollectorMock(t)
  1027  	hec.simulateServerError = true
  1028  	go hec.Serve()
  1029  
  1030  	info := logger.Info{
  1031  		Config: map[string]string{
  1032  			splunkURLKey:              hec.URL(),
  1033  			splunkTokenKey:            hec.token,
  1034  			splunkVerifyConnectionKey: "false",
  1035  		},
  1036  		ContainerID:        "containeriid",
  1037  		ContainerName:      "/container_name",
  1038  		ContainerImageID:   "contaimageid",
  1039  		ContainerImageName: "container_image_name",
  1040  	}
  1041  
  1042  	loggerDriver, err := New(info)
  1043  	if err != nil {
  1044  		t.Fatal(err)
  1045  	}
  1046  
  1047  	if hec.connectionVerified {
  1048  		t.Fatal("Connection should not be verified")
  1049  	}
  1050  
  1051  	for i := 0; i < defaultStreamChannelSize*2; i++ {
  1052  		if err := loggerDriver.Log(&logger.Message{Line: []byte(fmt.Sprintf("%d", i)), Source: "stdout", Timestamp: time.Now()}); err != nil {
  1053  			t.Fatal(err)
  1054  		}
  1055  	}
  1056  
  1057  	if len(hec.messages) != 0 {
  1058  		t.Fatal("No messages should be accepted at this point")
  1059  	}
  1060  
  1061  	hec.simulateServerError = false
  1062  
  1063  	for i := defaultStreamChannelSize * 2; i < defaultStreamChannelSize*4; i++ {
  1064  		if err := loggerDriver.Log(&logger.Message{Line: []byte(fmt.Sprintf("%d", i)), Source: "stdout", Timestamp: time.Now()}); err != nil {
  1065  			t.Fatal(err)
  1066  		}
  1067  	}
  1068  
  1069  	err = loggerDriver.Close()
  1070  	if err != nil {
  1071  		t.Fatal(err)
  1072  	}
  1073  
  1074  	if len(hec.messages) != defaultStreamChannelSize*4 {
  1075  		t.Fatal("Not all messages delivered")
  1076  	}
  1077  
  1078  	for i, message := range hec.messages {
  1079  		if event, err := message.EventAsMap(); err != nil {
  1080  			t.Fatal(err)
  1081  		} else {
  1082  			if event["line"] != fmt.Sprintf("%d", i) {
  1083  				t.Fatalf("Unexpected event in message %v", event)
  1084  			}
  1085  		}
  1086  	}
  1087  
  1088  	err = hec.Close()
  1089  	if err != nil {
  1090  		t.Fatal(err)
  1091  	}
  1092  }
  1093  
  1094  // Verify logic for when we filled whole buffer
  1095  func TestBufferMaximum(t *testing.T) {
  1096  	if err := os.Setenv(envVarPostMessagesBatchSize, "2"); err != nil {
  1097  		t.Fatal(err)
  1098  	}
  1099  
  1100  	if err := os.Setenv(envVarBufferMaximum, "10"); err != nil {
  1101  		t.Fatal(err)
  1102  	}
  1103  
  1104  	if err := os.Setenv(envVarStreamChannelSize, "0"); err != nil {
  1105  		t.Fatal(err)
  1106  	}
  1107  
  1108  	hec := NewHTTPEventCollectorMock(t)
  1109  	hec.simulateServerError = true
  1110  	go hec.Serve()
  1111  
  1112  	info := logger.Info{
  1113  		Config: map[string]string{
  1114  			splunkURLKey:              hec.URL(),
  1115  			splunkTokenKey:            hec.token,
  1116  			splunkVerifyConnectionKey: "false",
  1117  		},
  1118  		ContainerID:        "containeriid",
  1119  		ContainerName:      "/container_name",
  1120  		ContainerImageID:   "contaimageid",
  1121  		ContainerImageName: "container_image_name",
  1122  	}
  1123  
  1124  	loggerDriver, err := New(info)
  1125  	if err != nil {
  1126  		t.Fatal(err)
  1127  	}
  1128  
  1129  	if hec.connectionVerified {
  1130  		t.Fatal("Connection should not be verified")
  1131  	}
  1132  
  1133  	for i := 0; i < 11; i++ {
  1134  		if err := loggerDriver.Log(&logger.Message{Line: []byte(fmt.Sprintf("%d", i)), Source: "stdout", Timestamp: time.Now()}); err != nil {
  1135  			t.Fatal(err)
  1136  		}
  1137  	}
  1138  
  1139  	if len(hec.messages) != 0 {
  1140  		t.Fatal("No messages should be accepted at this point")
  1141  	}
  1142  
  1143  	hec.simulateServerError = false
  1144  
  1145  	err = loggerDriver.Close()
  1146  	if err != nil {
  1147  		t.Fatal(err)
  1148  	}
  1149  
  1150  	if len(hec.messages) != 9 {
  1151  		t.Fatalf("Expected # of messages %d, got %d", 9, len(hec.messages))
  1152  	}
  1153  
  1154  	// First 1000 messages are written to daemon log when buffer was full
  1155  	for i, message := range hec.messages {
  1156  		if event, err := message.EventAsMap(); err != nil {
  1157  			t.Fatal(err)
  1158  		} else {
  1159  			if event["line"] != fmt.Sprintf("%d", i+2) {
  1160  				t.Fatalf("Unexpected event in message %v", event)
  1161  			}
  1162  		}
  1163  	}
  1164  
  1165  	err = hec.Close()
  1166  	if err != nil {
  1167  		t.Fatal(err)
  1168  	}
  1169  
  1170  	if err := os.Setenv(envVarPostMessagesBatchSize, ""); err != nil {
  1171  		t.Fatal(err)
  1172  	}
  1173  
  1174  	if err := os.Setenv(envVarBufferMaximum, ""); err != nil {
  1175  		t.Fatal(err)
  1176  	}
  1177  
  1178  	if err := os.Setenv(envVarStreamChannelSize, ""); err != nil {
  1179  		t.Fatal(err)
  1180  	}
  1181  }
  1182  
  1183  // Verify that we are not blocking close when HEC is down for the whole time
  1184  func TestServerAlwaysDown(t *testing.T) {
  1185  	if err := os.Setenv(envVarPostMessagesBatchSize, "2"); err != nil {
  1186  		t.Fatal(err)
  1187  	}
  1188  
  1189  	if err := os.Setenv(envVarBufferMaximum, "4"); err != nil {
  1190  		t.Fatal(err)
  1191  	}
  1192  
  1193  	if err := os.Setenv(envVarStreamChannelSize, "0"); err != nil {
  1194  		t.Fatal(err)
  1195  	}
  1196  
  1197  	hec := NewHTTPEventCollectorMock(t)
  1198  	hec.simulateServerError = true
  1199  	go hec.Serve()
  1200  
  1201  	info := logger.Info{
  1202  		Config: map[string]string{
  1203  			splunkURLKey:              hec.URL(),
  1204  			splunkTokenKey:            hec.token,
  1205  			splunkVerifyConnectionKey: "false",
  1206  		},
  1207  		ContainerID:        "containeriid",
  1208  		ContainerName:      "/container_name",
  1209  		ContainerImageID:   "contaimageid",
  1210  		ContainerImageName: "container_image_name",
  1211  	}
  1212  
  1213  	loggerDriver, err := New(info)
  1214  	if err != nil {
  1215  		t.Fatal(err)
  1216  	}
  1217  
  1218  	if hec.connectionVerified {
  1219  		t.Fatal("Connection should not be verified")
  1220  	}
  1221  
  1222  	for i := 0; i < 5; i++ {
  1223  		if err := loggerDriver.Log(&logger.Message{Line: []byte(fmt.Sprintf("%d", i)), Source: "stdout", Timestamp: time.Now()}); err != nil {
  1224  			t.Fatal(err)
  1225  		}
  1226  	}
  1227  
  1228  	err = loggerDriver.Close()
  1229  	if err != nil {
  1230  		t.Fatal(err)
  1231  	}
  1232  
  1233  	if len(hec.messages) != 0 {
  1234  		t.Fatal("No messages should be sent")
  1235  	}
  1236  
  1237  	err = hec.Close()
  1238  	if err != nil {
  1239  		t.Fatal(err)
  1240  	}
  1241  
  1242  	if err := os.Setenv(envVarPostMessagesBatchSize, ""); err != nil {
  1243  		t.Fatal(err)
  1244  	}
  1245  
  1246  	if err := os.Setenv(envVarBufferMaximum, ""); err != nil {
  1247  		t.Fatal(err)
  1248  	}
  1249  
  1250  	if err := os.Setenv(envVarStreamChannelSize, ""); err != nil {
  1251  		t.Fatal(err)
  1252  	}
  1253  }
  1254  
  1255  // Cannot send messages after we close driver
  1256  func TestCannotSendAfterClose(t *testing.T) {
  1257  	hec := NewHTTPEventCollectorMock(t)
  1258  	go hec.Serve()
  1259  
  1260  	info := logger.Info{
  1261  		Config: map[string]string{
  1262  			splunkURLKey:   hec.URL(),
  1263  			splunkTokenKey: hec.token,
  1264  		},
  1265  		ContainerID:        "containeriid",
  1266  		ContainerName:      "/container_name",
  1267  		ContainerImageID:   "contaimageid",
  1268  		ContainerImageName: "container_image_name",
  1269  	}
  1270  
  1271  	loggerDriver, err := New(info)
  1272  	if err != nil {
  1273  		t.Fatal(err)
  1274  	}
  1275  
  1276  	if err := loggerDriver.Log(&logger.Message{Line: []byte("message1"), Source: "stdout", Timestamp: time.Now()}); err != nil {
  1277  		t.Fatal(err)
  1278  	}
  1279  
  1280  	err = loggerDriver.Close()
  1281  	if err != nil {
  1282  		t.Fatal(err)
  1283  	}
  1284  
  1285  	if err := loggerDriver.Log(&logger.Message{Line: []byte("message2"), Source: "stdout", Timestamp: time.Now()}); err == nil {
  1286  		t.Fatal("Driver should not allow to send messages after close")
  1287  	}
  1288  
  1289  	if len(hec.messages) != 1 {
  1290  		t.Fatal("Only one message should be sent")
  1291  	}
  1292  
  1293  	message := hec.messages[0]
  1294  	if event, err := message.EventAsMap(); err != nil {
  1295  		t.Fatal(err)
  1296  	} else {
  1297  		if event["line"] != "message1" {
  1298  			t.Fatalf("Unexpected event in message %v", event)
  1299  		}
  1300  	}
  1301  
  1302  	err = hec.Close()
  1303  	if err != nil {
  1304  		t.Fatal(err)
  1305  	}
  1306  }