istio.io/istio@v0.0.0-20240520182934-d79c90f27776/cni/pkg/log/uds_test.go (about)

     1  // Copyright Istio Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package log
    16  
    17  import (
    18  	"io"
    19  	"os"
    20  	"path/filepath"
    21  	"strings"
    22  	"testing"
    23  
    24  	"istio.io/istio/cni/pkg/constants"
    25  	"istio.io/istio/pkg/log"
    26  	"istio.io/istio/pkg/test/util/assert"
    27  )
    28  
    29  func TestUDSLog(t *testing.T) {
    30  	// Start UDS log server
    31  	udsSockDir := t.TempDir()
    32  	udsSock := filepath.Join(udsSockDir, "cni.sock")
    33  	logger := NewUDSLogger()
    34  	pluginLog.SetOutputLevel(log.DebugLevel) // this will be configured by global.logging.level
    35  	stop := make(chan struct{})
    36  	defer close(stop)
    37  	assert.NoError(t, logger.StartUDSLogServer(udsSock, stop))
    38  
    39  	// Configure log to tee to UDS server
    40  	stdout := os.Stdout
    41  	r, w, _ := os.Pipe()
    42  	os.Stdout = w
    43  	loggingOptions := log.DefaultOptions()
    44  	loggingOptions.WithTeeToUDS(udsSock, constants.UDSLogPath)
    45  	assert.NoError(t, log.Configure(loggingOptions))
    46  	log.FindScope("default").SetOutputLevel(log.DebugLevel)
    47  	log.Debug("debug log")
    48  	log.Info("info log")
    49  	log.Warn("warn log")
    50  	log.Error("error log")
    51  	// This will error because stdout cannot sync, but the UDS part should sync
    52  	// Ideally we would fail if the UDS part fails but the error library makes it kind of tricky
    53  	_ = log.Sync()
    54  
    55  	// Restore os stdout.
    56  	os.Stdout = stdout
    57  	assert.NoError(t, log.Configure(loggingOptions))
    58  
    59  	assert.NoError(t, w.Close())
    60  	out, err := io.ReadAll(r)
    61  	assert.NoError(t, err)
    62  
    63  	// For each level, there should be two lines, one from direct log,
    64  	// the other one from UDS server
    65  	wantLevels := []string{"debug", "info", "warn", "error", "debug", "info", "warn", "error"}
    66  	gotLogs := strings.Split(
    67  		strings.TrimSuffix(string(out), "\n"), "\n")
    68  	if want, got := len(wantLevels), len(gotLogs); want != got {
    69  		t.Fatalf("Number of logs want %v, got %v logs: %v", want, got, gotLogs)
    70  	}
    71  
    72  	for i, l := range gotLogs {
    73  		// For each line, there should be two level string, e.g.
    74  		// "2021-07-09T03:26:08.984951Z	debug	debug log"
    75  		if got, want := strings.Count(l, wantLevels[i]), 2; want != got {
    76  			t.Errorf("Number of log level string want %v, got %v", want, got)
    77  		}
    78  	}
    79  }