github.com/argoproj/argo-cd/v3@v3.2.1/server/application/logs_test.go (about) 1 package application 2 3 import ( 4 "io" 5 "strings" 6 "testing" 7 "time" 8 9 "github.com/stretchr/testify/assert" 10 "github.com/stretchr/testify/require" 11 ) 12 13 func TestParseLogsStream_Successful(t *testing.T) { 14 r := io.NopCloser(strings.NewReader(`2021-02-09T22:13:45.916570818Z hello 15 2021-02-09T22:13:45.916570818Z world`)) 16 17 res := make(chan logEntry) 18 go func() { 19 parseLogsStream("test", r, res) 20 close(res) 21 }() 22 23 var entries []logEntry 24 expectedTimestamp, err := time.Parse(time.RFC3339Nano, "2021-02-09T22:13:45.916570818Z") 25 require.NoError(t, err) 26 27 for entry := range res { 28 entries = append(entries, entry) 29 } 30 31 assert.Equal(t, []logEntry{ 32 {timeStamp: expectedTimestamp, podName: "test", line: "hello"}, 33 {timeStamp: expectedTimestamp, podName: "test", line: "world"}, 34 }, entries) 35 } 36 37 func TestParseLogsStream_ParsingError(t *testing.T) { 38 r := io.NopCloser(strings.NewReader(`hello world`)) 39 40 res := make(chan logEntry) 41 go func() { 42 parseLogsStream("test", r, res) 43 close(res) 44 }() 45 46 var entries []logEntry 47 for entry := range res { 48 entries = append(entries, entry) 49 } 50 51 require.Len(t, entries, 1) 52 assert.Error(t, entries[0].err) 53 } 54 55 func TestMergeLogStreams(t *testing.T) { 56 first := make(chan logEntry) 57 go func() { 58 parseLogsStream("first", io.NopCloser(strings.NewReader(`2021-02-09T00:00:01Z 1 59 2021-02-09T00:00:03Z 3`)), first) 60 close(first) 61 }() 62 63 second := make(chan logEntry) 64 go func() { 65 parseLogsStream("second", io.NopCloser(strings.NewReader(`2021-02-09T00:00:02Z 2 66 2021-02-09T00:00:04Z 4`)), second) 67 close(second) 68 }() 69 70 merged := mergeLogStreams([]chan logEntry{first, second}, time.Second) 71 var lines []string 72 for entry := range merged { 73 lines = append(lines, entry.line) 74 } 75 76 assert.Equal(t, []string{"1", "2", "3", "4"}, lines) 77 } 78 79 func TestMergeLogStreams_RaceCondition(_ *testing.T) { 80 // Test for regression of this issue: https://github.com/argoproj/argo-cd/issues/7006 81 for i := 0; i < 5000; i++ { 82 first := make(chan logEntry) 83 second := make(chan logEntry) 84 85 go func() { 86 parseLogsStream("first", io.NopCloser(strings.NewReader(`2021-02-09T00:00:01Z 1`)), first) 87 time.Sleep(time.Duration(i%3) * time.Millisecond) 88 close(first) 89 }() 90 91 go func() { 92 parseLogsStream("second", io.NopCloser(strings.NewReader(`2021-02-09T00:00:02Z 2`)), second) 93 time.Sleep(time.Duration((i+1)%3) * time.Millisecond) 94 close(second) 95 }() 96 97 merged := mergeLogStreams([]chan logEntry{first, second}, 1*time.Millisecond) 98 99 // Drain the channel 100 for range merged { 101 } 102 103 // This test intentionally doesn't test the order of the output. Under these intense conditions, the test would 104 // fail often due to out of order entries. This test is only meant to reproduce a race between a channel writer 105 // and channel closer. 106 } 107 }